pax_global_header00006660000000000000000000000064143524534730014524gustar00rootroot0000000000000052 comment=4fd5291632232fbe1ba49b2c26bb6b2bf1c6c9cf iverilog-12_0/000077500000000000000000000000001435245347300133475ustar00rootroot00000000000000iverilog-12_0/.gitattributes000066400000000000000000000000771435245347300162460ustar00rootroot00000000000000# gperf in MSYS chokes on DOS line endings *.gperf text eol=lf iverilog-12_0/.github/000077500000000000000000000000001435245347300147075ustar00rootroot00000000000000iverilog-12_0/.github/test.sh000077500000000000000000000002761435245347300162320ustar00rootroot00000000000000#!/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 perl vpi_reg.pl || status=1 exit $status iverilog-12_0/.github/workflows/000077500000000000000000000000001435245347300167445ustar00rootroot00000000000000iverilog-12_0/.github/workflows/deploy_docs.yml000066400000000000000000000013521435245347300217740ustar00rootroot00000000000000 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-12_0/.github/workflows/test.yml000066400000000000000000000045251435245347300204540ustar00rootroot00000000000000name: test on: # Every push onto the main branch and releases triggers a retest. push: branches: - master - v12-branch # All pull_requests trigger a retest. pull_request: jobs: mac: strategy: fail-fast: false runs-on: macos-latest name: '๐Ÿ macOS' steps: - uses: actions/checkout@v2 - name: Install dependencies run: | brew install bison - name: Build, check and install run: | export PATH="/usr/local/opt/bison/bin:$PATH" autoconf ./configure make check sudo make install - name: Test run: ./.github/test.sh lin: strategy: fail-fast: false matrix: os: [ '20.04', '22.04' ] runs-on: ubuntu-${{ matrix.os }} name: '๐Ÿง Ubuntu ${{ matrix.os }}' steps: - uses: actions/checkout@v2 - name: Install dependencies run: | sudo apt update -qq sudo apt install -y make g++ git bison flex gperf libreadline-dev autoconf python3-sphinx - name: Build, check and install run: | autoconf ./configure make 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, arch: x86_64 }, { msystem: MINGW32, arch: i686 } ] name: ๐ŸŸช ${{ matrix.msystem}} ยท ${{ matrix.arch }} defaults: run: shell: msys2 {0} env: MINGW_ARCH: ${{ matrix.msystem }} steps: - run: git config --global core.autocrlf input shell: bash - uses: actions/checkout@v2 - uses: msys2/setup-msys2@v2 with: msystem: ${{ matrix.msystem }} update: true install: > git base-devel gperf mingw-w64-${{ matrix.arch }}-toolchain - name: Build and check run: | cd msys2 makepkg-mingw --noconfirm --noprogressbar -sCLf - name: Install run: pacman -U --noconfirm msys2/*.zst - name: Test run: ./.github/test.sh - uses: actions/upload-artifact@v2 with: name: ${{ matrix.msystem }}-${{ matrix.arch }} path: msys2/*.zst iverilog-12_0/.gitignore000066400000000000000000000030571435245347300153440ustar00rootroot00000000000000# 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] 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-12_0/AStatement.cc000066400000000000000000000020431435245347300157220ustar00rootroot00000000000000/* * 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-12_0/AStatement.h000066400000000000000000000045701435245347300155730ustar00rootroot00000000000000#ifndef IVL_AStatement_H #define IVL_AStatement_H /* * Copyright (c) 2008-2021 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(); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; 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(); 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-12_0/Attrib.cc000066400000000000000000000043771435245347300151160ustar00rootroot00000000000000/* * 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-12_0/Attrib.h000066400000000000000000000034041435245347300147460ustar00rootroot00000000000000#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-12_0/BUGS.txt000066400000000000000000000170031435245347300146510ustar00rootroot00000000000000 HOW TO REPORT BUGS Before I can fix an error, I need to understand what the problem is. Try to explain what is wrong and why you think it is wrong. Please try to include sample code that demonstrates the problem. Include a description of what Icarus Verilog does that is wrong, and what you expect should happen. And include the command line flags passed to the compiler to make the error happen. (This is often overlooked, and sometimes important.) * The Compiler Doesn't Compile If Icarus Verilog doesn't compile, I need to know about the compilation tools you are using. Specifically, I need to know: - Operating system and processor type, - Compiler w/ version, - Versions of any libraries being linked, and - anything else you think relevant. Be aware that I do not have at my disposal a porting lab. I have the workstation on my desk, a Mac laptop, and the Linux/Intel box with a logic analyzer and 'scope hanging off it. * The Compiler Crashes No compiler should crash, no matter what kind of garbage is fed to it. If the compiler crashes, you definitely found a bug and I need to know about it. Icarus Verilog internally checks its state while it works, and if it detects something wrong that it cannot recover from, it will abort intentionally. The "assertion failure" message that the program prints in the process of dying is very important. It tells me where in the source the bad thing happened. Include that message in the bug report. If there are no assertion messages, I need to know that as well. I also need a complete test program that demonstrates the crash. * It Doesn't Like My Perfectly Valid Program(tm) I need to know what you think is right that Icarus Verilog gets wrong. Does it reject your "Perfectly Valid Program(tm)" or does it compile it but give incorrect results? The latter is the most insidious as it doesn't scream out to be fixed unless someone is watching closely. However, if I get a sample program from you, and I can compile it, and I run it and nuclear junk doesn't fall from the sky, I'm moving on to the next problem. So, if your program doesn't compile, tell me so, tell me where the error occurs, and include a complete Perfectly Valid Test Program(tm). You tell me that it fails to compile for you, and I find that it compiles for me, then hooray I fixed it. It can happen, you know. What's on my disk is more recent than the latest snapshot. If your program does compile, but generates incorrect output, I need to know what it says and what you think it should say. From this I can take your sample program and work on Icarus Verilog until it gets the proper results. For this to work, of course, I first need to know what is wrong with the output. Spell it out, because I've been known to miss the obvious. Compiler writers often get buried in the details of the wrong problem. * It Generates Incorrect Target Code As Icarus Verilog adds target code generators, there will be cases where errors in the output netlist format occur. This is a tough nut because I might not have all the tools to test the target format you are reporting problems with. However, if you clearly explain what is right and wrong about the generated output, I will probably be able to fix the problem. It may take a few iterations. In this case, if possible include not only the sample Verilog program, but the generated netlist file(s) and a clear indication of what went wrong or what is expected. If it is not clear to me, I will ask for clarification. * The Output is Correct, But Less Than Ideal If the output is strictly correct, but just not good enough for practical use, I would like to know. These sorts of problems are likely to be more subjective than a core dump, but are worthy of consideration. However, realize that outright errors will get more attention than missed optimizations. THE MAKING OF A GOOD TEST PROGRAM If at all possible, please submit a complete source file that demonstrates the problem. If the error occurs after elaboration, please include a top level module in the program that is suitable for the target format. If I have to write the module myself, I might not write it in a way that tickles the bug. So please, send all the Verilog source that I need to invoke the error. Also, include the command line you use to invoke the compiler. For example: iverilog -o foo.out -tvvp foo.v iverilog foo.vl -s starthere If the error occurs with the null target (``-tnull'') then a top level module may not be needed as long as the ``-s '' switch is given. So when you send a test case, ask yourself "Can poor overworked Steve invoke the error without any Verilog other than what is included?" And while we are at it, please place a copyright notice in your test program and include a GPL license statement if you can. Your test program may find its way into the test suite, and the notices will make it all nice and legal. Please look at the existing tests in the test suite for examples of good test programs. RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS The URL is the main bug tracking system, although some users have reported bugs at . Once you believe you have found a bug, you may browse the bugs database for existing bugs that may be related to yours. You might find that your bug has already been fixed in a later release or snapshot. If that's the case, then you are set. Also, consider if you are reporting a bug or really asking for a new feature, and use the appropriate tracker. system (although you will also find bug rep The bug database supports basic keyword searches, and you can optionally limit your search to active bugs, or fixed bugs. You may also browse the bug database, just to get an idea what is still broken. You may for example find a related bug that explains your symptom. The root page of the bug report database describes how to submit your completed bug report. HOW TO SEND PATCHES Bug reports with patches are very welcome, especially if they are formatted such that I can inspect them, decide that they are obviously correct, and apply them without worry. I prefer patches generated by the git source code tracking system. If you are editing the source, you really should be using the latest version from git. Please see the developer documentation for more detailed instructions -- . When you make a patch, submit it to the "Patches" tracker at . Patches added to the "Patches" tracker enter the developer workflow, are checked, applied to the appropriate git branch, and are pushed. Then the tracker item is closed. If you send patches, *please* tell me what this patch is supposed to accomplish, which branch you intended to be patched, and if appropriate include a test program that demonstrates the efficacy of the patch. (If I have no idea what the patch is for, I will ask for clarification before applying it.) COPYRIGHT ISSUES Icarus Verilog is Copyright (c) 1998-2018 Stephen Williams except where otherwise noted. Minor patches are covered as derivative works (or editorial comment or whatever the appropriate legal term is) and folded into the rest of ivl. However, if a submission can reasonably be considered independently copyrightable, it's yours and I encourage you to claim it with appropriate copyright notices. This submission then falls under the "otherwise noted" category. I must insist that any copyright material submitted for inclusion include the GPL license notice as shown in the rest of the source. iverilog-12_0/COPYING000066400000000000000000000432541435245347300144120ustar00rootroot00000000000000 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-12_0/Documentation/000077500000000000000000000000001435245347300161605ustar00rootroot00000000000000iverilog-12_0/Documentation/.gitignore000066400000000000000000000000221435245347300201420ustar00rootroot00000000000000_build/ !Makefile iverilog-12_0/Documentation/Makefile000066400000000000000000000011421435245347300176160ustar00rootroot00000000000000# 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-12_0/Documentation/conf.py000066400000000000000000000112651435245347300174640ustar00rootroot00000000000000# -*- 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 = '2022, 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 = None # 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' # -- 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'] # 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 = {} # -- 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-12_0/Documentation/developer/000077500000000000000000000000001435245347300201455ustar00rootroot00000000000000iverilog-12_0/Documentation/developer/getting_started.rst000066400000000000000000000205441435245347300240730ustar00rootroot00000000000000 Getting Started as a Contributer ================================ 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). 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 need 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 --strict will run all the regression tests for the simulation engine. (This is what most people will want to do.) You should rerun this test 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.) 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 reuqest 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-12_0/Documentation/developer/index.rst000066400000000000000000000003461435245347300220110ustar00rootroot00000000000000 Icarus Verilog Developer Support ================================ This section contains documents to help support developers who contribute to Icarus Verilog. .. toctree:: :maxdepth: 1 getting_started version_stamps iverilog-12_0/Documentation/developer/version_stamps.rst000066400000000000000000000021701435245347300237530ustar00rootroot00000000000000 Files With Version Information ============================== These are the only files that have version information in them: * version_base.h -- This should be the 1 source for version info. * version_tag.h -- Generated automatically with git tag information. * verilog.spec -- Used to stamp RPM packages When versions are changed, the above files need to be edited to account for the new version information. The following used to have verion information in them, but now their version information is generated: Replaced with version_base.h, which is edited manually, and version_tag.h which is generated from git tag information. * version-base.in -- Most compiled code gets version from here These are now edited by the makefile and the version.exe program. * iverilog-vpi.man -- The .TH tag has a version string * driver/iverilog.man -- The .TH tag has a version string * driver-vpi/res.rc -- Used to build Windows version stamp * vvp/vvp.man -- The .TH tag has a version string This now includes version_base.h to get the version * vpi/vams_simparam.c -- Hard coded result to simulatorVersion query iverilog-12_0/Documentation/index.rst000066400000000000000000000007671435245347300200330ustar00rootroot00000000000000.. Icarus Verilog documentation master file, created by sphinx-quickstart on Sun Apr 10 16:28:38 2022. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Icarus Verilog ============== Welcome to the documentation for Icarus Verilog. .. toctree:: :maxdepth: 2 :caption: Contents: usage/index targets/index developer/index Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` iverilog-12_0/Documentation/make.bat000066400000000000000000000014611435245347300175670ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build set SPHINXPROJ=IcarusVerilog if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd iverilog-12_0/Documentation/targets/000077500000000000000000000000001435245347300176315ustar00rootroot00000000000000iverilog-12_0/Documentation/targets/index.rst000066400000000000000000000006621435245347300214760ustar00rootroot00000000000000 The Icarus Verilog Targets ========================== Icarus Verilog elaborates the design, then sends to the design to code generates (targets) for processing. new code generators can be added by external packages, but these are the code generators that are bundled with Icarus Verilog. The code generator is selected by the "-t" command line flag. .. toctree:: :maxdepth: 1 vvp stub null vhdl verilog95 pcb iverilog-12_0/Documentation/targets/null.rst000066400000000000000000000002521435245347300213340ustar00rootroot00000000000000 The null Code Generator (-tnull) ================================ The null target generates no code. Invoking this code generator causes no code generation to happen. iverilog-12_0/Documentation/targets/pcb.rst000066400000000000000000000035161435245347300211340ustar00rootroot00000000000000 Using the PCB code generator ============================ The PCB target code generator is designed to allow a user to enter a netlist in Verilog format, then generate input files for the GNU PCB layout program. Invocation ---------- The PCB target code generation is invoked with the -tpcb flag to the iverilog command. The default output file, "a.out", contains the generated .PCB file. Use the "-o" flag to set the output file name explicitly. The default output file contains only the elements. To generate a "netlist" file, add the flag "-pnetlist=" command line flag. Altogether, this example generates the foo.net and foo.pcb files from the foo.v source file:: % iverilog -tpcb -ofoo.pcb -pnetlist=foo.net foo.v Flags ----- * -o Set the output (pcb) file path * -pnetlist=path Write a netlist file to the given path. Attributes Summary ------------------ Attributes are attached to various constructs using the Verilog "(\* \*)" attribute syntax. * ivl_black_box Attached to a module declaration or module instantiation, this indicates that the module is a black box. The code generator will create an element for black box instances. Parameters Summary ------------------ Within modules, The PCB code generator uses certain parameters to control details. Parameters may have defaults, and can be overridden using the usual Verilog parameter override syntax. Parameters have preferred types. * description (string, default="") The "description" is a text string that describes the black box. This string is written into the description field of the PCB Element. * value (string, default="") The "value" is a text tring that describes some value for the black box. Like the description, the code generator does not interpret this value, other then to write it to the appropriate field in the PCB Element." iverilog-12_0/Documentation/targets/stub.rst000066400000000000000000000003531435245347300213410ustar00rootroot00000000000000 The stub Code Generator (-tstub) ================================ The stub code generator is a debugging aid for the Icarus Verilog compiler itself. It outputs a text dump of the elaborated design as it is passed to code generators. iverilog-12_0/Documentation/targets/verilog95.rst000066400000000000000000000056761435245347300222260ustar00rootroot00000000000000 Using The Verilog '95 Code Generator ==================================== Icarus Verilog contains a code generator to emit 1995 compliant Verilog from the input Verilog netlist. This allows Icarus Verilog to function as a Verilog > 1995 to Verilog 1995 translator. The main goal of the project was to convert @*, ANSI style arguments and other constructs to something allowed in 1995 Verilog. Invocation ---------- To translate a Verilog program to 1995 compliant Verilog, invoke "iverilog" with the -tvlog95 flag:: % iverilog -tvlog95 -o my_design_95.v my_design.v The generated Verilog will be placed in a single file (a.out by default), even if the input Verilog is spread over multiple files. Generator Flags --------------- * -pspacing=N Set the indent spacing (the default is 2). * -pallowsigned=1 Allow emitting the various signed constructs as an extension to 1995 Verilog (off by default). * -pfileline=1 Emit the original file and line information as a comment for each generated line (off by default). Structures that cannot be converted to 1995 compatible Verilog -------------------------------------------------------------- The following Verilog constructs are not translatable to 1995 compatible Verilog: * Automatic tasks or functions. * The power operator (**). Expressions of the form (2**N)** (where N is a constant) can be converter to a shift. * Some System Verilog constructs (e.g. final blocks, ++/-- operators, etc.). 2-state variables are converted to 4-state variables. Icarus extensions that cannot be translated: * Integer constants greater than 32 bits. * Real valued nets. * Real modulus. * Most Verilog-A constructs. Known Issues and Limitations ---------------------------- Some things are just not finished and should generate an appropriate warning. Here is a list of the major things that still need to be looked at. * There are still a few module instantiation port issues (pr1723367 and partselsynth). * inout ports are not converted (tran-VP). * Variable selects of a non-zero based vector in a continuous assignment are not converted. * There is no support for translating a zero repeat in a continuous assignment. It is currently just dropped. * A pull device connected to a signal select is not translated correctly (this may be fixed). * L-value indexed part selects with a constant undefined base in a continuous assignment are not translated. * Logic gates are not arrayed exactly the same as the input and the instance name is not always the same. * The signed support does not generate $signed() or $unsigned() function calls in a continuous assignment expression. * The special power operator cases are not converted in a continuous assignment. * Currently a signed constant that sets the MSB in an unsigned context will be displayed as a negative value (e.g. bit = 1 translates to bit = -1). * Can net arrays, etc. be unrolled? * Can generate blocks be converted? iverilog-12_0/Documentation/targets/vhdl.rst000066400000000000000000000034761435245347300213320ustar00rootroot00000000000000 The VHDL Code Generator (-tvhdl) ================================ Icarus Verilog contains a code generator to emit VHDL from the Verilog netlist. This allows Icarus Verilog to function as a Verilog to VHDL translator. Invocation ---------- To translate a Verilog program to VHDL, invoke "iverilog" with the -tvhdl flag:: % iverilog -t vhdl -o my_design.vhd my_design.v The generated VHDL will be placed in a single file (a.out by default), even if the Verilog is spread over multiple files. Flags ----- * -pdebug=1 Print progress messages as the code generator visits each part of the design. * -pdepth=N Only output VHDL entities for modules found at depth < N in the hierarchy. N=0, the default, outputs all entities. For example, -pdepth=1 outputs only the top-level entity. Supported Constructs -------------------- TODO Limitations ----------- Signal Values and Resolution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ There are several cases where the behaviour of the translated VHDL deviates from the source Verilog: * The result of division by zero is x in Verilog but raises an exception in VHDL. * Similarly, the result of reading past the end of an array in Verilog is x, whereas VHDL raises an exception. * Any signal that is driven by two or more processes will have the value 'U'. This is the result of the signal resolution function in the std_logic_1164 package. Constructs Not Supported ^^^^^^^^^^^^^^^^^^^^^^^^ The following Verilog constructs cannot be translated to VHDL: * fork and join * force and release * disable * real-valued variables * switches * hierarchical dereferencing Other Limitations ^^^^^^^^^^^^^^^^^ * The test expressions in case statements must be constant. * Translation of a parameter to a corresponding VHDL generic declaration. Instead the default parameter value is used. iverilog-12_0/Documentation/targets/vvp.rst000066400000000000000000000003251435245347300211760ustar00rootroot00000000000000 The vvp Code Generator (-tvvp) ============================== The vvp target generates code for the "vvp" run time. This is the most commonly used target for Icarus Verilog, as it is the main simulation engine. iverilog-12_0/Documentation/usage/000077500000000000000000000000001435245347300172645ustar00rootroot00000000000000iverilog-12_0/Documentation/usage/GTKWave_Example2.png000066400000000000000000001175521435245347300230120ustar00rootroot00000000000000‰PNG  IHDRTsถ5฿ญ pHYsฤฤ•+ IDATxœ์w|Eเwv๗zz๏ คก$ ฝƒ๔.ฝฃ ข"‚RQคŠ า้ฝJ ฝ„„4า้น\ู6฿B:Iลyฬ“-ณ3ณทป๏ฮฬ๎กพkโ€ ‚ ‚x?Po;AAฤ›รตu๘อAA๑Zน๚HหAAฤ{…AA๏AAผG˜2งฐฟว๒cŠFX@ย€LS”(ŠQข(า ย"ˆ"–ษ%ณ{๓F๓NAATQูม_ุ˜%oฅ$ศณฅiู่,ZBHฬ์ฅq๗ิ…œe'๊sSYQภu;YD\ฮa5ย‚Mใpึ ‚ ‚ ˆช*;๘!3-‘กผ\:;] อฦ9ี๋bฮ๋,@"งฯ:๚]ไd2™ฉนผs,&๓MAATCูมเbQ r๔S99๑a>8ึU ดค$๒(dX=… ‚จ&สช๓ผร}!r๗œoŽคˆo-#’ฦฏฌน็œ_:m๓CroOWสŒญd zYP4R™3 {[(L™’ฆ%ศึ[$JJฆค›~dญอแU–ฟ๎Xฤฦ–’7œu‚ สE™ึnักc๓F^nถFRเ49i‰OŸ< >{๚zRญ‘ซ็t0/๛a/1๋์าi*'o๘4H†๘ะ?>๛t†H้ั๓ำฯิ5Ebฦํm["›O์อˆษG|ฑ;J@ฦญfฌžุHŠ„ไƒ ็- Uห้k&ศpฦฉ๏gn %ฑAฤปฃ์เO›วล฿อง%ศฉ*๎NพW“ฤ.5\‹1ถ๗Vฦ?ะ`Œcoซk51Žฟ—/ X›'ผแฌQ&dไีkฺ๔พuL(‹‚(5ฒr๑ฑr๑ชล‡๏ชbr”ฉ฿™Ÿvญญ@lาลห7_ฯpถH่ํDู๘๘XQQฉ"H<๊x0hk_k*:UฦำืS‚kรวศ ขbwn/๚็ฐกร*ฟVั…KO)Sูมฏ3ใ๔Œ ูz)2ใ๔f๖าจ+yฺ,>3Nfvฒ่kน๕”Y๑ฌc]1;Qฯ๋1ฏ{ABF†OํWืa1๛ัแmปN฿‹อfAช2ตv๖๖ซอ็Š|ฺถ้cveห้ซฦ7ำ๔ี—๓ƒ(๐( 01ฦบู๘™[9Hฐ6ุ๊ฯซv=ฬ?ษ๙ะษœrฉใฅ:–šGน๘xฉ“ญ16u๕๕ROอฃ\๋xS€น่ะpํัmส –ฮv–ฆ*ฅุผŒ๘ฐว>t#™iัหพ่h…s]๕ู†ป: ,;ฮY1ช.#ฦ์๛bมDสํƒ^ฝ:4๖qถP ]vBุใs5^‹หญƒ ๋งผิQƒQ gตณEฺm –žJฦฆM๛ภ ๒๎พเวMบ”Wสฆ๋ey1Bิ_ฮw้ยXŸt๏ุถ-็5ƒG๖nVฒ#ฏํดZ ขc7๊๐oWMt๒ฏmมจใ๏๑็ฑะœ2NฃU(~e*Sแาผว‡ํ}]ญhN™unวš#ศ[ ัง…ง•w๋ไ02’‡ œaC‡•ˆ*o๛ฮํ†hฏ๒)”๓žฟยฃc@`ใฉH‹ะ™‹SยดVตไ€ px`๕ฮรAิ,dฺธ}3€ำฯฏ[น7๘i6+ˆl~Vbุ๕วnฅ`EŽg9ŽๅxN(6Dใ8Žๅ8ฎpPVอ?jr+็„์]บt็รlร<.๚๑=ฤx๘zHY๛x[SโำsวjฐฤฃŽง(kook &††็bฺาณžณ\“๑่๎‡Os$vžอzM3ฌ€ ปx%IสธQP}eไอ ฬ…]ธœ,R๘ jฤnk็?}๘ 2O้ะ}๒ืณบปTg IEฉa๕]๋ฤqHYgะุฮฮVอFŽji…p๚ต฿7]J+(B‘ไบN฿สY‰™™kณมำ็3g|WE1*฿๖ใ'vด+rฦฅjuำร1ixผš1ซlะ็ำบ:ัUษpi/ฏL๏_-๘ธWฝ)สMIฮไŒ\๊๛ุI™Œ™=ฉc];%ƒ๕ผ‘_ฟฯ†7’Wฃ† ‚จฎJถ๖•นส๖ #ฟสคSvหŸHRป™1EƒสRโำึิศ’ฑp–Ihฤdb/Qš‹FVŒO[S••ฤญฑ1ฦXiRฮณ#AผA”ณฃˆ๙กwรuาfำึ(Q}้ว7ฏdG,eํแ €ตกป~๘๑h<๛b†>"4šoZWข๒ฉใสDฺ๛ธPb๚“‡Wk๗๒๓๒ue"ํ๋ธPbVุ“dธ›ง}ฌึ1*ccฅŒ‘y๕›;กนนE`3๏?๏฿ใb.ี}งชa‹FF7ฏๆ4mๆA#ฌ}p!8Sสถ๕€.ฮRเŸ๎_๔ํ8คCฟ›฿รมซgฯF็ื็ฯ0ข†z_a^เลโ-i”Mลฉ้"๖ฏ฿็=ฐ๗ภน฿ฐ&fภ'๐วญl๑%E(>“q๑๛ECป/aฐ;mloz/~:“[าฒi˜Jjื๕TžHั<_š‹๘๋%'REสฎW? ๑–{t้ไ{jkJU2\r WฆM๋\ek#Yบ@คZสศษIฮP6-บ7ณ@HT฿2ๅ๙4dำ~ๆท#"ท๕Qก๒*฿o[tษjด•Xฅ’-;bC"ฐ๑Pค<ัŠฦ"ฦ`ภ!‘วฉแZkwน^#ŠyŒEาG@๏คดุ่ง&ถฎ6ชj}ฃ’ืnีกmทา ว๕ŠYaaIb]Wฺาวูหัƒม๊๐ว1ูษกฑbƒZ>>NO%ฐ&qŒ ณn+า …๓รsซ*U™ิdฆVฆ2ร‚Œ‰•Šzš-พดฯ“ัj ใcAฬi๒9๔XP$pDดไ๙๙—ฆห้8ฉz๑+Q™€หฏ8,๐ฯGpนก'ˆ—ชF_miฅใฟ*ญ[ARๅ)๏”๓โจท๗U๏|F19ษ &4\ัJล๘ถh†(!2,\ƒAŒ{Dต•O‹ ๑a†E๊เdC#sn๋๔#™ทnฅ,–œ๗bpNใถf>ฝG;›ะ ฦ_นa่eๆcขb๘ฆF’sะฮGj €”๖๕๋›'d”<้ˆQปg ]A^šR๙ ™รUŠ๓โb๕ŽฎVAฃว=Ž๑|ฺK‹P ศ> น็‘ุ':นWP#[ @ฬ‹‹หฌZ†)ซร‡7ทฆ…ุำ๖ฯว/ฉฬง‘1|So‰ดnงn๗DชE@r[;ezrฆ/4๗b˜ฺพžŠ๋ด ๐ช[‹Ad47Aผ!• ฺJฏe๘ฅ่•Iช์เO"ฅ,\eฅฒd”ๆŒยŒ1ฒ`&Œฅ› c0ฒdDks•9cdลXบสKๅี๊Q"ขfแผ[ึฒ™ฺหำุาภฌFฑภ๓อPTu.ๅ˜Kพดnฑ&ึ'ํœอ ๒sฃ•+UcะG„DsA~RŠF ค†>y&๕8’kๅ/ฃ@ฬ 3ผฃXศิ’˜42N}'ฯฉYฟ’M๚‹ืาZwณ337ฬ…_บ_ะก)ฆ]๘๛tซฯป:u˜๕ƒwXTฏฒดstฒUฅ^8ฃŠฅyIj”yำฑฺูัumหา฿sบ-๘ข›SƒaปE~์ๅEจ2ฬ[ถrUเ3ญยฦสˆBXy๒T(ๆUศ0 ฅwฃF.'น+ศYe>ปธ็Xหู=ไžฝ็ฏn•”ช‘˜˜Gmฒโ_Mฺีใ7บz6ทฐl?e๕ƒxไ๊็gA"?‚x“ชA‘–ยสw—๓ภ‡1ใ@…(ฐ๑Pp:มกฎR"งbB 7กe&4งร๚|มฦSกหEหศ๑Nภ๊ว๛}๙ฐU็๖อxปู˜ส››žš™๛่ๆี+มช<@Cศธ๕ว’๙3ง๕๐0๒๊๕๙\ีš๎dๅ„‡&Š~ตhQ$4NภšฐะXม฿‹ภš๐วฑ† '๛uฝ้่-ฝ\šดSD<ถTง1]Š?ูสG^บืนŸฐ๎๑…ki…zX๛x็โoใz~ุ฿วูงก=—Ÿ•๚๐โฃ›ทŸU#4ฉ(5ฺฎร„QMฬALฟด๙ฯ›YZผoใ฿yฝk{๕ธ_๘ยฟ_Z„*็%แ๘ฺŠŽ}Z๚›s๏ฬŽmวโ…’/`จV๑+จฬ'{/L๘ฐg‡@Wk{G•&+๑แ“Tpฮอ฿–mิŒ่ไi็[‡\ฺถหnฬะ@๒ภ/AผVฏุk\z๕J&ˆ๚ฎ‰€จญร‹N>ื๏ษ,\dg8ฺ“เH–ฉฝฤAs[ ตše%ฒู‰lๆญฮฎJz๖T๗ํฆOX|๏Uส@๑๏๙7‚ C๎ฃ„๒๓‡y|`2`…›•›,๖NA_Bแท๗bก`ภpฝ|+WyๅnmL)Dบ} ‚ ‚ uๅŒ๙“1‰ท๘““<‚L%Hnใฌ0ถ–šXKญ˜3ภสhc|cณ:๒jถภ‰’1ฏิBAAผe 6Ÿะ4…็Bศ๐–QยPcŠŒ1`เๆอ;AฤŽ˜~๒Q'฿v.‚xŸ•อ๎ฝ ็ƒ ‚ ‚xศ@=‚ ‚ ˆ๗ ‚ ‚ #$๘#‚ ‚xเ ‚ โ=B‚?‚ ‚ ˆ๗Hมำพำ&๔=ำจˆวo77AAฤk2๛@a๐7zงเ๎Y็-fˆ ‚ ‚xB‘แ!†฿ ‚ฟจˆว๎žuHหAAฤ™Kฮ“Œ๙#‚ ‚xเ ‚ โ=B‚?‚ ‚ ˆ๗ ‚ ‚ #$๘#‚ ‚xิ\๐'&>8pฬL\c)Vb›ษ;?j8vgฺ›f ขื๕ œt(m็ใCชฅฺฦHAฝZ๐๗๎\oœผuค*jฉR‚ โHฅƒ?œตw\#ฏบ…?uฦํฯBNcv฿}€ช๑|•ฺœ‡O๋yWธr—งŠไDˆู8 pยj\ชต‘G—L่ยฟQฦ?๗Ž[iๅo๒-›่WทXxี๕๐ชู๋๐๓Sk)0์/๏ภ1{ำฤ็ำ„ะ5}๋z5™wแญฤB8๓เวAAณฯซ‹NSvŒlาๆ`๕fซgํะfษEN~๐แ/แย›ษA๑ฉสย”ำจ?ฯ|้_ฅu^ม€๖สI๓/ฮ฿pฒ“—2/ๆ…[บู`jsษหAlxhxOท๎ุง-พ1๙สโo;›”งc่žCO๛Žsง@ผ็0๋แ!O{หูชdัa`๛ฅณ๖Ÿษhำฒ ฦžฺwืก๗œ๙อAAิจืีํ‹sCv}=บcณ฿๚-;^z4FJ*‚O<๛จฎ~m‡ฯก+™๖ไฌห๏kฮอ ๒๔ช๋;๘xฑโ๔Š”&๕ั4—n#{ิณVHU6^-ฮ_S๙•Sœผ“=ผ๊zzื๗kk“ -3B๔บพ‡-ู4k`วF๕ฆำแœ;ๆ้P/ฐ๓๙žh †ี!}1ธcฃzตฝไljอด๋)9๙ํ๓ํึ ์>mำ๘[[>๏ำชIญz}q0๚y›\M์/dม€ฎน๗>`็\}ฦถ_iมJึ•ถ09ฌyฒใ“ฎm'๙Hหฮ^‰uฆmfŸึอ๊6hูa๐›oeVzฯจš๗๋a~}๏ฑค็kq๖Šฌทฏ]โs^ff๒O}ุใ็„ะี}ผ๋ #oEว_ำ–ณีjy๙ฮขื๕mัโ3๛ถkP/ ฐ'?_IฏRmAว^ฯำพbโพ™“ึgด]rเ฿7๖ฮo๐hแ”u๗ูšHYˆฺู—งญ&๎ธ|ํ๒๖ษึ—?ไK,!ํผb฿็ ”ํ–^‹ =านาEคlฺล^็ู‡ ู๚"ืสr‹cgศ๐ˆฐ[—ถNด>7๏ซ})…กรอS!พ}มํ5]าw}6yMb“ฏw_ธu๎๗™uCN4\ญน[็ž4žื๕;็ท ฅ๗/X{E๗j•S6๎ึ…่ๆ฿|๓่า€จ•c?Z‘ุ๙วฃWnžใqใ‡eว2qEฌ"Yƒ}Tว๖\ห1ๅุพ›~{9ัฯ็Uฎฎบ) ฯ./๕๑n๋™ื ฏงL*?{/ึ]ํ๗ท๋Rฎ๓บq๋ิฆx๗๔/๗$’๐ ‚จb๐'&l๎c^ๆdฦ™rฃแ้ฑมžๆ ดWJ๖-'O๎”s๊XHษ0ญ ›๓ช๋Qo์ฮ4,Dž8^โœ^>ฆ2ฅc๓Of๔rจม๐Uๆ?kหฯCLƒืLิา?จUฟiหDj*S$5๗๊2mจ็ฝ‹ทžc†}6ุฯRFud๗mทq '|เj,7vl€ณฯ๏?ลทะัชDๅeYyF]ฝ™-ๆบ0ilร'ืnซลŒืb}‚›Tyด`๑ฟO็%wธŠ3P*ฦkศŒ1ึrนeร3‡9฿>x6…DAผ๊˜ฟr.&bjRชฦ‚V~ '!ฃ^U๋…+ks\Dz†สมัฌเZสุ;ฺQ‘ULถ"Rวcถ h’๎้‹นฒL/dส+Ž.โŸU฿v๚nLบš0Iใ6น"˜PV6–†V/๑YjบิลอฎŒ8ศฤิุ01R ๐ผ๐:'Eฦ&[†‘ศM ZกDย‚5ถฟ(›.ƒšฎ๐ํ๊l]ืUAJธ\8งRuยใ›u–ฝทญoŠเeู{ฑ.ํ>lลbnฒIr( ภรG๖ฎgZฅ ‹r่2 ล/Kพ>ญกื๑}—U]ืด2.นLน™ก›6ฑูxํNฆ้๕ว>อฟkฅ=ด๑ฺฝ |5ฤ)่K›ช฿ก๐‹ ฟํu โ ”.“}Aญา๖Nv(๓Y&‡*g„ ‚๘ฟ๓Zžฆ ฌlญ”ญfœYฟฆŸคฌฌ,๓๏%fcฐF $'•ีšŒ_)ข•Ž๎ฑใฬ้{ ธKูลใทอ_xณฮ›—9›+จิํc:)บี‚…)k[k๖฿˜\ัWjืไBฦmu~ไ๋YŸื“@แ(F1~Oe๊ ˜€ฯ6tฝ>kส8้ฯ๋งšกrณ'”XW^ซใไe'ƒ˜๔๐ขัcJOุฝJแ2๏0 าฯ๗Ÿ๎Ww฿m‡>Ÿ๛หJ-RA]y7”}๙๏Nๅ=ง O,ํดMอw‹ฟk8ฒ6]*™๊+7%1)!E„”ฤlั์อ>NAผซ^K8B{๔๊่ืov'ไq๚œ„‡ง๑ใ้šxq/ํัฉปวƒMหGไpฺไk:˜TF“‡‰น)ŠTWฑ้JL{๎”•{ฏ…'ๅฐผ&๕mGcŒ๋ิu–Sฬ๊t"#S*•>ใั๎•ูQJปw่๔ท/วๅ้ีIท๗|๗หฅื2ธฏฺjvษšฬฝzw๏Xทข!O%๋ช€ิตืา฿zž:fูฅgb%ณว]]3วรทcณ๕‚ˆ)ฌFS๕Wฬ(›๗๋a๖๏สฯw†ืํำืปŒ ญ‚ฬH๋7 PŸr\คฉ=Eื ไูr– hVฏF๏ฐ*ฝณ๘๐ซถหะ๋3๏๏\น=ร๖e4>A๏กืs9 œญ\?ษ๒โ‚Aํ4้>rัIก[–ชชฆR|ุ“Wฃ r1ํ9vีwmSึjัค๙ะ_R‚บ๘•พฒ"ณc‡ž™าดNฝ*=ํK9t™ะ฿โ๚™}Zึmฺ๋“m™อ็:ฏqyลกkœ;ษ๚ดฎ ถ๐ฯV ส~ู ๅๆปฤฌq้Y'bื,ˆขจ–Ž๛ธฯญ‘-–•}{ำรฉ?|pตฦSํแดม฿ิฑ ฦS~รฦL˜๖ถณ๐NภฟโซHMผzMyŸ}Z\xBnBššD3c™ญนฒS }FŽ2)ƒ"! ๑†U6๘Q›6m๔iค›‹Kั้‰ษษ*•J&“Uiร†ฯznnNล‹™˜˜V)YƒGW๗]ูฟRซษล@im{ฺนึnะภฝ่-ZิOHxถใฯํŠคฟˆrฅi๋s|›๕ฌ8Yร qล7‚ข(.Zถ’็ธตซtฐทD^A”*E-7ื&Mถฑcัฒ•_ฯžQีX๊ฟ˜ry๒โV็'lTฺ ฉฦบ"ๆฏ%ึ}ขRjšญI็๔Ÿฅƒฟ'™ืถ†ฮ|้ญEๅi…ผ฿B>ๅ๛ฃทEP‰Yใ์฿y„™าVรๆ์:๚[ฏฺŸSจ์รช2ŸŸ๒<ษผ๖็“ูฌ ญฦบ/ลŠšmas†z}[฿บ:y{•rีธ้Q5๕ฦ.R“ๅีd•>๐j ทแเฃQ9ฺ๘7 0ณฑPQ•ฃึฅeชฏ ฿r์7ฃzปZR๕๏ƒไ?ODnœAลฑเ;uธ]Uธ–S%“ษาาาJLŒh$—หซดแยwh9?~\ํณฯฅฝหบ7ฑ๎฿ฦฝQŸ… 3ณดดvw๗rw๗rw๗๖๐๐๖๐๐๑๔๔ฑถถFึจ๓ไm{4ฑบฐ็๛สคXk} IDAT›ุฟaๅวาM ฑํ9bคฤศ,_ฃฮำไึTสF๒*)—)/n5าž๓j:โแูUจZม_ล๎ฆ8๛ำ๔nฟK-j6eณภ้]ุ้'œ odำฅfฏภดวโ~ฌฏฦฒ๊t‘W’‹‰฿๔ฎk~:๑ ‹ูfv}^฿†โ=1t$ฌA๗^mdไ้,ตํŒQLฯีg็sqฯ๒/…h\อ†๔i๛ห?Pƒ๚ดูธํธFฃ166ฆ(๊ํt ั๋ บ?๊ย๚žชทฐuโ ชl๐gkk›์™{mw_฿SงNO""ทmaaก.ลปƒ+V๘ษ 3’””XณฃŒ w๏mถ)sำ•ซ– b๕nœปxนGทฮNކ[7Cุg`๘}โไ‰2ฉœฆธQ#†žฟty่ภพีHน0>ป|FŽ *ฅหณ5•rQีNน4Cไ็ัx8E‰ˆ‚ด[อ™5ฃp‘Y–[ด{๕‡?‚“9ดajื• ™’uฏ˜Z ึ)dสฉ]Wฎ99“tM์{ืl๚e N๙็Lโฦฉ]WJ$Rืp‰ŠโฑŽf่)Wrr&'่>pฌNoฉIฟๆ‰<+๐ฌN“๛[z์&หคฦU๘•p9i๗ฅ”?'už–P™\ฌeห๒บ/.—ขJฉqwืiถKLฟz๔h์j ›Wz–ืqXงๆRณIฟ฿p๊+๋Z: ฎvn+ใrโ๎หi'u18“5gœ`ฦ…2ชHฦ(ปึ๚ค•ใะ Rป‘zเPไ*-WF้€รบถGิ$Œ๑ฟ๗“Mอพ_{H!แ|ญ๕nvศฌ6%b”–›๔ไqR๐ํะฎ›;Y*24F ‰„Fฉ๔z=ฦ/้๖-ำqๆหด๚๎่ol 7๑B่šž}ืE๗ูxๅป65฿ห๒Žณ์_ป~฿™‘)jl์XงEแSฦutWพลณŒ>แ๒๎ต›๖žพ› U8ิ๏0|ฮ์ม LQีง€ผ}๙Oปฯ†คK\[ Ÿ๛ีฤ kบ†rY…n_[[คค$WW7/ฏ”คฤ˜ธธO#f1–c;อ฿rjหkนผr„TŽs [‚3๖้ธ@ค๕™|ย .z ๔’"Oso๏8๙SK‡A*๗ฬp(jๅ “<ฬ›Re๕!=Ÿงณ•”ล่๖๓ทœVฯkบบ}๒สๅ œFyๆK*œhj s๐๋็~1Zc๊ำy๒Š_ฟ๊`๗ฝึtรCร—ธ๋Ž}ฺโใŸฏ,nQ๕@sjํโe›นฏrmาkฺาe7ต@X๚๗๒…?ํ:{7žณ๐m;rมส๙ฝjIสซ๙๒—„1ห~๙Q+K0Œ\กษคขQlฃำ]{œ~ุ่ๅ~ฝชdŒž‘b9^:เฏ|”งc่žCO๛Žsง@ผ็0๋แ!/9J ฮผธxศด Žcๆ๒u—ตT“v๕ศ_๛/}ษ๘ญeŠป๙ืž๔FW~๊็,Kพ๔ำ์y˜ŸXีลœฏโtšซGO๙ทœeG๓Rฆ]cืนจ&ƒผj(๚ซย9ูะ๘—••enn๎[งตkW4lhnnžŸŸŸ™ูคถ•6l๘ˆ ‚เๅๅeษ._-hU* ิ •Žุ*&๐,๐".ัน\$์ใSG๒‚X•jx \ชAฎˆฆiT๕x๓ฟ˜ฒฏ‰ะ$nvo::/็พ6'c (JDฉTGcฏฝลkoหŒ:ืjะ)&dŠeƒUMxฬฺ‡9'Gtœร!u6—a˜ซป ุ๐฿๓a 2คr4๒ั่หh`ึ่s|ž้ข๔8!รํBˆ €NฬUQ–#:ฮู~n…^|-฿๙๕a๎ฉ‘ํ็ฐ(7Ÿ/,Q0๙ c\P& ฅฐ–ป๑/`พ‚เOหชญ•ต’4กฌ˜‚‚ฒม๓B :1OIY oลฮ๓ห๙งบkอฌแฒ ั๋ ผาxขฝ=ggถXveuภํต‹Vํพ•…,ผ[ žี˜ k๚๙b“์๏๎:š-qm9aัฌF๗^ผๅโ“นgื™ซ๕ช-!zใG=4udz๑อp–~ ๚KI}ฌฃ˜ะkภ0‹ง>ฉ…eRฏ”Qแฯk๒ั๑โ5ษ^ุด)%่‹= kหใŽ-9ฆ็วึ!ปZAึ‰-GWZ๏gญน๗๛'†6พyuNบœšGๅ-–jแ๕‹KQlํุาฯ !P*”r…\ย0E‰ขศฒฌ‰™้ๅ๐ะุ˜JDžว๐0ฌdม€ sป๗>๑E#)ฮนธ๛Œmฟq๖ฟญ5ฬอ;0ฉ๕็็๔ัrหZอ๚อ๘vzk{บิ๑๘ถบฯ“รš';?Ÿ›0๔—ร๊Šw/_๑๛้ …sภ‡ำL๏๎&+ฑ๎Gม…ฃ฿›ูญƒM‹๗ฃก[~ดกคฮ บMnะ ๘ป‹ปฬะ.<๕] ˆ †๖ธ๗์†fO‹•w้ั‘ษห—y%<›ฑ๗m9dึ์ั-จ๒Ž‘J–Wาrๆฯ- ~7๎๔ษ =oผ%ti\ี้Tส_b๛o\ุฯO nญง”~˜ฝnภภห์n๏>ž#ui6ซ…SZXQ8๛ๆๆE%สUbีช mmmcbŸfeeูX๘๚ึ๑๕๖ีjตaaaŽ๖๖UJว@EŒqxxxxxDDDDั@ญจะะะะะฐะะฐฐฐฐJF4#ฑHฎฏฏฏฏฏฏOo__฿ยอ ีฟำ*ฉv-—ไ”d^ไy/|เฃจ‰“'ZโkUแƒES9bไฺ5k [7ฌฐvอฺ‘#Fึ`ส…?ฏ’r!F้iโฑ(๎มQAtๅPฝผ|ะ่ํณr-“Rd๑ษ–,‹9๕I•‰’F‚ ‹{yŠE`ภีg†ดฆA้์S-Ÿฃแฒ5lv›‘ซKฯีฆ็๊žๅ๊žๅjำsต้นฺgฑน๗S๓ฃสK-5?*6๗~ฎ๖๙๒…๋๊า๓ุ ›ญแฒต|N๛Tƒา‡ด๖X}ๆNึe;ฝ"T}vHi๙8-}ชแs4\v>›งฯสีeๆ้2๓๔นบŒ<]fฎ.#W——๛ 9?ผ2)งๆGลๆ3ฌeX=Oo๘%3OŸ•ฯfkธl Ÿ“มฦไแไmฆFio์‹๘ฎฦ ภ<า่๋ื^ำ9iหด{ก฿๚ณื๏œ\ัCฝใ“™ล‰pท.D7๎๏เ›G—Dญ๛ัŠฤฮ?ฝr๛๐?,;–YQถธเญ[ย‚f.โcชฐl4๛OผฎnZgป|P ‹™Beํีr๘>3œp๖ญ yจdJkŸNŸ^0ิgX;กฝญJiแzา–‡๊ๆ›P„่๒+ผ,า.‹๗.ำมฯษTeๅืซ M๓n\ ใEe[ฟ่่f&W94›0ฎฝ๑ฝ0ฎš/o๙by ]าุจํ๔%รMไJ๋บ=žNก=๕Ž๋าิฑg‹ZๆfึVVๆๆfฦFF …B&“) ##ฃฟฏค3 {';#ca,5UJX^ ฝยฃฒ๛จŽํน–bสฑ}7๚๗r*ŒJŒ๛ฌฟv๋าึ‰ึ็ๆ}ต/ๅy59ป‚(,<ปผtิวปญgn_3ผž2i฿ฬI๋3ฺ.9๐๏ƒ{็7xดpสบ๛lษuซ_Sี%<ฝz9ูฅSw?Eีึ{‘็ี๎ป.ตํสCทn฿:งYส…๋้ธโcคŠๅลูwnFส||่ชOืฟ@V›๙๗ณิซุผ็ง?_J-๋Hๅnฝํ3๏ฏทNm€wOrOข(<ูQFนŠซZ“—ก๑ฯอตVxxxN^Nl\ฌต•uN^vรzี๙zA0ฦ CำLaห_a฿n๑?\ะSiผ(–๎\.Tุพ(5๖%w๎nn11qต\ตๅ?;lx5๑ฃวa๎ตช—ฒฤศฬ0‘ฆ‹}pj0ๅษsQ ๋^€ลไะŸ๊v2‚Dแ HAำ2,๊59ื2ฒข-ฬ1รFšุ8๊rn(ๅ/rHEž‰€ฑุกYฯmฐ(๒H š‚ฯ 6ŒAฤ‚–หษf“u|~#หr‡(ฐ‘,gTfR{…ฤ”B4BฯฦPแ?e๋R(Š้ะฌ็ถฃ? ผภsย+๔ืภ€๗F|—ศo฿ด็S๕us ’clhไ{^ภ‹Xฤข†ฯษaStผฺุย*qมเ8>:๓ถ”Všส์TŒ…(D=o|QF„dแ$šข6้~๑ึฑแ๓{.DจzG‰˜ฐuธฯV@ชžฟ^^ูฟaŸ ๖ณค„''†z96ศฯ‚h4๊‹!‡๛:?hข3HF|ฺหŒhีฃน๕แิกำ:ิ60๎ุ=pษ’ฐxก—tํ ปMธTด&ำ>Lq hdmจฺอฟกษw๗CtP๗ล3Œƒ_ฆ.N์}ไ๑ล@Uฺ?<›ฺrฐ=Ž๙ฃ๎฿K็y๛PS‹ฬ‹?|๔Qฟon-i*‰0ธ๛"Kวเ ศุฤธ`รHไฦ&๏E S๑@Qง#cี๓ZA*c#16Wƒกp ฉ\ฦศ”ฦ*นฬิ-hิส !lื๚‹๕f‡}๚`ิ๑ซฏ๛l™ฒ๗ฮยฦ&;7^๖ž๕เซฮ๎€Yห ฟถ,sร๏ผr+ํฅซjCึŽ˜zฎแโ‹Cl *gัำ~ิ= ใบใ~;า฿กขš/c๙R˜z“~๘ฌน=ะ์ำe๏q0~tว2๖ิ;.+O?rษ9ญฎไ9มมฺhหญez฿ย6ูู9YYY๙๙๙ฯ€„aLLMU*รTQ_สฆห ฆ๋6|ป:[ืuU.ฮัEณ๊๛฿N฿IWsฦ i&W€ขว#๗oึY๖:ดพแฉ15)UcA+ฟ…‹ ฃ^™†{๋–!ะิ&ณฮ้@ฺbษล ฏ|Z๔ฯ–ีโ‘นฅ9|–‰กj]/๒Lป[ฑ˜[ทlRฟสย#ฐว๐‘ฝ๋™VxRzyyŸำ†mŸ9n?fใ๊กต˜jLG •’ขฝL์๋cF๘฿m๛ค๓ืณGธ–จ2สมษพ Kดฝ“ส|–I•Uฎ๙ซr๐็ho๐๐?Aอš๏ทฏ^่พ}•Rภ๋๕z„วqrนถ์a ลGRล0ŒaVัˆอp;๕RผˆกH็2๘๚๚nm]‰๐‚aฑŠฎ%•dogณ[—ญ์;v๘ยE dRนJa$bZ๛๋Z\๐.๔ร๒ๅ}{๕จา ๓ŠฆœงษeyVฅ0>|8$ˆBงฬ0 $b๑UR.Maำ‹|์รตตšัดดัq6๓Rƒ๏ฺะุอj๕HYv๋cq˜gฝ–ใฅ<ธrตพgำ(ํ<.ใ‚€H,l๖+ณเw–ๅสlวBˆbYNฏใ ฺฟงg๕y(ถ๙Qฯ็ 0’XบชšนŠx–ืk9^!ภซ๕Ji๙ไ›~๔้็}Zล่oๅ่S1Vc๑y) KTผt,วมหZๆŠ—B,โิT‹าP€2‘ฺธ(ƒC.a ๓Iร฿ฅT7qœพ(++ 68™Ž‰๑‰`Qฎษ:/๙๎ภ๙yjสุคุ€ด๏ด?7ฑKfwmšE[ืi=x๊ŒแBblข๖'ฮ๔‹G]ษฐgขŸ"s๗t๚ฯฌn…็?X3ธ๛nฦ‘“ผ o–‘๙ศรบ‘ข.-ไ่ใฦท›j|g}—ŠjพŒๅปš•ุ4ํRห…)ีฅ%งกฒ๖ิป๐yV.—ญ๚z˜(bc,‚^ฯm}&ศSฅีjๅr9ร0&&ฦ2™LxQฤ–ร‰อํใขzฅ๗ผ ใ6ƒ:~?r๕ฌฯ๋I ๐ช&ฦ๏™ฟ๐f7/r6WPฉวt:RฌํฅHLภgบ^Ÿ5eœ๔็๕Sอeekฅl5ใฬฺ%j](ฝnT= )๚ๅY%|tญๆ-ํ7ž>่ใบ J~ษขŠ็๘็cssr‹› ๓,ฏีq๒ฒŽ“Aฬzxั่ฑ ฅง~์๒’cคป็฿4}๒๙วฟ2ฬ[Qอ้Jฯ:ฎLr‰KJ“R0ก@HILมอ,PYๅ*๑Lฅฮe-<ผภฏ๐GqZl\ฌ_ฝ๚ฑqฑ์ฅ้Eg=8ด๐ๅี‚ฑ(ŠV––๋6ฌ1ฌ฿๘๋บ k ิ(ภ'Ožะ4-Šโ†MkืmXณv/๋6ฌนy+ธ’# /๐+์\ฎWฏMำ"เฮปu๎ุอฟQcpษ;Zƒc {—ฯา3ุถKเEž็ิ๙นy๊|ญšๅXใ„ฤ”)ำgddezyบฝ)—ฆดฌฐŸ๓๐ชภ็ำk…m?‰I mvผLn ศ,/+Aj\ฉฏ‡fY^งe9Ž pพ48ไ‚ซ<@‰-Yห๊8Vหฑบฒ(^ฦฒ,”๙ย˜eYŠ—•ท๎๓dY%ถt•‡\ภ๙RŠใx–eูWm๙ %๏ทึHฐฟ๚เ”ƒคพุ๋uœ^ว๊u๓Vฏ-๘PXŠ— ฌ๐๒ืC`ฬฒzŠWIŠำkK%ฎใT`ใ$ktํั‰ึtข฿๚ื๙ฝ@{tะ;๔๗ฅ๛BฒX}๚ฝญKwลึ๏ัูฅ๒รล…่ƒ๋u้a๑{7dๅ็g—x๗๎ณ‚ถ˜;๗r=ิ-qPx๕™ฟ๕ไี›ืิ!๖›.“๖dbฺฮัฮจ๏iโ‹`[ฬ๙ณงŒถwฒืGE$'›Uค /จษ2ึม97–๖๊ฒ }qโŸฯ—บ๚PrฟพณF5J9>ŒฏDอ[พิฦ„ธง๑S…๘˜xlcoC•ตงjข2^ร5ฮpsv๔Vาแเค›‘ทFัlvCZฃี ‚@ำดBก055177ทดดฐฐ0?x=5๘IถD๒ชสšฬฝzw๏ุbรษ0ซำ‰ŒLฉTJ๘ŒGVlปWัูJฺ๊k้๏ =ฯNณ์า3‘๖่1ิัฏ฿์Nศใ๔9 O:ใวำeŒl*๛`|$๕วูG1s๊š3S๓yอIxp|—หO็ๅ์ใม]๛็xt>ฏMปปํ็Qe—ปบf๚‡oวf๋SX†ซIฉœ๒โ์เŸ&M๘หlฦึ•ล#ผ*Nง=z ชŸฐoร'9œ>๎›Žฉ;5/ฆ,>|๗ชm๗2๔๚ฬ๛;Wn๗ฐฝPVนJx๙็์มก…ฑท๗๕๛ญ.+N“๊ค๛แgfC‡e F๛{˜94ฅ•œุิ๏น ‚ _ืจ~}ฝž^Dรฤ+7ฎ—XP4-๎ฺฑ;ใ๏ัF`ฉดงX„@๛^ฯ›”กpธœa`d๊= UฦทJ(yd๊=_‹ถฯ๖ด‡รณฟ7“" lTตๅ~ืŸฑfG๘-›}ฉ)ห : หฑ|ๅ๎J^‚B๔ˆ:ห๗:้ขจ?คฮที๊Wiดวุี+t‹~฿fq&ฒ๔n5๘—%Ch€Wผ~HšŒํ๓ม_๎n๕S›งฬ5ผ๙œ!พลŽq๖ฬ‚‘็<งŒ้เย` ^ญๆ€ฎ๓ัคๆkพ๛๘—ฺหFู ‰ฯ๏Xuฃ†eฝ}‡Œkฑ๊ษKึMme}๛ฏegVฬ๏๚฿๓Wn…—g\บ็ภ]N?œcดw‘ฃFslัฌจฦz๙:0/tำ,่Soฆš/o๙’๘Gๆาๅ๗ษ ัƒM_ฌn9ฏง3_ึžzวN6ย๓6๛|เโ`{๘,„ว็XYZbŒ ็–ย^ฏ]g"/Mู๊ยE„š๚ ๕ขฺ่็Nบ?Zือ๙R๛zํทj yT๑ vnV.›_ี+๐ฉcฃ๛ตญs=ก๔๚’ฦ๚?eล๘ฅuFn.žำ ผาI ็^ุธ๙^ _t>๑…!—ฦ=7\๛พญถjำIiืกหืไ-๙a\‡๙™”ฅ๗ฃึฬ\F็ƒ$ฐkร‡฿|’-un๖ั‹9RดuๅบQ|ต—ฑท๗u้;๎๊นาžS+€D"€๔เศรxkำ;ท๗U!„†QฉTJฅR,€ e%F”ˆุš::8ผ4ภ‰ฐXุน E ‚๘,=ํQศ}ปœใJmด€ก†๏ๆ)Š๚ฐ[งฦ ฮ]ผ|๊ฬ๙่งqPป–‹ป›’…๓ =ง™9j[kำ3็/่9v๔G•}W๐1ๅ2)FXE=BˆืDJ(1๚‰ส้›Jฆภ&v ^ IDATsผ^ห๒,ขGึ]ฑ็ษยka'kตล&๐p๖ั_ฅ_O#b!ช{ญ)ฅำ์V๋“ฃ1kž&‡–~a พ`Vว;™๙ุสฏ…๐4j6ะ{!}žๅ๕Z–็j ๅฯไ=H๔๊ซกGkตฦr๚iึ=‘GงYบ…c‘กๅkOฉเ=/๐ก๛g‡ฃVE%‡”ฯuช?œีq.f~VŒ๓ตว',ฺ๕๖˜สล0๐ํ%&าต'๏ฟYtc฿jฺฺVำ*\Œ๑Ÿ}๖Zแ_’_<_ธ\Y|Hฬูป-o๒์GiL|:ผ็ฯI๎ลห-`์˜ป๓็v๛์Vฌึฤ๓ƒก›Vd‹j฿u อ๛๒“ๆ_Eๆส๋ท๖ลขŽฦเ>iื~๖Ÿ4]’ˆš ๊—มU๛6๓ทJํ็žQv…—3zg^ถโjšฦ๘์ศt๘มิm* ํv็๋ฟงQ:ึiูwอ๑ozšฃrkพๅKถุึิ๋ฒฺํ'๏2ขํหS๏4ร…Lห๒ฦJ วแฬ<ฝ\Bw๏ุt๛ู›‘ฯžถ๐s๐tฑภ€าฒด๑9‡ฏ%ไik+3'K)หฒ รขร*mqภoทJkาถKn\๓อšL๕ฤไณ&ฟ๘๑X๔ธฃ,[~ฑ็บ!บƒlTโย^๒X~ำ|e ผuKF—ธ}ธd๏‡K .(p๑\ฑนฟ‡izkโั133“aFcไึ.=็šฟ‡้ญ๕}Z U'€ŒŒLSSSน\๖าqaค%Šb]_ฝ^ฏำ้๔zฝ Šข๐โลiEB4’ฐLŽใ๓ิyฏ’ Z‘‰ ๚หpแฟ{mvvŽ!ฌ,๑ผืฤ9ฦR2‰๔วาฝ๛)ผ—„ใX–e9=Ÿ \ฎภ[ฤGคp–฿€N.`D"•JฅE†ห$> ฅn‘ปŒQ2&‡ฃชeYูv่Jz–๗4ใม‡ตง9๔/1KฤXฤš}rจP๛>2‰ษ๎ะy.~ฏ#}ƒ”˜ธฬG=็๙v}}[!ˆ๗Bฏa๗พิฟ1“ฮิขโ€kvสๆ‘8™๗เไ?ๅ๖O?5๕วิบๅู˜‚ณžง;ภzYU๚ฟwzq|.~7๙.…‚;™Ÿ฿๐E้jl™ไœžžNำ —ห13clซ]~๐๑ษ๛$-ณ|.ัำ"•uXวfU*๊๋๋kjj8โฅD} ๔ข<6| „ฌh“\ญ†u๎O;หฒ4MK$ฑX’9อขิ๙๊|>OถAuZZš(-กŠ"\ฎšO-๋จ๒}‘Jฅ‰4##=%%%9%•กiYŸ"KX‰XBำ4M3,ašฆ้Ÿ;ฟqีธZšš::ฺBกP]]C‘K๘=™๋ฆ1ŒT*ฅi)-•JiZถ6—หแry<ž—รๅˆฐบษกตญ‹คๅQษก–ETิŸˆI}k&จVไลฦฆพ3T-๒b•์fภ|/f๙“ะ w2ป฿ป“ฒ่d๛ะp8ูึฉฉฉ))ฉฉ"‘X,f†รๅช๓๙Z-ก@ ิีีhygนn\2||xXศ฿—ดI>dหฒจฉฉihhdO”…หๅสVlษ~H…๏]Y๗!Ÿฯ …& #—Lถ–’์ฒl.ˆฌKQถ๒‡โpน'๛ิaฐEฑขฒแ๑x,“น๚}ึๆู3yuE๙BJBไG)ŽศR"?BH๓–ญัYU$p'œl๎`๖ว_‡ฯ็ …B‰TJKiูื“ššงฆ–ํ‰‡ ๅŠขKฝไ๗ฆ,Qั’ฌ%่ท+แdO๙ !ง Œส๑อ๘ฃoBกฝหŠ[ฉ฿ช‡เ ๙ๅฑ๏อ€+ชj(มฯเฏไ €b๒3๘  Qa;@ 0ๆ A๐PŽ ๘(Gไƒ๙่฿วaศ‘olมYJ P& PPฬiแ็– ๗hฺ พM#๗ฮรํ Ž“ไ—ž|f„M๕š9jิ›rI\$ๅE๏:Nล!๘๗2ภzEฟ…‰=ะฎ๊gtๆหO{ีฉbๆํŒฬใษฦ6j6- ]e €ข๓ม_ฦCฟ‘snr๑๎ใ๛V ฎ๙vืก’|า5:oy๖p]; ƒ^[_†…„‡…ผy๒OluŠห๏]„cๆ่h๕้ม4!„ฐ)ม๗Vช&|x/L ŠŸฤิwชฏฎาF@ัศ=ศ?WฝฆMPะƒ9™ุOใ*uุษึX“/0ฉูด๗œ >ฮผ|ำ\พ๏ฎ_๛Jข./๖jืภถAVงฏŸ็Qo่8–ะ๏6y4ฐิZ๗๚ถ๕๋ป^r5–&„ไ#TฏiSฃ–ฝsW๏U7>ำน*fฟ?ุ>ฉ{‹&6u]Z๗™ถ#๘ฃ /njพ |ศB2ž>ฏึ{„ |Mก_฿{lํ่ ’ืb>ํ\ฯck๘›FG๘๗ฌื{Ma“Bฬ์คa{—6ƒ—Ÿ‹ศ ค์฿L€.g๐็่่ฐoฯ.CCƒ๋ืฏณ,{๚uCCƒ}{v9::ไ<ำิฎžู‡3›๗\}๑{S`:ภŸS่Eฟู>aV€๙˜ƒw๎?ฮ<่โ iึ1I๐ตืๆบ๗่๚๎~ใs7I'„hw฿(<,ไอซเ›ปF_›5๓hLŽข้ื๛lŠmๅw:๘ม…]S›ฤ๛RฦFชู85Rz๏q!าW๗้7rnีคn๔ƒ ,a>ฟูช‰ƒ)'ฯล1oญqิูS/ew™;s&ผ^—N•ธ„‰>:iไๆฏญ–œธ๕,่ศœบ/ๆ๔T\n&@ษ–วc_GG‡ukz๖์1oผž={ฌ[ใ—;๒#„๕“wฎ๋ซ{รO—Nอ{Œ็lธHN:ภŸSเEฟนt๎]=๏)j๊๒5อGM่j๑๓mฮkเ5ัรฺ@ฏgฃฝ}JxXlถ0โ๋ืl7พ_'7‚SrิหS็s๙Muพvล๚fN๎`RึFj4tฒ—< z!ก?g4h\]XทIืEฬ๗เภื†ŽMชrณ๒zฃ(รV. gO=B$ฯO‰u๊ฦ”C่๗็๗฿ฏ1|ฮs-žฆนหจQm/‘–ƒ› Pขฉๅ™*‹๚5(ฯ>ฟ, M‡ฮo:”Z๔้๑ฉ5ำฆOะ9ณคน ฟ๔bป (ณn\ษ๚๛`๏qo฿„ๆ๎r๙y ๓๕ห7-3 ฬ€‚kfaฦy๓ใ ฅฃซ- )5>Hฅ4KH๚›“ซ—nฟ8โKŠ„fYยkิ2‰!:ูšมญ6`ๅbษฆ#{$r ช;t๚k`7[๊5ฌwn[Wฌ—'dท+ฟฃนoฌnใ&ตฟธล๔มงzฝlx”†ƒฃล†{/’ธAO5๖ตQห๗FqtZtoตpๆ™{พ?9s!ต๙,7}Š&๖SlFะๆvsณjข„]ฟ1๚ฅ๏f”^นฟ๒!ŽŽฯŸkjj*R.WหขQ๏ม๖]นไ#ผท tล ๖'๛KŽ๗๎/๏.—ŸฟZp  Dฯ>'ฒฤˆ"„ะ1Ÿr>ฤuxฮึซvใdฉฏษ‰;คอY6ืsH*๎ฃVธ"L๊๛3 ฯฟดชใ›ะฌถ•4ŠR9n,วกIลตฟฌๅ@‹ชขCC“wN‡โzchศปQšMบด็OซนpRหงe๓f”๒‚?๙8ํ†๗<ฒ}๓ค•O>|g4ซิu›๕ฏฏซ6‡ไ^„†r+ฟwa„[sุ๊_gญ๎้4›2ฑnีญฮ๓x^๓อนU{O๙tฮ๘๖;R๙ๆถn}šืๅฝศ™‡ืจGฯะ๕+ฝ—?NZ5์ผxzฃฒ7Ng็ิ@}Eญ.•eฟซ๑ํ›ิฝ^ฉwcs!DRซำตSๅkU=ืวฝๆT๔๔Lญ^3ืsmdŠบyญ&]‡๛ธสษอ(น( !+ฺ$๖ฬƒ‡Žไ™วณืŸ6 เ‡›Wไ]+P๚๙๎Sูฅื็น”ง๕† ผo~c ไห๑ฏ฿—ดษŸ๔ฺูXMปŠwa๓AชUŸๆUีcnmXuzMร๒๙ศ๑มŸญMถ ่pŒ5-์=๛u<1ฒoใ๛๏dG…&.”ฟ”Xƒ†~๛ฝU €่๖๖€าม@9‚วพPšTฏ‰‘ฆ๒„‡…‰ธฑ๒YYMˆˆXฃ๊V@y๑˜+ม”2มมมชnB ีจQ#U7 dใ5๓ฯ*฿n๕ SžŸX2j์ๆGฉ†9S’‰Nใ‰;wฮhoEฟ9=เฐOR)ฦ7ํ]ะขย๔)ชพ(Nž8ฆxๆ๑พำ"฿ฟ‘“ม” ซฮ}ซ฿™ๆๆ๛$nส‘S“๎6 GJฃEฟทOๆ฿๛ศล-ใœั๘{๛dž ๆfฆ, ฅU}-PM๚{ถ"ู(Š๏;M~P.0๏vŽ/๛๋S’\)ผMฺ7wghbูฒ๙๚Twซำ‚ถFm<“˜๐D–bน<4"วŽแ๊๗—?ชใpn่>฿พcผฅM.ฺณad‹ชz|๖_๓:“๎J”{นPธ2อ€+Š”“G๐งเ™›L€๒Q:Mt”๎(ฮ•B[๔2‰‰(&„ดจ_ฬ,+T˜ฤD~–L1็’œม!„WฟVผปฝq„อฌ3‡V๔บ;จฌ_ๆุ๋˜ฮ*ํส’wฯ฿`๏qJn”C;ทญ+ถฒฅฯึ๖ž’<ๅ์,'lํฟะจ3|๗ฺš๛๗ธ—–GŠกัt]tIส฿ฬใ!Nž4ฬJษƒ$p๏๖เoi์#๏.;rฯฝzEOฟ|I๕ภ kงO฿๙–ฉJ–๏c฿โb(nj๖ใ_Tu# ฤQฏ1่๛{ ๗๘7$=ฏ๎งจำj†ท†ึu ยžbฃ? bLซ้?8Yืa,ๅs>#~v๐QEฯrh็ฺฝนุƒ3zLฉ็y0=€P„าำำฏrmูLCCฃฐ็ส๓7d๘๘?h€<,หม/ษ็|ฮฝ)5‘[yะฮรcญนฺ4(ฃ๘ีฝv๖ }ู$6๏๚อลK฿NT็ึพ๗๐–๏[๑Z๓าทำ{ฦPW–•๛™/!„็ิhรใkืุณ๊ใ_Haฟ†\ฺ๛๒๖ญฯ•[๘V1ไ8Lข"•า.^‹‹ฟzV‡v๎Uธำ ˜๐มฒ๘EŠ๓ำ๎่wท#!„~z|งํVŽ๛ึร%Oอn๐ิž๕ฌี๎~ŸO!้'๛›/ฒษ‘bภŠa~ปvŽ๓ฃ฿œž?p](-ฅV ๓;ผwAฬก™)y–.y๒ฮbM่ทœะ}๛Š็6Z๒,pz.“‘ฐษว"?(* ร\นO๙๘1๚ๆํภๆ.N…Š ๘ฦ์4zQž้g7ฮส๏@ึN๔(ถฒูคณพํๆŽ~ทต็Œ๙ฬjป.ึ†๛.D๊ะ]|แ`0ง๙๔อ ฺ›q›๒๒ฤฺี{ฎ…ฤŠตซ4๋๗ดuu ๙;”า‡3mx3s$ๆN!Aซ<ฌWe{อ&ญ้Nฐศ3๛๕ส๔ร~˜žaอ›๑Gํศภ๛‘‘QY/_ฝz-j7ฌoซx J๊.™6eชXสคI่Tฑt๗VŒ&„โC้tZ}ท“lยว/ุ ห›9ญ฿ฮˆYท\>เ๔อ/m{}oม„-"ฯ…{Vืฦ\Z๎;}ฅๅม๙-@ษไาดI๗๎ut๕ณ'&%&ฤว}Vฐ%b)SS—HฅœkQby๙(nพ๕7ฬป+ย๓f(Z‹๊ี *๐ฌt-ฬj‰ฌ๔ฟ๙ฦ2์๕“Fฝv jlม!คZ‡ํ๗พ๖Dฒนบช›ซ\VVT€’NวdFฃ[ฤx‚•ฑาšๅZ|gลCฝ”‰ฤR‰„#‘ฐษขb[ๅ#ศEฉ๑ิแrน<žกธ\Mำ„๛EzณgใอY๙๘ฮ "–จ—ฏฎฟโุดT9{ก*mวU\N‰ญE9•ฅ;V–ฟ(ญฅU๔ฃ๏bญEIม_J†๔ฺIršธƒ?6แไช'‹ซt(ƒXB(CcCuว'6x–ฏhส-%{ทฏWNE…ย1qํโฐห฿๏D๕๑ํj S"‚/ผซ;์๏.Uท เWEต›๒ึวX5พMำo8ฎ๘)\ฝjฝ{ทjWX‡คF„มฏำ๔ใ๑Mฯ#E„ˆ"Ÿyๆๆ“szวฬฆ]ตฏว฿~ฯ’z๛ฟ?\S@ต "Aม็ยฟ)ฒยณศr๊qฌœฃ”ŽPWš“˜็2_โˆ–E๑„:Iqขฬltย๗ฏLฎเOWG_š๐)ณ~ห † ชบ  ๅฬฟSN-Jซ—Sย+*n๘RbkQZEสฉฅX๛zMฉศฐ ร2 K๔‹'„tง+fฤRI†$ึ5BH๕Ÿำ%b -&,{ฆf๎Bุค”$5+3Š|c !C}" KfY^J’zc-B’!„ซฏg˜k„“˜” VBŸ"๑ˆส‘HTp&ศGฑŒlงฺ^ืกฎžƒ”ษฬ0ƒฮฐืmhฏ_/Mš.KI—คืทฐoTฑรไŸัŸ_D›u๋Qฟšหืฉุต{#๓ˆ็wใY๚ำซ[ฑ–l+irี๕ฌzuฒ3ษ๕t›‰ น๘ึะฃOำ๚ฦ๊| ]๋ฆํ๚ฺ`๋W€โ้๙ฃYšai–0๔เ/]"ัฉ้tšHœNˆ"‘Jh†fหฐLฅ0๑'ทW๏j๎ขv:ljdh๐ฒ}มŸBHqณบ]W.๏ฬ&} zฎฒถ4วŽูlยC๎ฎฃv1$ษano~ˆู๒ “@žฒ๒dJ>%ฌ:[<มC฿z›aูŸมŸ4V๔tฉ8]’ู๓ว0์ƒศ9ใพ_j–&„๏พ/W๙’๘ะญkBทBแื้ฐี9๑Kzฮsูิg๖๎>ณทˆ/  ฌย"ืr(m %(–เ๏ศšฏ9R๎๚๓ แgO‰?W๋w‹ง 4kว†๚Eฌ_ญo๚้ั—่ืƒ’ฦฒ,+ _ๅŒ8 ,( ็/๗b~%Œพs‡ตฮT (œW*R2๑5๋๑‚=~ฟ›~ปถuร๗ณํ\อsX๔เ๊ฤฯIyๆ?i๒“ฯฟiZตถb 7•๏,B๗Zดดึๅฮี›=ไบ,๙๏ะฮวz>K๓ฐZฃ%O๖}˜ ช ๊o€2[m๕๏ฉ™’ž-uาnไัฅชœศˆn/k๚sงM?ผ9;’ณkเ่=ั๙L}RV๕EJำ ร04#๚„=สPึค‡ืบถฉกiญ6SฯFœžyiล –6ŒMฌv›q๊ฝ˜Bคฯ5ึ่w๖n}k=@ c?#H’~EHž๎_จณW๏lฑŸ$pšŽaฏ‰Y)โ{‡ฦด๐™าสB g;hrฃ[ฯ~Ry๔—zyึ˜ภŽbาEัวš^น๐‚?๊ ๅo IDAT€ฒม”-๔ห รฦ฿ชฝ^dฤอู๚w/~๘‰๏๎9 ้ถzx๔ป€E5ฎพ%œ&Dอnึฤิ„3Cฬซ๚\๙žššš๔l‰#/ Hฝแ๐[]MๅMŸeb_‡%VจSK‡"„^-šไอหpUฯ[ขL๛l๘tG -ํ*}๎ดนถซๆ”9 Lก#.{i3hb็*BMำf}ฺ D/|ืY;gvณ3ัไ ญฺ ๑จ๒"่ฉyB…อŸ‰rฮท๛ 6บูร&žำฒคฏG๚้feฅฆ-ก๚ป-ซ5˜zCชฉลIMNU๕R{ผzฎMฟ^8›–๚แ๊หiM[bqt€ฒม”)lB|elf*{cซ›˜x‹‹฿žœีหฉ–…กŽPจำh“ ‘(C^ฐUุ2Lไaซฆž^M5ๅ็ฃด"Jษจ:โฬGห[จฅ‰hP ๊n6๚รป่j๚6ณะา4oห"๊m”bฝPŠ ๘ƒ2…c`bHโcใdฃ็2โbdcใ=๊Œ๘cOฃ’Sƒfฺฉฑ์ฯXŽข(–ษ>โฎ€๙‘พุณ๋‘ญืป‚:ฬ8&ตj่Fฟ Kf !DFีฐฎฎ๊n6๚ี†Q3ร๎}๛๋.}วn`xNผ‘JLทฉ้{G, [ั๋ฝ”r LแTnษ&tืšsฉiฑwึmผ(‹ฎ+ฅั-Tqd“nหกข6_]งฒณ๗ฮ4B$SjจQ™ิj}ORp1P’ฉ HqkบถY่dGหสอๆฦ7nSI‡q,๚.œk}gD= ณšํ–F;wถฯหฆfํ5ต/ฝญuE]aๆl_๙๙๓ฦ&\๐?–ึn`7นS=~ะr™ณ{‰๕ํu+Ti๗ฏุkืฟUฤง”@ีฯ™Ššz ฯตW<ืxนH๖ฅpฬ๎{c~f™n%5ื<ฒ๏)??!Drwชฮฒ์ปQ๚=v่‘g›xNหB’–ๅHึบ๕ฦะญน2g-ฯยЉชg›”lุุ”E รฟe<่ิทAลU:ทฦฤ€๏‹ซ๔|ฉzถ @‰fe5!๑” ”ัาาRuส +ซ ชn@I‡ ” ”‰DชnB„. ๙ะ๓สๅ]ฌฅcˆ9@9‚เ A๐PŽ ๘(GA šQท๊˜+bUท#ง› ภ ๋ฎ๘K้ษoy พ.(ต'๕.;cS’C–;็ฝ%.ฯqษำwถๆ+นUPŽ!๘ƒrD|องบด@์N ๅ‚?€rม”V้aวตฎmjhZซอิณั๔ฯ๔ศK+ตดฉ`lbีฐŒS๏ล„"}พจฑฎ@ฟณ็w๋[๋ ๛A’๓็G๚tacห~‡ฟeŽ“>šฐา€ฃ laห!„พฏง@ hWuT_~ืP$A้Dฟ0lญฺห๏EFœญ๗โ‡Q’๘๎ž’n๋ฏ‡Gฟ XTใฺจแ[ยiBิ์fOLM83ฤผชฯ•๏ฉฉฉIฯ–8๒๒ฯŸ5ž=*<๒฿–B$Ž๚ึบw[}ชฐๅB้๕?๚-๕๛ต๑Uน ]@ั@๐ฅq้K›A;Wjš6›่ำNHeแปฮฺ9ณ›‰&_hีfˆG•AOำๅ•Tศšฝj=r>Ž%$ใัำ)m{ปjNฝ…ฝ.€ขเJ%6!>263•ฝีMฬ ~ผ•ลoOฮ๊ๅTหยPG(ิi4I†H”‘{‰•Ÿ ›Ÿ[ญ[O๛Gฯ~fา๏=+ู้่B๘[ๅ๖บŠพY Tโ˜’๘ุ8†BHF\L‚์olแฟGั์iTBrJbะL;5–ƒQล2Lถr ศŸgี•บ๕ช๘่้77Žœ็t๎ๅฌฉ@9<—ddˆ ๓ป.€ข‚เJ%NๅถlBwญ9‘š{gฦ‹ษฒภŠ‹าhžถž€'Žฝฟcลฐ์cๆ8F&๑_ฅdET๒๓็SทE็Ÿ๏™ด๚œfื^Ž๊ ี[วZ?๔า…wi…๙]@QA๐ฅทึ่ญk›…Nvดฌln|ใ6•dำ&8}ฮตพ3ขž…YอvKฃ;ซe;Iอฺkj_z[๋Šบยฬูพ๒๓็ƒ2ู้่์]@ a๗^ 2ืn. u฿ฝพ-mbขญc=๕ฎ„"น?ณฎŽ@ ็บ6ลBฟYาคไ%YUv่็w7%„HŸ/jฌ+ะ๏์๙๚ึz@ว~F„๚ๅ๒ฆfทF1ฒบ˜w๋อ\ื†ำชผ`([๓๙๐ศ‹?ธญป>:์ฬhฮ6ฏ)gฟณ„ยฆWq๊Tำ๓[฿x\ ^Y็๊ฮ–ลpโภ‹๏ป๘๊HŸ๏ซฯบ’Bˆšฌ๛‰ฉ g†˜W๕น๒=555ู้G!Z}๚ื{ธ๏ˆ,ฃ_>๐ผQ฿UหโŽr " ๙tj็ณแห|[Vึึิณ๎3ัSาษ;้„ยญlkkbeSSฟฒ]]sณZ5Œพฦฤห‚?žํ_“zิะึ0j<สง}ฦล3ฤ๙Wภฉิฃำ๐žI‘<>p่C‹+เc E฿*…ภฤDวd<]่ #ฎำฒ”ฏ_RYBฅฦ็ยUSใ๓y„RSใJฅRูI3cู'obช—๔ๅ‹ผ”I—๎_Ž์ฟ—žvwฑ๗~จbฟ,(G๒ุํfภๅทสงมใJืv‚SsS WŸgง‡š’eไ•™อ“‰‰gˆ!—I\l‚ะภ€๗#EQ,รzฅf@งi#๗žv`NI;miญSฤ—ๅ\ม!dฐ๗8%ทสกึฉบ …ฦฉะีซๅชำmyึำM|}๓่ฦK๚ำผฬไ$yพw๕ U๔_m๗?๕6[๓”fdb#๐UŠ“0['ผ yA๗)Sˆn฿ใอลx5Pๅฉ EQ,หœJ Šขฒๆ,ŸAพC•7ฎ๑lฌ^ฬืๅŽผเOษฯใฒ7—ฎ็€ๅY๎“žญศ‰E•ึเJฏแฐ๕†ญ%Qฝ๓ฮจฮ„bฑ๖U+B!๓<$„šB Ž;ไ7'ก{Jkฎyฌษ•ฮั36ิดkๅiฏด฿ฮๆ)ซ"€า)‚ไ ”V%ซ็ส€cw *-ˆ$๎ช฿ฆว Gmฎฉผ%^ๆ)ญ&€RษสjBDโ?P–~ล[<‚?(eดดดT„ย 5yยๅkjii)4i—~พ Qฃล‘ีบ.;4ฒถPฃธ›๗ƒ•ีeUPZแce‚?(eD"‘ช›P(ว^‹KHšขอฎ6๙NยdB!Œ/]๒ก็”หปXKว:PŒาำำฯw9==]ี €L ธHฅ๔…‹Wฃขขฏ^ฟ…9%๛Ba>๚๗๋~ปวลฝ ฐ›B‘`ๆสต€ธธxBศวั7o6wqขpsK,D็raถ/(ี›โ-พ๖1๛8 9๒ ฿V%ูภ๛‘‘QY/_ฝz่ษ ถ @แ?๘‘๗cUe‚ส€Ÿr๔Sฬ ๎๙ags5ืU”V‡๏ำ†Ÿื E'-๊;ฮฟฮ1ชZฏEŸ‘ร{72แq*9๘`H๑ึ สฅi“๎ป๋่๊gOLJLˆ๛ฌช&Q$๘๒\ถC๚๙qM็iฏปณธ)ฏ€3ŠHฦCฟ‘sn:ฬูrฑMMญไˆ'wzPืวYIีรŸŠ๛ŒP ค๙วพLฬA๏6ฝฆ3_ำoทyิเษ๚&FoไแZืถกC‡1๋๎|‘mZฯ&…˜=ุฝIร:๖.m/?‘ซ/1w5ฑ/žฦU๊0ฐ“ญฑ&_`Rณi๏9|œy9๛Jข./๖jืภถAVงฏŸ็Qo่8Vึ’Kง๕qฏo[ฟพ๋เ%WciBI>1ฒA๕š65jู9w๕^uใ3ซb๖๛ƒํ“บทhbSืฅuŸi;‚ฟ1…ฟG%ำoำ๖ฝ[ฤ:๒HภIž;ัจ{งJฒข$ฮ=ฌ=๋PP๐ฅmฝุƒfŽf}tาศอ_[-9q๋Yะ‘9u_ฬป้ฉธภj์๊™}8ณyฯี็ฟgไ€ัoถO˜`>ๆเ{w๗3บ๘BšuL|ํuฃ9‡๎=บพป๗๘wา !ฺ7?  y๓*๘ๆฎฦืfอ<“ฃh๚๕พ›b[๙~paืิ&1๗พ`t!”ฟ3แƒาmึง={ศBˆ(๐ะ™ฤ=gŽOTซูืwHc รz^“X>%<,6[˜G๑๕kถ฿ฏฦ“ม)9๊ๅฉ๓น| ฆ:_ปbn3'w0)ก—eษอ€+๒Tภ’‚Mzผcl;{K#“jฮื&ฐ„ยDmlkฺn๖&฿6uL Mkตu%ฟ|@Q๚ฝฅ^4๕๎f8เ่ล๘ญ]ๆบฏmฎ#@โXT4ฯ”k^ัŒ๚M๛)6#hnsปนYPยฎ โจulboฏ)Ul๋ฌG!’็Cผ=Xข๗dqWู๛ถšnฃผM~ ฌ๛อuธ5บ๕ฑ}๘TPRภ]รฮŽšYG˜Ochขร%„ะ1ั1ฌAž‘ฉ‘Vs฿+{๎"z\-‹Fฝwฺwๅ๒“ด‹ +chd z๖9‘%F!„Ž๙”๓!๎ฏ˜จรsๆ?ฐ^ตใ'K}MN์!mฮๆ^~XฃŠ๛จ๎ฃ“๚ฬยมC็๓/ญ๊ˆ๐O1ฌbซ9#Fd>ฺyลlx€oหส\Bฌ๛L๔\ื้ไ๔ฮี !jึ}}บUrIwหํฏ฿J ‚?(2ฟปศ3วฌฃง๓ฺ…ำ6ฅTฒภ:[)าฐƒซw7[ิฏ๕๊ฐ฿จcฬิฬ;๕kฐ๏฿y๛*ตพ1vิฮg5Nrไ_>!L๔ฑ™K#๔๏ิิฺส„—r~๗นํz6\’˜•‡[รฝC•m[yฎŒถDทฏ=‰ฉ#งLVœžฮจฉkii๑ค__œ[น๛‰ิ UŽ<’ปฆVซg3[ .หกˆX$’ฦ *ฟพ •ŸO~ !LLtLฦำ…: ณ’ิฟคฒDB้๊๋ษ:ญy|#•`สก฿แƒาkีซŠหวk้j•ฝW‚็ะพ๓ฝ^็[6้ฟjฑg!=6Sซืฬ๕\™ขn^ซIืแ>.r#?Bวข๐žGถožด๒ษ‡๏Œฆq•บnณ๕uี&์ฯเpk[ฝเ๋ฌี=fS&ึmปบีyฯห-nีำG>3พŽTพนญ[Ÿๆuyนๆ5๊ั3tJ๏ๅฯฃำ…V ;/žลจผwSA‘ใ˜š›jธ๚<;=ิ๔ืw=(fŠึ=์=ษศ [๔lk๖หคJ~€฿ฌ9Nฆtl<็n๓œK Ti9hqหA‹sฆฒศ3ฟrปู{ฺอ&„’~gพ๛Q3s!EธUG๐๓ํฮ[žt&„ขืxิฟ๚yddๆŸูสไ›ป [โ2ฌ0M($N…ฎ^-Wญ˜ๆoปศณžnโ๋›G7^าŸ๎็UYี €2๏wทwcำ}Yฝใ7=•v‹1q6ฎ๛๏eœ(#๑•Uซ.p[ทkˆU กไใT่ทๅฐ๐่ง*ๆี[ุjhWหRธ"”:ฟ๕ุW0ูy๊ถ}—Œฬ6ีC%8FŽŽš‹๖ž:žูท๑wฒช[ Jฏแฐ๕†ญ5•c9๚b์่ฬjถ3๎ล*ฝaPถV๐วoน2๘ูส้9ถ*ว กท฿~o%ื P:๖„ีะาาRuส +ซ ชn@I‡ ” ”‰Dg‚BŠˆXฃ๊&”hVV๐1%*'šaPŽศ๋๙SีbผX ˜ไฉj.lP|๒ ค ภ ไภ˜?(AชีฐฎVรZีญ(ƒpc ‚?(Yพ ญ^ำFีญ(ƒpc@ม” PŠ n,dม:Pฒ„‡…จบ en,ศ ็ ฐ๗๗2uฑภงฝฅกŽPhไu2ƒMบ5ฑF๗oฅ„6แ๊ฤ๚5zํ~Oห+…Mzผcl;{K#“jฮื&ฐ„ยDmlkฺn๖&฿6uL Mkตu%Sฏ (•ฆเ‰ฺะJป๕ๆO๘.,ณJฯผi่™›zใŽ=œ˜’๒ew7uJงู<1ขe#ึ<}>แ๋sอiฆฟชp๓/€๙|xdลึ~vf4g›ื”ณ฿3฿ฺ’็Cšn|๙๚X๏”ญณท‡ส!Rzn,ป" ˜w~.ฺํw”’> ษฝฟkชQลoดไๅ~ฏฒฑ[jPล5r^\4ญ+็Jษ่4Nล~sguจกวน,ฅบฯถ๙ฦ;ผฺzL}ำ{๋Š๖F๒Vฌd>ฺyลl๘2฿–•ต5๕ฌ๛L๔ิฟt๒Nบ์ šu_Ÿnี…FM<-#^ฟ•E‹Kษ€bWDมงช๏ํไ CUผ@3ถข‰v็%ƒRFC.dˆƒgิแ"พ4ŒKeรQoถๆ=“๓IฤฉiฌMB‹z=^‰a!„2~1]|วทชœ>PX้ P8&fนฬr+u&ใix๕ฟ;ๅŸฯฤDวd<]่ #ฎำฒ”ฏ_Re๏\JW_O๖ษไ๑yŒT’๋ฝXhฅ็ฦ@ฑ+M}‹ ฟอึšอ$บ>ึJเ์ูฝrŽ;#yถผื_'Lg”yn$ูึkภฆw น„‡…”ึฉ ์ืK3&^ดำ3แŸ1›_ห๏ๆ˜š›jธฎ{—’šๅษr; P)พฑPค ’๗3ถ›๕HJ‘>™cฯใ;.ฃ !’{Sj™>+๚๕ฑ/rI#ก๋ฤฅ^NVz‚ž‡D์๗เ-#\k™ิตŒkท™x(,]๑๖I"NNvฏa ฉฉ_ฅูˆ]/D™ษ฿wwัค(Šรแ ฬl;อ8%%„dะ`ZPสูAŠRw๑{วไ™M๖๛…m‡“ฺx๗ฉฤ!„ะฏ—;jYฯ–"นฟk็+งIK๚ึึี4ฌ๏ฝtLอป;๖้3c(K่ศcฦlพnำ’5;ฦJฒ๘^Šœœ ]ฝZ†ฎ›ๆ’‘์ฺ‘vGโื (~ ยฆnฎD2„๙pใ›Uฅศ๋q,กรฏฤ9บ9kๆ>C|๓๘CงuA1ขิฃฝโ๛w\ืe๛รุไ๘‡๋ƒ}z,สPฌutจ_฿'MgD'Dฬ1ปt(X"; ็u:eY†N‰ผ<ำ๔แQ Q๗ุ๛h™ฃฐำฎo หf๖ญสษ3›ฬ็ฃฮ๒บ๋’ณ†๒yL…๚๕3Ÿksญิำy๓4คQ,(ข๔ฮKHพึ{fdŸอKฺP๊6>›็™๏๕ž|..œ ถ๖แTลผzซ;c[ ํjYl๑ฅ๗ฦ@‘Sh?สธ…ซอคซ7ฟNะฝq]๓i3ำๆ\ฝ•4ฬๅฦตฐบ]š๋Q„ไŽใ9Œ]:ม”K๒ภๆถฟืฌ"‡ก๛ฬูwŽ=๒hพฃฏภzฅ!‡ผh2๕ฤ@{ŠธฯZ์ตทฏฯญ(u#;ฯyฃทžฟ™4ผฟ^พ X6๚อํ7อ๛_sหฏลญ55H4•B่”ไ"ิˆ )ถ‰LฑD โaŽeŽltZษ~@ฉ๏Hlฟ_“4์|/E๘xลญ2๐่”B้5ถยฐ๕ฟฆr,G_Œ๙Bอvฦฝุ?o/!คภ;ฏˆช(ฃ"ศU7 ศ(ถศ3วชeห +ฎŽ7ธ๚ธฎ๛–๖ฉ๛—]นว^}TีีฏB^ฝS Sู::2:ํฺK๎˜ฌƒ”ฮ€x…žo1ฑ1๑ฺ•+dฦW<ห*นฒฏ.Qศž้“9“$ฆY–๐›uฮ\Q‚ู2‰๎๙vะฎFื#ิ’”ไิA.›šœยัึัBไWด0/ก˜|c็)ฉ%ฅ”•ี„ˆฤ , ฮ๒'แCอฮญ…ฦะ ›…Vฎ๓L*ŠZo<ทUจืb\ํฆนfฦE\ณ fย‹รฯ.T`Žฉ™qr`ไ7–˜Q„iTฤGšB˜w[GนQ฿•นV3pฃ7ธี9ศศ&฿Raูฬ-lyJฝถ}_ดห์ฟjๆqE”‘Y๔ใว๑ฌƒ9E๑่IRฮ6…ฝ"(P}~ZZZสiIศ8ฺ[ฏื‘\ฃx๕ๆ? žcงโ๒oฌ•ีฅต ”ยวส EทwSo์ึ4y่๊ร•|ฎVโpYืfโN~'x]๗4,่แ-ืบH็ ‹Fฏฏบb “9๚พีAถ[VtำV qึ==ญW3uฏ๓ฯ*)ท—ฯi@a3Di OC(๒ฅqมปgฌป+1้L!}#๊‹$ฆ™.'lyaฟœ~,ฃใ–^?{2้ืห๋ฯํๆณ%xฎlีŒƒอืt7yฟ้†9Oํ[๋ปไแfภ•b-_$œฉค่ฐ๋k๊ฎ<d”ฌห@—€|่๙ๅ๒.ึาW่โๆ >ฺีFาภญ9oํaงึyM๖ศSี๛ภyjึŒ1ฮ3ร“4,ํL[่ฎ@ไG!jถ“๘ว{Ou1๗fอ๕าปัฃpBท๖ˆ•ำ๏๎]ร/Yฃbรn#ฺ7แ?$„Bv™4a๐ฎฆซฟณN+_ศ'[˜‡ถ]ิ๎uฒฃ~>“ผบS์N5ฝ™๙ ‘Nํถฃ๏Y ๋ไไBQ๔$\6)แํ›ะ"jdย€, ”้ฐDร~ผา์่G๛<สฉ๊{;9sธ;ทฮŒเไ_Nีk่ฝแข๗†฿iฟjฟซ=ฒ^ฯ‘aุbๆ้™?ณM๛Q•ก๋‚หแ ฒาซๆ™-Z8•ว\K“#๑็„BแYu[~ก๒฿นŠ๒ใ๖อซXBi˜๐Q*แฦ€Lyํผbฟ๘ทW/ชํ๘Maษฟข€ ลคเหโ?๘‘๗๑~ ๊( ๗•%ผ&+ยค+Šค(สt๘ล๔แERB˜๐ฟง€‹‰๋rฉ`ฬ_€Rkƒrฅผ๖”K มFล7ฒ ๘ƒ’ฅT ๛_๓ฉn7-Pข๊vFฉธฑ  A€RLpc ‚?(YยรBJ๒œ้๓Eu๚?ฟ[฿ZO ุ่ฯ’ย&š๎Xฃ๛ŽทRB›pubฝvฟ—;œMzผcl;{K#“jฮื&ฐ„ยDmlkฺn๖&฿6uL Mkตu%พhฆ•๐ Jƒเ ิ์fOLM83ฤผชฯ•๏ฉฉฉIฯ–8๒กtšอ๓#Z6bอ3ั็พ>ืœึm๚ซŠœ-`˜ฯ‡G๖Xมmํ๗ัagFsถyM9๛=3ฬ“<8าtใƒศืวzงlฝ=๋@B๐%Hฉž— nใณmพ๑ฏถS฿๔บขฝ‘ผีS˜Oงv^1พฬทeemM=๋>=๕/ผ“น ฐšu_Ÿnี…FM<-#^ฟ•qJ๕-งo์IDAT€ข…เJ–า<:[ฉห๐6Oรซ5ุA(?+“๑tกƒŽ@ บNหBRพ~I•uQบ๚zฒO&ฯcคฆ(Wšo,%P‚”š…ข(–ษ“ฑ_/อ˜xั~Lฯ„ฦl~-–[วิTรuป”ิ,฿N”Y๘'Jอ€โ‡เJ–R1/cdb8๐UJถ๘Ž?f์อๆ๋6-YณcฌไŸ!‹๏ฅศ+กBWฏ–ก๋ฆ๙EงdคD?;ฟvไ„‘Eาล—Rqc@ ššตืิพ๔ถึu…™ณ}ำŸฏ๕žูg๓’6”บฯๆyๆ{ฝ'Ÿ‹หข.งBฟ-‡}„GG8U1ฏjฤฮุVCปZโใลฏ4ํํหDmpณ>้๙๚๒H‹ฐ)๓ฮฏyหƒ฿j,ง5%ซอ%žlRย7กชnHAธ•<ึ\๓ศถฯ'ฯฮ๗R„oึแ*พX@”^รa๋/ [k*วr๔ลุั™/ิlg‹-Š๖–š Y™ง๊6@UDมŸb‘P™Uฮ/ฟHษFงแe‘ร(eๆฉบ BŠท๘" 8U}o'๛œฏ˜ัa+š6ผ5๊ร้๚J ยJศๅ—~ŠฬKะาาRNcŠ@ฦัzฝŽค็Lๆี›0xŽœU‹Z7ึสj‚าPJแceFiz์ ๅA]S"‘H9-) v}M•็‘ e_†ฑFฮQฐฒš€ (‘wฑ–ฎะ๓ไใŒํf=’BคOๆุ๓๘ŽหรhBˆไ”ZๆƒฯŠa๙นhท฿ฯB่—K ]'.๕rฒาำ๔<$bฟoแZหD ฎe\ปอฤCaนzB๒'‰89ูฝ†ฆฆ~•f#vฝ๘๑}๙}wMŠข8žภฬถำŒณQRBHฦ๑ ฆฅœdภก(uฟwLžู๒ฤ|๘ืUืaIึ^ tุ?Nฺฮ+฿ะ๙ิ•ใ์l—Ÿo›TOกเOุิอแร๕€H†0n|ณชy= Ž%t๘๕€8G7gอgˆo่ด.(F”zดWœŽKใบl›pฝcฐOAŠตŽ๕๋;๐ค้ฬ€่„จ€9f—Kd๔ผNงฑ,หะ)‘—gšŸ2?Š!๊{-svฺ๕aูŒพU9yfห๛>X๖ุโํพ}OdH_์฿ฺฤซO5n>uF›TOกเ2nแjr๕ๆWๆ๋๏šO›์๔๊ญ$&๖ฦตฐบnอ๕๒^วsปtธƒฉ‡ะฏlพa๛๗๚qอ,…|A%๗™ณป'=๒Hก€Hr๘ภ‹&SWด7ะVvŸตุซRŽ๖R๊Fvž๓F;3Iœ2้โี6เžภ Bˆ๘ม]๖ฌภ)\! ต@u L8V-[Vxp๕vซ๋บwl๏V;่สฝธ[WUumY!ฏ"8ฆฆฒแ์ttdtฺต1–\JFณํึOฑฑ๑ ญfหฤฦฤkWฎl]๒,ซTฬ#/ ู3พฝ}E= 5‡[qฬ5ัท๘๏yฉ`6B!”~{ฏ.G๗\O%iท๖I๊0ฐ‹lฟ…ย"ฏอชง`ฏ”š[ 6_ดrmaRฑeKใ็ถจืขUํB›ฬ่‡kVมLุม?Žaณ0‰{บจ+ิ8S3ใไศศo™+ๅJฃ">า„ยผ:jฬš‹ฏ„}M“2๔‡๕-yŒlฏ-Šขหfๆฯ?[ฎ^=ีO๏พ๐แา๎lทmt~งฺ ฅ™$hFชcฎศ฿ฑ  TP๔‘คzcทฆษ‡Wึlัช‡[หต™x฿ ฑ‹[C^'rญ๛t^4z๗‰โ๔o๏[ิ๏๏“ษ Uชfำำ๚?S๗†$ˆEQืฯ!„6C”ฦ๐4„B!_ผsฦบป™O‘9๚Fิ๛!I๒ณๅ{‘N๕1พฐfค฿Y^อe Šถฺ P(<M่โๆ N6wตQ#„ืภญ9/Y๊ิ:ฏษ9kจ๊}เ4ำscœ+๊ึj3๎ํ้ํฎญXฅjถ“๘w๚8฿ล\วขูœhทx„ยญ=bๅt๓ณฝk่j[8ฟmำพ _–Ÿ2์2i‚ลษฎฆ<Žบ‹_dอ|ฒๅ‹Wo@๊ปkู๏ฏฦ™y๓ญซm( ^็2๖ŸhุWšใhŸGณฏrฬญ3#๘—ž=Jฏก๗†‹~ง}ช=ฎ๖๐หz=G๖‡a‹™งCfฬ6ํGU†ฎ .‡/ศJฏšwถ|q๋L1—$*ฟบฒ]๒ฏ‹<็ำfีรLT(˜จmM;ํˆe !D๚bIำวา~คท›ฝษทMSCำZmg]ษ\ฎ‘ค‡ืบถฉกiญ6SฯFนษ&=1ถฝฅ‘I5็kุG๗๗2uฑภงฝฅกŽPhไu2#฿๔ยท H”ปเ_้ฤง~ล1|Nม•ก,’<8าtใƒศืวzงlฝ=”&„ะ/7 ซ๖๒{‘7g๋฿ฝ๘!3๚c>ูc๑ทuท฿G‡อูๆ5ๅ์๗Ÿแ™4๔ฬMฝqวžNLI๙ฒป›zA้ ท ˆ”ปเ[}r ˜๓ugG…ฆCูคfืง[uก†Qwหˆืoฅ„ะ—ฮฝด4ฑsกฆiณ‰>ํ„ฒ้๋ฬงS;ฏ˜ _ๆฒฒถฆžuŸ‰ž๚—N๙นg งbฟนณ:ิะใ็X2ฟtEPTฐท/ฅซฏ'๛5ˆว็1R C›Ÿ@›™ส’ีMฬ 8ษ„ยฤDวd<]่ ณ0๋lu๗/ฉ,ั”Eu ณผ>T๙ฅ+ฺ€ข‚เสJว%Rฑ„%„"์๗„D๙#้8&†ไnlC„B2โb!„pLอM5\}žjชH^‘ต จ”ปวพPNQีซ๋ผ8โeฒ81dฯึณฑ๒ปำ8•vฒ ตๆ\DjZ์u/&ห‚3N…ฎ^-CืM๓ŠNษH‰~v~ํศ ป#ฃkฎํ(* œPo6aQงฏ+[XUi>๋Cฃถี ุu[k๔ึตอB';ZVn67พq›J™๙9๚m9์#<:ยฉŠy๕V#vฦถฺี๒w>F…l@มc_(/ิชznพ๋น9๓ีผqฒ?9–ฃ/ฦŽ‘ลvฦฝุ๙ีkxฎฝโน๖วหE?B้5ถยฐ๕นkะํw$ถ_5็^ุ๖ฏyสฉ ดŠ kT€"ƒเภสjBDโ?P–ผ:Š‚?(eดดดT„2ศสj‚ช›Pาแce‚?(eD"‘ช›PกK@>๔ryk้˜๐PŽ ๘(G”#E1๏\ด๏ˆว.%YM๘เT๕ฝ์[4e?:lEำ†ทF}8=Pฯถ่‚œš6sU$EQ‰ธธนaถ/ฑทoBๅgธpE9-€z์›|ผŸฑฌGRBˆ๔ษ{฿qyM‘›Rห|๐Yัฏ}้—K ]'.๕rฒาำ๔<$bฟoแZหD ฎe\ปอฤCa้Šท/๏s3ซX6ฐI%] -c[๎ผฝํืฯมRGC`ึp๐^ห:•่—K [MX2ภมRGCหุฆหห1 ษ8> มด ”ณƒ 8ฅ๎ฒ๊๎ๆถ๚ <ง3kค_.mฌใโŽญV  R(๘6us๘p= ’!ฬว€฿ฌ*E^ˆc ~= ฮัอY3๗โ›ว:ญ Šฅํ็฿ฟใาธ.ฦ&ว?\๏์ำcAP†bญc"๒?W|๛Kทญใพฝ๖w ีพ้๔ศ^{_|๙๚ฬฏฮ๕‰Sg>฿mฒำ๓ซท’˜ุืย๊บ5ืหcฯa์าแฆBฟ>ฐ๙†ํ฿๋ว5ณ๒•gฮ๎žp๔ศ#‰"๕ส=—฿tข๖†๊Z–ํ๚ถ1#ฮฃtฏฅหT๋ัง'๔้[ifjถ#—Mt6ืิ4m2nล่*ท๖ŠสังG้w›=ผใb!$ๅสถ ํ‡๔0ร`@(‹๋฿โXตlYแมี๑wฎ>ฎ๋ฑฝ[ํ +๗โn]}Tีตe…ผŠเ˜Z˜r !„ะั‘ัiืฦXr)อถ[?ลฦฦ+๔PU๎น”ฎพ^fี<_SO/ณ’โ๑yด๔G์Gธ•ชTRห๚ซ%๗9.Wš.รšž~<†Ž?ต$ืcH๛ผZ(Œน๓Vฏi“g๎ผ…ชn(บิ‹š[ 6_ดrmaRฑeKใ็ถจืขUmn>งd†O\ณ fยq ›…IำE]‘Zไ่๏ฃ2#A:*"Š517แŠขห\—Fอvw;๗\ทํฒiฟม-ฐy์›3{†›[ซฌ—nnญๆฬžกย๖€Œข#ิป5M>ผ๚ฐf‹V•8Zฎอฤ{Nˆ]๒ 8‘kคs๐ขั๋oผOง{เุข~ŸLVจา?9๗้‹-ำื฿‹MOปฟqฺฦw.}ปXr8๚Fิ๛!IY}€ห>รรVต$จŽืภฏ ฦๅrื๘ญฌ[ืžRทฎฟ•\n~ฟ'€๒(<ญA่โๆ N6wตQ#„ืภญ9/Y๊ิ:ฏษ9kจ๊}เ4ำscœ+๊ึj3๎ํ้ํฎญ`๋เLๆฝƒ}๋V๎ฐ‘ผงท‡P†]&Mฐ8ูี”วQw๑{วB(ƒNร{i|Iuาฟ&b”ขกฉฉฑmหฟอ›ปl๒ฏฆฆ†ช›„b?สtุขa?^iv๔ฃอพศ3ทฮŒเ_z็(ฝ†.zo๘๖ๅ}๎ฏU๐œWฝ‰อzลoปํ๓l่6ทoํฬฅบ.ธพเ—4:=Mช~HฏŠ˜ๆ[t ทoQu+เ',๒L!„M ูพ๚คFฟc] 1ีส0ts’qฦห@ฯแŸิA๋gตฤT(ำสtฯ_ฎะyS๏ผ;Aฒป๘›SN`๗6€’ฌL t…วๆ%๛B‘๏;M"+๘ฃ๊ฦ”Sy๗ํถNษํ€ฒ|Jผ<‚ฟมใ”฿P‚<‚ฟทoB•฿PŒ๙(G”#สๅ‚?€rคD์๐ มสชๆ-[ซบ ๐‹B† ฏ๊&@cYห”4%%๘#„ฐ,ซ๊&@‘AุP2aฬ@9‚เ )d๐ว|๔๏๓๖๎<*Š#xubธ๑`Cxูจร bP‘(5KTไR•š/โFI"w๑6J‚‚ฦฤEwทH4‚W"gD* =ฝ€x0 30=็๗๓๘ƒ)ฆซ~U^๓{U]nQYตX PE$H๘ิล๓ษ[—ํlec๑รฮฎฃ,ข2๓ฟ 4ก^8”นณ%ะ-&็’BUัyท/m1kW%ฺ 2าใe฿–…ฉ—0าฺฦvXpฦ]!a๏]้ใ๎:ฬมร7๒ณ๏4Bskใิแa)[N๗qถswธ๑ึ–`;ฟ]a8้ˆัใพฺใื๎[ไจ็๕ููา’โk™3_!ๅ๛’b7—’s๒๒๙ฌŽE+็mผิา๖eA‘b็ๅ™็.ฌŸจ#ซะ@Z“?aูŽ๐กm๗ ‘˜ื"aEฬํร{.Xวฌs3ืำ๊k๎็[ไpq+!„>๖a ม๖ฆ:4!„๗ZLfัO๏ู๓dื Œ๗ %ชHX]Q|>ูำ>นฃˆzษฟถํ`ฺl€)’=…๋อพŠขžพ“6hฆ็™˜ท!เ…mมํ๗๖ฝธWไฏo๘  Œ ฉป%7 !„g59ฤฅ(ฃส š๋หฎMOL;ฺะ๙0>ฅษeไ=;|`ผื๙vร‚3๎‹ ฯ7ลšžH๒r1iๆวนฬฤ~ฒ‹zํ๙e_ส8p[Aเ _ก-ข2๓ฃ:N(#๗๙y๓Ÿ~ำภ6(ykP๒๓‡๓^‹หฮ๎sLfQŒ,b)๕bๆT ’? ‚ไ@ƒ ๙ะ H4Ho๒,c7Kฏ*:5ง,ษ_ว›B ณ_›'“z”"๙๓๋i?€ฎP”ฬ”ซษˆ!แฉ$9"’?ะํ2ฉ„๋ยุํ  Ah$Dฤ=ฒฺH ะญศ9 ฐั@rงNŸ+พ๚ณ%ถกฃ%ฏA๔†ศ9 z€พ๚…ขCP1ฃFŽ˜’าาถ|>?<"โัร๚{VJXC—ป}1 lhšใแ๘ธฑฌฌาา244๔๑ใษ3?‚{TKŸ>”Z|โb EยŸnkรฬจ˜~๚):น๚vฉ kC๒ช;…9‚ภE *ผ์+ฌ๊4{ฯŸฌขQ ยฒฏ‚ขฒj1š๊M…“?V“?ๆฦฆ้C‡ผ“s_ๅ็Šุบฌhืฑ)ฟถrT?sgK [Lฮู[—ํleckecgรws๗‹Zต•?ภกž&‚+๛ิ๛Lฑฟผ๏ว2้)ฒE[ฬฺ๕[Iัo…นggๅขEŒขCๅีรไฏ๑l๖ฯ๚๑หขวWฬพ$`nmœ:๙jqฐณณณWdสฑ๊ถ6Zห}2หฯีลe\๘ฒ์าฆvฟ“ฎšfส฿–4ๅ w[G๏เล/ึvสึ…ำ}œํฌ๙“S/5`คตํฐเŒปไสดถ‰ํ”ทF่T”l$ล&๒\<ใaNฌ‹•ญ๕๛QsาNT>9รlๅหข|GบฺนŸฑ"็z#eC ”zด—ญหห:7,4~๐KFaำดูk์27๖ฟ ๒,Xดี|๚ทฝห฿yoษ€›‚uQn^น/)v“ึœต9้NF๕็7ฟŸ8oฃE๖{Žผ็‚uLn˜ š=ธ8฿ซฯst „hนD$Lๅ›ะ„ุM๓sXŸ]R-๔๓%sำ‡Rฤpิป‰g฿แX๖๔ฝW]ฃm๙๊ ็nWn–^…Žทv๛Me&y/d๕ถGน5 ๔qไ์•ฺGา&tG!EQ„ใY(Zวฬ6๘ฃE๙“—ฏษ™ด=ศœ›ศs๔t(…wฟ[ฑ2ŸŸถ=uไ+ฦ}้๊oข|`YB่๛ทœผS%$–O๓ฟ.ฅ$๕††3๛ ว ~:ซฅใไแz+็ษถึ’ฬu; ๏77ื^ฺ๓๙7w]zณmฆHDน–ีไ—ข๔v_({(hฎ/ปr4=1ํhC—M๓ฌ|'Y]šzจด^๐ธ๒†ฌW๒'8ณฝดCฟีฬYš"-ย“0~ฺภุบ[rใวัRฦ^๏DผzqŽ‹ลวึี9jวถ45 ๛่่้้iต/สYปณฐํ!8ผม“ฆป–ผๅิ›U|ท๊ห_š$.ฑ,{ๆ์น6ฉ8gฮ^rถP(\ต๚S๙ด QVญT(TุำRคLฺุผฌใฌ๛hณ3†}‡{:Wศ*h"„-7?ง+ ts๑žฝ[ถ:่ๅถ&D•ำAŸoŠ5=‘ไๅ8bาฬs™‰b^สณžฝnีธช AฃGŒ ๙ฒjไ{yฝNk๘ดรณk็Lvuฒฉึg๕โ˜Q’ฦOyฯ˜7๏uพwป} !„๐วLx|pรมJกธุบ:GOjym๚‡ฑว๛99 \๕ซตงฃV่WBึmˆ3?›0ึu\TZฑญฏซŽิ'QึZ[[ๆ็JัUณƒไืชโ\)บzโไูึVฎžJูกฉฉi‚„ปธn@ํศุ5ABS“์[" )ณ'สฤ?Œ‹…†ฮ๙B˜[„P๚aŸ/›๙H‘ๅ”mP๒ึ ไ็Kyฏลe็?จึๆยทฺ~ีzลg้NŸฅš']๘ขQฦ ปiฺ#:ล#บำก’ฤO(#๗๙y๓e๋ อ?y[กW๊ฉsํDฦFˆ่sA[DeๆG=‰wD\๚ฯqOqค‘SDJFDส๓ีuู็ššš~ส=๖็Ÿ๗!†F&5๗ช„]ฟ^า๐จม๛MO๎ฟ#uuusๆพ[Xx‰ฃ๚ ๗H^uDิึอ้ฦฦฦrnฏwvฟ'2?MSV^~๚l>วีžขคE‹‘๙pญฐ๐Rา"ฮ๗๖v†ไT˜ืุ1/+: ฐดด 0ˆซพงฅ~๊ไไศQๅะฦษษ1-UทVห๔ฆน—;ป+๙Sฏsกซซ;q‚๗ษำฎ]ปฆ่XไวฮฮnฦŒ ำZU๑GMณ๓ซค…ไมณ]81ื;mํgบบบ๒oZ^;&ธAQ”งว๋๚ŠDN์ํ๘aแแ ซซส9๖ซซซ๛ๅ๋R>Yร]kึฬ๐%พOำŠY€E๒๊ภษ_Wญขฃ‡Q#G<จฏ“ฯึšฆ—-Uภอ(jOฑWW๓jBCถ๚M๊)pAข™?๕xง“๊๖Bu#็ˆไขC'ท^จวpHEฏฑ'ฅฏํR^จnไ‘|@ิc่ไึ ๕.ฉhๆ5ถ๛ไ๏FIฑโเš๊๖Bu#็B|โโ๘D…&{XะLA‹š5$ l๘U๒๛ํRE‡ ž0ฐš>4ˆ่™ฟฏท~!็8@D$‘sศ?ษ฿อาซ๒ +˜‡ๆ@3aร(5ฬCs  ฑRร<4G0ฐ ป}4’? าพ์๛}ลฦr€™? ๒}Wคp?IENDฎB`‚iverilog-12_0/Documentation/usage/command_files.rst000066400000000000000000000167521435245347300226310ustar00rootroot00000000000000 Command File Format =================== The basic format of a command file is one source file or compiler argument per line. Command files may also have comments of various form, and options for controlling the compiler. Comments -------- Lines that start with a "#" character are comments. All text after the "#" character, is ignored. The "//" character sequence also starts a comment that continues to the end of the line. The "/\*" and "\*/" character sequences surround multi-line comments. All the text between the comment start and comment end sequences is ignored, even when that text spans multiple lines. This style of comment does not nest, so a "/\*" sequence within a multi-line comment is probably an error. Plus-args --------- Outside of comments, lines that start with a "+" character are compiler arguments. These are called plusargs but they are not the same as extended arguments passed to the "vvp" command. The supported plusargs are definitively listed in the iverilog manual page. The plusargs lines are generally "++..." where the name is the name of an switch, and the arguments are separated by "+" characters, as in:: +libext+.v+.V+.ver With plusargs lines, the "+" character separates tokens, and not white space, so arguments, which may include file paths, may include spaces. A plusarg line is terminated by the line end. The line in the command file may also be a "-y" argument. This works exactly the same as the:: -y argument to the compiler; it declares a library directory. The "-y" syntax is also a shorthand for the "+libdir" plusarg, which is a more general form:: +libdir+... File Names ---------- Any lines that are not comments, compiler arguments or plusargs are taken by the compiler to be a source file. The path can contain any characters (other then comment sequences) including blanks, although leading and trailing white space characters are stripped. The restriction of one file name per line is in support of operating systems that can name files any which way. It is not appropriate to expect white spaces to separate file names. Variable Substitution --------------------- The syntax "$(name)" is a variable reference, and may be used anywhere within filenames or directory names. The contents of the variable are read from the environment and substituted in place of the variable reference. In Windows, these environment variables are the very same variables that are set through the Control Panel->System dialog box, and in UNIX these variables are environment variables as exported by your shell. Variables are useful for giving command files some installation independence. For example, one can import a vendor library with the line:: -y $(VENDOR)/verilog/library in the command file, and the next programmer will be able to use this command file without editing it to point to the location of VENDOR on his machine. Note the use of forward slashes as a directory separator. This works even under Windows, so always use forward slashes in file paths and Windows and UNIX users will be able to share command files. An Example ---------- This sample:: # This is a comment in a command file. # The -y statement declares a library # search directory -y $(PROJ_LIBRARY)/prims # # This plusarg tells the compiler that # files in libraries may have .v or .vl # extensions. +libext+.v+.vl # main.v // This is a source file # # This is a file name with blanks. C:/Project Directory/file name.vl is a command file that demonstrates the major syntactic elements of command files. It demonstrates the use of comments, variables, plusargs and file names. It contains a lot of information about the hypothetical project, and suggests that command files can be used to describe the project as a whole fairly concisely. The syntax of command files is rich enough that they can be used to document and control the assembly and compilation of large Verilog programs. It is not unusual to have command files that are hundreds of lines long, although judicious use of libraries can lead to very short command files even for large designs. It is also practical to have different command files that pull together combinations of sources and compiler arguments to make different designs from the same Verilog source files. Summary ------- Given the above description of the command file format, the following is a list of the special records with their meaning. * +libdir+*dir-path* Specify directories to be searched for library modules. The *dir-path* can have multiple directories, separated by "+" characters. * +libdir-nocase+dir-path This is the same as "+libdir+", but when searching "nocase" libraries for module files, case will not be taken as significant. This is useful when the library is on a case insensitive file system. * +libext+*suffix-string* Declare the suffix strings to use when searching library directories for Verilog files. The compiler may test a list of suffix strings to support a variety of naming conventions. * -y dir-path This is like "+libdir+" but each line takes only one path. Like "+libdir+" there can be multiple "-y" records to declare multiple library directories. This is similar to the "-y" flag on the iverilog command line. * -v *file-name* or -l *file-name* This declares a library file. A library file is just like any other Verilog source file, except that modules declared within it are not implicitly possible root modules. NOTE: The "-l" alias is new as of 2 October 2016. It will become available in releases and snapshots made after that date. * +incdir+*include-dir-path* Declare a directory or list of directories to search for files included by the "include" compiler directive. The directories are searched in order. This is similar to the "-I" flag on the iverilog command line. * +define+*name=value* Define the preprocessor symbol "name" to have the string value "value". If the value (and the "=") are omitted, then it is assumed to be the string "1". This is similar to the "-D" on the iverilog command line. * +timescale+*units/precision* Define the default timescale. This is the timescale that is used if there is no other timescale directive in the Verilog source. The compiler default default is "+timescale+1s/1s", which this command file setting can change. The format of the units/precision is the same as that for the timescale directive in the verilog source. * +toupper-filename This token causes file names after this in the command file to be translated to uppercase. this helps with situations where a directory has passed through a DOS machine (or a FAT file system) and in the process the file names become munged. This is not meant to be used in general, but only in emergencies. * +tolower-filename The is the lowercase version of "+toupper-filename". * +parameter+*name=value* This token causes the compiler to override a parameter value for a top-level module. For example, if the module main has the parameter WIDTH, set the width like this "+parameter+main.WIDTH=5". Note the use of the complete hierarchical name. This currently only works for parameters defined in root (top level) modules and a defparam may override the command file value. * +vhdl-work+*path* When compiling VHDL, this token allows control over the directory to use for holding working package declarations. For example, "+vhdl-work+workdir" will cause the directory "workdir" to be used as a directory for holding working working copies of package headers. iverilog-12_0/Documentation/usage/command_line_flags.rst000066400000000000000000000374721435245347300236340ustar00rootroot00000000000000 iverilog Command Line Flags =========================== The iverilog command is the compiler/driver that takes the Verilog input and generates the output format, whether the simulation file or synthesis results. This information is at least summarized in the iverilog man page distributed in typical installations, but here we try to include more detail. General ------- These flags affect the general behavior of the compiler. * -c This flag selects the command file to use. The command file is an alternative to writing a long command line with a lot of file names and compiler flags. See the Command File Format page for more information. * -d Enable compiler debug output. These are aids for debugging Icarus Verilog, and this flag is not commonly used. The flag is one of these debug classes: * scope * eval_tree * elaborate * synth2 * -g the generation is the compiler language, and specifies the language and extensions to use during the compile. The language level can be selected by a major level selector, and by controlling various features. Various "-g" flags can be compined. For example, to get Verilog 2001 without specify supoprt, use "-g2001 -gno-specify". The supported flags are: * 1995 This flag enables the IEEE1364-1995 standard. * 2001 This flag enables the IEEE1364-2001 standard. * 2001-noconfig This flag enables the IEEE1364-2001 standard with config file support disabled. This eliminates the config file keywords from the language and so helps some programs written to older 2001 support compile. * 2005 This flag enables the IEEE1364-2005 standard. This is default enabled after v0.9. * 2009 This flag enables the IEEE1800-2009 standard, which includes SystemVerilog. The SystemVerilog support is not present in v0.9 and earlier. It is new to git master as of November 2009. Actual SystemVerilog support is ongoing. * 2012 This flag enables the IEEE1800-2012 standard, which includes SystemVerilog. * verilog-ams This flag enables Verilog-AMS features that are supported by Icarus Verilog. (This is new as of 5 May 2008.) * assertions/supported-assertions/no-assertions Enable or disable SystemVerilog assertions. When enabled, assertion statements are elaborated. When disabled, assertion statements are parsed but ignored. The supported-assertions option only enables assertions that are currently supported by the compiler. * specify/no-specify Enable or disable support for specify block timing controls. When disabled, specify blocks are parsed but ignored. When enabled, specify blocks cause timing path and timing checks to be active. * std-include/no-std-include Enable or disable the search of a standard installation include directory after all other explicit include directories. This standard include directory is a convenient place to install standard header files that a Verilog program may include. * relative-include/no-relative-include Enable or disable adding the local files directory to the beginning of the include file search path. This allows files to be included relative to the current file. * xtypes/no-xtypes Enable or disable support for extended types. Enabling types allows for new types and type syntax that are Icarus Verilog extensions. * io-range-error/no-io-range-error When enabled the range for a port and any associated net declaration must match exactly. When disabled a scalar port is allowed to have a net declaration with a range (obsolete usage). A warning message will be printed for this combination. All other permutations are still considered an error. * strict-ca-eval/no-strict-ca-eval The standard requires that if any input to a continuous assignment expression changes value, the entire expression is re-evaluated. By default, parts of the expression that do not depend on the changed input value(s) are not re-evaluated. If an expression contains a call to a function that doesn't depend solely on its input values or that has side effects, the resulting behavior will differ from that required by the standard. Enabling strict-ca-eval will force standard compliant behavior (with some loss in performance). * strict-expr-width/no-strict-expr-width Enable or disable strict compliance with the standard rules for determining expression bit lengths. When disabled, the RHS of a parameter assignment is evaluated as a lossless expression, as is any expression containing an unsized constant number, and unsized constant numbers are not truncated to integer width. * shared-loop-index/no-shared-loop-index Enable or disable the exclusion of for-loop control variables from implicit event_expression lists. When enabled, if a for-loop control variable (loop index) is only used inside the for-loop statement, the compiler will not include it in an implicit event_expression list it calculates for that statement or any enclosing statement. This allows the same control variable to be used in multiple processes without risk of entering an infinite loop caused by each process triggering all other processes that use the same variable. For strict compliance with the standards, this behaviour should be disabled. * -i Ignore missing modules. Normally it is an error if a module instantiation refers to an undefined module. This option causes the compiler to skip over that instantiation. It will also stop the compiler returning an error if there are no top level modules. This allows the compiler to be used to check incomplete designs for errors. NOTE: The "-i" flag was added in v11.0. * -L Add the specified directory to the path list used to locate VPI modules. The default path includes only the install directory for the system.vpi module, but this flag can add other directories. Multiple paths are allowed, and the paths will be searched in order. NOTE: The "-L" flag was added in v11.0. * -l Add the specified file to the list of source files to be compiled, but mark it as a library file. All modules contained within that file will be treated as library modules, and only elaborated if they are instantiated by other modules in the design. NOTE: The "-l" flag is new as of 2 October 2016. It will become available in releases and snapshots made after that date. * -M= Write into the file specified by path a list of files that contribute to the compilation of the design. If _mode_ is *all* or *prefix*, this includes files that are included by include directives and files that are automatically loaded by library support as well as the files explicitly specified by the user. If _mode_ is *include*, only files that are included by include directives are listed. If _mode_ is *module*, only files that are specified by the user or that are automatically loaded by library support are listed. The output is one file name per line, with no leading or trailing space. If _mode_ is *prefix*, files that are included by include directives are prefixed by "I " and other files are prefixed by "M ". * -m Add this module to the list of VPI modules to be loaded by the simulation. Many modules can be specified, and all will be loaded, in the order specified. The system module is implicit and always included (and loaded last). If the specified name includes at least one directory character, it is assumed to be prefixed by the path to the module, otherwise the module is searched for in the paths specified by preceding -L options, and if not found there, in the iverilog base directory. NOTE: The "-m" flag was added in v11.0. * -o Specify the output file. The is the name of the file to hold the output. The default is "a.out". * -S Activate synthesis. This flag tells the compiler to do what synthesis it can do before calling the code generator. This flag is rarely used explicitly, and certain code generators will implicitly enable this flag. * -u Treat each source file as a separate compilation unit (as defined in SystemVerilog). If compiling for an IEEE1364 generation, this will just reset all compiler directives (including macro definitions) before each new file is processed. NOTE: The "-u" flag was added in v11.0. * -v Be verbose. Print copyright information, progress messages, and some timing information about various compilation phases. (New in snapshots after 2014-12-16) If the selected target is vvp, the -v switch is appended to the shebang line in the compiler output file, so directly executing the compiler output file will turn on verbose messages in vvp. This extra verbosity can be avoided by using the vvp command to indirectly execute the compiler output file. * -V Print the version information. This skips all compilation. Just print the version information, including version details for the various components of the compiler. * -R Print the runtime paths of the compiler. This can be useful to find, e.g., the include path of vpi_user.h. * -W Enable/disable warnings. All the warning types (other then "all") can be prefixed with no- to disable that warning. * all This enables almost all of the available warnings. More specifically, it enables these warnings:: -Wanachronisms -Wimplicit -Wimplicit-dimensions -Wmacro-replacement -Wportbind -Wselect-range -Wtimescale -Wsensitivity-entire-array * anachronisms This enables warnings for use of features that have been deprecated or removed in the selected generation of the Verilog language. * implicit This enables warnings for creation of implicit declarations. For example, if a scalar wire X is used but not declared in the Verilog source, this will print a warning at its first use. * implicit-dimensions This enables warnings for the case where a port declaration or a var/net declaration for the same name is missing dimensions. Normally, Verilog allows you to do this (the undecorated declaration gets its dimensions form the decorated declaration) but this is no longer common, and some other tools (notable Xilix synthesizers) do not handle this correctly. This flag is supported in release 10.1 or master branch snapshots after 2016-02-06. * macro-redefinition This enables warnings when a macro is redefined, even if the macro text remains the same. NOTE: The "macro-redefinition" flag was added in v11.0. * macro-replacement This enables warnings when a macro is redefined and the macro text changes. Use no-macro-redefinition to disable this, NOTE: The "macro-replacement" flag was added in v11.0. * portbind This enables warnings for ports of module instantiations that are not connected properly, but probably should be. Dangling input ports, for example, will generate a warning. * select-range This enables warnings for constant out-of-bound selects. This includes partial or fully out-of-bound select as well as a select containing a 'bx or 'bz in the index. * timescale This enables warnings for inconsistent use of the timescale directive. It detects if some modules have no timescale, or if modules inherit timescale from another file. Both probably mean that timescales are inconsistent, and simulation timing can be confusing and dependent on compilation order. * infloop This enables warnings for always statements that may have runtime infinite loops (i.e. has paths with zero or no delay). This class of warnings is not included in -Wall and hence does not have a no- variant. A fatal error message will always be printed when the compiler can determine that there will definitely be an infinite loop (all paths have no or zero delay). When you suspect an always statement is producing a runtine infinite loop, use this flag to find the always statements that need to have their logic verified. it is expected that many of the warnings will be false positives, since the code treats the value of all variables and signals as indeterninite. * sensitivity-entire-vector This enables warnings for when a part select with an "always @*" statement results in the entire vector being added to the implicit sensitivity list. Although this behavior is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the vector is large. * sensitivity-entire-array This enables warnings for when a word select with an "always @*" statement results in the entire array being added to the implicit sensitivity list. Although this behavior is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the array is large. * floating-nets This enables warnings for nets that are present but have no drivers. This flag was added in version 11.0 or later (and is in the master branch as of 2015-10-01). * -y Append the directory to the library module search path. When the compiler finds an undefined module, it looks in these directories for files with the right name. * -Y Appends suf to the list of file extensions that are used to resolve an undefined module to a file name. Should be specified before any -y flag. For example, this command:: % iverilog -Y .sv -y sources src.v will try to resolve any undefined module m by looking into the directory sources and checking if there exist files named m.v or m.sv. Preprocessor Flags ------------------ These flags control the behavior of the preprocessor. They are similar to flags for the typical "C" compiler, so C programmers will find them familiar. * -E This flag is special in that it tells the compiler to only run the preprocessor. This is useful for example as a way to resolve preprocessing for other tools. For example, this command:: % iverilog -E -ofoo.v -DKEY=10 src1.v src2.v runs the preprocessor on the source files src1.v and src2.v and produces the single output file foo.v that has all the preprocessing (including header includes and ifdefs) processed. * -D Assign a value to the macro name. The format of this flag is one of:: -Dkey=value -Dkey The key is defined to have the given value. If no value is given, then it is assumed to be "1". The above examples are the same as these defines in Verilog source:: `define key value `define key * -I Append directory to list of directories searched for Verilog include files. The -I switch may be used many times to specify several directories to search, the directories are searched in the order they appear on the command line. Elaboration Flags ----------------- These are flags that pass information to the elaboration steps. * -P= Define a parameter using the defparam behavior to override a parameter values. This can only be used for parameters of root module instances. * -s Specify the top level module to elaborate. Icarus Verilog will by default choose modules that are not instantiated in any other modules, but sometimes that is not sufficient, or instantiates too many modules. If the user specifies one or more root modules with "-s" flags, then they will be used as root modules instead. * -Tmin, -Ttyp, -Tmax Select the timings to use. The Verilog language allows many timings to be specified as three numbers, min:typical:max, but for simulation you need to choose which set to use. The "-Tmin" flag tells the compiler to at elaboration time choose "min" times. The default is "-Ttyp". Target Flags ------------ iverilog-12_0/Documentation/usage/getting_started.rst000066400000000000000000000142451435245347300232130ustar00rootroot00000000000000 Getting Started With Icarus Verilog =================================== Before getting started with actual examples, here are a few notes on conventions. First, command lines and sequences take the same arguments on all supported operating environments, including Linux, Windows and the various Unix systems. When an example command is shown in a figure, the generic prompt character "% " takes the place of whatever prompt string is appropriate for your system. Under Windows, the commands are invoked in a command window. Second, when creating a file to hold Verilog code, it is common to use the ".v" or the ".vl" suffix. This is not a requirement imposed by Icarus Verilog, but a useful convention. Some people also use the suffixes ".ver" or even ".vlg". Examples in this book will use the ".v" suffix. So let us start. Given that you are going to use Icarus Verilog as part of your design process, the first thing to do as a designer is learn how to compile and execute even the most trivial design. For the purposes of simulation, we use as our example the most trivial simulation, a simple Hello, World program. .. code-block:: verilog module hello; initial begin $display("Hello, World"); $finish ; end endmodule Use a text editor to place the program in a text file, hello.v, then compile this program with the command:: % iverilog -o hello hello.v The results of this compile are placed into the file "hello", because the "-o" flag tells the compiler where to place the compiled result. Next, execute the compiled program like so:: % vvp hello Hello, World And there it is, the program has been executed. So what happened? The first step, the "iverilog" command, read and interpreted the source file, then generated a compiled result. The compiled form may be selected by command line switches, but the default is the "vvp" format, which is actually run later, as needed. The "vvp" command of the second step interpreted the "hello" file from the first step, causing the program to execute. The "iverilog" and "vvp" commands are the most important commands available to users of Icarus Verilog. The "iverilog" command is the compiler, and the "vvp" command is the simulation runtime engine. What sort of output the compiler actually creates is controlled by command line switches, but normally it produces output in the default vvp format, which is in turn executed by the vvp program. As designs get larger and more complex, they gain hierarchy in the form of modules that are instantiated within others, and it becomes convenient to organize them into multiple files. A common convention is to write one moderate sized module per file (or group related tiny modules into a single file) then combine the files of the design together during compilation. For example, the counter model in counter.v .. code-block:: verilog module counter(output, clk, reset); parameter WIDTH = 8; output [WIDTH-1 : 0] output; input clk, reset; reg [WIDTH-1 : 0] out; wire clk, reset; always @(posedge clk or posedge reset) if (reset) output <= 0; else output <= output + 1; endmodule // counter and the test bench in counter_tb.v .. code-block:: verilog module test; /* Make a reset that pulses once. */ reg reset = 0; initial begin # 17 reset = 1; # 11 reset = 0; # 29 reset = 1; # 11 reset = 0; # 100 $stop; end /* Make a regular pulsing clock. */ reg clk = 0; always #5 clk = !clk; wire [7:0] value; counter c1 (value, clk, reset); initial $monitor("At time %t, value = %h (%0d)", $time, value, value); endmodule // test are written into different files. The "iverilog" command supports multi-file designs by two methods. The simplest is to list the files on the command line:: % iverilog -o my_design counter_tb.v counter.v % vvp my_design This command compiles the design, which is spread across two input files, and generates the compiled result into the "my_design" file. This works for small to medium sized designs, but gets cumbersome when there are lots of files. Another technique is to use a commandfile, which lists the input files in a text file. For example, create a text file called "file_list.txt" with the files listed one per line:: counter.v counter_tb.v Then compile and execute the design with a command like so:: % iverilog -o my_design -c file_list.txt % vvp my_design The command file technique clearly supports much larger designs simply by saving you the trouble of listing all the source files on the command line. Name the files that are part of the design in the command file and use the "-c" flag to tell iverilog to read the command file as a list of Verilog input files. As designs get more complicated, they almost certainly contain many Verilog modules that represent the hierarchy of your design. Typically, there is one module that instantiates other modules but is not instantiated by any other modules. This is called a root module. Icarus Verilog chooses as roots (There can be more than one root) all the modules that are not instantiated by other modules. If there are no such modules, the compiler will not be able to choose any root, and the designer must use the "-sroot" switch to identify the root module, like this:: % iverilog -s main -o hello hello.v If there are multiple candidate roots, all of them will be elaborated. The compiler will do this even if there are many root modules that you do not intend to simulate, or that have no effect on the simulation. This can happen, for example, if you include a source file that has multiple modules, but are only really interested in some of them. The "-s" flag identifies a specific root module and also turns off the automatic search for other root modules. You can use this feature to prevent instantiation of unwanted roots. As designs get even larger, they become spread across many dozens or even hundreds of files. When designs are that complex, more advanced source code management techniques become necessary. These are described in later chapters, along with other advanced design management techniques supported by Icarus Verilog. iverilog-12_0/Documentation/usage/gtkwave.rst000066400000000000000000000056611435245347300214760ustar00rootroot00000000000000 Waveforms With GTKWave ====================== GTKWave is a VCD waveform viewer based on the GTK library. This viewer support VCD and LXT formats for signal dumps. GTKWAVE is available on github `here `_. Most Linux distributions already include gtkwave prepackaged. .. image:: GTKWave_Example2.png Generating VCD/FST files for GTKWAVE ------------------------------------ Waveform dumps are written by the Icarus Verilog runtime program vvp. The user uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the vvp runtime takes care of the rest. The output is written into the file specified by the $dumpfile system task. If the $dumpfile call is absent, the compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending on runtime flags. The example below dumps everything in and below the test module: .. code-block:: verilog // Do this in your test bench initial begin $dumpfile("test.vcd"); $dumpvars(0,test); end By default, the vvp runtime will generate VCD dump output. This is the default because it is the most portable. However, when using gtkwave, the FST output format is faster and most compact. Use the "-fst" extended argument to activate LXT output. For example, if your compiled output is written into the file "foo.vvp", the command: .. code-block:: console % vvp foo.vvp -fst will cause the dumpfile output to be written in FST format. Absent any specific $dumpfile command, this file will be called dump.fst, which can be viewed with the command: .. code-block:: console % gtkwave dump.fst A Working Example ----------------- First, the design itself: .. code-block:: verilog module counter(out, clk, reset); parameter WIDTH = 8; output [WIDTH-1 : 0] out; input clk, reset; reg [WIDTH-1 : 0] out; wire clk, reset; always @(posedge clk) out <= out + 1; always @reset if (reset) assign out = 0; else deassign out; endmodule // counter Then the simulation file: .. code-block:: verilog module test; /* Make a reset that pulses once. */ reg reset = 0; initial begin $dumpfile("test.vcd"); $dumpvars(0,test); # 17 reset = 1; # 11 reset = 0; # 29 reset = 1; # 5 reset =0; # 513 $finish; end /* Make a regular pulsing clock. */ reg clk = 0; always #1 clk = !clk; wire [7:0] value; counter c1 (value, clk, reset); initial $monitor("At time %t, value = %h (%0d)", $time, value, value); endmodule // test Compile, run, and view waveforms with these commands: .. code-block:: console % iverilog -o dsn counter_tb.v counter.v % vvp dsn % gtkwave test.vcd & Click on the 'test', then 'c1' in the top left box on GTKWAVE, then drag the signals to the Signals box. You will be able to add signals to display, scanning by scope. iverilog-12_0/Documentation/usage/index.rst000066400000000000000000000005441435245347300211300ustar00rootroot00000000000000 Icarus Verilog Usage ==================== This section contains documents to help support developers who contribute to Icarus Verilog. .. toctree:: :maxdepth: 1 installation getting_started simulation command_line_flags command_files verilog_attributes vvp_flags gtkwave vvp_debug vpi ivl_target reporting_issues iverilog-12_0/Documentation/usage/installation.rst000066400000000000000000000136231435245347300225240ustar00rootroot00000000000000 Installation Guide ================== Icarus Verilog may be installed from source code, or from pre-packaged binary distributions. If you don't have need for the very latest, and prepackaged binaries are available, that would be the best place to start. Installation From Source ------------------------ Icarus is developed for Unix-like environments but can also be compiled on Windows systems using the Cygwin environment or MinGW compilers. The following instructions are the common steps for obtaining the Icarus Verilog source, compiling and installing. Note that there are precompiled and/or prepackaged versions for a variety of systems, so if you find an appropriate packaged version, then that is the easiest way to install. The source code for Icarus is stored under the git source code control system. You can use git to get the latest development head or the latest of a specific branch. Stable releases are placed on branches, and in particular v11 stable releases are on the branch "v11-branch" To get the development version of the code follow these steps:: % git config --global user.name "Your Name Goes Here" % git config --global user.email you@yourpublicemail.example.com % git clone https://github.com/steveicarus/iverilog.git The first two lines are optional and are used to tell git who you are. This information is important if/when you submit a patch. We suggest that you add this information now so you don't forget to do it later. The clone will create a directory, named iverilog, containing the source tree, and will populate that directory with the most current source from the HEAD of the repository. Change into this directory using:: % 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 the v11-branch (the branch where the latest v11 patches are) then you checkout that branch with the command:: % 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:: % git pull The git system remembers the repository that it was cloned from, so you don't need to re-enter it when you pull. Finally, configuration files are built by the extra step:: % sh autoconf.sh The source is then compiled as appropriate for your system. See the specific build instructions below for your operation system for what to do next. You will need autoconf and gperf installed in order for the script to work. If you get errors such as:: 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. 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:: --enable-suffix[=suffix] This option allows the user to build Icarus with a default suffix or when provided a user defined suffix. Older stable releases have this flag on by default e.g.(V0.8 by default will build with a "-0.8" suffix). All versions have an appropriate default 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). :: --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 need when checking for basic errors with valgrind. Compiling on Linux/Unix ----------------------- (Note: You will need to install bison, flex, g++ and gcc) This is probably the easiest case. Given that you have the source tree from the above instructions, the compile and install is generally as simple as:: % ./configure % make (su to root) # make install The "make install" typically needs to be done as root so that it can install in directories such as "/usr/local/bin" etc. You can change where you want to install by passing a prefix to the "configure" command:: % ./configure --prefix=/my/special/directory This will configure the source for eventual installation in the directory that you specify. Note that "rpm" packages of binaries for Linux are typically configured with "--prefix=/usr" per the Linux File System Standard. Make sure you have the latest version of flex otherwise you will get an error when parsing lexor.lex. Compiling on Macintosh OS X --------------------------- Since Mac OS X is a BSD flavor of Unix, you can install Icarus Verilog from source using the procedure described above. You need to install the Xcode software, which includes the C and C++ compilers for Mac OS X. The package is available for free download from Apple's developer site. Once Xcode is installed, you can build Icarus Verilog in a terminal window just like any other Unix install. For versions newer than 10.3 the GNU Bison tool (packaged with Xcode) needs to be updated to version 3. :: brew install bison echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile Icarus Verilog is also available through the Homebrew package manager: "brew install icarus-verilog". iverilog-12_0/Documentation/usage/ivl_target.rst000066400000000000000000000100301435245347300221500ustar00rootroot00000000000000 Loadable Target API (ivl_target.h) ================================== 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". iverilog-12_0/Documentation/usage/reporting_issues.rst000066400000000000000000000037321435245347300234270ustar00rootroot00000000000000 Reporting Issues ================ The developers of and contributers to Icarus Verilog use github to track issues and to create patches for the product. If you believe you have found a problem, use the Issues tracker at the `Icarus Verilog github page `_. On the main page, you will find a row of selections near the top. Click the `Issues `_ link to get to the list of issues, open and closed. You will find a friendly green button where you can create a new issue. You will be asked to create a title for your issue, and to write a detailed description of your issue. Please include enough information that anyone who sees your issue can understand and reproduce it. One key characteristic of a well reported issue is a small sample program that demonstrates the issue. The smaller the better. No developer wants to wade through hundreds of lines of working Verilog to find the few lines that cause trouble, so if you can get it down to a 10 line sample program, then your issue will be far more likely to be addressed. Be prepared to have a conversation about your issue. More often then you would expect, the issue turns out to be a bug in your program, and the person looking into your issue may point out a bug in your code. You learn something, and we all win. We are not always correct, though, so if we are incorrect, help us see our error, if that's appropriate. If we don't understand what your issue is, we will label your issue with a "Need info" label, and if we never hear from you again, your issue may be closed summarily. If you can submit a complete, working program that we can use in the regression test suite, then that is the best. Check out the existing tests in the regression test suite to see how they are structured. If you have a complete test that can go into the test suite, then that saves everyone a lot of grief, and again you increase the odds that your issue will be addressed. iverilog-12_0/Documentation/usage/simulation.rst000066400000000000000000000502471435245347300222120ustar00rootroot00000000000000 Simulation Using Icarus Verilog =============================== Simulation is the process of creating models that mimic the behavior of the device you are designing (simulation models) and creating models to exercise the device (test benches). The simulation model need not reflect any understanding of the underlying technology, and the simulator need not know that the design is intended for any specific technology. The Verilog simulator, in fact, is usually a different program than the synthesizer. It may even come from a different vendor. The simulator need not know of or generate netlists for the target technology, so it is possible to write one simulator that can be used to model designs intended for a wide variety of technologies. A synthesizer, on the other hand, does need to know a great deal about the target technology in order to generate efficient netlists. Synthesizers are often technology specific and come from vendors with specialized knowledge, whereas simulators are more general purpose. Simulation models and test benches, therefore, can use the full range of Verilog features to model the intended design as clearly as possible. This is the time to test the algorithms of the design using language that is relatively easy for humans to read. The simulator, along with the test bench, can test that the clearly written model really does behave as intended, and that the intended behavior really does meet expectations. The test benches model the world outside the design, so they are rarely destined for real hardware. They are written in Verilog simply as a matter of convenience, and sometimes they are not written in Verilog at all. The test benches are not throw-away code either, as they are used to retest the device under test as it is transformed from a simulation model to a synthesizeable description. Compilation and Elaboration --------------------------- Simulation of a design amounts to compiling and executing a program. The Verilog source that represents the simulation model and the test bench is compiled into an executable form and executed by a simulation engine. Internally, Icarus Verilog divides the compilation of program source to an executable form into several steps, and basic understanding of these steps helps understand the nature of failures and errors. The first step is macro preprocessing, then compilation, elaboration, optional optimizations and finally code generation. The boundary between these steps is often blurred, but this progression remains a useful model of the compilation process. The macro preprocessing step performs textual substitutions of macros defined with "\`define" statements, textual inclusion with "\`include" statements, and conditional compilation by "\`ifdef" and "\`ifndef" statements. The macropreprocessor for Icarus Verilog is internally a separate program that can be accessed independently by using the "-E" flag to the "iverilog" command, like so:: % iverilog -E -o out.v example.v This command causes the input Verilog file "example.v" to be preprocessed, and the output, a Verilog file without preprocessor statements, written into "out.v". The "\`include" and "\`ifdef" directives in the input file are interpreted, and defined macros substituted, so that the output, a single file, is the same Verilog but with the preprocessor directives gone. All the explicitly specified source files are also combined by the preprocessor, so that the preprocessed result is a single Verilog stream. Normally, however, the "-E" flag is not used and the preprocessed Verilog is instead sent directly to the next step, the compiler. The compiler core takes as input preprocessed Verilog and generates an internal parsed form. The parsed form is an internal representation of the Verilog source, in a format convenient for further processing, and is not accessible to the user. The next step, elaboration, takes the parsed form, chooses the root modules, and instantiates (makes *instances* of) those roots. The root instances may contain instances of other modules, which may in turn contain instances of yet other modules. The elaboration process creates a hierarchy of module instances that ends with primitive gates and statements. Note that there is a difference between a module and a module instance. A module is a type. It is a description of the contents of module instances that have its type. When a module is instantiated within another module, the module name identifies the type of the instance, and the instance name identifies the specific instance of the module. There can be many instances of any given module. Root modules are a special case, in that the programmer does not give them instance names. Instead, the instance names of root modules are the same as the name of the module. This is valid because, due to the nature of the Verilog syntax, a module can be a root module only once, so the module name itself is a safe instance name. Elaboration creates a hierarchy of scopes. Each module instance creates a new scope within its parent module, with each root module starting a hierarchy. Every module instance in the elaborated program has a unique scope path, a hierarchical name, that starts with its root scope and ends with its own instance name. Every named object, including variables, parameters, nets and gates, also has a hierarchical name that starts with a root scope and ends with its own base name. The compiler uses hierarchical names in error messages generated during or after elaboration, so that erroneous items can be completely identified. These hierarchical names are also used by waveform viewers that display waveform output from simulations. The elaboration process creates from the parsed form the scope hierarchy including the primitive objects within each scope. The elaborated design then is optimized to reduce it to a more optimal, but equivalent design. The optimization step takes the fully elaborated design and transforms it to an equivalent design that is smaller or more efficient. These optimizations are, for example, forms of constant propagation and dead code elimination. Useless logic is eliminated, and constant expressions are pre-calculated. The resulting design behaves as if the optimizations were not performed, but is smaller and more efficient. The elimination (and spontaneous creation) of gates and statements only affects the programmer when writing VPI modules, which through the API have limited access to the structures of the design. Finally, the optimized design, which is still in an internal form not accessible to users, is passed to a code generator that writes the design into an executable form. For simulation, the code generator is selected to generate the vvp format--a text format that can be executed by the simulation engine. Other code generators may be selected by the Icarus Verilog user, even third party code generators, but the vvp code generator is the default for simulation purposes. Making and Using Libraries -------------------------- Although simple programs may be written into a single source file, this gets inconvenient as the designs get larger. Also, writing the entire program into a single file makes it difficult for different programs to share common code. It therefore makes sense to divide large programs into several source files, and to put generally useful source code files somewhere accessible to multiple designs. Once the program is divided into many files, the compiler needs to be told how to find the files of the program. The simplest way to do that is to list the source files on the command line or in a command file. This is for example the best way to divide up and integrate test bench code with the simulation model of the device under test. The Macro Preprocessor ^^^^^^^^^^^^^^^^^^^^^^ Another technique is to use the macro preprocessor to include library files into a main file. The `include` directive takes the name of a source file to include. The preprocessor inserts the entire contents of the included file in place of the `include` directive. The preprocessor normally looks in the current working directory (the current working directory of the running compiler, and not the directory where the source file is located) for the included file, but the "-I" switch to "iverilog" can add directories to the search locations list. :: % iverilog -I/directory/to/search example.v It is common to create include directories shared by a set of programs. The preprocessor `include` directive can be used by the individual programs to include the source files that it needs. The preprocessor method of placing source code into libraries is general (arbitrary source code can be placed in the included files) but is static, in the sense that the programmer must explicitly include the desired library files. The automatic module library is a bit more constrained, but is automatic. Automatic Module Libraries ^^^^^^^^^^^^^^^^^^^^^^^^^^ A common use for libraries is to store module definitions that may be of use to a variety of programs. If modules are divided into a single module per file, and the files are named appropriately, and the compiler is told where to look, then the compiler can automatically locate library files when it finds that a module definition is missing. For this to work properly, the library files must be Verilog source, they should contain a single module definition, and the files must be named after the module they contain. For example, if the module "AND2" is a module in the library, then it belongs in a file called "AND2.v" and that file contains only the "AND2" module. A library, then, is a directory that contains properly named and formatted source files. :: % iverilog -y/library/to/search example.v The "-y" flag to "iverilog" tells the compiler to look in the specified directory for library modules whenever the program instantiates a module that is not otherwise defined. The programmer may include several "-y" flags on the command line (or in a command file) and the compiler will search each directory in order until an appropriate library file is found to resolve the module. Once a module is defined, either in the program or by reading a library module, the loaded definition is used from then on within the program. If the module is defined within a program file or within an included file, then the included definition is used instead of any library definition. If a module is defined in multiple libraries, then the first definition that the compiler finds is used, and later definitions are never read. Icarus Verilog accesses automatic libraries during elaboration, after it has already preprocessed and parsed the non-library source files. Modules in libraries are not candidates for root modules, and are not even parsed unless they are instantiated in other source files. However, a library module may reference other library modules, and reading in a library module causes it to be parsed and elaborated, and further library references resolved, just like a non-library module. The library lookup and resolution process iterates until all referenced modules are resolved, or known to be missing from the libraries. The automatic module library technique is useful for including vendor or technology libraries into a program. Many EDA vendors offer module libraries that are formatted appropriately; and with this technique, Icarus Verilog can use them for simulation. Advanced Command Files ---------------------- Command files were mentioned in the "Getting Started" chapter, but only briefly. In practice, Verilog programs quickly grow far beyond the usefulness of simple command line options, and even the macro preprocessor lacks the flexibility to combine source and library modules according to the advancing development process. The main contents of a command file is a list of Verilog source files. You can name in a command file all the source files that make up your design. This is a convenient way to collect together all the files that make up your design. Compiling the design can then be reduced to a simple command line like the following:: % iverilog -c example.cf The command file describes a configuration. That is, it lists the specific files that make up your design. It is reasonable, during the course of development, to have a set of different but similar variations of your design. These variations may have different source files but also many common source files. A command file can be written for each variation, and each command file lists the source file names used by each variation. A configuration may also specify the use of libraries. For example, different configurations may be implementations for different technologies so may use different parts libraries. To make this work, command files may include "-y" statements. These work in command files exactly how they work on "iverilog" command line. Each "-y" flag is followed by a directory name, and the directories are searched for library modules in the order that they are listed in the command file. The include search path can also be specified in configuration files with "+incdir+" tokens. These tokens start with the "+incdir+" string, then continue with directory paths, separated from each other with "+" characters (not spaces) for the length of the line. Other information can be included in the command file. See the section Command File Format for complete details on what can go in a command file. Input Data at Runtime --------------------- Often, it is useful to compile a program into an executable simulation, then run the simulation with various inputs. This requires some means to pass data and arguments to the compiled program each time it is executed. For example, if the design models a micro-controller, one would like to run the compiled simulation against a variety of different ROM images. There are a variety of ways for a Verilog program to get data from the outside world into the program at run time. Arguments can be entered on the command line, and larger amounts of data can be read from files. The simplest method is to take arguments from the command line. Consider this running example of a square root calculator .. code-block:: verilog module sqrt32(clk, rdy, reset, x, .y(acc)); input clk; output rdy; input reset; input [31:0] x; output [15:0] acc; // acc holds the accumulated result, and acc2 is // the accumulated square of the accumulated result. reg [15:0] acc; reg [31:0] acc2; // Keep track of which bit I'm working on. reg [4:0] bitl; wire [15:0] bit = 1 << bitl; wire [31:0] bit2 = 1 << (bitl << 1); // The output is ready when the bitl counter underflows. wire rdy = bitl[4]; // guess holds the potential next values for acc, // and guess2 holds the square of that guess. wire [15:0] guess = acc | bit; wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1); task clear; begin acc = 0; acc2 = 0; bitl = 15; end endtask initial clear; always @(reset or posedge clk) if (reset) clear; else begin if (guess2 <= x) begin acc <= guess; acc2 <= guess2; end bitl <= bitl - 1; end endmodule One could write the test bench as a program that passes a representative set of input values into the device and checks the output result. However, we can also write a program that takes on the command line an integer value to be used as input to the device. We can write and compile this program, then pass different input values on the run time command line without recompiling the simulation. This example demonstrates the use of the "$value$plusargs" to access command line arguments of a simulation .. code-block:: verilog module main; reg clk, reset; reg [31:0] x; wire [15:0] y; wire rdy; sqrt32 dut (clk, rdy, reset, x, y); always #10 clk = ~clk; initial begin clk = 0; reset = 1; if (! $value$plusargs("x=%d", x)) begin $display("ERROR: please specify +x= to start."); $finish; end #35 reset = 0; wait (rdy) $display("y=%d", y); $finish; end // initial begin endmodule // main The "$value$plusargs" system function takes a string pattern that describes the format of the command line argument, and a reference to a variable that receives the value. The "sqrt_plusargs" program can be compiled and executed like this:: % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v % vvp sqrt_plusargs.vvp +x=81 y= 9 Notice that the "x=%d" string of the "$value$plusargs" function describes the format of the argument. The "%d" matches a decimal value, which in the sample run is "81". This gets assigned to "x" by the "$value$plusargs" function, which returns TRUE, and the simulation continues from there. If two arguments have to be passed to the testbench then the main module would be modified as follows .. code-block:: verilog module main; reg clk, reset; reg [31:0] x; reg [31:0] z; wire [15:0] y1,y2; wire rdy1,rdy2; sqrt32 dut1 (clk, rdy1, reset, x, y1); sqrt32 dut2 (clk, rdy2, reset, z, y2); always #10 clk = ~clk; initial begin clk = 0; reset = 1; if (! $value$plusargs("x=%d", x)) begin $display("ERROR: please specify +x= to start."); $finish; end if (! $value$plusargs("z=%d", z)) begin $display("ERROR: please specify +z= to start."); $finish; end #35 reset = 0; wait (rdy1) $display("y1=%d", y1); wait (rdy2) $display("y2=%d", y2); $finish; end // initial begin endmodule // main and the "sqrt_plusargs" program would be compiled and executed as follows:: % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v % vvp sqrt_plusargs.vvp +x=81 +z=64 y1= 9 y2= 8 In general, the "vvp" command that executes the compiled simulation takes a few predefined argument flags, then the file name of the simulation. All the arguments after the simulation file name are extended arguments to "vvp" and are passed to the executed design. Extended arguments that start with a "+" character are accessible through the "$test$plusargs" and "$value$plusargs" system functions. Extended arguments that do not start with a "+" character are only accessible to system tasks and functions written in C using the VPI. In the previous example, the program pulls the argument from the command line, assigns it to the variable "x", and runs the sqrt device under test with that value. This program can take the integer square root of any single value. Of course, if you wish to test with a large number of input values, executing the program many times may become tedious. Another technique would be to put a set of input values into a data file, and write the test bench to read the file. We can then edit the file to add new input values, then rerun the simulation without compiling it again. The advantage of this technique is that we can accumulate a large set of test input values, and run the lot as a batch. This example .. code-block:: verilog module main; reg clk, reset; reg [31:0] data[4:0]; reg [31:0] x; wire [15:0] y; wire rdy; sqrt32 dut (clk, rdy, reset, x, y); always #10 clk = ~clk; integer i; initial begin /* Load the data set from the hex file. */ $readmemh("sqrt.hex", data); for (i = 0 ; i <= 4 ; i = i + 1) begin clk = 0; reset = 1; x = data[i]; #35 reset = 0; wait (rdy) $display("y=%d", y); end $finish; end // initial begin endmodule // main demonstrates the use of "$readmemh" to read data samples from a file into a Verilog array. Start by putting into the file "sqrt.hex" the numbers:: 51 19 1a 18 1 Then run the simulation with the command sequence:: % iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl % vvp sqrt_readmem.vvp y= 9 y= 5 y= 5 y= 4 y= 1 It is easy enough to change this program to work with larger data sets, or to change the "data.hex" file to contain different data. This technique is also common for simulating algorithms that take in larger data sets. One can extend this idea slightly by using a "$value$plusargs" statement to select the file to read. iverilog-12_0/Documentation/usage/verilog_attributes.rst000066400000000000000000000022001435245347300237250ustar00rootroot00000000000000 Verilog Attributes ================== This is a description of the various attributes that the Icarus Verilog tools understand. The attributes are attached to objects using the "(\* ... \*)" syntax, which is described by the Verilog LRM. Attributes that start with "ivl\_" are Icarus Verilog specific are are probably ignored by other tools. Optimizations ------------- * ivl_do_not_elide (snapshot 20140619 or later) This applies to signals (i.e. reg, wire, etc.) and tells the optimizer to not elide the signal, even if it is not referenced anywhere in the design. This is useful if the signal is for some reason only accessed by VPI/PLI code. Synthesis --------- * ivl_synthesis_cell Applied to a module definition, this tells the synthesizer that the module is a cell. The synthesizer does not descend into synthesis cells, as they are assumed to be primitives in the target technology. * ivl_synthesis_off Attached to an "always" statement, this tells the synthesizer that the statement is not to be synthesized. This may be useful, for example, to tell the compiler that a stretch of code is test-bench code. iverilog-12_0/Documentation/usage/vpi.rst000066400000000000000000000246161435245347300206250ustar00rootroot00000000000000 Using VPI ========= Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows programmers to write C code that interfaces with Verilog simulations to perform tasks otherwise impractical with straight Verilog. Many Verilog designers, especially those who only use Verilog as a synthesis tool, can safely ignore the entire matter of the PLI (and this chapter) but the designer who wishes to interface a simulation with the outside world cannot escape VPI. The rest of this article assumes some knowledge of C programming, Verilog PLI, and of the compiler on your system. In most cases, Icarus Verilog assumes the GNU Compilation System is the compiler you are using, so tips and instructions that follow reflect that. If you are not a C programmer, or are not planning any VPI modules, you can skip this entire article. There are references at the bottom for information about more general topics. How It Works ------------ The VPI modules are compiled loadable object code that the runtime loads at the user's request. The user commands vvp to locate and load modules with the "-m" switch. For example, to load the "sample.vpi" module:: % vvp -msample foo.vvp The vvp run-time loads the modules first, before executing any of the simulation, or even before compiling the vvp code. Part of the loading includes invoking initialization routines. These routines register with the run-time all the system tasks and functions that the module implements. Once this is done, the run time loader can match names of the called system tasks of the design with the implementations in the VPI modules. (There is a special module, the system.vpi module, that is always loaded to provide the core system tasks.) The simulator run time (The "vvp" program) gets a handle on a freshly loaded module by looking for the symbol "vlog_startup_routines" in the loaded module. This table, provided by the module author and compiled into the module, is a null terminated table of function pointers. The simulator calls each of the functions in the table in order. The following simple C definition defines a sample table:: void (*vlog_startup_routines[])() = { hello_register, 0 }; Note that the "vlog_startup_routines" table is an array of function pointers, with the last pointer a 0 to mark the end. The programmer can organize the module to include many startup functions in this table, if desired. The job of the startup functions that are collected in the startup table is to declare the system tasks and functions that the module provides. A module may implement as many tasks/functions as desired, so a module can legitimately be called a library of system tasks and functions. Compiling VPI Modules --------------------- To compile and link a VPI module for use with Icarus Verilog, you must compile all the source files of a module as if you were compiling for a DLL or shared object. With gcc under Linux, this means compiling with the "-fpic" flag. The module is then linked together with the vpi library like so:: % gcc -c -fpic hello.c % gcc -shared -o hello.vpi hello.o -lvpi This assumes that the "vpi_user.h header file and the libvpi.a library file are installed on your system so that gcc may find them. This is normally the case under Linux and UNIX systems. An easier, the preferred method that works on all supported systems is to use the single command:: % iverilog-vpi hello.c The "iverilog-vpi" command takes as command arguments the source files for your VPI module, compiles them with proper compiler flags, and links them into a vpi module with any system specific libraries and linker flags that are required. This simple command makes the "hello.vpi" module with minimum fuss. A Worked Example ---------------- Let us try a complete, working example. Place the C code that follows into the file hello.c:: # include static int hello_compiletf(char*user_data) { return 0; } static int hello_calltf(char*user_data) { vpi_printf("Hello, World!\n"); return 0; } void hello_register() { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$hello"; tf_data.calltf = hello_calltf; tf_data.compiletf = hello_compiletf; tf_data.sizetf = 0; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])() = { hello_register, 0 }; and place the Verilog code that follows into hello.v:: module main; initial $hello; endmodule Next, compile and execute the code with these steps:: % iverilog-vpi hello.c % iverilog -ohello.vvp hello.v % vvp -M. -mhello hello.vvp Hello, World! The compile and link in this example are conveniently combined into the "iverilog-vpi" command. The "iverilog" command then compiles the "hello.v" Verilog source file to the "hello.vvp" program. Next, the "vvp" command demonstrates the use of the "-M" and "-m" flags to specify a vpi module search directory and vpi module name. Specifically, they tell the "vvp" command where to find the module we just compiled. The "vvp" command, when executed as above, loads the "hello.vpi" module that it finds in the current working directory. When the module is loaded, the vlog_startup_routines table is scanned, and the "hello_register" function is executed. The "hello_register" function in turn tells "vvp" about the system tasks that are included in this module. After the modules are all loaded, the "hello.vvp" design file is loaded and its call to the "$hello" system task is matched up to the version declared by the module. While "vvp" compiles the "hello.vvp" source, any calls to "$hello" are referred to the "compiletf" function. This function is called at compile time and can be used to check parameters to system tasks or function. It can be left empty like this, or left out completely. The "compiletf" function can help performance by collecting parameter checks in compile time, so they do not need to be done each time the system task is run, thus potentially saving execution time overall. When the run-time executes the call to the hello system task, the "hello_calltf" function is invoked in the loaded module, and thus the output is generated. The "calltf" function is called at run time when the Verilog code actually executes the system task. This is where the active code of the task belongs. System Function Return Types ---------------------------- Icarus Verilog supports system functions as well as system tasks, but there is a complication. Notice how the module that you compile is only loaded by the "vvp" program. This is mostly not an issue, but elaboration of expressions needs to keep track of types, so the main compiler needs to know the return type of functions. Starting with Icarus Verilog v11, the solution is quite simple. The names and locations of the user's VPI modules can be passed to the compiler via the "iverilog" -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment variable. The compiler will load and analyse the specified modules to automatically determine any function return types. The compiler will also automatically pass the names and locations of the specified modules to the "vvp" program, so that they don't need to be specified again on the "vvp" command line. For Icarus Verilog versions prior to v11, the solution requires that the developer of a module include the table in a form that the compiler can read. The System Function Table file carries this information. A simple example looks like this:: # Example sft declarations of some common functions $random vpiSysFuncInt $bitstoreal vpiSysFuncReal $realtobits vpiSysFuncSized 64 unsigned This demonstrates the format of the file and support types. Each line contains a comment (starts with "#") or a type declaration for a single function. The declaration starts with the name of the system function (including the leading "$") and ends with the type. The supported types are: * vpiSysFuncInt * vpiSysFuncReal * vpiSysFuncSized Any functions that do not have an explicit type declaration in an SFT file are implicitly taken to be "vpiSysFuncSized 32 unsigned". The module author provides, along with the ".vpi" file that is the module, a ".sft" that declares all the function return types. For example, if the file is named "example.sft", pass it to the "iverilog" command line or in the command file exactly as if it were an ordinary source file. Cadence PLI 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. In addition, a 64-bit version of vvp can only load 64-bit PLI1 applications, etc. 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. Other References ---------------- Since the above only explains how to get PLI/VPI working with Icarus Verilog, here are some references to material to help with the common aspects of PLI/VPI. * Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6 * The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X iverilog-12_0/Documentation/usage/vvp_debug.rst000066400000000000000000000106651435245347300220070ustar00rootroot00000000000000Vvp Interactive Mode ==================== The vvp command has an interactive debug mode, where you can stop the simulation and browse the current state of the simulation. There are a couple ways to enter the debug mode, but once in interactive debug mode, the usage is the same. Consider the example below: .. code-block:: verilog module clock(output reg clock); initial clock = 1'b1; always #100 clock = !clock; endmodule // clock module main; reg [2:0] foo; wire clk; clock foo_clock(clk); always @(posedge clk) foo <= foo + 1; initial begin foo = 3'b000; #250 $stop; end endmodule In examples that follow, we will use the above sample program. Enter Interactive Mode ---------------------- The first and most common method is to put "$stop" system task calls in the simulation at the times where you want to simulation to break and enter interactive mode. The example above has a $stop, so the output looks like this:: ../foo.vl:25: $stop called at 250 (1s) ** VVP Stop(0) ** ** Flushing output streams. ** Current simulation time is 250 ticks. > You can get some interactive help by using the "help" command:: > help Commands can be from the following table of base commands, or can be invocations of system tasks/functions. cd - Synonym for push. cont - Resume (continue) the simulation finish - Finish the simulation. help - Get help. list - List items in the current scope. load - Load a VPI module, a la vvp -m. ls - Shorthand for "list". pop - Pop one scope from the scope stack. push - Descend into the named scope. step - Single-step the scheduler for 1 event. time - Print the current simulation time. trace - Control statement tracing (on/off) when the code is instrumented. where - Show current scope, and scope hierarchy stack. If the command name starts with a '$' character, it is taken to be the name of a system task, and a call is built up and executed. For example, "$display foo" will call the function as $display(foo). You can also enter interactive mode at the terminal by interrupting the execution with a "^C" (Control-C) character. The vvp engine catches the terminal interrupt and drops you into the interactive prompt:: ^C** VVP Stop(0) ** ** Flushing output streams. ** Current simulation time is 533928600 ticks. > This could be useful if you suspect that your simulation is stuck in an infinite loop and you want to rummage around and see what's going on. And finally, you can pass the "-s" command line flag to vvp to tell it to execute "$stop" at the beginning of the simulation, before any other events are executed. This may be useful as a way to manually set up some details about the simulation. Browsing the Design ------------------- Now that you are in the interactive prompt, you can browse around the design:: > ls 2 items in this scope: package : $unit module : main > cd main > ls 3 items in this scope: reg : foo[2:0] module : foo_clock net : clk > where module main > $display foo 1 > cd foo_clock > where module foo_clock module main > ls 2 items in this scope: port : clock -- output reg : clock In the above example, the 'cd' and 'pop' commands descend into a scope or pop back up a scope level. The 'where' command shows the scope stack, and the 'ls' command lists the items present in the scope. With these commands, one can browse freely throughout the design scope hierarchy. It is also possible to call system tasks within the debug mode. The call to the "$display" function is an example of this. In general, any system task can be invoked, in the current context, with the objects that are included on the command line passed as arguments. The arguments can be variables or nets, and various kinds of literals:: > ls 2 items in this scope: port : clock -- output reg : clock > $display "Hello, World! " 10 " " clock Hello, World! 10 1 This is a great way to call custom system tasks as well. And system task that vvp knows about can be invoked this way. Leave Interactive Mode ---------------------- After you are done probing around in the interactive mode, you can resume the simulation, or termimate execution. Resume the simulation with the "cont" command, and terminate the simulation with the "finish" command. The latter is the same as executing the "$finish" system task. iverilog-12_0/Documentation/usage/vvp_flags.rst000066400000000000000000000064211435245347300220100ustar00rootroot00000000000000VVP Command Line Flags ====================== The vvp command is the simulation run-time engine. The command line for vvp execution is first the options and flags, then the vvp input file, and finally extended arguments. Typical usage looks like this:: % vvp foo.vvp Options/Flags ------------- These options/flags go before the path to the vvp-executable program. They effect behavior of the vvp runtime engine, including preparation for simulation. * -l This flag specifies a logfile where all MCI output goes. Specify logfile as '-' to send log output to . $display and friends send their output both to and . * -M Add the directory path to the (VPI) module search path. Multiple "-M" flags are allowed, and the directories are added in the order that they are given on the command line. The string "-M-" is special, in that it doesn't add a directory to the path. It instead *removes* the compiled directory. This is generally used only for development of the vvp engine. * -m Name a VPI module that should be loaded. The vvp engine looks for the named module in the module search path, which includes the compiled in default directory and directories given by "-M" flags. NOTE: Starting with v11.0, the VPI modules to be loaded can be specified when you compile your design. This allows the compiler to automatically determine the return types of user-defined system functions. If specified at compile-time, there is no need to specify them again here. * -s $stop right away, in the beginning of the simulation. This kicks the vvp program into interactive debug mode. * -v Show verbose progress while setting up or cleaning up the runtime engine. This also displays some performance information. Extended Arguments ------------------ The extended arguments are available to the simulation runtime, especially system tasks, system functions and any VPI/PLI code. Extended arguments that start with a "+" character are left for use by the user via the $plus$flag and $plus$value functions. VCD/FST/LXT Arguments ^^^^^^^^^^^^^^^^^^^^^ If not otherwise specified, the vvp engine will by default use VCD formats to support the $dumpvars system task. The flags described here can alter that behavior. * -none/-vcd-none/-vcd-off/-fst-none Disable trace output. The trace output will be stubbed so that no trace file is created and the cost of dumping is avoided. All off these options are synonyms for turning of dumping. * -fst Generate FST format outputs instead of VCD format waveform dumps. This is the preferred output format if using GTKWave for viewing waveforms. * -lxt/-lxt2 Generate LXT or LXT2format instead of VCD format waveform dumps. The LXT2 format is more advanced. SDF Support ^^^^^^^^^^^ The Icarus Verilog support for SDF back-annotation can take some extended arguments to control aspects of SDF support. * -sdf-warn Print warnings during load of/annotation from an SDF file. * -sdf-info Print interesting information about an SDF file while parsing it. * -sdf-verbose Print warnings and info messages. Environment Variables --------------------- The vvp program pays attention to certain environment variables. * IVERILOG_DUMPER iverilog-12_0/HName.cc000066400000000000000000000055211435245347300146510ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "config.h" # include "HName.h" # include # include # include using namespace std; hname_t::hname_t() { } hname_t::hname_t(perm_string text) : name_(text) { } hname_t::hname_t(perm_string text, int num) : name_(text), number_(1) { number_[0] = num; } hname_t::hname_t(perm_string text, const vector&nums) : name_(text), number_(nums) { } hname_t::hname_t(const hname_t&that) : name_(that.name_), number_(that.number_) { } hname_t& hname_t::operator = (const hname_t&that) { name_ = that.name_; number_ = that.number_; return *this; } bool hname_t::operator < (const hname_t&r) const { int cmp = strcmp(name_, r.name_); if (cmp < 0) return true; if (cmp > 0) return false; // The text parts are equal, so compare then number // parts. Finish as soon as we find one to be less or more // than the other. size_t idx = 0; while (number_.size() > idx || r.number_.size() > idx) { // Ran out of l numbers, so less. if (number_.size() <= idx) return true; // Ran out of r numbers, so greater. if (r.number_.size() <= idx) return false; if (number_[idx] < r.number_[idx]) return true; if (number_[idx] > r.number_[idx]) return false; idx += 1; } // Fall-through means that we are equal, including all the // number parts, so not less. return false; } bool hname_t::operator == (const hname_t&r) const { if (name_ == r.name_) { if (number_.size() != r.number_.size()) return false; for (size_t idx = 0 ; idx < number_.size() ; idx += 1) if (number_[idx] != r.number_[idx]) return false; return true; } return false; } ostream& operator<< (ostream&out, const hname_t&that) { if (that.peek_name() == 0) { out << ""; return out; } out << that.peek_name(); for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1) out << "[" << that.number_[idx] << "]"; return out; } iverilog-12_0/HName.h000066400000000000000000000060301435245347300145070ustar00rootroot00000000000000#ifndef IVL_HName_H #define IVL_HName_H /* * Copyright (c) 2001-2021 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 # include # include "StringHeap.h" # include /* * This class represents a component of a Verilog hierarchical name. A * hierarchical component contains a name string (represented here * with a perm_string) and an optional signed number. This signed * number is used if the scope is part of an array, for example an * array of module instances or a loop generated scope. */ class hname_t { friend std::ostream& operator<< (std::ostream&out, const hname_t&that); public: hname_t (); explicit hname_t (perm_string text); explicit hname_t (perm_string text, int num); explicit hname_t (perm_string text, const std::vector&nums); hname_t (const hname_t&that); ~hname_t(); hname_t& operator= (const hname_t&); bool operator == (const hname_t&that) const; bool operator < (const hname_t&that) const; // Return the string part of the hname_t. perm_string peek_name(void) const; size_t has_numbers() const; int peek_number(size_t idx) const; const std::vector&peek_numbers() const; private: perm_string name_; // If this vector has size, then the numbers all together make // up part of the hierarchical name. std::vector number_; private: // not implemented }; inline hname_t::~hname_t() { } inline perm_string hname_t::peek_name(void) const { return name_; } inline int hname_t::peek_number(size_t idx) const { assert(number_.size() > idx); return number_[idx]; } inline const std::vector& hname_t::peek_numbers(void) const { return number_; } inline size_t hname_t::has_numbers() const { return number_.size(); } extern std::ostream& operator<< (std::ostream&, const hname_t&); inline bool operator != (const hname_t&l, const hname_t&r) { return ! (l == r); } inline std::ostream& operator<< (std::ostream&out, const std::list&ll) { std::list::const_iterator cur = ll.begin(); out << *cur; ++ cur; while (cur != ll.end()) { out << "." << *cur; ++ cur; } return out; } #endif /* IVL_HName_H */ iverilog-12_0/INSTALL000066400000000000000000000170501435245347300144030ustar00rootroot00000000000000Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. iverilog-12_0/Makefile.in000066400000000000000000000324351435245347300154230ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh # The interesting make targets are: # # make version # Force the version_tag.h file to be rebuilt. Otherwise, it will only # be built if it is missing. # # make all # make install # # The "suffix" is used as an installation suffix. It modifies certain # key install paths/files such that a build and install of Icarus Verilog # with the same $(prefix) but a different $(suffix) will not interfere. # The normal configuration leaves suffix empty suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ datarootdir = @datarootdir@ SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \ tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver # Only run distclean for these directories. NOTUSED = tgt-fpga tgt-pal tgt-verilog ifeq (@MINGW32@,yes) SUBDIRS += driver-vpi else NOTUSED += driver-vpi endif # To get the version headers to build correctly we only want to look # for C++ files in the source directory. All other files will require # an explicit $(srcdir). The one exception to this is if we need to # rebuild the lexor_keyword.cc file. If we do, then we want to use the # local version instead of the one is $(srcdir). vpath lexor_keyword.cc . vpath %.cc $(srcdir)/libmisc vpath %.cc $(srcdir) bindir = @bindir@ libdir = @libdir@ # This is actually the directory where we install our own header files. # It is a little different from the generic includedir. includedir = @includedir@/iverilog$(suffix) mandir = @mandir@ dllib=@DLLIB@ # For a cross compile these defines will need to be set accordingly. HOSTCC = @CC@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ BUILDCC = @CC_FOR_BUILD@ BUILDEXT = @BUILD_EXEEXT@ CXX = @CXX@ DLLTOOL = @DLLTOOL@ INSTALL = @INSTALL@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ YACC = @YACC@ MAN = @MAN@ PS2PDF = @PS2PDF@ GIT = @GIT@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -Ilibmisc else INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc endif CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ PICFLAGS = @PICFLAG@ LDFLAGS = @rdynamic@ @LDFLAGS@ CTARGETFLAGS = @CTARGETFLAGS@ # Source files in the libmisc directory M = LineInfo.o StringHeap.o TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-dll-analog.o FF = cprop.o exposenodes.o nodangle.o synth.o synth2.o syn-rules.o O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \ elab_expr.o elaborate_analog.o elab_lval.o elab_net.o \ elab_scope.o elab_sig.o elab_sig_analog.o elab_type.o \ emit.o eval_attrib.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \ net_design.o netclass.o netdarray.o \ netenum.o netparray.o netqueue.o netscalar.o netstruct.o netvector.o \ net_event.o net_expr.o net_func.o \ net_func_eval.o net_link.o net_modulo.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ pform_disciplines.o pform_dump.o pform_package.o pform_pclass.o \ pform_types.o \ symbol_search.o sync.o sys_funcs.o verinum.o verireal.o vpi_modules.o target.o \ Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PFunction.o \ PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o \ PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT) all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true # In the windows world, the installer will need a dosify program to # dosify text files. ifeq (@MINGW32@,yes) all: dosify$(BUILDEXT) dosify$(BUILDEXT): $(srcdir)/dosify.c $(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c endif # This rule rules the compiler in the trivial hello.vl program to make # sure the basics were compiled properly. check: all $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true test -r check.conf || cp $(srcdir)/check.conf . driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl ifeq (@WIN32@,yes) ifeq (@install_suffix@,) vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World' else # On Windows if we have a suffix we must run the vvp part of # the test with a suffix since it was built/linked that way. ln vvp/vvp.exe vvp/vvp$(suffix).exe vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World' rm vvp/vvp$(suffix).exe endif else vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World' endif clean: $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true rm -f *.o parse.cc parse.h lexor.cc rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc rm -rf dep rm -f version.exe distclean: clean $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true $(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) $@ && ) true rm -f Makefile config.status config.log config.cache rm -f stamp-config-h config.h rm -f stamp-_pli_types-h _pli_types.h ifneq (@srcdir@,.) rm -f version_tag.h check.conf rmdir $(SUBDIRS) $(NOTUSED) endif rm -rf autom4te.cache cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYSTYPE -U__SIZE_TYPE__ -Umalloc -Ufree \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ cppcheck-all: $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) cppcheck && ) true $(foreach dir,$(NOTUSED),$(MAKE) -C $(dir) cppcheck && ) true $(MAKE) cppcheck Makefile: $(srcdir)/Makefile.in config.status ./config.status --file=$@ dep: mkdir dep stamp-config-h: $(srcdir)/config.h.in config.status @rm -f $@ ./config.status config.h config.h: stamp-config-h stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status @rm -f $@ ./config.status _pli_types.h _pli_types.h: stamp-_pli_types-h $(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4 cd $(srcdir) && autoconf config.status: $(srcdir)/configure ./config.status --recheck ./config.status ifeq (@WIN32@,yes) # Under Windows (mingw) I need to make the ivl.exe in two steps. # The first step makes an ivl.exe that dlltool can use to make an # export and import library, and the last link makes a, ivl.exe # that really exports the things that the import library imports. ivl@EXEEXT@: $O $(srcdir)/ivl.def $(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@ $(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \ --output-lib libivl.a --output-exp ivl.exp $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@ else ivl@EXEEXT@: $O $(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib) endif ifeq (@MINGW32@,no) all: iverilog-vpi iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \ -e 's;@SUFFIX@;$(suffix);' \ -e 's;@IVCC@;$(CC);' \ -e 's;@IVCXX@;$(CXX);' \ -e 's;@IVCFLAGS@;$(CFLAGS);' \ -e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \ -e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \ -e 's;@INCLUDEDIR@;$(includedir);' \ -e 's;@LIBDIR@;@libdir@;' $< > $@ chmod +x $@ endif version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h $(BUILDCC) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c %.o: %.cc config.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep/$*.d # Here are some explicit dependencies needed to get things going. main.o: main.cc version_tag.h lexor.o: lexor.cc parse.h parse.o: parse.cc # Use pattern rules to avoid parallel build issues (see pr3462585) parse%cc parse%h: $(srcdir)/parse%y $(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $< syn-rules.cc: $(srcdir)/syn-rules.y $(YACC) --verbose -t -p syn_ -o $@ $< lexor.cc: $(srcdir)/lexor.lex $(LEX) -s -t $< > $@ lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false) iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe ./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@ tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@ iverilog-vpi.ps: iverilog-vpi.man $(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps iverilog-vpi.pdf: iverilog-vpi.ps $(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf # For VERSION_TAG in driver/main.c, first try git-describe, then look for a # version_tag.h file in the source tree (included in snapshots and releases), # and finally use nothing. # "true" and "false" in the next few lines are Unix shell command names ifeq ($(GIT),none) GIT_PRESENT = false else GIT_PRESENT = true endif version_tag.h version: @if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \ echo "Using git-describe for VERSION_TAG"; \ tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \ | sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \ echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \ elif test -r $(srcdir)/version_tag.h; then \ echo "Using $(srcdir)/version_tag.h for VERSION_TAG"; \ diff $(srcdir)/version_tag.h version_tag.h > /dev/null 2>&1 || cp $(srcdir)/version_tag.h version_tag.h; \ else \ echo "Using empty VERSION_TAG"; \ echo '#define VERSION_TAG ""' > version_tag.h; \ fi ifeq (@MINGW32@,yes) ifeq ($(MAN),none) INSTALL_DOC = installman else ifeq ($(PS2PDF),none) INSTALL_DOC = installman else INSTALL_DOC = installpdf installman all: dep iverilog-vpi.pdf endif endif INSTALL_DOCDIR = $(mandir)/man1 else INSTALL_DOC = installman INSTALL_DOCDIR = $(mandir)/man1 endif ifeq (@MINGW32@,yes) WIN32_INSTALL = else WIN32_INSTALL = installwin32 endif install: all installdirs installfiles $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true F = ./ivl@EXEEXT@ \ $(srcdir)/constants.vams \ $(srcdir)/disciplines.vams \ $(srcdir)/ivl_target.h \ ./_pli_types.h \ $(srcdir)/sv_vpi_user.h \ $(srcdir)/vpi_user.h \ $(srcdir)/acc_user.h \ $(srcdir)/veriuser.h \ $(INSTALL_DOC) \ $(WIN32_INSTALL) installwin32: ./iverilog-vpi installdirs $(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)" installman: iverilog-vpi.man installdirs $(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" installpdf: iverilog-vpi.pdf installdirs $(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf" installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@" $(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams" $(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams" $(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h" $(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h" $(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h" $(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h" $(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h" $(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h" installdirs: $(srcdir)/mkinstalldirs $(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(includedir)" \ "$(DESTDIR)$(libdir)/ivl$(suffix)" \ "$(DESTDIR)$(libdir)/ivl$(suffix)/include" \ "$(DESTDIR)$(mandir)" \ "$(DESTDIR)$(mandir)/man1" uninstall: $(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true for f in ivl@EXEEXT@ include/constants.vams include/disciplines.vams; \ do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include" -rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)" for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \ do rm -f "$(DESTDIR)$(bindir)/$$f"; done for f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \ do rm -f "$(DESTDIR)$(includedir)/$$f"; done -test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)" rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" "$(DESTDIR)$(prefix)/iverilog-vpi$(suffix).pdf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/Module.cc000066400000000000000000000077471435245347300151220ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 "Module.h" # include "PGate.h" # include "PWire.h" # include using namespace std; list Module::user_defparms; /* n is a permallocated string. */ Module::Module(LexicalScope*parent, perm_string n) : PScopeExtra(n, parent) { library_flag = false; is_cell = false; is_interface = false; program_block = false; uc_drive = UCD_NONE; } Module::~Module() { } void Module::add_gate(PGate*gate) { gates_.push_back(gate); } unsigned Module::port_count() const { return ports.size(); } /* * Return the array of PEIdent object that are at this port of the * module. If the port is internally unconnected, return an empty * array. */ const vector& Module::get_port(unsigned idx) const { assert(idx < ports.size()); static const vector zero; if (ports[idx]) return ports[idx]->expr; else return zero; } unsigned Module::find_port(const char*name) const { assert(name != 0); for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { if (ports[idx] == 0) { /* It is possible to have undeclared ports. These are ports that are skipped in the declaration, for example like so: module foo(x ,, y); The port between x and y is unnamed and thus inaccessible to binding by name. */ continue; } assert(ports[idx]); if (ports[idx]->name == name) return idx; } return ports.size(); } perm_string Module::get_port_name(unsigned idx) const { assert(idx < ports.size()); if (ports[idx] == 0 || ports[idx]->name.str() == 0) { /* It is possible to have undeclared ports. These are ports that are skipped in the declaration, for example like so: module foo(x ,, y); The port between x and y is unnamed and thus inaccessible to binding by name. Port references that aren't simple or escaped identifiers are also inaccessible to binding by name. */ return perm_string::literal("unnamed"); } return ports[idx]->name; } PExpr* Module::get_port_default_value(unsigned idx) const { assert(idx < ports.size()); return ports[idx] ? ports[idx]->default_value : 0; } PGate* Module::get_gate(perm_string name) { for (list::iterator cur = gates_.begin() ; cur != gates_.end() ; ++ cur ) { if ((*cur)->get_name() == name) return *cur; } return 0; } const list& Module::get_gates() const { return gates_; } PNamedItem::SymbolType Module::symbol_type() const { if (program_block) return PROGRAM; if (is_interface) return INTERFACE; return MODULE; } bool Module::can_be_toplevel() const { // Don't choose library modules. if (library_flag) return false; // Don't choose modules with parameters without default value for (std::map::const_iterator cur = parameters.begin(); cur != parameters.end(); cur++) { if (cur->second->expr == 0) return false; } return true; } iverilog-12_0/Module.h000066400000000000000000000136631435245347300147560ustar00rootroot00000000000000#ifndef IVL_Module_H #define IVL_Module_H /* * Copyright (c) 1998-2021 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 # include # include # include "StringHeap.h" # include "HName.h" # include "named.h" # include "PScope.h" # include "PNamedItem.h" # include "netlist.h" # include "pform_types.h" class PExpr; class PEIdent; class PGate; class PGenerate; class PModport; class PSpecPath; class PTask; class PFunction; class PWire; class PProcess; class Design; class NetScope; /* * A module is a named container and scope. A module holds a bunch of * semantic quantities such as wires and gates. The module is * therefore the handle for grasping the described circuit. * * SystemVerilog introduces program blocks and interfaces. These have * much in common with modules, so the Module class is used to represent * these containers as well. */ class Module : public PScopeExtra, public PNamedItem { /* The module ports are in general a vector of port_t objects. Each port has a name and an ordered list of wires. The name is the means that the outside uses to access the port, the wires are the internal connections to the port. In SystemVerilog, input ports may also have a default value. */ public: struct port_t { perm_string name; std::vector expr; PExpr*default_value; }; public: /* The name passed here is the module name, not the instance name. This name must be a permallocated string. */ explicit Module(LexicalScope*parent, perm_string name); ~Module(); /* Initially false. This is set to true if the module has been declared as a library module. This makes the module ineligible for being chosen as an implicit root. It has no other effect. */ bool library_flag; bool is_cell; /* This is true if the module represents a program block instead of a module/cell. Program blocks have content restrictions and slightly modify scheduling semantics. */ bool program_block; /* This is true if the module represents a interface instead of a module/cell. Interfaces have different content restrictions and some extra allowed items. */ bool is_interface; enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; UCDriveType uc_drive; /* specparams are simpler than other parameters, in that they can have a range, but not an explicit type. The restrictions are enforced by the parser. */ std::mapspecparams; /* The module also has defparam assignments which don't create new parameters within the module, but may be used to set values within this module (when instantiated) or in other instantiated modules. */ typedef std::pair named_expr_t; std::listdefparms; static std::listuser_defparms; /* Parameters may be overridden at instantiation time; the overrides do not contain explicit parameter names, but rather refer to parameters in the order they appear in the instantiated module. Therefore a list of names in module-order is needed to pass from a parameter-index to its name. */ std::list param_names; /* This is an array of port descriptors, which is in turn a named array of PEident pointers. */ std::vector ports; std::map attributes; /* The module has a list of generate schemes that appear in the module definition. These are used at elaboration time. */ std::list generate_schemes; /* Nested modules are placed here, and are not elaborated unless they are instantiated, implicitly or explicitly. */ std::map nested_modules; /* An interface can contain one or more named modport lists. The parser will ensure these don't appear in modules or program blocks. */ std::map modports; std::list specify_paths; // The mod_name() is the name of the module type. perm_string mod_name() const { return pscope_name(); } void add_gate(PGate*gate); unsigned port_count() const; const std::vector& get_port(unsigned idx) const; unsigned find_port(const char*name) const; // Return port name ("" for undeclared port) perm_string get_port_name(unsigned idx) const; PExpr* get_port_default_value(unsigned idx) const; PGate* get_gate(perm_string name); const std::list& get_gates() const; void dump(std::ostream&out) const; bool elaborate(Design*, NetScope*scope) const; typedef std::map replace_t; bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep); bool elaborate_sig(Design*, NetScope*scope) const; SymbolType symbol_type() const; bool can_be_toplevel() const; private: void dump_specparams_(std::ostream&out, unsigned indent) const; std::list gates_; private: // Not implemented Module(const Module&); Module& operator= (const Module&); }; #endif /* IVL_Module_H */ iverilog-12_0/PClass.cc000066400000000000000000000020611435245347300150420ustar00rootroot00000000000000/* * Copyright (c) 2012-2019 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 "PClass.h" PClass::PClass(perm_string name, LexicalScope*parent) : PScopeExtra(name, parent), type(0) { } PClass::~PClass() { } PNamedItem::SymbolType PClass::symbol_type() const { return CLASS; } iverilog-12_0/PClass.h000066400000000000000000000027171435245347300147140ustar00rootroot00000000000000#ifndef IVL_PClass_H #define IVL_PClass_H /* * Copyright (c) 2012-2019 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 "PScope.h" # include "PNamedItem.h" # include "StringHeap.h" # include class PChainConstructor; /* * SystemVerilog supports class declarations with their own lexical * scope, etc. The parser arranges for these to be created and * collected. */ class PClass : public PScopeExtra, public PNamedItem { public: explicit PClass (perm_string name, LexicalScope*parent); ~PClass(); void dump(std::ostream&out, unsigned indent) const; SymbolType symbol_type() const; public: class_type_t*type; }; #endif /* IVL_PClass_H */ iverilog-12_0/PDelays.cc000066400000000000000000000111771435245347300152260ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 # include "PDelays.h" # include "PExpr.h" # include "verinum.h" # include "netmisc.h" using namespace std; PDelays::PDelays() { delete_flag_ = true; for (unsigned idx = 0 ; idx < 3 ; idx += 1) delay_[idx] = 0; } PDelays::~PDelays() { if (delete_flag_) { for (unsigned idx = 0 ; idx < 3 ; idx += 1) delete delay_[idx]; } } void PDelays::set_delay(PExpr*del) { assert(del); assert(delay_[0] == 0); delay_[0] = del; delete_flag_ = true; } void PDelays::set_delays(const list*del, bool df) { assert(del); assert(del->size() <= 3); list::const_iterator cur = del->begin(); for (unsigned idx = 0 ; cur != del->end() ; idx += 1, ++cur) delay_[idx] = *cur; delete_flag_ = df; } unsigned PDelays::delay_count() const { unsigned dly_cnt = 0; for (unsigned idx = 0 ; idx < 3 ; idx += 1) if (delay_[idx]) dly_cnt += 1; return dly_cnt; } static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr) { NetExpr*dex = elab_and_eval(des, scope, expr, -1); check_for_inconsistent_delays(scope); /* If the delay expression is a real constant or vector constant, then evaluate it, scale it to the local time units, and return an adjusted value. */ if (NetECReal*tmp = dynamic_cast(dex)) { uint64_t delay = get_scaled_time_from_real(des, scope, tmp); delete tmp; NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); tmp2->set_line(*expr); return tmp2; } if (NetEConst*tmp = dynamic_cast(dex)) { verinum fn = tmp->value(); uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope); delete tmp; NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); tmp2->set_line(*expr); return tmp2; } /* Oops, cannot evaluate down to a constant. */ return dex; } static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr) { if (expr == 0) return 0; if (dynamic_cast (expr)) return expr; if (dynamic_cast (expr)) return expr; NetNet*sig = expr->synthesize(des, scope, expr); if (sig == 0) { cerr << expr->get_fileline() << ": error: Expression " << *expr << " is not suitable as a delay expression." << endl; des->errors += 1; return 0; } expr = new NetESignal(sig); return expr; } static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall) { NetEConst *c_rise = dynamic_cast(rise); NetEConst *c_fall = dynamic_cast(fall); if (c_rise && c_fall) { if (c_rise->value() < c_fall->value()) return rise; else return fall; } return 0; } void PDelays::eval_delays(Design*des, NetScope*scope, NetExpr*&rise_time, NetExpr*&fall_time, NetExpr*&decay_time, bool as_nets_flag) const { assert(scope); if (delay_[0]) { rise_time = calculate_val(des, scope, delay_[0]); if (as_nets_flag) rise_time = make_delay_nets(des, scope, rise_time); if (delay_[1]) { fall_time = calculate_val(des, scope, delay_[1]); if (as_nets_flag) fall_time = make_delay_nets(des, scope, fall_time); if (delay_[2]) { decay_time = calculate_val(des, scope, delay_[2]); if (as_nets_flag) decay_time = make_delay_nets(des, scope, decay_time); } else { // If this is zero then we need to do the min() // at run time. decay_time = calc_decay_time(rise_time, fall_time); } } else { assert(delay_[2] == 0); fall_time = rise_time; decay_time = rise_time; } } else { rise_time = 0; fall_time = 0; decay_time = 0; } } iverilog-12_0/PDelays.h000066400000000000000000000037501435245347300150660ustar00rootroot00000000000000#ifndef IVL_PDelays_H #define IVL_PDelays_H /* * Copyright (c) 1999-2021 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 # include class Design; class NetScope; class NetExpr; class PExpr; /* * Various PForm objects can carry delays. These delays include rise, * fall and decay times. This class arranges to carry the triplet. */ class PDelays { public: PDelays(); ~PDelays(); /* Set the delay expressions. If the delete_flag is true, then this object takes ownership of the expressions, and will delete it in the destructor. */ void set_delay(PExpr*); void set_delays(const std::list*del, bool delete_flag=true); unsigned delay_count() const; void eval_delays(Design*des, NetScope*scope, NetExpr*&rise_time, NetExpr*&fall_time, NetExpr*&decay_time, bool as_nets_flag =false) const; void dump_delays(std::ostream&out) const; private: PExpr* delay_[3]; bool delete_flag_; private: // not implemented PDelays(const PDelays&); PDelays& operator= (const PDelays&); }; std::ostream& operator << (std::ostream&o, const PDelays&); #endif /* IVL_PDelays_H */ iverilog-12_0/PEvent.cc000066400000000000000000000021171435245347300150600ustar00rootroot00000000000000/* * Copyright (c) 2004-2019 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 "PEvent.h" PEvent::PEvent(perm_string n) : name_(n) { } PEvent::~PEvent() { } perm_string PEvent::name() const { return name_; } PNamedItem::SymbolType PEvent::symbol_type() const { return EVENT; } iverilog-12_0/PEvent.h000066400000000000000000000032561435245347300147270ustar00rootroot00000000000000#ifndef IVL_PEvent_H #define IVL_PEvent_H /* * Copyright (c) 2000-2019 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 "PNamedItem.h" # include "StringHeap.h" # include class Design; class NetScope; /* * The PEvent class represents event objects. These are things that * are declared in Verilog as ``event foo;'' The name passed to the * constructor is the "foo" part of the declaration. */ class PEvent : public PNamedItem { public: // The name is a perm-allocated string. It is the simple name // of the event, without any scope. explicit PEvent(perm_string name); ~PEvent(); perm_string name() const; void elaborate_scope(Design*des, NetScope*scope) const; SymbolType symbol_type() const; private: perm_string name_; private: // not implemented PEvent(const PEvent&); PEvent& operator= (const PEvent&); }; #endif /* IVL_PEvent_H */ iverilog-12_0/PExpr.cc000066400000000000000000000323751435245347300147260ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 Stephen Williams * Copyright CERN 2013 / 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 # include "compiler.h" # include "PExpr.h" # include "PWire.h" # include "Module.h" # include "netmisc.h" # include "util.h" # include using namespace std; PExpr::PExpr() : expr_type_(IVL_VT_NO_TYPE) { expr_width_ = 0; min_width_ = 0; signed_flag_ = false; } PExpr::~PExpr() { } void PExpr::declare_implicit_nets(LexicalScope*, NetNet::Type) { } bool PExpr::has_aa_term(Design*, NetScope*) const { return false; } NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const { cerr << get_fileline() << ": error: " << "expression not valid in assign l-value: " << *this << endl; return 0; } NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const { cerr << get_fileline() << ": error: " << "expression not valid as argument to inout port: " << *this << endl; return 0; } bool PExpr::is_collapsible_net(Design*, NetScope*, NetNet::PortType) const { return false; } const char* PExpr::width_mode_name(width_mode_t mode) { switch (mode) { case PExpr::SIZED: return "sized"; case PExpr::UNSIZED: return "unsized"; case PExpr::EXPAND: return "expand"; case PExpr::LOSSLESS: return "lossless"; case PExpr::UPSIZE: return "upsize"; default: return "??"; } } PEAssignPattern::PEAssignPattern() { } PEAssignPattern::PEAssignPattern(const list&p) : parms_(p.size()) { size_t idx = 0; for (list::const_iterator cur = p.begin() ; cur != p.end() ; ++cur) { parms_[idx] = *cur; idx += 1; } } PEAssignPattern::~PEAssignPattern() { } PEBinary::PEBinary(char op, PExpr*l, PExpr*r) : op_(op), left_(l), right_(r) { } PEBinary::~PEBinary() { } void PEBinary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { if (left_) left_->declare_implicit_nets(scope, type); if (right_) right_->declare_implicit_nets(scope, type); } bool PEBinary::has_aa_term(Design*des, NetScope*scope) const { assert(left_ && right_); return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope); } PECastSize::PECastSize(PExpr*si, PExpr*b) : size_(si), base_(b) { } PECastSize::~PECastSize() { } bool PECastSize::has_aa_term(Design *des, NetScope *scope) const { return base_->has_aa_term(des, scope); } PECastType::PECastType(data_type_t*t, PExpr*b) : target_(t), base_(b) { } PECastType::~PECastType() { } bool PECastType::has_aa_term(Design *des, NetScope *scope) const { return base_->has_aa_term(des, scope); } PECastSign::PECastSign(bool signed_flag, PExpr *base) : base_(base) { signed_flag_ = signed_flag; } bool PECastSign::has_aa_term(Design *des, NetScope *scope) const { return base_->has_aa_term(des, scope); } PEBComp::PEBComp(char op, PExpr*l, PExpr*r) : PEBinary(op, l, r) { l_width_ = 0; r_width_ = 0; } PEBComp::~PEBComp() { } PEBLogic::PEBLogic(char op, PExpr*l, PExpr*r) : PEBinary(op, l, r) { assert(op == 'a' || op == 'o' || op == 'q' || op == 'Q'); } PEBLogic::~PEBLogic() { } PEBLeftWidth::PEBLeftWidth(char op, PExpr*l, PExpr*r) : PEBinary(op, l, r) { } PEBLeftWidth::~PEBLeftWidth() { } PEBPower::PEBPower(char op, PExpr*l, PExpr*r) : PEBLeftWidth(op, l, r) { } PEBPower::~PEBPower() { } PEBShift::PEBShift(char op, PExpr*l, PExpr*r) : PEBLeftWidth(op, l, r) { } PEBShift::~PEBShift() { } PECallFunction::PECallFunction(const pform_name_t&n, const vector &parms) : package_(0), path_(n), parms_(parms), is_overridden_(false) { } PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector &parms) : package_(pkg), path_(n), parms_(parms), is_overridden_(false) { } static pform_name_t pn_from_ps(perm_string n) { name_component_t tmp_name (n); pform_name_t tmp; tmp.push_back(tmp_name); return tmp; } PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list &parms) : package_(pkg), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false) { int tmp_idx = 0; assert(parms_.size() == parms.size()); for (list::const_iterator idx = parms.begin() ; idx != parms.end() ; ++idx) parms_[tmp_idx++] = *idx; } PECallFunction::PECallFunction(perm_string n, const vector&parms) : package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false) { } PECallFunction::PECallFunction(perm_string n) : package_(0), path_(pn_from_ps(n)), is_overridden_(false) { } // NOTE: Anachronism. Try to work all use of svector out. PECallFunction::PECallFunction(const pform_name_t&n, const list &parms) : package_(0), path_(n), parms_(parms.size()), is_overridden_(false) { int tmp_idx = 0; assert(parms_.size() == parms.size()); for (list::const_iterator idx = parms.begin() ; idx != parms.end() ; ++idx) parms_[tmp_idx++] = *idx; } PECallFunction::PECallFunction(perm_string n, const list&parms) : package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false) { int tmp_idx = 0; assert(parms_.size() == parms.size()); for (list::const_iterator idx = parms.begin() ; idx != parms.end() ; ++idx) parms_[tmp_idx++] = *idx; } PECallFunction::~PECallFunction() { } void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx]->declare_implicit_nets(scope, type); } } bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const { bool flag = false; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { flag = parms_[idx]->has_aa_term(des, scope) || flag; } return flag; } PEConcat::PEConcat(const list&p, PExpr*r) : parms_(p.size()), width_modes_(SIZED, p.size()), repeat_(r) { int tmp_idx = 0; assert(parms_.size() == p.size()); for (list::const_iterator idx = p.begin() ; idx != p.end() ; ++idx) parms_[tmp_idx++] = *idx; tested_scope_ = 0; repeat_count_ = 1; } PEConcat::~PEConcat() { delete repeat_; } void PEConcat::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx]->declare_implicit_nets(scope, type); } } bool PEConcat::has_aa_term(Design*des, NetScope*scope) const { bool flag = false; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { flag = parms_[idx]->has_aa_term(des, scope) || flag; } if (repeat_) flag = repeat_->has_aa_term(des, scope) || flag; return flag; } PEEvent::PEEvent(PEEvent::edge_t t, PExpr*e) : type_(t), expr_(e) { } PEEvent::~PEEvent() { } PEEvent::edge_t PEEvent::type() const { return type_; } bool PEEvent::has_aa_term(Design*des, NetScope*scope) const { assert(expr_); return expr_->has_aa_term(des, scope); } PExpr* PEEvent::expr() const { return expr_; } PENull::PENull(void) { } PENull::~PENull() { } PEFNumber::PEFNumber(verireal*v) : value_(v) { } PEFNumber::~PEFNumber() { delete value_; } const verireal& PEFNumber::value() const { return *value_; } PEIdent::PEIdent(const pform_name_t&that) : package_(0), path_(that), no_implicit_sig_(false) { } PEIdent::PEIdent(perm_string s, bool no_implicit_sig) : package_(0), no_implicit_sig_(no_implicit_sig) { path_.push_back(name_component_t(s)); } PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that) : package_(pkg), path_(that), no_implicit_sig_(true) { } PEIdent::~PEIdent() { } static bool find_enum_constant(LexicalScope*scope, perm_string name) { for (vector::const_iterator cur = scope->enum_sets.begin() ; cur != scope->enum_sets.end() ; ++ cur) { for (list::const_iterator idx = (*cur)->names->begin() ; idx != (*cur)->names->end() ; ++ idx) { if (idx->name == name) return true; } } return false; } void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { /* We create an implicit wire if: - this is a simple identifier - an identifier of that name has not already been declared in any enclosing scope. - this is not an implicit named port connection */ if (no_implicit_sig_) return; if ((path_.size() == 1) && (path_.front().index.size() == 0)) { perm_string name = path_.front().name; LexicalScope*ss = scope; while (ss) { if (ss->wires.find(name) != ss->wires.end()) return; if (ss->parameters.find(name) != ss->parameters.end()) return; if (ss->genvars.find(name) != ss->genvars.end()) return; if (ss->events.find(name) != ss->events.end()) return; if (find_enum_constant(ss, name)) return; /* Strictly speaking, we should also check for name clashes with tasks, functions, named blocks, module instances, and generate blocks. However, this information is not readily available. As these names would not be legal in this context, we can declare implicit nets here and rely on later checks for name clashes to report the error. */ ss = ss->parent_scope(); } PWire*net = new PWire(name, type, NetNet::NOT_A_PORT); net->set_file(get_file()); net->set_lineno(get_lineno()); scope->wires[name] = net; if (warn_implicit) { cerr << get_fileline() << ": warning: implicit " "definition of wire '" << name << "'." << endl; } } } bool PEIdent::has_aa_term(Design*des, NetScope*scope) const { symbol_search_results sr; if (!symbol_search(this, des, scope, path_, &sr)) return false; // Class properties are not considered automatic since a non-blocking // assignment to an object stored in an automatic variable is supposed to // capture a reference to the object, not the variable. if (!sr.path_tail.empty() && sr.net && sr.net->class_type()) return false; return sr.scope->is_auto(); } PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr) : size_(size_expr), init_(init_expr) { } PENewArray::~PENewArray() { delete size_; } PENewClass::PENewClass(void) { } PENewClass::PENewClass(const list&p, data_type_t *class_type) : parms_(p.size()), class_type_(class_type) { size_t tmp_idx = 0; for (list::const_iterator cur = p.begin() ; cur != p.end() ; ++ cur) { parms_[tmp_idx++] = *cur; } } PENewClass::~PENewClass() { } PENewCopy::PENewCopy(PExpr*src) : src_(src) { } PENewCopy::~PENewCopy() { } PENumber::PENumber(verinum*vp) : value_(vp) { assert(vp); } PENumber::~PENumber() { delete value_; } const verinum& PENumber::value() const { return *value_; } PEString::PEString(char*s) : text_(s) { } PEString::~PEString() { delete[]text_; } string PEString::value() const { return text_; } PETernary::PETernary(PExpr*e, PExpr*t, PExpr*f) : expr_(e), tru_(t), fal_(f) { } PETernary::~PETernary() { } void PETernary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { assert(expr_ && tru_ && fal_); expr_->declare_implicit_nets(scope, type); tru_->declare_implicit_nets(scope, type); fal_->declare_implicit_nets(scope, type); } bool PETernary::has_aa_term(Design*des, NetScope*scope) const { assert(expr_ && tru_ && fal_); return expr_->has_aa_term(des, scope) || tru_->has_aa_term(des, scope) || fal_->has_aa_term(des, scope); } PETypename::PETypename(data_type_t*dt) : data_type_(dt) { } PETypename::~PETypename() { } PEUnary::PEUnary(char op, PExpr*ex) : op_(op), expr_(ex) { } PEUnary::~PEUnary() { } void PEUnary::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) { assert(expr_); expr_->declare_implicit_nets(scope, type); } bool PEUnary::has_aa_term(Design*des, NetScope*scope) const { assert(expr_); return expr_->has_aa_term(des, scope); } PEVoid::PEVoid() { } PEVoid::~PEVoid() { } iverilog-12_0/PExpr.h000066400000000000000000001042371435245347300145650ustar00rootroot00000000000000#ifndef IVL_PExpr_H #define IVL_PExpr_H /* * Copyright (c) 1998-2021 Stephen Williams * Copyright CERN 2013 / 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 # include # include # include "netlist.h" # include "verinum.h" # include "LineInfo.h" # include "pform_types.h" class Design; class Module; class LexicalScope; class NetNet; class NetExpr; class NetScope; class PPackage; struct symbol_search_results; /* * The PExpr class hierarchy supports the description of * expressions. The parser can generate expression objects from the * source, possibly reducing things that it knows how to reduce. */ class PExpr : public LineInfo { public: // Mode values used by test_width() (see below for description). enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE }; // Flag values that can be passed to elaborate_expr(). static const unsigned NO_FLAGS = 0x0; static const unsigned NEED_CONST = 0x1; static const unsigned SYS_TASK_ARG = 0x2; static const unsigned ANNOTATABLE = 0x4; // Convert width mode to human-readable form. static const char*width_mode_name(width_mode_t mode); PExpr(); virtual ~PExpr(); virtual void dump(std::ostream&) const; // This method tests whether the expression contains any identifiers // that have not been previously declared in the specified scope or // in any containing scope. Any such identifiers are added to the // specified scope as scalar nets of the specified type. // // This operation must be performed by the parser, to ensure that // subsequent declarations do not affect the decision to create an // implicit net. virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); // This method tests whether the expression contains any // references to automatically allocated variables. virtual bool has_aa_term(Design*des, NetScope*scope) const; // This method tests the type and width that the expression wants // to be. It should be called before elaborating an expression to // figure out the type and width of the expression. It also figures // out the minimum width that can be used to evaluate the expression // without changing the result. This allows the expression width to // be pruned when not all bits of the result are used. // // Normally mode should be initialized to SIZED before starting to // test the width of an expression. In SIZED mode the expression // width will be calculated strictly according to the IEEE standard // rules for expression width. // // If the expression is found to contain an unsized literal number // and gn_strict_expr_width_flag is set, mode will be changed to // UNSIZED. In UNSIZED mode the expression width will be calculated // exactly as in SIZED mode - the change in mode simply flags that // the expression contains an unsized numbers. // // If the expression is found to contain an unsized literal number // and gn_strict_expr_width_flag is not set, mode will be changed // to LOSSLESS. In LOSSLESS mode the expression width will be // calculated as the minimum width necessary to avoid arithmetic // overflow or underflow. // // Once in LOSSLESS mode, if the expression is found to contain // an operation that coerces a vector operand to a different type // (signed <-> unsigned), mode will be changed to UPSIZE. UPSIZE // mode is the same as LOSSLESS, except that the final expression // width will be forced to be at least integer_width. This is // necessary to ensure compatibility with the IEEE standard, which // requires unsized numbers to be treated as having the same width // as an integer. The lossless width calculation is inadequate in // this case because coercing an operand to a different type means // that the expression no longer obeys the normal rules of arithmetic. // // If mode is initialized to EXPAND instead of SIZED, the expression // width will be calculated as the minimum width necessary to avoid // arithmetic overflow or underflow, even if it contains no unsized // literals. mode will be changed LOSSLESS or UPSIZE as described // above. This supports a non-standard mode of expression width // calculation. // // When the final value of mode is UPSIZE, the width returned by // this method is the calculated lossless width, but the width // returned by a subsequent call to the expr_width method will be // the final expression width. virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); // After the test_width method is complete, these methods // return valid results. ivl_variable_type_t expr_type() const { return expr_type_; } unsigned expr_width() const { return expr_width_; } unsigned min_width() const { return min_width_; } bool has_sign() const { return signed_flag_; } // This method allows the expression type (signed/unsigned) // to be propagated down to any context-dependant operands. void cast_signed(bool flag) { signed_flag_ = flag; } // This is the more generic form of the elaborate_expr method // below. The plan is to replace the simpler elaborate_expr // method with this version, which can handle more advanced // types. But for now, this is only implemented in special cases. virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; // Procedural elaboration of the expression. The expr_width is // the required width of the expression. // // The sys_task_arg flag is true if expressions are allowed to // be incomplete. virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; // This method elaborates the expression as gates, but // restricted for use as l-values of continuous assignments. virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; // This is similar to elaborate_lnet, except that the // expression is evaluated to be bi-directional. This is // useful for arguments to inout ports of module instances and // ports of tran primitives. virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; // Expressions that can be in the l-value of procedural // assignments can be elaborated with this method. If the // is_cassign or is_force flags are true, then the set of // valid l-value types is slightly modified to accommodate // the Verilog procedural continuous assignment statements. virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const; // This method returns true if the expression represents a // structural net that can have multiple drivers. This is // used to test whether an input port connection can be // collapsed to a single wire. virtual bool is_collapsible_net(Design*des, NetScope*scope, NetNet::PortType port_type) const; protected: unsigned fix_width_(width_mode_t mode); // The derived class test_width methods should fill these in. ivl_variable_type_t expr_type_; unsigned expr_width_; unsigned min_width_; bool signed_flag_; private: // not implemented PExpr(const PExpr&); PExpr& operator= (const PExpr&); }; std::ostream& operator << (std::ostream&, const PExpr&); class PEAssignPattern : public PExpr { public: explicit PEAssignPattern(); explicit PEAssignPattern(const std::list&p); ~PEAssignPattern(); void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; private: NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; private: std::vectorparms_; }; class PEConcat : public PExpr { public: explicit PEConcat(const std::list&p, PExpr*r =0); ~PEConcat(); virtual void dump(std::ostream&) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const; virtual bool is_collapsible_net(Design*des, NetScope*scope, NetNet::PortType port_type) const; private: NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const; private: std::vectorparms_; std::valarraywidth_modes_; PExpr*repeat_; NetScope*tested_scope_; unsigned repeat_count_; }; /* * Event expressions are expressions that can be combined with the * event "or" operator. These include "posedge foo" and similar, and * also include named events. "edge" events are associated with an * expression, whereas named events simply have a name, which * represents an event variable. */ class PEEvent : public PExpr { public: enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, EDGE, POSITIVE}; // Use this constructor to create events based on edges or levels. PEEvent(edge_t t, PExpr*e); ~PEEvent(); edge_t type() const; PExpr* expr() const; virtual void dump(std::ostream&) const; virtual bool has_aa_term(Design*des, NetScope*scope) const; private: edge_t type_; PExpr *expr_; }; /* * This holds a floating point constant in the source. */ class PEFNumber : public PExpr { public: explicit PEFNumber(verireal*vp); ~PEFNumber(); const verireal& value() const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; virtual void dump(std::ostream&) const; private: verireal*value_; }; class PEIdent : public PExpr { public: explicit PEIdent(perm_string, bool no_implicit_sig=false); explicit PEIdent(PPackage*pkg, const pform_name_t&name); explicit PEIdent(const pform_name_t&); ~PEIdent(); // Add another name to the string of hierarchy that is the // current identifier. void append_name(perm_string); virtual void dump(std::ostream&) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); // Identifiers are allowed (with restrictions) is assign l-values. virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; // Identifiers are also allowed as procedural assignment l-values. virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; // Elaborate the PEIdent as a port to a module. This method // only applies to Ident expressions. NetNet* elaborate_subport(Design*des, NetScope*sc) const; // Elaborate the identifier allowing for unpacked arrays. This // method only applies to Ident expressions because only Ident // expressions can can be unpacked arrays. NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const; virtual bool is_collapsible_net(Design*des, NetScope*scope, NetNet::PortType port_type) const; const PPackage* package() const { return package_; } const pform_name_t& path() const { return path_; } private: PPackage*package_; pform_name_t path_; bool no_implicit_sig_; private: // Common functions to calculate parts of part/bit // selects. These methods return true if the expressions // elaborate/calculate, or false if there is some sort of // source error. bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const; // The calculate_parts_ method calculates the range // expressions of a part select for the current object. The // part select expressions are elaborated and evaluated, and // the values written to the msb/lsb arguments. If there are // invalid bits (xz) in either expression, then the defined // flag is set to *false*. bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const; NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const; bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const; // Evaluate the prefix indices. All but the final index in a // chain of indices must be a single value and must evaluate // to constants at compile time. For example: // [x] - OK // [1][2][x] - OK // [1][x:y] - OK // [2:0][x] - BAD // [y][x] - BAD // Leave the last index for special handling. bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net, std::list&prefix_indices) const; private: NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const; NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*, bool need_const_idx) const; bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*, bool need_const_idx) const; bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const; bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*, index_component_t::ctype_t, bool need_const_idx) const; NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*, const netclass_t *class_type, NetNet*, pform_name_t) const; bool elaborate_lval_net_packed_member_(Design*, NetScope*, NetAssign_*, pform_name_t member_path) const; bool elaborate_lval_darray_bit_(Design*, NetScope*, NetAssign_*) const; private: NetExpr* elaborate_expr_(Design *des, NetScope *scope, unsigned expr_wid, unsigned flags) const; NetExpr*elaborate_expr_param_or_specparam_(Design*des, NetScope*scope, const NetExpr*par, NetScope*found_in, ivl_type_t par_type, unsigned expr_wid, unsigned flags) const; NetExpr*elaborate_expr_param_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, unsigned expr_wid, unsigned flags) const; NetExpr*elaborate_expr_param_bit_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const; NetExpr*elaborate_expr_param_part_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, unsigned expr_wid) const; NetExpr*elaborate_expr_param_idx_up_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const; NetExpr*elaborate_expr_param_idx_do_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const; NetExpr*elaborate_expr_net(Design*des, NetScope*scope, NetNet*net, NetScope*found, unsigned expr_wid, unsigned flags) const; NetExpr*elaborate_expr_net_word_(Design*des, NetScope*scope, NetNet*net, NetScope*found, unsigned expr_wid, unsigned flags) const; NetExpr*elaborate_expr_net_part_(Design*des, NetScope*scope, NetESignal*net, NetScope*found, unsigned expr_wid) const; NetExpr*elaborate_expr_net_idx_up_(Design*des, NetScope*scope, NetESignal*net, NetScope*found, bool need_const) const; NetExpr*elaborate_expr_net_idx_do_(Design*des, NetScope*scope, NetESignal*net, NetScope*found, bool need_const) const; NetExpr*elaborate_expr_net_bit_(Design*des, NetScope*scope, NetESignal*net, NetScope*found, bool need_const) const; NetExpr*elaborate_expr_net_bit_last_(Design*des, NetScope*scope, NetESignal*net, NetScope*found, bool need_const) const; NetExpr*elaborate_expr_class_member_(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; NetExpr *elaborate_expr_class_field_(Design*des, NetScope*scope, const symbol_search_results &sr, unsigned expr_wid, unsigned flags) const; unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode); unsigned test_width_parameter_(const NetExpr *par, width_mode_t&mode); private: NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const; bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig, long&midx, long&lidx) const; }; class PENewArray : public PExpr { public: explicit PENewArray (PExpr*s, PExpr*i); ~PENewArray(); virtual void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; private: PExpr*size_; PExpr*init_; }; class PENewClass : public PExpr { public: // New without (or with default) constructor explicit PENewClass (); // New with constructor arguments explicit PENewClass (const std::list&p, data_type_t *class_type = nullptr); ~PENewClass(); virtual void dump(std::ostream&) const; // Class objects don't have a useful width, but the expression // is IVL_VT_CLASS. virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); // Note that class (new) expressions only appear in context // that uses this form of the elaborate_expr method. In fact, // the type argument is going to be a netclass_t object. virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; private: NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope, const netclass_t*ctype, NetExpr*obj, unsigned flags) const; private: std::vectorparms_; data_type_t *class_type_; }; class PENewCopy : public PExpr { public: explicit PENewCopy(PExpr*src); ~PENewCopy(); virtual void dump(std::ostream&) const; // Class objects don't have a useful width, but the expression // is IVL_VT_CLASS. virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); // Note that class (new) expressions only appear in context // that uses this form of the elaborate_expr method. In fact, // the type argument is going to be a netclass_t object. virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; private: PExpr*src_; }; class PENull : public PExpr { public: explicit PENull(); ~PENull(); virtual void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; }; class PENumber : public PExpr { public: explicit PENumber(verinum*vp); ~PENumber(); const verinum& value() const; virtual void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr *elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned) const; virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const; private: verinum*const value_; }; /* * This represents a string constant in an expression. * * The s parameter to the PEString constructor is a C string that this * class instance will take for its own. The caller should not delete * the string, the destructor will do it. */ class PEString : public PExpr { public: explicit PEString(char*s); ~PEString(); std::string value() const; virtual void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetEConst*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetEConst*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned) const; private: char*text_; }; class PETypename : public PExpr { public: explicit PETypename(data_type_t*data_type); ~PETypename(); virtual void dump(std::ostream&) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; inline data_type_t* get_type() const { return data_type_; } private: data_type_t*data_type_; }; class PEUnary : public PExpr { public: explicit PEUnary(char op, PExpr*ex); ~PEUnary(); virtual void dump(std::ostream&out) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; public: inline char get_op() const { return op_; } inline PExpr*get_expr() const { return expr_; } private: NetExpr* elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const; private: char op_; PExpr*expr_; }; class PEBinary : public PExpr { public: explicit PEBinary(char op, PExpr*l, PExpr*r); ~PEBinary(); virtual void dump(std::ostream&out) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; protected: char op_; PExpr*left_; PExpr*right_; NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; }; /* * Here are a few specialized classes for handling specific binary * operators. */ class PEBComp : public PEBinary { public: explicit PEBComp(char op, PExpr*l, PExpr*r); ~PEBComp(); virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); NetExpr* elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; private: unsigned l_width_; unsigned r_width_; }; /* * This derived class is for handling logical expressions: && and ||. */ class PEBLogic : public PEBinary { public: explicit PEBLogic(char op, PExpr*l, PExpr*r); ~PEBLogic(); virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); NetExpr* elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; }; /* * A couple of the binary operands have a special sub-expression rule * where the expression width is carried entirely by the left * expression, and the right operand is self-determined. */ class PEBLeftWidth : public PEBinary { public: explicit PEBLeftWidth(char op, PExpr*l, PExpr*r); ~PEBLeftWidth() =0; virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const =0; protected: virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; }; class PEBPower : public PEBLeftWidth { public: explicit PEBPower(char op, PExpr*l, PExpr*r); ~PEBPower(); NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; }; class PEBShift : public PEBLeftWidth { public: explicit PEBShift(char op, PExpr*l, PExpr*r); ~PEBShift(); NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const; }; /* * This class supports the ternary (?:) operator. The operator takes * three expressions, the test, the true result and the false result. */ class PETernary : public PExpr { public: explicit PETernary(PExpr*e, PExpr*t, PExpr*f); ~PETernary(); virtual void dump(std::ostream&out) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); virtual NetExpr*elaborate_expr(Design*des, NetScope*, unsigned expr_wid, unsigned flags) const; private: NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope, PExpr*expr, unsigned expr_wid, unsigned flags, bool short_cct) const; private: PExpr*expr_; PExpr*tru_; PExpr*fal_; }; /* * This class represents a parsed call to a function, including calls * to system functions. The parameters in the parms list are the * expressions that are passed as input to the ports of the function. */ class PECallFunction : public PExpr { public: explicit PECallFunction(const pform_name_t&n, const std::vector &parms); // Call function defined in package. explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector &parms); explicit PECallFunction(PPackage*pkg, perm_string n, const std::list &parms); // Used to convert a user function called as a task explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector &parms); // Call of system function (name is not hierarchical) explicit PECallFunction(perm_string n, const std::vector &parms); explicit PECallFunction(perm_string n); // std::list versions. Should be removed! explicit PECallFunction(const pform_name_t&n, const std::list &parms); explicit PECallFunction(perm_string n, const std::list &parms); ~PECallFunction(); virtual void dump(std::ostream &) const; virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); virtual bool has_aa_term(Design*des, NetScope*scope) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); private: PPackage*package_; pform_name_t path_; std::vector parms_; // For system functions. bool is_overridden_; bool check_call_matches_definition_(Design*des, NetScope*dscope) const; NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const; NetExpr* elaborate_expr_(Design *des, NetScope *scope, unsigned flags) const; NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope, unsigned flags)const; NetExpr* elaborate_expr_method_(Design*des, NetScope*scope, symbol_search_results&search_results) const; NetExpr* elaborate_expr_method_par_(Design*des, NetScope*scope, symbol_search_results&search_results) const; NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t) const; unsigned test_width_sfunc_(Design*des, NetScope*scope, width_mode_t&mode); unsigned test_width_method_(Design*des, NetScope*scope, symbol_search_results&search_results, width_mode_t&mode); NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope, unsigned flags) const; unsigned elaborate_arguments_(Design*des, NetScope*scope, NetFuncDef*def, bool need_const, std::vector&parms, unsigned parm_off) const; }; /* * Support the SystemVerilog cast to size. */ class PECastSize : public PExpr { public: explicit PECastSize(PExpr*size, PExpr*base); ~PECastSize(); void dump(std::ostream &out) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; virtual bool has_aa_term(Design *des, NetScope *scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); private: PExpr* size_; PExpr* base_; }; /* * Support the SystemVerilog cast to a different type. */ class PECastType : public PExpr { public: explicit PECastType(data_type_t*target, PExpr*base); ~PECastType(); void dump(std::ostream &out) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const; virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; virtual bool has_aa_term(Design *des, NetScope *scope) const; virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); private: data_type_t* target_; ivl_type_t target_type_; PExpr* base_; }; /* * Support the SystemVerilog sign cast. */ class PECastSign : public PExpr { public: explicit PECastSign(bool signed_flag, PExpr *base); ~PECastSign() = default; void dump(std::ostream &out) const; NetExpr* elaborate_expr(Design *des, NetScope *scope, unsigned expr_wid, unsigned flags) const; virtual bool has_aa_term(Design *des, NetScope *scope) const; unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode); private: std::unique_ptr base_; }; /* * This class is used for error recovery. All methods do nothing and return * null or default values. */ class PEVoid : public PExpr { public: explicit PEVoid(); ~PEVoid(); virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const; }; #endif /* IVL_PExpr_H */ iverilog-12_0/PFunction.cc000066400000000000000000000051711435245347300155670ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "PTask.h" # include "Statement.h" # include # include "ivl_assert.h" using namespace std; PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__) : PTaskFunc(name, parent), statement_(0) { is_auto_ = is_auto__; return_type_ = 0; } PFunction::~PFunction() { } void PFunction::set_statement(Statement*s) { assert(s != 0); assert(statement_ == 0); statement_ = s; } void PFunction::push_statement_front(Statement*stmt) { // This should not be possible. ivl_assert(*this, statement_); // Get the PBlock of the statement. If it is not a PBlock, // then create one to wrap the existing statement and the new // statement that we're pushing. PBlock*blk = dynamic_cast (statement_); if (blk == 0) { PBlock*tmp = new PBlock(PBlock::BL_SEQ); tmp->set_line(*this); vectortmp_list(1); tmp_list[0] = statement_; tmp->set_statement(tmp_list); statement_ = tmp; blk = tmp; } // Now do the push. blk->push_statement_front(stmt); } void PFunction::set_return(data_type_t*t) { return_type_ = t; } PChainConstructor* PFunction::extract_chain_constructor() { PChainConstructor*res = 0; if ((res = dynamic_cast (statement_))) { statement_ = new PBlock(PBlock::BL_SEQ); statement_->set_line(*this); } else if (PBlock*blk = dynamic_cast(statement_)) { res = blk->extract_chain_constructor(); } return res; } PNamedItem::SymbolType PFunction::symbol_type() const { return FUNCTION; } PLet::PLet(perm_string name, LexicalScope*parent, list*ports, PExpr*expr) : PTaskFunc(name, parent), ports_(ports), expr_(expr) { } PLet::~PLet() { } iverilog-12_0/PGate.cc000066400000000000000000000135251435245347300146640ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "PGate.h" # include "PExpr.h" # include "verinum.h" # include using namespace std; void PGate::set_pins_(list*pins) { assert(pins); assert(pins->size() == pins_.size()); for (size_t idx = 0 ; idx < pins_.size() ; idx += 1) { pins_[idx] = pins->front(); pins->pop_front(); } assert(pins->empty()); delete pins; } PGate::PGate(perm_string name, list*pins, const list*del) : name_(name), pins_(pins? pins->size() : 0), ranges_(0) { if (pins) set_pins_(pins); if (del) delay_.set_delays(del); str0_ = IVL_DR_STRONG; str1_ = IVL_DR_STRONG; } PGate::PGate(perm_string name, list*pins, PExpr*del) : name_(name), pins_(pins? pins->size() : 0), ranges_(0) { if (pins) set_pins_(pins); if (del) delay_.set_delay(del); str0_ = IVL_DR_STRONG; str1_ = IVL_DR_STRONG; } PGate::PGate(perm_string name, list*pins) : name_(name), pins_(pins? pins->size() : 0), ranges_(0) { if (pins) set_pins_(pins); str0_ = IVL_DR_STRONG; str1_ = IVL_DR_STRONG; } PGate::~PGate() { } void PGate::set_ranges(list*ranges) { assert(ranges_ == 0); ranges_ = ranges; } ivl_drive_t PGate::strength0() const { return str0_; } void PGate::strength0(ivl_drive_t s) { str0_ = s; } ivl_drive_t PGate::strength1() const { return str1_; } void PGate::strength1(ivl_drive_t s) { str1_ = s; } void PGate::elaborate_scope(Design*, NetScope*) const { } /* * This method is used during elaboration to calculate the * rise/fall/decay times for the gate. These values were set in pform * by the constructor, so here I evaluate the expression in the given * design context and save the calculated delays into the output * parameters. This method understands how to handle the different * numbers of expressions. */ void PGate::eval_delays(Design*des, NetScope*scope, NetExpr*&rise_expr, NetExpr*&fall_expr, NetExpr*&decay_expr, bool as_net_flag) const { delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr, as_net_flag); } unsigned PGate::delay_count() const { return delay_.delay_count(); } PNamedItem::SymbolType PGate::symbol_type() const { return INSTANCE; } PGAssign::PGAssign(list*pins) : PGate(perm_string(), pins) { assert(pin_count() == 2); } PGAssign::PGAssign(list*pins, list*dels) : PGate(perm_string(), pins, dels) { assert(pin_count() == 2); } PGAssign::~PGAssign() { } PGBuiltin::PGBuiltin(Type t, perm_string name, list*pins, list*del) : PGate(name, pins, del), type_(t) { } PGBuiltin::PGBuiltin(Type t, perm_string name, list*pins, PExpr*del) : PGate(name, pins, del), type_(t) { } PGBuiltin::~PGBuiltin() { } const char* PGBuiltin::gate_name() const { switch(type_) { case AND: return "AND"; break; case NAND: return "NAND"; break; case OR: return "OR"; break; case NOR: return "NOR"; break; case XOR: return "XOR"; break; case XNOR: return "XNOR"; break; case BUF: return "BUF"; break; case NOT: return "NOT"; break; case BUFIF0: return "BUFIF0"; break; case NOTIF0: return "NOTIF0"; break; case BUFIF1: return "BUFIF1"; break; case NOTIF1: return "NOTIF1"; break; case NMOS: return "NMOS"; break; case RNMOS: return "RNMOS"; break; case PMOS: return "PMOS"; break; case RPMOS: return "RPMOS"; break; case TRAN: return "TRAN"; break; case RTRAN: return "RTRAN"; break; case TRANIF0: return "TRANIF0"; break; case RTRANIF0: return "RTRANIF0"; break; case TRANIF1: return "TRANIF1"; break; case RTRANIF1: return "RTRANIF1"; break; case CMOS: return "CMOS"; break; case RCMOS: return "RCMOS"; break; case PULLUP: return "PULLUP"; break; case PULLDOWN: return "PULLDOWN"; break; } return ""; } PGModule::PGModule(perm_string type, perm_string name, list*pins) : PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0), npins_(0), parms_(0), nparms_(0) { } PGModule::PGModule(perm_string type, perm_string name, named*pins, unsigned npins) : PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins), npins_(npins), parms_(0), nparms_(0) { } PGModule::PGModule(Module*type, perm_string name) : PGate(name, 0), bound_type_(type), overrides_(0), pins_(0), npins_(0), parms_(0), nparms_(0) { } PGModule::~PGModule() { } void PGModule::set_parameters(list*o) { assert(overrides_ == 0); overrides_ = o; } void PGModule::set_parameters(named*pa, unsigned npa) { assert(parms_ == 0); assert(overrides_ == 0); parms_ = pa; nparms_ = npa; } perm_string PGModule::get_type() const { return type_; } iverilog-12_0/PGate.h000066400000000000000000000207521435245347300145260ustar00rootroot00000000000000#ifndef IVL_PGate_H #define IVL_PGate_H /* * Copyright (c) 1998-2021 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 "named.h" # include "PNamedItem.h" # include "PDelays.h" # include "netlist.h" # include # include # include # include class PExpr; class PUdp; class Module; /* * A PGate represents a Verilog gate. The gate has a name and other * properties, and a set of pins that connect to wires. It is known at * the time a gate is constructed how many pins the gate has. * * This pins of a gate are connected to expressions. The elaboration * step will need to convert expressions to a network of gates in * order to elaborate expression inputs, but that can easily be done. * * The PGate base class also carries the strength0 and strength1 * strengths for those gates where the driver[s] can be described by a * single strength pair. There is a strength of the 0 drive, and a * strength of the 1 drive. */ class PGate : public PNamedItem { public: explicit PGate(perm_string name, std::list*pins, const std::list*del); explicit PGate(perm_string name, std::list*pins, PExpr*del); explicit PGate(perm_string name, std::list*pins); virtual ~PGate(); void set_ranges(std::list*ranges); bool is_array() const { return ranges_ != 0; } perm_string get_name() const { return name_; } // This evaluates the delays as far as possible, but returns // an expression, and do not signal errors. void eval_delays(Design*des, NetScope*scope, NetExpr*&rise_time, NetExpr*&fall_time, NetExpr*&decay_time, bool as_net_flag =false) const; unsigned delay_count() const; unsigned pin_count() const { return pins_.size(); } PExpr*pin(unsigned idx) const { return pins_[idx]; } ivl_drive_t strength0() const; ivl_drive_t strength1() const; void strength0(ivl_drive_t); void strength1(ivl_drive_t); std::map attributes; virtual void dump(std::ostream&out, unsigned ind =4) const; virtual void elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*sc) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const; SymbolType symbol_type() const; protected: const std::vector& get_pins() const { return pins_; } unsigned calculate_array_size_(Design*, NetScope*, long&high, long&low) const; void dump_pins(std::ostream&out) const; void dump_delays(std::ostream&out) const; void dump_ranges(std::ostream&out) const; private: perm_string name_; PDelays delay_; std::vectorpins_; std::list*ranges_; ivl_drive_t str0_, str1_; void set_pins_(std::list*pins); private: // not implemented PGate(const PGate&); PGate& operator= (const PGate&); }; /* A continuous assignment has a single output and a single input. The input is passed directly to the output. This is different from a BUF because elaboration may need to turn this into a vector of gates. */ class PGAssign : public PGate { public: explicit PGAssign(std::list*pins); explicit PGAssign(std::list*pins, std::list*dels); ~PGAssign(); void dump(std::ostream&out, unsigned ind =4) const; virtual void elaborate(Design*des, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const; private: void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const; }; /* * The Builtin class is specifically a gate with one of the builtin * types. The parser recognizes these types during parse. These types * have special properties that allow them to be treated specially. * * A PGBuiltin can be grouped into an array of devices. If this is * done, the msb_ and lsb_ are set to the indices of the array * range. Elaboration causes a gate to be created for each element of * the array, and a name will be generated for each gate. */ class PGBuiltin : public PGate { public: enum Type { AND, NAND, OR, NOR, XOR, XNOR, BUF, BUFIF0, BUFIF1, NOT, NOTIF0, NOTIF1, PULLDOWN, PULLUP, NMOS, RNMOS, PMOS, RPMOS, CMOS, RCMOS, TRAN, RTRAN, TRANIF0, TRANIF1, RTRANIF0, RTRANIF1 }; public: explicit PGBuiltin(Type t, perm_string name, std::list*pins, std::list*del); explicit PGBuiltin(Type t, perm_string name, std::list*pins, PExpr*del); ~PGBuiltin(); Type type() const { return type_; } const char * gate_name() const; virtual void dump(std::ostream&out, unsigned ind =4) const; virtual void elaborate(Design*, NetScope*scope) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const; private: void calculate_gate_and_lval_count_(unsigned&gate_count, unsigned&lval_count) const; NetNode* create_gate_for_output_(Design*, NetScope*, perm_string gate_name, unsigned instance_width) const; bool check_delay_count(Design*des) const; Type type_; }; /* * This kind of gate is an instantiation of a module. The stored type * is the name of a module definition somewhere in the pform. This * type also handles UDP devices, because it is generally not known at * parse time whether a name belongs to a module or a UDP. */ class PGModule : public PGate { public: // The name is the *instance* name of the gate. // If the binding of ports is by position, this constructor // builds everything all at once. explicit PGModule(perm_string type, perm_string name, std::list*pins); // If the binding of ports is by name, this constructor takes // the bindings and stores them for later elaboration. explicit PGModule(perm_string type, perm_string name, named*pins, unsigned npins); // If the module type is known by design, then use this // constructor. explicit PGModule(Module*type, perm_string name); ~PGModule(); // Parameter overrides can come as an ordered list, or a set // of named expressions. void set_parameters(std::list*o); void set_parameters(named*pa, unsigned npa); std::map attributes; virtual void dump(std::ostream&out, unsigned ind =4) const; virtual void elaborate(Design*, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*sc) const; virtual bool elaborate_sig(Design*des, NetScope*scope) const; // This returns the module name of this module. It is a // permallocated string. perm_string get_type() const; private: Module*bound_type_; perm_string type_; std::list*overrides_; named*pins_; unsigned npins_; // These members support parameter override by name named*parms_; unsigned nparms_; friend class delayed_elaborate_scope_mod_instances; void elaborate_mod_(Design*, Module*mod, NetScope*scope) const; void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const; void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const; void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const; bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const; // Not currently used. #if 0 bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const; #endif NetNet*resize_net_to_port_(Design*des, NetScope*scope, NetNet*sig, unsigned port_wid, NetNet::PortType dir, bool as_signed) const; }; #endif /* IVL_PGate_H */ iverilog-12_0/PGenerate.cc000066400000000000000000000036401435245347300155330ustar00rootroot00000000000000/* * Copyright (c) 2006-2021 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 "PGenerate.h" # include "PWire.h" # include "ivl_assert.h" using namespace std; PGenerate::PGenerate(LexicalScope*parent, unsigned id) : LexicalScope(parent), id_number(id) { scheme_type = GS_NONE; directly_nested = false; local_index = false; loop_init = 0; loop_test = 0; loop_step = 0; } PGenerate::~PGenerate() { } void PGenerate::add_gate(PGate*gate) { gates.push_back(gate); } ostream& operator << (ostream&out, PGenerate::scheme_t type) { switch (type) { case PGenerate::GS_NONE: out << "GS_NONE"; break; case PGenerate::GS_LOOP: out << "GS_LOOP"; break; case PGenerate::GS_CONDIT: out << "GS_CONDIT"; break; case PGenerate::GS_ELSE: out << "GS_ELSE"; break; case PGenerate::GS_CASE: out << "GS_CASE"; break; case PGenerate::GS_CASE_ITEM: out << "GS_CASE_ITEM"; break; case PGenerate::GS_NBLOCK: out << "GS_NBLOCK"; break; } return out; } PNamedItem::SymbolType PGenerate::symbol_type() const { return GENBLOCK; } iverilog-12_0/PGenerate.h000066400000000000000000000114531435245347300153760ustar00rootroot00000000000000#ifndef IVL_PGenerate_H #define IVL_PGenerate_H /* * Copyright (c) 2006-2021 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 "PNamedItem.h" # include "StringHeap.h" # include "HName.h" # include "PScope.h" # include # include # include # include "pform_types.h" class Design; class NetScope; class PExpr; class PFunction; class PProcess; class PTask; class PGate; class PWire; /* * This represents a generate scheme. The interpretation of the * members depends on the scheme_type. * * GS_LOOP * * GS_CASE * loop_test is the expression to be compared. * generates contains only GS_CASE_ITEM schemes. * GS_CASE_ITEM * The parent points to the GS_CASE that contains this item. * the loop_test is compared with the parent->loop_test expression. */ class PGenerate : public PNamedItem, public LexicalScope { public: explicit PGenerate(LexicalScope*parent, unsigned id_number); ~PGenerate(); // Generate schemes have an ID number, for when the scope is // implicit. const unsigned id_number; perm_string scope_name; // This is used during parsing to stack lexical scopes within // this generate scheme. // LexicalScope*lexical_scope; enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE, GS_CASE, GS_CASE_ITEM, GS_NBLOCK}; scheme_t scheme_type; bool directly_nested; // generate loops have an index variable and three // expressions: for (index = ; ; index=) // the index is local if it was declared in the init expression, // e.g. for (genvar index = ; ; index=) bool local_index; perm_string loop_index; PExpr*loop_init; PExpr*loop_test; PExpr*loop_step; // Case items may have multiple guard expression values. It is // enough for any on of the guards to match the case statement // test value. std::valarray item_test; // defparam assignments found in this scope. typedef std::pair named_expr_t; std::listdefparms; std::list gates; void add_gate(PGate*); // Tasks instantiated within this scheme. std::map tasks; std::mapfuncs; // Generate schemes can contain further generate schemes. std::list generate_schemes; // PGenerate*parent; // This method is called by the elaboration of a module to // generate scopes. the container is the scope that is to // contain the generated scope. bool generate_scope(Design*des, NetScope*container); // Elaborate signals within any of the generated scopes that // were made by this generate block within the given container scope. bool elaborate_sig(Design*des, NetScope*container) const; bool elaborate(Design*des, NetScope*container) const; void dump(std::ostream&out, unsigned indent) const; SymbolType symbol_type() const; private: void check_for_valid_genvar_value_(long value); bool generate_scope_loop_(Design*des, NetScope*container); bool generate_scope_condit_(Design*des, NetScope*container, bool else_flag); bool generate_scope_case_(Design*des, NetScope*container); bool generate_scope_nblock_(Design*des, NetScope*container); // Elaborate_scope within a generated scope. void elaborate_subscope_(Design*des, NetScope*scope); void elaborate_subscope_direct_(Design*des, NetScope*scope); // These are the scopes created by generate_scope. std::listscope_list_; // internal function called on each scope generated by this scheme. bool elaborate_sig_(Design*des, NetScope*scope) const; bool elaborate_sig_direct_(Design*des, NetScope*scope) const; bool elaborate_(Design*des, NetScope*scope) const; bool elaborate_direct_(Design*des, NetScope*scope) const; private: // not implemented PGenerate(const PGenerate&); PGenerate& operator= (const PGenerate&); }; extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t); #endif /* IVL_PGenerate_H */ iverilog-12_0/PModport.cc000066400000000000000000000020421435245347300154200ustar00rootroot00000000000000/* * Copyright (c) 2015-2019 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 "PModport.h" PModport::PModport(perm_string n) : name_(n) { } PModport::~PModport() { } PNamedItem::SymbolType PModport::symbol_type() const { return MODPORT; } iverilog-12_0/PModport.h000066400000000000000000000032471435245347300152720ustar00rootroot00000000000000#ifndef IVL_PModport_H #define IVL_PModport_H /* * Copyright (c) 2015-2021 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 "PNamedItem.h" # include "PScope.h" # include "StringHeap.h" # include "netlist.h" # include /* * The PModport class represents a parsed SystemVerilog modport list. */ class PModport : public PNamedItem { public: // The name is a perm-allocated string. It is the simple name // of the modport, without any scope. explicit PModport(perm_string name); ~PModport(); perm_string name() const { return name_; } typedef std::pair simple_port_t; std::map simple_ports; SymbolType symbol_type() const; private: perm_string name_; private: // not implemented PModport(const PModport&); PModport& operator= (const PModport&); }; #endif /* IVL_PModport_H */ iverilog-12_0/PNamedItem.cc000066400000000000000000000057261435245347300156530ustar00rootroot00000000000000/* * Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk) * * 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 "PNamedItem.h" # include PNamedItem::PNamedItem() { } PNamedItem::~PNamedItem() { } PNamedItem::SymbolType PNamedItem::symbol_type() const { return ANY; } std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st) { switch (st) { case PNamedItem::ANY: o << "a symbol"; break; case PNamedItem::PARAM: o << "a parameter"; break; case PNamedItem::NET: o << "a net"; break; case PNamedItem::VAR: o << "a variable"; break; case PNamedItem::GENVAR: o << "a genvar"; break; case PNamedItem::EVENT: o << "an event"; break; case PNamedItem::TYPE: o << "a type"; break; case PNamedItem::ENUM: o << "an enum type or value"; break; case PNamedItem::CLASS: o << "a class"; break; case PNamedItem::FUNCTION: o << "a function"; break; case PNamedItem::TASK: o << "a task"; break; case PNamedItem::BLOCK: o << "a named block"; break; case PNamedItem::GENBLOCK: o << "a generate block"; break; case PNamedItem::MODPORT: o << "a modport"; break; case PNamedItem::PACKAGE: o << "a package"; break; case PNamedItem::MODULE: o << "a module"; break; case PNamedItem::PROGRAM: o << "a program"; break; case PNamedItem::INTERFACE: o << "an interface"; break; case PNamedItem::PRIMITIVE: o << "a primitive"; break; case PNamedItem::INSTANCE: o << "an instance name"; break; default: break; } return o; } PGenvar::PGenvar() { } PGenvar::~PGenvar() { } PNamedItem::SymbolType PGenvar::symbol_type() const { return GENVAR; } iverilog-12_0/PNamedItem.h000066400000000000000000000034631435245347300155110ustar00rootroot00000000000000#ifndef IVL_PNamedItem_H #define IVL_PNamedItem_H /* * Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk) * * 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 "LineInfo.h" /* * The PNamedItem class is the base class for all items that can be added * to a scope's local symbol map. */ class PNamedItem : virtual public LineInfo { public: enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM, CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT, PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE, INSTANCE }; explicit PNamedItem(); virtual ~PNamedItem(); virtual SymbolType symbol_type() const; }; extern std::ostream& operator << (std::ostream&, PNamedItem::SymbolType); /* * The PGenvar class represents a genvar. This is only used to represent * genvar in a scope's local symbol map. */ class PGenvar : public PNamedItem { public: explicit PGenvar(); virtual ~PGenvar(); SymbolType symbol_type() const; }; #endif /* IVL_PNamedItem_H */ iverilog-12_0/PPackage.cc000066400000000000000000000020351435245347300153310ustar00rootroot00000000000000/* * Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "PPackage.h" PPackage::PPackage(perm_string name, LexicalScope*parent) : PScopeExtra(name, parent) { } PPackage::~PPackage() { } iverilog-12_0/PPackage.h000066400000000000000000000031171435245347300151750ustar00rootroot00000000000000#ifndef IVL_PPackage_H #define IVL_PPackage_H /* * Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "PScope.h" # include "LineInfo.h" # include "StringHeap.h" # include /* * SystemVerilog supports class declarations with their own lexical * scope, etc. The parser arranges for these to be created and * collected. */ class PPackage : public PScopeExtra, public LineInfo { public: explicit PPackage (perm_string name, LexicalScope*parent); ~PPackage(); bool elaborate_scope(Design*des, NetScope*scope); bool elaborate_sig(Design*des, NetScope*scope) const; bool elaborate(Design*des, NetScope*scope) const; void pform_dump(std::ostream&out) const; }; #endif /* IVL_PPackage_H */ iverilog-12_0/PScope.cc000066400000000000000000000034361435245347300150550ustar00rootroot00000000000000/* * Copyright (c) 2008-2021 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 "PScope.h" using namespace std; bool LexicalScope::var_init_needs_explicit_lifetime() const { return false; } PWire* LexicalScope::wires_find(perm_string name) { map::const_iterator cur = wires.find(name); if (cur == wires.end()) return 0; else return (*cur).second; } PNamedItem::SymbolType LexicalScope::param_expr_t::symbol_type() const { return PARAM; } PScope::PScope(perm_string n, LexicalScope*parent) : LexicalScope(parent), name_(n) { time_unit = 0; time_precision = 0; time_unit_is_default = true; time_prec_is_default = true; } PScope::~PScope() { for(typedef_map_t::iterator it = typedefs.begin(); it != typedefs.end(); ++it) delete it->second; } PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent) : PScope(n, parent) { time_unit_is_local = false; time_prec_is_local = false; } PScopeExtra::~PScopeExtra() { } iverilog-12_0/PScope.h000066400000000000000000000177331435245347300147240ustar00rootroot00000000000000#ifndef IVL_PScope_H #define IVL_PScope_H /* * Copyright (c) 2008-2021 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 "PNamedItem.h" # include "StringHeap.h" # include "pform_types.h" # include "ivl_target.h" # include # include # include class PEvent; class PExpr; class PFunction; class PPackage; class AProcess; class PProcess; class PClass; class PTask; class PWire; class Statement; class PCallTask; class Design; class NetScope; /* * The PScope class is a base representation of an object that * represents lexical scope. For example, a module, a function/task, a * named block is derived from a PScope. * * NOTE: This is not the same concept as the "scope" of an elaborated * hierarchy. That is represented by NetScope objects after elaboration. */ class LexicalScope { public: enum lifetime_t { INHERITED, STATIC, AUTOMATIC }; explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), has_parameter_port_list(false), generate_counter(0), parent_(parent) { } // A virtual destructor is so that dynamic_cast can work. virtual ~LexicalScope() { } lifetime_t default_lifetime; // Symbols that are defined or declared in this scope. std::maplocal_symbols; // Symbols that are explicitly imported. Bind the imported name // to the package from which the name is imported. std::mapexplicit_imports; // Packages that are wildcard imported. When identifiers from // these packages are referenced, they will be added to the // explicit imports (IEEE 1800-2012 26.3). std::listpotential_imports; // A task or function call may reference a task or function defined // later in the scope. So here we stash the potential imports for // task and function calls. They will be added to the explicit // imports if we don't find a local definition. std::mappossible_imports; struct range_t { // True if this is an exclude bool exclude_flag; // lower bound // If low_open_flag is false and low_expr=0, then use -inf bool low_open_flag; PExpr*low_expr; // upper bound // If high_open_flag is false and high_expr=0, then use +inf bool high_open_flag; PExpr*high_expr; // Next range description in list struct range_t*next; }; /* The scope has parameters that are evaluated when the scope is elaborated. During parsing, I put the parameters into this map. */ struct param_expr_t : public PNamedItem { inline param_expr_t() : data_type(0), expr(0), range(0), local_flag(false), overridable(true) { } // Type information. data_type_t*data_type; // Value expression PExpr*expr; // If there are range constraints, list them here range_t*range; // Whether it is a local parameter bool local_flag; // Whether the parameter can be overridden bool overridable; // Whether the parameter is a type parameter bool type_flag = false; SymbolType symbol_type() const; }; std::mapparameters; bool has_parameter_port_list; // Defined types in the scope. typedef std::map typedef_map_t; typedef_map_t typedefs; // Named events in the scope. std::mapevents; // Nets and variables (wires) in the scope std::mapwires; PWire* wires_find(perm_string name); // Genvars in the scope. These will only be present in module // scopes, but are listed here to allow them to be found when // creating implicit nets. std::map genvars; // Variable initializations in this scope std::vector var_inits; // Behaviors (processes) in this scope std::list behaviors; std::list analog_behaviors; // The elaboration tasks in this scope std::list elab_tasks; // Enumeration sets. std::vector enum_sets; // A count of the generate constructs in this scope. This is // used to automatically name unnamed generate blocks, as // specified in the LRM. unsigned generate_counter; LexicalScope* parent_scope() const { return parent_; } virtual bool var_init_needs_explicit_lifetime() const; protected: void dump_typedefs_(std::ostream&out, unsigned indent) const; void dump_parameters_(std::ostream&out, unsigned indent) const; void dump_enumerations_(std::ostream&out, unsigned indent) const; void dump_events_(std::ostream&out, unsigned indent) const; void dump_wires_(std::ostream&out, unsigned indent) const; void dump_var_inits_(std::ostream&out, unsigned indent) const; bool elaborate_var_inits_(Design*des, NetScope*scope) const; private: LexicalScope*parent_; }; class PScope : public LexicalScope { public: // When created, a scope has a name and a parent. The name is // the name of the definition. For example, if this is a // module declaration, the name is the name after the "module" // keyword, and if this is a task scope, the name is the task // name. The parent is the lexical parent of this scope. Since // modules do not nest in Verilog, the parent must be nil for // modules. Scopes for tasks and functions point to their // containing module. explicit PScope(perm_string name, LexicalScope*parent =0); virtual ~PScope(); perm_string pscope_name() const { return name_; } /* These are the timescale for this scope. The value is set by the `timescale directive or, in SystemVerilog, by timeunit and timeprecision statements. */ int time_unit, time_precision; /* Flags used to support warnings about timescales. */ bool time_unit_is_default; bool time_prec_is_default; bool has_explicit_timescale() const { return !(time_unit_is_default || time_prec_is_default); } protected: bool elaborate_sig_wires_(Design*des, NetScope*scope) const; bool elaborate_behaviors_(Design*des, NetScope*scope) const; private: perm_string name_; }; /* * Some scopes can carry definitions. These include Modules and PClass * scopes. These derive from PScopeExtra so that they hold the maps of * extra definitions. */ class PScopeExtra : public PScope { public: explicit PScopeExtra(perm_string, LexicalScope*parent =0); ~PScopeExtra(); /* Task definitions within this module */ std::map tasks; std::map funcs; /* Class definitions within this module. */ std::map classes; /* This is the lexical order of the classes, and is used by elaboration to choose an elaboration order. */ std::vector classes_lexical; /* Flags used to support warnings about timescales. */ bool time_unit_is_local; bool time_prec_is_local; protected: void dump_classes_(std::ostream&out, unsigned indent) const; void dump_tasks_(std::ostream&out, unsigned indent) const; void dump_funcs_(std::ostream&out, unsigned indent) const; }; #endif /* IVL_PScope_H */ iverilog-12_0/PSpec.cc000066400000000000000000000022341435245347300146710ustar00rootroot00000000000000/* * Copyright (c) 2006-2011 Stephen Williams * * 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 "PSpec.h" PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, bool full_flag) : conditional(false), condition(0), edge(0), src(src_cnt), dst(dst_cnt), data_source_expression(0) { full_flag_ = full_flag; polarity_ = polarity; } PSpecPath::~PSpecPath() { } iverilog-12_0/PSpec.h000066400000000000000000000055741435245347300145450ustar00rootroot00000000000000#ifndef IVL_PSpec_H #define IVL_PSpec_H /* * Copyright (c) 2006-2014 Stephen Williams * * 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 "LineInfo.h" # include "StringHeap.h" # include class PExpr; /* * The PSpecPath is the parse of a specify path, which is in its most * general form = . The are collected into the * "delays" vector in all cases, and the variety is in the other * members. * * All paths also have a list of source names in the src vector, and a * list of destination names in the dst vector. These pairs are the * actual paths. * * If the path is a simple path, then: * condition == nil * edge == 0 * data_source_expression == nil * * If the path is conditional, then conditional == true and condition * is the condition expression. If the condition expression is nil, * then this is an ifnone conditional path. * * If data_source_expression != nil, then the path is edge sensitive * and the edge might not be 0. * * The full flag is used to verify that only vectors of the same size * are used in a parallel connection. Icarus always creates a full * connection between the source and destination. The polarity is for * informational (display) purposes only. The polarity is either '+', * '-' or 0. */ class PSpecPath : public LineInfo { public: PSpecPath(unsigned src_cnt, unsigned dst_cnt, char polarity, bool full_flag); ~PSpecPath(); void elaborate(class Design*des, class NetScope*scope) const; void dump(std::ostream&out, unsigned ind) const; public: // Condition expression, if present. bool conditional; class PExpr* condition; // Edge specification (-1==negedge, 0 = no edge, 1==posedge) int edge; // Is this a full connection. bool full_flag_; // What is the polarity of the connection. char polarity_; // Ordered set of source nodes of a path std::vector src; // Ordered set of destination nodes of a path std::vector dst; // Data source expression class PExpr* data_source_expression; std::vectordelays; }; #endif /* IVL_PSpec_H */ iverilog-12_0/PTask.cc000066400000000000000000000040321435245347300146770ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "PTask.h" # include using namespace std; PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p) : PScope(n,p), this_type_(0), ports_(0) { } PTaskFunc::~PTaskFunc() { } bool PTaskFunc::var_init_needs_explicit_lifetime() const { return default_lifetime == STATIC; } void PTaskFunc::set_ports(vector*p) { assert(ports_ == 0); ports_ = p; } void PTaskFunc::set_this(class_type_t*type, PWire*this_wire) { assert(this_type_ == 0); this_type_ = type; // Push a synthesis argument that is the "this" value. if (ports_==0) ports_ = new vector; size_t use_size = ports_->size(); ports_->resize(use_size + 1); for (size_t idx = use_size ; idx > 0 ; idx -= 1) ports_->at(idx) = ports_->at(idx-1); ports_->at(0) = pform_tf_port_t(this_wire); } PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__) : PTaskFunc(name, parent), statement_(0) { is_auto_ = is_auto__; } PTask::~PTask() { } void PTask::set_statement(Statement*s) { assert(statement_ == 0); statement_ = s; } PNamedItem::SymbolType PTask::symbol_type() const { return TASK; } iverilog-12_0/PTask.h000066400000000000000000000127721435245347300145530ustar00rootroot00000000000000#ifndef IVL_PTask_H #define IVL_PTask_H /* * Copyright (c) 1999-2021 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 "PScope.h" # include "PNamedItem.h" # include "StringHeap.h" # include # include # include class Design; class NetExpr; class NetNet; class NetScope; class PChainConstructor; class PWire; class Statement; class PExpr; class PTaskFunc : public PScope, public PNamedItem { public: PTaskFunc(perm_string name, LexicalScope*parent); ~PTaskFunc(); bool var_init_needs_explicit_lifetime() const; void set_ports(std::vector*p); void set_this(class_type_t*use_type, PWire*this_wire); // If this task is a method of a class, this returns a pointer // to the class type. inline class_type_t* method_of() const { return this_type_; } virtual void elaborate_sig(Design*des, NetScope*scope) const =0; virtual void elaborate(Design*des, NetScope*scope) const =0; virtual void dump(std::ostream&, unsigned) const =0; protected: // Elaborate the ports list. Write into the ports vector the // NetNet pointers for the ports, and write into the pdefs the // default value expressions, if any. void elaborate_sig_ports_(Design*des, NetScope*scope, std::vector&ports, std::vector&pdefs) const; void dump_ports_(std::ostream&out, unsigned ind) const; private: class_type_t*this_type_; std::vector*ports_; }; /* * The PTask holds the parsed definitions of a task. */ class PTask : public PTaskFunc { public: explicit PTask(perm_string name, LexicalScope*parent, bool is_auto); ~PTask(); void set_statement(Statement *s); // Tasks introduce scope, to need to be handled during the // scope elaboration pass. The scope passed is my scope, // created by the containing scope. I fill it in with stuff if // I need to. void elaborate_scope(Design*des, NetScope*scope) const; // Bind the ports to the regs that are the ports. void elaborate_sig(Design*des, NetScope*scope) const; // Elaborate the statement to finish off the task definition. void elaborate(Design*des, NetScope*scope) const; bool is_auto() const { return is_auto_; }; void dump(std::ostream&, unsigned) const; SymbolType symbol_type() const; private: Statement*statement_; bool is_auto_; private: // Not implemented PTask(const PTask&); PTask& operator=(const PTask&); }; /* * The function is similar to a task (in this context) but there is a * single output port and a set of input ports. The output port is the * function return value. * * The output value is not elaborated until elaborate_sig. */ class PFunction : public PTaskFunc { public: explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto); ~PFunction(); void set_statement(Statement *s); void set_return(data_type_t*t); inline Statement* get_statement() { return statement_; } // Push this statement to the front of the existing // definition. If the statement is a simple statement, make a // block to contain the statements. void push_statement_front(Statement*stmt); // This is only used if this function is a constructor. In // that case, this method looks for a PChainConstructor in the // statement and extracts it if found. PChainConstructor*extract_chain_constructor(); void elaborate_scope(Design*des, NetScope*scope) const; /* elaborate the ports and return value. */ void elaborate_sig(Design *des, NetScope*) const; /* Elaborate the behavioral statement. */ void elaborate(Design *des, NetScope*) const; bool is_auto() const { return is_auto_; }; void dump(std::ostream&, unsigned) const; SymbolType symbol_type() const; private: data_type_t* return_type_; Statement *statement_; bool is_auto_; }; // A let is like a simple function that is expanded in the compiler class PLet : public PTaskFunc { public: typedef struct let_port { data_type_t*type_; perm_string name_; std::list*range_; PExpr*def_; void dump(std::ostream&, unsigned) const; } let_port_t; // FIXME: Should the port list be a vector. Check once implemented completely explicit PLet(perm_string name, LexicalScope*parent, std::list*ports, PExpr*expr); ~PLet(); void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; } void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; } void dump(std::ostream&, unsigned) const; private: std::list*ports_; PExpr*expr_; }; #endif /* IVL_PTask_H */ iverilog-12_0/PUdp.cc000066400000000000000000000022411435245347300145250ustar00rootroot00000000000000/* * Copyright (c) 2003-2004 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 "PUdp.h" PUdp::PUdp(perm_string n, unsigned nports) : ports(nports), sequential(false), initial(verinum::Vx), name_(n) { } unsigned PUdp::find_port(const char*name) { for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { if (ports[idx] == name) return idx; } return ports.size(); } iverilog-12_0/PUdp.h000066400000000000000000000046031435245347300143730ustar00rootroot00000000000000#ifndef IVL_PUdp_H #define IVL_PUdp_H /* * Copyright (c) 1998-2021 Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include "LineInfo.h" # include "StringHeap.h" # include "verinum.h" class PExpr; /* * This class represents a parsed UDP. This is a much simpler object * than a module or macromodule. * * - all ports are scalar, * - pin 0 (the first port) is always output, * and the remaining pins are input. * * Thus, the ports can be represented as an ordered list of pin names. * If the output port is declared as a register in the Verilog source, * then this is a sequential UDP and the sequential flag is set to true. * * STATE TABLE * Each entry in the state table is given as a string with the same * number of characters as inputs. If the UDP is sequential, a * character is also included at the end of the string to represent * the current output. * * If the UDP is sequential, the "initial" member is taken to be the * initial value assigned in the source, or 'x' if none is given. */ class PUdp : public LineInfo { public: explicit PUdp(perm_string n, unsigned nports); std::vector ports; unsigned find_port(const char*name); bool sequential; std::vector tinput; std::vector tcurrent; std::vector toutput; verinum::V initial; std::map attributes; void dump(std::ostream&out) const; perm_string name_; private: private: // Not implemented PUdp(const PUdp&); PUdp& operator= (const PUdp&); }; #endif /* IVL_PUdp_H */ iverilog-12_0/PWire.cc000066400000000000000000000107761435245347300147170ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "ivl_assert.h" # include "PWire.h" # include "PExpr.h" # include using namespace std; PWire::PWire(perm_string n, NetNet::Type t, NetNet::PortType pt, PWSRType rt) : name_(n), type_(t), port_type_(pt), signed_(false), port_set_(false), net_set_(false), is_scalar_(false), error_cnt_(0), discipline_(0) { switch (rt) { case SR_PORT: port_set_ = true; break; case SR_NET: net_set_ = true; break; case SR_BOTH: port_set_ = true; net_set_ = true; break; } } NetNet::Type PWire::get_wire_type() const { return type_; } perm_string PWire::basename() const { return name_; } bool PWire::set_wire_type(NetNet::Type t) { assert(t != NetNet::IMPLICIT); switch (type_) { case NetNet::IMPLICIT: type_ = t; return true; case NetNet::IMPLICIT_REG: if (t == NetNet::REG) { type_ = t; return true; } if (t == NetNet::IMPLICIT_REG) return true; return false; case NetNet::REG: if (t == NetNet::REG) return true; return false; default: if (type_ != t) return false; else return true; } } NetNet::PortType PWire::get_port_type() const { return port_type_; } bool PWire::set_port_type(NetNet::PortType pt) { assert(pt != NetNet::NOT_A_PORT); assert(pt != NetNet::PIMPLICIT); switch (port_type_) { case NetNet::PIMPLICIT: case NetNet::NOT_A_PORT: port_type_ = pt; return true; default: if (port_type_ != pt) return false; else return true; } } void PWire::set_signed(bool flag) { // For a non-ANSI style port declaration where the data type is // specified in a corresponding variable declaration, the signed // attribute may be attached to either the port declaration or to // the variable declaration (IEEE 1364-2005 section 12.3.3). The // signal is signed if either the port or the variable is signed. // Handle that here. signed_ = signed_ || flag; } bool PWire::get_signed() const { return signed_; } void PWire::set_port(NetNet::PortType pt) { ivl_assert(*this, !port_set_); port_set_ = true; bool rc = set_port_type(pt); ivl_assert(*this, rc); } void PWire::set_net(NetNet::Type t) { ivl_assert(*this, !net_set_); net_set_ = true; if (t != NetNet::IMPLICIT) { bool rc = set_wire_type(t); ivl_assert(*this, rc); } } void PWire::set_range(const list&rlist, PWSRType type) { switch (type) { case SR_PORT: if (!port_.empty()) return; port_ = rlist; break; case SR_NET: if (!net_.empty()) return; net_ = rlist; break; case SR_BOTH: if (!port_.empty() || !net_.empty()) return; port_ = rlist; net_ = rlist; break; } } void PWire::set_unpacked_idx(const list&ranges) { if (! unpacked_.empty()) { cerr << get_fileline() << ": error: Array ``" << name_ << "'' has already been declared." << endl; error_cnt_ += 1; } else { unpacked_ = ranges; } } void PWire::set_data_type(data_type_t*type) { if (set_data_type_.get() == type) return; assert(!set_data_type_.get()); set_data_type_.reset(type); } void PWire::set_discipline(ivl_discipline_t d) { assert(discipline_ == 0); discipline_ = d; } ivl_discipline_t PWire::get_discipline(void) const { return discipline_; } PNamedItem::SymbolType PWire::symbol_type() const { switch (type_) { case NetNet::IMPLICIT_REG: case NetNet::REG: return VAR; default: return NET; } } iverilog-12_0/PWire.h000066400000000000000000000103311435245347300145440ustar00rootroot00000000000000#ifndef IVL_PWire_H #define IVL_PWire_H /* * Copyright (c) 1998-2021 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 "netlist.h" # include "PNamedItem.h" # include # include # include "StringHeap.h" #ifdef HAVE_IOSFWD # include #else # include #endif class PExpr; class Design; class netdarray_t; /* * The different type of PWire::set_range() calls. */ enum PWSRType {SR_PORT, SR_NET, SR_BOTH}; /* * Wires include nets, registers and ports. A net or register becomes * a port by declaration, so ports are not separate. The module * identifies a port by keeping it in its port list. * * The hname parameter to the constructor is a hierarchical name. It * is the name of the wire within a module, so does not include the * current scope or any instances. Modules contain all the wires, so * from that perspective, sub-scopes within the module are a part of * the wire name. */ class PWire : public PNamedItem { public: PWire(perm_string name, NetNet::Type t, NetNet::PortType pt, PWSRType rt = SR_NET); // Return a hierarchical name. perm_string basename() const; NetNet::Type get_wire_type() const; bool set_wire_type(NetNet::Type); NetNet::PortType get_port_type() const; bool set_port_type(NetNet::PortType); void set_signed(bool flag); bool get_signed() const; void set_range(const std::list&ranges, PWSRType type); void set_unpacked_idx(const std::list&ranges); void set_data_type(data_type_t*type); void set_discipline(ivl_discipline_t); ivl_discipline_t get_discipline(void) const; std::map attributes; // Write myself to the specified stream. void dump(std::ostream&out, unsigned ind=4) const; NetNet* elaborate_sig(Design*, NetScope*scope) const; SymbolType symbol_type() const; bool is_net() const { return net_set_; }; bool is_port() const { return port_set_; }; void set_net(NetNet::Type t); void set_port(NetNet::PortType pt); private: perm_string name_; NetNet::Type type_; NetNet::PortType port_type_; bool signed_; // These members hold expressions for the bit width of the // wire. If they do not exist, the wire is 1 bit wide. If they // do exist, they represent the packed dimensions of the // bit. The first item in the list is the first range, and so // on. For example "reg [3:0][7:0] ..." will contains the // range_t object for [3:0] first and [7:0] last. std::listport_; bool port_set_; std::listnet_; bool net_set_; bool is_scalar_; unsigned error_cnt_; // If this wire is actually a memory, these indices will give // me the size and address ranges of the memory. std::listunpacked_; // This is the complex type of the wire. the data_type_ may // modify how this is interpreted. std::unique_ptr set_data_type_; ivl_discipline_t discipline_; private: // not implemented PWire(const PWire&); PWire& operator= (const PWire&); ivl_type_t elaborate_type(Design*des, NetScope*scope, const std::vector&packed_dimensions) const; ivl_type_t elaborate_darray_type(Design*des, NetScope*scope, const char *darray_type, const std::vector&packed_dimensions) const; }; #endif /* IVL_PWire_H */ iverilog-12_0/QUICK_START.txt000066400000000000000000000057211435245347300157460ustar00rootroot00000000000000 * Getting Started with Icarus Verilog Icarus Verilog is a Verilog compiler. It is suitable for use as a simulator, and, to some degree, synthesizer. Icarus Verilog runs under Linux and a variety of UNIX systems, as well as Windows as a command line tool, so the instructions are generally applicable to all environments. Note that this is only a quick start. For more detailed documentation, see the manual page for the iverilog command. * Hello, World! The first thing you want to do as a user is learn how to compile and execute even the most trivial design. For the purposes of simulation, we use as our example *the* most trivial simulation: module main; initial begin $display("Hello, World"); $finish ; end endmodule By a text editor (or copy hello.vl from the Icarus Verilog examples directory) arrange for this program to be in a text file, "hello.vl". Next, compile this program with a command like this: % iverilog -o hello hello.vl The results of this compile are placed into the file "hello", as the "-o" flag tells the compiler where to place the compiled result. Next, execute the compiled program like so: % vvp hello Hello, World And there it is, the program has been executed. So what happened? The first step, the "iverilog" command, read and interpreted the source file, then generated a compiled result. The compiled form may be selected by command line switches, but the default form is the VVP format, which is actually run by the "vvp" command. The "iverilog" and "vvp" commands are the only commands that users use to invoke Icarus Verilog. What the compiler actually does is controlled by command line switches. In our little example, we asked the compiler to compile the source program to the default vvp form, which is in turn executed by the vvp program. * Windows Install The easiest way to install under Windows is to get a precompiled installer for the version you wish to install. Icarus Verilog is distributed for Windows users as a self-installing .exe. Just execute the installer and follow the instructions. During the install, take note of the directory where the program is installed: for example, C:\iverilog is a good place to install. Once the binary is installed, you need to add the bin directory to your execution path. The executables you need are in C:\iverilog\bin, where the "C:\iverilog" part is actually the root of where you installed the package. The programs are in the bin subdirectory. Put this directory in your PATH environment variable, and the above commands become accessible to you at the command line prompt, or even in batch files. * Linux Install Under Linux, the install is even easier. For RedHat and Mandrake based systems, there is the appropriate RPM file. Just install the package with the "rpm -U " command. Debian users should get Icarus Verilog packages from the main Debian software site. * Install From Source In this case, see README.txt and other documentation that comes with the source. iverilog-12_0/README.md000066400000000000000000000440251435245347300146330ustar00rootroot00000000000000# The ICARUS Verilog Compilation System Copyright 2000-2019 Stephen Williams ## What is ICARUS Verilog? Icarus Verilog is intended to compile ALL of the Verilog HDL as described in the IEEE-1364 standard. Of course, it's not quite there yet. It does currently handle a mix of structural and behavioural constructs. For a view of the current state of Icarus Verilog, see its home page at http://iverilog.icarus.com/. Icarus Verilog is not aimed at being a simulator in the traditional sense, but a compiler that generates code employed by back-end tools. > For instructions on how to run Icarus Verilog, see the `iverilog` man page. ## Building/Installing Icarus Verilog From Source If you are starting from the source, the build process is designed to be as simple as practical. Someone basically familiar with the target system and C/C++ compilation should be able to build the source distribution with little effort. Some actual programming skills are not required, but helpful in case of problems. > If you are building on Windows, see the mingw.txt file. ### Compile Time Prerequisites You need the following software to compile Icarus Verilog from source on a UNIX-like system: - GNU Make The Makefiles use some GNU extensions, so a basic POSIX make will not work. Linux systems typically come with a satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD) typically have GNU make as the gmake program. - ISO C++ Compiler The ivl and ivlpp programs are written in C++ and make use of templates and some of the standard C++ library. egcs and recent gcc compilers with the associated libstdc++ are known to work. MSVC++ 5 and 6 are known to definitely *not* work. - bison and flex OSX note: bison 2.3 shipped with MacOS including Catalina generates broken code, but bison 3+ works. We recommend using the Fink project version of bison and flex (finkproject.org), brew version works fine either. - gperf 3.0 or later The lexical analyzer doesn't recognize keywords directly, but instead matches symbols and looks them up in a hash table in order to get the proper lexical code. The gperf program generates the lookup table. A version problem with this program is the most common cause of difficulty. See the Icarus Verilog FAQ. - readline 4.2 or later On Linux systems, this usually means the readline-devel rpm. In any case, it is the development headers of readline that are needed. - termcap The readline library, in turn, uses termcap. > If you are building from git, you will also need software to generate the configure scripts. - autoconf 2.53 or later This generates configure scripts from configure.ac. The 2.53 or later versions are known to work, autoconf 2.13 is reported to *not* work. ### Compilation Unpack the tar-ball and cd into the `verilog-#########` directory (presumably, that is how you got to this README) and compile the source with the commands: ``` ./configure make ``` If you are building from git, you have to run the command below before compiling the source. This will generate the "configure" file, which is automatically done when building from tarball. ``` sh autoconf.sh ``` Normally, this command automatically figures out everything it needs to know. It generally works pretty well. There are a few flags to the configure script that modify its behaviour: ``` --prefix= The default is /usr/local, which causes the tool suite to be compiled for install in /usr/local/bin, /usr/local/share/ivl, etc. I recommend that if you are configuring for precompiled binaries, use --prefix=/usr. On Solaris systems, it is common to use --prefix=/opt. You can configure for a non-root install with --prefix=$HOME. --enable-suffix --enable-suffix= --disable-suffix Enable/disable changing the names of install files to use a suffix string so that this version or install can co- exist with other versions. This renames the installed commands (iverilog, iverilog-vpi, vvp) and the installed library files and include directory so that installations with the same prefix but different suffix are guaranteed to not interfere with each other. --host= Compile iverilog for a different platform. You can use: x64_64-w64-mingw32 for building 64-bit Windows executables i686-w64-mingw32 for building 32-bit Windows executables Both options require installing the required mingw-w64 packages. ``` ### (Optional) Testing To run a simple test before installation, execute ``` make check ``` The commands printed by this run might help you in running Icarus Verilog on your own Verilog sources before the package is installed by root. ### Installation Now install the files in an appropriate place. (The makefiles by default install in /usr/local unless you specify a different prefix with the `--prefix=` flag to the configure command.) You may need to do this as root to gain access to installation directories. ``` make install ``` ### Uninstallation The generated Makefiles also include the uninstall target. This should remove all the files that `make install` creates. ## How Icarus Verilog Works This tool includes a parser which reads in Verilog (plus extensions) and generates an internal netlist. The netlist is passed to various processing steps that transform the design to more optimal/practical forms, then is passed to a code generator for final output. The processing steps and the code generator are selected by command line switches. ### Preprocessing There is a separate program, ivlpp, that does the preprocessing. This program implements the `` `include `` and `` `define `` directives producing output that is equivalent but without the directives. The output is a single file with line number directives, so that the actual compiler only sees a single input file. See ivlpp/ivlpp.txt for details. ### Parse The Verilog compiler starts by parsing the Verilog source file. The output of the parse is a list of Module objects in "pform". The pform (see `pform.h`) is mostly a direct reflection of the compilation step. There may be dangling references, and it is not yet clear which module is the root. One can see a human-readable version of the final pform by using the `-P ` flag to the `ivl` subcommand. This will cause ivl to dump the pform into the file named ``. (Note that this is not normally done, unless debugging the `ivl` subcommand.) ### Elaboration This phase takes the pform and generates a netlist. The driver selects (by user request or lucky guess) the root module to elaborate, resolves references and expands the instantiations to form the design netlist. (See netlist.txt.) Final semantic checks are performed during elaboration, and some simple optimizations are performed. The netlist includes all the behavioural descriptions, as well as gates and wires. The `elaborate()` function performs the elaboration. One can see a human-readable version of the final, elaborated and optimized netlist by using the `-N ` flag to the compiler. If elaboration succeeds, the final netlist (i.e., after optimizations but before code generation) will be dumped into the file named ``. Elaboration is performed in two steps: scopes and parameters first, followed by the structural and behavioural elaboration. #### Scope Elaboration This pass scans through the pform looking for scopes and parameters. A tree of NetScope objects is built up and placed in the Design object, with the root module represented by the root NetScope object. The `elab_scope.cc` file contains most of the code for handling this phase. The tail of the elaborate_scope behaviour (after the pform is traversed) includes a scan of the NetScope tree to locate defparam assignments that were collected during scope elaboration. This is when the defparam overrides are applied to the parameters. #### Netlist Elaboration After the scopes and parameters are generated and the NetScope tree fully formed, the elaboration runs through the pform again, this time generating the structural and behavioural netlist. Parameters are elaborated and evaluated by now so all the constants of code generation are now known locally, so the netlist can be generated by simply passing through the pform. ### Optimization This is a collection of processing steps that perform optimizations that do not depend on the target technology. Examples of some useful transformations are - eliminate null effect circuitry - combinational reduction - constant propagation The actual functions performed are specified on the `ivl` command line by the `-F` flags (see below). ### Code Generation This step takes the design netlist and uses it to drive the code generator (see target.h). This may require transforming the design to suit the technology. The `emit()` method of the Design class performs this step. It runs through the design elements, calling target functions as the need arises to generate actual output. The user selects the target code generator with the `-t` flag on the command line. ### ATTRIBUTES > NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized. The parser accepts, as an extension to Verilog, the $attribute module item. The syntax of the $attribute item is: ``` $attribute (, , ); ``` The $attribute keyword looks like a system task invocation. The difference here is that the parameters are more restricted than those of a system task. The `` must be an identifier. This will be the item to get an attribute. The `` and `` are strings, not expressions, that give the key and the value of the attribute to be attached to the identified object. Attributes are `[ ]` pairs and are used to communicate with the various processing steps. See the documentation for the processing step for a list of the pertinent attributes. Attributes can also be applied to gate types. When this is done, the attribute is given to every instantiation of the primitive. The syntax for the attribute statement is the same, except that the `` names a primitive earlier in the compilation unit and the statement is placed in the global scope, instead of within a module. The semicolon is not part of a type attribute. Note that attributes are also occasionally used for communication between processing steps. Processing steps that are aware of others may place attributes on netlist objects to communicate information to later steps. Icarus Verilog also accepts the Verilog 2001 syntax for attributes. They have the same general meaning as with the $attribute syntax, but they are attached to objects by position instead of by name. Also, the key is a Verilog identifier instead of a string. ## Running iverilog The preferred way to invoke the compiler is with the `iverilog`(1) command. This program invokes the preprocessor (ivlpp) and the compiler (`ivl`) with the proper command line options to get the job done in a friendly way. See the `iverilog`(1) man page for usage details. ## EXAMPLES Example: Compiling `"hello.vl"` ``` ------------------------ hello.vl ---------------------------- module main(); initial begin $display("Hi there"); $finish ; end endmodule -------------------------------------------------------------- ``` Ensure that `iverilog` is on your search path, and the vpi library is available. To compile the program: ``` iverilog hello.vl ``` (The above presumes that /usr/local/include and /usr/local/lib are part of the compiler search path, which is usually the case for gcc.) To run the program: ``` ./a.out ``` You can use the `-o` switch to name the output command to be generated by the compiler. See the `iverilog`(1) man page. ## Unsupported Constructs Icarus Verilog is in development - as such it still only supports a (growing) subset of Verilog. Below is a description of some of the currently unsupported Verilog features. This list is not exhaustive and does not account for errors in the compiler. See the Icarus Verilog web page for the current state of support for Verilog, and in particular, browse the bug report database for reported unsupported constructs. - System functions are supported, but the return value is a little tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page. - Specify blocks are parsed but ignored in general. - `trireg` is not supported. `tri0` and `tri1` are supported. - tran primitives, i.e. `tran`, `tranif1`, `tranif0`, `rtran`, `rtranif1` and `rtranif0` are not supported. - Net delays, of the form `wire #N foo;` do not work. Delays in every other context do work properly, including the V2001 form `wire #5 foo = bar;` - Event controls inside non-blocking assignments are not supported. i.e.: `a <= @(posedge clk) b;` - Macro arguments are not supported. `` `define `` macros are supported, but they cannot take arguments. ## Nonstandard Constructs or Behaviors Icarus Verilog includes some features that are not part of the IEEE1364 standard, but have well-defined meaning, and also sometimes gives nonstandard (but extended) meanings to some features of the language that are defined. See the "extensions.txt" documentation for more details. * `$is_signed()` This system function returns 1 if the expression contained is signed, or 0 otherwise. This is mostly of use for compiler regression tests. * `$sizeof()`, `$bits()` The `$bits` system function returns the size in bits of the expression that is its argument. The result of this function is undefined if the argument doesn't have a self-determined size. The `$sizeof` function is deprecated in favour of `$bits`, which is the same thing, but included in the SystemVerilog definition. * `$simtime` The `$simtime` system function returns as a 64bit value the simulation time, unscaled by the time units of local scope. This is different from the $time and $stime functions which return the scaled times. This function is added for regression testing of the compiler and run time, but can be used by applications who really want the simulation time. Note that the simulation time can be confusing if there are lots of different `` `timescales`` within a design. It is not in general possible to predict what the simulation precision will turn out to be. * `$mti_random()`, `$mti_dist_uniform` These functions are similar to the IEEE1364 standard $random functions, but they use the Mersenne Twister (MT19937) algorithm. This is considered an excellent random number generator, but does not generate the same sequence as the standardized $random. ### Builtin system functions Certain of the system functions have well-defined meanings, so can theoretically be evaluated at compile-time, instead of using runtime VPI code. Doing so means that VPI cannot override the definitions of functions handled in this manner. On the other hand, this makes them synthesizable, and also allows for more aggressive constant propagation. The functions handled in this manner are: * `$bits` * `$signed` * `$sizeof` * `$unsigned` Implementations of these system functions in VPI modules will be ignored. ### Preprocessing Library Modules Icarus Verilog does preprocess modules that are loaded from libraries via the -y mechanism. However, the only macros defined during the compilation of that file are those that it defines itself (or includes) or that are defined in the command line or command file. Specifically, macros defined in the non-library source files are not remembered when the library module is loaded. This is intentional. If it were otherwise, then compilation results might vary depending on the order that libraries are loaded, and that is too unpredictable. It is said that some commercial compilers do allow macro definitions to span library modules. That's just plain weird. ### Width in `%t` Time Formats Standard Verilog does not allow width fields in the %t formats of display strings. For example, this is illegal: ``` $display("Time is %0t", $time); ``` Standard Verilog instead relies on the $timeformat to completely specify the format. Icarus Verilog allows the programmer to specify the field width. The `%t` format in Icarus Verilog works exactly as it does in standard Verilog. However, if the programmer chooses to specify a minimum width (i.e., `%5t`), then for that display Icarus Verilog will override the `$timeformat` minimum width and use the explicit minimum width. ### vpiScope iterator on vpiScope objects. In the VPI, the normal way to iterate over vpiScope objects contained within a vpiScope object, is the vpiInternalScope iterator. Icarus Verilog adds support for the vpiScope iterator of a vpiScope object, that iterates over *everything* the is contained in the current scope. This is useful in cases where one wants to iterate over all the objects in a scope without iterating over all the contained types explicitly. ### time 0 race resolution. Combinational logic is routinely modelled using always blocks. However, this can lead to race conditions if the inputs to the combinational block are initialized in initial statements. Icarus Verilog slightly modifies time 0 scheduling by arranging for always statements with ANYEDGE sensitivity lists to be scheduled before any other threads. This causes combinational always blocks to be triggered when the values in the sensitivity list are initialized by initial threads. ### Nets with Types Icarus Verilog supports an extended syntax that allows nets and regs to be explicitly typed. The currently supported types are logic, bool and real. This implies that `logic` and `bool` are new keywords. Typical syntax is: ``` wire real foo = 1.0; reg logic bar, bat; ``` ... and so forth. The syntax can be turned off by using the -g2 flag to iverilog, and turned on explicitly with the -g2x flag to iverilog. ## CREDITS Except where otherwise noted, Icarus Verilog, ivl and ivlpp are Copyright Stephen Williams. The proper notices are in the head of each file. However, I have early on received aid in the form of fixes, Verilog guidance, and especially testing from many people. Testers, in particular, include a larger community of people interested in a GPL Verilog for Linux. iverilog-12_0/Statement.cc000066400000000000000000000203571435245347300156310ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 "Statement.h" # include "PExpr.h" # include "ivl_assert.h" using namespace std; Statement::~Statement() { } PAssign_::PAssign_(PExpr*lval__, PExpr*ex, bool is_constant) : event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(is_constant) { delay_ = 0; } PAssign_::PAssign_(PExpr*lval__, PExpr*de, PExpr*ex) : event_(0), count_(0), lval_(lval__), rval_(ex), is_constant_(false) { delay_ = de; } PAssign_::PAssign_(PExpr*lval__, PExpr*cnt, PEventStatement*ev, PExpr*ex) : event_(ev), count_(cnt), lval_(lval__), rval_(ex), is_constant_(false) { delay_ = 0; } PAssign_::~PAssign_() { delete lval_; delete rval_; } PAssign::PAssign(PExpr*lval__, PExpr*ex) : PAssign_(lval__, ex, false), op_(0) { } PAssign::PAssign(PExpr*lval__, char op, PExpr*ex) : PAssign_(lval__, ex, false), op_(op) { } PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex) : PAssign_(lval__, d, ex), op_(0) { } PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex) : PAssign_(lval__, cnt, d, ex), op_(0) { } PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant) : PAssign_(lval__, ex, is_constant), op_(0) { } PAssign::~PAssign() { } PAssignNB::PAssignNB(PExpr*lval__, PExpr*ex) : PAssign_(lval__, ex, false) { } PAssignNB::PAssignNB(PExpr*lval__, PExpr*d, PExpr*ex) : PAssign_(lval__, d, ex) { } PAssignNB::PAssignNB(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex) : PAssign_(lval__, cnt, d, ex) { } PAssignNB::~PAssignNB() { } PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t) : PScope(n, parent), bl_type_(t) { } PBlock::PBlock(BL_TYPE t) : PScope(perm_string()), bl_type_(t) { } PBlock::~PBlock() { for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) delete list_[idx]; } bool PBlock::var_init_needs_explicit_lifetime() const { return default_lifetime == STATIC; } PChainConstructor* PBlock::extract_chain_constructor() { if (list_.empty()) return 0; if (PChainConstructor*res = dynamic_cast (list_[0])) { for (size_t idx = 0 ; idx < list_.size()-1 ; idx += 1) list_[idx] = list_[idx+1]; list_.resize(list_.size()-1); return res; } return 0; } void PBlock::set_join_type(PBlock::BL_TYPE type) { assert(bl_type_ == BL_PAR); assert(type==BL_PAR || type==BL_JOIN_NONE || type==BL_JOIN_ANY); bl_type_ = type; } void PBlock::set_statement(const vector&st) { list_ = st; } void PBlock::push_statement_front(Statement*that) { ivl_assert(*this, bl_type_==BL_SEQ); list_.resize(list_.size()+1); for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1) list_[idx] = list_[idx-1]; list_[0] = that; } PNamedItem::SymbolType PBlock::symbol_type() const { return BLOCK; } PCallTask::PCallTask(const pform_name_t&n, const list&p) : package_(0), path_(n), parms_(p.size()) { list::const_iterator cur = p.begin(); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx] = *cur; ++cur; } assert(cur == p.end()); } PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list&p) : package_(pkg), path_(n), parms_(p.size()) { list::const_iterator cur = p.begin(); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx] = *cur; ++cur; } assert(cur == p.end()); } PCallTask::PCallTask(perm_string n, const list&p) : package_(0), parms_(p.size()) { list::const_iterator cur = p.begin(); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx] = *cur; ++cur; } assert(cur == p.end()); path_.push_back(name_component_t(n)); } PCallTask::~PCallTask() { } const pform_name_t& PCallTask::path() const { return path_; } PCase::PCase(ivl_case_quality_t q, NetCase::TYPE t, PExpr*ex, std::vector*l) : quality_(q), type_(t), expr_(ex), items_(l) { } PCase::~PCase() { delete expr_; for (unsigned idx = 0 ; idx < items_->size() ; idx += 1) if ((*items_)[idx]->stat) delete (*items_)[idx]->stat; delete[]items_; } PCAssign::PCAssign(PExpr*l, PExpr*r) : lval_(l), expr_(r) { } PCAssign::~PCAssign() { delete lval_; delete expr_; } PChainConstructor::PChainConstructor(const list&parms) : parms_(parms.size()) { list::const_iterator cur = parms.begin(); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { parms_[idx] = *cur; ++cur; } assert(cur == parms.end()); } PChainConstructor::~PChainConstructor() { } PCondit::PCondit(PExpr*ex, Statement*i, Statement*e) : expr_(ex), if_(i), else_(e) { } PCondit::~PCondit() { delete expr_; delete if_; delete else_; } PDeassign::PDeassign(PExpr*l) : lval_(l) { } PDeassign::~PDeassign() { delete lval_; } PDelayStatement::PDelayStatement(PExpr*d, Statement*st) : delay_(d), statement_(st) { } PDelayStatement::~PDelayStatement() { } PDisable::PDisable(const pform_name_t&sc) : scope_(sc) { } PDisable::~PDisable() { } PDoWhile::PDoWhile(PExpr*ex, Statement*st) : cond_(ex), statement_(st) { } PDoWhile::~PDoWhile() { delete cond_; delete statement_; } PEventStatement::PEventStatement(const std::vector&ee) : expr_(ee), statement_(0), always_sens_(false) { assert(expr_.size() > 0); } PEventStatement::PEventStatement(PEEvent*ee) : expr_(1), statement_(0), always_sens_(false) { expr_[0] = ee; } PEventStatement::PEventStatement(bool always_sens) : statement_(0), always_sens_(always_sens) { } PEventStatement::~PEventStatement() { // delete the events and the statement? } void PEventStatement::set_statement(Statement*st) { statement_ = st; } bool PEventStatement::has_aa_term(Design*des, NetScope*scope) { bool flag = false; for (unsigned idx = 0 ; idx < expr_.size() ; idx += 1) { flag = expr_[idx]->has_aa_term(des, scope) || flag; } return flag; } PForce::PForce(PExpr*l, PExpr*r) : lval_(l), expr_(r) { } PForce::~PForce() { delete lval_; delete expr_; } PForeach::PForeach(perm_string av, const list&ix, Statement*s) : array_var_(av), index_vars_(ix.size()), statement_(s) { size_t idx = 0; for (list::const_iterator cur = ix.begin() ; cur != ix.end() ; ++cur) index_vars_[idx++] = *cur; } PForeach::~PForeach() { delete statement_; } PForever::PForever(Statement*s) : statement_(s) { } PForever::~PForever() { delete statement_; } PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond, Statement*step, Statement*st) : name1_(n1), expr1_(e1), cond_(cond), step_(step), statement_(st) { } PForStatement::~PForStatement() { } PProcess::~PProcess() { delete statement_; } PRelease::PRelease(PExpr*l) : lval_(l) { } PRelease::~PRelease() { delete lval_; } PRepeat::PRepeat(PExpr*e, Statement*s) : expr_(e), statement_(s) { } PRepeat::~PRepeat() { delete expr_; delete statement_; } PReturn::PReturn(PExpr*e) : expr_(e) { } PReturn::~PReturn() { delete expr_; } PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev) : package_(pkg), event_(ev) { } PTrigger::~PTrigger() { } PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly) : event_(ev), dly_(dly) { } PNBTrigger::~PNBTrigger() { } PWhile::PWhile(PExpr*ex, Statement*st) : cond_(ex), statement_(st) { } PWhile::~PWhile() { delete cond_; delete statement_; } iverilog-12_0/Statement.h000066400000000000000000000441001435245347300154630ustar00rootroot00000000000000#ifndef IVL_Statement_H #define IVL_Statement_H /* * Copyright (c) 1998-2021 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 # include # include "ivl_target.h" # include "StringHeap.h" # include "PDelays.h" # include "PExpr.h" # include "PScope.h" # include "HName.h" # include "LineInfo.h" class PExpr; class PChainConstructor; class PPackage; class Statement; class PEventStatement; class Design; class NetAssign_; class NetCAssign; class NetDeassign; class NetForce; class NetScope; /* * The PProcess is the root of a behavioral process. Each process gets * one of these, which contains its type (initial, always, or final) * and a pointer to the single statement that is the process. A module * may have several concurrent processes. */ class PProcess : public LineInfo { public: PProcess(ivl_process_type_t t, Statement*st) : type_(t), statement_(st) { } virtual ~PProcess(); bool elaborate(Design*des, NetScope*scope) const; ivl_process_type_t type() const { return type_; } Statement*statement() { return statement_; } std::map attributes; virtual void dump(std::ostream&out, unsigned ind) const; private: ivl_process_type_t type_; Statement*statement_; }; /* * The PProcess is a process, the Statement is the actual action. In * fact, the Statement class is abstract and represents all the * possible kinds of statements that exist in Verilog. */ class Statement : virtual public LineInfo { public: Statement() { } virtual ~Statement() =0; virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; std::map attributes; }; /* * Assignment statements of the various forms are handled by this * type. The rvalue is an expression. The lvalue needs to be figured * out by the parser as much as possible. */ class PAssign_ : public Statement { public: explicit PAssign_(PExpr*lval, PExpr*ex, bool is_constant); explicit PAssign_(PExpr*lval, PExpr*de, PExpr*ex); explicit PAssign_(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); virtual ~PAssign_() =0; const PExpr* lval() const { return lval_; } PExpr* rval() const { return rval_; } protected: NetAssign_* elaborate_lval(Design*, NetScope*scope) const; NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type, ivl_variable_type_t lv_type, unsigned lv_width, bool force_unsigned =false) const; NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const; NetExpr* elaborate_rval_obj_(Design*, NetScope*, ivl_variable_type_t type) const; PExpr* delay_; PEventStatement*event_; PExpr* count_; private: PExpr* lval_; PExpr* rval_; bool is_constant_; }; class PAssign : public PAssign_ { public: // lval - assignment l-value // ex - assignment r-value // op - compressed assignment operator (i.e. '+', '-', ...) // de - delayed assignment delay expression explicit PAssign(PExpr*lval, PExpr*ex); explicit PAssign(PExpr*lval, char op, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant); ~PAssign(); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; private: NetProc* elaborate_compressed_(Design*des, NetScope*scope) const; char op_; }; class PAssignNB : public PAssign_ { public: explicit PAssignNB(PExpr*lval, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex); explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); ~PAssignNB(); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; private: NetProc*assign_to_memory_(class NetMemory*, PExpr*, Design*des, NetScope*scope) const; }; /* * A block statement is an ordered list of statements that make up the * block. The block can be sequential or parallel, which only affects * how the block is interpreted. The parser collects the list of * statements before constructing this object, so it knows a priori * what is contained. */ class PBlock : public PScope, public Statement, public PNamedItem { public: enum BL_TYPE { BL_SEQ, BL_PAR, BL_JOIN_NONE, BL_JOIN_ANY }; // If the block has a name, it is a scope and also has a parent. explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t); // If it doesn't have a name, it's not a scope explicit PBlock(BL_TYPE t); ~PBlock(); BL_TYPE bl_type() const { return bl_type_; } bool var_init_needs_explicit_lifetime() const; // This is only used if this block is the statement list for a // constructor. We look for a PChainConstructor as the first // statement, and if it is there, extract it. PChainConstructor*extract_chain_constructor(); // If the bl_type() is BL_PAR, it is possible to replace it // with JOIN_NONE or JOIN_ANY. This is to help the parser. void set_join_type(BL_TYPE); void set_statement(const std::vector&st); // Copy the statement from that block to the front of this // block. void push_statement_front(Statement*that); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; SymbolType symbol_type() const; private: BL_TYPE bl_type_; std::vectorlist_; }; class PCallTask : public Statement { public: explicit PCallTask(PPackage*pkg, const pform_name_t&n, const std::list&parms); explicit PCallTask(const pform_name_t&n, const std::list&parms); explicit PCallTask(perm_string n, const std::list&parms); ~PCallTask(); const pform_name_t& path() const; virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; bool elaborate_elab(Design*des, NetScope*scope) const; void void_cast() { void_cast_ = true; } private: NetProc* elaborate_sys(Design*des, NetScope*scope) const; NetProc* elaborate_usr(Design*des, NetScope*scope) const; NetProc*elaborate_method_(Design*des, NetScope*scope, bool add_this_flag = false) const; NetProc*elaborate_function_(Design*des, NetScope*scope) const; NetProc*elaborate_void_function_(Design*des, NetScope*scope, NetFuncDef*def) const; NetProc *elaborate_non_void_function_(Design *des, NetScope *scope) const; NetProc*elaborate_build_call_(Design*des, NetScope*scope, NetScope*task, NetExpr*use_this) const; NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, const char*sys_task_name) const; NetProc*elaborate_queue_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, const char*sys_task_name) const; NetProc*elaborate_method_func_(NetScope*scope, NetNet*net, ivl_type_t type, perm_string method_name, const char*sys_task_name) const; bool test_task_calls_ok_(Design*des, NetScope*scope) const; PPackage*package_; pform_name_t path_; std::vector parms_; bool void_cast_ = false; }; class PCase : public Statement { public: struct Item { std::listexpr; Statement*stat; }; PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, std::vector*); ~PCase(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: ivl_case_quality_t quality_; NetCase::TYPE type_; PExpr*expr_; std::vector*items_; private: // not implemented PCase(const PCase&); PCase& operator= (const PCase&); }; class PCAssign : public Statement { public: explicit PCAssign(PExpr*l, PExpr*r); ~PCAssign(); virtual NetCAssign* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*lval_; PExpr*expr_; }; /* * This represents the syntax "super.new(...)". This is not really an * executable statement, but the elaborator will handle these * specially and will remove them from the statement stream. If any */ class PChainConstructor : public Statement { public: explicit PChainConstructor(const std::list&parms); ~PChainConstructor(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; inline const std::vector& chain_args(void) const { return parms_; } private: std::vector parms_; }; class PCondit : public Statement { public: PCondit(PExpr*ex, Statement*i, Statement*e); ~PCondit(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*expr_; Statement*if_; Statement*else_; private: // not implemented PCondit(const PCondit&); PCondit& operator= (const PCondit&); }; class PDeassign : public Statement { public: explicit PDeassign(PExpr*l); ~PDeassign(); virtual NetDeassign* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*lval_; }; class PDelayStatement : public Statement { public: PDelayStatement(PExpr*d, Statement*st); ~PDelayStatement(); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; private: PExpr*delay_; Statement*statement_; }; /* * This represents the parsing of a disable statement. */ class PDisable : public Statement { public: explicit PDisable(const pform_name_t&sc); ~PDisable(); virtual void dump(std::ostream&out, unsigned ind) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; private: pform_name_t scope_; }; class PDoWhile : public Statement { public: PDoWhile(PExpr*ex, Statement*st); ~PDoWhile(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*cond_; Statement*statement_; }; /* * The event statement represents the event delay in behavioral * code. It comes from such things as: * * @name ; * @(expr) ; * @* ; */ class PEventStatement : public Statement { public: explicit PEventStatement(const std::vector&ee); explicit PEventStatement(PEEvent*ee); // Make an @* statement or make a special @* version with the items // from functions added and outputs removed for always_comb/latch. explicit PEventStatement(bool always_sens = false); ~PEventStatement(); void set_statement(Statement*st); virtual void dump(std::ostream&out, unsigned ind) const; // Call this with a NULL statement only. It is used to print // the event expression for inter-assignment event controls. virtual void dump_inline(std::ostream&out) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; bool has_aa_term(Design*des, NetScope*scope); // This method is used to elaborate, but attach a previously // elaborated statement to the event. NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const; NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const; NetProc* elaborate_wait_fork(Design*des, NetScope*scope) const; private: std::vectorexpr_; Statement*statement_; bool always_sens_; }; std::ostream& operator << (std::ostream&o, const PEventStatement&obj); class PForce : public Statement { public: explicit PForce(PExpr*l, PExpr*r); ~PForce(); virtual NetForce* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*lval_; PExpr*expr_; }; class PForeach : public Statement { public: explicit PForeach(perm_string var, const std::list&ix, Statement*stmt); ~PForeach(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: NetProc* elaborate_static_array_(Design*des, NetScope*scope, const std::vector&dims) const; private: perm_string array_var_; std::vector index_vars_; Statement*statement_; }; class PForever : public Statement { public: explicit PForever(Statement*s); ~PForever(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: Statement*statement_; }; class PForStatement : public Statement { public: PForStatement(PExpr*n1, PExpr*e1, PExpr*cond, Statement*step, Statement*body); ~PForStatement(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr* name1_; PExpr* expr1_; PExpr*cond_; Statement*step_; Statement*statement_; }; class PNoop : public Statement { public: PNoop() { } ~PNoop() { } }; class PRepeat : public Statement { public: explicit PRepeat(PExpr*expr, Statement*s); ~PRepeat(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*expr_; Statement*statement_; }; class PRelease : public Statement { public: explicit PRelease(PExpr*l); ~PRelease(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*lval_; }; class PReturn : public Statement { public: explicit PReturn(PExpr*e); ~PReturn(); NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*expr_; }; /* * The PTrigger statement sends a trigger to a named event. Take the * name here. */ class PTrigger : public Statement { public: explicit PTrigger(PPackage*pkg, const pform_name_t&ev); ~PTrigger(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PPackage*package_; pform_name_t event_; }; class PNBTrigger : public Statement { public: explicit PNBTrigger(const pform_name_t&ev, PExpr*dly); ~PNBTrigger(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: pform_name_t event_; PExpr*dly_; }; class PWhile : public Statement { public: PWhile(PExpr*ex, Statement*st); ~PWhile(); virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual void elaborate_scope(Design*des, NetScope*scope) const; virtual void elaborate_sig(Design*des, NetScope*scope) const; virtual void dump(std::ostream&out, unsigned ind) const; private: PExpr*cond_; Statement*statement_; }; #endif /* IVL_Statement_H */ iverilog-12_0/_pli_types.h.in000066400000000000000000000046101435245347300162750ustar00rootroot00000000000000#ifndef PLI_TYPES_H #define PLI_TYPES_H /* * Copyright (c) 2003-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. */ # undef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H /* * If the host environment has the stdint.h header file, * then use that to size our PLI types. */ #ifndef __STDC_FORMAT_MACROS # define __STDC_FORMAT_MACROS #endif # include typedef uint64_t PLI_UINT64; typedef int64_t PLI_INT64; typedef uint32_t PLI_UINT32; typedef int32_t PLI_INT32; typedef signed short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; # define PLI_UINT64_FMT PRIu64 #else /* * If we do not have the c99 stdint.h header file, then use * configure detection to guess the pli types ourselves. */ # define SIZEOF_UNSIGNED_LONG_LONG 8 # define SIZEOF_UNSIGNED_LONG 8 # define SIZEOF_UNSIGNED 4 #if SIZEOF_UNSIGNED >= 8 typedef unsigned PLI_UINT64; typedef int PLI_INT64; # define PLI_UINT64_FMT "u" #else # if SIZEOF_UNSIGNED_LONG >= 8 typedef unsigned long PLI_UINT64; typedef long PLI_INT64; # define PLI_UINT64_FMT "lu" # else # if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG typedef unsigned long long PLI_UINT64; typedef long long PLI_INT64; # define PLI_UINT64_FMT "llu" # else typedef unsigned long PLI_UINT64; typedef long PLI_INT64; # define PLI_UINT64_FMT "lu" # endif # endif #endif typedef signed int PLI_INT32; typedef unsigned int PLI_UINT32; typedef signed short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; #endif #endif /* PLI_TYPES_H */ iverilog-12_0/acc_user.h000066400000000000000000000167521435245347300153170ustar00rootroot00000000000000#ifndef ACC_USER_H #define ACC_USER_H /* * Copyright (c) 2002-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. */ /* * This header file contains the definitions and declarations needed * by an Icarus Verilog user using acc_ routines. * * NOTE: Icarus Verilog does not support acc_ routines. This is just a * stub. The functions that are implemented here are actually * implemented using VPI routines. */ #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_END } #else # define EXTERN_C_START # define EXTERN_C_END # define bool int #endif EXTERN_C_START # include "_pli_types.h" /* * This is a declaration of the "handle" type that is compatible with * the vpiHandle from vpi_user.h. The libveriuser library implements * the acc handle type as a vpiHandle, to prevent useless indirection. */ typedef struct __vpiHandle *handle; /* OBJECT TYPES */ #define accModule 20 #define accScope 21 #define accNet 25 #define accReg 30 #define accIntegerParam 200 #define accRealParam 202 #define accStringParam 204 #define accParameter 220 #define accTopModule 224 #define accModuleInstance 226 #define accWire 260 #define accNamedEvent 280 #define accIntegerVar 281 #define accRealVar 282 #define accTimeVar 283 #define accIntVar accIntegerVar #define accScalar 300 #define accVector 302 #define accUnknown 412 #define accConstant 600 /* type VALUES FOR t_setval_delay STRUCTURE */ #define accNoDelay 0 #define accInertialDelay 1 #define accTransportDelay 2 #define accPureTransportDelay 3 #define accForceFlag 4 #define accReleaseFlag 5 /* type VALUES FOR t_setval_value STRUCTURE */ #define accBinStrVal 1 #define accOctStrVal 2 #define accDecStrVal 3 #define accHexStrVal 4 #define accScalarVal 5 #define accIntVal 6 #define accRealVal 7 #define accStringVal 8 #define accVectorVal 9 /* Scalar values */ #define acc0 0 #define acc1 1 #define accX 2 #define accZ 3 /* type VALUES FOR t_acc_time STRUCTURE */ #define accTime 1 #define accSimTime 2 #define accRealTime 3 /* reason codes */ #define logic_value_change 1 #define strength_value_change 2 #define real_value_change 3 #define vector_value_change 4 #define event_value_change 5 #define integer_value_change 6 #define time_value_change 7 #define sregister_value_change 8 #define vregister_value_change 9 #define realtime_value_change 10 /* VCL strength values */ #define vclSupply 7 #define vclStrong 6 #define vclPull 5 #define vclLarge 4 #define vclWeak 3 #define vclMedium 2 #define vclSmall 1 #define vclHighZ 0 /* Constants used by acc_vcl_add */ #define vcl_verilog_logic 2 #define VCL_VERILOG_LOGIC vcl_verilog_logic #define vcl_verilog_strength 3 #define VCL_VERILOG_STRENGTH vcl_verilog_strength typedef struct t_acc_time { int type; int low, high; double real; } s_acc_time, *p_acc_time; typedef struct t_setval_delay { s_acc_time time; int model; } s_setval_delay, *p_setval_delay; typedef struct t_acc_vecval { int aval; int bval; } s_acc_vecval, *p_acc_vecval; typedef struct t_setval_value { int format; union { char*str; int scalar; int integer; double real; p_acc_vecval vector; } value; } s_setval_value, *p_setval_value, s_acc_value, *p_acc_value; typedef struct t_strengths { PLI_UBYTE8 logic_value; PLI_UBYTE8 strength1; PLI_UBYTE8 strength2; } s_strengths, *p_strengths; typedef struct t_vc_record { PLI_INT32 vc_reason; PLI_INT32 vc_hightime; PLI_INT32 vc_lowtime; void* user_data; union { PLI_UBYTE8 logic_value; double real_value; handle vector_handle; s_strengths strengths_s; } out_value; } s_vc_record, *p_vc_record; typedef struct t_location { PLI_INT32 line_no; const char*filename; } s_location, *p_location; extern int acc_error_flag; extern int acc_initialize(void); extern void acc_close(void); /* * This is the acc_configure command, and the config_param * codes that are accepted. */ extern int acc_configure(PLI_INT32 config_param, const char*value); #define accEnableArgs 6 #define accDevelopmentVersion 11 extern int acc_fetch_argc(void); extern char**acc_fetch_argv(void); extern PLI_INT32 acc_fetch_direction(handle obj); /* XXXX FIXME: Values returned by acc_fetch_direction */ # define accInout 2 extern char* acc_fetch_fullname(handle obj); extern int acc_fetch_location(p_location loc, handle obj); extern char* acc_fetch_name(handle obj); extern char* acc_fetch_defname(handle obj); extern double acc_fetch_paramval(handle obj); extern double acc_fetch_tfarg(PLI_INT32); extern double acc_fetch_itfarg(PLI_INT32, handle); extern PLI_INT32 acc_fetch_tfarg_int(PLI_INT32); extern PLI_INT32 acc_fetch_itfarg_int(PLI_INT32, handle); extern char* acc_fetch_tfarg_str(PLI_INT32); extern char* acc_fetch_itfarg_str(PLI_INT32, handle); typedef struct t_timescale_info { PLI_INT16 unit; PLI_INT16 precision; } s_timescale_info, *p_timescale_info; extern void acc_fetch_timescale_info(handle obj, p_timescale_info info); extern PLI_INT32 acc_fetch_size(handle obj); extern PLI_INT32 acc_fetch_type(handle obj); extern PLI_INT32 acc_fetch_fulltype(handle obj); extern PLI_INT32 acc_fetch_paramtype(handle obj); extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb); extern const char* acc_fetch_type_str(PLI_INT32 type); extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value); extern handle acc_handle_by_name(const char*name, handle scope); extern handle acc_handle_hiconn(handle port_ref_handle); extern handle acc_handle_object(const char*name); extern handle acc_handle_parent(handle obj); extern handle acc_handle_scope(handle obj); extern handle acc_handle_simulated_net(handle net); extern handle acc_handle_tfarg(int n); extern handle acc_handle_tfinst(void); extern PLI_INT32 acc_compare_handles(handle, handle); extern handle acc_next(PLI_INT32 *, handle, handle); extern handle acc_next_bit(handle ref, handle bit); extern handle acc_next_port(handle ref, handle bit); extern handle acc_next_scope(handle, handle); extern handle acc_next_topmod(handle prev_topmod); extern int acc_object_in_typelist(handle object, PLI_INT32*typelist); extern int acc_object_of_type(handle object, PLI_INT32 type); extern char*acc_product_version(void); extern char*acc_set_scope(handle ref, ...); extern int acc_set_value(handle obj, p_setval_value value, p_setval_delay delay); extern void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record), void*data, PLI_INT32 vcl_flag); extern void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record), void*data, PLI_INT32 vcl_flag); extern char* acc_version(void); EXTERN_C_END #endif /* ACC_USER_H */ iverilog-12_0/aclocal.m4000066400000000000000000000265531435245347300152220ustar00rootroot00000000000000 # AX_ENABLE_SUFFIX # ---------------- # Create the configure option --enable-suffix[=suffix] to generate suffix # strings for the installed commands. This allows for shared installs of # different builds. Remember to change the default suffix string to some # value appropriate for the current version. AC_DEFUN([AX_ENABLE_SUFFIX], [AC_ARG_ENABLE([suffix],[AS_HELP_STRING([--enable-suffix], [Use/set the installation command suffix])], [true],[enable_suffix=no]) if test X$enable_suffix = Xyes; then install_suffix='-0.10' elif test X$enable_suffix = Xno; then install_suffix='' else install_suffix="$enable_suffix" fi AC_SUBST(install_suffix) ])# AX_ENABLE_SUFFIX # _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH) # ------------------------------ # Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING. # Unwarranted assumptions: # - the object file produced by AC_COMPILE_IFELSE is called # "conftest.$ac_objext" # - the nm(1) utility or an equivalent is available, and its name # is defined by the $NM variable. AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF], [AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])], [AS_IF([$NM conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])], [AC_MSG_ERROR([underscore test crashed])] )]) # AX_C_UNDERSCORES_LEADING # --------------------------------- # Check if symbol names in object files produced by C compiler have # leading underscores. Define NEED_LU if so. AC_DEFUN([AX_C_UNDERSCORES_LEADING], [AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading, [_AX_C_UNDERSCORES_MATCH_IF([_underscore], [AS_VAR_SET(ax_cv_c_underscores_leading, yes)], [AS_VAR_SET(ax_cv_c_underscores_leading, no)])]) if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.]) fi ])# AX_C_UNDERSCORES_LEADING # AX_C_UNDERSCORES_TRAILING # --------------------------------- # Check if symbol names in object files produced by C compiler have # trailing underscores. Define NEED_TU if so. AC_DEFUN([AX_C_UNDERSCORES_TRAILING], [AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing, [_AX_C_UNDERSCORES_MATCH_IF([underscore_], [AS_VAR_SET(ax_cv_c_underscores_trailing, yes)], [AS_VAR_SET(ax_cv_c_underscores_trailing, no)])]) if test $ax_cv_c_underscores_trailing = yes; then AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.]) fi ])# AX_C_UNDERSCORES_TRAILING # AX_WIN32 # -------- # Combined check for several flavors of Microsoft Windows so # their "issues" can be dealt with AC_DEFUN([AX_WIN32], [AC_MSG_CHECKING([for Microsoft Windows]) AC_REQUIRE([AC_CANONICAL_HOST]) []dnl case $host_os in *cygwin*) MINGW32=no; WIN32=yes;; *mingw*) MINGW32=yes; WIN32=yes;; *) MINGW32=no; WIN32=no;; esac AC_SUBST(MINGW32) AC_SUBST(WIN32) AC_MSG_RESULT($WIN32) if test $WIN32 = yes; then AC_MSG_CHECKING([for MinGW]) AC_MSG_RESULT($MINGW32) fi ])# AX_WIN32 # AX_LD_EXTRALIBS # --------------- # mingw needs to link with libiberty.a, but cygwin alone can't tolerate it AC_DEFUN([AX_LD_EXTRALIBS], [AC_MSG_CHECKING([for extra libs needed]) EXTRALIBS= case "${host}" in *-*-cygwin* ) if test "$MINGW32" = "yes"; then EXTRALIBS="-liberty" fi ;; esac AC_SUBST(EXTRALIBS) AC_MSG_RESULT($EXTRALIBS) ])# AX_LD_EXTRALIBS # AX_LD_SHAREDLIB_OPTS # -------------------- # linker options when building a shared library AC_DEFUN([AX_LD_SHAREDLIB_OPTS], [AC_MSG_CHECKING([for shared library link flag]) shared=-shared case "${host}" in *-*-cygwin*) shared="-shared -Wl,--enable-auto-image-base" ;; *-*-mingw*) shared="-shared -Wl,--enable-auto-image-base" ;; *-*-hpux*) shared="-b" ;; *-*-darwin1.[0123]) shared="-bundle -undefined suppress" ;; *-*-darwin*) shared="-bundle -undefined suppress -flat_namespace" ;; *-*-solaris*) if test ${using_sunpro_c} = 1 then shared="-G" fi ;; esac AC_SUBST(shared) AC_MSG_RESULT($shared) ])# AX_LD_SHAREDLIB_OPTS # AX_C_PICFLAG # ------------ # The -fPIC flag is used to tell the compiler to make position # independent code. It is needed when making shared objects. AC_DEFUN([AX_C_PICFLAG], [AC_MSG_CHECKING([for flag to make position independent code]) PICFLAG=-fPIC case "${host}" in *-*-cygwin*) PICFLAG= ;; *-*-mingw*) PICFLAG= ;; *-*-hpux*) PICFLAG=+z ;; *-*-solaris*) if test ${using_sunpro_c} = 1 then PICFLAG=-G fi ;; esac AC_SUBST(PICFLAG) AC_MSG_RESULT($PICFLAG) ])# AX_C_PICFLAG # AX_LD_RDYNAMIC # -------------- # The -rdynamic flag is used by iverilog when compiling the target, # to know how to export symbols of the main program to loadable modules # that are brought in by -ldl AC_DEFUN([AX_LD_RDYNAMIC], [AC_MSG_CHECKING([for -rdynamic compiler flag]) rdynamic=-rdynamic case "${host}" in *-*-netbsd*) rdynamic="-Wl,--export-dynamic" ;; *-*-openbsd*) rdynamic="-Wl,--export-dynamic" ;; *-*-solaris*) rdynamic="" ;; *-*-cygwin*) rdynamic="" ;; *-*-mingw*) rdynamic="" ;; *-*-hpux*) rdynamic="-E" ;; *-*-darwin*) rdynamic="-Wl,-all_load" strip_dynamic="-SX" ;; esac AC_SUBST(rdynamic) AC_MSG_RESULT($rdynamic) AC_SUBST(strip_dynamic) # since we didn't tell them we're "checking", no good place to tell the answer # AC_MSG_RESULT($strip_dynamic) ])# AX_LD_RDYNAMIC # AX_C99_STRTOD # ------------- AC_DEFUN([AX_C99_STRTOD], [# On MinGW we need to jump through hoops to get a C99 compliant strtod(). # mingw-w64 doesn't need this, and the 64-bit version doesn't support it. case "${host}" in x86_64-w64-mingw32) ;; *-*-mingw32) LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod" ;; esac ])# AX_C99_STRTOD # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp file name are based on the header name. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [ _config_header=$1 _stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name ]) #_AC_AM_CONFIG_HEADER_HOOK # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html # =========================================================================== # # SYNOPSIS # # AX_PROG_CC_FOR_BUILD # # DESCRIPTION # # This macro searches for a C compiler that generates native executables, # that is a C compiler that surely is not a cross-compiler. This can be # useful if you have to generate source code at compile-time like for # example GCC does. # # The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything # needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). # The value of these variables can be overridden by the user by specifying # a compiler with an environment variable (like you do for standard CC). # # It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object # file extensions for the build platform, and GCC_FOR_BUILD to `yes' if # the compiler we found is GCC. All these variables but GCC_FOR_BUILD are # substituted in the Makefile. # # LICENSE # # Copyright (c) 2008 Paolo Bonzini # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 18 AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CPP])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl dnl Use the standard macros, but make them use other variable names dnl pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl pushdef([ac_cv_objext], ac_cv_build_objext)dnl pushdef([ac_exeext], ac_build_exeext)dnl pushdef([ac_objext], ac_build_objext)dnl pushdef([CC], CC_FOR_BUILD)dnl pushdef([CPP], CPP_FOR_BUILD)dnl pushdef([GCC], GCC_FOR_BUILD)dnl pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl pushdef([EXEEXT], BUILD_EXEEXT)dnl pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl pushdef([OBJEXT], BUILD_OBJEXT)dnl pushdef([host], build)dnl pushdef([host_alias], build_alias)dnl pushdef([host_cpu], build_cpu)dnl pushdef([host_vendor], build_vendor)dnl pushdef([host_os], build_os)dnl pushdef([ac_cv_host], ac_cv_build)dnl pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl pushdef([ac_cv_host_os], ac_cv_build_os)dnl pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl pushdef([cross_compiling], cross_compiling_build)dnl cross_compiling_build=no ac_build_tool_prefix= AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"], [test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"]) AC_LANG_PUSH([C]) AC_PROG_CC _AC_COMPILER_EXEEXT _AC_COMPILER_OBJEXT AC_PROG_CPP dnl Restore the old definitions dnl popdef([cross_compiling])dnl popdef([am_cv_prog_cc_c_o])dnl popdef([am_cv_CC_dependencies_compiler_type])dnl popdef([ac_tool_prefix])dnl popdef([ac_cv_host_os])dnl popdef([ac_cv_host_vendor])dnl popdef([ac_cv_host_cpu])dnl popdef([ac_cv_host_alias])dnl popdef([ac_cv_host])dnl popdef([host_os])dnl popdef([host_vendor])dnl popdef([host_cpu])dnl popdef([host_alias])dnl popdef([host])dnl popdef([OBJEXT])dnl popdef([LDFLAGS])dnl popdef([EXEEXT])dnl popdef([CPPFLAGS])dnl popdef([CFLAGS])dnl popdef([GCC])dnl popdef([CPP])dnl popdef([CC])dnl popdef([ac_objext])dnl popdef([ac_exeext])dnl popdef([ac_cv_objext])dnl popdef([ac_cv_exeext])dnl popdef([ac_cv_c_compiler_gnu])dnl popdef([ac_cv_prog_cc_g])dnl popdef([ac_cv_prog_cc_cross])dnl popdef([ac_cv_prog_cc_works])dnl popdef([ac_cv_prog_cc_c89])dnl popdef([ac_cv_prog_gcc])dnl popdef([ac_cv_prog_CPP])dnl dnl restore global variables ac_ext, ac_cpp, ac_compile, dnl ac_link, ac_compiler_gnu (dependant on the current dnl language after popping): AC_LANG_POP([C]) dnl Finally, set Makefile variables dnl AC_SUBST(BUILD_EXEEXT)dnl AC_SUBST(BUILD_OBJEXT)dnl AC_SUBST([CFLAGS_FOR_BUILD])dnl AC_SUBST([CPPFLAGS_FOR_BUILD])dnl AC_SUBST([LDFLAGS_FOR_BUILD])dnl ]) iverilog-12_0/async.cc000066400000000000000000000050001435245347300147660ustar00rootroot00000000000000/* * Copyright (c) 2002-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 "functor.h" # include "netlist.h" # include bool NetAssign::is_asynchronous() { return true; } bool NetCondit::is_asynchronous() { return false; } /* * NetEvWait statements come from statements of the form @(...) in the * Verilog source. These event waits are considered asynchronous if * all of the events in the list are ANYEDGE, and all the inputs to * the statement are included in the sensitivity list. If any of the * events are posedge or negedge, the statement is synchronous * (i.e. an edge-triggered flip-flop) and if any of the inputs are * unaccounted for in the sensitivity list then the statement is a * latch. */ bool NetEvWait::is_asynchronous() { /* The "sense" set contains the set of Nexa that are in the sensitivity list. We also require that the events are all level sensitive, but the nex_async_ method takes care of that test. */ NexusSet*sense = new NexusSet; for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { NexusSet*tmp = events_[idx]->nex_async_(); if (tmp == 0) { delete sense; return false; } sense->add(*tmp); delete tmp; } NexusSet*inputs = statement_->nex_input(); if (! sense->contains(*inputs)) { delete sense; delete inputs; return false; } delete sense; delete inputs; /* If it passes all the other tests, then this statement is asynchronous. */ return true; } bool NetProc::is_asynchronous() { return false; } bool NetProcTop::is_asynchronous() const { if (type_ == IVL_PR_INITIAL) return false; return statement_->is_asynchronous(); } iverilog-12_0/attributes.txt000066400000000000000000000055371435245347300163100ustar00rootroot00000000000000 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-12_0/autoconf.sh000066400000000000000000000011641435245347300155230ustar00rootroot00000000000000#!/bin/sh # # This shell script exists to run autoconf on source distributions # that are pulled from git The configure script is not included # in git, so it is easiest to just run this script whenever needed # to generate the configure script. # echo "Autoconf in root..." autoconf -f echo "Precompiling lexor_keyword.gperf" gperf -o -i 7 -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc echo "Precompiling vhdlpp/lexor_keyword.gperf" (cd vhdlpp ; gperf -o -i 7 --ignore-case -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc ) iverilog-12_0/cadpli/000077500000000000000000000000001435245347300146035ustar00rootroot00000000000000iverilog-12_0/cadpli/Makefile.in000066400000000000000000000045211435245347300166520ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include vpidir = @libdir@/ivl$(suffix) CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = cadpli.o all: dep cadpli.vpl $(ALL32) check: all clean: rm -rf *.o dep cadpli.vpl distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=cadpli/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< mv $*.d dep SYSTEM_VPI_LDFLAGS = -L../vpi -lvpi ifeq (@MINGW32@,yes) SYSTEM_VPI_LDFLAGS += @EXTRALIBS@ endif cadpli.vpl: $O ../vpi/libvpi.a ../libveriuser/libveriuser.o $(CC) @shared@ $(LDFLAGS) -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS) install: all installdirs installfiles F = ./cadpli.vpl installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./cadpli.vpl "$(DESTDIR)$(vpidir)/cadpli.vpl" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(vpidir)" uninstall: $(UNINSTALL32) rm -f "$(DESTDIR)$(vpidir)/cadpli.vpl" uninstall32: -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/cadpli/cadpli.c000066400000000000000000000041701435245347300162050ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include # include # include # include "config.h" # include "ivl_dlfcn.h" # include "ivl_alloc.h" typedef void* (*funcvp)(void); static void thunker_register(void) { struct t_vpi_vlog_info vlog_info; void*mod; void*boot; struct t_tfcell*tf; int idx; vpi_get_vlog_info(&vlog_info); for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { char*module, *cp, *bp; if (strncmp("-cadpli=", vlog_info.argv[idx], 8) != 0) continue; cp = vlog_info.argv[idx] + 8; assert(cp); bp = strchr(cp, ':'); assert(bp); module = malloc(bp-cp+1); strncpy(module, cp, bp-cp); module[bp-cp] = 0; mod = ivl_dlopen(module); if (mod == 0) { vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror()); free(module); continue; } bp += 1; boot = ivl_dlsym(mod, bp); if (boot == 0) { vpi_printf("%s: Symbol %s not found.\n", vlog_info.argv[idx], bp); free(module); continue; } free(module); assert(boot); tf = (*((funcvp)boot))(); assert(tf); veriusertfs_register_table(tf); } } void (*vlog_startup_routines[])(void) = { thunker_register, 0 }; iverilog-12_0/cadpli/cadpli.txt000066400000000000000000000032011435245347300165740ustar00rootroot00000000000000 CADENCE PLI1 MODULES Copyright 2003 Stephen Williams 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-12_0/cadpli/ivl_dlfcn.h000066400000000000000000000052321435245347300167160ustar00rootroot00000000000000#ifndef IVL_ivl_dlfcn_H #define IVL_ivl_dlfcn_H /* * Copyright (c) 2001-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. */ #if defined(__MINGW32__) # include # include typedef void * ivl_dll_t; #elif defined(HAVE_DLFCN_H) # include typedef void* ivl_dll_t; #elif defined(HAVE_DL_H) # include typedef shl_t ivl_dll_t; #endif #if defined(__MINGW32__) static __inline__ ivl_dll_t ivl_dlopen(const char *name) { return (void *)LoadLibrary(name); } static __inline__ void *ivl_dlsym(ivl_dll_t dll, const char *nm) { return (void *)GetProcAddress((HINSTANCE)dll,nm);} static __inline__ void ivl_dlclose(ivl_dll_t dll) { (void)FreeLibrary((HINSTANCE)dll);} static __inline__ const char *dlerror(void) { static char msg[256]; unsigned long err = GetLastError(); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &msg, sizeof(msg) - 1, NULL ); return msg; } #elif defined(HAVE_DLFCN_H) static __inline__ ivl_dll_t ivl_dlopen(const char*name) { return dlopen(name,RTLD_LAZY); } static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm) { void*sym = dlsym(dll, nm); /* Not found? try without the leading _ */ if (sym == 0 && nm[0] == '_') sym = dlsym(dll, nm+1); return sym; } static __inline__ void ivl_dlclose(ivl_dll_t dll) { dlclose(dll); } #elif defined(HAVE_DL_H) static __inline__ ivl_dll_t ivl_dlopen(const char*name) { return shl_load(name, BIND_IMMEDIATE, 0); } static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm) { void*sym; int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym); return (rc == 0) ? sym : 0; } static __inline__ void ivl_dlclose(ivl_dll_t dll) { shl_unload(dll); } static __inline__ const char*dlerror(void) { return strerror( errno ); } #endif #endif /* IVL_ivl_dlfcn_H */ iverilog-12_0/check.conf000066400000000000000000000000771435245347300152770ustar00rootroot00000000000000functor:cprop functor:nodangle -t:dll flag:DLL=tgt-vvp/vvp.tgt iverilog-12_0/compiler.h000066400000000000000000000232151435245347300153350ustar00rootroot00000000000000#ifndef IVL_compiler_H #define IVL_compiler_H /* * Copyright (c) 1999-2021 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 # include "netlist.h" # include "StringHeap.h" /* * This defines constants and defaults for the compiler in general. */ /* * The integer_width is the width of integer variables. This is also * the minimum width of unsized integers when they are found in * self-determined contexts. */ extern unsigned integer_width; /* * The width_cap is the width limit for unsized expressions. */ extern unsigned width_cap; /* * This is the maximum number of recursive module loops allowed within * a generate block. */ extern unsigned recursive_mod_limit; /* The TIME_WIDTH is the width of time variables. */ #ifndef TIME_WIDTH # define TIME_WIDTH 64 #endif /* * When doing dynamic linking, we need a uniform way to identify the * symbol. Some compilers put leading _, some trailing _. The * configure script figures out which is the local convention and * defines NEED_LU and NEED_TU as required. */ #ifdef NEED_LU #define LU "_" #else #define LU "" #endif #ifdef NEED_TU #define TU "_" #else #define TU "" #endif /* * These are flags to enable various sorts of warnings. By default all * the warnings are off, the -W parameter arranges for each to be * enabled. */ /* Implicit definitions of wires. */ extern bool warn_implicit; /* Warn if dimensions of port or var/net are implicitly taken from the input/output/inout declaration. */ extern bool warn_implicit_dimensions; /* inherit timescales across files. */ extern bool warn_timescale; /* Warn about legal but questionable module port bindings. */ extern bool warn_portbinding; /* Warn about constant out of bound selects. */ extern bool warn_ob_select; /* Warn about structures that may have infinite loops. */ extern bool warn_inf_loop; /* Warn about always @* statements where a part or word select causes sensitivity to an entire vector or array. */ extern bool warn_sens_entire_vec; extern bool warn_sens_entire_arr; /* Warn about level-appropriate anachronisms. */ extern bool warn_anachronisms; /* Warn about nets that are references but not driven. */ extern bool warn_floating_nets; /* This is true if verbose output is requested. */ extern bool verbose_flag; extern bool debug_scopes; extern bool debug_eval_tree; extern bool debug_elaborate; extern bool debug_emit; extern bool debug_synth2; extern bool debug_optimizer; /* Ignore errors about missing modules */ extern bool ignore_missing_modules; /* Treat each source file as a separate compilation unit (as defined by SystemVerilog). */ extern bool separate_compilation; /* Control evaluation of functions at compile time: * 0 = only for functions in constant expressions * 1 = only for automatic functions * 2 = for all functions * Level 2 should only be used if the user can guarantee that a * function's local variables are never accessed from outside the * function. */ extern unsigned opt_const_func; /* Possibly temporary flag to control virtualization of pin arrays */ extern bool disable_virtual_pins; /* The vlog95 code generator does not want the compiler to generate concat-Z * LPM objects so this flag is used to block them from being generated. */ extern bool disable_concatz_generation; /* Limit to size of devirtualized arrays */ extern unsigned long array_size_limit; /* Path to a directory useful for finding subcomponents. */ extern const char*basedir; /* This is an ordered list of library suffixes to search. */ extern std::listlibrary_suff; extern int build_library_index(const char*path, bool key_case_sensitive); /* This is the generation of Verilog that the compiler is asked to support. Then there are also more detailed controls for more specific language features. Note that the compiler often assumes this is an ordered list. */ enum generation_t { GN_VER1995 = 1, GN_VER2001_NOCONFIG = 2, GN_VER2001 = 3, GN_VER2005 = 4, GN_VER2005_SV = 5, GN_VER2009 = 6, GN_VER2012 = 7, GN_DEFAULT = 4 }; extern generation_t generation_flag; /* If this flag is true, enable extended types support. */ extern bool gn_cadence_types_flag; /* If this flag is true, enable miscellaneous extensions. */ extern bool gn_icarus_misc_flag; /* If this flag is true, then elaborate specify blocks. If this flag is false, then skip elaboration of specify behavior. */ extern bool gn_specify_blocks_flag; /* If this flag is true, then elaborate supported assertion statements. If this flag is false, then stub out supported assertion statements. */ extern bool gn_supported_assertions_flag; /* If this flag is true, then error on unsupported assertion statements. If this flag is false, then stub out unsupported assertion statements. */ extern bool gn_unsupported_assertions_flag; /* If this flag is true, then support/elaborate Verilog-AMS. */ extern bool gn_verilog_ams_flag; /* If this flag is false a warning is printed when the port declaration is scalar and the net/register definition is vectored. */ extern bool gn_io_range_error_flag; /* If this flag is true, then force re-evaluation of user functions in a continuous assignment when any part of the expression is re-evaluated. */ extern bool gn_strict_ca_eval_flag; /* If this flag is true, then force strict conformance to the IEEE standard expression width rules. */ extern bool gn_strict_expr_width_flag; /* If this flag is true, then don't add a for-loop control variable to an implicit event_expression list if it is only used inside the loop. */ extern bool gn_shared_loop_index_flag; static inline bool gn_system_verilog(void) { if (generation_flag >= GN_VER2005_SV) return true; return false; } /* If variables can be converted to uwires by a continuous assignment (assuming no procedural assign), then return true. This will be true for SystemVerilog */ static inline bool gn_var_can_be_uwire(void) { return gn_system_verilog(); } static inline bool gn_modules_nest(void) { return gn_system_verilog(); } /* The bits of these GN_KEYWORDS_* constants define non-intersecting sets of keywords. The compiler enables groups of keywords by setting lexor_keyword_mask with the OR of the bits for the keywords to be enabled. */ enum { GN_KEYWORDS_1364_1995 = 0x0001, GN_KEYWORDS_1364_2001 = 0x0002, GN_KEYWORDS_1364_2001_CONFIG = 0x0004, GN_KEYWORDS_1364_2005 = 0x0008, GN_KEYWORDS_VAMS_2_3 = 0x0010, GN_KEYWORDS_1800_2005 = 0x0020, GN_KEYWORDS_1800_2009 = 0x0040, GN_KEYWORDS_1800_2012 = 0x0080, GN_KEYWORDS_ICARUS = 0x8000 }; extern int lexor_keyword_mask; /* This is the string to use to invoke the preprocessor. */ extern char*ivlpp_string; extern std::map missing_modules; /* Files that are library files are in this map. The lexor compares file names as it processes `line directives, and if the file name matches an entry in this table, it will turn on the library_active_flag so that modules know that they are in a library. */ extern std::map library_file_map; /* * the lex_strings are perm_strings made up of tokens from the source * file. Identifiers are so likely to be used many times that it makes * much sense to use a StringHeapLex to hold them. */ extern StringHeapLex lex_strings; /* * The ivl_target.h API in a variety of places keeps strings of * bits. Manage these as perm_string in a StringHeap. */ extern StringHeapLex bits_strings; /* * The filename_strings are perm_strings for file names. They are put * into their own StringHeapLex because these paths are used a *lot* * and this makes them more sure to hash together. */ extern StringHeapLex filename_strings; /* * system task/function listings. */ /* * This table describes all the return values of various system * functions. This table is used to elaborate expressions that are * system function calls. */ struct sfunc_return_type { const char* name; ivl_variable_type_t type; unsigned wid; bool signed_flag; bool override_flag; }; extern void add_sys_func(const struct sfunc_return_type&ret_type); extern const struct sfunc_return_type* lookup_sys_func(const char*name); extern int load_sys_func_table(const char*path); extern void cleanup_sys_func_table(); /* * This temporarily loads a VPI module, to determine the return values * of system functions provided by that module, and adds the return values * to the system function table. */ extern bool load_vpi_module(const char*path); /* * In system Verilog it is allowed with a warning to call a function * as a task. You can even cast the return value away and have no * warning message. */ extern ivl_sfunc_as_task_t def_sfunc_as_task; extern void pre_process_failed(const char*text); #endif /* IVL_compiler_H */ iverilog-12_0/config.guess000077500000000000000000001246371435245347300157040ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-03-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: iverilog-12_0/config.h.in000066400000000000000000000033571435245347300154020ustar00rootroot00000000000000#ifndef IVL_config_H /* -*- c++ -*- */ #define IVL_config_H /* * Copyright (c) 2001-2021 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. */ # undef NEED_LU # undef NEED_TU # undef WLU # undef WTU # undef HAVE_TIMES # undef HAVE_IOSFWD # undef HAVE_GETOPT_H # undef HAVE_INTTYPES_H # undef HAVE_LIBIBERTY_H # undef HAVE_DLFCN_H # undef HAVE_DL_H # undef HAVE_FCHMOD # undef HAVE_LIBREADLINE # undef HAVE_LIBZ # undef HAVE_LIBBZ2 # undef HAVE_LROUND # undef HAVE_SYS_WAIT_H # undef WORDS_BIGENDIAN #ifdef HAVE_INTTYPES_H # include #endif /* These two are needed by the lxt and lxt2 files (copied from GTKWave). */ # undef HAVE_ALLOCA_H # undef HAVE_FSEEKO /* And this is needed by the fst files (copied from GTKWave). */ # undef HAVE_LIBPTHREAD # undef HAVE_REALPATH /* * Define this if you want to compile vvp with memory freeing and * special valgrind hooks for the memory pools. */ # undef CHECK_WITH_VALGRIND #endif /* IVL_config_H */ iverilog-12_0/config.sub000077500000000000000000001063671435245347300153470ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. timestamp='2015-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: iverilog-12_0/configure.ac000066400000000000000000000243441435245347300156440ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_SRCDIR([netlist.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([_pli_types.h]) AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h]) AC_CONFIG_HEADERS([vvp/config.h]) AC_CONFIG_HEADERS([vpi/vpi_config.h]) AC_CONFIG_HEADERS([libveriuser/config.h]) AC_CONFIG_HEADERS([tgt-vvp/vvp_config.h]) AC_CONFIG_HEADERS([tgt-vhdl/vhdl_config.h]) AC_CONFIG_HEADERS([tgt-pcb/pcb_config.h]) AC_CANONICAL_HOST dnl Checks for programs. AC_PROG_CC AX_PROG_CC_FOR_BUILD AC_PREREQ([2.62]) m4_version_prereq([2.70], [], [AC_PROG_CC_C99]) AC_PROG_CXX AC_PROG_RANLIB AC_CHECK_TOOL(LD, ld, false) AC_CHECK_TOOL(AR, ar, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(STRIP, strip, true) AC_CHECK_TOOL(WINDRES,windres,false) AC_CHECK_PROGS(XGPERF,gperf,none) AC_CHECK_PROGS(MAN,man,none) AC_CHECK_PROGS(PS2PDF,ps2pdf,none) AC_CHECK_PROGS(GIT,git,none) if test "$XGPERF" = "none" then echo "" echo "*** Warning: No suitable gperf found. ***" echo " The gperf package is essential for building ivl from" echo " git sources, or modifying the parse engine of ivl itself." echo " You can get away without it when simply building from" echo " snapshots or major releases." echo "" fi AC_CHECK_PROGS(LEX,flex,none) if test "$LEX" = "none" then echo "*** Error: No suitable flex found. ***" echo " Please install the 'flex' package." exit 1 fi AC_CHECK_PROGS(YACC,bison,none) if test "$YACC" = "none" then echo "*** Error: No suitable bison found. ***" echo " Please install the 'bison' package." exit 1 fi if test "x$NM" = "x"; then NM=nm fi AC_EXEEXT AC_SUBST(EXEEXT) # Combined check for Microsoft-related bogosities; sets WIN32 if found AX_WIN32 # Check to see if we are using the Sun compiler. If so then configure # some of the flags to match the Sun compiler syntax. This is also used # in the aclocal.m4 file to configure the flags used to build and link # dynamic libraries AC_CHECK_DECL(__SUNPRO_C, using_sunpro_c=1, using_sunpro_c=0) if test ${using_sunpro_c} = 1 then AC_SUBST(DEPENDENCY_FLAG, [-xMMD]) AC_SUBST(WARNING_FLAGS, [""]) AC_SUBST(WARNING_FLAGS_CXX, [""]) else # Check to see if -Wextra is supported. iverilog_temp_cflags="$CFLAGS" CFLAGS="-Wextra $CFLAGS" AC_MSG_CHECKING(if gcc supports -Wextra) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [[iverilog_wextra_flag="-Wextra";] AC_MSG_RESULT(yes)], [[iverilog_wextra_flag="-W";] AC_MSG_RESULT(no)]) CFLAGS="$iverilog_temp_cflags" AC_SUBST(DEPENDENCY_FLAG, [-MD]) AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"]) AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"]) AC_SUBST(WARNING_FLAGS_CXX, [""]) fi AC_LANG(C++) AC_ARG_WITH([m32], [AS_HELP_STRING([--with-m32],[Compile 32-bit on x86_64])], [ with_m32=yes ],[ with_m32=no ]) AS_IF( [test "x$with_m32" = xyes], [ AC_MSG_NOTICE([Compiling for 32-bit environment - needs gcc on x86_64]) LDTARGETFLAGS="-m elf_i386" CTARGETFLAGS="-m32" ], []) CFLAGS="$CTARGETFLAGS $CFLAGS" CXXFLAGS="$CTARGETFLAGS $CXXFLAGS -std=c++11" LDFLAGS="$CTARGETFLAGS $LDFLAGS" # Check that we are using either the GNU compilers or the Sun compilers # but not a mixture of the two (not currently supported). AC_CHECK_DECL(__SUNPRO_CC, using_sunpro_cc=1, using_sunpro_cc=0) if test ${using_sunpro_c} = 1 then if test ${using_sunpro_cc} = 0 then echo "*** Error: No support for mixing GNU and Sun compilers. ***" echo " Using Sun C compiler and GNU C++ compiler.." exit 1 fi else if test ${using_sunpro_cc} = 1 then echo "*** Error: No support for mixing GNU and Sun compilers. ***" echo " Using GNU C compiler and Sun C++ compiler.." exit 1 fi fi iverilog_temp_cxxflags="$CXXFLAGS" CXXFLAGS="-DHAVE_DECL_BASENAME $CXXFLAGS" AC_CHECK_HEADERS(getopt.h inttypes.h libiberty.h iosfwd sys/wait.h) CXXFLAGS="$iverilog_temp_cxxflags" AC_CHECK_SIZEOF(unsigned long long) AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned) AC_CHECK_SIZEOF(void *) # vvp uses these... AC_CHECK_LIB(termcap, tputs) AC_CHECK_LIB(readline, readline) AC_CHECK_LIB(readline, add_history, NEED_LIBHISTORY=no, NEED_LIBHISTORY=yes) if test "$NEED_LIBHISTORY" = "yes"; then AC_CHECK_LIB(history, add_history) else # libreadline includes libhistory functions AC_DEFINE(HAVE_LIBHISTORY, 1) fi AC_CHECK_HEADERS(readline/readline.h readline/history.h sys/resource.h) case "${host}" in *linux*) AC_DEFINE([LINUX], [1], [Host operating system is Linux.]) ;; esac # vpi uses these AC_CHECK_LIB(pthread, pthread_create) AC_CHECK_LIB(z, gzwrite) AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no) AC_SUBST(HAVE_LIBZ) if test "$WIN32" = "yes"; then AC_CHECK_LIB(bz2, main) AC_CHECK_LIB(bz2, main, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no) else AC_CHECK_LIB(bz2, BZ2_bzdopen) AC_CHECK_LIB(bz2, BZ2_bzdopen, HAVE_LIBBZ2=yes, HAVE_LIBBZ2=no) fi AC_SUBST(HAVE_LIBBZ2) # The lxt/lxt2 files from GTKWave use these... AC_FUNC_ALLOCA AC_FUNC_FSEEKO # valgrind checks AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])], [], [check_valgrind=yes]) AS_IF([test "x$check_valgrind" = xyes], [AC_MSG_NOTICE([Not using valgrind hooks])], [AC_CHECK_HEADER([valgrind/memcheck.h], [AC_DEFINE([CHECK_WITH_VALGRIND], [1], [Define to one to use the valgrind hooks])], [AC_MSG_ERROR([Could not find ])])]) AC_MSG_CHECKING(for sys/times) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[{clock_t a = times(0)/sysconf(_SC_CLK_TCK);}]])],[do_times=yes AC_DEFINE(HAVE_TIMES, 1, The times system call is available in the host operating system.)],[do_times=no ]) AC_MSG_RESULT($do_times) # -- # Look for a dl library to use. First look for the standard dlopen # functions, and failing that look for the HP specific shl_load function. AC_CHECK_HEADERS(dlfcn.h dl.h, break) DLLIB='' AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl]) if test -z "$DLLIB" ; then AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld]) fi AC_SUBST(DLLIB) AC_SUBST(LDRELOCFLAGS) AC_SUBST(CTARGETFLAGS) AC_SUBST(LDTARGETFLAGS) AC_PROG_INSTALL AC_LANG(C) AC_C_BIGENDIAN # $host AX_ENABLE_SUFFIX AX_LD_EXTRALIBS # Compiler option for position independent code, needed when making shared objects. # CFLAGS inherited by cadpli/Makefile? AX_C_PICFLAG # may modify LDFLAGS AX_C99_STRTOD # Processor specific compile flags case "${host}" in alpha*-*-linux*) CPPFLAGS="-mieee $CPPFLAGS" CFLAGS="-mieee $CFLAGS" ;; *-*-mingw*) CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS" CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS" ;; esac # Do some more operating system specific setup. We put the file64_support # define in a substitution instead of simply a define because there # are source files (namely lxt support files) that don't include any # config.h header file. file64_support='' case "${host}" in *-*-linux*) AC_DEFINE([_LARGEFILE_SOURCE], [1], [Indicates LFS (i.e. the ability to create files larger than 2 GiB on 32-bit operating systems).]) file64_support='-D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64' ;; esac AC_SUBST(file64_support) # fstapi.c (from GTKWave) needs this define. AC_CHECK_FUNCS(realpath) # Check that these functions exist. They are mostly C99 # functions that older compilers may not yet support. AC_CHECK_FUNCS(fopen64) # The following math functions may be defined in the math library so look # in the default libraries first and then look in -lm for them. On some # systems we may need to use the compiler in C99 mode to get a definition. # autoconf >= 2.70 will enable C99 if it is available. For older autoconf # versions, we requested C99 mode earlier with AC_PROG_CC_C99. AC_SEARCH_LIBS([lround], [m], [AC_DEFINE([HAVE_LROUND], [1])]) AC_SEARCH_LIBS([llround], [m], [AC_DEFINE([HAVE_LLROUND], [1])]) AC_SEARCH_LIBS([nan], [m], [AC_DEFINE([HAVE_NAN], [1])]) AC_SEARCH_LIBS([fmin], [m], [AC_DEFINE([HAVE_FMIN], [1])]) AC_SEARCH_LIBS([fmax], [m], [AC_DEFINE([HAVE_FMAX], [1])]) # Check to see if an unsigned long and uint64_t are the same from # a compiler perspective. We can not just check that they are the # same size since unsigned long and unsigned long long are not the # same from an overloading perspective even though they could be # the same size on some 64 bit machines. The result from this test # is only used if inttypes.h is available, so if the test fails for # that reason we don't care. AC_LANG(C++) AC_MSG_CHECKING(if uint64_t and unsigned long are identical) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "inttypes.h" static bool check(unsigned long val) { return val != 0; } static bool check(uint64_t val) { return val != 0; }]], [[unsigned long ulval = 1; bool result = check(ulval); uint64_t uival = 1; result &= check(uival); return !result;]])], [AC_MSG_RESULT(no)], [AC_DEFINE([UINT64_T_AND_ULONG_SAME], [1]) AC_MSG_RESULT(yes)]) # Linker option used when compiling the target AX_LD_RDYNAMIC # linker options when building a shared library AX_LD_SHAREDLIB_OPTS ####################### ## test for underscores. The vpi module loader needs to know this ## in order to know the name of the start symbol for the .vpi module. ####################### AX_C_UNDERSCORES_LEADING AX_C_UNDERSCORES_TRAILING ####################### ## end of test for underscores ####################### ####################### # Sanity check the configured results ####################### AC_MSG_CHECKING(for sanity of prefix) if test `echo "$prefix" | wc -w` != 1 then AC_MSG_ERROR(cannot configure white space in prefix: $prefix) fi AC_MSG_RESULT(ok) AC_MSG_CHECKING(for sanity of exec_prefix) if test `echo "$exec_prefix" | wc -w` != 1 then AC_MSG_ERROR(cannot configure white space in exec_prefix: $exec_prefix) fi AC_MSG_RESULT(ok) AC_MSG_CHECKING(for sanity of libdir) if test `echo "$libdir" | wc -w` != 1 then AC_MSG_ERROR(cannot configure white space in libdir: $libdir) fi AC_MSG_RESULT(ok) AC_CONFIG_FILES([Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile]) AC_OUTPUT iverilog-12_0/constants.vams000066400000000000000000000025411435245347300162550ustar00rootroot00000000000000// Mathematical and physical constants `ifdef CONSTANTS_VAMS `else `define CONSTANTS_VAMS 1 // M_ is a mathematical constant `define M_E 2.7182818284590452354 `define M_LOG2E 1.4426950408889634074 `define M_LOG10E 0.43429448190325182765 `define M_LN2 0.69314718055994530942 `define M_LN10 2.30258509299404568402 `define M_PI 3.14159265358979323846 `define M_TWO_PI 6.28318530717958647693 `define M_PI_2 1.57079632679489661923 `define M_PI_4 0.78539816339744830962 `define M_1_PI 0.31830988618379067154 `define M_2_PI 0.63661977236758134308 `define M_2_SQRTPI 1.12837916709551257390 `define M_SQRT2 1.41421356237309504880 `define M_SQRT1_2 0.70710678118654752440 /* * Do we need these? For now they are not available. * // The following constants have been taken from http://physics.nist.gov // P_ is a physical constant // charge of electron in coulombs `define P_Q 1.602176462e-19 // speed of light in vacuum in meters/sec `define P_C 2.99792458e8 // Boltzmann's constant in joules/kelvin `define P_K 1.3806503e-23 // Planck's constant in joules*sec `define P_H 6.62606876e-34 // permittivity of vacuum in farads/meter `define P_EPS0 8.854187817e-12 // permeability of vacuum in henrys/meter `define P_U0 (4.0e-7 * `M_PI) // zero celsius in kelvin `define P_CELSIUS0 273.15 */ `endif iverilog-12_0/cppcheck.sup000066400000000000000000000404551435245347300156700ustar00rootroot00000000000000// These are correct and are used to find the base (zero) pin. thisSubtraction:netlist.h:5213 thisSubtraction:netlist.h:5222 // This is used when running a debugger // debugger_release knownConditionTrueFalse:main.cc:919 // This are just stubs // vpi_control() unusedFunction:vpi_modules.cc:107 // vpi_mcd_printf() unusedFunction:vpi_modules.cc:84 // vpi_printf() unusedFunction:vpi_modules.cc:88 // vpi_sim_control() unusedFunction:vpi_modules.cc:108 // These are the functions that the compiler exports to the targets. //ivl_branch_island() unusedFunction:t-dll-api.cc:39 //ivl_branch_terminal() unusedFunction:t-dll-api.cc:45 //ivl_const_bits() unusedFunction:t-dll-api.cc:189 //ivl_const_delay() unusedFunction:t-dll-api.cc:207 //ivl_const_file() unusedFunction:t-dll-api.cc:214 //ivl_const_lineno() unusedFunction:t-dll-api.cc:220 //ivl_const_nex() unusedFunction:t-dll-api.cc:226 //ivl_const_real() unusedFunction:t-dll-api.cc:232 //ivl_const_scope() unusedFunction:t-dll-api.cc:239 //ivl_const_signed() unusedFunction:t-dll-api.cc:245 //ivl_const_type() unusedFunction:t-dll-api.cc:183 //ivl_const_width() unusedFunction:t-dll-api.cc:251 //ivl_design_const() unusedFunction:t-dll-api.cc:120 //ivl_design_consts() unusedFunction:t-dll-api.cc:114 //ivl_design_delay_sel() unusedFunction:t-dll-api.cc:52 //ivl_design_discipline() unusedFunction:t-dll-api.cc:133 //ivl_design_disciplines() unusedFunction:t-dll-api.cc:127 //ivl_design_flag() unusedFunction:t-dll-api.cc:59 //ivl_design_process() unusedFunction:t-dll-api.cc:66 //ivl_design_root() unusedFunction:t-dll-api.cc:80 //ivl_design_roots() unusedFunction:t-dll-api.cc:89 //ivl_design_time_precision() unusedFunction:t-dll-api.cc:108 //ivl_discipline_domain() unusedFunction:t-dll-api.cc:140 //ivl_discipline_flow() unusedFunction:t-dll-api.cc:146 //ivl_discipline_name() unusedFunction:t-dll-api.cc:152 //ivl_discipline_potential() unusedFunction:t-dll-api.cc:158 //ivl_enum_bits() unusedFunction:t-dll-api.cc:270 //ivl_enum_file() unusedFunction:t-dll-api.cc:295 //ivl_enum_lineno() unusedFunction:t-dll-api.cc:301 //ivl_enum_name() unusedFunction:t-dll-api.cc:263 //ivl_enum_names() unusedFunction:t-dll-api.cc:257 //ivl_enum_signed() unusedFunction:t-dll-api.cc:289 //ivl_enum_type() unusedFunction:t-dll-api.cc:277 //ivl_enum_width() unusedFunction:t-dll-api.cc:283 //ivl_event_any() unusedFunction:t-dll-api.cc:362 //ivl_event_file() unusedFunction:t-dll-api.cc:338 //ivl_event_lineno() unusedFunction:t-dll-api.cc:344 //ivl_event_name() unusedFunction:t-dll-api.cc:307 //ivl_event_nany() unusedFunction:t-dll-api.cc:356 //ivl_event_neg() unusedFunction:t-dll-api.cc:375 //ivl_event_nneg() unusedFunction:t-dll-api.cc:369 //ivl_event_npos() unusedFunction:t-dll-api.cc:382 //ivl_event_pos() unusedFunction:t-dll-api.cc:388 //ivl_event_scope() unusedFunction:t-dll-api.cc:350 //ivl_expr_bits() unusedFunction:t-dll-api.cc:395 //ivl_expr_branch() unusedFunction:t-dll-api.cc:402 //ivl_expr_def() unusedFunction:t-dll-api.cc:409 //ivl_expr_delay_val() unusedFunction:t-dll-api.cc:425 //ivl_expr_dvalue() unusedFunction:t-dll-api.cc:432 //ivl_expr_enumtype() unusedFunction:t-dll-api.cc:439 //ivl_expr_event() unusedFunction:t-dll-api.cc:649 //ivl_expr_file() unusedFunction:t-dll-api.cc:171 //ivl_expr_lineno() unusedFunction:t-dll-api.cc:177 //ivl_expr_name() unusedFunction:t-dll-api.cc:452 //ivl_expr_nature() unusedFunction:t-dll-api.cc:476 //ivl_expr_net_type() unusedFunction:t-dll-api.cc:446 //ivl_expr_opcode() unusedFunction:t-dll-api.cc:483 //ivl_expr_oper1() unusedFunction:t-dll-api.cc:499 //ivl_expr_oper2() unusedFunction:t-dll-api.cc:537 //ivl_expr_oper3() unusedFunction:t-dll-api.cc:563 //ivl_expr_parameter() unusedFunction:t-dll-api.cc:577 //ivl_expr_parm() unusedFunction:t-dll-api.cc:592 //ivl_expr_parms() unusedFunction:t-dll-api.cc:619 //ivl_expr_repeat() unusedFunction:t-dll-api.cc:642 //ivl_expr_scope() unusedFunction:t-dll-api.cc:663 //ivl_expr_sel_type() unusedFunction:t-dll-api.cc:670 //ivl_expr_signed() unusedFunction:t-dll-api.cc:795 //ivl_expr_sized() unusedFunction:t-dll-api.cc:701 //ivl_expr_string() unusedFunction:t-dll-api.cc:707 //ivl_expr_type() unusedFunction:t-dll-api.cc:164 //ivl_expr_uvalue() unusedFunction:t-dll-api.cc:714 //ivl_expr_value() unusedFunction:t-dll-api.cc:740 //ivl_expr_width() unusedFunction:t-dll-api.cc:746 //ivl_file_table_index() unusedFunction:t-dll-api.cc:788 //ivl_file_table_item() unusedFunction:t-dll-api.cc:778 //ivl_file_table_size() unusedFunction:t-dll-api.cc:806 //ivl_island_flag_set() unusedFunction:t-dll-api.cc:815 //ivl_island_flag_test() unusedFunction:t-dll-api.cc:830 //ivl_logic_attr() unusedFunction:t-dll-api.cc:857 //ivl_logic_attr_cnt() unusedFunction:t-dll-api.cc:873 //ivl_logic_attr_val() unusedFunction:t-dll-api.cc:879 //ivl_logic_basename() unusedFunction:t-dll-api.cc:928 //ivl_logic_delay() unusedFunction:t-dll-api.cc:967 //ivl_logic_drive0() unusedFunction:t-dll-api.cc:887 //ivl_logic_drive1() unusedFunction:t-dll-api.cc:904 //ivl_logic_file() unusedFunction:t-dll-api.cc:839 //ivl_logic_is_cassign() unusedFunction:t-dll-api.cc:851 //ivl_logic_lineno() unusedFunction:t-dll-api.cc:845 //ivl_logic_name() unusedFunction:t-dll-api.cc:921 //ivl_logic_pins() unusedFunction:t-dll-api.cc:946 //ivl_logic_scope() unusedFunction:t-dll-api.cc:934 //ivl_logic_type() unusedFunction:t-dll-api.cc:940 //ivl_logic_udp() unusedFunction:t-dll-api.cc:959 //ivl_logic_width() unusedFunction:t-dll-api.cc:974 //ivl_lpm_array() unusedFunction:t-dll-api.cc:1102 //ivl_lpm_aset_value() unusedFunction:t-dll-api.cc:1153 //ivl_lpm_async_clr() unusedFunction:t-dll-api.cc:1047 //ivl_lpm_async_set() unusedFunction:t-dll-api.cc:1078 //ivl_lpm_base() unusedFunction:t-dll-api.cc:1114 //ivl_lpm_basename() unusedFunction:t-dll-api.cc:1041 //ivl_lpm_clk() unusedFunction:t-dll-api.cc:1141 //ivl_lpm_data() unusedFunction:t-dll-api.cc:1214 //ivl_lpm_datab() unusedFunction:t-dll-api.cc:1316 //ivl_lpm_define() unusedFunction:t-dll-api.cc:1176 //ivl_lpm_delay() unusedFunction:t-dll-api.cc:1071 //ivl_lpm_drive0() unusedFunction:t-dll-api.cc:1450 //ivl_lpm_drive1() unusedFunction:t-dll-api.cc:1467 //ivl_lpm_enable() unusedFunction:t-dll-api.cc:1188 //ivl_lpm_file() unusedFunction:t-dll-api.cc:1202 //ivl_lpm_lineno() unusedFunction:t-dll-api.cc:1208 //ivl_lpm_name() unusedFunction:t-dll-api.cc:1350 //ivl_lpm_negedge() unusedFunction:t-dll-api.cc:1129 //ivl_lpm_select() unusedFunction:t-dll-api.cc:1490 //ivl_lpm_selects() unusedFunction:t-dll-api.cc:1507 //ivl_lpm_signed() unusedFunction:t-dll-api.cc:1526 //ivl_lpm_size() unusedFunction:t-dll-api.cc:1587 //ivl_lpm_sset_value() unusedFunction:t-dll-api.cc:1164 //ivl_lpm_string() unusedFunction:t-dll-api.cc:1640 //ivl_lpm_sync_clr() unusedFunction:t-dll-api.cc:1059 //ivl_lpm_sync_set() unusedFunction:t-dll-api.cc:1090 //ivl_lpm_trigger() unusedFunction:t-dll-api.cc:1659 //ivl_lpm_type() unusedFunction:t-dll-api.cc:1647 //ivl_lpm_width() unusedFunction:t-dll-api.cc:1653 //ivl_lval_idx() unusedFunction:t-dll-api.cc:1681 //ivl_lval_mux() unusedFunction:t-dll-api.cc:1676 //ivl_lval_nest() unusedFunction:t-dll-api.cc:1726 //ivl_lval_part_off() unusedFunction:t-dll-api.cc:1690 //ivl_lval_property_idx() unusedFunction:t-dll-api.cc:1708 //ivl_lval_sel_type() unusedFunction:t-dll-api.cc:1696 //ivl_lval_sig() unusedFunction:t-dll-api.cc:1714 //ivl_nature_name() unusedFunction:t-dll-api.cc:1735 //ivl_nexus_get_private() unusedFunction:t-dll-api.cc:1756 //ivl_nexus_name() unusedFunction:t-dll-api.cc:1745 //ivl_nexus_ptr_branch() unusedFunction:t-dll-api.cc:1799 //ivl_nexus_ptr_con() unusedFunction:t-dll-api.cc:1808 //ivl_nexus_ptr_sig() unusedFunction:t-dll-api.cc:1835 //ivl_nexus_ptr_switch() unusedFunction:t-dll-api.cc:1844 //ivl_nexus_set_private() unusedFunction:t-dll-api.cc:1762 //ivl_parameter_basename() unusedFunction:t-dll-api.cc:1853 //ivl_parameter_expr() unusedFunction:t-dll-api.cc:1896 //ivl_parameter_file() unusedFunction:t-dll-api.cc:1902 //ivl_parameter_lineno() unusedFunction:t-dll-api.cc:1908 //ivl_parameter_local() unusedFunction:t-dll-api.cc:1859 //ivl_parameter_lsb() unusedFunction:t-dll-api.cc:1877 //ivl_parameter_msb() unusedFunction:t-dll-api.cc:1871 //ivl_parameter_scope() unusedFunction:t-dll-api.cc:1914 //ivl_parameter_signed() unusedFunction:t-dll-api.cc:1865 //ivl_parameter_width() unusedFunction:t-dll-api.cc:1887 //ivl_path_condit() unusedFunction:t-dll-api.cc:1920 //ivl_path_delay() unusedFunction:t-dll-api.cc:1938 //ivl_path_is_condit() unusedFunction:t-dll-api.cc:1926 //ivl_path_is_parallel() unusedFunction:t-dll-api.cc:1932 //ivl_path_scope() unusedFunction:t-dll-api.cc:1944 //ivl_path_source() unusedFunction:t-dll-api.cc:1951 //ivl_path_source_negedge() unusedFunction:t-dll-api.cc:1963 //ivl_path_source_posedge() unusedFunction:t-dll-api.cc:1957 //ivl_process_analog() unusedFunction:t-dll-api.cc:1987 //ivl_process_attr_cnt() unusedFunction:t-dll-api.cc:2005 //ivl_process_attr_val() unusedFunction:t-dll-api.cc:2011 //ivl_process_file() unusedFunction:t-dll-api.cc:1969 //ivl_process_lineno() unusedFunction:t-dll-api.cc:1975 //ivl_process_scope() unusedFunction:t-dll-api.cc:1993 //ivl_process_stmt() unusedFunction:t-dll-api.cc:1999 //ivl_process_type() unusedFunction:t-dll-api.cc:1981 //ivl_scope_attr_cnt() unusedFunction:t-dll-api.cc:2019 //ivl_scope_attr_val() unusedFunction:t-dll-api.cc:2025 //ivl_scope_basename() unusedFunction:t-dll-api.cc:2033 //ivl_scope_child() unusedFunction:t-dll-api.cc:2060 //ivl_scope_children() unusedFunction:t-dll-api.cc:2039 //ivl_scope_childs() unusedFunction:t-dll-api.cc:2053 //ivl_scope_class() unusedFunction:t-dll-api.cc:2067 //ivl_scope_classes() unusedFunction:t-dll-api.cc:2074 //ivl_scope_def() unusedFunction:t-dll-api.cc:2081 //ivl_scope_def_file() unusedFunction:t-dll-api.cc:2087 //ivl_scope_def_lineno() unusedFunction:t-dll-api.cc:2093 //ivl_scope_enumerate() unusedFunction:t-dll-api.cc:2105 //ivl_scope_enumerates() unusedFunction:t-dll-api.cc:2099 //ivl_scope_event() unusedFunction:t-dll-api.cc:2118 //ivl_scope_events() unusedFunction:t-dll-api.cc:2112 //ivl_scope_file() unusedFunction:t-dll-api.cc:2125 //ivl_scope_func_signed unusedFunction:t-dll-api.cc:2138 //ivl_scope_func_type unusedFunction:t-dll-api.cc:2131 //ivl_scope_func_width unusedFunction:t-dll-api.cc:2146 //ivl_scope_is_auto() unusedFunction:t-dll-api.cc:2154 //ivl_scope_is_cell() unusedFunction:t-dll-api.cc:2160 //ivl_scope_lineno() unusedFunction:t-dll-api.cc:2166 //ivl_scope_log() unusedFunction:t-dll-api.cc:2178 //ivl_scope_logs() unusedFunction:t-dll-api.cc:2172 //ivl_scope_lpm() unusedFunction:t-dll-api.cc:2191 //ivl_scope_lpms() unusedFunction:t-dll-api.cc:2185 //ivl_scope_mod_module_port_name() unusedFunction:t-dll-api.cc:2270 //ivl_scope_mod_module_port_type() unusedFunction:t-dll-api.cc:2279 //ivl_scope_mod_module_port_width() unusedFunction:t-dll-api.cc:2291 //ivl_scope_mod_module_ports() unusedFunction:t-dll-api.cc:2263 //ivl_scope_mod_port() unusedFunction:t-dll-api.cc:2316 //ivl_scope_param() unusedFunction:t-dll-api.cc:2249 //ivl_scope_params() unusedFunction:t-dll-api.cc:2243 //ivl_scope_parent() unusedFunction:t-dll-api.cc:2256 //ivl_scope_port() unusedFunction:t-dll-api.cc:2307 //ivl_scope_ports() unusedFunction:t-dll-api.cc:2298 //ivl_scope_sig() unusedFunction:t-dll-api.cc:2330 //ivl_scope_sigs() unusedFunction:t-dll-api.cc:2324 //ivl_scope_switch() unusedFunction:t-dll-api.cc:2343 //ivl_scope_switches() unusedFunction:t-dll-api.cc:2337 //ivl_scope_time_precision() unusedFunction:t-dll-api.cc:2350 //ivl_scope_time_units() unusedFunction:t-dll-api.cc:2356 //ivl_scope_tname() unusedFunction:t-dll-api.cc:2368 //ivl_scope_type() unusedFunction:t-dll-api.cc:2362 //ivl_signal_array_addr_swapped() unusedFunction:t-dll-api.cc:2386 //ivl_signal_array_base() unusedFunction:t-dll-api.cc:2374 //ivl_signal_array_count() unusedFunction:t-dll-api.cc:2380 //ivl_signal_attr() unusedFunction:t-dll-api.cc:2404 //ivl_signal_attr_cnt() unusedFunction:t-dll-api.cc:2420 //ivl_signal_attr_val() unusedFunction:t-dll-api.cc:2426 //ivl_signal_basename() unusedFunction:t-dll-api.cc:2433 //ivl_signal_data_type() unusedFunction:t-dll-api.cc:2584 //ivl_signal_dimensions() unusedFunction:t-dll-api.cc:2392 //ivl_signal_discipline() unusedFunction:t-dll-api.cc:2398 //ivl_signal_file() unusedFunction:t-dll-api.cc:2561 //ivl_signal_forced_net() unusedFunction:t-dll-api.cc:2555 //ivl_signal_integer() unusedFunction:t-dll-api.cc:2573 //ivl_signal_lineno() unusedFunction:t-dll-api.cc:2567 //ivl_signal_local() unusedFunction:t-dll-api.cc:2542 //ivl_signal_lsb() unusedFunction:t-dll-api.cc:2507 //ivl_signal_module_port_index() unusedFunction:t-dll-api.cc:2536 //ivl_signal_msb() unusedFunction:t-dll-api.cc:2497 //ivl_signal_name() unusedFunction:t-dll-api.cc:2439 //ivl_signal_nex() unusedFunction:t-dll-api.cc:2460 //ivl_signal_npath() unusedFunction:t-dll-api.cc:2597 //ivl_signal_packed_dimensions() unusedFunction:t-dll-api.cc:2477 //ivl_signal_packed_lsb() unusedFunction:t-dll-api.cc:2490 //ivl_signal_packed_msb() unusedFunction:t-dll-api.cc:2483 //ivl_signal_path() unusedFunction:t-dll-api.cc:2603 //ivl_signal_port() unusedFunction:t-dll-api.cc:2530 //ivl_signal_scope() unusedFunction:t-dll-api.cc:2517 //ivl_signal_signed() unusedFunction:t-dll-api.cc:2548 //ivl_signal_width() unusedFunction:t-dll-api.cc:2523 //ivl_statement_type() unusedFunction:t-dll-api.cc:2616 //ivl_stmt_block_count() unusedFunction:t-dll-api.cc:2649 //ivl_stmt_block_scope() unusedFunction:t-dll-api.cc:2634 //ivl_stmt_block_stmt() unusedFunction:t-dll-api.cc:2664 //ivl_stmt_call() unusedFunction:t-dll-api.cc:2680 //ivl_stmt_case_count() unusedFunction:t-dll-api.cc:2701 //ivl_stmt_case_expr() unusedFunction:t-dll-api.cc:2716 //ivl_stmt_case_quality() unusedFunction:t-dll-api.cc:2733 //ivl_stmt_case_stmt() unusedFunction:t-dll-api.cc:2749 //ivl_stmt_cond_expr() unusedFunction:t-dll-api.cc:2766 //ivl_stmt_cond_false() unusedFunction:t-dll-api.cc:2793 //ivl_stmt_cond_true() unusedFunction:t-dll-api.cc:2803 //ivl_stmt_delay_expr() unusedFunction:t-dll-api.cc:2813 //ivl_stmt_delay_val() unusedFunction:t-dll-api.cc:2830 //ivl_stmt_events() unusedFunction:t-dll-api.cc:2866 //ivl_stmt_file() unusedFunction:t-dll-api.cc:2622 //ivl_stmt_lexp() unusedFunction:t-dll-api.cc:2894 //ivl_stmt_lineno() unusedFunction:t-dll-api.cc:2628 //ivl_stmt_lval() unusedFunction:t-dll-api.cc:2906 //ivl_stmt_lvals() unusedFunction:t-dll-api.cc:2925 //ivl_stmt_lwidth() unusedFunction:t-dll-api.cc:2943 //ivl_stmt_name() unusedFunction:t-dll-api.cc:2976 //ivl_stmt_needs_t0_trigger() unusedFunction:t-dll-api.cc:2837 //ivl_stmt_nevent() unusedFunction:t-dll-api.cc:2847 //ivl_stmt_opcode() unusedFunction:t-dll-api.cc:2989 //ivl_stmt_parm() unusedFunction:t-dll-api.cc:3001 //ivl_stmt_parm_count() unusedFunction:t-dll-api.cc:3015 //ivl_stmt_rval() unusedFunction:t-dll-api.cc:3027 //ivl_stmt_sfunc_as_task() unusedFunction:t-dll-api.cc:3045 //ivl_stmt_sub_stmt() unusedFunction:t-dll-api.cc:3058 //ivl_switch_a() unusedFunction:t-dll-api.cc:3099 //ivl_switch_b() unusedFunction:t-dll-api.cc:3105 //ivl_switch_basename() unusedFunction:t-dll-api.cc:3081 //ivl_switch_delay() unusedFunction:t-dll-api.cc:3135 //ivl_switch_enable() unusedFunction:t-dll-api.cc:3111 //ivl_switch_file() unusedFunction:t-dll-api.cc:3142 //ivl_switch_island() unusedFunction:t-dll-api.cc:3148 //ivl_switch_lineno() unusedFunction:t-dll-api.cc:3154 //ivl_switch_offset() unusedFunction:t-dll-api.cc:3129 //ivl_switch_part() unusedFunction:t-dll-api.cc:3123 //ivl_switch_scope() unusedFunction:t-dll-api.cc:3087 //ivl_switch_type() unusedFunction:t-dll-api.cc:3093 //ivl_switch_width() unusedFunction:t-dll-api.cc:3117 //ivl_type_base() //unusedFunction:t-dll-api.cc:3128 Used in netmisc.cc //ivl_type_element() unusedFunction:t-dll-api.cc:3166 //ivl_type_name() unusedFunction:t-dll-api.cc:3198 //ivl_type_packed_dimensions() unusedFunction:t-dll-api.cc:3175 //ivl_type_packed_lsb() unusedFunction:t-dll-api.cc:3182 //ivl_type_packed_msb() unusedFunction:t-dll-api.cc:3190 //ivl_type_prop_type() unusedFunction:t-dll-api.cc:3223 //ivl_type_properties() unusedFunction:t-dll-api.cc:3206 //ivl_type_signed() unusedFunction:t-dll-api.cc:3231 //ivl_udp_file() unusedFunction:t-dll-api.cc:1029 //ivl_udp_init() unusedFunction:t-dll-api.cc:992 //ivl_udp_lineno() unusedFunction:t-dll-api.cc:1035 //ivl_udp_name() unusedFunction:t-dll-api.cc:1022 //ivl_udp_nin() unusedFunction:t-dll-api.cc:986 //ivl_udp_port() unusedFunction:t-dll-api.cc:998 //ivl_udp_row() unusedFunction:t-dll-api.cc:1007 //ivl_udp_rows() unusedFunction:t-dll-api.cc:1016 // ivl_udp_sequ() unusedFunction:t-dll-api.cc:980 iverilog-12_0/cprop.cc000066400000000000000000000323611435245347300150060ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 # include # include # include "netlist.h" # include "netmisc.h" # include "functor.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; /* * The cprop function below invokes constant propagation where * possible. The elaboration generates NetConst objects. I can remove * these and replace the gates connected to it with simpler ones. I * may even be able to replace nets with a new constant. */ struct cprop_functor : public functor_t { unsigned count; virtual void signal(Design*des, NetNet*obj); virtual void lpm_add_sub(Design*des, NetAddSub*obj); virtual void lpm_compare(Design*des, const NetCompare*obj); virtual void lpm_concat(Design*des, NetConcat*obj); virtual void lpm_ff(Design*des, NetFF*obj); virtual void lpm_logic(Design*des, NetLogic*obj); virtual void lpm_mux(Design*des, NetMux*obj); virtual void lpm_part_select(Design*des, NetPartSelect*obj); void lpm_compare_eq_(Design*des, const NetCompare*obj); }; void cprop_functor::signal(Design*, NetNet*) { } void cprop_functor::lpm_add_sub(Design*, NetAddSub*) { } void cprop_functor::lpm_compare(Design*des, const NetCompare*obj) { if (obj->pin_AEB().is_linked()) { assert( ! obj->pin_AGB().is_linked() ); assert( ! obj->pin_AGEB().is_linked() ); assert( ! obj->pin_ALB().is_linked() ); assert( ! obj->pin_ALEB().is_linked() ); assert( ! obj->pin_AGB().is_linked() ); assert( ! obj->pin_ANEB().is_linked() ); lpm_compare_eq_(des, obj); return; } } void cprop_functor::lpm_compare_eq_(Design*, const NetCompare*) { } void cprop_functor::lpm_concat(Design*des, NetConcat*obj) { // Sorry, I don't know how to constant-propagate through // transparent concatenations. if (obj->transparent()) return; verinum result (verinum::Vz, obj->width()); unsigned off = 0; for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) { Nexus*nex = obj->pin(idx).nexus(); // If there are non-constant drivers, then give up. if (! nex->drivers_constant()) return; verinum tmp = nex->driven_vector(); result.set(off, tmp); off += tmp.len(); } if (debug_optimizer) cerr << obj->get_fileline() << ": cprop_functor::lpm_concat: " << "Replace NetConcat with " << result << "." << endl; NetScope*scope = obj->scope(); // Create a NetConst object to carry the result. Give it the // same name as the Concat object that we are replacing, and // link the NetConst to the NetConcat object. Then delete the // concat that is now replaced. NetConst*result_obj = new NetConst(scope, obj->name(), result); result_obj->set_line(*obj); des->add_node(result_obj); connect(obj->pin(0), result_obj->pin(0)); // Note that this will leave the const inputs to dangle. They // will be reaped by other passes of cprop_functor. delete obj; count += 1; } void cprop_functor::lpm_ff(Design*, NetFF*obj) { // Look for and count unlinked FF outputs. Note that if the // Data and Q pins are connected together, they can be removed // from the circuit, since it doesn't do anything. if (connected(obj->pin_Data(), obj->pin_Q()) && (! obj->pin_Sclr().is_linked()) && (! obj->pin_Sset().is_linked()) && (! obj->pin_Aclr().is_linked()) && (! obj->pin_Aset().is_linked())) { obj->pin_Data().unlink(); obj->pin_Q().unlink(); delete obj; } } void cprop_functor::lpm_logic(Design*, NetLogic*) { } /* * This detects the case where the mux selects between a value and * Vz. In this case, replace the device with a mos with the sel * input used to enable the output. */ void cprop_functor::lpm_mux(Design*des, NetMux*obj) { if (obj->size() != 2) return; if (obj->sel_width() != 1) return; Nexus*sel_nex = obj->pin_Sel().nexus(); /* If the select input is constant, then replace with a BUFZ */ // If the select is not constant, there is nothing we can do. if (! sel_nex->drivers_constant()) return; // If the constant select is 'bz or 'bx, then give up. verinum::V sel_val = sel_nex->driven_value(); if (sel_val == verinum::Vz || sel_val == verinum::Vx) return; // The Select input must be a defined constant value, so we // can replace the device with a BUFZ. NetBUFZ*tmp = new NetBUFZ(obj->scope(), obj->name(), obj->width(), true); tmp->set_line(*obj); if (debug_optimizer) cerr << obj->get_fileline() << ": debug: " << "Replace binary MUX with constant select=" << sel_val << " with a BUFZ to the selected input." << endl; tmp->rise_time(obj->rise_time()); tmp->fall_time(obj->fall_time()); tmp->decay_time(obj->decay_time()); connect(tmp->pin(0), obj->pin_Result()); if (sel_val == verinum::V1) connect(tmp->pin(1), obj->pin_Data(1)); else connect(tmp->pin(1), obj->pin_Data(0)); delete obj; des->add_node(tmp); count += 1; } static bool compare_base(NetPartSelect*a, NetPartSelect*b) { return a->base() < b->base(); } /* * This optimization searches for Nexa that are driven only by * NetPartSelect(PV) outputs. These might turn from Verilog input that * looks like this: * wire [7:0] foo * assign foo[7:4] = a; * assign foo[3:0] = b; * The idea is to convert the part selects of the above to a single * concatenation that looks like this: * assign foo = {a, b}; */ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj) { if (obj->dir() != NetPartSelect::PV) return; NetScope*scope = obj->scope(); Nexus*nex = obj->pin(1).nexus(); vector obj_set; for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { // If this is an input (or passive) then ignore it. if (cur->get_dir() != Link::OUTPUT) continue; // Check to see if this is the output of a // NetPartSelect::PV. If not, then give up on the blend. NetPins*tmp_obj = cur->get_obj(); unsigned tmp_pin = cur->get_pin(); NetPartSelect*cur_obj = dynamic_cast (tmp_obj); if (cur_obj == 0) return; if (cur_obj->dir() != NetPartSelect::PV) return; if (tmp_pin != 1) return; obj_set.push_back(cur_obj); } if (obj_set.size() < 2) return; if (debug_optimizer) cerr << obj->get_fileline() << ": cprop::lpm_part_select: " << "Found " << obj_set.size() << " NetPartSelect(PV) objects." << endl; // Sort by increasing base offset. sort(obj_set.begin(), obj_set.end(), compare_base); // Check and make sure there are no overlaps. If there are, // then give up on this optimization. for (size_t idx = 1 ; idx < obj_set.size() ; idx += 1) { unsigned top = obj_set[idx-1]->base() + obj_set[idx-1]->width(); if (top > obj_set[idx]->base()) { if (debug_optimizer) cerr << obj->get_fileline() << ": cprop::lpm_part_select: " << "Range [" << obj_set[idx-1]->base() << " " << top << ") overlaps PV starting at " << obj_set[idx]->base() << ". Give up." << endl; return; } } // Check if the tail runs off the end of the target. If so it // should be possible to replace it with a bit select to // shorten the object for the target, but for now just give up. unsigned sig_width = nex->vector_width(); if (obj_set.back()->base() + obj_set.back()->width() > sig_width) { if (debug_optimizer) cerr << obj->get_fileline() << ": cprop::lpm_part_select: " << "Range [" << obj_set.back()->base() << ":" << (obj_set.back()->base() + obj_set.back()->width() - 1) << "] runs off the end of target." << endl; return; } // Figure out how many components we are going to need. unsigned part_count = 0; unsigned off = 0; for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) { if (obj_set[idx]->base() > off) { off = obj_set[idx]->base(); part_count += 1; } off += obj_set[idx]->width(); part_count += 1; } if (off < sig_width) part_count += 1; NetConcat*cncat = new NetConcat(scope, scope->local_symbol(), sig_width, part_count); cncat->set_line(*obj); des->add_node(cncat); connect(cncat->pin(0), obj->pin(1)); off = 0; size_t concat_pin = 1; for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) { NetPartSelect*cobj = obj_set[idx]; if (cobj->base() > off) { NetNet*zzz = make_const_z(des, scope, cobj->base()-off); connect(cncat->pin(concat_pin), zzz->pin(0)); concat_pin += 1; off = cobj->base(); } connect(cncat->pin(concat_pin), cobj->pin(0)); concat_pin += 1; off += cobj->width(); } if (off < sig_width) { NetNet*zzz = make_const_z(des, scope, sig_width-off); connect(cncat->pin(concat_pin), zzz->pin(0)); concat_pin += 1; } ivl_assert(*obj, concat_pin == cncat->pin_count()); for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) { delete obj_set[idx]; } count += 1; } /* * This functor looks to see if the constant is connected to nothing * but signals. If that is the case, delete the dangling constant and * the now useless signals. This functor is applied after the regular * functor to clean up dangling constants that might be left behind. */ struct cprop_dc_functor : public functor_t { virtual void lpm_const(Design*des, NetConst*obj); }; struct nexus_info_s { Nexus*nex; unsigned inp; unsigned out; }; void cprop_dc_functor::lpm_const(Design*, NetConst*obj) { // 'bz constant values drive high impedance to whatever is // connected to it. In other words, it is a noop. But that is // only true if *all* the bits of the vectors. { unsigned tmp = 0; ivl_assert(*obj, obj->pin_count()==1); for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) { if (obj->value(idx) == verinum::Vz) { tmp += 1; } } if (tmp == obj->width()) { delete obj; return; } } std::vector nexus_info (obj->pin_count()); for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) { nexus_info[idx].nex = obj->pin(idx).nexus(); unsigned inputs = 0, outputs = 0; nexus_info[idx].nex -> count_io(inputs, outputs); nexus_info[idx].inp = inputs; nexus_info[idx].out = outputs; } // If there are any links that take input, the constant is // used structurally somewhere. for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) if (nexus_info[idx].inp > 0) return; // Look for signals that have NetESignal nodes attached to // them. If I find any, then this constant is used by a // behavioral expression somewhere. for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) { for (Link*clnk = nexus_info[idx].nex->first_nlink() ; clnk ; clnk = clnk->next_nlink()) { NetPins*cur; unsigned pin; clnk->cur_link(cur, pin); const NetNet*tmp = dynamic_cast(cur); if (tmp == 0) continue; assert(tmp->scope()); // If the net is a signal name from the source, // then users will probably want to see it in the // waveform dump, so unhooking the constant will // make it look wrong. if (! tmp->local_flag()) return; // If the net has an eref, then there is an // expression somewhere that reads this signal. So // the constant does get read. if (tmp->peek_eref() > 0) return; // If the net is a port of the root module, then // the constant may be driving something outside // the design, so do not eliminate it. if ((tmp->port_type() != NetNet::NOT_A_PORT) && (tmp->scope()->parent() == 0)) return; } } // Done. Found no reason to keep this object, so delete it. delete obj; } void cprop(Design*des) { // Continually propagate constants until a scan finds nothing // to do. cprop_functor prop; do { prop.count = 0; des->functor(&prop); if (verbose_flag) { cout << " ... Iteration detected " << prop.count << " optimizations." << endl << flush; } } while (prop.count > 0); if (verbose_flag) { cout << " ... Look for dangling constants" << endl << flush; } cprop_dc_functor dc; des->functor(&dc); if (verbose_flag) { cout << " ... done" << endl << flush; } } iverilog-12_0/cygwin.txt000066400000000000000000000015441435245347300154140ustar00rootroot00000000000000 This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K) ---------------------------------------------------------------------------- Note: Icarus Verilog also compiles to native Windows binaries if you use the instructions in the mingw.txt file. Some people prefer cygwin binaries, and these instructions apply. To build using cygwin: Prerequisites: o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin) Procedure: o Get the source code - see the main Icarus Verilog page for how to do this o cd to the verilog directory o autoconf.sh o ./configure o make o make install That's all that's needed. To build your own extensions - just include vpi_user.h and link with a command like this: $(CC) -shared -o -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip - Venkat Iyer iverilog-12_0/design_dump.cc000066400000000000000000001331511435245347300161600ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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" /* * This file contains all the dump methods of the netlist classes. */ # include # include # include # include "netlist.h" # include "compiler.h" # include "discipline.h" # include "netclass.h" # include "netdarray.h" # include "netqueue.h" # include "netscalar.h" # include "netvector.h" # include "ivl_assert.h" # include "PExpr.h" using namespace std; static ostream& operator<< (ostream&o, NetBlock::Type t) { switch (t) { case NetBlock::SEQU: o << "begin"; break; case NetBlock::PARA: o << "fork"; break; case NetBlock::PARA_JOIN_NONE: o << "fork-join_none"; break; case NetBlock::PARA_JOIN_ANY: o << "fork-join_any"; break; } return o; } ostream& operator << (ostream&o, ivl_drive_t str) { switch (str) { case IVL_DR_HiZ: o << "highz"; break; case IVL_DR_SMALL: o << "small"; break; case IVL_DR_MEDIUM: o << "medium"; break; case IVL_DR_WEAK: o << "weak"; break; case IVL_DR_LARGE: o << "large"; break; case IVL_DR_PULL: o << "pull"; break; case IVL_DR_STRONG: o << "strong"; break; case IVL_DR_SUPPLY: o << "supply"; break; default: assert(0); } return o; } ostream& operator << (ostream&o, ivl_variable_type_t val) { switch (val) { case IVL_VT_VOID: o << "void"; break; case IVL_VT_NO_TYPE: o << ""; break; case IVL_VT_REAL: o << "real"; break; case IVL_VT_BOOL: o << "bool"; break; case IVL_VT_LOGIC: o << "logic"; break; case IVL_VT_STRING: o << "string"; break; case IVL_VT_DARRAY: o << "darray"; break; case IVL_VT_CLASS: o << "class"; break; case IVL_VT_QUEUE: o << "queue"; break; } return o; } ostream& operator << (ostream&o, ivl_switch_type_t val) { switch (val) { case IVL_SW_TRAN: o << "tran"; break; case IVL_SW_TRANIF0: o << "tranif0"; break; case IVL_SW_TRANIF1: o << "tranif1"; break; case IVL_SW_RTRAN: o << "rtran"; break; case IVL_SW_RTRANIF0: o << "rtranif0"; break; case IVL_SW_RTRANIF1: o << "rtranif1"; break; case IVL_SW_TRAN_VP: o << "tran(VP)"; break; } return o; } ostream& operator << (ostream&fd, PortType::Enum val) { switch (val) { case PortType::NOT_A_PORT: fd << "NOT_A_PORT"; break; case PortType::PIMPLICIT: fd << "PIMPLICIT"; break; case PortType::PINPUT: fd << "PINPUT"; break; case PortType::POUTPUT: fd << "POUTPUT"; break; case PortType::PINOUT: fd << "PINOUT"; break; case PortType::PREF: fd << "PREF"; break; default: fd << "PortType::Enum::?"; break; } return fd; } ostream& operator << (ostream&fd, NetCaseCmp::kind_t that) { switch (that) { case NetCaseCmp::EEQ: fd << "==="; break; case NetCaseCmp::NEQ: fd << "!=="; break; case NetCaseCmp::WEQ: fd << "==?"; break; case NetCaseCmp::WNE: fd << "!=?"; break; case NetCaseCmp::XEQ: fd << "==x?"; break; case NetCaseCmp::ZEQ: fd << "==z?"; break; } return fd; } ostream& ivl_type_s::debug_dump(ostream&o) const { o << typeid(*this).name(); return o; } ostream& netclass_t::debug_dump(ostream&fd) const { fd << "class " << name_ << "{"; for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) { if (idx != 0) fd << "; "; if (property_table_[idx].type) property_table_[idx].type->debug_dump(fd); else fd << "NO_TYPE"; fd << " " << property_table_[idx].name; } fd << "}"; return fd; } ostream& netdarray_t::debug_dump(ostream&o) const { o << "dynamic array of " << *element_type(); return o; } ostream& netqueue_t::debug_dump(ostream&fd) const { fd << "queue of "; if (max_idx_ >= 0) fd << "(maximum of " << max_idx_+1 << " elements) "; fd << *element_type(); return fd; } ostream& netreal_t::debug_dump(ostream&fd) const { fd << "real"; return fd; } ostream& netstring_t::debug_dump(ostream&fd) const { fd << "string"; return fd; } ostream& netvector_t::debug_dump(ostream&o) const { o << "netvector_t:" << type_ << (signed_? " signed" : " unsigned") << packed_dims_; return o; } static inline void dump_scope_path(ostream&o, const NetScope*scope) { const NetScope*parent = scope->parent(); if (parent) { dump_scope_path(o, parent); o << "."; } o << scope->fullname(); } ostream& operator <<(ostream&o, struct __ScopePathManip marg) { if (marg.scope != 0) dump_scope_path(o, marg.scope); return o; } ostream& operator <<(ostream&o, struct __ObjectPathManip marg) { if (marg.obj != 0) { dump_scope_path(o, marg.obj->scope()); o << "." << marg.obj->name(); } return o; } ostream& operator <<(ostream&fd, Link::DIR dir) { switch (dir) { case Link::PASSIVE: fd << "PASSIVE"; break; case Link::INPUT: fd << "INPUT"; break; case Link::OUTPUT: fd << "OUTPUT"; break; default: fd << "<" << (int)dir << ">"; break; } return fd; } void NetPins::show_type(ostream&fd) const { fd << typeid(*this).name(); } void NetObj::show_type(ostream&fd) const { fd << typeid(*this).name() << "[" << scope_path(scope_) << "." << name_ << "]"; } struct __ShowTypeManip { const NetPins*pins; }; inline __ShowTypeManip show_type(const NetPins*pins) { __ShowTypeManip tmp; tmp.pins = pins; return tmp; } inline ostream& operator << (ostream&fd, __ShowTypeManip man) { if (man.pins == 0) fd << "NexusSet"; else man.pins->show_type(fd); return fd; } void Link::dump_link(ostream&fd, unsigned ind) const { const Link*cur; const Nexus*nex = nexus(); if (nex == 0) { fd << setw(ind) << "" << "" << endl; return; } for (cur = nex->first_nlink() ; cur; cur = cur->next_nlink()) { const NetPins*obj = cur->get_obj(); unsigned pin = cur->get_pin(); fd << setw(ind) << "" << "Pin " << pin << " of " << show_type(obj) << ", dir=" << cur->dir_ << endl; } } void NetBranch::dump(ostream&o, unsigned ind) const { static const char*pin_names[2] = { "terminal0", "terminal1" }; o << setw(ind) << "" << "branch island=" << get_island(); o << " // " << get_fileline() << endl; dump_node_pins(o, ind+4, pin_names); } void NetDelaySrc::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "specify delay"; if (posedge_) o << " posedge"; if (negedge_) o << " negedge"; if (is_condit()) { if (has_condit()) o << " if"; else o << " ifnone"; } if (parallel_) o << " parallel"; else o << " full"; o << " src " << "(" << transition_delays_[IVL_PE_01] << "," << transition_delays_[IVL_PE_10] << "," << transition_delays_[IVL_PE_0z] << "/" << transition_delays_[IVL_PE_z1] << "," << transition_delays_[IVL_PE_1z] << "," << transition_delays_[IVL_PE_z0] << "/" << transition_delays_[IVL_PE_0x] << "," << transition_delays_[IVL_PE_x1] << "," << transition_delays_[IVL_PE_1x] << "/" << transition_delays_[IVL_PE_x0] << "," << transition_delays_[IVL_PE_xz] << "," << transition_delays_[IVL_PE_zx] << ") scope=" << scope_path(scope()) << endl; dump_node_pins(o, ind+4); } static inline ostream&operator<<(ostream&out, const netrange_t&that) { if (that.defined()) out << "[" << that.get_msb() << ":" << that.get_lsb() << "]"; else out << "[]"; return out; } ostream&operator<<(ostream&out, const list&rlist) { for (list::const_iterator cur = rlist.begin() ; cur != rlist.end() ; ++cur) { out << *cur; } return out; } ostream&operator<<(ostream&out, const vector&rlist) { for (vector::const_iterator cur = rlist.begin() ; cur != rlist.end() ; ++cur) { out << *cur; } return out; } /* Dump a net. This can be a wire or register. */ void NetNet::dump_net(ostream&o, unsigned ind) const { o << setw(ind) << "" << type() << ": " << name() << unpacked_dims_ << " unpacked dims=" << unpacked_dimensions(); o << " pin_count=" << pin_count(); if (local_flag_) o << " (local)"; switch (port_type_) { case NetNet::NOT_A_PORT: break; case NetNet::PIMPLICIT: o << " implicit-port?"; break; case NetNet::PINPUT: o << " input"; break; case NetNet::POUTPUT: o << " output"; break; case NetNet::PINOUT: o << " inout"; break; case NetNet::PREF: o <<" ref"; break; } if (ivl_discipline_t dis = get_discipline()) o << " discipline=" << dis->name(); if (net_type_) o << " " << *net_type_; o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")"; if (scope()) o << " scope=" << scope_path(scope()); o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() << ") vector_width=" << vector_width() << " pin_count=" << pin_count(); if (pins_are_virtual()) { o << " pins_are_virtual" << endl; return; } o << endl; for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { if (! pin(idx).is_linked()) continue; const Nexus*nex = pin(idx).nexus(); o << setw(ind+4) << "" << "[" << idx << "]: " << nex << " " << nex->name() << endl; } for (unsigned idx = 0 ; idx < delay_paths_.size() ; idx += 1) { const NetDelaySrc*cur = delay_paths_[idx]; cur->dump(o, ind+4); } dump_obj_attr(o, ind+4); } /* Dump a NetNode and its pins. Dump what I know about the netnode on the first line, then list all the pins, with the name of the connected signal. */ void NetNode::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "node: "; o << typeid(*this).name() << " #(" << rise_time() << "," << fall_time() << "," << decay_time() << ") " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } /* This is the generic dumping of all the signals connected to each pin of the object. The "this" object is not printed, only the signals connected to this. */ void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) const { for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { o << setw(ind) << "" << idx; if (pin_names && pin_names[idx]) o << " " << pin_names[idx]; else o << " pin" << idx; switch (pin(idx).get_dir()) { case Link::PASSIVE: o << " p"; break; case Link::INPUT: o << " I"; break; case Link::OUTPUT: o << " O"; break; } o << " (" << pin(idx).drive0() << "0 " << pin(idx).drive1() << "1): "; if (pin(idx).is_linked()) { const Nexus*nex = pin(idx).nexus(); o << nex << " " << nex->name(); } o << endl; } } void NetObj::dump_obj_attr(ostream&o, unsigned ind) const { unsigned idx; for (idx = 0 ; idx < attr_cnt() ; idx += 1) { o << setw(ind) << "" << attr_key(idx) << " = \"" << attr_value(idx) << "\"" << endl; } } void NetAbs::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Absolute value (NetAbs): " << name() << " width=" << width() << " pin_count=" << pin_count() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetAddSub::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Adder (NetAddSub): " << name() << " width=" << width() << " pin_count=" << pin_count() << endl; static const char* pin_names[] = { "Cout ", "DataA ", "DataB ", "Result" }; dump_node_pins(o, ind+4, pin_names); dump_obj_attr(o, ind+4); } void NetArrayDq::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "NetArrayDq: " << name() << " array=" << mem_->name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetCastInt2::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Cast to int2. (NetCastInt2): " << name() << " width=" << width() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetCastInt4::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Cast to int4. (NetCastInt4): " << name() << " width=" << width() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetCastReal::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Cast to real (NetCastReal): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetCLShift::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Combinatorial shift (NetCLShift): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetCompare::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_COMPARE (NetCompare " << (get_signed()? "signed" : "unsigned") << "): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetConcat::dump_node(ostream&o, unsigned ind) const { if (transparent_) o << setw(ind) << "" << "NetConcat8: "; else o << setw(ind) << "" << "NetConcat: "; o << name(); if (rise_time()) o << " #(" << *rise_time() << "," << *fall_time() << "," << *decay_time() << ")"; else o << " #(0,0,0)"; o << " scope=" << scope_path(scope()) << " width=" << width_ << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetDivide::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetMult::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetPow::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_POW (NetPow): " << name() << " scope=" << scope_path(scope()) << " delay=("; if (rise_time()) o << *rise_time() << "," << *fall_time() << "," << *decay_time(); else o << "0,0,0"; o << ")" << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetMux::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "Multiplexer (NetMux): " << name() << " width=" << width_ << " swidth=" << swidth_ << " size=" << size_ << " scope=" << scope_path(scope()) << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetBUFZ::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "NetBUFZ: " << name() << " scope=" << scope_path(scope()) << " delay=(" << rise_time() << "," << fall_time() << "," << decay_time() << ") width=" << width() << (transparent()? " " : " non-") << "transparent" << endl; dump_node_pins(o, ind+4); } void NetCaseCmp::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "case compare " << kind_ << ": " << name() << endl; dump_node_pins(o, ind+4); } void NetConst::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "constant " << value_; o << ": " << name(); if (rise_time()) o << " #(" << *rise_time() << "," << *fall_time() << "," << *decay_time() << ")"; else o << " #(.,.,.)"; o << endl; dump_node_pins(o, ind+4); } void NetFF::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_FF: " << name() << " scope=" << scope_path(scope()); if (negedge_) o << " negedge"; else o << " posedge"; o << " aset_value=" << aset_value_ << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetLatch::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "LPM_LATCH: " << name() << " scope=" << scope_path(scope()) << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetLiteral::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "constant real " << real_ << ": " << name(); if (rise_time()) o << " #(" << *rise_time() << "," << *fall_time() << "," << *decay_time() << ")"; else o << " #(.,.,.)"; o << endl; dump_node_pins(o, ind+4); } void NetLogic::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "logic: "; switch (type_) { case AND: o << "and"; break; case BUF: o << "buf"; break; case BUFIF0: o << "bufif0"; break; case BUFIF1: o << "bufif1"; break; case CMOS: o << "cmos"; break; case EQUIV: o << "<->"; break; case IMPL: o << "->"; break; case NAND: o << "nand"; break; case NMOS: o << "nmos"; break; case NOR: o << "nor"; break; case NOT: o << "not"; break; case NOTIF0: o << "notif0"; break; case NOTIF1: o << "notif1"; break; case OR: o << "or"; break; case PULLDOWN: o << "pulldown"; break; case PULLUP: o << "pullup"; break; case RCMOS: o << "rcmos"; break; case RNMOS: o << "rnmos"; break; case RPMOS: o << "rpmos"; break; case PMOS: o << "pmos"; break; case XNOR: o << "xnor"; break; case XOR: o << "xor"; break; } o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() << ") " << name() << " scope=" << scope_path(scope()) << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetModulo::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "NET_MODULO (NetModulo): " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetPartSelect::dump_node(ostream&o, unsigned ind) const { const char*pt = ""; switch (dir_) { case VP: pt = "VP"; break; case PV: pt = "PV"; break; } o << setw(ind) << "" << "NetPartSelect(" << pt << "): " << name(); if (rise_time()) o << " #(" << *rise_time() << "," << *fall_time() << "," << *decay_time() << ")"; else o << " #(.,.,.)"; o << " off=" << off_ << " wid=" << wid_ <name << "(...) -->" << data_type() << " width=" << vector_width() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetUserFunc::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "USER FUNC: " << scope_path(def_); if (rise_time()) o << " #(" <<*rise_time() <<","<<*fall_time() << "," <<*decay_time() << ")"; o << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetTaskDef::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "task " << scope_path(scope()) << ";" << endl; for (unsigned idx = 0 ; idx < port_count() ; idx += 1) { const NetNet*pnet = port(idx); o << setw(ind+4) << ""; assert(pnet); switch (pnet->port_type()) { case NetNet::PINPUT: o << "input "; break; case NetNet::POUTPUT: o << "output "; break; case NetNet::PINOUT: o << "input "; break; default: o << "NOT_A_PORT "; break; } o << pnet->name() << ";" << endl; } if (proc_) proc_->dump(o, ind+4); else o << setw(ind+4) << "" << "MISSING PROCEDURAL CODE" << endl; o << setw(ind) << "" << "endtask" << endl; } void NetTran::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << type_ << " " << name() << " island " << get_island(); if (type_ == IVL_SW_TRAN_VP) { o << " width=" << vector_width() << " part=" << part_width() << " offset=" << part_offset(); } o << " delay=("; if (rise_time()) o << *rise_time() << "," << *fall_time() << "," << *decay_time(); else o << "0,0,0"; o << ")" << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetUDP::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << "" << "UDP (" << udp_name() << "): "; o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() << ") " << name() << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetProcTop::dump(ostream&o, unsigned ind) const { switch (type_) { case IVL_PR_INITIAL: o << "initial /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_ALWAYS: o << "always /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_ALWAYS_COMB: o << "always_comb /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_ALWAYS_FF: o << "always_ff /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_ALWAYS_LATCH: o << "always_latch /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_FINAL: o << "final /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; } for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) { o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = " << attr_value(idx) << " *)" << endl; } statement_->dump(o, ind+2); } void NetAnalogTop::dump(ostream&o, unsigned ind) const { switch (type_) { case IVL_PR_INITIAL: o << "analog initial /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; case IVL_PR_ALWAYS: o << "analog /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; // These are not used in an analog context. case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: assert(0); break; case IVL_PR_FINAL: o << "analog final /* " << get_fileline() << " in " << scope_path(scope_) << " */" << endl; break; } statement_->dump(o, ind+2); } void NetAlloc::dump(ostream&o, unsigned ind) const { o << setw(ind) << "// allocate storage : " << scope_path(scope_) << endl; } void NetAssign_::dump_lval(ostream&o) const { if (sig_) o << sig_->name(); else if (nest_) { o << "("; nest_->dump_lval(o); o << ")"; } else o << ""; if (! member_.nil()) { o << "." << member_; } if (word_) { o << "[word=" << *word_ << "]"; } if (base_) { o << "[" << *base_ << " +: " << lwid_ << "]"; } } void NetAssignBase::dump_lval(ostream&o) const { o << "{"; lval_->dump_lval(o); for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) { o << ", "; cur->dump_lval(o); } o << "}"; } /* Dump an assignment statement */ void NetAssign::dump(ostream&o, unsigned ind) const { o << setw(ind) << ""; dump_lval(o); if (op_) o << " " << op_ << "= "; else o << " = "; if (const NetExpr*de = get_delay()) o << "#(" << *de << ") "; if (rval()) o << *rval() << ";" << endl; else o << ";" << endl; } void NetAssignNB::dump(ostream&o, unsigned ind) const { o << setw(ind) << ""; dump_lval(o); o << " <= "; if (const NetExpr*de = get_delay()) o << "#(" << *de << ") "; if (count_) o << "repeat(" << *count_ << ") "; if (event_) { o << *event_; } if (rval()) o << *rval() << ";" << endl; else o << "rval elaboration error>;" << endl; } void NetAssignBase::dump(ostream&o, unsigned ind) const { if (const NetAssignNB *n1 = dynamic_cast(this)) { n1->dump(o,ind); } else if (const NetAssign *n2 = dynamic_cast(this)) { n2->dump(o,ind); } } /* Dump a block statement */ void NetBlock::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << type_; if (subscope_) o << " : " << scope_path(subscope_); o << endl; if (last_) { const NetProc*cur = last_; do { cur = cur->next_; cur->dump(o, ind+4); } while (cur != last_); } o << setw(ind) << "" << "end" << endl; } void NetCase::dump(ostream&o, unsigned ind) const { o << setw(ind) << ""; switch (quality_) { case IVL_CASE_QUALITY_BASIC: break; case IVL_CASE_QUALITY_UNIQUE: o << "unique "; break; case IVL_CASE_QUALITY_UNIQUE0: o << "unique0 "; break; case IVL_CASE_QUALITY_PRIORITY: o << "priority "; break; } switch (type_) { case EQ: o << "case (" << *expr_ << ")" << endl; break; case EQX: o << "casex (" << *expr_ << ")" << endl; break; case EQZ: o << "casez (" << *expr_ << ")" << endl; break; } for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) { o << setw(ind+2) << ""; if (items_[idx].guard) o << *items_[idx].guard << ":"; else o << "default:"; if (items_[idx].statement) { o << endl; items_[idx].statement->dump(o, ind+6); } else { o << " ;" << endl; } } o << setw(ind) << "" << "endcase" << endl; } void NetCAssign::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "cassign "; dump_lval(o); o << " = " << *rval() << "; /* " << get_fileline() << " */" << endl; } void NetCondit::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "if ("; expr_->dump(o); o << ")" << endl; if (if_) if_->dump(o, ind+4); else o << setw(ind+4) << "" << "/* empty */ ;" << endl; if (else_) { o << setw(ind) << "" << "else" << endl; else_->dump(o, ind+4); } } void NetContribution::dump(ostream&o, unsigned ind) const { o << setw(ind) << ""; lval_->dump(o); o << " <+ "; rval_->dump(o); o << ";" << endl; } void NetDeassign::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "deassign "; dump_lval(o); o << "; /* " << get_fileline() << " */" << endl; } void NetDisable::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "disable "; if (target_) o << scope_path(target_); else o << "fork"; o << "; " << "/* " << get_fileline() << " */" << endl; } void NetDoWhile::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "do" << endl; proc_->dump(o, ind+3); o << setw(ind) << "" << "while (" << *cond_ << ");" << endl; } void NetEvProbe::dump_node(ostream&o, unsigned ind) const { o << setw(ind) << ""; switch (edge_) { case ANYEDGE: o << "anyedge "; break; case POSEDGE: o << "posedge "; break; case NEGEDGE: o << "negedge "; break; case EDGE: o << "edge "; break; } o << setw(ind) << "" << "-> " << event_->name() << "; " << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } void NetEvTrig::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "-> " << event_->name() << "; " << "// " << get_fileline() << endl; } void NetEvNBTrig::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "->> " ; if (dly_) o << "#" << *dly_ << " "; o << event_->name() << "; " << "// " << get_fileline() << endl; } void NetEvWait::dump(ostream&o, unsigned ind) const { o << setw(ind) << ""; /* Check for a wait fork. */ if ((nevents() == 1) && (event(0) == 0)) { o << "wait fork;"; return; } o << "@("; if (nevents() > 0) o << event(0)->name(); for (unsigned idx = 1 ; idx < nevents() ; idx += 1) o << " or " << event(idx)->name(); o << ") // " << get_fileline() << endl; if (statement_) statement_->dump(o, ind+2); else o << setw(ind+2) << "" << "/* noop */ ;" << endl; } ostream& operator << (ostream&out, const NetEvWait&obj) { obj.dump_inline(out); return out; } void NetEvWait::dump_inline(ostream&o) const { /* Check for a wait fork. */ if ((nevents() == 1) && (event(0) == 0)) { o << "wait fork;"; return; } o << "@("; if (nevents() > 0) o << event(0)->name(); for (unsigned idx = 1 ; idx < nevents() ; idx += 1) o << " or " << event(idx)->name(); o << ") "; } void NetForce::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "force "; dump_lval(o); o << " = " << *rval() << "; /* " << get_fileline() << " */" << endl; } void NetForever::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "forever" << endl; statement_->dump(o, ind+2); } void NetForLoop::dump(ostream&fd, unsigned ind) const { fd << setw(ind) << "" << "FOR LOOP index="; if (index_) fd << index_->name(); else fd << ""; fd << endl; statement_->dump(fd, ind+4); if (step_statement_) step_statement_->dump(fd, ind+4); } void NetFree::dump(ostream&o, unsigned ind) const { o << setw(ind) << "// free storage : " << scope_path(scope_) << endl; } void NetFuncDef::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "function definition for " << scope_path(scope()) << endl; if (result_sig_) { o << setw(ind+2) << "" << "Return signal: "; if (result_sig_->get_signed()) o << "+"; o << result_sig_->name() << endl; } o << setw(ind+2) << "" << "Arguments: "; if (port_count() == 0) o << ""; o << endl; for (unsigned idx = 0; idx < port_count(); idx += 1) { o << setw(ind+4) << "" << "Arg[" << idx+1 << "] = "; switch (port(idx)->port_type()) { default: o << "implicit-port? "; break; case NetNet::PINPUT: o << "input "; break; case NetNet::POUTPUT: o << "output "; break; case NetNet::PINOUT: o << "inout "; break; } if (port(idx)->get_signed()) o << "+"; o << port(idx)->name() << endl; } if (proc_) proc_->dump(o, ind+2); else o << setw(ind+2) << "" << "MISSING PROCEDURAL CODE" << endl; } void NetPDelay::dump(ostream&o, unsigned ind) const { if (expr_) { o << setw(ind) << "" << "#" << *expr_; } else { o << setw(ind) << "" << "#" << delay_; } if (statement_) { o << endl; statement_->dump(o, ind+2); } else { o << " /* noop */;" << endl; } } void NetRelease::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "release "; dump_lval(o); o << "; /* " << get_fileline() << " */" << endl; } void NetRepeat::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl; statement_->dump(o, ind+2); } void netclass_t::dump_scope(ostream&fd) const { class_scope_->dump(fd); } void NetScope::dump(ostream&o) const { /* This is a constructed hierarchical name. */ o << scope_path(this) << " "; print_type(o); if (is_auto()) o << " (automatic)"; if (is_cell()) o << " (cell)"; if (nested_module()) o << " (nested)"; if (program_block()) o << " (program)"; if (is_interface()) o << " (interface)"; o << " " << children_.size() << " children, " << classes_.size() << " classes" << endl; if (unit() && !is_unit()) o << " in compilation unit " << unit()->basename() << endl; for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) o << " (* " << attr_key(idx) << " = " << attr_value(idx) << " *)" << endl; o << " timescale = 10e" << time_unit() << " / 10e" << time_precision() << endl; /* Dump the parameters for this scope. */ { map::const_iterator pp; for (pp = parameters.begin() ; pp != parameters.end() ; ++ pp ) { if ((*pp).second.is_annotatable) o << " specparam "; else o << " parameter "; if (pp->second.ivl_type) pp->second.ivl_type->debug_dump(o); o << (*pp).first << " = "; if (pp->second.val) o << *(*pp).second.val; else o << ""; for (range_t*ran = (*pp).second.range ; ran ; ran = ran->next) { if (ran->exclude_flag) o << " exclude "; else o << " from "; if (ran->low_open_flag) o << "("; else o << "["; if (ran->low_expr) o << *ran->low_expr; else if (ran->low_open_flag==false) o << "-inf"; else o << ""; if (ran->high_expr) o << ":" << *ran->high_expr; else if (ran->high_open_flag==false) o << ":inf"; else o << ":"; if (ran->high_open_flag) o << ")"; else o << "]"; } o << ";" << endl; } } /* Dump the saved defparam assignments here. */ { list >::const_iterator pp; for (pp = defparams.begin() ; pp != defparams.end() ; ++ pp ) { o << " defparam " << (*pp).first << " = " << *(*pp).second << ";" << endl; } } { list,PExpr*> >::const_iterator pp; for (pp = defparams_later.begin() ; pp != defparams_later.end() ; ++ pp ) { o << " defparam(later) " << pp->first << " = " << *(pp->second) << ";" << endl; } } o << " enum sets {" << endl; /* Dump the enumerations and enum names in this scope. */ for (map::const_iterator cur = enum_sets_.begin() ; cur != enum_sets_.end() ; ++ cur) { o << " " << cur->second << endl; } o << " }" << endl; o << " enum names {" << endl; for (map::const_iterator cur = enum_names_.begin() ; cur != enum_names_.end() ; ++ cur) { o << " " << cur->first << " = " << cur->second->value() << " from " << cur->second->enumeration() << endl; } o << " }" << endl; /* Dump the events in this scope. */ for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) { o << " event " << cur->name() << "; nprobe=" << cur->nprobe() << " scope=" << scope_path(cur->scope()) << " // " << cur->get_fileline() << endl; } // Dump the signals, for (signals_map_iter_t cur = signals_map_.begin() ; cur != signals_map_.end() ; ++ cur) { cur->second->dump_net(o, 4); } switch (type_) { case FUNC: if (func_def()) func_def()->dump(o, 4); else o << " MISSING FUNCTION DEFINITION" << endl; break; case TASK: if (task_def()) task_def()->dump(o, 4); else o << " MISSING TASK DEFINITION" << endl; break; default: break; } /* Dump any sub-scopes. */ for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->dump(o); for (map::const_iterator cur = classes_.begin() ; cur != classes_.end() ; ++ cur ) { cur->second->dump_scope(o); } } void NetSTask::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << name_; if (! parms_.empty()) { o << "("; if (parms_[0]) parms_[0]->dump(o); for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { o << ", "; if (parms_[idx]) parms_[idx]->dump(o); } o << ")"; } o << ";" << endl; } void NetUTask::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << scope_path(task_) << ";" << endl; } void NetWhile::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "while (" << *cond_ << ")" << endl; proc_->dump(o, ind+3); } /* Dump a statement type that someone didn't write a dump for. */ void NetProc::dump(ostream&o, unsigned ind) const { o << setw(ind) << "" << "// " << typeid(*this).name() << endl; } /* Dump an expression that no one wrote a dump method for. */ void NetExpr::dump(ostream&o) const { o << "(?" << typeid(*this).name() << "?)"; } void NetEAccess::dump(ostream&o) const { o << nature_->name() << "." << nature_->access() << "("; assert(branch_); if (branch_->pin(0).is_linked()) o << branch_->pin(0).nexus()->name(); o << ", "; if (branch_->pin(1).is_linked()) o << branch_->pin(1).nexus()->name(); o << ")"; } void NetEArrayPattern::dump(ostream&fd) const { fd << "'{"; if (items_.size() >= 1) { if (items_[0]) fd << *items_[0]; } for (size_t idx = 1 ; idx < items_.size() ; idx += 1) { fd << ", "; if (items_[idx]) fd << *items_[idx]; } fd << "}"; } void NetEBinary::dump(ostream&o) const { if (op_ == 'm' || op_ == 'M') { if (op_ == 'm') o << "min"; else o << "max"; o << "("; left_->dump(o); o << ", "; right_->dump(o); o << ")"; return; } o << "("; left_->dump(o); o << ")"; switch (op_) { default: o << op_; break; case 'a': o << "&&"; break; case 'A': o << "~&"; break; case 'e': o << "=="; break; case 'E': o << "==="; break; case 'w': o << "==?"; break; case 'G': o << ">="; break; case 'l': o << "<<"; break; case 'L': o << "<="; break; case 'n': o << "!="; break; case 'N': o << "!=="; break; case 'W': o << "!=?"; break; case 'o': o << "||"; break; case 'O': o << "~|"; break; case 'p': o << "**"; break; case 'q': o << "->"; break; case 'Q': o << "<->"; break; case 'r': o << ">>"; break; case 'R': o << ">>>"; break; case 'X': o << "~^"; break; } o << "("; right_->dump(o); o << ")"; } void NetECast::dump(ostream&fd) const { if (op_=='2') fd << "bool<" << expr_width() << ">(" << *expr_ << ")"; else if (op_=='v') fd << "logic<" << expr_width() << ">(" << *expr_ << ")"; else NetEUnary::dump(fd); } void NetEConcat::dump(ostream&o) const { if (repeat_ != 1) o << repeat_; if (parms_[0]) o << "{" << *parms_[0]; else o << "{"; for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]) o << ", " << *parms_[idx]; else o << ", "; } o << "}"; } void NetEConst::dump(ostream&o) const { if (value_.is_string()) o << "\"" << value_.as_string() << "\""; else o << value_; } void NetEConstEnum::dump(ostream&o) const { o << "<" << name_ << "="; NetEConst::dump(o); o << ", wid=" << expr_width() << ">"; } void NetEConstParam::dump(ostream&o) const { o << "<" << name_ << "="; NetEConst::dump(o); o << ", wid=" << expr_width() << ">"; } void NetECReal::dump(ostream&o) const { o << value_; } void NetECRealParam::dump(ostream&o) const { o << "<" << name_ << "="; NetECReal::dump(o); o << ">"; } void NetEEvent::dump(ostream&o) const { o << "name() << ">"; } void NetELast::dump(ostream&fd) const { fd << "name() << ">"; } void NetENetenum::dump(ostream&o) const { o << ""; } void NetENew::dump(ostream&o) const { o << "new ["; if (size_) size_->dump(o); o << "]"; if (init_val_) { o << "("; init_val_->dump(o); o << ")"; } } void NetENull::dump(ostream&o) const { o << ""; } void NetEProperty::dump(ostream&o) const { o << net_->name() << ".<" << pidx_ << ">"; if (index_) o << "[" << *index_ << "]"; } void NetEScope::dump(ostream&o) const { o << ""; } void NetESelect::dump(ostream&o) const { o << "dump(o); o << "["; if (base_) base_->dump(o); else o << "(0)"; o << "+:" << expr_width() << "]"; if (ivl_type_t nt = net_type()) { o << " net_type=(" << *nt << ")"; } else { o << " expr_type=" << expr_type(); } o << ">"; } void NetESFunc::dump(ostream&o) const { o << name_ << "("; if (nparms() > 0) o << *parm(0); for (unsigned idx = 1 ; idx < nparms() ; idx += 1) o << ", " << *parm(idx); o << ")"; } void NetEShallowCopy::dump(ostream&o) const { o << ""; } void NetESignal::dump(ostream&o) const { if (has_sign()) o << "+"; o << name(); if (word_) o << "[word=" << *word_ << "]"; vectortmp = net_->net_type()->slice_dimensions(); o << tmp; } void NetETernary::dump(ostream&o) const { o << "(" << *cond_ << ") ? (" << *true_val_ << ") : (" << *false_val_ << ")"; } void NetEUFunc::dump(ostream&o) const { o << scope_path(func_) << "("; if (! parms_.empty()) { parms_[0]->dump(o); for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { o << ", "; parms_[idx]->dump(o); } } o << ")"; } void NetEUnary::dump(ostream&o) const { switch (op_) { case 'A': o << "~&"; break; case 'm': o << "abs"; break; case 'N': o << "~|"; break; case 'X': o << "~^"; break; case 'I': o << "++"; break; case 'D': o << "--"; break; case 'i': case 'd': break; default: o << op_; break; } o << "("; expr_->dump(o); o << ")"; switch (op_) { case 'i': o << "++"; break; case 'd': o << "--"; break; } } void Design::dump(ostream&o) const { o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl; o << "PACKAGES:" << endl; for (map::const_iterator cur = packages_.begin() ; cur != packages_.end() ; ++cur) { cur->second->dump(o); } o << "SCOPES:" << endl; for (list::const_iterator scope = root_scopes_.begin(); scope != root_scopes_.end(); ++ scope ) { (*scope)->dump(o); } o << "ELABORATED NODES:" << endl; // dump the nodes, if (nodes_) { NetNode*cur = nodes_->node_next_; do { assert(cur); cur->dump_node(o, 0); cur = cur->node_next_; } while (cur != nodes_->node_next_); } o << "ELABORATED BRANCHES:" << endl; if (branches_) { for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) cur->dump(o, 0); } o << "ELABORATED PROCESSES:" << endl; // Dump the processes. for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_) idx->dump(o, 0); for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_) idx->dump(o, 0); } iverilog-12_0/developer-quick-start.txt000066400000000000000000000141071435245347300203450ustar00rootroot00000000000000 Developer Quick Start for Icarus Verilog The documentation for getting, building and installing Icarus Verilog is kept and maintained at the iverilog documentation wiki at . 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. What this documentation *will* cover is the 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. * 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 (this 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. iverilog-12_0/discipline.cc000066400000000000000000000023571435245347300160100ustar00rootroot00000000000000/* * 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 "discipline.h" ivl_nature_s::ivl_nature_s(perm_string name__, perm_string access__) : name_(name__), access_(access__) { } ivl_nature_s::~ivl_nature_s() { } ivl_discipline_s::ivl_discipline_s(perm_string name__, ivl_dis_domain_t domain__, ivl_nature_t pot, ivl_nature_t flow__) : name_(name__), domain_(domain__), potential_(pot), flow_(flow__) { } ivl_discipline_s::~ivl_discipline_s() { } iverilog-12_0/discipline.h000066400000000000000000000050461435245347300156500ustar00rootroot00000000000000#ifndef IVL_discipline_H #define IVL_discipline_H /* * Copyright (c) 2008-2021 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. */ /* * The discipline types include the discipline, nature and other * related types for managing declared and used disciplines in a * Verilog-AMS program. */ # include "StringHeap.h" # include # include # include "ivl_target.h" # include "LineInfo.h" extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t); class ivl_nature_s : public LineInfo { public: explicit ivl_nature_s(perm_string name, perm_string access); ~ivl_nature_s(); perm_string name() const { return name_; } // Identifier for the access function for this nature perm_string access() const { return access_; } private: perm_string name_; perm_string access_; }; class ivl_discipline_s : public LineInfo { public: explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom, ivl_nature_t pot, ivl_nature_t flow); ~ivl_discipline_s(); perm_string name() const { return name_; } ivl_dis_domain_t domain() const { return domain_; } ivl_nature_t potential() const { return potential_; } ivl_nature_t flow() const { return flow_; } private: perm_string name_; ivl_dis_domain_t domain_; ivl_nature_t potential_; ivl_nature_t flow_; private: // not implemented ivl_discipline_s(const ivl_discipline_s&); ivl_discipline_s& operator = (const ivl_discipline_s&); }; extern std::map natures; extern std::map disciplines; // Map access function name to the nature that it accesses. extern std::map access_function_nature; #endif /* IVL_discipline_H */ iverilog-12_0/disciplines.vams000066400000000000000000000021451435245347300165470ustar00rootroot00000000000000 // Standard definitions for Verilog-AMS `ifdef DISCIPLINES_VAMS `else `define DISCIPLINES_VAMS 1 discipline \logic ; domain discrete; enddiscipline discipline ddiscrete; domain discrete; enddiscipline nature Current; units = "A"; access = I; idt_nature = Charge; `ifdef CURRENT_ABSTOL abstol = `CURRENT_ABSTOL `else abstol = 1e-12; `endif endnature nature Charge; units = "coul"; access = Q; ddt_nature = Current; `ifdef CHARGE_ABSTOL abstol = `CHARGE_ABSTOL; `else abstol = 1e-14; `endif endnature nature Voltage; units = "V"; access = V; idt_nature = Flux; `ifdef VOLTAGE_ABSTOL abstol = `VOLTAGE_ABSTOL; `else abstol = 1e-6; `endif endnature nature Flux; units = "Wb"; access = Phi; ddt_nature = Voltage; `ifdef FLUX_ABSTOL abstol = `flux_ABSTOL; `else abstol = 1e-9; `endif endnature discipline electrical; potential Voltage; flow Current; enddiscipline discipline voltage; potential Voltage; enddiscipline discipline current; flow Current; enddiscipline `endif // !`ifdef DISCIPLINES_VAMS iverilog-12_0/dosify.c000066400000000000000000000036151435245347300150150ustar00rootroot00000000000000/* * Copyright (c) 2001-2009 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. */ /* * This is a simple program to make a dosified copy of the * original. That is, it converts Unix style line ends to DOS * style. This is useful for installing text files. * * The exact substitution is to replace \n with \r\n. If the line * already ends with \r\n then it is not changed to \r\r\n. */ # include int main(int argc, char*argv[]) { FILE*ifile; FILE*ofile; int ch, pr; if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } ifile = fopen(argv[1], "rb"); if (ifile == 0) { fprintf(stderr, "Unable to open %s for input.\n", argv[1]); return 2; } ofile = fopen(argv[2], "wb"); if (ofile == 0) { fprintf(stderr, "Unable to open %s for output.\n", argv[2]); fclose(ifile); return 2; } pr = 0; while ((ch = fgetc(ifile)) != EOF) { if ((ch == '\n') && (pr != '\r')) fputc('\r', ofile); fputc(ch, ofile); pr = ch; } fclose(ifile); fclose(ofile); return 0; } iverilog-12_0/driver-vpi/000077500000000000000000000000001435245347300154365ustar00rootroot00000000000000iverilog-12_0/driver-vpi/Makefile.in000066400000000000000000000061471435245347300175130ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ datarootdir = @datarootdir@ VPATH = $(srcdir) suffix = @install_suffix@ bindir = $(exec_prefix)/bin libdir = $(exec_prefix)/lib includedir = $(prefix)/include mandir = @mandir@ dllib=@DLLIB@ CC = @CC@ HOSTCC := @CC@ WINDRES = @WINDRES@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ O = main.o res.o all: iverilog-vpi@EXEEXT@ check: all clean: rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc distclean: clean rm -f Makefile config.log cppcheck: main.c cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=driver-vpi/$@ iverilog-vpi@EXEEXT@: $O $(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@ main.o: $(srcdir)/main.c config.h $(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c config.h: $(srcdir)/config.h.in Makefile sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \ -e 's;@SUFFIX@;$(suffix);g' \ -e 's;@IVLCFLAGS@;$(CFLAGS);' \ -e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \ -e 's;@SHARED@;@shared@;' $< > $@ # Windows specific... res.rc: $(srcdir)/res.rc.in ../version.exe sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \ $(srcdir)/res.rc.in > $@ res.o: res.rc $(WINDRES) -i res.rc -o res.o # install: all installdirs installfiles F = ./iverilog-vpi@EXEEXT@ installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@" ifeq (@WIN32@,yes) ifneq ($(HOSTCC),$(CC)) $(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)" $(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libgcc_s_sjlj-1.dll) "$(DESTDIR)$(bindir)" $(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libstdc++-6.dll) "$(DESTDIR)$(bindir)" endif endif installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" uninstall: rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@ iverilog-12_0/driver-vpi/config.h.in000066400000000000000000000010351435245347300174600ustar00rootroot00000000000000/* For now do not put the Icarus Verilog include or library paths here. * They are generated from a registry entry the user must set (-ivl=). * This may change in the future once I have thought about it more. */ #define IVERILOG_VPI_CC "@IVLCC@" #define IVERILOG_VPI_CXX "@IVLCXX@" #define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@" #define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@" #define IVERILOG_VPI_LDFLAGS "@SHARED@" #define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@" #define IVERILOG_SUFFIX "@SUFFIX@" iverilog-12_0/driver-vpi/main.c000066400000000000000000000431431435245347300165330ustar00rootroot00000000000000/* * Copyright (c) 2015-2022 Martin Whitaker * Copyright (c) 2002 Gus Baldauf (gus@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * iverilog-vpi.c * * this program provides the functionality of iverilog-vpi.sh under Windows */ #include #include #include #include #include #include static void setup_ivl_environment(void); static void assign(char **ptr, char *str); /* The compile options: compiler, flags, etc. are in here */ #include "config.h" /* pointers to global strings */ static struct global_strings { char *pCCSRC; /* list of C source files (*.c) */ char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */ char *pOBJ; /* list of object files */ char *pLIB; /* list of library files */ char *pINCS; /* list of include directories */ char *pDEFS; /* list of definitions */ char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */ char *pMINGW; /* path to MinGW directory */ char *pIVL; /* path to IVL directory */ char *pCCFLAGS; /* compiler flags for compiling C source files */ char *pCXFLAGS; /* compiler flags for compiling C++ source files */ char *pLDLIBS; /* linker flags for final linking stage */ char *pCCNAME; /* base name of compiler */ char *pLD; /* what to use for a linker */ } gstr; static void deInitDynString(char *str) { free(str); } /* when finished, free allocated memory and return error code */ static void myExit(int exitVal) { deInitDynString(gstr.pCCSRC); deInitDynString(gstr.pCXSRC); deInitDynString(gstr.pOBJ); deInitDynString(gstr.pLIB); deInitDynString(gstr.pINCS); deInitDynString(gstr.pDEFS); deInitDynString(gstr.pOUT); deInitDynString(gstr.pMINGW); deInitDynString(gstr.pIVL); deInitDynString(gstr.pCCFLAGS); deInitDynString(gstr.pCXFLAGS); deInitDynString(gstr.pLDLIBS); deInitDynString(gstr.pCCNAME); deInitDynString(gstr.pLD); exit(exitVal); } /* display usage summary and exit */ static void usage(void) { fprintf(stderr, "usage: iverilog-vpi" IVERILOG_SUFFIX " [options] [src and obj files]...\n"); fprintf(stderr, " or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n"); myExit(1); } static void initDynString(char **str) { *str = (char *) malloc(1); if (!*str) { fprintf(stderr, "error: out of memory\n"); myExit(4); } *str[0] = 0; } /* initialize dynamic memory buffers */ static void init(void) { char *ptr; initDynString(&gstr.pCCSRC); initDynString(&gstr.pCXSRC); initDynString(&gstr.pOBJ); initDynString(&gstr.pLIB); initDynString(&gstr.pINCS); initDynString(&gstr.pDEFS); initDynString(&gstr.pOUT); initDynString(&gstr.pMINGW); initDynString(&gstr.pIVL); initDynString(&gstr.pCCFLAGS); initDynString(&gstr.pCXFLAGS); initDynString(&gstr.pLDLIBS); initDynString(&gstr.pCCNAME); initDynString(&gstr.pLD); /* Get the base name of the C compiler. */ assign(&gstr.pCCNAME, IVERILOG_VPI_CC); ptr = strchr(gstr.pCCNAME, ' '); if (ptr != NULL) *ptr = '\0'; /* By default use the C compiler to link the programs. */ assign(&gstr.pLD, IVERILOG_VPI_CC); } /* return true if "str" is terminated with with "end", case insensitive */ static int endsIn (char *end, char *str) { char *ext; if (strlen(end) >= strlen(str)) return 0; ext = str + (strlen(str) - strlen(end)); return stricmp(end, ext) ? 0 : 1; } /* return true if "str" begins with "prefix", case insensitive */ static int startsWith (char *prefix, char *str) { if (strlen(prefix) >= strlen(str)) return 0; return strnicmp(prefix, str, strlen(prefix)) ? 0 : 1; } /* append "app" to "ptr", allocating memory as needed */ /* if count is zero, then copy all characters of "app" */ static void appendn (char **ptr, char *app, size_t count) { char *nptr = (char *) realloc(*ptr, strlen(*ptr) + (count ? count : strlen(app)) + 1); if (nptr == NULL) { fprintf(stderr, "error: out of memory\n"); free(*ptr); myExit(4); } *ptr = nptr; if (count) strncat(*ptr, app, count); else strcat(*ptr, app); } /* append "app" to "ptr", allocating memory as needed */ static void append (char **ptr, char *app) { appendn(ptr, app, 0); } /* if the string does not end with a backslash, add one */ static void appendBackSlash(char **str) { if ((*str)[strlen(*str)-1] != '\\') append(str, "\\"); } /* copy count characters of "str" to "ptr", allocating memory as needed */ /* if count is zero, then copy all characters of "str" */ static void assignn (char **ptr, char *str, size_t count) { char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1); if (nptr == NULL) { fprintf(stderr, "error: out of memory\n"); free(*ptr); myExit(4); } *ptr = nptr; if (count) { strncpy(*ptr, str, count); (*ptr)[count] = 0; } else strcpy(*ptr, str); } /* copy count characters of "str" to "ptr", allocating memory as needed */ static void assign (char **ptr, char *str) { assignn(ptr, str, 0); } /* get a copy of a Icarus Verilog registry string key */ static int GetRegistryKey(char *key, char **value) { long lrv; HKEY hkKey; char *regKeyBuffer; DWORD regKeyType, regKeySize; lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, KEY_QUERY_VALUE, &hkKey); if (lrv != ERROR_SUCCESS) return 0; lrv = RegQueryValueEx(hkKey, key, NULL, ®KeyType, NULL, ®KeySize); if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) { RegCloseKey(hkKey); return 0; } regKeyBuffer = (char *) malloc(regKeySize+1); if (!regKeyBuffer) { RegCloseKey(hkKey); fprintf(stderr, "error: out of memory\n"); myExit(4); } regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */ /* This needs an unsigned char *, but for MinGW the char is signed. */ lrv = RegQueryValueEx(hkKey, key, NULL, ®KeyType, (unsigned char *) regKeyBuffer, ®KeySize); if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) { RegCloseKey(hkKey); free(regKeyBuffer); return 0; } RegCloseKey(hkKey); assign(value, regKeyBuffer); free(regKeyBuffer); return 1; } /* store a copy of a Icarus Verilog registry string key */ static void SetRegistryKey(char *key, char *value) { long lrv; HKEY hkKey; DWORD res; lrv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkKey, &res); if (lrv != ERROR_SUCCESS) { char message[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lrv, LANG_USER_DEFAULT, message, sizeof(message), NULL); fprintf(stderr, "error: couldn't write to registry - %s\n", message); if (lrv == ERROR_ACCESS_DENIED) { fprintf(stderr, " try running as administrator\n"); } return; } /* This needs an unsigned char *, but for MinGW the char is signed. */ RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value, strlen(value)+1); RegCloseKey(hkKey); printf("info: storing %s in Windows' registry entry\n", value); printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n", key); } /* parse the command line, assign results to global variable strings */ static int parse(int argc, char *argv[]) { int idx, srcFileCnt=0; char dot_c_ext[] = ".c"; char dot_cc_ext[] = ".cc"; char dot_cpp_ext[] = ".cpp"; char dot_o_ext[] = ".o"; char name_option[] = "--name="; char lib_option[] = "-l"; char inc_option[] = "-I"; char mingw_option[] = "-mingw="; char def_option[] = "-D"; if (argc == 1) return 0; for (idx=1; idx $@ # Use pattern rules to avoid parallel build issues (see pr3462585) cfparse%c cfparse%h: $(srcdir)/cfparse%y $(YACC) --verbose -t -p cf -d -o cfparse.c $< %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' -DIVL_INCLUDE_INSTALL_DIR="\"$(realpath $(DESTDIR)/$(includedir))\"" $(srcdir)/main.c mv $*.d dep cflexor.o: cflexor.c cfparse.h iverilog.man: $(srcdir)/iverilog.man.in ../version.exe ../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@ tail -n +2 $(srcdir)/iverilog.man.in >> $@ iverilog.ps: iverilog.man $(MAN) -t ./iverilog.man > iverilog.ps iverilog.pdf: iverilog.ps $(PS2PDF) iverilog.ps iverilog.pdf ifeq (@MINGW32@,yes) ifeq ($(MAN),none) INSTALL_DOC = installman else ifeq ($(PS2PDF),none) INSTALL_DOC = installman else INSTALL_DOC = installpdf installman all: iverilog.pdf endif endif INSTALL_DOCDIR = $(mandir)/man1 else INSTALL_DOC = installman INSTALL_DOCDIR = $(mandir)/man1 endif install: all installdirs installfiles F = ./iverilog@EXEEXT@ \ $(INSTALL_DOC) installman: iverilog.man installdirs $(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" installpdf: iverilog.pdf installdirs $(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf" installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(INSTALL_DOCDIR)" uninstall: rm -f "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@" rm -f "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" "$(DESTDIR)$(prefix)/iverilog$(suffix).pdf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/driver/cflexor.lex000066400000000000000000000175161435245347300170300ustar00rootroot00000000000000%option prefix="cf" %option nounput %option noinput %{ /* * Copyright (c) 2001-2021 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 "cfparse_misc.h" # include "cfparse.h" # include "globals.h" # include char *current_file = NULL; static int comment_enter; static char* trim_trailing_white(char*txt, int trim); /* * Mostly copied from the flex manual. Do not make this arbitrary * depth without checking for looping files. */ #define MAX_CMDFILE_DEPTH 15 typedef struct t_cmdfile { char *cmdfile; YY_BUFFER_STATE buffer; } s_cmdfile; s_cmdfile cmdfile_stack[MAX_CMDFILE_DEPTH]; int cmdfile_stack_ptr = 0; # define PROCESS_EOF \ if (--cmdfile_stack_ptr < 0) { \ free(current_file); \ yyterminate(); \ } else { \ yy_delete_buffer(YY_CURRENT_BUFFER); \ yy_switch_to_buffer(cmdfile_stack[cmdfile_stack_ptr].buffer); \ free(current_file); \ current_file = cmdfile_stack[cmdfile_stack_ptr].cmdfile; \ } %} %x CCOMMENT %x LCOMMENT %x PLUS_ARGS %x FILE_NAME %% /* Accept C++ style comments. */ "//".* { comment_enter = YY_START; BEGIN(LCOMMENT); } . { yymore(); } \n { cflloc.first_line += 1; BEGIN(comment_enter); } <> { fprintf(stderr, "%s:%u: ERROR: Comment not terminated.\n", current_file, cflloc.first_line); command_file_errors += 1; BEGIN(0); PROCESS_EOF } /* Accept C style comments. */ "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); } . { yymore(); } \n { cflloc.first_line += 1; yymore(); } "*/" { BEGIN(comment_enter); } <> { fprintf(stderr, "%s:%u: ERROR: Comment not terminated.\n", current_file, cflloc.first_line); command_file_errors += 1; BEGIN(0); PROCESS_EOF } /* Accept shell type comments. */ ^"#".* { ; } /* Skip white space. */ [ \t\f\r] { ; } /* Skip line ends, but also count the line. */ \n { cflloc.first_line += 1; } "+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; } "+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; } "+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; } "+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; } "+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; } "+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; } "+parameter+" { BEGIN(PLUS_ARGS); return TOK_PARAMETER; } "+timescale+" { BEGIN(PLUS_ARGS); return TOK_TIMESCALE; } "+vhdl-work+" { BEGIN(PLUS_ARGS); return TOK_VHDL_WORK; } "+vhdl-libdir+" { BEGIN(PLUS_ARGS); return TOK_VHDL_LIBDIR; } "+width-cap+" { BEGIN(PLUS_ARGS); return TOK_WIDTH_CAP; } /* If it is not any known plus-flag, return the generic form. */ "+"[^\n \t\b\f\r+]* { cflval.text = strdup(yytext); BEGIN(PLUS_ARGS); return TOK_PLUSWORD; } /* Once in PLUS_ARGS mode, words are delimited by + characters. White space and line end terminate PLUS_ARGS mode, but + terminates only the word. */ [^\n \t\b\f\r+]* { cflval.text = strdup(yytext); return TOK_PLUSARG; } /* Within plusargs, this is a delimiter. */ "+" { } /* White space end plus_args mode. */ [ \t\b\f\r] { BEGIN(0); } \n { cflloc.first_line += 1; BEGIN(0); } <> { BEGIN(0); fprintf(stderr, "%s:%u: ERROR: Plusargs statement not terminated.\n", current_file, cflloc.first_line); command_file_errors += 1; PROCESS_EOF } /* Notice the -a flag. */ "-a" { return TOK_Da; } /* Notice the -c or -f flag. */ "-c" { return TOK_Dc; } "-f" { return TOK_Dc; } /* Notice the -l or -v flag. */ "-l" { return TOK_Dv; } "-v" { return TOK_Dv; } /* Notice the -y flag. */ "-y" { return TOK_Dy; } /* This rule matches paths and strings that may be file names. This is a little bit tricky, as we don't want to mistake a comment for a string word. */ "/"[\r\n] { /* Special case of file name "/" */ cflval.text = trim_trailing_white(yytext, 0); return TOK_STRING; } "/"[^\*\/] { /* A file name that starts with "/". */ yymore(); BEGIN(FILE_NAME); } [^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */ yymore(); BEGIN(FILE_NAME); } "//" { /* Found a trailing comment. Returning the terminated name. */ cflval.text = trim_trailing_white(yytext, 2); BEGIN(LCOMMENT); return TOK_STRING; } "/"?[^/\n\r]* { yymore(); /* not a comment... continuing */; } [\n\r] { /* No trailing comment. Return the file name. */ cflval.text = trim_trailing_white(yytext, 0); BEGIN(0); return TOK_STRING; } <> { cflval.text = trim_trailing_white(yytext, 0); BEGIN(0); fprintf(stderr, "%s:%u: ERROR: File name not terminated.\n", current_file, cflloc.first_line); command_file_errors += 1; PROCESS_EOF } /* Fallback match. */ . { return yytext[0]; } /* At the end of file switch back to the previous buffer. */ <> { PROCESS_EOF } %% static char* trim_trailing_white(char*text, int trim) { char*cp = text + strlen(text); while (cp > text && trim > 0) { trim -= 1; cp -= 1; *cp = 0; } while (cp > text && strchr("\n\r\t\b", cp[-1])) cp -= 1; cp[0] = 0; return strdup(text); } int yywrap() { return 1; } void switch_to_command_file(const char *file) { char path[4096]; if (cmdfile_stack_ptr >= MAX_CMDFILE_DEPTH) { fprintf(stderr, "Error: command files nested too deeply (%d) " "at %s:%u.\n", MAX_CMDFILE_DEPTH, current_file, cflloc.first_line); exit(1); } cmdfile_stack[cmdfile_stack_ptr].buffer = YY_CURRENT_BUFFER; cmdfile_stack[cmdfile_stack_ptr].cmdfile = current_file; cmdfile_stack_ptr += 1; /* * If this is a relative file then add the current path to the * file name. */ if (file[0] != '/') { char *cp; strcpy(path, current_file); cp = strrchr(path, '/'); if (cp == 0) strcpy(path, file); /* A base file. */ else { *(cp+1) = '\0'; strcat(path, file); } } else strcpy(path, file); /* An absolute path. */ yyin = fopen(path, "r"); if (yyin == NULL) { fprintf(stderr, "Error: unable to read nested command file (%s) " "at %s:%u.\n", path, current_file, cflloc.first_line); exit(1); } current_file = strdup(path); yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); cflloc.first_line = 1; } void cfreset(FILE*fd, const char*path) { command_file_errors = 0; yyin = fd; yyrestart(fd); current_file = strdup(path); cflloc.first_line = 1; } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_lexor(void) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } iverilog-12_0/driver/cfparse.y000066400000000000000000000141331435245347300164610ustar00rootroot00000000000000%{ /* * Copyright (c) 2001-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 "globals.h" # include "cfparse_misc.h" # include # include # include # include # include "ivl_alloc.h" /* * This flag is set to 0, 1 or 2 if file names are to be translated to * uppercase(1) or lowercase(2). */ static int setcase_filename_flag = 0; static void translate_file_name(char*text) { switch (setcase_filename_flag) { case 0: break; case 1: while (*text) { *text = toupper((int)*text); text += 1; } break; case 2: while (*text) { *text = tolower((int)*text); text += 1; } break; } } %} %union { char*text; }; %token TOK_Da TOK_Dc TOK_Dv TOK_Dy %token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE %token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK TOK_VHDL_LIBDIR %token TOK_WIDTH_CAP %token TOK_PLUSARG TOK_PLUSWORD TOK_STRING %% start : | item_list ; item_list : item_list item | item ; item /* Absent any other matching, a token string is taken to be the name of a source file. Add the file to the file list. */ : TOK_STRING { char*tmp = substitutions($1); translate_file_name(tmp); process_file_name(tmp, 0); free($1); free(tmp); } /* The -a flag is completely ignored. */ | TOK_Da { } /* Match a -c or -f */ | TOK_Dc TOK_STRING { char*tmp = substitutions($2); translate_file_name(tmp); switch_to_command_file(tmp); free($2); free(tmp); } /* The -v flag is ignored, and the is processed as an ordinary source file. */ | TOK_Dv TOK_STRING { char*tmp = substitutions($2); translate_file_name(tmp); process_file_name(tmp, 1); free($2); free(tmp); } /* This rule matches "-y " sequences. This does the same thing as -y on the command line, so add the path to the library directory list. */ | TOK_Dy TOK_STRING { char*tmp = substitutions($2); process_library_switch(tmp); free($2); free(tmp); } | TOK_LIBDIR TOK_PLUSARG { char*tmp = substitutions($2); process_library_switch(tmp); free($2); free(tmp); } | TOK_LIBDIR_NOCASE TOK_PLUSARG { char*tmp = substitutions($2); process_library_nocase_switch(tmp); free($2); free(tmp); } | TOK_PARAMETER TOK_PLUSARG { char*tmp = substitutions($2); process_parameter(tmp); free($2); free(tmp); } /* The +timescale token is used to set the default timescale for the simulator. */ | TOK_TIMESCALE TOK_PLUSARG { char*tmp = substitutions($2); process_timescale(tmp); free($2); free(tmp); } | TOK_DEFINE TOK_PLUSARG { process_define($2); free($2); } | TOK_VHDL_WORK TOK_PLUSARG { char*tmp = substitutions($2); vhdlpp_work = tmp; free($2); } | TOK_VHDL_LIBDIR TOK_PLUSARG { char*tmp = substitutions($2); vhdlpp_libdir = realloc(vhdlpp_libdir, (vhdlpp_libdir_cnt+1)*sizeof(char*)); vhdlpp_libdir[vhdlpp_libdir_cnt] = tmp; vhdlpp_libdir_cnt += 1; free($2); } /* The +incdir token introduces a list of + arguments that are the include directories to search. */ | TOK_INCDIR inc_args /* The +libext token introduces a list of + arguments that become individual -Y flags to ivl. */ | TOK_LIBEXT libext_args /* These are various misc flags that are supported. */ | TOK_INTEGER_WIDTH TOK_PLUSARG { char*tmp = substitutions($2); free($2); integer_width = strtoul(tmp,0,10); free(tmp); } | TOK_WIDTH_CAP TOK_PLUSARG { char*tmp = substitutions($2); free($2); width_cap = strtoul(tmp,0,10); free(tmp); } /* The + tokens that are not otherwise matched, are ignored. The skip_args rule arranges for all the argument words to be consumed. */ | TOK_PLUSWORD skip_args { fprintf(stderr, "%s:%u: Ignoring %s\n", @1.text, @1.first_line, $1); free($1); } | TOK_PLUSWORD { if (strcmp($1, "+toupper-filenames") == 0) { setcase_filename_flag = 1; } else if (strcmp($1, "+tolower-filenames") == 0) { setcase_filename_flag = 2; } else { fprintf(stderr, "%s:%u: Ignoring %s\n", @1.text, @1.first_line, $1); } free($1); } | error { fprintf(stderr, "Error: unable to parse line %u in " "%s.\n", cflloc.first_line, current_file); return 1; } ; /* inc_args are +incdir+ arguments in order. */ inc_args : inc_args inc_arg | inc_arg ; inc_arg : TOK_PLUSARG { char*tmp = substitutions($1); process_include_dir(tmp); free($1); free(tmp); } ; /* inc_args are +incdir+ arguments in order. */ libext_args : libext_args libext_arg | libext_arg ; libext_arg : TOK_PLUSARG { process_library2_switch($1); free($1); } ; /* skip_args are arguments to a +word flag that is not otherwise parsed. This rule matches them and releases the strings, so that they can be safely ignored. */ skip_args : skip_args skip_arg | skip_arg ; skip_arg : TOK_PLUSARG { free($1); } ; %% int command_file_errors = 0; int yyerror(const char*msg) { (void)msg; /* Parameter is not used. */ command_file_errors += 1; return 0; } iverilog-12_0/driver/cfparse_misc.h000066400000000000000000000027761435245347300174650ustar00rootroot00000000000000#ifndef IVL_cfparse_misc_H #define IVL_cfparse_misc_H /* * Copyright (c) 2001-2014 Picture Elements, Inc. * Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * The vlltype supports the passing of detailed source file location * information between the lexical analyzer and the parser. Defining * YYLTYPE compels the lexor to use this type and not something other. */ struct cfltype { unsigned first_line; unsigned first_column; unsigned last_line; unsigned last_column; const char*text; }; # define YYLTYPE struct cfltype int cflex(void); int cferror(const char *); int cfparse(void); void switch_to_command_file(const char *); void destroy_lexor(void); extern char *current_file; #endif /* IVL_cfparse_misc_H */ iverilog-12_0/driver/globals.h000066400000000000000000000041211435245347300164340ustar00rootroot00000000000000#ifndef IVL_globals_H #define IVL_globals_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 /* Count errors in the command file. */ extern int command_file_errors; /* This is the integer-width argument that will be passed to ivl. */ extern unsigned integer_width; /* This is the width-cap argument that will be passed to ivl. */ extern unsigned width_cap; extern const char*vhdlpp_work; extern const char**vhdlpp_libdir; extern unsigned vhdlpp_libdir_cnt; /* Perform variable substitutions on the string. */ extern char* substitutions(const char*str); /* Add the name to the list of source files. */ extern void process_file_name(const char*name, int lib_flag); /* Add the name to the list of library directories. */ extern void process_library_switch(const char*name); extern void process_library_nocase_switch(const char*name); extern void process_library2_switch(const char*name); /* Add a new include file search directory */ extern void process_include_dir(const char*name); /* Add a new -D define. */ extern void process_define(const char*name); /* Add a new parameter definition */ extern void process_parameter(const char*name); /* Set the default timescale for the simulator. */ extern void process_timescale(const char*ts_string); #endif /* IVL_globals_H */ iverilog-12_0/driver/iverilog.man.in000066400000000000000000000643651435245347300176020ustar00rootroot00000000000000.TH iverilog 1 "Jan 14th, 2021" "" "Version %M.%n%E" .SH NAME iverilog - Icarus Verilog compiler .SH SYNOPSIS .B iverilog [\-EiRSuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]] [\-Pparameter=value] [\-pflag=value] [\-dname] [\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g] [\-Iincludedir] [\-Lmoduledir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename] [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] [\-lfile] sourcefile .SH DESCRIPTION .PP \fIiverilog\fP is a compiler that translates Verilog source code into executable programs for simulation, or other netlist formats for further processing. The currently supported targets are \fIvvp\fP for simulation, and \fIfpga\fP for synthesis. Other target types are added as code generators are implemented. .SH OPTIONS \fIiverilog\fP accepts the following options: .TP 8 .B -B\fIbase\fP The \fIiverilog\fP program uses external programs and configuration files to preprocess and compile the Verilog source. Normally, the path used to locate these tools is built into the \fIiverilog\fP program. However, the \fB\-B\fP switch allows the user to select a different set of programs. The path given is used to locate \fIivlpp\fP, \fIivl\fP, code generators and the VPI modules. .TP 8 .B -c\fIfile\fP -f\fIfile\fP These flags specify an input file that contains a list of Verilog source files. This is similar to the \fIcommand file\fP of other Verilog simulators, in that it is a file that contains the file names instead of taking them on the command line. See \fBCommand Files\fP below. .TP 8 .B -D\fImacro\fP Defines macro \fImacro\fP with the string `1' as its definition. This form is normally only used to trigger ifdef conditionals in the Verilog source. .TP 8 .B -D\fImacro=defn\fP Defines macro \fImacro\fP as \fIdefn\fP. .TP 8 .B -P\fIparameter=value\fP Override (i.e. defparam) a parameter in a root module. This allows the user to override at compile time (defparam) a parameter in a root module instance. For example, \fB\-Pmain.foo=2\fP overrides the parameter foo in the root instance main with the value 2. .TP 8 .B -d\fIname\fP Activate a class of compiler debugging messages. The \fB\-d\fP switch may be used as often as necessary to activate all the desired messages. Supported names are scopes, eval_tree, elaborate, and synth2; any other names are ignored. .TP 8 .B -E Preprocess the Verilog source, but do not compile it. The output file is the Verilog input, but with file inclusions and macro references expanded and removed. This is useful, for example, to preprocess Verilog source for use by other compilers. .TP 8 .B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012 Select the Verilog language \fIgeneration\fP to support in the compiler. This selects between \fIIEEE1364\-1995\fP, \fIIEEE1364\-2001\fP, \fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or \fIIEEE1800\-2012\fP. Icarus Verilog currently defaults to the \fIIEEE1364\-2005\fP generation of the language. This flag is used to restrict the language to a set of keywords/features, this allows simulation of older Verilog code that may use newer keywords and for compatibility with other tools. Much of the \fIIEEE1800\fP generations functionality is not currently supported. The \fIIEEE1800\fP generations do parse all the keywords, so they can be used to verify that \fIIEEE1364\fP compliant Verilog code does not use any of the new \fIIEEE1800\fP keywords. .TP 8 .B -gverilog-ams\fI|\fP-gno-verilog-ams Enable or disable (default) support for Verilog\-AMS. Very little Verilog\-AMS specific functionality is currently supported. .TP 8 .B -gassertions\fI|\fP-gsupported-assertions\fI|\fP-gno-assertions Enable (default) or disable SystemVerilog assertions. When enabled, assertion statements are elaborated. When disabled, assertion statements are parsed but ignored. The \fB\-gsupported-assertions\fP option only enables assertions that are currently supported by the compiler. .TP 8 .B -gspecify\fI|\fP-gno-specify Enable or disable (default) specify block support. When enabled, specify block code is elaborated. When disabled, specify blocks are parsed but ignored. Specify blocks are commonly not needed for RTL simulation, and in fact can hurt performance of the simulation. However, disabling specify blocks reduces accuracy of full-timing simulations. .TP 8 .B -gstd-include\fI|\fP-gno-std-include Enable (default) or disable the search of a standard installation include directory after all other explicit include directories. This standard include directory is a convenient place to install standard header files that a Verilog program may include. .TP 8 .B -grelative-include\fI|\fP-gno-relative-include Enable or disable (default) adding the local files directory to the beginning of the include file search path. This allows files to be included relative to the current file not the more common files are only found in the working directory or in the specified include file search path. .TP 8 .B -gxtypes\fI|\fP-gno-xtypes Enable (default) or disable support for extended types. Enabling extended types allows for new types that are supported by Icarus Verilog as extensions beyond the baseline Verilog. It may be necessary to disable extended types if compiling code that clashes with the few new keywords used to implement the type system. .TP 8 .B -gio-range-error\fI|\fP-gno-io-range-error The standards requires that a vectored port have matching ranges for its port declaration as well as any net/register declaration. It was common practice in the past to only specify the range for the net/register declaration and some tools still allow this. By default any mismatch is reported as a error. Using \fB\-gno\-io\-range\-error\fP will produce a warning instead of a fatal error for the case of a vectored net/register and a scalar port declaration. This warning is included in the \fBanachronisms\fP category. .TP 8 .B -gstrict-ca-eval\fI|\fP-gno-strict-ca-eval The standard requires that if any input to a continuous assignment expression changes value, the entire expression is re-evaluated. By default, parts of the expression that do not depend on the changed input value(s) are not re-evaluated. If an expression contains a call to a function that doesn't depend solely on its input values or that has side effects, the resulting behavior will differ from that required by the standard. Using \fB\-gstrict\-ca\-eval\fP will force standard compliant behavior (with some loss in performance). .TP 8 .B -gstrict-expr-width\fI|\fP-gno-strict-expr-width Enable or disable (default) strict compliance with the standard rules for determining expression bit lengths. When disabled, the RHS of a parameter assignment is evaluated as a lossless expression, as is any expression containing an unsized constant number, and unsized constant numbers are not truncated to integer width. .TP 8 .B -gshared-loop-index\fI|\fP-gno-shared-loop-index Enable (default) or disable the exclusion of for-loop control variables from implicit event_expression lists. When enabled, if a for-loop control variable (loop index) is only used inside the for-loop statement, the compiler will not include it in an implicit event_expression list it calculates for that statement or any enclosing statement. This allows the same control variable to be used in multiple processes without risk of entering an infinite loop caused by each process triggering all other processes that use the same varaible. For strict compliance with the standards, this behaviour should be disabled. .TP 8 .B -I\fIincludedir\fP Append directory \fIincludedir\fP to list of directories searched for Verilog include files. The \fB\-I\fP switch may be used many times to specify several directories to search, the directories are searched in the order they appear on the command line. .TP 8 .B -i Ignore missing modules. Normally it is an error if a module instantiation refers to an undefined module. This option causes the compiler to skip over that instantiation. It will also stop the compiler returning an error if there are no top level modules. This allows the compiler to be used to check incomplete designs for errors. .TP 8 .B -L\fIpath\fP This flag adds a directory to the path list used to locate VPI modules. The default path includes only the install directory for the system.vpi module, but this flag can add other directories. Multiple paths are allowed, and the paths will be searched in order. .TP 8 .B -l\fIfile\fP Add the specified file to the list of source files to be compiled, but mark it as a library file. All modules contained within that file will be treated as library modules, and only elaborated if they are instantiated by other modules in the design. .TP 8 .B -M\fIpath\fP This is equivalent to \fB\-Mall=path\fP. Preserved for backwards compatibility. .TP 8 .B -M\fImode=path\fP Write into the file specified by path a list of files that contribute to the compilation of the design. If \fBmode\fP is \fBall\fP or \fBprefix\fP, this includes files that are included by include directives and files that are automatically loaded by library support as well as the files explicitly specified by the user. If \fBmode\fP is \fBinclude\fP, only files that are included by include directives are listed. If \fBmode\fP is \fBmodule\fP, only files that are specified by the user or that are automatically loaded by library support are listed. The output is one file name per line, with no leading or trailing space. If \fBmode\fP is \fBprefix\fP, files that are included by include directives are prefixed by "I " and other files are prefixed by "M ". .TP 8 .B -m\fImodule\fP Add this module to the list of VPI modules to be loaded by the simulation. Many modules can be specified, and all will be loaded, in the order specified. The system module is implicit and always included (and loaded last). If the specified name includes at least one directory character, it is assumed to be prefixed by the path to the module, otherwise the module is searched for in the paths specified by preceding \fB-L\fP options, and if not found there, in the \fIiverilog\fP base directory. .TP 8 .B -N\fIpath\fP This is used for debugging the compiler proper. Dump the final netlist form of the design to the specified file. It otherwise does not affect operation of the compiler. The dump happens after the design is elaborated and optimized. .TP 8 .B -o \fIfilename\fP Place output in the file \fIfilename\fP. If no output file name is specified, \fIiverilog\fP uses the default name \fBa.out\fP. .TP 8 .B -p\fIflag=value\fP Assign a value to a target specific flag. The \fB\-p\fP switch may be used as often as necessary to specify all the desired flags. The flags that are used depend on the target that is selected, and are described in target specific documentation. Flags that are not used are ignored. .TP 8 .B -S Synthesize. Normally, if the target can accept behavioral descriptions the compiler will leave processes in behavioral form. The \fB\-S\fP switch causes the compiler to perform synthesis even if it is not necessary for the target. If the target type is a netlist format, the \fB\-S\fP switch is unnecessary and has no effect. .TP 8 .B -s \fItopmodule\fP Specify the top level module to elaborate. Icarus Verilog will by default choose modules that are not instantiated in any other modules, but sometimes that is not sufficient, or instantiates too many modules. If the user specifies one or more root modules with \fB\-s\fP flags, then they will be used as root modules instead. .TP 8 .B -T\fImin|typ|max\fP Use this switch to select min, typ or max times from min:typ:max expressions. Normally, the compiler will simply use the typ value from these expressions (printing a warning for the first ten it finds) but this switch will tell the compiler explicitly which value to use. This will suppress the warning that the compiler is making a choice. .TP 8 .B -t\fItarget\fP Use this switch to specify the target output format. See the \fBTARGETS\fP section below for a list of valid output formats. .TP 8 .B -u Treat each source file as a separate compilation unit (as defined in SystemVerilog). If compiling for an \fIIEEE1364\fP generation, this will just reset all compiler directives (including macro definitions) before each new file is processed. .TP 8 .B -v Turn on verbose messages. This will print the command lines that are executed to perform the actual compilation, along with version information from the various components, as well as the version of the product as a whole. You will notice that the command lines include a reference to a key temporary file that passes information to the compiler proper. To keep that file from being deleted at the end of the process, provide a file name of your own in the environment variable \fBIVERILOG_ICONFIG\fP. If the selected target is \fIvvp\fP, the \fB\-v\fP switch is appended to the shebang line in the compiler output file, so directly executing the compiler output file will turn on verbose messages in \fIvvp\fP. This extra verbosity can be avoided by using the \fIvvp\fP command to indirectly execute the compiler output file. .TP 8 .B -V Print the version of the compiler, and exit. .TP 8 .B -R Print the runtime paths of the compiler, and exit. .TP 8 .B -W\fIclass\fP Turn on different classes of warnings. See the \fBWARNING TYPES\fP section below for descriptions of the different warning groups. If multiple \fB\-W\fP switches are used, the warning set is the union of all the requested classes. .TP 8 .B -y\fIlibdir\fP Append the directory to the library module search path. When the compiler finds an undefined module, it looks in these directories for files with the right name. .TP 8 .B -Y\fIsuffix\fP Add suffix to the list of accepted file name suffixes used when searching a library for cells. The list defaults to the single entry \fI.v\fP. .SH MODULE LIBRARIES The Icarus Verilog compiler supports module libraries as directories that contain Verilog source files. During elaboration, the compiler notices the instantiation of undefined module types. If the user specifies library search directories, the compiler will search the directory for files with the name of the missing module type. If it finds such a file, it loads it as a Verilog source file, then tries again to elaborate the module. Library module files should contain only a single module, but this is not a requirement. Library modules may reference other modules in the library or in the main design. .SH TARGETS The Icarus Verilog compiler supports a variety of targets, for different purposes, and the \fB\-t\fP switch is used to select the desired target. .TP 8 .B null The null target causes no code to be generated. It is useful for checking the syntax of the Verilog source. .TP 8 .B vvp This is the default. The vvp target generates code for the vvp runtime. The output is a complete program that simulates the design but must be run by the \fBvvp\fP command. The -pfileline=1 option can be used to add procedural statement debugging opcodes to the generated code. These opcodes are also used to generate file and line information for procedural warning/error messages. To enable the debug command tracing us the trace command (trace on) from the vvp interactive prompt. .TP 8 .B fpga This is a synthesis target that supports a variety of fpga devices, mostly by EDIF format output. The Icarus Verilog fpga code generator can generate complete designs or EDIF macros that can in turn be imported into larger designs by other tools. The \fBfpga\fP target implies the synthesis \fB\-S\fP flag. .TP 8 .B vhdl This target produces a VHDL translation of the Verilog netlist. The output is a single file containing VHDL entities corresponding to the modules in the Verilog source code. Note that only a subset of the Verilog language is supported. See the wiki for more information. .SH "WARNING TYPES" These are the types of warnings that can be selected by the \fB\-W\fP switch. All the warning types (other than \fBall\fP) can also be prefixed with \fBno\-\fP to turn off that warning. This is most useful after a \fB\-Wall\fP argument to suppress isolated warning types. .TP 8 .B all This enables the anachronisms, implicit, macro-replacement, portbind, select\-range, timescale, and sensitivity\-entire\-array warning categories. .TP 8 .B anachronisms This enables warnings for use of features that have been deprecated or removed in the selected generation of the Verilog language. .TP 8 .B implicit This enables warnings for creation of implicit declarations. For example, if a scalar wire X is used but not declared in the Verilog source, this will print a warning at its first use. .TP 8 .B macro-redefinition\fI | \fPmacro-replacement This enables preprocessor warnings when a macro is being redefined. The first variant prints a warning any time a macro is redefined. The second variant only prints a warning if the macro text changes. Use \fBno-macro-redefinition\fP to turn off all warnings of this type. .TP 8 .B portbind This enables warnings for ports of module instantiations that are not connected but probably should be. Dangling input ports, for example, will generate a warning. .TP 8 .B select-range This enables warnings for constant out of bound selects. This includes partial or fully out of bound selects as well as a select containing a 'bx or 'bz in the index. .TP 8 .B timescale This enables warnings for inconsistent use of the timescale directive. It detects if some modules have no timescale, or if modules inherit timescale from another file. Both probably mean that timescales are inconsistent, and simulation timing can be confusing and dependent on compilation order. .TP 8 .B infloop This enables warnings for \fRalways\fP statements that may have runtime infinite loops (has paths with no or zero delay). This class of warnings is not included in \fB\-Wall\fP and hence does not have a \fBno\-\fP variant. A fatal error message will always be printed when the compiler can determine that there will definitely be an infinite loop (all paths have no or zero delay). When you suspect an always statement is producing a runtime infinite loop use this flag to find the always statements that need to have their logic verified. It is expected that many of the warnings will be false positives, since the code treats the value of all variables and signals as indeterminate. .TP 8 .B sensitivity-entire-vector This enables warnings for when a part select within an "always @*" statement results in the entire vector being added to the implicit sensitivity list. Although this behaviour is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the vector is large. .TP 8 .B sensitivity-entire-array This enables warnings for when a word select within an "always @*" statement results in the entire array being added to the implicit sensitivity list. Although this behaviour is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the array is large. .SH "VPI MODULES" If the source file name has a \fB.vpi\fP or \fB.vpl\fP suffix, then it is taken to be a VPI module. VPI modules supplied by the user are scanned to determine the return types of any system functions they provide. This is necessary because the compiler needs this information to elaborate expressions that contain these system functions. The module path/name is passed on to the target to allow the VPI module to be automatically loaded at the start of simulation. VPI modules may also be supplied using the \fB-L\fP and \fB-m\fP options. .SH "SYSTEM FUNCTION TABLE FILES [deprecated]" If the source file name has a \fB.sft\fP suffix, then it is taken to be a system function table file. A system function table file is the old method used to describe to the compiler the return types for system functions. Users are encouraged to switch to the new method of simply supplying the VPI module. The format of the table is ASCII, one function per line. Empty lines are ignored, and lines that start with the '\fI#\fP' character are comment lines. Each non-comment line starts with the function name, then the vpi type (i.e. vpiSysFuncReal). The following types are supported: .TP 8 .B vpiSysFuncReal The function returns a real/realtime value. .TP 8 .B vpiSysFuncInt The function returns an integer. .TP 8 .B vpiSysFuncSized The function returns a vector with the given width, and is signed or unsigned according to the flag. .TP 8 .B vpiSysFuncString The function returns a string. This is an Icarus-specific extension, not available in the VPI standard. .SH "COMMAND FILES" The command file allows the user to place source file names and certain command line switches into a text file instead of on a long command line. Command files can include C or C++ style comments, as well as # comments, if the # starts the line. .TP 8 .I "file name" A simple file name or file path is taken to be the name of a Verilog source file. The path starts with the first non-white-space character. Variables are substituted in file names. .TP 8 .B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it does on the command line. The cmdfile may be on the same line or the next non-comment line. .TP 8 .B -l\ \fIfile\fP -v\ \fIfile\fP A \fB\-l\fP token prefixes a library file in the command file, exactly like it does on the command line. The parameter to the \fB\-l\fP flag may be on the same line or the next non-comment line. \fB\-v\fP is an alias for \fB\-l\fP, provided for compatibility with other simulators. Variables in the \fIfile\fP are substituted. .TP 8 .B -y\ \fIlibdir\fP A \fB\-y\fP token prefixes a library directory in the command file, exactly like it does on the command line. The parameter to the \fB\-y\fP flag may be on the same line or the next non-comment line. Variables in the \fIlibdir\fP are substituted. .TP 8 .B +incdir+\fIincludedir\fP The \fB+incdir+\fP token in command files gives directories to search for include files in much the same way that \fB\-I\fP flags work on the command line. The difference is that multiple \fI+includedir\fP directories are valid parameters to a single \fB+incdir+\fP token, although you may also have multiple \fB+incdir+\fP lines. Variables in the \fIincludedir\fP are substituted. .TP 8 .B +libext+\fIext\fP The \fB+libext\fP token in command files lists file extensions to try when looking for a library file. This is useful in conjunction with \fB\-y\fP flags to list suffixes to try in each directory before moving on to the next library directory. .TP 8 .B +libdir+\fIdir\fP This is another way to specify library directories. See the \-y flag. .TP 8 .B +libdir-nocase+\fIdir\fP This is like the \fB+libdir\fP statement, but file names inside the directories declared here are case insensitive. The missing module name in a lookup need not match the file name case, as long as the letters are correct. For example, "foo" matches "Foo.v" but not "bar.v". .TP 8 .B +define+\fINAME\fP=\fIvalue\fP The \fB+define+\fP token is the same as the \fB\-D\fP option on the command line. The value part of the token is optional. .TP 8 .B +parameter+\fINAME\fP=\fIvalue\fP The \fB+parameter+\fP token is the same as the \fB\-P\fP option on the command line. .TP 8 .B +timescale+\fIvalue\fP The \fB+timescale+\fP token is used to set the default timescale for the simulation. This is the time units and precision before any `timescale directive or after a `resetall directive. The default is 1s/1s. .TP 8 .B +toupper-filename This token causes file names after this in the command file to be translated to uppercase. This helps with situations where a directory has passed through a DOS machine, and in the process the file names become munged. .TP 8 .B +tolower-filename This is similar to the \fB+toupper\-filename\fP hack described above. .TP 8 .B +integer-width+\fIvalue\fP This allows the programmer to select the width for integer variables in the Verilog source. The default is 32, the value can be any desired integer value. .TP 8 .B +width-cap+\fIvalue\fP This allows the programmer to select the width cap for unsized expressions. If the calculated width for an unsized expression exceeds this value, the compiler will issue a warning and limit the expression width to this value. .SH "VARIABLES IN COMMAND FILES" In certain cases, iverilog supports variables in command files. These are strings of the form "$(\fIvarname\fP)" or "${\fIvarname\fP}", where \fIvarname\fP is the name of the environment variable to read. The entire string is replaced with the contents of that variable. Variables are only substituted in contexts that explicitly support them, including file and directory strings. Variable values come from the operating system environment, and not from preprocessor defines elsewhere in the file or the command line. .SH PREDEFINED MACROS The following macros are predefined by the compiler: .TP 8 .B __ICARUS__ = 1 This is always defined when compiling with Icarus Verilog. .TP 8 .B __ICARUS_SYNTH__ = 1 This is defined when synthesis is enabled. .TP 8 .B __VAMS_ENABLE__ = 1 This is defined when Verilog\-AMS is enabled. .SH ENVIRONMENT .PP \fIiverilog\fP also accepts some environment variables that control its behavior. These can be used to make semi-permanent changes. .TP 8 .B IVERILOG_ICONFIG=\fIfile-name\fP This sets the name used for the temporary file that passes parameters to the compiler proper, and prevents that file being deleted after the compiler has exited. .TP 8 .B IVERILOG_VPI_MODULE_PATH=\fI/some/path:/some/other/path\fP This adds additional components to the VPI module search path. Paths specified in this way are searched after paths specified with \fB-L\fP, but before the default search path. Multiple paths can be separated with colons (semicolons if using Windows). .SH EXAMPLES These examples assume that you have a Verilog source file called hello.v in the current directory To compile hello.v to an executable file called a.out: iverilog hello.v To compile hello.v to an executable file called hello: iverilog \-o hello hello.v To compile and run explicitly using the vvp runtime: iverilog \-ohello.vvp \-tvvp hello.v .SH "AUTHOR" .nf Steve Williams (steve@icarus.com) .SH SEE ALSO vvp(1), .BR "" Tips on using, debugging, and developing the compiler can be found at .BR "" .SH COPYRIGHT .nf Copyright \(co 2002\-2021 Stephen Williams This document can be freely redistributed according to the terms of the GNU General Public License version 2.0 iverilog-12_0/driver/main.c000066400000000000000000001225221435245347300157360ustar00rootroot00000000000000const char COPYRIGHT[] = "Copyright (c) 2000-2021 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 "version_base.h" # include "version_tag.h" const char NOTICE[] = " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; const char HELP[] = "Usage: iverilog [-EiRSuvV] [-B base] [-c cmdfile|-f cmdfile]\n" " [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g]\n" " [-D macro[=defn]] [-I includedir] [-L moduledir]\n" " [-M [mode=]depfile] [-m module]\n" " [-N file] [-o filename] [-p flag=value]\n" " [-s topmodule] [-t target] [-T min|typ|max]\n" " [-W class] [-y dir] [-Y suf] [-l file] source_file(s)\n" "\n" "See the man page for details."; #define MAXSIZE 4096 #include #include #include #include #include #include #include #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef __MINGW32__ # include # include #ifdef HAVE_LIBIBERTY_H # include #endif #endif #include #ifdef HAVE_GETOPT_H #include #endif #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H) extern int getopt(int argc, char*argv[], const char*fmt); extern int optind; extern const char*optarg; #endif #if !defined(WIFEXITED) # define WIFEXITED(rc) ((rc&0x7f) == 0) #endif #if !defined(WEXITSTATUS) # define WEXITSTATUS(rc) (rc>>8) #endif #ifndef IVL_ROOT # define IVL_ROOT "." #endif # include "globals.h" #include "cfparse_misc.h" /* cfparse() */ #include "ivl_alloc.h" #ifdef __MINGW32__ const char sep = '\\'; const char path_sep = ';'; #else const char sep = '/'; const char path_sep = ':'; #endif extern void cfreset(FILE*fd, const char*path); const char*base = 0; const char*vpi_dir = 0; const char*ivlpp_dir = 0; const char*vhdlpp_dir= 0; const char*vhdlpp_work = 0; const char*mtm = 0; const char*opath = "a.out"; const char*npath = 0; const char*targ = "vvp"; const char*depfile = 0; const char**vhdlpp_libdir = 0; unsigned vhdlpp_libdir_cnt = 0; char depmode = 'a'; const char*generation = "2005"; const char*gen_specify = "no-specify"; const char*gen_assertions = "assertions"; const char*gen_xtypes = "xtypes"; const char*gen_icarus = "icarus-misc"; const char*gen_io_range_error = "io-range-error"; const char*gen_strict_ca_eval = "no-strict-ca-eval"; const char*gen_strict_expr_width = "no-strict-expr-width"; const char*gen_shared_loop_index = "shared-loop-index"; const char*gen_verilog_ams = "no-verilog-ams"; /* Boolean: true means use a default include dir, false means don't */ int gen_std_include = 1; /* Boolean: true means add the local file directory to the start of the include list. */ int gen_relative_include = 0; char warning_flags[17] = "n"; int separate_compilation_flag = 0; /* Boolean: true means ignore errors about missing modules */ int ignore_missing_modules = 0; unsigned integer_width = 32; unsigned width_cap = 65536; char*mod_list = 0; char*command_filename = 0; /* These are used to collect the list of file names that will be passed to ivlpp. Keep the list in a file because it can be a long list. */ char*source_path = 0; FILE*source_file = 0; unsigned source_count = 0; char*defines_path = 0; FILE*defines_file = 0; char*iconfig_path = 0; FILE*iconfig_file = 0; char*compiled_defines_path = 0; static char iconfig_common_path[4096] = ""; static const char**vpi_path_list = 0; static unsigned vpi_path_list_size = 0; static const char**env_vpi_path_list = 0; static unsigned env_vpi_path_list_size = 0; int synth_flag = 0; int verbose_flag = 0; FILE *fp; char line[MAXSIZE]; char tmp[MAXSIZE+24]; static char ivl_root[MAXSIZE]; /* Structure to keep a FIFO list of the command files */ typedef struct t_command_file { char *filename; struct t_command_file *next; } s_command_file, *p_command_file; p_command_file cmd_file_head = NULL; /* The FIFO head */ p_command_file cmd_file_tail = NULL; /* The FIFO tail */ /* Temporarily store parameter definition from command line and * parse it after we have dealt with command file */ static const char** defparm_base = 0; static int defparm_size = 0; /* Function to add a command file name to the FIFO. */ static void add_cmd_file(const char* filename) { p_command_file new; new = (p_command_file) malloc(sizeof(s_command_file)); new->filename = strdup(filename); new->next = NULL; if (cmd_file_head == NULL) { cmd_file_head = new; cmd_file_tail = new; } else { cmd_file_tail->next = new; cmd_file_tail = new; } } /* Function to return the top command file name from the FIFO. */ static char *get_cmd_file(void) { char *filename; if (cmd_file_head == NULL) filename = NULL; else { p_command_file head; filename = cmd_file_head->filename; head = cmd_file_head; cmd_file_head = cmd_file_head->next; free(head); } return filename; } #ifdef __MINGW32__ static FILE*fopen_safe(const char*path) { FILE*file = 0; int fd; fd = _open(path, _O_WRONLY|_O_CREAT|_O_EXCL, 0700); if (fd != -1) file = _fdopen(fd, "w"); return file; } #else static FILE*fopen_safe(const char*path) { FILE*file = 0; int fd; fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0700); if (fd != -1) file = fdopen(fd, "w"); return file; } #endif #ifdef __MINGW32__ /* * The MinGW version of getenv() returns the path with a forward * slash. This should be converted to a back slash to keep every * thing in the code using a back slash. This function wraps the * code for this in one place. The conversion can not be done * directly on the getenv() result since it is const char*. */ static void convert_to_MS_path(char *path) { char *t; for (t = path; *t; t++) { if (*t == '/') *t = '\\'; } } #endif static const char*my_tempfile(const char*str, FILE**fout) { FILE*file; int retry; static char pathbuf[8192]; const char*tmpdir = getenv("TMP"); if (tmpdir == 0) tmpdir = getenv("TMPDIR"); if (tmpdir == 0) tmpdir = getenv("TEMP"); #ifdef __MINGW32__ if (tmpdir == 0) tmpdir = "C:\\TEMP"; #else if (tmpdir == 0) tmpdir = "/tmp"; #endif assert(tmpdir); assert((strlen(tmpdir) + strlen(str)) < sizeof pathbuf - 10); srand(getpid()); retry = 100; file = NULL; while ((retry > 0) && (file == NULL)) { unsigned code = rand(); snprintf(pathbuf, sizeof pathbuf, "%s%c%s%04x", tmpdir, sep, str, code); #ifdef __MINGW32__ convert_to_MS_path(pathbuf); #endif file = fopen_safe(pathbuf); retry -= 1; } *fout = file; return pathbuf; } static int t_version_only(void) { int rc; remove(source_path); free(source_path); fflush(0); snprintf(tmp, sizeof tmp, "%s%civlpp -V", ivlpp_dir, sep); rc = system(tmp); if (rc != 0) { fprintf(stderr, "Unable to get version from \"%s\"\n", tmp); } fflush(0); snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep, iconfig_path, iconfig_common_path); rc = system(tmp); if (rc != 0) { fprintf(stderr, "Unable to get version from \"%s\"\n", tmp); } if ( ! getenv("IVERILOG_ICONFIG")) { remove(iconfig_path); free(iconfig_path); remove(defines_path); free(defines_path); remove(compiled_defines_path); free(compiled_defines_path); } return 0; } static void build_preprocess_command(int e_flag) { snprintf(tmp, sizeof tmp, "%s%civlpp%s%s%s -F\"%s\" -f\"%s\" -p\"%s\"%s", ivlpp_dir, sep, verbose_flag ? " -v" : "", e_flag ? "" : " -L", strchr(warning_flags, 'r') ? " -Wredef-all" : strchr(warning_flags, 'R') ? " -Wredef-chg" : "", defines_path, source_path, compiled_defines_path, e_flag ? "" : " |"); } static int t_preprocess_only(void) { int rc; char*cmd; unsigned ncmd; build_preprocess_command(1); ncmd = strlen(tmp); cmd = malloc(ncmd+1); strcpy(cmd, tmp); if (strcmp(opath,"-") != 0) { snprintf(tmp, sizeof tmp, " > \"%s\"", opath); cmd = realloc(cmd, ncmd+strlen(tmp)+1); strcpy(cmd+ncmd, tmp); } if (verbose_flag) printf("preprocess: %s\n", cmd); rc = system(cmd); remove(source_path); free(source_path); if ( ! getenv("IVERILOG_ICONFIG")) { remove(iconfig_path); free(iconfig_path); remove(defines_path); free(defines_path); remove(compiled_defines_path); free(compiled_defines_path); } if (rc != 0) { if (WIFEXITED(rc)) { fprintf(stderr, "errors preprocessing Verilog program.\n"); free(cmd); return WEXITSTATUS(rc); } fprintf(stderr, "Command signaled: %s\n", cmd); free(cmd); return -1; } free(cmd); return 0; } /* * This is the default target type. It looks up the bits that are * needed to run the command from the configuration file (which is * already parsed for us) so we can handle must of the generic cases. */ static int t_compile(void) { unsigned rc; /* Start by building the preprocess command line, if required. This pipes into the main ivl command. */ if (!separate_compilation_flag) build_preprocess_command(0); else strcpy(tmp, ""); size_t ncmd = strlen(tmp); char*cmd = malloc(ncmd + 1); strcpy(cmd, tmp); #ifndef __MINGW32__ int rtn; #endif /* Build the ivl command. */ snprintf(tmp, sizeof tmp, "%s%civl", base, sep); rc = strlen(tmp); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, tmp); ncmd += rc; if (verbose_flag) { const char*vv = " -v"; rc = strlen(vv); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, vv); ncmd += rc; } if (npath != 0) { snprintf(tmp, sizeof tmp, " -N\"%s\"", npath); rc = strlen(tmp); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, tmp); ncmd += rc; } snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_path); rc = strlen(tmp); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, tmp); ncmd += rc; snprintf(tmp, sizeof tmp, " -C\"%s\"", iconfig_common_path); rc = strlen(tmp); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, tmp); ncmd += rc; if (separate_compilation_flag) snprintf(tmp, sizeof tmp, " -F\"%s\"", source_path); else snprintf(tmp, sizeof tmp, " -- -"); rc = strlen(tmp); cmd = realloc(cmd, ncmd+rc+1); strcpy(cmd+ncmd, tmp); if (verbose_flag) printf("translate: %s\n", cmd); rc = system(cmd); if ( ! getenv("IVERILOG_ICONFIG")) { remove(source_path); free(source_path); remove(iconfig_path); free(iconfig_path); remove(defines_path); free(defines_path); remove(compiled_defines_path); free(compiled_defines_path); } #ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */ free(cmd); return rc; #else rtn = 0; if (rc != 0) { if (rc == 127) { fprintf(stderr, "Failed to execute: %s\n", cmd); rtn = 1; } else if (WIFEXITED(rc)) { rtn = WEXITSTATUS(rc); } else { fprintf(stderr, "Command signaled: %s\n", cmd); rtn = -1; } } free(cmd); return rtn; #endif } static void process_warning_switch(const char*name) { if (strcmp(name,"all") == 0) { process_warning_switch("anachronisms"); process_warning_switch("implicit"); process_warning_switch("implicit-dimensions"); process_warning_switch("macro-replacement"); process_warning_switch("portbind"); process_warning_switch("select-range"); process_warning_switch("timescale"); process_warning_switch("sensitivity-entire-array"); } else if (strcmp(name,"anachronisms") == 0) { if (! strchr(warning_flags, 'n')) strcat(warning_flags, "n"); } else if (strcmp(name,"floating-nets") == 0) { if (! strchr(warning_flags, 'f')) strcat(warning_flags, "f"); } else if (strcmp(name,"implicit") == 0) { if (! strchr(warning_flags, 'i')) strcat(warning_flags, "i"); } else if (strcmp(name,"implicit-dimensions") == 0) { if (! strchr(warning_flags, 'd')) strcat(warning_flags, "d"); } else if (strcmp(name,"macro-redefinition") == 0) { if (! strchr(warning_flags, 'r')) strcat(warning_flags, "r"); } else if (strcmp(name,"macro-replacement") == 0) { if (! strchr(warning_flags, 'R')) strcat(warning_flags, "R"); } else if (strcmp(name,"portbind") == 0) { if (! strchr(warning_flags, 'p')) strcat(warning_flags, "p"); } else if (strcmp(name,"select-range") == 0) { if (! strchr(warning_flags, 's')) strcat(warning_flags, "s"); } else if (strcmp(name,"timescale") == 0) { if (! strchr(warning_flags, 't')) strcat(warning_flags, "t"); /* Since the infinite loop check is not part of 'all' it * does not have a no- version. */ } else if (strcmp(name,"infloop") == 0) { if (! strchr(warning_flags, 'l')) strcat(warning_flags, "l"); } else if (strcmp(name,"sensitivity-entire-vector") == 0) { if (! strchr(warning_flags, 'v')) strcat(warning_flags, "v"); } else if (strcmp(name,"sensitivity-entire-array") == 0) { if (! strchr(warning_flags, 'a')) strcat(warning_flags, "a"); } else if (strcmp(name,"no-anachronisms") == 0) { char*cp = strchr(warning_flags, 'n'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-floating-nets") == 0) { char*cp = strchr(warning_flags, 'f'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-implicit") == 0) { char*cp = strchr(warning_flags, 'i'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-implicit-dimensions") == 0) { char*cp = strchr(warning_flags, 'd'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-macro-redefinition") == 0) { char*cp = strchr(warning_flags, 'r'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } cp = strchr(warning_flags, 'R'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-portbind") == 0) { char*cp = strchr(warning_flags, 'p'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-select-range") == 0) { char*cp = strchr(warning_flags, 's'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-timescale") == 0) { char*cp = strchr(warning_flags, 't'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-sensitivity-entire-vector") == 0) { char*cp = strchr(warning_flags, 'v'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else if (strcmp(name,"no-sensitivity-entire-array") == 0) { char*cp = strchr(warning_flags, 'a'); if (cp) while (*cp) { cp[0] = cp[1]; cp += 1; } } else { fprintf(stderr, "Ignoring unknown warning class " "%s\n", name); } } void process_library_switch(const char *name) { fprintf(iconfig_file, "-y:%s\n", name); } void process_library_nocase_switch(const char *name) { fprintf(iconfig_file, "-yl:%s\n", name); } void process_library2_switch(const char *name) { fprintf(iconfig_file, "-Y:%s\n", name); } void process_include_dir(const char *name) { fprintf(defines_file, "I:%s\n", name); } void process_define(const char*name) { fprintf(defines_file,"D:%s\n", name); } void process_parameter(const char*name) { fprintf(iconfig_file,"defparam:%s\n", name); } void process_timescale(const char*ts_string) { fprintf(iconfig_file, "timescale:%s\n", ts_string); } /* * This function is called while processing a file name in a command * file, or a file name on the command line. Look to see if there is a * .sft or .vpi suffix, and if so pass that as a sys_func or module * file. Otherwise, it is a Verilog source file to be written into the * file list. */ void process_file_name(const char*name, int lib_flag) { if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) { fprintf(stderr, "SFT files are deprecated. Please pass the VPI module instead.\n"); fprintf(iconfig_file,"sys_func:%s\n", name); } else if (strlen(name) > 4 && strcasecmp(".vpi", name+strlen(name)-4) == 0) { fprintf(iconfig_file,"module:%s\n", name); } else { fprintf(source_file, "%s\n", name); source_count += 1; if (lib_flag) fprintf(iconfig_file,"library_file:%s\n", name); } } static int process_generation(const char*name) { if (strcmp(name,"1995") == 0) generation = "1995"; else if (strcmp(name,"2001") == 0) generation = "2001"; else if (strcmp(name,"2001-noconfig") == 0) generation = "2001-noconfig"; else if (strcmp(name,"2005") == 0) generation = "2005"; else if (strcmp(name,"2005-sv") == 0) generation = "2005-sv"; else if (strcmp(name,"2009") == 0) generation = "2009"; else if (strcmp(name,"2012") == 0) generation = "2012"; else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */ generation = "1995"; gen_xtypes = "no-xtypes"; gen_icarus = "no-icarus-misc"; } else if (strcmp(name,"2") == 0) { /* Deprecated: use 2001 */ generation = "2001"; gen_xtypes = "no-xtypes"; gen_icarus = "no-icarus-misc"; } else if (strcmp(name,"2x") == 0) { /* Deprecated: use 2005/xtypes */ generation = "2005"; gen_xtypes = "xtypes"; gen_icarus = "icarus-misc"; } else if (strcmp(name,"xtypes") == 0) gen_xtypes = "xtypes"; else if (strcmp(name,"no-xtypes") == 0) gen_xtypes = "no-xtypes"; else if (strcmp(name,"icarus-misc") == 0) gen_icarus = "icarus-misc"; else if (strcmp(name,"no-icarus-misc") == 0) gen_icarus = "no-icarus-misc"; else if (strcmp(name,"specify") == 0) gen_specify = "specify"; else if (strcmp(name,"no-specify") == 0) gen_specify = "no-specify"; else if (strcmp(name,"assertions") == 0) gen_assertions = "assertions"; else if (strcmp(name,"supported-assertions") == 0) gen_assertions = "supported-assertions"; else if (strcmp(name,"no-assertions") == 0) gen_assertions = "no-assertions"; else if (strcmp(name,"std-include") == 0) gen_std_include = 1; else if (strcmp(name,"no-std-include") == 0) gen_std_include = 0; else if (strcmp(name,"relative-include") == 0) gen_relative_include = 1; else if (strcmp(name,"no-relative-include") == 0) gen_relative_include = 0; else if (strcmp(name,"io-range-error") == 0) gen_io_range_error = "io-range-error"; else if (strcmp(name,"no-io-range-error") == 0) gen_io_range_error = "no-io-range-error"; else if (strcmp(name,"strict-ca-eval") == 0) gen_strict_ca_eval = "strict-ca-eval"; else if (strcmp(name,"no-strict-ca-eval") == 0) gen_strict_ca_eval = "no-strict-ca-eval"; else if (strcmp(name,"strict-expr-width") == 0) gen_strict_expr_width = "strict-expr-width"; else if (strcmp(name,"no-strict-expr-width") == 0) gen_strict_expr_width = "no-strict-expr-width"; else if (strcmp(name,"shared-loop-index") == 0) gen_shared_loop_index = "shared-loop-index"; else if (strcmp(name,"no-shared-loop-index") == 0) gen_shared_loop_index = "no-shared-loop-index"; else if (strcmp(name,"verilog-ams") == 0) gen_verilog_ams = "verilog-ams"; else if (strcmp(name,"no-verilog-ams") == 0) gen_verilog_ams = "no-verilog-ams"; else { fprintf(stderr, "Unknown/Unsupported Language generation " "%s\n\n", name); fprintf(stderr, "Supported generations are:\n"); fprintf(stderr, " 1995 -- IEEE1364-1995\n" " 2001 -- IEEE1364-2001\n" " 2005 -- IEEE1364-2005\n" " 2005-sv -- IEEE1800-2005\n" " 2009 -- IEEE1800-2009\n" " 2012 -- IEEE1800-2012\n" "Other generation flags:\n" " assertions | supported-assertions | no-assertions\n" " specify | no-specify\n" " verilog-ams | no-verilog-ams\n" " std-include | no-std-include\n" " relative-include | no-relative-include\n" " xtypes | no-xtypes\n" " icarus-misc | no-icarus-misc\n" " io-range-error | no-io-range-error\n" " strict-ca-eval | no-strict-ca-eval\n" " strict-expr-width | no-strict-expr-width\n" " shared-loop-index | no-shared-loop-index\n"); return 1; } return 0; } static int process_depfile(const char*name) { const char*cp = strchr(name, '='); if (cp) { int match_length = (int)(cp - name) + 1; if (strncmp(name, "all=", match_length) == 0) { depmode = 'a'; } else if (strncmp(name, "include=", match_length) == 0) { depmode = 'i'; } else if (strncmp(name, "module=", match_length) == 0) { depmode = 'm'; } else if (strncmp(name, "prefix=", match_length) == 0) { depmode = 'p'; } else { fprintf(stderr, "Unknown dependency file mode '%.*s'\n\n", match_length - 1, name); fprintf(stderr, "Supported modes are:\n"); fprintf(stderr, " all\n"); fprintf(stderr, " include\n"); fprintf(stderr, " module\n"); fprintf(stderr, " prefix\n"); return -1; } depfile = cp + 1; } else { depmode = 'a'; depfile = name; } return 0; } static void add_env_vpi_module_path(const char*path) { env_vpi_path_list_size += 1; env_vpi_path_list = (const char**)realloc(env_vpi_path_list, env_vpi_path_list_size*sizeof(char*)); env_vpi_path_list[env_vpi_path_list_size-1] = path; } static void get_env_vpi_module_paths(void) { char *var = getenv("IVERILOG_VPI_MODULE_PATH"); char *ptr, *end; if (!var) return; var = strdup(var); #ifdef __MINGW32__ convert_to_MS_path(var); #endif ptr = var; end = var+strlen(var); int len = 0; while (ptr <= end) { if (*ptr == 0 || *ptr == path_sep) { *ptr = 0; if (len > 0) { add_env_vpi_module_path(var); } len = 0; var = ptr+1; } else { len++; } ptr++; } } static void add_vpi_module_path(const char*path) { #ifdef __MINGW32__ char*tmp_path = strdup(path); convert_to_MS_path(tmp_path); path = tmp_path; #endif vpi_path_list_size += 1; vpi_path_list = (const char**)realloc(vpi_path_list, vpi_path_list_size*sizeof(char*)); vpi_path_list[vpi_path_list_size-1] = path; } static int probe_for_vpi_module(const char*base_path, const char*name, char*path, unsigned path_size) { snprintf(path, path_size, "%s%c%s.vpi", base_path, sep, name); if (access(path, R_OK) == 0) return 1; snprintf(path, path_size, "%s%c%s.vpl", base_path, sep, name); if (access(path, R_OK) == 0) return 1; return 0; } /* * If it exists add the VPI file for the given module. */ static void add_vpi_file(const char *name) { const char*base_dir = vpi_dir ? vpi_dir : base; char path[4096]; #ifdef __MINGW32__ char*tmp_name = strdup(name); convert_to_MS_path(tmp_name); name = tmp_name; #endif int found = 0; if (strchr(name, sep)) { /* If the name has at least one directory character in it then assume it is a complete name, maybe including any possible .vpi or .vpl suffix. */ found = access(name, R_OK) == 0; if (!found) { snprintf(path, sizeof(path), "%s.vpi", name); found = access(path, R_OK) == 0; if (!found) { snprintf(path, sizeof(path), "%s.vpl", name); found = access(path, R_OK) == 0; } } else { strncpy(path, name, sizeof(path) - 1); } } else { for (unsigned idx = 0; !found && (idx < vpi_path_list_size); idx += 1) { found = probe_for_vpi_module(vpi_path_list[idx], name, path, sizeof(path)); } for (unsigned idx = 0; !found && (idx < env_vpi_path_list_size); idx += 1) { found = probe_for_vpi_module(env_vpi_path_list[idx], name, path, sizeof(path)); } if (!found) { found = probe_for_vpi_module(base_dir, name, path, sizeof(path)); } } if (found) { fprintf(iconfig_file, "module:%s\n", path); } else { fprintf(stderr, "Unable to find VPI module '%s'\n", name); } #ifdef __MINGW32__ free(tmp_name); #endif } static void find_ivl_root_failed(const char *reason) { fprintf(stderr, "Cannot locate IVL modules : %s\n", reason); exit(1); } static void find_ivl_root(void) { #ifdef __MINGW32__ const char *ivl_lib_prefix = "\\lib"; const char *ivl_lib_suffix = "\\ivl" IVL_SUFFIX; #else const char *ivl_lib_prefix = IVL_LIB; const char *ivl_lib_suffix = "/ivl" IVL_SUFFIX; #endif ssize_t len = 0; char *s; #ifndef __MINGW32__ /* First try the location specified in the build process. */ if (access(IVL_ROOT, F_OK) != -1) { assert(strlen(IVL_ROOT) < sizeof ivl_root); strcpy(ivl_root, IVL_ROOT); return; } #endif /* If that fails, calculate the ivl_root from the path to the command. This is always necessary on Windows because of the installation process, but may also be necessary on other OSs if the package has been relocated. On Windows we know the command path is formed like this: $(prefix)\bin\iverilog.exe The module path in a Windows installation is the path: $(prefix)\lib\ivl$(suffix) so we chop the file name and the last directory by turning the last two \ characters to null. Then we append the lib\ivl$(suffix) to finish. On other OSs, we expect the command path to be: $(prefix)/bin/iverilog and the module path to be: $(prefix)/$(lib)/ivl$(suffix) so we extract the $(prefix) from the command location as for Windows and the $(lib) from IVL_LIB. This will of course fail if the user has overridden $(bindir) or $(libdir), but there's not a lot we can do in that case. */ #if defined(__MINGW32__) char tmppath[MAXSIZE]; len = GetModuleFileName(NULL, tmppath, sizeof tmppath); if (len >= (ssize_t) sizeof ivl_root) { find_ivl_root_failed("command path exceeds size of string buffer."); } /* Convert to a short name to remove any embedded spaces. */ len = GetShortPathName(tmppath, ivl_root, sizeof ivl_root); #elif defined(__APPLE__) uint32_t size = sizeof ivl_root; len = _NSGetExecutablePath(ivl_root, &size) + 1; #else len = readlink("/proc/self/exe", ivl_root, sizeof ivl_root); #endif if (len >= (ssize_t) sizeof ivl_root) { find_ivl_root_failed("command path exceeds size of string buffer."); } if (len <= 0) { // We've failed, but we may yet find a -B option on the command line. // Use the built-in path so the user sees a sensible error message. assert(strlen(IVL_ROOT) < sizeof ivl_root); strcpy(ivl_root, IVL_ROOT); return; } s = strrchr(ivl_root, sep); if (s == 0) { find_ivl_root_failed("missing first separator in command path."); } *s = 0; s = strrchr(ivl_root, sep); if (s == 0) { find_ivl_root_failed("missing second separator in command path."); } *s = 0; len = s - ivl_root; s = strrchr(ivl_lib_prefix, sep); assert(s); if (len + strlen(s) + strlen(ivl_lib_suffix) >= (ssize_t) sizeof ivl_root) { find_ivl_root_failed("module path exceeds size of string buffer."); } strcat(ivl_root, s); strcat(ivl_root, ivl_lib_suffix); } static void print_runtime_paths(void) { printf("includedir: %s\n", IVL_INCLUDE_INSTALL_DIR); } int main(int argc, char **argv) { int e_flag = 0; int version_flag = 0; int opt; find_ivl_root(); base = ivl_root; get_env_vpi_module_paths(); /* Create a temporary file for communicating input parameters to the preprocessor. */ source_path = strdup(my_tempfile("ivrlg", &source_file)); if (NULL == source_file) { fprintf(stderr, "%s: Error opening temporary file %s\n", argv[0], source_path); fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]); return 1; } defines_path = strdup(my_tempfile("ivrlg2", &defines_file)); if (NULL == defines_file) { fprintf(stderr, "%s: Error opening temporary file %s\n", argv[0], defines_path); fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]); fclose(source_file); remove(source_path); return 1; } fprintf(defines_file, "D:__ICARUS__=1\n"); /* Create another temporary file for passing configuration information to ivl. */ if ( (iconfig_path = getenv("IVERILOG_ICONFIG")) ) { fprintf(stderr, "%s: IVERILOG_ICONFIG=%s\n", argv[0], iconfig_path); iconfig_file = fopen(iconfig_path, "w"); } else { iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file)); } if (NULL == iconfig_file) { fprintf(stderr, "%s: Error opening temporary file %s\n", argv[0], iconfig_path); fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]); fclose(source_file); remove(source_path); fclose(defines_file); remove(defines_path); return 1; } /* Create a temporary file (I only really need the path) that can carry preprocessor precompiled defines to the library. */ { FILE*tmp_file = 0; compiled_defines_path = strdup(my_tempfile("ivrli", &tmp_file)); if (tmp_file) { fclose(tmp_file); } } while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:iL:M:m:N:o:P:p:RSs:T:t:uvVW:y:Y:")) != EOF) { switch (opt) { case 'B': /* The individual components can be located by a single base, or by individual bases. The first character of the path indicates which path the user is specifying. */ switch (optarg[0]) { case 'M': /* Path for the VPI modules */ vpi_dir = optarg+1; break; case 'P': /* Path for the ivlpp preprocessor */ ivlpp_dir = optarg+1; break; case 'V': /* Path for the vhdlpp VHDL processor */ vhdlpp_dir = optarg+1; break; default: /* Otherwise, this is a default base. */ base=optarg; break; } break; case 'c': case 'f': add_cmd_file(optarg); break; case 'D': process_define(optarg); break; case 'E': e_flag = 1; break; case 'P': defparm_size += 1; defparm_base = (const char**)realloc(defparm_base, defparm_size*sizeof(char*)); defparm_base[defparm_size-1] = optarg; break; case 'p': fprintf(iconfig_file, "flag:%s\n", optarg); break; case 'd': fprintf(iconfig_file, "debug:%s\n", optarg); break; case 'g': if (process_generation(optarg) != 0) return -1; break; case 'h': fprintf(stderr, "%s\n", HELP); return 1; case 'I': process_include_dir(optarg); break; case 'i': ignore_missing_modules = 1; break; case 'L': add_vpi_module_path(optarg); break; case 'l': process_file_name(optarg, 1); break; case 'M': if (process_depfile(optarg) != 0) return -1; break; case 'm': add_vpi_file(optarg); break; case 'N': npath = optarg; break; case 'o': opath = optarg; break; case 'R': print_runtime_paths(); return 0; case 'S': synth_flag = 1; break; case 's': fprintf(iconfig_file, "root:%s\n", optarg); break; case 'T': if (strcmp(optarg,"min") == 0) { mtm = "min"; } else if (strcmp(optarg,"typ") == 0) { mtm = "typ"; } else if (strcmp(optarg,"max") == 0) { mtm = "max"; } else { fprintf(stderr, "%s: invalid -T%s argument\n", argv[0], optarg); return 1; } break; case 't': targ = optarg; break; case 'u': separate_compilation_flag = 1; break; case 'v': verbose_flag = 1; break; case 'V': version_flag = 1; break; case 'W': process_warning_switch(optarg); break; case 'y': process_library_switch(optarg); break; case 'Y': process_library2_switch(optarg); break; case '?': default: fclose(source_file); remove(source_path); free(source_path); fclose(defines_file); remove(defines_path); free(defines_path); fclose(iconfig_file); remove(iconfig_path); free(iconfig_path); remove(compiled_defines_path); free(compiled_defines_path); while( (command_filename = get_cmd_file()) ) { free(command_filename); } return 1; } } if (strcmp(gen_verilog_ams,"verilog-ams") == 0) fprintf(defines_file, "D:__VAMS_ENABLE__=1\n"); if (synth_flag) fprintf(defines_file, "D:__ICARUS_SYNTH__=1\n"); if (vpi_dir == 0) vpi_dir = base; if (ivlpp_dir == 0) ivlpp_dir = base; if (vhdlpp_dir == 0) vhdlpp_dir = base; if (version_flag || verbose_flag) { printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n"); printf("%s\n\n", COPYRIGHT); puts(NOTICE); } /* Make a common conf file path to reflect the target. */ snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf", base, sep, targ, synth_flag? "-s" : ""); /* Write values to the iconfig file. */ fprintf(iconfig_file, "basedir:%s\n", base); /* Tell the core where to find the system VPI modules. */ fprintf(iconfig_file, "module:%s%csystem.vpi\n", vpi_dir, sep); fprintf(iconfig_file, "module:%s%cvhdl_sys.vpi\n", vpi_dir, sep); fprintf(iconfig_file, "module:%s%cvhdl_textio.vpi\n", vpi_dir, sep); /* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams, * then include the v2005_math library. */ if (strcmp(generation, "2005") == 0 || strcmp(generation, "2009") == 0 || strcmp(generation, "2012") == 0 || strcmp(gen_icarus, "icarus-misc") == 0 || strcmp(gen_verilog_ams, "verilog-ams") == 0) { fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep); } /* If verilog-ams or icarus_misc is enabled, then include the * va_math module as well. */ if (strcmp(gen_verilog_ams,"verilog-ams") == 0 || strcmp(gen_icarus, "icarus-misc") == 0) { fprintf(iconfig_file, "module:%s%cva_math.vpi\n", vpi_dir, sep); } /* If verilog-2009 (SystemVerilog) is enabled, then include the v2009 module. */ if (strcmp(generation, "2005-sv") == 0 || strcmp(generation, "2009") == 0 || strcmp(generation, "2012") == 0) { fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep); } if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm); fprintf(iconfig_file, "generation:%s\n", generation); fprintf(iconfig_file, "generation:%s\n", gen_specify); fprintf(iconfig_file, "generation:%s\n", gen_assertions); fprintf(iconfig_file, "generation:%s\n", gen_xtypes); fprintf(iconfig_file, "generation:%s\n", gen_io_range_error); fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval); fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width); fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index); fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams); fprintf(iconfig_file, "generation:%s\n", gen_icarus); fprintf(iconfig_file, "warnings:%s\n", warning_flags); fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false"); fprintf(iconfig_file, "out:%s\n", opath); if (depfile) { fprintf(iconfig_file, "depfile:%s\n", depfile); fprintf(iconfig_file, "depmode:%c\n", depmode); } while ( (command_filename = get_cmd_file()) ) { int rc; if (( fp = fopen(command_filename, "r")) == NULL ) { fprintf(stderr, "%s: cannot open command file %s " "for reading.\n", argv[0], command_filename); return 1; } cfreset(fp, command_filename); rc = cfparse(); if (rc != 0 || command_file_errors > 0) { fprintf(stderr, "%s: parsing failed in base command " "file %s.\n", argv[0], command_filename); return 1; } free(command_filename); fclose(fp); } destroy_lexor(); if (depfile) { fprintf(defines_file, "M%c:%s\n", depmode, depfile); } if (vhdlpp_work == 0) vhdlpp_work = "ivl_vhdl_work"; fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep); fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work); for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1) fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]); /* Process parameter definition from command line. The last defined would override previous ones. */ int pitr; for (pitr = 0; pitr < defparm_size; pitr++) process_parameter(defparm_base[pitr]); free(defparm_base); defparm_base = 0; defparm_size = 0; /* Finally, process all the remaining words on the command line as file names. */ for (int idx = optind ; idx < argc ; idx += 1) process_file_name(argv[idx], 0); /* If the use of a default include directory is not specifically disabled, then write that directory as the very last include directory to use... always. */ if (gen_std_include) { fprintf(defines_file, "I:%s%cinclude\n", base, sep); } if (gen_relative_include) { fprintf(defines_file, "relative include:true\n"); } else { fprintf(defines_file, "relative include:false\n"); } fclose(source_file); source_file = 0; fclose(defines_file); defines_file = 0; /* If we are planning on opening a dependencies file, then open and truncate it here. The other phases of compilation will append to the file, so this is necessary to make sure it starts out empty. */ if (depfile) { FILE *fd = fopen(depfile, "w"); if (!fd) { fprintf(stderr, "%s: can't open %s file.\n\n%s\n", argv[0], depfile, HELP); return 1; } fclose(fd); } if (source_count == 0 && !version_flag) { fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP); return 1; } fprintf(iconfig_file, "iwidth:%u\n", integer_width); fprintf(iconfig_file, "widthcap:%u\n", width_cap); /* Write the preprocessor command needed to preprocess a single file. This may be used to preprocess library files. */ fprintf(iconfig_file, "ivlpp:%s%civlpp %s -L -F\"%s\" -P\"%s\"\n", ivlpp_dir, sep, strchr(warning_flags, 'r') ? "-Wredef-all" : strchr(warning_flags, 'R') ? "-Wredef-chg" : "", defines_path, compiled_defines_path ); /* Done writing to the iconfig file. Close it now. */ fclose(iconfig_file); /* If we're only here for the version output, then we're done. */ if (version_flag) return t_version_only(); /* If the -E flag was given on the command line, then all we do is run the preprocessor and put the output where the user wants it. */ if (e_flag) return t_preprocess_only(); /* Otherwise, this is a full compile. */ return t_compile(); } iverilog-12_0/driver/substit.c000066400000000000000000000047741435245347300165170ustar00rootroot00000000000000/* * Copyright (c) 2002-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 # include # include # include "ivl_alloc.h" # include "globals.h" char* substitutions(const char*str) { size_t nbuf = strlen(str) + 1; char*buf = malloc(nbuf); char*cp = buf; while (*str) { if ((str[0] == '$') && ((str[1] == '(') || str[1] == '{')) { /* If I find a $(x) or ${x} string in the source, replace it in the destination with the contents of the environment variable x. */ char*name; char*value; const char*ep = strchr(str, (str[1]=='(') ? ')' : '}'); str += 2; name = malloc(ep-str+1); strncpy(name, str, ep-str); name[ep-str] = 0; str = ep + 1; value = getenv(name); if (value == 0) { fprintf(stderr, "Warning: environment variable " "\"%s\" not found during command file " "processing.\n", name); free(name); continue; } free(name); if (strlen(value) >= (nbuf - (cp-buf))) { size_t old_size = cp - buf; nbuf = (cp - buf) + strlen(value) + 1; buf = realloc(buf, nbuf); cp = buf + old_size; } strcpy(cp, value); cp += strlen(cp); } else { if ( cp == (buf + nbuf) ) { size_t old_size = nbuf; nbuf = old_size + 32; buf = realloc(buf, nbuf); cp = buf + old_size; } *cp++ = *str++; } } /* Add the trailing nul to the string, and reallocate the buffer to be a tight fit. */ if ( cp == (buf + nbuf) ) { size_t old_size = nbuf; nbuf = old_size + 1; buf = realloc(buf, nbuf); buf[old_size] = 0; } else { *cp++ = 0; nbuf = cp - buf; buf = realloc(buf, nbuf); } return buf; } iverilog-12_0/dup_expr.cc000066400000000000000000000201351435245347300155050ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "netlist.h" # include # include # include "ivl_assert.h" using namespace std; NetEAccess* NetEAccess::dup_expr() const { NetEAccess*tmp = new NetEAccess(branch_, nature_); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEArrayPattern*NetEArrayPattern::dup_expr() const { vectortmp (items_.size()); for (size_t idx = 0 ; idx < tmp.size() ; idx += 1) tmp[idx] = items_[idx]->dup_expr(); NetEArrayPattern*res = new NetEArrayPattern(net_type(), tmp); res->set_line(*this); return res; } NetEBinary* NetEBinary::dup_expr() const { ivl_assert(*this, 0); return 0; } NetEBAdd* NetEBAdd::dup_expr() const { NetEBAdd*tmp = new NetEBAdd(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBBits* NetEBBits::dup_expr() const { NetEBBits*tmp = new NetEBBits(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBComp* NetEBComp::dup_expr() const { NetEBComp*tmp = new NetEBComp(op_, left_->dup_expr(), right_->dup_expr()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBDiv* NetEBDiv::dup_expr() const { NetEBDiv*tmp = new NetEBDiv(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBLogic* NetEBLogic::dup_expr() const { NetEBLogic*tmp = new NetEBLogic(op_, left_->dup_expr(), right_->dup_expr()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBMult* NetEBMult::dup_expr() const { NetEBMult*tmp = new NetEBMult(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBPow* NetEBPow::dup_expr() const { NetEBPow*tmp = new NetEBPow(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEBShift* NetEBShift::dup_expr() const { NetEBShift*tmp = new NetEBShift(op_, left_->dup_expr(), right_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEConcat* NetEConcat::dup_expr() const { NetEConcat*dup = new NetEConcat(parms_.size(), repeat_, expr_type_); ivl_assert(*this, dup); dup->set_line(*this); for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) if (parms_[idx]) { NetExpr*tmp = parms_[idx]->dup_expr(); ivl_assert(*this, tmp); dup->parms_[idx] = tmp; } dup->expr_width(expr_width()); return dup; } NetEConst* NetEConst::dup_expr() const { NetEConst*tmp = new NetEConst(value_); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEConstEnum* NetEConstEnum::dup_expr() const { NetEConstEnum*tmp = new NetEConstEnum(name_, enum_set_, value()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEConstParam* NetEConstParam::dup_expr() const { NetEConstParam*tmp = new NetEConstParam(scope_, name_, value()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetECReal* NetECReal::dup_expr() const { NetECReal*tmp = new NetECReal(value_); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetECRealParam* NetECRealParam::dup_expr() const { NetECRealParam*tmp = new NetECRealParam(scope_, name_, value()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEEvent* NetEEvent::dup_expr() const { ivl_assert(*this, 0); return 0; } NetELast* NetELast::dup_expr() const { NetELast*tmp = new NetELast(sig_); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetENetenum* NetENetenum::dup_expr() const { ivl_assert(*this, 0); return 0; } NetENew* NetENew::dup_expr() const { ivl_assert(*this, 0); return 0; } NetENull* NetENull::dup_expr() const { ivl_assert(*this, 0); return 0; } NetEProperty* NetEProperty::dup_expr() const { ivl_assert(*this, 0); return 0; } NetEScope* NetEScope::dup_expr() const { ivl_assert(*this, 0); return 0; } NetESelect* NetESelect::dup_expr() const { NetESelect*tmp = new NetESelect(expr_->dup_expr(), base_? base_->dup_expr() : 0, expr_width(), sel_type_); ivl_assert(*this, tmp); tmp->cast_signed(has_sign()); tmp->set_line(*this); return tmp; } NetESFunc* NetESFunc::dup_expr() const { NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_); ivl_assert(*this, tmp); tmp->cast_signed(has_sign()); for (unsigned idx = 0 ; idx < nparms() ; idx += 1) { ivl_assert(*this, parm(idx)); tmp->parm(idx, parm(idx)->dup_expr()); } tmp->set_line(*this); return tmp; } NetEShallowCopy* NetEShallowCopy::dup_expr() const { ivl_assert(*this, 0); return 0; } NetESignal* NetESignal::dup_expr() const { NetESignal*tmp = new NetESignal(net_, word_); ivl_assert(*this, tmp); tmp->expr_width(expr_width()); tmp->cast_signed(has_sign()); tmp->set_line(*this); return tmp; } NetETernary* NetETernary::dup_expr() const { NetETernary*tmp = new NetETernary(cond_->dup_expr(), true_val_->dup_expr(), false_val_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEUFunc* NetEUFunc::dup_expr() const { NetEUFunc*tmp; vector tmp_parms (parms_.size()); for (unsigned idx = 0 ; idx < tmp_parms.size() ; idx += 1) { ivl_assert(*this, parms_[idx]); tmp_parms[idx] = parms_[idx]->dup_expr(); } tmp = new NetEUFunc(scope_, func_, result_sig_->dup_expr(), tmp_parms, need_const_); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEUBits* NetEUBits::dup_expr() const { NetEUBits*tmp = new NetEUBits(op_, expr_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEUnary* NetEUnary::dup_expr() const { NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetEUReduce* NetEUReduce::dup_expr() const { NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } NetECast* NetECast::dup_expr() const { NetECast*tmp = new NetECast(op_, expr_->dup_expr(), expr_width(), has_sign()); ivl_assert(*this, tmp); tmp->set_line(*this); return tmp; } iverilog-12_0/elab_expr.cc000066400000000000000000007367261435245347300156440ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 # include # include # include # include "compiler.h" # include "PPackage.h" # include "pform.h" # include "netlist.h" # include "netclass.h" # include "netenum.h" # include "netparray.h" # include "netvector.h" # include "discipline.h" # include "netmisc.h" # include "netdarray.h" # include "netqueue.h" # include "netstruct.h" # include "netscalar.h" # include "util.h" # include "ivl_assert.h" using namespace std; bool type_is_vectorable(ivl_variable_type_t type) { switch (type) { case IVL_VT_BOOL: case IVL_VT_LOGIC: return true; default: return false; } } static ivl_nature_t find_access_function(const pform_name_t&path) { if (path.size() != 1) return 0; else return access_function_nature[peek_tail_name(path)]; } /* * Look at the signal to see if there is already a branch that * connects the sig to the gnd. If there is, then return it. If not, * return 0. */ static NetBranch* find_existing_implicit_branch(NetNet*sig, NetNet*gnd) { Nexus*nex = sig->pin(0).nexus(); for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur->is_equal(sig->pin(0))) continue; if (cur->get_pin() != 0) continue; NetBranch*tmp = dynamic_cast (cur->get_obj()); if (tmp == 0) continue; if (tmp->name()) continue; if (tmp->pin(1).is_linked(gnd->pin(0))) return tmp; } return 0; } NetExpr* elaborate_rval_expr(Design *des, NetScope *scope, ivl_type_t lv_net_type, PExpr *expr, bool need_const, bool force_unsigned) { return elaborate_rval_expr(des, scope, lv_net_type, lv_net_type->base_type(), lv_net_type->packed_width(), expr, need_const, force_unsigned); } NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type, ivl_variable_type_t lv_type, unsigned lv_width, PExpr*expr, bool need_const, bool force_unsigned) { if (debug_elaborate) { cerr << expr->get_fileline() << ": elaborate_rval_expr: " << "expr=" << *expr; if (lv_net_type) cerr << ", lv_net_type=" << *lv_net_type; else cerr << ", lv_net_type="; cerr << ", lv_type=" << lv_type << ", lv_width=" << lv_width << endl; } int context_wid = -1; switch (lv_type) { case IVL_VT_DARRAY: case IVL_VT_QUEUE: case IVL_VT_CLASS: // For these types, use a different elab_and_eval that // uses the lv_net_type. We should eventually transition // all the types to this new form. if (lv_net_type) return elab_and_eval(des, scope, expr, lv_net_type, need_const); break; case IVL_VT_REAL: case IVL_VT_STRING: break; case IVL_VT_BOOL: case IVL_VT_LOGIC: context_wid = lv_width; break; case IVL_VT_VOID: case IVL_VT_NO_TYPE: ivl_assert(*expr, 0); break; } return elab_and_eval(des, scope, expr, context_wid, need_const, false, lv_type, force_unsigned); } /* * If the mode is UPSIZE, make sure the final expression width is at * least integer_width, but return the calculated lossless width to * the caller. */ unsigned PExpr::fix_width_(width_mode_t mode) { unsigned width = expr_width_; if ((mode == UPSIZE) && type_is_vectorable(expr_type_) && (width < integer_width)) expr_width_ = integer_width; return width; } unsigned PExpr::test_width(Design*des, NetScope*, width_mode_t&) { cerr << get_fileline() << ": internal error: I do not know how to" << " test the width of this expression. " << endl; cerr << get_fileline() << ": : Expression is: " << *this << endl; des->errors += 1; return 1; } NetExpr* PExpr::elaborate_expr(Design*des, NetScope*scope, ivl_type_t, unsigned flags) const { // Fall back to the old method. Currently the new method won't be used // if the target is a vector type, so we can use an arbitrary width. return elaborate_expr(des, scope, 1, flags); } NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const { cerr << get_fileline() << ": internal error: I do not know how to" << " elaborate this expression. " << endl; cerr << get_fileline() << ": : Expression is: " << *this << endl; cerr << get_fileline() << ": : Expression type: " << typeid(*this).name() << endl; des->errors += 1; return 0; } /* * For now, assume that assignment patterns are for dynamic * objects. This is not really true as this expression type, fully * supported, can assign to packed arrays and structs, unpacked arrays * and dynamic arrays. */ unsigned PEAssignPattern::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_DARRAY; expr_width_ = 1; min_width_ = 1; signed_flag_= false; return 1; } NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { // Special case: If this is an empty pattern (i.e. '{}) and // the expected type is a DARRAY or QUEUE, then convert this // to a null handle. Internally, Icarus Verilog uses this to // represent nil dynamic arrays. if (parms_.size() == 0 && (ntype->base_type()==IVL_VT_DARRAY || ntype->base_type()==IVL_VT_QUEUE)) { NetENull*tmp = new NetENull; tmp->set_line(*this); return tmp; } if (ntype->base_type()==IVL_VT_DARRAY || ntype->base_type()==IVL_VT_QUEUE) return elaborate_expr_darray_(des, scope, ntype, flags); cerr << get_fileline() << ": sorry: I don't know how to elaborate " << "assignment_pattern expressions yet." << endl; cerr << get_fileline() << ": : Expression is: " << *this << endl; des->errors += 1; return 0; } NetExpr*PEAssignPattern::elaborate_expr_darray_(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { const netdarray_t*array_type = dynamic_cast (ntype); ivl_assert(*this, array_type); bool need_const = NEED_CONST & flags; // This is an array pattern, so run through the elements of // the expression and elaborate each as if they are // element_type expressions. ivl_type_t elem_type = array_type->element_type(); vector elem_exprs (parms_.size()); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { NetExpr*tmp = elaborate_rval_expr(des, scope, elem_type, parms_[idx], need_const); elem_exprs[idx] = tmp; } NetEArrayPattern*res = new NetEArrayPattern(array_type, elem_exprs); res->set_line(*this); return res; } NetExpr* PEAssignPattern::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const { cerr << get_fileline() << ": sorry: I do not know how to" << " elaborate assignment patterns using old method." << endl; cerr << get_fileline() << ": : Expression is: " << *this << endl; des->errors += 1; ivl_assert(*this, 0); return 0; } unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode) { ivl_assert(*this, left_); ivl_assert(*this, right_); unsigned r_width = right_->test_width(des, scope, mode); width_mode_t saved_mode = mode; unsigned l_width = left_->test_width(des, scope, mode); if (debug_elaborate) { cerr << get_fileline() << ": PEBinary::test_width: " << "op_=" << op_ << ", l_width=" << l_width << ", r_width=" << r_width << ", saved_mode=" << saved_mode << endl; } // If the width mode changed, retest the right operand, as it // may choose a different width if it is in a lossless context. if ((mode >= LOSSLESS) && (saved_mode < LOSSLESS)) r_width = right_->test_width(des, scope, mode); ivl_variable_type_t l_type = left_->expr_type(); ivl_variable_type_t r_type = right_->expr_type(); if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) { cerr << get_fileline() << ": error: " << "Class/null is not allowed with the '" << human_readable_op(op_) << "' operator." << endl; des->errors += 1; } if (l_type == IVL_VT_REAL || r_type == IVL_VT_REAL) expr_type_ = IVL_VT_REAL; else if (l_type == IVL_VT_LOGIC || r_type == IVL_VT_LOGIC) expr_type_ = IVL_VT_LOGIC; else expr_type_ = IVL_VT_BOOL; if (expr_type_ == IVL_VT_REAL) { expr_width_ = 1; min_width_ = 1; signed_flag_ = true; } else { expr_width_ = max(l_width, r_width); min_width_ = max(left_->min_width(), right_->min_width()); signed_flag_ = left_->has_sign() && right_->has_sign(); // If the operands are different types, the expression is // forced to unsigned. In this case the lossless width // calculation is unreliable and we need to make sure the // final expression width is at least integer_width. if ((mode == LOSSLESS) && (left_->has_sign() != right_->has_sign())) mode = UPSIZE; switch (op_) { case '+': case '-': if (mode >= EXPAND) expr_width_ += 1; break; case '*': if (mode >= EXPAND) expr_width_ = l_width + r_width; break; case '%': case '/': min_width_ = UINT_MAX; // disable width pruning break; case 'l': // << Should be handled by PEBLeftWidth case 'r': // >> Should be handled by PEBLeftWidth case 'R': // >>> Should be handled by PEBLeftWidth case '<': // < Should be handled by PEBComp case '>': // > Should be handled by PEBComp case 'e': // == Should be handled by PEBComp case 'E': // === Should be handled by PEBComp case 'w': // ==? Should be handled by PEBComp case 'L': // <= Should be handled by PEBComp case 'G': // >= Should be handled by PEBComp case 'n': // != Should be handled by PEBComp case 'N': // !== Should be handled by PEBComp case 'W': // !=? Should be handled by PEBComp case 'p': // ** should be handled by PEBLeftWidth ivl_assert(*this, 0); default: break; } } return fix_width_(mode); } /* * Elaborate binary expressions. This involves elaborating the left * and right sides, and creating one of a variety of different NetExpr * types. */ NetExpr* PEBinary::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_assert(*this, left_); ivl_assert(*this, right_); // Handle the special case that one of the operands is a real // value and the other is a vector type. In that case, // elaborate the vectorable argument as self-determined. // Propagate the expression type (signed/unsigned) down to // any context-determined operands. unsigned l_width = expr_wid; unsigned r_width = expr_wid; if (left_->expr_type()==IVL_VT_REAL && type_is_vectorable(right_->expr_type())) { r_width = right_->expr_width(); } else { right_->cast_signed(signed_flag_); } if (right_->expr_type()==IVL_VT_REAL && type_is_vectorable(left_->expr_type())) { l_width = left_->expr_width(); } else { left_->cast_signed(signed_flag_); } NetExpr*lp = left_->elaborate_expr(des, scope, l_width, flags); NetExpr*rp = right_->elaborate_expr(des, scope, r_width, flags); if ((lp == 0) || (rp == 0)) { delete lp; delete rp; return 0; } return elaborate_expr_base_(des, lp, rp, expr_wid); } /* * This is the common elaboration of the operator. It presumes that the * operands are elaborated as necessary, and all I need to do is make * the correct NetEBinary object and connect the parameters. */ NetExpr* PEBinary::elaborate_expr_base_(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { if (debug_elaborate) { cerr << get_fileline() << ": debug: elaborate expression " << *this << " expr_width=" << expr_wid << endl; } NetExpr*tmp; switch (op_) { default: tmp = new NetEBinary(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); break; case 'a': case 'o': case 'q': case 'Q': cerr << get_fileline() << ": internal error: " << "Elaboration of " << human_readable_op(op_) << " Should have been handled in NetEBLogic::elaborate." << endl; des->errors += 1; return 0; case 'p': cerr << get_fileline() << ": internal error: " << "Elaboration of " << human_readable_op(op_) << " Should have been handled in NetEBPower::elaborate." << endl; des->errors += 1; return 0; case '*': tmp = elaborate_expr_base_mult_(des, lp, rp, expr_wid); break; case '%': case '/': tmp = elaborate_expr_base_div_(des, lp, rp, expr_wid); break; case 'l': case 'r': case 'R': cerr << get_fileline() << ": internal error: " << "Elaboration of " << human_readable_op(op_) << " Should have been handled in NetEBShift::elaborate." << endl; des->errors += 1; return 0; case '^': case '&': case '|': case 'O': // NOR (~|) case 'A': // NAND (~&) case 'X': tmp = elaborate_expr_base_bits_(des, lp, rp, expr_wid); break; case '+': case '-': tmp = new NetEBAdd(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); break; case 'E': /* === */ case 'N': /* !== */ case 'e': /* == */ case 'n': /* != */ case 'L': /* <= */ case 'G': /* >= */ case '<': case '>': cerr << get_fileline() << ": internal error: " << "Elaboration of " << human_readable_op(op_) << " Should have been handled in NetEBComp::elaborate." << endl; des->errors += 1; return 0; case 'm': // min(l,r) case 'M': // max(l,r) tmp = new NetEBMinMax(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); break; } return tmp; } NetExpr* PEBinary::elaborate_expr_base_bits_(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: " << human_readable_op(op_) << " operator may not have REAL operands." << endl; des->errors += 1; return 0; } NetEBBits*tmp = new NetEBBits(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } NetExpr* PEBinary::elaborate_expr_base_div_(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { /* The % operator does not support real arguments in baseline Verilog. But we allow it in our extended form of Verilog. */ if (op_ == '%' && ! gn_icarus_misc_flag) { if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: Modulus operator " "may not have REAL operands." << endl; des->errors += 1; } } NetEBDiv*tmp = new NetEBDiv(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } NetExpr* PEBinary::elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { // Keep constants on the right side. if (dynamic_cast(lp)) { NetExpr*tmp = lp; lp = rp; rp = tmp; } // Handle a few special case multiplies against constants. if (NetEConst*rp_const = dynamic_cast (rp)) { verinum rp_val = rp_const->value(); if (!rp_val.is_defined() && (lp->expr_type() == IVL_VT_LOGIC)) { NetEConst*tmp = make_const_x(expr_wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } if (rp_val.is_zero() && (lp->expr_type() == IVL_VT_BOOL)) { NetEConst*tmp = make_const_0(expr_wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } } NetEBMult*tmp = new NetEBMult(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } unsigned PEBComp::test_width(Design*des, NetScope*scope, width_mode_t&) { ivl_assert(*this, left_); ivl_assert(*this, right_); // The width and type of a comparison are fixed and well known. expr_type_ = IVL_VT_LOGIC; expr_width_ = 1; min_width_ = 1; signed_flag_ = false; // The widths of the operands are semi-self-determined. They // affect each other, but not the result. width_mode_t mode = SIZED; unsigned r_width = right_->test_width(des, scope, mode); width_mode_t saved_mode = mode; unsigned l_width = left_->test_width(des, scope, mode); // If the width mode changed, retest the right operand, as it // may choose a different width if it is in a lossless context. if ((mode >= LOSSLESS) && (saved_mode < LOSSLESS)) r_width = right_->test_width(des, scope, mode); ivl_variable_type_t l_type = left_->expr_type(); ivl_variable_type_t r_type = right_->expr_type(); l_width_ = l_width; if (type_is_vectorable(l_type) && (r_width > l_width)) l_width_ = r_width; r_width_ = r_width; if (type_is_vectorable(r_type) && (l_width > r_width)) r_width_ = l_width; // If the expression is lossless and smaller than the integer // minimum, then tweak the size up. // NOTE: I really would rather try to figure out what it would // take to get expand the sub-expressions so that they are // exactly the right width to behave just like infinite // width. I suspect that adding 1 more is sufficient in all // cases, but I'm not certain. Ideas? if (mode >= EXPAND) { if (type_is_vectorable(l_type) && (l_width_ < integer_width)) l_width_ += 1; if (type_is_vectorable(r_type) && (r_width_ < integer_width)) r_width_ += 1; } if (debug_elaborate) { cerr << get_fileline() << ": PEBComp::test_width: " << "Comparison expression operands are " << l_type << " " << l_width << " bits and " << r_type << " " << r_width << " bits. Resorting to " << l_width_ << " bits and " << r_width_ << " bits." << endl; } switch (op_) { case 'e': /* == */ case 'n': /* != */ case 'E': /* === */ case 'N': /* !== */ if ((l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) && l_type != r_type) { cerr << get_fileline() << ": error: " << "Both arguments ("<< l_type << ", " << r_type << ") must be class/null for '" << human_readable_op(op_) << "' operator." << endl; des->errors += 1; } break; default: if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) { cerr << get_fileline() << ": error: " << "Class/null is not allowed with the '" << human_readable_op(op_) << "' operator." << endl; des->errors += 1; } } return expr_width_; } NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_assert(*this, left_); ivl_assert(*this, right_); if (debug_elaborate) { cerr << get_fileline() << ": PEBComp::elaborate_expr: " << "Left expression: " << *left_ << endl; cerr << get_fileline() << ": PEBComp::elaborate_expr: " << "Right expression: " << *right_ << endl; cerr << get_fileline() << ": PEBComp::elaborate_expr: " << "op_: " << human_readable_op(op_) << ", expr_wid=" << expr_wid << ", flags=0x" << hex << flags << dec << endl; } // Propagate the comparison type (signed/unsigned) down to // the operands. if (type_is_vectorable(left_->expr_type()) && !left_->has_sign()) right_->cast_signed(false); if (type_is_vectorable(right_->expr_type()) && !right_->has_sign()) left_->cast_signed(false); NetExpr*lp = left_->elaborate_expr(des, scope, l_width_, flags); if (lp && debug_elaborate) { cerr << get_fileline() << ": PEBComp::elaborate_expr: " << "Elaborated left_: " << *lp << endl; } NetExpr*rp = right_->elaborate_expr(des, scope, r_width_, flags); if (rp && debug_elaborate) { cerr << get_fileline() << ": PEBComp::elaborate_expr: " << "Elaborated right_: " << *rp << endl; } if ((lp == 0) || (rp == 0)) { delete lp; delete rp; return 0; } eval_expr(lp, l_width_); eval_expr(rp, r_width_); // Handle some operand-specific special cases... switch (op_) { case 'E': /* === */ case 'N': /* !== */ if (lp->expr_type() == IVL_VT_REAL || lp->expr_type() == IVL_VT_STRING || rp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_STRING) { cerr << get_fileline() << ": error: " << human_readable_op(op_) << " operator may not have REAL or STRING operands." << endl; des->errors += 1; return 0; } break; case 'w': /* ==? */ case 'W': /* !=? */ if ((lp->expr_type() != IVL_VT_BOOL && lp->expr_type() != IVL_VT_LOGIC) || (rp->expr_type() != IVL_VT_BOOL && rp->expr_type() != IVL_VT_LOGIC)) { cerr << get_fileline() << ": error: " << human_readable_op(op_) << " operator may only have INTEGRAL operands." << endl; des->errors += 1; return 0; } break; default: break; } NetExpr*tmp = new NetEBComp(op_, lp, rp); tmp->set_line(*this); return pad_to_width(tmp, expr_wid, signed_flag_, *this); } unsigned PEBLogic::test_width(Design*, NetScope*, width_mode_t&) { // The width and type of a logical operation are fixed. expr_type_ = IVL_VT_LOGIC; expr_width_ = 1; min_width_ = 1; signed_flag_ = false; // The widths of the operands are self determined. We don't need // them now, so they can be tested when they are elaborated. return expr_width_; } NetExpr*PEBLogic::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { ivl_assert(*this, left_); ivl_assert(*this, right_); bool need_const = NEED_CONST & flags; NetExpr*lp = elab_and_eval(des, scope, left_, -1, need_const); NetExpr*rp = elab_and_eval(des, scope, right_, -1, need_const); if ((lp == 0) || (rp == 0)) { delete lp; delete rp; return 0; } lp = condition_reduce(lp); rp = condition_reduce(rp); NetExpr*tmp = new NetEBLogic(op_, lp, rp); tmp->set_line(*this); return pad_to_width(tmp, expr_wid, signed_flag_, *this); } unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode) { ivl_assert(*this, left_); ivl_assert(*this, right_); if (debug_elaborate) { cerr << get_fileline() << ": PEBLeftWidth::test_width: " << "op_=" << op_ << ", left_=" << *left_ << ", right_=" << *right_ << ", mode=" << width_mode_name(mode) << endl; } // The right operand is self determined. Test its type and // width for use later. We only need to know its width now // if the left operand is unsized and we need to calculate // the lossless width. width_mode_t r_mode = SIZED; unsigned r_width = right_->test_width(des, scope, r_mode); // The left operand is what will determine the size of the // expression. The l_mode will be converted to UNSIZED if the // expression does not have a well-determined size. width_mode_t l_mode = SIZED; expr_width_ = left_->test_width(des, scope, l_mode); expr_type_ = left_->expr_type(); signed_flag_ = left_->has_sign(); if (expr_type_ == IVL_VT_CLASS || right_->expr_type() == IVL_VT_CLASS) { cerr << get_fileline() << ": error: " << "Class/null is not allowed with the '" << human_readable_op(op_) << "' operator." << endl; des->errors += 1; } if (mode==SIZED) mode = l_mode; // The left operand width defines the size of the // expression. If the expression has a well-defined size, the // left_->test_width() above would have set mode==SIZED and we // can skip a lot of stuff. But if the mode is an undetermined // size, we need to figure out what we really want to keep a // lossless value. That's what the following if(...) {...} is // all about. if ((mode >= EXPAND) && type_is_vectorable(expr_type_)) { // We need to make our best guess at the right operand // value, to minimize the calculated width. This is // particularly important for the power operator... // Start off by assuming the maximum value for the // type and width of the right operand. long r_val = LONG_MAX; if (r_width < sizeof(long)*8) { r_val = (1UL << r_width) - 1UL; if ((op_ == 'p') && right_->has_sign()) r_val >>= 1; } // If the right operand is constant, we can use the // actual value. NetExpr*rp = right_->elaborate_expr(des, scope, r_width, NO_FLAGS); if (rp) { eval_expr(rp, r_width); } else { // error recovery PEVoid*tmp = new PEVoid(); tmp->set_line(*this); delete right_; right_ = tmp; } NetEConst*rc = dynamic_cast (rp); // Adjust the expression width that can be converter depending // on if the R-value is signed or not. unsigned c_width = sizeof(long)*8; if (! right_->has_sign()) c_width -= 1; if (rc && (r_width <= c_width)) r_val = rc->value().as_long(); if (debug_elaborate && rc) { cerr << get_fileline() << ": PEBLeftWidth::test_width: " << "Evaluated rc=" << *rc << ", r_val=" << r_val << ", width_cap=" << width_cap << endl; } // Clip to a sensible range to avoid underflow/overflow // in the following calculations. if (r_val < 0) r_val = 0; if ((unsigned long)r_val > width_cap) r_val = width_cap; // If the left operand is a simple unsized number, we // can calculate the actual width required for the power // operator. PENumber*lc = dynamic_cast (left_); // Now calculate the lossless width. unsigned use_width = expr_width_; switch (op_) { case 'l': // << if (l_mode != SIZED) use_width += (unsigned)r_val; break; case 'r': // >> case 'R': // >>> // A logical shift will effectively coerce a signed // operand to unsigned. We have to assume an arithmetic // shift may do the same, as we don't yet know the final // expression type. if ((mode == LOSSLESS) && signed_flag_) mode = UPSIZE; break; case 'p': // ** if (lc && rc) { verinum result = pow(lc->value(), rc->value()); use_width = max(use_width, result.len()); } else { if (signed_flag_) use_width -= 1; use_width *= (unsigned)r_val; if (signed_flag_) use_width += 2; } break; default: cerr << get_fileline() << ": internal error: " << "Unexpected opcode " << human_readable_op(op_) << " in PEBLeftWidth::test_width." << endl; des->errors += 1; } // If the right operand is not constant, we could end up // grossly overestimating the required width. So in this // case, don't expand beyond the width of an integer // (which meets the requirements of the standard). if ((rc == 0) && (use_width > expr_width_) && (use_width > integer_width)) use_width = integer_width; if (use_width >= width_cap) { cerr << get_fileline() << ": warning: " << "Unsized expression (" << *this << ")" << " expanded beyond and was clipped to " << use_width << " bits. Try using sized operands." << endl; } expr_width_ = use_width; } if (op_ == 'l') min_width_ = left_->min_width(); else min_width_ = UINT_MAX; // disable width pruning if (debug_elaborate) { cerr << get_fileline() << ": PEBLeftWidth::test_width: " << "Done calculating expr_width_=" << expr_width_ << ", min_width_=" << min_width_ << ", mode=" << width_mode_name(mode) << endl; } return fix_width_(mode); } NetExpr*PEBLeftWidth::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_assert(*this, left_); // The left operand is always context determined, so propagate // down the expression type (signed/unsigned). left_->cast_signed(signed_flag_); unsigned r_width = right_->expr_width(); NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, flags); NetExpr*rp = right_->elaborate_expr(des, scope, r_width, flags); if (lp == 0 || rp == 0) { delete lp; delete rp; return 0; } // For shift operations, the right operand is always treated as // unsigned, so coerce it if necessary. if ((op_ != 'p') && rp->has_sign()) { rp = new NetESelect(rp, 0, rp->expr_width()); rp->cast_signed(false); rp->set_line(*this); } eval_expr(lp, expr_wid); eval_expr(rp, r_width); return elaborate_expr_leaf(des, lp, rp, expr_wid); } NetExpr*PEBPower::elaborate_expr_leaf(Design*, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { if (debug_elaborate) { cerr << get_fileline() << ": debug: elaborate expression " << *this << " expr_wid=" << expr_wid << endl; } NetExpr*tmp = new NetEBPow(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } static unsigned int sign_cast_width(Design*des, NetScope*scope, PExpr &expr, PExpr::width_mode_t&mode) { unsigned int width; // The argument type/width is self-determined, but affects // the result width. PExpr::width_mode_t arg_mode = PExpr::SIZED; width = expr.test_width(des, scope, arg_mode); if ((arg_mode >= PExpr::EXPAND) && type_is_vectorable(expr.expr_type())) { if (mode < PExpr::LOSSLESS) mode = PExpr::LOSSLESS; if (width < integer_width) width = integer_width; } return width; } NetExpr*PEBShift::elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, unsigned expr_wid) const { switch (op_) { case 'l': // << case 'r': // >> case 'R': // >>> break; default: cerr << get_fileline() << ": internal error: " << "Unexpected opcode " << human_readable_op(op_) << " in PEBShift::elaborate_expr_leaf." << endl; des->errors += 1; return 0; } if (lp->expr_type() == IVL_VT_REAL || rp->expr_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: " << human_readable_op(op_) << " operator may not have REAL operands." << endl; des->errors += 1; delete lp; delete rp; return 0; } NetExpr*tmp; // If the left expression is constant, then there are some // special cases we can work with. If the left expression is // not constant, but the right expression is constant, then // there are some other interesting cases. But if neither are // constant, then there is the general case. if (NetEConst*lpc = dynamic_cast (lp)) { // Special case: The left expression is zero. If the // shift value contains no 'x' or 'z' bits, the result // is going to be zero. if (lpc->value().is_defined() && lpc->value().is_zero() && (rp->expr_type() == IVL_VT_BOOL)) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Shift of zero always returns zero." << " Elaborate as constant zero." << endl; tmp = make_const_0(expr_wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } } else if (NetEConst*rpc = dynamic_cast (rp)) { // Special case: The shift value contains 'x' or 'z' bits. // Elaborate as a constant-x. if (!rpc->value().is_defined()) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Shift by undefined value. " << "Elaborate as constant 'x'." << endl; tmp = make_const_x(expr_wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); delete lp; delete rp; return tmp; } unsigned long shift = rpc->value().as_ulong(); // Special case: The shift is zero. The result is simply // the left operand. if (shift == 0) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Shift by zero. Elaborate as the " << "left hand operand." << endl; delete rp; return lp; } // Special case: the shift is at least the size of the entire // left operand, and the shift is a signed right shift. // Elaborate as a replication of the top bit of the left // expression. if ((op_=='R' && signed_flag_) && (shift >= expr_wid)) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Value signed-right-shifted " << shift << " beyond width of " << expr_wid << ". Elaborate as replicated top bit." << endl; tmp = new NetEConst(verinum(expr_wid-1)); tmp->set_line(*this); tmp = new NetESelect(lp, tmp, 1); tmp->set_line(*this); tmp = pad_to_width(tmp, expr_wid, true, *this); delete rp; return tmp; } // Special case: The shift is at least the size of the entire // left operand, and the shift is not a signed right shift // (which is caught by the previous special case). Elaborate // as a constant-0. if (shift >= expr_wid) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Value shifted " << shift << " beyond width of " << expr_wid << ". Elaborate as constant zero." << endl; tmp = make_const_0(expr_wid); tmp->cast_signed(signed_flag_); tmp->set_line(*this); delete lp; delete rp; return tmp; } } // Fallback, handle the general case. tmp = new NetEBShift(op_, lp, rp, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, width_mode_t&mode) { perm_string name = peek_tail_name(path_); if (name=="$ivlh_to_unsigned") { ivl_assert(*this, parms_.size() == 2); // The Icarus Verilog specific $ivlh_to_unsigned() system // task takes a second argument which is the output // size. This can be an arbitrary constant function. PExpr*pexpr = parms_[1]; if (pexpr == 0) { cerr << get_fileline() << ": error: " << "Missing $ivlh_to_unsigned width." << endl; return 0; } NetExpr*nexpr = elab_and_eval(des, scope, pexpr, -1, true); if (nexpr == 0) { cerr << get_fileline() << ": error: " << "Unable to evaluate " << name << " width argument: " << *pexpr << endl; return 0; } long value = 0; bool rc = eval_as_long(value, nexpr); ivl_assert(*this, rc && value>=0); // The argument width is self-determined and doesn't // affect the result width. width_mode_t arg_mode = SIZED; parms_[0]->test_width(des, scope, arg_mode); expr_type_ = pexpr->expr_type(); expr_width_ = value; min_width_ = value; signed_flag_= false; return expr_width_; } if (name=="$signed" || name=="$unsigned") { PExpr*expr = parms_[0]; if (expr == 0) return 0; expr_width_ = sign_cast_width(des, scope, *expr, mode); expr_type_ = expr->expr_type(); min_width_ = expr->min_width(); signed_flag_ = (name[1] == 's'); if (debug_elaborate) cerr << get_fileline() << ": debug: " << name << " argument width = " << expr_width_ << "." << endl; return expr_width_; } if (name=="$sizeof" || name=="$bits") { PExpr*expr = parms_[0]; if (expr == 0) return 0; if (! dynamic_cast(expr)) { // The argument type/width is self-determined and doesn't // affect the result type/width. Note that if the // argument is a type name (a special case) then // don't bother with this step. width_mode_t arg_mode = SIZED; expr->test_width(des, scope, arg_mode); } expr_type_ = IVL_VT_BOOL; expr_width_ = integer_width; min_width_ = integer_width; signed_flag_ = false; if (debug_elaborate) cerr << get_fileline() << ": " << __func__ << ": " << "test_width of " << name << " returns test_width" << " of compiler integer." << endl; return expr_width_; } if (name=="$is_signed") { PExpr*expr = parms_[0]; if (expr == 0) return 0; // The argument type/width is self-determined and doesn't // affect the result type/width. width_mode_t arg_mode = SIZED; expr->test_width(des, scope, arg_mode); expr_type_ = IVL_VT_BOOL; expr_width_ = 1; min_width_ = 1; signed_flag_ = false; if (debug_elaborate) cerr << get_fileline() << ": " << __func__ << ": " << "test_width of $is_signed returns test_width" << " of 1." << endl; return expr_width_; } /* Get the return type of the system function by looking it up in the sfunc_table. */ const struct sfunc_return_type*sfunc_info = lookup_sys_func(name); expr_type_ = sfunc_info->type; expr_width_ = sfunc_info->wid; min_width_ = expr_width_; signed_flag_ = sfunc_info->signed_flag; is_overridden_ = sfunc_info->override_flag; if (debug_elaborate) cerr << get_fileline() << ": " << __func__ << ": " << "test_width of system function " << name << " returns wid=" << expr_width_ << ", type=" << expr_type_ << "." << endl; return expr_width_; } /* * Get the function definition from the scope that we believe to be a * function. If it is not, return 0. If it is, handle the special case that we * may be still elaborating things. For example: * * localparam foo = func(...) * * In this case, the function is not necessarily elaborated yet, and we need * to force enough elaboration that we can get a definition. */ static NetFuncDef* find_function_definition(Design*des, NetScope*, NetScope*func) { if (func && (func->type() == NetScope::FUNC)) { if (func->elab_stage() < 2) { func->need_const_func(true); const PFunction*pfunc = func->func_pform(); assert(pfunc); pfunc->elaborate_sig(des, func); } return func->func_def(); } return 0; } unsigned PECallFunction::test_width_method_(Design*, NetScope*, symbol_search_results&search_results, width_mode_t&) { if (!gn_system_verilog()) return 0; if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "search_results.path_head: " << search_results.path_head << endl; cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "search_results.path_tail: " << search_results.path_tail << endl; if (search_results.net) cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "search_results.net->data_type: " << search_results.net->data_type() << endl; if (search_results.net && search_results.net->net_type()) cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "search_results.net->net_type: " << *search_results.net->net_type() << endl; } // Don't support multiple chained methods yet. if (search_results.path_tail.size() > 1) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "Chained path tail (" << search_results.path_tail << ") not supported." << endl; } return 0; } ivl_assert(*this, search_results.path_tail.size() == 1); perm_string method_name = search_results.path_tail.back().name; // Dynamic array variable without a select expression. The method // applies to the array itself, and not to the object that might be // indexed from it. So return // the expr_width for the return value of the queue method. For example: // .x.size(); // In this example, x is a dynamic array. if (search_results.net && search_results.net->data_type()==IVL_VT_DARRAY && search_results.path_head.back().index.empty()) { NetNet*net = search_results.net; const netdarray_t*darray = net->darray_type(); ivl_assert(*this, darray); if (method_name == "size") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = expr_width_; signed_flag_= true; return expr_width_; } return 0; } // Queue variable without a select expression. The method applies to the // queue, and not to the object that might be indexed from it. So return // the expr_width for the return value of the queue method. For example: // .x.size(); // In this example, x is a queue. if (search_results.net && search_results.net->data_type()==IVL_VT_QUEUE && search_results.path_head.back().index.empty()) { NetNet*net = search_results.net; const netdarray_t*darray = net->darray_type(); ivl_assert(*this, darray); if (method_name == "size") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = expr_width_; signed_flag_= true; return expr_width_; } if (method_name=="pop_back" || method_name=="pop_front") { expr_type_ = darray->element_base_type(); expr_width_ = darray->element_width(); min_width_ = expr_width_; signed_flag_= darray->get_signed(); return expr_width_; } return 0; } // Queue variable with a select expression. The type of this expression // is the type of the object that will interpret the method. For // example: // .x[e].len() // If for example x is a queue of strings, then x[e] is a string and // x[e].len() is the length of the string. if (search_results.net && (search_results.net->data_type()==IVL_VT_QUEUE || search_results.net->data_type()==IVL_VT_DARRAY) && search_results.path_head.back().index.size()) { NetNet*net = search_results.net; const netdarray_t*darray = net->darray_type(); ivl_assert(*this, darray); if (darray->element_base_type()==IVL_VT_STRING && method_name=="atohex") { expr_type_ = IVL_VT_BOOL; expr_width_ = integer_width; min_width_ = integer_width; signed_flag_ = true; return expr_width_; } if (darray->element_base_type()==IVL_VT_STRING && method_name=="atoi") { expr_type_ = IVL_VT_BOOL; expr_width_ = integer_width; min_width_ = integer_width; return expr_width_; } if (darray->element_base_type()==IVL_VT_STRING && method_name=="len") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = 32; signed_flag_= true; return expr_width_; } } // Enumeration variable. Check for the various enumeration methods. if (search_results.net && search_results.net->enumeration()) { NetNet*net = search_results.net; const netenum_t*enum_type = net->enumeration(); if (method_name=="first" || method_name=="last" || method_name=="prev" || method_name=="next") { expr_type_ = IVL_VT_BOOL; expr_width_ = enum_type->packed_width(); min_width_ = expr_width_; signed_flag_= enum_type->get_signed(); return expr_width_; } if (method_name=="num") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = expr_width_; signed_flag_= true; return expr_width_; } if (method_name=="name") { expr_type_ = IVL_VT_STRING; expr_width_ = 1; min_width_ = 1; signed_flag_= false; return expr_width_; } return 0; } // Class variables. In this case, the search found the class instance, // and the scope is the scope where the instance lives. The class method // in turn defines it's own scope. Use that to find the return value. if (search_results.net && search_results.net->data_type()==IVL_VT_CLASS) { const netclass_t *class_type = dynamic_cast(search_results.type); ivl_assert(*this, class_type); NetScope*method = class_type->method_from_name(method_name); if (method == 0) { return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "Found method " << scope_path(method) << "(...)" << endl; } // Get the return value of the method function. if (NetNet*res = method->find_signal(method->basename())) { expr_type_ = res->data_type(); expr_width_ = res->vector_width(); min_width_ = expr_width_; signed_flag_ = res->get_signed(); if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "test_width of class method returns width " << expr_width_ << ", type=" << expr_type_ << "." << endl; } return expr_width_; } return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width_method_: " << "I give up." << endl; } return 0; } unsigned PECallFunction::test_width(Design*des, NetScope*scope, width_mode_t&mode) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "path_: " << path_ << endl; cerr << get_fileline() << ": PECallFunction::test_width: " << "mode: " << width_mode_name(mode) << endl; } if (peek_tail_name(path_)[0] == '$') return test_width_sfunc_(des, scope, mode); // Search for the symbol. This should turn up a scope. symbol_search_results search_results; bool search_flag = symbol_search(this, des, scope, path_, &search_results); if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "search_flag: " << (search_flag? "true" : "false") << endl; if (search_results.scope) cerr << get_fileline() << ": PECallFunction::test_width: " << "search_results.scope: " << scope_path(search_results.scope) << endl; if (search_results.net) cerr << get_fileline() << ": PECallFunction::test_width: " << "search_results.net: " << search_results.net->name() << endl; cerr << get_fileline() << ": PECallFunction::test_width: " << "search_results.path_head: " << search_results.path_head << endl; cerr << get_fileline() << ": PECallFunction::test_width: " << "search_results.path_tail: " << search_results.path_tail << endl; } // Nothing found? Return nothing. if (!search_flag) { expr_width_ = 0; min_width_ = 0; signed_flag_ = false; if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "Not found, returning nil width results." << endl; } return expr_width_; } // Catch the special case that this is not a scope, but that we // are in fact in a function calling ourself recursively. For // example: // // function integer factoral; // input integer n; // begin // if (n > 1) // factorial = n * factorial(n-1); <== HERE // else // factorial = n; // end // endfunction // // In this case, the call to factorial within itself will find the // net "factorial", but we can notice that the scope is a function // with the same name as the function. if (test_function_return_value(search_results)) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "Net " << search_results.net->name() << " is actually a function call to " << scope_path(search_results.scope) << "." << endl; } NetNet*res = search_results.net; expr_type_ = res->data_type(); expr_width_ = res->vector_width(); min_width_ = expr_width_; signed_flag_ = res->get_signed(); if (debug_elaborate) cerr << get_fileline() << ": PECallFunction::test_width: " << "test_width of function returns width " << dec << expr_width_ << ", type=" << expr_type_ << "." << endl; return expr_width_; } // If the symbol is found, but is not a scope... if (!search_results.is_scope()) { if (!search_results.path_tail.empty()) { return test_width_method_(des, scope, search_results, mode); } // I don't know what to do about this. if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "I don't know how to handle non-scopes here." << endl; } return 0; } NetFuncDef*def = find_function_definition(des, scope, search_results.scope); if (def == 0) { // If this is an access function, then the width and // type are known by definition. if (find_access_function(path_)) { expr_type_ = IVL_VT_REAL; expr_width_ = 1; min_width_ = 1; signed_flag_ = true; return expr_width_; } // I don't know what to do about this. if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::test_width: " << "Scope is not a function." << endl; } return 0; } if (def->is_void()) return 0; NetScope*dscope = def->scope(); assert(dscope); if (NetNet*res = dscope->find_signal(dscope->basename())) { expr_type_ = res->data_type(); expr_width_ = res->vector_width(); min_width_ = expr_width_; signed_flag_ = res->get_signed(); if (debug_elaborate) cerr << get_fileline() << ": PECallFunction::test_width: " << "test_width of function returns width " << expr_width_ << ", type=" << expr_type_ << "." << endl; return expr_width_; } ivl_assert(*this, 0); return 0; } NetExpr*PECallFunction::cast_to_width_(NetExpr*expr, unsigned wid) const { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::cast_to_width_: " << "cast to " << wid << " bits " << (signed_flag_ ? "signed" : "unsigned") << " from expr_width()=" << expr->expr_width() << endl; } return cast_to_width(expr, wid, signed_flag_, *this); } /* * Given a call to a system function, generate the proper expression * nodes to represent the call in the netlist. Since we don't support * size_tf functions, make assumptions about widths based on some * known function names. */ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { perm_string name = peek_tail_name(path_); /* Catch the special case that the system function is the $ivl_unsigned function. In this case the second argument is the size of the expression, but should already be accounted for so treat this very much like the $unsigned() function. */ if (name=="$ivlh_to_unsigned") { ivl_assert(*this, parms_.size()==2); PExpr*expr = parms_[0]; ivl_assert(*this, expr); NetExpr*sub = expr->elaborate_expr(des, scope, expr->expr_width(), flags); return cast_to_width_(sub, expr_wid); } /* Catch the special case that the system function is the $signed function. Its argument will be evaluated as a self-determined expression. */ if (name=="$signed" || name=="$unsigned") { if ((parms_.size() != 1) || (parms_[0] == 0)) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; return 0; } if (!type_is_vectorable(expr_type_)) { cerr << get_fileline() << ": error: The argument to " << name << " must be a vector type." << endl; des->errors += 1; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: " << name << " expression is the argument cast to expr_wid=" << expr_wid << endl; } PExpr*expr = parms_[0]; NetExpr*sub = expr->elaborate_expr(des, scope, expr_width_, flags); return cast_to_width_(sub, expr_wid); } /* Interpret the internal $sizeof system function to return the bit width of the sub-expression. The value of the sub-expression is not used, so the expression itself can be deleted. */ if (name=="$sizeof" || name=="$bits") { if ((parms_.size() != 1) || (parms_[0] == 0)) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; return 0; } if (name=="$sizeof") cerr << get_fileline() << ": warning: $sizeof is deprecated." << " Use $bits() instead." << endl; PExpr*expr = parms_[0]; uint64_t use_width = 0; if (PETypename*type_expr = dynamic_cast(expr)) { ivl_type_t data_type = type_expr->get_type()->elaborate_type(des, scope); ivl_assert(*this, data_type); use_width = 1; while (const netuarray_t *utype = dynamic_cast(data_type)) { const vector &dims = utype->static_dimensions(); for (size_t i = 0; i < dims.size(); i++) use_width *= dims[i].width(); data_type = utype->element_type(); } if (!data_type->packed()) { use_width = 0; cerr << get_fileline() << ": error: " << "Invalid data type for $bits()." << endl; des->errors++; } else { use_width *= data_type->packed_width(); } if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: " << " Packed width of type argument is " << use_width << endl; } } else { use_width = expr->expr_width(); if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: " << " Width of expression argument is " << use_width << endl; } } verinum val (use_width, integer_width); NetEConst*sub = new NetEConst(val); sub->set_line(*this); return cast_to_width_(sub, expr_wid); } /* Interpret the internal $is_signed system function to return a single bit flag -- 1 if the expression is signed, 0 otherwise. */ if (name=="$is_signed") { if ((parms_.size() != 1) || (parms_[0] == 0)) { cerr << get_fileline() << ": error: The " << name << " function takes exactly one(1) argument." << endl; des->errors += 1; return 0; } PExpr*expr = parms_[0]; verinum val (expr->has_sign() ? verinum::V1 : verinum::V0, 1); NetEConst*sub = new NetEConst(val); sub->set_line(*this); return cast_to_width_(sub, expr_wid); } /* How many parameters are there? The Verilog language allows empty parameters in certain contexts, so the parser will allow things like func(1,,3). It will also cause func() to be interpreted as a single empty parameter. Functions cannot really take empty parameters, but the case ``func()'' is the same as no parameters at all. So catch that special case here. */ unsigned nparms = parms_.size(); if ((nparms == 1) && (parms_[0] == 0)) nparms = 0; NetESFunc*fun = new NetESFunc(name, expr_type_, expr_width_, nparms, is_overridden_); fun->set_line(*this); bool need_const = NEED_CONST & flags; /* We don't support evaluating overridden functions. */ if (is_overridden_ && (need_const || scope->need_const_func())) { cerr << get_fileline() << ": sorry: Cannot evaluate " "overridden system function." << endl; des->errors += 1; } if (is_overridden_ || !fun->is_built_in()) { if (scope->need_const_func()) { cerr << get_fileline() << ": error: " << name << " is not a built-in function, so cannot" << " be used in a constant function." << endl; des->errors += 1; } scope->is_const_func(false); } /* Now run through the expected parameters. If we find that there are missing parameters, print an error message. While we're at it, try to evaluate the function parameter expression as much as possible, and use the reduced expression if one is created. */ /* These functions can work in a constant context with a signal expression. */ if ((nparms == 1) && (dynamic_cast(parms_[0]))) { if (strcmp(name, "$dimensions") == 0) need_const = false; else if (strcmp(name, "$high") == 0) need_const = false; else if (strcmp(name, "$increment") == 0) need_const = false; else if (strcmp(name, "$left") == 0) need_const = false; else if (strcmp(name, "$low") == 0) need_const = false; else if (strcmp(name, "$right") == 0) need_const = false; else if (strcmp(name, "$size") == 0) need_const = false; else if (strcmp(name, "$unpacked_dimensions") == 0) need_const = false; } unsigned parm_errors = 0; unsigned missing_parms = 0; for (unsigned idx = 0 ; idx < nparms ; idx += 1) { PExpr*expr = parms_[idx]; if (expr) { NetExpr*tmp = elab_sys_task_arg(des, scope, name, idx, expr, need_const); if (tmp) { fun->parm(idx, tmp); } else { parm_errors += 1; fun->parm(idx, 0); } } else { missing_parms += 1; fun->parm(idx, 0); } } if (missing_parms > 0) { cerr << get_fileline() << ": error: The function " << name << " has been called with missing/empty parameters." << endl; cerr << get_fileline() << ": : Verilog doesn't allow " << "passing empty parameters to functions." << endl; des->errors += 1; } if (missing_parms || parm_errors) return 0; return pad_to_width(fun, expr_wid, signed_flag_, *this); } NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t nature) const { // An access function must have 1 or 2 arguments. ivl_assert(*this, parms_.size()==2 || parms_.size()==1); NetBranch*branch = 0; if (parms_.size() == 1) { PExpr*arg1 = parms_[0]; PEIdent*arg_ident = dynamic_cast (arg1); ivl_assert(*this, arg_ident); const pform_name_t&path = arg_ident->path(); ivl_assert(*this, path.size()==1); perm_string name = peek_tail_name(path); NetNet*sig = scope->find_signal(name); ivl_assert(*this, sig); ivl_discipline_t dis = sig->get_discipline(); ivl_assert(*this, dis); ivl_assert(*this, nature == dis->potential() || nature == dis->flow()); NetNet*gnd = des->find_discipline_reference(dis, scope); if ( (branch = find_existing_implicit_branch(sig, gnd)) ) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Re-use implicit branch from " << branch->get_fileline() << endl; } else { branch = new NetBranch(dis); branch->set_line(*this); connect(branch->pin(0), sig->pin(0)); connect(branch->pin(1), gnd->pin(0)); des->add_branch(branch); join_island(branch); if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Create implicit branch." << endl; } } else { ivl_assert(*this, 0); } NetExpr*tmp = new NetEAccess(branch, nature); tmp->set_line(*this); return tmp; } /* * Routine to look for and build enumeration method calls. */ static NetExpr* check_for_enum_methods(const LineInfo*li, Design*des, NetScope*scope, const netenum_t*netenum, const pform_name_t&use_path, perm_string method_name, NetExpr*expr, PExpr*parg, unsigned args) { if (debug_elaborate) { cerr << li->get_fileline() << ": " << __func__ << ": " << "Check for method " << method_name << " of enumeration at " << netenum->get_fileline() << endl; cerr << li->get_fileline() << ": " << __func__ << ": " << "use_path=" << use_path << endl; cerr << li->get_fileline() << ": " << __func__ << ": " << "expr=" << *expr << endl; } // First, look for some special methods that can be replace with // constant literals. These get properties of the enumeration type, and // so can be fully evaluated at compile time. if (method_name == "num") { // The "num()" method returns the number of elements. This is // actually a static constant, and can be replaced at compile time // with a constant value. if (args != 0) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".num() does not " "take an argument." << endl; des->errors += 1; } NetEConst*tmp = make_const_val(netenum->size()); tmp->set_line(*li); delete expr; // The elaborated enum variable is not needed. return tmp; } if (method_name == "first") { // The "first()" method returns the first enumeration value. This // doesn't actually care about the constant value, and instead // returns as a constant literal the first value of the enumeration. if (args != 0) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".first() does not " "take an argument." << endl; des->errors += 1; } netenum_t::iterator item = netenum->first_name(); NetEConstEnum*tmp = new NetEConstEnum(item->first, netenum, item->second); tmp->set_line(*li); delete expr; // The elaborated enum variable is not needed. return tmp; } if (method_name == "last") { // The "last()" method returns the first enumeration value. This // doesn't actually care about the constant value, and instead // returns as a constant literal the last value of the enumeration. if (args != 0) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".last() does not " "take an argument." << endl; des->errors += 1; } netenum_t::iterator item = netenum->last_name(); NetEConstEnum*tmp = new NetEConstEnum(item->first, netenum, item->second); tmp->set_line(*li); delete expr; // The elaborated enum variable is not needed. return tmp; } NetESFunc*sys_expr; // Process the method argument if it is available. NetExpr* count = 0; if (args != 0 && parg) { count = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, parg); if (count == 0) { cerr << li->get_fileline() << ": error: unable to elaborate " "enumeration method argument " << use_path << "." << method_name << "(" << parg << ")." << endl; args = 0; des->errors += 1; } else if (NetEEvent*evt = dynamic_cast (count)) { cerr << evt->get_fileline() << ": error: An event '" << evt->event()->name() << "' cannot be an enumeration " "method argument." << endl; args = 0; des->errors += 1; } } if (method_name == "name") { // The "name()" method returns the name of the current enumeration // value. The generated system task takes the enumeration // definition and the enumeration value. The return value is the // string name of the enumeration. if (args != 0) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".name() does not " "take an argument." << endl; des->errors += 1; } // Generate the internal system function. Make sure the return // value is "string" type. sys_expr = new NetESFunc("$ivl_enum_method$name", &netstring_t::type_string, 2); NetENetenum* def = new NetENetenum(netenum); def->set_line(*li); sys_expr->parm(0, def); sys_expr->parm(1, expr); } else if (method_name == "next") { // The "next()" method returns the next enumeration value. if (args > 1) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".next() take at " "most one argument." << endl; des->errors += 1; } sys_expr = new NetESFunc("$ivl_enum_method$next", netenum, 2 + (args != 0)); NetENetenum* def = new NetENetenum(netenum); def->set_line(*li); sys_expr->parm(0, def); sys_expr->parm(1, expr); if (args != 0) sys_expr->parm(2, count); } else if (method_name == "prev") { // The "prev()" method returns the previous enumeration value. if (args > 1) { cerr << li->get_fileline() << ": error: enumeration " "method " << use_path << ".prev() take at " "most one argument." << endl; des->errors += 1; } sys_expr = new NetESFunc("$ivl_enum_method$prev", netenum, 2 + (args != 0)); NetENetenum* def = new NetENetenum(netenum); def->set_line(*li); sys_expr->parm(0, def); sys_expr->parm(1, expr); if (args != 0) sys_expr->parm(2, count); } else { // This is an unknown enumeration method. cerr << li->get_fileline() << ": error: Unknown enumeration " "method " << use_path << "." << method_name << "()." << endl; des->errors += 1; return expr; } sys_expr->set_line(*li); if (debug_elaborate) { cerr << li->get_fileline() << ": " << __func__ << ": Generate " << sys_expr->name() << "(" << use_path << ")" << endl; } return sys_expr; } /* * If the method matches a structure member then return the member otherwise * return 0. Also return the offset of the member. */ static const netstruct_t::member_t*get_struct_member(const LineInfo*li, Design*des, NetScope*, NetNet*net, perm_string method_name, unsigned long&off) { const netstruct_t*type = net->struct_type(); ivl_assert(*li, type); if (! type->packed()) { cerr << li->get_fileline() << ": sorry: unpacked structures not supported here. " << "Method=" << method_name << endl; des->errors += 1; return 0; } return type->packed_member(method_name, off); } bool calculate_part(const LineInfo*li, Design*des, NetScope*scope, const index_component_t&index, long&off, unsigned long&wid) { if (index.sel == index_component_t::SEL_BIT_LAST) { cerr << li->get_fileline() << ": sorry: " << "Last element select expression " << "not supported." << endl; des->errors += 1; return false; } // Evaluate the last index expression into a constant long. NetExpr*texpr = elab_and_eval(des, scope, index.msb, -1, true); long msb; if (texpr == 0 || !eval_as_long(msb, texpr)) { cerr << li->get_fileline() << ": error: " "Array/part index expressions must be constant here." << endl; des->errors += 1; return false; } delete texpr; long lsb = msb; if (index.lsb) { texpr = elab_and_eval(des, scope, index.lsb, -1, true); if (texpr==0 || !eval_as_long(lsb, texpr)) { cerr << li->get_fileline() << ": error: " "Array/part index expressions must be constant here." << endl; des->errors += 1; return false; } delete texpr; } switch (index.sel) { case index_component_t::SEL_BIT: off = msb; wid = 1; return true; case index_component_t::SEL_PART: off = lsb; if (msb >= lsb) { wid = msb - lsb + 1; } else { wid = lsb - msb + 1; } return true; case index_component_t::SEL_IDX_UP: wid = lsb; off = msb; break; default: ivl_assert(*li, 0); break; } return true; } /* * Test if the tail name (method_name argument) is a member name and * the net is a struct. If that turns out to be the case, and the * struct is packed, then return a NetExpr that selects the member out * of the variable. */ static NetExpr* check_for_struct_members(const LineInfo*li, Design*des, NetScope*scope, NetNet*net, const list&base_index, pform_name_t member_path) { const netstruct_t*struct_type = net->struct_type(); ivl_assert(*li, struct_type); if (! struct_type->packed()) { cerr << li->get_fileline() << ": sorry: " << "Unpacked structures not supported here." << endl; des->errors += 1; return 0; } // These make up the "part" select that is the equivilent of // following the member path through the nested structs. To // start with, the off[set] is zero, and use_width is the // width of the entire variable. The first member_comp is at // some offset within the variable, and will have a reduced // width. As we step through the member_path the off // increases, and use_width shrinks. unsigned long off = 0; unsigned long use_width = struct_type->packed_width(); pform_name_t completed_path; ivl_type_t member_type = 0; do { const name_component_t member_comp = member_path.front(); const perm_string&member_name = member_comp.name; if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "Processing member_comp=" << member_comp << " (completed_path=" << completed_path << ")" << endl; } // Calculate the offset within the packed structure of the // member, and any indices. We will add in the offset of the // struct into the packed array later. Note that this works // for packed unions as well (although the offset will be 0 // for union members). unsigned long tmp_off; const netstruct_t::member_t* member = struct_type->packed_member(member_name, tmp_off); if (member == 0) { cerr << li->get_fileline() << ": error: Member " << member_name << " is not a member of struct type of " << net->name() << "." << completed_path << endl; des->errors += 1; return 0; } member_type = member->net_type; if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "Member type: " << *member_type << " (" << typeid(*member_type).name() << ")" << endl; } off += tmp_off; ivl_assert(*li, use_width >= (unsigned long)member_type->packed_width()); use_width = member_type->packed_width(); // At this point, off and use_width are the part select // expressed by the member_comp, which is a member of the // struct. We can further refine the part select with any // indices that might be present. if (const netstruct_t*tmp_struct = dynamic_cast(member_type)) { // If the member is itself a struct, then get // ready to go on to the next iteration. struct_type = tmp_struct; } else if (const netenum_t*tmp_enum = dynamic_cast (member_type)) { // If the element is an enum, then we don't have // anything special to do. if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "Tail element is an enum" << *tmp_enum << endl; } struct_type = 0; } else if (const netvector_t*mem_vec = dynamic_cast(member_type)) { if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "member_comp=" << member_comp << " has " << member_comp.index.size() << " indices." << endl; } // If the member type is a netvector_t, then it is a // vector of atom or scaler objects. For example, if the // l-value expression is "foo.member[1][2]", // then the member should be something like: // ... logic [h:l][m:n] member; // There should be index expressions index the vector // down, but there doesn't need to be all of them. We // can, for example, be selecting a part of the vector. // We only need to process this if there are any // index expressions. If not, then the packed // vector can be handled atomically. // In any case, this should be the tail of the // member_path, because the array element of this // kind of array cannot be a struct. if (!member_comp.index.empty()) { // These are the dimensions defined by the type const vector&mem_packed_dims = mem_vec->packed_dims(); if (member_comp.index.size() > mem_packed_dims.size()) { cerr << li->get_fileline() << ": error: " << "Too many index expressions for member." << endl; des->errors += 1; return 0; } // Evaluate all but the last index expression, into prefix_indices. listprefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); ivl_assert(*li, rc); if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "prefix_indices.size()==" << prefix_indices.size() << ", mem_packed_dims.size()==" << mem_packed_dims.size() << endl; } long tail_off = 0; unsigned long tail_wid = 0; rc = calculate_part(li, des, scope, member_comp.index.back(), tail_off, tail_wid); if (! rc) return 0; if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_member: " << "calculate_part for tail returns tail_off=" << tail_off << ", tail_wid=" << tail_wid << endl; } // Now use the prefix_to_slice function to calculate the // offset and width of the addressed slice // of the member. The lwid comming out of // the prefix_to_slice is the number of // elements, and should be 1. The tmp_wid it // the bit with of the result. long loff; unsigned long lwid; prefix_to_slice(mem_packed_dims, prefix_indices, tail_off, loff, lwid); if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "Calculate loff=" << loff << " lwid=" << lwid << " tail_off=" << tail_off << " tail_wid=" << tail_wid << " off=" << off << " use_width=" << use_width << endl; } off += loff; use_width = lwid * tail_wid; } // The netvector_t only has atom elements, so // there is no next struct type. struct_type = 0; } else if (const netparray_t*array = dynamic_cast(member_type)) { // If the member is a parray, then the elements // are themselves packed object, including // possibly a struct. Handle this by taking the // part select of the current part of the // variable, then stepping to the element type to // possibly iterate through more of the member_path. ivl_assert(*li, array->packed()); ivl_assert(*li, !member_comp.index.empty()); // These are the dimensions defined by the type const vector&mem_packed_dims = array->static_dimensions(); if (member_comp.index.size() != mem_packed_dims.size()) { cerr << li->get_fileline() << ": error: " << "Incorrect number of index expressions for member " << member_name << "." << endl; des->errors += 1; return 0; } // Evaluate all but the last index expression, into prefix_indices. listprefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); ivl_assert(*li, rc); // Evaluate the last index expression into a constant long. NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true); long tmp; if (texpr == 0 || !eval_as_long(tmp, texpr)) { cerr << li->get_fileline() << ": error: " << "Array index expressions for member " << member_name << " must be constant here." << endl; des->errors += 1; return 0; } delete texpr; // Now use the prefix_to_slice function to calculate the // offset and width of the addressed slice of the member. long loff; unsigned long lwid; prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid); ivl_type_t element_type = array->element_type(); long element_width = element_type->packed_width(); if (debug_elaborate) { cerr << li->get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "parray subselection loff=" << loff << ", lwid=" << lwid << ", element_width=" << element_width << endl; } // The width and offset calculated from the // indices is actually in elements, and not // bits. In fact, in this context, the lwid should // come down to 1 (one element). off += loff * element_width; ivl_assert(*li, lwid==1); use_width = element_width; // To move on to the next component in the member // path, get the element type. For example, for // the path a.b[1].c, we are processing b[1] here, // and the element type should be a netstruct_t // that will wind up containing the member c. struct_type = dynamic_cast (element_type); } else { // Unknown type? cerr << li->get_fileline() << ": internal error: " << "Unexpected member type? " << *member_type << endl; des->errors += 1; struct_type = 0; } // Complete this component of the path, mark it // completed, and set up for the next component. completed_path .push_back(member_comp); member_path.pop_front(); } while (!member_path.empty() && struct_type != 0); // The dimensions in the expression must match the packed // dimensions that are declared for the variable. For example, // if foo is a packed array of struct, then this expression // must be "b[n][m]" with the right number of dimensions to // match the declaration of "b". // Note that one of the packed dimensions is the packed struct // itself. ivl_assert(*li, base_index.size()+1 == net->packed_dimensions()); NetExpr*packed_base = 0; if (net->packed_dimensions() > 1) { listtmp_index = base_index; index_component_t member_select; member_select.sel = index_component_t::SEL_BIT; member_select.msb = new PENumber(new verinum(off)); tmp_index.push_back(member_select); packed_base = collapse_array_exprs(des, scope, li, net, tmp_index); ivl_assert(*li, packed_base); if (debug_elaborate) { cerr << li->get_fileline() << ": debug: check_for_struct_members: " << "Got collapsed array expr: " << *packed_base << endl; } } long tmp; if (packed_base && eval_as_long(tmp, packed_base)) { off += tmp; delete packed_base; packed_base = 0; } NetESignal*sig = new NetESignal(net); NetExpr *base = packed_base? packed_base : make_const_val(off); NetESelect*sel = new NetESelect(sig, base, use_width, member_type); if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_member: " << "Finally, completed_path=" << completed_path << ", off=" << off << ", use_width=" << use_width << ", base=" << *base << endl; } return sel; } static NetExpr* class_static_property_expression(const LineInfo*li, const netclass_t*class_type, perm_string name) { NetNet*sig = class_type->find_static_property(name); ivl_assert(*li, sig); NetESignal*expr = new NetESignal(sig); expr->set_line(*li); return expr; } NetExpr* PEIdent::elaborate_expr_class_field_(Design*des, NetScope*scope, const symbol_search_results &sr, unsigned expr_wid, unsigned flags) const { const netclass_t *class_type = dynamic_cast(sr.type); const name_component_t comp = sr.path_tail.front(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " << "Ident " << sr.path_head << " look for property " << comp << endl; } if (sr.path_tail.size() > 1) { cerr << get_fileline() << ": sorry: " << "Nested member path not yet supported for class properties." << endl; return nullptr; } ivl_type_t par_type; const NetExpr *par_val = class_type->get_parameter(des, comp.name, par_type); if (par_val) return elaborate_expr_param_(des, scope, par_val, class_type->class_scope(), par_type, expr_wid, flags); int pidx = class_type->property_idx_from_name(comp.name); if (pidx < 0) { cerr << get_fileline() << ": error: " << "Class " << class_type->get_name() << " has no property " << comp.name << "." << endl; des->errors += 1; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": check_for_class_property: " << "Property " << comp.name << " of net " << sr.net->name() << ", context scope=" << scope_path(scope) << endl; } property_qualifier_t qual = class_type->get_prop_qual(pidx); if (qual.test_local() && ! class_type->test_scope_is_method(scope)) { cerr << get_fileline() << ": error: " << "Local property " << class_type->get_prop_name(pidx) << " is not accessible in this context." << " (scope=" << scope_path(scope) << ")" << endl; des->errors += 1; } if (qual.test_static()) { perm_string prop_name = lex_strings.make(class_type->get_prop_name(pidx)); return class_static_property_expression(this, class_type, prop_name); } NetEProperty*tmp = new NetEProperty(sr.net, pidx); tmp->set_line(*this); return tmp; } NetExpr* PECallFunction::elaborate_expr_pkg_(Design*des, NetScope*scope, unsigned flags) const { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr_pkg_: " << "Elaborate " << path_ << " as function in package " << package_->pscope_name() << "." << endl; } // Find the package that contains this definition, and use the // package scope as the search starting point for the function // definition. NetScope*pscope = des->find_package(package_->pscope_name()); ivl_assert(*this, pscope); NetFuncDef*def = des->find_function(pscope, path_); ivl_assert(*this, def); NetScope*dscope = def->scope(); ivl_assert(*this, dscope); if (! check_call_matches_definition_(des, dscope)) return 0; return elaborate_base_(des, scope, dscope, flags); } NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "path_: " << path_ << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "expr_wid: " << expr_wid << endl; if (package_) cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "package_: " << package_->pscope_name() << " at " << package_->get_fileline() << endl; } if (peek_tail_name(path_)[0] == '$') return elaborate_sfunc_(des, scope, expr_wid, flags); NetExpr *result = elaborate_expr_(des, scope, flags); if (!result || !type_is_vectorable(expr_type_)) return result; return pad_to_width(result, expr_wid, signed_flag_, *this); } NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope, unsigned flags) const { if (package_) return elaborate_expr_pkg_(des, scope, flags); flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag // Search for the symbol. This should turn up a scope. symbol_search_results search_results; bool search_flag = symbol_search(this, des, scope, path_, &search_results); if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_flag: " << (search_flag? "true" : "false") << endl; if (search_results.scope) cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_results.scope: " << scope_path(search_results.scope) << endl; if (search_results.net) cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_results.net: " << search_results.net->name() << endl; if (search_results.par_val) cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_results.par_val: " << *search_results.par_val << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_results.path_head: " << search_results.path_head << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "search_results.path_tail: " << search_results.path_tail << endl; } // If the symbol is not found at all... if (!search_flag) { cerr << get_fileline() << ": error: No function named `" << path_ << "' found in this context (" << scope_path(scope) << ")." << endl; des->errors += 1; return 0; } // If the symbol is found, but is not a scope... if (! search_results.is_scope() && !test_function_return_value(search_results)) { // Maybe this is a method of an object? Give it a try. if (!search_results.path_tail.empty()) { NetExpr*tmp = elaborate_expr_method_(des, scope, search_results); if (tmp) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "Elaborated method: " << *tmp << endl; } return tmp; } else { cerr << get_fileline() << ": error: " << "Object " << scope_path(search_results.scope) << "." << search_results.path_head.back() << " has no method \"" << search_results.path_tail << "(...)\"." << endl; des->errors += 1; return 0; } } cerr << get_fileline() << ": error: Object " << search_results.path_head.back() << " in " << scope_path(search_results.scope) << " is not a function." << endl; des->errors += 1; return 0; } // If the symbol is found, but is not a _function_ scope... if (search_results.scope->type() != NetScope::FUNC) { // Not a user defined function. Maybe it is an access // function for a nature? If so then elaborate it that // way. ivl_nature_t access_nature = find_access_function(path_); if (access_nature) return elaborate_access_func_(des, scope, access_nature); // Nothing was found so report this as an error. cerr << get_fileline() << ": error: No function named `" << path_ << "' found in this context (" << scope_path(scope) << ")." << endl; des->errors += 1; return 0; } NetFuncDef*def = search_results.scope->func_def(); ivl_assert(*this, def); ivl_assert(*this, def->scope() == search_results.scope); NetScope*dscope = search_results.scope; // In SystemVerilog, a method calling another method in the current // class needs to be elaborated as a method with an implicit "this" // added. This is a special case. If we detect this case, then // synthesize a new symbol_search_results thast properly reflects the // implicit "this", and treat this item as a class method. if (gn_system_verilog() && (path_.size() == 1)) { const NetScope *c_scope = scope->get_class_scope(); if (c_scope && (c_scope == dscope->get_class_scope())) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "Found a class method calling another method." << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "scope: " << scope_path(scope) << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr: " << "c_scope: " << scope_path(c_scope) << endl; } symbol_search_results use_search_results; use_search_results.scope = scope; use_search_results.path_tail.push_back(search_results.path_head.back()); use_search_results.path_head.push_back(name_component_t(perm_string::literal(THIS_TOKEN))); use_search_results.net = scope->find_signal(perm_string::literal(THIS_TOKEN)); use_search_results.type = use_search_results.net->net_type(); ivl_assert(*this, use_search_results.net); return elaborate_expr_method_(des, scope, use_search_results); } } bool need_const = NEED_CONST & flags; // It is possible to get here before the called function has been // fully elaborated. If this is the case, elaborate it now. This // ensures we know whether or not it is a constant function. if (dscope->elab_stage() < 3) { dscope->need_const_func(need_const || scope->need_const_func()); const PFunction*pfunc = dscope->func_pform(); ivl_assert(*this, pfunc); pfunc->elaborate(des, dscope); } if (dscope->parent() != scope->parent() || !dscope->is_const_func()) { if (scope->need_const_func()) { cerr << get_fileline() << ": error: A function invoked by " "a constant function must be a constant function " "local to the current module." << endl; des->errors += 1; } scope->is_const_func(false); } return elaborate_base_(des, scope, dscope, flags); } NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const { const netdarray_t*darray = dynamic_cast(type); unsigned int width = 1; // Icarus allows a dynamic array to be initialised with a single // elementary value, in that case the expression needs to be evaluated // with the rigth width. if (darray) width = darray->element_type()->packed_width(); return elaborate_expr(des, scope, width, flags); } NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*dscope, unsigned flags) const { if (! check_call_matches_definition_(des, dscope)) return 0; NetFuncDef*def = dscope->func_def(); bool need_const = NEED_CONST & flags; // If this is a constant expression, it is possible that we // are being elaborated before the function definition. If // that's the case, try to elaborate the function as a const // function. if (need_const && ! def->proc()) { if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_base_: " << "Try to elaborate " << scope_path(dscope) << " as constant function." << endl; } dscope->set_elab_stage(2); dscope->need_const_func(true); const PFunction*pfunc = dscope->func_pform(); ivl_assert(*this, pfunc); pfunc->elaborate(des, dscope); } unsigned parms_count = def->port_count(); vector parms (parms_count); if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_base_: " << "Expecting " << parms_count << " argument for function " << scope_path(dscope) << "." << endl; } /* Elaborate the input expressions for the function. This is done in the scope of the function call, and not the scope of the function being called. The scope of the called function is elaborated when the definition is elaborated. */ unsigned parm_errors = elaborate_arguments_(des, scope, def, need_const, parms, 0); if (need_const && !dscope->is_const_func()) { // If this is the first time the function has been called in // a constant context, force the function to be re-elaborated. // This will generate the necessary error messages to allow // the user to diagnose the fault. if (!dscope->need_const_func()) { dscope->set_elab_stage(2); dscope->need_const_func(true); const PFunction*pfunc = dscope->func_pform(); ivl_assert(*this, pfunc); pfunc->elaborate(des, dscope); } cerr << get_fileline() << ": error: `" << dscope->basename() << "' is not a constant function." << endl; des->errors += 1; return 0; } if (parm_errors) return 0; if (def->is_void()) { cerr << get_fileline() << ": error: void function `" << dscope->basename() << "` can not be called in an expression." << endl; des->errors++; return nullptr; } /* Look for the return value signal for the called function. This return value is a magic signal in the scope of the function, that has the name of the function. The function code assigns to this signal to return a value. dscope, in this case, is the scope of the function, so the return value is the name within that scope. */ if (NetNet*res = dscope->find_signal(dscope->basename())) { NetESignal*eres = new NetESignal(res); NetEUFunc*func = new NetEUFunc(scope, dscope, eres, parms, need_const); func->set_line(*this); return func; } cerr << get_fileline() << ": internal error: Unable to locate " "function return value for " << path_ << " in " << dscope->basename() << "." << endl; des->errors += 1; return 0; } /* * Elaborate the arguments of a function or method. The parms vector * is where to place the elaborated expressions, so it an output. The * parm_off is where in the parms vector to start writing * arguments. This value is normally 0, but is 1 if this is a method * so that parms[0] can hold the "this" argument. In this latter case, * def->port(0) will be the "this" argument and should be skipped. */ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope, NetFuncDef*def, bool need_const, vector&parms, unsigned parm_off) const { unsigned parm_errors = 0; unsigned missing_parms = 0; const unsigned parm_count = parms.size() - parm_off; const unsigned actual_count = parms_.size(); /* The parser can't distinguish between a function call with no arguments and a function call with one empty argument, and always supplies one empty argument. Handle the no argument case here. */ if ((parm_count == 0) && (actual_count == 1) && (parms_[0] == 0)) return 0; if (actual_count > parm_count) { cerr << get_fileline() << ": error: " << "Too many arguments (" << actual_count << ", expecting " << parm_count << ")" << " in call to function." << endl; des->errors += 1; } for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { unsigned pidx = idx + parm_off; PExpr*tmp = (idx < actual_count) ? parms_[idx] : 0; if (tmp) { parms[pidx] = elaborate_rval_expr(des, scope, def->port(pidx)->net_type(), tmp, need_const); if (parms[pidx] == 0) { parm_errors += 1; continue; } if (NetEEvent*evt = dynamic_cast (parms[pidx])) { cerr << evt->get_fileline() << ": error: An event '" << evt->event()->name() << "' can not be a user " "function argument." << endl; des->errors += 1; } if (debug_elaborate) cerr << get_fileline() << ": debug:" << " function " << path_ << " arg " << (idx+1) << " argwid=" << parms[pidx]->expr_width() << ": " << *parms[idx] << endl; } else if (def->port_defe(pidx)) { if (! gn_system_verilog()) { cerr << get_fileline() << ": internal error: " << "Found (and using) default function argument " << "requires SystemVerilog." << endl; des->errors += 1; } parms[pidx] = def->port_defe(pidx); } else { missing_parms += 1; parms[pidx] = 0; } } if (missing_parms > 0) { cerr << get_fileline() << ": error: The function " << path_ << " has been called with missing/empty parameters." << endl; cerr << get_fileline() << ": : Verilog doesn't allow " << "passing empty parameters to functions." << endl; parm_errors += 1; des->errors += 1; } return parm_errors; } /* * Look for a method of a given object. The search_results gives us the * information we need to look into this case: The net is the object that will * have its method applied, and the path_tail is the method we are looking * for. The method name is to be interpreted based on the type of the item. So * for example if the object is: * * .x.len() * * Then net refers to object named x, and path_head is ".x". The method is * "len" in path_tail, and if x is a string object, we can handle the case. */ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope, symbol_search_results&search_results) const { if (!gn_system_verilog()) { cerr << get_fileline() << ": error: " << "Enable SystemVerilog to support object methods." << endl; des->errors += 1; return 0; } if (search_results.path_tail.size() > 1) { cerr << get_fileline() << ": sorry: " << "Method name nesting is not supported yet." << endl; cerr << get_fileline() << ": : " << "method path: " << search_results.path_tail << endl; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.scope: " << scope_path(search_results.scope) << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.path_head: " << search_results.path_head << endl; cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.path_tail: " << search_results.path_tail << endl; if (search_results.net) cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.net->data_type: " << search_results.net->data_type() << endl; if (search_results.net && search_results.net->net_type()) cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.net->net_type: " << *search_results.net->net_type() << endl; if (search_results.par_val) cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.par_val: " << *search_results.par_val << endl; if (search_results.type) cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "search_results.type: " << *search_results.type << endl; } if (search_results.par_val && search_results.type) { return elaborate_expr_method_par_(des, scope, search_results); } NetExpr* sub_expr = 0; if (search_results.net) { NetESignal*tmp = new NetESignal(search_results.net); tmp->set_line(*this); sub_expr = tmp; } // Queue variable with a select expression. The type of this expression // is the type of the object that will interpret the method. For // example: // .x[e].len() // If x is a queue of strings, then x[e] is a string. Elaborate the x[e] // expression and pass that to the len() method. if (search_results.net && search_results.net->data_type()==IVL_VT_QUEUE && search_results.path_head.back().index.size()==1) { NetNet*net = search_results.net; const netdarray_t*darray = net->darray_type(); const index_component_t&use_index = search_results.path_head.back().index.back(); ivl_assert(*this, use_index.msb != 0); ivl_assert(*this, use_index.lsb == 0); NetExpr*mux = elab_and_eval(des, scope, use_index.msb, -1, false); if (!mux) return 0; NetESelect*tmp = new NetESelect(sub_expr, mux, darray->element_width(), darray->element_type()); tmp->set_line(*this); sub_expr = tmp; } if (debug_elaborate && sub_expr) { cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "sub_expr->expr_type: " << sub_expr->expr_type() << endl; if (sub_expr->net_type()) cerr << get_fileline() << ": PECallFunction::elaborate_expr_method_: " << "sub_expr->net_type: " << *sub_expr->net_type() << endl; } ivl_assert(*this, sub_expr); // Dynamic array methods. This handles the case that the located signal // is a dynamic array, and there is no index. if (search_results.net && search_results.net->data_type()==IVL_VT_DARRAY && search_results.path_head.back().index.size()==0) { // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; if (method_name == "size") { if (parms_.size() != 0) { cerr << get_fileline() << ": error: size() method " << "takes no arguments" << endl; des->errors += 1; } NetESFunc*sys_expr = new NetESFunc("$size", &netvector_t::atom2u32, 1); sys_expr->set_line(*this); sys_expr->parm(0, sub_expr); return sys_expr; } cerr << get_fileline() << ": error: Method " << method_name << " is not a dynamic array method." << endl; return 0; } // Queue methods. This handles the case that the located signal is a // QUEUE object, and there is a method. if (search_results.net && search_results.net->data_type()==IVL_VT_QUEUE && search_results.path_head.back().index.size()==0) { // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; if (method_name == "size") { if (parms_.size() != 0) { cerr << get_fileline() << ": error: size() method " << "takes no arguments" << endl; des->errors += 1; } NetESFunc*sys_expr = new NetESFunc("$size", &netvector_t::atom2u32, 1); sys_expr->set_line(*this); sys_expr->parm(0, sub_expr); return sys_expr; } const netqueue_t*queue = search_results.net->queue_type(); ivl_type_t element_type = queue->element_type(); if (method_name == "pop_back") { if (parms_.size() != 0) { cerr << get_fileline() << ": error: pop_back() method " << "takes no arguments" << endl; des->errors += 1; } NetESFunc*sys_expr = new NetESFunc("$ivl_queue_method$pop_back", element_type, 1); sys_expr->set_line(*this); sys_expr->parm(0, sub_expr); return sys_expr; } if (method_name == "pop_front") { if (parms_.size() != 0) { cerr << get_fileline() << ": error: pop_front() method " << "takes no arguments" << endl; des->errors += 1; } NetESFunc*sys_expr = new NetESFunc("$ivl_queue_method$pop_front", element_type, 1); sys_expr->set_line(*this); sys_expr->parm(0, sub_expr); return sys_expr; } cerr << get_fileline() << ": error: Method " << method_name << " is not a queue method." << endl; des->errors += 1; return 0; } // Enumeration methods. if (search_results.net && search_results.net->enumeration()) { NetNet*net = search_results.net; const netenum_t*netenum = net->enumeration(); // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; PExpr*tmp = parms_.size() ? parms_[0] : 0; return check_for_enum_methods(this, des, scope, netenum, path_, method_name, sub_expr, tmp, parms_.size()); } // Class methods. Generate function call to the class method. if (sub_expr->expr_type()==IVL_VT_CLASS) { // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; NetNet*net = search_results.net; const netclass_t*class_type = dynamic_cast(search_results.type); ivl_assert(*this, class_type); NetScope*method = class_type->method_from_name(method_name); if (method == 0) { cerr << get_fileline() << ": Error: " << method_name << " is not a method of class " << class_type->get_name() << "." << endl; des->errors += 1; return 0; } NetFuncDef*def = method->func_def(); ivl_assert(*this, def); NetNet*res = method->find_signal(method->basename()); ivl_assert(*this, res); vector parms(def->port_count()); ivl_assert(*this, def->port_count() >= 1); NetESignal*ethis = new NetESignal(net); ethis->set_line(*this); parms[0] = ethis; elaborate_arguments_(des, scope, def, false, parms, 1); NetESignal*eres = new NetESignal(res); NetEUFunc*call = new NetEUFunc(scope, method, eres, parms, false); call->set_line(*this); return call; } // String methods. if (sub_expr->expr_type()==IVL_VT_STRING) { // Get the method name that we are looking for. perm_string method_name = search_results.path_tail.back().name; if (method_name == "len") { NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$len", &netvector_t::atom2u32, 1); sys_expr->parm(0, sub_expr); return sys_expr; } if (method_name == "atoi") { NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$atoi", netvector_t::integer_type(), 1); sys_expr->parm(0, sub_expr); return sys_expr; } if (method_name == "atoreal") { NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$atoreal", &netreal_t::type_real, 1); sys_expr->parm(0, sub_expr); return sys_expr; } if (method_name == "atohex") { NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$atohex", netvector_t::integer_type(), 1); sys_expr->parm(0, sub_expr); return sys_expr; } if (method_name == "substr") { NetESFunc*sys_expr = new NetESFunc("$ivl_string_method$substr", &netstring_t::type_string, 3); sys_expr->set_line(*this); // First argument is the source string. sys_expr->parm(0, sub_expr); ivl_assert(*this, parms_.size() == 2); NetExpr*tmp; tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, parms_[0], false); sys_expr->parm(1, tmp); tmp = elaborate_rval_expr(des, scope, &netvector_t::atom2u32, parms_[1], false); sys_expr->parm(2, tmp); return sys_expr; } cerr << get_fileline() << ": error: Method " << method_name << " is not a string method." << endl; return 0; } return 0; } /* * Handle parameters differently because some must constant elimination is * possible here. We know by definition that the par_val is a constant * expression of some sort (it's a parameter value) and most methods are * stable in the sense that they generate a constant value for a constant input. */ NetExpr* PECallFunction::elaborate_expr_method_par_(Design*des, NetScope*scope, symbol_search_results&search_results) const { ivl_assert(*this, search_results.par_val); ivl_assert(*this, search_results.type); const NetExpr*par_val = search_results.par_val; ivl_type_t par_type = search_results.type; perm_string method_name = search_results.path_tail.back().name; // If the parameter is of type string, then look for the standard string // methods. Return an error if not found. Since we are assured that the // expression is a constant string, it should be able to calculate the // result at compile time. if (dynamic_cast(par_type)) { const NetECString*par_string = dynamic_cast(par_val); ivl_assert(*par_val, par_string); string par_value = par_string->value().as_string(); if (method_name=="len") { NetEConst*use_val = make_const_val(par_value.size()); use_val->set_line(*this); return use_val; } if (method_name == "atoi") { NetEConst*use_val = make_const_val(atoi(par_value.c_str())); use_val->set_line(*this); return use_val; } if (method_name == "atoreal") { NetECReal*use_val = new NetECReal(verireal(par_value.c_str())); use_val->set_line(*this); return use_val; } if (method_name == "atohex") { NetEConst*use_val = make_const_val(strtoul(par_value.c_str(),0,16)); use_val->set_line(*this); return use_val; } // Returning 0 here will cause the caller to print an error // message and increment the error count, so there is no need to // increment des->error_count here. cerr << get_fileline() << ": error: " << "Unknown or unsupport string method: " << method_name << endl; return 0; } // If we haven't figured out what to do with this method by now, // something went wrong. cerr << get_fileline() << ": sorry: Don't know how to handle methods of parameters of type:" << endl; cerr << get_fileline() << ": : " << *par_type << endl; cerr << get_fileline() << ": : in scope " << scope_path(scope) << endl; des->errors += 1; return 0; } unsigned PECastSize::test_width(Design*des, NetScope*scope, width_mode_t&) { ivl_assert(*this, size_); ivl_assert(*this, base_); NetExpr*size_ex = elab_and_eval(des, scope, size_, -1, true); NetEConst*size_ce = dynamic_cast(size_ex); expr_width_ = size_ce ? size_ce->value().as_ulong() : 0; delete size_ex; if (expr_width_ == 0) { cerr << get_fileline() << ": error: Cast size expression " "must be constant and greater than zero." << endl; des->errors += 1; return 0; } width_mode_t tmp_mode = PExpr::SIZED; base_->test_width(des, scope, tmp_mode); if (!type_is_vectorable(base_->expr_type())) { cerr << get_fileline() << ": error: Cast base expression " "must be a vector type." << endl; des->errors += 1; return 0; } expr_type_ = base_->expr_type(); min_width_ = expr_width_; signed_flag_ = base_->has_sign(); return expr_width_; } NetExpr* PECastSize::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_assert(*this, size_); ivl_assert(*this, base_); // A cast behaves exactly like an assignment to a temporary variable, // so the temporary result size may affect the sub-expression width. unsigned cast_width = base_->expr_width(); if (cast_width < expr_width_) cast_width = expr_width_; NetExpr*sub = base_->elaborate_expr(des, scope, cast_width, flags); if (sub == 0) return 0; // Perform the cast. The extension method (zero/sign), if needed, // depends on the type of the base expression. NetExpr*tmp = cast_to_width(sub, expr_width_, base_->has_sign(), *this); // Pad up to the expression width. The extension method (zero/sign) // depends on the type of enclosing expression. return pad_to_width(tmp, expr_wid, signed_flag_, *this); } unsigned PECastType::test_width(Design*des, NetScope*scope, width_mode_t&) { target_type_ = target_->elaborate_type(des, scope); width_mode_t tmp_mode = PExpr::SIZED; base_->test_width(des, scope, tmp_mode); if (const netdarray_t*use_darray = dynamic_cast(target_type_)) { expr_type_ = use_darray->element_base_type(); expr_width_ = use_darray->element_width(); } else if (const netstring_t*use_string = dynamic_cast(target_type_)) { expr_type_ = use_string->base_type(); expr_width_ = 8; } else { expr_type_ = target_type_->base_type(); expr_width_ = target_type_->packed_width(); } min_width_ = expr_width_; signed_flag_ = target_type_->get_signed(); return expr_width_; } NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope, ivl_type_t type, unsigned flags) const { const netdarray_t*darray = NULL; const netvector_t*vector = NULL; // Casting array of vectors to dynamic array type if((darray = dynamic_cast(type)) && (vector = dynamic_cast(darray->element_type()))) { PExpr::width_mode_t mode = PExpr::SIZED; unsigned use_wid = base_->test_width(des, scope, mode); NetExpr*base = base_->elaborate_expr(des, scope, use_wid, NO_FLAGS); assert(vector->packed_width() > 0); assert(base->expr_width() > 0); // Find rounded up length that can fit the whole casted array of vectors int len = base->expr_width() + vector->packed_width() - 1; if(base->expr_width() > (unsigned)vector->packed_width()) { len /= vector->packed_width(); } else { len /= base->expr_width(); } // Number of words in the created dynamic array NetEConst*len_expr = new NetEConst(verinum(len)); return new NetENew(type, len_expr, base); } // Fallback return elaborate_expr(des, scope, (unsigned) 0, flags); } NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag // A cast behaves exactly like an assignment to a temporary variable, // so the temporary result size may affect the sub-expression width. unsigned cast_width = base_->expr_width(); if (type_is_vectorable(base_->expr_type()) && (cast_width < expr_width_)) cast_width = expr_width_; NetExpr*sub = base_->elaborate_expr(des, scope, cast_width, flags); if (sub == 0) return 0; NetExpr*tmp = 0; if (dynamic_cast(target_type_)) { return cast_to_real(sub); } else if (dynamic_cast(target_type_)) { if (base_->expr_type() == IVL_VT_STRING) return sub; // no conversion if (base_->expr_type() == IVL_VT_LOGIC || base_->expr_type() == IVL_VT_BOOL) return sub; // handled by the target as special cases } else if (target_type_ && target_type_->packed()) { switch (target_type_->base_type()) { case IVL_VT_BOOL: tmp = cast_to_int2(sub, expr_width_); break; case IVL_VT_LOGIC: tmp = cast_to_int4(sub, expr_width_); break; default: break; } } if (tmp) { if (tmp == sub) { // We already had the correct base type, so we just need to // fix the size. Note that even if the size is already correct, // we still need to isolate the sub-expression from changes in // the signedness pushed down from the main expression. tmp = cast_to_width(sub, expr_width_, sub->has_sign(), *this); } return pad_to_width(tmp, expr_wid, signed_flag_, *this, target_type_); } cerr << get_fileline() << ": sorry: This cast operation is not yet supported." << endl; des->errors += 1; return 0; } unsigned PECastSign::test_width(Design *des, NetScope *scope, width_mode_t &mode) { ivl_assert(*this, base_); expr_width_ = sign_cast_width(des, scope, *base_, mode); expr_type_ = base_->expr_type(); min_width_ = base_->min_width(); if (!type_is_vectorable(base_->expr_type())) { cerr << get_fileline() << ": error: Cast base expression " "must be a vector type." << endl; des->errors += 1; return 0; } return expr_width_; } NetExpr* PECastSign::elaborate_expr(Design *des, NetScope *scope, unsigned expr_wid, unsigned flags) const { ivl_assert(*this, base_); flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag NetExpr *sub = base_->elaborate_expr(des, scope, expr_width_, flags); if (!sub) return nullptr; return cast_to_width(sub, expr_wid, signed_flag_, *this); } unsigned PEConcat::test_width(Design*des, NetScope*scope, width_mode_t&) { expr_width_ = 0; enum {NO, MAYBE, YES} expr_is_string = MAYBE; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { // Add in the width of this sub-expression. expr_width_ += parms_[idx]->test_width(des, scope, width_modes_[idx]); // If we already know this is not a string, then move on. if (expr_is_string == NO) continue; // If this expression is a string, then the // concatenation is a string until we find a reason to // deny it. if (parms_[idx]->expr_type()==IVL_VT_STRING) { expr_is_string = YES; continue; } // If this is a string literal, then this may yet be a string. if (dynamic_cast (parms_[idx])) continue; // Failed to allow a string result. expr_is_string = NO; } expr_type_ = (expr_is_string==YES) ? IVL_VT_STRING : IVL_VT_LOGIC; signed_flag_ = false; // If there is a repeat expression, then evaluate the constant // value and set the repeat count. if (repeat_ && (scope != tested_scope_)) { NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1, true); if (tmp == 0) return 0; if (tmp->expr_type() == IVL_VT_REAL) { cerr << tmp->get_fileline() << ": error: Concatenation " << "repeat expression can not be REAL." << endl; des->errors += 1; return 0; } NetEConst*rep = dynamic_cast(tmp); if (rep == 0) { cerr << get_fileline() << ": error: " "Concatenation repeat expression is not constant." << endl; cerr << get_fileline() << ": : The expression is: " << *tmp << endl; des->errors += 1; return 0; } if (!rep->value().is_defined()) { cerr << get_fileline() << ": error: Concatenation repeat " << "may not be undefined (" << rep->value() << ")." << endl; des->errors += 1; return 0; } if (rep->value().is_negative()) { cerr << get_fileline() << ": error: Concatenation repeat " << "may not be negative (" << rep->value().as_long() << ")." << endl; des->errors += 1; return 0; } repeat_count_ = rep->value().as_ulong(); tested_scope_ = scope; } expr_width_ *= repeat_count_; min_width_ = expr_width_; return expr_width_; } // Keep track of the concatenation/repeat depth. static int concat_depth = 0; NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { switch (ntype->base_type()) { case IVL_VT_QUEUE: // FIXME: Does a DARRAY support a zero size? case IVL_VT_DARRAY: if (parms_.size() == 0) { NetENull*tmp = new NetENull; tmp->set_line(*this); return tmp; } else { const netdarray_t*array_type = dynamic_cast (ntype); ivl_assert(*this, array_type); // This is going to be an array pattern, so run through the // elements of the expression and elaborate each as if they // are element_type expressions. ivl_type_t elem_type = array_type->element_type(); vector elem_exprs (parms_.size()); for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { NetExpr*tmp = parms_[idx]->elaborate_expr(des, scope, elem_type, flags); elem_exprs[idx] = tmp; } NetEArrayPattern*res = new NetEArrayPattern(array_type, elem_exprs); res->set_line(*this); return res; } default: cerr << get_fileline() << ": internal error: " << "I don't know how to elaborate(ivl_type_t)" << " this expression: " << *this << endl; return 0; } } NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag concat_depth += 1; if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate expr=" << *this << ", expr_wid=" << expr_wid << endl; } if (repeat_count_ == 0 && concat_depth < 2) { cerr << get_fileline() << ": error: Concatenation repeat " << "may not be zero in this context." << endl; des->errors += 1; concat_depth -= 1; return 0; } unsigned wid_sum = 0; unsigned parm_cnt = 0; unsigned parm_errors = 0; std::vector parms(parms_.size()); /* Elaborate all the parameters and attach them to the concat node. */ for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx] == 0) { cerr << get_fileline() << ": error: Missing expression " << (idx+1) << " of concatenation list." << endl; des->errors += 1; continue; } assert(parms_[idx]); unsigned wid = parms_[idx]->expr_width(); NetExpr*ex = parms_[idx]->elaborate_expr(des, scope, wid, flags); if (ex == 0) continue; ex->set_line(*parms_[idx]); eval_expr(ex, -1); if (ex->expr_type() == IVL_VT_REAL) { cerr << ex->get_fileline() << ": error: " << "Concatenation operand can not be real: " << *parms_[idx] << endl; des->errors += 1; parm_errors += 1; continue; } if (width_modes_[idx] != SIZED) { cerr << ex->get_fileline() << ": error: " << "Concatenation operand \"" << *parms_[idx] << "\" has indefinite width." << endl; des->errors += 1; parm_errors += 1; continue; } /* We are going to ignore zero width constants. */ if ((ex->expr_width() == 0) && dynamic_cast(ex)) { parms[idx] = 0; } else { parms[idx] = ex; parm_cnt += 1; } wid_sum += ex->expr_width(); } if (parm_errors) { concat_depth -= 1; return 0; } /* Make the empty concat expression. */ NetEConcat*cncat = new NetEConcat(parm_cnt, repeat_count_, expr_type_); cncat->set_line(*this); /* Remove any zero width constants. */ unsigned off = 0; for (unsigned idx = 0 ; idx < parm_cnt ; idx += 1) { while (parms[off+idx] == 0) off += 1; cncat->set(idx, parms[off+idx]); } if (wid_sum == 0 && expr_type_ != IVL_VT_STRING) { cerr << get_fileline() << ": error: Concatenation/replication " << "may not have zero width in this context." << endl; des->errors += 1; concat_depth -= 1; delete cncat; return 0; } NetExpr*tmp = pad_to_width(cncat, expr_wid, signed_flag_, *this); concat_depth -= 1; return tmp; } /* * Floating point literals are not vectorable. It's not particularly * clear what to do about an actual width to return, but whatever the * width, it is unsigned. * * Absent any better idea, we call all real valued results a width of 1. */ unsigned PEFNumber::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_REAL; expr_width_ = 1; min_width_ = 1; signed_flag_ = true; return expr_width_; } NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, ivl_type_t, unsigned) const { NetECReal*tmp = new NetECReal(*value_); tmp->set_line(*this); return tmp; } NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const { NetECReal*tmp = new NetECReal(*value_); tmp->set_line(*this); return tmp; } bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net, list&prefix_indices) const { unsigned dimensions = net->unpacked_dimensions() + net->packed_dimensions(); switch (net->data_type()) { case IVL_VT_STRING: case IVL_VT_DARRAY: case IVL_VT_QUEUE: dimensions += 1; default: break; } if (path_.back().index.size() > dimensions) { cerr << get_fileline() << ": error: the number of indices (" << path_.back().index.size() << ") is greater than the number of dimensions (" << dimensions << ")." << endl; des->errors += 1; return false; } list index; index = path_.back().index; ivl_assert(*this, index.size() >= net->unpacked_dimensions()); for (size_t idx = 0 ; idx < net->unpacked_dimensions() ; idx += 1) index.pop_front(); return evaluate_index_prefix(des, scope, prefix_indices, index); } bool PEIdent::calculate_bits_(Design*des, NetScope*scope, long&msb, bool&defined) const { defined = true; const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.sel == index_component_t::SEL_BIT); ivl_assert(*this, index_tail.msb && !index_tail.lsb); /* This handles bit selects. In this case, there in one bit select expressions which must be constant. */ NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, -1, true); NetEConst*msb_c = dynamic_cast(msb_ex); if (msb_c == 0) { cerr << index_tail.msb->get_fileline() << ": error: " "Bit select expressions must be constant." << endl; cerr << index_tail.msb->get_fileline() << ": : " "This msb expression violates the rule: " << *index_tail.msb << endl; des->errors += 1; /* Attempt to recover from error. */ msb = 0; } else { if (! msb_c->value().is_defined()) defined = false; msb = msb_c->value().as_long(); } delete msb_ex; return true; } /* * Given that the msb_ and lsb_ are part select expressions, this * function calculates their values. Note that this method does *not* * convert the values to canonical form. */ bool PEIdent::calculate_parts_(Design*des, NetScope*scope, long&msb, long&lsb, bool&defined) const { defined = true; const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.sel == index_component_t::SEL_PART); ivl_assert(*this, index_tail.msb && index_tail.lsb); /* This handles part selects. In this case, there are two bit select expressions, and both must be constant. Evaluate them and pass the results back to the caller. */ NetExpr*lsb_ex = elab_and_eval(des, scope, index_tail.lsb, -1, true); NetEConst*lsb_c = dynamic_cast(lsb_ex); if (lsb_c == 0) { cerr << index_tail.lsb->get_fileline() << ": error: " "Part select expressions must be constant." << endl; cerr << index_tail.lsb->get_fileline() << ": : " "This lsb expression violates the rule: " << *index_tail.lsb << endl; des->errors += 1; /* Attempt to recover from error. */ lsb = 0; } else { if (! lsb_c->value().is_defined()) defined = false; lsb = lsb_c->value().as_long(); } NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, -1, true); NetEConst*msb_c = dynamic_cast(msb_ex); if (msb_c == 0) { cerr << index_tail.msb->get_fileline() << ": error: " "Part select expressions must be constant." << endl; cerr << index_tail.msb->get_fileline() << ": : " "This msb expression violates the rule: " << *index_tail.msb << endl; des->errors += 1; /* Attempt to recover from error. */ msb = lsb; } else { if (! msb_c->value().is_defined()) defined = false; msb = msb_c->value().as_long(); } delete msb_ex; delete lsb_ex; return true; } bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope, unsigned long&wid) const { const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.lsb && index_tail.msb); bool flag = true; /* Calculate the width expression (in the lsb_ position) first. If the expression is not constant, error but guess 1 so we can keep going and find more errors. */ NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1, true); NetEConst*wid_c = dynamic_cast(wid_ex); wid = wid_c ? wid_c->value().as_ulong() : 0; if (wid == 0) { cerr << index_tail.lsb->get_fileline() << ": error: " "Indexed part widths must be constant and greater than zero." << endl; cerr << index_tail.lsb->get_fileline() << ": : " "This part width expression violates the rule: " << *index_tail.lsb << endl; des->errors += 1; flag = false; wid = 1; } delete wid_ex; return flag; } /* * When we know that this is an indexed part select (up or down) this * method calculates the up/down base, as far at it can be calculated. */ NetExpr* PEIdent::calculate_up_do_base_(Design*des, NetScope*scope, bool need_const) const { const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.lsb != 0); ivl_assert(*this, index_tail.msb != 0); NetExpr*tmp = elab_and_eval(des, scope, index_tail.msb, -1, need_const); return tmp; } unsigned PEIdent::test_width_method_(Design*des, NetScope*scope, width_mode_t&) { if (!gn_system_verilog()) return 0; if (path_.size() < 2) return 0; pform_name_t use_path = path_; perm_string member_name = peek_tail_name(path_); use_path.pop_back(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::test_width_method_: " << "Try to find method=" << member_name << " of signal " << use_path << endl; } NetNet*net = 0; ivl_type_t cls_val = 0; const NetExpr*par = 0; ivl_type_t par_type = 0; NetEvent*eve = 0; symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val); if (net == 0) { if (debug_elaborate) cerr << get_fileline() << ": PEIdent::test_width_method_: " << "Only nets can have methods, so give up here." << endl; return 0; } if (/*const netdarray_t*dtype =*/ net->darray_type()) { if (member_name == "size") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = 32; signed_flag_= true; return 32; } } if (const class netqueue_t *queue = net->queue_type()) { if (member_name == "pop_back" || member_name == "pop_front") { expr_type_ = queue->element_base_type(); expr_width_ = queue->element_width(); min_width_ = expr_width_; signed_flag_ = queue->get_signed(); return expr_width_; } } // Look for the enumeration attributes. if (const netenum_t*netenum = net->enumeration()) { if (member_name == "num") { expr_type_ = IVL_VT_BOOL; expr_width_ = 32; min_width_ = 32; signed_flag_= true; return 32; } if ((member_name == "first") || (member_name == "last") || (member_name == "next") || (member_name == "prev")) { expr_type_ = netenum->base_type(); expr_width_ = netenum->packed_width();; min_width_ = expr_width_; signed_flag_ = netenum->get_signed(); return expr_width_; } } return 0; } unsigned PEIdent::test_width_parameter_(const NetExpr *par, width_mode_t&mode) { // The width of an enumeration literal is the width of the // enumeration base. if (const NetEConstEnum*par_enum = dynamic_cast (par)) { const netenum_t*use_enum = par_enum->enumeration(); ivl_assert(*this, use_enum != 0); expr_type_ = use_enum->base_type(); expr_width_ = use_enum->packed_width(); min_width_ = expr_width_; signed_flag_ = par_enum->has_sign(); return expr_width_; } expr_type_ = par->expr_type(); expr_width_ = par->expr_width(); min_width_ = expr_width_; signed_flag_ = par->has_sign(); if (!par->has_width() && (mode < LOSSLESS)) mode = LOSSLESS; return expr_width_; } unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode) { NetScope*use_scope = scope; if (package_) { use_scope = des->find_package(package_->pscope_name()); ivl_assert(*this, use_scope); } if (unsigned tmp = test_width_method_(des, scope, mode)) { return tmp; } symbol_search_results sr; symbol_search(this, des, use_scope, path_, &sr); // If there is a part/bit select expression, then process it // here. This constrains the results no matter what kind the // name is. const name_component_t&name_tail = path_.back(); index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (!name_tail.index.empty()) { const index_component_t&index_tail = name_tail.index.back(); // Skip full array word net selects. if (!sr.net || (name_tail.index.size() > sr.net->unpacked_dimensions())) { use_sel = index_tail.sel; } } unsigned use_width = UINT_MAX; switch (use_sel) { case index_component_t::SEL_NONE: break; case index_component_t::SEL_PART: { long msb, lsb; bool parts_defined; calculate_parts_(des, scope, msb, lsb, parts_defined); if (parts_defined) use_width = 1 + ((msb>lsb) ? (msb-lsb) : (lsb-msb)); else use_width = UINT_MAX; break; } case index_component_t::SEL_IDX_UP: case index_component_t::SEL_IDX_DO: { unsigned long tmp = 0; calculate_up_do_width_(des, scope, tmp); use_width = tmp; break; } case index_component_t::SEL_BIT: { ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb); } // If we have a net in hand, then we can predict what the // slice width will be. If not, then assume it will be a // simple bit select. If the net only has a single dimension // then this is still a simple bit select. if ((sr.net == 0) || (sr.net->packed_dimensions() <= 1)) use_width = 1; break; case index_component_t::SEL_BIT_LAST: if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::test_width: " << "Queue/Darray last index ($)" << endl; } break; default: ivl_assert(*this, 0); } if (const netdarray_t*darray = sr.net ? sr.net->darray_type() : 0) { switch (use_sel) { case index_component_t::SEL_BIT: case index_component_t::SEL_BIT_LAST: expr_type_ = darray->element_base_type(); expr_width_ = darray->element_width(); min_width_ = expr_width_; signed_flag_ = sr.net->get_signed(); break; default: expr_type_ = sr.net->data_type(); expr_width_ = sr.net->vector_width(); min_width_ = expr_width_; signed_flag_ = sr.net->get_signed(); break; } return expr_width_; } // Look for a class property. if (gn_system_verilog() && sr.cls_val) { expr_type_ = sr.cls_val->base_type(); expr_width_ = sr.cls_val->packed_width(); min_width_ = expr_width_; signed_flag_ = sr.cls_val->get_signed(); return expr_width_; } if (use_width != UINT_MAX) { // We have a bit/part select. Account for any remaining dimensions // beyond the indexed dimension. size_t use_depth = name_tail.index.size(); if (sr.net) { if (use_depth >= sr.net->unpacked_dimensions()) use_depth -= sr.net->unpacked_dimensions(); use_width *= sr.net->slice_width(use_depth); } expr_type_ = IVL_VT_LOGIC; // Assume bit/parts selects are logic expr_width_ = use_width; min_width_ = use_width; signed_flag_ = false; return expr_width_; } // The width of a signal expression is the width of the signal. if (sr.net != 0) { // If this net is a struct, the path tail may be // a struct member. If it is, then we know the // width of this identifier by knowing the width // of the member. We don't even need to know // anything about positions in containing arrays. if (sr.net->struct_type() != 0 && !sr.path_tail.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": debug: PEIdent::test_width: " << "Net " << sr.path_head << " is a struct, " << "checking width of member " << sr.path_tail << endl; } const netstruct_t::member_t*mem; unsigned long unused; mem = get_struct_member(this, des, scope, sr.net, peek_tail_name(sr.path_tail), unused); if (mem) { expr_type_ = mem->data_type(); expr_width_ = mem->net_type->packed_width(); min_width_ = expr_width_; signed_flag_ = mem->get_signed(); return expr_width_; } } // Similarly, if this net is an object, the path tail may // be a class property. const netclass_t *class_type = dynamic_cast(sr.type); if (class_type && !sr.path_tail.empty()) { perm_string pname = peek_tail_name(sr.path_tail); ivl_type_t par_type; const NetExpr *par = class_type->get_parameter(des, pname, par_type); if (par) return test_width_parameter_(par, mode); int pidx = class_type->property_idx_from_name(pname); if (pidx >= 0) { ivl_type_t ptype = class_type->get_prop_type(pidx); expr_type_ = ptype->base_type(); expr_width_ = ptype->packed_width(); min_width_ = expr_width_; signed_flag_ = ptype->get_signed(); return expr_width_; } } size_t use_depth = name_tail.index.size(); // Account for unpacked dimensions by assuming that the // unpacked dimensions are consumed first, so subtract // the unpacked dimensions from the dimension depth // useable for making the slice. if (use_depth >= sr.net->unpacked_dimensions()) { use_depth -= sr.net->unpacked_dimensions(); } else { // In this case, we have a slice of an unpacked // array. This likely handled as an array instead // of a slice. Hmm... use_depth = 0; } expr_type_ = sr.net->data_type(); expr_width_ = sr.net->slice_width(use_depth); min_width_ = expr_width_; signed_flag_ = sr.net->get_signed(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::test_width: " << sr.net->name() << " is a net, " << "type=" << expr_type_ << ", width=" << expr_width_ << ", signed_=" << (signed_flag_ ? "true" : "false") << ", use_depth=" << use_depth << ", packed_dimensions=" << sr.net->packed_dimensions() << ", unpacked_dimensions=" << sr.net->unpacked_dimensions() << endl; } return expr_width_; } // The width of a parameter is the width of the parameter value // (as evaluated earlier). if (sr.par_val != 0) return test_width_parameter_(sr.par_val, mode); if (path_.size() == 1 && scope->genvar_tmp.str() && strcmp(peek_tail_name(path_), scope->genvar_tmp) == 0) { verinum val (scope->genvar_tmp_val); expr_type_ = IVL_VT_BOOL; expr_width_ = val.len(); min_width_ = expr_width_; signed_flag_ = true; if (gn_strict_expr_width_flag) { expr_width_ = integer_width; mode = UNSIZED; } else if (mode < LOSSLESS) { mode = LOSSLESS; } return expr_width_; } // Not a net, and not a parameter? Give up on the type, but // set the width to 0. expr_type_ = IVL_VT_NO_TYPE; expr_width_ = 0; min_width_ = 0; signed_flag_ = false; return expr_width_; } NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { bool need_const = NEED_CONST & flags; NetScope*use_scope = scope; if (package_) { use_scope = des->find_package(package_->pscope_name()); ivl_assert(*this, use_scope); } if (NetExpr* tmp = elaborate_expr_class_member_(des, scope, 0, flags)) { return tmp; } symbol_search_results sr; symbol_search(this, des, use_scope, path_, &sr); if (!sr.net) { cerr << get_fileline() << ": error: Unable to bind variable `" << path_ << "' in `" << scope_path(use_scope) << "'" << endl; des->errors++; return nullptr; } NetNet *net = sr.net; if (!sr.path_tail.empty()) { if (net->struct_type()) { return check_for_struct_members(this, des, use_scope, net, sr.path_head.back().index, sr.path_tail); } else if (dynamic_cast(sr.type)) { return elaborate_expr_class_field_(des, scope, sr, 0, flags); } } if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " << "Found net " << net->name() << " for expr " << *this << endl; } ivl_type_t check_type = ntype; if (const netdarray_t*array_type = dynamic_cast (ntype)) { if (array_type->type_compatible(net->net_type())) { NetESignal*tmp = new NetESignal(net); tmp->set_line(*this); return tmp; } // Icarus allows a dynamic array to be initialised with a // single elementary value, so try that next. check_type = array_type->element_type(); } if (! check_type->type_compatible(net->net_type())) { cerr << get_fileline() << ": error: the type of the variable '" << path_ << "' doesn't match the context type." << endl; cerr << get_fileline() << ": : " << "variable type="; if (net->net_type()) net->net_type()->debug_dump(cerr); else cerr << ""; cerr << endl; cerr << get_fileline() << ": : " << "context type="; ivl_assert(*this, ntype); ntype->debug_dump(cerr); cerr << endl; des->errors += 1; return 0; } ivl_assert(*this, ntype->type_compatible(net->net_type())); const name_component_t&use_comp = path_.back(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " << "Typed ident " << net->name() << " with " << use_comp.index.size() << " indices" << " and " << net->unpacked_dimensions() << " expected." << endl; } // FIXME: The real array to queue is failing here. if (net->unpacked_dimensions() != use_comp.index.size()) { cerr << get_fileline() << ": sorry: " << "Net " << net->name() << " expects " << net->unpacked_dimensions() << ", but got " << use_comp.index.size() << "." << endl; des->errors += 1; NetESignal*tmp = new NetESignal(net); tmp->set_line(*this); return tmp; } if (net->unpacked_dimensions() == 0) { NetESignal*tmp = new NetESignal(net); tmp->set_line(*this); return tmp; } // Convert a set of index expressions to a single expression // that addresses the canonical element. listunpacked_indices; list unpacked_indices_const; indices_flags idx_flags; indices_to_expressions(des, scope, this, use_comp.index, net->unpacked_dimensions(), need_const, idx_flags, unpacked_indices, unpacked_indices_const); NetExpr*canon_index = 0; if (idx_flags.invalid) { // Nothing to do } else if (idx_flags.undefined) { cerr << get_fileline() << ": warning: " << "returning 'bx for undefined array access " << net->name() << as_indices(unpacked_indices) << "." << endl; } else if (idx_flags.variable) { ivl_assert(*this, unpacked_indices.size() == net->unpacked_dimensions()); canon_index = normalize_variable_unpacked(net, unpacked_indices); } else { ivl_assert(*this, unpacked_indices_const.size() == net->unpacked_dimensions()); canon_index = normalize_variable_unpacked(net, unpacked_indices_const); } ivl_assert(*this, canon_index); NetESignal*tmp = new NetESignal(net, canon_index); tmp->set_line(*this); return tmp; } /* * Guess that the path_ is the name of a member of a containing class, * and see how that works. If it turns out that the current scope is * not a method, or the name is not in the parent class, then * fail. Otherwise, return a NetEProperty. */ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope, unsigned, unsigned) const { if (!gn_system_verilog()) return 0; if (scope->parent() == 0) return 0; if (path_.size() != 1) return 0; const netclass_t*class_type = find_class_containing_scope(*this, scope); if (class_type == 0) return 0; const name_component_t&name_comp = path_.back(); perm_string member_name = name_comp.name; int pidx = class_type->property_idx_from_name(member_name); if (pidx < 0) return 0; NetScope*scope_method = find_method_containing_scope(*this, scope); ivl_assert(*this, scope_method); NetNet*this_net = scope_method->find_signal(perm_string::literal(THIS_TOKEN)); if (this_net == 0) { cerr << get_fileline() << ": internal error: " << "Unable to find 'this' port of " << scope_path(scope_method) << "." << endl; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr_class_member: " << "Found member " << member_name << " is a member of class " << class_type->get_name() << ", context scope=" << scope_path(scope) << ", type=" << *class_type->get_prop_type(pidx) << ", so making a NetEProperty." << endl; } property_qualifier_t qual = class_type->get_prop_qual(pidx); if (qual.test_local() && ! class_type->test_scope_is_method(scope)) { cerr << get_fileline() << ": error: " << "Local property " << class_type->get_prop_name(pidx) << " is not accessible in this context." << " (scope=" << scope_path(scope) << ")" << endl; des->errors += 1; } if (qual.test_static()) { return class_static_property_expression(this, class_type, member_name); } NetExpr*canon_index = 0; ivl_type_t tmp_type = class_type->get_prop_type(pidx); if (const netuarray_t*tmp_ua = dynamic_cast(tmp_type)) { const std::vector&dims = tmp_ua->static_dimensions(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr_class_member_: " << "Property " << class_type->get_prop_name(pidx) << " has " << dims.size() << " dimensions, " << " got " << name_comp.index.size() << " indices." << endl; } if (dims.size() != name_comp.index.size()) { cerr << get_fileline() << ": error: " << "Got " << name_comp.index.size() << " indices, " << "expecting " << dims.size() << " to index the property " << class_type->get_prop_name(pidx) << "." << endl; des->errors += 1; } else { canon_index = make_canonical_index(des, scope, this, name_comp.index, tmp_ua, false); } } if (debug_elaborate && canon_index) { cerr << get_fileline() << ": PEIdent::elaborate_expr_class_member_: " << "Property " << class_type->get_prop_name(pidx) << " canonical index: " << *canon_index << endl; } NetEProperty*tmp = new NetEProperty(this_net, pidx, canon_index); tmp->set_line(*this); return tmp; } /* * Elaborate an identifier in an expression. The identifier can be a * parameter name, a signal name or a memory name. It can also be a * scope name (Return a NetEScope) but only certain callers can use * scope names. However, we still support it here. * * Function names are not handled here, they are detected by the * parser and are elaborated by PECallFunction. * * The signal name may be escaped, but that affects nothing here. */ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { NetExpr *result; result = elaborate_expr_(des, scope, expr_wid, flags); if (!result || !type_is_vectorable(expr_type_)) return result; return pad_to_width(result, expr_wid, signed_flag_, *this); } NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { ivl_assert(*this, scope); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " << "path_=" << path_ << endl; } // Special case: Detect the special situation that this name // is the name of a variable in the class, and this is a class // method. We sense that this might be the case by noting that // the parent scope of where we are working is a // NetScope::CLASS, the path_ is a single component, and the // name is a property of the class. If that turns out to be // the case, then handle this specially. if (NetExpr*tmp = elaborate_expr_class_member_(des, scope, expr_wid, flags)) { return tmp; } if (path_.size() > 1) { if (NEED_CONST & flags) { cerr << get_fileline() << ": error: A hierarchical reference" " (`" << path_ << "') is not allowed in a constant" " expression." << endl; des->errors += 1; return 0; } if (scope->need_const_func()) { cerr << get_fileline() << ": error: A hierarchical reference" " (`" << path_ << "') is not allowed in a constant" " function." << endl; des->errors += 1; return 0; } scope->is_const_func(false); } // If this identifier is pulled from a package, then switch // the scope we are using. NetScope*use_scope = scope; if (package_) { use_scope = des->find_package(package_->pscope_name()); ivl_assert(*this, use_scope); } // Find the net/parameter/event object that this name refers // to. The path_ may be a scoped path, and may include method // or member name parts. For example, main.a.b.c may refer to // a net called "b" in the scope "main.a" and with a member // named "c". symbol_search() handles this for us. symbol_search_results sr; symbol_search(this, des, use_scope, path_, &sr); // If the identifier name is a parameter name, then return // the parameter value. if (sr.par_val != 0) { if (!sr.path_tail.empty()) { cerr << get_fileline() << ": error: Parameter name " << sr.path_head << " can't have member names (" << sr.path_tail << ")." << endl; des->errors += 1; } return elaborate_expr_param_or_specparam_(des, scope, sr.par_val, sr.scope, sr.type, expr_wid, flags); } // If the identifier names a signal (a variable or a net) // then create a NetESignal node to handle it. if (sr.net != 0) { if (NEED_CONST & flags) { cerr << get_fileline() << ": error: A reference to a wire " "or reg (`" << path_ << "') is not allowed in " "a constant expression." << endl; des->errors += 1; return 0; } if (sr.net->scope()->type() == NetScope::MODULE) { if (scope->need_const_func()) { cerr << get_fileline() << ": error: A reference to a " "non-local wire or reg (`" << path_ << "') is " "not allowed in a constant function." << endl; des->errors += 1; return 0; } scope->is_const_func(false); } // If this is a struct, and there are members in the // member_path, then generate an expression that // reflects the member selection. if (sr.net->struct_type() && !sr.path_tail.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " "Ident " << sr.path_head << " look for struct member " << sr.path_tail << endl; } return check_for_struct_members(this, des, use_scope, sr.net, sr.path_head.back().index, sr.path_tail); } // If this is an array object, and there are members in // the sr.path_tail, check for array properties. if (sr.net->darray_type() && !sr.path_tail.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " "Ident " << sr.path_head << " looking for array property " << sr.path_tail << endl; } ivl_assert(*this, sr.path_tail.size() == 1); const name_component_t member_comp = sr.path_tail.front(); if (member_comp.name == "size") { NetESFunc*fun = new NetESFunc("$size", &netvector_t::atom2s32, 1); fun->set_line(*this); NetESignal*arg = new NetESignal(sr.net); arg->set_line(*sr.net); fun->parm(0, arg); return fun; } else if (member_comp.name == "find") { cerr << get_fileline() << ": sorry: 'find()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "find_index") { cerr << get_fileline() << ": sorry: 'find_index()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "find_first") { cerr << get_fileline() << ": sorry: 'find_first()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "find_first_index") { cerr << get_fileline() << ": sorry: 'find_first_index()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "find_last") { cerr << get_fileline() << ": sorry: 'find_last()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "find_last_index") { cerr << get_fileline() << ": sorry: 'find_last_index()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "min") { cerr << get_fileline() << ": sorry: 'min()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "max") { cerr << get_fileline() << ": sorry: 'max()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "unique") { cerr << get_fileline() << ": sorry: 'unique()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "unique_index") { cerr << get_fileline() << ": sorry: 'unique_index()' " "array location method is not currently " "implemented." << endl; des->errors += 1; return 0; // FIXME: Check this is a real or integral type. } else if (member_comp.name == "sum") { cerr << get_fileline() << ": sorry: 'sum()' " "array reduction method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "product") { cerr << get_fileline() << ": sorry: 'product()' " "array reduction method is not currently " "implemented." << endl; des->errors += 1; return 0; // FIXME: Check this is only an integral type. } else if (member_comp.name == "and") { cerr << get_fileline() << ": sorry: 'and()' " "array reduction method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "or") { cerr << get_fileline() << ": sorry: 'or()' " "array reduction method is not currently " "implemented." << endl; des->errors += 1; return 0; } else if (member_comp.name == "xor") { cerr << get_fileline() << ": sorry: 'xor()' " "array reduction method is not currently " "implemented." << endl; des->errors += 1; return 0; } } // If this is a queue object, and there are members in // the sr.path_tail, check for array properties. if (sr.net->queue_type() && !sr.path_tail.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " << "Ident " << sr.path_head << " looking for queue property " << sr.path_tail << endl; } ivl_assert(*this, sr.path_tail.size() == 1); const name_component_t member_comp = sr.path_tail.front(); const netqueue_t*queue = sr.net->queue_type(); ivl_type_t element_type = queue->element_type(); if (member_comp.name == "pop_back") { NetESFunc*fun = new NetESFunc("$ivl_queue_method$pop_back", element_type, 1); fun->set_line(*this); NetESignal*arg = new NetESignal(sr.net); arg->set_line(*sr.net); fun->parm(0, arg); return fun; } if (member_comp.name == "pop_front") { NetESFunc*fun = new NetESFunc("$ivl_queue_method$pop_front", element_type, 1); fun->set_line(*this); NetESignal*arg = new NetESignal(sr.net); arg->set_line(*sr.net); fun->parm(0, arg); return fun; } } if ((sr.net->data_type() == IVL_VT_STRING) && !sr.path_tail.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " "Ident " << sr.path_head << " looking for string property " << sr.path_tail << endl; } ivl_assert(*this, sr.path_tail.size() == 1); const name_component_t member_comp = sr.path_tail.front(); cerr << get_fileline() << ": sorry: String method '" << member_comp.name << "' currently requires ()." << endl; des->errors += 1; return 0; } if (dynamic_cast(sr.type) && !sr.path_tail.empty()) { return elaborate_expr_class_field_(des, use_scope, sr, expr_wid, flags); } if (sr.net->enumeration() && !sr.path_tail.empty()) { const netenum_t*netenum = sr.net->enumeration(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " "Ident " << sr.path_head << " look for enumeration method " << sr.path_tail << endl; } NetESignal*expr = new NetESignal(sr.net); expr->set_line(*this); ivl_assert(*this, sr.path_tail.size() == 1); const name_component_t member_comp = sr.path_tail.front(); ivl_assert(*this, member_comp.index.empty()); return check_for_enum_methods(this, des, use_scope, netenum, sr.path_head, member_comp.name, expr, NULL, 0); } ivl_assert(*this, sr.path_tail.empty()); NetExpr*tmp = elaborate_expr_net(des, scope, sr.net, sr.scope, expr_wid, flags); if (!tmp) return 0; if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr: " "Expression as net. expr_wid=" << expr_wid << ", tmp->expr_width()=" << tmp->expr_width() << ", tmp=" << *tmp << endl; } return tmp; } // If the identifier is a named event // then create a NetEEvent node to handle it. if (sr.eve != 0) { if (NEED_CONST & flags) { cerr << get_fileline() << ": error: A reference to a named " "event (`" << path_ << "') is not allowed in a " "constant expression." << endl; des->errors += 1; return 0; } if (sr.eve->scope() != scope) { if (scope->need_const_func()) { cerr << get_fileline() << ": error: A reference to a " "non-local named event (`" << path_ << "') is " "not allowed in a constant function." << endl; des->errors += 1; return 0; } scope->is_const_func(false); } if (!sr.path_tail.empty()) { cerr << get_fileline() << ": error: Event name " << sr.path_head << " can't have member names (" << sr.path_tail << ")" << endl; des->errors += 1; } NetEEvent*tmp = new NetEEvent(sr.eve); tmp->set_line(*this); return tmp; } // Hmm... maybe this is a genvar? This is only possible while // processing generate blocks, but then the genvar_tmp will be // set in the scope. if (path_.size() == 1 && scope->genvar_tmp.str() && strcmp(peek_tail_name(path_), scope->genvar_tmp) == 0) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << path_ << " is genvar with value " << scope->genvar_tmp_val << "." << endl; verinum val (scope->genvar_tmp_val, expr_wid); val.has_sign(true); NetEConst*tmp = new NetEConst(val); tmp->set_line(*this); return tmp; } // At this point we've exhausted all the possibilities that // are not scopes. If this is not a system task argument, then // it cannot be a scope name, so give up. if ( !(SYS_TASK_ARG & flags) ) { // I cannot interpret this identifier. Error message. cerr << get_fileline() << ": error: Unable to bind " << ((NEED_CONST & flags) ? "parameter" : "wire/reg/memory") << " `" << path_ << "' in `" << scope_path(scope) << "'" << endl; if (scope->need_const_func()) { cerr << get_fileline() << ": : `" << scope->basename() << "' is being used as a constant function, so may " "only reference local variables." << endl; } des->errors += 1; return 0; } // Finally, if this is a scope name, then return that. Look // first to see if this is a name of a local scope. Failing // that, search globally for a hierarchical name. if ((path_.size() == 1)) { hname_t use_name ( peek_tail_name(path_) ); if (NetScope*nsc = scope->child(use_name)) { NetEScope*tmp = new NetEScope(nsc); tmp->set_line(*this); if (debug_elaborate) cerr << get_fileline() << ": debug: Found scope " << use_name << " in scope " << scope->basename() << endl; return tmp; } } list spath = eval_scope_path(des, scope, path_); ivl_assert(*this, spath.size() == path_.size()); // Try full hierarchical scope name. if (NetScope*nsc = des->find_scope(spath)) { NetEScope*tmp = new NetEScope(nsc); tmp->set_line(*this); if (debug_elaborate) cerr << get_fileline() << ": debug: Found scope " << nsc->basename() << " path=" << path_ << endl; if ( !(SYS_TASK_ARG & flags) ) { cerr << get_fileline() << ": error: Scope name " << nsc->basename() << " not allowed here." << endl; des->errors += 1; } return tmp; } // Try relative scope name. if (NetScope*nsc = des->find_scope(scope, spath)) { NetEScope*tmp = new NetEScope(nsc); tmp->set_line(*this); if (debug_elaborate) cerr << get_fileline() << ": debug: Found scope " << nsc->basename() << " in " << scope_path(scope) << endl; return tmp; } // I cannot interpret this identifier. Error message. cerr << get_fileline() << ": error: Unable to bind wire/reg/memory " "`" << path_ << "' in `" << scope_path(scope) << "'" << endl; des->errors += 1; return 0; } static verinum param_part_select_bits(const verinum&par_val, long wid, long lsv) { verinum result (verinum::Vx, wid, true); for (long idx = 0 ; idx < wid ; idx += 1) { long off = idx + lsv; if (off < 0) continue; else if (off < (long)par_val.len()) result.set(idx, par_val.get(off)); else if (par_val.is_string()) // Pad strings with nulls. result.set(idx, verinum::V0); else if (par_val.has_len()) // Pad sized parameters with X continue; else // Unsized parameters are "infinite" width. result.set(idx, sign_bit(par_val)); } // If the input is a string, and the part select is working on // byte boundaries, then make the result into a string. if (par_val.is_string() && (labs(lsv)%8 == 0) && (wid%8 == 0)) return verinum(result.as_string()); return result; } NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const { const NetEConst*par_ex = dynamic_cast (par); ivl_assert(*this, par_ex); long par_msv, par_lsv; if(! calculate_param_range(*this, par_type, par_msv, par_lsv, par_ex->value().len())) return 0; const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb); ivl_assert(*this, !index_tail.lsb); NetExpr*sel = elab_and_eval(des, scope, index_tail.msb, -1, need_const); if (sel == 0) return 0; if (debug_elaborate) cerr << get_fileline() << ": debug: Calculate bit select " << "[" << *sel << "] from range " << "[" << par_msv << ":" << par_lsv << "]." << endl; perm_string name = peek_tail_name(path_); // Handle the special case that the selection is constant. In this // case, just precalculate the entire constant result. if (NetEConst*sel_c = dynamic_cast (sel)) { // Special case: If the bit select is constant and not fully // defined, then we know that the result must be 1'bx. if (! sel_c->value().is_defined()) { if (warn_ob_select) { cerr << get_fileline() << ": warning: " "Constant undefined bit select [" << sel_c->value() << "] for parameter '" << name << "'." << endl; cerr << get_fileline() << ": : " "Replacing select with a constant 1'bx." << endl; } NetEConst*res = make_const_x(1); res->set_line(*this); return res; } // Calculate the canonical index value. long sel_v = sel_c->value().as_long(); if (par_msv >= par_lsv) sel_v -= par_lsv; else sel_v = par_lsv - sel_v; // Select a bit from the parameter. verinum par_v = par_ex->value(); verinum::V rtn = verinum::Vx; // A constant in range select. if ((sel_v >= 0) && ((unsigned long) sel_v < par_v.len())) { rtn = par_v[sel_v]; // An unsized after select. } else if ((sel_v >= 0) && (! par_v.has_len())) { if (par_v.has_sign()) rtn = par_v[par_v.len()-1]; else rtn = verinum::V0; } else if (warn_ob_select) { cerr << get_fileline() << ": warning: " "Constant bit select [" << sel_c->value().as_long() << "] is "; if (sel_v < 0) cerr << "before "; else cerr << "after "; cerr << name << "["; if (par_v.has_len()) cerr << par_msv; else cerr << ""; cerr << ":" << par_lsv << "]." << endl; cerr << get_fileline() << ": : " "Replacing select with a constant 1'bx." << endl; } NetEConst*res = new NetEConst(verinum(rtn, 1)); res->set_line(*this); return res; } sel = normalize_variable_base(sel, par_msv, par_lsv, 1, true); /* Create a parameter reference for the variable select. */ NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value()); ptmp->set_line(found_in->get_parameter_line_info(name)); NetExpr*tmp = new NetESelect(ptmp, sel, 1); tmp->set_line(*this); return tmp; } NetExpr* PEIdent::elaborate_expr_param_part_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*, ivl_type_t par_type, unsigned expr_wid) const { long msv, lsv; bool parts_defined_flag; bool flag = calculate_parts_(des, scope, msv, lsv, parts_defined_flag); if (!flag) return 0; const NetEConst*par_ex = dynamic_cast (par); ivl_assert(*this, par_ex); long par_msv, par_lsv; if (! calculate_param_range(*this, par_type, par_msv, par_lsv, par_ex->value().len())) return 0; if (! parts_defined_flag) { if (warn_ob_select) { const index_component_t&psel = path_.back().index.back(); perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": warning: " "Undefined part select [" << *(psel.msb) << ":" << *(psel.lsb) << "] for parameter '" << name << "'." << endl; cerr << get_fileline() << ": : " "Replacing select with a constant 'bx." << endl; } verinum val(verinum::Vx, expr_wid, true); NetEConst*tmp = new NetEConst(val); tmp->set_line(*this); return tmp; } // Notice that the par_msv is not used in this function other // than for this test. It is used to tell the direction that // the bits are numbers, so that we can make sure the // direction matches the part select direction. After that, // we only need the par_lsv. if ((msv>lsv && par_msv=par_lsv)) { perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": error: Part select " << name << "[" << msv << ":" << lsv << "] is out of order." << endl; des->errors += 1; return 0; } long wid = 1 + labs(msv-lsv); // Watch out for reversed bit numbering. We're making // the part select from LSB to MSB. long base; if (par_msv < par_lsv) { base = par_lsv - lsv; } else { base = lsv - par_lsv; } if (warn_ob_select) { if (base < 0) { perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": warning: Part select " << "[" << msv << ":" << lsv << "] is selecting " "before the parameter " << name << "["; if (par_ex->value().has_len()) cerr << par_msv; else cerr << ""; cerr << ":" << par_lsv << "]." << endl; cerr << get_fileline() << ": : Replacing " "the out of bound bits with 'bx." << endl; } if (par_ex->value().has_len() && (base+wid > (long)par->expr_width())) { perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": warning: Part select " << name << "[" << msv << ":" << lsv << "] is selecting " "after the parameter " << name << "[" << par_msv << ":" << par_lsv << "]." << endl; cerr << get_fileline() << ": : Replacing " "the out of bound bits with 'bx." << endl; } } verinum result = param_part_select_bits(par_ex->value(), wid, base); NetEConst*result_ex = new NetEConst(result); result_ex->set_line(*this); return result_ex; } static void warn_param_ob(long par_msv, long par_lsv, bool defined, long par_base, unsigned long wid, long pwid, const LineInfo *info, perm_string name, bool up) { long par_max; if (defined) { if (par_msv < par_lsv) par_max = par_lsv-par_msv; else par_max = par_msv-par_lsv; } else { if (pwid < 0) par_max = integer_width; else par_max = pwid; } /* Is this a select before the start of the parameter? */ if (par_base < 0) { cerr << info->get_fileline() << ": warning: " << name << "[" << par_base; if (up) cerr << "+:"; else cerr << "-:"; cerr << wid << "] is selecting before vector." << endl; } /* Is this a select after the end of the parameter? */ if (par_base + (long)wid - 1 > par_max) { cerr << info->get_fileline() << ": warning: " << name << "[" << par_base; if (up) cerr << "+:"; else cerr << "-:"; cerr << wid << "] is selecting after vector." << endl; } } NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const { const NetEConst*par_ex = dynamic_cast (par); ivl_assert(*this, par_ex); long par_msv, par_lsv; if(! calculate_param_range(*this, par_type, par_msv, par_lsv, par_ex->value().len())) return 0; NetExpr*base = calculate_up_do_base_(des, scope, need_const); if (base == 0) return 0; // Use the part select width already calculated by test_width(). unsigned long wid = min_width_; if (debug_elaborate) cerr << get_fileline() << ": debug: Calculate part select " << "[" << *base << "+:" << wid << "] from range " << "[" << par_msv << ":" << par_lsv << "]." << endl; perm_string name = peek_tail_name(path_); // Handle the special case that the base is constant. In this // case, just precalculate the entire constant result. if (NetEConst*base_c = dynamic_cast (base)) { if (! base_c->value().is_defined()) { NetEConst *ex; ex = new NetEConst(verinum(verinum::Vx, wid, true)); ex->set_line(*this); if (warn_ob_select) { cerr << get_fileline() << ": warning: " << name << "['bx+:" << wid << "] is always outside vector." << endl; } return ex; } long lsv = base_c->value().as_long(); long par_base = par_lsv; // Watch out for reversed bit numbering. We're making // the part select from LSB to MSB. if (par_msv < par_lsv) { par_base = lsv; lsv = par_lsv - wid + 1; } if (warn_ob_select) { bool defined = true; // Check to see if the parameter has a defined range. if (par_type == 0) { defined = false; } // Get the parameter values width. long pwid = -1; if (par_ex->has_width()) pwid = par_ex->expr_width()-1; warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid, pwid, this, name, true); } verinum result = param_part_select_bits(par_ex->value(), wid, lsv-par_base); NetEConst*result_ex = new NetEConst(result); result_ex->set_line(*this); return result_ex; } base = normalize_variable_base(base, par_msv, par_lsv, wid, true); /* Create a parameter reference for the variable select. */ NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value()); ptmp->set_line(found_in->get_parameter_line_info(name)); NetExpr*tmp = new NetESelect(ptmp, base, wid, IVL_SEL_IDX_UP); tmp->set_line(*this); return tmp; } NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, bool need_const) const { const NetEConst*par_ex = dynamic_cast (par); ivl_assert(*this, par_ex); long par_msv, par_lsv; if(! calculate_param_range(*this, par_type, par_msv, par_lsv, par_ex->value().len())) return 0; NetExpr*base = calculate_up_do_base_(des, scope, need_const); if (base == 0) return 0; // Use the part select width already calculated by test_width(). unsigned long wid = min_width_; if (debug_elaborate) cerr << get_fileline() << ": debug: Calculate part select " << "[" << *base << "-:" << wid << "] from range " << "[" << par_msv << ":" << par_lsv << "]." << endl; perm_string name = peek_tail_name(path_); // Handle the special case that the base is constant. In this // case, just precalculate the entire constant result. if (NetEConst*base_c = dynamic_cast (base)) { if (! base_c->value().is_defined()) { NetEConst *ex; ex = new NetEConst(verinum(verinum::Vx, wid, true)); ex->set_line(*this); if (warn_ob_select) { cerr << get_fileline() << ": warning: " << name << "['bx-:" << wid << "] is always outside vector." << endl; } return ex; } long lsv = base_c->value().as_long(); long par_base = par_lsv + wid - 1; // Watch out for reversed bit numbering. We're making // the part select from LSB to MSB. if (par_msv < par_lsv) { par_base = lsv; lsv = par_lsv; } if (warn_ob_select) { bool defined = true; // Check to see if the parameter has a defined range. if (par_type == 0) { defined = false; } // Get the parameter values width. long pwid = -1; if (par_ex->has_width()) pwid = par_ex->expr_width()-1; warn_param_ob(par_msv, par_lsv, defined, lsv-par_base, wid, pwid, this, name, false); } verinum result = param_part_select_bits(par_ex->value(), wid, lsv-par_base); NetEConst*result_ex = new NetEConst(result); result_ex->set_line(*this); return result_ex; } base = normalize_variable_base(base, par_msv, par_lsv, wid, false); /* Create a parameter reference for the variable select. */ NetEConstParam*ptmp = new NetEConstParam(found_in, name, par_ex->value()); ptmp->set_line(found_in->get_parameter_line_info(name)); NetExpr*tmp = new NetESelect(ptmp, base, wid, IVL_SEL_IDX_DOWN); tmp->set_line(*this); return tmp; } NetExpr* PEIdent::elaborate_expr_param_or_specparam_(Design*des, NetScope*scope, const NetExpr*par, NetScope*found_in, ivl_type_t par_type, unsigned expr_wid, unsigned flags) const { bool need_const = NEED_CONST & flags; if (need_const && !(ANNOTATABLE & flags)) { perm_string name = peek_tail_name(path_); if (found_in->make_parameter_unannotatable(name)) { cerr << get_fileline() << ": warning: specparam '" << name << "' is being used in a constant expression." << endl; cerr << get_fileline() << ": : This will prevent it " "being annotated at run time." << endl; } } return elaborate_expr_param_(des, scope, par, found_in, par_type, expr_wid, flags); } /* * Handle the case that the identifier is a parameter reference. The * parameter expression has already been located for us (as the par * argument) so we just need to process the sub-expression. */ NetExpr* PEIdent::elaborate_expr_param_(Design*des, NetScope*scope, const NetExpr*par, const NetScope*found_in, ivl_type_t par_type, unsigned expr_wid, unsigned flags) const { bool need_const = NEED_CONST & flags; if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "Parameter: " << path_ << endl; if (par_type) cerr << get_fileline() << ": " << __func__ << ": " << "par_type: " << *par_type << endl; else cerr << get_fileline() << ": " << __func__ << ": " << "par_type: " << endl; } const name_component_t&name_tail = path_.back(); index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (!name_tail.index.empty()) use_sel = name_tail.index.back().sel; if (par->expr_type() == IVL_VT_REAL && use_sel != index_component_t::SEL_NONE) { perm_string name = peek_tail_name(path_); cerr << get_fileline() << ": error: " << "can not select part of real parameter: " << name << endl; des->errors += 1; return 0; } ivl_assert(*this, use_sel != index_component_t::SEL_BIT_LAST); if (use_sel == index_component_t::SEL_BIT) return elaborate_expr_param_bit_(des, scope, par, found_in, par_type, need_const); if (use_sel == index_component_t::SEL_PART) return elaborate_expr_param_part_(des, scope, par, found_in, par_type, expr_wid); if (use_sel == index_component_t::SEL_IDX_UP) return elaborate_expr_param_idx_up_(des, scope, par, found_in, par_type, need_const); if (use_sel == index_component_t::SEL_IDX_DO) return elaborate_expr_param_idx_do_(des, scope, par, found_in, par_type, need_const); NetExpr*tmp = 0; const NetEConstEnum*etmp = dynamic_cast(par); if (etmp) { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Elaborate parameter <" << path_ << "> as enumeration constant." << *etmp << endl; tmp = etmp->dup_expr(); } else { perm_string name = peek_tail_name(path_); /* No bit or part select. Make the constant into a NetEConstParam or NetECRealParam as appropriate. */ const NetEConst*ctmp = dynamic_cast(par); if (ctmp) { verinum cvalue = ctmp->value(); if (cvalue.has_len()) cvalue.has_sign(signed_flag_); cvalue = cast_to_width(cvalue, expr_wid); tmp = new NetEConstParam(found_in, name, cvalue); tmp->cast_signed(signed_flag_); tmp->set_line(*par); if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Elaborate parameter <" << name << "> as constant " << *tmp << endl; } const NetECReal*rtmp = dynamic_cast(par); if (rtmp) { tmp = new NetECRealParam(found_in, name, rtmp->value()); tmp->set_line(*par); if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Elaborate parameter <" << name << "> as constant " << *tmp << endl; } /* The numeric parameter value needs to have the file and line * information for the actual parameter not the expression. */ assert(tmp); tmp->set_line(found_in->get_parameter_line_info(name)); } return tmp; } /* * Handle word selects of vector arrays. */ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope, NetNet*net, NetScope*found_in, unsigned expr_wid, unsigned flags) const { bool need_const = NEED_CONST & flags; const name_component_t&name_tail = path_.back(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_net_word_: " << "expr_wid=" << expr_wid << ", net->get_scalar()==" << (net->get_scalar()?"true":"false") << endl; } // Special case: This is the entire array, and we are a direct // argument of a system task. if (name_tail.index.empty() && (SYS_TASK_ARG & flags)) { NetESignal*res = new NetESignal(net, 0); res->set_line(*this); return res; } if (name_tail.index.empty()) { cerr << get_fileline() << ": error: Array " << path() << " needs an array index here." << endl; des->errors += 1; return 0; } // Make sure there are enough indices to address an array element. if (name_tail.index.size() < net->unpacked_dimensions()) { cerr << get_fileline() << ": error: Array " << path() << " needs " << net->unpacked_dimensions() << " indices," << " but got only " << name_tail.index.size() << "." << endl; des->errors += 1; return 0; } // Evaluate all the index expressions into an // "unpacked_indices" array. listunpacked_indices; list unpacked_indices_const; indices_flags idx_flags; indices_to_expressions(des, scope, this, name_tail.index, net->unpacked_dimensions(), need_const, idx_flags, unpacked_indices, unpacked_indices_const); NetExpr*canon_index = 0; if (idx_flags.invalid) { // Nothing to do. } else if (idx_flags.undefined) { cerr << get_fileline() << ": warning: " << "returning 'bx for undefined array access " << net->name() << as_indices(unpacked_indices) << "." << endl; } else if (idx_flags.variable) { ivl_assert(*this, unpacked_indices.size() == net->unpacked_dimensions()); canon_index = normalize_variable_unpacked(net, unpacked_indices); } else { ivl_assert(*this, unpacked_indices_const.size() == net->unpacked_dimensions()); canon_index = normalize_variable_unpacked(net, unpacked_indices_const); if (canon_index == 0) { cerr << get_fileline() << ": warning: " << "returning 'bx for out of bounds array access " << net->name() << as_indices(unpacked_indices_const) << "." << endl; } } if (canon_index == 0) { NetEConst*xxx = make_const_x(net->vector_width()); xxx->set_line(*this); return xxx; } canon_index->set_line(*this); NetESignal*res = new NetESignal(net, canon_index); res->set_line(*this); // Detect that the word has a bit/part select as well. index_component_t::ctype_t word_sel = index_component_t::SEL_NONE; if (name_tail.index.size() > net->unpacked_dimensions()) word_sel = name_tail.index.back().sel; if (net->get_scalar() && word_sel != index_component_t::SEL_NONE) { cerr << get_fileline() << ": error: can not select part of "; if (res->expr_type() == IVL_VT_REAL) cerr << "real"; else cerr << "scalar"; cerr << " array word: " << net->name() << as_indices(unpacked_indices) << endl; des->errors += 1; delete res; return 0; } if (word_sel == index_component_t::SEL_PART) return elaborate_expr_net_part_(des, scope, res, found_in, expr_wid); if (word_sel == index_component_t::SEL_IDX_UP) return elaborate_expr_net_idx_up_(des, scope, res, found_in, need_const); if (word_sel == index_component_t::SEL_IDX_DO) return elaborate_expr_net_idx_do_(des, scope, res, found_in, need_const); if (word_sel == index_component_t::SEL_BIT) return elaborate_expr_net_bit_(des, scope, res, found_in, need_const); ivl_assert(*this, word_sel == index_component_t::SEL_NONE); return res; } /* * Handle part selects of NetNet identifiers. */ NetExpr* PEIdent::elaborate_expr_net_part_(Design*des, NetScope*scope, NetESignal*net, NetScope*, unsigned expr_wid) const { list prefix_indices; bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices); if (!rc) return 0; long msv, lsv; bool parts_defined_flag; bool flag = calculate_parts_(des, scope, msv, lsv, parts_defined_flag); if (!flag) return 0; /* The indices of part selects are signed integers, so allow negative values. However, the width that they represent is unsigned. Remember that any order is possible, i.e., [1:0], [-4:6], etc. */ unsigned long wid = 1 + labs(msv-lsv); /* But wait... if the part select expressions are not fully defined, then fall back on the tested width. */ if (!parts_defined_flag) { if (warn_ob_select) { const index_component_t&psel = path_.back().index.back(); cerr << get_fileline() << ": warning: " "Undefined part select [" << *(psel.msb) << ":" << *(psel.lsb) << "] for "; if (net->word_index()) cerr << "array word"; else cerr << "vector"; cerr << " '" << net->name(); if (net->word_index()) cerr << "[]"; cerr << "'." << endl; cerr << get_fileline() << ": : " "Replacing select with a constant 'bx." << endl; } NetEConst*tmp = new NetEConst(verinum(verinum::Vx, expr_wid, true)); tmp->set_line(*this); return tmp; } long sb_lsb, sb_msb; if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) { // Here we have a slice that doesn't have enough indices // to get to a single slice. For example: // wire [9:0][5:1] foo // ... foo[4:3] ... // Make this work by finding the indexed slices and // creating a generated slice that spans the whole // range. long loff, moff; unsigned long lwid, mwid; bool lrc, mrc; lrc = net->sig()->sb_to_slice(prefix_indices, lsv, loff, lwid); mrc = net->sig()->sb_to_slice(prefix_indices, msv, moff, mwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << msv << ":" << lsv; cerr << "] exceeds the declared bounds for "; cerr << net->sig()->name(); if (net->sig()->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, lwid == mwid); if (moff > loff) { sb_lsb = loff; sb_msb = moff + mwid - 1; } else { sb_lsb = moff; sb_msb = loff + lwid - 1; } wid = sb_msb - sb_lsb + 1; } else { // This case, the prefix indices are enough to index // down to a single bit/slice. ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size()); sb_lsb = net->sig()->sb_to_idx(prefix_indices, lsv); sb_msb = net->sig()->sb_to_idx(prefix_indices, msv); } if (sb_msb < sb_lsb) { cerr << get_fileline() << ": error: part select " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << msv << ":" << lsv << "] is out of order." << endl; des->errors += 1; //delete lsn; //delete msn; return net; } if (warn_ob_select) { if ((sb_lsb >= (signed) net->vector_width()) || (sb_msb >= (signed) net->vector_width())) { cerr << get_fileline() << ": warning: " "Part select " << "[" << msv << ":" << lsv << "] is selecting after the "; if (net->word_index()) cerr << "array word "; else cerr << "vector "; cerr << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << net->msi() << ":" << net->lsi() << "]." << endl; cerr << get_fileline() << ": : " << "Replacing the out of bound bits with 'bx." << endl; } if ((sb_msb < 0) || (sb_lsb < 0)) { cerr << get_fileline() << ": warning: " "Part select " << "[" << msv << ":" << lsv << "] is selecting before the "; if (net->word_index()) cerr << "array word "; else cerr << "vector "; cerr << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << net->msi() << ":" << net->lsi() << "]." << endl; cerr << get_fileline() << ": : " "Replacing the out of bound bits with 'bx." << endl; } } // If the part select covers exactly the entire // vector, then do not bother with it. Return the // signal itself, casting to unsigned if necessary. if (sb_lsb == 0 && wid == net->vector_width()) { net->cast_signed(false); return net; } // If the part select covers NONE of the vector, then return a // constant X. if ((sb_lsb >= (signed) net->vector_width()) || (sb_msb < 0)) { NetEConst*tmp = make_const_x(wid); tmp->set_line(*this); return tmp; } NetExpr*ex = new NetEConst(verinum(sb_lsb)); NetESelect*ss = new NetESelect(net, ex, wid); ss->set_line(*this); return ss; } /* * Part select indexed up, i.e. net[ +: ] */ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope, NetESignal*net, NetScope*, bool need_const) const { listprefix_indices; bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices); if (!rc) return 0; NetExpr*base = calculate_up_do_base_(des, scope, need_const); // Use the part select width already calculated by test_width(). unsigned long wid = min_width_; // Handle the special case that the base is constant as // well. In this case it can be converted to a conventional // part select. if (NetEConst*base_c = dynamic_cast (base)) { NetExpr*ex; if (base_c->value().is_defined()) { long lsv = base_c->value().as_long(); long rel_base = 0; // Get the signal range. const vector&packed = net->sig()->packed_dims(); if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) { // Here we are selecting one or more sub-arrays. // Make this work by finding the indexed sub-arrays and // creating a generated slice that spans the whole range. unsigned long swid = net->sig()->slice_width(prefix_indices.size()+1); ivl_assert(*this, swid > 0); long loff, moff; unsigned long lwid, mwid; bool lrc, mrc; mrc = net->sig()->sb_to_slice(prefix_indices, lsv, moff, mwid); lrc = net->sig()->sb_to_slice(prefix_indices, lsv+(wid/swid)-1, loff, lwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << lsv << "+:" << (wid/swid); cerr << "] exceeds the declared bounds for "; cerr << net->sig()->name(); if (net->sig()->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, mwid == swid); ivl_assert(*this, lwid == swid); if (moff > loff) { rel_base = loff; } else { rel_base = moff; } } else { long offset = 0; // We want the last range, which is where we work. const netrange_t&rng = packed.back(); if (rng.get_msb() < rng.get_lsb()) { offset = -wid + 1; } rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset; } // If the part select covers exactly the entire // vector, then do not bother with it. Return the // signal itself. if (rel_base == 0 && wid == net->vector_width()) { delete base; net->cast_signed(false); return net; } // Otherwise, make a part select that covers the right // range. ex = new NetEConst(verinum(rel_base)); if (warn_ob_select) { if (rel_base < 0) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << lsv << "+:" << wid << "] is selecting before vector." << endl; } if (rel_base + wid > net->vector_width()) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << lsv << "+:" << wid << "] is selecting after vector." << endl; } } } else { // Return 'bx for an undefined base. ex = new NetEConst(verinum(verinum::Vx, wid, true)); ex->set_line(*this); delete base; if (warn_ob_select) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "['bx+:" << wid << "] is always outside vector." << endl; } return ex; } NetESelect*ss = new NetESelect(net, ex, wid); ss->set_line(*this); delete base; return ss; } ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size()); // Convert the non-constant part select index expression into // an expression that returns a canonical base. base = normalize_variable_part_base(prefix_indices, base, net->sig(), wid, true); NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_UP); ss->set_line(*this); if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate part " << "select base="<< *base << ", wid="<< wid << endl; } return ss; } /* * Part select indexed down, i.e. net[ -: ] */ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope, NetESignal*net, NetScope*, bool need_const) const { listprefix_indices; bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices); if (!rc) return 0; NetExpr*base = calculate_up_do_base_(des, scope, need_const); // Use the part select width already calculated by test_width(). unsigned long wid = min_width_; // Handle the special case that the base is constant as // well. In this case it can be converted to a conventional // part select. if (NetEConst*base_c = dynamic_cast (base)) { NetExpr*ex; if (base_c->value().is_defined()) { long lsv = base_c->value().as_long(); long rel_base = 0; // Get the signal range. const vector&packed = net->sig()->packed_dims(); if (prefix_indices.size()+1 < net->sig()->packed_dims().size()) { // Here we are selecting one or more sub-arrays. // Make this work by finding the indexed sub-arrays and // creating a generated slice that spans the whole range. unsigned long swid = net->sig()->slice_width(prefix_indices.size()+1); ivl_assert(*this, swid > 0); long loff, moff; unsigned long lwid, mwid; bool lrc, mrc; mrc = net->sig()->sb_to_slice(prefix_indices, lsv, moff, mwid); lrc = net->sig()->sb_to_slice(prefix_indices, lsv-(wid/swid)+1, loff, lwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << lsv << "-:" << (wid/swid); cerr << "] exceeds the declared bounds for "; cerr << net->sig()->name(); if (net->sig()->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, mwid == swid); ivl_assert(*this, lwid == swid); if (moff > loff) { rel_base = loff; } else { rel_base = moff; } } else { long offset = 0; // We want the last range, which is where we work. const netrange_t&rng = packed.back(); if (rng.get_msb() > rng.get_lsb()) { offset = -wid + 1; } rel_base = net->sig()->sb_to_idx(prefix_indices, lsv) + offset; } // If the part select covers exactly the entire // vector, then do not bother with it. Return the // signal itself. if (rel_base == (long)(wid-1) && wid == net->vector_width()) { delete base; net->cast_signed(false); return net; } // Otherwise, make a part select that covers the right // range. ex = new NetEConst(verinum(rel_base)); if (warn_ob_select) { if (rel_base < 0) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << lsv << "-:" << wid << "] is selecting before vector." << endl; } if (rel_base + wid > net->vector_width()) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "[" << lsv << "-:" << wid << "] is selecting after vector." << endl; } } } else { // Return 'bx for an undefined base. ex = new NetEConst(verinum(verinum::Vx, wid, true)); ex->set_line(*this); delete base; if (warn_ob_select) { cerr << get_fileline() << ": warning: " << net->name(); if (net->word_index()) cerr << "[]"; cerr << "['bx-:" << wid << "] is always outside vector." << endl; } return ex; } NetESelect*ss = new NetESelect(net, ex, wid); ss->set_line(*this); delete base; return ss; } ivl_assert(*this, prefix_indices.size()+1 == net->sig()->packed_dims().size()); // Convert the non-constant part select index expression into // an expression that returns a canonical base. base = normalize_variable_part_base(prefix_indices, base, net->sig(), wid, false); NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_DOWN); ss->set_line(*this); if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate part " << "select base="<< *base << ", wid="<< wid << endl; } return ss; } NetExpr* PEIdent::elaborate_expr_net_bit_(Design*des, NetScope*scope, NetESignal*net, NetScope*, bool need_const) const { listprefix_indices; bool rc = calculate_packed_indices_(des, scope, net->sig(), prefix_indices); if (!rc) return 0; const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb != 0); ivl_assert(*this, index_tail.lsb == 0); NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1, need_const); if (!mux) return 0; if (const netdarray_t*darray = net->sig()->darray_type()) { // Special case: This is a select of a dynamic // array. Generate a NetESelect and attach it to // the NetESignal. This should be interpreted as // an array word select downstream. if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Bit select of a dynamic array becomes NetESelect." << endl; } NetESelect*res = new NetESelect(net, mux, darray->element_width(), darray->element_type()); res->set_line(*net); return res; } // If the bit select is constant, then treat it similar // to the part select, so that I save the effort of // making a mux part in the netlist. if (NetEConst*msc = dynamic_cast (mux)) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr_net_bit_: " << "mux is constant=" << *msc << ", packed_dims()=" << net->sig()->packed_dims() << ", packed_dims().size()=" << net->sig()->packed_dims().size() << ", prefix_indices.size()=" << prefix_indices.size() << endl; } // Special case: The bit select expression is constant // x/z. The result of the expression is 1'bx. if (! msc->value().is_defined()) { if (warn_ob_select) { cerr << get_fileline() << ": warning: " "Constant bit select [" << msc->value() << "] is undefined for "; if (net->word_index()) cerr << "array word"; else cerr << "vector"; cerr << " '" << net->name(); if (net->word_index()) cerr << "[]"; cerr << "'." << endl; cerr << get_fileline() << ": : " << "Replacing select with a constant 1'bx." << endl; } // FIXME: Should I be using slice_width() here? NetEConst*tmp = make_const_x(1); tmp->set_line(*this); delete mux; return tmp; } long msv = msc->value().as_long(); const vector& sig_packed = net->sig()->packed_dims(); if (prefix_indices.size()+2 <= sig_packed.size()) { // Special case: this is a slice of a multi-dimensional // packed array. For example: // reg [3:0][7:0] x; // ... x[2] ... // This shows up as the prefix_indices being too short // for the packed dimensions of the vector. What we do // here is convert to a "slice" of the vector. unsigned long lwid; long idx; rc = net->sig()->sb_to_slice(prefix_indices, msv, idx, lwid); ivl_assert(*this, rc); // Make an expression out of the index NetEConst*idx_c = new NetEConst(verinum(idx)); idx_c->set_line(*net); NetESelect*res = new NetESelect(net, idx_c, lwid); res->set_line(*net); return res; } if (net->sig()->data_type()==IVL_VT_STRING && (msv < 0)) { // Special case: This is a constant bit select of // a string, and the index is < 0. For example: // string foo; // ... foo[-1] ... // This is known to be 8'h00. NetEConst*tmp = make_const_0(8); tmp->set_line(*this); delete mux; return tmp; } if (net->sig()->data_type()==IVL_VT_STRING) { // Special case: This is a select of a string // variable. Generate a NetESelect and attach it // to the NetESignal. This should be interpreted // as a character select downstream. if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Bit select of string becomes NetESelect." << endl; } NetESelect*res = new NetESelect(net, mux, 8); res->set_line(*net); return res; } long idx = net->sig()->sb_to_idx(prefix_indices,msv); if (idx >= (long)net->vector_width() || idx < 0) { /* The bit select is out of range of the vector. This is legal, but returns a constant 1'bx value. */ if (warn_ob_select) { cerr << get_fileline() << ": warning: " "Constant bit select [" << msv << "] is "; if (idx < 0) cerr << "before "; else cerr << "after "; if (net->word_index()) cerr << "array word "; else cerr << "vector "; cerr << net->name(); if (net->word_index()) cerr << "[]"; cerr << net->sig()->packed_dims() << "." << endl; cerr << get_fileline() << ": : " << "Replacing select with a constant 1'bx." << endl; } NetEConst*tmp = make_const_x(1); tmp->set_line(*this); delete mux; return tmp; } // If the vector is only one bit, we are done. The // bit select will return the scalar itself. if (net->vector_width() == 1) return net; if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr_net_bit_: " << "Make bit select idx=" << idx << endl; } // Make an expression out of the index NetEConst*idx_c = new NetEConst(verinum(idx)); idx_c->set_line(*net); // Make a bit select with the canonical index NetESelect*res = new NetESelect(net, idx_c, 1); res->set_line(*net); return res; } const vector& sig_packed = net->sig()->packed_dims(); if (prefix_indices.size()+2 <= sig_packed.size()) { // Special case: this is a slice of a multi-dimensional // packed array. For example: // reg [3:0][7:0] x; // x[2] = ... // This shows up as the prefix_indices being too short // for the packed dimensions of the vector. What we do // here is convert to a "slice" of the vector. unsigned long lwid; mux = normalize_variable_slice_base(prefix_indices, mux, net->sig(), lwid); mux->set_line(*net); // Make a PART select with the canonical index NetESelect*res = new NetESelect(net, mux, lwid); res->set_line(*net); return res; } if (net->sig()->data_type() == IVL_VT_STRING) { // Special case: This is a select of a string. // This should be interpreted as a byte select. if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Bit select of a string becomes NetESelect." << endl; } NetESelect*res = new NetESelect(net, mux, 8); res->set_line(*net); return res; } // Non-constant bit select? punt and make a subsignal // device to mux the bit in the net. This is a fairly // complicated task because we need to generate // expressions to convert calculated bit select // values to canonical values that are used internally. mux = normalize_variable_bit_base(prefix_indices, mux, net->sig()); NetESelect*ss = new NetESelect(net, mux, 1); ss->set_line(*this); return ss; } NetExpr* PEIdent::elaborate_expr_net_bit_last_(Design*, NetScope*, NetESignal*net, NetScope* /* found_in */, bool need_const) const { if (need_const) { cerr << get_fileline() << ": error: " << "Expression with \"[$]\" is not constant." << endl; return 0; } unsigned use_width = 1; ivl_type_t use_type = 0; if (const netdarray_t*darray = net->sig()->darray_type()) { use_width = darray->element_width(); use_type = darray->element_type(); } NetELast*mux = new NetELast(net->sig()); mux->set_line(*this); NetESelect*ss = new NetESelect(net, mux, use_width, use_type); ss->set_line(*this); return ss; } NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope, NetNet*net, NetScope*found_in, unsigned expr_wid, unsigned flags) const { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_expr_net: " << "net=" << net->name() << ", net->unpacked_dimensions()=" << net->unpacked_dimensions() << ", net->get_scalar()=" << (net->get_scalar()?"true":"false") << ", net->net_type()=" << *net->net_type() << endl; } if (net->unpacked_dimensions() > 0) return elaborate_expr_net_word_(des, scope, net, found_in, expr_wid, flags); bool need_const = NEED_CONST & flags; NetESignal*node = new NetESignal(net); node->set_line(*this); index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (! path_.back().index.empty()) use_sel = path_.back().index.back().sel; if (net->get_scalar() && use_sel != index_component_t::SEL_NONE) { cerr << get_fileline() << ": error: can not select part of "; if (node->expr_type() == IVL_VT_REAL) cerr << "real: "; else cerr << "scalar: "; cerr << net->name() << endl; des->errors += 1; return 0; } list prefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, path_.back().index); if (!rc) return 0; // If this is a part select of a signal, then make a new // temporary signal that is connected to just the // selected bits. The lsb_ and msb_ expressions are from // the foo[msb:lsb] expression in the original. if (use_sel == index_component_t::SEL_PART) return elaborate_expr_net_part_(des, scope, node, found_in, expr_wid); if (use_sel == index_component_t::SEL_IDX_UP) return elaborate_expr_net_idx_up_(des, scope, node, found_in, need_const); if (use_sel == index_component_t::SEL_IDX_DO) return elaborate_expr_net_idx_do_(des, scope, node, found_in, need_const); if (use_sel == index_component_t::SEL_BIT) return elaborate_expr_net_bit_(des, scope, node, found_in, need_const); if (use_sel == index_component_t::SEL_BIT_LAST) return elaborate_expr_net_bit_last_(des, scope, node, found_in, need_const); // It's not anything else, so this must be a simple identifier // expression with no part or bit select. Return the signal // itself as the expression. assert(use_sel == index_component_t::SEL_NONE); return node; } unsigned PENewArray::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_DARRAY; expr_width_ = 1; min_width_ = 1; signed_flag_= false; return 1; } NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { // Elaborate the size expression. width_mode_t mode = LOSSLESS; unsigned use_wid = size_->test_width(des, scope, mode); NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags); NetExpr*init_val = 0; if (dynamic_cast (init_)) { // Special case: the initial value expression is an // array_pattern. Elaborate the expression like the // r-value to an assignment to array. init_val = init_->elaborate_expr(des, scope, ntype, flags); } else if (init_) { // Regular case: The initial value is an // expression. Elaborate the expression as an element // type. The run-time will assign this value to each element. const netarray_t*array_type = dynamic_cast (ntype); init_val = init_->elaborate_expr(des, scope, array_type, flags); } NetENew*tmp = new NetENew(ntype, size, init_val); tmp->set_line(*this); return tmp; } NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const { cerr << get_fileline() << ": error: The new array constructor may " "only be used in an assignment to a dynamic array." << endl; des->errors += 1; return 0; } unsigned PENewClass::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_CLASS; expr_width_ = 1; min_width_ = 1; signed_flag_= false; return 1; } /* * This elaborates the constructor for a class. This arranges for the * call of class constructor, if present, and also * initializers in front of an explicit constructor. * * The derived argument is the type of the class derived from the * current one. This is used to get chained constructor arguments, if necessary. */ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope, const netclass_t*ctype, NetExpr*obj, unsigned /*flags*/) const { ivl_assert(*this, ctype); // If there is an initializer function, then pass the object // through that function first. Note that the initializer // function has no arguments other than the object itself. if (NetScope*new1_scope = ctype->method_from_name(perm_string::literal("new@"))) { NetFuncDef*def1 = new1_scope->func_def(); ivl_assert(*this, def1); ivl_assert(*this, def1->port_count()==1); vector parms1 (1); parms1[0] = obj; // The return value of the initializer is the "this" // variable, instead of the "new&" scope name. NetNet*res1 = new1_scope->find_signal(perm_string::literal(THIS_TOKEN)); ivl_assert(*this, res1); NetESignal*eres = new NetESignal(res1); NetEUFunc*tmp = new NetEUFunc(scope, new1_scope, eres, parms1, true); tmp->set_line(*this); obj = tmp; } NetScope*new_scope = ctype->method_from_name(perm_string::literal("new")); if (new_scope == 0) { // No constructor. if (parms_.size() > 0) { cerr << get_fileline() << ": error: " << "Class " << ctype->get_name() << " has no constructor, but you passed " << parms_.size() << " arguments to the new operator." << endl; des->errors += 1; } return obj; } NetFuncDef*def = new_scope->func_def(); if (def == 0) { cerr << get_fileline() << ": internal error: " << "Scope " << scope_path(new_scope) << " is missing constructor definition." << endl; des->errors += 1; } ivl_assert(*this, def); // Are there too many arguments passed to the function. If so, // generate an error message. The case of too few arguments // will be handled below, when we run out of arguments. if ((parms_.size()+1) > def->port_count()) { cerr << get_fileline() << ": error: Parm count mismatch" << " passing " << parms_.size() << " arguments " << " to constructor expecting " << (def->port_count()-1) << " arguments." << endl; des->errors += 1; } vector parms (def->port_count()); parms[0] = obj; int missing_parms = 0; for (size_t idx = 1 ; idx < parms.size() ; idx += 1) { // While there are default arguments, check them. if (idx <= parms_.size() && parms_[idx-1]) { PExpr*tmp = parms_[idx-1]; parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->net_type(), tmp, false); // NOTE: if elaborate_rval_expr fails, it will return a // nullptr, but it will also increment des->errors so there // is nothing we need to do here. continue; } // Ran out of explicit arguments. Is there a default // argument we can use? if (NetExpr*tmp = def->port_defe(idx)) { parms[idx] = tmp; continue; } // If we run out of passed expressions, and there is no // default value for this port, then we will need to // report an error that we are missing parameters. missing_parms += 1; parms[idx] = 0; } if (missing_parms > 0) { cerr << get_fileline() << ": error: The " << scope_path(new_scope) << " constructor call is missing arguments." << endl; des->errors += 1; } // The return value for the constructor is actually the "this" // variable, instead of the "new" scope name. NetNet*res = new_scope->find_signal(perm_string::literal(THIS_TOKEN)); ivl_assert(*this, res); NetESignal*eres = new NetESignal(res); NetEUFunc*con = new NetEUFunc(scope, new_scope, eres, parms, true); con->set_line(*this); return con; } NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { // Find the constructor for the class. If there is no // constructor then the result of this expression is the // allocation alone. const netclass_t*ctype = dynamic_cast (ntype); if (!ctype) { cerr << get_fileline() << ": error: class new not allowed here. " << "Left-hand side is not of class type." << endl; des->errors++; return 0; } if (class_type_) { ivl_type_t elab_class_type = class_type_->elaborate_type(des, scope); ctype = dynamic_cast (elab_class_type); if (!ctype) { cerr << get_fileline() << ": error: Incompatible type in" << " typed constructor call.\n" << get_fileline() << ": : Constructor type `" << *elab_class_type << "` is not a class type." << endl; des->errors++; return nullptr; } if (!ntype->type_compatible(ctype)) { cerr << get_fileline() << ": error: Incompatible type in" << " typed constructor call.\n" << get_fileline() << ": : Constructor type `" << *ctype << "` is not compatible with the target type `" << *ntype << "`." << endl; des->errors++; return nullptr; } } if (ctype->is_virtual()) { cerr << get_fileline() << ": error: " << "Can not create object of virtual class `" << ctype->get_name() << "`." << endl; des->errors++; return 0; } NetExpr*obj = new NetENew(ctype); obj->set_line(*this); obj = elaborate_expr_constructor_(des, scope, ctype, obj, flags); return obj; } unsigned PENewCopy::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_CLASS; expr_width_ = 1; min_width_ = 1; signed_flag_= false; return 1; } NetExpr* PENewCopy::elaborate_expr(Design*des, NetScope*scope, ivl_type_t obj_type, unsigned) const { NetExpr*copy_arg = src_->elaborate_expr(des, scope, obj_type, 0); if (copy_arg == 0) return 0; NetENew*obj_new = new NetENew(obj_type); obj_new->set_line(*this); NetEShallowCopy*copy = new NetEShallowCopy(obj_new, copy_arg); copy->set_line(*this); return copy; } /* * A "null" expression represents class objects/handles. This brings * up a ton of special cases, but we handle it here by setting the * expr_type_ and expr_width_ to fixed values. */ unsigned PENull::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_CLASS; expr_width_ = 1; min_width_ = 1; signed_flag_ = false; return expr_width_; } NetExpr* PENull::elaborate_expr(Design*, NetScope*, ivl_type_t, unsigned) const { NetENull*tmp = new NetENull; tmp->set_line(*this); return tmp; } NetExpr* PENull::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const { NetENull*tmp = new NetENull; tmp->set_line(*this); return tmp; } unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode) { expr_type_ = IVL_VT_LOGIC; expr_width_ = value_->len(); min_width_ = expr_width_; signed_flag_ = value_->has_sign(); if (!value_->has_len() && !value_->is_single()) { if (gn_strict_expr_width_flag) { expr_width_ = integer_width; mode = UNSIZED; } else if (mode < LOSSLESS) { if (expr_width_ < integer_width) { expr_width_ = integer_width; if (mode < UNSIZED) mode = UNSIZED; } else { mode = LOSSLESS; } } } if (debug_elaborate) { cerr << get_fileline() << ": PENumber::test_width: " << "Value=" << *value_ << ", width=" << expr_width_ << ", output mode=" << width_mode_name(mode) << endl; } return expr_width_; } NetExpr* PENumber::elaborate_expr(Design*, NetScope*, ivl_type_t ntype, unsigned) const { if (debug_elaborate) { cerr << get_fileline() << ": PENumber::elaborate_expr: " << "expression: " << *this << endl; if (ntype) cerr << get_fileline() << ": PENumber::elaborate_expr: " << "ntype=" << *ntype << endl; } // Icarus allows dynamic arrays to be initialised with a single value. if (const netdarray_t*array_type = dynamic_cast (ntype)) ntype = array_type->element_type(); // Special case: If the context type is REAL, then cast the // vector value to a real and return a NetECReal. if (ntype->base_type() == IVL_VT_REAL) { verireal val (value_->as_long()); NetECReal*tmp = new NetECReal(val); tmp->set_line(*this); return tmp; } verinum use_val = value(); use_val.has_sign( ntype->get_signed() ); use_val = cast_to_width(use_val, ntype->packed_width()); NetEConst*tmp = new NetEConst(use_val); tmp->set_line(*this); return tmp; } NetEConst* PENumber::elaborate_expr(Design*, NetScope*, unsigned expr_wid, unsigned) const { assert(value_); verinum val = *value_; if (val.has_len()) val.has_sign(signed_flag_); val = cast_to_width(val, expr_wid); NetEConst*tmp = new NetEConst(val); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } unsigned PEString::test_width(Design*, NetScope*, width_mode_t&) { expr_type_ = IVL_VT_BOOL; expr_width_ = text_ ? verinum(text_).len() : 0; min_width_ = expr_width_; signed_flag_ = false; return expr_width_; } NetEConst* PEString::elaborate_expr(Design*, NetScope*, ivl_type_t, unsigned) const { NetECString*tmp = new NetECString(value()); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } /* * When the expression is being elaborated with a width, then we are trying to * make a vector, so create a NetEConst with the basic types. */ NetEConst* PEString::elaborate_expr(Design*, NetScope*, unsigned expr_wid, unsigned) const { verinum val(value()); val = pad_to_width(val, expr_wid); NetEConst*tmp = new NetEConst(val); tmp->cast_signed(signed_flag_); tmp->set_line(*this); return tmp; } unsigned PETernary::test_width(Design*des, NetScope*scope, width_mode_t&mode) { // The condition of the ternary is self-determined, so // we will test its width when we elaborate it. // Test the width of the true and false clauses. unsigned tru_width = tru_->test_width(des, scope, mode); width_mode_t saved_mode = mode; unsigned fal_width = fal_->test_width(des, scope, mode); // If the width mode changed, retest the true clause, as it // may choose a different width if it is in a lossless context. if ((mode >= LOSSLESS) && (saved_mode < LOSSLESS)) { tru_width = tru_->test_width(des, scope, mode); } // If either of the alternatives is IVL_VT_REAL, then the // expression as a whole is IVL_VT_REAL. Otherwise, if either // of the alternatives is IVL_VT_LOGIC, then the expression as // a whole is IVL_VT_LOGIC. The fallback assumes that the // types are the same and we take that. ivl_variable_type_t tru_type = tru_->expr_type(); ivl_variable_type_t fal_type = fal_->expr_type(); if (tru_type == IVL_VT_REAL || fal_type == IVL_VT_REAL) { expr_type_ = IVL_VT_REAL; } else if (tru_type == IVL_VT_LOGIC || fal_type == IVL_VT_LOGIC) { expr_type_ = IVL_VT_LOGIC; } else { expr_type_ = tru_type; } if (expr_type_ == IVL_VT_REAL) { expr_width_ = 1; min_width_ = 1; signed_flag_ = true; } else { expr_width_ = max(tru_width, fal_width); min_width_ = max(tru_->min_width(), fal_->min_width()); signed_flag_ = tru_->has_sign() && fal_->has_sign(); // If the alternatives are different types, the expression // is forced to unsigned. In this case the lossless width // calculation is unreliable and we need to make sure the // final expression width is at least integer_width. if ((mode == LOSSLESS) && (tru_->has_sign() != fal_->has_sign())) mode = UPSIZE; } if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Ternary expression type=" << expr_type_ << ", width=" << expr_width_ << " (tru_type=" << tru_type << ", fal_type=" << fal_type << ")" << endl; return fix_width_(mode); } bool NetETernary::test_operand_compat(ivl_variable_type_t l, ivl_variable_type_t r) { if (l == IVL_VT_LOGIC && r == IVL_VT_BOOL) return true; if (l == IVL_VT_BOOL && r == IVL_VT_LOGIC) return true; if (l == IVL_VT_REAL && (r == IVL_VT_LOGIC || r == IVL_VT_BOOL)) return true; if (r == IVL_VT_REAL && (l == IVL_VT_LOGIC || l == IVL_VT_BOOL)) return true; if (l == r) return true; return false; } /* * Elaborate the Ternary operator. I know that the expressions were * parsed so I can presume that they exist, and call elaboration * methods. If any elaboration fails, then give up and return 0. */ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_assert(*this, expr_); ivl_assert(*this, tru_); ivl_assert(*this, fal_); // Elaborate and evaluate the condition expression. Note that // it is always self-determined. NetExpr*con = elab_and_eval(des, scope, expr_, -1, NEED_CONST & flags); if (con == 0) return 0; /* Make sure the condition expression reduces to a single bit. */ con = condition_reduce(con); // Verilog doesn't say that we must do short circuit evaluation // of ternary expressions, but it doesn't disallow it. if (NetEConst*tmp = dynamic_cast (con)) { verinum cval = tmp->value(); ivl_assert(*this, cval.len()==1); // Condition is constant TRUE, so we only need the true clause. if (cval.get(0) == verinum::V1) { if (debug_elaborate) cerr << get_fileline() << ": debug: Short-circuit " "elaborate TRUE clause of ternary." << endl; // Evaluate the alternate expression to find any errors. NetExpr*dmy = elab_and_eval_alternative_(des, scope, fal_, expr_wid, flags, true); delete dmy; delete con; return elab_and_eval_alternative_(des, scope, tru_, expr_wid, flags, true); } // Condition is constant FALSE, so we only need the // false clause. if (cval.get(0) == verinum::V0) { if (debug_elaborate) cerr << get_fileline() << ": debug: Short-circuit " "elaborate FALSE clause of ternary." << endl; // Evaluate the alternate expression to find any errors. NetExpr*dmy = elab_and_eval_alternative_(des, scope, tru_, expr_wid, flags, true); delete dmy; delete con; return elab_and_eval_alternative_(des, scope, fal_, expr_wid, flags, true); } // X and Z conditions need to blend both results, so we // can't short-circuit. } NetExpr*tru = elab_and_eval_alternative_(des, scope, tru_, expr_wid, flags, false); if (tru == 0) { delete con; return 0; } NetExpr*fal = elab_and_eval_alternative_(des, scope, fal_, expr_wid, flags, false); if (fal == 0) { delete con; delete tru; return 0; } if (! NetETernary::test_operand_compat(tru->expr_type(), fal->expr_type())) { cerr << get_fileline() << ": error: Data types " << tru->expr_type() << " and " << fal->expr_type() << " of ternary" << " do not match." << endl; des->errors += 1; return 0; } NetETernary*res = new NetETernary(con, tru, fal, expr_wid, signed_flag_); res->set_line(*this); return res; } /* * When elaborating the true or false alternative expression of a * ternary, take into account the overall expression type. If the type * is not vectorable, then the alternative expression is evaluated as * self-determined. */ NetExpr* PETernary::elab_and_eval_alternative_(Design*des, NetScope*scope, PExpr*expr, unsigned expr_wid, unsigned flags, bool short_cct) const { int context_wid = expr_wid; if (type_is_vectorable(expr->expr_type()) && !type_is_vectorable(expr_type_)) { expr_wid = expr->expr_width(); context_wid = -1; } else { expr->cast_signed(signed_flag_); } NetExpr*tmp = expr->elaborate_expr(des, scope, expr_wid, flags); if (tmp == 0) return 0; if (short_cct && (expr_type_ == IVL_VT_REAL) && (expr->expr_type() != IVL_VT_REAL)) tmp = cast_to_real(tmp); eval_expr(tmp, context_wid); return tmp; } /* * A typename expression is only legal in very narrow cases. This is * just a placeholder. */ unsigned PETypename::test_width(Design*des, NetScope*, width_mode_t&) { cerr << get_fileline() << ": error: " << "Type names are not valid expressions here." << endl; des->errors += 1; expr_type_ = IVL_VT_NO_TYPE; expr_width_ = 1; min_width_ = 1; signed_flag_ = false; return expr_width_; } NetExpr*PETypename::elaborate_expr(Design*des, NetScope*, ivl_type_t, unsigned) const { cerr << get_fileline() << ": error: Type name not a valid expression here." << endl; des->errors += 1; return 0; } unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode) { // Evaluate the expression width to get the correct type information expr_width_ = expr_->test_width(des, scope, mode); if (expr_->expr_type() == IVL_VT_CLASS) { cerr << get_fileline() << ": error: " << "Class/null is not allowed with the '" << human_readable_op(op_) << "' operator." << endl; des->errors += 1; } switch (op_) { case '&': // Reduction AND case '|': // Reduction OR case '^': // Reduction XOR case 'A': // Reduction NAND (~&) case 'N': // Reduction NOR (~|) case 'X': // Reduction NXOR (~^) case '!': { width_mode_t sub_mode = SIZED; unsigned sub_width = expr_->test_width(des, scope, sub_mode); expr_type_ = expr_->expr_type(); expr_width_ = 1; min_width_ = 1; signed_flag_ = false; if ((op_ == '!') && (expr_type_ != IVL_VT_BOOL)) expr_type_ = IVL_VT_LOGIC; if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Test width of sub-expression of " << op_ << " returns " << sub_width << "." << endl; } return expr_width_; } expr_type_ = expr_->expr_type(); min_width_ = expr_->min_width(); signed_flag_ = expr_->has_sign(); return fix_width_(mode); } NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, unsigned expr_wid, unsigned flags) const { flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag ivl_variable_type_t t; unsigned sub_width = expr_wid; switch (op_) { // Reduction operators and ! always have a self determined width. case '!': case '&': // Reduction AND case '|': // Reduction OR case '^': // Reduction XOR case 'A': // Reduction NAND (~&) case 'N': // Reduction NOR (~|) case 'X': // Reduction NXOR (~^) sub_width = expr_->expr_width(); break; // Other operators have context determined operands, so propagate // the expression type (signed/unsigned) down to the operands. default: expr_->cast_signed(signed_flag_); break; } NetExpr*ip = expr_->elaborate_expr(des, scope, sub_width, flags); if (ip == 0) return 0; ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE); NetExpr*tmp; switch (op_) { case 'i': case 'I': case 'D': case 'd': t = ip->expr_type(); if (expr_wid != expr_->expr_width()) { /* * TODO: Need to modify draw_unary_expr() to support * increment/decrement operations on slice of vector. */ cerr << get_fileline() << ": sorry: " << human_readable_op(op_, true) << " operation is not yet supported on " << "vector slice." << endl; des->errors += 1; return 0; } else if (t == IVL_VT_LOGIC || t == IVL_VT_BOOL || t == IVL_VT_REAL) { if (dynamic_cast (ip) || dynamic_cast (ip)) { /* * invalid operand: operand is a constant * or real number */ cerr << get_fileline() << ": error: " << "inappropriate use of " << human_readable_op(op_, true) << " operator." << endl; des->errors += 1; return 0; } /* * **** Valid use of operator *** * For REAL variables draw_unary_real() is invoked during * evaluation and for LOGIC/BOOLEAN draw_unary_expr() * is called for evaluation. */ tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_); tmp->set_line(*this); } else { cerr << get_fileline() << ": error: " << "inappropriate use of " << human_readable_op(op_, true) << " operator." << endl; des->errors += 1; return 0; } break; default: tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_); tmp->set_line(*this); break; case '-': if (NetEConst*ipc = dynamic_cast(ip)) { verinum val = - ipc->value(); tmp = new NetEConst(val); tmp->cast_signed(signed_flag_); tmp->set_line(*this); delete ip; } else if (NetECReal*ipr = dynamic_cast(ip)) { /* When taking the - of a real, fold this into the constant value. */ verireal val = - ipr->value(); tmp = new NetECReal(val); tmp->set_line(*this); delete ip; } else { tmp = new NetEUnary(op_, ip, expr_wid, signed_flag_); tmp->set_line(*this); } break; case '+': tmp = ip; break; case '!': // Logical NOT /* If the operand to unary ! is a constant, then I can evaluate this expression here and return a logical constant in its place. */ if (NetEConst*ipc = dynamic_cast(ip)) { verinum val = ipc->value(); unsigned v1 = 0; unsigned vx = 0; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) switch (val[idx]) { case verinum::V0: break; case verinum::V1: v1 += 1; break; default: vx += 1; break; } verinum::V res; if (v1 > 0) res = verinum::V0; else if (vx > 0) res = verinum::Vx; else res = verinum::V1; verinum vres (res, 1, true); tmp = new NetEConst(vres); tmp->set_line(*this); delete ip; } else if (NetECReal*ipr = dynamic_cast(ip)) { verinum::V res; if (ipr->value().as_double() == 0.0) res = verinum::V1; else res = verinum::V0; verinum vres (res, 1, true); tmp = new NetEConst(vres); tmp->set_line(*this); delete ip; } else { if (ip->expr_type() == IVL_VT_REAL) { tmp = new NetEBComp('e', ip, new NetECReal(verireal(0.0))); } else { tmp = new NetEUReduce(op_, ip); } tmp->set_line(*this); } tmp = pad_to_width(tmp, expr_wid, signed_flag_, *this); break; case '&': // Reduction AND case '|': // Reduction OR case '^': // Reduction XOR case 'A': // Reduction NAND (~&) case 'N': // Reduction NOR (~|) case 'X': // Reduction NXOR (~^) if (ip->expr_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: " << human_readable_op(op_, true) << " operator may not have a REAL operand." << endl; des->errors += 1; return 0; } tmp = new NetEUReduce(op_, ip); tmp->set_line(*this); tmp = pad_to_width(tmp, expr_wid, signed_flag_, *this); break; case '~': tmp = elaborate_expr_bits_(ip, expr_wid); break; } return tmp; } NetExpr* PEUnary::elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const { // Handle the special case that the operand is a // constant. Simply calculate the constant results of the // expression and return that. if (NetEConst*ctmp = dynamic_cast (operand)) { verinum value = ctmp->value(); // The only operand that I know can get here is the // unary not (~). ivl_assert(*this, op_ == '~'); value = ~value; ctmp = new NetEConst(value); ctmp->set_line(*this); delete operand; return ctmp; } NetEUBits*tmp = new NetEUBits(op_, operand, expr_wid, signed_flag_); tmp->set_line(*this); return tmp; } NetExpr* PEVoid::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const { return 0; } NetNet* Design::find_discipline_reference(ivl_discipline_t dis, NetScope*scope) { NetNet*gnd = discipline_references_[dis->name()]; if (gnd) return gnd; string name = string(dis->name()) + "$gnd"; netvector_t*gnd_vec = new netvector_t(IVL_VT_REAL,0,0); gnd = new NetNet(scope, lex_strings.make(name), NetNet::WIRE, gnd_vec); gnd->set_discipline(dis); discipline_references_[dis->name()] = gnd; if (debug_elaborate) cerr << gnd->get_fileline() << ": debug: " << "Create an implicit reference terminal" << " for discipline=" << dis->name() << " in scope=" << scope_path(scope) << endl; return gnd; } iverilog-12_0/elab_lval.cc000066400000000000000000001531571435245347300156130ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2013 / 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 "PExpr.h" # include "PPackage.h" # include "netlist.h" # include "netmisc.h" # include "netstruct.h" # include "netclass.h" # include "netdarray.h" # include "netparray.h" # include "netvector.h" # include "netenum.h" # include "compiler.h" # include # include # include # include "ivl_assert.h" using namespace std; /* * These methods generate a NetAssign_ object for the l-value of the * assignment. This is common code for the = and <= statements. * * What gets generated depends on the structure of the l-value. If the * l-value is a simple name (i.e., foo <= ) then the NetAssign_ * is created the width of the foo reg and connected to all the * bits. * * If there is a part select (i.e., foo[3:1] <= ) the NetAssign_ * is made only as wide as it needs to be (3 bits in this example) and * connected to the correct bits of foo. A constant bit select is a * special case of the part select. * * If the bit-select is non-constant (i.e., foo[] = ) the * NetAssign_ is made wide enough to connect to all the bits of foo, * then the mux expression is elaborated and attached to the * NetAssign_ node as a b_mux value. The target must interpret the * presence of a bmux value as taking a single bit and assigning it to * the bit selected by the bmux expression. * * If the l-value expression is non-trivial, but can be fully * evaluated at compile time (meaning any bit selects are constant) * then elaboration will make a single NetAssign_ that connects to a * synthetic reg that in turn connects to all the proper pins of the * l-value. * * This last case can turn up in statements like: {a, b[1]} = c; * rather than create a NetAssign_ for each item in the concatenation, * elaboration makes a single NetAssign_ and connects it up properly. */ /* * The default interpretation of an l-value to a procedural assignment * is to try to make a net elaboration, and see if the result is * suitable for assignment. */ NetAssign_* PExpr::elaborate_lval(Design*, NetScope*, bool, bool) const { cerr << get_fileline() << ": Assignment l-value too complex." << endl; return 0; } /* * Concatenation expressions can appear as l-values. Handle them here. * * If adjacent l-values in the concatenation are not bit selects, then * merge them into a single NetAssign_ object. This can happen is code * like ``{ ...a, b, ...}''. As long as "a" and "b" do not have bit * selects (or the bit selects are constant) we can merge the * NetAssign_ objects. * * Be careful to get the bit order right. In the expression ``{a, b}'' * a is the MSB and b the LSB. Connect the LSB to the low pins of the * NetAssign_ object. */ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const { if (repeat_) { cerr << get_fileline() << ": error: Repeat concatenations make " "no sense in l-value expressions. I refuse." << endl; des->errors += 1; return 0; } NetAssign_*res = 0; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx] == 0) { cerr << get_fileline() << ": error: Empty expressions " << "not allowed in concatenations." << endl; des->errors += 1; continue; } NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_cassign, is_force); /* If the l-value doesn't elaborate, the error was already detected and printed. We just skip it and let the compiler catch more errors. */ if (tmp == 0) continue; if (tmp->expr_type() == IVL_VT_REAL) { cerr << parms_[idx]->get_fileline() << ": error: " << "concatenation operand can not be real: " << *parms_[idx] << endl; des->errors += 1; continue; } /* A concatenation is always unsigned. */ tmp->set_signed(false); /* Link the new l-value to the previous one. */ NetAssign_*last = tmp; while (last->more) last = last->more; last->more = res; res = tmp; } return res; } /* * Handle the ident as an l-value. This includes bit and part selects * of that ident. */ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope, bool is_cassign, bool is_force) const { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval: " << "Elaborate l-value ident expression: " << *this << endl; } /* Try to detect the special case that we are in a method and the identifier is a member of the class. */ if (NetAssign_*tmp = elaborate_lval_method_class_member_(des, scope)) return tmp; /* Normally find the name in the passed scope. But if this is imported from a package, then located the variable from the package scope. */ NetScope*use_scope = scope; if (package_) { use_scope = des->find_package(package_->pscope_name()); ivl_assert(*this, use_scope); } symbol_search_results sr; symbol_search(this, des, use_scope, path_, &sr); NetNet *reg = sr.net; pform_name_t &base_path = sr.path_head; pform_name_t &member_path = sr.path_tail; /* The l-value must be a variable. If not, then give up and print a useful error message. */ if (reg == 0) { if (use_scope->type()==NetScope::FUNC && use_scope->func_def()->is_void() && use_scope->basename()==peek_tail_name(path_)) { cerr << get_fileline() << ": error: " << "Cannot assign to " << path_ << " because function " << scope_path(use_scope) << " is void." << endl; } else { cerr << get_fileline() << ": error: Could not find variable ``" << path_ << "'' in ``" << scope_path(use_scope) << "''" << endl; } des->errors += 1; return 0; } ivl_assert(*this, reg); if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "Found l-value path_=" << path_ << " as reg=" << reg->name() << endl; cerr << get_fileline() << ": " << __func__ << ": " << "reg->type()=" << reg->type() << ", reg->unpacked_dimensions()=" << reg->unpacked_dimensions() << endl; if (reg->net_type()) cerr << get_fileline() << ": " << __func__ << ": " << "reg->net_type()=" << *reg->net_type() << endl; else cerr << get_fileline() << ": " << __func__ << ": " << "reg->net_type()=" << endl; cerr << get_fileline() << ": " << __func__ << ": " << " base_path=" << base_path << ", member_path=" << member_path << endl; } // We are processing the tail of a string of names. For // example, the Verilog may be "a.b.c", so we are processing // "c" at this point. const name_component_t&name_tail = path_.back(); // Use the last index to determine what kind of select // (bit/part/etc) we are processing. For example, the Verilog // may be "a.b.c[1][2][]". All but the last index must // be simple expressions, only the may be a part // select etc., so look at it to determine how we will be // proceeding. index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (!name_tail.index.empty()) use_sel = name_tail.index.back().sel; // Special case: The l-value is an entire memory, or array // slice. Detect the situation by noting if the index count // is less than the array dimensions (unpacked). if (reg->unpacked_dimensions() > name_tail.index.size()) { if (gn_system_verilog()) { cerr << get_fileline() << ": sorry: Assignment to an entire" " array or to an array slice is not yet supported." << endl; } else { cerr << get_fileline() << ": error: Assignment to an entire" " array or to an array slice requires SystemVerilog." << endl; } des->errors += 1; return 0; } /* Get the signal referenced by the identifier, and make sure it is a register. Wires are not allowed in this context, unless this is the l-value of a force. */ if ((reg->type() != NetNet::REG) && (reg->type() != NetNet::UNRESOLVED_WIRE) && !is_force) { cerr << get_fileline() << ": error: " << path_ << " is not a valid l-value in " << scope_path(use_scope) << "." << endl; cerr << reg->get_fileline() << ": : " << path_ << " is declared here as " << reg->type() << "." << endl; des->errors += 1; return 0; } // If we find that the matched variable is a packed struct, // then we can handled it with the net_packed_member_ method. if (reg->struct_type() && !member_path.empty()) { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_net_packed_member_(des, use_scope, lv, member_path); return lv; } // If the variable is a class object, then handle it with the // net_class_member_ method. const netclass_t *class_type = dynamic_cast(sr.type); if (class_type && !member_path.empty() && gn_system_verilog()) { NetAssign_*lv = elaborate_lval_net_class_member_(des, use_scope, class_type, reg, member_path); return lv; } // Past this point, we should have taken care of the cases // where the name is a member/method of a struct/class. // XXXX ivl_assert(*this, method_name.nil()); ivl_assert(*this, member_path.empty()); bool need_const_idx = is_cassign || is_force || (reg->type()==NetNet::UNRESOLVED_WIRE); if (reg->unpacked_dimensions() > 0) return elaborate_lval_net_word_(des, scope, reg, need_const_idx); // This must be after the array word elaboration above! if (reg->get_scalar() && use_sel != index_component_t::SEL_NONE) { cerr << get_fileline() << ": error: can not select part of "; if (reg->data_type() == IVL_VT_REAL) cerr << "real: "; else cerr << "scalar: "; cerr << reg->name() << endl; des->errors += 1; return 0; } if (use_sel == index_component_t::SEL_PART) { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_net_part_(des, scope, lv); return lv; } if (use_sel == index_component_t::SEL_IDX_UP || use_sel == index_component_t::SEL_IDX_DO) { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_net_idx_(des, scope, lv, use_sel, need_const_idx); return lv; } if (use_sel == index_component_t::SEL_BIT) { if (reg->darray_type()) { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_darray_bit_(des, scope, lv); return lv; } else { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_net_bit_(des, scope, lv, need_const_idx); return lv; } } ivl_assert(*this, use_sel == index_component_t::SEL_NONE); if (reg->type()==NetNet::UNRESOLVED_WIRE && !is_force) { cerr << get_fileline() << ": error: " << path_ << " Unable to assign to unresolved wires." << endl; des->errors += 1; return 0; } /* No select expressions. */ NetAssign_*lv = new NetAssign_(reg); lv->set_signed(reg->get_signed()); return lv; } NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des, NetScope*scope) const { if (!gn_system_verilog()) return 0; if (scope->parent() == 0 || scope->type() == NetScope::CLASS) return 0; if (path_.size() != 1) return 0; const netclass_t*class_type = find_class_containing_scope(*this, scope); if (class_type == 0) return 0; const name_component_t&name_comp = path_.back(); perm_string member_name = name_comp.name; int pidx = class_type->property_idx_from_name(member_name); if (pidx < 0) return 0; property_qualifier_t qual = class_type->get_prop_qual(pidx); // Static properties are handled as normal signals. Regular symbol // search will find it. if (qual.test_static()) return 0; NetScope*scope_method = find_method_containing_scope(*this, scope); ivl_assert(*this, scope_method); NetNet*this_net = scope_method->find_signal(perm_string::literal(THIS_TOKEN)); if (this_net == 0) { cerr << get_fileline() << ": internal error: " << "Unable to find 'this' port of " << scope_path(scope_method) << "." << endl; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: " << "Ident " << member_name << " is a property of class " << class_type->get_name() << endl; } NetExpr*canon_index = 0; if (! name_comp.index.empty()) { ivl_type_t property_type = class_type->get_prop_type(pidx); if (const netsarray_t* stype = dynamic_cast (property_type)) { canon_index = make_canonical_index(des, scope, this, name_comp.index, stype, false); } else { cerr << get_fileline() << ": error: " << "Index expressions don't apply to this type of property." << endl; des->errors += 1; } } // Detect assignment to constant properties. Note that the // initializer constructor MAY assign to constant properties, // as this is how the property gets its value. if (qual.test_const()) { if (class_type->get_prop_initialized(pidx)) { cerr << get_fileline() << ": error: " << "Property " << class_type->get_prop_name(pidx) << " is constant in this method." << " (scope=" << scope_path(scope) << ")" << endl; des->errors += 1; } else if (scope->basename()!="new" && scope->basename()!="new@") { cerr << get_fileline() << ": error: " << "Property " << class_type->get_prop_name(pidx) << " is constant in this method." << " (scope=" << scope_path(scope) << ")" << endl; des->errors += 1; } else { // Mark this property as initialized. This is used // to know that we have initialized the constant // object so the next assignment will be marked as // illegal. class_type->set_prop_initialized(pidx); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: " << "Found initializers for property " << class_type->get_prop_name(pidx) << endl; } } } ivl_type_t tmp_type = class_type->get_prop_type(pidx); if (const netuarray_t*tmp_ua = dynamic_cast(tmp_type)) { const std::vector&dims = tmp_ua->static_dimensions(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: " << "Property " << class_type->get_prop_name(pidx) << " has " << dims.size() << " dimensions, " << " got " << name_comp.index.size() << " indices." << endl; if (canon_index) { cerr << get_fileline() << ": PEIdent::elaborate_lval_method_class_member_: " << "Canonical index is:" << *canon_index << endl; }; } if (dims.size() != name_comp.index.size()) { cerr << get_fileline() << ": error: " << "Got " << name_comp.index.size() << " indices, " << "expecting " << dims.size() << " to index the property " << class_type->get_prop_name(pidx) << "." << endl; des->errors += 1; } } NetAssign_*this_lval = new NetAssign_(this_net); this_lval->set_property(member_name, pidx); if (canon_index) this_lval->set_word(canon_index); return this_lval; } NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des, NetScope*scope, NetNet*reg, bool need_const_idx) const { const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_word_: " << "Handle as n-dimensional array." << endl; } if (name_tail.index.size() < reg->unpacked_dimensions()) { cerr << get_fileline() << ": error: Array " << reg->name() << " needs " << reg->unpacked_dimensions() << " indices," << " but got only " << name_tail.index.size() << "." << endl; des->errors += 1; return 0; } // Make sure there are enough indices to address an array element. const index_component_t&index_head = name_tail.index.front(); if (index_head.sel == index_component_t::SEL_PART) { cerr << get_fileline() << ": error: cannot perform a part " << "select on array " << reg->name() << "." << endl; des->errors += 1; return 0; } // Evaluate all the index expressions into an // "unpacked_indices" array. listunpacked_indices; list unpacked_indices_const; indices_flags flags; indices_to_expressions(des, scope, this, name_tail.index, reg->unpacked_dimensions(), false, flags, unpacked_indices, unpacked_indices_const); NetExpr*canon_index = 0; if (flags.invalid) { // Nothing to do. } else if (flags.undefined) { cerr << get_fileline() << ": warning: " << "ignoring undefined l-value array access " << reg->name() << as_indices(unpacked_indices) << "." << endl; } else if (flags.variable) { if (need_const_idx) { cerr << get_fileline() << ": error: array '" << reg->name() << "' index must be a constant in this context." << endl; des->errors += 1; return 0; } ivl_assert(*this, unpacked_indices.size() == reg->unpacked_dimensions()); canon_index = normalize_variable_unpacked(reg, unpacked_indices); } else { ivl_assert(*this, unpacked_indices_const.size() == reg->unpacked_dimensions()); canon_index = normalize_variable_unpacked(reg, unpacked_indices_const); if (canon_index == 0) { cerr << get_fileline() << ": warning: " << "ignoring out of bounds l-value array access " << reg->name() << as_indices(unpacked_indices_const) << "." << endl; } } // Ensure invalid array accesses are ignored. if (canon_index == 0) canon_index = new NetEConst(verinum(verinum::Vx)); canon_index->set_line(*this); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_word_: " << "canon_index=" << *canon_index << endl; } if (reg->type()==NetNet::UNRESOLVED_WIRE) { cerr << get_fileline() << ": error: " << "Unable to assign words of unresolved wire array." << endl; des->errors += 1; return 0; } NetAssign_*lv = new NetAssign_(reg); lv->set_word(canon_index); if (debug_elaborate) cerr << get_fileline() << ": debug: Set array word=" << *canon_index << endl; /* An array word may also have part selects applied to them. */ index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (name_tail.index.size() > reg->unpacked_dimensions()) use_sel = name_tail.index.back().sel; if (reg->get_scalar() && use_sel != index_component_t::SEL_NONE) { cerr << get_fileline() << ": error: can not select part of "; if (reg->data_type() == IVL_VT_REAL) cerr << "real"; else cerr << "scalar"; cerr << " array word: " << reg->name() << as_indices(unpacked_indices) << endl; des->errors += 1; return 0; } if (use_sel == index_component_t::SEL_BIT) elaborate_lval_net_bit_(des, scope, lv, need_const_idx); if (use_sel == index_component_t::SEL_PART) elaborate_lval_net_part_(des, scope, lv); if (use_sel == index_component_t::SEL_IDX_UP || use_sel == index_component_t::SEL_IDX_DO) elaborate_lval_net_idx_(des, scope, lv, use_sel, need_const_idx); return lv; } bool PEIdent::elaborate_lval_net_bit_(Design*des, NetScope*scope, NetAssign_*lv, bool need_const_idx) const { listprefix_indices; bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices); if (!rc) return false; const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb != 0); ivl_assert(*this, index_tail.lsb == 0); NetNet*reg = lv->sig(); ivl_assert(*this, reg); // Bit selects have a single select expression. Evaluate the // constant value and treat it as a part select with a bit // width of 1. NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1); long lsb = 0; if (NetEConst*index_con = dynamic_cast (mux)) { // The index has a constant defined value. if (index_con->value().is_defined()) { lsb = index_con->value().as_long(); mux = 0; // The index is undefined and this is a packed array. } else if (prefix_indices.size()+2 <= reg->packed_dims().size()) { long loff; unsigned long lwid; bool rcl = reg->sb_to_slice(prefix_indices, lsb, loff, lwid); ivl_assert(*this, rcl); if (warn_ob_select) { cerr << get_fileline() << ": warning: L-value packed array select of " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << " has an undefined index." << endl; } lv->set_part(new NetEConst(verinum(verinum::Vx)), lwid); return true; // The index is undefined and this is a bit select. } else { if (warn_ob_select) { cerr << get_fileline() << ": warning: L-value bit select of " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << " has an undefined index." << endl; } lv->set_part(new NetEConst(verinum(verinum::Vx)), 1); return true; } } if (debug_elaborate && (reg->type()==NetNet::UNRESOLVED_WIRE)) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_bit_: " << "Try to assign bits of unresolved wire." << endl; } // Notice that we might be assigning to an unresolved wire. This // can happen if we are actually assigning to a variable that // has a partial continuous assignment to it. If that is the // case, then the bit select must be constant. ivl_assert(*this, need_const_idx || (reg->type()!=NetNet::UNRESOLVED_WIRE)); if (prefix_indices.size()+2 <= reg->packed_dims().size()) { // Special case: this is a slice of a multi-dimensional // packed array. For example: // reg [3:0][7:0] x; // x[2] = ... // This shows up as the prefix_indices being too short // for the packed dimensions of the vector. What we do // here is convert to a "slice" of the vector. if (mux == 0) { long loff; unsigned long lwid; bool rcl = reg->sb_to_slice(prefix_indices, lsb, loff, lwid); ivl_assert(*this, rcl); if (reg->type()==NetNet::UNRESOLVED_WIRE) { bool rct = reg->test_and_set_part_driver(loff+lwid-1, loff); if (rct) { cerr << get_fileline() << ": error: " << "These bits are already driven." << endl; des->errors += 1; } } lv->set_part(new NetEConst(verinum(loff)), lwid); } else { ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE); unsigned long lwid; mux = normalize_variable_slice_base(prefix_indices, mux, reg, lwid); lv->set_part(mux, lwid); } } else if (reg->data_type() == IVL_VT_STRING) { ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE); // Special case: This is a select of a string // variable. The target of the assignment is a character // select of a string. Force the r-value to be an 8bit // vector and set the "part" to be the character select // expression. The code generator knows what to do with // this. if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Bit select of string becomes character select." << endl; } if (mux) lv->set_part(mux, 8); else lv->set_part(new NetEConst(verinum(lsb)), 8); } else if (mux) { ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE); // Non-constant bit mux. Correct the mux for the range // of the vector, then set the l-value part select // expression. if (need_const_idx) { cerr << get_fileline() << ": error: '" << reg->name() << "' bit select must be a constant in this context." << endl; des->errors += 1; return false; } mux = normalize_variable_bit_base(prefix_indices, mux, reg); lv->set_part(mux, 1); } else if (reg->vector_width() == 1 && reg->sb_is_valid(prefix_indices,lsb)) { // Constant bit mux that happens to select the only bit // of the l-value. Don't bother with any select at all. // NOTE: Don't know what to do about unresolved wires // here, but they are probably wrong. ivl_assert(*this, reg->type()!=NetNet::UNRESOLVED_WIRE); } else { // Constant bit select that does something useful. long loff = reg->sb_to_idx(prefix_indices,lsb); if (warn_ob_select && (loff < 0 || loff >= (long)reg->vector_width())) { cerr << get_fileline() << ": warning: bit select " << reg->name() << "[" <type()==NetNet::UNRESOLVED_WIRE) { bool rct = reg->test_and_set_part_driver(loff, loff); if (rct) { cerr << get_fileline() << ": error: " << "Bit " << loff << " is already driven." << endl; des->errors += 1; } } lv->set_part(new NetEConst(verinum(loff)), 1); } return true; } bool PEIdent::elaborate_lval_darray_bit_(Design*des, NetScope*scope, NetAssign_*lv)const { const name_component_t&name_tail = path_.back(); ivl_assert(*this, !name_tail.index.empty()); // For now, only support single-dimension dynamic arrays. ivl_assert(*this, name_tail.index.size() == 1); if (lv->sig()->type()==NetNet::UNRESOLVED_WIRE) { cerr << get_fileline() << ": error: " << path_ << " Unable to darray word select unresolved wires." << endl; des->errors += 1; return false; } const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb != 0); ivl_assert(*this, index_tail.lsb == 0); // Evaluate the select expression... NetExpr*mux = elab_and_eval(des, scope, index_tail.msb, -1); lv->set_word(mux); return true; } bool PEIdent::elaborate_lval_net_part_(Design*des, NetScope*scope, NetAssign_*lv) const { list prefix_indices; bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices); ivl_assert(*this, rc); // The range expressions of a part select must be // constant. The calculate_parts_ function calculates the // values into msb and lsb. long msb, lsb; bool parts_defined_flag; bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag); if (!flag) return false; NetNet*reg = lv->sig(); ivl_assert(*this, reg); if (! parts_defined_flag) { if (warn_ob_select) { cerr << get_fileline() << ": warning: L-value part select of " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << " has an undefined index." << endl; } // Use a width of two here so we can distinguish between an // undefined bit or part select. lv->set_part(new NetEConst(verinum(verinum::Vx)), 2); return true; } if (reg->type()==NetNet::UNRESOLVED_WIRE) { bool rct = reg->test_and_set_part_driver(msb, lsb); if (rct) { cerr << get_fileline() << ": error: " << path_ << "Part select is double-driving unresolved wire." << endl; des->errors += 1; return false; } } const vector&packed = reg->packed_dims(); long loff, moff; long wid; if (prefix_indices.size()+1 < packed.size()) { // If there are fewer indices then there are packed // dimensions, then this is a range of slices. Calculate // it into a big slice. bool lrc, mrc; unsigned long tmp_lwid, tmp_mwid; lrc = reg->sb_to_slice(prefix_indices, lsb, loff, tmp_lwid); mrc = reg->sb_to_slice(prefix_indices, msb, moff, tmp_mwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << msb << ":" << lsb; cerr << "] exceeds the declared bounds for "; cerr << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } if (loff < moff) { moff = moff + tmp_mwid - 1; } else { long ltmp = moff; moff = loff + tmp_lwid - 1; loff = ltmp; } wid = moff - loff + 1; } else { loff = reg->sb_to_idx(prefix_indices,lsb); moff = reg->sb_to_idx(prefix_indices,msb); wid = moff - loff + 1; if (moff < loff) { cerr << get_fileline() << ": error: part select " << reg->name() << "[" << msb<<":"<errors += 1; return false; } } // Special case: The range winds up selecting the entire // vector. Treat this as no part select at all. if (loff == 0 && moff == (long)(reg->vector_width()-1)) { return true; } /* If the part select extends beyond the extremes of the variable, then output a warning. Note that loff is converted to normalized form so is relative the variable pins. */ if (warn_ob_select && (loff < 0 || moff >= (long)reg->vector_width())) { cerr << get_fileline() << ": warning: Part select " << reg->name() << "[" << msb<<":"<set_part(new NetEConst(verinum(loff)), wid); return true; } bool PEIdent::elaborate_lval_net_idx_(Design*des, NetScope*scope, NetAssign_*lv, index_component_t::ctype_t use_sel, bool need_const_idx) const { listprefix_indices; bool rc = calculate_packed_indices_(des, scope, lv->sig(), prefix_indices); ivl_assert(*this, rc); const name_component_t&name_tail = path_.back();; ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); ivl_assert(*this, index_tail.msb != 0); ivl_assert(*this, index_tail.lsb != 0); NetNet*reg = lv->sig(); assert(reg); unsigned long wid; calculate_up_do_width_(des, scope, wid); NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1); ivl_select_type_t sel_type = IVL_SEL_OTHER; // Handle the special case that the base is constant. For this // case we can reduce the expression. if (NetEConst*base_c = dynamic_cast (base)) { // For the undefined case just let the constant pass and // we will handle it in the code generator. if (base_c->value().is_defined()) { long lsv = base_c->value().as_long(); long rel_base = 0; // Get the signal range. const vector&packed = reg->packed_dims(); if (prefix_indices.size()+1 < reg->packed_dims().size()) { // Here we are selecting one or more sub-arrays. // Make this work by finding the indexed sub-arrays and // creating a generated slice that spans the whole range. long loff, moff; unsigned long lwid, mwid; bool lrc, mrc; mrc = reg->sb_to_slice(prefix_indices, lsv, moff, mwid); if (use_sel == index_component_t::SEL_IDX_UP) lrc = reg->sb_to_slice(prefix_indices, lsv+wid-1, loff, lwid); else lrc = reg->sb_to_slice(prefix_indices, lsv-wid+1, loff, lwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << lsv; if (index_tail.sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] exceeds the declared bounds for "; cerr << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, lwid == mwid); if (moff > loff) { rel_base = loff; wid = moff + mwid - loff; } else { rel_base = moff; wid = loff + lwid - moff; } } else { long offset = 0; // We want the last range, which is where we work. const netrange_t&rng = packed.back(); if (((rng.get_msb() < rng.get_lsb()) && use_sel == index_component_t::SEL_IDX_UP) || ((rng.get_msb() > rng.get_lsb()) && use_sel == index_component_t::SEL_IDX_DO)) { offset = -wid + 1; } rel_base = reg->sb_to_idx(prefix_indices,lsv) + offset; } delete base; /* If we cover the entire lvalue just skip the select. */ if (rel_base == 0 && wid == reg->vector_width()) return true; base = new NetEConst(verinum(rel_base)); if (warn_ob_select) { if (rel_base < 0) { cerr << get_fileline() << ": warning: " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << "[" << lsv; if (use_sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] is selecting before vector." << endl; } if (rel_base + wid > reg->vector_width()) { cerr << get_fileline() << ": warning: " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << "[" << lsv; if (use_sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] is selecting after vector." << endl; } } } else if (warn_ob_select) { cerr << get_fileline() << ": warning: L-value indexed part " << "select of " << reg->name(); if (reg->unpacked_dimensions() > 0) cerr << "[]"; cerr << " has an undefined base." << endl; } } else { if (need_const_idx) { cerr << get_fileline() << ": error: '" << reg->name() << "' base index must be a constant in this context." << endl; des->errors += 1; return false; } ivl_assert(*this, prefix_indices.size()+1 == reg->packed_dims().size()); /* Correct the mux for the range of the vector. */ if (use_sel == index_component_t::SEL_IDX_UP) { base = normalize_variable_part_base(prefix_indices, base, reg, wid, true); sel_type = IVL_SEL_IDX_UP; } else { // This is assumed to be a SEL_IDX_DO. base = normalize_variable_part_base(prefix_indices, base, reg, wid, false); sel_type = IVL_SEL_IDX_DOWN; } } if (debug_elaborate) cerr << get_fileline() << ": debug: Set part select width=" << wid << ", base=" << *base << endl; lv->set_part(base, wid, sel_type); return true; } /* * When the l-value turns out to be a class object, this method is * called with the bound variable, and the method path. For example, * if path_=a.b.c and a.b binds to the variable, then sig is b, and * member_path=c. if path_=obj.base.x, and base_path=obj, then sig is * obj, and member_path=base.x. */ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope, const netclass_t *class_type, NetNet*sig, pform_name_t member_path) const { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_class_member_: " << "l-value is property " << member_path << " of " << sig->name() << "." << endl; } ivl_assert(*this, class_type); // Iterate over the member_path. This handles nested class // object, by generating nested NetAssign_ object. We start // with lv==0, so the front of the member_path is the member // of the outermost class. This generates an lv from sig. Then // iterate over the remaining of the member_path, replacing // the outer lv with an lv that nests the lv from the previous // iteration. NetAssign_*lv = 0; do { // Start with the first component of the member path... perm_string method_name = peek_head_name(member_path); // Pull that component from the member_path. We need to // know the current member being worked on, and will // need to know if there are more members to be worked on. name_component_t member_cur = member_path.front(); member_path.pop_front(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_class_member_: " << "Processing member_cur=" << member_cur << endl; } // Make sure the property is really present in the class. If // not, then generate an error message and return an error. int pidx = class_type->property_idx_from_name(method_name); if (pidx < 0) { cerr << get_fileline() << ": error: Class " << class_type->get_name() << " does not have a property " << method_name << "." << endl; des->errors += 1; return 0; } property_qualifier_t qual = class_type->get_prop_qual(pidx); if (qual.test_local() && ! class_type->test_scope_is_method(scope)) { cerr << get_fileline() << ": error: " << "Local property " << class_type->get_prop_name(pidx) << " is not accessible (l-value) in this context." << " (scope=" << scope_path(scope) << ")" << endl; des->errors += 1; } else if (qual.test_static()) { // Special case: this is a static property. Ignore the // "this" sig and use the property itself, which is not // part of the sig, as the l-value. NetNet*psig = class_type->find_static_property(method_name); ivl_assert(*this, psig); lv = new NetAssign_(psig); return lv; } else if (qual.test_const()) { cerr << get_fileline() << ": error: " << "Property " << class_type->get_prop_name(pidx) << " is constant in this context." << endl; des->errors += 1; } lv = lv? new NetAssign_(lv) : new NetAssign_(sig); lv->set_property(method_name, pidx); // Now get the type of the property. ivl_type_t ptype = class_type->get_prop_type(pidx); const netdarray_t*mtype = dynamic_cast (ptype); if (mtype) { if (! member_cur.index.empty()) { cerr << get_fileline() << ": sorry: " << "Array index of array properties not supported." << endl; des->errors += 1; } } // If the current member is a class object, then get the // type. We may wind up iterating, and need the proper // class type. class_type = dynamic_cast(ptype); } while (!member_path.empty()); return lv; } /* * This method is caled to handle l-value identifiers that are packed * structs. The lv is already attached to the variable, so this method * calculates the part select that is defined by the member_path. For * example, if the path_ is main.sub.sub_local, and the variable is * main, then we know at this point that main is a packed struct, and * lv contains the reference to the bound variable (main). In this * case member_path==sub.sub_local, and it is up to this method to * work out the part select that the member_path represents. */ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope, NetAssign_*lv, pform_name_t member_path) const { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "path_=" << path_ << " member_path=" << member_path << endl; } NetNet*reg = lv->sig(); ivl_assert(*this, reg); const netstruct_t*struct_type = reg->struct_type(); ivl_assert(*this, struct_type); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "Type=" << *struct_type << endl; } if (! struct_type->packed()) { cerr << get_fileline() << ": sorry: Only packed structures " << "are supported in l-value." << endl; des->errors += 1; return false; } // Looking for the base name. We need that to know about // indices we may need to apply. This is to handle the case // that the base is an array of structs, and not just a // struct. pform_name_t::const_reverse_iterator name_idx = path_.rbegin(); for (size_t idx = 1 ; idx < member_path.size() ; idx += 1) ++ name_idx; if (name_idx->name != peek_head_name(member_path)) { cerr << get_fileline() << ": internal error: " << "name_idx=" << name_idx->name << ", expecting member_name=" << peek_head_name(member_path) << endl; des->errors += 1; return false; } ivl_assert(*this, name_idx->name == peek_head_name(member_path)); ++ name_idx; const name_component_t&name_base = *name_idx; // Shouldn't be seeing unpacked arrays of packed structs... ivl_assert(*this, reg->unpacked_dimensions() == 0); // These make up the "part" select that is the equivilent of // following the member path through the nested structs. To // start with, the off[set] is zero, and use_width is the // width of the entire variable. The first member_comp is at // some offset within the variable, and will have a reduced // width. As we step through the member_path the off // increases, and use_width shrinks. unsigned long off = 0; unsigned long use_width = struct_type->packed_width(); pform_name_t completed_path; do { const name_component_t member_comp = member_path.front(); const perm_string&member_name = member_comp.name; if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "Processing member_comp=" << member_comp << " (completed_path=" << completed_path << ")" << endl; } // This is a packed member, so the name is of the form // "a.b[...].c[...]" which means that the path_ must have at // least 2 components. We are processing "c[...]" at that // point (otherwise known as member_name) and we have a // reference to it in member_comp. // The member_path is the members we want to follow for the // variable. For example, main[N].a.b may have main[N] as the // base_name, and member_path=a.b. The member_name is the // start of the member_path, and is "a". The member_name // should be a member of the struct_type type. // Calculate the offset within the packed structure of the // member, and any indices. We will add in the offset of the // struct into the packed array later. Note that this works // for packed unions as well (although the offset will be 0 // for union members). unsigned long tmp_off; const netstruct_t::member_t* member = struct_type->packed_member(member_name, tmp_off); if (member == 0) { cerr << get_fileline() << ": error: Member " << member_name << " is not a member of struct type of " << reg->name() << "." << completed_path << endl; des->errors += 1; return false; } if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "Member type: " << *(member->net_type) << endl; } off += tmp_off; ivl_assert(*this, use_width >= (unsigned long)member->net_type->packed_width()); use_width = member->net_type->packed_width(); // At this point, off and use_width are the part select // expressed by the member_comp, which is a member of the // struct. We can further refine the part select with any // indices that might be present. // Get the index component type. At this point, we only // support bit select or none. index_component_t::ctype_t use_sel = index_component_t::SEL_NONE; if (!member_comp.index.empty()) use_sel = member_comp.index.back().sel; if (use_sel != index_component_t::SEL_NONE && use_sel != index_component_t::SEL_BIT && use_sel != index_component_t::SEL_PART) { cerr << get_fileline() << ": sorry: Assignments to part selects of " "a struct member are not yet supported." << endl; des->errors += 1; return false; } if (const netvector_t*mem_vec = dynamic_cast(member->net_type)) { // If the member type is a netvector_t, then it is a // vector of atom or scaler objects. For example, if the // l-value expression is "foo.member[1][2]", // then the member should be something like: // ... logic [h:l][m:n] member; // There should be index expressions index the vector // down, but there doesn't need to be all of them. We // can, for example, be selecting a part of the vector. // We only need to process this if there are any // index expressions. If not, then the packed // vector can be handled atomically. // In any case, this should be the tail of the // member_path, because the array element of this // kind of array cannot be a struct. if (!member_comp.index.empty()) { // These are the dimensions defined by the type const vector&mem_packed_dims = mem_vec->packed_dims(); if (member_comp.index.size() > mem_packed_dims.size()) { cerr << get_fileline() << ": error: " << "Too many index expressions for member." << endl; des->errors += 1; return false; } // Evaluate all but the last index expression, into prefix_indices. listprefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); ivl_assert(*this, rc); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "prefix_indices.size()==" << prefix_indices.size() << ", mem_packed_dims.size()==" << mem_packed_dims.size() << " (netvector_t context)" << endl; } long tail_off = 0; unsigned long tail_wid = 0; rc = calculate_part(this, des, scope, member_comp.index.back(), tail_off, tail_wid); ivl_assert(*this, rc); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "calculate_part for tail returns tail_off=" << tail_off << ", tail_wid=" << tail_wid << endl; } // Now use the prefix_to_slice function to calculate the // offset and width of the addressed slice of the member. long loff; unsigned long lwid; prefix_to_slice(mem_packed_dims, prefix_indices, tail_off, loff, lwid); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "Calculate loff=" << loff << " lwid=" << lwid << " tail_off=" << tail_off << " tail_wid=" << tail_wid << " off=" << off << " use_width=" << use_width << endl; } off += loff; use_width = lwid * tail_wid; } // The netvector_t only has atom elements, to // there is no next struct type. struct_type = 0; } else if (const netparray_t*array = dynamic_cast (member->net_type)) { // If the member is a parray, then the elements // are themselves packed object, including // possibly a struct. Handle this by taking the // part select of the current part of the // variable, then stepping to the element type to // possibly iterate through more of the member_path. ivl_assert(*this, array->packed()); ivl_assert(*this, !member_comp.index.empty()); // These are the dimensions defined by the type const vector&mem_packed_dims = array->static_dimensions(); if (member_comp.index.size() != mem_packed_dims.size()) { cerr << get_fileline() << ": error: " << "Incorrect number of index expressions for member " << member_name << "." << endl; des->errors += 1; return false; } // Evaluate all but the last index expression, into prefix_indices. listprefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, member_comp.index); ivl_assert(*this, rc); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "prefix_indices.size()==" << prefix_indices.size() << ", mem_packed_dims.size()==" << mem_packed_dims.size() << " (netparray_t context)" << endl; } // Evaluate the last index expression into a constant long. NetExpr*texpr = elab_and_eval(des, scope, member_comp.index.back().msb, -1, true); long tmp; if (texpr == 0 || !eval_as_long(tmp, texpr)) { cerr << get_fileline() << ": error: " << "Array index expressions for member " << member_name << " must be constant here." << endl; des->errors += 1; return false; } delete texpr; // Now use the prefix_to_slice function to calculate the // offset and width of the addressed slice of the member. long loff; unsigned long lwid; prefix_to_slice(mem_packed_dims, prefix_indices, tmp, loff, lwid); ivl_type_t element_type = array->element_type(); long element_width = element_type->packed_width(); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "parray subselection loff=" << loff << ", lwid=" << lwid << ", element_width=" << element_width << endl; } // The width and offset calculated from the // indices is actually in elements, and not // bits. In fact, in this context, the lwid should // come down to 1 (one element). off += loff * element_width; ivl_assert(*this, lwid==1); use_width = element_width; // To move on to the next component in the member // path, get the element type. For example, for // the path a.b[1].c, we are processing b[1] here, // and the element type should be a netstruct_t // that will wind up containing the member c. struct_type = dynamic_cast (element_type); } else if (const netstruct_t*tmp_struct = dynamic_cast (member->net_type)) { // If the member is itself a struct, then get // ready to go on to the next iteration. struct_type = tmp_struct; } else if (const netenum_t*tmp_enum = dynamic_cast (member->net_type)) { // If the element is an enum, then we don't have // anything special to do. if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "Tail element is an enum: " << *tmp_enum << endl; } struct_type = 0; } else { // Unknown type? cerr << get_fileline() << ": internal error: " << "Unexpected member type? " << *(member->net_type) << endl; des->errors += 1; return false; } // Complete this component of the path, mark it // completed, and set up for the next component. completed_path .push_back(member_comp); member_path.pop_front(); } while (!member_path.empty() && struct_type != 0); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lval_net_packed_member_: " << "After processing member_path, " << "off=" << off << ", use_width=" << use_width << ", completed_path=" << completed_path << ", member_path=" << member_path << endl; } // The dimensions in the expression must match the packed // dimensions that are declared for the variable. For example, // if foo is a packed array of struct, then this expression // must be "b[n][m]" with the right number of dimensions to // match the declaration of "b". // Note that one of the packed dimensions is the packed struct // itself. ivl_assert(*this, name_base.index.size()+1 == reg->packed_dimensions()); // Generate an expression that takes the input array of // expressions and generates a canonical offset into the // packed array. NetExpr*packed_base = 0; if (reg->packed_dimensions() > 1) { listtmp_index = name_base.index; index_component_t member_select; member_select.sel = index_component_t::SEL_BIT; member_select.msb = new PENumber(new verinum(off)); tmp_index.push_back(member_select); packed_base = collapse_array_indices(des, scope, reg, tmp_index); } long tmp; if (packed_base && eval_as_long(tmp, packed_base)) { off = tmp; delete packed_base; packed_base = 0; } if (reg->type()==NetNet::UNRESOLVED_WIRE) { cerr << get_fileline() << ": error: " << path_ << " Unable to member-select unresolved wires." << endl; des->errors += 1; return false; } if (packed_base == 0) { lv->set_part(new NetEConst(verinum(off)), use_width); return true; } // Oops, packed_base is not fully evaluated, so I don't know // yet what to do with it. cerr << get_fileline() << ": internal error: " << "I don't know how to handle this index expression? " << *packed_base << endl; ivl_assert(*this, 0); return false; } NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool, bool) const { cerr << get_fileline() << ": error: Constant values not allowed " << "in l-value expressions." << endl; des->errors += 1; return 0; } iverilog-12_0/elab_net.cc000066400000000000000000001107001435245347300154260ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / 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 "PExpr.h" # include "netlist.h" # include "netmisc.h" # include "netstruct.h" # include "netvector.h" # include "compiler.h" # include # include # include # include "ivl_assert.h" using namespace std; /* * The concatenation is also OK an an l-value. This method elaborates * it as a structural l-value. The return values is the *input* net of * the l-value, which may feed via part selects to the final * destination. The caller can connect gate outputs to this signal to * make the l-value connections. */ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const { assert(scope); std::vector nets(parms_.size()); unsigned width = 0; unsigned errors = 0; if (repeat_) { cerr << get_fileline() << ": sorry: I do not know how to" " elaborate repeat concatenation nets." << endl; return 0; } /* Elaborate the operands of the concatenation. */ for (unsigned idx = 0 ; idx < nets.size() ; idx += 1) { if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate subexpression " << idx << " of " << nets.size() << " l-values: " << *parms_[idx] << endl; } if (parms_[idx] == 0) { cerr << get_fileline() << ": error: Empty expressions " << "not allowed in concatenations." << endl; errors += 1; continue; } if (bidirectional_flag) { nets[idx] = parms_[idx]->elaborate_bi_net(des, scope); } else { nets[idx] = parms_[idx]->elaborate_lnet(des, scope); } if (nets[idx] == 0) { errors += 1; } else if (nets[idx]->data_type() == IVL_VT_REAL) { cerr << parms_[idx]->get_fileline() << ": error: " << "concatenation operand can no be real: " << *parms_[idx] << endl; errors += 1; continue; } else { width += nets[idx]->vector_width(); } } if (errors) { des->errors += errors; return 0; } /* Make the temporary signal that connects to all the operands, and connect it up. Scan the operands of the concat operator from most significant to least significant, which is the order they are given in the concat list. */ netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp2_vec); /* Assume that the data types of the nets are all the same, so we can take the data type of any, the first will do. */ osig->local_flag(true); osig->set_line(*this); if (bidirectional_flag) { if (debug_elaborate) { cerr << get_fileline() << ": debug: Generating tran(VP) " << "to connect input l-value to subexpressions." << endl; } for (unsigned idx = 0 ; idx < nets.size() ; idx += 1) { unsigned wid = nets[idx]->vector_width(); unsigned off = width - wid; NetTran*ps = new NetTran(scope, scope->local_symbol(), osig->vector_width(), wid, off); des->add_node(ps); ps->set_line(*this); connect(ps->pin(0), osig->pin(0)); connect(ps->pin(1), nets[idx]->pin(0)); ivl_assert(*this, wid <= width); width -= wid; } } else { if (debug_elaborate) { cerr << get_fileline() << ": debug: Generating part selects " << "to connect input l-value to subexpressions." << endl; } NetPartSelect::dir_t part_dir = NetPartSelect::VP; for (unsigned idx = 0 ; idx < nets.size() ; idx += 1) { unsigned wid = nets[idx]->vector_width(); unsigned off = width - wid; NetPartSelect*ps = new NetPartSelect(osig, off, wid, part_dir); des->add_node(ps); ps->set_line(*this); connect(ps->pin(1), osig->pin(0)); connect(ps->pin(0), nets[idx]->pin(0)); assert(wid <= width); width -= wid; } assert(width == 0); } return osig; } NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const { return elaborate_lnet_common_(des, scope, false); } NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const { return elaborate_lnet_common_(des, scope, true); } bool PEConcat::is_collapsible_net(Design*des, NetScope*scope, NetNet::PortType port_type) const { assert(scope); // Repeat concatenations are not currently supported. if (repeat_) return false; // Test the operands of the concatenation. for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { // Empty expressions are not allowed in concatenations if (parms_[idx] == 0) return false; if (!parms_[idx]->is_collapsible_net(des, scope, port_type)) return false; } return true; } /* * This private method evaluates the part selects (if any) for the * signal. The sig argument is the NetNet already located for the * PEIdent name. The midx and lidx arguments are loaded with the * results, which may be the whole vector, or a single bit, or * anything in between. The values are in canonical indices. */ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig, long&midx, long&lidx) const { list prefix_indices; bool rc = calculate_packed_indices_(des, scope, sig, prefix_indices); ivl_assert(*this, rc); const name_component_t&name_tail = path_.back(); // Only treat as part/bit selects any index that is beyond the // word selects for an array. This is not an array, then // dimensions==0 and any index is treated as a select. if (name_tail.index.size() <= sig->unpacked_dimensions()) { midx = sig->vector_width()-1; lidx = 0; return true; } ivl_assert(*this, !name_tail.index.empty()); const index_component_t&index_tail = name_tail.index.back(); switch (index_tail.sel) { default: cerr << get_fileline() << ": internal error: " << "Unexpected sel_ value = " << index_tail.sel << endl; ivl_assert(*this, 0); break; case index_component_t::SEL_IDX_DO: case index_component_t::SEL_IDX_UP: { NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1, true); NetEConst*tmp = dynamic_cast(tmp_ex); if (!tmp) { cerr << get_fileline() << ": error: indexed part select of " << sig->name() << " must be a constant in this context." << endl; des->errors += 1; return 0; } /* The width (a constant) is calculated here. */ unsigned long wid = 0; bool flag = calculate_up_do_width_(des, scope, wid); if (! flag) return false; /* We have an undefined index and that is out of range. */ if (! tmp->value().is_defined()) { if (warn_ob_select) { cerr << get_fileline() << ": warning: " << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "['bx"; if (index_tail.sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] is always outside the vector." << endl; } return false; } long midx_val = tmp->value().as_long(); delete tmp_ex; if (prefix_indices.size()+1 < sig->packed_dims().size()) { // Here we are selecting one or more sub-arrays. // Make this work by finding the indexed sub-arrays and // creating a generated slice that spans the whole range. long loff, moff; unsigned long lwid, mwid; bool mrc, lrc; mrc = sig->sb_to_slice(prefix_indices, midx_val, moff, mwid); if (index_tail.sel == index_component_t::SEL_IDX_UP) lrc = sig->sb_to_slice(prefix_indices, midx_val+wid-1, loff, lwid); else lrc = sig->sb_to_slice(prefix_indices, midx_val-wid+1, loff, lwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << midx_val; if (index_tail.sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] exceeds the declared bounds for "; cerr << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, lwid == mwid); if (moff > loff) { lidx = loff; midx = moff + mwid - 1; } else { lidx = moff; midx = loff + lwid - 1; } } else { midx = sig->sb_to_idx(prefix_indices, midx_val); if (index_tail.sel == index_component_t::SEL_IDX_UP) lidx = sig->sb_to_idx(prefix_indices, midx_val+wid-1); else lidx = sig->sb_to_idx(prefix_indices, midx_val-wid+1); if (midx < lidx) { long tmpx = midx; midx = lidx; lidx = tmpx; } /* Warn about an indexed part select that is out of range. */ if (warn_ob_select && (lidx < 0)) { cerr << get_fileline() << ": warning: " << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "[" << midx_val; if (index_tail.sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] is selecting before vector." << endl; } if (warn_ob_select && (midx >= (long)sig->vector_width())) { cerr << get_fileline() << ": warning: " << sig->name(); if (sig->unpacked_dimensions() > 0) { cerr << "[]"; } cerr << "[" << midx_val; if (index_tail.sel == index_component_t::SEL_IDX_UP) { cerr << "+:"; } else { cerr << "-:"; } cerr << wid << "] is selecting after vector." << endl; } /* This is completely out side the signal so just skip it. */ if (lidx >= (long)sig->vector_width() || midx < 0) { return false; } } break; } case index_component_t::SEL_PART: { long msb, lsb; bool part_defined_flag; /* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag); /* We have an undefined index and that is out of range. */ if (!part_defined_flag) { if (warn_ob_select) { cerr << get_fileline() << ": warning: " << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "['bx] is always outside the vector." << endl; } return false; } if (prefix_indices.size()+1 < sig->packed_dims().size()) { // Here we have a slice that doesn't have enough indices // to get to a single slice. For example: // wire [9:0][5:1] foo // ... foo[4:3] ... // Make this work by finding the indexed slices and // creating a generated slice that spans the whole // range. long loff, moff; unsigned long lwid, mwid; bool lrc, mrc; lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid); mrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid); if (!mrc || !lrc) { cerr << get_fileline() << ": error: "; cerr << "Part-select [" << msb << ":" << lsb; cerr << "] exceeds the declared bounds for "; cerr << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, lwid == mwid); if (moff > loff) { lidx = loff; midx = moff + mwid - 1; } else { lidx = moff; midx = loff + lwid - 1; } } else { long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb); long midx_tmp = sig->sb_to_idx(prefix_indices, msb); /* Detect reversed indices of a part select. */ if (lidx_tmp > midx_tmp) { cerr << get_fileline() << ": error: Part select " << sig->name() << "[" << msb << ":" << lsb << "] indices reversed." << endl; cerr << get_fileline() << ": : Did you mean " << sig->name() << "[" << lsb << ":" << msb << "]?" << endl; long tmp = midx_tmp; midx_tmp = lidx_tmp; lidx_tmp = tmp; des->errors += 1; } /* Warn about a part select that is out of range. */ if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) { cerr << get_fileline() << ": warning: Part select " << sig->name(); if (sig->unpacked_dimensions() > 0) { cerr << "[]"; } cerr << "[" << msb << ":" << lsb << "] is out of range." << endl; } /* This is completely out side the signal so just skip it. */ if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) { return false; } midx = midx_tmp; lidx = lidx_tmp; } break; } case index_component_t::SEL_BIT: if (name_tail.index.size() > sig->unpacked_dimensions()) { long msb; bool bit_defined_flag; /* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag); /* We have an undefined index and that is out of range. */ if (!bit_defined_flag) { if (warn_ob_select) { cerr << get_fileline() << ": warning: " << sig->name(); if (sig->unpacked_dimensions() > 0) cerr << "[]"; cerr << "['bx] is always outside the vector." << endl; } return false; } if (prefix_indices.size()+2 <= sig->packed_dims().size()) { long tmp_loff; unsigned long tmp_lwid; bool rcl = sig->sb_to_slice(prefix_indices, msb, tmp_loff, tmp_lwid); ivl_assert(*this, rcl); midx = tmp_loff + tmp_lwid - 1; lidx = tmp_loff; } else { midx = sig->sb_to_idx(prefix_indices, msb); if (midx >= (long)sig->vector_width()) { cerr << get_fileline() << ": error: Index " << sig->name() << "[" << msb << "] is out of range." << endl; des->errors += 1; midx = 0; } lidx = midx; } } else { cerr << get_fileline() << ": internal error: " << "Bit select " << path_ << endl; ivl_assert(*this, 0); midx = sig->vector_width() - 1; lidx = 0; } break; } return true; } /* * This is the common code for l-value nets and bi-directional * nets. There is very little that is different between the two cases, * so most of the work for both is done here. */ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, bool bidirectional_flag) const { assert(scope); NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; symbol_search(this, des, scope, path_, sig, par, eve); if (eve != 0) { cerr << get_fileline() << ": error: named events (" << path_ << ") cannot be l-values in continuous " << "assignments." << endl; des->errors += 1; return 0; } pform_name_t base_path = path_; pform_name_t member_path; while (sig == 0 && !base_path.empty()) { symbol_search(this, des, scope, base_path, sig, par, eve); // Found it! if (sig != 0) break; // Not found. Try to pop another name off the base_path // and push it to the front of the member_path. member_path.push_front( base_path.back() ); base_path.pop_back(); } if (sig == 0) { cerr << get_fileline() << ": error: Net " << path_ << " is not defined in this context." << endl; des->errors += 1; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "Found l-value path_=" << path_ << " as sig=" << sig->name() << " base_path=" << base_path << " member_path=" << member_path << " unpacked_dimensions()=" << sig->unpacked_dimensions() << endl; } // If this is SystemVerilog and the variable is not yet // assigned by anything, then convert it to an unresolved // wire. if (gn_var_can_be_uwire() && (sig->type() == NetNet::REG) && (sig->peek_lref() == 0) ) { sig->type(NetNet::UNRESOLVED_WIRE); } // Don't allow registers as assign l-values. if (sig->type() == NetNet::REG) { cerr << get_fileline() << ": error: reg " << sig->name() << "; cannot be driven by primitives" << " or continuous assignment." << endl; des->errors += 1; return 0; } // Some parts below need the tail component. This is a convenient // reference to it. const name_component_t&path_tail = path_.back(); // Default part select is the entire word. unsigned midx = sig->vector_width()-1, lidx = 0; // The default word select is the first. long widx = 0; // Set this to true if we calculate the word index. This is // used to distinguish between unpacked array assignment and // array word assignment. bool widx_flag = false; list unpacked_indices_const; // Detect the net is a structure and there was a method path // detected. We have already broken the path_ into the path to // the net, and the path of member names. For example, if the // path_ is a.b.x.y, we have determined that a.b is a reference // to the net, and that x.y are the member_path. So in this case // we handle the member_path. const netstruct_t*struct_type = 0; if ((struct_type = sig->struct_type()) && !member_path.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: " << "Signal " << sig->name() << " is a structure, " << "try to match member path " << member_path << endl; } unsigned long member_off = 0; unsigned long member_width = sig->vector_width(); // Might be an array of structs, like a.b[N].x.y. (A packed // array.) Handle that here by taking a part select that // reflects the array index. if (sig->packed_dimensions() > 1) { listtmp_index = base_path.back().index; index_component_t member_select; member_select.sel = index_component_t::SEL_BIT; member_select.msb = new PENumber(new verinum(member_off)); tmp_index.push_back(member_select); NetExpr*packed_base = collapse_array_indices(des, scope, sig, tmp_index); if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "packed_base=" << *packed_base << endl; } long tmp; if (packed_base && eval_as_long(tmp, packed_base)) { member_off = tmp; member_width = struct_type->packed_width(); delete packed_base; packed_base = 0; } // Only support constant dimensions here. ivl_assert(*this, packed_base == 0); } // Now run through the member names, possibly nested, to take // further part selects reflected by the member name. So for // example, (.x.y) member x has an offset and width within the // containing vector, and member y an offset and width within // that. pform_name_t use_path = member_path; while (! use_path.empty()) { const name_component_t member_comp = use_path.front(); const perm_string&member_name = member_comp.name; unsigned long tmp_off; const struct netstruct_t::member_t*member = struct_type->packed_member(member_name, tmp_off); ivl_assert(*this, member); member_off += tmp_off; member_width = member->net_type->packed_width(); if (const netstruct_t*tmp_struct = dynamic_cast (member->net_type)) { struct_type = tmp_struct; } else { struct_type = 0; } use_path.pop_front(); } // Look for part selects on the final member. For example if // the path is a.b.x.y[3:0], the end of the member_path will // have an index that needs to be handled. // For now, assume there is unly a single part/bit select, and // assume it's constant. if (member_path.back().index.size() > 0) { listtmp_index = member_path.back().index; if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "Process trailing bit/part select. " << "index.size()=" << tmp_index.size() << endl; } ivl_assert(*this, tmp_index.size() == 1); const index_component_t&tail_sel = tmp_index.back(); ivl_assert(*this, tail_sel.sel == index_component_t::SEL_PART || tail_sel.sel == index_component_t::SEL_BIT); long tmp_off; unsigned long tmp_wid; bool rc = calculate_part(this, des, scope, tail_sel, tmp_off, tmp_wid); ivl_assert(*this, rc); member_off += tmp_off; member_width = tmp_wid; } if (debug_elaborate) { cerr << get_fileline() << ": " << __func__ << ": " << "Final, calculated member " << member_path << " offset=" << member_off << " width=" << member_width << endl; } // Rewrite a member select of a packed structure as a // part select of the base variable. lidx = member_off; midx = lidx + member_width - 1; // Elaborate an expression from the packed indices and // the member offset (into the structure) to get a // canonical expression into the packed signal vector. if (sig->packed_dimensions() > 1) { listtmp_index = base_path.back().index; index_component_t member_select; member_select.sel = index_component_t::SEL_BIT; member_select.msb = new PENumber(new verinum(member_off)); tmp_index.push_back(member_select); NetExpr*packed_base = collapse_array_indices(des, scope, sig, tmp_index); if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: " << "packed_base=" << *packed_base << ", member_off=" << member_off << endl; } } } else if (gn_system_verilog() && sig->unpacked_dimensions() > 0 && path_tail.index.empty()) { // In this case, we are doing a continuous assignment to // an unpacked array. The NetNet representation is a // NetNet with a pin for each array element, so there is // nothing more needed here. // // This can come up from code like this: // logic [...] data [0:3]; // assign data = ...; // In this case, "sig" is "data", and sig->pin_count() // is 4 to account for the unpacked size. if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: " << "Net assign to unpacked array \"" << sig->name() << "\" with " << sig->pin_count() << " elements." << endl; } } else if (sig->unpacked_dimensions() > 0) { // Make sure there are enough indices to address an array element. if (path_tail.index.size() < sig->unpacked_dimensions()) { cerr << get_fileline() << ": error: Array " << path() << " needs " << sig->unpacked_dimensions() << " indices," << " but got only " << path_tail.index.size() << ". (net)" << endl; des->errors += 1; return 0; } // Evaluate all the index expressions into an // "unpacked_indices" array. listunpacked_indices; indices_flags flags; indices_to_expressions(des, scope, this, path_tail.index, sig->unpacked_dimensions(), true, flags, unpacked_indices, unpacked_indices_const); if (flags.invalid) { return 0; } else if (flags.variable) { cerr << get_fileline() << ": error: array '" << sig->name() << "' index must be a constant in this context." << endl; des->errors += 1; return 0; } else if (flags.undefined) { cerr << get_fileline() << ": warning: " << "ignoring undefined l-value array access " << sig->name() << as_indices(unpacked_indices) << "." << endl; widx = -1; widx_flag = true; } else { NetExpr*canon_index = 0; ivl_assert(*this, unpacked_indices_const.size() == sig->unpacked_dimensions()); canon_index = normalize_variable_unpacked(sig, unpacked_indices_const); if (canon_index == 0) { cerr << get_fileline() << ": warning: " << "ignoring out of bounds l-value array access " << sig->name() << as_indices(unpacked_indices_const) << "." << endl; widx = -1; widx_flag = true; } else { NetEConst*canon_const = dynamic_cast(canon_index); ivl_assert(*this, canon_const); widx = canon_const->value().as_long(); widx_flag = true; delete canon_index; } } if (debug_elaborate) cerr << get_fileline() << ": debug: Use [" << widx << "]" << " to index l-value array." << endl; /* The array has a part/bit select at the end. */ if (path_tail.index.size() > sig->unpacked_dimensions()) { if (sig->get_scalar()) { cerr << get_fileline() << ": error: " << "can not select part of "; if (sig->data_type() == IVL_VT_REAL) cerr << "real"; else cerr << "scalar"; cerr << " array word: " << sig->name() << as_indices(unpacked_indices_const) << endl; des->errors += 1; return 0; } long midx_tmp, lidx_tmp; if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) return 0; if (lidx_tmp < 0) { cerr << get_fileline() << ": sorry: part selects " "straddling the start of signal (" << path_ << ") are not currently supported." << endl; des->errors += 1; return 0; } midx = midx_tmp; lidx = lidx_tmp; } } else if (!path_tail.index.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: " << "path_tail.index.size()=" << path_tail.index.size() << endl; } // There are index expressions on the name, so this is a // bit/slice select of the name. Calculate a canonical // part select. if (sig->get_scalar()) { cerr << get_fileline() << ": error: " << "can not select part of "; if (sig->data_type() == IVL_VT_REAL) cerr << "real: "; else cerr << "scalar: "; cerr << sig->name() << endl; des->errors += 1; return 0; } long midx_tmp, lidx_tmp; if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) return 0; if (lidx_tmp < 0) { cerr << get_fileline() << ": sorry: part selects " "straddling the start of signal (" << path_ << ") are not currently supported." << endl; des->errors += 1; return 0; } midx = midx_tmp; lidx = lidx_tmp; } unsigned subnet_wid = midx-lidx+1; /* Check if the l-value bits are double-driven. */ if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_and_set_part_driver(midx,lidx, widx_flag? widx : 0)) { cerr << get_fileline() << ": error: Unresolved net/uwire " << sig->name() << " cannot have multiple drivers." << endl; if (debug_elaborate) { cerr << get_fileline() << ": : Overlap in " << "[" << midx << ":" << lidx << "] (canonical)" << ", widx=" << (widx_flag? widx : 0) << ", vector width=" << sig->vector_width() << endl; } des->errors += 1; return 0; } if (sig->pin_count() > 1 && widx_flag) { if (widx < 0 || widx >= (long) sig->pin_count()) return 0; netvector_t*tmp2_vec = new netvector_t(sig->data_type(), sig->vector_width()-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), sig->type(), tmp2_vec); tmp->set_line(*this); tmp->local_flag(true); connect(sig->pin(widx), tmp->pin(0)); sig = tmp; } else if (sig->pin_count() > 1) { // If this turns out to be an l-value unpacked array, // then let the caller handle it. It will probably be // converted into an array of assignments. return sig; } /* If the desired l-value vector is narrower than the signal itself, then use a NetPartSelect node to arrange for connection to the desired bits. All this can be skipped if the desired width matches the original vector. */ if (subnet_wid != sig->vector_width()) { /* If we are processing a tran or inout, then the partselect is bi-directional. Otherwise, it is a Part-to-Vector select. */ if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Elaborate lnet part select " << sig->name() << "[base=" << lidx << " wid=" << subnet_wid <<"]" << endl; netvector_t*tmp2_vec = new netvector_t(sig->data_type(), subnet_wid-1,0); NetNet*subsig = new NetNet(sig->scope(), sig->scope()->local_symbol(), NetNet::WIRE, tmp2_vec); subsig->local_flag(true); subsig->set_line(*this); if (bidirectional_flag) { // Make a tran(VP) NetTran*sub = new NetTran(scope, scope->local_symbol(), sig->vector_width(), subnet_wid, lidx); sub->set_line(*this); des->add_node(sub); connect(sub->pin(0), sig->pin(0)); connect(sub->pin(1), subsig->pin(0)); } else { NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid, NetPartSelect::PV); des->add_node(sub); sub->set_line(*this); connect(sub->pin(0), subsig->pin(0)); collapse_partselect_pv_to_concat(des, sig); } sig = subsig; } return sig; } /* * Identifiers in continuous assignment l-values are limited to wires * and that ilk. Detect registers and memories here and report errors. */ NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const { return elaborate_lnet_common_(des, scope, false); } NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const { return elaborate_lnet_common_(des, scope, true); } /* * This method is used to elaborate identifiers that are ports to a * scope. The scope is presumed to be that of the module that has the * port. This elaboration is done inside the module, and is only done * to PEIdent objects. This method is used by elaboration of a module * instantiation (PGModule::elaborate_mod_) to get NetNet objects for * the port. */ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const { ivl_assert(*this, scope->type() == NetScope::MODULE); NetNet*sig = des->find_signal(scope, path_); if (sig == 0) { cerr << get_fileline() << ": error: no wire/reg " << path_ << " in module " << scope_path(scope) << "." << endl; des->errors += 1; return 0; } /* Check the port_type of the signal to make sure it is really a port, and its direction is resolved. */ switch (sig->port_type()) { case NetNet::PINPUT: case NetNet::POUTPUT: case NetNet::PINOUT: case NetNet::PREF: break; /* If the name matches, but the signal is not a port, then the user declared the object but there is no matching input/output/inout declaration. */ case NetNet::NOT_A_PORT: cerr << get_fileline() << ": error: signal " << path_ << " in" << " module " << scope_path(scope) << " is not a port." << endl; cerr << get_fileline() << ": : Are you missing an input/" << "output/inout declaration?" << endl; des->errors += 1; return 0; /* This should not happen. A PWire can only become PIMPLICIT if this is a UDP reg port, and the make_udp function should turn it into an output.... I think. */ case NetNet::PIMPLICIT: cerr << get_fileline() << ": internal error: signal " << path_ << " in module " << scope_path(scope) << " is left as " << "port type PIMPLICIT." << endl; des->errors += 1; return 0; } long midx; long lidx; if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_subport: " << "path_ = \"" << path_ << "\", unpacked_dimensions=" << sig->unpacked_dimensions() << ", port_type()=" << sig->port_type() << endl; } if (sig->unpacked_dimensions() && !gn_system_verilog()) { cerr << get_fileline() << ": error: " << "Ports cannot be unpacked arrays. Try enabling SystemVerilog support." << endl; des->errors += 1; return 0; } // There cannot be parts to an unpacked array, so process this // simply as an unpacked array. if (sig->unpacked_dimensions()) { if (debug_elaborate) { cerr << get_fileline() << ": PEIdent::elaborate_subport: " << "path_=\"" << path_ << "\" is an unpacked array with " << sig->pin_count() << " elements." << endl; } scope->add_module_port_net(sig); return sig; } /* Evaluate the part/bit select expressions, to get the part select of the signal that attaches to the port. Also handle range and direction checking here. */ if (! eval_part_select_(des, scope, sig, midx, lidx)) return 0; /* If this is a part select of the entire signal (or no part select at all) then we're done. */ if ((lidx == 0) && (midx == (long)sig->vector_width()-1)) { scope->add_module_port_net(sig); return sig; } unsigned swid = abs(midx - lidx) + 1; ivl_assert(*this, swid > 0 && swid < sig->vector_width()); netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp2_vec); tmp->port_type(sig->port_type()); tmp->set_line(*this); tmp->local_flag(true); NetNode*ps = 0; switch (sig->port_type()) { case NetNet::PINPUT: ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::PV); connect(tmp->pin(0), ps->pin(0)); sig = tmp; break; case NetNet::POUTPUT: ps = new NetPartSelect(sig, lidx, swid, NetPartSelect::VP); connect(tmp->pin(0), ps->pin(0)); sig = tmp; break; case NetNet::PREF: // For the purposes of module ports, treat ref ports // just like inout ports. case NetNet::PINOUT: ps = new NetTran(scope, scope->local_symbol(), sig->vector_width(), swid, lidx); connect(sig->pin(0), ps->pin(0)); connect(tmp->pin(0), ps->pin(1)); sig = tmp; break; default: ivl_assert(*this, 0); break; } ps->set_line(*this); des->add_node(ps); scope->add_module_port_net(sig); return sig; } NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const { NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; perm_string method_name; symbol_search(this, des, scope, path_, sig, par, eve); if (!sig) { cerr << get_fileline() << ": error: Net " << path_ << " is not defined in this context." << endl; des->errors += 1; return nullptr; } const name_component_t&name_tail = path_.back(); if (name_tail.index.size() != 0) { cerr << get_fileline() << ": sorry: Array slices are not yet " << "supported for continuous assignment." << endl; des->errors += 1; return nullptr; } return sig; } bool PEIdent::is_collapsible_net(Design*des, NetScope*scope, NetNet::PortType port_type) const { assert(scope); NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; symbol_search(this, des, scope, path_, sig, par, eve); if (eve != 0) return false; if (sig == 0) return false; assert(sig); /* If this is SystemVerilog and the variable is not yet assigned by anything, then convert it to an unresolved wire. */ if (gn_var_can_be_uwire() && (sig->type() == NetNet::REG) && (sig->peek_eref() == 0) && (port_type == NetNet::POUTPUT)) { sig->type(NetNet::UNRESOLVED_WIRE); } if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->pin(0).is_linked()) return false; if (sig->type() == NetNet::REG) return false; return true; } iverilog-12_0/elab_scope.cc000066400000000000000000001617601435245347300157650ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "compiler.h" # include "netmisc.h" # include "netvector.h" # include "netparray.h" # include # include # include # include /* * Elaboration happens in two passes, generally. The first scans the * pform to generate the NetScope tree and attach it to the Design * object. The methods in this source file implement the elaboration * of the scopes. */ # include "Module.h" # include "PClass.h" # include "PExpr.h" # include "PEvent.h" # include "PClass.h" # include "PGate.h" # include "PGenerate.h" # include "PPackage.h" # include "PTask.h" # include "PWire.h" # include "Statement.h" # include "AStatement.h" # include "netlist.h" # include "netclass.h" # include "netenum.h" # include "netqueue.h" # include "parse_api.h" # include "util.h" # include # include # include "ivl_assert.h" using namespace std; void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope) { scope->time_unit(pscope->time_unit); scope->time_precision(pscope->time_precision); scope->time_from_timescale(pscope->has_explicit_timescale()); des->set_precision(pscope->time_precision); } typedef map::const_iterator mparm_it_t; static void collect_parm_item(Design*des, NetScope*scope, perm_string name, const LexicalScope::param_expr_t&cur, bool is_annotatable) { if (debug_scopes) { cerr << cur.get_fileline() << ": " << __func__ << ": " << "parameter " << name << " "; if (cur.data_type) cerr << *cur.data_type; else cerr << "(nil type)"; ivl_assert(cur, cur.expr); cerr << " = " << *cur.expr << "; "; if (cur.range) cerr << "with ranges "; else cerr << "without ranges "; cerr << "; in scope " << scope_path(scope) << endl; } NetScope::range_t*range_list = 0; for (LexicalScope::range_t*range = cur.range ; range ; range = range->next) { NetScope::range_t*tmp = new NetScope::range_t; tmp->exclude_flag = range->exclude_flag; tmp->low_open_flag = range->low_open_flag; tmp->high_open_flag = range->high_open_flag; if (range->low_expr) { tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1); ivl_assert(*range->low_expr, tmp->low_expr); } else { tmp->low_expr = 0; } if (range->high_expr && range->high_expr==range->low_expr) { // Detect the special case of a "point" // range. These are called out by setting the high // and low expression ranges to the same // expression. The exclude_flags should be false // in this case ivl_assert(*range->high_expr, tmp->low_open_flag==false && tmp->high_open_flag==false); tmp->high_expr = tmp->low_expr; } else if (range->high_expr) { tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1); ivl_assert(*range->high_expr, tmp->high_expr); } else { tmp->high_expr = 0; } tmp->next = range_list; range_list = tmp; } // The type of the parameter, if unspecified in the source, will come // from the type of the value assigned to it. Therefore, if the type is // not yet known, don't try to guess here, put the type guess off. Also // don't try to elaborate it here, because there may be references to // other parameters still being located during scope elaboration. scope->set_parameter(name, is_annotatable, cur, range_list); } static void collect_scope_parameters(Design*des, NetScope*scope, const map¶meters) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " << "collect parameters for " << scope_path(scope) << "." << endl; } for (mparm_it_t cur = parameters.begin() ; cur != parameters.end() ; ++ cur ) { collect_parm_item(des, scope, cur->first, *(cur->second), false); } } static void collect_scope_specparams(Design*des, NetScope*scope, const map&specparams) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " << "collect specparams for " << scope_path(scope) << "." << endl; } for (mparm_it_t cur = specparams.begin() ; cur != specparams.end() ; ++ cur ) { collect_parm_item(des, scope, cur->first, *(cur->second), true); } } /* * Elaborate the enumeration into the given scope. */ static void elaborate_scope_enumeration(Design*des, NetScope*scope, enum_type_t*enum_type) { bool rc_flag; enum_type->elaborate_type(des, scope); netenum_t *use_enum = scope->enumeration_for_key(enum_type); size_t name_idx = 0; // Find the enumeration width. long raw_width = use_enum->packed_width(); assert(raw_width > 0); unsigned enum_width = (unsigned)raw_width; bool is_signed = use_enum->get_signed(); // Define the default start value and the increment value to be the // correct type for this enumeration. verinum cur_value ((uint64_t)0, enum_width); cur_value.has_sign(is_signed); verinum one_value ((uint64_t)1, enum_width); one_value.has_sign(is_signed); // Find the maximum allowed enumeration value. verinum max_value (0); if (is_signed) { max_value = pow(verinum(2), verinum(enum_width-1)) - one_value; } else { max_value = pow(verinum(2), verinum(enum_width)) - one_value; } max_value.has_sign(is_signed); // Variable to indicate when a defined value wraps. bool implicit_wrapped = false; // Process the enumeration definition. for (list::const_iterator cur = enum_type->names->begin() ; cur != enum_type->names->end() ; ++ cur, name_idx += 1) { // Check to see if the enumeration name has a value given. if (cur->parm) { // There is an explicit value. elaborate/evaluate // the value and assign it to the enumeration name. NetExpr*val = elab_and_eval(des, scope, cur->parm, -1); NetEConst*val_const = dynamic_cast (val); if (val_const == 0) { cerr << use_enum->get_fileline() << ": error: Enumeration expression for " << cur->name <<" is not an integer constant." << endl; des->errors += 1; continue; } cur_value = val_const->value(); // Clear the implicit wrapped flag if a parameter is given. implicit_wrapped = false; // A 2-state value can not have a constant with X/Z bits. if (use_enum->base_type() == IVL_VT_BOOL && ! cur_value.is_defined()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " can not have an undefined value." << endl; des->errors += 1; } // If this is a literal constant and it has a defined // width then the width must match the enumeration width. if (PENumber *tmp = dynamic_cast(cur->parm)) { if (tmp->value().has_len() && (tmp->value().len() != enum_width)) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has an incorrectly sized constant." << endl; des->errors += 1; } } // If we are padding/truncating a negative value for an // unsigned enumeration that is an error or if the new // value does not have a defined width. if (((cur_value.len() != enum_width) || ! cur_value.has_len()) && ! is_signed && cur_value.is_negative()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has a negative value." << endl; des->errors += 1; } // Narrower values need to be padded to the width of the // enumeration and defined to have the specified width. if (cur_value.len() < enum_width) { cur_value = pad_to_width(cur_value, enum_width); } // Some wider values can be truncated. if (cur_value.len() > enum_width) { unsigned check_width = enum_width - 1; // Check that the upper bits match the MSB for (unsigned idx = enum_width; idx < cur_value.len(); idx += 1) { if (cur_value[idx] != cur_value[check_width]) { // If this is an unsigned enumeration // then zero padding is okay. if (!is_signed && (idx == enum_width) && (cur_value[idx] == verinum::V0)) { check_width += 1; continue; } if (cur_value.is_defined()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has a value that is too " << ((cur_value > max_value) ? "large" : "small") << " " << cur_value << "." << endl; } else { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has trimmed bits that do " << "not match the enumeration " << "MSB: " << cur_value << "." << endl; } des->errors += 1; break; } } // If this is an unsigned value then make sure // The upper bits are not 1. if (! cur_value.has_sign() && (cur_value[enum_width] == verinum::V1)) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has a value that is too large: " << cur_value << "." << endl; des->errors += 1; break; } cur_value = verinum(cur_value, enum_width); } // At this point the value has the correct size and needs // to have the correct sign attribute set. cur_value.has_len(true); cur_value.has_sign(is_signed); } else if (! cur_value.is_defined()) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has an undefined inferred value." << endl; des->errors += 1; continue; } // Check to see if an implicitly wrapped value is used. if (implicit_wrapped) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " has an inferred value that overflowed." << endl; des->errors += 1; } // The enumeration value must be unique. perm_string dup_name = use_enum->find_value(cur_value); if (dup_name) { cerr << use_enum->get_fileline() << ": error: Enumeration name " << cur->name << " and " << dup_name << " have the same value: " << cur_value << endl; des->errors += 1; } rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value); rc_flag &= scope->add_enumeration_name(use_enum, cur->name); if (! rc_flag) { cerr << use_enum->get_fileline() << ": error: Duplicate enumeration name " << cur->name << endl; des->errors += 1; } // In case the next name has an implicit value, // increment the current value by one. if (cur_value.is_defined()) { if (cur_value == max_value) implicit_wrapped = true; cur_value = cur_value + one_value; } } use_enum->insert_name_close(); } static void elaborate_scope_enumerations(Design*des, NetScope*scope, const vector&enum_types) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " << "Elaborate " << enum_types.size() << " enumerations" << " in scope " << scope_path(scope) << "." << endl; } for (vector::const_iterator cur = enum_types.begin() ; cur != enum_types.end() ; ++ cur) { enum_type_t*curp = *cur; elaborate_scope_enumeration(des, scope, curp); } } /* * If the pclass includes an implicit and explicit constructor, then * merge the implicit constructor into the explicit constructor as * statements in the beginning. * * This is not necessary for proper functionality, it is an * optimization, so we can easily give up if it doesn't seem like it * will obviously work. */ static void blend_class_constructors(PClass*pclass) { perm_string new1 = perm_string::literal("new"); perm_string new2 = perm_string::literal("new@"); PFunction*use_new; PFunction*use_new2; // Locate the explicit constructor. map::iterator iter_new = pclass->funcs.find(new1); if (iter_new == pclass->funcs.end()) use_new = 0; else use_new = iter_new->second; // Locate the implicit constructor. map::iterator iter_new2 = pclass->funcs.find(new2); if (iter_new2 == pclass->funcs.end()) use_new2 = 0; else use_new2 = iter_new2->second; // If there are no constructors, then we are done. if (use_new==0 && use_new2==0) return; // While we're here, look for a super.new() call. If we find // it, strip it out of the constructor and set it aside for // when we actually call the chained constructor. PChainConstructor*chain_new = use_new? use_new->extract_chain_constructor() : 0; // If we do not have an explicit constructor chain, but there // is a parent class, then create an implicit chain. if (chain_new==0 && pclass->type->base_type) { chain_new = new PChainConstructor(pclass->type->base_args); chain_new->set_line(*pclass); } // If there are both an implicit and explicit constructor, // then blend the implicit constructor into the explicit // constructor. This eases the task for the elaborator later. if (use_new && use_new2) { // These constructors must be methods of the same class. ivl_assert(*use_new, use_new->method_of() == use_new2->method_of()); Statement*def_new = use_new->get_statement(); Statement*def_new2 = use_new2->get_statement(); // It is possible, i.e. recovering from a parse error, // for the statement from the constructor to be // missing. In that case, create an empty one. if (def_new==0) { def_new = new PBlock(PBlock::BL_SEQ); use_new->set_statement(def_new); } if (def_new2) use_new->push_statement_front(def_new2); // Now the implicit initializations are all built into // the constructor. Delete the "new@" constructor. pclass->funcs.erase(iter_new2); delete use_new2; use_new2 = 0; } if (chain_new) { if (use_new2) { use_new2->push_statement_front(chain_new); } else { use_new->push_statement_front(chain_new); } chain_new = 0; } } static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) { class_type_t*use_type = pclass->type; if (debug_scopes) { cerr << pclass->get_fileline() <<": elaborate_scope_class: " << "Elaborate scope class " << pclass->pscope_name() << " within scope " << scope_path(scope) << endl; } const netclass_t*use_base_class = 0; if (use_type->base_type) { ivl_type_t base_type = use_type->base_type->elaborate_type(des, scope); use_base_class = dynamic_cast(base_type); if (!use_base_class) { cerr << pclass->get_fileline() << ": error: " << "Base type of " << use_type->name << " is not a class." << endl; des->errors += 1; } } netclass_t*use_class = new netclass_t(use_type->name, use_base_class); NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()), NetScope::CLASS, scope->unit()); class_scope->set_line(pclass); class_scope->set_class_def(use_class); use_class->set_class_scope(class_scope); use_class->set_definition_scope(scope); use_class->set_virtual(use_type->virtual_class); set_scope_timescale(des, class_scope, pclass); class_scope->add_typedefs(&pclass->typedefs); collect_scope_parameters(des, class_scope, pclass->parameters); // Elaborate enum types declared in the class. We need these // now because enumeration constants can be used during scope // elaboration. if (debug_scopes) { cerr << pclass->get_fileline() << ": elaborate_scope_class: " << "Elaborate " << pclass->enum_sets.size() << " enumerations" << " in class " << scope_path(class_scope) << ", scope=" << scope_path(scope) << "." << endl; } elaborate_scope_enumerations(des, class_scope, pclass->enum_sets); for (map::iterator cur = pclass->tasks.begin() ; cur != pclass->tasks.end() ; ++cur) { hname_t use_name (cur->first); NetScope*method_scope = new NetScope(class_scope, use_name, NetScope::TASK); // Task methods are always automatic... if (!cur->second->is_auto()) { cerr << "error: Lifetime of method `" << scope_path(method_scope) << "` must not be static" << endl; des->errors += 1; } method_scope->is_auto(true); method_scope->set_line(cur->second); method_scope->add_imports(&cur->second->explicit_imports); if (debug_scopes) { cerr << cur->second->get_fileline() << ": elaborate_scope_class: " << "Elaborate method (task) scope " << scope_path(method_scope) << endl; } cur->second->elaborate_scope(des, method_scope); } for (map::iterator cur = pclass->funcs.begin() ; cur != pclass->funcs.end() ; ++cur) { hname_t use_name (cur->first); NetScope*method_scope = new NetScope(class_scope, use_name, NetScope::FUNC); // Function methods are always automatic... if (!cur->second->is_auto()) { cerr << "error: Lifetime of method `" << scope_path(method_scope) << "` must not be static" << endl; des->errors += 1; } method_scope->is_auto(true); method_scope->set_line(cur->second); method_scope->add_imports(&cur->second->explicit_imports); if (debug_scopes) { cerr << cur->second->get_fileline() << ": elaborate_scope_class: " << "Elaborate method (function) scope " << scope_path(method_scope) << endl; } cur->second->elaborate_scope(des, method_scope); } scope->add_class(use_class); } static void elaborate_scope_classes(Design*des, NetScope*scope, const vector&classes) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " << "Elaborate " << classes.size() << " classes" << " in scope " << scope_path(scope) << "." << endl; } for (size_t idx = 0 ; idx < classes.size() ; idx += 1) { blend_class_constructors(classes[idx]); elaborate_scope_class(des, scope, classes[idx]); } } static void replace_scope_parameters(Design *des, NetScope*scope, const LineInfo&loc, const Module::replace_t&replacements) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " << "Replace scope parameters for " << scope_path(scope) << "." << endl; } for (Module::replace_t::const_iterator cur = replacements.begin() ; cur != replacements.end() ; ++ cur ) { PExpr*val = (*cur).second; if (val == 0) { cerr << loc.get_fileline() << ": internal error: " << "Missing expression in parameter replacement for " << (*cur).first << endl;; } assert(val); if (debug_scopes) { cerr << loc.get_fileline() << ": debug: " << "Replace " << (*cur).first << " with expression " << *val << " from " << val->get_fileline() << "." << endl; cerr << loc.get_fileline() << ": : " << "Type=" << val->expr_type() << endl; } scope->replace_parameter(des, (*cur).first, val, scope->parent()); } } static void elaborate_scope_events_(Design*des, NetScope*scope, const map&events) { for (map::const_iterator et = events.begin() ; et != events.end() ; ++ et ) { (*et).second->elaborate_scope(des, scope); } } static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task) { hname_t use_name( task->pscope_name() ); NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK); task_scope->is_auto(task->is_auto()); task_scope->set_line(task); task_scope->add_imports(&task->explicit_imports); if (debug_scopes) { cerr << task->get_fileline() << ": elaborate_scope_task: " << "Elaborate task scope " << scope_path(task_scope) << endl; } task->elaborate_scope(des, task_scope); } static void elaborate_scope_tasks(Design*des, NetScope*scope, const map&tasks) { typedef map::const_iterator tasks_it_t; for (tasks_it_t cur = tasks.begin() ; cur != tasks.end() ; ++ cur ) { elaborate_scope_task(des, scope, cur->second); } } static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task) { hname_t use_name( task->pscope_name() ); NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC); task_scope->is_auto(task->is_auto()); task_scope->set_line(task); task_scope->add_imports(&task->explicit_imports); if (debug_scopes) { cerr << task->get_fileline() << ": elaborate_scope_func: " << "Elaborate function scope " << scope_path(task_scope) << endl; } task->elaborate_scope(des, task_scope); } static void elaborate_scope_funcs(Design*des, NetScope*scope, const map&funcs) { typedef map::const_iterator funcs_it_t; for (funcs_it_t cur = funcs.begin() ; cur != funcs.end() ; ++ cur ) { elaborate_scope_func(des, scope, cur->second); } } class generate_schemes_work_item_t : public elaborator_work_item_t { public: generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod) : elaborator_work_item_t(des__), scope_(scope), mod_(mod) { } void elaborate_runrun() { if (debug_scopes) cerr << mod_->get_fileline() << ": debug: " << "Processing generate schemes for " << scope_path(scope_) << endl; // Generate schemes can create new scopes in the form of // generated code. Scan the generate schemes, and *generate* // new scopes, which is slightly different from simple // elaboration. typedef list::const_iterator generate_it_t; for (generate_it_t cur = mod_->generate_schemes.begin() ; cur != mod_->generate_schemes.end() ; ++ cur ) { (*cur) -> generate_scope(des, scope_); } } private: // The scope_ is the scope that contains the generate scheme // we are to work on. the mod_ is the Module definition for // that scope, and contains the parsed generate schemes. NetScope*scope_; Module*mod_; }; bool PPackage::elaborate_scope(Design*des, NetScope*scope) { if (debug_scopes) { cerr << get_fileline() << ": PPackage::elaborate_scope: " << "Elaborate package " << scope_path(scope) << "." << endl; } scope->add_typedefs(&typedefs); collect_scope_parameters(des, scope, parameters); if (debug_scopes) { cerr << get_fileline() << ": PPackage::elaborate_scope: " << "Elaborate " << enum_sets.size() << " enumerations" << " in package scope " << scope_path(scope) << "." << endl; } elaborate_scope_enumerations(des, scope, enum_sets); elaborate_scope_classes(des, scope, classes_lexical); elaborate_scope_funcs(des, scope, funcs); elaborate_scope_tasks(des, scope, tasks); elaborate_scope_events_(des, scope, events); return true; } bool Module::elaborate_scope(Design*des, NetScope*scope, const replace_t&replacements) { if (debug_scopes) { cerr << get_fileline() << ": Module::elaborate_scope: " << "Elaborate " << scope_path(scope) << "." << endl; } scope->add_typedefs(&typedefs); // Add the genvars to the scope. typedef map::const_iterator genvar_it_t; for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); ++ cur ) { scope->add_genvar((*cur).first, (*cur).second); } // Scan the parameters in the module, and store the information // needed to evaluate the parameter expressions. The expressions // will be evaluated later, once all parameter overrides for this // module have been done. collect_scope_parameters(des, scope, parameters); collect_scope_specparams(des, scope, specparams); // Run parameter replacements that were collected from the // containing scope and meant for me. replace_scope_parameters(des, scope, *this, replacements); elaborate_scope_enumerations(des, scope, enum_sets); assert(classes.size() == classes_lexical.size()); elaborate_scope_classes(des, scope, classes_lexical); // Run through the defparams for this module and save the result // in a table for later final override. typedef list::const_iterator defparms_iter_t; for (defparms_iter_t cur = defparms.begin() ; cur != defparms.end() ; ++ cur ) { scope->defparams.push_back(make_pair(cur->first, cur->second)); } // Evaluate the attributes. Evaluate them in the scope of the // module that the attribute is attached to. Is this correct? unsigned nattr; attrib_list_t*attr = evaluate_attributes(attributes, nattr, des, scope); for (unsigned idx = 0 ; idx < nattr ; idx += 1) scope->attribute(attr[idx].key, attr[idx].val); delete[]attr; // Generate schemes need to have their scopes elaborated, but // we can not do that until defparams are run, so push it off // into an elaborate work item. if (debug_scopes) cerr << get_fileline() << ": " << __func__ << ": " << "Schedule generates within " << scope_path(scope) << " for elaboration after defparams." << endl; des->elaboration_work_list.push_back(new generate_schemes_work_item_t(des, scope, this)); // Tasks introduce new scopes, so scan the tasks in this // module. Create a scope for the task and pass that to the // elaborate_scope method of the PTask for detailed // processing. elaborate_scope_tasks(des, scope, tasks); // Functions are very similar to tasks, at least from the // perspective of scopes. So handle them exactly the same // way. elaborate_scope_funcs(des, scope, funcs); // Look for implicit modules and implicit gates for them. for (map::iterator cur = nested_modules.begin() ; cur != nested_modules.end() ; ++cur) { // Skip modules that must be explicitly instantiated. if (cur->second->port_count() > 0) continue; PGModule*nested_gate = new PGModule(cur->second, cur->second->mod_name()); nested_gate->set_line(*cur->second); gates_.push_back(nested_gate); } // Gates include modules, which might introduce new scopes, so // scan all of them to create those scopes. typedef list::const_iterator gates_it_t; for (gates_it_t cur = gates_.begin() ; cur != gates_.end() ; ++ cur ) { (*cur) -> elaborate_scope(des, scope); } // initial and always blocks may contain begin-end and // fork-join blocks that can introduce scopes. Therefore, I // get to scan processes here. typedef list::const_iterator proc_it_t; for (proc_it_t cur = behaviors.begin() ; cur != behaviors.end() ; ++ cur ) { (*cur) -> statement() -> elaborate_scope(des, scope); } // Scan through all the named events in this scope. We do not // need anything more than the current scope to do this // elaboration, so do it now. This allows for normal // elaboration to reference these events. elaborate_scope_events_(des, scope, events); scope->is_cell(is_cell); return des->errors == 0; } bool PGenerate::generate_scope(Design*des, NetScope*container) { switch (scheme_type) { case GS_LOOP: return generate_scope_loop_(des, container); case GS_CONDIT: return generate_scope_condit_(des, container, false); case GS_ELSE: return generate_scope_condit_(des, container, true); case GS_CASE: return generate_scope_case_(des, container); case GS_NBLOCK: return generate_scope_nblock_(des, container); case GS_CASE_ITEM: cerr << get_fileline() << ": internal error: " << "Case item outside of a case generate scheme?" << endl; return false; default: cerr << get_fileline() << ": sorry: Generate of this sort" << " is not supported yet!" << endl; return false; } } void PGenerate::check_for_valid_genvar_value_(long value) { if (generation_flag < GN_VER2005 && value < 0) { cerr << get_fileline() << ": warning: A negative value (" << value << ") has been assigned to genvar '" << loop_index << "'." << endl; cerr << get_fileline() << ": : This is illegal in " "Verilog-2001. Use at least -g2005 to remove this warning." << endl; } } /* * This is the elaborate scope method for a generate loop. */ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container) { if (!local_index) { // Check that the loop_index variable was declared in a // genvar statement. NetScope*cscope = container; while (cscope && !cscope->find_genvar(loop_index)) { if (cscope->symbol_exists(loop_index)) { cerr << get_fileline() << ": error: " << "generate loop variable '" << loop_index << "' is not a genvar in this scope." << endl; des->errors += 1; return false; } cscope = cscope->parent(); } if (!cscope) { cerr << get_fileline() << ": error: genvar is missing for " "generate \"loop\" variable '" << loop_index << "'." << endl; des->errors += 1; return false; } } // We're going to need a genvar... long genvar; // The initial value for the genvar does not need (nor can it // use) the genvar itself, so we can evaluate this expression // the same way any other parameter value is evaluated. NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1, true); NetEConst*init = dynamic_cast (init_ex); if (init == 0) { cerr << get_fileline() << ": error: Cannot evaluate genvar" << " init expression: " << *loop_init << endl; des->errors += 1; return false; } genvar = init->value().as_long(); check_for_valid_genvar_value_(genvar); delete init_ex; if (debug_scopes) cerr << get_fileline() << ": debug: genvar init = " << genvar << endl; container->genvar_tmp = loop_index; container->genvar_tmp_val = genvar; NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1, true); NetEConst*test = dynamic_cast(test_ex); if (test == 0) { cerr << get_fileline() << ": error: Cannot evaluate genvar" << " conditional expression: " << *loop_test << endl; des->errors += 1; return false; } while (test->value().as_long()) { // The actual name of the scope includes the genvar so // that each instance has a unique name in the // container. The format of using [] is part of the // Verilog standard. hname_t use_name (scope_name, genvar); if (debug_scopes) cerr << get_fileline() << ": debug: " << "Create generated scope " << use_name << endl; NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); scope->add_imports(&explicit_imports); // Set in the scope a localparam for the value of the // genvar within this instance of the generate // block. Code within this scope thus has access to the // genvar as a constant. { verinum genvar_verinum; if (gn_strict_expr_width_flag) genvar_verinum = verinum(genvar, integer_width); else genvar_verinum = verinum(genvar); genvar_verinum.has_sign(true); NetEConstParam*gp = new NetEConstParam(scope, loop_index, genvar_verinum); // The file and line information should really come // from the genvar statement, not the for loop. scope->set_parameter(loop_index, gp, *this); if (debug_scopes) cerr << get_fileline() << ": debug: " << "Create implicit localparam " << loop_index << " = " << genvar_verinum << endl; } elaborate_subscope_(des, scope); // Calculate the step for the loop variable. NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1, true); NetEConst*step = dynamic_cast(step_ex); if (step == 0) { cerr << get_fileline() << ": error: Cannot evaluate genvar" << " step expression: " << *loop_step << endl; des->errors += 1; return false; } if (debug_scopes) cerr << get_fileline() << ": debug: genvar step from " << genvar << " to " << step->value().as_long() << endl; genvar = step->value().as_long(); check_for_valid_genvar_value_(genvar); container->genvar_tmp_val = genvar; delete step; delete test_ex; test_ex = elab_and_eval(des, container, loop_test, -1, true); test = dynamic_cast(test_ex); assert(test); } // Clear the genvar_tmp field in the scope to reflect that the // genvar is no longer valid for evaluating expressions. container->genvar_tmp = perm_string(); return true; } bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag) { NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1, true); NetEConst*test = dynamic_cast (test_ex); if (test == 0) { cerr << get_fileline() << ": error: Cannot evaluate genvar" << " conditional expression: " << *loop_test << endl; des->errors += 1; return false; } // If the condition evaluates as false, then do not create the // scope. if ( (test->value().as_long() == 0 && !else_flag) || (test->value().as_long() != 0 && else_flag) ) { if (debug_scopes) cerr << get_fileline() << ": debug: Generate condition " << (else_flag? "(else)" : "(if)") << " value=" << test->value() << ": skip generation" << endl; delete test_ex; return true; } hname_t use_name (scope_name); if (debug_scopes) cerr << get_fileline() << ": debug: Generate condition " << (else_flag? "(else)" : "(if)") << " value=" << test->value() << ": Generate scope=" << use_name << endl; if (directly_nested) { if (debug_scopes) cerr << get_fileline() << ": debug: Generate condition " << (else_flag? "(else)" : "(if)") << " detected direct nesting." << endl; elaborate_subscope_direct_(des, container); return true; } // If this is not directly nested, then generate a scope // for myself. That is what I will pass to the subscope. NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); scope->add_imports(&explicit_imports); elaborate_subscope_(des, scope); return true; } bool PGenerate::generate_scope_case_(Design*des, NetScope*container) { NetExpr*case_value_ex = elab_and_eval(des, container, loop_test, -1, true); NetEConst*case_value_co = dynamic_cast(case_value_ex); if (case_value_co == 0) { cerr << get_fileline() << ": error: Cannot evaluate genvar case" << " expression: " << *loop_test << endl; des->errors += 1; return false; } if (debug_scopes) cerr << get_fileline() << ": debug: Generate case " << "switch value=" << case_value_co->value() << endl; PGenerate*default_item = 0; typedef list::const_iterator generator_it_t; generator_it_t cur = generate_schemes.begin(); while (cur != generate_schemes.end()) { PGenerate*item = *cur; assert( item->scheme_type == PGenerate::GS_CASE_ITEM ); // Detect that the item is a default. if (item->item_test.size() == 0) { default_item = item; ++ cur; continue; } bool match_flag = false; for (unsigned idx = 0 ; idx < item->item_test.size() && !match_flag ; idx +=1 ) { NetExpr*item_value_ex = elab_and_eval(des, container, item->item_test[idx], -1, true); NetEConst*item_value_co = dynamic_cast(item_value_ex); if (item_value_co == 0) { cerr << get_fileline() << ": error: Cannot evaluate " << " genvar case item expression: " << *item->item_test[idx] << endl; des->errors += 1; return false; } if (debug_scopes) cerr << get_fileline() << ": debug: Generate case " << "item value=" << item_value_co->value() << endl; if (case_value_co->value() == item_value_co->value()) match_flag = true; delete item_value_co; } // If we stumble on the item that matches, then break out now. if (match_flag) break; ++ cur; } delete case_value_co; case_value_co = 0; PGenerate*item = (cur == generate_schemes.end())? default_item : *cur; if (item == 0) { cerr << get_fileline() << ": debug: " << "No generate items found" << endl; return true; } if (debug_scopes) cerr << get_fileline() << ": debug: " << "Generate case matches item at " << item->get_fileline() << endl; // The name of the scope to generate, whatever that item is. hname_t use_name (item->scope_name); if (item->directly_nested) { if (debug_scopes) cerr << get_fileline() << ": debug: Generate case item " << scope_name << " detected direct nesting." << endl; item->elaborate_subscope_direct_(des, container); return true; } if (debug_scopes) { cerr << get_fileline() << ": PGenerate::generate_scope_case_: " << "Generate subscope " << use_name << " and elaborate." << endl; } NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); scope->add_imports(&explicit_imports); item->elaborate_subscope_(des, scope); return true; } bool PGenerate::generate_scope_nblock_(Design*des, NetScope*container) { hname_t use_name (scope_name); if (debug_scopes) cerr << get_fileline() << ": debug: Generate named block " << ": Generate scope=" << use_name << endl; NetScope*scope = new NetScope(container, use_name, NetScope::GENBLOCK); scope->set_line(get_file(), get_lineno()); scope->add_imports(&explicit_imports); elaborate_subscope_(des, scope); return true; } void PGenerate::elaborate_subscope_direct_(Design*des, NetScope*scope) { typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { PGenerate*curp = *cur; if (debug_scopes) { cerr << get_fileline() << ": elaborate_subscope_direct_: " << "Elaborate direct subscope " << curp->scope_name << " within scope " << scope_name << endl; } curp -> generate_scope(des, scope); } } void PGenerate::elaborate_subscope_(Design*des, NetScope*scope) { scope->add_typedefs(&typedefs); // Add the genvars to this scope. typedef map::const_iterator genvar_it_t; for (genvar_it_t cur = genvars.begin(); cur != genvars.end(); ++ cur ) { scope->add_genvar((*cur).first, (*cur).second); } // Scan the parameters in this scope, and store the information // needed to evaluate the parameter expressions. The expressions // will be evaluated later, once all parameter overrides for this // module have been done. collect_scope_parameters(des, scope, parameters); // Run through the defparams for this scope and save the result // in a table for later final override. typedef list::const_iterator defparms_iter_t; for (defparms_iter_t cur = defparms.begin() ; cur != defparms.end() ; ++ cur ) { scope->defparams.push_back(make_pair(cur->first, cur->second)); } // Scan the generated scope for nested generate schemes, // and *generate* new scopes, which is slightly different // from simple elaboration. typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur) -> generate_scope(des, scope); } // Scan through all the task and function declarations in this // scope. elaborate_scope_tasks(des, scope, tasks); elaborate_scope_funcs(des, scope, funcs); // Scan the generated scope for gates that may create // their own scopes. typedef list::const_iterator pgate_list_it_t; for (pgate_list_it_t cur = gates.begin() ; cur != gates.end() ; ++ cur ) { (*cur) ->elaborate_scope(des, scope); } typedef list::const_iterator proc_it_t; for (proc_it_t cur = behaviors.begin() ; cur != behaviors.end() ; ++ cur ) { (*cur) -> statement() -> elaborate_scope(des, scope); } // Scan through all the named events in this scope. elaborate_scope_events_(des, scope, events); if (debug_scopes) cerr << get_fileline() << ": debug: Generated scope " << scope_path(scope) << " for generate block " << scope_name << endl; // Save the scope that we created, for future use. scope_list_.push_back(scope); } class delayed_elaborate_scope_mod_instances : public elaborator_work_item_t { public: delayed_elaborate_scope_mod_instances(Design*des__, const PGModule*obj, Module*mod, NetScope*sc) : elaborator_work_item_t(des__), obj_(obj), mod_(mod), sc_(sc) { } ~delayed_elaborate_scope_mod_instances() { } virtual void elaborate_runrun(); private: const PGModule*obj_; Module*mod_; NetScope*sc_; }; void delayed_elaborate_scope_mod_instances::elaborate_runrun() { if (debug_scopes) cerr << obj_->get_fileline() << ": debug: " << "Resume scope elaboration of instances of " << mod_->mod_name() << "." << endl; obj_->elaborate_scope_mod_instances_(des, mod_, sc_); } /* * Here we handle the elaborate scope of a module instance. The caller * has already figured out that this "gate" is a module, and has found * the module definition. The "sc" argument is the scope that will * contain this instance. */ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const { if (get_name() == "") { cerr << get_fileline() << ": error: Instantiation of module " << mod->mod_name() << " requires an instance name." << endl; des->errors += 1; return; } // Missing module instance names have already been rejected. assert(get_name() != ""); // check for recursive instantiation by scanning the current // scope and its parents. Look for a module instantiation of // the same module, but farther up in the scope. unsigned rl_count = 0; bool in_genblk = false; for (NetScope*scn = sc ; scn ; scn = scn->parent()) { // We need to know if we are inside a generate block to allow // recursive instances. if (scn->type() == NetScope::GENBLOCK) { in_genblk = true; continue; } if (scn->type() != NetScope::MODULE) continue; if (strcmp(mod->mod_name(), scn->module_name()) != 0) continue; // We allow nested scopes if they are inside a generate block, // but only to a certain nesting depth. if (in_genblk) { rl_count += 1; if (rl_count > recursive_mod_limit) { cerr << get_fileline() << ": error: instance " << scope_path(sc) << "." << get_name() << " of module " << mod->mod_name() << " is nested too deep." << endl; cerr << get_fileline() << ": : check for " "proper recursion termination or increase the " "limit (" << recursive_mod_limit << ") with the -pRECURSIVE_MOD_LIMIT flag." << endl; des->errors += 1; return; } continue; } cerr << get_fileline() << ": error: You can not instantiate " << "module " << mod->mod_name() << " within itself." << endl; cerr << get_fileline() << ": : The offending instance is " << get_name() << " within " << scope_path(scn) << "." << endl; des->errors += 1; return; } if (is_array()) { // If there are expressions to evaluate in order to know // the actual number of instances that will be // instantiated, then we have to delay further scope // elaboration until after defparams (above me) are // run. Do that by appending a work item to the // elaboration work list. if (debug_scopes) cerr << get_fileline() << ": debug: delay elaborate_scope" << " of array of " << get_name() << " in scope " << scope_path(sc) << "." << endl; elaborator_work_item_t*tmp = new delayed_elaborate_scope_mod_instances(des, this, mod, sc); des->elaboration_work_list.push_back(tmp); } else { // If there are no expressions that need to be evaluated // to elaborate the scope of this next instances, then // get right to it. elaborate_scope_mod_instances_(des, mod, sc); } } /* * This method is called to process a module instantiation after basic * sanity testing is already complete. */ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const { long instance_low = 0; long instance_high = 0; long instance_count = calculate_array_size_(des, sc, instance_high, instance_low); if (instance_count == 0) return; NetScope::scope_vec_t instances (instance_count); struct attrib_list_t*attrib_list; unsigned attrib_list_n = 0; attrib_list = evaluate_attributes(attributes, attrib_list_n, des, sc); // Run through the module instances, and make scopes out of // them. Also do parameter overrides that are done on the // instantiation line. for (int idx = 0 ; idx < instance_count ; idx += 1) { hname_t use_name (get_name()); if (is_array()) { int instance_idx; if (instance_low < instance_high) instance_idx = instance_low + idx; else instance_idx = instance_low - idx; use_name = hname_t(get_name(), instance_idx); } if (debug_scopes) { cerr << get_fileline() << ": debug: Module instance " << use_name << " becomes child of " << scope_path(sc) << "." << endl; } // Create the new scope as a MODULE with my name. Note // that if this is a nested module, mark it thus so that // scope searches will continue into the parent scope. NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE, 0, bound_type_? true : false, mod->program_block, mod->is_interface); my_scope->set_line(get_file(), mod->get_file(), get_lineno(), mod->get_lineno()); my_scope->set_module_name(mod->mod_name()); my_scope->add_imports(&mod->explicit_imports); for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) my_scope->attribute(attrib_list[adx].key, attrib_list[adx].val); instances[idx] = my_scope; set_scope_timescale(des, my_scope, mod); // Look for module parameter replacements. The "replace" map // maps parameter name to replacement expression that is // passed. It is built up by the ordered overrides or named // overrides. Module::replace_t replace; // Positional parameter overrides are matched to parameter // names by using the param_names list of parameter // names. This is an ordered list of names so the first name // is parameter 0, the second parameter 1, and so on. if (overrides_) { assert(parms_ == 0); list::const_iterator cur = mod->param_names.begin(); list::const_iterator jdx = overrides_->begin(); for (;;) { if (jdx == overrides_->end()) break; // If we reached here we have more overrides than // module parameters, so print a warning. if (cur == mod->param_names.end()) { cerr << get_fileline() << ": warning: " "ignoring " << overrides_->size() - mod->param_names.size() << " extra parameter override(s) for " "instance '" << use_name << "' of module '" << mod->mod_name() << "' which expects " << mod->param_names.size() << " parameter(s)." << endl; break; } // No expression means that the parameter is not // replaced at all. if (*jdx) replace[*cur] = *jdx; ++ jdx; ++ cur; } } // Named parameter overrides carry a name with each override // so the mapping into the replace list is much easier. if (parms_) { assert(overrides_ == 0); for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1) { // No expression means that the parameter is not // replaced. if (parms_[jdx].parm) replace[parms_[jdx].name] = parms_[jdx].parm; } } // This call actually arranges for the description of the // module type to process this instance and handle parameters // and sub-scopes that might occur. Parameters are also // created in that scope, as they exist. (I'll override them // later.) mod->elaborate_scope(des, my_scope, replace); } delete[]attrib_list; /* Stash the instance array of scopes into the parent scope. Later elaboration passes will use this vector to further elaborate the array. Note that the array is ordered from LSB to MSB. We will use that fact in the main elaborate to connect things in the correct order. */ sc->instance_arrays[get_name()] = instances; } /* * The isn't really able to create new scopes, but it does create the * event name in the current scope, so can be done during the * elaborate_scope scan. Note that the name_ of the PEvent object has * no hierarchy, but neither does the NetEvent, until it is stored in * the NetScope object. */ void PEvent::elaborate_scope(Design*, NetScope*scope) const { NetEvent*ev = new NetEvent(name_); ev->set_line(*this); scope->add_event(ev); } void PFunction::elaborate_scope(Design*des, NetScope*scope) const { ivl_assert(*this, scope->type() == NetScope::FUNC); // Save a reference to the pform representation of the function // in case we need to perform early elaboration. scope->set_func_pform(this); // Assume the function is a constant function until we // find otherwise. scope->is_const_func(true); scope->add_typedefs(&typedefs); // Scan the parameters in the function, and store the information // needed to evaluate the parameter expressions. collect_scope_parameters(des, scope, parameters); // Scan through all the named events in this scope. elaborate_scope_events_(des, scope, events); if (statement_) statement_->elaborate_scope(des, scope); } void PTask::elaborate_scope(Design*des, NetScope*scope) const { assert(scope->type() == NetScope::TASK); scope->add_typedefs(&typedefs); // Scan the parameters in the task, and store the information // needed to evaluate the parameter expressions. collect_scope_parameters(des, scope, parameters); // Scan through all the named events in this scope. elaborate_scope_events_(des, scope, events); if (statement_) statement_->elaborate_scope(des, scope); } /* * The base statement does not have sub-statements and does not * introduce any scope, so this is a no-op. */ void Statement::elaborate_scope(Design*, NetScope*) const { } /* * When I get a behavioral block, check to see if it has a name. If it * does, then create a new scope for the statements within it, * otherwise use the current scope. Use the selected scope to scan the * statements that I contain. */ void PBlock::elaborate_scope(Design*des, NetScope*scope) const { NetScope*my_scope = scope; if (pscope_name() != 0) { hname_t use_name(pscope_name()); if (debug_scopes) cerr << get_fileline() << ": debug: " << "Elaborate block scope " << use_name << " within " << scope_path(scope) << endl; // The scope type is begin-end or fork-join. The // sub-types of fork-join are not interesting to the scope. my_scope = new NetScope(scope, use_name, bl_type_!=BL_SEQ ? NetScope::FORK_JOIN : NetScope::BEGIN_END); my_scope->set_line(get_file(), get_lineno()); my_scope->is_auto(scope->is_auto()); my_scope->add_imports(&explicit_imports); my_scope->add_typedefs(&typedefs); // Scan the parameters in the scope, and store the information // needed to evaluate the parameter expressions. collect_scope_parameters(des, my_scope, parameters); // Scan through all the named events in this scope. elaborate_scope_events_(des, my_scope, events); } for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) list_[idx] -> elaborate_scope(des, my_scope); } /* * The case statement itself does not introduce scope, but contains * other statements that may be named blocks. So scan the case items * with the elaborate_scope method. */ void PCase::elaborate_scope(Design*des, NetScope*scope) const { assert(items_); for (unsigned idx = 0 ; idx < (*items_).size() ; idx += 1) { assert( (*items_)[idx] ); if (Statement*sp = (*items_)[idx]->stat) sp -> elaborate_scope(des, scope); } } /* * The conditional statement (if-else) does not introduce scope, but * the statements of the clauses may, so elaborate_scope the contained * statements. */ void PCondit::elaborate_scope(Design*des, NetScope*scope) const { if (if_) if_ -> elaborate_scope(des, scope); if (else_) else_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PDelayStatement::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PDoWhile::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PEventStatement::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * The standard says that we create an implicit scope for foreach * loops, but that is just to hold the index variables, and we'll * handle them by creating unique names. So just jump into the * contained statement for scope elaboration. */ void PForeach::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PForever::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PForStatement::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PRepeat::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } /* * Statements that contain a further statement but do not * intrinsically add a scope need to elaborate_scope the contained * statement. */ void PWhile::elaborate_scope(Design*des, NetScope*scope) const { if (statement_) statement_ -> elaborate_scope(des, scope); } iverilog-12_0/elab_sig.cc000066400000000000000000001102261435245347300154250ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / 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 # include # include # include "Module.h" # include "PClass.h" # include "PExpr.h" # include "PGate.h" # include "PGenerate.h" # include "PPackage.h" # include "PTask.h" # include "PWire.h" # include "Statement.h" # include "compiler.h" # include "netlist.h" # include "netmisc.h" # include "netclass.h" # include "netenum.h" # include "netvector.h" # include "netdarray.h" # include "netparray.h" # include "netqueue.h" # include "netscalar.h" # include "util.h" # include "ivl_assert.h" using namespace std; #if 0 /* These functions are not currently used. */ static bool get_const_argument(NetExpr*exp, verinum&res) { switch (exp->expr_type()) { case IVL_VT_REAL: { NetECReal*cv = dynamic_cast(exp); if (cv == 0) return false; verireal tmp = cv->value(); res = verinum(tmp.as_long()); break; } case IVL_VT_BOOL: case IVL_VT_LOGIC: { NetEConst*cv = dynamic_cast(exp); if (cv == 0) return false; res = cv->value(); break; } default: assert(0);; } return true; } static bool get_const_argument(NetExpr*exp, long&res) { verinum tmp; bool rc = get_const_argument(exp, tmp); if (rc == false) return false; res = tmp.as_long(); return true; } #endif void Statement::elaborate_sig(Design*, NetScope*) const { } static void sig_check_data_type(Design*des, NetScope*scope, PWire *wire, NetNet *sig) { ivl_type_t type = sig->net_type(); if (!type) return; if (type->packed()) { switch (type->base_type()) { case IVL_VT_LOGIC: // 4-state packed is allowed by the standard case IVL_VT_BOOL: // Icarus allows 2-state packed as an extension return; default: break; } } // Icarus allows real nets as an extension if (type->base_type() == IVL_VT_REAL) return; if (wire->symbol_type() == PNamedItem::NET) { cerr << wire->get_fileline() << ": error: Net `" << wire->basename() << "` can not be of type `" << sig->data_type() << "`." << endl; des->errors++; } else if (scope->type() == NetScope::MODULE && sig->port_type() != NetNet::NOT_A_PORT) { // Module ports only support wire types a the moment cerr << wire->get_fileline() << ": sorry: Port `" << wire->basename() << "` of module `" << scope->module_name() << "` with type `" << sig->data_type() << "` is not supported." << endl; des->errors++; } } static void sig_check_port_type(Design*des, NetScope*scope, PWire *wire, NetNet *sig) { if (sig->port_type() == NetNet::PREF) { cerr << wire->get_fileline() << ": sorry: " << "Reference ports not supported yet." << endl; des->errors += 1; } // Some extra checks for module ports if (scope->type() != NetScope::MODULE) return; /* If the signal is an input and is also declared as a reg, then report an error. In SystemVerilog a input is allowed to be a register. It will get converted to a unresolved wire when the port is connected. */ if (sig->port_type() == NetNet::PINPUT && sig->type() == NetNet::REG && !gn_var_can_be_uwire()) { cerr << wire->get_fileline() << ": error: Port `" << wire->basename() << "` of module `" << scope->module_name() << "` is declared as input and as a reg type." << endl; des->errors += 1; } if (sig->port_type() == NetNet::PINOUT && sig->type() == NetNet::REG) { cerr << wire->get_fileline() << ": error: Port `" << wire->basename() << "` of module `" << scope->module_name() << "` is declared as inout and as a reg type." << endl; des->errors += 1; } if (sig->port_type() == NetNet::PINOUT && sig->data_type() == IVL_VT_REAL) { cerr << wire->get_fileline() << ": error: Port `" << wire->basename() << "` of module `" << scope->module_name() << "` is declared as a real inout port." << endl; des->errors += 1; } } bool PScope::elaborate_sig_wires_(Design*des, NetScope*scope) const { bool flag = true; for (map::const_iterator wt = wires.begin() ; wt != wires.end() ; ++ wt ) { PWire*cur = (*wt).second; NetNet*sig = cur->elaborate_sig(des, scope); if (!sig || sig->scope() != scope) continue; sig_check_data_type(des, scope, cur, sig); sig_check_port_type(des, scope, cur, sig); } return flag; } static void elaborate_sig_funcs(Design*des, NetScope*scope, const map&funcs) { typedef map::const_iterator mfunc_it_t; for (mfunc_it_t cur = funcs.begin() ; cur != funcs.end() ; ++ cur ) { hname_t use_name ( (*cur).first ); NetScope*fscope = scope->child(use_name); if (fscope == 0) { cerr << (*cur).second->get_fileline() << ": internal error: " << "Child scope for function " << (*cur).first << " missing in " << scope_path(scope) << "." << endl; des->errors += 1; continue; } if (debug_elaborate) { cerr << cur->second->get_fileline() << ": elaborate_sig_funcs: " << "Elaborate function " << use_name << " in " << scope_path(fscope) << endl; } cur->second->elaborate_sig(des, fscope); } } static void elaborate_sig_tasks(Design*des, NetScope*scope, const map&tasks) { typedef map::const_iterator mtask_it_t; for (mtask_it_t cur = tasks.begin() ; cur != tasks.end() ; ++ cur ) { NetScope*tscope = scope->child( hname_t((*cur).first) ); assert(tscope); (*cur).second->elaborate_sig(des, tscope); } } static void elaborate_sig_classes(Design*des, NetScope*scope, const map&classes) { for (map::const_iterator cur = classes.begin() ; cur != classes.end() ; ++ cur) { netclass_t*use_class = scope->find_class(des, cur->second->pscope_name()); use_class->elaborate_sig(des, cur->second); } } bool PPackage::elaborate_sig(Design*des, NetScope*scope) const { bool flag = true; if (debug_elaborate) { cerr << get_fileline() << ": PPackage::elaborate_sig: " << "Start package scope=" << scope_path(scope) << endl; } flag = elaborate_sig_wires_(des, scope) && flag; // After all the wires are elaborated, we are free to // elaborate the ports of the tasks defined within this // module. Run through them now. elaborate_sig_funcs(des, scope, funcs); elaborate_sig_tasks(des, scope, tasks); elaborate_sig_classes(des, scope, classes); if (debug_elaborate) { cerr << get_fileline() << ": PPackage::elaborate_sig: " << "Done package scope=" << scope_path(scope) << ", flag=" << flag << endl; } return flag; } bool Module::elaborate_sig(Design*des, NetScope*scope) const { bool flag = true; // Scan all the ports of the module, and make sure that each // is connected to wires that have port declarations. for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { Module::port_t*pp = ports[idx]; if (pp == 0) continue; // The port has a name and an array of expressions. The // expression are all identifiers that should reference // wires within the scope. map::const_iterator wt; for (unsigned cc = 0 ; cc < pp->expr.size() ; cc += 1) { pform_name_t port_path (pp->expr[cc]->path()); // A concatenated wire of a port really should not // have any hierarchy. if (port_path.size() != 1) { cerr << get_fileline() << ": internal error: " << "Port " << port_path << " has a funny name?" << endl; des->errors += 1; } wt = wires.find(peek_tail_name(port_path)); if (wt == wires.end()) { cerr << get_fileline() << ": error: " << "Port " << port_path << " (" << (idx+1) << ") of module " << mod_name() << " is not declared within module." << endl; des->errors += 1; continue; } if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) { cerr << get_fileline() << ": error: " << "Port " << pp->expr[cc]->path() << " (" << (idx+1) << ") of module " << mod_name() << " has no direction declaration." << endl; des->errors += 1; } } } flag = elaborate_sig_wires_(des, scope) && flag; // Run through all the generate schemes to elaborate the // signals that they hold. Note that the generate schemes hold // the scopes that they instantiated, so we don't pass any // scope in. typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur) -> elaborate_sig(des, scope); } // Get all the gates of the module and elaborate them by // connecting them to the signals. The gate may be simple or // complex. What we are looking for is gates that are modules // that can create scopes and signals. const list&gl = get_gates(); for (list::const_iterator gt = gl.begin() ; gt != gl.end() ; ++ gt ) { flag &= (*gt)->elaborate_sig(des, scope); } // After all the wires are elaborated, we are free to // elaborate the ports of the tasks defined within this // module. Run through them now. elaborate_sig_funcs(des, scope, funcs); elaborate_sig_tasks(des, scope, tasks); elaborate_sig_classes(des, scope, classes); // initial and always blocks may contain begin-end and // fork-join blocks that can introduce scopes. Therefore, I // get to scan processes here. typedef list::const_iterator proc_it_t; for (proc_it_t cur = behaviors.begin() ; cur != behaviors.end() ; ++ cur ) { (*cur) -> statement() -> elaborate_sig(des, scope); } return flag; } void netclass_t::elaborate_sig(Design*des, PClass*pclass) { // Collect the properties, elaborate them, and add them to the // elaborated class definition. for (map::iterator cur = pclass->type->properties.begin() ; cur != pclass->type->properties.end() ; ++ cur) { ivl_type_t use_type = cur->second.type->elaborate_type(des, class_scope_); if (debug_scopes) { cerr << pclass->get_fileline() << ": elaborate_scope_class: " << " Property " << cur->first << " type=" << *use_type << endl; } if (dynamic_cast (use_type)) { cerr << cur->second.get_fileline() << ": sorry: " << "Queues inside classes are not yet supported." << endl; des->errors++; } set_property(cur->first, cur->second.qual, use_type); if (! cur->second.qual.test_static()) continue; if (debug_elaborate) { cerr << pclass->get_fileline() << ": netclass_t::elaborate_sig: " << "Elaborate static property " << cur->first << " as signal in scope " << scope_path(class_scope_) << "." << endl; } list nil_list; /* NetNet*sig = */ new NetNet(class_scope_, cur->first, NetNet::REG, nil_list, use_type); } for (map::iterator cur = pclass->funcs.begin() ; cur != pclass->funcs.end() ; ++ cur) { if (debug_elaborate) { cerr << cur->second->get_fileline() << ": netclass_t::elaborate_sig: " << "Elaborate signals in function method " << cur->first << endl; } NetScope*scope = class_scope_->child( hname_t(cur->first) ); ivl_assert(*cur->second, scope); cur->second->elaborate_sig(des, scope); } for (map::iterator cur = pclass->tasks.begin() ; cur != pclass->tasks.end() ; ++ cur) { if (debug_elaborate) { cerr << cur->second->get_fileline() << ": netclass_t::elaborate_sig: " << "Elaborate signals in task method " << cur->first << endl; } NetScope*scope = class_scope_->child( hname_t(cur->first) ); ivl_assert(*cur->second, scope); cur->second->elaborate_sig(des, scope); } } bool PGate::elaborate_sig(Design*, NetScope*) const { return true; } bool PGBuiltin::elaborate_sig(Design*, NetScope*) const { return true; } bool PGAssign::elaborate_sig(Design*, NetScope*) const { return true; } bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope, Module*rmod) const { bool flag = true; NetScope::scope_vec_t instance = scope->instance_arrays[get_name()]; for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) { // I know a priori that the elaborate_scope created the scope // already, so just look it up as a child of the current scope. NetScope*my_scope = instance[idx]; assert(my_scope); if (my_scope->parent() != scope) { cerr << get_fileline() << ": internal error: " << "Instance " << scope_path(my_scope) << " is in parent " << scope_path(my_scope->parent()) << " instead of " << scope_path(scope) << endl; } assert(my_scope->parent() == scope); if (! rmod->elaborate_sig(des, my_scope)) flag = false; } return flag; } // Not currently used. #if 0 bool PGModule::elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const { return true; } #endif bool PGenerate::elaborate_sig(Design*des, NetScope*container) const { if (directly_nested) return elaborate_sig_direct_(des, container); bool flag = true; // Handle the special case that this is a CASE scheme. In this // case the PGenerate itself does not have the generated // item. Look instead for the case ITEM that has a scope // generated for it. if (scheme_type == PGenerate::GS_CASE) { if (debug_elaborate) cerr << get_fileline() << ": debug: generate case" << " elaborate_sig in scope " << scope_path(container) << "." << endl; typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { PGenerate*item = *cur; if (item->directly_nested || !item->scope_list_.empty()) { flag &= item->elaborate_sig(des, container); } } return flag; } typedef list::const_iterator scope_list_it_t; for (scope_list_it_t cur = scope_list_.begin() ; cur != scope_list_.end() ; ++ cur ) { NetScope*scope = *cur; if (scope->parent() != container) continue; if (debug_elaborate) cerr << get_fileline() << ": debug: Elaborate nets in " << "scope " << scope_path(*cur) << " in generate " << id_number << endl; flag = elaborate_sig_(des, *cur) & flag; } return flag; } bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "Direct nesting " << scope_name << " (scheme_type=" << scheme_type << ")" << " elaborate_sig in scope " << scope_path(container) << "." << endl; // Elaborate_sig for a direct nested generated scheme knows // that there are only sub_schemes to be elaborated. There // should be exactly 1 active generate scheme, search for it // using this loop. bool flag = true; typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { PGenerate*item = *cur; if (item->scheme_type == PGenerate::GS_CASE) { for (generate_it_t icur = item->generate_schemes.begin() ; icur != item->generate_schemes.end() ; ++ icur ) { PGenerate*case_item = *icur; if (case_item->directly_nested || !case_item->scope_list_.empty()) { flag &= case_item->elaborate_sig(des, container); } } } else { if (item->directly_nested || !item->scope_list_.empty()) { // Found the item, and it is direct nested. flag &= item->elaborate_sig(des, container); } } } return flag; } bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const { // Scan the declared PWires to elaborate the obvious signals // in the current scope. typedef map::const_iterator wires_it_t; for (wires_it_t wt = wires.begin() ; wt != wires.end() ; ++ wt ) { PWire*cur = (*wt).second; if (debug_elaborate) cerr << get_fileline() << ": debug: Elaborate PWire " << cur->basename() << " in scope " << scope_path(scope) << endl; cur->elaborate_sig(des, scope); } elaborate_sig_funcs(des, scope, funcs); elaborate_sig_tasks(des, scope, tasks); typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur) -> elaborate_sig(des, scope); } typedef list::const_iterator pgate_list_it_t; for (pgate_list_it_t cur = gates.begin() ; cur != gates.end() ; ++ cur ) { (*cur) ->elaborate_sig(des, scope); } typedef list::const_iterator proc_it_t; for (proc_it_t cur = behaviors.begin() ; cur != behaviors.end() ; ++ cur ) { (*cur) -> statement() -> elaborate_sig(des, scope); } return true; } /* * A function definition exists within an elaborated module. This * matters when elaborating signals, as the ports of the function are * created as signals/variables for each instance of the * function. That is why PFunction has an elaborate_sig method. */ void PFunction::elaborate_sig(Design*des, NetScope*scope) const { if (scope->elab_stage() > 1) return; scope->set_elab_stage(2); perm_string fname = scope->basename(); assert(scope->type() == NetScope::FUNC); elaborate_sig_wires_(des, scope); NetNet*ret_sig; if (gn_system_verilog() && (fname=="new" || fname=="new@")) { // Special case: this is a constructor, so the return // signal is also the first argument. For example, the // source code for the definition may be: // function new(...); // endfunction // In this case, the "@" port (THIS_TOKEN) is the synthetic // "this" argument and we also use it as a return value at // the same time. ret_sig = scope->find_signal(perm_string::literal(THIS_TOKEN)); ivl_assert(*this, ret_sig); if (debug_elaborate) cerr << get_fileline() << ": PFunction::elaborate_sig: " << "Scope " << scope_path(scope) << " is a CONSTRUCTOR, so use \"this\" argument" << " as return value." << endl; } else { ivl_type_t ret_type; if (return_type_) { if (dynamic_cast (return_type_)) { ret_type = 0; } else { ret_type = return_type_->elaborate_type(des, scope->parent()); ivl_assert(*this, ret_type); } } else { netvector_t*tmp = new netvector_t(IVL_VT_LOGIC); ret_type = tmp; } if (ret_type) { if (debug_elaborate) { cerr << get_fileline() << ": PFunction::elaborate_sig: " << "return type: " << *ret_type << endl; if (return_type_) return_type_->pform_dump(cerr, 8); } list ret_unpacked; ret_sig = new NetNet(scope, fname, NetNet::REG, ret_unpacked, ret_type); ret_sig->set_line(*this); ret_sig->port_type(NetNet::POUTPUT); } else { ret_sig = 0; if (debug_elaborate) { cerr << get_fileline() << ": PFunction::elaborate_sig: " << "Detected that function is void." << endl; } } } vectorports; vectorpdef; elaborate_sig_ports_(des, scope, ports, pdef); NetFuncDef*def = new NetFuncDef(scope, ret_sig, ports, pdef); if (debug_elaborate) cerr << get_fileline() << ": PFunction::elaborate_sig: " << "Attach function definition " << scope_path(scope) << " with ret_sig width=" << (ret_sig? ret_sig->vector_width() : 0) << "." << endl; scope->set_func_def(def); // Look for further signals in the sub-statement if (statement_) statement_->elaborate_sig(des, scope); } /* * A task definition is a scope within an elaborated module. When we * are elaborating signals, the scopes have already been created, as * have the reg objects that are the parameters of this task. The * elaborate_sig method of PTask is therefore left to connect the * signals to the ports of the NetTaskDef definition. We know for * certain that signals exist (They are in my scope!) so the port * binding is sure to work. */ void PTask::elaborate_sig(Design*des, NetScope*scope) const { assert(scope->type() == NetScope::TASK); elaborate_sig_wires_(des, scope); vectorports; vectorpdefs; elaborate_sig_ports_(des, scope, ports, pdefs); NetTaskDef*def = new NetTaskDef(scope, ports, pdefs); scope->set_task_def(def); // Look for further signals in the sub-statement if (statement_) statement_->elaborate_sig(des, scope); } void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope, vector&ports, vector&pdefs) const { if (ports_ == 0) { ports.clear(); pdefs.clear(); /* Make sure the function has at least one input port. If it fails this test, print an error message. Keep going so we can find more errors. */ if (scope->type()==NetScope::FUNC && !gn_system_verilog()) { cerr << get_fileline() << ": error: " << "Function " << scope->basename() << " has no ports." << endl; cerr << get_fileline() << ": : " << "Functions must have at least one input port." << endl; des->errors += 1; } return; } ports.resize(ports_->size()); pdefs.resize(ports_->size()); for (size_t idx = 0 ; idx < ports_->size() ; idx += 1) { perm_string port_name = ports_->at(idx).port->basename(); ports[idx] = 0; pdefs[idx] = 0; NetNet*tmp = scope->find_signal(port_name); NetExpr*tmp_def = 0; if (tmp == 0) { cerr << get_fileline() << ": internal error: " << "task/function " << scope_path(scope) << " is missing port " << port_name << "." << endl; scope->dump(cerr); cerr << get_fileline() << ": Continuing..." << endl; des->errors += 1; continue; } // If the port has a default expression, elaborate // that expression here. if (ports_->at(idx).defe != 0) { if (tmp->port_type() == NetNet::PINPUT) { // Elaborate a class port default in the context of // the class type. if (tmp->data_type() == IVL_VT_CLASS) { tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe, tmp->net_type(), scope->need_const_func()); } else { tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe, -1, scope->need_const_func()); } if (tmp_def == 0) { cerr << get_fileline() << ": error: Unable to evaluate " << *ports_->at(idx).defe << " as a port default expression." << endl; des->errors += 1; } } else { cerr << get_fileline() << ": sorry: Default arguments " "for subroutine output or inout ports are not " "yet supported." << endl; des->errors += 1; } } if (tmp->port_type() == NetNet::NOT_A_PORT) { cerr << get_fileline() << ": internal error: " << "task/function " << scope_path(scope) << " port " << port_name << " is a port but is not a port?" << endl; des->errors += 1; scope->dump(cerr); continue; } ports[idx] = tmp; pdefs[idx] = tmp_def; if (scope->type()==NetScope::FUNC && tmp->port_type()!=NetNet::PINPUT) { cerr << tmp->get_fileline() << ": error: " << "Function " << scope_path(scope) << " port " << port_name << " is not an input port." << endl; cerr << tmp->get_fileline() << ": : " << "Function arguments must be input ports." << endl; des->errors += 1; } if (tmp->unpacked_dimensions() != 0) { cerr << get_fileline() << ": sorry: Subroutine ports with " "unpacked dimensions are not yet supported." << endl; des->errors += 1; } } } void PBlock::elaborate_sig(Design*des, NetScope*scope) const { NetScope*my_scope = scope; if (pscope_name() != 0) { hname_t use_name (pscope_name()); my_scope = scope->child(use_name); if (my_scope == 0) { cerr << get_fileline() << ": internal error: " << "Unable to find child scope " << pscope_name() << " in this context?" << endl; des->errors += 1; my_scope = scope; } else { if (debug_elaborate) cerr << get_fileline() << ": debug: " << "elaborate_sig descending into " << scope_path(my_scope) << "." << endl; elaborate_sig_wires_(des, my_scope); } } // elaborate_sig in the statements included in the // block. There may be named blocks in there. for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) list_[idx] -> elaborate_sig(des, my_scope); } void PCase::elaborate_sig(Design*des, NetScope*scope) const { if (items_ == 0) return; for (unsigned idx = 0 ; idx < items_->size() ; idx += 1) { if ( (*items_)[idx]->stat ) (*items_)[idx]->stat ->elaborate_sig(des,scope); } } void PCondit::elaborate_sig(Design*des, NetScope*scope) const { if (if_) if_->elaborate_sig(des, scope); if (else_) else_->elaborate_sig(des, scope); } void PDelayStatement::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PDoWhile::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PEventStatement::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PForeach::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PForever::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PForStatement::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PRepeat::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } void PWhile::elaborate_sig(Design*des, NetScope*scope) const { if (statement_) statement_->elaborate_sig(des, scope); } bool test_ranges_eeq(const vector&lef, const vector&rig) { if (lef.size() != rig.size()) return false; vector::const_iterator lcur = lef.begin(); vector::const_iterator rcur = rig.begin(); while (lcur != lef.end()) { if (lcur->get_msb() != rcur->get_msb()) return false; if (lcur->get_lsb() != rcur->get_lsb()) return false; ++ lcur; ++ rcur; } return true; } ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope, const std::vector&packed_dimensions) const { vector_type_t *vec_type = dynamic_cast(set_data_type_.get()); if (set_data_type_ && !vec_type) { ivl_assert(*this, packed_dimensions.empty()); return set_data_type_->elaborate_type(des, scope); } // Fallback method. Create vector type. ivl_variable_type_t use_data_type; if (vec_type) { use_data_type = vec_type->base_type; } else { use_data_type = IVL_VT_LOGIC; } if (use_data_type == IVL_VT_NO_TYPE) { use_data_type = IVL_VT_LOGIC; if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " << "Signal " << name_ << " in scope " << scope_path(scope) << " defaults to data type " << use_data_type << endl; } } ivl_assert(*this, use_data_type == IVL_VT_LOGIC || use_data_type == IVL_VT_BOOL); netvector_t*vec = new netvector_t(packed_dimensions, use_data_type); vec->set_signed(get_signed()); return vec; } /* * Elaborate a source wire. The "wire" is the declaration of wires, * registers, ports and memories. The parser has already merged the * multiple properties of a wire (i.e., "input wire"), so come the * elaboration this creates an object in the design that represents the * defined item. */ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const { // This sets the vector or array dimension size that will // cause a warning. For now, these warnings are permanently // enabled. const long warn_dimension_size = 1 << 30; NetNet::Type wtype = type_; if (wtype == NetNet::IMPLICIT) wtype = NetNet::WIRE; // Certain contexts, such as arguments to functions, presume // "reg" instead of "wire". The parser reports these as // IMPLICIT_REG. if (wtype == NetNet::IMPLICIT_REG) wtype = NetNet::REG; if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " << "Signal " << basename() << ", wtype=" << wtype; if (set_data_type_) cerr << ", set_data_type_=" << *set_data_type_; cerr << ", unpacked_.size()=" << unpacked_.size() << endl; } unsigned wid = 1; vectorpacked_dimensions; des->errors += error_cnt_; if (port_set_ || net_set_) { if (warn_implicit_dimensions && port_set_ && net_set_ && net_.empty() && !port_.empty()) { cerr << get_fileline() << ": warning: " << "var/net declaration of " << basename() << " inherits dimensions from port declaration." << endl; } if (warn_implicit_dimensions && port_set_ && net_set_ && port_.empty() && !net_.empty()) { cerr << get_fileline() << ": warning: " << "Port declaration of " << basename() << " inherits dimensions from var/net." << endl; } bool dimensions_ok = true; vector plist, nlist; /* If they exist get the port definition MSB and LSB */ if (port_set_ && !port_.empty()) { if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " << "Evaluate ranges for port " << basename() << endl; } dimensions_ok &= evaluate_ranges(des, scope, this, plist, port_); } assert(port_set_ || port_.empty()); /* If they exist get the net/etc. definition MSB and LSB */ if (net_set_ && !net_.empty() && dimensions_ok) { nlist.clear(); if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " << "Evaluate ranges for net " << basename() << endl; } dimensions_ok &= evaluate_ranges(des, scope, this, nlist, net_); } assert(net_set_ || net_.empty()); if (debug_elaborate) { cerr << get_fileline() << ": PWire::elaborate_sig: " << "Calculated ranges for " << basename() << ". Now check for consistency." << endl; } /* We have a port size error. Skip this if the dimensions could not * be evaluated since it will likely print nonsensical errors. */ if (port_set_ && net_set_ && !test_ranges_eeq(plist, nlist) && dimensions_ok) { /* Scalar port with a vector net/etc. definition */ if (port_.empty()) { if (gn_io_range_error_flag) { cerr << get_fileline() << ": error: Scalar port ``" << name_ << "'' has a vectored net declaration " << nlist << "." << endl; des->errors += 1; } else if (warn_anachronisms) { cerr << get_fileline() << ": warning: Scalar port ``" << name_ << "'' has a vectored net declaration " << nlist << "." << endl; } } /* Vectored port with a scalar net/etc. definition */ if (net_.empty()) { cerr << port_.front().first->get_fileline() << ": error: Vectored port ``" << name_ << "'' " << plist << " has a scalar net declaration at " << get_fileline() << "." << endl; des->errors += 1; } /* Both vectored, but they have different ranges. */ if (!port_.empty() && !net_.empty()) { cerr << port_.front().first->get_fileline() << ": error: Vectored port ``" << name_ << "'' " << plist << " has a net declaration " << nlist << " at " << net_.front().first->get_fileline() << " that does not match." << endl; des->errors += 1; } } packed_dimensions = net_set_ ? nlist : plist; wid = netrange_width(packed_dimensions); if (wid > warn_dimension_size) { cerr << get_fileline() << ": warning: Vector size " "is greater than " << warn_dimension_size << "." << endl; } } unsigned nattrib = 0; attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib, des, scope); /* If the net type is supply0 or supply1, replace it with a simple wire with a pulldown/pullup with supply strength. In other words, transform: supply0 foo; to: wire foo; pulldown #(supply0) (foo); This reduces the backend burden, and behaves exactly the same. */ NetLogic*pull = 0; if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) { if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Generate a SUPPLY pull for the "; if (wtype == NetNet::SUPPLY0) cerr << "supply0"; else cerr << "supply1"; cerr << " net." << endl; } NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1) ? NetLogic::PULLUP : NetLogic::PULLDOWN; pull = new NetLogic(scope, scope->local_symbol(), 1, pull_type, wid); pull->set_line(*this); pull->pin(0).drive0(IVL_DR_SUPPLY); pull->pin(0).drive1(IVL_DR_SUPPLY); des->add_node(pull); wtype = NetNet::WIRE; } ivl_type_t type = elaborate_type(des, scope, packed_dimensions); // Create the type for the unpacked dimensions. If the // unpacked_dimensions are empty this will just return the base type. type = elaborate_array_type(des, scope, *this, type, unpacked_); list unpacked_dimensions; // If this is an unpacked array extract the base type and unpacked // dimensions as these are separate properties of the NetNet. while (const netuarray_t *atype = dynamic_cast(type)) { unpacked_dimensions.insert(unpacked_dimensions.begin(), atype->static_dimensions().begin(), atype->static_dimensions().end()); type = atype->element_type(); } if (debug_elaborate) { cerr << get_fileline() << ": debug: Create signal " << wtype; if (set_data_type_) cout << " " << *set_data_type_; cout << name_ << unpacked_dimensions << " in scope " << scope_path(scope) << endl; } NetNet*sig = new NetNet(scope, name_, wtype, unpacked_dimensions, type); if (wtype == NetNet::WIRE) sig->devirtualize_pins(); sig->set_line(*this); sig->port_type(port_type_); if (ivl_discipline_t dis = get_discipline()) { sig->set_discipline(dis); } if (pull) connect(sig->pin(0), pull->pin(0)); for (unsigned idx = 0 ; idx < nattrib ; idx += 1) sig->attribute(attrib_list[idx].key, attrib_list[idx].val); return sig; } iverilog-12_0/elab_sig_analog.cc000066400000000000000000000016571435245347300167550ustar00rootroot00000000000000/* * 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" # include # include iverilog-12_0/elab_type.cc000066400000000000000000000333211435245347300156240ustar00rootroot00000000000000/* * Copyright (c) 2012-2020 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 "PExpr.h" # include "PScope.h" # include "pform_types.h" # include "netlist.h" # include "netclass.h" # include "netdarray.h" # include "netenum.h" # include "netqueue.h" # include "netparray.h" # include "netscalar.h" # include "netstruct.h" # include "netvector.h" # include "netmisc.h" # include # include "ivl_assert.h" using namespace std; /* * Elaborations of types may vary depending on the scope that it is * done in, so keep a per-scope cache of the results. */ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope) { scope = find_scope(des, scope); Definitions*use_definitions = scope; map::iterator pos = cache_type_elaborate_.lower_bound(use_definitions); if (pos != cache_type_elaborate_.end() && pos->first == use_definitions) return pos->second; ivl_type_t tmp; if (elaborating) { des->errors++; cerr << get_fileline() << ": error: " << "Circular type definition found involving `" << *this << "`." << endl; // Try to recover tmp = netvector_t::integer_type(); } else { elaborating = true; tmp = elaborate_type_raw(des, scope); elaborating = false; } cache_type_elaborate_.insert(pos, pair(scope, tmp)); return tmp; } NetScope *data_type_t::find_scope(Design *, NetScope *scope) const { return scope; } ivl_type_t data_type_t::elaborate_type_raw(Design*des, NetScope*) const { cerr << get_fileline() << ": internal error: " << "Elaborate method not implemented for " << typeid(*this).name() << "." << endl; des->errors += 1; return 0; } ivl_type_t atom_type_t::elaborate_type_raw(Design*des, NetScope*) const { switch (type_code) { case INTEGER: return netvector_t::integer_type(signed_flag); case TIME: if (signed_flag) return &netvector_t::time_signed; else return &netvector_t::time_unsigned; case LONGINT: if (signed_flag) return &netvector_t::atom2s64; else return &netvector_t::atom2u64; case INT: if (signed_flag) return &netvector_t::atom2s32; else return &netvector_t::atom2u32; case SHORTINT: if (signed_flag) return &netvector_t::atom2s16; else return &netvector_t::atom2u16; case BYTE: if (signed_flag) return &netvector_t::atom2s8; else return &netvector_t::atom2u8; default: cerr << get_fileline() << ": internal error: " << "atom_type_t type_code=" << type_code << "." << endl; des->errors += 1; return 0; } } ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { return scope->find_class(des, name); } /* * elaborate_type_raw for enumerations is actually mostly performed * during scope elaboration so that the enumeration literals are * available at the right time. At that time, the netenum_t* object is * stashed in the scope so that I can retrieve it here. */ ivl_type_t enum_type_t::elaborate_type_raw(Design *des, NetScope *scope) const { ivl_type_t base = base_type->elaborate_type(des, scope); const class netvector_t *vec_type = dynamic_cast(base); if (!vec_type && !dynamic_cast(base)) { cerr << get_fileline() << ": error: " << "Invalid enum base type `" << *base << "`." << endl; des->errors++; } else if (base->slice_dimensions().size() > 1) { cerr << get_fileline() << ": error: " << "Enum type must not have more than 1 packed dimension." << endl; des->errors++; } bool integer_flag = false; if (vec_type) integer_flag = vec_type->get_isint(); netenum_t *type = new netenum_t(base, names->size(), integer_flag); type->set_line(*this); scope->add_enumeration_set(this, type); return type; } ivl_type_t vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { vector packed; if (pdims.get()) evaluate_ranges(des, scope, this, packed, *pdims); netvector_t*tmp = new netvector_t(packed, base_type); tmp->set_signed(signed_flag); tmp->set_isint(integer_flag); tmp->set_implicit(implicit_flag); return tmp; } ivl_type_t real_type_t::elaborate_type_raw(Design*, NetScope*) const { switch (type_code_) { case REAL: return &netreal_t::type_real; case SHORTREAL: return &netreal_t::type_shortreal; } return 0; } ivl_type_t string_type_t::elaborate_type_raw(Design*, NetScope*) const { return &netstring_t::type_string; } ivl_type_t parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { vectorpacked; if (dims.get()) evaluate_ranges(des, scope, this, packed, *dims); ivl_type_t etype = base_type->elaborate_type(des, scope); if (!etype->packed()) { cerr << this->get_fileline() << " error: Packed array "; cerr << "base-type `"; cerr << *base_type; cerr << "` is not packed." << endl; des->errors++; } return new netparray_t(packed, etype); } ivl_type_t struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { netstruct_t*res = new netstruct_t; res->set_line(*this); res->packed(packed_flag); res->set_signed(signed_flag); if (union_flag) res->union_flag(true); for (list::iterator cur = members->begin() ; cur != members->end() ; ++ cur) { // Elaborate the type of the member. struct_member_t*curp = *cur; ivl_type_t mem_vec = curp->type->elaborate_type(des, scope); if (mem_vec == 0) continue; // There may be several names that are the same type: // name1, name2, ...; // Process all the member, and give them a type. for (list::iterator cur_name = curp->names->begin() ; cur_name != curp->names->end() ; ++ cur_name) { decl_assignment_t*namep = *cur_name; netstruct_t::member_t memb; memb.name = namep->name; memb.net_type = elaborate_array_type(des, scope, *this, mem_vec, namep->index); res->append_member(des, memb); } } return res; } static ivl_type_t elaborate_darray_check_type(Design *des, const LineInfo &li, ivl_type_t type, const char *darray_type) { if (dynamic_cast(type) || dynamic_cast(type) || dynamic_cast(type) || dynamic_cast(type)) return type; cerr << li.get_fileline() << ": Sorry: " << darray_type << " of type `" << *type << "` is not yet supported." << endl; des->errors++; // Return something to recover return new netvector_t(IVL_VT_LOGIC); } static ivl_type_t elaborate_queue_type(Design *des, NetScope *scope, const LineInfo &li, ivl_type_t base_type, PExpr *ridx) { base_type = elaborate_darray_check_type(des, li, base_type, "Queue"); long max_idx = -1; if (ridx) { NetExpr*tmp = elab_and_eval(des, scope, ridx, -1, true); NetEConst*cv = dynamic_cast(tmp); if (cv == 0) { cerr << li.get_fileline() << ": error: " << "queue bound must be constant." << endl; des->errors++; } else { verinum res = cv->value(); if (res.is_defined()) { max_idx = res.as_long(); if (max_idx < 0) { cerr << li.get_fileline() << ": error: " << "queue bound must be positive (" << max_idx << ")." << endl; des->errors++; max_idx = -1; } } else { cerr << li.get_fileline() << ": error: " << "queue bound must be defined." << endl; des->errors++; } } delete cv; } return new netqueue_t(base_type, max_idx); } // If dims is not empty create a unpacked array type and clear dims, otherwise // return the base type. Also check that we actually support the base type. static ivl_type_t elaborate_static_array_type(Design *des, const LineInfo &li, ivl_type_t base_type, std::vector &dims) { if (dims.empty()) return base_type; if (dynamic_cast(base_type)) { cerr << li.get_fileline() << ": sorry: " << "array of queue type is not yet supported." << endl; des->errors++; // Recover base_type = new netvector_t(IVL_VT_LOGIC); } else if (dynamic_cast(base_type)) { cerr << li.get_fileline() << ": sorry: " << "array of dynamic array type is not yet supported." << endl; des->errors++; // Recover base_type = new netvector_t(IVL_VT_LOGIC); } ivl_type_t type = new netuarray_t(dims, base_type); dims.clear(); return type; } ivl_type_t elaborate_array_type(Design *des, NetScope *scope, const LineInfo &li, ivl_type_t base_type, const list &dims) { const long warn_dimension_size = 1 << 30; std::vector dimensions; dimensions.reserve(dims.size()); ivl_type_t type = base_type; for (list::const_iterator cur = dims.begin(); cur != dims.end() ; ++cur) { PExpr *lidx = cur->first; PExpr *ridx = cur->second; if (lidx == 0 && ridx == 0) { // Special case: If we encounter an undefined dimensions, // then turn this into a dynamic array and put all the // packed dimensions there. type = elaborate_static_array_type(des, li, type, dimensions); type = elaborate_darray_check_type(des, li, type, "Dynamic array"); type = new netdarray_t(type); continue; } else if (dynamic_cast(lidx)) { // Special case: Detect the mark for a QUEUE declaration, // which is the dimensions [null:max_idx]. type = elaborate_static_array_type(des, li, type, dimensions); type = elaborate_queue_type(des, scope, li, type, ridx); continue; } long index_l, index_r; evaluate_range(des, scope, &li, *cur, index_l, index_r); if (abs(index_r - index_l) > warn_dimension_size) { cerr << li.get_fileline() << ": warning: " << "Array dimension is greater than " << warn_dimension_size << "." << endl; } dimensions.push_back(netrange_t(index_l, index_r)); } return elaborate_static_array_type(des, li, type, dimensions); } ivl_type_t uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { ivl_type_t btype = base_type->elaborate_type(des, scope); return elaborate_array_type(des, scope, *this, btype, *dims.get()); } ivl_type_t typeref_t::elaborate_type_raw(Design*des, NetScope*s) const { if (!s) { // Try to recover return new netvector_t(IVL_VT_LOGIC); } return type->elaborate_type(des, s); } NetScope *typeref_t::find_scope(Design *des, NetScope *s) const { // If a scope has been specified use that as a starting point for the // search if (scope) s = des->find_package(scope->pscope_name()); return s; } ivl_type_t typedef_t::elaborate_type(Design *des, NetScope *scope) { if (!data_type.get()) { cerr << get_fileline() << ": error: Undefined type `" << name << "`." << endl; des->errors++; // Try to recover return netvector_t::integer_type(); } // Search upwards from where the type was referenced scope = scope->find_typedef_scope(des, this); if (!scope) { cerr << get_fileline() << ": sorry: " << "Can not find the scope type defintion `" << name << "`." << endl; des->errors++; // Try to recover return netvector_t::integer_type(); } ivl_type_t elab_type = data_type->elaborate_type(des, scope); if (!elab_type) return netvector_t::integer_type(); bool type_ok = true; switch (basic_type) { case ENUM: type_ok = dynamic_cast(elab_type); break; case STRUCT: { const netstruct_t *struct_type = dynamic_cast(elab_type); type_ok = struct_type && !struct_type->union_flag(); break; } case UNION: { const netstruct_t *struct_type = dynamic_cast(elab_type); type_ok = struct_type && struct_type->union_flag(); break; } case CLASS: type_ok = dynamic_cast(elab_type); break; default: break; } if (!type_ok) { cerr << data_type->get_fileline() << " error: " << "Unexpected type `" << *elab_type << "` for `" << name << "`. It was forward declared as `" << basic_type << "` at " << get_fileline() << "." << endl; des->errors++; } return elab_type; } ivl_type_t type_parameter_t::elaborate_type_raw(Design *des, NetScope*scope) const { ivl_type_t type; scope->get_parameter(des, name, type); // Recover if (!type) return netvector_t::integer_type(); return type; } iverilog-12_0/elaborate.cc000066400000000000000000007130111435245347300156170ustar00rootroot00000000000000/* * Copyright (c) 1998-2022 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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" /* * Elaboration takes as input a complete parse tree and the name of a * root module, and generates as output the elaborated design. This * elaborated design is presented as a Module, which does not * reference any other modules. It is entirely self contained. */ # include # include # include # include # include # include # include # include "pform.h" # include "PClass.h" # include "PEvent.h" # include "PGenerate.h" # include "PPackage.h" # include "PScope.h" # include "PSpec.h" # include "netlist.h" # include "netenum.h" # include "netvector.h" # include "netdarray.h" # include "netparray.h" # include "netscalar.h" # include "netclass.h" # include "netmisc.h" # include "util.h" # include "parse_api.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; // Implemented in elab_scope.cc extern void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope); void PGate::elaborate(Design*, NetScope*) const { cerr << "internal error: what kind of gate? " << typeid(*this).name() << endl; } unsigned PGate::calculate_array_size_(Design*des, NetScope*scope, long&high, long&low) const { if (ranges_ && ranges_->size() > 1) { if (gn_system_verilog()) { cerr << get_fileline() << ": sorry: Multi-dimensional" << " arrays of instances are not yet supported." << endl; } else { cerr << get_fileline() << ": error: Multi-dimensional" << " arrays of instances require SystemVerilog." << endl; } des->errors += 1; return 0; } unsigned size = 1; high = 0; low = 0; if (ranges_) { if (!evaluate_range(des, scope, this, ranges_->front(), high, low)) return 0; if (high > low) size = high - low + 1; else size = low - high + 1; if (debug_elaborate) { cerr << get_fileline() << ": debug: PGate: Make array " << "[" << high << ":" << low << "]" << " of " << size << " instances for " << get_name() << endl; } } return size; } /* * Elaborate the continuous assign. (This is *not* the procedural * assign.) Elaborate the lvalue and rvalue, and do the assignment. */ void PGAssign::elaborate(Design*des, NetScope*scope) const { assert(scope); NetExpr* rise_time, *fall_time, *decay_time; eval_delays(des, scope, rise_time, fall_time, decay_time, true); ivl_drive_t drive0 = strength0(); ivl_drive_t drive1 = strength1(); assert(pin(0)); assert(pin(1)); /* Elaborate the l-value. */ NetNet*lval = pin(0)->elaborate_lnet(des, scope); if (lval == 0) { return; } // If this turns out to be an assignment to an unpacked array, // then handle that special case elsewhere. if (lval->pin_count() > 1) { elaborate_unpacked_array_(des, scope, lval); return; } ivl_assert(*this, lval->pin_count() == 1); if (debug_elaborate) { cerr << get_fileline() << ": PGAssign::elaborate: elaborated l-value" << " width=" << lval->vector_width() << ", pin_count=" << lval->pin_count() << endl; } NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->net_type(), pin(1)); if (rval_expr == 0) { cerr << get_fileline() << ": error: Unable to elaborate r-value: " << *pin(1) << endl; des->errors += 1; return; } if (lval->enumeration()) { if (! rval_expr->enumeration()) { cerr << get_fileline() << ": error: " "This assignment requires an explicit cast." << endl; des->errors += 1; } else if (! lval->enumeration()->matches(rval_expr->enumeration())) { cerr << get_fileline() << ": error: " "Enumeration type mismatch in assignment." << endl; des->errors += 1; } } NetNet*rval = rval_expr->synthesize(des, scope, rval_expr); if (rval == 0) { cerr << get_fileline() << ": internal error: " << "Failed to synthesize expression: " << *rval_expr << endl; des->errors += 1; return; } if (debug_elaborate) { cerr << get_fileline() << ": debug: PGAssign: elaborated r-value" << " width="<< rval->vector_width() << ", type="<< rval->data_type() << ", expr=" << *rval_expr << endl; } ivl_assert(*this, lval && rval); ivl_assert(*this, rval->pin_count() == 1); // Detect the case that the rvalue-expression is a simple // expression. In this case, we will need to create a driver // (later) to carry strengths. bool need_driver_flag = false; if (dynamic_cast(rval_expr) ||!rval->is_linked()) need_driver_flag = true; // expression elaboration should have caused the rval width to // match the l-value by now. if (rval->vector_width() < lval->vector_width()) { cerr << get_fileline() << ": internal error: " << "lval-rval width mismatch: " << "rval->vector_width()==" << rval->vector_width() << ", lval->vector_width()==" << lval->vector_width() << endl; } ivl_assert(*this, rval->vector_width() >= lval->vector_width()); /* If the r-value insists on being larger than the l-value, use a part select to chop it down down to size. */ if (lval->vector_width() < rval->vector_width()) { NetPartSelect*tmp = new NetPartSelect(rval, 0,lval->vector_width(), NetPartSelect::VP); des->add_node(tmp); tmp->set_line(*this); netvector_t*osig_vec = new netvector_t(rval->data_type(), lval->vector_width()-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::TRI, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(osig->pin(0), tmp->pin(0)); rval = osig; need_driver_flag = false; } /* When we are given a non-default strength value and if the drive * source is a bit, part, indexed select or a concatenation we need * to add a driver (BUFZ) to convey the strength information. */ if ((drive0 != IVL_DR_STRONG || drive1 != IVL_DR_STRONG) && ((dynamic_cast(rval_expr)) || (dynamic_cast(rval_expr)))) { need_driver_flag = true; } if (need_driver_flag) { NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(), rval->vector_width(), false); driver->set_line(*this); des->add_node(driver); connect(rval->pin(0), driver->pin(1)); netvector_t*tmp_vec = new netvector_t(rval->data_type(), rval->vector_width()-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); connect(driver->pin(0), tmp->pin(0)); rval = tmp; } /* Set the drive and delays for the r-val. */ if (drive0 != IVL_DR_STRONG || drive1 != IVL_DR_STRONG) rval->pin(0).drivers_drive(drive0, drive1); if (rise_time || fall_time || decay_time) rval->pin(0).drivers_delays(rise_time, fall_time, decay_time); connect(lval->pin(0), rval->pin(0)); if (lval->local_flag()) delete lval; } NetNet *elaborate_unpacked_array(Design *des, NetScope *scope, const LineInfo &loc, const NetNet *lval, PExpr *expr) { PEIdent* ident = dynamic_cast (expr); if (!ident) { des->errors++; if (dynamic_cast (expr)) { cout << loc.get_fileline() << ": sorry: Continuous assignment" << " of array concatenation is not yet supported." << endl; } else if (dynamic_cast (expr)) { cout << loc.get_fileline() << ": sorry: Continuous assignment" << " of assignment pattern is not yet supported." << endl; } else { cout << loc.get_fileline() << ": error: Can not assign" << " non-array expression `" << *expr << "` to array." << endl; } return nullptr; } NetNet *expr_net = ident->elaborate_unpacked_net(des, scope); if (!expr_net) return nullptr; auto const &lval_dims = lval->unpacked_dims(); auto const &expr_dims = expr_net->unpacked_dims(); if (expr_dims.empty()) { cerr << loc.get_fileline() << ": error: Can not assign" << " non-array identifier `" << *expr << "` to array." << endl; des->errors++; return nullptr; } if (!netrange_equivalent(lval_dims, expr_dims)) { cerr << loc.get_fileline() << ": error: Unpacked dimensions" << " are not compatible in array assignment." << endl; des->errors++; return nullptr; } if (!lval->net_type()->type_equivalent(expr_net->net_type())) { cerr << loc.get_fileline() << ": error: Element types are not" << " compatible in array assignment." << endl; des->errors++; return nullptr; } return expr_net; } void PGAssign::elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const { NetNet *rval_net = elaborate_unpacked_array(des, scope, *this, lval, pin(1)); if (rval_net) assign_unpacked_with_bufz(des, scope, lval, lval, rval_net); } void PGBuiltin::calculate_gate_and_lval_count_(unsigned&gate_count, unsigned&lval_count) const { switch (type()) { case BUF: case NOT: if (pin_count() > 2) gate_count = pin_count() - 1; else gate_count = 1; lval_count = gate_count; break; case PULLDOWN: case PULLUP: gate_count = pin_count(); lval_count = gate_count; break; case TRAN: case RTRAN: case TRANIF0: case TRANIF1: case RTRANIF0: case RTRANIF1: gate_count = 1; lval_count = 2; break; default: gate_count = 1; lval_count = 1; break; } } NetNode* PGBuiltin::create_gate_for_output_(Design*des, NetScope*scope, perm_string inst_name, unsigned instance_width) const { NetNode*gate = 0; switch (type()) { case AND: if (pin_count() < 2) { cerr << get_fileline() << ": error: the AND " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::AND, instance_width); } break; case BUF: if (pin_count() < 2) { cerr << get_fileline() << ": error: the BUF " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, 2, NetLogic::BUF, instance_width); } break; case BUFIF0: if (pin_count() != 3) { cerr << get_fileline() << ": error: the BUFIF0 " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::BUFIF0, instance_width); } break; case BUFIF1: if (pin_count() != 3) { cerr << get_fileline() << ": error: the BUFIF1 " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::BUFIF1, instance_width); } break; case CMOS: if (pin_count() != 4) { cerr << get_fileline() << ": error: the CMOS " "primitive must have four arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::CMOS, instance_width); } break; case NAND: if (pin_count() < 2) { cerr << get_fileline() << ": error: the NAND " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::NAND, instance_width); } break; case NMOS: if (pin_count() != 3) { cerr << get_fileline() << ": error: the NMOS " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::NMOS, instance_width); } break; case NOR: if (pin_count() < 2) { cerr << get_fileline() << ": error: the NOR " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::NOR, instance_width); } break; case NOT: if (pin_count() < 2) { cerr << get_fileline() << ": error: the NOT " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, 2, NetLogic::NOT, instance_width); } break; case NOTIF0: if (pin_count() != 3) { cerr << get_fileline() << ": error: the NOTIF0 " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::NOTIF0, instance_width); } break; case NOTIF1: if (pin_count() != 3) { cerr << get_fileline() << ": error: the NOTIF1 " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::NOTIF1, instance_width); } break; case OR: if (pin_count() < 2) { cerr << get_fileline() << ": error: the OR " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::OR, instance_width); } break; case RCMOS: if (pin_count() != 4) { cerr << get_fileline() << ": error: the RCMOS " "primitive must have four arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::RCMOS, instance_width); } break; case RNMOS: if (pin_count() != 3) { cerr << get_fileline() << ": error: the RNMOS " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::RNMOS, instance_width); } break; case RPMOS: if (pin_count() != 3) { cerr << get_fileline() << ": error: the RPMOS " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::RPMOS, instance_width); } break; case PMOS: if (pin_count() != 3) { cerr << get_fileline() << ": error: the PMOS " "primitive must have three arguments." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::PMOS, instance_width); } break; case PULLDOWN: gate = new NetLogic(scope, inst_name, 1, NetLogic::PULLDOWN, instance_width); break; case PULLUP: gate = new NetLogic(scope, inst_name, 1, NetLogic::PULLUP, instance_width); break; case XNOR: if (pin_count() < 2) { cerr << get_fileline() << ": error: the XNOR " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::XNOR, instance_width); } break; case XOR: if (pin_count() < 2) { cerr << get_fileline() << ": error: the XOR " "primitive must have an input." << endl; des->errors += 1; } else { gate = new NetLogic(scope, inst_name, pin_count(), NetLogic::XOR, instance_width); } break; case TRAN: if (pin_count() != 2) { cerr << get_fileline() << ": error: Pin count for " << "tran device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_TRAN, instance_width); } break; case RTRAN: if (pin_count() != 2) { cerr << get_fileline() << ": error: Pin count for " << "rtran device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_RTRAN, instance_width); } break; case TRANIF0: if (pin_count() != 3) { cerr << get_fileline() << ": error: Pin count for " << "tranif0 device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_TRANIF0, instance_width); } break; case RTRANIF0: if (pin_count() != 3) { cerr << get_fileline() << ": error: Pin count for " << "rtranif0 device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_RTRANIF0, instance_width); } break; case TRANIF1: if (pin_count() != 3) { cerr << get_fileline() << ": error: Pin count for " << "tranif1 device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_TRANIF1, instance_width); } break; case RTRANIF1: if (pin_count() != 3) { cerr << get_fileline() << ": error: Pin count for " << "rtranif1 device." << endl; des->errors += 1; } else { gate = new NetTran(scope, inst_name, IVL_SW_RTRANIF1, instance_width); } break; default: cerr << get_fileline() << ": internal error: unhandled " "gate type." << endl; des->errors += 1; break; } return gate; } bool PGBuiltin::check_delay_count(Design*des) const { switch (type()) { case AND: case NAND: case OR: case NOR: case XOR: case XNOR: case BUF: case NOT: if (delay_count() > 2) { cerr << get_fileline() << ": error: More than two delays " << "given to a " << gate_name() << " gate." << endl; des->errors += 1; return true; } break; case BUFIF0: case NOTIF0: case BUFIF1: case NOTIF1: if (delay_count() > 3) { cerr << get_fileline() << ": error: More than three delays " << "given to a " << gate_name() << " gate." << endl; des->errors += 1; return true; } break; case NMOS: case RNMOS: case PMOS: case RPMOS: case CMOS: case RCMOS: if (delay_count() > 3) { cerr << get_fileline() << ": error: More than three delays " << "given to a " << gate_name() << " switch." << endl; des->errors += 1; return true; } break; case TRAN: case RTRAN: if (delay_count() != 0) { cerr << get_fileline() << ": error: A " << gate_name() << " switch does not take any delays." << endl; des->errors += 1; return true; } break; case TRANIF0: case TRANIF1: if (delay_count() > 2) { cerr << get_fileline() << ": error: More than two delays " << "given to a " << gate_name() << " switch." << endl; des->errors += 1; return true; } break; case RTRANIF0: case RTRANIF1: if (delay_count() > 2) { cerr << get_fileline() << ": error: More than two delays " << "given to an " << gate_name() << " switch." << endl; des->errors += 1; return true; } break; case PULLUP: case PULLDOWN: if (delay_count() != 0) { cerr << get_fileline() << ": error: A " << gate_name() << " source does not take any delays." << endl; des->errors += 1; return true; } break; default: cerr << get_fileline() << ": internal error: unhandled " "gate type." << endl; des->errors += 1; return true; break; } return false; } /* * Elaborate a Builtin gate. These normally get translated into * NetLogic nodes that reflect the particular logic function. */ void PGBuiltin::elaborate(Design*des, NetScope*scope) const { unsigned instance_width = 1; perm_string name = get_name(); if (name == "") name = scope->local_symbol(); /* Calculate the array bounds and instance count for the gate, as described in the Verilog source. If there is none, then the count is 1, and high==low==0. */ long low=0, high=0; unsigned array_count = calculate_array_size_(des, scope, high, low); if (array_count == 0) return; unsigned gate_count = 0, lval_count = 0; calculate_gate_and_lval_count_(gate_count, lval_count); /* Now we have a gate count. Elaborate the lval (output or bi-directional) expressions only. We do it early so that we can see if we can make wide gates instead of an array of gates. */ vectorlval_sigs (lval_count); for (unsigned idx = 0 ; idx < lval_count ; idx += 1) { if (pin(idx) == 0) { cerr << get_fileline() << ": error: Logic gate port " "expressions are not optional." << endl; des->errors += 1; return; } if (lval_count > gate_count) lval_sigs[idx] = pin(idx)->elaborate_bi_net(des, scope); else lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope); // The only way this should return zero is if an error // happened, so for that case just return. if (lval_sigs[idx] == 0) return; // For now, assume all the outputs are the same width. ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width()); } /* Detect the special case that the l-value width exactly matches the gate count. In this case, we will make a single gate that has the desired vector width. NOTE: This assumes that all the outputs have the same width. For gates with 1 output, this is trivially true. */ if (lval_sigs[0]->vector_width() == array_count) { instance_width = array_count; array_count = 1; if (debug_elaborate && instance_width != 1) cerr << get_fileline() << ": debug: PGBuiltin: " "Collapsed gate array into single wide " "(" << instance_width << ") instance." << endl; } /* Calculate the gate delays from the delay expressions given in the source. For logic gates, the decay time is meaningless because it can never go to high impedance. However, the bufif devices can generate 'bz output, so we will pretend that anything can. If only one delay value expression is given (i.e., #5 nand(foo,...)) then rise, fall and decay times are all the same value. If two values are given, rise and fall times are use, and the decay time is the minimum of the rise and fall times. Finally, if all three values are given, they are taken as specified. */ if (check_delay_count(des)) return; NetExpr* rise_time, *fall_time, *decay_time; eval_delays(des, scope, rise_time, fall_time, decay_time, true); struct attrib_list_t*attrib_list; unsigned attrib_list_n = 0; attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope); /* Allocate all the netlist nodes for the gates. */ vectorcur (array_count*gate_count); /* Now make as many gates as the bit count dictates. Give each a unique name, and set the delay times. */ for (unsigned idx = 0 ; idx < array_count*gate_count ; idx += 1) { unsigned array_idx = idx/gate_count; unsigned gate_idx = idx%gate_count; ostringstream tmp; unsigned index = (low < high)? (low+array_idx) : (low-array_idx); tmp << name << "<" << index << "." << gate_idx << ">"; perm_string inm = lex_strings.make(tmp.str()); cur[idx] = create_gate_for_output_(des, scope, inm, instance_width); if (cur[idx] == 0) return; for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) cur[idx]->attribute(attrib_list[adx].key, attrib_list[adx].val); /* Set the delays and drive strength for all built in gates. */ cur[idx]->rise_time(rise_time); cur[idx]->fall_time(fall_time); cur[idx]->decay_time(decay_time); cur[idx]->pin(0).drive0(strength0()); cur[idx]->pin(0).drive1(strength1()); cur[idx]->set_line(*this); des->add_node(cur[idx]); } delete[]attrib_list; /* The gates have all been allocated, this loop runs through the parameters and attaches the ports of the objects. */ for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) { PExpr*ex = pin(idx); if (ex == 0) { cerr << get_fileline() << ": error: Logic gate port " "expressions are not optional." << endl; des->errors += 1; return; } NetNet*sig = 0; if (idx < lval_count) { sig = lval_sigs[idx]; } else { // If this is an array, the port expression is required // to be the exact width required (this will be checked // later). But if this is a single instance, consensus // is that we just take the LSB of the port expression. NetExpr*tmp = elab_and_eval(des, scope, ex, is_array() ? -1 : 1); if (tmp == 0) continue; if (!is_array() && tmp->expr_width() != 1) tmp = new NetESelect(tmp, make_const_0(1), 1, IVL_SEL_IDX_UP); sig = tmp->synthesize(des, scope, tmp); delete tmp; } if (sig == 0) continue; ivl_assert(*this, sig); if (array_count == 1) { /* Handle the case where there is one gate that carries the whole vector width. */ if (1 == sig->vector_width() && instance_width != 1) { assert(sig->vector_width() == 1); NetReplicate*rep = new NetReplicate(scope, scope->local_symbol(), instance_width, instance_width); rep->set_line(*this); des->add_node(rep); connect(rep->pin(1), sig->pin(0)); netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC, instance_width-1,0); sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, osig_vec); sig->set_line(*this); sig->local_flag(true); connect(rep->pin(0), sig->pin(0)); } if (instance_width != sig->vector_width()) { cerr << get_fileline() << ": error: " << "Expression width " << sig->vector_width() << " does not match width " << instance_width << " of logic gate array port " << idx+1 << "." << endl; des->errors += 1; } // There is only 1 instance, but there may be // multiple outputs to that gate. That would // potentially mean multiple actual gates. // Although in Verilog proper a multiple // output gate has only 1 input, this conditional // handles gates with N outputs and M inputs. if (idx < gate_count) { connect(cur[idx]->pin(0), sig->pin(0)); } else { for (unsigned dev = 0 ; dev < gate_count; dev += 1) connect(cur[dev]->pin(idx-gate_count+1), sig->pin(0)); } } else if (sig->vector_width() == 1) { /* Handle the case where a single bit is connected repetitively to all the instances. If idx is an output port, connect it to all array_count devices that have outputs at this position. Otherwise, idx is an input to all array_count*gate_count devices. */ if (idx < gate_count) { for (unsigned gdx = 0 ; gdx < array_count ; gdx += 1) { unsigned dev = gdx*gate_count; connect(cur[dev+idx]->pin(0), sig->pin(0)); } } else { unsigned use_idx = idx - gate_count + 1; for (unsigned gdx = 0 ; gdx < cur.size() ; gdx += 1) connect(cur[gdx]->pin(use_idx), sig->pin(0)); } } else if (sig->vector_width() == array_count) { /* Bi-directional switches should get collapsed into a single wide instance, so should never reach this point. Check this is so, as the following code doesn't handle bi-directional connections. */ ivl_assert(*this, lval_count == gate_count); /* Handle the general case that each bit of the value is connected to a different instance. In this case, the output is handled slightly different from the inputs. */ if (idx < gate_count) { NetConcat*cc = new NetConcat(scope, scope->local_symbol(), sig->vector_width(), array_count); cc->set_line(*this); des->add_node(cc); /* Connect the concat to the signal. */ connect(cc->pin(0), sig->pin(0)); /* Connect the outputs of the gates to the concat. */ for (unsigned gdx = 0 ; gdx < array_count; gdx += 1) { unsigned dev = gdx*gate_count; connect(cur[dev+idx]->pin(0), cc->pin(gdx+1)); netvector_t*tmp2_vec = new netvector_t(IVL_VT_LOGIC); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp2_vec); tmp2->set_line(*this); tmp2->local_flag(true); connect(cc->pin(gdx+1), tmp2->pin(0)); } } else for (unsigned gdx = 0 ; gdx < array_count ; gdx += 1) { /* Use part selects to get the bits connected to the inputs of out gate. */ NetPartSelect*tmp1 = new NetPartSelect(sig, gdx, 1, NetPartSelect::VP); tmp1->set_line(*this); des->add_node(tmp1); connect(tmp1->pin(1), sig->pin(0)); netvector_t*tmp2_vec = new netvector_t(sig->data_type()); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp2_vec); tmp2->set_line(*this); tmp2->local_flag(true); connect(tmp1->pin(0), tmp2->pin(0)); unsigned use_idx = idx - gate_count + 1; unsigned dev = gdx*gate_count; for (unsigned gdx2 = 0 ; gdx2 < gate_count ; gdx2 += 1) connect(cur[dev+gdx2]->pin(use_idx), tmp1->pin(0)); } } else { cerr << get_fileline() << ": error: Gate count of " << array_count << " does not match net width of " << sig->vector_width() << " at pin " << idx << "." << endl; des->errors += 1; } } } NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope, NetNet*sig, unsigned port_wid, NetNet::PortType dir, bool as_signed) const { ivl_assert(*this, dir != NetNet::NOT_A_PORT); ivl_assert(*this, dir != NetNet::PIMPLICIT); netvector_t*tmp_type = new netvector_t(IVL_VT_LOGIC, port_wid-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_type); tmp->local_flag(true); tmp->set_line(*this); // Handle the special case of a bi-directional part // select. Create a NetTran(VP) instead of a uni-directional // NetPartSelect node. if (dir == NetNet::PINOUT) { unsigned wida = sig->vector_width(); unsigned widb = tmp->vector_width(); bool part_b = widb < wida; // This needs to pad the value! // Also delete the inout specific warning when this is fixed. // It is located just before this routine is called. NetTran*node = new NetTran(scope, scope->local_symbol(), part_b? wida : widb, part_b? widb : wida, 0); if (part_b) { connect(node->pin(0), sig->pin(0)); connect(node->pin(1), tmp->pin(0)); } else { connect(node->pin(0), tmp->pin(0)); connect(node->pin(1), sig->pin(0)); } node->set_line(*this); des->add_node(node); return tmp; } unsigned pwidth = tmp->vector_width(); unsigned swidth = sig->vector_width(); switch (dir) { case NetNet::POUTPUT: if (pwidth > swidth) { NetPartSelect*node = new NetPartSelect(tmp, 0, swidth, NetPartSelect::VP); connect(node->pin(0), sig->pin(0)); des->add_node(node); } else { NetNet*osig; if (as_signed) { osig = pad_to_width_signed(des, tmp, swidth, *this); } else { osig = pad_to_width(des, tmp, swidth, *this); } connect(osig->pin(0), sig->pin(0)); } break; case NetNet::PINPUT: if (pwidth > swidth) { delete tmp; if (as_signed) { tmp = pad_to_width_signed(des, sig, pwidth, *this); } else { tmp = pad_to_width(des, sig, pwidth, *this); } } else { NetPartSelect*node = new NetPartSelect(sig, 0, pwidth, NetPartSelect::VP); connect(node->pin(0), tmp->pin(0)); des->add_node(node); } break; case NetNet::PINOUT: ivl_assert(*this, 0); break; case NetNet::PREF: ivl_assert(*this, 0); break; default: ivl_assert(*this, 0); } return tmp; } static bool need_bufz_for_input_port(const vector&prts) { if (prts[0]->port_type() != NetNet::PINPUT) return false; if (prts[0]->pin(0).nexus()->drivers_present()) return true; return false; } /* * Convert a wire or tri to a tri0 or tri1 as needed to make * an unconnected drive pull for floating inputs. */ static void convert_net(Design*des, const LineInfo *line, NetNet *net, NetNet::Type type) { // If the types already match just return. if (net->type() == type) return; // We can only covert a wire or tri to have a default pull. if (net->type() == NetNet::WIRE || net->type() == NetNet::TRI) { net->type(type); return; } // We may have to support this at some point in time! cerr << line->get_fileline() << ": sorry: Can not pull floating " "input type '" << net->type() << "'." << endl; des->errors += 1; } static void isolate_and_connect(Design*des, NetScope*scope, const PGModule*mod, NetNet*port, NetNet*sig, NetNet::PortType ptype) { switch (ptype) { case NetNet::POUTPUT: { NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(), sig->vector_width(), true); tmp->set_line(*mod); des->add_node(tmp); connect(tmp->pin(1), port->pin(0)); connect(tmp->pin(0), sig->pin(0)); } break; case NetNet::PINOUT: { NetTran*tmp = new NetTran(scope, scope->local_symbol(), sig->vector_width(), sig->vector_width(), 0); tmp->set_line(*mod); des->add_node(tmp); connect(tmp->pin(1), port->pin(0)); connect(tmp->pin(0), sig->pin(0)); } break; default: ivl_assert(*mod, 0); break; } } void elaborate_unpacked_port(Design *des, NetScope *scope, NetNet *port_net, PExpr *expr, NetNet::PortType port_type, Module *mod, unsigned int port_idx) { NetNet *expr_net = elaborate_unpacked_array(des, scope, *expr, port_net, expr); if (!expr_net) { perm_string port_name = mod->get_port_name(port_idx); cerr << expr->get_fileline() << ": : Port " << port_idx+1 << " (" << port_name << ") of " << mod->mod_name() << " is connected to " << *expr << endl; return; } ivl_assert(*port_net, expr_net->pin_count() == port_net->pin_count()); if (port_type == NetNet::POUTPUT) assign_unpacked_with_bufz(des, scope, port_net, expr_net, port_net); else assign_unpacked_with_bufz(des, scope, port_net, port_net, expr_net); } /* * Instantiate a module by recursively elaborating it. Set the path of * the recursive elaboration so that signal names get properly * set. Connect the ports of the instantiated module to the signals of * the parameters. This is done with BUFZ gates so that they look just * like continuous assignment connections. */ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const { assert(scope); if (debug_elaborate) { cerr << get_fileline() << ": debug: Instantiate module " << rmod->mod_name() << " with instance name " << get_name() << " in scope " << scope_path(scope) << endl; } // This is the array of pin expressions, shuffled to match the // order of the declaration. If the source instantiation uses // bind by order, this is the same as the source list. Otherwise, // the source list is rearranged by name binding into this list. vectorpins (rmod->port_count()); vectorpins_fromwc (rmod->port_count(), false); vectorpins_is_explicitly_not_connected (rmod->port_count(), false); // If the instance has a pins_ member, then we know we are // binding by name. Therefore, make up a pins array that // reflects the positions of the named ports. if (pins_) { unsigned nexp = rmod->port_count(); // Scan the bindings, matching them with port names. for (unsigned idx = 0 ; idx < npins_ ; idx += 1) { // Handle wildcard named port if (pins_[idx].name[0] == '*') { for (unsigned j = 0 ; j < nexp ; j += 1) { if (rmod->ports[j] && !pins[j] && !pins_is_explicitly_not_connected[j]) { pins_fromwc[j] = true; NetNet* net = 0; const NetExpr*par = 0; NetEvent* eve = 0; pform_name_t path_; path_.push_back(name_component_t(rmod->ports[j]->name)); symbol_search(this, des, scope, path_, net, par, eve); if (net != 0) { pins[j] = new PEIdent(rmod->ports[j]->name, true); pins[j]->set_lineno(get_lineno()); pins[j]->set_file(get_file()); } } } continue; } // Given a binding, look at the module port names // for the position that matches the binding name. unsigned pidx = rmod->find_port(pins_[idx].name); // If the port name doesn't exist, the find_port // method will return the port count. Detect that // as an error. if (pidx == nexp) { cerr << get_fileline() << ": error: port ``" << pins_[idx].name << "'' is not a port of " << get_name() << "." << endl; des->errors += 1; continue; } // If I am overriding a wildcard port, delete and // override it if (pins_fromwc[pidx]) { delete pins[pidx]; pins_fromwc[pidx] = false; // If I already explicitly bound something to // this port, then the pins array will already // have a pointer value where I want to place this // expression. } else if (pins[pidx]) { cerr << get_fileline() << ": error: port ``" << pins_[idx].name << "'' already bound." << endl; des->errors += 1; continue; } // OK, do the binding by placing the expression in // the right place. pins[pidx] = pins_[idx].parm; if (!pins[pidx]) pins_is_explicitly_not_connected[pidx] = true; } } else if (pin_count() == 0) { /* Handle the special case that no ports are connected. It is possible that this is an empty connect-by-name list, so we'll allow it and assume that is the case. */ for (unsigned idx = 0 ; idx < rmod->port_count() ; idx += 1) pins[idx] = 0; } else { /* Otherwise, this is a positional list of port connections. In this case, the port count must be right. Check that is is, the get the pin list. */ if (pin_count() != rmod->port_count()) { cerr << get_fileline() << ": error: Wrong number " "of ports. Expecting " << rmod->port_count() << ", got " << pin_count() << "." << endl; des->errors += 1; return; } // No named bindings, just use the positional list I // already have. assert(pin_count() == rmod->port_count()); pins = get_pins(); } // Elaborate these instances of the module. The recursive // elaboration causes the module to generate a netlist with // the ports represented by NetNet objects. I will find them // later. NetScope::scope_vec_t&instance = scope->instance_arrays[get_name()]; if (debug_elaborate) cerr << get_fileline() << ": debug: start " "recursive elaboration of " << instance.size() << " instance(s) of " << get_name() << "..." << endl; for (unsigned inst = 0 ; inst < instance.size() ; inst += 1) { rmod->elaborate(des, instance[inst]); instance[inst]->set_num_ports( rmod->port_count() ); } if (debug_elaborate) cerr << get_fileline() << ": debug: ...done." << endl; // Now connect the ports of the newly elaborated designs to // the expressions that are the instantiation parameters. Scan // the pins, elaborate the expressions attached to them, and // bind them to the port of the elaborated module. // This can get rather complicated because the port can be // unconnected (meaning an empty parameter is passed) connected // to a concatenation, or connected to an internally // unconnected port. for (unsigned idx = 0 ; idx < pins.size() ; idx += 1) { bool unconnected_port = false; bool using_default = false; perm_string port_name = rmod->get_port_name(idx); // If the port is unconnected, substitute the default // value. The parser ensures that a default value only // exists for input ports. if (pins[idx] == 0) { PExpr*default_value = rmod->get_port_default_value(idx); if (default_value) { pins[idx] = default_value; using_default = true; } } // Skip unconnected module ports. This happens when a // null parameter is passed in and there is no default // value. if (pins[idx] == 0) { if (pins_fromwc[idx]) { cerr << get_fileline() << ": error: Wildcard named " "port connection (.*) did not find a matching " "identifier for port " << (idx+1) << " (" << port_name << ")." << endl; des->errors += 1; return; } // We need this information to support the // unconnected_drive directive and for a // unconnected input warning when asked for. vector mport = rmod->get_port(idx); if (mport.empty()) continue; perm_string pname = peek_tail_name(mport[0]->path()); NetNet*tmp = instance[0]->find_signal(pname); // Handle the error case where there is no internal // signal connected to the port. if (!tmp) continue; assert(tmp); if (tmp->port_type() == NetNet::PINPUT) { // If we have an unconnected input convert it // as needed if an unconnected_drive directive // was given. This only works for tri or wire! switch (rmod->uc_drive) { case Module::UCD_PULL0: convert_net(des, this, tmp, NetNet::TRI0); break; case Module::UCD_PULL1: convert_net(des, this, tmp, NetNet::TRI1); break; case Module::UCD_NONE: break; } // Print a warning for an unconnected input. if (warn_portbinding) { cerr << get_fileline() << ": warning: " << "Instantiating module " << rmod->mod_name() << " with dangling input port " << (idx+1) << " (" << port_name; switch (rmod->uc_drive) { case Module::UCD_PULL0: cerr << ") pulled low." << endl; break; case Module::UCD_PULL1: cerr << ") pulled high." << endl; break; case Module::UCD_NONE: cerr << ") floating." << endl; break; } } } unconnected_port = true; } // Inside the module, the port connects zero or more signals // that were already elaborated. List all those signals // and the NetNet equivalents, for all the instances. vector mport = rmod->get_port(idx); vector prts (mport.size() * instance.size()); if (debug_elaborate) { cerr << get_fileline() << ": debug: " << get_name() << ": Port " << (idx+1) << " (" << port_name << ") has " << prts.size() << " sub-ports." << endl; } // Count the internal vector bits of the port. unsigned prts_vector_width = 0; for (unsigned inst = 0 ; inst < instance.size() ; inst += 1) { // Scan the instances from MSB to LSB. The port // will be assembled in that order as well. NetScope*inst_scope = instance[instance.size()-inst-1]; unsigned int prt_vector_width = 0; PortType::Enum ptype = PortType::PIMPLICIT; // Scan the module sub-ports for this instance... // (Sub-ports are concatenated ports that form the // single port for the instance. This is not a // commonly used feature.) for (unsigned ldx = 0 ; ldx < mport.size() ; ldx += 1) { unsigned lbase = inst * mport.size(); PEIdent*pport = mport[ldx]; ivl_assert(*this, pport); NetNet *netnet = pport->elaborate_subport(des, inst_scope); prts[lbase + ldx] = netnet; if (netnet == 0) continue; ivl_assert(*this, netnet); unsigned port_width = netnet->vector_width() * netnet->pin_count(); prts_vector_width += port_width; prt_vector_width += port_width; ptype = PortType::merged(netnet->port_type(), ptype); } inst_scope->add_module_port_info(idx, port_name, ptype, prt_vector_width ); } // If I find that the port is unconnected inside the // module, then there is nothing to connect. Skip the // argument. if ((prts_vector_width == 0) || unconnected_port) { continue; } // We know by design that each instance has the same // width port. Therefore, the prts_pin_count must be an // even multiple of the instance count. assert(prts_vector_width % instance.size() == 0); if (!prts.empty() && (prts[0]->port_type() == NetNet::PINPUT) && prts[0]->pin(0).nexus()->drivers_present() && pins[idx]->is_collapsible_net(des, scope, prts[0]->port_type())) { prts[0]->port_type(NetNet::PINOUT); cerr << pins[idx]->get_fileline() << ": warning: input port " << prts[0]->name() << " is coerced to inout." << endl; } if (!prts.empty() && (prts[0]->port_type() == NetNet::POUTPUT) && (prts[0]->type() != NetNet::REG) && prts[0]->pin(0).nexus()->has_floating_input() && pins[idx]->is_collapsible_net(des, scope, prts[0]->port_type())) { prts[0]->port_type(NetNet::PINOUT); cerr << pins[idx]->get_fileline() << ": warning: output port " << prts[0]->name() << " is coerced to inout." << endl; } // Elaborate the expression that connects to the // module[s] port. sig is the thing outside the module // that connects to the port. NetNet*sig = 0; NetNet::PortType ptype; if (prts.empty()) ptype = NetNet::NOT_A_PORT; else ptype = prts[0]->port_type(); if (prts.empty() || (ptype == NetNet::PINPUT)) { // Special case: If the input port is an unpacked // array, then there should be no sub-ports and // the r-value expression is processed // differently. if (prts.size() >= 1 && prts[0]->pin_count()>1) { ivl_assert(*this, prts.size()==1); elaborate_unpacked_port(des, scope, prts[0], pins[idx], ptype, rmod, idx); continue; } /* Input to module. Here we elaborate the source expression using its self-determined width. This allows us to check for and warn about port width mismatches. But in the special case that the source expression is a SV unbased unsized literal, we need to force the expression width to match the destination. NOTE that this also handles the case that the port is actually empty on the inside. We assume in that case that the port is input. */ int context_width = -1; if (PENumber*literal = dynamic_cast(pins[idx])) { if (literal->value().is_single()) context_width = prts_vector_width; } NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx], context_width, using_default); if (tmp_expr == 0) { cerr << pins[idx]->get_fileline() << ": error: Failed to elaborate port " << (using_default ? "default value." : "expression.") << endl; des->errors += 1; continue; } if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Elaborating INPUT port expression: " << *tmp_expr << endl; } sig = tmp_expr->synthesize(des, scope, tmp_expr); if (sig == 0) { cerr << pins[idx]->get_fileline() << ": internal error: Port expression " << "too complicated for elaboration." << endl; continue; } delete tmp_expr; if (!sig->get_lineno()) sig->set_line(*this); if (ptype == NetNet::PINPUT && gn_var_can_be_uwire()) { for (unsigned int i = 0; i < prts.size(); i++) { if (prts[i]->type() == NetNet::REG) prts[i]->type(NetNet::UNRESOLVED_WIRE); } } if (need_bufz_for_input_port(prts)) { NetBUFZ*tmp = new NetBUFZ(scope, scope->local_symbol(), sig->vector_width(), true); tmp->set_line(*this); des->add_node(tmp); connect(tmp->pin(1), sig->pin(0)); netvector_t*tmp2_vec = new netvector_t(sig->data_type(), sig->vector_width()-1,0); NetNet*tmp2 = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp2_vec); tmp2->local_flag(true); tmp2->set_line(*this); connect(tmp->pin(0), tmp2->pin(0)); sig = tmp2; } // If we have a real signal driving a bit/vector port // then we convert the real value using the appropriate // width cast. Since a real is only one bit the whole // thing needs to go to each instance when arrayed. if ((sig->data_type() == IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) { sig = cast_to_int4(des, scope, sig, prts_vector_width/instance.size()); } // If we have a bit/vector signal driving a real port // then we convert the value to a real. if ((sig->data_type() != IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) { sig = cast_to_real(des, scope, sig); } // If we have a 4-state bit/vector signal driving a // 2-state port then we convert the value to 2-state. if ((sig->data_type() == IVL_VT_LOGIC ) && !prts.empty() && (prts[0]->data_type() == IVL_VT_BOOL )) { sig = cast_to_int2(des, scope, sig, sig->vector_width()); } } else if (ptype == NetNet::PINOUT) { // For now, do not support unpacked array outputs. ivl_assert(*this, prts[0]->unpacked_dimensions()==0); /* Inout to/from module. This is a more complicated case, where the expression must be an lnet, but also an r-value net. Normally, this winds up being the same as if we just elaborated as an lnet, as passing a simple identifier elaborates to the same NetNet in both cases so the extra elaboration has no effect. But if the expression passed to the inout port is a part select, a special part select must be created that can pass data in both directions. Use the elaborate_bi_net method to handle all the possible cases. */ sig = pins[idx]->elaborate_bi_net(des, scope); if (sig == 0) { cerr << pins[idx]->get_fileline() << ": error: " << "Inout port expression must support " << "continuous assignment." << endl; cerr << pins[idx]->get_fileline() << ": : Port " << (idx+1) << " (" << port_name << ") of " << rmod->mod_name() << " is connected to " << *pins[idx] << endl; des->errors += 1; continue; } // We do not support automatic bits to real conversion // for inout ports. if ((sig->data_type() == IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) { cerr << pins[idx]->get_fileline() << ": error: " << "Cannot automatically connect bit based " "inout port " << (idx+1) << " (" << port_name << ") of module " << rmod->mod_name() << " to real signal " << sig->name() << "." << endl; des->errors += 1; continue; } // We do not support real inout ports at all. if (!prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) { cerr << pins[idx]->get_fileline() << ": error: " << "No support for connecting real inout ports (" "port " << (idx+1) << " (" << port_name << ") of module " << rmod->mod_name() << ")." << endl; des->errors += 1; continue; } } else { /* Port type must be OUTPUT here. */ ivl_assert(*this, ptype == NetNet::POUTPUT); // Special case: If the output port is an unpacked // array, then there should be no sub-ports and // the passed port expression is processed // differently. Note that we are calling it the // "r-value" expression, but since this is an // output port, we assign to it from the internal object. if (prts[0]->pin_count() > 1) { elaborate_unpacked_port(des, scope, prts[0], pins[idx], ptype, rmod, idx); continue; } // At this point, arrays are handled. ivl_assert(*this, prts[0]->unpacked_dimensions()==0); /* Output from module. Elaborate the port expression as the l-value of a continuous assignment, as the port will continuous assign into the port. */ sig = pins[idx]->elaborate_lnet(des, scope); if (sig == 0) { cerr << pins[idx]->get_fileline() << ": error: " << "Output port expression must support " << "continuous assignment." << endl; cerr << pins[idx]->get_fileline() << ": : Port " << (idx+1) << " (" << port_name << ") of " << rmod->mod_name() << " is connected to " << *pins[idx] << endl; des->errors += 1; continue; } // If we have a real port driving a bit/vector signal // then we convert the real value using the appropriate // width cast. Since a real is only one bit the whole // thing needs to go to each instance when arrayed. if ((sig->data_type() != IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL )) { if (sig->vector_width() % instance.size() != 0) { cerr << pins[idx]->get_fileline() << ": error: " "When automatically converting a real " "port of an arrayed instance to a bit " "signal" << endl; cerr << pins[idx]->get_fileline() << ": : " "the signal width (" << sig->vector_width() << ") must be an " "integer multiple of the instance count (" << instance.size() << ")." << endl; des->errors += 1; continue; } prts_vector_width = sig->vector_width(); for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) { prts[pidx] = cast_to_int4(des, scope, prts[pidx], prts_vector_width / instance.size()); } } // If we have a bit/vector port driving a single real // signal then we convert the value to a real. if ((sig->data_type() == IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() != IVL_VT_REAL )) { prts_vector_width -= prts[0]->vector_width() - 1; prts[0] = cast_to_real(des, scope, prts[0]); // No support for multiple real drivers. if (instance.size() != 1) { cerr << pins[idx]->get_fileline() << ": error: " << "Cannot connect an arrayed instance of " "module " << rmod->mod_name() << " to " "real signal " << sig->name() << "." << endl; des->errors += 1; continue; } } // If we have a 4-state bit/vector port driving a // 2-state signal then we convert the value to 2-state. if ((sig->data_type() == IVL_VT_BOOL ) && !prts.empty() && (prts[0]->data_type() == IVL_VT_LOGIC )) { for (unsigned pidx = 0; pidx < prts.size(); pidx += 1) { prts[pidx] = cast_to_int2(des, scope, prts[pidx], prts[pidx]->vector_width()); } } // A real to real connection is not allowed for arrayed // instances. You cannot have multiple real drivers. if ((sig->data_type() == IVL_VT_REAL ) && !prts.empty() && (prts[0]->data_type() == IVL_VT_REAL ) && instance.size() != 1) { cerr << pins[idx]->get_fileline() << ": error: " << "An arrayed instance of " << rmod->mod_name() << " cannot have a real port (port " << (idx+1) << " : " << port_name << ") connected to a " "real signal (" << sig->name() << ")." << endl; des->errors += 1; continue; } } assert(sig); #ifndef NDEBUG if ((! prts.empty()) && (ptype != NetNet::PINPUT)) { assert(sig->type() != NetNet::REG); } #endif /* If we are working with an instance array, then the signal width must match the port width exactly. */ if ((instance.size() != 1) && (sig->vector_width() != prts_vector_width) && (sig->vector_width() != prts_vector_width/instance.size())) { cerr << pins[idx]->get_fileline() << ": error: " << "Port expression width " << sig->vector_width() << " does not match expected width "<< prts_vector_width << " or " << (prts_vector_width/instance.size()) << "." << endl; des->errors += 1; continue; } if (debug_elaborate) { cerr << get_fileline() << ": debug: " << get_name() << ": Port " << (idx+1) << " (" << port_name << ") has vector width of " << prts_vector_width << "." << endl; } // Check that the parts have matching pin counts. If // not, they are different widths. Note that idx is 0 // based, but users count parameter positions from 1. if ((instance.size() == 1) && (prts_vector_width != sig->vector_width())) { bool as_signed = false; switch (ptype) { case NetNet::POUTPUT: as_signed = prts[0]->get_signed(); break; case NetNet::PINPUT: as_signed = sig->get_signed(); break; case NetNet::PINOUT: /* This may not be correct! */ as_signed = prts[0]->get_signed() && sig->get_signed(); break; case NetNet::PREF: ivl_assert(*this, 0); break; default: ivl_assert(*this, 0); } cerr << get_fileline() << ": warning: Port " << (idx+1) << " (" << port_name << ") of " << type_ << " expects " << prts_vector_width << " bits, got " << sig->vector_width() << "." << endl; // Delete this when inout ports pad correctly. if (ptype == NetNet::PINOUT) { if (prts_vector_width > sig->vector_width()) { cerr << get_fileline() << ": : Leaving " << (prts_vector_width-sig->vector_width()) << " high bits of the port unconnected." << endl; } else { cerr << get_fileline() << ": : Leaving " << (sig->vector_width()-prts_vector_width) << " high bits of the expression dangling." << endl; } // Keep the if, but delete the "} else" when fixed. } else if (prts_vector_width > sig->vector_width()) { cerr << get_fileline() << ": : Padding "; if (as_signed) cerr << "(signed) "; cerr << (prts_vector_width-sig->vector_width()) << " high bits of the port." << endl; } else { if (ptype == NetNet::PINPUT) { cerr << get_fileline() << ": : Pruning "; } else { cerr << get_fileline() << ": : Padding "; } if (as_signed) cerr << "(signed) "; cerr << (sig->vector_width()-prts_vector_width) << " high bits of the expression." << endl; } sig = resize_net_to_port_(des, scope, sig, prts_vector_width, ptype, as_signed); } // Connect the sig expression that is the context of the // module instance to the ports of the elaborated module. // The prts_pin_count variable is the total width of the // port and is the maximum number of connections to // make. sig is the elaborated expression that connects // to that port. If sig has too few pins, then reduce // the number of connections to make. // Connect this many of the port pins. If the expression // is too small, then reduce the number of connects. unsigned ccount = prts_vector_width; if (instance.size() == 1 && sig->vector_width() < ccount) ccount = sig->vector_width(); // Now scan the concatenation that makes up the port, // connecting pins until we run out of port pins or sig // pins. The sig object is the NetNet that is connected // to the port from the outside, and the prts object is // an array of signals to be connected to the sig. NetConcat*ctmp; if (prts.size() == 1) { // The simplest case, there are no // parts/concatenations on the inside of the // module, so the port and sig need simply be // connected directly. But don't collapse ports // that are a delay path destination, to avoid // the delay being applied to other drivers of // the external signal. if (prts[0]->delay_paths() > 0) { isolate_and_connect(des, scope, this, prts[0], sig, ptype); } else { connect(prts[0]->pin(0), sig->pin(0)); } } else if (sig->vector_width()==prts_vector_width/instance.size() && prts.size()/instance.size() == 1) { if (debug_elaborate){ cerr << get_fileline() << ": debug: " << get_name() << ": Replicating " << prts_vector_width << " bits across all " << prts_vector_width/instance.size() << " sub-ports." << endl; } // The signal width is exactly the width of a // single instance of the port. In this case, // connect the sig to all the ports identically. for (unsigned ldx = 0 ; ldx < prts.size() ; ldx += 1) { if (prts[ldx]->delay_paths() > 0) { isolate_and_connect(des, scope, this, prts[ldx], sig, ptype); } else { connect(prts[ldx]->pin(0), sig->pin(0)); } } } else switch (ptype) { case NetNet::POUTPUT: ctmp = new NetConcat(scope, scope->local_symbol(), prts_vector_width, prts.size()); ctmp->set_line(*this); des->add_node(ctmp); connect(ctmp->pin(0), sig->pin(0)); for (unsigned ldx = 0 ; ldx < prts.size() ; ldx += 1) { connect(ctmp->pin(ldx+1), prts[prts.size()-ldx-1]->pin(0)); } break; case NetNet::PINPUT: if (debug_elaborate){ cerr << get_fileline() << ": debug: " << get_name() << ": Dividing " << prts_vector_width << " bits across all " << prts_vector_width/instance.size() << " input sub-ports of port " << (idx+1) << "." << endl; } for (unsigned ldx = 0, spin = 0 ; ldx < prts.size() ; ldx += 1) { NetNet*sp = prts[prts.size()-ldx-1]; NetPartSelect*ptmp = new NetPartSelect(sig, spin, sp->vector_width(), NetPartSelect::VP); ptmp->set_line(*this); des->add_node(ptmp); connect(ptmp->pin(0), sp->pin(0)); spin += sp->vector_width(); } break; case NetNet::PINOUT: for (unsigned ldx = 0, spin = 0 ; ldx < prts.size() ; ldx += 1) { NetNet*sp = prts[prts.size()-ldx-1]; NetTran*ttmp = new NetTran(scope, scope->local_symbol(), sig->vector_width(), sp->vector_width(), spin); ttmp->set_line(*this); des->add_node(ttmp); connect(ttmp->pin(0), sig->pin(0)); connect(ttmp->pin(1), sp->pin(0)); spin += sp->vector_width(); } break; case NetNet::PREF: cerr << get_fileline() << ": sorry: " << "Reference ports not supported yet." << endl; des->errors += 1; break; case NetNet::PIMPLICIT: cerr << get_fileline() << ": internal error: " << "Unexpected IMPLICIT port" << endl; des->errors += 1; break; case NetNet::NOT_A_PORT: cerr << get_fileline() << ": internal error: " << "Unexpected NOT_A_PORT port." << endl; des->errors += 1; break; } } } /* * From a UDP definition in the source, make a NetUDP * object. Elaborate the pin expressions as netlists, then connect * those networks to the pins. */ void PGModule::elaborate_udp_(Design*des, PUdp*udp, NetScope*scope) const { NetExpr*rise_expr =0, *fall_expr =0, *decay_expr =0; perm_string my_name = get_name(); if (my_name == 0) my_name = scope->local_symbol(); /* When the parser notices delay expressions in front of a module or primitive, it interprets them as parameter overrides. Correct that misconception here. */ if (overrides_) { if (overrides_->size() > 2) { cerr << get_fileline() << ": error: UDPs take at most two " "delay arguments." << endl; des->errors += 1; } else { PDelays tmp_del; tmp_del.set_delays(overrides_, false); tmp_del.eval_delays(des, scope, rise_expr, fall_expr, decay_expr, true); } } long low = 0, high = 0; unsigned inst_count = calculate_array_size_(des, scope, high, low); if (inst_count == 0) return; if (inst_count != 1) { cerr << get_fileline() << ": sorry: UDPs with a range (" << my_name << " [" << high << ":" << low << "]) are " << "not supported." << endl; des->errors += 1; return; } assert(udp); NetUDP*net = new NetUDP(scope, my_name, udp->ports.size(), udp); net->set_line(*this); net->rise_time(rise_expr); net->fall_time(fall_expr); net->decay_time(decay_expr); struct attrib_list_t*attrib_list; unsigned attrib_list_n = 0; attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope); for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) net->attribute(attrib_list[adx].key, attrib_list[adx].val); delete[]attrib_list; // This is the array of pin expressions, shuffled to match the // order of the declaration. If the source instantiation uses // bind by order, this is the same as the source // list. Otherwise, the source list is rearranged by name // binding into this list. vectorpins; // Detect binding by name. If I am binding by name, then make // up a pins array that reflects the positions of the named // ports. If this is simply positional binding in the first // place, then get the binding from the base class. if (pins_) { unsigned nexp = udp->ports.size(); pins = vector(nexp); // Scan the bindings, matching them with port names. for (unsigned idx = 0 ; idx < npins_ ; idx += 1) { // Given a binding, look at the module port names // for the position that matches the binding name. unsigned pidx = udp->find_port(pins_[idx].name); // If the port name doesn't exist, the find_port // method will return the port count. Detect that // as an error. if (pidx == nexp) { cerr << get_fileline() << ": error: port ``" << pins_[idx].name << "'' is not a port of " << get_name() << "." << endl; des->errors += 1; continue; } // If I already bound something to this port, then // the (*exp) array will already have a pointer // value where I want to place this expression. if (pins[pidx]) { cerr << get_fileline() << ": error: port ``" << pins_[idx].name << "'' already bound." << endl; des->errors += 1; continue; } // OK, do the binding by placing the expression in // the right place. pins[pidx] = pins_[idx].parm; } } else { /* Otherwise, this is a positional list of port connections. In this case, the port count must be right. Check that is is, the get the pin list. */ if (pin_count() != udp->ports.size()) { cerr << get_fileline() << ": error: Wrong number " "of ports. Expecting " << udp->ports.size() << ", got " << pin_count() << "." << endl; des->errors += 1; return; } // No named bindings, just use the positional list I // already have. assert(pin_count() == udp->ports.size()); pins = get_pins(); } /* Handle the output port of the primitive special. It is an output port (the only output port) so must be passed an l-value net. */ if (pins[0] == 0) { cerr << get_fileline() << ": warning: output port unconnected." << endl; } else { NetNet*sig = pins[0]->elaborate_lnet(des, scope); if (sig == 0) { cerr << get_fileline() << ": error: " << "Output port expression is not valid." << endl; cerr << get_fileline() << ": : Output " << "port of " << udp->name_ << " is " << udp->ports[0] << "." << endl; des->errors += 1; return; } else { connect(sig->pin(0), net->pin(0)); } if (sig->vector_width() != 1) { cerr << get_fileline() << ": error: " << "Output port expression " << *pins[0] << " is too wide (" << sig->vector_width() << ") expected 1." << endl; des->errors += 1; } } /* Run through the pins, making netlists for the pin expressions and connecting them to the pin in question. All of this is independent of the nature of the UDP. */ for (unsigned idx = 1 ; idx < net->pin_count() ; idx += 1) { if (pins[idx] == 0) continue; NetExpr*expr_tmp = elab_and_eval(des, scope, pins[idx], 1); if (expr_tmp == 0) { cerr << "internal error: Expression too complicated " "for elaboration:" << *pins[idx] << endl; continue; } NetNet*sig = expr_tmp->synthesize(des, scope, expr_tmp); ivl_assert(*this, sig); sig->set_line(*this); delete expr_tmp; connect(sig->pin(0), net->pin(idx)); if (sig->vector_width() != 1) { cerr << get_fileline() << ": error: " << "Input port expression " << *pins[idx] << " is too wide (" << sig->vector_width() << ") expected 1." << endl; des->errors += 1; } } // All done. Add the object to the design. des->add_node(net); } bool PGModule::elaborate_sig(Design*des, NetScope*scope) const { if (bound_type_) { return elaborate_sig_mod_(des, scope, bound_type_); } // Look for the module type map::const_iterator mod = pform_modules.find(type_); if (mod != pform_modules.end()) return elaborate_sig_mod_(des, scope, (*mod).second); // elaborate_sig_udp_ currently always returns true so skip all this // for now. #if 0 map::const_iterator udp = pform_primitives.find(type_); if (udp != pform_primitives.end()) return elaborate_sig_udp_(des, scope, (*udp).second); #endif return true; } void PGModule::elaborate(Design*des, NetScope*scope) const { if (bound_type_) { elaborate_mod_(des, bound_type_, scope); return; } // Look for the module type map::const_iterator mod = pform_modules.find(type_); if (mod != pform_modules.end()) { elaborate_mod_(des, (*mod).second, scope); return; } // Try a primitive type map::const_iterator udp = pform_primitives.find(type_); if (udp != pform_primitives.end()) { assert((*udp).second); elaborate_udp_(des, (*udp).second, scope); return; } if (!ignore_missing_modules) { cerr << get_fileline() << ": internal error: Unknown module type: " << type_ << endl; } } void PGModule::elaborate_scope(Design*des, NetScope*sc) const { // If the module type is known by design, then go right to it. if (bound_type_) { elaborate_scope_mod_(des, bound_type_, sc); return; } // Look for the module type map::const_iterator mod = pform_modules.find(type_); if (mod != pform_modules.end()) { elaborate_scope_mod_(des, mod->second, sc); return; } // Try a primitive type map::const_iterator udp = pform_primitives.find(type_); if (udp != pform_primitives.end()) return; // Not a module or primitive that I know about yet, so try to // load a library module file (which parses some new Verilog // code) and try again. int parser_errors = 0; if (load_module(type_, parser_errors)) { // Try again to find the module type mod = pform_modules.find(type_); if (mod != pform_modules.end()) { elaborate_scope_mod_(des, mod->second, sc); return; } // Try again to find a primitive type udp = pform_primitives.find(type_); if (udp != pform_primitives.end()) return; } if (parser_errors) { cerr << get_fileline() << ": error: Failed to parse library file." << endl; des->errors += parser_errors + 1; } // Not a module or primitive that I know about or can find by // any means, so give up. if (!ignore_missing_modules) { cerr << get_fileline() << ": error: Unknown module type: " << type_ << endl; missing_modules[type_] += 1; des->errors += 1; } } NetProc* Statement::elaborate(Design*des, NetScope*) const { cerr << get_fileline() << ": internal error: elaborate: " "What kind of statement? " << typeid(*this).name() << endl; NetProc*cur = new NetProc; des->errors += 1; return cur; } NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const { // A function called as a task does not have an L-value. if (! lval_) { // The R-value must be a simple function call. assert (dynamic_cast(rval_)); PExpr::width_mode_t mode = PExpr::SIZED; rval_->test_width(des, scope, mode); // Create a L-value that matches the function return type. NetNet*tmp; netvector_t*tmp_vec = new netvector_t(rval_->expr_type(), rval_->expr_width()-1, 0, rval_->has_sign()); if(rval_->expr_type() == IVL_VT_DARRAY) { netdarray_t*darray = new netdarray_t(tmp_vec); tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, darray); } else { tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp_vec); } tmp->set_file(rval_->get_file()); tmp->set_lineno(rval_->get_lineno()); NetAssign_*lv = new NetAssign_(tmp); return lv; } if (debug_elaborate) { cerr << get_fileline() << ": PAssign_::elaborate_lval: " << "lval_ = " << *lval_ << endl; cerr << get_fileline() << ": PAssign_::elaborate_lval: " << "lval_ expr type = " << typeid(*lval_).name() << endl; } return lval_->elaborate_lval(des, scope, false, false); } NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope, ivl_type_t net_type) const { ivl_assert(*this, rval_); NetExpr*rv = elab_and_eval(des, scope, rval_, net_type, is_constant_); if (!is_constant_ || !rv) return rv; cerr << get_fileline() << ": error: " "The RHS expression must be constant." << endl; cerr << get_fileline() << " : " "This expression violates the rule: " << *rv << endl; des->errors += 1; delete rv; return 0; } NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope, ivl_type_t lv_net_type, ivl_variable_type_t lv_type, unsigned lv_width, bool force_unsigned) const { ivl_assert(*this, rval_); // Don't have a good value for the lv_net_type argument to // elaborate_rval_expr, so punt and pass nil. In the future we // should look into fixing calls to this method to pass a // net_type instead of the separate lv_width/lv_type values. NetExpr*rv = elaborate_rval_expr(des, scope, lv_net_type, lv_type, lv_width, rval(), is_constant_, force_unsigned); if (!is_constant_ || !rv) return rv; if (dynamic_cast(rv)) return rv; if (dynamic_cast(rv)) return rv; cerr << get_fileline() << ": error: " "The RHS expression must be constant." << endl; cerr << get_fileline() << " : " "This expression violates the rule: " << *rv << endl; des->errors += 1; delete rv; return 0; } /* * This function elaborates delay expressions. This is a little * different from normal elaboration because the result may need to be * scaled. */ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope) { NetExpr*dex = elab_and_eval(des, scope, expr, -1); // If the elab_and_eval returns nil, then the function // failed. It should already have printed an error message, // but we can add some detail. Lets add the error count, just // in case. if (dex == 0) { cerr << expr->get_fileline() << ": error: " << "Unable to elaborate (or evaluate) delay expression." << endl; des->errors += 1; return 0; } check_for_inconsistent_delays(scope); /* If the delay expression is a real constant or vector constant, then evaluate it, scale it to the local time units, and return an adjusted NetEConst. */ if (NetECReal*tmp = dynamic_cast(dex)) { uint64_t delay = get_scaled_time_from_real(des, scope, tmp); delete tmp; NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); tmp2->set_line(*expr); return tmp2; } if (NetEConst*tmp = dynamic_cast(dex)) { verinum fn = tmp->value(); uint64_t delay = des->scale_to_precision(fn.as_ulong64(), scope); delete tmp; NetEConst*tmp2 = new NetEConst(verinum(delay, 64)); tmp2->set_line(*expr); return tmp2; } /* The expression is not constant, so generate an expanded expression that includes the necessary scale shifts, and return that expression. */ ivl_assert(*expr, dex); if (dex->expr_type() == IVL_VT_REAL) { // Scale the real value. int shift = scope->time_unit() - scope->time_precision(); assert(shift >= 0); double round = 1; for (int lp = 0; lp < shift; lp += 1) round *= 10.0; NetExpr*scal_val = new NetECReal(verireal(round)); scal_val->set_line(*expr); dex = new NetEBMult('*', dex, scal_val, 1, true); dex->set_line(*expr); // Cast this part of the expression to an integer. dex = new NetECast('v', dex, 64, false); dex->set_line(*expr); // Now scale the integer value. shift = scope->time_precision() - des->get_precision(); assert(shift >= 0); uint64_t scale = 1; for (int lp = 0; lp < shift; lp += 1) scale *= 10; scal_val = new NetEConst(verinum(scale, 64)); scal_val->set_line(*expr); dex = new NetEBMult('*', dex, scal_val, 64, false); dex->set_line(*expr); } else { int shift = scope->time_unit() - des->get_precision(); assert(shift >= 0); uint64_t scale = 1; for (int lp = 0; lp < shift; lp += 1) scale *= 10; NetExpr*scal_val = new NetEConst(verinum(scale, 64)); scal_val->set_line(*expr); dex = new NetEBMult('*', dex, scal_val, 64, false); dex->set_line(*expr); } return dex; } NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const { ivl_assert(*this, ! delay_); ivl_assert(*this, ! count_); ivl_assert(*this, ! event_); NetAssign_*lv = elaborate_lval(des, scope); if (lv == 0) return 0; // Compressed assignments should behave identically to the // equivalent uncompressed assignments. This means we need // to take the type of the LHS into account when determining // the type of the RHS expression. bool force_unsigned; switch (op_) { case 'l': case 'r': case 'R': // The right-hand operand of shift operations is // self-determined. force_unsigned = false; break; default: force_unsigned = !lv->get_signed(); break; } NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv), force_unsigned); if (rv == 0) return 0; // The ivl_target API doesn't support signalling the type // of a lval, so convert arithmetic shifts into logical // shifts now if the lval is unsigned. char op = op_; if ((op == 'R') && !lv->get_signed()) op = 'r'; NetAssign*cur = new NetAssign(lv, op, rv); cur->set_line(*this); return cur; } /* * Assignments within program blocks are supposed to be run * in the Reactive region, but that is currently not supported * so find out if we are assigning to something outside a * program block and print a warning for that. */ static bool lval_not_program_variable(const NetAssign_*lv) { while (lv) { NetScope*sig_scope = lv->scope(); if (! sig_scope->program_block()) return true; lv = lv->more; } return false; } NetProc* PAssign::elaborate(Design*des, NetScope*scope) const { assert(scope); /* If this is a compressed assignment, then handle the elaboration in a specialized function. */ if (op_ != 0) return elaborate_compressed_(des, scope); /* elaborate the lval. This detects any part selects and mux expressions that might exist. */ NetAssign_*lv = elaborate_lval(des, scope); if (lv == 0) return 0; if (scope->program_block() && lval_not_program_variable(lv)) { cerr << get_fileline() << ": warning: Program blocking " "assignments are not currently scheduled in the " "Reactive region." << endl; } /* If there is an internal delay expression, elaborate it. */ NetExpr*delay = 0; if (delay_ != 0) delay = elaborate_delay_expr(delay_, des, scope); NetExpr*rv; const ivl_type_s*lv_net_type = lv->net_type(); if (debug_elaborate) { cerr << get_fileline() << ": PAssign::elaborate: "; if (lv_net_type) cerr << "lv_net_type=" << *lv_net_type << endl; else cerr << "lv_net_type=" << endl; } /* If the l-value is a compound type of some sort, then use the newer net_type form of the elaborate_rval_ method to handle the new types. */ if (dynamic_cast (lv_net_type)) { ivl_assert(*this, lv->more==0); rv = elaborate_rval_(des, scope, lv_net_type); } else if (const netdarray_t*dtype = dynamic_cast (lv_net_type)) { ivl_assert(*this, lv->more==0); if (debug_elaborate) { if (lv->word()) cerr << get_fileline() << ": PAssign::elaborate: " << "lv->word() = " << *lv->word() << endl; else cerr << get_fileline() << ": PAssign::elaborate: " << "lv->word() = " << endl; } ivl_type_t use_lv_type = lv_net_type; if (lv->word()) use_lv_type = dtype->element_type(); rv = elaborate_rval_(des, scope, use_lv_type); } else if (const netuarray_t*utype = dynamic_cast(lv_net_type)) { ivl_assert(*this, lv->more==0); if (debug_elaborate) { if (lv->word()) cerr << get_fileline() << ": PAssign::elaborate: " << "lv->word() = " << *lv->word() << endl; else cerr << get_fileline() << ": PAssign::elaborate: " << "lv->word() = " << endl; } ivl_assert(*this, lv->word()); ivl_type_t use_lv_type = utype->element_type(); ivl_assert(*this, use_lv_type); rv = elaborate_rval_(des, scope, use_lv_type); } else { /* Elaborate the r-value expression, then try to evaluate it. */ rv = elaborate_rval_(des, scope, lv_net_type, lv->expr_type(), count_lval_width(lv)); } if (rv == 0) { delete lv; return 0; } assert(rv); if (count_) assert(event_); /* Rewrite delayed assignments as assignments that are delayed. For example, a = # b; becomes: begin tmp = b; # a = tmp; end If the delay is an event delay, then the transform is similar, with the event delay replacing the time delay. It is an event delay if the event_ member has a value. This rewriting of the expression allows me to not bother to actually and literally represent the delayed assign in the netlist. The compound statement is exactly equivalent. */ if (delay || event_) { unsigned wid = count_lval_width(lv); netvector_t*tmp2_vec = new netvector_t(rv->expr_type(),wid-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, tmp2_vec); tmp->local_flag(true); tmp->set_line(*this); NetESignal*sig = new NetESignal(tmp); /* Generate an assignment of the l-value to the temporary... */ NetAssign_*lvt = new NetAssign_(tmp); NetAssign*a1 = new NetAssign(lvt, rv); a1->set_line(*this); /* Generate an assignment of the temporary to the r-value... */ NetAssign*a2 = new NetAssign(lv, sig); a2->set_line(*this); /* Generate the delay statement with the final assignment attached to it. If this is an event delay, elaborate the PEventStatement. Otherwise, create the right NetPDelay object. For a repeat event control repeat the event and then do the final assignment. */ NetProc*st; if (event_) { if (count_) { NetExpr*count = elab_and_eval(des, scope, count_, -1); if (count == 0) { cerr << get_fileline() << ": Unable to " "elaborate repeat expression." << endl; des->errors += 1; return 0; } st = event_->elaborate(des, scope); if (st == 0) { cerr << event_->get_fileline() << ": error: " "unable to elaborate event expression." << endl; des->errors += 1; return 0; } st->set_line(*this); // If the expression is a constant, handle // certain special iteration counts. if (NetEConst*ce = dynamic_cast(count)) { long val = ce->value().as_long(); // We only need the real statement. if (val <= 0) { delete count; delete st; st = 0; // We don't need the repeat statement. } else if (val == 1) { delete count; // We need a repeat statement. } else { st = new NetRepeat(count, st); st->set_line(*this); } } else { st = new NetRepeat(count, st); st->set_line(*this); } } else { st = event_->elaborate_st(des, scope, a2); if (st == 0) { cerr << event_->get_fileline() << ": error: " "unable to elaborate event expression." << endl; des->errors += 1; return 0; } st->set_line(*this); } } else { NetPDelay*de = new NetPDelay(delay, a2); de->set_line(*this); st = de; } /* And build up the complex statement. */ NetBlock*bl = new NetBlock(NetBlock::SEQU, 0); bl->append(a1); if (st) bl->append(st); if (count_) bl->append(a2); bl->set_line(*this); return bl; } if (lv->enumeration()) { if (! rv->enumeration()) { cerr << get_fileline() << ": error: " "This assignment requires an explicit cast." << endl; des->errors += 1; } else if (! lv->enumeration()->matches(rv->enumeration())) { cerr << get_fileline() << ": error: " "Enumeration type mismatch in assignment." << endl; des->errors += 1; } } NetAssign*cur = new NetAssign(lv, rv); cur->set_line(*this); return cur; } /* * Elaborate non-blocking assignments. The statement is of the general * form: * * <= # ; */ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const { assert(scope); if (scope->in_func()) { cerr << get_fileline() << ": error: functions cannot have non " "blocking assignment statements." << endl; des->errors += 1; return 0; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot have " "non blocking assignment statements." << endl; des->errors += 1; return 0; } if (scope->is_auto() && lval()->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be assigned values using non-blocking " "assignments." << endl; des->errors += 1; return 0; } /* Elaborate the l-value. */ NetAssign_*lv = elaborate_lval(des, scope); if (lv == 0) return 0; if (scope->program_block() && lval_not_program_variable(lv)) { cerr << get_fileline() << ": warning: Program non-blocking " "assignments are not currently scheduled in the " "Reactive-NBA region." << endl; } NetExpr*rv = elaborate_rval_(des, scope, 0, lv->expr_type(), count_lval_width(lv)); if (rv == 0) return 0; NetExpr*delay = 0; if (delay_ != 0) { assert(count_ == 0 && event_ == 0); delay = elaborate_delay_expr(delay_, des, scope); } NetExpr*count = 0; NetEvWait*event = 0; if (count_ != 0 || event_ != 0) { if (count_ != 0) { if (scope->is_auto() && count_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically " "allocated variables may not be referenced " "in intra-assignment event controls of " "non-blocking assignments." << endl; des->errors += 1; return 0; } assert(event_ != 0); count = elab_and_eval(des, scope, count_, -1); if (count == 0) { cerr << get_fileline() << ": Unable to elaborate " "repeat expression." << endl; des->errors += 1; return 0; } } if (scope->is_auto() && event_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically " "allocated variables may not be referenced " "in intra-assignment event controls of " "non-blocking assignments." << endl; des->errors += 1; return 0; } NetProc*st = event_->elaborate(des, scope); if (st == 0) { cerr << get_fileline() << ": unable to elaborate " "event expression." << endl; des->errors += 1; return 0; } event = dynamic_cast(st) ; assert(event); // Some constant values are special. if (NetEConst*ce = dynamic_cast(count)) { long val = ce->value().as_long(); // We only need the assignment statement. if (val <= 0) { delete count; delete event; count = 0; event = 0; // We only need the event. } else if (val == 1) { delete count; count = 0; } } } /* All done with this node. Mark its line number and check it in. */ NetAssignNB*cur = new NetAssignNB(lv, rv, event, count); cur->set_delay(delay); cur->set_line(*this); return cur; } /* * This is the elaboration method for a begin-end block. Try to * elaborate the entire block, even if it fails somewhere. This way I * get all the error messages out of it. Then, if I detected a failure * then pass the failure up. */ NetProc* PBlock::elaborate(Design*des, NetScope*scope) const { assert(scope); NetBlock::Type type; switch (bl_type_) { case PBlock::BL_SEQ: type = NetBlock::SEQU; break; case PBlock::BL_PAR: type = NetBlock::PARA; break; case PBlock::BL_JOIN_NONE: type = NetBlock::PARA_JOIN_NONE; break; case PBlock::BL_JOIN_ANY: type = NetBlock::PARA_JOIN_ANY; break; // Added to remove a "type" uninitialized compiler warning. // This should never be reached since all the PBlock enumeration // cases are handled above. default: type = NetBlock::SEQU; assert(0); } NetScope*nscope = 0; if (pscope_name() != 0) { nscope = scope->child(hname_t(pscope_name())); if (nscope == 0) { cerr << get_fileline() << ": internal error: " "unable to find block scope " << scope_path(scope) << "." << pscope_name() << endl; des->errors += 1; return 0; } assert(nscope); } NetBlock*cur = new NetBlock(type, nscope); if (nscope) { // Handle any variable initialization statements in this scope. // For automatic scopes these statements need to be executed // each time the block is entered, so add them to the main // block. For static scopes, put them in a separate process // that will be executed at the start of simulation. if (nscope->is_auto()) { for (unsigned idx = 0; idx < var_inits.size(); idx += 1) { NetProc*tmp = var_inits[idx]->elaborate(des, nscope); if (tmp) cur->append(tmp); } } else { elaborate_var_inits_(des, nscope); } } if (nscope == 0) nscope = scope; // Handle the special case that the sequential block contains // only one statement. There is no need to keep the block node. // Also, don't elide named blocks, because they might be // referenced elsewhere. if ((type == NetBlock::SEQU) && (list_.size() == 1) && (pscope_name() == 0)) { assert(list_[0]); NetProc*tmp = list_[0]->elaborate(des, nscope); return tmp; } for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) { assert(list_[idx]); // Detect the error that a super.new() statement is in the // midst of a block. Report the error. Continue on with the // elaboration so that other errors might be found. if (PChainConstructor*supernew = dynamic_cast (list_[idx])) { if (debug_elaborate) { cerr << get_fileline() << ": PBlock::elaborate: " << "Found super.new statement, idx=" << idx << ", " << " at " << supernew->get_fileline() << "." << endl; } if (idx > 0) { des->errors += 1; cerr << supernew->get_fileline() << ": error: " << "super.new(...) must be the first statement in a block." << endl; } } NetProc*tmp = list_[idx]->elaborate(des, nscope); // If the statement fails to elaborate, then simply // ignore it. Presumably, the elaborate for the // statement already generated an error message and // marked the error count in the design so no need to // do any of that here. if (tmp == 0) { continue; } // If the result turns out to be a noop, then skip it. if (NetBlock*tbl = dynamic_cast(tmp)) if (tbl->proc_first() == 0) { delete tbl; continue; } cur->append(tmp); } // Update flags in parent scope. if (!nscope->is_const_func()) scope->is_const_func(false); if (nscope->calls_sys_task()) scope->calls_sys_task(true); cur->set_line(*this); return cur; } static int test_case_width(Design*des, NetScope*scope, PExpr*pe, PExpr::width_mode_t&mode) { unsigned expr_width = pe->test_width(des, scope, mode); if (debug_elaborate) { cerr << pe->get_fileline() << ": debug: test_width " << "of case expression " << *pe << endl; cerr << pe->get_fileline() << ": " << "returns type=" << pe->expr_type() << ", width=" << expr_width << ", signed=" << pe->has_sign() << ", mode=" << PExpr::width_mode_name(mode) << endl; } return expr_width; } static NetExpr*elab_and_eval_case(Design*des, NetScope*scope, PExpr*pe, bool context_is_real, bool context_unsigned, unsigned context_width) { if (context_unsigned) pe->cast_signed(false); unsigned width = context_is_real ? pe->expr_width() : context_width; NetExpr*expr = pe->elaborate_expr(des, scope, width, PExpr::NO_FLAGS); if (expr == 0) return 0; if (context_is_real) expr = cast_to_real(expr); eval_expr(expr, context_width); return expr; } /* * Elaborate a case statement. */ NetProc* PCase::elaborate(Design*des, NetScope*scope) const { ivl_assert(*this, scope); /* The type of the case expression and case item expressions is determined according to the following rules: - if any of the expressions is real, all the expressions are evaluated as real (non-real expressions will be treated as self-determined, then converted to real) - otherwise if any of the expressions is unsigned, all the expressions are evaluated as unsigned - otherwise all the expressions are evaluated as signed If the type is not real, the bit width is determined by the largest self-determined width of any of the expressions. */ PExpr::width_mode_t context_mode = PExpr::SIZED; unsigned context_width = test_case_width(des, scope, expr_, context_mode); bool context_is_real = (expr_->expr_type() == IVL_VT_REAL); bool context_unsigned = !expr_->has_sign(); for (unsigned idx = 0; idx < items_->size(); idx += 1) { PCase::Item*cur = (*items_)[idx]; for (list::iterator idx_expr = cur->expr.begin() ; idx_expr != cur->expr.end() ; ++idx_expr) { PExpr*cur_expr = *idx_expr; ivl_assert(*this, cur_expr); PExpr::width_mode_t cur_mode = PExpr::SIZED; unsigned cur_width = test_case_width(des, scope, cur_expr, cur_mode); if (cur_mode > context_mode) context_mode = cur_mode; if (cur_width > context_width) context_width = cur_width; if (cur_expr->expr_type() == IVL_VT_REAL) context_is_real = true; if (!cur_expr->has_sign()) context_unsigned = true; } } if (context_is_real) { context_width = 1; context_unsigned = false; } else if (context_mode >= PExpr::LOSSLESS) { /* Expressions may choose a different size if they are in a lossless context, so we need to run through the process again to get the final expression width. */ context_width = test_case_width(des, scope, expr_, context_mode); for (unsigned idx = 0; idx < items_->size(); idx += 1) { PCase::Item*cur = (*items_)[idx]; for (list::iterator idx_expr = cur->expr.begin() ; idx_expr != cur->expr.end() ; ++idx_expr) { PExpr*cur_expr = *idx_expr; ivl_assert(*this, cur_expr); unsigned cur_width = test_case_width(des, scope, cur_expr, context_mode); if (cur_width > context_width) context_width = cur_width; } } if (context_width < integer_width) context_width += 1; } if (debug_elaborate) { cerr << get_fileline() << ": debug: case context is "; if (context_is_real) { cerr << "real" << endl; } else { cerr << (context_unsigned ? "unsigned" : "signed") << " vector, width=" << context_width << endl; } } NetExpr*expr = elab_and_eval_case(des, scope, expr_, context_is_real, context_unsigned, context_width); if (expr == 0) { cerr << get_fileline() << ": error: Unable to elaborate this case" " expression." << endl; return 0; } /* Count the items in the case statement. Note that there may be some cases that have multiple guards. Count each as a separate item. */ unsigned icount = 0; for (unsigned idx = 0 ; idx < items_->size() ; idx += 1) { PCase::Item*cur = (*items_)[idx]; if (cur->expr.empty()) icount += 1; else icount += cur->expr.size(); } NetCase*res = new NetCase(quality_, type_, expr, icount); res->set_line(*this); /* Iterate over all the case items (guard/statement pairs) elaborating them. If the guard has no expression, then this is a "default" case. Otherwise, the guard has one or more expressions, and each guard is a case. */ unsigned inum = 0; for (unsigned idx = 0 ; idx < items_->size() ; idx += 1) { ivl_assert(*this, inum < icount); PCase::Item*cur = (*items_)[idx]; if (cur->expr.empty()) { /* If there are no expressions, then this is the default case. */ NetProc*st = 0; if (cur->stat) st = cur->stat->elaborate(des, scope); res->set_case(inum, 0, st); inum += 1; } else for (list::iterator idx_expr = cur->expr.begin() ; idx_expr != cur->expr.end() ; ++idx_expr) { /* If there are one or more expressions, then iterate over the guard expressions, elaborating a separate case for each. (Yes, the statement will be elaborated again for each.) */ PExpr*cur_expr = *idx_expr; ivl_assert(*this, cur_expr); NetExpr*gu = elab_and_eval_case(des, scope, cur_expr, context_is_real, context_unsigned, context_width); NetProc*st = 0; if (cur->stat) st = cur->stat->elaborate(des, scope); res->set_case(inum, gu, st); inum += 1; } } res->prune(); return res; } NetProc* PChainConstructor::elaborate(Design*des, NetScope*scope) const { assert(scope); if (debug_elaborate) { cerr << get_fileline() << ": PChainConstructor::elaborate: " << "Elaborate constructor chain in scope=" << scope_path(scope) << endl; } // The scope is the .new function, so scope->parent() // is the class. Use that to get the class type that we are // constructing. NetScope*scope_class = scope->parent(); const netclass_t*class_this = scope_class->class_def(); ivl_assert(*this, class_this); // We also need the super-class. const netclass_t*class_super = class_this->get_super(); if (class_super == 0) { cerr << get_fileline() << ": error: " << "Class " << class_this->get_name() << " has no parent class for super.new constructor chaining." << endl; des->errors += 1; NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0); tmp->set_line(*this); return tmp; } // Need the "this" variable for the current constructor. We're // going to pass this to the chained constructor. NetNet*var_this = scope->find_signal(perm_string::literal(THIS_TOKEN)); // If super.new is an implicit constructor, then there are no // arguments (other than "this" to worry about, so make a // NetEUFunc and there we go. if (NetScope*new_scope = class_super->method_from_name(perm_string::literal("new@"))) { NetESignal*eres = new NetESignal(var_this); vector parms(1); parms[0] = eres; NetEUFunc*tmp = new NetEUFunc(scope, new_scope, eres, parms, true); tmp->set_line(*this); NetAssign_*lval_this = new NetAssign_(var_this); NetAssign*stmt = new NetAssign(lval_this, tmp); stmt->set_line(*this); return stmt; } // If super.new(...) is a user defined constructor, then call // it. This is a bit more complicated because there may be arguments. if (NetScope*new_scope = class_super->method_from_name(perm_string::literal("new"))) { int missing_parms = 0; NetFuncDef*def = new_scope->func_def(); ivl_assert(*this, def); NetESignal*eres = new NetESignal(var_this); vector parms (def->port_count()); parms[0] = eres; for (size_t idx = 1 ; idx < parms.size() ; idx += 1) { if (idx <= parms_.size() && parms_[idx-1]) { PExpr*tmp = parms_[idx-1]; parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->net_type(), tmp, false); continue; } if (NetExpr*tmp = def->port_defe(idx)) { parms[idx] = tmp; continue; } missing_parms += 1; parms[idx] = 0; } if (missing_parms) { cerr << get_fileline() << ": error: " << "Missing " << missing_parms << " arguments to constructor " << scope_path(new_scope) << "." << endl; des->errors += 1; } NetEUFunc*tmp = new NetEUFunc(scope, new_scope, eres, parms, true); tmp->set_line(*this); NetAssign_*lval_this = new NetAssign_(var_this); NetAssign*stmt = new NetAssign(lval_this, tmp); stmt->set_line(*this); return stmt; } // There is no constructor at all in the parent, so skip it. NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0); tmp->set_line(*this); return tmp; } NetProc* PCondit::elaborate(Design*des, NetScope*scope) const { assert(scope); if (debug_elaborate) cerr << get_fileline() << ": PCondit::elaborate: " << "Elaborate condition statement" << " with conditional: " << *expr_ << endl; // Elaborate and try to evaluate the conditional expression. NetExpr*expr = elab_and_eval(des, scope, expr_, -1); if (expr == 0) { cerr << get_fileline() << ": error: Unable to elaborate" " condition expression." << endl; des->errors += 1; return 0; } // If the condition of the conditional statement is constant, // then look at the value and elaborate either the if statement // or the else statement. I don't need both. If there is no // else_ statement, then use an empty block as a noop. if (NetEConst*ce = dynamic_cast(expr)) { verinum val = ce->value(); if (debug_elaborate) { cerr << get_fileline() << ": debug: Condition expression " << "is a constant " << val << "." << endl; } verinum::V reduced = verinum::V0; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) reduced = reduced | val[idx]; delete expr; if (reduced == verinum::V1) if (if_) { return if_->elaborate(des, scope); } else { NetBlock*tmp = new NetBlock(NetBlock::SEQU, 0); tmp->set_line(*this); return tmp; } else if (else_) return else_->elaborate(des, scope); else return new NetBlock(NetBlock::SEQU, 0); } // If the condition expression is more than 1 bits, then // generate a comparison operator to get the result down to // one bit. Turn into != 0; if (expr->expr_width() < 1) { cerr << get_fileline() << ": internal error: " "incomprehensible expression width (0)." << endl; return 0; } // Make sure the condition expression evaluates to a condition. expr = condition_reduce(expr); // Well, I actually need to generate code to handle the // conditional, so elaborate. NetProc*i = if_? if_->elaborate(des, scope) : 0; NetProc*e = else_? else_->elaborate(des, scope) : 0; // Detect the special cases that the if or else statements are // empty blocks. If this is the case, remove the blocks as // null statements. if (NetBlock*tmp = dynamic_cast(i)) { if (tmp->proc_first() == 0) { delete i; i = 0; } } if (NetBlock*tmp = dynamic_cast(e)) { if (tmp->proc_first() == 0) { delete e; e = 0; } } NetCondit*res = new NetCondit(expr, i, e); res->set_line(*this); return res; } NetProc* PCallTask::elaborate(Design*des, NetScope*scope) const { if (peek_tail_name(path_)[0] == '$') { if (void_cast_) return elaborate_non_void_function_(des, scope); else return elaborate_sys(des, scope); } else { return elaborate_usr(des, scope); } } /* * A call to a system task involves elaborating all the parameters, * then passing the list to the NetSTask object. *XXXX * There is a single special case in the call to a system * task. Normally, an expression cannot take an unindexed * memory. However, it is possible to take a system task parameter a * memory if the expression is trivial. */ NetProc* PCallTask::elaborate_sys(Design*des, NetScope*scope) const { assert(scope); if (path_.size() > 1) { cerr << get_fileline() << ": error: Hierarchical system task names" << " make no sense: " << path_ << endl; des->errors += 1; } unsigned parm_count = parms_.size(); /* Catch the special case that the system task has no parameters. The "()" string will be parsed as a single empty parameter, when we really mean no parameters at all. */ if ((parm_count== 1) && (parms_[0] == 0)) parm_count = 0; vectoreparms (parm_count); perm_string name = peek_tail_name(path_); for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { PExpr*ex = parms_[idx]; if (ex != 0) { eparms[idx] = elab_sys_task_arg(des, scope, name, idx, ex); } else { eparms[idx] = 0; } } // Special case: Specify blocks are turned off, and this is an // $sdf_annotate system task. There will be nothing for $sdf // to annotate, and the user is intending to turn the behavior // off anyhow, so replace the system task invocation with a no-op. if (gn_specify_blocks_flag == false && name == "$sdf_annotate") { cerr << get_fileline() << ": warning: Omitting $sdf_annotate() " << "since specify blocks are being omitted." << endl; NetBlock*noop = new NetBlock(NetBlock::SEQU, scope); noop->set_line(*this); return noop; } scope->calls_sys_task(true); NetSTask*cur = new NetSTask(name, def_sfunc_as_task, eparms); cur->set_line(*this); return cur; } /* * A call to a user defined task is different from a call to a system * task because a user task in a netlist has no parameters: the * assignments are done by the calling thread. For example: * * task foo; * input a; * output b; * [...] * endtask; * * [...] foo(x, y); * * is really: * * task foo; * reg a; * reg b; * [...] * endtask; * * [...] * begin * a = x; * foo; * y = b; * end */ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const { assert(scope); NetScope*pscope = scope; if (package_) { pscope = des->find_package(package_->pscope_name()); ivl_assert(*this, pscope); } NetScope*task = des->find_task(pscope, path_); if (task == 0) { // For SystemVerilog this may be a few other things. if (gn_system_verilog()) { NetProc *tmp; // This could be a method attached to a signal // or defined in this object? bool try_implicit_this = scope->get_class_scope() && path_.size() == 1; tmp = elaborate_method_(des, scope, try_implicit_this); if (tmp) return tmp; // Or it could be a function call ignoring the return? tmp = elaborate_function_(des, scope); if (tmp) return tmp; } cerr << get_fileline() << ": error: Enable of unknown task " << "``" << path_ << "''." << endl; des->errors += 1; return 0; } assert(task); assert(task->type() == NetScope::TASK); NetTaskDef*def = task->task_def(); if (def == 0) { cerr << get_fileline() << ": internal error: task " << path_ << " doesn't have a definition in " << scope_path(scope) << "." << endl; des->errors += 1; return 0; } assert(def); /* In SystemVerilog a method calling another method in the * current class needs to be elaborated as a method with an * implicit this added. */ if (gn_system_verilog() && (path_.size() == 1)) { const NetScope *c_scope = scope->get_class_scope(); if (c_scope && (c_scope == task->get_class_scope())) { NetProc *tmp = elaborate_method_(des, scope, true); assert(tmp); return tmp; } } unsigned parm_count = def->port_count(); /* Handle non-automatic tasks with no parameters specially. There is no need to make a sequential block to hold the generated code. */ if ((parm_count == 0) && !task->is_auto()) { // Check if a task call is allowed in this context. test_task_calls_ok_(des, scope); NetUTask*cur = new NetUTask(task); cur->set_line(*this); return cur; } return elaborate_build_call_(des, scope, task, 0); } /* * This private method is called to elaborate built-in methods. The * method_name is the detected name of the built-in method, and the * sys_task_name is the internal system-task name to use. */ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, const char*sys_task_name) const { NetESignal*sig = new NetESignal(net); sig->set_line(*this); /* If there is a single NULL argument then ignore it since it is * left over from the parser and is not needed by the method. */ unsigned nparms = parms_.size(); if ((nparms == 1) && (parms_[0] == 0)) nparms = 0; vectorargv (1 + nparms); argv[0] = sig; if (method_name == "delete") { // The queue delete method takes an optional element. if (net->queue_type()) { if (nparms > 1) { cerr << get_fileline() << ": error: queue delete() " << "method takes zero or one argument." << endl; des->errors += 1; } } else if (nparms > 0) { cerr << get_fileline() << ": error: darray delete() " << "method takes no arguments." << endl; des->errors += 1; } } for (unsigned idx = 0 ; idx < nparms ; idx += 1) { PExpr*ex = parms_[idx]; if (ex != 0) { argv[idx+1] = elab_sys_task_arg(des, scope, method_name, idx, ex); } else { argv[idx+1] = 0; } } NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv); sys->set_line(*this); return sys; } /* * This private method is called to elaborate queue push methods. The * sys_task_name is the internal system-task name to use. */ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope, NetNet*net, perm_string method_name, const char*sys_task_name) const { NetESignal*sig = new NetESignal(net); sig->set_line(*this); unsigned nparms = parms_.size(); // insert() requires two arguments. if ((method_name == "insert") && (nparms != 2)) { cerr << get_fileline() << ": error: " << method_name << "() method requires two arguments." << endl; des->errors += 1; } // push_front() and push_back() require one argument. if ((method_name != "insert") && (nparms != 1)) { cerr << get_fileline() << ": error: " << method_name << "() method requires a single argument." << endl; des->errors += 1; } // Get the context width if this is a logic type. ivl_variable_type_t base_type = net->darray_type()->element_base_type(); int context_width = -1; switch (base_type) { case IVL_VT_BOOL: case IVL_VT_LOGIC: context_width = net->darray_type()->element_width(); break; default: break; } vectorargv (nparms+1); argv[0] = sig; if (method_name != "insert") { if ((nparms == 0) || (parms_[0] == 0)) { argv[1] = 0; cerr << get_fileline() << ": error: " << method_name << "() methods first argument is missing." << endl; des->errors += 1; } else argv[1] = elab_and_eval(des, scope, parms_[0], context_width, false, false, base_type); } else { if ((nparms == 0) || (parms_[0] == 0)) { argv[1] = 0; cerr << get_fileline() << ": error: " << method_name << "() methods first argument is missing." << endl; des->errors += 1; } else argv[1] = elab_and_eval(des, scope, parms_[0], 32, false, false, IVL_VT_LOGIC); if ((nparms < 2) || (parms_[1] == 0)) { argv[2] = 0; cerr << get_fileline() << ": error: " << method_name << "() methods second argument is missing." << endl; des->errors += 1; } else argv[2] = elab_and_eval(des, scope, parms_[1], context_width, false, false, base_type); } NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv); sys->set_line(*this); return sys; } /* * This is used for array/queue function methods called as tasks. */ NetProc* PCallTask::elaborate_method_func_(NetScope*scope, NetNet*net, ivl_type_t type, perm_string method_name, const char*sys_task_name) const { if (!void_cast_) { cerr << get_fileline() << ": warning: method function '" << method_name << "' is being called as a task." << endl; } // Generate the function. NetESFunc*sys_expr = new NetESFunc(sys_task_name, type, 1); sys_expr->set_line(*this); NetESignal*arg = new NetESignal(net); arg->set_line(*net); sys_expr->parm(0, arg); // Create a L-value that matches the function return type. NetNet*tmp; tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, type); tmp->set_line(*this); NetAssign_*lv = new NetAssign_(tmp); // Generate an assign to the fake L-value. NetAssign*cur = new NetAssign(lv, sys_expr); cur->set_line(*this); return cur; } NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, bool add_this_flag) const { pform_name_t use_path = path_; perm_string method_name = peek_tail_name(use_path); use_path.pop_back(); NetNet *net; ivl_type_t cls_val = 0; const NetExpr *par; ivl_type_t par_type = 0; NetEvent *eve; /* Add the implicit this reference when requested. */ if (add_this_flag) { assert(use_path.empty()); use_path.push_front(name_component_t(perm_string::literal(THIS_TOKEN))); } if (debug_elaborate) { cerr << get_fileline() << ": PCallTask::elaborate_method_: " << "use_path=" << use_path << ", method_name=" << method_name << ", add_this_flag=" << add_this_flag << endl; } // There is no signal to search for so this cannot be a method. if (use_path.empty()) return 0; // Search for an object using the use_path. This should // resolve to a class object. Note that the "this" symbol // (internally represented as "@") is handled by there being a // "this" object in the instance scope. symbol_search(this, des, scope, use_path, net, par, eve, par_type, cls_val); if (net == 0) return 0; if (debug_elaborate) { cerr << get_fileline() << ": PCallTask::elaborate_method_: " << "Try to match method " << method_name << " of object " << net->name() << "." << endl; if (net->net_type()) cerr << get_fileline() << ": PCallTask::elaborate_method_: " << net->name() << ".net_type() --> " << *net->net_type() << endl; cerr << get_fileline() << ": PCallTask::elaborate_method_: " << net->name() << ".data_type() --> " << net->data_type() << endl; } // Is this a method of a "string" type? if (dynamic_cast(net->net_type())) { if (method_name=="itoa") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_string_method$itoa"); else if (method_name=="hextoa") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_string_method$hextoa"); else if (method_name=="octtoa") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_string_method$octtoa"); else if (method_name=="bintoa") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_string_method$bintoa"); else if (method_name=="realtoa") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_string_method$realtoa"); } // Is this a delete method for dynamic arrays or queues? if (net->darray_type()) { if (method_name=="delete") return elaborate_sys_task_method_(des, scope, net, method_name, "$ivl_darray_method$delete"); else if (method_name=="size") // This returns an int. It could be removed, but keep for now. return elaborate_method_func_(scope, net, &netvector_t::atom2s32, method_name, "$size"); else if (method_name=="reverse") { cerr << get_fileline() << ": sorry: 'reverse()' " "array sorting method is not currently supported." << endl; des->errors += 1; return 0; } else if (method_name=="sort") { cerr << get_fileline() << ": sorry: 'sort()' " "array sorting method is not currently supported." << endl; des->errors += 1; return 0; } else if (method_name=="rsort") { cerr << get_fileline() << ": sorry: 'rsort()' " "array sorting method is not currently supported." << endl; des->errors += 1; return 0; } else if (method_name=="shuffle") { cerr << get_fileline() << ": sorry: 'shuffle()' " "array sorting method is not currently supported." << endl; des->errors += 1; return 0; } } if (net->queue_type()) { const netdarray_t*use_darray = net->darray_type(); if (method_name == "push_back") return elaborate_queue_method_(des, scope, net, method_name, "$ivl_queue_method$push_back"); else if (method_name == "push_front") return elaborate_queue_method_(des, scope, net, method_name, "$ivl_queue_method$push_front"); else if (method_name == "insert") return elaborate_queue_method_(des, scope, net, method_name, "$ivl_queue_method$insert"); else if (method_name == "pop_front") return elaborate_method_func_(scope, net, use_darray->element_type(), method_name, "$ivl_queue_method$pop_front"); else if (method_name == "pop_back") return elaborate_method_func_(scope, net, use_darray->element_type(), method_name, "$ivl_queue_method$pop_back"); } if (const netclass_t*class_type = dynamic_cast(par_type)) { NetScope*task = class_type->method_from_name(method_name); if (task == 0) { // If an implicit this was added it is not an error if we // don't find a method. It might actually be a call to a // function outside of the class. if (!add_this_flag) { cerr << get_fileline() << ": error: " << "Can't find task " << method_name << " in class " << class_type->get_name() << endl; des->errors += 1; } return 0; } if (debug_elaborate) { cerr << get_fileline() << ": PCallTask::elaborate_method_: " << "Elaborate " << class_type->get_name() << " method " << task->basename() << endl; } NetESignal*use_this = new NetESignal(net); use_this->set_line(*this); return elaborate_build_call_(des, scope, task, use_this); } return 0; } /* * If during elaboration we determine (for sure) that we are calling a * task (and not just a void function) then this method tests if that * task call is allowed in the current context. If so, return true. If * not, print an error message and return false; */ bool PCallTask::test_task_calls_ok_(Design*des, NetScope*scope) const { if (scope->in_func()) { cerr << get_fileline() << ": error: Functions cannot enable/call " "tasks." << endl; des->errors += 1; return false; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot " "enable/call tasks." << endl; des->errors += 1; return false; } return true; } NetProc *PCallTask::elaborate_non_void_function_(Design *des, NetScope *scope) const { // Generate a function call version of this task call. PExpr*rval = new PECallFunction(package_, path_, parms_); rval->set_file(get_file()); rval->set_lineno(get_lineno()); // Generate an assign to nothing. PAssign*tmp = new PAssign(0, rval); tmp->set_file(get_file()); tmp->set_lineno(get_lineno()); if (!void_cast_) { cerr << get_fileline() << ": warning: User function '" << peek_tail_name(path_) << "' is being called as a task." << endl; } // Elaborate the assignment to a dummy variable. return tmp->elaborate(des, scope); } NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const { NetFuncDef*func = des->find_function(scope, path_); // This is not a function, so this task call cannot be a function // call with a missing return assignment. if (!func) return nullptr; if (gn_system_verilog() && func->is_void()) return elaborate_void_function_(des, scope, func); return elaborate_non_void_function_(des, scope); } NetProc* PCallTask::elaborate_void_function_(Design*des, NetScope*scope, NetFuncDef*def) const { NetScope*dscope = def->scope(); if (debug_elaborate) { cerr << get_fileline() << ": PCallTask::elaborate_void_function_: " << "function void " << scope_path(dscope) << endl; } // If we haven't already elaborated the function, do so now. // This allows elaborate_build_call_ to elide the function call // if the function body is empty. if (dscope->elab_stage() < 3) { const PFunction*pfunc = dscope->func_pform(); ivl_assert(*this, pfunc); pfunc->elaborate(des, dscope); } return elaborate_build_call_(des, scope, dscope, 0); } NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, NetScope*task, NetExpr*use_this) const { NetBaseDef*def = 0; if (task->type() == NetScope::TASK) { def = task->task_def(); // OK, this is certainly a TASK that I'm calling. Make // sure that is OK where I am. Even if this test fails, // continue with the elaboration as if it were OK so // that we can catch more errors. test_task_calls_ok_(des, scope); if (void_cast_) { cerr << get_fileline() << ": error: void casting user task '" << peek_tail_name(path_) << "' is not allowed." << endl; des->errors++; } } else if (task->type() == NetScope::FUNC) { NetFuncDef*tmp = task->func_def(); if (!tmp->is_void()) return elaborate_non_void_function_(des, scope); def = tmp; if (void_cast_) { cerr << get_fileline() << ": error: void casting user void function '" << peek_tail_name(path_) << "' is not allowed." << endl; des->errors++; } } /* The caller has checked the parms_ size to make sure it matches the task definition, so we can just use the task definition to get the parm_count. */ unsigned parm_count = def->port_count(); if (parms_.size() > parm_count) { cerr << get_fileline() << ": error: " << "Too many arguments (" << parms_.size() << ", expecting " << parm_count << ")" << " in call to task." << endl; des->errors += 1; } NetBlock*block = new NetBlock(NetBlock::SEQU, 0); block->set_line(*this); /* Detect the case where the definition of the task is known empty. In this case, we need not bother with calls to the task, all the assignments, etc. Just return a no-op. */ if (const NetBlock*tp = dynamic_cast(def->proc())) { if (tp->proc_first() == 0) { if (debug_elaborate) { cerr << get_fileline() << ": PCallTask::elaborate_build_call_: " << "Eliding call to empty task " << task->basename() << endl; } return block; } } /* If this is an automatic task, generate a statement to allocate the local storage. */ if (task->is_auto()) { NetAlloc*ap = new NetAlloc(task); ap->set_line(*this); block->append(ap); } /* If this is a method call, then the use_this pointer will have an expression for the "this" argument. The "this" argument is the first argument of any method, so emit it here. */ if (use_this) { ivl_assert(*this, def->port_count() >= 1); NetNet*port = def->port(0); ivl_assert(*this, port->port_type()==NetNet::PINPUT); NetAssign_*lv = new NetAssign_(port); NetAssign*pr = new NetAssign(lv, use_this); pr->set_line(*this); block->append(pr); } /* Generate assignment statement statements for the input and INOUT ports of the task. These are managed by writing assignments with the task port the l-value and the passed expression the r-value. We know by definition that the port is a reg type, so this elaboration is pretty obvious. */ for (unsigned idx = use_this?1:0 ; idx < parm_count ; idx += 1) { size_t parms_idx = use_this? idx-1 : idx; NetNet*port = def->port(idx); assert(port->port_type() != NetNet::NOT_A_PORT); if (port->port_type() == NetNet::POUTPUT) continue; NetAssign_*lv = new NetAssign_(port); unsigned wid = count_lval_width(lv); ivl_variable_type_t lv_type = lv->expr_type(); NetExpr*rv = 0; if (parms_idx < parms_.size() && parms_[parms_idx]) { rv = elaborate_rval_expr(des, scope, port->net_type(), parms_ [parms_idx]); if (NetEEvent*evt = dynamic_cast (rv)) { cerr << evt->get_fileline() << ": error: An event '" << evt->event()->name() << "' can not be a user " "task argument." << endl; des->errors += 1; continue; } } else if (def->port_defe(idx)) { if (! gn_system_verilog()) { cerr << get_fileline() << ": internal error: " << "Found (and using) default task expression " "requires SystemVerilog." << endl; des->errors += 1; } rv = def->port_defe(idx); if (lv_type==IVL_VT_BOOL||lv_type==IVL_VT_LOGIC) rv = pad_to_width(rv->dup_expr(), wid, *this); } else { cerr << get_fileline() << ": error: " << "Missing argument " << (idx+1) << " of call to task." << endl; des->errors += 1; continue; } NetAssign*pr = new NetAssign(lv, rv); pr->set_line(*this); block->append(pr); } /* Generate the task call proper... */ NetUTask*cur = new NetUTask(task); cur->set_line(*this); block->append(cur); /* Generate assignment statements for the output and INOUT ports of the task. The l-value in this case is the expression passed as a parameter, and the r-value is the port to be copied out. We know by definition that the r-value of this copy-out is the port, which is a reg. The l-value, however, may be any expression that can be a target to a procedural assignment, including a memory word. */ for (unsigned idx = use_this?1:0 ; idx < parm_count ; idx += 1) { size_t parms_idx = use_this? idx-1 : idx; NetNet*port = def->port(idx); /* Skip input ports. */ assert(port->port_type() != NetNet::NOT_A_PORT); if (port->port_type() == NetNet::PINPUT) continue; /* Elaborate an l-value version of the port expression for output and inout ports. If the expression does not exist or is not a valid l-value print an error message. Note that the elaborate_lval method already printed a detailed message for the latter case. */ NetAssign_*lv = 0; if (parms_idx < parms_.size() && parms_[parms_idx]) { lv = parms_[parms_idx]->elaborate_lval(des, scope, false, false); if (lv == 0) { cerr << parms_[parms_idx]->get_fileline() << ": error: " << "I give up on task port " << (idx+1) << " expression: " << *parms_[parms_idx] << endl; } } else if (port->port_type() == NetNet::POUTPUT) { // Output ports were skipped earlier, so // report the error now. cerr << get_fileline() << ": error: " << "Missing argument " << (idx+1) << " of call to task." << endl; des->errors += 1; } if (lv == 0) continue; NetExpr*rv = new NetESignal(port); /* Handle any implicit cast. */ unsigned lv_width = count_lval_width(lv); if (lv->expr_type() != rv->expr_type()) { switch (lv->expr_type()) { case IVL_VT_REAL: rv = cast_to_real(rv); break; case IVL_VT_BOOL: rv = cast_to_int2(rv, lv_width); break; case IVL_VT_LOGIC: rv = cast_to_int4(rv, lv_width); break; default: /* Don't yet know how to handle this. */ ivl_assert(*this, 0); break; } } rv = pad_to_width(rv, lv_width, *this); /* Generate the assignment statement. */ NetAssign*ass = new NetAssign(lv, rv); ass->set_line(*this); block->append(ass); } /* If this is an automatic task, generate a statement to free the local storage. */ if (task->is_auto()) { NetFree*fp = new NetFree(task); fp->set_line(*this); block->append(fp); } return block; } static bool check_parm_is_const(NetExpr*param) { // FIXME: Are these actually needed and are others needed? // if (dynamic_cast(param)) { cerr << "Enum" << endl; return; } // if (dynamic_cast(param)) { cerr << "String" << endl; return; } if (dynamic_cast(param)) return true; if (dynamic_cast(param)) return true; if (dynamic_cast(param)) return true; if (dynamic_cast(param)) return true; return false; } static bool get_value_as_long(const NetExpr*expr, long&val) { switch(expr->expr_type()) { case IVL_VT_REAL: { const NetECReal*c = dynamic_cast (expr); assert(c); verireal tmp = c->value(); val = tmp.as_long(); break; } case IVL_VT_BOOL: case IVL_VT_LOGIC: { const NetEConst*c = dynamic_cast(expr); assert(c); verinum tmp = c->value(); if (tmp.is_string()) return false; val = tmp.as_long(); break; } default: return false; } return true; } static bool get_value_as_string(const NetExpr*expr, string&str) { switch(expr->expr_type()) { case IVL_VT_REAL: return false; break; case IVL_VT_BOOL: case IVL_VT_LOGIC: { const NetEConst*c = dynamic_cast(expr); assert(c); verinum tmp = c->value(); if (!tmp.is_string()) return false; str = tmp.as_string(); break; } default: return false; } return true; } /* Elaborate an elaboration task. */ bool PCallTask::elaborate_elab(Design*des, NetScope*scope) const { assert(scope); assert(path_.size() == 1); unsigned parm_count = parms_.size(); /* Catch the special case that the elaboration task has no parameters. The "()" string will be parsed as a single empty parameter, when we really mean no parameters at all. */ if ((parm_count== 1) && (parms_[0] == 0)) parm_count = 0; perm_string name = peek_tail_name(path_); if (!gn_system_verilog()) { cerr << get_fileline() << ": error: Elaboration task '" << name << "' requires SystemVerilog." << endl; des->errors += 1; return false; } if (name != "$fatal" && name != "$error" && name != "$warning" && name != "$info") { cerr << get_fileline() << ": error: '" << name << "' is not a valid elaboration task." << endl; des->errors += 1; return true; } vectoreparms (parm_count); bool const_parms = true; for (unsigned idx = 0 ; idx < parm_count ; idx += 1) { PExpr*ex = parms_[idx]; if (ex != 0) { eparms[idx] = elab_sys_task_arg(des, scope, name, idx, ex); if (!check_parm_is_const(eparms[idx])) { cerr << get_fileline() << ": error: Elaboration task " << name << "() parameter [" << idx+1 << "] '" << *eparms[idx] << "' is not constant." << endl; des->errors += 1; const_parms = false; } } else { eparms[idx] = 0; } } if (!const_parms) return true; // Drop the $ and convert to upper case for the severity string string sstr = name.str()+1; transform(sstr.begin(), sstr.end(), sstr.begin(), ::toupper); cerr << sstr << ": " << get_fileline() << ":"; if (parm_count != 0) { unsigned param_start = 0; // Drop the finish number, but check it is actually valid! if (name == "$fatal") { long finish_num = 1; if (!get_value_as_long(eparms[0],finish_num)) { cerr << endl; cerr << get_fileline() << ": error: Elaboration task " "$fatal() finish number argument must be " "numeric." << endl;; des->errors += 1; cerr << string(sstr.size()+1, ' '); } else if ((finish_num < 0) || (finish_num > 2)) { cerr << endl; cerr << get_fileline() << ": error: Elaboration task " "$fatal() finish number argument must be in " "the range [0-2], given '" << finish_num << "'." << endl;; des->errors += 1; cerr << string(sstr.size()+1, ' '); } param_start += 1; } // FIXME: For now just handle a single string value. string str; if ((parm_count == param_start + 1) && (get_value_as_string(eparms[param_start], str))) { cerr << " " << str; } else if (param_start < parm_count) { cerr << endl; cerr << get_fileline() << ": sorry: Elaboration tasks " "currently only support a single string argument."; des->errors += 1; } /* cerr << *eparms[0]; for (unsigned idx = 1; idx < parm_count; idx += 1) { cerr << ", " << *eparms[idx]; } */ } cerr << endl; cerr << string(sstr.size(), ' ') << " During elaboration Scope: " << scope->fullname() << endl; // For a fatal mark as an error and fail elaboration. if (name == "$fatal") { des->errors += 1; return false; } // For an error just set it as an error. if (name == "$error") des->errors += 1; return true; } /* * Elaborate a procedural continuous assign. This really looks very * much like other procedural assignments, at this point, but there * is no delay to worry about. The code generator will take care of * the differences between continuous assign and normal assignments. */ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const { NetCAssign*dev = 0; assert(scope); if (scope->is_auto() && lval_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be assigned values using procedural " "continuous assignments." << endl; des->errors += 1; return 0; } if (scope->is_auto() && expr_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be referenced in procedural " "continuous assignments." << endl; des->errors += 1; return 0; } NetAssign_*lval = lval_->elaborate_lval(des, scope, true, false); if (lval == 0) return 0; unsigned lwid = count_lval_width(lval); ivl_variable_type_t ltype = lval->expr_type(); // Need to figure out a better thing to do about the // lv_net_type argument to elaborate_rval_expr here. This // would entail getting the NetAssign_ to give us an // ivl_type_t as needed. NetExpr*rexp = elaborate_rval_expr(des, scope, 0, ltype, lwid, expr_); if (rexp == 0) return 0; dev = new NetCAssign(lval, rexp); if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate cassign," << " lval width=" << lwid << " rval width=" << rexp->expr_width() << " rval=" << *rexp << endl; } dev->set_line(*this); return dev; } NetDeassign* PDeassign::elaborate(Design*des, NetScope*scope) const { assert(scope); if (scope->is_auto() && lval_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be assigned values using procedural " "continuous assignments." << endl; des->errors += 1; return 0; } NetAssign_*lval = lval_->elaborate_lval(des, scope, true, false); if (lval == 0) return 0; NetDeassign*dev = new NetDeassign(lval); dev->set_line( *this ); return dev; } /* * Elaborate the delay statement (of the form # ) as a * NetPDelay object. If the expression is constant, evaluate it now * and make a constant delay. If not, then pass an elaborated * expression to the constructor of NetPDelay so that the code * generator knows to evaluate the expression at run time. */ NetProc* PDelayStatement::elaborate(Design*des, NetScope*scope) const { assert(scope); if (scope->in_func()) { cerr << get_fileline() << ": error: functions cannot have " "delay statements." << endl; des->errors += 1; return 0; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot " "have delay statements." << endl; des->errors += 1; return 0; } /* This call evaluates the delay expression to a NetEConst, if possible. This includes transforming NetECReal values to integers, and applying the proper scaling. */ NetExpr*dex = elaborate_delay_expr(delay_, des, scope); NetPDelay *obj; if (NetEConst*tmp = dynamic_cast(dex)) { if (statement_) obj = new NetPDelay(tmp->value().as_ulong64(), statement_->elaborate(des, scope)); else obj = new NetPDelay(tmp->value().as_ulong64(), 0); delete dex; } else { if (statement_) obj = new NetPDelay(dex, statement_->elaborate(des, scope)); else obj = new NetPDelay(dex, 0); } obj->set_line(*this); return obj; } /* * The disable statement is not yet supported. */ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const { assert(scope); /* If the disable scope_ is empty then this is a SystemVerilog * disable fork statement. */ if (scope_.empty()) { if (gn_system_verilog()) { NetDisable*obj = new NetDisable(0); obj->set_line(*this); return obj; } else { cerr << get_fileline() << ": error: 'disable fork' requires SystemVerilog." << endl; des->errors += 1; return 0; } } list spath = eval_scope_path(des, scope, scope_); NetScope*target = des->find_scope(scope, spath); if (target == 0) { cerr << get_fileline() << ": error: Cannot find scope " << scope_ << " in " << scope_path(scope) << endl; des->errors += 1; return 0; } switch (target->type()) { case NetScope::FUNC: cerr << get_fileline() << ": error: Cannot disable functions." << endl; des->errors += 1; return 0; case NetScope::MODULE: cerr << get_fileline() << ": error: Cannot disable modules." << endl; des->errors += 1; return 0; default: break; } NetDisable*obj = new NetDisable(target); obj->set_line(*this); return obj; } /* * The do/while loop is fairly directly represented in the netlist. */ NetProc* PDoWhile::elaborate(Design*des, NetScope*scope) const { NetExpr*ce = elab_and_eval(des, scope, cond_, -1); NetProc*sub; if (statement_) sub = statement_->elaborate(des, scope); else sub = new NetBlock(NetBlock::SEQU, 0); if (ce == 0 || sub == 0) { delete ce; delete sub; return 0; } NetDoWhile*loop = new NetDoWhile(ce, sub); loop->set_line(*this); return loop; } /* * An event statement is an event delay of some sort, attached to a * statement. Some Verilog examples are: * * @(posedge CLK) $display("clock rise"); * @event_1 $display("event triggered."); * @(data or negedge clk) $display("data or clock fall."); * * The elaborated netlist uses the NetEvent, NetEvWait and NetEvProbe * classes. The NetEvWait class represents the part of the netlist * that is executed by behavioral code. The process starts waiting on * the NetEvent when it executes the NetEvWait step. Net NetEvProbe * and NetEvTrig are structural and behavioral equivalents that * trigger the event, and awakens any processes blocking in the * associated wait. * * The basic data structure is: * * NetEvWait ---/---> NetEvent <----\---- NetEvProbe * ... | | ... * NetEvWait ---+ +---- NetEvProbe * | ... * +---- NetEvTrig * * That is, many NetEvWait statements may wait on a single NetEvent * object, and Many NetEvProbe objects may trigger the NetEvent * object. The many NetEvWait objects pointing to the NetEvent object * reflects the possibility of different places in the code blocking * on the same named event, like so: * * event foo; * [...] * always begin @foo ; @foo end * * This tends to not happen with signal edges. The multiple probes * pointing to the same event reflect the possibility of many * expressions in the same blocking statement, like so: * * wire reset, clk; * [...] * always @(reset or posedge clk) ; * * Conjunctions like this cause a NetEvent object be created to * represent the overall conjunction, and NetEvProbe objects for each * event expression. * * If the NetEvent object represents a named event from the source, * then there are NetEvTrig objects that represent the trigger * statements instead of the NetEvProbe objects representing signals. * For example: * * event foo; * always @foo ; * initial begin * [...] * -> foo; * [...] * -> foo; * [...] * end * * Each trigger statement in the source generates a separate NetEvTrig * object in the netlist. Those trigger objects are elaborated * elsewhere. * * Additional complications arise when named events show up in * conjunctions. An example of such a case is: * * event foo; * wire bar; * always @(foo or posedge bar) ; * * Since there is by definition a NetEvent object for the foo object, * this is handled by allowing the NetEvWait object to point to * multiple NetEvent objects. All the NetEvProbe based objects are * collected and pointed as the synthetic NetEvent object, and all the * named events are added into the list of NetEvent object that the * NetEvWait object can refer to. */ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope, NetProc*enet) const { assert(scope); if (scope->in_func()) { cerr << get_fileline() << ": error: functions cannot have " "event statements." << endl; des->errors += 1; return 0; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot " "have event statements." << endl; des->errors += 1; return 0; } /* Create a single NetEvent and NetEvWait. Then, create a NetEvProbe for each conjunctive event in the event list. The NetEvProbe objects all refer back to the NetEvent object. */ NetEvent*ev = new NetEvent(scope->local_symbol()); ev->set_line(*this); ev->local_flag(true); unsigned expr_count = 0; NetEvWait*wa = new NetEvWait(enet); wa->set_line(*this); /* If there are no expressions, this is a signal that it is an @* statement. Generate an expression to use. */ if (expr_.size() == 0) { assert(enet); /* For synthesis or always_comb/latch we want just the inputs, * but for the rest we want inputs and outputs that may cause * a value to change. */ extern bool synthesis; /* Synthesis flag from main.cc */ bool rem_out = false; if (synthesis || always_sens_) { rem_out = true; } // If this is an always_comb/latch then we need an implicit T0 // trigger of the event expression. if (always_sens_) wa->set_t0_trigger(); NexusSet*nset = enet->nex_input(rem_out, always_sens_); if (nset == 0) { cerr << get_fileline() << ": error: Unable to elaborate:" << endl; enet->dump(cerr, 6); des->errors += 1; return enet; } if (nset->size() == 0) { if (always_sens_) return wa; cerr << get_fileline() << ": warning: @* found no " "sensitivities so it will never trigger." << endl; /* Add the currently unreferenced event to the scope. */ scope->add_event(ev); /* Delete the current wait, create a new one with no * statement and add the event to it. This creates a * perpetual wait since nothing will ever trigger the * unreferenced event. */ delete wa; wa = new NetEvWait(0); wa->set_line(*this); wa->add_event(ev); return wa; } NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::ANYEDGE, nset->size()); for (unsigned idx = 0 ; idx < nset->size() ; idx += 1) { unsigned wid = nset->at(idx).wid; unsigned vwid = nset->at(idx).lnk.nexus()->vector_width(); // Is this a part select? if (always_sens_ && (wid != vwid)) { cerr << get_fileline() << ": sorry: constant " "selects in always_* processes are not " "currently supported (all bits will be " "included)." << endl; # if 0 unsigned base = nset->at(idx).base; cerr << get_fileline() << ": base = " << base << endl; // FIXME: make this work with selects that go before the base. assert(base < vwid); if (base + wid > vwid) wid = vwid - base; cerr << get_fileline() << ": base = " << base << ", width = " << wid << ", expr width = " << vwid << endl; nset->at(idx).lnk.dump_link(cerr, 4); cerr << endl; // FIXME: Convert the link to the appropriate NetNet netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, vwid, 0); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec); NetPartSelect*tmp = new NetPartSelect(sig, base, wid, NetPartSelect::VP); des->add_node(tmp); tmp->set_line(*this); // FIXME: create a part select to get the correct bits to connect. connect(tmp->pin(1), nset->at(idx).lnk); connect(tmp->pin(0), pr->pin(idx)); # endif connect(nset->at(idx).lnk, pr->pin(idx)); } else { connect(nset->at(idx).lnk, pr->pin(idx)); } } delete nset; des->add_node(pr); expr_count = 1; } else for (unsigned idx = 0 ; idx < expr_.size() ; idx += 1) { assert(expr_[idx]->expr()); /* If the expression is an identifier that matches a named event, then handle this case all at once and skip the rest of the expression handling. */ if (PEIdent*id = dynamic_cast(expr_[idx]->expr())) { NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; NetScope*use_scope = scope; if (id->package()) { use_scope = des->find_package(id->package()->pscope_name()); ivl_assert(*this, use_scope); } NetScope*found_in = symbol_search(this, des, use_scope, id->path(), sig, par, eve); if (found_in && eve) { wa->add_event(eve); /* You can not look for the posedge or negedge of * an event. */ if (expr_[idx]->type() != PEEvent::ANYEDGE) { cerr << get_fileline() << ": error: "; switch (expr_[idx]->type()) { case PEEvent::POSEDGE: cerr << "posedge"; break; case PEEvent::NEGEDGE: cerr << "negedge"; break; default: cerr << "unknown edge type!"; assert(0); } cerr << " can not be used with a named event (" << eve->name() << ")." << endl; des->errors += 1; } continue; } } /* So now we have a normal event expression. Elaborate the sub-expression as a net and decide how to handle the edge. */ if (scope->is_auto()) { if (! dynamic_cast(expr_[idx]->expr())) { cerr << get_fileline() << ": sorry, complex event " "expressions are not yet supported in " "automatic tasks." << endl; des->errors += 1; return 0; } } NetExpr*tmp = elab_and_eval(des, scope, expr_[idx]->expr(), -1); if (tmp == 0) { cerr << get_fileline() << ": error: " "Failed to evaluate event expression '" << *expr_[idx] << "'." << endl; des->errors += 1; continue; } NetNet*expr = tmp->synthesize(des, scope, tmp); if (expr == 0) { expr_[idx]->dump(cerr); cerr << endl; des->errors += 1; continue; } assert(expr); delete tmp; unsigned pins = (expr_[idx]->type() == PEEvent::ANYEDGE) ? expr->pin_count() : 1; NetEvProbe*pr; switch (expr_[idx]->type()) { case PEEvent::POSEDGE: pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::POSEDGE, pins); break; case PEEvent::NEGEDGE: pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::NEGEDGE, pins); break; case PEEvent::EDGE: pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::EDGE, pins); break; case PEEvent::ANYEDGE: pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::ANYEDGE, pins); break; default: pr = NULL; assert(0); } for (unsigned p = 0 ; p < pr->pin_count() ; p += 1) connect(pr->pin(p), expr->pin(p)); des->add_node(pr); expr_count += 1; } /* If there was at least one conjunction that was an expression (and not a named event) then add this event. Otherwise, we didn't use it so delete it. */ if (expr_count > 0) { scope->add_event(ev); wa->add_event(ev); /* NOTE: This event that I am adding to the wait may be a duplicate of another event somewhere else. However, I don't know that until all the modules are hooked up, so it is best to leave find_similar_event to after elaboration. */ } else { delete ev; } return wa; } /* * This is the special case of the event statement, the wait * statement. This is elaborated into a slightly more complicated * statement that uses non-wait statements: * * wait () * * becomes * * begin * while (1 !== ) * @() ; * ; * end */ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope, NetProc*enet) const { assert(scope); assert(expr_.size() == 1); if (scope->in_func()) { cerr << get_fileline() << ": error: functions cannot have " "wait statements." << endl; des->errors += 1; return 0; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot " "have wait statements." << endl; des->errors += 1; return 0; } PExpr *pe = expr_[0]->expr(); /* Elaborate wait expression. Don't eval yet, we will do that shortly, after we apply a reduction or. */ PExpr::width_mode_t mode = PExpr::SIZED; pe->test_width(des, scope, mode); NetExpr*expr = pe->elaborate_expr(des, scope, pe->expr_width(), PExpr::NO_FLAGS); if (expr == 0) { cerr << get_fileline() << ": error: Unable to elaborate" " wait condition expression." << endl; des->errors += 1; return 0; } // If the condition expression is more than 1 bits, then // generate a reduction operator to get the result down to // one bit. In other words, Turn into |; if (expr->expr_width() < 1) { cerr << get_fileline() << ": internal error: " "incomprehensible wait expression width (0)." << endl; return 0; } if (expr->expr_width() > 1) { assert(expr->expr_width() > 1); NetEUReduce*cmp = new NetEUReduce('|', expr); cmp->set_line(*pe); expr = cmp; } /* precalculate as much as possible of the wait expression. */ eval_expr(expr); /* Detect the unusual case that the wait expression is constant. Constant true is OK (it becomes transparent) but constant false is almost certainly not what is intended. */ assert(expr->expr_width() == 1); if (NetEConst*ce = dynamic_cast(expr)) { verinum val = ce->value(); assert(val.len() == 1); /* Constant true -- wait(1) reduces to . */ if (val[0] == verinum::V1) { delete expr; assert(enet); return enet; } /* Otherwise, false. wait(0) blocks permanently. */ cerr << get_fileline() << ": warning: wait expression is " << "constant false." << endl; cerr << get_fileline() << ": : The statement will " << "block permanently." << endl; /* Create an event wait and an otherwise unreferenced event variable to force a perpetual wait. */ NetEvent*wait_event = new NetEvent(scope->local_symbol()); wait_event->set_line(*this); wait_event->local_flag(true); scope->add_event(wait_event); NetEvWait*wait = new NetEvWait(0); wait->add_event(wait_event); wait->set_line(*this); delete expr; delete enet; return wait; } /* Invert the sense of the test with an exclusive NOR. In other words, if this adjusted expression returns TRUE, then wait. */ assert(expr->expr_width() == 1); expr = new NetEBComp('N', expr, new NetEConst(verinum(verinum::V1))); expr->set_line(*pe); eval_expr(expr); NetEvent*wait_event = new NetEvent(scope->local_symbol()); wait_event->set_line(*this); wait_event->local_flag(true); scope->add_event(wait_event); NetEvWait*wait = new NetEvWait(0 /* noop */); wait->add_event(wait_event); wait->set_line(*this); NexusSet*wait_set = expr->nex_input(); if (wait_set == 0) { cerr << get_fileline() << ": internal error: No NexusSet" << " from wait expression." << endl; des->errors += 1; return 0; } if (wait_set->size() == 0) { cerr << get_fileline() << ": internal error: Empty NexusSet" << " from wait expression." << endl; des->errors += 1; return 0; } NetEvProbe*wait_pr = new NetEvProbe(scope, scope->local_symbol(), wait_event, NetEvProbe::ANYEDGE, wait_set->size()); for (unsigned idx = 0; idx < wait_set->size() ; idx += 1) connect(wait_set->at(idx).lnk, wait_pr->pin(idx)); delete wait_set; des->add_node(wait_pr); NetWhile*loop = new NetWhile(expr, wait); loop->set_line(*this); /* If there is no real substatement (i.e., "wait (foo) ;") then we are done. */ if (enet == 0) return loop; /* Create a sequential block to combine the wait loop and the delayed statement. */ NetBlock*block = new NetBlock(NetBlock::SEQU, 0); block->append(loop); block->append(enet); block->set_line(*this); return block; } /* * This is a special case of the event statement, the wait fork * statement. This is elaborated into a simplified statement. * * wait fork; * * becomes * * @(0) ; */ NetProc* PEventStatement::elaborate_wait_fork(Design*des, NetScope*scope) const { assert(scope); assert(expr_.size() == 1); assert(expr_[0] == 0); assert(! statement_); if (scope->in_func()) { cerr << get_fileline() << ": error: functions cannot have " "wait fork statements." << endl; des->errors += 1; return 0; } if (scope->in_final()) { cerr << get_fileline() << ": error: final procedures cannot " "have wait fork statements." << endl; des->errors += 1; return 0; } if (gn_system_verilog()) { NetEvWait*wait = new NetEvWait(0 /* noop */); wait->add_event(0); wait->set_line(*this); return wait; } else { cerr << get_fileline() << ": error: 'wait fork' requires SystemVerilog." << endl; des->errors += 1; return 0; } } NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const { /* Check to see if this is a wait fork statement. */ if ((expr_.size() == 1) && (expr_[0] == 0)) return elaborate_wait_fork(des, scope); NetProc*enet = 0; if (statement_) { enet = statement_->elaborate(des, scope); if (enet == 0) return 0; } else { enet = new NetBlock(NetBlock::SEQU, 0); enet->set_line(*this); } if ((expr_.size() == 1) && (expr_[0]->type() == PEEvent::POSITIVE)) return elaborate_wait(des, scope, enet); return elaborate_st(des, scope, enet); } /* * Forever statements are represented directly in the netlist. It is * theoretically possible to use a while structure with a constant * expression to represent the loop, but why complicate the code * generators so? */ NetProc* PForever::elaborate(Design*des, NetScope*scope) const { NetProc*stat; if (statement_) stat = statement_->elaborate(des, scope); else stat = new NetBlock(NetBlock::SEQU, 0); if (stat == 0) return 0; NetForever*proc = new NetForever(stat); proc->set_line(*this); return proc; } /* * Force is like a procedural assignment, most notably procedural * continuous assignment: * * force = * * The can be anything that a normal behavioral assignment can * take, plus net signals. This is a little bit more lax than the * other procedural assignments. */ NetForce* PForce::elaborate(Design*des, NetScope*scope) const { NetForce*dev = 0; assert(scope); if (scope->is_auto() && lval_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be assigned values using procedural " "force statements." << endl; des->errors += 1; return 0; } if (scope->is_auto() && expr_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be referenced in procedural force " "statements." << endl; des->errors += 1; return 0; } NetAssign_*lval = lval_->elaborate_lval(des, scope, false, true); if (lval == 0) return 0; unsigned lwid = count_lval_width(lval); ivl_variable_type_t ltype = lval->expr_type(); // Like a variety of other assigns, we need to figure out a // better way to get a reasonable lv_net_type value, and that // probably will involve NetAssign_ having a method for // synthesizing one as needed. NetExpr*rexp = elaborate_rval_expr(des, scope, lval->net_type(), ltype, lwid, expr_); if (rexp == 0) return 0; dev = new NetForce(lval, rexp); if (debug_elaborate) { cerr << get_fileline() << ": debug: Elaborate force," << " lval width=" << lval->lwidth() << " rval width=" << rexp->expr_width() << " rval=" << *rexp << endl; } dev->set_line(*this); return dev; } static void find_property_in_class(const LineInfo&loc, const NetScope*scope, perm_string name, const netclass_t*&found_in, int&property) { found_in = find_class_containing_scope(loc, scope); property = -1; if (found_in==0) return; property = found_in->property_idx_from_name(name); if (property < 0) { found_in = 0; return; } } /* * The foreach statement can be written as a for statement like so: * * for ( = $low() ; <= $high() ; += 1) * * * The variable is already known to be in the containing named * block scope, which was created by the parser. */ NetProc* PForeach::elaborate(Design*des, NetScope*scope) const { // Locate the signal for the array variable pform_name_t array_name; array_name.push_back(name_component_t(array_var_)); NetNet*array_sig = des->find_signal(scope, array_name); // And if necessary, look for the class property that is // referenced. const netclass_t*class_scope = 0; int class_property = -1; if (array_sig == 0) find_property_in_class(*this, scope, array_var_, class_scope, class_property); if (debug_elaborate && array_sig) { cerr << get_fileline() << ": PForeach::elaborate: " << "Found array_sig in " << scope_path(array_sig->scope()) << "." << endl; } if (debug_elaborate && class_scope) { cerr << get_fileline() << ": PForeach::elaborate: " << "Found array_sig property (" << class_property << ") in class " << class_scope->get_name() << " as " << *class_scope->get_prop_type(class_property) << "." << endl; } if (class_scope!=0 && class_property >= 0) { ivl_type_t ptype = class_scope->get_prop_type(class_property); const netsarray_t*atype = dynamic_cast (ptype); if (atype == 0) { cerr << get_fileline() << ": error: " << "I can't handle the type of " << array_var_ << " as a foreach loop." << endl; des->errors += 1; return 0; } const std::vector&dims = atype->static_dimensions(); if (dims.size() < index_vars_.size()) { cerr << get_fileline() << ": error: " << "class " << class_scope->get_name() << " property " << array_var_ << " has too few dimensions for foreach dimension list." << endl; des->errors += 1; return 0; } return elaborate_static_array_(des, scope, dims); } if (array_sig == 0) { cerr << get_fileline() << ": error:" << " Unable to find foreach array " << array_name << " in scope " << scope_path(scope) << "." << endl; des->errors += 1; return 0; } ivl_assert(*this, array_sig); if (debug_elaborate) { cerr << get_fileline() << ": PForeach::elaborate: " << "Scan array " << array_sig->name() << " of " << array_sig->data_type() << " with " << array_sig->unpacked_dimensions() << " unpacked" << " and " << array_sig->packed_dimensions() << " packed dimensions." << endl; } std::vectordims = array_sig->unpacked_dims(); if (array_sig->packed_dimensions() > 0) { dims.insert(dims.end(), array_sig->packed_dims().begin(), array_sig->packed_dims().end()); } // Classic arrays are processed this way. if (array_sig->data_type()==IVL_VT_BOOL) return elaborate_static_array_(des, scope, dims); if (array_sig->data_type()==IVL_VT_LOGIC) return elaborate_static_array_(des, scope, dims); if (array_sig->unpacked_dimensions() >= index_vars_.size()) return elaborate_static_array_(des, scope, dims); // At this point, we know that the array is dynamic so we // handle that slightly differently, using run-time tests. if (index_vars_.size() != 1) { cerr << get_fileline() << ": sorry: " << "Multi-index foreach loops not supported." << endl; des->errors += 1; } // Get the signal for the index variable. pform_name_t index_name; index_name.push_back(name_component_t(index_vars_[0])); NetNet*idx_sig = des->find_signal(scope, index_name); ivl_assert(*this, idx_sig); NetESignal*array_exp = new NetESignal(array_sig); array_exp->set_line(*this); NetESignal*idx_exp = new NetESignal(idx_sig); idx_exp->set_line(*this); // Make an initialization expression for the index. NetESFunc*init_expr = new NetESFunc("$low", &netvector_t::atom2s32, 1); init_expr->set_line(*this); init_expr->parm(0, array_exp); // Make a condition expression: idx <= $high(array) NetESFunc*high_exp = new NetESFunc("$high", &netvector_t::atom2s32, 1); high_exp->set_line(*this); high_exp->parm(0, array_exp); NetEBComp*cond_expr = new NetEBComp('L', idx_exp, high_exp); cond_expr->set_line(*this); /* Elaborate the statement that is contained in the foreach loop. */ NetProc*sub; if (statement_) sub = statement_->elaborate(des, scope); else sub = new NetBlock(NetBlock::SEQU, 0); /* Make a step statement: idx += 1 */ NetAssign_*idx_lv = new NetAssign_(idx_sig); NetEConst*step_val = make_const_val(1); NetAssign*step = new NetAssign(idx_lv, '+', step_val); step->set_line(*this); NetForLoop*stmt = new NetForLoop(idx_sig, init_expr, cond_expr, sub, step); stmt->set_line(*this); stmt->wrap_up(); return stmt; } /* * This is a variant of the PForeach::elaborate() method that handles * the case that the array has static dimensions. We can use constants * and possibly do some optimizations. */ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope, const vector&dims) const { if (debug_elaborate) { cerr << get_fileline() << ": PForeach::elaborate_static_array_: " << "Handle as array with static dimensions." << endl; } NetProc*sub; if (statement_) sub = statement_->elaborate(des, scope); else sub = new NetBlock(NetBlock::SEQU, 0); NetForLoop*stmt = 0; if (index_vars_.size() > dims.size()) { delete sub; cerr << get_fileline() << ": error: Number of foreach loop variables" << "(" << index_vars_.size() << ") must not exceed number of " << "array dimensions (" << dims.size() << ")." << endl; des->errors++; return nullptr; } for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) { const netrange_t&idx_range = dims[idx_idx]; // It is possible to skip dimensions by not providing a identifier // name for it. E.g. `int x[1][2][3]; foreach(x[a,,b]) ...` if (index_vars_[idx_idx].nil()) continue; // Get the $high and $low constant values for this slice // of the array. NetEConst*hig_expr = make_const_val_s(idx_range.get_msb()); NetEConst*low_expr = make_const_val_s(idx_range.get_lsb()); if (idx_range.get_msb() < idx_range.get_lsb()) { NetEConst*tmp = hig_expr; hig_expr = low_expr; low_expr = tmp; } hig_expr->set_line(*this); low_expr->set_line(*this); pform_name_t idx_name; idx_name.push_back(name_component_t(index_vars_[idx_idx])); NetNet*idx_sig = des->find_signal(scope, idx_name); ivl_assert(*this, idx_sig); // Make the condition expression <= $high(slice) NetESignal*idx_expr = new NetESignal(idx_sig); idx_expr->set_line(*this); NetEBComp*cond_expr = new NetEBComp('L', idx_expr, hig_expr); cond_expr->set_line(*this); // Make the step statement: += 1 NetAssign_*idx_lv = new NetAssign_(idx_sig); NetEConst*step_val = make_const_val_s(1); NetAssign*step = new NetAssign(idx_lv, '+', step_val); step->set_line(*this); stmt = new NetForLoop(idx_sig, low_expr, cond_expr, sub, step); stmt->set_line(*this); stmt->wrap_up(); sub = stmt; } // If there are no loop variables elide the whole block if (!stmt) { delete sub; return new NetBlock(NetBlock::SEQU, 0); } return stmt; } /* * Elaborate the PForStatement as discovered by the parser into a * NetForLoop object. The parser detects the: * * - index variable (name1_) (optional) * - initial value (expr1_) (only if name1_ is present) * - condition expression (cond_) * - step statement (step_) (optional) * - sub-statement (statement_) * * The rules that lead to the PForStatment look like: * * for ( = ; ; ) * for ( ; ) */ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const { NetExpr*initial_expr; NetNet*sig; bool error_flag = false; assert(scope); if (!name1_) { // If there is no initial assignment expression, then mark that // fact with null pointers. ivl_assert(*this, !expr1_); sig = nullptr; initial_expr = nullptr; } else if (const PEIdent*id1 = dynamic_cast(name1_)) { // If there is an initialization assignment, make the expression, // and later the initial assignment to the condition variable. The // statement in the for loop is very specifically an assignment. sig = des->find_signal(scope, id1->path()); if (sig == 0) { cerr << id1->get_fileline() << ": register ``" << id1->path() << "'' unknown in " << scope_path(scope) << "." << endl; des->errors += 1; return 0; } // Make the r-value of the initial assignment, and size it // properly. Then use it to build the assignment statement. initial_expr = elaborate_rval_expr(des, scope, sig->net_type(), expr1_); if (!initial_expr) error_flag = true; if (debug_elaborate && initial_expr) { cerr << get_fileline() << ": debug: FOR initial assign: " << sig->name() << " = " << *initial_expr << endl; } } else { cerr << get_fileline() << ": internal error: " << "Index name " << *name1_ << " is not a PEIdent." << endl; des->errors += 1; return 0; } // Elaborate the statement that is contained in the for // loop. If there is an error, this will return 0 and I should // skip the append. No need to worry, the error has been // reported so it's OK that the netlist is bogus. NetProc*sub; if (statement_) { sub = statement_->elaborate(des, scope); if (sub == 0) error_flag = true; } else { sub = new NetBlock(NetBlock::SEQU, 0); } // Now elaborate the for_step statement. I really should do // some error checking here to make sure the step statement // really does step the variable. NetProc*step = nullptr; if (step_) { step = step_->elaborate(des, scope); if (!step) error_flag = true; } // Elaborate the condition expression. Try to evaluate it too, // in case it is a constant. This is an interesting case // worthy of a warning. NetExpr*ce = elab_and_eval(des, scope, cond_, -1); if (!ce) error_flag = true; if (dynamic_cast(ce)) { cerr << get_fileline() << ": warning: condition expression " "of for-loop is constant." << endl; } // Error recovery - if we failed to elaborate any of the loop // expressions, give up now. Error counts where handled elsewhere. if (error_flag) { if (initial_expr) delete initial_expr; if (ce) delete ce; if (step) delete step; if (sub) delete sub; return 0; } // All done, build up the loop. Note that sig and initial_expr may be // nil. But if one is nil, then so is the other. The follow-on code // can handle that case, but let's make sure with an assert that we // have a consistent input. ivl_assert(*this, sig || !initial_expr); NetForLoop*loop = new NetForLoop(sig, initial_expr, ce, sub, step); loop->set_line(*this); loop->wrap_up(); return loop; } /* * (See the PTask::elaborate methods for basic common stuff.) * * The return value of a function is represented as a reg variable * within the scope of the function that has the name of the * function. So for example with the function: * * function [7:0] incr; * input [7:0] in1; * incr = in1 + 1; * endfunction * * The scope of the function is .incr and there is a reg * variable .incr.incr. The elaborate_1 method is called with * the scope of the function, so the return reg is easily located. * * The function parameters are all inputs, except for the synthetic * output parameter that is the return value. The return value goes * into port 0, and the parameters are all the remaining ports. */ void PFunction::elaborate(Design*des, NetScope*scope) const { if (scope->elab_stage() > 2) return; scope->set_elab_stage(3); NetFuncDef*def = scope->func_def(); if (def == 0) { cerr << get_fileline() << ": internal error: " << "No function definition for function " << scope_path(scope) << endl; des->errors += 1; return; } assert(def); NetProc*st; if (statement_ == 0) { st = new NetBlock(NetBlock::SEQU, 0); } else { st = statement_->elaborate(des, scope); if (st == 0) { cerr << statement_->get_fileline() << ": error: Unable to elaborate " "statement in function " << scope->basename() << "." << endl; scope->is_const_func(true); // error recovery des->errors += 1; return; } } // Handle any variable initialization statements in this scope. // For automatic functions, these statements need to be executed // each time the function is called, so insert them at the start // of the elaborated definition. For static functions, put them // in a separate process that will be executed before the start // of simulation. if (is_auto_) { // Get the NetBlock of the statement. If it is not a // NetBlock then create one to wrap the initialization // statements and the original statement. NetBlock*blk = dynamic_cast (st); if ((blk == 0) && (var_inits.size() > 0)) { blk = new NetBlock(NetBlock::SEQU, scope); blk->set_line(*this); blk->append(st); st = blk; } for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) { NetProc*tmp = var_inits[idx-1]->elaborate(des, scope); if (tmp) blk->prepend(tmp); } } else { elaborate_var_inits_(des, scope); } def->set_proc(st); } NetProc* PRelease::elaborate(Design*des, NetScope*scope) const { assert(scope); if (scope->is_auto() && lval_->has_aa_term(des, scope)) { cerr << get_fileline() << ": error: automatically allocated " "variables may not be assigned values using procedural " "force statements." << endl; des->errors += 1; return 0; } NetAssign_*lval = lval_->elaborate_lval(des, scope, false, true); if (lval == 0) return 0; NetRelease*dev = new NetRelease(lval); dev->set_line( *this ); return dev; } NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const { assert(scope); NetExpr*expr = elab_and_eval(des, scope, expr_, -1); if (expr == 0) { cerr << get_fileline() << ": Unable to elaborate" " repeat expression." << endl; des->errors += 1; return 0; } // If the expression is real, convert to an integer. 64 bits // should be more enough for any real use case. if (expr->expr_type() == IVL_VT_REAL) expr = cast_to_int4(expr, 64); NetProc*stat; if (statement_) stat = statement_->elaborate(des, scope); else stat = new NetBlock(NetBlock::SEQU, 0); if (stat == 0) return 0; // If the expression is a constant, handle certain special // iteration counts. if (NetEConst*ce = dynamic_cast(expr)) { long val = ce->value().as_long(); if (val <= 0) { delete expr; delete stat; return new NetBlock(NetBlock::SEQU, 0); } else if (val == 1) { delete expr; return stat; } } NetRepeat*proc = new NetRepeat(expr, stat); proc->set_line( *this ); return proc; } NetProc* PReturn::elaborate(Design*des, NetScope*scope) const { NetScope*target = scope; for (;;) { if (target == 0) { cerr << get_fileline() << ": error: " << "Return statement is not in a function." << endl; des->errors += 1; return 0; } if (target->type() == NetScope::FUNC) break; if (target->type() == NetScope::TASK) { cerr << get_fileline() << ": error: " << "Cannot \"return\" from tasks." << endl; des->errors += 1; return 0; } if (target->type()==NetScope::BEGIN_END) { target = target->parent(); continue; } cerr << get_fileline() << ": error: " << "Cannot \"return\" from this scope: " << scope_path(target) << endl; des->errors += 1; return 0; } ivl_assert(*this, target->type() == NetScope::FUNC); if (target->func_def()->is_void()) { if (expr_) { cerr << get_fileline() << ": error: " << "A value can't be returned from a void function." << endl; des->errors += 1; return 0; } NetDisable*disa = new NetDisable(target, true); disa->set_line( *this ); return disa; } if (expr_ == 0) { cerr << get_fileline() << ": error: " << "Return from " << scope_path(target) << " requires a return value expression." << endl; des->errors += 1; return 0; } NetNet*res = target->find_signal(target->basename()); ivl_assert(*this, res); NetAssign_*lv = new NetAssign_(res); NetExpr*val = elaborate_rval_expr(des, scope, res->net_type(), expr_); NetBlock*proc = new NetBlock(NetBlock::SEQU, 0); proc->set_line( *this ); NetAssign*assn = new NetAssign(lv, val); assn->set_line( *this ); proc->append(assn); NetDisable*disa = new NetDisable(target, true); disa->set_line( *this ); proc->append( disa ); return proc; } /* * A task definition is elaborated by elaborating the statement that * it contains, and connecting its ports to NetNet objects. The * netlist doesn't really need the array of parameters once elaboration * is complete, but this is the best place to store them. * * The first elaboration pass finds the reg objects that match the * port names, and creates the NetTaskDef object. The port names are * in the form task.port. * * task foo; * output blah; * begin end * endtask * * So in the foo example, the PWire objects that represent the ports * of the task will include a foo.blah for the blah port. This port is * bound to a NetNet object by looking up the name. All of this is * handled by the PTask::elaborate_sig method and the results stashed * in the created NetTaskDef attached to the scope. * * Elaboration pass 2 for the task definition causes the statement of * the task to be elaborated and attached to the NetTaskDef object * created in pass 1. * * NOTE: I am not sure why I bothered to prepend the task name to the * port name when making the port list. It is not really useful, but * that is what I did in pform_make_task_ports, so there it is. */ void PTask::elaborate(Design*des, NetScope*task) const { NetTaskDef*def = task->task_def(); assert(def); NetProc*st; if (statement_ == 0) { st = new NetBlock(NetBlock::SEQU, 0); } else { st = statement_->elaborate(des, task); if (st == 0) { cerr << statement_->get_fileline() << ": Unable to elaborate " "statement in task " << scope_path(task) << " at " << get_fileline() << "." << endl; return; } } // Handle any variable initialization statements in this scope. // For automatic tasks , these statements need to be executed // each time the task is called, so insert them at the start // of the elaborated definition. For static tasks, put them // in a separate process that will be executed before the start // of simulation. if (is_auto_) { // Get the NetBlock of the statement. If it is not a // NetBlock then create one to wrap the initialization // statements and the original statement. NetBlock*blk = dynamic_cast (st); if ((blk == 0) && (var_inits.size() > 0)) { blk = new NetBlock(NetBlock::SEQU, task); blk->set_line(*this); blk->append(st); st = blk; } for (unsigned idx = var_inits.size(); idx > 0; idx -= 1) { NetProc*tmp = var_inits[idx-1]->elaborate(des, task); if (tmp) blk->prepend(tmp); } } else { elaborate_var_inits_(des, task); } def->set_proc(st); } NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const { assert(scope); NetScope*use_scope = scope; if (package_) { use_scope = des->find_package(package_->pscope_name()); ivl_assert(*this, use_scope); } NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; NetScope*found_in = symbol_search(this, des, use_scope, event_, sig, par, eve); if (found_in == 0) { cerr << get_fileline() << ": error: event <" << event_ << ">" << " not found." << endl; des->errors += 1; return 0; } if (eve == 0) { cerr << get_fileline() << ": error: <" << event_ << ">" << " is not a named event." << endl; des->errors += 1; return 0; } NetEvTrig*trig = new NetEvTrig(eve); trig->set_line(*this); return trig; } NetProc* PNBTrigger::elaborate(Design*des, NetScope*scope) const { assert(scope); NetNet* sig = 0; const NetExpr*par = 0; NetEvent* eve = 0; NetScope*found_in = symbol_search(this, des, scope, event_, sig, par, eve); if (found_in == 0) { cerr << get_fileline() << ": error: event <" << event_ << ">" << " not found." << endl; des->errors += 1; return 0; } if (eve == 0) { cerr << get_fileline() << ": error: <" << event_ << ">" << " is not a named event." << endl; des->errors += 1; return 0; } NetExpr*dly = 0; if (dly_) dly = elab_and_eval(des, scope, dly_, -1); NetEvNBTrig*trig = new NetEvNBTrig(eve, dly); trig->set_line(*this); return trig; } /* * The while loop is fairly directly represented in the netlist. */ NetProc* PWhile::elaborate(Design*des, NetScope*scope) const { NetExpr*ce = elab_and_eval(des, scope, cond_, -1); NetProc*sub; if (statement_) sub = statement_->elaborate(des, scope); else sub = new NetBlock(NetBlock::SEQU, 0); if (ce == 0 || sub == 0) { delete ce; delete sub; return 0; } NetWhile*loop = new NetWhile(ce, sub); loop->set_line(*this); return loop; } bool PProcess::elaborate(Design*des, NetScope*scope) const { scope->in_final(type() == IVL_PR_FINAL); NetProc*cur = statement_->elaborate(des, scope); scope->in_final(false); if (cur == 0) { return false; } NetProcTop*top=new NetProcTop(scope, type(), cur); ivl_assert(*this, top); // Evaluate the attributes for this process, if there // are any. These attributes are to be attached to the // NetProcTop object. struct attrib_list_t*attrib_list; unsigned attrib_list_n = 0; attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope); for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) top->attribute(attrib_list[adx].key, attrib_list[adx].val); delete[]attrib_list; top->set_line(*this); des->add_process(top); /* Detect the special case that this is a combinational always block. We want to attach an _ivl_schedule_push attribute to this process so that it starts up and gets into its wait statement before non-combinational code is executed. */ do { if ((top->type() != IVL_PR_ALWAYS) && (top->type() != IVL_PR_ALWAYS_COMB) && (top->type() != IVL_PR_ALWAYS_FF) && (top->type() != IVL_PR_ALWAYS_LATCH)) break; NetEvWait*st = dynamic_cast(top->statement()); if (st == 0) break; if (st->nevents() != 1) break; NetEvent*ev = st->event(0); if (ev->nprobe() == 0) break; bool anyedge_test = true; for (unsigned idx = 0 ; anyedge_test && (idxnprobe()) ; idx += 1) { const NetEvProbe*pr = ev->probe(idx); if (pr->edge() != NetEvProbe::ANYEDGE) anyedge_test = false; } if (! anyedge_test) break; top->attribute(perm_string::literal("_ivl_schedule_push"), verinum(1)); } while (0); return true; } void PSpecPath::elaborate(Design*des, NetScope*scope) const { uint64_t delay_value[12]; unsigned ndelays = 0; /* Do not elaborate specify delay paths if this feature is turned off. */ if (!gn_specify_blocks_flag) return; ivl_assert(*this, conditional || (condition==0)); ndelays = delays.size(); if (ndelays > 12) ndelays = 12; check_for_inconsistent_delays(scope); /* Elaborate the delay values themselves. Remember to scale them for the timescale/precision of the scope. */ for (unsigned idx = 0 ; idx < ndelays ; idx += 1) { PExpr*exp = delays[idx]; NetExpr*cur = elab_and_eval(des, scope, exp, -1); if (NetEConst*con = dynamic_cast (cur)) { verinum fn = con->value(); delay_value[idx] = des->scale_to_precision(fn.as_ulong64(), scope); } else if (NetECReal*rcon = dynamic_cast(cur)) { delay_value[idx] = get_scaled_time_from_real(des, scope, rcon); } else { cerr << get_fileline() << ": error: Path delay value " << "must be constant (" << *cur << ")." << endl; delay_value[idx] = 0; des->errors += 1; } delete cur; } switch (delays.size()) { case 1: case 2: case 3: case 6: case 12: break; default: cerr << get_fileline() << ": error: Incorrect delay configuration." << " Given " << delays.size() << " delay expressions." << endl; ndelays = 1; des->errors += 1; break; } NetNet*condit_sig = 0; if (conditional && condition) { NetExpr*tmp = elab_and_eval(des, scope, condition, -1); ivl_assert(*condition, tmp); // FIXME: Look for constant expressions here? // Get a net form. condit_sig = tmp->synthesize(des, scope, tmp); ivl_assert(*condition, condit_sig); } /* A parallel connection does not support more than a one to one connection (source/destination). */ if (! full_flag_ && ((src.size() != 1) || (dst.size() != 1))) { /* To be compatible with NC-Verilog we allow a parallel connection * with multiple sources/destinations if all the paths are only a * single bit wide (a scalar or a one bit vector). */ bool all_single = true; typedef std::vector::const_iterator str_vec_iter; for (str_vec_iter cur = src.begin(); ( cur != src.end() && all_single); ++ cur) { NetNet *psig = scope->find_signal(*cur); /* We will report a missing signal as invalid later. For * now assume it's a single bit. */ if (psig == 0) continue; if (psig->vector_width() != 1) all_single = false; } for (str_vec_iter cur = dst.begin(); ( cur != dst.end() && all_single); ++ cur) { NetNet *psig = scope->find_signal(*cur); /* The same as above for source paths. */ if (psig == 0) continue; if (psig->vector_width() != 1) all_single = false; } if (! all_single) { cerr << get_fileline() << ": error: Parallel connections " "only support one source/destination path found (" << src.size() << "/" << dst.size() << ")." << endl; des->errors += 1; } } /* Create all the various paths from the path specifier. */ typedef std::vector::const_iterator str_vector_iter; for (str_vector_iter cur = dst.begin() ; cur != dst.end() ; ++ cur ) { if (debug_elaborate) { cerr << get_fileline() << ": debug: Path to " << (*cur); if (condit_sig) cerr << " if " << condit_sig->name(); else if (conditional) cerr << " ifnone"; cerr << " from "; } NetNet*dst_sig = scope->find_signal(*cur); if (dst_sig == 0) { cerr << get_fileline() << ": error: No wire '" << *cur << "' in this module." << endl; des->errors += 1; continue; } unsigned long dst_wid = dst_sig->vector_width(); if (dst_sig->port_type() != NetNet::POUTPUT && dst_sig->port_type() != NetNet::PINOUT) { cerr << get_fileline() << ": error: Path destination " << *cur << " must be an output or inout port." << endl; des->errors += 1; } NetDelaySrc*path = new NetDelaySrc(scope, scope->local_symbol(), src.size(), condit_sig, conditional, !full_flag_); path->set_line(*this); // The presence of the data_source_expression indicates // that this is an edge sensitive path. If so, then set // the edges. Note that edge==0 is BOTH edges. if (data_source_expression) { if (edge >= 0) path->set_posedge(); if (edge <= 0) path->set_negedge(); } switch (ndelays) { case 12: path->set_delays(delay_value[0], delay_value[1], delay_value[2], delay_value[3], delay_value[4], delay_value[5], delay_value[6], delay_value[7], delay_value[8], delay_value[9], delay_value[10], delay_value[11]); break; case 6: path->set_delays(delay_value[0], delay_value[1], delay_value[2], delay_value[3], delay_value[4], delay_value[5]); break; case 3: path->set_delays(delay_value[0], delay_value[1], delay_value[2]); break; case 2: path->set_delays(delay_value[0], delay_value[1]); break; case 1: path->set_delays(delay_value[0]); break; } unsigned idx = 0; for (str_vector_iter cur_src = src.begin() ; cur_src != src.end() ; ++ cur_src ) { NetNet*src_sig = scope->find_signal(*cur_src); if (src_sig == 0) { cerr << get_fileline() << ": error: No wire '" << *cur_src << "' in this module." << endl; des->errors += 1; continue; } if (debug_elaborate) { if (cur_src != src.begin()) cerr << " and "; cerr << src_sig->name(); } if ( (src_sig->port_type() != NetNet::PINPUT) && (src_sig->port_type() != NetNet::PINOUT) ) { cerr << get_fileline() << ": error: Path source " << *cur_src << " must be an input or inout port." << endl; des->errors += 1; } // For a parallel connection the source and destination // must be the same width. if (! full_flag_) { unsigned long src_wid = src_sig->vector_width(); if (src_wid != dst_wid) { cerr << get_fileline() << ": error: For a " "parallel connection the " "source/destination width must match " "found (" << src_wid << "/" << dst_wid << ")." << endl; des->errors += 1; } } connect(src_sig->pin(0), path->pin(idx)); idx += 1; } if (debug_elaborate) { cerr << endl; } if (condit_sig) connect(condit_sig->pin(0), path->pin(idx)); dst_sig->add_delay_path(path); } } static void elaborate_functions(Design*des, NetScope*scope, const map&funcs) { typedef map::const_iterator mfunc_it_t; for (mfunc_it_t cur = funcs.begin() ; cur != funcs.end() ; ++ cur ) { hname_t use_name ( (*cur).first ); NetScope*fscope = scope->child(use_name); assert(fscope); (*cur).second->elaborate(des, fscope); } } static void elaborate_tasks(Design*des, NetScope*scope, const map&tasks) { typedef map::const_iterator mtask_it_t; for (mtask_it_t cur = tasks.begin() ; cur != tasks.end() ; ++ cur ) { hname_t use_name ( (*cur).first ); NetScope*tscope = scope->child(use_name); assert(tscope); (*cur).second->elaborate(des, tscope); } } static void elaborate_classes(Design*des, NetScope*scope, const map&classes) { for (map::const_iterator cur = classes.begin() ; cur != classes.end() ; ++ cur) { netclass_t*use_class = scope->find_class(des, cur->second->pscope_name()); use_class->elaborate(des, cur->second); if (use_class->test_for_missing_initializers()) { cerr << cur->second->get_fileline() << ": error: " << "Const properties of class " << use_class->get_name() << " are missing initialization." << endl; des->errors += 1; } } } bool PPackage::elaborate(Design*des, NetScope*scope) const { bool result_flag = true; // Elaborate function methods, and... elaborate_functions(des, scope, funcs); // Elaborate task methods. elaborate_tasks(des, scope, tasks); // Elaborate class definitions. elaborate_classes(des, scope, classes); // Elaborate the variable initialization statements, making a // single initial process out of them. result_flag &= elaborate_var_inits_(des, scope); return result_flag; } /* * When a module is instantiated, it creates the scope then uses this * method to elaborate the contents of the module. */ bool Module::elaborate(Design*des, NetScope*scope) const { bool result_flag = true; // Elaborate within the generate blocks. typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur)->elaborate(des, scope); } // Elaborate functions. elaborate_functions(des, scope, funcs); // Elaborate the task definitions. This is done before the // behaviors so that task calls may reference these, and after // the signals so that the tasks can reference them. elaborate_tasks(des, scope, tasks); // Elaborate class definitions. elaborate_classes(des, scope, classes); // Get all the gates of the module and elaborate them by // connecting them to the signals. The gate may be simple or // complex. const list&gl = get_gates(); for (list::const_iterator gt = gl.begin() ; gt != gl.end() ; ++ gt ) { (*gt)->elaborate(des, scope); } // Elaborate the variable initialization statements, making a // single initial process out of them. result_flag &= elaborate_var_inits_(des, scope); // Elaborate the behaviors, making processes out of them. This // involves scanning the PProcess* list, creating a NetProcTop // for each process. result_flag &= elaborate_behaviors_(des, scope); // Elaborate the specify paths of the module. for (list::const_iterator sp = specify_paths.begin() ; sp != specify_paths.end() ; ++ sp ) { (*sp)->elaborate(des, scope); } // Elaborate the elaboration tasks. for (list::const_iterator et = elab_tasks.begin() ; et != elab_tasks.end() ; ++ et ) { result_flag &= (*et)->elaborate_elab(des, scope); } return result_flag; } /* * Elaborating a netclass_t means elaborating the PFunction and PTask * objects that it contains. The scopes and signals have already been * elaborated in the class of the netclass_t scope, so we can get the * child scope for each definition and use that for the context of the * function. */ void netclass_t::elaborate(Design*des, PClass*pclass) { if (! pclass->type->initialize_static.empty()) { std::vector&stmt_list = pclass->type->initialize_static; NetBlock*stmt = new NetBlock(NetBlock::SEQU, 0); for (size_t idx = 0 ; idx < stmt_list.size() ; idx += 1) { NetProc*tmp = stmt_list[idx]->elaborate(des, class_scope_); if (tmp == 0) continue; stmt->append(tmp); } NetProcTop*top = new NetProcTop(class_scope_, IVL_PR_INITIAL, stmt); top->set_line(*pclass); des->add_process(top); } for (map::iterator cur = pclass->funcs.begin() ; cur != pclass->funcs.end() ; ++ cur) { if (debug_elaborate) { cerr << cur->second->get_fileline() << ": netclass_t::elaborate: " << "Elaborate class " << scope_path(class_scope_) << " function method " << cur->first << endl; } NetScope*scope = class_scope_->child( hname_t(cur->first) ); ivl_assert(*cur->second, scope); cur->second->elaborate(des, scope); } for (map::iterator cur = pclass->tasks.begin() ; cur != pclass->tasks.end() ; ++ cur) { if (debug_elaborate) { cerr << cur->second->get_fileline() << ": netclass_t::elaborate: " << "Elaborate class " << scope_path(class_scope_) << " task method " << cur->first << endl; } NetScope*scope = class_scope_->child( hname_t(cur->first) ); ivl_assert(*cur->second, scope); cur->second->elaborate(des, scope); } } bool PGenerate::elaborate(Design*des, NetScope*container) const { if (directly_nested) return elaborate_direct_(des, container); bool flag = true; if (debug_elaborate) { cerr << get_fileline() << ": PGenerate::elaborate: " "generate " << scheme_type << " elaborating in scope " << scope_path(container) << "." << endl; cerr << get_fileline() << ": PGenerate::elaborate: " "generate scope_name=" << scope_name << ", id_number=" << id_number << endl; } // Handle the special case that this is a CASE scheme. In this // case the PGenerate itself does not have the generated // item. Look instead for the case ITEM that has a scope // generated for it. if (scheme_type == PGenerate::GS_CASE) { typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { PGenerate*item = *cur; if (item->directly_nested || !item->scope_list_.empty()) { flag &= item->elaborate(des, container); } } return flag; } typedef list::const_iterator scope_list_it_t; for (scope_list_it_t cur = scope_list_.begin() ; cur != scope_list_.end() ; ++ cur ) { NetScope*scope = *cur; // Check that this scope is one that is contained in the // container that the caller passed in. if (scope->parent() != container) continue; // If this was an unnamed generate block, replace its // temporary name with a name generated using the naming // scheme defined in the Verilog-2005 standard. const char*name = scope_name.str(); if (name[0] == '$') { if (!scope->auto_name("genblk", '0', name + 4)) { cerr << get_fileline() << ": warning: Couldn't build" << " unique name for unnamed generate block" << " - using internal name " << name << endl; } } if (debug_elaborate) cerr << get_fileline() << ": debug: Elaborate in " << "scope " << scope_path(scope) << endl; flag = elaborate_(des, scope) & flag; } return flag; } bool PGenerate::elaborate_direct_(Design*des, NetScope*container) const { bool flag = true; if (debug_elaborate) { cerr << get_fileline() << ": debug: " << "Direct nesting elaborate in scope " << scope_path(container) << ", scheme_type=" << scheme_type << endl; } // Elaborate for a direct nested generated scheme knows // that there are only sub_schemes to be elaborated. There // should be exactly 1 active generate scheme, search for it // using this loop. typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { PGenerate*item = *cur; if (debug_elaborate) { cerr << get_fileline() << ": PGenerate::elaborate_direct_: " << "item->scope_name=" << item->scope_name << ", item->scheme_type=" << item->scheme_type << ", item->directly_nested=" << item->directly_nested << ", item->scope_list_.size()=" << item->scope_list_.size() << "." << endl; } // Special case: If this is a case generate scheme, then // the PGenerate object (item) does not actually // contain anything. Instead scan the case items, which // are listed as sub-schemes of the item. if (item->scheme_type == PGenerate::GS_CASE) { for (generate_it_t icur = item->generate_schemes.begin() ; icur != item->generate_schemes.end() ; ++ icur ) { PGenerate*case_item = *icur; if (case_item->directly_nested || !case_item->scope_list_.empty()) { flag &= case_item->elaborate(des, container); } } } else { if (item->directly_nested || !item->scope_list_.empty()) { // Found the item, and it is direct nested. flag &= item->elaborate(des, container); } } } return flag; } bool PGenerate::elaborate_(Design*des, NetScope*scope) const { elaborate_functions(des, scope, funcs); elaborate_tasks(des, scope, tasks); typedef list::const_iterator gates_it_t; for (gates_it_t cur = gates.begin() ; cur != gates.end() ; ++ cur ) (*cur)->elaborate(des, scope); elaborate_var_inits_(des, scope); typedef list::const_iterator proc_it_t; for (proc_it_t cur = behaviors.begin(); cur != behaviors.end(); ++ cur ) (*cur)->elaborate(des, scope); typedef list::const_iterator generate_it_t; for (generate_it_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur)->elaborate(des, scope); } return true; } bool PScope::elaborate_behaviors_(Design*des, NetScope*scope) const { bool result_flag = true; // Elaborate the behaviors, making processes out of them. This // involves scanning the PProcess* list, creating a NetProcTop // for each process. for (list::const_iterator st = behaviors.begin() ; st != behaviors.end() ; ++ st ) { result_flag &= (*st)->elaborate(des, scope); } for (list::const_iterator st = analog_behaviors.begin() ; st != analog_behaviors.end() ; ++ st ) { result_flag &= (*st)->elaborate(des, scope); } return result_flag; } bool LexicalScope::elaborate_var_inits_(Design*des, NetScope*scope) const { if (var_inits.size() == 0) return true; NetProc*proc = 0; if (var_inits.size() == 1) { proc = var_inits[0]->elaborate(des, scope); } else { NetBlock*blk = new NetBlock(NetBlock::SEQU, 0); bool flag = true; for (unsigned idx = 0; idx < var_inits.size(); idx += 1) { NetProc*tmp = var_inits[idx]->elaborate(des, scope); if (tmp) blk->append(tmp); else flag = false; } if (flag) proc = blk; } if (proc == 0) return false; NetProcTop*top = new NetProcTop(scope, IVL_PR_INITIAL, proc); if (const LineInfo*li = dynamic_cast(this)) { top->set_line(*li); } if (gn_system_verilog()) { top->attribute(perm_string::literal("_ivl_schedule_init"), verinum(1)); } des->add_process(top); scope->set_var_init(proc); return true; } class elaborate_package_t : public elaborator_work_item_t { public: elaborate_package_t(Design*d, NetScope*scope, PPackage*p) : elaborator_work_item_t(d), scope_(scope), package_(p) { } ~elaborate_package_t() { } virtual void elaborate_runrun() { if (! package_->elaborate_scope(des, scope_)) des->errors += 1; } private: NetScope*scope_; PPackage*package_; }; class elaborate_root_scope_t : public elaborator_work_item_t { public: elaborate_root_scope_t(Design*des__, NetScope*scope, Module*rmod) : elaborator_work_item_t(des__), scope_(scope), rmod_(rmod) { } ~elaborate_root_scope_t() { } virtual void elaborate_runrun() { Module::replace_t root_repl; for (list::iterator cur = Module::user_defparms.begin() ; cur != Module::user_defparms.end() ; ++ cur ) { pform_name_t tmp_name = cur->first; if (peek_head_name(tmp_name) != scope_->basename()) continue; tmp_name.pop_front(); if (tmp_name.size() != 1) continue; root_repl[peek_head_name(tmp_name)] = cur->second; } if (! rmod_->elaborate_scope(des, scope_, root_repl)) des->errors += 1; } private: NetScope*scope_; Module*rmod_; }; class top_defparams : public elaborator_work_item_t { public: explicit top_defparams(Design*des__) : elaborator_work_item_t(des__) { } ~top_defparams() { } virtual void elaborate_runrun() { if (debug_scopes) { cerr << "debug: top_defparams::elaborate_runrun()" << endl; } // This method recurses through the scopes, looking for // defparam assignments to apply to the parameters in the // various scopes. This needs to be done after all the scopes // and basic parameters are taken care of because the defparam // can assign to a parameter declared *after* it. des->run_defparams(); // At this point, all parameter overrides are done. Scan the // scopes and evaluate the parameters all the way down to // constants. des->evaluate_parameters(); if (debug_scopes) { cerr << "debug: top_defparams::elaborate_runrun() done" << endl; } } }; class later_defparams : public elaborator_work_item_t { public: explicit later_defparams(Design*des__) : elaborator_work_item_t(des__) { } ~later_defparams() { } virtual void elaborate_runrun() { if (debug_scopes) { cerr << "debug: later_defparams::elaborate_runrun()" << endl; } listtmp_list; for (set::iterator cur = des->defparams_later.begin() ; cur != des->defparams_later.end() ; ++ cur ) tmp_list.push_back(*cur); des->defparams_later.clear(); while (! tmp_list.empty()) { NetScope*cur = tmp_list.front(); tmp_list.pop_front(); cur->run_defparams_later(des); } // The overridden parameters will be evaluated later in // a top_defparams work item. if (debug_scopes) { cerr << "debuf: later_defparams::elaborate_runrun() done" << endl; } } }; static ostream& operator<< (ostream&o, ivl_process_type_t t) { switch (t) { case IVL_PR_ALWAYS: o << "always"; break; case IVL_PR_ALWAYS_COMB: o << "always_comb"; break; case IVL_PR_ALWAYS_FF: o << "always_ff"; break; case IVL_PR_ALWAYS_LATCH: o << "always_latch"; break; case IVL_PR_INITIAL: o << "initial"; break; case IVL_PR_FINAL: o << "final"; break; } return o; } bool Design::check_proc_delay() const { bool result = false; for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) { /* If this is an always process and we have no or zero delay then * a runtime infinite loop will happen. If we possibly have some * delay then print a warning that an infinite loop is possible. */ if (pr->type() == IVL_PR_ALWAYS) { DelayType dly_type = pr->statement()->delay_type(); if (dly_type == NO_DELAY || dly_type == ZERO_DELAY) { cerr << pr->get_fileline() << ": error: always " "process does not have any delay." << endl; cerr << pr->get_fileline() << ": : A runtime " "infinite loop will occur." << endl; result = true; } else if (dly_type == POSSIBLE_DELAY && warn_inf_loop) { cerr << pr->get_fileline() << ": warning: always " "process may not have any delay." << endl; cerr << pr->get_fileline() << ": : A runtime " << "infinite loop may be possible." << endl; } } // The always_comb/ff/latch processes have special delay rules // that need to be checked. if ((pr->type() == IVL_PR_ALWAYS_COMB) || (pr->type() == IVL_PR_ALWAYS_FF) || (pr->type() == IVL_PR_ALWAYS_LATCH)) { const NetEvWait *wait = dynamic_cast (pr->statement()); if (! wait) { // The always_comb/latch processes have an event // control added automatically by the compiler. assert(pr->type() == IVL_PR_ALWAYS_FF); cerr << pr->get_fileline() << ": error: the first " "statement of an always_ff process must be " "an event control statement." << endl; result = true; } else if (wait->statement()->delay_type(true) != NO_DELAY) { cerr << pr->get_fileline() << ": error: there must "; if (pr->type() == IVL_PR_ALWAYS_FF) { cerr << "only be a single event control and " "no blocking delays in an always_ff " "process."; } else { cerr << "be no event controls or blocking " "delays in an " << pr->type() << " process."; } cerr << endl; result = true; } if ((pr->type() != IVL_PR_ALWAYS_FF) && (wait->nevents() == 0)) { if (pr->type() == IVL_PR_ALWAYS_LATCH) { cerr << pr->get_fileline() << ": error: " "always_latch process has no event " "control." << endl; result = true; } else { assert(pr->type() == IVL_PR_ALWAYS_COMB); cerr << pr->get_fileline() << ": warning: " "always_comb process has no " "sensitivities." << endl; } } } /* If this is a final block it must not have a delay, but this should have been caught by the statement elaboration, so maybe this should be an internal error? */ if (pr->type() == IVL_PR_FINAL) { DelayType dly_type = pr->statement()->delay_type(); if (dly_type != NO_DELAY) { cerr << pr->get_fileline() << ": error: final" << " statement contains a delay." << endl; result = true; } } } return result; } static void print_nexus_name(const Nexus*nex) { for (const Link*cur = nex->first_nlink(); cur; cur = cur->next_nlink()) { if (cur->get_dir() != Link::OUTPUT) continue; const NetPins*obj = cur->get_obj(); // For a NetNet (signal) just use the name. if (const NetNet*net = dynamic_cast(obj)) { cerr << net->name(); return; // For a NetPartSelect calculate the name. } else if (const NetPartSelect*ps = dynamic_cast(obj)) { assert(ps->pin_count() >= 2); assert(ps->pin(1).get_dir() == Link::INPUT); assert(ps->pin(1).is_linked()); print_nexus_name(ps->pin(1).nexus()); cerr << "[]"; return; // For a NetUReduce calculate the name. } else if (const NetUReduce*reduce = dynamic_cast(obj)) { assert(reduce->pin_count() == 2); assert(reduce->pin(1).get_dir() == Link::INPUT); assert(reduce->pin(1).is_linked()); switch (reduce->type()) { case NetUReduce::AND: cerr << "&"; break; case NetUReduce::OR: cerr << "|"; break; case NetUReduce::XOR: cerr << "^"; break; case NetUReduce::NAND: cerr << "~&"; break; case NetUReduce::NOR: cerr << "~|"; break; case NetUReduce::XNOR: cerr << "~^"; break; case NetUReduce::NONE: assert(0); } print_nexus_name(reduce->pin(1).nexus()); return; } else if (const NetLogic*logic = dynamic_cast(obj)) { assert(logic->pin_count() >= 2); assert(logic->pin(1).get_dir() == Link::INPUT); assert(logic->pin(1).is_linked()); switch (logic->type()) { case NetLogic::NOT: cerr << "~"; break; default: // The other operators should never be used here, // so just return the nexus name. cerr << nex->name(); return; } print_nexus_name(logic->pin(1).nexus()); return; } // Use the following to find the type of anything that may be missing: // cerr << "(" << typeid(*obj).name() << ") "; } // Otherwise just use the nexus name so somthing is printed. cerr << nex->name(); } static void print_event_probe_name(const NetEvProbe *prb) { assert(prb->pin_count() == 1); assert(prb->pin(0).get_dir() == Link::INPUT); assert(prb->pin(0).is_linked()); print_nexus_name(prb->pin(0).nexus()); } static void check_event_probe_width(const LineInfo *info, const NetEvProbe *prb) { assert(prb->pin_count() == 1); assert(prb->pin(0).get_dir() == Link::INPUT); assert(prb->pin(0).is_linked()); if (prb->edge() == NetEvProbe::ANYEDGE) return; if (prb->pin(0).nexus()->vector_width() > 1) { cerr << info->get_fileline() << " warning: Synthesis wants " "the sensitivity list expressions for '"; switch (prb->edge()) { case NetEvProbe::POSEDGE: cerr << "posedge "; break; case NetEvProbe::NEGEDGE: cerr << "negedge "; break; default: break; } print_nexus_name(prb->pin(0).nexus()); cerr << "' to be a single bit." << endl; } } static void check_ff_sensitivity(const NetProc* statement) { const NetEvWait *evwt = dynamic_cast (statement); // We have already checked for and reported if the first statmemnt is // not a wait. if (! evwt) return; for (unsigned cevt = 0; cevt < evwt->nevents(); cevt += 1) { const NetEvent *evt = evwt->event(cevt); for (unsigned cprb = 0; cprb < evt->nprobe(); cprb += 1) { const NetEvProbe *prb = evt->probe(cprb); check_event_probe_width(evwt, prb); if (prb->edge() == NetEvProbe::ANYEDGE) { cerr << evwt->get_fileline() << " warning: Synthesis " "requires the sensitivity list of an " "always_ff process to only be edge " "sensitive. "; print_event_probe_name(prb); cerr << " is missing a pos/negedge." << endl; } } } } /* * Check to see if the always_* processes only contain synthesizable * constructs. */ bool Design::check_proc_synth() const { bool result = false; for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) { if ((pr->type() == IVL_PR_ALWAYS_COMB) || (pr->type() == IVL_PR_ALWAYS_FF) || (pr->type() == IVL_PR_ALWAYS_LATCH)) { result |= pr->statement()->check_synth(pr->type(), pr->scope()); if (pr->type() == IVL_PR_ALWAYS_FF) { check_ff_sensitivity(pr->statement()); } } } return result; } /* * Check whether all design elements have an explicit timescale or all * design elements use the default timescale. If a mixture of explicit * and default timescales is found, a warning message is output. Note * that we only need to check the top level design elements - nested * design elements will always inherit the timescale from their parent * if they don't have any local timescale declarations. * * NOTE: Strictly speaking, this should be an error for SystemVerilog * (1800-2012 section 3.14.2). */ static void check_timescales(bool&some_explicit, bool&some_implicit, const PScope*scope) { if (scope->time_unit_is_default) some_implicit = true; else some_explicit = true; if (scope->time_prec_is_default) some_implicit = true; else some_explicit = true; } static void check_timescales() { bool some_explicit = false; bool some_implicit = false; map::iterator mod; for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) { const Module*mp = (*mod).second; check_timescales(some_explicit, some_implicit, mp); if (some_explicit && some_implicit) break; } vector::iterator pkg; if (gn_system_verilog() && !(some_explicit && some_implicit)) { for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) { const PPackage*pp = *pkg; check_timescales(some_explicit, some_implicit, pp); if (some_explicit && some_implicit) break; } } if (gn_system_verilog() && !(some_explicit && some_implicit)) { for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) { const PPackage*pp = *pkg; // We don't need a timescale if the compilation unit // contains no items outside a design element. if (pp->parameters.empty() && pp->wires.empty() && pp->tasks.empty() && pp->funcs.empty() && pp->classes.empty()) continue; check_timescales(some_explicit, some_implicit, pp); if (some_explicit && some_implicit) break; } } if (!(some_explicit && some_implicit)) return; if (gn_system_verilog()) { cerr << "warning: " << "Some design elements have no explicit time unit and/or" << endl; cerr << " : " << "time precision. This may cause confusing timing results." << endl; cerr << " : " << "Affected design elements are:" << endl; } else { cerr << "warning: " << "Some modules have no timescale. This may cause" << endl; cerr << " : " << "confusing timing results. Affected modules are:" << endl; } for (mod = pform_modules.begin(); mod != pform_modules.end(); ++mod) { Module*mp = (*mod).second; if (mp->has_explicit_timescale()) continue; cerr << " : -- module " << (*mod).first << " declared here: " << mp->get_fileline() << endl; } if (!gn_system_verilog()) return; for (pkg = pform_packages.begin(); pkg != pform_packages.end(); ++pkg) { PPackage*pp = *pkg; if (pp->has_explicit_timescale()) continue; cerr << " : -- package " << pp->pscope_name() << " declared here: " << pp->get_fileline() << endl; } for (pkg = pform_units.begin(); pkg != pform_units.end(); ++pkg) { PPackage*pp = *pkg; if (pp->has_explicit_timescale()) continue; if (pp->parameters.empty() && pp->wires.empty() && pp->tasks.empty() && pp->funcs.empty() && pp->classes.empty()) continue; cerr << " : -- compilation unit"; if (pform_units.size() > 1) { cerr << " from: " << pp->get_file(); } cerr << endl; } } /* * This function is the root of all elaboration. The input is the list * of root module names. The function locates the Module definitions * for each root, does the whole elaboration sequence, and fills in * the resulting Design. */ struct pack_elem { PPackage*pack; NetScope*scope; }; struct root_elem { Module *mod; NetScope *scope; }; Design* elaborate(listroots) { unsigned npackages = pform_packages.size(); if (gn_system_verilog()) npackages += pform_units.size(); vector root_elems(roots.size()); vector pack_elems(npackages); map unit_scopes; bool rc = true; unsigned i = 0; // This is the output design. I fill it in as I scan the root // module and elaborate what I find. Design*des = new Design; // Elaborate the compilation unit scopes. From here on, these are // treated as an additional set of packages. if (gn_system_verilog()) { for (vector::iterator pkg = pform_units.begin() ; pkg != pform_units.end() ; ++pkg) { PPackage*unit = *pkg; NetScope*scope = des->make_package_scope(unit->pscope_name(), 0, true); scope->set_line(unit); scope->add_imports(&unit->explicit_imports); set_scope_timescale(des, scope, unit); elaborator_work_item_t*es = new elaborate_package_t(des, scope, unit); des->elaboration_work_list.push_back(es); pack_elems[i].pack = unit; pack_elems[i].scope = scope; i += 1; unit_scopes[unit] = scope; } } // Elaborate the packages. Package elaboration is simpler // because there are fewer sub-scopes involved. Note that // in SystemVerilog, packages are not allowed to refer to // the compilation unit scope, but the VHDL preprocessor // assumes they can. for (vector::iterator pkg = pform_packages.begin() ; pkg != pform_packages.end() ; ++pkg) { PPackage*pack = *pkg; NetScope*unit_scope = unit_scopes[pack->parent_scope()]; NetScope*scope = des->make_package_scope(pack->pscope_name(), unit_scope, false); scope->set_line(pack); scope->add_imports(&pack->explicit_imports); set_scope_timescale(des, scope, pack); elaborator_work_item_t*es = new elaborate_package_t(des, scope, pack); des->elaboration_work_list.push_back(es); pack_elems[i].pack = pack; pack_elems[i].scope = scope; i += 1; } // Scan the root modules by name, and elaborate their scopes. i = 0; for (list::const_iterator root = roots.begin() ; root != roots.end() ; ++ root ) { // Look for the root module in the list. map::const_iterator mod = pform_modules.find(*root); if (mod == pform_modules.end()) { cerr << "error: Unable to find the root module \"" << (*root) << "\" in the Verilog source." << endl; cerr << " : Perhaps ``-s " << (*root) << "'' is incorrect?" << endl; des->errors++; continue; } // Get the module definition for this root instance. Module *rmod = (*mod).second; // Get the compilation unit scope for this module. NetScope*unit_scope = unit_scopes[rmod->parent_scope()]; // Make the root scope. This makes a NetScope object and // pushes it into the list of root scopes in the Design. NetScope*scope = des->make_root_scope(*root, unit_scope, rmod->program_block, rmod->is_interface); // Collect some basic properties of this scope from the // Module definition. scope->set_line(rmod); scope->add_imports(&rmod->explicit_imports); set_scope_timescale(des, scope, rmod); // Save this scope, along with its definition, in the // "root_elems" list for later passes. root_elems[i].mod = rmod; root_elems[i].scope = scope; i += 1; // Arrange for these scopes to be elaborated as root // scopes. Create an "elaborate_root_scope" object to // contain the work item, and append it to the scope // elaborations work list. elaborator_work_item_t*es = new elaborate_root_scope_t(des, scope, rmod); des->elaboration_work_list.push_back(es); } // Run the work list of scope elaborations until the list is // empty. This list is initially populated above where the // initial root scopes are primed. while (! des->elaboration_work_list.empty()) { // Push a work item to process the defparams of any scopes // that are elaborated during this pass. For the first pass // this will be all the root scopes. For subsequent passes // it will be any scopes created during the previous pass // by a generate construct or instance array. des->elaboration_work_list.push_back(new top_defparams(des)); // Transfer the queue to a temporary queue. list cur_queue; std::swap(cur_queue, des->elaboration_work_list); // Run from the temporary queue. If the temporary queue // items create new work queue items, they will show up // in the elaboration_work_list and then we get to run // through them in the next pass. while (! cur_queue.empty()) { elaborator_work_item_t*tmp = cur_queue.front(); cur_queue.pop_front(); tmp->elaborate_runrun(); delete tmp; } if (! des->elaboration_work_list.empty()) { des->elaboration_work_list.push_back(new later_defparams(des)); } } if (debug_elaborate) { cerr << ": elaborate: " << "elaboration work list done. Start processing residual defparams." << endl; } // Look for residual defparams (that point to a non-existent // scope) and clean them out. des->residual_defparams(); // Errors already? Probably missing root modules. Just give up // now and return nothing. if (des->errors > 0) return des; // Now we have the full design, check for timescale inconsistencies. if (warn_timescale) check_timescales(); if (debug_elaborate) { cerr << ": elaborate: " << "Start calling Package elaborate_sig methods." << endl; } // With the parameters evaluated down to constants, we have // what we need to elaborate signals and memories. This pass // creates all the NetNet and NetMemory objects for declared // objects. for (i = 0; i < pack_elems.size(); i += 1) { PPackage*pack = pack_elems[i].pack; NetScope*scope= pack_elems[i].scope; if (! pack->elaborate_sig(des, scope)) { if (debug_elaborate) { cerr << "" << ": debug: " << pack->pscope_name() << ": elaborate_sig failed!!!" << endl; } delete des; return 0; } } if (debug_elaborate) { cerr << ": elaborate: " << "Start calling $root elaborate_sig methods." << endl; } if (debug_elaborate) { cerr << ": elaborate: " << "Start calling root module elaborate_sig methods." << endl; } for (i = 0; i < root_elems.size(); i++) { Module *rmod = root_elems[i].mod; NetScope *scope = root_elems[i].scope; scope->set_num_ports( rmod->port_count() ); if (debug_elaborate) { cerr << "" << ": debug: " << rmod->mod_name() << ": port elaboration root " << rmod->port_count() << " ports" << endl; } if (! rmod->elaborate_sig(des, scope)) { if (debug_elaborate) { cerr << "" << ": debug: " << rmod->mod_name() << ": elaborate_sig failed!!!" << endl; } delete des; return 0; } // Some of the generators need to have the ports correctly // defined for the root modules. This code does that. for (unsigned idx = 0; idx < rmod->port_count(); idx += 1) { vector mport = rmod->get_port(idx); unsigned int prt_vector_width = 0; PortType::Enum ptype = PortType::PIMPLICIT; for (unsigned pin = 0; pin < mport.size(); pin += 1) { // This really does more than we need and adds extra // stuff to the design that should be cleaned later. NetNet *netnet = mport[pin]->elaborate_subport(des, scope); if (netnet != 0) { // Elaboration may actually fail with // erroneous input source prt_vector_width += netnet->vector_width() * netnet->pin_count(); ptype = PortType::merged(netnet->port_type(), ptype); } } if (debug_elaborate) { cerr << "" << ": debug: " << rmod->mod_name() << ": adding module port " << rmod->get_port_name(idx) << endl; } scope->add_module_port_info(idx, rmod->get_port_name(idx), ptype, prt_vector_width ); } } // Now that the structure and parameters are taken care of, // run through the pform again and generate the full netlist. for (i = 0; i < pack_elems.size(); i += 1) { PPackage*pkg = pack_elems[i].pack; NetScope*scope = pack_elems[i].scope; rc &= pkg->elaborate(des, scope); } for (i = 0; i < root_elems.size(); i++) { Module *rmod = root_elems[i].mod; NetScope *scope = root_elems[i].scope; rc &= rmod->elaborate(des, scope); } if (rc == false) { delete des; return 0; } // Now that everything is fully elaborated verify that we do // not have an always block with no delay (an infinite loop), // or a final block with a delay. bool has_failure = des->check_proc_delay(); // Check to see if the always_comb/ff/latch processes only have // synthesizable constructs has_failure |= des->check_proc_synth(); if (debug_elaborate) { cerr << "" << ": debug: " << " finishing with " << des->find_root_scopes().size() << " root scopes " << endl; } if (has_failure) { delete des; des = 0; } return des; } iverilog-12_0/elaborate_analog.cc000066400000000000000000000044521435245347300171420ustar00rootroot00000000000000/* * Copyright (c) 2008-2021 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" # include "netlist.h" # include "netmisc.h" # include "util.h" # include using namespace std; NetProc* AContrib::elaborate(Design*des, NetScope*scope) const { NetExpr*lval = elab_and_eval(des, scope, lval_, -1); NetExpr*rval = elab_and_eval(des, scope, rval_, -1); NetEAccess*lacc = dynamic_cast (lval); if (lacc == 0) { cerr << get_fileline() << ": error: The l-value of a contribution" << " statement must be a branch probe access function." << endl; des->errors += 1; return 0; } NetContribution*st = new NetContribution(lacc, rval); st->set_line(*this); return st; } bool AProcess::elaborate(Design*des, NetScope*scope) const { NetProc*estatement = statement_->elaborate(des, scope); if (estatement == 0) return false; NetAnalogTop*top = new NetAnalogTop(scope, type_, estatement); // Evaluate the attributes for this process, if there // are any. These attributes are to be attached to the // NetProcTop object. struct attrib_list_t*attrib_list; unsigned attrib_list_n = 0; attrib_list = evaluate_attributes(attributes, attrib_list_n, des, scope); for (unsigned adx = 0 ; adx < attrib_list_n ; adx += 1) top->attribute(attrib_list[adx].key, attrib_list[adx].val); delete[]attrib_list; top->set_line(*this); des->add_process(top); return true; } iverilog-12_0/emit.cc000066400000000000000000000356301435245347300146230ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 /* * The emit function is called to generate the output required of the * target. */ # include "target.h" # include "netclass.h" # include "netlist.h" # include "compiler.h" # include # include # include using namespace std; bool NetNode::emit_node(struct target_t*) const { cerr << "EMIT: Gate type? " << typeid(*this).name() << endl; return false; } bool NetLogic::emit_node(struct target_t*tgt) const { tgt->logic(this); return true; } bool NetUDP::emit_node(struct target_t*tgt) const { tgt->udp(this); return true; } bool NetAbs::emit_node(struct target_t*tgt) const { tgt->lpm_abs(this); return true; } bool NetAddSub::emit_node(struct target_t*tgt) const { tgt->lpm_add_sub(this); return true; } bool NetArrayDq::emit_node(struct target_t*tgt) const { return tgt->lpm_array_dq(this); } bool NetCaseCmp::emit_node(struct target_t*tgt) const { tgt->net_case_cmp(this); return true; } bool NetCastInt2::emit_node(struct target_t*tgt) const { return tgt->lpm_cast_int2(this); } bool NetCastInt4::emit_node(struct target_t*tgt) const { return tgt->lpm_cast_int4(this); } bool NetCastReal::emit_node(struct target_t*tgt) const { return tgt->lpm_cast_real(this); } bool NetCLShift::emit_node(struct target_t*tgt) const { tgt->lpm_clshift(this); return true; } bool NetCompare::emit_node(struct target_t*tgt) const { tgt->lpm_compare(this); return true; } bool NetConcat::emit_node(struct target_t*tgt) const { return tgt->concat(this); } bool NetConst::emit_node(struct target_t*tgt) const { return tgt->net_const(this); } bool NetDivide::emit_node(struct target_t*tgt) const { tgt->lpm_divide(this); return true; } bool NetFF::emit_node(struct target_t*tgt) const { tgt->lpm_ff(this); return true; } bool NetLatch::emit_node(struct target_t*tgt) const { tgt->lpm_latch(this); return true; } bool NetLiteral::emit_node(struct target_t*tgt) const { return tgt->net_literal(this); } bool NetModulo::emit_node(struct target_t*tgt) const { tgt->lpm_modulo(this); return true; } bool NetMult::emit_node(struct target_t*tgt) const { tgt->lpm_mult(this); return true; } bool NetMux::emit_node(struct target_t*tgt) const { tgt->lpm_mux(this); return true; } bool NetPartSelect::emit_node(struct target_t*tgt) const { return tgt->part_select(this); } bool NetPow::emit_node(struct target_t*tgt) const { tgt->lpm_pow(this); return true; } bool NetReplicate::emit_node(struct target_t*tgt) const { return tgt->replicate(this); } bool NetSignExtend::emit_node(struct target_t*tgt) const { return tgt->sign_extend(this); } bool NetSubstitute::emit_node(struct target_t*tgt) const { return tgt->substitute(this); } bool NetUReduce::emit_node(struct target_t*tgt) const { return tgt->ureduce(this); } bool NetSysFunc::emit_node(struct target_t*tgt) const { return tgt->net_sysfunction(this); } bool NetUserFunc::emit_node(struct target_t*tgt) const { return tgt->net_function(this); } bool NetTran::emit_node(struct target_t*tgt) const { return tgt->tran(this); } bool NetBUFZ::emit_node(struct target_t*tgt) const { return tgt->bufz(this); } bool NetProcTop::emit(struct target_t*tgt) const { return tgt->process(this); } bool NetAnalogTop::emit(struct target_t*tgt) const { return tgt->process(this); } bool NetProc::emit_proc(struct target_t*) const { cerr << "EMIT: Proc type? " << typeid(*this).name() << endl; return false; } bool NetAlloc::emit_proc(struct target_t*tgt) const { tgt->proc_alloc(this); return true; } bool NetAssign::emit_proc(struct target_t*tgt) const { return tgt->proc_assign(this); } bool NetAssignNB::emit_proc(struct target_t*tgt) const { tgt->proc_assign_nb(this); return true; } bool NetBlock::emit_proc(struct target_t*tgt) const { return tgt->proc_block(this); } bool NetCase::emit_proc(struct target_t*tgt) const { tgt->proc_case(this); return true; } bool NetCAssign::emit_proc(struct target_t*tgt) const { return tgt->proc_cassign(this); } bool NetCondit::emit_proc(struct target_t*tgt) const { return tgt->proc_condit(this); } bool NetContribution::emit_proc(struct target_t*tgt) const { return tgt->proc_contribution(this); } bool NetDeassign::emit_proc(struct target_t*tgt) const { return tgt->proc_deassign(this); } bool NetDisable::emit_proc(struct target_t*tgt) const { return tgt->proc_disable(this); } bool NetDoWhile::emit_proc(struct target_t*tgt) const { tgt->proc_do_while(this); return true; } void NetDoWhile::emit_proc_recurse(struct target_t*tgt) const { proc_->emit_proc(tgt); } bool NetForce::emit_proc(struct target_t*tgt) const { return tgt->proc_force(this); } bool NetForever::emit_proc(struct target_t*tgt) const { tgt->proc_forever(this); return true; } bool NetForLoop::emit_proc(struct target_t*tgt) const { return tgt->proc_block(as_block_); } bool NetFree::emit_proc(struct target_t*tgt) const { tgt->proc_free(this); return true; } bool NetPDelay::emit_proc(struct target_t*tgt) const { return tgt->proc_delay(this); } bool NetPDelay::emit_proc_recurse(struct target_t*tgt) const { if (statement_) return statement_->emit_proc(tgt); return true; } bool NetRelease::emit_proc(struct target_t*tgt) const { return tgt->proc_release(this); } bool NetRepeat::emit_proc(struct target_t*tgt) const { tgt->proc_repeat(this); return true; } bool NetSTask::emit_proc(struct target_t*tgt) const { tgt->proc_stask(this); return true; } bool NetUTask::emit_proc(struct target_t*tgt) const { tgt->proc_utask(this); return true; } bool NetWhile::emit_proc(struct target_t*tgt) const { tgt->proc_while(this); return true; } void NetWhile::emit_proc_recurse(struct target_t*tgt) const { proc_->emit_proc(tgt); } void NetBlock::emit_recurse(struct target_t*tgt) const { if (last_ == 0) return; NetProc*cur = last_; do { cur = cur->next_; cur->emit_proc(tgt); } while (cur != last_); } bool NetCondit::emit_recurse_if(struct target_t*tgt) const { if (if_) return if_->emit_proc(tgt); else return true; } bool NetCondit::emit_recurse_else(struct target_t*tgt) const { if (else_) return else_->emit_proc(tgt); else return true; } bool NetEvProbe::emit_node(struct target_t*tgt) const { tgt->net_probe(this); return true; } bool NetEvTrig::emit_proc(struct target_t*tgt) const { return tgt->proc_trigger(this); } bool NetEvNBTrig::emit_proc(struct target_t*tgt) const { return tgt->proc_nb_trigger(this); } bool NetEvWait::emit_proc(struct target_t*tgt) const { return tgt->proc_wait(this); } bool NetEvWait::emit_recurse(struct target_t*tgt) const { if (!statement_) return true; return statement_->emit_proc(tgt); } void NetForever::emit_recurse(struct target_t*tgt) const { if (statement_) statement_->emit_proc(tgt); } void NetRepeat::emit_recurse(struct target_t*tgt) const { if (statement_) statement_->emit_proc(tgt); } void netclass_t::emit_scope(struct target_t*tgt) const { class_scope_->emit_scope(tgt); } void NetScope::emit_scope(struct target_t*tgt) const { if (debug_emit) { cerr << "NetScope::emit_scope: " << "Emit scope " << scope_path(this) << endl; } tgt->scope(this); for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) tgt->event(cur); for (map::const_iterator cur = classes_.begin() ; cur != classes_.end() ; ++cur) { cur->second->emit_scope(tgt); tgt->class_type(this, cur->second); } for (map::const_iterator cur = enum_sets_.begin() ; cur != enum_sets_.end() ; ++cur) tgt->enumeration(this, cur->second); for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->emit_scope(tgt); for (signals_map_iter_t cur = signals_map_.begin() ; cur != signals_map_.end() ; ++ cur ) { tgt->signal(cur->second); } // Run the signals again, but this time to connect the // delay paths. This is done as a second pass because // the paths reference other signals that may be later // in the list. We can do it here because delay paths are // always connected within the scope. for (signals_map_iter_t cur = signals_map_.begin() ; cur != signals_map_.end() ; ++ cur) { tgt->signal_paths(cur->second); } if (type_ == MODULE) tgt->convert_module_ports(this); } bool NetScope::emit_defs(struct target_t*tgt) const { bool flag = true; if (debug_emit) { cerr << "NetScope::emit_defs: " << "Emit definitions for " << scope_path(this) << endl; } switch (type_) { case PACKAGE: case MODULE: for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) flag &= cur->second->emit_defs(tgt); for (map::const_iterator cur = classes_.begin() ; cur != classes_.end() ; ++ cur) flag &= cur->second->emit_defs(tgt); break; case FUNC: flag &= tgt->func_def(this); break; case TASK: tgt->task_def(this); break; default: /* BEGIN_END and FORK_JOIN, GENERATE... */ for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) flag &= cur->second->emit_defs(tgt); break; } return flag; } bool netclass_t::emit_defs(struct target_t*tgt) const { return class_scope_->emit_defs(tgt); } int Design::emit(struct target_t*tgt) const { int rc = 0; if (tgt->start_design(this) == false) return -2; // enumerate package scopes for (map::const_iterator scope = packages_.begin() ; scope != packages_.end() ; ++ scope) { scope->second->emit_scope(tgt); } // enumerate root scopes for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end(); ++ scope ) { (*scope)->emit_scope(tgt); } // emit nodes bool nodes_rc = true; if (nodes_) { NetNode*cur = nodes_->node_next_; do { nodes_rc = nodes_rc && cur->emit_node(tgt); cur = cur->node_next_; } while (cur != nodes_->node_next_); } bool branches_rc = true; for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) { branches_rc = tgt->branch(cur) && branches_rc; } // emit task and function definitions bool tasks_rc = true; for (map::const_iterator scope = packages_.begin() ; scope != packages_.end() ; ++ scope ) tasks_rc &= scope->second->emit_defs(tgt); for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end(); ++ scope ) tasks_rc &= (*scope)->emit_defs(tgt); // emit the processes bool proc_rc = true; for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_) proc_rc &= idx->emit(tgt); for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_) proc_rc &= idx->emit(tgt); if (nodes_rc == false) tgt->errors += 1; if (tasks_rc == false) tgt->errors += 1; if (proc_rc == false) tgt->errors += 1; if (branches_rc == false) tgt->errors += 1; rc = tgt->end_design(this); if (nodes_rc == false) return -1; if (tasks_rc == false) return -2; if (proc_rc == false) return -3; if (branches_rc == false) return -4; return rc; } void NetEAccess::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_access_func(this); } void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_array_pattern(this); } void NetEBinary::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_binary(this); } void NetEConcat::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_concat(this); } void NetEConst::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_const(this); } void NetEConstEnum::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_const(this); } void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_param(this); } void NetECReal::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_creal(this); } void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_rparam(this); } void NetEEvent::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_event(this); } void NetELast::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_last(this); } void NetENetenum::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_netenum(this); } void NetENew::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_new(this); } void NetENull::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_null(this); } void NetEProperty::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_property(this); } void NetEScope::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_scope(this); } void NetESelect::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_select(this); } void NetESFunc::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_sfunc(this); } void NetEShallowCopy::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_scopy(this); } void NetEShallowCopy::expr_scan_oper1(struct expr_scan_t*tgt) const { arg1_->expr_scan(tgt); } void NetEShallowCopy::expr_scan_oper2(struct expr_scan_t*tgt) const { arg2_->expr_scan(tgt); } void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_ufunc(this); } void NetESignal::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_signal(this); } void NetETernary::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_ternary(this); } void NetEUnary::expr_scan(struct expr_scan_t*tgt) const { tgt->expr_unary(this); } iverilog-12_0/eval_attrib.cc000066400000000000000000000046041435245347300161560ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 "util.h" # include "PExpr.h" # include "netlist.h" # include "netmisc.h" # include # include using namespace std; /* * The evaluate_attributes function evaluates the attribute * expressions from the map, and returns a table in a form suitable * for passing to netlist devices. */ attrib_list_t* evaluate_attributes(const map&att, unsigned&natt, Design*des, NetScope*scope) { natt = att.size(); if (natt == 0) return 0; attrib_list_t*table = new attrib_list_t [natt]; unsigned idx = 0; typedef map::const_iterator iter_t; for (iter_t cur = att.begin() ; cur != att.end() ; ++ cur , idx += 1) { table[idx].key = (*cur).first; PExpr*exp = (*cur).second; /* If the attribute value is given in the source, then evaluate it as a constant. If the value is not given, then assume the value is 1. */ if (exp) { NetExpr *tmp = elab_and_eval(des, scope, exp, -1, true); if (!tmp) continue; if (NetEConst *ce = dynamic_cast(tmp)) { table[idx].val = ce->value(); } else if (NetECReal *cer = dynamic_cast(tmp)) { table[idx].val = verinum(cer->value().as_long()); } else { cerr << exp->get_fileline() << ": error: ``" << *exp << "'' is not a constant expression." << endl; des->errors += 1; } delete tmp; } else { table[idx].val = verinum(1); } } assert(idx == natt); return table; } iverilog-12_0/eval_tree.cc000066400000000000000000002025031435245347300156260ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "compiler.h" # include # include # include # include # include "netlist.h" # include "ivl_assert.h" # include "netmisc.h" using namespace std; NetExpr* NetExpr::eval_tree() { return 0; } static void eval_debug(const NetExpr*expr, NetExpr*res, bool is_real) { if (res != 0) { res->set_line(*expr); if (debug_eval_tree) { cerr << expr->get_fileline() << ": debug: Evaluated"; if (is_real) cerr << " (real)"; cerr << ": " << *expr << " --> " << *res << endl; } } } static bool get_real_arg_(const NetExpr*expr, verireal&val) { switch (expr->expr_type()) { case IVL_VT_REAL: { const NetECReal*c = dynamic_cast (expr); if (c == 0) return false; val = c->value(); break; } case IVL_VT_BOOL: case IVL_VT_LOGIC: { const NetEConst*c = dynamic_cast(expr); if (c == 0) return false; verinum tmp = c->value(); val = verireal(tmp.as_double()); break; } case IVL_VT_DARRAY: return false; default: ivl_assert(*expr, 0); } return true; } static bool get_real_arguments(const NetExpr*le, const NetExpr*re, double&lval, double&rval) { verireal val; if (!get_real_arg_(le, val)) return false; lval = val.as_double(); if (!get_real_arg_(re, val)) return false; rval = val.as_double(); return true; } NetExpr* NetEBinary::eval_tree() { eval_expr(left_); eval_expr(right_); return eval_arguments_(left_, right_); } NetExpr* NetEBinary::eval_arguments_(const NetExpr*, const NetExpr*) const { // this method should be overridden in all sub-classes ivl_assert(*this, 0); return 0; } NetECReal* NetEBAdd::eval_tree_real_(const NetExpr*l, const NetExpr*r) const { double lval; double rval; bool flag = get_real_arguments(l, r, lval, rval); if (!flag) return 0; double res_val; switch (op()) { case '+': res_val = lval + rval; break; case '-': res_val = lval - rval; break; default: ivl_assert(*this, 0); } NetECReal*res = new NetECReal( verireal(res_val) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEBAdd::eval_tree() { eval_expr(left_); eval_expr(right_); // First try to elaborate the expression completely. NetExpr*res = eval_arguments_(left_,right_); if (res != 0) return res; // If the expression type is real, then do not attempt the // following alternative processing. if (expr_type() == IVL_VT_REAL) return 0; // The expression has not evaluated to a constant. Let's still // try to optimize by trying to combine a right constant value // with the right constant value of a sub-expression add. For // example, the expression (a + 2) - 1 can be rewritten as a + 1. NetEBAdd*se = dynamic_cast(left_); NetEConst*lc = se? dynamic_cast(se->right_) : 0; NetEConst*rc = dynamic_cast(right_); if (lc != 0 && rc != 0) { ivl_assert(*this, se != 0); if (debug_eval_tree) { cerr << get_fileline() << ": debug: " << "Partially evaluate " << *this << " using (a+2)-1 --> (a+1) transform." << endl; } verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum val; if (op_ == se->op_) { /* (a + lval) + rval --> a + (rval+lval) */ /* (a - lval) - rval --> a - (rval+lval) */ val = cast_to_width(rval + lval, wid); } else { /* (a - lval) + rval --> a + (rval-lval) */ /* (a + lval) - rval --> a - (rval-lval) */ val = cast_to_width(rval - lval, wid); } NetEConst*tmp = new NetEConst(val); left_ = se->left_->dup_expr(); delete se; tmp->set_line(*right_); delete right_; right_ = tmp; } // We may have changed the subexpression, but the result is // still not constant, so return nil here anyhow. return 0; } NetExpr* NetEBAdd::eval_arguments_(const NetExpr*l, const NetExpr*r) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); /* If both operands are constant, then replace the entire expression with a constant value. */ if (lc != 0 && rc != 0) { verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum val; switch (op_) { case '+': val = cast_to_width(lval + rval, wid); break; case '-': val = cast_to_width(lval - rval, wid); break; default: return 0; } NetEConst *res = new NetEConst(val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } /* Nothing more to be done, the value is not constant. */ return 0; } NetEConst* NetEBBits::eval_arguments_(const NetExpr*l, const NetExpr*r) const { const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); if (lc == 0 || rc == 0) return 0; /* Notice the special case where one of the operands is 0 and this is a bitwise &. If this happens, then the result is known to be 0. */ if ((op() == '&') && (lc->value() == verinum(0))) { verinum res (verinum::V0, expr_width()); res.has_sign(has_sign()); NetEConst*tmp = new NetEConst(res); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } if ((op() == '&') && (rc->value() == verinum(0))) { verinum res (verinum::V0, expr_width()); res.has_sign(has_sign()); NetEConst*tmp = new NetEConst(res); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum res (verinum::V0, wid); switch (op()) { case '|': { for (unsigned idx = 0 ; idx < wid ; idx += 1) res.set(idx, lval.get(idx) | rval.get(idx)); break; } case '&': { for (unsigned idx = 0 ; idx < wid ; idx += 1) res.set(idx, lval.get(idx) & rval.get(idx)); break; } case 'X': { for (unsigned idx = 0 ; idx < wid ; idx += 1) res.set(idx, ~(lval.get(idx) ^ rval.get(idx))); break; } case '^': { for (unsigned idx = 0 ; idx < wid ; idx += 1) res.set(idx, lval.get(idx) ^ rval.get(idx)); break; } default: return 0; } res.has_sign(has_sign()); NetEConst*tmp = new NetEConst(res); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } NetEConst* NetEBComp::eval_less_(const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_leeq_real_(le, re, false); const NetEConst*rc = dynamic_cast(re); if (rc == 0) return 0; verinum rv = rc->value(); if (! rv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (NetEConst*tmp = must_be_leeq_(le, rv, false)) { return tmp; } /* Now go on to the normal test of the values. */ const NetEConst*lc = dynamic_cast(le); if (lc == 0) return 0; verinum lv = lc->value(); if (! lv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (lv < rv) { NetEConst*res = new NetEConst(verinum(verinum::V1, 1)); ivl_assert(*this, res); return res; } else { NetEConst*res = new NetEConst(verinum(verinum::V0, 1)); ivl_assert(*this, res); return res; } } NetEConst* NetEBComp::must_be_leeq_(const NetExpr*le, const verinum&rv, bool eq_flag) const { // The following optimization is not valid if le can contain 'x' // or 'z' values. if (le->expr_type() == IVL_VT_LOGIC) return 0; ivl_assert(*le, le->expr_width() > 0); verinum lv (verinum::V1, le->expr_width()); if (le->has_sign() && rv.has_sign()) { // If the expression is signed, then the largest // possible value for the left_ needs to have a 0 in the // sign position. lv.set(lv.len()-1, verinum::V0); lv.has_sign(true); } if (lv < rv || (eq_flag && (lv == rv))) { NetEConst*res = new NetEConst(verinum(verinum::V1, 1)); ivl_assert(*this, res); return res; } return 0; } NetEConst* NetEBComp::eval_leeq_real_(const NetExpr*le, const NetExpr*re, bool eq_flag) const { double lval; double rval; bool flag = get_real_arguments(le, re, lval, rval); if (! flag) return 0; bool tmp = false; if (lval < rval) tmp = true; if (tmp == false && eq_flag && lval == rval) tmp = true; verinum result(tmp ? verinum::V1 : verinum::V0, 1); NetEConst*res = new NetEConst(result); ivl_assert(*this, res); return res; } NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_leeq_real_(le, re, true); const NetEConst*r = dynamic_cast(re); if (r == 0) return 0; verinum rv = r->value(); if (! rv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (NetEConst*tmp = must_be_leeq_(le, rv, true)) { return tmp; } /* Now go on to the normal test of the values. */ const NetEConst*l = dynamic_cast(le); if (l == 0) return 0; verinum lv = l->value(); if (! lv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (lv <= rv) { NetEConst*res = new NetEConst(verinum(verinum::V1, 1)); ivl_assert(*this, res); return res; } else { NetEConst*res = new NetEConst(verinum(verinum::V0, 1)); ivl_assert(*this, res); return res; } } NetEConst* NetEBComp::eval_gt_(const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_leeq_real_(re, le, false); const NetEConst*l = dynamic_cast(le); if (l == 0) return 0; verinum lv = l->value(); if (! lv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (NetEConst*tmp = must_be_leeq_(re, lv, false)) { return tmp; } /* Now go on to the normal test of the values. */ const NetEConst*r = dynamic_cast(re); if (r == 0) return 0; verinum rv = r->value(); if (! rv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (lv > rv) { NetEConst*res = new NetEConst(verinum(verinum::V1, 1)); ivl_assert(*this, res); return res; } else { NetEConst*res = new NetEConst(verinum(verinum::V0, 1)); ivl_assert(*this, res); return res; } } NetEConst* NetEBComp::eval_gteq_(const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_leeq_real_(re, le, true); const NetEConst*l = dynamic_cast(le); if (l == 0) return 0; verinum lv = l->value(); if (! lv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (NetEConst*tmp = must_be_leeq_(re, lv, true)) { return tmp; } /* Now go on to the normal test of the values. */ const NetEConst*r = dynamic_cast(re); if (r == 0) return 0; verinum rv = r->value(); if (! rv.is_defined()) { NetEConst*res = new NetEConst(verinum(verinum::Vx, 1)); ivl_assert(*this, res); return res; } if (lv >= rv) { NetEConst*res = new NetEConst(verinum(verinum::V1, 1)); ivl_assert(*this, res); return res; } else { NetEConst*res = new NetEConst(verinum(verinum::V0, 1)); ivl_assert(*this, res); return res; } } /* * Evaluate == or !=. The equality operator checks all the * bits and returns true(false) if there are any bits in the vector * that are defined (0 or 1) and different. If all the defined bits * are equal, but there are are x/z bits, then the situation is * ambiguous so the result is x. */ NetEConst* NetEBComp::eval_eqeq_real_(bool ne_flag, const NetExpr*le, const NetExpr*re) const { double lval; double rval; bool flag = get_real_arguments(le, re, lval, rval); if (! flag) return 0; verinum result(((lval == rval) != ne_flag) ? verinum::V1 : verinum::V0, 1); NetEConst*res = new NetEConst(result); ivl_assert(*this, res); return res; } NetEConst* NetEBComp::eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_eqeq_real_(ne_flag, le, re); const NetEConst*lc = dynamic_cast(le); const NetEConst*rc = dynamic_cast(re); if (lc == 0 || rc == 0) return 0; const verinum&lv = lc->value(); const verinum&rv = rc->value(); const verinum::V eq_res = ne_flag? verinum::V0 : verinum::V1; const verinum::V ne_res = ne_flag? verinum::V1 : verinum::V0; verinum::V res = eq_res; // The two expressions should already be padded to the same size. ivl_assert(*this, lv.len() == rv.len()); for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) { bool x_bit_present = false; switch (lv.get(idx)) { case verinum::Vx: case verinum::Vz: res = verinum::Vx; x_bit_present = true; break; default: break; } switch (rv.get(idx)) { case verinum::Vx: case verinum::Vz: res = verinum::Vx; x_bit_present = true; break; default: break; } if (x_bit_present) continue; if (rv.get(idx) != lv.get(idx)) { res = ne_res; break; } } NetEConst*result = new NetEConst(verinum(res, 1)); ivl_assert(*this, result); return result; } NetEConst* NetEBComp::eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const { const NetEConst*lc = dynamic_cast(le); const NetEConst*rc = dynamic_cast(re); if (lc == 0 || rc == 0) return 0; const verinum&lv = lc->value(); const verinum&rv = rc->value(); verinum::V res = verinum::V1; // The two expressions should already be padded to the same size. ivl_assert(*this, lv.len() == rv.len()); for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) if (lv.get(idx) != rv.get(idx)) { res = verinum::V0; break; } if (ne_flag) { if (res == verinum::V0) res = verinum::V1; else res = verinum::V0; } NetEConst*result = new NetEConst(verinum(res, 1)); ivl_assert(*this, result); return result; } NetEConst* NetEBComp::eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const { const NetEConst*lc = dynamic_cast(le); const NetEConst*rc = dynamic_cast(re); if (lc == 0 || rc == 0) return 0; const verinum&lv = lc->value(); const verinum&rv = rc->value(); const verinum::V eq_res = ne_flag ? verinum::V0 : verinum::V1; const verinum::V ne_res = ne_flag ? verinum::V1 : verinum::V0; verinum::V res = eq_res; // The two expressions should already be padded to the same size. ivl_assert(*this, lv.len() == rv.len()); for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) { // An X or Z in the R-value matches any L-value. switch (rv.get(idx)) { case verinum::Vx: case verinum::Vz: continue; default: break; } // An X or Z in the L-value that is not matches by an R-value X/Z returns undefined. switch (lv.get(idx)) { case verinum::Vx: case verinum::Vz: res = verinum::Vx; continue; default: break; } // A hard (0/1) mismatch gives a not-equal result. if (rv.get(idx) != lv.get(idx)) { res = ne_res; break; } } NetEConst*result = new NetEConst(verinum(res, 1)); ivl_assert(*this, result); return result; } NetEConst* NetEBComp::eval_arguments_(const NetExpr*l, const NetExpr*r) const { NetEConst*res = 0; switch (op_) { case 'E': // Case equality (===) res = eval_eqeqeq_(false, l, r); break; case 'e': // Equality (==) res = eval_eqeq_(false, l, r); break; case 'w': // Wild equality (==?) res = eval_weqeq_(false, l, r); break; case 'G': // >= res = eval_gteq_(l, r); break; case 'L': // <= res = eval_leeq_(l, r); break; case 'N': // Case inequality (!==) res = eval_eqeqeq_(true, l, r); break; case 'n': // not-equal (!=) res = eval_eqeq_(true, l, r); break; case 'W': // Wild not-equal (!=?) res = eval_weqeq_(true, l, r); break; case '<': // Less than res = eval_less_(l, r); break; case '>': // Greater than res = eval_gt_(l, r); break; } eval_debug(this, res, l->expr_type() == IVL_VT_REAL || r->expr_type() == IVL_VT_REAL); return res; } NetExpr* NetEBDiv::eval_tree_real_(const NetExpr*l, const NetExpr*r) const { double lval; double rval; bool flag = get_real_arguments(l, r, lval, rval); if (! flag) return 0; double res_val = 0.0; switch (op_) { case '/': res_val = lval / rval; break; case '%': // Since this could/may be called early we don't want to // leak functionality. if (!gn_icarus_misc_flag) return 0; res_val = fmod(lval, rval); break; } NetECReal*res = new NetECReal( verireal(res_val) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEBDiv::eval_arguments_(const NetExpr*l, const NetExpr*r) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r); ivl_assert(*this, expr_type() == IVL_VT_LOGIC); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); if (lc == 0 || rc == 0) return 0; verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum val; switch (op_) { case '/': val = cast_to_width(lval / rval, wid); break; case '%': val = cast_to_width(lval % rval, wid); break; default: return 0; } NetExpr*tmp = new NetEConst(val); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } NetEConst* NetEBLogic::eval_arguments_(const NetExpr*l, const NetExpr*r) const { // NetEBLogic arguments should have already been reduced so real is not possible. ivl_assert(*this, (l->expr_type() != IVL_VT_REAL) && (r->expr_type() != IVL_VT_REAL)); ivl_assert(*this, expr_type() == IVL_VT_LOGIC); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); // If the left side is constant and the right side is short circuited // replace the expression with a constant if (rc == 0 && lc != 0) { verinum v = lc->value(); verinum::V res = verinum::Vx; switch (op_) { case 'a': // Logical AND (&&) if (v.is_zero()) res = verinum::V0; break; case 'o': // Logical OR (||) if (! v.is_zero() && v.is_defined()) res = verinum::V1; break; case 'q': // Logical implication (->) if (v.is_zero()) res = verinum::V1; break; default: break; } if (res != verinum::Vx) { NetEConst*tmp = new NetEConst(verinum(res, 1)); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } } if (lc == 0 || rc == 0) return 0; verinum::V lv = verinum::V0; verinum::V rv = verinum::V0; verinum v = lc->value(); for (unsigned idx = 0 ; idx < v.len() ; idx += 1) if (v.get(idx) == verinum::V1) { lv = verinum::V1; break; } if (lv == verinum::V0 && ! v.is_defined()) lv = verinum::Vx; v = rc->value(); for (unsigned idx = 0 ; idx < v.len() ; idx += 1) if (v.get(idx) == verinum::V1) { rv = verinum::V1; break; } if (rv == verinum::V0 && ! v.is_defined()) rv = verinum::Vx; verinum::V res; switch (op_) { case 'a': // Logical AND (&&) if ((lv == verinum::V0) || (rv == verinum::V0)) res = verinum::V0; else if ((lv == verinum::V1) && (rv == verinum::V1)) res = verinum::V1; else res = verinum::Vx; break; case 'o': // Logical OR (||) if ((lv == verinum::V1) || (rv == verinum::V1)) res = verinum::V1; else if ((lv == verinum::V0) && (rv == verinum::V0)) res = verinum::V0; else res = verinum::Vx; break; case 'q': // Logical implication (->) if ((lv == verinum::V0) || (rv == verinum::V1)) res = verinum::V1; else if ((lv == verinum::V1) && (rv == verinum::V0)) res = verinum::V0; else res = verinum::Vx; break; case 'Q': // Logical equivalence (<->) if (((lv == verinum::V0) && (rv == verinum::V0)) || ((lv == verinum::V1) && (rv == verinum::V1))) res = verinum::V1; else if (((lv == verinum::V0) && (rv == verinum::V1)) || ((lv == verinum::V1) && (rv == verinum::V0))) res = verinum::V0; else res = verinum::Vx; break; default: return 0; } NetEConst*tmp = new NetEConst(verinum(res, 1)); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } NetExpr* NetEBMinMax::eval_tree_real_(const NetExpr*l, const NetExpr*r) const { double lval; double rval; bool flag = get_real_arguments(l, r, lval, rval); if (! flag) return 0; double res_val; switch (op()) { case 'm': res_val = lval < rval ? lval : rval; break; case 'M': res_val = lval > rval ? lval : rval; break; default: ivl_assert(*this, 0); } NetECReal*res = new NetECReal( verireal(res_val) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEBMinMax::eval_arguments_(const NetExpr*l, const NetExpr*r) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r); ivl_assert(*this, expr_type() == IVL_VT_LOGIC); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); if (lc == 0 || rc == 0) return 0; verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum res_val; if (lval.is_defined() && rval.is_defined()) { switch (op()) { case 'm': res_val = lval < rval ? lval : rval; break; case 'M': res_val = lval > rval ? lval : rval; break; default: ivl_assert(*this, 0); } } else { res_val = verinum(verinum::Vx, wid); } res_val.has_sign(has_sign()); NetEConst*res = new NetEConst(res_val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } NetExpr* NetEBMult::eval_tree_real_(const NetExpr*l, const NetExpr*r) const { double lval; double rval; bool flag = get_real_arguments(l, r, lval, rval); if (! flag) return 0; NetECReal*res = new NetECReal( verireal(lval * rval) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEBMult::eval_arguments_(const NetExpr*l, const NetExpr*r) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r); ivl_assert(*this, expr_type() == IVL_VT_LOGIC); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); if (lc == 0 || rc == 0) return 0; verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); ivl_assert(*this, rval.len() == wid); verinum val = cast_to_width(lval * rval, wid); NetEConst*tmp = new NetEConst(val); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } NetExpr* NetEBPow::eval_tree_real_(const NetExpr*l, const NetExpr*r) const { double lval; double rval; bool flag = get_real_arguments(l, r, lval, rval); if (! flag) return 0; NetECReal*res = new NetECReal( verireal( pow(lval,rval) ) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEBPow::eval_arguments_(const NetExpr*l, const NetExpr*r) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(l,r); ivl_assert(*this, expr_type() == IVL_VT_LOGIC); const NetEConst*lc = dynamic_cast(l); const NetEConst*rc = dynamic_cast(r); if (lc == 0 || rc == 0) return 0; verinum lval = lc->value(); verinum rval = rc->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lval.len() == wid); verinum val = cast_to_width(pow(lval, rval), wid); NetEConst*res = new NetEConst(val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } NetEConst* NetEBShift::eval_arguments_(const NetExpr*l, const NetExpr*r) const { const NetEConst*le = dynamic_cast(l); const NetEConst*re = dynamic_cast(r); if (le == 0 || re == 0) return 0; NetEConst*res; verinum lv = le->value(); verinum rv = re->value(); unsigned wid = expr_width(); ivl_assert(*this, wid > 0); ivl_assert(*this, lv.len() == wid); verinum val; if (rv.is_defined()) { unsigned shift = rv.as_unsigned(); switch (op_) { case 'l': val = cast_to_width(lv << shift, wid); break; case 'r': lv.has_sign(false); // fallthrough case 'R': val = cast_to_width(lv >> shift, wid); break; default: return 0; } } else { val = verinum(verinum::Vx, wid); } val.has_sign(has_sign()); res = new NetEConst(val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } NetEConst* NetEConcat::eval_tree() { unsigned local_errors = 0; unsigned gap = 0; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { // Parameter not here? This is an error, but presumably // already caught and we are here just to catch more. if (parms_[idx] == 0) continue; // If this parameter is already a constant, all is well // so go on. if (dynamic_cast(parms_[idx])) { gap += parms_[idx]->expr_width(); continue; } // Finally, try to evaluate the parameter expression // that is here. If I succeed, reset the parameter to // the evaluated value. ivl_assert(*this, parms_[idx]); NetExpr*expr = parms_[idx]->eval_tree(); if (expr) { expr->set_line(*parms_[idx]); delete parms_[idx]; parms_[idx] = expr; if (! expr->has_width()) { cerr << get_fileline() << ": error: concatenation " << "operand has indefinite width: " << *parms_[idx] << endl; local_errors += 1; } else if (expr->expr_width() == 0) { cerr << expr->get_fileline() << ": internal error: " << "Operand of concatenation has no width: " << *expr << endl; local_errors += 1; } gap += expr->expr_width(); } } if (local_errors > 0) return 0; return eval_arguments_(parms_, gap); } NetEConst* NetEConcat::eval_arguments_(const vector&vals, unsigned gap) const { unsigned repeat_val = repeat(); // At this point, the "gap" is the width of a single repeat of // the concatenation. The total width of the result is the gap // times the repeat count. verinum val (verinum::Vx, repeat_val * gap); // build up the result from least significant to most. unsigned cur = 0; bool is_string_flag = true; for (unsigned idx = vals.size() ; idx > 0 ; idx -= 1) { const NetEConst*expr = dynamic_cast(vals[idx-1]); if (expr == 0) return 0; verinum tmp = expr->value(); for (unsigned bit = 0; bit < tmp.len(); bit += 1, cur += 1) for (unsigned rep = 0 ; rep < repeat_val ; rep += 1) val.set(rep*gap+cur, tmp[bit]); is_string_flag = is_string_flag && tmp.is_string(); } /* If all the values were strings, then re-stringify this constant. This might be useful information in the code generator or other optimizer steps. */ if (is_string_flag) { val = verinum(val.as_string()); } // Normally, concatenations are unsigned. However, the // $signed() function works by marking the expression as // signed, so we really have to check. val.has_sign( this->has_sign() ); NetEConst*res = new NetEConst(val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } NetEConst* NetESelect::eval_tree() { eval_expr(expr_); NetEConst*expr = dynamic_cast(expr_); long bval = 0; if (base_) { eval_expr(base_); NetEConst*base = dynamic_cast(base_); if (base == 0) return 0; bval = base->value().as_long(); } if (expr == 0) return 0; verinum eval = expr->value(); verinum oval (verinum::V0, expr_width(), true); verinum::V pad_bit = verinum::Vx; if (base_ == 0) { /* If the base is NULL (different from 0) then this select is here for zero or sign extension. So calculate a proper pad bit. */ if (has_sign()) pad_bit = eval.get(expr->expr_width()-1); else pad_bit = verinum::V0; } for (unsigned long idx = 0 ; idx < expr_width() ; idx += 1) { if ((bval >= 0) && ((unsigned long) bval < eval.len())) oval.set(idx, eval.get(bval)); else oval.set(idx, pad_bit); bval += 1; } oval.has_sign(has_sign()); NetEConst*res = new NetEConst(oval); eval_debug(this, res, false); return res; } static void print_ternary_cond(NetExpr*expr) { if (NetEConst*c = dynamic_cast(expr)) { cerr << c->value() << endl; return; } if (NetECReal*c = dynamic_cast(expr)) { cerr << c->value() << endl; return; } ivl_assert(*expr, 0); } /* * A ternary expression evaluation is controlled by the condition * expression. If the condition evaluates to true or false, then * return the evaluated true or false expression. If the condition * evaluates to x or z, then merge the constant bits of the true and * false expressions. */ NetExpr* NetETernary::eval_tree() { eval_expr(cond_); switch (const_logical(cond_)) { case C_0: eval_expr(false_val_); if (debug_eval_tree) { cerr << get_fileline() << ": debug: Evaluate ternary with " << "constant condition value: "; print_ternary_cond(cond_); cerr << get_fileline() << ": : Selecting false case: " << *false_val_ << endl; } // Elaborate the alternate expression to check for errors. eval_expr(true_val_); if (expr_type() == IVL_VT_REAL && false_val_->expr_type() != IVL_VT_REAL) { verireal f; if (get_real_arg_(false_val_, f)) { NetECReal*rc = new NetECReal(f); rc->set_line(*this); return rc; } } return false_val_->dup_expr(); case C_1: eval_expr(true_val_); if (debug_eval_tree) { cerr << get_fileline() << ": debug: Evaluate ternary with " << "constant condition value: "; print_ternary_cond(cond_); cerr << get_fileline() << ": : Selecting true case: " << *true_val_ << endl; } // Elaborate the alternate expression to check for errors. eval_expr(false_val_); if (expr_type() == IVL_VT_REAL && true_val_->expr_type() != IVL_VT_REAL) { verireal t; if (get_real_arg_(true_val_, t)) { NetECReal*rc = new NetECReal(t); rc->set_line(*this); return rc; } } return true_val_->dup_expr(); case C_X: break; default: return 0; } /* Here we have a more complex case. We need to evaluate both expressions down to constants then compare the values to build up a constant result. */ eval_expr(true_val_); eval_expr(false_val_); return blended_arguments_(true_val_, false_val_); } NetExpr*NetETernary::blended_arguments_(const NetExpr*te, const NetExpr*fe) const { const NetEConst*t = dynamic_cast(te); const NetEConst*f = dynamic_cast(fe); if (t == 0 || f == 0) { verireal tv, fv; if (!get_real_arg_(te, tv)) return 0; if (!get_real_arg_(fe, fv)) return 0; verireal val = verireal(0.0); if (tv.as_double() == fv.as_double()) val = tv; if (debug_eval_tree) { cerr << get_fileline() << ": debug: Evaluate ternary with " << "constant condition value: "; print_ternary_cond(cond_); cerr << get_fileline() << ": : Blending real cases " << "true=" << tv.as_double() << ", false=" << fv.as_double() << ", to get " << val << endl; } NetECReal*rc = new NetECReal(val); rc->set_line(*this); return rc; } unsigned tsize = t->expr_width(); unsigned fsize = f->expr_width(); /* Size of the result is the size of the widest operand. */ unsigned rsize = tsize > fsize? tsize : fsize; verinum val (verinum::V0, rsize); for (unsigned idx = 0 ; idx < rsize ; idx += 1) { verinum::V tv = idx < tsize? t->value().get(idx) : verinum::V0; verinum::V fv = idx < fsize? f->value().get(idx) : verinum::V0; if (tv == fv) val.set(idx, tv); else val.set(idx, verinum::Vx); } val.has_sign(has_sign()); if (debug_eval_tree) { cerr << get_fileline() << ": debug: Evaluate ternary with " << "constant condition value: "; print_ternary_cond(cond_); cerr << get_fileline() << ": : Blending cases to get " << val << endl; } NetEConst*rc = new NetEConst(val); rc->set_line(*this); return rc; } NetExpr* NetEUnary::eval_tree() { eval_expr(expr_); return eval_arguments_(expr_); } NetExpr* NetEUnary::eval_tree_real_(const NetExpr*ex) const { const NetECReal*val= dynamic_cast (ex); if (val == 0) return 0; double res_val = val->value().as_double(); switch (op_) { case '+': break; case '-': res_val = -res_val; break; case 'm': if (res_val < 0.0) res_val = -res_val; break; default: return 0; } NetECReal *res = new NetECReal( verireal(res_val) ); ivl_assert(*this, res); eval_debug(this, res, true); return res; } NetExpr* NetEUnary::eval_arguments_(const NetExpr*ex) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex); const NetEConst*rval = dynamic_cast(ex); if (rval == 0) return 0; verinum val = rval->value(); switch (op_) { case '+': /* Unary + is a no-op. */ break; case '-': val = -val; break; case 'm': if (!val.is_defined()) { for (unsigned idx = 0 ; idx < val.len() ; idx += 1) val.set(idx, verinum::Vx); } else if (val.is_negative()) { val = -val; } break; case '~': /* Bitwise not is even simpler than logical not. Just invert all the bits of the operand and make the new value with the same dimensions. */ for (unsigned idx = 0 ; idx < val.len() ; idx += 1) switch (val.get(idx)) { case verinum::V0: val.set(idx, verinum::V1); break; case verinum::V1: val.set(idx, verinum::V0); break; default: val.set(idx, verinum::Vx); } break; case '!': ivl_assert(*this, 0); default: return 0; } NetEConst *res = new NetEConst(val); ivl_assert(*this, res); eval_debug(this, res, false); return res; } NetEConst* NetEUReduce::eval_tree_real_(const NetExpr*ex) const { ivl_assert(*this, op_ == '!'); const NetECReal*val= dynamic_cast (ex); if (val == 0) return 0; verinum::V res = val->value().as_double() == 0.0 ? verinum::V1 : verinum::V0; NetEConst*tmp = new NetEConst(verinum(res, 1)); ivl_assert(*this, tmp); eval_debug(this, tmp, true); return tmp; } NetEConst* NetEUReduce::eval_arguments_(const NetExpr*ex) const { if (expr_type() == IVL_VT_REAL) return eval_tree_real_(ex); const NetEConst*rval = dynamic_cast(ex); if (rval == 0) return 0; verinum val = rval->value(); verinum::V res; bool invert = false; switch (op_) { case '!': { /* Evaluate the unary logical not by first scanning the operand value for V1 and Vx bits. If we find any V1 bits we know that the value is TRUE, so the result of ! is V0. If there are no V1 bits but there are some Vx/Vz bits, the result is unknown. Otherwise, the result is V1. */ bool v1 = false, vx = false; for (unsigned idx = 0 ; idx < val.len() && !v1 ; idx += 1) { switch (val.get(idx)) { case verinum::V0: break; case verinum::V1: v1 = true; break; default: vx = true; break; } } res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1); break; } case 'A': invert = true; // fallthrough case '&': { res = verinum::V1; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) res = res & val.get(idx); break; } case 'N': invert = true; // fallthrough case '|': { res = verinum::V0; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) res = res | val.get(idx); break; } case 'X': invert = true; // fallthrough case '^': { /* Reduction XOR. */ unsigned ones = 0, unknown = 0; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) switch (val.get(idx)) { case verinum::V0: break; case verinum::V1: ones += 1; break; default: unknown += 1; break; } if (unknown) res = verinum::Vx; else if (ones%2) res = verinum::V1; else res = verinum::V0; break; } default: return 0; } if (invert) res = ~res; NetEConst*tmp = new NetEConst(verinum(res, 1)); ivl_assert(*this, tmp); eval_debug(this, tmp, false); return tmp; } NetExpr* NetECast::eval_arguments_(const NetExpr*ex) const { NetExpr*res = 0; switch (op_) { case 'r': if (const NetEConst*val = dynamic_cast(ex)) { verireal res_val(val->value().as_double()); res = new NetECReal(res_val); } break; case '2': if (const NetEConst*val = dynamic_cast(ex)) { verinum res_val(val->value()); res_val.cast_to_int2(); if (expr_width() > 0) res_val = cast_to_width(res_val, expr_width()); res = new NetEConst(res_val); } // fallthrough case 'v': if (const NetECReal*val = dynamic_cast(ex)) { verinum res_val(val->value().as_double(), false); if (expr_width() > 0) res_val = cast_to_width(res_val, expr_width()); res = new NetEConst(res_val); } break; default: ivl_assert(*this, 0); return 0; } if (res == 0) return 0; ivl_assert(*this, res); eval_debug(this, res, op_ == 'r'); return res; } NetEConst* NetESFunc::evaluate_clog2_(const NetExpr*arg_) const { const NetEConst*tmpi = dynamic_cast(arg_); const NetECReal*tmpr = dynamic_cast(arg_); if (tmpi == 0 && tmpr == 0) return 0; verinum arg; if (tmpi) { arg = tmpi->value(); } else { arg = verinum(tmpr->value().as_double(), true); } NetEConst*rtn; /* If we have an x in the verinum we return 'bx. */ if (!arg.is_defined()) { verinum tmp (verinum::Vx, integer_width); tmp.has_sign(true); rtn = new NetEConst(tmp); ivl_assert(*this, rtn); } else { bool is_neg = false; uint64_t res = 0; if (arg.is_negative()) { is_neg = true; // If the length is not defined, then work with // the trimmed version of the number. if (! arg.has_len()) arg = trim_vnum(arg); } arg.has_sign(false); // $unsigned() if (!arg.is_zero()) { arg = arg - verinum((uint64_t)1, 1); while (!arg.is_zero()) { res += 1; arg = arg >> 1; } } if (is_neg && res < integer_width) res = integer_width; verinum tmp (res, integer_width); tmp.has_sign(true); rtn = new NetEConst(tmp); ivl_assert(*this, rtn); } eval_debug(this, rtn, false); return rtn; } NetEConst* NetESFunc::evaluate_rtoi_(const NetExpr*arg_) const { const NetEConst*tmpi = dynamic_cast(arg_); const NetECReal*tmpr = dynamic_cast(arg_); if (tmpi == 0 && tmpr == 0) return 0; /* If the argument is already a bit based value just extend/trim it * to the integer width and translate all undefined bits to zero. */ if (tmpi) { verinum arg = verinum(tmpi->value(), integer_width); arg.cast_to_int2(); return new NetEConst(arg); } /* Get the value of the real argument as a bit based value and then * extend/trim it to the integer width. */ double arg = tmpr->value().as_double(); if (arg >= 0.0) arg = floor(arg); else arg = ceil(arg); return new NetEConst(verinum(verinum(arg, false), integer_width)); } NetECReal* NetESFunc::evaluate_itor_(const NetExpr*arg_) const { const NetEConst*tmpi = dynamic_cast(arg_); const NetECReal*tmpr = dynamic_cast(arg_); if (tmpi == 0 && tmpr == 0) return 0; /* If the argument is already a real value round it, but NaN and * +/- infinity need to be translated to 0.0. */ if (tmpr) { double arg = tmpr->value().as_double(); /* Convert a NaN or +/- infinity to 0.0 since these convert * to 'bz which is then translated to 0.0. */ if (arg != arg || (arg && (arg == 0.5*arg))) { return new NetECReal(verireal(0.0)); } if (arg >= 0.0) arg = floor(arg + 0.5); else arg = ceil(arg - 0.5); return new NetECReal(verireal(arg)); } /* Convert the bit based value to a real value. */ double arg = tmpi->value().as_double(); return new NetECReal(verireal(arg)); } NetECReal* NetESFunc::evaluate_math_one_arg_(ID id, const NetExpr*arg_) const { const NetEConst*tmpi = dynamic_cast(arg_); const NetECReal*tmpr = dynamic_cast(arg_); NetECReal*res = 0; if (tmpi || tmpr) { double arg; if (tmpi) { arg = tmpi->value().as_double(); } else { arg = tmpr->value().as_double(); } switch (id) { case LN: res = new NetECReal(verireal(log(arg))); break; case LOG10: res = new NetECReal(verireal(log10(arg))); break; case EXP: res = new NetECReal(verireal(exp(arg))); break; case SQRT: res = new NetECReal(verireal(sqrt(arg))); break; case FLOOR: res = new NetECReal(verireal(floor(arg))); break; case CEIL: res = new NetECReal(verireal(ceil(arg))); break; case SIN: res = new NetECReal(verireal(sin(arg))); break; case COS: res = new NetECReal(verireal(cos(arg))); break; case TAN: res = new NetECReal(verireal(tan(arg))); break; case ASIN: res = new NetECReal(verireal(asin(arg))); break; case ACOS: res = new NetECReal(verireal(acos(arg))); break; case ATAN: res = new NetECReal(verireal(atan(arg))); break; case SINH: res = new NetECReal(verireal(sinh(arg))); break; case COSH: res = new NetECReal(verireal(cosh(arg))); break; case TANH: res = new NetECReal(verireal(tanh(arg))); break; case ASINH: res = new NetECReal(verireal(asinh(arg))); break; case ACOSH: res = new NetECReal(verireal(acosh(arg))); break; case ATANH: res = new NetECReal(verireal(atanh(arg))); break; default: ivl_assert(*this, 0); break; } ivl_assert(*this, res); } eval_debug(this, res, true); return res; } NetECReal* NetESFunc::evaluate_math_two_arg_(ID id, const NetExpr*arg0_, const NetExpr*arg1_) const { const NetEConst*tmpi0 = dynamic_cast(arg0_); const NetECReal*tmpr0 = dynamic_cast(arg0_); const NetEConst*tmpi1 = dynamic_cast(arg1_); const NetECReal*tmpr1 = dynamic_cast(arg1_); NetECReal*res = 0; if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) { double arg0, arg1; if (tmpi0) { arg0 = tmpi0->value().as_double(); } else { arg0 = tmpr0->value().as_double(); } if (tmpi1) { arg1 = tmpi1->value().as_double(); } else { arg1 = tmpr1->value().as_double(); } switch (id) { case POW: res = new NetECReal(verireal(pow(arg0, arg1))); break; case ATAN2: res = new NetECReal(verireal(atan2(arg0, arg1))); break; case HYPOT: res = new NetECReal(verireal(hypot(arg0, arg1))); break; default: ivl_assert(*this, 0); break; } ivl_assert(*this, res); } eval_debug(this, res, true); return res; } NetExpr* NetESFunc::evaluate_abs_(const NetExpr*arg_) const { NetExpr*res = 0; const NetEConst*tmpi = dynamic_cast(arg_); const NetECReal*tmpr = dynamic_cast(arg_); if (tmpi || tmpr) { double arg; if (tmpi) { arg = tmpi->value().as_double(); } else { arg = tmpr->value().as_double(); } res = new NetECReal(verireal(fabs(arg))); ivl_assert(*this, res); } eval_debug(this, res, true); return res; } NetExpr* NetESFunc::evaluate_min_max_(ID id, const NetExpr*arg0_, const NetExpr*arg1_) const { const NetEConst*tmpi0 = dynamic_cast(arg0_); const NetECReal*tmpr0 = dynamic_cast(arg0_); const NetEConst*tmpi1 = dynamic_cast(arg1_); const NetECReal*tmpr1 = dynamic_cast(arg1_); NetExpr*res = 0; if ((tmpi0 || tmpr0) && (tmpi1 || tmpr1)) { double arg0, arg1; if (tmpi0) { arg0 = tmpi0->value().as_double(); } else { arg0 = tmpr0->value().as_double(); } if (tmpi1) { arg1 = tmpi1->value().as_double(); } else { arg1 = tmpr1->value().as_double(); } switch (id) { case MIN: res = new NetECReal(verireal(arg0 < arg1 ? arg0 : arg1)); break; case MAX: res = new NetECReal(verireal(arg0 < arg1 ? arg1 : arg0)); break; default: ivl_assert(*this, 0); break; } ivl_assert(*this, res); } eval_debug(this, res, true); return res; } static void no_string_arg(const NetESFunc*info, unsigned arg_num) { cerr << info->get_fileline() << ": error: constant function " << info->name() << "() does not support a string argument (" << arg_num+1 << ")." << endl; } NetEConst* NetESFunc::evaluate_countbits_() const { const NetEConst*tmpi = dynamic_cast(parms_[0]); NetEConst*res = 0; if (tmpi) { verinum value = tmpi->value(); if (value.is_string()) { no_string_arg(this, 0); return 0; } /* Find which values need to be counted. */ bool count_0 = false; bool count_1 = false; bool count_z = false; bool count_x = false; for (unsigned arg=1; arg < parms_.size(); ++arg) { const NetEConst*argi = dynamic_cast(parms_[arg]); if (! argi) return 0; verinum check_for = argi->value(); if (check_for.is_string()) { no_string_arg(this, arg); return 0; } switch (check_for[0]) { case verinum::V0: count_0 = true; break; case verinum::V1: count_1 = true; break; case verinum::Vz: count_z = true; break; case verinum::Vx: count_x = true; break; } } /* Search each bit of the vector looking for the values to * be counted. */ int count = 0; for (unsigned bit=0; bit < value.len(); ++bit) { switch (value[bit]) { case verinum::V0: if (count_0) ++count; break; case verinum::V1: if (count_1) ++count; break; case verinum::Vz: if (count_z) ++count; break; case verinum::Vx: if (count_x) ++count; break; } } verinum tmp (count, integer_width); tmp.has_sign(true); res = new NetEConst(tmp); ivl_assert(*this, res); } return res; } NetEConst* NetESFunc::evaluate_countones_(const NetExpr* arg) const { const NetEConst*tmpi = dynamic_cast(arg); NetEConst*res = 0; if (tmpi) { verinum value = tmpi->value(); int count = 0; if (value.is_string()) { no_string_arg(this, 0); return 0; } for (unsigned bit=0; bit < value.len(); ++bit) { if (value[bit] == verinum::V1) ++count; } verinum tmp (count, integer_width); tmp.has_sign(true); res = new NetEConst(tmp); ivl_assert(*this, res); } return res; } /* Get the total number of dimensions for the given expression. */ NetEConst* NetESFunc::evaluate_dimensions_(const NetExpr*arg) const { const NetESignal*esig = dynamic_cast(arg); long res = 0; if (esig != 0) { const NetNet *sig = esig->sig(); res = sig->packed_dimensions() + sig->unpacked_dimensions(); /* Icarus does not think a string has a packed size so to * make these routines work correct add one if this is a * string data type. */ if (sig->data_type() == IVL_VT_STRING) { ivl_assert(*this, sig->packed_dimensions() == 0); res += 1; } } /* Return the result as an integer sized constant. */ return new NetEConst(verinum(verinum(res), integer_width)); } NetEConst* NetESFunc::evaluate_isunknown_(const NetExpr* arg) const { const NetEConst*tmpi = dynamic_cast(arg); NetEConst*res = 0; if (tmpi) { verinum value = tmpi->value(); unsigned is_unknown = 1; if (value.is_string()) { no_string_arg(this, 0); return 0; } if (value.is_defined()) is_unknown = 0; verinum tmp (is_unknown, 1U); tmp.has_sign(false); res = new NetEConst(tmp); ivl_assert(*this, res); } return res; } static bool is_onehot(const verinum&value, bool zero_is_okay) { bool found_a_one = false; for (unsigned bit=0; bit < value.len(); ++bit) { if (value[bit] == verinum::V1) { if (found_a_one) return false; found_a_one = true; } } /* If no one bit was found return true if zero is okay. */ if (zero_is_okay) found_a_one = true; return found_a_one; } NetEConst* NetESFunc::evaluate_onehot_(const NetExpr* arg) const { const NetEConst*tmpi = dynamic_cast(arg); NetEConst*res = 0; if (tmpi) { verinum value = tmpi->value(); if (value.is_string()) { no_string_arg(this, 0); return 0; } verinum tmp (is_onehot(value, false), 1U); tmp.has_sign(false); res = new NetEConst(tmp); ivl_assert(*this, res); } return res; } NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* arg) const { const NetEConst*tmpi = dynamic_cast(arg); NetEConst*res = 0; if (tmpi) { verinum value = tmpi->value(); if (value.is_string()) { no_string_arg(this, 0); return 0; } verinum tmp (is_onehot(value, true), 1U); tmp.has_sign(false); res = new NetEConst(tmp); ivl_assert(*this, res); } return res; } /* Get the number of unpacked dimensions for the given expression. */ NetEConst* NetESFunc::evaluate_unpacked_dimensions_(const NetExpr*arg) const { const NetESignal*esig = dynamic_cast(arg); long res = 0; if (esig != 0) { const NetNet *sig = esig->sig(); res = sig->unpacked_dimensions(); } /* Return the result as an integer sized constant. */ return new NetEConst(verinum(verinum(res), integer_width)); } /* This code assumes that the dimension value will fit in a long. * Return true if no constant dimension value is available. */ static bool check_dimension(const NetExpr*dim_expr, long &dim) { const NetEConst*dimi = dynamic_cast(dim_expr); const NetECReal*dimr = dynamic_cast(dim_expr); if (dimi == 0 && dimr == 0) return true; if (dimi) dim = dimi->value().as_long(); if (dimr) dim = dimr->value().as_long(); return false; } /* Get the left and right values for the argument at the given dimension * if it exists. Return true if no values are available. Set defer to true * if this should be handled in the run time. */ static bool get_array_info(const NetExpr*arg, long dim, long &left, long &right, bool&defer) { if (const NetEConstParam*param = dynamic_cast(arg)) { ivl_assert(*arg, dim == 1); left = param->expr_width() - 1; right = 0; return false; } /* The argument must be a signal that has enough dimensions. */ const NetESignal*esig = dynamic_cast(arg); if (esig == 0) return true; const NetNet *sig = esig->sig(); /* A string or dynamic array must be handled by the run time. */ switch (sig->data_type()) { case IVL_VT_DARRAY: case IVL_VT_QUEUE: case IVL_VT_STRING: defer = true; return true; break; default: break; } long pdims = sig->packed_dimensions(); long updims = sig->unpacked_dimensions(); if (dim > (pdims + updims)) return true; /* Get the appropriate unpacked or packed dimension information. */ if (dim > updims) { const vector&dim_vals = sig->packed_dims(); const netrange_t&range = dim_vals[dim-updims-1]; left = range.get_msb(); right = range.get_lsb(); } else { const vector&dim_vals = sig->unpacked_dims(); const netrange_t&range = dim_vals[dim-1]; left = range.get_msb(); right = range.get_lsb(); } return false; } /* Calculate the array property functions. */ NetEConst* NetESFunc::evaluate_array_funcs_(ID id, const NetExpr*arg0, const NetExpr*arg1) const { long dim = 0; /* Check to see if the dimension argument is constant. */ if (check_dimension(arg1, dim)) return 0; /* If dimension is less than 1 return undefined. */ if (dim < 1) { return new NetEConst(verinum(verinum::Vx, integer_width)); } /* Get the left/right information for this dimension if it exists. */ long left = 0; long right = 0; bool defer = false; if (get_array_info(arg0, dim, left, right, defer)) { /* If this is a string or dynamic array defer this function * call since the left/right information is dynamic and is * not available yet. */ if (defer) return 0; return new NetEConst(verinum(verinum::Vx, integer_width)); } /* Calculate the appropriate array function result. */ long res; switch (id) { case HIGH: res = (right > left) ? right : left; break; case INCR: res = (right > left) ? -1 : 1; break; case LEFT: res = left; break; case LOW: res = (right > left) ? left : right; break; case RIGHT: res = right; break; case SIZE: res = (right > left) ? right - left : left - right; res += 1; break; default: res = 0; ivl_assert(*this, 0); } /* Return the result as an integer sized constant. */ return new NetEConst(verinum(verinum(res), integer_width)); } /* Make a constant one value that can be used by the one argument * array properties calls. */ const NetEConst* NetESFunc::const_one_ = new NetEConst(verinum(1U, 32U)); NetExpr* NetESFunc::evaluate_one_arg_(ID id, const NetExpr*arg) const { switch (id) { case ABS: return evaluate_abs_(arg); case CLOG2: return evaluate_clog2_(arg); case CTONES: return evaluate_countones_(arg); case DIMS: return evaluate_dimensions_(arg); /* The array functions are handled together. */ case HIGH: case INCR: case LEFT: case LOW: case RIGHT: case SIZE: return evaluate_array_funcs_(id, arg, const_one_); case ISUNKN: return evaluate_isunknown_(arg); case ITOR: return evaluate_itor_(arg); case ONEHT: return evaluate_onehot_(arg); case ONEHT0: return evaluate_onehot0_(arg); case RTOI: return evaluate_rtoi_(arg); case UPDIMS: return evaluate_unpacked_dimensions_(arg); default: return evaluate_math_one_arg_(id, arg); } } NetExpr* NetESFunc::evaluate_two_arg_(ID id, const NetExpr*arg0, const NetExpr*arg1) const { switch (id) { case CTBITS: return evaluate_countbits_(); /* The array functions are handled together. */ case HIGH: case INCR: case LEFT: case LOW: case RIGHT: case SIZE: return evaluate_array_funcs_(id, arg0, arg1); case MAX: case MIN: return evaluate_min_max_(id, arg0, arg1); default: return evaluate_math_two_arg_(id, arg0, arg1); } } NetESFunc::ID NetESFunc::built_in_id_() const { static map built_in_func; static bool funcs_need_init = true; /* These functions are always available. */ if (funcs_need_init) { built_in_func["$itor"] = ITOR; built_in_func["$rtoi"] = RTOI; } /* These are available in 1364-2005 and later or if the Icarus misc * flag was given. */ if (funcs_need_init && ((generation_flag >= GN_VER2005) || gn_icarus_misc_flag)) { built_in_func["$acos" ] = ACOS; built_in_func["$acosh"] = ACOSH; built_in_func["$asin" ] = ASIN; built_in_func["$asinh"] = ASINH; built_in_func["$atan" ] = ATAN; built_in_func["$atanh"] = ATANH; built_in_func["$atan2"] = ATAN2; built_in_func["$ceil" ] = CEIL; built_in_func["$clog2"] = CLOG2; built_in_func["$cos" ] = COS; built_in_func["$cosh" ] = COSH; built_in_func["$exp" ] = EXP; built_in_func["$floor"] = FLOOR; built_in_func["$hypot"] = HYPOT; built_in_func["$ln" ] = LN; built_in_func["$log10"] = LOG10; built_in_func["$pow" ] = POW; built_in_func["$sin" ] = SIN; built_in_func["$sinh" ] = SINH; built_in_func["$sqrt" ] = SQRT; built_in_func["$tan" ] = TAN; built_in_func["$tanh" ] = TANH; } /* These are available in 1800-2005 and later. */ if (funcs_need_init && (generation_flag >= GN_VER2005_SV)) { built_in_func["$dimensions" ] = DIMS; built_in_func["$high" ] = HIGH; built_in_func["$increment" ] = INCR; built_in_func["$isunknown" ] = ISUNKN; built_in_func["$left" ] = LEFT; built_in_func["$low" ] = LOW; built_in_func["$onehot" ] = ONEHT; built_in_func["$onehot0" ] = ONEHT0; built_in_func["$right" ] = RIGHT; built_in_func["$size" ] = SIZE; built_in_func["$unpacked_dimensions" ] = UPDIMS; } /* This is available in 1800-2009 and later. */ if (funcs_need_init && (generation_flag >= GN_VER2009)) { built_in_func["$countones" ] = CTONES; } /* This is available in 1800-2012 and later. */ if (funcs_need_init && (generation_flag >= GN_VER2012)) { built_in_func["$countbits" ] = CTBITS; } /* These are available in Verilog-A as Icarus extensions or if the * Icarus misc flag was given. */ if (funcs_need_init && (gn_verilog_ams_flag || gn_icarus_misc_flag)) { built_in_func["$abs"] = ABS; built_in_func["$max"] = MAX; built_in_func["$min"] = MIN; } /* The function table has been initialized at this point. */ funcs_need_init = false; /* Look for the given function and if it is not available return * NOT_BUILT_IN otherwise return the ID for the function. */ map::iterator idx = built_in_func.find(name_); if (idx == built_in_func.end()) return NOT_BUILT_IN; return idx->second; } NetExpr* NetESFunc::eval_tree() { /* We don't support evaluating overridden functions. */ if (is_overridden_) return 0; /* Get the ID for this system function if it can be used as a * constant function. */ ID id = built_in_id_(); if (id == NOT_BUILT_IN) return 0; switch (parms_.size()) { case 1: if (! takes_nargs_(id, 1)) { cerr << get_fileline() << ": error: constant function " << name_ << "() does not support a single argument." << endl; return 0; } eval_expr(parms_[0]); return evaluate_one_arg_(id, parms_[0]); case 2: if (! takes_nargs_(id, 2)) { cerr << get_fileline() << ": error: constant function " << name_ << "() does not support two arguments." << endl; return 0; } eval_expr(parms_[0]); eval_expr(parms_[1]); return evaluate_two_arg_(id, parms_[0], parms_[1]); default: /* Check to see if the function was called correctly. */ if (! takes_nargs_(id, parms_.size())) { cerr << get_fileline() << ": error: constant function " << name_ << "() does not support " << parms_.size() << " arguments." << endl; return 0; } if (id == CTBITS) { for (unsigned bit = 0; bit < parms_.size(); ++bit) { eval_expr(parms_[bit]); } return evaluate_countbits_(); } else { cerr << get_fileline() << ": sorry: constant functions with " << parms_.size() << " arguments are not supported: " << name_ << "()." << endl; } return 0; } } NetExpr* NetEUFunc::eval_tree() { // If we know the function cannot be evaluated as a constant, // give up now. if (!func()->is_const_func() || (func()->calls_sys_task() && !need_const_)) return 0; // If we neither want nor need to evaluate the function at // compile time, give up now. if (!opt_const_func && !need_const_) return 0; // Variables inside static functions can be accessed from outside // the function, so we can't be sure they are constant unless the // function was called in a constant context or the user has told // us this is safe. if (!func()->is_auto() && !need_const_ && (opt_const_func < 2)) return 0; // Run through the input parameters to check they are constants. for (unsigned idx = 0; idx < parm_count(); idx += 1) { if (dynamic_cast (parm(idx))) continue; if (dynamic_cast (parm(idx))) continue; return 0; } NetFuncDef*def = func_->func_def(); ivl_assert(*this, def); vectorargs(parms_.size()); for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) args[idx] = parms_[idx]->dup_expr(); NetExpr*res = def->evaluate_function(*this, args); return res; } iverilog-12_0/examples/000077500000000000000000000000001435245347300151655ustar00rootroot00000000000000iverilog-12_0/examples/clbff.v000066400000000000000000000064601435245347300164360ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This source file demonstrates how to synthesize CLB flip-flops from * Icarus Verilog, including giving the device an initial value. * * To compile this for XNF, try a command like this: * * iverilog -txnf -ppart=XC4010XLPQ160 -pncf=clbff.ncf -oclbff.xnf clbff.v * * That command causes an clbff.xnf and clbff.ncf file to be created. * Next, make the clbff.ngd file with the command: * * xnf2ngd -l xilinxun -u clbff.xnf clbff.ngo * ngdbuild clbff.ngo clbff.ngd * * Finally, map the file to fully render it in the target part. The * par command is the step that actually optimizes the design and tries * to meet timing constraints. * * map -o map.ncd clbff.ngd * par -w map.ncd clbff.ncd * * At this point, you can use the FPGA Editor to edit the clbff.ncd * file. Notice that the design uses two CLB flip-flops (possibly in * the same CLB) with their outputs ANDed together. If you go into the * block editor, you will see that the FF connected to main/Q<0> is * configured so start up reset, and the FF connected to main/Q<1> is * configured to start up set. */ module main; wire clk, iclk; wire i0, i1; wire out; wire [1:0] D = {i1, i0}; // This statement declares Q to be a 2 bit reg vector. The // initial assignment will cause the synthesized device to take // on an initial value specified here. Without the assignment, // the initial value is unspecified. (Verilog simulates it as 2'bx.) reg [1:0] Q = 2'b10; // This simple logic gate get turned into a function unit. // The par program will map this into a CLB F or G unit. and (out, Q[0], Q[1]); // This creates a global clock buffer. Notice how I attach an // attribute to the named gate to force it to be mapped to the // desired XNF device. This device will not be pulled into the // IOB associated with iclk because of the attribute. buf gbuf(clk, iclk); $attribute(gbuf, "XNF-LCA", "GCLK:O,I"); // This is mapped to a DFF. Since Q and D are two bits wide, the // code generator actually makes two DFF devices that share a // clock input. always @(posedge clk) Q <= D; // These attribute commands assign pins to the listed wires. // This can be done to wires and registers, as internally both // are treated as named signals. $attribute(out, "PAD", "o150"); $attribute(i0, "PAD", "i152"); $attribute(i1, "PAD", "i153"); $attribute(iclk,"PAD", "i154"); endmodule /* main */ iverilog-12_0/examples/des.v000066400000000000000000001354741435245347300161450ustar00rootroot00000000000000// // Name: testbench1.vhdl // // Author: Chris Eilbeck, chris@yordas.demon.co.uk // // Purpose: VHDL testbench for a DES encryptor. // // IP Status: Free use is hereby granted for all civil use including personal, educational and commercial use. // The use of this code for military, diplomatic or governmental purposes is specifically forbidden. // // Warranty: There is absolutely no warranty given with this code. You accept all responsibility for the use // of this code and any damage so caused. // // Vers Info: v0.1 14/11/1998 - Creation. // 14/11/1999 - Converted to Verilog (ajb) // module top; reg clk; reg [1:64] pt, key; wire [1:64] ct; integer i; des des(pt, key, ct, clk); initial begin $dumpfile("des.vcd"); $dumpvars(0, top); key = 64'h0000000000000000; pt = 64'h0000000000000000; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'hffffffffffffffff; pt = 64'hffffffffffffffff; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h3000000000000000; pt = 64'h1000000000000001; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h1111111111111111; pt = 64'h1111111111111111; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h0123456789abcdef; pt = 64'h1111111111111111; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h1111111111111111; pt = 64'h0123456789abcdef; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h0000000000000000; pt = 64'h0000000000000000; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'hfedcba9876543210; pt = 64'h0123456789abcdef; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h7ca110454a1a6e57; pt = 64'h01a1d6d039776742; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h0131d9619dc1376e; pt = 64'h5cd54ca83def57da; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h07a1133e4a0b2686; pt = 64'h0248d43806f67172; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h3849674c2602319e; pt = 64'h51454b582ddf440a; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h04b915ba43feb5b6; pt = 64'h42fd443059577fa2; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h0113b970fd34f2ce; pt = 64'h059b5e0851cf143a; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h0170f175468fb5e6; pt = 64'h0756d8e0774761d2; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h43297fad38e373fe; pt = 64'h762514b829bf486a; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h07a7137045da2a16; pt = 64'h3bdd119049372802; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h04689104c2fd3b2f; pt = 64'h26955f6835af609a; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h37d06bb516cb7546; pt = 64'h164d5e404f275232; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h1f08260d1ac2465e; pt = 64'h6b056e18759f5cca; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h584023641aba6176; pt = 64'h004bd6ef09176062; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end key = 64'h025816164629b007; pt = 64'h480d39006ee762f2; for(i=0;i<16;i=i+1) begin #1 clk=0; #1 clk=1; end /* int testkeys[]= // key, pt, ct { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8ca64de9, 0xc1b123a7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7359b216, 0x3e4edc58, 0x30000000, 0x00000000, 0x10000000, 0x00000001, 0x958e6e62, 0x7a05557b, 0x11111111, 0x11111111, 0x11111111, 0x11111111, 0xf40379ab, 0x9e0ec533, 0x01234567, 0x89abcdef, 0x11111111, 0x11111111, 0x17668dfc, 0x7292532d, 0x11111111, 0x11111111, 0x01234567, 0x89abcdef, 0x8a5ae1f8, 0x1ab8f2dd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8ca64de9, 0xc1b123a7, 0xfedcba98, 0x76543210, 0x01234567, 0x89abcdef, 0xed39d950, 0xfa74bcc4, 0x7ca11045, 0x4a1a6e57, 0x01a1d6d0, 0x39776742, 0x690f5b0d, 0x9a26939b, 0x0131d961, 0x9dc1376e, 0x5cd54ca8, 0x3def57da, 0x7a389d10, 0x354bd271, 0x07a1133e, 0x4a0b2686, 0x0248d438, 0x06f67172, 0x868ebb51, 0xcab4599a, 0x3849674c, 0x2602319e, 0x51454b58, 0x2ddf440a, 0x7178876e, 0x01f19b2a, 0x04b915ba, 0x43feb5b6, 0x42fd4430, 0x59577fa2, 0xaf37fb42, 0x1f8c4095, 0x0113b970, 0xfd34f2ce, 0x059b5e08, 0x51cf143a, 0x86a560f1, 0x0ec6d85b, 0x0170f175, 0x468fb5e6, 0x0756d8e0, 0x774761d2, 0x0cd3da02, 0x0021dc09, 0x43297fad, 0x38e373fe, 0x762514b8, 0x29bf486a, 0xea676b2c, 0xb7db2b7a, 0x07a71370, 0x45da2a16, 0x3bdd1190, 0x49372802, 0xdfd64a81, 0x5caf1a0f, 0x04689104, 0xc2fd3b2f, 0x26955f68, 0x35af609a, 0x5c513c9c, 0x4886c088, 0x37d06bb5, 0x16cb7546, 0x164d5e40, 0x4f275232, 0x0a2aeeae, 0x3ff4ab77, 0x1f08260d, 0x1ac2465e, 0x6b056e18, 0x759f5cca, 0xef1bf03e, 0x5dfa575a, 0x58402364, 0x1aba6176, 0x004bd6ef, 0x09176062, 0x88bf0db6, 0xd70dee56, 0x02581616, 0x4629b007, 0x480d3900, 0x6ee762f2, 0xa1f99155, 0x41020b56, 0x49793ebc, 0x79b3258f, 0x437540c8, 0x698f3cfa, 0x6fbf1caf, 0xcffd0556, 0x4fb05e15, 0x15ab73a7, 0x072d43a0, 0x77075292, 0x2f22e49b, 0xab7ca1ac, 0x49e95d6d, 0x4ca229bf, 0x02fe5577, 0x8117f12a, 0x5a6b612c, 0xc26cce4a, 0x018310dc, 0x409b26d6, 0x1d9d5c50, 0x18f728c2, 0x5f4c038e, 0xd12b2e41, 0x1c587f1c, 0x13924fef, 0x30553228, 0x6d6f295a, 0x63fac0d0, 0x34d9f793, 0x01010101, 0x01010101, 0x01234567, 0x89abcdef, 0x617b3a0c, 0xe8f07100, 0x1f1f1f1f, 0x0e0e0e0e, 0x01234567, 0x89abcdef, 0xdb958605, 0xf8c8c606, 0xe0fee0fe, 0xf1fef1fe, 0x01234567, 0x89abcdef, 0xedbfd1c6, 0x6c29ccc7, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x355550b2, 0x150e2451, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xcaaaaf4d, 0xeaf1dbae, 0x01234567, 0x89abcdef, 0x00000000, 0x00000000, 0xd5d44ff7, 0x20683d0d, 0xfedcba98, 0x76543210, 0xffffffff, 0xffffffff, 0x2a2bb008, 0xdf97c2f2, }; */ end endmodule module des(pt, key, ct, clk); input [1:64] pt; input [1:64] key; output [1:64] ct; input clk; wire [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; wire [1:32] l0x,l1x,l2x,l3x,l4x,l5x,l6x,l7x,l8x,l9x,l10x,l11x,l12x,l13x,l14x,l15x,l16x; wire [1:32] r0x,r1x,r2x,r3x,r4x,r5x,r6x,r7x,r8x,r9x,r10x,r11x,r12x,r13x,r14x,r15x,r16x; keysched keysched(key, k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x); ip ip(pt, l0x, r0x); roundfunc round1(clk, l0x, r0x, l1x, r1x, k1x); roundfunc round2(clk, l1x, r1x, l2x, r2x, k2x); roundfunc round3(clk, l2x, r2x, l3x, r3x, k3x); roundfunc round4(clk, l3x, r3x, l4x, r4x, k4x); roundfunc round5(clk, l4x, r4x, l5x, r5x, k5x); roundfunc round6(clk, l5x, r5x, l6x, r6x, k6x); roundfunc round7(clk, l6x, r6x, l7x, r7x, k7x); roundfunc round8(clk, l7x, r7x, l8x, r8x, k8x); roundfunc round9(clk, l8x, r8x, l9x, r9x, k9x); roundfunc round10(clk, l9x, r9x, l10x, r10x, k10x); roundfunc round11(clk, l10x, r10x, l11x, r11x, k11x); roundfunc round12(clk, l11x, r11x, l12x, r12x, k12x); roundfunc round13(clk, l12x, r12x, l13x, r13x, k13x); roundfunc round14(clk, l13x, r13x, l14x, r14x, k14x); roundfunc round15(clk, l14x, r14x, l15x, r15x, k15x); roundfunc round16(clk, l15x, r15x, l16x, r16x, k16x); fp fp(r16x, l16x, ct); endmodule module pc1(key, c0x, d0x); input [1:64] key; output [1:28] c0x, d0x; wire [1:56] XX; assign XX[1]=key[57]; assign XX[2]=key[49]; assign XX[3]=key[41]; assign XX[4]=key[33]; assign XX[5]=key[25]; assign XX[6]=key[17]; assign XX[7]=key[9]; assign XX[8]=key[1]; assign XX[9]=key[58]; assign XX[10]=key[50]; assign XX[11]=key[42]; assign XX[12]=key[34]; assign XX[13]=key[26]; assign XX[14]=key[18]; assign XX[15]=key[10]; assign XX[16]=key[2]; assign XX[17]=key[59]; assign XX[18]=key[51]; assign XX[19]=key[43]; assign XX[20]=key[35]; assign XX[21]=key[27]; assign XX[22]=key[19]; assign XX[23]=key[11]; assign XX[24]=key[3]; assign XX[25]=key[60]; assign XX[26]=key[52]; assign XX[27]=key[44]; assign XX[28]=key[36]; assign XX[29]=key[63]; assign XX[30]=key[55]; assign XX[31]=key[47]; assign XX[32]=key[39]; assign XX[33]=key[31]; assign XX[34]=key[23]; assign XX[35]=key[15]; assign XX[36]=key[7]; assign XX[37]=key[62]; assign XX[38]=key[54]; assign XX[39]=key[46]; assign XX[40]=key[38]; assign XX[41]=key[30]; assign XX[42]=key[22]; assign XX[43]=key[14]; assign XX[44]=key[6]; assign XX[45]=key[61]; assign XX[46]=key[53]; assign XX[47]=key[45]; assign XX[48]=key[37]; assign XX[49]=key[29]; assign XX[50]=key[21]; assign XX[51]=key[13]; assign XX[52]=key[5]; assign XX[53]=key[28]; assign XX[54]=key[20]; assign XX[55]=key[12]; assign XX[56]=key[4]; assign c0x=XX[1:28]; assign d0x=XX[29:56]; endmodule module pc2(c,d,k); input [1:28] c,d; output [1:48] k; wire [1:56] YY; assign YY[1:28]=c; assign YY[29:56]=d; assign k[1]=YY[14]; assign k[2]=YY[17]; assign k[3]=YY[11]; assign k[4]=YY[24]; assign k[5]=YY[1]; assign k[6]=YY[5]; assign k[7]=YY[3]; assign k[8]=YY[28]; assign k[9]=YY[15]; assign k[10]=YY[6]; assign k[11]=YY[21]; assign k[12]=YY[10]; assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8]; assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2]; assign k[25]=YY[41]; assign k[26]=YY[52]; assign k[27]=YY[31]; assign k[28]=YY[37]; assign k[29]=YY[47]; assign k[30]=YY[55]; assign k[31]=YY[30]; assign k[32]=YY[40]; assign k[33]=YY[51]; assign k[34]=YY[45]; assign k[35]=YY[33]; assign k[36]=YY[48]; assign k[37]=YY[44]; assign k[38]=YY[49]; assign k[39]=YY[39]; assign k[40]=YY[56]; assign k[41]=YY[34]; assign k[42]=YY[53]; assign k[43]=YY[46]; assign k[44]=YY[42]; assign k[45]=YY[50]; assign k[46]=YY[36]; assign k[47]=YY[29]; assign k[48]=YY[32]; endmodule module rol1(o, i); output [1:28] o; input [1:28] i; assign o={i[2:28],i[1]}; endmodule module rol2(o, i); output [1:28] o; input [1:28] i; assign o={i[3:28],i[1:2]}; endmodule module keysched(key,k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x); input [1:64] key; output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x; wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x; wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x; pc1 pc1(key, c0x, d0x); rol1 rc1(c1x, c0x); rol1 rd1(d1x, d0x); rol1 rc2(c2x, c1x); rol1 rd2(d2x, d1x); rol2 rc3(c3x, c2x); rol2 rd3(d3x, d2x); rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x); rol2 rc5(c5x, c4x); rol2 rd5(d5x, d4x); rol2 rc6(c6x, c5x); rol2 rd6(d6x, d5x); rol2 rc7(c7x, c6x); rol2 rd7(d7x, d6x); rol2 rc8(c8x, c7x); rol2 rd8(d8x, d7x); rol1 rc9(c9x, c8x); rol1 rd9(d9x, d8x); rol2 rca(c10x, c9x); rol2 rda(d10x, d9x); rol2 rcb(c11x, c10x); rol2 rdb(d11x, d10x); rol2 rcc(c12x, c11x); rol2 rdc(d12x, d11x); rol2 rcd(c13x, c12x); rol2 rdd(d13x, d12x); rol2 rce(c14x, c13x); rol2 rde(d14x, d13x); rol2 rcf(c15x, c14x); rol2 rdf(d15x, d14x); rol1 rcg(c16x, c15x); rol1 rdg(d16x, d15x); pc2 pc2x1(c1x,d1x,k1x); pc2 pc2x2(c2x,d2x,k2x); pc2 pc2x3(c3x,d3x,k3x); pc2 pc2x4(c4x,d4x,k4x); pc2 pc2x5(c5x,d5x,k5x); pc2 pc2x6(c6x,d6x,k6x); pc2 pc2x7(c7x,d7x,k7x); pc2 pc2x8(c8x,d8x,k8x); pc2 pc2x9(c9x,d9x,k9x); pc2 pc2x10(c10x,d10x,k10x); pc2 pc2x11(c11x,d11x,k11x); pc2 pc2x12(c12x,d12x,k12x); pc2 pc2x13(c13x,d13x,k13x); pc2 pc2x14(c14x,d14x,k14x); pc2 pc2x15(c15x,d15x,k15x); pc2 pc2x16(c16x,d16x,k16x); endmodule module s1(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'he; 6'b000010 : so=4'h4; 6'b000100 : so=4'hd; 6'b000110 : so=4'h1; 6'b001000 : so=4'h2; 6'b001010 : so=4'hf; 6'b001100 : so=4'hb; 6'b001110 : so=4'h8; 6'b010000 : so=4'h3; 6'b010010 : so=4'ha; 6'b010100 : so=4'h6; 6'b010110 : so=4'hc; 6'b011000 : so=4'h5; 6'b011010 : so=4'h9; 6'b011100 : so=4'h0; 6'b011110 : so=4'h7; 6'b000001 : so=4'h0; 6'b000011 : so=4'hf; 6'b000101 : so=4'h7; 6'b000111 : so=4'h4; 6'b001001 : so=4'he; 6'b001011 : so=4'h2; 6'b001101 : so=4'hd; 6'b001111 : so=4'h1; 6'b010001 : so=4'ha; 6'b010011 : so=4'h6; 6'b010101 : so=4'hc; 6'b010111 : so=4'hb; 6'b011001 : so=4'h9; 6'b011011 : so=4'h5; 6'b011101 : so=4'h3; 6'b011111 : so=4'h8; 6'b100000 : so=4'h4; 6'b100010 : so=4'h1; 6'b100100 : so=4'he; 6'b100110 : so=4'h8; 6'b101000 : so=4'hd; 6'b101010 : so=4'h6; 6'b101100 : so=4'h2; 6'b101110 : so=4'hb; 6'b110000 : so=4'hf; 6'b110010 : so=4'hc; 6'b110100 : so=4'h9; 6'b110110 : so=4'h7; 6'b111000 : so=4'h3; 6'b111010 : so=4'ha; 6'b111100 : so=4'h5; 6'b111110 : so=4'h0; 6'b100001 : so=4'hf; 6'b100011 : so=4'hc; 6'b100101 : so=4'h8; 6'b100111 : so=4'h2; 6'b101001 : so=4'h4; 6'b101011 : so=4'h9; 6'b101101 : so=4'h1; 6'b101111 : so=4'h7; 6'b110001 : so=4'h5; 6'b110011 : so=4'hb; 6'b110101 : so=4'h3; 6'b110111 : so=4'he; 6'b111001 : so=4'ha; 6'b111011 : so=4'h0; 6'b111101 : so=4'h6; default so=4'hd; endcase endmodule module s2(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'hf; 6'b000010 : so=4'h1; 6'b000100 : so=4'h8; 6'b000110 : so=4'he; 6'b001000 : so=4'h6; 6'b001010 : so=4'hb; 6'b001100 : so=4'h3; 6'b001110 : so=4'h4; 6'b010000 : so=4'h9; 6'b010010 : so=4'h7; 6'b010100 : so=4'h2; 6'b010110 : so=4'hd; 6'b011000 : so=4'hc; 6'b011010 : so=4'h0; 6'b011100 : so=4'h5; 6'b011110 : so=4'ha; 6'b000001 : so=4'h3; 6'b000011 : so=4'hd; 6'b000101 : so=4'h4; 6'b000111 : so=4'h7; 6'b001001 : so=4'hf; 6'b001011 : so=4'h2; 6'b001101 : so=4'h8; 6'b001111 : so=4'he; 6'b010001 : so=4'hc; 6'b010011 : so=4'h0; 6'b010101 : so=4'h1; 6'b010111 : so=4'ha; 6'b011001 : so=4'h6; 6'b011011 : so=4'h9; 6'b011101 : so=4'hb; 6'b011111 : so=4'h5; 6'b100000 : so=4'h0; 6'b100010 : so=4'he; 6'b100100 : so=4'h7; 6'b100110 : so=4'hb; 6'b101000 : so=4'ha; 6'b101010 : so=4'h4; 6'b101100 : so=4'hd; 6'b101110 : so=4'h1; 6'b110000 : so=4'h5; 6'b110010 : so=4'h8; 6'b110100 : so=4'hc; 6'b110110 : so=4'h6; 6'b111000 : so=4'h9; 6'b111010 : so=4'h3; 6'b111100 : so=4'h2; 6'b111110 : so=4'hf; 6'b100001 : so=4'hd; 6'b100011 : so=4'h8; 6'b100101 : so=4'ha; 6'b100111 : so=4'h1; 6'b101001 : so=4'h3; 6'b101011 : so=4'hf; 6'b101101 : so=4'h4; 6'b101111 : so=4'h2; 6'b110001 : so=4'hb; 6'b110011 : so=4'h6; 6'b110101 : so=4'h7; 6'b110111 : so=4'hc; 6'b111001 : so=4'h0; 6'b111011 : so=4'h5; 6'b111101 : so=4'he; default so=4'h9; endcase endmodule module s3(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'ha; 6'b000010 : so=4'h0; 6'b000100 : so=4'h9; 6'b000110 : so=4'he; 6'b001000 : so=4'h6; 6'b001010 : so=4'h3; 6'b001100 : so=4'hf; 6'b001110 : so=4'h5; 6'b010000 : so=4'h1; 6'b010010 : so=4'hd; 6'b010100 : so=4'hc; 6'b010110 : so=4'h7; 6'b011000 : so=4'hb; 6'b011010 : so=4'h4; 6'b011100 : so=4'h2; 6'b011110 : so=4'h8; 6'b000001 : so=4'hd; 6'b000011 : so=4'h7; 6'b000101 : so=4'h0; 6'b000111 : so=4'h9; 6'b001001 : so=4'h3; 6'b001011 : so=4'h4; 6'b001101 : so=4'h6; 6'b001111 : so=4'ha; 6'b010001 : so=4'h2; 6'b010011 : so=4'h8; 6'b010101 : so=4'h5; 6'b010111 : so=4'he; 6'b011001 : so=4'hc; 6'b011011 : so=4'hb; 6'b011101 : so=4'hf; 6'b011111 : so=4'h1; 6'b100000 : so=4'hd; 6'b100010 : so=4'h6; 6'b100100 : so=4'h4; 6'b100110 : so=4'h9; 6'b101000 : so=4'h8; 6'b101010 : so=4'hf; 6'b101100 : so=4'h3; 6'b101110 : so=4'h0; 6'b110000 : so=4'hb; 6'b110010 : so=4'h1; 6'b110100 : so=4'h2; 6'b110110 : so=4'hc; 6'b111000 : so=4'h5; 6'b111010 : so=4'ha; 6'b111100 : so=4'he; 6'b111110 : so=4'h7; 6'b100001 : so=4'h1; 6'b100011 : so=4'ha; 6'b100101 : so=4'hd; 6'b100111 : so=4'h0; 6'b101001 : so=4'h6; 6'b101011 : so=4'h9; 6'b101101 : so=4'h8; 6'b101111 : so=4'h7; 6'b110001 : so=4'h4; 6'b110011 : so=4'hf; 6'b110101 : so=4'he; 6'b110111 : so=4'h3; 6'b111001 : so=4'hb; 6'b111011 : so=4'h5; 6'b111101 : so=4'h2; default so=4'hc; endcase endmodule module s4(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'h7; 6'b000010 : so=4'hd; 6'b000100 : so=4'he; 6'b000110 : so=4'h3; 6'b001000 : so=4'h0; 6'b001010 : so=4'h6; 6'b001100 : so=4'h9; 6'b001110 : so=4'ha; 6'b010000 : so=4'h1; 6'b010010 : so=4'h2; 6'b010100 : so=4'h8; 6'b010110 : so=4'h5; 6'b011000 : so=4'hb; 6'b011010 : so=4'hc; 6'b011100 : so=4'h4; 6'b011110 : so=4'hf; 6'b000001 : so=4'hd; 6'b000011 : so=4'h8; 6'b000101 : so=4'hb; 6'b000111 : so=4'h5; 6'b001001 : so=4'h6; 6'b001011 : so=4'hf; 6'b001101 : so=4'h0; 6'b001111 : so=4'h3; 6'b010001 : so=4'h4; 6'b010011 : so=4'h7; 6'b010101 : so=4'h2; 6'b010111 : so=4'hc; 6'b011001 : so=4'h1; 6'b011011 : so=4'ha; 6'b011101 : so=4'he; 6'b011111 : so=4'h9; 6'b100000 : so=4'ha; 6'b100010 : so=4'h6; 6'b100100 : so=4'h9; 6'b100110 : so=4'h0; 6'b101000 : so=4'hc; 6'b101010 : so=4'hb; 6'b101100 : so=4'h7; 6'b101110 : so=4'hd; 6'b110000 : so=4'hf; 6'b110010 : so=4'h1; 6'b110100 : so=4'h3; 6'b110110 : so=4'he; 6'b111000 : so=4'h5; 6'b111010 : so=4'h2; 6'b111100 : so=4'h8; 6'b111110 : so=4'h4; 6'b100001 : so=4'h3; 6'b100011 : so=4'hf; 6'b100101 : so=4'h0; 6'b100111 : so=4'h6; 6'b101001 : so=4'ha; 6'b101011 : so=4'h1; 6'b101101 : so=4'hd; 6'b101111 : so=4'h8; 6'b110001 : so=4'h9; 6'b110011 : so=4'h4; 6'b110101 : so=4'h5; 6'b110111 : so=4'hb; 6'b111001 : so=4'hc; 6'b111011 : so=4'h7; 6'b111101 : so=4'h2; default so=4'he; endcase endmodule module s5(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'h2; 6'b000010 : so=4'hc; 6'b000100 : so=4'h4; 6'b000110 : so=4'h1; 6'b001000 : so=4'h7; 6'b001010 : so=4'ha; 6'b001100 : so=4'hb; 6'b001110 : so=4'h6; 6'b010000 : so=4'h8; 6'b010010 : so=4'h5; 6'b010100 : so=4'h3; 6'b010110 : so=4'hf; 6'b011000 : so=4'hd; 6'b011010 : so=4'h0; 6'b011100 : so=4'he; 6'b011110 : so=4'h9; 6'b000001 : so=4'he; 6'b000011 : so=4'hb; 6'b000101 : so=4'h2; 6'b000111 : so=4'hc; 6'b001001 : so=4'h4; 6'b001011 : so=4'h7; 6'b001101 : so=4'hd; 6'b001111 : so=4'h1; 6'b010001 : so=4'h5; 6'b010011 : so=4'h0; 6'b010101 : so=4'hf; 6'b010111 : so=4'ha; 6'b011001 : so=4'h3; 6'b011011 : so=4'h9; 6'b011101 : so=4'h8; 6'b011111 : so=4'h6; 6'b100000 : so=4'h4; 6'b100010 : so=4'h2; 6'b100100 : so=4'h1; 6'b100110 : so=4'hb; 6'b101000 : so=4'ha; 6'b101010 : so=4'hd; 6'b101100 : so=4'h7; 6'b101110 : so=4'h8; 6'b110000 : so=4'hf; 6'b110010 : so=4'h9; 6'b110100 : so=4'hc; 6'b110110 : so=4'h5; 6'b111000 : so=4'h6; 6'b111010 : so=4'h3; 6'b111100 : so=4'h0; 6'b111110 : so=4'he; 6'b100001 : so=4'hb; 6'b100011 : so=4'h8; 6'b100101 : so=4'hc; 6'b100111 : so=4'h7; 6'b101001 : so=4'h1; 6'b101011 : so=4'he; 6'b101101 : so=4'h2; 6'b101111 : so=4'hd; 6'b110001 : so=4'h6; 6'b110011 : so=4'hf; 6'b110101 : so=4'h0; 6'b110111 : so=4'h9; 6'b111001 : so=4'ha; 6'b111011 : so=4'h4; 6'b111101 : so=4'h5; default so=4'h3; endcase endmodule module s6(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'hc; 6'b000010 : so=4'h1; 6'b000100 : so=4'ha; 6'b000110 : so=4'hf; 6'b001000 : so=4'h9; 6'b001010 : so=4'h2; 6'b001100 : so=4'h6; 6'b001110 : so=4'h8; 6'b010000 : so=4'h0; 6'b010010 : so=4'hd; 6'b010100 : so=4'h3; 6'b010110 : so=4'h4; 6'b011000 : so=4'he; 6'b011010 : so=4'h7; 6'b011100 : so=4'h5; 6'b011110 : so=4'hb; 6'b000001 : so=4'ha; 6'b000011 : so=4'hf; 6'b000101 : so=4'h4; 6'b000111 : so=4'h2; 6'b001001 : so=4'h7; 6'b001011 : so=4'hc; 6'b001101 : so=4'h9; 6'b001111 : so=4'h5; 6'b010001 : so=4'h6; 6'b010011 : so=4'h1; 6'b010101 : so=4'hd; 6'b010111 : so=4'he; 6'b011001 : so=4'h0; 6'b011011 : so=4'hb; 6'b011101 : so=4'h3; 6'b011111 : so=4'h8; 6'b100000 : so=4'h9; 6'b100010 : so=4'he; 6'b100100 : so=4'hf; 6'b100110 : so=4'h5; 6'b101000 : so=4'h2; 6'b101010 : so=4'h8; 6'b101100 : so=4'hc; 6'b101110 : so=4'h3; 6'b110000 : so=4'h7; 6'b110010 : so=4'h0; 6'b110100 : so=4'h4; 6'b110110 : so=4'ha; 6'b111000 : so=4'h1; 6'b111010 : so=4'hd; 6'b111100 : so=4'hb; 6'b111110 : so=4'h6; 6'b100001 : so=4'h4; 6'b100011 : so=4'h3; 6'b100101 : so=4'h2; 6'b100111 : so=4'hc; 6'b101001 : so=4'h9; 6'b101011 : so=4'h5; 6'b101101 : so=4'hf; 6'b101111 : so=4'ha; 6'b110001 : so=4'hb; 6'b110011 : so=4'he; 6'b110101 : so=4'h1; 6'b110111 : so=4'h7; 6'b111001 : so=4'h6; 6'b111011 : so=4'h0; 6'b111101 : so=4'h8; default so=4'hd; endcase endmodule module s7(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'h4; 6'b000010 : so=4'hb; 6'b000100 : so=4'h2; 6'b000110 : so=4'he; 6'b001000 : so=4'hf; 6'b001010 : so=4'h0; 6'b001100 : so=4'h8; 6'b001110 : so=4'hd; 6'b010000 : so=4'h3; 6'b010010 : so=4'hc; 6'b010100 : so=4'h9; 6'b010110 : so=4'h7; 6'b011000 : so=4'h5; 6'b011010 : so=4'ha; 6'b011100 : so=4'h6; 6'b011110 : so=4'h1; 6'b000001 : so=4'hd; 6'b000011 : so=4'h0; 6'b000101 : so=4'hb; 6'b000111 : so=4'h7; 6'b001001 : so=4'h4; 6'b001011 : so=4'h9; 6'b001101 : so=4'h1; 6'b001111 : so=4'ha; 6'b010001 : so=4'he; 6'b010011 : so=4'h3; 6'b010101 : so=4'h5; 6'b010111 : so=4'hc; 6'b011001 : so=4'h2; 6'b011011 : so=4'hf; 6'b011101 : so=4'h8; 6'b011111 : so=4'h6; 6'b100000 : so=4'h1; 6'b100010 : so=4'h4; 6'b100100 : so=4'hb; 6'b100110 : so=4'hd; 6'b101000 : so=4'hc; 6'b101010 : so=4'h3; 6'b101100 : so=4'h7; 6'b101110 : so=4'he; 6'b110000 : so=4'ha; 6'b110010 : so=4'hf; 6'b110100 : so=4'h6; 6'b110110 : so=4'h8; 6'b111000 : so=4'h0; 6'b111010 : so=4'h5; 6'b111100 : so=4'h9; 6'b111110 : so=4'h2; 6'b100001 : so=4'h6; 6'b100011 : so=4'hb; 6'b100101 : so=4'hd; 6'b100111 : so=4'h8; 6'b101001 : so=4'h1; 6'b101011 : so=4'h4; 6'b101101 : so=4'ha; 6'b101111 : so=4'h7; 6'b110001 : so=4'h9; 6'b110011 : so=4'h5; 6'b110101 : so=4'h0; 6'b110111 : so=4'hf; 6'b111001 : so=4'he; 6'b111011 : so=4'h2; 6'b111101 : so=4'h3; default so=4'hc; endcase endmodule module s8(clk, b, so); input clk; input [1:6] b; output [1:4] so; reg [1:4] so; always @(posedge clk) casex(b) 6'b000000 : so=4'hd; 6'b000010 : so=4'h2; 6'b000100 : so=4'h8; 6'b000110 : so=4'h4; 6'b001000 : so=4'h6; 6'b001010 : so=4'hf; 6'b001100 : so=4'hb; 6'b001110 : so=4'h1; 6'b010000 : so=4'ha; 6'b010010 : so=4'h9; 6'b010100 : so=4'h3; 6'b010110 : so=4'he; 6'b011000 : so=4'h5; 6'b011010 : so=4'h0; 6'b011100 : so=4'hc; 6'b011110 : so=4'h7; 6'b000001 : so=4'h1; 6'b000011 : so=4'hf; 6'b000101 : so=4'hd; 6'b000111 : so=4'h8; 6'b001001 : so=4'ha; 6'b001011 : so=4'h3; 6'b001101 : so=4'h7; 6'b001111 : so=4'h4; 6'b010001 : so=4'hc; 6'b010011 : so=4'h5; 6'b010101 : so=4'h6; 6'b010111 : so=4'hb; 6'b011001 : so=4'h0; 6'b011011 : so=4'he; 6'b011101 : so=4'h9; 6'b011111 : so=4'h2; 6'b100000 : so=4'h7; 6'b100010 : so=4'hb; 6'b100100 : so=4'h4; 6'b100110 : so=4'h1; 6'b101000 : so=4'h9; 6'b101010 : so=4'hc; 6'b101100 : so=4'he; 6'b101110 : so=4'h2; 6'b110000 : so=4'h0; 6'b110010 : so=4'h6; 6'b110100 : so=4'ha; 6'b110110 : so=4'hd; 6'b111000 : so=4'hf; 6'b111010 : so=4'h3; 6'b111100 : so=4'h5; 6'b111110 : so=4'h8; 6'b100001 : so=4'h2; 6'b100011 : so=4'h1; 6'b100101 : so=4'he; 6'b100111 : so=4'h7; 6'b101001 : so=4'h4; 6'b101011 : so=4'ha; 6'b101101 : so=4'h8; 6'b101111 : so=4'hd; 6'b110001 : so=4'hf; 6'b110011 : so=4'hc; 6'b110101 : so=4'h9; 6'b110111 : so=4'h0; 6'b111001 : so=4'h3; 6'b111011 : so=4'h5; 6'b111101 : so=4'h6; default so=4'hb; endcase endmodule module ip(pt, l0x, r0x); input [1:64] pt; output [1:32] l0x, r0x; assign l0x[1]=pt[58]; assign l0x[2]=pt[50]; assign l0x[3]=pt[42]; assign l0x[4]=pt[34]; assign l0x[5]=pt[26]; assign l0x[6]=pt[18]; assign l0x[7]=pt[10]; assign l0x[8]=pt[2]; assign l0x[9]=pt[60]; assign l0x[10]=pt[52]; assign l0x[11]=pt[44]; assign l0x[12]=pt[36]; assign l0x[13]=pt[28]; assign l0x[14]=pt[20]; assign l0x[15]=pt[12]; assign l0x[16]=pt[4]; assign l0x[17]=pt[62]; assign l0x[18]=pt[54]; assign l0x[19]=pt[46]; assign l0x[20]=pt[38]; assign l0x[21]=pt[30]; assign l0x[22]=pt[22]; assign l0x[23]=pt[14]; assign l0x[24]=pt[6]; assign l0x[25]=pt[64]; assign l0x[26]=pt[56]; assign l0x[27]=pt[48]; assign l0x[28]=pt[40]; assign l0x[29]=pt[32]; assign l0x[30]=pt[24]; assign l0x[31]=pt[16]; assign l0x[32]=pt[8]; assign r0x[1]=pt[57]; assign r0x[2]=pt[49]; assign r0x[3]=pt[41]; assign r0x[4]=pt[33]; assign r0x[5]=pt[25]; assign r0x[6]=pt[17]; assign r0x[7]=pt[9]; assign r0x[8]=pt[1]; assign r0x[9]=pt[59]; assign r0x[10]=pt[51]; assign r0x[11]=pt[43]; assign r0x[12]=pt[35]; assign r0x[13]=pt[27]; assign r0x[14]=pt[19]; assign r0x[15]=pt[11]; assign r0x[16]=pt[3]; assign r0x[17]=pt[61]; assign r0x[18]=pt[53]; assign r0x[19]=pt[45]; assign r0x[20]=pt[37]; assign r0x[21]=pt[29]; assign r0x[22]=pt[21]; assign r0x[23]=pt[13]; assign r0x[24]=pt[5]; assign r0x[25]=pt[63]; assign r0x[26]=pt[55]; assign r0x[27]=pt[47]; assign r0x[28]=pt[39]; assign r0x[29]=pt[31]; assign r0x[30]=pt[23]; assign r0x[31]=pt[15]; assign r0x[32]=pt[7]; endmodule module xp(ri, e); input [1:32] ri; output [1:48] e; assign e[1]=ri[32]; assign e[2]=ri[1]; assign e[3]=ri[2]; assign e[4]=ri[3]; assign e[5]=ri[4]; assign e[6]=ri[5]; assign e[7]=ri[4]; assign e[8]=ri[5]; assign e[9]=ri[6]; assign e[10]=ri[7]; assign e[11]=ri[8]; assign e[12]=ri[9]; assign e[13]=ri[8]; assign e[14]=ri[9]; assign e[15]=ri[10]; assign e[16]=ri[11]; assign e[17]=ri[12]; assign e[18]=ri[13]; assign e[19]=ri[12]; assign e[20]=ri[13]; assign e[21]=ri[14]; assign e[22]=ri[15]; assign e[23]=ri[16]; assign e[24]=ri[17]; assign e[25]=ri[16]; assign e[26]=ri[17]; assign e[27]=ri[18]; assign e[28]=ri[19]; assign e[29]=ri[20]; assign e[30]=ri[21]; assign e[31]=ri[20]; assign e[32]=ri[21]; assign e[33]=ri[22]; assign e[34]=ri[23]; assign e[35]=ri[24]; assign e[36]=ri[25]; assign e[37]=ri[24]; assign e[38]=ri[25]; assign e[39]=ri[26]; assign e[40]=ri[27]; assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1]; endmodule module desxor1(e,b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x,k); input [1:48] e; output [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x; input [1:48] k; wire [1:48] XX; assign XX = k ^ e; assign b1x = XX[1:6]; assign b2x = XX[7:12]; assign b3x = XX[13:18]; assign b4x = XX[19:24]; assign b5x = XX[25:30]; assign b6x = XX[31:36]; assign b7x = XX[37:42]; assign b8x = XX[43:48]; endmodule module pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x,ppo); input [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x; output [1:32] ppo; wire [1:32] XX; assign XX[1:4]=so1x; assign XX[5:8]=so2x; assign XX[9:12]=so3x; assign XX[13:16]=so4x; assign XX[17:20]=so5x; assign XX[21:24]=so6x; assign XX[25:28]=so7x; assign XX[29:32]=so8x; assign ppo[1]=XX[16]; assign ppo[2]=XX[7]; assign ppo[3]=XX[20]; assign ppo[4]=XX[21]; assign ppo[5]=XX[29]; assign ppo[6]=XX[12]; assign ppo[7]=XX[28]; assign ppo[8]=XX[17]; assign ppo[9]=XX[1]; assign ppo[10]=XX[15]; assign ppo[11]=XX[23]; assign ppo[12]=XX[26]; assign ppo[13]=XX[5]; assign ppo[14]=XX[18]; assign ppo[15]=XX[31]; assign ppo[16]=XX[10]; assign ppo[17]=XX[2]; assign ppo[18]=XX[8]; assign ppo[19]=XX[24]; assign ppo[20]=XX[14]; assign ppo[21]=XX[32]; assign ppo[22]=XX[27]; assign ppo[23]=XX[3]; assign ppo[24]=XX[9]; assign ppo[25]=XX[19]; assign ppo[26]=XX[13]; assign ppo[27]=XX[30]; assign ppo[28]=XX[6]; assign ppo[29]=XX[22]; assign ppo[30]=XX[11]; assign ppo[31]=XX[4]; assign ppo[32]=XX[25]; endmodule module desxor2(d,l,q); input [1:32] d,l; output [1:32] q; assign q = d ^ l; endmodule module roundfunc(clk, li, ri, lo, ro, k); input clk; input [1:32] li, ri; input [1:48] k; output [1:32] lo, ro; wire [1:48] e; wire [1:6] b1x,b2x,b3x,b4x,b5x,b6x,b7x,b8x; wire [1:4] so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x; wire [1:32] ppo; xp xp(ri, e); desxor1 desxor1(e, b1x, b2x, b3x, b4x, b5x, b6x, b7x, b8x, k); s1 s1(clk, b1x, so1x); s2 s2(clk, b2x, so2x); s3 s3(clk, b3x, so3x); s4 s4(clk, b4x, so4x); s5 s5(clk, b5x, so5x); s6 s6(clk, b6x, so6x); s7 s7(clk, b7x, so7x); s8 s8(clk, b8x, so8x); pp pp(so1x,so2x,so3x,so4x,so5x,so6x,so7x,so8x, ppo); desxor2 desxor2(ppo, li, ro); assign lo=ri; endmodule module fp(l,r,ct); input [1:32] l,r; output [1:64] ct; assign ct[1]=r[8]; assign ct[2]=l[8]; assign ct[3]=r[16]; assign ct[4]=l[16]; assign ct[5]=r[24]; assign ct[6]=l[24]; assign ct[7]=r[32]; assign ct[8]=l[32]; assign ct[9]=r[7]; assign ct[10]=l[7]; assign ct[11]=r[15]; assign ct[12]=l[15]; assign ct[13]=r[23]; assign ct[14]=l[23]; assign ct[15]=r[31]; assign ct[16]=l[31]; assign ct[17]=r[6]; assign ct[18]=l[6]; assign ct[19]=r[14]; assign ct[20]=l[14]; assign ct[21]=r[22]; assign ct[22]=l[22]; assign ct[23]=r[30]; assign ct[24]=l[30]; assign ct[25]=r[5]; assign ct[26]=l[5]; assign ct[27]=r[13]; assign ct[28]=l[13]; assign ct[29]=r[21]; assign ct[30]=l[21]; assign ct[31]=r[29]; assign ct[32]=l[29]; assign ct[33]=r[4]; assign ct[34]=l[4]; assign ct[35]=r[12]; assign ct[36]=l[12]; assign ct[37]=r[20]; assign ct[38]=l[20]; assign ct[39]=r[28]; assign ct[40]=l[28]; assign ct[41]=r[3]; assign ct[42]=l[3]; assign ct[43]=r[11]; assign ct[44]=l[11]; assign ct[45]=r[19]; assign ct[46]=l[19]; assign ct[47]=r[27]; assign ct[48]=l[27]; assign ct[49]=r[2]; assign ct[50]=l[2]; assign ct[51]=r[10]; assign ct[52]=l[10]; assign ct[53]=r[18]; assign ct[54]=l[18]; assign ct[55]=r[26]; assign ct[56]=l[26]; assign ct[57]=r[1]; assign ct[58]=l[1]; assign ct[59]=r[9]; assign ct[60]=l[9]; assign ct[61]=r[17]; assign ct[62]=l[17]; assign ct[63]=r[25]; assign ct[64]=l[25]; endmodule iverilog-12_0/examples/hello.vl000066400000000000000000000031451435245347300166360ustar00rootroot00000000000000/* * Copyright (c) 1998 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. */ /* * Here we have the canonical "Hello, World" program written in Verilog. * We simply print to the program output a simple message. This example * demonstrates the process of compiling and executing a program with * Icarus Verilog. * * Compile this program with the command: * * iverilog -ohello hello.vl * * After churning for a little while, the program will create the output * file "hello" which is compiled, linked and ready to run. Run this * program like so: * * vvp hello * * and the program will print the message to its output. Easy! For * more on how to make the iverilog command work, see the iverilog * manual page. */ module main(); initial begin $display("Hello, World"); $finish ; end endmodule iverilog-12_0/examples/hello_vpi.c000066400000000000000000000034301435245347300173120ustar00rootroot00000000000000/* * Copyright (c) 2002 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. */ /* * This file contains an example VPI module to demonstrate the tools * to create vpi modules. To compile this module, use the iverilog-vpi * command like so: * * iverilog-vpi hello_vpi.c * * The result is the hello_vpi.vpi module. See the hello_vpi.vl * program for example Verilog code to call this module. */ # include static PLI_INT32 my_hello_calltf(char *xx) { vpi_printf("Hello World, from VPI.\n"); return 0; } static void my_hello_register() { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$my_hello"; tf_data.calltf = my_hello_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])() = { my_hello_register, 0 }; iverilog-12_0/examples/hello_vpi.vl000066400000000000000000000032101435245347300175050ustar00rootroot00000000000000/* * Copyright (c) 2002 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. */ /* * Here we have the canonical "Hello, World" program written in Verilog, * with VPI. It uses the hello_vpi.vpi module that is compiled from * the hello_vpi.c program also in this directory. See the * hello_vpi.c for instructions on how to compile it. * * Compile this program with the command: * * iverilog -ohello_vpi hello_vpi.vl * * After churning for a little while, the program will create the output * file "hello" which is compiled, linked and ready to run. Run this * program like so: * * vvp -M. -mhello_vpi hello_vpi * * and the program will print the message to its output. Easy! For * more on how to make the iverilog command work, see the iverilog * manual page. */ module main(); initial begin $my_hello; $finish ; end endmodule iverilog-12_0/examples/outff.v000066400000000000000000000054171435245347300165060ustar00rootroot00000000000000/* * Copyright (c) 1998-1999 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. */ /* * IVL should generate an AND gate, and should make an OBUF and two * IBUF objects, along with the PAD objects. * * To compile this for XNF, try a command like this: * * iverilog -txnf -ppart=XC4010XLPQ160 -ooutff.xnf -pncf=outff.ncf outff.v * * That command causes an outff.xnf and outff.ncf file to be created. * Next, make the outff.ngd file with the command: * * xnf2ngd -l xilinxun -u outff.xnf outff.ngo * ngdbuild outff.ngo outff.ngd * * Finally, map the file to fully render it in the target part. The * par command is the step that actually optimizes the design and tries * to meet timing constraints. * * map -o map.ncd outff.ngd * par -w map.ncd outff.ncd * * At this point, you can use the FPGA Editor to edit the outff.ncd * file to see that the AND gate is in a CLB and the IOB for pin 150 * has its flip-flop in use, and that gbuf is a global buffer. */ module main; wire clk, iclk; wire i0, i1; wire out; reg o0; // This simple logic gate get turned into a function unit. // The par program will map this into a CLB F or G unit. and (out, i0, i1); // This creates a global clock buffer. Notice how I attach an // attribute to the named gate to force it to be mapped to the // desired XNF device. This device will not be pulled into the // IOB associated with iclk because of the attribute. buf gbuf(clk, iclk); $attribute(gbuf, "XNF-LCA", "GCLK:O,I"); // This is mapped to a DFF. Since o0 is connected to a PAD, it // is turned into a OUTFF so that it get placed into an IOB. always @(posedge clk) o0 = out; // These attribute commands assign pins to the listed wires. // This can be done to wires and registers, as internally both // are treated as named signals. $attribute(o0, "PAD", "o150"); $attribute(i0, "PAD", "i152"); $attribute(i1, "PAD", "i153"); $attribute(iclk,"PAD", "i154"); endmodule /* main */ iverilog-12_0/examples/pal_reg.v000066400000000000000000000104231435245347300167650ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This example shows how to use Icarus Verilog to generate PLD output. * The design is intended to fit into a 22v10 in a PLCC package, with * pin assignments locked down by design. The command to compile this * into a jedec file is; * * iverilog -tpal -ppart=generic-22v10-plcc -opal_reg.jed pal_reg.v * * The output file name (passed through the -o switch) can be * any file you desire. If the compilation and fitting all succeed, the * output file will be a JEDEC file that you can take to your favorite * PROM programmer to program the part. * * This source demonstrates some important principles of synthesizing * a design for a PLD, including how to specify synchronous logic, and * how to assign signals to pins. The pin assignment in particular is * part specific, and must be right for the fitting to succeed. */ /* * The register module is an 8 bit register that copies the input to * the output registers on the rising edge of the clk input. The * always statement creates a simple d-type flip-flop that is loaded * on the rising edge of the clock. * * The output drivers are controlled by a single active low output * enable. I used bufif0 devices in this example, but the exact same * thing can be achieved with a continuous assignment like so: * * assign out = oe? 8'hzz : Q; * * Many people prefer the expression form. It is true that it does * seem to express the intent a bit more clearly. */ module register (out, val, clk, oe); output [7:0] out; input [7:0] val; input clk, oe; reg [7:0] Q; wire [7:0] out; bufif0 drv[7:0](out, Q, oe); always @(posedge clk) Q = val; endmodule /* * The module pal is used to attach pin information to all the pins of * the device. We use this to lock down the pin assignments of the * synthesized result. The pin number assignments are for a 22v10 in * a PLCC package. * * Note that this module has no logic in it. It is a convention I use * that I put all the functionality in a separate module (seen above) * and isolate the Icarus Verilog specific $attribute madness into a * top-level module. The advantage of this style is that the entire * module can be `ifdef'ed out when doing simulation and you don't * need to worry that functionality will be affected. */ module pal; wire out7, out6, out5, out4, out3, out2, out1, out0; wire inp7, inp6, inp5, inp4, inp3, inp2, inp1, inp0; wire clk, oe; // The PAD attributes attach the wires to pins of the // device. Output pins are prefixed by a 'o', and input pins by an // 'i'. If not all the available output pins are used, then the // remaining are available for the synthesizer to drop internal // registers or extra logic layers. $attribute(out7, "PAD", "o27"); $attribute(out6, "PAD", "o26"); $attribute(out5, "PAD", "o25"); $attribute(out4, "PAD", "o24"); $attribute(out3, "PAD", "o23"); $attribute(out2, "PAD", "o21"); $attribute(out1, "PAD", "o20"); $attribute(out0, "PAD", "o19"); $attribute(inp7, "PAD", "i10"); $attribute(inp6, "PAD", "i9"); $attribute(inp5, "PAD", "i7"); $attribute(inp4, "PAD", "i6"); $attribute(inp3, "PAD", "i5"); $attribute(inp2, "PAD", "i4"); $attribute(inp1, "PAD", "i3"); $attribute(inp0, "PAD", "i2"); //$attribute(clk, "PAD", "CLK"); $attribute(oe, "PAD", "i13"); register dev({out7, out6, out5, out4, out3, out2, out1, out0}, {inp7, inp6, inp5, inp4, inp3, inp2, inp1, inp0}, clk, oe); endmodule // pal iverilog-12_0/examples/show_vcd.vl000066400000000000000000000075141435245347300173530ustar00rootroot00000000000000/* * Copyright (c) 1999 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. */ /* * This example program simulates a 16x1 ram, and is used as an * example for using VCD output and waveform viewers. * * Like any other Verilog simulation, compile this program with the * command: * * iverilog show_vcd.vl * * This will generate the show_vcd command in the current directory. * When you run the command, you will see the output from all the * calls to $display, but also there will be a dump file ``show_vcd.vcd''. * The name of this file is set by the statement: * * $dumpfile("show_vcd.vcd"); * * in the main module. The output file uses the standard VCD file format * so can be viewed using off-the-shelf waveform viewers. The remaining * steps describe how to use GTKWave to view the file. If you are using * a different viewer, see the documentation for that tool. * * To view the output generated by running show_vcd, start the GTKWave * viewer with the command: * * gtkwave show_vcd.vcd * * The GTKWave program will display its main window, and show in a small * status box (upper left corner) that it succeeded in loading the dump * file. However, there are no waveforms displayed yet. Select signals to * add to the waveform display using the menu selection: * * "Search --> Signal Search Tree" * * This will bring up a dialog box that shows in directory tree format * the signals of the program. Select the signals you wish to view, and * click one of the buttons on the bottom of the dialog box to display * the selected signals in the waveform window. Click "Exit" on the box * to get rid of it. * * The magic that makes all this work is contained in the $dumpfile and * $dumpvars system tasks. The $dumpfile task tells the simulation where * to write the VCD output. This task must be called once before the * $dumpvars task is called. * * The $dumpvars task tells the simulation what variables to write to * the VCD output. The first parameter is how far to descend while * scanning a scope, and the remaining parameters are signals or scope * names to include in the dump. If a scope name is given, all the * signals within the scope are dumped. If a wire or register name is * given, that signal is included. */ module ram16x1 (q, d, a, we, wclk); output q; input d; input [3:0] a; input we; input wclk; reg mem[15:0]; assign q = mem[a]; always @(posedge wclk) if (we) mem[a] = d; endmodule /* ram16x1 */ module main; wire q; reg d; reg [3:0] a; reg we, wclk; ram16x1 r1 (q, d, a, we, wclk); initial begin $dumpfile("show_vcd.vcd"); $dumpvars(1, main.r1); wclk = 0; we = 1; for (a = 0 ; a < 4'hf ; a = a + 1) begin d = a[0]; #1 wclk = 1; #1 wclk = 0; $display("r1[%x] == %b", a, q); end for (a = 0 ; a < 4'hf ; a = a + 1) #1 if (q !== a[0]) begin $display("FAILED -- mem[%h] !== %b", a, a[0]); $finish; end $display("PASSED"); end endmodule /* main */ iverilog-12_0/examples/sqrt-virtex.v000066400000000000000000000274131435245347300176730ustar00rootroot00000000000000/* * Copyright (c) 2002 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. * * $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $" */ /* * This module is a synthesizable square-root function. It is also a * detailed example of how to target Xilinx Virtex parts using * Icarus Verilog. In fact, for no particular reason other than to * be excessively specific, I will step through the process of * generating a design for a Spartan-II XC2S15-VQ100, and also how to * generate a generic library part for larger Virtex designs. * * In addition to Icarus Verilog, you will need implementation * software from Xilinx. As of this writing, this example was tested * with Foundation 4.2i, but it should work the same with ISE and * WebPACK software. * * This example source contains all the Verilog needed to do * everything described below. We use conditional compilation to * select the bits of Verilog that are needed to perform each specific * task. * * SIMULATE THE DESIGN * * This source file includes a simulation test bench. To compile the * program to include this test bench, use the command line: * * iverilog -DSIMULATE=1 -oa.out sqrt-virtex.v * * This generates the file "a.out" that can then be executed with the * command: * * vvp a.out * * This causes the simulation to run a long set of example sqrt * calculations. Each result is checked by the test bench to assure * that the result is valid. When it is done, the program prints * "PASSED" and finishes the simulation. * * When you take a close look at the "main" module below, you will see * that it uses Verilog constructs that are not synthesizable. This * is fine, as we will never try to synthesize it. * * LIBRARY PARTS * * One can use the sqrt32 module to generate an EDIF file suitable for * use as a library part. This part can be imported to the Xilinx * schematic editor, then placed like any other pre-existing * macro. One can also pass the generated EDIF as a precompiled macro * that other designers may use as they see fit. * * To make an EDIF file from the sqrt32 module, execute the command: * * iverilog -osqrt32.edf -tfpga -parch=virtex sqrt-virtex.v * * The -parch=virtex tells the code generator to generate code for the * virtex architecture family (we don't yet care what specific part) * and the -osqrt32.edf places the output into the file * sqrt32.edf. * * Without any preprocessor directives, the only module is the sqrt32 * module, so sqrt32 is compiled as the root. The ports of the module * are automatically made into ports of the sqrt32.edf netlist, and * the contents of the sqrt32 module are connected appropriately. * * COMPLETE CHIP DESIGNS * * To make a complete chip design, there are other bits that need to * be accounted for. Signals must be assigned to pins, and some * special devices may need to be created. We also want to write into * the EDIF file complete part information so that the implementation * tools know how to route the complete design. The command to compile * for our target part is: * * iverilog -ochip.edf -tfpga \ * -parch=virtex -ppart=XC2S15-VQ100 \ * -DMAKE_CHIP=1 sqrt-virtex.v * * This command uses the "chip" module as the root. This module in * turn has ports that are destined to be the pins of the completed * part. The -ppart= option gives complete part information, that is * in turn written into the EDIF file. This saves us the drudgery of * repeating that part number for later commands. * * The next steps involve Xilinx software, and to talk to Xilinx * software, the netlist must be in the form of an "ngd" file, a * binary netlist format. The command: * * ngdbuild chip.edf chip.ngd * * does the trick. The input to ngdbuild is the chip.edf file created * by Icarus Verilog, and the output is the chip.ngd file that the * implementation tools may read. From this point, it is best to refer * to Xilinx documentation for the software you are using, but the * quick summary is: * * map -o map.ncd chip.ngd * par -w map.ncd chip.ncd * * The result of this sequence of commands is the chip.ncd file that * is ready to be viewed by FPGA Edit, or converted to a bit stream, * or whatever. * * POST MAP SIMULATION * * Warm fuzzies are good, and retesting your design after the part * is mapped by the Xilinx backend tools is a cheap source of fuzzies. * The command to make a Verilog file out of the mapped design is: * * ngd2ver chip.ngd chip_root.v * * This command creates from the chip.ngd the file "chip_root.v" that * contains Verilog code that simulates the mapped design. This output * Verilog has the single root module "chip_root", which came from the * name of the root module when we were making the EDIF file in the * first place. The module has ports named just line the ports of the * chip_root module below. * * The generated Verilog uses the library in the directory * $(XILINX)/verilog/src/simprims. This directory comes with the ISE * WebPACK installation that you are using. Icarus Verilog is able to * simulate using that library. * * To compile a post-map simulation of the chip_root.v, use the * command: * * iverilog -DSIMULATE -DPOST_MAP -ob.out \ * -y $(XILINX)/verilog/src/simprims \ * sqrt-virtex.v chip_root.v \ * $(XILINX)/verilog/src/glbl.v * * This command line generates b.out from the source files * sqrt-virtex.v and chip_root.v (the latter from ngd2ver) * and the "-y " flag specifies the library directory that will * be needed. The glbl.v source file is also included to provide the * GSR and related signals. * * The POST_MAP compiler directive causes the GSR manipulations * included in the test bench to be compiled in, to simulate the chip * startup. Other than that, the test bench runs the post-map design * the same way the pre-synthesis design works. * * Run this design with the command: * * vvp b.out * * And there you go. */ `ifndef POST_MAP /* * This module approximates the square root of an unsigned 32bit * number. The algorithm works by doing a bit-wise binary search. * Starting from the most significant bit, the accumulated value * tries to put a 1 in the bit position. If that makes the square * too big for the input, the bit is left zero, otherwise it is set * in the result. This continues for each bit, decreasing in * significance, until all the bits are calculated or all the * remaining bits are zero. * * Since the result is an integer, this function really calculates * value of the expression: * * x = floor(sqrt(y)) * * where sqrt(y) is the exact square root of y and floor(N) is the * largest integer <= N. * * For 32 bit numbers, this will never run more than 16 iterations, * which amounts to 16 clocks. */ module sqrt32(clk, rdy, reset, x, .y(acc)); input clk; output rdy; input reset; input [31:0] x; output [15:0] acc; // acc holds the accumulated result, and acc2 is the accumulated // square of the accumulated result. reg [15:0] acc; reg [31:0] acc2; // Keep track of which bit I'm working on. reg [4:0] bitl; wire [15:0] bit = 1 << bitl; wire [31:0] bit2 = 1 << (bitl << 1); // The output is ready when the bitl counter underflows. wire rdy = bitl[4]; // guess holds the potential next values for acc, and guess2 holds // the square of that guess. The guess2 calculation is a little bit // subtle. The idea is that: // // guess2 = (acc + bit) * (acc + bit) // = (acc * acc) + 2*acc*bit + bit*bit // = acc2 + 2*acc*bit + bit2 // = acc2 + 2 * (acc< ((y + 1)*(y + 1))) begin $display("ERROR: y is too small"); $finish; end end $display("PASSED"); $finish; end endmodule // main `endif `ifdef MAKE_CHIP /* * This module represents the chip packaging that we intend to * generate. We bind pins here, and route the clock to the global * clock buffer. */ module chip_root(clk, rdy, reset, x, y); input clk; output rdy; input reset; input [31:0] x; output [15:0] y; wire clk_int; (* cellref="BUFG:O,I" *) buf gbuf (clk_int, clk); sqrt32 dut(.clk(clk_int), .reset(reset), .rdy(rdy), .x(x), .y(y)); /* Assign the clk to GCLK0, which is on pin P39. */ $attribute(clk, "PAD", "P39"); // We don't care where the remaining pins go, so set the pin number // to 0. This tells the implementation tools that we want a PAD, // but we don't care which. Also note the use of a comma (,) // separated list to assign pins to the bits of a vector. $attribute(rdy, "PAD", "0"); $attribute(reset, "PAD", "0"); $attribute(x, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); $attribute(y, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); endmodule // chip_root `endif iverilog-12_0/examples/sqrt.vl000066400000000000000000000076651435245347300165370ustar00rootroot00000000000000/* * Copyright (c) 1999 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. * * $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $" */ /* * This example shows that Icarus Verilog can run non-trivial * programs, too. This uses a variety of Verilog language features * to implement the module of a square-root device. The program * uses IEEE1364-1995 language features and should work correctly * on any Verilog compiler. * * Run the file with Icarus Verilog under UNIX using the command: * * % iverilog -osqrt sqrt.v * % ./sqrt */ /* * This module approximates the square root of an unsigned 32bit * number. The algorithm works by doing a bit-wise binary search. * Starting from the most significant bit, the accumulated value * tries to put a 1 in the bit position. If that makes the square * to big for the input, the bit is left zero, otherwise it is set * in the result. This continues for each bit, decreasing in * significance, until all the bits are calculated or all the * remaining bits are zero. * * Since the result is an integer, this function really calculates * value of the expression: * * x = floor(sqrt(y)) * * where sqrt(y) is the exact square root of y and floor(N) is the * largest integer <= N. * * For 32 bit numbers, this will never run more than 16 iterations, * which amounts to 16 clocks. */ module sqrt32(clk, rdy, reset, x, .y(acc)); input clk; output rdy; input reset; input [31:0] x; output [15:0] acc; // acc holds the accumulated result, and acc2 is the accumulated // square of the accumulated result. reg [15:0] acc; reg [31:0] acc2; // Keep track of which bit I'm working on. reg [4:0] bitl; wire [15:0] bit = 1 << bitl; wire [31:0] bit2 = 1 << (bitl << 1); // The output is ready when the bitl counter underflows. wire rdy = bitl[4]; // guess holds the potential next values for acc, and guess2 holds // the square of that guess. The guess2 calculation is a little bit // subtle. The idea is that: // // guess2 = (acc + bit) * (acc + bit) // = (acc * acc) + 2*acc*bit + bit*bit // = acc2 + 2*acc*bit + bit2 // = acc2 + 2 * (acc< %d", value, result); $finish; end initial begin clk = 0; reset = 1; $monitor($time,,"%m.acc = %b", root.acc); #100 value = 63; reset = 0; end endmodule /* main */ iverilog-12_0/examples/xnf_add.vl000066400000000000000000000072361435245347300171430ustar00rootroot00000000000000/* * Copyright (c) 1999 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. */ /* * This example demonstrates Icarus Verilog's ability to synthesize * efficient adders for Xilinx 4000 series FPGAs. The synthesis and * code generation makes an adder and translates that into XOR gates * and fast carry chain hardware. * * To compile this for XNF, try a command like this: * * iverilog -txnf -ppart=XC4010XLPQ160 -pncf=xnf_add.ncf -oxnf_add.xnf xnf_add.v * * That command causes an xnf_add.xnf and xnf_add.ncf file to be created. * Next, Use Xilinx Alliance or Foundation tools to make the xnf_add.ngd * file with the command: * * xnf2ngd -l xilinxun -u xnf_add.xnf xnf_add.ngo * ngdbuild xnf_add.ngo xnf_add.ngd * * Finally, map the file to fully render it in the target part. The * par command is the step that actually optimizes the design and tries * to meet timing constraints. * * map -o map.ncd xnf_add.ngd * par -w map.ncd xnf_add.ncd * * At this point, you can use the Xilinx FPGA Editor to edit the xnf_add.ncd * file and see the carry chains made up to support the adder. */ module main; wire [3:0] a, b; wire [3:0] out; wire carry; wire a0, a1, a2, a3, b0, b1, b2, b3; wire out0, out1, out2, out3; // This creates the actual adder. Note that we also create a link // to the carry output. The principle adder is 4 bits wide, so two // IOBs are used to to the actual addition. PAR will place them in // order along carry lines. An extra carry cell from below a[0] is // used in FORCE-0 mode to load the bottom carry node. // // The carry signal from the top CY device is used to drive the // main.carry wire shown here. It is managed in this case by using // an ADD-FG-CI CY device for the top pair and using the CLB above // the carry chain, with its CY in EXAMINE-CI mode, to put the carry // out through its G function unit. assign {carry, out} = a + b; // These attribute commands assign pins to the listed wires. // This can be done to wires and registers, as internally both // are treated as named signals. It doesn't work (yet) on vectors, // though, so break out the vectors with scalar assignments. assign a[0] = a0; assign a[1] = a1; assign a[2] = a2; assign a[3] = a3; $attribute(a0, "PAD", "i150"); $attribute(a1, "PAD", "i152"); $attribute(a2, "PAD", "i153"); $attribute(a3, "PAD", "i154"); assign b[0] = b0; assign b[1] = b1; assign b[2] = b2; assign b[3] = b3; $attribute(b0, "PAD", "i155"); $attribute(b1, "PAD", "i156"); $attribute(b2, "PAD", "i157"); $attribute(b3, "PAD", "i158"); assign out0 = out[0]; assign out1 = out[1]; assign out2 = out[2]; assign out3 = out[3]; $attribute(out0, "PAD", "o71"); $attribute(out1, "PAD", "o72"); $attribute(out2, "PAD", "o73"); $attribute(out3, "PAD", "o74"); $attribute(carry, "PAD", "o75"); endmodule /* main */ iverilog-12_0/examples/xram16x1.v000066400000000000000000000026411435245347300167460ustar00rootroot00000000000000/* * Copyright (c) 1999 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. */ // This example describes a 16x1 RAM that can be synthesized into // a CLB ram in a Xilinx FPGA. module ram16x1 (q, d, a, we, wclk); output q; input d; input [3:0] a; input we; input wclk; reg mem[15:0]; assign q = mem[a]; always @(posedge wclk) if (we) mem[a] = d; endmodule /* ram16x1 */ module main; wire q; reg d; reg [3:0] a; reg we, wclk; ram16x1 r1 (q, d, a, we, wclk); initial begin $monitor("q = %b", q); d = 0; wclk = 0; a = 5; we = 1; #1 wclk = 1; #1 wclk = 0; end endmodule /* main */ iverilog-12_0/exposenodes.cc000066400000000000000000000076421435245347300162230ustar00rootroot00000000000000/* * Copyright (c) 2016-2021 Martin Whitaker (icarus@martin-whitaker.me.uk) * * 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 # include # include "netlist.h" # include "functor.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; /* * The exposenodes functor is primarily provided for use by the vlog95 * target. To implement some LPM objects, it needs to take a bit or part * of one of the LPM inputs. If that input is not connected to a real * net in the design, we need to create a net at that point so that * there is something to which we can apply a bit or part select. This * has the effect of splitting the synthesised structure at that point. * Rather than creating a new net, we just look for a temporary net * created by the synthesis process (there should be at least one) and * reset its "local" flag. We also prepend another '_' to the synthetic * name to avoid name collisions when we recompile the vlog95 output * (because NetScope::local_symbol() doesn't actually check that the * name it generates is unique). */ struct exposenodes_functor : public functor_t { unsigned count; virtual void lpm_mux(Design*des, NetMux*obj); virtual void lpm_part_select(Design*des, NetPartSelect*obj); virtual void lpm_substitute(Design*des, NetSubstitute*obj); }; static bool expose_nexus(Nexus*nex) { NetNet*sig = 0; for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { // Don't expose nodes that are attached to constants if (dynamic_cast (cur->get_obj())) return false; if (dynamic_cast (cur->get_obj())) return false; NetNet*cur_sig = dynamic_cast (cur->get_obj()); if (cur_sig == 0) continue; if (!cur_sig->local_flag()) return false; sig = cur_sig; } assert(sig); ostringstream res; res << "_" << sig->name(); sig->rename(lex_strings.make(res.str())); sig->local_flag(false); return true; } /* * The vlog95 target implements a wide mux as a hierarchy of 2:1 muxes, * picking off one bit of the select input at each level of the hierarchy. */ void exposenodes_functor::lpm_mux(Design*, NetMux*obj) { if (obj->sel_width() == 1) return; if (expose_nexus(obj->pin_Sel().nexus())) count += 1; } /* * A VP part select is going to select a part from its input. */ void exposenodes_functor::lpm_part_select(Design*, NetPartSelect*obj) { if (obj->dir() != NetPartSelect::VP) return; if (expose_nexus(obj->pin(1).nexus())) count += 1; } /* * A substitute is going to select one or two parts from the wider input signal. */ void exposenodes_functor::lpm_substitute(Design*, NetSubstitute*obj) { if (expose_nexus(obj->pin(1).nexus())) count += 1; } void exposenodes(Design*des) { exposenodes_functor exposenodes; exposenodes.count = 0; if (verbose_flag) { cout << " ... Look for intermediate nodes" << endl << flush; } des->functor(&exposenodes); if (verbose_flag) { cout << " ... Exposed " << exposenodes.count << " intermediate signals." << endl << flush; } } iverilog-12_0/expr_synth.cc000066400000000000000000001343731435245347300160740ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "compiler.h" # include # include # include "netlist.h" # include "netvector.h" # include "netmisc.h" # include "ivl_assert.h" using namespace std; static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetEConst*expr) { verireal vrl(expr->value().as_double()); NetECReal rlval(vrl); NetNet* sig = rlval.synthesize(des, scope, 0); return sig; } /* Note that lsig, rsig and real_args are references. */ static bool process_binary_args(Design*des, NetScope*scope, NetExpr*root, NetExpr*left, NetExpr*right, NetNet*&lsig, NetNet*&rsig, bool&real_args) { if (left->expr_type() == IVL_VT_REAL || right->expr_type() == IVL_VT_REAL) { real_args = true; /* Convert the arguments to real. Handle the special cases of constants, which can be converted more directly. */ if (left->expr_type() == IVL_VT_REAL) { lsig = left->synthesize(des, scope, root); } else if (NetEConst*tmpc = dynamic_cast (left)) { lsig = convert_to_real_const(des, scope, tmpc); } else { NetNet*tmp = left->synthesize(des, scope, root); lsig = cast_to_real(des, scope, tmp); } if (right->expr_type() == IVL_VT_REAL) { rsig = right->synthesize(des, scope, root); } else if (NetEConst*tmpc = dynamic_cast (right)) { rsig = convert_to_real_const(des, scope, tmpc); } else { NetNet*tmp = right->synthesize(des, scope, root); rsig = cast_to_real(des, scope, tmp); } } else { real_args = false; lsig = left->synthesize(des, scope, root); rsig = right->synthesize(des, scope, root); } if (lsig == 0 || rsig == 0) return true; else return false; } NetNet* NetExpr::synthesize(Design*des, NetScope*, NetExpr*) { cerr << get_fileline() << ": internal error: cannot synthesize expression: " << *this << endl; des->errors += 1; return 0; } /* * Make an LPM_ADD_SUB device from addition operators. */ NetNet* NetEBAdd::synthesize(Design*des, NetScope*scope, NetExpr*root) { ivl_assert(*this, (op()=='+') || (op()=='-')); NetNet *lsig=0, *rsig=0; bool real_args=false; if (process_binary_args(des, scope, root, left_, right_, lsig, rsig, real_args)) { return 0; } ivl_assert(*this, expr_width() >= lsig->vector_width()); ivl_assert(*this, expr_width() >= rsig->vector_width()); unsigned width; if (expr_type() == IVL_VT_REAL) { width = 1; if (lsig->data_type() != IVL_VT_REAL) lsig = cast_to_real(des, scope, lsig); if (rsig->data_type() != IVL_VT_REAL) rsig = cast_to_real(des, scope, rsig); } else { lsig = pad_to_width(des, lsig, expr_width(), *this); rsig = pad_to_width(des, rsig, expr_width(), *this); assert(lsig->vector_width() == rsig->vector_width()); width=lsig->vector_width(); } perm_string path = lsig->scope()->local_symbol(); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); perm_string oname = osig->scope()->local_symbol(); NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width); adder->set_line(*this); connect(lsig->pin(0), adder->pin_DataA()); connect(rsig->pin(0), adder->pin_DataB()); connect(osig->pin(0), adder->pin_Result()); des->add_node(adder); switch (op()) { case '+': adder->attribute(perm_string::literal("LPM_Direction"), verinum("ADD")); break; case '-': adder->attribute(perm_string::literal("LPM_Direction"), verinum("SUB")); break; } return osig; } /* * The bitwise logic operators are turned into discrete gates pretty * easily. Synthesize the left and right sub-expressions to get * signals, then just connect a single gate to each bit of the vector * of the expression. */ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet*lsig = left_->synthesize(des, scope, root); NetNet*rsig = right_->synthesize(des, scope, root); if (lsig == 0 || rsig == 0) return 0; /* You cannot do bitwise operations on real values. */ if (lsig->data_type() == IVL_VT_REAL || rsig->data_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: " << human_readable_op(op_) << " operator may not have REAL operands." << endl; des->errors += 1; return 0; } unsigned width = expr_width(); if (rsig->vector_width() > width) width = rsig->vector_width(); lsig = pad_to_width(des, lsig, width, *this); rsig = pad_to_width(des, rsig, width, *this); assert(lsig->vector_width() == rsig->vector_width()); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); perm_string oname = scope->local_symbol(); NetLogic*gate; switch (op()) { case '&': gate = new NetLogic(scope, oname, 3, NetLogic::AND, width, true); break; case 'A': gate = new NetLogic(scope, oname, 3, NetLogic::NAND, width, true); break; case '|': gate = new NetLogic(scope, oname, 3, NetLogic::OR, width, true); break; case '^': gate = new NetLogic(scope, oname, 3, NetLogic::XOR, width, true); break; case 'O': gate = new NetLogic(scope, oname, 3, NetLogic::NOR, width, true); break; case 'X': gate = new NetLogic(scope, oname, 3, NetLogic::XNOR, width, true); break; default: gate = NULL; assert(0); } connect(osig->pin(0), gate->pin(0)); connect(lsig->pin(0), gate->pin(1)); connect(rsig->pin(0), gate->pin(2)); gate->set_line(*this); des->add_node(gate); return osig; } NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; if (process_binary_args(des, scope, root, left_, right_, lsig, rsig, real_args)) { return 0; } if (real_args) { width = 1; } else { width = lsig->vector_width(); if (rsig->vector_width() > width) width = rsig->vector_width(); if (lsig->get_signed()) lsig = pad_to_width_signed(des, lsig, width, *this); else lsig = pad_to_width(des, lsig, width, *this); if (rsig->get_signed()) rsig = pad_to_width_signed(des, rsig, width, *this); else rsig = pad_to_width(des, rsig, width, *this); } netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); // Test if the comparison is signed. // // Note 1: This is not the same as asking if the result is // signed. In fact, the result will typically be UNsigned. The // decision to make the comparison signed depends on the // operand expressions. // // Note 2: The operand expressions may be signed even if the // sig that comes out of synthesis is unsigned. The $signed() // function marks the expression but doesn't change the // underlying signals. bool signed_compare = left_->has_sign() && right_->has_sign(); if (debug_elaborate) { cerr << get_fileline() << ": debug: Comparison (" << op_ << ")" << " is " << (signed_compare? "signed" : "unsigned") << endl; cerr << get_fileline() << ": : lsig is " << (lsig->get_signed()? "signed" : "unsigned") << " rsig is " << (rsig->get_signed()? "signed" : "unsigned") << endl; } if (op_ == 'E' || op_ == 'N') { NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(), width, op_=='E' ? NetCaseCmp::EEQ : NetCaseCmp::NEQ); gate->set_line(*this); connect(gate->pin(0), osig->pin(0)); connect(gate->pin(1), lsig->pin(0)); connect(gate->pin(2), rsig->pin(0)); des->add_node(gate); return osig; } if (op_ == 'w' || op_ == 'W') { NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(), width, op_=='w' ? NetCaseCmp::WEQ : NetCaseCmp::WNE); gate->set_line(*this); connect(gate->pin(0), osig->pin(0)); connect(gate->pin(1), lsig->pin(0)); connect(gate->pin(2), rsig->pin(0)); des->add_node(gate); return osig; } /* Handle the special case of a single bit equality operation. Make an XNOR gate instead of a comparator. */ if ((width == 1) && (op_ == 'e') && !real_args) { NetLogic*gate = new NetLogic(scope, scope->local_symbol(), 3, NetLogic::XNOR, 1, true); gate->set_line(*this); connect(gate->pin(0), osig->pin(0)); connect(gate->pin(1), lsig->pin(0)); connect(gate->pin(2), rsig->pin(0)); des->add_node(gate); return osig; } /* Handle the special case of a single bit inequality operation. This is similar to single bit equality, but uses an XOR instead of an XNOR gate. */ if ((width == 1) && (op_ == 'n') && !real_args) { NetLogic*gate = new NetLogic(scope, scope->local_symbol(), 3, NetLogic::XOR, 1, true); gate->set_line(*this); connect(gate->pin(0), osig->pin(0)); connect(gate->pin(1), lsig->pin(0)); connect(gate->pin(2), rsig->pin(0)); des->add_node(gate); return osig; } NetCompare*dev = new NetCompare(scope, scope->local_symbol(), width); dev->set_line(*this); des->add_node(dev); connect(dev->pin_DataA(), lsig->pin(0)); connect(dev->pin_DataB(), rsig->pin(0)); switch (op_) { case '<': connect(dev->pin_ALB(), osig->pin(0)); dev->set_signed(signed_compare); break; case '>': connect(dev->pin_AGB(), osig->pin(0)); dev->set_signed(signed_compare); break; case 'E': // === ? if (real_args) { cerr << get_fileline() << ": error: Case equality may " "not have real operands." << endl; des->errors += 1; return 0; } // fallthrough case 'e': // == connect(dev->pin_AEB(), osig->pin(0)); break; case 'G': // >= connect(dev->pin_AGEB(), osig->pin(0)); dev->set_signed(signed_compare); break; case 'L': // <= connect(dev->pin_ALEB(), osig->pin(0)); dev->set_signed(signed_compare); break; case 'N': // !== if (real_args) { cerr << get_fileline() << ": error: Case inequality may " "not have real operands." << endl; des->errors += 1; return 0; } // fallthrough case 'n': // != connect(dev->pin_ANEB(), osig->pin(0)); break; default: cerr << get_fileline() << ": internal error: cannot synthesize " "comparison: " << *this << endl; des->errors += 1; return 0; } return osig; } NetNet* NetEBPow::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; if (process_binary_args(des, scope, root, left_, right_, lsig, rsig, real_args)) { return 0; } if (real_args) width = 1; else width = expr_width(); NetPow*powr = new NetPow(scope, scope->local_symbol(), width, lsig->vector_width(), rsig->vector_width()); powr->set_line(*this); des->add_node(powr); // The lpm_pwr object only cares about the signedness of the exponent. powr->set_signed( right_->has_sign() ); connect(powr->pin_DataA(), lsig->pin(0)); connect(powr->pin_DataB(), rsig->pin(0)); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(powr->pin_Result(), osig->pin(0)); return osig; } NetNet* NetEBMult::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; if (process_binary_args(des, scope, root, left_, right_, lsig, rsig, real_args)) { return 0; } if (real_args) width = 1; else width = expr_width(); NetMult*mult = new NetMult(scope, scope->local_symbol(), width, lsig->vector_width(), rsig->vector_width()); mult->set_line(*this); des->add_node(mult); mult->set_signed( has_sign() ); connect(mult->pin_DataA(), lsig->pin(0)); connect(mult->pin_DataB(), rsig->pin(0)); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(mult->pin_Result(), osig->pin(0)); return osig; } NetNet* NetEBDiv::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet *lsig=0, *rsig=0; unsigned width; bool real_args=false; if (process_binary_args(des, scope, root, left_, right_, lsig, rsig, real_args)) { return 0; } if (real_args) width = 1; else width = expr_width(); netvector_t*osig_vec = new netvector_t(lsig->data_type(), width-1, 0); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); switch (op()) { case '/': { NetDivide*div = new NetDivide(scope, scope->local_symbol(), width, lsig->vector_width(), rsig->vector_width()); div->set_line(*this); div->set_signed(has_sign()); des->add_node(div); connect(div->pin_DataA(), lsig->pin(0)); connect(div->pin_DataB(), rsig->pin(0)); connect(div->pin_Result(),osig->pin(0)); break; } case '%': { /* Baseline Verilog does not support the % operator with real arguments, but we allow it in our extended form. */ if (real_args && !gn_icarus_misc_flag) { cerr << get_fileline() << ": error: Modulus operator " "may not have REAL operands." << endl; des->errors += 1; return 0; } NetModulo*div = new NetModulo(scope, scope->local_symbol(), width, lsig->vector_width(), rsig->vector_width()); div->set_line(*this); div->set_signed(has_sign()); des->add_node(div); connect(div->pin_DataA(), lsig->pin(0)); connect(div->pin_DataB(), rsig->pin(0)); connect(div->pin_Result(),osig->pin(0)); break; } default: { cerr << get_fileline() << ": internal error: " << "NetEBDiv has unexpected op() code: " << op() << endl; des->errors += 1; delete osig; return 0; } } return osig; } NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet*lsig = left_->synthesize(des, scope, root); NetNet*rsig = right_->synthesize(des, scope, root); if (lsig == 0 || rsig == 0) return 0; /* Any real value should have already been converted to a bit value. */ if (lsig->data_type() == IVL_VT_REAL || rsig->data_type() == IVL_VT_REAL) { cerr << get_fileline() << ": internal error: " << human_readable_op(op_) << " is missing real to bit conversion." << endl; des->errors += 1; return 0; } NetLogic*olog; perm_string oname = scope->local_symbol(); /* Create the logic OR/AND gate. This has a single bit output, * with single bit inputs for the two operands. */ switch (op()) { case 'a': olog = new NetLogic(scope, oname, 3, NetLogic::AND, 1, true); break; case 'o': olog = new NetLogic(scope, oname, 3, NetLogic::OR, 1, true); break; case 'q': olog = new NetLogic(scope, oname, 3, NetLogic::IMPL, 1, true); break; case 'Q': olog = new NetLogic(scope, oname, 3, NetLogic::EQUIV, 1, true); break; default: cerr << get_fileline() << ": sorry: " << human_readable_op(op_) << " is not currently supported." << endl; des->errors += 1; return 0; } olog->set_line(*this); des->add_node(olog); netvector_t*osig_tmp = new netvector_t(expr_type()); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_tmp); osig->set_line(*this); osig->local_flag(true); connect(osig->pin(0), olog->pin(0)); /* The left and right operands have already been reduced to a * single bit value, so just connect then to the logic gate. */ assert(lsig->pin_count() == 1); connect(lsig->pin(0), olog->pin(1)); assert(rsig->pin_count() == 1); connect(rsig->pin(0), olog->pin(2)); return osig; } NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root) { eval_expr(right_); NetNet*lsig = left_->synthesize(des, scope, root); if (lsig == 0) return 0; /* Cannot shift a real values. */ if (lsig->data_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: shift operator (" << human_readable_op(op_) << ") cannot shift a real values." << endl; des->errors += 1; return 0; } const bool right_flag = op_ == 'r' || op_ == 'R'; const bool signed_flag = has_sign() && op_ == 'R'; /* Detect the special case where the shift amount is constant. Evaluate the shift amount, and simply reconnect the left operand to the output, but shifted. */ if (NetEConst*rcon = dynamic_cast(right_)) { verinum shift_v = rcon->value(); long shift = shift_v.as_long(); if (right_flag) shift = 0-shift; if (shift == 0) return lsig; netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); // ushift is the amount of pad created by the shift. unsigned long ushift = shift>=0? shift : -shift; ivl_assert(*this, ushift < osig->vector_width()); // part_width is the bits of the vector that survive the shift. unsigned long part_width = osig->vector_width() - ushift; // Create a part select to reduce the width of the lsig // to the amount left by the shift. NetPartSelect*psel = new NetPartSelect(lsig, shift<0? ushift : 0, part_width, NetPartSelect::VP, signed_flag && right_flag); psel->set_line(*this); des->add_node(psel); netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0); NetNet*psig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, psig_vec); psig->set_line(*this); psig->local_flag(true); connect(psig->pin(0), psel->pin(0)); // Handle the special case of a signed right shift. In // this case, use the NetSignExtend device to pad the // result to the desired width. if (signed_flag && right_flag) { NetSignExtend*pad = new NetSignExtend(scope, scope->local_symbol(), osig->vector_width()); pad->set_line(*this); des->add_node(pad); connect(pad->pin(1), psig->pin(0)); connect(pad->pin(0), osig->pin(0)); return osig; } // Other cases are handled by zero-extending on the // proper end. verinum znum (verinum::V0, ushift, true); NetConst*zcon = new NetConst(scope, scope->local_symbol(), znum); des->add_node(zcon); netvector_t*zsig_vec = new netvector_t(osig->data_type(), znum.len()-1, 0); NetNet*zsig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, zsig_vec); zsig->set_line(*this); zsig->local_flag(true); connect(zcon->pin(0), zsig->pin(0)); NetConcat*ccat = new NetConcat(scope, scope->local_symbol(), osig->vector_width(), 2); ccat->set_line(*this); des->add_node(ccat); connect(ccat->pin(0), osig->pin(0)); if (shift > 0) { // Left shift. connect(ccat->pin(1), zsig->pin(0)); connect(ccat->pin(2), psig->pin(0)); } else { // Right shift connect(ccat->pin(1), psig->pin(0)); connect(ccat->pin(2), zsig->pin(0)); } return osig; } NetNet*rsig = right_->synthesize(des, scope, root); if (rsig == 0) return 0; netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(), osig->vector_width(), rsig->vector_width(), right_flag, signed_flag); dev->set_line(*this); des->add_node(dev); connect(dev->pin_Result(), osig->pin(0)); assert(lsig->vector_width() == dev->width()); connect(dev->pin_Data(), lsig->pin(0)); connect(dev->pin_Distance(), rsig->pin(0)); return osig; } NetNet* NetEConcat::synthesize(Design*des, NetScope*scope, NetExpr*root) { /* First, synthesize the operands. */ unsigned num_parms = parms_.size(); NetNet**tmp = new NetNet*[parms_.size()]; bool flag = true; ivl_variable_type_t data_type = IVL_VT_NO_TYPE; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]->expr_width() == 0) { /* We need to synthesize a replication of zero. */ tmp[idx] = parms_[idx]->synthesize(des, scope, root); assert(tmp[idx] == 0); num_parms -= 1; } else { tmp[idx] = parms_[idx]->synthesize(des, scope, root); if (tmp[idx] == 0) flag = false; /* Set the data type to the first one found. */ switch (data_type) { case IVL_VT_NO_TYPE: data_type = tmp[idx]->data_type(); break; case IVL_VT_BOOL: if (tmp[idx]->data_type()==IVL_VT_LOGIC) data_type = IVL_VT_LOGIC; break; default: break; } } } if (flag == false) { delete[]tmp; return 0; } ivl_assert(*this, data_type != IVL_VT_NO_TYPE); /* If this is a replication of zero just return 0. */ if (expr_width() == 0) { delete[]tmp; return 0; } /* Make a NetNet object to carry the output vector. */ perm_string path = scope->local_symbol(); netvector_t*osig_vec = new netvector_t(data_type, expr_width()-1, 0); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); NetConcat*cncat = new NetConcat(scope, scope->local_symbol(), osig->vector_width(), num_parms * repeat()); cncat->set_line(*this); des->add_node(cncat); connect(cncat->pin(0), osig->pin(0)); unsigned count_input_width = 0; unsigned cur_pin = 1; for (unsigned rpt = 0; rpt < repeat(); rpt += 1) { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { unsigned concat_item = parms_.size()-idx-1; if (tmp[concat_item] == 0) continue; connect(cncat->pin(cur_pin), tmp[concat_item]->pin(0)); cur_pin += 1; count_input_width += tmp[concat_item]->vector_width(); } } if (count_input_width != osig->vector_width()) { cerr << get_fileline() << ": internal error: " << "NetEConcat input width = " << count_input_width << ", expecting " << osig->vector_width() << " (repeat=" << repeat() << ")" << endl; des->errors += 1; } delete[]tmp; return osig; } NetNet* NetEConst::synthesize(Design*des, NetScope*scope, NetExpr*) { perm_string path = scope->local_symbol(); unsigned width=expr_width(); if (width == 0) { cerr << get_fileline() << ": internal error: " << "Found a zero width constant!" << endl; return 0; } netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); NetConst*con = new NetConst(scope, scope->local_symbol(), value()); con->set_line(*this); des->add_node(con); connect(osig->pin(0), con->pin(0)); return osig; } /* * Create a NetLiteral object to represent real valued constants. */ NetNet* NetECReal::synthesize(Design*des, NetScope*scope, NetExpr*) { perm_string path = scope->local_symbol(); netvector_t*osig_vec = new netvector_t(IVL_VT_REAL); osig_vec->set_signed(has_sign()); NetNet*osig = new NetNet(scope, path, NetNet::WIRE, osig_vec); osig->set_line(*this); osig->local_flag(true); NetLiteral*con = new NetLiteral(scope, scope->local_symbol(), value_); con->set_line(*this); des->add_node(con); connect(osig->pin(0), con->pin(0)); return osig; } /* * The bitwise unary logic operator (there is only one) is turned * into discrete gates just as easily as the binary ones above. */ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet*isig = expr_->synthesize(des, scope, root); if (isig == 0) return 0; if (isig->data_type() == IVL_VT_REAL) { cerr << get_fileline() << ": error: bit-wise negation (" << human_readable_op(op_) << ") may not have a REAL operand." << endl; des->errors += 1; return 0; } unsigned width = isig->vector_width(); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); perm_string oname = scope->local_symbol(); NetLogic*gate; switch (op()) { case '~': gate = new NetLogic(scope, oname, 2, NetLogic::NOT, width, true); gate->set_line(*this); break; default: gate = NULL; assert(0); } connect(osig->pin(0), gate->pin(0)); connect(isig->pin(0), gate->pin(1)); des->add_node(gate); return osig; } NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root) { if (op_ == '+') return expr_->synthesize(des, scope, root); if (op_ == '-') { NetNet*sig = expr_->synthesize(des, scope, root); sig = sub_net_from(des, scope, 0, sig); return sig; } if (op_ == 'm') { NetNet*sub = expr_->synthesize(des, scope, root); if (expr_->has_sign() == false) return sub; netvector_t*sig_vec = new netvector_t(sub->data_type(), sub->vector_width()-1, 0); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sig_vec); sig->set_line(*this); sig->local_flag(true); NetAbs*tmp = new NetAbs(scope, scope->local_symbol(), sub->vector_width()); tmp->set_line(*this); des->add_node(tmp); connect(tmp->pin(1), sub->pin(0)); connect(tmp->pin(0), sig->pin(0)); return sig; } cerr << get_fileline() << ": internal error: " << "NetEUnary::synthesize cannot handle op_=" << op_ << endl; des->errors += 1; return expr_->synthesize(des, scope, root); } NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet*isig = expr_->synthesize(des, scope, root); if (isig == 0) return 0; if (isig->data_type() == IVL_VT_REAL) { if (op() == '!') { cerr << get_fileline() << ": sorry: ! is currently " "unsupported for real values." << endl; des->errors += 1; return 0; } cerr << get_fileline() << ": error: reduction operator (" << human_readable_op(op_) << ") may not have a REAL operand." << endl; des->errors += 1; return 0; } NetUReduce::TYPE rtype = NetUReduce::NONE; switch (op()) { case 'N': case '!': rtype = NetUReduce::NOR; break; case '&': rtype = NetUReduce::AND; break; case '|': rtype = NetUReduce::OR; break; case '^': rtype = NetUReduce::XOR; break; case 'A': rtype = NetUReduce::NAND; break; case 'X': rtype = NetUReduce::XNOR; break; default: cerr << get_fileline() << ": internal error: " << "Unable to synthesize " << *this << "." << endl; return 0; } NetUReduce*gate = new NetUReduce(scope, scope->local_symbol(), rtype, isig->vector_width()); gate->set_line(*this); des->add_node(gate); netvector_t*osig_vec = new netvector_t(expr_type()); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(gate->pin(0), osig->pin(0)); for (unsigned idx = 0 ; idx < isig->pin_count() ; idx += 1) connect(gate->pin(1+idx), isig->pin(idx)); return osig; } NetNet* NetECast::synthesize(Design*des, NetScope*scope, NetExpr*root) { NetNet*isig = expr_->synthesize(des, scope, root); if (isig == 0) return 0; switch (op()) { case 'v': isig = cast_to_int4(des, scope, isig, expr_width()); break; case '2': isig = cast_to_int2(des, scope, isig, expr_width()); break; case 'r': isig = cast_to_real(des, scope, isig); break; default: cerr << get_fileline() << ": internal error: " << "Unable to synthesize " << *this << "." << endl; return 0; } return isig; } /* * Turn a part/bit select expression into gates. * We know some things about the expression that elaboration enforces * for us: * * - Expression elaboration already converted the offset expression into * canonical form, so we don't have to worry about that here. */ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) { NetNet*sub = expr_->synthesize(des, scope, root); if (sub == 0) return 0; // Detect the special case that there is a base expression and // it is constant. In this case we can generate fixed part selects. if (NetEConst*base_const = dynamic_cast(base_)) { verinum base_tmp = base_const->value(); unsigned select_width = expr_width(); // Return 'bx for a constant undefined selections. if (!base_tmp.is_defined()) { NetNet*result = make_const_x(des, scope, select_width); result->set_line(*this); return result; } long base_val = base_tmp.as_long(); unsigned below_width = 0; // Any below X bits? NetNet*below = 0; if (base_val < 0) { below_width = abs(base_val); base_val = 0; if (below_width > select_width) { below_width = select_width; select_width = 0; } else { select_width -= below_width; } below = make_const_x(des, scope, below_width); below->set_line(*this); // All the selected bits are below the signal. if (select_width == 0) return below; } // Any above bits? NetNet*above = 0; if ((unsigned)base_val+select_width > sub->vector_width()) { if (base_val > (long)sub->vector_width()) { select_width = 0; } else { select_width = sub->vector_width() - base_val; } ivl_assert(*this, expr_width() > (select_width+below_width)); unsigned above_width = expr_width() - select_width - below_width; above = make_const_x(des, scope, above_width); above->set_line(*this); // All the selected bits are above the signal. if (select_width == 0) return above; } // Make the make part select. NetPartSelect*sel = new NetPartSelect(sub, base_val, select_width, NetPartSelect::VP); des->add_node(sel); ivl_assert(*this, select_width > 0); netvector_t*tmp_vec = new netvector_t(sub->data_type(), select_width-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); connect(sel->pin(0), tmp->pin(0)); unsigned concat_count = 1; if (above) concat_count += 1; if (below) concat_count += 1; if (concat_count > 1) { NetConcat*cat = new NetConcat(scope, scope->local_symbol(), expr_width(), concat_count); cat->set_line(*this); des->add_node(cat); if (below) { connect(cat->pin(1), below->pin(0)); connect(cat->pin(2), tmp->pin(0)); } else { connect(cat->pin(1), tmp->pin(0)); } if (above) { connect(cat->pin(concat_count), above->pin(0)); } tmp_vec = new netvector_t(sub->data_type(), expr_width()-1, 0); tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); connect(cat->pin(0), tmp->pin(0)); } return tmp; } // This handles the case that the NetESelect exists to do an // actual part/bit select. Generate a NetPartSelect object to // do the work, and replace "sub" with the selected output. if (base_ != 0) { NetNet*off = base_->synthesize(des, scope, root); NetPartSelect*sel = new NetPartSelect(sub, off, expr_width(), base_->has_sign()); sel->set_line(*this); des->add_node(sel); netvector_t*tmp_vec = new netvector_t(sub->data_type(), expr_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec); tmp->local_flag(true); tmp->set_line(*this); sub = tmp; connect(sub->pin(0), sel->pin(0)); } // Now look for the case that the NetESelect actually exists // to change the width of the expression. (i.e. to do // padding.) If this was for an actual part select that at // this point the output vector_width is exactly right, and we // are done. if (sub->vector_width() == expr_width()) return sub; netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0); net_vec->set_signed(has_sign()); NetNet*net = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, net_vec); net->set_line(*this); net->local_flag(true); // It may still happen that the expression is wider than the selection, // and there was no part select created earlier (size casting). if(expr_width() < sub->vector_width()) { NetPartSelect*sel = new NetPartSelect(sub, 0, expr_width(), NetPartSelect::VP, has_sign()); sel->set_line(*this); des->add_node(sel); connect(net->pin(0), sel->pin(0)); // The vector_width is not exactly right, so the source is // probably asking for padding. Create nodes to do sign // extension or 0 extension, depending on the has_sign() mode // of the expression. } else if (has_sign()) { NetSignExtend*pad = new NetSignExtend(scope, scope->local_symbol(), expr_width()); pad->set_line(*this); des->add_node(pad); connect(pad->pin(1), sub->pin(0)); connect(pad->pin(0), net->pin(0)); } else { NetConcat*cat = new NetConcat(scope, scope->local_symbol(), expr_width(), 2); cat->set_line(*this); des->add_node(cat); unsigned pad_width = expr_width() - sub->vector_width(); verinum pad((uint64_t)0, pad_width); NetConst*con = new NetConst(scope, scope->local_symbol(), pad); con->set_line(*this); des->add_node(con); netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); connect(tmp->pin(0), con->pin(0)); connect(cat->pin(0), net->pin(0)); connect(cat->pin(1), sub->pin(0)); connect(cat->pin(2), con->pin(0)); } return net; } /* * Synthesize a ?: operator as a NetMux device. Connect the condition * expression to the select input, then connect the true and false * expressions to the B and A inputs. This way, when the select input * is one, the B input, which is the true expression, is selected. */ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root) { NetNet*csig = cond_->synthesize(des, scope, root), *tsig = true_val_->synthesize(des, scope, root), *fsig = false_val_->synthesize(des, scope, root); if (csig == 0 || tsig == 0 || fsig == 0) return 0; if (! NetETernary::test_operand_compat(tsig->data_type(),fsig->data_type())) { cerr << get_fileline() << ": internal error: " << " True and False clauses of ternary expression " << " have incompatible types." << endl; cerr << get_fileline() << ": : True clause is: " << tsig->data_type() << " (" << true_val_->expr_type() << "): " << *true_val_ << endl; cerr << get_fileline() << ": : False clause is: " << fsig->data_type() << " (" << false_val_->expr_type() << "): " << *false_val_ << endl; des->errors += 1; return 0; } else if (tsig->data_type() == IVL_VT_NO_TYPE) { cerr << get_fileline() << ": internal error: True and False " "clauses of ternary both have NO TYPE." << endl; des->errors += 1; return 0; } perm_string path = csig->scope()->local_symbol(); ivl_assert(*this, csig->vector_width() == 1); unsigned width=expr_width(); netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0); NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, osig_vec); osig->set_line(*this); osig->local_flag(true); /* Make sure the types match. */ if (expr_type() == IVL_VT_REAL) { tsig = cast_to_real(des, scope, tsig); fsig = cast_to_real(des, scope, fsig); } /* Make sure both value operands are the right width. */ if (type_is_vectorable(expr_type())) { tsig = crop_to_width(des, pad_to_width(des, tsig, width, *this), width); fsig = crop_to_width(des, pad_to_width(des, fsig, width, *this), width); ivl_assert(*this, width == tsig->vector_width()); ivl_assert(*this, width == fsig->vector_width()); } perm_string oname = csig->scope()->local_symbol(); NetMux *mux = new NetMux(csig->scope(), oname, width, 2, csig->vector_width()); mux->set_line(*this); connect(tsig->pin(0), mux->pin_Data(1)); connect(fsig->pin(0), mux->pin_Data(0)); connect(osig->pin(0), mux->pin_Result()); connect(csig->pin(0), mux->pin_Sel()); des->add_node(mux); return osig; } /* * When synthesizing a signal expression, it is usually fine to simply * return the NetNet that it refers to. If this is an array word though, * a bit more work needs to be done. Return a temporary that represents * the selected word. */ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root) { // If this is a synthesis with a specific value for the // signal, then replace it (here) with a constant value. if (net_->scope()==scope && net_->name()==scope->genvar_tmp) { netvector_t*tmp_vec = new netvector_t(net_->data_type(), net_->vector_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); verinum tmp_val ((uint64_t)scope->genvar_tmp_val, net_->vector_width()); NetConst*tmp_const = new NetConst(scope, scope->local_symbol(), tmp_val); tmp_const->set_line(*this); des->add_node(tmp_const); connect(tmp->pin(0), tmp_const->pin(0)); return tmp; } if (word_ == 0) return net_; netvector_t*tmp_vec = new netvector_t(net_->data_type(), net_->vector_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::IMPLICIT, tmp_vec); tmp->set_line(*this); tmp->local_flag(true); // For NetExpr objects, the word index is already converted to // a canonical (lsb==0) address. Just use the index directly. if (NetEConst*index_co = dynamic_cast (word_)) { long index = index_co->value().as_long(); connect(tmp->pin(0), net_->pin(index)); } else { unsigned selwid = word_->expr_width(); NetArrayDq*mux = new NetArrayDq(scope, scope->local_symbol(), net_, selwid); mux->set_line(*this); des->add_node(mux); NetNet*index_net = word_->synthesize(des, scope, root); connect(mux->pin_Address(), index_net->pin(0)); connect(tmp->pin(0), mux->pin_Result()); } return tmp; } static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root) { NetEvWait*trigger = 0; NexusSet*nset = root->nex_input(false); if (nset && (nset->size() > 0)) { NetEvent*ev = new NetEvent(scope->local_symbol()); ev->set_line(*root); ev->local_flag(true); NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(), ev, NetEvProbe::ANYEDGE, nset->size()); pr->set_line(*root); for (unsigned idx = 0 ; idx < nset->size() ; idx += 1) connect(nset->at(idx).lnk, pr->pin(idx)); des->add_node(pr); scope->add_event(ev); trigger = new NetEvWait(0); trigger->set_line(*root); trigger->add_event(ev); } delete nset; return trigger; } NetNet* NetESFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) { const struct sfunc_return_type*def = lookup_sys_func(name_); /* We cannot use the default value for system functions in a * continuous assignment since the function name is NULL. */ if (def == 0 || def->name == 0) { cerr << get_fileline() << ": error: System function " << name_ << " not defined in system " "table or SFT file(s)." << endl; des->errors += 1; return 0; } if (debug_elaborate) { cerr << get_fileline() << ": debug: Net system function " << name_ << " returns " << def->type << endl; } NetEvWait*trigger = 0; if (parms_.empty()) { trigger = make_func_trigger(des, scope, root); } NetSysFunc*net = new NetSysFunc(scope, scope->local_symbol(), def, 1+parms_.size(), trigger); net->set_line(*this); des->add_node(net); netvector_t*osig_vec = new netvector_t(def->type, def->wid-1, 0); osig_vec->set_signed(def->type==IVL_VT_REAL? true : false); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(net->pin(0), osig->pin(0)); unsigned errors = 0; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { NetNet*tmp = parms_[idx]->synthesize(des, scope, root); if (tmp == 0) { cerr << get_fileline() << ": error: Unable to elaborate " << "argument " << idx << " of call to " << name_ << "." << endl; errors += 1; des->errors += 1; continue; } connect(net->pin(1+idx), tmp->pin(0)); } if (errors > 0) return 0; return osig; } NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root) { vector eparms (parms_.size()); /* Synthesize the arguments. */ bool errors = false; for (unsigned idx = 0; idx < eparms.size(); idx += 1) { if (dynamic_cast (parms_[idx])) { errors = true; continue; } NetNet*tmp = parms_[idx]->synthesize(des, scope, root); if (tmp == 0) { cerr << get_fileline() << ": error: Unable to synthesize " "port " << idx << " of call to " << func_->basename() << "." << endl; errors = true; des->errors += 1; continue; } eparms[idx] = tmp; } if (errors) return 0; NetEvWait*trigger = 0; if (gn_strict_ca_eval_flag) { /* Ideally we would only do this for functions that have hidden dependencies or side effects. Once constant functions are implemented, we may be able to reuse some code to achieve this. */ trigger = make_func_trigger(des, scope, root); } NetUserFunc*net = new NetUserFunc(scope_, scope_->local_symbol(), func_, trigger); net->set_line(*this); des->add_node(net); /* Create an output signal and connect it to the function. */ netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(), result_sig_->vector_width()-1, 0); NetNet*osig = new NetNet(scope_, scope_->local_symbol(), NetNet::WIRE, osig_vec); osig->set_line(*this); osig->local_flag(true); connect(net->pin(0), osig->pin(0)); if (debug_synth2) { cerr << get_fileline() << ": NetEUFunc::synthesize: " << "result_sig_->vector_width()=" << result_sig_->vector_width() << ", osig->vector_width()=" << osig->vector_width() << endl; } /* Connect the pins to the arguments. */ NetFuncDef*def = func_->func_def(); for (unsigned idx = 0; idx < eparms.size(); idx += 1) { unsigned width = def->port(idx)->vector_width(); NetNet*tmp; if (eparms[idx]->get_signed()) { tmp = pad_to_width_signed(des, eparms[idx], width, *this); } else { tmp = pad_to_width(des, eparms[idx], width, *this); } NetNet*tmpc = crop_to_width(des, tmp, width); connect(net->pin(idx+1), tmpc->pin(0)); } return osig; } iverilog-12_0/extensions.txt000066400000000000000000000060271435245347300163140ustar00rootroot00000000000000 Icarus Verilog Extensions Icarus Verilog supports certain extensions to the baseline IEEE1364 standard. Some of these are picked from extended variants of the language, such as SystemVerilog, and some are expressions of internal behavior of Icarus Verilog, made available as a tool debugging aid. * Builtin System Functions ** Extended Verilog Data Types This feature is turned off if the generation flag "-g" is set to other then the default "2x". For example, "iverilog -g2x" enables extended data types, and "iverilog -g2" disables them. Icarus Verilog adds support for extended data types. This extended type syntax is based on a proposal by Cadence Design Systems, originally as an update to the IEEE1364. That original proposal has apparently been absorbed by the IEEE1800 SystemVerilog standard. Icarus Verilog currently only takes the new primitive types from the proposal. Extended data types separates the concept of net/variable from the data type. Both nets and variables can declared with any data type. The primitive types available are: logic - The familiar 0, 1, x and z, optionally with strength. bool - Limited to only 0 and 1 real - 64bit real values Nets with logic type may have multiple drivers with strength, and the value is resolved the usual way. Only logic values may be driven to logic nets, so bool values driven onto logic nets are implicitly converted to logic. Nets with any other type may not have multiple drivers. The compiler should detect the multiple drivers and report an error. - Declarations The declaration of a net is extended to include the type of the wire, with the syntax: wire ... ; The , if omitted, is taken to be logic. The "wire" can be any of the net keywords. Wires can be logic, bool, real, or vectors of logic or bool. Some valid examples: wire real foo = 1.0; tri logic bus[31:0]; wire bool addr[23:0]; ... and so on. The declarations of variables is similar. The "reg" keyword is used to specify that this is a variable. Variables can have the same data types as nets. - Ports Module and task ports in standard Verilog are restricted to logic types. This extension removes that restriction, allowing any type to pass through the port consistent with the continuous assignment connectivity that is implied by the type. - Expressions Expressions in the face of real values is covered by the baseline Verilog standard. The bool type supports the same operators as the logic type, with the obvious differences imposed by the limited domain. Comparison operators (not case compare) return logic if either of their operands is logic. If both are bool or real (including mix of bool and real) then the result is bool. This is because comparison of bools and reals always return exactly true or false. Case comparison returns bool. This differs from baseline Verilog, which strictly speaking returns a logic, but only 0 or 1 values. All the arithmetic operators return bool if both of their operands are bool or real. Otherwise, they return logic. iverilog-12_0/functor.cc000066400000000000000000000146401435245347300153430ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 # include "functor.h" # include "netlist.h" using namespace std; functor_t::~functor_t() { } void functor_t::event(Design*, NetEvent*) { } void functor_t::signal(Design*, NetNet*) { } void functor_t::process(Design*, NetProcTop*) { } void functor_t::lpm_abs(Design*, NetAbs*) { } void functor_t::lpm_add_sub(Design*, NetAddSub*) { } void functor_t::lpm_compare(Design*, const NetCompare*) { } void functor_t::lpm_concat(Design*, NetConcat*) { } void functor_t::lpm_const(Design*, NetConst*) { } void functor_t::lpm_divide(Design*, NetDivide*) { } void functor_t::lpm_literal(Design*, NetLiteral*) { } void functor_t::lpm_modulo(Design*, NetModulo*) { } void functor_t::lpm_ff(Design*, NetFF*) { } void functor_t::lpm_latch(Design*, NetLatch*) { } void functor_t::lpm_logic(Design*, NetLogic*) { } void functor_t::lpm_mult(Design*, NetMult*) { } void functor_t::lpm_mux(Design*, NetMux*) { } void functor_t::lpm_part_select(Design*, NetPartSelect*) { } void functor_t::lpm_pow(Design*, NetPow*) { } void functor_t::sign_extend(Design*, NetSignExtend*) { } void functor_t::lpm_substitute(Design*, NetSubstitute*) { } void functor_t::lpm_ureduce(Design*, NetUReduce*) { } void NetScope::run_functor(Design*des, functor_t*fun) { for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->run_functor(des, fun); for (NetEvent*cur = events_ ; cur ; /* */) { NetEvent*tmp = cur; cur = cur->snext_; fun->event(des, tmp); } // apply to signals. Each iteration, allow for the possibility // that the current signal deletes itself. signals_map_iter_t cur = signals_map_.begin(); while (cur != signals_map_.end()) { signals_map_iter_t tmp = cur; ++ cur; fun->signal(des, tmp->second); } } void Design::functor(functor_t*fun) { // Scan the scopes for (list::const_iterator scope = root_scopes_.begin(); scope != root_scopes_.end(); ++ scope ) (*scope)->run_functor(this, fun); // apply to processes procs_idx_ = procs_; while (procs_idx_) { NetProcTop*idx = procs_idx_; procs_idx_ = idx->next_; fun->process(this, idx); } // apply to nodes if (nodes_) { assert(nodes_functor_cur_ == 0); assert(nodes_functor_nxt_ == 0); /* Scan the circular list of nodes, starting with the front of the list. This loop interacts with the Design::del_node method so that the functor is free to delete any nodes it choose. The destructors of the NetNode objects call the del_node method, which checks with the nodes_functor_* members, to keep the iterator operating safely. */ nodes_functor_cur_ = nodes_; do { nodes_functor_nxt_ = nodes_functor_cur_->node_next_; nodes_functor_cur_->functor_node(this, fun); if (nodes_functor_nxt_ == 0) break; nodes_functor_cur_ = nodes_functor_nxt_; } while (nodes_ && (nodes_functor_cur_ != nodes_)); nodes_functor_cur_ = 0; nodes_functor_nxt_ = 0; } } void NetNode::functor_node(Design*, functor_t*) { } void NetAbs::functor_node(Design*des, functor_t*fun) { fun->lpm_abs(des, this); } void NetAddSub::functor_node(Design*des, functor_t*fun) { fun->lpm_add_sub(des, this); } void NetCompare::functor_node(Design*des, functor_t*fun) { fun->lpm_compare(des, this); } void NetConcat::functor_node(Design*des, functor_t*fun) { fun->lpm_concat(des, this); } void NetConst::functor_node(Design*des, functor_t*fun) { fun->lpm_const(des, this); } void NetDivide::functor_node(Design*des, functor_t*fun) { fun->lpm_divide(des, this); } void NetFF::functor_node(Design*des, functor_t*fun) { fun->lpm_ff(des, this); } void NetLatch::functor_node(Design*des, functor_t*fun) { fun->lpm_latch(des, this); } void NetLiteral::functor_node(Design*des, functor_t*fun) { fun->lpm_literal(des, this); } void NetLogic::functor_node(Design*des, functor_t*fun) { fun->lpm_logic(des, this); } void NetModulo::functor_node(Design*des, functor_t*fun) { fun->lpm_modulo(des, this); } void NetMult::functor_node(Design*des, functor_t*fun) { fun->lpm_mult(des, this); } void NetMux::functor_node(Design*des, functor_t*fun) { fun->lpm_mux(des, this); } void NetPartSelect::functor_node(Design*des, functor_t*fun) { fun->lpm_part_select(des, this); } void NetPow::functor_node(Design*des, functor_t*fun) { fun->lpm_pow(des, this); } void NetSignExtend::functor_node(Design*des, functor_t*fun) { fun->sign_extend(des, this); } void NetSubstitute::functor_node(Design*des, functor_t*fun) { fun->lpm_substitute(des, this); } void NetUReduce::functor_node(Design*des, functor_t*fun) { fun->lpm_ureduce(des, this); } proc_match_t::~proc_match_t() { } int NetProc::match_proc(proc_match_t*) { return 0; } int proc_match_t::assign(NetAssign*) { return 0; } int NetAssign::match_proc(proc_match_t*that) { return that->assign(this); } int proc_match_t::assign_nb(NetAssignNB*) { return 0; } int NetAssignNB::match_proc(proc_match_t*that) { return that->assign_nb(this); } int proc_match_t::block(NetBlock*) { return 0; } int NetBlock::match_proc(proc_match_t*that) { return that->block(this); } int proc_match_t::condit(NetCondit*) { return 0; } int NetCondit::match_proc(proc_match_t*that) { return that->condit(this); } int NetEvWait::match_proc(proc_match_t*that) { return that->event_wait(this); } int proc_match_t::event_wait(NetEvWait*) { return 0; } iverilog-12_0/functor.h000066400000000000000000000100511435245347300151750ustar00rootroot00000000000000#ifndef IVL_functor_H #define IVL_functor_H /* * Copyright (c) 1999-2021 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. */ /* * The functor is an object that can be applied to a design to * transform it. This is different from the target_t, which can only * scan the design but not transform it in any way. * * When a functor it scanning a process, signal or node, the functor * is free to manipulate the list by deleting items, including the * node being scanned. The Design class scanner knows how to handle * the situation. However, if objects are added to the netlist, there * is no guarantee that object will be scanned unless the functor is * rerun. */ class Design; class NetNet; class NetProcTop; struct functor_t { virtual ~functor_t(); /* Events are scanned here. */ virtual void event(Design*des, class NetEvent*); /* This is called once for each signal in the design. */ virtual void signal(Design*des, NetNet*); /* This method is called for each process in the design. */ virtual void process(Design*des, NetProcTop*); /* This method is called for each structural abs(). */ virtual void lpm_abs(Design*des, class NetAbs*); /* This method is called for each structural adder. */ virtual void lpm_add_sub(Design*des, class NetAddSub*); /* This method is called for each structural comparator. */ virtual void lpm_compare(Design*des, const class NetCompare*); /* This method is called for each structural concatenation. */ virtual void lpm_concat(Design*des, class NetConcat*); /* This method is called for each structural constant. */ virtual void lpm_const(Design*des, class NetConst*); /* This method is called for each structural constant. */ virtual void lpm_divide(Design*des, class NetDivide*); /* Constant literals. */ virtual void lpm_literal(Design*des, class NetLiteral*); /* This method is called for each structural constant. */ virtual void lpm_modulo(Design*des, class NetModulo*); /* This method is called for each FF in the design. */ virtual void lpm_ff(Design*des, class NetFF*); /* This method is called for each LATCH in the design. */ virtual void lpm_latch(Design*des, class NetLatch*); /* Handle LPM combinational logic devices. */ virtual void lpm_logic(Design*des, class NetLogic*); /* This method is called for each multiplier. */ virtual void lpm_mult(Design*des, class NetMult*); /* This method is called for each MUX. */ virtual void lpm_mux(Design*des, class NetMux*); virtual void lpm_part_select(Design*des, class NetPartSelect*); /* This method is called for each power. */ virtual void lpm_pow(Design*des, class NetPow*); /* This method is called for each part substitute. */ virtual void lpm_substitute(Design*des, class NetSubstitute*); /* This method is called for each unary reduction gate. */ virtual void lpm_ureduce(Design*des, class NetUReduce*); virtual void sign_extend(Design*des, class NetSignExtend*); }; struct proc_match_t { virtual ~proc_match_t(); virtual int assign(class NetAssign*); virtual int assign_nb(class NetAssignNB*); virtual int condit(class NetCondit*); virtual int event_wait(class NetEvWait*); virtual int block(class NetBlock*); }; #endif /* IVL_functor_H */ iverilog-12_0/glossary.txt000066400000000000000000000024551435245347300157610ustar00rootroot00000000000000 Throughout Icarus Verilog descriptions and source code, I use a variety of terms and acronyms that might be specific to Icarus Verilog, have an Icarus Verilog specific meaning, or just aren't widely known. So here I define these terms. LRM - Language Reference Manual This is a generic acronym, but in the Verilog world we sometimes mean *the* language reference manual, the IEEE1364 standard. PLI - Programming Language Interface This is a C API into Verilog simulators that is defined by the IEEE1364. There are two major interfaces, sometimes called PLI 1 and PLI 2. PLI 2 is also often called VPI. UDP - User Defined Primitive These are objects that Verilog programmers define with the "primitive" keyword. They are truth-table based devices. The syntax for defining them is described in the LRM. VPI - This is the C API that is defined by the Verilog standard, and that Icarus Verilog partially implements. See also PLI. VVM - Verilog Virtual Machine This is the Icarus Verilog runtime that works with the code generator that generates C++. VVP - Verilog Virtual Processor This is the Icarus Verilog runtime that reads in custom code in a form that I call "VVP Assembly". See the vvp/ directory for documentation on that. iverilog-12_0/ieee1364-notes.txt000066400000000000000000000466061435245347300164770ustar00rootroot00000000000000 NOTE: THE CONTENTS OF THIS FILE ARE BEING MOVED TO THE DOCUMENTATION WIKI AT http://iverilog.wikia.com. PLEASE ADD NEW ENTRIES THERE. Icarus Verilog vs. IEEE1364 Copyright 2000 Stephen Williams 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-12_0/install-sh000077500000000000000000000112351435245347300153550ustar00rootroot00000000000000#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 iverilog-12_0/iverilog-vpi.man.in000066400000000000000000000071621435245347300170730ustar00rootroot00000000000000.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E" .SH NAME iverilog-vpi - Compile front end for VPI modules .SH SYNOPSIS .B iverilog-vpi [options] \fIsourcefile\fP... .SH DESCRIPTION .PP \fIiverilog\-vpi\fP is a tool to simplify the compilation of VPI modules for use with Icarus Verilog. It takes on the command line a list of C or C++ source files, and generates as output a linked VPI module. See the \fBvvp\fP(1) man page for a description of how the linked module is loaded by a simulation. By default the output is named after the first source file. For example, if the first source file is named \fIfoo.c\fP, the output becomes \fIfoo.vpi\fP. .SH OPTIONS \fIiverilog\-vpi\fP accepts the following options: .TP 8 .B -l\fIlibrary\fP Include the named library in the link of the VPI module. This allows VPI modules to further reference external libraries. .TP 8 .B -L\fIdirectory\fP Add \fIdirectory\fP to the list of directories that will be searched for library files. .TP 8 .B -I\fIdirectory\fP Add \fIdirectory\fP to the list of directories that will be searched for header files. .TP 8 .B -D\fIdefine\fP Define a macro named \fIdefine\fP. .TP 8 .B --name=\fIname\fP Normally, the output VPI module will be named after the first source file passed to the command. This flag sets the name (without the .vpi suffix) of the output vpi module. .SH "PC-ONLY OPTIONS" When built as a native Windows program (using the MinGW toolchain), by default \fIiverilog\-vpi\fP will attempt to locate the MinGW tools needed to compile a VPI module on the system path (as set by the PATH environment variable). As an alternative, the user may specify the location of the MinGW tools via the following option. .TP 8 .B -mingw=\fIpath\fP Tell the program the root of the MinGW compiler tool suite. The \fBvvp\fP runtime is compiled with this compiler, and this is the compiler that \fIiverilog\-vpi\fP expects to use to compile your source code. If this option accompanies a list of files, it will apply to the current build only. If this option is provided on its own, \fIiverilog\-vpi\fP will save the \fIpath\fP in the registry and use that path in preference to the system path for subsequent operations, avoiding the need to specify it on the command line every time. .SH "INFORMATIONAL OPTIONS" \fIiverilog\-vpi\fP includes additional flags to let Makefile gurus peek at the configuration of the \fIiverilog\fP installation. This way, Makefiles can be written that handle complex VPI builds natively, and without hard-coding values that depend on the system and installation. If used at all, these options must be used one at a time, and without any other options or directives. .TP 8 .B --install-dir Print the install directory for VPI modules. .TP 8 .B --cflags Print the compiler flags (CFLAGS or CXXFLAGS) needed to compile source code destined for a VPI module. .TP 8 .B --ldflags Print the linker flags (LDFLAGS) needed to link a VPI module. .TP 8 .B --ldlibs Print the libraries (LDLIBS) needed to link a VPI module. .P Example GNU makefile that takes advantage of these flags: .IP "" 4 CFLAGS = \-Wall \-O $(CFLAGS_$@) .br VPI_CFLAGS := $(shell iverilog-vpi \-\-cflags) .br CFLAGS_messagev.o = $(VPI_CFLAGS) .br CFLAGS_fifo.o = $(VPI_CFLAGS) .br messagev.o fifo.o: transport.h .br messagev.vpi: messagev.o fifo.o .br iverilog-vpi $^ .SH "AUTHOR" .nf Steve Williams (steve@icarus.com) .SH SEE ALSO iverilog(1), vvp(1), .BR "", .BR "", .SH COPYRIGHT .nf Copyright \(co 2002\-2017 Stephen Williams This document can be freely redistributed according to the terms of the GNU General Public License version 2.0 iverilog-12_0/iverilog-vpi.sh000066400000000000000000000061011435245347300163150ustar00rootroot00000000000000#!/bin/sh # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Boston, MA 02111-1307, USA # # These are the variables used for compiling files CC="@IVCC@" CXX=@IVCXX@ CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@" CXXFLAGS="@PIC@ @IVCXXFLAGS@ -I@INCLUDEDIR@" SUFFIX=@SUFFIX@ # These are used for linking... LD=$CC LDFLAGS="@IVCTARGETFLAGS@ @SHARED@ -L@LIBDIR@" LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX" CCSRC= CXSRC= OBJ= LIB= LIBDIR= OUT= INCOPT= DEFS= # -- # parse the command line switches. This collects the source files # and precompiled object files, and maybe user libraries. As we are # going, guess an output file name. for parm do case $parm in *.c) CCSRC="$CCSRC $parm" if [ x$OUT = x ]; then OUT=`basename $parm .c` fi ;; *.cc) CXSRC="$CXSRC $parm" LD=$CXX if [ x$OUT = x ]; then OUT=`basename $parm .cc` fi ;; *.cpp) CXSRC="$CXSRC $parm" LD=$CXX if [ x$OUT = x ]; then OUT=`basename $parm .cpp` fi ;; *.o) OBJ="$OBJ $parm" if [ x$OUT = x ]; then OUT=`basename $parm .o` fi ;; --name=*) OUT=`echo $parm | cut -b8-` ;; -l*) LIB="$LIB $parm" ;; -L*) LIBDIR="$LIBDIR $parm" ;; -I*) INCOPT="$INCOPT $parm" ;; -D*) DEFS="$DEFS $parm" ;; --cflags) echo "$CFLAGS" exit; ;; --ccflags) echo "$CXXFLAGS" exit; ;; --ldflags) echo "$LDFLAGS" exit; ;; --ldlibs) echo "$LDLIBS" exit; ;; --install-dir) echo "@LIBDIR@/ivl$SUFFIX" exit ;; esac done if [ x$OUT = x ]; then echo "Usage: $0 [src and obj files]..." 1>&2 exit 0 fi # Put the .vpi on the result file. OUT=$OUT".vpi" compile_errors=0 # Compile all the source files into object files for src in $CCSRC do base=`basename $src .c` obj=$base".o" echo "Compiling $src..." $CC -c -o $obj $DEFS $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1` OBJ="$OBJ $obj" done for src in $CXSRC do base=`basename $src .cc` obj=$base".o" echo "Compiling $src..." $CXX -c -o $obj $DEFS $CXXFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1` OBJ="$OBJ $obj" done if test $compile_errors -gt 0 then echo "$0: $compile_errors file(s) failed to compile." exit $compile_errors fi echo "Making $OUT from $OBJ..." exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS iverilog-12_0/ivl.def000066400000000000000000000127451435245347300146320ustar00rootroot00000000000000EXPORTS ivl_branch_island ivl_branch_terminal ivl_design_const ivl_design_consts ivl_design_discipline ivl_design_disciplines ivl_design_delay_sel ivl_design_flag ivl_design_process ivl_design_root ivl_design_roots ivl_design_time_precision ivl_const_bits ivl_const_delay ivl_const_file ivl_const_lineno ivl_const_nex ivl_const_real ivl_const_scope ivl_const_signed ivl_const_type ivl_const_width ivl_discipline_domain ivl_discipline_flow ivl_discipline_name ivl_discipline_potential ivl_enum_bits ivl_enum_file ivl_enum_lineno ivl_enum_name ivl_enum_names ivl_enum_signed ivl_enum_type ivl_enum_width ivl_event_any ivl_event_basename ivl_event_edg ivl_event_file ivl_event_lineno ivl_event_name ivl_event_nany ivl_event_nedg ivl_event_neg ivl_event_nneg ivl_event_npos ivl_event_pos ivl_event_scope ivl_expr_type ivl_expr_bits ivl_expr_branch ivl_expr_def ivl_expr_delay_val ivl_expr_dvalue ivl_expr_enumtype ivl_expr_event ivl_expr_file ivl_expr_lineno ivl_expr_name ivl_expr_nature ivl_expr_net_type ivl_expr_opcode ivl_expr_oper1 ivl_expr_oper2 ivl_expr_oper3 ivl_expr_parameter ivl_expr_parm ivl_expr_parms ivl_expr_property_idx ivl_expr_repeat ivl_expr_scope ivl_expr_sel_type ivl_expr_signal ivl_expr_signed ivl_expr_sized ivl_expr_string ivl_expr_uvalue ivl_expr_value ivl_expr_width ivl_file_table_index ivl_file_table_item ivl_file_table_size ivl_island_flag_set ivl_island_flag_test ivl_logic_attr ivl_logic_attr_cnt ivl_logic_attr_val ivl_logic_basename ivl_logic_delay ivl_logic_drive0 ivl_logic_drive1 ivl_logic_file ivl_logic_is_cassign ivl_logic_lineno ivl_logic_name ivl_logic_pin ivl_logic_pins ivl_logic_scope ivl_logic_type ivl_logic_udp ivl_logic_width ivl_lpm_array ivl_lpm_aset_value ivl_lpm_async_clr ivl_lpm_async_set ivl_lpm_base ivl_lpm_basename ivl_lpm_clk ivl_lpm_data ivl_lpm_datab ivl_lpm_define ivl_lpm_delay ivl_lpm_drive0 ivl_lpm_drive1 ivl_lpm_enable ivl_lpm_file ivl_lpm_lineno ivl_lpm_name ivl_lpm_negedge ivl_lpm_q ivl_lpm_scope ivl_lpm_select ivl_lpm_selects ivl_lpm_signed ivl_lpm_size ivl_lpm_sset_value ivl_lpm_string ivl_lpm_sync_clr ivl_lpm_sync_set ivl_lpm_trigger ivl_lpm_type ivl_lpm_width ivl_lval_idx ivl_lval_mux ivl_lval_nest ivl_lval_part_off ivl_lval_property_idx ivl_lval_sel_type ivl_lval_sig ivl_lval_width ivl_nature_name ivl_nexus_get_private ivl_nexus_name ivl_nexus_ptrs ivl_nexus_ptr ivl_nexus_set_private ivl_nexus_ptr_branch ivl_nexus_ptr_con ivl_nexus_ptr_drive0 ivl_nexus_ptr_drive1 ivl_nexus_ptr_pin ivl_nexus_ptr_lpm ivl_nexus_ptr_log ivl_nexus_ptr_sig ivl_nexus_ptr_switch ivl_parameter_basename ivl_parameter_expr ivl_parameter_file ivl_parameter_is_type ivl_parameter_lineno ivl_parameter_local ivl_parameter_lsb ivl_parameter_msb ivl_parameter_scope ivl_parameter_signed ivl_parameter_width ivl_path_condit ivl_path_delay ivl_path_is_condit ivl_path_is_parallel ivl_path_scope ivl_path_source ivl_path_source_negedge ivl_path_source_posedge ivl_process_analog ivl_process_attr_cnt ivl_process_attr_val ivl_process_file ivl_process_lineno ivl_process_scope ivl_process_stmt ivl_process_type ivl_scope_attr_cnt ivl_scope_attr_val ivl_scope_basename ivl_scope_children ivl_scope_child ivl_scope_childs ivl_scope_class ivl_scope_classes ivl_scope_def ivl_scope_def_file ivl_scope_def_lineno ivl_scope_enumerate ivl_scope_enumerates ivl_scope_event ivl_scope_events ivl_scope_file ivl_scope_func_type ivl_scope_func_signed ivl_scope_func_width ivl_scope_is_auto ivl_scope_is_cell ivl_scope_lineno ivl_scope_logs ivl_scope_log ivl_scope_lpms ivl_scope_lpm ivl_scope_mod_module_ports ivl_scope_mod_module_port_name ivl_scope_mod_module_port_type ivl_scope_mod_module_port_width ivl_scope_mod_port ivl_scope_name ivl_scope_param ivl_scope_params ivl_scope_parent ivl_scope_port ivl_scope_ports ivl_scope_sigs ivl_scope_sig ivl_scope_switch ivl_scope_switches ivl_scope_time_precision ivl_scope_time_units ivl_scope_type ivl_scope_tname ivl_signal_array_addr_swapped ivl_signal_array_base ivl_signal_array_count ivl_signal_attr ivl_signal_attr_cnt ivl_signal_attr_val ivl_signal_basename ivl_signal_data_type ivl_signal_dimensions ivl_signal_discipline ivl_signal_file ivl_signal_forced_net ivl_signal_integer ivl_signal_lineno ivl_signal_local ivl_signal_lsb ivl_signal_msb ivl_signal_name ivl_signal_net_type ivl_signal_nex ivl_signal_npath ivl_signal_packed_dimensions ivl_signal_packed_lsb ivl_signal_packed_msb ivl_signal_path ivl_signal_port ivl_signal_scope ivl_signal_signed ivl_signal_type ivl_signal_width ivl_statement_type ivl_stmt_block_count ivl_stmt_block_scope ivl_stmt_block_stmt ivl_stmt_call ivl_stmt_case_count ivl_stmt_case_expr ivl_stmt_case_quality ivl_stmt_case_stmt ivl_stmt_cond_expr ivl_stmt_cond_false ivl_stmt_cond_true ivl_stmt_delay_expr ivl_stmt_delay_val ivl_stmt_events ivl_stmt_file ivl_stmt_flow_control ivl_stmt_lexp ivl_stmt_lineno ivl_stmt_lval ivl_stmt_lvals ivl_stmt_lwidth ivl_stmt_name ivl_stmt_needs_t0_trigger ivl_stmt_nevent ivl_stmt_opcode ivl_stmt_parm ivl_stmt_parm_count ivl_stmt_rval ivl_stmt_sfunc_as_task ivl_stmt_sub_stmt ivl_switch_a ivl_switch_b ivl_switch_basename ivl_switch_delay ivl_switch_enable ivl_switch_file ivl_switch_island ivl_switch_lineno ivl_switch_offset ivl_switch_part ivl_switch_scope ivl_switch_type ivl_switch_width ivl_type_base ivl_type_element ivl_type_name ivl_type_packed_dimensions ivl_type_packed_lsb ivl_type_packed_msb ivl_type_packed_width ivl_type_prop_name ivl_type_prop_type ivl_type_properties ivl_type_signed ivl_udp_init ivl_udp_file ivl_udp_lineno ivl_udp_name ivl_udp_nin ivl_udp_port ivl_udp_row ivl_udp_rows ivl_udp_sequ iverilog-12_0/ivl_alloc.h000066400000000000000000000052341435245347300154700ustar00rootroot00000000000000#ifndef IVL_ivl_alloc_H #define IVL_ivl_alloc_H /* * Copyright (C) 2010-2014 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. */ #ifdef __cplusplus # include # include #else # include # include #endif #if defined(__GNUC__) /* * Define a safer version of malloc(). */ #define malloc(__ivl_size) \ ({ \ /* To be safe we only evaluate the argument once. */ \ size_t __ivl_lsize = __ivl_size; \ void *__ivl_rtn = malloc(__ivl_lsize); \ /* If we run out of memory then exit with a message. */ \ if ((__ivl_rtn == NULL) && (__ivl_lsize != 0)) { \ fprintf(stderr, "%s:%d: Error: malloc() ran out of memory.\n", \ __FILE__, __LINE__); \ exit(1); \ } \ __ivl_rtn; \ }) /* * Define a safer version of realloc(). */ #define realloc(__ivl_ptr, __ivl_size) \ ({ \ /* To be safe we only evaluate the arguments once. */ \ void *__ivl_lptr = __ivl_ptr; \ size_t __ivl_lsize = __ivl_size; \ void *__ivl_rtn = realloc(__ivl_lptr, __ivl_lsize); \ /* If we run out of memory then exit with a message. */ \ if ((__ivl_rtn == NULL) && (__ivl_lsize != 0)) { \ fprintf(stderr, "%s:%d: Error: realloc() ran out of memory.\n", \ __FILE__, __LINE__); \ free(__ivl_lptr); \ exit(1); \ } \ __ivl_rtn; \ }) /* * Define a safer version of calloc(). */ #define calloc(__ivl_count, __ivl_size) \ ({ \ /* To be safe we only evaluate the arguments once. */ \ size_t __ivl_lcount = __ivl_count; \ size_t __ivl_lsize = __ivl_size; \ void *__ivl_rtn = calloc(__ivl_lcount, __ivl_lsize); \ /* If we run out of memory then exit with a message. */ \ if ((__ivl_rtn == NULL) && (__ivl_lcount != 0) && (__ivl_lsize != 0)) { \ fprintf(stderr, "%s:%d: Error: calloc() ran out of memory.\n", \ __FILE__, __LINE__); \ exit(1); \ } \ __ivl_rtn; \ }) #endif #endif /* IVL_ivl_alloc_H */ iverilog-12_0/ivl_assert.h000066400000000000000000000023301435245347300156710ustar00rootroot00000000000000#ifndef IVL_ivl_assert_H #define IVL_ivl_assert_H /* * Copyright (c) 2007-2021 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 #define ivl_assert(tok, expression) \ do { \ if (! (expression)) { \ std::cerr << (tok).get_fileline() << ": assert: " \ << __FILE__ << ":" << __LINE__ \ << ": failed assertion " << #expression << std::endl; \ abort(); \ } \ } while (0) #endif /* IVL_ivl_assert_H */ iverilog-12_0/ivl_target.h000066400000000000000000002744551435245347300157010ustar00rootroot00000000000000#ifndef IVL_ivl_target_H #define IVL_ivl_target_H /* * Copyright (c) 2000-2021 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 # include /* Re the _CLASS define: clang++ wants this to be class to match the * definition, but clang (the C) compiler needs it to be a struct * since class is not defined in C. They are effectively both pointers * to an object so everything works out. */ #ifdef __cplusplus #define _BEGIN_DECL extern "C" { #define _END_DECL } #define _CLASS class #else #define _BEGIN_DECL #define _END_DECL #define _CLASS struct #endif #ifndef __GNUC__ # define __attribute__(x) #endif #if defined(__cplusplus) && defined(_MSC_VER) # define ENUM_UNSIGNED_INT : unsigned int #else # define ENUM_UNSIGNED_INT #endif _BEGIN_DECL /* * This header file describes the API for the loadable target * module. The main program can load these modules and access the * functions within the loaded module to implement the backend * behavior. * * The interface is divided into two parts: the entry points within * the core that are called by the module, and the entry points in * the module that are called by the core. It is the latter that * causes the module to be invoked in the first place, but most of the * interesting information about the design is accessed through the * various access functions that the modules calls into the core. */ /* * In order to grab onto data in the design, the core passes cookies * to the various functions of the module. These cookies can in turn * be passed to access functions in the core to get more detailed * information. * * The following typedefs list the various cookies that may be passed * around. * * ivl_array_t * This object represents an array that can be a memory or a net * array. (They are the same from the perspective of ivl_target.h.) * * ivl_branch_t * this object represents an analog branch. * * ivl_design_t * This object represents the entire elaborated design. Various * global properties and methods are available from this. * * ivl_event_t * This object represents an event node. An event node stands for * named events written explicitly in the Verilog, and net events * that are implicit when @ statements are used. * * ivl_expr_t * This object represents a node of an expression. If the * expression has sub-expressions, they can be accessed from * various method described below. The ivl_expr_type method in * particular gets the type of the node in the form of an * ivl_expr_type_t enumeration value. * * Objects of this type represent expressions in processes. * Structural expressions are instead treated as logic gates. * * ivl_island_t * Certain types of objects may belong to islands. The island that * they belong to is represented by the ivl_island_t cookie. To * know if objects belong to the same island, it is sufficient to * compare island cookies. If a==b, then island a is the same as * island b. * * ivl_lpm_t * This object is the base class for all the various LPM type * device nodes. This object carries a few base properties * (including a type) including a handle to the specific type. * * ivl_net_logic_t * This object represents various built in logic devices. In fact, * this includes just about every directional device that has a * single output, including logic gates and nmos, pmos and cmos * devices. There is also the occasional Icarus Verilog creation. * What is common about these devices is that they are * bitwise. That is, when fed a vector, they produce a vector * result where each bit of the output is made only from the same * bits in the vector inputs. * * ivl_nexus_t * Structural links within an elaborated design are connected * together at each bit. The connection point is a nexus, so pins * of devices refer to an ivl_nexus_t. Furthermore, from a nexus * there are backward references to all the device pins that point * to it. * * ivl_parameter_t * Scopes have zero or more parameter objects that represent * parameters that the source defined. The parameter has a value * that is fully elaborated, with defparams and other parameter * overrides taken care of. * * ivl_process_t * A Verilog process is represented by one of these. A process may * be an "initial" or an "always" process. These come from initial * or always statements from the Verilog source. * * ivl_scope_t * Elaborated scopes within a design are represented by this * type. Objects of this type also act as containers for scoped * objects such as signals. * * ivl_statement_t * Statements within processes are represented by one of these. The * ivl_process_t object holds one of these, but a statement may in * turn contain other statements. * * ivl_switch_t * Switches are the tran/tranif devices in the design. * * -- A Note About Bit Sets -- * Some objects hold a value as an array of bits. In these cases there * is some method that retrieves the width of the value and another * that returns a "char*". The latter is a pointer to the least * significant bit value. Bit values are represented by the characters * '0', '1', 'x' and 'z'. Strengths are stored elsewhere. * * -- A Note About Names -- * The names of objects are complete, hierarchical names. That is, * they include the instance name of the module that contains them. * * basenames are the name of the object without the containing * scope. These names are unique within a scope, but not necessarily * throughout the design. */ typedef struct ivl_array_s *ivl_array_t; typedef struct ivl_branch_s *ivl_branch_t; typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_design_s *ivl_design_t; typedef _CLASS ivl_discipline_s*ivl_discipline_t; typedef const _CLASS netenum_t*ivl_enumtype_t; typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_expr_s *ivl_expr_t; typedef struct ivl_island_s *ivl_island_t; typedef struct ivl_lpm_s *ivl_lpm_t; typedef struct ivl_lval_s *ivl_lval_t; typedef struct ivl_net_const_s*ivl_net_const_t; typedef struct ivl_net_logic_s*ivl_net_logic_t; typedef struct ivl_udp_s *ivl_udp_t; typedef _CLASS ivl_nature_s *ivl_nature_t; typedef struct ivl_net_probe_s*ivl_net_probe_t; typedef struct ivl_nexus_s *ivl_nexus_t; typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t; typedef struct ivl_parameter_s*ivl_parameter_t; typedef struct ivl_process_s *ivl_process_t; typedef struct ivl_scope_s *ivl_scope_t; typedef struct ivl_signal_s *ivl_signal_t; typedef struct ivl_port_info_s*ivl_port_info_t; typedef struct ivl_switch_s *ivl_switch_t; typedef struct ivl_memory_s *ivl_memory_t; //XXXX __attribute__((deprecated)); typedef struct ivl_statement_s*ivl_statement_t; typedef const _CLASS ivl_type_s*ivl_type_t; /* * These are types that are defined as enumerations. These have * explicit values so that the binary API is a bit more resilient to * changes and additions to the enumerations. */ typedef enum ivl_dis_domain_e { IVL_DIS_NONE = 0, IVL_DIS_DISCRETE = 1, IVL_DIS_CONTINUOUS = 2 } ivl_dis_domain_t; typedef enum ivl_drive_e ENUM_UNSIGNED_INT { IVL_DR_HiZ = 0, IVL_DR_SMALL = 1, IVL_DR_MEDIUM = 2, IVL_DR_WEAK = 3, IVL_DR_LARGE = 4, IVL_DR_PULL = 5, IVL_DR_STRONG = 6, IVL_DR_SUPPLY = 7 } ivl_drive_t; /* This is the type of an ivl_expr_t object. The explicit numbers allow additions to the enumeration without causing values to shift and incompatibilities to be introduced. */ typedef enum ivl_expr_type_e { IVL_EX_NONE = 0, IVL_EX_ARRAY = 18, IVL_EX_BACCESS= 19, IVL_EX_BINARY = 2, IVL_EX_CONCAT = 3, IVL_EX_DELAY = 20, IVL_EX_ENUMTYPE = 21, IVL_EX_EVENT = 17, IVL_EX_MEMORY = 4, IVL_EX_NEW = 23, IVL_EX_NULL = 22, IVL_EX_NUMBER = 5, IVL_EX_ARRAY_PATTERN = 26, IVL_EX_PROPERTY = 24, IVL_EX_REALNUM = 16, IVL_EX_SCOPE = 6, IVL_EX_SELECT = 7, IVL_EX_SFUNC = 8, IVL_EX_SHALLOWCOPY = 25, IVL_EX_SIGNAL = 9, IVL_EX_STRING = 10, IVL_EX_TERNARY = 11, IVL_EX_UFUNC = 12, IVL_EX_ULONG = 13, IVL_EX_UNARY = 14 } ivl_expr_type_t; typedef enum ivl_select_type_e ENUM_UNSIGNED_INT { IVL_SEL_OTHER = 0, IVL_SEL_IDX_UP = 1, IVL_SEL_IDX_DOWN = 2 } ivl_select_type_t; /* This is the type code for an ivl_net_logic_t object. */ typedef enum ivl_logic_e { IVL_LO_NONE = 0, IVL_LO_AND = 1, IVL_LO_BUF = 2, IVL_LO_BUFIF0 = 3, IVL_LO_BUFIF1 = 4, IVL_LO_BUFT = 24, /* transparent bufz. (NOT "tri-state") */ IVL_LO_BUFZ = 5, IVL_LO_CMOS = 22, IVL_LO_EQUIV = 25, IVL_LO_IMPL = 26, IVL_LO_NAND = 6, IVL_LO_NMOS = 7, IVL_LO_NOR = 8, IVL_LO_NOT = 9, IVL_LO_NOTIF0 = 10, IVL_LO_NOTIF1 = 11, IVL_LO_OR = 12, IVL_LO_PMOS = 17, IVL_LO_PULLDOWN = 13, IVL_LO_PULLUP = 14, IVL_LO_RCMOS = 23, IVL_LO_RNMOS = 15, IVL_LO_RPMOS = 16, IVL_LO_XNOR = 18, IVL_LO_XOR = 19, IVL_LO_UDP = 21 } ivl_logic_t; /* This is the type of a ivl_switch_t object */ typedef enum ivl_switch_type_e { IVL_SW_TRAN = 0, IVL_SW_TRANIF0 = 1, IVL_SW_TRANIF1 = 2, IVL_SW_RTRAN = 3, IVL_SW_RTRANIF0 = 4, IVL_SW_RTRANIF1 = 5, IVL_SW_TRAN_VP = 6 } ivl_switch_type_t; /* This is the type of an LPM object. */ typedef enum ivl_lpm_type_e { IVL_LPM_ABS = 32, IVL_LPM_ADD = 0, IVL_LPM_ARRAY = 30, IVL_LPM_CAST_INT = 34, IVL_LPM_CAST_INT2 = 35, IVL_LPM_CAST_REAL = 33, IVL_LPM_CONCAT = 16, IVL_LPM_CONCATZ = 36, /* Transparent concat */ IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */ IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (casex) */ IVL_LPM_CMP_EQZ= 38, /* casez EQ */ IVL_LPM_CMP_WEQ= 41, IVL_LPM_CMP_WNE= 42, IVL_LPM_CMP_EQ = 10, IVL_LPM_CMP_GE = 1, IVL_LPM_CMP_GT = 2, IVL_LPM_CMP_NE = 11, IVL_LPM_CMP_NEE= 19, /* Case NE (!==) */ IVL_LPM_DIVIDE = 12, IVL_LPM_FF = 3, IVL_LPM_LATCH = 40, IVL_LPM_MOD = 13, IVL_LPM_MULT = 4, IVL_LPM_MUX = 5, /* IVL_LPM_PART_BI= 28, / obsolete */ IVL_LPM_PART_VP= 15, /* part select: vector to part */ IVL_LPM_PART_PV= 17, /* part select: part written to vector */ IVL_LPM_POW = 31, IVL_LPM_RE_AND = 20, IVL_LPM_RE_NAND= 21, IVL_LPM_RE_NOR = 22, IVL_LPM_RE_OR = 23, IVL_LPM_RE_XNOR= 24, IVL_LPM_RE_XOR = 25, IVL_LPM_REPEAT = 26, IVL_LPM_SFUNC = 29, IVL_LPM_SHIFTL = 6, IVL_LPM_SHIFTR = 7, IVL_LPM_SIGN_EXT=27, IVL_LPM_SUB = 8, IVL_LPM_SUBSTITUTE=39, /* IVL_LPM_RAM = 9, / obsolete */ IVL_LPM_UFUNC = 14 } ivl_lpm_type_t; /* The path edge type is the edge type used to select a specific delay. */ typedef enum ivl_path_edge_e { IVL_PE_01 = 0, IVL_PE_10, IVL_PE_0z, IVL_PE_z1, IVL_PE_1z, IVL_PE_z0, IVL_PE_0x, IVL_PE_x1, IVL_PE_1x, IVL_PE_x0, IVL_PE_xz, IVL_PE_zx, IVL_PE_COUNT } ivl_path_edge_t; /* Processes are initial, always, or final blocks with a statement. This is the type of the ivl_process_t object. */ typedef enum ivl_process_type_e ENUM_UNSIGNED_INT { IVL_PR_INITIAL = 0, IVL_PR_ALWAYS = 1, IVL_PR_ALWAYS_COMB = 3, IVL_PR_ALWAYS_FF = 4, IVL_PR_ALWAYS_LATCH = 5, IVL_PR_FINAL = 2 } ivl_process_type_t; /* These are the sorts of reasons a scope may come to be. These types are properties of ivl_scope_t objects. */ typedef enum ivl_scope_type_e { IVL_SCT_MODULE = 0, IVL_SCT_FUNCTION= 1, IVL_SCT_TASK = 2, IVL_SCT_BEGIN = 3, IVL_SCT_FORK = 4, IVL_SCT_GENERATE= 5, IVL_SCT_PACKAGE = 6, IVL_SCT_CLASS = 7 } ivl_scope_type_t; /* Signals (ivl_signal_t) that are ports into the scope that contains them have a port type. Otherwise, they are port IVL_SIP_NONE. */ typedef enum OUT { IVL_SIP_NONE = 0, IVL_SIP_INPUT = 1, IVL_SIP_OUTPUT= 2, IVL_SIP_INOUT = 3 } ivl_signal_port_t; /* This is the type code for an ivl_signal_t object. Implicit types are resolved by the core compiler, and integers are converted into signed registers. */ typedef enum ivl_signal_type_e { IVL_SIT_NONE = 0, IVL_SIT_REG = 1, IVL_SIT_TRI = 4, IVL_SIT_TRI0 = 5, IVL_SIT_TRI1 = 6, IVL_SIT_TRIAND = 7, IVL_SIT_TRIOR = 8, IVL_SIT_UWIRE = 9 } ivl_signal_type_t; /* This is the type code for ivl_statement_t objects. */ typedef enum ivl_statement_type_e { IVL_ST_NONE = 0, IVL_ST_NOOP = 1, IVL_ST_ALLOC = 25, IVL_ST_ASSIGN = 2, IVL_ST_ASSIGN_NB = 3, IVL_ST_BLOCK = 4, IVL_ST_CASE = 5, IVL_ST_CASER = 24, /* Case statement with real expressions. */ IVL_ST_CASEX = 6, IVL_ST_CASEZ = 7, IVL_ST_CASSIGN = 8, IVL_ST_CONDIT = 9, IVL_ST_CONTRIB = 27, IVL_ST_DEASSIGN = 10, IVL_ST_DELAY = 11, IVL_ST_DELAYX = 12, IVL_ST_DISABLE = 13, IVL_ST_DO_WHILE = 30, IVL_ST_FORCE = 14, IVL_ST_FOREVER = 15, IVL_ST_FORK = 16, IVL_ST_FORK_JOIN_ANY = 28, IVL_ST_FORK_JOIN_NONE = 29, IVL_ST_FREE = 26, IVL_ST_NB_TRIGGER = 31, IVL_ST_RELEASE = 17, IVL_ST_REPEAT = 18, IVL_ST_STASK = 19, IVL_ST_TRIGGER = 20, IVL_ST_UTASK = 21, IVL_ST_WAIT = 22, IVL_ST_WHILE = 23 } ivl_statement_type_t; /* Case statements can be tagged as unique/unique0/priority. */ typedef enum ivl_case_quality_t { IVL_CASE_QUALITY_BASIC = 0, /* no quality flags */ IVL_CASE_QUALITY_UNIQUE = 1, IVL_CASE_QUALITY_UNIQUE0 = 2, IVL_CASE_QUALITY_PRIORITY = 3 } ivl_case_quality_t; /* SystemVerilog allows a system function to be called as a task. */ typedef enum ivl_sfunc_as_task_e { IVL_SFUNC_AS_TASK_ERROR = 0, IVL_SFUNC_AS_TASK_WARNING = 1, IVL_SFUNC_AS_TASK_IGNORE = 2 } ivl_sfunc_as_task_t; /* This is the type of a variable, and also used as the type for an expression. */ typedef enum ivl_variable_type_e ENUM_UNSIGNED_INT { IVL_VT_VOID = 0, /* Not used */ IVL_VT_NO_TYPE = 1, /* Place holder for missing/unknown type. */ IVL_VT_REAL = 2, IVL_VT_BOOL = 3, IVL_VT_LOGIC = 4, IVL_VT_STRING = 5, IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */ IVL_VT_CLASS = 7, /* SystemVerilog class instances */ IVL_VT_QUEUE = 8, /* SystemVerilog queue instances */ IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */ } ivl_variable_type_t; /* This is the type of the function to apply to a process. */ typedef int (*ivl_process_f)(ivl_process_t net, void*cd); /* This is the type of a function to apply to a scope. The ivl_scope_t parameter is the scope, and the cd parameter is client data that the user passes to the scanner. */ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd); /* Attributes, which can be attached to various object types, have this form. */ typedef enum ivl_attribute_type_e { IVL_ATT_VOID = 0, IVL_ATT_STR, IVL_ATT_NUM } ivl_attribute_type_t; struct ivl_attribute_s { const char*key; ivl_attribute_type_t type; union val_ { const char*str; long num; } val; }; typedef const struct ivl_attribute_s*ivl_attribute_t; /* BRANCH * Branches are analog constructs, a pair of terminals that is used in * branch access functions. Terminal-1 is the reference node (The * "ground") for the purposes of the access function that accesses it. * * SEMANTIC NOTES * All the branches in an island are connected by terminals or by * expressions. The island is the connection of branches that must be * solved together. */ /* extern ivl_scope_t ivl_branch_scope(ivl_branch_t obj); */ extern ivl_nexus_t ivl_branch_terminal(ivl_branch_t obj, int idx); extern ivl_island_t ivl_branch_island(ivl_branch_t obj); /* DELAYPATH * Delaypath objects represent delay paths called out by a specify * block in the Verilog source file. The destination signal references * the path object, which in turn points to the source for the path. * * ivl_path_scope * This returns the scope of the delay path. This scope corresponds * to the scope of the specify-block that led to this path. * * ivl_path_source * This returns the nexus that is the source end of the delay * path. Transitions on the source are the start of the delay time * for this path. * * ivl_path_condit * This returns the nexus that tracks the condition for the * delay. If the delay path is unconditional, this returns nil. * ivl_path_is_condit * Is this a conditional structure? Needed for ifnone. * * ivl_path_is_parallel * This returns true if the path is a parallel connection and * false if the path is a full connection. * * ivl_path_source_posedge * ivl_path_source_negedge * These functions return true if the source is edge sensitive. */ extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj); extern ivl_nexus_t ivl_path_source(ivl_delaypath_t obj); extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t pt); extern ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj); extern int ivl_path_is_condit(ivl_delaypath_t obj); extern int ivl_path_is_parallel(ivl_delaypath_t obj); extern int ivl_path_source_posedge(ivl_delaypath_t obj); extern int ivl_path_source_negedge(ivl_delaypath_t obj); /* DESIGN * When handed a design (ivl_design_t) there are a few things that you * can do with it. The Verilog program has one design that carries the * entire program. Use the design methods to iterate over the elements * of the design. * * ivl_design_delay_sel * Returns the tool delay selection: "MINIMUM", "TYPICAL" or "MAXIMUM"? * * ivl_design_flag * This function returns the string value of a named flag. Flags * come from the "-pkey=value" options to the iverilog command and * are stored in a map for this function. Given the key, this * function returns the value. * * The special key "-o" is the argument to the -o flag of the * command line (or the default if the -o flag is not used) and is * generally how the target learns the name of the output file. * * ivl_design_process * This function scans the processes (threads) in the design. It * calls the user supplied function on each of the processes until * one of the functors returns non-0 or all the processes are * scanned. This function will return 0, or the non-zero value that * was returned from the last scanned process. * * ivl_design_root (ANACHRONISM) * A design has a root named scope that is an instance of the top * level module in the design. This is a hook for naming the * design, or for starting the scope scan. * * ivl_design_roots * A design has some number of root scopes. These are the starting * points for structural elaboration. This function returns to the * caller a pointer to an ivl_scope_t array, and the size of the * array. * * ivl_design_time_precision * A design as a time precision. This is the size in seconds (a * signed power of 10) of a simulation tick. */ extern const char* ivl_design_delay_sel(ivl_design_t des); extern const char* ivl_design_flag(ivl_design_t des, const char*key); extern int ivl_design_process(ivl_design_t des, ivl_process_f fun, void*cd); extern ivl_scope_t ivl_design_root(ivl_design_t des); extern void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes, unsigned int *nscopes); extern int ivl_design_time_precision(ivl_design_t des); extern unsigned ivl_design_consts(ivl_design_t des); extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx); extern unsigned ivl_design_disciplines(ivl_design_t des); extern ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx); /* LITERAL CONSTANTS * Literal constants are nodes with no input and a single constant * output. The form of the output depends on the type of the node. * The output is an array of 4-value bits, using a single char * value for each bit. The bits of the vector are in canonical (lsb * first) order for the width of the constant. * * ivl_const_type * The is the type of the node. * * ivl_const_bits * This returns a pointer to an array of constant characters, * each byte a '0', '1', 'x' or 'z'. The array is *not* nul * terminated. This value is only value if ivl_const_type is * IVL_VT_LOGIC or IVL_VT_BOOL. It returns nil otherwise. * * ivl_const_nex * Return the ivl_nexus_t of the output for the constant. * * ivl_const_scope * Return the scope this constant was defined in. * ivl_const_signed * Return true (!0) if the constant is a signed value, 0 otherwise. * * ivl_const_width * Return the width, in logical bits, of the constant. * * ivl_const_delay * T0 delay for a transition (0, 1 and Z). * * SEMANTIC NOTES * * The const_type of the literal constant must match the * ivl_signal_data_type if the signals that share the nexus of this * node. The compiler makes sure it is so, converting constant values * as needed. * * - IVL_VT_LOGIC * * - IVL_VT_REAL * Real valued constants have a width of 1. The value emitted to the * output is ivl_const_real. */ extern ivl_variable_type_t ivl_const_type(ivl_net_const_t net); extern const char* ivl_const_bits(ivl_net_const_t net); extern ivl_expr_t ivl_const_delay(ivl_net_const_t net, unsigned transition); extern ivl_nexus_t ivl_const_nex(ivl_net_const_t net); extern ivl_scope_t ivl_const_scope(ivl_net_const_t net); extern int ivl_const_signed(ivl_net_const_t net); extern unsigned ivl_const_width(ivl_net_const_t net); extern double ivl_const_real(ivl_net_const_t net); extern const char* ivl_const_file(ivl_net_const_t net); extern unsigned ivl_const_lineno(ivl_net_const_t net); /* extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx); */ /* extern unsigned ivl_const_pins(ivl_net_const_t net); */ /* DISCIPLINES * * Disciplines are Verilog-AMS construct. A discipline is a collection * of attributes that can be attached to a signal. * * FUNCTION SUMMARY * * ivl_discipline_name * This is the name of the discipline in the Verilog-AMS source. * * ivl_discipline_domain * This is the domain: continuous or discrete. * * SEMANTIC NOTES * * The discipline domain will not be IVL_DIS_NONE. The "none" domain * is a place-holder internally for incomplete parsing, and is also * available for code generators to use. */ extern const char*ivl_discipline_name(ivl_discipline_t net); extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net); extern ivl_nature_t ivl_discipline_potential(ivl_discipline_t net); extern ivl_nature_t ivl_discipline_flow(ivl_discipline_t net); extern const char* ivl_nature_name(ivl_nature_t net); /* ENUMERATIONS * * Enumerations are a collections of symbolic names and vector * values. The enumeration has a base type, and a list of names and * values. * * FUNCTION SUMMARY * * ivl_enum_names * This is the number of enumeration names in the enum type. * * ivl_enum_name * Get the string name for an item in the enumeration * * ivl_enum_bits * Get the bits (lsb first) of the enumeration value. The width * of the enumeration should match the length of this string. Every * name also has bits that make up the value. * * ivl_enum_signed * Is the base type for the enum signed? * * ivl_enum_type * Get the data-type for the base type that the enum uses. This * will be either IVL_VT_BOOL or IVL_VT_LOGIC * * ivl_enum_width * Return the bit width of the base type for this enum type. * * SEMANTIC NOTES */ extern unsigned ivl_enum_names(ivl_enumtype_t net); extern const char*ivl_enum_name(ivl_enumtype_t net, unsigned idx); extern const char*ivl_enum_bits(ivl_enumtype_t net, unsigned idx); extern int ivl_enum_signed(ivl_enumtype_t net); extern ivl_variable_type_t ivl_enum_type(ivl_enumtype_t net); extern unsigned ivl_enum_width(ivl_enumtype_t net); extern const char*ivl_enum_file(ivl_enumtype_t net); extern unsigned ivl_enum_lineno(ivl_enumtype_t net); /* EVENTS * * Events are a unification of named events and implicit events * generated by the @ statements. * * FUNCTION SUMMARY * * ivl_event_name (Obsolete) * ivl_event_basename * Return the name of the event. The basename is the name within * the scope, as declared by the user or generated by elaboration. * * ivl_event_scope * All events exist within a scope. * * SEMANTICS NOTES * * Named events (i.e. event objects declared by the Verilog * declaration "event foo") are recognized by the fact that they have * no edge sources. The name of the event as given in the Verilog * source is available from the ivl_event_basename function. * * Named events are referenced in trigger statements. * * Named events have file and line number information. * * Edge events are created implicitly by the @(...) Verilog syntax to * watch for the correct type of edge for the functor being * watched. The nodes to watch are collected into groups based on the * type of edge to be watched for on that node. For example, nodes to * be watched for positive edges are accessed via the ivl_event_npos * and ivl_event_pos functions. */ extern const char* ivl_event_name(ivl_event_t net); extern const char* ivl_event_basename(ivl_event_t net); extern ivl_scope_t ivl_event_scope(ivl_event_t net); extern unsigned ivl_event_nany(ivl_event_t net); extern ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx); extern unsigned ivl_event_nedg(ivl_event_t net); extern ivl_nexus_t ivl_event_edg(ivl_event_t net, unsigned idx); extern unsigned ivl_event_nneg(ivl_event_t net); extern ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx); extern unsigned ivl_event_npos(ivl_event_t net); extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx); extern const char*ivl_event_file(ivl_event_t net); extern unsigned ivl_event_lineno(ivl_event_t net); /* EXPRESSIONS * * These methods operate on expression objects from the * design. Expressions mainly exist in behavioral code. The * ivl_expr_type() function returns the type of the expression node, * and the remaining functions access value bits of the expression. * * ivl_expr_signed * This method returns true (!= 0) if the expression node * represents a signed expression. It is possible for sub- * expressions to be unsigned even if a node is signed, but the * IVL core figures all this out for you. At any rate, this method * can be applied to any expression node. * * ivl_expr_sized * This method returns false (0) if the expression node does not * have a defined size. This is unusual, but may happen for * constant expressions. * * ivl_expr_type * Get the type of the expression node. Every expression node has a * type, which can affect how some of the other expression methods * operate on the node * * ivl_expr_value * Get the data type of the expression node. This uses the variable * type enum to express the type of the expression node. * * ivl_expr_net_type * This is used in some cases to carry more advanced type * descriptions. Over the long run, all type information will be * moved into the ivl_type_t type description method. * * ivl_expr_width * This method returns the bit width of the expression at this * node. It can be applied to any expression node, and returns the * *output* width of the expression node. * * ivl_expr_parameter * This function returns the ivl_parameter_t object that represents * this object, or 0 (nil) if it is not a parameter value. This * function allows the code generator to detect the case where the * expression is a parameter. This will normally only return a * non-nil value for constants. * * ivl_expr_opcode * IVL_EX_BINARY and IVL_EX_UNARY expression nodes include an * opcode from this table: * & -- AND * A -- NAND (~&) * X -- XNOR (~^) * * -- Multiply * * SEMANTIC NOTES * * - IVL_EX_ARRAY * This expression type is a special case of the IVL_EX_SIGNAL where * the target is an array (ivl_signal_t with an array_count) but there * is no index expression. This is used only in the special situation * where the array is passed to a system task/function. The function * ivl_expr_signal returns the ivl_signal_t of the array object, and * from that all the properties of the array can be determined. * * - IVL_EX_BINARY * * - IVL_EX_PROPERTY * This expression represents the property select from a class * type, for example "foo.property" where "foo" is a class handle and * "property" is the name of one of the properties of the class. The * ivl_expr_signal function returns the ivl_signal_t for "foo" and the * data_type for the signal will be IVL_VT_CLASS. * * The ivl_signal_net_type(sig) for the "foo" signal will be a class * type and from there you can get access to the type information. * * Elaboration reduces the properties of a class to a vector numbered * from 0 to the number of properties. The ivl_expr_property_idx() * function gets the index of the selected property into the property * table. That number can be passed to ivl_type_prop_*() functions to * get details about the property. * * If the property is an array, then the ivl_expr_oper1() function * returns the canonical expression for accessing the element of the * property. * * - IVL_EX_NEW * This expression takes one or two operands. The first operand, * returned by ivl_expr_oper1() is the number of elements to create * for the dynamic array. The second operand, if present, is returned * by the ivl_expr_oper2() function. If this returns a non-nil * expression, it is the initial value to be written to the elements * of the array. If the expression is an IVL_EX_ARRAY_PATTERN, then * this is the very special case of a list of values to be written to * array elements. * * - IVL_EX_SELECT * This expression takes two operands, oper1 is the expression to * select from, and oper2 is the selection base. The ivl_expr_width * value is the width of the bit/part select. The ivl_expr_oper1 value * is the base of a vector. The compiler has already figured out any * conversion from signal units to vector units, so the result of * ivl_expr_oper1 should range from 0 to ivl_expr_width(). * * This expression is also used to implement string substrings. If the * sub-expression (oper1) is IVL_VT_STRING, then the base expression * (oper2) is a character address, with 0 the first address of the * string, 1 the second, and so on. This is OPPOSITE how a part select * of a string cast to a vector works, to be aware. The size of the * expression is an even multiple of 8, and is 8 times the number of * characters to pick. * * - IVL_EX_SIGNAL * This expression references a signal vector. The ivl_expr_signal * function gets a handle for the signal that is referenced. The * signal may be an array (see the ivl_signal_array_count function) * that is addressed by the expression returned by the ivl_expr_oper1 * function. This expression returns a *canonical* address. The core * compiler already corrected the expression to account for index * bases. * * The ivl_expr_width function returns the vector width of the signal * word. The ivl_expr_value returns the data type of the word. * * Bit and part selects are not done here. The IVL_EX_SELECT * expression does bit/part selects on the word read from the signal. * * - IVL_EX_STRING * This expression refers to a string constant. The ivl_expr_string * function returns a pointer to the first byte of the string. The * compiler has translated it to a "vvp escaped string" which has * quoting and escapes eliminated. The string may contain octal * escapes (\) so that the string text returned by * ivl_expr_string will only contain graphical characters. It is up to * the target to change the escaped \NNN to the proper byte value when * using this string. No other escape sequences will appear in the * string. Quote (") and slash (\) characters will be delivered in * \NNN form. */ extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net); extern ivl_type_t ivl_expr_net_type(ivl_expr_t net); extern ivl_variable_type_t ivl_expr_value(ivl_expr_t net); extern const char*ivl_expr_file(ivl_expr_t net); extern unsigned ivl_expr_lineno(ivl_expr_t net); /* IVL_EX_NUMBER */ extern const char* ivl_expr_bits(ivl_expr_t net); /* IVL_EX_BACCESS */ extern ivl_branch_t ivl_expr_branch(ivl_expr_t net); /* IVL_EX_UFUNC */ extern ivl_scope_t ivl_expr_def(ivl_expr_t net); /* IVL_EX_DELAY */ extern uint64_t ivl_expr_delay_val(ivl_expr_t net); /* IVL_EX_REALNUM */ extern double ivl_expr_dvalue(ivl_expr_t net); /* IVL_EX_ENUMTYPE */ extern ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net); /* IVL_EX_PROPERTY IVL_EX_SIGNAL IVL_EX_SFUNC IVL_EX_VARIABLE */ extern const char* ivl_expr_name(ivl_expr_t net); /* IVL_EX_BACCESS */ extern ivl_nature_t ivl_expr_nature(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_UNARY */ extern char ivl_expr_opcode(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_NEW IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_NEW IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net); /* IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net); /* and expression */ extern ivl_parameter_t ivl_expr_parameter(ivl_expr_t net); /* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_UFUNC */ extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx); /* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */ extern unsigned ivl_expr_parms(ivl_expr_t net); /* IVL_EX_CONCAT */ extern unsigned ivl_expr_repeat(ivl_expr_t net); /* IVL_EX_SELECT */ extern ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net); /* IVL_EX_EVENT */ extern ivl_event_t ivl_expr_event(ivl_expr_t net); /* IVL_EX_PROPERTY */ extern int ivl_expr_property_idx(ivl_expr_t net); /* IVL_EX_SCOPE */ extern ivl_scope_t ivl_expr_scope(ivl_expr_t net); /* IVL_EX_PROPERTY IVL_EX_SIGNAL */ extern ivl_signal_t ivl_expr_signal(ivl_expr_t net); /* any expression */ extern int ivl_expr_signed(ivl_expr_t net); /* any expression */ extern int ivl_expr_sized(ivl_expr_t net); /* IVL_EX_STRING */ extern const char* ivl_expr_string(ivl_expr_t net); /* IVL_EX_ULONG */ extern unsigned long ivl_expr_uvalue(ivl_expr_t net); /* any expression */ extern unsigned ivl_expr_width(ivl_expr_t net); extern const char* ivl_file_table_item(unsigned idx); extern unsigned ivl_file_table_index(const char *); extern unsigned ivl_file_table_size(void); /* ISLAND * * ivl_island_flag_set * ivl_island_flag_test * Allow the user to test or set a boolean flag associated with the * island. */ extern int ivl_island_flag_set(ivl_island_t net, unsigned flag, int value); extern int ivl_island_flag_test(ivl_island_t net, unsigned flag); extern const char* ivl_logic_file(ivl_net_logic_t net); extern unsigned ivl_logic_lineno(ivl_net_logic_t net); /* LOGIC * These types and functions support manipulation of logic gates. The * ivl_logic_t enumeration identifies the various kinds of gates that * the ivl_net_logic_t can represent. The various functions then * provide access to the bits of information for a given logic device. * * The ivl_net_logic_t nodes are bit-slice devices. That means that * the device may have width (and therefore processes vectors) but * each bit slice of the width is independent. * * ivl_logic_type * This method returns the type of logic gate that the node * represents. The logic type implies the meaning of the various pins. * * ivl_logic_name (obsolete) * This method returns the complete name of the logic gate. Every * gate has a complete name (that includes the scope) even if the * Verilog source doesn't include one. The compiler will choose one * if necessary. * * ivl_logic_basename * This is the name of the gate without the scope part. * * ivl_logic_scope * This is the scope that directly contains the logic device. * * ivl_logic_pins * ivl_logic_pin * Return the nexus for the pin. If two pins are connected * together, then these values are the same. Use the nexus * functions to find other pins that are connected to this nexus. * * ivl_logic_width * This returns the width of the logic array. This does not affect * the number of pins, but implies the width of the vector at each * pin. * * ivl_logic_delay * Logic devices have a delay for each transition (0, 1 and Z). * * ivl_logic_attr (obsolete) * Return the value of a specific attribute, given the key name as * a string. If the key is not defined, then return 0 (null). * * ivl_logic_attr_cnt * ivl_logic_attr_val * These support iterating over logic attributes. The _cnt method * returns the number of attributes attached to the gate, and the * ivl_logic_attr_val returns the value of the attribute. * * SEMANTIC NOTES * The ivl_logic_width applies to all the pins of a logic device. If a * logic device has width, that means that it is actually an array of * logic devices that each process a bit slice of the * inputs/output. That implies that the widths of all the inputs and * the output must be identical. * * The ivl_logic_width and ivl_logic_pins are *not* related. A logic * device has a number of pins that is the number of inputs to a logic * array of identical gates, and the ivl_logic_width, is the width of * the vector into each input pin and out of the output pin. * * The output pin is pin-0. The ivl_logic_driveX functions return the * drive strengths for the output pin-0, and match the drive values * stored in the ivl_nexus_ptr_t object for the pin. * * Logic devices have a logic propagation delay. The delay can be any * expression, although the most common expression is an IVL_EX_NUMBER * for a number value. The expression already includes scaling for the * containing module, so the delay value is always taken to be in * simulation clock ticks. * * If the delay is present, then ivl_logic_delay returns a non-nil * object. If any of the three delays is present, then all three are * present, even if they are all the same. The compiler will translate * shorthands into a complete set of delay expressions. * * The ivl_logic_delay expression will always be an IVL_EX_NUMBER, an * IVL_EX_ULONG, or an IVL_EX_SIGNAL. These expressions can easily be * used in structural contexts. The compiler will take care of * elaborating more complex expressions to nets. * * - IVL_LO_PULLUP/IVL_LO_PULLDOWN * These devices are grouped as logic devices with zero inputs because * the outputs have the same characteristics as other logic * devices. They are special only in that they have zero inputs, and * their drivers typically have strength other than strong. * * - IVL_LO_UDP * User defined primitives (UDPs) are like any other logic devices, in * that they are bit-slice devices. If they have a width, then they * are repeated to accommodate that width, and that implies that the * output and all the inputs must have the same width. * * The IVL_LO_UDP represents instantiations of UDP devices. The * ivl_udp_t describes the implementation. */ extern const char* ivl_logic_name(ivl_net_logic_t net); extern const char* ivl_logic_basename(ivl_net_logic_t net); extern ivl_scope_t ivl_logic_scope(ivl_net_logic_t net); extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net); extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin); extern unsigned ivl_logic_pins(ivl_net_logic_t net); extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net); extern ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition); extern ivl_drive_t ivl_logic_drive0(ivl_net_logic_t net); extern ivl_drive_t ivl_logic_drive1(ivl_net_logic_t net); extern unsigned ivl_logic_width(ivl_net_logic_t net); extern unsigned ivl_logic_is_cassign(ivl_net_logic_t net); /* DEPRECATED */ extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key); extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net); extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx); /* UDP * These methods allow access to the ivl_udp_t definition of a UDP. * The UDP definition is accessed through the ivl_logic_udp method of * an ivl_net_logic_t object. * * ivl_udp_name * This returns the name of the definition of the primitive. * * ivl_udp_nin * This is the number of inputs for the UDP definition. * * ivl_udp_rows * ivl_udp_row * These methods give access to the rows that define the table of * the primitive. * * SEMANTIC NOTES * * - Combinational primitives * These devices have no edge dependencies, and have no table entry * for the current input value. These have ivl_udp_sequ return 0 * (false) and the length of each row is the number of inputs plus 1. * The first N characters correspond to the N inputs of the * device. The next character, the last character, is the output for * that row. * * - Sequential primitives * These devices allow edge transitions, and the rows are 1+N+1 * characters long. The first character is the current output, the * next N characters the current input and the last character is the * new output. * * The ivl_udp_init value is only valid if the device is * sequential. It is the initial value for the output of the storage * element. */ extern int ivl_udp_sequ(ivl_udp_t net); extern unsigned ivl_udp_nin(ivl_udp_t net); extern char ivl_udp_init(ivl_udp_t net); extern const char* ivl_udp_row(ivl_udp_t net, unsigned idx); extern unsigned ivl_udp_rows(ivl_udp_t net); extern const char* ivl_udp_name(ivl_udp_t net); extern const char* ivl_udp_file(ivl_udp_t net); extern unsigned ivl_udp_lineno(ivl_udp_t net); extern const char* ivl_udp_port(ivl_udp_t net, unsigned idx); extern const char* ivl_lpm_file(ivl_lpm_t net); extern unsigned ivl_lpm_lineno(ivl_lpm_t net); /* LPM * These functions support access to the properties of LPM * devices. LPM devices are a variety of devices that handle more * complex structural semantics. They are based on EIA LPM standard * devices, but vary to suite the technical situation. * * These are the functions that apply to all LPM devices: * * ivl_lpm_name (Obsolete) * ivl_lpm_basename * Return the name of the device. The name is the name of the * device with the scope part, and the basename is without the scope. * * ivl_lpm_delay * LPM devices have a delay for each transition (0, 1 and Z). * * ivl_lpm_scope * LPM devices exist within a scope. Return the scope that contains * this device. * * ivl_lpm_type * Return the ivl_lpm_type_t of the specific LPM device. * * ivl_lpm_width * Return the width of the LPM device. What this means depends on * the LPM type, but it generally has to do with the width of the * output data path. * * * These functions apply to a subset of the LPM devices, or may have * varying meaning depending on the device: * * ivl_lpm_base * The IVL_LPM_PART objects use this value as the base (first bit) * of the part select. The ivl_lpm_width is the size of the part. * * ivl_lpm_data * Return the input data nexus for device types that have input * vectors. The "idx" parameter selects which data input is selected. * * ivl_lpm_datab (ANACHRONISM) * This is the same as ivl_lpm_data(net,1), in other words the * second data input. Use the ivl_lpm_data method instead. * * ivl_lpm_q * Return the output data nexus for device types that have a single * output vector. This is most devices, it turns out. * * ivl_lpm_selects * This is the size of the select input for a LPM_MUX device, or the * address bus width of an LPM_RAM. * * ivl_lpm_signed * Arithmetic LPM devices may be signed or unsigned if there is a * distinction. For some devices this gives the signedness of the * output, but not all devices. * * ivl_lpm_size * In addition to a width, some devices have a size. The size is * often the number of inputs per out, i.e., the number of inputs * per bit for a MUX. * * ivl_lpm_trigger * SFUNC and UFUNC devices may have a trigger that forces the * function output to be re-evaluated. * * SEMANTIC NOTES * * - Concatenation (IVL_LPM_CONCAT) * These devices take vectors in and combine them to form a single * output the width specified by ivl_lpm_width. * * The ivl_lpm_q nexus is the output from the concatenation. * * The ivl_lpm_data function returns the connections for the inputs to * the concatenation. The ivl_lpm_size function returns the number of * inputs help by the device. * * - Divide (IVL_LPM_DIVIDE) * The divide operators take two inputs and generate an output. The * ivl_lpm_width returns the width of the result. The width of the * inputs are their own. * * - Multiply (IVL_LPM_MULT) * The multiply takes two inputs and generates an output. Unlike other * arithmetic nodes, the width only refers to the output. The inputs * have independent widths, to reflect the arithmetic truth that the * width of a general multiply is the sum of the widths of the * inputs. In fact, the compiler doesn't assure that the widths of the * inputs add up to the width of the output, but the possibility * exists. It is *not* an error for the sum of the input widths to be * more than the width of the output, although the possibility of * overflow exists at run time. * * The inputs are always treated as unsigned. If the expression is * supposed to be signed, elaboration will generate the necessary sign * extension, so the target need not (must not) consider signedness. * * - Power (IVL_LPM_POW) * The power takes two inputs and generates an output. Unlike other * arithmetic nodes, the width only refers to the output. The inputs * have independent widths, to reflect the arithmetic truth that the * width of a general power is the XXXX of the widths of the * inputs. * * Power may be signed. This indicates the type of the exponent. The * base will always be treated as unsigned. The compiler must ensure * the width of the base is equal to the width of the output to * obtain the correct result when the base is really a signed value. * * - Part Select (IVL_LPM_PART_VP and IVL_LPM_PART_PV) * There are two part select devices, one that extracts a part from a * vector, and another that writes a part of a vector. The _VP is * Vector-to-Part, and _PV is Part-to-Vector. The _VP form is meant to * model part/bin selects in r-value expressions, where the _PV from * is meant to model part selects in l-value nets. * * In both cases, ivl_lpm_data(0) is the input pin, and ivl_lpm_q is the * output. In the case of the _VP device, the vector is input and the * part is the output. In the case of the _PV device, the part is the * input and the vector is the output. * * If the base of the part select is non-constant, then * ivl_lpm_data(1) is non-nil and is the select, or base, address of * the part. If this pin is nil, then the constant base is used * instead. * * Also in both cases, the width of the device is the width of the * part. In the _VP case, this is obvious as the output nexus has the * part width. In the _PV case, this is a little less obvious, but * still correct. The output being written to the wider vector is * indeed the width of the part, even though it is written to a wider * gate. The target will need to handle this case specially. * * - Bi-directional Part Select (IVL_LPM_PART_BI) * This is not exactly a part select but a bi-directional partial link * of two nexa with different widths. This is used to implement tran * devices and inout ports in certain cases. The device width is the * width of the part. The ivl_lpm_q is the part end, and the * ivl_lpm_data(0) is the non-part end. * * - Comparisons (IVL_LPM_CMP_GT/GE/EQ/NE/EEQ/NEE/EQX/EQZ) * These devices have two inputs, available by the ivl_lpm_data() * function, and one output available by the ivl_lpm_q function. The * output width is always 1, but the ivl_lpm_width() returns the width * of the inputs. Both inputs must have the same width. * * The CMP_GE and CMP_GT nodes may also be signed or unsigned, with * the obvious implications. The widths are matched by the compiler * (so the target need not worry about sign extension) but when doing * magnitude compare, the signedness does matter. In any case, the * result of the compare is always unsigned. * * The EQX and EQZ nodes are wildcard compares, where xz bits (EQX) or * z bits (EQZ) in the data(1) operand are treated as wildcards. no * bits in the data(0) operand are wild. This matches the * SystemVerilog convention for the ==? operator. * * - Mux Device (IVL_LPM_MUX) * The MUX device has a q output, a select input, and a number of data * inputs. The ivl_lpm_q output and the ivl_lpm_data inputs all have * the width from the ivl_lpm_width() method. The Select input, from * ivl_lpm_select, has the width ivl_lpm_selects(). * * The ivl_lpm_data() method returns the inputs of the MUX device. The * ivl_lpm_size() method returns the number of data inputs there * are. All the data inputs have the same width, the width of the * ivl_lpm_q output. The type of the device is divined from the * inputs and the Q. All the types must be exactly the same. * * - D-FlipFlop (IVL_LPM_FF) * This device is an edge sensitive register. The ivl_lpm_q output and * single ivl_lpm_data input are the same width, ivl_lpm_width. This * device carries a vector like other LPM devices. * * - Latch (IVL_LPM_LATCH) * This device is an asynchronous latch. The ivl_lpm_q output and * single ivl_lpm_data input are the same width, ivl_lpm_width. This * device carries a vector like other LPM devices. * * - Memory port (IVL_LPM_RAM) (deprecated in favor of IVL_LPM_ARRAY) * These are structural ports into a memory device. They represent * address/data ports of a memory device that the context can hook to * for read or write. Read devices have an ivl_lpm_q output port that * is the data being read. * * The ivl_lpm_memory function returns the ivl_memory_t for the memory * that the port access. The ivl_lpm_width for the port then must * match the ivl_memory_width of the memory device. * * Read or write, the ivl_lpm_select nexus is the address. The * ivl_lpm_selects function returns the vector width of the * address. The range of the address is always from 0 to the memory * size-1 -- the canonical form. It is up to the compiler to generate * offsets to correct for a range declaration. * * Read ports use the ivl_lpm_q as the data output, and write ports * use the ivl_lpm_data(0) as the input. In either case the width of * the vector matches the width of the memory itself. * * - Reduction operators (IVL_LPM_RE_*) * These devices have one input, a vector, and generate a single bit * result. The width from the ivl_lpm_width is the width of the input * vector. * * - Repeat Node (IVL_LPM_REPEAT) * This node takes as input a single vector, and outputs a single * vector. The ivl_lpm_width if this node is the width of the *output* * vector. The ivl_lpm_size() returns the number of times the input is * repeated to get the desired width. The ivl core assures that the * input vector is exactly ivl_lpm_width() / ivl_lpm_size() bits. * * - Sign Extend (IVL_LPM_SIGN_EXT) * This node takes a single input and generates a single output. The * input must be signed, and the output will be a vector sign extended * to the desired width. The ivl_lpm_width() value is the output * width, the input will be whatever it wants to be. * * - Shifts (IVL_LPM_SHIFTL/SHIFTR) * This node takes two inputs, a vector and a shift distance. The * ivl_lpm_data(0) nexus is the vector input, and the ivl_lpm_data(1) * the shift distance. The vector input is the same width as the * output, but the distance has its own width. * * The ivl_lpm_signed() flag means for IVL_LPM_SHIFTR that the right * shift is *signed*. For SHIFTL, then signed-ness is meaningless. * * - System function call (IVL_LPM_SFUNC) * This device represents a netlist call to a system function. The * inputs to the device are passed to a system function, and the * result is sent via the output. The ivl_lpm_q function returns the * output nexus. * * The ivl_lpm_size function returns the number of arguments, and the * ivl_lpm_data(net,N) returns the nexa for the argument. * * The ivl_lpm_string(net) function returns the name of the system * function (i.e. "$display") that was found in the source code. The * compiler does little checking of that name. * * The ivl_lpm_trigger function retrieves the trigger event that * indicates when the system function needs to be re-evaluated. If * there is no trigger event, the system function only needs to be * re-evaluated when a change is detected on its input ports. * * - User Function Call (IVL_LPM_UFUNC) * This device is special as it represents a call to a user defined * function (behavioral code) within a netlist. The inputs to the * function are connected to the net, as is the output. * * The function definition is associated with a scope, and the * ivl_lpm_define function returns the scope that is that definition. * See the ivl_scope_* functions for how to get at the actual * definition. * * As with many LPM nodes, the ivl_lpm_q function returns the nexus * for the signal function return value. The width of this nexus must * exactly match the width of the device from ivl_lpm_width. * * The ivl_lpm_data function retrieves the nexa for all the input * ports. The ivl_lpm_size function returns the number of inputs for * the device, and the ivl_lpm_data() function index argument selects * the port to retrieve. Each port is sized independently. * * The ivl_lpm_trigger function retrieves the trigger event that * indicates when the user function needs to be re-evaluated. If * there is no trigger event, the user function only needs to be * re-evaluated when a change is detected on its input ports. */ extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */ extern const char* ivl_lpm_basename(ivl_lpm_t net); extern ivl_expr_t ivl_lpm_delay(ivl_lpm_t net, unsigned transition); extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net); extern int ivl_lpm_signed(ivl_lpm_t net); extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net); extern unsigned ivl_lpm_width(ivl_lpm_t net); extern ivl_event_t ivl_lpm_trigger(ivl_lpm_t net); /* IVL_LPM_FF */ extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net); extern ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_sync_clr(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net); extern ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net); /* IVL_LPM_ARRAY */ extern ivl_signal_t ivl_lpm_array(ivl_lpm_t net); /* IVL_LPM_PART IVL_LPM_SUBSTITUTE */ extern unsigned ivl_lpm_base(ivl_lpm_t net); /* IVL_LPM_FF */ extern unsigned ivl_lpm_negedge(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net); /* IVL_LPM_UFUNC */ extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net); /* IVL_LPM_FF IVL_LPM_LATCH*/ extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net); /* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT IVL_LPM_MUX IVL_LPM_POW IVL_LPM_SHIFTL IVL_LPM_SHIFTR IVL_LPM_SUB IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE IVL_LPM_LATCH */ extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx); /* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_POW IVL_LPM_SUB IVL_LPM_CMP_EQ IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE */ extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx); /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_POW IVL_LPM_SUB IVL_LPM_UFUNC IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE IVL_LPM_LATCH */ extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net); extern ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net); extern ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net); /* IVL_LPM_MUX */ extern unsigned ivl_lpm_selects(ivl_lpm_t net); /* IVL_LPM_MUX */ extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net); /* IVL_LPM_CONCAT IVL_LPM_MUX IVL_LPM_REPEAT IVL_LPM_UFUNC */ extern unsigned ivl_lpm_size(ivl_lpm_t net); /* IVL_LPM_SFUNC */ extern const char*ivl_lpm_string(ivl_lpm_t net); /* LVAL * The l-values of assignments are concatenation of ivl_lval_t * objects. Each lvi_lval_t object is an assignment to a var or a * memory, through a bit select, part select or word select. * * Var lvals are things like assignments to a part select or a bit * select. Assignment to the whole variable is a special case of a * part select, as is a bit select with a constant expression. * * ivl_lval_width * The width of a vector that this lval can receive. This accounts * for the local part selecting I might to in the lval object, as * well as the target object width. * * ivl_lval_mux (* obsolete *) * * ivl_lval_nest * If the l-value is an object more complex than a variable, then * this returns the nested l-value (and ivl_lval_sig==0). * * ivl_lval_sig * If the l-value is a variable, this method returns the signal * object that is the target of the assign. * * ivl_lval_part_off * The part select of the signal is based here. This is the * canonical index of bit-0 of the part select. The return value is * an ivl_expr_t. If the return value is nil, then take the offset * as zero. Otherwise, evaluate the expression to get the offset. * * ivl_lval_idx * If the l-value is a memory, this method returns an * ivl_expr_t that represents the index expression. Otherwise, it * returns 0. * * ivl_lval_property_idx * If the l-value is a class object, this is the name of a property * to select from the object. If this property is not present (<0) * then the l-value represents the class object itself. * * SEMANTIC NOTES * The ivl_lval_width is not necessarily the same as the width of the * signal or memory word it represents. It is the width of the vector * it receives and assigns. This may be less than the width of the * signal (or even 1) if only a part of the l-value signal is to be * assigned. * * The ivl_lval_part_off is the canonical base of a part or * bit select. * * - Array words * If the l-value is an array, then ivl_lval_idx function will return * an expression that calculates the address of the array word. If * the referenced signal has more than one word, this expression must * be present. If the signal has exactly one word (it is not an array) * then the ivl_lval_idx expression must *not* be present. * * For array words, the ivl_lval_width is the width of the word. * * - Arrayed properties * If the l-value is a class property, then the ivl_lval_idx function * will return an expression if the property is in fact arrayed. The * expression is the canonical index for elements in the property. */ extern unsigned ivl_lval_width(ivl_lval_t net); extern ivl_expr_t ivl_lval_mux(ivl_lval_t net) __attribute__((deprecated)); /* XXXX Obsolete? */ extern ivl_expr_t ivl_lval_idx(ivl_lval_t net); extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net); extern ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net); extern int ivl_lval_property_idx(ivl_lval_t net); extern ivl_signal_t ivl_lval_sig(ivl_lval_t net); extern ivl_lval_t ivl_lval_nest(ivl_lval_t net); /* NEXUS * connections of signals and nodes is handled by single-bit * nexus. These functions manage the ivl_nexus_t object. They also * manage the ivl_nexus_ptr_t objects that are closely related to the * nexus. * * ivl_nexus_name * Each nexus is given a name, typically derived from the signals * connected to it, but completely made up if need be. The name of * every nexus is unique. * * ivl_nexus_ptrs * This function returns the number of pointers that are held by * the nexus. It should always return at least 1. The pointer * proper is accessed by index. * * ivl_nexus_ptr * Return a nexus pointer given the nexus and an index. * * ivl_nexus_set_private * ivl_nexus_get_private * The target module often needs to associate data with a nexus for * later use when the nexus is encountered associated with a * device. These methods allow the code generator to store to or * retrieve from a nexus a void* of private data. This pointer is * guaranteed to be 0 before the target module is invoked. * * Once an ivl_nexus_ptr_t is selected by the ivl_nexus_ptr method, * the properties of the pointer can be accessed by the following * methods: * * ivl_nexus_ptr_pin * This returns the pin number of the device where this nexus * points. It is the bit within the signal or logic device that is * connected to the nexus. * * If the target is an LPM device, then this value is zero, and it * is up to the application to find the pin that refers to this * nexus. The problem is that LPM devices do not have a pinout per * se, the pins all have specific names. * * ivl_nexus_ptr_con * If this is a pointer to a magic constant device, then this * returns the net_const object. * * ivl_nexus_ptr_drive0 * ivl_nexus_ptr_drive1 * These are the 0 and 1 strength values for the devices. For most * devices, these values are fixed by the description in the * original source, with the default as IVL_DR_STRONG. For pins * that are input only, drive0 and drive1 are both IVL_DR_HiZ. * * The strength of strength-aware devices (such as nmos devices) * does not really matter, as long as the output is not * IVL_DR_HiZ. Testing for HiZ drivers is how code generators * detect inputs. * * ivl_nexus_ptr_log * If the target object is an ivl_net_logic_t, this method returns * the object. Otherwise, this method returns 0. * * ivl_nexus_ptr_lpm * If the target object is an ivl_lpm_t, this method returns the * object. Otherwise, this method returns 0. * * ivl_nexus_ptr_sig * If the target object is an ivl_signal_t, this method returns the * object. If the target is not a signal, this method returns 0. * * SEMANTIC NOTES * All the device pins that connect to a nexus have the same * type. That means, for example, that vector pins have the same * width. The compiler will insure this is so. */ extern const char* ivl_nexus_name(ivl_nexus_t net) __attribute__((deprecated)); extern unsigned ivl_nexus_ptrs(ivl_nexus_t net); extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx); extern void ivl_nexus_set_private(ivl_nexus_t net, void*data); extern void* ivl_nexus_get_private(ivl_nexus_t net); extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net); extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net); extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net); extern ivl_branch_t ivl_nexus_ptr_branch(ivl_nexus_ptr_t net); extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net); extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net); extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net); extern ivl_switch_t ivl_nexus_ptr_switch(ivl_nexus_ptr_t net); extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net); /* PARAMETER * Parameters are named constants associated with a scope. The user * may set in the Verilog source the value of parameters, and that * leads to ivl_parameter_t objects contained in the ivl_scope_t * objects. * * Parameters are essentially named constants. These constant values * can be accessed by looking at the scope (using ivl_scope_param) or * they can be discovered when they are used, via the * ivl_expr_parameter function. The fact that a constant has a name * (i.e. is a parameter) does not otherwise impose on the value or * interpretation of the constant expression so far as ivl_target is * concerned. The target may need this information, or may choose to * completely ignore it. * * ivl_parameter_basename * return the name of the parameter. * * ivl_parameter_scope * Return the scope of the parameter. The parameter name is only * unique within its scope. * * ivl_parameter_expr * Return the value of the parameter. This should be a simple * constant expression, an IVL_EX_STRING or IVL_EX_NUMBER. * * ivl_parameter_msb * ivl_parameter_lsb * Returns the MSB and LSB for the parameter. For a parameter without * a range the value is zero based and the width of the expression is * used to determine the MSB. * * ivl_parameter_width * return |MSB - LSB| + 1 * * ivl_parameter_signed * Returns if the parameter was declared to be signed. * * ivl_parameter_local * Return whether parameter was local (localparam, implicit genvar etc) * or not. * * ivl_parameter_is_type * Return whether the parameter is a type parameter or not. * * ivl_parameter_file * ivl_parameter_lineno * Returns the file and line where this parameter is defined */ extern const char* ivl_parameter_basename(ivl_parameter_t net); extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net); extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net); extern int ivl_parameter_msb(ivl_parameter_t net); extern int ivl_parameter_lsb(ivl_parameter_t net); extern unsigned ivl_parameter_width(ivl_parameter_t net); extern int ivl_parameter_signed(ivl_parameter_t net); extern int ivl_parameter_local(ivl_parameter_t net); extern int ivl_parameter_is_type(ivl_parameter_t net); extern const char* ivl_parameter_file(ivl_parameter_t net); extern unsigned ivl_parameter_lineno(ivl_parameter_t net); /* SCOPE * Scopes of various sort have these properties. Use these methods to * access them. Scopes come to exist in the elaborated design * generally when a module is instantiated, though they also come from * named blocks, tasks and functions. * * - module instances (IVL_SCT_MODULE) * A module instance scope may contain events, logic gates, lpm * nodes, signals, and possibly children. The children are further * instances, or function/task scopes. Module instances do *not* * contain a definition. * * - function scopes (IVL_SCT_FUNCTION) * These scopes represent functions. A function may not be a root, * so it is contained within a module instance scope. A function is * required to have a definition (in the form of a statement) and a * signal (IVL_SIG_REG) that is its return value. * * A single function scope is created each time the module with the * definition is instantiated. * * * - task scopes (IVL_SCT_TASK) * [...] * * ivl_scope_attr_cnt * ivl_scope_attr_val * A scope may have attributes attached to it. These functions * allow the target to access the attributes values. * * ivl_scope_children * A scope may in turn contain other scopes. This method iterates * through all the child scopes of a given scope. If the function * returns any value other than 0, the iteration stops and the * method returns that value. Otherwise, iteration continues until * the children run out. * * If the scope has no children, this method will return 0 and * otherwise do nothing. * * ivl_scope_childs * ivl_scope_child * This is an alternative way of getting at the childs scopes of a * given scope. * * ivl_scope_def * Task definition scopes carry a task definition, in the form of * a statement. This method accesses that definition. The * ivl_scope_def function must return a statement for scopes that * are type FUNCTION or TASK, and must return nil otherwise. * * ivl_scope_def_file * ivl_scope_def_lineno * Returns the file and line where this scope is defined. * * ivl_scope_enumerate * ivl_scope_enumerates * Scopes have 0 or more enumeration types in them. * * ivl_scope_event * ivl_scope_events * Scopes have 0 or more event objects in them. * * ivl_scope_file * ivl_scope_lineno * Returns the instantiation file and line for this scope. * * ivl_scope_func_type * ivl_scope_func_signed * ivl_scope_func_width * * If the scope is a function, these function can be used to get * the type of the return value. * * ivl_scope_is_auto * Is the task or function declared to be automatic? * * ivl_scope_is_cell * Is the module defined to be a cell? * * ivl_scope_var * ivl_scope_vars * REMOVED * * ivl_scope_log * ivl_scope_logs * Scopes have 0 or more logic devices in them. A logic device is * represented by ivl_logic_t. * * ivl_scope_lpm * ivl_scope_lpms * Scopes have 0 or more LPM devices in them. These functions access * those devices. * * ivl_scope_name * ivl_scope_basename * Every scope has a hierarchical name. This name is also a prefix * of all the names of objects contained within the scope. The * ivl_scope_basename is the name of the scope without the included * hierarchy. * * ivl_scope_param * ivl_scope_params * A scope has zero or more named parameters. These parameters have * a name and an expression value. * * ivl_scope_parent * If this is a non-root scope, then the parent is the scope that * contains this scope. Otherwise, the parent is nil. * * ivl_scope_port * ivl_scope_ports * Scopes that are functions or tasks have ports defined by * signals. These methods access the ports by name. * * If this scope represents a function, then the ports list * includes the return value, as port 0. The remaining ports are * the input ports in order. * * ivl_scope_sig * ivl_scope_sigs * Scopes have 0 or more signals in them. These signals are * anything that can become and ivl_signal_t, include synthetic * signals generated by the compiler. * * ivl_scope_time_precision * Scopes have their own intrinsic time precision, typically from * the timescale compiler directive. This method returns the * precision as a signed power of 10 value. * * ivl_scope_time_units * Scopes have their own intrinsic time units, typically from the * timescale compiler directive. This method returns the units as a * signed power of 10 value. * * ivl_scope_type * ivl_scope_tname * Scopes have a type and a type name. For example, if a scope is * an instance of module foo, its type is IVL_SCT_MODULE and its * type name is "foo". This is different from the instance name * returned by ivl_scope_name above. */ extern unsigned ivl_scope_attr_cnt(ivl_scope_t net); extern ivl_attribute_t ivl_scope_attr_val(ivl_scope_t net, unsigned idx); extern int ivl_scope_children(ivl_scope_t net, ivl_scope_f func, void*cd); extern ivl_statement_t ivl_scope_def(ivl_scope_t net); extern const char* ivl_scope_def_file(ivl_scope_t net); extern unsigned ivl_scope_def_lineno(ivl_scope_t net); extern size_t ivl_scope_childs(ivl_scope_t net); extern ivl_scope_t ivl_scope_child(ivl_scope_t net, size_t idx); extern unsigned ivl_scope_classes(ivl_scope_t net); extern ivl_type_t ivl_scope_class(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_enumerates(ivl_scope_t net); extern ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_events(ivl_scope_t net); extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx); extern const char* ivl_scope_file(ivl_scope_t net); extern unsigned ivl_scope_is_auto(ivl_scope_t net); extern unsigned ivl_scope_is_cell(ivl_scope_t net); extern unsigned ivl_scope_lineno(ivl_scope_t net); extern unsigned ivl_scope_logs(ivl_scope_t net); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_lpms(ivl_scope_t net); extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx); extern const char* ivl_scope_name(ivl_scope_t net); extern const char* ivl_scope_basename(ivl_scope_t net); extern unsigned ivl_scope_params(ivl_scope_t net); extern ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx); extern ivl_scope_t ivl_scope_parent(ivl_scope_t net); extern unsigned ivl_scope_mod_module_ports(ivl_scope_t net); extern const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx ); extern ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx ); extern unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx ); extern unsigned ivl_scope_ports(ivl_scope_t net); extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx); extern ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_sigs(ivl_scope_t net); extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_switches(ivl_scope_t net); extern ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx); extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net); extern const char* ivl_scope_tname(ivl_scope_t net); extern int ivl_scope_time_precision(ivl_scope_t net); extern int ivl_scope_time_units(ivl_scope_t net); extern ivl_variable_type_t ivl_scope_func_type(ivl_scope_t net); extern int ivl_scope_func_signed(ivl_scope_t net); extern unsigned ivl_scope_func_width(ivl_scope_t net); /* SIGNALS * Signals are named things in the Verilog source, like wires and * regs, and also named things that are created as temporaries during * certain elaboration or optimization steps. A signal may also be a * port of a module or task. * * Signals have a name (obviously) and types. A signal may also be * signed or unsigned. * * ivl_signal_nex * This is the nexus of the signal. This is used for managing * connections to the rest of the net. There is exactly one pin for * each word of a signal. Each word may in turn be a vector. The * word address is the zero-based index for the word. It is up to * the context to translate different bases to the canonical address. * * ivl_signal_array_base * ivl_signal_array_count * ivl_signal_array_addr_swapped * The signal may be arrayed. If so, the array_count is >1. Each * word of the array has its own nexus. The array_base is the * address in the Verilog source for the canonical zero word. This * may be negative, positive or zero. The array addresses may be * reversed/swapped. * * Note that arraying of the signal into words is distinct from the * vectors. The width of a signal is the width of a WORD. * * ivl_signal_dimensions * The signal may be an array (of vectors) in which case this * function returns >0, the number of dimensions of the array. * * ivl_signal_discipline * If the signal has been declared with a domain (Verilog-AMS) then * this function will return a non-nil ivl_discipline_t. * * ivl_signal_msb (deprecated) * ivl_signal_lsb (deprecated) * ivl_signal_packed_dimensions * ivl_signal_packed_msb * ivl_signal_packed_lsb * ivl_signal_width * These functions return the msb and lsb packed indices. The * packed dimensions are declared differently from array * dimensions, like so: * reg [4:1][7:0] sig... * which has two packed dimensions. The [4:1] dimension is the * first, and so forth. If the signal is a scalar, it has 0 * dimension. * * The ivl_signal_msb/ivl_signal_lsb functions are deprecated * versions that only work with variables that have less than two * dimensions. They will return msb==lsb==0 for scalars. * * ivl_signal_port * If the signal is a port to a module, this function returns the * port direction. If the signal is not a port, it returns * IVL_SIP_NONE. * * ivl_signal_signed * A signal, which is a vector, may be signed. In Verilog 2000, any * net or variable may be signed. This function returns true if the * signal is signed. * * ivl_signal_local * A signal that was generated by the compiler as a place holder is * marked as local. * * ivl_signal_forced_net * Return whether the signal is a net that is the subject of a force * statement. * * ivl_signal_type * Return the type of the signal, i.e., reg, wire, tri0, etc. * * ivl_signal_data_type * Return the data type of the signal, i.e. logic, real, bool, * etc. All the signals connected to a nexus should have the same * data type * * ivl_signal_npath * ivl_signal_path * This function returns the delay path object for the signal. The * delay path has this signal as the output, the source is attached * to the delay path itself. * * ivl_signal_name (DEPRECATED) * This function returns the fully scoped hierarchical name for the * signal. The name refers to the entire vector that is the signal. * * NOTE: This function is deprecated. The hierarchical name is too * vague a construct when escaped names can have . characters in * them. Do no use this function in new code, it will disappear. * * ivl_signal_basename * This function returns the name of the signal, without the scope * information. This is the tail of the signal name. Since Verilog * has an escape syntax, this name can contain any ASCII * characters, except NULL or white space. The leading \ and * trailing ' ' of escaped names in Verilog source are not part of * the name, so not included here. * * ivl_signal_attr * Icarus Verilog supports attaching attributes to signals, with * the attribute value (a string) associated with a key. This * function returns the attribute value for the given key. If the * key does not exist, the function returns 0. * * ivl_signal_file * ivl_signal_lineno * Returns the file and line where this signal is defined. */ extern ivl_scope_t ivl_signal_scope(ivl_signal_t net); extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word); extern int ivl_signal_array_base(ivl_signal_t net); extern unsigned ivl_signal_array_count(ivl_signal_t net); extern unsigned ivl_signal_array_addr_swapped(ivl_signal_t net); extern unsigned ivl_signal_dimensions(ivl_signal_t net); extern ivl_discipline_t ivl_signal_discipline(ivl_signal_t net); extern unsigned ivl_signal_packed_dimensions(ivl_signal_t net); extern int ivl_signal_packed_msb(ivl_signal_t net, unsigned dim); extern int ivl_signal_packed_lsb(ivl_signal_t net, unsigned dim); extern int ivl_signal_msb(ivl_signal_t net) __attribute__((deprecated)); extern int ivl_signal_lsb(ivl_signal_t net) __attribute__((deprecated)); extern unsigned ivl_signal_width(ivl_signal_t net); extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net); extern int ivl_signal_module_port_index(ivl_signal_t net); extern int ivl_signal_signed(ivl_signal_t net); extern int ivl_signal_integer(ivl_signal_t net); extern int ivl_signal_local(ivl_signal_t net); extern unsigned ivl_signal_forced_net(ivl_signal_t net); extern unsigned ivl_signal_npath(ivl_signal_t net); extern ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); extern ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net); extern ivl_type_t ivl_signal_net_type(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); extern const char* ivl_signal_file(ivl_signal_t net); extern unsigned ivl_signal_lineno(ivl_signal_t net); extern unsigned ivl_signal_attr_cnt(ivl_signal_t net); extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx); /* ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx); */ /* unsigned ivl_signal_pins(ivl_signal_t net); */ /* * These functions get information about a process. A process is * an initial or always block within the original Verilog source, that * is translated into a type and a single statement. (The statement * may be a compound statement.) * * ivl_process_type * ivl_process_analog * The ivl_process_type function returns the type of the process, * an "initial" or "always" statement. The ivl_process_analog * returns true if the process is analog. * * ivl_process_scope * A process is placed in a scope. The statement within the process * operates within the scope of the process unless there are calls * outside the scope. * * The ivl_process_stmt function gets the statement that forms the * process. See the statement related functions for how to manipulate * statements. * * Processes can have attributes attached to them. the attr_cnt and * attr_val methods return those attributes. */ extern ivl_process_type_t ivl_process_type(ivl_process_t net); extern int ivl_process_analog(ivl_process_t net); extern ivl_scope_t ivl_process_scope(ivl_process_t net); extern ivl_statement_t ivl_process_stmt(ivl_process_t net); extern unsigned ivl_process_attr_cnt(ivl_process_t net); extern ivl_attribute_t ivl_process_attr_val(ivl_process_t net, unsigned idx); extern const char* ivl_process_file(ivl_process_t net); extern unsigned ivl_process_lineno(ivl_process_t net); /* * These functions manage statements of various type. This includes * all the different kinds of statements (as enumerated in * ivl_statement_type_t) that might occur in behavioral code. * * The ivl_statement_type() function returns the type code for the * statement. This is the major type, and implies which of the later * functions are applicable to the statement. * * the ivl_statement_file() and _lineno() functions return the source * file and line number of the statement in the Verilog source. This * information is useful for diagnostic information. */ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net); extern const char* ivl_stmt_file(ivl_statement_t net); extern unsigned ivl_stmt_lineno(ivl_statement_t net); /* * The following functions retrieve specific single values from the * statement. These values are the bits of data and parameters that * make up the statement. Many of these functions apply to more than * one type of statement, so the comment in front of them tells which * statement types can be passed to the function. * * FUNCTION SUMMARY: * * ivl_stmt_block_scope * If the block is named, then there is a scope associated with * this. The code generator may need to know this in order to * handle disable statements. * * ivl_stmt_events * ivl_stmt_needs_t0_trigger * ivl_stmt_nevent * Statements that have event arguments (TRIGGER and WAIT) make * those event objects available through these methods. * * ivl_stmt_lval * ivl_stmt_lvals * Return the number of l-values for an assignment statement, or * the specific l-value. If there is more than 1 l-value, then the * l-values are presumed to be vector values concatenated together * from msb (idx==0) to lsb. * * ivl_stmt_rval * Return the rval expression of the assignment. This is the value * that is to be calculated and assigned to the l-value in all the * assignment statements. * * ivl_stmt_sub_stmt * Some statements contain a single, subordinate statement. An * example is the IVL_ST_WAIT, which contains the statement to be * executed after the wait completes. This method retrieves that * sub-statement. * * SEMANTIC NOTES: * * - Assignments: IVL_ST_ASSIGN, IVL_ST_ASSIGN_NB, IVL_CASSIGN, IVL_ST_FORCE * * The assignments support ivl_stmt_rval to get the r-value expression * that is to be assign to the l-value, and ivl_stmt_lval[s] to get * the l-value that receives the value. The compiler has already made * sure that the types (l-value and r-value) are compatible. * * If the l-value is a vector, then the compiler also makes sure the * expression width of the r-values matches. It handles padding or * operator sizing as needed to get the width exactly right. * * The blocking and non-blocking assignments may also have an internal * delay. These are of the form "lval = # rval;" and is * the internal delay expression. (It is internal because it is inside * the statement.) The ivl_stmt_delay_expr function returns the * expression for the delay, or nil if there is no delay expression. * * The blocking assignment (IVL_ST_ASSIGN) may have an associated * opcode, that can be extracted from ivl_stmt_opcode(). This opcode * is the compressed operator used it statements like this: * foo += * The ivl_stmt_opcode() returns null (0) if this is not a compressed * assignment statement. * * - IVL_ST_CASSIGN * This reflects a procedural continuous assignment to an l-value. The * l-value is the same as any other assignment (use ivl_stmt_lval). * * The value to be assigned is an ivl_expr_t retrieved by the * ivl_stmt_rval function. The run time is expected to calculate the * value of the expression at the assignment, then continuous assign * that constant value. If the expression is non-constant, the code * generator is supposed to know what to do about that, too. * * - IVL_ST_CONTRIB * This is an analog contribution statement. The ivl_stmt_lexp * function returns the l-value expression which is guaranteed to be a * branch access expression. The ivl_stmt_rval returns the r-value * expression for the assignment. * * - IVL_ST_DELAY, IVL_ST_DELAYX * These statement types are delay statements. They are a way to * attach a delay to a statement. The ivl_stmt_sub_stmt() function * gets the statement to be executed after the delay. If this is * IVL_ST_DELAY, then the ivl_stmt_delay_val function gets the * constant delay. If this is IVL_ST_DELAYX, then the * ivl_stmt_delay_expr gets the expression of the delay. In this case, * the expression is not necessarily constant. * * Whether constant or calculated, the resulting delay is in units of * simulation ticks. The compiler has already taken care of converting * the delay to the time scale/precision of the scope. * * - IVL_ST_FORCE * This is very much like IVL_ST_CASSIGN, but adds that l-values can * include nets (tri, wire, etc). Memory words are restricted from * force l-values, and also non-constant bit or part selects. The * compiler will assure these constraints are met. * * - IVL_ST_TRIGGER * This represents the "-> name" statement that sends a trigger to a * named event. The ivl_stmt_nevent function should always return 1, * and the ivl_stmt_events(net,0) function returns the target event, * as an ivl_event_t. The only behavior of this statement is to send a * "trigger" to the target event. * * - IVL_ST_WAIT * This is the edge sensitive wait (for event) statement. The * statement contains an array of events that are to be tested, and a * single statement that is to be executed when any of the array of * events triggers. * * the ivl_stmt_events function accesses the array of events to wait * for, and the ivl_stmt_sub_stmt function gets the sub-statement, * which may be null, that is to be executed when an event * triggers. The statement waits even if the sub-statement is nul. */ /* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */ extern unsigned ivl_stmt_block_count(ivl_statement_t net); /* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */ extern ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net); /* IVL_ST_BLOCK, IVL_ST_FORK, IVL_ST_FORK_JOIN_ANY, IVL_ST_FORK_JOIN_NONE */ extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i); /* IVL_ST_UTASK IVL_ST_DISABLE */ extern ivl_scope_t ivl_stmt_call(ivl_statement_t net); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern unsigned ivl_stmt_case_count(ivl_statement_t net); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i); /* IVL+ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i); /* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */ extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net); /* IVL_ST_CONDIT */ extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net); /* IVL_ST_CONDIT */ extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_DELAYX */ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net); /* IVL_ST_DELAY */ extern uint64_t ivl_stmt_delay_val(ivl_statement_t net); /* IVL_ST_WAIT IVL_ST_TRIGGER */ extern unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net); extern unsigned ivl_stmt_nevent(ivl_statement_t net); extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx); /* IVL_ST_DISABLE */ extern bool ivl_stmt_flow_control(ivl_statement_t net); /* IVL_ST_CONTRIB */ extern ivl_expr_t ivl_stmt_lexp(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN IVL_ST_FORCE IVL_ST_RELEASE */ extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN IVL_ST_FORCE IVL_ST_RELEASE */ extern unsigned ivl_stmt_lvals(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN */ extern unsigned ivl_stmt_lwidth(ivl_statement_t net); /* IVL_ST_STASK */ extern const char* ivl_stmt_name(ivl_statement_t net); /* IVL_ST_ASSIGN */ extern char ivl_stmt_opcode(ivl_statement_t net); /* IVL_ST_STASK */ extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx); /* IVL_ST_STASK */ extern unsigned ivl_stmt_parm_count(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_CONTRIB IVL_ST_FORCE */ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net); /* IVL_ST_STASK */ extern ivl_sfunc_as_task_t ivl_stmt_sfunc_as_task(ivl_statement_t net); /* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT IVL_ST_WAIT, IVL_ST_WHILE */ extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net); /* SWITCHES * * The switches represent the tran devices in the design. * * FUNCTION SUMMARY * * ivl_switch_type * Return the enumerated value that is the type of the switch. * * ivl_switch_basename * This is the name given to the device in the source code. * * ivl_switch_a * ivl_switch_b * The a and b ports are the two ports of the switch. * * ivl_switch_enable * If the device has an enable (tranifX) then this is the enable * port. * * SEMANTIC NOTES * The a/b ports can be any type, but the types must exactly * match, including vector widths. The enable must be a scalar. * * The IVL_SW_TRAN_VP is an exception to the above. In this case, * the B side may be a different size, and the a side will have a * a fixed width. The unused bits are padded to Z on the A side. */ extern ivl_switch_type_t ivl_switch_type(ivl_switch_t net); extern ivl_scope_t ivl_switch_scope(ivl_switch_t net); extern const char*ivl_switch_basename(ivl_switch_t net); extern ivl_nexus_t ivl_switch_a(ivl_switch_t net); extern ivl_nexus_t ivl_switch_b(ivl_switch_t net); extern ivl_nexus_t ivl_switch_enable(ivl_switch_t net); extern ivl_island_t ivl_switch_island(ivl_switch_t net); /* These are only support for IVL_SW_TRAN_VP switches. */ extern unsigned ivl_switch_width(ivl_switch_t net); extern unsigned ivl_switch_part(ivl_switch_t net); extern unsigned ivl_switch_offset(ivl_switch_t net); extern ivl_expr_t ivl_switch_delay(ivl_switch_t net, unsigned transition); /* Not implemented yet extern unsigned ivl_switch_attr_cnt(ivl_switch_t net); extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx); *** */ extern const char* ivl_switch_file(ivl_switch_t net); extern unsigned ivl_switch_lineno(ivl_switch_t net); /* TYPES * * ivl_type_base * This returns the base type for the type. See the * ivl_variable_type_t definition for the various base types. * * ivl_type_element * Return the type of the element of an array. This is only valid * for array types. * * ivl_type_packed_width * Returns the total width of all packed dimensions. * * ivl_type_signed * Return TRUE if the type represents a signed packed vector or * signed atomic type, and FALSE otherwise. * * SEMANTIC NOTES * * Class types have names and properties. */ extern ivl_variable_type_t ivl_type_base(ivl_type_t net); extern ivl_type_t ivl_type_element(ivl_type_t net); extern unsigned ivl_type_packed_dimensions(ivl_type_t net); extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim); extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim); extern unsigned ivl_type_packed_width(ivl_type_t net); extern int ivl_type_signed(ivl_type_t net); extern const char* ivl_type_name(ivl_type_t net); extern int ivl_type_properties(ivl_type_t net); extern const char* ivl_type_prop_name(ivl_type_t net, int idx); extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx); #if defined(__MINGW32__) || defined (__CYGWIN__) # define DLLEXPORT __declspec(dllexport) #else # define DLLEXPORT #endif extern DLLEXPORT int target_design(ivl_design_t des); extern DLLEXPORT const char* target_query(const char*key); /* target_design The "target_design" function is called once after the whole design is processed and available to the target. The target doesn't return from this function until it is finished with the design. The return value of this function should normally be zero. If the code generator detects errors, however, then the code generator returns a positive number to indicate the approximate number of errors detected (before it gave up.) Return values <0 are reserved for system and infrastructure errors. This function is implemented in the loaded target, and not in the ivl core. This function is how the target module is invoked. */ typedef int (*target_design_f)(ivl_design_t des); typedef const char* (*target_query_f) (const char*key); _END_DECL #undef ENUM_UNSIGNED_INT #endif /* IVL_ivl_target_H */ iverilog-12_0/ivl_target.txt000066400000000000000000000026641435245347300162600ustar00rootroot00000000000000 Icarus Verilog LOADABLE TARGET API (ivl_target) Copyright 2002 Stephen Williams The ivl_target API is the interface available to modules that the Icarus Verilog compiler loads to act as a code generator. The API provides an interface to the elaborated, possibly synthesized, design for code generators that are intended to write netlist files or executable programs. The functions and types of the API are summarized in the ivl_target.h header file. This document describes how the functions and types of the API are used to access and interpret the netlist of the design. 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-12_0/ivl_target_priv.h000066400000000000000000000053741435245347300167310ustar00rootroot00000000000000#ifndef IVL_ivl_target_priv_H #define IVL_ivl_target_priv_H /* * Copyright (c) 2008-2019 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 "ivl_target.h" # include # include # include # include # include class NetScope; /* * This header has declarations related to the ivl_target.h API that * are not to be exported outside of the core via the ivl_target.h * interface. * * (NOTE: A lot of similar definitions exist in the t-dll.h header * file. That is a legacy from an earlier time before the * ivl_target_priv.h header file was started, and those definitions * should gradually be moved over to this header file.) */ /* * This is the root of a design, from the ivl_target point of few. The * ivl_target API uses this as the root for getting at everything else * in the design. */ struct ivl_design_s { int time_precision; ivl_process_t threads_; // Keep arrays of root scopes. std::vector packages; std::vector roots; // This is used to implement the ivl_design_roots function. std::vector root_scope_list; // Keep an array of constants objects. std::vector consts; // Keep a handy array of all of the disciplines in the design. std::valarray disciplines; const class Design*self; }; /* * A branch is a pair of terminals. The elaborator assures that the * terminals have compatible disciplines. */ struct ivl_branch_s { ivl_nexus_t pins[2]; ivl_island_t island; }; /* * Information about islands. Connected branches within a net are * collected into islands. Branches that are purely ddiscrete do not * have disciplines and do not belong to islands. */ struct ivl_island_s { ivl_discipline_t discipline; // user accessible flags. They are initially false, always. std::vector flags; }; extern std::ostream& operator << (std::ostream&o, ivl_drive_t str); #endif /* IVL_ivl_target_priv_H */ iverilog-12_0/ivlpp/000077500000000000000000000000001435245347300145015ustar00rootroot00000000000000iverilog-12_0/ivlpp/Makefile.in000066400000000000000000000044341435245347300165530ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. In order to redistribute the software in # binary form, you will need a Picture Elements Binary Software # License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = main.o lexor.o all: ivlpp@EXEEXT@ check: all clean: rm -f *.o lexor.c ivlpp@EXEEXT@ distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=ivlpp/$@ ivlpp@EXEEXT@: $O $(CC) $(LDFLAGS) $O -o ivlpp@EXEEXT@ @EXTRALIBS@ lexor.c: $(srcdir)/lexor.lex $(LEX) -t $< > $@ install: all installdirs installfiles F = ivlpp@EXEEXT@ installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./ivlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@" lexor.o: lexor.c globals.h main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h iverilog-12_0/ivlpp/globals.h000066400000000000000000000036551435245347300163060ustar00rootroot00000000000000#ifndef IVL_globals_H #define IVL_globals_H /* * Copyright (c) 1999-2017 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 extern void reset_lexor(FILE*out, char*paths[]); extern void destroy_lexor(void); extern void load_precompiled_defines(FILE*src); extern void define_macro(const char*name, const char*value, int keyword, int argc); extern void free_macros(void); extern void dump_precompiled_defines(FILE*out); /* These variables contain the include directories to be searched when an include directive in encountered. */ extern char**include_dir; extern unsigned include_cnt; /* Program to use for VHDL processing. */ extern char*vhdlpp_path; /* vhdlpp work directory */ extern char*vhdlpp_work; extern char**vhdlpp_libdir; extern unsigned vhdlpp_libdir_cnt; extern int relative_include; /* This flag is true if #line directives are to be generated. */ extern int line_direct_flag; extern unsigned error_count; extern FILE *depend_file; extern char dep_mode; extern int verbose_flag; extern int warn_redef; extern int warn_redef_all; /* This is the entry to the lexer. */ extern int yylex(void); #endif /* IVL_globals_H */ iverilog-12_0/ivlpp/ivlpp.txt000066400000000000000000000121611435245347300163750ustar00rootroot00000000000000 Copyright (c) 1999 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. THE IVL PREPROCESSOR The ivlpp command is a Verilog preprocessor that handles file inclusion and macro substitution. The program runs separate from the actual compiler so as to ease the task of the compiler proper, and provides a means of preprocessing files off-line. USAGE: ivlpp [options] The parameter is the name of the file to be read and preprocessed. The resulting output is sent to standard output. The valid options include: -Dname[=value] Predefine the symbol ``name'' to have the specified value. If the value is not specified, then ``1'' is used. This is mostly of use for controlling conditional compilation. This option does *not* override existing `define directives in the source file. -F Read ivlpp options from a FLAGS FILE. This is not the same as a file list. This file contains flags, not source files. There may be multiple flags files. -f Read ivlpp input files from a file list. There can be no more than one file list. -I Add a directory to the include path. Normally, only "." is in the search path. The -I flag causes other directories to be searched for a named file. There may be as many -I flags as needed. -L Generate `line directives. The ivl compiler understands these directives and uses them to keep track of the current line of the original source file. This makes error messages more meaningful. -o Send the output to the named file, instead of to standard output. -v Print version and copyright information before processing input files. -V Print version and copyright information, then exit WITHOUT processing any input files. FLAGS FILE A flags file contains flags for use by ivlpp. This is a convenient way for programs to pass complex sets of flags to the ivlpp program. Blank lines and lines that start with "#" are ignored. The latter can be used as comment lines. All other lines are flag lines. Leading and trailing white space are removed before the lines are interpreted. Other lines have the simple format: : The colon character separates a key from the value. The supported keys, with their corresponding values, are: D:name= This is exactly the same as the "-Dname=" described above. I: This is exactly the same as "-I". relative include: The can be "true" or "false". This enables "relative includes" nesting behavior. vhdlpp: Give the path to the vhdlpp program. This program is used to process VHDL input files. LOCATING INCLUDED FILES The ivlpp preprocessor implements the `include directives by substituting the contents of the included file in place of the line with the `include directive. The name that the programmer specifies is a file name. Normally, the preprocessor looks in the current working directory for the named file. However, the ``-I'' flags can be used to specify a path of directories to search for named include files. The current directory will be searched first, followed by all the include directories in the order that the -I flag appears. The exception to this process is include files that have a name that starts with the '/' character. These file names are ``rooted names'' and must be in the rooted location specified. GENERATED LINE DIRECTIVES Compilers generally try to print along with their error messages the file and line number where the error occurred. Icarus Verilog is no exception. However, if a separate preprocessor is actually selecting and opening files, then the line numbers counted by the compiler proper will not reflect the actual line numbers in the source file. To handle this situation, the preprocessor can generate line directives. These directives are lines of the form: `line where is the file name in double-quotes and is the line number in the file. The parser changes the filename and line number counters in such a way that the next line is line number in the file named . For example: `line 6 "foo.vl" 0 // I am on line 6 in file foo.vl. The preprocessor generates a `line directive every time it switches files. That includes starting an included file (`line 1 "foo.vlh" 1) or returning to the including file. iverilog-12_0/ivlpp/lexor.lex000066400000000000000000001722161435245347300163550ustar00rootroot00000000000000%option prefix="yy" %{ /* * Copyright (c) 1999-2022 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 # include # include # include # include # include "globals.h" # include "ivl_alloc.h" static void output_init(void); #define YY_USER_INIT output_init() static void handle_line_directive(void); static void def_start(void); static void def_add_arg(void); static void def_finish(void); static void def_undefine(void); static void do_define(void); static int def_is_done(void); static void def_continue(void); static int is_defined(const char*name); static int macro_needs_args(const char*name); static void macro_start_args(void); static void macro_add_to_arg(int is_whitespace); static void macro_finish_arg(void); static void do_expand(int use_args); static const char* do_magic(const char*name); static const char* macro_name(void); static void include_filename(int macro_str); static void do_include(void); static int load_next_input(void); struct include_stack_t { char* path; /* If the current input is from a file, this member is set. */ FILE* file; int (*file_close)(FILE*); /* If we are reparsing a macro expansion, file is 0 and this * member points to the string in progress */ char* str; char* orig_str; int stringify_flag; unsigned lineno; YY_BUFFER_STATE yybs; struct include_stack_t* next; /* A single line comment can be associated with this include. */ char* comment; }; static unsigned get_line(struct include_stack_t* isp); static const char *get_path(struct include_stack_t* isp); static void emit_pathline(struct include_stack_t* isp); /* * The file_queue is a singly-linked list of the files that were * listed on the command line/file list. */ static struct include_stack_t* file_queue = 0; static int do_expand_stringify_flag = 0; /* * The istack is the inclusion stack. */ static struct include_stack_t* istack = 0; static struct include_stack_t* standby = 0; /* * Keep a stack of active ifdef, so that I can report errors * when there are missing endifs. */ struct ifdef_stack_t { char* path; unsigned lineno; struct ifdef_stack_t* next; }; static struct ifdef_stack_t* ifdef_stack = 0; static void ifdef_enter(void) { struct ifdef_stack_t*cur; cur = (struct ifdef_stack_t*) calloc(1, sizeof(struct ifdef_stack_t)); if (istack->path) cur->path = strdup(istack->path); cur->lineno = istack->lineno; cur->next = ifdef_stack; ifdef_stack = cur; } static void ifdef_leave(void) { struct ifdef_stack_t* cur; assert(ifdef_stack); cur = ifdef_stack; ifdef_stack = cur->next; /* If either path is from a non-file context e.g.(macro expansion) * we assume that the non-file part is from this file. */ if (istack->path != NULL && cur->path != NULL && strcmp(istack->path,cur->path) != 0) { fprintf(stderr, "%s:%u: warning: This `endif matches an ifdef " "in another file.\n", istack->path, istack->lineno+1); fprintf(stderr, "%s:%u: This is the odd matched `ifdef.\n", cur->path, cur->lineno+1); } free(cur->path); free(cur); } #define YY_INPUT(buf,result,max_size) do { \ if (istack->file) { \ size_t rc = fread(buf, 1, max_size, istack->file); \ result = (rc == 0) ? YY_NULL : rc; \ } else { \ /* We are expanding a macro. Handle the SV `` delimiter. \ If the delimiter terminates a defined macro usage, leave \ it in place, otherwise remove it now. */ \ if (!(yytext[0] == '`' && is_defined(yytext+1))) { \ while ((istack->str[0] == '`') && \ (istack->str[1] == '`')) { \ istack->str += 2; \ } \ } \ if (*istack->str == 0) { \ result = YY_NULL; \ } else { \ buf[0] = *istack->str++; \ result = 1; \ } \ } \ } while (0) static int comment_enter = 0; static int pragma_enter = 0; static int string_enter = 0; static int prev_state = 0; static int ma_parenthesis_level = 0; %} %option stack %option noinput %option noyy_top_state %option noyywrap %x PPINCLUDE %x PPCCOMMENT %x DEF_NAME %x DEF_ESC %x DEF_ARG %x DEF_SEP %x DEF_TXT %x MN_ESC %x MA_START %x MA_ADD %x CCOMMENT %x IFCCOMMENT %x PCOMENT %x CSTRING %x ERROR_LINE %x IFDEF_NAME %x IFNDEF_NAME %s IFDEF_TRUE %x IFDEF_FALSE %x IFDEF_SUPR %x ELSIF_NAME %x ELSIF_SUPR %s ELSE_TRUE %x ELSE_SUPR W [ \t\b\f]+ /* The grouping parentheses are necessary for compatibility with * older versions of flex (at least 2.5.31); they are supposed to * be implied, according to the flex manual. */ keywords (line|include|define|undef|ifdef|ifndef|else|elsif|endif) %% /* Recognize and handle the `line directive. Also pass it through to * the output so the main compiler is aware of the change. */ ^[ \t]?"`line"[ \t]+.+ { handle_line_directive(); ECHO; } /* Detect single line comments, passing them directly to the output. */ "//"[^\r\n]* { ECHO; } /* detect multiline, c-style comments, passing them directly to the * output. This is necessary to allow for ignoring directives that * are included within the comments. */ "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); ECHO; } [^\r\n] { ECHO; } \n\r | \r\n | \n | \r { istack->lineno += 1; fputc('\n', yyout); } "*/" { BEGIN(comment_enter); ECHO; } /* Detect and pass multiline pragma comments. As with C-style * comments, pragma comments are passed through, and preprocessor * directives contained within are ignored. Contains macros are * expanded, however. */ "(*"{W}?")" { ECHO; } "(*" { pragma_enter = YY_START; BEGIN(PCOMENT); ECHO; } [^\r\n] { ECHO; } \n\r | \r\n | \n | \r { istack->lineno += 1; fputc('\n', yyout); } "*)" { BEGIN(pragma_enter); ECHO; } `{keywords} { emit_pathline(istack); fprintf(stderr, "error: macro expansion cannot be directive keywords " "('%s').\n", yytext); error_count += 1; } `[a-zA-Z][a-zA-Z0-9_$]* { if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0); } /* Strings do not contain preprocessor directives or macro expansions. */ \" { string_enter = YY_START; BEGIN(CSTRING); ECHO; } \\\\ | \\\" | \\` { ECHO; } \r\n | \n\r | \n | \r { fputc('\n', yyout); } \" { BEGIN(string_enter); ECHO; } . { ECHO; } /* This set of patterns matches the include directive and the name * that follows it. when the directive ends, the do_include function * performs the include operation. */ ^{W}?`include { yy_push_state(PPINCLUDE); } `{keywords} { emit_pathline(istack); fprintf(stderr, "error: macro expansion cannot be directive keywords " "('%s').\n", yytext); error_count += 1; BEGIN(ERROR_LINE); } `[a-zA-Z][a-zA-Z0-9_]* { if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0); } \"[^\"]*\" { include_filename(0); } /* A normal (") string */ `\"[^\"]*`\" { include_filename(1); } /* A macro (`") string */ [ \t\b\f] { ; } /* Catch single-line comments that share the line with an include * directive. And while I'm at it, I might as well preserve the * comment in the output stream. This will be printed after the * file has been included. For simplicity, if there is more than * one comment on the line, only the first one will be preserved. */ "//"[^\r\n]* | "/*"[^\r\n]*"*/" { if (!standby->comment) standby->comment = strdup(yytext); } /* Now catch the start of a multi-line comment. In this case we * discard the comment then execute the inclusion. */ "/*" { BEGIN(PPCCOMMENT); } [^\r\n] {} \n\r | \r\n | \n | \r { istack->lineno += 1; } "*/" { yy_pop_state(); do_include(); } /* These finish the include directive (EOF or EOL) so I revert the * lexor state and execute the inclusion. */ /* There is a bug in flex <= 2.5.34 that prevents the continued action '|' * from working properly when the final action is associated with <>. * Therefore, the action is repeated. */ \r\n | \n\r | \n | \r { istack->lineno += 1; yy_pop_state(); do_include(); } <> { istack->lineno += 1; yy_pop_state(); do_include(); } /* Anything that is not matched by the above is an error of some * sort. Print an error message and absorb the rest of the line. */ . { emit_pathline(istack); fprintf(stderr, "error: malformed `include directive. Did you quote the file name?\n"); error_count += 1; BEGIN(ERROR_LINE); } /* Detect the define directive, and match the name. If followed by a * '(', collect the formal arguments. Consume any white space, then * go into DEF_TXT mode and collect the defined value. */ `define{W} { yy_push_state(DEF_NAME); } {keywords}{W}? { emit_pathline(istack); fprintf(stderr, "error: malformed `define directive: macro names " "cannot be directive keywords ('%s')\n", yytext); error_count += 1; BEGIN(ERROR_LINE); } [a-zA-Z_][a-zA-Z0-9_$]*"("{W}? { BEGIN(DEF_ARG); def_start(); } [a-zA-Z_][a-zA-Z0-9_$]*{W}? { BEGIN(DEF_TXT); def_start(); } \\ { BEGIN(DEF_ESC); } [^ \t\b\f\n\r]+{W}"("{W}? { BEGIN(DEF_ARG); def_start(); } [^ \t\b\f\n\r]+{W} { BEGIN(DEF_TXT); def_start(); } /* define arg: = */ [a-zA-Z_][a-zA-Z0-9_$]*{W}*"="[^,\)]*{W}? { BEGIN(DEF_SEP); def_add_arg(); } /* define arg: */ [a-zA-Z_][a-zA-Z0-9_$]*{W}? { BEGIN(DEF_SEP); def_add_arg(); } ","{W}? { BEGIN(DEF_ARG); } ")"{W}? { BEGIN(DEF_TXT); } "//"[^\r\n]* { ECHO; } "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); ECHO; } {W} {} (\n|"\r\n"|"\n\r"|\r){W}? { istack->lineno += 1; fputc('\n', yyout); } . { emit_pathline(istack); fprintf(stderr, "error: malformed `define directive ('%s').\n", yytext); error_count += 1; BEGIN(ERROR_LINE); } .*[^\r\n] { do_define(); } (\n|"\r\n"|"\n\r"|\r) { if (def_is_done()) { def_finish(); yy_pop_state(); } else { def_continue(); } istack->lineno += 1; fputc('\n', yyout); } /* If the define is terminated by an EOF, then finish the define * whether there was a continuation or not. */ <> { def_finish(); istack->lineno += 1; fputc('\n', yyout); yy_pop_state(); if (!load_next_input()) yyterminate(); } `undef{W}[a-zA-Z_][a-zA-Z0-9_$]*{W}?.* { def_undefine(); } /* Detect conditional compilation directives, and parse them. If I * find the name defined, switch to the IFDEF_TRUE state and stay * there until I get an `else or `endif. Otherwise, switch to the * IFDEF_FALSE state and start tossing data. * * Handle suppressed `ifdef with an additional suppress start * condition that stacks on top of the IFDEF_FALSE so that output is * not accidentally turned on within nested ifdefs. */ `ifdef{W} { ifdef_enter(); yy_push_state(IFDEF_NAME); } `ifndef{W} { ifdef_enter(); yy_push_state(IFNDEF_NAME); } `ifdef{W} | `ifndef{W} { ifdef_enter(); yy_push_state(IFDEF_SUPR); } `elsif{W} | `elsif{W} { prev_state = YYSTATE; BEGIN(ELSIF_SUPR); } `elsif{W} { prev_state = YYSTATE; BEGIN(ELSIF_NAME); } `else | `else { BEGIN(ELSE_SUPR); } `else { BEGIN(ELSE_TRUE); } [a-zA-Z_][a-zA-Z0-9_$]* { if (is_defined(yytext)) BEGIN(IFDEF_TRUE); else BEGIN(IFDEF_FALSE); } [a-zA-Z_][a-zA-Z0-9_$]* { if (!is_defined(yytext)) BEGIN(IFDEF_TRUE); else BEGIN(IFDEF_FALSE); } [a-zA-Z_][a-zA-Z0-9_$]* { if (is_defined(yytext)) BEGIN(IFDEF_TRUE); else BEGIN(IFDEF_FALSE); } [a-zA-Z_][a-zA-Z0-9_$]* { BEGIN(IFDEF_SUPR); } "//"[^\r\n]* {} "/*" { comment_enter = YY_START; BEGIN(IFCCOMMENT); } [^\r\n] {} \n\r | \r\n | \n | \r { istack->lineno += 1; fputc('\n', yyout); } "*/" { BEGIN(comment_enter); } [^\r\n] { } \n\r | \r\n | \n | \r { istack->lineno += 1; fputc('\n', yyout); } `endif { ifdef_leave(); yy_pop_state(); } (\n|\r) | . | `ifdef { emit_pathline(istack); fprintf(stderr, "error: `ifdef without a macro name.\n"); error_count += 1; if (YY_START == IFDEF_NAME) { ifdef_leave(); yy_pop_state(); unput(yytext[0]); } } (\n|\r) | . | `ifndef { emit_pathline(istack); fprintf(stderr, "error: `ifndef without a macro name.\n"); error_count += 1; if (YY_START == IFNDEF_NAME) { ifdef_leave(); yy_pop_state(); unput(yytext[0]); } } (\n|\r) | . | `elsif { emit_pathline(istack); fprintf(stderr, "error: `elsif without a macro name.\n"); error_count += 1; if (YY_START != INITIAL) { BEGIN(prev_state); unput(yytext[0]); } } `elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { emit_pathline(istack); fprintf(stderr, "error: `elsif after a matching `else.\n"); error_count += 1; BEGIN(ELSE_SUPR); } `else { emit_pathline(istack); fprintf(stderr, "error: `else after a matching `else.\n"); error_count += 1; BEGIN(ELSE_SUPR); } `elsif{W}[a-zA-Z_][a-zA-Z0-9_$]* { emit_pathline(istack); fprintf(stderr, "error: `elsif without a matching `ifdef.\n"); error_count += 1; } `else { emit_pathline(istack); fprintf(stderr, "error: `else without a matching `ifdef.\n"); error_count += 1; } `endif { emit_pathline(istack); fprintf(stderr, "error: `endif without a matching `ifdef.\n"); error_count += 1; } `{keywords} { emit_pathline(istack); fprintf(stderr, "error: macro expansion cannot be directive keywords " "('%s').\n", yytext); error_count += 1; } /* This pattern notices macros and arranges for them to be replaced. */ `[a-zA-Z_][a-zA-Z0-9_$]* { if (macro_needs_args(yytext+1)) yy_push_state(MA_START); else do_expand(0); } `\\ { yy_push_state(MN_ESC); } [^ \t\b\f\n\r]+ { yy_pop_state(); if (macro_needs_args(yytext)) yy_push_state(MA_START); else do_expand(0); } . { yy_pop_state(); unput(yytext[0]); emit_pathline(istack); fprintf(stderr, "error: malformed macro name.\n"); error_count += 1; } /* Stringified version of macro expansion. This is an Icarus extension. When expanding macro text, the SV usage of `` takes precedence. */ ``[a-zA-Z_][a-zA-Z0-9_$]* { if (istack->file) { assert(do_expand_stringify_flag == 0); do_expand_stringify_flag = 1; fputc('"', yyout); if (macro_needs_args(yytext+2)) yy_push_state(MA_START); else do_expand(0); } else { REJECT; } } /* If we are expanding a macro, remove the SV `` delimiter, otherwise * leave it to be handled by the normal rules. */ `` { if (istack->file) REJECT; } /* If we are expanding a macro, handle the SV `" override. This avoids * entering CSTRING state, thus allowing nested macro expansions. */ `\" { if (!istack->file) fputc('"', yyout); else REJECT; } /* If we are expanding a macro, handle the SV `\`" escape sequence. */ `\\`\" { if (!istack->file) fputs("\\\"", yyout); else REJECT; } \( { BEGIN(MA_ADD); macro_start_args(); } {W} {} (\n|"\r\n"|"\n\r"|\r){W}? { istack->lineno += 1; fputc('\n', yyout); } . { emit_pathline(istack); fprintf(stderr, "error: missing argument list for `%s.\n", macro_name()); error_count += 1; yy_pop_state(); yyless(0); } \"[^\"\n\r]*\" { macro_add_to_arg(0); } \"[^\"\n\r]* { emit_pathline(istack); fprintf(stderr, "error: unterminated string.\n"); error_count += 1; BEGIN(ERROR_LINE); } '[^\n\r]' { macro_add_to_arg(0); } {W} { macro_add_to_arg(1); } [({] { macro_add_to_arg(0); ma_parenthesis_level++; } "," { if (ma_parenthesis_level > 0) macro_add_to_arg(0); else macro_finish_arg(); } [)}] { if (ma_parenthesis_level > 0) { macro_add_to_arg(0); ma_parenthesis_level--; } else { macro_finish_arg(); yy_pop_state(); do_expand(1); } } (\n|"\r\n"|"\n\r"|\r){W}? { macro_add_to_arg(1); istack->lineno += 1; fputc('\n', yyout); } . { macro_add_to_arg(0); } "//"[^\r\n]* { ECHO; } "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); ECHO; } /* Any text that is not a directive just gets passed through to the * output. Very easy. */ [^\r\n] { ECHO; } \n\r | \r\n | \n | \r { istack->lineno += 1; fputc('\n', yyout); } /* Absorb the rest of the line when a broken directive is detected. */ [^\r\n]* { yy_pop_state(); } (\n|"\r\n"|"\n\r"|\r) { yy_pop_state(); istack->lineno += 1; fputc('\n', yyout); } <> { if (!load_next_input()) yyterminate(); } %% /* * Parse a `line directive and set the current file name and line * number accordingly. This ensures we restore the correct name * and line number when returning from an include file or macro * expansion. Ignore an invalid directive - the main compiler * will report the error. */ static void handle_line_directive(void) { char *cp; char *cpr; unsigned long lineno; char*fn_start; char*fn_end; /* Skip any leading space. */ cp = strchr(yytext, '`'); /* Skip the `line directive. */ assert(strncmp(cp, "`line", 5) == 0); cp += 5; /* strtoul skips leading space. */ lineno = strtoul(cp, &cpr, 10); if (cp == cpr || lineno == 0) { return; } cp = cpr; /* Skip the space between the line number and the file name. */ cpr += strspn(cp, " \t"); if (cp == cpr) { return; } cp = cpr; /* Find the starting " and skip it. */ fn_start = strchr(cp, '"'); if (cp != fn_start) { return; } fn_start += 1; /* Find the last ". */ fn_end = strrchr(fn_start, '"'); if (!fn_end) { return; } /* Skip the space after the file name. */ cp = fn_end + 1; cpr = cp; cpr += strspn(cp, " \t"); if (cp == cpr) { return; } cp = cpr; /* Check that the level is correct, we do not need the level. */ if (strspn(cp, "012") != 1) { return; } cp += 1; /* Verify that only space is left. */ cp += strspn(cp, " \t"); if ((size_t)(cp-yytext) != strlen(yytext)) { return; } /* Update the current file name and line number. Subtract 1 from the line number because `line sets the number for the next line, and 1 because our line numbers are zero-based. This will underflow on line 1, but that's OK because we are using unsigned arithmetic. */ assert(istack); istack->path = realloc(istack->path, fn_end-fn_start+1); strncpy(istack->path, fn_start, fn_end-fn_start); istack->path[fn_end-fn_start] = '\0'; istack->lineno = lineno - 2; } /* Defined macros are kept in this table for convenient lookup. As * `define directives are matched (and the do_define() function * called) the tree is built up to match names with values. If a * define redefines an existing name, the new value it taken. */ struct define_t { char* name; char* value; int keyword; /* keywords don't get rescanned for fresh values. */ int argc; char** defaults; int magic; /* 1 for 'magic' macros like __FILE__ and __LINE__. magic * macros cannot be undefined. magic macros are expanded * by do_magic. N.B. DON'T set a magic macro with * argc > 1 or with keyword true. */ struct define_t* left; struct define_t* right; struct define_t* up; }; static struct define_t* def_table = 0; /* * magic macros */ static struct define_t def_FILE; static struct define_t def_LINE = { .name = "__LINE__", .value = "__LINE__", .keyword = 0, .argc = 1, .magic = 1, .left = &def_FILE, .right = 0, .up = 0 }; static struct define_t def_FILE = { .name = "__FILE__", .value = "__FILE__", .keyword = 0, .argc = 1, .magic = 1, .left = 0, .right = 0, .up = &def_LINE }; static struct define_t* magic_table = &def_LINE; /* * helper function for def_lookup */ static struct define_t* def_lookup_internal(const char*name, struct define_t*cur) { if (cur == 0) return 0; assert(cur->up == 0); while (cur) { int cmp = strcmp(name, cur->name); if (cmp == 0) return cur; cur = (cmp < 0) ? cur->left : cur->right; } return 0; } static struct define_t* def_lookup(const char*name) { // first, try a magic macro if(name[0] == '_' && name[1] == '_' && name[2] != '\0') { struct define_t* result = def_lookup_internal(name, magic_table); if(result) { return result; } } // either there was no matching magic macro, or we didn't try looking // look for a normal macro return def_lookup_internal(name, def_table); } static int is_defined(const char*name) { return def_lookup(name) != 0; } /* * The following variables are used to temporarily hold the name and * formal arguments of a macro definition as it is being parsed. As * for C program arguments, def_argc counts the arguments (including * the macro name), the value returned by def_argv(0) points to the * macro name, the value returned by def_argv(1) points to the first * argument, and so on. * * These variables are also used for storing the actual arguments when * a macro is instantiated. */ #define MAX_DEF_ARG 256 /* allows argument IDs to be stored in a single char */ #define DEF_BUF_CHUNK 256 /* * During parse of macro definitions, and the name/arguments in * particular, keep the names and name lengths in a compact stretch of * memory. Note that we do not keep the argument names once the * definition is fully processed, because arguments are always * positional and the definition string is replaced with position * tokens. */ static char* def_buf = 0; static int def_buf_size = 0; static int def_buf_free = 0; static int def_argc = 0; static int def_argo[MAX_DEF_ARG]; /* offset of first character of arg name */ static int def_argl[MAX_DEF_ARG]; /* lengths of arg names. */ static int def_argd[MAX_DEF_ARG]; /* Offset of default value */ /* * Return a pointer to the start of argument 'arg'. Returned pointers * may go stale after a call to def_buf_grow_to_fit. */ static /* inline */ char* def_argv(int arg) { return def_buf + def_argo[arg]; } static void check_for_max_args(void) { if (def_argc == MAX_DEF_ARG) { emit_pathline(istack); fprintf(stderr, "error: too many macro arguments - aborting\n"); error_count += 1; exit(1); } } static void def_buf_grow_to_fit(int length) { while (length >= def_buf_free) { def_buf_size += DEF_BUF_CHUNK; def_buf_free += DEF_BUF_CHUNK; def_buf = realloc(def_buf, def_buf_size); assert(def_buf != 0); } } static void def_start(void) { def_buf_free = def_buf_size; def_argc = 0; def_add_arg(); } static void def_add_arg(void) { int length = yyleng; check_for_max_args(); /* Remove trailing white space and, if necessary, opening brace. */ while (isspace((int)yytext[length - 1])) length--; /* This can happen because we are also processing "argv[0]", the macro name, as a pseudo-argument. The lexor will match that as name(, so chop off the ( here. If we have an escaped name, we also need to strip off the white space that terminates the name. */ if (yytext[length - 1] == '(') { length--; while (isspace((int)yytext[length - 1])) length--; } yytext[length] = 0; char*arg = yytext; char*val; int val_length = 0; /* Break into ARG = value. This happens if the source specifies a default value for the formal argument. In that case, the lexor will match the whole thing as the argument and it is up to us to chop it up to name and value. */ if ( (val=strchr(arg,'=')) ) { *val++ = 0; while (*val && isspace(*val)) val += 1; val_length = strlen(val); while (val_length>0 && isspace(val[val_length-1])) { val_length -= 1; val[val_length] = 0; } /* Strip white space from between arg and "=". */ length = strlen(arg); while (length>0 && isspace(arg[length-1])) { length -= 1; arg[length] = 0; } } /* Make sure there's room in the buffer for the new argument. */ def_buf_grow_to_fit(length); /* Store the new argument name. */ def_argl[def_argc] = length; def_argo[def_argc] = def_buf_size - def_buf_free; strcpy(def_argv(def_argc), arg); def_buf_free -= length + 1; /* If there is a default text, then stash it away as well. */ if (val) { def_buf_grow_to_fit(val_length); def_argd[def_argc] = def_buf_size - def_buf_free; strcpy(def_buf+def_argd[def_argc], val); def_buf_free -= val_length + 1; } else { def_argd[def_argc] = 0; } def_argc += 1; } void define_macro(const char* name, const char* value, int keyword, int argc) { int idx; struct define_t* def; struct define_t* prev; /* Verilog has a very nasty system of macros jumping from * file to file, resulting in a global macro scope. Here * we optionally warn about any redefinitions. * * If istack is empty, we are processing a configuration * or precompiled macro file, so don't want to check for * redefinitions - when a precompiled macro file is used, * it will contain copies of any predefined macros. */ if (warn_redef && istack) { prev = def_lookup(name); if (prev && (warn_redef_all || (strcmp(prev->value, value) != 0))) { emit_pathline(istack); fprintf(stderr, "warning: redefinition of macro %s from value '%s' to '%s'\n", name, prev->value, value); } } def = malloc(sizeof(struct define_t)); def->name = strdup(name); def->value = strdup(value); def->keyword = keyword; def->argc = argc; def->magic = 0; def->left = 0; def->right = 0; def->up = 0; def->defaults = calloc(argc, sizeof(char*)); for (idx = 0 ; idx < argc ; idx += 1) { if (def_argd[idx] == 0) { def->defaults[idx] = 0; } else { def->defaults[idx] = strdup(def_buf+def_argd[idx]); } } if (def_table == 0) { def_table = def; } else { struct define_t* cur = def_table; while (1) { int cmp = strcmp(def->name, cur->name); if (cmp == 0) { free(cur->value); cur->value = def->value; free(def->name); free(def); break; } else if (cmp < 0) { if (cur->left != 0) { cur = cur->left; } else { cur->left = def; def->up = cur; break; } } else { if (cur->right != 0) { cur = cur->right; } else { cur->right = def; def->up = cur; break; } } } } } static void free_macro(struct define_t* def) { int idx; if (def == 0) return; free_macro(def->left); free_macro(def->right); free(def->name); free(def->value); for (idx = 0 ; idx < def->argc ; idx += 1) free(def->defaults[idx]); free(def->defaults); free(def); } void free_macros(void) { free_macro(def_table); } /* * The do_define function accumulates the defined value in these * variables. When the define is over, the def_finish() function * executes the define and clears this text. The define_continue_flag * is set if do_define detects that the definition is to be continued * on the next line. */ static char* define_text = 0; static size_t define_cnt = 0; static int define_continue_flag = 0; /* * The do_magic function puts the expansions of magic macros into * this buffer and returns its address. It reallocs as needed to * fit its whole expansion. Because of this, do_magic is * -NOT REENTRANT-. It is called from do_expand, which strdups * or otherwise copies the result before doing any recursion, so * I don't anticipate any problems. */ static char* magic_text = 0; static size_t magic_cnt = 0; /* * Define a special character code used to mark the insertion point * for arguments in the macro text. This should be a character that * will not occur in the Verilog source code. */ #define ARG_MARK '\a' #define _STR1(x) #x #define _STR2(x) _STR1(x) static int is_id_char(char c) { return isalnum((int)c) || c == '_' || c == '$'; } /* * Find an argument, but only if it is not directly preceded by something * that would make it part of another simple identifier ([a-zA-Z0-9_$]). */ static char *find_arg(char*ptr, char*head, char*arg) { char *cp = ptr; size_t len = strlen(arg); while (1) { /* Look for a candidate match, just return if none is found. */ cp = strstr(cp, arg); if (!cp) break; /* Verify that this match is not in the middle of another identifier. */ if ((cp != head && is_id_char(cp[-1])) || is_id_char(cp[len])) { cp++; continue; } break; } return cp; } /* * Collect the definition. Normally, this returns 0. If there is a * continuation, then return 1 and this function may be called again * to collect another line of the definition. */ static void do_define(void) { char* cp; char* head; char* tail; int added_cnt; int arg; define_continue_flag = 0; /* Look for comments in the definition, and remove them. */ cp = strchr(yytext, '/'); while (cp && *cp) { if (cp[1] == '/') { if (cp[strlen(cp) - 1] == '\\') { define_continue_flag = 1; *cp++ = '\\'; } *cp = 0; break; } if (cp[1] == '*') { tail = strstr(cp+2, "*/"); if (tail == 0) { *cp = 0; fprintf(stderr, "%s:%u: Unterminated comment in define\n", istack->path, istack->lineno+1 ); break; } memmove(cp, tail+2, strlen(tail+2)+1); continue; } cp = strchr(cp+1, '/'); } /* Trim trailing white space. */ cp = yytext + strlen(yytext); while (cp > yytext) { if (!isspace((int)cp[-1])) break; cp -= 1; *cp = 0; } /* Detect the continuation sequence. If I find it, remove it * and the white space that precedes it, then replace all that * with a single newline. */ if ((cp > yytext) && (cp[-1] == '\\')) { cp -= 1; cp[0] = 0; while ((cp > yytext) && isspace((int)cp[-1])) { cp -= 1; *cp = 0; } *cp++ = '\n'; *cp = 0; define_continue_flag = 1; } /* Accumulate this text into the define_text string. */ define_text = realloc(define_text, define_cnt + (cp-yytext) + 1); head = &define_text[define_cnt]; strcpy(head, yytext); define_cnt += cp-yytext; tail = &define_text[define_cnt]; /* If the text for a macro with arguments contains occurrences * of ARG_MARK, issue an error message and suppress the macro. */ if ((def_argc > 1) && strchr(head, ARG_MARK)) { emit_pathline(istack); def_argc = 0; fprintf(stderr, "error: implementation restriction - " "macro text may not contain a %s character\n", _STR2(ARG_MARK)); error_count += 1; } /* Look for formal argument names in the definition, and replace * each occurrence with the sequence ARG_MARK,'\ddd' where ddd is * the formal argument index number. */ added_cnt = 0; for (arg = 1; arg < def_argc; arg++) { int argl = def_argl[arg]; cp = find_arg(head, head, def_argv(arg)); while (cp && *cp) { added_cnt += 2 - argl; if (added_cnt > 0) { char* base = define_text; define_cnt += added_cnt; define_text = realloc(define_text, define_cnt + 1); head = &define_text[head - base]; tail = &define_text[tail - base]; cp = &define_text[cp - base]; added_cnt = 0; } memmove(cp+2, cp+argl, tail-(cp+argl)+1); tail += 2 - argl; *cp++ = ARG_MARK; *cp++ = arg; cp = find_arg(cp, head, def_argv(arg)); } } define_cnt += added_cnt; } /* * Return true if the definition text is done. This is the opposite of * the define_continue_flag. */ static int def_is_done(void) { return !define_continue_flag; } /* * Reset the define_continue_flag. */ static void def_continue(void) { define_continue_flag = 0; } /* * After some number of calls to do_define, this function is called to * assigned value to the parsed name. If there is no value, then * assign the string "" (empty string.) */ static void def_finish(void) { define_continue_flag = 0; if (def_argc <= 0) return; if (!define_text) { define_macro(def_argv(0), "", 0, def_argc); } else { define_macro(def_argv(0), define_text, 0, def_argc); free(define_text); define_text = 0; define_cnt = 0; } def_argc = 0; } static void def_undefine(void) { struct define_t* cur; struct define_t* tail; int idx; /* def_buf is used to store the macro name. Make sure there is * enough space. */ def_buf_grow_to_fit(yyleng); sscanf(yytext, "`undef %s", def_buf); cur = def_lookup(def_buf); if (cur == 0) return; if (cur->magic) return; if (cur->up == 0) { if ((cur->left == 0) && (cur->right == 0)) { def_table = 0; } else if (cur->left == 0) { def_table = cur->right; if (cur->right) cur->right->up = 0; } else if (cur->right == 0) { assert(cur->left); def_table = cur->left; def_table->up = 0; } else { tail = cur->left; while (tail->right) tail = tail->right; tail->right = cur->right; tail->right->up = tail; def_table = cur->left; def_table->up = 0; } } else if (cur->left == 0) { if (cur->up->left == cur) { cur->up->left = cur->right; } else { assert(cur->up->right == cur); cur->up->right = cur->right; } if (cur->right) cur->right->up = cur->up; } else if (cur->right == 0) { assert(cur->left); if (cur->up->left == cur) { cur->up->left = cur->left; } else { assert(cur->up->right == cur); cur->up->right = cur->left; } cur->left->up = cur->up; } else { tail = cur->left; assert(cur->left && cur->right); while (tail->right) tail = tail->right; tail->right = cur->right; tail->right->up = tail; if (cur->up->left == cur) { cur->up->left = cur->left; } else { assert(cur->up->right == cur); cur->up->right = cur->left; } cur->left->up = cur->up; } free(cur->name); free(cur->value); for (idx = 0 ; idx < cur->argc ; idx += 1) free(cur->defaults[idx]); free(cur->defaults); free(cur); } /* * When a macro is instantiated in the source, macro_needs_args() is * used to look up the name and return whether it is a macro that * takes arguments. A pointer to the macro descriptor is stored in * cur_macro so that do_expand() doesn't need to look it up again. */ static struct define_t* cur_macro = 0; static int macro_needs_args(const char*text) { cur_macro = def_lookup(text); if (cur_macro) { return (cur_macro->argc > 1); } else { emit_pathline(istack); fprintf(stderr, "warning: macro %s undefined (and assumed null) at this point.\n", text); return 0; } } static const char* macro_name(void) { return cur_macro ? cur_macro->name : ""; } static void macro_start_args(void) { /* The macro name can be found via cur_macro, so create a null * entry for arg 0. This will be used by macro_finish_arg() to * calculate the buffer location for arg 1. */ if (def_buf) { def_buf_free = def_buf_size - 1; def_buf[0] = 0; } def_argo[0] = 0; def_argl[0] = 0; def_argc = 1; } static void macro_add_to_arg(int is_white_space) { char* tail; int length = yyleng; check_for_max_args(); /* Replace any run of white space with a single space */ if (is_white_space) { yytext[0] = ' '; yytext[1] = 0; length = 1; } /* Make sure there's room in the buffer for the new argument. */ def_buf_grow_to_fit(length); /* Store the new text. */ tail = &def_buf[def_buf_size - def_buf_free]; strcpy(tail, yytext); def_buf_free -= length; } static void macro_finish_arg(void) { int offs; char* head; char* tail; check_for_max_args(); offs = def_argo[def_argc-1] + def_argl[def_argc-1] + 1; head = &def_buf[offs]; tail = &def_buf[def_buf_size - def_buf_free]; /* Eat any leading and trailing white space. */ if ((head < tail) && (*head == ' ')) { offs++; head++; } if ((tail > head) && (*(tail-1) == ' ')) { def_buf_free++; tail--; } *tail = 0; def_argo[def_argc] = offs; def_argl[def_argc] = tail - head; def_buf_free -= 1; def_argc++; } /* * The following variables are used to hold macro expansions that are * built dynamically using supplied arguments. Buffer space is allocated * as the macro is expanded, and is only released once the expansion has * been reparsed. This means that the buffer acts as a stack for nested * macro expansions. * * The expansion buffer is only used for macros with arguments - the * text for simple macros can be taken directly from the macro table. */ #define EXP_BUF_CHUNK 256 static char*exp_buf = 0; static int exp_buf_size = 0; static int exp_buf_free = 0; static void exp_buf_grow_to_fit(int length) { while (length >= exp_buf_free) { exp_buf_size += EXP_BUF_CHUNK; exp_buf_free += EXP_BUF_CHUNK; exp_buf = realloc(exp_buf, exp_buf_size); } } static void expand_using_args(void) { char* head; char* tail; char* dest; int arg; int length; if (def_argc > cur_macro->argc) { emit_pathline(istack); fprintf(stderr, "error: too many arguments for `%s\n", cur_macro->name); error_count += 1; return; } while (def_argc < cur_macro->argc) { if (cur_macro->defaults[def_argc]) { def_argl[def_argc] = 0; def_argc += 1; continue; } emit_pathline(istack); fprintf(stderr, "error: too few arguments for `%s\n", cur_macro->name); error_count += 1; return; } assert(def_argc == cur_macro->argc); head = cur_macro->value; tail = head; while (*tail) { if (*tail != ARG_MARK) { tail++; } else { arg = tail[1]; assert(arg < def_argc); char*use_argv; int use_argl; if (def_argl[arg] == 0 && cur_macro->defaults[arg]) { use_argv = cur_macro->defaults[arg]; use_argl = strlen(use_argv); } else { use_argv = def_argv(arg); use_argl = def_argl[arg]; } length = (tail - head) + use_argl; exp_buf_grow_to_fit(length); dest = &exp_buf[exp_buf_size - exp_buf_free]; memcpy(dest, head, tail - head); dest += tail - head; memcpy(dest, use_argv, use_argl); exp_buf_free -= length; head = tail + 2; tail = head; } } length = tail - head; exp_buf_grow_to_fit(length); dest = &exp_buf[exp_buf_size - exp_buf_free]; memcpy(dest, head, length + 1); exp_buf_free -= length + 1; } /* * When a macro use is discovered in the source, this function is * used to emit the substitution in its place. */ static void do_expand(int use_args) { if (cur_macro) { struct include_stack_t*isp; int head = 0; const char *cp; unsigned escapes = 0; char *str_buf = 0; if (cur_macro->keyword) { fprintf(yyout, "%s", cur_macro->value); if (do_expand_stringify_flag) { do_expand_stringify_flag = 0; fputc('"', yyout); } return; } if (use_args) { int tail = 0; head = exp_buf_size - exp_buf_free; expand_using_args(); tail = exp_buf_size - exp_buf_free; exp_buf_free += tail - head; if (tail == head) return; } isp = (struct include_stack_t*) calloc(1, sizeof(struct include_stack_t)); isp->stringify_flag = do_expand_stringify_flag; do_expand_stringify_flag = 0; if (use_args) { isp->str = &exp_buf[head]; } else if(cur_macro->magic) { // cast const char * to char * to suppress warning, since we won't // be modifying isp->str in place. isp->str = (char*)do_magic(cur_macro->name); } else { isp->str = cur_macro->value; } /* Escape some characters if we are making a string version. */ for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1); if (escapes && isp->stringify_flag) { unsigned idx = 0; str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1); for (cp = isp->str; *cp; cp += 1) { if (*cp == '"') { str_buf[idx] = '\\'; str_buf[idx+1] = '0'; str_buf[idx+2] = '4'; str_buf[idx+3] = '2'; idx += 4; continue; } if (*cp == '\\') { str_buf[idx] = '\\'; str_buf[idx+1] = '1'; str_buf[idx+2] = '3'; str_buf[idx+3] = '4'; idx += 4; continue; } str_buf[idx] = *cp; idx += 1; } str_buf[idx] = 0; idx += 1; exp_buf_free -= idx; isp->str = str_buf; } else isp->str = strdup(isp->str); isp->orig_str = isp->str; isp->next = istack; istack->yybs = YY_CURRENT_BUFFER; istack = isp; yy_switch_to_buffer(yy_create_buffer(istack->file, YY_BUF_SIZE)); } else { if (do_expand_stringify_flag) { do_expand_stringify_flag = 0; fputc('"', yyout); } } } /* * Expand the magic macro named name. Return a buffer containing the expansion. */ static const char* do_magic(const char*name) { size_t desired_cnt = 0; if(!magic_text) magic_text = malloc(24); // unimportant initial size if(!strcmp(name, "__LINE__")) { // istack->lineno is unsigned. the largest it could be is 64 bits. // 2^64 is between 10^19 and 10^20. So the decimal representation of // lineno can't possibly be longer than 23 bytes. I'm generous but // bytes are cheap and this is nobody's critical path. desired_cnt = 24; if(magic_cnt < desired_cnt) { magic_text = realloc(magic_text, desired_cnt); assert(magic_text); magic_cnt = desired_cnt; } int actual_len = snprintf(magic_text, desired_cnt, "%u", get_line(istack)); assert(actual_len >= 0); assert((unsigned) actual_len < desired_cnt); return magic_text; } else if(!strcmp(name, "__FILE__")) { const char *path = get_path(istack); if(path) { desired_cnt = strlen(path)+2+1; // two quotes and a null if(magic_cnt < desired_cnt) { magic_text = realloc(magic_text, desired_cnt); assert(magic_text); magic_cnt = desired_cnt; } int actual_len = snprintf(magic_text, desired_cnt, "\"%s\"", path); assert(actual_len >= 0); assert((unsigned) actual_len < (unsigned)desired_cnt); return magic_text; } } // if we get here, then either there was no magic macro with the requested // name, or for some reason (an error?) we want to return an empty string assert(magic_cnt > 0); magic_text[0] = '\0'; return magic_text; } /* * Include file handling works by keeping an include stack of the * files that are opened and being processed. The first item on the * stack is the current file being scanned. If I get to an include * statement, * * open the new file, * save the current buffer context, * create a new buffer context, * and push the new file information. * * When the file runs out, it is closed and the buffer is deleted * If after popping the current file information there is another * file on the stack, that file's buffer context is restored and * parsing resumes. */ static void output_init(void) { if (line_direct_flag) { fprintf(yyout, "`line 1 \"%s\" 0\n", istack->path); } } static void include_filename(int macro_str) { if(standby) { emit_pathline(istack); fprintf(stderr, "error: malformed `include directive. Extra junk on line?\n"); error_count += 1; exit(1); } standby = malloc(sizeof(struct include_stack_t)); standby->path = strdup(yytext+1+macro_str); standby->path[strlen(standby->path)-1-macro_str] = 0; standby->lineno = 0; standby->comment = NULL; } static void do_include(void) { /* standby is defined by include_filename() */ if (standby->path[0] == '/') { if ((standby->file = fopen(standby->path, "r"))) { standby->file_close = fclose; goto code_that_switches_buffers; } } else { unsigned idx, start = 1; char path[4096]; char *cp; struct include_stack_t* isp; /* Add the current path to the start of the include_dir list. */ isp = istack; while(isp && (isp->path == NULL)) isp = isp->next; assert(isp); strcpy(path, isp->path); cp = strrchr(path, '/'); /* I may need the relative path for a planned warning even when * we are not in relative mode, so for now keep it around. */ if (cp != 0) { *cp = '\0'; include_dir[0] = strdup(path); if (relative_include) start = 0; } for (idx = start ; idx < include_cnt ; idx += 1) { snprintf(path, sizeof(path), "%s/%s", include_dir[idx], standby->path); if ((standby->file = fopen(path, "r"))) { standby->file_close = fclose; /* Free the original path before we overwrite it. */ free(standby->path); standby->path = strdup(path); goto code_that_switches_buffers; } } } emit_pathline(istack); fprintf(stderr, "Include file %s not found\n", standby->path); exit(1); code_that_switches_buffers: /* Clear the current files path from the search list. */ free(include_dir[0]); include_dir[0] = 0; if (depend_file) { if (dep_mode == 'p') { fprintf(depend_file, "I %s\n", standby->path); } else if (dep_mode != 'm') { fprintf(depend_file, "%s\n", standby->path); } } if (line_direct_flag) { fprintf(yyout, "\n`line 1 \"%s\" 1\n", standby->path); } standby->next = istack; standby->stringify_flag = 0; istack->yybs = YY_CURRENT_BUFFER; istack = standby; standby = 0; yy_switch_to_buffer(yy_create_buffer(istack->file, YY_BUF_SIZE)); } /* * walk the include stack until we find an entry with a valid pathname, * and return the line from that entry for use in an error message. * This is the real file and line in which the outermost macro was used. */ static unsigned get_line(struct include_stack_t* isp) { while(isp && (isp->path == NULL)) isp = isp->next; assert(isp); return isp->lineno+1; } /* * walk the include stack until we find an entry with a valid pathname, * and return the path from that entry for use in an error message. * This is the real file and line in which the outermost macro was used. */ static const char* get_path(struct include_stack_t* isp) { while(isp && (isp->path == NULL)) isp = isp->next; assert(isp); return isp->path; } /* walk the include stack until we find an entry with a valid pathname, * and print the file and line from that entry for use in an error message. * The istack entries created by do_expand() for macro expansions do not * contain pathnames. This finds instead the real file in which the outermost * macro was used. */ static void emit_pathline(struct include_stack_t* isp) { while(isp && (isp->path == NULL)) isp = isp->next; assert(isp); fprintf(stderr, "%s:%u: ", isp->path, isp->lineno+1); } static void lexor_done(void) { while (ifdef_stack) { struct ifdef_stack_t*cur = ifdef_stack; ifdef_stack = cur->next; fprintf(stderr, "%s:%u: error: This `ifdef lacks an `endif.\n", cur->path, cur->lineno+1); error_count += 1; free(cur->path); free(cur); } } /* * Use this function to open a source file that is to be * processed. Do NOT use this function for opening include files, * instead only use this file for opening base source files. */ static void open_input_file(struct include_stack_t*isp) { char*cp; int is_vhdl = 0; unsigned idx; isp->file = 0; /* look for a suffix for the input file. If the suffix indicates that this is a VHDL source file, then invoke vhdlpp to get a data stream. */ cp = strrchr(isp->path, '.'); if (cp && vhdlpp_path) { if (strcmp(cp, ".vhd") == 0) { is_vhdl = 1; } else if (strcmp(cp, ".vhdl") == 0) { is_vhdl = 1; } } if (is_vhdl == 0) { isp->file = fopen(isp->path, "r"); isp->file_close = fclose; return; } size_t cmdlen = strlen(vhdlpp_path); cmdlen += strlen(isp->path); cmdlen += 8+strlen(vhdlpp_work); size_t liblen = 1; char*libs = strdup(""); for (idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1) { size_t next_len = 6 + strlen(vhdlpp_libdir[idx]); libs = realloc(libs, liblen+next_len); snprintf(libs+liblen-1, next_len, " -L\"%s\"", vhdlpp_libdir[idx]); liblen = strlen(libs) + 1; } cmdlen += liblen; char*cmd = malloc(cmdlen); snprintf(cmd, cmdlen, "%s -w\"%s\"%s %s", vhdlpp_path, vhdlpp_work, libs, isp->path); if (verbose_flag) fprintf(stderr, "Invoke vhdlpp: %s\n", cmd); isp->file = popen(cmd, "r"); isp->file_close = pclose; free(libs); free(cmd); return; } /* * The load_next_input() function is called by the lexical analyzer * when the current file runs out. When the EOF of the current input * file is matched, this function figures out if this is the end of an * included file (in which case the including file is resumed) or the * end of a base file, in which case the next base source file is * opened. */ static int load_next_input(void) { int line_mask_flag = 0; struct include_stack_t* isp = istack; istack = isp->next; /* Delete the current input buffers, and free the cell. */ yy_delete_buffer(YY_CURRENT_BUFFER); /* If there was a comment for this include print it before we * return to the previous input stream. This technically belongs * to the previous stream, but it should not create any problems * since it is only a comment. */ if (isp->comment) { fprintf(yyout, "%s\n", isp->comment); free(isp->comment); isp->comment = NULL; } if (isp->file) { free(isp->path); assert(isp->file_close); isp->file_close(isp->file); } else { /* If I am printing line directives and I just finished * macro substitution, I should terminate the line and * arrange for a new directive to be printed. */ if (line_direct_flag && istack && istack->path && isp->lineno) { fprintf(yyout, "\n"); } else line_mask_flag = 1; free(isp->orig_str); } if (isp->stringify_flag) fputc('"', yyout); free(isp); /* If I am out of include stack, the main input is * done. Look for another file to process in the input * queue. If none are there, give up. Otherwise, open the file * and continue parsing. */ if (istack == 0) { if (file_queue == 0) { lexor_done(); return 0; } istack = file_queue; file_queue = file_queue->next; istack->next = 0; istack->lineno = 0; open_input_file(istack); if (istack->file == 0) { perror(istack->path); error_count += 1; return 0; } if (line_direct_flag) { fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path); } if (depend_file) { if (dep_mode == 'p') { fprintf(depend_file, "M %s\n", istack->path); } else if (dep_mode != 'i') { fprintf(depend_file, "%s\n", istack->path); } } /* This works around an issue in flex yyrestart() where it * uses yyin to create a new buffer when one does not exist. * I would have assumed that it would use the file argument. * The problem is that we have deleted the buffer and freed * yyin (isp->file) above. */ yyin = 0; yyrestart(istack->file); return 1; } /* Otherwise, resume the input buffer that is the new stack * top. If I need to print a line directive, do so. */ yy_switch_to_buffer(istack->yybs); if (line_direct_flag && istack->path && !line_mask_flag) { fprintf(yyout, "\n`line %u \"%s\" 2\n", istack->lineno+1, istack->path); } return 1; } /* * The dump_precompiled_defines() and load_precompiled_defines() * functions dump/load macro definitions to/from a file. The defines * are in the form: * * ::: * * for easy extraction. The value is already precompiled to handle * macro substitution. The is the number of bytes in the * . This is necessary because the value may contain arbitrary * text, including ':' and \n characters. * * Each record is terminated by a \n character. */ static void do_dump_precompiled_defines(FILE* out, struct define_t* table) { if (!table->keyword) fprintf(out, "%s:%d:%zd:%s\n", table->name, table->argc, strlen(table->value), table->value); if (table->left) do_dump_precompiled_defines(out, table->left); if (table->right) do_dump_precompiled_defines(out, table->right); } void dump_precompiled_defines(FILE* out) { if (def_table) do_dump_precompiled_defines(out, def_table); } void load_precompiled_defines(FILE* src) { char*buf = malloc(4096); size_t buf_len = 4096; int ch; while ((ch = fgetc(src)) != EOF) { char* cp = buf; char* name = 0; int argc = 0; size_t len = 0; *cp++ = ch; while ((ch = fgetc(src)) != EOF && ch != ':') { *cp++ = ch; assert( (size_t)(cp-buf) < buf_len ); } if (ch != ':') return; /* Terminate the name string. */ *cp++ = 0; assert( (size_t)(cp-buf) < buf_len ); /* Read the argc number. (this doesn't need buffer space) */ while (isdigit(ch = fgetc(src))) argc = 10*argc + ch-'0'; if (ch != ':') return; /* Read the value len (this doesn't need buffer space) */ while (isdigit(ch = fgetc(src))) len = 10*len + ch-'0'; if (ch != ':') return; /* Save the name, and start the buffer over. */ name = strdup(buf); /* We now know how big the value should be, so if necessary, reallocate the buffer to be sure we can hold it. */ if ((len+4) >= buf_len) { buf = realloc(buf, len+8); assert(buf); } cp = buf; while (len > 0) { ch = fgetc(src); if (ch == EOF) { free(name); return; } *cp++ = ch; len -= 1; } *cp++ = 0; ch = fgetc(src); if (ch != '\n') { free(name); free(buf); return; } define_macro(name, buf, 0, argc); free(name); } } /* * This function initializes the whole process. The first file is * opened, and the lexor is initialized. The include stack is cleared * and ready to go. */ void reset_lexor(FILE* out, char* paths[]) { unsigned idx; struct include_stack_t* isp; struct include_stack_t* tail = 0; isp = malloc(sizeof(struct include_stack_t)); isp->next = 0; isp->path = strdup(paths[0]); open_input_file(isp); isp->str = 0; isp->lineno = 0; isp->stringify_flag = 0; isp->comment = NULL; if (isp->file == 0) { perror(paths[0]); exit(1); } if (depend_file) { if (dep_mode == 'p') { fprintf(depend_file, "M %s\n", paths[0]); } else if (dep_mode != 'i') { fprintf(depend_file, "%s\n", paths[0]); } } yyout = out; yyrestart(isp->file); assert(istack == 0); istack = isp; /* Now build up a queue of all the remaining file names, so * that load_next_input() can pull them when needed. */ for (idx = 1 ; paths[idx] ; idx += 1) { isp = malloc(sizeof(struct include_stack_t)); isp->path = strdup(paths[idx]); isp->file = 0; isp->str = 0; isp->next = 0; isp->lineno = 0; isp->stringify_flag = 0; isp->comment = NULL; if (tail) tail->next = isp; else file_queue = isp; tail = isp; } } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_lexor(void) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif free(def_buf); free(exp_buf); } iverilog-12_0/ivlpp/main.c000066400000000000000000000332251435245347300155760ustar00rootroot00000000000000const char COPYRIGHT[] = "Copyright (c) 1999-2021 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 "version_base.h" # include "version_tag.h" const char NOTICE[] = " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; # include # include # include # include # include #if defined(HAVE_GETOPT_H) # include #endif # include "globals.h" # include "ivl_alloc.h" #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H) extern int getopt(int argc, char*argv[], const char*fmt); extern int optind; extern const char*optarg; #endif /* Path to the dependency file, if there is one. */ char *dep_path = NULL; /* Dependency file output mode */ char dep_mode = 'a'; /* verbose flag */ int verbose_flag = 0; /* Path to vhdlpp */ char *vhdlpp_path = 0; /* vhdlpp work directory */ char *vhdlpp_work = 0; char**vhdlpp_libdir = 0; unsigned vhdlpp_libdir_cnt = 0; /* * Keep in source_list an array of pointers to file names. The array * is terminated by a pointer to null. */ static char**source_list = 0; static unsigned source_cnt = 0; void add_source_file(const char*name) { if (source_list == 0) { source_list = calloc(2, sizeof(char*)); source_list[0] = strdup(name); source_list[1] = 0; source_cnt = 1; } else { source_list = realloc(source_list, sizeof(char*) * (source_cnt+2)); source_list[source_cnt+0] = strdup(name); source_list[source_cnt+1] = 0; source_cnt += 1; } } char**include_dir = 0; unsigned include_cnt = 0; int relative_include = 0; int line_direct_flag = 0; unsigned error_count = 0; FILE *depend_file = NULL; /* Should we warn about macro redefinitions? */ int warn_redef = 0; int warn_redef_all = 0; static int flist_read_flags(const char*path) { char line_buf[2048]; FILE*fd = fopen(path, "r"); if (fd == 0) { fprintf(stderr, "%s: unable to open for reading.\n", path); return -1; } while (fgets(line_buf, sizeof line_buf, fd) != 0) { /* Skip leading white space. */ char*cp = line_buf + strspn(line_buf, " \t\r\b\f"); /* Remove trailing white space. */ char*tail = cp + strlen(cp); char*arg; while (tail > cp) { if (! isspace((int)tail[-1])) break; tail -= 1; tail[0] = 0; } /* Skip empty lines */ if (*cp == 0) continue; /* Skip comment lines */ if (cp[0] == '#') continue; /* The arg points to the argument to the keyword. */ arg = strchr(cp, ':'); if (arg) *arg++ = 0; if (strcmp(cp,"D") == 0) { char*val = strchr(arg, '='); const char *valo = "1"; if (val) { *val++ = 0; valo = val; } define_macro(arg, valo, 0, 0); } else if (strcmp(cp,"I") == 0) { include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*)); include_dir[include_cnt] = strdup(arg); include_cnt += 1; } else if (strcmp(cp,"keyword") == 0) { char*buf = malloc(strlen(arg) + 2); buf[0] = '`'; strcpy(buf+1, optarg); define_macro(optarg, buf, 1, 0); free(buf); } else if ((strcmp(cp,"Ma") == 0) || (strcmp(cp,"Mi") == 0) || (strcmp(cp,"Mm") == 0) || (strcmp(cp,"Mp") == 0)) { if (dep_path) { fprintf(stderr, "duplicate -M flag.\n"); } else { dep_mode = cp[1]; dep_path = strdup(arg); } } else if (strcmp(cp,"relative include") == 0) { if (strcmp(arg, "true") == 0) { relative_include = 1; } else { relative_include = 0; } } else if (strcmp(cp,"vhdlpp") == 0) { if (vhdlpp_path) { fprintf(stderr, "Ignore multiple vhdlpp flags\n"); } else { vhdlpp_path = strdup(arg); } } else if (strcmp(cp,"vhdlpp-work") == 0) { if (vhdlpp_work) { fprintf(stderr, "Ignore duplicate vhdlpp-work flags\n"); } else { vhdlpp_work = strdup(arg); } } else if (strcmp(cp,"vhdlpp-libdir") == 0) { vhdlpp_libdir = realloc(vhdlpp_libdir, (vhdlpp_libdir_cnt+1)*sizeof(char*)); vhdlpp_libdir[vhdlpp_libdir_cnt] = strdup(arg); vhdlpp_libdir_cnt += 1; } else { fprintf(stderr, "%s: Invalid keyword %s\n", path, cp); } } fclose(fd); return 0; } /* * This function reads from a file a list of file names. Each name * starts with the first non-space character, and ends with the last * non-space character. Spaces in the middle are OK. */ static int flist_read_names(const char*path) { char line_buf[2048]; FILE*fd = fopen(path, "r"); if (fd == 0) { fprintf(stderr, "%s: unable to open for reading.\n", path); return 1; } while (fgets(line_buf, sizeof line_buf, fd) != 0) { char*cp = line_buf + strspn(line_buf, " \t\r\b\f"); char*tail = cp + strlen(cp); while (tail > cp) { if (! isspace((int)tail[-1])) break; tail -= 1; tail[0] = 0; } if (cp < tail) add_source_file(cp); } fclose(fd); return 0; } int main(int argc, char*argv[]) { int opt, idx; unsigned lp; const char*flist_path = 0; unsigned flag_errors = 0; char*out_path = 0; FILE*out; char*precomp_out_path = 0; FILE*precomp_out = NULL; /* Define preprocessor keywords that I plan to just pass. */ /* From 1364-2005 Chapter 19. */ define_macro("begin_keywords", "`begin_keywords", 1, 0); define_macro("celldefine", "`celldefine", 1, 0); define_macro("default_nettype", "`default_nettype", 1, 0); define_macro("end_keywords", "`end_keywords", 1, 0); define_macro("endcelldefine", "`endcelldefine", 1, 0); define_macro("line", "`line", 1, 0); define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0); define_macro("pragma", "`pragma", 1, 0); define_macro("resetall", "`resetall", 1, 0); define_macro("timescale", "`timescale", 1, 0); define_macro("unconnected_drive", "`unconnected_drive", 1, 0); /* From 1364-2005 Annex D. */ define_macro("default_decay_time", "`default_decay_time", 1, 0); define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0); define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0); define_macro("delay_mode_path", "`delay_mode_path", 1, 0); define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0); define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0); /* From other places. */ define_macro("disable_portfaults", "`disable_portfaults", 1, 0); define_macro("enable_portfaults", "`enable_portfaults", 1, 0); define_macro("endprotect", "`endprotect", 1, 0); define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0); define_macro("protect", "`protect", 1, 0); define_macro("suppress_faults", "`suppress_faults", 1, 0); define_macro("uselib", "`uselib", 1, 0); include_cnt = 2; include_dir = malloc(include_cnt*sizeof(char*)); include_dir[0] = 0; /* 0 is reserved for the current files path. */ include_dir[1] = strdup("."); while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vVW:")) != EOF) switch (opt) { case 'F': flist_read_flags(optarg); break; case 'f': if (flist_path) { fprintf(stderr, "%s: duplicate -f flag\n", argv[0]); flag_errors += 1; } flist_path = optarg; break; case 'K': { char*buf = malloc(strlen(optarg) + 2); buf[0] = '`'; strcpy(buf+1, optarg); define_macro(optarg, buf, 1, 0); free(buf); break; } case 'L': line_direct_flag = 1; break; case 'o': if (out_path) { fprintf(stderr, "duplicate -o flag.\n"); } else { out_path = optarg; } break; case 'p': if (precomp_out_path) { fprintf(stderr, "duplicate -p flag.\n"); } else { precomp_out_path = optarg; } break; case 'P': { FILE*src = fopen(optarg, "rb"); if (src == 0) { perror(optarg); exit(1); } load_precompiled_defines(src); fclose(src); break; } case 'W': if (strcmp(optarg, "redef-all") == 0) { warn_redef_all = 1; warn_redef = 1; } else if (strcmp(optarg, "redef-chg") == 0) { warn_redef = 1; } break; case 'v': fprintf(stderr, "Icarus Verilog Preprocessor version " VERSION " (" VERSION_TAG ")\n\n"); fprintf(stderr, "%s\n\n", COPYRIGHT); fputs(NOTICE, stderr); verbose_flag = 1; break; case 'V': fprintf(stdout, "Icarus Verilog Preprocessor version " VERSION " (" VERSION_TAG ")\n\n"); fprintf(stdout, "%s\n\n", COPYRIGHT); fputs(NOTICE, stdout); return 0; default: flag_errors += 1; break; } if (flag_errors) { fprintf(stderr, "\nUsage: %s [-v][-L][-F][-f] ...\n" " -F - Get defines and includes from file\n" " -f - Read the sources listed in the file\n" " -K - Define a keyword macro that I just pass\n" " -L - Emit line number directives\n" " -o - Send the output to \n" " -p - Write precompiled defines to \n" " -P - Read precompiled defines from \n" " -v - Verbose\n" " -V - Print version information and quit\n" " -W - Enable extra ivlpp warning category:\n" " o redef-all - all macro redefinitions\n" " o redef-chg - macro definition changes\n", argv[0]); return flag_errors; } /* Collect the file names on the command line in the source file list, then if there is a file list, read more file names from there. */ for (idx = optind ; idx < argc ; idx += 1) add_source_file(argv[idx]); if (flist_path) { int rc = flist_read_names(flist_path); if (rc != 0) return rc; } /* Figure out what to use for an output file. Write to stdout if no path is specified. */ if (out_path) { out = fopen(out_path, "w"); if (out == 0) { perror(out_path); exit(1); } } else { out = stdout; } if (precomp_out_path) { precomp_out = fopen(precomp_out_path, "wb"); if (precomp_out == 0) { if (out_path) fclose(out); perror(precomp_out_path); exit(1); } } if (dep_path) { depend_file = fopen(dep_path, "a"); if (depend_file == 0) { if (out_path) fclose(out); if (precomp_out) fclose(precomp_out); perror(dep_path); exit(1); } } if (source_cnt == 0) { fprintf(stderr, "%s: No input files given.\n", argv[0]); if (out_path) fclose(out); if (depend_file) fclose(depend_file); if (precomp_out) fclose(precomp_out); return 1; } if (vhdlpp_work == 0) { vhdlpp_work = strdup("ivl_vhdl_work"); } /* Pass to the lexical analyzer the list of input file, and start scanning. */ reset_lexor(out, source_list); if (yylex()) { if (out_path) fclose(out); if (depend_file) fclose(depend_file); if (precomp_out) fclose(precomp_out); return -1; } destroy_lexor(); if (depend_file) fclose(depend_file); if (precomp_out) { dump_precompiled_defines(precomp_out); fclose(precomp_out); } if (error_count) { if (out_path) fprintf(stderr, "%s: had (%u) errors.\n", argv[0], error_count); fprintf(out, "// Icarus preprocessor had (%u) errors.\n", error_count); } if (out_path) fclose(out); /* Free the source and include directory lists. */ for (lp = 0; lp < source_cnt; lp += 1) { free(source_list[lp]); } free(source_list); for (lp = 0; lp < include_cnt; lp += 1) { free(include_dir[lp]); } free(include_dir); /* Free the VHDL library directories, the path and work directory. */ for (lp = 0; lp < vhdlpp_libdir_cnt; lp += 1) { free(vhdlpp_libdir[lp]); } free(vhdlpp_libdir); free(vhdlpp_path); free(vhdlpp_work); free_macros(); return error_count; } iverilog-12_0/ivtest/000077500000000000000000000000001435245347300146655ustar00rootroot00000000000000iverilog-12_0/ivtest/.gitattributes000066400000000000000000000002771435245347300175660ustar00rootroot00000000000000# This test is sensitive to the number of bytes in the text file. ivltests/pr1819452.txt text eol=lf # MSY2 expected results require LF line endings. regression_report-msys2.txt text eol=lf iverilog-12_0/ivtest/.gitignore000066400000000000000000000011031435245347300166500ustar00rootroot00000000000000# Lines that start with '#' are comments. # # This file is for the development branch of Icarus Verilog. # # The following files will be ignored by git. # The log and work directories ivl_vhdl_work/ log/ work/ vpi_log/ vhdl/ # The normal regression output files. regression_report.txt vhdl_regression_report.txt # These should be cleaned up, but ignore them as well. *~ *.o *.vpi *.tmp src/vcddiff vsim vlog95.v tmp_blif.blif tmp_blif.v tmp_blif.vvp # Some tests do not work out of the work directory, so # ignore these files that they leave in the home directory. dump.vcd iverilog-12_0/ivtest/COPYING000066400000000000000000000431061435245347300157240ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: 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) 19yy 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. iverilog-12_0/ivtest/README000066400000000000000000000057471435245347300155620ustar00rootroot00000000000000#################### # # Main test script # #################### There are a group of tests that are meant to exercise the compiler and the run time. To run them just type: ./regress or perl vvp_reg.pl or if perl is located in /usr/bin ./vvp_reg.pl The output from these tests are displayed on the screen and are also placed in the regression_report.txt file. The expected output for the current development release is located in the regression_report-devel.txt file. The expected output for stable (released) versions can be found in files named regression_report-v.txt. The results from individual tests can be found in the log directory and gold files, when needed, are in the gold directory. The source files can be found in the ivltests and contrib directories. The list of tests and how they are run are in the regress-*.list files. To check a specific suffixed version of Icarus Verilog use the --suffix= flag to tell the script which version to run e.g.(--suffix=-10 will test iverilog-10, etc.). You can also run the test with valgrind (very very slow) by giving the script the --with-valgrind flag. #################### # # VPI test script # #################### To test the VPI interface type: perl vpi_reg.pl or if perl is located in /usr/bin ./vpi_reg.pl All these tests should pass for V11.devel. There are some expected failures for V10, which are flagged as Not Implemented The individual test results are found in the vpi_log directory and the gold files are in the vpi_gold directory. The source files are in the vpi directory. The vpi_regress.list file has the tests to perform. This script also takes the --suffix= and the --with-valgrind flags described above. #################### # # VHDL test script # #################### ** Note this is no longer maintained ** This test script require that ghdl be installed in your path and is used to test the Verilog to VHDL translation. perl vhdl_reg.pl or if perl is located in /usr/bin ./vhdl_reg.pl The expected output for V0.10.devel and V0.9 is located in the vhdl_regression_report-devel.txt file. V0.8 does not support converting Verilog to VHDL. This script also takes the --suffix= and the --with-valgrind flags described above. #################### # # BLIF test script # #################### This test script require that abc be installed in your path and is used to test the Verilog to VHDL translation. python blif_reg.py There is no expected output as of yet so to check for regressions simply run with and without your patches. #################### # # Windows (MinGW) test issues # #################### When running under Windows using a MinGW build in a MSYS2 shell, the expected output from vvp_reg.pl can be found in regression_report-msys2.txt. The MinGW/MSYS2 specific test exceptions can be found in regress-msys2.list. Exceptions for the VPI tests can be found in the vpi_regress.list file. With Windows 10 and MSYS2, there are now very few differences between the Windows and Linux builds. iverilog-12_0/ivtest/blif.list000066400000000000000000000002531435245347300164760ustar00rootroot00000000000000blif01a blif01b blif01c blif01d blif01e blif01f blif01g blif01h blif01i blif02a blif02b blif02c blif02d blif02e blif02f blif02g blif02h blif02i blif02j blif02k blif_shift iverilog-12_0/ivtest/blif/000077500000000000000000000000001435245347300156015ustar00rootroot00000000000000iverilog-12_0/ivtest/blif/blif01a.v000066400000000000000000000027231435245347300172120ustar00rootroot00000000000000 /* * Generate a combinational adder of any width. The width parameter can * be any integer value >0. The A and B inputs have WID bits, and the Q * output has WID+1 bits to include the overflow. */ module addN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output wire [WID:0] Q /* */); wire [WID-1:0] Cout; /* The least significant slice has no Cin */ add1 U0 (.A(A[0]), .B(B[0]), .Cin(1'b0), .Q(Q[0]), .Cout(Cout[0])); /* Generate all the remaining slices */ genvar i; for (i = 1 ; i < WID ; i = i+1) begin : U add1 Un (.A(A[i]), .B(B[i]), .Cin(Cout[i-1]), .Q(Q[i]), .Cout(Cout[i])); end assign Q[WID] = Cout[WID-1]; endmodule // add /* * This is a single-bit combinational adder used by the addH module * above. */ module add1(input A, input B, input Cin, output Q, output Cout); assign Q = A ^ B ^ Cin; assign Cout = A&B | A&Cin | B&Cin; endmodule // hadd `ifdef TEST_BENCH module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; addN #(.WID(WID)) usum (.A(A), .B(B), .Q(Q)); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx+bdx)) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main `endif iverilog-12_0/ivtest/blif/blif01a_tb.v000066400000000000000000000017531435245347300177010ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx+bdx)) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif01b.v000066400000000000000000000003071435245347300172070ustar00rootroot00000000000000 module test_logic(input A, B, output q_nand, q_nor, q_xnor, q_not); assign q_nand = A ~& B; assign q_nor = A ~| B; assign q_xnor = A ~^ B; assign q_not = ~A; endmodule // test_logic iverilog-12_0/ivtest/blif/blif01b_tb.v000066400000000000000000000014341435245347300176760ustar00rootroot00000000000000 module main; reg [2:0] X; wire q_nand, q_nor, q_xnor, q_not; test_logic DUT(.A(X[0]), .B(X[1]), .q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor), .q_not(q_not)); initial begin for (X = 0 ; X < 4 ; X = X+1) begin #1 /* Let gates settle. */; if (q_nand !== (X[0] ~& X[1])) begin $display("FAILED -- q_nand=%b, X=%b", q_nand, X[1:0]); $finish; end if (q_nor !== (X[0] ~| X[1])) begin $display("FAILED -- q_nor=%b, X=%b", q_nor, X[1:0]); $finish; end if (q_xnor !== (X[0] ~^ X[1])) begin $display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[1:0]); $finish; end if (q_not !== (~X[0])) begin $display("FAILED -- q_not=%b, X=%b", q_not, X[0]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif01c.v000066400000000000000000000002531435245347300172100ustar00rootroot00000000000000 module addN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output wire [WID:0] Q /* */); assign Q = A + B; endmodule // add iverilog-12_0/ivtest/blif/blif01c_tb.v000066400000000000000000000017531435245347300177030ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx+bdx)) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif01d.v000066400000000000000000000002531435245347300172110ustar00rootroot00000000000000 module subN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output wire [WID:0] Q /* */); assign Q = A - B; endmodule // add iverilog-12_0/ivtest/blif/blif01d_tb.v000066400000000000000000000017751435245347300177100ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; subN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx[WID-1:0]-bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif01e.v000066400000000000000000000003711435245347300172130ustar00rootroot00000000000000 module cmpN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output wire QE, QN, QGT, QGE /* */); assign QE = A == B; assign QN = A != B; assign QGT = A > B; assign QGE = A >= B; endmodule // add iverilog-12_0/ivtest/blif/blif01e_tb.v000066400000000000000000000026211435245347300177000ustar00rootroot00000000000000 /* * This is a post-synthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire QE, QN, QGT, QGE; cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE)); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 ; if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE); $finish; end if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN); $finish; end if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT); $finish; end if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif01f.v000066400000000000000000000002721435245347300172140ustar00rootroot00000000000000 module muxN #(parameter WID = 4, parameter SWID = 2) (input wire [WID-1:0] D, input wire [SWID-1:0] S, output wire Q /* */); assign Q = D[S]; endmodule // add iverilog-12_0/ivtest/blif/blif01f_tb.v000066400000000000000000000012311435245347300176750ustar00rootroot00000000000000 module main; parameter WID = 4; parameter SWID = 2; reg [WID-1:0] D; reg [SWID-1:0] S; wire Q; muxN dut(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]), .\S[1] (S[1]), .\S[0] (S[0]), .Q(Q)); integer idx, sdx; initial begin for (idx = 0 ; idx < 50 ; idx += 1) begin D = $random; for (sdx = 0 ; sdx < (1<0. The A and B inputs have WID bits, and the Q * output has WID+1 bits to include the overflow. */ module addN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output wire [WID:0] Q /* */); wire [WID-1:0] Cout; /* The least significant slice has no Cin */ add1 U0 (.A(A[0]), .B(B[0]), .Cin(1'b0), .Q(Q[0]), .Cout(Cout[0])); /* Generate all the remaining slices */ genvar i; for (i = 1 ; i < WID ; i = i+1) begin : U add1 Un (.A(A[i]), .B(B[i]), .Cin(Cout[i-1]), .Q(Q[i]), .Cout(Cout[i])); end assign Q[WID] = Cout[WID-1]; endmodule // add /* * This is a single-bit combinational adder used by the addH module * above. */ module add1(input A, input B, input Cin, output reg Q, output reg Cout); always @* begin Q = A ^ B ^ Cin; Cout = A&B | A&Cin | B&Cin; end endmodule // hadd iverilog-12_0/ivtest/blif/blif02a_tb.v000066400000000000000000000017531435245347300177020ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx+bdx)) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02b.v000066400000000000000000000003321435245347300172060ustar00rootroot00000000000000 module test_logic(input A, B, output reg q_nand, q_nor, q_xnor, q_not); always @(A, B) begin q_nand = A ~& B; q_nor = A ~| B; q_xnor = A ~^ B; q_not = ~A; end endmodule // test_logic iverilog-12_0/ivtest/blif/blif02b_tb.v000066400000000000000000000014341435245347300176770ustar00rootroot00000000000000 module main; reg [2:0] X; wire q_nand, q_nor, q_xnor, q_not; test_logic DUT(.A(X[0]), .B(X[1]), .q_nand(q_nand), .q_nor(q_nor), .q_xnor(q_xnor), .q_not(q_not)); initial begin for (X = 0 ; X < 4 ; X = X+1) begin #1 /* Let gates settle. */; if (q_nand !== (X[0] ~& X[1])) begin $display("FAILED -- q_nand=%b, X=%b", q_nand, X[1:0]); $finish; end if (q_nor !== (X[0] ~| X[1])) begin $display("FAILED -- q_nor=%b, X=%b", q_nor, X[1:0]); $finish; end if (q_xnor !== (X[0] ~^ X[1])) begin $display("FAILED -- q_xnor=%b, X=%b", q_xnor, X[1:0]); $finish; end if (q_not !== (~X[0])) begin $display("FAILED -- q_not=%b, X=%b", q_not, X[0]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02c.v000066400000000000000000000002551435245347300172130ustar00rootroot00000000000000 module addN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output reg [WID:0] Q /* */); always @* Q = A + B; endmodule // add iverilog-12_0/ivtest/blif/blif02c_tb.v000066400000000000000000000017531435245347300177040ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; addN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx+bdx)) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02d.v000066400000000000000000000002641435245347300172140ustar00rootroot00000000000000 module subN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output reg [WID:0] Q /* */); always @(A or B) Q = A - B; endmodule // add iverilog-12_0/ivtest/blif/blif02d_tb.v000066400000000000000000000017751435245347300177110ustar00rootroot00000000000000 /* * This is a post-wynthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire [WID:0] Q; subN usum(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 if (Q !== (adx[WID-1:0]-bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, Q=%b", A, B, Q); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02e.v000066400000000000000000000006021435245347300172110ustar00rootroot00000000000000 module cmpN #(parameter WID = 4) (input wire [WID-1:0] A, input wire [WID-1:0] B, output reg QE, QN, QGT, QGE /* */); always @(A, B) if (A > B) begin QE = 0; QN = 1; QGT = 1; QGE = 1; end else if (A == B) begin QE = 1; QN = 0; QGT = 0; QGE = 1; end else begin QE = 0; QN = 1; QGT = 0; QGE = 0; end endmodule // add iverilog-12_0/ivtest/blif/blif02e_tb.v000066400000000000000000000026211435245347300177010ustar00rootroot00000000000000 /* * This is a post-synthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire QE, QN, QGT, QGE; cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE)); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 ; if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE); $finish; end if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN); $finish; end if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT); $finish; end if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02f.v000066400000000000000000000002741435245347300172170ustar00rootroot00000000000000 module muxN #(parameter WID = 4, parameter SWID = 2) (input wire [WID-1:0] D, input wire [SWID-1:0] S, output reg Q /* */); always @* Q = D[S]; endmodule // add iverilog-12_0/ivtest/blif/blif02f_tb.v000066400000000000000000000012271435245347300177030ustar00rootroot00000000000000 module main; parameter WID = 4; parameter SWID = 2; reg [WID-1:0] D; reg [SWID-1:0] S; wire Q; muxN dut(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]), .\S[1] (S[1]), .\S[0] (S[0]), .Q(Q)); integer idx, sdx; initial begin for (idx = 0 ; idx < 50 ; idx += 1) begin D = $random; for (sdx = 0 ; sdx < (1< B) QGT = 1; else QGT = 0; always @(A, B) if (A >= B) QGE = 1; else QGE = 0; always @(A, B) if (A == B) QE = 1; else QE = 0; always @(A, B) if (A != B) QN = 1; else QN = 0; /* always @(A, B) if (A > B) begin QE = 0; QN = 1; QGT = 1; QGE = 1; end else if (A == B) begin QE = 1; QN = 0; QGT = 0; QGE = 1; end else begin QE = 0; QN = 1; QGT = 0; QGE = 0; end */ endmodule // add iverilog-12_0/ivtest/blif/blif02i_tb.v000066400000000000000000000026211435245347300177050ustar00rootroot00000000000000 /* * This is a post-synthesis test for the blif01a.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif01a.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif02a_tb.v foo.v * $ vvp foo.vvp */ module main; parameter WID = 4; reg [WID-1:0] A, B; wire QE, QN, QGT, QGE; cmpN ucmp(.\A[3] (A[3]), .\A[2] (A[2]), .\A[1] (A[1]), .\A[0] (A[0]), .\B[3] (B[3]), .\B[2] (B[2]), .\B[1] (B[1]), .\B[0] (B[0]), .QE(QE), .QN(QN), .QGT(QGT), .QGE(QGE)); int adx; int bdx; initial begin for (bdx = 0 ; bdx[WID]==0 ; bdx = bdx+1) begin for (adx = 0 ; adx[WID]==0 ; adx = adx+1) begin A <= adx[WID-1:0]; B <= bdx[WID-1:0]; #1 ; if (QE !== (adx[WID-1:0]==bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QE=%b", A, B, QE); $finish; end if (QN !== (adx[WID-1:0]!=bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QN=%b", A, B, QN); $finish; end if (QGT !== (adx[WID-1:0] > bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGT=%b", A, B, QGT); $finish; end if (QGE !== (adx[WID-1:0] >= bdx[WID-1:0])) begin $display("FAILED -- A=%b, B=%b, QGE=%b", A, B, QGE); $finish; end end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02j.v000066400000000000000000000004061435245347300172200ustar00rootroot00000000000000 module test_mux (input wire [1:0] D0, D1, input wire [1:0] S, output reg [1:0] Q); always @(*) begin if (S[1]==1'b0) case (S[0]) 1'b0: Q = D0; 1'b1: Q = D1; endcase // case (S[0]) else Q = 2'b0; end endmodule // test_mux iverilog-12_0/ivtest/blif/blif02j_tb.v000066400000000000000000000011351435245347300177050ustar00rootroot00000000000000 module main; reg [1:0] D0, D1; reg sel; wire [1:0] Q; test_mux DUT(.\S[1] (1'b0), .\S[0] (sel), .\D0[1] (D0[1]), .\D0[0] (D0[0]), .\D1[1] (D1[1]), .\D1[0] (D1[0]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); initial begin D0 = 'b01; D1 = 'b10; sel = 0; #1 ; if (Q !== D0) begin $display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q); $finish; end sel = 1; #1 ; if (Q !== D1) begin $display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif02k.v000066400000000000000000000005511435245347300172220ustar00rootroot00000000000000 module test_mux (input wire [1:0] D0, D1, input wire [1:0] S, output reg [1:0] Q, R); always @(*) begin if (S[1]==1'b0) case (S[0]) 1'b0: Q = D0; 1'b1: Q = D1; endcase // case (S[0]) else Q = 2'b0; case (S[1]) 1'b0: if (S[0]) R = D1; else R = D0; 1'b1: R = 2'b00; endcase end endmodule // test_mux iverilog-12_0/ivtest/blif/blif02k_tb.v000066400000000000000000000021501435245347300177040ustar00rootroot00000000000000 module main; reg [1:0] D0, D1; reg [1:0] sel; wire [1:0] Q, R; test_mux DUT(.\S[1] (sel[1]), .\S[0] (sel[0]), .\D0[1] (D0[1]), .\D0[0] (D0[0]), .\D1[1] (D1[1]), .\D1[0] (D1[0]), .\Q[1] (Q[1]), .\Q[0] (Q[0]), .\R[1] (R[1]), .\R[0] (R[0])); initial begin D0 = 'b01; D1 = 'b10; sel = 0; #1 ; if (Q !== D0) begin $display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q); $finish; end if (R !== D0) begin $display("FAILED -- D0=%b, D1=%b, S=%b, R=%b", D0, D1, sel, R); $finish; end sel = 1; #1 ; if (Q !== D1) begin $display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q); $finish; end if (R !== D1) begin $display("FAILED -- D0=%b, D1=%b, S=%b, R=%b", D0, D1, sel, R); $finish; end sel = 2; #1 ; if (Q !== 'b00) begin $display("FAILED -- D0=%b, D1=%b, S=%b, Q=%b", D0, D1, sel, Q); $finish; end if (R !== 'b00) begin $display("FAILED -- D0=%b, D1=%b, S=%b, R=%b", D0, D1, sel, R); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif_shift.v000066400000000000000000000010351435245347300201000ustar00rootroot00000000000000 /* * Generate a barrel shifter of arbitrary width. * T can be 0 for <<, 1 for >>, 2 for <<< or 3 for >>>. */ module shift #(parameter WI = 4, WS = 4, parameter WO = 6) (input wire [WI-1:0] D, input wire [WS-1:0] S, output wire [WO-1:0] SHL, output wire [WO-1:0] SHR, output wire signed [WO-1:0] ASHL, output wire signed [WO-1:0] ASHR /* */); wire signed [WI-1:0] DS; assign DS = D; assign SHL = D << S ; assign SHR = D >> S ; assign ASHL = DS <<< S ; assign ASHR = DS >>> S ; endmodule iverilog-12_0/ivtest/blif/blif_shift_tb.v000066400000000000000000000045631435245347300205760ustar00rootroot00000000000000 /* * This is a post-synthesis test for the blif_shift.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif_shift.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif_shift_tb.v foo.v * $ vvp foo.vvp */ module main; parameter W=3; reg [W:0] D; reg [W:0] S; parameter WO=5; wire [WO:0] SHL; wire [WO:0] SHR; wire [WO:0] ASHL; wire [WO:0] ASHR; reg [WO:0] shl; reg [WO:0] shr; reg [WO:0] ashl; reg [WO:0] ashr; `ifdef DUMMY shift ss(.D (D), .S (S), .SHL (SHL), .SHR (SHR), .ASHL (ASHL), .ASHR (ASHR)); `else shift ss(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]), .\S[3] (S[3]), .\S[2] (S[2]), .\S[1] (S[1]), .\S[0] (S[0]), .\SHL[5] (SHL[5]), .\SHL[4] (SHL[4]), .\SHL[3] (SHL[3]), .\SHL[2] (SHL[2]), .\SHL[1] (SHL[1]), .\SHL[0] (SHL[0]), .\SHR[5] (SHR[5]), .\SHR[4] (SHR[4]), .\SHR[3] (SHR[3]), .\SHR[2] (SHR[2]), .\SHR[1] (SHR[1]), .\SHR[0] (SHR[0]), .\ASHL[5] (ASHL[5]), .\ASHL[4] (ASHL[4]), .\ASHL[3] (ASHL[3]), .\ASHL[2] (ASHL[2]), .\ASHL[1] (ASHL[1]), .\ASHL[0] (ASHL[0]), .\ASHR[5] (ASHR[5]), .\ASHR[4] (ASHR[4]), .\ASHR[3] (ASHR[3]), .\ASHR[2] (ASHR[2]), .\ASHR[1] (ASHR[1]), .\ASHR[0] (ASHR[0])); `endif int ddx; int sdx; initial begin for (ddx = 0 ; ddx < 1 << (W+1) ; ddx = ddx+1) for (sdx = 0 ; sdx < WO + 2 ; sdx = sdx+1) begin D = ddx[W:0]; S = sdx[W:0]; shl = D << S; shr = D >> S; ashl = $signed(D) <<< S; ashr = $signed(D) >>> S; // $display("D = %b, S = %b", D, S); // $display("shl = %b, shr = %b", shl, shr); // $display("ashl = %b, ashr = %b", ashl, ashr); #1; if (SHL !== shl) begin $display("FAILED -- D=%b, S=%b, SHL=%b (should be %b)", D, S, SHL, shl); $finish; end if (SHR !== shr) begin $display("FAILED -- D=%b, S=%b, SHR=%b (should be %b)", D, S, SHR, shr); $finish; end if (ASHL !== ashl) begin $display("FAILED -- D=%b, S=%b, ASHL=%b (should be %b)", D, S, ASHL, ashl); $finish; end if (ASHR !== ashr) begin $display("FAILED -- D=%b, S=%b, SHL=%b (should be %b)", D, S, ASHR, ashr); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif/blif_sign_ext.v000066400000000000000000000003611435245347300206040ustar00rootroot00000000000000 /* * Sign extend input * T can be 0 for <<, 1 for >>, 2 for <<< or 3 for >>>. */ module sign_ext #(parameter WI = 4, WO = 6) (input wire signed [WI-1:0] D, output wire signed [WO-1:0] Q /* */); assign Q = D; endmodule iverilog-12_0/ivtest/blif/blif_sign_ext_tb.v000066400000000000000000000017141435245347300212740ustar00rootroot00000000000000 /* * This is a post-synthesis test for the blif_sign_ext.v test. Run this * simulation in these steps: * * $ iverilog -tblif -o foo.blif blif_sign_ext.v * $ abc * abc 01> read_blif foo.blif * abc 02> write_verilog foo.v * abc 03> quit * $ iverilog -g2009 -o foo.vvp blif_sign_ext_tb.v foo.v * $ vvp foo.vvp */ module main; parameter W=3, WO=5; reg signed [W:0] D; reg signed [WO:0] q; wire [WO:0] Q; sign_ext se(.\D[3] (D[3]), .\D[2] (D[2]), .\D[1] (D[1]), .\D[0] (D[0]), .\Q[5] (Q[5]), .\Q[4] (Q[4]), .\Q[3] (Q[3]), .\Q[2] (Q[2]), .\Q[1] (Q[1]), .\Q[0] (Q[0])); int ddx; initial begin for (ddx = 0 ; ddx < 1 << (W+1) ; ddx = ddx+1) begin D = ddx[W:0]; q = D; $display("D = %b, q = %b", D, q); #1; if (Q !== q) begin $display("FAILED -- D=%b, Q=%b (should be %b)", D, Q, q); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/blif_reg.py000066400000000000000000000047051435245347300170160ustar00rootroot00000000000000# # This is a python script for testing the blif code generator with # programs specifically set aside for it. The general pattern is that # the test program comes in two parts: the test bench and the device # to be tested. The files blif/*_tb.v are the test benches for the # corresponding files blif/*.v. # # This script requires the "abc" command available here: # # # Run this script with the command: python blif_reg.py # import os import subprocess import re # This is the name of the iverilog command and vvp command. These may # vary in different installations. iverilog = "iverilog" vvp = "vvp" list_file = open("blif.list") # The list file contains a list of test names. The first word in the # line is the name of the test. match_prog = re.compile(r"^([a-zA-Z0-9_.]+).*$") tests = [] for line in list_file: if line[0] == "#": continue match = match_prog.search(line) if match: tests.append(match.group(1)) list_file.close() def run_test(test): global count_passed, count_failed # Assemble the paths for the test-bench and DUT. dut = "blif/" + test + ".v" tb = "blif/" + test + "_tb.v" redirect = "log/" + test + ".log 2>&1" # Process the DUT into a .blif file ivl_blif_cmd = iverilog + " -g2009 -tblif -otmp_blif.blif " + dut + " > " + redirect rc = subprocess.call(ivl_blif_cmd, shell=True) if rc == 0: # Use ABC to convert the .blif file to Verilog abc_cmd = "abc -c 'read_blif tmp_blif.blif ; write_verilog tmp_blif.v' >> " + redirect rc = subprocess.call(abc_cmd, shell=True); if rc == 0: # Compile ivl_blif_tb_cmd = iverilog + " -g2009 -otmp_blif.vvp " + tb + " tmp_blif.v >> " + redirect rc = subprocess.call(ivl_blif_tb_cmd, shell=True) if rc == 0: # Now simulate to make sure the tranlation worked properly. vvp_cmd = vvp + " tmp_blif.vvp" output = subprocess.check_output(vvp_cmd, shell=True) rc = 0 if output == "PASSED\n" else 1 if rc == 0: print test, "PASSED" count_passed = count_passed + 1 else: print test, "FAILED" count_failed = count_failed + 1 for tmp in ["tmp_blif.blif", "tmp_blif.v", "tmp_blif.vvp"]: if os.path.exists(tmp): os.remove(tmp) count_passed = 0 count_failed = 0 for test in tests: run_test(test) print print count_passed, "tests passed,", count_failed, "tests failed." iverilog-12_0/ivtest/contrib/000077500000000000000000000000001435245347300163255ustar00rootroot00000000000000iverilog-12_0/ivtest/contrib/TEST9.ROM000066400000000000000000000200001435245347300175440ustar00rootroot00000000000000CFF 005 040 006 007 069 C14 028 209 002 027 201 026 2E8 A0B 2A9 C07 169 A06 FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF FFF A00 iverilog-12_0/ivtest/contrib/add32.v000066400000000000000000000013711435245347300174130ustar00rootroot00000000000000module add32(sum, cOut, clock, a, b, cIn); input clock; input a, b, cIn; output sum, cOut; reg [31:0] a, b; reg cIn; wire [31:0] sum; wire cOut; always @(posedge clock) //{cOut, sum} = a + b + cIn; assign sum = a + b + cIn; endmodule ////////////////////////// module main; reg CLOCK; reg [31:0] A, B; reg C_IN; reg [31:0] SUM; wire C_OUT; add32 myAdder(SUM, C_OUT, CLOCK, A, B, C_OUT); always #1 CLOCK = ~ CLOCK; initial begin $monitor($time,, " CLOCK=%d, A=%x, B=%x, C_IN=%d -- SUM=%x, C_OUT=%d", CLOCK, A, B, C_IN, SUM, C_OUT); end initial begin CLOCK = 0; A = 32'h00000001; B = 32'h00000002; C_IN = 1'b0; #20 $finish; end endmodule iverilog-12_0/ivtest/contrib/div16.v000066400000000000000000000176041435245347300174550ustar00rootroot00000000000000// // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // Integer Multicycle Divide circuit (divide a 16-bit number by a 16-bit number in 16 cycles). // // a / b = q with remainder r // // Where a is 16-bits, // Where b is 16 bits // // Module is actually parameterized if you want other widths. // // *** Test the ranges of values for which you'll use this. For example, you // can't divide FFFF by FF without underflow (overflow?). Mess with // the testbench. You may need to widen some thing. *** // // The answer is 16-bits and the remainder is also 16-bits. // After the start pulse, the module requires 16 cycles to complete. // The q/r outputs stay the same until next start pulse. // Start pulse should be a single cycle. // Division by zero results in a quotient equal to FFFF and remainder equal to 'a'. // // // Written by tom coonan. // // Notes: // - This ain't fancy. I wanted something straight-forward quickly. Go study // more elaborate algorithms if you want to optimize area or speed. If you // have an isolated divide and can spare N cycles for N bits; this may meet your needs. // - You might want to think more about the sizes of things. I wanted a basic estimate // of gates plus I specifically needed to divide 16-bits (not even full range) // by 8-bits. // - Handle divide by zero at higher level.. // - I needed a remainder so I could easily to truncate and rounding stuff, // but remove this to save gates if you don't need a remainder. // - This is about 800 asic gates (0.25um, Standard Cell, 27Mhz). 27Mhz // is my system clock and NOT the maximum it can go.. // - I tried to keep everything parameterized by N, but I only worked through // the N=16 case because that's what I needed... // module div16 (clk, resetb, start, a, b, q, r, done); parameter N = 16; // a/b = q remainder r, where all operands are N wide. input clk; input resetb; // Asynchronous, active low reset. input start; // Pulse this to start the division. input [N-1:0] a; // This is the number we are dividing (the dividend) input [N-1:0] b; // This is the 'divisor' output [N-1:0] q; // This is the 'quotient' output [N-1:0] r; // Here is the remainder. output done; // Will be asserted when q and r are available. // Registered q reg [N-1:0] q; reg done; // Power is the current 2^n bit we are considering. Power is a shifting // '1' that starts at the highest power of 2 and goes all the way down // to ...00001 Shift this until it is zero at which point we stop. // reg [N-1:0] power; // This is the accumulator. We are start with the accumulator set to 'a' (the dividend). // For each (divisor*2^N) term, we see if we can subtract (divisor*2^N) from the accumulator. // We subtract these terms as long as adding in the term doesn't cause the accumulator // to exceed a. When we are done, whatever is left in the accumulator is the remainder. // reg [N-1:0] accum; // This is the divisor*2^N term. Essentually, we are taking the divisor ('b'), initially // shifting it all the way to the left, and shifting it 1 bit at a time to the right. // reg [(2*N-1):0] bpower; // Remainder will be whatever is left in the accumulator. assign r = accum; // Do this addition here for resource sharing. // ** Note that 'accum' is N bits wide, but bpower is 2*N-1 bits wide ** // wire [2*N-1:0] accum_minus_bpower = accum - bpower; always @(posedge clk or negedge resetb) begin if (~resetb) begin q <= 0; accum <= 0; power <= 0; bpower <= 0; done <= 0; end else begin if (start) begin // Reinitialize the divide circuit. q <= 0; accum <= a; // Accumulator initially gets the dividend. power[N-1] <= 1'b1; // We start with highest power of 2 (which is a '1' in MSB) bpower <= b << N-1; // Start with highest bpower, which is (divisor * 2^(N-1)) done <= 0; end else begin // Go until power is zero. // if (power != 0) begin // // Can we add this divisor*2^(power) to the accumulator without going negative? // Just test the MSB of the subtraction. If it is '1', then it must be negative. // if ( ~accum_minus_bpower[2*N-1]) begin // Yes! Set this power of 2 in the quotieny and // then actually comitt to the subtraction from our accumulator. // q <= q | power; accum <= accum_minus_bpower; end // Regardless, always go to next lower power of 2. // power <= power >> 1; bpower <= bpower >> 1; end else begin // We're done. Set done flag. done <= 1; end end end end endmodule // synopsys translate_off module test_div16; reg clk; reg resetb; reg start; reg [15:0] a; reg [15:0] b; wire [15:0] q; wire [15:0] r; wire done; integer num_errors; div16 div16 ( .clk(clk), .resetb(resetb), .start(start), .a(a), .b(b), .q(q), .r(r), .done(done) ); initial begin num_errors = 0; start = 0; // Wait till reset is completely over. #200; // Do some divisions where divisor is constrained to 8-bits and dividend is 16-bits $display ("16-bit Dividend, 8-bit divisor"); repeat (25) begin do_divide ($random, $random & 255); end // Do some divisions where divisor is constrained to 12-bits and dividend is 16-bits $display ("\n16-bit Dividend, 12-bit divisor"); repeat (25) begin do_divide ($random, $random & 4095); end // Do some divisions where both divisor and dividend is 16-bits $display ("\n16-bit Dividend, 16-bit divisor"); repeat (25) begin do_divide ($random, $random); end // Special cases $display ("\nSpecial Cases:"); do_divide (16'hFFFF, 16'hFFFF); // largest possible quotient do_divide (312, 1); // divide by 1 do_divide ( 0, 42); // divide 0 by something else do_divide (312, 0); // divide by zero // That's all. Summarize the test. if (num_errors === 0) begin $display ("\n\nPASSED"); end else begin $display ("\n\nFAILED - There were %0d Errors.", num_errors); end $finish; end task do_divide; input [15:0] arga; input [15:0] argb; begin a = arga; b = argb; @(posedge clk); #1 start = 1; @(posedge clk); #1 start = 0; while (~done) @(posedge clk); #1; $display ("Circuit: %0d / %0d = %0d, rem = %0d\t\t......... Reality: %0d, rem = %0d", arga, argb, q, r, a/b, a%b); if (b !== 0) begin if (q !== a/b) begin $display (" Error! Unexpected Quotient\n\n"); num_errors = num_errors + 1; end if (r !== a % b) begin $display (" Error! Unexpected Remainder\n\n"); num_errors = num_errors + 1; end end end endtask initial begin clk = 0; forever begin #10 clk = 1; #10 clk = 0; end end initial begin resetb = 0; #133 resetb = 1; end //initial begin // $dumpfile ("test_div16.vcd"); // $dumpvars (0,test_div16); //end endmodule iverilog-12_0/ivtest/contrib/fifo.v000066400000000000000000000170421435245347300174430ustar00rootroot00000000000000`begin_keywords "1364-2005" // // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Synchronous FIFO. 4 x 16 bit words. // // Modified by SDW to print out PASSED only if DEBUG not defined. // Also changed TEST1 so that it is "self checking" by adding a // passed in value to read_word. // module fifo (clk, rstp, din, writep, readp, dout, emptyp, fullp); input clk; input rstp; input [15:0] din; input readp; input writep; output [15:0] dout; output emptyp; output fullp; // Defines sizes in terms of bits. // parameter DEPTH = 3, // 2 bits, e.g. 4 words in the FIFO. MAX_COUNT = 3'b111; // topmost address in FIFO. reg emptyp; reg fullp; // Registered output. reg [15:0] dout; // Define the FIFO pointers. A FIFO is essentially a circular queue. // reg [(DEPTH-1):0] tail; reg [(DEPTH-1):0] head; // Define the FIFO counter. Counts the number of entries in the FIFO which // is how we figure out things like Empty and Full. // reg [(DEPTH-1):0] count; // Define our regsiter bank. This is actually synthesizable! // reg [15:0] fifomem[0:MAX_COUNT]; // Dout is registered and gets the value that tail points to RIGHT NOW. // always @(posedge clk) begin if (rstp == 1) dout <= 16'h0000; else dout <= fifomem[tail]; end // Update FIFO memory. always @(posedge clk) begin if (rstp == 1'b0 && writep == 1'b1 && fullp == 1'b0) begin fifomem[head] <= din; end end // Update the head register. // always @(posedge clk) begin if (rstp == 1'b1) begin head <= 2'b00; end else begin if (writep == 1'b1 && fullp == 1'b0) begin // WRITE head <= head + 1; end end end // Update the tail register. // always @(posedge clk) begin if (rstp == 1'b1) begin tail <= 2'b00; end else begin if (readp == 1'b1 && emptyp == 1'b0) begin // READ tail <= tail + 1; end end end // Update the count regsiter. // always @(posedge clk) begin if (rstp == 1'b1) begin count <= 2'b00; end else begin case ({readp, writep}) 2'b00: count <= count; 2'b01: // WRITE if (count != MAX_COUNT) count <= count + 1; 2'b10: // READ if (count != 2'b00) count <= count - 1; 2'b11: // Concurrent read and write.. no change in count count <= count; endcase end end // *** Update the flags // // First, update the empty flag. // always @(count) begin if (count == 2'b00) emptyp <= 1'b1; else emptyp <= 1'b0; end // Update the full flag // always @(count) begin if (count == MAX_COUNT) fullp <= 1'b1; else fullp <= 1'b0; end endmodule // synopsys translate_off `define TEST_FIFO // synopsys translate_off `ifdef TEST_FIFO module test_fifo; reg clk; reg rstp; reg [15:0] din; reg readp; reg writep; wire [15:0] dout; wire emptyp; wire fullp; reg error ; reg [15:0] value; fifo U1 ( .clk (clk), .rstp (rstp), .din (din), .readp (readp), .writep (writep), .dout (dout), .emptyp (emptyp), .fullp (fullp) ); // // SDW Added self testing aspect here.. // task read_word; input [15:0] expect; begin @(negedge clk); readp = 1; @(posedge clk) #5; `ifdef DEBUG $display ("Expect %0h, Read %0h from FIFO", `endif // DEBUG if(expect !== dout) begin $display ("FAILED - Expect %0h, Read %0h from FIFO", expect,dout); error = 1; end readp = 0; end endtask task write_word; input [15:0] value; begin @(negedge clk); din = value; writep = 1; @(posedge clk); `ifdef DEBUG $display ("Write %0h to FIFO", din); `endif // DEBUG #5; din = 16'hzzzz; writep = 0; end endtask initial begin clk = 0; forever begin #10 clk = 1; #10 clk = 0; end end initial begin error = 0; // Set error to zero here. `ifdef DEBUG $dumpfile("test.vcd"); $dumpvars(0,test_fifo); `endif // DEBUG test1; //test2; if(error == 0) $display("PASSED"); $finish; end task test1; begin din = 16'hzzzz; writep = 0; readp = 0; // Reset rstp = 1; #50; rstp = 0; #50; // ** Write 3 values. write_word (16'h1111); write_word (16'h2222); write_word (16'h3333); // ** Read 2 values read_word(16'h1111); read_word(16'h2222); // ** Write one more write_word (16'h4444); // ** Read a bunch of values read_word(16'h3333); // *** Write a bunch more values write_word (16'h0001); write_word (16'h0002); write_word (16'h0003); write_word (16'h0004); write_word (16'h0005); write_word (16'h0006); write_word (16'h0007); write_word (16'h0008); // ** Read a bunch of values read_word(16'h4444); read_word(16'h0001); read_word(16'h0002); read_word(16'h0003); read_word(16'h0004); read_word(16'h0005); read_word(16'h0006); end endtask `ifdef TEST2 // TEST2 // // This test will operate the FIFO in an orderly manner the way it normally works. // 2 threads are forked; a reader and a writer. The writer writes a counter to // the FIFO and obeys the fullp flag and delays randomly. The reader likewise // obeys the emptyp flag and reads at random intervals. The result should be that // the reader reads the incrementing counter out of the FIFO. The empty/full flags // should bounce around depending on the random delays. The writer repeats some // fixed number of times and then terminates both threads and kills the sim. // task test2; reg [15:0] writer_counter; begin writer_counter = 16'h0001; din = 16'hzzzz; writep = 0; readp = 0; // Reset rstp = 1; #50; rstp = 0; #50; fork // Writer begin repeat (500) begin @(negedge clk); if (fullp == 1'b0) begin write_word (writer_counter); #5; writer_counter = writer_counter + 1; end else begin $display ("WRITER is waiting.."); end // Delay a random amount of time between 0ns and 100ns #22 ; end $display ("Done with WRITER fork.."); $finish; end // Reader begin forever begin @(negedge clk); if (emptyp == 1'b0) begin read_word; end else begin $display ("READER is waiting.."); end // Delay a random amount of time between 0ns and 100ns #50; end end join end endtask /* always @(fullp) $display ("fullp = %0b", fullp); always @(emptyp) $display ("emptyp = %0b", emptyp); always @(U1.head) $display ("head = %0h", U1.head); always @(U1.tail) $display ("tail = %0h", U1.tail); */ `endif // TEST2 endmodule `endif `end_keywords iverilog-12_0/ivtest/contrib/gencrc.v000066400000000000000000000236211435245347300177610ustar00rootroot00000000000000`begin_keywords "1364-2005" // // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // Behavioral Verilog for CRC16 and CRC32 for use in a testbench. // // The specific polynomials and conventions regarding bit-ordering etc. // are specific to the Cable Modem DOCSIS protocol, but the general scheme // should be reusable for other types of CRCs with some fiddling. // // This CRC code works for a specific type of network protocol, and it // must do certain byte swappings, etc. You may need to play with it // for your protocol. Also, make sure the polynomials are what you // really want. This is obviously, not synthesizable - I just used this // in a testbench at one point. // // These tasks are crude and rely on some global parameters. They should // also read from a file, yada yada yada. It is probably better to do this // with a PLI call, but here it is anyway.. // // The test case includes a golden DOCSIS (Cable Modem) test message that // was captured in a lab. // // tom coonan, 1999. // module test_gencrc; // *** Buffer for the Golden Message *** reg [7:0] test_packet[0:54]; // *** Global parameter block for the CRC32 calculator. // parameter CRC32_POLY = 32'h04C11DB7; reg [ 7:0] crc32_packet[0:255]; integer crc32_length; reg [31:0] crc32_result; // *** Global parameter block for the CRC16 calculator. // parameter CRC16_POLY = 16'h1020; reg [ 7:0] crc16_packet[0:255]; integer crc16_length; reg [15:0] crc16_result; `define TEST_GENCRC `ifdef TEST_GENCRC // Call the main test task and then quit. // initial begin main_test; $finish; end `endif // **************************************************************** // * // * GOLDEN MESSAGE // * // * The golden message is a DOCSIS frame that was captured off // * the Broadcom reference design. It is a MAP message. It // * includes a HCS (crc 16) and a CRC32. // * // * // **************************************************************** // task initialize_test_packet; begin test_packet[00] = 8'hC2; // FC. HCS coverage starts here. test_packet[01] = 8'h00; // MACPARAM test_packet[02] = 8'h00; // MAC LEN test_packet[03] = 8'h30; // MAC LEN. HCS Coverage includes this byte and ends here. test_packet[04] = 8'hF2; // CRC16 (also known as HCS) test_packet[05] = 8'hCF; // CRC16 cont.. test_packet[06] = 8'h01; // Start of the IEEE payload. CRC32 covererage starts here. This is the DA field test_packet[07] = 8'hE0; // DA field cont.. test_packet[08] = 8'h2F; // DA field cont.. test_packet[09] = 8'h00; // DA field cont.. test_packet[10] = 8'h00; // DA field cont.. test_packet[11] = 8'h01; // DA field cont.. test_packet[12] = 8'h00; // SA field test_packet[13] = 8'h80; // SA field cont.. test_packet[14] = 8'h42; // SA field cont.. test_packet[15] = 8'h42; // SA field cont.. test_packet[16] = 8'h20; // SA field cont.. test_packet[17] = 8'h9E; // SA field cont.. test_packet[18] = 8'h00; // IEEE LEN field test_packet[19] = 8'h1E; // IEEE LEN field cont. test_packet[20] = 8'h00; // LLC field. test_packet[21] = 8'h00; // LLC field cont... test_packet[22] = 8'h03; // LLC field cont... test_packet[23] = 8'h01; // LLC field cont... test_packet[24] = 8'h03; // LLC field cont... This is also the TYPE, which indicates MAP. test_packet[25] = 8'h00; // LLC field cont... test_packet[26] = 8'h01; // Start of MAP message payload. test_packet[27] = 8'h01; // MAP message payload.. test_packet[28] = 8'h02; // MAP message payload.. test_packet[29] = 8'h00; // MAP message payload.. test_packet[30] = 8'h00; // MAP message payload.. test_packet[31] = 8'h18; // MAP message payload.. test_packet[32] = 8'hAA; // MAP message payload.. test_packet[33] = 8'h58; // MAP message payload.. test_packet[34] = 8'h00; // MAP message payload.. test_packet[35] = 8'h18; // MAP message payload.. test_packet[36] = 8'hA8; // MAP message payload.. test_packet[37] = 8'hA0; // MAP message payload.. test_packet[38] = 8'h02; // MAP message payload.. test_packet[39] = 8'h03; // MAP message payload.. test_packet[40] = 8'h03; // MAP message payload.. test_packet[41] = 8'h08; // MAP message payload.. test_packet[42] = 8'hFF; // MAP message payload.. test_packet[43] = 8'hFC; // MAP message payload.. test_packet[44] = 8'h40; // MAP message payload.. test_packet[45] = 8'h00; // MAP message payload.. test_packet[46] = 8'h00; // MAP message payload.. test_packet[47] = 8'h01; // MAP message payload.. test_packet[48] = 8'hC0; // MAP message payload.. test_packet[49] = 8'h14; // Last byte of MAP payload, last byte covered by CRC32. test_packet[50] = 8'hDD; // CRC32 Starts here test_packet[51] = 8'hBF; // CRC32 cont.. test_packet[52] = 8'hC1; // CRC32 cont.. test_packet[53] = 8'h2E; // Last byte of CRC32, last byte of DOCSIS. end endtask // ************************************************************************* // * // * Main test task. // * // * Use our primary "golden packet". Copy into the generic global // * variables that the low-level 'gencrc16' and 'gencrc32' tasks use. // * Comare against the expected values and report SUCCESS or FAILURE. // * // ************************************************************************* // task main_test; integer i, j; integer num_errors; reg [15:0] crc16_expected; reg [31:0] crc32_expected; begin num_errors = 0; // Initialize the Golden Message! // initialize_test_packet; // **** TEST CRC16 // // // Copy golden test_packet into the main crc16 buffer.. for (i=0; i<4; i=i+1) begin crc16_packet[i] = test_packet[i]; end crc16_expected = {test_packet[4], test_packet[5]}; crc16_length = 4; // Must tell test function the length gencrc16; // Call main test function if (crc16_result !== crc16_expected) begin num_errors = num_errors + 1; $display ("FAILED - Actual crc16_result = %h, Expected = %h", crc16_result, crc16_expected); end // **** TEST CRC16 // j = 0; for (i=6; i<50; i=i+1) begin crc32_packet[j] = test_packet[i]; j = j + 1; end crc32_expected = {test_packet[50], test_packet[51], test_packet[52], test_packet[53]}; crc32_length = 44; gencrc32; if (crc32_result !== crc32_expected) begin $display ("FAILED - Actual crc32_result = %h, Expected = %h", crc32_result, crc32_expected); num_errors = num_errors + 1; end if(num_errors == 0) $display("PASSED"); end endtask // **************************************************************** // * // * Main working CRC tasks are: gencrc16, gencrc32. // * // * These tasks rely on some globals (see front of program). // * // **************************************************************** // Generate a (DOCSIS) CRC16. // // Uses the GLOBAL variables: // // Globals referenced: // parameter CRC16_POLY = 16'h1020; // reg [ 7:0] crc16_packet[0:255]; // integer crc16_length; // // Globals modified: // reg [15:0] crc16_result; // task gencrc16; integer byte, bit; reg msb; reg [7:0] current_byte; reg [15:0] temp; begin crc16_result = 16'hffff; for (byte = 0; byte < crc16_length; byte = byte + 1) begin current_byte = crc16_packet[byte]; for (bit = 0; bit < 8; bit = bit + 1) begin msb = crc16_result[15]; crc16_result = crc16_result << 1; if (msb != current_byte[bit]) begin crc16_result = crc16_result ^ CRC16_POLY; crc16_result[0] = 1; end end end // Last step is to "mirror" every bit, swap the 2 bytes, and then complement each bit. // // Mirror: for (bit = 0; bit < 16; bit = bit + 1) temp[15-bit] = crc16_result[bit]; // Swap and Complement: crc16_result = ~{temp[7:0], temp[15:8]}; end endtask // Generate a (DOCSIS) CRC32. // // Uses the GLOBAL variables: // // Globals referenced: // parameter CRC32_POLY = 32'h04C11DB7; // reg [ 7:0] crc32_packet[0:255]; // integer crc32_length; // // Globals modified: // reg [31:0] crc32_result; // task gencrc32; integer byte, bit; reg msb; reg [7:0] current_byte; reg [31:0] temp; begin crc32_result = 32'hffffffff; for (byte = 0; byte < crc32_length; byte = byte + 1) begin current_byte = crc32_packet[byte]; for (bit = 0; bit < 8; bit = bit + 1) begin msb = crc32_result[31]; crc32_result = crc32_result << 1; if (msb != current_byte[bit]) begin crc32_result = crc32_result ^ CRC32_POLY; crc32_result[0] = 1; end end end // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit. // // Mirror: for (bit = 0; bit < 32; bit = bit + 1) temp[31-bit] = crc32_result[bit]; // Swap and Complement: crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]}; end endtask endmodule `end_keywords iverilog-12_0/ivtest/contrib/mult16.v000066400000000000000000000100441435245347300176430ustar00rootroot00000000000000// // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // **** Here's a simple, sequential multiplier. Very simple, unsigned.. // Not very well tested, play with testbench, use at your own risk, blah blah blah.. // // // Unsigned 16-bit multiply (multiply two 16-bit inputs to get a 32-bit output) // // Present data and assert start synchronous with clk. // Assert start for ONLY one cycle. // Wait N cycles for answer (at most). Answer will remain stable until next start. // You may use DONE signal as handshake. // // Written by tom coonan // module mult16 (clk, resetb, start, done, ain, bin, yout); parameter N = 16; input clk; input resetb; input start; // Register the ain and bin inputs (they can change afterwards) //input [N-1:0] ain; //input [N-1:0] bin; //output [2*N-1:0] yout; input [15:0] ain; input [15:0] bin; output [31:0] yout; output done; //reg [2*N-1:0] a; //reg [N-1:0] b; //reg [2*N-1:0] yout; reg [31:0] a; reg [15:0] b; reg [31:0] yout; reg done; always @(posedge clk or negedge resetb) begin if (~resetb) begin a <= 0; b <= 0; yout <= 0; done <= 1'b1; end else begin // Load will register the input and clear the counter. if (start) begin a <= ain; b <= bin; yout <= 0; done <= 0; end else begin // Go until b is zero if (~done) begin if (b != 0) begin // If '1' then add a to sum if (b[0]) begin yout <= yout + a; end b <= b >> 1; a <= a << 1; $display ("a = %h, b = %h, yout = %h", a,b,yout); end else begin done <= 1'b1; end end end end end endmodule module mul16; reg clk, resetb, start; reg [15:0] a; reg [15:0] b; wire [31:0] y; wire done; mult16 mult16inst (clk, resetb, start, done, a, b, y); initial begin clk = 0; forever begin #10 clk = ~clk; end end initial begin resetb = 0; #30 resetb = 1; end integer num_errors; parameter MAX_TRIALS = 10; initial begin // $dumpfile ("multdiv.vcd"); // $dumpvars (0,a); // $dumpvars (0,b); // $dumpvars (0,y); // $dumpvars (0,resetb); // $dumpvars (0,done); num_errors = 0; #100; // Do a bunch of random multiplies repeat (MAX_TRIALS) begin test_multiply ($random, $random); end // Special cases test_multiply ($random, 1); test_multiply (1, $random); test_multiply ($random, 0); test_multiply (0, $random); $display ("Done. %0d Errors", num_errors); if(num_errors == 0) $display("PASSED"); #800; $finish; end task test_multiply; input [15:0] aarg; input [15:0] barg; integer expected_answer; begin if (~done) begin $display ("Multiplier is Busy!!"); end else begin @(negedge clk); start = 1; a = aarg; b = barg; @(negedge clk) start = 0; @(posedge done); expected_answer = a*b; $display ("%0d * %0d = %0h, Reality = %0h", a, b, y, expected_answer); if (y !== expected_answer) begin $display (" FAILED!"); num_errors = num_errors + 1; end end end endtask endmodule iverilog-12_0/ivtest/contrib/onehot.v000066400000000000000000000153461435245347300200210ustar00rootroot00000000000000// // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // Just a little demo of some FSM techniques, including One-Hot and // using 'default' settings and the case statements to selectively // update registers (sort of like J-K flip-flops). // // tom coonan, 12/98. // // SDW - modified test to check final X and Y value... and print out // PASSED if it's okay. // module onehot (clk, resetb, a, b, x, y); input clk; input resetb; input [7:0] a; input [7:0] b; output [7:0] x; output [7:0] y; // Use One-Hot encoding. There will be 16 states. // reg [15:0] state, next_state; // These are working registers. Declare the register itself (e.g. 'x') and then // the input bus used to load in a new value (e.g. 'x_in'). The 'x_in' bus will // physically be a wire bus and 'x' will be the flip-flop register ('x_in' must // be declared 'reg' because it's used in an always block. // reg [7:0] x, x_in; reg [7:0] y, y_in; // Update state. 'state' is the actual flip-flop register and next_state is the combinatorial // bus used to update 'state''s value. Check for the ZERO state which means an unexpected // next state was computed. If this occurs, jump to our initialization state; state[0]. // // It is considered good practice by many designers to seperate the combinatorial // and sequential aspects of state registers, and often registers in general. // always @(posedge clk or negedge resetb) begin if (~resetb) state = 0; else begin if (next_state == 0) begin state = 16'h0001; end else begin state = next_state; end end end // Implement the X flip-flop register. Always load the input bus into the register. // Reset to zero. // always @(posedge clk or negedge resetb) begin if (~resetb) x = 0; else x = x_in; end // Implement the Y flip-flop register. Always load the input bus into the register. // Reset to zero. // always @(posedge clk or negedge resetb) begin if (~resetb) y = 0; else y = y_in; end // Generate the next_state function. Also, based on the current state, generate // any new values for X and Y. // always @(state or a or b or x or y) begin // *** Establish defaults. // Working registers by default retain their current value. If any particular // state does NOT need to change a register, then it doesn't have to reference // the register at all. In these cases, the default below takes affect. This // turns out to be a pretty succinct way to control stuff from the FSM. // x_in = x; y_in = y; // State by default will be cleared. If we somehow ever got into an unknown // state, then the default would throw state machine back to zero. Look // at the sequential 'always' block for state to see how this is handled. // next_state = 0; // One-Hot State Machine Encoding. // // *** Using a 1'b1 in the case statement is the trick to doing One-Hot... // DON'T include a 'default' clause within the case because we want to // establish the defaults above. *** // case (1'b1) // synopsys parallel_case // Initialization state. Set X and Y register to some interesting starting values. // state[0]: begin x_in = 8'd20; y_in = 8'd100; next_state[1] = 1'b1; end // Just for fun.. Jump through states.. state[1]: next_state[2] = 1'b1; state[2]: next_state[3] = 1'b1; state[3]: next_state[4] = 1'b1; state[4]: next_state[5] = 1'b1; state[5]: next_state[6] = 1'b1; state[6]: next_state[7] = 1'b1; // Conditionally decrement Y register. state[7]: begin if (a == 1) begin y_in = y - 1; next_state[1] = 1'b1; end else begin next_state[8] = 1'b1; end end // Just for fun.. Jump through states.. state[8]: next_state[9] = 1'b1; state[9]: next_state[10] = 1'b1; state[10]: next_state[11] = 1'b1; // Conditionally increment X register. state[11]: begin if (b == 1) begin x_in = x + 1; next_state[1] = 1'b1; end else begin next_state[12] = 1'b1; end end // Just for fun.. Jump through states.. state[12]: next_state[13] = 1'b1; state[13]: next_state[14] = 1'b1; state[14]: next_state[15] = 1'b1; state[15]: next_state[1] = 1'b1; // Don't go back to our // initialization state, but state // following that one. endcase end endmodule // synopsys translate_off module test_onehot; reg clk, resetb; reg [7:0] a; reg [7:0] b; wire [7:0] x; wire [7:0] y; reg error; // Instantiate module. // onehot onehot ( .clk(clk), .resetb(resetb), .a(a), .b(b), .x(x), .y(y) ); // Generate clock. // initial begin clk = 0; forever begin #10 clk = ~clk; end end // Reset.. // initial begin resetb = 0; #33 resetb = 1; end // Here's the test. // // Should see X and Y get initially loaded with their starting values. // As long as a and b are zero, nothing should change. // When a is asserted, Y should slowly decrement. When b is asserted, X should // slowly increment. That's it. // initial begin `ifdef DEBUG $dumpfile("test.vcd"); $dumpvars(0,test_onehot); `endif // DEBUG error = 0; a = 0; b = 0; repeat (64) @(posedge clk); #1 // Y should be decremented.. a = 1; b = 0; repeat (256) @(posedge clk); #1 // X should be incremented.. a = 0; b = 1; repeat (256) @(posedge clk); if (x !== 8'd43) begin error = 1; $display("FAILED - X Expected value 43, is %d",x); end if (y !== 8'd64) begin error = 1; $display("FAILED - Y Expected value 63, is %d",y); end if(error == 0) $display("PASSED"); $finish; end // Monitor the module. // endmodule iverilog-12_0/ivtest/contrib/pic.v000066400000000000000000002030641435245347300172740ustar00rootroot00000000000000// // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SYNTHETIC PIC 2.0 4/23/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // hex2rom.c - C program used to translate MPLAB's INTEL HEX output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // module picalu ( op, a, b, y, cin, cout, zout ); input [3:0] op; // ALU Operation input [7:0] a; // 8-bit Input a input [7:0] b; // 8-bit Input b output [7:0] y; // 8-bit Output input cin; output cout; output zout; // Reg declarations for outputs reg cout; reg zout; reg [7:0] y; // Internal declarations reg addercout; // Carry out straight from the adder itself. parameter ALUOP_ADD = 4'b0000; parameter ALUOP_SUB = 4'b1000; parameter ALUOP_AND = 4'b0001; parameter ALUOP_OR = 4'b0010; parameter ALUOP_XOR = 4'b0011; parameter ALUOP_COM = 4'b0100; parameter ALUOP_ROR = 4'b0101; parameter ALUOP_ROL = 4'b0110; parameter ALUOP_SWAP = 4'b0111; always @(a or b or cin or op) begin case (op) // synopsys full_case parallel_case ALUOP_ADD: {addercout, y} <= a + b; ALUOP_SUB: {addercout, y} <= a - b; // Carry out is really "borrow" ALUOP_AND: {addercout, y} <= {1'b0, a & b}; ALUOP_OR: {addercout, y} <= {1'b0, a | b}; ALUOP_XOR: {addercout, y} <= {1'b0, a ^ b}; ALUOP_COM: {addercout, y} <= {1'b0, ~a}; ALUOP_ROR: {addercout, y} <= {a[0], cin, a[7:1]}; ALUOP_ROL: {addercout, y} <= {a[7], a[6:0], cin}; ALUOP_SWAP: {addercout, y} <= {1'b0, a[3:0], a[7:4]}; default: {addercout, y} <= {1'b0, 8'h00}; endcase end always @(y) zout <= (y == 8'h00); always @(addercout or op) if (op == ALUOP_SUB) cout <= ~addercout; // Invert adder's carry to get borrow else cout <= addercout; endmodule // // SYNTHETIC PIC 2.0 4/23/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // hex2rom.c - C program used to translate MPLAB's INTEL HEX output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // module piccpu ( clk, reset, paddr, pdata, portain, portbout, portcout, debugw, debugpc, debuginst, debugstatus ); input clk; input reset; output [8:0] paddr; input [11:0] pdata; input [7:0] portain; output [7:0] portbout; output [7:0] portcout; output [7:0] debugw; output [8:0] debugpc; output [11:0] debuginst; output [7:0] debugstatus; // Register declarations for outputs reg [8:0] paddr; reg [7:0] portbout; reg [7:0] portcout; // This should be set to the ROM location where our restart vector is. // As set here, we have 512 words of program space. // parameter RESET_VECTOR = 9'h1FF; parameter INDF_ADDRESS = 3'h0, TMR0_ADDRESS = 3'h1, PCL_ADDRESS = 3'h2, STATUS_ADDRESS = 3'h3, FSR_ADDRESS = 3'h4, PORTA_ADDRESS = 3'h5, PORTB_ADDRESS = 3'h6, PORTC_ADDRESS = 3'h7; // Experimental custom peripheral, "Lil Adder (a 4-bit adder)" is at this address. // parameter EXPADDRESS_LILADDER = 7'h7F; // ********* Special internal registers // Instruction Register reg [11:0] inst; // Program Counter reg [8:0] pc; reg [8:0] pcplus1; // Output of the pc incrementer. // Stack Registers and Stack "levels" register. reg [ 1:0] stacklevel; reg [ 8:0] stack1; reg [ 8:0] stack2; // W Register reg [ 7:0] w; // The STATUS register (#3) is 8 bits wide, however, we only currently use 2 bits // of it; the C and Z bit. // // bit 0 - C // bit 2 - Z // reg [ 7:0] status; // The FSR register is the pointer register used for Indirect addressing (e.g. using INDF). reg [ 7:0] fsr; // Timer 0 reg [ 7:0] tmr0; reg [ 7:0] prescaler; // Option Register reg [7:0] option; // Tristate Control registers. We do not neccessarily support bidirectional ports, but // will save a place for these registers and the TRIS instruction. Use for debug. reg [7:0] trisa; reg [7:0] trisb; reg [7:0] trisc; // I/O Port registers // reg [7:0] porta; // Input PORT reg [7:0] portb; // Output PORT reg [7:0] portc; // Output PORT // ********** Instruction Related signals ****** reg skip; // When HI force a NOP (all zeros) into inst reg [2:0] pcinsel; // Derive special sub signals from inst register wire [ 7:0] k; wire [ 4:0] fsel; wire [ 8:0] longk; wire d; wire [ 2:0] b; // ********** File Address ************ // // This is the 7-bit Data Address that includes the lower 5-bit fsel, the // FSR bits and any indirect addressing. // Use this bus to address the Register File as well as all special registers, etc. // reg [6:0] fileaddr; // Address Selects reg specialsel; reg regfilesel; reg expsel; // ****** Instruction Decoder Outputs ************** // Write enable for the actual ZERO and CARRY bits within the status register. // Generated by the Instruction Decoder. // wire [1:0] aluasel; wire [1:0] alubsel; wire [3:0] aluop; wire zwe; wire cwe; wire isoption; wire istris; wire fwe; // High if any "register" is being written to at all. wire wwe; // Write Enable for the W register. Produced by Instruction Decoder. // ************* Internal Busses, mux connections, etc. ******************** // Bit decoder bits. reg [7:0] bd; // Final decoder value after any polarity inversion. reg [7:0] bdec; // e.g. "Bit Decoded" // Data in and out of the and out of the register file // reg [7:0] regfilein; // Input into Register File, is connected to the dbus. wire [7:0] regfileout; // Path leaving the register file, goes to SBUS Mux reg regfilewe; // Write Enable reg regfilere; // Read Enable // // The dbus (Destination Bus) comes out of the ALU. It is available to all // writable registers. // // The sbus (Source Bus) comes from all readable registers as well as the output // of the Register File. It is one of the primary inputs into the ALU muxes. // // The ebus (Expansion Bus) comes from any of our custom modules. They must // all coordinate to place whoever's data onto ebus. // reg [7:0] dbus; reg [7:0] sbus; reg [7:0] ebus; // ALU Signals // reg [7:0] alua; reg [7:0] alub; wire [7:0] aluout; wire alucin; wire alucout; wire aluz; // ALU A and B mux selects. // parameter ALUASEL_W = 2'b00, ALUASEL_SBUS = 2'b01, ALUASEL_K = 2'b10, ALUASEL_BD = 2'b11; parameter ALUBSEL_W = 2'b00, ALUBSEL_SBUS = 2'b01, ALUBSEL_K = 2'b10, ALUBSEL_1 = 2'b11; // ALU Operation codes. // parameter ALUOP_ADD = 4'b0000; parameter ALUOP_SUB = 4'b1000; parameter ALUOP_AND = 4'b0001; parameter ALUOP_OR = 4'b0010; parameter ALUOP_XOR = 4'b0011; parameter ALUOP_COM = 4'b0100; parameter ALUOP_ROR = 4'b0101; parameter ALUOP_ROL = 4'b0110; parameter ALUOP_SWAP = 4'b0111; // Instantiate each of our subcomponents // picregs regs ( .clk (clk), .reset (reset), .we (regfilewe), .re (regfilere), .bank (fileaddr[6:5]), .location (fileaddr[4:0]), .din (regfilein), .dout (regfileout) ); // Instatiate the ALU. // picalu alu ( .op (aluop), .a (alua), .b (alub), .y (aluout), .cin (status[0]), .cout (alucout), .zout (aluz) ); // Instantiate the Instruction Decoder. This is really just a lookup table. // Given the instruction, generate all the signals we need. // // For example, each instruction implies a specific ALU operation. Some of // these are obvious such as the ADDW uses an ADD alu op. Less obvious is // that a mov instruction uses an OR op which lets us do a simple copy. // // Data has to funnel through the ALU, which sometimes makes for contrived // ALU ops. // picidec idec ( .inst (inst), .aluasel (aluasel), .alubsel (alubsel), .aluop (aluop), .wwe (wwe), .fwe (fwe), .zwe (zwe), .cwe (cwe), .bdpol (bdpol), .option (isoption), .tris (istris) ); // *********** Debug **************** assign debugw = w; assign debugpc = pc; assign debuginst = inst; assign debugstatus = status; // *********** REGISTER FILE Addressing **************** // // We implement the following: // - The 5-bit fsel address is within a "BANK" which is 32 bytes. // - The FSR bits 6:5 are the BANK select, so there are 4 BANKS, a // total of 128 bytes. Minus the 8 special registers, that's // really 120 bytes. // - The INDF register is for indirect addressing. Referencing INDF // uses FSR as the pointer. Therefore, using INDF/FSR you address // 7-bits of memory. // We DO NOT currently implement the PAGE for program (e.g. STATUS register // bits 6:5) // // The fsel address *may* be zero in which case, we are to do indirect // addressing, using FSR register as the 8-bit pointer. // // Otherwise, use the 5-bits of FSEL (from the Instruction itself) and // 2 bank bits from the FSR register (bits 6:5). // always @(fsel or fsr) begin if (fsel == INDF_ADDRESS) begin // The INDEX register is addressed. There really is no INDEX register. // Use the FSR as an index, e.g. the FSR contents are the fsel. // fileaddr <= fsr[6:0]; end else begin // Use FSEL field and status bank select bits // fileaddr <= {fsr[6:5], fsel}; end end // Write Enable to Register File. // Assert this when the general fwe (write enable to *any* register) is true AND Register File // address range is specified. // always @(regfilesel or fwe) regfilewe <= regfilesel & fwe; // Read Enable (this if nothing else, helps in debug.) // Assert if Register File address range is specified AND the ALU is actually using some // data off the SBUS. // always @(regfilesel or aluasel or alubsel) regfilere <= regfilesel & ((aluasel == ALUASEL_SBUS) | (alubsel == ALUBSEL_SBUS)); // *********** Address Decodes ************** // // Generate 3 selects: specialsel, regfilesel and expsel always @(fileaddr) begin casex (fileaddr) 7'bXX00XXX: // The SPECIAL Registers are lower 8 addresses, in ALL BANKS begin specialsel <= 1'b1; regfilesel <= 1'b0; expsel <= 1'b0; end 7'b1111111: // EXPANSION Registers are the top (1) addresses begin specialsel <= 1'b0; regfilesel <= 1'b0; expsel <= 1'b1; end default: // Anything else must be in the Register File begin specialsel <= 1'b0; regfilesel <= 1'b1; expsel <= 1'b0; end endcase end // *********** SBUS ************** // The sbus (Source Bus) is the output of a multiplexor that takes // inputs from the Register File, and all other special registers // and input ports. The Source Bus then, one of the inputs to the ALU // First MUX selects from all the special regsiters // always @(fsel or fsr or tmr0 or pc or status or porta or portb or portc or regfileout or ebus or specialsel or regfilesel or expsel) begin // For our current mix of registers and peripherals, only the first 8 addresses // are "special" registers (e.g. not in the Register File). As more peripheral // registers are added, they must be muxed into this MUX as well. // // We currently prohibit tristates. // // if (specialsel) begin // Special register case (fsel[2:0]) // synopsys parallel_case full_case 3'h0: sbus <= fsr; 3'h1: sbus <= tmr0; 3'h2: sbus <= pc[7:0]; 3'h3: sbus <= status; 3'h4: sbus <= fsr; 3'h5: sbus <= porta; // PORTA is an input-only port 3'h6: sbus <= portb; // PORTB is an output-only port 3'h7: sbus <= portc; // PORTC is an output-only port endcase end else begin // // Put whatever address equation is neccessary here. Remember to remove unnecessary // memory elements from Register File (picregs.v). It'll still work, but they'd be // wasted flip-flops. // if (expsel) begin sbus <= ebus; end else begin if (regfilesel) begin // Final Priority is Choose the register file sbus <= regfileout; end else begin sbus <= 8'h00; end end end end // ************** DBUS ****** // The Destination bus is just the output of the ALU. // always @(aluout) dbus <= aluout; always @(dbus) regfilein <= dbus; // Drive the ROM address bus straight from the PC // always @(pc) paddr = pc; // Define sub-signals out of inst // assign k = inst[7:0]; assign fsel = inst[4:0]; assign longk = inst[8:0]; assign d = inst[5]; assign b = inst[7:5]; // Bit Decoder. // // Simply take the 3-bit b field in the PIC instruction and create the // expanded 8-bit decoder field, which is used as a mask. // always @(b) begin case (b) 3'b000: bdec <= 8'b00000001; 3'b001: bdec <= 8'b00000010; 3'b010: bdec <= 8'b00000100; 3'b011: bdec <= 8'b00001000; 3'b100: bdec <= 8'b00010000; 3'b101: bdec <= 8'b00100000; 3'b110: bdec <= 8'b01000000; 3'b111: bdec <= 8'b10000000; endcase end always @(bdec or bdpol) bd <= bdec ^ bdpol; // Instruction regsiter usually get the ROM data as its input, but // sometimes for branching, the skip signal must cause a NOP. // always @(posedge clk) begin if (reset) begin inst <= 12'h000; end else begin if (skip == 1'b1) begin inst <= 12'b000000000000; // FORCE NOP end else begin inst <= pdata; end end end // SKIP signal. // // We want to insert the NOP instruction for the following conditions: // GOTO,CALL and RETLW instructions (All have inst[11:10] = 2'b10 // BTFSS instruction when aluz is HI ( // BTFSC instruction when aluz is LO // always @(inst or aluz) begin casex ({inst, aluz}) 13'b10??_????_????_?: // A GOTO, CALL or RETLW instructions skip <= 1'b1; 13'b0110_????_????_1: // BTFSC instruction and aluz == 1 skip <= 1'b1; 13'b0111_????_????_0: // BTFSS instruction and aluz == 0 skip <= 1'b1; 13'b0010_11??_????_1: // DECFSZ instruction and aluz == 1 skip <= 1'b1; 13'b0011_11??_????_1: // INCFSZ instruction and aluz == 1 skip <= 1'b1; default: skip <= 1'b0; endcase end // 4:1 Data MUX into alua // // always @(aluasel or w or sbus or k or bd) begin case (aluasel) 2'b00: alua <= w; 2'b01: alua <= sbus; 2'b10: alua <= k; 2'b11: alua <= bd; endcase end // 4:1 Data MUX into alub // // always @(alubsel or w or sbus or k) begin case (alubsel) 2'b00: alub <= w; 2'b01: alub <= sbus; 2'b10: alub <= k; 2'b11: alub <= 8'b00000001; endcase end // W Register always @(posedge clk) begin if (reset) begin w <= 8'h00; end else begin if (wwe) begin w <= dbus; end end end // ************ Writes to various Special Registers (fsel between 0 and 7) // INDF Register (Register #0) // // Not a real register. This is the Indirect Addressing mode register. // See the regfileaddr logic. // TMR0 Register (Register #1) // // Timer0 is currently only a free-running timer clocked by the main system clock. // always @(posedge clk) begin if (reset) begin tmr0 <= 8'h00; end else begin // See if the status register is actually being written to if (fwe & specialsel & (fsel == TMR0_ADDRESS)) begin // Yes, so just update the register from the dbus tmr0 <= dbus; end else begin // Mask off the prescaler value based on desired divide ratio. // Whenever this is zero, then that is our divided pulse. Increment // the final timer value when it's zero. // case (option[2:0]) // synopsys parallel_case full_case 3'b000: if (~|(prescaler & 8'b00000001)) tmr0 <= tmr0 + 1; 3'b001: if (~|(prescaler & 8'b00000011)) tmr0 <= tmr0 + 1; 3'b010: if (~|(prescaler & 8'b00000111)) tmr0 <= tmr0 + 1; 3'b011: if (~|(prescaler & 8'b00001111)) tmr0 <= tmr0 + 1; 3'b100: if (~|(prescaler & 8'b00011111)) tmr0 <= tmr0 + 1; 3'b101: if (~|(prescaler & 8'b00111111)) tmr0 <= tmr0 + 1; 3'b110: if (~|(prescaler & 8'b01111111)) tmr0 <= tmr0 + 1; 3'b111: if (~|(prescaler & 8'b11111111)) tmr0 <= tmr0 + 1; endcase end end end // The prescaler is always counting from 00 to FF always @(posedge clk) begin if (reset) begin prescaler <= 8'h00; end else begin // See if the status register is actually being written to prescaler <= prescaler + 1; end end // PCL Register (Register #2) // // PC Lower 8 bits. This is handled in the PC section below... // STATUS Register (Register #3) // always @(posedge clk) begin if (reset) begin status <= 8'h00; end else begin // See if the status register is actually being written to if (fwe & specialsel & (fsel == STATUS_ADDRESS)) begin // Yes, so just update the register from the dbus status <= dbus; end else begin // Update status register on a bit-by-bit basis. // // For the carry and zero flags, each instruction has its own rule as // to whether to update this flag or not. The instruction decoder is // providing us with an enable for C and Z. Use this to decide whether // to retain the existing value, or update with the new alu status output. // status <= { status[7], // BIT 7: Undefined.. (maybe use for debugging) status[6], // BIT 6: Program Page, HI bit status[5], // BIT 5: Program Page, LO bit status[4], // BIT 4: Time Out bit (not implemented at this time) status[3], // BIT 3: Power Down bit (not implemented at this time) (zwe) ? aluz : status[2], // BIT 2: Z status[1], // BIT 1: DC (cwe) ? alucout : status[0] // BIT 0: C }; end end end // FSR Register (Register #4) // always @(posedge clk) begin if (reset) begin fsr <= 8'h00; end else begin // See if the status register is actually being written to if (fwe & specialsel & (fsel == FSR_ADDRESS)) begin fsr <= dbus; end end end // OPTION Register // // The special OPTION instruction should move W into the OPTION register. always @(posedge clk) begin if (reset) begin option <= 8'h00; end else begin if (isoption) option <= dbus; end end // PORTA Input Port (Register #5) // // Register anything on the module's porta input on every single clock. // always @(posedge clk) begin if (reset) begin porta <= 8'h00; end else begin porta <= portain; end end // PORTB Output Port (Register #6) always @(posedge clk) begin if (reset) begin portb <= 8'h00; end else begin if (fwe & specialsel & (fsel == PORTB_ADDRESS) & ~istris) begin portb <= dbus; end end end // Connect the output ports to the register output. always @(portb) portbout <= portb; // PORTC Output Port (Register #7) always @(posedge clk) begin if (reset) begin portc <= 8'h00; end else begin if (fwe & specialsel & (fsel == PORTC_ADDRESS) & ~istris) begin portc <= dbus; end end end // Connect the output ports to the register output. always @(portc) portcout <= portc; // TRIS Registers always @(posedge clk) begin if (reset) begin trisa <= 8'hff; // Default is to tristate them end else begin if (fwe & specialsel & (fsel == PORTA_ADDRESS) & istris) begin trisa <= dbus; end end end always @(posedge clk) begin if (reset) begin trisb <= 8'hff; // Default is to tristate them end else begin if (fwe & specialsel & (fsel == PORTB_ADDRESS) & istris) begin trisb <= dbus; end end end always @(posedge clk) begin if (reset) begin trisc <= 8'hff; // Default is to tristate them end else begin if (fwe & specialsel & (fsel == PORTC_ADDRESS) & istris) begin trisc <= dbus; end end end // ********** PC AND STACK ************************* // // There are 4 ways to change the PC. They are: // GOTO 101k_kkkk_kkkk // CALL 1001_kkkk_kkkk // RETLW 1000_kkkk_kkkk // MOVF 0010_0010_0010 (e.g. a write to reg #2) // // Remember that the skip instructions work by inserting // a NOP instruction or not into program stream and don't // change the PC. // // We need pc + 1 in several places, so lets define this incrementor and // its output signal it in one place so that we never get redundant adders. // always @(pc) pcplus1 <= pc + 1; parameter PC_SELECT_PCPLUS1 = 3'b000, PC_SELECT_K = 3'b001, PC_SELECT_STACK1 = 3'b010, PC_SELECT_STACK2 = 3'b011, PC_SELECT_DBUS = 3'b100, PC_SELECT_RESET_VECTOR = 3'b101; // 8:1 Data MUX into PC always @(posedge clk) begin case (pcinsel) // synopsys parallel_case full_case 3'b000: pc <= pcplus1; 3'b001: pc <= k; 3'b010: pc <= stack1; 3'b011: pc <= stack2; 3'b100: pc <= dbus; 3'b101: pc <= RESET_VECTOR; // Don't really carry about these... 3'b110: pc <= pc; 3'b111: pc <= pc; endcase end // Select for the MUX going into the PC. // // always @(inst or stacklevel or reset) begin if (reset == 1'b1) begin pcinsel <= PC_SELECT_RESET_VECTOR; end else begin casex ({inst, stacklevel}) 14'b101?_????_????_??: pcinsel <= PC_SELECT_K; // GOTO 14'b1001_????_????_??: pcinsel <= PC_SELECT_K; // CALL 14'b1000_????_????_00: pcinsel <= PC_SELECT_STACK1; // RETLW 14'b1000_????_????_01: pcinsel <= PC_SELECT_STACK1; // RETLW 14'b1000_????_????_10: pcinsel <= PC_SELECT_STACK2; // RETLW 14'b1000_????_????_11: pcinsel <= PC_SELECT_STACK2; // RETLW 14'b0010_0010_0010_??: pcinsel <= PC_SELECT_DBUS; // MOVF where f=PC default: pcinsel <= PC_SELECT_PCPLUS1; endcase end end // Implement STACK1 and STACK2 registers // // The Stack registers are only fed from the PC itself! // always @(posedge clk) begin if (reset) begin stack1 <= 9'h000; end else begin // CALL instruction if (inst[11:8] == 4'b1001) begin case (stacklevel) 2'b00: // No previous CALLs begin stack1 <= pc; $display ("Write to STACK1: %0h", pc); end 2'b01: // ONE previous CALL begin stack2 <= pc; $display ("Write to STACK2: %0h", pc); end 2'b10: // TWO previous CALLs -- This is illegal on the 16C5X! begin $display ("Too many CALLs!!"); end 2'b11: begin $display ("Too many CALLs!!"); end endcase end end end // Write to stacklevel // // The stacklevel register keeps track of the current stack depth. On this // puny processor, there are only 2 levels (you could fiddle with this and // increase the stack depth). There are two stack registers, stack1 and stack2. // The stack1 register is used first (e.g. the first time a call is performed), // then stack2. As CALLs are done, stacklevel increments. Conversely, as // RETs are done, stacklevel goes down. always @(posedge clk) begin if (reset == 1'b1) begin stacklevel <= 2'b00; // On reset, there should be no CALLs in progress end else begin casex ({inst, stacklevel}) // Call instructions 14'b1001_????_????_00: stacklevel <= 2'b01; // Record 1st CALL 14'b1001_????_????_01: stacklevel <= 2'b10; // Record 2nd CALL 14'b1001_????_????_10: stacklevel <= 2'b10; // Already 2! Ignore 14'b1001_????_????_11: stacklevel <= 2'b00; // {shouldn't happen} // Return instructions 14'b1000_????_????_00: stacklevel <= 2'b00; // {shouldn't happen} 14'b1000_????_????_01: stacklevel <= 2'b00; // Go back to no CALL in progress 14'b1000_????_????_10: stacklevel <= 2'b01; // Go back to 1 CALL in progress 14'b1000_????_????_11: stacklevel <= 2'b10; // {shouldn't happen} sort of like, Go back to 2 calls in progress default: stacklevel <= stacklevel; endcase end end // ************ EXPANSION ************************* // // The following is an example of customization. // // Example: Create a read/write port located at address 7F. It'll be 8-bits, where // the upper 4 bits are outputs and the lower 4 bits are inputs. // Use indirect addressing to access it (INDF/FSR). Just for fun, let's // attach a special loop-back circuit between the outputs and inputs. // Let's attach... say... a 4-bit adder. // reg [3:0] special_peripheral_writeable_bits; reg [3:0] special_peripheral_readeable_bits; // Implement the writeable bits. // always @(posedge clk) begin if (reset) begin special_peripheral_writeable_bits <= 4'b0000; end else begin if (fwe & expsel & (fileaddr == EXPADDRESS_LILADDER)) begin special_peripheral_writeable_bits <= dbus; end end end // Implement the special peripheral function (the 4-bit adder for this example). always @(special_peripheral_writeable_bits) begin special_peripheral_readeable_bits <= special_peripheral_writeable_bits + 1; end // Drive the ebus. With only one custom address, no more muxing needs to be // done, but if there are multiple custom circuits, everyone needs to cooperate // and drive ebus properly. // always @(fileaddr or special_peripheral_readeable_bits) begin if (fileaddr == EXPADDRESS_LILADDER) ebus <= special_peripheral_readeable_bits; else ebus <= 8'hff; end endmodule // // SYNTHETIC PIC 2.0 4/23/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // hex2rom.c - C program used to translate MPLAB's INTEL HEX output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // // This is the PIC Instruction Decoder. // // The 12-bit PIC instruction must result in a set of control // signals to the ALU, register write enables and other wires. // This is purely combinatorial. This can physically be // implemented as a ROM, or, in this implementation a Verilog // casex statement is used to directly synthesize the signals. // This approach is more portable, and hopefully much reduction // occurs in the equations. // // The Synthetic PIC Manual contains a table that better shows // all the required signals per instruction. I basically // took that table and created the Verilog implementation below. // module picidec ( inst, aluasel, alubsel, aluop, wwe, fwe, zwe, cwe, bdpol, option, tris ); input [11:0] inst; output [1:0] aluasel; output [1:0] alubsel; output [3:0] aluop; output wwe; output fwe; output zwe; output cwe; output bdpol; output option; output tris; reg [14:0] decodes; // For reference, the ALU Op codes are: // // ADD 0000 // SUB 1000 // AND 0001 // OR 0010 // XOR 0011 // COM 0100 // ROR 0101 // ROL 0110 // SWAP 0111 assign { aluasel, // Select source for ALU A input. 00=W, 01=SBUS, 10=K, 11=BD alubsel, // Select source for ALU B input. 00=W, 01=SBUS, 10=K, 11="1" aluop, // ALU Operation (see comments above for these codes) wwe, // W register Write Enable fwe, // File Register Write Enable zwe, // Status register Z bit update cwe, // Status register Z bit update bdpol, // Polarity on bit decode vector (0=no inversion, 1=invert) tris, // Instruction is an TRIS instruction option // Instruction is an OPTION instruction } = decodes; // This is a large combinatorial decoder. // I use the casex statement. always @(inst) begin casex (inst) // *** Byte-Oriented File Register Operations // // A A ALU W F Z C B T O // L L O W W W W D R P // U U P E E E E P I T // A B O S // L 12'b0000_0000_0000: decodes <= 15'b00_00_0000_0_0_0_0_0_0_0; // NOP 12'b0000_001X_XXXX: decodes <= 15'b00_00_0010_0_1_0_0_0_0_0; // MOVWF 12'b0000_0100_0000: decodes <= 15'b00_00_0011_1_0_1_0_0_0_0; // CLRW 12'b0000_011X_XXXX: decodes <= 15'b00_00_0011_0_1_1_0_0_0_0; // CLRF 12'b0000_100X_XXXX: decodes <= 15'b01_00_1000_1_0_1_1_0_0_0; // SUBWF (d=0) 12'b0000_101X_XXXX: decodes <= 15'b01_00_1000_0_1_1_1_0_0_0; // SUBWF (d=1) 12'b0000_110X_XXXX: decodes <= 15'b01_11_1000_1_0_1_0_0_0_0; // DECF (d=0) 12'b0000_111X_XXXX: decodes <= 15'b01_11_1000_0_1_1_0_0_0_0; // DECF (d=1) 12'b0001_000X_XXXX: decodes <= 15'b00_01_0010_1_0_1_0_0_0_0; // IORWF (d=0) 12'b0001_001X_XXXX: decodes <= 15'b00_01_0010_0_1_1_0_0_0_0; // IORWF (d=1) 12'b0001_010X_XXXX: decodes <= 15'b00_01_0001_1_0_1_0_0_0_0; // ANDWF (d=0) 12'b0001_011X_XXXX: decodes <= 15'b00_01_0001_0_1_1_0_0_0_0; // ANDWF (d=1) 12'b0001_100X_XXXX: decodes <= 15'b00_01_0011_1_0_1_0_0_0_0; // XORWF (d=0) 12'b0001_101X_XXXX: decodes <= 15'b00_01_0011_0_1_1_0_0_0_0; // XORWF (d=1) 12'b0001_110X_XXXX: decodes <= 15'b00_01_0000_1_0_1_1_0_0_0; // ADDWF (d=0) 12'b0001_111X_XXXX: decodes <= 15'b00_01_0000_0_1_1_1_0_0_0; // ADDWF (d=1) 12'b0010_000X_XXXX: decodes <= 15'b01_01_0010_1_0_1_0_0_0_0; // MOVF (d=0) 12'b0010_001X_XXXX: decodes <= 15'b01_01_0010_0_1_1_0_0_0_0; // MOVF (d=1) 12'b0010_010X_XXXX: decodes <= 15'b01_01_0100_1_0_1_0_0_0_0; // COMF (d=0) 12'b0010_011X_XXXX: decodes <= 15'b01_01_0100_0_1_1_0_0_0_0; // COMF (d=1) 12'b0010_100X_XXXX: decodes <= 15'b01_11_0000_1_0_1_0_0_0_0; // INCF (d=0) 12'b0010_101X_XXXX: decodes <= 15'b01_11_0000_0_1_1_0_0_0_0; // INCF (d=1) 12'b0010_110X_XXXX: decodes <= 15'b01_11_1000_1_0_0_0_0_0_0; // DECFSZ(d=0) 12'b0010_111X_XXXX: decodes <= 15'b01_11_1000_0_1_0_0_0_0_0; // DECFSZ(d=1) 12'b0011_000X_XXXX: decodes <= 15'b01_01_0101_1_0_0_1_0_0_0; // RRF (d=0) 12'b0011_001X_XXXX: decodes <= 15'b01_01_0101_0_1_0_1_0_0_0; // RRF (d=1) 12'b0011_010X_XXXX: decodes <= 15'b01_01_0110_1_0_0_1_0_0_0; // RLF (d=0) 12'b0011_011X_XXXX: decodes <= 15'b01_01_0110_0_1_0_1_0_0_0; // RLF (d=1) 12'b0011_100X_XXXX: decodes <= 15'b01_01_0111_1_0_0_0_0_0_0; // SWAPF (d=0) 12'b0011_101X_XXXX: decodes <= 15'b01_01_0111_0_1_0_0_0_0_0; // SWAPF (d=1) 12'b0011_110X_XXXX: decodes <= 15'b01_11_0000_1_0_0_0_0_0_0; // INCFSZ(d=0) 12'b0011_111X_XXXX: decodes <= 15'b01_11_0000_0_1_0_0_0_0_0; // INCFSZ(d=1) // *** Bit-Oriented File Register Operations // // A A ALU W F Z C B T O // L L O W W W W D R P // U U P E E E E P I T // A B O S // L 12'b0100_XXXX_XXXX: decodes <= 15'b11_01_0001_0_1_0_0_1_0_0; // BCF 12'b0101_XXXX_XXXX: decodes <= 15'b11_01_0010_0_1_0_0_0_0_0; // BSF 12'b0110_XXXX_XXXX: decodes <= 15'b11_01_0001_0_0_0_0_0_0_0; // BTFSC 12'b0111_XXXX_XXXX: decodes <= 15'b11_01_0001_0_0_0_0_0_0_0; // BTFSS // *** Literal and Control Operations // // A A ALU W F Z C B T O // L L O W W W W D R P // U U P E E E E P I T // A B O S // L 12'b0000_0000_0010: decodes <= 15'b00_00_0010_0_1_0_0_0_0_1; // OPTION 12'b0000_0000_0011: decodes <= 15'b00_00_0000_0_0_0_0_0_0_0; // SLEEP 12'b0000_0000_0100: decodes <= 15'b00_00_0000_0_0_0_0_0_0_0; // CLRWDT 12'b0000_0000_0101: decodes <= 15'b00_00_0000_0_1_0_0_0_1_0; // TRIS 5 12'b0000_0000_0110: decodes <= 15'b00_00_0010_0_1_0_0_0_1_0; // TRIS 6 12'b0000_0000_0111: decodes <= 15'b00_00_0010_0_1_0_0_0_1_0; // TRIS 7 // // A A ALU W F Z C B T O // L L O W W W W D R P // U U P E E E E P I T // A B O S // L 12'b1000_XXXX_XXXX: decodes <= 15'b10_10_0010_1_0_0_0_0_0_0; // RETLW 12'b1001_XXXX_XXXX: decodes <= 15'b10_10_0010_0_0_0_0_0_0_0; // CALL 12'b101X_XXXX_XXXX: decodes <= 15'b10_10_0010_0_0_0_0_0_0_0; // GOTO 12'b1100_XXXX_XXXX: decodes <= 15'b10_10_0010_1_0_0_0_0_0_0; // MOVLW 12'b1101_XXXX_XXXX: decodes <= 15'b00_10_0010_1_0_1_0_0_0_0; // IORLW 12'b1110_XXXX_XXXX: decodes <= 15'b00_10_0001_1_0_1_0_0_0_0; // ANDLW 12'b1111_XXXX_XXXX: decodes <= 15'b00_10_0011_1_0_1_0_0_0_0; // XORLW default: decodes <= 15'b00_00_0000_0_0_0_0_0_0_0; endcase end endmodule // // SYNTHETIC PIC 2.0 4/23/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // hex2rom.c - C program used to translate MPLAB's INTEL HEX output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // //`define DEBUG_SHOWREADS //`define DEBUG_SHOWWRITES // Memory Map: // // PIC Data Memory addressing is complicated. See the Data Book for full explanation.. // // Basically, each BANK contains 32 locations. The lowest 16 locations in ALL Banks // are really all mapped to the same bank (bank #0). The first 8 locations are the Special // registers like the STATUS and PC registers. The upper 16 words in each bank, really are // unique to each bank. The smallest PIC (16C54) only has the one bank #0. // // So, as a programmer, what you get is this. No matter what bank you are in (FSR[6:5]) // you always have access to your special registers and also to registers 8-15. You can // change to a 1 of 4 banks by setting FSR[6:5] and get 4 different sets of registers // 16-31. // // For numbering purposes, I've numbered the registers as if they are one linear memory // space, just like in the Data Book (see Figure 4-15 "Direct/Indirect Addressing"). // So, the unique 16 registers in bank #1 are named r48 - r63 (I use decimal). The // unique registers in bank #3 are therefore r112 - r127. There is no r111 because, // remember, the lower 16 registers each each bank are all reall the same registers 0-15. // // Confused?! The Data Book explains it better than I can. // // bank location // XX 00rrr - The special registers are not implemented in this register file. // XX 01rrr - The 8 common words, just above the Special Regs, same for all Banks // 00 1rrrr - The 16 words unique to Bank #0 // 01 1rrrr - The 16 words unique to Bank #1 // 10 1rrrr - The 16 words unique to Bank #2 // 11 1rrrr - The 16 words unique to Bank #3 // // So, // Special Regs are location[4:3] == 00 // Common Regs are location[4:3] == 01 // Words in banks location[4] == 1 // // // I had problems trying to use simple register file declarations that // would always, always work right, were synthesizable and allowed // me to easily remove locations from the memory space. SOOOooo... I // did the brute force thing and enumerated all the locations.. // // Much larger spaces will probably need a RAM and whatever I do would need // custom hacking anyway.. I don't see an obvious solution to all this, but // welcome suggestions.. // module picregs (clk, reset, we, re, bank, location, din, dout); input clk; input reset; input we; input re; input [1:0] bank; // Bank 0,1,2,3 input [4:0] location; // Location input [7:0] din; // Input output [7:0] dout; // Output //parameter MAX_ADDRESS = 127; reg [7:0] dout; integer index; // Declare the major busses in and out of each block. // reg [7:0] commonblockout; // Data Memory common across all banks reg [7:0] highblock0out; // Upper 16 bytes in BANK #0 reg [7:0] highblock1out; // Upper 16 bytes in BANK #1 reg [7:0] highblock2out; // Upper 16 bytes in BANK #2 reg [7:0] highblock3out; // Upper 16 bytes in BANK #3 reg [7:0] commonblockin; // Data Memory common across all banks reg [7:0] highblock0in; // Upper 16 bytes in BANK #0 reg [7:0] highblock1in; // Upper 16 bytes in BANK #1 reg [7:0] highblock2in; // Upper 16 bytes in BANK #2 reg [7:0] highblock3in; // Upper 16 bytes in BANK #3 reg commonblocksel; // Select reg highblock0sel; // Select reg highblock1sel; // Select reg highblock2sel; // Select reg highblock3sel; // Select // synopsys translate_off integer cycle_counter; initial cycle_counter = 0; always @(negedge clk) begin if (re) begin `ifdef DEBUG_SHOWREADS $display ("[%0d] Read: data = %0h(hex), from bank #%0d(dec) location %0h", cycle_counter, dout, bank, location); `endif end if (we) begin `ifdef DEBUG_SHOWWRITES $display ("[%0d] Write: data = %0h(hex), to bank #%0d(dec) location %0h", cycle_counter, din, bank, location); `endif end if (~reset) cycle_counter = cycle_counter + 1; end // synopsys translate_on // READ the Register File // always @(bank or location or re or commonblockout or highblock0out or highblock1out or highblock2out or highblock3out) begin if (re) begin if (location[4:3] == 2'b01) begin // This is the lower 8 words, common to all banks, just above special registers dout <= commonblockout; // Access to first 8 locations past Special Registers end else begin if (location[4]) begin // Address is in the upper 16 words on one of the 4 banks case (bank) // synopsys full_case parallel_case 2'b00: dout <= highblock0out; // Upper 16 words of Bank #0 2'b01: dout <= highblock1out; // Upper 16 words of Bank #1 2'b10: dout <= highblock2out; // Upper 16 words of Bank #2 2'b11: dout <= highblock3out; // Upper 16 words of Bank #3 endcase end else begin dout <= 8'hff; end end end else begin dout <= 8'hff; end end // Initial Write logic. // // Generate the specific write enables based on the PIC's bank/location rules. // The individual memory blocks will do the actual synchronous write. // always @(we or bank or location or reset) begin if (reset) begin commonblocksel <= 1'b0; highblock0sel <= 1'b0; highblock1sel <= 1'b0; highblock2sel <= 1'b0; highblock3sel <= 1'b0; end else begin if (we) begin if (location[4:3] == 2'b01) begin // This is the lower 8 words, common to all banks, just above special registers commonblocksel <= 1'b1; highblock0sel <= 1'b0; highblock1sel <= 1'b0; highblock2sel <= 1'b0; highblock3sel <= 1'b0; end else begin if (location[4]) begin // Address is in the upper 16 words on one of the 4 banks commonblocksel <= 1'b0; case (bank) // synopsys full_case parallel_case 2'b00: {highblock0sel, highblock1sel, highblock2sel, highblock3sel} <= 4'b1000; // Upper 16 words of Bank #0 2'b01: {highblock0sel, highblock1sel, highblock2sel, highblock3sel} <= 4'b0100; // Upper 16 words of Bank #1 2'b10: {highblock0sel, highblock1sel, highblock2sel, highblock3sel} <= 4'b0010; // Upper 16 words of Bank #2 2'b11: {highblock0sel, highblock1sel, highblock2sel, highblock3sel} <= 4'b0001; // Upper 16 words of Bank #3 endcase end else begin commonblocksel <= 1'b0; highblock0sel <= 1'b0; highblock1sel <= 1'b0; highblock2sel <= 1'b0; highblock3sel <= 1'b0; end end end else begin commonblocksel <= 1'b0; highblock0sel <= 1'b0; highblock1sel <= 1'b0; highblock2sel <= 1'b0; highblock3sel <= 1'b0; end end end // *** Buses feeding the memory blocks are driven directly from din. always @(din) commonblockin <= din; always @(din) highblock0in <= din; always @(din) highblock1in <= din; always @(din) highblock2in <= din; always @(din) highblock3in <= din; // ****************** Common Block ************* reg [7:0] r8, r9, r10, r11, r12, r13, r14, r15; // Read from common block always @(location or r8 or r9 or r10 or r11 or r12 or r13 or r14 or r15) begin case (location[2:0]) 3'h0: commonblockout <= r8; 3'h1: commonblockout <= r9; 3'h2: commonblockout <= r10; 3'h3: commonblockout <= r11; 3'h4: commonblockout <= r12; 3'h5: commonblockout <= r13; 3'h6: commonblockout <= r14; 3'h7: commonblockout <= r15; endcase end // Write to common block always @(posedge clk) begin if (we & commonblocksel) begin case (location[2:0]) 3'h0: r8 <= commonblockin; 3'h1: r9 <= commonblockin; 3'h2: r10 <= commonblockin; 3'h3: r11 <= commonblockin; 3'h4: r12 <= commonblockin; 3'h5: r13 <= commonblockin; 3'h6: r14 <= commonblockin; 3'h7: r15 <= commonblockin; endcase end end // **************** Highblock0 **************** reg [7:0] r16, r17, r18, r19, r20, r21, r22, r23; reg [7:0] r24, r25, r26, r27, r28, r29, r30, r31; // Read from high block bank0 always @(location or r16 or r17 or r18 or r19 or r20 or r21 or r22 or r23 or r24 or r25 or r26 or r27 or r28 or r29 or r30 or r31 ) begin case (location[3:0]) 4'h0: highblock0out <= r16; 4'h1: highblock0out <= r17; 4'h2: highblock0out <= r18; 4'h3: highblock0out <= r19; 4'h4: highblock0out <= r20; 4'h5: highblock0out <= r21; 4'h6: highblock0out <= r22; 4'h7: highblock0out <= r23; 4'h8: highblock0out <= r24; 4'h9: highblock0out <= r25; 4'hA: highblock0out <= r26; 4'hB: highblock0out <= r27; 4'hC: highblock0out <= r28; 4'hD: highblock0out <= r29; 4'hE: highblock0out <= r30; 4'hF: highblock0out <= r31; endcase end // Write to high block bank 0 always @(posedge clk) begin if (we & highblock0sel) begin case (location[3:0]) 4'h0: r16 <= highblock0in; 4'h1: r17 <= highblock0in; 4'h2: r18 <= highblock0in; 4'h3: r19 <= highblock0in; 4'h4: r20 <= highblock0in; 4'h5: r21 <= highblock0in; 4'h6: r22 <= highblock0in; 4'h7: r23 <= highblock0in; 4'h8: r24 <= highblock0in; 4'h9: r25 <= highblock0in; 4'hA: r26 <= highblock0in; 4'hB: r27 <= highblock0in; 4'hC: r28 <= highblock0in; 4'hD: r29 <= highblock0in; 4'hE: r30 <= highblock0in; 4'hF: r31 <= highblock0in; endcase end end // **************** Highblock1 **************** reg [7:0] r48, r49, r50, r51, r52, r53, r54, r55; reg [7:0] r56, r57, r58, r59, r60, r61, r62, r63; // Read always @(location or r48 or r49 or r50 or r51 or r52 or r53 or r54 or r55 or r56 or r57 or r58 or r59 or r60 or r61 or r62 or r63 ) begin case (location[3:0]) 4'h0: highblock1out <= r48; 4'h1: highblock1out <= r49; 4'h2: highblock1out <= r50; 4'h3: highblock1out <= r51; 4'h4: highblock1out <= r52; 4'h5: highblock1out <= r53; 4'h6: highblock1out <= r54; 4'h7: highblock1out <= r55; 4'h8: highblock1out <= r56; 4'h9: highblock1out <= r57; 4'hA: highblock1out <= r58; 4'hB: highblock1out <= r59; 4'hC: highblock1out <= r60; 4'hD: highblock1out <= r61; 4'hE: highblock1out <= r62; 4'hF: highblock1out <= r63; endcase end // Write always @(posedge clk) begin if (we & highblock1sel) begin case (location[3:0]) 4'h0: r48 <= highblock1in; 4'h1: r49 <= highblock1in; 4'h2: r50 <= highblock1in; 4'h3: r51 <= highblock1in; 4'h4: r52 <= highblock1in; 4'h5: r53 <= highblock1in; 4'h6: r54 <= highblock1in; 4'h7: r55 <= highblock1in; 4'h8: r56 <= highblock1in; 4'h9: r57 <= highblock1in; 4'hA: r58 <= highblock1in; 4'hB: r59 <= highblock1in; 4'hC: r60 <= highblock1in; 4'hD: r61 <= highblock1in; 4'hE: r62 <= highblock1in; 4'hF: r63 <= highblock1in; endcase end end // **************** Highblock2 **************** reg [7:0] r80, r81, r82, r83, r84, r85, r86, r87; reg [7:0] r88, r89, r90, r91, r92, r93, r94, r95; // Read always @(location or r80 or r81 or r82 or r83 or r84 or r85 or r86 or r87 or r88 or r89 or r90 or r91 or r92 or r93 or r94 or r95 ) begin case (location[3:0]) 4'h0: highblock2out <= r80; 4'h1: highblock2out <= r81; 4'h2: highblock2out <= r82; 4'h3: highblock2out <= r83; 4'h4: highblock2out <= r84; 4'h5: highblock2out <= r85; 4'h6: highblock2out <= r86; 4'h7: highblock2out <= r87; 4'h8: highblock2out <= r88; 4'h9: highblock2out <= r89; 4'hA: highblock2out <= r90; 4'hB: highblock2out <= r91; 4'hC: highblock2out <= r92; 4'hD: highblock2out <= r93; 4'hE: highblock2out <= r94; 4'hF: highblock2out <= r95; endcase end // Write always @(posedge clk) begin if (we & highblock2sel) begin case (location[3:0]) 4'h0: r80 <= highblock2in; 4'h1: r81 <= highblock2in; 4'h2: r82 <= highblock2in; 4'h3: r83 <= highblock2in; 4'h4: r84 <= highblock2in; 4'h5: r85 <= highblock2in; 4'h6: r86 <= highblock2in; 4'h7: r87 <= highblock2in; 4'h8: r88 <= highblock2in; 4'h9: r89 <= highblock2in; 4'hA: r90 <= highblock2in; 4'hB: r91 <= highblock2in; 4'hC: r92 <= highblock2in; 4'hD: r93 <= highblock2in; 4'hE: r94 <= highblock2in; 4'hF: r95 <= highblock2in; endcase end end // **************** Highblock3 **************** // *** The Following Registers are removed because of CUSTOM Hardware (see piccpu.v) ** // // r129 (or 7E) // // ********** reg [7:0] r112, r113, r114, r115, r116, r117, r118, r119; reg [7:0] r120, r121, r122, r123, r124, r125, r126 /*, r127*/ ; // Read always @(location or r112 or r113 or r114 or r115 or r116 or r117 or r118 or r119 or r120 or r121 or r122 or r123 or r124 or r125 or r126 /* or r127 */ ) begin case (location[3:0]) 4'h0: highblock3out <= r112; 4'h1: highblock3out <= r113; 4'h2: highblock3out <= r114; 4'h3: highblock3out <= r115; 4'h4: highblock3out <= r116; 4'h5: highblock3out <= r117; 4'h6: highblock3out <= r118; 4'h7: highblock3out <= r119; 4'h8: highblock3out <= r120; 4'h9: highblock3out <= r121; 4'hA: highblock3out <= r122; 4'hB: highblock3out <= r123; 4'hC: highblock3out <= r124; 4'hD: highblock3out <= r125; 4'hE: highblock3out <= r126; 4'hF: highblock3out <= 8'hff /* r127*/ ; endcase end // Write always @(posedge clk) begin if (we & highblock3sel) begin case (location[3:0]) 4'h0: r112 <= highblock3in; 4'h1: r113 <= highblock3in; 4'h2: r114 <= highblock3in; 4'h3: r115 <= highblock3in; 4'h4: r116 <= highblock3in; 4'h5: r117 <= highblock3in; 4'h6: r118 <= highblock3in; 4'h7: r119 <= highblock3in; 4'h8: r120 <= highblock3in; 4'h9: r121 <= highblock3in; 4'hA: r122 <= highblock3in; 4'hB: r123 <= highblock3in; 4'hC: r124 <= highblock3in; 4'hD: r125 <= highblock3in; 4'hE: r126 <= highblock3in; 4'hF: /* r127 <= highblock3in */; endcase end end // synopsys translate_off `define CLEAR_MEMORY `ifdef CLEAR_MEMORY initial begin $display ("Clearing SRAM."); clear_memory; end task clear_memory; begin // Common registers r8 = 0; r9 = 0; r10 = 0; r11 = 0; r12 = 0; r13 = 0; r14 = 0; r15 = 0; // Bank #0 r16 = 0; r17 = 0; r18 = 0; r19 = 0; r20 = 0; r21 = 0; r22 = 0; r23 = 0; r24 = 0; r25 = 0; r26 = 0; r27 = 0; r28 = 0; r29 = 0; r30 = 0; r31 = 0; // Bank #1 r48 = 0; r49 = 0; r50 = 0; r51 = 0; r52 = 0; r53 = 0; r54 = 0; r55 = 0; r56 = 0; r57 = 0; r58 = 0; r59 = 0; r60 = 0; r61 = 0; r62 = 0; r63 = 0; // Bank #2 r80 = 0; r94 = 0; // Bank #3 r112 = 0; r126 = 0; end endtask `endif // synopsys translate_on endmodule // // SYNTHETIC PIC 2.0 4/23/98 // // This is a synthesizable Microchip 16C57 compatible // microcontroller. This core is not intended as a high fidelity model of // the PIC, but simply a way to offer a simple processor core to people // familiar with the PIC who also have PIC tools. // // pictest.v - top-level testbench (NOT SYNTHESIZABLE) // piccpu.v - top-level synthesizable module // picregs.v - register file instantiated under piccpu // picalu.v - ALU instantiated under piccpu // picidec.v - Instruction Decoder instantiated under piccpu // hex2rom.c - C program used to translate MPLAB's INTEL HEX output // into the Verilog $readmemh compatible file // test*.asm - (note the wildcard..) Several test programs used // to help debug the verilog. I used MPLAB and the simulator // to develop these programs and get the expected results. // Then, I ran them on Verilog-XL where they appeared to // match. // // Copyright, Tom Coonan, '97. // Use freely, but not for resale as is. You may use this in your // own projects as desired. Just don't try to sell it as is! // // module pictest; // Select which test to run HERE.. parameter TEST_NUMBER = 9; // *** Testing variables // Debug flags. integer dbg_showporta; // Are set in an 'initial' for default values, integer dbg_showportb; // override in specific tests... integer dbg_showportc; // Setting to 1 will cause variable to be displayed. integer dbg_showinst; integer dbg_showrom; integer dbg_showw; integer dbg_showpc; // cycles counter variables integer dbg_showcycles; // Set to 1 to see cycles integer dbg_limitcycles;// Set to one to enable maxcycles check integer dbg_maxcycles; // Limit simulation to some number of cycles. integer cycles; // Cycles counter. // *** Interface to the PICCPU reg clk; reg reset; reg [7:0] porta; wire [7:0] portb; wire [7:0] portc; reg [11:0] rom[0:511]; wire [8:0] romaddr; reg [11:0] romdata; // ROM Interface always @(romaddr) begin romdata = rom[romaddr]; end reg [7:0] last_debugw; reg [8:0] last_debugpc; reg [11:0] last_debuginst; reg [7:0] last_debugstatus; wire [7:0] debugw; wire [8:0] debugpc; wire [11:0] debuginst; wire [7:0] debugstatus; // Instantiate one PICCPU to be tested. piccpu piccpu_inst ( .clk (clk), .reset (reset), .paddr (romaddr), .pdata (romdata), .portain (porta), .portbout (portb), .portcout (portc), .debugw (debugw), .debugpc (debugpc), .debuginst (debuginst), .debugstatus (debugstatus) ); // Reset initial begin // $dumpfile("pic.vcd"); // $dumpvars(0,pictest); reset = 1; #200; reset = 0; end // Drive the clock input initial begin clk = 0; forever begin #50 clk = 1; #50 clk = 0; end end // Debug defaults. Override in individual test tasks. // initial begin dbg_showporta = 0; dbg_showportb = 0; dbg_showportc = 0; dbg_showinst = 0; dbg_showrom = 0; dbg_showw = 0; dbg_showpc = 0; dbg_showcycles = 0; dbg_limitcycles = 1; dbg_maxcycles = 50000; end // Call the appropriate test task based on the TEST_NUMBER parameter set at top. // initial begin case (TEST_NUMBER) 1: test1; 2: test2; 3: test3; 4: test4; 5: test5; 6: test6; 7: test7; 8: test8; 9: test9; default: begin $display ("ERROR: Unknown Test Number: %0d", TEST_NUMBER); $finish; end endcase end task test1; begin $display ("SYNTHETIC PIC 2.0. This is TEST #1"); #1; // Only Watch Port B dbg_showportb = 1; dbg_showcycles = 1; $readmemh ("TEST1.ROM",rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test2; begin $display ("SYNTHETIC PIC 2.0. This is TEST #2"); #1; // Only Watch Port B dbg_showportb = 1; $readmemh ("TEST2.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test3; begin $display ("SYNTHETIC PIC 2.0. This is TEST #3"); #1; // Only Watch Port B dbg_showportb = 1; $readmemh ("TEST3.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test4; begin $display ("SYNTHETIC PIC 2.0. This is TEST #4"); #1; // Only Watch Port B dbg_showportb = 1; $readmemh ("TEST4.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test5; begin $display ("SYNTHETIC PIC 2.0. This is TEST #5"); #1; // Only Watch Port B dbg_showportb = 1; $readmemh ("TEST5.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test6; begin $display ("SYNTHETIC PIC 2.0. This is TEST #6"); #1; // Watch Port B and C dbg_showportb = 1; dbg_showportc = 1; dbg_limitcycles = 0; $readmemh ("TEST6.ROM", rom); #200; repeat (20) begin porta = $random; #10000; end $finish; end endtask task test7; begin $display ("SYNTHETIC PIC 2.0. This is TEST #7"); #1; // Only Watch Port B dbg_showportb = 1; $readmemh ("TEST7.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test8; begin $display ("SYNTHETIC PIC 2.0. This is TEST #8"); #1; // Watch All ports dbg_showporta = 1; dbg_showportb = 1; dbg_showportc = 1; $readmemh ("TEST8.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 500; end endtask task test9; begin $display ("SYNTHETIC PIC 2.0. This is TEST #9"); #1; // Watch All ports dbg_showportb = 1; dbg_showportc = 1; $readmemh ("contrib/TEST9.ROM", rom); dbg_limitcycles = 1; dbg_maxcycles = 2000; end endtask // ******** END Of TEST TASKS // Cycles counter // initial begin cycles = 0; #1; // Don't start counting until after reset. @(negedge reset); forever begin @(posedge clk); cycles = cycles + 1; if ((cycles % 256) == 0) begin if (dbg_showcycles) begin $display ("#Cycles = %0d", cycles); end end if (dbg_limitcycles) begin if (cycles > dbg_maxcycles) begin $display ("Maximum cycles (%0d) Exceeded. Halting simulation.", dbg_maxcycles); $finish(0); end end end end always @(romaddr) begin if (dbg_showrom) $display ("ROM Address = %h, Data = %h", romaddr, romdata); end always @(porta) begin if (dbg_showporta) $display ("%d: porta changes to: %h", $time, porta); end always @(portb) begin if (dbg_showportb) $display ("%d: portb changes to: %h", $time, portb); end always @(portc) begin if (dbg_showportc) $display ("%d: portc changes to: %h", $time, portc); end initial begin if (dbg_showw) begin forever begin @(negedge clk); if (debugw != last_debugw) begin $display ("W = %0h", debugw); end last_debugw = debugw; end end end initial begin if (dbg_showpc) begin forever begin @(negedge clk); $display ("PC = %0h", debugpc); end end end reg [11:0] last_pc; always @(posedge clk) begin last_pc = debugpc; end initial begin if (dbg_showinst) begin forever begin @(negedge clk); if (debuginst[11:0] == 12'b0000_0000_0000) begin $display ("%h NOP", last_pc); end else if (debuginst[11:5] == 7'b0000_001) begin $display ("%h MOVWF f=0x%0h", last_pc, debuginst[4:0]); end else if (debuginst == 12'b0000_0100_0000) begin $display ("%h CLRW", last_pc); end else if (debuginst[11:5] == 7'b0000_011) begin $display ("%h CLRF f=0x%0h", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0000_10) begin if (piccpu_inst.d == 0) $display ("%h SUBWF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h SUBWF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0000_11) begin if (piccpu_inst.d == 0) $display ("%h DECF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h DECF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0001_00) begin if (piccpu_inst.d == 0) $display ("%h IORWF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h IORWF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0001_01) begin if (piccpu_inst.d == 0) $display ("%h ANDWF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h ANDWF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0001_10) begin if (piccpu_inst.d == 0) $display ("XORWF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h XORWF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0001_11) begin if (piccpu_inst.d == 0) $display ("%h ADDWF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h ADDWF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0010_00) begin if (piccpu_inst.d == 0) $display ("%h MOVF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h MOVF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0010_01) begin if (piccpu_inst.d == 0) $display ("%h COMF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h COMF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0010_10) begin if (piccpu_inst.d == 0) $display ("%h INCF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h INCF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0010_11) begin if (piccpu_inst.d == 0) $display ("%h DECFSZ f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h DECFSZ f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0011_00) begin if (piccpu_inst.d == 0) $display ("%h RRF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h RRF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0011_01) begin if (piccpu_inst.d == 0) $display ("%h RLF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h RLF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0011_10) begin if (piccpu_inst.d == 0) $display ("%h SWAPF f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h SWAPF f=0x%0h, f", last_pc, debuginst[4:0]); end else if (debuginst[11:6] == 7'b0011_11) begin if (piccpu_inst.d == 0) $display ("%h INCFSZ f=0x%0h, W", last_pc, debuginst[4:0]); else $display ("%h INCFSZ f=0x%0h, f", last_pc, debuginst[4:0]); end // Bit-Oriented File Register Operations else if (debuginst[11:8] == 4'b0100) begin $display ("%h BCF f=0x%0h, bit=%0d", last_pc, debuginst[4:0], piccpu_inst.b); end else if (debuginst[11:8] == 4'b0101) begin $display ("%h BCF f=0x%0h, bit=%0d", last_pc, debuginst[4:0], piccpu_inst.b); end else if (debuginst[11:8] == 4'b0110) begin if (piccpu_inst.skip) $display ("%h BTFSC f=0x%0h, bit=%0d {Will Skip..}", last_pc, debuginst[4:0], piccpu_inst.b); else $display ("%h BTFSC f=0x%0h, bit=%0d {Will NOT Skip..}", last_pc, debuginst[4:0], piccpu_inst.b); end else if (debuginst[11:8] == 4'b0111) begin if (piccpu_inst.skip) $display ("%h BTFSS f=0x%0h, bit=%0d {Will Skip..}", last_pc, debuginst[4:0], piccpu_inst.b); else $display ("%h BTFSS f=0x%0h, bit=%0d {Will NOT Skip..}", last_pc, debuginst[4:0], piccpu_inst.b); end // Literal and Control Operations else if (debuginst[11:0] == 16'b0000_0000_0010) begin $display ("%h OPTION", last_pc); end else if (debuginst[11:0] == 16'b0000_0000_0011) begin $display ("%h SLEEP", last_pc); end else if (debuginst[11:0] == 16'b0000_0000_0100) begin $display ("%h CLRWDT", last_pc); end else if (debuginst[11:3] == 13'b0000_0000_0) begin $display ("%h TRIS, f=0x%0h", last_pc, debuginst[2:0]); end else if (debuginst[11:8] == 4'b1000) begin $display ("%h RETLW, k=0x%0h", last_pc, debuginst[7:0]); end else if (debuginst[11:8] == 4'b1001) begin $display ("%h CALL, k=0x%0h", last_pc, debuginst[7:0]); end else if (debuginst[11:9] == 3'b101) begin $display ("%h GOTO, k=0x%0h", last_pc, debuginst[8:0]); end else if (debuginst[11:8] == 4'b1100) begin $display ("%h MOVLW, k=0x%0h", last_pc, debuginst[7:0]); end else if (debuginst[11:8] == 4'b1101) begin $display ("%h IORLW, k=0x%0h", last_pc, debuginst[7:0]); end else if (debuginst[11:8] == 4'b1110) begin $display ("%h ANDLW, k=0x%0h", last_pc, debuginst[7:0]); end else if (debuginst[11:8] == 4'b1111) begin $display ("%h XORLW, k=0x%0h", last_pc, debuginst[7:0]); end else begin $display ("Hmmm! instruction not recognized?! %0h", debuginst); end end end end endmodule iverilog-12_0/ivtest/find_valg_all000077500000000000000000000026171435245347300174020ustar00rootroot00000000000000#!/bin/sh echo "VVP valgrind errors." echo "-------------------------" fgrep "ERROR SUMMARY" log/*.log | fgrep -v " 0 errors" || echo "No Errors." tail -n8 log/*.log | fgrep "definitely lost" | fgrep -v " 0 bytes" || \ echo "No \"definitely lost\" memory in vvp." tail -n8 log/*.log | fgrep "indirectly lost" | fgrep -v " 0 bytes" || \ echo "No \"indirectly lost\" memory in vvp." tail -n8 log/*.log | fgrep "possibly lost" | fgrep -v " 0 bytes" || \ echo "No \"possibly lost\" memory in vvp." tail -n8 log/*.log | fgrep "still reachable" | fgrep -v " 0 bytes" || \ echo "No \"still reachable\" memory in vvp." # egrep "^\*\*[0-9]+\*\*" log/*.log || echo "No \"missed deletes\" in vvp." echo "" echo "VPI valgrind errors." echo "-------------------------" fgrep "ERROR SUMMARY" vpi_log/*.log | fgrep -v " 0 errors" || echo "No Errors." tail -n8 vpi_log/*.log | fgrep "definitely lost" | fgrep -v " 0 bytes" || \ echo "No \"definitely lost\" memory in vvp." tail -n8 vpi_log/*.log | fgrep "indirectly lost" | fgrep -v " 0 bytes" || \ echo "No \"indirectly lost\" memory in vvp." tail -n8 vpi_log/*.log | fgrep "possibly lost" | fgrep -v " 0 bytes" || \ echo "No \"possibly lost\" memory in vvp." tail -n8 vpi_log/*.log | fgrep "still reachable" | fgrep -v " 0 bytes" || \ echo "No \"still reachable\" memory in vvp." # egrep "^\*\*[0-9]+\*\*" vpi_log/*.log || echo "No \"missed deletes\" in vvp." iverilog-12_0/ivtest/find_valg_errs000077500000000000000000000022331435245347300175770ustar00rootroot00000000000000#!/bin/sh echo "VVP valgrind errors." echo "-------------------------" fgrep "ERROR SUMMARY" log/*.log | fgrep -v " 0 errors" || echo "No Errors." tail -n8 log/*.log | fgrep "definitely lost" | fgrep -v " 0 bytes" || \ echo "No \"definitely lost\" memory in vvp." tail -n8 log/*.log | fgrep "indirectly lost" | fgrep -v " 0 bytes" || \ echo "No \"indirectly lost\" memory in vvp." tail -n8 log/*.log | fgrep "possibly lost" | fgrep -v " 0 bytes" || \ echo "No \"possibly lost\" memory in vvp." # egrep "^\*\*[0-9]+\*\*" log/*.log || echo "No \"missed deletes\" in vvp." echo "" echo "VPI valgrind errors." echo "-------------------------" fgrep "ERROR SUMMARY" vpi_log/*.log | fgrep -v " 0 errors" || echo "No Errors." tail -n8 vpi_log/*.log | fgrep "definitely lost" | fgrep -v " 0 bytes" || \ echo "No \"definitely lost\" memory in vvp." tail -n8 vpi_log/*.log | fgrep "indirectly lost" | fgrep -v " 0 bytes" || \ echo "No \"indirectly lost\" memory in vvp." tail -n8 vpi_log/*.log | fgrep "possibly lost" | fgrep -v " 0 bytes" || \ echo "No \"possibly lost\" memory in vvp." # egrep "^\*\*[0-9]+\*\*" vpi_log/*.log || echo "No \"missed deletes\" in vvp." iverilog-12_0/ivtest/fpga_tests/000077500000000000000000000000001435245347300170245ustar00rootroot00000000000000iverilog-12_0/ivtest/fpga_tests/.cvsignore000066400000000000000000000000221435245347300210160ustar00rootroot00000000000000fpga_log fpga_tmp iverilog-12_0/ivtest/fpga_tests/bufifab.v000066400000000000000000000001711435245347300206100ustar00rootroot00000000000000module bufifab (output Out0, output Out1, input I, input E); bufif0 (Out0, I, E); bufif1 (Out1, I, E); endmodule iverilog-12_0/ivtest/fpga_tests/bufifab_tb.v000066400000000000000000000012321435245347300212740ustar00rootroot00000000000000module main; reg [2:0] i; wire out0, out1; wire ref0, ref1; bufifab dut(.Out0(out0), .Out1(out1), .I(i[0]), .E(i[1])); bufif0 (ref0, i[0], i[1]); bufif1 (ref1, i[0], i[1]); initial begin i = 0; for (i = 0 ; i[2] == 0 ; i = i+1) begin #1 $display("I=%b, E=%b, Out0=%b, Out1=%b", i[0], i[1], out0, out1); if (out0 !== ref0) begin $display("FAILED -- ref0=%b, out0=%b", ref0, out0); $finish; end if (out1 !== ref1) begin $display("FAILED -- ref1=%b, out1=%b", ref1, out1); $finish; end end // for (i = 0 ; i[2] == 0 ; i = i+1) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/fpga_tests/cell_ld.v000066400000000000000000000003141435245347300206070ustar00rootroot00000000000000`timescale 100 ps / 10 ps (* ivl_synthesis_cell *) module LD (Q, D, G); output Q; reg q_out; input D, G; buf b1 (Q, q_out); always @(D or G) if (G) q_out <= D; endmodule iverilog-12_0/ivtest/fpga_tests/cell_ld_tb.v000077500000000000000000000014201435245347300212760ustar00rootroot00000000000000`timescale 100 ps / 10 ps module main; wire Q; reg D, G; LD u1 (.Q(Q), .D(D), .G(G)); initial begin D = 0; G = 1; #1 if (Q !== 0) begin $display("FAILED -- D=%b, G=%b --> Q=%b", D, G, Q); $finish; end D = 1; #1 if (Q !== 1) begin $display("FAILED -- D=%b, G=%b --> Q=%b", D, G, Q); $finish; end G = 0; #1 if (Q !== 1) begin $display("FAILED -- D=%b, G=%b --> Q=%b", D, G, Q); $finish; end D = 0; #1 if (Q !== 1) begin $display("FAILED -- D=%b, G=%b --> Q=%b", D, G, Q); $finish; end G = 1; #1 if (Q !== 0) begin $display("FAILED -- D=%b, G=%b --> Q=%b", D, G, Q); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/eqne.v000066400000000000000000000006161435245347300201460ustar00rootroot00000000000000module eqne(output wire eq1, output wire ne1, output wire eq2, output wire ne2, output wire eq5, output wire ne5, input wire [7:0] x, input wire [7:0] y); assign eq1 = x[0] == y[0]; assign ne1 = x[0] != y[0]; assign eq2 = x[1:0] == y[1:0]; assign ne2 = x[1:0] != y[1:0]; assign eq5 = x[4:0] == y[4:0]; assign ne5 = x[4:0] != y[4:0]; endmodule // eqne iverilog-12_0/ivtest/fpga_tests/eqne_tb.v000066400000000000000000000020171435245347300206300ustar00rootroot00000000000000module main; wire eq1, eq2, eq5; wire ne1, ne2, ne5; reg [7:0] x, y; eqne dut(.eq1(eq1), .eq2(eq2), .eq5(eq5), .ne1(ne1), .ne2(ne2), .ne5(ne5), .x(x), .y(y)); initial begin for (x = 0 ; x < 'h20 ; x = x+1) for (y = 0 ; y < 'h20 ; y = y+1) begin #1 $display("x=%h, y=%h: ", x, y, "eq1=%b, eq2=%b, eq5=%b, ", eq1, eq2, eq5, "ne1=%b, ne2=%b, ne5=%b", ne1, ne2, ne5); if (eq1 !== (x[0] == y[0])) begin $display("FAILED"); $finish; end if (eq2 !== (x[1:0] == y[1:0])) begin $display("FAILED"); $finish; end if (eq5 !== (x[4:0] == y[4:0])) begin $display("FAILED"); $finish; end if (ne1 !== (x[0] != y[0])) begin $display("FAILED"); $finish; end if (ne2 !== (x[1:0] != y[1:0])) begin $display("FAILED"); $finish; end if (ne5 !== (x[4:0] != y[4:0])) begin $display("FAILED"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/fpga_tests/fpga_reg.list000066400000000000000000000014421435245347300214740ustar00rootroot00000000000000# test testbench arch=? part=? gold_file eqne eqne_tb virtex XC2S15-VQ100 - eqne eqne_tb virtex2 XC2V40 - ge2 ge2_tb virtex XC2S15-VQ100 ge2.gold ge2 ge2_tb virtex2 XC2V40 ge2.gold ge8 ge8_tb virtex XC2S15-VQ100 - ge8 ge8_tb virtex2 XC2V40 - onehot16 onehot16_tb virtex XC2S15-VQ100 - onehot16 onehot16_tb virtex2 XC2V40 - sub8 sub8_tb virtex XC2S15-VQ100 - sub8 sub8_tb virtex2 XC2V40 - sqrt sqrt_tb virtex XC2S15-VQ100 - sqrt sqrt_tb virtex2 XC2V40-CS144 - timer timer_tb virtex XC2S15 - timer timer_tb virtex2 XC2V40 - cell_ld cell_ld_tb virtex2 XC2V40 - ornor4 ornor4_tb virtex XC2S15-VQ100 - ornor7 ornor7_tb virtex XC2S15-VQ100 - ornor8 ornor8_tb virtex XC2S15-VQ100 - bufifab bufifab_tb virtex XC2S15-VQ100 - iverilog-12_0/ivtest/fpga_tests/fpga_reg.sh000077500000000000000000000075141435245347300211440ustar00rootroot00000000000000#!/bin/sh # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., # 59 Temple Place - Suite 330 # Boston, MA 02111-1307, USA # #ident "$Id: fpga_reg.sh,v 1.5 2004/01/13 03:37:04 stevewilliams Exp $" # This script runs the synthesis tests listed in the fpga_reg.list # list file. The script uses Icarus Verilog from the path, and also # gets ngdbuild and ngd2ver from the path. The XILINX variable needs # to point to the XILINX install directory so that the simprims # can be found. The run test uses these to generate a simulation # from the synthesized file. # # Usage: sh ./fpga_reg.sh [select] # # If there is no select, then run all the tests. If there is a select, # then only run the tests that match the select regular expression. # # This is a diff command for comparing log with gold files. diff="diff --strip-trailing-cr -aq" # This is the output file. status_file=fpga_reg.txt true > $status_file if ! test -d fpga_log then mkdir fpga_log fi if ! test -d fpga_tmp then mkdir fpga_tmp fi if test "X$1" = "X"; then match='.*' else match="$1" fi cat fpga_reg.list | sed -e 's/#.*//' | while read test tb arch part gold junk do if test "X$test" = "X" -o 0 = `expr X$test : X$match` then : skip a comment else if test "X$part" != "X-" then part="-ppart=$part" else part= fi true > fpga_log/$test-$arch.log 2>&1 EDIF="$test-$arch.edf" synth="iverilog -ofpga_tmp/$EDIF -tfpga -parch=$arch $part $test.v" echo "synth=$synth" eval "$synth" > fpga_log/$test-$arch-synth.log 2>&1 if test $? != 0 then echo "$test-$arch: FAILED -- Synthesis error" >> $status_file continue fi ngdbuild="ngdbuild $EDIF $test.ngd" echo "ngdbuild=$ngdbuild" (eval "cd fpga_tmp; $ngdbuild") > fpga_log/$test-$arch-build.log 2>&1 if test $? != 0 then echo "$test-$arch: FAILED -- ngdbuild error" >> $status_file continue fi ngd2ver="ngd2ver -w $test.ngd $test.edf.v" echo "ngd2ver=$ngd2ver" (eval "cd fpga_tmp; $ngd2ver") > fpga_log/$test-$arch-ngd2ver.log 2>&1 if test $? != 0 then echo "$test-$arch: FAILED -- ngd2ver error" >> $status_file continue fi iverilog -oa.out -Ttyp $tb.v fpga_tmp/$test.edf.v $XILINX/verilog/src/glbl.v -y $XILINX/verilog/src/simprims if test $? != 0 then echo "$test-$arch: FAILED -- compiling test bench" >> $status_file continue fi vvp a.out > fpga_log/$test-$arch.log 2>&1 if test "X$gold" != "X-" ; then if $diff $gold fpga_log/$test-$arch.log > /dev/null then echo "$test-$arch: PASSED -- Correct output." >> $status_file else echo "$test-$arch: FAILED -- Incorrect output." >> $status_file fi else if grep -a -q PASSED fpga_log/$test-$arch.log then echo "$test-$arch: PASSED" >> $status_file else echo "$test-$arch: FAILED" >> $status_file fi fi rm a.out fi done PASSED=`grep ': PASSED' $status_file | wc -l` FAILED=`grep ': FAILED' $status_file | wc -l` echo "PASSED=$PASSED, FAILED=$FAILED" >> $status_file # $Log: fpga_reg.sh,v $ # Revision 1.5 2004/01/13 03:37:04 stevewilliams # Cope with dos line-ends while comparing gold files. # # Revision 1.4 2003/04/01 05:58:36 stevewilliams # Add a select argument. # iverilog-12_0/ivtest/fpga_tests/ge2.gold000066400000000000000000000003201435245347300203430ustar00rootroot0000000000000000 >= 00: 1 00 >= 01: 0 00 >= 10: 0 00 >= 11: 0 01 >= 00: 1 01 >= 01: 1 01 >= 10: 0 01 >= 11: 0 10 >= 00: 1 10 >= 01: 1 10 >= 10: 1 10 >= 11: 0 11 >= 00: 1 11 >= 01: 1 11 >= 10: 1 11 >= 11: 1 iverilog-12_0/ivtest/fpga_tests/ge2.v000066400000000000000000000001601435245347300176650ustar00rootroot00000000000000module ge2(output wire out, input wire [1:0] A, input wire [1:0] B); assign out = A >= B; endmodule // ge2 iverilog-12_0/ivtest/fpga_tests/ge2_tb.v000066400000000000000000000022041435245347300203530ustar00rootroot00000000000000module main; wire out; reg [1:0] A, B; ge2 dut(.out(out), .A(A), .B(B)); initial begin A = 0; B = 0; #1 $display("%b >= %b: %b", A, B, out); B = 1; #1 $display("%b >= %b: %b", A, B, out); B = 2; #1 $display("%b >= %b: %b", A, B, out); B = 3; #1 $display("%b >= %b: %b", A, B, out); A = 1; B = 0; #1 $display("%b >= %b: %b", A, B, out); B = 1; #1 $display("%b >= %b: %b", A, B, out); B = 2; #1 $display("%b >= %b: %b", A, B, out); B = 3; #1 $display("%b >= %b: %b", A, B, out); A = 2; B = 0; #1 $display("%b >= %b: %b", A, B, out); B = 1; #1 $display("%b >= %b: %b", A, B, out); B = 2; #1 $display("%b >= %b: %b", A, B, out); B = 3; #1 $display("%b >= %b: %b", A, B, out); A = 3; B = 0; #1 $display("%b >= %b: %b", A, B, out); B = 1; #1 $display("%b >= %b: %b", A, B, out); B = 2; #1 $display("%b >= %b: %b", A, B, out); B = 3; #1 $display("%b >= %b: %b", A, B, out); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/ge8.v000066400000000000000000000001511435245347300176730ustar00rootroot00000000000000module ge8(output wire out, input wire [7:0] A, input wire [7:0] B); assign out = A >= B; endmodule iverilog-12_0/ivtest/fpga_tests/ge8_tb.v000066400000000000000000000020711435245347300203630ustar00rootroot00000000000000/* * Exhaustive check of all the compare results. */ module main; wire out; reg [7:0] A, B; ge8 dut(.out(out), .A(A), .B(B)); reg error = 0; integer adx, bdx; initial begin A = 0; B = 0; #1 $display("%b >= %b: %b", A, B, out); for (adx = 0 ; adx < 256 ; adx = adx + 1) begin A = adx; for (bdx = 0 ; bdx < 256 ; bdx = bdx + 1) begin B = bdx; #1 $write("%b >= %b: %b", A, B, out); if (out === 1) begin if (A < B) begin $display(" ERROR"); error = 1; end else begin $display(" OK"); end end else if (out === 0) begin if (A < B) begin $display(" OK"); end else begin $display(" ERROR"); error = 1; end end else begin $display(" ERROR"); error = 1; end // else: !if(out === 0) end // for (bdx = 0 ; bdx < 256 ; bdx += 1) end // for (adx = 0 ; adx < 256 ; adx = adx + 1) if (error == 0) $display("PASSED"); else $display("FAILED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/onehot16.v000066400000000000000000000001411435245347300206520ustar00rootroot00000000000000module onehot16(output wire [15:0] out, input wire [3:0] A); assign out = 1 << A; endmodule iverilog-12_0/ivtest/fpga_tests/onehot16_tb.v000066400000000000000000000027741435245347300213550ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: onehot16_tb.v,v 1.1 2003/03/31 01:35:05 stevewilliams Exp $ */ /* * Exhaustive check of all the subtract results. */ module main; wire [15:0] out; reg [3:0] A; onehot16 dut(.out(out), .A(A)); reg error = 0; integer adx; initial begin A = 0; for (adx = 0 ; adx < 16 ; adx = adx + 1) begin A = adx; #1 $write("onehot(%b): %b", A, out); if (out !== (1 << adx)) begin $display(" ERROR"); error = 1; end else begin $display(" OK"); end end // for (adx = 0 ; adx < 256 ; adx = adx + 1) if (error == 0) $display("PASSED"); else $display("FAILED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/ornor4.v000066400000000000000000000002721435245347300204370ustar00rootroot00000000000000module ornor4(output wire O_OR, output wire O_NOR, input wire I0, I1, I2, I3); assign O_OR = | {I0, I1, I2, I3}; assign O_NOR = ~| {I0, I1, I2, I3}; endmodule // ornor4 iverilog-12_0/ivtest/fpga_tests/ornor4_tb.v000066400000000000000000000010601435245347300211200ustar00rootroot00000000000000module main; reg [4:0] val; ornor4 dut (.O_OR(o_or), .O_NOR(o_nor), .I0(val[0]), .I1(val[1]), .I2(val[2]), .I3(val[3])); initial begin for (val = 0 ; val[4] == 0 ; val = val+1) begin #1 if (o_or !== |val[3:0]) begin $display("FAILED -- |%b --> %b", val[3:0], o_or); $finish; end if (o_nor !== ~|val[3:0]) begin $display("FAILED -- ~|%b --> %b", val[3:0], o_nor); $finish; end end // for (val = 0 ; val[4] == 0 ; val = val+1) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/ornor7.v000066400000000000000000000003241435245347300204400ustar00rootroot00000000000000module ornor7(output wire O_OR, output wire O_NOR, input wire I0, I1, I2, I3, I4, I5, I6); assign O_OR = | {I0, I1, I2, I3, I4, I5, I6}; assign O_NOR = ~| {I0, I1, I2, I3, I4, I5, I6}; endmodule iverilog-12_0/ivtest/fpga_tests/ornor7_tb.v000077500000000000000000000010601435245347300211260ustar00rootroot00000000000000module main; reg [7:0] val; ornor7 dut (.O_OR(o_or), .O_NOR(o_nor), .I0(val[0]), .I1(val[1]), .I2(val[2]), .I3(val[3]), .I4(val[4]), .I5(val[5]), .I6(val[6])); initial begin for (val = 0 ; val[7] == 0 ; val = val+1) begin #1 if (o_or !== |val[6:0]) begin $display("FAILED -- |%b --> %b", val[6:0], o_or); $finish; end if (o_nor !== ~|val[6:0]) begin $display("FAILED -- ~|%b --> %b", val[6:0], o_nor); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/ornor8.v000066400000000000000000000003401435245347300204370ustar00rootroot00000000000000module ornor8(output wire O_OR, output wire O_NOR, input wire I0, I1, I2, I3, I4, I5, I6, I7); assign O_OR = | {I0, I1, I2, I3, I4, I5, I6, I7}; assign O_NOR = ~| {I0, I1, I2, I3, I4, I5, I6, I7}; endmodule iverilog-12_0/ivtest/fpga_tests/ornor8_tb.v000066400000000000000000000010751435245347300211320ustar00rootroot00000000000000module main; reg [8:0] val; ornor8 dut (.O_OR(o_or), .O_NOR(o_nor), .I0(val[0]), .I1(val[1]), .I2(val[2]), .I3(val[3]), .I4(val[4]), .I5(val[5]), .I6(val[6]), .I7(val[7])); initial begin for (val = 0 ; val[8] == 0 ; val = val+1) begin #1 if (o_or !== |val[7:0]) begin $display("FAILED -- |%b --> %b", val[7:0], o_or); $finish; end if (o_nor !== ~|val[7:0]) begin $display("FAILED -- ~|%b --> %b", val[7:0], o_nor); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/sqrt.v000066400000000000000000000100511435245347300202010ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: sqrt.v,v 1.1 2003/03/30 03:54:48 stevewilliams Exp $" */ /* * This module approximates the square root of an unsigned 32bit * number. The algorithm works by doing a bit-wise binary search. * Starting from the most significant bit, the accumulated value * tries to put a 1 in the bit position. If that makes the square * too big for the input, the bit is left zero, otherwise it is set * in the result. This continues for each bit, decreasing in * significance, until all the bits are calculated or all the * remaining bits are zero. * * Since the result is an integer, this function really calculates * value of the expression: * * x = floor(sqrt(y)) * * where sqrt(y) is the exact square root of y and floor(N) is the * largest integer <= N. * * For 32bit numbers, this will never run more then 16 iterations, * which amounts to 16 clocks. */ module sqrt32(clk, rdy, reset, x, .y(acc)); input clk; output rdy; input reset; input [31:0] x; output [15:0] acc; // acc holds the accumulated result, and acc2 is the accumulated // square of the accumulated result. reg [15:0] acc; reg [31:0] acc2; // Keep track of which bit I'm working on. reg [4:0] bitl; wire [15:0] bit = 1 << bitl; wire [31:0] bit2 = 1 << (bitl << 1); // The output is ready when the bitl counter underflows. wire rdy = bitl[4]; // guess holds the potential next values for acc, and guess2 holds // the square of that guess. The guess2 calculation is a little bit // subtle. The idea is that: // // guess2 = (acc + bit) * (acc + bit) // = (acc * acc) + 2*acc*bit + bit*bit // = acc2 + 2*acc*bit + bit2 // = acc2 + 2 * (acc< ((y + 1)*(y + 1))) begin $display("ERROR: y is too small"); $finish; end end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/fpga_tests/sub8.v000066400000000000000000000001571435245347300200770ustar00rootroot00000000000000module sub8(output wire [7:0] out, input wire [7:0] A, input wire [7:0] B); assign out = A - B; endmodule iverilog-12_0/ivtest/fpga_tests/sub8_tb.v000066400000000000000000000014041435245347300205600ustar00rootroot00000000000000/* * Exhaustive check of all the subtract results. */ module main; wire [7:0] out; reg [7:0] A, B; sub8 dut(.out(out), .A(A), .B(B)); reg error = 0; integer adx, bdx; initial begin A = 0; B = 0; for (adx = 0 ; adx < 256 ; adx = adx + 1) begin A = adx; for (bdx = 0 ; bdx < 256 ; bdx = bdx + 1) begin B = bdx; #1 $write("%b - %b: %b", A, B, out); if (out !== (A - B)) begin $display(" ERROR"); error = 1; end else begin $display(" OK"); end end // for (bdx = 0 ; bdx < 256 ; bdx += 1) end // for (adx = 0 ; adx < 256 ; adx = adx + 1) if (error == 0) $display("PASSED"); else $display("FAILED"); end // initial begin endmodule // main iverilog-12_0/ivtest/fpga_tests/timer.v000066400000000000000000000022131435245347300203310ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: timer.v,v 1.1 2003/04/01 05:55:24 stevewilliams Exp $ */ module timer(output wire rdy, input wire clk, input wire reset); reg [4:0] count; assign rdy = count[4]; always @(posedge clk or posedge reset) if (reset) count <= 5'h0f; else count <= count - 1; endmodule // timer iverilog-12_0/ivtest/fpga_tests/timer_tb.v000066400000000000000000000030161435245347300210200ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: timer_tb.v,v 1.1 2003/04/01 05:55:24 stevewilliams Exp $ */ `timescale 1us / 1us module main; wire rdy; reg reset, clk; timer dut(.rdy(rdy), .clk(clk), .reset(reset)); always begin #5 clk = 1; #5 clk = 0; end initial begin $dumpvars(0, main); #7 reset = 1; #1 if (rdy !== 0) begin $display("FAILED: reset did not clear rdy. rdy=%b", rdy); $finish; end #6 reset = 0; end always @(posedge clk) if (rdy === 1) begin $display("rdy=%b at time=%0d", rdy, $time); if ($time != 175) begin $display("FAILED: timer ran out incorrectly."); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/gold/000077500000000000000000000000001435245347300156125ustar00rootroot00000000000000iverilog-12_0/ivtest/gold/always_comb_no_sens.gold000066400000000000000000000001361435245347300225050ustar00rootroot00000000000000./ivltests/always_comb_no_sens.v:5: warning: always_comb process has no sensitivities. PASSED iverilog-12_0/ivtest/gold/always_comb_warn.gold000066400000000000000000000126701435245347300220160ustar00rootroot00000000000000./ivltests/always_comb_warn.v:20: warning: An event (int2) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:20: warning: An event (int1) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:21: warning: A non-integral variable (intrl) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:22: warning: A non-blocking assignment should not be used in an always_comb process. ./ivltests/always_comb_warn.v:23: warning: An event trigger statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:24: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:25: warning: A non-blocking assignment should not be used in an always_comb process. ./ivltests/always_comb_warn.v:25: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:26: warning: Assinging to a non-integral variable (ar) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:27: warning: A for statement must have a constant initial value to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:27: warning: A for statement must compare against a constant value to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:27: warning: A for statement must have a constant step value to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:27: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:28: warning: A for statement must use the index (idx) in the condition expression to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:28: warning: A for statement must use the index (idx) in the step expression to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:28: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:29: warning: A for statement step must be an assignment to the index variable (idx) to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:29: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:30: warning: A for statement step must be a simple assignment statement to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:30: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:31: warning: A for statement step does not support operator 'l' it must be +/- to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:31: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:32: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:33: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:35: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:12: warning: user task (a_task) must be automatic to be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:16: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:37: warning: A procedural assign statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:38: warning: A procedural deassign statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:39: warning: A do/while statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:39: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:41: warning: A force statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:42: warning: A release statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:43: warning: A while statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:44: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:47: warning: A repeat statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:47: warning: System task ($display) cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:48: warning: A disable statement can only be synthesized when disabling an enclosing block in an always_comb process. ./ivltests/always_comb_warn.v:49: warning: A forever statement cannot be synthesized in an always_comb process. ./ivltests/always_comb_warn.v:50: warning: System task ($display) cannot be synthesized in an always_comb process. For: 0 array size: 2 array size: 0 user task do/while while repeat repeat forever Expect compile warnings! PASSED iverilog-12_0/ivtest/gold/always_ff_warn.gold000066400000000000000000000120521435245347300214630ustar00rootroot00000000000000./ivltests/always_ff_warn.v:21: warning: An event (int2) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:21: warning: An event (int1) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:22: warning: A non-integral variable (intrl) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:24: warning: An event trigger statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:25: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:26: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:27: warning: Assinging to a non-integral variable (ar) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:28: warning: A for statement must have a constant initial value to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:28: warning: A for statement must compare against a constant value to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:28: warning: A for statement must have a constant step value to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:28: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:29: warning: A for statement must use the index (idx) in the condition expression to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:29: warning: A for statement must use the index (idx) in the step expression to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:29: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:30: warning: A for statement step must be an assignment to the index variable (idx) to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:30: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:31: warning: A for statement step must be a simple assignment statement to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:31: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:32: warning: A for statement step does not support operator 'l' it must be +/- to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:32: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:33: warning: A for statement step must be a simple binary +/- to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:33: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:34: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:35: warning: Dynamic array delete method cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:36: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:15: warning: An event (tevt) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:14: warning: A non-integral variable (trl) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:13: warning: user task (a_task) must be automatic to be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:17: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:38: warning: A procedural assign statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:39: warning: A procedural deassign statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:40: warning: A do/while statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:40: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:42: warning: A force statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:43: warning: A release statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:44: warning: A while statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:45: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:48: warning: A repeat statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:48: warning: System task ($display) cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:49: warning: A disable statement can only be synthesized when disabling an enclosing block in an always_ff process. ./ivltests/always_ff_warn.v:50: warning: A forever statement cannot be synthesized in an always_ff process. ./ivltests/always_ff_warn.v:51: warning: System task ($display) cannot be synthesized in an always_ff process. For: 0 array size: 2 array size: 0 user task do/while while repeat repeat forever Expect compile warnings! PASSED iverilog-12_0/ivtest/gold/always_ff_warn_sens.gold000066400000000000000000000022211435245347300225100ustar00rootroot00000000000000./ivltests/always_ff_warn_sens.v:53 warning: Synthesis wants the sensitivity list expressions for 'posedge rst' to be a single bit. ./ivltests/always_ff_warn_sens.v:45 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. &rst is missing a pos/negedge. ./ivltests/always_ff_warn_sens.v:37 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. ~rst[] is missing a pos/negedge. ./ivltests/always_ff_warn_sens.v:29 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. ~|rst is missing a pos/negedge. ./ivltests/always_ff_warn_sens.v:21 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. rst[] is missing a pos/negedge. ./ivltests/always_ff_warn_sens.v:13 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. rst[] is missing a pos/negedge. ./ivltests/always_ff_warn_sens.v:8 warning: Synthesis requires the sensitivity list of an always_ff process to only be edge sensitive. clk is missing a pos/negedge. Expect compile warnings! PASSED iverilog-12_0/ivtest/gold/always_latch_warn.gold000066400000000000000000000124461435245347300221720ustar00rootroot00000000000000./ivltests/always_latch_warn.v:20: warning: An event (int2) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:20: warning: An event (int1) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:21: warning: A non-integral variable (intrl) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:23: warning: An event trigger statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:24: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:25: warning: Assinging to a non-integral variable (rl) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:26: warning: Assinging to a non-integral variable (ar) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:27: warning: A for statement must have a constant initial value to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:27: warning: A for statement must compare against a constant value to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:27: warning: A for statement must have a constant step value to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:27: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:28: warning: A for statement must use the index (idx) in the condition expression to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:28: warning: A for statement must use the index (idx) in the step expression to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:28: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:29: warning: A for statement step must be an assignment to the index variable (idx) to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:29: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:30: warning: A for statement step must be a simple assignment statement to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:30: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:31: warning: A for statement step does not support operator 'l' it must be +/- to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:31: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:32: warning: A for statement step must be a simple binary +/- to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:32: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:33: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:34: warning: Dynamic array delete method cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:35: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:14: warning: An event (tevt) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:13: warning: A non-integral variable (trl) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:12: warning: user task (a_task) must be automatic to be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:16: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:37: warning: A procedural assign statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:38: warning: A procedural deassign statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:39: warning: A do/while statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:39: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:41: warning: A force statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:42: warning: A release statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:43: warning: A while statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:44: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:47: warning: A repeat statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:47: warning: System task ($display) cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:48: warning: A disable statement can only be synthesized when disabling an enclosing block in an always_latch process. ./ivltests/always_latch_warn.v:49: warning: A forever statement cannot be synthesized in an always_latch process. ./ivltests/always_latch_warn.v:50: warning: System task ($display) cannot be synthesized in an always_latch process. For: 0 array size: 2 array size: 0 user task do/while while repeat repeat forever Expect compile warnings! PASSED iverilog-12_0/ivtest/gold/always_star_array_lval.gold000066400000000000000000000000501435245347300232210ustar00rootroot000000000000000 1 2 3 4 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 iverilog-12_0/ivtest/gold/array_dump.vcd.gold000066400000000000000000000006701435245347300214020ustar00rootroot00000000000000$date Sun May 15 18:09:10 2022 $end $version Icarus Verilog $end $timescale 1s $end $scope module top $end $var reg 8 ! \array[0] [7:0] $end $upscope $end $scope module top $end $var reg 8 " \array[1] [7:0] $end $upscope $end $scope module top $end $var reg 8 # \array[2] [7:0] $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall $end #0 $dumpvars bx # bx " bx ! $end #1 b1010101 # b0 " b11111111 ! iverilog-12_0/ivtest/gold/array_packed_2d.gold000066400000000000000000000002441435245347300214730ustar00rootroot0000000000000002040608 2 4 6 8 2 4 6 8 02040608 2 4 6 8 2 4 6 8 08060402 2 4 6 8 2 4 6 8 08060402 2 4 6 8 2 4 6 8 iverilog-12_0/ivtest/gold/array_word_check.gold000066400000000000000000000003211435245347300217630ustar00rootroot00000000000000VCD info: dumpfile work/dup.vcd opened for output. VCD warning: array word top.array[0] will conflict with an escaped identifier. VCD warning: array word top.array[1] will conflict with an escaped identifier. iverilog-12_0/ivtest/gold/array_word_width.gold000066400000000000000000000000051435245347300220240ustar00rootroot000000000000000003 iverilog-12_0/ivtest/gold/automatic_error11.gold000066400000000000000000000001351435245347300220210ustar00rootroot00000000000000ERROR: ./ivltests/automatic_error11.v:9: $monitor argument "local" is an automatic variable. iverilog-12_0/ivtest/gold/automatic_error12.gold000066400000000000000000000001351435245347300220220ustar00rootroot00000000000000ERROR: ./ivltests/automatic_error12.v:10: $strobe argument "local" is an automatic variable. iverilog-12_0/ivtest/gold/automatic_error13.gold000066400000000000000000000001361435245347300220240ustar00rootroot00000000000000ERROR: ./ivltests/automatic_error13.v:10: $fstrobe argument "local" is an automatic variable. iverilog-12_0/ivtest/gold/automatic_events.gold000066400000000000000000000032701435245347300220350ustar00rootroot00000000000000task 1 triggered: 00000 00001 00001 22 task 2 triggered: 00000 00001 00001 24 task 1 triggered: 00000 00001 00000 32 task 2 triggered: 00000 00001 00000 34 task 1 triggered: 00000 00010 00010 62 task 2 triggered: 00000 00010 00010 64 task 1 triggered: 00000 00010 00000 72 task 2 triggered: 00000 00010 00000 74 task 1 triggered: 00000 00100 00100 102 task 2 triggered: 00000 00100 00100 104 task 1 triggered: 00000 00100 00000 112 task 2 triggered: 00000 00100 00000 114 task 1 triggered: 00000 01000 01000 142 task 2 triggered: 00000 01000 01000 144 task 1 triggered: 00000 01000 00000 152 task 2 triggered: 00000 01000 00000 154 task 1 triggered: 00000 10000 10000 182 task 2 triggered: 00000 10000 10000 184 task 1 triggered: 00000 10000 00000 192 task 2 triggered: 00000 10000 00000 194 task 1 triggered: 00001 00000 00000 211 task 2 triggered: 00001 00000 00000 212 task 1 triggered: 00000 00000 00000 221 task 2 triggered: 00000 00000 00000 222 task 1 triggered: 00010 00000 00000 231 task 2 triggered: 00010 00000 00000 232 task 1 triggered: 00000 00000 00000 241 task 2 triggered: 00000 00000 00000 242 task 1 triggered: 00100 00000 00000 251 task 2 triggered: 00100 00000 00000 252 task 1 triggered: 00000 00000 00000 261 task 2 triggered: 00000 00000 00000 262 task 1 triggered: 01000 00000 00000 271 task 2 triggered: 01000 00000 00000 272 task 1 triggered: 00000 00000 00000 281 task 2 triggered: 00000 00000 00000 282 task 1 triggered: 10000 00000 00000 291 task 2 triggered: 10000 00000 00000 292 task 1 triggered: 00000 00000 00000 301 task 2 triggered: 00000 00000 00000 302 iverilog-12_0/ivtest/gold/automatic_events3.gold000066400000000000000000000020101435245347300221070ustar00rootroot00000000000000Time 20 : Source[0] rise Time 20 : Source[0] edge Time 25 : Source[1] rise Time 25 : Source[1] edge Time 35 : Source[1] rise Time 35 : Source[1] edge Time 40 : Source[0] fall Time 40 : Source[0] edge Time 45 : Source[1] fall Time 45 : Source[1] edge Time 55 : Source[1] fall Time 55 : Source[1] edge Time 60 : Source[0] rise Time 60 : Source[0] edge Time 65 : Source[1] rise Time 65 : Source[1] edge Time 75 : Source[1] rise Time 75 : Source[1] edge Time 80 : Source[0] fall Time 80 : Source[0] edge Time 85 : Source[1] fall Time 85 : Source[1] edge Time 95 : Source[1] fall Time 95 : Source[1] edge iverilog-12_0/ivtest/gold/automatic_task.gold000066400000000000000000000001501435245347300214650ustar00rootroot00000000000000 1 x x x 2 x x x 1 1 x x 2 2 x x 1 1 1 x 2 2 2 x 1 1 1 1 2 2 2 2 iverilog-12_0/ivtest/gold/automatic_task2.gold000066400000000000000000000001501435245347300215470ustar00rootroot00000000000000 1 x x x 2 x x x 1 1 x x 2 2 x x 1 1 1 x 2 2 2 x 1 1 1 1 2 2 2 2 iverilog-12_0/ivtest/gold/automatic_task3.gold000066400000000000000000000003201435245347300215470ustar00rootroot00000000000000 1 x x x 1 x x x 2 x x x 2 x x x 2 1 x x 2 1 x x 2 2 x x 2 2 x x 2 2 1 x 2 2 1 x 2 2 2 x 2 2 2 x 2 2 2 1 2 2 2 1 2 2 2 2 2 2 2 2 iverilog-12_0/ivtest/gold/bitsel.gold000066400000000000000000000000201435245347300177330ustar00rootroot000000000000001 0 0 1 0 1 1 0 iverilog-12_0/ivtest/gold/br1003a-v10.gold000066400000000000000000000001701435245347300201330ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (testclass) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003a.gold000066400000000000000000000001641435245347300175320ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of ($unit) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003b-v10.gold000066400000000000000000000001641435245347300201370ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (delay) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003b-vlog95.gold000066400000000000000000000002001435245347300206450ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (ivl_package_$unit) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003b.gold000066400000000000000000000001641435245347300175330ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of ($unit) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003c-v10.gold000066400000000000000000000001641435245347300201400ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (delay) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003c-vlog95.gold000066400000000000000000000002001435245347300206460ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (ivl_package_$unit) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003c.gold000066400000000000000000000001641435245347300175340ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of ($unit) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003d-vlog95.gold000066400000000000000000000002061435245347300206550ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (ivl_package_testpackage) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1003d.gold000066400000000000000000000001721435245347300175340ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ps Time scale of (top) is 1ns / 1ps Time scale of (testpackage) is 100ps / 10ps 50 5 PASSED iverilog-12_0/ivtest/gold/br1005.gold000066400000000000000000000001551435245347300173730ustar00rootroot00000000000000./ivltests/br1005.v:2: sorry: SV queues inside classes are not yet supported. 2 error(s) during elaboration. iverilog-12_0/ivtest/gold/br1007-vlog95.gold000066400000000000000000000006421435245347300205210ustar00rootroot00000000000000./ivltests/br1007.v:15: warning: bit select value[5] is out of range. ./ivltests/br1007.v:20: warning: Part select value[5:5] is out of range. ./ivltests/br1007.v:25: warning: Part select value[5:4] is out of range. vlog95.v:17: warning: bit select value[5] is out of range. vlog95.v:20: warning: bit select value[5] is out of range. vlog95.v:23: warning: Part select value[5:4] is out of range. 0000 0000 1000 PASSED iverilog-12_0/ivtest/gold/br1007.gold000066400000000000000000000003561435245347300174000ustar00rootroot00000000000000./ivltests/br1007.v:15: warning: bit select value[5] is out of range. ./ivltests/br1007.v:20: warning: Part select value[5:5] is out of range. ./ivltests/br1007.v:25: warning: Part select value[5:4] is out of range. 0000 0000 1000 PASSED iverilog-12_0/ivtest/gold/br1008.gold000066400000000000000000000000201435245347300173650ustar00rootroot00000000000000b = [zzzz 0000] iverilog-12_0/ivtest/gold/br1027a-fsv.gold000066400000000000000000000000041435245347300203250ustar00rootroot000000000000000 1 iverilog-12_0/ivtest/gold/br1027a.gold000066400000000000000000000002121435245347300175320ustar00rootroot00000000000000./ivltests/br1027a.v:1: error: Missing task/function port direction. ./ivltests/br1027a.v:1: error: Missing task/function port direction. iverilog-12_0/ivtest/gold/br1027b.gold000066400000000000000000000000041435245347300175320ustar00rootroot000000000000000 1 iverilog-12_0/ivtest/gold/br1027c-fsv.gold000066400000000000000000000000301435245347300203260ustar00rootroot00000000000000 0 1 iverilog-12_0/ivtest/gold/br1027c.gold000066400000000000000000000001051435245347300175350ustar00rootroot00000000000000./ivltests/br1027c.v:1: error: Missing task/function port direction. iverilog-12_0/ivtest/gold/br1027d.gold000066400000000000000000000000301435245347300175330ustar00rootroot00000000000000 0 1 iverilog-12_0/ivtest/gold/br1027e-fsv.gold000066400000000000000000000000301435245347300203300ustar00rootroot00000000000000 0 1 iverilog-12_0/ivtest/gold/br1027e.gold000066400000000000000000000001051435245347300175370ustar00rootroot00000000000000./ivltests/br1027e.v:1: error: Missing task/function port direction. iverilog-12_0/ivtest/gold/br1027f.gold000066400000000000000000000000301435245347300175350ustar00rootroot00000000000000 0 1 iverilog-12_0/ivtest/gold/br1029a.gold000066400000000000000000000011251435245347300175400ustar00rootroot00000000000000a: 0.4 0 0 0 b: 0.5 1 1 1 c: 0.6 1 1 1 d: 2.4 2 2 10 e: 2.5 3 3 11 f: 2.6 3 3 11 a: -0.4 -0 0 0 b: -0.5 -1 ffffffffffffffff 1111111111111111111111111111111111111111111111111111111111111111 c: -0.6 -1 ffffffffffffffff 1111111111111111111111111111111111111111111111111111111111111111 d: -2.4 -2 fffffffffffffffe 1111111111111111111111111111111111111111111111111111111111111110 e: -2.5 -3 fffffffffffffffd 1111111111111111111111111111111111111111111111111111111111111101 f: -2.6 -3 fffffffffffffffd 1111111111111111111111111111111111111111111111111111111111111101 iverilog-12_0/ivtest/gold/br1029c.gold000066400000000000000000000001411435245347300175370ustar00rootroot00000000000000./ivltests/br1029c.v:3: error: The argument to $signed must be a vector type. Elaboration failed iverilog-12_0/ivtest/gold/br916a-vlog95.gold000066400000000000000000000004131435245347300206060ustar00rootroot00000000000000SORRY: vlog95.v:15: currently only simple signals or constant expressions may be passed to $strobe. NOTE: You can work around this by assigning the desired expression to an intermediate net (using a continuous assignment) and passing that net to $strobe. iverilog-12_0/ivtest/gold/br916a.gold000066400000000000000000000004251435245347300174660ustar00rootroot00000000000000SORRY: ./ivltests/br916a.v:6: currently only simple signals or constant expressions may be passed to $strobe. NOTE: You can work around this by assigning the desired expression to an intermediate net (using a continuous assignment) and passing that net to $strobe. iverilog-12_0/ivtest/gold/br916b-vlog95.gold000066400000000000000000000004151435245347300206110ustar00rootroot00000000000000SORRY: vlog95.v:13: currently only simple signals or constant expressions may be passed to $monitor. NOTE: You can work around this by assigning the desired expression to an intermediate net (using a continuous assignment) and passing that net to $monitor. iverilog-12_0/ivtest/gold/br916b.gold000066400000000000000000000004271435245347300174710ustar00rootroot00000000000000SORRY: ./ivltests/br916b.v:4: currently only simple signals or constant expressions may be passed to $monitor. NOTE: You can work around this by assigning the desired expression to an intermediate net (using a continuous assignment) and passing that net to $monitor. iverilog-12_0/ivtest/gold/br921.gold000066400000000000000000000001321435245347300173140ustar00rootroot00000000000000./ivltests/br921.v:6: warning: User function 'test_fcn' is being called as a task. PASSED iverilog-12_0/ivtest/gold/br947.gold000066400000000000000000000002301435245347300173230ustar00rootroot00000000000000 0 x x x x 100 1 x x 1 200 1 1 x 1 250 1 1 x x 300 1 1 1 1 PASSED iverilog-12_0/ivtest/gold/br960a.gold000066400000000000000000000002751435245347300174700ustar00rootroot00000000000000Max (X->Z) 0.00 x=0 0 0.30 z=0 0 Fall (Z->0) 10.00 z=0 1 11.30 0=0 1 Rise (0->Z) 20.00 0=0 0 21.20 z=0 0 25.00 z=1 0 Rise (Z->1) 30.00 z=1 1 31.20 1=1 1 Fall (1->Z) 40.00 1=1 0 41.30 z=1 0 iverilog-12_0/ivtest/gold/br960b.gold000066400000000000000000000003071435245347300174650ustar00rootroot00000000000000Max (X->Z) 0.00 x=0 0 0.40 z=0 0 Fall (Z->0) 10.00 z=0 1 11.30 0=0 1 To High-Z (0->Z) 20.00 0=0 0 21.40 z=0 0 25.00 z=1 0 Rise (Z->1) 30.00 z=1 1 31.20 1=1 1 To High-Z (1->Z) 40.00 1=1 0 41.40 z=1 0 iverilog-12_0/ivtest/gold/br960c.gold000066400000000000000000000002411435245347300174630ustar00rootroot00000000000000Max (X->Z) 0.00 x=0 0 0.40 z=0 0 Z->0 10.00 z=0 1 11.50 0=0 1 0->Z 20.00 0=0 0 21.20 z=0 0 25.00 z=1 0 Z->1 30.00 z=1 1 31.30 1=1 1 1->Z 40.00 1=1 0 41.40 z=1 0 iverilog-12_0/ivtest/gold/br960d.gold000066400000000000000000000002751435245347300174730ustar00rootroot00000000000000Max (X->Z) 0.00 x=0 0 0.20 z=0 0 Fall (Z->0) 10.00 z=0 1 11.20 0=0 1 Rise (0->Z) 20.00 0=0 0 21.20 z=0 0 25.00 z=1 0 Rise (Z->1) 30.00 z=1 1 31.20 1=1 1 Fall (1->Z) 40.00 1=1 0 41.20 z=1 0 iverilog-12_0/ivtest/gold/br975-v10.gold000066400000000000000000000005341435245347300177370ustar00rootroot00000000000000./ivltests/br975.v:12: error: duplicate declaration for net or variable 'w1' in 'bug'. ./ivltests/br975.v:15: error: duplicate declaration for net or variable 'd1' in 'bug'. ./ivltests/br975.v:18: error: duplicate declaration for net or variable 'e1' in 'bug'. ./ivltests/br975.v:21: error: duplicate declaration for net or variable 'r1' in 'bug'. iverilog-12_0/ivtest/gold/br975.gold000066400000000000000000000010631435245347300173310ustar00rootroot00000000000000./ivltests/br975.v:12: error: 'w1' has already been declared in this scope. ./ivltests/br975.v:11: : It was declared here as a net. ./ivltests/br975.v:15: error: 'd1' has already been declared in this scope. ./ivltests/br975.v:14: : It was declared here as a variable. ./ivltests/br975.v:18: error: 'e1' has already been declared in this scope. ./ivltests/br975.v:17: : It was declared here as a variable. ./ivltests/br975.v:21: error: 'r1' has already been declared in this scope. ./ivltests/br975.v:20: : It was declared here as a variable. iverilog-12_0/ivtest/gold/br991b.gold000066400000000000000000000013031435245347300174660ustar00rootroot00000000000000./ivltests/br991b.v:23: error: always process does not have any delay. ./ivltests/br991b.v:23: : A runtime infinite loop will occur. ./ivltests/br991b.v:19: error: always process does not have any delay. ./ivltests/br991b.v:19: : A runtime infinite loop will occur. ./ivltests/br991b.v:15: error: always process does not have any delay. ./ivltests/br991b.v:15: : A runtime infinite loop will occur. ./ivltests/br991b.v:11: error: always process does not have any delay. ./ivltests/br991b.v:11: : A runtime infinite loop will occur. ./ivltests/br991b.v:7: error: always process does not have any delay. ./ivltests/br991b.v:7: : A runtime infinite loop will occur. Elaboration failed iverilog-12_0/ivtest/gold/br_gh105a.gold000066400000000000000000000000141435245347300201240ustar00rootroot00000000000000Hello world iverilog-12_0/ivtest/gold/br_gh105b.gold000066400000000000000000000000471435245347300201330ustar00rootroot00000000000000No args Args = hello Args = 123, hello iverilog-12_0/ivtest/gold/br_gh127a.gold000066400000000000000000000006411435245347300201360ustar00rootroot00000000000000./ivltests/br_gh127a.v:21: warning: Port 2 (in) of copy expects 2 bits, got 1. ./ivltests/br_gh127a.v:21: : Padding 1 high bits of the port. ./ivltests/br_gh127a.v:23: warning: Port 2 (in) of copy expects 2 bits, got 3. ./ivltests/br_gh127a.v:23: : Pruning 1 high bits of the expression. 00 : 0 00 : 00 00 : 000 00 01 : 1 01 : 01 01 : 001 01 10 : 0 00 : 10 10 : 010 10 11 : 1 01 : 11 11 : 011 11 PASSED iverilog-12_0/ivtest/gold/br_gh127b.gold000066400000000000000000000006661435245347300201460ustar00rootroot00000000000000./ivltests/br_gh127b.v:21: warning: Port 2 (in) of copy expects 2 bits, got 1. ./ivltests/br_gh127b.v:21: : Leaving 1 high bits of the port unconnected. ./ivltests/br_gh127b.v:23: warning: Port 2 (in) of copy expects 2 bits, got 3. ./ivltests/br_gh127b.v:23: : Leaving 1 high bits of the expression dangling. 00 : 0 z0 : 00 00 : 000 00 01 : 1 z1 : 01 01 : 001 01 10 : 0 z0 : 10 10 : 010 10 11 : 1 z1 : 11 11 : 011 11 PASSED iverilog-12_0/ivtest/gold/br_gh127c.gold000066400000000000000000000015461435245347300201450ustar00rootroot00000000000000./ivltests/br_gh127c.v:21: warning: input port out is coerced to inout. ./ivltests/br_gh127c.v:21: warning: output port in is coerced to inout. ./ivltests/br_gh127c.v:21: warning: Port 2 (in) of copy expects 2 bits, got 1. ./ivltests/br_gh127c.v:21: : Leaving 1 high bits of the port unconnected. ./ivltests/br_gh127c.v:22: warning: input port out is coerced to inout. ./ivltests/br_gh127c.v:22: warning: output port in is coerced to inout. ./ivltests/br_gh127c.v:23: warning: input port out is coerced to inout. ./ivltests/br_gh127c.v:23: warning: output port in is coerced to inout. ./ivltests/br_gh127c.v:23: warning: Port 2 (in) of copy expects 2 bits, got 3. ./ivltests/br_gh127c.v:23: : Leaving 1 high bits of the expression dangling. 00 : 0 z0 : 00 00 : 000 00 01 : 1 z1 : 01 01 : 001 01 10 : 0 z0 : 10 10 : 010 10 11 : 1 z1 : 11 11 : 011 11 PASSED iverilog-12_0/ivtest/gold/br_gh127d.gold000066400000000000000000000006431435245347300201430ustar00rootroot00000000000000./ivltests/br_gh127d.v:21: warning: Port 1 (out) of copy expects 2 bits, got 1. ./ivltests/br_gh127d.v:21: : Padding 1 high bits of the port. ./ivltests/br_gh127d.v:23: warning: Port 1 (out) of copy expects 2 bits, got 3. ./ivltests/br_gh127d.v:23: : Padding 1 high bits of the expression. 00 : 00 0 : 00 00 : 00 000 01 : 01 1 : 01 01 : 01 001 10 : 10 0 : 10 10 : 10 010 11 : 11 1 : 11 11 : 11 011 PASSED iverilog-12_0/ivtest/gold/br_gh127e.gold000066400000000000000000000006701435245347300201440ustar00rootroot00000000000000./ivltests/br_gh127e.v:21: warning: Port 1 (out) of copy expects 2 bits, got 1. ./ivltests/br_gh127e.v:21: : Leaving 1 high bits of the port unconnected. ./ivltests/br_gh127e.v:23: warning: Port 1 (out) of copy expects 2 bits, got 3. ./ivltests/br_gh127e.v:23: : Leaving 1 high bits of the expression dangling. 00 : 00 0 : 00 00 : 00 z00 01 : 01 1 : 01 01 : 01 z01 10 : 10 0 : 10 10 : 10 z10 11 : 11 1 : 11 11 : 11 z11 PASSED iverilog-12_0/ivtest/gold/br_gh127f.gold000066400000000000000000000015501435245347300201430ustar00rootroot00000000000000./ivltests/br_gh127f.v:21: warning: input port out is coerced to inout. ./ivltests/br_gh127f.v:21: warning: Port 1 (out) of copy expects 2 bits, got 1. ./ivltests/br_gh127f.v:21: : Leaving 1 high bits of the port unconnected. ./ivltests/br_gh127f.v:21: warning: output port in is coerced to inout. ./ivltests/br_gh127f.v:22: warning: input port out is coerced to inout. ./ivltests/br_gh127f.v:22: warning: output port in is coerced to inout. ./ivltests/br_gh127f.v:23: warning: input port out is coerced to inout. ./ivltests/br_gh127f.v:23: warning: Port 1 (out) of copy expects 2 bits, got 3. ./ivltests/br_gh127f.v:23: : Leaving 1 high bits of the expression dangling. ./ivltests/br_gh127f.v:23: warning: output port in is coerced to inout. 00 : 00 0 : 00 00 : 00 z00 01 : 01 1 : 01 01 : 01 z01 10 : 10 0 : 10 10 : 10 z10 11 : 11 1 : 11 11 : 11 z11 PASSED iverilog-12_0/ivtest/gold/br_gh13a.gold000066400000000000000000000003031435245347300200430ustar00rootroot00000000000000./ivltests/br_gh13a.v:7: warning: Unsized expression (('sd1)<<(~(40'b0000000000000000000000000000000000000000))) expanded beyond and was clipped to 65568 bits. Try using sized operands. 0 PASSED iverilog-12_0/ivtest/gold/br_gh156.vcd.gold000066400000000000000000000006061435245347300205530ustar00rootroot00000000000000$date Sat May 21 10:00:47 2022 $end $version Icarus Verilog $end $timescale 1s $end $scope module main $end $var wire 4 ! bat [3:0] $end $var real 1 " PI $end $var parameter 4 # bar $end $var parameter 4 $ foo $end $var real 1 % tau $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall b101 $ b111 # r3.14 " $end #0 $dumpvars r6.28 % b1100 ! $end #1 iverilog-12_0/ivtest/gold/br_gh157.gold000066400000000000000000000001561435245347300200010ustar00rootroot00000000000000./ivltests/br_gh157.v:13: error: Cannot override localparam `x` in `test.dut`. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh165.gold000066400000000000000000000003241435245347300177750ustar00rootroot00000000000000main thread started at time 0 main thread continued at time 5 task 1 finished at time 1001 task 2 finished at time 1002 task 3 finished at time 1006 main thread finished at time 1006 task 4 finished at time 1007 iverilog-12_0/ivtest/gold/br_gh198.gold000066400000000000000000000001551435245347300200050ustar00rootroot0000000000000000 01 02 03 04 05 06 07 10 20 30 40 50 60 70 17 26 35 44 53 62 71 00 01 02 03 04 05 06 07 10 20 30 17 26 35 iverilog-12_0/ivtest/gold/br_gh209.dat000066400000000000000000000000041435245347300176120ustar00rootroot00000000000000iverilog-12_0/ivtest/gold/br_gh230-vlog95.gold000066400000000000000000000000731435245347300211120ustar00rootroot00000000000000ERROR: vlog95.v:13: $dumpvars cannot dump a vpiPartSelect. iverilog-12_0/ivtest/gold/br_gh230.gold000066400000000000000000000001071435245347300177650ustar00rootroot00000000000000ERROR: ./ivltests/br_gh230.v:6: $dumpvars cannot dump a vpiPartSelect. iverilog-12_0/ivtest/gold/br_gh265.gold000066400000000000000000000002011435245347300177700ustar00rootroot00000000000000./ivltests/br_gh265.v:8: error: The expression '(8'd1)<<('sd4)' cannot be implicitly cast to the target type. Elaboration failed iverilog-12_0/ivtest/gold/br_gh289d.gold000066400000000000000000000000321435245347300201440ustar00rootroot00000000000000m.p1 1 2 11 m.p2 1 4 1111 iverilog-12_0/ivtest/gold/br_gh33.gold000066400000000000000000000002141435245347300177050ustar00rootroot00000000000000a= 7, b= 0, c= 1 -> old= x, new= 1 a=15, b= 0, c= 2 -> old= x, new= 2 a= 7, b= 0, c= 3 -> old= 1, new= 3 a=15, b= 0, c= 4 -> old= 2, new= 4 iverilog-12_0/ivtest/gold/br_gh365.gold000066400000000000000000000001011435245347300177700ustar00rootroot00000000000000DIRECT ASSIGNED STRING is WORKING Controller's new state is IDLE iverilog-12_0/ivtest/gold/br_gh366.gold000066400000000000000000000000201435245347300177710ustar00rootroot00000000000000/usr/local/bin/ iverilog-12_0/ivtest/gold/br_gh368.gold000066400000000000000000000001021435245347300177740ustar00rootroot00000000000000Process #1 Process #2 Process #1 -- completes Test task completes iverilog-12_0/ivtest/gold/br_gh374.gold000066400000000000000000000000121435245347300177710ustar00rootroot00000000000000opt1 opt2 iverilog-12_0/ivtest/gold/br_gh377-vlog95.gold000066400000000000000000000002161435245347300211250ustar00rootroot00000000000000: error: invalid value specified for defparam: test.name : error: invalid value specified for defparam: test.name iverilog-12_0/ivtest/gold/br_gh377.gold000066400000000000000000000001071435245347300200010ustar00rootroot00000000000000: error: invalid value specified for defparam: test.name iverilog-12_0/ivtest/gold/br_gh383a.gold000066400000000000000000000000601435245347300201350ustar00rootroot00000000000000 1 2 3 4 4 3 2 1 8 7 6 5 iverilog-12_0/ivtest/gold/br_gh383b.gold000066400000000000000000000000601435245347300201360ustar00rootroot00000000000000 1 2 3 4 4 3 2 1 8 7 6 5 iverilog-12_0/ivtest/gold/br_gh383c.gold000066400000000000000000000000301435245347300201340ustar00rootroot00000000000000a b c d d c b a h g f e iverilog-12_0/ivtest/gold/br_gh383d-ivl.gold000066400000000000000000000001401435245347300207270ustar00rootroot000000000000001.00000 2.00000 3.00000 4.00000 4.00000 3.00000 2.00000 1.00000 8.00000 7.00000 6.00000 5.00000 iverilog-12_0/ivtest/gold/br_gh383d.gold000066400000000000000000000000301435245347300201350ustar00rootroot000000000000001 2 3 4 4 3 2 1 8 7 6 5 iverilog-12_0/ivtest/gold/br_gh388.gold000066400000000000000000000000741435245347300200060ustar00rootroot00000000000000new uvm_object new uvm_object new uvm_report_object u_0 r_0 iverilog-12_0/ivtest/gold/br_gh390b.gold000066400000000000000000000002341435245347300201370ustar00rootroot00000000000000Hello World uvm_object::new(uvm_object) uvm_object::Print: m_name=uvm_object uvm_object::new(uvm_report_object) uvm_object::Print: m_name=uvm_report_object iverilog-12_0/ivtest/gold/br_gh391.gold000066400000000000000000000000211435245347300177700ustar00rootroot00000000000000building running iverilog-12_0/ivtest/gold/br_gh433.gold000066400000000000000000000004161435245347300177750ustar00rootroot00000000000000./ivltests/br_gh433.v:8: warning: method function 'pop_back' is being called as a task. ./ivltests/br_gh433.v:16: warning: method function 'pop_front' is being called as a task. ./ivltests/br_gh433.v:22: warning: method function 'size' is being called as a task. PASSED iverilog-12_0/ivtest/gold/br_gh436.gold000066400000000000000000000001161435245347300177750ustar00rootroot00000000000000m_argv[0] = str0 LARGE: 4 LARGE: 4 (2) m_argv[1] = str1 LARGE: 4 LARGE: 4 (2) iverilog-12_0/ivtest/gold/br_gh440-v11.gold000066400000000000000000000010251435245347300203750ustar00rootroot00000000000000./ivltests/br_gh440.v:44: error: Class/null is not allowed with the '|' operator. ./ivltests/br_gh440.v:45: error: Class/null is not allowed with the '<<(<)' operator. ./ivltests/br_gh440.v:46: error: Class/null is not allowed with the '<<(<)' operator. ./ivltests/br_gh440.v:48: error: Class/null is not allowed with the '<=' operator. ./ivltests/br_gh440.v:49: error: Class/null is not allowed with the '<=' operator. ./ivltests/br_gh440.v:50: error: Class/null is not allowed with the '!' operator. 6 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh440.gold000066400000000000000000000020171435245347300177720ustar00rootroot00000000000000./ivltests/br_gh440.v:4: Error: Class/null r-value not allowed in this context. ./ivltests/br_gh440.v:30: Error: Class/null r-value not allowed in this context. ./ivltests/br_gh440.v:43: error: Both arguments (logic, class) must be class/null for '==' operator. ./ivltests/br_gh440.v:44: error: Class/null is not allowed with the '|' operator. ./ivltests/br_gh440.v:45: error: Class/null is not allowed with the '<<(<)' operator. ./ivltests/br_gh440.v:46: error: Class/null is not allowed with the '<<(<)' operator. ./ivltests/br_gh440.v:46: Error: Class/null r-value not allowed in this context. ./ivltests/br_gh440.v:48: error: Class/null is not allowed with the '<=' operator. ./ivltests/br_gh440.v:49: error: Class/null is not allowed with the '<=' operator. ./ivltests/br_gh440.v:50: error: Class/null is not allowed with the '!' operator. ./ivltests/br_gh440.v:51: Error: Class/null r-value not allowed in this context. ./ivltests/br_gh440.v:52: Error: Class/null r-value not allowed in this context. 12 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh451.gold000066400000000000000000000000231435245347300177670ustar00rootroot00000000000000foo=4 bar=2 math=8 iverilog-12_0/ivtest/gold/br_gh497b.gold000066400000000000000000000021761435245347300201560ustar00rootroot00000000000000./ivltests/br_gh497b.v:12: error: Part-select [-2+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497b.v:15: error: Part-select [4+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497b.v:17: error: Part-select [-1+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497b.v:19: error: Part-select [3+:2] exceeds the declared bounds for array2. ./ivltests/br_gh497b.v:21: error: Part-select [-1-:2] exceeds the declared bounds for array3. ./ivltests/br_gh497b.v:24: error: Part-select [5-:2] exceeds the declared bounds for array3. ./ivltests/br_gh497b.v:26: error: Part-select [0-:2] exceeds the declared bounds for array4. ./ivltests/br_gh497b.v:28: error: Part-select [4-:2] exceeds the declared bounds for array4. ./ivltests/br_gh497b.v:30: error: Part-select [-1:-2] exceeds the declared bounds for array5. ./ivltests/br_gh497b.v:33: error: Part-select [5:4] exceeds the declared bounds for array5. ./ivltests/br_gh497b.v:35: error: Part-select [0:-1] exceeds the declared bounds for array6. ./ivltests/br_gh497b.v:37: error: Part-select [4:3] exceeds the declared bounds for array6. 12 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh497d.gold000066400000000000000000000021761435245347300201600ustar00rootroot00000000000000./ivltests/br_gh497d.v:16: error: Part-select [-2+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497d.v:19: error: Part-select [4+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497d.v:21: error: Part-select [-1+:2] exceeds the declared bounds for array1. ./ivltests/br_gh497d.v:23: error: Part-select [3+:2] exceeds the declared bounds for array2. ./ivltests/br_gh497d.v:25: error: Part-select [-1-:2] exceeds the declared bounds for array3. ./ivltests/br_gh497d.v:28: error: Part-select [5-:2] exceeds the declared bounds for array3. ./ivltests/br_gh497d.v:30: error: Part-select [0-:2] exceeds the declared bounds for array4. ./ivltests/br_gh497d.v:32: error: Part-select [4-:2] exceeds the declared bounds for array4. ./ivltests/br_gh497d.v:34: error: Part-select [-1:-2] exceeds the declared bounds for array5. ./ivltests/br_gh497d.v:37: error: Part-select [5:4] exceeds the declared bounds for array5. ./ivltests/br_gh497d.v:39: error: Part-select [0:-1] exceeds the declared bounds for array6. ./ivltests/br_gh497d.v:41: error: Part-select [4:3] exceeds the declared bounds for array6. 12 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh497f.gold000066400000000000000000000061241435245347300201570ustar00rootroot00000000000000./ivltests/br_gh497f.v:12: error: Part-select [-2+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:12: error: Part-select [-2+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:12: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:13: error: Part-select [-1+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:13: error: Part-select [-1+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:13: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:17: error: Part-select [3+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:17: error: Part-select [3+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:17: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:18: error: Part-select [4+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:18: error: Part-select [4+:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:18: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:20: error: Part-select [-1-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:20: error: Part-select [-1-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:20: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:21: error: Part-select [0-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:21: error: Part-select [0-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:21: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:25: error: Part-select [4-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:25: error: Part-select [4-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:25: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:26: error: Part-select [5-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:26: error: Part-select [5-:2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:26: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:28: error: Part-select [-1:-2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:28: error: Part-select [-1:-2] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:28: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:29: error: Part-select [0:-1] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:29: error: Part-select [0:-1] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:29: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:33: error: Part-select [4:3] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:33: error: Part-select [4:3] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:33: error: Unable to elaborate condition expression. ./ivltests/br_gh497f.v:34: error: Part-select [5:4] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:34: error: Part-select [5:4] exceeds the declared bounds for array. ./ivltests/br_gh497f.v:34: error: Unable to elaborate condition expression. 36 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh531.gold000066400000000000000000000000521435245347300177700ustar00rootroot00000000000000C1 01 C2 x01x C3 01 C4 x01x C5 01 C6 x01x iverilog-12_0/ivtest/gold/br_gh567.gold000066400000000000000000000003371435245347300200070ustar00rootroot00000000000000./ivltests/br_gh567.v:7: warning: A negative value (-1) has been assigned to genvar 'i'. ./ivltests/br_gh567.v:7: : This is illegal in Verilog-2001. Use at least -g2005 to remove this warning. 3 2 1 0 PASSED iverilog-12_0/ivtest/gold/br_gh62.gold000066400000000000000000000013671435245347300177210ustar00rootroot00000000000000./ivltests/br_gh62.v:13: error: the number of indices (3) is greater than the number of dimensions (2). ./ivltests/br_gh62.v:14: error: the number of indices (3) is greater than the number of dimensions (2). ./ivltests/br_gh62.v:15: error: the number of indices (3) is greater than the number of dimensions (2). ./ivltests/br_gh62.v:16: error: the number of indices (2) is greater than the number of dimensions (1). ./ivltests/br_gh62.v:17: error: the number of indices (2) is greater than the number of dimensions (1). ./ivltests/br_gh62.v:18: error: the number of indices (2) is greater than the number of dimensions (1). ./ivltests/br_gh62.v:19: error: the number of indices (2) is greater than the number of dimensions (1). 7 error(s) during elaboration. iverilog-12_0/ivtest/gold/br_gh72a.gold000066400000000000000000000000501435245347300200470ustar00rootroot00000000000000d1 1 d1 d2 1 d2 1 2 d1 d2 1 d2 1 2 d1 2 iverilog-12_0/ivtest/gold/br_gh72b.gold000066400000000000000000000000061435245347300200510ustar00rootroot000000000000001 1 2 iverilog-12_0/ivtest/gold/br_gh72b_fail.gold000066400000000000000000000005661435245347300210570ustar00rootroot00000000000000./ivltests/br_gh72b_fail.v:5: error: too many arguments for `macro1 ./ivltests/br_gh72b_fail.v:6: error: too many arguments for `macro1 ./ivltests/br_gh72b_fail.v:8: error: too few arguments for `macro2 ./ivltests/br_gh72b_fail.v:9: error: too few arguments for `macro2 ./ivltests/br_gh72b_fail.v:10: error: too many arguments for `macro2 Preprocessor failed with 5 errors. iverilog-12_0/ivtest/gold/br_gh732.gold000066400000000000000000000002751435245347300200020ustar00rootroot00000000000000 0 x x x 1000 0 x x 1100 0 0 x 1200 0 0 0 2000 1 0 0 2100 1 1 0 2200 1 1 1 iverilog-12_0/ivtest/gold/br_gh782a.gold000066400000000000000000000005451435245347300201500ustar00rootroot00000000000000File ./ivltests/br_gh782a.v line 4 Included file ./ivltests/br_gh782a.vi line 1 File ./ivltests/br_gh782a.v line 6 Included file ./ivltests/br_gh782a.vi line 1 File ./ivltests/br_gh782a.v line 8 Included file ./ivltests/br_gh782a.vi line 1 File ./ivltests/br_gh782a.v line 11 Included file ./ivltests/br_gh782a.vi line 1 File ./ivltests/br_gh782a.v line 14 iverilog-12_0/ivtest/gold/br_gh782b.gold000066400000000000000000000005311435245347300201440ustar00rootroot00000000000000File ./ivltests/br_gh782b.v line 10 Time scale of (t1) is 1s / 100ms File ./ivltests/br_gh782b.v line 19 Time scale of (t2) is 100ms / 10ms File ./ivltests/br_gh782b.v line 28 Time scale of (t3) is 10us / 1us File ./ivltests/br_gh782b.v line 38 Time scale of (t4) is 1ns / 1ps File ./ivltests/br_gh782b.v line 48 Time scale of (t5) is 1ps / 1fs iverilog-12_0/ivtest/gold/br_gh788.gold000066400000000000000000000000031435245347300200020ustar00rootroot0000000000000042 iverilog-12_0/ivtest/gold/br_gh79.gold000066400000000000000000000013121435245347300177170ustar00rootroot00000000000000./ivltests/br_gh79.v:6: syntax error ./ivltests/br_gh79.v:6: error: Malformed statement ./ivltests/br_gh79.v:7: syntax error ./ivltests/br_gh79.v:7: error: Malformed statement ./ivltests/br_gh79.v:9: syntax error ./ivltests/br_gh79.v:9: error: Malformed statement ./ivltests/br_gh79.v:10: syntax error ./ivltests/br_gh79.v:10: error: Malformed statement ./ivltests/br_gh79.v:12: syntax error ./ivltests/br_gh79.v:12: error: Malformed statement ./ivltests/br_gh79.v:13: syntax error ./ivltests/br_gh79.v:13: error: Malformed statement ./ivltests/br_gh79.v:15: syntax error ./ivltests/br_gh79.v:15: error: Malformed statement ./ivltests/br_gh79.v:16: syntax error ./ivltests/br_gh79.v:16: error: Malformed statement iverilog-12_0/ivtest/gold/br_ml20190814.gold000066400000000000000000000000001435245347300203730ustar00rootroot00000000000000iverilog-12_0/ivtest/gold/br_ml_20150315.gold000066400000000000000000000000441435245347300205320ustar00rootroot00000000000000At time 1, field 1 = 1, field 2 = 2 iverilog-12_0/ivtest/gold/busbug.gold000066400000000000000000000000061435245347300177440ustar00rootroot0000000000000001=01 iverilog-12_0/ivtest/gold/ca_64delay.gold000066400000000000000000000004161435245347300203750ustar00rootroot00000000000000dl:ls32b- 1 ps rl:ls32b- 1 ps rg:ls32b- 2 ps ar:ls32b- 3 ps ps:ls32b- 4 ps dl:gt32b- 1000000000000 ps rl:gt32b- 1000000000000 ps rg:gt32b- 2000000000000 ps ar:gt32b- 3000000000000 ps ps:gt32b- 4000000000000 ps iverilog-12_0/ivtest/gold/ca_mult.gold000066400000000000000000000000751435245347300201070ustar00rootroot00000000000000 -2 -1.00000 0 0.00000 2 1.00000 iverilog-12_0/ivtest/gold/ca_time.gold000066400000000000000000000001561435245347300200640ustar00rootroot00000000000000 0 0 1 1 0 0 3 3 0 0 iverilog-12_0/ivtest/gold/ca_time_real-ivl.gold000066400000000000000000000000501435245347300216500ustar00rootroot000000000000000.00000 1.00000 0.00000 3.00000 0.00000 iverilog-12_0/ivtest/gold/ca_time_real.gold000066400000000000000000000000121435245347300210560ustar00rootroot000000000000000 1 0 3 0 iverilog-12_0/ivtest/gold/ca_time_smtm.gold000066400000000000000000000000671435245347300211250ustar00rootroot00000000000000 0 1 0 3 0 iverilog-12_0/ivtest/gold/case_priority-vlog95.gold000066400000000000000000000000341435245347300224550ustar00rootroot00000000000000case 0 case 1 case 3 PASSED iverilog-12_0/ivtest/gold/case_priority.gold000066400000000000000000000002371435245347300213370ustar00rootroot00000000000000case 0 case 1 WARNING: ./ivltests/case_priority.v:12: value is unhandled for priority or unique case statement Time: 50000 Scope: main case 3 PASSED iverilog-12_0/ivtest/gold/case_unique-vlog95.gold000066400000000000000000000000341435245347300221020ustar00rootroot00000000000000case 0 case 1 case 3 PASSED iverilog-12_0/ivtest/gold/case_unique.gold000066400000000000000000000003641435245347300207650ustar00rootroot00000000000000./ivltests/case_unique.v:12: vvp.tgt sorry: Case unique/unique0 qualities are ignored. case 0 case 1 WARNING: ./ivltests/case_unique.v:12: value is unhandled for priority or unique case statement Time: 50000 Scope: main case 3 PASSED iverilog-12_0/ivtest/gold/casesynth7.gold000066400000000000000000000003271435245347300205530ustar00rootroot00000000000000./ivltests/casesynth7.v:17: warning: A latch has been inferred for 'o'. ./ivltests/casesynth7.v:17: warning: The latch enable is connected to a synthesized expression. The latch may be sensitive to glitches. PASSED iverilog-12_0/ivtest/gold/cmos.gold000066400000000000000000000006301435245347300174210ustar00rootroot00000000000000zz HiZ HiZ 0 0 1 00 St0 St0 0 1 0 00 St0 St0 0 1 1 00 St0 St0 0 0 0 00 St0 St0 0 x 0 00 St0 St0 0 1 x xx StL StL 0 x 1 xx StL StL 0 0 x xx StL StL 0 x x zz HiZ HiZ 1 0 1 11 St1 St1 1 1 0 11 St1 St1 1 1 1 11 St1 St1 1 0 0 11 St1 St1 1 x 0 11 St1 St1 1 1 x xx StH StH 1 x 1 xx StH StH 1 0 x xx StH StH 1 x x zz HiZ HiZ x 0 1 xx StX StX x 1 0 xx StX StX x x x zz HiZ HiZ z 0 1 zz HiZ HiZ z 1 0 zz HiZ HiZ z x x iverilog-12_0/ivtest/gold/comp1000.gold000066400000000000000000000142031435245347300177200ustar00rootroot00000000000000r0 = 0011110100100100 r1 = 0000000000000000000000000 r2 = 0000000000000000000000000100 r3 = 1011 r4 = 0000000100000100010101 r5 = 0000000000000000000000000000000 r6 = 00 r7 = xxxxxxxxxxxxxxxxxxxxxx r8 = 0000000000000000x r9 = 00000000000000001 r10 = 01010110011 r11 = 000000000000000000000111101001 r12 = 111111111111111111111111111100 r13 = 0000000000000011111101101111 r14 = 000100101 r15 = 000000000000 r16 = 1100110 r17 = 000000000000010100001011 r18 = 0000000000000000001111110011 r19 = 00000000000000000111111110111111 r20 = 1 r21 = 000000000 r22 = 000000000000000 r23 = 0101 r24 = 1010010001000 r25 = 00000000000000000000100101010110 r26 = 00000000000000000000000001 r27 = 000000000000001 r28 = 00000000000000110010010100 r29 = 0000000000000x0xx00xx0xx0 r30 = 00000000000000000000000000000000 r31 = 10 r32 = 0000000000000000000000000000000 r33 = 0000000000000100010101110110 r34 = xxxxxxxxxxxxxxxxx r35 = 1100101001100 r36 = 0001 r37 = 000000000000000000000000000000 r38 = 0011100 r39 = 111101001 r40 = 000000000110110010111011 r41 = 00000000000000000100100000100101 r42 = 10111000111 r43 = 0000000000000000000000000000x r44 = 00000000000000000000000000 r45 = 0000000000001 r46 = 000000000000001 r47 = 000000000000100101111111111 r48 = 000100001000001001 r49 = 000000000000000000000000000001 r50 = 0000111010100000010 r51 = 00 r52 = 00000000000011000101100 r53 = 000000000110011001010000 r54 = 111 r55 = 0000000000000000000000000001 r56 = 101111011 r57 = 1111111111 r58 = 00000000000000000000x r59 = 00000000000000000000101111000010 r60 = 0000000000000000000001 r61 = 00000000000000001 r62 = 0010010101011 r63 = 000000000000001 r64 = 00000000100110111110000 r65 = 0000000100110001001110 r66 = 000000000000100000011010010 r67 = 000000000111010100010110 r68 = 000000001010010110 r69 = 000000000001 r70 = 0000000000011101111000000 r71 = 0000000110110010110101 r72 = 000000000110110011111111 r73 = 000000101111100000000 r74 = 0100100100011001 r75 = 100111011001010 r76 = 011110 r77 = 00000000000000000000000000000 r78 = 000100011001100001 r79 = 000000110111111110101 r80 = 000000 r81 = 000000000000000001000101100 r82 = 0000000000000000100000000010000 r83 = 0100100 r84 = 10110010010010 r85 = 000000011110110110110 r86 = xxx r87 = 111011111111111 r88 = 00000000000000100011110110000 r89 = 00000000000000000000000000 r90 = 00000000000000000000 r91 = 100 r92 = 011 r93 = 10111001 r94 = 0000000101111100000000 r95 = 110111 r96 = 000000000000000000000011 r97 = 000001 r98 = 0000000000110001110100010 r99 = 0111011 r100 = x r101 = 000000001 r102 = 000000000000000000000001 r103 = 000000000000000000000000000000 r104 = 00000101010101010 r105 = 00000000000000001 r106 = 0000000000000000000000000 r107 = 00000000000000000000 r108 = 0010 r109 = 00000010000 r110 = 000000000000000000 r111 = 00000010110101010010100000 r112 = 000 r113 = 011111011010010 r114 = 00000000000000000101110010110111 r115 = 111111110101100 r116 = 00011 r117 = 1 r118 = 0000000000000000 r119 = 0000000000000011101101101000 r120 = 0110001101 r121 = 000000010110111011 r122 = 000000000110001011101100 r123 = xxxxxxxxxxxxxxxxxxxxxxxxxx r124 = 0 r125 = 000000000000000001011110000111 r126 = 0000000000000000000000010101 r127 = 10110110 r128 = 0 r129 = 0100110011000 r130 = 000000000001 r131 = 000000000011111101010101 r132 = 00000000000000000 r133 = 000000000000000000001 r134 = 000 r135 = 1 r136 = 00 r137 = 00000100100100100110 r138 = 0000000x r139 = 110011101110 r140 = 000000000000001001 r141 = 000000000100110111110000 r142 = 11100111001000 r143 = 0100010101 r144 = 101001111 r145 = 0000000000000000000000001 r146 = 0000000001110000000111 r147 = 0000000000111010100000010 r148 = 00000000000000000000000000001 r149 = 0000000000000000000000000000 r150 = 000000000 r151 = 00010 r152 = 0000000000000000 r153 = 0000000000000001 r154 = 0 r155 = 100 r156 = 000110111001010 r157 = 000000000000000000 r158 = 0000000000000000000000000000000 r159 = 000000111100010000111 r160 = 0000000100000000010 r161 = 00001000011 r162 = 00000000000000000001 r163 = 00000000000 r164 = 10 r165 = 111001100001000 r166 = 000000000000000000000000000 r167 = 0000000000000000001000001110000 r168 = 001011001101 r169 = 000000000000000000000000000000 r170 = 000000000000000000000000000 r171 = 0000000001100101010010 r172 = 00000000000000001 r173 = 0010 r174 = 00000001 r175 = 0100 r176 = 00000000110110010110101 r177 = 000000000000001100001111101 r178 = 00000000000000000000000000000100 r179 = 111010 r180 = 0000000011011111111011 r181 = 000000 r182 = 0101100101111110 r183 = 11111110 r184 = 000000000000000 r185 = 000000000000000000001 r186 = 00000000000000 r187 = 000000000000000000000000000000 r188 = 01101011110101 r189 = 100010 r190 = 000000000000000000000000000000x r191 = 1000100000011 r192 = 00000000000010 r193 = 11111111111111111010111111111000 r194 = 00000110100001100 r195 = xx r196 = 0000011000011000011 r197 = 000000000000101000000001 r198 = 00000000000000000000000000000000 r199 = 00000000000100110010010 r200 = 000000000000001 r201 = 0000000000000x r202 = 0000101100100100010 r203 = 0000010111101100001 r204 = 00000000000000000101110001000100 r205 = 000000000000000 r206 = 000000000000000000000000000001 r207 = 000000010 r208 = 000000000000001 r209 = 000000000000000000x r210 = 1111111111111111111111111111111 r211 = 0000000101010011000100 r212 = 0000000000000000 r213 = 000000000000000000000000000000 r214 = xxx r215 = 11101 r216 = 000001 r217 = 0 r218 = 1 r219 = 0111010010001 r220 = 000000000000000000000000000001 r221 = 000000000000000000000001 r222 = 000000000000000000000110001 r223 = 000000001100010 r224 = 00000000000000000 r225 = 01111001010 r226 = 00 r227 = 00000000000000000000000000x r228 = 01011 r229 = 1111111111110011 r230 = 00000000000000000 r231 = 1111110010 r232 = 10011011000 r233 = 11100 r234 = 0000000000000000 r235 = 001 r236 = 00000000000000000000000000000000 r237 = 000000000000000011101011 r238 = 0000000000000000 r239 = 0000000000000000000000000 r240 = 10110111100101 r241 = 01 r242 = 0000000000000000001 r243 = 011101011 r244 = 00100100100 r245 = 00000 r246 = 100 r247 = 000000000000000100110001001110 r248 = 0000000001101011110101 r249 = 0000000000000000001 r250 = 000000000011100101101010 r251 = 10001010101110 r252 = 0000000000000000000000000000000 r253 = 000000001 r254 = 00000100110101100110 iverilog-12_0/ivtest/gold/comp1001.gold000066400000000000000000000137641435245347300177340ustar00rootroot00000000000000r0 = 0000010111011101100 r1 = 00000000000000000001010110000100 r2 = 000000000100011111100101 r3 = 11 r4 = 00000000000000000x r5 = 000000000011101001 r6 = 1 r7 = 00111010011 r8 = 00000000000000000000000 r9 = 000000000000000001 r10 = 000000000000000101010111011111 r11 = 1111111111111111111101 r12 = 10101011 r13 = 10101011 r14 = 0000000000000000000 r15 = 00000000000000000000000001 r16 = 00000 r17 = 0000000000000000000000000 r18 = 00 r19 = 1011010001 r20 = 0000000110000 r21 = 111100 r22 = 0100 r23 = 000000000000000000001 r24 = 00000000000000000000000001 r25 = 011100110010 r26 = xxxxxxxxxxxxxxxxxxxx r27 = 000000 r28 = 11 r29 = 110 r30 = 011 r31 = xxx r32 = 00000000111011010100111 r33 = 0 r34 = 11 r35 = 010000100001010 r36 = 000000 r37 = 0000000110100101101001 r38 = 000000000000000000100010111011 r39 = 0010111101 r40 = 00000000000000110001000010 r41 = 000000000000000 r42 = 00000000000000000111100010101 r43 = xxxxxxxxxxxxxx r44 = 000000000000000000000001 r45 = 0000000000000000000001 r46 = 0010 r47 = 111111111111111110 r48 = 00 r49 = 00000000000001 r50 = 0000000000000000000 r51 = 000000001 r52 = 0000000101001111010100 r53 = 0000000000000001100100111 r54 = 00010 r55 = 01 r56 = 00001110011010 r57 = 00000000000000000001 r58 = 000000000000000000 r59 = 01100100 r60 = 00000000000000000110100110010110 r61 = 000000000010111101000000 r62 = 000111110011000 r63 = 1 r64 = 11111111111111101111011001101 r65 = 000000000000000000000000x r66 = xxxxxxxxxx r67 = 0000000000000001 r68 = 00000000000000000001 r69 = 000000001 r70 = 00000000000000001 r71 = 000000101001000011111 r72 = 00000000000001 r73 = 00000000000000000001 r74 = 1001100100 r75 = 0000000000 r76 = 000000000000000001 r77 = 001 r78 = 000000000000000000000010000 r79 = 000000 r80 = 0 r81 = xxxxxxxxxxxxxxxxxxxxxxxxxx r82 = 1 r83 = 0000000000000000000000000000 r84 = 000000000000011110011110 r85 = 0000000000000000000000000001 r86 = 000000000000000000000000001 r87 = 000000000000000000000000000 r88 = 0000000000000000001 r89 = 11000 r90 = 000000000000000010101001001111 r91 = 00110111010110 r92 = 110000 r93 = 1100011111000 r94 = 00000000000000000000000000000001 r95 = 000000000000111010100100000 r96 = 11100 r97 = 0000000000 r98 = 0100100110101110 r99 = 1111x r100 = 000000000000000000000000001 r101 = 011011101101 r102 = 00000000000000000000000000 r103 = 000000000000 r104 = 0xxxxxxxxxxxxxxxxxxx r105 = 00000000000000000100011001111001 r106 = 00101 r107 = 0000001001 r108 = 0000000111010010001010 r109 = 110000101111001 r110 = 00000000001010110010011 r111 = 0000000000101110111000 r112 = 1 r113 = 0000000000000000110110000100111 r114 = 11001100110001 r115 = 100 r116 = 000000000010000010110 r117 = 010001000010011 r118 = 000011 r119 = 00000000000000000000100010101100 r120 = 1110100011 r121 = 00000000000000011100000100111 r122 = 000000000100011011011101 r123 = 00000000100001101001100 r124 = 00000000110010010010111 r125 = 0x r126 = 00000000101110110110001 r127 = 0100111010110111 r128 = 00011001111001 r129 = 000000000000000000 r130 = 0000001001000010110 r131 = 00000000001100 r132 = 0000000000000001111101100010 r133 = 000000000000000000000001100111 r134 = 000000000000000000000000 r135 = 01100011111110 r136 = 001001111111 r137 = 00000010110110111110 r138 = 00000000000001 r139 = 0000000000001 r140 = 000 r141 = 0000000000000000001100110111 r142 = 0000000000110011101101100 r143 = 0 r144 = 000 r145 = 000000000000000011110001100 r146 = 000000000000000000000000 r147 = 00000000000000111100111001110 r148 = 0011111100 r149 = 00011011001000011 r150 = 11001000 r151 = 0000000000000001 r152 = 0000001101011100110 r153 = 00000000000000111010100100000 r154 = 00000000000000000011110000001010 r155 = 0000 r156 = 00011000111100011 r157 = 0000000000000000000001 r158 = 00000000000000000001 r159 = 1 r160 = 000000000000000000000000x r161 = 000000000000000000 r162 = 00000000000000000001 r163 = 0101111101 r164 = 00000000000000000000001 r165 = 1 r166 = 0000000000001 r167 = 00000000000000010110110100101 r168 = 0000000000000000000000 r169 = 0001000111101010 r170 = 00100 r171 = 00000110110101000100 r172 = 00000000000000000000000000 r173 = 01001011 r174 = 0 r175 = 01101000 r176 = 0000010 r177 = 00111000010000 r178 = 00000000000000000000000000000000 r179 = 00000000111 r180 = 00000000000000000000000001 r181 = 0001 r182 = 0000000000000000000000000000000 r183 = 000000000001 r184 = 0000000000000 r185 = 00110 r186 = 00000001110111001100x r187 = 000000011110011101010 r188 = 0000000000000000000001 r189 = 0011111001 r190 = 00000000000000000000xxx r191 = 00000010101111 r192 = 111001 r193 = 000000000 r194 = 0000100010110000001 r195 = 00000000000000010000010101 r196 = 000000000001 r197 = xxxxxxxxxxxxxxxxxxx r198 = 00000000000000000000001 r199 = 0000000101010111110001 r200 = 00000001111101001 r201 = 0000000011011110100 r202 = 000000000 r203 = 0000000000000000000010111010010 r204 = 000000000000000000000000001 r205 = 00000000000000000000 r206 = 00100110101110 r207 = 01001001000 r208 = 0000000000001 r209 = 00000000000001011110100011 r210 = 011011 r211 = 0100110101110 r212 = 1001 r213 = 000001 r214 = 000000000000 r215 = 00000000000000000000 r216 = 0000000000110100101000011 r217 = xxxxxxxxxxxxxxxxxxxx r218 = 000000000011110110010010 r219 = 0000010110 r220 = 0110 r221 = 000000000000000000000000000000 r222 = 000000000000000000000000000000x r223 = 00000000000110101010010 r224 = 00000011101110110111 r225 = 0000000000000111100101000 r226 = 0001000000000100 r227 = 000000000000000000000000001010 r228 = 00000000000000000010101010 r229 = 000000000000000000000 r230 = 0000000000111101111000 r231 = 0000000000000000000000000000 r232 = 000000000000000000000000000000 r233 = 0000000000000000000101100001110 r234 = 000000000000100011011011101 r235 = 00000000000000 r236 = 110100 r237 = 00000000000000000000000000000000 r238 = 0 r239 = 1101111100 r240 = 00000101110101110111 r241 = 00000000000000000110111010100 r242 = 001111100 r243 = 001 r244 = 0000000 r245 = 00000000000101010110100 r246 = 000000000000001 r247 = 0000001 r248 = 00000000000000000000001 r249 = 10000111010 r250 = 101110111 r251 = 001 r252 = 000000000000101111101101000 r253 = 000110010010011110 r254 = 0000011111011 iverilog-12_0/ivtest/gold/dcomp1.gold000066400000000000000000000055571435245347300176600ustar00rootroot000000000000000 x 0 4 0 got here 0 0 0 4 4 1 0 0 4 200 got here 1 1 0 4 204 0 1 0 4 400 got here 0 0 0 4 404 1 0 0 4 600 got here 1 1 0 4 604 0 1 0 4 800 got here 0 0 0 4 804 1 0 0 4 1000 got here 1 1 0 4 1004 0 1 0 4 1200 got here 0 0 0 4 1204 1 0 0 4 1400 got here 1 1 0 4 1404 0 1 0 4 1600 got here 0 0 0 4 1604 1 0 0 4 1800 got here 1 1 0 4 1804 0 1 13 17 2000 got here 0 0 13 17 2017 1 0 13 17 2200 got here 1 1 13 17 2217 0 1 13 17 2400 got here 0 0 13 17 2417 1 0 13 17 2600 got here 1 1 13 17 2617 0 1 13 17 2800 got here 0 0 13 17 2817 1 0 13 17 3000 got here 1 1 13 17 3017 0 1 13 17 3200 got here 0 0 13 17 3217 1 0 13 17 3400 got here 1 1 13 17 3417 0 1 13 17 3600 got here 0 0 13 17 3617 1 0 13 17 3800 got here 1 1 13 17 3817 0 1 13 17 4000 iverilog-12_0/ivtest/gold/def_nettype_none.gold000066400000000000000000000001561435245347300220100ustar00rootroot00000000000000./ivltests/def_nettype_none.v:16: error: Net b is not defined in this context. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/defparam2.gold000066400000000000000000000001631435245347300203220ustar00rootroot00000000000000main.xx.U[0]: number=0 main.xx.U[1]: number=1 main.xx.U[2]: number=2 main.xx.U[3]: number=3 main.xx.U[4]: number=4 iverilog-12_0/ivtest/gold/defparam3.gold000066400000000000000000000002071435245347300203220ustar00rootroot00000000000000main.xx.sub[0].U: number=0 main.xx.sub[1].U: number=1 main.xx.sub[2].U: number=2 main.xx.sub[3].U: number=3 main.xx.sub[4].U: number=4 iverilog-12_0/ivtest/gold/defparam4.gold000066400000000000000000000002211435245347300203170ustar00rootroot00000000000000main.D.xx.sub[0].U: number=0 main.D.xx.sub[1].U: number=1 main.D.xx.sub[2].U: number=2 main.D.xx.sub[3].U: number=3 main.D.xx.sub[4].U: number=4 iverilog-12_0/ivtest/gold/delay.gold000066400000000000000000000003271435245347300175610ustar00rootroot00000000000000time=510, cat1=1 time=0052, cat2=1 time=0053, cat3=1 time=0054, cat4=1 time=0055, foo1=1 time=0056, foo2=1 time=0057, foo3=1 time=0058, foo4=1 time=0059, bar1=1 time=0059, bar2=1 time=0059, bar3=1 time=0059, bar4=1 iverilog-12_0/ivtest/gold/delay_var.gold000066400000000000000000000006301435245347300204260ustar00rootroot000000000000000.0 x x x x x x x x Should be 1.0: 1.0 1.0 1 x x x 1 x x x Should be 1.001: 1.001 Should be 1.1: 1.1 1.1 1 1 x x 1 1 x x Should be 1.2: 1.2 1.2 1 1 1 x 1 1 1 x Should be 1.3: 1.3 1.3 1 1 1 1 1 1 1 1 3.0 0 1 1 1 0 1 1 1 3.1 0 0 1 1 0 0 1 1 3.2 0 0 0 1 0 0 0 1 3.3 0 0 0 0 0 0 0 0 7.0 1 0 0 0 1 0 0 0 7.1 1 1 0 0 1 1 0 0 7.2 1 1 1 0 1 1 1 0 Large delay: 18446744073709552.0 18446744073709552.0 1 1 1 1 1 1 1 1 iverilog-12_0/ivtest/gold/delayed_sfunc-ivl.gold000066400000000000000000000002541435245347300220570ustar00rootroot000000000000000 0.00000 x x 10 1 0.00000 4 4 10 5 0.00000 4 4 20 6 0.00000 5 5 20 iverilog-12_0/ivtest/gold/delayed_sfunc.gold000066400000000000000000000002241435245347300212640ustar00rootroot000000000000000 0 x x 10 1 0 4 4 10 5 0 4 4 20 6 0 5 5 20 iverilog-12_0/ivtest/gold/disblock2.gold000066400000000000000000000000671435245347300203400ustar00rootroot00000000000000hello world, 'b1 Byte enable is 'h1 Byte enable is 'h0 iverilog-12_0/ivtest/gold/disp_dec.gold000066400000000000000000000001161435245347300202310ustar00rootroot000000000000004'bxxxx = x 4'bzzxx = X 4'bzzzz = z 4'b00zz = Z 4'b0000 = 0 4'b0011 = 3 iverilog-12_0/ivtest/gold/disp_dec2.gold000066400000000000000000000000221435245347300203070ustar00rootroot00000000000000-1 (should be -1) iverilog-12_0/ivtest/gold/disp_leading_z.gold000066400000000000000000000000431435245347300214310ustar00rootroot00000000000000|0000000011| |11| |0000000000| |0| iverilog-12_0/ivtest/gold/disp_parm.gold000066400000000000000000000001011435245347300204270ustar00rootroot00000000000000decimal GEORGE: 5, HARRY: 10 binary GEORGE: 'b101, HARRY: 'b1010 iverilog-12_0/ivtest/gold/disp_part.gold000066400000000000000000000000311435245347300204400ustar00rootroot000000000000001001 0100 0010 1001 1100 iverilog-12_0/ivtest/gold/display_bug.gold000066400000000000000000000000251435245347300207600ustar00rootroot00000000000000ab a b cd c d ab a b iverilog-12_0/ivtest/gold/drive_strength2.gold000066400000000000000000000000301435245347300215630ustar00rootroot000000000000001 0 1 0 0 1 1 0 1 0 0 1 iverilog-12_0/ivtest/gold/dummy7.gold000066400000000000000000000002501435245347300177000ustar00rootroot00000000000000should be 00 -- data1=00 data2=00 data3=00 data4=00 should be 11 -- data1=11 data2=11 data3=11 data4=11 should be 22 -- data1=22 data2=22 data3=22 data4=22 iverilog-12_0/ivtest/gold/dump_memword.vcd000066400000000000000000000004161435245347300210100ustar00rootroot00000000000000$date Sun May 15 18:09:25 2022 $end $version Icarus Verilog $end $timescale 1s $end $scope module top $end $var reg 8 ! \arr[4] [7:0] $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall $end #0 $dumpvars b0 ! $end #1 b11111111 ! iverilog-12_0/ivtest/gold/enum_dims_invalid.gold000066400000000000000000000011561435245347300221520ustar00rootroot00000000000000ivltests/enum_dims_invalid.v:13: error: An unsized dimension is not allowed here. ivltests/enum_dims_invalid.v:17: error: Dimension size must be greater than zero. ivltests/enum_dims_invalid.v:17 : This size expression violates the rule: -('sd1) ivltests/enum_dims_invalid.v:9: error: A queue dimension is not allowed here. ivltests/enum_dims_invalid.v:21: error: Dimension size must be greater than zero. ivltests/enum_dims_invalid.v:21 : This size expression violates the rule: 'sd0 ivltests/enum_dims_invalid.v:25: error: Enum type must not have more than 1 packed dimension. 6 error(s) during elaboration. iverilog-12_0/ivtest/gold/enum_line_info.gold000066400000000000000000000006061435245347300214510ustar00rootroot00000000000000./ivltests/enum_line_info.v:7: error: Enumeration name B and A have the same value: 1'd0 ./ivltests/enum_line_info.v:12: error: Enumeration name D and C have the same value: 1'd0 ./ivltests/enum_line_info.v:17: error: Enumeration name F and E have the same value: 1'd0 ./ivltests/enum_line_info.v:22: error: Enumeration name H and G have the same value: 1'd0 5 error(s) during elaboration. iverilog-12_0/ivtest/gold/eofmt_percent-v11.gold000066400000000000000000000000541435245347300217170ustar00rootroot00000000000000The following should be a single percent: % iverilog-12_0/ivtest/gold/eofmt_percent-vlog95.gold000066400000000000000000000002171435245347300224360ustar00rootroot00000000000000WARNING: vlog95.v:11: a single % at the end of format string $display<%> will be displayed as '%'. The following should be a single percent: % iverilog-12_0/ivtest/gold/eofmt_percent.gold000066400000000000000000000002401435245347300213070ustar00rootroot00000000000000WARNING: ./ivltests/eofmt_percent.v:2: a single % at the end of format string $display<%> will be displayed as '%'. The following should be a single percent: % iverilog-12_0/ivtest/gold/escaped_macro_name.gold000066400000000000000000000001451435245347300222460ustar00rootroot00000000000000simple name simple name escaped name escaped name backtick name backtick "text" "text" escaped quote iverilog-12_0/ivtest/gold/event3.gold000066400000000000000000000016641435245347300176740ustar00rootroot00000000000000T= 0, a= 10, b= 20, x= x, y= x T= 10, a= 30, b= 20, x= x, y= x T= 20, a= 30, b= 40, x= x, y= x T= 30, a= 50, b= 40, x= x, y= x T= 31, a= 50, b= 40, x= 50, y= x T= 33, a= 50, b= 40, x= 50, y= 40 T= 40, a= 50, b= 60, x= 50, y= 40 T= 43, a= 50, b= 60, x= 50, y= 60 T= 50, a= 70, b= 80, x= 50, y= 60 T= 51, a= 70, b= 80, x= 70, y= 60 T= 53, a= 70, b= 80, x= 70, y= 80 T= 60, a= 90, b= 80, x= 70, y= 80 iverilog-12_0/ivtest/gold/event_list3.gold000066400000000000000000000002701435245347300207170ustar00rootroot00000000000000 20 combinatorial process 0 time: 30 combinatorial process 1 time: 30 40 60 80 iverilog-12_0/ivtest/gold/fatal_et_al-vlog95.gold000066400000000000000000000004111435245347300220330ustar00rootroot00000000000000INFO: vlog95.v:12: This is the $info message. Time: 1 Scope: top WARNING: vlog95.v:13: This is the $warning message. Time: 2 Scope: top ERROR: vlog95.v:14: This is the $error message. Time: 3 Scope: top Check that the messages are correct. iverilog-12_0/ivtest/gold/fatal_et_al.gold000066400000000000000000000004661435245347300207220ustar00rootroot00000000000000INFO: ./ivltests/fatal_et_al.v:3: This is the $info message. Time: 1 Scope: top WARNING: ./ivltests/fatal_et_al.v:4: This is the $warning message. Time: 2 Scope: top ERROR: ./ivltests/fatal_et_al.v:5: This is the $error message. Time: 3 Scope: top Check that the messages are correct. iverilog-12_0/ivtest/gold/fatal_et_al2.gold000066400000000000000000000005571435245347300210050ustar00rootroot00000000000000INFO: ./ivltests/fatal_et_al2.v:3: This is the $info message. Time: 1 Scope: top WARNING: ./ivltests/fatal_et_al2.v:4: This is the $warning message. Time: 2 Scope: top ERROR: ./ivltests/fatal_et_al2.v:5: This is the $error message. Time: 3 Scope: top FATAL: ./ivltests/fatal_et_al2.v:6: This is the $fatal message. Time: 4 Scope: top iverilog-12_0/ivtest/gold/fdisplay1.gold000066400000000000000000000001551435245347300203560ustar00rootroot00000000000000message to stdout (from $display) another message (via fwrite) to stdout (via fdisplay) a = 01011010 at 5 iverilog-12_0/ivtest/gold/fdisplay2.out000066400000000000000000000000431435245347300202350ustar00rootroot00000000000000hello, world a = 'hac = 'b10101100 iverilog-12_0/ivtest/gold/fdisplay3-vlog95.gold000066400000000000000000000001051435245347300214760ustar00rootroot00000000000000ERROR: vlog95.v:12: $fdisplay's file descriptor/MCD must be numeric. iverilog-12_0/ivtest/gold/fdisplay3.gold000066400000000000000000000001231435245347300203530ustar00rootroot00000000000000ERROR: ./ivltests/fdisplay3.v:28: $fdisplay's file descriptor/MCD must be numeric. iverilog-12_0/ivtest/gold/fdisplay_fail_fd-v10.gold000066400000000000000000000001471435245347300223460ustar00rootroot00000000000000WARNING: ./ivltests/fdisplay_fail_fd.v:4: invalid file descriptor/MCD (0x8000000f) given to $fdisplay. iverilog-12_0/ivtest/gold/fdisplay_fail_fd-vlog95.gold000066400000000000000000000001211435245347300230550ustar00rootroot00000000000000WARNING: vlog95.v:11: invalid file descriptor (0x8000000f) given to $fdisplay(). iverilog-12_0/ivtest/gold/fdisplay_fail_fd.gold000066400000000000000000000001451435245347300217400ustar00rootroot00000000000000WARNING: ./ivltests/fdisplay_fail_fd.v:4: invalid file descriptor (0x8000000f) given to $fdisplay(). iverilog-12_0/ivtest/gold/fdisplay_fail_mcd-v10.gold000066400000000000000000000001501435245347300225120ustar00rootroot00000000000000WARNING: ./ivltests/fdisplay_fail_mcd.v:4: invalid file descriptor/MCD (0x40000000) given to $fdisplay. iverilog-12_0/ivtest/gold/fdisplay_fail_mcd-vlog95.gold000066400000000000000000000001051435245347300232310ustar00rootroot00000000000000WARNING: vlog95.v:11: invalid MCD (0x40000000) given to $fdisplay(). iverilog-12_0/ivtest/gold/fdisplay_fail_mcd.gold000066400000000000000000000001321435245347300221060ustar00rootroot00000000000000WARNING: ./ivltests/fdisplay_fail_mcd.v:4: invalid MCD (0x40000000) given to $fdisplay(). iverilog-12_0/ivtest/gold/fileio.gold000066400000000000000000000000411435245347300177230ustar00rootroot00000000000000From the write. From the append. iverilog-12_0/ivtest/gold/fileline.gold000066400000000000000000000000351435245347300202460ustar00rootroot00000000000000./ivltests/fileline.v PASSED iverilog-12_0/ivtest/gold/fileline2.gold000066400000000000000000000001521435245347300203300ustar00rootroot000000000000001 -> ./ivltests/fileline2.v:1003 2 -> imaginary-include-file:2003 3 -> ./ivltests/fileline2.v:3003 PASSED iverilog-12_0/ivtest/gold/final.gold000066400000000000000000000000171435245347300175500ustar00rootroot00000000000000x = 3, PASSED iverilog-12_0/ivtest/gold/final2.gold000066400000000000000000000000271435245347300176330ustar00rootroot00000000000000Final in t Final in t2 iverilog-12_0/ivtest/gold/format-vlog95.gold000066400000000000000000000001351435245347300210730ustar00rootroot00000000000000>16< > 16< >010< > 010< WARNING: vlog95.v:21: missing argument for $display<%d>. 16, <%d> iverilog-12_0/ivtest/gold/format.gold000066400000000000000000000001501435245347300177450ustar00rootroot00000000000000>16< > 16< >010< > 010< WARNING: ./ivltests/format.v:12: missing argument for $display<%d>. 16, <%d> iverilog-12_0/ivtest/gold/fread-error-vlog95.gold000066400000000000000000000006541435245347300220210ustar00rootroot00000000000000ERROR: vlog95.v:17: $fread's first argument must be a reg or memory. ERROR: vlog95.v:18: $fread requires a second (file descriptor) argument. ERROR: vlog95.v:19: $fread's second argument must be numeric. ERROR: vlog95.v:20: $fread's third argument must be numeric. ERROR: vlog95.v:21: $fread's fourth argument must be numeric. ERROR: vlog95.v:22: $fread takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/fread-error.gold000066400000000000000000000010311435245347300206640ustar00rootroot00000000000000ERROR: ./ivltests/fread-error.v:7: $fread's first argument must be a reg or memory. ERROR: ./ivltests/fread-error.v:8: $fread requires a second (file descriptor) argument. ERROR: ./ivltests/fread-error.v:9: $fread's second argument must be numeric. ERROR: ./ivltests/fread-error.v:10: $fread's third argument must be numeric. ERROR: ./ivltests/fread-error.v:11: $fread's fourth argument must be numeric. ERROR: ./ivltests/fread-error.v:12: $fread takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/fscanf_u_warn-vlog95.gold000066400000000000000000000011061435245347300224150ustar00rootroot00000000000000WARNING: vlog95.v:27: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: vlog95.v:38: $fscanf() only found 2 of 8 bytes needed by %u format code. WARNING: vlog95.v:49: $fscanf() only found 4 of 8 bytes needed by %u format code. WARNING: vlog95.v:60: $fscanf() only found 6 of 8 bytes needed by %u format code. WARNING: vlog95.v:71: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: vlog95.v:83: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: vlog95.v:110: $fscanf() only found 2 of 4 bytes needed by %u format code. PASSED iverilog-12_0/ivtest/gold/fscanf_u_warn.gold000066400000000000000000000013041435245347300212720ustar00rootroot00000000000000WARNING: ./ivltests/fscanf_u_warn.v:16: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:29: $fscanf() only found 2 of 8 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:42: $fscanf() only found 4 of 8 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:55: $fscanf() only found 6 of 8 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:68: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:82: $fscanf() only found 2 of 4 bytes needed by %u format code. WARNING: ./ivltests/fscanf_u_warn.v:110: $fscanf() only found 2 of 4 bytes needed by %u format code. PASSED iverilog-12_0/ivtest/gold/fscanf_z_warn-vlog95.gold000066400000000000000000000011121435245347300224170ustar00rootroot00000000000000WARNING: vlog95.v:26: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: vlog95.v:37: $fscanf() only found 4 of 16 bytes needed by %z format code. WARNING: vlog95.v:48: $fscanf() only found 8 of 16 bytes needed by %z format code. WARNING: vlog95.v:59: $fscanf() only found 12 of 16 bytes needed by %z format code. WARNING: vlog95.v:70: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: vlog95.v:81: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: vlog95.v:108: $fscanf() only found 4 of 8 bytes needed by %z format code. PASSED iverilog-12_0/ivtest/gold/fscanf_z_warn.gold000066400000000000000000000013101435245347300212740ustar00rootroot00000000000000WARNING: ./ivltests/fscanf_z_warn.v:16: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:29: $fscanf() only found 4 of 16 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:42: $fscanf() only found 8 of 16 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:55: $fscanf() only found 12 of 16 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:68: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:81: $fscanf() only found 4 of 8 bytes needed by %z format code. WARNING: ./ivltests/fscanf_z_warn.v:109: $fscanf() only found 4 of 8 bytes needed by %z format code. PASSED iverilog-12_0/ivtest/gold/function1.gold000066400000000000000000000000361435245347300203660ustar00rootroot000000000000000008 = sum(0003, 0005) PASSED iverilog-12_0/ivtest/gold/function12.gold000066400000000000000000000001531435245347300204500ustar00rootroot00000000000000loop 0 loop 1 loop 2 loop 3 loop 4 loop 5 PASS iverilog-12_0/ivtest/gold/gate_connect2.gold000066400000000000000000000005441435245347300211770ustar00rootroot00000000000000./ivltests/gate_connect2.v:10: error: Expression width 32 does not match width 1 of logic gate array port 2. ./ivltests/gate_connect2.v:11: error: Expression width 2 does not match width 1 of logic gate array port 2. ./ivltests/gate_connect2.v:12: error: Expression width 2 does not match width 1 of logic gate array port 2. 3 error(s) during elaboration. iverilog-12_0/ivtest/gold/generate_multi_loop.gold000066400000000000000000000001561435245347300225200ustar00rootroot00000000000000byte_value = 00010010 00110100 01010110 01111000 bit_value = 00010010 00110100 01010110 01111000 Test passed iverilog-12_0/ivtest/gold/idiv3.gold000066400000000000000000000000141435245347300174720ustar00rootroot00000000000000 -8 -1 iverilog-12_0/ivtest/gold/indef_width_concat.gold000066400000000000000000000001741435245347300222760ustar00rootroot00000000000000./ivltests/indef_width_concat.v:4: error: Concatenation operand "'sd2" has indefinite width. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/initmod.gold000066400000000000000000000006441435245347300201300ustar00rootroot000000000000000 x 0 x : xxxx : x x x x : xxxx : x x x x 1 0 0 1 : 0x0x : 0 x 0 x : 0x0x : 0 x 0 x 0 1 1 1 : 1001 : 1 0 0 1 : 1001 : 1 0 0 1 1 0 1 0 : 0111 : 0 1 1 1 : 0111 : 0 1 1 1 0 1 0 0 : 1010 : 1 0 1 0 : 1010 : 1 0 1 0 1 0 0 1 : 0100 : 0 1 0 0 : 0100 : 0 1 0 0 0 1 1 1 : 1001 : 1 0 0 1 : 1001 : 1 0 0 1 1 0 1 0 : 0111 : 0 1 1 1 : 0111 : 0 1 1 1 0 1 0 0 : 1010 : 1 0 1 0 : 1010 : 1 0 1 0 1 0 0 1 : 0100 : 0 1 0 0 : 0100 : 0 1 0 0 iverilog-12_0/ivtest/gold/initmod2.gold000066400000000000000000000000771435245347300202120ustar00rootroot00000000000000z z x 1 x x x : x 1 1 : x z z z x 1 x x x : x 1 1 : x z PASSED iverilog-12_0/ivtest/gold/int_not_signext.gold000066400000000000000000000002511435245347300216720ustar00rootroot0000000000000016 + -1 = 4294967311, 4294967311, 4294967311, 15, -1 = 4294967310 16 + 0 = 16, 16, 16, 16, -1 = 15 16 + 1 = 17, 17, 17, 17, -1 = 16 iverilog-12_0/ivtest/gold/itor_rtoi.gold000066400000000000000000000017051435245347300204760ustar00rootroot00000000000000Testing $itor() in a constant context. $itor(10) = 10 $itor(1'bx) = 0 $itor(1'bx) = 0 $itor(10.4) = 10 $itor(10.5) = 11 $itor(-1.4) = -1 $itor(-1.5) = -2 $itor(NaN) = 0 $itor(+inf) = 0 $itor(-inf) = 0 Testing $itor() in a variable context. $itor(10) = 10 $itor(1'bx) = 0 $itor(1'bx) = 0 $itor(10.4) = 10 $itor(10.5) = 11 $itor(-1.4) = -1 $itor(-1.5) = -2 $itor(NaN) = 0 $itor(+inf) = 0 $itor(-inf) = 0 Testing $rtoi() in a constant context. $rtoi(1.1) = 1 $rtoi(1.9) = 1 $rtoi(-1.1) = -1 $rtoi(-1.9) = -1 Overflow(0) = 0 Overflow(1) = 1 $rtoi(NaN) = x $rtoi(+inf) = x $rtoi(-inf) = x $rtoi(1) = 1 $rtoi(1'bx) = 0 $rtoi(1'bz) = 0 Testing $rtoi() in a variable context. $rtoi(1.1) = 1 $rtoi(1.9) = 1 $rtoi(-1.1) = -1 $rtoi(-1.9) = -1 Overflow(0) = 0 Overflow(1) = 1 $rtoi(NaN) = x $rtoi(+inf) = x $rtoi(-inf) = x $rtoi(1) = 1 $rtoi(1'bx) = 0 $rtoi(1'bz) = 0 iverilog-12_0/ivtest/gold/ivlh_event.gold000066400000000000000000000000701435245347300206210ustar00rootroot000000000000001: EVENT on a 2: EVENT on b 3: EVENT on a 4: EVENT on b iverilog-12_0/ivtest/gold/ivlh_rising_falling.gold000066400000000000000000000002261435245347300224720ustar00rootroot000000000000001: rising_edge(a) 2: rising_edge(b) 3: falling_edge(a) 4: falling_edge(b) 7: rising_edge(a) 8: rising_edge(b) 11: falling_edge(a) 12: falling_edge(b) iverilog-12_0/ivtest/gold/land4.gold000066400000000000000000000004641435245347300174670ustar00rootroot00000000000000clk=0: ena=0, enb=0, wea=0, web=0 --> out=0 clk=1: ena=0, enb=0, wea=0, web=0 --> out=0 clk=0: ena=1, enb=1, wea=0, web=0 --> out=0 clk=1: ena=1, enb=1, wea=0, web=0 --> out=0 clk=0: ena=1, enb=1, wea=1, web=1 --> out=0 clk=1: ena=1, enb=1, wea=1, web=1 --> out=1 clk=0: ena=1, enb=1, wea=1, web=1 --> out=1 iverilog-12_0/ivtest/gold/lh_memcat.gold000066400000000000000000000000311435245347300204040ustar00rootroot00000000000000 << BEGIN >> << END >> iverilog-12_0/ivtest/gold/line_directive.gold000066400000000000000000000002741435245347300214510ustar00rootroot00000000000000file ./ivltests/line_directive.v line 8 file real_source.v line 1 file ./ivltests/line_directive_inc.v line 1 file real_source.v line 3 file real_source.v line 4 file real_source.v line 5 iverilog-12_0/ivtest/gold/long_div.gold000066400000000000000000000001721435245347300202620ustar00rootroot00000000000000Using normal math routines. Result: 1 Modulus: 00000000 Using wide math routines. Result: 1 Modulus: 00000000000000000 iverilog-12_0/ivtest/gold/macro_redefinition.gold000066400000000000000000000002741435245347300223240ustar00rootroot00000000000000./ivltests/macro_redefinition.v:4: warning: redefinition of macro MACRO from value '1' to '1' ./ivltests/macro_redefinition.v:5: warning: redefinition of macro MACRO from value '1' to '2' iverilog-12_0/ivtest/gold/macro_replacement.gold000066400000000000000000000001351435245347300221400ustar00rootroot00000000000000./ivltests/macro_replacement.v:5: warning: redefinition of macro MACRO from value '1' to '2' iverilog-12_0/ivtest/gold/macro_str_esc.gold000066400000000000000000000005611435245347300213060ustar00rootroot00000000000000Using ``celldefine gives: `celldefine Plain ``celldefine gives: `celldefine Using `DEF1 gives: string1 Using ``DEF1 gives: "string1" Plain ``DEF1 gives: "string1" Using `DEF2 gives: string2" Using ``DEF2 gives: "string2\"" Plain ``DEF2 gives: "string2\"" Using ``DEF3 gives: a\b Plain ``DEF3 gives: a\b Using ``DEF4("tmp") gives: "tmp" Plain ``DEF4("tmp") gives: "tmp" iverilog-12_0/ivtest/gold/macro_with_args.gold000066400000000000000000000001421435245347300216260ustar00rootroot00000000000000first..last first,last last..first (a)..(c) (a,b,c) (c)..(a) sumsqr(3,4) = 25 sumsqr(5,12) = 169 iverilog-12_0/ivtest/gold/mcl1.gold000066400000000000000000026000001435245347300173130ustar00rootroot000000000000000 0 00 000 1 0 00 000 2 0 00 000 3 0 00 000 4 0 00 000 5 0 00 000 6 0 00 000 7 0 00 000 8 0 00 000 9 0 00 000 a 0 00 000 b 0 00 000 c 0 00 000 d 0 00 000 e 0 00 000 f 0 00 000 0 1 00 000 1 1 00 001 2 1 00 002 3 1 00 003 4 1 00 004 5 1 00 005 6 1 00 006 7 1 00 007 8 1 00 1f8 9 1 00 1f9 a 1 00 1fa b 1 00 1fb c 1 00 1fc d 1 00 1fd e 1 00 1fe f 1 00 1ff 0 2 00 000 1 2 00 002 2 2 00 004 3 2 00 006 4 2 00 008 5 2 00 00a 6 2 00 00c 7 2 00 00e 8 2 00 1f0 9 2 00 1f2 a 2 00 1f4 b 2 00 1f6 c 2 00 1f8 d 2 00 1fa e 2 00 1fc f 2 00 1fe 0 3 00 000 1 3 00 003 2 3 00 006 3 3 00 009 4 3 00 00c 5 3 00 00f 6 3 00 012 7 3 00 015 8 3 00 1e8 9 3 00 1eb a 3 00 1ee b 3 00 1f1 c 3 00 1f4 d 3 00 1f7 e 3 00 1fa f 3 00 1fd 0 4 00 000 1 4 00 004 2 4 00 008 3 4 00 00c 4 4 00 010 5 4 00 014 6 4 00 018 7 4 00 01c 8 4 00 1e0 9 4 00 1e4 a 4 00 1e8 b 4 00 1ec c 4 00 1f0 d 4 00 1f4 e 4 00 1f8 f 4 00 1fc 0 5 00 000 1 5 00 005 2 5 00 00a 3 5 00 00f 4 5 00 014 5 5 00 019 6 5 00 01e 7 5 00 023 8 5 00 1d8 9 5 00 1dd a 5 00 1e2 b 5 00 1e7 c 5 00 1ec d 5 00 1f1 e 5 00 1f6 f 5 00 1fb 0 6 00 000 1 6 00 006 2 6 00 00c 3 6 00 012 4 6 00 018 5 6 00 01e 6 6 00 024 7 6 00 02a 8 6 00 1d0 9 6 00 1d6 a 6 00 1dc b 6 00 1e2 c 6 00 1e8 d 6 00 1ee e 6 00 1f4 f 6 00 1fa 0 7 00 000 1 7 00 007 2 7 00 00e 3 7 00 015 4 7 00 01c 5 7 00 023 6 7 00 02a 7 7 00 031 8 7 00 1c8 9 7 00 1cf a 7 00 1d6 b 7 00 1dd c 7 00 1e4 d 7 00 1eb e 7 00 1f2 f 7 00 1f9 0 8 00 000 1 8 00 1f8 2 8 00 1f0 3 8 00 1e8 4 8 00 1e0 5 8 00 1d8 6 8 00 1d0 7 8 00 1c8 8 8 00 040 9 8 00 038 a 8 00 030 b 8 00 028 c 8 00 020 d 8 00 018 e 8 00 010 f 8 00 008 0 9 00 000 1 9 00 1f9 2 9 00 1f2 3 9 00 1eb 4 9 00 1e4 5 9 00 1dd 6 9 00 1d6 7 9 00 1cf 8 9 00 038 9 9 00 031 a 9 00 02a b 9 00 023 c 9 00 01c d 9 00 015 e 9 00 00e f 9 00 007 0 a 00 000 1 a 00 1fa 2 a 00 1f4 3 a 00 1ee 4 a 00 1e8 5 a 00 1e2 6 a 00 1dc 7 a 00 1d6 8 a 00 030 9 a 00 02a a a 00 024 b a 00 01e c a 00 018 d a 00 012 e a 00 00c f a 00 006 0 b 00 000 1 b 00 1fb 2 b 00 1f6 3 b 00 1f1 4 b 00 1ec 5 b 00 1e7 6 b 00 1e2 7 b 00 1dd 8 b 00 028 9 b 00 023 a b 00 01e b b 00 019 c b 00 014 d b 00 00f e b 00 00a f b 00 005 0 c 00 000 1 c 00 1fc 2 c 00 1f8 3 c 00 1f4 4 c 00 1f0 5 c 00 1ec 6 c 00 1e8 7 c 00 1e4 8 c 00 020 9 c 00 01c a c 00 018 b c 00 014 c c 00 010 d c 00 00c e c 00 008 f c 00 004 0 d 00 000 1 d 00 1fd 2 d 00 1fa 3 d 00 1f7 4 d 00 1f4 5 d 00 1f1 6 d 00 1ee 7 d 00 1eb 8 d 00 018 9 d 00 015 a d 00 012 b d 00 00f c d 00 00c d d 00 009 e d 00 006 f d 00 003 0 e 00 000 1 e 00 1fe 2 e 00 1fc 3 e 00 1fa 4 e 00 1f8 5 e 00 1f6 6 e 00 1f4 7 e 00 1f2 8 e 00 010 9 e 00 00e a e 00 00c b e 00 00a c e 00 008 d e 00 006 e e 00 004 f e 00 002 0 f 00 000 1 f 00 1ff 2 f 00 1fe 3 f 00 1fd 4 f 00 1fc 5 f 00 1fb 6 f 00 1fa 7 f 00 1f9 8 f 00 008 9 f 00 007 a f 00 006 b f 00 005 c f 00 004 d f 00 003 e f 00 002 f f 00 001 0 0 01 001 1 0 01 001 2 0 01 001 3 0 01 001 4 0 01 001 5 0 01 001 6 0 01 001 7 0 01 001 8 0 01 001 9 0 01 001 a 0 01 001 b 0 01 001 c 0 01 001 d 0 01 001 e 0 01 001 f 0 01 001 0 1 01 001 1 1 01 002 2 1 01 003 3 1 01 004 4 1 01 005 5 1 01 006 6 1 01 007 7 1 01 008 8 1 01 1f9 9 1 01 1fa a 1 01 1fb b 1 01 1fc c 1 01 1fd d 1 01 1fe e 1 01 1ff f 1 01 000 0 2 01 001 1 2 01 003 2 2 01 005 3 2 01 007 4 2 01 009 5 2 01 00b 6 2 01 00d 7 2 01 00f 8 2 01 1f1 9 2 01 1f3 a 2 01 1f5 b 2 01 1f7 c 2 01 1f9 d 2 01 1fb e 2 01 1fd f 2 01 1ff 0 3 01 001 1 3 01 004 2 3 01 007 3 3 01 00a 4 3 01 00d 5 3 01 010 6 3 01 013 7 3 01 016 8 3 01 1e9 9 3 01 1ec a 3 01 1ef b 3 01 1f2 c 3 01 1f5 d 3 01 1f8 e 3 01 1fb f 3 01 1fe 0 4 01 001 1 4 01 005 2 4 01 009 3 4 01 00d 4 4 01 011 5 4 01 015 6 4 01 019 7 4 01 01d 8 4 01 1e1 9 4 01 1e5 a 4 01 1e9 b 4 01 1ed c 4 01 1f1 d 4 01 1f5 e 4 01 1f9 f 4 01 1fd 0 5 01 001 1 5 01 006 2 5 01 00b 3 5 01 010 4 5 01 015 5 5 01 01a 6 5 01 01f 7 5 01 024 8 5 01 1d9 9 5 01 1de a 5 01 1e3 b 5 01 1e8 c 5 01 1ed d 5 01 1f2 e 5 01 1f7 f 5 01 1fc 0 6 01 001 1 6 01 007 2 6 01 00d 3 6 01 013 4 6 01 019 5 6 01 01f 6 6 01 025 7 6 01 02b 8 6 01 1d1 9 6 01 1d7 a 6 01 1dd b 6 01 1e3 c 6 01 1e9 d 6 01 1ef e 6 01 1f5 f 6 01 1fb 0 7 01 001 1 7 01 008 2 7 01 00f 3 7 01 016 4 7 01 01d 5 7 01 024 6 7 01 02b 7 7 01 032 8 7 01 1c9 9 7 01 1d0 a 7 01 1d7 b 7 01 1de c 7 01 1e5 d 7 01 1ec e 7 01 1f3 f 7 01 1fa 0 8 01 001 1 8 01 1f9 2 8 01 1f1 3 8 01 1e9 4 8 01 1e1 5 8 01 1d9 6 8 01 1d1 7 8 01 1c9 8 8 01 041 9 8 01 039 a 8 01 031 b 8 01 029 c 8 01 021 d 8 01 019 e 8 01 011 f 8 01 009 0 9 01 001 1 9 01 1fa 2 9 01 1f3 3 9 01 1ec 4 9 01 1e5 5 9 01 1de 6 9 01 1d7 7 9 01 1d0 8 9 01 039 9 9 01 032 a 9 01 02b b 9 01 024 c 9 01 01d d 9 01 016 e 9 01 00f f 9 01 008 0 a 01 001 1 a 01 1fb 2 a 01 1f5 3 a 01 1ef 4 a 01 1e9 5 a 01 1e3 6 a 01 1dd 7 a 01 1d7 8 a 01 031 9 a 01 02b a a 01 025 b a 01 01f c a 01 019 d a 01 013 e a 01 00d f a 01 007 0 b 01 001 1 b 01 1fc 2 b 01 1f7 3 b 01 1f2 4 b 01 1ed 5 b 01 1e8 6 b 01 1e3 7 b 01 1de 8 b 01 029 9 b 01 024 a b 01 01f b b 01 01a c b 01 015 d b 01 010 e b 01 00b f b 01 006 0 c 01 001 1 c 01 1fd 2 c 01 1f9 3 c 01 1f5 4 c 01 1f1 5 c 01 1ed 6 c 01 1e9 7 c 01 1e5 8 c 01 021 9 c 01 01d a c 01 019 b c 01 015 c c 01 011 d c 01 00d e c 01 009 f c 01 005 0 d 01 001 1 d 01 1fe 2 d 01 1fb 3 d 01 1f8 4 d 01 1f5 5 d 01 1f2 6 d 01 1ef 7 d 01 1ec 8 d 01 019 9 d 01 016 a d 01 013 b d 01 010 c d 01 00d d d 01 00a e d 01 007 f d 01 004 0 e 01 001 1 e 01 1ff 2 e 01 1fd 3 e 01 1fb 4 e 01 1f9 5 e 01 1f7 6 e 01 1f5 7 e 01 1f3 8 e 01 011 9 e 01 00f a e 01 00d b e 01 00b c e 01 009 d e 01 007 e e 01 005 f e 01 003 0 f 01 001 1 f 01 000 2 f 01 1ff 3 f 01 1fe 4 f 01 1fd 5 f 01 1fc 6 f 01 1fb 7 f 01 1fa 8 f 01 009 9 f 01 008 a f 01 007 b f 01 006 c f 01 005 d f 01 004 e f 01 003 f f 01 002 0 0 02 002 1 0 02 002 2 0 02 002 3 0 02 002 4 0 02 002 5 0 02 002 6 0 02 002 7 0 02 002 8 0 02 002 9 0 02 002 a 0 02 002 b 0 02 002 c 0 02 002 d 0 02 002 e 0 02 002 f 0 02 002 0 1 02 002 1 1 02 003 2 1 02 004 3 1 02 005 4 1 02 006 5 1 02 007 6 1 02 008 7 1 02 009 8 1 02 1fa 9 1 02 1fb a 1 02 1fc b 1 02 1fd c 1 02 1fe d 1 02 1ff e 1 02 000 f 1 02 001 0 2 02 002 1 2 02 004 2 2 02 006 3 2 02 008 4 2 02 00a 5 2 02 00c 6 2 02 00e 7 2 02 010 8 2 02 1f2 9 2 02 1f4 a 2 02 1f6 b 2 02 1f8 c 2 02 1fa d 2 02 1fc e 2 02 1fe f 2 02 000 0 3 02 002 1 3 02 005 2 3 02 008 3 3 02 00b 4 3 02 00e 5 3 02 011 6 3 02 014 7 3 02 017 8 3 02 1ea 9 3 02 1ed a 3 02 1f0 b 3 02 1f3 c 3 02 1f6 d 3 02 1f9 e 3 02 1fc f 3 02 1ff 0 4 02 002 1 4 02 006 2 4 02 00a 3 4 02 00e 4 4 02 012 5 4 02 016 6 4 02 01a 7 4 02 01e 8 4 02 1e2 9 4 02 1e6 a 4 02 1ea b 4 02 1ee c 4 02 1f2 d 4 02 1f6 e 4 02 1fa f 4 02 1fe 0 5 02 002 1 5 02 007 2 5 02 00c 3 5 02 011 4 5 02 016 5 5 02 01b 6 5 02 020 7 5 02 025 8 5 02 1da 9 5 02 1df a 5 02 1e4 b 5 02 1e9 c 5 02 1ee d 5 02 1f3 e 5 02 1f8 f 5 02 1fd 0 6 02 002 1 6 02 008 2 6 02 00e 3 6 02 014 4 6 02 01a 5 6 02 020 6 6 02 026 7 6 02 02c 8 6 02 1d2 9 6 02 1d8 a 6 02 1de b 6 02 1e4 c 6 02 1ea d 6 02 1f0 e 6 02 1f6 f 6 02 1fc 0 7 02 002 1 7 02 009 2 7 02 010 3 7 02 017 4 7 02 01e 5 7 02 025 6 7 02 02c 7 7 02 033 8 7 02 1ca 9 7 02 1d1 a 7 02 1d8 b 7 02 1df c 7 02 1e6 d 7 02 1ed e 7 02 1f4 f 7 02 1fb 0 8 02 002 1 8 02 1fa 2 8 02 1f2 3 8 02 1ea 4 8 02 1e2 5 8 02 1da 6 8 02 1d2 7 8 02 1ca 8 8 02 042 9 8 02 03a a 8 02 032 b 8 02 02a c 8 02 022 d 8 02 01a e 8 02 012 f 8 02 00a 0 9 02 002 1 9 02 1fb 2 9 02 1f4 3 9 02 1ed 4 9 02 1e6 5 9 02 1df 6 9 02 1d8 7 9 02 1d1 8 9 02 03a 9 9 02 033 a 9 02 02c b 9 02 025 c 9 02 01e d 9 02 017 e 9 02 010 f 9 02 009 0 a 02 002 1 a 02 1fc 2 a 02 1f6 3 a 02 1f0 4 a 02 1ea 5 a 02 1e4 6 a 02 1de 7 a 02 1d8 8 a 02 032 9 a 02 02c a a 02 026 b a 02 020 c a 02 01a d a 02 014 e a 02 00e f a 02 008 0 b 02 002 1 b 02 1fd 2 b 02 1f8 3 b 02 1f3 4 b 02 1ee 5 b 02 1e9 6 b 02 1e4 7 b 02 1df 8 b 02 02a 9 b 02 025 a b 02 020 b b 02 01b c b 02 016 d b 02 011 e b 02 00c f b 02 007 0 c 02 002 1 c 02 1fe 2 c 02 1fa 3 c 02 1f6 4 c 02 1f2 5 c 02 1ee 6 c 02 1ea 7 c 02 1e6 8 c 02 022 9 c 02 01e a c 02 01a b c 02 016 c c 02 012 d c 02 00e e c 02 00a f c 02 006 0 d 02 002 1 d 02 1ff 2 d 02 1fc 3 d 02 1f9 4 d 02 1f6 5 d 02 1f3 6 d 02 1f0 7 d 02 1ed 8 d 02 01a 9 d 02 017 a d 02 014 b d 02 011 c d 02 00e d d 02 00b e d 02 008 f d 02 005 0 e 02 002 1 e 02 000 2 e 02 1fe 3 e 02 1fc 4 e 02 1fa 5 e 02 1f8 6 e 02 1f6 7 e 02 1f4 8 e 02 012 9 e 02 010 a e 02 00e b e 02 00c c e 02 00a d e 02 008 e e 02 006 f e 02 004 0 f 02 002 1 f 02 001 2 f 02 000 3 f 02 1ff 4 f 02 1fe 5 f 02 1fd 6 f 02 1fc 7 f 02 1fb 8 f 02 00a 9 f 02 009 a f 02 008 b f 02 007 c f 02 006 d f 02 005 e f 02 004 f f 02 003 0 0 03 003 1 0 03 003 2 0 03 003 3 0 03 003 4 0 03 003 5 0 03 003 6 0 03 003 7 0 03 003 8 0 03 003 9 0 03 003 a 0 03 003 b 0 03 003 c 0 03 003 d 0 03 003 e 0 03 003 f 0 03 003 0 1 03 003 1 1 03 004 2 1 03 005 3 1 03 006 4 1 03 007 5 1 03 008 6 1 03 009 7 1 03 00a 8 1 03 1fb 9 1 03 1fc a 1 03 1fd b 1 03 1fe c 1 03 1ff d 1 03 000 e 1 03 001 f 1 03 002 0 2 03 003 1 2 03 005 2 2 03 007 3 2 03 009 4 2 03 00b 5 2 03 00d 6 2 03 00f 7 2 03 011 8 2 03 1f3 9 2 03 1f5 a 2 03 1f7 b 2 03 1f9 c 2 03 1fb d 2 03 1fd e 2 03 1ff f 2 03 001 0 3 03 003 1 3 03 006 2 3 03 009 3 3 03 00c 4 3 03 00f 5 3 03 012 6 3 03 015 7 3 03 018 8 3 03 1eb 9 3 03 1ee a 3 03 1f1 b 3 03 1f4 c 3 03 1f7 d 3 03 1fa e 3 03 1fd f 3 03 000 0 4 03 003 1 4 03 007 2 4 03 00b 3 4 03 00f 4 4 03 013 5 4 03 017 6 4 03 01b 7 4 03 01f 8 4 03 1e3 9 4 03 1e7 a 4 03 1eb b 4 03 1ef c 4 03 1f3 d 4 03 1f7 e 4 03 1fb f 4 03 1ff 0 5 03 003 1 5 03 008 2 5 03 00d 3 5 03 012 4 5 03 017 5 5 03 01c 6 5 03 021 7 5 03 026 8 5 03 1db 9 5 03 1e0 a 5 03 1e5 b 5 03 1ea c 5 03 1ef d 5 03 1f4 e 5 03 1f9 f 5 03 1fe 0 6 03 003 1 6 03 009 2 6 03 00f 3 6 03 015 4 6 03 01b 5 6 03 021 6 6 03 027 7 6 03 02d 8 6 03 1d3 9 6 03 1d9 a 6 03 1df b 6 03 1e5 c 6 03 1eb d 6 03 1f1 e 6 03 1f7 f 6 03 1fd 0 7 03 003 1 7 03 00a 2 7 03 011 3 7 03 018 4 7 03 01f 5 7 03 026 6 7 03 02d 7 7 03 034 8 7 03 1cb 9 7 03 1d2 a 7 03 1d9 b 7 03 1e0 c 7 03 1e7 d 7 03 1ee e 7 03 1f5 f 7 03 1fc 0 8 03 003 1 8 03 1fb 2 8 03 1f3 3 8 03 1eb 4 8 03 1e3 5 8 03 1db 6 8 03 1d3 7 8 03 1cb 8 8 03 043 9 8 03 03b a 8 03 033 b 8 03 02b c 8 03 023 d 8 03 01b e 8 03 013 f 8 03 00b 0 9 03 003 1 9 03 1fc 2 9 03 1f5 3 9 03 1ee 4 9 03 1e7 5 9 03 1e0 6 9 03 1d9 7 9 03 1d2 8 9 03 03b 9 9 03 034 a 9 03 02d b 9 03 026 c 9 03 01f d 9 03 018 e 9 03 011 f 9 03 00a 0 a 03 003 1 a 03 1fd 2 a 03 1f7 3 a 03 1f1 4 a 03 1eb 5 a 03 1e5 6 a 03 1df 7 a 03 1d9 8 a 03 033 9 a 03 02d a a 03 027 b a 03 021 c a 03 01b d a 03 015 e a 03 00f f a 03 009 0 b 03 003 1 b 03 1fe 2 b 03 1f9 3 b 03 1f4 4 b 03 1ef 5 b 03 1ea 6 b 03 1e5 7 b 03 1e0 8 b 03 02b 9 b 03 026 a b 03 021 b b 03 01c c b 03 017 d b 03 012 e b 03 00d f b 03 008 0 c 03 003 1 c 03 1ff 2 c 03 1fb 3 c 03 1f7 4 c 03 1f3 5 c 03 1ef 6 c 03 1eb 7 c 03 1e7 8 c 03 023 9 c 03 01f a c 03 01b b c 03 017 c c 03 013 d c 03 00f e c 03 00b f c 03 007 0 d 03 003 1 d 03 000 2 d 03 1fd 3 d 03 1fa 4 d 03 1f7 5 d 03 1f4 6 d 03 1f1 7 d 03 1ee 8 d 03 01b 9 d 03 018 a d 03 015 b d 03 012 c d 03 00f d d 03 00c e d 03 009 f d 03 006 0 e 03 003 1 e 03 001 2 e 03 1ff 3 e 03 1fd 4 e 03 1fb 5 e 03 1f9 6 e 03 1f7 7 e 03 1f5 8 e 03 013 9 e 03 011 a e 03 00f b e 03 00d c e 03 00b d e 03 009 e e 03 007 f e 03 005 0 f 03 003 1 f 03 002 2 f 03 001 3 f 03 000 4 f 03 1ff 5 f 03 1fe 6 f 03 1fd 7 f 03 1fc 8 f 03 00b 9 f 03 00a a f 03 009 b f 03 008 c f 03 007 d f 03 006 e f 03 005 f f 03 004 0 0 04 004 1 0 04 004 2 0 04 004 3 0 04 004 4 0 04 004 5 0 04 004 6 0 04 004 7 0 04 004 8 0 04 004 9 0 04 004 a 0 04 004 b 0 04 004 c 0 04 004 d 0 04 004 e 0 04 004 f 0 04 004 0 1 04 004 1 1 04 005 2 1 04 006 3 1 04 007 4 1 04 008 5 1 04 009 6 1 04 00a 7 1 04 00b 8 1 04 1fc 9 1 04 1fd a 1 04 1fe b 1 04 1ff c 1 04 000 d 1 04 001 e 1 04 002 f 1 04 003 0 2 04 004 1 2 04 006 2 2 04 008 3 2 04 00a 4 2 04 00c 5 2 04 00e 6 2 04 010 7 2 04 012 8 2 04 1f4 9 2 04 1f6 a 2 04 1f8 b 2 04 1fa c 2 04 1fc d 2 04 1fe e 2 04 000 f 2 04 002 0 3 04 004 1 3 04 007 2 3 04 00a 3 3 04 00d 4 3 04 010 5 3 04 013 6 3 04 016 7 3 04 019 8 3 04 1ec 9 3 04 1ef a 3 04 1f2 b 3 04 1f5 c 3 04 1f8 d 3 04 1fb e 3 04 1fe f 3 04 001 0 4 04 004 1 4 04 008 2 4 04 00c 3 4 04 010 4 4 04 014 5 4 04 018 6 4 04 01c 7 4 04 020 8 4 04 1e4 9 4 04 1e8 a 4 04 1ec b 4 04 1f0 c 4 04 1f4 d 4 04 1f8 e 4 04 1fc f 4 04 000 0 5 04 004 1 5 04 009 2 5 04 00e 3 5 04 013 4 5 04 018 5 5 04 01d 6 5 04 022 7 5 04 027 8 5 04 1dc 9 5 04 1e1 a 5 04 1e6 b 5 04 1eb c 5 04 1f0 d 5 04 1f5 e 5 04 1fa f 5 04 1ff 0 6 04 004 1 6 04 00a 2 6 04 010 3 6 04 016 4 6 04 01c 5 6 04 022 6 6 04 028 7 6 04 02e 8 6 04 1d4 9 6 04 1da a 6 04 1e0 b 6 04 1e6 c 6 04 1ec d 6 04 1f2 e 6 04 1f8 f 6 04 1fe 0 7 04 004 1 7 04 00b 2 7 04 012 3 7 04 019 4 7 04 020 5 7 04 027 6 7 04 02e 7 7 04 035 8 7 04 1cc 9 7 04 1d3 a 7 04 1da b 7 04 1e1 c 7 04 1e8 d 7 04 1ef e 7 04 1f6 f 7 04 1fd 0 8 04 004 1 8 04 1fc 2 8 04 1f4 3 8 04 1ec 4 8 04 1e4 5 8 04 1dc 6 8 04 1d4 7 8 04 1cc 8 8 04 044 9 8 04 03c a 8 04 034 b 8 04 02c c 8 04 024 d 8 04 01c e 8 04 014 f 8 04 00c 0 9 04 004 1 9 04 1fd 2 9 04 1f6 3 9 04 1ef 4 9 04 1e8 5 9 04 1e1 6 9 04 1da 7 9 04 1d3 8 9 04 03c 9 9 04 035 a 9 04 02e b 9 04 027 c 9 04 020 d 9 04 019 e 9 04 012 f 9 04 00b 0 a 04 004 1 a 04 1fe 2 a 04 1f8 3 a 04 1f2 4 a 04 1ec 5 a 04 1e6 6 a 04 1e0 7 a 04 1da 8 a 04 034 9 a 04 02e a a 04 028 b a 04 022 c a 04 01c d a 04 016 e a 04 010 f a 04 00a 0 b 04 004 1 b 04 1ff 2 b 04 1fa 3 b 04 1f5 4 b 04 1f0 5 b 04 1eb 6 b 04 1e6 7 b 04 1e1 8 b 04 02c 9 b 04 027 a b 04 022 b b 04 01d c b 04 018 d b 04 013 e b 04 00e f b 04 009 0 c 04 004 1 c 04 000 2 c 04 1fc 3 c 04 1f8 4 c 04 1f4 5 c 04 1f0 6 c 04 1ec 7 c 04 1e8 8 c 04 024 9 c 04 020 a c 04 01c b c 04 018 c c 04 014 d c 04 010 e c 04 00c f c 04 008 0 d 04 004 1 d 04 001 2 d 04 1fe 3 d 04 1fb 4 d 04 1f8 5 d 04 1f5 6 d 04 1f2 7 d 04 1ef 8 d 04 01c 9 d 04 019 a d 04 016 b d 04 013 c d 04 010 d d 04 00d e d 04 00a f d 04 007 0 e 04 004 1 e 04 002 2 e 04 000 3 e 04 1fe 4 e 04 1fc 5 e 04 1fa 6 e 04 1f8 7 e 04 1f6 8 e 04 014 9 e 04 012 a e 04 010 b e 04 00e c e 04 00c d e 04 00a e e 04 008 f e 04 006 0 f 04 004 1 f 04 003 2 f 04 002 3 f 04 001 4 f 04 000 5 f 04 1ff 6 f 04 1fe 7 f 04 1fd 8 f 04 00c 9 f 04 00b a f 04 00a b f 04 009 c f 04 008 d f 04 007 e f 04 006 f f 04 005 0 0 05 005 1 0 05 005 2 0 05 005 3 0 05 005 4 0 05 005 5 0 05 005 6 0 05 005 7 0 05 005 8 0 05 005 9 0 05 005 a 0 05 005 b 0 05 005 c 0 05 005 d 0 05 005 e 0 05 005 f 0 05 005 0 1 05 005 1 1 05 006 2 1 05 007 3 1 05 008 4 1 05 009 5 1 05 00a 6 1 05 00b 7 1 05 00c 8 1 05 1fd 9 1 05 1fe a 1 05 1ff b 1 05 000 c 1 05 001 d 1 05 002 e 1 05 003 f 1 05 004 0 2 05 005 1 2 05 007 2 2 05 009 3 2 05 00b 4 2 05 00d 5 2 05 00f 6 2 05 011 7 2 05 013 8 2 05 1f5 9 2 05 1f7 a 2 05 1f9 b 2 05 1fb c 2 05 1fd d 2 05 1ff e 2 05 001 f 2 05 003 0 3 05 005 1 3 05 008 2 3 05 00b 3 3 05 00e 4 3 05 011 5 3 05 014 6 3 05 017 7 3 05 01a 8 3 05 1ed 9 3 05 1f0 a 3 05 1f3 b 3 05 1f6 c 3 05 1f9 d 3 05 1fc e 3 05 1ff f 3 05 002 0 4 05 005 1 4 05 009 2 4 05 00d 3 4 05 011 4 4 05 015 5 4 05 019 6 4 05 01d 7 4 05 021 8 4 05 1e5 9 4 05 1e9 a 4 05 1ed b 4 05 1f1 c 4 05 1f5 d 4 05 1f9 e 4 05 1fd f 4 05 001 0 5 05 005 1 5 05 00a 2 5 05 00f 3 5 05 014 4 5 05 019 5 5 05 01e 6 5 05 023 7 5 05 028 8 5 05 1dd 9 5 05 1e2 a 5 05 1e7 b 5 05 1ec c 5 05 1f1 d 5 05 1f6 e 5 05 1fb f 5 05 000 0 6 05 005 1 6 05 00b 2 6 05 011 3 6 05 017 4 6 05 01d 5 6 05 023 6 6 05 029 7 6 05 02f 8 6 05 1d5 9 6 05 1db a 6 05 1e1 b 6 05 1e7 c 6 05 1ed d 6 05 1f3 e 6 05 1f9 f 6 05 1ff 0 7 05 005 1 7 05 00c 2 7 05 013 3 7 05 01a 4 7 05 021 5 7 05 028 6 7 05 02f 7 7 05 036 8 7 05 1cd 9 7 05 1d4 a 7 05 1db b 7 05 1e2 c 7 05 1e9 d 7 05 1f0 e 7 05 1f7 f 7 05 1fe 0 8 05 005 1 8 05 1fd 2 8 05 1f5 3 8 05 1ed 4 8 05 1e5 5 8 05 1dd 6 8 05 1d5 7 8 05 1cd 8 8 05 045 9 8 05 03d a 8 05 035 b 8 05 02d c 8 05 025 d 8 05 01d e 8 05 015 f 8 05 00d 0 9 05 005 1 9 05 1fe 2 9 05 1f7 3 9 05 1f0 4 9 05 1e9 5 9 05 1e2 6 9 05 1db 7 9 05 1d4 8 9 05 03d 9 9 05 036 a 9 05 02f b 9 05 028 c 9 05 021 d 9 05 01a e 9 05 013 f 9 05 00c 0 a 05 005 1 a 05 1ff 2 a 05 1f9 3 a 05 1f3 4 a 05 1ed 5 a 05 1e7 6 a 05 1e1 7 a 05 1db 8 a 05 035 9 a 05 02f a a 05 029 b a 05 023 c a 05 01d d a 05 017 e a 05 011 f a 05 00b 0 b 05 005 1 b 05 000 2 b 05 1fb 3 b 05 1f6 4 b 05 1f1 5 b 05 1ec 6 b 05 1e7 7 b 05 1e2 8 b 05 02d 9 b 05 028 a b 05 023 b b 05 01e c b 05 019 d b 05 014 e b 05 00f f b 05 00a 0 c 05 005 1 c 05 001 2 c 05 1fd 3 c 05 1f9 4 c 05 1f5 5 c 05 1f1 6 c 05 1ed 7 c 05 1e9 8 c 05 025 9 c 05 021 a c 05 01d b c 05 019 c c 05 015 d c 05 011 e c 05 00d f c 05 009 0 d 05 005 1 d 05 002 2 d 05 1ff 3 d 05 1fc 4 d 05 1f9 5 d 05 1f6 6 d 05 1f3 7 d 05 1f0 8 d 05 01d 9 d 05 01a a d 05 017 b d 05 014 c d 05 011 d d 05 00e e d 05 00b f d 05 008 0 e 05 005 1 e 05 003 2 e 05 001 3 e 05 1ff 4 e 05 1fd 5 e 05 1fb 6 e 05 1f9 7 e 05 1f7 8 e 05 015 9 e 05 013 a e 05 011 b e 05 00f c e 05 00d d e 05 00b e e 05 009 f e 05 007 0 f 05 005 1 f 05 004 2 f 05 003 3 f 05 002 4 f 05 001 5 f 05 000 6 f 05 1ff 7 f 05 1fe 8 f 05 00d 9 f 05 00c a f 05 00b b f 05 00a c f 05 009 d f 05 008 e f 05 007 f f 05 006 0 0 06 006 1 0 06 006 2 0 06 006 3 0 06 006 4 0 06 006 5 0 06 006 6 0 06 006 7 0 06 006 8 0 06 006 9 0 06 006 a 0 06 006 b 0 06 006 c 0 06 006 d 0 06 006 e 0 06 006 f 0 06 006 0 1 06 006 1 1 06 007 2 1 06 008 3 1 06 009 4 1 06 00a 5 1 06 00b 6 1 06 00c 7 1 06 00d 8 1 06 1fe 9 1 06 1ff a 1 06 000 b 1 06 001 c 1 06 002 d 1 06 003 e 1 06 004 f 1 06 005 0 2 06 006 1 2 06 008 2 2 06 00a 3 2 06 00c 4 2 06 00e 5 2 06 010 6 2 06 012 7 2 06 014 8 2 06 1f6 9 2 06 1f8 a 2 06 1fa b 2 06 1fc c 2 06 1fe d 2 06 000 e 2 06 002 f 2 06 004 0 3 06 006 1 3 06 009 2 3 06 00c 3 3 06 00f 4 3 06 012 5 3 06 015 6 3 06 018 7 3 06 01b 8 3 06 1ee 9 3 06 1f1 a 3 06 1f4 b 3 06 1f7 c 3 06 1fa d 3 06 1fd e 3 06 000 f 3 06 003 0 4 06 006 1 4 06 00a 2 4 06 00e 3 4 06 012 4 4 06 016 5 4 06 01a 6 4 06 01e 7 4 06 022 8 4 06 1e6 9 4 06 1ea a 4 06 1ee b 4 06 1f2 c 4 06 1f6 d 4 06 1fa e 4 06 1fe f 4 06 002 0 5 06 006 1 5 06 00b 2 5 06 010 3 5 06 015 4 5 06 01a 5 5 06 01f 6 5 06 024 7 5 06 029 8 5 06 1de 9 5 06 1e3 a 5 06 1e8 b 5 06 1ed c 5 06 1f2 d 5 06 1f7 e 5 06 1fc f 5 06 001 0 6 06 006 1 6 06 00c 2 6 06 012 3 6 06 018 4 6 06 01e 5 6 06 024 6 6 06 02a 7 6 06 030 8 6 06 1d6 9 6 06 1dc a 6 06 1e2 b 6 06 1e8 c 6 06 1ee d 6 06 1f4 e 6 06 1fa f 6 06 000 0 7 06 006 1 7 06 00d 2 7 06 014 3 7 06 01b 4 7 06 022 5 7 06 029 6 7 06 030 7 7 06 037 8 7 06 1ce 9 7 06 1d5 a 7 06 1dc b 7 06 1e3 c 7 06 1ea d 7 06 1f1 e 7 06 1f8 f 7 06 1ff 0 8 06 006 1 8 06 1fe 2 8 06 1f6 3 8 06 1ee 4 8 06 1e6 5 8 06 1de 6 8 06 1d6 7 8 06 1ce 8 8 06 046 9 8 06 03e a 8 06 036 b 8 06 02e c 8 06 026 d 8 06 01e e 8 06 016 f 8 06 00e 0 9 06 006 1 9 06 1ff 2 9 06 1f8 3 9 06 1f1 4 9 06 1ea 5 9 06 1e3 6 9 06 1dc 7 9 06 1d5 8 9 06 03e 9 9 06 037 a 9 06 030 b 9 06 029 c 9 06 022 d 9 06 01b e 9 06 014 f 9 06 00d 0 a 06 006 1 a 06 000 2 a 06 1fa 3 a 06 1f4 4 a 06 1ee 5 a 06 1e8 6 a 06 1e2 7 a 06 1dc 8 a 06 036 9 a 06 030 a a 06 02a b a 06 024 c a 06 01e d a 06 018 e a 06 012 f a 06 00c 0 b 06 006 1 b 06 001 2 b 06 1fc 3 b 06 1f7 4 b 06 1f2 5 b 06 1ed 6 b 06 1e8 7 b 06 1e3 8 b 06 02e 9 b 06 029 a b 06 024 b b 06 01f c b 06 01a d b 06 015 e b 06 010 f b 06 00b 0 c 06 006 1 c 06 002 2 c 06 1fe 3 c 06 1fa 4 c 06 1f6 5 c 06 1f2 6 c 06 1ee 7 c 06 1ea 8 c 06 026 9 c 06 022 a c 06 01e b c 06 01a c c 06 016 d c 06 012 e c 06 00e f c 06 00a 0 d 06 006 1 d 06 003 2 d 06 000 3 d 06 1fd 4 d 06 1fa 5 d 06 1f7 6 d 06 1f4 7 d 06 1f1 8 d 06 01e 9 d 06 01b a d 06 018 b d 06 015 c d 06 012 d d 06 00f e d 06 00c f d 06 009 0 e 06 006 1 e 06 004 2 e 06 002 3 e 06 000 4 e 06 1fe 5 e 06 1fc 6 e 06 1fa 7 e 06 1f8 8 e 06 016 9 e 06 014 a e 06 012 b e 06 010 c e 06 00e d e 06 00c e e 06 00a f e 06 008 0 f 06 006 1 f 06 005 2 f 06 004 3 f 06 003 4 f 06 002 5 f 06 001 6 f 06 000 7 f 06 1ff 8 f 06 00e 9 f 06 00d a f 06 00c b f 06 00b c f 06 00a d f 06 009 e f 06 008 f f 06 007 0 0 07 007 1 0 07 007 2 0 07 007 3 0 07 007 4 0 07 007 5 0 07 007 6 0 07 007 7 0 07 007 8 0 07 007 9 0 07 007 a 0 07 007 b 0 07 007 c 0 07 007 d 0 07 007 e 0 07 007 f 0 07 007 0 1 07 007 1 1 07 008 2 1 07 009 3 1 07 00a 4 1 07 00b 5 1 07 00c 6 1 07 00d 7 1 07 00e 8 1 07 1ff 9 1 07 000 a 1 07 001 b 1 07 002 c 1 07 003 d 1 07 004 e 1 07 005 f 1 07 006 0 2 07 007 1 2 07 009 2 2 07 00b 3 2 07 00d 4 2 07 00f 5 2 07 011 6 2 07 013 7 2 07 015 8 2 07 1f7 9 2 07 1f9 a 2 07 1fb b 2 07 1fd c 2 07 1ff d 2 07 001 e 2 07 003 f 2 07 005 0 3 07 007 1 3 07 00a 2 3 07 00d 3 3 07 010 4 3 07 013 5 3 07 016 6 3 07 019 7 3 07 01c 8 3 07 1ef 9 3 07 1f2 a 3 07 1f5 b 3 07 1f8 c 3 07 1fb d 3 07 1fe e 3 07 001 f 3 07 004 0 4 07 007 1 4 07 00b 2 4 07 00f 3 4 07 013 4 4 07 017 5 4 07 01b 6 4 07 01f 7 4 07 023 8 4 07 1e7 9 4 07 1eb a 4 07 1ef b 4 07 1f3 c 4 07 1f7 d 4 07 1fb e 4 07 1ff f 4 07 003 0 5 07 007 1 5 07 00c 2 5 07 011 3 5 07 016 4 5 07 01b 5 5 07 020 6 5 07 025 7 5 07 02a 8 5 07 1df 9 5 07 1e4 a 5 07 1e9 b 5 07 1ee c 5 07 1f3 d 5 07 1f8 e 5 07 1fd f 5 07 002 0 6 07 007 1 6 07 00d 2 6 07 013 3 6 07 019 4 6 07 01f 5 6 07 025 6 6 07 02b 7 6 07 031 8 6 07 1d7 9 6 07 1dd a 6 07 1e3 b 6 07 1e9 c 6 07 1ef d 6 07 1f5 e 6 07 1fb f 6 07 001 0 7 07 007 1 7 07 00e 2 7 07 015 3 7 07 01c 4 7 07 023 5 7 07 02a 6 7 07 031 7 7 07 038 8 7 07 1cf 9 7 07 1d6 a 7 07 1dd b 7 07 1e4 c 7 07 1eb d 7 07 1f2 e 7 07 1f9 f 7 07 000 0 8 07 007 1 8 07 1ff 2 8 07 1f7 3 8 07 1ef 4 8 07 1e7 5 8 07 1df 6 8 07 1d7 7 8 07 1cf 8 8 07 047 9 8 07 03f a 8 07 037 b 8 07 02f c 8 07 027 d 8 07 01f e 8 07 017 f 8 07 00f 0 9 07 007 1 9 07 000 2 9 07 1f9 3 9 07 1f2 4 9 07 1eb 5 9 07 1e4 6 9 07 1dd 7 9 07 1d6 8 9 07 03f 9 9 07 038 a 9 07 031 b 9 07 02a c 9 07 023 d 9 07 01c e 9 07 015 f 9 07 00e 0 a 07 007 1 a 07 001 2 a 07 1fb 3 a 07 1f5 4 a 07 1ef 5 a 07 1e9 6 a 07 1e3 7 a 07 1dd 8 a 07 037 9 a 07 031 a a 07 02b b a 07 025 c a 07 01f d a 07 019 e a 07 013 f a 07 00d 0 b 07 007 1 b 07 002 2 b 07 1fd 3 b 07 1f8 4 b 07 1f3 5 b 07 1ee 6 b 07 1e9 7 b 07 1e4 8 b 07 02f 9 b 07 02a a b 07 025 b b 07 020 c b 07 01b d b 07 016 e b 07 011 f b 07 00c 0 c 07 007 1 c 07 003 2 c 07 1ff 3 c 07 1fb 4 c 07 1f7 5 c 07 1f3 6 c 07 1ef 7 c 07 1eb 8 c 07 027 9 c 07 023 a c 07 01f b c 07 01b c c 07 017 d c 07 013 e c 07 00f f c 07 00b 0 d 07 007 1 d 07 004 2 d 07 001 3 d 07 1fe 4 d 07 1fb 5 d 07 1f8 6 d 07 1f5 7 d 07 1f2 8 d 07 01f 9 d 07 01c a d 07 019 b d 07 016 c d 07 013 d d 07 010 e d 07 00d f d 07 00a 0 e 07 007 1 e 07 005 2 e 07 003 3 e 07 001 4 e 07 1ff 5 e 07 1fd 6 e 07 1fb 7 e 07 1f9 8 e 07 017 9 e 07 015 a e 07 013 b e 07 011 c e 07 00f d e 07 00d e e 07 00b f e 07 009 0 f 07 007 1 f 07 006 2 f 07 005 3 f 07 004 4 f 07 003 5 f 07 002 6 f 07 001 7 f 07 000 8 f 07 00f 9 f 07 00e a f 07 00d b f 07 00c c f 07 00b d f 07 00a e f 07 009 f f 07 008 0 0 08 008 1 0 08 008 2 0 08 008 3 0 08 008 4 0 08 008 5 0 08 008 6 0 08 008 7 0 08 008 8 0 08 008 9 0 08 008 a 0 08 008 b 0 08 008 c 0 08 008 d 0 08 008 e 0 08 008 f 0 08 008 0 1 08 008 1 1 08 009 2 1 08 00a 3 1 08 00b 4 1 08 00c 5 1 08 00d 6 1 08 00e 7 1 08 00f 8 1 08 000 9 1 08 001 a 1 08 002 b 1 08 003 c 1 08 004 d 1 08 005 e 1 08 006 f 1 08 007 0 2 08 008 1 2 08 00a 2 2 08 00c 3 2 08 00e 4 2 08 010 5 2 08 012 6 2 08 014 7 2 08 016 8 2 08 1f8 9 2 08 1fa a 2 08 1fc b 2 08 1fe c 2 08 000 d 2 08 002 e 2 08 004 f 2 08 006 0 3 08 008 1 3 08 00b 2 3 08 00e 3 3 08 011 4 3 08 014 5 3 08 017 6 3 08 01a 7 3 08 01d 8 3 08 1f0 9 3 08 1f3 a 3 08 1f6 b 3 08 1f9 c 3 08 1fc d 3 08 1ff e 3 08 002 f 3 08 005 0 4 08 008 1 4 08 00c 2 4 08 010 3 4 08 014 4 4 08 018 5 4 08 01c 6 4 08 020 7 4 08 024 8 4 08 1e8 9 4 08 1ec a 4 08 1f0 b 4 08 1f4 c 4 08 1f8 d 4 08 1fc e 4 08 000 f 4 08 004 0 5 08 008 1 5 08 00d 2 5 08 012 3 5 08 017 4 5 08 01c 5 5 08 021 6 5 08 026 7 5 08 02b 8 5 08 1e0 9 5 08 1e5 a 5 08 1ea b 5 08 1ef c 5 08 1f4 d 5 08 1f9 e 5 08 1fe f 5 08 003 0 6 08 008 1 6 08 00e 2 6 08 014 3 6 08 01a 4 6 08 020 5 6 08 026 6 6 08 02c 7 6 08 032 8 6 08 1d8 9 6 08 1de a 6 08 1e4 b 6 08 1ea c 6 08 1f0 d 6 08 1f6 e 6 08 1fc f 6 08 002 0 7 08 008 1 7 08 00f 2 7 08 016 3 7 08 01d 4 7 08 024 5 7 08 02b 6 7 08 032 7 7 08 039 8 7 08 1d0 9 7 08 1d7 a 7 08 1de b 7 08 1e5 c 7 08 1ec d 7 08 1f3 e 7 08 1fa f 7 08 001 0 8 08 008 1 8 08 000 2 8 08 1f8 3 8 08 1f0 4 8 08 1e8 5 8 08 1e0 6 8 08 1d8 7 8 08 1d0 8 8 08 048 9 8 08 040 a 8 08 038 b 8 08 030 c 8 08 028 d 8 08 020 e 8 08 018 f 8 08 010 0 9 08 008 1 9 08 001 2 9 08 1fa 3 9 08 1f3 4 9 08 1ec 5 9 08 1e5 6 9 08 1de 7 9 08 1d7 8 9 08 040 9 9 08 039 a 9 08 032 b 9 08 02b c 9 08 024 d 9 08 01d e 9 08 016 f 9 08 00f 0 a 08 008 1 a 08 002 2 a 08 1fc 3 a 08 1f6 4 a 08 1f0 5 a 08 1ea 6 a 08 1e4 7 a 08 1de 8 a 08 038 9 a 08 032 a a 08 02c b a 08 026 c a 08 020 d a 08 01a e a 08 014 f a 08 00e 0 b 08 008 1 b 08 003 2 b 08 1fe 3 b 08 1f9 4 b 08 1f4 5 b 08 1ef 6 b 08 1ea 7 b 08 1e5 8 b 08 030 9 b 08 02b a b 08 026 b b 08 021 c b 08 01c d b 08 017 e b 08 012 f b 08 00d 0 c 08 008 1 c 08 004 2 c 08 000 3 c 08 1fc 4 c 08 1f8 5 c 08 1f4 6 c 08 1f0 7 c 08 1ec 8 c 08 028 9 c 08 024 a c 08 020 b c 08 01c c c 08 018 d c 08 014 e c 08 010 f c 08 00c 0 d 08 008 1 d 08 005 2 d 08 002 3 d 08 1ff 4 d 08 1fc 5 d 08 1f9 6 d 08 1f6 7 d 08 1f3 8 d 08 020 9 d 08 01d a d 08 01a b d 08 017 c d 08 014 d d 08 011 e d 08 00e f d 08 00b 0 e 08 008 1 e 08 006 2 e 08 004 3 e 08 002 4 e 08 000 5 e 08 1fe 6 e 08 1fc 7 e 08 1fa 8 e 08 018 9 e 08 016 a e 08 014 b e 08 012 c e 08 010 d e 08 00e e e 08 00c f e 08 00a 0 f 08 008 1 f 08 007 2 f 08 006 3 f 08 005 4 f 08 004 5 f 08 003 6 f 08 002 7 f 08 001 8 f 08 010 9 f 08 00f a f 08 00e b f 08 00d c f 08 00c d f 08 00b e f 08 00a f f 08 009 0 0 09 009 1 0 09 009 2 0 09 009 3 0 09 009 4 0 09 009 5 0 09 009 6 0 09 009 7 0 09 009 8 0 09 009 9 0 09 009 a 0 09 009 b 0 09 009 c 0 09 009 d 0 09 009 e 0 09 009 f 0 09 009 0 1 09 009 1 1 09 00a 2 1 09 00b 3 1 09 00c 4 1 09 00d 5 1 09 00e 6 1 09 00f 7 1 09 010 8 1 09 001 9 1 09 002 a 1 09 003 b 1 09 004 c 1 09 005 d 1 09 006 e 1 09 007 f 1 09 008 0 2 09 009 1 2 09 00b 2 2 09 00d 3 2 09 00f 4 2 09 011 5 2 09 013 6 2 09 015 7 2 09 017 8 2 09 1f9 9 2 09 1fb a 2 09 1fd b 2 09 1ff c 2 09 001 d 2 09 003 e 2 09 005 f 2 09 007 0 3 09 009 1 3 09 00c 2 3 09 00f 3 3 09 012 4 3 09 015 5 3 09 018 6 3 09 01b 7 3 09 01e 8 3 09 1f1 9 3 09 1f4 a 3 09 1f7 b 3 09 1fa c 3 09 1fd d 3 09 000 e 3 09 003 f 3 09 006 0 4 09 009 1 4 09 00d 2 4 09 011 3 4 09 015 4 4 09 019 5 4 09 01d 6 4 09 021 7 4 09 025 8 4 09 1e9 9 4 09 1ed a 4 09 1f1 b 4 09 1f5 c 4 09 1f9 d 4 09 1fd e 4 09 001 f 4 09 005 0 5 09 009 1 5 09 00e 2 5 09 013 3 5 09 018 4 5 09 01d 5 5 09 022 6 5 09 027 7 5 09 02c 8 5 09 1e1 9 5 09 1e6 a 5 09 1eb b 5 09 1f0 c 5 09 1f5 d 5 09 1fa e 5 09 1ff f 5 09 004 0 6 09 009 1 6 09 00f 2 6 09 015 3 6 09 01b 4 6 09 021 5 6 09 027 6 6 09 02d 7 6 09 033 8 6 09 1d9 9 6 09 1df a 6 09 1e5 b 6 09 1eb c 6 09 1f1 d 6 09 1f7 e 6 09 1fd f 6 09 003 0 7 09 009 1 7 09 010 2 7 09 017 3 7 09 01e 4 7 09 025 5 7 09 02c 6 7 09 033 7 7 09 03a 8 7 09 1d1 9 7 09 1d8 a 7 09 1df b 7 09 1e6 c 7 09 1ed d 7 09 1f4 e 7 09 1fb f 7 09 002 0 8 09 009 1 8 09 001 2 8 09 1f9 3 8 09 1f1 4 8 09 1e9 5 8 09 1e1 6 8 09 1d9 7 8 09 1d1 8 8 09 049 9 8 09 041 a 8 09 039 b 8 09 031 c 8 09 029 d 8 09 021 e 8 09 019 f 8 09 011 0 9 09 009 1 9 09 002 2 9 09 1fb 3 9 09 1f4 4 9 09 1ed 5 9 09 1e6 6 9 09 1df 7 9 09 1d8 8 9 09 041 9 9 09 03a a 9 09 033 b 9 09 02c c 9 09 025 d 9 09 01e e 9 09 017 f 9 09 010 0 a 09 009 1 a 09 003 2 a 09 1fd 3 a 09 1f7 4 a 09 1f1 5 a 09 1eb 6 a 09 1e5 7 a 09 1df 8 a 09 039 9 a 09 033 a a 09 02d b a 09 027 c a 09 021 d a 09 01b e a 09 015 f a 09 00f 0 b 09 009 1 b 09 004 2 b 09 1ff 3 b 09 1fa 4 b 09 1f5 5 b 09 1f0 6 b 09 1eb 7 b 09 1e6 8 b 09 031 9 b 09 02c a b 09 027 b b 09 022 c b 09 01d d b 09 018 e b 09 013 f b 09 00e 0 c 09 009 1 c 09 005 2 c 09 001 3 c 09 1fd 4 c 09 1f9 5 c 09 1f5 6 c 09 1f1 7 c 09 1ed 8 c 09 029 9 c 09 025 a c 09 021 b c 09 01d c c 09 019 d c 09 015 e c 09 011 f c 09 00d 0 d 09 009 1 d 09 006 2 d 09 003 3 d 09 000 4 d 09 1fd 5 d 09 1fa 6 d 09 1f7 7 d 09 1f4 8 d 09 021 9 d 09 01e a d 09 01b b d 09 018 c d 09 015 d d 09 012 e d 09 00f f d 09 00c 0 e 09 009 1 e 09 007 2 e 09 005 3 e 09 003 4 e 09 001 5 e 09 1ff 6 e 09 1fd 7 e 09 1fb 8 e 09 019 9 e 09 017 a e 09 015 b e 09 013 c e 09 011 d e 09 00f e e 09 00d f e 09 00b 0 f 09 009 1 f 09 008 2 f 09 007 3 f 09 006 4 f 09 005 5 f 09 004 6 f 09 003 7 f 09 002 8 f 09 011 9 f 09 010 a f 09 00f b f 09 00e c f 09 00d d f 09 00c e f 09 00b f f 09 00a 0 0 0a 00a 1 0 0a 00a 2 0 0a 00a 3 0 0a 00a 4 0 0a 00a 5 0 0a 00a 6 0 0a 00a 7 0 0a 00a 8 0 0a 00a 9 0 0a 00a a 0 0a 00a b 0 0a 00a c 0 0a 00a d 0 0a 00a e 0 0a 00a f 0 0a 00a 0 1 0a 00a 1 1 0a 00b 2 1 0a 00c 3 1 0a 00d 4 1 0a 00e 5 1 0a 00f 6 1 0a 010 7 1 0a 011 8 1 0a 002 9 1 0a 003 a 1 0a 004 b 1 0a 005 c 1 0a 006 d 1 0a 007 e 1 0a 008 f 1 0a 009 0 2 0a 00a 1 2 0a 00c 2 2 0a 00e 3 2 0a 010 4 2 0a 012 5 2 0a 014 6 2 0a 016 7 2 0a 018 8 2 0a 1fa 9 2 0a 1fc a 2 0a 1fe b 2 0a 000 c 2 0a 002 d 2 0a 004 e 2 0a 006 f 2 0a 008 0 3 0a 00a 1 3 0a 00d 2 3 0a 010 3 3 0a 013 4 3 0a 016 5 3 0a 019 6 3 0a 01c 7 3 0a 01f 8 3 0a 1f2 9 3 0a 1f5 a 3 0a 1f8 b 3 0a 1fb c 3 0a 1fe d 3 0a 001 e 3 0a 004 f 3 0a 007 0 4 0a 00a 1 4 0a 00e 2 4 0a 012 3 4 0a 016 4 4 0a 01a 5 4 0a 01e 6 4 0a 022 7 4 0a 026 8 4 0a 1ea 9 4 0a 1ee a 4 0a 1f2 b 4 0a 1f6 c 4 0a 1fa d 4 0a 1fe e 4 0a 002 f 4 0a 006 0 5 0a 00a 1 5 0a 00f 2 5 0a 014 3 5 0a 019 4 5 0a 01e 5 5 0a 023 6 5 0a 028 7 5 0a 02d 8 5 0a 1e2 9 5 0a 1e7 a 5 0a 1ec b 5 0a 1f1 c 5 0a 1f6 d 5 0a 1fb e 5 0a 000 f 5 0a 005 0 6 0a 00a 1 6 0a 010 2 6 0a 016 3 6 0a 01c 4 6 0a 022 5 6 0a 028 6 6 0a 02e 7 6 0a 034 8 6 0a 1da 9 6 0a 1e0 a 6 0a 1e6 b 6 0a 1ec c 6 0a 1f2 d 6 0a 1f8 e 6 0a 1fe f 6 0a 004 0 7 0a 00a 1 7 0a 011 2 7 0a 018 3 7 0a 01f 4 7 0a 026 5 7 0a 02d 6 7 0a 034 7 7 0a 03b 8 7 0a 1d2 9 7 0a 1d9 a 7 0a 1e0 b 7 0a 1e7 c 7 0a 1ee d 7 0a 1f5 e 7 0a 1fc f 7 0a 003 0 8 0a 00a 1 8 0a 002 2 8 0a 1fa 3 8 0a 1f2 4 8 0a 1ea 5 8 0a 1e2 6 8 0a 1da 7 8 0a 1d2 8 8 0a 04a 9 8 0a 042 a 8 0a 03a b 8 0a 032 c 8 0a 02a d 8 0a 022 e 8 0a 01a f 8 0a 012 0 9 0a 00a 1 9 0a 003 2 9 0a 1fc 3 9 0a 1f5 4 9 0a 1ee 5 9 0a 1e7 6 9 0a 1e0 7 9 0a 1d9 8 9 0a 042 9 9 0a 03b a 9 0a 034 b 9 0a 02d c 9 0a 026 d 9 0a 01f e 9 0a 018 f 9 0a 011 0 a 0a 00a 1 a 0a 004 2 a 0a 1fe 3 a 0a 1f8 4 a 0a 1f2 5 a 0a 1ec 6 a 0a 1e6 7 a 0a 1e0 8 a 0a 03a 9 a 0a 034 a a 0a 02e b a 0a 028 c a 0a 022 d a 0a 01c e a 0a 016 f a 0a 010 0 b 0a 00a 1 b 0a 005 2 b 0a 000 3 b 0a 1fb 4 b 0a 1f6 5 b 0a 1f1 6 b 0a 1ec 7 b 0a 1e7 8 b 0a 032 9 b 0a 02d a b 0a 028 b b 0a 023 c b 0a 01e d b 0a 019 e b 0a 014 f b 0a 00f 0 c 0a 00a 1 c 0a 006 2 c 0a 002 3 c 0a 1fe 4 c 0a 1fa 5 c 0a 1f6 6 c 0a 1f2 7 c 0a 1ee 8 c 0a 02a 9 c 0a 026 a c 0a 022 b c 0a 01e c c 0a 01a d c 0a 016 e c 0a 012 f c 0a 00e 0 d 0a 00a 1 d 0a 007 2 d 0a 004 3 d 0a 001 4 d 0a 1fe 5 d 0a 1fb 6 d 0a 1f8 7 d 0a 1f5 8 d 0a 022 9 d 0a 01f a d 0a 01c b d 0a 019 c d 0a 016 d d 0a 013 e d 0a 010 f d 0a 00d 0 e 0a 00a 1 e 0a 008 2 e 0a 006 3 e 0a 004 4 e 0a 002 5 e 0a 000 6 e 0a 1fe 7 e 0a 1fc 8 e 0a 01a 9 e 0a 018 a e 0a 016 b e 0a 014 c e 0a 012 d e 0a 010 e e 0a 00e f e 0a 00c 0 f 0a 00a 1 f 0a 009 2 f 0a 008 3 f 0a 007 4 f 0a 006 5 f 0a 005 6 f 0a 004 7 f 0a 003 8 f 0a 012 9 f 0a 011 a f 0a 010 b f 0a 00f c f 0a 00e d f 0a 00d e f 0a 00c f f 0a 00b 0 0 0b 00b 1 0 0b 00b 2 0 0b 00b 3 0 0b 00b 4 0 0b 00b 5 0 0b 00b 6 0 0b 00b 7 0 0b 00b 8 0 0b 00b 9 0 0b 00b a 0 0b 00b b 0 0b 00b c 0 0b 00b d 0 0b 00b e 0 0b 00b f 0 0b 00b 0 1 0b 00b 1 1 0b 00c 2 1 0b 00d 3 1 0b 00e 4 1 0b 00f 5 1 0b 010 6 1 0b 011 7 1 0b 012 8 1 0b 003 9 1 0b 004 a 1 0b 005 b 1 0b 006 c 1 0b 007 d 1 0b 008 e 1 0b 009 f 1 0b 00a 0 2 0b 00b 1 2 0b 00d 2 2 0b 00f 3 2 0b 011 4 2 0b 013 5 2 0b 015 6 2 0b 017 7 2 0b 019 8 2 0b 1fb 9 2 0b 1fd a 2 0b 1ff b 2 0b 001 c 2 0b 003 d 2 0b 005 e 2 0b 007 f 2 0b 009 0 3 0b 00b 1 3 0b 00e 2 3 0b 011 3 3 0b 014 4 3 0b 017 5 3 0b 01a 6 3 0b 01d 7 3 0b 020 8 3 0b 1f3 9 3 0b 1f6 a 3 0b 1f9 b 3 0b 1fc c 3 0b 1ff d 3 0b 002 e 3 0b 005 f 3 0b 008 0 4 0b 00b 1 4 0b 00f 2 4 0b 013 3 4 0b 017 4 4 0b 01b 5 4 0b 01f 6 4 0b 023 7 4 0b 027 8 4 0b 1eb 9 4 0b 1ef a 4 0b 1f3 b 4 0b 1f7 c 4 0b 1fb d 4 0b 1ff e 4 0b 003 f 4 0b 007 0 5 0b 00b 1 5 0b 010 2 5 0b 015 3 5 0b 01a 4 5 0b 01f 5 5 0b 024 6 5 0b 029 7 5 0b 02e 8 5 0b 1e3 9 5 0b 1e8 a 5 0b 1ed b 5 0b 1f2 c 5 0b 1f7 d 5 0b 1fc e 5 0b 001 f 5 0b 006 0 6 0b 00b 1 6 0b 011 2 6 0b 017 3 6 0b 01d 4 6 0b 023 5 6 0b 029 6 6 0b 02f 7 6 0b 035 8 6 0b 1db 9 6 0b 1e1 a 6 0b 1e7 b 6 0b 1ed c 6 0b 1f3 d 6 0b 1f9 e 6 0b 1ff f 6 0b 005 0 7 0b 00b 1 7 0b 012 2 7 0b 019 3 7 0b 020 4 7 0b 027 5 7 0b 02e 6 7 0b 035 7 7 0b 03c 8 7 0b 1d3 9 7 0b 1da a 7 0b 1e1 b 7 0b 1e8 c 7 0b 1ef d 7 0b 1f6 e 7 0b 1fd f 7 0b 004 0 8 0b 00b 1 8 0b 003 2 8 0b 1fb 3 8 0b 1f3 4 8 0b 1eb 5 8 0b 1e3 6 8 0b 1db 7 8 0b 1d3 8 8 0b 04b 9 8 0b 043 a 8 0b 03b b 8 0b 033 c 8 0b 02b d 8 0b 023 e 8 0b 01b f 8 0b 013 0 9 0b 00b 1 9 0b 004 2 9 0b 1fd 3 9 0b 1f6 4 9 0b 1ef 5 9 0b 1e8 6 9 0b 1e1 7 9 0b 1da 8 9 0b 043 9 9 0b 03c a 9 0b 035 b 9 0b 02e c 9 0b 027 d 9 0b 020 e 9 0b 019 f 9 0b 012 0 a 0b 00b 1 a 0b 005 2 a 0b 1ff 3 a 0b 1f9 4 a 0b 1f3 5 a 0b 1ed 6 a 0b 1e7 7 a 0b 1e1 8 a 0b 03b 9 a 0b 035 a a 0b 02f b a 0b 029 c a 0b 023 d a 0b 01d e a 0b 017 f a 0b 011 0 b 0b 00b 1 b 0b 006 2 b 0b 001 3 b 0b 1fc 4 b 0b 1f7 5 b 0b 1f2 6 b 0b 1ed 7 b 0b 1e8 8 b 0b 033 9 b 0b 02e a b 0b 029 b b 0b 024 c b 0b 01f d b 0b 01a e b 0b 015 f b 0b 010 0 c 0b 00b 1 c 0b 007 2 c 0b 003 3 c 0b 1ff 4 c 0b 1fb 5 c 0b 1f7 6 c 0b 1f3 7 c 0b 1ef 8 c 0b 02b 9 c 0b 027 a c 0b 023 b c 0b 01f c c 0b 01b d c 0b 017 e c 0b 013 f c 0b 00f 0 d 0b 00b 1 d 0b 008 2 d 0b 005 3 d 0b 002 4 d 0b 1ff 5 d 0b 1fc 6 d 0b 1f9 7 d 0b 1f6 8 d 0b 023 9 d 0b 020 a d 0b 01d b d 0b 01a c d 0b 017 d d 0b 014 e d 0b 011 f d 0b 00e 0 e 0b 00b 1 e 0b 009 2 e 0b 007 3 e 0b 005 4 e 0b 003 5 e 0b 001 6 e 0b 1ff 7 e 0b 1fd 8 e 0b 01b 9 e 0b 019 a e 0b 017 b e 0b 015 c e 0b 013 d e 0b 011 e e 0b 00f f e 0b 00d 0 f 0b 00b 1 f 0b 00a 2 f 0b 009 3 f 0b 008 4 f 0b 007 5 f 0b 006 6 f 0b 005 7 f 0b 004 8 f 0b 013 9 f 0b 012 a f 0b 011 b f 0b 010 c f 0b 00f d f 0b 00e e f 0b 00d f f 0b 00c 0 0 0c 00c 1 0 0c 00c 2 0 0c 00c 3 0 0c 00c 4 0 0c 00c 5 0 0c 00c 6 0 0c 00c 7 0 0c 00c 8 0 0c 00c 9 0 0c 00c a 0 0c 00c b 0 0c 00c c 0 0c 00c d 0 0c 00c e 0 0c 00c f 0 0c 00c 0 1 0c 00c 1 1 0c 00d 2 1 0c 00e 3 1 0c 00f 4 1 0c 010 5 1 0c 011 6 1 0c 012 7 1 0c 013 8 1 0c 004 9 1 0c 005 a 1 0c 006 b 1 0c 007 c 1 0c 008 d 1 0c 009 e 1 0c 00a f 1 0c 00b 0 2 0c 00c 1 2 0c 00e 2 2 0c 010 3 2 0c 012 4 2 0c 014 5 2 0c 016 6 2 0c 018 7 2 0c 01a 8 2 0c 1fc 9 2 0c 1fe a 2 0c 000 b 2 0c 002 c 2 0c 004 d 2 0c 006 e 2 0c 008 f 2 0c 00a 0 3 0c 00c 1 3 0c 00f 2 3 0c 012 3 3 0c 015 4 3 0c 018 5 3 0c 01b 6 3 0c 01e 7 3 0c 021 8 3 0c 1f4 9 3 0c 1f7 a 3 0c 1fa b 3 0c 1fd c 3 0c 000 d 3 0c 003 e 3 0c 006 f 3 0c 009 0 4 0c 00c 1 4 0c 010 2 4 0c 014 3 4 0c 018 4 4 0c 01c 5 4 0c 020 6 4 0c 024 7 4 0c 028 8 4 0c 1ec 9 4 0c 1f0 a 4 0c 1f4 b 4 0c 1f8 c 4 0c 1fc d 4 0c 000 e 4 0c 004 f 4 0c 008 0 5 0c 00c 1 5 0c 011 2 5 0c 016 3 5 0c 01b 4 5 0c 020 5 5 0c 025 6 5 0c 02a 7 5 0c 02f 8 5 0c 1e4 9 5 0c 1e9 a 5 0c 1ee b 5 0c 1f3 c 5 0c 1f8 d 5 0c 1fd e 5 0c 002 f 5 0c 007 0 6 0c 00c 1 6 0c 012 2 6 0c 018 3 6 0c 01e 4 6 0c 024 5 6 0c 02a 6 6 0c 030 7 6 0c 036 8 6 0c 1dc 9 6 0c 1e2 a 6 0c 1e8 b 6 0c 1ee c 6 0c 1f4 d 6 0c 1fa e 6 0c 000 f 6 0c 006 0 7 0c 00c 1 7 0c 013 2 7 0c 01a 3 7 0c 021 4 7 0c 028 5 7 0c 02f 6 7 0c 036 7 7 0c 03d 8 7 0c 1d4 9 7 0c 1db a 7 0c 1e2 b 7 0c 1e9 c 7 0c 1f0 d 7 0c 1f7 e 7 0c 1fe f 7 0c 005 0 8 0c 00c 1 8 0c 004 2 8 0c 1fc 3 8 0c 1f4 4 8 0c 1ec 5 8 0c 1e4 6 8 0c 1dc 7 8 0c 1d4 8 8 0c 04c 9 8 0c 044 a 8 0c 03c b 8 0c 034 c 8 0c 02c d 8 0c 024 e 8 0c 01c f 8 0c 014 0 9 0c 00c 1 9 0c 005 2 9 0c 1fe 3 9 0c 1f7 4 9 0c 1f0 5 9 0c 1e9 6 9 0c 1e2 7 9 0c 1db 8 9 0c 044 9 9 0c 03d a 9 0c 036 b 9 0c 02f c 9 0c 028 d 9 0c 021 e 9 0c 01a f 9 0c 013 0 a 0c 00c 1 a 0c 006 2 a 0c 000 3 a 0c 1fa 4 a 0c 1f4 5 a 0c 1ee 6 a 0c 1e8 7 a 0c 1e2 8 a 0c 03c 9 a 0c 036 a a 0c 030 b a 0c 02a c a 0c 024 d a 0c 01e e a 0c 018 f a 0c 012 0 b 0c 00c 1 b 0c 007 2 b 0c 002 3 b 0c 1fd 4 b 0c 1f8 5 b 0c 1f3 6 b 0c 1ee 7 b 0c 1e9 8 b 0c 034 9 b 0c 02f a b 0c 02a b b 0c 025 c b 0c 020 d b 0c 01b e b 0c 016 f b 0c 011 0 c 0c 00c 1 c 0c 008 2 c 0c 004 3 c 0c 000 4 c 0c 1fc 5 c 0c 1f8 6 c 0c 1f4 7 c 0c 1f0 8 c 0c 02c 9 c 0c 028 a c 0c 024 b c 0c 020 c c 0c 01c d c 0c 018 e c 0c 014 f c 0c 010 0 d 0c 00c 1 d 0c 009 2 d 0c 006 3 d 0c 003 4 d 0c 000 5 d 0c 1fd 6 d 0c 1fa 7 d 0c 1f7 8 d 0c 024 9 d 0c 021 a d 0c 01e b d 0c 01b c d 0c 018 d d 0c 015 e d 0c 012 f d 0c 00f 0 e 0c 00c 1 e 0c 00a 2 e 0c 008 3 e 0c 006 4 e 0c 004 5 e 0c 002 6 e 0c 000 7 e 0c 1fe 8 e 0c 01c 9 e 0c 01a a e 0c 018 b e 0c 016 c e 0c 014 d e 0c 012 e e 0c 010 f e 0c 00e 0 f 0c 00c 1 f 0c 00b 2 f 0c 00a 3 f 0c 009 4 f 0c 008 5 f 0c 007 6 f 0c 006 7 f 0c 005 8 f 0c 014 9 f 0c 013 a f 0c 012 b f 0c 011 c f 0c 010 d f 0c 00f e f 0c 00e f f 0c 00d 0 0 0d 00d 1 0 0d 00d 2 0 0d 00d 3 0 0d 00d 4 0 0d 00d 5 0 0d 00d 6 0 0d 00d 7 0 0d 00d 8 0 0d 00d 9 0 0d 00d a 0 0d 00d b 0 0d 00d c 0 0d 00d d 0 0d 00d e 0 0d 00d f 0 0d 00d 0 1 0d 00d 1 1 0d 00e 2 1 0d 00f 3 1 0d 010 4 1 0d 011 5 1 0d 012 6 1 0d 013 7 1 0d 014 8 1 0d 005 9 1 0d 006 a 1 0d 007 b 1 0d 008 c 1 0d 009 d 1 0d 00a e 1 0d 00b f 1 0d 00c 0 2 0d 00d 1 2 0d 00f 2 2 0d 011 3 2 0d 013 4 2 0d 015 5 2 0d 017 6 2 0d 019 7 2 0d 01b 8 2 0d 1fd 9 2 0d 1ff a 2 0d 001 b 2 0d 003 c 2 0d 005 d 2 0d 007 e 2 0d 009 f 2 0d 00b 0 3 0d 00d 1 3 0d 010 2 3 0d 013 3 3 0d 016 4 3 0d 019 5 3 0d 01c 6 3 0d 01f 7 3 0d 022 8 3 0d 1f5 9 3 0d 1f8 a 3 0d 1fb b 3 0d 1fe c 3 0d 001 d 3 0d 004 e 3 0d 007 f 3 0d 00a 0 4 0d 00d 1 4 0d 011 2 4 0d 015 3 4 0d 019 4 4 0d 01d 5 4 0d 021 6 4 0d 025 7 4 0d 029 8 4 0d 1ed 9 4 0d 1f1 a 4 0d 1f5 b 4 0d 1f9 c 4 0d 1fd d 4 0d 001 e 4 0d 005 f 4 0d 009 0 5 0d 00d 1 5 0d 012 2 5 0d 017 3 5 0d 01c 4 5 0d 021 5 5 0d 026 6 5 0d 02b 7 5 0d 030 8 5 0d 1e5 9 5 0d 1ea a 5 0d 1ef b 5 0d 1f4 c 5 0d 1f9 d 5 0d 1fe e 5 0d 003 f 5 0d 008 0 6 0d 00d 1 6 0d 013 2 6 0d 019 3 6 0d 01f 4 6 0d 025 5 6 0d 02b 6 6 0d 031 7 6 0d 037 8 6 0d 1dd 9 6 0d 1e3 a 6 0d 1e9 b 6 0d 1ef c 6 0d 1f5 d 6 0d 1fb e 6 0d 001 f 6 0d 007 0 7 0d 00d 1 7 0d 014 2 7 0d 01b 3 7 0d 022 4 7 0d 029 5 7 0d 030 6 7 0d 037 7 7 0d 03e 8 7 0d 1d5 9 7 0d 1dc a 7 0d 1e3 b 7 0d 1ea c 7 0d 1f1 d 7 0d 1f8 e 7 0d 1ff f 7 0d 006 0 8 0d 00d 1 8 0d 005 2 8 0d 1fd 3 8 0d 1f5 4 8 0d 1ed 5 8 0d 1e5 6 8 0d 1dd 7 8 0d 1d5 8 8 0d 04d 9 8 0d 045 a 8 0d 03d b 8 0d 035 c 8 0d 02d d 8 0d 025 e 8 0d 01d f 8 0d 015 0 9 0d 00d 1 9 0d 006 2 9 0d 1ff 3 9 0d 1f8 4 9 0d 1f1 5 9 0d 1ea 6 9 0d 1e3 7 9 0d 1dc 8 9 0d 045 9 9 0d 03e a 9 0d 037 b 9 0d 030 c 9 0d 029 d 9 0d 022 e 9 0d 01b f 9 0d 014 0 a 0d 00d 1 a 0d 007 2 a 0d 001 3 a 0d 1fb 4 a 0d 1f5 5 a 0d 1ef 6 a 0d 1e9 7 a 0d 1e3 8 a 0d 03d 9 a 0d 037 a a 0d 031 b a 0d 02b c a 0d 025 d a 0d 01f e a 0d 019 f a 0d 013 0 b 0d 00d 1 b 0d 008 2 b 0d 003 3 b 0d 1fe 4 b 0d 1f9 5 b 0d 1f4 6 b 0d 1ef 7 b 0d 1ea 8 b 0d 035 9 b 0d 030 a b 0d 02b b b 0d 026 c b 0d 021 d b 0d 01c e b 0d 017 f b 0d 012 0 c 0d 00d 1 c 0d 009 2 c 0d 005 3 c 0d 001 4 c 0d 1fd 5 c 0d 1f9 6 c 0d 1f5 7 c 0d 1f1 8 c 0d 02d 9 c 0d 029 a c 0d 025 b c 0d 021 c c 0d 01d d c 0d 019 e c 0d 015 f c 0d 011 0 d 0d 00d 1 d 0d 00a 2 d 0d 007 3 d 0d 004 4 d 0d 001 5 d 0d 1fe 6 d 0d 1fb 7 d 0d 1f8 8 d 0d 025 9 d 0d 022 a d 0d 01f b d 0d 01c c d 0d 019 d d 0d 016 e d 0d 013 f d 0d 010 0 e 0d 00d 1 e 0d 00b 2 e 0d 009 3 e 0d 007 4 e 0d 005 5 e 0d 003 6 e 0d 001 7 e 0d 1ff 8 e 0d 01d 9 e 0d 01b a e 0d 019 b e 0d 017 c e 0d 015 d e 0d 013 e e 0d 011 f e 0d 00f 0 f 0d 00d 1 f 0d 00c 2 f 0d 00b 3 f 0d 00a 4 f 0d 009 5 f 0d 008 6 f 0d 007 7 f 0d 006 8 f 0d 015 9 f 0d 014 a f 0d 013 b f 0d 012 c f 0d 011 d f 0d 010 e f 0d 00f f f 0d 00e 0 0 0e 00e 1 0 0e 00e 2 0 0e 00e 3 0 0e 00e 4 0 0e 00e 5 0 0e 00e 6 0 0e 00e 7 0 0e 00e 8 0 0e 00e 9 0 0e 00e a 0 0e 00e b 0 0e 00e c 0 0e 00e d 0 0e 00e e 0 0e 00e f 0 0e 00e 0 1 0e 00e 1 1 0e 00f 2 1 0e 010 3 1 0e 011 4 1 0e 012 5 1 0e 013 6 1 0e 014 7 1 0e 015 8 1 0e 006 9 1 0e 007 a 1 0e 008 b 1 0e 009 c 1 0e 00a d 1 0e 00b e 1 0e 00c f 1 0e 00d 0 2 0e 00e 1 2 0e 010 2 2 0e 012 3 2 0e 014 4 2 0e 016 5 2 0e 018 6 2 0e 01a 7 2 0e 01c 8 2 0e 1fe 9 2 0e 000 a 2 0e 002 b 2 0e 004 c 2 0e 006 d 2 0e 008 e 2 0e 00a f 2 0e 00c 0 3 0e 00e 1 3 0e 011 2 3 0e 014 3 3 0e 017 4 3 0e 01a 5 3 0e 01d 6 3 0e 020 7 3 0e 023 8 3 0e 1f6 9 3 0e 1f9 a 3 0e 1fc b 3 0e 1ff c 3 0e 002 d 3 0e 005 e 3 0e 008 f 3 0e 00b 0 4 0e 00e 1 4 0e 012 2 4 0e 016 3 4 0e 01a 4 4 0e 01e 5 4 0e 022 6 4 0e 026 7 4 0e 02a 8 4 0e 1ee 9 4 0e 1f2 a 4 0e 1f6 b 4 0e 1fa c 4 0e 1fe d 4 0e 002 e 4 0e 006 f 4 0e 00a 0 5 0e 00e 1 5 0e 013 2 5 0e 018 3 5 0e 01d 4 5 0e 022 5 5 0e 027 6 5 0e 02c 7 5 0e 031 8 5 0e 1e6 9 5 0e 1eb a 5 0e 1f0 b 5 0e 1f5 c 5 0e 1fa d 5 0e 1ff e 5 0e 004 f 5 0e 009 0 6 0e 00e 1 6 0e 014 2 6 0e 01a 3 6 0e 020 4 6 0e 026 5 6 0e 02c 6 6 0e 032 7 6 0e 038 8 6 0e 1de 9 6 0e 1e4 a 6 0e 1ea b 6 0e 1f0 c 6 0e 1f6 d 6 0e 1fc e 6 0e 002 f 6 0e 008 0 7 0e 00e 1 7 0e 015 2 7 0e 01c 3 7 0e 023 4 7 0e 02a 5 7 0e 031 6 7 0e 038 7 7 0e 03f 8 7 0e 1d6 9 7 0e 1dd a 7 0e 1e4 b 7 0e 1eb c 7 0e 1f2 d 7 0e 1f9 e 7 0e 000 f 7 0e 007 0 8 0e 00e 1 8 0e 006 2 8 0e 1fe 3 8 0e 1f6 4 8 0e 1ee 5 8 0e 1e6 6 8 0e 1de 7 8 0e 1d6 8 8 0e 04e 9 8 0e 046 a 8 0e 03e b 8 0e 036 c 8 0e 02e d 8 0e 026 e 8 0e 01e f 8 0e 016 0 9 0e 00e 1 9 0e 007 2 9 0e 000 3 9 0e 1f9 4 9 0e 1f2 5 9 0e 1eb 6 9 0e 1e4 7 9 0e 1dd 8 9 0e 046 9 9 0e 03f a 9 0e 038 b 9 0e 031 c 9 0e 02a d 9 0e 023 e 9 0e 01c f 9 0e 015 0 a 0e 00e 1 a 0e 008 2 a 0e 002 3 a 0e 1fc 4 a 0e 1f6 5 a 0e 1f0 6 a 0e 1ea 7 a 0e 1e4 8 a 0e 03e 9 a 0e 038 a a 0e 032 b a 0e 02c c a 0e 026 d a 0e 020 e a 0e 01a f a 0e 014 0 b 0e 00e 1 b 0e 009 2 b 0e 004 3 b 0e 1ff 4 b 0e 1fa 5 b 0e 1f5 6 b 0e 1f0 7 b 0e 1eb 8 b 0e 036 9 b 0e 031 a b 0e 02c b b 0e 027 c b 0e 022 d b 0e 01d e b 0e 018 f b 0e 013 0 c 0e 00e 1 c 0e 00a 2 c 0e 006 3 c 0e 002 4 c 0e 1fe 5 c 0e 1fa 6 c 0e 1f6 7 c 0e 1f2 8 c 0e 02e 9 c 0e 02a a c 0e 026 b c 0e 022 c c 0e 01e d c 0e 01a e c 0e 016 f c 0e 012 0 d 0e 00e 1 d 0e 00b 2 d 0e 008 3 d 0e 005 4 d 0e 002 5 d 0e 1ff 6 d 0e 1fc 7 d 0e 1f9 8 d 0e 026 9 d 0e 023 a d 0e 020 b d 0e 01d c d 0e 01a d d 0e 017 e d 0e 014 f d 0e 011 0 e 0e 00e 1 e 0e 00c 2 e 0e 00a 3 e 0e 008 4 e 0e 006 5 e 0e 004 6 e 0e 002 7 e 0e 000 8 e 0e 01e 9 e 0e 01c a e 0e 01a b e 0e 018 c e 0e 016 d e 0e 014 e e 0e 012 f e 0e 010 0 f 0e 00e 1 f 0e 00d 2 f 0e 00c 3 f 0e 00b 4 f 0e 00a 5 f 0e 009 6 f 0e 008 7 f 0e 007 8 f 0e 016 9 f 0e 015 a f 0e 014 b f 0e 013 c f 0e 012 d f 0e 011 e f 0e 010 f f 0e 00f 0 0 0f 00f 1 0 0f 00f 2 0 0f 00f 3 0 0f 00f 4 0 0f 00f 5 0 0f 00f 6 0 0f 00f 7 0 0f 00f 8 0 0f 00f 9 0 0f 00f a 0 0f 00f b 0 0f 00f c 0 0f 00f d 0 0f 00f e 0 0f 00f f 0 0f 00f 0 1 0f 00f 1 1 0f 010 2 1 0f 011 3 1 0f 012 4 1 0f 013 5 1 0f 014 6 1 0f 015 7 1 0f 016 8 1 0f 007 9 1 0f 008 a 1 0f 009 b 1 0f 00a c 1 0f 00b d 1 0f 00c e 1 0f 00d f 1 0f 00e 0 2 0f 00f 1 2 0f 011 2 2 0f 013 3 2 0f 015 4 2 0f 017 5 2 0f 019 6 2 0f 01b 7 2 0f 01d 8 2 0f 1ff 9 2 0f 001 a 2 0f 003 b 2 0f 005 c 2 0f 007 d 2 0f 009 e 2 0f 00b f 2 0f 00d 0 3 0f 00f 1 3 0f 012 2 3 0f 015 3 3 0f 018 4 3 0f 01b 5 3 0f 01e 6 3 0f 021 7 3 0f 024 8 3 0f 1f7 9 3 0f 1fa a 3 0f 1fd b 3 0f 000 c 3 0f 003 d 3 0f 006 e 3 0f 009 f 3 0f 00c 0 4 0f 00f 1 4 0f 013 2 4 0f 017 3 4 0f 01b 4 4 0f 01f 5 4 0f 023 6 4 0f 027 7 4 0f 02b 8 4 0f 1ef 9 4 0f 1f3 a 4 0f 1f7 b 4 0f 1fb c 4 0f 1ff d 4 0f 003 e 4 0f 007 f 4 0f 00b 0 5 0f 00f 1 5 0f 014 2 5 0f 019 3 5 0f 01e 4 5 0f 023 5 5 0f 028 6 5 0f 02d 7 5 0f 032 8 5 0f 1e7 9 5 0f 1ec a 5 0f 1f1 b 5 0f 1f6 c 5 0f 1fb d 5 0f 000 e 5 0f 005 f 5 0f 00a 0 6 0f 00f 1 6 0f 015 2 6 0f 01b 3 6 0f 021 4 6 0f 027 5 6 0f 02d 6 6 0f 033 7 6 0f 039 8 6 0f 1df 9 6 0f 1e5 a 6 0f 1eb b 6 0f 1f1 c 6 0f 1f7 d 6 0f 1fd e 6 0f 003 f 6 0f 009 0 7 0f 00f 1 7 0f 016 2 7 0f 01d 3 7 0f 024 4 7 0f 02b 5 7 0f 032 6 7 0f 039 7 7 0f 040 8 7 0f 1d7 9 7 0f 1de a 7 0f 1e5 b 7 0f 1ec c 7 0f 1f3 d 7 0f 1fa e 7 0f 001 f 7 0f 008 0 8 0f 00f 1 8 0f 007 2 8 0f 1ff 3 8 0f 1f7 4 8 0f 1ef 5 8 0f 1e7 6 8 0f 1df 7 8 0f 1d7 8 8 0f 04f 9 8 0f 047 a 8 0f 03f b 8 0f 037 c 8 0f 02f d 8 0f 027 e 8 0f 01f f 8 0f 017 0 9 0f 00f 1 9 0f 008 2 9 0f 001 3 9 0f 1fa 4 9 0f 1f3 5 9 0f 1ec 6 9 0f 1e5 7 9 0f 1de 8 9 0f 047 9 9 0f 040 a 9 0f 039 b 9 0f 032 c 9 0f 02b d 9 0f 024 e 9 0f 01d f 9 0f 016 0 a 0f 00f 1 a 0f 009 2 a 0f 003 3 a 0f 1fd 4 a 0f 1f7 5 a 0f 1f1 6 a 0f 1eb 7 a 0f 1e5 8 a 0f 03f 9 a 0f 039 a a 0f 033 b a 0f 02d c a 0f 027 d a 0f 021 e a 0f 01b f a 0f 015 0 b 0f 00f 1 b 0f 00a 2 b 0f 005 3 b 0f 000 4 b 0f 1fb 5 b 0f 1f6 6 b 0f 1f1 7 b 0f 1ec 8 b 0f 037 9 b 0f 032 a b 0f 02d b b 0f 028 c b 0f 023 d b 0f 01e e b 0f 019 f b 0f 014 0 c 0f 00f 1 c 0f 00b 2 c 0f 007 3 c 0f 003 4 c 0f 1ff 5 c 0f 1fb 6 c 0f 1f7 7 c 0f 1f3 8 c 0f 02f 9 c 0f 02b a c 0f 027 b c 0f 023 c c 0f 01f d c 0f 01b e c 0f 017 f c 0f 013 0 d 0f 00f 1 d 0f 00c 2 d 0f 009 3 d 0f 006 4 d 0f 003 5 d 0f 000 6 d 0f 1fd 7 d 0f 1fa 8 d 0f 027 9 d 0f 024 a d 0f 021 b d 0f 01e c d 0f 01b d d 0f 018 e d 0f 015 f d 0f 012 0 e 0f 00f 1 e 0f 00d 2 e 0f 00b 3 e 0f 009 4 e 0f 007 5 e 0f 005 6 e 0f 003 7 e 0f 001 8 e 0f 01f 9 e 0f 01d a e 0f 01b b e 0f 019 c e 0f 017 d e 0f 015 e e 0f 013 f e 0f 011 0 f 0f 00f 1 f 0f 00e 2 f 0f 00d 3 f 0f 00c 4 f 0f 00b 5 f 0f 00a 6 f 0f 009 7 f 0f 008 8 f 0f 017 9 f 0f 016 a f 0f 015 b f 0f 014 c f 0f 013 d f 0f 012 e f 0f 011 f f 0f 010 0 0 10 010 1 0 10 010 2 0 10 010 3 0 10 010 4 0 10 010 5 0 10 010 6 0 10 010 7 0 10 010 8 0 10 010 9 0 10 010 a 0 10 010 b 0 10 010 c 0 10 010 d 0 10 010 e 0 10 010 f 0 10 010 0 1 10 010 1 1 10 011 2 1 10 012 3 1 10 013 4 1 10 014 5 1 10 015 6 1 10 016 7 1 10 017 8 1 10 008 9 1 10 009 a 1 10 00a b 1 10 00b c 1 10 00c d 1 10 00d e 1 10 00e f 1 10 00f 0 2 10 010 1 2 10 012 2 2 10 014 3 2 10 016 4 2 10 018 5 2 10 01a 6 2 10 01c 7 2 10 01e 8 2 10 000 9 2 10 002 a 2 10 004 b 2 10 006 c 2 10 008 d 2 10 00a e 2 10 00c f 2 10 00e 0 3 10 010 1 3 10 013 2 3 10 016 3 3 10 019 4 3 10 01c 5 3 10 01f 6 3 10 022 7 3 10 025 8 3 10 1f8 9 3 10 1fb a 3 10 1fe b 3 10 001 c 3 10 004 d 3 10 007 e 3 10 00a f 3 10 00d 0 4 10 010 1 4 10 014 2 4 10 018 3 4 10 01c 4 4 10 020 5 4 10 024 6 4 10 028 7 4 10 02c 8 4 10 1f0 9 4 10 1f4 a 4 10 1f8 b 4 10 1fc c 4 10 000 d 4 10 004 e 4 10 008 f 4 10 00c 0 5 10 010 1 5 10 015 2 5 10 01a 3 5 10 01f 4 5 10 024 5 5 10 029 6 5 10 02e 7 5 10 033 8 5 10 1e8 9 5 10 1ed a 5 10 1f2 b 5 10 1f7 c 5 10 1fc d 5 10 001 e 5 10 006 f 5 10 00b 0 6 10 010 1 6 10 016 2 6 10 01c 3 6 10 022 4 6 10 028 5 6 10 02e 6 6 10 034 7 6 10 03a 8 6 10 1e0 9 6 10 1e6 a 6 10 1ec b 6 10 1f2 c 6 10 1f8 d 6 10 1fe e 6 10 004 f 6 10 00a 0 7 10 010 1 7 10 017 2 7 10 01e 3 7 10 025 4 7 10 02c 5 7 10 033 6 7 10 03a 7 7 10 041 8 7 10 1d8 9 7 10 1df a 7 10 1e6 b 7 10 1ed c 7 10 1f4 d 7 10 1fb e 7 10 002 f 7 10 009 0 8 10 010 1 8 10 008 2 8 10 000 3 8 10 1f8 4 8 10 1f0 5 8 10 1e8 6 8 10 1e0 7 8 10 1d8 8 8 10 050 9 8 10 048 a 8 10 040 b 8 10 038 c 8 10 030 d 8 10 028 e 8 10 020 f 8 10 018 0 9 10 010 1 9 10 009 2 9 10 002 3 9 10 1fb 4 9 10 1f4 5 9 10 1ed 6 9 10 1e6 7 9 10 1df 8 9 10 048 9 9 10 041 a 9 10 03a b 9 10 033 c 9 10 02c d 9 10 025 e 9 10 01e f 9 10 017 0 a 10 010 1 a 10 00a 2 a 10 004 3 a 10 1fe 4 a 10 1f8 5 a 10 1f2 6 a 10 1ec 7 a 10 1e6 8 a 10 040 9 a 10 03a a a 10 034 b a 10 02e c a 10 028 d a 10 022 e a 10 01c f a 10 016 0 b 10 010 1 b 10 00b 2 b 10 006 3 b 10 001 4 b 10 1fc 5 b 10 1f7 6 b 10 1f2 7 b 10 1ed 8 b 10 038 9 b 10 033 a b 10 02e b b 10 029 c b 10 024 d b 10 01f e b 10 01a f b 10 015 0 c 10 010 1 c 10 00c 2 c 10 008 3 c 10 004 4 c 10 000 5 c 10 1fc 6 c 10 1f8 7 c 10 1f4 8 c 10 030 9 c 10 02c a c 10 028 b c 10 024 c c 10 020 d c 10 01c e c 10 018 f c 10 014 0 d 10 010 1 d 10 00d 2 d 10 00a 3 d 10 007 4 d 10 004 5 d 10 001 6 d 10 1fe 7 d 10 1fb 8 d 10 028 9 d 10 025 a d 10 022 b d 10 01f c d 10 01c d d 10 019 e d 10 016 f d 10 013 0 e 10 010 1 e 10 00e 2 e 10 00c 3 e 10 00a 4 e 10 008 5 e 10 006 6 e 10 004 7 e 10 002 8 e 10 020 9 e 10 01e a e 10 01c b e 10 01a c e 10 018 d e 10 016 e e 10 014 f e 10 012 0 f 10 010 1 f 10 00f 2 f 10 00e 3 f 10 00d 4 f 10 00c 5 f 10 00b 6 f 10 00a 7 f 10 009 8 f 10 018 9 f 10 017 a f 10 016 b f 10 015 c f 10 014 d f 10 013 e f 10 012 f f 10 011 0 0 11 011 1 0 11 011 2 0 11 011 3 0 11 011 4 0 11 011 5 0 11 011 6 0 11 011 7 0 11 011 8 0 11 011 9 0 11 011 a 0 11 011 b 0 11 011 c 0 11 011 d 0 11 011 e 0 11 011 f 0 11 011 0 1 11 011 1 1 11 012 2 1 11 013 3 1 11 014 4 1 11 015 5 1 11 016 6 1 11 017 7 1 11 018 8 1 11 009 9 1 11 00a a 1 11 00b b 1 11 00c c 1 11 00d d 1 11 00e e 1 11 00f f 1 11 010 0 2 11 011 1 2 11 013 2 2 11 015 3 2 11 017 4 2 11 019 5 2 11 01b 6 2 11 01d 7 2 11 01f 8 2 11 001 9 2 11 003 a 2 11 005 b 2 11 007 c 2 11 009 d 2 11 00b e 2 11 00d f 2 11 00f 0 3 11 011 1 3 11 014 2 3 11 017 3 3 11 01a 4 3 11 01d 5 3 11 020 6 3 11 023 7 3 11 026 8 3 11 1f9 9 3 11 1fc a 3 11 1ff b 3 11 002 c 3 11 005 d 3 11 008 e 3 11 00b f 3 11 00e 0 4 11 011 1 4 11 015 2 4 11 019 3 4 11 01d 4 4 11 021 5 4 11 025 6 4 11 029 7 4 11 02d 8 4 11 1f1 9 4 11 1f5 a 4 11 1f9 b 4 11 1fd c 4 11 001 d 4 11 005 e 4 11 009 f 4 11 00d 0 5 11 011 1 5 11 016 2 5 11 01b 3 5 11 020 4 5 11 025 5 5 11 02a 6 5 11 02f 7 5 11 034 8 5 11 1e9 9 5 11 1ee a 5 11 1f3 b 5 11 1f8 c 5 11 1fd d 5 11 002 e 5 11 007 f 5 11 00c 0 6 11 011 1 6 11 017 2 6 11 01d 3 6 11 023 4 6 11 029 5 6 11 02f 6 6 11 035 7 6 11 03b 8 6 11 1e1 9 6 11 1e7 a 6 11 1ed b 6 11 1f3 c 6 11 1f9 d 6 11 1ff e 6 11 005 f 6 11 00b 0 7 11 011 1 7 11 018 2 7 11 01f 3 7 11 026 4 7 11 02d 5 7 11 034 6 7 11 03b 7 7 11 042 8 7 11 1d9 9 7 11 1e0 a 7 11 1e7 b 7 11 1ee c 7 11 1f5 d 7 11 1fc e 7 11 003 f 7 11 00a 0 8 11 011 1 8 11 009 2 8 11 001 3 8 11 1f9 4 8 11 1f1 5 8 11 1e9 6 8 11 1e1 7 8 11 1d9 8 8 11 051 9 8 11 049 a 8 11 041 b 8 11 039 c 8 11 031 d 8 11 029 e 8 11 021 f 8 11 019 0 9 11 011 1 9 11 00a 2 9 11 003 3 9 11 1fc 4 9 11 1f5 5 9 11 1ee 6 9 11 1e7 7 9 11 1e0 8 9 11 049 9 9 11 042 a 9 11 03b b 9 11 034 c 9 11 02d d 9 11 026 e 9 11 01f f 9 11 018 0 a 11 011 1 a 11 00b 2 a 11 005 3 a 11 1ff 4 a 11 1f9 5 a 11 1f3 6 a 11 1ed 7 a 11 1e7 8 a 11 041 9 a 11 03b a a 11 035 b a 11 02f c a 11 029 d a 11 023 e a 11 01d f a 11 017 0 b 11 011 1 b 11 00c 2 b 11 007 3 b 11 002 4 b 11 1fd 5 b 11 1f8 6 b 11 1f3 7 b 11 1ee 8 b 11 039 9 b 11 034 a b 11 02f b b 11 02a c b 11 025 d b 11 020 e b 11 01b f b 11 016 0 c 11 011 1 c 11 00d 2 c 11 009 3 c 11 005 4 c 11 001 5 c 11 1fd 6 c 11 1f9 7 c 11 1f5 8 c 11 031 9 c 11 02d a c 11 029 b c 11 025 c c 11 021 d c 11 01d e c 11 019 f c 11 015 0 d 11 011 1 d 11 00e 2 d 11 00b 3 d 11 008 4 d 11 005 5 d 11 002 6 d 11 1ff 7 d 11 1fc 8 d 11 029 9 d 11 026 a d 11 023 b d 11 020 c d 11 01d d d 11 01a e d 11 017 f d 11 014 0 e 11 011 1 e 11 00f 2 e 11 00d 3 e 11 00b 4 e 11 009 5 e 11 007 6 e 11 005 7 e 11 003 8 e 11 021 9 e 11 01f a e 11 01d b e 11 01b c e 11 019 d e 11 017 e e 11 015 f e 11 013 0 f 11 011 1 f 11 010 2 f 11 00f 3 f 11 00e 4 f 11 00d 5 f 11 00c 6 f 11 00b 7 f 11 00a 8 f 11 019 9 f 11 018 a f 11 017 b f 11 016 c f 11 015 d f 11 014 e f 11 013 f f 11 012 0 0 12 012 1 0 12 012 2 0 12 012 3 0 12 012 4 0 12 012 5 0 12 012 6 0 12 012 7 0 12 012 8 0 12 012 9 0 12 012 a 0 12 012 b 0 12 012 c 0 12 012 d 0 12 012 e 0 12 012 f 0 12 012 0 1 12 012 1 1 12 013 2 1 12 014 3 1 12 015 4 1 12 016 5 1 12 017 6 1 12 018 7 1 12 019 8 1 12 00a 9 1 12 00b a 1 12 00c b 1 12 00d c 1 12 00e d 1 12 00f e 1 12 010 f 1 12 011 0 2 12 012 1 2 12 014 2 2 12 016 3 2 12 018 4 2 12 01a 5 2 12 01c 6 2 12 01e 7 2 12 020 8 2 12 002 9 2 12 004 a 2 12 006 b 2 12 008 c 2 12 00a d 2 12 00c e 2 12 00e f 2 12 010 0 3 12 012 1 3 12 015 2 3 12 018 3 3 12 01b 4 3 12 01e 5 3 12 021 6 3 12 024 7 3 12 027 8 3 12 1fa 9 3 12 1fd a 3 12 000 b 3 12 003 c 3 12 006 d 3 12 009 e 3 12 00c f 3 12 00f 0 4 12 012 1 4 12 016 2 4 12 01a 3 4 12 01e 4 4 12 022 5 4 12 026 6 4 12 02a 7 4 12 02e 8 4 12 1f2 9 4 12 1f6 a 4 12 1fa b 4 12 1fe c 4 12 002 d 4 12 006 e 4 12 00a f 4 12 00e 0 5 12 012 1 5 12 017 2 5 12 01c 3 5 12 021 4 5 12 026 5 5 12 02b 6 5 12 030 7 5 12 035 8 5 12 1ea 9 5 12 1ef a 5 12 1f4 b 5 12 1f9 c 5 12 1fe d 5 12 003 e 5 12 008 f 5 12 00d 0 6 12 012 1 6 12 018 2 6 12 01e 3 6 12 024 4 6 12 02a 5 6 12 030 6 6 12 036 7 6 12 03c 8 6 12 1e2 9 6 12 1e8 a 6 12 1ee b 6 12 1f4 c 6 12 1fa d 6 12 000 e 6 12 006 f 6 12 00c 0 7 12 012 1 7 12 019 2 7 12 020 3 7 12 027 4 7 12 02e 5 7 12 035 6 7 12 03c 7 7 12 043 8 7 12 1da 9 7 12 1e1 a 7 12 1e8 b 7 12 1ef c 7 12 1f6 d 7 12 1fd e 7 12 004 f 7 12 00b 0 8 12 012 1 8 12 00a 2 8 12 002 3 8 12 1fa 4 8 12 1f2 5 8 12 1ea 6 8 12 1e2 7 8 12 1da 8 8 12 052 9 8 12 04a a 8 12 042 b 8 12 03a c 8 12 032 d 8 12 02a e 8 12 022 f 8 12 01a 0 9 12 012 1 9 12 00b 2 9 12 004 3 9 12 1fd 4 9 12 1f6 5 9 12 1ef 6 9 12 1e8 7 9 12 1e1 8 9 12 04a 9 9 12 043 a 9 12 03c b 9 12 035 c 9 12 02e d 9 12 027 e 9 12 020 f 9 12 019 0 a 12 012 1 a 12 00c 2 a 12 006 3 a 12 000 4 a 12 1fa 5 a 12 1f4 6 a 12 1ee 7 a 12 1e8 8 a 12 042 9 a 12 03c a a 12 036 b a 12 030 c a 12 02a d a 12 024 e a 12 01e f a 12 018 0 b 12 012 1 b 12 00d 2 b 12 008 3 b 12 003 4 b 12 1fe 5 b 12 1f9 6 b 12 1f4 7 b 12 1ef 8 b 12 03a 9 b 12 035 a b 12 030 b b 12 02b c b 12 026 d b 12 021 e b 12 01c f b 12 017 0 c 12 012 1 c 12 00e 2 c 12 00a 3 c 12 006 4 c 12 002 5 c 12 1fe 6 c 12 1fa 7 c 12 1f6 8 c 12 032 9 c 12 02e a c 12 02a b c 12 026 c c 12 022 d c 12 01e e c 12 01a f c 12 016 0 d 12 012 1 d 12 00f 2 d 12 00c 3 d 12 009 4 d 12 006 5 d 12 003 6 d 12 000 7 d 12 1fd 8 d 12 02a 9 d 12 027 a d 12 024 b d 12 021 c d 12 01e d d 12 01b e d 12 018 f d 12 015 0 e 12 012 1 e 12 010 2 e 12 00e 3 e 12 00c 4 e 12 00a 5 e 12 008 6 e 12 006 7 e 12 004 8 e 12 022 9 e 12 020 a e 12 01e b e 12 01c c e 12 01a d e 12 018 e e 12 016 f e 12 014 0 f 12 012 1 f 12 011 2 f 12 010 3 f 12 00f 4 f 12 00e 5 f 12 00d 6 f 12 00c 7 f 12 00b 8 f 12 01a 9 f 12 019 a f 12 018 b f 12 017 c f 12 016 d f 12 015 e f 12 014 f f 12 013 0 0 13 013 1 0 13 013 2 0 13 013 3 0 13 013 4 0 13 013 5 0 13 013 6 0 13 013 7 0 13 013 8 0 13 013 9 0 13 013 a 0 13 013 b 0 13 013 c 0 13 013 d 0 13 013 e 0 13 013 f 0 13 013 0 1 13 013 1 1 13 014 2 1 13 015 3 1 13 016 4 1 13 017 5 1 13 018 6 1 13 019 7 1 13 01a 8 1 13 00b 9 1 13 00c a 1 13 00d b 1 13 00e c 1 13 00f d 1 13 010 e 1 13 011 f 1 13 012 0 2 13 013 1 2 13 015 2 2 13 017 3 2 13 019 4 2 13 01b 5 2 13 01d 6 2 13 01f 7 2 13 021 8 2 13 003 9 2 13 005 a 2 13 007 b 2 13 009 c 2 13 00b d 2 13 00d e 2 13 00f f 2 13 011 0 3 13 013 1 3 13 016 2 3 13 019 3 3 13 01c 4 3 13 01f 5 3 13 022 6 3 13 025 7 3 13 028 8 3 13 1fb 9 3 13 1fe a 3 13 001 b 3 13 004 c 3 13 007 d 3 13 00a e 3 13 00d f 3 13 010 0 4 13 013 1 4 13 017 2 4 13 01b 3 4 13 01f 4 4 13 023 5 4 13 027 6 4 13 02b 7 4 13 02f 8 4 13 1f3 9 4 13 1f7 a 4 13 1fb b 4 13 1ff c 4 13 003 d 4 13 007 e 4 13 00b f 4 13 00f 0 5 13 013 1 5 13 018 2 5 13 01d 3 5 13 022 4 5 13 027 5 5 13 02c 6 5 13 031 7 5 13 036 8 5 13 1eb 9 5 13 1f0 a 5 13 1f5 b 5 13 1fa c 5 13 1ff d 5 13 004 e 5 13 009 f 5 13 00e 0 6 13 013 1 6 13 019 2 6 13 01f 3 6 13 025 4 6 13 02b 5 6 13 031 6 6 13 037 7 6 13 03d 8 6 13 1e3 9 6 13 1e9 a 6 13 1ef b 6 13 1f5 c 6 13 1fb d 6 13 001 e 6 13 007 f 6 13 00d 0 7 13 013 1 7 13 01a 2 7 13 021 3 7 13 028 4 7 13 02f 5 7 13 036 6 7 13 03d 7 7 13 044 8 7 13 1db 9 7 13 1e2 a 7 13 1e9 b 7 13 1f0 c 7 13 1f7 d 7 13 1fe e 7 13 005 f 7 13 00c 0 8 13 013 1 8 13 00b 2 8 13 003 3 8 13 1fb 4 8 13 1f3 5 8 13 1eb 6 8 13 1e3 7 8 13 1db 8 8 13 053 9 8 13 04b a 8 13 043 b 8 13 03b c 8 13 033 d 8 13 02b e 8 13 023 f 8 13 01b 0 9 13 013 1 9 13 00c 2 9 13 005 3 9 13 1fe 4 9 13 1f7 5 9 13 1f0 6 9 13 1e9 7 9 13 1e2 8 9 13 04b 9 9 13 044 a 9 13 03d b 9 13 036 c 9 13 02f d 9 13 028 e 9 13 021 f 9 13 01a 0 a 13 013 1 a 13 00d 2 a 13 007 3 a 13 001 4 a 13 1fb 5 a 13 1f5 6 a 13 1ef 7 a 13 1e9 8 a 13 043 9 a 13 03d a a 13 037 b a 13 031 c a 13 02b d a 13 025 e a 13 01f f a 13 019 0 b 13 013 1 b 13 00e 2 b 13 009 3 b 13 004 4 b 13 1ff 5 b 13 1fa 6 b 13 1f5 7 b 13 1f0 8 b 13 03b 9 b 13 036 a b 13 031 b b 13 02c c b 13 027 d b 13 022 e b 13 01d f b 13 018 0 c 13 013 1 c 13 00f 2 c 13 00b 3 c 13 007 4 c 13 003 5 c 13 1ff 6 c 13 1fb 7 c 13 1f7 8 c 13 033 9 c 13 02f a c 13 02b b c 13 027 c c 13 023 d c 13 01f e c 13 01b f c 13 017 0 d 13 013 1 d 13 010 2 d 13 00d 3 d 13 00a 4 d 13 007 5 d 13 004 6 d 13 001 7 d 13 1fe 8 d 13 02b 9 d 13 028 a d 13 025 b d 13 022 c d 13 01f d d 13 01c e d 13 019 f d 13 016 0 e 13 013 1 e 13 011 2 e 13 00f 3 e 13 00d 4 e 13 00b 5 e 13 009 6 e 13 007 7 e 13 005 8 e 13 023 9 e 13 021 a e 13 01f b e 13 01d c e 13 01b d e 13 019 e e 13 017 f e 13 015 0 f 13 013 1 f 13 012 2 f 13 011 3 f 13 010 4 f 13 00f 5 f 13 00e 6 f 13 00d 7 f 13 00c 8 f 13 01b 9 f 13 01a a f 13 019 b f 13 018 c f 13 017 d f 13 016 e f 13 015 f f 13 014 0 0 14 014 1 0 14 014 2 0 14 014 3 0 14 014 4 0 14 014 5 0 14 014 6 0 14 014 7 0 14 014 8 0 14 014 9 0 14 014 a 0 14 014 b 0 14 014 c 0 14 014 d 0 14 014 e 0 14 014 f 0 14 014 0 1 14 014 1 1 14 015 2 1 14 016 3 1 14 017 4 1 14 018 5 1 14 019 6 1 14 01a 7 1 14 01b 8 1 14 00c 9 1 14 00d a 1 14 00e b 1 14 00f c 1 14 010 d 1 14 011 e 1 14 012 f 1 14 013 0 2 14 014 1 2 14 016 2 2 14 018 3 2 14 01a 4 2 14 01c 5 2 14 01e 6 2 14 020 7 2 14 022 8 2 14 004 9 2 14 006 a 2 14 008 b 2 14 00a c 2 14 00c d 2 14 00e e 2 14 010 f 2 14 012 0 3 14 014 1 3 14 017 2 3 14 01a 3 3 14 01d 4 3 14 020 5 3 14 023 6 3 14 026 7 3 14 029 8 3 14 1fc 9 3 14 1ff a 3 14 002 b 3 14 005 c 3 14 008 d 3 14 00b e 3 14 00e f 3 14 011 0 4 14 014 1 4 14 018 2 4 14 01c 3 4 14 020 4 4 14 024 5 4 14 028 6 4 14 02c 7 4 14 030 8 4 14 1f4 9 4 14 1f8 a 4 14 1fc b 4 14 000 c 4 14 004 d 4 14 008 e 4 14 00c f 4 14 010 0 5 14 014 1 5 14 019 2 5 14 01e 3 5 14 023 4 5 14 028 5 5 14 02d 6 5 14 032 7 5 14 037 8 5 14 1ec 9 5 14 1f1 a 5 14 1f6 b 5 14 1fb c 5 14 000 d 5 14 005 e 5 14 00a f 5 14 00f 0 6 14 014 1 6 14 01a 2 6 14 020 3 6 14 026 4 6 14 02c 5 6 14 032 6 6 14 038 7 6 14 03e 8 6 14 1e4 9 6 14 1ea a 6 14 1f0 b 6 14 1f6 c 6 14 1fc d 6 14 002 e 6 14 008 f 6 14 00e 0 7 14 014 1 7 14 01b 2 7 14 022 3 7 14 029 4 7 14 030 5 7 14 037 6 7 14 03e 7 7 14 045 8 7 14 1dc 9 7 14 1e3 a 7 14 1ea b 7 14 1f1 c 7 14 1f8 d 7 14 1ff e 7 14 006 f 7 14 00d 0 8 14 014 1 8 14 00c 2 8 14 004 3 8 14 1fc 4 8 14 1f4 5 8 14 1ec 6 8 14 1e4 7 8 14 1dc 8 8 14 054 9 8 14 04c a 8 14 044 b 8 14 03c c 8 14 034 d 8 14 02c e 8 14 024 f 8 14 01c 0 9 14 014 1 9 14 00d 2 9 14 006 3 9 14 1ff 4 9 14 1f8 5 9 14 1f1 6 9 14 1ea 7 9 14 1e3 8 9 14 04c 9 9 14 045 a 9 14 03e b 9 14 037 c 9 14 030 d 9 14 029 e 9 14 022 f 9 14 01b 0 a 14 014 1 a 14 00e 2 a 14 008 3 a 14 002 4 a 14 1fc 5 a 14 1f6 6 a 14 1f0 7 a 14 1ea 8 a 14 044 9 a 14 03e a a 14 038 b a 14 032 c a 14 02c d a 14 026 e a 14 020 f a 14 01a 0 b 14 014 1 b 14 00f 2 b 14 00a 3 b 14 005 4 b 14 000 5 b 14 1fb 6 b 14 1f6 7 b 14 1f1 8 b 14 03c 9 b 14 037 a b 14 032 b b 14 02d c b 14 028 d b 14 023 e b 14 01e f b 14 019 0 c 14 014 1 c 14 010 2 c 14 00c 3 c 14 008 4 c 14 004 5 c 14 000 6 c 14 1fc 7 c 14 1f8 8 c 14 034 9 c 14 030 a c 14 02c b c 14 028 c c 14 024 d c 14 020 e c 14 01c f c 14 018 0 d 14 014 1 d 14 011 2 d 14 00e 3 d 14 00b 4 d 14 008 5 d 14 005 6 d 14 002 7 d 14 1ff 8 d 14 02c 9 d 14 029 a d 14 026 b d 14 023 c d 14 020 d d 14 01d e d 14 01a f d 14 017 0 e 14 014 1 e 14 012 2 e 14 010 3 e 14 00e 4 e 14 00c 5 e 14 00a 6 e 14 008 7 e 14 006 8 e 14 024 9 e 14 022 a e 14 020 b e 14 01e c e 14 01c d e 14 01a e e 14 018 f e 14 016 0 f 14 014 1 f 14 013 2 f 14 012 3 f 14 011 4 f 14 010 5 f 14 00f 6 f 14 00e 7 f 14 00d 8 f 14 01c 9 f 14 01b a f 14 01a b f 14 019 c f 14 018 d f 14 017 e f 14 016 f f 14 015 0 0 15 015 1 0 15 015 2 0 15 015 3 0 15 015 4 0 15 015 5 0 15 015 6 0 15 015 7 0 15 015 8 0 15 015 9 0 15 015 a 0 15 015 b 0 15 015 c 0 15 015 d 0 15 015 e 0 15 015 f 0 15 015 0 1 15 015 1 1 15 016 2 1 15 017 3 1 15 018 4 1 15 019 5 1 15 01a 6 1 15 01b 7 1 15 01c 8 1 15 00d 9 1 15 00e a 1 15 00f b 1 15 010 c 1 15 011 d 1 15 012 e 1 15 013 f 1 15 014 0 2 15 015 1 2 15 017 2 2 15 019 3 2 15 01b 4 2 15 01d 5 2 15 01f 6 2 15 021 7 2 15 023 8 2 15 005 9 2 15 007 a 2 15 009 b 2 15 00b c 2 15 00d d 2 15 00f e 2 15 011 f 2 15 013 0 3 15 015 1 3 15 018 2 3 15 01b 3 3 15 01e 4 3 15 021 5 3 15 024 6 3 15 027 7 3 15 02a 8 3 15 1fd 9 3 15 000 a 3 15 003 b 3 15 006 c 3 15 009 d 3 15 00c e 3 15 00f f 3 15 012 0 4 15 015 1 4 15 019 2 4 15 01d 3 4 15 021 4 4 15 025 5 4 15 029 6 4 15 02d 7 4 15 031 8 4 15 1f5 9 4 15 1f9 a 4 15 1fd b 4 15 001 c 4 15 005 d 4 15 009 e 4 15 00d f 4 15 011 0 5 15 015 1 5 15 01a 2 5 15 01f 3 5 15 024 4 5 15 029 5 5 15 02e 6 5 15 033 7 5 15 038 8 5 15 1ed 9 5 15 1f2 a 5 15 1f7 b 5 15 1fc c 5 15 001 d 5 15 006 e 5 15 00b f 5 15 010 0 6 15 015 1 6 15 01b 2 6 15 021 3 6 15 027 4 6 15 02d 5 6 15 033 6 6 15 039 7 6 15 03f 8 6 15 1e5 9 6 15 1eb a 6 15 1f1 b 6 15 1f7 c 6 15 1fd d 6 15 003 e 6 15 009 f 6 15 00f 0 7 15 015 1 7 15 01c 2 7 15 023 3 7 15 02a 4 7 15 031 5 7 15 038 6 7 15 03f 7 7 15 046 8 7 15 1dd 9 7 15 1e4 a 7 15 1eb b 7 15 1f2 c 7 15 1f9 d 7 15 000 e 7 15 007 f 7 15 00e 0 8 15 015 1 8 15 00d 2 8 15 005 3 8 15 1fd 4 8 15 1f5 5 8 15 1ed 6 8 15 1e5 7 8 15 1dd 8 8 15 055 9 8 15 04d a 8 15 045 b 8 15 03d c 8 15 035 d 8 15 02d e 8 15 025 f 8 15 01d 0 9 15 015 1 9 15 00e 2 9 15 007 3 9 15 000 4 9 15 1f9 5 9 15 1f2 6 9 15 1eb 7 9 15 1e4 8 9 15 04d 9 9 15 046 a 9 15 03f b 9 15 038 c 9 15 031 d 9 15 02a e 9 15 023 f 9 15 01c 0 a 15 015 1 a 15 00f 2 a 15 009 3 a 15 003 4 a 15 1fd 5 a 15 1f7 6 a 15 1f1 7 a 15 1eb 8 a 15 045 9 a 15 03f a a 15 039 b a 15 033 c a 15 02d d a 15 027 e a 15 021 f a 15 01b 0 b 15 015 1 b 15 010 2 b 15 00b 3 b 15 006 4 b 15 001 5 b 15 1fc 6 b 15 1f7 7 b 15 1f2 8 b 15 03d 9 b 15 038 a b 15 033 b b 15 02e c b 15 029 d b 15 024 e b 15 01f f b 15 01a 0 c 15 015 1 c 15 011 2 c 15 00d 3 c 15 009 4 c 15 005 5 c 15 001 6 c 15 1fd 7 c 15 1f9 8 c 15 035 9 c 15 031 a c 15 02d b c 15 029 c c 15 025 d c 15 021 e c 15 01d f c 15 019 0 d 15 015 1 d 15 012 2 d 15 00f 3 d 15 00c 4 d 15 009 5 d 15 006 6 d 15 003 7 d 15 000 8 d 15 02d 9 d 15 02a a d 15 027 b d 15 024 c d 15 021 d d 15 01e e d 15 01b f d 15 018 0 e 15 015 1 e 15 013 2 e 15 011 3 e 15 00f 4 e 15 00d 5 e 15 00b 6 e 15 009 7 e 15 007 8 e 15 025 9 e 15 023 a e 15 021 b e 15 01f c e 15 01d d e 15 01b e e 15 019 f e 15 017 0 f 15 015 1 f 15 014 2 f 15 013 3 f 15 012 4 f 15 011 5 f 15 010 6 f 15 00f 7 f 15 00e 8 f 15 01d 9 f 15 01c a f 15 01b b f 15 01a c f 15 019 d f 15 018 e f 15 017 f f 15 016 0 0 16 016 1 0 16 016 2 0 16 016 3 0 16 016 4 0 16 016 5 0 16 016 6 0 16 016 7 0 16 016 8 0 16 016 9 0 16 016 a 0 16 016 b 0 16 016 c 0 16 016 d 0 16 016 e 0 16 016 f 0 16 016 0 1 16 016 1 1 16 017 2 1 16 018 3 1 16 019 4 1 16 01a 5 1 16 01b 6 1 16 01c 7 1 16 01d 8 1 16 00e 9 1 16 00f a 1 16 010 b 1 16 011 c 1 16 012 d 1 16 013 e 1 16 014 f 1 16 015 0 2 16 016 1 2 16 018 2 2 16 01a 3 2 16 01c 4 2 16 01e 5 2 16 020 6 2 16 022 7 2 16 024 8 2 16 006 9 2 16 008 a 2 16 00a b 2 16 00c c 2 16 00e d 2 16 010 e 2 16 012 f 2 16 014 0 3 16 016 1 3 16 019 2 3 16 01c 3 3 16 01f 4 3 16 022 5 3 16 025 6 3 16 028 7 3 16 02b 8 3 16 1fe 9 3 16 001 a 3 16 004 b 3 16 007 c 3 16 00a d 3 16 00d e 3 16 010 f 3 16 013 0 4 16 016 1 4 16 01a 2 4 16 01e 3 4 16 022 4 4 16 026 5 4 16 02a 6 4 16 02e 7 4 16 032 8 4 16 1f6 9 4 16 1fa a 4 16 1fe b 4 16 002 c 4 16 006 d 4 16 00a e 4 16 00e f 4 16 012 0 5 16 016 1 5 16 01b 2 5 16 020 3 5 16 025 4 5 16 02a 5 5 16 02f 6 5 16 034 7 5 16 039 8 5 16 1ee 9 5 16 1f3 a 5 16 1f8 b 5 16 1fd c 5 16 002 d 5 16 007 e 5 16 00c f 5 16 011 0 6 16 016 1 6 16 01c 2 6 16 022 3 6 16 028 4 6 16 02e 5 6 16 034 6 6 16 03a 7 6 16 040 8 6 16 1e6 9 6 16 1ec a 6 16 1f2 b 6 16 1f8 c 6 16 1fe d 6 16 004 e 6 16 00a f 6 16 010 0 7 16 016 1 7 16 01d 2 7 16 024 3 7 16 02b 4 7 16 032 5 7 16 039 6 7 16 040 7 7 16 047 8 7 16 1de 9 7 16 1e5 a 7 16 1ec b 7 16 1f3 c 7 16 1fa d 7 16 001 e 7 16 008 f 7 16 00f 0 8 16 016 1 8 16 00e 2 8 16 006 3 8 16 1fe 4 8 16 1f6 5 8 16 1ee 6 8 16 1e6 7 8 16 1de 8 8 16 056 9 8 16 04e a 8 16 046 b 8 16 03e c 8 16 036 d 8 16 02e e 8 16 026 f 8 16 01e 0 9 16 016 1 9 16 00f 2 9 16 008 3 9 16 001 4 9 16 1fa 5 9 16 1f3 6 9 16 1ec 7 9 16 1e5 8 9 16 04e 9 9 16 047 a 9 16 040 b 9 16 039 c 9 16 032 d 9 16 02b e 9 16 024 f 9 16 01d 0 a 16 016 1 a 16 010 2 a 16 00a 3 a 16 004 4 a 16 1fe 5 a 16 1f8 6 a 16 1f2 7 a 16 1ec 8 a 16 046 9 a 16 040 a a 16 03a b a 16 034 c a 16 02e d a 16 028 e a 16 022 f a 16 01c 0 b 16 016 1 b 16 011 2 b 16 00c 3 b 16 007 4 b 16 002 5 b 16 1fd 6 b 16 1f8 7 b 16 1f3 8 b 16 03e 9 b 16 039 a b 16 034 b b 16 02f c b 16 02a d b 16 025 e b 16 020 f b 16 01b 0 c 16 016 1 c 16 012 2 c 16 00e 3 c 16 00a 4 c 16 006 5 c 16 002 6 c 16 1fe 7 c 16 1fa 8 c 16 036 9 c 16 032 a c 16 02e b c 16 02a c c 16 026 d c 16 022 e c 16 01e f c 16 01a 0 d 16 016 1 d 16 013 2 d 16 010 3 d 16 00d 4 d 16 00a 5 d 16 007 6 d 16 004 7 d 16 001 8 d 16 02e 9 d 16 02b a d 16 028 b d 16 025 c d 16 022 d d 16 01f e d 16 01c f d 16 019 0 e 16 016 1 e 16 014 2 e 16 012 3 e 16 010 4 e 16 00e 5 e 16 00c 6 e 16 00a 7 e 16 008 8 e 16 026 9 e 16 024 a e 16 022 b e 16 020 c e 16 01e d e 16 01c e e 16 01a f e 16 018 0 f 16 016 1 f 16 015 2 f 16 014 3 f 16 013 4 f 16 012 5 f 16 011 6 f 16 010 7 f 16 00f 8 f 16 01e 9 f 16 01d a f 16 01c b f 16 01b c f 16 01a d f 16 019 e f 16 018 f f 16 017 0 0 17 017 1 0 17 017 2 0 17 017 3 0 17 017 4 0 17 017 5 0 17 017 6 0 17 017 7 0 17 017 8 0 17 017 9 0 17 017 a 0 17 017 b 0 17 017 c 0 17 017 d 0 17 017 e 0 17 017 f 0 17 017 0 1 17 017 1 1 17 018 2 1 17 019 3 1 17 01a 4 1 17 01b 5 1 17 01c 6 1 17 01d 7 1 17 01e 8 1 17 00f 9 1 17 010 a 1 17 011 b 1 17 012 c 1 17 013 d 1 17 014 e 1 17 015 f 1 17 016 0 2 17 017 1 2 17 019 2 2 17 01b 3 2 17 01d 4 2 17 01f 5 2 17 021 6 2 17 023 7 2 17 025 8 2 17 007 9 2 17 009 a 2 17 00b b 2 17 00d c 2 17 00f d 2 17 011 e 2 17 013 f 2 17 015 0 3 17 017 1 3 17 01a 2 3 17 01d 3 3 17 020 4 3 17 023 5 3 17 026 6 3 17 029 7 3 17 02c 8 3 17 1ff 9 3 17 002 a 3 17 005 b 3 17 008 c 3 17 00b d 3 17 00e e 3 17 011 f 3 17 014 0 4 17 017 1 4 17 01b 2 4 17 01f 3 4 17 023 4 4 17 027 5 4 17 02b 6 4 17 02f 7 4 17 033 8 4 17 1f7 9 4 17 1fb a 4 17 1ff b 4 17 003 c 4 17 007 d 4 17 00b e 4 17 00f f 4 17 013 0 5 17 017 1 5 17 01c 2 5 17 021 3 5 17 026 4 5 17 02b 5 5 17 030 6 5 17 035 7 5 17 03a 8 5 17 1ef 9 5 17 1f4 a 5 17 1f9 b 5 17 1fe c 5 17 003 d 5 17 008 e 5 17 00d f 5 17 012 0 6 17 017 1 6 17 01d 2 6 17 023 3 6 17 029 4 6 17 02f 5 6 17 035 6 6 17 03b 7 6 17 041 8 6 17 1e7 9 6 17 1ed a 6 17 1f3 b 6 17 1f9 c 6 17 1ff d 6 17 005 e 6 17 00b f 6 17 011 0 7 17 017 1 7 17 01e 2 7 17 025 3 7 17 02c 4 7 17 033 5 7 17 03a 6 7 17 041 7 7 17 048 8 7 17 1df 9 7 17 1e6 a 7 17 1ed b 7 17 1f4 c 7 17 1fb d 7 17 002 e 7 17 009 f 7 17 010 0 8 17 017 1 8 17 00f 2 8 17 007 3 8 17 1ff 4 8 17 1f7 5 8 17 1ef 6 8 17 1e7 7 8 17 1df 8 8 17 057 9 8 17 04f a 8 17 047 b 8 17 03f c 8 17 037 d 8 17 02f e 8 17 027 f 8 17 01f 0 9 17 017 1 9 17 010 2 9 17 009 3 9 17 002 4 9 17 1fb 5 9 17 1f4 6 9 17 1ed 7 9 17 1e6 8 9 17 04f 9 9 17 048 a 9 17 041 b 9 17 03a c 9 17 033 d 9 17 02c e 9 17 025 f 9 17 01e 0 a 17 017 1 a 17 011 2 a 17 00b 3 a 17 005 4 a 17 1ff 5 a 17 1f9 6 a 17 1f3 7 a 17 1ed 8 a 17 047 9 a 17 041 a a 17 03b b a 17 035 c a 17 02f d a 17 029 e a 17 023 f a 17 01d 0 b 17 017 1 b 17 012 2 b 17 00d 3 b 17 008 4 b 17 003 5 b 17 1fe 6 b 17 1f9 7 b 17 1f4 8 b 17 03f 9 b 17 03a a b 17 035 b b 17 030 c b 17 02b d b 17 026 e b 17 021 f b 17 01c 0 c 17 017 1 c 17 013 2 c 17 00f 3 c 17 00b 4 c 17 007 5 c 17 003 6 c 17 1ff 7 c 17 1fb 8 c 17 037 9 c 17 033 a c 17 02f b c 17 02b c c 17 027 d c 17 023 e c 17 01f f c 17 01b 0 d 17 017 1 d 17 014 2 d 17 011 3 d 17 00e 4 d 17 00b 5 d 17 008 6 d 17 005 7 d 17 002 8 d 17 02f 9 d 17 02c a d 17 029 b d 17 026 c d 17 023 d d 17 020 e d 17 01d f d 17 01a 0 e 17 017 1 e 17 015 2 e 17 013 3 e 17 011 4 e 17 00f 5 e 17 00d 6 e 17 00b 7 e 17 009 8 e 17 027 9 e 17 025 a e 17 023 b e 17 021 c e 17 01f d e 17 01d e e 17 01b f e 17 019 0 f 17 017 1 f 17 016 2 f 17 015 3 f 17 014 4 f 17 013 5 f 17 012 6 f 17 011 7 f 17 010 8 f 17 01f 9 f 17 01e a f 17 01d b f 17 01c c f 17 01b d f 17 01a e f 17 019 f f 17 018 0 0 18 018 1 0 18 018 2 0 18 018 3 0 18 018 4 0 18 018 5 0 18 018 6 0 18 018 7 0 18 018 8 0 18 018 9 0 18 018 a 0 18 018 b 0 18 018 c 0 18 018 d 0 18 018 e 0 18 018 f 0 18 018 0 1 18 018 1 1 18 019 2 1 18 01a 3 1 18 01b 4 1 18 01c 5 1 18 01d 6 1 18 01e 7 1 18 01f 8 1 18 010 9 1 18 011 a 1 18 012 b 1 18 013 c 1 18 014 d 1 18 015 e 1 18 016 f 1 18 017 0 2 18 018 1 2 18 01a 2 2 18 01c 3 2 18 01e 4 2 18 020 5 2 18 022 6 2 18 024 7 2 18 026 8 2 18 008 9 2 18 00a a 2 18 00c b 2 18 00e c 2 18 010 d 2 18 012 e 2 18 014 f 2 18 016 0 3 18 018 1 3 18 01b 2 3 18 01e 3 3 18 021 4 3 18 024 5 3 18 027 6 3 18 02a 7 3 18 02d 8 3 18 000 9 3 18 003 a 3 18 006 b 3 18 009 c 3 18 00c d 3 18 00f e 3 18 012 f 3 18 015 0 4 18 018 1 4 18 01c 2 4 18 020 3 4 18 024 4 4 18 028 5 4 18 02c 6 4 18 030 7 4 18 034 8 4 18 1f8 9 4 18 1fc a 4 18 000 b 4 18 004 c 4 18 008 d 4 18 00c e 4 18 010 f 4 18 014 0 5 18 018 1 5 18 01d 2 5 18 022 3 5 18 027 4 5 18 02c 5 5 18 031 6 5 18 036 7 5 18 03b 8 5 18 1f0 9 5 18 1f5 a 5 18 1fa b 5 18 1ff c 5 18 004 d 5 18 009 e 5 18 00e f 5 18 013 0 6 18 018 1 6 18 01e 2 6 18 024 3 6 18 02a 4 6 18 030 5 6 18 036 6 6 18 03c 7 6 18 042 8 6 18 1e8 9 6 18 1ee a 6 18 1f4 b 6 18 1fa c 6 18 000 d 6 18 006 e 6 18 00c f 6 18 012 0 7 18 018 1 7 18 01f 2 7 18 026 3 7 18 02d 4 7 18 034 5 7 18 03b 6 7 18 042 7 7 18 049 8 7 18 1e0 9 7 18 1e7 a 7 18 1ee b 7 18 1f5 c 7 18 1fc d 7 18 003 e 7 18 00a f 7 18 011 0 8 18 018 1 8 18 010 2 8 18 008 3 8 18 000 4 8 18 1f8 5 8 18 1f0 6 8 18 1e8 7 8 18 1e0 8 8 18 058 9 8 18 050 a 8 18 048 b 8 18 040 c 8 18 038 d 8 18 030 e 8 18 028 f 8 18 020 0 9 18 018 1 9 18 011 2 9 18 00a 3 9 18 003 4 9 18 1fc 5 9 18 1f5 6 9 18 1ee 7 9 18 1e7 8 9 18 050 9 9 18 049 a 9 18 042 b 9 18 03b c 9 18 034 d 9 18 02d e 9 18 026 f 9 18 01f 0 a 18 018 1 a 18 012 2 a 18 00c 3 a 18 006 4 a 18 000 5 a 18 1fa 6 a 18 1f4 7 a 18 1ee 8 a 18 048 9 a 18 042 a a 18 03c b a 18 036 c a 18 030 d a 18 02a e a 18 024 f a 18 01e 0 b 18 018 1 b 18 013 2 b 18 00e 3 b 18 009 4 b 18 004 5 b 18 1ff 6 b 18 1fa 7 b 18 1f5 8 b 18 040 9 b 18 03b a b 18 036 b b 18 031 c b 18 02c d b 18 027 e b 18 022 f b 18 01d 0 c 18 018 1 c 18 014 2 c 18 010 3 c 18 00c 4 c 18 008 5 c 18 004 6 c 18 000 7 c 18 1fc 8 c 18 038 9 c 18 034 a c 18 030 b c 18 02c c c 18 028 d c 18 024 e c 18 020 f c 18 01c 0 d 18 018 1 d 18 015 2 d 18 012 3 d 18 00f 4 d 18 00c 5 d 18 009 6 d 18 006 7 d 18 003 8 d 18 030 9 d 18 02d a d 18 02a b d 18 027 c d 18 024 d d 18 021 e d 18 01e f d 18 01b 0 e 18 018 1 e 18 016 2 e 18 014 3 e 18 012 4 e 18 010 5 e 18 00e 6 e 18 00c 7 e 18 00a 8 e 18 028 9 e 18 026 a e 18 024 b e 18 022 c e 18 020 d e 18 01e e e 18 01c f e 18 01a 0 f 18 018 1 f 18 017 2 f 18 016 3 f 18 015 4 f 18 014 5 f 18 013 6 f 18 012 7 f 18 011 8 f 18 020 9 f 18 01f a f 18 01e b f 18 01d c f 18 01c d f 18 01b e f 18 01a f f 18 019 0 0 19 019 1 0 19 019 2 0 19 019 3 0 19 019 4 0 19 019 5 0 19 019 6 0 19 019 7 0 19 019 8 0 19 019 9 0 19 019 a 0 19 019 b 0 19 019 c 0 19 019 d 0 19 019 e 0 19 019 f 0 19 019 0 1 19 019 1 1 19 01a 2 1 19 01b 3 1 19 01c 4 1 19 01d 5 1 19 01e 6 1 19 01f 7 1 19 020 8 1 19 011 9 1 19 012 a 1 19 013 b 1 19 014 c 1 19 015 d 1 19 016 e 1 19 017 f 1 19 018 0 2 19 019 1 2 19 01b 2 2 19 01d 3 2 19 01f 4 2 19 021 5 2 19 023 6 2 19 025 7 2 19 027 8 2 19 009 9 2 19 00b a 2 19 00d b 2 19 00f c 2 19 011 d 2 19 013 e 2 19 015 f 2 19 017 0 3 19 019 1 3 19 01c 2 3 19 01f 3 3 19 022 4 3 19 025 5 3 19 028 6 3 19 02b 7 3 19 02e 8 3 19 001 9 3 19 004 a 3 19 007 b 3 19 00a c 3 19 00d d 3 19 010 e 3 19 013 f 3 19 016 0 4 19 019 1 4 19 01d 2 4 19 021 3 4 19 025 4 4 19 029 5 4 19 02d 6 4 19 031 7 4 19 035 8 4 19 1f9 9 4 19 1fd a 4 19 001 b 4 19 005 c 4 19 009 d 4 19 00d e 4 19 011 f 4 19 015 0 5 19 019 1 5 19 01e 2 5 19 023 3 5 19 028 4 5 19 02d 5 5 19 032 6 5 19 037 7 5 19 03c 8 5 19 1f1 9 5 19 1f6 a 5 19 1fb b 5 19 000 c 5 19 005 d 5 19 00a e 5 19 00f f 5 19 014 0 6 19 019 1 6 19 01f 2 6 19 025 3 6 19 02b 4 6 19 031 5 6 19 037 6 6 19 03d 7 6 19 043 8 6 19 1e9 9 6 19 1ef a 6 19 1f5 b 6 19 1fb c 6 19 001 d 6 19 007 e 6 19 00d f 6 19 013 0 7 19 019 1 7 19 020 2 7 19 027 3 7 19 02e 4 7 19 035 5 7 19 03c 6 7 19 043 7 7 19 04a 8 7 19 1e1 9 7 19 1e8 a 7 19 1ef b 7 19 1f6 c 7 19 1fd d 7 19 004 e 7 19 00b f 7 19 012 0 8 19 019 1 8 19 011 2 8 19 009 3 8 19 001 4 8 19 1f9 5 8 19 1f1 6 8 19 1e9 7 8 19 1e1 8 8 19 059 9 8 19 051 a 8 19 049 b 8 19 041 c 8 19 039 d 8 19 031 e 8 19 029 f 8 19 021 0 9 19 019 1 9 19 012 2 9 19 00b 3 9 19 004 4 9 19 1fd 5 9 19 1f6 6 9 19 1ef 7 9 19 1e8 8 9 19 051 9 9 19 04a a 9 19 043 b 9 19 03c c 9 19 035 d 9 19 02e e 9 19 027 f 9 19 020 0 a 19 019 1 a 19 013 2 a 19 00d 3 a 19 007 4 a 19 001 5 a 19 1fb 6 a 19 1f5 7 a 19 1ef 8 a 19 049 9 a 19 043 a a 19 03d b a 19 037 c a 19 031 d a 19 02b e a 19 025 f a 19 01f 0 b 19 019 1 b 19 014 2 b 19 00f 3 b 19 00a 4 b 19 005 5 b 19 000 6 b 19 1fb 7 b 19 1f6 8 b 19 041 9 b 19 03c a b 19 037 b b 19 032 c b 19 02d d b 19 028 e b 19 023 f b 19 01e 0 c 19 019 1 c 19 015 2 c 19 011 3 c 19 00d 4 c 19 009 5 c 19 005 6 c 19 001 7 c 19 1fd 8 c 19 039 9 c 19 035 a c 19 031 b c 19 02d c c 19 029 d c 19 025 e c 19 021 f c 19 01d 0 d 19 019 1 d 19 016 2 d 19 013 3 d 19 010 4 d 19 00d 5 d 19 00a 6 d 19 007 7 d 19 004 8 d 19 031 9 d 19 02e a d 19 02b b d 19 028 c d 19 025 d d 19 022 e d 19 01f f d 19 01c 0 e 19 019 1 e 19 017 2 e 19 015 3 e 19 013 4 e 19 011 5 e 19 00f 6 e 19 00d 7 e 19 00b 8 e 19 029 9 e 19 027 a e 19 025 b e 19 023 c e 19 021 d e 19 01f e e 19 01d f e 19 01b 0 f 19 019 1 f 19 018 2 f 19 017 3 f 19 016 4 f 19 015 5 f 19 014 6 f 19 013 7 f 19 012 8 f 19 021 9 f 19 020 a f 19 01f b f 19 01e c f 19 01d d f 19 01c e f 19 01b f f 19 01a 0 0 1a 01a 1 0 1a 01a 2 0 1a 01a 3 0 1a 01a 4 0 1a 01a 5 0 1a 01a 6 0 1a 01a 7 0 1a 01a 8 0 1a 01a 9 0 1a 01a a 0 1a 01a b 0 1a 01a c 0 1a 01a d 0 1a 01a e 0 1a 01a f 0 1a 01a 0 1 1a 01a 1 1 1a 01b 2 1 1a 01c 3 1 1a 01d 4 1 1a 01e 5 1 1a 01f 6 1 1a 020 7 1 1a 021 8 1 1a 012 9 1 1a 013 a 1 1a 014 b 1 1a 015 c 1 1a 016 d 1 1a 017 e 1 1a 018 f 1 1a 019 0 2 1a 01a 1 2 1a 01c 2 2 1a 01e 3 2 1a 020 4 2 1a 022 5 2 1a 024 6 2 1a 026 7 2 1a 028 8 2 1a 00a 9 2 1a 00c a 2 1a 00e b 2 1a 010 c 2 1a 012 d 2 1a 014 e 2 1a 016 f 2 1a 018 0 3 1a 01a 1 3 1a 01d 2 3 1a 020 3 3 1a 023 4 3 1a 026 5 3 1a 029 6 3 1a 02c 7 3 1a 02f 8 3 1a 002 9 3 1a 005 a 3 1a 008 b 3 1a 00b c 3 1a 00e d 3 1a 011 e 3 1a 014 f 3 1a 017 0 4 1a 01a 1 4 1a 01e 2 4 1a 022 3 4 1a 026 4 4 1a 02a 5 4 1a 02e 6 4 1a 032 7 4 1a 036 8 4 1a 1fa 9 4 1a 1fe a 4 1a 002 b 4 1a 006 c 4 1a 00a d 4 1a 00e e 4 1a 012 f 4 1a 016 0 5 1a 01a 1 5 1a 01f 2 5 1a 024 3 5 1a 029 4 5 1a 02e 5 5 1a 033 6 5 1a 038 7 5 1a 03d 8 5 1a 1f2 9 5 1a 1f7 a 5 1a 1fc b 5 1a 001 c 5 1a 006 d 5 1a 00b e 5 1a 010 f 5 1a 015 0 6 1a 01a 1 6 1a 020 2 6 1a 026 3 6 1a 02c 4 6 1a 032 5 6 1a 038 6 6 1a 03e 7 6 1a 044 8 6 1a 1ea 9 6 1a 1f0 a 6 1a 1f6 b 6 1a 1fc c 6 1a 002 d 6 1a 008 e 6 1a 00e f 6 1a 014 0 7 1a 01a 1 7 1a 021 2 7 1a 028 3 7 1a 02f 4 7 1a 036 5 7 1a 03d 6 7 1a 044 7 7 1a 04b 8 7 1a 1e2 9 7 1a 1e9 a 7 1a 1f0 b 7 1a 1f7 c 7 1a 1fe d 7 1a 005 e 7 1a 00c f 7 1a 013 0 8 1a 01a 1 8 1a 012 2 8 1a 00a 3 8 1a 002 4 8 1a 1fa 5 8 1a 1f2 6 8 1a 1ea 7 8 1a 1e2 8 8 1a 05a 9 8 1a 052 a 8 1a 04a b 8 1a 042 c 8 1a 03a d 8 1a 032 e 8 1a 02a f 8 1a 022 0 9 1a 01a 1 9 1a 013 2 9 1a 00c 3 9 1a 005 4 9 1a 1fe 5 9 1a 1f7 6 9 1a 1f0 7 9 1a 1e9 8 9 1a 052 9 9 1a 04b a 9 1a 044 b 9 1a 03d c 9 1a 036 d 9 1a 02f e 9 1a 028 f 9 1a 021 0 a 1a 01a 1 a 1a 014 2 a 1a 00e 3 a 1a 008 4 a 1a 002 5 a 1a 1fc 6 a 1a 1f6 7 a 1a 1f0 8 a 1a 04a 9 a 1a 044 a a 1a 03e b a 1a 038 c a 1a 032 d a 1a 02c e a 1a 026 f a 1a 020 0 b 1a 01a 1 b 1a 015 2 b 1a 010 3 b 1a 00b 4 b 1a 006 5 b 1a 001 6 b 1a 1fc 7 b 1a 1f7 8 b 1a 042 9 b 1a 03d a b 1a 038 b b 1a 033 c b 1a 02e d b 1a 029 e b 1a 024 f b 1a 01f 0 c 1a 01a 1 c 1a 016 2 c 1a 012 3 c 1a 00e 4 c 1a 00a 5 c 1a 006 6 c 1a 002 7 c 1a 1fe 8 c 1a 03a 9 c 1a 036 a c 1a 032 b c 1a 02e c c 1a 02a d c 1a 026 e c 1a 022 f c 1a 01e 0 d 1a 01a 1 d 1a 017 2 d 1a 014 3 d 1a 011 4 d 1a 00e 5 d 1a 00b 6 d 1a 008 7 d 1a 005 8 d 1a 032 9 d 1a 02f a d 1a 02c b d 1a 029 c d 1a 026 d d 1a 023 e d 1a 020 f d 1a 01d 0 e 1a 01a 1 e 1a 018 2 e 1a 016 3 e 1a 014 4 e 1a 012 5 e 1a 010 6 e 1a 00e 7 e 1a 00c 8 e 1a 02a 9 e 1a 028 a e 1a 026 b e 1a 024 c e 1a 022 d e 1a 020 e e 1a 01e f e 1a 01c 0 f 1a 01a 1 f 1a 019 2 f 1a 018 3 f 1a 017 4 f 1a 016 5 f 1a 015 6 f 1a 014 7 f 1a 013 8 f 1a 022 9 f 1a 021 a f 1a 020 b f 1a 01f c f 1a 01e d f 1a 01d e f 1a 01c f f 1a 01b 0 0 1b 01b 1 0 1b 01b 2 0 1b 01b 3 0 1b 01b 4 0 1b 01b 5 0 1b 01b 6 0 1b 01b 7 0 1b 01b 8 0 1b 01b 9 0 1b 01b a 0 1b 01b b 0 1b 01b c 0 1b 01b d 0 1b 01b e 0 1b 01b f 0 1b 01b 0 1 1b 01b 1 1 1b 01c 2 1 1b 01d 3 1 1b 01e 4 1 1b 01f 5 1 1b 020 6 1 1b 021 7 1 1b 022 8 1 1b 013 9 1 1b 014 a 1 1b 015 b 1 1b 016 c 1 1b 017 d 1 1b 018 e 1 1b 019 f 1 1b 01a 0 2 1b 01b 1 2 1b 01d 2 2 1b 01f 3 2 1b 021 4 2 1b 023 5 2 1b 025 6 2 1b 027 7 2 1b 029 8 2 1b 00b 9 2 1b 00d a 2 1b 00f b 2 1b 011 c 2 1b 013 d 2 1b 015 e 2 1b 017 f 2 1b 019 0 3 1b 01b 1 3 1b 01e 2 3 1b 021 3 3 1b 024 4 3 1b 027 5 3 1b 02a 6 3 1b 02d 7 3 1b 030 8 3 1b 003 9 3 1b 006 a 3 1b 009 b 3 1b 00c c 3 1b 00f d 3 1b 012 e 3 1b 015 f 3 1b 018 0 4 1b 01b 1 4 1b 01f 2 4 1b 023 3 4 1b 027 4 4 1b 02b 5 4 1b 02f 6 4 1b 033 7 4 1b 037 8 4 1b 1fb 9 4 1b 1ff a 4 1b 003 b 4 1b 007 c 4 1b 00b d 4 1b 00f e 4 1b 013 f 4 1b 017 0 5 1b 01b 1 5 1b 020 2 5 1b 025 3 5 1b 02a 4 5 1b 02f 5 5 1b 034 6 5 1b 039 7 5 1b 03e 8 5 1b 1f3 9 5 1b 1f8 a 5 1b 1fd b 5 1b 002 c 5 1b 007 d 5 1b 00c e 5 1b 011 f 5 1b 016 0 6 1b 01b 1 6 1b 021 2 6 1b 027 3 6 1b 02d 4 6 1b 033 5 6 1b 039 6 6 1b 03f 7 6 1b 045 8 6 1b 1eb 9 6 1b 1f1 a 6 1b 1f7 b 6 1b 1fd c 6 1b 003 d 6 1b 009 e 6 1b 00f f 6 1b 015 0 7 1b 01b 1 7 1b 022 2 7 1b 029 3 7 1b 030 4 7 1b 037 5 7 1b 03e 6 7 1b 045 7 7 1b 04c 8 7 1b 1e3 9 7 1b 1ea a 7 1b 1f1 b 7 1b 1f8 c 7 1b 1ff d 7 1b 006 e 7 1b 00d f 7 1b 014 0 8 1b 01b 1 8 1b 013 2 8 1b 00b 3 8 1b 003 4 8 1b 1fb 5 8 1b 1f3 6 8 1b 1eb 7 8 1b 1e3 8 8 1b 05b 9 8 1b 053 a 8 1b 04b b 8 1b 043 c 8 1b 03b d 8 1b 033 e 8 1b 02b f 8 1b 023 0 9 1b 01b 1 9 1b 014 2 9 1b 00d 3 9 1b 006 4 9 1b 1ff 5 9 1b 1f8 6 9 1b 1f1 7 9 1b 1ea 8 9 1b 053 9 9 1b 04c a 9 1b 045 b 9 1b 03e c 9 1b 037 d 9 1b 030 e 9 1b 029 f 9 1b 022 0 a 1b 01b 1 a 1b 015 2 a 1b 00f 3 a 1b 009 4 a 1b 003 5 a 1b 1fd 6 a 1b 1f7 7 a 1b 1f1 8 a 1b 04b 9 a 1b 045 a a 1b 03f b a 1b 039 c a 1b 033 d a 1b 02d e a 1b 027 f a 1b 021 0 b 1b 01b 1 b 1b 016 2 b 1b 011 3 b 1b 00c 4 b 1b 007 5 b 1b 002 6 b 1b 1fd 7 b 1b 1f8 8 b 1b 043 9 b 1b 03e a b 1b 039 b b 1b 034 c b 1b 02f d b 1b 02a e b 1b 025 f b 1b 020 0 c 1b 01b 1 c 1b 017 2 c 1b 013 3 c 1b 00f 4 c 1b 00b 5 c 1b 007 6 c 1b 003 7 c 1b 1ff 8 c 1b 03b 9 c 1b 037 a c 1b 033 b c 1b 02f c c 1b 02b d c 1b 027 e c 1b 023 f c 1b 01f 0 d 1b 01b 1 d 1b 018 2 d 1b 015 3 d 1b 012 4 d 1b 00f 5 d 1b 00c 6 d 1b 009 7 d 1b 006 8 d 1b 033 9 d 1b 030 a d 1b 02d b d 1b 02a c d 1b 027 d d 1b 024 e d 1b 021 f d 1b 01e 0 e 1b 01b 1 e 1b 019 2 e 1b 017 3 e 1b 015 4 e 1b 013 5 e 1b 011 6 e 1b 00f 7 e 1b 00d 8 e 1b 02b 9 e 1b 029 a e 1b 027 b e 1b 025 c e 1b 023 d e 1b 021 e e 1b 01f f e 1b 01d 0 f 1b 01b 1 f 1b 01a 2 f 1b 019 3 f 1b 018 4 f 1b 017 5 f 1b 016 6 f 1b 015 7 f 1b 014 8 f 1b 023 9 f 1b 022 a f 1b 021 b f 1b 020 c f 1b 01f d f 1b 01e e f 1b 01d f f 1b 01c 0 0 1c 01c 1 0 1c 01c 2 0 1c 01c 3 0 1c 01c 4 0 1c 01c 5 0 1c 01c 6 0 1c 01c 7 0 1c 01c 8 0 1c 01c 9 0 1c 01c a 0 1c 01c b 0 1c 01c c 0 1c 01c d 0 1c 01c e 0 1c 01c f 0 1c 01c 0 1 1c 01c 1 1 1c 01d 2 1 1c 01e 3 1 1c 01f 4 1 1c 020 5 1 1c 021 6 1 1c 022 7 1 1c 023 8 1 1c 014 9 1 1c 015 a 1 1c 016 b 1 1c 017 c 1 1c 018 d 1 1c 019 e 1 1c 01a f 1 1c 01b 0 2 1c 01c 1 2 1c 01e 2 2 1c 020 3 2 1c 022 4 2 1c 024 5 2 1c 026 6 2 1c 028 7 2 1c 02a 8 2 1c 00c 9 2 1c 00e a 2 1c 010 b 2 1c 012 c 2 1c 014 d 2 1c 016 e 2 1c 018 f 2 1c 01a 0 3 1c 01c 1 3 1c 01f 2 3 1c 022 3 3 1c 025 4 3 1c 028 5 3 1c 02b 6 3 1c 02e 7 3 1c 031 8 3 1c 004 9 3 1c 007 a 3 1c 00a b 3 1c 00d c 3 1c 010 d 3 1c 013 e 3 1c 016 f 3 1c 019 0 4 1c 01c 1 4 1c 020 2 4 1c 024 3 4 1c 028 4 4 1c 02c 5 4 1c 030 6 4 1c 034 7 4 1c 038 8 4 1c 1fc 9 4 1c 000 a 4 1c 004 b 4 1c 008 c 4 1c 00c d 4 1c 010 e 4 1c 014 f 4 1c 018 0 5 1c 01c 1 5 1c 021 2 5 1c 026 3 5 1c 02b 4 5 1c 030 5 5 1c 035 6 5 1c 03a 7 5 1c 03f 8 5 1c 1f4 9 5 1c 1f9 a 5 1c 1fe b 5 1c 003 c 5 1c 008 d 5 1c 00d e 5 1c 012 f 5 1c 017 0 6 1c 01c 1 6 1c 022 2 6 1c 028 3 6 1c 02e 4 6 1c 034 5 6 1c 03a 6 6 1c 040 7 6 1c 046 8 6 1c 1ec 9 6 1c 1f2 a 6 1c 1f8 b 6 1c 1fe c 6 1c 004 d 6 1c 00a e 6 1c 010 f 6 1c 016 0 7 1c 01c 1 7 1c 023 2 7 1c 02a 3 7 1c 031 4 7 1c 038 5 7 1c 03f 6 7 1c 046 7 7 1c 04d 8 7 1c 1e4 9 7 1c 1eb a 7 1c 1f2 b 7 1c 1f9 c 7 1c 000 d 7 1c 007 e 7 1c 00e f 7 1c 015 0 8 1c 01c 1 8 1c 014 2 8 1c 00c 3 8 1c 004 4 8 1c 1fc 5 8 1c 1f4 6 8 1c 1ec 7 8 1c 1e4 8 8 1c 05c 9 8 1c 054 a 8 1c 04c b 8 1c 044 c 8 1c 03c d 8 1c 034 e 8 1c 02c f 8 1c 024 0 9 1c 01c 1 9 1c 015 2 9 1c 00e 3 9 1c 007 4 9 1c 000 5 9 1c 1f9 6 9 1c 1f2 7 9 1c 1eb 8 9 1c 054 9 9 1c 04d a 9 1c 046 b 9 1c 03f c 9 1c 038 d 9 1c 031 e 9 1c 02a f 9 1c 023 0 a 1c 01c 1 a 1c 016 2 a 1c 010 3 a 1c 00a 4 a 1c 004 5 a 1c 1fe 6 a 1c 1f8 7 a 1c 1f2 8 a 1c 04c 9 a 1c 046 a a 1c 040 b a 1c 03a c a 1c 034 d a 1c 02e e a 1c 028 f a 1c 022 0 b 1c 01c 1 b 1c 017 2 b 1c 012 3 b 1c 00d 4 b 1c 008 5 b 1c 003 6 b 1c 1fe 7 b 1c 1f9 8 b 1c 044 9 b 1c 03f a b 1c 03a b b 1c 035 c b 1c 030 d b 1c 02b e b 1c 026 f b 1c 021 0 c 1c 01c 1 c 1c 018 2 c 1c 014 3 c 1c 010 4 c 1c 00c 5 c 1c 008 6 c 1c 004 7 c 1c 000 8 c 1c 03c 9 c 1c 038 a c 1c 034 b c 1c 030 c c 1c 02c d c 1c 028 e c 1c 024 f c 1c 020 0 d 1c 01c 1 d 1c 019 2 d 1c 016 3 d 1c 013 4 d 1c 010 5 d 1c 00d 6 d 1c 00a 7 d 1c 007 8 d 1c 034 9 d 1c 031 a d 1c 02e b d 1c 02b c d 1c 028 d d 1c 025 e d 1c 022 f d 1c 01f 0 e 1c 01c 1 e 1c 01a 2 e 1c 018 3 e 1c 016 4 e 1c 014 5 e 1c 012 6 e 1c 010 7 e 1c 00e 8 e 1c 02c 9 e 1c 02a a e 1c 028 b e 1c 026 c e 1c 024 d e 1c 022 e e 1c 020 f e 1c 01e 0 f 1c 01c 1 f 1c 01b 2 f 1c 01a 3 f 1c 019 4 f 1c 018 5 f 1c 017 6 f 1c 016 7 f 1c 015 8 f 1c 024 9 f 1c 023 a f 1c 022 b f 1c 021 c f 1c 020 d f 1c 01f e f 1c 01e f f 1c 01d 0 0 1d 01d 1 0 1d 01d 2 0 1d 01d 3 0 1d 01d 4 0 1d 01d 5 0 1d 01d 6 0 1d 01d 7 0 1d 01d 8 0 1d 01d 9 0 1d 01d a 0 1d 01d b 0 1d 01d c 0 1d 01d d 0 1d 01d e 0 1d 01d f 0 1d 01d 0 1 1d 01d 1 1 1d 01e 2 1 1d 01f 3 1 1d 020 4 1 1d 021 5 1 1d 022 6 1 1d 023 7 1 1d 024 8 1 1d 015 9 1 1d 016 a 1 1d 017 b 1 1d 018 c 1 1d 019 d 1 1d 01a e 1 1d 01b f 1 1d 01c 0 2 1d 01d 1 2 1d 01f 2 2 1d 021 3 2 1d 023 4 2 1d 025 5 2 1d 027 6 2 1d 029 7 2 1d 02b 8 2 1d 00d 9 2 1d 00f a 2 1d 011 b 2 1d 013 c 2 1d 015 d 2 1d 017 e 2 1d 019 f 2 1d 01b 0 3 1d 01d 1 3 1d 020 2 3 1d 023 3 3 1d 026 4 3 1d 029 5 3 1d 02c 6 3 1d 02f 7 3 1d 032 8 3 1d 005 9 3 1d 008 a 3 1d 00b b 3 1d 00e c 3 1d 011 d 3 1d 014 e 3 1d 017 f 3 1d 01a 0 4 1d 01d 1 4 1d 021 2 4 1d 025 3 4 1d 029 4 4 1d 02d 5 4 1d 031 6 4 1d 035 7 4 1d 039 8 4 1d 1fd 9 4 1d 001 a 4 1d 005 b 4 1d 009 c 4 1d 00d d 4 1d 011 e 4 1d 015 f 4 1d 019 0 5 1d 01d 1 5 1d 022 2 5 1d 027 3 5 1d 02c 4 5 1d 031 5 5 1d 036 6 5 1d 03b 7 5 1d 040 8 5 1d 1f5 9 5 1d 1fa a 5 1d 1ff b 5 1d 004 c 5 1d 009 d 5 1d 00e e 5 1d 013 f 5 1d 018 0 6 1d 01d 1 6 1d 023 2 6 1d 029 3 6 1d 02f 4 6 1d 035 5 6 1d 03b 6 6 1d 041 7 6 1d 047 8 6 1d 1ed 9 6 1d 1f3 a 6 1d 1f9 b 6 1d 1ff c 6 1d 005 d 6 1d 00b e 6 1d 011 f 6 1d 017 0 7 1d 01d 1 7 1d 024 2 7 1d 02b 3 7 1d 032 4 7 1d 039 5 7 1d 040 6 7 1d 047 7 7 1d 04e 8 7 1d 1e5 9 7 1d 1ec a 7 1d 1f3 b 7 1d 1fa c 7 1d 001 d 7 1d 008 e 7 1d 00f f 7 1d 016 0 8 1d 01d 1 8 1d 015 2 8 1d 00d 3 8 1d 005 4 8 1d 1fd 5 8 1d 1f5 6 8 1d 1ed 7 8 1d 1e5 8 8 1d 05d 9 8 1d 055 a 8 1d 04d b 8 1d 045 c 8 1d 03d d 8 1d 035 e 8 1d 02d f 8 1d 025 0 9 1d 01d 1 9 1d 016 2 9 1d 00f 3 9 1d 008 4 9 1d 001 5 9 1d 1fa 6 9 1d 1f3 7 9 1d 1ec 8 9 1d 055 9 9 1d 04e a 9 1d 047 b 9 1d 040 c 9 1d 039 d 9 1d 032 e 9 1d 02b f 9 1d 024 0 a 1d 01d 1 a 1d 017 2 a 1d 011 3 a 1d 00b 4 a 1d 005 5 a 1d 1ff 6 a 1d 1f9 7 a 1d 1f3 8 a 1d 04d 9 a 1d 047 a a 1d 041 b a 1d 03b c a 1d 035 d a 1d 02f e a 1d 029 f a 1d 023 0 b 1d 01d 1 b 1d 018 2 b 1d 013 3 b 1d 00e 4 b 1d 009 5 b 1d 004 6 b 1d 1ff 7 b 1d 1fa 8 b 1d 045 9 b 1d 040 a b 1d 03b b b 1d 036 c b 1d 031 d b 1d 02c e b 1d 027 f b 1d 022 0 c 1d 01d 1 c 1d 019 2 c 1d 015 3 c 1d 011 4 c 1d 00d 5 c 1d 009 6 c 1d 005 7 c 1d 001 8 c 1d 03d 9 c 1d 039 a c 1d 035 b c 1d 031 c c 1d 02d d c 1d 029 e c 1d 025 f c 1d 021 0 d 1d 01d 1 d 1d 01a 2 d 1d 017 3 d 1d 014 4 d 1d 011 5 d 1d 00e 6 d 1d 00b 7 d 1d 008 8 d 1d 035 9 d 1d 032 a d 1d 02f b d 1d 02c c d 1d 029 d d 1d 026 e d 1d 023 f d 1d 020 0 e 1d 01d 1 e 1d 01b 2 e 1d 019 3 e 1d 017 4 e 1d 015 5 e 1d 013 6 e 1d 011 7 e 1d 00f 8 e 1d 02d 9 e 1d 02b a e 1d 029 b e 1d 027 c e 1d 025 d e 1d 023 e e 1d 021 f e 1d 01f 0 f 1d 01d 1 f 1d 01c 2 f 1d 01b 3 f 1d 01a 4 f 1d 019 5 f 1d 018 6 f 1d 017 7 f 1d 016 8 f 1d 025 9 f 1d 024 a f 1d 023 b f 1d 022 c f 1d 021 d f 1d 020 e f 1d 01f f f 1d 01e 0 0 1e 01e 1 0 1e 01e 2 0 1e 01e 3 0 1e 01e 4 0 1e 01e 5 0 1e 01e 6 0 1e 01e 7 0 1e 01e 8 0 1e 01e 9 0 1e 01e a 0 1e 01e b 0 1e 01e c 0 1e 01e d 0 1e 01e e 0 1e 01e f 0 1e 01e 0 1 1e 01e 1 1 1e 01f 2 1 1e 020 3 1 1e 021 4 1 1e 022 5 1 1e 023 6 1 1e 024 7 1 1e 025 8 1 1e 016 9 1 1e 017 a 1 1e 018 b 1 1e 019 c 1 1e 01a d 1 1e 01b e 1 1e 01c f 1 1e 01d 0 2 1e 01e 1 2 1e 020 2 2 1e 022 3 2 1e 024 4 2 1e 026 5 2 1e 028 6 2 1e 02a 7 2 1e 02c 8 2 1e 00e 9 2 1e 010 a 2 1e 012 b 2 1e 014 c 2 1e 016 d 2 1e 018 e 2 1e 01a f 2 1e 01c 0 3 1e 01e 1 3 1e 021 2 3 1e 024 3 3 1e 027 4 3 1e 02a 5 3 1e 02d 6 3 1e 030 7 3 1e 033 8 3 1e 006 9 3 1e 009 a 3 1e 00c b 3 1e 00f c 3 1e 012 d 3 1e 015 e 3 1e 018 f 3 1e 01b 0 4 1e 01e 1 4 1e 022 2 4 1e 026 3 4 1e 02a 4 4 1e 02e 5 4 1e 032 6 4 1e 036 7 4 1e 03a 8 4 1e 1fe 9 4 1e 002 a 4 1e 006 b 4 1e 00a c 4 1e 00e d 4 1e 012 e 4 1e 016 f 4 1e 01a 0 5 1e 01e 1 5 1e 023 2 5 1e 028 3 5 1e 02d 4 5 1e 032 5 5 1e 037 6 5 1e 03c 7 5 1e 041 8 5 1e 1f6 9 5 1e 1fb a 5 1e 000 b 5 1e 005 c 5 1e 00a d 5 1e 00f e 5 1e 014 f 5 1e 019 0 6 1e 01e 1 6 1e 024 2 6 1e 02a 3 6 1e 030 4 6 1e 036 5 6 1e 03c 6 6 1e 042 7 6 1e 048 8 6 1e 1ee 9 6 1e 1f4 a 6 1e 1fa b 6 1e 000 c 6 1e 006 d 6 1e 00c e 6 1e 012 f 6 1e 018 0 7 1e 01e 1 7 1e 025 2 7 1e 02c 3 7 1e 033 4 7 1e 03a 5 7 1e 041 6 7 1e 048 7 7 1e 04f 8 7 1e 1e6 9 7 1e 1ed a 7 1e 1f4 b 7 1e 1fb c 7 1e 002 d 7 1e 009 e 7 1e 010 f 7 1e 017 0 8 1e 01e 1 8 1e 016 2 8 1e 00e 3 8 1e 006 4 8 1e 1fe 5 8 1e 1f6 6 8 1e 1ee 7 8 1e 1e6 8 8 1e 05e 9 8 1e 056 a 8 1e 04e b 8 1e 046 c 8 1e 03e d 8 1e 036 e 8 1e 02e f 8 1e 026 0 9 1e 01e 1 9 1e 017 2 9 1e 010 3 9 1e 009 4 9 1e 002 5 9 1e 1fb 6 9 1e 1f4 7 9 1e 1ed 8 9 1e 056 9 9 1e 04f a 9 1e 048 b 9 1e 041 c 9 1e 03a d 9 1e 033 e 9 1e 02c f 9 1e 025 0 a 1e 01e 1 a 1e 018 2 a 1e 012 3 a 1e 00c 4 a 1e 006 5 a 1e 000 6 a 1e 1fa 7 a 1e 1f4 8 a 1e 04e 9 a 1e 048 a a 1e 042 b a 1e 03c c a 1e 036 d a 1e 030 e a 1e 02a f a 1e 024 0 b 1e 01e 1 b 1e 019 2 b 1e 014 3 b 1e 00f 4 b 1e 00a 5 b 1e 005 6 b 1e 000 7 b 1e 1fb 8 b 1e 046 9 b 1e 041 a b 1e 03c b b 1e 037 c b 1e 032 d b 1e 02d e b 1e 028 f b 1e 023 0 c 1e 01e 1 c 1e 01a 2 c 1e 016 3 c 1e 012 4 c 1e 00e 5 c 1e 00a 6 c 1e 006 7 c 1e 002 8 c 1e 03e 9 c 1e 03a a c 1e 036 b c 1e 032 c c 1e 02e d c 1e 02a e c 1e 026 f c 1e 022 0 d 1e 01e 1 d 1e 01b 2 d 1e 018 3 d 1e 015 4 d 1e 012 5 d 1e 00f 6 d 1e 00c 7 d 1e 009 8 d 1e 036 9 d 1e 033 a d 1e 030 b d 1e 02d c d 1e 02a d d 1e 027 e d 1e 024 f d 1e 021 0 e 1e 01e 1 e 1e 01c 2 e 1e 01a 3 e 1e 018 4 e 1e 016 5 e 1e 014 6 e 1e 012 7 e 1e 010 8 e 1e 02e 9 e 1e 02c a e 1e 02a b e 1e 028 c e 1e 026 d e 1e 024 e e 1e 022 f e 1e 020 0 f 1e 01e 1 f 1e 01d 2 f 1e 01c 3 f 1e 01b 4 f 1e 01a 5 f 1e 019 6 f 1e 018 7 f 1e 017 8 f 1e 026 9 f 1e 025 a f 1e 024 b f 1e 023 c f 1e 022 d f 1e 021 e f 1e 020 f f 1e 01f 0 0 1f 01f 1 0 1f 01f 2 0 1f 01f 3 0 1f 01f 4 0 1f 01f 5 0 1f 01f 6 0 1f 01f 7 0 1f 01f 8 0 1f 01f 9 0 1f 01f a 0 1f 01f b 0 1f 01f c 0 1f 01f d 0 1f 01f e 0 1f 01f f 0 1f 01f 0 1 1f 01f 1 1 1f 020 2 1 1f 021 3 1 1f 022 4 1 1f 023 5 1 1f 024 6 1 1f 025 7 1 1f 026 8 1 1f 017 9 1 1f 018 a 1 1f 019 b 1 1f 01a c 1 1f 01b d 1 1f 01c e 1 1f 01d f 1 1f 01e 0 2 1f 01f 1 2 1f 021 2 2 1f 023 3 2 1f 025 4 2 1f 027 5 2 1f 029 6 2 1f 02b 7 2 1f 02d 8 2 1f 00f 9 2 1f 011 a 2 1f 013 b 2 1f 015 c 2 1f 017 d 2 1f 019 e 2 1f 01b f 2 1f 01d 0 3 1f 01f 1 3 1f 022 2 3 1f 025 3 3 1f 028 4 3 1f 02b 5 3 1f 02e 6 3 1f 031 7 3 1f 034 8 3 1f 007 9 3 1f 00a a 3 1f 00d b 3 1f 010 c 3 1f 013 d 3 1f 016 e 3 1f 019 f 3 1f 01c 0 4 1f 01f 1 4 1f 023 2 4 1f 027 3 4 1f 02b 4 4 1f 02f 5 4 1f 033 6 4 1f 037 7 4 1f 03b 8 4 1f 1ff 9 4 1f 003 a 4 1f 007 b 4 1f 00b c 4 1f 00f d 4 1f 013 e 4 1f 017 f 4 1f 01b 0 5 1f 01f 1 5 1f 024 2 5 1f 029 3 5 1f 02e 4 5 1f 033 5 5 1f 038 6 5 1f 03d 7 5 1f 042 8 5 1f 1f7 9 5 1f 1fc a 5 1f 001 b 5 1f 006 c 5 1f 00b d 5 1f 010 e 5 1f 015 f 5 1f 01a 0 6 1f 01f 1 6 1f 025 2 6 1f 02b 3 6 1f 031 4 6 1f 037 5 6 1f 03d 6 6 1f 043 7 6 1f 049 8 6 1f 1ef 9 6 1f 1f5 a 6 1f 1fb b 6 1f 001 c 6 1f 007 d 6 1f 00d e 6 1f 013 f 6 1f 019 0 7 1f 01f 1 7 1f 026 2 7 1f 02d 3 7 1f 034 4 7 1f 03b 5 7 1f 042 6 7 1f 049 7 7 1f 050 8 7 1f 1e7 9 7 1f 1ee a 7 1f 1f5 b 7 1f 1fc c 7 1f 003 d 7 1f 00a e 7 1f 011 f 7 1f 018 0 8 1f 01f 1 8 1f 017 2 8 1f 00f 3 8 1f 007 4 8 1f 1ff 5 8 1f 1f7 6 8 1f 1ef 7 8 1f 1e7 8 8 1f 05f 9 8 1f 057 a 8 1f 04f b 8 1f 047 c 8 1f 03f d 8 1f 037 e 8 1f 02f f 8 1f 027 0 9 1f 01f 1 9 1f 018 2 9 1f 011 3 9 1f 00a 4 9 1f 003 5 9 1f 1fc 6 9 1f 1f5 7 9 1f 1ee 8 9 1f 057 9 9 1f 050 a 9 1f 049 b 9 1f 042 c 9 1f 03b d 9 1f 034 e 9 1f 02d f 9 1f 026 0 a 1f 01f 1 a 1f 019 2 a 1f 013 3 a 1f 00d 4 a 1f 007 5 a 1f 001 6 a 1f 1fb 7 a 1f 1f5 8 a 1f 04f 9 a 1f 049 a a 1f 043 b a 1f 03d c a 1f 037 d a 1f 031 e a 1f 02b f a 1f 025 0 b 1f 01f 1 b 1f 01a 2 b 1f 015 3 b 1f 010 4 b 1f 00b 5 b 1f 006 6 b 1f 001 7 b 1f 1fc 8 b 1f 047 9 b 1f 042 a b 1f 03d b b 1f 038 c b 1f 033 d b 1f 02e e b 1f 029 f b 1f 024 0 c 1f 01f 1 c 1f 01b 2 c 1f 017 3 c 1f 013 4 c 1f 00f 5 c 1f 00b 6 c 1f 007 7 c 1f 003 8 c 1f 03f 9 c 1f 03b a c 1f 037 b c 1f 033 c c 1f 02f d c 1f 02b e c 1f 027 f c 1f 023 0 d 1f 01f 1 d 1f 01c 2 d 1f 019 3 d 1f 016 4 d 1f 013 5 d 1f 010 6 d 1f 00d 7 d 1f 00a 8 d 1f 037 9 d 1f 034 a d 1f 031 b d 1f 02e c d 1f 02b d d 1f 028 e d 1f 025 f d 1f 022 0 e 1f 01f 1 e 1f 01d 2 e 1f 01b 3 e 1f 019 4 e 1f 017 5 e 1f 015 6 e 1f 013 7 e 1f 011 8 e 1f 02f 9 e 1f 02d a e 1f 02b b e 1f 029 c e 1f 027 d e 1f 025 e e 1f 023 f e 1f 021 0 f 1f 01f 1 f 1f 01e 2 f 1f 01d 3 f 1f 01c 4 f 1f 01b 5 f 1f 01a 6 f 1f 019 7 f 1f 018 8 f 1f 027 9 f 1f 026 a f 1f 025 b f 1f 024 c f 1f 023 d f 1f 022 e f 1f 021 f f 1f 020 0 0 20 020 1 0 20 020 2 0 20 020 3 0 20 020 4 0 20 020 5 0 20 020 6 0 20 020 7 0 20 020 8 0 20 020 9 0 20 020 a 0 20 020 b 0 20 020 c 0 20 020 d 0 20 020 e 0 20 020 f 0 20 020 0 1 20 020 1 1 20 021 2 1 20 022 3 1 20 023 4 1 20 024 5 1 20 025 6 1 20 026 7 1 20 027 8 1 20 018 9 1 20 019 a 1 20 01a b 1 20 01b c 1 20 01c d 1 20 01d e 1 20 01e f 1 20 01f 0 2 20 020 1 2 20 022 2 2 20 024 3 2 20 026 4 2 20 028 5 2 20 02a 6 2 20 02c 7 2 20 02e 8 2 20 010 9 2 20 012 a 2 20 014 b 2 20 016 c 2 20 018 d 2 20 01a e 2 20 01c f 2 20 01e 0 3 20 020 1 3 20 023 2 3 20 026 3 3 20 029 4 3 20 02c 5 3 20 02f 6 3 20 032 7 3 20 035 8 3 20 008 9 3 20 00b a 3 20 00e b 3 20 011 c 3 20 014 d 3 20 017 e 3 20 01a f 3 20 01d 0 4 20 020 1 4 20 024 2 4 20 028 3 4 20 02c 4 4 20 030 5 4 20 034 6 4 20 038 7 4 20 03c 8 4 20 000 9 4 20 004 a 4 20 008 b 4 20 00c c 4 20 010 d 4 20 014 e 4 20 018 f 4 20 01c 0 5 20 020 1 5 20 025 2 5 20 02a 3 5 20 02f 4 5 20 034 5 5 20 039 6 5 20 03e 7 5 20 043 8 5 20 1f8 9 5 20 1fd a 5 20 002 b 5 20 007 c 5 20 00c d 5 20 011 e 5 20 016 f 5 20 01b 0 6 20 020 1 6 20 026 2 6 20 02c 3 6 20 032 4 6 20 038 5 6 20 03e 6 6 20 044 7 6 20 04a 8 6 20 1f0 9 6 20 1f6 a 6 20 1fc b 6 20 002 c 6 20 008 d 6 20 00e e 6 20 014 f 6 20 01a 0 7 20 020 1 7 20 027 2 7 20 02e 3 7 20 035 4 7 20 03c 5 7 20 043 6 7 20 04a 7 7 20 051 8 7 20 1e8 9 7 20 1ef a 7 20 1f6 b 7 20 1fd c 7 20 004 d 7 20 00b e 7 20 012 f 7 20 019 0 8 20 020 1 8 20 018 2 8 20 010 3 8 20 008 4 8 20 000 5 8 20 1f8 6 8 20 1f0 7 8 20 1e8 8 8 20 060 9 8 20 058 a 8 20 050 b 8 20 048 c 8 20 040 d 8 20 038 e 8 20 030 f 8 20 028 0 9 20 020 1 9 20 019 2 9 20 012 3 9 20 00b 4 9 20 004 5 9 20 1fd 6 9 20 1f6 7 9 20 1ef 8 9 20 058 9 9 20 051 a 9 20 04a b 9 20 043 c 9 20 03c d 9 20 035 e 9 20 02e f 9 20 027 0 a 20 020 1 a 20 01a 2 a 20 014 3 a 20 00e 4 a 20 008 5 a 20 002 6 a 20 1fc 7 a 20 1f6 8 a 20 050 9 a 20 04a a a 20 044 b a 20 03e c a 20 038 d a 20 032 e a 20 02c f a 20 026 0 b 20 020 1 b 20 01b 2 b 20 016 3 b 20 011 4 b 20 00c 5 b 20 007 6 b 20 002 7 b 20 1fd 8 b 20 048 9 b 20 043 a b 20 03e b b 20 039 c b 20 034 d b 20 02f e b 20 02a f b 20 025 0 c 20 020 1 c 20 01c 2 c 20 018 3 c 20 014 4 c 20 010 5 c 20 00c 6 c 20 008 7 c 20 004 8 c 20 040 9 c 20 03c a c 20 038 b c 20 034 c c 20 030 d c 20 02c e c 20 028 f c 20 024 0 d 20 020 1 d 20 01d 2 d 20 01a 3 d 20 017 4 d 20 014 5 d 20 011 6 d 20 00e 7 d 20 00b 8 d 20 038 9 d 20 035 a d 20 032 b d 20 02f c d 20 02c d d 20 029 e d 20 026 f d 20 023 0 e 20 020 1 e 20 01e 2 e 20 01c 3 e 20 01a 4 e 20 018 5 e 20 016 6 e 20 014 7 e 20 012 8 e 20 030 9 e 20 02e a e 20 02c b e 20 02a c e 20 028 d e 20 026 e e 20 024 f e 20 022 0 f 20 020 1 f 20 01f 2 f 20 01e 3 f 20 01d 4 f 20 01c 5 f 20 01b 6 f 20 01a 7 f 20 019 8 f 20 028 9 f 20 027 a f 20 026 b f 20 025 c f 20 024 d f 20 023 e f 20 022 f f 20 021 0 0 21 021 1 0 21 021 2 0 21 021 3 0 21 021 4 0 21 021 5 0 21 021 6 0 21 021 7 0 21 021 8 0 21 021 9 0 21 021 a 0 21 021 b 0 21 021 c 0 21 021 d 0 21 021 e 0 21 021 f 0 21 021 0 1 21 021 1 1 21 022 2 1 21 023 3 1 21 024 4 1 21 025 5 1 21 026 6 1 21 027 7 1 21 028 8 1 21 019 9 1 21 01a a 1 21 01b b 1 21 01c c 1 21 01d d 1 21 01e e 1 21 01f f 1 21 020 0 2 21 021 1 2 21 023 2 2 21 025 3 2 21 027 4 2 21 029 5 2 21 02b 6 2 21 02d 7 2 21 02f 8 2 21 011 9 2 21 013 a 2 21 015 b 2 21 017 c 2 21 019 d 2 21 01b e 2 21 01d f 2 21 01f 0 3 21 021 1 3 21 024 2 3 21 027 3 3 21 02a 4 3 21 02d 5 3 21 030 6 3 21 033 7 3 21 036 8 3 21 009 9 3 21 00c a 3 21 00f b 3 21 012 c 3 21 015 d 3 21 018 e 3 21 01b f 3 21 01e 0 4 21 021 1 4 21 025 2 4 21 029 3 4 21 02d 4 4 21 031 5 4 21 035 6 4 21 039 7 4 21 03d 8 4 21 001 9 4 21 005 a 4 21 009 b 4 21 00d c 4 21 011 d 4 21 015 e 4 21 019 f 4 21 01d 0 5 21 021 1 5 21 026 2 5 21 02b 3 5 21 030 4 5 21 035 5 5 21 03a 6 5 21 03f 7 5 21 044 8 5 21 1f9 9 5 21 1fe a 5 21 003 b 5 21 008 c 5 21 00d d 5 21 012 e 5 21 017 f 5 21 01c 0 6 21 021 1 6 21 027 2 6 21 02d 3 6 21 033 4 6 21 039 5 6 21 03f 6 6 21 045 7 6 21 04b 8 6 21 1f1 9 6 21 1f7 a 6 21 1fd b 6 21 003 c 6 21 009 d 6 21 00f e 6 21 015 f 6 21 01b 0 7 21 021 1 7 21 028 2 7 21 02f 3 7 21 036 4 7 21 03d 5 7 21 044 6 7 21 04b 7 7 21 052 8 7 21 1e9 9 7 21 1f0 a 7 21 1f7 b 7 21 1fe c 7 21 005 d 7 21 00c e 7 21 013 f 7 21 01a 0 8 21 021 1 8 21 019 2 8 21 011 3 8 21 009 4 8 21 001 5 8 21 1f9 6 8 21 1f1 7 8 21 1e9 8 8 21 061 9 8 21 059 a 8 21 051 b 8 21 049 c 8 21 041 d 8 21 039 e 8 21 031 f 8 21 029 0 9 21 021 1 9 21 01a 2 9 21 013 3 9 21 00c 4 9 21 005 5 9 21 1fe 6 9 21 1f7 7 9 21 1f0 8 9 21 059 9 9 21 052 a 9 21 04b b 9 21 044 c 9 21 03d d 9 21 036 e 9 21 02f f 9 21 028 0 a 21 021 1 a 21 01b 2 a 21 015 3 a 21 00f 4 a 21 009 5 a 21 003 6 a 21 1fd 7 a 21 1f7 8 a 21 051 9 a 21 04b a a 21 045 b a 21 03f c a 21 039 d a 21 033 e a 21 02d f a 21 027 0 b 21 021 1 b 21 01c 2 b 21 017 3 b 21 012 4 b 21 00d 5 b 21 008 6 b 21 003 7 b 21 1fe 8 b 21 049 9 b 21 044 a b 21 03f b b 21 03a c b 21 035 d b 21 030 e b 21 02b f b 21 026 0 c 21 021 1 c 21 01d 2 c 21 019 3 c 21 015 4 c 21 011 5 c 21 00d 6 c 21 009 7 c 21 005 8 c 21 041 9 c 21 03d a c 21 039 b c 21 035 c c 21 031 d c 21 02d e c 21 029 f c 21 025 0 d 21 021 1 d 21 01e 2 d 21 01b 3 d 21 018 4 d 21 015 5 d 21 012 6 d 21 00f 7 d 21 00c 8 d 21 039 9 d 21 036 a d 21 033 b d 21 030 c d 21 02d d d 21 02a e d 21 027 f d 21 024 0 e 21 021 1 e 21 01f 2 e 21 01d 3 e 21 01b 4 e 21 019 5 e 21 017 6 e 21 015 7 e 21 013 8 e 21 031 9 e 21 02f a e 21 02d b e 21 02b c e 21 029 d e 21 027 e e 21 025 f e 21 023 0 f 21 021 1 f 21 020 2 f 21 01f 3 f 21 01e 4 f 21 01d 5 f 21 01c 6 f 21 01b 7 f 21 01a 8 f 21 029 9 f 21 028 a f 21 027 b f 21 026 c f 21 025 d f 21 024 e f 21 023 f f 21 022 0 0 22 022 1 0 22 022 2 0 22 022 3 0 22 022 4 0 22 022 5 0 22 022 6 0 22 022 7 0 22 022 8 0 22 022 9 0 22 022 a 0 22 022 b 0 22 022 c 0 22 022 d 0 22 022 e 0 22 022 f 0 22 022 0 1 22 022 1 1 22 023 2 1 22 024 3 1 22 025 4 1 22 026 5 1 22 027 6 1 22 028 7 1 22 029 8 1 22 01a 9 1 22 01b a 1 22 01c b 1 22 01d c 1 22 01e d 1 22 01f e 1 22 020 f 1 22 021 0 2 22 022 1 2 22 024 2 2 22 026 3 2 22 028 4 2 22 02a 5 2 22 02c 6 2 22 02e 7 2 22 030 8 2 22 012 9 2 22 014 a 2 22 016 b 2 22 018 c 2 22 01a d 2 22 01c e 2 22 01e f 2 22 020 0 3 22 022 1 3 22 025 2 3 22 028 3 3 22 02b 4 3 22 02e 5 3 22 031 6 3 22 034 7 3 22 037 8 3 22 00a 9 3 22 00d a 3 22 010 b 3 22 013 c 3 22 016 d 3 22 019 e 3 22 01c f 3 22 01f 0 4 22 022 1 4 22 026 2 4 22 02a 3 4 22 02e 4 4 22 032 5 4 22 036 6 4 22 03a 7 4 22 03e 8 4 22 002 9 4 22 006 a 4 22 00a b 4 22 00e c 4 22 012 d 4 22 016 e 4 22 01a f 4 22 01e 0 5 22 022 1 5 22 027 2 5 22 02c 3 5 22 031 4 5 22 036 5 5 22 03b 6 5 22 040 7 5 22 045 8 5 22 1fa 9 5 22 1ff a 5 22 004 b 5 22 009 c 5 22 00e d 5 22 013 e 5 22 018 f 5 22 01d 0 6 22 022 1 6 22 028 2 6 22 02e 3 6 22 034 4 6 22 03a 5 6 22 040 6 6 22 046 7 6 22 04c 8 6 22 1f2 9 6 22 1f8 a 6 22 1fe b 6 22 004 c 6 22 00a d 6 22 010 e 6 22 016 f 6 22 01c 0 7 22 022 1 7 22 029 2 7 22 030 3 7 22 037 4 7 22 03e 5 7 22 045 6 7 22 04c 7 7 22 053 8 7 22 1ea 9 7 22 1f1 a 7 22 1f8 b 7 22 1ff c 7 22 006 d 7 22 00d e 7 22 014 f 7 22 01b 0 8 22 022 1 8 22 01a 2 8 22 012 3 8 22 00a 4 8 22 002 5 8 22 1fa 6 8 22 1f2 7 8 22 1ea 8 8 22 062 9 8 22 05a a 8 22 052 b 8 22 04a c 8 22 042 d 8 22 03a e 8 22 032 f 8 22 02a 0 9 22 022 1 9 22 01b 2 9 22 014 3 9 22 00d 4 9 22 006 5 9 22 1ff 6 9 22 1f8 7 9 22 1f1 8 9 22 05a 9 9 22 053 a 9 22 04c b 9 22 045 c 9 22 03e d 9 22 037 e 9 22 030 f 9 22 029 0 a 22 022 1 a 22 01c 2 a 22 016 3 a 22 010 4 a 22 00a 5 a 22 004 6 a 22 1fe 7 a 22 1f8 8 a 22 052 9 a 22 04c a a 22 046 b a 22 040 c a 22 03a d a 22 034 e a 22 02e f a 22 028 0 b 22 022 1 b 22 01d 2 b 22 018 3 b 22 013 4 b 22 00e 5 b 22 009 6 b 22 004 7 b 22 1ff 8 b 22 04a 9 b 22 045 a b 22 040 b b 22 03b c b 22 036 d b 22 031 e b 22 02c f b 22 027 0 c 22 022 1 c 22 01e 2 c 22 01a 3 c 22 016 4 c 22 012 5 c 22 00e 6 c 22 00a 7 c 22 006 8 c 22 042 9 c 22 03e a c 22 03a b c 22 036 c c 22 032 d c 22 02e e c 22 02a f c 22 026 0 d 22 022 1 d 22 01f 2 d 22 01c 3 d 22 019 4 d 22 016 5 d 22 013 6 d 22 010 7 d 22 00d 8 d 22 03a 9 d 22 037 a d 22 034 b d 22 031 c d 22 02e d d 22 02b e d 22 028 f d 22 025 0 e 22 022 1 e 22 020 2 e 22 01e 3 e 22 01c 4 e 22 01a 5 e 22 018 6 e 22 016 7 e 22 014 8 e 22 032 9 e 22 030 a e 22 02e b e 22 02c c e 22 02a d e 22 028 e e 22 026 f e 22 024 0 f 22 022 1 f 22 021 2 f 22 020 3 f 22 01f 4 f 22 01e 5 f 22 01d 6 f 22 01c 7 f 22 01b 8 f 22 02a 9 f 22 029 a f 22 028 b f 22 027 c f 22 026 d f 22 025 e f 22 024 f f 22 023 0 0 23 023 1 0 23 023 2 0 23 023 3 0 23 023 4 0 23 023 5 0 23 023 6 0 23 023 7 0 23 023 8 0 23 023 9 0 23 023 a 0 23 023 b 0 23 023 c 0 23 023 d 0 23 023 e 0 23 023 f 0 23 023 0 1 23 023 1 1 23 024 2 1 23 025 3 1 23 026 4 1 23 027 5 1 23 028 6 1 23 029 7 1 23 02a 8 1 23 01b 9 1 23 01c a 1 23 01d b 1 23 01e c 1 23 01f d 1 23 020 e 1 23 021 f 1 23 022 0 2 23 023 1 2 23 025 2 2 23 027 3 2 23 029 4 2 23 02b 5 2 23 02d 6 2 23 02f 7 2 23 031 8 2 23 013 9 2 23 015 a 2 23 017 b 2 23 019 c 2 23 01b d 2 23 01d e 2 23 01f f 2 23 021 0 3 23 023 1 3 23 026 2 3 23 029 3 3 23 02c 4 3 23 02f 5 3 23 032 6 3 23 035 7 3 23 038 8 3 23 00b 9 3 23 00e a 3 23 011 b 3 23 014 c 3 23 017 d 3 23 01a e 3 23 01d f 3 23 020 0 4 23 023 1 4 23 027 2 4 23 02b 3 4 23 02f 4 4 23 033 5 4 23 037 6 4 23 03b 7 4 23 03f 8 4 23 003 9 4 23 007 a 4 23 00b b 4 23 00f c 4 23 013 d 4 23 017 e 4 23 01b f 4 23 01f 0 5 23 023 1 5 23 028 2 5 23 02d 3 5 23 032 4 5 23 037 5 5 23 03c 6 5 23 041 7 5 23 046 8 5 23 1fb 9 5 23 000 a 5 23 005 b 5 23 00a c 5 23 00f d 5 23 014 e 5 23 019 f 5 23 01e 0 6 23 023 1 6 23 029 2 6 23 02f 3 6 23 035 4 6 23 03b 5 6 23 041 6 6 23 047 7 6 23 04d 8 6 23 1f3 9 6 23 1f9 a 6 23 1ff b 6 23 005 c 6 23 00b d 6 23 011 e 6 23 017 f 6 23 01d 0 7 23 023 1 7 23 02a 2 7 23 031 3 7 23 038 4 7 23 03f 5 7 23 046 6 7 23 04d 7 7 23 054 8 7 23 1eb 9 7 23 1f2 a 7 23 1f9 b 7 23 000 c 7 23 007 d 7 23 00e e 7 23 015 f 7 23 01c 0 8 23 023 1 8 23 01b 2 8 23 013 3 8 23 00b 4 8 23 003 5 8 23 1fb 6 8 23 1f3 7 8 23 1eb 8 8 23 063 9 8 23 05b a 8 23 053 b 8 23 04b c 8 23 043 d 8 23 03b e 8 23 033 f 8 23 02b 0 9 23 023 1 9 23 01c 2 9 23 015 3 9 23 00e 4 9 23 007 5 9 23 000 6 9 23 1f9 7 9 23 1f2 8 9 23 05b 9 9 23 054 a 9 23 04d b 9 23 046 c 9 23 03f d 9 23 038 e 9 23 031 f 9 23 02a 0 a 23 023 1 a 23 01d 2 a 23 017 3 a 23 011 4 a 23 00b 5 a 23 005 6 a 23 1ff 7 a 23 1f9 8 a 23 053 9 a 23 04d a a 23 047 b a 23 041 c a 23 03b d a 23 035 e a 23 02f f a 23 029 0 b 23 023 1 b 23 01e 2 b 23 019 3 b 23 014 4 b 23 00f 5 b 23 00a 6 b 23 005 7 b 23 000 8 b 23 04b 9 b 23 046 a b 23 041 b b 23 03c c b 23 037 d b 23 032 e b 23 02d f b 23 028 0 c 23 023 1 c 23 01f 2 c 23 01b 3 c 23 017 4 c 23 013 5 c 23 00f 6 c 23 00b 7 c 23 007 8 c 23 043 9 c 23 03f a c 23 03b b c 23 037 c c 23 033 d c 23 02f e c 23 02b f c 23 027 0 d 23 023 1 d 23 020 2 d 23 01d 3 d 23 01a 4 d 23 017 5 d 23 014 6 d 23 011 7 d 23 00e 8 d 23 03b 9 d 23 038 a d 23 035 b d 23 032 c d 23 02f d d 23 02c e d 23 029 f d 23 026 0 e 23 023 1 e 23 021 2 e 23 01f 3 e 23 01d 4 e 23 01b 5 e 23 019 6 e 23 017 7 e 23 015 8 e 23 033 9 e 23 031 a e 23 02f b e 23 02d c e 23 02b d e 23 029 e e 23 027 f e 23 025 0 f 23 023 1 f 23 022 2 f 23 021 3 f 23 020 4 f 23 01f 5 f 23 01e 6 f 23 01d 7 f 23 01c 8 f 23 02b 9 f 23 02a a f 23 029 b f 23 028 c f 23 027 d f 23 026 e f 23 025 f f 23 024 0 0 24 024 1 0 24 024 2 0 24 024 3 0 24 024 4 0 24 024 5 0 24 024 6 0 24 024 7 0 24 024 8 0 24 024 9 0 24 024 a 0 24 024 b 0 24 024 c 0 24 024 d 0 24 024 e 0 24 024 f 0 24 024 0 1 24 024 1 1 24 025 2 1 24 026 3 1 24 027 4 1 24 028 5 1 24 029 6 1 24 02a 7 1 24 02b 8 1 24 01c 9 1 24 01d a 1 24 01e b 1 24 01f c 1 24 020 d 1 24 021 e 1 24 022 f 1 24 023 0 2 24 024 1 2 24 026 2 2 24 028 3 2 24 02a 4 2 24 02c 5 2 24 02e 6 2 24 030 7 2 24 032 8 2 24 014 9 2 24 016 a 2 24 018 b 2 24 01a c 2 24 01c d 2 24 01e e 2 24 020 f 2 24 022 0 3 24 024 1 3 24 027 2 3 24 02a 3 3 24 02d 4 3 24 030 5 3 24 033 6 3 24 036 7 3 24 039 8 3 24 00c 9 3 24 00f a 3 24 012 b 3 24 015 c 3 24 018 d 3 24 01b e 3 24 01e f 3 24 021 0 4 24 024 1 4 24 028 2 4 24 02c 3 4 24 030 4 4 24 034 5 4 24 038 6 4 24 03c 7 4 24 040 8 4 24 004 9 4 24 008 a 4 24 00c b 4 24 010 c 4 24 014 d 4 24 018 e 4 24 01c f 4 24 020 0 5 24 024 1 5 24 029 2 5 24 02e 3 5 24 033 4 5 24 038 5 5 24 03d 6 5 24 042 7 5 24 047 8 5 24 1fc 9 5 24 001 a 5 24 006 b 5 24 00b c 5 24 010 d 5 24 015 e 5 24 01a f 5 24 01f 0 6 24 024 1 6 24 02a 2 6 24 030 3 6 24 036 4 6 24 03c 5 6 24 042 6 6 24 048 7 6 24 04e 8 6 24 1f4 9 6 24 1fa a 6 24 000 b 6 24 006 c 6 24 00c d 6 24 012 e 6 24 018 f 6 24 01e 0 7 24 024 1 7 24 02b 2 7 24 032 3 7 24 039 4 7 24 040 5 7 24 047 6 7 24 04e 7 7 24 055 8 7 24 1ec 9 7 24 1f3 a 7 24 1fa b 7 24 001 c 7 24 008 d 7 24 00f e 7 24 016 f 7 24 01d 0 8 24 024 1 8 24 01c 2 8 24 014 3 8 24 00c 4 8 24 004 5 8 24 1fc 6 8 24 1f4 7 8 24 1ec 8 8 24 064 9 8 24 05c a 8 24 054 b 8 24 04c c 8 24 044 d 8 24 03c e 8 24 034 f 8 24 02c 0 9 24 024 1 9 24 01d 2 9 24 016 3 9 24 00f 4 9 24 008 5 9 24 001 6 9 24 1fa 7 9 24 1f3 8 9 24 05c 9 9 24 055 a 9 24 04e b 9 24 047 c 9 24 040 d 9 24 039 e 9 24 032 f 9 24 02b 0 a 24 024 1 a 24 01e 2 a 24 018 3 a 24 012 4 a 24 00c 5 a 24 006 6 a 24 000 7 a 24 1fa 8 a 24 054 9 a 24 04e a a 24 048 b a 24 042 c a 24 03c d a 24 036 e a 24 030 f a 24 02a 0 b 24 024 1 b 24 01f 2 b 24 01a 3 b 24 015 4 b 24 010 5 b 24 00b 6 b 24 006 7 b 24 001 8 b 24 04c 9 b 24 047 a b 24 042 b b 24 03d c b 24 038 d b 24 033 e b 24 02e f b 24 029 0 c 24 024 1 c 24 020 2 c 24 01c 3 c 24 018 4 c 24 014 5 c 24 010 6 c 24 00c 7 c 24 008 8 c 24 044 9 c 24 040 a c 24 03c b c 24 038 c c 24 034 d c 24 030 e c 24 02c f c 24 028 0 d 24 024 1 d 24 021 2 d 24 01e 3 d 24 01b 4 d 24 018 5 d 24 015 6 d 24 012 7 d 24 00f 8 d 24 03c 9 d 24 039 a d 24 036 b d 24 033 c d 24 030 d d 24 02d e d 24 02a f d 24 027 0 e 24 024 1 e 24 022 2 e 24 020 3 e 24 01e 4 e 24 01c 5 e 24 01a 6 e 24 018 7 e 24 016 8 e 24 034 9 e 24 032 a e 24 030 b e 24 02e c e 24 02c d e 24 02a e e 24 028 f e 24 026 0 f 24 024 1 f 24 023 2 f 24 022 3 f 24 021 4 f 24 020 5 f 24 01f 6 f 24 01e 7 f 24 01d 8 f 24 02c 9 f 24 02b a f 24 02a b f 24 029 c f 24 028 d f 24 027 e f 24 026 f f 24 025 0 0 25 025 1 0 25 025 2 0 25 025 3 0 25 025 4 0 25 025 5 0 25 025 6 0 25 025 7 0 25 025 8 0 25 025 9 0 25 025 a 0 25 025 b 0 25 025 c 0 25 025 d 0 25 025 e 0 25 025 f 0 25 025 0 1 25 025 1 1 25 026 2 1 25 027 3 1 25 028 4 1 25 029 5 1 25 02a 6 1 25 02b 7 1 25 02c 8 1 25 01d 9 1 25 01e a 1 25 01f b 1 25 020 c 1 25 021 d 1 25 022 e 1 25 023 f 1 25 024 0 2 25 025 1 2 25 027 2 2 25 029 3 2 25 02b 4 2 25 02d 5 2 25 02f 6 2 25 031 7 2 25 033 8 2 25 015 9 2 25 017 a 2 25 019 b 2 25 01b c 2 25 01d d 2 25 01f e 2 25 021 f 2 25 023 0 3 25 025 1 3 25 028 2 3 25 02b 3 3 25 02e 4 3 25 031 5 3 25 034 6 3 25 037 7 3 25 03a 8 3 25 00d 9 3 25 010 a 3 25 013 b 3 25 016 c 3 25 019 d 3 25 01c e 3 25 01f f 3 25 022 0 4 25 025 1 4 25 029 2 4 25 02d 3 4 25 031 4 4 25 035 5 4 25 039 6 4 25 03d 7 4 25 041 8 4 25 005 9 4 25 009 a 4 25 00d b 4 25 011 c 4 25 015 d 4 25 019 e 4 25 01d f 4 25 021 0 5 25 025 1 5 25 02a 2 5 25 02f 3 5 25 034 4 5 25 039 5 5 25 03e 6 5 25 043 7 5 25 048 8 5 25 1fd 9 5 25 002 a 5 25 007 b 5 25 00c c 5 25 011 d 5 25 016 e 5 25 01b f 5 25 020 0 6 25 025 1 6 25 02b 2 6 25 031 3 6 25 037 4 6 25 03d 5 6 25 043 6 6 25 049 7 6 25 04f 8 6 25 1f5 9 6 25 1fb a 6 25 001 b 6 25 007 c 6 25 00d d 6 25 013 e 6 25 019 f 6 25 01f 0 7 25 025 1 7 25 02c 2 7 25 033 3 7 25 03a 4 7 25 041 5 7 25 048 6 7 25 04f 7 7 25 056 8 7 25 1ed 9 7 25 1f4 a 7 25 1fb b 7 25 002 c 7 25 009 d 7 25 010 e 7 25 017 f 7 25 01e 0 8 25 025 1 8 25 01d 2 8 25 015 3 8 25 00d 4 8 25 005 5 8 25 1fd 6 8 25 1f5 7 8 25 1ed 8 8 25 065 9 8 25 05d a 8 25 055 b 8 25 04d c 8 25 045 d 8 25 03d e 8 25 035 f 8 25 02d 0 9 25 025 1 9 25 01e 2 9 25 017 3 9 25 010 4 9 25 009 5 9 25 002 6 9 25 1fb 7 9 25 1f4 8 9 25 05d 9 9 25 056 a 9 25 04f b 9 25 048 c 9 25 041 d 9 25 03a e 9 25 033 f 9 25 02c 0 a 25 025 1 a 25 01f 2 a 25 019 3 a 25 013 4 a 25 00d 5 a 25 007 6 a 25 001 7 a 25 1fb 8 a 25 055 9 a 25 04f a a 25 049 b a 25 043 c a 25 03d d a 25 037 e a 25 031 f a 25 02b 0 b 25 025 1 b 25 020 2 b 25 01b 3 b 25 016 4 b 25 011 5 b 25 00c 6 b 25 007 7 b 25 002 8 b 25 04d 9 b 25 048 a b 25 043 b b 25 03e c b 25 039 d b 25 034 e b 25 02f f b 25 02a 0 c 25 025 1 c 25 021 2 c 25 01d 3 c 25 019 4 c 25 015 5 c 25 011 6 c 25 00d 7 c 25 009 8 c 25 045 9 c 25 041 a c 25 03d b c 25 039 c c 25 035 d c 25 031 e c 25 02d f c 25 029 0 d 25 025 1 d 25 022 2 d 25 01f 3 d 25 01c 4 d 25 019 5 d 25 016 6 d 25 013 7 d 25 010 8 d 25 03d 9 d 25 03a a d 25 037 b d 25 034 c d 25 031 d d 25 02e e d 25 02b f d 25 028 0 e 25 025 1 e 25 023 2 e 25 021 3 e 25 01f 4 e 25 01d 5 e 25 01b 6 e 25 019 7 e 25 017 8 e 25 035 9 e 25 033 a e 25 031 b e 25 02f c e 25 02d d e 25 02b e e 25 029 f e 25 027 0 f 25 025 1 f 25 024 2 f 25 023 3 f 25 022 4 f 25 021 5 f 25 020 6 f 25 01f 7 f 25 01e 8 f 25 02d 9 f 25 02c a f 25 02b b f 25 02a c f 25 029 d f 25 028 e f 25 027 f f 25 026 0 0 26 026 1 0 26 026 2 0 26 026 3 0 26 026 4 0 26 026 5 0 26 026 6 0 26 026 7 0 26 026 8 0 26 026 9 0 26 026 a 0 26 026 b 0 26 026 c 0 26 026 d 0 26 026 e 0 26 026 f 0 26 026 0 1 26 026 1 1 26 027 2 1 26 028 3 1 26 029 4 1 26 02a 5 1 26 02b 6 1 26 02c 7 1 26 02d 8 1 26 01e 9 1 26 01f a 1 26 020 b 1 26 021 c 1 26 022 d 1 26 023 e 1 26 024 f 1 26 025 0 2 26 026 1 2 26 028 2 2 26 02a 3 2 26 02c 4 2 26 02e 5 2 26 030 6 2 26 032 7 2 26 034 8 2 26 016 9 2 26 018 a 2 26 01a b 2 26 01c c 2 26 01e d 2 26 020 e 2 26 022 f 2 26 024 0 3 26 026 1 3 26 029 2 3 26 02c 3 3 26 02f 4 3 26 032 5 3 26 035 6 3 26 038 7 3 26 03b 8 3 26 00e 9 3 26 011 a 3 26 014 b 3 26 017 c 3 26 01a d 3 26 01d e 3 26 020 f 3 26 023 0 4 26 026 1 4 26 02a 2 4 26 02e 3 4 26 032 4 4 26 036 5 4 26 03a 6 4 26 03e 7 4 26 042 8 4 26 006 9 4 26 00a a 4 26 00e b 4 26 012 c 4 26 016 d 4 26 01a e 4 26 01e f 4 26 022 0 5 26 026 1 5 26 02b 2 5 26 030 3 5 26 035 4 5 26 03a 5 5 26 03f 6 5 26 044 7 5 26 049 8 5 26 1fe 9 5 26 003 a 5 26 008 b 5 26 00d c 5 26 012 d 5 26 017 e 5 26 01c f 5 26 021 0 6 26 026 1 6 26 02c 2 6 26 032 3 6 26 038 4 6 26 03e 5 6 26 044 6 6 26 04a 7 6 26 050 8 6 26 1f6 9 6 26 1fc a 6 26 002 b 6 26 008 c 6 26 00e d 6 26 014 e 6 26 01a f 6 26 020 0 7 26 026 1 7 26 02d 2 7 26 034 3 7 26 03b 4 7 26 042 5 7 26 049 6 7 26 050 7 7 26 057 8 7 26 1ee 9 7 26 1f5 a 7 26 1fc b 7 26 003 c 7 26 00a d 7 26 011 e 7 26 018 f 7 26 01f 0 8 26 026 1 8 26 01e 2 8 26 016 3 8 26 00e 4 8 26 006 5 8 26 1fe 6 8 26 1f6 7 8 26 1ee 8 8 26 066 9 8 26 05e a 8 26 056 b 8 26 04e c 8 26 046 d 8 26 03e e 8 26 036 f 8 26 02e 0 9 26 026 1 9 26 01f 2 9 26 018 3 9 26 011 4 9 26 00a 5 9 26 003 6 9 26 1fc 7 9 26 1f5 8 9 26 05e 9 9 26 057 a 9 26 050 b 9 26 049 c 9 26 042 d 9 26 03b e 9 26 034 f 9 26 02d 0 a 26 026 1 a 26 020 2 a 26 01a 3 a 26 014 4 a 26 00e 5 a 26 008 6 a 26 002 7 a 26 1fc 8 a 26 056 9 a 26 050 a a 26 04a b a 26 044 c a 26 03e d a 26 038 e a 26 032 f a 26 02c 0 b 26 026 1 b 26 021 2 b 26 01c 3 b 26 017 4 b 26 012 5 b 26 00d 6 b 26 008 7 b 26 003 8 b 26 04e 9 b 26 049 a b 26 044 b b 26 03f c b 26 03a d b 26 035 e b 26 030 f b 26 02b 0 c 26 026 1 c 26 022 2 c 26 01e 3 c 26 01a 4 c 26 016 5 c 26 012 6 c 26 00e 7 c 26 00a 8 c 26 046 9 c 26 042 a c 26 03e b c 26 03a c c 26 036 d c 26 032 e c 26 02e f c 26 02a 0 d 26 026 1 d 26 023 2 d 26 020 3 d 26 01d 4 d 26 01a 5 d 26 017 6 d 26 014 7 d 26 011 8 d 26 03e 9 d 26 03b a d 26 038 b d 26 035 c d 26 032 d d 26 02f e d 26 02c f d 26 029 0 e 26 026 1 e 26 024 2 e 26 022 3 e 26 020 4 e 26 01e 5 e 26 01c 6 e 26 01a 7 e 26 018 8 e 26 036 9 e 26 034 a e 26 032 b e 26 030 c e 26 02e d e 26 02c e e 26 02a f e 26 028 0 f 26 026 1 f 26 025 2 f 26 024 3 f 26 023 4 f 26 022 5 f 26 021 6 f 26 020 7 f 26 01f 8 f 26 02e 9 f 26 02d a f 26 02c b f 26 02b c f 26 02a d f 26 029 e f 26 028 f f 26 027 0 0 27 027 1 0 27 027 2 0 27 027 3 0 27 027 4 0 27 027 5 0 27 027 6 0 27 027 7 0 27 027 8 0 27 027 9 0 27 027 a 0 27 027 b 0 27 027 c 0 27 027 d 0 27 027 e 0 27 027 f 0 27 027 0 1 27 027 1 1 27 028 2 1 27 029 3 1 27 02a 4 1 27 02b 5 1 27 02c 6 1 27 02d 7 1 27 02e 8 1 27 01f 9 1 27 020 a 1 27 021 b 1 27 022 c 1 27 023 d 1 27 024 e 1 27 025 f 1 27 026 0 2 27 027 1 2 27 029 2 2 27 02b 3 2 27 02d 4 2 27 02f 5 2 27 031 6 2 27 033 7 2 27 035 8 2 27 017 9 2 27 019 a 2 27 01b b 2 27 01d c 2 27 01f d 2 27 021 e 2 27 023 f 2 27 025 0 3 27 027 1 3 27 02a 2 3 27 02d 3 3 27 030 4 3 27 033 5 3 27 036 6 3 27 039 7 3 27 03c 8 3 27 00f 9 3 27 012 a 3 27 015 b 3 27 018 c 3 27 01b d 3 27 01e e 3 27 021 f 3 27 024 0 4 27 027 1 4 27 02b 2 4 27 02f 3 4 27 033 4 4 27 037 5 4 27 03b 6 4 27 03f 7 4 27 043 8 4 27 007 9 4 27 00b a 4 27 00f b 4 27 013 c 4 27 017 d 4 27 01b e 4 27 01f f 4 27 023 0 5 27 027 1 5 27 02c 2 5 27 031 3 5 27 036 4 5 27 03b 5 5 27 040 6 5 27 045 7 5 27 04a 8 5 27 1ff 9 5 27 004 a 5 27 009 b 5 27 00e c 5 27 013 d 5 27 018 e 5 27 01d f 5 27 022 0 6 27 027 1 6 27 02d 2 6 27 033 3 6 27 039 4 6 27 03f 5 6 27 045 6 6 27 04b 7 6 27 051 8 6 27 1f7 9 6 27 1fd a 6 27 003 b 6 27 009 c 6 27 00f d 6 27 015 e 6 27 01b f 6 27 021 0 7 27 027 1 7 27 02e 2 7 27 035 3 7 27 03c 4 7 27 043 5 7 27 04a 6 7 27 051 7 7 27 058 8 7 27 1ef 9 7 27 1f6 a 7 27 1fd b 7 27 004 c 7 27 00b d 7 27 012 e 7 27 019 f 7 27 020 0 8 27 027 1 8 27 01f 2 8 27 017 3 8 27 00f 4 8 27 007 5 8 27 1ff 6 8 27 1f7 7 8 27 1ef 8 8 27 067 9 8 27 05f a 8 27 057 b 8 27 04f c 8 27 047 d 8 27 03f e 8 27 037 f 8 27 02f 0 9 27 027 1 9 27 020 2 9 27 019 3 9 27 012 4 9 27 00b 5 9 27 004 6 9 27 1fd 7 9 27 1f6 8 9 27 05f 9 9 27 058 a 9 27 051 b 9 27 04a c 9 27 043 d 9 27 03c e 9 27 035 f 9 27 02e 0 a 27 027 1 a 27 021 2 a 27 01b 3 a 27 015 4 a 27 00f 5 a 27 009 6 a 27 003 7 a 27 1fd 8 a 27 057 9 a 27 051 a a 27 04b b a 27 045 c a 27 03f d a 27 039 e a 27 033 f a 27 02d 0 b 27 027 1 b 27 022 2 b 27 01d 3 b 27 018 4 b 27 013 5 b 27 00e 6 b 27 009 7 b 27 004 8 b 27 04f 9 b 27 04a a b 27 045 b b 27 040 c b 27 03b d b 27 036 e b 27 031 f b 27 02c 0 c 27 027 1 c 27 023 2 c 27 01f 3 c 27 01b 4 c 27 017 5 c 27 013 6 c 27 00f 7 c 27 00b 8 c 27 047 9 c 27 043 a c 27 03f b c 27 03b c c 27 037 d c 27 033 e c 27 02f f c 27 02b 0 d 27 027 1 d 27 024 2 d 27 021 3 d 27 01e 4 d 27 01b 5 d 27 018 6 d 27 015 7 d 27 012 8 d 27 03f 9 d 27 03c a d 27 039 b d 27 036 c d 27 033 d d 27 030 e d 27 02d f d 27 02a 0 e 27 027 1 e 27 025 2 e 27 023 3 e 27 021 4 e 27 01f 5 e 27 01d 6 e 27 01b 7 e 27 019 8 e 27 037 9 e 27 035 a e 27 033 b e 27 031 c e 27 02f d e 27 02d e e 27 02b f e 27 029 0 f 27 027 1 f 27 026 2 f 27 025 3 f 27 024 4 f 27 023 5 f 27 022 6 f 27 021 7 f 27 020 8 f 27 02f 9 f 27 02e a f 27 02d b f 27 02c c f 27 02b d f 27 02a e f 27 029 f f 27 028 0 0 28 028 1 0 28 028 2 0 28 028 3 0 28 028 4 0 28 028 5 0 28 028 6 0 28 028 7 0 28 028 8 0 28 028 9 0 28 028 a 0 28 028 b 0 28 028 c 0 28 028 d 0 28 028 e 0 28 028 f 0 28 028 0 1 28 028 1 1 28 029 2 1 28 02a 3 1 28 02b 4 1 28 02c 5 1 28 02d 6 1 28 02e 7 1 28 02f 8 1 28 020 9 1 28 021 a 1 28 022 b 1 28 023 c 1 28 024 d 1 28 025 e 1 28 026 f 1 28 027 0 2 28 028 1 2 28 02a 2 2 28 02c 3 2 28 02e 4 2 28 030 5 2 28 032 6 2 28 034 7 2 28 036 8 2 28 018 9 2 28 01a a 2 28 01c b 2 28 01e c 2 28 020 d 2 28 022 e 2 28 024 f 2 28 026 0 3 28 028 1 3 28 02b 2 3 28 02e 3 3 28 031 4 3 28 034 5 3 28 037 6 3 28 03a 7 3 28 03d 8 3 28 010 9 3 28 013 a 3 28 016 b 3 28 019 c 3 28 01c d 3 28 01f e 3 28 022 f 3 28 025 0 4 28 028 1 4 28 02c 2 4 28 030 3 4 28 034 4 4 28 038 5 4 28 03c 6 4 28 040 7 4 28 044 8 4 28 008 9 4 28 00c a 4 28 010 b 4 28 014 c 4 28 018 d 4 28 01c e 4 28 020 f 4 28 024 0 5 28 028 1 5 28 02d 2 5 28 032 3 5 28 037 4 5 28 03c 5 5 28 041 6 5 28 046 7 5 28 04b 8 5 28 000 9 5 28 005 a 5 28 00a b 5 28 00f c 5 28 014 d 5 28 019 e 5 28 01e f 5 28 023 0 6 28 028 1 6 28 02e 2 6 28 034 3 6 28 03a 4 6 28 040 5 6 28 046 6 6 28 04c 7 6 28 052 8 6 28 1f8 9 6 28 1fe a 6 28 004 b 6 28 00a c 6 28 010 d 6 28 016 e 6 28 01c f 6 28 022 0 7 28 028 1 7 28 02f 2 7 28 036 3 7 28 03d 4 7 28 044 5 7 28 04b 6 7 28 052 7 7 28 059 8 7 28 1f0 9 7 28 1f7 a 7 28 1fe b 7 28 005 c 7 28 00c d 7 28 013 e 7 28 01a f 7 28 021 0 8 28 028 1 8 28 020 2 8 28 018 3 8 28 010 4 8 28 008 5 8 28 000 6 8 28 1f8 7 8 28 1f0 8 8 28 068 9 8 28 060 a 8 28 058 b 8 28 050 c 8 28 048 d 8 28 040 e 8 28 038 f 8 28 030 0 9 28 028 1 9 28 021 2 9 28 01a 3 9 28 013 4 9 28 00c 5 9 28 005 6 9 28 1fe 7 9 28 1f7 8 9 28 060 9 9 28 059 a 9 28 052 b 9 28 04b c 9 28 044 d 9 28 03d e 9 28 036 f 9 28 02f 0 a 28 028 1 a 28 022 2 a 28 01c 3 a 28 016 4 a 28 010 5 a 28 00a 6 a 28 004 7 a 28 1fe 8 a 28 058 9 a 28 052 a a 28 04c b a 28 046 c a 28 040 d a 28 03a e a 28 034 f a 28 02e 0 b 28 028 1 b 28 023 2 b 28 01e 3 b 28 019 4 b 28 014 5 b 28 00f 6 b 28 00a 7 b 28 005 8 b 28 050 9 b 28 04b a b 28 046 b b 28 041 c b 28 03c d b 28 037 e b 28 032 f b 28 02d 0 c 28 028 1 c 28 024 2 c 28 020 3 c 28 01c 4 c 28 018 5 c 28 014 6 c 28 010 7 c 28 00c 8 c 28 048 9 c 28 044 a c 28 040 b c 28 03c c c 28 038 d c 28 034 e c 28 030 f c 28 02c 0 d 28 028 1 d 28 025 2 d 28 022 3 d 28 01f 4 d 28 01c 5 d 28 019 6 d 28 016 7 d 28 013 8 d 28 040 9 d 28 03d a d 28 03a b d 28 037 c d 28 034 d d 28 031 e d 28 02e f d 28 02b 0 e 28 028 1 e 28 026 2 e 28 024 3 e 28 022 4 e 28 020 5 e 28 01e 6 e 28 01c 7 e 28 01a 8 e 28 038 9 e 28 036 a e 28 034 b e 28 032 c e 28 030 d e 28 02e e e 28 02c f e 28 02a 0 f 28 028 1 f 28 027 2 f 28 026 3 f 28 025 4 f 28 024 5 f 28 023 6 f 28 022 7 f 28 021 8 f 28 030 9 f 28 02f a f 28 02e b f 28 02d c f 28 02c d f 28 02b e f 28 02a f f 28 029 0 0 29 029 1 0 29 029 2 0 29 029 3 0 29 029 4 0 29 029 5 0 29 029 6 0 29 029 7 0 29 029 8 0 29 029 9 0 29 029 a 0 29 029 b 0 29 029 c 0 29 029 d 0 29 029 e 0 29 029 f 0 29 029 0 1 29 029 1 1 29 02a 2 1 29 02b 3 1 29 02c 4 1 29 02d 5 1 29 02e 6 1 29 02f 7 1 29 030 8 1 29 021 9 1 29 022 a 1 29 023 b 1 29 024 c 1 29 025 d 1 29 026 e 1 29 027 f 1 29 028 0 2 29 029 1 2 29 02b 2 2 29 02d 3 2 29 02f 4 2 29 031 5 2 29 033 6 2 29 035 7 2 29 037 8 2 29 019 9 2 29 01b a 2 29 01d b 2 29 01f c 2 29 021 d 2 29 023 e 2 29 025 f 2 29 027 0 3 29 029 1 3 29 02c 2 3 29 02f 3 3 29 032 4 3 29 035 5 3 29 038 6 3 29 03b 7 3 29 03e 8 3 29 011 9 3 29 014 a 3 29 017 b 3 29 01a c 3 29 01d d 3 29 020 e 3 29 023 f 3 29 026 0 4 29 029 1 4 29 02d 2 4 29 031 3 4 29 035 4 4 29 039 5 4 29 03d 6 4 29 041 7 4 29 045 8 4 29 009 9 4 29 00d a 4 29 011 b 4 29 015 c 4 29 019 d 4 29 01d e 4 29 021 f 4 29 025 0 5 29 029 1 5 29 02e 2 5 29 033 3 5 29 038 4 5 29 03d 5 5 29 042 6 5 29 047 7 5 29 04c 8 5 29 001 9 5 29 006 a 5 29 00b b 5 29 010 c 5 29 015 d 5 29 01a e 5 29 01f f 5 29 024 0 6 29 029 1 6 29 02f 2 6 29 035 3 6 29 03b 4 6 29 041 5 6 29 047 6 6 29 04d 7 6 29 053 8 6 29 1f9 9 6 29 1ff a 6 29 005 b 6 29 00b c 6 29 011 d 6 29 017 e 6 29 01d f 6 29 023 0 7 29 029 1 7 29 030 2 7 29 037 3 7 29 03e 4 7 29 045 5 7 29 04c 6 7 29 053 7 7 29 05a 8 7 29 1f1 9 7 29 1f8 a 7 29 1ff b 7 29 006 c 7 29 00d d 7 29 014 e 7 29 01b f 7 29 022 0 8 29 029 1 8 29 021 2 8 29 019 3 8 29 011 4 8 29 009 5 8 29 001 6 8 29 1f9 7 8 29 1f1 8 8 29 069 9 8 29 061 a 8 29 059 b 8 29 051 c 8 29 049 d 8 29 041 e 8 29 039 f 8 29 031 0 9 29 029 1 9 29 022 2 9 29 01b 3 9 29 014 4 9 29 00d 5 9 29 006 6 9 29 1ff 7 9 29 1f8 8 9 29 061 9 9 29 05a a 9 29 053 b 9 29 04c c 9 29 045 d 9 29 03e e 9 29 037 f 9 29 030 0 a 29 029 1 a 29 023 2 a 29 01d 3 a 29 017 4 a 29 011 5 a 29 00b 6 a 29 005 7 a 29 1ff 8 a 29 059 9 a 29 053 a a 29 04d b a 29 047 c a 29 041 d a 29 03b e a 29 035 f a 29 02f 0 b 29 029 1 b 29 024 2 b 29 01f 3 b 29 01a 4 b 29 015 5 b 29 010 6 b 29 00b 7 b 29 006 8 b 29 051 9 b 29 04c a b 29 047 b b 29 042 c b 29 03d d b 29 038 e b 29 033 f b 29 02e 0 c 29 029 1 c 29 025 2 c 29 021 3 c 29 01d 4 c 29 019 5 c 29 015 6 c 29 011 7 c 29 00d 8 c 29 049 9 c 29 045 a c 29 041 b c 29 03d c c 29 039 d c 29 035 e c 29 031 f c 29 02d 0 d 29 029 1 d 29 026 2 d 29 023 3 d 29 020 4 d 29 01d 5 d 29 01a 6 d 29 017 7 d 29 014 8 d 29 041 9 d 29 03e a d 29 03b b d 29 038 c d 29 035 d d 29 032 e d 29 02f f d 29 02c 0 e 29 029 1 e 29 027 2 e 29 025 3 e 29 023 4 e 29 021 5 e 29 01f 6 e 29 01d 7 e 29 01b 8 e 29 039 9 e 29 037 a e 29 035 b e 29 033 c e 29 031 d e 29 02f e e 29 02d f e 29 02b 0 f 29 029 1 f 29 028 2 f 29 027 3 f 29 026 4 f 29 025 5 f 29 024 6 f 29 023 7 f 29 022 8 f 29 031 9 f 29 030 a f 29 02f b f 29 02e c f 29 02d d f 29 02c e f 29 02b f f 29 02a 0 0 2a 02a 1 0 2a 02a 2 0 2a 02a 3 0 2a 02a 4 0 2a 02a 5 0 2a 02a 6 0 2a 02a 7 0 2a 02a 8 0 2a 02a 9 0 2a 02a a 0 2a 02a b 0 2a 02a c 0 2a 02a d 0 2a 02a e 0 2a 02a f 0 2a 02a 0 1 2a 02a 1 1 2a 02b 2 1 2a 02c 3 1 2a 02d 4 1 2a 02e 5 1 2a 02f 6 1 2a 030 7 1 2a 031 8 1 2a 022 9 1 2a 023 a 1 2a 024 b 1 2a 025 c 1 2a 026 d 1 2a 027 e 1 2a 028 f 1 2a 029 0 2 2a 02a 1 2 2a 02c 2 2 2a 02e 3 2 2a 030 4 2 2a 032 5 2 2a 034 6 2 2a 036 7 2 2a 038 8 2 2a 01a 9 2 2a 01c a 2 2a 01e b 2 2a 020 c 2 2a 022 d 2 2a 024 e 2 2a 026 f 2 2a 028 0 3 2a 02a 1 3 2a 02d 2 3 2a 030 3 3 2a 033 4 3 2a 036 5 3 2a 039 6 3 2a 03c 7 3 2a 03f 8 3 2a 012 9 3 2a 015 a 3 2a 018 b 3 2a 01b c 3 2a 01e d 3 2a 021 e 3 2a 024 f 3 2a 027 0 4 2a 02a 1 4 2a 02e 2 4 2a 032 3 4 2a 036 4 4 2a 03a 5 4 2a 03e 6 4 2a 042 7 4 2a 046 8 4 2a 00a 9 4 2a 00e a 4 2a 012 b 4 2a 016 c 4 2a 01a d 4 2a 01e e 4 2a 022 f 4 2a 026 0 5 2a 02a 1 5 2a 02f 2 5 2a 034 3 5 2a 039 4 5 2a 03e 5 5 2a 043 6 5 2a 048 7 5 2a 04d 8 5 2a 002 9 5 2a 007 a 5 2a 00c b 5 2a 011 c 5 2a 016 d 5 2a 01b e 5 2a 020 f 5 2a 025 0 6 2a 02a 1 6 2a 030 2 6 2a 036 3 6 2a 03c 4 6 2a 042 5 6 2a 048 6 6 2a 04e 7 6 2a 054 8 6 2a 1fa 9 6 2a 000 a 6 2a 006 b 6 2a 00c c 6 2a 012 d 6 2a 018 e 6 2a 01e f 6 2a 024 0 7 2a 02a 1 7 2a 031 2 7 2a 038 3 7 2a 03f 4 7 2a 046 5 7 2a 04d 6 7 2a 054 7 7 2a 05b 8 7 2a 1f2 9 7 2a 1f9 a 7 2a 000 b 7 2a 007 c 7 2a 00e d 7 2a 015 e 7 2a 01c f 7 2a 023 0 8 2a 02a 1 8 2a 022 2 8 2a 01a 3 8 2a 012 4 8 2a 00a 5 8 2a 002 6 8 2a 1fa 7 8 2a 1f2 8 8 2a 06a 9 8 2a 062 a 8 2a 05a b 8 2a 052 c 8 2a 04a d 8 2a 042 e 8 2a 03a f 8 2a 032 0 9 2a 02a 1 9 2a 023 2 9 2a 01c 3 9 2a 015 4 9 2a 00e 5 9 2a 007 6 9 2a 000 7 9 2a 1f9 8 9 2a 062 9 9 2a 05b a 9 2a 054 b 9 2a 04d c 9 2a 046 d 9 2a 03f e 9 2a 038 f 9 2a 031 0 a 2a 02a 1 a 2a 024 2 a 2a 01e 3 a 2a 018 4 a 2a 012 5 a 2a 00c 6 a 2a 006 7 a 2a 000 8 a 2a 05a 9 a 2a 054 a a 2a 04e b a 2a 048 c a 2a 042 d a 2a 03c e a 2a 036 f a 2a 030 0 b 2a 02a 1 b 2a 025 2 b 2a 020 3 b 2a 01b 4 b 2a 016 5 b 2a 011 6 b 2a 00c 7 b 2a 007 8 b 2a 052 9 b 2a 04d a b 2a 048 b b 2a 043 c b 2a 03e d b 2a 039 e b 2a 034 f b 2a 02f 0 c 2a 02a 1 c 2a 026 2 c 2a 022 3 c 2a 01e 4 c 2a 01a 5 c 2a 016 6 c 2a 012 7 c 2a 00e 8 c 2a 04a 9 c 2a 046 a c 2a 042 b c 2a 03e c c 2a 03a d c 2a 036 e c 2a 032 f c 2a 02e 0 d 2a 02a 1 d 2a 027 2 d 2a 024 3 d 2a 021 4 d 2a 01e 5 d 2a 01b 6 d 2a 018 7 d 2a 015 8 d 2a 042 9 d 2a 03f a d 2a 03c b d 2a 039 c d 2a 036 d d 2a 033 e d 2a 030 f d 2a 02d 0 e 2a 02a 1 e 2a 028 2 e 2a 026 3 e 2a 024 4 e 2a 022 5 e 2a 020 6 e 2a 01e 7 e 2a 01c 8 e 2a 03a 9 e 2a 038 a e 2a 036 b e 2a 034 c e 2a 032 d e 2a 030 e e 2a 02e f e 2a 02c 0 f 2a 02a 1 f 2a 029 2 f 2a 028 3 f 2a 027 4 f 2a 026 5 f 2a 025 6 f 2a 024 7 f 2a 023 8 f 2a 032 9 f 2a 031 a f 2a 030 b f 2a 02f c f 2a 02e d f 2a 02d e f 2a 02c f f 2a 02b 0 0 2b 02b 1 0 2b 02b 2 0 2b 02b 3 0 2b 02b 4 0 2b 02b 5 0 2b 02b 6 0 2b 02b 7 0 2b 02b 8 0 2b 02b 9 0 2b 02b a 0 2b 02b b 0 2b 02b c 0 2b 02b d 0 2b 02b e 0 2b 02b f 0 2b 02b 0 1 2b 02b 1 1 2b 02c 2 1 2b 02d 3 1 2b 02e 4 1 2b 02f 5 1 2b 030 6 1 2b 031 7 1 2b 032 8 1 2b 023 9 1 2b 024 a 1 2b 025 b 1 2b 026 c 1 2b 027 d 1 2b 028 e 1 2b 029 f 1 2b 02a 0 2 2b 02b 1 2 2b 02d 2 2 2b 02f 3 2 2b 031 4 2 2b 033 5 2 2b 035 6 2 2b 037 7 2 2b 039 8 2 2b 01b 9 2 2b 01d a 2 2b 01f b 2 2b 021 c 2 2b 023 d 2 2b 025 e 2 2b 027 f 2 2b 029 0 3 2b 02b 1 3 2b 02e 2 3 2b 031 3 3 2b 034 4 3 2b 037 5 3 2b 03a 6 3 2b 03d 7 3 2b 040 8 3 2b 013 9 3 2b 016 a 3 2b 019 b 3 2b 01c c 3 2b 01f d 3 2b 022 e 3 2b 025 f 3 2b 028 0 4 2b 02b 1 4 2b 02f 2 4 2b 033 3 4 2b 037 4 4 2b 03b 5 4 2b 03f 6 4 2b 043 7 4 2b 047 8 4 2b 00b 9 4 2b 00f a 4 2b 013 b 4 2b 017 c 4 2b 01b d 4 2b 01f e 4 2b 023 f 4 2b 027 0 5 2b 02b 1 5 2b 030 2 5 2b 035 3 5 2b 03a 4 5 2b 03f 5 5 2b 044 6 5 2b 049 7 5 2b 04e 8 5 2b 003 9 5 2b 008 a 5 2b 00d b 5 2b 012 c 5 2b 017 d 5 2b 01c e 5 2b 021 f 5 2b 026 0 6 2b 02b 1 6 2b 031 2 6 2b 037 3 6 2b 03d 4 6 2b 043 5 6 2b 049 6 6 2b 04f 7 6 2b 055 8 6 2b 1fb 9 6 2b 001 a 6 2b 007 b 6 2b 00d c 6 2b 013 d 6 2b 019 e 6 2b 01f f 6 2b 025 0 7 2b 02b 1 7 2b 032 2 7 2b 039 3 7 2b 040 4 7 2b 047 5 7 2b 04e 6 7 2b 055 7 7 2b 05c 8 7 2b 1f3 9 7 2b 1fa a 7 2b 001 b 7 2b 008 c 7 2b 00f d 7 2b 016 e 7 2b 01d f 7 2b 024 0 8 2b 02b 1 8 2b 023 2 8 2b 01b 3 8 2b 013 4 8 2b 00b 5 8 2b 003 6 8 2b 1fb 7 8 2b 1f3 8 8 2b 06b 9 8 2b 063 a 8 2b 05b b 8 2b 053 c 8 2b 04b d 8 2b 043 e 8 2b 03b f 8 2b 033 0 9 2b 02b 1 9 2b 024 2 9 2b 01d 3 9 2b 016 4 9 2b 00f 5 9 2b 008 6 9 2b 001 7 9 2b 1fa 8 9 2b 063 9 9 2b 05c a 9 2b 055 b 9 2b 04e c 9 2b 047 d 9 2b 040 e 9 2b 039 f 9 2b 032 0 a 2b 02b 1 a 2b 025 2 a 2b 01f 3 a 2b 019 4 a 2b 013 5 a 2b 00d 6 a 2b 007 7 a 2b 001 8 a 2b 05b 9 a 2b 055 a a 2b 04f b a 2b 049 c a 2b 043 d a 2b 03d e a 2b 037 f a 2b 031 0 b 2b 02b 1 b 2b 026 2 b 2b 021 3 b 2b 01c 4 b 2b 017 5 b 2b 012 6 b 2b 00d 7 b 2b 008 8 b 2b 053 9 b 2b 04e a b 2b 049 b b 2b 044 c b 2b 03f d b 2b 03a e b 2b 035 f b 2b 030 0 c 2b 02b 1 c 2b 027 2 c 2b 023 3 c 2b 01f 4 c 2b 01b 5 c 2b 017 6 c 2b 013 7 c 2b 00f 8 c 2b 04b 9 c 2b 047 a c 2b 043 b c 2b 03f c c 2b 03b d c 2b 037 e c 2b 033 f c 2b 02f 0 d 2b 02b 1 d 2b 028 2 d 2b 025 3 d 2b 022 4 d 2b 01f 5 d 2b 01c 6 d 2b 019 7 d 2b 016 8 d 2b 043 9 d 2b 040 a d 2b 03d b d 2b 03a c d 2b 037 d d 2b 034 e d 2b 031 f d 2b 02e 0 e 2b 02b 1 e 2b 029 2 e 2b 027 3 e 2b 025 4 e 2b 023 5 e 2b 021 6 e 2b 01f 7 e 2b 01d 8 e 2b 03b 9 e 2b 039 a e 2b 037 b e 2b 035 c e 2b 033 d e 2b 031 e e 2b 02f f e 2b 02d 0 f 2b 02b 1 f 2b 02a 2 f 2b 029 3 f 2b 028 4 f 2b 027 5 f 2b 026 6 f 2b 025 7 f 2b 024 8 f 2b 033 9 f 2b 032 a f 2b 031 b f 2b 030 c f 2b 02f d f 2b 02e e f 2b 02d f f 2b 02c 0 0 2c 02c 1 0 2c 02c 2 0 2c 02c 3 0 2c 02c 4 0 2c 02c 5 0 2c 02c 6 0 2c 02c 7 0 2c 02c 8 0 2c 02c 9 0 2c 02c a 0 2c 02c b 0 2c 02c c 0 2c 02c d 0 2c 02c e 0 2c 02c f 0 2c 02c 0 1 2c 02c 1 1 2c 02d 2 1 2c 02e 3 1 2c 02f 4 1 2c 030 5 1 2c 031 6 1 2c 032 7 1 2c 033 8 1 2c 024 9 1 2c 025 a 1 2c 026 b 1 2c 027 c 1 2c 028 d 1 2c 029 e 1 2c 02a f 1 2c 02b 0 2 2c 02c 1 2 2c 02e 2 2 2c 030 3 2 2c 032 4 2 2c 034 5 2 2c 036 6 2 2c 038 7 2 2c 03a 8 2 2c 01c 9 2 2c 01e a 2 2c 020 b 2 2c 022 c 2 2c 024 d 2 2c 026 e 2 2c 028 f 2 2c 02a 0 3 2c 02c 1 3 2c 02f 2 3 2c 032 3 3 2c 035 4 3 2c 038 5 3 2c 03b 6 3 2c 03e 7 3 2c 041 8 3 2c 014 9 3 2c 017 a 3 2c 01a b 3 2c 01d c 3 2c 020 d 3 2c 023 e 3 2c 026 f 3 2c 029 0 4 2c 02c 1 4 2c 030 2 4 2c 034 3 4 2c 038 4 4 2c 03c 5 4 2c 040 6 4 2c 044 7 4 2c 048 8 4 2c 00c 9 4 2c 010 a 4 2c 014 b 4 2c 018 c 4 2c 01c d 4 2c 020 e 4 2c 024 f 4 2c 028 0 5 2c 02c 1 5 2c 031 2 5 2c 036 3 5 2c 03b 4 5 2c 040 5 5 2c 045 6 5 2c 04a 7 5 2c 04f 8 5 2c 004 9 5 2c 009 a 5 2c 00e b 5 2c 013 c 5 2c 018 d 5 2c 01d e 5 2c 022 f 5 2c 027 0 6 2c 02c 1 6 2c 032 2 6 2c 038 3 6 2c 03e 4 6 2c 044 5 6 2c 04a 6 6 2c 050 7 6 2c 056 8 6 2c 1fc 9 6 2c 002 a 6 2c 008 b 6 2c 00e c 6 2c 014 d 6 2c 01a e 6 2c 020 f 6 2c 026 0 7 2c 02c 1 7 2c 033 2 7 2c 03a 3 7 2c 041 4 7 2c 048 5 7 2c 04f 6 7 2c 056 7 7 2c 05d 8 7 2c 1f4 9 7 2c 1fb a 7 2c 002 b 7 2c 009 c 7 2c 010 d 7 2c 017 e 7 2c 01e f 7 2c 025 0 8 2c 02c 1 8 2c 024 2 8 2c 01c 3 8 2c 014 4 8 2c 00c 5 8 2c 004 6 8 2c 1fc 7 8 2c 1f4 8 8 2c 06c 9 8 2c 064 a 8 2c 05c b 8 2c 054 c 8 2c 04c d 8 2c 044 e 8 2c 03c f 8 2c 034 0 9 2c 02c 1 9 2c 025 2 9 2c 01e 3 9 2c 017 4 9 2c 010 5 9 2c 009 6 9 2c 002 7 9 2c 1fb 8 9 2c 064 9 9 2c 05d a 9 2c 056 b 9 2c 04f c 9 2c 048 d 9 2c 041 e 9 2c 03a f 9 2c 033 0 a 2c 02c 1 a 2c 026 2 a 2c 020 3 a 2c 01a 4 a 2c 014 5 a 2c 00e 6 a 2c 008 7 a 2c 002 8 a 2c 05c 9 a 2c 056 a a 2c 050 b a 2c 04a c a 2c 044 d a 2c 03e e a 2c 038 f a 2c 032 0 b 2c 02c 1 b 2c 027 2 b 2c 022 3 b 2c 01d 4 b 2c 018 5 b 2c 013 6 b 2c 00e 7 b 2c 009 8 b 2c 054 9 b 2c 04f a b 2c 04a b b 2c 045 c b 2c 040 d b 2c 03b e b 2c 036 f b 2c 031 0 c 2c 02c 1 c 2c 028 2 c 2c 024 3 c 2c 020 4 c 2c 01c 5 c 2c 018 6 c 2c 014 7 c 2c 010 8 c 2c 04c 9 c 2c 048 a c 2c 044 b c 2c 040 c c 2c 03c d c 2c 038 e c 2c 034 f c 2c 030 0 d 2c 02c 1 d 2c 029 2 d 2c 026 3 d 2c 023 4 d 2c 020 5 d 2c 01d 6 d 2c 01a 7 d 2c 017 8 d 2c 044 9 d 2c 041 a d 2c 03e b d 2c 03b c d 2c 038 d d 2c 035 e d 2c 032 f d 2c 02f 0 e 2c 02c 1 e 2c 02a 2 e 2c 028 3 e 2c 026 4 e 2c 024 5 e 2c 022 6 e 2c 020 7 e 2c 01e 8 e 2c 03c 9 e 2c 03a a e 2c 038 b e 2c 036 c e 2c 034 d e 2c 032 e e 2c 030 f e 2c 02e 0 f 2c 02c 1 f 2c 02b 2 f 2c 02a 3 f 2c 029 4 f 2c 028 5 f 2c 027 6 f 2c 026 7 f 2c 025 8 f 2c 034 9 f 2c 033 a f 2c 032 b f 2c 031 c f 2c 030 d f 2c 02f e f 2c 02e f f 2c 02d 0 0 2d 02d 1 0 2d 02d 2 0 2d 02d 3 0 2d 02d 4 0 2d 02d 5 0 2d 02d 6 0 2d 02d 7 0 2d 02d 8 0 2d 02d 9 0 2d 02d a 0 2d 02d b 0 2d 02d c 0 2d 02d d 0 2d 02d e 0 2d 02d f 0 2d 02d 0 1 2d 02d 1 1 2d 02e 2 1 2d 02f 3 1 2d 030 4 1 2d 031 5 1 2d 032 6 1 2d 033 7 1 2d 034 8 1 2d 025 9 1 2d 026 a 1 2d 027 b 1 2d 028 c 1 2d 029 d 1 2d 02a e 1 2d 02b f 1 2d 02c 0 2 2d 02d 1 2 2d 02f 2 2 2d 031 3 2 2d 033 4 2 2d 035 5 2 2d 037 6 2 2d 039 7 2 2d 03b 8 2 2d 01d 9 2 2d 01f a 2 2d 021 b 2 2d 023 c 2 2d 025 d 2 2d 027 e 2 2d 029 f 2 2d 02b 0 3 2d 02d 1 3 2d 030 2 3 2d 033 3 3 2d 036 4 3 2d 039 5 3 2d 03c 6 3 2d 03f 7 3 2d 042 8 3 2d 015 9 3 2d 018 a 3 2d 01b b 3 2d 01e c 3 2d 021 d 3 2d 024 e 3 2d 027 f 3 2d 02a 0 4 2d 02d 1 4 2d 031 2 4 2d 035 3 4 2d 039 4 4 2d 03d 5 4 2d 041 6 4 2d 045 7 4 2d 049 8 4 2d 00d 9 4 2d 011 a 4 2d 015 b 4 2d 019 c 4 2d 01d d 4 2d 021 e 4 2d 025 f 4 2d 029 0 5 2d 02d 1 5 2d 032 2 5 2d 037 3 5 2d 03c 4 5 2d 041 5 5 2d 046 6 5 2d 04b 7 5 2d 050 8 5 2d 005 9 5 2d 00a a 5 2d 00f b 5 2d 014 c 5 2d 019 d 5 2d 01e e 5 2d 023 f 5 2d 028 0 6 2d 02d 1 6 2d 033 2 6 2d 039 3 6 2d 03f 4 6 2d 045 5 6 2d 04b 6 6 2d 051 7 6 2d 057 8 6 2d 1fd 9 6 2d 003 a 6 2d 009 b 6 2d 00f c 6 2d 015 d 6 2d 01b e 6 2d 021 f 6 2d 027 0 7 2d 02d 1 7 2d 034 2 7 2d 03b 3 7 2d 042 4 7 2d 049 5 7 2d 050 6 7 2d 057 7 7 2d 05e 8 7 2d 1f5 9 7 2d 1fc a 7 2d 003 b 7 2d 00a c 7 2d 011 d 7 2d 018 e 7 2d 01f f 7 2d 026 0 8 2d 02d 1 8 2d 025 2 8 2d 01d 3 8 2d 015 4 8 2d 00d 5 8 2d 005 6 8 2d 1fd 7 8 2d 1f5 8 8 2d 06d 9 8 2d 065 a 8 2d 05d b 8 2d 055 c 8 2d 04d d 8 2d 045 e 8 2d 03d f 8 2d 035 0 9 2d 02d 1 9 2d 026 2 9 2d 01f 3 9 2d 018 4 9 2d 011 5 9 2d 00a 6 9 2d 003 7 9 2d 1fc 8 9 2d 065 9 9 2d 05e a 9 2d 057 b 9 2d 050 c 9 2d 049 d 9 2d 042 e 9 2d 03b f 9 2d 034 0 a 2d 02d 1 a 2d 027 2 a 2d 021 3 a 2d 01b 4 a 2d 015 5 a 2d 00f 6 a 2d 009 7 a 2d 003 8 a 2d 05d 9 a 2d 057 a a 2d 051 b a 2d 04b c a 2d 045 d a 2d 03f e a 2d 039 f a 2d 033 0 b 2d 02d 1 b 2d 028 2 b 2d 023 3 b 2d 01e 4 b 2d 019 5 b 2d 014 6 b 2d 00f 7 b 2d 00a 8 b 2d 055 9 b 2d 050 a b 2d 04b b b 2d 046 c b 2d 041 d b 2d 03c e b 2d 037 f b 2d 032 0 c 2d 02d 1 c 2d 029 2 c 2d 025 3 c 2d 021 4 c 2d 01d 5 c 2d 019 6 c 2d 015 7 c 2d 011 8 c 2d 04d 9 c 2d 049 a c 2d 045 b c 2d 041 c c 2d 03d d c 2d 039 e c 2d 035 f c 2d 031 0 d 2d 02d 1 d 2d 02a 2 d 2d 027 3 d 2d 024 4 d 2d 021 5 d 2d 01e 6 d 2d 01b 7 d 2d 018 8 d 2d 045 9 d 2d 042 a d 2d 03f b d 2d 03c c d 2d 039 d d 2d 036 e d 2d 033 f d 2d 030 0 e 2d 02d 1 e 2d 02b 2 e 2d 029 3 e 2d 027 4 e 2d 025 5 e 2d 023 6 e 2d 021 7 e 2d 01f 8 e 2d 03d 9 e 2d 03b a e 2d 039 b e 2d 037 c e 2d 035 d e 2d 033 e e 2d 031 f e 2d 02f 0 f 2d 02d 1 f 2d 02c 2 f 2d 02b 3 f 2d 02a 4 f 2d 029 5 f 2d 028 6 f 2d 027 7 f 2d 026 8 f 2d 035 9 f 2d 034 a f 2d 033 b f 2d 032 c f 2d 031 d f 2d 030 e f 2d 02f f f 2d 02e 0 0 2e 02e 1 0 2e 02e 2 0 2e 02e 3 0 2e 02e 4 0 2e 02e 5 0 2e 02e 6 0 2e 02e 7 0 2e 02e 8 0 2e 02e 9 0 2e 02e a 0 2e 02e b 0 2e 02e c 0 2e 02e d 0 2e 02e e 0 2e 02e f 0 2e 02e 0 1 2e 02e 1 1 2e 02f 2 1 2e 030 3 1 2e 031 4 1 2e 032 5 1 2e 033 6 1 2e 034 7 1 2e 035 8 1 2e 026 9 1 2e 027 a 1 2e 028 b 1 2e 029 c 1 2e 02a d 1 2e 02b e 1 2e 02c f 1 2e 02d 0 2 2e 02e 1 2 2e 030 2 2 2e 032 3 2 2e 034 4 2 2e 036 5 2 2e 038 6 2 2e 03a 7 2 2e 03c 8 2 2e 01e 9 2 2e 020 a 2 2e 022 b 2 2e 024 c 2 2e 026 d 2 2e 028 e 2 2e 02a f 2 2e 02c 0 3 2e 02e 1 3 2e 031 2 3 2e 034 3 3 2e 037 4 3 2e 03a 5 3 2e 03d 6 3 2e 040 7 3 2e 043 8 3 2e 016 9 3 2e 019 a 3 2e 01c b 3 2e 01f c 3 2e 022 d 3 2e 025 e 3 2e 028 f 3 2e 02b 0 4 2e 02e 1 4 2e 032 2 4 2e 036 3 4 2e 03a 4 4 2e 03e 5 4 2e 042 6 4 2e 046 7 4 2e 04a 8 4 2e 00e 9 4 2e 012 a 4 2e 016 b 4 2e 01a c 4 2e 01e d 4 2e 022 e 4 2e 026 f 4 2e 02a 0 5 2e 02e 1 5 2e 033 2 5 2e 038 3 5 2e 03d 4 5 2e 042 5 5 2e 047 6 5 2e 04c 7 5 2e 051 8 5 2e 006 9 5 2e 00b a 5 2e 010 b 5 2e 015 c 5 2e 01a d 5 2e 01f e 5 2e 024 f 5 2e 029 0 6 2e 02e 1 6 2e 034 2 6 2e 03a 3 6 2e 040 4 6 2e 046 5 6 2e 04c 6 6 2e 052 7 6 2e 058 8 6 2e 1fe 9 6 2e 004 a 6 2e 00a b 6 2e 010 c 6 2e 016 d 6 2e 01c e 6 2e 022 f 6 2e 028 0 7 2e 02e 1 7 2e 035 2 7 2e 03c 3 7 2e 043 4 7 2e 04a 5 7 2e 051 6 7 2e 058 7 7 2e 05f 8 7 2e 1f6 9 7 2e 1fd a 7 2e 004 b 7 2e 00b c 7 2e 012 d 7 2e 019 e 7 2e 020 f 7 2e 027 0 8 2e 02e 1 8 2e 026 2 8 2e 01e 3 8 2e 016 4 8 2e 00e 5 8 2e 006 6 8 2e 1fe 7 8 2e 1f6 8 8 2e 06e 9 8 2e 066 a 8 2e 05e b 8 2e 056 c 8 2e 04e d 8 2e 046 e 8 2e 03e f 8 2e 036 0 9 2e 02e 1 9 2e 027 2 9 2e 020 3 9 2e 019 4 9 2e 012 5 9 2e 00b 6 9 2e 004 7 9 2e 1fd 8 9 2e 066 9 9 2e 05f a 9 2e 058 b 9 2e 051 c 9 2e 04a d 9 2e 043 e 9 2e 03c f 9 2e 035 0 a 2e 02e 1 a 2e 028 2 a 2e 022 3 a 2e 01c 4 a 2e 016 5 a 2e 010 6 a 2e 00a 7 a 2e 004 8 a 2e 05e 9 a 2e 058 a a 2e 052 b a 2e 04c c a 2e 046 d a 2e 040 e a 2e 03a f a 2e 034 0 b 2e 02e 1 b 2e 029 2 b 2e 024 3 b 2e 01f 4 b 2e 01a 5 b 2e 015 6 b 2e 010 7 b 2e 00b 8 b 2e 056 9 b 2e 051 a b 2e 04c b b 2e 047 c b 2e 042 d b 2e 03d e b 2e 038 f b 2e 033 0 c 2e 02e 1 c 2e 02a 2 c 2e 026 3 c 2e 022 4 c 2e 01e 5 c 2e 01a 6 c 2e 016 7 c 2e 012 8 c 2e 04e 9 c 2e 04a a c 2e 046 b c 2e 042 c c 2e 03e d c 2e 03a e c 2e 036 f c 2e 032 0 d 2e 02e 1 d 2e 02b 2 d 2e 028 3 d 2e 025 4 d 2e 022 5 d 2e 01f 6 d 2e 01c 7 d 2e 019 8 d 2e 046 9 d 2e 043 a d 2e 040 b d 2e 03d c d 2e 03a d d 2e 037 e d 2e 034 f d 2e 031 0 e 2e 02e 1 e 2e 02c 2 e 2e 02a 3 e 2e 028 4 e 2e 026 5 e 2e 024 6 e 2e 022 7 e 2e 020 8 e 2e 03e 9 e 2e 03c a e 2e 03a b e 2e 038 c e 2e 036 d e 2e 034 e e 2e 032 f e 2e 030 0 f 2e 02e 1 f 2e 02d 2 f 2e 02c 3 f 2e 02b 4 f 2e 02a 5 f 2e 029 6 f 2e 028 7 f 2e 027 8 f 2e 036 9 f 2e 035 a f 2e 034 b f 2e 033 c f 2e 032 d f 2e 031 e f 2e 030 f f 2e 02f 0 0 2f 02f 1 0 2f 02f 2 0 2f 02f 3 0 2f 02f 4 0 2f 02f 5 0 2f 02f 6 0 2f 02f 7 0 2f 02f 8 0 2f 02f 9 0 2f 02f a 0 2f 02f b 0 2f 02f c 0 2f 02f d 0 2f 02f e 0 2f 02f f 0 2f 02f 0 1 2f 02f 1 1 2f 030 2 1 2f 031 3 1 2f 032 4 1 2f 033 5 1 2f 034 6 1 2f 035 7 1 2f 036 8 1 2f 027 9 1 2f 028 a 1 2f 029 b 1 2f 02a c 1 2f 02b d 1 2f 02c e 1 2f 02d f 1 2f 02e 0 2 2f 02f 1 2 2f 031 2 2 2f 033 3 2 2f 035 4 2 2f 037 5 2 2f 039 6 2 2f 03b 7 2 2f 03d 8 2 2f 01f 9 2 2f 021 a 2 2f 023 b 2 2f 025 c 2 2f 027 d 2 2f 029 e 2 2f 02b f 2 2f 02d 0 3 2f 02f 1 3 2f 032 2 3 2f 035 3 3 2f 038 4 3 2f 03b 5 3 2f 03e 6 3 2f 041 7 3 2f 044 8 3 2f 017 9 3 2f 01a a 3 2f 01d b 3 2f 020 c 3 2f 023 d 3 2f 026 e 3 2f 029 f 3 2f 02c 0 4 2f 02f 1 4 2f 033 2 4 2f 037 3 4 2f 03b 4 4 2f 03f 5 4 2f 043 6 4 2f 047 7 4 2f 04b 8 4 2f 00f 9 4 2f 013 a 4 2f 017 b 4 2f 01b c 4 2f 01f d 4 2f 023 e 4 2f 027 f 4 2f 02b 0 5 2f 02f 1 5 2f 034 2 5 2f 039 3 5 2f 03e 4 5 2f 043 5 5 2f 048 6 5 2f 04d 7 5 2f 052 8 5 2f 007 9 5 2f 00c a 5 2f 011 b 5 2f 016 c 5 2f 01b d 5 2f 020 e 5 2f 025 f 5 2f 02a 0 6 2f 02f 1 6 2f 035 2 6 2f 03b 3 6 2f 041 4 6 2f 047 5 6 2f 04d 6 6 2f 053 7 6 2f 059 8 6 2f 1ff 9 6 2f 005 a 6 2f 00b b 6 2f 011 c 6 2f 017 d 6 2f 01d e 6 2f 023 f 6 2f 029 0 7 2f 02f 1 7 2f 036 2 7 2f 03d 3 7 2f 044 4 7 2f 04b 5 7 2f 052 6 7 2f 059 7 7 2f 060 8 7 2f 1f7 9 7 2f 1fe a 7 2f 005 b 7 2f 00c c 7 2f 013 d 7 2f 01a e 7 2f 021 f 7 2f 028 0 8 2f 02f 1 8 2f 027 2 8 2f 01f 3 8 2f 017 4 8 2f 00f 5 8 2f 007 6 8 2f 1ff 7 8 2f 1f7 8 8 2f 06f 9 8 2f 067 a 8 2f 05f b 8 2f 057 c 8 2f 04f d 8 2f 047 e 8 2f 03f f 8 2f 037 0 9 2f 02f 1 9 2f 028 2 9 2f 021 3 9 2f 01a 4 9 2f 013 5 9 2f 00c 6 9 2f 005 7 9 2f 1fe 8 9 2f 067 9 9 2f 060 a 9 2f 059 b 9 2f 052 c 9 2f 04b d 9 2f 044 e 9 2f 03d f 9 2f 036 0 a 2f 02f 1 a 2f 029 2 a 2f 023 3 a 2f 01d 4 a 2f 017 5 a 2f 011 6 a 2f 00b 7 a 2f 005 8 a 2f 05f 9 a 2f 059 a a 2f 053 b a 2f 04d c a 2f 047 d a 2f 041 e a 2f 03b f a 2f 035 0 b 2f 02f 1 b 2f 02a 2 b 2f 025 3 b 2f 020 4 b 2f 01b 5 b 2f 016 6 b 2f 011 7 b 2f 00c 8 b 2f 057 9 b 2f 052 a b 2f 04d b b 2f 048 c b 2f 043 d b 2f 03e e b 2f 039 f b 2f 034 0 c 2f 02f 1 c 2f 02b 2 c 2f 027 3 c 2f 023 4 c 2f 01f 5 c 2f 01b 6 c 2f 017 7 c 2f 013 8 c 2f 04f 9 c 2f 04b a c 2f 047 b c 2f 043 c c 2f 03f d c 2f 03b e c 2f 037 f c 2f 033 0 d 2f 02f 1 d 2f 02c 2 d 2f 029 3 d 2f 026 4 d 2f 023 5 d 2f 020 6 d 2f 01d 7 d 2f 01a 8 d 2f 047 9 d 2f 044 a d 2f 041 b d 2f 03e c d 2f 03b d d 2f 038 e d 2f 035 f d 2f 032 0 e 2f 02f 1 e 2f 02d 2 e 2f 02b 3 e 2f 029 4 e 2f 027 5 e 2f 025 6 e 2f 023 7 e 2f 021 8 e 2f 03f 9 e 2f 03d a e 2f 03b b e 2f 039 c e 2f 037 d e 2f 035 e e 2f 033 f e 2f 031 0 f 2f 02f 1 f 2f 02e 2 f 2f 02d 3 f 2f 02c 4 f 2f 02b 5 f 2f 02a 6 f 2f 029 7 f 2f 028 8 f 2f 037 9 f 2f 036 a f 2f 035 b f 2f 034 c f 2f 033 d f 2f 032 e f 2f 031 f f 2f 030 0 0 30 030 1 0 30 030 2 0 30 030 3 0 30 030 4 0 30 030 5 0 30 030 6 0 30 030 7 0 30 030 8 0 30 030 9 0 30 030 a 0 30 030 b 0 30 030 c 0 30 030 d 0 30 030 e 0 30 030 f 0 30 030 0 1 30 030 1 1 30 031 2 1 30 032 3 1 30 033 4 1 30 034 5 1 30 035 6 1 30 036 7 1 30 037 8 1 30 028 9 1 30 029 a 1 30 02a b 1 30 02b c 1 30 02c d 1 30 02d e 1 30 02e f 1 30 02f 0 2 30 030 1 2 30 032 2 2 30 034 3 2 30 036 4 2 30 038 5 2 30 03a 6 2 30 03c 7 2 30 03e 8 2 30 020 9 2 30 022 a 2 30 024 b 2 30 026 c 2 30 028 d 2 30 02a e 2 30 02c f 2 30 02e 0 3 30 030 1 3 30 033 2 3 30 036 3 3 30 039 4 3 30 03c 5 3 30 03f 6 3 30 042 7 3 30 045 8 3 30 018 9 3 30 01b a 3 30 01e b 3 30 021 c 3 30 024 d 3 30 027 e 3 30 02a f 3 30 02d 0 4 30 030 1 4 30 034 2 4 30 038 3 4 30 03c 4 4 30 040 5 4 30 044 6 4 30 048 7 4 30 04c 8 4 30 010 9 4 30 014 a 4 30 018 b 4 30 01c c 4 30 020 d 4 30 024 e 4 30 028 f 4 30 02c 0 5 30 030 1 5 30 035 2 5 30 03a 3 5 30 03f 4 5 30 044 5 5 30 049 6 5 30 04e 7 5 30 053 8 5 30 008 9 5 30 00d a 5 30 012 b 5 30 017 c 5 30 01c d 5 30 021 e 5 30 026 f 5 30 02b 0 6 30 030 1 6 30 036 2 6 30 03c 3 6 30 042 4 6 30 048 5 6 30 04e 6 6 30 054 7 6 30 05a 8 6 30 000 9 6 30 006 a 6 30 00c b 6 30 012 c 6 30 018 d 6 30 01e e 6 30 024 f 6 30 02a 0 7 30 030 1 7 30 037 2 7 30 03e 3 7 30 045 4 7 30 04c 5 7 30 053 6 7 30 05a 7 7 30 061 8 7 30 1f8 9 7 30 1ff a 7 30 006 b 7 30 00d c 7 30 014 d 7 30 01b e 7 30 022 f 7 30 029 0 8 30 030 1 8 30 028 2 8 30 020 3 8 30 018 4 8 30 010 5 8 30 008 6 8 30 000 7 8 30 1f8 8 8 30 070 9 8 30 068 a 8 30 060 b 8 30 058 c 8 30 050 d 8 30 048 e 8 30 040 f 8 30 038 0 9 30 030 1 9 30 029 2 9 30 022 3 9 30 01b 4 9 30 014 5 9 30 00d 6 9 30 006 7 9 30 1ff 8 9 30 068 9 9 30 061 a 9 30 05a b 9 30 053 c 9 30 04c d 9 30 045 e 9 30 03e f 9 30 037 0 a 30 030 1 a 30 02a 2 a 30 024 3 a 30 01e 4 a 30 018 5 a 30 012 6 a 30 00c 7 a 30 006 8 a 30 060 9 a 30 05a a a 30 054 b a 30 04e c a 30 048 d a 30 042 e a 30 03c f a 30 036 0 b 30 030 1 b 30 02b 2 b 30 026 3 b 30 021 4 b 30 01c 5 b 30 017 6 b 30 012 7 b 30 00d 8 b 30 058 9 b 30 053 a b 30 04e b b 30 049 c b 30 044 d b 30 03f e b 30 03a f b 30 035 0 c 30 030 1 c 30 02c 2 c 30 028 3 c 30 024 4 c 30 020 5 c 30 01c 6 c 30 018 7 c 30 014 8 c 30 050 9 c 30 04c a c 30 048 b c 30 044 c c 30 040 d c 30 03c e c 30 038 f c 30 034 0 d 30 030 1 d 30 02d 2 d 30 02a 3 d 30 027 4 d 30 024 5 d 30 021 6 d 30 01e 7 d 30 01b 8 d 30 048 9 d 30 045 a d 30 042 b d 30 03f c d 30 03c d d 30 039 e d 30 036 f d 30 033 0 e 30 030 1 e 30 02e 2 e 30 02c 3 e 30 02a 4 e 30 028 5 e 30 026 6 e 30 024 7 e 30 022 8 e 30 040 9 e 30 03e a e 30 03c b e 30 03a c e 30 038 d e 30 036 e e 30 034 f e 30 032 0 f 30 030 1 f 30 02f 2 f 30 02e 3 f 30 02d 4 f 30 02c 5 f 30 02b 6 f 30 02a 7 f 30 029 8 f 30 038 9 f 30 037 a f 30 036 b f 30 035 c f 30 034 d f 30 033 e f 30 032 f f 30 031 0 0 31 031 1 0 31 031 2 0 31 031 3 0 31 031 4 0 31 031 5 0 31 031 6 0 31 031 7 0 31 031 8 0 31 031 9 0 31 031 a 0 31 031 b 0 31 031 c 0 31 031 d 0 31 031 e 0 31 031 f 0 31 031 0 1 31 031 1 1 31 032 2 1 31 033 3 1 31 034 4 1 31 035 5 1 31 036 6 1 31 037 7 1 31 038 8 1 31 029 9 1 31 02a a 1 31 02b b 1 31 02c c 1 31 02d d 1 31 02e e 1 31 02f f 1 31 030 0 2 31 031 1 2 31 033 2 2 31 035 3 2 31 037 4 2 31 039 5 2 31 03b 6 2 31 03d 7 2 31 03f 8 2 31 021 9 2 31 023 a 2 31 025 b 2 31 027 c 2 31 029 d 2 31 02b e 2 31 02d f 2 31 02f 0 3 31 031 1 3 31 034 2 3 31 037 3 3 31 03a 4 3 31 03d 5 3 31 040 6 3 31 043 7 3 31 046 8 3 31 019 9 3 31 01c a 3 31 01f b 3 31 022 c 3 31 025 d 3 31 028 e 3 31 02b f 3 31 02e 0 4 31 031 1 4 31 035 2 4 31 039 3 4 31 03d 4 4 31 041 5 4 31 045 6 4 31 049 7 4 31 04d 8 4 31 011 9 4 31 015 a 4 31 019 b 4 31 01d c 4 31 021 d 4 31 025 e 4 31 029 f 4 31 02d 0 5 31 031 1 5 31 036 2 5 31 03b 3 5 31 040 4 5 31 045 5 5 31 04a 6 5 31 04f 7 5 31 054 8 5 31 009 9 5 31 00e a 5 31 013 b 5 31 018 c 5 31 01d d 5 31 022 e 5 31 027 f 5 31 02c 0 6 31 031 1 6 31 037 2 6 31 03d 3 6 31 043 4 6 31 049 5 6 31 04f 6 6 31 055 7 6 31 05b 8 6 31 001 9 6 31 007 a 6 31 00d b 6 31 013 c 6 31 019 d 6 31 01f e 6 31 025 f 6 31 02b 0 7 31 031 1 7 31 038 2 7 31 03f 3 7 31 046 4 7 31 04d 5 7 31 054 6 7 31 05b 7 7 31 062 8 7 31 1f9 9 7 31 000 a 7 31 007 b 7 31 00e c 7 31 015 d 7 31 01c e 7 31 023 f 7 31 02a 0 8 31 031 1 8 31 029 2 8 31 021 3 8 31 019 4 8 31 011 5 8 31 009 6 8 31 001 7 8 31 1f9 8 8 31 071 9 8 31 069 a 8 31 061 b 8 31 059 c 8 31 051 d 8 31 049 e 8 31 041 f 8 31 039 0 9 31 031 1 9 31 02a 2 9 31 023 3 9 31 01c 4 9 31 015 5 9 31 00e 6 9 31 007 7 9 31 000 8 9 31 069 9 9 31 062 a 9 31 05b b 9 31 054 c 9 31 04d d 9 31 046 e 9 31 03f f 9 31 038 0 a 31 031 1 a 31 02b 2 a 31 025 3 a 31 01f 4 a 31 019 5 a 31 013 6 a 31 00d 7 a 31 007 8 a 31 061 9 a 31 05b a a 31 055 b a 31 04f c a 31 049 d a 31 043 e a 31 03d f a 31 037 0 b 31 031 1 b 31 02c 2 b 31 027 3 b 31 022 4 b 31 01d 5 b 31 018 6 b 31 013 7 b 31 00e 8 b 31 059 9 b 31 054 a b 31 04f b b 31 04a c b 31 045 d b 31 040 e b 31 03b f b 31 036 0 c 31 031 1 c 31 02d 2 c 31 029 3 c 31 025 4 c 31 021 5 c 31 01d 6 c 31 019 7 c 31 015 8 c 31 051 9 c 31 04d a c 31 049 b c 31 045 c c 31 041 d c 31 03d e c 31 039 f c 31 035 0 d 31 031 1 d 31 02e 2 d 31 02b 3 d 31 028 4 d 31 025 5 d 31 022 6 d 31 01f 7 d 31 01c 8 d 31 049 9 d 31 046 a d 31 043 b d 31 040 c d 31 03d d d 31 03a e d 31 037 f d 31 034 0 e 31 031 1 e 31 02f 2 e 31 02d 3 e 31 02b 4 e 31 029 5 e 31 027 6 e 31 025 7 e 31 023 8 e 31 041 9 e 31 03f a e 31 03d b e 31 03b c e 31 039 d e 31 037 e e 31 035 f e 31 033 0 f 31 031 1 f 31 030 2 f 31 02f 3 f 31 02e 4 f 31 02d 5 f 31 02c 6 f 31 02b 7 f 31 02a 8 f 31 039 9 f 31 038 a f 31 037 b f 31 036 c f 31 035 d f 31 034 e f 31 033 f f 31 032 0 0 32 032 1 0 32 032 2 0 32 032 3 0 32 032 4 0 32 032 5 0 32 032 6 0 32 032 7 0 32 032 8 0 32 032 9 0 32 032 a 0 32 032 b 0 32 032 c 0 32 032 d 0 32 032 e 0 32 032 f 0 32 032 0 1 32 032 1 1 32 033 2 1 32 034 3 1 32 035 4 1 32 036 5 1 32 037 6 1 32 038 7 1 32 039 8 1 32 02a 9 1 32 02b a 1 32 02c b 1 32 02d c 1 32 02e d 1 32 02f e 1 32 030 f 1 32 031 0 2 32 032 1 2 32 034 2 2 32 036 3 2 32 038 4 2 32 03a 5 2 32 03c 6 2 32 03e 7 2 32 040 8 2 32 022 9 2 32 024 a 2 32 026 b 2 32 028 c 2 32 02a d 2 32 02c e 2 32 02e f 2 32 030 0 3 32 032 1 3 32 035 2 3 32 038 3 3 32 03b 4 3 32 03e 5 3 32 041 6 3 32 044 7 3 32 047 8 3 32 01a 9 3 32 01d a 3 32 020 b 3 32 023 c 3 32 026 d 3 32 029 e 3 32 02c f 3 32 02f 0 4 32 032 1 4 32 036 2 4 32 03a 3 4 32 03e 4 4 32 042 5 4 32 046 6 4 32 04a 7 4 32 04e 8 4 32 012 9 4 32 016 a 4 32 01a b 4 32 01e c 4 32 022 d 4 32 026 e 4 32 02a f 4 32 02e 0 5 32 032 1 5 32 037 2 5 32 03c 3 5 32 041 4 5 32 046 5 5 32 04b 6 5 32 050 7 5 32 055 8 5 32 00a 9 5 32 00f a 5 32 014 b 5 32 019 c 5 32 01e d 5 32 023 e 5 32 028 f 5 32 02d 0 6 32 032 1 6 32 038 2 6 32 03e 3 6 32 044 4 6 32 04a 5 6 32 050 6 6 32 056 7 6 32 05c 8 6 32 002 9 6 32 008 a 6 32 00e b 6 32 014 c 6 32 01a d 6 32 020 e 6 32 026 f 6 32 02c 0 7 32 032 1 7 32 039 2 7 32 040 3 7 32 047 4 7 32 04e 5 7 32 055 6 7 32 05c 7 7 32 063 8 7 32 1fa 9 7 32 001 a 7 32 008 b 7 32 00f c 7 32 016 d 7 32 01d e 7 32 024 f 7 32 02b 0 8 32 032 1 8 32 02a 2 8 32 022 3 8 32 01a 4 8 32 012 5 8 32 00a 6 8 32 002 7 8 32 1fa 8 8 32 072 9 8 32 06a a 8 32 062 b 8 32 05a c 8 32 052 d 8 32 04a e 8 32 042 f 8 32 03a 0 9 32 032 1 9 32 02b 2 9 32 024 3 9 32 01d 4 9 32 016 5 9 32 00f 6 9 32 008 7 9 32 001 8 9 32 06a 9 9 32 063 a 9 32 05c b 9 32 055 c 9 32 04e d 9 32 047 e 9 32 040 f 9 32 039 0 a 32 032 1 a 32 02c 2 a 32 026 3 a 32 020 4 a 32 01a 5 a 32 014 6 a 32 00e 7 a 32 008 8 a 32 062 9 a 32 05c a a 32 056 b a 32 050 c a 32 04a d a 32 044 e a 32 03e f a 32 038 0 b 32 032 1 b 32 02d 2 b 32 028 3 b 32 023 4 b 32 01e 5 b 32 019 6 b 32 014 7 b 32 00f 8 b 32 05a 9 b 32 055 a b 32 050 b b 32 04b c b 32 046 d b 32 041 e b 32 03c f b 32 037 0 c 32 032 1 c 32 02e 2 c 32 02a 3 c 32 026 4 c 32 022 5 c 32 01e 6 c 32 01a 7 c 32 016 8 c 32 052 9 c 32 04e a c 32 04a b c 32 046 c c 32 042 d c 32 03e e c 32 03a f c 32 036 0 d 32 032 1 d 32 02f 2 d 32 02c 3 d 32 029 4 d 32 026 5 d 32 023 6 d 32 020 7 d 32 01d 8 d 32 04a 9 d 32 047 a d 32 044 b d 32 041 c d 32 03e d d 32 03b e d 32 038 f d 32 035 0 e 32 032 1 e 32 030 2 e 32 02e 3 e 32 02c 4 e 32 02a 5 e 32 028 6 e 32 026 7 e 32 024 8 e 32 042 9 e 32 040 a e 32 03e b e 32 03c c e 32 03a d e 32 038 e e 32 036 f e 32 034 0 f 32 032 1 f 32 031 2 f 32 030 3 f 32 02f 4 f 32 02e 5 f 32 02d 6 f 32 02c 7 f 32 02b 8 f 32 03a 9 f 32 039 a f 32 038 b f 32 037 c f 32 036 d f 32 035 e f 32 034 f f 32 033 0 0 33 033 1 0 33 033 2 0 33 033 3 0 33 033 4 0 33 033 5 0 33 033 6 0 33 033 7 0 33 033 8 0 33 033 9 0 33 033 a 0 33 033 b 0 33 033 c 0 33 033 d 0 33 033 e 0 33 033 f 0 33 033 0 1 33 033 1 1 33 034 2 1 33 035 3 1 33 036 4 1 33 037 5 1 33 038 6 1 33 039 7 1 33 03a 8 1 33 02b 9 1 33 02c a 1 33 02d b 1 33 02e c 1 33 02f d 1 33 030 e 1 33 031 f 1 33 032 0 2 33 033 1 2 33 035 2 2 33 037 3 2 33 039 4 2 33 03b 5 2 33 03d 6 2 33 03f 7 2 33 041 8 2 33 023 9 2 33 025 a 2 33 027 b 2 33 029 c 2 33 02b d 2 33 02d e 2 33 02f f 2 33 031 0 3 33 033 1 3 33 036 2 3 33 039 3 3 33 03c 4 3 33 03f 5 3 33 042 6 3 33 045 7 3 33 048 8 3 33 01b 9 3 33 01e a 3 33 021 b 3 33 024 c 3 33 027 d 3 33 02a e 3 33 02d f 3 33 030 0 4 33 033 1 4 33 037 2 4 33 03b 3 4 33 03f 4 4 33 043 5 4 33 047 6 4 33 04b 7 4 33 04f 8 4 33 013 9 4 33 017 a 4 33 01b b 4 33 01f c 4 33 023 d 4 33 027 e 4 33 02b f 4 33 02f 0 5 33 033 1 5 33 038 2 5 33 03d 3 5 33 042 4 5 33 047 5 5 33 04c 6 5 33 051 7 5 33 056 8 5 33 00b 9 5 33 010 a 5 33 015 b 5 33 01a c 5 33 01f d 5 33 024 e 5 33 029 f 5 33 02e 0 6 33 033 1 6 33 039 2 6 33 03f 3 6 33 045 4 6 33 04b 5 6 33 051 6 6 33 057 7 6 33 05d 8 6 33 003 9 6 33 009 a 6 33 00f b 6 33 015 c 6 33 01b d 6 33 021 e 6 33 027 f 6 33 02d 0 7 33 033 1 7 33 03a 2 7 33 041 3 7 33 048 4 7 33 04f 5 7 33 056 6 7 33 05d 7 7 33 064 8 7 33 1fb 9 7 33 002 a 7 33 009 b 7 33 010 c 7 33 017 d 7 33 01e e 7 33 025 f 7 33 02c 0 8 33 033 1 8 33 02b 2 8 33 023 3 8 33 01b 4 8 33 013 5 8 33 00b 6 8 33 003 7 8 33 1fb 8 8 33 073 9 8 33 06b a 8 33 063 b 8 33 05b c 8 33 053 d 8 33 04b e 8 33 043 f 8 33 03b 0 9 33 033 1 9 33 02c 2 9 33 025 3 9 33 01e 4 9 33 017 5 9 33 010 6 9 33 009 7 9 33 002 8 9 33 06b 9 9 33 064 a 9 33 05d b 9 33 056 c 9 33 04f d 9 33 048 e 9 33 041 f 9 33 03a 0 a 33 033 1 a 33 02d 2 a 33 027 3 a 33 021 4 a 33 01b 5 a 33 015 6 a 33 00f 7 a 33 009 8 a 33 063 9 a 33 05d a a 33 057 b a 33 051 c a 33 04b d a 33 045 e a 33 03f f a 33 039 0 b 33 033 1 b 33 02e 2 b 33 029 3 b 33 024 4 b 33 01f 5 b 33 01a 6 b 33 015 7 b 33 010 8 b 33 05b 9 b 33 056 a b 33 051 b b 33 04c c b 33 047 d b 33 042 e b 33 03d f b 33 038 0 c 33 033 1 c 33 02f 2 c 33 02b 3 c 33 027 4 c 33 023 5 c 33 01f 6 c 33 01b 7 c 33 017 8 c 33 053 9 c 33 04f a c 33 04b b c 33 047 c c 33 043 d c 33 03f e c 33 03b f c 33 037 0 d 33 033 1 d 33 030 2 d 33 02d 3 d 33 02a 4 d 33 027 5 d 33 024 6 d 33 021 7 d 33 01e 8 d 33 04b 9 d 33 048 a d 33 045 b d 33 042 c d 33 03f d d 33 03c e d 33 039 f d 33 036 0 e 33 033 1 e 33 031 2 e 33 02f 3 e 33 02d 4 e 33 02b 5 e 33 029 6 e 33 027 7 e 33 025 8 e 33 043 9 e 33 041 a e 33 03f b e 33 03d c e 33 03b d e 33 039 e e 33 037 f e 33 035 0 f 33 033 1 f 33 032 2 f 33 031 3 f 33 030 4 f 33 02f 5 f 33 02e 6 f 33 02d 7 f 33 02c 8 f 33 03b 9 f 33 03a a f 33 039 b f 33 038 c f 33 037 d f 33 036 e f 33 035 f f 33 034 0 0 34 034 1 0 34 034 2 0 34 034 3 0 34 034 4 0 34 034 5 0 34 034 6 0 34 034 7 0 34 034 8 0 34 034 9 0 34 034 a 0 34 034 b 0 34 034 c 0 34 034 d 0 34 034 e 0 34 034 f 0 34 034 0 1 34 034 1 1 34 035 2 1 34 036 3 1 34 037 4 1 34 038 5 1 34 039 6 1 34 03a 7 1 34 03b 8 1 34 02c 9 1 34 02d a 1 34 02e b 1 34 02f c 1 34 030 d 1 34 031 e 1 34 032 f 1 34 033 0 2 34 034 1 2 34 036 2 2 34 038 3 2 34 03a 4 2 34 03c 5 2 34 03e 6 2 34 040 7 2 34 042 8 2 34 024 9 2 34 026 a 2 34 028 b 2 34 02a c 2 34 02c d 2 34 02e e 2 34 030 f 2 34 032 0 3 34 034 1 3 34 037 2 3 34 03a 3 3 34 03d 4 3 34 040 5 3 34 043 6 3 34 046 7 3 34 049 8 3 34 01c 9 3 34 01f a 3 34 022 b 3 34 025 c 3 34 028 d 3 34 02b e 3 34 02e f 3 34 031 0 4 34 034 1 4 34 038 2 4 34 03c 3 4 34 040 4 4 34 044 5 4 34 048 6 4 34 04c 7 4 34 050 8 4 34 014 9 4 34 018 a 4 34 01c b 4 34 020 c 4 34 024 d 4 34 028 e 4 34 02c f 4 34 030 0 5 34 034 1 5 34 039 2 5 34 03e 3 5 34 043 4 5 34 048 5 5 34 04d 6 5 34 052 7 5 34 057 8 5 34 00c 9 5 34 011 a 5 34 016 b 5 34 01b c 5 34 020 d 5 34 025 e 5 34 02a f 5 34 02f 0 6 34 034 1 6 34 03a 2 6 34 040 3 6 34 046 4 6 34 04c 5 6 34 052 6 6 34 058 7 6 34 05e 8 6 34 004 9 6 34 00a a 6 34 010 b 6 34 016 c 6 34 01c d 6 34 022 e 6 34 028 f 6 34 02e 0 7 34 034 1 7 34 03b 2 7 34 042 3 7 34 049 4 7 34 050 5 7 34 057 6 7 34 05e 7 7 34 065 8 7 34 1fc 9 7 34 003 a 7 34 00a b 7 34 011 c 7 34 018 d 7 34 01f e 7 34 026 f 7 34 02d 0 8 34 034 1 8 34 02c 2 8 34 024 3 8 34 01c 4 8 34 014 5 8 34 00c 6 8 34 004 7 8 34 1fc 8 8 34 074 9 8 34 06c a 8 34 064 b 8 34 05c c 8 34 054 d 8 34 04c e 8 34 044 f 8 34 03c 0 9 34 034 1 9 34 02d 2 9 34 026 3 9 34 01f 4 9 34 018 5 9 34 011 6 9 34 00a 7 9 34 003 8 9 34 06c 9 9 34 065 a 9 34 05e b 9 34 057 c 9 34 050 d 9 34 049 e 9 34 042 f 9 34 03b 0 a 34 034 1 a 34 02e 2 a 34 028 3 a 34 022 4 a 34 01c 5 a 34 016 6 a 34 010 7 a 34 00a 8 a 34 064 9 a 34 05e a a 34 058 b a 34 052 c a 34 04c d a 34 046 e a 34 040 f a 34 03a 0 b 34 034 1 b 34 02f 2 b 34 02a 3 b 34 025 4 b 34 020 5 b 34 01b 6 b 34 016 7 b 34 011 8 b 34 05c 9 b 34 057 a b 34 052 b b 34 04d c b 34 048 d b 34 043 e b 34 03e f b 34 039 0 c 34 034 1 c 34 030 2 c 34 02c 3 c 34 028 4 c 34 024 5 c 34 020 6 c 34 01c 7 c 34 018 8 c 34 054 9 c 34 050 a c 34 04c b c 34 048 c c 34 044 d c 34 040 e c 34 03c f c 34 038 0 d 34 034 1 d 34 031 2 d 34 02e 3 d 34 02b 4 d 34 028 5 d 34 025 6 d 34 022 7 d 34 01f 8 d 34 04c 9 d 34 049 a d 34 046 b d 34 043 c d 34 040 d d 34 03d e d 34 03a f d 34 037 0 e 34 034 1 e 34 032 2 e 34 030 3 e 34 02e 4 e 34 02c 5 e 34 02a 6 e 34 028 7 e 34 026 8 e 34 044 9 e 34 042 a e 34 040 b e 34 03e c e 34 03c d e 34 03a e e 34 038 f e 34 036 0 f 34 034 1 f 34 033 2 f 34 032 3 f 34 031 4 f 34 030 5 f 34 02f 6 f 34 02e 7 f 34 02d 8 f 34 03c 9 f 34 03b a f 34 03a b f 34 039 c f 34 038 d f 34 037 e f 34 036 f f 34 035 0 0 35 035 1 0 35 035 2 0 35 035 3 0 35 035 4 0 35 035 5 0 35 035 6 0 35 035 7 0 35 035 8 0 35 035 9 0 35 035 a 0 35 035 b 0 35 035 c 0 35 035 d 0 35 035 e 0 35 035 f 0 35 035 0 1 35 035 1 1 35 036 2 1 35 037 3 1 35 038 4 1 35 039 5 1 35 03a 6 1 35 03b 7 1 35 03c 8 1 35 02d 9 1 35 02e a 1 35 02f b 1 35 030 c 1 35 031 d 1 35 032 e 1 35 033 f 1 35 034 0 2 35 035 1 2 35 037 2 2 35 039 3 2 35 03b 4 2 35 03d 5 2 35 03f 6 2 35 041 7 2 35 043 8 2 35 025 9 2 35 027 a 2 35 029 b 2 35 02b c 2 35 02d d 2 35 02f e 2 35 031 f 2 35 033 0 3 35 035 1 3 35 038 2 3 35 03b 3 3 35 03e 4 3 35 041 5 3 35 044 6 3 35 047 7 3 35 04a 8 3 35 01d 9 3 35 020 a 3 35 023 b 3 35 026 c 3 35 029 d 3 35 02c e 3 35 02f f 3 35 032 0 4 35 035 1 4 35 039 2 4 35 03d 3 4 35 041 4 4 35 045 5 4 35 049 6 4 35 04d 7 4 35 051 8 4 35 015 9 4 35 019 a 4 35 01d b 4 35 021 c 4 35 025 d 4 35 029 e 4 35 02d f 4 35 031 0 5 35 035 1 5 35 03a 2 5 35 03f 3 5 35 044 4 5 35 049 5 5 35 04e 6 5 35 053 7 5 35 058 8 5 35 00d 9 5 35 012 a 5 35 017 b 5 35 01c c 5 35 021 d 5 35 026 e 5 35 02b f 5 35 030 0 6 35 035 1 6 35 03b 2 6 35 041 3 6 35 047 4 6 35 04d 5 6 35 053 6 6 35 059 7 6 35 05f 8 6 35 005 9 6 35 00b a 6 35 011 b 6 35 017 c 6 35 01d d 6 35 023 e 6 35 029 f 6 35 02f 0 7 35 035 1 7 35 03c 2 7 35 043 3 7 35 04a 4 7 35 051 5 7 35 058 6 7 35 05f 7 7 35 066 8 7 35 1fd 9 7 35 004 a 7 35 00b b 7 35 012 c 7 35 019 d 7 35 020 e 7 35 027 f 7 35 02e 0 8 35 035 1 8 35 02d 2 8 35 025 3 8 35 01d 4 8 35 015 5 8 35 00d 6 8 35 005 7 8 35 1fd 8 8 35 075 9 8 35 06d a 8 35 065 b 8 35 05d c 8 35 055 d 8 35 04d e 8 35 045 f 8 35 03d 0 9 35 035 1 9 35 02e 2 9 35 027 3 9 35 020 4 9 35 019 5 9 35 012 6 9 35 00b 7 9 35 004 8 9 35 06d 9 9 35 066 a 9 35 05f b 9 35 058 c 9 35 051 d 9 35 04a e 9 35 043 f 9 35 03c 0 a 35 035 1 a 35 02f 2 a 35 029 3 a 35 023 4 a 35 01d 5 a 35 017 6 a 35 011 7 a 35 00b 8 a 35 065 9 a 35 05f a a 35 059 b a 35 053 c a 35 04d d a 35 047 e a 35 041 f a 35 03b 0 b 35 035 1 b 35 030 2 b 35 02b 3 b 35 026 4 b 35 021 5 b 35 01c 6 b 35 017 7 b 35 012 8 b 35 05d 9 b 35 058 a b 35 053 b b 35 04e c b 35 049 d b 35 044 e b 35 03f f b 35 03a 0 c 35 035 1 c 35 031 2 c 35 02d 3 c 35 029 4 c 35 025 5 c 35 021 6 c 35 01d 7 c 35 019 8 c 35 055 9 c 35 051 a c 35 04d b c 35 049 c c 35 045 d c 35 041 e c 35 03d f c 35 039 0 d 35 035 1 d 35 032 2 d 35 02f 3 d 35 02c 4 d 35 029 5 d 35 026 6 d 35 023 7 d 35 020 8 d 35 04d 9 d 35 04a a d 35 047 b d 35 044 c d 35 041 d d 35 03e e d 35 03b f d 35 038 0 e 35 035 1 e 35 033 2 e 35 031 3 e 35 02f 4 e 35 02d 5 e 35 02b 6 e 35 029 7 e 35 027 8 e 35 045 9 e 35 043 a e 35 041 b e 35 03f c e 35 03d d e 35 03b e e 35 039 f e 35 037 0 f 35 035 1 f 35 034 2 f 35 033 3 f 35 032 4 f 35 031 5 f 35 030 6 f 35 02f 7 f 35 02e 8 f 35 03d 9 f 35 03c a f 35 03b b f 35 03a c f 35 039 d f 35 038 e f 35 037 f f 35 036 0 0 36 036 1 0 36 036 2 0 36 036 3 0 36 036 4 0 36 036 5 0 36 036 6 0 36 036 7 0 36 036 8 0 36 036 9 0 36 036 a 0 36 036 b 0 36 036 c 0 36 036 d 0 36 036 e 0 36 036 f 0 36 036 0 1 36 036 1 1 36 037 2 1 36 038 3 1 36 039 4 1 36 03a 5 1 36 03b 6 1 36 03c 7 1 36 03d 8 1 36 02e 9 1 36 02f a 1 36 030 b 1 36 031 c 1 36 032 d 1 36 033 e 1 36 034 f 1 36 035 0 2 36 036 1 2 36 038 2 2 36 03a 3 2 36 03c 4 2 36 03e 5 2 36 040 6 2 36 042 7 2 36 044 8 2 36 026 9 2 36 028 a 2 36 02a b 2 36 02c c 2 36 02e d 2 36 030 e 2 36 032 f 2 36 034 0 3 36 036 1 3 36 039 2 3 36 03c 3 3 36 03f 4 3 36 042 5 3 36 045 6 3 36 048 7 3 36 04b 8 3 36 01e 9 3 36 021 a 3 36 024 b 3 36 027 c 3 36 02a d 3 36 02d e 3 36 030 f 3 36 033 0 4 36 036 1 4 36 03a 2 4 36 03e 3 4 36 042 4 4 36 046 5 4 36 04a 6 4 36 04e 7 4 36 052 8 4 36 016 9 4 36 01a a 4 36 01e b 4 36 022 c 4 36 026 d 4 36 02a e 4 36 02e f 4 36 032 0 5 36 036 1 5 36 03b 2 5 36 040 3 5 36 045 4 5 36 04a 5 5 36 04f 6 5 36 054 7 5 36 059 8 5 36 00e 9 5 36 013 a 5 36 018 b 5 36 01d c 5 36 022 d 5 36 027 e 5 36 02c f 5 36 031 0 6 36 036 1 6 36 03c 2 6 36 042 3 6 36 048 4 6 36 04e 5 6 36 054 6 6 36 05a 7 6 36 060 8 6 36 006 9 6 36 00c a 6 36 012 b 6 36 018 c 6 36 01e d 6 36 024 e 6 36 02a f 6 36 030 0 7 36 036 1 7 36 03d 2 7 36 044 3 7 36 04b 4 7 36 052 5 7 36 059 6 7 36 060 7 7 36 067 8 7 36 1fe 9 7 36 005 a 7 36 00c b 7 36 013 c 7 36 01a d 7 36 021 e 7 36 028 f 7 36 02f 0 8 36 036 1 8 36 02e 2 8 36 026 3 8 36 01e 4 8 36 016 5 8 36 00e 6 8 36 006 7 8 36 1fe 8 8 36 076 9 8 36 06e a 8 36 066 b 8 36 05e c 8 36 056 d 8 36 04e e 8 36 046 f 8 36 03e 0 9 36 036 1 9 36 02f 2 9 36 028 3 9 36 021 4 9 36 01a 5 9 36 013 6 9 36 00c 7 9 36 005 8 9 36 06e 9 9 36 067 a 9 36 060 b 9 36 059 c 9 36 052 d 9 36 04b e 9 36 044 f 9 36 03d 0 a 36 036 1 a 36 030 2 a 36 02a 3 a 36 024 4 a 36 01e 5 a 36 018 6 a 36 012 7 a 36 00c 8 a 36 066 9 a 36 060 a a 36 05a b a 36 054 c a 36 04e d a 36 048 e a 36 042 f a 36 03c 0 b 36 036 1 b 36 031 2 b 36 02c 3 b 36 027 4 b 36 022 5 b 36 01d 6 b 36 018 7 b 36 013 8 b 36 05e 9 b 36 059 a b 36 054 b b 36 04f c b 36 04a d b 36 045 e b 36 040 f b 36 03b 0 c 36 036 1 c 36 032 2 c 36 02e 3 c 36 02a 4 c 36 026 5 c 36 022 6 c 36 01e 7 c 36 01a 8 c 36 056 9 c 36 052 a c 36 04e b c 36 04a c c 36 046 d c 36 042 e c 36 03e f c 36 03a 0 d 36 036 1 d 36 033 2 d 36 030 3 d 36 02d 4 d 36 02a 5 d 36 027 6 d 36 024 7 d 36 021 8 d 36 04e 9 d 36 04b a d 36 048 b d 36 045 c d 36 042 d d 36 03f e d 36 03c f d 36 039 0 e 36 036 1 e 36 034 2 e 36 032 3 e 36 030 4 e 36 02e 5 e 36 02c 6 e 36 02a 7 e 36 028 8 e 36 046 9 e 36 044 a e 36 042 b e 36 040 c e 36 03e d e 36 03c e e 36 03a f e 36 038 0 f 36 036 1 f 36 035 2 f 36 034 3 f 36 033 4 f 36 032 5 f 36 031 6 f 36 030 7 f 36 02f 8 f 36 03e 9 f 36 03d a f 36 03c b f 36 03b c f 36 03a d f 36 039 e f 36 038 f f 36 037 0 0 37 037 1 0 37 037 2 0 37 037 3 0 37 037 4 0 37 037 5 0 37 037 6 0 37 037 7 0 37 037 8 0 37 037 9 0 37 037 a 0 37 037 b 0 37 037 c 0 37 037 d 0 37 037 e 0 37 037 f 0 37 037 0 1 37 037 1 1 37 038 2 1 37 039 3 1 37 03a 4 1 37 03b 5 1 37 03c 6 1 37 03d 7 1 37 03e 8 1 37 02f 9 1 37 030 a 1 37 031 b 1 37 032 c 1 37 033 d 1 37 034 e 1 37 035 f 1 37 036 0 2 37 037 1 2 37 039 2 2 37 03b 3 2 37 03d 4 2 37 03f 5 2 37 041 6 2 37 043 7 2 37 045 8 2 37 027 9 2 37 029 a 2 37 02b b 2 37 02d c 2 37 02f d 2 37 031 e 2 37 033 f 2 37 035 0 3 37 037 1 3 37 03a 2 3 37 03d 3 3 37 040 4 3 37 043 5 3 37 046 6 3 37 049 7 3 37 04c 8 3 37 01f 9 3 37 022 a 3 37 025 b 3 37 028 c 3 37 02b d 3 37 02e e 3 37 031 f 3 37 034 0 4 37 037 1 4 37 03b 2 4 37 03f 3 4 37 043 4 4 37 047 5 4 37 04b 6 4 37 04f 7 4 37 053 8 4 37 017 9 4 37 01b a 4 37 01f b 4 37 023 c 4 37 027 d 4 37 02b e 4 37 02f f 4 37 033 0 5 37 037 1 5 37 03c 2 5 37 041 3 5 37 046 4 5 37 04b 5 5 37 050 6 5 37 055 7 5 37 05a 8 5 37 00f 9 5 37 014 a 5 37 019 b 5 37 01e c 5 37 023 d 5 37 028 e 5 37 02d f 5 37 032 0 6 37 037 1 6 37 03d 2 6 37 043 3 6 37 049 4 6 37 04f 5 6 37 055 6 6 37 05b 7 6 37 061 8 6 37 007 9 6 37 00d a 6 37 013 b 6 37 019 c 6 37 01f d 6 37 025 e 6 37 02b f 6 37 031 0 7 37 037 1 7 37 03e 2 7 37 045 3 7 37 04c 4 7 37 053 5 7 37 05a 6 7 37 061 7 7 37 068 8 7 37 1ff 9 7 37 006 a 7 37 00d b 7 37 014 c 7 37 01b d 7 37 022 e 7 37 029 f 7 37 030 0 8 37 037 1 8 37 02f 2 8 37 027 3 8 37 01f 4 8 37 017 5 8 37 00f 6 8 37 007 7 8 37 1ff 8 8 37 077 9 8 37 06f a 8 37 067 b 8 37 05f c 8 37 057 d 8 37 04f e 8 37 047 f 8 37 03f 0 9 37 037 1 9 37 030 2 9 37 029 3 9 37 022 4 9 37 01b 5 9 37 014 6 9 37 00d 7 9 37 006 8 9 37 06f 9 9 37 068 a 9 37 061 b 9 37 05a c 9 37 053 d 9 37 04c e 9 37 045 f 9 37 03e 0 a 37 037 1 a 37 031 2 a 37 02b 3 a 37 025 4 a 37 01f 5 a 37 019 6 a 37 013 7 a 37 00d 8 a 37 067 9 a 37 061 a a 37 05b b a 37 055 c a 37 04f d a 37 049 e a 37 043 f a 37 03d 0 b 37 037 1 b 37 032 2 b 37 02d 3 b 37 028 4 b 37 023 5 b 37 01e 6 b 37 019 7 b 37 014 8 b 37 05f 9 b 37 05a a b 37 055 b b 37 050 c b 37 04b d b 37 046 e b 37 041 f b 37 03c 0 c 37 037 1 c 37 033 2 c 37 02f 3 c 37 02b 4 c 37 027 5 c 37 023 6 c 37 01f 7 c 37 01b 8 c 37 057 9 c 37 053 a c 37 04f b c 37 04b c c 37 047 d c 37 043 e c 37 03f f c 37 03b 0 d 37 037 1 d 37 034 2 d 37 031 3 d 37 02e 4 d 37 02b 5 d 37 028 6 d 37 025 7 d 37 022 8 d 37 04f 9 d 37 04c a d 37 049 b d 37 046 c d 37 043 d d 37 040 e d 37 03d f d 37 03a 0 e 37 037 1 e 37 035 2 e 37 033 3 e 37 031 4 e 37 02f 5 e 37 02d 6 e 37 02b 7 e 37 029 8 e 37 047 9 e 37 045 a e 37 043 b e 37 041 c e 37 03f d e 37 03d e e 37 03b f e 37 039 0 f 37 037 1 f 37 036 2 f 37 035 3 f 37 034 4 f 37 033 5 f 37 032 6 f 37 031 7 f 37 030 8 f 37 03f 9 f 37 03e a f 37 03d b f 37 03c c f 37 03b d f 37 03a e f 37 039 f f 37 038 0 0 38 038 1 0 38 038 2 0 38 038 3 0 38 038 4 0 38 038 5 0 38 038 6 0 38 038 7 0 38 038 8 0 38 038 9 0 38 038 a 0 38 038 b 0 38 038 c 0 38 038 d 0 38 038 e 0 38 038 f 0 38 038 0 1 38 038 1 1 38 039 2 1 38 03a 3 1 38 03b 4 1 38 03c 5 1 38 03d 6 1 38 03e 7 1 38 03f 8 1 38 030 9 1 38 031 a 1 38 032 b 1 38 033 c 1 38 034 d 1 38 035 e 1 38 036 f 1 38 037 0 2 38 038 1 2 38 03a 2 2 38 03c 3 2 38 03e 4 2 38 040 5 2 38 042 6 2 38 044 7 2 38 046 8 2 38 028 9 2 38 02a a 2 38 02c b 2 38 02e c 2 38 030 d 2 38 032 e 2 38 034 f 2 38 036 0 3 38 038 1 3 38 03b 2 3 38 03e 3 3 38 041 4 3 38 044 5 3 38 047 6 3 38 04a 7 3 38 04d 8 3 38 020 9 3 38 023 a 3 38 026 b 3 38 029 c 3 38 02c d 3 38 02f e 3 38 032 f 3 38 035 0 4 38 038 1 4 38 03c 2 4 38 040 3 4 38 044 4 4 38 048 5 4 38 04c 6 4 38 050 7 4 38 054 8 4 38 018 9 4 38 01c a 4 38 020 b 4 38 024 c 4 38 028 d 4 38 02c e 4 38 030 f 4 38 034 0 5 38 038 1 5 38 03d 2 5 38 042 3 5 38 047 4 5 38 04c 5 5 38 051 6 5 38 056 7 5 38 05b 8 5 38 010 9 5 38 015 a 5 38 01a b 5 38 01f c 5 38 024 d 5 38 029 e 5 38 02e f 5 38 033 0 6 38 038 1 6 38 03e 2 6 38 044 3 6 38 04a 4 6 38 050 5 6 38 056 6 6 38 05c 7 6 38 062 8 6 38 008 9 6 38 00e a 6 38 014 b 6 38 01a c 6 38 020 d 6 38 026 e 6 38 02c f 6 38 032 0 7 38 038 1 7 38 03f 2 7 38 046 3 7 38 04d 4 7 38 054 5 7 38 05b 6 7 38 062 7 7 38 069 8 7 38 000 9 7 38 007 a 7 38 00e b 7 38 015 c 7 38 01c d 7 38 023 e 7 38 02a f 7 38 031 0 8 38 038 1 8 38 030 2 8 38 028 3 8 38 020 4 8 38 018 5 8 38 010 6 8 38 008 7 8 38 000 8 8 38 078 9 8 38 070 a 8 38 068 b 8 38 060 c 8 38 058 d 8 38 050 e 8 38 048 f 8 38 040 0 9 38 038 1 9 38 031 2 9 38 02a 3 9 38 023 4 9 38 01c 5 9 38 015 6 9 38 00e 7 9 38 007 8 9 38 070 9 9 38 069 a 9 38 062 b 9 38 05b c 9 38 054 d 9 38 04d e 9 38 046 f 9 38 03f 0 a 38 038 1 a 38 032 2 a 38 02c 3 a 38 026 4 a 38 020 5 a 38 01a 6 a 38 014 7 a 38 00e 8 a 38 068 9 a 38 062 a a 38 05c b a 38 056 c a 38 050 d a 38 04a e a 38 044 f a 38 03e 0 b 38 038 1 b 38 033 2 b 38 02e 3 b 38 029 4 b 38 024 5 b 38 01f 6 b 38 01a 7 b 38 015 8 b 38 060 9 b 38 05b a b 38 056 b b 38 051 c b 38 04c d b 38 047 e b 38 042 f b 38 03d 0 c 38 038 1 c 38 034 2 c 38 030 3 c 38 02c 4 c 38 028 5 c 38 024 6 c 38 020 7 c 38 01c 8 c 38 058 9 c 38 054 a c 38 050 b c 38 04c c c 38 048 d c 38 044 e c 38 040 f c 38 03c 0 d 38 038 1 d 38 035 2 d 38 032 3 d 38 02f 4 d 38 02c 5 d 38 029 6 d 38 026 7 d 38 023 8 d 38 050 9 d 38 04d a d 38 04a b d 38 047 c d 38 044 d d 38 041 e d 38 03e f d 38 03b 0 e 38 038 1 e 38 036 2 e 38 034 3 e 38 032 4 e 38 030 5 e 38 02e 6 e 38 02c 7 e 38 02a 8 e 38 048 9 e 38 046 a e 38 044 b e 38 042 c e 38 040 d e 38 03e e e 38 03c f e 38 03a 0 f 38 038 1 f 38 037 2 f 38 036 3 f 38 035 4 f 38 034 5 f 38 033 6 f 38 032 7 f 38 031 8 f 38 040 9 f 38 03f a f 38 03e b f 38 03d c f 38 03c d f 38 03b e f 38 03a f f 38 039 0 0 39 039 1 0 39 039 2 0 39 039 3 0 39 039 4 0 39 039 5 0 39 039 6 0 39 039 7 0 39 039 8 0 39 039 9 0 39 039 a 0 39 039 b 0 39 039 c 0 39 039 d 0 39 039 e 0 39 039 f 0 39 039 0 1 39 039 1 1 39 03a 2 1 39 03b 3 1 39 03c 4 1 39 03d 5 1 39 03e 6 1 39 03f 7 1 39 040 8 1 39 031 9 1 39 032 a 1 39 033 b 1 39 034 c 1 39 035 d 1 39 036 e 1 39 037 f 1 39 038 0 2 39 039 1 2 39 03b 2 2 39 03d 3 2 39 03f 4 2 39 041 5 2 39 043 6 2 39 045 7 2 39 047 8 2 39 029 9 2 39 02b a 2 39 02d b 2 39 02f c 2 39 031 d 2 39 033 e 2 39 035 f 2 39 037 0 3 39 039 1 3 39 03c 2 3 39 03f 3 3 39 042 4 3 39 045 5 3 39 048 6 3 39 04b 7 3 39 04e 8 3 39 021 9 3 39 024 a 3 39 027 b 3 39 02a c 3 39 02d d 3 39 030 e 3 39 033 f 3 39 036 0 4 39 039 1 4 39 03d 2 4 39 041 3 4 39 045 4 4 39 049 5 4 39 04d 6 4 39 051 7 4 39 055 8 4 39 019 9 4 39 01d a 4 39 021 b 4 39 025 c 4 39 029 d 4 39 02d e 4 39 031 f 4 39 035 0 5 39 039 1 5 39 03e 2 5 39 043 3 5 39 048 4 5 39 04d 5 5 39 052 6 5 39 057 7 5 39 05c 8 5 39 011 9 5 39 016 a 5 39 01b b 5 39 020 c 5 39 025 d 5 39 02a e 5 39 02f f 5 39 034 0 6 39 039 1 6 39 03f 2 6 39 045 3 6 39 04b 4 6 39 051 5 6 39 057 6 6 39 05d 7 6 39 063 8 6 39 009 9 6 39 00f a 6 39 015 b 6 39 01b c 6 39 021 d 6 39 027 e 6 39 02d f 6 39 033 0 7 39 039 1 7 39 040 2 7 39 047 3 7 39 04e 4 7 39 055 5 7 39 05c 6 7 39 063 7 7 39 06a 8 7 39 001 9 7 39 008 a 7 39 00f b 7 39 016 c 7 39 01d d 7 39 024 e 7 39 02b f 7 39 032 0 8 39 039 1 8 39 031 2 8 39 029 3 8 39 021 4 8 39 019 5 8 39 011 6 8 39 009 7 8 39 001 8 8 39 079 9 8 39 071 a 8 39 069 b 8 39 061 c 8 39 059 d 8 39 051 e 8 39 049 f 8 39 041 0 9 39 039 1 9 39 032 2 9 39 02b 3 9 39 024 4 9 39 01d 5 9 39 016 6 9 39 00f 7 9 39 008 8 9 39 071 9 9 39 06a a 9 39 063 b 9 39 05c c 9 39 055 d 9 39 04e e 9 39 047 f 9 39 040 0 a 39 039 1 a 39 033 2 a 39 02d 3 a 39 027 4 a 39 021 5 a 39 01b 6 a 39 015 7 a 39 00f 8 a 39 069 9 a 39 063 a a 39 05d b a 39 057 c a 39 051 d a 39 04b e a 39 045 f a 39 03f 0 b 39 039 1 b 39 034 2 b 39 02f 3 b 39 02a 4 b 39 025 5 b 39 020 6 b 39 01b 7 b 39 016 8 b 39 061 9 b 39 05c a b 39 057 b b 39 052 c b 39 04d d b 39 048 e b 39 043 f b 39 03e 0 c 39 039 1 c 39 035 2 c 39 031 3 c 39 02d 4 c 39 029 5 c 39 025 6 c 39 021 7 c 39 01d 8 c 39 059 9 c 39 055 a c 39 051 b c 39 04d c c 39 049 d c 39 045 e c 39 041 f c 39 03d 0 d 39 039 1 d 39 036 2 d 39 033 3 d 39 030 4 d 39 02d 5 d 39 02a 6 d 39 027 7 d 39 024 8 d 39 051 9 d 39 04e a d 39 04b b d 39 048 c d 39 045 d d 39 042 e d 39 03f f d 39 03c 0 e 39 039 1 e 39 037 2 e 39 035 3 e 39 033 4 e 39 031 5 e 39 02f 6 e 39 02d 7 e 39 02b 8 e 39 049 9 e 39 047 a e 39 045 b e 39 043 c e 39 041 d e 39 03f e e 39 03d f e 39 03b 0 f 39 039 1 f 39 038 2 f 39 037 3 f 39 036 4 f 39 035 5 f 39 034 6 f 39 033 7 f 39 032 8 f 39 041 9 f 39 040 a f 39 03f b f 39 03e c f 39 03d d f 39 03c e f 39 03b f f 39 03a 0 0 3a 03a 1 0 3a 03a 2 0 3a 03a 3 0 3a 03a 4 0 3a 03a 5 0 3a 03a 6 0 3a 03a 7 0 3a 03a 8 0 3a 03a 9 0 3a 03a a 0 3a 03a b 0 3a 03a c 0 3a 03a d 0 3a 03a e 0 3a 03a f 0 3a 03a 0 1 3a 03a 1 1 3a 03b 2 1 3a 03c 3 1 3a 03d 4 1 3a 03e 5 1 3a 03f 6 1 3a 040 7 1 3a 041 8 1 3a 032 9 1 3a 033 a 1 3a 034 b 1 3a 035 c 1 3a 036 d 1 3a 037 e 1 3a 038 f 1 3a 039 0 2 3a 03a 1 2 3a 03c 2 2 3a 03e 3 2 3a 040 4 2 3a 042 5 2 3a 044 6 2 3a 046 7 2 3a 048 8 2 3a 02a 9 2 3a 02c a 2 3a 02e b 2 3a 030 c 2 3a 032 d 2 3a 034 e 2 3a 036 f 2 3a 038 0 3 3a 03a 1 3 3a 03d 2 3 3a 040 3 3 3a 043 4 3 3a 046 5 3 3a 049 6 3 3a 04c 7 3 3a 04f 8 3 3a 022 9 3 3a 025 a 3 3a 028 b 3 3a 02b c 3 3a 02e d 3 3a 031 e 3 3a 034 f 3 3a 037 0 4 3a 03a 1 4 3a 03e 2 4 3a 042 3 4 3a 046 4 4 3a 04a 5 4 3a 04e 6 4 3a 052 7 4 3a 056 8 4 3a 01a 9 4 3a 01e a 4 3a 022 b 4 3a 026 c 4 3a 02a d 4 3a 02e e 4 3a 032 f 4 3a 036 0 5 3a 03a 1 5 3a 03f 2 5 3a 044 3 5 3a 049 4 5 3a 04e 5 5 3a 053 6 5 3a 058 7 5 3a 05d 8 5 3a 012 9 5 3a 017 a 5 3a 01c b 5 3a 021 c 5 3a 026 d 5 3a 02b e 5 3a 030 f 5 3a 035 0 6 3a 03a 1 6 3a 040 2 6 3a 046 3 6 3a 04c 4 6 3a 052 5 6 3a 058 6 6 3a 05e 7 6 3a 064 8 6 3a 00a 9 6 3a 010 a 6 3a 016 b 6 3a 01c c 6 3a 022 d 6 3a 028 e 6 3a 02e f 6 3a 034 0 7 3a 03a 1 7 3a 041 2 7 3a 048 3 7 3a 04f 4 7 3a 056 5 7 3a 05d 6 7 3a 064 7 7 3a 06b 8 7 3a 002 9 7 3a 009 a 7 3a 010 b 7 3a 017 c 7 3a 01e d 7 3a 025 e 7 3a 02c f 7 3a 033 0 8 3a 03a 1 8 3a 032 2 8 3a 02a 3 8 3a 022 4 8 3a 01a 5 8 3a 012 6 8 3a 00a 7 8 3a 002 8 8 3a 07a 9 8 3a 072 a 8 3a 06a b 8 3a 062 c 8 3a 05a d 8 3a 052 e 8 3a 04a f 8 3a 042 0 9 3a 03a 1 9 3a 033 2 9 3a 02c 3 9 3a 025 4 9 3a 01e 5 9 3a 017 6 9 3a 010 7 9 3a 009 8 9 3a 072 9 9 3a 06b a 9 3a 064 b 9 3a 05d c 9 3a 056 d 9 3a 04f e 9 3a 048 f 9 3a 041 0 a 3a 03a 1 a 3a 034 2 a 3a 02e 3 a 3a 028 4 a 3a 022 5 a 3a 01c 6 a 3a 016 7 a 3a 010 8 a 3a 06a 9 a 3a 064 a a 3a 05e b a 3a 058 c a 3a 052 d a 3a 04c e a 3a 046 f a 3a 040 0 b 3a 03a 1 b 3a 035 2 b 3a 030 3 b 3a 02b 4 b 3a 026 5 b 3a 021 6 b 3a 01c 7 b 3a 017 8 b 3a 062 9 b 3a 05d a b 3a 058 b b 3a 053 c b 3a 04e d b 3a 049 e b 3a 044 f b 3a 03f 0 c 3a 03a 1 c 3a 036 2 c 3a 032 3 c 3a 02e 4 c 3a 02a 5 c 3a 026 6 c 3a 022 7 c 3a 01e 8 c 3a 05a 9 c 3a 056 a c 3a 052 b c 3a 04e c c 3a 04a d c 3a 046 e c 3a 042 f c 3a 03e 0 d 3a 03a 1 d 3a 037 2 d 3a 034 3 d 3a 031 4 d 3a 02e 5 d 3a 02b 6 d 3a 028 7 d 3a 025 8 d 3a 052 9 d 3a 04f a d 3a 04c b d 3a 049 c d 3a 046 d d 3a 043 e d 3a 040 f d 3a 03d 0 e 3a 03a 1 e 3a 038 2 e 3a 036 3 e 3a 034 4 e 3a 032 5 e 3a 030 6 e 3a 02e 7 e 3a 02c 8 e 3a 04a 9 e 3a 048 a e 3a 046 b e 3a 044 c e 3a 042 d e 3a 040 e e 3a 03e f e 3a 03c 0 f 3a 03a 1 f 3a 039 2 f 3a 038 3 f 3a 037 4 f 3a 036 5 f 3a 035 6 f 3a 034 7 f 3a 033 8 f 3a 042 9 f 3a 041 a f 3a 040 b f 3a 03f c f 3a 03e d f 3a 03d e f 3a 03c f f 3a 03b 0 0 3b 03b 1 0 3b 03b 2 0 3b 03b 3 0 3b 03b 4 0 3b 03b 5 0 3b 03b 6 0 3b 03b 7 0 3b 03b 8 0 3b 03b 9 0 3b 03b a 0 3b 03b b 0 3b 03b c 0 3b 03b d 0 3b 03b e 0 3b 03b f 0 3b 03b 0 1 3b 03b 1 1 3b 03c 2 1 3b 03d 3 1 3b 03e 4 1 3b 03f 5 1 3b 040 6 1 3b 041 7 1 3b 042 8 1 3b 033 9 1 3b 034 a 1 3b 035 b 1 3b 036 c 1 3b 037 d 1 3b 038 e 1 3b 039 f 1 3b 03a 0 2 3b 03b 1 2 3b 03d 2 2 3b 03f 3 2 3b 041 4 2 3b 043 5 2 3b 045 6 2 3b 047 7 2 3b 049 8 2 3b 02b 9 2 3b 02d a 2 3b 02f b 2 3b 031 c 2 3b 033 d 2 3b 035 e 2 3b 037 f 2 3b 039 0 3 3b 03b 1 3 3b 03e 2 3 3b 041 3 3 3b 044 4 3 3b 047 5 3 3b 04a 6 3 3b 04d 7 3 3b 050 8 3 3b 023 9 3 3b 026 a 3 3b 029 b 3 3b 02c c 3 3b 02f d 3 3b 032 e 3 3b 035 f 3 3b 038 0 4 3b 03b 1 4 3b 03f 2 4 3b 043 3 4 3b 047 4 4 3b 04b 5 4 3b 04f 6 4 3b 053 7 4 3b 057 8 4 3b 01b 9 4 3b 01f a 4 3b 023 b 4 3b 027 c 4 3b 02b d 4 3b 02f e 4 3b 033 f 4 3b 037 0 5 3b 03b 1 5 3b 040 2 5 3b 045 3 5 3b 04a 4 5 3b 04f 5 5 3b 054 6 5 3b 059 7 5 3b 05e 8 5 3b 013 9 5 3b 018 a 5 3b 01d b 5 3b 022 c 5 3b 027 d 5 3b 02c e 5 3b 031 f 5 3b 036 0 6 3b 03b 1 6 3b 041 2 6 3b 047 3 6 3b 04d 4 6 3b 053 5 6 3b 059 6 6 3b 05f 7 6 3b 065 8 6 3b 00b 9 6 3b 011 a 6 3b 017 b 6 3b 01d c 6 3b 023 d 6 3b 029 e 6 3b 02f f 6 3b 035 0 7 3b 03b 1 7 3b 042 2 7 3b 049 3 7 3b 050 4 7 3b 057 5 7 3b 05e 6 7 3b 065 7 7 3b 06c 8 7 3b 003 9 7 3b 00a a 7 3b 011 b 7 3b 018 c 7 3b 01f d 7 3b 026 e 7 3b 02d f 7 3b 034 0 8 3b 03b 1 8 3b 033 2 8 3b 02b 3 8 3b 023 4 8 3b 01b 5 8 3b 013 6 8 3b 00b 7 8 3b 003 8 8 3b 07b 9 8 3b 073 a 8 3b 06b b 8 3b 063 c 8 3b 05b d 8 3b 053 e 8 3b 04b f 8 3b 043 0 9 3b 03b 1 9 3b 034 2 9 3b 02d 3 9 3b 026 4 9 3b 01f 5 9 3b 018 6 9 3b 011 7 9 3b 00a 8 9 3b 073 9 9 3b 06c a 9 3b 065 b 9 3b 05e c 9 3b 057 d 9 3b 050 e 9 3b 049 f 9 3b 042 0 a 3b 03b 1 a 3b 035 2 a 3b 02f 3 a 3b 029 4 a 3b 023 5 a 3b 01d 6 a 3b 017 7 a 3b 011 8 a 3b 06b 9 a 3b 065 a a 3b 05f b a 3b 059 c a 3b 053 d a 3b 04d e a 3b 047 f a 3b 041 0 b 3b 03b 1 b 3b 036 2 b 3b 031 3 b 3b 02c 4 b 3b 027 5 b 3b 022 6 b 3b 01d 7 b 3b 018 8 b 3b 063 9 b 3b 05e a b 3b 059 b b 3b 054 c b 3b 04f d b 3b 04a e b 3b 045 f b 3b 040 0 c 3b 03b 1 c 3b 037 2 c 3b 033 3 c 3b 02f 4 c 3b 02b 5 c 3b 027 6 c 3b 023 7 c 3b 01f 8 c 3b 05b 9 c 3b 057 a c 3b 053 b c 3b 04f c c 3b 04b d c 3b 047 e c 3b 043 f c 3b 03f 0 d 3b 03b 1 d 3b 038 2 d 3b 035 3 d 3b 032 4 d 3b 02f 5 d 3b 02c 6 d 3b 029 7 d 3b 026 8 d 3b 053 9 d 3b 050 a d 3b 04d b d 3b 04a c d 3b 047 d d 3b 044 e d 3b 041 f d 3b 03e 0 e 3b 03b 1 e 3b 039 2 e 3b 037 3 e 3b 035 4 e 3b 033 5 e 3b 031 6 e 3b 02f 7 e 3b 02d 8 e 3b 04b 9 e 3b 049 a e 3b 047 b e 3b 045 c e 3b 043 d e 3b 041 e e 3b 03f f e 3b 03d 0 f 3b 03b 1 f 3b 03a 2 f 3b 039 3 f 3b 038 4 f 3b 037 5 f 3b 036 6 f 3b 035 7 f 3b 034 8 f 3b 043 9 f 3b 042 a f 3b 041 b f 3b 040 c f 3b 03f d f 3b 03e e f 3b 03d f f 3b 03c 0 0 3c 03c 1 0 3c 03c 2 0 3c 03c 3 0 3c 03c 4 0 3c 03c 5 0 3c 03c 6 0 3c 03c 7 0 3c 03c 8 0 3c 03c 9 0 3c 03c a 0 3c 03c b 0 3c 03c c 0 3c 03c d 0 3c 03c e 0 3c 03c f 0 3c 03c 0 1 3c 03c 1 1 3c 03d 2 1 3c 03e 3 1 3c 03f 4 1 3c 040 5 1 3c 041 6 1 3c 042 7 1 3c 043 8 1 3c 034 9 1 3c 035 a 1 3c 036 b 1 3c 037 c 1 3c 038 d 1 3c 039 e 1 3c 03a f 1 3c 03b 0 2 3c 03c 1 2 3c 03e 2 2 3c 040 3 2 3c 042 4 2 3c 044 5 2 3c 046 6 2 3c 048 7 2 3c 04a 8 2 3c 02c 9 2 3c 02e a 2 3c 030 b 2 3c 032 c 2 3c 034 d 2 3c 036 e 2 3c 038 f 2 3c 03a 0 3 3c 03c 1 3 3c 03f 2 3 3c 042 3 3 3c 045 4 3 3c 048 5 3 3c 04b 6 3 3c 04e 7 3 3c 051 8 3 3c 024 9 3 3c 027 a 3 3c 02a b 3 3c 02d c 3 3c 030 d 3 3c 033 e 3 3c 036 f 3 3c 039 0 4 3c 03c 1 4 3c 040 2 4 3c 044 3 4 3c 048 4 4 3c 04c 5 4 3c 050 6 4 3c 054 7 4 3c 058 8 4 3c 01c 9 4 3c 020 a 4 3c 024 b 4 3c 028 c 4 3c 02c d 4 3c 030 e 4 3c 034 f 4 3c 038 0 5 3c 03c 1 5 3c 041 2 5 3c 046 3 5 3c 04b 4 5 3c 050 5 5 3c 055 6 5 3c 05a 7 5 3c 05f 8 5 3c 014 9 5 3c 019 a 5 3c 01e b 5 3c 023 c 5 3c 028 d 5 3c 02d e 5 3c 032 f 5 3c 037 0 6 3c 03c 1 6 3c 042 2 6 3c 048 3 6 3c 04e 4 6 3c 054 5 6 3c 05a 6 6 3c 060 7 6 3c 066 8 6 3c 00c 9 6 3c 012 a 6 3c 018 b 6 3c 01e c 6 3c 024 d 6 3c 02a e 6 3c 030 f 6 3c 036 0 7 3c 03c 1 7 3c 043 2 7 3c 04a 3 7 3c 051 4 7 3c 058 5 7 3c 05f 6 7 3c 066 7 7 3c 06d 8 7 3c 004 9 7 3c 00b a 7 3c 012 b 7 3c 019 c 7 3c 020 d 7 3c 027 e 7 3c 02e f 7 3c 035 0 8 3c 03c 1 8 3c 034 2 8 3c 02c 3 8 3c 024 4 8 3c 01c 5 8 3c 014 6 8 3c 00c 7 8 3c 004 8 8 3c 07c 9 8 3c 074 a 8 3c 06c b 8 3c 064 c 8 3c 05c d 8 3c 054 e 8 3c 04c f 8 3c 044 0 9 3c 03c 1 9 3c 035 2 9 3c 02e 3 9 3c 027 4 9 3c 020 5 9 3c 019 6 9 3c 012 7 9 3c 00b 8 9 3c 074 9 9 3c 06d a 9 3c 066 b 9 3c 05f c 9 3c 058 d 9 3c 051 e 9 3c 04a f 9 3c 043 0 a 3c 03c 1 a 3c 036 2 a 3c 030 3 a 3c 02a 4 a 3c 024 5 a 3c 01e 6 a 3c 018 7 a 3c 012 8 a 3c 06c 9 a 3c 066 a a 3c 060 b a 3c 05a c a 3c 054 d a 3c 04e e a 3c 048 f a 3c 042 0 b 3c 03c 1 b 3c 037 2 b 3c 032 3 b 3c 02d 4 b 3c 028 5 b 3c 023 6 b 3c 01e 7 b 3c 019 8 b 3c 064 9 b 3c 05f a b 3c 05a b b 3c 055 c b 3c 050 d b 3c 04b e b 3c 046 f b 3c 041 0 c 3c 03c 1 c 3c 038 2 c 3c 034 3 c 3c 030 4 c 3c 02c 5 c 3c 028 6 c 3c 024 7 c 3c 020 8 c 3c 05c 9 c 3c 058 a c 3c 054 b c 3c 050 c c 3c 04c d c 3c 048 e c 3c 044 f c 3c 040 0 d 3c 03c 1 d 3c 039 2 d 3c 036 3 d 3c 033 4 d 3c 030 5 d 3c 02d 6 d 3c 02a 7 d 3c 027 8 d 3c 054 9 d 3c 051 a d 3c 04e b d 3c 04b c d 3c 048 d d 3c 045 e d 3c 042 f d 3c 03f 0 e 3c 03c 1 e 3c 03a 2 e 3c 038 3 e 3c 036 4 e 3c 034 5 e 3c 032 6 e 3c 030 7 e 3c 02e 8 e 3c 04c 9 e 3c 04a a e 3c 048 b e 3c 046 c e 3c 044 d e 3c 042 e e 3c 040 f e 3c 03e 0 f 3c 03c 1 f 3c 03b 2 f 3c 03a 3 f 3c 039 4 f 3c 038 5 f 3c 037 6 f 3c 036 7 f 3c 035 8 f 3c 044 9 f 3c 043 a f 3c 042 b f 3c 041 c f 3c 040 d f 3c 03f e f 3c 03e f f 3c 03d 0 0 3d 03d 1 0 3d 03d 2 0 3d 03d 3 0 3d 03d 4 0 3d 03d 5 0 3d 03d 6 0 3d 03d 7 0 3d 03d 8 0 3d 03d 9 0 3d 03d a 0 3d 03d b 0 3d 03d c 0 3d 03d d 0 3d 03d e 0 3d 03d f 0 3d 03d 0 1 3d 03d 1 1 3d 03e 2 1 3d 03f 3 1 3d 040 4 1 3d 041 5 1 3d 042 6 1 3d 043 7 1 3d 044 8 1 3d 035 9 1 3d 036 a 1 3d 037 b 1 3d 038 c 1 3d 039 d 1 3d 03a e 1 3d 03b f 1 3d 03c 0 2 3d 03d 1 2 3d 03f 2 2 3d 041 3 2 3d 043 4 2 3d 045 5 2 3d 047 6 2 3d 049 7 2 3d 04b 8 2 3d 02d 9 2 3d 02f a 2 3d 031 b 2 3d 033 c 2 3d 035 d 2 3d 037 e 2 3d 039 f 2 3d 03b 0 3 3d 03d 1 3 3d 040 2 3 3d 043 3 3 3d 046 4 3 3d 049 5 3 3d 04c 6 3 3d 04f 7 3 3d 052 8 3 3d 025 9 3 3d 028 a 3 3d 02b b 3 3d 02e c 3 3d 031 d 3 3d 034 e 3 3d 037 f 3 3d 03a 0 4 3d 03d 1 4 3d 041 2 4 3d 045 3 4 3d 049 4 4 3d 04d 5 4 3d 051 6 4 3d 055 7 4 3d 059 8 4 3d 01d 9 4 3d 021 a 4 3d 025 b 4 3d 029 c 4 3d 02d d 4 3d 031 e 4 3d 035 f 4 3d 039 0 5 3d 03d 1 5 3d 042 2 5 3d 047 3 5 3d 04c 4 5 3d 051 5 5 3d 056 6 5 3d 05b 7 5 3d 060 8 5 3d 015 9 5 3d 01a a 5 3d 01f b 5 3d 024 c 5 3d 029 d 5 3d 02e e 5 3d 033 f 5 3d 038 0 6 3d 03d 1 6 3d 043 2 6 3d 049 3 6 3d 04f 4 6 3d 055 5 6 3d 05b 6 6 3d 061 7 6 3d 067 8 6 3d 00d 9 6 3d 013 a 6 3d 019 b 6 3d 01f c 6 3d 025 d 6 3d 02b e 6 3d 031 f 6 3d 037 0 7 3d 03d 1 7 3d 044 2 7 3d 04b 3 7 3d 052 4 7 3d 059 5 7 3d 060 6 7 3d 067 7 7 3d 06e 8 7 3d 005 9 7 3d 00c a 7 3d 013 b 7 3d 01a c 7 3d 021 d 7 3d 028 e 7 3d 02f f 7 3d 036 0 8 3d 03d 1 8 3d 035 2 8 3d 02d 3 8 3d 025 4 8 3d 01d 5 8 3d 015 6 8 3d 00d 7 8 3d 005 8 8 3d 07d 9 8 3d 075 a 8 3d 06d b 8 3d 065 c 8 3d 05d d 8 3d 055 e 8 3d 04d f 8 3d 045 0 9 3d 03d 1 9 3d 036 2 9 3d 02f 3 9 3d 028 4 9 3d 021 5 9 3d 01a 6 9 3d 013 7 9 3d 00c 8 9 3d 075 9 9 3d 06e a 9 3d 067 b 9 3d 060 c 9 3d 059 d 9 3d 052 e 9 3d 04b f 9 3d 044 0 a 3d 03d 1 a 3d 037 2 a 3d 031 3 a 3d 02b 4 a 3d 025 5 a 3d 01f 6 a 3d 019 7 a 3d 013 8 a 3d 06d 9 a 3d 067 a a 3d 061 b a 3d 05b c a 3d 055 d a 3d 04f e a 3d 049 f a 3d 043 0 b 3d 03d 1 b 3d 038 2 b 3d 033 3 b 3d 02e 4 b 3d 029 5 b 3d 024 6 b 3d 01f 7 b 3d 01a 8 b 3d 065 9 b 3d 060 a b 3d 05b b b 3d 056 c b 3d 051 d b 3d 04c e b 3d 047 f b 3d 042 0 c 3d 03d 1 c 3d 039 2 c 3d 035 3 c 3d 031 4 c 3d 02d 5 c 3d 029 6 c 3d 025 7 c 3d 021 8 c 3d 05d 9 c 3d 059 a c 3d 055 b c 3d 051 c c 3d 04d d c 3d 049 e c 3d 045 f c 3d 041 0 d 3d 03d 1 d 3d 03a 2 d 3d 037 3 d 3d 034 4 d 3d 031 5 d 3d 02e 6 d 3d 02b 7 d 3d 028 8 d 3d 055 9 d 3d 052 a d 3d 04f b d 3d 04c c d 3d 049 d d 3d 046 e d 3d 043 f d 3d 040 0 e 3d 03d 1 e 3d 03b 2 e 3d 039 3 e 3d 037 4 e 3d 035 5 e 3d 033 6 e 3d 031 7 e 3d 02f 8 e 3d 04d 9 e 3d 04b a e 3d 049 b e 3d 047 c e 3d 045 d e 3d 043 e e 3d 041 f e 3d 03f 0 f 3d 03d 1 f 3d 03c 2 f 3d 03b 3 f 3d 03a 4 f 3d 039 5 f 3d 038 6 f 3d 037 7 f 3d 036 8 f 3d 045 9 f 3d 044 a f 3d 043 b f 3d 042 c f 3d 041 d f 3d 040 e f 3d 03f f f 3d 03e 0 0 3e 03e 1 0 3e 03e 2 0 3e 03e 3 0 3e 03e 4 0 3e 03e 5 0 3e 03e 6 0 3e 03e 7 0 3e 03e 8 0 3e 03e 9 0 3e 03e a 0 3e 03e b 0 3e 03e c 0 3e 03e d 0 3e 03e e 0 3e 03e f 0 3e 03e 0 1 3e 03e 1 1 3e 03f 2 1 3e 040 3 1 3e 041 4 1 3e 042 5 1 3e 043 6 1 3e 044 7 1 3e 045 8 1 3e 036 9 1 3e 037 a 1 3e 038 b 1 3e 039 c 1 3e 03a d 1 3e 03b e 1 3e 03c f 1 3e 03d 0 2 3e 03e 1 2 3e 040 2 2 3e 042 3 2 3e 044 4 2 3e 046 5 2 3e 048 6 2 3e 04a 7 2 3e 04c 8 2 3e 02e 9 2 3e 030 a 2 3e 032 b 2 3e 034 c 2 3e 036 d 2 3e 038 e 2 3e 03a f 2 3e 03c 0 3 3e 03e 1 3 3e 041 2 3 3e 044 3 3 3e 047 4 3 3e 04a 5 3 3e 04d 6 3 3e 050 7 3 3e 053 8 3 3e 026 9 3 3e 029 a 3 3e 02c b 3 3e 02f c 3 3e 032 d 3 3e 035 e 3 3e 038 f 3 3e 03b 0 4 3e 03e 1 4 3e 042 2 4 3e 046 3 4 3e 04a 4 4 3e 04e 5 4 3e 052 6 4 3e 056 7 4 3e 05a 8 4 3e 01e 9 4 3e 022 a 4 3e 026 b 4 3e 02a c 4 3e 02e d 4 3e 032 e 4 3e 036 f 4 3e 03a 0 5 3e 03e 1 5 3e 043 2 5 3e 048 3 5 3e 04d 4 5 3e 052 5 5 3e 057 6 5 3e 05c 7 5 3e 061 8 5 3e 016 9 5 3e 01b a 5 3e 020 b 5 3e 025 c 5 3e 02a d 5 3e 02f e 5 3e 034 f 5 3e 039 0 6 3e 03e 1 6 3e 044 2 6 3e 04a 3 6 3e 050 4 6 3e 056 5 6 3e 05c 6 6 3e 062 7 6 3e 068 8 6 3e 00e 9 6 3e 014 a 6 3e 01a b 6 3e 020 c 6 3e 026 d 6 3e 02c e 6 3e 032 f 6 3e 038 0 7 3e 03e 1 7 3e 045 2 7 3e 04c 3 7 3e 053 4 7 3e 05a 5 7 3e 061 6 7 3e 068 7 7 3e 06f 8 7 3e 006 9 7 3e 00d a 7 3e 014 b 7 3e 01b c 7 3e 022 d 7 3e 029 e 7 3e 030 f 7 3e 037 0 8 3e 03e 1 8 3e 036 2 8 3e 02e 3 8 3e 026 4 8 3e 01e 5 8 3e 016 6 8 3e 00e 7 8 3e 006 8 8 3e 07e 9 8 3e 076 a 8 3e 06e b 8 3e 066 c 8 3e 05e d 8 3e 056 e 8 3e 04e f 8 3e 046 0 9 3e 03e 1 9 3e 037 2 9 3e 030 3 9 3e 029 4 9 3e 022 5 9 3e 01b 6 9 3e 014 7 9 3e 00d 8 9 3e 076 9 9 3e 06f a 9 3e 068 b 9 3e 061 c 9 3e 05a d 9 3e 053 e 9 3e 04c f 9 3e 045 0 a 3e 03e 1 a 3e 038 2 a 3e 032 3 a 3e 02c 4 a 3e 026 5 a 3e 020 6 a 3e 01a 7 a 3e 014 8 a 3e 06e 9 a 3e 068 a a 3e 062 b a 3e 05c c a 3e 056 d a 3e 050 e a 3e 04a f a 3e 044 0 b 3e 03e 1 b 3e 039 2 b 3e 034 3 b 3e 02f 4 b 3e 02a 5 b 3e 025 6 b 3e 020 7 b 3e 01b 8 b 3e 066 9 b 3e 061 a b 3e 05c b b 3e 057 c b 3e 052 d b 3e 04d e b 3e 048 f b 3e 043 0 c 3e 03e 1 c 3e 03a 2 c 3e 036 3 c 3e 032 4 c 3e 02e 5 c 3e 02a 6 c 3e 026 7 c 3e 022 8 c 3e 05e 9 c 3e 05a a c 3e 056 b c 3e 052 c c 3e 04e d c 3e 04a e c 3e 046 f c 3e 042 0 d 3e 03e 1 d 3e 03b 2 d 3e 038 3 d 3e 035 4 d 3e 032 5 d 3e 02f 6 d 3e 02c 7 d 3e 029 8 d 3e 056 9 d 3e 053 a d 3e 050 b d 3e 04d c d 3e 04a d d 3e 047 e d 3e 044 f d 3e 041 0 e 3e 03e 1 e 3e 03c 2 e 3e 03a 3 e 3e 038 4 e 3e 036 5 e 3e 034 6 e 3e 032 7 e 3e 030 8 e 3e 04e 9 e 3e 04c a e 3e 04a b e 3e 048 c e 3e 046 d e 3e 044 e e 3e 042 f e 3e 040 0 f 3e 03e 1 f 3e 03d 2 f 3e 03c 3 f 3e 03b 4 f 3e 03a 5 f 3e 039 6 f 3e 038 7 f 3e 037 8 f 3e 046 9 f 3e 045 a f 3e 044 b f 3e 043 c f 3e 042 d f 3e 041 e f 3e 040 f f 3e 03f 0 0 3f 03f 1 0 3f 03f 2 0 3f 03f 3 0 3f 03f 4 0 3f 03f 5 0 3f 03f 6 0 3f 03f 7 0 3f 03f 8 0 3f 03f 9 0 3f 03f a 0 3f 03f b 0 3f 03f c 0 3f 03f d 0 3f 03f e 0 3f 03f f 0 3f 03f 0 1 3f 03f 1 1 3f 040 2 1 3f 041 3 1 3f 042 4 1 3f 043 5 1 3f 044 6 1 3f 045 7 1 3f 046 8 1 3f 037 9 1 3f 038 a 1 3f 039 b 1 3f 03a c 1 3f 03b d 1 3f 03c e 1 3f 03d f 1 3f 03e 0 2 3f 03f 1 2 3f 041 2 2 3f 043 3 2 3f 045 4 2 3f 047 5 2 3f 049 6 2 3f 04b 7 2 3f 04d 8 2 3f 02f 9 2 3f 031 a 2 3f 033 b 2 3f 035 c 2 3f 037 d 2 3f 039 e 2 3f 03b f 2 3f 03d 0 3 3f 03f 1 3 3f 042 2 3 3f 045 3 3 3f 048 4 3 3f 04b 5 3 3f 04e 6 3 3f 051 7 3 3f 054 8 3 3f 027 9 3 3f 02a a 3 3f 02d b 3 3f 030 c 3 3f 033 d 3 3f 036 e 3 3f 039 f 3 3f 03c 0 4 3f 03f 1 4 3f 043 2 4 3f 047 3 4 3f 04b 4 4 3f 04f 5 4 3f 053 6 4 3f 057 7 4 3f 05b 8 4 3f 01f 9 4 3f 023 a 4 3f 027 b 4 3f 02b c 4 3f 02f d 4 3f 033 e 4 3f 037 f 4 3f 03b 0 5 3f 03f 1 5 3f 044 2 5 3f 049 3 5 3f 04e 4 5 3f 053 5 5 3f 058 6 5 3f 05d 7 5 3f 062 8 5 3f 017 9 5 3f 01c a 5 3f 021 b 5 3f 026 c 5 3f 02b d 5 3f 030 e 5 3f 035 f 5 3f 03a 0 6 3f 03f 1 6 3f 045 2 6 3f 04b 3 6 3f 051 4 6 3f 057 5 6 3f 05d 6 6 3f 063 7 6 3f 069 8 6 3f 00f 9 6 3f 015 a 6 3f 01b b 6 3f 021 c 6 3f 027 d 6 3f 02d e 6 3f 033 f 6 3f 039 0 7 3f 03f 1 7 3f 046 2 7 3f 04d 3 7 3f 054 4 7 3f 05b 5 7 3f 062 6 7 3f 069 7 7 3f 070 8 7 3f 007 9 7 3f 00e a 7 3f 015 b 7 3f 01c c 7 3f 023 d 7 3f 02a e 7 3f 031 f 7 3f 038 0 8 3f 03f 1 8 3f 037 2 8 3f 02f 3 8 3f 027 4 8 3f 01f 5 8 3f 017 6 8 3f 00f 7 8 3f 007 8 8 3f 07f 9 8 3f 077 a 8 3f 06f b 8 3f 067 c 8 3f 05f d 8 3f 057 e 8 3f 04f f 8 3f 047 0 9 3f 03f 1 9 3f 038 2 9 3f 031 3 9 3f 02a 4 9 3f 023 5 9 3f 01c 6 9 3f 015 7 9 3f 00e 8 9 3f 077 9 9 3f 070 a 9 3f 069 b 9 3f 062 c 9 3f 05b d 9 3f 054 e 9 3f 04d f 9 3f 046 0 a 3f 03f 1 a 3f 039 2 a 3f 033 3 a 3f 02d 4 a 3f 027 5 a 3f 021 6 a 3f 01b 7 a 3f 015 8 a 3f 06f 9 a 3f 069 a a 3f 063 b a 3f 05d c a 3f 057 d a 3f 051 e a 3f 04b f a 3f 045 0 b 3f 03f 1 b 3f 03a 2 b 3f 035 3 b 3f 030 4 b 3f 02b 5 b 3f 026 6 b 3f 021 7 b 3f 01c 8 b 3f 067 9 b 3f 062 a b 3f 05d b b 3f 058 c b 3f 053 d b 3f 04e e b 3f 049 f b 3f 044 0 c 3f 03f 1 c 3f 03b 2 c 3f 037 3 c 3f 033 4 c 3f 02f 5 c 3f 02b 6 c 3f 027 7 c 3f 023 8 c 3f 05f 9 c 3f 05b a c 3f 057 b c 3f 053 c c 3f 04f d c 3f 04b e c 3f 047 f c 3f 043 0 d 3f 03f 1 d 3f 03c 2 d 3f 039 3 d 3f 036 4 d 3f 033 5 d 3f 030 6 d 3f 02d 7 d 3f 02a 8 d 3f 057 9 d 3f 054 a d 3f 051 b d 3f 04e c d 3f 04b d d 3f 048 e d 3f 045 f d 3f 042 0 e 3f 03f 1 e 3f 03d 2 e 3f 03b 3 e 3f 039 4 e 3f 037 5 e 3f 035 6 e 3f 033 7 e 3f 031 8 e 3f 04f 9 e 3f 04d a e 3f 04b b e 3f 049 c e 3f 047 d e 3f 045 e e 3f 043 f e 3f 041 0 f 3f 03f 1 f 3f 03e 2 f 3f 03d 3 f 3f 03c 4 f 3f 03b 5 f 3f 03a 6 f 3f 039 7 f 3f 038 8 f 3f 047 9 f 3f 046 a f 3f 045 b f 3f 044 c f 3f 043 d f 3f 042 e f 3f 041 f f 3f 040 0 0 40 040 1 0 40 040 2 0 40 040 3 0 40 040 4 0 40 040 5 0 40 040 6 0 40 040 7 0 40 040 8 0 40 040 9 0 40 040 a 0 40 040 b 0 40 040 c 0 40 040 d 0 40 040 e 0 40 040 f 0 40 040 0 1 40 040 1 1 40 041 2 1 40 042 3 1 40 043 4 1 40 044 5 1 40 045 6 1 40 046 7 1 40 047 8 1 40 038 9 1 40 039 a 1 40 03a b 1 40 03b c 1 40 03c d 1 40 03d e 1 40 03e f 1 40 03f 0 2 40 040 1 2 40 042 2 2 40 044 3 2 40 046 4 2 40 048 5 2 40 04a 6 2 40 04c 7 2 40 04e 8 2 40 030 9 2 40 032 a 2 40 034 b 2 40 036 c 2 40 038 d 2 40 03a e 2 40 03c f 2 40 03e 0 3 40 040 1 3 40 043 2 3 40 046 3 3 40 049 4 3 40 04c 5 3 40 04f 6 3 40 052 7 3 40 055 8 3 40 028 9 3 40 02b a 3 40 02e b 3 40 031 c 3 40 034 d 3 40 037 e 3 40 03a f 3 40 03d 0 4 40 040 1 4 40 044 2 4 40 048 3 4 40 04c 4 4 40 050 5 4 40 054 6 4 40 058 7 4 40 05c 8 4 40 020 9 4 40 024 a 4 40 028 b 4 40 02c c 4 40 030 d 4 40 034 e 4 40 038 f 4 40 03c 0 5 40 040 1 5 40 045 2 5 40 04a 3 5 40 04f 4 5 40 054 5 5 40 059 6 5 40 05e 7 5 40 063 8 5 40 018 9 5 40 01d a 5 40 022 b 5 40 027 c 5 40 02c d 5 40 031 e 5 40 036 f 5 40 03b 0 6 40 040 1 6 40 046 2 6 40 04c 3 6 40 052 4 6 40 058 5 6 40 05e 6 6 40 064 7 6 40 06a 8 6 40 010 9 6 40 016 a 6 40 01c b 6 40 022 c 6 40 028 d 6 40 02e e 6 40 034 f 6 40 03a 0 7 40 040 1 7 40 047 2 7 40 04e 3 7 40 055 4 7 40 05c 5 7 40 063 6 7 40 06a 7 7 40 071 8 7 40 008 9 7 40 00f a 7 40 016 b 7 40 01d c 7 40 024 d 7 40 02b e 7 40 032 f 7 40 039 0 8 40 040 1 8 40 038 2 8 40 030 3 8 40 028 4 8 40 020 5 8 40 018 6 8 40 010 7 8 40 008 8 8 40 080 9 8 40 078 a 8 40 070 b 8 40 068 c 8 40 060 d 8 40 058 e 8 40 050 f 8 40 048 0 9 40 040 1 9 40 039 2 9 40 032 3 9 40 02b 4 9 40 024 5 9 40 01d 6 9 40 016 7 9 40 00f 8 9 40 078 9 9 40 071 a 9 40 06a b 9 40 063 c 9 40 05c d 9 40 055 e 9 40 04e f 9 40 047 0 a 40 040 1 a 40 03a 2 a 40 034 3 a 40 02e 4 a 40 028 5 a 40 022 6 a 40 01c 7 a 40 016 8 a 40 070 9 a 40 06a a a 40 064 b a 40 05e c a 40 058 d a 40 052 e a 40 04c f a 40 046 0 b 40 040 1 b 40 03b 2 b 40 036 3 b 40 031 4 b 40 02c 5 b 40 027 6 b 40 022 7 b 40 01d 8 b 40 068 9 b 40 063 a b 40 05e b b 40 059 c b 40 054 d b 40 04f e b 40 04a f b 40 045 0 c 40 040 1 c 40 03c 2 c 40 038 3 c 40 034 4 c 40 030 5 c 40 02c 6 c 40 028 7 c 40 024 8 c 40 060 9 c 40 05c a c 40 058 b c 40 054 c c 40 050 d c 40 04c e c 40 048 f c 40 044 0 d 40 040 1 d 40 03d 2 d 40 03a 3 d 40 037 4 d 40 034 5 d 40 031 6 d 40 02e 7 d 40 02b 8 d 40 058 9 d 40 055 a d 40 052 b d 40 04f c d 40 04c d d 40 049 e d 40 046 f d 40 043 0 e 40 040 1 e 40 03e 2 e 40 03c 3 e 40 03a 4 e 40 038 5 e 40 036 6 e 40 034 7 e 40 032 8 e 40 050 9 e 40 04e a e 40 04c b e 40 04a c e 40 048 d e 40 046 e e 40 044 f e 40 042 0 f 40 040 1 f 40 03f 2 f 40 03e 3 f 40 03d 4 f 40 03c 5 f 40 03b 6 f 40 03a 7 f 40 039 8 f 40 048 9 f 40 047 a f 40 046 b f 40 045 c f 40 044 d f 40 043 e f 40 042 f f 40 041 0 0 41 041 1 0 41 041 2 0 41 041 3 0 41 041 4 0 41 041 5 0 41 041 6 0 41 041 7 0 41 041 8 0 41 041 9 0 41 041 a 0 41 041 b 0 41 041 c 0 41 041 d 0 41 041 e 0 41 041 f 0 41 041 0 1 41 041 1 1 41 042 2 1 41 043 3 1 41 044 4 1 41 045 5 1 41 046 6 1 41 047 7 1 41 048 8 1 41 039 9 1 41 03a a 1 41 03b b 1 41 03c c 1 41 03d d 1 41 03e e 1 41 03f f 1 41 040 0 2 41 041 1 2 41 043 2 2 41 045 3 2 41 047 4 2 41 049 5 2 41 04b 6 2 41 04d 7 2 41 04f 8 2 41 031 9 2 41 033 a 2 41 035 b 2 41 037 c 2 41 039 d 2 41 03b e 2 41 03d f 2 41 03f 0 3 41 041 1 3 41 044 2 3 41 047 3 3 41 04a 4 3 41 04d 5 3 41 050 6 3 41 053 7 3 41 056 8 3 41 029 9 3 41 02c a 3 41 02f b 3 41 032 c 3 41 035 d 3 41 038 e 3 41 03b f 3 41 03e 0 4 41 041 1 4 41 045 2 4 41 049 3 4 41 04d 4 4 41 051 5 4 41 055 6 4 41 059 7 4 41 05d 8 4 41 021 9 4 41 025 a 4 41 029 b 4 41 02d c 4 41 031 d 4 41 035 e 4 41 039 f 4 41 03d 0 5 41 041 1 5 41 046 2 5 41 04b 3 5 41 050 4 5 41 055 5 5 41 05a 6 5 41 05f 7 5 41 064 8 5 41 019 9 5 41 01e a 5 41 023 b 5 41 028 c 5 41 02d d 5 41 032 e 5 41 037 f 5 41 03c 0 6 41 041 1 6 41 047 2 6 41 04d 3 6 41 053 4 6 41 059 5 6 41 05f 6 6 41 065 7 6 41 06b 8 6 41 011 9 6 41 017 a 6 41 01d b 6 41 023 c 6 41 029 d 6 41 02f e 6 41 035 f 6 41 03b 0 7 41 041 1 7 41 048 2 7 41 04f 3 7 41 056 4 7 41 05d 5 7 41 064 6 7 41 06b 7 7 41 072 8 7 41 009 9 7 41 010 a 7 41 017 b 7 41 01e c 7 41 025 d 7 41 02c e 7 41 033 f 7 41 03a 0 8 41 041 1 8 41 039 2 8 41 031 3 8 41 029 4 8 41 021 5 8 41 019 6 8 41 011 7 8 41 009 8 8 41 081 9 8 41 079 a 8 41 071 b 8 41 069 c 8 41 061 d 8 41 059 e 8 41 051 f 8 41 049 0 9 41 041 1 9 41 03a 2 9 41 033 3 9 41 02c 4 9 41 025 5 9 41 01e 6 9 41 017 7 9 41 010 8 9 41 079 9 9 41 072 a 9 41 06b b 9 41 064 c 9 41 05d d 9 41 056 e 9 41 04f f 9 41 048 0 a 41 041 1 a 41 03b 2 a 41 035 3 a 41 02f 4 a 41 029 5 a 41 023 6 a 41 01d 7 a 41 017 8 a 41 071 9 a 41 06b a a 41 065 b a 41 05f c a 41 059 d a 41 053 e a 41 04d f a 41 047 0 b 41 041 1 b 41 03c 2 b 41 037 3 b 41 032 4 b 41 02d 5 b 41 028 6 b 41 023 7 b 41 01e 8 b 41 069 9 b 41 064 a b 41 05f b b 41 05a c b 41 055 d b 41 050 e b 41 04b f b 41 046 0 c 41 041 1 c 41 03d 2 c 41 039 3 c 41 035 4 c 41 031 5 c 41 02d 6 c 41 029 7 c 41 025 8 c 41 061 9 c 41 05d a c 41 059 b c 41 055 c c 41 051 d c 41 04d e c 41 049 f c 41 045 0 d 41 041 1 d 41 03e 2 d 41 03b 3 d 41 038 4 d 41 035 5 d 41 032 6 d 41 02f 7 d 41 02c 8 d 41 059 9 d 41 056 a d 41 053 b d 41 050 c d 41 04d d d 41 04a e d 41 047 f d 41 044 0 e 41 041 1 e 41 03f 2 e 41 03d 3 e 41 03b 4 e 41 039 5 e 41 037 6 e 41 035 7 e 41 033 8 e 41 051 9 e 41 04f a e 41 04d b e 41 04b c e 41 049 d e 41 047 e e 41 045 f e 41 043 0 f 41 041 1 f 41 040 2 f 41 03f 3 f 41 03e 4 f 41 03d 5 f 41 03c 6 f 41 03b 7 f 41 03a 8 f 41 049 9 f 41 048 a f 41 047 b f 41 046 c f 41 045 d f 41 044 e f 41 043 f f 41 042 0 0 42 042 1 0 42 042 2 0 42 042 3 0 42 042 4 0 42 042 5 0 42 042 6 0 42 042 7 0 42 042 8 0 42 042 9 0 42 042 a 0 42 042 b 0 42 042 c 0 42 042 d 0 42 042 e 0 42 042 f 0 42 042 0 1 42 042 1 1 42 043 2 1 42 044 3 1 42 045 4 1 42 046 5 1 42 047 6 1 42 048 7 1 42 049 8 1 42 03a 9 1 42 03b a 1 42 03c b 1 42 03d c 1 42 03e d 1 42 03f e 1 42 040 f 1 42 041 0 2 42 042 1 2 42 044 2 2 42 046 3 2 42 048 4 2 42 04a 5 2 42 04c 6 2 42 04e 7 2 42 050 8 2 42 032 9 2 42 034 a 2 42 036 b 2 42 038 c 2 42 03a d 2 42 03c e 2 42 03e f 2 42 040 0 3 42 042 1 3 42 045 2 3 42 048 3 3 42 04b 4 3 42 04e 5 3 42 051 6 3 42 054 7 3 42 057 8 3 42 02a 9 3 42 02d a 3 42 030 b 3 42 033 c 3 42 036 d 3 42 039 e 3 42 03c f 3 42 03f 0 4 42 042 1 4 42 046 2 4 42 04a 3 4 42 04e 4 4 42 052 5 4 42 056 6 4 42 05a 7 4 42 05e 8 4 42 022 9 4 42 026 a 4 42 02a b 4 42 02e c 4 42 032 d 4 42 036 e 4 42 03a f 4 42 03e 0 5 42 042 1 5 42 047 2 5 42 04c 3 5 42 051 4 5 42 056 5 5 42 05b 6 5 42 060 7 5 42 065 8 5 42 01a 9 5 42 01f a 5 42 024 b 5 42 029 c 5 42 02e d 5 42 033 e 5 42 038 f 5 42 03d 0 6 42 042 1 6 42 048 2 6 42 04e 3 6 42 054 4 6 42 05a 5 6 42 060 6 6 42 066 7 6 42 06c 8 6 42 012 9 6 42 018 a 6 42 01e b 6 42 024 c 6 42 02a d 6 42 030 e 6 42 036 f 6 42 03c 0 7 42 042 1 7 42 049 2 7 42 050 3 7 42 057 4 7 42 05e 5 7 42 065 6 7 42 06c 7 7 42 073 8 7 42 00a 9 7 42 011 a 7 42 018 b 7 42 01f c 7 42 026 d 7 42 02d e 7 42 034 f 7 42 03b 0 8 42 042 1 8 42 03a 2 8 42 032 3 8 42 02a 4 8 42 022 5 8 42 01a 6 8 42 012 7 8 42 00a 8 8 42 082 9 8 42 07a a 8 42 072 b 8 42 06a c 8 42 062 d 8 42 05a e 8 42 052 f 8 42 04a 0 9 42 042 1 9 42 03b 2 9 42 034 3 9 42 02d 4 9 42 026 5 9 42 01f 6 9 42 018 7 9 42 011 8 9 42 07a 9 9 42 073 a 9 42 06c b 9 42 065 c 9 42 05e d 9 42 057 e 9 42 050 f 9 42 049 0 a 42 042 1 a 42 03c 2 a 42 036 3 a 42 030 4 a 42 02a 5 a 42 024 6 a 42 01e 7 a 42 018 8 a 42 072 9 a 42 06c a a 42 066 b a 42 060 c a 42 05a d a 42 054 e a 42 04e f a 42 048 0 b 42 042 1 b 42 03d 2 b 42 038 3 b 42 033 4 b 42 02e 5 b 42 029 6 b 42 024 7 b 42 01f 8 b 42 06a 9 b 42 065 a b 42 060 b b 42 05b c b 42 056 d b 42 051 e b 42 04c f b 42 047 0 c 42 042 1 c 42 03e 2 c 42 03a 3 c 42 036 4 c 42 032 5 c 42 02e 6 c 42 02a 7 c 42 026 8 c 42 062 9 c 42 05e a c 42 05a b c 42 056 c c 42 052 d c 42 04e e c 42 04a f c 42 046 0 d 42 042 1 d 42 03f 2 d 42 03c 3 d 42 039 4 d 42 036 5 d 42 033 6 d 42 030 7 d 42 02d 8 d 42 05a 9 d 42 057 a d 42 054 b d 42 051 c d 42 04e d d 42 04b e d 42 048 f d 42 045 0 e 42 042 1 e 42 040 2 e 42 03e 3 e 42 03c 4 e 42 03a 5 e 42 038 6 e 42 036 7 e 42 034 8 e 42 052 9 e 42 050 a e 42 04e b e 42 04c c e 42 04a d e 42 048 e e 42 046 f e 42 044 0 f 42 042 1 f 42 041 2 f 42 040 3 f 42 03f 4 f 42 03e 5 f 42 03d 6 f 42 03c 7 f 42 03b 8 f 42 04a 9 f 42 049 a f 42 048 b f 42 047 c f 42 046 d f 42 045 e f 42 044 f f 42 043 0 0 43 043 1 0 43 043 2 0 43 043 3 0 43 043 4 0 43 043 5 0 43 043 6 0 43 043 7 0 43 043 8 0 43 043 9 0 43 043 a 0 43 043 b 0 43 043 c 0 43 043 d 0 43 043 e 0 43 043 f 0 43 043 0 1 43 043 1 1 43 044 2 1 43 045 3 1 43 046 4 1 43 047 5 1 43 048 6 1 43 049 7 1 43 04a 8 1 43 03b 9 1 43 03c a 1 43 03d b 1 43 03e c 1 43 03f d 1 43 040 e 1 43 041 f 1 43 042 0 2 43 043 1 2 43 045 2 2 43 047 3 2 43 049 4 2 43 04b 5 2 43 04d 6 2 43 04f 7 2 43 051 8 2 43 033 9 2 43 035 a 2 43 037 b 2 43 039 c 2 43 03b d 2 43 03d e 2 43 03f f 2 43 041 0 3 43 043 1 3 43 046 2 3 43 049 3 3 43 04c 4 3 43 04f 5 3 43 052 6 3 43 055 7 3 43 058 8 3 43 02b 9 3 43 02e a 3 43 031 b 3 43 034 c 3 43 037 d 3 43 03a e 3 43 03d f 3 43 040 0 4 43 043 1 4 43 047 2 4 43 04b 3 4 43 04f 4 4 43 053 5 4 43 057 6 4 43 05b 7 4 43 05f 8 4 43 023 9 4 43 027 a 4 43 02b b 4 43 02f c 4 43 033 d 4 43 037 e 4 43 03b f 4 43 03f 0 5 43 043 1 5 43 048 2 5 43 04d 3 5 43 052 4 5 43 057 5 5 43 05c 6 5 43 061 7 5 43 066 8 5 43 01b 9 5 43 020 a 5 43 025 b 5 43 02a c 5 43 02f d 5 43 034 e 5 43 039 f 5 43 03e 0 6 43 043 1 6 43 049 2 6 43 04f 3 6 43 055 4 6 43 05b 5 6 43 061 6 6 43 067 7 6 43 06d 8 6 43 013 9 6 43 019 a 6 43 01f b 6 43 025 c 6 43 02b d 6 43 031 e 6 43 037 f 6 43 03d 0 7 43 043 1 7 43 04a 2 7 43 051 3 7 43 058 4 7 43 05f 5 7 43 066 6 7 43 06d 7 7 43 074 8 7 43 00b 9 7 43 012 a 7 43 019 b 7 43 020 c 7 43 027 d 7 43 02e e 7 43 035 f 7 43 03c 0 8 43 043 1 8 43 03b 2 8 43 033 3 8 43 02b 4 8 43 023 5 8 43 01b 6 8 43 013 7 8 43 00b 8 8 43 083 9 8 43 07b a 8 43 073 b 8 43 06b c 8 43 063 d 8 43 05b e 8 43 053 f 8 43 04b 0 9 43 043 1 9 43 03c 2 9 43 035 3 9 43 02e 4 9 43 027 5 9 43 020 6 9 43 019 7 9 43 012 8 9 43 07b 9 9 43 074 a 9 43 06d b 9 43 066 c 9 43 05f d 9 43 058 e 9 43 051 f 9 43 04a 0 a 43 043 1 a 43 03d 2 a 43 037 3 a 43 031 4 a 43 02b 5 a 43 025 6 a 43 01f 7 a 43 019 8 a 43 073 9 a 43 06d a a 43 067 b a 43 061 c a 43 05b d a 43 055 e a 43 04f f a 43 049 0 b 43 043 1 b 43 03e 2 b 43 039 3 b 43 034 4 b 43 02f 5 b 43 02a 6 b 43 025 7 b 43 020 8 b 43 06b 9 b 43 066 a b 43 061 b b 43 05c c b 43 057 d b 43 052 e b 43 04d f b 43 048 0 c 43 043 1 c 43 03f 2 c 43 03b 3 c 43 037 4 c 43 033 5 c 43 02f 6 c 43 02b 7 c 43 027 8 c 43 063 9 c 43 05f a c 43 05b b c 43 057 c c 43 053 d c 43 04f e c 43 04b f c 43 047 0 d 43 043 1 d 43 040 2 d 43 03d 3 d 43 03a 4 d 43 037 5 d 43 034 6 d 43 031 7 d 43 02e 8 d 43 05b 9 d 43 058 a d 43 055 b d 43 052 c d 43 04f d d 43 04c e d 43 049 f d 43 046 0 e 43 043 1 e 43 041 2 e 43 03f 3 e 43 03d 4 e 43 03b 5 e 43 039 6 e 43 037 7 e 43 035 8 e 43 053 9 e 43 051 a e 43 04f b e 43 04d c e 43 04b d e 43 049 e e 43 047 f e 43 045 0 f 43 043 1 f 43 042 2 f 43 041 3 f 43 040 4 f 43 03f 5 f 43 03e 6 f 43 03d 7 f 43 03c 8 f 43 04b 9 f 43 04a a f 43 049 b f 43 048 c f 43 047 d f 43 046 e f 43 045 f f 43 044 0 0 44 044 1 0 44 044 2 0 44 044 3 0 44 044 4 0 44 044 5 0 44 044 6 0 44 044 7 0 44 044 8 0 44 044 9 0 44 044 a 0 44 044 b 0 44 044 c 0 44 044 d 0 44 044 e 0 44 044 f 0 44 044 0 1 44 044 1 1 44 045 2 1 44 046 3 1 44 047 4 1 44 048 5 1 44 049 6 1 44 04a 7 1 44 04b 8 1 44 03c 9 1 44 03d a 1 44 03e b 1 44 03f c 1 44 040 d 1 44 041 e 1 44 042 f 1 44 043 0 2 44 044 1 2 44 046 2 2 44 048 3 2 44 04a 4 2 44 04c 5 2 44 04e 6 2 44 050 7 2 44 052 8 2 44 034 9 2 44 036 a 2 44 038 b 2 44 03a c 2 44 03c d 2 44 03e e 2 44 040 f 2 44 042 0 3 44 044 1 3 44 047 2 3 44 04a 3 3 44 04d 4 3 44 050 5 3 44 053 6 3 44 056 7 3 44 059 8 3 44 02c 9 3 44 02f a 3 44 032 b 3 44 035 c 3 44 038 d 3 44 03b e 3 44 03e f 3 44 041 0 4 44 044 1 4 44 048 2 4 44 04c 3 4 44 050 4 4 44 054 5 4 44 058 6 4 44 05c 7 4 44 060 8 4 44 024 9 4 44 028 a 4 44 02c b 4 44 030 c 4 44 034 d 4 44 038 e 4 44 03c f 4 44 040 0 5 44 044 1 5 44 049 2 5 44 04e 3 5 44 053 4 5 44 058 5 5 44 05d 6 5 44 062 7 5 44 067 8 5 44 01c 9 5 44 021 a 5 44 026 b 5 44 02b c 5 44 030 d 5 44 035 e 5 44 03a f 5 44 03f 0 6 44 044 1 6 44 04a 2 6 44 050 3 6 44 056 4 6 44 05c 5 6 44 062 6 6 44 068 7 6 44 06e 8 6 44 014 9 6 44 01a a 6 44 020 b 6 44 026 c 6 44 02c d 6 44 032 e 6 44 038 f 6 44 03e 0 7 44 044 1 7 44 04b 2 7 44 052 3 7 44 059 4 7 44 060 5 7 44 067 6 7 44 06e 7 7 44 075 8 7 44 00c 9 7 44 013 a 7 44 01a b 7 44 021 c 7 44 028 d 7 44 02f e 7 44 036 f 7 44 03d 0 8 44 044 1 8 44 03c 2 8 44 034 3 8 44 02c 4 8 44 024 5 8 44 01c 6 8 44 014 7 8 44 00c 8 8 44 084 9 8 44 07c a 8 44 074 b 8 44 06c c 8 44 064 d 8 44 05c e 8 44 054 f 8 44 04c 0 9 44 044 1 9 44 03d 2 9 44 036 3 9 44 02f 4 9 44 028 5 9 44 021 6 9 44 01a 7 9 44 013 8 9 44 07c 9 9 44 075 a 9 44 06e b 9 44 067 c 9 44 060 d 9 44 059 e 9 44 052 f 9 44 04b 0 a 44 044 1 a 44 03e 2 a 44 038 3 a 44 032 4 a 44 02c 5 a 44 026 6 a 44 020 7 a 44 01a 8 a 44 074 9 a 44 06e a a 44 068 b a 44 062 c a 44 05c d a 44 056 e a 44 050 f a 44 04a 0 b 44 044 1 b 44 03f 2 b 44 03a 3 b 44 035 4 b 44 030 5 b 44 02b 6 b 44 026 7 b 44 021 8 b 44 06c 9 b 44 067 a b 44 062 b b 44 05d c b 44 058 d b 44 053 e b 44 04e f b 44 049 0 c 44 044 1 c 44 040 2 c 44 03c 3 c 44 038 4 c 44 034 5 c 44 030 6 c 44 02c 7 c 44 028 8 c 44 064 9 c 44 060 a c 44 05c b c 44 058 c c 44 054 d c 44 050 e c 44 04c f c 44 048 0 d 44 044 1 d 44 041 2 d 44 03e 3 d 44 03b 4 d 44 038 5 d 44 035 6 d 44 032 7 d 44 02f 8 d 44 05c 9 d 44 059 a d 44 056 b d 44 053 c d 44 050 d d 44 04d e d 44 04a f d 44 047 0 e 44 044 1 e 44 042 2 e 44 040 3 e 44 03e 4 e 44 03c 5 e 44 03a 6 e 44 038 7 e 44 036 8 e 44 054 9 e 44 052 a e 44 050 b e 44 04e c e 44 04c d e 44 04a e e 44 048 f e 44 046 0 f 44 044 1 f 44 043 2 f 44 042 3 f 44 041 4 f 44 040 5 f 44 03f 6 f 44 03e 7 f 44 03d 8 f 44 04c 9 f 44 04b a f 44 04a b f 44 049 c f 44 048 d f 44 047 e f 44 046 f f 44 045 0 0 45 045 1 0 45 045 2 0 45 045 3 0 45 045 4 0 45 045 5 0 45 045 6 0 45 045 7 0 45 045 8 0 45 045 9 0 45 045 a 0 45 045 b 0 45 045 c 0 45 045 d 0 45 045 e 0 45 045 f 0 45 045 0 1 45 045 1 1 45 046 2 1 45 047 3 1 45 048 4 1 45 049 5 1 45 04a 6 1 45 04b 7 1 45 04c 8 1 45 03d 9 1 45 03e a 1 45 03f b 1 45 040 c 1 45 041 d 1 45 042 e 1 45 043 f 1 45 044 0 2 45 045 1 2 45 047 2 2 45 049 3 2 45 04b 4 2 45 04d 5 2 45 04f 6 2 45 051 7 2 45 053 8 2 45 035 9 2 45 037 a 2 45 039 b 2 45 03b c 2 45 03d d 2 45 03f e 2 45 041 f 2 45 043 0 3 45 045 1 3 45 048 2 3 45 04b 3 3 45 04e 4 3 45 051 5 3 45 054 6 3 45 057 7 3 45 05a 8 3 45 02d 9 3 45 030 a 3 45 033 b 3 45 036 c 3 45 039 d 3 45 03c e 3 45 03f f 3 45 042 0 4 45 045 1 4 45 049 2 4 45 04d 3 4 45 051 4 4 45 055 5 4 45 059 6 4 45 05d 7 4 45 061 8 4 45 025 9 4 45 029 a 4 45 02d b 4 45 031 c 4 45 035 d 4 45 039 e 4 45 03d f 4 45 041 0 5 45 045 1 5 45 04a 2 5 45 04f 3 5 45 054 4 5 45 059 5 5 45 05e 6 5 45 063 7 5 45 068 8 5 45 01d 9 5 45 022 a 5 45 027 b 5 45 02c c 5 45 031 d 5 45 036 e 5 45 03b f 5 45 040 0 6 45 045 1 6 45 04b 2 6 45 051 3 6 45 057 4 6 45 05d 5 6 45 063 6 6 45 069 7 6 45 06f 8 6 45 015 9 6 45 01b a 6 45 021 b 6 45 027 c 6 45 02d d 6 45 033 e 6 45 039 f 6 45 03f 0 7 45 045 1 7 45 04c 2 7 45 053 3 7 45 05a 4 7 45 061 5 7 45 068 6 7 45 06f 7 7 45 076 8 7 45 00d 9 7 45 014 a 7 45 01b b 7 45 022 c 7 45 029 d 7 45 030 e 7 45 037 f 7 45 03e 0 8 45 045 1 8 45 03d 2 8 45 035 3 8 45 02d 4 8 45 025 5 8 45 01d 6 8 45 015 7 8 45 00d 8 8 45 085 9 8 45 07d a 8 45 075 b 8 45 06d c 8 45 065 d 8 45 05d e 8 45 055 f 8 45 04d 0 9 45 045 1 9 45 03e 2 9 45 037 3 9 45 030 4 9 45 029 5 9 45 022 6 9 45 01b 7 9 45 014 8 9 45 07d 9 9 45 076 a 9 45 06f b 9 45 068 c 9 45 061 d 9 45 05a e 9 45 053 f 9 45 04c 0 a 45 045 1 a 45 03f 2 a 45 039 3 a 45 033 4 a 45 02d 5 a 45 027 6 a 45 021 7 a 45 01b 8 a 45 075 9 a 45 06f a a 45 069 b a 45 063 c a 45 05d d a 45 057 e a 45 051 f a 45 04b 0 b 45 045 1 b 45 040 2 b 45 03b 3 b 45 036 4 b 45 031 5 b 45 02c 6 b 45 027 7 b 45 022 8 b 45 06d 9 b 45 068 a b 45 063 b b 45 05e c b 45 059 d b 45 054 e b 45 04f f b 45 04a 0 c 45 045 1 c 45 041 2 c 45 03d 3 c 45 039 4 c 45 035 5 c 45 031 6 c 45 02d 7 c 45 029 8 c 45 065 9 c 45 061 a c 45 05d b c 45 059 c c 45 055 d c 45 051 e c 45 04d f c 45 049 0 d 45 045 1 d 45 042 2 d 45 03f 3 d 45 03c 4 d 45 039 5 d 45 036 6 d 45 033 7 d 45 030 8 d 45 05d 9 d 45 05a a d 45 057 b d 45 054 c d 45 051 d d 45 04e e d 45 04b f d 45 048 0 e 45 045 1 e 45 043 2 e 45 041 3 e 45 03f 4 e 45 03d 5 e 45 03b 6 e 45 039 7 e 45 037 8 e 45 055 9 e 45 053 a e 45 051 b e 45 04f c e 45 04d d e 45 04b e e 45 049 f e 45 047 0 f 45 045 1 f 45 044 2 f 45 043 3 f 45 042 4 f 45 041 5 f 45 040 6 f 45 03f 7 f 45 03e 8 f 45 04d 9 f 45 04c a f 45 04b b f 45 04a c f 45 049 d f 45 048 e f 45 047 f f 45 046 0 0 46 046 1 0 46 046 2 0 46 046 3 0 46 046 4 0 46 046 5 0 46 046 6 0 46 046 7 0 46 046 8 0 46 046 9 0 46 046 a 0 46 046 b 0 46 046 c 0 46 046 d 0 46 046 e 0 46 046 f 0 46 046 0 1 46 046 1 1 46 047 2 1 46 048 3 1 46 049 4 1 46 04a 5 1 46 04b 6 1 46 04c 7 1 46 04d 8 1 46 03e 9 1 46 03f a 1 46 040 b 1 46 041 c 1 46 042 d 1 46 043 e 1 46 044 f 1 46 045 0 2 46 046 1 2 46 048 2 2 46 04a 3 2 46 04c 4 2 46 04e 5 2 46 050 6 2 46 052 7 2 46 054 8 2 46 036 9 2 46 038 a 2 46 03a b 2 46 03c c 2 46 03e d 2 46 040 e 2 46 042 f 2 46 044 0 3 46 046 1 3 46 049 2 3 46 04c 3 3 46 04f 4 3 46 052 5 3 46 055 6 3 46 058 7 3 46 05b 8 3 46 02e 9 3 46 031 a 3 46 034 b 3 46 037 c 3 46 03a d 3 46 03d e 3 46 040 f 3 46 043 0 4 46 046 1 4 46 04a 2 4 46 04e 3 4 46 052 4 4 46 056 5 4 46 05a 6 4 46 05e 7 4 46 062 8 4 46 026 9 4 46 02a a 4 46 02e b 4 46 032 c 4 46 036 d 4 46 03a e 4 46 03e f 4 46 042 0 5 46 046 1 5 46 04b 2 5 46 050 3 5 46 055 4 5 46 05a 5 5 46 05f 6 5 46 064 7 5 46 069 8 5 46 01e 9 5 46 023 a 5 46 028 b 5 46 02d c 5 46 032 d 5 46 037 e 5 46 03c f 5 46 041 0 6 46 046 1 6 46 04c 2 6 46 052 3 6 46 058 4 6 46 05e 5 6 46 064 6 6 46 06a 7 6 46 070 8 6 46 016 9 6 46 01c a 6 46 022 b 6 46 028 c 6 46 02e d 6 46 034 e 6 46 03a f 6 46 040 0 7 46 046 1 7 46 04d 2 7 46 054 3 7 46 05b 4 7 46 062 5 7 46 069 6 7 46 070 7 7 46 077 8 7 46 00e 9 7 46 015 a 7 46 01c b 7 46 023 c 7 46 02a d 7 46 031 e 7 46 038 f 7 46 03f 0 8 46 046 1 8 46 03e 2 8 46 036 3 8 46 02e 4 8 46 026 5 8 46 01e 6 8 46 016 7 8 46 00e 8 8 46 086 9 8 46 07e a 8 46 076 b 8 46 06e c 8 46 066 d 8 46 05e e 8 46 056 f 8 46 04e 0 9 46 046 1 9 46 03f 2 9 46 038 3 9 46 031 4 9 46 02a 5 9 46 023 6 9 46 01c 7 9 46 015 8 9 46 07e 9 9 46 077 a 9 46 070 b 9 46 069 c 9 46 062 d 9 46 05b e 9 46 054 f 9 46 04d 0 a 46 046 1 a 46 040 2 a 46 03a 3 a 46 034 4 a 46 02e 5 a 46 028 6 a 46 022 7 a 46 01c 8 a 46 076 9 a 46 070 a a 46 06a b a 46 064 c a 46 05e d a 46 058 e a 46 052 f a 46 04c 0 b 46 046 1 b 46 041 2 b 46 03c 3 b 46 037 4 b 46 032 5 b 46 02d 6 b 46 028 7 b 46 023 8 b 46 06e 9 b 46 069 a b 46 064 b b 46 05f c b 46 05a d b 46 055 e b 46 050 f b 46 04b 0 c 46 046 1 c 46 042 2 c 46 03e 3 c 46 03a 4 c 46 036 5 c 46 032 6 c 46 02e 7 c 46 02a 8 c 46 066 9 c 46 062 a c 46 05e b c 46 05a c c 46 056 d c 46 052 e c 46 04e f c 46 04a 0 d 46 046 1 d 46 043 2 d 46 040 3 d 46 03d 4 d 46 03a 5 d 46 037 6 d 46 034 7 d 46 031 8 d 46 05e 9 d 46 05b a d 46 058 b d 46 055 c d 46 052 d d 46 04f e d 46 04c f d 46 049 0 e 46 046 1 e 46 044 2 e 46 042 3 e 46 040 4 e 46 03e 5 e 46 03c 6 e 46 03a 7 e 46 038 8 e 46 056 9 e 46 054 a e 46 052 b e 46 050 c e 46 04e d e 46 04c e e 46 04a f e 46 048 0 f 46 046 1 f 46 045 2 f 46 044 3 f 46 043 4 f 46 042 5 f 46 041 6 f 46 040 7 f 46 03f 8 f 46 04e 9 f 46 04d a f 46 04c b f 46 04b c f 46 04a d f 46 049 e f 46 048 f f 46 047 0 0 47 047 1 0 47 047 2 0 47 047 3 0 47 047 4 0 47 047 5 0 47 047 6 0 47 047 7 0 47 047 8 0 47 047 9 0 47 047 a 0 47 047 b 0 47 047 c 0 47 047 d 0 47 047 e 0 47 047 f 0 47 047 0 1 47 047 1 1 47 048 2 1 47 049 3 1 47 04a 4 1 47 04b 5 1 47 04c 6 1 47 04d 7 1 47 04e 8 1 47 03f 9 1 47 040 a 1 47 041 b 1 47 042 c 1 47 043 d 1 47 044 e 1 47 045 f 1 47 046 0 2 47 047 1 2 47 049 2 2 47 04b 3 2 47 04d 4 2 47 04f 5 2 47 051 6 2 47 053 7 2 47 055 8 2 47 037 9 2 47 039 a 2 47 03b b 2 47 03d c 2 47 03f d 2 47 041 e 2 47 043 f 2 47 045 0 3 47 047 1 3 47 04a 2 3 47 04d 3 3 47 050 4 3 47 053 5 3 47 056 6 3 47 059 7 3 47 05c 8 3 47 02f 9 3 47 032 a 3 47 035 b 3 47 038 c 3 47 03b d 3 47 03e e 3 47 041 f 3 47 044 0 4 47 047 1 4 47 04b 2 4 47 04f 3 4 47 053 4 4 47 057 5 4 47 05b 6 4 47 05f 7 4 47 063 8 4 47 027 9 4 47 02b a 4 47 02f b 4 47 033 c 4 47 037 d 4 47 03b e 4 47 03f f 4 47 043 0 5 47 047 1 5 47 04c 2 5 47 051 3 5 47 056 4 5 47 05b 5 5 47 060 6 5 47 065 7 5 47 06a 8 5 47 01f 9 5 47 024 a 5 47 029 b 5 47 02e c 5 47 033 d 5 47 038 e 5 47 03d f 5 47 042 0 6 47 047 1 6 47 04d 2 6 47 053 3 6 47 059 4 6 47 05f 5 6 47 065 6 6 47 06b 7 6 47 071 8 6 47 017 9 6 47 01d a 6 47 023 b 6 47 029 c 6 47 02f d 6 47 035 e 6 47 03b f 6 47 041 0 7 47 047 1 7 47 04e 2 7 47 055 3 7 47 05c 4 7 47 063 5 7 47 06a 6 7 47 071 7 7 47 078 8 7 47 00f 9 7 47 016 a 7 47 01d b 7 47 024 c 7 47 02b d 7 47 032 e 7 47 039 f 7 47 040 0 8 47 047 1 8 47 03f 2 8 47 037 3 8 47 02f 4 8 47 027 5 8 47 01f 6 8 47 017 7 8 47 00f 8 8 47 087 9 8 47 07f a 8 47 077 b 8 47 06f c 8 47 067 d 8 47 05f e 8 47 057 f 8 47 04f 0 9 47 047 1 9 47 040 2 9 47 039 3 9 47 032 4 9 47 02b 5 9 47 024 6 9 47 01d 7 9 47 016 8 9 47 07f 9 9 47 078 a 9 47 071 b 9 47 06a c 9 47 063 d 9 47 05c e 9 47 055 f 9 47 04e 0 a 47 047 1 a 47 041 2 a 47 03b 3 a 47 035 4 a 47 02f 5 a 47 029 6 a 47 023 7 a 47 01d 8 a 47 077 9 a 47 071 a a 47 06b b a 47 065 c a 47 05f d a 47 059 e a 47 053 f a 47 04d 0 b 47 047 1 b 47 042 2 b 47 03d 3 b 47 038 4 b 47 033 5 b 47 02e 6 b 47 029 7 b 47 024 8 b 47 06f 9 b 47 06a a b 47 065 b b 47 060 c b 47 05b d b 47 056 e b 47 051 f b 47 04c 0 c 47 047 1 c 47 043 2 c 47 03f 3 c 47 03b 4 c 47 037 5 c 47 033 6 c 47 02f 7 c 47 02b 8 c 47 067 9 c 47 063 a c 47 05f b c 47 05b c c 47 057 d c 47 053 e c 47 04f f c 47 04b 0 d 47 047 1 d 47 044 2 d 47 041 3 d 47 03e 4 d 47 03b 5 d 47 038 6 d 47 035 7 d 47 032 8 d 47 05f 9 d 47 05c a d 47 059 b d 47 056 c d 47 053 d d 47 050 e d 47 04d f d 47 04a 0 e 47 047 1 e 47 045 2 e 47 043 3 e 47 041 4 e 47 03f 5 e 47 03d 6 e 47 03b 7 e 47 039 8 e 47 057 9 e 47 055 a e 47 053 b e 47 051 c e 47 04f d e 47 04d e e 47 04b f e 47 049 0 f 47 047 1 f 47 046 2 f 47 045 3 f 47 044 4 f 47 043 5 f 47 042 6 f 47 041 7 f 47 040 8 f 47 04f 9 f 47 04e a f 47 04d b f 47 04c c f 47 04b d f 47 04a e f 47 049 f f 47 048 0 0 48 048 1 0 48 048 2 0 48 048 3 0 48 048 4 0 48 048 5 0 48 048 6 0 48 048 7 0 48 048 8 0 48 048 9 0 48 048 a 0 48 048 b 0 48 048 c 0 48 048 d 0 48 048 e 0 48 048 f 0 48 048 0 1 48 048 1 1 48 049 2 1 48 04a 3 1 48 04b 4 1 48 04c 5 1 48 04d 6 1 48 04e 7 1 48 04f 8 1 48 040 9 1 48 041 a 1 48 042 b 1 48 043 c 1 48 044 d 1 48 045 e 1 48 046 f 1 48 047 0 2 48 048 1 2 48 04a 2 2 48 04c 3 2 48 04e 4 2 48 050 5 2 48 052 6 2 48 054 7 2 48 056 8 2 48 038 9 2 48 03a a 2 48 03c b 2 48 03e c 2 48 040 d 2 48 042 e 2 48 044 f 2 48 046 0 3 48 048 1 3 48 04b 2 3 48 04e 3 3 48 051 4 3 48 054 5 3 48 057 6 3 48 05a 7 3 48 05d 8 3 48 030 9 3 48 033 a 3 48 036 b 3 48 039 c 3 48 03c d 3 48 03f e 3 48 042 f 3 48 045 0 4 48 048 1 4 48 04c 2 4 48 050 3 4 48 054 4 4 48 058 5 4 48 05c 6 4 48 060 7 4 48 064 8 4 48 028 9 4 48 02c a 4 48 030 b 4 48 034 c 4 48 038 d 4 48 03c e 4 48 040 f 4 48 044 0 5 48 048 1 5 48 04d 2 5 48 052 3 5 48 057 4 5 48 05c 5 5 48 061 6 5 48 066 7 5 48 06b 8 5 48 020 9 5 48 025 a 5 48 02a b 5 48 02f c 5 48 034 d 5 48 039 e 5 48 03e f 5 48 043 0 6 48 048 1 6 48 04e 2 6 48 054 3 6 48 05a 4 6 48 060 5 6 48 066 6 6 48 06c 7 6 48 072 8 6 48 018 9 6 48 01e a 6 48 024 b 6 48 02a c 6 48 030 d 6 48 036 e 6 48 03c f 6 48 042 0 7 48 048 1 7 48 04f 2 7 48 056 3 7 48 05d 4 7 48 064 5 7 48 06b 6 7 48 072 7 7 48 079 8 7 48 010 9 7 48 017 a 7 48 01e b 7 48 025 c 7 48 02c d 7 48 033 e 7 48 03a f 7 48 041 0 8 48 048 1 8 48 040 2 8 48 038 3 8 48 030 4 8 48 028 5 8 48 020 6 8 48 018 7 8 48 010 8 8 48 088 9 8 48 080 a 8 48 078 b 8 48 070 c 8 48 068 d 8 48 060 e 8 48 058 f 8 48 050 0 9 48 048 1 9 48 041 2 9 48 03a 3 9 48 033 4 9 48 02c 5 9 48 025 6 9 48 01e 7 9 48 017 8 9 48 080 9 9 48 079 a 9 48 072 b 9 48 06b c 9 48 064 d 9 48 05d e 9 48 056 f 9 48 04f 0 a 48 048 1 a 48 042 2 a 48 03c 3 a 48 036 4 a 48 030 5 a 48 02a 6 a 48 024 7 a 48 01e 8 a 48 078 9 a 48 072 a a 48 06c b a 48 066 c a 48 060 d a 48 05a e a 48 054 f a 48 04e 0 b 48 048 1 b 48 043 2 b 48 03e 3 b 48 039 4 b 48 034 5 b 48 02f 6 b 48 02a 7 b 48 025 8 b 48 070 9 b 48 06b a b 48 066 b b 48 061 c b 48 05c d b 48 057 e b 48 052 f b 48 04d 0 c 48 048 1 c 48 044 2 c 48 040 3 c 48 03c 4 c 48 038 5 c 48 034 6 c 48 030 7 c 48 02c 8 c 48 068 9 c 48 064 a c 48 060 b c 48 05c c c 48 058 d c 48 054 e c 48 050 f c 48 04c 0 d 48 048 1 d 48 045 2 d 48 042 3 d 48 03f 4 d 48 03c 5 d 48 039 6 d 48 036 7 d 48 033 8 d 48 060 9 d 48 05d a d 48 05a b d 48 057 c d 48 054 d d 48 051 e d 48 04e f d 48 04b 0 e 48 048 1 e 48 046 2 e 48 044 3 e 48 042 4 e 48 040 5 e 48 03e 6 e 48 03c 7 e 48 03a 8 e 48 058 9 e 48 056 a e 48 054 b e 48 052 c e 48 050 d e 48 04e e e 48 04c f e 48 04a 0 f 48 048 1 f 48 047 2 f 48 046 3 f 48 045 4 f 48 044 5 f 48 043 6 f 48 042 7 f 48 041 8 f 48 050 9 f 48 04f a f 48 04e b f 48 04d c f 48 04c d f 48 04b e f 48 04a f f 48 049 0 0 49 049 1 0 49 049 2 0 49 049 3 0 49 049 4 0 49 049 5 0 49 049 6 0 49 049 7 0 49 049 8 0 49 049 9 0 49 049 a 0 49 049 b 0 49 049 c 0 49 049 d 0 49 049 e 0 49 049 f 0 49 049 0 1 49 049 1 1 49 04a 2 1 49 04b 3 1 49 04c 4 1 49 04d 5 1 49 04e 6 1 49 04f 7 1 49 050 8 1 49 041 9 1 49 042 a 1 49 043 b 1 49 044 c 1 49 045 d 1 49 046 e 1 49 047 f 1 49 048 0 2 49 049 1 2 49 04b 2 2 49 04d 3 2 49 04f 4 2 49 051 5 2 49 053 6 2 49 055 7 2 49 057 8 2 49 039 9 2 49 03b a 2 49 03d b 2 49 03f c 2 49 041 d 2 49 043 e 2 49 045 f 2 49 047 0 3 49 049 1 3 49 04c 2 3 49 04f 3 3 49 052 4 3 49 055 5 3 49 058 6 3 49 05b 7 3 49 05e 8 3 49 031 9 3 49 034 a 3 49 037 b 3 49 03a c 3 49 03d d 3 49 040 e 3 49 043 f 3 49 046 0 4 49 049 1 4 49 04d 2 4 49 051 3 4 49 055 4 4 49 059 5 4 49 05d 6 4 49 061 7 4 49 065 8 4 49 029 9 4 49 02d a 4 49 031 b 4 49 035 c 4 49 039 d 4 49 03d e 4 49 041 f 4 49 045 0 5 49 049 1 5 49 04e 2 5 49 053 3 5 49 058 4 5 49 05d 5 5 49 062 6 5 49 067 7 5 49 06c 8 5 49 021 9 5 49 026 a 5 49 02b b 5 49 030 c 5 49 035 d 5 49 03a e 5 49 03f f 5 49 044 0 6 49 049 1 6 49 04f 2 6 49 055 3 6 49 05b 4 6 49 061 5 6 49 067 6 6 49 06d 7 6 49 073 8 6 49 019 9 6 49 01f a 6 49 025 b 6 49 02b c 6 49 031 d 6 49 037 e 6 49 03d f 6 49 043 0 7 49 049 1 7 49 050 2 7 49 057 3 7 49 05e 4 7 49 065 5 7 49 06c 6 7 49 073 7 7 49 07a 8 7 49 011 9 7 49 018 a 7 49 01f b 7 49 026 c 7 49 02d d 7 49 034 e 7 49 03b f 7 49 042 0 8 49 049 1 8 49 041 2 8 49 039 3 8 49 031 4 8 49 029 5 8 49 021 6 8 49 019 7 8 49 011 8 8 49 089 9 8 49 081 a 8 49 079 b 8 49 071 c 8 49 069 d 8 49 061 e 8 49 059 f 8 49 051 0 9 49 049 1 9 49 042 2 9 49 03b 3 9 49 034 4 9 49 02d 5 9 49 026 6 9 49 01f 7 9 49 018 8 9 49 081 9 9 49 07a a 9 49 073 b 9 49 06c c 9 49 065 d 9 49 05e e 9 49 057 f 9 49 050 0 a 49 049 1 a 49 043 2 a 49 03d 3 a 49 037 4 a 49 031 5 a 49 02b 6 a 49 025 7 a 49 01f 8 a 49 079 9 a 49 073 a a 49 06d b a 49 067 c a 49 061 d a 49 05b e a 49 055 f a 49 04f 0 b 49 049 1 b 49 044 2 b 49 03f 3 b 49 03a 4 b 49 035 5 b 49 030 6 b 49 02b 7 b 49 026 8 b 49 071 9 b 49 06c a b 49 067 b b 49 062 c b 49 05d d b 49 058 e b 49 053 f b 49 04e 0 c 49 049 1 c 49 045 2 c 49 041 3 c 49 03d 4 c 49 039 5 c 49 035 6 c 49 031 7 c 49 02d 8 c 49 069 9 c 49 065 a c 49 061 b c 49 05d c c 49 059 d c 49 055 e c 49 051 f c 49 04d 0 d 49 049 1 d 49 046 2 d 49 043 3 d 49 040 4 d 49 03d 5 d 49 03a 6 d 49 037 7 d 49 034 8 d 49 061 9 d 49 05e a d 49 05b b d 49 058 c d 49 055 d d 49 052 e d 49 04f f d 49 04c 0 e 49 049 1 e 49 047 2 e 49 045 3 e 49 043 4 e 49 041 5 e 49 03f 6 e 49 03d 7 e 49 03b 8 e 49 059 9 e 49 057 a e 49 055 b e 49 053 c e 49 051 d e 49 04f e e 49 04d f e 49 04b 0 f 49 049 1 f 49 048 2 f 49 047 3 f 49 046 4 f 49 045 5 f 49 044 6 f 49 043 7 f 49 042 8 f 49 051 9 f 49 050 a f 49 04f b f 49 04e c f 49 04d d f 49 04c e f 49 04b f f 49 04a 0 0 4a 04a 1 0 4a 04a 2 0 4a 04a 3 0 4a 04a 4 0 4a 04a 5 0 4a 04a 6 0 4a 04a 7 0 4a 04a 8 0 4a 04a 9 0 4a 04a a 0 4a 04a b 0 4a 04a c 0 4a 04a d 0 4a 04a e 0 4a 04a f 0 4a 04a 0 1 4a 04a 1 1 4a 04b 2 1 4a 04c 3 1 4a 04d 4 1 4a 04e 5 1 4a 04f 6 1 4a 050 7 1 4a 051 8 1 4a 042 9 1 4a 043 a 1 4a 044 b 1 4a 045 c 1 4a 046 d 1 4a 047 e 1 4a 048 f 1 4a 049 0 2 4a 04a 1 2 4a 04c 2 2 4a 04e 3 2 4a 050 4 2 4a 052 5 2 4a 054 6 2 4a 056 7 2 4a 058 8 2 4a 03a 9 2 4a 03c a 2 4a 03e b 2 4a 040 c 2 4a 042 d 2 4a 044 e 2 4a 046 f 2 4a 048 0 3 4a 04a 1 3 4a 04d 2 3 4a 050 3 3 4a 053 4 3 4a 056 5 3 4a 059 6 3 4a 05c 7 3 4a 05f 8 3 4a 032 9 3 4a 035 a 3 4a 038 b 3 4a 03b c 3 4a 03e d 3 4a 041 e 3 4a 044 f 3 4a 047 0 4 4a 04a 1 4 4a 04e 2 4 4a 052 3 4 4a 056 4 4 4a 05a 5 4 4a 05e 6 4 4a 062 7 4 4a 066 8 4 4a 02a 9 4 4a 02e a 4 4a 032 b 4 4a 036 c 4 4a 03a d 4 4a 03e e 4 4a 042 f 4 4a 046 0 5 4a 04a 1 5 4a 04f 2 5 4a 054 3 5 4a 059 4 5 4a 05e 5 5 4a 063 6 5 4a 068 7 5 4a 06d 8 5 4a 022 9 5 4a 027 a 5 4a 02c b 5 4a 031 c 5 4a 036 d 5 4a 03b e 5 4a 040 f 5 4a 045 0 6 4a 04a 1 6 4a 050 2 6 4a 056 3 6 4a 05c 4 6 4a 062 5 6 4a 068 6 6 4a 06e 7 6 4a 074 8 6 4a 01a 9 6 4a 020 a 6 4a 026 b 6 4a 02c c 6 4a 032 d 6 4a 038 e 6 4a 03e f 6 4a 044 0 7 4a 04a 1 7 4a 051 2 7 4a 058 3 7 4a 05f 4 7 4a 066 5 7 4a 06d 6 7 4a 074 7 7 4a 07b 8 7 4a 012 9 7 4a 019 a 7 4a 020 b 7 4a 027 c 7 4a 02e d 7 4a 035 e 7 4a 03c f 7 4a 043 0 8 4a 04a 1 8 4a 042 2 8 4a 03a 3 8 4a 032 4 8 4a 02a 5 8 4a 022 6 8 4a 01a 7 8 4a 012 8 8 4a 08a 9 8 4a 082 a 8 4a 07a b 8 4a 072 c 8 4a 06a d 8 4a 062 e 8 4a 05a f 8 4a 052 0 9 4a 04a 1 9 4a 043 2 9 4a 03c 3 9 4a 035 4 9 4a 02e 5 9 4a 027 6 9 4a 020 7 9 4a 019 8 9 4a 082 9 9 4a 07b a 9 4a 074 b 9 4a 06d c 9 4a 066 d 9 4a 05f e 9 4a 058 f 9 4a 051 0 a 4a 04a 1 a 4a 044 2 a 4a 03e 3 a 4a 038 4 a 4a 032 5 a 4a 02c 6 a 4a 026 7 a 4a 020 8 a 4a 07a 9 a 4a 074 a a 4a 06e b a 4a 068 c a 4a 062 d a 4a 05c e a 4a 056 f a 4a 050 0 b 4a 04a 1 b 4a 045 2 b 4a 040 3 b 4a 03b 4 b 4a 036 5 b 4a 031 6 b 4a 02c 7 b 4a 027 8 b 4a 072 9 b 4a 06d a b 4a 068 b b 4a 063 c b 4a 05e d b 4a 059 e b 4a 054 f b 4a 04f 0 c 4a 04a 1 c 4a 046 2 c 4a 042 3 c 4a 03e 4 c 4a 03a 5 c 4a 036 6 c 4a 032 7 c 4a 02e 8 c 4a 06a 9 c 4a 066 a c 4a 062 b c 4a 05e c c 4a 05a d c 4a 056 e c 4a 052 f c 4a 04e 0 d 4a 04a 1 d 4a 047 2 d 4a 044 3 d 4a 041 4 d 4a 03e 5 d 4a 03b 6 d 4a 038 7 d 4a 035 8 d 4a 062 9 d 4a 05f a d 4a 05c b d 4a 059 c d 4a 056 d d 4a 053 e d 4a 050 f d 4a 04d 0 e 4a 04a 1 e 4a 048 2 e 4a 046 3 e 4a 044 4 e 4a 042 5 e 4a 040 6 e 4a 03e 7 e 4a 03c 8 e 4a 05a 9 e 4a 058 a e 4a 056 b e 4a 054 c e 4a 052 d e 4a 050 e e 4a 04e f e 4a 04c 0 f 4a 04a 1 f 4a 049 2 f 4a 048 3 f 4a 047 4 f 4a 046 5 f 4a 045 6 f 4a 044 7 f 4a 043 8 f 4a 052 9 f 4a 051 a f 4a 050 b f 4a 04f c f 4a 04e d f 4a 04d e f 4a 04c f f 4a 04b 0 0 4b 04b 1 0 4b 04b 2 0 4b 04b 3 0 4b 04b 4 0 4b 04b 5 0 4b 04b 6 0 4b 04b 7 0 4b 04b 8 0 4b 04b 9 0 4b 04b a 0 4b 04b b 0 4b 04b c 0 4b 04b d 0 4b 04b e 0 4b 04b f 0 4b 04b 0 1 4b 04b 1 1 4b 04c 2 1 4b 04d 3 1 4b 04e 4 1 4b 04f 5 1 4b 050 6 1 4b 051 7 1 4b 052 8 1 4b 043 9 1 4b 044 a 1 4b 045 b 1 4b 046 c 1 4b 047 d 1 4b 048 e 1 4b 049 f 1 4b 04a 0 2 4b 04b 1 2 4b 04d 2 2 4b 04f 3 2 4b 051 4 2 4b 053 5 2 4b 055 6 2 4b 057 7 2 4b 059 8 2 4b 03b 9 2 4b 03d a 2 4b 03f b 2 4b 041 c 2 4b 043 d 2 4b 045 e 2 4b 047 f 2 4b 049 0 3 4b 04b 1 3 4b 04e 2 3 4b 051 3 3 4b 054 4 3 4b 057 5 3 4b 05a 6 3 4b 05d 7 3 4b 060 8 3 4b 033 9 3 4b 036 a 3 4b 039 b 3 4b 03c c 3 4b 03f d 3 4b 042 e 3 4b 045 f 3 4b 048 0 4 4b 04b 1 4 4b 04f 2 4 4b 053 3 4 4b 057 4 4 4b 05b 5 4 4b 05f 6 4 4b 063 7 4 4b 067 8 4 4b 02b 9 4 4b 02f a 4 4b 033 b 4 4b 037 c 4 4b 03b d 4 4b 03f e 4 4b 043 f 4 4b 047 0 5 4b 04b 1 5 4b 050 2 5 4b 055 3 5 4b 05a 4 5 4b 05f 5 5 4b 064 6 5 4b 069 7 5 4b 06e 8 5 4b 023 9 5 4b 028 a 5 4b 02d b 5 4b 032 c 5 4b 037 d 5 4b 03c e 5 4b 041 f 5 4b 046 0 6 4b 04b 1 6 4b 051 2 6 4b 057 3 6 4b 05d 4 6 4b 063 5 6 4b 069 6 6 4b 06f 7 6 4b 075 8 6 4b 01b 9 6 4b 021 a 6 4b 027 b 6 4b 02d c 6 4b 033 d 6 4b 039 e 6 4b 03f f 6 4b 045 0 7 4b 04b 1 7 4b 052 2 7 4b 059 3 7 4b 060 4 7 4b 067 5 7 4b 06e 6 7 4b 075 7 7 4b 07c 8 7 4b 013 9 7 4b 01a a 7 4b 021 b 7 4b 028 c 7 4b 02f d 7 4b 036 e 7 4b 03d f 7 4b 044 0 8 4b 04b 1 8 4b 043 2 8 4b 03b 3 8 4b 033 4 8 4b 02b 5 8 4b 023 6 8 4b 01b 7 8 4b 013 8 8 4b 08b 9 8 4b 083 a 8 4b 07b b 8 4b 073 c 8 4b 06b d 8 4b 063 e 8 4b 05b f 8 4b 053 0 9 4b 04b 1 9 4b 044 2 9 4b 03d 3 9 4b 036 4 9 4b 02f 5 9 4b 028 6 9 4b 021 7 9 4b 01a 8 9 4b 083 9 9 4b 07c a 9 4b 075 b 9 4b 06e c 9 4b 067 d 9 4b 060 e 9 4b 059 f 9 4b 052 0 a 4b 04b 1 a 4b 045 2 a 4b 03f 3 a 4b 039 4 a 4b 033 5 a 4b 02d 6 a 4b 027 7 a 4b 021 8 a 4b 07b 9 a 4b 075 a a 4b 06f b a 4b 069 c a 4b 063 d a 4b 05d e a 4b 057 f a 4b 051 0 b 4b 04b 1 b 4b 046 2 b 4b 041 3 b 4b 03c 4 b 4b 037 5 b 4b 032 6 b 4b 02d 7 b 4b 028 8 b 4b 073 9 b 4b 06e a b 4b 069 b b 4b 064 c b 4b 05f d b 4b 05a e b 4b 055 f b 4b 050 0 c 4b 04b 1 c 4b 047 2 c 4b 043 3 c 4b 03f 4 c 4b 03b 5 c 4b 037 6 c 4b 033 7 c 4b 02f 8 c 4b 06b 9 c 4b 067 a c 4b 063 b c 4b 05f c c 4b 05b d c 4b 057 e c 4b 053 f c 4b 04f 0 d 4b 04b 1 d 4b 048 2 d 4b 045 3 d 4b 042 4 d 4b 03f 5 d 4b 03c 6 d 4b 039 7 d 4b 036 8 d 4b 063 9 d 4b 060 a d 4b 05d b d 4b 05a c d 4b 057 d d 4b 054 e d 4b 051 f d 4b 04e 0 e 4b 04b 1 e 4b 049 2 e 4b 047 3 e 4b 045 4 e 4b 043 5 e 4b 041 6 e 4b 03f 7 e 4b 03d 8 e 4b 05b 9 e 4b 059 a e 4b 057 b e 4b 055 c e 4b 053 d e 4b 051 e e 4b 04f f e 4b 04d 0 f 4b 04b 1 f 4b 04a 2 f 4b 049 3 f 4b 048 4 f 4b 047 5 f 4b 046 6 f 4b 045 7 f 4b 044 8 f 4b 053 9 f 4b 052 a f 4b 051 b f 4b 050 c f 4b 04f d f 4b 04e e f 4b 04d f f 4b 04c 0 0 4c 04c 1 0 4c 04c 2 0 4c 04c 3 0 4c 04c 4 0 4c 04c 5 0 4c 04c 6 0 4c 04c 7 0 4c 04c 8 0 4c 04c 9 0 4c 04c a 0 4c 04c b 0 4c 04c c 0 4c 04c d 0 4c 04c e 0 4c 04c f 0 4c 04c 0 1 4c 04c 1 1 4c 04d 2 1 4c 04e 3 1 4c 04f 4 1 4c 050 5 1 4c 051 6 1 4c 052 7 1 4c 053 8 1 4c 044 9 1 4c 045 a 1 4c 046 b 1 4c 047 c 1 4c 048 d 1 4c 049 e 1 4c 04a f 1 4c 04b 0 2 4c 04c 1 2 4c 04e 2 2 4c 050 3 2 4c 052 4 2 4c 054 5 2 4c 056 6 2 4c 058 7 2 4c 05a 8 2 4c 03c 9 2 4c 03e a 2 4c 040 b 2 4c 042 c 2 4c 044 d 2 4c 046 e 2 4c 048 f 2 4c 04a 0 3 4c 04c 1 3 4c 04f 2 3 4c 052 3 3 4c 055 4 3 4c 058 5 3 4c 05b 6 3 4c 05e 7 3 4c 061 8 3 4c 034 9 3 4c 037 a 3 4c 03a b 3 4c 03d c 3 4c 040 d 3 4c 043 e 3 4c 046 f 3 4c 049 0 4 4c 04c 1 4 4c 050 2 4 4c 054 3 4 4c 058 4 4 4c 05c 5 4 4c 060 6 4 4c 064 7 4 4c 068 8 4 4c 02c 9 4 4c 030 a 4 4c 034 b 4 4c 038 c 4 4c 03c d 4 4c 040 e 4 4c 044 f 4 4c 048 0 5 4c 04c 1 5 4c 051 2 5 4c 056 3 5 4c 05b 4 5 4c 060 5 5 4c 065 6 5 4c 06a 7 5 4c 06f 8 5 4c 024 9 5 4c 029 a 5 4c 02e b 5 4c 033 c 5 4c 038 d 5 4c 03d e 5 4c 042 f 5 4c 047 0 6 4c 04c 1 6 4c 052 2 6 4c 058 3 6 4c 05e 4 6 4c 064 5 6 4c 06a 6 6 4c 070 7 6 4c 076 8 6 4c 01c 9 6 4c 022 a 6 4c 028 b 6 4c 02e c 6 4c 034 d 6 4c 03a e 6 4c 040 f 6 4c 046 0 7 4c 04c 1 7 4c 053 2 7 4c 05a 3 7 4c 061 4 7 4c 068 5 7 4c 06f 6 7 4c 076 7 7 4c 07d 8 7 4c 014 9 7 4c 01b a 7 4c 022 b 7 4c 029 c 7 4c 030 d 7 4c 037 e 7 4c 03e f 7 4c 045 0 8 4c 04c 1 8 4c 044 2 8 4c 03c 3 8 4c 034 4 8 4c 02c 5 8 4c 024 6 8 4c 01c 7 8 4c 014 8 8 4c 08c 9 8 4c 084 a 8 4c 07c b 8 4c 074 c 8 4c 06c d 8 4c 064 e 8 4c 05c f 8 4c 054 0 9 4c 04c 1 9 4c 045 2 9 4c 03e 3 9 4c 037 4 9 4c 030 5 9 4c 029 6 9 4c 022 7 9 4c 01b 8 9 4c 084 9 9 4c 07d a 9 4c 076 b 9 4c 06f c 9 4c 068 d 9 4c 061 e 9 4c 05a f 9 4c 053 0 a 4c 04c 1 a 4c 046 2 a 4c 040 3 a 4c 03a 4 a 4c 034 5 a 4c 02e 6 a 4c 028 7 a 4c 022 8 a 4c 07c 9 a 4c 076 a a 4c 070 b a 4c 06a c a 4c 064 d a 4c 05e e a 4c 058 f a 4c 052 0 b 4c 04c 1 b 4c 047 2 b 4c 042 3 b 4c 03d 4 b 4c 038 5 b 4c 033 6 b 4c 02e 7 b 4c 029 8 b 4c 074 9 b 4c 06f a b 4c 06a b b 4c 065 c b 4c 060 d b 4c 05b e b 4c 056 f b 4c 051 0 c 4c 04c 1 c 4c 048 2 c 4c 044 3 c 4c 040 4 c 4c 03c 5 c 4c 038 6 c 4c 034 7 c 4c 030 8 c 4c 06c 9 c 4c 068 a c 4c 064 b c 4c 060 c c 4c 05c d c 4c 058 e c 4c 054 f c 4c 050 0 d 4c 04c 1 d 4c 049 2 d 4c 046 3 d 4c 043 4 d 4c 040 5 d 4c 03d 6 d 4c 03a 7 d 4c 037 8 d 4c 064 9 d 4c 061 a d 4c 05e b d 4c 05b c d 4c 058 d d 4c 055 e d 4c 052 f d 4c 04f 0 e 4c 04c 1 e 4c 04a 2 e 4c 048 3 e 4c 046 4 e 4c 044 5 e 4c 042 6 e 4c 040 7 e 4c 03e 8 e 4c 05c 9 e 4c 05a a e 4c 058 b e 4c 056 c e 4c 054 d e 4c 052 e e 4c 050 f e 4c 04e 0 f 4c 04c 1 f 4c 04b 2 f 4c 04a 3 f 4c 049 4 f 4c 048 5 f 4c 047 6 f 4c 046 7 f 4c 045 8 f 4c 054 9 f 4c 053 a f 4c 052 b f 4c 051 c f 4c 050 d f 4c 04f e f 4c 04e f f 4c 04d 0 0 4d 04d 1 0 4d 04d 2 0 4d 04d 3 0 4d 04d 4 0 4d 04d 5 0 4d 04d 6 0 4d 04d 7 0 4d 04d 8 0 4d 04d 9 0 4d 04d a 0 4d 04d b 0 4d 04d c 0 4d 04d d 0 4d 04d e 0 4d 04d f 0 4d 04d 0 1 4d 04d 1 1 4d 04e 2 1 4d 04f 3 1 4d 050 4 1 4d 051 5 1 4d 052 6 1 4d 053 7 1 4d 054 8 1 4d 045 9 1 4d 046 a 1 4d 047 b 1 4d 048 c 1 4d 049 d 1 4d 04a e 1 4d 04b f 1 4d 04c 0 2 4d 04d 1 2 4d 04f 2 2 4d 051 3 2 4d 053 4 2 4d 055 5 2 4d 057 6 2 4d 059 7 2 4d 05b 8 2 4d 03d 9 2 4d 03f a 2 4d 041 b 2 4d 043 c 2 4d 045 d 2 4d 047 e 2 4d 049 f 2 4d 04b 0 3 4d 04d 1 3 4d 050 2 3 4d 053 3 3 4d 056 4 3 4d 059 5 3 4d 05c 6 3 4d 05f 7 3 4d 062 8 3 4d 035 9 3 4d 038 a 3 4d 03b b 3 4d 03e c 3 4d 041 d 3 4d 044 e 3 4d 047 f 3 4d 04a 0 4 4d 04d 1 4 4d 051 2 4 4d 055 3 4 4d 059 4 4 4d 05d 5 4 4d 061 6 4 4d 065 7 4 4d 069 8 4 4d 02d 9 4 4d 031 a 4 4d 035 b 4 4d 039 c 4 4d 03d d 4 4d 041 e 4 4d 045 f 4 4d 049 0 5 4d 04d 1 5 4d 052 2 5 4d 057 3 5 4d 05c 4 5 4d 061 5 5 4d 066 6 5 4d 06b 7 5 4d 070 8 5 4d 025 9 5 4d 02a a 5 4d 02f b 5 4d 034 c 5 4d 039 d 5 4d 03e e 5 4d 043 f 5 4d 048 0 6 4d 04d 1 6 4d 053 2 6 4d 059 3 6 4d 05f 4 6 4d 065 5 6 4d 06b 6 6 4d 071 7 6 4d 077 8 6 4d 01d 9 6 4d 023 a 6 4d 029 b 6 4d 02f c 6 4d 035 d 6 4d 03b e 6 4d 041 f 6 4d 047 0 7 4d 04d 1 7 4d 054 2 7 4d 05b 3 7 4d 062 4 7 4d 069 5 7 4d 070 6 7 4d 077 7 7 4d 07e 8 7 4d 015 9 7 4d 01c a 7 4d 023 b 7 4d 02a c 7 4d 031 d 7 4d 038 e 7 4d 03f f 7 4d 046 0 8 4d 04d 1 8 4d 045 2 8 4d 03d 3 8 4d 035 4 8 4d 02d 5 8 4d 025 6 8 4d 01d 7 8 4d 015 8 8 4d 08d 9 8 4d 085 a 8 4d 07d b 8 4d 075 c 8 4d 06d d 8 4d 065 e 8 4d 05d f 8 4d 055 0 9 4d 04d 1 9 4d 046 2 9 4d 03f 3 9 4d 038 4 9 4d 031 5 9 4d 02a 6 9 4d 023 7 9 4d 01c 8 9 4d 085 9 9 4d 07e a 9 4d 077 b 9 4d 070 c 9 4d 069 d 9 4d 062 e 9 4d 05b f 9 4d 054 0 a 4d 04d 1 a 4d 047 2 a 4d 041 3 a 4d 03b 4 a 4d 035 5 a 4d 02f 6 a 4d 029 7 a 4d 023 8 a 4d 07d 9 a 4d 077 a a 4d 071 b a 4d 06b c a 4d 065 d a 4d 05f e a 4d 059 f a 4d 053 0 b 4d 04d 1 b 4d 048 2 b 4d 043 3 b 4d 03e 4 b 4d 039 5 b 4d 034 6 b 4d 02f 7 b 4d 02a 8 b 4d 075 9 b 4d 070 a b 4d 06b b b 4d 066 c b 4d 061 d b 4d 05c e b 4d 057 f b 4d 052 0 c 4d 04d 1 c 4d 049 2 c 4d 045 3 c 4d 041 4 c 4d 03d 5 c 4d 039 6 c 4d 035 7 c 4d 031 8 c 4d 06d 9 c 4d 069 a c 4d 065 b c 4d 061 c c 4d 05d d c 4d 059 e c 4d 055 f c 4d 051 0 d 4d 04d 1 d 4d 04a 2 d 4d 047 3 d 4d 044 4 d 4d 041 5 d 4d 03e 6 d 4d 03b 7 d 4d 038 8 d 4d 065 9 d 4d 062 a d 4d 05f b d 4d 05c c d 4d 059 d d 4d 056 e d 4d 053 f d 4d 050 0 e 4d 04d 1 e 4d 04b 2 e 4d 049 3 e 4d 047 4 e 4d 045 5 e 4d 043 6 e 4d 041 7 e 4d 03f 8 e 4d 05d 9 e 4d 05b a e 4d 059 b e 4d 057 c e 4d 055 d e 4d 053 e e 4d 051 f e 4d 04f 0 f 4d 04d 1 f 4d 04c 2 f 4d 04b 3 f 4d 04a 4 f 4d 049 5 f 4d 048 6 f 4d 047 7 f 4d 046 8 f 4d 055 9 f 4d 054 a f 4d 053 b f 4d 052 c f 4d 051 d f 4d 050 e f 4d 04f f f 4d 04e 0 0 4e 04e 1 0 4e 04e 2 0 4e 04e 3 0 4e 04e 4 0 4e 04e 5 0 4e 04e 6 0 4e 04e 7 0 4e 04e 8 0 4e 04e 9 0 4e 04e a 0 4e 04e b 0 4e 04e c 0 4e 04e d 0 4e 04e e 0 4e 04e f 0 4e 04e 0 1 4e 04e 1 1 4e 04f 2 1 4e 050 3 1 4e 051 4 1 4e 052 5 1 4e 053 6 1 4e 054 7 1 4e 055 8 1 4e 046 9 1 4e 047 a 1 4e 048 b 1 4e 049 c 1 4e 04a d 1 4e 04b e 1 4e 04c f 1 4e 04d 0 2 4e 04e 1 2 4e 050 2 2 4e 052 3 2 4e 054 4 2 4e 056 5 2 4e 058 6 2 4e 05a 7 2 4e 05c 8 2 4e 03e 9 2 4e 040 a 2 4e 042 b 2 4e 044 c 2 4e 046 d 2 4e 048 e 2 4e 04a f 2 4e 04c 0 3 4e 04e 1 3 4e 051 2 3 4e 054 3 3 4e 057 4 3 4e 05a 5 3 4e 05d 6 3 4e 060 7 3 4e 063 8 3 4e 036 9 3 4e 039 a 3 4e 03c b 3 4e 03f c 3 4e 042 d 3 4e 045 e 3 4e 048 f 3 4e 04b 0 4 4e 04e 1 4 4e 052 2 4 4e 056 3 4 4e 05a 4 4 4e 05e 5 4 4e 062 6 4 4e 066 7 4 4e 06a 8 4 4e 02e 9 4 4e 032 a 4 4e 036 b 4 4e 03a c 4 4e 03e d 4 4e 042 e 4 4e 046 f 4 4e 04a 0 5 4e 04e 1 5 4e 053 2 5 4e 058 3 5 4e 05d 4 5 4e 062 5 5 4e 067 6 5 4e 06c 7 5 4e 071 8 5 4e 026 9 5 4e 02b a 5 4e 030 b 5 4e 035 c 5 4e 03a d 5 4e 03f e 5 4e 044 f 5 4e 049 0 6 4e 04e 1 6 4e 054 2 6 4e 05a 3 6 4e 060 4 6 4e 066 5 6 4e 06c 6 6 4e 072 7 6 4e 078 8 6 4e 01e 9 6 4e 024 a 6 4e 02a b 6 4e 030 c 6 4e 036 d 6 4e 03c e 6 4e 042 f 6 4e 048 0 7 4e 04e 1 7 4e 055 2 7 4e 05c 3 7 4e 063 4 7 4e 06a 5 7 4e 071 6 7 4e 078 7 7 4e 07f 8 7 4e 016 9 7 4e 01d a 7 4e 024 b 7 4e 02b c 7 4e 032 d 7 4e 039 e 7 4e 040 f 7 4e 047 0 8 4e 04e 1 8 4e 046 2 8 4e 03e 3 8 4e 036 4 8 4e 02e 5 8 4e 026 6 8 4e 01e 7 8 4e 016 8 8 4e 08e 9 8 4e 086 a 8 4e 07e b 8 4e 076 c 8 4e 06e d 8 4e 066 e 8 4e 05e f 8 4e 056 0 9 4e 04e 1 9 4e 047 2 9 4e 040 3 9 4e 039 4 9 4e 032 5 9 4e 02b 6 9 4e 024 7 9 4e 01d 8 9 4e 086 9 9 4e 07f a 9 4e 078 b 9 4e 071 c 9 4e 06a d 9 4e 063 e 9 4e 05c f 9 4e 055 0 a 4e 04e 1 a 4e 048 2 a 4e 042 3 a 4e 03c 4 a 4e 036 5 a 4e 030 6 a 4e 02a 7 a 4e 024 8 a 4e 07e 9 a 4e 078 a a 4e 072 b a 4e 06c c a 4e 066 d a 4e 060 e a 4e 05a f a 4e 054 0 b 4e 04e 1 b 4e 049 2 b 4e 044 3 b 4e 03f 4 b 4e 03a 5 b 4e 035 6 b 4e 030 7 b 4e 02b 8 b 4e 076 9 b 4e 071 a b 4e 06c b b 4e 067 c b 4e 062 d b 4e 05d e b 4e 058 f b 4e 053 0 c 4e 04e 1 c 4e 04a 2 c 4e 046 3 c 4e 042 4 c 4e 03e 5 c 4e 03a 6 c 4e 036 7 c 4e 032 8 c 4e 06e 9 c 4e 06a a c 4e 066 b c 4e 062 c c 4e 05e d c 4e 05a e c 4e 056 f c 4e 052 0 d 4e 04e 1 d 4e 04b 2 d 4e 048 3 d 4e 045 4 d 4e 042 5 d 4e 03f 6 d 4e 03c 7 d 4e 039 8 d 4e 066 9 d 4e 063 a d 4e 060 b d 4e 05d c d 4e 05a d d 4e 057 e d 4e 054 f d 4e 051 0 e 4e 04e 1 e 4e 04c 2 e 4e 04a 3 e 4e 048 4 e 4e 046 5 e 4e 044 6 e 4e 042 7 e 4e 040 8 e 4e 05e 9 e 4e 05c a e 4e 05a b e 4e 058 c e 4e 056 d e 4e 054 e e 4e 052 f e 4e 050 0 f 4e 04e 1 f 4e 04d 2 f 4e 04c 3 f 4e 04b 4 f 4e 04a 5 f 4e 049 6 f 4e 048 7 f 4e 047 8 f 4e 056 9 f 4e 055 a f 4e 054 b f 4e 053 c f 4e 052 d f 4e 051 e f 4e 050 f f 4e 04f 0 0 4f 04f 1 0 4f 04f 2 0 4f 04f 3 0 4f 04f 4 0 4f 04f 5 0 4f 04f 6 0 4f 04f 7 0 4f 04f 8 0 4f 04f 9 0 4f 04f a 0 4f 04f b 0 4f 04f c 0 4f 04f d 0 4f 04f e 0 4f 04f f 0 4f 04f 0 1 4f 04f 1 1 4f 050 2 1 4f 051 3 1 4f 052 4 1 4f 053 5 1 4f 054 6 1 4f 055 7 1 4f 056 8 1 4f 047 9 1 4f 048 a 1 4f 049 b 1 4f 04a c 1 4f 04b d 1 4f 04c e 1 4f 04d f 1 4f 04e 0 2 4f 04f 1 2 4f 051 2 2 4f 053 3 2 4f 055 4 2 4f 057 5 2 4f 059 6 2 4f 05b 7 2 4f 05d 8 2 4f 03f 9 2 4f 041 a 2 4f 043 b 2 4f 045 c 2 4f 047 d 2 4f 049 e 2 4f 04b f 2 4f 04d 0 3 4f 04f 1 3 4f 052 2 3 4f 055 3 3 4f 058 4 3 4f 05b 5 3 4f 05e 6 3 4f 061 7 3 4f 064 8 3 4f 037 9 3 4f 03a a 3 4f 03d b 3 4f 040 c 3 4f 043 d 3 4f 046 e 3 4f 049 f 3 4f 04c 0 4 4f 04f 1 4 4f 053 2 4 4f 057 3 4 4f 05b 4 4 4f 05f 5 4 4f 063 6 4 4f 067 7 4 4f 06b 8 4 4f 02f 9 4 4f 033 a 4 4f 037 b 4 4f 03b c 4 4f 03f d 4 4f 043 e 4 4f 047 f 4 4f 04b 0 5 4f 04f 1 5 4f 054 2 5 4f 059 3 5 4f 05e 4 5 4f 063 5 5 4f 068 6 5 4f 06d 7 5 4f 072 8 5 4f 027 9 5 4f 02c a 5 4f 031 b 5 4f 036 c 5 4f 03b d 5 4f 040 e 5 4f 045 f 5 4f 04a 0 6 4f 04f 1 6 4f 055 2 6 4f 05b 3 6 4f 061 4 6 4f 067 5 6 4f 06d 6 6 4f 073 7 6 4f 079 8 6 4f 01f 9 6 4f 025 a 6 4f 02b b 6 4f 031 c 6 4f 037 d 6 4f 03d e 6 4f 043 f 6 4f 049 0 7 4f 04f 1 7 4f 056 2 7 4f 05d 3 7 4f 064 4 7 4f 06b 5 7 4f 072 6 7 4f 079 7 7 4f 080 8 7 4f 017 9 7 4f 01e a 7 4f 025 b 7 4f 02c c 7 4f 033 d 7 4f 03a e 7 4f 041 f 7 4f 048 0 8 4f 04f 1 8 4f 047 2 8 4f 03f 3 8 4f 037 4 8 4f 02f 5 8 4f 027 6 8 4f 01f 7 8 4f 017 8 8 4f 08f 9 8 4f 087 a 8 4f 07f b 8 4f 077 c 8 4f 06f d 8 4f 067 e 8 4f 05f f 8 4f 057 0 9 4f 04f 1 9 4f 048 2 9 4f 041 3 9 4f 03a 4 9 4f 033 5 9 4f 02c 6 9 4f 025 7 9 4f 01e 8 9 4f 087 9 9 4f 080 a 9 4f 079 b 9 4f 072 c 9 4f 06b d 9 4f 064 e 9 4f 05d f 9 4f 056 0 a 4f 04f 1 a 4f 049 2 a 4f 043 3 a 4f 03d 4 a 4f 037 5 a 4f 031 6 a 4f 02b 7 a 4f 025 8 a 4f 07f 9 a 4f 079 a a 4f 073 b a 4f 06d c a 4f 067 d a 4f 061 e a 4f 05b f a 4f 055 0 b 4f 04f 1 b 4f 04a 2 b 4f 045 3 b 4f 040 4 b 4f 03b 5 b 4f 036 6 b 4f 031 7 b 4f 02c 8 b 4f 077 9 b 4f 072 a b 4f 06d b b 4f 068 c b 4f 063 d b 4f 05e e b 4f 059 f b 4f 054 0 c 4f 04f 1 c 4f 04b 2 c 4f 047 3 c 4f 043 4 c 4f 03f 5 c 4f 03b 6 c 4f 037 7 c 4f 033 8 c 4f 06f 9 c 4f 06b a c 4f 067 b c 4f 063 c c 4f 05f d c 4f 05b e c 4f 057 f c 4f 053 0 d 4f 04f 1 d 4f 04c 2 d 4f 049 3 d 4f 046 4 d 4f 043 5 d 4f 040 6 d 4f 03d 7 d 4f 03a 8 d 4f 067 9 d 4f 064 a d 4f 061 b d 4f 05e c d 4f 05b d d 4f 058 e d 4f 055 f d 4f 052 0 e 4f 04f 1 e 4f 04d 2 e 4f 04b 3 e 4f 049 4 e 4f 047 5 e 4f 045 6 e 4f 043 7 e 4f 041 8 e 4f 05f 9 e 4f 05d a e 4f 05b b e 4f 059 c e 4f 057 d e 4f 055 e e 4f 053 f e 4f 051 0 f 4f 04f 1 f 4f 04e 2 f 4f 04d 3 f 4f 04c 4 f 4f 04b 5 f 4f 04a 6 f 4f 049 7 f 4f 048 8 f 4f 057 9 f 4f 056 a f 4f 055 b f 4f 054 c f 4f 053 d f 4f 052 e f 4f 051 f f 4f 050 0 0 50 050 1 0 50 050 2 0 50 050 3 0 50 050 4 0 50 050 5 0 50 050 6 0 50 050 7 0 50 050 8 0 50 050 9 0 50 050 a 0 50 050 b 0 50 050 c 0 50 050 d 0 50 050 e 0 50 050 f 0 50 050 0 1 50 050 1 1 50 051 2 1 50 052 3 1 50 053 4 1 50 054 5 1 50 055 6 1 50 056 7 1 50 057 8 1 50 048 9 1 50 049 a 1 50 04a b 1 50 04b c 1 50 04c d 1 50 04d e 1 50 04e f 1 50 04f 0 2 50 050 1 2 50 052 2 2 50 054 3 2 50 056 4 2 50 058 5 2 50 05a 6 2 50 05c 7 2 50 05e 8 2 50 040 9 2 50 042 a 2 50 044 b 2 50 046 c 2 50 048 d 2 50 04a e 2 50 04c f 2 50 04e 0 3 50 050 1 3 50 053 2 3 50 056 3 3 50 059 4 3 50 05c 5 3 50 05f 6 3 50 062 7 3 50 065 8 3 50 038 9 3 50 03b a 3 50 03e b 3 50 041 c 3 50 044 d 3 50 047 e 3 50 04a f 3 50 04d 0 4 50 050 1 4 50 054 2 4 50 058 3 4 50 05c 4 4 50 060 5 4 50 064 6 4 50 068 7 4 50 06c 8 4 50 030 9 4 50 034 a 4 50 038 b 4 50 03c c 4 50 040 d 4 50 044 e 4 50 048 f 4 50 04c 0 5 50 050 1 5 50 055 2 5 50 05a 3 5 50 05f 4 5 50 064 5 5 50 069 6 5 50 06e 7 5 50 073 8 5 50 028 9 5 50 02d a 5 50 032 b 5 50 037 c 5 50 03c d 5 50 041 e 5 50 046 f 5 50 04b 0 6 50 050 1 6 50 056 2 6 50 05c 3 6 50 062 4 6 50 068 5 6 50 06e 6 6 50 074 7 6 50 07a 8 6 50 020 9 6 50 026 a 6 50 02c b 6 50 032 c 6 50 038 d 6 50 03e e 6 50 044 f 6 50 04a 0 7 50 050 1 7 50 057 2 7 50 05e 3 7 50 065 4 7 50 06c 5 7 50 073 6 7 50 07a 7 7 50 081 8 7 50 018 9 7 50 01f a 7 50 026 b 7 50 02d c 7 50 034 d 7 50 03b e 7 50 042 f 7 50 049 0 8 50 050 1 8 50 048 2 8 50 040 3 8 50 038 4 8 50 030 5 8 50 028 6 8 50 020 7 8 50 018 8 8 50 090 9 8 50 088 a 8 50 080 b 8 50 078 c 8 50 070 d 8 50 068 e 8 50 060 f 8 50 058 0 9 50 050 1 9 50 049 2 9 50 042 3 9 50 03b 4 9 50 034 5 9 50 02d 6 9 50 026 7 9 50 01f 8 9 50 088 9 9 50 081 a 9 50 07a b 9 50 073 c 9 50 06c d 9 50 065 e 9 50 05e f 9 50 057 0 a 50 050 1 a 50 04a 2 a 50 044 3 a 50 03e 4 a 50 038 5 a 50 032 6 a 50 02c 7 a 50 026 8 a 50 080 9 a 50 07a a a 50 074 b a 50 06e c a 50 068 d a 50 062 e a 50 05c f a 50 056 0 b 50 050 1 b 50 04b 2 b 50 046 3 b 50 041 4 b 50 03c 5 b 50 037 6 b 50 032 7 b 50 02d 8 b 50 078 9 b 50 073 a b 50 06e b b 50 069 c b 50 064 d b 50 05f e b 50 05a f b 50 055 0 c 50 050 1 c 50 04c 2 c 50 048 3 c 50 044 4 c 50 040 5 c 50 03c 6 c 50 038 7 c 50 034 8 c 50 070 9 c 50 06c a c 50 068 b c 50 064 c c 50 060 d c 50 05c e c 50 058 f c 50 054 0 d 50 050 1 d 50 04d 2 d 50 04a 3 d 50 047 4 d 50 044 5 d 50 041 6 d 50 03e 7 d 50 03b 8 d 50 068 9 d 50 065 a d 50 062 b d 50 05f c d 50 05c d d 50 059 e d 50 056 f d 50 053 0 e 50 050 1 e 50 04e 2 e 50 04c 3 e 50 04a 4 e 50 048 5 e 50 046 6 e 50 044 7 e 50 042 8 e 50 060 9 e 50 05e a e 50 05c b e 50 05a c e 50 058 d e 50 056 e e 50 054 f e 50 052 0 f 50 050 1 f 50 04f 2 f 50 04e 3 f 50 04d 4 f 50 04c 5 f 50 04b 6 f 50 04a 7 f 50 049 8 f 50 058 9 f 50 057 a f 50 056 b f 50 055 c f 50 054 d f 50 053 e f 50 052 f f 50 051 0 0 51 051 1 0 51 051 2 0 51 051 3 0 51 051 4 0 51 051 5 0 51 051 6 0 51 051 7 0 51 051 8 0 51 051 9 0 51 051 a 0 51 051 b 0 51 051 c 0 51 051 d 0 51 051 e 0 51 051 f 0 51 051 0 1 51 051 1 1 51 052 2 1 51 053 3 1 51 054 4 1 51 055 5 1 51 056 6 1 51 057 7 1 51 058 8 1 51 049 9 1 51 04a a 1 51 04b b 1 51 04c c 1 51 04d d 1 51 04e e 1 51 04f f 1 51 050 0 2 51 051 1 2 51 053 2 2 51 055 3 2 51 057 4 2 51 059 5 2 51 05b 6 2 51 05d 7 2 51 05f 8 2 51 041 9 2 51 043 a 2 51 045 b 2 51 047 c 2 51 049 d 2 51 04b e 2 51 04d f 2 51 04f 0 3 51 051 1 3 51 054 2 3 51 057 3 3 51 05a 4 3 51 05d 5 3 51 060 6 3 51 063 7 3 51 066 8 3 51 039 9 3 51 03c a 3 51 03f b 3 51 042 c 3 51 045 d 3 51 048 e 3 51 04b f 3 51 04e 0 4 51 051 1 4 51 055 2 4 51 059 3 4 51 05d 4 4 51 061 5 4 51 065 6 4 51 069 7 4 51 06d 8 4 51 031 9 4 51 035 a 4 51 039 b 4 51 03d c 4 51 041 d 4 51 045 e 4 51 049 f 4 51 04d 0 5 51 051 1 5 51 056 2 5 51 05b 3 5 51 060 4 5 51 065 5 5 51 06a 6 5 51 06f 7 5 51 074 8 5 51 029 9 5 51 02e a 5 51 033 b 5 51 038 c 5 51 03d d 5 51 042 e 5 51 047 f 5 51 04c 0 6 51 051 1 6 51 057 2 6 51 05d 3 6 51 063 4 6 51 069 5 6 51 06f 6 6 51 075 7 6 51 07b 8 6 51 021 9 6 51 027 a 6 51 02d b 6 51 033 c 6 51 039 d 6 51 03f e 6 51 045 f 6 51 04b 0 7 51 051 1 7 51 058 2 7 51 05f 3 7 51 066 4 7 51 06d 5 7 51 074 6 7 51 07b 7 7 51 082 8 7 51 019 9 7 51 020 a 7 51 027 b 7 51 02e c 7 51 035 d 7 51 03c e 7 51 043 f 7 51 04a 0 8 51 051 1 8 51 049 2 8 51 041 3 8 51 039 4 8 51 031 5 8 51 029 6 8 51 021 7 8 51 019 8 8 51 091 9 8 51 089 a 8 51 081 b 8 51 079 c 8 51 071 d 8 51 069 e 8 51 061 f 8 51 059 0 9 51 051 1 9 51 04a 2 9 51 043 3 9 51 03c 4 9 51 035 5 9 51 02e 6 9 51 027 7 9 51 020 8 9 51 089 9 9 51 082 a 9 51 07b b 9 51 074 c 9 51 06d d 9 51 066 e 9 51 05f f 9 51 058 0 a 51 051 1 a 51 04b 2 a 51 045 3 a 51 03f 4 a 51 039 5 a 51 033 6 a 51 02d 7 a 51 027 8 a 51 081 9 a 51 07b a a 51 075 b a 51 06f c a 51 069 d a 51 063 e a 51 05d f a 51 057 0 b 51 051 1 b 51 04c 2 b 51 047 3 b 51 042 4 b 51 03d 5 b 51 038 6 b 51 033 7 b 51 02e 8 b 51 079 9 b 51 074 a b 51 06f b b 51 06a c b 51 065 d b 51 060 e b 51 05b f b 51 056 0 c 51 051 1 c 51 04d 2 c 51 049 3 c 51 045 4 c 51 041 5 c 51 03d 6 c 51 039 7 c 51 035 8 c 51 071 9 c 51 06d a c 51 069 b c 51 065 c c 51 061 d c 51 05d e c 51 059 f c 51 055 0 d 51 051 1 d 51 04e 2 d 51 04b 3 d 51 048 4 d 51 045 5 d 51 042 6 d 51 03f 7 d 51 03c 8 d 51 069 9 d 51 066 a d 51 063 b d 51 060 c d 51 05d d d 51 05a e d 51 057 f d 51 054 0 e 51 051 1 e 51 04f 2 e 51 04d 3 e 51 04b 4 e 51 049 5 e 51 047 6 e 51 045 7 e 51 043 8 e 51 061 9 e 51 05f a e 51 05d b e 51 05b c e 51 059 d e 51 057 e e 51 055 f e 51 053 0 f 51 051 1 f 51 050 2 f 51 04f 3 f 51 04e 4 f 51 04d 5 f 51 04c 6 f 51 04b 7 f 51 04a 8 f 51 059 9 f 51 058 a f 51 057 b f 51 056 c f 51 055 d f 51 054 e f 51 053 f f 51 052 0 0 52 052 1 0 52 052 2 0 52 052 3 0 52 052 4 0 52 052 5 0 52 052 6 0 52 052 7 0 52 052 8 0 52 052 9 0 52 052 a 0 52 052 b 0 52 052 c 0 52 052 d 0 52 052 e 0 52 052 f 0 52 052 0 1 52 052 1 1 52 053 2 1 52 054 3 1 52 055 4 1 52 056 5 1 52 057 6 1 52 058 7 1 52 059 8 1 52 04a 9 1 52 04b a 1 52 04c b 1 52 04d c 1 52 04e d 1 52 04f e 1 52 050 f 1 52 051 0 2 52 052 1 2 52 054 2 2 52 056 3 2 52 058 4 2 52 05a 5 2 52 05c 6 2 52 05e 7 2 52 060 8 2 52 042 9 2 52 044 a 2 52 046 b 2 52 048 c 2 52 04a d 2 52 04c e 2 52 04e f 2 52 050 0 3 52 052 1 3 52 055 2 3 52 058 3 3 52 05b 4 3 52 05e 5 3 52 061 6 3 52 064 7 3 52 067 8 3 52 03a 9 3 52 03d a 3 52 040 b 3 52 043 c 3 52 046 d 3 52 049 e 3 52 04c f 3 52 04f 0 4 52 052 1 4 52 056 2 4 52 05a 3 4 52 05e 4 4 52 062 5 4 52 066 6 4 52 06a 7 4 52 06e 8 4 52 032 9 4 52 036 a 4 52 03a b 4 52 03e c 4 52 042 d 4 52 046 e 4 52 04a f 4 52 04e 0 5 52 052 1 5 52 057 2 5 52 05c 3 5 52 061 4 5 52 066 5 5 52 06b 6 5 52 070 7 5 52 075 8 5 52 02a 9 5 52 02f a 5 52 034 b 5 52 039 c 5 52 03e d 5 52 043 e 5 52 048 f 5 52 04d 0 6 52 052 1 6 52 058 2 6 52 05e 3 6 52 064 4 6 52 06a 5 6 52 070 6 6 52 076 7 6 52 07c 8 6 52 022 9 6 52 028 a 6 52 02e b 6 52 034 c 6 52 03a d 6 52 040 e 6 52 046 f 6 52 04c 0 7 52 052 1 7 52 059 2 7 52 060 3 7 52 067 4 7 52 06e 5 7 52 075 6 7 52 07c 7 7 52 083 8 7 52 01a 9 7 52 021 a 7 52 028 b 7 52 02f c 7 52 036 d 7 52 03d e 7 52 044 f 7 52 04b 0 8 52 052 1 8 52 04a 2 8 52 042 3 8 52 03a 4 8 52 032 5 8 52 02a 6 8 52 022 7 8 52 01a 8 8 52 092 9 8 52 08a a 8 52 082 b 8 52 07a c 8 52 072 d 8 52 06a e 8 52 062 f 8 52 05a 0 9 52 052 1 9 52 04b 2 9 52 044 3 9 52 03d 4 9 52 036 5 9 52 02f 6 9 52 028 7 9 52 021 8 9 52 08a 9 9 52 083 a 9 52 07c b 9 52 075 c 9 52 06e d 9 52 067 e 9 52 060 f 9 52 059 0 a 52 052 1 a 52 04c 2 a 52 046 3 a 52 040 4 a 52 03a 5 a 52 034 6 a 52 02e 7 a 52 028 8 a 52 082 9 a 52 07c a a 52 076 b a 52 070 c a 52 06a d a 52 064 e a 52 05e f a 52 058 0 b 52 052 1 b 52 04d 2 b 52 048 3 b 52 043 4 b 52 03e 5 b 52 039 6 b 52 034 7 b 52 02f 8 b 52 07a 9 b 52 075 a b 52 070 b b 52 06b c b 52 066 d b 52 061 e b 52 05c f b 52 057 0 c 52 052 1 c 52 04e 2 c 52 04a 3 c 52 046 4 c 52 042 5 c 52 03e 6 c 52 03a 7 c 52 036 8 c 52 072 9 c 52 06e a c 52 06a b c 52 066 c c 52 062 d c 52 05e e c 52 05a f c 52 056 0 d 52 052 1 d 52 04f 2 d 52 04c 3 d 52 049 4 d 52 046 5 d 52 043 6 d 52 040 7 d 52 03d 8 d 52 06a 9 d 52 067 a d 52 064 b d 52 061 c d 52 05e d d 52 05b e d 52 058 f d 52 055 0 e 52 052 1 e 52 050 2 e 52 04e 3 e 52 04c 4 e 52 04a 5 e 52 048 6 e 52 046 7 e 52 044 8 e 52 062 9 e 52 060 a e 52 05e b e 52 05c c e 52 05a d e 52 058 e e 52 056 f e 52 054 0 f 52 052 1 f 52 051 2 f 52 050 3 f 52 04f 4 f 52 04e 5 f 52 04d 6 f 52 04c 7 f 52 04b 8 f 52 05a 9 f 52 059 a f 52 058 b f 52 057 c f 52 056 d f 52 055 e f 52 054 f f 52 053 0 0 53 053 1 0 53 053 2 0 53 053 3 0 53 053 4 0 53 053 5 0 53 053 6 0 53 053 7 0 53 053 8 0 53 053 9 0 53 053 a 0 53 053 b 0 53 053 c 0 53 053 d 0 53 053 e 0 53 053 f 0 53 053 0 1 53 053 1 1 53 054 2 1 53 055 3 1 53 056 4 1 53 057 5 1 53 058 6 1 53 059 7 1 53 05a 8 1 53 04b 9 1 53 04c a 1 53 04d b 1 53 04e c 1 53 04f d 1 53 050 e 1 53 051 f 1 53 052 0 2 53 053 1 2 53 055 2 2 53 057 3 2 53 059 4 2 53 05b 5 2 53 05d 6 2 53 05f 7 2 53 061 8 2 53 043 9 2 53 045 a 2 53 047 b 2 53 049 c 2 53 04b d 2 53 04d e 2 53 04f f 2 53 051 0 3 53 053 1 3 53 056 2 3 53 059 3 3 53 05c 4 3 53 05f 5 3 53 062 6 3 53 065 7 3 53 068 8 3 53 03b 9 3 53 03e a 3 53 041 b 3 53 044 c 3 53 047 d 3 53 04a e 3 53 04d f 3 53 050 0 4 53 053 1 4 53 057 2 4 53 05b 3 4 53 05f 4 4 53 063 5 4 53 067 6 4 53 06b 7 4 53 06f 8 4 53 033 9 4 53 037 a 4 53 03b b 4 53 03f c 4 53 043 d 4 53 047 e 4 53 04b f 4 53 04f 0 5 53 053 1 5 53 058 2 5 53 05d 3 5 53 062 4 5 53 067 5 5 53 06c 6 5 53 071 7 5 53 076 8 5 53 02b 9 5 53 030 a 5 53 035 b 5 53 03a c 5 53 03f d 5 53 044 e 5 53 049 f 5 53 04e 0 6 53 053 1 6 53 059 2 6 53 05f 3 6 53 065 4 6 53 06b 5 6 53 071 6 6 53 077 7 6 53 07d 8 6 53 023 9 6 53 029 a 6 53 02f b 6 53 035 c 6 53 03b d 6 53 041 e 6 53 047 f 6 53 04d 0 7 53 053 1 7 53 05a 2 7 53 061 3 7 53 068 4 7 53 06f 5 7 53 076 6 7 53 07d 7 7 53 084 8 7 53 01b 9 7 53 022 a 7 53 029 b 7 53 030 c 7 53 037 d 7 53 03e e 7 53 045 f 7 53 04c 0 8 53 053 1 8 53 04b 2 8 53 043 3 8 53 03b 4 8 53 033 5 8 53 02b 6 8 53 023 7 8 53 01b 8 8 53 093 9 8 53 08b a 8 53 083 b 8 53 07b c 8 53 073 d 8 53 06b e 8 53 063 f 8 53 05b 0 9 53 053 1 9 53 04c 2 9 53 045 3 9 53 03e 4 9 53 037 5 9 53 030 6 9 53 029 7 9 53 022 8 9 53 08b 9 9 53 084 a 9 53 07d b 9 53 076 c 9 53 06f d 9 53 068 e 9 53 061 f 9 53 05a 0 a 53 053 1 a 53 04d 2 a 53 047 3 a 53 041 4 a 53 03b 5 a 53 035 6 a 53 02f 7 a 53 029 8 a 53 083 9 a 53 07d a a 53 077 b a 53 071 c a 53 06b d a 53 065 e a 53 05f f a 53 059 0 b 53 053 1 b 53 04e 2 b 53 049 3 b 53 044 4 b 53 03f 5 b 53 03a 6 b 53 035 7 b 53 030 8 b 53 07b 9 b 53 076 a b 53 071 b b 53 06c c b 53 067 d b 53 062 e b 53 05d f b 53 058 0 c 53 053 1 c 53 04f 2 c 53 04b 3 c 53 047 4 c 53 043 5 c 53 03f 6 c 53 03b 7 c 53 037 8 c 53 073 9 c 53 06f a c 53 06b b c 53 067 c c 53 063 d c 53 05f e c 53 05b f c 53 057 0 d 53 053 1 d 53 050 2 d 53 04d 3 d 53 04a 4 d 53 047 5 d 53 044 6 d 53 041 7 d 53 03e 8 d 53 06b 9 d 53 068 a d 53 065 b d 53 062 c d 53 05f d d 53 05c e d 53 059 f d 53 056 0 e 53 053 1 e 53 051 2 e 53 04f 3 e 53 04d 4 e 53 04b 5 e 53 049 6 e 53 047 7 e 53 045 8 e 53 063 9 e 53 061 a e 53 05f b e 53 05d c e 53 05b d e 53 059 e e 53 057 f e 53 055 0 f 53 053 1 f 53 052 2 f 53 051 3 f 53 050 4 f 53 04f 5 f 53 04e 6 f 53 04d 7 f 53 04c 8 f 53 05b 9 f 53 05a a f 53 059 b f 53 058 c f 53 057 d f 53 056 e f 53 055 f f 53 054 0 0 54 054 1 0 54 054 2 0 54 054 3 0 54 054 4 0 54 054 5 0 54 054 6 0 54 054 7 0 54 054 8 0 54 054 9 0 54 054 a 0 54 054 b 0 54 054 c 0 54 054 d 0 54 054 e 0 54 054 f 0 54 054 0 1 54 054 1 1 54 055 2 1 54 056 3 1 54 057 4 1 54 058 5 1 54 059 6 1 54 05a 7 1 54 05b 8 1 54 04c 9 1 54 04d a 1 54 04e b 1 54 04f c 1 54 050 d 1 54 051 e 1 54 052 f 1 54 053 0 2 54 054 1 2 54 056 2 2 54 058 3 2 54 05a 4 2 54 05c 5 2 54 05e 6 2 54 060 7 2 54 062 8 2 54 044 9 2 54 046 a 2 54 048 b 2 54 04a c 2 54 04c d 2 54 04e e 2 54 050 f 2 54 052 0 3 54 054 1 3 54 057 2 3 54 05a 3 3 54 05d 4 3 54 060 5 3 54 063 6 3 54 066 7 3 54 069 8 3 54 03c 9 3 54 03f a 3 54 042 b 3 54 045 c 3 54 048 d 3 54 04b e 3 54 04e f 3 54 051 0 4 54 054 1 4 54 058 2 4 54 05c 3 4 54 060 4 4 54 064 5 4 54 068 6 4 54 06c 7 4 54 070 8 4 54 034 9 4 54 038 a 4 54 03c b 4 54 040 c 4 54 044 d 4 54 048 e 4 54 04c f 4 54 050 0 5 54 054 1 5 54 059 2 5 54 05e 3 5 54 063 4 5 54 068 5 5 54 06d 6 5 54 072 7 5 54 077 8 5 54 02c 9 5 54 031 a 5 54 036 b 5 54 03b c 5 54 040 d 5 54 045 e 5 54 04a f 5 54 04f 0 6 54 054 1 6 54 05a 2 6 54 060 3 6 54 066 4 6 54 06c 5 6 54 072 6 6 54 078 7 6 54 07e 8 6 54 024 9 6 54 02a a 6 54 030 b 6 54 036 c 6 54 03c d 6 54 042 e 6 54 048 f 6 54 04e 0 7 54 054 1 7 54 05b 2 7 54 062 3 7 54 069 4 7 54 070 5 7 54 077 6 7 54 07e 7 7 54 085 8 7 54 01c 9 7 54 023 a 7 54 02a b 7 54 031 c 7 54 038 d 7 54 03f e 7 54 046 f 7 54 04d 0 8 54 054 1 8 54 04c 2 8 54 044 3 8 54 03c 4 8 54 034 5 8 54 02c 6 8 54 024 7 8 54 01c 8 8 54 094 9 8 54 08c a 8 54 084 b 8 54 07c c 8 54 074 d 8 54 06c e 8 54 064 f 8 54 05c 0 9 54 054 1 9 54 04d 2 9 54 046 3 9 54 03f 4 9 54 038 5 9 54 031 6 9 54 02a 7 9 54 023 8 9 54 08c 9 9 54 085 a 9 54 07e b 9 54 077 c 9 54 070 d 9 54 069 e 9 54 062 f 9 54 05b 0 a 54 054 1 a 54 04e 2 a 54 048 3 a 54 042 4 a 54 03c 5 a 54 036 6 a 54 030 7 a 54 02a 8 a 54 084 9 a 54 07e a a 54 078 b a 54 072 c a 54 06c d a 54 066 e a 54 060 f a 54 05a 0 b 54 054 1 b 54 04f 2 b 54 04a 3 b 54 045 4 b 54 040 5 b 54 03b 6 b 54 036 7 b 54 031 8 b 54 07c 9 b 54 077 a b 54 072 b b 54 06d c b 54 068 d b 54 063 e b 54 05e f b 54 059 0 c 54 054 1 c 54 050 2 c 54 04c 3 c 54 048 4 c 54 044 5 c 54 040 6 c 54 03c 7 c 54 038 8 c 54 074 9 c 54 070 a c 54 06c b c 54 068 c c 54 064 d c 54 060 e c 54 05c f c 54 058 0 d 54 054 1 d 54 051 2 d 54 04e 3 d 54 04b 4 d 54 048 5 d 54 045 6 d 54 042 7 d 54 03f 8 d 54 06c 9 d 54 069 a d 54 066 b d 54 063 c d 54 060 d d 54 05d e d 54 05a f d 54 057 0 e 54 054 1 e 54 052 2 e 54 050 3 e 54 04e 4 e 54 04c 5 e 54 04a 6 e 54 048 7 e 54 046 8 e 54 064 9 e 54 062 a e 54 060 b e 54 05e c e 54 05c d e 54 05a e e 54 058 f e 54 056 0 f 54 054 1 f 54 053 2 f 54 052 3 f 54 051 4 f 54 050 5 f 54 04f 6 f 54 04e 7 f 54 04d 8 f 54 05c 9 f 54 05b a f 54 05a b f 54 059 c f 54 058 d f 54 057 e f 54 056 f f 54 055 0 0 55 055 1 0 55 055 2 0 55 055 3 0 55 055 4 0 55 055 5 0 55 055 6 0 55 055 7 0 55 055 8 0 55 055 9 0 55 055 a 0 55 055 b 0 55 055 c 0 55 055 d 0 55 055 e 0 55 055 f 0 55 055 0 1 55 055 1 1 55 056 2 1 55 057 3 1 55 058 4 1 55 059 5 1 55 05a 6 1 55 05b 7 1 55 05c 8 1 55 04d 9 1 55 04e a 1 55 04f b 1 55 050 c 1 55 051 d 1 55 052 e 1 55 053 f 1 55 054 0 2 55 055 1 2 55 057 2 2 55 059 3 2 55 05b 4 2 55 05d 5 2 55 05f 6 2 55 061 7 2 55 063 8 2 55 045 9 2 55 047 a 2 55 049 b 2 55 04b c 2 55 04d d 2 55 04f e 2 55 051 f 2 55 053 0 3 55 055 1 3 55 058 2 3 55 05b 3 3 55 05e 4 3 55 061 5 3 55 064 6 3 55 067 7 3 55 06a 8 3 55 03d 9 3 55 040 a 3 55 043 b 3 55 046 c 3 55 049 d 3 55 04c e 3 55 04f f 3 55 052 0 4 55 055 1 4 55 059 2 4 55 05d 3 4 55 061 4 4 55 065 5 4 55 069 6 4 55 06d 7 4 55 071 8 4 55 035 9 4 55 039 a 4 55 03d b 4 55 041 c 4 55 045 d 4 55 049 e 4 55 04d f 4 55 051 0 5 55 055 1 5 55 05a 2 5 55 05f 3 5 55 064 4 5 55 069 5 5 55 06e 6 5 55 073 7 5 55 078 8 5 55 02d 9 5 55 032 a 5 55 037 b 5 55 03c c 5 55 041 d 5 55 046 e 5 55 04b f 5 55 050 0 6 55 055 1 6 55 05b 2 6 55 061 3 6 55 067 4 6 55 06d 5 6 55 073 6 6 55 079 7 6 55 07f 8 6 55 025 9 6 55 02b a 6 55 031 b 6 55 037 c 6 55 03d d 6 55 043 e 6 55 049 f 6 55 04f 0 7 55 055 1 7 55 05c 2 7 55 063 3 7 55 06a 4 7 55 071 5 7 55 078 6 7 55 07f 7 7 55 086 8 7 55 01d 9 7 55 024 a 7 55 02b b 7 55 032 c 7 55 039 d 7 55 040 e 7 55 047 f 7 55 04e 0 8 55 055 1 8 55 04d 2 8 55 045 3 8 55 03d 4 8 55 035 5 8 55 02d 6 8 55 025 7 8 55 01d 8 8 55 095 9 8 55 08d a 8 55 085 b 8 55 07d c 8 55 075 d 8 55 06d e 8 55 065 f 8 55 05d 0 9 55 055 1 9 55 04e 2 9 55 047 3 9 55 040 4 9 55 039 5 9 55 032 6 9 55 02b 7 9 55 024 8 9 55 08d 9 9 55 086 a 9 55 07f b 9 55 078 c 9 55 071 d 9 55 06a e 9 55 063 f 9 55 05c 0 a 55 055 1 a 55 04f 2 a 55 049 3 a 55 043 4 a 55 03d 5 a 55 037 6 a 55 031 7 a 55 02b 8 a 55 085 9 a 55 07f a a 55 079 b a 55 073 c a 55 06d d a 55 067 e a 55 061 f a 55 05b 0 b 55 055 1 b 55 050 2 b 55 04b 3 b 55 046 4 b 55 041 5 b 55 03c 6 b 55 037 7 b 55 032 8 b 55 07d 9 b 55 078 a b 55 073 b b 55 06e c b 55 069 d b 55 064 e b 55 05f f b 55 05a 0 c 55 055 1 c 55 051 2 c 55 04d 3 c 55 049 4 c 55 045 5 c 55 041 6 c 55 03d 7 c 55 039 8 c 55 075 9 c 55 071 a c 55 06d b c 55 069 c c 55 065 d c 55 061 e c 55 05d f c 55 059 0 d 55 055 1 d 55 052 2 d 55 04f 3 d 55 04c 4 d 55 049 5 d 55 046 6 d 55 043 7 d 55 040 8 d 55 06d 9 d 55 06a a d 55 067 b d 55 064 c d 55 061 d d 55 05e e d 55 05b f d 55 058 0 e 55 055 1 e 55 053 2 e 55 051 3 e 55 04f 4 e 55 04d 5 e 55 04b 6 e 55 049 7 e 55 047 8 e 55 065 9 e 55 063 a e 55 061 b e 55 05f c e 55 05d d e 55 05b e e 55 059 f e 55 057 0 f 55 055 1 f 55 054 2 f 55 053 3 f 55 052 4 f 55 051 5 f 55 050 6 f 55 04f 7 f 55 04e 8 f 55 05d 9 f 55 05c a f 55 05b b f 55 05a c f 55 059 d f 55 058 e f 55 057 f f 55 056 0 0 56 056 1 0 56 056 2 0 56 056 3 0 56 056 4 0 56 056 5 0 56 056 6 0 56 056 7 0 56 056 8 0 56 056 9 0 56 056 a 0 56 056 b 0 56 056 c 0 56 056 d 0 56 056 e 0 56 056 f 0 56 056 0 1 56 056 1 1 56 057 2 1 56 058 3 1 56 059 4 1 56 05a 5 1 56 05b 6 1 56 05c 7 1 56 05d 8 1 56 04e 9 1 56 04f a 1 56 050 b 1 56 051 c 1 56 052 d 1 56 053 e 1 56 054 f 1 56 055 0 2 56 056 1 2 56 058 2 2 56 05a 3 2 56 05c 4 2 56 05e 5 2 56 060 6 2 56 062 7 2 56 064 8 2 56 046 9 2 56 048 a 2 56 04a b 2 56 04c c 2 56 04e d 2 56 050 e 2 56 052 f 2 56 054 0 3 56 056 1 3 56 059 2 3 56 05c 3 3 56 05f 4 3 56 062 5 3 56 065 6 3 56 068 7 3 56 06b 8 3 56 03e 9 3 56 041 a 3 56 044 b 3 56 047 c 3 56 04a d 3 56 04d e 3 56 050 f 3 56 053 0 4 56 056 1 4 56 05a 2 4 56 05e 3 4 56 062 4 4 56 066 5 4 56 06a 6 4 56 06e 7 4 56 072 8 4 56 036 9 4 56 03a a 4 56 03e b 4 56 042 c 4 56 046 d 4 56 04a e 4 56 04e f 4 56 052 0 5 56 056 1 5 56 05b 2 5 56 060 3 5 56 065 4 5 56 06a 5 5 56 06f 6 5 56 074 7 5 56 079 8 5 56 02e 9 5 56 033 a 5 56 038 b 5 56 03d c 5 56 042 d 5 56 047 e 5 56 04c f 5 56 051 0 6 56 056 1 6 56 05c 2 6 56 062 3 6 56 068 4 6 56 06e 5 6 56 074 6 6 56 07a 7 6 56 080 8 6 56 026 9 6 56 02c a 6 56 032 b 6 56 038 c 6 56 03e d 6 56 044 e 6 56 04a f 6 56 050 0 7 56 056 1 7 56 05d 2 7 56 064 3 7 56 06b 4 7 56 072 5 7 56 079 6 7 56 080 7 7 56 087 8 7 56 01e 9 7 56 025 a 7 56 02c b 7 56 033 c 7 56 03a d 7 56 041 e 7 56 048 f 7 56 04f 0 8 56 056 1 8 56 04e 2 8 56 046 3 8 56 03e 4 8 56 036 5 8 56 02e 6 8 56 026 7 8 56 01e 8 8 56 096 9 8 56 08e a 8 56 086 b 8 56 07e c 8 56 076 d 8 56 06e e 8 56 066 f 8 56 05e 0 9 56 056 1 9 56 04f 2 9 56 048 3 9 56 041 4 9 56 03a 5 9 56 033 6 9 56 02c 7 9 56 025 8 9 56 08e 9 9 56 087 a 9 56 080 b 9 56 079 c 9 56 072 d 9 56 06b e 9 56 064 f 9 56 05d 0 a 56 056 1 a 56 050 2 a 56 04a 3 a 56 044 4 a 56 03e 5 a 56 038 6 a 56 032 7 a 56 02c 8 a 56 086 9 a 56 080 a a 56 07a b a 56 074 c a 56 06e d a 56 068 e a 56 062 f a 56 05c 0 b 56 056 1 b 56 051 2 b 56 04c 3 b 56 047 4 b 56 042 5 b 56 03d 6 b 56 038 7 b 56 033 8 b 56 07e 9 b 56 079 a b 56 074 b b 56 06f c b 56 06a d b 56 065 e b 56 060 f b 56 05b 0 c 56 056 1 c 56 052 2 c 56 04e 3 c 56 04a 4 c 56 046 5 c 56 042 6 c 56 03e 7 c 56 03a 8 c 56 076 9 c 56 072 a c 56 06e b c 56 06a c c 56 066 d c 56 062 e c 56 05e f c 56 05a 0 d 56 056 1 d 56 053 2 d 56 050 3 d 56 04d 4 d 56 04a 5 d 56 047 6 d 56 044 7 d 56 041 8 d 56 06e 9 d 56 06b a d 56 068 b d 56 065 c d 56 062 d d 56 05f e d 56 05c f d 56 059 0 e 56 056 1 e 56 054 2 e 56 052 3 e 56 050 4 e 56 04e 5 e 56 04c 6 e 56 04a 7 e 56 048 8 e 56 066 9 e 56 064 a e 56 062 b e 56 060 c e 56 05e d e 56 05c e e 56 05a f e 56 058 0 f 56 056 1 f 56 055 2 f 56 054 3 f 56 053 4 f 56 052 5 f 56 051 6 f 56 050 7 f 56 04f 8 f 56 05e 9 f 56 05d a f 56 05c b f 56 05b c f 56 05a d f 56 059 e f 56 058 f f 56 057 0 0 57 057 1 0 57 057 2 0 57 057 3 0 57 057 4 0 57 057 5 0 57 057 6 0 57 057 7 0 57 057 8 0 57 057 9 0 57 057 a 0 57 057 b 0 57 057 c 0 57 057 d 0 57 057 e 0 57 057 f 0 57 057 0 1 57 057 1 1 57 058 2 1 57 059 3 1 57 05a 4 1 57 05b 5 1 57 05c 6 1 57 05d 7 1 57 05e 8 1 57 04f 9 1 57 050 a 1 57 051 b 1 57 052 c 1 57 053 d 1 57 054 e 1 57 055 f 1 57 056 0 2 57 057 1 2 57 059 2 2 57 05b 3 2 57 05d 4 2 57 05f 5 2 57 061 6 2 57 063 7 2 57 065 8 2 57 047 9 2 57 049 a 2 57 04b b 2 57 04d c 2 57 04f d 2 57 051 e 2 57 053 f 2 57 055 0 3 57 057 1 3 57 05a 2 3 57 05d 3 3 57 060 4 3 57 063 5 3 57 066 6 3 57 069 7 3 57 06c 8 3 57 03f 9 3 57 042 a 3 57 045 b 3 57 048 c 3 57 04b d 3 57 04e e 3 57 051 f 3 57 054 0 4 57 057 1 4 57 05b 2 4 57 05f 3 4 57 063 4 4 57 067 5 4 57 06b 6 4 57 06f 7 4 57 073 8 4 57 037 9 4 57 03b a 4 57 03f b 4 57 043 c 4 57 047 d 4 57 04b e 4 57 04f f 4 57 053 0 5 57 057 1 5 57 05c 2 5 57 061 3 5 57 066 4 5 57 06b 5 5 57 070 6 5 57 075 7 5 57 07a 8 5 57 02f 9 5 57 034 a 5 57 039 b 5 57 03e c 5 57 043 d 5 57 048 e 5 57 04d f 5 57 052 0 6 57 057 1 6 57 05d 2 6 57 063 3 6 57 069 4 6 57 06f 5 6 57 075 6 6 57 07b 7 6 57 081 8 6 57 027 9 6 57 02d a 6 57 033 b 6 57 039 c 6 57 03f d 6 57 045 e 6 57 04b f 6 57 051 0 7 57 057 1 7 57 05e 2 7 57 065 3 7 57 06c 4 7 57 073 5 7 57 07a 6 7 57 081 7 7 57 088 8 7 57 01f 9 7 57 026 a 7 57 02d b 7 57 034 c 7 57 03b d 7 57 042 e 7 57 049 f 7 57 050 0 8 57 057 1 8 57 04f 2 8 57 047 3 8 57 03f 4 8 57 037 5 8 57 02f 6 8 57 027 7 8 57 01f 8 8 57 097 9 8 57 08f a 8 57 087 b 8 57 07f c 8 57 077 d 8 57 06f e 8 57 067 f 8 57 05f 0 9 57 057 1 9 57 050 2 9 57 049 3 9 57 042 4 9 57 03b 5 9 57 034 6 9 57 02d 7 9 57 026 8 9 57 08f 9 9 57 088 a 9 57 081 b 9 57 07a c 9 57 073 d 9 57 06c e 9 57 065 f 9 57 05e 0 a 57 057 1 a 57 051 2 a 57 04b 3 a 57 045 4 a 57 03f 5 a 57 039 6 a 57 033 7 a 57 02d 8 a 57 087 9 a 57 081 a a 57 07b b a 57 075 c a 57 06f d a 57 069 e a 57 063 f a 57 05d 0 b 57 057 1 b 57 052 2 b 57 04d 3 b 57 048 4 b 57 043 5 b 57 03e 6 b 57 039 7 b 57 034 8 b 57 07f 9 b 57 07a a b 57 075 b b 57 070 c b 57 06b d b 57 066 e b 57 061 f b 57 05c 0 c 57 057 1 c 57 053 2 c 57 04f 3 c 57 04b 4 c 57 047 5 c 57 043 6 c 57 03f 7 c 57 03b 8 c 57 077 9 c 57 073 a c 57 06f b c 57 06b c c 57 067 d c 57 063 e c 57 05f f c 57 05b 0 d 57 057 1 d 57 054 2 d 57 051 3 d 57 04e 4 d 57 04b 5 d 57 048 6 d 57 045 7 d 57 042 8 d 57 06f 9 d 57 06c a d 57 069 b d 57 066 c d 57 063 d d 57 060 e d 57 05d f d 57 05a 0 e 57 057 1 e 57 055 2 e 57 053 3 e 57 051 4 e 57 04f 5 e 57 04d 6 e 57 04b 7 e 57 049 8 e 57 067 9 e 57 065 a e 57 063 b e 57 061 c e 57 05f d e 57 05d e e 57 05b f e 57 059 0 f 57 057 1 f 57 056 2 f 57 055 3 f 57 054 4 f 57 053 5 f 57 052 6 f 57 051 7 f 57 050 8 f 57 05f 9 f 57 05e a f 57 05d b f 57 05c c f 57 05b d f 57 05a e f 57 059 f f 57 058 0 0 58 058 1 0 58 058 2 0 58 058 3 0 58 058 4 0 58 058 5 0 58 058 6 0 58 058 7 0 58 058 8 0 58 058 9 0 58 058 a 0 58 058 b 0 58 058 c 0 58 058 d 0 58 058 e 0 58 058 f 0 58 058 0 1 58 058 1 1 58 059 2 1 58 05a 3 1 58 05b 4 1 58 05c 5 1 58 05d 6 1 58 05e 7 1 58 05f 8 1 58 050 9 1 58 051 a 1 58 052 b 1 58 053 c 1 58 054 d 1 58 055 e 1 58 056 f 1 58 057 0 2 58 058 1 2 58 05a 2 2 58 05c 3 2 58 05e 4 2 58 060 5 2 58 062 6 2 58 064 7 2 58 066 8 2 58 048 9 2 58 04a a 2 58 04c b 2 58 04e c 2 58 050 d 2 58 052 e 2 58 054 f 2 58 056 0 3 58 058 1 3 58 05b 2 3 58 05e 3 3 58 061 4 3 58 064 5 3 58 067 6 3 58 06a 7 3 58 06d 8 3 58 040 9 3 58 043 a 3 58 046 b 3 58 049 c 3 58 04c d 3 58 04f e 3 58 052 f 3 58 055 0 4 58 058 1 4 58 05c 2 4 58 060 3 4 58 064 4 4 58 068 5 4 58 06c 6 4 58 070 7 4 58 074 8 4 58 038 9 4 58 03c a 4 58 040 b 4 58 044 c 4 58 048 d 4 58 04c e 4 58 050 f 4 58 054 0 5 58 058 1 5 58 05d 2 5 58 062 3 5 58 067 4 5 58 06c 5 5 58 071 6 5 58 076 7 5 58 07b 8 5 58 030 9 5 58 035 a 5 58 03a b 5 58 03f c 5 58 044 d 5 58 049 e 5 58 04e f 5 58 053 0 6 58 058 1 6 58 05e 2 6 58 064 3 6 58 06a 4 6 58 070 5 6 58 076 6 6 58 07c 7 6 58 082 8 6 58 028 9 6 58 02e a 6 58 034 b 6 58 03a c 6 58 040 d 6 58 046 e 6 58 04c f 6 58 052 0 7 58 058 1 7 58 05f 2 7 58 066 3 7 58 06d 4 7 58 074 5 7 58 07b 6 7 58 082 7 7 58 089 8 7 58 020 9 7 58 027 a 7 58 02e b 7 58 035 c 7 58 03c d 7 58 043 e 7 58 04a f 7 58 051 0 8 58 058 1 8 58 050 2 8 58 048 3 8 58 040 4 8 58 038 5 8 58 030 6 8 58 028 7 8 58 020 8 8 58 098 9 8 58 090 a 8 58 088 b 8 58 080 c 8 58 078 d 8 58 070 e 8 58 068 f 8 58 060 0 9 58 058 1 9 58 051 2 9 58 04a 3 9 58 043 4 9 58 03c 5 9 58 035 6 9 58 02e 7 9 58 027 8 9 58 090 9 9 58 089 a 9 58 082 b 9 58 07b c 9 58 074 d 9 58 06d e 9 58 066 f 9 58 05f 0 a 58 058 1 a 58 052 2 a 58 04c 3 a 58 046 4 a 58 040 5 a 58 03a 6 a 58 034 7 a 58 02e 8 a 58 088 9 a 58 082 a a 58 07c b a 58 076 c a 58 070 d a 58 06a e a 58 064 f a 58 05e 0 b 58 058 1 b 58 053 2 b 58 04e 3 b 58 049 4 b 58 044 5 b 58 03f 6 b 58 03a 7 b 58 035 8 b 58 080 9 b 58 07b a b 58 076 b b 58 071 c b 58 06c d b 58 067 e b 58 062 f b 58 05d 0 c 58 058 1 c 58 054 2 c 58 050 3 c 58 04c 4 c 58 048 5 c 58 044 6 c 58 040 7 c 58 03c 8 c 58 078 9 c 58 074 a c 58 070 b c 58 06c c c 58 068 d c 58 064 e c 58 060 f c 58 05c 0 d 58 058 1 d 58 055 2 d 58 052 3 d 58 04f 4 d 58 04c 5 d 58 049 6 d 58 046 7 d 58 043 8 d 58 070 9 d 58 06d a d 58 06a b d 58 067 c d 58 064 d d 58 061 e d 58 05e f d 58 05b 0 e 58 058 1 e 58 056 2 e 58 054 3 e 58 052 4 e 58 050 5 e 58 04e 6 e 58 04c 7 e 58 04a 8 e 58 068 9 e 58 066 a e 58 064 b e 58 062 c e 58 060 d e 58 05e e e 58 05c f e 58 05a 0 f 58 058 1 f 58 057 2 f 58 056 3 f 58 055 4 f 58 054 5 f 58 053 6 f 58 052 7 f 58 051 8 f 58 060 9 f 58 05f a f 58 05e b f 58 05d c f 58 05c d f 58 05b e f 58 05a f f 58 059 0 0 59 059 1 0 59 059 2 0 59 059 3 0 59 059 4 0 59 059 5 0 59 059 6 0 59 059 7 0 59 059 8 0 59 059 9 0 59 059 a 0 59 059 b 0 59 059 c 0 59 059 d 0 59 059 e 0 59 059 f 0 59 059 0 1 59 059 1 1 59 05a 2 1 59 05b 3 1 59 05c 4 1 59 05d 5 1 59 05e 6 1 59 05f 7 1 59 060 8 1 59 051 9 1 59 052 a 1 59 053 b 1 59 054 c 1 59 055 d 1 59 056 e 1 59 057 f 1 59 058 0 2 59 059 1 2 59 05b 2 2 59 05d 3 2 59 05f 4 2 59 061 5 2 59 063 6 2 59 065 7 2 59 067 8 2 59 049 9 2 59 04b a 2 59 04d b 2 59 04f c 2 59 051 d 2 59 053 e 2 59 055 f 2 59 057 0 3 59 059 1 3 59 05c 2 3 59 05f 3 3 59 062 4 3 59 065 5 3 59 068 6 3 59 06b 7 3 59 06e 8 3 59 041 9 3 59 044 a 3 59 047 b 3 59 04a c 3 59 04d d 3 59 050 e 3 59 053 f 3 59 056 0 4 59 059 1 4 59 05d 2 4 59 061 3 4 59 065 4 4 59 069 5 4 59 06d 6 4 59 071 7 4 59 075 8 4 59 039 9 4 59 03d a 4 59 041 b 4 59 045 c 4 59 049 d 4 59 04d e 4 59 051 f 4 59 055 0 5 59 059 1 5 59 05e 2 5 59 063 3 5 59 068 4 5 59 06d 5 5 59 072 6 5 59 077 7 5 59 07c 8 5 59 031 9 5 59 036 a 5 59 03b b 5 59 040 c 5 59 045 d 5 59 04a e 5 59 04f f 5 59 054 0 6 59 059 1 6 59 05f 2 6 59 065 3 6 59 06b 4 6 59 071 5 6 59 077 6 6 59 07d 7 6 59 083 8 6 59 029 9 6 59 02f a 6 59 035 b 6 59 03b c 6 59 041 d 6 59 047 e 6 59 04d f 6 59 053 0 7 59 059 1 7 59 060 2 7 59 067 3 7 59 06e 4 7 59 075 5 7 59 07c 6 7 59 083 7 7 59 08a 8 7 59 021 9 7 59 028 a 7 59 02f b 7 59 036 c 7 59 03d d 7 59 044 e 7 59 04b f 7 59 052 0 8 59 059 1 8 59 051 2 8 59 049 3 8 59 041 4 8 59 039 5 8 59 031 6 8 59 029 7 8 59 021 8 8 59 099 9 8 59 091 a 8 59 089 b 8 59 081 c 8 59 079 d 8 59 071 e 8 59 069 f 8 59 061 0 9 59 059 1 9 59 052 2 9 59 04b 3 9 59 044 4 9 59 03d 5 9 59 036 6 9 59 02f 7 9 59 028 8 9 59 091 9 9 59 08a a 9 59 083 b 9 59 07c c 9 59 075 d 9 59 06e e 9 59 067 f 9 59 060 0 a 59 059 1 a 59 053 2 a 59 04d 3 a 59 047 4 a 59 041 5 a 59 03b 6 a 59 035 7 a 59 02f 8 a 59 089 9 a 59 083 a a 59 07d b a 59 077 c a 59 071 d a 59 06b e a 59 065 f a 59 05f 0 b 59 059 1 b 59 054 2 b 59 04f 3 b 59 04a 4 b 59 045 5 b 59 040 6 b 59 03b 7 b 59 036 8 b 59 081 9 b 59 07c a b 59 077 b b 59 072 c b 59 06d d b 59 068 e b 59 063 f b 59 05e 0 c 59 059 1 c 59 055 2 c 59 051 3 c 59 04d 4 c 59 049 5 c 59 045 6 c 59 041 7 c 59 03d 8 c 59 079 9 c 59 075 a c 59 071 b c 59 06d c c 59 069 d c 59 065 e c 59 061 f c 59 05d 0 d 59 059 1 d 59 056 2 d 59 053 3 d 59 050 4 d 59 04d 5 d 59 04a 6 d 59 047 7 d 59 044 8 d 59 071 9 d 59 06e a d 59 06b b d 59 068 c d 59 065 d d 59 062 e d 59 05f f d 59 05c 0 e 59 059 1 e 59 057 2 e 59 055 3 e 59 053 4 e 59 051 5 e 59 04f 6 e 59 04d 7 e 59 04b 8 e 59 069 9 e 59 067 a e 59 065 b e 59 063 c e 59 061 d e 59 05f e e 59 05d f e 59 05b 0 f 59 059 1 f 59 058 2 f 59 057 3 f 59 056 4 f 59 055 5 f 59 054 6 f 59 053 7 f 59 052 8 f 59 061 9 f 59 060 a f 59 05f b f 59 05e c f 59 05d d f 59 05c e f 59 05b f f 59 05a 0 0 5a 05a 1 0 5a 05a 2 0 5a 05a 3 0 5a 05a 4 0 5a 05a 5 0 5a 05a 6 0 5a 05a 7 0 5a 05a 8 0 5a 05a 9 0 5a 05a a 0 5a 05a b 0 5a 05a c 0 5a 05a d 0 5a 05a e 0 5a 05a f 0 5a 05a 0 1 5a 05a 1 1 5a 05b 2 1 5a 05c 3 1 5a 05d 4 1 5a 05e 5 1 5a 05f 6 1 5a 060 7 1 5a 061 8 1 5a 052 9 1 5a 053 a 1 5a 054 b 1 5a 055 c 1 5a 056 d 1 5a 057 e 1 5a 058 f 1 5a 059 0 2 5a 05a 1 2 5a 05c 2 2 5a 05e 3 2 5a 060 4 2 5a 062 5 2 5a 064 6 2 5a 066 7 2 5a 068 8 2 5a 04a 9 2 5a 04c a 2 5a 04e b 2 5a 050 c 2 5a 052 d 2 5a 054 e 2 5a 056 f 2 5a 058 0 3 5a 05a 1 3 5a 05d 2 3 5a 060 3 3 5a 063 4 3 5a 066 5 3 5a 069 6 3 5a 06c 7 3 5a 06f 8 3 5a 042 9 3 5a 045 a 3 5a 048 b 3 5a 04b c 3 5a 04e d 3 5a 051 e 3 5a 054 f 3 5a 057 0 4 5a 05a 1 4 5a 05e 2 4 5a 062 3 4 5a 066 4 4 5a 06a 5 4 5a 06e 6 4 5a 072 7 4 5a 076 8 4 5a 03a 9 4 5a 03e a 4 5a 042 b 4 5a 046 c 4 5a 04a d 4 5a 04e e 4 5a 052 f 4 5a 056 0 5 5a 05a 1 5 5a 05f 2 5 5a 064 3 5 5a 069 4 5 5a 06e 5 5 5a 073 6 5 5a 078 7 5 5a 07d 8 5 5a 032 9 5 5a 037 a 5 5a 03c b 5 5a 041 c 5 5a 046 d 5 5a 04b e 5 5a 050 f 5 5a 055 0 6 5a 05a 1 6 5a 060 2 6 5a 066 3 6 5a 06c 4 6 5a 072 5 6 5a 078 6 6 5a 07e 7 6 5a 084 8 6 5a 02a 9 6 5a 030 a 6 5a 036 b 6 5a 03c c 6 5a 042 d 6 5a 048 e 6 5a 04e f 6 5a 054 0 7 5a 05a 1 7 5a 061 2 7 5a 068 3 7 5a 06f 4 7 5a 076 5 7 5a 07d 6 7 5a 084 7 7 5a 08b 8 7 5a 022 9 7 5a 029 a 7 5a 030 b 7 5a 037 c 7 5a 03e d 7 5a 045 e 7 5a 04c f 7 5a 053 0 8 5a 05a 1 8 5a 052 2 8 5a 04a 3 8 5a 042 4 8 5a 03a 5 8 5a 032 6 8 5a 02a 7 8 5a 022 8 8 5a 09a 9 8 5a 092 a 8 5a 08a b 8 5a 082 c 8 5a 07a d 8 5a 072 e 8 5a 06a f 8 5a 062 0 9 5a 05a 1 9 5a 053 2 9 5a 04c 3 9 5a 045 4 9 5a 03e 5 9 5a 037 6 9 5a 030 7 9 5a 029 8 9 5a 092 9 9 5a 08b a 9 5a 084 b 9 5a 07d c 9 5a 076 d 9 5a 06f e 9 5a 068 f 9 5a 061 0 a 5a 05a 1 a 5a 054 2 a 5a 04e 3 a 5a 048 4 a 5a 042 5 a 5a 03c 6 a 5a 036 7 a 5a 030 8 a 5a 08a 9 a 5a 084 a a 5a 07e b a 5a 078 c a 5a 072 d a 5a 06c e a 5a 066 f a 5a 060 0 b 5a 05a 1 b 5a 055 2 b 5a 050 3 b 5a 04b 4 b 5a 046 5 b 5a 041 6 b 5a 03c 7 b 5a 037 8 b 5a 082 9 b 5a 07d a b 5a 078 b b 5a 073 c b 5a 06e d b 5a 069 e b 5a 064 f b 5a 05f 0 c 5a 05a 1 c 5a 056 2 c 5a 052 3 c 5a 04e 4 c 5a 04a 5 c 5a 046 6 c 5a 042 7 c 5a 03e 8 c 5a 07a 9 c 5a 076 a c 5a 072 b c 5a 06e c c 5a 06a d c 5a 066 e c 5a 062 f c 5a 05e 0 d 5a 05a 1 d 5a 057 2 d 5a 054 3 d 5a 051 4 d 5a 04e 5 d 5a 04b 6 d 5a 048 7 d 5a 045 8 d 5a 072 9 d 5a 06f a d 5a 06c b d 5a 069 c d 5a 066 d d 5a 063 e d 5a 060 f d 5a 05d 0 e 5a 05a 1 e 5a 058 2 e 5a 056 3 e 5a 054 4 e 5a 052 5 e 5a 050 6 e 5a 04e 7 e 5a 04c 8 e 5a 06a 9 e 5a 068 a e 5a 066 b e 5a 064 c e 5a 062 d e 5a 060 e e 5a 05e f e 5a 05c 0 f 5a 05a 1 f 5a 059 2 f 5a 058 3 f 5a 057 4 f 5a 056 5 f 5a 055 6 f 5a 054 7 f 5a 053 8 f 5a 062 9 f 5a 061 a f 5a 060 b f 5a 05f c f 5a 05e d f 5a 05d e f 5a 05c f f 5a 05b 0 0 5b 05b 1 0 5b 05b 2 0 5b 05b 3 0 5b 05b 4 0 5b 05b 5 0 5b 05b 6 0 5b 05b 7 0 5b 05b 8 0 5b 05b 9 0 5b 05b a 0 5b 05b b 0 5b 05b c 0 5b 05b d 0 5b 05b e 0 5b 05b f 0 5b 05b 0 1 5b 05b 1 1 5b 05c 2 1 5b 05d 3 1 5b 05e 4 1 5b 05f 5 1 5b 060 6 1 5b 061 7 1 5b 062 8 1 5b 053 9 1 5b 054 a 1 5b 055 b 1 5b 056 c 1 5b 057 d 1 5b 058 e 1 5b 059 f 1 5b 05a 0 2 5b 05b 1 2 5b 05d 2 2 5b 05f 3 2 5b 061 4 2 5b 063 5 2 5b 065 6 2 5b 067 7 2 5b 069 8 2 5b 04b 9 2 5b 04d a 2 5b 04f b 2 5b 051 c 2 5b 053 d 2 5b 055 e 2 5b 057 f 2 5b 059 0 3 5b 05b 1 3 5b 05e 2 3 5b 061 3 3 5b 064 4 3 5b 067 5 3 5b 06a 6 3 5b 06d 7 3 5b 070 8 3 5b 043 9 3 5b 046 a 3 5b 049 b 3 5b 04c c 3 5b 04f d 3 5b 052 e 3 5b 055 f 3 5b 058 0 4 5b 05b 1 4 5b 05f 2 4 5b 063 3 4 5b 067 4 4 5b 06b 5 4 5b 06f 6 4 5b 073 7 4 5b 077 8 4 5b 03b 9 4 5b 03f a 4 5b 043 b 4 5b 047 c 4 5b 04b d 4 5b 04f e 4 5b 053 f 4 5b 057 0 5 5b 05b 1 5 5b 060 2 5 5b 065 3 5 5b 06a 4 5 5b 06f 5 5 5b 074 6 5 5b 079 7 5 5b 07e 8 5 5b 033 9 5 5b 038 a 5 5b 03d b 5 5b 042 c 5 5b 047 d 5 5b 04c e 5 5b 051 f 5 5b 056 0 6 5b 05b 1 6 5b 061 2 6 5b 067 3 6 5b 06d 4 6 5b 073 5 6 5b 079 6 6 5b 07f 7 6 5b 085 8 6 5b 02b 9 6 5b 031 a 6 5b 037 b 6 5b 03d c 6 5b 043 d 6 5b 049 e 6 5b 04f f 6 5b 055 0 7 5b 05b 1 7 5b 062 2 7 5b 069 3 7 5b 070 4 7 5b 077 5 7 5b 07e 6 7 5b 085 7 7 5b 08c 8 7 5b 023 9 7 5b 02a a 7 5b 031 b 7 5b 038 c 7 5b 03f d 7 5b 046 e 7 5b 04d f 7 5b 054 0 8 5b 05b 1 8 5b 053 2 8 5b 04b 3 8 5b 043 4 8 5b 03b 5 8 5b 033 6 8 5b 02b 7 8 5b 023 8 8 5b 09b 9 8 5b 093 a 8 5b 08b b 8 5b 083 c 8 5b 07b d 8 5b 073 e 8 5b 06b f 8 5b 063 0 9 5b 05b 1 9 5b 054 2 9 5b 04d 3 9 5b 046 4 9 5b 03f 5 9 5b 038 6 9 5b 031 7 9 5b 02a 8 9 5b 093 9 9 5b 08c a 9 5b 085 b 9 5b 07e c 9 5b 077 d 9 5b 070 e 9 5b 069 f 9 5b 062 0 a 5b 05b 1 a 5b 055 2 a 5b 04f 3 a 5b 049 4 a 5b 043 5 a 5b 03d 6 a 5b 037 7 a 5b 031 8 a 5b 08b 9 a 5b 085 a a 5b 07f b a 5b 079 c a 5b 073 d a 5b 06d e a 5b 067 f a 5b 061 0 b 5b 05b 1 b 5b 056 2 b 5b 051 3 b 5b 04c 4 b 5b 047 5 b 5b 042 6 b 5b 03d 7 b 5b 038 8 b 5b 083 9 b 5b 07e a b 5b 079 b b 5b 074 c b 5b 06f d b 5b 06a e b 5b 065 f b 5b 060 0 c 5b 05b 1 c 5b 057 2 c 5b 053 3 c 5b 04f 4 c 5b 04b 5 c 5b 047 6 c 5b 043 7 c 5b 03f 8 c 5b 07b 9 c 5b 077 a c 5b 073 b c 5b 06f c c 5b 06b d c 5b 067 e c 5b 063 f c 5b 05f 0 d 5b 05b 1 d 5b 058 2 d 5b 055 3 d 5b 052 4 d 5b 04f 5 d 5b 04c 6 d 5b 049 7 d 5b 046 8 d 5b 073 9 d 5b 070 a d 5b 06d b d 5b 06a c d 5b 067 d d 5b 064 e d 5b 061 f d 5b 05e 0 e 5b 05b 1 e 5b 059 2 e 5b 057 3 e 5b 055 4 e 5b 053 5 e 5b 051 6 e 5b 04f 7 e 5b 04d 8 e 5b 06b 9 e 5b 069 a e 5b 067 b e 5b 065 c e 5b 063 d e 5b 061 e e 5b 05f f e 5b 05d 0 f 5b 05b 1 f 5b 05a 2 f 5b 059 3 f 5b 058 4 f 5b 057 5 f 5b 056 6 f 5b 055 7 f 5b 054 8 f 5b 063 9 f 5b 062 a f 5b 061 b f 5b 060 c f 5b 05f d f 5b 05e e f 5b 05d f f 5b 05c 0 0 5c 05c 1 0 5c 05c 2 0 5c 05c 3 0 5c 05c 4 0 5c 05c 5 0 5c 05c 6 0 5c 05c 7 0 5c 05c 8 0 5c 05c 9 0 5c 05c a 0 5c 05c b 0 5c 05c c 0 5c 05c d 0 5c 05c e 0 5c 05c f 0 5c 05c 0 1 5c 05c 1 1 5c 05d 2 1 5c 05e 3 1 5c 05f 4 1 5c 060 5 1 5c 061 6 1 5c 062 7 1 5c 063 8 1 5c 054 9 1 5c 055 a 1 5c 056 b 1 5c 057 c 1 5c 058 d 1 5c 059 e 1 5c 05a f 1 5c 05b 0 2 5c 05c 1 2 5c 05e 2 2 5c 060 3 2 5c 062 4 2 5c 064 5 2 5c 066 6 2 5c 068 7 2 5c 06a 8 2 5c 04c 9 2 5c 04e a 2 5c 050 b 2 5c 052 c 2 5c 054 d 2 5c 056 e 2 5c 058 f 2 5c 05a 0 3 5c 05c 1 3 5c 05f 2 3 5c 062 3 3 5c 065 4 3 5c 068 5 3 5c 06b 6 3 5c 06e 7 3 5c 071 8 3 5c 044 9 3 5c 047 a 3 5c 04a b 3 5c 04d c 3 5c 050 d 3 5c 053 e 3 5c 056 f 3 5c 059 0 4 5c 05c 1 4 5c 060 2 4 5c 064 3 4 5c 068 4 4 5c 06c 5 4 5c 070 6 4 5c 074 7 4 5c 078 8 4 5c 03c 9 4 5c 040 a 4 5c 044 b 4 5c 048 c 4 5c 04c d 4 5c 050 e 4 5c 054 f 4 5c 058 0 5 5c 05c 1 5 5c 061 2 5 5c 066 3 5 5c 06b 4 5 5c 070 5 5 5c 075 6 5 5c 07a 7 5 5c 07f 8 5 5c 034 9 5 5c 039 a 5 5c 03e b 5 5c 043 c 5 5c 048 d 5 5c 04d e 5 5c 052 f 5 5c 057 0 6 5c 05c 1 6 5c 062 2 6 5c 068 3 6 5c 06e 4 6 5c 074 5 6 5c 07a 6 6 5c 080 7 6 5c 086 8 6 5c 02c 9 6 5c 032 a 6 5c 038 b 6 5c 03e c 6 5c 044 d 6 5c 04a e 6 5c 050 f 6 5c 056 0 7 5c 05c 1 7 5c 063 2 7 5c 06a 3 7 5c 071 4 7 5c 078 5 7 5c 07f 6 7 5c 086 7 7 5c 08d 8 7 5c 024 9 7 5c 02b a 7 5c 032 b 7 5c 039 c 7 5c 040 d 7 5c 047 e 7 5c 04e f 7 5c 055 0 8 5c 05c 1 8 5c 054 2 8 5c 04c 3 8 5c 044 4 8 5c 03c 5 8 5c 034 6 8 5c 02c 7 8 5c 024 8 8 5c 09c 9 8 5c 094 a 8 5c 08c b 8 5c 084 c 8 5c 07c d 8 5c 074 e 8 5c 06c f 8 5c 064 0 9 5c 05c 1 9 5c 055 2 9 5c 04e 3 9 5c 047 4 9 5c 040 5 9 5c 039 6 9 5c 032 7 9 5c 02b 8 9 5c 094 9 9 5c 08d a 9 5c 086 b 9 5c 07f c 9 5c 078 d 9 5c 071 e 9 5c 06a f 9 5c 063 0 a 5c 05c 1 a 5c 056 2 a 5c 050 3 a 5c 04a 4 a 5c 044 5 a 5c 03e 6 a 5c 038 7 a 5c 032 8 a 5c 08c 9 a 5c 086 a a 5c 080 b a 5c 07a c a 5c 074 d a 5c 06e e a 5c 068 f a 5c 062 0 b 5c 05c 1 b 5c 057 2 b 5c 052 3 b 5c 04d 4 b 5c 048 5 b 5c 043 6 b 5c 03e 7 b 5c 039 8 b 5c 084 9 b 5c 07f a b 5c 07a b b 5c 075 c b 5c 070 d b 5c 06b e b 5c 066 f b 5c 061 0 c 5c 05c 1 c 5c 058 2 c 5c 054 3 c 5c 050 4 c 5c 04c 5 c 5c 048 6 c 5c 044 7 c 5c 040 8 c 5c 07c 9 c 5c 078 a c 5c 074 b c 5c 070 c c 5c 06c d c 5c 068 e c 5c 064 f c 5c 060 0 d 5c 05c 1 d 5c 059 2 d 5c 056 3 d 5c 053 4 d 5c 050 5 d 5c 04d 6 d 5c 04a 7 d 5c 047 8 d 5c 074 9 d 5c 071 a d 5c 06e b d 5c 06b c d 5c 068 d d 5c 065 e d 5c 062 f d 5c 05f 0 e 5c 05c 1 e 5c 05a 2 e 5c 058 3 e 5c 056 4 e 5c 054 5 e 5c 052 6 e 5c 050 7 e 5c 04e 8 e 5c 06c 9 e 5c 06a a e 5c 068 b e 5c 066 c e 5c 064 d e 5c 062 e e 5c 060 f e 5c 05e 0 f 5c 05c 1 f 5c 05b 2 f 5c 05a 3 f 5c 059 4 f 5c 058 5 f 5c 057 6 f 5c 056 7 f 5c 055 8 f 5c 064 9 f 5c 063 a f 5c 062 b f 5c 061 c f 5c 060 d f 5c 05f e f 5c 05e f f 5c 05d 0 0 5d 05d 1 0 5d 05d 2 0 5d 05d 3 0 5d 05d 4 0 5d 05d 5 0 5d 05d 6 0 5d 05d 7 0 5d 05d 8 0 5d 05d 9 0 5d 05d a 0 5d 05d b 0 5d 05d c 0 5d 05d d 0 5d 05d e 0 5d 05d f 0 5d 05d 0 1 5d 05d 1 1 5d 05e 2 1 5d 05f 3 1 5d 060 4 1 5d 061 5 1 5d 062 6 1 5d 063 7 1 5d 064 8 1 5d 055 9 1 5d 056 a 1 5d 057 b 1 5d 058 c 1 5d 059 d 1 5d 05a e 1 5d 05b f 1 5d 05c 0 2 5d 05d 1 2 5d 05f 2 2 5d 061 3 2 5d 063 4 2 5d 065 5 2 5d 067 6 2 5d 069 7 2 5d 06b 8 2 5d 04d 9 2 5d 04f a 2 5d 051 b 2 5d 053 c 2 5d 055 d 2 5d 057 e 2 5d 059 f 2 5d 05b 0 3 5d 05d 1 3 5d 060 2 3 5d 063 3 3 5d 066 4 3 5d 069 5 3 5d 06c 6 3 5d 06f 7 3 5d 072 8 3 5d 045 9 3 5d 048 a 3 5d 04b b 3 5d 04e c 3 5d 051 d 3 5d 054 e 3 5d 057 f 3 5d 05a 0 4 5d 05d 1 4 5d 061 2 4 5d 065 3 4 5d 069 4 4 5d 06d 5 4 5d 071 6 4 5d 075 7 4 5d 079 8 4 5d 03d 9 4 5d 041 a 4 5d 045 b 4 5d 049 c 4 5d 04d d 4 5d 051 e 4 5d 055 f 4 5d 059 0 5 5d 05d 1 5 5d 062 2 5 5d 067 3 5 5d 06c 4 5 5d 071 5 5 5d 076 6 5 5d 07b 7 5 5d 080 8 5 5d 035 9 5 5d 03a a 5 5d 03f b 5 5d 044 c 5 5d 049 d 5 5d 04e e 5 5d 053 f 5 5d 058 0 6 5d 05d 1 6 5d 063 2 6 5d 069 3 6 5d 06f 4 6 5d 075 5 6 5d 07b 6 6 5d 081 7 6 5d 087 8 6 5d 02d 9 6 5d 033 a 6 5d 039 b 6 5d 03f c 6 5d 045 d 6 5d 04b e 6 5d 051 f 6 5d 057 0 7 5d 05d 1 7 5d 064 2 7 5d 06b 3 7 5d 072 4 7 5d 079 5 7 5d 080 6 7 5d 087 7 7 5d 08e 8 7 5d 025 9 7 5d 02c a 7 5d 033 b 7 5d 03a c 7 5d 041 d 7 5d 048 e 7 5d 04f f 7 5d 056 0 8 5d 05d 1 8 5d 055 2 8 5d 04d 3 8 5d 045 4 8 5d 03d 5 8 5d 035 6 8 5d 02d 7 8 5d 025 8 8 5d 09d 9 8 5d 095 a 8 5d 08d b 8 5d 085 c 8 5d 07d d 8 5d 075 e 8 5d 06d f 8 5d 065 0 9 5d 05d 1 9 5d 056 2 9 5d 04f 3 9 5d 048 4 9 5d 041 5 9 5d 03a 6 9 5d 033 7 9 5d 02c 8 9 5d 095 9 9 5d 08e a 9 5d 087 b 9 5d 080 c 9 5d 079 d 9 5d 072 e 9 5d 06b f 9 5d 064 0 a 5d 05d 1 a 5d 057 2 a 5d 051 3 a 5d 04b 4 a 5d 045 5 a 5d 03f 6 a 5d 039 7 a 5d 033 8 a 5d 08d 9 a 5d 087 a a 5d 081 b a 5d 07b c a 5d 075 d a 5d 06f e a 5d 069 f a 5d 063 0 b 5d 05d 1 b 5d 058 2 b 5d 053 3 b 5d 04e 4 b 5d 049 5 b 5d 044 6 b 5d 03f 7 b 5d 03a 8 b 5d 085 9 b 5d 080 a b 5d 07b b b 5d 076 c b 5d 071 d b 5d 06c e b 5d 067 f b 5d 062 0 c 5d 05d 1 c 5d 059 2 c 5d 055 3 c 5d 051 4 c 5d 04d 5 c 5d 049 6 c 5d 045 7 c 5d 041 8 c 5d 07d 9 c 5d 079 a c 5d 075 b c 5d 071 c c 5d 06d d c 5d 069 e c 5d 065 f c 5d 061 0 d 5d 05d 1 d 5d 05a 2 d 5d 057 3 d 5d 054 4 d 5d 051 5 d 5d 04e 6 d 5d 04b 7 d 5d 048 8 d 5d 075 9 d 5d 072 a d 5d 06f b d 5d 06c c d 5d 069 d d 5d 066 e d 5d 063 f d 5d 060 0 e 5d 05d 1 e 5d 05b 2 e 5d 059 3 e 5d 057 4 e 5d 055 5 e 5d 053 6 e 5d 051 7 e 5d 04f 8 e 5d 06d 9 e 5d 06b a e 5d 069 b e 5d 067 c e 5d 065 d e 5d 063 e e 5d 061 f e 5d 05f 0 f 5d 05d 1 f 5d 05c 2 f 5d 05b 3 f 5d 05a 4 f 5d 059 5 f 5d 058 6 f 5d 057 7 f 5d 056 8 f 5d 065 9 f 5d 064 a f 5d 063 b f 5d 062 c f 5d 061 d f 5d 060 e f 5d 05f f f 5d 05e 0 0 5e 05e 1 0 5e 05e 2 0 5e 05e 3 0 5e 05e 4 0 5e 05e 5 0 5e 05e 6 0 5e 05e 7 0 5e 05e 8 0 5e 05e 9 0 5e 05e a 0 5e 05e b 0 5e 05e c 0 5e 05e d 0 5e 05e e 0 5e 05e f 0 5e 05e 0 1 5e 05e 1 1 5e 05f 2 1 5e 060 3 1 5e 061 4 1 5e 062 5 1 5e 063 6 1 5e 064 7 1 5e 065 8 1 5e 056 9 1 5e 057 a 1 5e 058 b 1 5e 059 c 1 5e 05a d 1 5e 05b e 1 5e 05c f 1 5e 05d 0 2 5e 05e 1 2 5e 060 2 2 5e 062 3 2 5e 064 4 2 5e 066 5 2 5e 068 6 2 5e 06a 7 2 5e 06c 8 2 5e 04e 9 2 5e 050 a 2 5e 052 b 2 5e 054 c 2 5e 056 d 2 5e 058 e 2 5e 05a f 2 5e 05c 0 3 5e 05e 1 3 5e 061 2 3 5e 064 3 3 5e 067 4 3 5e 06a 5 3 5e 06d 6 3 5e 070 7 3 5e 073 8 3 5e 046 9 3 5e 049 a 3 5e 04c b 3 5e 04f c 3 5e 052 d 3 5e 055 e 3 5e 058 f 3 5e 05b 0 4 5e 05e 1 4 5e 062 2 4 5e 066 3 4 5e 06a 4 4 5e 06e 5 4 5e 072 6 4 5e 076 7 4 5e 07a 8 4 5e 03e 9 4 5e 042 a 4 5e 046 b 4 5e 04a c 4 5e 04e d 4 5e 052 e 4 5e 056 f 4 5e 05a 0 5 5e 05e 1 5 5e 063 2 5 5e 068 3 5 5e 06d 4 5 5e 072 5 5 5e 077 6 5 5e 07c 7 5 5e 081 8 5 5e 036 9 5 5e 03b a 5 5e 040 b 5 5e 045 c 5 5e 04a d 5 5e 04f e 5 5e 054 f 5 5e 059 0 6 5e 05e 1 6 5e 064 2 6 5e 06a 3 6 5e 070 4 6 5e 076 5 6 5e 07c 6 6 5e 082 7 6 5e 088 8 6 5e 02e 9 6 5e 034 a 6 5e 03a b 6 5e 040 c 6 5e 046 d 6 5e 04c e 6 5e 052 f 6 5e 058 0 7 5e 05e 1 7 5e 065 2 7 5e 06c 3 7 5e 073 4 7 5e 07a 5 7 5e 081 6 7 5e 088 7 7 5e 08f 8 7 5e 026 9 7 5e 02d a 7 5e 034 b 7 5e 03b c 7 5e 042 d 7 5e 049 e 7 5e 050 f 7 5e 057 0 8 5e 05e 1 8 5e 056 2 8 5e 04e 3 8 5e 046 4 8 5e 03e 5 8 5e 036 6 8 5e 02e 7 8 5e 026 8 8 5e 09e 9 8 5e 096 a 8 5e 08e b 8 5e 086 c 8 5e 07e d 8 5e 076 e 8 5e 06e f 8 5e 066 0 9 5e 05e 1 9 5e 057 2 9 5e 050 3 9 5e 049 4 9 5e 042 5 9 5e 03b 6 9 5e 034 7 9 5e 02d 8 9 5e 096 9 9 5e 08f a 9 5e 088 b 9 5e 081 c 9 5e 07a d 9 5e 073 e 9 5e 06c f 9 5e 065 0 a 5e 05e 1 a 5e 058 2 a 5e 052 3 a 5e 04c 4 a 5e 046 5 a 5e 040 6 a 5e 03a 7 a 5e 034 8 a 5e 08e 9 a 5e 088 a a 5e 082 b a 5e 07c c a 5e 076 d a 5e 070 e a 5e 06a f a 5e 064 0 b 5e 05e 1 b 5e 059 2 b 5e 054 3 b 5e 04f 4 b 5e 04a 5 b 5e 045 6 b 5e 040 7 b 5e 03b 8 b 5e 086 9 b 5e 081 a b 5e 07c b b 5e 077 c b 5e 072 d b 5e 06d e b 5e 068 f b 5e 063 0 c 5e 05e 1 c 5e 05a 2 c 5e 056 3 c 5e 052 4 c 5e 04e 5 c 5e 04a 6 c 5e 046 7 c 5e 042 8 c 5e 07e 9 c 5e 07a a c 5e 076 b c 5e 072 c c 5e 06e d c 5e 06a e c 5e 066 f c 5e 062 0 d 5e 05e 1 d 5e 05b 2 d 5e 058 3 d 5e 055 4 d 5e 052 5 d 5e 04f 6 d 5e 04c 7 d 5e 049 8 d 5e 076 9 d 5e 073 a d 5e 070 b d 5e 06d c d 5e 06a d d 5e 067 e d 5e 064 f d 5e 061 0 e 5e 05e 1 e 5e 05c 2 e 5e 05a 3 e 5e 058 4 e 5e 056 5 e 5e 054 6 e 5e 052 7 e 5e 050 8 e 5e 06e 9 e 5e 06c a e 5e 06a b e 5e 068 c e 5e 066 d e 5e 064 e e 5e 062 f e 5e 060 0 f 5e 05e 1 f 5e 05d 2 f 5e 05c 3 f 5e 05b 4 f 5e 05a 5 f 5e 059 6 f 5e 058 7 f 5e 057 8 f 5e 066 9 f 5e 065 a f 5e 064 b f 5e 063 c f 5e 062 d f 5e 061 e f 5e 060 f f 5e 05f 0 0 5f 05f 1 0 5f 05f 2 0 5f 05f 3 0 5f 05f 4 0 5f 05f 5 0 5f 05f 6 0 5f 05f 7 0 5f 05f 8 0 5f 05f 9 0 5f 05f a 0 5f 05f b 0 5f 05f c 0 5f 05f d 0 5f 05f e 0 5f 05f f 0 5f 05f 0 1 5f 05f 1 1 5f 060 2 1 5f 061 3 1 5f 062 4 1 5f 063 5 1 5f 064 6 1 5f 065 7 1 5f 066 8 1 5f 057 9 1 5f 058 a 1 5f 059 b 1 5f 05a c 1 5f 05b d 1 5f 05c e 1 5f 05d f 1 5f 05e 0 2 5f 05f 1 2 5f 061 2 2 5f 063 3 2 5f 065 4 2 5f 067 5 2 5f 069 6 2 5f 06b 7 2 5f 06d 8 2 5f 04f 9 2 5f 051 a 2 5f 053 b 2 5f 055 c 2 5f 057 d 2 5f 059 e 2 5f 05b f 2 5f 05d 0 3 5f 05f 1 3 5f 062 2 3 5f 065 3 3 5f 068 4 3 5f 06b 5 3 5f 06e 6 3 5f 071 7 3 5f 074 8 3 5f 047 9 3 5f 04a a 3 5f 04d b 3 5f 050 c 3 5f 053 d 3 5f 056 e 3 5f 059 f 3 5f 05c 0 4 5f 05f 1 4 5f 063 2 4 5f 067 3 4 5f 06b 4 4 5f 06f 5 4 5f 073 6 4 5f 077 7 4 5f 07b 8 4 5f 03f 9 4 5f 043 a 4 5f 047 b 4 5f 04b c 4 5f 04f d 4 5f 053 e 4 5f 057 f 4 5f 05b 0 5 5f 05f 1 5 5f 064 2 5 5f 069 3 5 5f 06e 4 5 5f 073 5 5 5f 078 6 5 5f 07d 7 5 5f 082 8 5 5f 037 9 5 5f 03c a 5 5f 041 b 5 5f 046 c 5 5f 04b d 5 5f 050 e 5 5f 055 f 5 5f 05a 0 6 5f 05f 1 6 5f 065 2 6 5f 06b 3 6 5f 071 4 6 5f 077 5 6 5f 07d 6 6 5f 083 7 6 5f 089 8 6 5f 02f 9 6 5f 035 a 6 5f 03b b 6 5f 041 c 6 5f 047 d 6 5f 04d e 6 5f 053 f 6 5f 059 0 7 5f 05f 1 7 5f 066 2 7 5f 06d 3 7 5f 074 4 7 5f 07b 5 7 5f 082 6 7 5f 089 7 7 5f 090 8 7 5f 027 9 7 5f 02e a 7 5f 035 b 7 5f 03c c 7 5f 043 d 7 5f 04a e 7 5f 051 f 7 5f 058 0 8 5f 05f 1 8 5f 057 2 8 5f 04f 3 8 5f 047 4 8 5f 03f 5 8 5f 037 6 8 5f 02f 7 8 5f 027 8 8 5f 09f 9 8 5f 097 a 8 5f 08f b 8 5f 087 c 8 5f 07f d 8 5f 077 e 8 5f 06f f 8 5f 067 0 9 5f 05f 1 9 5f 058 2 9 5f 051 3 9 5f 04a 4 9 5f 043 5 9 5f 03c 6 9 5f 035 7 9 5f 02e 8 9 5f 097 9 9 5f 090 a 9 5f 089 b 9 5f 082 c 9 5f 07b d 9 5f 074 e 9 5f 06d f 9 5f 066 0 a 5f 05f 1 a 5f 059 2 a 5f 053 3 a 5f 04d 4 a 5f 047 5 a 5f 041 6 a 5f 03b 7 a 5f 035 8 a 5f 08f 9 a 5f 089 a a 5f 083 b a 5f 07d c a 5f 077 d a 5f 071 e a 5f 06b f a 5f 065 0 b 5f 05f 1 b 5f 05a 2 b 5f 055 3 b 5f 050 4 b 5f 04b 5 b 5f 046 6 b 5f 041 7 b 5f 03c 8 b 5f 087 9 b 5f 082 a b 5f 07d b b 5f 078 c b 5f 073 d b 5f 06e e b 5f 069 f b 5f 064 0 c 5f 05f 1 c 5f 05b 2 c 5f 057 3 c 5f 053 4 c 5f 04f 5 c 5f 04b 6 c 5f 047 7 c 5f 043 8 c 5f 07f 9 c 5f 07b a c 5f 077 b c 5f 073 c c 5f 06f d c 5f 06b e c 5f 067 f c 5f 063 0 d 5f 05f 1 d 5f 05c 2 d 5f 059 3 d 5f 056 4 d 5f 053 5 d 5f 050 6 d 5f 04d 7 d 5f 04a 8 d 5f 077 9 d 5f 074 a d 5f 071 b d 5f 06e c d 5f 06b d d 5f 068 e d 5f 065 f d 5f 062 0 e 5f 05f 1 e 5f 05d 2 e 5f 05b 3 e 5f 059 4 e 5f 057 5 e 5f 055 6 e 5f 053 7 e 5f 051 8 e 5f 06f 9 e 5f 06d a e 5f 06b b e 5f 069 c e 5f 067 d e 5f 065 e e 5f 063 f e 5f 061 0 f 5f 05f 1 f 5f 05e 2 f 5f 05d 3 f 5f 05c 4 f 5f 05b 5 f 5f 05a 6 f 5f 059 7 f 5f 058 8 f 5f 067 9 f 5f 066 a f 5f 065 b f 5f 064 c f 5f 063 d f 5f 062 e f 5f 061 f f 5f 060 0 0 60 060 1 0 60 060 2 0 60 060 3 0 60 060 4 0 60 060 5 0 60 060 6 0 60 060 7 0 60 060 8 0 60 060 9 0 60 060 a 0 60 060 b 0 60 060 c 0 60 060 d 0 60 060 e 0 60 060 f 0 60 060 0 1 60 060 1 1 60 061 2 1 60 062 3 1 60 063 4 1 60 064 5 1 60 065 6 1 60 066 7 1 60 067 8 1 60 058 9 1 60 059 a 1 60 05a b 1 60 05b c 1 60 05c d 1 60 05d e 1 60 05e f 1 60 05f 0 2 60 060 1 2 60 062 2 2 60 064 3 2 60 066 4 2 60 068 5 2 60 06a 6 2 60 06c 7 2 60 06e 8 2 60 050 9 2 60 052 a 2 60 054 b 2 60 056 c 2 60 058 d 2 60 05a e 2 60 05c f 2 60 05e 0 3 60 060 1 3 60 063 2 3 60 066 3 3 60 069 4 3 60 06c 5 3 60 06f 6 3 60 072 7 3 60 075 8 3 60 048 9 3 60 04b a 3 60 04e b 3 60 051 c 3 60 054 d 3 60 057 e 3 60 05a f 3 60 05d 0 4 60 060 1 4 60 064 2 4 60 068 3 4 60 06c 4 4 60 070 5 4 60 074 6 4 60 078 7 4 60 07c 8 4 60 040 9 4 60 044 a 4 60 048 b 4 60 04c c 4 60 050 d 4 60 054 e 4 60 058 f 4 60 05c 0 5 60 060 1 5 60 065 2 5 60 06a 3 5 60 06f 4 5 60 074 5 5 60 079 6 5 60 07e 7 5 60 083 8 5 60 038 9 5 60 03d a 5 60 042 b 5 60 047 c 5 60 04c d 5 60 051 e 5 60 056 f 5 60 05b 0 6 60 060 1 6 60 066 2 6 60 06c 3 6 60 072 4 6 60 078 5 6 60 07e 6 6 60 084 7 6 60 08a 8 6 60 030 9 6 60 036 a 6 60 03c b 6 60 042 c 6 60 048 d 6 60 04e e 6 60 054 f 6 60 05a 0 7 60 060 1 7 60 067 2 7 60 06e 3 7 60 075 4 7 60 07c 5 7 60 083 6 7 60 08a 7 7 60 091 8 7 60 028 9 7 60 02f a 7 60 036 b 7 60 03d c 7 60 044 d 7 60 04b e 7 60 052 f 7 60 059 0 8 60 060 1 8 60 058 2 8 60 050 3 8 60 048 4 8 60 040 5 8 60 038 6 8 60 030 7 8 60 028 8 8 60 0a0 9 8 60 098 a 8 60 090 b 8 60 088 c 8 60 080 d 8 60 078 e 8 60 070 f 8 60 068 0 9 60 060 1 9 60 059 2 9 60 052 3 9 60 04b 4 9 60 044 5 9 60 03d 6 9 60 036 7 9 60 02f 8 9 60 098 9 9 60 091 a 9 60 08a b 9 60 083 c 9 60 07c d 9 60 075 e 9 60 06e f 9 60 067 0 a 60 060 1 a 60 05a 2 a 60 054 3 a 60 04e 4 a 60 048 5 a 60 042 6 a 60 03c 7 a 60 036 8 a 60 090 9 a 60 08a a a 60 084 b a 60 07e c a 60 078 d a 60 072 e a 60 06c f a 60 066 0 b 60 060 1 b 60 05b 2 b 60 056 3 b 60 051 4 b 60 04c 5 b 60 047 6 b 60 042 7 b 60 03d 8 b 60 088 9 b 60 083 a b 60 07e b b 60 079 c b 60 074 d b 60 06f e b 60 06a f b 60 065 0 c 60 060 1 c 60 05c 2 c 60 058 3 c 60 054 4 c 60 050 5 c 60 04c 6 c 60 048 7 c 60 044 8 c 60 080 9 c 60 07c a c 60 078 b c 60 074 c c 60 070 d c 60 06c e c 60 068 f c 60 064 0 d 60 060 1 d 60 05d 2 d 60 05a 3 d 60 057 4 d 60 054 5 d 60 051 6 d 60 04e 7 d 60 04b 8 d 60 078 9 d 60 075 a d 60 072 b d 60 06f c d 60 06c d d 60 069 e d 60 066 f d 60 063 0 e 60 060 1 e 60 05e 2 e 60 05c 3 e 60 05a 4 e 60 058 5 e 60 056 6 e 60 054 7 e 60 052 8 e 60 070 9 e 60 06e a e 60 06c b e 60 06a c e 60 068 d e 60 066 e e 60 064 f e 60 062 0 f 60 060 1 f 60 05f 2 f 60 05e 3 f 60 05d 4 f 60 05c 5 f 60 05b 6 f 60 05a 7 f 60 059 8 f 60 068 9 f 60 067 a f 60 066 b f 60 065 c f 60 064 d f 60 063 e f 60 062 f f 60 061 0 0 61 061 1 0 61 061 2 0 61 061 3 0 61 061 4 0 61 061 5 0 61 061 6 0 61 061 7 0 61 061 8 0 61 061 9 0 61 061 a 0 61 061 b 0 61 061 c 0 61 061 d 0 61 061 e 0 61 061 f 0 61 061 0 1 61 061 1 1 61 062 2 1 61 063 3 1 61 064 4 1 61 065 5 1 61 066 6 1 61 067 7 1 61 068 8 1 61 059 9 1 61 05a a 1 61 05b b 1 61 05c c 1 61 05d d 1 61 05e e 1 61 05f f 1 61 060 0 2 61 061 1 2 61 063 2 2 61 065 3 2 61 067 4 2 61 069 5 2 61 06b 6 2 61 06d 7 2 61 06f 8 2 61 051 9 2 61 053 a 2 61 055 b 2 61 057 c 2 61 059 d 2 61 05b e 2 61 05d f 2 61 05f 0 3 61 061 1 3 61 064 2 3 61 067 3 3 61 06a 4 3 61 06d 5 3 61 070 6 3 61 073 7 3 61 076 8 3 61 049 9 3 61 04c a 3 61 04f b 3 61 052 c 3 61 055 d 3 61 058 e 3 61 05b f 3 61 05e 0 4 61 061 1 4 61 065 2 4 61 069 3 4 61 06d 4 4 61 071 5 4 61 075 6 4 61 079 7 4 61 07d 8 4 61 041 9 4 61 045 a 4 61 049 b 4 61 04d c 4 61 051 d 4 61 055 e 4 61 059 f 4 61 05d 0 5 61 061 1 5 61 066 2 5 61 06b 3 5 61 070 4 5 61 075 5 5 61 07a 6 5 61 07f 7 5 61 084 8 5 61 039 9 5 61 03e a 5 61 043 b 5 61 048 c 5 61 04d d 5 61 052 e 5 61 057 f 5 61 05c 0 6 61 061 1 6 61 067 2 6 61 06d 3 6 61 073 4 6 61 079 5 6 61 07f 6 6 61 085 7 6 61 08b 8 6 61 031 9 6 61 037 a 6 61 03d b 6 61 043 c 6 61 049 d 6 61 04f e 6 61 055 f 6 61 05b 0 7 61 061 1 7 61 068 2 7 61 06f 3 7 61 076 4 7 61 07d 5 7 61 084 6 7 61 08b 7 7 61 092 8 7 61 029 9 7 61 030 a 7 61 037 b 7 61 03e c 7 61 045 d 7 61 04c e 7 61 053 f 7 61 05a 0 8 61 061 1 8 61 059 2 8 61 051 3 8 61 049 4 8 61 041 5 8 61 039 6 8 61 031 7 8 61 029 8 8 61 0a1 9 8 61 099 a 8 61 091 b 8 61 089 c 8 61 081 d 8 61 079 e 8 61 071 f 8 61 069 0 9 61 061 1 9 61 05a 2 9 61 053 3 9 61 04c 4 9 61 045 5 9 61 03e 6 9 61 037 7 9 61 030 8 9 61 099 9 9 61 092 a 9 61 08b b 9 61 084 c 9 61 07d d 9 61 076 e 9 61 06f f 9 61 068 0 a 61 061 1 a 61 05b 2 a 61 055 3 a 61 04f 4 a 61 049 5 a 61 043 6 a 61 03d 7 a 61 037 8 a 61 091 9 a 61 08b a a 61 085 b a 61 07f c a 61 079 d a 61 073 e a 61 06d f a 61 067 0 b 61 061 1 b 61 05c 2 b 61 057 3 b 61 052 4 b 61 04d 5 b 61 048 6 b 61 043 7 b 61 03e 8 b 61 089 9 b 61 084 a b 61 07f b b 61 07a c b 61 075 d b 61 070 e b 61 06b f b 61 066 0 c 61 061 1 c 61 05d 2 c 61 059 3 c 61 055 4 c 61 051 5 c 61 04d 6 c 61 049 7 c 61 045 8 c 61 081 9 c 61 07d a c 61 079 b c 61 075 c c 61 071 d c 61 06d e c 61 069 f c 61 065 0 d 61 061 1 d 61 05e 2 d 61 05b 3 d 61 058 4 d 61 055 5 d 61 052 6 d 61 04f 7 d 61 04c 8 d 61 079 9 d 61 076 a d 61 073 b d 61 070 c d 61 06d d d 61 06a e d 61 067 f d 61 064 0 e 61 061 1 e 61 05f 2 e 61 05d 3 e 61 05b 4 e 61 059 5 e 61 057 6 e 61 055 7 e 61 053 8 e 61 071 9 e 61 06f a e 61 06d b e 61 06b c e 61 069 d e 61 067 e e 61 065 f e 61 063 0 f 61 061 1 f 61 060 2 f 61 05f 3 f 61 05e 4 f 61 05d 5 f 61 05c 6 f 61 05b 7 f 61 05a 8 f 61 069 9 f 61 068 a f 61 067 b f 61 066 c f 61 065 d f 61 064 e f 61 063 f f 61 062 0 0 62 062 1 0 62 062 2 0 62 062 3 0 62 062 4 0 62 062 5 0 62 062 6 0 62 062 7 0 62 062 8 0 62 062 9 0 62 062 a 0 62 062 b 0 62 062 c 0 62 062 d 0 62 062 e 0 62 062 f 0 62 062 0 1 62 062 1 1 62 063 2 1 62 064 3 1 62 065 4 1 62 066 5 1 62 067 6 1 62 068 7 1 62 069 8 1 62 05a 9 1 62 05b a 1 62 05c b 1 62 05d c 1 62 05e d 1 62 05f e 1 62 060 f 1 62 061 0 2 62 062 1 2 62 064 2 2 62 066 3 2 62 068 4 2 62 06a 5 2 62 06c 6 2 62 06e 7 2 62 070 8 2 62 052 9 2 62 054 a 2 62 056 b 2 62 058 c 2 62 05a d 2 62 05c e 2 62 05e f 2 62 060 0 3 62 062 1 3 62 065 2 3 62 068 3 3 62 06b 4 3 62 06e 5 3 62 071 6 3 62 074 7 3 62 077 8 3 62 04a 9 3 62 04d a 3 62 050 b 3 62 053 c 3 62 056 d 3 62 059 e 3 62 05c f 3 62 05f 0 4 62 062 1 4 62 066 2 4 62 06a 3 4 62 06e 4 4 62 072 5 4 62 076 6 4 62 07a 7 4 62 07e 8 4 62 042 9 4 62 046 a 4 62 04a b 4 62 04e c 4 62 052 d 4 62 056 e 4 62 05a f 4 62 05e 0 5 62 062 1 5 62 067 2 5 62 06c 3 5 62 071 4 5 62 076 5 5 62 07b 6 5 62 080 7 5 62 085 8 5 62 03a 9 5 62 03f a 5 62 044 b 5 62 049 c 5 62 04e d 5 62 053 e 5 62 058 f 5 62 05d 0 6 62 062 1 6 62 068 2 6 62 06e 3 6 62 074 4 6 62 07a 5 6 62 080 6 6 62 086 7 6 62 08c 8 6 62 032 9 6 62 038 a 6 62 03e b 6 62 044 c 6 62 04a d 6 62 050 e 6 62 056 f 6 62 05c 0 7 62 062 1 7 62 069 2 7 62 070 3 7 62 077 4 7 62 07e 5 7 62 085 6 7 62 08c 7 7 62 093 8 7 62 02a 9 7 62 031 a 7 62 038 b 7 62 03f c 7 62 046 d 7 62 04d e 7 62 054 f 7 62 05b 0 8 62 062 1 8 62 05a 2 8 62 052 3 8 62 04a 4 8 62 042 5 8 62 03a 6 8 62 032 7 8 62 02a 8 8 62 0a2 9 8 62 09a a 8 62 092 b 8 62 08a c 8 62 082 d 8 62 07a e 8 62 072 f 8 62 06a 0 9 62 062 1 9 62 05b 2 9 62 054 3 9 62 04d 4 9 62 046 5 9 62 03f 6 9 62 038 7 9 62 031 8 9 62 09a 9 9 62 093 a 9 62 08c b 9 62 085 c 9 62 07e d 9 62 077 e 9 62 070 f 9 62 069 0 a 62 062 1 a 62 05c 2 a 62 056 3 a 62 050 4 a 62 04a 5 a 62 044 6 a 62 03e 7 a 62 038 8 a 62 092 9 a 62 08c a a 62 086 b a 62 080 c a 62 07a d a 62 074 e a 62 06e f a 62 068 0 b 62 062 1 b 62 05d 2 b 62 058 3 b 62 053 4 b 62 04e 5 b 62 049 6 b 62 044 7 b 62 03f 8 b 62 08a 9 b 62 085 a b 62 080 b b 62 07b c b 62 076 d b 62 071 e b 62 06c f b 62 067 0 c 62 062 1 c 62 05e 2 c 62 05a 3 c 62 056 4 c 62 052 5 c 62 04e 6 c 62 04a 7 c 62 046 8 c 62 082 9 c 62 07e a c 62 07a b c 62 076 c c 62 072 d c 62 06e e c 62 06a f c 62 066 0 d 62 062 1 d 62 05f 2 d 62 05c 3 d 62 059 4 d 62 056 5 d 62 053 6 d 62 050 7 d 62 04d 8 d 62 07a 9 d 62 077 a d 62 074 b d 62 071 c d 62 06e d d 62 06b e d 62 068 f d 62 065 0 e 62 062 1 e 62 060 2 e 62 05e 3 e 62 05c 4 e 62 05a 5 e 62 058 6 e 62 056 7 e 62 054 8 e 62 072 9 e 62 070 a e 62 06e b e 62 06c c e 62 06a d e 62 068 e e 62 066 f e 62 064 0 f 62 062 1 f 62 061 2 f 62 060 3 f 62 05f 4 f 62 05e 5 f 62 05d 6 f 62 05c 7 f 62 05b 8 f 62 06a 9 f 62 069 a f 62 068 b f 62 067 c f 62 066 d f 62 065 e f 62 064 f f 62 063 0 0 63 063 1 0 63 063 2 0 63 063 3 0 63 063 4 0 63 063 5 0 63 063 6 0 63 063 7 0 63 063 8 0 63 063 9 0 63 063 a 0 63 063 b 0 63 063 c 0 63 063 d 0 63 063 e 0 63 063 f 0 63 063 0 1 63 063 1 1 63 064 2 1 63 065 3 1 63 066 4 1 63 067 5 1 63 068 6 1 63 069 7 1 63 06a 8 1 63 05b 9 1 63 05c a 1 63 05d b 1 63 05e c 1 63 05f d 1 63 060 e 1 63 061 f 1 63 062 0 2 63 063 1 2 63 065 2 2 63 067 3 2 63 069 4 2 63 06b 5 2 63 06d 6 2 63 06f 7 2 63 071 8 2 63 053 9 2 63 055 a 2 63 057 b 2 63 059 c 2 63 05b d 2 63 05d e 2 63 05f f 2 63 061 0 3 63 063 1 3 63 066 2 3 63 069 3 3 63 06c 4 3 63 06f 5 3 63 072 6 3 63 075 7 3 63 078 8 3 63 04b 9 3 63 04e a 3 63 051 b 3 63 054 c 3 63 057 d 3 63 05a e 3 63 05d f 3 63 060 0 4 63 063 1 4 63 067 2 4 63 06b 3 4 63 06f 4 4 63 073 5 4 63 077 6 4 63 07b 7 4 63 07f 8 4 63 043 9 4 63 047 a 4 63 04b b 4 63 04f c 4 63 053 d 4 63 057 e 4 63 05b f 4 63 05f 0 5 63 063 1 5 63 068 2 5 63 06d 3 5 63 072 4 5 63 077 5 5 63 07c 6 5 63 081 7 5 63 086 8 5 63 03b 9 5 63 040 a 5 63 045 b 5 63 04a c 5 63 04f d 5 63 054 e 5 63 059 f 5 63 05e 0 6 63 063 1 6 63 069 2 6 63 06f 3 6 63 075 4 6 63 07b 5 6 63 081 6 6 63 087 7 6 63 08d 8 6 63 033 9 6 63 039 a 6 63 03f b 6 63 045 c 6 63 04b d 6 63 051 e 6 63 057 f 6 63 05d 0 7 63 063 1 7 63 06a 2 7 63 071 3 7 63 078 4 7 63 07f 5 7 63 086 6 7 63 08d 7 7 63 094 8 7 63 02b 9 7 63 032 a 7 63 039 b 7 63 040 c 7 63 047 d 7 63 04e e 7 63 055 f 7 63 05c 0 8 63 063 1 8 63 05b 2 8 63 053 3 8 63 04b 4 8 63 043 5 8 63 03b 6 8 63 033 7 8 63 02b 8 8 63 0a3 9 8 63 09b a 8 63 093 b 8 63 08b c 8 63 083 d 8 63 07b e 8 63 073 f 8 63 06b 0 9 63 063 1 9 63 05c 2 9 63 055 3 9 63 04e 4 9 63 047 5 9 63 040 6 9 63 039 7 9 63 032 8 9 63 09b 9 9 63 094 a 9 63 08d b 9 63 086 c 9 63 07f d 9 63 078 e 9 63 071 f 9 63 06a 0 a 63 063 1 a 63 05d 2 a 63 057 3 a 63 051 4 a 63 04b 5 a 63 045 6 a 63 03f 7 a 63 039 8 a 63 093 9 a 63 08d a a 63 087 b a 63 081 c a 63 07b d a 63 075 e a 63 06f f a 63 069 0 b 63 063 1 b 63 05e 2 b 63 059 3 b 63 054 4 b 63 04f 5 b 63 04a 6 b 63 045 7 b 63 040 8 b 63 08b 9 b 63 086 a b 63 081 b b 63 07c c b 63 077 d b 63 072 e b 63 06d f b 63 068 0 c 63 063 1 c 63 05f 2 c 63 05b 3 c 63 057 4 c 63 053 5 c 63 04f 6 c 63 04b 7 c 63 047 8 c 63 083 9 c 63 07f a c 63 07b b c 63 077 c c 63 073 d c 63 06f e c 63 06b f c 63 067 0 d 63 063 1 d 63 060 2 d 63 05d 3 d 63 05a 4 d 63 057 5 d 63 054 6 d 63 051 7 d 63 04e 8 d 63 07b 9 d 63 078 a d 63 075 b d 63 072 c d 63 06f d d 63 06c e d 63 069 f d 63 066 0 e 63 063 1 e 63 061 2 e 63 05f 3 e 63 05d 4 e 63 05b 5 e 63 059 6 e 63 057 7 e 63 055 8 e 63 073 9 e 63 071 a e 63 06f b e 63 06d c e 63 06b d e 63 069 e e 63 067 f e 63 065 0 f 63 063 1 f 63 062 2 f 63 061 3 f 63 060 4 f 63 05f 5 f 63 05e 6 f 63 05d 7 f 63 05c 8 f 63 06b 9 f 63 06a a f 63 069 b f 63 068 c f 63 067 d f 63 066 e f 63 065 f f 63 064 0 0 64 064 1 0 64 064 2 0 64 064 3 0 64 064 4 0 64 064 5 0 64 064 6 0 64 064 7 0 64 064 8 0 64 064 9 0 64 064 a 0 64 064 b 0 64 064 c 0 64 064 d 0 64 064 e 0 64 064 f 0 64 064 0 1 64 064 1 1 64 065 2 1 64 066 3 1 64 067 4 1 64 068 5 1 64 069 6 1 64 06a 7 1 64 06b 8 1 64 05c 9 1 64 05d a 1 64 05e b 1 64 05f c 1 64 060 d 1 64 061 e 1 64 062 f 1 64 063 0 2 64 064 1 2 64 066 2 2 64 068 3 2 64 06a 4 2 64 06c 5 2 64 06e 6 2 64 070 7 2 64 072 8 2 64 054 9 2 64 056 a 2 64 058 b 2 64 05a c 2 64 05c d 2 64 05e e 2 64 060 f 2 64 062 0 3 64 064 1 3 64 067 2 3 64 06a 3 3 64 06d 4 3 64 070 5 3 64 073 6 3 64 076 7 3 64 079 8 3 64 04c 9 3 64 04f a 3 64 052 b 3 64 055 c 3 64 058 d 3 64 05b e 3 64 05e f 3 64 061 0 4 64 064 1 4 64 068 2 4 64 06c 3 4 64 070 4 4 64 074 5 4 64 078 6 4 64 07c 7 4 64 080 8 4 64 044 9 4 64 048 a 4 64 04c b 4 64 050 c 4 64 054 d 4 64 058 e 4 64 05c f 4 64 060 0 5 64 064 1 5 64 069 2 5 64 06e 3 5 64 073 4 5 64 078 5 5 64 07d 6 5 64 082 7 5 64 087 8 5 64 03c 9 5 64 041 a 5 64 046 b 5 64 04b c 5 64 050 d 5 64 055 e 5 64 05a f 5 64 05f 0 6 64 064 1 6 64 06a 2 6 64 070 3 6 64 076 4 6 64 07c 5 6 64 082 6 6 64 088 7 6 64 08e 8 6 64 034 9 6 64 03a a 6 64 040 b 6 64 046 c 6 64 04c d 6 64 052 e 6 64 058 f 6 64 05e 0 7 64 064 1 7 64 06b 2 7 64 072 3 7 64 079 4 7 64 080 5 7 64 087 6 7 64 08e 7 7 64 095 8 7 64 02c 9 7 64 033 a 7 64 03a b 7 64 041 c 7 64 048 d 7 64 04f e 7 64 056 f 7 64 05d 0 8 64 064 1 8 64 05c 2 8 64 054 3 8 64 04c 4 8 64 044 5 8 64 03c 6 8 64 034 7 8 64 02c 8 8 64 0a4 9 8 64 09c a 8 64 094 b 8 64 08c c 8 64 084 d 8 64 07c e 8 64 074 f 8 64 06c 0 9 64 064 1 9 64 05d 2 9 64 056 3 9 64 04f 4 9 64 048 5 9 64 041 6 9 64 03a 7 9 64 033 8 9 64 09c 9 9 64 095 a 9 64 08e b 9 64 087 c 9 64 080 d 9 64 079 e 9 64 072 f 9 64 06b 0 a 64 064 1 a 64 05e 2 a 64 058 3 a 64 052 4 a 64 04c 5 a 64 046 6 a 64 040 7 a 64 03a 8 a 64 094 9 a 64 08e a a 64 088 b a 64 082 c a 64 07c d a 64 076 e a 64 070 f a 64 06a 0 b 64 064 1 b 64 05f 2 b 64 05a 3 b 64 055 4 b 64 050 5 b 64 04b 6 b 64 046 7 b 64 041 8 b 64 08c 9 b 64 087 a b 64 082 b b 64 07d c b 64 078 d b 64 073 e b 64 06e f b 64 069 0 c 64 064 1 c 64 060 2 c 64 05c 3 c 64 058 4 c 64 054 5 c 64 050 6 c 64 04c 7 c 64 048 8 c 64 084 9 c 64 080 a c 64 07c b c 64 078 c c 64 074 d c 64 070 e c 64 06c f c 64 068 0 d 64 064 1 d 64 061 2 d 64 05e 3 d 64 05b 4 d 64 058 5 d 64 055 6 d 64 052 7 d 64 04f 8 d 64 07c 9 d 64 079 a d 64 076 b d 64 073 c d 64 070 d d 64 06d e d 64 06a f d 64 067 0 e 64 064 1 e 64 062 2 e 64 060 3 e 64 05e 4 e 64 05c 5 e 64 05a 6 e 64 058 7 e 64 056 8 e 64 074 9 e 64 072 a e 64 070 b e 64 06e c e 64 06c d e 64 06a e e 64 068 f e 64 066 0 f 64 064 1 f 64 063 2 f 64 062 3 f 64 061 4 f 64 060 5 f 64 05f 6 f 64 05e 7 f 64 05d 8 f 64 06c 9 f 64 06b a f 64 06a b f 64 069 c f 64 068 d f 64 067 e f 64 066 f f 64 065 0 0 65 065 1 0 65 065 2 0 65 065 3 0 65 065 4 0 65 065 5 0 65 065 6 0 65 065 7 0 65 065 8 0 65 065 9 0 65 065 a 0 65 065 b 0 65 065 c 0 65 065 d 0 65 065 e 0 65 065 f 0 65 065 0 1 65 065 1 1 65 066 2 1 65 067 3 1 65 068 4 1 65 069 5 1 65 06a 6 1 65 06b 7 1 65 06c 8 1 65 05d 9 1 65 05e a 1 65 05f b 1 65 060 c 1 65 061 d 1 65 062 e 1 65 063 f 1 65 064 0 2 65 065 1 2 65 067 2 2 65 069 3 2 65 06b 4 2 65 06d 5 2 65 06f 6 2 65 071 7 2 65 073 8 2 65 055 9 2 65 057 a 2 65 059 b 2 65 05b c 2 65 05d d 2 65 05f e 2 65 061 f 2 65 063 0 3 65 065 1 3 65 068 2 3 65 06b 3 3 65 06e 4 3 65 071 5 3 65 074 6 3 65 077 7 3 65 07a 8 3 65 04d 9 3 65 050 a 3 65 053 b 3 65 056 c 3 65 059 d 3 65 05c e 3 65 05f f 3 65 062 0 4 65 065 1 4 65 069 2 4 65 06d 3 4 65 071 4 4 65 075 5 4 65 079 6 4 65 07d 7 4 65 081 8 4 65 045 9 4 65 049 a 4 65 04d b 4 65 051 c 4 65 055 d 4 65 059 e 4 65 05d f 4 65 061 0 5 65 065 1 5 65 06a 2 5 65 06f 3 5 65 074 4 5 65 079 5 5 65 07e 6 5 65 083 7 5 65 088 8 5 65 03d 9 5 65 042 a 5 65 047 b 5 65 04c c 5 65 051 d 5 65 056 e 5 65 05b f 5 65 060 0 6 65 065 1 6 65 06b 2 6 65 071 3 6 65 077 4 6 65 07d 5 6 65 083 6 6 65 089 7 6 65 08f 8 6 65 035 9 6 65 03b a 6 65 041 b 6 65 047 c 6 65 04d d 6 65 053 e 6 65 059 f 6 65 05f 0 7 65 065 1 7 65 06c 2 7 65 073 3 7 65 07a 4 7 65 081 5 7 65 088 6 7 65 08f 7 7 65 096 8 7 65 02d 9 7 65 034 a 7 65 03b b 7 65 042 c 7 65 049 d 7 65 050 e 7 65 057 f 7 65 05e 0 8 65 065 1 8 65 05d 2 8 65 055 3 8 65 04d 4 8 65 045 5 8 65 03d 6 8 65 035 7 8 65 02d 8 8 65 0a5 9 8 65 09d a 8 65 095 b 8 65 08d c 8 65 085 d 8 65 07d e 8 65 075 f 8 65 06d 0 9 65 065 1 9 65 05e 2 9 65 057 3 9 65 050 4 9 65 049 5 9 65 042 6 9 65 03b 7 9 65 034 8 9 65 09d 9 9 65 096 a 9 65 08f b 9 65 088 c 9 65 081 d 9 65 07a e 9 65 073 f 9 65 06c 0 a 65 065 1 a 65 05f 2 a 65 059 3 a 65 053 4 a 65 04d 5 a 65 047 6 a 65 041 7 a 65 03b 8 a 65 095 9 a 65 08f a a 65 089 b a 65 083 c a 65 07d d a 65 077 e a 65 071 f a 65 06b 0 b 65 065 1 b 65 060 2 b 65 05b 3 b 65 056 4 b 65 051 5 b 65 04c 6 b 65 047 7 b 65 042 8 b 65 08d 9 b 65 088 a b 65 083 b b 65 07e c b 65 079 d b 65 074 e b 65 06f f b 65 06a 0 c 65 065 1 c 65 061 2 c 65 05d 3 c 65 059 4 c 65 055 5 c 65 051 6 c 65 04d 7 c 65 049 8 c 65 085 9 c 65 081 a c 65 07d b c 65 079 c c 65 075 d c 65 071 e c 65 06d f c 65 069 0 d 65 065 1 d 65 062 2 d 65 05f 3 d 65 05c 4 d 65 059 5 d 65 056 6 d 65 053 7 d 65 050 8 d 65 07d 9 d 65 07a a d 65 077 b d 65 074 c d 65 071 d d 65 06e e d 65 06b f d 65 068 0 e 65 065 1 e 65 063 2 e 65 061 3 e 65 05f 4 e 65 05d 5 e 65 05b 6 e 65 059 7 e 65 057 8 e 65 075 9 e 65 073 a e 65 071 b e 65 06f c e 65 06d d e 65 06b e e 65 069 f e 65 067 0 f 65 065 1 f 65 064 2 f 65 063 3 f 65 062 4 f 65 061 5 f 65 060 6 f 65 05f 7 f 65 05e 8 f 65 06d 9 f 65 06c a f 65 06b b f 65 06a c f 65 069 d f 65 068 e f 65 067 f f 65 066 0 0 66 066 1 0 66 066 2 0 66 066 3 0 66 066 4 0 66 066 5 0 66 066 6 0 66 066 7 0 66 066 8 0 66 066 9 0 66 066 a 0 66 066 b 0 66 066 c 0 66 066 d 0 66 066 e 0 66 066 f 0 66 066 0 1 66 066 1 1 66 067 2 1 66 068 3 1 66 069 4 1 66 06a 5 1 66 06b 6 1 66 06c 7 1 66 06d 8 1 66 05e 9 1 66 05f a 1 66 060 b 1 66 061 c 1 66 062 d 1 66 063 e 1 66 064 f 1 66 065 0 2 66 066 1 2 66 068 2 2 66 06a 3 2 66 06c 4 2 66 06e 5 2 66 070 6 2 66 072 7 2 66 074 8 2 66 056 9 2 66 058 a 2 66 05a b 2 66 05c c 2 66 05e d 2 66 060 e 2 66 062 f 2 66 064 0 3 66 066 1 3 66 069 2 3 66 06c 3 3 66 06f 4 3 66 072 5 3 66 075 6 3 66 078 7 3 66 07b 8 3 66 04e 9 3 66 051 a 3 66 054 b 3 66 057 c 3 66 05a d 3 66 05d e 3 66 060 f 3 66 063 0 4 66 066 1 4 66 06a 2 4 66 06e 3 4 66 072 4 4 66 076 5 4 66 07a 6 4 66 07e 7 4 66 082 8 4 66 046 9 4 66 04a a 4 66 04e b 4 66 052 c 4 66 056 d 4 66 05a e 4 66 05e f 4 66 062 0 5 66 066 1 5 66 06b 2 5 66 070 3 5 66 075 4 5 66 07a 5 5 66 07f 6 5 66 084 7 5 66 089 8 5 66 03e 9 5 66 043 a 5 66 048 b 5 66 04d c 5 66 052 d 5 66 057 e 5 66 05c f 5 66 061 0 6 66 066 1 6 66 06c 2 6 66 072 3 6 66 078 4 6 66 07e 5 6 66 084 6 6 66 08a 7 6 66 090 8 6 66 036 9 6 66 03c a 6 66 042 b 6 66 048 c 6 66 04e d 6 66 054 e 6 66 05a f 6 66 060 0 7 66 066 1 7 66 06d 2 7 66 074 3 7 66 07b 4 7 66 082 5 7 66 089 6 7 66 090 7 7 66 097 8 7 66 02e 9 7 66 035 a 7 66 03c b 7 66 043 c 7 66 04a d 7 66 051 e 7 66 058 f 7 66 05f 0 8 66 066 1 8 66 05e 2 8 66 056 3 8 66 04e 4 8 66 046 5 8 66 03e 6 8 66 036 7 8 66 02e 8 8 66 0a6 9 8 66 09e a 8 66 096 b 8 66 08e c 8 66 086 d 8 66 07e e 8 66 076 f 8 66 06e 0 9 66 066 1 9 66 05f 2 9 66 058 3 9 66 051 4 9 66 04a 5 9 66 043 6 9 66 03c 7 9 66 035 8 9 66 09e 9 9 66 097 a 9 66 090 b 9 66 089 c 9 66 082 d 9 66 07b e 9 66 074 f 9 66 06d 0 a 66 066 1 a 66 060 2 a 66 05a 3 a 66 054 4 a 66 04e 5 a 66 048 6 a 66 042 7 a 66 03c 8 a 66 096 9 a 66 090 a a 66 08a b a 66 084 c a 66 07e d a 66 078 e a 66 072 f a 66 06c 0 b 66 066 1 b 66 061 2 b 66 05c 3 b 66 057 4 b 66 052 5 b 66 04d 6 b 66 048 7 b 66 043 8 b 66 08e 9 b 66 089 a b 66 084 b b 66 07f c b 66 07a d b 66 075 e b 66 070 f b 66 06b 0 c 66 066 1 c 66 062 2 c 66 05e 3 c 66 05a 4 c 66 056 5 c 66 052 6 c 66 04e 7 c 66 04a 8 c 66 086 9 c 66 082 a c 66 07e b c 66 07a c c 66 076 d c 66 072 e c 66 06e f c 66 06a 0 d 66 066 1 d 66 063 2 d 66 060 3 d 66 05d 4 d 66 05a 5 d 66 057 6 d 66 054 7 d 66 051 8 d 66 07e 9 d 66 07b a d 66 078 b d 66 075 c d 66 072 d d 66 06f e d 66 06c f d 66 069 0 e 66 066 1 e 66 064 2 e 66 062 3 e 66 060 4 e 66 05e 5 e 66 05c 6 e 66 05a 7 e 66 058 8 e 66 076 9 e 66 074 a e 66 072 b e 66 070 c e 66 06e d e 66 06c e e 66 06a f e 66 068 0 f 66 066 1 f 66 065 2 f 66 064 3 f 66 063 4 f 66 062 5 f 66 061 6 f 66 060 7 f 66 05f 8 f 66 06e 9 f 66 06d a f 66 06c b f 66 06b c f 66 06a d f 66 069 e f 66 068 f f 66 067 0 0 67 067 1 0 67 067 2 0 67 067 3 0 67 067 4 0 67 067 5 0 67 067 6 0 67 067 7 0 67 067 8 0 67 067 9 0 67 067 a 0 67 067 b 0 67 067 c 0 67 067 d 0 67 067 e 0 67 067 f 0 67 067 0 1 67 067 1 1 67 068 2 1 67 069 3 1 67 06a 4 1 67 06b 5 1 67 06c 6 1 67 06d 7 1 67 06e 8 1 67 05f 9 1 67 060 a 1 67 061 b 1 67 062 c 1 67 063 d 1 67 064 e 1 67 065 f 1 67 066 0 2 67 067 1 2 67 069 2 2 67 06b 3 2 67 06d 4 2 67 06f 5 2 67 071 6 2 67 073 7 2 67 075 8 2 67 057 9 2 67 059 a 2 67 05b b 2 67 05d c 2 67 05f d 2 67 061 e 2 67 063 f 2 67 065 0 3 67 067 1 3 67 06a 2 3 67 06d 3 3 67 070 4 3 67 073 5 3 67 076 6 3 67 079 7 3 67 07c 8 3 67 04f 9 3 67 052 a 3 67 055 b 3 67 058 c 3 67 05b d 3 67 05e e 3 67 061 f 3 67 064 0 4 67 067 1 4 67 06b 2 4 67 06f 3 4 67 073 4 4 67 077 5 4 67 07b 6 4 67 07f 7 4 67 083 8 4 67 047 9 4 67 04b a 4 67 04f b 4 67 053 c 4 67 057 d 4 67 05b e 4 67 05f f 4 67 063 0 5 67 067 1 5 67 06c 2 5 67 071 3 5 67 076 4 5 67 07b 5 5 67 080 6 5 67 085 7 5 67 08a 8 5 67 03f 9 5 67 044 a 5 67 049 b 5 67 04e c 5 67 053 d 5 67 058 e 5 67 05d f 5 67 062 0 6 67 067 1 6 67 06d 2 6 67 073 3 6 67 079 4 6 67 07f 5 6 67 085 6 6 67 08b 7 6 67 091 8 6 67 037 9 6 67 03d a 6 67 043 b 6 67 049 c 6 67 04f d 6 67 055 e 6 67 05b f 6 67 061 0 7 67 067 1 7 67 06e 2 7 67 075 3 7 67 07c 4 7 67 083 5 7 67 08a 6 7 67 091 7 7 67 098 8 7 67 02f 9 7 67 036 a 7 67 03d b 7 67 044 c 7 67 04b d 7 67 052 e 7 67 059 f 7 67 060 0 8 67 067 1 8 67 05f 2 8 67 057 3 8 67 04f 4 8 67 047 5 8 67 03f 6 8 67 037 7 8 67 02f 8 8 67 0a7 9 8 67 09f a 8 67 097 b 8 67 08f c 8 67 087 d 8 67 07f e 8 67 077 f 8 67 06f 0 9 67 067 1 9 67 060 2 9 67 059 3 9 67 052 4 9 67 04b 5 9 67 044 6 9 67 03d 7 9 67 036 8 9 67 09f 9 9 67 098 a 9 67 091 b 9 67 08a c 9 67 083 d 9 67 07c e 9 67 075 f 9 67 06e 0 a 67 067 1 a 67 061 2 a 67 05b 3 a 67 055 4 a 67 04f 5 a 67 049 6 a 67 043 7 a 67 03d 8 a 67 097 9 a 67 091 a a 67 08b b a 67 085 c a 67 07f d a 67 079 e a 67 073 f a 67 06d 0 b 67 067 1 b 67 062 2 b 67 05d 3 b 67 058 4 b 67 053 5 b 67 04e 6 b 67 049 7 b 67 044 8 b 67 08f 9 b 67 08a a b 67 085 b b 67 080 c b 67 07b d b 67 076 e b 67 071 f b 67 06c 0 c 67 067 1 c 67 063 2 c 67 05f 3 c 67 05b 4 c 67 057 5 c 67 053 6 c 67 04f 7 c 67 04b 8 c 67 087 9 c 67 083 a c 67 07f b c 67 07b c c 67 077 d c 67 073 e c 67 06f f c 67 06b 0 d 67 067 1 d 67 064 2 d 67 061 3 d 67 05e 4 d 67 05b 5 d 67 058 6 d 67 055 7 d 67 052 8 d 67 07f 9 d 67 07c a d 67 079 b d 67 076 c d 67 073 d d 67 070 e d 67 06d f d 67 06a 0 e 67 067 1 e 67 065 2 e 67 063 3 e 67 061 4 e 67 05f 5 e 67 05d 6 e 67 05b 7 e 67 059 8 e 67 077 9 e 67 075 a e 67 073 b e 67 071 c e 67 06f d e 67 06d e e 67 06b f e 67 069 0 f 67 067 1 f 67 066 2 f 67 065 3 f 67 064 4 f 67 063 5 f 67 062 6 f 67 061 7 f 67 060 8 f 67 06f 9 f 67 06e a f 67 06d b f 67 06c c f 67 06b d f 67 06a e f 67 069 f f 67 068 0 0 68 068 1 0 68 068 2 0 68 068 3 0 68 068 4 0 68 068 5 0 68 068 6 0 68 068 7 0 68 068 8 0 68 068 9 0 68 068 a 0 68 068 b 0 68 068 c 0 68 068 d 0 68 068 e 0 68 068 f 0 68 068 0 1 68 068 1 1 68 069 2 1 68 06a 3 1 68 06b 4 1 68 06c 5 1 68 06d 6 1 68 06e 7 1 68 06f 8 1 68 060 9 1 68 061 a 1 68 062 b 1 68 063 c 1 68 064 d 1 68 065 e 1 68 066 f 1 68 067 0 2 68 068 1 2 68 06a 2 2 68 06c 3 2 68 06e 4 2 68 070 5 2 68 072 6 2 68 074 7 2 68 076 8 2 68 058 9 2 68 05a a 2 68 05c b 2 68 05e c 2 68 060 d 2 68 062 e 2 68 064 f 2 68 066 0 3 68 068 1 3 68 06b 2 3 68 06e 3 3 68 071 4 3 68 074 5 3 68 077 6 3 68 07a 7 3 68 07d 8 3 68 050 9 3 68 053 a 3 68 056 b 3 68 059 c 3 68 05c d 3 68 05f e 3 68 062 f 3 68 065 0 4 68 068 1 4 68 06c 2 4 68 070 3 4 68 074 4 4 68 078 5 4 68 07c 6 4 68 080 7 4 68 084 8 4 68 048 9 4 68 04c a 4 68 050 b 4 68 054 c 4 68 058 d 4 68 05c e 4 68 060 f 4 68 064 0 5 68 068 1 5 68 06d 2 5 68 072 3 5 68 077 4 5 68 07c 5 5 68 081 6 5 68 086 7 5 68 08b 8 5 68 040 9 5 68 045 a 5 68 04a b 5 68 04f c 5 68 054 d 5 68 059 e 5 68 05e f 5 68 063 0 6 68 068 1 6 68 06e 2 6 68 074 3 6 68 07a 4 6 68 080 5 6 68 086 6 6 68 08c 7 6 68 092 8 6 68 038 9 6 68 03e a 6 68 044 b 6 68 04a c 6 68 050 d 6 68 056 e 6 68 05c f 6 68 062 0 7 68 068 1 7 68 06f 2 7 68 076 3 7 68 07d 4 7 68 084 5 7 68 08b 6 7 68 092 7 7 68 099 8 7 68 030 9 7 68 037 a 7 68 03e b 7 68 045 c 7 68 04c d 7 68 053 e 7 68 05a f 7 68 061 0 8 68 068 1 8 68 060 2 8 68 058 3 8 68 050 4 8 68 048 5 8 68 040 6 8 68 038 7 8 68 030 8 8 68 0a8 9 8 68 0a0 a 8 68 098 b 8 68 090 c 8 68 088 d 8 68 080 e 8 68 078 f 8 68 070 0 9 68 068 1 9 68 061 2 9 68 05a 3 9 68 053 4 9 68 04c 5 9 68 045 6 9 68 03e 7 9 68 037 8 9 68 0a0 9 9 68 099 a 9 68 092 b 9 68 08b c 9 68 084 d 9 68 07d e 9 68 076 f 9 68 06f 0 a 68 068 1 a 68 062 2 a 68 05c 3 a 68 056 4 a 68 050 5 a 68 04a 6 a 68 044 7 a 68 03e 8 a 68 098 9 a 68 092 a a 68 08c b a 68 086 c a 68 080 d a 68 07a e a 68 074 f a 68 06e 0 b 68 068 1 b 68 063 2 b 68 05e 3 b 68 059 4 b 68 054 5 b 68 04f 6 b 68 04a 7 b 68 045 8 b 68 090 9 b 68 08b a b 68 086 b b 68 081 c b 68 07c d b 68 077 e b 68 072 f b 68 06d 0 c 68 068 1 c 68 064 2 c 68 060 3 c 68 05c 4 c 68 058 5 c 68 054 6 c 68 050 7 c 68 04c 8 c 68 088 9 c 68 084 a c 68 080 b c 68 07c c c 68 078 d c 68 074 e c 68 070 f c 68 06c 0 d 68 068 1 d 68 065 2 d 68 062 3 d 68 05f 4 d 68 05c 5 d 68 059 6 d 68 056 7 d 68 053 8 d 68 080 9 d 68 07d a d 68 07a b d 68 077 c d 68 074 d d 68 071 e d 68 06e f d 68 06b 0 e 68 068 1 e 68 066 2 e 68 064 3 e 68 062 4 e 68 060 5 e 68 05e 6 e 68 05c 7 e 68 05a 8 e 68 078 9 e 68 076 a e 68 074 b e 68 072 c e 68 070 d e 68 06e e e 68 06c f e 68 06a 0 f 68 068 1 f 68 067 2 f 68 066 3 f 68 065 4 f 68 064 5 f 68 063 6 f 68 062 7 f 68 061 8 f 68 070 9 f 68 06f a f 68 06e b f 68 06d c f 68 06c d f 68 06b e f 68 06a f f 68 069 0 0 69 069 1 0 69 069 2 0 69 069 3 0 69 069 4 0 69 069 5 0 69 069 6 0 69 069 7 0 69 069 8 0 69 069 9 0 69 069 a 0 69 069 b 0 69 069 c 0 69 069 d 0 69 069 e 0 69 069 f 0 69 069 0 1 69 069 1 1 69 06a 2 1 69 06b 3 1 69 06c 4 1 69 06d 5 1 69 06e 6 1 69 06f 7 1 69 070 8 1 69 061 9 1 69 062 a 1 69 063 b 1 69 064 c 1 69 065 d 1 69 066 e 1 69 067 f 1 69 068 0 2 69 069 1 2 69 06b 2 2 69 06d 3 2 69 06f 4 2 69 071 5 2 69 073 6 2 69 075 7 2 69 077 8 2 69 059 9 2 69 05b a 2 69 05d b 2 69 05f c 2 69 061 d 2 69 063 e 2 69 065 f 2 69 067 0 3 69 069 1 3 69 06c 2 3 69 06f 3 3 69 072 4 3 69 075 5 3 69 078 6 3 69 07b 7 3 69 07e 8 3 69 051 9 3 69 054 a 3 69 057 b 3 69 05a c 3 69 05d d 3 69 060 e 3 69 063 f 3 69 066 0 4 69 069 1 4 69 06d 2 4 69 071 3 4 69 075 4 4 69 079 5 4 69 07d 6 4 69 081 7 4 69 085 8 4 69 049 9 4 69 04d a 4 69 051 b 4 69 055 c 4 69 059 d 4 69 05d e 4 69 061 f 4 69 065 0 5 69 069 1 5 69 06e 2 5 69 073 3 5 69 078 4 5 69 07d 5 5 69 082 6 5 69 087 7 5 69 08c 8 5 69 041 9 5 69 046 a 5 69 04b b 5 69 050 c 5 69 055 d 5 69 05a e 5 69 05f f 5 69 064 0 6 69 069 1 6 69 06f 2 6 69 075 3 6 69 07b 4 6 69 081 5 6 69 087 6 6 69 08d 7 6 69 093 8 6 69 039 9 6 69 03f a 6 69 045 b 6 69 04b c 6 69 051 d 6 69 057 e 6 69 05d f 6 69 063 0 7 69 069 1 7 69 070 2 7 69 077 3 7 69 07e 4 7 69 085 5 7 69 08c 6 7 69 093 7 7 69 09a 8 7 69 031 9 7 69 038 a 7 69 03f b 7 69 046 c 7 69 04d d 7 69 054 e 7 69 05b f 7 69 062 0 8 69 069 1 8 69 061 2 8 69 059 3 8 69 051 4 8 69 049 5 8 69 041 6 8 69 039 7 8 69 031 8 8 69 0a9 9 8 69 0a1 a 8 69 099 b 8 69 091 c 8 69 089 d 8 69 081 e 8 69 079 f 8 69 071 0 9 69 069 1 9 69 062 2 9 69 05b 3 9 69 054 4 9 69 04d 5 9 69 046 6 9 69 03f 7 9 69 038 8 9 69 0a1 9 9 69 09a a 9 69 093 b 9 69 08c c 9 69 085 d 9 69 07e e 9 69 077 f 9 69 070 0 a 69 069 1 a 69 063 2 a 69 05d 3 a 69 057 4 a 69 051 5 a 69 04b 6 a 69 045 7 a 69 03f 8 a 69 099 9 a 69 093 a a 69 08d b a 69 087 c a 69 081 d a 69 07b e a 69 075 f a 69 06f 0 b 69 069 1 b 69 064 2 b 69 05f 3 b 69 05a 4 b 69 055 5 b 69 050 6 b 69 04b 7 b 69 046 8 b 69 091 9 b 69 08c a b 69 087 b b 69 082 c b 69 07d d b 69 078 e b 69 073 f b 69 06e 0 c 69 069 1 c 69 065 2 c 69 061 3 c 69 05d 4 c 69 059 5 c 69 055 6 c 69 051 7 c 69 04d 8 c 69 089 9 c 69 085 a c 69 081 b c 69 07d c c 69 079 d c 69 075 e c 69 071 f c 69 06d 0 d 69 069 1 d 69 066 2 d 69 063 3 d 69 060 4 d 69 05d 5 d 69 05a 6 d 69 057 7 d 69 054 8 d 69 081 9 d 69 07e a d 69 07b b d 69 078 c d 69 075 d d 69 072 e d 69 06f f d 69 06c 0 e 69 069 1 e 69 067 2 e 69 065 3 e 69 063 4 e 69 061 5 e 69 05f 6 e 69 05d 7 e 69 05b 8 e 69 079 9 e 69 077 a e 69 075 b e 69 073 c e 69 071 d e 69 06f e e 69 06d f e 69 06b 0 f 69 069 1 f 69 068 2 f 69 067 3 f 69 066 4 f 69 065 5 f 69 064 6 f 69 063 7 f 69 062 8 f 69 071 9 f 69 070 a f 69 06f b f 69 06e c f 69 06d d f 69 06c e f 69 06b f f 69 06a 0 0 6a 06a 1 0 6a 06a 2 0 6a 06a 3 0 6a 06a 4 0 6a 06a 5 0 6a 06a 6 0 6a 06a 7 0 6a 06a 8 0 6a 06a 9 0 6a 06a a 0 6a 06a b 0 6a 06a c 0 6a 06a d 0 6a 06a e 0 6a 06a f 0 6a 06a 0 1 6a 06a 1 1 6a 06b 2 1 6a 06c 3 1 6a 06d 4 1 6a 06e 5 1 6a 06f 6 1 6a 070 7 1 6a 071 8 1 6a 062 9 1 6a 063 a 1 6a 064 b 1 6a 065 c 1 6a 066 d 1 6a 067 e 1 6a 068 f 1 6a 069 0 2 6a 06a 1 2 6a 06c 2 2 6a 06e 3 2 6a 070 4 2 6a 072 5 2 6a 074 6 2 6a 076 7 2 6a 078 8 2 6a 05a 9 2 6a 05c a 2 6a 05e b 2 6a 060 c 2 6a 062 d 2 6a 064 e 2 6a 066 f 2 6a 068 0 3 6a 06a 1 3 6a 06d 2 3 6a 070 3 3 6a 073 4 3 6a 076 5 3 6a 079 6 3 6a 07c 7 3 6a 07f 8 3 6a 052 9 3 6a 055 a 3 6a 058 b 3 6a 05b c 3 6a 05e d 3 6a 061 e 3 6a 064 f 3 6a 067 0 4 6a 06a 1 4 6a 06e 2 4 6a 072 3 4 6a 076 4 4 6a 07a 5 4 6a 07e 6 4 6a 082 7 4 6a 086 8 4 6a 04a 9 4 6a 04e a 4 6a 052 b 4 6a 056 c 4 6a 05a d 4 6a 05e e 4 6a 062 f 4 6a 066 0 5 6a 06a 1 5 6a 06f 2 5 6a 074 3 5 6a 079 4 5 6a 07e 5 5 6a 083 6 5 6a 088 7 5 6a 08d 8 5 6a 042 9 5 6a 047 a 5 6a 04c b 5 6a 051 c 5 6a 056 d 5 6a 05b e 5 6a 060 f 5 6a 065 0 6 6a 06a 1 6 6a 070 2 6 6a 076 3 6 6a 07c 4 6 6a 082 5 6 6a 088 6 6 6a 08e 7 6 6a 094 8 6 6a 03a 9 6 6a 040 a 6 6a 046 b 6 6a 04c c 6 6a 052 d 6 6a 058 e 6 6a 05e f 6 6a 064 0 7 6a 06a 1 7 6a 071 2 7 6a 078 3 7 6a 07f 4 7 6a 086 5 7 6a 08d 6 7 6a 094 7 7 6a 09b 8 7 6a 032 9 7 6a 039 a 7 6a 040 b 7 6a 047 c 7 6a 04e d 7 6a 055 e 7 6a 05c f 7 6a 063 0 8 6a 06a 1 8 6a 062 2 8 6a 05a 3 8 6a 052 4 8 6a 04a 5 8 6a 042 6 8 6a 03a 7 8 6a 032 8 8 6a 0aa 9 8 6a 0a2 a 8 6a 09a b 8 6a 092 c 8 6a 08a d 8 6a 082 e 8 6a 07a f 8 6a 072 0 9 6a 06a 1 9 6a 063 2 9 6a 05c 3 9 6a 055 4 9 6a 04e 5 9 6a 047 6 9 6a 040 7 9 6a 039 8 9 6a 0a2 9 9 6a 09b a 9 6a 094 b 9 6a 08d c 9 6a 086 d 9 6a 07f e 9 6a 078 f 9 6a 071 0 a 6a 06a 1 a 6a 064 2 a 6a 05e 3 a 6a 058 4 a 6a 052 5 a 6a 04c 6 a 6a 046 7 a 6a 040 8 a 6a 09a 9 a 6a 094 a a 6a 08e b a 6a 088 c a 6a 082 d a 6a 07c e a 6a 076 f a 6a 070 0 b 6a 06a 1 b 6a 065 2 b 6a 060 3 b 6a 05b 4 b 6a 056 5 b 6a 051 6 b 6a 04c 7 b 6a 047 8 b 6a 092 9 b 6a 08d a b 6a 088 b b 6a 083 c b 6a 07e d b 6a 079 e b 6a 074 f b 6a 06f 0 c 6a 06a 1 c 6a 066 2 c 6a 062 3 c 6a 05e 4 c 6a 05a 5 c 6a 056 6 c 6a 052 7 c 6a 04e 8 c 6a 08a 9 c 6a 086 a c 6a 082 b c 6a 07e c c 6a 07a d c 6a 076 e c 6a 072 f c 6a 06e 0 d 6a 06a 1 d 6a 067 2 d 6a 064 3 d 6a 061 4 d 6a 05e 5 d 6a 05b 6 d 6a 058 7 d 6a 055 8 d 6a 082 9 d 6a 07f a d 6a 07c b d 6a 079 c d 6a 076 d d 6a 073 e d 6a 070 f d 6a 06d 0 e 6a 06a 1 e 6a 068 2 e 6a 066 3 e 6a 064 4 e 6a 062 5 e 6a 060 6 e 6a 05e 7 e 6a 05c 8 e 6a 07a 9 e 6a 078 a e 6a 076 b e 6a 074 c e 6a 072 d e 6a 070 e e 6a 06e f e 6a 06c 0 f 6a 06a 1 f 6a 069 2 f 6a 068 3 f 6a 067 4 f 6a 066 5 f 6a 065 6 f 6a 064 7 f 6a 063 8 f 6a 072 9 f 6a 071 a f 6a 070 b f 6a 06f c f 6a 06e d f 6a 06d e f 6a 06c f f 6a 06b 0 0 6b 06b 1 0 6b 06b 2 0 6b 06b 3 0 6b 06b 4 0 6b 06b 5 0 6b 06b 6 0 6b 06b 7 0 6b 06b 8 0 6b 06b 9 0 6b 06b a 0 6b 06b b 0 6b 06b c 0 6b 06b d 0 6b 06b e 0 6b 06b f 0 6b 06b 0 1 6b 06b 1 1 6b 06c 2 1 6b 06d 3 1 6b 06e 4 1 6b 06f 5 1 6b 070 6 1 6b 071 7 1 6b 072 8 1 6b 063 9 1 6b 064 a 1 6b 065 b 1 6b 066 c 1 6b 067 d 1 6b 068 e 1 6b 069 f 1 6b 06a 0 2 6b 06b 1 2 6b 06d 2 2 6b 06f 3 2 6b 071 4 2 6b 073 5 2 6b 075 6 2 6b 077 7 2 6b 079 8 2 6b 05b 9 2 6b 05d a 2 6b 05f b 2 6b 061 c 2 6b 063 d 2 6b 065 e 2 6b 067 f 2 6b 069 0 3 6b 06b 1 3 6b 06e 2 3 6b 071 3 3 6b 074 4 3 6b 077 5 3 6b 07a 6 3 6b 07d 7 3 6b 080 8 3 6b 053 9 3 6b 056 a 3 6b 059 b 3 6b 05c c 3 6b 05f d 3 6b 062 e 3 6b 065 f 3 6b 068 0 4 6b 06b 1 4 6b 06f 2 4 6b 073 3 4 6b 077 4 4 6b 07b 5 4 6b 07f 6 4 6b 083 7 4 6b 087 8 4 6b 04b 9 4 6b 04f a 4 6b 053 b 4 6b 057 c 4 6b 05b d 4 6b 05f e 4 6b 063 f 4 6b 067 0 5 6b 06b 1 5 6b 070 2 5 6b 075 3 5 6b 07a 4 5 6b 07f 5 5 6b 084 6 5 6b 089 7 5 6b 08e 8 5 6b 043 9 5 6b 048 a 5 6b 04d b 5 6b 052 c 5 6b 057 d 5 6b 05c e 5 6b 061 f 5 6b 066 0 6 6b 06b 1 6 6b 071 2 6 6b 077 3 6 6b 07d 4 6 6b 083 5 6 6b 089 6 6 6b 08f 7 6 6b 095 8 6 6b 03b 9 6 6b 041 a 6 6b 047 b 6 6b 04d c 6 6b 053 d 6 6b 059 e 6 6b 05f f 6 6b 065 0 7 6b 06b 1 7 6b 072 2 7 6b 079 3 7 6b 080 4 7 6b 087 5 7 6b 08e 6 7 6b 095 7 7 6b 09c 8 7 6b 033 9 7 6b 03a a 7 6b 041 b 7 6b 048 c 7 6b 04f d 7 6b 056 e 7 6b 05d f 7 6b 064 0 8 6b 06b 1 8 6b 063 2 8 6b 05b 3 8 6b 053 4 8 6b 04b 5 8 6b 043 6 8 6b 03b 7 8 6b 033 8 8 6b 0ab 9 8 6b 0a3 a 8 6b 09b b 8 6b 093 c 8 6b 08b d 8 6b 083 e 8 6b 07b f 8 6b 073 0 9 6b 06b 1 9 6b 064 2 9 6b 05d 3 9 6b 056 4 9 6b 04f 5 9 6b 048 6 9 6b 041 7 9 6b 03a 8 9 6b 0a3 9 9 6b 09c a 9 6b 095 b 9 6b 08e c 9 6b 087 d 9 6b 080 e 9 6b 079 f 9 6b 072 0 a 6b 06b 1 a 6b 065 2 a 6b 05f 3 a 6b 059 4 a 6b 053 5 a 6b 04d 6 a 6b 047 7 a 6b 041 8 a 6b 09b 9 a 6b 095 a a 6b 08f b a 6b 089 c a 6b 083 d a 6b 07d e a 6b 077 f a 6b 071 0 b 6b 06b 1 b 6b 066 2 b 6b 061 3 b 6b 05c 4 b 6b 057 5 b 6b 052 6 b 6b 04d 7 b 6b 048 8 b 6b 093 9 b 6b 08e a b 6b 089 b b 6b 084 c b 6b 07f d b 6b 07a e b 6b 075 f b 6b 070 0 c 6b 06b 1 c 6b 067 2 c 6b 063 3 c 6b 05f 4 c 6b 05b 5 c 6b 057 6 c 6b 053 7 c 6b 04f 8 c 6b 08b 9 c 6b 087 a c 6b 083 b c 6b 07f c c 6b 07b d c 6b 077 e c 6b 073 f c 6b 06f 0 d 6b 06b 1 d 6b 068 2 d 6b 065 3 d 6b 062 4 d 6b 05f 5 d 6b 05c 6 d 6b 059 7 d 6b 056 8 d 6b 083 9 d 6b 080 a d 6b 07d b d 6b 07a c d 6b 077 d d 6b 074 e d 6b 071 f d 6b 06e 0 e 6b 06b 1 e 6b 069 2 e 6b 067 3 e 6b 065 4 e 6b 063 5 e 6b 061 6 e 6b 05f 7 e 6b 05d 8 e 6b 07b 9 e 6b 079 a e 6b 077 b e 6b 075 c e 6b 073 d e 6b 071 e e 6b 06f f e 6b 06d 0 f 6b 06b 1 f 6b 06a 2 f 6b 069 3 f 6b 068 4 f 6b 067 5 f 6b 066 6 f 6b 065 7 f 6b 064 8 f 6b 073 9 f 6b 072 a f 6b 071 b f 6b 070 c f 6b 06f d f 6b 06e e f 6b 06d f f 6b 06c 0 0 6c 06c 1 0 6c 06c 2 0 6c 06c 3 0 6c 06c 4 0 6c 06c 5 0 6c 06c 6 0 6c 06c 7 0 6c 06c 8 0 6c 06c 9 0 6c 06c a 0 6c 06c b 0 6c 06c c 0 6c 06c d 0 6c 06c e 0 6c 06c f 0 6c 06c 0 1 6c 06c 1 1 6c 06d 2 1 6c 06e 3 1 6c 06f 4 1 6c 070 5 1 6c 071 6 1 6c 072 7 1 6c 073 8 1 6c 064 9 1 6c 065 a 1 6c 066 b 1 6c 067 c 1 6c 068 d 1 6c 069 e 1 6c 06a f 1 6c 06b 0 2 6c 06c 1 2 6c 06e 2 2 6c 070 3 2 6c 072 4 2 6c 074 5 2 6c 076 6 2 6c 078 7 2 6c 07a 8 2 6c 05c 9 2 6c 05e a 2 6c 060 b 2 6c 062 c 2 6c 064 d 2 6c 066 e 2 6c 068 f 2 6c 06a 0 3 6c 06c 1 3 6c 06f 2 3 6c 072 3 3 6c 075 4 3 6c 078 5 3 6c 07b 6 3 6c 07e 7 3 6c 081 8 3 6c 054 9 3 6c 057 a 3 6c 05a b 3 6c 05d c 3 6c 060 d 3 6c 063 e 3 6c 066 f 3 6c 069 0 4 6c 06c 1 4 6c 070 2 4 6c 074 3 4 6c 078 4 4 6c 07c 5 4 6c 080 6 4 6c 084 7 4 6c 088 8 4 6c 04c 9 4 6c 050 a 4 6c 054 b 4 6c 058 c 4 6c 05c d 4 6c 060 e 4 6c 064 f 4 6c 068 0 5 6c 06c 1 5 6c 071 2 5 6c 076 3 5 6c 07b 4 5 6c 080 5 5 6c 085 6 5 6c 08a 7 5 6c 08f 8 5 6c 044 9 5 6c 049 a 5 6c 04e b 5 6c 053 c 5 6c 058 d 5 6c 05d e 5 6c 062 f 5 6c 067 0 6 6c 06c 1 6 6c 072 2 6 6c 078 3 6 6c 07e 4 6 6c 084 5 6 6c 08a 6 6 6c 090 7 6 6c 096 8 6 6c 03c 9 6 6c 042 a 6 6c 048 b 6 6c 04e c 6 6c 054 d 6 6c 05a e 6 6c 060 f 6 6c 066 0 7 6c 06c 1 7 6c 073 2 7 6c 07a 3 7 6c 081 4 7 6c 088 5 7 6c 08f 6 7 6c 096 7 7 6c 09d 8 7 6c 034 9 7 6c 03b a 7 6c 042 b 7 6c 049 c 7 6c 050 d 7 6c 057 e 7 6c 05e f 7 6c 065 0 8 6c 06c 1 8 6c 064 2 8 6c 05c 3 8 6c 054 4 8 6c 04c 5 8 6c 044 6 8 6c 03c 7 8 6c 034 8 8 6c 0ac 9 8 6c 0a4 a 8 6c 09c b 8 6c 094 c 8 6c 08c d 8 6c 084 e 8 6c 07c f 8 6c 074 0 9 6c 06c 1 9 6c 065 2 9 6c 05e 3 9 6c 057 4 9 6c 050 5 9 6c 049 6 9 6c 042 7 9 6c 03b 8 9 6c 0a4 9 9 6c 09d a 9 6c 096 b 9 6c 08f c 9 6c 088 d 9 6c 081 e 9 6c 07a f 9 6c 073 0 a 6c 06c 1 a 6c 066 2 a 6c 060 3 a 6c 05a 4 a 6c 054 5 a 6c 04e 6 a 6c 048 7 a 6c 042 8 a 6c 09c 9 a 6c 096 a a 6c 090 b a 6c 08a c a 6c 084 d a 6c 07e e a 6c 078 f a 6c 072 0 b 6c 06c 1 b 6c 067 2 b 6c 062 3 b 6c 05d 4 b 6c 058 5 b 6c 053 6 b 6c 04e 7 b 6c 049 8 b 6c 094 9 b 6c 08f a b 6c 08a b b 6c 085 c b 6c 080 d b 6c 07b e b 6c 076 f b 6c 071 0 c 6c 06c 1 c 6c 068 2 c 6c 064 3 c 6c 060 4 c 6c 05c 5 c 6c 058 6 c 6c 054 7 c 6c 050 8 c 6c 08c 9 c 6c 088 a c 6c 084 b c 6c 080 c c 6c 07c d c 6c 078 e c 6c 074 f c 6c 070 0 d 6c 06c 1 d 6c 069 2 d 6c 066 3 d 6c 063 4 d 6c 060 5 d 6c 05d 6 d 6c 05a 7 d 6c 057 8 d 6c 084 9 d 6c 081 a d 6c 07e b d 6c 07b c d 6c 078 d d 6c 075 e d 6c 072 f d 6c 06f 0 e 6c 06c 1 e 6c 06a 2 e 6c 068 3 e 6c 066 4 e 6c 064 5 e 6c 062 6 e 6c 060 7 e 6c 05e 8 e 6c 07c 9 e 6c 07a a e 6c 078 b e 6c 076 c e 6c 074 d e 6c 072 e e 6c 070 f e 6c 06e 0 f 6c 06c 1 f 6c 06b 2 f 6c 06a 3 f 6c 069 4 f 6c 068 5 f 6c 067 6 f 6c 066 7 f 6c 065 8 f 6c 074 9 f 6c 073 a f 6c 072 b f 6c 071 c f 6c 070 d f 6c 06f e f 6c 06e f f 6c 06d 0 0 6d 06d 1 0 6d 06d 2 0 6d 06d 3 0 6d 06d 4 0 6d 06d 5 0 6d 06d 6 0 6d 06d 7 0 6d 06d 8 0 6d 06d 9 0 6d 06d a 0 6d 06d b 0 6d 06d c 0 6d 06d d 0 6d 06d e 0 6d 06d f 0 6d 06d 0 1 6d 06d 1 1 6d 06e 2 1 6d 06f 3 1 6d 070 4 1 6d 071 5 1 6d 072 6 1 6d 073 7 1 6d 074 8 1 6d 065 9 1 6d 066 a 1 6d 067 b 1 6d 068 c 1 6d 069 d 1 6d 06a e 1 6d 06b f 1 6d 06c 0 2 6d 06d 1 2 6d 06f 2 2 6d 071 3 2 6d 073 4 2 6d 075 5 2 6d 077 6 2 6d 079 7 2 6d 07b 8 2 6d 05d 9 2 6d 05f a 2 6d 061 b 2 6d 063 c 2 6d 065 d 2 6d 067 e 2 6d 069 f 2 6d 06b 0 3 6d 06d 1 3 6d 070 2 3 6d 073 3 3 6d 076 4 3 6d 079 5 3 6d 07c 6 3 6d 07f 7 3 6d 082 8 3 6d 055 9 3 6d 058 a 3 6d 05b b 3 6d 05e c 3 6d 061 d 3 6d 064 e 3 6d 067 f 3 6d 06a 0 4 6d 06d 1 4 6d 071 2 4 6d 075 3 4 6d 079 4 4 6d 07d 5 4 6d 081 6 4 6d 085 7 4 6d 089 8 4 6d 04d 9 4 6d 051 a 4 6d 055 b 4 6d 059 c 4 6d 05d d 4 6d 061 e 4 6d 065 f 4 6d 069 0 5 6d 06d 1 5 6d 072 2 5 6d 077 3 5 6d 07c 4 5 6d 081 5 5 6d 086 6 5 6d 08b 7 5 6d 090 8 5 6d 045 9 5 6d 04a a 5 6d 04f b 5 6d 054 c 5 6d 059 d 5 6d 05e e 5 6d 063 f 5 6d 068 0 6 6d 06d 1 6 6d 073 2 6 6d 079 3 6 6d 07f 4 6 6d 085 5 6 6d 08b 6 6 6d 091 7 6 6d 097 8 6 6d 03d 9 6 6d 043 a 6 6d 049 b 6 6d 04f c 6 6d 055 d 6 6d 05b e 6 6d 061 f 6 6d 067 0 7 6d 06d 1 7 6d 074 2 7 6d 07b 3 7 6d 082 4 7 6d 089 5 7 6d 090 6 7 6d 097 7 7 6d 09e 8 7 6d 035 9 7 6d 03c a 7 6d 043 b 7 6d 04a c 7 6d 051 d 7 6d 058 e 7 6d 05f f 7 6d 066 0 8 6d 06d 1 8 6d 065 2 8 6d 05d 3 8 6d 055 4 8 6d 04d 5 8 6d 045 6 8 6d 03d 7 8 6d 035 8 8 6d 0ad 9 8 6d 0a5 a 8 6d 09d b 8 6d 095 c 8 6d 08d d 8 6d 085 e 8 6d 07d f 8 6d 075 0 9 6d 06d 1 9 6d 066 2 9 6d 05f 3 9 6d 058 4 9 6d 051 5 9 6d 04a 6 9 6d 043 7 9 6d 03c 8 9 6d 0a5 9 9 6d 09e a 9 6d 097 b 9 6d 090 c 9 6d 089 d 9 6d 082 e 9 6d 07b f 9 6d 074 0 a 6d 06d 1 a 6d 067 2 a 6d 061 3 a 6d 05b 4 a 6d 055 5 a 6d 04f 6 a 6d 049 7 a 6d 043 8 a 6d 09d 9 a 6d 097 a a 6d 091 b a 6d 08b c a 6d 085 d a 6d 07f e a 6d 079 f a 6d 073 0 b 6d 06d 1 b 6d 068 2 b 6d 063 3 b 6d 05e 4 b 6d 059 5 b 6d 054 6 b 6d 04f 7 b 6d 04a 8 b 6d 095 9 b 6d 090 a b 6d 08b b b 6d 086 c b 6d 081 d b 6d 07c e b 6d 077 f b 6d 072 0 c 6d 06d 1 c 6d 069 2 c 6d 065 3 c 6d 061 4 c 6d 05d 5 c 6d 059 6 c 6d 055 7 c 6d 051 8 c 6d 08d 9 c 6d 089 a c 6d 085 b c 6d 081 c c 6d 07d d c 6d 079 e c 6d 075 f c 6d 071 0 d 6d 06d 1 d 6d 06a 2 d 6d 067 3 d 6d 064 4 d 6d 061 5 d 6d 05e 6 d 6d 05b 7 d 6d 058 8 d 6d 085 9 d 6d 082 a d 6d 07f b d 6d 07c c d 6d 079 d d 6d 076 e d 6d 073 f d 6d 070 0 e 6d 06d 1 e 6d 06b 2 e 6d 069 3 e 6d 067 4 e 6d 065 5 e 6d 063 6 e 6d 061 7 e 6d 05f 8 e 6d 07d 9 e 6d 07b a e 6d 079 b e 6d 077 c e 6d 075 d e 6d 073 e e 6d 071 f e 6d 06f 0 f 6d 06d 1 f 6d 06c 2 f 6d 06b 3 f 6d 06a 4 f 6d 069 5 f 6d 068 6 f 6d 067 7 f 6d 066 8 f 6d 075 9 f 6d 074 a f 6d 073 b f 6d 072 c f 6d 071 d f 6d 070 e f 6d 06f f f 6d 06e 0 0 6e 06e 1 0 6e 06e 2 0 6e 06e 3 0 6e 06e 4 0 6e 06e 5 0 6e 06e 6 0 6e 06e 7 0 6e 06e 8 0 6e 06e 9 0 6e 06e a 0 6e 06e b 0 6e 06e c 0 6e 06e d 0 6e 06e e 0 6e 06e f 0 6e 06e 0 1 6e 06e 1 1 6e 06f 2 1 6e 070 3 1 6e 071 4 1 6e 072 5 1 6e 073 6 1 6e 074 7 1 6e 075 8 1 6e 066 9 1 6e 067 a 1 6e 068 b 1 6e 069 c 1 6e 06a d 1 6e 06b e 1 6e 06c f 1 6e 06d 0 2 6e 06e 1 2 6e 070 2 2 6e 072 3 2 6e 074 4 2 6e 076 5 2 6e 078 6 2 6e 07a 7 2 6e 07c 8 2 6e 05e 9 2 6e 060 a 2 6e 062 b 2 6e 064 c 2 6e 066 d 2 6e 068 e 2 6e 06a f 2 6e 06c 0 3 6e 06e 1 3 6e 071 2 3 6e 074 3 3 6e 077 4 3 6e 07a 5 3 6e 07d 6 3 6e 080 7 3 6e 083 8 3 6e 056 9 3 6e 059 a 3 6e 05c b 3 6e 05f c 3 6e 062 d 3 6e 065 e 3 6e 068 f 3 6e 06b 0 4 6e 06e 1 4 6e 072 2 4 6e 076 3 4 6e 07a 4 4 6e 07e 5 4 6e 082 6 4 6e 086 7 4 6e 08a 8 4 6e 04e 9 4 6e 052 a 4 6e 056 b 4 6e 05a c 4 6e 05e d 4 6e 062 e 4 6e 066 f 4 6e 06a 0 5 6e 06e 1 5 6e 073 2 5 6e 078 3 5 6e 07d 4 5 6e 082 5 5 6e 087 6 5 6e 08c 7 5 6e 091 8 5 6e 046 9 5 6e 04b a 5 6e 050 b 5 6e 055 c 5 6e 05a d 5 6e 05f e 5 6e 064 f 5 6e 069 0 6 6e 06e 1 6 6e 074 2 6 6e 07a 3 6 6e 080 4 6 6e 086 5 6 6e 08c 6 6 6e 092 7 6 6e 098 8 6 6e 03e 9 6 6e 044 a 6 6e 04a b 6 6e 050 c 6 6e 056 d 6 6e 05c e 6 6e 062 f 6 6e 068 0 7 6e 06e 1 7 6e 075 2 7 6e 07c 3 7 6e 083 4 7 6e 08a 5 7 6e 091 6 7 6e 098 7 7 6e 09f 8 7 6e 036 9 7 6e 03d a 7 6e 044 b 7 6e 04b c 7 6e 052 d 7 6e 059 e 7 6e 060 f 7 6e 067 0 8 6e 06e 1 8 6e 066 2 8 6e 05e 3 8 6e 056 4 8 6e 04e 5 8 6e 046 6 8 6e 03e 7 8 6e 036 8 8 6e 0ae 9 8 6e 0a6 a 8 6e 09e b 8 6e 096 c 8 6e 08e d 8 6e 086 e 8 6e 07e f 8 6e 076 0 9 6e 06e 1 9 6e 067 2 9 6e 060 3 9 6e 059 4 9 6e 052 5 9 6e 04b 6 9 6e 044 7 9 6e 03d 8 9 6e 0a6 9 9 6e 09f a 9 6e 098 b 9 6e 091 c 9 6e 08a d 9 6e 083 e 9 6e 07c f 9 6e 075 0 a 6e 06e 1 a 6e 068 2 a 6e 062 3 a 6e 05c 4 a 6e 056 5 a 6e 050 6 a 6e 04a 7 a 6e 044 8 a 6e 09e 9 a 6e 098 a a 6e 092 b a 6e 08c c a 6e 086 d a 6e 080 e a 6e 07a f a 6e 074 0 b 6e 06e 1 b 6e 069 2 b 6e 064 3 b 6e 05f 4 b 6e 05a 5 b 6e 055 6 b 6e 050 7 b 6e 04b 8 b 6e 096 9 b 6e 091 a b 6e 08c b b 6e 087 c b 6e 082 d b 6e 07d e b 6e 078 f b 6e 073 0 c 6e 06e 1 c 6e 06a 2 c 6e 066 3 c 6e 062 4 c 6e 05e 5 c 6e 05a 6 c 6e 056 7 c 6e 052 8 c 6e 08e 9 c 6e 08a a c 6e 086 b c 6e 082 c c 6e 07e d c 6e 07a e c 6e 076 f c 6e 072 0 d 6e 06e 1 d 6e 06b 2 d 6e 068 3 d 6e 065 4 d 6e 062 5 d 6e 05f 6 d 6e 05c 7 d 6e 059 8 d 6e 086 9 d 6e 083 a d 6e 080 b d 6e 07d c d 6e 07a d d 6e 077 e d 6e 074 f d 6e 071 0 e 6e 06e 1 e 6e 06c 2 e 6e 06a 3 e 6e 068 4 e 6e 066 5 e 6e 064 6 e 6e 062 7 e 6e 060 8 e 6e 07e 9 e 6e 07c a e 6e 07a b e 6e 078 c e 6e 076 d e 6e 074 e e 6e 072 f e 6e 070 0 f 6e 06e 1 f 6e 06d 2 f 6e 06c 3 f 6e 06b 4 f 6e 06a 5 f 6e 069 6 f 6e 068 7 f 6e 067 8 f 6e 076 9 f 6e 075 a f 6e 074 b f 6e 073 c f 6e 072 d f 6e 071 e f 6e 070 f f 6e 06f 0 0 6f 06f 1 0 6f 06f 2 0 6f 06f 3 0 6f 06f 4 0 6f 06f 5 0 6f 06f 6 0 6f 06f 7 0 6f 06f 8 0 6f 06f 9 0 6f 06f a 0 6f 06f b 0 6f 06f c 0 6f 06f d 0 6f 06f e 0 6f 06f f 0 6f 06f 0 1 6f 06f 1 1 6f 070 2 1 6f 071 3 1 6f 072 4 1 6f 073 5 1 6f 074 6 1 6f 075 7 1 6f 076 8 1 6f 067 9 1 6f 068 a 1 6f 069 b 1 6f 06a c 1 6f 06b d 1 6f 06c e 1 6f 06d f 1 6f 06e 0 2 6f 06f 1 2 6f 071 2 2 6f 073 3 2 6f 075 4 2 6f 077 5 2 6f 079 6 2 6f 07b 7 2 6f 07d 8 2 6f 05f 9 2 6f 061 a 2 6f 063 b 2 6f 065 c 2 6f 067 d 2 6f 069 e 2 6f 06b f 2 6f 06d 0 3 6f 06f 1 3 6f 072 2 3 6f 075 3 3 6f 078 4 3 6f 07b 5 3 6f 07e 6 3 6f 081 7 3 6f 084 8 3 6f 057 9 3 6f 05a a 3 6f 05d b 3 6f 060 c 3 6f 063 d 3 6f 066 e 3 6f 069 f 3 6f 06c 0 4 6f 06f 1 4 6f 073 2 4 6f 077 3 4 6f 07b 4 4 6f 07f 5 4 6f 083 6 4 6f 087 7 4 6f 08b 8 4 6f 04f 9 4 6f 053 a 4 6f 057 b 4 6f 05b c 4 6f 05f d 4 6f 063 e 4 6f 067 f 4 6f 06b 0 5 6f 06f 1 5 6f 074 2 5 6f 079 3 5 6f 07e 4 5 6f 083 5 5 6f 088 6 5 6f 08d 7 5 6f 092 8 5 6f 047 9 5 6f 04c a 5 6f 051 b 5 6f 056 c 5 6f 05b d 5 6f 060 e 5 6f 065 f 5 6f 06a 0 6 6f 06f 1 6 6f 075 2 6 6f 07b 3 6 6f 081 4 6 6f 087 5 6 6f 08d 6 6 6f 093 7 6 6f 099 8 6 6f 03f 9 6 6f 045 a 6 6f 04b b 6 6f 051 c 6 6f 057 d 6 6f 05d e 6 6f 063 f 6 6f 069 0 7 6f 06f 1 7 6f 076 2 7 6f 07d 3 7 6f 084 4 7 6f 08b 5 7 6f 092 6 7 6f 099 7 7 6f 0a0 8 7 6f 037 9 7 6f 03e a 7 6f 045 b 7 6f 04c c 7 6f 053 d 7 6f 05a e 7 6f 061 f 7 6f 068 0 8 6f 06f 1 8 6f 067 2 8 6f 05f 3 8 6f 057 4 8 6f 04f 5 8 6f 047 6 8 6f 03f 7 8 6f 037 8 8 6f 0af 9 8 6f 0a7 a 8 6f 09f b 8 6f 097 c 8 6f 08f d 8 6f 087 e 8 6f 07f f 8 6f 077 0 9 6f 06f 1 9 6f 068 2 9 6f 061 3 9 6f 05a 4 9 6f 053 5 9 6f 04c 6 9 6f 045 7 9 6f 03e 8 9 6f 0a7 9 9 6f 0a0 a 9 6f 099 b 9 6f 092 c 9 6f 08b d 9 6f 084 e 9 6f 07d f 9 6f 076 0 a 6f 06f 1 a 6f 069 2 a 6f 063 3 a 6f 05d 4 a 6f 057 5 a 6f 051 6 a 6f 04b 7 a 6f 045 8 a 6f 09f 9 a 6f 099 a a 6f 093 b a 6f 08d c a 6f 087 d a 6f 081 e a 6f 07b f a 6f 075 0 b 6f 06f 1 b 6f 06a 2 b 6f 065 3 b 6f 060 4 b 6f 05b 5 b 6f 056 6 b 6f 051 7 b 6f 04c 8 b 6f 097 9 b 6f 092 a b 6f 08d b b 6f 088 c b 6f 083 d b 6f 07e e b 6f 079 f b 6f 074 0 c 6f 06f 1 c 6f 06b 2 c 6f 067 3 c 6f 063 4 c 6f 05f 5 c 6f 05b 6 c 6f 057 7 c 6f 053 8 c 6f 08f 9 c 6f 08b a c 6f 087 b c 6f 083 c c 6f 07f d c 6f 07b e c 6f 077 f c 6f 073 0 d 6f 06f 1 d 6f 06c 2 d 6f 069 3 d 6f 066 4 d 6f 063 5 d 6f 060 6 d 6f 05d 7 d 6f 05a 8 d 6f 087 9 d 6f 084 a d 6f 081 b d 6f 07e c d 6f 07b d d 6f 078 e d 6f 075 f d 6f 072 0 e 6f 06f 1 e 6f 06d 2 e 6f 06b 3 e 6f 069 4 e 6f 067 5 e 6f 065 6 e 6f 063 7 e 6f 061 8 e 6f 07f 9 e 6f 07d a e 6f 07b b e 6f 079 c e 6f 077 d e 6f 075 e e 6f 073 f e 6f 071 0 f 6f 06f 1 f 6f 06e 2 f 6f 06d 3 f 6f 06c 4 f 6f 06b 5 f 6f 06a 6 f 6f 069 7 f 6f 068 8 f 6f 077 9 f 6f 076 a f 6f 075 b f 6f 074 c f 6f 073 d f 6f 072 e f 6f 071 f f 6f 070 0 0 70 070 1 0 70 070 2 0 70 070 3 0 70 070 4 0 70 070 5 0 70 070 6 0 70 070 7 0 70 070 8 0 70 070 9 0 70 070 a 0 70 070 b 0 70 070 c 0 70 070 d 0 70 070 e 0 70 070 f 0 70 070 0 1 70 070 1 1 70 071 2 1 70 072 3 1 70 073 4 1 70 074 5 1 70 075 6 1 70 076 7 1 70 077 8 1 70 068 9 1 70 069 a 1 70 06a b 1 70 06b c 1 70 06c d 1 70 06d e 1 70 06e f 1 70 06f 0 2 70 070 1 2 70 072 2 2 70 074 3 2 70 076 4 2 70 078 5 2 70 07a 6 2 70 07c 7 2 70 07e 8 2 70 060 9 2 70 062 a 2 70 064 b 2 70 066 c 2 70 068 d 2 70 06a e 2 70 06c f 2 70 06e 0 3 70 070 1 3 70 073 2 3 70 076 3 3 70 079 4 3 70 07c 5 3 70 07f 6 3 70 082 7 3 70 085 8 3 70 058 9 3 70 05b a 3 70 05e b 3 70 061 c 3 70 064 d 3 70 067 e 3 70 06a f 3 70 06d 0 4 70 070 1 4 70 074 2 4 70 078 3 4 70 07c 4 4 70 080 5 4 70 084 6 4 70 088 7 4 70 08c 8 4 70 050 9 4 70 054 a 4 70 058 b 4 70 05c c 4 70 060 d 4 70 064 e 4 70 068 f 4 70 06c 0 5 70 070 1 5 70 075 2 5 70 07a 3 5 70 07f 4 5 70 084 5 5 70 089 6 5 70 08e 7 5 70 093 8 5 70 048 9 5 70 04d a 5 70 052 b 5 70 057 c 5 70 05c d 5 70 061 e 5 70 066 f 5 70 06b 0 6 70 070 1 6 70 076 2 6 70 07c 3 6 70 082 4 6 70 088 5 6 70 08e 6 6 70 094 7 6 70 09a 8 6 70 040 9 6 70 046 a 6 70 04c b 6 70 052 c 6 70 058 d 6 70 05e e 6 70 064 f 6 70 06a 0 7 70 070 1 7 70 077 2 7 70 07e 3 7 70 085 4 7 70 08c 5 7 70 093 6 7 70 09a 7 7 70 0a1 8 7 70 038 9 7 70 03f a 7 70 046 b 7 70 04d c 7 70 054 d 7 70 05b e 7 70 062 f 7 70 069 0 8 70 070 1 8 70 068 2 8 70 060 3 8 70 058 4 8 70 050 5 8 70 048 6 8 70 040 7 8 70 038 8 8 70 0b0 9 8 70 0a8 a 8 70 0a0 b 8 70 098 c 8 70 090 d 8 70 088 e 8 70 080 f 8 70 078 0 9 70 070 1 9 70 069 2 9 70 062 3 9 70 05b 4 9 70 054 5 9 70 04d 6 9 70 046 7 9 70 03f 8 9 70 0a8 9 9 70 0a1 a 9 70 09a b 9 70 093 c 9 70 08c d 9 70 085 e 9 70 07e f 9 70 077 0 a 70 070 1 a 70 06a 2 a 70 064 3 a 70 05e 4 a 70 058 5 a 70 052 6 a 70 04c 7 a 70 046 8 a 70 0a0 9 a 70 09a a a 70 094 b a 70 08e c a 70 088 d a 70 082 e a 70 07c f a 70 076 0 b 70 070 1 b 70 06b 2 b 70 066 3 b 70 061 4 b 70 05c 5 b 70 057 6 b 70 052 7 b 70 04d 8 b 70 098 9 b 70 093 a b 70 08e b b 70 089 c b 70 084 d b 70 07f e b 70 07a f b 70 075 0 c 70 070 1 c 70 06c 2 c 70 068 3 c 70 064 4 c 70 060 5 c 70 05c 6 c 70 058 7 c 70 054 8 c 70 090 9 c 70 08c a c 70 088 b c 70 084 c c 70 080 d c 70 07c e c 70 078 f c 70 074 0 d 70 070 1 d 70 06d 2 d 70 06a 3 d 70 067 4 d 70 064 5 d 70 061 6 d 70 05e 7 d 70 05b 8 d 70 088 9 d 70 085 a d 70 082 b d 70 07f c d 70 07c d d 70 079 e d 70 076 f d 70 073 0 e 70 070 1 e 70 06e 2 e 70 06c 3 e 70 06a 4 e 70 068 5 e 70 066 6 e 70 064 7 e 70 062 8 e 70 080 9 e 70 07e a e 70 07c b e 70 07a c e 70 078 d e 70 076 e e 70 074 f e 70 072 0 f 70 070 1 f 70 06f 2 f 70 06e 3 f 70 06d 4 f 70 06c 5 f 70 06b 6 f 70 06a 7 f 70 069 8 f 70 078 9 f 70 077 a f 70 076 b f 70 075 c f 70 074 d f 70 073 e f 70 072 f f 70 071 0 0 71 071 1 0 71 071 2 0 71 071 3 0 71 071 4 0 71 071 5 0 71 071 6 0 71 071 7 0 71 071 8 0 71 071 9 0 71 071 a 0 71 071 b 0 71 071 c 0 71 071 d 0 71 071 e 0 71 071 f 0 71 071 0 1 71 071 1 1 71 072 2 1 71 073 3 1 71 074 4 1 71 075 5 1 71 076 6 1 71 077 7 1 71 078 8 1 71 069 9 1 71 06a a 1 71 06b b 1 71 06c c 1 71 06d d 1 71 06e e 1 71 06f f 1 71 070 0 2 71 071 1 2 71 073 2 2 71 075 3 2 71 077 4 2 71 079 5 2 71 07b 6 2 71 07d 7 2 71 07f 8 2 71 061 9 2 71 063 a 2 71 065 b 2 71 067 c 2 71 069 d 2 71 06b e 2 71 06d f 2 71 06f 0 3 71 071 1 3 71 074 2 3 71 077 3 3 71 07a 4 3 71 07d 5 3 71 080 6 3 71 083 7 3 71 086 8 3 71 059 9 3 71 05c a 3 71 05f b 3 71 062 c 3 71 065 d 3 71 068 e 3 71 06b f 3 71 06e 0 4 71 071 1 4 71 075 2 4 71 079 3 4 71 07d 4 4 71 081 5 4 71 085 6 4 71 089 7 4 71 08d 8 4 71 051 9 4 71 055 a 4 71 059 b 4 71 05d c 4 71 061 d 4 71 065 e 4 71 069 f 4 71 06d 0 5 71 071 1 5 71 076 2 5 71 07b 3 5 71 080 4 5 71 085 5 5 71 08a 6 5 71 08f 7 5 71 094 8 5 71 049 9 5 71 04e a 5 71 053 b 5 71 058 c 5 71 05d d 5 71 062 e 5 71 067 f 5 71 06c 0 6 71 071 1 6 71 077 2 6 71 07d 3 6 71 083 4 6 71 089 5 6 71 08f 6 6 71 095 7 6 71 09b 8 6 71 041 9 6 71 047 a 6 71 04d b 6 71 053 c 6 71 059 d 6 71 05f e 6 71 065 f 6 71 06b 0 7 71 071 1 7 71 078 2 7 71 07f 3 7 71 086 4 7 71 08d 5 7 71 094 6 7 71 09b 7 7 71 0a2 8 7 71 039 9 7 71 040 a 7 71 047 b 7 71 04e c 7 71 055 d 7 71 05c e 7 71 063 f 7 71 06a 0 8 71 071 1 8 71 069 2 8 71 061 3 8 71 059 4 8 71 051 5 8 71 049 6 8 71 041 7 8 71 039 8 8 71 0b1 9 8 71 0a9 a 8 71 0a1 b 8 71 099 c 8 71 091 d 8 71 089 e 8 71 081 f 8 71 079 0 9 71 071 1 9 71 06a 2 9 71 063 3 9 71 05c 4 9 71 055 5 9 71 04e 6 9 71 047 7 9 71 040 8 9 71 0a9 9 9 71 0a2 a 9 71 09b b 9 71 094 c 9 71 08d d 9 71 086 e 9 71 07f f 9 71 078 0 a 71 071 1 a 71 06b 2 a 71 065 3 a 71 05f 4 a 71 059 5 a 71 053 6 a 71 04d 7 a 71 047 8 a 71 0a1 9 a 71 09b a a 71 095 b a 71 08f c a 71 089 d a 71 083 e a 71 07d f a 71 077 0 b 71 071 1 b 71 06c 2 b 71 067 3 b 71 062 4 b 71 05d 5 b 71 058 6 b 71 053 7 b 71 04e 8 b 71 099 9 b 71 094 a b 71 08f b b 71 08a c b 71 085 d b 71 080 e b 71 07b f b 71 076 0 c 71 071 1 c 71 06d 2 c 71 069 3 c 71 065 4 c 71 061 5 c 71 05d 6 c 71 059 7 c 71 055 8 c 71 091 9 c 71 08d a c 71 089 b c 71 085 c c 71 081 d c 71 07d e c 71 079 f c 71 075 0 d 71 071 1 d 71 06e 2 d 71 06b 3 d 71 068 4 d 71 065 5 d 71 062 6 d 71 05f 7 d 71 05c 8 d 71 089 9 d 71 086 a d 71 083 b d 71 080 c d 71 07d d d 71 07a e d 71 077 f d 71 074 0 e 71 071 1 e 71 06f 2 e 71 06d 3 e 71 06b 4 e 71 069 5 e 71 067 6 e 71 065 7 e 71 063 8 e 71 081 9 e 71 07f a e 71 07d b e 71 07b c e 71 079 d e 71 077 e e 71 075 f e 71 073 0 f 71 071 1 f 71 070 2 f 71 06f 3 f 71 06e 4 f 71 06d 5 f 71 06c 6 f 71 06b 7 f 71 06a 8 f 71 079 9 f 71 078 a f 71 077 b f 71 076 c f 71 075 d f 71 074 e f 71 073 f f 71 072 0 0 72 072 1 0 72 072 2 0 72 072 3 0 72 072 4 0 72 072 5 0 72 072 6 0 72 072 7 0 72 072 8 0 72 072 9 0 72 072 a 0 72 072 b 0 72 072 c 0 72 072 d 0 72 072 e 0 72 072 f 0 72 072 0 1 72 072 1 1 72 073 2 1 72 074 3 1 72 075 4 1 72 076 5 1 72 077 6 1 72 078 7 1 72 079 8 1 72 06a 9 1 72 06b a 1 72 06c b 1 72 06d c 1 72 06e d 1 72 06f e 1 72 070 f 1 72 071 0 2 72 072 1 2 72 074 2 2 72 076 3 2 72 078 4 2 72 07a 5 2 72 07c 6 2 72 07e 7 2 72 080 8 2 72 062 9 2 72 064 a 2 72 066 b 2 72 068 c 2 72 06a d 2 72 06c e 2 72 06e f 2 72 070 0 3 72 072 1 3 72 075 2 3 72 078 3 3 72 07b 4 3 72 07e 5 3 72 081 6 3 72 084 7 3 72 087 8 3 72 05a 9 3 72 05d a 3 72 060 b 3 72 063 c 3 72 066 d 3 72 069 e 3 72 06c f 3 72 06f 0 4 72 072 1 4 72 076 2 4 72 07a 3 4 72 07e 4 4 72 082 5 4 72 086 6 4 72 08a 7 4 72 08e 8 4 72 052 9 4 72 056 a 4 72 05a b 4 72 05e c 4 72 062 d 4 72 066 e 4 72 06a f 4 72 06e 0 5 72 072 1 5 72 077 2 5 72 07c 3 5 72 081 4 5 72 086 5 5 72 08b 6 5 72 090 7 5 72 095 8 5 72 04a 9 5 72 04f a 5 72 054 b 5 72 059 c 5 72 05e d 5 72 063 e 5 72 068 f 5 72 06d 0 6 72 072 1 6 72 078 2 6 72 07e 3 6 72 084 4 6 72 08a 5 6 72 090 6 6 72 096 7 6 72 09c 8 6 72 042 9 6 72 048 a 6 72 04e b 6 72 054 c 6 72 05a d 6 72 060 e 6 72 066 f 6 72 06c 0 7 72 072 1 7 72 079 2 7 72 080 3 7 72 087 4 7 72 08e 5 7 72 095 6 7 72 09c 7 7 72 0a3 8 7 72 03a 9 7 72 041 a 7 72 048 b 7 72 04f c 7 72 056 d 7 72 05d e 7 72 064 f 7 72 06b 0 8 72 072 1 8 72 06a 2 8 72 062 3 8 72 05a 4 8 72 052 5 8 72 04a 6 8 72 042 7 8 72 03a 8 8 72 0b2 9 8 72 0aa a 8 72 0a2 b 8 72 09a c 8 72 092 d 8 72 08a e 8 72 082 f 8 72 07a 0 9 72 072 1 9 72 06b 2 9 72 064 3 9 72 05d 4 9 72 056 5 9 72 04f 6 9 72 048 7 9 72 041 8 9 72 0aa 9 9 72 0a3 a 9 72 09c b 9 72 095 c 9 72 08e d 9 72 087 e 9 72 080 f 9 72 079 0 a 72 072 1 a 72 06c 2 a 72 066 3 a 72 060 4 a 72 05a 5 a 72 054 6 a 72 04e 7 a 72 048 8 a 72 0a2 9 a 72 09c a a 72 096 b a 72 090 c a 72 08a d a 72 084 e a 72 07e f a 72 078 0 b 72 072 1 b 72 06d 2 b 72 068 3 b 72 063 4 b 72 05e 5 b 72 059 6 b 72 054 7 b 72 04f 8 b 72 09a 9 b 72 095 a b 72 090 b b 72 08b c b 72 086 d b 72 081 e b 72 07c f b 72 077 0 c 72 072 1 c 72 06e 2 c 72 06a 3 c 72 066 4 c 72 062 5 c 72 05e 6 c 72 05a 7 c 72 056 8 c 72 092 9 c 72 08e a c 72 08a b c 72 086 c c 72 082 d c 72 07e e c 72 07a f c 72 076 0 d 72 072 1 d 72 06f 2 d 72 06c 3 d 72 069 4 d 72 066 5 d 72 063 6 d 72 060 7 d 72 05d 8 d 72 08a 9 d 72 087 a d 72 084 b d 72 081 c d 72 07e d d 72 07b e d 72 078 f d 72 075 0 e 72 072 1 e 72 070 2 e 72 06e 3 e 72 06c 4 e 72 06a 5 e 72 068 6 e 72 066 7 e 72 064 8 e 72 082 9 e 72 080 a e 72 07e b e 72 07c c e 72 07a d e 72 078 e e 72 076 f e 72 074 0 f 72 072 1 f 72 071 2 f 72 070 3 f 72 06f 4 f 72 06e 5 f 72 06d 6 f 72 06c 7 f 72 06b 8 f 72 07a 9 f 72 079 a f 72 078 b f 72 077 c f 72 076 d f 72 075 e f 72 074 f f 72 073 0 0 73 073 1 0 73 073 2 0 73 073 3 0 73 073 4 0 73 073 5 0 73 073 6 0 73 073 7 0 73 073 8 0 73 073 9 0 73 073 a 0 73 073 b 0 73 073 c 0 73 073 d 0 73 073 e 0 73 073 f 0 73 073 0 1 73 073 1 1 73 074 2 1 73 075 3 1 73 076 4 1 73 077 5 1 73 078 6 1 73 079 7 1 73 07a 8 1 73 06b 9 1 73 06c a 1 73 06d b 1 73 06e c 1 73 06f d 1 73 070 e 1 73 071 f 1 73 072 0 2 73 073 1 2 73 075 2 2 73 077 3 2 73 079 4 2 73 07b 5 2 73 07d 6 2 73 07f 7 2 73 081 8 2 73 063 9 2 73 065 a 2 73 067 b 2 73 069 c 2 73 06b d 2 73 06d e 2 73 06f f 2 73 071 0 3 73 073 1 3 73 076 2 3 73 079 3 3 73 07c 4 3 73 07f 5 3 73 082 6 3 73 085 7 3 73 088 8 3 73 05b 9 3 73 05e a 3 73 061 b 3 73 064 c 3 73 067 d 3 73 06a e 3 73 06d f 3 73 070 0 4 73 073 1 4 73 077 2 4 73 07b 3 4 73 07f 4 4 73 083 5 4 73 087 6 4 73 08b 7 4 73 08f 8 4 73 053 9 4 73 057 a 4 73 05b b 4 73 05f c 4 73 063 d 4 73 067 e 4 73 06b f 4 73 06f 0 5 73 073 1 5 73 078 2 5 73 07d 3 5 73 082 4 5 73 087 5 5 73 08c 6 5 73 091 7 5 73 096 8 5 73 04b 9 5 73 050 a 5 73 055 b 5 73 05a c 5 73 05f d 5 73 064 e 5 73 069 f 5 73 06e 0 6 73 073 1 6 73 079 2 6 73 07f 3 6 73 085 4 6 73 08b 5 6 73 091 6 6 73 097 7 6 73 09d 8 6 73 043 9 6 73 049 a 6 73 04f b 6 73 055 c 6 73 05b d 6 73 061 e 6 73 067 f 6 73 06d 0 7 73 073 1 7 73 07a 2 7 73 081 3 7 73 088 4 7 73 08f 5 7 73 096 6 7 73 09d 7 7 73 0a4 8 7 73 03b 9 7 73 042 a 7 73 049 b 7 73 050 c 7 73 057 d 7 73 05e e 7 73 065 f 7 73 06c 0 8 73 073 1 8 73 06b 2 8 73 063 3 8 73 05b 4 8 73 053 5 8 73 04b 6 8 73 043 7 8 73 03b 8 8 73 0b3 9 8 73 0ab a 8 73 0a3 b 8 73 09b c 8 73 093 d 8 73 08b e 8 73 083 f 8 73 07b 0 9 73 073 1 9 73 06c 2 9 73 065 3 9 73 05e 4 9 73 057 5 9 73 050 6 9 73 049 7 9 73 042 8 9 73 0ab 9 9 73 0a4 a 9 73 09d b 9 73 096 c 9 73 08f d 9 73 088 e 9 73 081 f 9 73 07a 0 a 73 073 1 a 73 06d 2 a 73 067 3 a 73 061 4 a 73 05b 5 a 73 055 6 a 73 04f 7 a 73 049 8 a 73 0a3 9 a 73 09d a a 73 097 b a 73 091 c a 73 08b d a 73 085 e a 73 07f f a 73 079 0 b 73 073 1 b 73 06e 2 b 73 069 3 b 73 064 4 b 73 05f 5 b 73 05a 6 b 73 055 7 b 73 050 8 b 73 09b 9 b 73 096 a b 73 091 b b 73 08c c b 73 087 d b 73 082 e b 73 07d f b 73 078 0 c 73 073 1 c 73 06f 2 c 73 06b 3 c 73 067 4 c 73 063 5 c 73 05f 6 c 73 05b 7 c 73 057 8 c 73 093 9 c 73 08f a c 73 08b b c 73 087 c c 73 083 d c 73 07f e c 73 07b f c 73 077 0 d 73 073 1 d 73 070 2 d 73 06d 3 d 73 06a 4 d 73 067 5 d 73 064 6 d 73 061 7 d 73 05e 8 d 73 08b 9 d 73 088 a d 73 085 b d 73 082 c d 73 07f d d 73 07c e d 73 079 f d 73 076 0 e 73 073 1 e 73 071 2 e 73 06f 3 e 73 06d 4 e 73 06b 5 e 73 069 6 e 73 067 7 e 73 065 8 e 73 083 9 e 73 081 a e 73 07f b e 73 07d c e 73 07b d e 73 079 e e 73 077 f e 73 075 0 f 73 073 1 f 73 072 2 f 73 071 3 f 73 070 4 f 73 06f 5 f 73 06e 6 f 73 06d 7 f 73 06c 8 f 73 07b 9 f 73 07a a f 73 079 b f 73 078 c f 73 077 d f 73 076 e f 73 075 f f 73 074 0 0 74 074 1 0 74 074 2 0 74 074 3 0 74 074 4 0 74 074 5 0 74 074 6 0 74 074 7 0 74 074 8 0 74 074 9 0 74 074 a 0 74 074 b 0 74 074 c 0 74 074 d 0 74 074 e 0 74 074 f 0 74 074 0 1 74 074 1 1 74 075 2 1 74 076 3 1 74 077 4 1 74 078 5 1 74 079 6 1 74 07a 7 1 74 07b 8 1 74 06c 9 1 74 06d a 1 74 06e b 1 74 06f c 1 74 070 d 1 74 071 e 1 74 072 f 1 74 073 0 2 74 074 1 2 74 076 2 2 74 078 3 2 74 07a 4 2 74 07c 5 2 74 07e 6 2 74 080 7 2 74 082 8 2 74 064 9 2 74 066 a 2 74 068 b 2 74 06a c 2 74 06c d 2 74 06e e 2 74 070 f 2 74 072 0 3 74 074 1 3 74 077 2 3 74 07a 3 3 74 07d 4 3 74 080 5 3 74 083 6 3 74 086 7 3 74 089 8 3 74 05c 9 3 74 05f a 3 74 062 b 3 74 065 c 3 74 068 d 3 74 06b e 3 74 06e f 3 74 071 0 4 74 074 1 4 74 078 2 4 74 07c 3 4 74 080 4 4 74 084 5 4 74 088 6 4 74 08c 7 4 74 090 8 4 74 054 9 4 74 058 a 4 74 05c b 4 74 060 c 4 74 064 d 4 74 068 e 4 74 06c f 4 74 070 0 5 74 074 1 5 74 079 2 5 74 07e 3 5 74 083 4 5 74 088 5 5 74 08d 6 5 74 092 7 5 74 097 8 5 74 04c 9 5 74 051 a 5 74 056 b 5 74 05b c 5 74 060 d 5 74 065 e 5 74 06a f 5 74 06f 0 6 74 074 1 6 74 07a 2 6 74 080 3 6 74 086 4 6 74 08c 5 6 74 092 6 6 74 098 7 6 74 09e 8 6 74 044 9 6 74 04a a 6 74 050 b 6 74 056 c 6 74 05c d 6 74 062 e 6 74 068 f 6 74 06e 0 7 74 074 1 7 74 07b 2 7 74 082 3 7 74 089 4 7 74 090 5 7 74 097 6 7 74 09e 7 7 74 0a5 8 7 74 03c 9 7 74 043 a 7 74 04a b 7 74 051 c 7 74 058 d 7 74 05f e 7 74 066 f 7 74 06d 0 8 74 074 1 8 74 06c 2 8 74 064 3 8 74 05c 4 8 74 054 5 8 74 04c 6 8 74 044 7 8 74 03c 8 8 74 0b4 9 8 74 0ac a 8 74 0a4 b 8 74 09c c 8 74 094 d 8 74 08c e 8 74 084 f 8 74 07c 0 9 74 074 1 9 74 06d 2 9 74 066 3 9 74 05f 4 9 74 058 5 9 74 051 6 9 74 04a 7 9 74 043 8 9 74 0ac 9 9 74 0a5 a 9 74 09e b 9 74 097 c 9 74 090 d 9 74 089 e 9 74 082 f 9 74 07b 0 a 74 074 1 a 74 06e 2 a 74 068 3 a 74 062 4 a 74 05c 5 a 74 056 6 a 74 050 7 a 74 04a 8 a 74 0a4 9 a 74 09e a a 74 098 b a 74 092 c a 74 08c d a 74 086 e a 74 080 f a 74 07a 0 b 74 074 1 b 74 06f 2 b 74 06a 3 b 74 065 4 b 74 060 5 b 74 05b 6 b 74 056 7 b 74 051 8 b 74 09c 9 b 74 097 a b 74 092 b b 74 08d c b 74 088 d b 74 083 e b 74 07e f b 74 079 0 c 74 074 1 c 74 070 2 c 74 06c 3 c 74 068 4 c 74 064 5 c 74 060 6 c 74 05c 7 c 74 058 8 c 74 094 9 c 74 090 a c 74 08c b c 74 088 c c 74 084 d c 74 080 e c 74 07c f c 74 078 0 d 74 074 1 d 74 071 2 d 74 06e 3 d 74 06b 4 d 74 068 5 d 74 065 6 d 74 062 7 d 74 05f 8 d 74 08c 9 d 74 089 a d 74 086 b d 74 083 c d 74 080 d d 74 07d e d 74 07a f d 74 077 0 e 74 074 1 e 74 072 2 e 74 070 3 e 74 06e 4 e 74 06c 5 e 74 06a 6 e 74 068 7 e 74 066 8 e 74 084 9 e 74 082 a e 74 080 b e 74 07e c e 74 07c d e 74 07a e e 74 078 f e 74 076 0 f 74 074 1 f 74 073 2 f 74 072 3 f 74 071 4 f 74 070 5 f 74 06f 6 f 74 06e 7 f 74 06d 8 f 74 07c 9 f 74 07b a f 74 07a b f 74 079 c f 74 078 d f 74 077 e f 74 076 f f 74 075 0 0 75 075 1 0 75 075 2 0 75 075 3 0 75 075 4 0 75 075 5 0 75 075 6 0 75 075 7 0 75 075 8 0 75 075 9 0 75 075 a 0 75 075 b 0 75 075 c 0 75 075 d 0 75 075 e 0 75 075 f 0 75 075 0 1 75 075 1 1 75 076 2 1 75 077 3 1 75 078 4 1 75 079 5 1 75 07a 6 1 75 07b 7 1 75 07c 8 1 75 06d 9 1 75 06e a 1 75 06f b 1 75 070 c 1 75 071 d 1 75 072 e 1 75 073 f 1 75 074 0 2 75 075 1 2 75 077 2 2 75 079 3 2 75 07b 4 2 75 07d 5 2 75 07f 6 2 75 081 7 2 75 083 8 2 75 065 9 2 75 067 a 2 75 069 b 2 75 06b c 2 75 06d d 2 75 06f e 2 75 071 f 2 75 073 0 3 75 075 1 3 75 078 2 3 75 07b 3 3 75 07e 4 3 75 081 5 3 75 084 6 3 75 087 7 3 75 08a 8 3 75 05d 9 3 75 060 a 3 75 063 b 3 75 066 c 3 75 069 d 3 75 06c e 3 75 06f f 3 75 072 0 4 75 075 1 4 75 079 2 4 75 07d 3 4 75 081 4 4 75 085 5 4 75 089 6 4 75 08d 7 4 75 091 8 4 75 055 9 4 75 059 a 4 75 05d b 4 75 061 c 4 75 065 d 4 75 069 e 4 75 06d f 4 75 071 0 5 75 075 1 5 75 07a 2 5 75 07f 3 5 75 084 4 5 75 089 5 5 75 08e 6 5 75 093 7 5 75 098 8 5 75 04d 9 5 75 052 a 5 75 057 b 5 75 05c c 5 75 061 d 5 75 066 e 5 75 06b f 5 75 070 0 6 75 075 1 6 75 07b 2 6 75 081 3 6 75 087 4 6 75 08d 5 6 75 093 6 6 75 099 7 6 75 09f 8 6 75 045 9 6 75 04b a 6 75 051 b 6 75 057 c 6 75 05d d 6 75 063 e 6 75 069 f 6 75 06f 0 7 75 075 1 7 75 07c 2 7 75 083 3 7 75 08a 4 7 75 091 5 7 75 098 6 7 75 09f 7 7 75 0a6 8 7 75 03d 9 7 75 044 a 7 75 04b b 7 75 052 c 7 75 059 d 7 75 060 e 7 75 067 f 7 75 06e 0 8 75 075 1 8 75 06d 2 8 75 065 3 8 75 05d 4 8 75 055 5 8 75 04d 6 8 75 045 7 8 75 03d 8 8 75 0b5 9 8 75 0ad a 8 75 0a5 b 8 75 09d c 8 75 095 d 8 75 08d e 8 75 085 f 8 75 07d 0 9 75 075 1 9 75 06e 2 9 75 067 3 9 75 060 4 9 75 059 5 9 75 052 6 9 75 04b 7 9 75 044 8 9 75 0ad 9 9 75 0a6 a 9 75 09f b 9 75 098 c 9 75 091 d 9 75 08a e 9 75 083 f 9 75 07c 0 a 75 075 1 a 75 06f 2 a 75 069 3 a 75 063 4 a 75 05d 5 a 75 057 6 a 75 051 7 a 75 04b 8 a 75 0a5 9 a 75 09f a a 75 099 b a 75 093 c a 75 08d d a 75 087 e a 75 081 f a 75 07b 0 b 75 075 1 b 75 070 2 b 75 06b 3 b 75 066 4 b 75 061 5 b 75 05c 6 b 75 057 7 b 75 052 8 b 75 09d 9 b 75 098 a b 75 093 b b 75 08e c b 75 089 d b 75 084 e b 75 07f f b 75 07a 0 c 75 075 1 c 75 071 2 c 75 06d 3 c 75 069 4 c 75 065 5 c 75 061 6 c 75 05d 7 c 75 059 8 c 75 095 9 c 75 091 a c 75 08d b c 75 089 c c 75 085 d c 75 081 e c 75 07d f c 75 079 0 d 75 075 1 d 75 072 2 d 75 06f 3 d 75 06c 4 d 75 069 5 d 75 066 6 d 75 063 7 d 75 060 8 d 75 08d 9 d 75 08a a d 75 087 b d 75 084 c d 75 081 d d 75 07e e d 75 07b f d 75 078 0 e 75 075 1 e 75 073 2 e 75 071 3 e 75 06f 4 e 75 06d 5 e 75 06b 6 e 75 069 7 e 75 067 8 e 75 085 9 e 75 083 a e 75 081 b e 75 07f c e 75 07d d e 75 07b e e 75 079 f e 75 077 0 f 75 075 1 f 75 074 2 f 75 073 3 f 75 072 4 f 75 071 5 f 75 070 6 f 75 06f 7 f 75 06e 8 f 75 07d 9 f 75 07c a f 75 07b b f 75 07a c f 75 079 d f 75 078 e f 75 077 f f 75 076 0 0 76 076 1 0 76 076 2 0 76 076 3 0 76 076 4 0 76 076 5 0 76 076 6 0 76 076 7 0 76 076 8 0 76 076 9 0 76 076 a 0 76 076 b 0 76 076 c 0 76 076 d 0 76 076 e 0 76 076 f 0 76 076 0 1 76 076 1 1 76 077 2 1 76 078 3 1 76 079 4 1 76 07a 5 1 76 07b 6 1 76 07c 7 1 76 07d 8 1 76 06e 9 1 76 06f a 1 76 070 b 1 76 071 c 1 76 072 d 1 76 073 e 1 76 074 f 1 76 075 0 2 76 076 1 2 76 078 2 2 76 07a 3 2 76 07c 4 2 76 07e 5 2 76 080 6 2 76 082 7 2 76 084 8 2 76 066 9 2 76 068 a 2 76 06a b 2 76 06c c 2 76 06e d 2 76 070 e 2 76 072 f 2 76 074 0 3 76 076 1 3 76 079 2 3 76 07c 3 3 76 07f 4 3 76 082 5 3 76 085 6 3 76 088 7 3 76 08b 8 3 76 05e 9 3 76 061 a 3 76 064 b 3 76 067 c 3 76 06a d 3 76 06d e 3 76 070 f 3 76 073 0 4 76 076 1 4 76 07a 2 4 76 07e 3 4 76 082 4 4 76 086 5 4 76 08a 6 4 76 08e 7 4 76 092 8 4 76 056 9 4 76 05a a 4 76 05e b 4 76 062 c 4 76 066 d 4 76 06a e 4 76 06e f 4 76 072 0 5 76 076 1 5 76 07b 2 5 76 080 3 5 76 085 4 5 76 08a 5 5 76 08f 6 5 76 094 7 5 76 099 8 5 76 04e 9 5 76 053 a 5 76 058 b 5 76 05d c 5 76 062 d 5 76 067 e 5 76 06c f 5 76 071 0 6 76 076 1 6 76 07c 2 6 76 082 3 6 76 088 4 6 76 08e 5 6 76 094 6 6 76 09a 7 6 76 0a0 8 6 76 046 9 6 76 04c a 6 76 052 b 6 76 058 c 6 76 05e d 6 76 064 e 6 76 06a f 6 76 070 0 7 76 076 1 7 76 07d 2 7 76 084 3 7 76 08b 4 7 76 092 5 7 76 099 6 7 76 0a0 7 7 76 0a7 8 7 76 03e 9 7 76 045 a 7 76 04c b 7 76 053 c 7 76 05a d 7 76 061 e 7 76 068 f 7 76 06f 0 8 76 076 1 8 76 06e 2 8 76 066 3 8 76 05e 4 8 76 056 5 8 76 04e 6 8 76 046 7 8 76 03e 8 8 76 0b6 9 8 76 0ae a 8 76 0a6 b 8 76 09e c 8 76 096 d 8 76 08e e 8 76 086 f 8 76 07e 0 9 76 076 1 9 76 06f 2 9 76 068 3 9 76 061 4 9 76 05a 5 9 76 053 6 9 76 04c 7 9 76 045 8 9 76 0ae 9 9 76 0a7 a 9 76 0a0 b 9 76 099 c 9 76 092 d 9 76 08b e 9 76 084 f 9 76 07d 0 a 76 076 1 a 76 070 2 a 76 06a 3 a 76 064 4 a 76 05e 5 a 76 058 6 a 76 052 7 a 76 04c 8 a 76 0a6 9 a 76 0a0 a a 76 09a b a 76 094 c a 76 08e d a 76 088 e a 76 082 f a 76 07c 0 b 76 076 1 b 76 071 2 b 76 06c 3 b 76 067 4 b 76 062 5 b 76 05d 6 b 76 058 7 b 76 053 8 b 76 09e 9 b 76 099 a b 76 094 b b 76 08f c b 76 08a d b 76 085 e b 76 080 f b 76 07b 0 c 76 076 1 c 76 072 2 c 76 06e 3 c 76 06a 4 c 76 066 5 c 76 062 6 c 76 05e 7 c 76 05a 8 c 76 096 9 c 76 092 a c 76 08e b c 76 08a c c 76 086 d c 76 082 e c 76 07e f c 76 07a 0 d 76 076 1 d 76 073 2 d 76 070 3 d 76 06d 4 d 76 06a 5 d 76 067 6 d 76 064 7 d 76 061 8 d 76 08e 9 d 76 08b a d 76 088 b d 76 085 c d 76 082 d d 76 07f e d 76 07c f d 76 079 0 e 76 076 1 e 76 074 2 e 76 072 3 e 76 070 4 e 76 06e 5 e 76 06c 6 e 76 06a 7 e 76 068 8 e 76 086 9 e 76 084 a e 76 082 b e 76 080 c e 76 07e d e 76 07c e e 76 07a f e 76 078 0 f 76 076 1 f 76 075 2 f 76 074 3 f 76 073 4 f 76 072 5 f 76 071 6 f 76 070 7 f 76 06f 8 f 76 07e 9 f 76 07d a f 76 07c b f 76 07b c f 76 07a d f 76 079 e f 76 078 f f 76 077 0 0 77 077 1 0 77 077 2 0 77 077 3 0 77 077 4 0 77 077 5 0 77 077 6 0 77 077 7 0 77 077 8 0 77 077 9 0 77 077 a 0 77 077 b 0 77 077 c 0 77 077 d 0 77 077 e 0 77 077 f 0 77 077 0 1 77 077 1 1 77 078 2 1 77 079 3 1 77 07a 4 1 77 07b 5 1 77 07c 6 1 77 07d 7 1 77 07e 8 1 77 06f 9 1 77 070 a 1 77 071 b 1 77 072 c 1 77 073 d 1 77 074 e 1 77 075 f 1 77 076 0 2 77 077 1 2 77 079 2 2 77 07b 3 2 77 07d 4 2 77 07f 5 2 77 081 6 2 77 083 7 2 77 085 8 2 77 067 9 2 77 069 a 2 77 06b b 2 77 06d c 2 77 06f d 2 77 071 e 2 77 073 f 2 77 075 0 3 77 077 1 3 77 07a 2 3 77 07d 3 3 77 080 4 3 77 083 5 3 77 086 6 3 77 089 7 3 77 08c 8 3 77 05f 9 3 77 062 a 3 77 065 b 3 77 068 c 3 77 06b d 3 77 06e e 3 77 071 f 3 77 074 0 4 77 077 1 4 77 07b 2 4 77 07f 3 4 77 083 4 4 77 087 5 4 77 08b 6 4 77 08f 7 4 77 093 8 4 77 057 9 4 77 05b a 4 77 05f b 4 77 063 c 4 77 067 d 4 77 06b e 4 77 06f f 4 77 073 0 5 77 077 1 5 77 07c 2 5 77 081 3 5 77 086 4 5 77 08b 5 5 77 090 6 5 77 095 7 5 77 09a 8 5 77 04f 9 5 77 054 a 5 77 059 b 5 77 05e c 5 77 063 d 5 77 068 e 5 77 06d f 5 77 072 0 6 77 077 1 6 77 07d 2 6 77 083 3 6 77 089 4 6 77 08f 5 6 77 095 6 6 77 09b 7 6 77 0a1 8 6 77 047 9 6 77 04d a 6 77 053 b 6 77 059 c 6 77 05f d 6 77 065 e 6 77 06b f 6 77 071 0 7 77 077 1 7 77 07e 2 7 77 085 3 7 77 08c 4 7 77 093 5 7 77 09a 6 7 77 0a1 7 7 77 0a8 8 7 77 03f 9 7 77 046 a 7 77 04d b 7 77 054 c 7 77 05b d 7 77 062 e 7 77 069 f 7 77 070 0 8 77 077 1 8 77 06f 2 8 77 067 3 8 77 05f 4 8 77 057 5 8 77 04f 6 8 77 047 7 8 77 03f 8 8 77 0b7 9 8 77 0af a 8 77 0a7 b 8 77 09f c 8 77 097 d 8 77 08f e 8 77 087 f 8 77 07f 0 9 77 077 1 9 77 070 2 9 77 069 3 9 77 062 4 9 77 05b 5 9 77 054 6 9 77 04d 7 9 77 046 8 9 77 0af 9 9 77 0a8 a 9 77 0a1 b 9 77 09a c 9 77 093 d 9 77 08c e 9 77 085 f 9 77 07e 0 a 77 077 1 a 77 071 2 a 77 06b 3 a 77 065 4 a 77 05f 5 a 77 059 6 a 77 053 7 a 77 04d 8 a 77 0a7 9 a 77 0a1 a a 77 09b b a 77 095 c a 77 08f d a 77 089 e a 77 083 f a 77 07d 0 b 77 077 1 b 77 072 2 b 77 06d 3 b 77 068 4 b 77 063 5 b 77 05e 6 b 77 059 7 b 77 054 8 b 77 09f 9 b 77 09a a b 77 095 b b 77 090 c b 77 08b d b 77 086 e b 77 081 f b 77 07c 0 c 77 077 1 c 77 073 2 c 77 06f 3 c 77 06b 4 c 77 067 5 c 77 063 6 c 77 05f 7 c 77 05b 8 c 77 097 9 c 77 093 a c 77 08f b c 77 08b c c 77 087 d c 77 083 e c 77 07f f c 77 07b 0 d 77 077 1 d 77 074 2 d 77 071 3 d 77 06e 4 d 77 06b 5 d 77 068 6 d 77 065 7 d 77 062 8 d 77 08f 9 d 77 08c a d 77 089 b d 77 086 c d 77 083 d d 77 080 e d 77 07d f d 77 07a 0 e 77 077 1 e 77 075 2 e 77 073 3 e 77 071 4 e 77 06f 5 e 77 06d 6 e 77 06b 7 e 77 069 8 e 77 087 9 e 77 085 a e 77 083 b e 77 081 c e 77 07f d e 77 07d e e 77 07b f e 77 079 0 f 77 077 1 f 77 076 2 f 77 075 3 f 77 074 4 f 77 073 5 f 77 072 6 f 77 071 7 f 77 070 8 f 77 07f 9 f 77 07e a f 77 07d b f 77 07c c f 77 07b d f 77 07a e f 77 079 f f 77 078 0 0 78 078 1 0 78 078 2 0 78 078 3 0 78 078 4 0 78 078 5 0 78 078 6 0 78 078 7 0 78 078 8 0 78 078 9 0 78 078 a 0 78 078 b 0 78 078 c 0 78 078 d 0 78 078 e 0 78 078 f 0 78 078 0 1 78 078 1 1 78 079 2 1 78 07a 3 1 78 07b 4 1 78 07c 5 1 78 07d 6 1 78 07e 7 1 78 07f 8 1 78 070 9 1 78 071 a 1 78 072 b 1 78 073 c 1 78 074 d 1 78 075 e 1 78 076 f 1 78 077 0 2 78 078 1 2 78 07a 2 2 78 07c 3 2 78 07e 4 2 78 080 5 2 78 082 6 2 78 084 7 2 78 086 8 2 78 068 9 2 78 06a a 2 78 06c b 2 78 06e c 2 78 070 d 2 78 072 e 2 78 074 f 2 78 076 0 3 78 078 1 3 78 07b 2 3 78 07e 3 3 78 081 4 3 78 084 5 3 78 087 6 3 78 08a 7 3 78 08d 8 3 78 060 9 3 78 063 a 3 78 066 b 3 78 069 c 3 78 06c d 3 78 06f e 3 78 072 f 3 78 075 0 4 78 078 1 4 78 07c 2 4 78 080 3 4 78 084 4 4 78 088 5 4 78 08c 6 4 78 090 7 4 78 094 8 4 78 058 9 4 78 05c a 4 78 060 b 4 78 064 c 4 78 068 d 4 78 06c e 4 78 070 f 4 78 074 0 5 78 078 1 5 78 07d 2 5 78 082 3 5 78 087 4 5 78 08c 5 5 78 091 6 5 78 096 7 5 78 09b 8 5 78 050 9 5 78 055 a 5 78 05a b 5 78 05f c 5 78 064 d 5 78 069 e 5 78 06e f 5 78 073 0 6 78 078 1 6 78 07e 2 6 78 084 3 6 78 08a 4 6 78 090 5 6 78 096 6 6 78 09c 7 6 78 0a2 8 6 78 048 9 6 78 04e a 6 78 054 b 6 78 05a c 6 78 060 d 6 78 066 e 6 78 06c f 6 78 072 0 7 78 078 1 7 78 07f 2 7 78 086 3 7 78 08d 4 7 78 094 5 7 78 09b 6 7 78 0a2 7 7 78 0a9 8 7 78 040 9 7 78 047 a 7 78 04e b 7 78 055 c 7 78 05c d 7 78 063 e 7 78 06a f 7 78 071 0 8 78 078 1 8 78 070 2 8 78 068 3 8 78 060 4 8 78 058 5 8 78 050 6 8 78 048 7 8 78 040 8 8 78 0b8 9 8 78 0b0 a 8 78 0a8 b 8 78 0a0 c 8 78 098 d 8 78 090 e 8 78 088 f 8 78 080 0 9 78 078 1 9 78 071 2 9 78 06a 3 9 78 063 4 9 78 05c 5 9 78 055 6 9 78 04e 7 9 78 047 8 9 78 0b0 9 9 78 0a9 a 9 78 0a2 b 9 78 09b c 9 78 094 d 9 78 08d e 9 78 086 f 9 78 07f 0 a 78 078 1 a 78 072 2 a 78 06c 3 a 78 066 4 a 78 060 5 a 78 05a 6 a 78 054 7 a 78 04e 8 a 78 0a8 9 a 78 0a2 a a 78 09c b a 78 096 c a 78 090 d a 78 08a e a 78 084 f a 78 07e 0 b 78 078 1 b 78 073 2 b 78 06e 3 b 78 069 4 b 78 064 5 b 78 05f 6 b 78 05a 7 b 78 055 8 b 78 0a0 9 b 78 09b a b 78 096 b b 78 091 c b 78 08c d b 78 087 e b 78 082 f b 78 07d 0 c 78 078 1 c 78 074 2 c 78 070 3 c 78 06c 4 c 78 068 5 c 78 064 6 c 78 060 7 c 78 05c 8 c 78 098 9 c 78 094 a c 78 090 b c 78 08c c c 78 088 d c 78 084 e c 78 080 f c 78 07c 0 d 78 078 1 d 78 075 2 d 78 072 3 d 78 06f 4 d 78 06c 5 d 78 069 6 d 78 066 7 d 78 063 8 d 78 090 9 d 78 08d a d 78 08a b d 78 087 c d 78 084 d d 78 081 e d 78 07e f d 78 07b 0 e 78 078 1 e 78 076 2 e 78 074 3 e 78 072 4 e 78 070 5 e 78 06e 6 e 78 06c 7 e 78 06a 8 e 78 088 9 e 78 086 a e 78 084 b e 78 082 c e 78 080 d e 78 07e e e 78 07c f e 78 07a 0 f 78 078 1 f 78 077 2 f 78 076 3 f 78 075 4 f 78 074 5 f 78 073 6 f 78 072 7 f 78 071 8 f 78 080 9 f 78 07f a f 78 07e b f 78 07d c f 78 07c d f 78 07b e f 78 07a f f 78 079 0 0 79 079 1 0 79 079 2 0 79 079 3 0 79 079 4 0 79 079 5 0 79 079 6 0 79 079 7 0 79 079 8 0 79 079 9 0 79 079 a 0 79 079 b 0 79 079 c 0 79 079 d 0 79 079 e 0 79 079 f 0 79 079 0 1 79 079 1 1 79 07a 2 1 79 07b 3 1 79 07c 4 1 79 07d 5 1 79 07e 6 1 79 07f 7 1 79 080 8 1 79 071 9 1 79 072 a 1 79 073 b 1 79 074 c 1 79 075 d 1 79 076 e 1 79 077 f 1 79 078 0 2 79 079 1 2 79 07b 2 2 79 07d 3 2 79 07f 4 2 79 081 5 2 79 083 6 2 79 085 7 2 79 087 8 2 79 069 9 2 79 06b a 2 79 06d b 2 79 06f c 2 79 071 d 2 79 073 e 2 79 075 f 2 79 077 0 3 79 079 1 3 79 07c 2 3 79 07f 3 3 79 082 4 3 79 085 5 3 79 088 6 3 79 08b 7 3 79 08e 8 3 79 061 9 3 79 064 a 3 79 067 b 3 79 06a c 3 79 06d d 3 79 070 e 3 79 073 f 3 79 076 0 4 79 079 1 4 79 07d 2 4 79 081 3 4 79 085 4 4 79 089 5 4 79 08d 6 4 79 091 7 4 79 095 8 4 79 059 9 4 79 05d a 4 79 061 b 4 79 065 c 4 79 069 d 4 79 06d e 4 79 071 f 4 79 075 0 5 79 079 1 5 79 07e 2 5 79 083 3 5 79 088 4 5 79 08d 5 5 79 092 6 5 79 097 7 5 79 09c 8 5 79 051 9 5 79 056 a 5 79 05b b 5 79 060 c 5 79 065 d 5 79 06a e 5 79 06f f 5 79 074 0 6 79 079 1 6 79 07f 2 6 79 085 3 6 79 08b 4 6 79 091 5 6 79 097 6 6 79 09d 7 6 79 0a3 8 6 79 049 9 6 79 04f a 6 79 055 b 6 79 05b c 6 79 061 d 6 79 067 e 6 79 06d f 6 79 073 0 7 79 079 1 7 79 080 2 7 79 087 3 7 79 08e 4 7 79 095 5 7 79 09c 6 7 79 0a3 7 7 79 0aa 8 7 79 041 9 7 79 048 a 7 79 04f b 7 79 056 c 7 79 05d d 7 79 064 e 7 79 06b f 7 79 072 0 8 79 079 1 8 79 071 2 8 79 069 3 8 79 061 4 8 79 059 5 8 79 051 6 8 79 049 7 8 79 041 8 8 79 0b9 9 8 79 0b1 a 8 79 0a9 b 8 79 0a1 c 8 79 099 d 8 79 091 e 8 79 089 f 8 79 081 0 9 79 079 1 9 79 072 2 9 79 06b 3 9 79 064 4 9 79 05d 5 9 79 056 6 9 79 04f 7 9 79 048 8 9 79 0b1 9 9 79 0aa a 9 79 0a3 b 9 79 09c c 9 79 095 d 9 79 08e e 9 79 087 f 9 79 080 0 a 79 079 1 a 79 073 2 a 79 06d 3 a 79 067 4 a 79 061 5 a 79 05b 6 a 79 055 7 a 79 04f 8 a 79 0a9 9 a 79 0a3 a a 79 09d b a 79 097 c a 79 091 d a 79 08b e a 79 085 f a 79 07f 0 b 79 079 1 b 79 074 2 b 79 06f 3 b 79 06a 4 b 79 065 5 b 79 060 6 b 79 05b 7 b 79 056 8 b 79 0a1 9 b 79 09c a b 79 097 b b 79 092 c b 79 08d d b 79 088 e b 79 083 f b 79 07e 0 c 79 079 1 c 79 075 2 c 79 071 3 c 79 06d 4 c 79 069 5 c 79 065 6 c 79 061 7 c 79 05d 8 c 79 099 9 c 79 095 a c 79 091 b c 79 08d c c 79 089 d c 79 085 e c 79 081 f c 79 07d 0 d 79 079 1 d 79 076 2 d 79 073 3 d 79 070 4 d 79 06d 5 d 79 06a 6 d 79 067 7 d 79 064 8 d 79 091 9 d 79 08e a d 79 08b b d 79 088 c d 79 085 d d 79 082 e d 79 07f f d 79 07c 0 e 79 079 1 e 79 077 2 e 79 075 3 e 79 073 4 e 79 071 5 e 79 06f 6 e 79 06d 7 e 79 06b 8 e 79 089 9 e 79 087 a e 79 085 b e 79 083 c e 79 081 d e 79 07f e e 79 07d f e 79 07b 0 f 79 079 1 f 79 078 2 f 79 077 3 f 79 076 4 f 79 075 5 f 79 074 6 f 79 073 7 f 79 072 8 f 79 081 9 f 79 080 a f 79 07f b f 79 07e c f 79 07d d f 79 07c e f 79 07b f f 79 07a 0 0 7a 07a 1 0 7a 07a 2 0 7a 07a 3 0 7a 07a 4 0 7a 07a 5 0 7a 07a 6 0 7a 07a 7 0 7a 07a 8 0 7a 07a 9 0 7a 07a a 0 7a 07a b 0 7a 07a c 0 7a 07a d 0 7a 07a e 0 7a 07a f 0 7a 07a 0 1 7a 07a 1 1 7a 07b 2 1 7a 07c 3 1 7a 07d 4 1 7a 07e 5 1 7a 07f 6 1 7a 080 7 1 7a 081 8 1 7a 072 9 1 7a 073 a 1 7a 074 b 1 7a 075 c 1 7a 076 d 1 7a 077 e 1 7a 078 f 1 7a 079 0 2 7a 07a 1 2 7a 07c 2 2 7a 07e 3 2 7a 080 4 2 7a 082 5 2 7a 084 6 2 7a 086 7 2 7a 088 8 2 7a 06a 9 2 7a 06c a 2 7a 06e b 2 7a 070 c 2 7a 072 d 2 7a 074 e 2 7a 076 f 2 7a 078 0 3 7a 07a 1 3 7a 07d 2 3 7a 080 3 3 7a 083 4 3 7a 086 5 3 7a 089 6 3 7a 08c 7 3 7a 08f 8 3 7a 062 9 3 7a 065 a 3 7a 068 b 3 7a 06b c 3 7a 06e d 3 7a 071 e 3 7a 074 f 3 7a 077 0 4 7a 07a 1 4 7a 07e 2 4 7a 082 3 4 7a 086 4 4 7a 08a 5 4 7a 08e 6 4 7a 092 7 4 7a 096 8 4 7a 05a 9 4 7a 05e a 4 7a 062 b 4 7a 066 c 4 7a 06a d 4 7a 06e e 4 7a 072 f 4 7a 076 0 5 7a 07a 1 5 7a 07f 2 5 7a 084 3 5 7a 089 4 5 7a 08e 5 5 7a 093 6 5 7a 098 7 5 7a 09d 8 5 7a 052 9 5 7a 057 a 5 7a 05c b 5 7a 061 c 5 7a 066 d 5 7a 06b e 5 7a 070 f 5 7a 075 0 6 7a 07a 1 6 7a 080 2 6 7a 086 3 6 7a 08c 4 6 7a 092 5 6 7a 098 6 6 7a 09e 7 6 7a 0a4 8 6 7a 04a 9 6 7a 050 a 6 7a 056 b 6 7a 05c c 6 7a 062 d 6 7a 068 e 6 7a 06e f 6 7a 074 0 7 7a 07a 1 7 7a 081 2 7 7a 088 3 7 7a 08f 4 7 7a 096 5 7 7a 09d 6 7 7a 0a4 7 7 7a 0ab 8 7 7a 042 9 7 7a 049 a 7 7a 050 b 7 7a 057 c 7 7a 05e d 7 7a 065 e 7 7a 06c f 7 7a 073 0 8 7a 07a 1 8 7a 072 2 8 7a 06a 3 8 7a 062 4 8 7a 05a 5 8 7a 052 6 8 7a 04a 7 8 7a 042 8 8 7a 0ba 9 8 7a 0b2 a 8 7a 0aa b 8 7a 0a2 c 8 7a 09a d 8 7a 092 e 8 7a 08a f 8 7a 082 0 9 7a 07a 1 9 7a 073 2 9 7a 06c 3 9 7a 065 4 9 7a 05e 5 9 7a 057 6 9 7a 050 7 9 7a 049 8 9 7a 0b2 9 9 7a 0ab a 9 7a 0a4 b 9 7a 09d c 9 7a 096 d 9 7a 08f e 9 7a 088 f 9 7a 081 0 a 7a 07a 1 a 7a 074 2 a 7a 06e 3 a 7a 068 4 a 7a 062 5 a 7a 05c 6 a 7a 056 7 a 7a 050 8 a 7a 0aa 9 a 7a 0a4 a a 7a 09e b a 7a 098 c a 7a 092 d a 7a 08c e a 7a 086 f a 7a 080 0 b 7a 07a 1 b 7a 075 2 b 7a 070 3 b 7a 06b 4 b 7a 066 5 b 7a 061 6 b 7a 05c 7 b 7a 057 8 b 7a 0a2 9 b 7a 09d a b 7a 098 b b 7a 093 c b 7a 08e d b 7a 089 e b 7a 084 f b 7a 07f 0 c 7a 07a 1 c 7a 076 2 c 7a 072 3 c 7a 06e 4 c 7a 06a 5 c 7a 066 6 c 7a 062 7 c 7a 05e 8 c 7a 09a 9 c 7a 096 a c 7a 092 b c 7a 08e c c 7a 08a d c 7a 086 e c 7a 082 f c 7a 07e 0 d 7a 07a 1 d 7a 077 2 d 7a 074 3 d 7a 071 4 d 7a 06e 5 d 7a 06b 6 d 7a 068 7 d 7a 065 8 d 7a 092 9 d 7a 08f a d 7a 08c b d 7a 089 c d 7a 086 d d 7a 083 e d 7a 080 f d 7a 07d 0 e 7a 07a 1 e 7a 078 2 e 7a 076 3 e 7a 074 4 e 7a 072 5 e 7a 070 6 e 7a 06e 7 e 7a 06c 8 e 7a 08a 9 e 7a 088 a e 7a 086 b e 7a 084 c e 7a 082 d e 7a 080 e e 7a 07e f e 7a 07c 0 f 7a 07a 1 f 7a 079 2 f 7a 078 3 f 7a 077 4 f 7a 076 5 f 7a 075 6 f 7a 074 7 f 7a 073 8 f 7a 082 9 f 7a 081 a f 7a 080 b f 7a 07f c f 7a 07e d f 7a 07d e f 7a 07c f f 7a 07b 0 0 7b 07b 1 0 7b 07b 2 0 7b 07b 3 0 7b 07b 4 0 7b 07b 5 0 7b 07b 6 0 7b 07b 7 0 7b 07b 8 0 7b 07b 9 0 7b 07b a 0 7b 07b b 0 7b 07b c 0 7b 07b d 0 7b 07b e 0 7b 07b f 0 7b 07b 0 1 7b 07b 1 1 7b 07c 2 1 7b 07d 3 1 7b 07e 4 1 7b 07f 5 1 7b 080 6 1 7b 081 7 1 7b 082 8 1 7b 073 9 1 7b 074 a 1 7b 075 b 1 7b 076 c 1 7b 077 d 1 7b 078 e 1 7b 079 f 1 7b 07a 0 2 7b 07b 1 2 7b 07d 2 2 7b 07f 3 2 7b 081 4 2 7b 083 5 2 7b 085 6 2 7b 087 7 2 7b 089 8 2 7b 06b 9 2 7b 06d a 2 7b 06f b 2 7b 071 c 2 7b 073 d 2 7b 075 e 2 7b 077 f 2 7b 079 0 3 7b 07b 1 3 7b 07e 2 3 7b 081 3 3 7b 084 4 3 7b 087 5 3 7b 08a 6 3 7b 08d 7 3 7b 090 8 3 7b 063 9 3 7b 066 a 3 7b 069 b 3 7b 06c c 3 7b 06f d 3 7b 072 e 3 7b 075 f 3 7b 078 0 4 7b 07b 1 4 7b 07f 2 4 7b 083 3 4 7b 087 4 4 7b 08b 5 4 7b 08f 6 4 7b 093 7 4 7b 097 8 4 7b 05b 9 4 7b 05f a 4 7b 063 b 4 7b 067 c 4 7b 06b d 4 7b 06f e 4 7b 073 f 4 7b 077 0 5 7b 07b 1 5 7b 080 2 5 7b 085 3 5 7b 08a 4 5 7b 08f 5 5 7b 094 6 5 7b 099 7 5 7b 09e 8 5 7b 053 9 5 7b 058 a 5 7b 05d b 5 7b 062 c 5 7b 067 d 5 7b 06c e 5 7b 071 f 5 7b 076 0 6 7b 07b 1 6 7b 081 2 6 7b 087 3 6 7b 08d 4 6 7b 093 5 6 7b 099 6 6 7b 09f 7 6 7b 0a5 8 6 7b 04b 9 6 7b 051 a 6 7b 057 b 6 7b 05d c 6 7b 063 d 6 7b 069 e 6 7b 06f f 6 7b 075 0 7 7b 07b 1 7 7b 082 2 7 7b 089 3 7 7b 090 4 7 7b 097 5 7 7b 09e 6 7 7b 0a5 7 7 7b 0ac 8 7 7b 043 9 7 7b 04a a 7 7b 051 b 7 7b 058 c 7 7b 05f d 7 7b 066 e 7 7b 06d f 7 7b 074 0 8 7b 07b 1 8 7b 073 2 8 7b 06b 3 8 7b 063 4 8 7b 05b 5 8 7b 053 6 8 7b 04b 7 8 7b 043 8 8 7b 0bb 9 8 7b 0b3 a 8 7b 0ab b 8 7b 0a3 c 8 7b 09b d 8 7b 093 e 8 7b 08b f 8 7b 083 0 9 7b 07b 1 9 7b 074 2 9 7b 06d 3 9 7b 066 4 9 7b 05f 5 9 7b 058 6 9 7b 051 7 9 7b 04a 8 9 7b 0b3 9 9 7b 0ac a 9 7b 0a5 b 9 7b 09e c 9 7b 097 d 9 7b 090 e 9 7b 089 f 9 7b 082 0 a 7b 07b 1 a 7b 075 2 a 7b 06f 3 a 7b 069 4 a 7b 063 5 a 7b 05d 6 a 7b 057 7 a 7b 051 8 a 7b 0ab 9 a 7b 0a5 a a 7b 09f b a 7b 099 c a 7b 093 d a 7b 08d e a 7b 087 f a 7b 081 0 b 7b 07b 1 b 7b 076 2 b 7b 071 3 b 7b 06c 4 b 7b 067 5 b 7b 062 6 b 7b 05d 7 b 7b 058 8 b 7b 0a3 9 b 7b 09e a b 7b 099 b b 7b 094 c b 7b 08f d b 7b 08a e b 7b 085 f b 7b 080 0 c 7b 07b 1 c 7b 077 2 c 7b 073 3 c 7b 06f 4 c 7b 06b 5 c 7b 067 6 c 7b 063 7 c 7b 05f 8 c 7b 09b 9 c 7b 097 a c 7b 093 b c 7b 08f c c 7b 08b d c 7b 087 e c 7b 083 f c 7b 07f 0 d 7b 07b 1 d 7b 078 2 d 7b 075 3 d 7b 072 4 d 7b 06f 5 d 7b 06c 6 d 7b 069 7 d 7b 066 8 d 7b 093 9 d 7b 090 a d 7b 08d b d 7b 08a c d 7b 087 d d 7b 084 e d 7b 081 f d 7b 07e 0 e 7b 07b 1 e 7b 079 2 e 7b 077 3 e 7b 075 4 e 7b 073 5 e 7b 071 6 e 7b 06f 7 e 7b 06d 8 e 7b 08b 9 e 7b 089 a e 7b 087 b e 7b 085 c e 7b 083 d e 7b 081 e e 7b 07f f e 7b 07d 0 f 7b 07b 1 f 7b 07a 2 f 7b 079 3 f 7b 078 4 f 7b 077 5 f 7b 076 6 f 7b 075 7 f 7b 074 8 f 7b 083 9 f 7b 082 a f 7b 081 b f 7b 080 c f 7b 07f d f 7b 07e e f 7b 07d f f 7b 07c 0 0 7c 07c 1 0 7c 07c 2 0 7c 07c 3 0 7c 07c 4 0 7c 07c 5 0 7c 07c 6 0 7c 07c 7 0 7c 07c 8 0 7c 07c 9 0 7c 07c a 0 7c 07c b 0 7c 07c c 0 7c 07c d 0 7c 07c e 0 7c 07c f 0 7c 07c 0 1 7c 07c 1 1 7c 07d 2 1 7c 07e 3 1 7c 07f 4 1 7c 080 5 1 7c 081 6 1 7c 082 7 1 7c 083 8 1 7c 074 9 1 7c 075 a 1 7c 076 b 1 7c 077 c 1 7c 078 d 1 7c 079 e 1 7c 07a f 1 7c 07b 0 2 7c 07c 1 2 7c 07e 2 2 7c 080 3 2 7c 082 4 2 7c 084 5 2 7c 086 6 2 7c 088 7 2 7c 08a 8 2 7c 06c 9 2 7c 06e a 2 7c 070 b 2 7c 072 c 2 7c 074 d 2 7c 076 e 2 7c 078 f 2 7c 07a 0 3 7c 07c 1 3 7c 07f 2 3 7c 082 3 3 7c 085 4 3 7c 088 5 3 7c 08b 6 3 7c 08e 7 3 7c 091 8 3 7c 064 9 3 7c 067 a 3 7c 06a b 3 7c 06d c 3 7c 070 d 3 7c 073 e 3 7c 076 f 3 7c 079 0 4 7c 07c 1 4 7c 080 2 4 7c 084 3 4 7c 088 4 4 7c 08c 5 4 7c 090 6 4 7c 094 7 4 7c 098 8 4 7c 05c 9 4 7c 060 a 4 7c 064 b 4 7c 068 c 4 7c 06c d 4 7c 070 e 4 7c 074 f 4 7c 078 0 5 7c 07c 1 5 7c 081 2 5 7c 086 3 5 7c 08b 4 5 7c 090 5 5 7c 095 6 5 7c 09a 7 5 7c 09f 8 5 7c 054 9 5 7c 059 a 5 7c 05e b 5 7c 063 c 5 7c 068 d 5 7c 06d e 5 7c 072 f 5 7c 077 0 6 7c 07c 1 6 7c 082 2 6 7c 088 3 6 7c 08e 4 6 7c 094 5 6 7c 09a 6 6 7c 0a0 7 6 7c 0a6 8 6 7c 04c 9 6 7c 052 a 6 7c 058 b 6 7c 05e c 6 7c 064 d 6 7c 06a e 6 7c 070 f 6 7c 076 0 7 7c 07c 1 7 7c 083 2 7 7c 08a 3 7 7c 091 4 7 7c 098 5 7 7c 09f 6 7 7c 0a6 7 7 7c 0ad 8 7 7c 044 9 7 7c 04b a 7 7c 052 b 7 7c 059 c 7 7c 060 d 7 7c 067 e 7 7c 06e f 7 7c 075 0 8 7c 07c 1 8 7c 074 2 8 7c 06c 3 8 7c 064 4 8 7c 05c 5 8 7c 054 6 8 7c 04c 7 8 7c 044 8 8 7c 0bc 9 8 7c 0b4 a 8 7c 0ac b 8 7c 0a4 c 8 7c 09c d 8 7c 094 e 8 7c 08c f 8 7c 084 0 9 7c 07c 1 9 7c 075 2 9 7c 06e 3 9 7c 067 4 9 7c 060 5 9 7c 059 6 9 7c 052 7 9 7c 04b 8 9 7c 0b4 9 9 7c 0ad a 9 7c 0a6 b 9 7c 09f c 9 7c 098 d 9 7c 091 e 9 7c 08a f 9 7c 083 0 a 7c 07c 1 a 7c 076 2 a 7c 070 3 a 7c 06a 4 a 7c 064 5 a 7c 05e 6 a 7c 058 7 a 7c 052 8 a 7c 0ac 9 a 7c 0a6 a a 7c 0a0 b a 7c 09a c a 7c 094 d a 7c 08e e a 7c 088 f a 7c 082 0 b 7c 07c 1 b 7c 077 2 b 7c 072 3 b 7c 06d 4 b 7c 068 5 b 7c 063 6 b 7c 05e 7 b 7c 059 8 b 7c 0a4 9 b 7c 09f a b 7c 09a b b 7c 095 c b 7c 090 d b 7c 08b e b 7c 086 f b 7c 081 0 c 7c 07c 1 c 7c 078 2 c 7c 074 3 c 7c 070 4 c 7c 06c 5 c 7c 068 6 c 7c 064 7 c 7c 060 8 c 7c 09c 9 c 7c 098 a c 7c 094 b c 7c 090 c c 7c 08c d c 7c 088 e c 7c 084 f c 7c 080 0 d 7c 07c 1 d 7c 079 2 d 7c 076 3 d 7c 073 4 d 7c 070 5 d 7c 06d 6 d 7c 06a 7 d 7c 067 8 d 7c 094 9 d 7c 091 a d 7c 08e b d 7c 08b c d 7c 088 d d 7c 085 e d 7c 082 f d 7c 07f 0 e 7c 07c 1 e 7c 07a 2 e 7c 078 3 e 7c 076 4 e 7c 074 5 e 7c 072 6 e 7c 070 7 e 7c 06e 8 e 7c 08c 9 e 7c 08a a e 7c 088 b e 7c 086 c e 7c 084 d e 7c 082 e e 7c 080 f e 7c 07e 0 f 7c 07c 1 f 7c 07b 2 f 7c 07a 3 f 7c 079 4 f 7c 078 5 f 7c 077 6 f 7c 076 7 f 7c 075 8 f 7c 084 9 f 7c 083 a f 7c 082 b f 7c 081 c f 7c 080 d f 7c 07f e f 7c 07e f f 7c 07d 0 0 7d 07d 1 0 7d 07d 2 0 7d 07d 3 0 7d 07d 4 0 7d 07d 5 0 7d 07d 6 0 7d 07d 7 0 7d 07d 8 0 7d 07d 9 0 7d 07d a 0 7d 07d b 0 7d 07d c 0 7d 07d d 0 7d 07d e 0 7d 07d f 0 7d 07d 0 1 7d 07d 1 1 7d 07e 2 1 7d 07f 3 1 7d 080 4 1 7d 081 5 1 7d 082 6 1 7d 083 7 1 7d 084 8 1 7d 075 9 1 7d 076 a 1 7d 077 b 1 7d 078 c 1 7d 079 d 1 7d 07a e 1 7d 07b f 1 7d 07c 0 2 7d 07d 1 2 7d 07f 2 2 7d 081 3 2 7d 083 4 2 7d 085 5 2 7d 087 6 2 7d 089 7 2 7d 08b 8 2 7d 06d 9 2 7d 06f a 2 7d 071 b 2 7d 073 c 2 7d 075 d 2 7d 077 e 2 7d 079 f 2 7d 07b 0 3 7d 07d 1 3 7d 080 2 3 7d 083 3 3 7d 086 4 3 7d 089 5 3 7d 08c 6 3 7d 08f 7 3 7d 092 8 3 7d 065 9 3 7d 068 a 3 7d 06b b 3 7d 06e c 3 7d 071 d 3 7d 074 e 3 7d 077 f 3 7d 07a 0 4 7d 07d 1 4 7d 081 2 4 7d 085 3 4 7d 089 4 4 7d 08d 5 4 7d 091 6 4 7d 095 7 4 7d 099 8 4 7d 05d 9 4 7d 061 a 4 7d 065 b 4 7d 069 c 4 7d 06d d 4 7d 071 e 4 7d 075 f 4 7d 079 0 5 7d 07d 1 5 7d 082 2 5 7d 087 3 5 7d 08c 4 5 7d 091 5 5 7d 096 6 5 7d 09b 7 5 7d 0a0 8 5 7d 055 9 5 7d 05a a 5 7d 05f b 5 7d 064 c 5 7d 069 d 5 7d 06e e 5 7d 073 f 5 7d 078 0 6 7d 07d 1 6 7d 083 2 6 7d 089 3 6 7d 08f 4 6 7d 095 5 6 7d 09b 6 6 7d 0a1 7 6 7d 0a7 8 6 7d 04d 9 6 7d 053 a 6 7d 059 b 6 7d 05f c 6 7d 065 d 6 7d 06b e 6 7d 071 f 6 7d 077 0 7 7d 07d 1 7 7d 084 2 7 7d 08b 3 7 7d 092 4 7 7d 099 5 7 7d 0a0 6 7 7d 0a7 7 7 7d 0ae 8 7 7d 045 9 7 7d 04c a 7 7d 053 b 7 7d 05a c 7 7d 061 d 7 7d 068 e 7 7d 06f f 7 7d 076 0 8 7d 07d 1 8 7d 075 2 8 7d 06d 3 8 7d 065 4 8 7d 05d 5 8 7d 055 6 8 7d 04d 7 8 7d 045 8 8 7d 0bd 9 8 7d 0b5 a 8 7d 0ad b 8 7d 0a5 c 8 7d 09d d 8 7d 095 e 8 7d 08d f 8 7d 085 0 9 7d 07d 1 9 7d 076 2 9 7d 06f 3 9 7d 068 4 9 7d 061 5 9 7d 05a 6 9 7d 053 7 9 7d 04c 8 9 7d 0b5 9 9 7d 0ae a 9 7d 0a7 b 9 7d 0a0 c 9 7d 099 d 9 7d 092 e 9 7d 08b f 9 7d 084 0 a 7d 07d 1 a 7d 077 2 a 7d 071 3 a 7d 06b 4 a 7d 065 5 a 7d 05f 6 a 7d 059 7 a 7d 053 8 a 7d 0ad 9 a 7d 0a7 a a 7d 0a1 b a 7d 09b c a 7d 095 d a 7d 08f e a 7d 089 f a 7d 083 0 b 7d 07d 1 b 7d 078 2 b 7d 073 3 b 7d 06e 4 b 7d 069 5 b 7d 064 6 b 7d 05f 7 b 7d 05a 8 b 7d 0a5 9 b 7d 0a0 a b 7d 09b b b 7d 096 c b 7d 091 d b 7d 08c e b 7d 087 f b 7d 082 0 c 7d 07d 1 c 7d 079 2 c 7d 075 3 c 7d 071 4 c 7d 06d 5 c 7d 069 6 c 7d 065 7 c 7d 061 8 c 7d 09d 9 c 7d 099 a c 7d 095 b c 7d 091 c c 7d 08d d c 7d 089 e c 7d 085 f c 7d 081 0 d 7d 07d 1 d 7d 07a 2 d 7d 077 3 d 7d 074 4 d 7d 071 5 d 7d 06e 6 d 7d 06b 7 d 7d 068 8 d 7d 095 9 d 7d 092 a d 7d 08f b d 7d 08c c d 7d 089 d d 7d 086 e d 7d 083 f d 7d 080 0 e 7d 07d 1 e 7d 07b 2 e 7d 079 3 e 7d 077 4 e 7d 075 5 e 7d 073 6 e 7d 071 7 e 7d 06f 8 e 7d 08d 9 e 7d 08b a e 7d 089 b e 7d 087 c e 7d 085 d e 7d 083 e e 7d 081 f e 7d 07f 0 f 7d 07d 1 f 7d 07c 2 f 7d 07b 3 f 7d 07a 4 f 7d 079 5 f 7d 078 6 f 7d 077 7 f 7d 076 8 f 7d 085 9 f 7d 084 a f 7d 083 b f 7d 082 c f 7d 081 d f 7d 080 e f 7d 07f f f 7d 07e 0 0 7e 07e 1 0 7e 07e 2 0 7e 07e 3 0 7e 07e 4 0 7e 07e 5 0 7e 07e 6 0 7e 07e 7 0 7e 07e 8 0 7e 07e 9 0 7e 07e a 0 7e 07e b 0 7e 07e c 0 7e 07e d 0 7e 07e e 0 7e 07e f 0 7e 07e 0 1 7e 07e 1 1 7e 07f 2 1 7e 080 3 1 7e 081 4 1 7e 082 5 1 7e 083 6 1 7e 084 7 1 7e 085 8 1 7e 076 9 1 7e 077 a 1 7e 078 b 1 7e 079 c 1 7e 07a d 1 7e 07b e 1 7e 07c f 1 7e 07d 0 2 7e 07e 1 2 7e 080 2 2 7e 082 3 2 7e 084 4 2 7e 086 5 2 7e 088 6 2 7e 08a 7 2 7e 08c 8 2 7e 06e 9 2 7e 070 a 2 7e 072 b 2 7e 074 c 2 7e 076 d 2 7e 078 e 2 7e 07a f 2 7e 07c 0 3 7e 07e 1 3 7e 081 2 3 7e 084 3 3 7e 087 4 3 7e 08a 5 3 7e 08d 6 3 7e 090 7 3 7e 093 8 3 7e 066 9 3 7e 069 a 3 7e 06c b 3 7e 06f c 3 7e 072 d 3 7e 075 e 3 7e 078 f 3 7e 07b 0 4 7e 07e 1 4 7e 082 2 4 7e 086 3 4 7e 08a 4 4 7e 08e 5 4 7e 092 6 4 7e 096 7 4 7e 09a 8 4 7e 05e 9 4 7e 062 a 4 7e 066 b 4 7e 06a c 4 7e 06e d 4 7e 072 e 4 7e 076 f 4 7e 07a 0 5 7e 07e 1 5 7e 083 2 5 7e 088 3 5 7e 08d 4 5 7e 092 5 5 7e 097 6 5 7e 09c 7 5 7e 0a1 8 5 7e 056 9 5 7e 05b a 5 7e 060 b 5 7e 065 c 5 7e 06a d 5 7e 06f e 5 7e 074 f 5 7e 079 0 6 7e 07e 1 6 7e 084 2 6 7e 08a 3 6 7e 090 4 6 7e 096 5 6 7e 09c 6 6 7e 0a2 7 6 7e 0a8 8 6 7e 04e 9 6 7e 054 a 6 7e 05a b 6 7e 060 c 6 7e 066 d 6 7e 06c e 6 7e 072 f 6 7e 078 0 7 7e 07e 1 7 7e 085 2 7 7e 08c 3 7 7e 093 4 7 7e 09a 5 7 7e 0a1 6 7 7e 0a8 7 7 7e 0af 8 7 7e 046 9 7 7e 04d a 7 7e 054 b 7 7e 05b c 7 7e 062 d 7 7e 069 e 7 7e 070 f 7 7e 077 0 8 7e 07e 1 8 7e 076 2 8 7e 06e 3 8 7e 066 4 8 7e 05e 5 8 7e 056 6 8 7e 04e 7 8 7e 046 8 8 7e 0be 9 8 7e 0b6 a 8 7e 0ae b 8 7e 0a6 c 8 7e 09e d 8 7e 096 e 8 7e 08e f 8 7e 086 0 9 7e 07e 1 9 7e 077 2 9 7e 070 3 9 7e 069 4 9 7e 062 5 9 7e 05b 6 9 7e 054 7 9 7e 04d 8 9 7e 0b6 9 9 7e 0af a 9 7e 0a8 b 9 7e 0a1 c 9 7e 09a d 9 7e 093 e 9 7e 08c f 9 7e 085 0 a 7e 07e 1 a 7e 078 2 a 7e 072 3 a 7e 06c 4 a 7e 066 5 a 7e 060 6 a 7e 05a 7 a 7e 054 8 a 7e 0ae 9 a 7e 0a8 a a 7e 0a2 b a 7e 09c c a 7e 096 d a 7e 090 e a 7e 08a f a 7e 084 0 b 7e 07e 1 b 7e 079 2 b 7e 074 3 b 7e 06f 4 b 7e 06a 5 b 7e 065 6 b 7e 060 7 b 7e 05b 8 b 7e 0a6 9 b 7e 0a1 a b 7e 09c b b 7e 097 c b 7e 092 d b 7e 08d e b 7e 088 f b 7e 083 0 c 7e 07e 1 c 7e 07a 2 c 7e 076 3 c 7e 072 4 c 7e 06e 5 c 7e 06a 6 c 7e 066 7 c 7e 062 8 c 7e 09e 9 c 7e 09a a c 7e 096 b c 7e 092 c c 7e 08e d c 7e 08a e c 7e 086 f c 7e 082 0 d 7e 07e 1 d 7e 07b 2 d 7e 078 3 d 7e 075 4 d 7e 072 5 d 7e 06f 6 d 7e 06c 7 d 7e 069 8 d 7e 096 9 d 7e 093 a d 7e 090 b d 7e 08d c d 7e 08a d d 7e 087 e d 7e 084 f d 7e 081 0 e 7e 07e 1 e 7e 07c 2 e 7e 07a 3 e 7e 078 4 e 7e 076 5 e 7e 074 6 e 7e 072 7 e 7e 070 8 e 7e 08e 9 e 7e 08c a e 7e 08a b e 7e 088 c e 7e 086 d e 7e 084 e e 7e 082 f e 7e 080 0 f 7e 07e 1 f 7e 07d 2 f 7e 07c 3 f 7e 07b 4 f 7e 07a 5 f 7e 079 6 f 7e 078 7 f 7e 077 8 f 7e 086 9 f 7e 085 a f 7e 084 b f 7e 083 c f 7e 082 d f 7e 081 e f 7e 080 f f 7e 07f 0 0 7f 07f 1 0 7f 07f 2 0 7f 07f 3 0 7f 07f 4 0 7f 07f 5 0 7f 07f 6 0 7f 07f 7 0 7f 07f 8 0 7f 07f 9 0 7f 07f a 0 7f 07f b 0 7f 07f c 0 7f 07f d 0 7f 07f e 0 7f 07f f 0 7f 07f 0 1 7f 07f 1 1 7f 080 2 1 7f 081 3 1 7f 082 4 1 7f 083 5 1 7f 084 6 1 7f 085 7 1 7f 086 8 1 7f 077 9 1 7f 078 a 1 7f 079 b 1 7f 07a c 1 7f 07b d 1 7f 07c e 1 7f 07d f 1 7f 07e 0 2 7f 07f 1 2 7f 081 2 2 7f 083 3 2 7f 085 4 2 7f 087 5 2 7f 089 6 2 7f 08b 7 2 7f 08d 8 2 7f 06f 9 2 7f 071 a 2 7f 073 b 2 7f 075 c 2 7f 077 d 2 7f 079 e 2 7f 07b f 2 7f 07d 0 3 7f 07f 1 3 7f 082 2 3 7f 085 3 3 7f 088 4 3 7f 08b 5 3 7f 08e 6 3 7f 091 7 3 7f 094 8 3 7f 067 9 3 7f 06a a 3 7f 06d b 3 7f 070 c 3 7f 073 d 3 7f 076 e 3 7f 079 f 3 7f 07c 0 4 7f 07f 1 4 7f 083 2 4 7f 087 3 4 7f 08b 4 4 7f 08f 5 4 7f 093 6 4 7f 097 7 4 7f 09b 8 4 7f 05f 9 4 7f 063 a 4 7f 067 b 4 7f 06b c 4 7f 06f d 4 7f 073 e 4 7f 077 f 4 7f 07b 0 5 7f 07f 1 5 7f 084 2 5 7f 089 3 5 7f 08e 4 5 7f 093 5 5 7f 098 6 5 7f 09d 7 5 7f 0a2 8 5 7f 057 9 5 7f 05c a 5 7f 061 b 5 7f 066 c 5 7f 06b d 5 7f 070 e 5 7f 075 f 5 7f 07a 0 6 7f 07f 1 6 7f 085 2 6 7f 08b 3 6 7f 091 4 6 7f 097 5 6 7f 09d 6 6 7f 0a3 7 6 7f 0a9 8 6 7f 04f 9 6 7f 055 a 6 7f 05b b 6 7f 061 c 6 7f 067 d 6 7f 06d e 6 7f 073 f 6 7f 079 0 7 7f 07f 1 7 7f 086 2 7 7f 08d 3 7 7f 094 4 7 7f 09b 5 7 7f 0a2 6 7 7f 0a9 7 7 7f 0b0 8 7 7f 047 9 7 7f 04e a 7 7f 055 b 7 7f 05c c 7 7f 063 d 7 7f 06a e 7 7f 071 f 7 7f 078 0 8 7f 07f 1 8 7f 077 2 8 7f 06f 3 8 7f 067 4 8 7f 05f 5 8 7f 057 6 8 7f 04f 7 8 7f 047 8 8 7f 0bf 9 8 7f 0b7 a 8 7f 0af b 8 7f 0a7 c 8 7f 09f d 8 7f 097 e 8 7f 08f f 8 7f 087 0 9 7f 07f 1 9 7f 078 2 9 7f 071 3 9 7f 06a 4 9 7f 063 5 9 7f 05c 6 9 7f 055 7 9 7f 04e 8 9 7f 0b7 9 9 7f 0b0 a 9 7f 0a9 b 9 7f 0a2 c 9 7f 09b d 9 7f 094 e 9 7f 08d f 9 7f 086 0 a 7f 07f 1 a 7f 079 2 a 7f 073 3 a 7f 06d 4 a 7f 067 5 a 7f 061 6 a 7f 05b 7 a 7f 055 8 a 7f 0af 9 a 7f 0a9 a a 7f 0a3 b a 7f 09d c a 7f 097 d a 7f 091 e a 7f 08b f a 7f 085 0 b 7f 07f 1 b 7f 07a 2 b 7f 075 3 b 7f 070 4 b 7f 06b 5 b 7f 066 6 b 7f 061 7 b 7f 05c 8 b 7f 0a7 9 b 7f 0a2 a b 7f 09d b b 7f 098 c b 7f 093 d b 7f 08e e b 7f 089 f b 7f 084 0 c 7f 07f 1 c 7f 07b 2 c 7f 077 3 c 7f 073 4 c 7f 06f 5 c 7f 06b 6 c 7f 067 7 c 7f 063 8 c 7f 09f 9 c 7f 09b a c 7f 097 b c 7f 093 c c 7f 08f d c 7f 08b e c 7f 087 f c 7f 083 0 d 7f 07f 1 d 7f 07c 2 d 7f 079 3 d 7f 076 4 d 7f 073 5 d 7f 070 6 d 7f 06d 7 d 7f 06a 8 d 7f 097 9 d 7f 094 a d 7f 091 b d 7f 08e c d 7f 08b d d 7f 088 e d 7f 085 f d 7f 082 0 e 7f 07f 1 e 7f 07d 2 e 7f 07b 3 e 7f 079 4 e 7f 077 5 e 7f 075 6 e 7f 073 7 e 7f 071 8 e 7f 08f 9 e 7f 08d a e 7f 08b b e 7f 089 c e 7f 087 d e 7f 085 e e 7f 083 f e 7f 081 0 f 7f 07f 1 f 7f 07e 2 f 7f 07d 3 f 7f 07c 4 f 7f 07b 5 f 7f 07a 6 f 7f 079 7 f 7f 078 8 f 7f 087 9 f 7f 086 a f 7f 085 b f 7f 084 c f 7f 083 d f 7f 082 e f 7f 081 f f 7f 080 0 0 80 180 1 0 80 180 2 0 80 180 3 0 80 180 4 0 80 180 5 0 80 180 6 0 80 180 7 0 80 180 8 0 80 180 9 0 80 180 a 0 80 180 b 0 80 180 c 0 80 180 d 0 80 180 e 0 80 180 f 0 80 180 0 1 80 180 1 1 80 181 2 1 80 182 3 1 80 183 4 1 80 184 5 1 80 185 6 1 80 186 7 1 80 187 8 1 80 178 9 1 80 179 a 1 80 17a b 1 80 17b c 1 80 17c d 1 80 17d e 1 80 17e f 1 80 17f 0 2 80 180 1 2 80 182 2 2 80 184 3 2 80 186 4 2 80 188 5 2 80 18a 6 2 80 18c 7 2 80 18e 8 2 80 170 9 2 80 172 a 2 80 174 b 2 80 176 c 2 80 178 d 2 80 17a e 2 80 17c f 2 80 17e 0 3 80 180 1 3 80 183 2 3 80 186 3 3 80 189 4 3 80 18c 5 3 80 18f 6 3 80 192 7 3 80 195 8 3 80 168 9 3 80 16b a 3 80 16e b 3 80 171 c 3 80 174 d 3 80 177 e 3 80 17a f 3 80 17d 0 4 80 180 1 4 80 184 2 4 80 188 3 4 80 18c 4 4 80 190 5 4 80 194 6 4 80 198 7 4 80 19c 8 4 80 160 9 4 80 164 a 4 80 168 b 4 80 16c c 4 80 170 d 4 80 174 e 4 80 178 f 4 80 17c 0 5 80 180 1 5 80 185 2 5 80 18a 3 5 80 18f 4 5 80 194 5 5 80 199 6 5 80 19e 7 5 80 1a3 8 5 80 158 9 5 80 15d a 5 80 162 b 5 80 167 c 5 80 16c d 5 80 171 e 5 80 176 f 5 80 17b 0 6 80 180 1 6 80 186 2 6 80 18c 3 6 80 192 4 6 80 198 5 6 80 19e 6 6 80 1a4 7 6 80 1aa 8 6 80 150 9 6 80 156 a 6 80 15c b 6 80 162 c 6 80 168 d 6 80 16e e 6 80 174 f 6 80 17a 0 7 80 180 1 7 80 187 2 7 80 18e 3 7 80 195 4 7 80 19c 5 7 80 1a3 6 7 80 1aa 7 7 80 1b1 8 7 80 148 9 7 80 14f a 7 80 156 b 7 80 15d c 7 80 164 d 7 80 16b e 7 80 172 f 7 80 179 0 8 80 180 1 8 80 178 2 8 80 170 3 8 80 168 4 8 80 160 5 8 80 158 6 8 80 150 7 8 80 148 8 8 80 1c0 9 8 80 1b8 a 8 80 1b0 b 8 80 1a8 c 8 80 1a0 d 8 80 198 e 8 80 190 f 8 80 188 0 9 80 180 1 9 80 179 2 9 80 172 3 9 80 16b 4 9 80 164 5 9 80 15d 6 9 80 156 7 9 80 14f 8 9 80 1b8 9 9 80 1b1 a 9 80 1aa b 9 80 1a3 c 9 80 19c d 9 80 195 e 9 80 18e f 9 80 187 0 a 80 180 1 a 80 17a 2 a 80 174 3 a 80 16e 4 a 80 168 5 a 80 162 6 a 80 15c 7 a 80 156 8 a 80 1b0 9 a 80 1aa a a 80 1a4 b a 80 19e c a 80 198 d a 80 192 e a 80 18c f a 80 186 0 b 80 180 1 b 80 17b 2 b 80 176 3 b 80 171 4 b 80 16c 5 b 80 167 6 b 80 162 7 b 80 15d 8 b 80 1a8 9 b 80 1a3 a b 80 19e b b 80 199 c b 80 194 d b 80 18f e b 80 18a f b 80 185 0 c 80 180 1 c 80 17c 2 c 80 178 3 c 80 174 4 c 80 170 5 c 80 16c 6 c 80 168 7 c 80 164 8 c 80 1a0 9 c 80 19c a c 80 198 b c 80 194 c c 80 190 d c 80 18c e c 80 188 f c 80 184 0 d 80 180 1 d 80 17d 2 d 80 17a 3 d 80 177 4 d 80 174 5 d 80 171 6 d 80 16e 7 d 80 16b 8 d 80 198 9 d 80 195 a d 80 192 b d 80 18f c d 80 18c d d 80 189 e d 80 186 f d 80 183 0 e 80 180 1 e 80 17e 2 e 80 17c 3 e 80 17a 4 e 80 178 5 e 80 176 6 e 80 174 7 e 80 172 8 e 80 190 9 e 80 18e a e 80 18c b e 80 18a c e 80 188 d e 80 186 e e 80 184 f e 80 182 0 f 80 180 1 f 80 17f 2 f 80 17e 3 f 80 17d 4 f 80 17c 5 f 80 17b 6 f 80 17a 7 f 80 179 8 f 80 188 9 f 80 187 a f 80 186 b f 80 185 c f 80 184 d f 80 183 e f 80 182 f f 80 181 0 0 81 181 1 0 81 181 2 0 81 181 3 0 81 181 4 0 81 181 5 0 81 181 6 0 81 181 7 0 81 181 8 0 81 181 9 0 81 181 a 0 81 181 b 0 81 181 c 0 81 181 d 0 81 181 e 0 81 181 f 0 81 181 0 1 81 181 1 1 81 182 2 1 81 183 3 1 81 184 4 1 81 185 5 1 81 186 6 1 81 187 7 1 81 188 8 1 81 179 9 1 81 17a a 1 81 17b b 1 81 17c c 1 81 17d d 1 81 17e e 1 81 17f f 1 81 180 0 2 81 181 1 2 81 183 2 2 81 185 3 2 81 187 4 2 81 189 5 2 81 18b 6 2 81 18d 7 2 81 18f 8 2 81 171 9 2 81 173 a 2 81 175 b 2 81 177 c 2 81 179 d 2 81 17b e 2 81 17d f 2 81 17f 0 3 81 181 1 3 81 184 2 3 81 187 3 3 81 18a 4 3 81 18d 5 3 81 190 6 3 81 193 7 3 81 196 8 3 81 169 9 3 81 16c a 3 81 16f b 3 81 172 c 3 81 175 d 3 81 178 e 3 81 17b f 3 81 17e 0 4 81 181 1 4 81 185 2 4 81 189 3 4 81 18d 4 4 81 191 5 4 81 195 6 4 81 199 7 4 81 19d 8 4 81 161 9 4 81 165 a 4 81 169 b 4 81 16d c 4 81 171 d 4 81 175 e 4 81 179 f 4 81 17d 0 5 81 181 1 5 81 186 2 5 81 18b 3 5 81 190 4 5 81 195 5 5 81 19a 6 5 81 19f 7 5 81 1a4 8 5 81 159 9 5 81 15e a 5 81 163 b 5 81 168 c 5 81 16d d 5 81 172 e 5 81 177 f 5 81 17c 0 6 81 181 1 6 81 187 2 6 81 18d 3 6 81 193 4 6 81 199 5 6 81 19f 6 6 81 1a5 7 6 81 1ab 8 6 81 151 9 6 81 157 a 6 81 15d b 6 81 163 c 6 81 169 d 6 81 16f e 6 81 175 f 6 81 17b 0 7 81 181 1 7 81 188 2 7 81 18f 3 7 81 196 4 7 81 19d 5 7 81 1a4 6 7 81 1ab 7 7 81 1b2 8 7 81 149 9 7 81 150 a 7 81 157 b 7 81 15e c 7 81 165 d 7 81 16c e 7 81 173 f 7 81 17a 0 8 81 181 1 8 81 179 2 8 81 171 3 8 81 169 4 8 81 161 5 8 81 159 6 8 81 151 7 8 81 149 8 8 81 1c1 9 8 81 1b9 a 8 81 1b1 b 8 81 1a9 c 8 81 1a1 d 8 81 199 e 8 81 191 f 8 81 189 0 9 81 181 1 9 81 17a 2 9 81 173 3 9 81 16c 4 9 81 165 5 9 81 15e 6 9 81 157 7 9 81 150 8 9 81 1b9 9 9 81 1b2 a 9 81 1ab b 9 81 1a4 c 9 81 19d d 9 81 196 e 9 81 18f f 9 81 188 0 a 81 181 1 a 81 17b 2 a 81 175 3 a 81 16f 4 a 81 169 5 a 81 163 6 a 81 15d 7 a 81 157 8 a 81 1b1 9 a 81 1ab a a 81 1a5 b a 81 19f c a 81 199 d a 81 193 e a 81 18d f a 81 187 0 b 81 181 1 b 81 17c 2 b 81 177 3 b 81 172 4 b 81 16d 5 b 81 168 6 b 81 163 7 b 81 15e 8 b 81 1a9 9 b 81 1a4 a b 81 19f b b 81 19a c b 81 195 d b 81 190 e b 81 18b f b 81 186 0 c 81 181 1 c 81 17d 2 c 81 179 3 c 81 175 4 c 81 171 5 c 81 16d 6 c 81 169 7 c 81 165 8 c 81 1a1 9 c 81 19d a c 81 199 b c 81 195 c c 81 191 d c 81 18d e c 81 189 f c 81 185 0 d 81 181 1 d 81 17e 2 d 81 17b 3 d 81 178 4 d 81 175 5 d 81 172 6 d 81 16f 7 d 81 16c 8 d 81 199 9 d 81 196 a d 81 193 b d 81 190 c d 81 18d d d 81 18a e d 81 187 f d 81 184 0 e 81 181 1 e 81 17f 2 e 81 17d 3 e 81 17b 4 e 81 179 5 e 81 177 6 e 81 175 7 e 81 173 8 e 81 191 9 e 81 18f a e 81 18d b e 81 18b c e 81 189 d e 81 187 e e 81 185 f e 81 183 0 f 81 181 1 f 81 180 2 f 81 17f 3 f 81 17e 4 f 81 17d 5 f 81 17c 6 f 81 17b 7 f 81 17a 8 f 81 189 9 f 81 188 a f 81 187 b f 81 186 c f 81 185 d f 81 184 e f 81 183 f f 81 182 0 0 82 182 1 0 82 182 2 0 82 182 3 0 82 182 4 0 82 182 5 0 82 182 6 0 82 182 7 0 82 182 8 0 82 182 9 0 82 182 a 0 82 182 b 0 82 182 c 0 82 182 d 0 82 182 e 0 82 182 f 0 82 182 0 1 82 182 1 1 82 183 2 1 82 184 3 1 82 185 4 1 82 186 5 1 82 187 6 1 82 188 7 1 82 189 8 1 82 17a 9 1 82 17b a 1 82 17c b 1 82 17d c 1 82 17e d 1 82 17f e 1 82 180 f 1 82 181 0 2 82 182 1 2 82 184 2 2 82 186 3 2 82 188 4 2 82 18a 5 2 82 18c 6 2 82 18e 7 2 82 190 8 2 82 172 9 2 82 174 a 2 82 176 b 2 82 178 c 2 82 17a d 2 82 17c e 2 82 17e f 2 82 180 0 3 82 182 1 3 82 185 2 3 82 188 3 3 82 18b 4 3 82 18e 5 3 82 191 6 3 82 194 7 3 82 197 8 3 82 16a 9 3 82 16d a 3 82 170 b 3 82 173 c 3 82 176 d 3 82 179 e 3 82 17c f 3 82 17f 0 4 82 182 1 4 82 186 2 4 82 18a 3 4 82 18e 4 4 82 192 5 4 82 196 6 4 82 19a 7 4 82 19e 8 4 82 162 9 4 82 166 a 4 82 16a b 4 82 16e c 4 82 172 d 4 82 176 e 4 82 17a f 4 82 17e 0 5 82 182 1 5 82 187 2 5 82 18c 3 5 82 191 4 5 82 196 5 5 82 19b 6 5 82 1a0 7 5 82 1a5 8 5 82 15a 9 5 82 15f a 5 82 164 b 5 82 169 c 5 82 16e d 5 82 173 e 5 82 178 f 5 82 17d 0 6 82 182 1 6 82 188 2 6 82 18e 3 6 82 194 4 6 82 19a 5 6 82 1a0 6 6 82 1a6 7 6 82 1ac 8 6 82 152 9 6 82 158 a 6 82 15e b 6 82 164 c 6 82 16a d 6 82 170 e 6 82 176 f 6 82 17c 0 7 82 182 1 7 82 189 2 7 82 190 3 7 82 197 4 7 82 19e 5 7 82 1a5 6 7 82 1ac 7 7 82 1b3 8 7 82 14a 9 7 82 151 a 7 82 158 b 7 82 15f c 7 82 166 d 7 82 16d e 7 82 174 f 7 82 17b 0 8 82 182 1 8 82 17a 2 8 82 172 3 8 82 16a 4 8 82 162 5 8 82 15a 6 8 82 152 7 8 82 14a 8 8 82 1c2 9 8 82 1ba a 8 82 1b2 b 8 82 1aa c 8 82 1a2 d 8 82 19a e 8 82 192 f 8 82 18a 0 9 82 182 1 9 82 17b 2 9 82 174 3 9 82 16d 4 9 82 166 5 9 82 15f 6 9 82 158 7 9 82 151 8 9 82 1ba 9 9 82 1b3 a 9 82 1ac b 9 82 1a5 c 9 82 19e d 9 82 197 e 9 82 190 f 9 82 189 0 a 82 182 1 a 82 17c 2 a 82 176 3 a 82 170 4 a 82 16a 5 a 82 164 6 a 82 15e 7 a 82 158 8 a 82 1b2 9 a 82 1ac a a 82 1a6 b a 82 1a0 c a 82 19a d a 82 194 e a 82 18e f a 82 188 0 b 82 182 1 b 82 17d 2 b 82 178 3 b 82 173 4 b 82 16e 5 b 82 169 6 b 82 164 7 b 82 15f 8 b 82 1aa 9 b 82 1a5 a b 82 1a0 b b 82 19b c b 82 196 d b 82 191 e b 82 18c f b 82 187 0 c 82 182 1 c 82 17e 2 c 82 17a 3 c 82 176 4 c 82 172 5 c 82 16e 6 c 82 16a 7 c 82 166 8 c 82 1a2 9 c 82 19e a c 82 19a b c 82 196 c c 82 192 d c 82 18e e c 82 18a f c 82 186 0 d 82 182 1 d 82 17f 2 d 82 17c 3 d 82 179 4 d 82 176 5 d 82 173 6 d 82 170 7 d 82 16d 8 d 82 19a 9 d 82 197 a d 82 194 b d 82 191 c d 82 18e d d 82 18b e d 82 188 f d 82 185 0 e 82 182 1 e 82 180 2 e 82 17e 3 e 82 17c 4 e 82 17a 5 e 82 178 6 e 82 176 7 e 82 174 8 e 82 192 9 e 82 190 a e 82 18e b e 82 18c c e 82 18a d e 82 188 e e 82 186 f e 82 184 0 f 82 182 1 f 82 181 2 f 82 180 3 f 82 17f 4 f 82 17e 5 f 82 17d 6 f 82 17c 7 f 82 17b 8 f 82 18a 9 f 82 189 a f 82 188 b f 82 187 c f 82 186 d f 82 185 e f 82 184 f f 82 183 0 0 83 183 1 0 83 183 2 0 83 183 3 0 83 183 4 0 83 183 5 0 83 183 6 0 83 183 7 0 83 183 8 0 83 183 9 0 83 183 a 0 83 183 b 0 83 183 c 0 83 183 d 0 83 183 e 0 83 183 f 0 83 183 0 1 83 183 1 1 83 184 2 1 83 185 3 1 83 186 4 1 83 187 5 1 83 188 6 1 83 189 7 1 83 18a 8 1 83 17b 9 1 83 17c a 1 83 17d b 1 83 17e c 1 83 17f d 1 83 180 e 1 83 181 f 1 83 182 0 2 83 183 1 2 83 185 2 2 83 187 3 2 83 189 4 2 83 18b 5 2 83 18d 6 2 83 18f 7 2 83 191 8 2 83 173 9 2 83 175 a 2 83 177 b 2 83 179 c 2 83 17b d 2 83 17d e 2 83 17f f 2 83 181 0 3 83 183 1 3 83 186 2 3 83 189 3 3 83 18c 4 3 83 18f 5 3 83 192 6 3 83 195 7 3 83 198 8 3 83 16b 9 3 83 16e a 3 83 171 b 3 83 174 c 3 83 177 d 3 83 17a e 3 83 17d f 3 83 180 0 4 83 183 1 4 83 187 2 4 83 18b 3 4 83 18f 4 4 83 193 5 4 83 197 6 4 83 19b 7 4 83 19f 8 4 83 163 9 4 83 167 a 4 83 16b b 4 83 16f c 4 83 173 d 4 83 177 e 4 83 17b f 4 83 17f 0 5 83 183 1 5 83 188 2 5 83 18d 3 5 83 192 4 5 83 197 5 5 83 19c 6 5 83 1a1 7 5 83 1a6 8 5 83 15b 9 5 83 160 a 5 83 165 b 5 83 16a c 5 83 16f d 5 83 174 e 5 83 179 f 5 83 17e 0 6 83 183 1 6 83 189 2 6 83 18f 3 6 83 195 4 6 83 19b 5 6 83 1a1 6 6 83 1a7 7 6 83 1ad 8 6 83 153 9 6 83 159 a 6 83 15f b 6 83 165 c 6 83 16b d 6 83 171 e 6 83 177 f 6 83 17d 0 7 83 183 1 7 83 18a 2 7 83 191 3 7 83 198 4 7 83 19f 5 7 83 1a6 6 7 83 1ad 7 7 83 1b4 8 7 83 14b 9 7 83 152 a 7 83 159 b 7 83 160 c 7 83 167 d 7 83 16e e 7 83 175 f 7 83 17c 0 8 83 183 1 8 83 17b 2 8 83 173 3 8 83 16b 4 8 83 163 5 8 83 15b 6 8 83 153 7 8 83 14b 8 8 83 1c3 9 8 83 1bb a 8 83 1b3 b 8 83 1ab c 8 83 1a3 d 8 83 19b e 8 83 193 f 8 83 18b 0 9 83 183 1 9 83 17c 2 9 83 175 3 9 83 16e 4 9 83 167 5 9 83 160 6 9 83 159 7 9 83 152 8 9 83 1bb 9 9 83 1b4 a 9 83 1ad b 9 83 1a6 c 9 83 19f d 9 83 198 e 9 83 191 f 9 83 18a 0 a 83 183 1 a 83 17d 2 a 83 177 3 a 83 171 4 a 83 16b 5 a 83 165 6 a 83 15f 7 a 83 159 8 a 83 1b3 9 a 83 1ad a a 83 1a7 b a 83 1a1 c a 83 19b d a 83 195 e a 83 18f f a 83 189 0 b 83 183 1 b 83 17e 2 b 83 179 3 b 83 174 4 b 83 16f 5 b 83 16a 6 b 83 165 7 b 83 160 8 b 83 1ab 9 b 83 1a6 a b 83 1a1 b b 83 19c c b 83 197 d b 83 192 e b 83 18d f b 83 188 0 c 83 183 1 c 83 17f 2 c 83 17b 3 c 83 177 4 c 83 173 5 c 83 16f 6 c 83 16b 7 c 83 167 8 c 83 1a3 9 c 83 19f a c 83 19b b c 83 197 c c 83 193 d c 83 18f e c 83 18b f c 83 187 0 d 83 183 1 d 83 180 2 d 83 17d 3 d 83 17a 4 d 83 177 5 d 83 174 6 d 83 171 7 d 83 16e 8 d 83 19b 9 d 83 198 a d 83 195 b d 83 192 c d 83 18f d d 83 18c e d 83 189 f d 83 186 0 e 83 183 1 e 83 181 2 e 83 17f 3 e 83 17d 4 e 83 17b 5 e 83 179 6 e 83 177 7 e 83 175 8 e 83 193 9 e 83 191 a e 83 18f b e 83 18d c e 83 18b d e 83 189 e e 83 187 f e 83 185 0 f 83 183 1 f 83 182 2 f 83 181 3 f 83 180 4 f 83 17f 5 f 83 17e 6 f 83 17d 7 f 83 17c 8 f 83 18b 9 f 83 18a a f 83 189 b f 83 188 c f 83 187 d f 83 186 e f 83 185 f f 83 184 0 0 84 184 1 0 84 184 2 0 84 184 3 0 84 184 4 0 84 184 5 0 84 184 6 0 84 184 7 0 84 184 8 0 84 184 9 0 84 184 a 0 84 184 b 0 84 184 c 0 84 184 d 0 84 184 e 0 84 184 f 0 84 184 0 1 84 184 1 1 84 185 2 1 84 186 3 1 84 187 4 1 84 188 5 1 84 189 6 1 84 18a 7 1 84 18b 8 1 84 17c 9 1 84 17d a 1 84 17e b 1 84 17f c 1 84 180 d 1 84 181 e 1 84 182 f 1 84 183 0 2 84 184 1 2 84 186 2 2 84 188 3 2 84 18a 4 2 84 18c 5 2 84 18e 6 2 84 190 7 2 84 192 8 2 84 174 9 2 84 176 a 2 84 178 b 2 84 17a c 2 84 17c d 2 84 17e e 2 84 180 f 2 84 182 0 3 84 184 1 3 84 187 2 3 84 18a 3 3 84 18d 4 3 84 190 5 3 84 193 6 3 84 196 7 3 84 199 8 3 84 16c 9 3 84 16f a 3 84 172 b 3 84 175 c 3 84 178 d 3 84 17b e 3 84 17e f 3 84 181 0 4 84 184 1 4 84 188 2 4 84 18c 3 4 84 190 4 4 84 194 5 4 84 198 6 4 84 19c 7 4 84 1a0 8 4 84 164 9 4 84 168 a 4 84 16c b 4 84 170 c 4 84 174 d 4 84 178 e 4 84 17c f 4 84 180 0 5 84 184 1 5 84 189 2 5 84 18e 3 5 84 193 4 5 84 198 5 5 84 19d 6 5 84 1a2 7 5 84 1a7 8 5 84 15c 9 5 84 161 a 5 84 166 b 5 84 16b c 5 84 170 d 5 84 175 e 5 84 17a f 5 84 17f 0 6 84 184 1 6 84 18a 2 6 84 190 3 6 84 196 4 6 84 19c 5 6 84 1a2 6 6 84 1a8 7 6 84 1ae 8 6 84 154 9 6 84 15a a 6 84 160 b 6 84 166 c 6 84 16c d 6 84 172 e 6 84 178 f 6 84 17e 0 7 84 184 1 7 84 18b 2 7 84 192 3 7 84 199 4 7 84 1a0 5 7 84 1a7 6 7 84 1ae 7 7 84 1b5 8 7 84 14c 9 7 84 153 a 7 84 15a b 7 84 161 c 7 84 168 d 7 84 16f e 7 84 176 f 7 84 17d 0 8 84 184 1 8 84 17c 2 8 84 174 3 8 84 16c 4 8 84 164 5 8 84 15c 6 8 84 154 7 8 84 14c 8 8 84 1c4 9 8 84 1bc a 8 84 1b4 b 8 84 1ac c 8 84 1a4 d 8 84 19c e 8 84 194 f 8 84 18c 0 9 84 184 1 9 84 17d 2 9 84 176 3 9 84 16f 4 9 84 168 5 9 84 161 6 9 84 15a 7 9 84 153 8 9 84 1bc 9 9 84 1b5 a 9 84 1ae b 9 84 1a7 c 9 84 1a0 d 9 84 199 e 9 84 192 f 9 84 18b 0 a 84 184 1 a 84 17e 2 a 84 178 3 a 84 172 4 a 84 16c 5 a 84 166 6 a 84 160 7 a 84 15a 8 a 84 1b4 9 a 84 1ae a a 84 1a8 b a 84 1a2 c a 84 19c d a 84 196 e a 84 190 f a 84 18a 0 b 84 184 1 b 84 17f 2 b 84 17a 3 b 84 175 4 b 84 170 5 b 84 16b 6 b 84 166 7 b 84 161 8 b 84 1ac 9 b 84 1a7 a b 84 1a2 b b 84 19d c b 84 198 d b 84 193 e b 84 18e f b 84 189 0 c 84 184 1 c 84 180 2 c 84 17c 3 c 84 178 4 c 84 174 5 c 84 170 6 c 84 16c 7 c 84 168 8 c 84 1a4 9 c 84 1a0 a c 84 19c b c 84 198 c c 84 194 d c 84 190 e c 84 18c f c 84 188 0 d 84 184 1 d 84 181 2 d 84 17e 3 d 84 17b 4 d 84 178 5 d 84 175 6 d 84 172 7 d 84 16f 8 d 84 19c 9 d 84 199 a d 84 196 b d 84 193 c d 84 190 d d 84 18d e d 84 18a f d 84 187 0 e 84 184 1 e 84 182 2 e 84 180 3 e 84 17e 4 e 84 17c 5 e 84 17a 6 e 84 178 7 e 84 176 8 e 84 194 9 e 84 192 a e 84 190 b e 84 18e c e 84 18c d e 84 18a e e 84 188 f e 84 186 0 f 84 184 1 f 84 183 2 f 84 182 3 f 84 181 4 f 84 180 5 f 84 17f 6 f 84 17e 7 f 84 17d 8 f 84 18c 9 f 84 18b a f 84 18a b f 84 189 c f 84 188 d f 84 187 e f 84 186 f f 84 185 0 0 85 185 1 0 85 185 2 0 85 185 3 0 85 185 4 0 85 185 5 0 85 185 6 0 85 185 7 0 85 185 8 0 85 185 9 0 85 185 a 0 85 185 b 0 85 185 c 0 85 185 d 0 85 185 e 0 85 185 f 0 85 185 0 1 85 185 1 1 85 186 2 1 85 187 3 1 85 188 4 1 85 189 5 1 85 18a 6 1 85 18b 7 1 85 18c 8 1 85 17d 9 1 85 17e a 1 85 17f b 1 85 180 c 1 85 181 d 1 85 182 e 1 85 183 f 1 85 184 0 2 85 185 1 2 85 187 2 2 85 189 3 2 85 18b 4 2 85 18d 5 2 85 18f 6 2 85 191 7 2 85 193 8 2 85 175 9 2 85 177 a 2 85 179 b 2 85 17b c 2 85 17d d 2 85 17f e 2 85 181 f 2 85 183 0 3 85 185 1 3 85 188 2 3 85 18b 3 3 85 18e 4 3 85 191 5 3 85 194 6 3 85 197 7 3 85 19a 8 3 85 16d 9 3 85 170 a 3 85 173 b 3 85 176 c 3 85 179 d 3 85 17c e 3 85 17f f 3 85 182 0 4 85 185 1 4 85 189 2 4 85 18d 3 4 85 191 4 4 85 195 5 4 85 199 6 4 85 19d 7 4 85 1a1 8 4 85 165 9 4 85 169 a 4 85 16d b 4 85 171 c 4 85 175 d 4 85 179 e 4 85 17d f 4 85 181 0 5 85 185 1 5 85 18a 2 5 85 18f 3 5 85 194 4 5 85 199 5 5 85 19e 6 5 85 1a3 7 5 85 1a8 8 5 85 15d 9 5 85 162 a 5 85 167 b 5 85 16c c 5 85 171 d 5 85 176 e 5 85 17b f 5 85 180 0 6 85 185 1 6 85 18b 2 6 85 191 3 6 85 197 4 6 85 19d 5 6 85 1a3 6 6 85 1a9 7 6 85 1af 8 6 85 155 9 6 85 15b a 6 85 161 b 6 85 167 c 6 85 16d d 6 85 173 e 6 85 179 f 6 85 17f 0 7 85 185 1 7 85 18c 2 7 85 193 3 7 85 19a 4 7 85 1a1 5 7 85 1a8 6 7 85 1af 7 7 85 1b6 8 7 85 14d 9 7 85 154 a 7 85 15b b 7 85 162 c 7 85 169 d 7 85 170 e 7 85 177 f 7 85 17e 0 8 85 185 1 8 85 17d 2 8 85 175 3 8 85 16d 4 8 85 165 5 8 85 15d 6 8 85 155 7 8 85 14d 8 8 85 1c5 9 8 85 1bd a 8 85 1b5 b 8 85 1ad c 8 85 1a5 d 8 85 19d e 8 85 195 f 8 85 18d 0 9 85 185 1 9 85 17e 2 9 85 177 3 9 85 170 4 9 85 169 5 9 85 162 6 9 85 15b 7 9 85 154 8 9 85 1bd 9 9 85 1b6 a 9 85 1af b 9 85 1a8 c 9 85 1a1 d 9 85 19a e 9 85 193 f 9 85 18c 0 a 85 185 1 a 85 17f 2 a 85 179 3 a 85 173 4 a 85 16d 5 a 85 167 6 a 85 161 7 a 85 15b 8 a 85 1b5 9 a 85 1af a a 85 1a9 b a 85 1a3 c a 85 19d d a 85 197 e a 85 191 f a 85 18b 0 b 85 185 1 b 85 180 2 b 85 17b 3 b 85 176 4 b 85 171 5 b 85 16c 6 b 85 167 7 b 85 162 8 b 85 1ad 9 b 85 1a8 a b 85 1a3 b b 85 19e c b 85 199 d b 85 194 e b 85 18f f b 85 18a 0 c 85 185 1 c 85 181 2 c 85 17d 3 c 85 179 4 c 85 175 5 c 85 171 6 c 85 16d 7 c 85 169 8 c 85 1a5 9 c 85 1a1 a c 85 19d b c 85 199 c c 85 195 d c 85 191 e c 85 18d f c 85 189 0 d 85 185 1 d 85 182 2 d 85 17f 3 d 85 17c 4 d 85 179 5 d 85 176 6 d 85 173 7 d 85 170 8 d 85 19d 9 d 85 19a a d 85 197 b d 85 194 c d 85 191 d d 85 18e e d 85 18b f d 85 188 0 e 85 185 1 e 85 183 2 e 85 181 3 e 85 17f 4 e 85 17d 5 e 85 17b 6 e 85 179 7 e 85 177 8 e 85 195 9 e 85 193 a e 85 191 b e 85 18f c e 85 18d d e 85 18b e e 85 189 f e 85 187 0 f 85 185 1 f 85 184 2 f 85 183 3 f 85 182 4 f 85 181 5 f 85 180 6 f 85 17f 7 f 85 17e 8 f 85 18d 9 f 85 18c a f 85 18b b f 85 18a c f 85 189 d f 85 188 e f 85 187 f f 85 186 0 0 86 186 1 0 86 186 2 0 86 186 3 0 86 186 4 0 86 186 5 0 86 186 6 0 86 186 7 0 86 186 8 0 86 186 9 0 86 186 a 0 86 186 b 0 86 186 c 0 86 186 d 0 86 186 e 0 86 186 f 0 86 186 0 1 86 186 1 1 86 187 2 1 86 188 3 1 86 189 4 1 86 18a 5 1 86 18b 6 1 86 18c 7 1 86 18d 8 1 86 17e 9 1 86 17f a 1 86 180 b 1 86 181 c 1 86 182 d 1 86 183 e 1 86 184 f 1 86 185 0 2 86 186 1 2 86 188 2 2 86 18a 3 2 86 18c 4 2 86 18e 5 2 86 190 6 2 86 192 7 2 86 194 8 2 86 176 9 2 86 178 a 2 86 17a b 2 86 17c c 2 86 17e d 2 86 180 e 2 86 182 f 2 86 184 0 3 86 186 1 3 86 189 2 3 86 18c 3 3 86 18f 4 3 86 192 5 3 86 195 6 3 86 198 7 3 86 19b 8 3 86 16e 9 3 86 171 a 3 86 174 b 3 86 177 c 3 86 17a d 3 86 17d e 3 86 180 f 3 86 183 0 4 86 186 1 4 86 18a 2 4 86 18e 3 4 86 192 4 4 86 196 5 4 86 19a 6 4 86 19e 7 4 86 1a2 8 4 86 166 9 4 86 16a a 4 86 16e b 4 86 172 c 4 86 176 d 4 86 17a e 4 86 17e f 4 86 182 0 5 86 186 1 5 86 18b 2 5 86 190 3 5 86 195 4 5 86 19a 5 5 86 19f 6 5 86 1a4 7 5 86 1a9 8 5 86 15e 9 5 86 163 a 5 86 168 b 5 86 16d c 5 86 172 d 5 86 177 e 5 86 17c f 5 86 181 0 6 86 186 1 6 86 18c 2 6 86 192 3 6 86 198 4 6 86 19e 5 6 86 1a4 6 6 86 1aa 7 6 86 1b0 8 6 86 156 9 6 86 15c a 6 86 162 b 6 86 168 c 6 86 16e d 6 86 174 e 6 86 17a f 6 86 180 0 7 86 186 1 7 86 18d 2 7 86 194 3 7 86 19b 4 7 86 1a2 5 7 86 1a9 6 7 86 1b0 7 7 86 1b7 8 7 86 14e 9 7 86 155 a 7 86 15c b 7 86 163 c 7 86 16a d 7 86 171 e 7 86 178 f 7 86 17f 0 8 86 186 1 8 86 17e 2 8 86 176 3 8 86 16e 4 8 86 166 5 8 86 15e 6 8 86 156 7 8 86 14e 8 8 86 1c6 9 8 86 1be a 8 86 1b6 b 8 86 1ae c 8 86 1a6 d 8 86 19e e 8 86 196 f 8 86 18e 0 9 86 186 1 9 86 17f 2 9 86 178 3 9 86 171 4 9 86 16a 5 9 86 163 6 9 86 15c 7 9 86 155 8 9 86 1be 9 9 86 1b7 a 9 86 1b0 b 9 86 1a9 c 9 86 1a2 d 9 86 19b e 9 86 194 f 9 86 18d 0 a 86 186 1 a 86 180 2 a 86 17a 3 a 86 174 4 a 86 16e 5 a 86 168 6 a 86 162 7 a 86 15c 8 a 86 1b6 9 a 86 1b0 a a 86 1aa b a 86 1a4 c a 86 19e d a 86 198 e a 86 192 f a 86 18c 0 b 86 186 1 b 86 181 2 b 86 17c 3 b 86 177 4 b 86 172 5 b 86 16d 6 b 86 168 7 b 86 163 8 b 86 1ae 9 b 86 1a9 a b 86 1a4 b b 86 19f c b 86 19a d b 86 195 e b 86 190 f b 86 18b 0 c 86 186 1 c 86 182 2 c 86 17e 3 c 86 17a 4 c 86 176 5 c 86 172 6 c 86 16e 7 c 86 16a 8 c 86 1a6 9 c 86 1a2 a c 86 19e b c 86 19a c c 86 196 d c 86 192 e c 86 18e f c 86 18a 0 d 86 186 1 d 86 183 2 d 86 180 3 d 86 17d 4 d 86 17a 5 d 86 177 6 d 86 174 7 d 86 171 8 d 86 19e 9 d 86 19b a d 86 198 b d 86 195 c d 86 192 d d 86 18f e d 86 18c f d 86 189 0 e 86 186 1 e 86 184 2 e 86 182 3 e 86 180 4 e 86 17e 5 e 86 17c 6 e 86 17a 7 e 86 178 8 e 86 196 9 e 86 194 a e 86 192 b e 86 190 c e 86 18e d e 86 18c e e 86 18a f e 86 188 0 f 86 186 1 f 86 185 2 f 86 184 3 f 86 183 4 f 86 182 5 f 86 181 6 f 86 180 7 f 86 17f 8 f 86 18e 9 f 86 18d a f 86 18c b f 86 18b c f 86 18a d f 86 189 e f 86 188 f f 86 187 0 0 87 187 1 0 87 187 2 0 87 187 3 0 87 187 4 0 87 187 5 0 87 187 6 0 87 187 7 0 87 187 8 0 87 187 9 0 87 187 a 0 87 187 b 0 87 187 c 0 87 187 d 0 87 187 e 0 87 187 f 0 87 187 0 1 87 187 1 1 87 188 2 1 87 189 3 1 87 18a 4 1 87 18b 5 1 87 18c 6 1 87 18d 7 1 87 18e 8 1 87 17f 9 1 87 180 a 1 87 181 b 1 87 182 c 1 87 183 d 1 87 184 e 1 87 185 f 1 87 186 0 2 87 187 1 2 87 189 2 2 87 18b 3 2 87 18d 4 2 87 18f 5 2 87 191 6 2 87 193 7 2 87 195 8 2 87 177 9 2 87 179 a 2 87 17b b 2 87 17d c 2 87 17f d 2 87 181 e 2 87 183 f 2 87 185 0 3 87 187 1 3 87 18a 2 3 87 18d 3 3 87 190 4 3 87 193 5 3 87 196 6 3 87 199 7 3 87 19c 8 3 87 16f 9 3 87 172 a 3 87 175 b 3 87 178 c 3 87 17b d 3 87 17e e 3 87 181 f 3 87 184 0 4 87 187 1 4 87 18b 2 4 87 18f 3 4 87 193 4 4 87 197 5 4 87 19b 6 4 87 19f 7 4 87 1a3 8 4 87 167 9 4 87 16b a 4 87 16f b 4 87 173 c 4 87 177 d 4 87 17b e 4 87 17f f 4 87 183 0 5 87 187 1 5 87 18c 2 5 87 191 3 5 87 196 4 5 87 19b 5 5 87 1a0 6 5 87 1a5 7 5 87 1aa 8 5 87 15f 9 5 87 164 a 5 87 169 b 5 87 16e c 5 87 173 d 5 87 178 e 5 87 17d f 5 87 182 0 6 87 187 1 6 87 18d 2 6 87 193 3 6 87 199 4 6 87 19f 5 6 87 1a5 6 6 87 1ab 7 6 87 1b1 8 6 87 157 9 6 87 15d a 6 87 163 b 6 87 169 c 6 87 16f d 6 87 175 e 6 87 17b f 6 87 181 0 7 87 187 1 7 87 18e 2 7 87 195 3 7 87 19c 4 7 87 1a3 5 7 87 1aa 6 7 87 1b1 7 7 87 1b8 8 7 87 14f 9 7 87 156 a 7 87 15d b 7 87 164 c 7 87 16b d 7 87 172 e 7 87 179 f 7 87 180 0 8 87 187 1 8 87 17f 2 8 87 177 3 8 87 16f 4 8 87 167 5 8 87 15f 6 8 87 157 7 8 87 14f 8 8 87 1c7 9 8 87 1bf a 8 87 1b7 b 8 87 1af c 8 87 1a7 d 8 87 19f e 8 87 197 f 8 87 18f 0 9 87 187 1 9 87 180 2 9 87 179 3 9 87 172 4 9 87 16b 5 9 87 164 6 9 87 15d 7 9 87 156 8 9 87 1bf 9 9 87 1b8 a 9 87 1b1 b 9 87 1aa c 9 87 1a3 d 9 87 19c e 9 87 195 f 9 87 18e 0 a 87 187 1 a 87 181 2 a 87 17b 3 a 87 175 4 a 87 16f 5 a 87 169 6 a 87 163 7 a 87 15d 8 a 87 1b7 9 a 87 1b1 a a 87 1ab b a 87 1a5 c a 87 19f d a 87 199 e a 87 193 f a 87 18d 0 b 87 187 1 b 87 182 2 b 87 17d 3 b 87 178 4 b 87 173 5 b 87 16e 6 b 87 169 7 b 87 164 8 b 87 1af 9 b 87 1aa a b 87 1a5 b b 87 1a0 c b 87 19b d b 87 196 e b 87 191 f b 87 18c 0 c 87 187 1 c 87 183 2 c 87 17f 3 c 87 17b 4 c 87 177 5 c 87 173 6 c 87 16f 7 c 87 16b 8 c 87 1a7 9 c 87 1a3 a c 87 19f b c 87 19b c c 87 197 d c 87 193 e c 87 18f f c 87 18b 0 d 87 187 1 d 87 184 2 d 87 181 3 d 87 17e 4 d 87 17b 5 d 87 178 6 d 87 175 7 d 87 172 8 d 87 19f 9 d 87 19c a d 87 199 b d 87 196 c d 87 193 d d 87 190 e d 87 18d f d 87 18a 0 e 87 187 1 e 87 185 2 e 87 183 3 e 87 181 4 e 87 17f 5 e 87 17d 6 e 87 17b 7 e 87 179 8 e 87 197 9 e 87 195 a e 87 193 b e 87 191 c e 87 18f d e 87 18d e e 87 18b f e 87 189 0 f 87 187 1 f 87 186 2 f 87 185 3 f 87 184 4 f 87 183 5 f 87 182 6 f 87 181 7 f 87 180 8 f 87 18f 9 f 87 18e a f 87 18d b f 87 18c c f 87 18b d f 87 18a e f 87 189 f f 87 188 0 0 88 188 1 0 88 188 2 0 88 188 3 0 88 188 4 0 88 188 5 0 88 188 6 0 88 188 7 0 88 188 8 0 88 188 9 0 88 188 a 0 88 188 b 0 88 188 c 0 88 188 d 0 88 188 e 0 88 188 f 0 88 188 0 1 88 188 1 1 88 189 2 1 88 18a 3 1 88 18b 4 1 88 18c 5 1 88 18d 6 1 88 18e 7 1 88 18f 8 1 88 180 9 1 88 181 a 1 88 182 b 1 88 183 c 1 88 184 d 1 88 185 e 1 88 186 f 1 88 187 0 2 88 188 1 2 88 18a 2 2 88 18c 3 2 88 18e 4 2 88 190 5 2 88 192 6 2 88 194 7 2 88 196 8 2 88 178 9 2 88 17a a 2 88 17c b 2 88 17e c 2 88 180 d 2 88 182 e 2 88 184 f 2 88 186 0 3 88 188 1 3 88 18b 2 3 88 18e 3 3 88 191 4 3 88 194 5 3 88 197 6 3 88 19a 7 3 88 19d 8 3 88 170 9 3 88 173 a 3 88 176 b 3 88 179 c 3 88 17c d 3 88 17f e 3 88 182 f 3 88 185 0 4 88 188 1 4 88 18c 2 4 88 190 3 4 88 194 4 4 88 198 5 4 88 19c 6 4 88 1a0 7 4 88 1a4 8 4 88 168 9 4 88 16c a 4 88 170 b 4 88 174 c 4 88 178 d 4 88 17c e 4 88 180 f 4 88 184 0 5 88 188 1 5 88 18d 2 5 88 192 3 5 88 197 4 5 88 19c 5 5 88 1a1 6 5 88 1a6 7 5 88 1ab 8 5 88 160 9 5 88 165 a 5 88 16a b 5 88 16f c 5 88 174 d 5 88 179 e 5 88 17e f 5 88 183 0 6 88 188 1 6 88 18e 2 6 88 194 3 6 88 19a 4 6 88 1a0 5 6 88 1a6 6 6 88 1ac 7 6 88 1b2 8 6 88 158 9 6 88 15e a 6 88 164 b 6 88 16a c 6 88 170 d 6 88 176 e 6 88 17c f 6 88 182 0 7 88 188 1 7 88 18f 2 7 88 196 3 7 88 19d 4 7 88 1a4 5 7 88 1ab 6 7 88 1b2 7 7 88 1b9 8 7 88 150 9 7 88 157 a 7 88 15e b 7 88 165 c 7 88 16c d 7 88 173 e 7 88 17a f 7 88 181 0 8 88 188 1 8 88 180 2 8 88 178 3 8 88 170 4 8 88 168 5 8 88 160 6 8 88 158 7 8 88 150 8 8 88 1c8 9 8 88 1c0 a 8 88 1b8 b 8 88 1b0 c 8 88 1a8 d 8 88 1a0 e 8 88 198 f 8 88 190 0 9 88 188 1 9 88 181 2 9 88 17a 3 9 88 173 4 9 88 16c 5 9 88 165 6 9 88 15e 7 9 88 157 8 9 88 1c0 9 9 88 1b9 a 9 88 1b2 b 9 88 1ab c 9 88 1a4 d 9 88 19d e 9 88 196 f 9 88 18f 0 a 88 188 1 a 88 182 2 a 88 17c 3 a 88 176 4 a 88 170 5 a 88 16a 6 a 88 164 7 a 88 15e 8 a 88 1b8 9 a 88 1b2 a a 88 1ac b a 88 1a6 c a 88 1a0 d a 88 19a e a 88 194 f a 88 18e 0 b 88 188 1 b 88 183 2 b 88 17e 3 b 88 179 4 b 88 174 5 b 88 16f 6 b 88 16a 7 b 88 165 8 b 88 1b0 9 b 88 1ab a b 88 1a6 b b 88 1a1 c b 88 19c d b 88 197 e b 88 192 f b 88 18d 0 c 88 188 1 c 88 184 2 c 88 180 3 c 88 17c 4 c 88 178 5 c 88 174 6 c 88 170 7 c 88 16c 8 c 88 1a8 9 c 88 1a4 a c 88 1a0 b c 88 19c c c 88 198 d c 88 194 e c 88 190 f c 88 18c 0 d 88 188 1 d 88 185 2 d 88 182 3 d 88 17f 4 d 88 17c 5 d 88 179 6 d 88 176 7 d 88 173 8 d 88 1a0 9 d 88 19d a d 88 19a b d 88 197 c d 88 194 d d 88 191 e d 88 18e f d 88 18b 0 e 88 188 1 e 88 186 2 e 88 184 3 e 88 182 4 e 88 180 5 e 88 17e 6 e 88 17c 7 e 88 17a 8 e 88 198 9 e 88 196 a e 88 194 b e 88 192 c e 88 190 d e 88 18e e e 88 18c f e 88 18a 0 f 88 188 1 f 88 187 2 f 88 186 3 f 88 185 4 f 88 184 5 f 88 183 6 f 88 182 7 f 88 181 8 f 88 190 9 f 88 18f a f 88 18e b f 88 18d c f 88 18c d f 88 18b e f 88 18a f f 88 189 0 0 89 189 1 0 89 189 2 0 89 189 3 0 89 189 4 0 89 189 5 0 89 189 6 0 89 189 7 0 89 189 8 0 89 189 9 0 89 189 a 0 89 189 b 0 89 189 c 0 89 189 d 0 89 189 e 0 89 189 f 0 89 189 0 1 89 189 1 1 89 18a 2 1 89 18b 3 1 89 18c 4 1 89 18d 5 1 89 18e 6 1 89 18f 7 1 89 190 8 1 89 181 9 1 89 182 a 1 89 183 b 1 89 184 c 1 89 185 d 1 89 186 e 1 89 187 f 1 89 188 0 2 89 189 1 2 89 18b 2 2 89 18d 3 2 89 18f 4 2 89 191 5 2 89 193 6 2 89 195 7 2 89 197 8 2 89 179 9 2 89 17b a 2 89 17d b 2 89 17f c 2 89 181 d 2 89 183 e 2 89 185 f 2 89 187 0 3 89 189 1 3 89 18c 2 3 89 18f 3 3 89 192 4 3 89 195 5 3 89 198 6 3 89 19b 7 3 89 19e 8 3 89 171 9 3 89 174 a 3 89 177 b 3 89 17a c 3 89 17d d 3 89 180 e 3 89 183 f 3 89 186 0 4 89 189 1 4 89 18d 2 4 89 191 3 4 89 195 4 4 89 199 5 4 89 19d 6 4 89 1a1 7 4 89 1a5 8 4 89 169 9 4 89 16d a 4 89 171 b 4 89 175 c 4 89 179 d 4 89 17d e 4 89 181 f 4 89 185 0 5 89 189 1 5 89 18e 2 5 89 193 3 5 89 198 4 5 89 19d 5 5 89 1a2 6 5 89 1a7 7 5 89 1ac 8 5 89 161 9 5 89 166 a 5 89 16b b 5 89 170 c 5 89 175 d 5 89 17a e 5 89 17f f 5 89 184 0 6 89 189 1 6 89 18f 2 6 89 195 3 6 89 19b 4 6 89 1a1 5 6 89 1a7 6 6 89 1ad 7 6 89 1b3 8 6 89 159 9 6 89 15f a 6 89 165 b 6 89 16b c 6 89 171 d 6 89 177 e 6 89 17d f 6 89 183 0 7 89 189 1 7 89 190 2 7 89 197 3 7 89 19e 4 7 89 1a5 5 7 89 1ac 6 7 89 1b3 7 7 89 1ba 8 7 89 151 9 7 89 158 a 7 89 15f b 7 89 166 c 7 89 16d d 7 89 174 e 7 89 17b f 7 89 182 0 8 89 189 1 8 89 181 2 8 89 179 3 8 89 171 4 8 89 169 5 8 89 161 6 8 89 159 7 8 89 151 8 8 89 1c9 9 8 89 1c1 a 8 89 1b9 b 8 89 1b1 c 8 89 1a9 d 8 89 1a1 e 8 89 199 f 8 89 191 0 9 89 189 1 9 89 182 2 9 89 17b 3 9 89 174 4 9 89 16d 5 9 89 166 6 9 89 15f 7 9 89 158 8 9 89 1c1 9 9 89 1ba a 9 89 1b3 b 9 89 1ac c 9 89 1a5 d 9 89 19e e 9 89 197 f 9 89 190 0 a 89 189 1 a 89 183 2 a 89 17d 3 a 89 177 4 a 89 171 5 a 89 16b 6 a 89 165 7 a 89 15f 8 a 89 1b9 9 a 89 1b3 a a 89 1ad b a 89 1a7 c a 89 1a1 d a 89 19b e a 89 195 f a 89 18f 0 b 89 189 1 b 89 184 2 b 89 17f 3 b 89 17a 4 b 89 175 5 b 89 170 6 b 89 16b 7 b 89 166 8 b 89 1b1 9 b 89 1ac a b 89 1a7 b b 89 1a2 c b 89 19d d b 89 198 e b 89 193 f b 89 18e 0 c 89 189 1 c 89 185 2 c 89 181 3 c 89 17d 4 c 89 179 5 c 89 175 6 c 89 171 7 c 89 16d 8 c 89 1a9 9 c 89 1a5 a c 89 1a1 b c 89 19d c c 89 199 d c 89 195 e c 89 191 f c 89 18d 0 d 89 189 1 d 89 186 2 d 89 183 3 d 89 180 4 d 89 17d 5 d 89 17a 6 d 89 177 7 d 89 174 8 d 89 1a1 9 d 89 19e a d 89 19b b d 89 198 c d 89 195 d d 89 192 e d 89 18f f d 89 18c 0 e 89 189 1 e 89 187 2 e 89 185 3 e 89 183 4 e 89 181 5 e 89 17f 6 e 89 17d 7 e 89 17b 8 e 89 199 9 e 89 197 a e 89 195 b e 89 193 c e 89 191 d e 89 18f e e 89 18d f e 89 18b 0 f 89 189 1 f 89 188 2 f 89 187 3 f 89 186 4 f 89 185 5 f 89 184 6 f 89 183 7 f 89 182 8 f 89 191 9 f 89 190 a f 89 18f b f 89 18e c f 89 18d d f 89 18c e f 89 18b f f 89 18a 0 0 8a 18a 1 0 8a 18a 2 0 8a 18a 3 0 8a 18a 4 0 8a 18a 5 0 8a 18a 6 0 8a 18a 7 0 8a 18a 8 0 8a 18a 9 0 8a 18a a 0 8a 18a b 0 8a 18a c 0 8a 18a d 0 8a 18a e 0 8a 18a f 0 8a 18a 0 1 8a 18a 1 1 8a 18b 2 1 8a 18c 3 1 8a 18d 4 1 8a 18e 5 1 8a 18f 6 1 8a 190 7 1 8a 191 8 1 8a 182 9 1 8a 183 a 1 8a 184 b 1 8a 185 c 1 8a 186 d 1 8a 187 e 1 8a 188 f 1 8a 189 0 2 8a 18a 1 2 8a 18c 2 2 8a 18e 3 2 8a 190 4 2 8a 192 5 2 8a 194 6 2 8a 196 7 2 8a 198 8 2 8a 17a 9 2 8a 17c a 2 8a 17e b 2 8a 180 c 2 8a 182 d 2 8a 184 e 2 8a 186 f 2 8a 188 0 3 8a 18a 1 3 8a 18d 2 3 8a 190 3 3 8a 193 4 3 8a 196 5 3 8a 199 6 3 8a 19c 7 3 8a 19f 8 3 8a 172 9 3 8a 175 a 3 8a 178 b 3 8a 17b c 3 8a 17e d 3 8a 181 e 3 8a 184 f 3 8a 187 0 4 8a 18a 1 4 8a 18e 2 4 8a 192 3 4 8a 196 4 4 8a 19a 5 4 8a 19e 6 4 8a 1a2 7 4 8a 1a6 8 4 8a 16a 9 4 8a 16e a 4 8a 172 b 4 8a 176 c 4 8a 17a d 4 8a 17e e 4 8a 182 f 4 8a 186 0 5 8a 18a 1 5 8a 18f 2 5 8a 194 3 5 8a 199 4 5 8a 19e 5 5 8a 1a3 6 5 8a 1a8 7 5 8a 1ad 8 5 8a 162 9 5 8a 167 a 5 8a 16c b 5 8a 171 c 5 8a 176 d 5 8a 17b e 5 8a 180 f 5 8a 185 0 6 8a 18a 1 6 8a 190 2 6 8a 196 3 6 8a 19c 4 6 8a 1a2 5 6 8a 1a8 6 6 8a 1ae 7 6 8a 1b4 8 6 8a 15a 9 6 8a 160 a 6 8a 166 b 6 8a 16c c 6 8a 172 d 6 8a 178 e 6 8a 17e f 6 8a 184 0 7 8a 18a 1 7 8a 191 2 7 8a 198 3 7 8a 19f 4 7 8a 1a6 5 7 8a 1ad 6 7 8a 1b4 7 7 8a 1bb 8 7 8a 152 9 7 8a 159 a 7 8a 160 b 7 8a 167 c 7 8a 16e d 7 8a 175 e 7 8a 17c f 7 8a 183 0 8 8a 18a 1 8 8a 182 2 8 8a 17a 3 8 8a 172 4 8 8a 16a 5 8 8a 162 6 8 8a 15a 7 8 8a 152 8 8 8a 1ca 9 8 8a 1c2 a 8 8a 1ba b 8 8a 1b2 c 8 8a 1aa d 8 8a 1a2 e 8 8a 19a f 8 8a 192 0 9 8a 18a 1 9 8a 183 2 9 8a 17c 3 9 8a 175 4 9 8a 16e 5 9 8a 167 6 9 8a 160 7 9 8a 159 8 9 8a 1c2 9 9 8a 1bb a 9 8a 1b4 b 9 8a 1ad c 9 8a 1a6 d 9 8a 19f e 9 8a 198 f 9 8a 191 0 a 8a 18a 1 a 8a 184 2 a 8a 17e 3 a 8a 178 4 a 8a 172 5 a 8a 16c 6 a 8a 166 7 a 8a 160 8 a 8a 1ba 9 a 8a 1b4 a a 8a 1ae b a 8a 1a8 c a 8a 1a2 d a 8a 19c e a 8a 196 f a 8a 190 0 b 8a 18a 1 b 8a 185 2 b 8a 180 3 b 8a 17b 4 b 8a 176 5 b 8a 171 6 b 8a 16c 7 b 8a 167 8 b 8a 1b2 9 b 8a 1ad a b 8a 1a8 b b 8a 1a3 c b 8a 19e d b 8a 199 e b 8a 194 f b 8a 18f 0 c 8a 18a 1 c 8a 186 2 c 8a 182 3 c 8a 17e 4 c 8a 17a 5 c 8a 176 6 c 8a 172 7 c 8a 16e 8 c 8a 1aa 9 c 8a 1a6 a c 8a 1a2 b c 8a 19e c c 8a 19a d c 8a 196 e c 8a 192 f c 8a 18e 0 d 8a 18a 1 d 8a 187 2 d 8a 184 3 d 8a 181 4 d 8a 17e 5 d 8a 17b 6 d 8a 178 7 d 8a 175 8 d 8a 1a2 9 d 8a 19f a d 8a 19c b d 8a 199 c d 8a 196 d d 8a 193 e d 8a 190 f d 8a 18d 0 e 8a 18a 1 e 8a 188 2 e 8a 186 3 e 8a 184 4 e 8a 182 5 e 8a 180 6 e 8a 17e 7 e 8a 17c 8 e 8a 19a 9 e 8a 198 a e 8a 196 b e 8a 194 c e 8a 192 d e 8a 190 e e 8a 18e f e 8a 18c 0 f 8a 18a 1 f 8a 189 2 f 8a 188 3 f 8a 187 4 f 8a 186 5 f 8a 185 6 f 8a 184 7 f 8a 183 8 f 8a 192 9 f 8a 191 a f 8a 190 b f 8a 18f c f 8a 18e d f 8a 18d e f 8a 18c f f 8a 18b 0 0 8b 18b 1 0 8b 18b 2 0 8b 18b 3 0 8b 18b 4 0 8b 18b 5 0 8b 18b 6 0 8b 18b 7 0 8b 18b 8 0 8b 18b 9 0 8b 18b a 0 8b 18b b 0 8b 18b c 0 8b 18b d 0 8b 18b e 0 8b 18b f 0 8b 18b 0 1 8b 18b 1 1 8b 18c 2 1 8b 18d 3 1 8b 18e 4 1 8b 18f 5 1 8b 190 6 1 8b 191 7 1 8b 192 8 1 8b 183 9 1 8b 184 a 1 8b 185 b 1 8b 186 c 1 8b 187 d 1 8b 188 e 1 8b 189 f 1 8b 18a 0 2 8b 18b 1 2 8b 18d 2 2 8b 18f 3 2 8b 191 4 2 8b 193 5 2 8b 195 6 2 8b 197 7 2 8b 199 8 2 8b 17b 9 2 8b 17d a 2 8b 17f b 2 8b 181 c 2 8b 183 d 2 8b 185 e 2 8b 187 f 2 8b 189 0 3 8b 18b 1 3 8b 18e 2 3 8b 191 3 3 8b 194 4 3 8b 197 5 3 8b 19a 6 3 8b 19d 7 3 8b 1a0 8 3 8b 173 9 3 8b 176 a 3 8b 179 b 3 8b 17c c 3 8b 17f d 3 8b 182 e 3 8b 185 f 3 8b 188 0 4 8b 18b 1 4 8b 18f 2 4 8b 193 3 4 8b 197 4 4 8b 19b 5 4 8b 19f 6 4 8b 1a3 7 4 8b 1a7 8 4 8b 16b 9 4 8b 16f a 4 8b 173 b 4 8b 177 c 4 8b 17b d 4 8b 17f e 4 8b 183 f 4 8b 187 0 5 8b 18b 1 5 8b 190 2 5 8b 195 3 5 8b 19a 4 5 8b 19f 5 5 8b 1a4 6 5 8b 1a9 7 5 8b 1ae 8 5 8b 163 9 5 8b 168 a 5 8b 16d b 5 8b 172 c 5 8b 177 d 5 8b 17c e 5 8b 181 f 5 8b 186 0 6 8b 18b 1 6 8b 191 2 6 8b 197 3 6 8b 19d 4 6 8b 1a3 5 6 8b 1a9 6 6 8b 1af 7 6 8b 1b5 8 6 8b 15b 9 6 8b 161 a 6 8b 167 b 6 8b 16d c 6 8b 173 d 6 8b 179 e 6 8b 17f f 6 8b 185 0 7 8b 18b 1 7 8b 192 2 7 8b 199 3 7 8b 1a0 4 7 8b 1a7 5 7 8b 1ae 6 7 8b 1b5 7 7 8b 1bc 8 7 8b 153 9 7 8b 15a a 7 8b 161 b 7 8b 168 c 7 8b 16f d 7 8b 176 e 7 8b 17d f 7 8b 184 0 8 8b 18b 1 8 8b 183 2 8 8b 17b 3 8 8b 173 4 8 8b 16b 5 8 8b 163 6 8 8b 15b 7 8 8b 153 8 8 8b 1cb 9 8 8b 1c3 a 8 8b 1bb b 8 8b 1b3 c 8 8b 1ab d 8 8b 1a3 e 8 8b 19b f 8 8b 193 0 9 8b 18b 1 9 8b 184 2 9 8b 17d 3 9 8b 176 4 9 8b 16f 5 9 8b 168 6 9 8b 161 7 9 8b 15a 8 9 8b 1c3 9 9 8b 1bc a 9 8b 1b5 b 9 8b 1ae c 9 8b 1a7 d 9 8b 1a0 e 9 8b 199 f 9 8b 192 0 a 8b 18b 1 a 8b 185 2 a 8b 17f 3 a 8b 179 4 a 8b 173 5 a 8b 16d 6 a 8b 167 7 a 8b 161 8 a 8b 1bb 9 a 8b 1b5 a a 8b 1af b a 8b 1a9 c a 8b 1a3 d a 8b 19d e a 8b 197 f a 8b 191 0 b 8b 18b 1 b 8b 186 2 b 8b 181 3 b 8b 17c 4 b 8b 177 5 b 8b 172 6 b 8b 16d 7 b 8b 168 8 b 8b 1b3 9 b 8b 1ae a b 8b 1a9 b b 8b 1a4 c b 8b 19f d b 8b 19a e b 8b 195 f b 8b 190 0 c 8b 18b 1 c 8b 187 2 c 8b 183 3 c 8b 17f 4 c 8b 17b 5 c 8b 177 6 c 8b 173 7 c 8b 16f 8 c 8b 1ab 9 c 8b 1a7 a c 8b 1a3 b c 8b 19f c c 8b 19b d c 8b 197 e c 8b 193 f c 8b 18f 0 d 8b 18b 1 d 8b 188 2 d 8b 185 3 d 8b 182 4 d 8b 17f 5 d 8b 17c 6 d 8b 179 7 d 8b 176 8 d 8b 1a3 9 d 8b 1a0 a d 8b 19d b d 8b 19a c d 8b 197 d d 8b 194 e d 8b 191 f d 8b 18e 0 e 8b 18b 1 e 8b 189 2 e 8b 187 3 e 8b 185 4 e 8b 183 5 e 8b 181 6 e 8b 17f 7 e 8b 17d 8 e 8b 19b 9 e 8b 199 a e 8b 197 b e 8b 195 c e 8b 193 d e 8b 191 e e 8b 18f f e 8b 18d 0 f 8b 18b 1 f 8b 18a 2 f 8b 189 3 f 8b 188 4 f 8b 187 5 f 8b 186 6 f 8b 185 7 f 8b 184 8 f 8b 193 9 f 8b 192 a f 8b 191 b f 8b 190 c f 8b 18f d f 8b 18e e f 8b 18d f f 8b 18c 0 0 8c 18c 1 0 8c 18c 2 0 8c 18c 3 0 8c 18c 4 0 8c 18c 5 0 8c 18c 6 0 8c 18c 7 0 8c 18c 8 0 8c 18c 9 0 8c 18c a 0 8c 18c b 0 8c 18c c 0 8c 18c d 0 8c 18c e 0 8c 18c f 0 8c 18c 0 1 8c 18c 1 1 8c 18d 2 1 8c 18e 3 1 8c 18f 4 1 8c 190 5 1 8c 191 6 1 8c 192 7 1 8c 193 8 1 8c 184 9 1 8c 185 a 1 8c 186 b 1 8c 187 c 1 8c 188 d 1 8c 189 e 1 8c 18a f 1 8c 18b 0 2 8c 18c 1 2 8c 18e 2 2 8c 190 3 2 8c 192 4 2 8c 194 5 2 8c 196 6 2 8c 198 7 2 8c 19a 8 2 8c 17c 9 2 8c 17e a 2 8c 180 b 2 8c 182 c 2 8c 184 d 2 8c 186 e 2 8c 188 f 2 8c 18a 0 3 8c 18c 1 3 8c 18f 2 3 8c 192 3 3 8c 195 4 3 8c 198 5 3 8c 19b 6 3 8c 19e 7 3 8c 1a1 8 3 8c 174 9 3 8c 177 a 3 8c 17a b 3 8c 17d c 3 8c 180 d 3 8c 183 e 3 8c 186 f 3 8c 189 0 4 8c 18c 1 4 8c 190 2 4 8c 194 3 4 8c 198 4 4 8c 19c 5 4 8c 1a0 6 4 8c 1a4 7 4 8c 1a8 8 4 8c 16c 9 4 8c 170 a 4 8c 174 b 4 8c 178 c 4 8c 17c d 4 8c 180 e 4 8c 184 f 4 8c 188 0 5 8c 18c 1 5 8c 191 2 5 8c 196 3 5 8c 19b 4 5 8c 1a0 5 5 8c 1a5 6 5 8c 1aa 7 5 8c 1af 8 5 8c 164 9 5 8c 169 a 5 8c 16e b 5 8c 173 c 5 8c 178 d 5 8c 17d e 5 8c 182 f 5 8c 187 0 6 8c 18c 1 6 8c 192 2 6 8c 198 3 6 8c 19e 4 6 8c 1a4 5 6 8c 1aa 6 6 8c 1b0 7 6 8c 1b6 8 6 8c 15c 9 6 8c 162 a 6 8c 168 b 6 8c 16e c 6 8c 174 d 6 8c 17a e 6 8c 180 f 6 8c 186 0 7 8c 18c 1 7 8c 193 2 7 8c 19a 3 7 8c 1a1 4 7 8c 1a8 5 7 8c 1af 6 7 8c 1b6 7 7 8c 1bd 8 7 8c 154 9 7 8c 15b a 7 8c 162 b 7 8c 169 c 7 8c 170 d 7 8c 177 e 7 8c 17e f 7 8c 185 0 8 8c 18c 1 8 8c 184 2 8 8c 17c 3 8 8c 174 4 8 8c 16c 5 8 8c 164 6 8 8c 15c 7 8 8c 154 8 8 8c 1cc 9 8 8c 1c4 a 8 8c 1bc b 8 8c 1b4 c 8 8c 1ac d 8 8c 1a4 e 8 8c 19c f 8 8c 194 0 9 8c 18c 1 9 8c 185 2 9 8c 17e 3 9 8c 177 4 9 8c 170 5 9 8c 169 6 9 8c 162 7 9 8c 15b 8 9 8c 1c4 9 9 8c 1bd a 9 8c 1b6 b 9 8c 1af c 9 8c 1a8 d 9 8c 1a1 e 9 8c 19a f 9 8c 193 0 a 8c 18c 1 a 8c 186 2 a 8c 180 3 a 8c 17a 4 a 8c 174 5 a 8c 16e 6 a 8c 168 7 a 8c 162 8 a 8c 1bc 9 a 8c 1b6 a a 8c 1b0 b a 8c 1aa c a 8c 1a4 d a 8c 19e e a 8c 198 f a 8c 192 0 b 8c 18c 1 b 8c 187 2 b 8c 182 3 b 8c 17d 4 b 8c 178 5 b 8c 173 6 b 8c 16e 7 b 8c 169 8 b 8c 1b4 9 b 8c 1af a b 8c 1aa b b 8c 1a5 c b 8c 1a0 d b 8c 19b e b 8c 196 f b 8c 191 0 c 8c 18c 1 c 8c 188 2 c 8c 184 3 c 8c 180 4 c 8c 17c 5 c 8c 178 6 c 8c 174 7 c 8c 170 8 c 8c 1ac 9 c 8c 1a8 a c 8c 1a4 b c 8c 1a0 c c 8c 19c d c 8c 198 e c 8c 194 f c 8c 190 0 d 8c 18c 1 d 8c 189 2 d 8c 186 3 d 8c 183 4 d 8c 180 5 d 8c 17d 6 d 8c 17a 7 d 8c 177 8 d 8c 1a4 9 d 8c 1a1 a d 8c 19e b d 8c 19b c d 8c 198 d d 8c 195 e d 8c 192 f d 8c 18f 0 e 8c 18c 1 e 8c 18a 2 e 8c 188 3 e 8c 186 4 e 8c 184 5 e 8c 182 6 e 8c 180 7 e 8c 17e 8 e 8c 19c 9 e 8c 19a a e 8c 198 b e 8c 196 c e 8c 194 d e 8c 192 e e 8c 190 f e 8c 18e 0 f 8c 18c 1 f 8c 18b 2 f 8c 18a 3 f 8c 189 4 f 8c 188 5 f 8c 187 6 f 8c 186 7 f 8c 185 8 f 8c 194 9 f 8c 193 a f 8c 192 b f 8c 191 c f 8c 190 d f 8c 18f e f 8c 18e f f 8c 18d 0 0 8d 18d 1 0 8d 18d 2 0 8d 18d 3 0 8d 18d 4 0 8d 18d 5 0 8d 18d 6 0 8d 18d 7 0 8d 18d 8 0 8d 18d 9 0 8d 18d a 0 8d 18d b 0 8d 18d c 0 8d 18d d 0 8d 18d e 0 8d 18d f 0 8d 18d 0 1 8d 18d 1 1 8d 18e 2 1 8d 18f 3 1 8d 190 4 1 8d 191 5 1 8d 192 6 1 8d 193 7 1 8d 194 8 1 8d 185 9 1 8d 186 a 1 8d 187 b 1 8d 188 c 1 8d 189 d 1 8d 18a e 1 8d 18b f 1 8d 18c 0 2 8d 18d 1 2 8d 18f 2 2 8d 191 3 2 8d 193 4 2 8d 195 5 2 8d 197 6 2 8d 199 7 2 8d 19b 8 2 8d 17d 9 2 8d 17f a 2 8d 181 b 2 8d 183 c 2 8d 185 d 2 8d 187 e 2 8d 189 f 2 8d 18b 0 3 8d 18d 1 3 8d 190 2 3 8d 193 3 3 8d 196 4 3 8d 199 5 3 8d 19c 6 3 8d 19f 7 3 8d 1a2 8 3 8d 175 9 3 8d 178 a 3 8d 17b b 3 8d 17e c 3 8d 181 d 3 8d 184 e 3 8d 187 f 3 8d 18a 0 4 8d 18d 1 4 8d 191 2 4 8d 195 3 4 8d 199 4 4 8d 19d 5 4 8d 1a1 6 4 8d 1a5 7 4 8d 1a9 8 4 8d 16d 9 4 8d 171 a 4 8d 175 b 4 8d 179 c 4 8d 17d d 4 8d 181 e 4 8d 185 f 4 8d 189 0 5 8d 18d 1 5 8d 192 2 5 8d 197 3 5 8d 19c 4 5 8d 1a1 5 5 8d 1a6 6 5 8d 1ab 7 5 8d 1b0 8 5 8d 165 9 5 8d 16a a 5 8d 16f b 5 8d 174 c 5 8d 179 d 5 8d 17e e 5 8d 183 f 5 8d 188 0 6 8d 18d 1 6 8d 193 2 6 8d 199 3 6 8d 19f 4 6 8d 1a5 5 6 8d 1ab 6 6 8d 1b1 7 6 8d 1b7 8 6 8d 15d 9 6 8d 163 a 6 8d 169 b 6 8d 16f c 6 8d 175 d 6 8d 17b e 6 8d 181 f 6 8d 187 0 7 8d 18d 1 7 8d 194 2 7 8d 19b 3 7 8d 1a2 4 7 8d 1a9 5 7 8d 1b0 6 7 8d 1b7 7 7 8d 1be 8 7 8d 155 9 7 8d 15c a 7 8d 163 b 7 8d 16a c 7 8d 171 d 7 8d 178 e 7 8d 17f f 7 8d 186 0 8 8d 18d 1 8 8d 185 2 8 8d 17d 3 8 8d 175 4 8 8d 16d 5 8 8d 165 6 8 8d 15d 7 8 8d 155 8 8 8d 1cd 9 8 8d 1c5 a 8 8d 1bd b 8 8d 1b5 c 8 8d 1ad d 8 8d 1a5 e 8 8d 19d f 8 8d 195 0 9 8d 18d 1 9 8d 186 2 9 8d 17f 3 9 8d 178 4 9 8d 171 5 9 8d 16a 6 9 8d 163 7 9 8d 15c 8 9 8d 1c5 9 9 8d 1be a 9 8d 1b7 b 9 8d 1b0 c 9 8d 1a9 d 9 8d 1a2 e 9 8d 19b f 9 8d 194 0 a 8d 18d 1 a 8d 187 2 a 8d 181 3 a 8d 17b 4 a 8d 175 5 a 8d 16f 6 a 8d 169 7 a 8d 163 8 a 8d 1bd 9 a 8d 1b7 a a 8d 1b1 b a 8d 1ab c a 8d 1a5 d a 8d 19f e a 8d 199 f a 8d 193 0 b 8d 18d 1 b 8d 188 2 b 8d 183 3 b 8d 17e 4 b 8d 179 5 b 8d 174 6 b 8d 16f 7 b 8d 16a 8 b 8d 1b5 9 b 8d 1b0 a b 8d 1ab b b 8d 1a6 c b 8d 1a1 d b 8d 19c e b 8d 197 f b 8d 192 0 c 8d 18d 1 c 8d 189 2 c 8d 185 3 c 8d 181 4 c 8d 17d 5 c 8d 179 6 c 8d 175 7 c 8d 171 8 c 8d 1ad 9 c 8d 1a9 a c 8d 1a5 b c 8d 1a1 c c 8d 19d d c 8d 199 e c 8d 195 f c 8d 191 0 d 8d 18d 1 d 8d 18a 2 d 8d 187 3 d 8d 184 4 d 8d 181 5 d 8d 17e 6 d 8d 17b 7 d 8d 178 8 d 8d 1a5 9 d 8d 1a2 a d 8d 19f b d 8d 19c c d 8d 199 d d 8d 196 e d 8d 193 f d 8d 190 0 e 8d 18d 1 e 8d 18b 2 e 8d 189 3 e 8d 187 4 e 8d 185 5 e 8d 183 6 e 8d 181 7 e 8d 17f 8 e 8d 19d 9 e 8d 19b a e 8d 199 b e 8d 197 c e 8d 195 d e 8d 193 e e 8d 191 f e 8d 18f 0 f 8d 18d 1 f 8d 18c 2 f 8d 18b 3 f 8d 18a 4 f 8d 189 5 f 8d 188 6 f 8d 187 7 f 8d 186 8 f 8d 195 9 f 8d 194 a f 8d 193 b f 8d 192 c f 8d 191 d f 8d 190 e f 8d 18f f f 8d 18e 0 0 8e 18e 1 0 8e 18e 2 0 8e 18e 3 0 8e 18e 4 0 8e 18e 5 0 8e 18e 6 0 8e 18e 7 0 8e 18e 8 0 8e 18e 9 0 8e 18e a 0 8e 18e b 0 8e 18e c 0 8e 18e d 0 8e 18e e 0 8e 18e f 0 8e 18e 0 1 8e 18e 1 1 8e 18f 2 1 8e 190 3 1 8e 191 4 1 8e 192 5 1 8e 193 6 1 8e 194 7 1 8e 195 8 1 8e 186 9 1 8e 187 a 1 8e 188 b 1 8e 189 c 1 8e 18a d 1 8e 18b e 1 8e 18c f 1 8e 18d 0 2 8e 18e 1 2 8e 190 2 2 8e 192 3 2 8e 194 4 2 8e 196 5 2 8e 198 6 2 8e 19a 7 2 8e 19c 8 2 8e 17e 9 2 8e 180 a 2 8e 182 b 2 8e 184 c 2 8e 186 d 2 8e 188 e 2 8e 18a f 2 8e 18c 0 3 8e 18e 1 3 8e 191 2 3 8e 194 3 3 8e 197 4 3 8e 19a 5 3 8e 19d 6 3 8e 1a0 7 3 8e 1a3 8 3 8e 176 9 3 8e 179 a 3 8e 17c b 3 8e 17f c 3 8e 182 d 3 8e 185 e 3 8e 188 f 3 8e 18b 0 4 8e 18e 1 4 8e 192 2 4 8e 196 3 4 8e 19a 4 4 8e 19e 5 4 8e 1a2 6 4 8e 1a6 7 4 8e 1aa 8 4 8e 16e 9 4 8e 172 a 4 8e 176 b 4 8e 17a c 4 8e 17e d 4 8e 182 e 4 8e 186 f 4 8e 18a 0 5 8e 18e 1 5 8e 193 2 5 8e 198 3 5 8e 19d 4 5 8e 1a2 5 5 8e 1a7 6 5 8e 1ac 7 5 8e 1b1 8 5 8e 166 9 5 8e 16b a 5 8e 170 b 5 8e 175 c 5 8e 17a d 5 8e 17f e 5 8e 184 f 5 8e 189 0 6 8e 18e 1 6 8e 194 2 6 8e 19a 3 6 8e 1a0 4 6 8e 1a6 5 6 8e 1ac 6 6 8e 1b2 7 6 8e 1b8 8 6 8e 15e 9 6 8e 164 a 6 8e 16a b 6 8e 170 c 6 8e 176 d 6 8e 17c e 6 8e 182 f 6 8e 188 0 7 8e 18e 1 7 8e 195 2 7 8e 19c 3 7 8e 1a3 4 7 8e 1aa 5 7 8e 1b1 6 7 8e 1b8 7 7 8e 1bf 8 7 8e 156 9 7 8e 15d a 7 8e 164 b 7 8e 16b c 7 8e 172 d 7 8e 179 e 7 8e 180 f 7 8e 187 0 8 8e 18e 1 8 8e 186 2 8 8e 17e 3 8 8e 176 4 8 8e 16e 5 8 8e 166 6 8 8e 15e 7 8 8e 156 8 8 8e 1ce 9 8 8e 1c6 a 8 8e 1be b 8 8e 1b6 c 8 8e 1ae d 8 8e 1a6 e 8 8e 19e f 8 8e 196 0 9 8e 18e 1 9 8e 187 2 9 8e 180 3 9 8e 179 4 9 8e 172 5 9 8e 16b 6 9 8e 164 7 9 8e 15d 8 9 8e 1c6 9 9 8e 1bf a 9 8e 1b8 b 9 8e 1b1 c 9 8e 1aa d 9 8e 1a3 e 9 8e 19c f 9 8e 195 0 a 8e 18e 1 a 8e 188 2 a 8e 182 3 a 8e 17c 4 a 8e 176 5 a 8e 170 6 a 8e 16a 7 a 8e 164 8 a 8e 1be 9 a 8e 1b8 a a 8e 1b2 b a 8e 1ac c a 8e 1a6 d a 8e 1a0 e a 8e 19a f a 8e 194 0 b 8e 18e 1 b 8e 189 2 b 8e 184 3 b 8e 17f 4 b 8e 17a 5 b 8e 175 6 b 8e 170 7 b 8e 16b 8 b 8e 1b6 9 b 8e 1b1 a b 8e 1ac b b 8e 1a7 c b 8e 1a2 d b 8e 19d e b 8e 198 f b 8e 193 0 c 8e 18e 1 c 8e 18a 2 c 8e 186 3 c 8e 182 4 c 8e 17e 5 c 8e 17a 6 c 8e 176 7 c 8e 172 8 c 8e 1ae 9 c 8e 1aa a c 8e 1a6 b c 8e 1a2 c c 8e 19e d c 8e 19a e c 8e 196 f c 8e 192 0 d 8e 18e 1 d 8e 18b 2 d 8e 188 3 d 8e 185 4 d 8e 182 5 d 8e 17f 6 d 8e 17c 7 d 8e 179 8 d 8e 1a6 9 d 8e 1a3 a d 8e 1a0 b d 8e 19d c d 8e 19a d d 8e 197 e d 8e 194 f d 8e 191 0 e 8e 18e 1 e 8e 18c 2 e 8e 18a 3 e 8e 188 4 e 8e 186 5 e 8e 184 6 e 8e 182 7 e 8e 180 8 e 8e 19e 9 e 8e 19c a e 8e 19a b e 8e 198 c e 8e 196 d e 8e 194 e e 8e 192 f e 8e 190 0 f 8e 18e 1 f 8e 18d 2 f 8e 18c 3 f 8e 18b 4 f 8e 18a 5 f 8e 189 6 f 8e 188 7 f 8e 187 8 f 8e 196 9 f 8e 195 a f 8e 194 b f 8e 193 c f 8e 192 d f 8e 191 e f 8e 190 f f 8e 18f 0 0 8f 18f 1 0 8f 18f 2 0 8f 18f 3 0 8f 18f 4 0 8f 18f 5 0 8f 18f 6 0 8f 18f 7 0 8f 18f 8 0 8f 18f 9 0 8f 18f a 0 8f 18f b 0 8f 18f c 0 8f 18f d 0 8f 18f e 0 8f 18f f 0 8f 18f 0 1 8f 18f 1 1 8f 190 2 1 8f 191 3 1 8f 192 4 1 8f 193 5 1 8f 194 6 1 8f 195 7 1 8f 196 8 1 8f 187 9 1 8f 188 a 1 8f 189 b 1 8f 18a c 1 8f 18b d 1 8f 18c e 1 8f 18d f 1 8f 18e 0 2 8f 18f 1 2 8f 191 2 2 8f 193 3 2 8f 195 4 2 8f 197 5 2 8f 199 6 2 8f 19b 7 2 8f 19d 8 2 8f 17f 9 2 8f 181 a 2 8f 183 b 2 8f 185 c 2 8f 187 d 2 8f 189 e 2 8f 18b f 2 8f 18d 0 3 8f 18f 1 3 8f 192 2 3 8f 195 3 3 8f 198 4 3 8f 19b 5 3 8f 19e 6 3 8f 1a1 7 3 8f 1a4 8 3 8f 177 9 3 8f 17a a 3 8f 17d b 3 8f 180 c 3 8f 183 d 3 8f 186 e 3 8f 189 f 3 8f 18c 0 4 8f 18f 1 4 8f 193 2 4 8f 197 3 4 8f 19b 4 4 8f 19f 5 4 8f 1a3 6 4 8f 1a7 7 4 8f 1ab 8 4 8f 16f 9 4 8f 173 a 4 8f 177 b 4 8f 17b c 4 8f 17f d 4 8f 183 e 4 8f 187 f 4 8f 18b 0 5 8f 18f 1 5 8f 194 2 5 8f 199 3 5 8f 19e 4 5 8f 1a3 5 5 8f 1a8 6 5 8f 1ad 7 5 8f 1b2 8 5 8f 167 9 5 8f 16c a 5 8f 171 b 5 8f 176 c 5 8f 17b d 5 8f 180 e 5 8f 185 f 5 8f 18a 0 6 8f 18f 1 6 8f 195 2 6 8f 19b 3 6 8f 1a1 4 6 8f 1a7 5 6 8f 1ad 6 6 8f 1b3 7 6 8f 1b9 8 6 8f 15f 9 6 8f 165 a 6 8f 16b b 6 8f 171 c 6 8f 177 d 6 8f 17d e 6 8f 183 f 6 8f 189 0 7 8f 18f 1 7 8f 196 2 7 8f 19d 3 7 8f 1a4 4 7 8f 1ab 5 7 8f 1b2 6 7 8f 1b9 7 7 8f 1c0 8 7 8f 157 9 7 8f 15e a 7 8f 165 b 7 8f 16c c 7 8f 173 d 7 8f 17a e 7 8f 181 f 7 8f 188 0 8 8f 18f 1 8 8f 187 2 8 8f 17f 3 8 8f 177 4 8 8f 16f 5 8 8f 167 6 8 8f 15f 7 8 8f 157 8 8 8f 1cf 9 8 8f 1c7 a 8 8f 1bf b 8 8f 1b7 c 8 8f 1af d 8 8f 1a7 e 8 8f 19f f 8 8f 197 0 9 8f 18f 1 9 8f 188 2 9 8f 181 3 9 8f 17a 4 9 8f 173 5 9 8f 16c 6 9 8f 165 7 9 8f 15e 8 9 8f 1c7 9 9 8f 1c0 a 9 8f 1b9 b 9 8f 1b2 c 9 8f 1ab d 9 8f 1a4 e 9 8f 19d f 9 8f 196 0 a 8f 18f 1 a 8f 189 2 a 8f 183 3 a 8f 17d 4 a 8f 177 5 a 8f 171 6 a 8f 16b 7 a 8f 165 8 a 8f 1bf 9 a 8f 1b9 a a 8f 1b3 b a 8f 1ad c a 8f 1a7 d a 8f 1a1 e a 8f 19b f a 8f 195 0 b 8f 18f 1 b 8f 18a 2 b 8f 185 3 b 8f 180 4 b 8f 17b 5 b 8f 176 6 b 8f 171 7 b 8f 16c 8 b 8f 1b7 9 b 8f 1b2 a b 8f 1ad b b 8f 1a8 c b 8f 1a3 d b 8f 19e e b 8f 199 f b 8f 194 0 c 8f 18f 1 c 8f 18b 2 c 8f 187 3 c 8f 183 4 c 8f 17f 5 c 8f 17b 6 c 8f 177 7 c 8f 173 8 c 8f 1af 9 c 8f 1ab a c 8f 1a7 b c 8f 1a3 c c 8f 19f d c 8f 19b e c 8f 197 f c 8f 193 0 d 8f 18f 1 d 8f 18c 2 d 8f 189 3 d 8f 186 4 d 8f 183 5 d 8f 180 6 d 8f 17d 7 d 8f 17a 8 d 8f 1a7 9 d 8f 1a4 a d 8f 1a1 b d 8f 19e c d 8f 19b d d 8f 198 e d 8f 195 f d 8f 192 0 e 8f 18f 1 e 8f 18d 2 e 8f 18b 3 e 8f 189 4 e 8f 187 5 e 8f 185 6 e 8f 183 7 e 8f 181 8 e 8f 19f 9 e 8f 19d a e 8f 19b b e 8f 199 c e 8f 197 d e 8f 195 e e 8f 193 f e 8f 191 0 f 8f 18f 1 f 8f 18e 2 f 8f 18d 3 f 8f 18c 4 f 8f 18b 5 f 8f 18a 6 f 8f 189 7 f 8f 188 8 f 8f 197 9 f 8f 196 a f 8f 195 b f 8f 194 c f 8f 193 d f 8f 192 e f 8f 191 f f 8f 190 0 0 90 190 1 0 90 190 2 0 90 190 3 0 90 190 4 0 90 190 5 0 90 190 6 0 90 190 7 0 90 190 8 0 90 190 9 0 90 190 a 0 90 190 b 0 90 190 c 0 90 190 d 0 90 190 e 0 90 190 f 0 90 190 0 1 90 190 1 1 90 191 2 1 90 192 3 1 90 193 4 1 90 194 5 1 90 195 6 1 90 196 7 1 90 197 8 1 90 188 9 1 90 189 a 1 90 18a b 1 90 18b c 1 90 18c d 1 90 18d e 1 90 18e f 1 90 18f 0 2 90 190 1 2 90 192 2 2 90 194 3 2 90 196 4 2 90 198 5 2 90 19a 6 2 90 19c 7 2 90 19e 8 2 90 180 9 2 90 182 a 2 90 184 b 2 90 186 c 2 90 188 d 2 90 18a e 2 90 18c f 2 90 18e 0 3 90 190 1 3 90 193 2 3 90 196 3 3 90 199 4 3 90 19c 5 3 90 19f 6 3 90 1a2 7 3 90 1a5 8 3 90 178 9 3 90 17b a 3 90 17e b 3 90 181 c 3 90 184 d 3 90 187 e 3 90 18a f 3 90 18d 0 4 90 190 1 4 90 194 2 4 90 198 3 4 90 19c 4 4 90 1a0 5 4 90 1a4 6 4 90 1a8 7 4 90 1ac 8 4 90 170 9 4 90 174 a 4 90 178 b 4 90 17c c 4 90 180 d 4 90 184 e 4 90 188 f 4 90 18c 0 5 90 190 1 5 90 195 2 5 90 19a 3 5 90 19f 4 5 90 1a4 5 5 90 1a9 6 5 90 1ae 7 5 90 1b3 8 5 90 168 9 5 90 16d a 5 90 172 b 5 90 177 c 5 90 17c d 5 90 181 e 5 90 186 f 5 90 18b 0 6 90 190 1 6 90 196 2 6 90 19c 3 6 90 1a2 4 6 90 1a8 5 6 90 1ae 6 6 90 1b4 7 6 90 1ba 8 6 90 160 9 6 90 166 a 6 90 16c b 6 90 172 c 6 90 178 d 6 90 17e e 6 90 184 f 6 90 18a 0 7 90 190 1 7 90 197 2 7 90 19e 3 7 90 1a5 4 7 90 1ac 5 7 90 1b3 6 7 90 1ba 7 7 90 1c1 8 7 90 158 9 7 90 15f a 7 90 166 b 7 90 16d c 7 90 174 d 7 90 17b e 7 90 182 f 7 90 189 0 8 90 190 1 8 90 188 2 8 90 180 3 8 90 178 4 8 90 170 5 8 90 168 6 8 90 160 7 8 90 158 8 8 90 1d0 9 8 90 1c8 a 8 90 1c0 b 8 90 1b8 c 8 90 1b0 d 8 90 1a8 e 8 90 1a0 f 8 90 198 0 9 90 190 1 9 90 189 2 9 90 182 3 9 90 17b 4 9 90 174 5 9 90 16d 6 9 90 166 7 9 90 15f 8 9 90 1c8 9 9 90 1c1 a 9 90 1ba b 9 90 1b3 c 9 90 1ac d 9 90 1a5 e 9 90 19e f 9 90 197 0 a 90 190 1 a 90 18a 2 a 90 184 3 a 90 17e 4 a 90 178 5 a 90 172 6 a 90 16c 7 a 90 166 8 a 90 1c0 9 a 90 1ba a a 90 1b4 b a 90 1ae c a 90 1a8 d a 90 1a2 e a 90 19c f a 90 196 0 b 90 190 1 b 90 18b 2 b 90 186 3 b 90 181 4 b 90 17c 5 b 90 177 6 b 90 172 7 b 90 16d 8 b 90 1b8 9 b 90 1b3 a b 90 1ae b b 90 1a9 c b 90 1a4 d b 90 19f e b 90 19a f b 90 195 0 c 90 190 1 c 90 18c 2 c 90 188 3 c 90 184 4 c 90 180 5 c 90 17c 6 c 90 178 7 c 90 174 8 c 90 1b0 9 c 90 1ac a c 90 1a8 b c 90 1a4 c c 90 1a0 d c 90 19c e c 90 198 f c 90 194 0 d 90 190 1 d 90 18d 2 d 90 18a 3 d 90 187 4 d 90 184 5 d 90 181 6 d 90 17e 7 d 90 17b 8 d 90 1a8 9 d 90 1a5 a d 90 1a2 b d 90 19f c d 90 19c d d 90 199 e d 90 196 f d 90 193 0 e 90 190 1 e 90 18e 2 e 90 18c 3 e 90 18a 4 e 90 188 5 e 90 186 6 e 90 184 7 e 90 182 8 e 90 1a0 9 e 90 19e a e 90 19c b e 90 19a c e 90 198 d e 90 196 e e 90 194 f e 90 192 0 f 90 190 1 f 90 18f 2 f 90 18e 3 f 90 18d 4 f 90 18c 5 f 90 18b 6 f 90 18a 7 f 90 189 8 f 90 198 9 f 90 197 a f 90 196 b f 90 195 c f 90 194 d f 90 193 e f 90 192 f f 90 191 0 0 91 191 1 0 91 191 2 0 91 191 3 0 91 191 4 0 91 191 5 0 91 191 6 0 91 191 7 0 91 191 8 0 91 191 9 0 91 191 a 0 91 191 b 0 91 191 c 0 91 191 d 0 91 191 e 0 91 191 f 0 91 191 0 1 91 191 1 1 91 192 2 1 91 193 3 1 91 194 4 1 91 195 5 1 91 196 6 1 91 197 7 1 91 198 8 1 91 189 9 1 91 18a a 1 91 18b b 1 91 18c c 1 91 18d d 1 91 18e e 1 91 18f f 1 91 190 0 2 91 191 1 2 91 193 2 2 91 195 3 2 91 197 4 2 91 199 5 2 91 19b 6 2 91 19d 7 2 91 19f 8 2 91 181 9 2 91 183 a 2 91 185 b 2 91 187 c 2 91 189 d 2 91 18b e 2 91 18d f 2 91 18f 0 3 91 191 1 3 91 194 2 3 91 197 3 3 91 19a 4 3 91 19d 5 3 91 1a0 6 3 91 1a3 7 3 91 1a6 8 3 91 179 9 3 91 17c a 3 91 17f b 3 91 182 c 3 91 185 d 3 91 188 e 3 91 18b f 3 91 18e 0 4 91 191 1 4 91 195 2 4 91 199 3 4 91 19d 4 4 91 1a1 5 4 91 1a5 6 4 91 1a9 7 4 91 1ad 8 4 91 171 9 4 91 175 a 4 91 179 b 4 91 17d c 4 91 181 d 4 91 185 e 4 91 189 f 4 91 18d 0 5 91 191 1 5 91 196 2 5 91 19b 3 5 91 1a0 4 5 91 1a5 5 5 91 1aa 6 5 91 1af 7 5 91 1b4 8 5 91 169 9 5 91 16e a 5 91 173 b 5 91 178 c 5 91 17d d 5 91 182 e 5 91 187 f 5 91 18c 0 6 91 191 1 6 91 197 2 6 91 19d 3 6 91 1a3 4 6 91 1a9 5 6 91 1af 6 6 91 1b5 7 6 91 1bb 8 6 91 161 9 6 91 167 a 6 91 16d b 6 91 173 c 6 91 179 d 6 91 17f e 6 91 185 f 6 91 18b 0 7 91 191 1 7 91 198 2 7 91 19f 3 7 91 1a6 4 7 91 1ad 5 7 91 1b4 6 7 91 1bb 7 7 91 1c2 8 7 91 159 9 7 91 160 a 7 91 167 b 7 91 16e c 7 91 175 d 7 91 17c e 7 91 183 f 7 91 18a 0 8 91 191 1 8 91 189 2 8 91 181 3 8 91 179 4 8 91 171 5 8 91 169 6 8 91 161 7 8 91 159 8 8 91 1d1 9 8 91 1c9 a 8 91 1c1 b 8 91 1b9 c 8 91 1b1 d 8 91 1a9 e 8 91 1a1 f 8 91 199 0 9 91 191 1 9 91 18a 2 9 91 183 3 9 91 17c 4 9 91 175 5 9 91 16e 6 9 91 167 7 9 91 160 8 9 91 1c9 9 9 91 1c2 a 9 91 1bb b 9 91 1b4 c 9 91 1ad d 9 91 1a6 e 9 91 19f f 9 91 198 0 a 91 191 1 a 91 18b 2 a 91 185 3 a 91 17f 4 a 91 179 5 a 91 173 6 a 91 16d 7 a 91 167 8 a 91 1c1 9 a 91 1bb a a 91 1b5 b a 91 1af c a 91 1a9 d a 91 1a3 e a 91 19d f a 91 197 0 b 91 191 1 b 91 18c 2 b 91 187 3 b 91 182 4 b 91 17d 5 b 91 178 6 b 91 173 7 b 91 16e 8 b 91 1b9 9 b 91 1b4 a b 91 1af b b 91 1aa c b 91 1a5 d b 91 1a0 e b 91 19b f b 91 196 0 c 91 191 1 c 91 18d 2 c 91 189 3 c 91 185 4 c 91 181 5 c 91 17d 6 c 91 179 7 c 91 175 8 c 91 1b1 9 c 91 1ad a c 91 1a9 b c 91 1a5 c c 91 1a1 d c 91 19d e c 91 199 f c 91 195 0 d 91 191 1 d 91 18e 2 d 91 18b 3 d 91 188 4 d 91 185 5 d 91 182 6 d 91 17f 7 d 91 17c 8 d 91 1a9 9 d 91 1a6 a d 91 1a3 b d 91 1a0 c d 91 19d d d 91 19a e d 91 197 f d 91 194 0 e 91 191 1 e 91 18f 2 e 91 18d 3 e 91 18b 4 e 91 189 5 e 91 187 6 e 91 185 7 e 91 183 8 e 91 1a1 9 e 91 19f a e 91 19d b e 91 19b c e 91 199 d e 91 197 e e 91 195 f e 91 193 0 f 91 191 1 f 91 190 2 f 91 18f 3 f 91 18e 4 f 91 18d 5 f 91 18c 6 f 91 18b 7 f 91 18a 8 f 91 199 9 f 91 198 a f 91 197 b f 91 196 c f 91 195 d f 91 194 e f 91 193 f f 91 192 0 0 92 192 1 0 92 192 2 0 92 192 3 0 92 192 4 0 92 192 5 0 92 192 6 0 92 192 7 0 92 192 8 0 92 192 9 0 92 192 a 0 92 192 b 0 92 192 c 0 92 192 d 0 92 192 e 0 92 192 f 0 92 192 0 1 92 192 1 1 92 193 2 1 92 194 3 1 92 195 4 1 92 196 5 1 92 197 6 1 92 198 7 1 92 199 8 1 92 18a 9 1 92 18b a 1 92 18c b 1 92 18d c 1 92 18e d 1 92 18f e 1 92 190 f 1 92 191 0 2 92 192 1 2 92 194 2 2 92 196 3 2 92 198 4 2 92 19a 5 2 92 19c 6 2 92 19e 7 2 92 1a0 8 2 92 182 9 2 92 184 a 2 92 186 b 2 92 188 c 2 92 18a d 2 92 18c e 2 92 18e f 2 92 190 0 3 92 192 1 3 92 195 2 3 92 198 3 3 92 19b 4 3 92 19e 5 3 92 1a1 6 3 92 1a4 7 3 92 1a7 8 3 92 17a 9 3 92 17d a 3 92 180 b 3 92 183 c 3 92 186 d 3 92 189 e 3 92 18c f 3 92 18f 0 4 92 192 1 4 92 196 2 4 92 19a 3 4 92 19e 4 4 92 1a2 5 4 92 1a6 6 4 92 1aa 7 4 92 1ae 8 4 92 172 9 4 92 176 a 4 92 17a b 4 92 17e c 4 92 182 d 4 92 186 e 4 92 18a f 4 92 18e 0 5 92 192 1 5 92 197 2 5 92 19c 3 5 92 1a1 4 5 92 1a6 5 5 92 1ab 6 5 92 1b0 7 5 92 1b5 8 5 92 16a 9 5 92 16f a 5 92 174 b 5 92 179 c 5 92 17e d 5 92 183 e 5 92 188 f 5 92 18d 0 6 92 192 1 6 92 198 2 6 92 19e 3 6 92 1a4 4 6 92 1aa 5 6 92 1b0 6 6 92 1b6 7 6 92 1bc 8 6 92 162 9 6 92 168 a 6 92 16e b 6 92 174 c 6 92 17a d 6 92 180 e 6 92 186 f 6 92 18c 0 7 92 192 1 7 92 199 2 7 92 1a0 3 7 92 1a7 4 7 92 1ae 5 7 92 1b5 6 7 92 1bc 7 7 92 1c3 8 7 92 15a 9 7 92 161 a 7 92 168 b 7 92 16f c 7 92 176 d 7 92 17d e 7 92 184 f 7 92 18b 0 8 92 192 1 8 92 18a 2 8 92 182 3 8 92 17a 4 8 92 172 5 8 92 16a 6 8 92 162 7 8 92 15a 8 8 92 1d2 9 8 92 1ca a 8 92 1c2 b 8 92 1ba c 8 92 1b2 d 8 92 1aa e 8 92 1a2 f 8 92 19a 0 9 92 192 1 9 92 18b 2 9 92 184 3 9 92 17d 4 9 92 176 5 9 92 16f 6 9 92 168 7 9 92 161 8 9 92 1ca 9 9 92 1c3 a 9 92 1bc b 9 92 1b5 c 9 92 1ae d 9 92 1a7 e 9 92 1a0 f 9 92 199 0 a 92 192 1 a 92 18c 2 a 92 186 3 a 92 180 4 a 92 17a 5 a 92 174 6 a 92 16e 7 a 92 168 8 a 92 1c2 9 a 92 1bc a a 92 1b6 b a 92 1b0 c a 92 1aa d a 92 1a4 e a 92 19e f a 92 198 0 b 92 192 1 b 92 18d 2 b 92 188 3 b 92 183 4 b 92 17e 5 b 92 179 6 b 92 174 7 b 92 16f 8 b 92 1ba 9 b 92 1b5 a b 92 1b0 b b 92 1ab c b 92 1a6 d b 92 1a1 e b 92 19c f b 92 197 0 c 92 192 1 c 92 18e 2 c 92 18a 3 c 92 186 4 c 92 182 5 c 92 17e 6 c 92 17a 7 c 92 176 8 c 92 1b2 9 c 92 1ae a c 92 1aa b c 92 1a6 c c 92 1a2 d c 92 19e e c 92 19a f c 92 196 0 d 92 192 1 d 92 18f 2 d 92 18c 3 d 92 189 4 d 92 186 5 d 92 183 6 d 92 180 7 d 92 17d 8 d 92 1aa 9 d 92 1a7 a d 92 1a4 b d 92 1a1 c d 92 19e d d 92 19b e d 92 198 f d 92 195 0 e 92 192 1 e 92 190 2 e 92 18e 3 e 92 18c 4 e 92 18a 5 e 92 188 6 e 92 186 7 e 92 184 8 e 92 1a2 9 e 92 1a0 a e 92 19e b e 92 19c c e 92 19a d e 92 198 e e 92 196 f e 92 194 0 f 92 192 1 f 92 191 2 f 92 190 3 f 92 18f 4 f 92 18e 5 f 92 18d 6 f 92 18c 7 f 92 18b 8 f 92 19a 9 f 92 199 a f 92 198 b f 92 197 c f 92 196 d f 92 195 e f 92 194 f f 92 193 0 0 93 193 1 0 93 193 2 0 93 193 3 0 93 193 4 0 93 193 5 0 93 193 6 0 93 193 7 0 93 193 8 0 93 193 9 0 93 193 a 0 93 193 b 0 93 193 c 0 93 193 d 0 93 193 e 0 93 193 f 0 93 193 0 1 93 193 1 1 93 194 2 1 93 195 3 1 93 196 4 1 93 197 5 1 93 198 6 1 93 199 7 1 93 19a 8 1 93 18b 9 1 93 18c a 1 93 18d b 1 93 18e c 1 93 18f d 1 93 190 e 1 93 191 f 1 93 192 0 2 93 193 1 2 93 195 2 2 93 197 3 2 93 199 4 2 93 19b 5 2 93 19d 6 2 93 19f 7 2 93 1a1 8 2 93 183 9 2 93 185 a 2 93 187 b 2 93 189 c 2 93 18b d 2 93 18d e 2 93 18f f 2 93 191 0 3 93 193 1 3 93 196 2 3 93 199 3 3 93 19c 4 3 93 19f 5 3 93 1a2 6 3 93 1a5 7 3 93 1a8 8 3 93 17b 9 3 93 17e a 3 93 181 b 3 93 184 c 3 93 187 d 3 93 18a e 3 93 18d f 3 93 190 0 4 93 193 1 4 93 197 2 4 93 19b 3 4 93 19f 4 4 93 1a3 5 4 93 1a7 6 4 93 1ab 7 4 93 1af 8 4 93 173 9 4 93 177 a 4 93 17b b 4 93 17f c 4 93 183 d 4 93 187 e 4 93 18b f 4 93 18f 0 5 93 193 1 5 93 198 2 5 93 19d 3 5 93 1a2 4 5 93 1a7 5 5 93 1ac 6 5 93 1b1 7 5 93 1b6 8 5 93 16b 9 5 93 170 a 5 93 175 b 5 93 17a c 5 93 17f d 5 93 184 e 5 93 189 f 5 93 18e 0 6 93 193 1 6 93 199 2 6 93 19f 3 6 93 1a5 4 6 93 1ab 5 6 93 1b1 6 6 93 1b7 7 6 93 1bd 8 6 93 163 9 6 93 169 a 6 93 16f b 6 93 175 c 6 93 17b d 6 93 181 e 6 93 187 f 6 93 18d 0 7 93 193 1 7 93 19a 2 7 93 1a1 3 7 93 1a8 4 7 93 1af 5 7 93 1b6 6 7 93 1bd 7 7 93 1c4 8 7 93 15b 9 7 93 162 a 7 93 169 b 7 93 170 c 7 93 177 d 7 93 17e e 7 93 185 f 7 93 18c 0 8 93 193 1 8 93 18b 2 8 93 183 3 8 93 17b 4 8 93 173 5 8 93 16b 6 8 93 163 7 8 93 15b 8 8 93 1d3 9 8 93 1cb a 8 93 1c3 b 8 93 1bb c 8 93 1b3 d 8 93 1ab e 8 93 1a3 f 8 93 19b 0 9 93 193 1 9 93 18c 2 9 93 185 3 9 93 17e 4 9 93 177 5 9 93 170 6 9 93 169 7 9 93 162 8 9 93 1cb 9 9 93 1c4 a 9 93 1bd b 9 93 1b6 c 9 93 1af d 9 93 1a8 e 9 93 1a1 f 9 93 19a 0 a 93 193 1 a 93 18d 2 a 93 187 3 a 93 181 4 a 93 17b 5 a 93 175 6 a 93 16f 7 a 93 169 8 a 93 1c3 9 a 93 1bd a a 93 1b7 b a 93 1b1 c a 93 1ab d a 93 1a5 e a 93 19f f a 93 199 0 b 93 193 1 b 93 18e 2 b 93 189 3 b 93 184 4 b 93 17f 5 b 93 17a 6 b 93 175 7 b 93 170 8 b 93 1bb 9 b 93 1b6 a b 93 1b1 b b 93 1ac c b 93 1a7 d b 93 1a2 e b 93 19d f b 93 198 0 c 93 193 1 c 93 18f 2 c 93 18b 3 c 93 187 4 c 93 183 5 c 93 17f 6 c 93 17b 7 c 93 177 8 c 93 1b3 9 c 93 1af a c 93 1ab b c 93 1a7 c c 93 1a3 d c 93 19f e c 93 19b f c 93 197 0 d 93 193 1 d 93 190 2 d 93 18d 3 d 93 18a 4 d 93 187 5 d 93 184 6 d 93 181 7 d 93 17e 8 d 93 1ab 9 d 93 1a8 a d 93 1a5 b d 93 1a2 c d 93 19f d d 93 19c e d 93 199 f d 93 196 0 e 93 193 1 e 93 191 2 e 93 18f 3 e 93 18d 4 e 93 18b 5 e 93 189 6 e 93 187 7 e 93 185 8 e 93 1a3 9 e 93 1a1 a e 93 19f b e 93 19d c e 93 19b d e 93 199 e e 93 197 f e 93 195 0 f 93 193 1 f 93 192 2 f 93 191 3 f 93 190 4 f 93 18f 5 f 93 18e 6 f 93 18d 7 f 93 18c 8 f 93 19b 9 f 93 19a a f 93 199 b f 93 198 c f 93 197 d f 93 196 e f 93 195 f f 93 194 0 0 94 194 1 0 94 194 2 0 94 194 3 0 94 194 4 0 94 194 5 0 94 194 6 0 94 194 7 0 94 194 8 0 94 194 9 0 94 194 a 0 94 194 b 0 94 194 c 0 94 194 d 0 94 194 e 0 94 194 f 0 94 194 0 1 94 194 1 1 94 195 2 1 94 196 3 1 94 197 4 1 94 198 5 1 94 199 6 1 94 19a 7 1 94 19b 8 1 94 18c 9 1 94 18d a 1 94 18e b 1 94 18f c 1 94 190 d 1 94 191 e 1 94 192 f 1 94 193 0 2 94 194 1 2 94 196 2 2 94 198 3 2 94 19a 4 2 94 19c 5 2 94 19e 6 2 94 1a0 7 2 94 1a2 8 2 94 184 9 2 94 186 a 2 94 188 b 2 94 18a c 2 94 18c d 2 94 18e e 2 94 190 f 2 94 192 0 3 94 194 1 3 94 197 2 3 94 19a 3 3 94 19d 4 3 94 1a0 5 3 94 1a3 6 3 94 1a6 7 3 94 1a9 8 3 94 17c 9 3 94 17f a 3 94 182 b 3 94 185 c 3 94 188 d 3 94 18b e 3 94 18e f 3 94 191 0 4 94 194 1 4 94 198 2 4 94 19c 3 4 94 1a0 4 4 94 1a4 5 4 94 1a8 6 4 94 1ac 7 4 94 1b0 8 4 94 174 9 4 94 178 a 4 94 17c b 4 94 180 c 4 94 184 d 4 94 188 e 4 94 18c f 4 94 190 0 5 94 194 1 5 94 199 2 5 94 19e 3 5 94 1a3 4 5 94 1a8 5 5 94 1ad 6 5 94 1b2 7 5 94 1b7 8 5 94 16c 9 5 94 171 a 5 94 176 b 5 94 17b c 5 94 180 d 5 94 185 e 5 94 18a f 5 94 18f 0 6 94 194 1 6 94 19a 2 6 94 1a0 3 6 94 1a6 4 6 94 1ac 5 6 94 1b2 6 6 94 1b8 7 6 94 1be 8 6 94 164 9 6 94 16a a 6 94 170 b 6 94 176 c 6 94 17c d 6 94 182 e 6 94 188 f 6 94 18e 0 7 94 194 1 7 94 19b 2 7 94 1a2 3 7 94 1a9 4 7 94 1b0 5 7 94 1b7 6 7 94 1be 7 7 94 1c5 8 7 94 15c 9 7 94 163 a 7 94 16a b 7 94 171 c 7 94 178 d 7 94 17f e 7 94 186 f 7 94 18d 0 8 94 194 1 8 94 18c 2 8 94 184 3 8 94 17c 4 8 94 174 5 8 94 16c 6 8 94 164 7 8 94 15c 8 8 94 1d4 9 8 94 1cc a 8 94 1c4 b 8 94 1bc c 8 94 1b4 d 8 94 1ac e 8 94 1a4 f 8 94 19c 0 9 94 194 1 9 94 18d 2 9 94 186 3 9 94 17f 4 9 94 178 5 9 94 171 6 9 94 16a 7 9 94 163 8 9 94 1cc 9 9 94 1c5 a 9 94 1be b 9 94 1b7 c 9 94 1b0 d 9 94 1a9 e 9 94 1a2 f 9 94 19b 0 a 94 194 1 a 94 18e 2 a 94 188 3 a 94 182 4 a 94 17c 5 a 94 176 6 a 94 170 7 a 94 16a 8 a 94 1c4 9 a 94 1be a a 94 1b8 b a 94 1b2 c a 94 1ac d a 94 1a6 e a 94 1a0 f a 94 19a 0 b 94 194 1 b 94 18f 2 b 94 18a 3 b 94 185 4 b 94 180 5 b 94 17b 6 b 94 176 7 b 94 171 8 b 94 1bc 9 b 94 1b7 a b 94 1b2 b b 94 1ad c b 94 1a8 d b 94 1a3 e b 94 19e f b 94 199 0 c 94 194 1 c 94 190 2 c 94 18c 3 c 94 188 4 c 94 184 5 c 94 180 6 c 94 17c 7 c 94 178 8 c 94 1b4 9 c 94 1b0 a c 94 1ac b c 94 1a8 c c 94 1a4 d c 94 1a0 e c 94 19c f c 94 198 0 d 94 194 1 d 94 191 2 d 94 18e 3 d 94 18b 4 d 94 188 5 d 94 185 6 d 94 182 7 d 94 17f 8 d 94 1ac 9 d 94 1a9 a d 94 1a6 b d 94 1a3 c d 94 1a0 d d 94 19d e d 94 19a f d 94 197 0 e 94 194 1 e 94 192 2 e 94 190 3 e 94 18e 4 e 94 18c 5 e 94 18a 6 e 94 188 7 e 94 186 8 e 94 1a4 9 e 94 1a2 a e 94 1a0 b e 94 19e c e 94 19c d e 94 19a e e 94 198 f e 94 196 0 f 94 194 1 f 94 193 2 f 94 192 3 f 94 191 4 f 94 190 5 f 94 18f 6 f 94 18e 7 f 94 18d 8 f 94 19c 9 f 94 19b a f 94 19a b f 94 199 c f 94 198 d f 94 197 e f 94 196 f f 94 195 0 0 95 195 1 0 95 195 2 0 95 195 3 0 95 195 4 0 95 195 5 0 95 195 6 0 95 195 7 0 95 195 8 0 95 195 9 0 95 195 a 0 95 195 b 0 95 195 c 0 95 195 d 0 95 195 e 0 95 195 f 0 95 195 0 1 95 195 1 1 95 196 2 1 95 197 3 1 95 198 4 1 95 199 5 1 95 19a 6 1 95 19b 7 1 95 19c 8 1 95 18d 9 1 95 18e a 1 95 18f b 1 95 190 c 1 95 191 d 1 95 192 e 1 95 193 f 1 95 194 0 2 95 195 1 2 95 197 2 2 95 199 3 2 95 19b 4 2 95 19d 5 2 95 19f 6 2 95 1a1 7 2 95 1a3 8 2 95 185 9 2 95 187 a 2 95 189 b 2 95 18b c 2 95 18d d 2 95 18f e 2 95 191 f 2 95 193 0 3 95 195 1 3 95 198 2 3 95 19b 3 3 95 19e 4 3 95 1a1 5 3 95 1a4 6 3 95 1a7 7 3 95 1aa 8 3 95 17d 9 3 95 180 a 3 95 183 b 3 95 186 c 3 95 189 d 3 95 18c e 3 95 18f f 3 95 192 0 4 95 195 1 4 95 199 2 4 95 19d 3 4 95 1a1 4 4 95 1a5 5 4 95 1a9 6 4 95 1ad 7 4 95 1b1 8 4 95 175 9 4 95 179 a 4 95 17d b 4 95 181 c 4 95 185 d 4 95 189 e 4 95 18d f 4 95 191 0 5 95 195 1 5 95 19a 2 5 95 19f 3 5 95 1a4 4 5 95 1a9 5 5 95 1ae 6 5 95 1b3 7 5 95 1b8 8 5 95 16d 9 5 95 172 a 5 95 177 b 5 95 17c c 5 95 181 d 5 95 186 e 5 95 18b f 5 95 190 0 6 95 195 1 6 95 19b 2 6 95 1a1 3 6 95 1a7 4 6 95 1ad 5 6 95 1b3 6 6 95 1b9 7 6 95 1bf 8 6 95 165 9 6 95 16b a 6 95 171 b 6 95 177 c 6 95 17d d 6 95 183 e 6 95 189 f 6 95 18f 0 7 95 195 1 7 95 19c 2 7 95 1a3 3 7 95 1aa 4 7 95 1b1 5 7 95 1b8 6 7 95 1bf 7 7 95 1c6 8 7 95 15d 9 7 95 164 a 7 95 16b b 7 95 172 c 7 95 179 d 7 95 180 e 7 95 187 f 7 95 18e 0 8 95 195 1 8 95 18d 2 8 95 185 3 8 95 17d 4 8 95 175 5 8 95 16d 6 8 95 165 7 8 95 15d 8 8 95 1d5 9 8 95 1cd a 8 95 1c5 b 8 95 1bd c 8 95 1b5 d 8 95 1ad e 8 95 1a5 f 8 95 19d 0 9 95 195 1 9 95 18e 2 9 95 187 3 9 95 180 4 9 95 179 5 9 95 172 6 9 95 16b 7 9 95 164 8 9 95 1cd 9 9 95 1c6 a 9 95 1bf b 9 95 1b8 c 9 95 1b1 d 9 95 1aa e 9 95 1a3 f 9 95 19c 0 a 95 195 1 a 95 18f 2 a 95 189 3 a 95 183 4 a 95 17d 5 a 95 177 6 a 95 171 7 a 95 16b 8 a 95 1c5 9 a 95 1bf a a 95 1b9 b a 95 1b3 c a 95 1ad d a 95 1a7 e a 95 1a1 f a 95 19b 0 b 95 195 1 b 95 190 2 b 95 18b 3 b 95 186 4 b 95 181 5 b 95 17c 6 b 95 177 7 b 95 172 8 b 95 1bd 9 b 95 1b8 a b 95 1b3 b b 95 1ae c b 95 1a9 d b 95 1a4 e b 95 19f f b 95 19a 0 c 95 195 1 c 95 191 2 c 95 18d 3 c 95 189 4 c 95 185 5 c 95 181 6 c 95 17d 7 c 95 179 8 c 95 1b5 9 c 95 1b1 a c 95 1ad b c 95 1a9 c c 95 1a5 d c 95 1a1 e c 95 19d f c 95 199 0 d 95 195 1 d 95 192 2 d 95 18f 3 d 95 18c 4 d 95 189 5 d 95 186 6 d 95 183 7 d 95 180 8 d 95 1ad 9 d 95 1aa a d 95 1a7 b d 95 1a4 c d 95 1a1 d d 95 19e e d 95 19b f d 95 198 0 e 95 195 1 e 95 193 2 e 95 191 3 e 95 18f 4 e 95 18d 5 e 95 18b 6 e 95 189 7 e 95 187 8 e 95 1a5 9 e 95 1a3 a e 95 1a1 b e 95 19f c e 95 19d d e 95 19b e e 95 199 f e 95 197 0 f 95 195 1 f 95 194 2 f 95 193 3 f 95 192 4 f 95 191 5 f 95 190 6 f 95 18f 7 f 95 18e 8 f 95 19d 9 f 95 19c a f 95 19b b f 95 19a c f 95 199 d f 95 198 e f 95 197 f f 95 196 0 0 96 196 1 0 96 196 2 0 96 196 3 0 96 196 4 0 96 196 5 0 96 196 6 0 96 196 7 0 96 196 8 0 96 196 9 0 96 196 a 0 96 196 b 0 96 196 c 0 96 196 d 0 96 196 e 0 96 196 f 0 96 196 0 1 96 196 1 1 96 197 2 1 96 198 3 1 96 199 4 1 96 19a 5 1 96 19b 6 1 96 19c 7 1 96 19d 8 1 96 18e 9 1 96 18f a 1 96 190 b 1 96 191 c 1 96 192 d 1 96 193 e 1 96 194 f 1 96 195 0 2 96 196 1 2 96 198 2 2 96 19a 3 2 96 19c 4 2 96 19e 5 2 96 1a0 6 2 96 1a2 7 2 96 1a4 8 2 96 186 9 2 96 188 a 2 96 18a b 2 96 18c c 2 96 18e d 2 96 190 e 2 96 192 f 2 96 194 0 3 96 196 1 3 96 199 2 3 96 19c 3 3 96 19f 4 3 96 1a2 5 3 96 1a5 6 3 96 1a8 7 3 96 1ab 8 3 96 17e 9 3 96 181 a 3 96 184 b 3 96 187 c 3 96 18a d 3 96 18d e 3 96 190 f 3 96 193 0 4 96 196 1 4 96 19a 2 4 96 19e 3 4 96 1a2 4 4 96 1a6 5 4 96 1aa 6 4 96 1ae 7 4 96 1b2 8 4 96 176 9 4 96 17a a 4 96 17e b 4 96 182 c 4 96 186 d 4 96 18a e 4 96 18e f 4 96 192 0 5 96 196 1 5 96 19b 2 5 96 1a0 3 5 96 1a5 4 5 96 1aa 5 5 96 1af 6 5 96 1b4 7 5 96 1b9 8 5 96 16e 9 5 96 173 a 5 96 178 b 5 96 17d c 5 96 182 d 5 96 187 e 5 96 18c f 5 96 191 0 6 96 196 1 6 96 19c 2 6 96 1a2 3 6 96 1a8 4 6 96 1ae 5 6 96 1b4 6 6 96 1ba 7 6 96 1c0 8 6 96 166 9 6 96 16c a 6 96 172 b 6 96 178 c 6 96 17e d 6 96 184 e 6 96 18a f 6 96 190 0 7 96 196 1 7 96 19d 2 7 96 1a4 3 7 96 1ab 4 7 96 1b2 5 7 96 1b9 6 7 96 1c0 7 7 96 1c7 8 7 96 15e 9 7 96 165 a 7 96 16c b 7 96 173 c 7 96 17a d 7 96 181 e 7 96 188 f 7 96 18f 0 8 96 196 1 8 96 18e 2 8 96 186 3 8 96 17e 4 8 96 176 5 8 96 16e 6 8 96 166 7 8 96 15e 8 8 96 1d6 9 8 96 1ce a 8 96 1c6 b 8 96 1be c 8 96 1b6 d 8 96 1ae e 8 96 1a6 f 8 96 19e 0 9 96 196 1 9 96 18f 2 9 96 188 3 9 96 181 4 9 96 17a 5 9 96 173 6 9 96 16c 7 9 96 165 8 9 96 1ce 9 9 96 1c7 a 9 96 1c0 b 9 96 1b9 c 9 96 1b2 d 9 96 1ab e 9 96 1a4 f 9 96 19d 0 a 96 196 1 a 96 190 2 a 96 18a 3 a 96 184 4 a 96 17e 5 a 96 178 6 a 96 172 7 a 96 16c 8 a 96 1c6 9 a 96 1c0 a a 96 1ba b a 96 1b4 c a 96 1ae d a 96 1a8 e a 96 1a2 f a 96 19c 0 b 96 196 1 b 96 191 2 b 96 18c 3 b 96 187 4 b 96 182 5 b 96 17d 6 b 96 178 7 b 96 173 8 b 96 1be 9 b 96 1b9 a b 96 1b4 b b 96 1af c b 96 1aa d b 96 1a5 e b 96 1a0 f b 96 19b 0 c 96 196 1 c 96 192 2 c 96 18e 3 c 96 18a 4 c 96 186 5 c 96 182 6 c 96 17e 7 c 96 17a 8 c 96 1b6 9 c 96 1b2 a c 96 1ae b c 96 1aa c c 96 1a6 d c 96 1a2 e c 96 19e f c 96 19a 0 d 96 196 1 d 96 193 2 d 96 190 3 d 96 18d 4 d 96 18a 5 d 96 187 6 d 96 184 7 d 96 181 8 d 96 1ae 9 d 96 1ab a d 96 1a8 b d 96 1a5 c d 96 1a2 d d 96 19f e d 96 19c f d 96 199 0 e 96 196 1 e 96 194 2 e 96 192 3 e 96 190 4 e 96 18e 5 e 96 18c 6 e 96 18a 7 e 96 188 8 e 96 1a6 9 e 96 1a4 a e 96 1a2 b e 96 1a0 c e 96 19e d e 96 19c e e 96 19a f e 96 198 0 f 96 196 1 f 96 195 2 f 96 194 3 f 96 193 4 f 96 192 5 f 96 191 6 f 96 190 7 f 96 18f 8 f 96 19e 9 f 96 19d a f 96 19c b f 96 19b c f 96 19a d f 96 199 e f 96 198 f f 96 197 0 0 97 197 1 0 97 197 2 0 97 197 3 0 97 197 4 0 97 197 5 0 97 197 6 0 97 197 7 0 97 197 8 0 97 197 9 0 97 197 a 0 97 197 b 0 97 197 c 0 97 197 d 0 97 197 e 0 97 197 f 0 97 197 0 1 97 197 1 1 97 198 2 1 97 199 3 1 97 19a 4 1 97 19b 5 1 97 19c 6 1 97 19d 7 1 97 19e 8 1 97 18f 9 1 97 190 a 1 97 191 b 1 97 192 c 1 97 193 d 1 97 194 e 1 97 195 f 1 97 196 0 2 97 197 1 2 97 199 2 2 97 19b 3 2 97 19d 4 2 97 19f 5 2 97 1a1 6 2 97 1a3 7 2 97 1a5 8 2 97 187 9 2 97 189 a 2 97 18b b 2 97 18d c 2 97 18f d 2 97 191 e 2 97 193 f 2 97 195 0 3 97 197 1 3 97 19a 2 3 97 19d 3 3 97 1a0 4 3 97 1a3 5 3 97 1a6 6 3 97 1a9 7 3 97 1ac 8 3 97 17f 9 3 97 182 a 3 97 185 b 3 97 188 c 3 97 18b d 3 97 18e e 3 97 191 f 3 97 194 0 4 97 197 1 4 97 19b 2 4 97 19f 3 4 97 1a3 4 4 97 1a7 5 4 97 1ab 6 4 97 1af 7 4 97 1b3 8 4 97 177 9 4 97 17b a 4 97 17f b 4 97 183 c 4 97 187 d 4 97 18b e 4 97 18f f 4 97 193 0 5 97 197 1 5 97 19c 2 5 97 1a1 3 5 97 1a6 4 5 97 1ab 5 5 97 1b0 6 5 97 1b5 7 5 97 1ba 8 5 97 16f 9 5 97 174 a 5 97 179 b 5 97 17e c 5 97 183 d 5 97 188 e 5 97 18d f 5 97 192 0 6 97 197 1 6 97 19d 2 6 97 1a3 3 6 97 1a9 4 6 97 1af 5 6 97 1b5 6 6 97 1bb 7 6 97 1c1 8 6 97 167 9 6 97 16d a 6 97 173 b 6 97 179 c 6 97 17f d 6 97 185 e 6 97 18b f 6 97 191 0 7 97 197 1 7 97 19e 2 7 97 1a5 3 7 97 1ac 4 7 97 1b3 5 7 97 1ba 6 7 97 1c1 7 7 97 1c8 8 7 97 15f 9 7 97 166 a 7 97 16d b 7 97 174 c 7 97 17b d 7 97 182 e 7 97 189 f 7 97 190 0 8 97 197 1 8 97 18f 2 8 97 187 3 8 97 17f 4 8 97 177 5 8 97 16f 6 8 97 167 7 8 97 15f 8 8 97 1d7 9 8 97 1cf a 8 97 1c7 b 8 97 1bf c 8 97 1b7 d 8 97 1af e 8 97 1a7 f 8 97 19f 0 9 97 197 1 9 97 190 2 9 97 189 3 9 97 182 4 9 97 17b 5 9 97 174 6 9 97 16d 7 9 97 166 8 9 97 1cf 9 9 97 1c8 a 9 97 1c1 b 9 97 1ba c 9 97 1b3 d 9 97 1ac e 9 97 1a5 f 9 97 19e 0 a 97 197 1 a 97 191 2 a 97 18b 3 a 97 185 4 a 97 17f 5 a 97 179 6 a 97 173 7 a 97 16d 8 a 97 1c7 9 a 97 1c1 a a 97 1bb b a 97 1b5 c a 97 1af d a 97 1a9 e a 97 1a3 f a 97 19d 0 b 97 197 1 b 97 192 2 b 97 18d 3 b 97 188 4 b 97 183 5 b 97 17e 6 b 97 179 7 b 97 174 8 b 97 1bf 9 b 97 1ba a b 97 1b5 b b 97 1b0 c b 97 1ab d b 97 1a6 e b 97 1a1 f b 97 19c 0 c 97 197 1 c 97 193 2 c 97 18f 3 c 97 18b 4 c 97 187 5 c 97 183 6 c 97 17f 7 c 97 17b 8 c 97 1b7 9 c 97 1b3 a c 97 1af b c 97 1ab c c 97 1a7 d c 97 1a3 e c 97 19f f c 97 19b 0 d 97 197 1 d 97 194 2 d 97 191 3 d 97 18e 4 d 97 18b 5 d 97 188 6 d 97 185 7 d 97 182 8 d 97 1af 9 d 97 1ac a d 97 1a9 b d 97 1a6 c d 97 1a3 d d 97 1a0 e d 97 19d f d 97 19a 0 e 97 197 1 e 97 195 2 e 97 193 3 e 97 191 4 e 97 18f 5 e 97 18d 6 e 97 18b 7 e 97 189 8 e 97 1a7 9 e 97 1a5 a e 97 1a3 b e 97 1a1 c e 97 19f d e 97 19d e e 97 19b f e 97 199 0 f 97 197 1 f 97 196 2 f 97 195 3 f 97 194 4 f 97 193 5 f 97 192 6 f 97 191 7 f 97 190 8 f 97 19f 9 f 97 19e a f 97 19d b f 97 19c c f 97 19b d f 97 19a e f 97 199 f f 97 198 0 0 98 198 1 0 98 198 2 0 98 198 3 0 98 198 4 0 98 198 5 0 98 198 6 0 98 198 7 0 98 198 8 0 98 198 9 0 98 198 a 0 98 198 b 0 98 198 c 0 98 198 d 0 98 198 e 0 98 198 f 0 98 198 0 1 98 198 1 1 98 199 2 1 98 19a 3 1 98 19b 4 1 98 19c 5 1 98 19d 6 1 98 19e 7 1 98 19f 8 1 98 190 9 1 98 191 a 1 98 192 b 1 98 193 c 1 98 194 d 1 98 195 e 1 98 196 f 1 98 197 0 2 98 198 1 2 98 19a 2 2 98 19c 3 2 98 19e 4 2 98 1a0 5 2 98 1a2 6 2 98 1a4 7 2 98 1a6 8 2 98 188 9 2 98 18a a 2 98 18c b 2 98 18e c 2 98 190 d 2 98 192 e 2 98 194 f 2 98 196 0 3 98 198 1 3 98 19b 2 3 98 19e 3 3 98 1a1 4 3 98 1a4 5 3 98 1a7 6 3 98 1aa 7 3 98 1ad 8 3 98 180 9 3 98 183 a 3 98 186 b 3 98 189 c 3 98 18c d 3 98 18f e 3 98 192 f 3 98 195 0 4 98 198 1 4 98 19c 2 4 98 1a0 3 4 98 1a4 4 4 98 1a8 5 4 98 1ac 6 4 98 1b0 7 4 98 1b4 8 4 98 178 9 4 98 17c a 4 98 180 b 4 98 184 c 4 98 188 d 4 98 18c e 4 98 190 f 4 98 194 0 5 98 198 1 5 98 19d 2 5 98 1a2 3 5 98 1a7 4 5 98 1ac 5 5 98 1b1 6 5 98 1b6 7 5 98 1bb 8 5 98 170 9 5 98 175 a 5 98 17a b 5 98 17f c 5 98 184 d 5 98 189 e 5 98 18e f 5 98 193 0 6 98 198 1 6 98 19e 2 6 98 1a4 3 6 98 1aa 4 6 98 1b0 5 6 98 1b6 6 6 98 1bc 7 6 98 1c2 8 6 98 168 9 6 98 16e a 6 98 174 b 6 98 17a c 6 98 180 d 6 98 186 e 6 98 18c f 6 98 192 0 7 98 198 1 7 98 19f 2 7 98 1a6 3 7 98 1ad 4 7 98 1b4 5 7 98 1bb 6 7 98 1c2 7 7 98 1c9 8 7 98 160 9 7 98 167 a 7 98 16e b 7 98 175 c 7 98 17c d 7 98 183 e 7 98 18a f 7 98 191 0 8 98 198 1 8 98 190 2 8 98 188 3 8 98 180 4 8 98 178 5 8 98 170 6 8 98 168 7 8 98 160 8 8 98 1d8 9 8 98 1d0 a 8 98 1c8 b 8 98 1c0 c 8 98 1b8 d 8 98 1b0 e 8 98 1a8 f 8 98 1a0 0 9 98 198 1 9 98 191 2 9 98 18a 3 9 98 183 4 9 98 17c 5 9 98 175 6 9 98 16e 7 9 98 167 8 9 98 1d0 9 9 98 1c9 a 9 98 1c2 b 9 98 1bb c 9 98 1b4 d 9 98 1ad e 9 98 1a6 f 9 98 19f 0 a 98 198 1 a 98 192 2 a 98 18c 3 a 98 186 4 a 98 180 5 a 98 17a 6 a 98 174 7 a 98 16e 8 a 98 1c8 9 a 98 1c2 a a 98 1bc b a 98 1b6 c a 98 1b0 d a 98 1aa e a 98 1a4 f a 98 19e 0 b 98 198 1 b 98 193 2 b 98 18e 3 b 98 189 4 b 98 184 5 b 98 17f 6 b 98 17a 7 b 98 175 8 b 98 1c0 9 b 98 1bb a b 98 1b6 b b 98 1b1 c b 98 1ac d b 98 1a7 e b 98 1a2 f b 98 19d 0 c 98 198 1 c 98 194 2 c 98 190 3 c 98 18c 4 c 98 188 5 c 98 184 6 c 98 180 7 c 98 17c 8 c 98 1b8 9 c 98 1b4 a c 98 1b0 b c 98 1ac c c 98 1a8 d c 98 1a4 e c 98 1a0 f c 98 19c 0 d 98 198 1 d 98 195 2 d 98 192 3 d 98 18f 4 d 98 18c 5 d 98 189 6 d 98 186 7 d 98 183 8 d 98 1b0 9 d 98 1ad a d 98 1aa b d 98 1a7 c d 98 1a4 d d 98 1a1 e d 98 19e f d 98 19b 0 e 98 198 1 e 98 196 2 e 98 194 3 e 98 192 4 e 98 190 5 e 98 18e 6 e 98 18c 7 e 98 18a 8 e 98 1a8 9 e 98 1a6 a e 98 1a4 b e 98 1a2 c e 98 1a0 d e 98 19e e e 98 19c f e 98 19a 0 f 98 198 1 f 98 197 2 f 98 196 3 f 98 195 4 f 98 194 5 f 98 193 6 f 98 192 7 f 98 191 8 f 98 1a0 9 f 98 19f a f 98 19e b f 98 19d c f 98 19c d f 98 19b e f 98 19a f f 98 199 0 0 99 199 1 0 99 199 2 0 99 199 3 0 99 199 4 0 99 199 5 0 99 199 6 0 99 199 7 0 99 199 8 0 99 199 9 0 99 199 a 0 99 199 b 0 99 199 c 0 99 199 d 0 99 199 e 0 99 199 f 0 99 199 0 1 99 199 1 1 99 19a 2 1 99 19b 3 1 99 19c 4 1 99 19d 5 1 99 19e 6 1 99 19f 7 1 99 1a0 8 1 99 191 9 1 99 192 a 1 99 193 b 1 99 194 c 1 99 195 d 1 99 196 e 1 99 197 f 1 99 198 0 2 99 199 1 2 99 19b 2 2 99 19d 3 2 99 19f 4 2 99 1a1 5 2 99 1a3 6 2 99 1a5 7 2 99 1a7 8 2 99 189 9 2 99 18b a 2 99 18d b 2 99 18f c 2 99 191 d 2 99 193 e 2 99 195 f 2 99 197 0 3 99 199 1 3 99 19c 2 3 99 19f 3 3 99 1a2 4 3 99 1a5 5 3 99 1a8 6 3 99 1ab 7 3 99 1ae 8 3 99 181 9 3 99 184 a 3 99 187 b 3 99 18a c 3 99 18d d 3 99 190 e 3 99 193 f 3 99 196 0 4 99 199 1 4 99 19d 2 4 99 1a1 3 4 99 1a5 4 4 99 1a9 5 4 99 1ad 6 4 99 1b1 7 4 99 1b5 8 4 99 179 9 4 99 17d a 4 99 181 b 4 99 185 c 4 99 189 d 4 99 18d e 4 99 191 f 4 99 195 0 5 99 199 1 5 99 19e 2 5 99 1a3 3 5 99 1a8 4 5 99 1ad 5 5 99 1b2 6 5 99 1b7 7 5 99 1bc 8 5 99 171 9 5 99 176 a 5 99 17b b 5 99 180 c 5 99 185 d 5 99 18a e 5 99 18f f 5 99 194 0 6 99 199 1 6 99 19f 2 6 99 1a5 3 6 99 1ab 4 6 99 1b1 5 6 99 1b7 6 6 99 1bd 7 6 99 1c3 8 6 99 169 9 6 99 16f a 6 99 175 b 6 99 17b c 6 99 181 d 6 99 187 e 6 99 18d f 6 99 193 0 7 99 199 1 7 99 1a0 2 7 99 1a7 3 7 99 1ae 4 7 99 1b5 5 7 99 1bc 6 7 99 1c3 7 7 99 1ca 8 7 99 161 9 7 99 168 a 7 99 16f b 7 99 176 c 7 99 17d d 7 99 184 e 7 99 18b f 7 99 192 0 8 99 199 1 8 99 191 2 8 99 189 3 8 99 181 4 8 99 179 5 8 99 171 6 8 99 169 7 8 99 161 8 8 99 1d9 9 8 99 1d1 a 8 99 1c9 b 8 99 1c1 c 8 99 1b9 d 8 99 1b1 e 8 99 1a9 f 8 99 1a1 0 9 99 199 1 9 99 192 2 9 99 18b 3 9 99 184 4 9 99 17d 5 9 99 176 6 9 99 16f 7 9 99 168 8 9 99 1d1 9 9 99 1ca a 9 99 1c3 b 9 99 1bc c 9 99 1b5 d 9 99 1ae e 9 99 1a7 f 9 99 1a0 0 a 99 199 1 a 99 193 2 a 99 18d 3 a 99 187 4 a 99 181 5 a 99 17b 6 a 99 175 7 a 99 16f 8 a 99 1c9 9 a 99 1c3 a a 99 1bd b a 99 1b7 c a 99 1b1 d a 99 1ab e a 99 1a5 f a 99 19f 0 b 99 199 1 b 99 194 2 b 99 18f 3 b 99 18a 4 b 99 185 5 b 99 180 6 b 99 17b 7 b 99 176 8 b 99 1c1 9 b 99 1bc a b 99 1b7 b b 99 1b2 c b 99 1ad d b 99 1a8 e b 99 1a3 f b 99 19e 0 c 99 199 1 c 99 195 2 c 99 191 3 c 99 18d 4 c 99 189 5 c 99 185 6 c 99 181 7 c 99 17d 8 c 99 1b9 9 c 99 1b5 a c 99 1b1 b c 99 1ad c c 99 1a9 d c 99 1a5 e c 99 1a1 f c 99 19d 0 d 99 199 1 d 99 196 2 d 99 193 3 d 99 190 4 d 99 18d 5 d 99 18a 6 d 99 187 7 d 99 184 8 d 99 1b1 9 d 99 1ae a d 99 1ab b d 99 1a8 c d 99 1a5 d d 99 1a2 e d 99 19f f d 99 19c 0 e 99 199 1 e 99 197 2 e 99 195 3 e 99 193 4 e 99 191 5 e 99 18f 6 e 99 18d 7 e 99 18b 8 e 99 1a9 9 e 99 1a7 a e 99 1a5 b e 99 1a3 c e 99 1a1 d e 99 19f e e 99 19d f e 99 19b 0 f 99 199 1 f 99 198 2 f 99 197 3 f 99 196 4 f 99 195 5 f 99 194 6 f 99 193 7 f 99 192 8 f 99 1a1 9 f 99 1a0 a f 99 19f b f 99 19e c f 99 19d d f 99 19c e f 99 19b f f 99 19a 0 0 9a 19a 1 0 9a 19a 2 0 9a 19a 3 0 9a 19a 4 0 9a 19a 5 0 9a 19a 6 0 9a 19a 7 0 9a 19a 8 0 9a 19a 9 0 9a 19a a 0 9a 19a b 0 9a 19a c 0 9a 19a d 0 9a 19a e 0 9a 19a f 0 9a 19a 0 1 9a 19a 1 1 9a 19b 2 1 9a 19c 3 1 9a 19d 4 1 9a 19e 5 1 9a 19f 6 1 9a 1a0 7 1 9a 1a1 8 1 9a 192 9 1 9a 193 a 1 9a 194 b 1 9a 195 c 1 9a 196 d 1 9a 197 e 1 9a 198 f 1 9a 199 0 2 9a 19a 1 2 9a 19c 2 2 9a 19e 3 2 9a 1a0 4 2 9a 1a2 5 2 9a 1a4 6 2 9a 1a6 7 2 9a 1a8 8 2 9a 18a 9 2 9a 18c a 2 9a 18e b 2 9a 190 c 2 9a 192 d 2 9a 194 e 2 9a 196 f 2 9a 198 0 3 9a 19a 1 3 9a 19d 2 3 9a 1a0 3 3 9a 1a3 4 3 9a 1a6 5 3 9a 1a9 6 3 9a 1ac 7 3 9a 1af 8 3 9a 182 9 3 9a 185 a 3 9a 188 b 3 9a 18b c 3 9a 18e d 3 9a 191 e 3 9a 194 f 3 9a 197 0 4 9a 19a 1 4 9a 19e 2 4 9a 1a2 3 4 9a 1a6 4 4 9a 1aa 5 4 9a 1ae 6 4 9a 1b2 7 4 9a 1b6 8 4 9a 17a 9 4 9a 17e a 4 9a 182 b 4 9a 186 c 4 9a 18a d 4 9a 18e e 4 9a 192 f 4 9a 196 0 5 9a 19a 1 5 9a 19f 2 5 9a 1a4 3 5 9a 1a9 4 5 9a 1ae 5 5 9a 1b3 6 5 9a 1b8 7 5 9a 1bd 8 5 9a 172 9 5 9a 177 a 5 9a 17c b 5 9a 181 c 5 9a 186 d 5 9a 18b e 5 9a 190 f 5 9a 195 0 6 9a 19a 1 6 9a 1a0 2 6 9a 1a6 3 6 9a 1ac 4 6 9a 1b2 5 6 9a 1b8 6 6 9a 1be 7 6 9a 1c4 8 6 9a 16a 9 6 9a 170 a 6 9a 176 b 6 9a 17c c 6 9a 182 d 6 9a 188 e 6 9a 18e f 6 9a 194 0 7 9a 19a 1 7 9a 1a1 2 7 9a 1a8 3 7 9a 1af 4 7 9a 1b6 5 7 9a 1bd 6 7 9a 1c4 7 7 9a 1cb 8 7 9a 162 9 7 9a 169 a 7 9a 170 b 7 9a 177 c 7 9a 17e d 7 9a 185 e 7 9a 18c f 7 9a 193 0 8 9a 19a 1 8 9a 192 2 8 9a 18a 3 8 9a 182 4 8 9a 17a 5 8 9a 172 6 8 9a 16a 7 8 9a 162 8 8 9a 1da 9 8 9a 1d2 a 8 9a 1ca b 8 9a 1c2 c 8 9a 1ba d 8 9a 1b2 e 8 9a 1aa f 8 9a 1a2 0 9 9a 19a 1 9 9a 193 2 9 9a 18c 3 9 9a 185 4 9 9a 17e 5 9 9a 177 6 9 9a 170 7 9 9a 169 8 9 9a 1d2 9 9 9a 1cb a 9 9a 1c4 b 9 9a 1bd c 9 9a 1b6 d 9 9a 1af e 9 9a 1a8 f 9 9a 1a1 0 a 9a 19a 1 a 9a 194 2 a 9a 18e 3 a 9a 188 4 a 9a 182 5 a 9a 17c 6 a 9a 176 7 a 9a 170 8 a 9a 1ca 9 a 9a 1c4 a a 9a 1be b a 9a 1b8 c a 9a 1b2 d a 9a 1ac e a 9a 1a6 f a 9a 1a0 0 b 9a 19a 1 b 9a 195 2 b 9a 190 3 b 9a 18b 4 b 9a 186 5 b 9a 181 6 b 9a 17c 7 b 9a 177 8 b 9a 1c2 9 b 9a 1bd a b 9a 1b8 b b 9a 1b3 c b 9a 1ae d b 9a 1a9 e b 9a 1a4 f b 9a 19f 0 c 9a 19a 1 c 9a 196 2 c 9a 192 3 c 9a 18e 4 c 9a 18a 5 c 9a 186 6 c 9a 182 7 c 9a 17e 8 c 9a 1ba 9 c 9a 1b6 a c 9a 1b2 b c 9a 1ae c c 9a 1aa d c 9a 1a6 e c 9a 1a2 f c 9a 19e 0 d 9a 19a 1 d 9a 197 2 d 9a 194 3 d 9a 191 4 d 9a 18e 5 d 9a 18b 6 d 9a 188 7 d 9a 185 8 d 9a 1b2 9 d 9a 1af a d 9a 1ac b d 9a 1a9 c d 9a 1a6 d d 9a 1a3 e d 9a 1a0 f d 9a 19d 0 e 9a 19a 1 e 9a 198 2 e 9a 196 3 e 9a 194 4 e 9a 192 5 e 9a 190 6 e 9a 18e 7 e 9a 18c 8 e 9a 1aa 9 e 9a 1a8 a e 9a 1a6 b e 9a 1a4 c e 9a 1a2 d e 9a 1a0 e e 9a 19e f e 9a 19c 0 f 9a 19a 1 f 9a 199 2 f 9a 198 3 f 9a 197 4 f 9a 196 5 f 9a 195 6 f 9a 194 7 f 9a 193 8 f 9a 1a2 9 f 9a 1a1 a f 9a 1a0 b f 9a 19f c f 9a 19e d f 9a 19d e f 9a 19c f f 9a 19b 0 0 9b 19b 1 0 9b 19b 2 0 9b 19b 3 0 9b 19b 4 0 9b 19b 5 0 9b 19b 6 0 9b 19b 7 0 9b 19b 8 0 9b 19b 9 0 9b 19b a 0 9b 19b b 0 9b 19b c 0 9b 19b d 0 9b 19b e 0 9b 19b f 0 9b 19b 0 1 9b 19b 1 1 9b 19c 2 1 9b 19d 3 1 9b 19e 4 1 9b 19f 5 1 9b 1a0 6 1 9b 1a1 7 1 9b 1a2 8 1 9b 193 9 1 9b 194 a 1 9b 195 b 1 9b 196 c 1 9b 197 d 1 9b 198 e 1 9b 199 f 1 9b 19a 0 2 9b 19b 1 2 9b 19d 2 2 9b 19f 3 2 9b 1a1 4 2 9b 1a3 5 2 9b 1a5 6 2 9b 1a7 7 2 9b 1a9 8 2 9b 18b 9 2 9b 18d a 2 9b 18f b 2 9b 191 c 2 9b 193 d 2 9b 195 e 2 9b 197 f 2 9b 199 0 3 9b 19b 1 3 9b 19e 2 3 9b 1a1 3 3 9b 1a4 4 3 9b 1a7 5 3 9b 1aa 6 3 9b 1ad 7 3 9b 1b0 8 3 9b 183 9 3 9b 186 a 3 9b 189 b 3 9b 18c c 3 9b 18f d 3 9b 192 e 3 9b 195 f 3 9b 198 0 4 9b 19b 1 4 9b 19f 2 4 9b 1a3 3 4 9b 1a7 4 4 9b 1ab 5 4 9b 1af 6 4 9b 1b3 7 4 9b 1b7 8 4 9b 17b 9 4 9b 17f a 4 9b 183 b 4 9b 187 c 4 9b 18b d 4 9b 18f e 4 9b 193 f 4 9b 197 0 5 9b 19b 1 5 9b 1a0 2 5 9b 1a5 3 5 9b 1aa 4 5 9b 1af 5 5 9b 1b4 6 5 9b 1b9 7 5 9b 1be 8 5 9b 173 9 5 9b 178 a 5 9b 17d b 5 9b 182 c 5 9b 187 d 5 9b 18c e 5 9b 191 f 5 9b 196 0 6 9b 19b 1 6 9b 1a1 2 6 9b 1a7 3 6 9b 1ad 4 6 9b 1b3 5 6 9b 1b9 6 6 9b 1bf 7 6 9b 1c5 8 6 9b 16b 9 6 9b 171 a 6 9b 177 b 6 9b 17d c 6 9b 183 d 6 9b 189 e 6 9b 18f f 6 9b 195 0 7 9b 19b 1 7 9b 1a2 2 7 9b 1a9 3 7 9b 1b0 4 7 9b 1b7 5 7 9b 1be 6 7 9b 1c5 7 7 9b 1cc 8 7 9b 163 9 7 9b 16a a 7 9b 171 b 7 9b 178 c 7 9b 17f d 7 9b 186 e 7 9b 18d f 7 9b 194 0 8 9b 19b 1 8 9b 193 2 8 9b 18b 3 8 9b 183 4 8 9b 17b 5 8 9b 173 6 8 9b 16b 7 8 9b 163 8 8 9b 1db 9 8 9b 1d3 a 8 9b 1cb b 8 9b 1c3 c 8 9b 1bb d 8 9b 1b3 e 8 9b 1ab f 8 9b 1a3 0 9 9b 19b 1 9 9b 194 2 9 9b 18d 3 9 9b 186 4 9 9b 17f 5 9 9b 178 6 9 9b 171 7 9 9b 16a 8 9 9b 1d3 9 9 9b 1cc a 9 9b 1c5 b 9 9b 1be c 9 9b 1b7 d 9 9b 1b0 e 9 9b 1a9 f 9 9b 1a2 0 a 9b 19b 1 a 9b 195 2 a 9b 18f 3 a 9b 189 4 a 9b 183 5 a 9b 17d 6 a 9b 177 7 a 9b 171 8 a 9b 1cb 9 a 9b 1c5 a a 9b 1bf b a 9b 1b9 c a 9b 1b3 d a 9b 1ad e a 9b 1a7 f a 9b 1a1 0 b 9b 19b 1 b 9b 196 2 b 9b 191 3 b 9b 18c 4 b 9b 187 5 b 9b 182 6 b 9b 17d 7 b 9b 178 8 b 9b 1c3 9 b 9b 1be a b 9b 1b9 b b 9b 1b4 c b 9b 1af d b 9b 1aa e b 9b 1a5 f b 9b 1a0 0 c 9b 19b 1 c 9b 197 2 c 9b 193 3 c 9b 18f 4 c 9b 18b 5 c 9b 187 6 c 9b 183 7 c 9b 17f 8 c 9b 1bb 9 c 9b 1b7 a c 9b 1b3 b c 9b 1af c c 9b 1ab d c 9b 1a7 e c 9b 1a3 f c 9b 19f 0 d 9b 19b 1 d 9b 198 2 d 9b 195 3 d 9b 192 4 d 9b 18f 5 d 9b 18c 6 d 9b 189 7 d 9b 186 8 d 9b 1b3 9 d 9b 1b0 a d 9b 1ad b d 9b 1aa c d 9b 1a7 d d 9b 1a4 e d 9b 1a1 f d 9b 19e 0 e 9b 19b 1 e 9b 199 2 e 9b 197 3 e 9b 195 4 e 9b 193 5 e 9b 191 6 e 9b 18f 7 e 9b 18d 8 e 9b 1ab 9 e 9b 1a9 a e 9b 1a7 b e 9b 1a5 c e 9b 1a3 d e 9b 1a1 e e 9b 19f f e 9b 19d 0 f 9b 19b 1 f 9b 19a 2 f 9b 199 3 f 9b 198 4 f 9b 197 5 f 9b 196 6 f 9b 195 7 f 9b 194 8 f 9b 1a3 9 f 9b 1a2 a f 9b 1a1 b f 9b 1a0 c f 9b 19f d f 9b 19e e f 9b 19d f f 9b 19c 0 0 9c 19c 1 0 9c 19c 2 0 9c 19c 3 0 9c 19c 4 0 9c 19c 5 0 9c 19c 6 0 9c 19c 7 0 9c 19c 8 0 9c 19c 9 0 9c 19c a 0 9c 19c b 0 9c 19c c 0 9c 19c d 0 9c 19c e 0 9c 19c f 0 9c 19c 0 1 9c 19c 1 1 9c 19d 2 1 9c 19e 3 1 9c 19f 4 1 9c 1a0 5 1 9c 1a1 6 1 9c 1a2 7 1 9c 1a3 8 1 9c 194 9 1 9c 195 a 1 9c 196 b 1 9c 197 c 1 9c 198 d 1 9c 199 e 1 9c 19a f 1 9c 19b 0 2 9c 19c 1 2 9c 19e 2 2 9c 1a0 3 2 9c 1a2 4 2 9c 1a4 5 2 9c 1a6 6 2 9c 1a8 7 2 9c 1aa 8 2 9c 18c 9 2 9c 18e a 2 9c 190 b 2 9c 192 c 2 9c 194 d 2 9c 196 e 2 9c 198 f 2 9c 19a 0 3 9c 19c 1 3 9c 19f 2 3 9c 1a2 3 3 9c 1a5 4 3 9c 1a8 5 3 9c 1ab 6 3 9c 1ae 7 3 9c 1b1 8 3 9c 184 9 3 9c 187 a 3 9c 18a b 3 9c 18d c 3 9c 190 d 3 9c 193 e 3 9c 196 f 3 9c 199 0 4 9c 19c 1 4 9c 1a0 2 4 9c 1a4 3 4 9c 1a8 4 4 9c 1ac 5 4 9c 1b0 6 4 9c 1b4 7 4 9c 1b8 8 4 9c 17c 9 4 9c 180 a 4 9c 184 b 4 9c 188 c 4 9c 18c d 4 9c 190 e 4 9c 194 f 4 9c 198 0 5 9c 19c 1 5 9c 1a1 2 5 9c 1a6 3 5 9c 1ab 4 5 9c 1b0 5 5 9c 1b5 6 5 9c 1ba 7 5 9c 1bf 8 5 9c 174 9 5 9c 179 a 5 9c 17e b 5 9c 183 c 5 9c 188 d 5 9c 18d e 5 9c 192 f 5 9c 197 0 6 9c 19c 1 6 9c 1a2 2 6 9c 1a8 3 6 9c 1ae 4 6 9c 1b4 5 6 9c 1ba 6 6 9c 1c0 7 6 9c 1c6 8 6 9c 16c 9 6 9c 172 a 6 9c 178 b 6 9c 17e c 6 9c 184 d 6 9c 18a e 6 9c 190 f 6 9c 196 0 7 9c 19c 1 7 9c 1a3 2 7 9c 1aa 3 7 9c 1b1 4 7 9c 1b8 5 7 9c 1bf 6 7 9c 1c6 7 7 9c 1cd 8 7 9c 164 9 7 9c 16b a 7 9c 172 b 7 9c 179 c 7 9c 180 d 7 9c 187 e 7 9c 18e f 7 9c 195 0 8 9c 19c 1 8 9c 194 2 8 9c 18c 3 8 9c 184 4 8 9c 17c 5 8 9c 174 6 8 9c 16c 7 8 9c 164 8 8 9c 1dc 9 8 9c 1d4 a 8 9c 1cc b 8 9c 1c4 c 8 9c 1bc d 8 9c 1b4 e 8 9c 1ac f 8 9c 1a4 0 9 9c 19c 1 9 9c 195 2 9 9c 18e 3 9 9c 187 4 9 9c 180 5 9 9c 179 6 9 9c 172 7 9 9c 16b 8 9 9c 1d4 9 9 9c 1cd a 9 9c 1c6 b 9 9c 1bf c 9 9c 1b8 d 9 9c 1b1 e 9 9c 1aa f 9 9c 1a3 0 a 9c 19c 1 a 9c 196 2 a 9c 190 3 a 9c 18a 4 a 9c 184 5 a 9c 17e 6 a 9c 178 7 a 9c 172 8 a 9c 1cc 9 a 9c 1c6 a a 9c 1c0 b a 9c 1ba c a 9c 1b4 d a 9c 1ae e a 9c 1a8 f a 9c 1a2 0 b 9c 19c 1 b 9c 197 2 b 9c 192 3 b 9c 18d 4 b 9c 188 5 b 9c 183 6 b 9c 17e 7 b 9c 179 8 b 9c 1c4 9 b 9c 1bf a b 9c 1ba b b 9c 1b5 c b 9c 1b0 d b 9c 1ab e b 9c 1a6 f b 9c 1a1 0 c 9c 19c 1 c 9c 198 2 c 9c 194 3 c 9c 190 4 c 9c 18c 5 c 9c 188 6 c 9c 184 7 c 9c 180 8 c 9c 1bc 9 c 9c 1b8 a c 9c 1b4 b c 9c 1b0 c c 9c 1ac d c 9c 1a8 e c 9c 1a4 f c 9c 1a0 0 d 9c 19c 1 d 9c 199 2 d 9c 196 3 d 9c 193 4 d 9c 190 5 d 9c 18d 6 d 9c 18a 7 d 9c 187 8 d 9c 1b4 9 d 9c 1b1 a d 9c 1ae b d 9c 1ab c d 9c 1a8 d d 9c 1a5 e d 9c 1a2 f d 9c 19f 0 e 9c 19c 1 e 9c 19a 2 e 9c 198 3 e 9c 196 4 e 9c 194 5 e 9c 192 6 e 9c 190 7 e 9c 18e 8 e 9c 1ac 9 e 9c 1aa a e 9c 1a8 b e 9c 1a6 c e 9c 1a4 d e 9c 1a2 e e 9c 1a0 f e 9c 19e 0 f 9c 19c 1 f 9c 19b 2 f 9c 19a 3 f 9c 199 4 f 9c 198 5 f 9c 197 6 f 9c 196 7 f 9c 195 8 f 9c 1a4 9 f 9c 1a3 a f 9c 1a2 b f 9c 1a1 c f 9c 1a0 d f 9c 19f e f 9c 19e f f 9c 19d 0 0 9d 19d 1 0 9d 19d 2 0 9d 19d 3 0 9d 19d 4 0 9d 19d 5 0 9d 19d 6 0 9d 19d 7 0 9d 19d 8 0 9d 19d 9 0 9d 19d a 0 9d 19d b 0 9d 19d c 0 9d 19d d 0 9d 19d e 0 9d 19d f 0 9d 19d 0 1 9d 19d 1 1 9d 19e 2 1 9d 19f 3 1 9d 1a0 4 1 9d 1a1 5 1 9d 1a2 6 1 9d 1a3 7 1 9d 1a4 8 1 9d 195 9 1 9d 196 a 1 9d 197 b 1 9d 198 c 1 9d 199 d 1 9d 19a e 1 9d 19b f 1 9d 19c 0 2 9d 19d 1 2 9d 19f 2 2 9d 1a1 3 2 9d 1a3 4 2 9d 1a5 5 2 9d 1a7 6 2 9d 1a9 7 2 9d 1ab 8 2 9d 18d 9 2 9d 18f a 2 9d 191 b 2 9d 193 c 2 9d 195 d 2 9d 197 e 2 9d 199 f 2 9d 19b 0 3 9d 19d 1 3 9d 1a0 2 3 9d 1a3 3 3 9d 1a6 4 3 9d 1a9 5 3 9d 1ac 6 3 9d 1af 7 3 9d 1b2 8 3 9d 185 9 3 9d 188 a 3 9d 18b b 3 9d 18e c 3 9d 191 d 3 9d 194 e 3 9d 197 f 3 9d 19a 0 4 9d 19d 1 4 9d 1a1 2 4 9d 1a5 3 4 9d 1a9 4 4 9d 1ad 5 4 9d 1b1 6 4 9d 1b5 7 4 9d 1b9 8 4 9d 17d 9 4 9d 181 a 4 9d 185 b 4 9d 189 c 4 9d 18d d 4 9d 191 e 4 9d 195 f 4 9d 199 0 5 9d 19d 1 5 9d 1a2 2 5 9d 1a7 3 5 9d 1ac 4 5 9d 1b1 5 5 9d 1b6 6 5 9d 1bb 7 5 9d 1c0 8 5 9d 175 9 5 9d 17a a 5 9d 17f b 5 9d 184 c 5 9d 189 d 5 9d 18e e 5 9d 193 f 5 9d 198 0 6 9d 19d 1 6 9d 1a3 2 6 9d 1a9 3 6 9d 1af 4 6 9d 1b5 5 6 9d 1bb 6 6 9d 1c1 7 6 9d 1c7 8 6 9d 16d 9 6 9d 173 a 6 9d 179 b 6 9d 17f c 6 9d 185 d 6 9d 18b e 6 9d 191 f 6 9d 197 0 7 9d 19d 1 7 9d 1a4 2 7 9d 1ab 3 7 9d 1b2 4 7 9d 1b9 5 7 9d 1c0 6 7 9d 1c7 7 7 9d 1ce 8 7 9d 165 9 7 9d 16c a 7 9d 173 b 7 9d 17a c 7 9d 181 d 7 9d 188 e 7 9d 18f f 7 9d 196 0 8 9d 19d 1 8 9d 195 2 8 9d 18d 3 8 9d 185 4 8 9d 17d 5 8 9d 175 6 8 9d 16d 7 8 9d 165 8 8 9d 1dd 9 8 9d 1d5 a 8 9d 1cd b 8 9d 1c5 c 8 9d 1bd d 8 9d 1b5 e 8 9d 1ad f 8 9d 1a5 0 9 9d 19d 1 9 9d 196 2 9 9d 18f 3 9 9d 188 4 9 9d 181 5 9 9d 17a 6 9 9d 173 7 9 9d 16c 8 9 9d 1d5 9 9 9d 1ce a 9 9d 1c7 b 9 9d 1c0 c 9 9d 1b9 d 9 9d 1b2 e 9 9d 1ab f 9 9d 1a4 0 a 9d 19d 1 a 9d 197 2 a 9d 191 3 a 9d 18b 4 a 9d 185 5 a 9d 17f 6 a 9d 179 7 a 9d 173 8 a 9d 1cd 9 a 9d 1c7 a a 9d 1c1 b a 9d 1bb c a 9d 1b5 d a 9d 1af e a 9d 1a9 f a 9d 1a3 0 b 9d 19d 1 b 9d 198 2 b 9d 193 3 b 9d 18e 4 b 9d 189 5 b 9d 184 6 b 9d 17f 7 b 9d 17a 8 b 9d 1c5 9 b 9d 1c0 a b 9d 1bb b b 9d 1b6 c b 9d 1b1 d b 9d 1ac e b 9d 1a7 f b 9d 1a2 0 c 9d 19d 1 c 9d 199 2 c 9d 195 3 c 9d 191 4 c 9d 18d 5 c 9d 189 6 c 9d 185 7 c 9d 181 8 c 9d 1bd 9 c 9d 1b9 a c 9d 1b5 b c 9d 1b1 c c 9d 1ad d c 9d 1a9 e c 9d 1a5 f c 9d 1a1 0 d 9d 19d 1 d 9d 19a 2 d 9d 197 3 d 9d 194 4 d 9d 191 5 d 9d 18e 6 d 9d 18b 7 d 9d 188 8 d 9d 1b5 9 d 9d 1b2 a d 9d 1af b d 9d 1ac c d 9d 1a9 d d 9d 1a6 e d 9d 1a3 f d 9d 1a0 0 e 9d 19d 1 e 9d 19b 2 e 9d 199 3 e 9d 197 4 e 9d 195 5 e 9d 193 6 e 9d 191 7 e 9d 18f 8 e 9d 1ad 9 e 9d 1ab a e 9d 1a9 b e 9d 1a7 c e 9d 1a5 d e 9d 1a3 e e 9d 1a1 f e 9d 19f 0 f 9d 19d 1 f 9d 19c 2 f 9d 19b 3 f 9d 19a 4 f 9d 199 5 f 9d 198 6 f 9d 197 7 f 9d 196 8 f 9d 1a5 9 f 9d 1a4 a f 9d 1a3 b f 9d 1a2 c f 9d 1a1 d f 9d 1a0 e f 9d 19f f f 9d 19e 0 0 9e 19e 1 0 9e 19e 2 0 9e 19e 3 0 9e 19e 4 0 9e 19e 5 0 9e 19e 6 0 9e 19e 7 0 9e 19e 8 0 9e 19e 9 0 9e 19e a 0 9e 19e b 0 9e 19e c 0 9e 19e d 0 9e 19e e 0 9e 19e f 0 9e 19e 0 1 9e 19e 1 1 9e 19f 2 1 9e 1a0 3 1 9e 1a1 4 1 9e 1a2 5 1 9e 1a3 6 1 9e 1a4 7 1 9e 1a5 8 1 9e 196 9 1 9e 197 a 1 9e 198 b 1 9e 199 c 1 9e 19a d 1 9e 19b e 1 9e 19c f 1 9e 19d 0 2 9e 19e 1 2 9e 1a0 2 2 9e 1a2 3 2 9e 1a4 4 2 9e 1a6 5 2 9e 1a8 6 2 9e 1aa 7 2 9e 1ac 8 2 9e 18e 9 2 9e 190 a 2 9e 192 b 2 9e 194 c 2 9e 196 d 2 9e 198 e 2 9e 19a f 2 9e 19c 0 3 9e 19e 1 3 9e 1a1 2 3 9e 1a4 3 3 9e 1a7 4 3 9e 1aa 5 3 9e 1ad 6 3 9e 1b0 7 3 9e 1b3 8 3 9e 186 9 3 9e 189 a 3 9e 18c b 3 9e 18f c 3 9e 192 d 3 9e 195 e 3 9e 198 f 3 9e 19b 0 4 9e 19e 1 4 9e 1a2 2 4 9e 1a6 3 4 9e 1aa 4 4 9e 1ae 5 4 9e 1b2 6 4 9e 1b6 7 4 9e 1ba 8 4 9e 17e 9 4 9e 182 a 4 9e 186 b 4 9e 18a c 4 9e 18e d 4 9e 192 e 4 9e 196 f 4 9e 19a 0 5 9e 19e 1 5 9e 1a3 2 5 9e 1a8 3 5 9e 1ad 4 5 9e 1b2 5 5 9e 1b7 6 5 9e 1bc 7 5 9e 1c1 8 5 9e 176 9 5 9e 17b a 5 9e 180 b 5 9e 185 c 5 9e 18a d 5 9e 18f e 5 9e 194 f 5 9e 199 0 6 9e 19e 1 6 9e 1a4 2 6 9e 1aa 3 6 9e 1b0 4 6 9e 1b6 5 6 9e 1bc 6 6 9e 1c2 7 6 9e 1c8 8 6 9e 16e 9 6 9e 174 a 6 9e 17a b 6 9e 180 c 6 9e 186 d 6 9e 18c e 6 9e 192 f 6 9e 198 0 7 9e 19e 1 7 9e 1a5 2 7 9e 1ac 3 7 9e 1b3 4 7 9e 1ba 5 7 9e 1c1 6 7 9e 1c8 7 7 9e 1cf 8 7 9e 166 9 7 9e 16d a 7 9e 174 b 7 9e 17b c 7 9e 182 d 7 9e 189 e 7 9e 190 f 7 9e 197 0 8 9e 19e 1 8 9e 196 2 8 9e 18e 3 8 9e 186 4 8 9e 17e 5 8 9e 176 6 8 9e 16e 7 8 9e 166 8 8 9e 1de 9 8 9e 1d6 a 8 9e 1ce b 8 9e 1c6 c 8 9e 1be d 8 9e 1b6 e 8 9e 1ae f 8 9e 1a6 0 9 9e 19e 1 9 9e 197 2 9 9e 190 3 9 9e 189 4 9 9e 182 5 9 9e 17b 6 9 9e 174 7 9 9e 16d 8 9 9e 1d6 9 9 9e 1cf a 9 9e 1c8 b 9 9e 1c1 c 9 9e 1ba d 9 9e 1b3 e 9 9e 1ac f 9 9e 1a5 0 a 9e 19e 1 a 9e 198 2 a 9e 192 3 a 9e 18c 4 a 9e 186 5 a 9e 180 6 a 9e 17a 7 a 9e 174 8 a 9e 1ce 9 a 9e 1c8 a a 9e 1c2 b a 9e 1bc c a 9e 1b6 d a 9e 1b0 e a 9e 1aa f a 9e 1a4 0 b 9e 19e 1 b 9e 199 2 b 9e 194 3 b 9e 18f 4 b 9e 18a 5 b 9e 185 6 b 9e 180 7 b 9e 17b 8 b 9e 1c6 9 b 9e 1c1 a b 9e 1bc b b 9e 1b7 c b 9e 1b2 d b 9e 1ad e b 9e 1a8 f b 9e 1a3 0 c 9e 19e 1 c 9e 19a 2 c 9e 196 3 c 9e 192 4 c 9e 18e 5 c 9e 18a 6 c 9e 186 7 c 9e 182 8 c 9e 1be 9 c 9e 1ba a c 9e 1b6 b c 9e 1b2 c c 9e 1ae d c 9e 1aa e c 9e 1a6 f c 9e 1a2 0 d 9e 19e 1 d 9e 19b 2 d 9e 198 3 d 9e 195 4 d 9e 192 5 d 9e 18f 6 d 9e 18c 7 d 9e 189 8 d 9e 1b6 9 d 9e 1b3 a d 9e 1b0 b d 9e 1ad c d 9e 1aa d d 9e 1a7 e d 9e 1a4 f d 9e 1a1 0 e 9e 19e 1 e 9e 19c 2 e 9e 19a 3 e 9e 198 4 e 9e 196 5 e 9e 194 6 e 9e 192 7 e 9e 190 8 e 9e 1ae 9 e 9e 1ac a e 9e 1aa b e 9e 1a8 c e 9e 1a6 d e 9e 1a4 e e 9e 1a2 f e 9e 1a0 0 f 9e 19e 1 f 9e 19d 2 f 9e 19c 3 f 9e 19b 4 f 9e 19a 5 f 9e 199 6 f 9e 198 7 f 9e 197 8 f 9e 1a6 9 f 9e 1a5 a f 9e 1a4 b f 9e 1a3 c f 9e 1a2 d f 9e 1a1 e f 9e 1a0 f f 9e 19f 0 0 9f 19f 1 0 9f 19f 2 0 9f 19f 3 0 9f 19f 4 0 9f 19f 5 0 9f 19f 6 0 9f 19f 7 0 9f 19f 8 0 9f 19f 9 0 9f 19f a 0 9f 19f b 0 9f 19f c 0 9f 19f d 0 9f 19f e 0 9f 19f f 0 9f 19f 0 1 9f 19f 1 1 9f 1a0 2 1 9f 1a1 3 1 9f 1a2 4 1 9f 1a3 5 1 9f 1a4 6 1 9f 1a5 7 1 9f 1a6 8 1 9f 197 9 1 9f 198 a 1 9f 199 b 1 9f 19a c 1 9f 19b d 1 9f 19c e 1 9f 19d f 1 9f 19e 0 2 9f 19f 1 2 9f 1a1 2 2 9f 1a3 3 2 9f 1a5 4 2 9f 1a7 5 2 9f 1a9 6 2 9f 1ab 7 2 9f 1ad 8 2 9f 18f 9 2 9f 191 a 2 9f 193 b 2 9f 195 c 2 9f 197 d 2 9f 199 e 2 9f 19b f 2 9f 19d 0 3 9f 19f 1 3 9f 1a2 2 3 9f 1a5 3 3 9f 1a8 4 3 9f 1ab 5 3 9f 1ae 6 3 9f 1b1 7 3 9f 1b4 8 3 9f 187 9 3 9f 18a a 3 9f 18d b 3 9f 190 c 3 9f 193 d 3 9f 196 e 3 9f 199 f 3 9f 19c 0 4 9f 19f 1 4 9f 1a3 2 4 9f 1a7 3 4 9f 1ab 4 4 9f 1af 5 4 9f 1b3 6 4 9f 1b7 7 4 9f 1bb 8 4 9f 17f 9 4 9f 183 a 4 9f 187 b 4 9f 18b c 4 9f 18f d 4 9f 193 e 4 9f 197 f 4 9f 19b 0 5 9f 19f 1 5 9f 1a4 2 5 9f 1a9 3 5 9f 1ae 4 5 9f 1b3 5 5 9f 1b8 6 5 9f 1bd 7 5 9f 1c2 8 5 9f 177 9 5 9f 17c a 5 9f 181 b 5 9f 186 c 5 9f 18b d 5 9f 190 e 5 9f 195 f 5 9f 19a 0 6 9f 19f 1 6 9f 1a5 2 6 9f 1ab 3 6 9f 1b1 4 6 9f 1b7 5 6 9f 1bd 6 6 9f 1c3 7 6 9f 1c9 8 6 9f 16f 9 6 9f 175 a 6 9f 17b b 6 9f 181 c 6 9f 187 d 6 9f 18d e 6 9f 193 f 6 9f 199 0 7 9f 19f 1 7 9f 1a6 2 7 9f 1ad 3 7 9f 1b4 4 7 9f 1bb 5 7 9f 1c2 6 7 9f 1c9 7 7 9f 1d0 8 7 9f 167 9 7 9f 16e a 7 9f 175 b 7 9f 17c c 7 9f 183 d 7 9f 18a e 7 9f 191 f 7 9f 198 0 8 9f 19f 1 8 9f 197 2 8 9f 18f 3 8 9f 187 4 8 9f 17f 5 8 9f 177 6 8 9f 16f 7 8 9f 167 8 8 9f 1df 9 8 9f 1d7 a 8 9f 1cf b 8 9f 1c7 c 8 9f 1bf d 8 9f 1b7 e 8 9f 1af f 8 9f 1a7 0 9 9f 19f 1 9 9f 198 2 9 9f 191 3 9 9f 18a 4 9 9f 183 5 9 9f 17c 6 9 9f 175 7 9 9f 16e 8 9 9f 1d7 9 9 9f 1d0 a 9 9f 1c9 b 9 9f 1c2 c 9 9f 1bb d 9 9f 1b4 e 9 9f 1ad f 9 9f 1a6 0 a 9f 19f 1 a 9f 199 2 a 9f 193 3 a 9f 18d 4 a 9f 187 5 a 9f 181 6 a 9f 17b 7 a 9f 175 8 a 9f 1cf 9 a 9f 1c9 a a 9f 1c3 b a 9f 1bd c a 9f 1b7 d a 9f 1b1 e a 9f 1ab f a 9f 1a5 0 b 9f 19f 1 b 9f 19a 2 b 9f 195 3 b 9f 190 4 b 9f 18b 5 b 9f 186 6 b 9f 181 7 b 9f 17c 8 b 9f 1c7 9 b 9f 1c2 a b 9f 1bd b b 9f 1b8 c b 9f 1b3 d b 9f 1ae e b 9f 1a9 f b 9f 1a4 0 c 9f 19f 1 c 9f 19b 2 c 9f 197 3 c 9f 193 4 c 9f 18f 5 c 9f 18b 6 c 9f 187 7 c 9f 183 8 c 9f 1bf 9 c 9f 1bb a c 9f 1b7 b c 9f 1b3 c c 9f 1af d c 9f 1ab e c 9f 1a7 f c 9f 1a3 0 d 9f 19f 1 d 9f 19c 2 d 9f 199 3 d 9f 196 4 d 9f 193 5 d 9f 190 6 d 9f 18d 7 d 9f 18a 8 d 9f 1b7 9 d 9f 1b4 a d 9f 1b1 b d 9f 1ae c d 9f 1ab d d 9f 1a8 e d 9f 1a5 f d 9f 1a2 0 e 9f 19f 1 e 9f 19d 2 e 9f 19b 3 e 9f 199 4 e 9f 197 5 e 9f 195 6 e 9f 193 7 e 9f 191 8 e 9f 1af 9 e 9f 1ad a e 9f 1ab b e 9f 1a9 c e 9f 1a7 d e 9f 1a5 e e 9f 1a3 f e 9f 1a1 0 f 9f 19f 1 f 9f 19e 2 f 9f 19d 3 f 9f 19c 4 f 9f 19b 5 f 9f 19a 6 f 9f 199 7 f 9f 198 8 f 9f 1a7 9 f 9f 1a6 a f 9f 1a5 b f 9f 1a4 c f 9f 1a3 d f 9f 1a2 e f 9f 1a1 f f 9f 1a0 0 0 a0 1a0 1 0 a0 1a0 2 0 a0 1a0 3 0 a0 1a0 4 0 a0 1a0 5 0 a0 1a0 6 0 a0 1a0 7 0 a0 1a0 8 0 a0 1a0 9 0 a0 1a0 a 0 a0 1a0 b 0 a0 1a0 c 0 a0 1a0 d 0 a0 1a0 e 0 a0 1a0 f 0 a0 1a0 0 1 a0 1a0 1 1 a0 1a1 2 1 a0 1a2 3 1 a0 1a3 4 1 a0 1a4 5 1 a0 1a5 6 1 a0 1a6 7 1 a0 1a7 8 1 a0 198 9 1 a0 199 a 1 a0 19a b 1 a0 19b c 1 a0 19c d 1 a0 19d e 1 a0 19e f 1 a0 19f 0 2 a0 1a0 1 2 a0 1a2 2 2 a0 1a4 3 2 a0 1a6 4 2 a0 1a8 5 2 a0 1aa 6 2 a0 1ac 7 2 a0 1ae 8 2 a0 190 9 2 a0 192 a 2 a0 194 b 2 a0 196 c 2 a0 198 d 2 a0 19a e 2 a0 19c f 2 a0 19e 0 3 a0 1a0 1 3 a0 1a3 2 3 a0 1a6 3 3 a0 1a9 4 3 a0 1ac 5 3 a0 1af 6 3 a0 1b2 7 3 a0 1b5 8 3 a0 188 9 3 a0 18b a 3 a0 18e b 3 a0 191 c 3 a0 194 d 3 a0 197 e 3 a0 19a f 3 a0 19d 0 4 a0 1a0 1 4 a0 1a4 2 4 a0 1a8 3 4 a0 1ac 4 4 a0 1b0 5 4 a0 1b4 6 4 a0 1b8 7 4 a0 1bc 8 4 a0 180 9 4 a0 184 a 4 a0 188 b 4 a0 18c c 4 a0 190 d 4 a0 194 e 4 a0 198 f 4 a0 19c 0 5 a0 1a0 1 5 a0 1a5 2 5 a0 1aa 3 5 a0 1af 4 5 a0 1b4 5 5 a0 1b9 6 5 a0 1be 7 5 a0 1c3 8 5 a0 178 9 5 a0 17d a 5 a0 182 b 5 a0 187 c 5 a0 18c d 5 a0 191 e 5 a0 196 f 5 a0 19b 0 6 a0 1a0 1 6 a0 1a6 2 6 a0 1ac 3 6 a0 1b2 4 6 a0 1b8 5 6 a0 1be 6 6 a0 1c4 7 6 a0 1ca 8 6 a0 170 9 6 a0 176 a 6 a0 17c b 6 a0 182 c 6 a0 188 d 6 a0 18e e 6 a0 194 f 6 a0 19a 0 7 a0 1a0 1 7 a0 1a7 2 7 a0 1ae 3 7 a0 1b5 4 7 a0 1bc 5 7 a0 1c3 6 7 a0 1ca 7 7 a0 1d1 8 7 a0 168 9 7 a0 16f a 7 a0 176 b 7 a0 17d c 7 a0 184 d 7 a0 18b e 7 a0 192 f 7 a0 199 0 8 a0 1a0 1 8 a0 198 2 8 a0 190 3 8 a0 188 4 8 a0 180 5 8 a0 178 6 8 a0 170 7 8 a0 168 8 8 a0 1e0 9 8 a0 1d8 a 8 a0 1d0 b 8 a0 1c8 c 8 a0 1c0 d 8 a0 1b8 e 8 a0 1b0 f 8 a0 1a8 0 9 a0 1a0 1 9 a0 199 2 9 a0 192 3 9 a0 18b 4 9 a0 184 5 9 a0 17d 6 9 a0 176 7 9 a0 16f 8 9 a0 1d8 9 9 a0 1d1 a 9 a0 1ca b 9 a0 1c3 c 9 a0 1bc d 9 a0 1b5 e 9 a0 1ae f 9 a0 1a7 0 a a0 1a0 1 a a0 19a 2 a a0 194 3 a a0 18e 4 a a0 188 5 a a0 182 6 a a0 17c 7 a a0 176 8 a a0 1d0 9 a a0 1ca a a a0 1c4 b a a0 1be c a a0 1b8 d a a0 1b2 e a a0 1ac f a a0 1a6 0 b a0 1a0 1 b a0 19b 2 b a0 196 3 b a0 191 4 b a0 18c 5 b a0 187 6 b a0 182 7 b a0 17d 8 b a0 1c8 9 b a0 1c3 a b a0 1be b b a0 1b9 c b a0 1b4 d b a0 1af e b a0 1aa f b a0 1a5 0 c a0 1a0 1 c a0 19c 2 c a0 198 3 c a0 194 4 c a0 190 5 c a0 18c 6 c a0 188 7 c a0 184 8 c a0 1c0 9 c a0 1bc a c a0 1b8 b c a0 1b4 c c a0 1b0 d c a0 1ac e c a0 1a8 f c a0 1a4 0 d a0 1a0 1 d a0 19d 2 d a0 19a 3 d a0 197 4 d a0 194 5 d a0 191 6 d a0 18e 7 d a0 18b 8 d a0 1b8 9 d a0 1b5 a d a0 1b2 b d a0 1af c d a0 1ac d d a0 1a9 e d a0 1a6 f d a0 1a3 0 e a0 1a0 1 e a0 19e 2 e a0 19c 3 e a0 19a 4 e a0 198 5 e a0 196 6 e a0 194 7 e a0 192 8 e a0 1b0 9 e a0 1ae a e a0 1ac b e a0 1aa c e a0 1a8 d e a0 1a6 e e a0 1a4 f e a0 1a2 0 f a0 1a0 1 f a0 19f 2 f a0 19e 3 f a0 19d 4 f a0 19c 5 f a0 19b 6 f a0 19a 7 f a0 199 8 f a0 1a8 9 f a0 1a7 a f a0 1a6 b f a0 1a5 c f a0 1a4 d f a0 1a3 e f a0 1a2 f f a0 1a1 0 0 a1 1a1 1 0 a1 1a1 2 0 a1 1a1 3 0 a1 1a1 4 0 a1 1a1 5 0 a1 1a1 6 0 a1 1a1 7 0 a1 1a1 8 0 a1 1a1 9 0 a1 1a1 a 0 a1 1a1 b 0 a1 1a1 c 0 a1 1a1 d 0 a1 1a1 e 0 a1 1a1 f 0 a1 1a1 0 1 a1 1a1 1 1 a1 1a2 2 1 a1 1a3 3 1 a1 1a4 4 1 a1 1a5 5 1 a1 1a6 6 1 a1 1a7 7 1 a1 1a8 8 1 a1 199 9 1 a1 19a a 1 a1 19b b 1 a1 19c c 1 a1 19d d 1 a1 19e e 1 a1 19f f 1 a1 1a0 0 2 a1 1a1 1 2 a1 1a3 2 2 a1 1a5 3 2 a1 1a7 4 2 a1 1a9 5 2 a1 1ab 6 2 a1 1ad 7 2 a1 1af 8 2 a1 191 9 2 a1 193 a 2 a1 195 b 2 a1 197 c 2 a1 199 d 2 a1 19b e 2 a1 19d f 2 a1 19f 0 3 a1 1a1 1 3 a1 1a4 2 3 a1 1a7 3 3 a1 1aa 4 3 a1 1ad 5 3 a1 1b0 6 3 a1 1b3 7 3 a1 1b6 8 3 a1 189 9 3 a1 18c a 3 a1 18f b 3 a1 192 c 3 a1 195 d 3 a1 198 e 3 a1 19b f 3 a1 19e 0 4 a1 1a1 1 4 a1 1a5 2 4 a1 1a9 3 4 a1 1ad 4 4 a1 1b1 5 4 a1 1b5 6 4 a1 1b9 7 4 a1 1bd 8 4 a1 181 9 4 a1 185 a 4 a1 189 b 4 a1 18d c 4 a1 191 d 4 a1 195 e 4 a1 199 f 4 a1 19d 0 5 a1 1a1 1 5 a1 1a6 2 5 a1 1ab 3 5 a1 1b0 4 5 a1 1b5 5 5 a1 1ba 6 5 a1 1bf 7 5 a1 1c4 8 5 a1 179 9 5 a1 17e a 5 a1 183 b 5 a1 188 c 5 a1 18d d 5 a1 192 e 5 a1 197 f 5 a1 19c 0 6 a1 1a1 1 6 a1 1a7 2 6 a1 1ad 3 6 a1 1b3 4 6 a1 1b9 5 6 a1 1bf 6 6 a1 1c5 7 6 a1 1cb 8 6 a1 171 9 6 a1 177 a 6 a1 17d b 6 a1 183 c 6 a1 189 d 6 a1 18f e 6 a1 195 f 6 a1 19b 0 7 a1 1a1 1 7 a1 1a8 2 7 a1 1af 3 7 a1 1b6 4 7 a1 1bd 5 7 a1 1c4 6 7 a1 1cb 7 7 a1 1d2 8 7 a1 169 9 7 a1 170 a 7 a1 177 b 7 a1 17e c 7 a1 185 d 7 a1 18c e 7 a1 193 f 7 a1 19a 0 8 a1 1a1 1 8 a1 199 2 8 a1 191 3 8 a1 189 4 8 a1 181 5 8 a1 179 6 8 a1 171 7 8 a1 169 8 8 a1 1e1 9 8 a1 1d9 a 8 a1 1d1 b 8 a1 1c9 c 8 a1 1c1 d 8 a1 1b9 e 8 a1 1b1 f 8 a1 1a9 0 9 a1 1a1 1 9 a1 19a 2 9 a1 193 3 9 a1 18c 4 9 a1 185 5 9 a1 17e 6 9 a1 177 7 9 a1 170 8 9 a1 1d9 9 9 a1 1d2 a 9 a1 1cb b 9 a1 1c4 c 9 a1 1bd d 9 a1 1b6 e 9 a1 1af f 9 a1 1a8 0 a a1 1a1 1 a a1 19b 2 a a1 195 3 a a1 18f 4 a a1 189 5 a a1 183 6 a a1 17d 7 a a1 177 8 a a1 1d1 9 a a1 1cb a a a1 1c5 b a a1 1bf c a a1 1b9 d a a1 1b3 e a a1 1ad f a a1 1a7 0 b a1 1a1 1 b a1 19c 2 b a1 197 3 b a1 192 4 b a1 18d 5 b a1 188 6 b a1 183 7 b a1 17e 8 b a1 1c9 9 b a1 1c4 a b a1 1bf b b a1 1ba c b a1 1b5 d b a1 1b0 e b a1 1ab f b a1 1a6 0 c a1 1a1 1 c a1 19d 2 c a1 199 3 c a1 195 4 c a1 191 5 c a1 18d 6 c a1 189 7 c a1 185 8 c a1 1c1 9 c a1 1bd a c a1 1b9 b c a1 1b5 c c a1 1b1 d c a1 1ad e c a1 1a9 f c a1 1a5 0 d a1 1a1 1 d a1 19e 2 d a1 19b 3 d a1 198 4 d a1 195 5 d a1 192 6 d a1 18f 7 d a1 18c 8 d a1 1b9 9 d a1 1b6 a d a1 1b3 b d a1 1b0 c d a1 1ad d d a1 1aa e d a1 1a7 f d a1 1a4 0 e a1 1a1 1 e a1 19f 2 e a1 19d 3 e a1 19b 4 e a1 199 5 e a1 197 6 e a1 195 7 e a1 193 8 e a1 1b1 9 e a1 1af a e a1 1ad b e a1 1ab c e a1 1a9 d e a1 1a7 e e a1 1a5 f e a1 1a3 0 f a1 1a1 1 f a1 1a0 2 f a1 19f 3 f a1 19e 4 f a1 19d 5 f a1 19c 6 f a1 19b 7 f a1 19a 8 f a1 1a9 9 f a1 1a8 a f a1 1a7 b f a1 1a6 c f a1 1a5 d f a1 1a4 e f a1 1a3 f f a1 1a2 0 0 a2 1a2 1 0 a2 1a2 2 0 a2 1a2 3 0 a2 1a2 4 0 a2 1a2 5 0 a2 1a2 6 0 a2 1a2 7 0 a2 1a2 8 0 a2 1a2 9 0 a2 1a2 a 0 a2 1a2 b 0 a2 1a2 c 0 a2 1a2 d 0 a2 1a2 e 0 a2 1a2 f 0 a2 1a2 0 1 a2 1a2 1 1 a2 1a3 2 1 a2 1a4 3 1 a2 1a5 4 1 a2 1a6 5 1 a2 1a7 6 1 a2 1a8 7 1 a2 1a9 8 1 a2 19a 9 1 a2 19b a 1 a2 19c b 1 a2 19d c 1 a2 19e d 1 a2 19f e 1 a2 1a0 f 1 a2 1a1 0 2 a2 1a2 1 2 a2 1a4 2 2 a2 1a6 3 2 a2 1a8 4 2 a2 1aa 5 2 a2 1ac 6 2 a2 1ae 7 2 a2 1b0 8 2 a2 192 9 2 a2 194 a 2 a2 196 b 2 a2 198 c 2 a2 19a d 2 a2 19c e 2 a2 19e f 2 a2 1a0 0 3 a2 1a2 1 3 a2 1a5 2 3 a2 1a8 3 3 a2 1ab 4 3 a2 1ae 5 3 a2 1b1 6 3 a2 1b4 7 3 a2 1b7 8 3 a2 18a 9 3 a2 18d a 3 a2 190 b 3 a2 193 c 3 a2 196 d 3 a2 199 e 3 a2 19c f 3 a2 19f 0 4 a2 1a2 1 4 a2 1a6 2 4 a2 1aa 3 4 a2 1ae 4 4 a2 1b2 5 4 a2 1b6 6 4 a2 1ba 7 4 a2 1be 8 4 a2 182 9 4 a2 186 a 4 a2 18a b 4 a2 18e c 4 a2 192 d 4 a2 196 e 4 a2 19a f 4 a2 19e 0 5 a2 1a2 1 5 a2 1a7 2 5 a2 1ac 3 5 a2 1b1 4 5 a2 1b6 5 5 a2 1bb 6 5 a2 1c0 7 5 a2 1c5 8 5 a2 17a 9 5 a2 17f a 5 a2 184 b 5 a2 189 c 5 a2 18e d 5 a2 193 e 5 a2 198 f 5 a2 19d 0 6 a2 1a2 1 6 a2 1a8 2 6 a2 1ae 3 6 a2 1b4 4 6 a2 1ba 5 6 a2 1c0 6 6 a2 1c6 7 6 a2 1cc 8 6 a2 172 9 6 a2 178 a 6 a2 17e b 6 a2 184 c 6 a2 18a d 6 a2 190 e 6 a2 196 f 6 a2 19c 0 7 a2 1a2 1 7 a2 1a9 2 7 a2 1b0 3 7 a2 1b7 4 7 a2 1be 5 7 a2 1c5 6 7 a2 1cc 7 7 a2 1d3 8 7 a2 16a 9 7 a2 171 a 7 a2 178 b 7 a2 17f c 7 a2 186 d 7 a2 18d e 7 a2 194 f 7 a2 19b 0 8 a2 1a2 1 8 a2 19a 2 8 a2 192 3 8 a2 18a 4 8 a2 182 5 8 a2 17a 6 8 a2 172 7 8 a2 16a 8 8 a2 1e2 9 8 a2 1da a 8 a2 1d2 b 8 a2 1ca c 8 a2 1c2 d 8 a2 1ba e 8 a2 1b2 f 8 a2 1aa 0 9 a2 1a2 1 9 a2 19b 2 9 a2 194 3 9 a2 18d 4 9 a2 186 5 9 a2 17f 6 9 a2 178 7 9 a2 171 8 9 a2 1da 9 9 a2 1d3 a 9 a2 1cc b 9 a2 1c5 c 9 a2 1be d 9 a2 1b7 e 9 a2 1b0 f 9 a2 1a9 0 a a2 1a2 1 a a2 19c 2 a a2 196 3 a a2 190 4 a a2 18a 5 a a2 184 6 a a2 17e 7 a a2 178 8 a a2 1d2 9 a a2 1cc a a a2 1c6 b a a2 1c0 c a a2 1ba d a a2 1b4 e a a2 1ae f a a2 1a8 0 b a2 1a2 1 b a2 19d 2 b a2 198 3 b a2 193 4 b a2 18e 5 b a2 189 6 b a2 184 7 b a2 17f 8 b a2 1ca 9 b a2 1c5 a b a2 1c0 b b a2 1bb c b a2 1b6 d b a2 1b1 e b a2 1ac f b a2 1a7 0 c a2 1a2 1 c a2 19e 2 c a2 19a 3 c a2 196 4 c a2 192 5 c a2 18e 6 c a2 18a 7 c a2 186 8 c a2 1c2 9 c a2 1be a c a2 1ba b c a2 1b6 c c a2 1b2 d c a2 1ae e c a2 1aa f c a2 1a6 0 d a2 1a2 1 d a2 19f 2 d a2 19c 3 d a2 199 4 d a2 196 5 d a2 193 6 d a2 190 7 d a2 18d 8 d a2 1ba 9 d a2 1b7 a d a2 1b4 b d a2 1b1 c d a2 1ae d d a2 1ab e d a2 1a8 f d a2 1a5 0 e a2 1a2 1 e a2 1a0 2 e a2 19e 3 e a2 19c 4 e a2 19a 5 e a2 198 6 e a2 196 7 e a2 194 8 e a2 1b2 9 e a2 1b0 a e a2 1ae b e a2 1ac c e a2 1aa d e a2 1a8 e e a2 1a6 f e a2 1a4 0 f a2 1a2 1 f a2 1a1 2 f a2 1a0 3 f a2 19f 4 f a2 19e 5 f a2 19d 6 f a2 19c 7 f a2 19b 8 f a2 1aa 9 f a2 1a9 a f a2 1a8 b f a2 1a7 c f a2 1a6 d f a2 1a5 e f a2 1a4 f f a2 1a3 0 0 a3 1a3 1 0 a3 1a3 2 0 a3 1a3 3 0 a3 1a3 4 0 a3 1a3 5 0 a3 1a3 6 0 a3 1a3 7 0 a3 1a3 8 0 a3 1a3 9 0 a3 1a3 a 0 a3 1a3 b 0 a3 1a3 c 0 a3 1a3 d 0 a3 1a3 e 0 a3 1a3 f 0 a3 1a3 0 1 a3 1a3 1 1 a3 1a4 2 1 a3 1a5 3 1 a3 1a6 4 1 a3 1a7 5 1 a3 1a8 6 1 a3 1a9 7 1 a3 1aa 8 1 a3 19b 9 1 a3 19c a 1 a3 19d b 1 a3 19e c 1 a3 19f d 1 a3 1a0 e 1 a3 1a1 f 1 a3 1a2 0 2 a3 1a3 1 2 a3 1a5 2 2 a3 1a7 3 2 a3 1a9 4 2 a3 1ab 5 2 a3 1ad 6 2 a3 1af 7 2 a3 1b1 8 2 a3 193 9 2 a3 195 a 2 a3 197 b 2 a3 199 c 2 a3 19b d 2 a3 19d e 2 a3 19f f 2 a3 1a1 0 3 a3 1a3 1 3 a3 1a6 2 3 a3 1a9 3 3 a3 1ac 4 3 a3 1af 5 3 a3 1b2 6 3 a3 1b5 7 3 a3 1b8 8 3 a3 18b 9 3 a3 18e a 3 a3 191 b 3 a3 194 c 3 a3 197 d 3 a3 19a e 3 a3 19d f 3 a3 1a0 0 4 a3 1a3 1 4 a3 1a7 2 4 a3 1ab 3 4 a3 1af 4 4 a3 1b3 5 4 a3 1b7 6 4 a3 1bb 7 4 a3 1bf 8 4 a3 183 9 4 a3 187 a 4 a3 18b b 4 a3 18f c 4 a3 193 d 4 a3 197 e 4 a3 19b f 4 a3 19f 0 5 a3 1a3 1 5 a3 1a8 2 5 a3 1ad 3 5 a3 1b2 4 5 a3 1b7 5 5 a3 1bc 6 5 a3 1c1 7 5 a3 1c6 8 5 a3 17b 9 5 a3 180 a 5 a3 185 b 5 a3 18a c 5 a3 18f d 5 a3 194 e 5 a3 199 f 5 a3 19e 0 6 a3 1a3 1 6 a3 1a9 2 6 a3 1af 3 6 a3 1b5 4 6 a3 1bb 5 6 a3 1c1 6 6 a3 1c7 7 6 a3 1cd 8 6 a3 173 9 6 a3 179 a 6 a3 17f b 6 a3 185 c 6 a3 18b d 6 a3 191 e 6 a3 197 f 6 a3 19d 0 7 a3 1a3 1 7 a3 1aa 2 7 a3 1b1 3 7 a3 1b8 4 7 a3 1bf 5 7 a3 1c6 6 7 a3 1cd 7 7 a3 1d4 8 7 a3 16b 9 7 a3 172 a 7 a3 179 b 7 a3 180 c 7 a3 187 d 7 a3 18e e 7 a3 195 f 7 a3 19c 0 8 a3 1a3 1 8 a3 19b 2 8 a3 193 3 8 a3 18b 4 8 a3 183 5 8 a3 17b 6 8 a3 173 7 8 a3 16b 8 8 a3 1e3 9 8 a3 1db a 8 a3 1d3 b 8 a3 1cb c 8 a3 1c3 d 8 a3 1bb e 8 a3 1b3 f 8 a3 1ab 0 9 a3 1a3 1 9 a3 19c 2 9 a3 195 3 9 a3 18e 4 9 a3 187 5 9 a3 180 6 9 a3 179 7 9 a3 172 8 9 a3 1db 9 9 a3 1d4 a 9 a3 1cd b 9 a3 1c6 c 9 a3 1bf d 9 a3 1b8 e 9 a3 1b1 f 9 a3 1aa 0 a a3 1a3 1 a a3 19d 2 a a3 197 3 a a3 191 4 a a3 18b 5 a a3 185 6 a a3 17f 7 a a3 179 8 a a3 1d3 9 a a3 1cd a a a3 1c7 b a a3 1c1 c a a3 1bb d a a3 1b5 e a a3 1af f a a3 1a9 0 b a3 1a3 1 b a3 19e 2 b a3 199 3 b a3 194 4 b a3 18f 5 b a3 18a 6 b a3 185 7 b a3 180 8 b a3 1cb 9 b a3 1c6 a b a3 1c1 b b a3 1bc c b a3 1b7 d b a3 1b2 e b a3 1ad f b a3 1a8 0 c a3 1a3 1 c a3 19f 2 c a3 19b 3 c a3 197 4 c a3 193 5 c a3 18f 6 c a3 18b 7 c a3 187 8 c a3 1c3 9 c a3 1bf a c a3 1bb b c a3 1b7 c c a3 1b3 d c a3 1af e c a3 1ab f c a3 1a7 0 d a3 1a3 1 d a3 1a0 2 d a3 19d 3 d a3 19a 4 d a3 197 5 d a3 194 6 d a3 191 7 d a3 18e 8 d a3 1bb 9 d a3 1b8 a d a3 1b5 b d a3 1b2 c d a3 1af d d a3 1ac e d a3 1a9 f d a3 1a6 0 e a3 1a3 1 e a3 1a1 2 e a3 19f 3 e a3 19d 4 e a3 19b 5 e a3 199 6 e a3 197 7 e a3 195 8 e a3 1b3 9 e a3 1b1 a e a3 1af b e a3 1ad c e a3 1ab d e a3 1a9 e e a3 1a7 f e a3 1a5 0 f a3 1a3 1 f a3 1a2 2 f a3 1a1 3 f a3 1a0 4 f a3 19f 5 f a3 19e 6 f a3 19d 7 f a3 19c 8 f a3 1ab 9 f a3 1aa a f a3 1a9 b f a3 1a8 c f a3 1a7 d f a3 1a6 e f a3 1a5 f f a3 1a4 0 0 a4 1a4 1 0 a4 1a4 2 0 a4 1a4 3 0 a4 1a4 4 0 a4 1a4 5 0 a4 1a4 6 0 a4 1a4 7 0 a4 1a4 8 0 a4 1a4 9 0 a4 1a4 a 0 a4 1a4 b 0 a4 1a4 c 0 a4 1a4 d 0 a4 1a4 e 0 a4 1a4 f 0 a4 1a4 0 1 a4 1a4 1 1 a4 1a5 2 1 a4 1a6 3 1 a4 1a7 4 1 a4 1a8 5 1 a4 1a9 6 1 a4 1aa 7 1 a4 1ab 8 1 a4 19c 9 1 a4 19d a 1 a4 19e b 1 a4 19f c 1 a4 1a0 d 1 a4 1a1 e 1 a4 1a2 f 1 a4 1a3 0 2 a4 1a4 1 2 a4 1a6 2 2 a4 1a8 3 2 a4 1aa 4 2 a4 1ac 5 2 a4 1ae 6 2 a4 1b0 7 2 a4 1b2 8 2 a4 194 9 2 a4 196 a 2 a4 198 b 2 a4 19a c 2 a4 19c d 2 a4 19e e 2 a4 1a0 f 2 a4 1a2 0 3 a4 1a4 1 3 a4 1a7 2 3 a4 1aa 3 3 a4 1ad 4 3 a4 1b0 5 3 a4 1b3 6 3 a4 1b6 7 3 a4 1b9 8 3 a4 18c 9 3 a4 18f a 3 a4 192 b 3 a4 195 c 3 a4 198 d 3 a4 19b e 3 a4 19e f 3 a4 1a1 0 4 a4 1a4 1 4 a4 1a8 2 4 a4 1ac 3 4 a4 1b0 4 4 a4 1b4 5 4 a4 1b8 6 4 a4 1bc 7 4 a4 1c0 8 4 a4 184 9 4 a4 188 a 4 a4 18c b 4 a4 190 c 4 a4 194 d 4 a4 198 e 4 a4 19c f 4 a4 1a0 0 5 a4 1a4 1 5 a4 1a9 2 5 a4 1ae 3 5 a4 1b3 4 5 a4 1b8 5 5 a4 1bd 6 5 a4 1c2 7 5 a4 1c7 8 5 a4 17c 9 5 a4 181 a 5 a4 186 b 5 a4 18b c 5 a4 190 d 5 a4 195 e 5 a4 19a f 5 a4 19f 0 6 a4 1a4 1 6 a4 1aa 2 6 a4 1b0 3 6 a4 1b6 4 6 a4 1bc 5 6 a4 1c2 6 6 a4 1c8 7 6 a4 1ce 8 6 a4 174 9 6 a4 17a a 6 a4 180 b 6 a4 186 c 6 a4 18c d 6 a4 192 e 6 a4 198 f 6 a4 19e 0 7 a4 1a4 1 7 a4 1ab 2 7 a4 1b2 3 7 a4 1b9 4 7 a4 1c0 5 7 a4 1c7 6 7 a4 1ce 7 7 a4 1d5 8 7 a4 16c 9 7 a4 173 a 7 a4 17a b 7 a4 181 c 7 a4 188 d 7 a4 18f e 7 a4 196 f 7 a4 19d 0 8 a4 1a4 1 8 a4 19c 2 8 a4 194 3 8 a4 18c 4 8 a4 184 5 8 a4 17c 6 8 a4 174 7 8 a4 16c 8 8 a4 1e4 9 8 a4 1dc a 8 a4 1d4 b 8 a4 1cc c 8 a4 1c4 d 8 a4 1bc e 8 a4 1b4 f 8 a4 1ac 0 9 a4 1a4 1 9 a4 19d 2 9 a4 196 3 9 a4 18f 4 9 a4 188 5 9 a4 181 6 9 a4 17a 7 9 a4 173 8 9 a4 1dc 9 9 a4 1d5 a 9 a4 1ce b 9 a4 1c7 c 9 a4 1c0 d 9 a4 1b9 e 9 a4 1b2 f 9 a4 1ab 0 a a4 1a4 1 a a4 19e 2 a a4 198 3 a a4 192 4 a a4 18c 5 a a4 186 6 a a4 180 7 a a4 17a 8 a a4 1d4 9 a a4 1ce a a a4 1c8 b a a4 1c2 c a a4 1bc d a a4 1b6 e a a4 1b0 f a a4 1aa 0 b a4 1a4 1 b a4 19f 2 b a4 19a 3 b a4 195 4 b a4 190 5 b a4 18b 6 b a4 186 7 b a4 181 8 b a4 1cc 9 b a4 1c7 a b a4 1c2 b b a4 1bd c b a4 1b8 d b a4 1b3 e b a4 1ae f b a4 1a9 0 c a4 1a4 1 c a4 1a0 2 c a4 19c 3 c a4 198 4 c a4 194 5 c a4 190 6 c a4 18c 7 c a4 188 8 c a4 1c4 9 c a4 1c0 a c a4 1bc b c a4 1b8 c c a4 1b4 d c a4 1b0 e c a4 1ac f c a4 1a8 0 d a4 1a4 1 d a4 1a1 2 d a4 19e 3 d a4 19b 4 d a4 198 5 d a4 195 6 d a4 192 7 d a4 18f 8 d a4 1bc 9 d a4 1b9 a d a4 1b6 b d a4 1b3 c d a4 1b0 d d a4 1ad e d a4 1aa f d a4 1a7 0 e a4 1a4 1 e a4 1a2 2 e a4 1a0 3 e a4 19e 4 e a4 19c 5 e a4 19a 6 e a4 198 7 e a4 196 8 e a4 1b4 9 e a4 1b2 a e a4 1b0 b e a4 1ae c e a4 1ac d e a4 1aa e e a4 1a8 f e a4 1a6 0 f a4 1a4 1 f a4 1a3 2 f a4 1a2 3 f a4 1a1 4 f a4 1a0 5 f a4 19f 6 f a4 19e 7 f a4 19d 8 f a4 1ac 9 f a4 1ab a f a4 1aa b f a4 1a9 c f a4 1a8 d f a4 1a7 e f a4 1a6 f f a4 1a5 0 0 a5 1a5 1 0 a5 1a5 2 0 a5 1a5 3 0 a5 1a5 4 0 a5 1a5 5 0 a5 1a5 6 0 a5 1a5 7 0 a5 1a5 8 0 a5 1a5 9 0 a5 1a5 a 0 a5 1a5 b 0 a5 1a5 c 0 a5 1a5 d 0 a5 1a5 e 0 a5 1a5 f 0 a5 1a5 0 1 a5 1a5 1 1 a5 1a6 2 1 a5 1a7 3 1 a5 1a8 4 1 a5 1a9 5 1 a5 1aa 6 1 a5 1ab 7 1 a5 1ac 8 1 a5 19d 9 1 a5 19e a 1 a5 19f b 1 a5 1a0 c 1 a5 1a1 d 1 a5 1a2 e 1 a5 1a3 f 1 a5 1a4 0 2 a5 1a5 1 2 a5 1a7 2 2 a5 1a9 3 2 a5 1ab 4 2 a5 1ad 5 2 a5 1af 6 2 a5 1b1 7 2 a5 1b3 8 2 a5 195 9 2 a5 197 a 2 a5 199 b 2 a5 19b c 2 a5 19d d 2 a5 19f e 2 a5 1a1 f 2 a5 1a3 0 3 a5 1a5 1 3 a5 1a8 2 3 a5 1ab 3 3 a5 1ae 4 3 a5 1b1 5 3 a5 1b4 6 3 a5 1b7 7 3 a5 1ba 8 3 a5 18d 9 3 a5 190 a 3 a5 193 b 3 a5 196 c 3 a5 199 d 3 a5 19c e 3 a5 19f f 3 a5 1a2 0 4 a5 1a5 1 4 a5 1a9 2 4 a5 1ad 3 4 a5 1b1 4 4 a5 1b5 5 4 a5 1b9 6 4 a5 1bd 7 4 a5 1c1 8 4 a5 185 9 4 a5 189 a 4 a5 18d b 4 a5 191 c 4 a5 195 d 4 a5 199 e 4 a5 19d f 4 a5 1a1 0 5 a5 1a5 1 5 a5 1aa 2 5 a5 1af 3 5 a5 1b4 4 5 a5 1b9 5 5 a5 1be 6 5 a5 1c3 7 5 a5 1c8 8 5 a5 17d 9 5 a5 182 a 5 a5 187 b 5 a5 18c c 5 a5 191 d 5 a5 196 e 5 a5 19b f 5 a5 1a0 0 6 a5 1a5 1 6 a5 1ab 2 6 a5 1b1 3 6 a5 1b7 4 6 a5 1bd 5 6 a5 1c3 6 6 a5 1c9 7 6 a5 1cf 8 6 a5 175 9 6 a5 17b a 6 a5 181 b 6 a5 187 c 6 a5 18d d 6 a5 193 e 6 a5 199 f 6 a5 19f 0 7 a5 1a5 1 7 a5 1ac 2 7 a5 1b3 3 7 a5 1ba 4 7 a5 1c1 5 7 a5 1c8 6 7 a5 1cf 7 7 a5 1d6 8 7 a5 16d 9 7 a5 174 a 7 a5 17b b 7 a5 182 c 7 a5 189 d 7 a5 190 e 7 a5 197 f 7 a5 19e 0 8 a5 1a5 1 8 a5 19d 2 8 a5 195 3 8 a5 18d 4 8 a5 185 5 8 a5 17d 6 8 a5 175 7 8 a5 16d 8 8 a5 1e5 9 8 a5 1dd a 8 a5 1d5 b 8 a5 1cd c 8 a5 1c5 d 8 a5 1bd e 8 a5 1b5 f 8 a5 1ad 0 9 a5 1a5 1 9 a5 19e 2 9 a5 197 3 9 a5 190 4 9 a5 189 5 9 a5 182 6 9 a5 17b 7 9 a5 174 8 9 a5 1dd 9 9 a5 1d6 a 9 a5 1cf b 9 a5 1c8 c 9 a5 1c1 d 9 a5 1ba e 9 a5 1b3 f 9 a5 1ac 0 a a5 1a5 1 a a5 19f 2 a a5 199 3 a a5 193 4 a a5 18d 5 a a5 187 6 a a5 181 7 a a5 17b 8 a a5 1d5 9 a a5 1cf a a a5 1c9 b a a5 1c3 c a a5 1bd d a a5 1b7 e a a5 1b1 f a a5 1ab 0 b a5 1a5 1 b a5 1a0 2 b a5 19b 3 b a5 196 4 b a5 191 5 b a5 18c 6 b a5 187 7 b a5 182 8 b a5 1cd 9 b a5 1c8 a b a5 1c3 b b a5 1be c b a5 1b9 d b a5 1b4 e b a5 1af f b a5 1aa 0 c a5 1a5 1 c a5 1a1 2 c a5 19d 3 c a5 199 4 c a5 195 5 c a5 191 6 c a5 18d 7 c a5 189 8 c a5 1c5 9 c a5 1c1 a c a5 1bd b c a5 1b9 c c a5 1b5 d c a5 1b1 e c a5 1ad f c a5 1a9 0 d a5 1a5 1 d a5 1a2 2 d a5 19f 3 d a5 19c 4 d a5 199 5 d a5 196 6 d a5 193 7 d a5 190 8 d a5 1bd 9 d a5 1ba a d a5 1b7 b d a5 1b4 c d a5 1b1 d d a5 1ae e d a5 1ab f d a5 1a8 0 e a5 1a5 1 e a5 1a3 2 e a5 1a1 3 e a5 19f 4 e a5 19d 5 e a5 19b 6 e a5 199 7 e a5 197 8 e a5 1b5 9 e a5 1b3 a e a5 1b1 b e a5 1af c e a5 1ad d e a5 1ab e e a5 1a9 f e a5 1a7 0 f a5 1a5 1 f a5 1a4 2 f a5 1a3 3 f a5 1a2 4 f a5 1a1 5 f a5 1a0 6 f a5 19f 7 f a5 19e 8 f a5 1ad 9 f a5 1ac a f a5 1ab b f a5 1aa c f a5 1a9 d f a5 1a8 e f a5 1a7 f f a5 1a6 0 0 a6 1a6 1 0 a6 1a6 2 0 a6 1a6 3 0 a6 1a6 4 0 a6 1a6 5 0 a6 1a6 6 0 a6 1a6 7 0 a6 1a6 8 0 a6 1a6 9 0 a6 1a6 a 0 a6 1a6 b 0 a6 1a6 c 0 a6 1a6 d 0 a6 1a6 e 0 a6 1a6 f 0 a6 1a6 0 1 a6 1a6 1 1 a6 1a7 2 1 a6 1a8 3 1 a6 1a9 4 1 a6 1aa 5 1 a6 1ab 6 1 a6 1ac 7 1 a6 1ad 8 1 a6 19e 9 1 a6 19f a 1 a6 1a0 b 1 a6 1a1 c 1 a6 1a2 d 1 a6 1a3 e 1 a6 1a4 f 1 a6 1a5 0 2 a6 1a6 1 2 a6 1a8 2 2 a6 1aa 3 2 a6 1ac 4 2 a6 1ae 5 2 a6 1b0 6 2 a6 1b2 7 2 a6 1b4 8 2 a6 196 9 2 a6 198 a 2 a6 19a b 2 a6 19c c 2 a6 19e d 2 a6 1a0 e 2 a6 1a2 f 2 a6 1a4 0 3 a6 1a6 1 3 a6 1a9 2 3 a6 1ac 3 3 a6 1af 4 3 a6 1b2 5 3 a6 1b5 6 3 a6 1b8 7 3 a6 1bb 8 3 a6 18e 9 3 a6 191 a 3 a6 194 b 3 a6 197 c 3 a6 19a d 3 a6 19d e 3 a6 1a0 f 3 a6 1a3 0 4 a6 1a6 1 4 a6 1aa 2 4 a6 1ae 3 4 a6 1b2 4 4 a6 1b6 5 4 a6 1ba 6 4 a6 1be 7 4 a6 1c2 8 4 a6 186 9 4 a6 18a a 4 a6 18e b 4 a6 192 c 4 a6 196 d 4 a6 19a e 4 a6 19e f 4 a6 1a2 0 5 a6 1a6 1 5 a6 1ab 2 5 a6 1b0 3 5 a6 1b5 4 5 a6 1ba 5 5 a6 1bf 6 5 a6 1c4 7 5 a6 1c9 8 5 a6 17e 9 5 a6 183 a 5 a6 188 b 5 a6 18d c 5 a6 192 d 5 a6 197 e 5 a6 19c f 5 a6 1a1 0 6 a6 1a6 1 6 a6 1ac 2 6 a6 1b2 3 6 a6 1b8 4 6 a6 1be 5 6 a6 1c4 6 6 a6 1ca 7 6 a6 1d0 8 6 a6 176 9 6 a6 17c a 6 a6 182 b 6 a6 188 c 6 a6 18e d 6 a6 194 e 6 a6 19a f 6 a6 1a0 0 7 a6 1a6 1 7 a6 1ad 2 7 a6 1b4 3 7 a6 1bb 4 7 a6 1c2 5 7 a6 1c9 6 7 a6 1d0 7 7 a6 1d7 8 7 a6 16e 9 7 a6 175 a 7 a6 17c b 7 a6 183 c 7 a6 18a d 7 a6 191 e 7 a6 198 f 7 a6 19f 0 8 a6 1a6 1 8 a6 19e 2 8 a6 196 3 8 a6 18e 4 8 a6 186 5 8 a6 17e 6 8 a6 176 7 8 a6 16e 8 8 a6 1e6 9 8 a6 1de a 8 a6 1d6 b 8 a6 1ce c 8 a6 1c6 d 8 a6 1be e 8 a6 1b6 f 8 a6 1ae 0 9 a6 1a6 1 9 a6 19f 2 9 a6 198 3 9 a6 191 4 9 a6 18a 5 9 a6 183 6 9 a6 17c 7 9 a6 175 8 9 a6 1de 9 9 a6 1d7 a 9 a6 1d0 b 9 a6 1c9 c 9 a6 1c2 d 9 a6 1bb e 9 a6 1b4 f 9 a6 1ad 0 a a6 1a6 1 a a6 1a0 2 a a6 19a 3 a a6 194 4 a a6 18e 5 a a6 188 6 a a6 182 7 a a6 17c 8 a a6 1d6 9 a a6 1d0 a a a6 1ca b a a6 1c4 c a a6 1be d a a6 1b8 e a a6 1b2 f a a6 1ac 0 b a6 1a6 1 b a6 1a1 2 b a6 19c 3 b a6 197 4 b a6 192 5 b a6 18d 6 b a6 188 7 b a6 183 8 b a6 1ce 9 b a6 1c9 a b a6 1c4 b b a6 1bf c b a6 1ba d b a6 1b5 e b a6 1b0 f b a6 1ab 0 c a6 1a6 1 c a6 1a2 2 c a6 19e 3 c a6 19a 4 c a6 196 5 c a6 192 6 c a6 18e 7 c a6 18a 8 c a6 1c6 9 c a6 1c2 a c a6 1be b c a6 1ba c c a6 1b6 d c a6 1b2 e c a6 1ae f c a6 1aa 0 d a6 1a6 1 d a6 1a3 2 d a6 1a0 3 d a6 19d 4 d a6 19a 5 d a6 197 6 d a6 194 7 d a6 191 8 d a6 1be 9 d a6 1bb a d a6 1b8 b d a6 1b5 c d a6 1b2 d d a6 1af e d a6 1ac f d a6 1a9 0 e a6 1a6 1 e a6 1a4 2 e a6 1a2 3 e a6 1a0 4 e a6 19e 5 e a6 19c 6 e a6 19a 7 e a6 198 8 e a6 1b6 9 e a6 1b4 a e a6 1b2 b e a6 1b0 c e a6 1ae d e a6 1ac e e a6 1aa f e a6 1a8 0 f a6 1a6 1 f a6 1a5 2 f a6 1a4 3 f a6 1a3 4 f a6 1a2 5 f a6 1a1 6 f a6 1a0 7 f a6 19f 8 f a6 1ae 9 f a6 1ad a f a6 1ac b f a6 1ab c f a6 1aa d f a6 1a9 e f a6 1a8 f f a6 1a7 0 0 a7 1a7 1 0 a7 1a7 2 0 a7 1a7 3 0 a7 1a7 4 0 a7 1a7 5 0 a7 1a7 6 0 a7 1a7 7 0 a7 1a7 8 0 a7 1a7 9 0 a7 1a7 a 0 a7 1a7 b 0 a7 1a7 c 0 a7 1a7 d 0 a7 1a7 e 0 a7 1a7 f 0 a7 1a7 0 1 a7 1a7 1 1 a7 1a8 2 1 a7 1a9 3 1 a7 1aa 4 1 a7 1ab 5 1 a7 1ac 6 1 a7 1ad 7 1 a7 1ae 8 1 a7 19f 9 1 a7 1a0 a 1 a7 1a1 b 1 a7 1a2 c 1 a7 1a3 d 1 a7 1a4 e 1 a7 1a5 f 1 a7 1a6 0 2 a7 1a7 1 2 a7 1a9 2 2 a7 1ab 3 2 a7 1ad 4 2 a7 1af 5 2 a7 1b1 6 2 a7 1b3 7 2 a7 1b5 8 2 a7 197 9 2 a7 199 a 2 a7 19b b 2 a7 19d c 2 a7 19f d 2 a7 1a1 e 2 a7 1a3 f 2 a7 1a5 0 3 a7 1a7 1 3 a7 1aa 2 3 a7 1ad 3 3 a7 1b0 4 3 a7 1b3 5 3 a7 1b6 6 3 a7 1b9 7 3 a7 1bc 8 3 a7 18f 9 3 a7 192 a 3 a7 195 b 3 a7 198 c 3 a7 19b d 3 a7 19e e 3 a7 1a1 f 3 a7 1a4 0 4 a7 1a7 1 4 a7 1ab 2 4 a7 1af 3 4 a7 1b3 4 4 a7 1b7 5 4 a7 1bb 6 4 a7 1bf 7 4 a7 1c3 8 4 a7 187 9 4 a7 18b a 4 a7 18f b 4 a7 193 c 4 a7 197 d 4 a7 19b e 4 a7 19f f 4 a7 1a3 0 5 a7 1a7 1 5 a7 1ac 2 5 a7 1b1 3 5 a7 1b6 4 5 a7 1bb 5 5 a7 1c0 6 5 a7 1c5 7 5 a7 1ca 8 5 a7 17f 9 5 a7 184 a 5 a7 189 b 5 a7 18e c 5 a7 193 d 5 a7 198 e 5 a7 19d f 5 a7 1a2 0 6 a7 1a7 1 6 a7 1ad 2 6 a7 1b3 3 6 a7 1b9 4 6 a7 1bf 5 6 a7 1c5 6 6 a7 1cb 7 6 a7 1d1 8 6 a7 177 9 6 a7 17d a 6 a7 183 b 6 a7 189 c 6 a7 18f d 6 a7 195 e 6 a7 19b f 6 a7 1a1 0 7 a7 1a7 1 7 a7 1ae 2 7 a7 1b5 3 7 a7 1bc 4 7 a7 1c3 5 7 a7 1ca 6 7 a7 1d1 7 7 a7 1d8 8 7 a7 16f 9 7 a7 176 a 7 a7 17d b 7 a7 184 c 7 a7 18b d 7 a7 192 e 7 a7 199 f 7 a7 1a0 0 8 a7 1a7 1 8 a7 19f 2 8 a7 197 3 8 a7 18f 4 8 a7 187 5 8 a7 17f 6 8 a7 177 7 8 a7 16f 8 8 a7 1e7 9 8 a7 1df a 8 a7 1d7 b 8 a7 1cf c 8 a7 1c7 d 8 a7 1bf e 8 a7 1b7 f 8 a7 1af 0 9 a7 1a7 1 9 a7 1a0 2 9 a7 199 3 9 a7 192 4 9 a7 18b 5 9 a7 184 6 9 a7 17d 7 9 a7 176 8 9 a7 1df 9 9 a7 1d8 a 9 a7 1d1 b 9 a7 1ca c 9 a7 1c3 d 9 a7 1bc e 9 a7 1b5 f 9 a7 1ae 0 a a7 1a7 1 a a7 1a1 2 a a7 19b 3 a a7 195 4 a a7 18f 5 a a7 189 6 a a7 183 7 a a7 17d 8 a a7 1d7 9 a a7 1d1 a a a7 1cb b a a7 1c5 c a a7 1bf d a a7 1b9 e a a7 1b3 f a a7 1ad 0 b a7 1a7 1 b a7 1a2 2 b a7 19d 3 b a7 198 4 b a7 193 5 b a7 18e 6 b a7 189 7 b a7 184 8 b a7 1cf 9 b a7 1ca a b a7 1c5 b b a7 1c0 c b a7 1bb d b a7 1b6 e b a7 1b1 f b a7 1ac 0 c a7 1a7 1 c a7 1a3 2 c a7 19f 3 c a7 19b 4 c a7 197 5 c a7 193 6 c a7 18f 7 c a7 18b 8 c a7 1c7 9 c a7 1c3 a c a7 1bf b c a7 1bb c c a7 1b7 d c a7 1b3 e c a7 1af f c a7 1ab 0 d a7 1a7 1 d a7 1a4 2 d a7 1a1 3 d a7 19e 4 d a7 19b 5 d a7 198 6 d a7 195 7 d a7 192 8 d a7 1bf 9 d a7 1bc a d a7 1b9 b d a7 1b6 c d a7 1b3 d d a7 1b0 e d a7 1ad f d a7 1aa 0 e a7 1a7 1 e a7 1a5 2 e a7 1a3 3 e a7 1a1 4 e a7 19f 5 e a7 19d 6 e a7 19b 7 e a7 199 8 e a7 1b7 9 e a7 1b5 a e a7 1b3 b e a7 1b1 c e a7 1af d e a7 1ad e e a7 1ab f e a7 1a9 0 f a7 1a7 1 f a7 1a6 2 f a7 1a5 3 f a7 1a4 4 f a7 1a3 5 f a7 1a2 6 f a7 1a1 7 f a7 1a0 8 f a7 1af 9 f a7 1ae a f a7 1ad b f a7 1ac c f a7 1ab d f a7 1aa e f a7 1a9 f f a7 1a8 0 0 a8 1a8 1 0 a8 1a8 2 0 a8 1a8 3 0 a8 1a8 4 0 a8 1a8 5 0 a8 1a8 6 0 a8 1a8 7 0 a8 1a8 8 0 a8 1a8 9 0 a8 1a8 a 0 a8 1a8 b 0 a8 1a8 c 0 a8 1a8 d 0 a8 1a8 e 0 a8 1a8 f 0 a8 1a8 0 1 a8 1a8 1 1 a8 1a9 2 1 a8 1aa 3 1 a8 1ab 4 1 a8 1ac 5 1 a8 1ad 6 1 a8 1ae 7 1 a8 1af 8 1 a8 1a0 9 1 a8 1a1 a 1 a8 1a2 b 1 a8 1a3 c 1 a8 1a4 d 1 a8 1a5 e 1 a8 1a6 f 1 a8 1a7 0 2 a8 1a8 1 2 a8 1aa 2 2 a8 1ac 3 2 a8 1ae 4 2 a8 1b0 5 2 a8 1b2 6 2 a8 1b4 7 2 a8 1b6 8 2 a8 198 9 2 a8 19a a 2 a8 19c b 2 a8 19e c 2 a8 1a0 d 2 a8 1a2 e 2 a8 1a4 f 2 a8 1a6 0 3 a8 1a8 1 3 a8 1ab 2 3 a8 1ae 3 3 a8 1b1 4 3 a8 1b4 5 3 a8 1b7 6 3 a8 1ba 7 3 a8 1bd 8 3 a8 190 9 3 a8 193 a 3 a8 196 b 3 a8 199 c 3 a8 19c d 3 a8 19f e 3 a8 1a2 f 3 a8 1a5 0 4 a8 1a8 1 4 a8 1ac 2 4 a8 1b0 3 4 a8 1b4 4 4 a8 1b8 5 4 a8 1bc 6 4 a8 1c0 7 4 a8 1c4 8 4 a8 188 9 4 a8 18c a 4 a8 190 b 4 a8 194 c 4 a8 198 d 4 a8 19c e 4 a8 1a0 f 4 a8 1a4 0 5 a8 1a8 1 5 a8 1ad 2 5 a8 1b2 3 5 a8 1b7 4 5 a8 1bc 5 5 a8 1c1 6 5 a8 1c6 7 5 a8 1cb 8 5 a8 180 9 5 a8 185 a 5 a8 18a b 5 a8 18f c 5 a8 194 d 5 a8 199 e 5 a8 19e f 5 a8 1a3 0 6 a8 1a8 1 6 a8 1ae 2 6 a8 1b4 3 6 a8 1ba 4 6 a8 1c0 5 6 a8 1c6 6 6 a8 1cc 7 6 a8 1d2 8 6 a8 178 9 6 a8 17e a 6 a8 184 b 6 a8 18a c 6 a8 190 d 6 a8 196 e 6 a8 19c f 6 a8 1a2 0 7 a8 1a8 1 7 a8 1af 2 7 a8 1b6 3 7 a8 1bd 4 7 a8 1c4 5 7 a8 1cb 6 7 a8 1d2 7 7 a8 1d9 8 7 a8 170 9 7 a8 177 a 7 a8 17e b 7 a8 185 c 7 a8 18c d 7 a8 193 e 7 a8 19a f 7 a8 1a1 0 8 a8 1a8 1 8 a8 1a0 2 8 a8 198 3 8 a8 190 4 8 a8 188 5 8 a8 180 6 8 a8 178 7 8 a8 170 8 8 a8 1e8 9 8 a8 1e0 a 8 a8 1d8 b 8 a8 1d0 c 8 a8 1c8 d 8 a8 1c0 e 8 a8 1b8 f 8 a8 1b0 0 9 a8 1a8 1 9 a8 1a1 2 9 a8 19a 3 9 a8 193 4 9 a8 18c 5 9 a8 185 6 9 a8 17e 7 9 a8 177 8 9 a8 1e0 9 9 a8 1d9 a 9 a8 1d2 b 9 a8 1cb c 9 a8 1c4 d 9 a8 1bd e 9 a8 1b6 f 9 a8 1af 0 a a8 1a8 1 a a8 1a2 2 a a8 19c 3 a a8 196 4 a a8 190 5 a a8 18a 6 a a8 184 7 a a8 17e 8 a a8 1d8 9 a a8 1d2 a a a8 1cc b a a8 1c6 c a a8 1c0 d a a8 1ba e a a8 1b4 f a a8 1ae 0 b a8 1a8 1 b a8 1a3 2 b a8 19e 3 b a8 199 4 b a8 194 5 b a8 18f 6 b a8 18a 7 b a8 185 8 b a8 1d0 9 b a8 1cb a b a8 1c6 b b a8 1c1 c b a8 1bc d b a8 1b7 e b a8 1b2 f b a8 1ad 0 c a8 1a8 1 c a8 1a4 2 c a8 1a0 3 c a8 19c 4 c a8 198 5 c a8 194 6 c a8 190 7 c a8 18c 8 c a8 1c8 9 c a8 1c4 a c a8 1c0 b c a8 1bc c c a8 1b8 d c a8 1b4 e c a8 1b0 f c a8 1ac 0 d a8 1a8 1 d a8 1a5 2 d a8 1a2 3 d a8 19f 4 d a8 19c 5 d a8 199 6 d a8 196 7 d a8 193 8 d a8 1c0 9 d a8 1bd a d a8 1ba b d a8 1b7 c d a8 1b4 d d a8 1b1 e d a8 1ae f d a8 1ab 0 e a8 1a8 1 e a8 1a6 2 e a8 1a4 3 e a8 1a2 4 e a8 1a0 5 e a8 19e 6 e a8 19c 7 e a8 19a 8 e a8 1b8 9 e a8 1b6 a e a8 1b4 b e a8 1b2 c e a8 1b0 d e a8 1ae e e a8 1ac f e a8 1aa 0 f a8 1a8 1 f a8 1a7 2 f a8 1a6 3 f a8 1a5 4 f a8 1a4 5 f a8 1a3 6 f a8 1a2 7 f a8 1a1 8 f a8 1b0 9 f a8 1af a f a8 1ae b f a8 1ad c f a8 1ac d f a8 1ab e f a8 1aa f f a8 1a9 0 0 a9 1a9 1 0 a9 1a9 2 0 a9 1a9 3 0 a9 1a9 4 0 a9 1a9 5 0 a9 1a9 6 0 a9 1a9 7 0 a9 1a9 8 0 a9 1a9 9 0 a9 1a9 a 0 a9 1a9 b 0 a9 1a9 c 0 a9 1a9 d 0 a9 1a9 e 0 a9 1a9 f 0 a9 1a9 0 1 a9 1a9 1 1 a9 1aa 2 1 a9 1ab 3 1 a9 1ac 4 1 a9 1ad 5 1 a9 1ae 6 1 a9 1af 7 1 a9 1b0 8 1 a9 1a1 9 1 a9 1a2 a 1 a9 1a3 b 1 a9 1a4 c 1 a9 1a5 d 1 a9 1a6 e 1 a9 1a7 f 1 a9 1a8 0 2 a9 1a9 1 2 a9 1ab 2 2 a9 1ad 3 2 a9 1af 4 2 a9 1b1 5 2 a9 1b3 6 2 a9 1b5 7 2 a9 1b7 8 2 a9 199 9 2 a9 19b a 2 a9 19d b 2 a9 19f c 2 a9 1a1 d 2 a9 1a3 e 2 a9 1a5 f 2 a9 1a7 0 3 a9 1a9 1 3 a9 1ac 2 3 a9 1af 3 3 a9 1b2 4 3 a9 1b5 5 3 a9 1b8 6 3 a9 1bb 7 3 a9 1be 8 3 a9 191 9 3 a9 194 a 3 a9 197 b 3 a9 19a c 3 a9 19d d 3 a9 1a0 e 3 a9 1a3 f 3 a9 1a6 0 4 a9 1a9 1 4 a9 1ad 2 4 a9 1b1 3 4 a9 1b5 4 4 a9 1b9 5 4 a9 1bd 6 4 a9 1c1 7 4 a9 1c5 8 4 a9 189 9 4 a9 18d a 4 a9 191 b 4 a9 195 c 4 a9 199 d 4 a9 19d e 4 a9 1a1 f 4 a9 1a5 0 5 a9 1a9 1 5 a9 1ae 2 5 a9 1b3 3 5 a9 1b8 4 5 a9 1bd 5 5 a9 1c2 6 5 a9 1c7 7 5 a9 1cc 8 5 a9 181 9 5 a9 186 a 5 a9 18b b 5 a9 190 c 5 a9 195 d 5 a9 19a e 5 a9 19f f 5 a9 1a4 0 6 a9 1a9 1 6 a9 1af 2 6 a9 1b5 3 6 a9 1bb 4 6 a9 1c1 5 6 a9 1c7 6 6 a9 1cd 7 6 a9 1d3 8 6 a9 179 9 6 a9 17f a 6 a9 185 b 6 a9 18b c 6 a9 191 d 6 a9 197 e 6 a9 19d f 6 a9 1a3 0 7 a9 1a9 1 7 a9 1b0 2 7 a9 1b7 3 7 a9 1be 4 7 a9 1c5 5 7 a9 1cc 6 7 a9 1d3 7 7 a9 1da 8 7 a9 171 9 7 a9 178 a 7 a9 17f b 7 a9 186 c 7 a9 18d d 7 a9 194 e 7 a9 19b f 7 a9 1a2 0 8 a9 1a9 1 8 a9 1a1 2 8 a9 199 3 8 a9 191 4 8 a9 189 5 8 a9 181 6 8 a9 179 7 8 a9 171 8 8 a9 1e9 9 8 a9 1e1 a 8 a9 1d9 b 8 a9 1d1 c 8 a9 1c9 d 8 a9 1c1 e 8 a9 1b9 f 8 a9 1b1 0 9 a9 1a9 1 9 a9 1a2 2 9 a9 19b 3 9 a9 194 4 9 a9 18d 5 9 a9 186 6 9 a9 17f 7 9 a9 178 8 9 a9 1e1 9 9 a9 1da a 9 a9 1d3 b 9 a9 1cc c 9 a9 1c5 d 9 a9 1be e 9 a9 1b7 f 9 a9 1b0 0 a a9 1a9 1 a a9 1a3 2 a a9 19d 3 a a9 197 4 a a9 191 5 a a9 18b 6 a a9 185 7 a a9 17f 8 a a9 1d9 9 a a9 1d3 a a a9 1cd b a a9 1c7 c a a9 1c1 d a a9 1bb e a a9 1b5 f a a9 1af 0 b a9 1a9 1 b a9 1a4 2 b a9 19f 3 b a9 19a 4 b a9 195 5 b a9 190 6 b a9 18b 7 b a9 186 8 b a9 1d1 9 b a9 1cc a b a9 1c7 b b a9 1c2 c b a9 1bd d b a9 1b8 e b a9 1b3 f b a9 1ae 0 c a9 1a9 1 c a9 1a5 2 c a9 1a1 3 c a9 19d 4 c a9 199 5 c a9 195 6 c a9 191 7 c a9 18d 8 c a9 1c9 9 c a9 1c5 a c a9 1c1 b c a9 1bd c c a9 1b9 d c a9 1b5 e c a9 1b1 f c a9 1ad 0 d a9 1a9 1 d a9 1a6 2 d a9 1a3 3 d a9 1a0 4 d a9 19d 5 d a9 19a 6 d a9 197 7 d a9 194 8 d a9 1c1 9 d a9 1be a d a9 1bb b d a9 1b8 c d a9 1b5 d d a9 1b2 e d a9 1af f d a9 1ac 0 e a9 1a9 1 e a9 1a7 2 e a9 1a5 3 e a9 1a3 4 e a9 1a1 5 e a9 19f 6 e a9 19d 7 e a9 19b 8 e a9 1b9 9 e a9 1b7 a e a9 1b5 b e a9 1b3 c e a9 1b1 d e a9 1af e e a9 1ad f e a9 1ab 0 f a9 1a9 1 f a9 1a8 2 f a9 1a7 3 f a9 1a6 4 f a9 1a5 5 f a9 1a4 6 f a9 1a3 7 f a9 1a2 8 f a9 1b1 9 f a9 1b0 a f a9 1af b f a9 1ae c f a9 1ad d f a9 1ac e f a9 1ab f f a9 1aa 0 0 aa 1aa 1 0 aa 1aa 2 0 aa 1aa 3 0 aa 1aa 4 0 aa 1aa 5 0 aa 1aa 6 0 aa 1aa 7 0 aa 1aa 8 0 aa 1aa 9 0 aa 1aa a 0 aa 1aa b 0 aa 1aa c 0 aa 1aa d 0 aa 1aa e 0 aa 1aa f 0 aa 1aa 0 1 aa 1aa 1 1 aa 1ab 2 1 aa 1ac 3 1 aa 1ad 4 1 aa 1ae 5 1 aa 1af 6 1 aa 1b0 7 1 aa 1b1 8 1 aa 1a2 9 1 aa 1a3 a 1 aa 1a4 b 1 aa 1a5 c 1 aa 1a6 d 1 aa 1a7 e 1 aa 1a8 f 1 aa 1a9 0 2 aa 1aa 1 2 aa 1ac 2 2 aa 1ae 3 2 aa 1b0 4 2 aa 1b2 5 2 aa 1b4 6 2 aa 1b6 7 2 aa 1b8 8 2 aa 19a 9 2 aa 19c a 2 aa 19e b 2 aa 1a0 c 2 aa 1a2 d 2 aa 1a4 e 2 aa 1a6 f 2 aa 1a8 0 3 aa 1aa 1 3 aa 1ad 2 3 aa 1b0 3 3 aa 1b3 4 3 aa 1b6 5 3 aa 1b9 6 3 aa 1bc 7 3 aa 1bf 8 3 aa 192 9 3 aa 195 a 3 aa 198 b 3 aa 19b c 3 aa 19e d 3 aa 1a1 e 3 aa 1a4 f 3 aa 1a7 0 4 aa 1aa 1 4 aa 1ae 2 4 aa 1b2 3 4 aa 1b6 4 4 aa 1ba 5 4 aa 1be 6 4 aa 1c2 7 4 aa 1c6 8 4 aa 18a 9 4 aa 18e a 4 aa 192 b 4 aa 196 c 4 aa 19a d 4 aa 19e e 4 aa 1a2 f 4 aa 1a6 0 5 aa 1aa 1 5 aa 1af 2 5 aa 1b4 3 5 aa 1b9 4 5 aa 1be 5 5 aa 1c3 6 5 aa 1c8 7 5 aa 1cd 8 5 aa 182 9 5 aa 187 a 5 aa 18c b 5 aa 191 c 5 aa 196 d 5 aa 19b e 5 aa 1a0 f 5 aa 1a5 0 6 aa 1aa 1 6 aa 1b0 2 6 aa 1b6 3 6 aa 1bc 4 6 aa 1c2 5 6 aa 1c8 6 6 aa 1ce 7 6 aa 1d4 8 6 aa 17a 9 6 aa 180 a 6 aa 186 b 6 aa 18c c 6 aa 192 d 6 aa 198 e 6 aa 19e f 6 aa 1a4 0 7 aa 1aa 1 7 aa 1b1 2 7 aa 1b8 3 7 aa 1bf 4 7 aa 1c6 5 7 aa 1cd 6 7 aa 1d4 7 7 aa 1db 8 7 aa 172 9 7 aa 179 a 7 aa 180 b 7 aa 187 c 7 aa 18e d 7 aa 195 e 7 aa 19c f 7 aa 1a3 0 8 aa 1aa 1 8 aa 1a2 2 8 aa 19a 3 8 aa 192 4 8 aa 18a 5 8 aa 182 6 8 aa 17a 7 8 aa 172 8 8 aa 1ea 9 8 aa 1e2 a 8 aa 1da b 8 aa 1d2 c 8 aa 1ca d 8 aa 1c2 e 8 aa 1ba f 8 aa 1b2 0 9 aa 1aa 1 9 aa 1a3 2 9 aa 19c 3 9 aa 195 4 9 aa 18e 5 9 aa 187 6 9 aa 180 7 9 aa 179 8 9 aa 1e2 9 9 aa 1db a 9 aa 1d4 b 9 aa 1cd c 9 aa 1c6 d 9 aa 1bf e 9 aa 1b8 f 9 aa 1b1 0 a aa 1aa 1 a aa 1a4 2 a aa 19e 3 a aa 198 4 a aa 192 5 a aa 18c 6 a aa 186 7 a aa 180 8 a aa 1da 9 a aa 1d4 a a aa 1ce b a aa 1c8 c a aa 1c2 d a aa 1bc e a aa 1b6 f a aa 1b0 0 b aa 1aa 1 b aa 1a5 2 b aa 1a0 3 b aa 19b 4 b aa 196 5 b aa 191 6 b aa 18c 7 b aa 187 8 b aa 1d2 9 b aa 1cd a b aa 1c8 b b aa 1c3 c b aa 1be d b aa 1b9 e b aa 1b4 f b aa 1af 0 c aa 1aa 1 c aa 1a6 2 c aa 1a2 3 c aa 19e 4 c aa 19a 5 c aa 196 6 c aa 192 7 c aa 18e 8 c aa 1ca 9 c aa 1c6 a c aa 1c2 b c aa 1be c c aa 1ba d c aa 1b6 e c aa 1b2 f c aa 1ae 0 d aa 1aa 1 d aa 1a7 2 d aa 1a4 3 d aa 1a1 4 d aa 19e 5 d aa 19b 6 d aa 198 7 d aa 195 8 d aa 1c2 9 d aa 1bf a d aa 1bc b d aa 1b9 c d aa 1b6 d d aa 1b3 e d aa 1b0 f d aa 1ad 0 e aa 1aa 1 e aa 1a8 2 e aa 1a6 3 e aa 1a4 4 e aa 1a2 5 e aa 1a0 6 e aa 19e 7 e aa 19c 8 e aa 1ba 9 e aa 1b8 a e aa 1b6 b e aa 1b4 c e aa 1b2 d e aa 1b0 e e aa 1ae f e aa 1ac 0 f aa 1aa 1 f aa 1a9 2 f aa 1a8 3 f aa 1a7 4 f aa 1a6 5 f aa 1a5 6 f aa 1a4 7 f aa 1a3 8 f aa 1b2 9 f aa 1b1 a f aa 1b0 b f aa 1af c f aa 1ae d f aa 1ad e f aa 1ac f f aa 1ab 0 0 ab 1ab 1 0 ab 1ab 2 0 ab 1ab 3 0 ab 1ab 4 0 ab 1ab 5 0 ab 1ab 6 0 ab 1ab 7 0 ab 1ab 8 0 ab 1ab 9 0 ab 1ab a 0 ab 1ab b 0 ab 1ab c 0 ab 1ab d 0 ab 1ab e 0 ab 1ab f 0 ab 1ab 0 1 ab 1ab 1 1 ab 1ac 2 1 ab 1ad 3 1 ab 1ae 4 1 ab 1af 5 1 ab 1b0 6 1 ab 1b1 7 1 ab 1b2 8 1 ab 1a3 9 1 ab 1a4 a 1 ab 1a5 b 1 ab 1a6 c 1 ab 1a7 d 1 ab 1a8 e 1 ab 1a9 f 1 ab 1aa 0 2 ab 1ab 1 2 ab 1ad 2 2 ab 1af 3 2 ab 1b1 4 2 ab 1b3 5 2 ab 1b5 6 2 ab 1b7 7 2 ab 1b9 8 2 ab 19b 9 2 ab 19d a 2 ab 19f b 2 ab 1a1 c 2 ab 1a3 d 2 ab 1a5 e 2 ab 1a7 f 2 ab 1a9 0 3 ab 1ab 1 3 ab 1ae 2 3 ab 1b1 3 3 ab 1b4 4 3 ab 1b7 5 3 ab 1ba 6 3 ab 1bd 7 3 ab 1c0 8 3 ab 193 9 3 ab 196 a 3 ab 199 b 3 ab 19c c 3 ab 19f d 3 ab 1a2 e 3 ab 1a5 f 3 ab 1a8 0 4 ab 1ab 1 4 ab 1af 2 4 ab 1b3 3 4 ab 1b7 4 4 ab 1bb 5 4 ab 1bf 6 4 ab 1c3 7 4 ab 1c7 8 4 ab 18b 9 4 ab 18f a 4 ab 193 b 4 ab 197 c 4 ab 19b d 4 ab 19f e 4 ab 1a3 f 4 ab 1a7 0 5 ab 1ab 1 5 ab 1b0 2 5 ab 1b5 3 5 ab 1ba 4 5 ab 1bf 5 5 ab 1c4 6 5 ab 1c9 7 5 ab 1ce 8 5 ab 183 9 5 ab 188 a 5 ab 18d b 5 ab 192 c 5 ab 197 d 5 ab 19c e 5 ab 1a1 f 5 ab 1a6 0 6 ab 1ab 1 6 ab 1b1 2 6 ab 1b7 3 6 ab 1bd 4 6 ab 1c3 5 6 ab 1c9 6 6 ab 1cf 7 6 ab 1d5 8 6 ab 17b 9 6 ab 181 a 6 ab 187 b 6 ab 18d c 6 ab 193 d 6 ab 199 e 6 ab 19f f 6 ab 1a5 0 7 ab 1ab 1 7 ab 1b2 2 7 ab 1b9 3 7 ab 1c0 4 7 ab 1c7 5 7 ab 1ce 6 7 ab 1d5 7 7 ab 1dc 8 7 ab 173 9 7 ab 17a a 7 ab 181 b 7 ab 188 c 7 ab 18f d 7 ab 196 e 7 ab 19d f 7 ab 1a4 0 8 ab 1ab 1 8 ab 1a3 2 8 ab 19b 3 8 ab 193 4 8 ab 18b 5 8 ab 183 6 8 ab 17b 7 8 ab 173 8 8 ab 1eb 9 8 ab 1e3 a 8 ab 1db b 8 ab 1d3 c 8 ab 1cb d 8 ab 1c3 e 8 ab 1bb f 8 ab 1b3 0 9 ab 1ab 1 9 ab 1a4 2 9 ab 19d 3 9 ab 196 4 9 ab 18f 5 9 ab 188 6 9 ab 181 7 9 ab 17a 8 9 ab 1e3 9 9 ab 1dc a 9 ab 1d5 b 9 ab 1ce c 9 ab 1c7 d 9 ab 1c0 e 9 ab 1b9 f 9 ab 1b2 0 a ab 1ab 1 a ab 1a5 2 a ab 19f 3 a ab 199 4 a ab 193 5 a ab 18d 6 a ab 187 7 a ab 181 8 a ab 1db 9 a ab 1d5 a a ab 1cf b a ab 1c9 c a ab 1c3 d a ab 1bd e a ab 1b7 f a ab 1b1 0 b ab 1ab 1 b ab 1a6 2 b ab 1a1 3 b ab 19c 4 b ab 197 5 b ab 192 6 b ab 18d 7 b ab 188 8 b ab 1d3 9 b ab 1ce a b ab 1c9 b b ab 1c4 c b ab 1bf d b ab 1ba e b ab 1b5 f b ab 1b0 0 c ab 1ab 1 c ab 1a7 2 c ab 1a3 3 c ab 19f 4 c ab 19b 5 c ab 197 6 c ab 193 7 c ab 18f 8 c ab 1cb 9 c ab 1c7 a c ab 1c3 b c ab 1bf c c ab 1bb d c ab 1b7 e c ab 1b3 f c ab 1af 0 d ab 1ab 1 d ab 1a8 2 d ab 1a5 3 d ab 1a2 4 d ab 19f 5 d ab 19c 6 d ab 199 7 d ab 196 8 d ab 1c3 9 d ab 1c0 a d ab 1bd b d ab 1ba c d ab 1b7 d d ab 1b4 e d ab 1b1 f d ab 1ae 0 e ab 1ab 1 e ab 1a9 2 e ab 1a7 3 e ab 1a5 4 e ab 1a3 5 e ab 1a1 6 e ab 19f 7 e ab 19d 8 e ab 1bb 9 e ab 1b9 a e ab 1b7 b e ab 1b5 c e ab 1b3 d e ab 1b1 e e ab 1af f e ab 1ad 0 f ab 1ab 1 f ab 1aa 2 f ab 1a9 3 f ab 1a8 4 f ab 1a7 5 f ab 1a6 6 f ab 1a5 7 f ab 1a4 8 f ab 1b3 9 f ab 1b2 a f ab 1b1 b f ab 1b0 c f ab 1af d f ab 1ae e f ab 1ad f f ab 1ac 0 0 ac 1ac 1 0 ac 1ac 2 0 ac 1ac 3 0 ac 1ac 4 0 ac 1ac 5 0 ac 1ac 6 0 ac 1ac 7 0 ac 1ac 8 0 ac 1ac 9 0 ac 1ac a 0 ac 1ac b 0 ac 1ac c 0 ac 1ac d 0 ac 1ac e 0 ac 1ac f 0 ac 1ac 0 1 ac 1ac 1 1 ac 1ad 2 1 ac 1ae 3 1 ac 1af 4 1 ac 1b0 5 1 ac 1b1 6 1 ac 1b2 7 1 ac 1b3 8 1 ac 1a4 9 1 ac 1a5 a 1 ac 1a6 b 1 ac 1a7 c 1 ac 1a8 d 1 ac 1a9 e 1 ac 1aa f 1 ac 1ab 0 2 ac 1ac 1 2 ac 1ae 2 2 ac 1b0 3 2 ac 1b2 4 2 ac 1b4 5 2 ac 1b6 6 2 ac 1b8 7 2 ac 1ba 8 2 ac 19c 9 2 ac 19e a 2 ac 1a0 b 2 ac 1a2 c 2 ac 1a4 d 2 ac 1a6 e 2 ac 1a8 f 2 ac 1aa 0 3 ac 1ac 1 3 ac 1af 2 3 ac 1b2 3 3 ac 1b5 4 3 ac 1b8 5 3 ac 1bb 6 3 ac 1be 7 3 ac 1c1 8 3 ac 194 9 3 ac 197 a 3 ac 19a b 3 ac 19d c 3 ac 1a0 d 3 ac 1a3 e 3 ac 1a6 f 3 ac 1a9 0 4 ac 1ac 1 4 ac 1b0 2 4 ac 1b4 3 4 ac 1b8 4 4 ac 1bc 5 4 ac 1c0 6 4 ac 1c4 7 4 ac 1c8 8 4 ac 18c 9 4 ac 190 a 4 ac 194 b 4 ac 198 c 4 ac 19c d 4 ac 1a0 e 4 ac 1a4 f 4 ac 1a8 0 5 ac 1ac 1 5 ac 1b1 2 5 ac 1b6 3 5 ac 1bb 4 5 ac 1c0 5 5 ac 1c5 6 5 ac 1ca 7 5 ac 1cf 8 5 ac 184 9 5 ac 189 a 5 ac 18e b 5 ac 193 c 5 ac 198 d 5 ac 19d e 5 ac 1a2 f 5 ac 1a7 0 6 ac 1ac 1 6 ac 1b2 2 6 ac 1b8 3 6 ac 1be 4 6 ac 1c4 5 6 ac 1ca 6 6 ac 1d0 7 6 ac 1d6 8 6 ac 17c 9 6 ac 182 a 6 ac 188 b 6 ac 18e c 6 ac 194 d 6 ac 19a e 6 ac 1a0 f 6 ac 1a6 0 7 ac 1ac 1 7 ac 1b3 2 7 ac 1ba 3 7 ac 1c1 4 7 ac 1c8 5 7 ac 1cf 6 7 ac 1d6 7 7 ac 1dd 8 7 ac 174 9 7 ac 17b a 7 ac 182 b 7 ac 189 c 7 ac 190 d 7 ac 197 e 7 ac 19e f 7 ac 1a5 0 8 ac 1ac 1 8 ac 1a4 2 8 ac 19c 3 8 ac 194 4 8 ac 18c 5 8 ac 184 6 8 ac 17c 7 8 ac 174 8 8 ac 1ec 9 8 ac 1e4 a 8 ac 1dc b 8 ac 1d4 c 8 ac 1cc d 8 ac 1c4 e 8 ac 1bc f 8 ac 1b4 0 9 ac 1ac 1 9 ac 1a5 2 9 ac 19e 3 9 ac 197 4 9 ac 190 5 9 ac 189 6 9 ac 182 7 9 ac 17b 8 9 ac 1e4 9 9 ac 1dd a 9 ac 1d6 b 9 ac 1cf c 9 ac 1c8 d 9 ac 1c1 e 9 ac 1ba f 9 ac 1b3 0 a ac 1ac 1 a ac 1a6 2 a ac 1a0 3 a ac 19a 4 a ac 194 5 a ac 18e 6 a ac 188 7 a ac 182 8 a ac 1dc 9 a ac 1d6 a a ac 1d0 b a ac 1ca c a ac 1c4 d a ac 1be e a ac 1b8 f a ac 1b2 0 b ac 1ac 1 b ac 1a7 2 b ac 1a2 3 b ac 19d 4 b ac 198 5 b ac 193 6 b ac 18e 7 b ac 189 8 b ac 1d4 9 b ac 1cf a b ac 1ca b b ac 1c5 c b ac 1c0 d b ac 1bb e b ac 1b6 f b ac 1b1 0 c ac 1ac 1 c ac 1a8 2 c ac 1a4 3 c ac 1a0 4 c ac 19c 5 c ac 198 6 c ac 194 7 c ac 190 8 c ac 1cc 9 c ac 1c8 a c ac 1c4 b c ac 1c0 c c ac 1bc d c ac 1b8 e c ac 1b4 f c ac 1b0 0 d ac 1ac 1 d ac 1a9 2 d ac 1a6 3 d ac 1a3 4 d ac 1a0 5 d ac 19d 6 d ac 19a 7 d ac 197 8 d ac 1c4 9 d ac 1c1 a d ac 1be b d ac 1bb c d ac 1b8 d d ac 1b5 e d ac 1b2 f d ac 1af 0 e ac 1ac 1 e ac 1aa 2 e ac 1a8 3 e ac 1a6 4 e ac 1a4 5 e ac 1a2 6 e ac 1a0 7 e ac 19e 8 e ac 1bc 9 e ac 1ba a e ac 1b8 b e ac 1b6 c e ac 1b4 d e ac 1b2 e e ac 1b0 f e ac 1ae 0 f ac 1ac 1 f ac 1ab 2 f ac 1aa 3 f ac 1a9 4 f ac 1a8 5 f ac 1a7 6 f ac 1a6 7 f ac 1a5 8 f ac 1b4 9 f ac 1b3 a f ac 1b2 b f ac 1b1 c f ac 1b0 d f ac 1af e f ac 1ae f f ac 1ad 0 0 ad 1ad 1 0 ad 1ad 2 0 ad 1ad 3 0 ad 1ad 4 0 ad 1ad 5 0 ad 1ad 6 0 ad 1ad 7 0 ad 1ad 8 0 ad 1ad 9 0 ad 1ad a 0 ad 1ad b 0 ad 1ad c 0 ad 1ad d 0 ad 1ad e 0 ad 1ad f 0 ad 1ad 0 1 ad 1ad 1 1 ad 1ae 2 1 ad 1af 3 1 ad 1b0 4 1 ad 1b1 5 1 ad 1b2 6 1 ad 1b3 7 1 ad 1b4 8 1 ad 1a5 9 1 ad 1a6 a 1 ad 1a7 b 1 ad 1a8 c 1 ad 1a9 d 1 ad 1aa e 1 ad 1ab f 1 ad 1ac 0 2 ad 1ad 1 2 ad 1af 2 2 ad 1b1 3 2 ad 1b3 4 2 ad 1b5 5 2 ad 1b7 6 2 ad 1b9 7 2 ad 1bb 8 2 ad 19d 9 2 ad 19f a 2 ad 1a1 b 2 ad 1a3 c 2 ad 1a5 d 2 ad 1a7 e 2 ad 1a9 f 2 ad 1ab 0 3 ad 1ad 1 3 ad 1b0 2 3 ad 1b3 3 3 ad 1b6 4 3 ad 1b9 5 3 ad 1bc 6 3 ad 1bf 7 3 ad 1c2 8 3 ad 195 9 3 ad 198 a 3 ad 19b b 3 ad 19e c 3 ad 1a1 d 3 ad 1a4 e 3 ad 1a7 f 3 ad 1aa 0 4 ad 1ad 1 4 ad 1b1 2 4 ad 1b5 3 4 ad 1b9 4 4 ad 1bd 5 4 ad 1c1 6 4 ad 1c5 7 4 ad 1c9 8 4 ad 18d 9 4 ad 191 a 4 ad 195 b 4 ad 199 c 4 ad 19d d 4 ad 1a1 e 4 ad 1a5 f 4 ad 1a9 0 5 ad 1ad 1 5 ad 1b2 2 5 ad 1b7 3 5 ad 1bc 4 5 ad 1c1 5 5 ad 1c6 6 5 ad 1cb 7 5 ad 1d0 8 5 ad 185 9 5 ad 18a a 5 ad 18f b 5 ad 194 c 5 ad 199 d 5 ad 19e e 5 ad 1a3 f 5 ad 1a8 0 6 ad 1ad 1 6 ad 1b3 2 6 ad 1b9 3 6 ad 1bf 4 6 ad 1c5 5 6 ad 1cb 6 6 ad 1d1 7 6 ad 1d7 8 6 ad 17d 9 6 ad 183 a 6 ad 189 b 6 ad 18f c 6 ad 195 d 6 ad 19b e 6 ad 1a1 f 6 ad 1a7 0 7 ad 1ad 1 7 ad 1b4 2 7 ad 1bb 3 7 ad 1c2 4 7 ad 1c9 5 7 ad 1d0 6 7 ad 1d7 7 7 ad 1de 8 7 ad 175 9 7 ad 17c a 7 ad 183 b 7 ad 18a c 7 ad 191 d 7 ad 198 e 7 ad 19f f 7 ad 1a6 0 8 ad 1ad 1 8 ad 1a5 2 8 ad 19d 3 8 ad 195 4 8 ad 18d 5 8 ad 185 6 8 ad 17d 7 8 ad 175 8 8 ad 1ed 9 8 ad 1e5 a 8 ad 1dd b 8 ad 1d5 c 8 ad 1cd d 8 ad 1c5 e 8 ad 1bd f 8 ad 1b5 0 9 ad 1ad 1 9 ad 1a6 2 9 ad 19f 3 9 ad 198 4 9 ad 191 5 9 ad 18a 6 9 ad 183 7 9 ad 17c 8 9 ad 1e5 9 9 ad 1de a 9 ad 1d7 b 9 ad 1d0 c 9 ad 1c9 d 9 ad 1c2 e 9 ad 1bb f 9 ad 1b4 0 a ad 1ad 1 a ad 1a7 2 a ad 1a1 3 a ad 19b 4 a ad 195 5 a ad 18f 6 a ad 189 7 a ad 183 8 a ad 1dd 9 a ad 1d7 a a ad 1d1 b a ad 1cb c a ad 1c5 d a ad 1bf e a ad 1b9 f a ad 1b3 0 b ad 1ad 1 b ad 1a8 2 b ad 1a3 3 b ad 19e 4 b ad 199 5 b ad 194 6 b ad 18f 7 b ad 18a 8 b ad 1d5 9 b ad 1d0 a b ad 1cb b b ad 1c6 c b ad 1c1 d b ad 1bc e b ad 1b7 f b ad 1b2 0 c ad 1ad 1 c ad 1a9 2 c ad 1a5 3 c ad 1a1 4 c ad 19d 5 c ad 199 6 c ad 195 7 c ad 191 8 c ad 1cd 9 c ad 1c9 a c ad 1c5 b c ad 1c1 c c ad 1bd d c ad 1b9 e c ad 1b5 f c ad 1b1 0 d ad 1ad 1 d ad 1aa 2 d ad 1a7 3 d ad 1a4 4 d ad 1a1 5 d ad 19e 6 d ad 19b 7 d ad 198 8 d ad 1c5 9 d ad 1c2 a d ad 1bf b d ad 1bc c d ad 1b9 d d ad 1b6 e d ad 1b3 f d ad 1b0 0 e ad 1ad 1 e ad 1ab 2 e ad 1a9 3 e ad 1a7 4 e ad 1a5 5 e ad 1a3 6 e ad 1a1 7 e ad 19f 8 e ad 1bd 9 e ad 1bb a e ad 1b9 b e ad 1b7 c e ad 1b5 d e ad 1b3 e e ad 1b1 f e ad 1af 0 f ad 1ad 1 f ad 1ac 2 f ad 1ab 3 f ad 1aa 4 f ad 1a9 5 f ad 1a8 6 f ad 1a7 7 f ad 1a6 8 f ad 1b5 9 f ad 1b4 a f ad 1b3 b f ad 1b2 c f ad 1b1 d f ad 1b0 e f ad 1af f f ad 1ae 0 0 ae 1ae 1 0 ae 1ae 2 0 ae 1ae 3 0 ae 1ae 4 0 ae 1ae 5 0 ae 1ae 6 0 ae 1ae 7 0 ae 1ae 8 0 ae 1ae 9 0 ae 1ae a 0 ae 1ae b 0 ae 1ae c 0 ae 1ae d 0 ae 1ae e 0 ae 1ae f 0 ae 1ae 0 1 ae 1ae 1 1 ae 1af 2 1 ae 1b0 3 1 ae 1b1 4 1 ae 1b2 5 1 ae 1b3 6 1 ae 1b4 7 1 ae 1b5 8 1 ae 1a6 9 1 ae 1a7 a 1 ae 1a8 b 1 ae 1a9 c 1 ae 1aa d 1 ae 1ab e 1 ae 1ac f 1 ae 1ad 0 2 ae 1ae 1 2 ae 1b0 2 2 ae 1b2 3 2 ae 1b4 4 2 ae 1b6 5 2 ae 1b8 6 2 ae 1ba 7 2 ae 1bc 8 2 ae 19e 9 2 ae 1a0 a 2 ae 1a2 b 2 ae 1a4 c 2 ae 1a6 d 2 ae 1a8 e 2 ae 1aa f 2 ae 1ac 0 3 ae 1ae 1 3 ae 1b1 2 3 ae 1b4 3 3 ae 1b7 4 3 ae 1ba 5 3 ae 1bd 6 3 ae 1c0 7 3 ae 1c3 8 3 ae 196 9 3 ae 199 a 3 ae 19c b 3 ae 19f c 3 ae 1a2 d 3 ae 1a5 e 3 ae 1a8 f 3 ae 1ab 0 4 ae 1ae 1 4 ae 1b2 2 4 ae 1b6 3 4 ae 1ba 4 4 ae 1be 5 4 ae 1c2 6 4 ae 1c6 7 4 ae 1ca 8 4 ae 18e 9 4 ae 192 a 4 ae 196 b 4 ae 19a c 4 ae 19e d 4 ae 1a2 e 4 ae 1a6 f 4 ae 1aa 0 5 ae 1ae 1 5 ae 1b3 2 5 ae 1b8 3 5 ae 1bd 4 5 ae 1c2 5 5 ae 1c7 6 5 ae 1cc 7 5 ae 1d1 8 5 ae 186 9 5 ae 18b a 5 ae 190 b 5 ae 195 c 5 ae 19a d 5 ae 19f e 5 ae 1a4 f 5 ae 1a9 0 6 ae 1ae 1 6 ae 1b4 2 6 ae 1ba 3 6 ae 1c0 4 6 ae 1c6 5 6 ae 1cc 6 6 ae 1d2 7 6 ae 1d8 8 6 ae 17e 9 6 ae 184 a 6 ae 18a b 6 ae 190 c 6 ae 196 d 6 ae 19c e 6 ae 1a2 f 6 ae 1a8 0 7 ae 1ae 1 7 ae 1b5 2 7 ae 1bc 3 7 ae 1c3 4 7 ae 1ca 5 7 ae 1d1 6 7 ae 1d8 7 7 ae 1df 8 7 ae 176 9 7 ae 17d a 7 ae 184 b 7 ae 18b c 7 ae 192 d 7 ae 199 e 7 ae 1a0 f 7 ae 1a7 0 8 ae 1ae 1 8 ae 1a6 2 8 ae 19e 3 8 ae 196 4 8 ae 18e 5 8 ae 186 6 8 ae 17e 7 8 ae 176 8 8 ae 1ee 9 8 ae 1e6 a 8 ae 1de b 8 ae 1d6 c 8 ae 1ce d 8 ae 1c6 e 8 ae 1be f 8 ae 1b6 0 9 ae 1ae 1 9 ae 1a7 2 9 ae 1a0 3 9 ae 199 4 9 ae 192 5 9 ae 18b 6 9 ae 184 7 9 ae 17d 8 9 ae 1e6 9 9 ae 1df a 9 ae 1d8 b 9 ae 1d1 c 9 ae 1ca d 9 ae 1c3 e 9 ae 1bc f 9 ae 1b5 0 a ae 1ae 1 a ae 1a8 2 a ae 1a2 3 a ae 19c 4 a ae 196 5 a ae 190 6 a ae 18a 7 a ae 184 8 a ae 1de 9 a ae 1d8 a a ae 1d2 b a ae 1cc c a ae 1c6 d a ae 1c0 e a ae 1ba f a ae 1b4 0 b ae 1ae 1 b ae 1a9 2 b ae 1a4 3 b ae 19f 4 b ae 19a 5 b ae 195 6 b ae 190 7 b ae 18b 8 b ae 1d6 9 b ae 1d1 a b ae 1cc b b ae 1c7 c b ae 1c2 d b ae 1bd e b ae 1b8 f b ae 1b3 0 c ae 1ae 1 c ae 1aa 2 c ae 1a6 3 c ae 1a2 4 c ae 19e 5 c ae 19a 6 c ae 196 7 c ae 192 8 c ae 1ce 9 c ae 1ca a c ae 1c6 b c ae 1c2 c c ae 1be d c ae 1ba e c ae 1b6 f c ae 1b2 0 d ae 1ae 1 d ae 1ab 2 d ae 1a8 3 d ae 1a5 4 d ae 1a2 5 d ae 19f 6 d ae 19c 7 d ae 199 8 d ae 1c6 9 d ae 1c3 a d ae 1c0 b d ae 1bd c d ae 1ba d d ae 1b7 e d ae 1b4 f d ae 1b1 0 e ae 1ae 1 e ae 1ac 2 e ae 1aa 3 e ae 1a8 4 e ae 1a6 5 e ae 1a4 6 e ae 1a2 7 e ae 1a0 8 e ae 1be 9 e ae 1bc a e ae 1ba b e ae 1b8 c e ae 1b6 d e ae 1b4 e e ae 1b2 f e ae 1b0 0 f ae 1ae 1 f ae 1ad 2 f ae 1ac 3 f ae 1ab 4 f ae 1aa 5 f ae 1a9 6 f ae 1a8 7 f ae 1a7 8 f ae 1b6 9 f ae 1b5 a f ae 1b4 b f ae 1b3 c f ae 1b2 d f ae 1b1 e f ae 1b0 f f ae 1af 0 0 af 1af 1 0 af 1af 2 0 af 1af 3 0 af 1af 4 0 af 1af 5 0 af 1af 6 0 af 1af 7 0 af 1af 8 0 af 1af 9 0 af 1af a 0 af 1af b 0 af 1af c 0 af 1af d 0 af 1af e 0 af 1af f 0 af 1af 0 1 af 1af 1 1 af 1b0 2 1 af 1b1 3 1 af 1b2 4 1 af 1b3 5 1 af 1b4 6 1 af 1b5 7 1 af 1b6 8 1 af 1a7 9 1 af 1a8 a 1 af 1a9 b 1 af 1aa c 1 af 1ab d 1 af 1ac e 1 af 1ad f 1 af 1ae 0 2 af 1af 1 2 af 1b1 2 2 af 1b3 3 2 af 1b5 4 2 af 1b7 5 2 af 1b9 6 2 af 1bb 7 2 af 1bd 8 2 af 19f 9 2 af 1a1 a 2 af 1a3 b 2 af 1a5 c 2 af 1a7 d 2 af 1a9 e 2 af 1ab f 2 af 1ad 0 3 af 1af 1 3 af 1b2 2 3 af 1b5 3 3 af 1b8 4 3 af 1bb 5 3 af 1be 6 3 af 1c1 7 3 af 1c4 8 3 af 197 9 3 af 19a a 3 af 19d b 3 af 1a0 c 3 af 1a3 d 3 af 1a6 e 3 af 1a9 f 3 af 1ac 0 4 af 1af 1 4 af 1b3 2 4 af 1b7 3 4 af 1bb 4 4 af 1bf 5 4 af 1c3 6 4 af 1c7 7 4 af 1cb 8 4 af 18f 9 4 af 193 a 4 af 197 b 4 af 19b c 4 af 19f d 4 af 1a3 e 4 af 1a7 f 4 af 1ab 0 5 af 1af 1 5 af 1b4 2 5 af 1b9 3 5 af 1be 4 5 af 1c3 5 5 af 1c8 6 5 af 1cd 7 5 af 1d2 8 5 af 187 9 5 af 18c a 5 af 191 b 5 af 196 c 5 af 19b d 5 af 1a0 e 5 af 1a5 f 5 af 1aa 0 6 af 1af 1 6 af 1b5 2 6 af 1bb 3 6 af 1c1 4 6 af 1c7 5 6 af 1cd 6 6 af 1d3 7 6 af 1d9 8 6 af 17f 9 6 af 185 a 6 af 18b b 6 af 191 c 6 af 197 d 6 af 19d e 6 af 1a3 f 6 af 1a9 0 7 af 1af 1 7 af 1b6 2 7 af 1bd 3 7 af 1c4 4 7 af 1cb 5 7 af 1d2 6 7 af 1d9 7 7 af 1e0 8 7 af 177 9 7 af 17e a 7 af 185 b 7 af 18c c 7 af 193 d 7 af 19a e 7 af 1a1 f 7 af 1a8 0 8 af 1af 1 8 af 1a7 2 8 af 19f 3 8 af 197 4 8 af 18f 5 8 af 187 6 8 af 17f 7 8 af 177 8 8 af 1ef 9 8 af 1e7 a 8 af 1df b 8 af 1d7 c 8 af 1cf d 8 af 1c7 e 8 af 1bf f 8 af 1b7 0 9 af 1af 1 9 af 1a8 2 9 af 1a1 3 9 af 19a 4 9 af 193 5 9 af 18c 6 9 af 185 7 9 af 17e 8 9 af 1e7 9 9 af 1e0 a 9 af 1d9 b 9 af 1d2 c 9 af 1cb d 9 af 1c4 e 9 af 1bd f 9 af 1b6 0 a af 1af 1 a af 1a9 2 a af 1a3 3 a af 19d 4 a af 197 5 a af 191 6 a af 18b 7 a af 185 8 a af 1df 9 a af 1d9 a a af 1d3 b a af 1cd c a af 1c7 d a af 1c1 e a af 1bb f a af 1b5 0 b af 1af 1 b af 1aa 2 b af 1a5 3 b af 1a0 4 b af 19b 5 b af 196 6 b af 191 7 b af 18c 8 b af 1d7 9 b af 1d2 a b af 1cd b b af 1c8 c b af 1c3 d b af 1be e b af 1b9 f b af 1b4 0 c af 1af 1 c af 1ab 2 c af 1a7 3 c af 1a3 4 c af 19f 5 c af 19b 6 c af 197 7 c af 193 8 c af 1cf 9 c af 1cb a c af 1c7 b c af 1c3 c c af 1bf d c af 1bb e c af 1b7 f c af 1b3 0 d af 1af 1 d af 1ac 2 d af 1a9 3 d af 1a6 4 d af 1a3 5 d af 1a0 6 d af 19d 7 d af 19a 8 d af 1c7 9 d af 1c4 a d af 1c1 b d af 1be c d af 1bb d d af 1b8 e d af 1b5 f d af 1b2 0 e af 1af 1 e af 1ad 2 e af 1ab 3 e af 1a9 4 e af 1a7 5 e af 1a5 6 e af 1a3 7 e af 1a1 8 e af 1bf 9 e af 1bd a e af 1bb b e af 1b9 c e af 1b7 d e af 1b5 e e af 1b3 f e af 1b1 0 f af 1af 1 f af 1ae 2 f af 1ad 3 f af 1ac 4 f af 1ab 5 f af 1aa 6 f af 1a9 7 f af 1a8 8 f af 1b7 9 f af 1b6 a f af 1b5 b f af 1b4 c f af 1b3 d f af 1b2 e f af 1b1 f f af 1b0 0 0 b0 1b0 1 0 b0 1b0 2 0 b0 1b0 3 0 b0 1b0 4 0 b0 1b0 5 0 b0 1b0 6 0 b0 1b0 7 0 b0 1b0 8 0 b0 1b0 9 0 b0 1b0 a 0 b0 1b0 b 0 b0 1b0 c 0 b0 1b0 d 0 b0 1b0 e 0 b0 1b0 f 0 b0 1b0 0 1 b0 1b0 1 1 b0 1b1 2 1 b0 1b2 3 1 b0 1b3 4 1 b0 1b4 5 1 b0 1b5 6 1 b0 1b6 7 1 b0 1b7 8 1 b0 1a8 9 1 b0 1a9 a 1 b0 1aa b 1 b0 1ab c 1 b0 1ac d 1 b0 1ad e 1 b0 1ae f 1 b0 1af 0 2 b0 1b0 1 2 b0 1b2 2 2 b0 1b4 3 2 b0 1b6 4 2 b0 1b8 5 2 b0 1ba 6 2 b0 1bc 7 2 b0 1be 8 2 b0 1a0 9 2 b0 1a2 a 2 b0 1a4 b 2 b0 1a6 c 2 b0 1a8 d 2 b0 1aa e 2 b0 1ac f 2 b0 1ae 0 3 b0 1b0 1 3 b0 1b3 2 3 b0 1b6 3 3 b0 1b9 4 3 b0 1bc 5 3 b0 1bf 6 3 b0 1c2 7 3 b0 1c5 8 3 b0 198 9 3 b0 19b a 3 b0 19e b 3 b0 1a1 c 3 b0 1a4 d 3 b0 1a7 e 3 b0 1aa f 3 b0 1ad 0 4 b0 1b0 1 4 b0 1b4 2 4 b0 1b8 3 4 b0 1bc 4 4 b0 1c0 5 4 b0 1c4 6 4 b0 1c8 7 4 b0 1cc 8 4 b0 190 9 4 b0 194 a 4 b0 198 b 4 b0 19c c 4 b0 1a0 d 4 b0 1a4 e 4 b0 1a8 f 4 b0 1ac 0 5 b0 1b0 1 5 b0 1b5 2 5 b0 1ba 3 5 b0 1bf 4 5 b0 1c4 5 5 b0 1c9 6 5 b0 1ce 7 5 b0 1d3 8 5 b0 188 9 5 b0 18d a 5 b0 192 b 5 b0 197 c 5 b0 19c d 5 b0 1a1 e 5 b0 1a6 f 5 b0 1ab 0 6 b0 1b0 1 6 b0 1b6 2 6 b0 1bc 3 6 b0 1c2 4 6 b0 1c8 5 6 b0 1ce 6 6 b0 1d4 7 6 b0 1da 8 6 b0 180 9 6 b0 186 a 6 b0 18c b 6 b0 192 c 6 b0 198 d 6 b0 19e e 6 b0 1a4 f 6 b0 1aa 0 7 b0 1b0 1 7 b0 1b7 2 7 b0 1be 3 7 b0 1c5 4 7 b0 1cc 5 7 b0 1d3 6 7 b0 1da 7 7 b0 1e1 8 7 b0 178 9 7 b0 17f a 7 b0 186 b 7 b0 18d c 7 b0 194 d 7 b0 19b e 7 b0 1a2 f 7 b0 1a9 0 8 b0 1b0 1 8 b0 1a8 2 8 b0 1a0 3 8 b0 198 4 8 b0 190 5 8 b0 188 6 8 b0 180 7 8 b0 178 8 8 b0 1f0 9 8 b0 1e8 a 8 b0 1e0 b 8 b0 1d8 c 8 b0 1d0 d 8 b0 1c8 e 8 b0 1c0 f 8 b0 1b8 0 9 b0 1b0 1 9 b0 1a9 2 9 b0 1a2 3 9 b0 19b 4 9 b0 194 5 9 b0 18d 6 9 b0 186 7 9 b0 17f 8 9 b0 1e8 9 9 b0 1e1 a 9 b0 1da b 9 b0 1d3 c 9 b0 1cc d 9 b0 1c5 e 9 b0 1be f 9 b0 1b7 0 a b0 1b0 1 a b0 1aa 2 a b0 1a4 3 a b0 19e 4 a b0 198 5 a b0 192 6 a b0 18c 7 a b0 186 8 a b0 1e0 9 a b0 1da a a b0 1d4 b a b0 1ce c a b0 1c8 d a b0 1c2 e a b0 1bc f a b0 1b6 0 b b0 1b0 1 b b0 1ab 2 b b0 1a6 3 b b0 1a1 4 b b0 19c 5 b b0 197 6 b b0 192 7 b b0 18d 8 b b0 1d8 9 b b0 1d3 a b b0 1ce b b b0 1c9 c b b0 1c4 d b b0 1bf e b b0 1ba f b b0 1b5 0 c b0 1b0 1 c b0 1ac 2 c b0 1a8 3 c b0 1a4 4 c b0 1a0 5 c b0 19c 6 c b0 198 7 c b0 194 8 c b0 1d0 9 c b0 1cc a c b0 1c8 b c b0 1c4 c c b0 1c0 d c b0 1bc e c b0 1b8 f c b0 1b4 0 d b0 1b0 1 d b0 1ad 2 d b0 1aa 3 d b0 1a7 4 d b0 1a4 5 d b0 1a1 6 d b0 19e 7 d b0 19b 8 d b0 1c8 9 d b0 1c5 a d b0 1c2 b d b0 1bf c d b0 1bc d d b0 1b9 e d b0 1b6 f d b0 1b3 0 e b0 1b0 1 e b0 1ae 2 e b0 1ac 3 e b0 1aa 4 e b0 1a8 5 e b0 1a6 6 e b0 1a4 7 e b0 1a2 8 e b0 1c0 9 e b0 1be a e b0 1bc b e b0 1ba c e b0 1b8 d e b0 1b6 e e b0 1b4 f e b0 1b2 0 f b0 1b0 1 f b0 1af 2 f b0 1ae 3 f b0 1ad 4 f b0 1ac 5 f b0 1ab 6 f b0 1aa 7 f b0 1a9 8 f b0 1b8 9 f b0 1b7 a f b0 1b6 b f b0 1b5 c f b0 1b4 d f b0 1b3 e f b0 1b2 f f b0 1b1 0 0 b1 1b1 1 0 b1 1b1 2 0 b1 1b1 3 0 b1 1b1 4 0 b1 1b1 5 0 b1 1b1 6 0 b1 1b1 7 0 b1 1b1 8 0 b1 1b1 9 0 b1 1b1 a 0 b1 1b1 b 0 b1 1b1 c 0 b1 1b1 d 0 b1 1b1 e 0 b1 1b1 f 0 b1 1b1 0 1 b1 1b1 1 1 b1 1b2 2 1 b1 1b3 3 1 b1 1b4 4 1 b1 1b5 5 1 b1 1b6 6 1 b1 1b7 7 1 b1 1b8 8 1 b1 1a9 9 1 b1 1aa a 1 b1 1ab b 1 b1 1ac c 1 b1 1ad d 1 b1 1ae e 1 b1 1af f 1 b1 1b0 0 2 b1 1b1 1 2 b1 1b3 2 2 b1 1b5 3 2 b1 1b7 4 2 b1 1b9 5 2 b1 1bb 6 2 b1 1bd 7 2 b1 1bf 8 2 b1 1a1 9 2 b1 1a3 a 2 b1 1a5 b 2 b1 1a7 c 2 b1 1a9 d 2 b1 1ab e 2 b1 1ad f 2 b1 1af 0 3 b1 1b1 1 3 b1 1b4 2 3 b1 1b7 3 3 b1 1ba 4 3 b1 1bd 5 3 b1 1c0 6 3 b1 1c3 7 3 b1 1c6 8 3 b1 199 9 3 b1 19c a 3 b1 19f b 3 b1 1a2 c 3 b1 1a5 d 3 b1 1a8 e 3 b1 1ab f 3 b1 1ae 0 4 b1 1b1 1 4 b1 1b5 2 4 b1 1b9 3 4 b1 1bd 4 4 b1 1c1 5 4 b1 1c5 6 4 b1 1c9 7 4 b1 1cd 8 4 b1 191 9 4 b1 195 a 4 b1 199 b 4 b1 19d c 4 b1 1a1 d 4 b1 1a5 e 4 b1 1a9 f 4 b1 1ad 0 5 b1 1b1 1 5 b1 1b6 2 5 b1 1bb 3 5 b1 1c0 4 5 b1 1c5 5 5 b1 1ca 6 5 b1 1cf 7 5 b1 1d4 8 5 b1 189 9 5 b1 18e a 5 b1 193 b 5 b1 198 c 5 b1 19d d 5 b1 1a2 e 5 b1 1a7 f 5 b1 1ac 0 6 b1 1b1 1 6 b1 1b7 2 6 b1 1bd 3 6 b1 1c3 4 6 b1 1c9 5 6 b1 1cf 6 6 b1 1d5 7 6 b1 1db 8 6 b1 181 9 6 b1 187 a 6 b1 18d b 6 b1 193 c 6 b1 199 d 6 b1 19f e 6 b1 1a5 f 6 b1 1ab 0 7 b1 1b1 1 7 b1 1b8 2 7 b1 1bf 3 7 b1 1c6 4 7 b1 1cd 5 7 b1 1d4 6 7 b1 1db 7 7 b1 1e2 8 7 b1 179 9 7 b1 180 a 7 b1 187 b 7 b1 18e c 7 b1 195 d 7 b1 19c e 7 b1 1a3 f 7 b1 1aa 0 8 b1 1b1 1 8 b1 1a9 2 8 b1 1a1 3 8 b1 199 4 8 b1 191 5 8 b1 189 6 8 b1 181 7 8 b1 179 8 8 b1 1f1 9 8 b1 1e9 a 8 b1 1e1 b 8 b1 1d9 c 8 b1 1d1 d 8 b1 1c9 e 8 b1 1c1 f 8 b1 1b9 0 9 b1 1b1 1 9 b1 1aa 2 9 b1 1a3 3 9 b1 19c 4 9 b1 195 5 9 b1 18e 6 9 b1 187 7 9 b1 180 8 9 b1 1e9 9 9 b1 1e2 a 9 b1 1db b 9 b1 1d4 c 9 b1 1cd d 9 b1 1c6 e 9 b1 1bf f 9 b1 1b8 0 a b1 1b1 1 a b1 1ab 2 a b1 1a5 3 a b1 19f 4 a b1 199 5 a b1 193 6 a b1 18d 7 a b1 187 8 a b1 1e1 9 a b1 1db a a b1 1d5 b a b1 1cf c a b1 1c9 d a b1 1c3 e a b1 1bd f a b1 1b7 0 b b1 1b1 1 b b1 1ac 2 b b1 1a7 3 b b1 1a2 4 b b1 19d 5 b b1 198 6 b b1 193 7 b b1 18e 8 b b1 1d9 9 b b1 1d4 a b b1 1cf b b b1 1ca c b b1 1c5 d b b1 1c0 e b b1 1bb f b b1 1b6 0 c b1 1b1 1 c b1 1ad 2 c b1 1a9 3 c b1 1a5 4 c b1 1a1 5 c b1 19d 6 c b1 199 7 c b1 195 8 c b1 1d1 9 c b1 1cd a c b1 1c9 b c b1 1c5 c c b1 1c1 d c b1 1bd e c b1 1b9 f c b1 1b5 0 d b1 1b1 1 d b1 1ae 2 d b1 1ab 3 d b1 1a8 4 d b1 1a5 5 d b1 1a2 6 d b1 19f 7 d b1 19c 8 d b1 1c9 9 d b1 1c6 a d b1 1c3 b d b1 1c0 c d b1 1bd d d b1 1ba e d b1 1b7 f d b1 1b4 0 e b1 1b1 1 e b1 1af 2 e b1 1ad 3 e b1 1ab 4 e b1 1a9 5 e b1 1a7 6 e b1 1a5 7 e b1 1a3 8 e b1 1c1 9 e b1 1bf a e b1 1bd b e b1 1bb c e b1 1b9 d e b1 1b7 e e b1 1b5 f e b1 1b3 0 f b1 1b1 1 f b1 1b0 2 f b1 1af 3 f b1 1ae 4 f b1 1ad 5 f b1 1ac 6 f b1 1ab 7 f b1 1aa 8 f b1 1b9 9 f b1 1b8 a f b1 1b7 b f b1 1b6 c f b1 1b5 d f b1 1b4 e f b1 1b3 f f b1 1b2 0 0 b2 1b2 1 0 b2 1b2 2 0 b2 1b2 3 0 b2 1b2 4 0 b2 1b2 5 0 b2 1b2 6 0 b2 1b2 7 0 b2 1b2 8 0 b2 1b2 9 0 b2 1b2 a 0 b2 1b2 b 0 b2 1b2 c 0 b2 1b2 d 0 b2 1b2 e 0 b2 1b2 f 0 b2 1b2 0 1 b2 1b2 1 1 b2 1b3 2 1 b2 1b4 3 1 b2 1b5 4 1 b2 1b6 5 1 b2 1b7 6 1 b2 1b8 7 1 b2 1b9 8 1 b2 1aa 9 1 b2 1ab a 1 b2 1ac b 1 b2 1ad c 1 b2 1ae d 1 b2 1af e 1 b2 1b0 f 1 b2 1b1 0 2 b2 1b2 1 2 b2 1b4 2 2 b2 1b6 3 2 b2 1b8 4 2 b2 1ba 5 2 b2 1bc 6 2 b2 1be 7 2 b2 1c0 8 2 b2 1a2 9 2 b2 1a4 a 2 b2 1a6 b 2 b2 1a8 c 2 b2 1aa d 2 b2 1ac e 2 b2 1ae f 2 b2 1b0 0 3 b2 1b2 1 3 b2 1b5 2 3 b2 1b8 3 3 b2 1bb 4 3 b2 1be 5 3 b2 1c1 6 3 b2 1c4 7 3 b2 1c7 8 3 b2 19a 9 3 b2 19d a 3 b2 1a0 b 3 b2 1a3 c 3 b2 1a6 d 3 b2 1a9 e 3 b2 1ac f 3 b2 1af 0 4 b2 1b2 1 4 b2 1b6 2 4 b2 1ba 3 4 b2 1be 4 4 b2 1c2 5 4 b2 1c6 6 4 b2 1ca 7 4 b2 1ce 8 4 b2 192 9 4 b2 196 a 4 b2 19a b 4 b2 19e c 4 b2 1a2 d 4 b2 1a6 e 4 b2 1aa f 4 b2 1ae 0 5 b2 1b2 1 5 b2 1b7 2 5 b2 1bc 3 5 b2 1c1 4 5 b2 1c6 5 5 b2 1cb 6 5 b2 1d0 7 5 b2 1d5 8 5 b2 18a 9 5 b2 18f a 5 b2 194 b 5 b2 199 c 5 b2 19e d 5 b2 1a3 e 5 b2 1a8 f 5 b2 1ad 0 6 b2 1b2 1 6 b2 1b8 2 6 b2 1be 3 6 b2 1c4 4 6 b2 1ca 5 6 b2 1d0 6 6 b2 1d6 7 6 b2 1dc 8 6 b2 182 9 6 b2 188 a 6 b2 18e b 6 b2 194 c 6 b2 19a d 6 b2 1a0 e 6 b2 1a6 f 6 b2 1ac 0 7 b2 1b2 1 7 b2 1b9 2 7 b2 1c0 3 7 b2 1c7 4 7 b2 1ce 5 7 b2 1d5 6 7 b2 1dc 7 7 b2 1e3 8 7 b2 17a 9 7 b2 181 a 7 b2 188 b 7 b2 18f c 7 b2 196 d 7 b2 19d e 7 b2 1a4 f 7 b2 1ab 0 8 b2 1b2 1 8 b2 1aa 2 8 b2 1a2 3 8 b2 19a 4 8 b2 192 5 8 b2 18a 6 8 b2 182 7 8 b2 17a 8 8 b2 1f2 9 8 b2 1ea a 8 b2 1e2 b 8 b2 1da c 8 b2 1d2 d 8 b2 1ca e 8 b2 1c2 f 8 b2 1ba 0 9 b2 1b2 1 9 b2 1ab 2 9 b2 1a4 3 9 b2 19d 4 9 b2 196 5 9 b2 18f 6 9 b2 188 7 9 b2 181 8 9 b2 1ea 9 9 b2 1e3 a 9 b2 1dc b 9 b2 1d5 c 9 b2 1ce d 9 b2 1c7 e 9 b2 1c0 f 9 b2 1b9 0 a b2 1b2 1 a b2 1ac 2 a b2 1a6 3 a b2 1a0 4 a b2 19a 5 a b2 194 6 a b2 18e 7 a b2 188 8 a b2 1e2 9 a b2 1dc a a b2 1d6 b a b2 1d0 c a b2 1ca d a b2 1c4 e a b2 1be f a b2 1b8 0 b b2 1b2 1 b b2 1ad 2 b b2 1a8 3 b b2 1a3 4 b b2 19e 5 b b2 199 6 b b2 194 7 b b2 18f 8 b b2 1da 9 b b2 1d5 a b b2 1d0 b b b2 1cb c b b2 1c6 d b b2 1c1 e b b2 1bc f b b2 1b7 0 c b2 1b2 1 c b2 1ae 2 c b2 1aa 3 c b2 1a6 4 c b2 1a2 5 c b2 19e 6 c b2 19a 7 c b2 196 8 c b2 1d2 9 c b2 1ce a c b2 1ca b c b2 1c6 c c b2 1c2 d c b2 1be e c b2 1ba f c b2 1b6 0 d b2 1b2 1 d b2 1af 2 d b2 1ac 3 d b2 1a9 4 d b2 1a6 5 d b2 1a3 6 d b2 1a0 7 d b2 19d 8 d b2 1ca 9 d b2 1c7 a d b2 1c4 b d b2 1c1 c d b2 1be d d b2 1bb e d b2 1b8 f d b2 1b5 0 e b2 1b2 1 e b2 1b0 2 e b2 1ae 3 e b2 1ac 4 e b2 1aa 5 e b2 1a8 6 e b2 1a6 7 e b2 1a4 8 e b2 1c2 9 e b2 1c0 a e b2 1be b e b2 1bc c e b2 1ba d e b2 1b8 e e b2 1b6 f e b2 1b4 0 f b2 1b2 1 f b2 1b1 2 f b2 1b0 3 f b2 1af 4 f b2 1ae 5 f b2 1ad 6 f b2 1ac 7 f b2 1ab 8 f b2 1ba 9 f b2 1b9 a f b2 1b8 b f b2 1b7 c f b2 1b6 d f b2 1b5 e f b2 1b4 f f b2 1b3 0 0 b3 1b3 1 0 b3 1b3 2 0 b3 1b3 3 0 b3 1b3 4 0 b3 1b3 5 0 b3 1b3 6 0 b3 1b3 7 0 b3 1b3 8 0 b3 1b3 9 0 b3 1b3 a 0 b3 1b3 b 0 b3 1b3 c 0 b3 1b3 d 0 b3 1b3 e 0 b3 1b3 f 0 b3 1b3 0 1 b3 1b3 1 1 b3 1b4 2 1 b3 1b5 3 1 b3 1b6 4 1 b3 1b7 5 1 b3 1b8 6 1 b3 1b9 7 1 b3 1ba 8 1 b3 1ab 9 1 b3 1ac a 1 b3 1ad b 1 b3 1ae c 1 b3 1af d 1 b3 1b0 e 1 b3 1b1 f 1 b3 1b2 0 2 b3 1b3 1 2 b3 1b5 2 2 b3 1b7 3 2 b3 1b9 4 2 b3 1bb 5 2 b3 1bd 6 2 b3 1bf 7 2 b3 1c1 8 2 b3 1a3 9 2 b3 1a5 a 2 b3 1a7 b 2 b3 1a9 c 2 b3 1ab d 2 b3 1ad e 2 b3 1af f 2 b3 1b1 0 3 b3 1b3 1 3 b3 1b6 2 3 b3 1b9 3 3 b3 1bc 4 3 b3 1bf 5 3 b3 1c2 6 3 b3 1c5 7 3 b3 1c8 8 3 b3 19b 9 3 b3 19e a 3 b3 1a1 b 3 b3 1a4 c 3 b3 1a7 d 3 b3 1aa e 3 b3 1ad f 3 b3 1b0 0 4 b3 1b3 1 4 b3 1b7 2 4 b3 1bb 3 4 b3 1bf 4 4 b3 1c3 5 4 b3 1c7 6 4 b3 1cb 7 4 b3 1cf 8 4 b3 193 9 4 b3 197 a 4 b3 19b b 4 b3 19f c 4 b3 1a3 d 4 b3 1a7 e 4 b3 1ab f 4 b3 1af 0 5 b3 1b3 1 5 b3 1b8 2 5 b3 1bd 3 5 b3 1c2 4 5 b3 1c7 5 5 b3 1cc 6 5 b3 1d1 7 5 b3 1d6 8 5 b3 18b 9 5 b3 190 a 5 b3 195 b 5 b3 19a c 5 b3 19f d 5 b3 1a4 e 5 b3 1a9 f 5 b3 1ae 0 6 b3 1b3 1 6 b3 1b9 2 6 b3 1bf 3 6 b3 1c5 4 6 b3 1cb 5 6 b3 1d1 6 6 b3 1d7 7 6 b3 1dd 8 6 b3 183 9 6 b3 189 a 6 b3 18f b 6 b3 195 c 6 b3 19b d 6 b3 1a1 e 6 b3 1a7 f 6 b3 1ad 0 7 b3 1b3 1 7 b3 1ba 2 7 b3 1c1 3 7 b3 1c8 4 7 b3 1cf 5 7 b3 1d6 6 7 b3 1dd 7 7 b3 1e4 8 7 b3 17b 9 7 b3 182 a 7 b3 189 b 7 b3 190 c 7 b3 197 d 7 b3 19e e 7 b3 1a5 f 7 b3 1ac 0 8 b3 1b3 1 8 b3 1ab 2 8 b3 1a3 3 8 b3 19b 4 8 b3 193 5 8 b3 18b 6 8 b3 183 7 8 b3 17b 8 8 b3 1f3 9 8 b3 1eb a 8 b3 1e3 b 8 b3 1db c 8 b3 1d3 d 8 b3 1cb e 8 b3 1c3 f 8 b3 1bb 0 9 b3 1b3 1 9 b3 1ac 2 9 b3 1a5 3 9 b3 19e 4 9 b3 197 5 9 b3 190 6 9 b3 189 7 9 b3 182 8 9 b3 1eb 9 9 b3 1e4 a 9 b3 1dd b 9 b3 1d6 c 9 b3 1cf d 9 b3 1c8 e 9 b3 1c1 f 9 b3 1ba 0 a b3 1b3 1 a b3 1ad 2 a b3 1a7 3 a b3 1a1 4 a b3 19b 5 a b3 195 6 a b3 18f 7 a b3 189 8 a b3 1e3 9 a b3 1dd a a b3 1d7 b a b3 1d1 c a b3 1cb d a b3 1c5 e a b3 1bf f a b3 1b9 0 b b3 1b3 1 b b3 1ae 2 b b3 1a9 3 b b3 1a4 4 b b3 19f 5 b b3 19a 6 b b3 195 7 b b3 190 8 b b3 1db 9 b b3 1d6 a b b3 1d1 b b b3 1cc c b b3 1c7 d b b3 1c2 e b b3 1bd f b b3 1b8 0 c b3 1b3 1 c b3 1af 2 c b3 1ab 3 c b3 1a7 4 c b3 1a3 5 c b3 19f 6 c b3 19b 7 c b3 197 8 c b3 1d3 9 c b3 1cf a c b3 1cb b c b3 1c7 c c b3 1c3 d c b3 1bf e c b3 1bb f c b3 1b7 0 d b3 1b3 1 d b3 1b0 2 d b3 1ad 3 d b3 1aa 4 d b3 1a7 5 d b3 1a4 6 d b3 1a1 7 d b3 19e 8 d b3 1cb 9 d b3 1c8 a d b3 1c5 b d b3 1c2 c d b3 1bf d d b3 1bc e d b3 1b9 f d b3 1b6 0 e b3 1b3 1 e b3 1b1 2 e b3 1af 3 e b3 1ad 4 e b3 1ab 5 e b3 1a9 6 e b3 1a7 7 e b3 1a5 8 e b3 1c3 9 e b3 1c1 a e b3 1bf b e b3 1bd c e b3 1bb d e b3 1b9 e e b3 1b7 f e b3 1b5 0 f b3 1b3 1 f b3 1b2 2 f b3 1b1 3 f b3 1b0 4 f b3 1af 5 f b3 1ae 6 f b3 1ad 7 f b3 1ac 8 f b3 1bb 9 f b3 1ba a f b3 1b9 b f b3 1b8 c f b3 1b7 d f b3 1b6 e f b3 1b5 f f b3 1b4 0 0 b4 1b4 1 0 b4 1b4 2 0 b4 1b4 3 0 b4 1b4 4 0 b4 1b4 5 0 b4 1b4 6 0 b4 1b4 7 0 b4 1b4 8 0 b4 1b4 9 0 b4 1b4 a 0 b4 1b4 b 0 b4 1b4 c 0 b4 1b4 d 0 b4 1b4 e 0 b4 1b4 f 0 b4 1b4 0 1 b4 1b4 1 1 b4 1b5 2 1 b4 1b6 3 1 b4 1b7 4 1 b4 1b8 5 1 b4 1b9 6 1 b4 1ba 7 1 b4 1bb 8 1 b4 1ac 9 1 b4 1ad a 1 b4 1ae b 1 b4 1af c 1 b4 1b0 d 1 b4 1b1 e 1 b4 1b2 f 1 b4 1b3 0 2 b4 1b4 1 2 b4 1b6 2 2 b4 1b8 3 2 b4 1ba 4 2 b4 1bc 5 2 b4 1be 6 2 b4 1c0 7 2 b4 1c2 8 2 b4 1a4 9 2 b4 1a6 a 2 b4 1a8 b 2 b4 1aa c 2 b4 1ac d 2 b4 1ae e 2 b4 1b0 f 2 b4 1b2 0 3 b4 1b4 1 3 b4 1b7 2 3 b4 1ba 3 3 b4 1bd 4 3 b4 1c0 5 3 b4 1c3 6 3 b4 1c6 7 3 b4 1c9 8 3 b4 19c 9 3 b4 19f a 3 b4 1a2 b 3 b4 1a5 c 3 b4 1a8 d 3 b4 1ab e 3 b4 1ae f 3 b4 1b1 0 4 b4 1b4 1 4 b4 1b8 2 4 b4 1bc 3 4 b4 1c0 4 4 b4 1c4 5 4 b4 1c8 6 4 b4 1cc 7 4 b4 1d0 8 4 b4 194 9 4 b4 198 a 4 b4 19c b 4 b4 1a0 c 4 b4 1a4 d 4 b4 1a8 e 4 b4 1ac f 4 b4 1b0 0 5 b4 1b4 1 5 b4 1b9 2 5 b4 1be 3 5 b4 1c3 4 5 b4 1c8 5 5 b4 1cd 6 5 b4 1d2 7 5 b4 1d7 8 5 b4 18c 9 5 b4 191 a 5 b4 196 b 5 b4 19b c 5 b4 1a0 d 5 b4 1a5 e 5 b4 1aa f 5 b4 1af 0 6 b4 1b4 1 6 b4 1ba 2 6 b4 1c0 3 6 b4 1c6 4 6 b4 1cc 5 6 b4 1d2 6 6 b4 1d8 7 6 b4 1de 8 6 b4 184 9 6 b4 18a a 6 b4 190 b 6 b4 196 c 6 b4 19c d 6 b4 1a2 e 6 b4 1a8 f 6 b4 1ae 0 7 b4 1b4 1 7 b4 1bb 2 7 b4 1c2 3 7 b4 1c9 4 7 b4 1d0 5 7 b4 1d7 6 7 b4 1de 7 7 b4 1e5 8 7 b4 17c 9 7 b4 183 a 7 b4 18a b 7 b4 191 c 7 b4 198 d 7 b4 19f e 7 b4 1a6 f 7 b4 1ad 0 8 b4 1b4 1 8 b4 1ac 2 8 b4 1a4 3 8 b4 19c 4 8 b4 194 5 8 b4 18c 6 8 b4 184 7 8 b4 17c 8 8 b4 1f4 9 8 b4 1ec a 8 b4 1e4 b 8 b4 1dc c 8 b4 1d4 d 8 b4 1cc e 8 b4 1c4 f 8 b4 1bc 0 9 b4 1b4 1 9 b4 1ad 2 9 b4 1a6 3 9 b4 19f 4 9 b4 198 5 9 b4 191 6 9 b4 18a 7 9 b4 183 8 9 b4 1ec 9 9 b4 1e5 a 9 b4 1de b 9 b4 1d7 c 9 b4 1d0 d 9 b4 1c9 e 9 b4 1c2 f 9 b4 1bb 0 a b4 1b4 1 a b4 1ae 2 a b4 1a8 3 a b4 1a2 4 a b4 19c 5 a b4 196 6 a b4 190 7 a b4 18a 8 a b4 1e4 9 a b4 1de a a b4 1d8 b a b4 1d2 c a b4 1cc d a b4 1c6 e a b4 1c0 f a b4 1ba 0 b b4 1b4 1 b b4 1af 2 b b4 1aa 3 b b4 1a5 4 b b4 1a0 5 b b4 19b 6 b b4 196 7 b b4 191 8 b b4 1dc 9 b b4 1d7 a b b4 1d2 b b b4 1cd c b b4 1c8 d b b4 1c3 e b b4 1be f b b4 1b9 0 c b4 1b4 1 c b4 1b0 2 c b4 1ac 3 c b4 1a8 4 c b4 1a4 5 c b4 1a0 6 c b4 19c 7 c b4 198 8 c b4 1d4 9 c b4 1d0 a c b4 1cc b c b4 1c8 c c b4 1c4 d c b4 1c0 e c b4 1bc f c b4 1b8 0 d b4 1b4 1 d b4 1b1 2 d b4 1ae 3 d b4 1ab 4 d b4 1a8 5 d b4 1a5 6 d b4 1a2 7 d b4 19f 8 d b4 1cc 9 d b4 1c9 a d b4 1c6 b d b4 1c3 c d b4 1c0 d d b4 1bd e d b4 1ba f d b4 1b7 0 e b4 1b4 1 e b4 1b2 2 e b4 1b0 3 e b4 1ae 4 e b4 1ac 5 e b4 1aa 6 e b4 1a8 7 e b4 1a6 8 e b4 1c4 9 e b4 1c2 a e b4 1c0 b e b4 1be c e b4 1bc d e b4 1ba e e b4 1b8 f e b4 1b6 0 f b4 1b4 1 f b4 1b3 2 f b4 1b2 3 f b4 1b1 4 f b4 1b0 5 f b4 1af 6 f b4 1ae 7 f b4 1ad 8 f b4 1bc 9 f b4 1bb a f b4 1ba b f b4 1b9 c f b4 1b8 d f b4 1b7 e f b4 1b6 f f b4 1b5 0 0 b5 1b5 1 0 b5 1b5 2 0 b5 1b5 3 0 b5 1b5 4 0 b5 1b5 5 0 b5 1b5 6 0 b5 1b5 7 0 b5 1b5 8 0 b5 1b5 9 0 b5 1b5 a 0 b5 1b5 b 0 b5 1b5 c 0 b5 1b5 d 0 b5 1b5 e 0 b5 1b5 f 0 b5 1b5 0 1 b5 1b5 1 1 b5 1b6 2 1 b5 1b7 3 1 b5 1b8 4 1 b5 1b9 5 1 b5 1ba 6 1 b5 1bb 7 1 b5 1bc 8 1 b5 1ad 9 1 b5 1ae a 1 b5 1af b 1 b5 1b0 c 1 b5 1b1 d 1 b5 1b2 e 1 b5 1b3 f 1 b5 1b4 0 2 b5 1b5 1 2 b5 1b7 2 2 b5 1b9 3 2 b5 1bb 4 2 b5 1bd 5 2 b5 1bf 6 2 b5 1c1 7 2 b5 1c3 8 2 b5 1a5 9 2 b5 1a7 a 2 b5 1a9 b 2 b5 1ab c 2 b5 1ad d 2 b5 1af e 2 b5 1b1 f 2 b5 1b3 0 3 b5 1b5 1 3 b5 1b8 2 3 b5 1bb 3 3 b5 1be 4 3 b5 1c1 5 3 b5 1c4 6 3 b5 1c7 7 3 b5 1ca 8 3 b5 19d 9 3 b5 1a0 a 3 b5 1a3 b 3 b5 1a6 c 3 b5 1a9 d 3 b5 1ac e 3 b5 1af f 3 b5 1b2 0 4 b5 1b5 1 4 b5 1b9 2 4 b5 1bd 3 4 b5 1c1 4 4 b5 1c5 5 4 b5 1c9 6 4 b5 1cd 7 4 b5 1d1 8 4 b5 195 9 4 b5 199 a 4 b5 19d b 4 b5 1a1 c 4 b5 1a5 d 4 b5 1a9 e 4 b5 1ad f 4 b5 1b1 0 5 b5 1b5 1 5 b5 1ba 2 5 b5 1bf 3 5 b5 1c4 4 5 b5 1c9 5 5 b5 1ce 6 5 b5 1d3 7 5 b5 1d8 8 5 b5 18d 9 5 b5 192 a 5 b5 197 b 5 b5 19c c 5 b5 1a1 d 5 b5 1a6 e 5 b5 1ab f 5 b5 1b0 0 6 b5 1b5 1 6 b5 1bb 2 6 b5 1c1 3 6 b5 1c7 4 6 b5 1cd 5 6 b5 1d3 6 6 b5 1d9 7 6 b5 1df 8 6 b5 185 9 6 b5 18b a 6 b5 191 b 6 b5 197 c 6 b5 19d d 6 b5 1a3 e 6 b5 1a9 f 6 b5 1af 0 7 b5 1b5 1 7 b5 1bc 2 7 b5 1c3 3 7 b5 1ca 4 7 b5 1d1 5 7 b5 1d8 6 7 b5 1df 7 7 b5 1e6 8 7 b5 17d 9 7 b5 184 a 7 b5 18b b 7 b5 192 c 7 b5 199 d 7 b5 1a0 e 7 b5 1a7 f 7 b5 1ae 0 8 b5 1b5 1 8 b5 1ad 2 8 b5 1a5 3 8 b5 19d 4 8 b5 195 5 8 b5 18d 6 8 b5 185 7 8 b5 17d 8 8 b5 1f5 9 8 b5 1ed a 8 b5 1e5 b 8 b5 1dd c 8 b5 1d5 d 8 b5 1cd e 8 b5 1c5 f 8 b5 1bd 0 9 b5 1b5 1 9 b5 1ae 2 9 b5 1a7 3 9 b5 1a0 4 9 b5 199 5 9 b5 192 6 9 b5 18b 7 9 b5 184 8 9 b5 1ed 9 9 b5 1e6 a 9 b5 1df b 9 b5 1d8 c 9 b5 1d1 d 9 b5 1ca e 9 b5 1c3 f 9 b5 1bc 0 a b5 1b5 1 a b5 1af 2 a b5 1a9 3 a b5 1a3 4 a b5 19d 5 a b5 197 6 a b5 191 7 a b5 18b 8 a b5 1e5 9 a b5 1df a a b5 1d9 b a b5 1d3 c a b5 1cd d a b5 1c7 e a b5 1c1 f a b5 1bb 0 b b5 1b5 1 b b5 1b0 2 b b5 1ab 3 b b5 1a6 4 b b5 1a1 5 b b5 19c 6 b b5 197 7 b b5 192 8 b b5 1dd 9 b b5 1d8 a b b5 1d3 b b b5 1ce c b b5 1c9 d b b5 1c4 e b b5 1bf f b b5 1ba 0 c b5 1b5 1 c b5 1b1 2 c b5 1ad 3 c b5 1a9 4 c b5 1a5 5 c b5 1a1 6 c b5 19d 7 c b5 199 8 c b5 1d5 9 c b5 1d1 a c b5 1cd b c b5 1c9 c c b5 1c5 d c b5 1c1 e c b5 1bd f c b5 1b9 0 d b5 1b5 1 d b5 1b2 2 d b5 1af 3 d b5 1ac 4 d b5 1a9 5 d b5 1a6 6 d b5 1a3 7 d b5 1a0 8 d b5 1cd 9 d b5 1ca a d b5 1c7 b d b5 1c4 c d b5 1c1 d d b5 1be e d b5 1bb f d b5 1b8 0 e b5 1b5 1 e b5 1b3 2 e b5 1b1 3 e b5 1af 4 e b5 1ad 5 e b5 1ab 6 e b5 1a9 7 e b5 1a7 8 e b5 1c5 9 e b5 1c3 a e b5 1c1 b e b5 1bf c e b5 1bd d e b5 1bb e e b5 1b9 f e b5 1b7 0 f b5 1b5 1 f b5 1b4 2 f b5 1b3 3 f b5 1b2 4 f b5 1b1 5 f b5 1b0 6 f b5 1af 7 f b5 1ae 8 f b5 1bd 9 f b5 1bc a f b5 1bb b f b5 1ba c f b5 1b9 d f b5 1b8 e f b5 1b7 f f b5 1b6 0 0 b6 1b6 1 0 b6 1b6 2 0 b6 1b6 3 0 b6 1b6 4 0 b6 1b6 5 0 b6 1b6 6 0 b6 1b6 7 0 b6 1b6 8 0 b6 1b6 9 0 b6 1b6 a 0 b6 1b6 b 0 b6 1b6 c 0 b6 1b6 d 0 b6 1b6 e 0 b6 1b6 f 0 b6 1b6 0 1 b6 1b6 1 1 b6 1b7 2 1 b6 1b8 3 1 b6 1b9 4 1 b6 1ba 5 1 b6 1bb 6 1 b6 1bc 7 1 b6 1bd 8 1 b6 1ae 9 1 b6 1af a 1 b6 1b0 b 1 b6 1b1 c 1 b6 1b2 d 1 b6 1b3 e 1 b6 1b4 f 1 b6 1b5 0 2 b6 1b6 1 2 b6 1b8 2 2 b6 1ba 3 2 b6 1bc 4 2 b6 1be 5 2 b6 1c0 6 2 b6 1c2 7 2 b6 1c4 8 2 b6 1a6 9 2 b6 1a8 a 2 b6 1aa b 2 b6 1ac c 2 b6 1ae d 2 b6 1b0 e 2 b6 1b2 f 2 b6 1b4 0 3 b6 1b6 1 3 b6 1b9 2 3 b6 1bc 3 3 b6 1bf 4 3 b6 1c2 5 3 b6 1c5 6 3 b6 1c8 7 3 b6 1cb 8 3 b6 19e 9 3 b6 1a1 a 3 b6 1a4 b 3 b6 1a7 c 3 b6 1aa d 3 b6 1ad e 3 b6 1b0 f 3 b6 1b3 0 4 b6 1b6 1 4 b6 1ba 2 4 b6 1be 3 4 b6 1c2 4 4 b6 1c6 5 4 b6 1ca 6 4 b6 1ce 7 4 b6 1d2 8 4 b6 196 9 4 b6 19a a 4 b6 19e b 4 b6 1a2 c 4 b6 1a6 d 4 b6 1aa e 4 b6 1ae f 4 b6 1b2 0 5 b6 1b6 1 5 b6 1bb 2 5 b6 1c0 3 5 b6 1c5 4 5 b6 1ca 5 5 b6 1cf 6 5 b6 1d4 7 5 b6 1d9 8 5 b6 18e 9 5 b6 193 a 5 b6 198 b 5 b6 19d c 5 b6 1a2 d 5 b6 1a7 e 5 b6 1ac f 5 b6 1b1 0 6 b6 1b6 1 6 b6 1bc 2 6 b6 1c2 3 6 b6 1c8 4 6 b6 1ce 5 6 b6 1d4 6 6 b6 1da 7 6 b6 1e0 8 6 b6 186 9 6 b6 18c a 6 b6 192 b 6 b6 198 c 6 b6 19e d 6 b6 1a4 e 6 b6 1aa f 6 b6 1b0 0 7 b6 1b6 1 7 b6 1bd 2 7 b6 1c4 3 7 b6 1cb 4 7 b6 1d2 5 7 b6 1d9 6 7 b6 1e0 7 7 b6 1e7 8 7 b6 17e 9 7 b6 185 a 7 b6 18c b 7 b6 193 c 7 b6 19a d 7 b6 1a1 e 7 b6 1a8 f 7 b6 1af 0 8 b6 1b6 1 8 b6 1ae 2 8 b6 1a6 3 8 b6 19e 4 8 b6 196 5 8 b6 18e 6 8 b6 186 7 8 b6 17e 8 8 b6 1f6 9 8 b6 1ee a 8 b6 1e6 b 8 b6 1de c 8 b6 1d6 d 8 b6 1ce e 8 b6 1c6 f 8 b6 1be 0 9 b6 1b6 1 9 b6 1af 2 9 b6 1a8 3 9 b6 1a1 4 9 b6 19a 5 9 b6 193 6 9 b6 18c 7 9 b6 185 8 9 b6 1ee 9 9 b6 1e7 a 9 b6 1e0 b 9 b6 1d9 c 9 b6 1d2 d 9 b6 1cb e 9 b6 1c4 f 9 b6 1bd 0 a b6 1b6 1 a b6 1b0 2 a b6 1aa 3 a b6 1a4 4 a b6 19e 5 a b6 198 6 a b6 192 7 a b6 18c 8 a b6 1e6 9 a b6 1e0 a a b6 1da b a b6 1d4 c a b6 1ce d a b6 1c8 e a b6 1c2 f a b6 1bc 0 b b6 1b6 1 b b6 1b1 2 b b6 1ac 3 b b6 1a7 4 b b6 1a2 5 b b6 19d 6 b b6 198 7 b b6 193 8 b b6 1de 9 b b6 1d9 a b b6 1d4 b b b6 1cf c b b6 1ca d b b6 1c5 e b b6 1c0 f b b6 1bb 0 c b6 1b6 1 c b6 1b2 2 c b6 1ae 3 c b6 1aa 4 c b6 1a6 5 c b6 1a2 6 c b6 19e 7 c b6 19a 8 c b6 1d6 9 c b6 1d2 a c b6 1ce b c b6 1ca c c b6 1c6 d c b6 1c2 e c b6 1be f c b6 1ba 0 d b6 1b6 1 d b6 1b3 2 d b6 1b0 3 d b6 1ad 4 d b6 1aa 5 d b6 1a7 6 d b6 1a4 7 d b6 1a1 8 d b6 1ce 9 d b6 1cb a d b6 1c8 b d b6 1c5 c d b6 1c2 d d b6 1bf e d b6 1bc f d b6 1b9 0 e b6 1b6 1 e b6 1b4 2 e b6 1b2 3 e b6 1b0 4 e b6 1ae 5 e b6 1ac 6 e b6 1aa 7 e b6 1a8 8 e b6 1c6 9 e b6 1c4 a e b6 1c2 b e b6 1c0 c e b6 1be d e b6 1bc e e b6 1ba f e b6 1b8 0 f b6 1b6 1 f b6 1b5 2 f b6 1b4 3 f b6 1b3 4 f b6 1b2 5 f b6 1b1 6 f b6 1b0 7 f b6 1af 8 f b6 1be 9 f b6 1bd a f b6 1bc b f b6 1bb c f b6 1ba d f b6 1b9 e f b6 1b8 f f b6 1b7 0 0 b7 1b7 1 0 b7 1b7 2 0 b7 1b7 3 0 b7 1b7 4 0 b7 1b7 5 0 b7 1b7 6 0 b7 1b7 7 0 b7 1b7 8 0 b7 1b7 9 0 b7 1b7 a 0 b7 1b7 b 0 b7 1b7 c 0 b7 1b7 d 0 b7 1b7 e 0 b7 1b7 f 0 b7 1b7 0 1 b7 1b7 1 1 b7 1b8 2 1 b7 1b9 3 1 b7 1ba 4 1 b7 1bb 5 1 b7 1bc 6 1 b7 1bd 7 1 b7 1be 8 1 b7 1af 9 1 b7 1b0 a 1 b7 1b1 b 1 b7 1b2 c 1 b7 1b3 d 1 b7 1b4 e 1 b7 1b5 f 1 b7 1b6 0 2 b7 1b7 1 2 b7 1b9 2 2 b7 1bb 3 2 b7 1bd 4 2 b7 1bf 5 2 b7 1c1 6 2 b7 1c3 7 2 b7 1c5 8 2 b7 1a7 9 2 b7 1a9 a 2 b7 1ab b 2 b7 1ad c 2 b7 1af d 2 b7 1b1 e 2 b7 1b3 f 2 b7 1b5 0 3 b7 1b7 1 3 b7 1ba 2 3 b7 1bd 3 3 b7 1c0 4 3 b7 1c3 5 3 b7 1c6 6 3 b7 1c9 7 3 b7 1cc 8 3 b7 19f 9 3 b7 1a2 a 3 b7 1a5 b 3 b7 1a8 c 3 b7 1ab d 3 b7 1ae e 3 b7 1b1 f 3 b7 1b4 0 4 b7 1b7 1 4 b7 1bb 2 4 b7 1bf 3 4 b7 1c3 4 4 b7 1c7 5 4 b7 1cb 6 4 b7 1cf 7 4 b7 1d3 8 4 b7 197 9 4 b7 19b a 4 b7 19f b 4 b7 1a3 c 4 b7 1a7 d 4 b7 1ab e 4 b7 1af f 4 b7 1b3 0 5 b7 1b7 1 5 b7 1bc 2 5 b7 1c1 3 5 b7 1c6 4 5 b7 1cb 5 5 b7 1d0 6 5 b7 1d5 7 5 b7 1da 8 5 b7 18f 9 5 b7 194 a 5 b7 199 b 5 b7 19e c 5 b7 1a3 d 5 b7 1a8 e 5 b7 1ad f 5 b7 1b2 0 6 b7 1b7 1 6 b7 1bd 2 6 b7 1c3 3 6 b7 1c9 4 6 b7 1cf 5 6 b7 1d5 6 6 b7 1db 7 6 b7 1e1 8 6 b7 187 9 6 b7 18d a 6 b7 193 b 6 b7 199 c 6 b7 19f d 6 b7 1a5 e 6 b7 1ab f 6 b7 1b1 0 7 b7 1b7 1 7 b7 1be 2 7 b7 1c5 3 7 b7 1cc 4 7 b7 1d3 5 7 b7 1da 6 7 b7 1e1 7 7 b7 1e8 8 7 b7 17f 9 7 b7 186 a 7 b7 18d b 7 b7 194 c 7 b7 19b d 7 b7 1a2 e 7 b7 1a9 f 7 b7 1b0 0 8 b7 1b7 1 8 b7 1af 2 8 b7 1a7 3 8 b7 19f 4 8 b7 197 5 8 b7 18f 6 8 b7 187 7 8 b7 17f 8 8 b7 1f7 9 8 b7 1ef a 8 b7 1e7 b 8 b7 1df c 8 b7 1d7 d 8 b7 1cf e 8 b7 1c7 f 8 b7 1bf 0 9 b7 1b7 1 9 b7 1b0 2 9 b7 1a9 3 9 b7 1a2 4 9 b7 19b 5 9 b7 194 6 9 b7 18d 7 9 b7 186 8 9 b7 1ef 9 9 b7 1e8 a 9 b7 1e1 b 9 b7 1da c 9 b7 1d3 d 9 b7 1cc e 9 b7 1c5 f 9 b7 1be 0 a b7 1b7 1 a b7 1b1 2 a b7 1ab 3 a b7 1a5 4 a b7 19f 5 a b7 199 6 a b7 193 7 a b7 18d 8 a b7 1e7 9 a b7 1e1 a a b7 1db b a b7 1d5 c a b7 1cf d a b7 1c9 e a b7 1c3 f a b7 1bd 0 b b7 1b7 1 b b7 1b2 2 b b7 1ad 3 b b7 1a8 4 b b7 1a3 5 b b7 19e 6 b b7 199 7 b b7 194 8 b b7 1df 9 b b7 1da a b b7 1d5 b b b7 1d0 c b b7 1cb d b b7 1c6 e b b7 1c1 f b b7 1bc 0 c b7 1b7 1 c b7 1b3 2 c b7 1af 3 c b7 1ab 4 c b7 1a7 5 c b7 1a3 6 c b7 19f 7 c b7 19b 8 c b7 1d7 9 c b7 1d3 a c b7 1cf b c b7 1cb c c b7 1c7 d c b7 1c3 e c b7 1bf f c b7 1bb 0 d b7 1b7 1 d b7 1b4 2 d b7 1b1 3 d b7 1ae 4 d b7 1ab 5 d b7 1a8 6 d b7 1a5 7 d b7 1a2 8 d b7 1cf 9 d b7 1cc a d b7 1c9 b d b7 1c6 c d b7 1c3 d d b7 1c0 e d b7 1bd f d b7 1ba 0 e b7 1b7 1 e b7 1b5 2 e b7 1b3 3 e b7 1b1 4 e b7 1af 5 e b7 1ad 6 e b7 1ab 7 e b7 1a9 8 e b7 1c7 9 e b7 1c5 a e b7 1c3 b e b7 1c1 c e b7 1bf d e b7 1bd e e b7 1bb f e b7 1b9 0 f b7 1b7 1 f b7 1b6 2 f b7 1b5 3 f b7 1b4 4 f b7 1b3 5 f b7 1b2 6 f b7 1b1 7 f b7 1b0 8 f b7 1bf 9 f b7 1be a f b7 1bd b f b7 1bc c f b7 1bb d f b7 1ba e f b7 1b9 f f b7 1b8 0 0 b8 1b8 1 0 b8 1b8 2 0 b8 1b8 3 0 b8 1b8 4 0 b8 1b8 5 0 b8 1b8 6 0 b8 1b8 7 0 b8 1b8 8 0 b8 1b8 9 0 b8 1b8 a 0 b8 1b8 b 0 b8 1b8 c 0 b8 1b8 d 0 b8 1b8 e 0 b8 1b8 f 0 b8 1b8 0 1 b8 1b8 1 1 b8 1b9 2 1 b8 1ba 3 1 b8 1bb 4 1 b8 1bc 5 1 b8 1bd 6 1 b8 1be 7 1 b8 1bf 8 1 b8 1b0 9 1 b8 1b1 a 1 b8 1b2 b 1 b8 1b3 c 1 b8 1b4 d 1 b8 1b5 e 1 b8 1b6 f 1 b8 1b7 0 2 b8 1b8 1 2 b8 1ba 2 2 b8 1bc 3 2 b8 1be 4 2 b8 1c0 5 2 b8 1c2 6 2 b8 1c4 7 2 b8 1c6 8 2 b8 1a8 9 2 b8 1aa a 2 b8 1ac b 2 b8 1ae c 2 b8 1b0 d 2 b8 1b2 e 2 b8 1b4 f 2 b8 1b6 0 3 b8 1b8 1 3 b8 1bb 2 3 b8 1be 3 3 b8 1c1 4 3 b8 1c4 5 3 b8 1c7 6 3 b8 1ca 7 3 b8 1cd 8 3 b8 1a0 9 3 b8 1a3 a 3 b8 1a6 b 3 b8 1a9 c 3 b8 1ac d 3 b8 1af e 3 b8 1b2 f 3 b8 1b5 0 4 b8 1b8 1 4 b8 1bc 2 4 b8 1c0 3 4 b8 1c4 4 4 b8 1c8 5 4 b8 1cc 6 4 b8 1d0 7 4 b8 1d4 8 4 b8 198 9 4 b8 19c a 4 b8 1a0 b 4 b8 1a4 c 4 b8 1a8 d 4 b8 1ac e 4 b8 1b0 f 4 b8 1b4 0 5 b8 1b8 1 5 b8 1bd 2 5 b8 1c2 3 5 b8 1c7 4 5 b8 1cc 5 5 b8 1d1 6 5 b8 1d6 7 5 b8 1db 8 5 b8 190 9 5 b8 195 a 5 b8 19a b 5 b8 19f c 5 b8 1a4 d 5 b8 1a9 e 5 b8 1ae f 5 b8 1b3 0 6 b8 1b8 1 6 b8 1be 2 6 b8 1c4 3 6 b8 1ca 4 6 b8 1d0 5 6 b8 1d6 6 6 b8 1dc 7 6 b8 1e2 8 6 b8 188 9 6 b8 18e a 6 b8 194 b 6 b8 19a c 6 b8 1a0 d 6 b8 1a6 e 6 b8 1ac f 6 b8 1b2 0 7 b8 1b8 1 7 b8 1bf 2 7 b8 1c6 3 7 b8 1cd 4 7 b8 1d4 5 7 b8 1db 6 7 b8 1e2 7 7 b8 1e9 8 7 b8 180 9 7 b8 187 a 7 b8 18e b 7 b8 195 c 7 b8 19c d 7 b8 1a3 e 7 b8 1aa f 7 b8 1b1 0 8 b8 1b8 1 8 b8 1b0 2 8 b8 1a8 3 8 b8 1a0 4 8 b8 198 5 8 b8 190 6 8 b8 188 7 8 b8 180 8 8 b8 1f8 9 8 b8 1f0 a 8 b8 1e8 b 8 b8 1e0 c 8 b8 1d8 d 8 b8 1d0 e 8 b8 1c8 f 8 b8 1c0 0 9 b8 1b8 1 9 b8 1b1 2 9 b8 1aa 3 9 b8 1a3 4 9 b8 19c 5 9 b8 195 6 9 b8 18e 7 9 b8 187 8 9 b8 1f0 9 9 b8 1e9 a 9 b8 1e2 b 9 b8 1db c 9 b8 1d4 d 9 b8 1cd e 9 b8 1c6 f 9 b8 1bf 0 a b8 1b8 1 a b8 1b2 2 a b8 1ac 3 a b8 1a6 4 a b8 1a0 5 a b8 19a 6 a b8 194 7 a b8 18e 8 a b8 1e8 9 a b8 1e2 a a b8 1dc b a b8 1d6 c a b8 1d0 d a b8 1ca e a b8 1c4 f a b8 1be 0 b b8 1b8 1 b b8 1b3 2 b b8 1ae 3 b b8 1a9 4 b b8 1a4 5 b b8 19f 6 b b8 19a 7 b b8 195 8 b b8 1e0 9 b b8 1db a b b8 1d6 b b b8 1d1 c b b8 1cc d b b8 1c7 e b b8 1c2 f b b8 1bd 0 c b8 1b8 1 c b8 1b4 2 c b8 1b0 3 c b8 1ac 4 c b8 1a8 5 c b8 1a4 6 c b8 1a0 7 c b8 19c 8 c b8 1d8 9 c b8 1d4 a c b8 1d0 b c b8 1cc c c b8 1c8 d c b8 1c4 e c b8 1c0 f c b8 1bc 0 d b8 1b8 1 d b8 1b5 2 d b8 1b2 3 d b8 1af 4 d b8 1ac 5 d b8 1a9 6 d b8 1a6 7 d b8 1a3 8 d b8 1d0 9 d b8 1cd a d b8 1ca b d b8 1c7 c d b8 1c4 d d b8 1c1 e d b8 1be f d b8 1bb 0 e b8 1b8 1 e b8 1b6 2 e b8 1b4 3 e b8 1b2 4 e b8 1b0 5 e b8 1ae 6 e b8 1ac 7 e b8 1aa 8 e b8 1c8 9 e b8 1c6 a e b8 1c4 b e b8 1c2 c e b8 1c0 d e b8 1be e e b8 1bc f e b8 1ba 0 f b8 1b8 1 f b8 1b7 2 f b8 1b6 3 f b8 1b5 4 f b8 1b4 5 f b8 1b3 6 f b8 1b2 7 f b8 1b1 8 f b8 1c0 9 f b8 1bf a f b8 1be b f b8 1bd c f b8 1bc d f b8 1bb e f b8 1ba f f b8 1b9 0 0 b9 1b9 1 0 b9 1b9 2 0 b9 1b9 3 0 b9 1b9 4 0 b9 1b9 5 0 b9 1b9 6 0 b9 1b9 7 0 b9 1b9 8 0 b9 1b9 9 0 b9 1b9 a 0 b9 1b9 b 0 b9 1b9 c 0 b9 1b9 d 0 b9 1b9 e 0 b9 1b9 f 0 b9 1b9 0 1 b9 1b9 1 1 b9 1ba 2 1 b9 1bb 3 1 b9 1bc 4 1 b9 1bd 5 1 b9 1be 6 1 b9 1bf 7 1 b9 1c0 8 1 b9 1b1 9 1 b9 1b2 a 1 b9 1b3 b 1 b9 1b4 c 1 b9 1b5 d 1 b9 1b6 e 1 b9 1b7 f 1 b9 1b8 0 2 b9 1b9 1 2 b9 1bb 2 2 b9 1bd 3 2 b9 1bf 4 2 b9 1c1 5 2 b9 1c3 6 2 b9 1c5 7 2 b9 1c7 8 2 b9 1a9 9 2 b9 1ab a 2 b9 1ad b 2 b9 1af c 2 b9 1b1 d 2 b9 1b3 e 2 b9 1b5 f 2 b9 1b7 0 3 b9 1b9 1 3 b9 1bc 2 3 b9 1bf 3 3 b9 1c2 4 3 b9 1c5 5 3 b9 1c8 6 3 b9 1cb 7 3 b9 1ce 8 3 b9 1a1 9 3 b9 1a4 a 3 b9 1a7 b 3 b9 1aa c 3 b9 1ad d 3 b9 1b0 e 3 b9 1b3 f 3 b9 1b6 0 4 b9 1b9 1 4 b9 1bd 2 4 b9 1c1 3 4 b9 1c5 4 4 b9 1c9 5 4 b9 1cd 6 4 b9 1d1 7 4 b9 1d5 8 4 b9 199 9 4 b9 19d a 4 b9 1a1 b 4 b9 1a5 c 4 b9 1a9 d 4 b9 1ad e 4 b9 1b1 f 4 b9 1b5 0 5 b9 1b9 1 5 b9 1be 2 5 b9 1c3 3 5 b9 1c8 4 5 b9 1cd 5 5 b9 1d2 6 5 b9 1d7 7 5 b9 1dc 8 5 b9 191 9 5 b9 196 a 5 b9 19b b 5 b9 1a0 c 5 b9 1a5 d 5 b9 1aa e 5 b9 1af f 5 b9 1b4 0 6 b9 1b9 1 6 b9 1bf 2 6 b9 1c5 3 6 b9 1cb 4 6 b9 1d1 5 6 b9 1d7 6 6 b9 1dd 7 6 b9 1e3 8 6 b9 189 9 6 b9 18f a 6 b9 195 b 6 b9 19b c 6 b9 1a1 d 6 b9 1a7 e 6 b9 1ad f 6 b9 1b3 0 7 b9 1b9 1 7 b9 1c0 2 7 b9 1c7 3 7 b9 1ce 4 7 b9 1d5 5 7 b9 1dc 6 7 b9 1e3 7 7 b9 1ea 8 7 b9 181 9 7 b9 188 a 7 b9 18f b 7 b9 196 c 7 b9 19d d 7 b9 1a4 e 7 b9 1ab f 7 b9 1b2 0 8 b9 1b9 1 8 b9 1b1 2 8 b9 1a9 3 8 b9 1a1 4 8 b9 199 5 8 b9 191 6 8 b9 189 7 8 b9 181 8 8 b9 1f9 9 8 b9 1f1 a 8 b9 1e9 b 8 b9 1e1 c 8 b9 1d9 d 8 b9 1d1 e 8 b9 1c9 f 8 b9 1c1 0 9 b9 1b9 1 9 b9 1b2 2 9 b9 1ab 3 9 b9 1a4 4 9 b9 19d 5 9 b9 196 6 9 b9 18f 7 9 b9 188 8 9 b9 1f1 9 9 b9 1ea a 9 b9 1e3 b 9 b9 1dc c 9 b9 1d5 d 9 b9 1ce e 9 b9 1c7 f 9 b9 1c0 0 a b9 1b9 1 a b9 1b3 2 a b9 1ad 3 a b9 1a7 4 a b9 1a1 5 a b9 19b 6 a b9 195 7 a b9 18f 8 a b9 1e9 9 a b9 1e3 a a b9 1dd b a b9 1d7 c a b9 1d1 d a b9 1cb e a b9 1c5 f a b9 1bf 0 b b9 1b9 1 b b9 1b4 2 b b9 1af 3 b b9 1aa 4 b b9 1a5 5 b b9 1a0 6 b b9 19b 7 b b9 196 8 b b9 1e1 9 b b9 1dc a b b9 1d7 b b b9 1d2 c b b9 1cd d b b9 1c8 e b b9 1c3 f b b9 1be 0 c b9 1b9 1 c b9 1b5 2 c b9 1b1 3 c b9 1ad 4 c b9 1a9 5 c b9 1a5 6 c b9 1a1 7 c b9 19d 8 c b9 1d9 9 c b9 1d5 a c b9 1d1 b c b9 1cd c c b9 1c9 d c b9 1c5 e c b9 1c1 f c b9 1bd 0 d b9 1b9 1 d b9 1b6 2 d b9 1b3 3 d b9 1b0 4 d b9 1ad 5 d b9 1aa 6 d b9 1a7 7 d b9 1a4 8 d b9 1d1 9 d b9 1ce a d b9 1cb b d b9 1c8 c d b9 1c5 d d b9 1c2 e d b9 1bf f d b9 1bc 0 e b9 1b9 1 e b9 1b7 2 e b9 1b5 3 e b9 1b3 4 e b9 1b1 5 e b9 1af 6 e b9 1ad 7 e b9 1ab 8 e b9 1c9 9 e b9 1c7 a e b9 1c5 b e b9 1c3 c e b9 1c1 d e b9 1bf e e b9 1bd f e b9 1bb 0 f b9 1b9 1 f b9 1b8 2 f b9 1b7 3 f b9 1b6 4 f b9 1b5 5 f b9 1b4 6 f b9 1b3 7 f b9 1b2 8 f b9 1c1 9 f b9 1c0 a f b9 1bf b f b9 1be c f b9 1bd d f b9 1bc e f b9 1bb f f b9 1ba 0 0 ba 1ba 1 0 ba 1ba 2 0 ba 1ba 3 0 ba 1ba 4 0 ba 1ba 5 0 ba 1ba 6 0 ba 1ba 7 0 ba 1ba 8 0 ba 1ba 9 0 ba 1ba a 0 ba 1ba b 0 ba 1ba c 0 ba 1ba d 0 ba 1ba e 0 ba 1ba f 0 ba 1ba 0 1 ba 1ba 1 1 ba 1bb 2 1 ba 1bc 3 1 ba 1bd 4 1 ba 1be 5 1 ba 1bf 6 1 ba 1c0 7 1 ba 1c1 8 1 ba 1b2 9 1 ba 1b3 a 1 ba 1b4 b 1 ba 1b5 c 1 ba 1b6 d 1 ba 1b7 e 1 ba 1b8 f 1 ba 1b9 0 2 ba 1ba 1 2 ba 1bc 2 2 ba 1be 3 2 ba 1c0 4 2 ba 1c2 5 2 ba 1c4 6 2 ba 1c6 7 2 ba 1c8 8 2 ba 1aa 9 2 ba 1ac a 2 ba 1ae b 2 ba 1b0 c 2 ba 1b2 d 2 ba 1b4 e 2 ba 1b6 f 2 ba 1b8 0 3 ba 1ba 1 3 ba 1bd 2 3 ba 1c0 3 3 ba 1c3 4 3 ba 1c6 5 3 ba 1c9 6 3 ba 1cc 7 3 ba 1cf 8 3 ba 1a2 9 3 ba 1a5 a 3 ba 1a8 b 3 ba 1ab c 3 ba 1ae d 3 ba 1b1 e 3 ba 1b4 f 3 ba 1b7 0 4 ba 1ba 1 4 ba 1be 2 4 ba 1c2 3 4 ba 1c6 4 4 ba 1ca 5 4 ba 1ce 6 4 ba 1d2 7 4 ba 1d6 8 4 ba 19a 9 4 ba 19e a 4 ba 1a2 b 4 ba 1a6 c 4 ba 1aa d 4 ba 1ae e 4 ba 1b2 f 4 ba 1b6 0 5 ba 1ba 1 5 ba 1bf 2 5 ba 1c4 3 5 ba 1c9 4 5 ba 1ce 5 5 ba 1d3 6 5 ba 1d8 7 5 ba 1dd 8 5 ba 192 9 5 ba 197 a 5 ba 19c b 5 ba 1a1 c 5 ba 1a6 d 5 ba 1ab e 5 ba 1b0 f 5 ba 1b5 0 6 ba 1ba 1 6 ba 1c0 2 6 ba 1c6 3 6 ba 1cc 4 6 ba 1d2 5 6 ba 1d8 6 6 ba 1de 7 6 ba 1e4 8 6 ba 18a 9 6 ba 190 a 6 ba 196 b 6 ba 19c c 6 ba 1a2 d 6 ba 1a8 e 6 ba 1ae f 6 ba 1b4 0 7 ba 1ba 1 7 ba 1c1 2 7 ba 1c8 3 7 ba 1cf 4 7 ba 1d6 5 7 ba 1dd 6 7 ba 1e4 7 7 ba 1eb 8 7 ba 182 9 7 ba 189 a 7 ba 190 b 7 ba 197 c 7 ba 19e d 7 ba 1a5 e 7 ba 1ac f 7 ba 1b3 0 8 ba 1ba 1 8 ba 1b2 2 8 ba 1aa 3 8 ba 1a2 4 8 ba 19a 5 8 ba 192 6 8 ba 18a 7 8 ba 182 8 8 ba 1fa 9 8 ba 1f2 a 8 ba 1ea b 8 ba 1e2 c 8 ba 1da d 8 ba 1d2 e 8 ba 1ca f 8 ba 1c2 0 9 ba 1ba 1 9 ba 1b3 2 9 ba 1ac 3 9 ba 1a5 4 9 ba 19e 5 9 ba 197 6 9 ba 190 7 9 ba 189 8 9 ba 1f2 9 9 ba 1eb a 9 ba 1e4 b 9 ba 1dd c 9 ba 1d6 d 9 ba 1cf e 9 ba 1c8 f 9 ba 1c1 0 a ba 1ba 1 a ba 1b4 2 a ba 1ae 3 a ba 1a8 4 a ba 1a2 5 a ba 19c 6 a ba 196 7 a ba 190 8 a ba 1ea 9 a ba 1e4 a a ba 1de b a ba 1d8 c a ba 1d2 d a ba 1cc e a ba 1c6 f a ba 1c0 0 b ba 1ba 1 b ba 1b5 2 b ba 1b0 3 b ba 1ab 4 b ba 1a6 5 b ba 1a1 6 b ba 19c 7 b ba 197 8 b ba 1e2 9 b ba 1dd a b ba 1d8 b b ba 1d3 c b ba 1ce d b ba 1c9 e b ba 1c4 f b ba 1bf 0 c ba 1ba 1 c ba 1b6 2 c ba 1b2 3 c ba 1ae 4 c ba 1aa 5 c ba 1a6 6 c ba 1a2 7 c ba 19e 8 c ba 1da 9 c ba 1d6 a c ba 1d2 b c ba 1ce c c ba 1ca d c ba 1c6 e c ba 1c2 f c ba 1be 0 d ba 1ba 1 d ba 1b7 2 d ba 1b4 3 d ba 1b1 4 d ba 1ae 5 d ba 1ab 6 d ba 1a8 7 d ba 1a5 8 d ba 1d2 9 d ba 1cf a d ba 1cc b d ba 1c9 c d ba 1c6 d d ba 1c3 e d ba 1c0 f d ba 1bd 0 e ba 1ba 1 e ba 1b8 2 e ba 1b6 3 e ba 1b4 4 e ba 1b2 5 e ba 1b0 6 e ba 1ae 7 e ba 1ac 8 e ba 1ca 9 e ba 1c8 a e ba 1c6 b e ba 1c4 c e ba 1c2 d e ba 1c0 e e ba 1be f e ba 1bc 0 f ba 1ba 1 f ba 1b9 2 f ba 1b8 3 f ba 1b7 4 f ba 1b6 5 f ba 1b5 6 f ba 1b4 7 f ba 1b3 8 f ba 1c2 9 f ba 1c1 a f ba 1c0 b f ba 1bf c f ba 1be d f ba 1bd e f ba 1bc f f ba 1bb 0 0 bb 1bb 1 0 bb 1bb 2 0 bb 1bb 3 0 bb 1bb 4 0 bb 1bb 5 0 bb 1bb 6 0 bb 1bb 7 0 bb 1bb 8 0 bb 1bb 9 0 bb 1bb a 0 bb 1bb b 0 bb 1bb c 0 bb 1bb d 0 bb 1bb e 0 bb 1bb f 0 bb 1bb 0 1 bb 1bb 1 1 bb 1bc 2 1 bb 1bd 3 1 bb 1be 4 1 bb 1bf 5 1 bb 1c0 6 1 bb 1c1 7 1 bb 1c2 8 1 bb 1b3 9 1 bb 1b4 a 1 bb 1b5 b 1 bb 1b6 c 1 bb 1b7 d 1 bb 1b8 e 1 bb 1b9 f 1 bb 1ba 0 2 bb 1bb 1 2 bb 1bd 2 2 bb 1bf 3 2 bb 1c1 4 2 bb 1c3 5 2 bb 1c5 6 2 bb 1c7 7 2 bb 1c9 8 2 bb 1ab 9 2 bb 1ad a 2 bb 1af b 2 bb 1b1 c 2 bb 1b3 d 2 bb 1b5 e 2 bb 1b7 f 2 bb 1b9 0 3 bb 1bb 1 3 bb 1be 2 3 bb 1c1 3 3 bb 1c4 4 3 bb 1c7 5 3 bb 1ca 6 3 bb 1cd 7 3 bb 1d0 8 3 bb 1a3 9 3 bb 1a6 a 3 bb 1a9 b 3 bb 1ac c 3 bb 1af d 3 bb 1b2 e 3 bb 1b5 f 3 bb 1b8 0 4 bb 1bb 1 4 bb 1bf 2 4 bb 1c3 3 4 bb 1c7 4 4 bb 1cb 5 4 bb 1cf 6 4 bb 1d3 7 4 bb 1d7 8 4 bb 19b 9 4 bb 19f a 4 bb 1a3 b 4 bb 1a7 c 4 bb 1ab d 4 bb 1af e 4 bb 1b3 f 4 bb 1b7 0 5 bb 1bb 1 5 bb 1c0 2 5 bb 1c5 3 5 bb 1ca 4 5 bb 1cf 5 5 bb 1d4 6 5 bb 1d9 7 5 bb 1de 8 5 bb 193 9 5 bb 198 a 5 bb 19d b 5 bb 1a2 c 5 bb 1a7 d 5 bb 1ac e 5 bb 1b1 f 5 bb 1b6 0 6 bb 1bb 1 6 bb 1c1 2 6 bb 1c7 3 6 bb 1cd 4 6 bb 1d3 5 6 bb 1d9 6 6 bb 1df 7 6 bb 1e5 8 6 bb 18b 9 6 bb 191 a 6 bb 197 b 6 bb 19d c 6 bb 1a3 d 6 bb 1a9 e 6 bb 1af f 6 bb 1b5 0 7 bb 1bb 1 7 bb 1c2 2 7 bb 1c9 3 7 bb 1d0 4 7 bb 1d7 5 7 bb 1de 6 7 bb 1e5 7 7 bb 1ec 8 7 bb 183 9 7 bb 18a a 7 bb 191 b 7 bb 198 c 7 bb 19f d 7 bb 1a6 e 7 bb 1ad f 7 bb 1b4 0 8 bb 1bb 1 8 bb 1b3 2 8 bb 1ab 3 8 bb 1a3 4 8 bb 19b 5 8 bb 193 6 8 bb 18b 7 8 bb 183 8 8 bb 1fb 9 8 bb 1f3 a 8 bb 1eb b 8 bb 1e3 c 8 bb 1db d 8 bb 1d3 e 8 bb 1cb f 8 bb 1c3 0 9 bb 1bb 1 9 bb 1b4 2 9 bb 1ad 3 9 bb 1a6 4 9 bb 19f 5 9 bb 198 6 9 bb 191 7 9 bb 18a 8 9 bb 1f3 9 9 bb 1ec a 9 bb 1e5 b 9 bb 1de c 9 bb 1d7 d 9 bb 1d0 e 9 bb 1c9 f 9 bb 1c2 0 a bb 1bb 1 a bb 1b5 2 a bb 1af 3 a bb 1a9 4 a bb 1a3 5 a bb 19d 6 a bb 197 7 a bb 191 8 a bb 1eb 9 a bb 1e5 a a bb 1df b a bb 1d9 c a bb 1d3 d a bb 1cd e a bb 1c7 f a bb 1c1 0 b bb 1bb 1 b bb 1b6 2 b bb 1b1 3 b bb 1ac 4 b bb 1a7 5 b bb 1a2 6 b bb 19d 7 b bb 198 8 b bb 1e3 9 b bb 1de a b bb 1d9 b b bb 1d4 c b bb 1cf d b bb 1ca e b bb 1c5 f b bb 1c0 0 c bb 1bb 1 c bb 1b7 2 c bb 1b3 3 c bb 1af 4 c bb 1ab 5 c bb 1a7 6 c bb 1a3 7 c bb 19f 8 c bb 1db 9 c bb 1d7 a c bb 1d3 b c bb 1cf c c bb 1cb d c bb 1c7 e c bb 1c3 f c bb 1bf 0 d bb 1bb 1 d bb 1b8 2 d bb 1b5 3 d bb 1b2 4 d bb 1af 5 d bb 1ac 6 d bb 1a9 7 d bb 1a6 8 d bb 1d3 9 d bb 1d0 a d bb 1cd b d bb 1ca c d bb 1c7 d d bb 1c4 e d bb 1c1 f d bb 1be 0 e bb 1bb 1 e bb 1b9 2 e bb 1b7 3 e bb 1b5 4 e bb 1b3 5 e bb 1b1 6 e bb 1af 7 e bb 1ad 8 e bb 1cb 9 e bb 1c9 a e bb 1c7 b e bb 1c5 c e bb 1c3 d e bb 1c1 e e bb 1bf f e bb 1bd 0 f bb 1bb 1 f bb 1ba 2 f bb 1b9 3 f bb 1b8 4 f bb 1b7 5 f bb 1b6 6 f bb 1b5 7 f bb 1b4 8 f bb 1c3 9 f bb 1c2 a f bb 1c1 b f bb 1c0 c f bb 1bf d f bb 1be e f bb 1bd f f bb 1bc 0 0 bc 1bc 1 0 bc 1bc 2 0 bc 1bc 3 0 bc 1bc 4 0 bc 1bc 5 0 bc 1bc 6 0 bc 1bc 7 0 bc 1bc 8 0 bc 1bc 9 0 bc 1bc a 0 bc 1bc b 0 bc 1bc c 0 bc 1bc d 0 bc 1bc e 0 bc 1bc f 0 bc 1bc 0 1 bc 1bc 1 1 bc 1bd 2 1 bc 1be 3 1 bc 1bf 4 1 bc 1c0 5 1 bc 1c1 6 1 bc 1c2 7 1 bc 1c3 8 1 bc 1b4 9 1 bc 1b5 a 1 bc 1b6 b 1 bc 1b7 c 1 bc 1b8 d 1 bc 1b9 e 1 bc 1ba f 1 bc 1bb 0 2 bc 1bc 1 2 bc 1be 2 2 bc 1c0 3 2 bc 1c2 4 2 bc 1c4 5 2 bc 1c6 6 2 bc 1c8 7 2 bc 1ca 8 2 bc 1ac 9 2 bc 1ae a 2 bc 1b0 b 2 bc 1b2 c 2 bc 1b4 d 2 bc 1b6 e 2 bc 1b8 f 2 bc 1ba 0 3 bc 1bc 1 3 bc 1bf 2 3 bc 1c2 3 3 bc 1c5 4 3 bc 1c8 5 3 bc 1cb 6 3 bc 1ce 7 3 bc 1d1 8 3 bc 1a4 9 3 bc 1a7 a 3 bc 1aa b 3 bc 1ad c 3 bc 1b0 d 3 bc 1b3 e 3 bc 1b6 f 3 bc 1b9 0 4 bc 1bc 1 4 bc 1c0 2 4 bc 1c4 3 4 bc 1c8 4 4 bc 1cc 5 4 bc 1d0 6 4 bc 1d4 7 4 bc 1d8 8 4 bc 19c 9 4 bc 1a0 a 4 bc 1a4 b 4 bc 1a8 c 4 bc 1ac d 4 bc 1b0 e 4 bc 1b4 f 4 bc 1b8 0 5 bc 1bc 1 5 bc 1c1 2 5 bc 1c6 3 5 bc 1cb 4 5 bc 1d0 5 5 bc 1d5 6 5 bc 1da 7 5 bc 1df 8 5 bc 194 9 5 bc 199 a 5 bc 19e b 5 bc 1a3 c 5 bc 1a8 d 5 bc 1ad e 5 bc 1b2 f 5 bc 1b7 0 6 bc 1bc 1 6 bc 1c2 2 6 bc 1c8 3 6 bc 1ce 4 6 bc 1d4 5 6 bc 1da 6 6 bc 1e0 7 6 bc 1e6 8 6 bc 18c 9 6 bc 192 a 6 bc 198 b 6 bc 19e c 6 bc 1a4 d 6 bc 1aa e 6 bc 1b0 f 6 bc 1b6 0 7 bc 1bc 1 7 bc 1c3 2 7 bc 1ca 3 7 bc 1d1 4 7 bc 1d8 5 7 bc 1df 6 7 bc 1e6 7 7 bc 1ed 8 7 bc 184 9 7 bc 18b a 7 bc 192 b 7 bc 199 c 7 bc 1a0 d 7 bc 1a7 e 7 bc 1ae f 7 bc 1b5 0 8 bc 1bc 1 8 bc 1b4 2 8 bc 1ac 3 8 bc 1a4 4 8 bc 19c 5 8 bc 194 6 8 bc 18c 7 8 bc 184 8 8 bc 1fc 9 8 bc 1f4 a 8 bc 1ec b 8 bc 1e4 c 8 bc 1dc d 8 bc 1d4 e 8 bc 1cc f 8 bc 1c4 0 9 bc 1bc 1 9 bc 1b5 2 9 bc 1ae 3 9 bc 1a7 4 9 bc 1a0 5 9 bc 199 6 9 bc 192 7 9 bc 18b 8 9 bc 1f4 9 9 bc 1ed a 9 bc 1e6 b 9 bc 1df c 9 bc 1d8 d 9 bc 1d1 e 9 bc 1ca f 9 bc 1c3 0 a bc 1bc 1 a bc 1b6 2 a bc 1b0 3 a bc 1aa 4 a bc 1a4 5 a bc 19e 6 a bc 198 7 a bc 192 8 a bc 1ec 9 a bc 1e6 a a bc 1e0 b a bc 1da c a bc 1d4 d a bc 1ce e a bc 1c8 f a bc 1c2 0 b bc 1bc 1 b bc 1b7 2 b bc 1b2 3 b bc 1ad 4 b bc 1a8 5 b bc 1a3 6 b bc 19e 7 b bc 199 8 b bc 1e4 9 b bc 1df a b bc 1da b b bc 1d5 c b bc 1d0 d b bc 1cb e b bc 1c6 f b bc 1c1 0 c bc 1bc 1 c bc 1b8 2 c bc 1b4 3 c bc 1b0 4 c bc 1ac 5 c bc 1a8 6 c bc 1a4 7 c bc 1a0 8 c bc 1dc 9 c bc 1d8 a c bc 1d4 b c bc 1d0 c c bc 1cc d c bc 1c8 e c bc 1c4 f c bc 1c0 0 d bc 1bc 1 d bc 1b9 2 d bc 1b6 3 d bc 1b3 4 d bc 1b0 5 d bc 1ad 6 d bc 1aa 7 d bc 1a7 8 d bc 1d4 9 d bc 1d1 a d bc 1ce b d bc 1cb c d bc 1c8 d d bc 1c5 e d bc 1c2 f d bc 1bf 0 e bc 1bc 1 e bc 1ba 2 e bc 1b8 3 e bc 1b6 4 e bc 1b4 5 e bc 1b2 6 e bc 1b0 7 e bc 1ae 8 e bc 1cc 9 e bc 1ca a e bc 1c8 b e bc 1c6 c e bc 1c4 d e bc 1c2 e e bc 1c0 f e bc 1be 0 f bc 1bc 1 f bc 1bb 2 f bc 1ba 3 f bc 1b9 4 f bc 1b8 5 f bc 1b7 6 f bc 1b6 7 f bc 1b5 8 f bc 1c4 9 f bc 1c3 a f bc 1c2 b f bc 1c1 c f bc 1c0 d f bc 1bf e f bc 1be f f bc 1bd 0 0 bd 1bd 1 0 bd 1bd 2 0 bd 1bd 3 0 bd 1bd 4 0 bd 1bd 5 0 bd 1bd 6 0 bd 1bd 7 0 bd 1bd 8 0 bd 1bd 9 0 bd 1bd a 0 bd 1bd b 0 bd 1bd c 0 bd 1bd d 0 bd 1bd e 0 bd 1bd f 0 bd 1bd 0 1 bd 1bd 1 1 bd 1be 2 1 bd 1bf 3 1 bd 1c0 4 1 bd 1c1 5 1 bd 1c2 6 1 bd 1c3 7 1 bd 1c4 8 1 bd 1b5 9 1 bd 1b6 a 1 bd 1b7 b 1 bd 1b8 c 1 bd 1b9 d 1 bd 1ba e 1 bd 1bb f 1 bd 1bc 0 2 bd 1bd 1 2 bd 1bf 2 2 bd 1c1 3 2 bd 1c3 4 2 bd 1c5 5 2 bd 1c7 6 2 bd 1c9 7 2 bd 1cb 8 2 bd 1ad 9 2 bd 1af a 2 bd 1b1 b 2 bd 1b3 c 2 bd 1b5 d 2 bd 1b7 e 2 bd 1b9 f 2 bd 1bb 0 3 bd 1bd 1 3 bd 1c0 2 3 bd 1c3 3 3 bd 1c6 4 3 bd 1c9 5 3 bd 1cc 6 3 bd 1cf 7 3 bd 1d2 8 3 bd 1a5 9 3 bd 1a8 a 3 bd 1ab b 3 bd 1ae c 3 bd 1b1 d 3 bd 1b4 e 3 bd 1b7 f 3 bd 1ba 0 4 bd 1bd 1 4 bd 1c1 2 4 bd 1c5 3 4 bd 1c9 4 4 bd 1cd 5 4 bd 1d1 6 4 bd 1d5 7 4 bd 1d9 8 4 bd 19d 9 4 bd 1a1 a 4 bd 1a5 b 4 bd 1a9 c 4 bd 1ad d 4 bd 1b1 e 4 bd 1b5 f 4 bd 1b9 0 5 bd 1bd 1 5 bd 1c2 2 5 bd 1c7 3 5 bd 1cc 4 5 bd 1d1 5 5 bd 1d6 6 5 bd 1db 7 5 bd 1e0 8 5 bd 195 9 5 bd 19a a 5 bd 19f b 5 bd 1a4 c 5 bd 1a9 d 5 bd 1ae e 5 bd 1b3 f 5 bd 1b8 0 6 bd 1bd 1 6 bd 1c3 2 6 bd 1c9 3 6 bd 1cf 4 6 bd 1d5 5 6 bd 1db 6 6 bd 1e1 7 6 bd 1e7 8 6 bd 18d 9 6 bd 193 a 6 bd 199 b 6 bd 19f c 6 bd 1a5 d 6 bd 1ab e 6 bd 1b1 f 6 bd 1b7 0 7 bd 1bd 1 7 bd 1c4 2 7 bd 1cb 3 7 bd 1d2 4 7 bd 1d9 5 7 bd 1e0 6 7 bd 1e7 7 7 bd 1ee 8 7 bd 185 9 7 bd 18c a 7 bd 193 b 7 bd 19a c 7 bd 1a1 d 7 bd 1a8 e 7 bd 1af f 7 bd 1b6 0 8 bd 1bd 1 8 bd 1b5 2 8 bd 1ad 3 8 bd 1a5 4 8 bd 19d 5 8 bd 195 6 8 bd 18d 7 8 bd 185 8 8 bd 1fd 9 8 bd 1f5 a 8 bd 1ed b 8 bd 1e5 c 8 bd 1dd d 8 bd 1d5 e 8 bd 1cd f 8 bd 1c5 0 9 bd 1bd 1 9 bd 1b6 2 9 bd 1af 3 9 bd 1a8 4 9 bd 1a1 5 9 bd 19a 6 9 bd 193 7 9 bd 18c 8 9 bd 1f5 9 9 bd 1ee a 9 bd 1e7 b 9 bd 1e0 c 9 bd 1d9 d 9 bd 1d2 e 9 bd 1cb f 9 bd 1c4 0 a bd 1bd 1 a bd 1b7 2 a bd 1b1 3 a bd 1ab 4 a bd 1a5 5 a bd 19f 6 a bd 199 7 a bd 193 8 a bd 1ed 9 a bd 1e7 a a bd 1e1 b a bd 1db c a bd 1d5 d a bd 1cf e a bd 1c9 f a bd 1c3 0 b bd 1bd 1 b bd 1b8 2 b bd 1b3 3 b bd 1ae 4 b bd 1a9 5 b bd 1a4 6 b bd 19f 7 b bd 19a 8 b bd 1e5 9 b bd 1e0 a b bd 1db b b bd 1d6 c b bd 1d1 d b bd 1cc e b bd 1c7 f b bd 1c2 0 c bd 1bd 1 c bd 1b9 2 c bd 1b5 3 c bd 1b1 4 c bd 1ad 5 c bd 1a9 6 c bd 1a5 7 c bd 1a1 8 c bd 1dd 9 c bd 1d9 a c bd 1d5 b c bd 1d1 c c bd 1cd d c bd 1c9 e c bd 1c5 f c bd 1c1 0 d bd 1bd 1 d bd 1ba 2 d bd 1b7 3 d bd 1b4 4 d bd 1b1 5 d bd 1ae 6 d bd 1ab 7 d bd 1a8 8 d bd 1d5 9 d bd 1d2 a d bd 1cf b d bd 1cc c d bd 1c9 d d bd 1c6 e d bd 1c3 f d bd 1c0 0 e bd 1bd 1 e bd 1bb 2 e bd 1b9 3 e bd 1b7 4 e bd 1b5 5 e bd 1b3 6 e bd 1b1 7 e bd 1af 8 e bd 1cd 9 e bd 1cb a e bd 1c9 b e bd 1c7 c e bd 1c5 d e bd 1c3 e e bd 1c1 f e bd 1bf 0 f bd 1bd 1 f bd 1bc 2 f bd 1bb 3 f bd 1ba 4 f bd 1b9 5 f bd 1b8 6 f bd 1b7 7 f bd 1b6 8 f bd 1c5 9 f bd 1c4 a f bd 1c3 b f bd 1c2 c f bd 1c1 d f bd 1c0 e f bd 1bf f f bd 1be 0 0 be 1be 1 0 be 1be 2 0 be 1be 3 0 be 1be 4 0 be 1be 5 0 be 1be 6 0 be 1be 7 0 be 1be 8 0 be 1be 9 0 be 1be a 0 be 1be b 0 be 1be c 0 be 1be d 0 be 1be e 0 be 1be f 0 be 1be 0 1 be 1be 1 1 be 1bf 2 1 be 1c0 3 1 be 1c1 4 1 be 1c2 5 1 be 1c3 6 1 be 1c4 7 1 be 1c5 8 1 be 1b6 9 1 be 1b7 a 1 be 1b8 b 1 be 1b9 c 1 be 1ba d 1 be 1bb e 1 be 1bc f 1 be 1bd 0 2 be 1be 1 2 be 1c0 2 2 be 1c2 3 2 be 1c4 4 2 be 1c6 5 2 be 1c8 6 2 be 1ca 7 2 be 1cc 8 2 be 1ae 9 2 be 1b0 a 2 be 1b2 b 2 be 1b4 c 2 be 1b6 d 2 be 1b8 e 2 be 1ba f 2 be 1bc 0 3 be 1be 1 3 be 1c1 2 3 be 1c4 3 3 be 1c7 4 3 be 1ca 5 3 be 1cd 6 3 be 1d0 7 3 be 1d3 8 3 be 1a6 9 3 be 1a9 a 3 be 1ac b 3 be 1af c 3 be 1b2 d 3 be 1b5 e 3 be 1b8 f 3 be 1bb 0 4 be 1be 1 4 be 1c2 2 4 be 1c6 3 4 be 1ca 4 4 be 1ce 5 4 be 1d2 6 4 be 1d6 7 4 be 1da 8 4 be 19e 9 4 be 1a2 a 4 be 1a6 b 4 be 1aa c 4 be 1ae d 4 be 1b2 e 4 be 1b6 f 4 be 1ba 0 5 be 1be 1 5 be 1c3 2 5 be 1c8 3 5 be 1cd 4 5 be 1d2 5 5 be 1d7 6 5 be 1dc 7 5 be 1e1 8 5 be 196 9 5 be 19b a 5 be 1a0 b 5 be 1a5 c 5 be 1aa d 5 be 1af e 5 be 1b4 f 5 be 1b9 0 6 be 1be 1 6 be 1c4 2 6 be 1ca 3 6 be 1d0 4 6 be 1d6 5 6 be 1dc 6 6 be 1e2 7 6 be 1e8 8 6 be 18e 9 6 be 194 a 6 be 19a b 6 be 1a0 c 6 be 1a6 d 6 be 1ac e 6 be 1b2 f 6 be 1b8 0 7 be 1be 1 7 be 1c5 2 7 be 1cc 3 7 be 1d3 4 7 be 1da 5 7 be 1e1 6 7 be 1e8 7 7 be 1ef 8 7 be 186 9 7 be 18d a 7 be 194 b 7 be 19b c 7 be 1a2 d 7 be 1a9 e 7 be 1b0 f 7 be 1b7 0 8 be 1be 1 8 be 1b6 2 8 be 1ae 3 8 be 1a6 4 8 be 19e 5 8 be 196 6 8 be 18e 7 8 be 186 8 8 be 1fe 9 8 be 1f6 a 8 be 1ee b 8 be 1e6 c 8 be 1de d 8 be 1d6 e 8 be 1ce f 8 be 1c6 0 9 be 1be 1 9 be 1b7 2 9 be 1b0 3 9 be 1a9 4 9 be 1a2 5 9 be 19b 6 9 be 194 7 9 be 18d 8 9 be 1f6 9 9 be 1ef a 9 be 1e8 b 9 be 1e1 c 9 be 1da d 9 be 1d3 e 9 be 1cc f 9 be 1c5 0 a be 1be 1 a be 1b8 2 a be 1b2 3 a be 1ac 4 a be 1a6 5 a be 1a0 6 a be 19a 7 a be 194 8 a be 1ee 9 a be 1e8 a a be 1e2 b a be 1dc c a be 1d6 d a be 1d0 e a be 1ca f a be 1c4 0 b be 1be 1 b be 1b9 2 b be 1b4 3 b be 1af 4 b be 1aa 5 b be 1a5 6 b be 1a0 7 b be 19b 8 b be 1e6 9 b be 1e1 a b be 1dc b b be 1d7 c b be 1d2 d b be 1cd e b be 1c8 f b be 1c3 0 c be 1be 1 c be 1ba 2 c be 1b6 3 c be 1b2 4 c be 1ae 5 c be 1aa 6 c be 1a6 7 c be 1a2 8 c be 1de 9 c be 1da a c be 1d6 b c be 1d2 c c be 1ce d c be 1ca e c be 1c6 f c be 1c2 0 d be 1be 1 d be 1bb 2 d be 1b8 3 d be 1b5 4 d be 1b2 5 d be 1af 6 d be 1ac 7 d be 1a9 8 d be 1d6 9 d be 1d3 a d be 1d0 b d be 1cd c d be 1ca d d be 1c7 e d be 1c4 f d be 1c1 0 e be 1be 1 e be 1bc 2 e be 1ba 3 e be 1b8 4 e be 1b6 5 e be 1b4 6 e be 1b2 7 e be 1b0 8 e be 1ce 9 e be 1cc a e be 1ca b e be 1c8 c e be 1c6 d e be 1c4 e e be 1c2 f e be 1c0 0 f be 1be 1 f be 1bd 2 f be 1bc 3 f be 1bb 4 f be 1ba 5 f be 1b9 6 f be 1b8 7 f be 1b7 8 f be 1c6 9 f be 1c5 a f be 1c4 b f be 1c3 c f be 1c2 d f be 1c1 e f be 1c0 f f be 1bf 0 0 bf 1bf 1 0 bf 1bf 2 0 bf 1bf 3 0 bf 1bf 4 0 bf 1bf 5 0 bf 1bf 6 0 bf 1bf 7 0 bf 1bf 8 0 bf 1bf 9 0 bf 1bf a 0 bf 1bf b 0 bf 1bf c 0 bf 1bf d 0 bf 1bf e 0 bf 1bf f 0 bf 1bf 0 1 bf 1bf 1 1 bf 1c0 2 1 bf 1c1 3 1 bf 1c2 4 1 bf 1c3 5 1 bf 1c4 6 1 bf 1c5 7 1 bf 1c6 8 1 bf 1b7 9 1 bf 1b8 a 1 bf 1b9 b 1 bf 1ba c 1 bf 1bb d 1 bf 1bc e 1 bf 1bd f 1 bf 1be 0 2 bf 1bf 1 2 bf 1c1 2 2 bf 1c3 3 2 bf 1c5 4 2 bf 1c7 5 2 bf 1c9 6 2 bf 1cb 7 2 bf 1cd 8 2 bf 1af 9 2 bf 1b1 a 2 bf 1b3 b 2 bf 1b5 c 2 bf 1b7 d 2 bf 1b9 e 2 bf 1bb f 2 bf 1bd 0 3 bf 1bf 1 3 bf 1c2 2 3 bf 1c5 3 3 bf 1c8 4 3 bf 1cb 5 3 bf 1ce 6 3 bf 1d1 7 3 bf 1d4 8 3 bf 1a7 9 3 bf 1aa a 3 bf 1ad b 3 bf 1b0 c 3 bf 1b3 d 3 bf 1b6 e 3 bf 1b9 f 3 bf 1bc 0 4 bf 1bf 1 4 bf 1c3 2 4 bf 1c7 3 4 bf 1cb 4 4 bf 1cf 5 4 bf 1d3 6 4 bf 1d7 7 4 bf 1db 8 4 bf 19f 9 4 bf 1a3 a 4 bf 1a7 b 4 bf 1ab c 4 bf 1af d 4 bf 1b3 e 4 bf 1b7 f 4 bf 1bb 0 5 bf 1bf 1 5 bf 1c4 2 5 bf 1c9 3 5 bf 1ce 4 5 bf 1d3 5 5 bf 1d8 6 5 bf 1dd 7 5 bf 1e2 8 5 bf 197 9 5 bf 19c a 5 bf 1a1 b 5 bf 1a6 c 5 bf 1ab d 5 bf 1b0 e 5 bf 1b5 f 5 bf 1ba 0 6 bf 1bf 1 6 bf 1c5 2 6 bf 1cb 3 6 bf 1d1 4 6 bf 1d7 5 6 bf 1dd 6 6 bf 1e3 7 6 bf 1e9 8 6 bf 18f 9 6 bf 195 a 6 bf 19b b 6 bf 1a1 c 6 bf 1a7 d 6 bf 1ad e 6 bf 1b3 f 6 bf 1b9 0 7 bf 1bf 1 7 bf 1c6 2 7 bf 1cd 3 7 bf 1d4 4 7 bf 1db 5 7 bf 1e2 6 7 bf 1e9 7 7 bf 1f0 8 7 bf 187 9 7 bf 18e a 7 bf 195 b 7 bf 19c c 7 bf 1a3 d 7 bf 1aa e 7 bf 1b1 f 7 bf 1b8 0 8 bf 1bf 1 8 bf 1b7 2 8 bf 1af 3 8 bf 1a7 4 8 bf 19f 5 8 bf 197 6 8 bf 18f 7 8 bf 187 8 8 bf 1ff 9 8 bf 1f7 a 8 bf 1ef b 8 bf 1e7 c 8 bf 1df d 8 bf 1d7 e 8 bf 1cf f 8 bf 1c7 0 9 bf 1bf 1 9 bf 1b8 2 9 bf 1b1 3 9 bf 1aa 4 9 bf 1a3 5 9 bf 19c 6 9 bf 195 7 9 bf 18e 8 9 bf 1f7 9 9 bf 1f0 a 9 bf 1e9 b 9 bf 1e2 c 9 bf 1db d 9 bf 1d4 e 9 bf 1cd f 9 bf 1c6 0 a bf 1bf 1 a bf 1b9 2 a bf 1b3 3 a bf 1ad 4 a bf 1a7 5 a bf 1a1 6 a bf 19b 7 a bf 195 8 a bf 1ef 9 a bf 1e9 a a bf 1e3 b a bf 1dd c a bf 1d7 d a bf 1d1 e a bf 1cb f a bf 1c5 0 b bf 1bf 1 b bf 1ba 2 b bf 1b5 3 b bf 1b0 4 b bf 1ab 5 b bf 1a6 6 b bf 1a1 7 b bf 19c 8 b bf 1e7 9 b bf 1e2 a b bf 1dd b b bf 1d8 c b bf 1d3 d b bf 1ce e b bf 1c9 f b bf 1c4 0 c bf 1bf 1 c bf 1bb 2 c bf 1b7 3 c bf 1b3 4 c bf 1af 5 c bf 1ab 6 c bf 1a7 7 c bf 1a3 8 c bf 1df 9 c bf 1db a c bf 1d7 b c bf 1d3 c c bf 1cf d c bf 1cb e c bf 1c7 f c bf 1c3 0 d bf 1bf 1 d bf 1bc 2 d bf 1b9 3 d bf 1b6 4 d bf 1b3 5 d bf 1b0 6 d bf 1ad 7 d bf 1aa 8 d bf 1d7 9 d bf 1d4 a d bf 1d1 b d bf 1ce c d bf 1cb d d bf 1c8 e d bf 1c5 f d bf 1c2 0 e bf 1bf 1 e bf 1bd 2 e bf 1bb 3 e bf 1b9 4 e bf 1b7 5 e bf 1b5 6 e bf 1b3 7 e bf 1b1 8 e bf 1cf 9 e bf 1cd a e bf 1cb b e bf 1c9 c e bf 1c7 d e bf 1c5 e e bf 1c3 f e bf 1c1 0 f bf 1bf 1 f bf 1be 2 f bf 1bd 3 f bf 1bc 4 f bf 1bb 5 f bf 1ba 6 f bf 1b9 7 f bf 1b8 8 f bf 1c7 9 f bf 1c6 a f bf 1c5 b f bf 1c4 c f bf 1c3 d f bf 1c2 e f bf 1c1 f f bf 1c0 0 0 c0 1c0 1 0 c0 1c0 2 0 c0 1c0 3 0 c0 1c0 4 0 c0 1c0 5 0 c0 1c0 6 0 c0 1c0 7 0 c0 1c0 8 0 c0 1c0 9 0 c0 1c0 a 0 c0 1c0 b 0 c0 1c0 c 0 c0 1c0 d 0 c0 1c0 e 0 c0 1c0 f 0 c0 1c0 0 1 c0 1c0 1 1 c0 1c1 2 1 c0 1c2 3 1 c0 1c3 4 1 c0 1c4 5 1 c0 1c5 6 1 c0 1c6 7 1 c0 1c7 8 1 c0 1b8 9 1 c0 1b9 a 1 c0 1ba b 1 c0 1bb c 1 c0 1bc d 1 c0 1bd e 1 c0 1be f 1 c0 1bf 0 2 c0 1c0 1 2 c0 1c2 2 2 c0 1c4 3 2 c0 1c6 4 2 c0 1c8 5 2 c0 1ca 6 2 c0 1cc 7 2 c0 1ce 8 2 c0 1b0 9 2 c0 1b2 a 2 c0 1b4 b 2 c0 1b6 c 2 c0 1b8 d 2 c0 1ba e 2 c0 1bc f 2 c0 1be 0 3 c0 1c0 1 3 c0 1c3 2 3 c0 1c6 3 3 c0 1c9 4 3 c0 1cc 5 3 c0 1cf 6 3 c0 1d2 7 3 c0 1d5 8 3 c0 1a8 9 3 c0 1ab a 3 c0 1ae b 3 c0 1b1 c 3 c0 1b4 d 3 c0 1b7 e 3 c0 1ba f 3 c0 1bd 0 4 c0 1c0 1 4 c0 1c4 2 4 c0 1c8 3 4 c0 1cc 4 4 c0 1d0 5 4 c0 1d4 6 4 c0 1d8 7 4 c0 1dc 8 4 c0 1a0 9 4 c0 1a4 a 4 c0 1a8 b 4 c0 1ac c 4 c0 1b0 d 4 c0 1b4 e 4 c0 1b8 f 4 c0 1bc 0 5 c0 1c0 1 5 c0 1c5 2 5 c0 1ca 3 5 c0 1cf 4 5 c0 1d4 5 5 c0 1d9 6 5 c0 1de 7 5 c0 1e3 8 5 c0 198 9 5 c0 19d a 5 c0 1a2 b 5 c0 1a7 c 5 c0 1ac d 5 c0 1b1 e 5 c0 1b6 f 5 c0 1bb 0 6 c0 1c0 1 6 c0 1c6 2 6 c0 1cc 3 6 c0 1d2 4 6 c0 1d8 5 6 c0 1de 6 6 c0 1e4 7 6 c0 1ea 8 6 c0 190 9 6 c0 196 a 6 c0 19c b 6 c0 1a2 c 6 c0 1a8 d 6 c0 1ae e 6 c0 1b4 f 6 c0 1ba 0 7 c0 1c0 1 7 c0 1c7 2 7 c0 1ce 3 7 c0 1d5 4 7 c0 1dc 5 7 c0 1e3 6 7 c0 1ea 7 7 c0 1f1 8 7 c0 188 9 7 c0 18f a 7 c0 196 b 7 c0 19d c 7 c0 1a4 d 7 c0 1ab e 7 c0 1b2 f 7 c0 1b9 0 8 c0 1c0 1 8 c0 1b8 2 8 c0 1b0 3 8 c0 1a8 4 8 c0 1a0 5 8 c0 198 6 8 c0 190 7 8 c0 188 8 8 c0 000 9 8 c0 1f8 a 8 c0 1f0 b 8 c0 1e8 c 8 c0 1e0 d 8 c0 1d8 e 8 c0 1d0 f 8 c0 1c8 0 9 c0 1c0 1 9 c0 1b9 2 9 c0 1b2 3 9 c0 1ab 4 9 c0 1a4 5 9 c0 19d 6 9 c0 196 7 9 c0 18f 8 9 c0 1f8 9 9 c0 1f1 a 9 c0 1ea b 9 c0 1e3 c 9 c0 1dc d 9 c0 1d5 e 9 c0 1ce f 9 c0 1c7 0 a c0 1c0 1 a c0 1ba 2 a c0 1b4 3 a c0 1ae 4 a c0 1a8 5 a c0 1a2 6 a c0 19c 7 a c0 196 8 a c0 1f0 9 a c0 1ea a a c0 1e4 b a c0 1de c a c0 1d8 d a c0 1d2 e a c0 1cc f a c0 1c6 0 b c0 1c0 1 b c0 1bb 2 b c0 1b6 3 b c0 1b1 4 b c0 1ac 5 b c0 1a7 6 b c0 1a2 7 b c0 19d 8 b c0 1e8 9 b c0 1e3 a b c0 1de b b c0 1d9 c b c0 1d4 d b c0 1cf e b c0 1ca f b c0 1c5 0 c c0 1c0 1 c c0 1bc 2 c c0 1b8 3 c c0 1b4 4 c c0 1b0 5 c c0 1ac 6 c c0 1a8 7 c c0 1a4 8 c c0 1e0 9 c c0 1dc a c c0 1d8 b c c0 1d4 c c c0 1d0 d c c0 1cc e c c0 1c8 f c c0 1c4 0 d c0 1c0 1 d c0 1bd 2 d c0 1ba 3 d c0 1b7 4 d c0 1b4 5 d c0 1b1 6 d c0 1ae 7 d c0 1ab 8 d c0 1d8 9 d c0 1d5 a d c0 1d2 b d c0 1cf c d c0 1cc d d c0 1c9 e d c0 1c6 f d c0 1c3 0 e c0 1c0 1 e c0 1be 2 e c0 1bc 3 e c0 1ba 4 e c0 1b8 5 e c0 1b6 6 e c0 1b4 7 e c0 1b2 8 e c0 1d0 9 e c0 1ce a e c0 1cc b e c0 1ca c e c0 1c8 d e c0 1c6 e e c0 1c4 f e c0 1c2 0 f c0 1c0 1 f c0 1bf 2 f c0 1be 3 f c0 1bd 4 f c0 1bc 5 f c0 1bb 6 f c0 1ba 7 f c0 1b9 8 f c0 1c8 9 f c0 1c7 a f c0 1c6 b f c0 1c5 c f c0 1c4 d f c0 1c3 e f c0 1c2 f f c0 1c1 0 0 c1 1c1 1 0 c1 1c1 2 0 c1 1c1 3 0 c1 1c1 4 0 c1 1c1 5 0 c1 1c1 6 0 c1 1c1 7 0 c1 1c1 8 0 c1 1c1 9 0 c1 1c1 a 0 c1 1c1 b 0 c1 1c1 c 0 c1 1c1 d 0 c1 1c1 e 0 c1 1c1 f 0 c1 1c1 0 1 c1 1c1 1 1 c1 1c2 2 1 c1 1c3 3 1 c1 1c4 4 1 c1 1c5 5 1 c1 1c6 6 1 c1 1c7 7 1 c1 1c8 8 1 c1 1b9 9 1 c1 1ba a 1 c1 1bb b 1 c1 1bc c 1 c1 1bd d 1 c1 1be e 1 c1 1bf f 1 c1 1c0 0 2 c1 1c1 1 2 c1 1c3 2 2 c1 1c5 3 2 c1 1c7 4 2 c1 1c9 5 2 c1 1cb 6 2 c1 1cd 7 2 c1 1cf 8 2 c1 1b1 9 2 c1 1b3 a 2 c1 1b5 b 2 c1 1b7 c 2 c1 1b9 d 2 c1 1bb e 2 c1 1bd f 2 c1 1bf 0 3 c1 1c1 1 3 c1 1c4 2 3 c1 1c7 3 3 c1 1ca 4 3 c1 1cd 5 3 c1 1d0 6 3 c1 1d3 7 3 c1 1d6 8 3 c1 1a9 9 3 c1 1ac a 3 c1 1af b 3 c1 1b2 c 3 c1 1b5 d 3 c1 1b8 e 3 c1 1bb f 3 c1 1be 0 4 c1 1c1 1 4 c1 1c5 2 4 c1 1c9 3 4 c1 1cd 4 4 c1 1d1 5 4 c1 1d5 6 4 c1 1d9 7 4 c1 1dd 8 4 c1 1a1 9 4 c1 1a5 a 4 c1 1a9 b 4 c1 1ad c 4 c1 1b1 d 4 c1 1b5 e 4 c1 1b9 f 4 c1 1bd 0 5 c1 1c1 1 5 c1 1c6 2 5 c1 1cb 3 5 c1 1d0 4 5 c1 1d5 5 5 c1 1da 6 5 c1 1df 7 5 c1 1e4 8 5 c1 199 9 5 c1 19e a 5 c1 1a3 b 5 c1 1a8 c 5 c1 1ad d 5 c1 1b2 e 5 c1 1b7 f 5 c1 1bc 0 6 c1 1c1 1 6 c1 1c7 2 6 c1 1cd 3 6 c1 1d3 4 6 c1 1d9 5 6 c1 1df 6 6 c1 1e5 7 6 c1 1eb 8 6 c1 191 9 6 c1 197 a 6 c1 19d b 6 c1 1a3 c 6 c1 1a9 d 6 c1 1af e 6 c1 1b5 f 6 c1 1bb 0 7 c1 1c1 1 7 c1 1c8 2 7 c1 1cf 3 7 c1 1d6 4 7 c1 1dd 5 7 c1 1e4 6 7 c1 1eb 7 7 c1 1f2 8 7 c1 189 9 7 c1 190 a 7 c1 197 b 7 c1 19e c 7 c1 1a5 d 7 c1 1ac e 7 c1 1b3 f 7 c1 1ba 0 8 c1 1c1 1 8 c1 1b9 2 8 c1 1b1 3 8 c1 1a9 4 8 c1 1a1 5 8 c1 199 6 8 c1 191 7 8 c1 189 8 8 c1 001 9 8 c1 1f9 a 8 c1 1f1 b 8 c1 1e9 c 8 c1 1e1 d 8 c1 1d9 e 8 c1 1d1 f 8 c1 1c9 0 9 c1 1c1 1 9 c1 1ba 2 9 c1 1b3 3 9 c1 1ac 4 9 c1 1a5 5 9 c1 19e 6 9 c1 197 7 9 c1 190 8 9 c1 1f9 9 9 c1 1f2 a 9 c1 1eb b 9 c1 1e4 c 9 c1 1dd d 9 c1 1d6 e 9 c1 1cf f 9 c1 1c8 0 a c1 1c1 1 a c1 1bb 2 a c1 1b5 3 a c1 1af 4 a c1 1a9 5 a c1 1a3 6 a c1 19d 7 a c1 197 8 a c1 1f1 9 a c1 1eb a a c1 1e5 b a c1 1df c a c1 1d9 d a c1 1d3 e a c1 1cd f a c1 1c7 0 b c1 1c1 1 b c1 1bc 2 b c1 1b7 3 b c1 1b2 4 b c1 1ad 5 b c1 1a8 6 b c1 1a3 7 b c1 19e 8 b c1 1e9 9 b c1 1e4 a b c1 1df b b c1 1da c b c1 1d5 d b c1 1d0 e b c1 1cb f b c1 1c6 0 c c1 1c1 1 c c1 1bd 2 c c1 1b9 3 c c1 1b5 4 c c1 1b1 5 c c1 1ad 6 c c1 1a9 7 c c1 1a5 8 c c1 1e1 9 c c1 1dd a c c1 1d9 b c c1 1d5 c c c1 1d1 d c c1 1cd e c c1 1c9 f c c1 1c5 0 d c1 1c1 1 d c1 1be 2 d c1 1bb 3 d c1 1b8 4 d c1 1b5 5 d c1 1b2 6 d c1 1af 7 d c1 1ac 8 d c1 1d9 9 d c1 1d6 a d c1 1d3 b d c1 1d0 c d c1 1cd d d c1 1ca e d c1 1c7 f d c1 1c4 0 e c1 1c1 1 e c1 1bf 2 e c1 1bd 3 e c1 1bb 4 e c1 1b9 5 e c1 1b7 6 e c1 1b5 7 e c1 1b3 8 e c1 1d1 9 e c1 1cf a e c1 1cd b e c1 1cb c e c1 1c9 d e c1 1c7 e e c1 1c5 f e c1 1c3 0 f c1 1c1 1 f c1 1c0 2 f c1 1bf 3 f c1 1be 4 f c1 1bd 5 f c1 1bc 6 f c1 1bb 7 f c1 1ba 8 f c1 1c9 9 f c1 1c8 a f c1 1c7 b f c1 1c6 c f c1 1c5 d f c1 1c4 e f c1 1c3 f f c1 1c2 0 0 c2 1c2 1 0 c2 1c2 2 0 c2 1c2 3 0 c2 1c2 4 0 c2 1c2 5 0 c2 1c2 6 0 c2 1c2 7 0 c2 1c2 8 0 c2 1c2 9 0 c2 1c2 a 0 c2 1c2 b 0 c2 1c2 c 0 c2 1c2 d 0 c2 1c2 e 0 c2 1c2 f 0 c2 1c2 0 1 c2 1c2 1 1 c2 1c3 2 1 c2 1c4 3 1 c2 1c5 4 1 c2 1c6 5 1 c2 1c7 6 1 c2 1c8 7 1 c2 1c9 8 1 c2 1ba 9 1 c2 1bb a 1 c2 1bc b 1 c2 1bd c 1 c2 1be d 1 c2 1bf e 1 c2 1c0 f 1 c2 1c1 0 2 c2 1c2 1 2 c2 1c4 2 2 c2 1c6 3 2 c2 1c8 4 2 c2 1ca 5 2 c2 1cc 6 2 c2 1ce 7 2 c2 1d0 8 2 c2 1b2 9 2 c2 1b4 a 2 c2 1b6 b 2 c2 1b8 c 2 c2 1ba d 2 c2 1bc e 2 c2 1be f 2 c2 1c0 0 3 c2 1c2 1 3 c2 1c5 2 3 c2 1c8 3 3 c2 1cb 4 3 c2 1ce 5 3 c2 1d1 6 3 c2 1d4 7 3 c2 1d7 8 3 c2 1aa 9 3 c2 1ad a 3 c2 1b0 b 3 c2 1b3 c 3 c2 1b6 d 3 c2 1b9 e 3 c2 1bc f 3 c2 1bf 0 4 c2 1c2 1 4 c2 1c6 2 4 c2 1ca 3 4 c2 1ce 4 4 c2 1d2 5 4 c2 1d6 6 4 c2 1da 7 4 c2 1de 8 4 c2 1a2 9 4 c2 1a6 a 4 c2 1aa b 4 c2 1ae c 4 c2 1b2 d 4 c2 1b6 e 4 c2 1ba f 4 c2 1be 0 5 c2 1c2 1 5 c2 1c7 2 5 c2 1cc 3 5 c2 1d1 4 5 c2 1d6 5 5 c2 1db 6 5 c2 1e0 7 5 c2 1e5 8 5 c2 19a 9 5 c2 19f a 5 c2 1a4 b 5 c2 1a9 c 5 c2 1ae d 5 c2 1b3 e 5 c2 1b8 f 5 c2 1bd 0 6 c2 1c2 1 6 c2 1c8 2 6 c2 1ce 3 6 c2 1d4 4 6 c2 1da 5 6 c2 1e0 6 6 c2 1e6 7 6 c2 1ec 8 6 c2 192 9 6 c2 198 a 6 c2 19e b 6 c2 1a4 c 6 c2 1aa d 6 c2 1b0 e 6 c2 1b6 f 6 c2 1bc 0 7 c2 1c2 1 7 c2 1c9 2 7 c2 1d0 3 7 c2 1d7 4 7 c2 1de 5 7 c2 1e5 6 7 c2 1ec 7 7 c2 1f3 8 7 c2 18a 9 7 c2 191 a 7 c2 198 b 7 c2 19f c 7 c2 1a6 d 7 c2 1ad e 7 c2 1b4 f 7 c2 1bb 0 8 c2 1c2 1 8 c2 1ba 2 8 c2 1b2 3 8 c2 1aa 4 8 c2 1a2 5 8 c2 19a 6 8 c2 192 7 8 c2 18a 8 8 c2 002 9 8 c2 1fa a 8 c2 1f2 b 8 c2 1ea c 8 c2 1e2 d 8 c2 1da e 8 c2 1d2 f 8 c2 1ca 0 9 c2 1c2 1 9 c2 1bb 2 9 c2 1b4 3 9 c2 1ad 4 9 c2 1a6 5 9 c2 19f 6 9 c2 198 7 9 c2 191 8 9 c2 1fa 9 9 c2 1f3 a 9 c2 1ec b 9 c2 1e5 c 9 c2 1de d 9 c2 1d7 e 9 c2 1d0 f 9 c2 1c9 0 a c2 1c2 1 a c2 1bc 2 a c2 1b6 3 a c2 1b0 4 a c2 1aa 5 a c2 1a4 6 a c2 19e 7 a c2 198 8 a c2 1f2 9 a c2 1ec a a c2 1e6 b a c2 1e0 c a c2 1da d a c2 1d4 e a c2 1ce f a c2 1c8 0 b c2 1c2 1 b c2 1bd 2 b c2 1b8 3 b c2 1b3 4 b c2 1ae 5 b c2 1a9 6 b c2 1a4 7 b c2 19f 8 b c2 1ea 9 b c2 1e5 a b c2 1e0 b b c2 1db c b c2 1d6 d b c2 1d1 e b c2 1cc f b c2 1c7 0 c c2 1c2 1 c c2 1be 2 c c2 1ba 3 c c2 1b6 4 c c2 1b2 5 c c2 1ae 6 c c2 1aa 7 c c2 1a6 8 c c2 1e2 9 c c2 1de a c c2 1da b c c2 1d6 c c c2 1d2 d c c2 1ce e c c2 1ca f c c2 1c6 0 d c2 1c2 1 d c2 1bf 2 d c2 1bc 3 d c2 1b9 4 d c2 1b6 5 d c2 1b3 6 d c2 1b0 7 d c2 1ad 8 d c2 1da 9 d c2 1d7 a d c2 1d4 b d c2 1d1 c d c2 1ce d d c2 1cb e d c2 1c8 f d c2 1c5 0 e c2 1c2 1 e c2 1c0 2 e c2 1be 3 e c2 1bc 4 e c2 1ba 5 e c2 1b8 6 e c2 1b6 7 e c2 1b4 8 e c2 1d2 9 e c2 1d0 a e c2 1ce b e c2 1cc c e c2 1ca d e c2 1c8 e e c2 1c6 f e c2 1c4 0 f c2 1c2 1 f c2 1c1 2 f c2 1c0 3 f c2 1bf 4 f c2 1be 5 f c2 1bd 6 f c2 1bc 7 f c2 1bb 8 f c2 1ca 9 f c2 1c9 a f c2 1c8 b f c2 1c7 c f c2 1c6 d f c2 1c5 e f c2 1c4 f f c2 1c3 0 0 c3 1c3 1 0 c3 1c3 2 0 c3 1c3 3 0 c3 1c3 4 0 c3 1c3 5 0 c3 1c3 6 0 c3 1c3 7 0 c3 1c3 8 0 c3 1c3 9 0 c3 1c3 a 0 c3 1c3 b 0 c3 1c3 c 0 c3 1c3 d 0 c3 1c3 e 0 c3 1c3 f 0 c3 1c3 0 1 c3 1c3 1 1 c3 1c4 2 1 c3 1c5 3 1 c3 1c6 4 1 c3 1c7 5 1 c3 1c8 6 1 c3 1c9 7 1 c3 1ca 8 1 c3 1bb 9 1 c3 1bc a 1 c3 1bd b 1 c3 1be c 1 c3 1bf d 1 c3 1c0 e 1 c3 1c1 f 1 c3 1c2 0 2 c3 1c3 1 2 c3 1c5 2 2 c3 1c7 3 2 c3 1c9 4 2 c3 1cb 5 2 c3 1cd 6 2 c3 1cf 7 2 c3 1d1 8 2 c3 1b3 9 2 c3 1b5 a 2 c3 1b7 b 2 c3 1b9 c 2 c3 1bb d 2 c3 1bd e 2 c3 1bf f 2 c3 1c1 0 3 c3 1c3 1 3 c3 1c6 2 3 c3 1c9 3 3 c3 1cc 4 3 c3 1cf 5 3 c3 1d2 6 3 c3 1d5 7 3 c3 1d8 8 3 c3 1ab 9 3 c3 1ae a 3 c3 1b1 b 3 c3 1b4 c 3 c3 1b7 d 3 c3 1ba e 3 c3 1bd f 3 c3 1c0 0 4 c3 1c3 1 4 c3 1c7 2 4 c3 1cb 3 4 c3 1cf 4 4 c3 1d3 5 4 c3 1d7 6 4 c3 1db 7 4 c3 1df 8 4 c3 1a3 9 4 c3 1a7 a 4 c3 1ab b 4 c3 1af c 4 c3 1b3 d 4 c3 1b7 e 4 c3 1bb f 4 c3 1bf 0 5 c3 1c3 1 5 c3 1c8 2 5 c3 1cd 3 5 c3 1d2 4 5 c3 1d7 5 5 c3 1dc 6 5 c3 1e1 7 5 c3 1e6 8 5 c3 19b 9 5 c3 1a0 a 5 c3 1a5 b 5 c3 1aa c 5 c3 1af d 5 c3 1b4 e 5 c3 1b9 f 5 c3 1be 0 6 c3 1c3 1 6 c3 1c9 2 6 c3 1cf 3 6 c3 1d5 4 6 c3 1db 5 6 c3 1e1 6 6 c3 1e7 7 6 c3 1ed 8 6 c3 193 9 6 c3 199 a 6 c3 19f b 6 c3 1a5 c 6 c3 1ab d 6 c3 1b1 e 6 c3 1b7 f 6 c3 1bd 0 7 c3 1c3 1 7 c3 1ca 2 7 c3 1d1 3 7 c3 1d8 4 7 c3 1df 5 7 c3 1e6 6 7 c3 1ed 7 7 c3 1f4 8 7 c3 18b 9 7 c3 192 a 7 c3 199 b 7 c3 1a0 c 7 c3 1a7 d 7 c3 1ae e 7 c3 1b5 f 7 c3 1bc 0 8 c3 1c3 1 8 c3 1bb 2 8 c3 1b3 3 8 c3 1ab 4 8 c3 1a3 5 8 c3 19b 6 8 c3 193 7 8 c3 18b 8 8 c3 003 9 8 c3 1fb a 8 c3 1f3 b 8 c3 1eb c 8 c3 1e3 d 8 c3 1db e 8 c3 1d3 f 8 c3 1cb 0 9 c3 1c3 1 9 c3 1bc 2 9 c3 1b5 3 9 c3 1ae 4 9 c3 1a7 5 9 c3 1a0 6 9 c3 199 7 9 c3 192 8 9 c3 1fb 9 9 c3 1f4 a 9 c3 1ed b 9 c3 1e6 c 9 c3 1df d 9 c3 1d8 e 9 c3 1d1 f 9 c3 1ca 0 a c3 1c3 1 a c3 1bd 2 a c3 1b7 3 a c3 1b1 4 a c3 1ab 5 a c3 1a5 6 a c3 19f 7 a c3 199 8 a c3 1f3 9 a c3 1ed a a c3 1e7 b a c3 1e1 c a c3 1db d a c3 1d5 e a c3 1cf f a c3 1c9 0 b c3 1c3 1 b c3 1be 2 b c3 1b9 3 b c3 1b4 4 b c3 1af 5 b c3 1aa 6 b c3 1a5 7 b c3 1a0 8 b c3 1eb 9 b c3 1e6 a b c3 1e1 b b c3 1dc c b c3 1d7 d b c3 1d2 e b c3 1cd f b c3 1c8 0 c c3 1c3 1 c c3 1bf 2 c c3 1bb 3 c c3 1b7 4 c c3 1b3 5 c c3 1af 6 c c3 1ab 7 c c3 1a7 8 c c3 1e3 9 c c3 1df a c c3 1db b c c3 1d7 c c c3 1d3 d c c3 1cf e c c3 1cb f c c3 1c7 0 d c3 1c3 1 d c3 1c0 2 d c3 1bd 3 d c3 1ba 4 d c3 1b7 5 d c3 1b4 6 d c3 1b1 7 d c3 1ae 8 d c3 1db 9 d c3 1d8 a d c3 1d5 b d c3 1d2 c d c3 1cf d d c3 1cc e d c3 1c9 f d c3 1c6 0 e c3 1c3 1 e c3 1c1 2 e c3 1bf 3 e c3 1bd 4 e c3 1bb 5 e c3 1b9 6 e c3 1b7 7 e c3 1b5 8 e c3 1d3 9 e c3 1d1 a e c3 1cf b e c3 1cd c e c3 1cb d e c3 1c9 e e c3 1c7 f e c3 1c5 0 f c3 1c3 1 f c3 1c2 2 f c3 1c1 3 f c3 1c0 4 f c3 1bf 5 f c3 1be 6 f c3 1bd 7 f c3 1bc 8 f c3 1cb 9 f c3 1ca a f c3 1c9 b f c3 1c8 c f c3 1c7 d f c3 1c6 e f c3 1c5 f f c3 1c4 0 0 c4 1c4 1 0 c4 1c4 2 0 c4 1c4 3 0 c4 1c4 4 0 c4 1c4 5 0 c4 1c4 6 0 c4 1c4 7 0 c4 1c4 8 0 c4 1c4 9 0 c4 1c4 a 0 c4 1c4 b 0 c4 1c4 c 0 c4 1c4 d 0 c4 1c4 e 0 c4 1c4 f 0 c4 1c4 0 1 c4 1c4 1 1 c4 1c5 2 1 c4 1c6 3 1 c4 1c7 4 1 c4 1c8 5 1 c4 1c9 6 1 c4 1ca 7 1 c4 1cb 8 1 c4 1bc 9 1 c4 1bd a 1 c4 1be b 1 c4 1bf c 1 c4 1c0 d 1 c4 1c1 e 1 c4 1c2 f 1 c4 1c3 0 2 c4 1c4 1 2 c4 1c6 2 2 c4 1c8 3 2 c4 1ca 4 2 c4 1cc 5 2 c4 1ce 6 2 c4 1d0 7 2 c4 1d2 8 2 c4 1b4 9 2 c4 1b6 a 2 c4 1b8 b 2 c4 1ba c 2 c4 1bc d 2 c4 1be e 2 c4 1c0 f 2 c4 1c2 0 3 c4 1c4 1 3 c4 1c7 2 3 c4 1ca 3 3 c4 1cd 4 3 c4 1d0 5 3 c4 1d3 6 3 c4 1d6 7 3 c4 1d9 8 3 c4 1ac 9 3 c4 1af a 3 c4 1b2 b 3 c4 1b5 c 3 c4 1b8 d 3 c4 1bb e 3 c4 1be f 3 c4 1c1 0 4 c4 1c4 1 4 c4 1c8 2 4 c4 1cc 3 4 c4 1d0 4 4 c4 1d4 5 4 c4 1d8 6 4 c4 1dc 7 4 c4 1e0 8 4 c4 1a4 9 4 c4 1a8 a 4 c4 1ac b 4 c4 1b0 c 4 c4 1b4 d 4 c4 1b8 e 4 c4 1bc f 4 c4 1c0 0 5 c4 1c4 1 5 c4 1c9 2 5 c4 1ce 3 5 c4 1d3 4 5 c4 1d8 5 5 c4 1dd 6 5 c4 1e2 7 5 c4 1e7 8 5 c4 19c 9 5 c4 1a1 a 5 c4 1a6 b 5 c4 1ab c 5 c4 1b0 d 5 c4 1b5 e 5 c4 1ba f 5 c4 1bf 0 6 c4 1c4 1 6 c4 1ca 2 6 c4 1d0 3 6 c4 1d6 4 6 c4 1dc 5 6 c4 1e2 6 6 c4 1e8 7 6 c4 1ee 8 6 c4 194 9 6 c4 19a a 6 c4 1a0 b 6 c4 1a6 c 6 c4 1ac d 6 c4 1b2 e 6 c4 1b8 f 6 c4 1be 0 7 c4 1c4 1 7 c4 1cb 2 7 c4 1d2 3 7 c4 1d9 4 7 c4 1e0 5 7 c4 1e7 6 7 c4 1ee 7 7 c4 1f5 8 7 c4 18c 9 7 c4 193 a 7 c4 19a b 7 c4 1a1 c 7 c4 1a8 d 7 c4 1af e 7 c4 1b6 f 7 c4 1bd 0 8 c4 1c4 1 8 c4 1bc 2 8 c4 1b4 3 8 c4 1ac 4 8 c4 1a4 5 8 c4 19c 6 8 c4 194 7 8 c4 18c 8 8 c4 004 9 8 c4 1fc a 8 c4 1f4 b 8 c4 1ec c 8 c4 1e4 d 8 c4 1dc e 8 c4 1d4 f 8 c4 1cc 0 9 c4 1c4 1 9 c4 1bd 2 9 c4 1b6 3 9 c4 1af 4 9 c4 1a8 5 9 c4 1a1 6 9 c4 19a 7 9 c4 193 8 9 c4 1fc 9 9 c4 1f5 a 9 c4 1ee b 9 c4 1e7 c 9 c4 1e0 d 9 c4 1d9 e 9 c4 1d2 f 9 c4 1cb 0 a c4 1c4 1 a c4 1be 2 a c4 1b8 3 a c4 1b2 4 a c4 1ac 5 a c4 1a6 6 a c4 1a0 7 a c4 19a 8 a c4 1f4 9 a c4 1ee a a c4 1e8 b a c4 1e2 c a c4 1dc d a c4 1d6 e a c4 1d0 f a c4 1ca 0 b c4 1c4 1 b c4 1bf 2 b c4 1ba 3 b c4 1b5 4 b c4 1b0 5 b c4 1ab 6 b c4 1a6 7 b c4 1a1 8 b c4 1ec 9 b c4 1e7 a b c4 1e2 b b c4 1dd c b c4 1d8 d b c4 1d3 e b c4 1ce f b c4 1c9 0 c c4 1c4 1 c c4 1c0 2 c c4 1bc 3 c c4 1b8 4 c c4 1b4 5 c c4 1b0 6 c c4 1ac 7 c c4 1a8 8 c c4 1e4 9 c c4 1e0 a c c4 1dc b c c4 1d8 c c c4 1d4 d c c4 1d0 e c c4 1cc f c c4 1c8 0 d c4 1c4 1 d c4 1c1 2 d c4 1be 3 d c4 1bb 4 d c4 1b8 5 d c4 1b5 6 d c4 1b2 7 d c4 1af 8 d c4 1dc 9 d c4 1d9 a d c4 1d6 b d c4 1d3 c d c4 1d0 d d c4 1cd e d c4 1ca f d c4 1c7 0 e c4 1c4 1 e c4 1c2 2 e c4 1c0 3 e c4 1be 4 e c4 1bc 5 e c4 1ba 6 e c4 1b8 7 e c4 1b6 8 e c4 1d4 9 e c4 1d2 a e c4 1d0 b e c4 1ce c e c4 1cc d e c4 1ca e e c4 1c8 f e c4 1c6 0 f c4 1c4 1 f c4 1c3 2 f c4 1c2 3 f c4 1c1 4 f c4 1c0 5 f c4 1bf 6 f c4 1be 7 f c4 1bd 8 f c4 1cc 9 f c4 1cb a f c4 1ca b f c4 1c9 c f c4 1c8 d f c4 1c7 e f c4 1c6 f f c4 1c5 0 0 c5 1c5 1 0 c5 1c5 2 0 c5 1c5 3 0 c5 1c5 4 0 c5 1c5 5 0 c5 1c5 6 0 c5 1c5 7 0 c5 1c5 8 0 c5 1c5 9 0 c5 1c5 a 0 c5 1c5 b 0 c5 1c5 c 0 c5 1c5 d 0 c5 1c5 e 0 c5 1c5 f 0 c5 1c5 0 1 c5 1c5 1 1 c5 1c6 2 1 c5 1c7 3 1 c5 1c8 4 1 c5 1c9 5 1 c5 1ca 6 1 c5 1cb 7 1 c5 1cc 8 1 c5 1bd 9 1 c5 1be a 1 c5 1bf b 1 c5 1c0 c 1 c5 1c1 d 1 c5 1c2 e 1 c5 1c3 f 1 c5 1c4 0 2 c5 1c5 1 2 c5 1c7 2 2 c5 1c9 3 2 c5 1cb 4 2 c5 1cd 5 2 c5 1cf 6 2 c5 1d1 7 2 c5 1d3 8 2 c5 1b5 9 2 c5 1b7 a 2 c5 1b9 b 2 c5 1bb c 2 c5 1bd d 2 c5 1bf e 2 c5 1c1 f 2 c5 1c3 0 3 c5 1c5 1 3 c5 1c8 2 3 c5 1cb 3 3 c5 1ce 4 3 c5 1d1 5 3 c5 1d4 6 3 c5 1d7 7 3 c5 1da 8 3 c5 1ad 9 3 c5 1b0 a 3 c5 1b3 b 3 c5 1b6 c 3 c5 1b9 d 3 c5 1bc e 3 c5 1bf f 3 c5 1c2 0 4 c5 1c5 1 4 c5 1c9 2 4 c5 1cd 3 4 c5 1d1 4 4 c5 1d5 5 4 c5 1d9 6 4 c5 1dd 7 4 c5 1e1 8 4 c5 1a5 9 4 c5 1a9 a 4 c5 1ad b 4 c5 1b1 c 4 c5 1b5 d 4 c5 1b9 e 4 c5 1bd f 4 c5 1c1 0 5 c5 1c5 1 5 c5 1ca 2 5 c5 1cf 3 5 c5 1d4 4 5 c5 1d9 5 5 c5 1de 6 5 c5 1e3 7 5 c5 1e8 8 5 c5 19d 9 5 c5 1a2 a 5 c5 1a7 b 5 c5 1ac c 5 c5 1b1 d 5 c5 1b6 e 5 c5 1bb f 5 c5 1c0 0 6 c5 1c5 1 6 c5 1cb 2 6 c5 1d1 3 6 c5 1d7 4 6 c5 1dd 5 6 c5 1e3 6 6 c5 1e9 7 6 c5 1ef 8 6 c5 195 9 6 c5 19b a 6 c5 1a1 b 6 c5 1a7 c 6 c5 1ad d 6 c5 1b3 e 6 c5 1b9 f 6 c5 1bf 0 7 c5 1c5 1 7 c5 1cc 2 7 c5 1d3 3 7 c5 1da 4 7 c5 1e1 5 7 c5 1e8 6 7 c5 1ef 7 7 c5 1f6 8 7 c5 18d 9 7 c5 194 a 7 c5 19b b 7 c5 1a2 c 7 c5 1a9 d 7 c5 1b0 e 7 c5 1b7 f 7 c5 1be 0 8 c5 1c5 1 8 c5 1bd 2 8 c5 1b5 3 8 c5 1ad 4 8 c5 1a5 5 8 c5 19d 6 8 c5 195 7 8 c5 18d 8 8 c5 005 9 8 c5 1fd a 8 c5 1f5 b 8 c5 1ed c 8 c5 1e5 d 8 c5 1dd e 8 c5 1d5 f 8 c5 1cd 0 9 c5 1c5 1 9 c5 1be 2 9 c5 1b7 3 9 c5 1b0 4 9 c5 1a9 5 9 c5 1a2 6 9 c5 19b 7 9 c5 194 8 9 c5 1fd 9 9 c5 1f6 a 9 c5 1ef b 9 c5 1e8 c 9 c5 1e1 d 9 c5 1da e 9 c5 1d3 f 9 c5 1cc 0 a c5 1c5 1 a c5 1bf 2 a c5 1b9 3 a c5 1b3 4 a c5 1ad 5 a c5 1a7 6 a c5 1a1 7 a c5 19b 8 a c5 1f5 9 a c5 1ef a a c5 1e9 b a c5 1e3 c a c5 1dd d a c5 1d7 e a c5 1d1 f a c5 1cb 0 b c5 1c5 1 b c5 1c0 2 b c5 1bb 3 b c5 1b6 4 b c5 1b1 5 b c5 1ac 6 b c5 1a7 7 b c5 1a2 8 b c5 1ed 9 b c5 1e8 a b c5 1e3 b b c5 1de c b c5 1d9 d b c5 1d4 e b c5 1cf f b c5 1ca 0 c c5 1c5 1 c c5 1c1 2 c c5 1bd 3 c c5 1b9 4 c c5 1b5 5 c c5 1b1 6 c c5 1ad 7 c c5 1a9 8 c c5 1e5 9 c c5 1e1 a c c5 1dd b c c5 1d9 c c c5 1d5 d c c5 1d1 e c c5 1cd f c c5 1c9 0 d c5 1c5 1 d c5 1c2 2 d c5 1bf 3 d c5 1bc 4 d c5 1b9 5 d c5 1b6 6 d c5 1b3 7 d c5 1b0 8 d c5 1dd 9 d c5 1da a d c5 1d7 b d c5 1d4 c d c5 1d1 d d c5 1ce e d c5 1cb f d c5 1c8 0 e c5 1c5 1 e c5 1c3 2 e c5 1c1 3 e c5 1bf 4 e c5 1bd 5 e c5 1bb 6 e c5 1b9 7 e c5 1b7 8 e c5 1d5 9 e c5 1d3 a e c5 1d1 b e c5 1cf c e c5 1cd d e c5 1cb e e c5 1c9 f e c5 1c7 0 f c5 1c5 1 f c5 1c4 2 f c5 1c3 3 f c5 1c2 4 f c5 1c1 5 f c5 1c0 6 f c5 1bf 7 f c5 1be 8 f c5 1cd 9 f c5 1cc a f c5 1cb b f c5 1ca c f c5 1c9 d f c5 1c8 e f c5 1c7 f f c5 1c6 0 0 c6 1c6 1 0 c6 1c6 2 0 c6 1c6 3 0 c6 1c6 4 0 c6 1c6 5 0 c6 1c6 6 0 c6 1c6 7 0 c6 1c6 8 0 c6 1c6 9 0 c6 1c6 a 0 c6 1c6 b 0 c6 1c6 c 0 c6 1c6 d 0 c6 1c6 e 0 c6 1c6 f 0 c6 1c6 0 1 c6 1c6 1 1 c6 1c7 2 1 c6 1c8 3 1 c6 1c9 4 1 c6 1ca 5 1 c6 1cb 6 1 c6 1cc 7 1 c6 1cd 8 1 c6 1be 9 1 c6 1bf a 1 c6 1c0 b 1 c6 1c1 c 1 c6 1c2 d 1 c6 1c3 e 1 c6 1c4 f 1 c6 1c5 0 2 c6 1c6 1 2 c6 1c8 2 2 c6 1ca 3 2 c6 1cc 4 2 c6 1ce 5 2 c6 1d0 6 2 c6 1d2 7 2 c6 1d4 8 2 c6 1b6 9 2 c6 1b8 a 2 c6 1ba b 2 c6 1bc c 2 c6 1be d 2 c6 1c0 e 2 c6 1c2 f 2 c6 1c4 0 3 c6 1c6 1 3 c6 1c9 2 3 c6 1cc 3 3 c6 1cf 4 3 c6 1d2 5 3 c6 1d5 6 3 c6 1d8 7 3 c6 1db 8 3 c6 1ae 9 3 c6 1b1 a 3 c6 1b4 b 3 c6 1b7 c 3 c6 1ba d 3 c6 1bd e 3 c6 1c0 f 3 c6 1c3 0 4 c6 1c6 1 4 c6 1ca 2 4 c6 1ce 3 4 c6 1d2 4 4 c6 1d6 5 4 c6 1da 6 4 c6 1de 7 4 c6 1e2 8 4 c6 1a6 9 4 c6 1aa a 4 c6 1ae b 4 c6 1b2 c 4 c6 1b6 d 4 c6 1ba e 4 c6 1be f 4 c6 1c2 0 5 c6 1c6 1 5 c6 1cb 2 5 c6 1d0 3 5 c6 1d5 4 5 c6 1da 5 5 c6 1df 6 5 c6 1e4 7 5 c6 1e9 8 5 c6 19e 9 5 c6 1a3 a 5 c6 1a8 b 5 c6 1ad c 5 c6 1b2 d 5 c6 1b7 e 5 c6 1bc f 5 c6 1c1 0 6 c6 1c6 1 6 c6 1cc 2 6 c6 1d2 3 6 c6 1d8 4 6 c6 1de 5 6 c6 1e4 6 6 c6 1ea 7 6 c6 1f0 8 6 c6 196 9 6 c6 19c a 6 c6 1a2 b 6 c6 1a8 c 6 c6 1ae d 6 c6 1b4 e 6 c6 1ba f 6 c6 1c0 0 7 c6 1c6 1 7 c6 1cd 2 7 c6 1d4 3 7 c6 1db 4 7 c6 1e2 5 7 c6 1e9 6 7 c6 1f0 7 7 c6 1f7 8 7 c6 18e 9 7 c6 195 a 7 c6 19c b 7 c6 1a3 c 7 c6 1aa d 7 c6 1b1 e 7 c6 1b8 f 7 c6 1bf 0 8 c6 1c6 1 8 c6 1be 2 8 c6 1b6 3 8 c6 1ae 4 8 c6 1a6 5 8 c6 19e 6 8 c6 196 7 8 c6 18e 8 8 c6 006 9 8 c6 1fe a 8 c6 1f6 b 8 c6 1ee c 8 c6 1e6 d 8 c6 1de e 8 c6 1d6 f 8 c6 1ce 0 9 c6 1c6 1 9 c6 1bf 2 9 c6 1b8 3 9 c6 1b1 4 9 c6 1aa 5 9 c6 1a3 6 9 c6 19c 7 9 c6 195 8 9 c6 1fe 9 9 c6 1f7 a 9 c6 1f0 b 9 c6 1e9 c 9 c6 1e2 d 9 c6 1db e 9 c6 1d4 f 9 c6 1cd 0 a c6 1c6 1 a c6 1c0 2 a c6 1ba 3 a c6 1b4 4 a c6 1ae 5 a c6 1a8 6 a c6 1a2 7 a c6 19c 8 a c6 1f6 9 a c6 1f0 a a c6 1ea b a c6 1e4 c a c6 1de d a c6 1d8 e a c6 1d2 f a c6 1cc 0 b c6 1c6 1 b c6 1c1 2 b c6 1bc 3 b c6 1b7 4 b c6 1b2 5 b c6 1ad 6 b c6 1a8 7 b c6 1a3 8 b c6 1ee 9 b c6 1e9 a b c6 1e4 b b c6 1df c b c6 1da d b c6 1d5 e b c6 1d0 f b c6 1cb 0 c c6 1c6 1 c c6 1c2 2 c c6 1be 3 c c6 1ba 4 c c6 1b6 5 c c6 1b2 6 c c6 1ae 7 c c6 1aa 8 c c6 1e6 9 c c6 1e2 a c c6 1de b c c6 1da c c c6 1d6 d c c6 1d2 e c c6 1ce f c c6 1ca 0 d c6 1c6 1 d c6 1c3 2 d c6 1c0 3 d c6 1bd 4 d c6 1ba 5 d c6 1b7 6 d c6 1b4 7 d c6 1b1 8 d c6 1de 9 d c6 1db a d c6 1d8 b d c6 1d5 c d c6 1d2 d d c6 1cf e d c6 1cc f d c6 1c9 0 e c6 1c6 1 e c6 1c4 2 e c6 1c2 3 e c6 1c0 4 e c6 1be 5 e c6 1bc 6 e c6 1ba 7 e c6 1b8 8 e c6 1d6 9 e c6 1d4 a e c6 1d2 b e c6 1d0 c e c6 1ce d e c6 1cc e e c6 1ca f e c6 1c8 0 f c6 1c6 1 f c6 1c5 2 f c6 1c4 3 f c6 1c3 4 f c6 1c2 5 f c6 1c1 6 f c6 1c0 7 f c6 1bf 8 f c6 1ce 9 f c6 1cd a f c6 1cc b f c6 1cb c f c6 1ca d f c6 1c9 e f c6 1c8 f f c6 1c7 0 0 c7 1c7 1 0 c7 1c7 2 0 c7 1c7 3 0 c7 1c7 4 0 c7 1c7 5 0 c7 1c7 6 0 c7 1c7 7 0 c7 1c7 8 0 c7 1c7 9 0 c7 1c7 a 0 c7 1c7 b 0 c7 1c7 c 0 c7 1c7 d 0 c7 1c7 e 0 c7 1c7 f 0 c7 1c7 0 1 c7 1c7 1 1 c7 1c8 2 1 c7 1c9 3 1 c7 1ca 4 1 c7 1cb 5 1 c7 1cc 6 1 c7 1cd 7 1 c7 1ce 8 1 c7 1bf 9 1 c7 1c0 a 1 c7 1c1 b 1 c7 1c2 c 1 c7 1c3 d 1 c7 1c4 e 1 c7 1c5 f 1 c7 1c6 0 2 c7 1c7 1 2 c7 1c9 2 2 c7 1cb 3 2 c7 1cd 4 2 c7 1cf 5 2 c7 1d1 6 2 c7 1d3 7 2 c7 1d5 8 2 c7 1b7 9 2 c7 1b9 a 2 c7 1bb b 2 c7 1bd c 2 c7 1bf d 2 c7 1c1 e 2 c7 1c3 f 2 c7 1c5 0 3 c7 1c7 1 3 c7 1ca 2 3 c7 1cd 3 3 c7 1d0 4 3 c7 1d3 5 3 c7 1d6 6 3 c7 1d9 7 3 c7 1dc 8 3 c7 1af 9 3 c7 1b2 a 3 c7 1b5 b 3 c7 1b8 c 3 c7 1bb d 3 c7 1be e 3 c7 1c1 f 3 c7 1c4 0 4 c7 1c7 1 4 c7 1cb 2 4 c7 1cf 3 4 c7 1d3 4 4 c7 1d7 5 4 c7 1db 6 4 c7 1df 7 4 c7 1e3 8 4 c7 1a7 9 4 c7 1ab a 4 c7 1af b 4 c7 1b3 c 4 c7 1b7 d 4 c7 1bb e 4 c7 1bf f 4 c7 1c3 0 5 c7 1c7 1 5 c7 1cc 2 5 c7 1d1 3 5 c7 1d6 4 5 c7 1db 5 5 c7 1e0 6 5 c7 1e5 7 5 c7 1ea 8 5 c7 19f 9 5 c7 1a4 a 5 c7 1a9 b 5 c7 1ae c 5 c7 1b3 d 5 c7 1b8 e 5 c7 1bd f 5 c7 1c2 0 6 c7 1c7 1 6 c7 1cd 2 6 c7 1d3 3 6 c7 1d9 4 6 c7 1df 5 6 c7 1e5 6 6 c7 1eb 7 6 c7 1f1 8 6 c7 197 9 6 c7 19d a 6 c7 1a3 b 6 c7 1a9 c 6 c7 1af d 6 c7 1b5 e 6 c7 1bb f 6 c7 1c1 0 7 c7 1c7 1 7 c7 1ce 2 7 c7 1d5 3 7 c7 1dc 4 7 c7 1e3 5 7 c7 1ea 6 7 c7 1f1 7 7 c7 1f8 8 7 c7 18f 9 7 c7 196 a 7 c7 19d b 7 c7 1a4 c 7 c7 1ab d 7 c7 1b2 e 7 c7 1b9 f 7 c7 1c0 0 8 c7 1c7 1 8 c7 1bf 2 8 c7 1b7 3 8 c7 1af 4 8 c7 1a7 5 8 c7 19f 6 8 c7 197 7 8 c7 18f 8 8 c7 007 9 8 c7 1ff a 8 c7 1f7 b 8 c7 1ef c 8 c7 1e7 d 8 c7 1df e 8 c7 1d7 f 8 c7 1cf 0 9 c7 1c7 1 9 c7 1c0 2 9 c7 1b9 3 9 c7 1b2 4 9 c7 1ab 5 9 c7 1a4 6 9 c7 19d 7 9 c7 196 8 9 c7 1ff 9 9 c7 1f8 a 9 c7 1f1 b 9 c7 1ea c 9 c7 1e3 d 9 c7 1dc e 9 c7 1d5 f 9 c7 1ce 0 a c7 1c7 1 a c7 1c1 2 a c7 1bb 3 a c7 1b5 4 a c7 1af 5 a c7 1a9 6 a c7 1a3 7 a c7 19d 8 a c7 1f7 9 a c7 1f1 a a c7 1eb b a c7 1e5 c a c7 1df d a c7 1d9 e a c7 1d3 f a c7 1cd 0 b c7 1c7 1 b c7 1c2 2 b c7 1bd 3 b c7 1b8 4 b c7 1b3 5 b c7 1ae 6 b c7 1a9 7 b c7 1a4 8 b c7 1ef 9 b c7 1ea a b c7 1e5 b b c7 1e0 c b c7 1db d b c7 1d6 e b c7 1d1 f b c7 1cc 0 c c7 1c7 1 c c7 1c3 2 c c7 1bf 3 c c7 1bb 4 c c7 1b7 5 c c7 1b3 6 c c7 1af 7 c c7 1ab 8 c c7 1e7 9 c c7 1e3 a c c7 1df b c c7 1db c c c7 1d7 d c c7 1d3 e c c7 1cf f c c7 1cb 0 d c7 1c7 1 d c7 1c4 2 d c7 1c1 3 d c7 1be 4 d c7 1bb 5 d c7 1b8 6 d c7 1b5 7 d c7 1b2 8 d c7 1df 9 d c7 1dc a d c7 1d9 b d c7 1d6 c d c7 1d3 d d c7 1d0 e d c7 1cd f d c7 1ca 0 e c7 1c7 1 e c7 1c5 2 e c7 1c3 3 e c7 1c1 4 e c7 1bf 5 e c7 1bd 6 e c7 1bb 7 e c7 1b9 8 e c7 1d7 9 e c7 1d5 a e c7 1d3 b e c7 1d1 c e c7 1cf d e c7 1cd e e c7 1cb f e c7 1c9 0 f c7 1c7 1 f c7 1c6 2 f c7 1c5 3 f c7 1c4 4 f c7 1c3 5 f c7 1c2 6 f c7 1c1 7 f c7 1c0 8 f c7 1cf 9 f c7 1ce a f c7 1cd b f c7 1cc c f c7 1cb d f c7 1ca e f c7 1c9 f f c7 1c8 0 0 c8 1c8 1 0 c8 1c8 2 0 c8 1c8 3 0 c8 1c8 4 0 c8 1c8 5 0 c8 1c8 6 0 c8 1c8 7 0 c8 1c8 8 0 c8 1c8 9 0 c8 1c8 a 0 c8 1c8 b 0 c8 1c8 c 0 c8 1c8 d 0 c8 1c8 e 0 c8 1c8 f 0 c8 1c8 0 1 c8 1c8 1 1 c8 1c9 2 1 c8 1ca 3 1 c8 1cb 4 1 c8 1cc 5 1 c8 1cd 6 1 c8 1ce 7 1 c8 1cf 8 1 c8 1c0 9 1 c8 1c1 a 1 c8 1c2 b 1 c8 1c3 c 1 c8 1c4 d 1 c8 1c5 e 1 c8 1c6 f 1 c8 1c7 0 2 c8 1c8 1 2 c8 1ca 2 2 c8 1cc 3 2 c8 1ce 4 2 c8 1d0 5 2 c8 1d2 6 2 c8 1d4 7 2 c8 1d6 8 2 c8 1b8 9 2 c8 1ba a 2 c8 1bc b 2 c8 1be c 2 c8 1c0 d 2 c8 1c2 e 2 c8 1c4 f 2 c8 1c6 0 3 c8 1c8 1 3 c8 1cb 2 3 c8 1ce 3 3 c8 1d1 4 3 c8 1d4 5 3 c8 1d7 6 3 c8 1da 7 3 c8 1dd 8 3 c8 1b0 9 3 c8 1b3 a 3 c8 1b6 b 3 c8 1b9 c 3 c8 1bc d 3 c8 1bf e 3 c8 1c2 f 3 c8 1c5 0 4 c8 1c8 1 4 c8 1cc 2 4 c8 1d0 3 4 c8 1d4 4 4 c8 1d8 5 4 c8 1dc 6 4 c8 1e0 7 4 c8 1e4 8 4 c8 1a8 9 4 c8 1ac a 4 c8 1b0 b 4 c8 1b4 c 4 c8 1b8 d 4 c8 1bc e 4 c8 1c0 f 4 c8 1c4 0 5 c8 1c8 1 5 c8 1cd 2 5 c8 1d2 3 5 c8 1d7 4 5 c8 1dc 5 5 c8 1e1 6 5 c8 1e6 7 5 c8 1eb 8 5 c8 1a0 9 5 c8 1a5 a 5 c8 1aa b 5 c8 1af c 5 c8 1b4 d 5 c8 1b9 e 5 c8 1be f 5 c8 1c3 0 6 c8 1c8 1 6 c8 1ce 2 6 c8 1d4 3 6 c8 1da 4 6 c8 1e0 5 6 c8 1e6 6 6 c8 1ec 7 6 c8 1f2 8 6 c8 198 9 6 c8 19e a 6 c8 1a4 b 6 c8 1aa c 6 c8 1b0 d 6 c8 1b6 e 6 c8 1bc f 6 c8 1c2 0 7 c8 1c8 1 7 c8 1cf 2 7 c8 1d6 3 7 c8 1dd 4 7 c8 1e4 5 7 c8 1eb 6 7 c8 1f2 7 7 c8 1f9 8 7 c8 190 9 7 c8 197 a 7 c8 19e b 7 c8 1a5 c 7 c8 1ac d 7 c8 1b3 e 7 c8 1ba f 7 c8 1c1 0 8 c8 1c8 1 8 c8 1c0 2 8 c8 1b8 3 8 c8 1b0 4 8 c8 1a8 5 8 c8 1a0 6 8 c8 198 7 8 c8 190 8 8 c8 008 9 8 c8 000 a 8 c8 1f8 b 8 c8 1f0 c 8 c8 1e8 d 8 c8 1e0 e 8 c8 1d8 f 8 c8 1d0 0 9 c8 1c8 1 9 c8 1c1 2 9 c8 1ba 3 9 c8 1b3 4 9 c8 1ac 5 9 c8 1a5 6 9 c8 19e 7 9 c8 197 8 9 c8 000 9 9 c8 1f9 a 9 c8 1f2 b 9 c8 1eb c 9 c8 1e4 d 9 c8 1dd e 9 c8 1d6 f 9 c8 1cf 0 a c8 1c8 1 a c8 1c2 2 a c8 1bc 3 a c8 1b6 4 a c8 1b0 5 a c8 1aa 6 a c8 1a4 7 a c8 19e 8 a c8 1f8 9 a c8 1f2 a a c8 1ec b a c8 1e6 c a c8 1e0 d a c8 1da e a c8 1d4 f a c8 1ce 0 b c8 1c8 1 b c8 1c3 2 b c8 1be 3 b c8 1b9 4 b c8 1b4 5 b c8 1af 6 b c8 1aa 7 b c8 1a5 8 b c8 1f0 9 b c8 1eb a b c8 1e6 b b c8 1e1 c b c8 1dc d b c8 1d7 e b c8 1d2 f b c8 1cd 0 c c8 1c8 1 c c8 1c4 2 c c8 1c0 3 c c8 1bc 4 c c8 1b8 5 c c8 1b4 6 c c8 1b0 7 c c8 1ac 8 c c8 1e8 9 c c8 1e4 a c c8 1e0 b c c8 1dc c c c8 1d8 d c c8 1d4 e c c8 1d0 f c c8 1cc 0 d c8 1c8 1 d c8 1c5 2 d c8 1c2 3 d c8 1bf 4 d c8 1bc 5 d c8 1b9 6 d c8 1b6 7 d c8 1b3 8 d c8 1e0 9 d c8 1dd a d c8 1da b d c8 1d7 c d c8 1d4 d d c8 1d1 e d c8 1ce f d c8 1cb 0 e c8 1c8 1 e c8 1c6 2 e c8 1c4 3 e c8 1c2 4 e c8 1c0 5 e c8 1be 6 e c8 1bc 7 e c8 1ba 8 e c8 1d8 9 e c8 1d6 a e c8 1d4 b e c8 1d2 c e c8 1d0 d e c8 1ce e e c8 1cc f e c8 1ca 0 f c8 1c8 1 f c8 1c7 2 f c8 1c6 3 f c8 1c5 4 f c8 1c4 5 f c8 1c3 6 f c8 1c2 7 f c8 1c1 8 f c8 1d0 9 f c8 1cf a f c8 1ce b f c8 1cd c f c8 1cc d f c8 1cb e f c8 1ca f f c8 1c9 0 0 c9 1c9 1 0 c9 1c9 2 0 c9 1c9 3 0 c9 1c9 4 0 c9 1c9 5 0 c9 1c9 6 0 c9 1c9 7 0 c9 1c9 8 0 c9 1c9 9 0 c9 1c9 a 0 c9 1c9 b 0 c9 1c9 c 0 c9 1c9 d 0 c9 1c9 e 0 c9 1c9 f 0 c9 1c9 0 1 c9 1c9 1 1 c9 1ca 2 1 c9 1cb 3 1 c9 1cc 4 1 c9 1cd 5 1 c9 1ce 6 1 c9 1cf 7 1 c9 1d0 8 1 c9 1c1 9 1 c9 1c2 a 1 c9 1c3 b 1 c9 1c4 c 1 c9 1c5 d 1 c9 1c6 e 1 c9 1c7 f 1 c9 1c8 0 2 c9 1c9 1 2 c9 1cb 2 2 c9 1cd 3 2 c9 1cf 4 2 c9 1d1 5 2 c9 1d3 6 2 c9 1d5 7 2 c9 1d7 8 2 c9 1b9 9 2 c9 1bb a 2 c9 1bd b 2 c9 1bf c 2 c9 1c1 d 2 c9 1c3 e 2 c9 1c5 f 2 c9 1c7 0 3 c9 1c9 1 3 c9 1cc 2 3 c9 1cf 3 3 c9 1d2 4 3 c9 1d5 5 3 c9 1d8 6 3 c9 1db 7 3 c9 1de 8 3 c9 1b1 9 3 c9 1b4 a 3 c9 1b7 b 3 c9 1ba c 3 c9 1bd d 3 c9 1c0 e 3 c9 1c3 f 3 c9 1c6 0 4 c9 1c9 1 4 c9 1cd 2 4 c9 1d1 3 4 c9 1d5 4 4 c9 1d9 5 4 c9 1dd 6 4 c9 1e1 7 4 c9 1e5 8 4 c9 1a9 9 4 c9 1ad a 4 c9 1b1 b 4 c9 1b5 c 4 c9 1b9 d 4 c9 1bd e 4 c9 1c1 f 4 c9 1c5 0 5 c9 1c9 1 5 c9 1ce 2 5 c9 1d3 3 5 c9 1d8 4 5 c9 1dd 5 5 c9 1e2 6 5 c9 1e7 7 5 c9 1ec 8 5 c9 1a1 9 5 c9 1a6 a 5 c9 1ab b 5 c9 1b0 c 5 c9 1b5 d 5 c9 1ba e 5 c9 1bf f 5 c9 1c4 0 6 c9 1c9 1 6 c9 1cf 2 6 c9 1d5 3 6 c9 1db 4 6 c9 1e1 5 6 c9 1e7 6 6 c9 1ed 7 6 c9 1f3 8 6 c9 199 9 6 c9 19f a 6 c9 1a5 b 6 c9 1ab c 6 c9 1b1 d 6 c9 1b7 e 6 c9 1bd f 6 c9 1c3 0 7 c9 1c9 1 7 c9 1d0 2 7 c9 1d7 3 7 c9 1de 4 7 c9 1e5 5 7 c9 1ec 6 7 c9 1f3 7 7 c9 1fa 8 7 c9 191 9 7 c9 198 a 7 c9 19f b 7 c9 1a6 c 7 c9 1ad d 7 c9 1b4 e 7 c9 1bb f 7 c9 1c2 0 8 c9 1c9 1 8 c9 1c1 2 8 c9 1b9 3 8 c9 1b1 4 8 c9 1a9 5 8 c9 1a1 6 8 c9 199 7 8 c9 191 8 8 c9 009 9 8 c9 001 a 8 c9 1f9 b 8 c9 1f1 c 8 c9 1e9 d 8 c9 1e1 e 8 c9 1d9 f 8 c9 1d1 0 9 c9 1c9 1 9 c9 1c2 2 9 c9 1bb 3 9 c9 1b4 4 9 c9 1ad 5 9 c9 1a6 6 9 c9 19f 7 9 c9 198 8 9 c9 001 9 9 c9 1fa a 9 c9 1f3 b 9 c9 1ec c 9 c9 1e5 d 9 c9 1de e 9 c9 1d7 f 9 c9 1d0 0 a c9 1c9 1 a c9 1c3 2 a c9 1bd 3 a c9 1b7 4 a c9 1b1 5 a c9 1ab 6 a c9 1a5 7 a c9 19f 8 a c9 1f9 9 a c9 1f3 a a c9 1ed b a c9 1e7 c a c9 1e1 d a c9 1db e a c9 1d5 f a c9 1cf 0 b c9 1c9 1 b c9 1c4 2 b c9 1bf 3 b c9 1ba 4 b c9 1b5 5 b c9 1b0 6 b c9 1ab 7 b c9 1a6 8 b c9 1f1 9 b c9 1ec a b c9 1e7 b b c9 1e2 c b c9 1dd d b c9 1d8 e b c9 1d3 f b c9 1ce 0 c c9 1c9 1 c c9 1c5 2 c c9 1c1 3 c c9 1bd 4 c c9 1b9 5 c c9 1b5 6 c c9 1b1 7 c c9 1ad 8 c c9 1e9 9 c c9 1e5 a c c9 1e1 b c c9 1dd c c c9 1d9 d c c9 1d5 e c c9 1d1 f c c9 1cd 0 d c9 1c9 1 d c9 1c6 2 d c9 1c3 3 d c9 1c0 4 d c9 1bd 5 d c9 1ba 6 d c9 1b7 7 d c9 1b4 8 d c9 1e1 9 d c9 1de a d c9 1db b d c9 1d8 c d c9 1d5 d d c9 1d2 e d c9 1cf f d c9 1cc 0 e c9 1c9 1 e c9 1c7 2 e c9 1c5 3 e c9 1c3 4 e c9 1c1 5 e c9 1bf 6 e c9 1bd 7 e c9 1bb 8 e c9 1d9 9 e c9 1d7 a e c9 1d5 b e c9 1d3 c e c9 1d1 d e c9 1cf e e c9 1cd f e c9 1cb 0 f c9 1c9 1 f c9 1c8 2 f c9 1c7 3 f c9 1c6 4 f c9 1c5 5 f c9 1c4 6 f c9 1c3 7 f c9 1c2 8 f c9 1d1 9 f c9 1d0 a f c9 1cf b f c9 1ce c f c9 1cd d f c9 1cc e f c9 1cb f f c9 1ca 0 0 ca 1ca 1 0 ca 1ca 2 0 ca 1ca 3 0 ca 1ca 4 0 ca 1ca 5 0 ca 1ca 6 0 ca 1ca 7 0 ca 1ca 8 0 ca 1ca 9 0 ca 1ca a 0 ca 1ca b 0 ca 1ca c 0 ca 1ca d 0 ca 1ca e 0 ca 1ca f 0 ca 1ca 0 1 ca 1ca 1 1 ca 1cb 2 1 ca 1cc 3 1 ca 1cd 4 1 ca 1ce 5 1 ca 1cf 6 1 ca 1d0 7 1 ca 1d1 8 1 ca 1c2 9 1 ca 1c3 a 1 ca 1c4 b 1 ca 1c5 c 1 ca 1c6 d 1 ca 1c7 e 1 ca 1c8 f 1 ca 1c9 0 2 ca 1ca 1 2 ca 1cc 2 2 ca 1ce 3 2 ca 1d0 4 2 ca 1d2 5 2 ca 1d4 6 2 ca 1d6 7 2 ca 1d8 8 2 ca 1ba 9 2 ca 1bc a 2 ca 1be b 2 ca 1c0 c 2 ca 1c2 d 2 ca 1c4 e 2 ca 1c6 f 2 ca 1c8 0 3 ca 1ca 1 3 ca 1cd 2 3 ca 1d0 3 3 ca 1d3 4 3 ca 1d6 5 3 ca 1d9 6 3 ca 1dc 7 3 ca 1df 8 3 ca 1b2 9 3 ca 1b5 a 3 ca 1b8 b 3 ca 1bb c 3 ca 1be d 3 ca 1c1 e 3 ca 1c4 f 3 ca 1c7 0 4 ca 1ca 1 4 ca 1ce 2 4 ca 1d2 3 4 ca 1d6 4 4 ca 1da 5 4 ca 1de 6 4 ca 1e2 7 4 ca 1e6 8 4 ca 1aa 9 4 ca 1ae a 4 ca 1b2 b 4 ca 1b6 c 4 ca 1ba d 4 ca 1be e 4 ca 1c2 f 4 ca 1c6 0 5 ca 1ca 1 5 ca 1cf 2 5 ca 1d4 3 5 ca 1d9 4 5 ca 1de 5 5 ca 1e3 6 5 ca 1e8 7 5 ca 1ed 8 5 ca 1a2 9 5 ca 1a7 a 5 ca 1ac b 5 ca 1b1 c 5 ca 1b6 d 5 ca 1bb e 5 ca 1c0 f 5 ca 1c5 0 6 ca 1ca 1 6 ca 1d0 2 6 ca 1d6 3 6 ca 1dc 4 6 ca 1e2 5 6 ca 1e8 6 6 ca 1ee 7 6 ca 1f4 8 6 ca 19a 9 6 ca 1a0 a 6 ca 1a6 b 6 ca 1ac c 6 ca 1b2 d 6 ca 1b8 e 6 ca 1be f 6 ca 1c4 0 7 ca 1ca 1 7 ca 1d1 2 7 ca 1d8 3 7 ca 1df 4 7 ca 1e6 5 7 ca 1ed 6 7 ca 1f4 7 7 ca 1fb 8 7 ca 192 9 7 ca 199 a 7 ca 1a0 b 7 ca 1a7 c 7 ca 1ae d 7 ca 1b5 e 7 ca 1bc f 7 ca 1c3 0 8 ca 1ca 1 8 ca 1c2 2 8 ca 1ba 3 8 ca 1b2 4 8 ca 1aa 5 8 ca 1a2 6 8 ca 19a 7 8 ca 192 8 8 ca 00a 9 8 ca 002 a 8 ca 1fa b 8 ca 1f2 c 8 ca 1ea d 8 ca 1e2 e 8 ca 1da f 8 ca 1d2 0 9 ca 1ca 1 9 ca 1c3 2 9 ca 1bc 3 9 ca 1b5 4 9 ca 1ae 5 9 ca 1a7 6 9 ca 1a0 7 9 ca 199 8 9 ca 002 9 9 ca 1fb a 9 ca 1f4 b 9 ca 1ed c 9 ca 1e6 d 9 ca 1df e 9 ca 1d8 f 9 ca 1d1 0 a ca 1ca 1 a ca 1c4 2 a ca 1be 3 a ca 1b8 4 a ca 1b2 5 a ca 1ac 6 a ca 1a6 7 a ca 1a0 8 a ca 1fa 9 a ca 1f4 a a ca 1ee b a ca 1e8 c a ca 1e2 d a ca 1dc e a ca 1d6 f a ca 1d0 0 b ca 1ca 1 b ca 1c5 2 b ca 1c0 3 b ca 1bb 4 b ca 1b6 5 b ca 1b1 6 b ca 1ac 7 b ca 1a7 8 b ca 1f2 9 b ca 1ed a b ca 1e8 b b ca 1e3 c b ca 1de d b ca 1d9 e b ca 1d4 f b ca 1cf 0 c ca 1ca 1 c ca 1c6 2 c ca 1c2 3 c ca 1be 4 c ca 1ba 5 c ca 1b6 6 c ca 1b2 7 c ca 1ae 8 c ca 1ea 9 c ca 1e6 a c ca 1e2 b c ca 1de c c ca 1da d c ca 1d6 e c ca 1d2 f c ca 1ce 0 d ca 1ca 1 d ca 1c7 2 d ca 1c4 3 d ca 1c1 4 d ca 1be 5 d ca 1bb 6 d ca 1b8 7 d ca 1b5 8 d ca 1e2 9 d ca 1df a d ca 1dc b d ca 1d9 c d ca 1d6 d d ca 1d3 e d ca 1d0 f d ca 1cd 0 e ca 1ca 1 e ca 1c8 2 e ca 1c6 3 e ca 1c4 4 e ca 1c2 5 e ca 1c0 6 e ca 1be 7 e ca 1bc 8 e ca 1da 9 e ca 1d8 a e ca 1d6 b e ca 1d4 c e ca 1d2 d e ca 1d0 e e ca 1ce f e ca 1cc 0 f ca 1ca 1 f ca 1c9 2 f ca 1c8 3 f ca 1c7 4 f ca 1c6 5 f ca 1c5 6 f ca 1c4 7 f ca 1c3 8 f ca 1d2 9 f ca 1d1 a f ca 1d0 b f ca 1cf c f ca 1ce d f ca 1cd e f ca 1cc f f ca 1cb 0 0 cb 1cb 1 0 cb 1cb 2 0 cb 1cb 3 0 cb 1cb 4 0 cb 1cb 5 0 cb 1cb 6 0 cb 1cb 7 0 cb 1cb 8 0 cb 1cb 9 0 cb 1cb a 0 cb 1cb b 0 cb 1cb c 0 cb 1cb d 0 cb 1cb e 0 cb 1cb f 0 cb 1cb 0 1 cb 1cb 1 1 cb 1cc 2 1 cb 1cd 3 1 cb 1ce 4 1 cb 1cf 5 1 cb 1d0 6 1 cb 1d1 7 1 cb 1d2 8 1 cb 1c3 9 1 cb 1c4 a 1 cb 1c5 b 1 cb 1c6 c 1 cb 1c7 d 1 cb 1c8 e 1 cb 1c9 f 1 cb 1ca 0 2 cb 1cb 1 2 cb 1cd 2 2 cb 1cf 3 2 cb 1d1 4 2 cb 1d3 5 2 cb 1d5 6 2 cb 1d7 7 2 cb 1d9 8 2 cb 1bb 9 2 cb 1bd a 2 cb 1bf b 2 cb 1c1 c 2 cb 1c3 d 2 cb 1c5 e 2 cb 1c7 f 2 cb 1c9 0 3 cb 1cb 1 3 cb 1ce 2 3 cb 1d1 3 3 cb 1d4 4 3 cb 1d7 5 3 cb 1da 6 3 cb 1dd 7 3 cb 1e0 8 3 cb 1b3 9 3 cb 1b6 a 3 cb 1b9 b 3 cb 1bc c 3 cb 1bf d 3 cb 1c2 e 3 cb 1c5 f 3 cb 1c8 0 4 cb 1cb 1 4 cb 1cf 2 4 cb 1d3 3 4 cb 1d7 4 4 cb 1db 5 4 cb 1df 6 4 cb 1e3 7 4 cb 1e7 8 4 cb 1ab 9 4 cb 1af a 4 cb 1b3 b 4 cb 1b7 c 4 cb 1bb d 4 cb 1bf e 4 cb 1c3 f 4 cb 1c7 0 5 cb 1cb 1 5 cb 1d0 2 5 cb 1d5 3 5 cb 1da 4 5 cb 1df 5 5 cb 1e4 6 5 cb 1e9 7 5 cb 1ee 8 5 cb 1a3 9 5 cb 1a8 a 5 cb 1ad b 5 cb 1b2 c 5 cb 1b7 d 5 cb 1bc e 5 cb 1c1 f 5 cb 1c6 0 6 cb 1cb 1 6 cb 1d1 2 6 cb 1d7 3 6 cb 1dd 4 6 cb 1e3 5 6 cb 1e9 6 6 cb 1ef 7 6 cb 1f5 8 6 cb 19b 9 6 cb 1a1 a 6 cb 1a7 b 6 cb 1ad c 6 cb 1b3 d 6 cb 1b9 e 6 cb 1bf f 6 cb 1c5 0 7 cb 1cb 1 7 cb 1d2 2 7 cb 1d9 3 7 cb 1e0 4 7 cb 1e7 5 7 cb 1ee 6 7 cb 1f5 7 7 cb 1fc 8 7 cb 193 9 7 cb 19a a 7 cb 1a1 b 7 cb 1a8 c 7 cb 1af d 7 cb 1b6 e 7 cb 1bd f 7 cb 1c4 0 8 cb 1cb 1 8 cb 1c3 2 8 cb 1bb 3 8 cb 1b3 4 8 cb 1ab 5 8 cb 1a3 6 8 cb 19b 7 8 cb 193 8 8 cb 00b 9 8 cb 003 a 8 cb 1fb b 8 cb 1f3 c 8 cb 1eb d 8 cb 1e3 e 8 cb 1db f 8 cb 1d3 0 9 cb 1cb 1 9 cb 1c4 2 9 cb 1bd 3 9 cb 1b6 4 9 cb 1af 5 9 cb 1a8 6 9 cb 1a1 7 9 cb 19a 8 9 cb 003 9 9 cb 1fc a 9 cb 1f5 b 9 cb 1ee c 9 cb 1e7 d 9 cb 1e0 e 9 cb 1d9 f 9 cb 1d2 0 a cb 1cb 1 a cb 1c5 2 a cb 1bf 3 a cb 1b9 4 a cb 1b3 5 a cb 1ad 6 a cb 1a7 7 a cb 1a1 8 a cb 1fb 9 a cb 1f5 a a cb 1ef b a cb 1e9 c a cb 1e3 d a cb 1dd e a cb 1d7 f a cb 1d1 0 b cb 1cb 1 b cb 1c6 2 b cb 1c1 3 b cb 1bc 4 b cb 1b7 5 b cb 1b2 6 b cb 1ad 7 b cb 1a8 8 b cb 1f3 9 b cb 1ee a b cb 1e9 b b cb 1e4 c b cb 1df d b cb 1da e b cb 1d5 f b cb 1d0 0 c cb 1cb 1 c cb 1c7 2 c cb 1c3 3 c cb 1bf 4 c cb 1bb 5 c cb 1b7 6 c cb 1b3 7 c cb 1af 8 c cb 1eb 9 c cb 1e7 a c cb 1e3 b c cb 1df c c cb 1db d c cb 1d7 e c cb 1d3 f c cb 1cf 0 d cb 1cb 1 d cb 1c8 2 d cb 1c5 3 d cb 1c2 4 d cb 1bf 5 d cb 1bc 6 d cb 1b9 7 d cb 1b6 8 d cb 1e3 9 d cb 1e0 a d cb 1dd b d cb 1da c d cb 1d7 d d cb 1d4 e d cb 1d1 f d cb 1ce 0 e cb 1cb 1 e cb 1c9 2 e cb 1c7 3 e cb 1c5 4 e cb 1c3 5 e cb 1c1 6 e cb 1bf 7 e cb 1bd 8 e cb 1db 9 e cb 1d9 a e cb 1d7 b e cb 1d5 c e cb 1d3 d e cb 1d1 e e cb 1cf f e cb 1cd 0 f cb 1cb 1 f cb 1ca 2 f cb 1c9 3 f cb 1c8 4 f cb 1c7 5 f cb 1c6 6 f cb 1c5 7 f cb 1c4 8 f cb 1d3 9 f cb 1d2 a f cb 1d1 b f cb 1d0 c f cb 1cf d f cb 1ce e f cb 1cd f f cb 1cc 0 0 cc 1cc 1 0 cc 1cc 2 0 cc 1cc 3 0 cc 1cc 4 0 cc 1cc 5 0 cc 1cc 6 0 cc 1cc 7 0 cc 1cc 8 0 cc 1cc 9 0 cc 1cc a 0 cc 1cc b 0 cc 1cc c 0 cc 1cc d 0 cc 1cc e 0 cc 1cc f 0 cc 1cc 0 1 cc 1cc 1 1 cc 1cd 2 1 cc 1ce 3 1 cc 1cf 4 1 cc 1d0 5 1 cc 1d1 6 1 cc 1d2 7 1 cc 1d3 8 1 cc 1c4 9 1 cc 1c5 a 1 cc 1c6 b 1 cc 1c7 c 1 cc 1c8 d 1 cc 1c9 e 1 cc 1ca f 1 cc 1cb 0 2 cc 1cc 1 2 cc 1ce 2 2 cc 1d0 3 2 cc 1d2 4 2 cc 1d4 5 2 cc 1d6 6 2 cc 1d8 7 2 cc 1da 8 2 cc 1bc 9 2 cc 1be a 2 cc 1c0 b 2 cc 1c2 c 2 cc 1c4 d 2 cc 1c6 e 2 cc 1c8 f 2 cc 1ca 0 3 cc 1cc 1 3 cc 1cf 2 3 cc 1d2 3 3 cc 1d5 4 3 cc 1d8 5 3 cc 1db 6 3 cc 1de 7 3 cc 1e1 8 3 cc 1b4 9 3 cc 1b7 a 3 cc 1ba b 3 cc 1bd c 3 cc 1c0 d 3 cc 1c3 e 3 cc 1c6 f 3 cc 1c9 0 4 cc 1cc 1 4 cc 1d0 2 4 cc 1d4 3 4 cc 1d8 4 4 cc 1dc 5 4 cc 1e0 6 4 cc 1e4 7 4 cc 1e8 8 4 cc 1ac 9 4 cc 1b0 a 4 cc 1b4 b 4 cc 1b8 c 4 cc 1bc d 4 cc 1c0 e 4 cc 1c4 f 4 cc 1c8 0 5 cc 1cc 1 5 cc 1d1 2 5 cc 1d6 3 5 cc 1db 4 5 cc 1e0 5 5 cc 1e5 6 5 cc 1ea 7 5 cc 1ef 8 5 cc 1a4 9 5 cc 1a9 a 5 cc 1ae b 5 cc 1b3 c 5 cc 1b8 d 5 cc 1bd e 5 cc 1c2 f 5 cc 1c7 0 6 cc 1cc 1 6 cc 1d2 2 6 cc 1d8 3 6 cc 1de 4 6 cc 1e4 5 6 cc 1ea 6 6 cc 1f0 7 6 cc 1f6 8 6 cc 19c 9 6 cc 1a2 a 6 cc 1a8 b 6 cc 1ae c 6 cc 1b4 d 6 cc 1ba e 6 cc 1c0 f 6 cc 1c6 0 7 cc 1cc 1 7 cc 1d3 2 7 cc 1da 3 7 cc 1e1 4 7 cc 1e8 5 7 cc 1ef 6 7 cc 1f6 7 7 cc 1fd 8 7 cc 194 9 7 cc 19b a 7 cc 1a2 b 7 cc 1a9 c 7 cc 1b0 d 7 cc 1b7 e 7 cc 1be f 7 cc 1c5 0 8 cc 1cc 1 8 cc 1c4 2 8 cc 1bc 3 8 cc 1b4 4 8 cc 1ac 5 8 cc 1a4 6 8 cc 19c 7 8 cc 194 8 8 cc 00c 9 8 cc 004 a 8 cc 1fc b 8 cc 1f4 c 8 cc 1ec d 8 cc 1e4 e 8 cc 1dc f 8 cc 1d4 0 9 cc 1cc 1 9 cc 1c5 2 9 cc 1be 3 9 cc 1b7 4 9 cc 1b0 5 9 cc 1a9 6 9 cc 1a2 7 9 cc 19b 8 9 cc 004 9 9 cc 1fd a 9 cc 1f6 b 9 cc 1ef c 9 cc 1e8 d 9 cc 1e1 e 9 cc 1da f 9 cc 1d3 0 a cc 1cc 1 a cc 1c6 2 a cc 1c0 3 a cc 1ba 4 a cc 1b4 5 a cc 1ae 6 a cc 1a8 7 a cc 1a2 8 a cc 1fc 9 a cc 1f6 a a cc 1f0 b a cc 1ea c a cc 1e4 d a cc 1de e a cc 1d8 f a cc 1d2 0 b cc 1cc 1 b cc 1c7 2 b cc 1c2 3 b cc 1bd 4 b cc 1b8 5 b cc 1b3 6 b cc 1ae 7 b cc 1a9 8 b cc 1f4 9 b cc 1ef a b cc 1ea b b cc 1e5 c b cc 1e0 d b cc 1db e b cc 1d6 f b cc 1d1 0 c cc 1cc 1 c cc 1c8 2 c cc 1c4 3 c cc 1c0 4 c cc 1bc 5 c cc 1b8 6 c cc 1b4 7 c cc 1b0 8 c cc 1ec 9 c cc 1e8 a c cc 1e4 b c cc 1e0 c c cc 1dc d c cc 1d8 e c cc 1d4 f c cc 1d0 0 d cc 1cc 1 d cc 1c9 2 d cc 1c6 3 d cc 1c3 4 d cc 1c0 5 d cc 1bd 6 d cc 1ba 7 d cc 1b7 8 d cc 1e4 9 d cc 1e1 a d cc 1de b d cc 1db c d cc 1d8 d d cc 1d5 e d cc 1d2 f d cc 1cf 0 e cc 1cc 1 e cc 1ca 2 e cc 1c8 3 e cc 1c6 4 e cc 1c4 5 e cc 1c2 6 e cc 1c0 7 e cc 1be 8 e cc 1dc 9 e cc 1da a e cc 1d8 b e cc 1d6 c e cc 1d4 d e cc 1d2 e e cc 1d0 f e cc 1ce 0 f cc 1cc 1 f cc 1cb 2 f cc 1ca 3 f cc 1c9 4 f cc 1c8 5 f cc 1c7 6 f cc 1c6 7 f cc 1c5 8 f cc 1d4 9 f cc 1d3 a f cc 1d2 b f cc 1d1 c f cc 1d0 d f cc 1cf e f cc 1ce f f cc 1cd 0 0 cd 1cd 1 0 cd 1cd 2 0 cd 1cd 3 0 cd 1cd 4 0 cd 1cd 5 0 cd 1cd 6 0 cd 1cd 7 0 cd 1cd 8 0 cd 1cd 9 0 cd 1cd a 0 cd 1cd b 0 cd 1cd c 0 cd 1cd d 0 cd 1cd e 0 cd 1cd f 0 cd 1cd 0 1 cd 1cd 1 1 cd 1ce 2 1 cd 1cf 3 1 cd 1d0 4 1 cd 1d1 5 1 cd 1d2 6 1 cd 1d3 7 1 cd 1d4 8 1 cd 1c5 9 1 cd 1c6 a 1 cd 1c7 b 1 cd 1c8 c 1 cd 1c9 d 1 cd 1ca e 1 cd 1cb f 1 cd 1cc 0 2 cd 1cd 1 2 cd 1cf 2 2 cd 1d1 3 2 cd 1d3 4 2 cd 1d5 5 2 cd 1d7 6 2 cd 1d9 7 2 cd 1db 8 2 cd 1bd 9 2 cd 1bf a 2 cd 1c1 b 2 cd 1c3 c 2 cd 1c5 d 2 cd 1c7 e 2 cd 1c9 f 2 cd 1cb 0 3 cd 1cd 1 3 cd 1d0 2 3 cd 1d3 3 3 cd 1d6 4 3 cd 1d9 5 3 cd 1dc 6 3 cd 1df 7 3 cd 1e2 8 3 cd 1b5 9 3 cd 1b8 a 3 cd 1bb b 3 cd 1be c 3 cd 1c1 d 3 cd 1c4 e 3 cd 1c7 f 3 cd 1ca 0 4 cd 1cd 1 4 cd 1d1 2 4 cd 1d5 3 4 cd 1d9 4 4 cd 1dd 5 4 cd 1e1 6 4 cd 1e5 7 4 cd 1e9 8 4 cd 1ad 9 4 cd 1b1 a 4 cd 1b5 b 4 cd 1b9 c 4 cd 1bd d 4 cd 1c1 e 4 cd 1c5 f 4 cd 1c9 0 5 cd 1cd 1 5 cd 1d2 2 5 cd 1d7 3 5 cd 1dc 4 5 cd 1e1 5 5 cd 1e6 6 5 cd 1eb 7 5 cd 1f0 8 5 cd 1a5 9 5 cd 1aa a 5 cd 1af b 5 cd 1b4 c 5 cd 1b9 d 5 cd 1be e 5 cd 1c3 f 5 cd 1c8 0 6 cd 1cd 1 6 cd 1d3 2 6 cd 1d9 3 6 cd 1df 4 6 cd 1e5 5 6 cd 1eb 6 6 cd 1f1 7 6 cd 1f7 8 6 cd 19d 9 6 cd 1a3 a 6 cd 1a9 b 6 cd 1af c 6 cd 1b5 d 6 cd 1bb e 6 cd 1c1 f 6 cd 1c7 0 7 cd 1cd 1 7 cd 1d4 2 7 cd 1db 3 7 cd 1e2 4 7 cd 1e9 5 7 cd 1f0 6 7 cd 1f7 7 7 cd 1fe 8 7 cd 195 9 7 cd 19c a 7 cd 1a3 b 7 cd 1aa c 7 cd 1b1 d 7 cd 1b8 e 7 cd 1bf f 7 cd 1c6 0 8 cd 1cd 1 8 cd 1c5 2 8 cd 1bd 3 8 cd 1b5 4 8 cd 1ad 5 8 cd 1a5 6 8 cd 19d 7 8 cd 195 8 8 cd 00d 9 8 cd 005 a 8 cd 1fd b 8 cd 1f5 c 8 cd 1ed d 8 cd 1e5 e 8 cd 1dd f 8 cd 1d5 0 9 cd 1cd 1 9 cd 1c6 2 9 cd 1bf 3 9 cd 1b8 4 9 cd 1b1 5 9 cd 1aa 6 9 cd 1a3 7 9 cd 19c 8 9 cd 005 9 9 cd 1fe a 9 cd 1f7 b 9 cd 1f0 c 9 cd 1e9 d 9 cd 1e2 e 9 cd 1db f 9 cd 1d4 0 a cd 1cd 1 a cd 1c7 2 a cd 1c1 3 a cd 1bb 4 a cd 1b5 5 a cd 1af 6 a cd 1a9 7 a cd 1a3 8 a cd 1fd 9 a cd 1f7 a a cd 1f1 b a cd 1eb c a cd 1e5 d a cd 1df e a cd 1d9 f a cd 1d3 0 b cd 1cd 1 b cd 1c8 2 b cd 1c3 3 b cd 1be 4 b cd 1b9 5 b cd 1b4 6 b cd 1af 7 b cd 1aa 8 b cd 1f5 9 b cd 1f0 a b cd 1eb b b cd 1e6 c b cd 1e1 d b cd 1dc e b cd 1d7 f b cd 1d2 0 c cd 1cd 1 c cd 1c9 2 c cd 1c5 3 c cd 1c1 4 c cd 1bd 5 c cd 1b9 6 c cd 1b5 7 c cd 1b1 8 c cd 1ed 9 c cd 1e9 a c cd 1e5 b c cd 1e1 c c cd 1dd d c cd 1d9 e c cd 1d5 f c cd 1d1 0 d cd 1cd 1 d cd 1ca 2 d cd 1c7 3 d cd 1c4 4 d cd 1c1 5 d cd 1be 6 d cd 1bb 7 d cd 1b8 8 d cd 1e5 9 d cd 1e2 a d cd 1df b d cd 1dc c d cd 1d9 d d cd 1d6 e d cd 1d3 f d cd 1d0 0 e cd 1cd 1 e cd 1cb 2 e cd 1c9 3 e cd 1c7 4 e cd 1c5 5 e cd 1c3 6 e cd 1c1 7 e cd 1bf 8 e cd 1dd 9 e cd 1db a e cd 1d9 b e cd 1d7 c e cd 1d5 d e cd 1d3 e e cd 1d1 f e cd 1cf 0 f cd 1cd 1 f cd 1cc 2 f cd 1cb 3 f cd 1ca 4 f cd 1c9 5 f cd 1c8 6 f cd 1c7 7 f cd 1c6 8 f cd 1d5 9 f cd 1d4 a f cd 1d3 b f cd 1d2 c f cd 1d1 d f cd 1d0 e f cd 1cf f f cd 1ce 0 0 ce 1ce 1 0 ce 1ce 2 0 ce 1ce 3 0 ce 1ce 4 0 ce 1ce 5 0 ce 1ce 6 0 ce 1ce 7 0 ce 1ce 8 0 ce 1ce 9 0 ce 1ce a 0 ce 1ce b 0 ce 1ce c 0 ce 1ce d 0 ce 1ce e 0 ce 1ce f 0 ce 1ce 0 1 ce 1ce 1 1 ce 1cf 2 1 ce 1d0 3 1 ce 1d1 4 1 ce 1d2 5 1 ce 1d3 6 1 ce 1d4 7 1 ce 1d5 8 1 ce 1c6 9 1 ce 1c7 a 1 ce 1c8 b 1 ce 1c9 c 1 ce 1ca d 1 ce 1cb e 1 ce 1cc f 1 ce 1cd 0 2 ce 1ce 1 2 ce 1d0 2 2 ce 1d2 3 2 ce 1d4 4 2 ce 1d6 5 2 ce 1d8 6 2 ce 1da 7 2 ce 1dc 8 2 ce 1be 9 2 ce 1c0 a 2 ce 1c2 b 2 ce 1c4 c 2 ce 1c6 d 2 ce 1c8 e 2 ce 1ca f 2 ce 1cc 0 3 ce 1ce 1 3 ce 1d1 2 3 ce 1d4 3 3 ce 1d7 4 3 ce 1da 5 3 ce 1dd 6 3 ce 1e0 7 3 ce 1e3 8 3 ce 1b6 9 3 ce 1b9 a 3 ce 1bc b 3 ce 1bf c 3 ce 1c2 d 3 ce 1c5 e 3 ce 1c8 f 3 ce 1cb 0 4 ce 1ce 1 4 ce 1d2 2 4 ce 1d6 3 4 ce 1da 4 4 ce 1de 5 4 ce 1e2 6 4 ce 1e6 7 4 ce 1ea 8 4 ce 1ae 9 4 ce 1b2 a 4 ce 1b6 b 4 ce 1ba c 4 ce 1be d 4 ce 1c2 e 4 ce 1c6 f 4 ce 1ca 0 5 ce 1ce 1 5 ce 1d3 2 5 ce 1d8 3 5 ce 1dd 4 5 ce 1e2 5 5 ce 1e7 6 5 ce 1ec 7 5 ce 1f1 8 5 ce 1a6 9 5 ce 1ab a 5 ce 1b0 b 5 ce 1b5 c 5 ce 1ba d 5 ce 1bf e 5 ce 1c4 f 5 ce 1c9 0 6 ce 1ce 1 6 ce 1d4 2 6 ce 1da 3 6 ce 1e0 4 6 ce 1e6 5 6 ce 1ec 6 6 ce 1f2 7 6 ce 1f8 8 6 ce 19e 9 6 ce 1a4 a 6 ce 1aa b 6 ce 1b0 c 6 ce 1b6 d 6 ce 1bc e 6 ce 1c2 f 6 ce 1c8 0 7 ce 1ce 1 7 ce 1d5 2 7 ce 1dc 3 7 ce 1e3 4 7 ce 1ea 5 7 ce 1f1 6 7 ce 1f8 7 7 ce 1ff 8 7 ce 196 9 7 ce 19d a 7 ce 1a4 b 7 ce 1ab c 7 ce 1b2 d 7 ce 1b9 e 7 ce 1c0 f 7 ce 1c7 0 8 ce 1ce 1 8 ce 1c6 2 8 ce 1be 3 8 ce 1b6 4 8 ce 1ae 5 8 ce 1a6 6 8 ce 19e 7 8 ce 196 8 8 ce 00e 9 8 ce 006 a 8 ce 1fe b 8 ce 1f6 c 8 ce 1ee d 8 ce 1e6 e 8 ce 1de f 8 ce 1d6 0 9 ce 1ce 1 9 ce 1c7 2 9 ce 1c0 3 9 ce 1b9 4 9 ce 1b2 5 9 ce 1ab 6 9 ce 1a4 7 9 ce 19d 8 9 ce 006 9 9 ce 1ff a 9 ce 1f8 b 9 ce 1f1 c 9 ce 1ea d 9 ce 1e3 e 9 ce 1dc f 9 ce 1d5 0 a ce 1ce 1 a ce 1c8 2 a ce 1c2 3 a ce 1bc 4 a ce 1b6 5 a ce 1b0 6 a ce 1aa 7 a ce 1a4 8 a ce 1fe 9 a ce 1f8 a a ce 1f2 b a ce 1ec c a ce 1e6 d a ce 1e0 e a ce 1da f a ce 1d4 0 b ce 1ce 1 b ce 1c9 2 b ce 1c4 3 b ce 1bf 4 b ce 1ba 5 b ce 1b5 6 b ce 1b0 7 b ce 1ab 8 b ce 1f6 9 b ce 1f1 a b ce 1ec b b ce 1e7 c b ce 1e2 d b ce 1dd e b ce 1d8 f b ce 1d3 0 c ce 1ce 1 c ce 1ca 2 c ce 1c6 3 c ce 1c2 4 c ce 1be 5 c ce 1ba 6 c ce 1b6 7 c ce 1b2 8 c ce 1ee 9 c ce 1ea a c ce 1e6 b c ce 1e2 c c ce 1de d c ce 1da e c ce 1d6 f c ce 1d2 0 d ce 1ce 1 d ce 1cb 2 d ce 1c8 3 d ce 1c5 4 d ce 1c2 5 d ce 1bf 6 d ce 1bc 7 d ce 1b9 8 d ce 1e6 9 d ce 1e3 a d ce 1e0 b d ce 1dd c d ce 1da d d ce 1d7 e d ce 1d4 f d ce 1d1 0 e ce 1ce 1 e ce 1cc 2 e ce 1ca 3 e ce 1c8 4 e ce 1c6 5 e ce 1c4 6 e ce 1c2 7 e ce 1c0 8 e ce 1de 9 e ce 1dc a e ce 1da b e ce 1d8 c e ce 1d6 d e ce 1d4 e e ce 1d2 f e ce 1d0 0 f ce 1ce 1 f ce 1cd 2 f ce 1cc 3 f ce 1cb 4 f ce 1ca 5 f ce 1c9 6 f ce 1c8 7 f ce 1c7 8 f ce 1d6 9 f ce 1d5 a f ce 1d4 b f ce 1d3 c f ce 1d2 d f ce 1d1 e f ce 1d0 f f ce 1cf 0 0 cf 1cf 1 0 cf 1cf 2 0 cf 1cf 3 0 cf 1cf 4 0 cf 1cf 5 0 cf 1cf 6 0 cf 1cf 7 0 cf 1cf 8 0 cf 1cf 9 0 cf 1cf a 0 cf 1cf b 0 cf 1cf c 0 cf 1cf d 0 cf 1cf e 0 cf 1cf f 0 cf 1cf 0 1 cf 1cf 1 1 cf 1d0 2 1 cf 1d1 3 1 cf 1d2 4 1 cf 1d3 5 1 cf 1d4 6 1 cf 1d5 7 1 cf 1d6 8 1 cf 1c7 9 1 cf 1c8 a 1 cf 1c9 b 1 cf 1ca c 1 cf 1cb d 1 cf 1cc e 1 cf 1cd f 1 cf 1ce 0 2 cf 1cf 1 2 cf 1d1 2 2 cf 1d3 3 2 cf 1d5 4 2 cf 1d7 5 2 cf 1d9 6 2 cf 1db 7 2 cf 1dd 8 2 cf 1bf 9 2 cf 1c1 a 2 cf 1c3 b 2 cf 1c5 c 2 cf 1c7 d 2 cf 1c9 e 2 cf 1cb f 2 cf 1cd 0 3 cf 1cf 1 3 cf 1d2 2 3 cf 1d5 3 3 cf 1d8 4 3 cf 1db 5 3 cf 1de 6 3 cf 1e1 7 3 cf 1e4 8 3 cf 1b7 9 3 cf 1ba a 3 cf 1bd b 3 cf 1c0 c 3 cf 1c3 d 3 cf 1c6 e 3 cf 1c9 f 3 cf 1cc 0 4 cf 1cf 1 4 cf 1d3 2 4 cf 1d7 3 4 cf 1db 4 4 cf 1df 5 4 cf 1e3 6 4 cf 1e7 7 4 cf 1eb 8 4 cf 1af 9 4 cf 1b3 a 4 cf 1b7 b 4 cf 1bb c 4 cf 1bf d 4 cf 1c3 e 4 cf 1c7 f 4 cf 1cb 0 5 cf 1cf 1 5 cf 1d4 2 5 cf 1d9 3 5 cf 1de 4 5 cf 1e3 5 5 cf 1e8 6 5 cf 1ed 7 5 cf 1f2 8 5 cf 1a7 9 5 cf 1ac a 5 cf 1b1 b 5 cf 1b6 c 5 cf 1bb d 5 cf 1c0 e 5 cf 1c5 f 5 cf 1ca 0 6 cf 1cf 1 6 cf 1d5 2 6 cf 1db 3 6 cf 1e1 4 6 cf 1e7 5 6 cf 1ed 6 6 cf 1f3 7 6 cf 1f9 8 6 cf 19f 9 6 cf 1a5 a 6 cf 1ab b 6 cf 1b1 c 6 cf 1b7 d 6 cf 1bd e 6 cf 1c3 f 6 cf 1c9 0 7 cf 1cf 1 7 cf 1d6 2 7 cf 1dd 3 7 cf 1e4 4 7 cf 1eb 5 7 cf 1f2 6 7 cf 1f9 7 7 cf 000 8 7 cf 197 9 7 cf 19e a 7 cf 1a5 b 7 cf 1ac c 7 cf 1b3 d 7 cf 1ba e 7 cf 1c1 f 7 cf 1c8 0 8 cf 1cf 1 8 cf 1c7 2 8 cf 1bf 3 8 cf 1b7 4 8 cf 1af 5 8 cf 1a7 6 8 cf 19f 7 8 cf 197 8 8 cf 00f 9 8 cf 007 a 8 cf 1ff b 8 cf 1f7 c 8 cf 1ef d 8 cf 1e7 e 8 cf 1df f 8 cf 1d7 0 9 cf 1cf 1 9 cf 1c8 2 9 cf 1c1 3 9 cf 1ba 4 9 cf 1b3 5 9 cf 1ac 6 9 cf 1a5 7 9 cf 19e 8 9 cf 007 9 9 cf 000 a 9 cf 1f9 b 9 cf 1f2 c 9 cf 1eb d 9 cf 1e4 e 9 cf 1dd f 9 cf 1d6 0 a cf 1cf 1 a cf 1c9 2 a cf 1c3 3 a cf 1bd 4 a cf 1b7 5 a cf 1b1 6 a cf 1ab 7 a cf 1a5 8 a cf 1ff 9 a cf 1f9 a a cf 1f3 b a cf 1ed c a cf 1e7 d a cf 1e1 e a cf 1db f a cf 1d5 0 b cf 1cf 1 b cf 1ca 2 b cf 1c5 3 b cf 1c0 4 b cf 1bb 5 b cf 1b6 6 b cf 1b1 7 b cf 1ac 8 b cf 1f7 9 b cf 1f2 a b cf 1ed b b cf 1e8 c b cf 1e3 d b cf 1de e b cf 1d9 f b cf 1d4 0 c cf 1cf 1 c cf 1cb 2 c cf 1c7 3 c cf 1c3 4 c cf 1bf 5 c cf 1bb 6 c cf 1b7 7 c cf 1b3 8 c cf 1ef 9 c cf 1eb a c cf 1e7 b c cf 1e3 c c cf 1df d c cf 1db e c cf 1d7 f c cf 1d3 0 d cf 1cf 1 d cf 1cc 2 d cf 1c9 3 d cf 1c6 4 d cf 1c3 5 d cf 1c0 6 d cf 1bd 7 d cf 1ba 8 d cf 1e7 9 d cf 1e4 a d cf 1e1 b d cf 1de c d cf 1db d d cf 1d8 e d cf 1d5 f d cf 1d2 0 e cf 1cf 1 e cf 1cd 2 e cf 1cb 3 e cf 1c9 4 e cf 1c7 5 e cf 1c5 6 e cf 1c3 7 e cf 1c1 8 e cf 1df 9 e cf 1dd a e cf 1db b e cf 1d9 c e cf 1d7 d e cf 1d5 e e cf 1d3 f e cf 1d1 0 f cf 1cf 1 f cf 1ce 2 f cf 1cd 3 f cf 1cc 4 f cf 1cb 5 f cf 1ca 6 f cf 1c9 7 f cf 1c8 8 f cf 1d7 9 f cf 1d6 a f cf 1d5 b f cf 1d4 c f cf 1d3 d f cf 1d2 e f cf 1d1 f f cf 1d0 0 0 d0 1d0 1 0 d0 1d0 2 0 d0 1d0 3 0 d0 1d0 4 0 d0 1d0 5 0 d0 1d0 6 0 d0 1d0 7 0 d0 1d0 8 0 d0 1d0 9 0 d0 1d0 a 0 d0 1d0 b 0 d0 1d0 c 0 d0 1d0 d 0 d0 1d0 e 0 d0 1d0 f 0 d0 1d0 0 1 d0 1d0 1 1 d0 1d1 2 1 d0 1d2 3 1 d0 1d3 4 1 d0 1d4 5 1 d0 1d5 6 1 d0 1d6 7 1 d0 1d7 8 1 d0 1c8 9 1 d0 1c9 a 1 d0 1ca b 1 d0 1cb c 1 d0 1cc d 1 d0 1cd e 1 d0 1ce f 1 d0 1cf 0 2 d0 1d0 1 2 d0 1d2 2 2 d0 1d4 3 2 d0 1d6 4 2 d0 1d8 5 2 d0 1da 6 2 d0 1dc 7 2 d0 1de 8 2 d0 1c0 9 2 d0 1c2 a 2 d0 1c4 b 2 d0 1c6 c 2 d0 1c8 d 2 d0 1ca e 2 d0 1cc f 2 d0 1ce 0 3 d0 1d0 1 3 d0 1d3 2 3 d0 1d6 3 3 d0 1d9 4 3 d0 1dc 5 3 d0 1df 6 3 d0 1e2 7 3 d0 1e5 8 3 d0 1b8 9 3 d0 1bb a 3 d0 1be b 3 d0 1c1 c 3 d0 1c4 d 3 d0 1c7 e 3 d0 1ca f 3 d0 1cd 0 4 d0 1d0 1 4 d0 1d4 2 4 d0 1d8 3 4 d0 1dc 4 4 d0 1e0 5 4 d0 1e4 6 4 d0 1e8 7 4 d0 1ec 8 4 d0 1b0 9 4 d0 1b4 a 4 d0 1b8 b 4 d0 1bc c 4 d0 1c0 d 4 d0 1c4 e 4 d0 1c8 f 4 d0 1cc 0 5 d0 1d0 1 5 d0 1d5 2 5 d0 1da 3 5 d0 1df 4 5 d0 1e4 5 5 d0 1e9 6 5 d0 1ee 7 5 d0 1f3 8 5 d0 1a8 9 5 d0 1ad a 5 d0 1b2 b 5 d0 1b7 c 5 d0 1bc d 5 d0 1c1 e 5 d0 1c6 f 5 d0 1cb 0 6 d0 1d0 1 6 d0 1d6 2 6 d0 1dc 3 6 d0 1e2 4 6 d0 1e8 5 6 d0 1ee 6 6 d0 1f4 7 6 d0 1fa 8 6 d0 1a0 9 6 d0 1a6 a 6 d0 1ac b 6 d0 1b2 c 6 d0 1b8 d 6 d0 1be e 6 d0 1c4 f 6 d0 1ca 0 7 d0 1d0 1 7 d0 1d7 2 7 d0 1de 3 7 d0 1e5 4 7 d0 1ec 5 7 d0 1f3 6 7 d0 1fa 7 7 d0 001 8 7 d0 198 9 7 d0 19f a 7 d0 1a6 b 7 d0 1ad c 7 d0 1b4 d 7 d0 1bb e 7 d0 1c2 f 7 d0 1c9 0 8 d0 1d0 1 8 d0 1c8 2 8 d0 1c0 3 8 d0 1b8 4 8 d0 1b0 5 8 d0 1a8 6 8 d0 1a0 7 8 d0 198 8 8 d0 010 9 8 d0 008 a 8 d0 000 b 8 d0 1f8 c 8 d0 1f0 d 8 d0 1e8 e 8 d0 1e0 f 8 d0 1d8 0 9 d0 1d0 1 9 d0 1c9 2 9 d0 1c2 3 9 d0 1bb 4 9 d0 1b4 5 9 d0 1ad 6 9 d0 1a6 7 9 d0 19f 8 9 d0 008 9 9 d0 001 a 9 d0 1fa b 9 d0 1f3 c 9 d0 1ec d 9 d0 1e5 e 9 d0 1de f 9 d0 1d7 0 a d0 1d0 1 a d0 1ca 2 a d0 1c4 3 a d0 1be 4 a d0 1b8 5 a d0 1b2 6 a d0 1ac 7 a d0 1a6 8 a d0 000 9 a d0 1fa a a d0 1f4 b a d0 1ee c a d0 1e8 d a d0 1e2 e a d0 1dc f a d0 1d6 0 b d0 1d0 1 b d0 1cb 2 b d0 1c6 3 b d0 1c1 4 b d0 1bc 5 b d0 1b7 6 b d0 1b2 7 b d0 1ad 8 b d0 1f8 9 b d0 1f3 a b d0 1ee b b d0 1e9 c b d0 1e4 d b d0 1df e b d0 1da f b d0 1d5 0 c d0 1d0 1 c d0 1cc 2 c d0 1c8 3 c d0 1c4 4 c d0 1c0 5 c d0 1bc 6 c d0 1b8 7 c d0 1b4 8 c d0 1f0 9 c d0 1ec a c d0 1e8 b c d0 1e4 c c d0 1e0 d c d0 1dc e c d0 1d8 f c d0 1d4 0 d d0 1d0 1 d d0 1cd 2 d d0 1ca 3 d d0 1c7 4 d d0 1c4 5 d d0 1c1 6 d d0 1be 7 d d0 1bb 8 d d0 1e8 9 d d0 1e5 a d d0 1e2 b d d0 1df c d d0 1dc d d d0 1d9 e d d0 1d6 f d d0 1d3 0 e d0 1d0 1 e d0 1ce 2 e d0 1cc 3 e d0 1ca 4 e d0 1c8 5 e d0 1c6 6 e d0 1c4 7 e d0 1c2 8 e d0 1e0 9 e d0 1de a e d0 1dc b e d0 1da c e d0 1d8 d e d0 1d6 e e d0 1d4 f e d0 1d2 0 f d0 1d0 1 f d0 1cf 2 f d0 1ce 3 f d0 1cd 4 f d0 1cc 5 f d0 1cb 6 f d0 1ca 7 f d0 1c9 8 f d0 1d8 9 f d0 1d7 a f d0 1d6 b f d0 1d5 c f d0 1d4 d f d0 1d3 e f d0 1d2 f f d0 1d1 0 0 d1 1d1 1 0 d1 1d1 2 0 d1 1d1 3 0 d1 1d1 4 0 d1 1d1 5 0 d1 1d1 6 0 d1 1d1 7 0 d1 1d1 8 0 d1 1d1 9 0 d1 1d1 a 0 d1 1d1 b 0 d1 1d1 c 0 d1 1d1 d 0 d1 1d1 e 0 d1 1d1 f 0 d1 1d1 0 1 d1 1d1 1 1 d1 1d2 2 1 d1 1d3 3 1 d1 1d4 4 1 d1 1d5 5 1 d1 1d6 6 1 d1 1d7 7 1 d1 1d8 8 1 d1 1c9 9 1 d1 1ca a 1 d1 1cb b 1 d1 1cc c 1 d1 1cd d 1 d1 1ce e 1 d1 1cf f 1 d1 1d0 0 2 d1 1d1 1 2 d1 1d3 2 2 d1 1d5 3 2 d1 1d7 4 2 d1 1d9 5 2 d1 1db 6 2 d1 1dd 7 2 d1 1df 8 2 d1 1c1 9 2 d1 1c3 a 2 d1 1c5 b 2 d1 1c7 c 2 d1 1c9 d 2 d1 1cb e 2 d1 1cd f 2 d1 1cf 0 3 d1 1d1 1 3 d1 1d4 2 3 d1 1d7 3 3 d1 1da 4 3 d1 1dd 5 3 d1 1e0 6 3 d1 1e3 7 3 d1 1e6 8 3 d1 1b9 9 3 d1 1bc a 3 d1 1bf b 3 d1 1c2 c 3 d1 1c5 d 3 d1 1c8 e 3 d1 1cb f 3 d1 1ce 0 4 d1 1d1 1 4 d1 1d5 2 4 d1 1d9 3 4 d1 1dd 4 4 d1 1e1 5 4 d1 1e5 6 4 d1 1e9 7 4 d1 1ed 8 4 d1 1b1 9 4 d1 1b5 a 4 d1 1b9 b 4 d1 1bd c 4 d1 1c1 d 4 d1 1c5 e 4 d1 1c9 f 4 d1 1cd 0 5 d1 1d1 1 5 d1 1d6 2 5 d1 1db 3 5 d1 1e0 4 5 d1 1e5 5 5 d1 1ea 6 5 d1 1ef 7 5 d1 1f4 8 5 d1 1a9 9 5 d1 1ae a 5 d1 1b3 b 5 d1 1b8 c 5 d1 1bd d 5 d1 1c2 e 5 d1 1c7 f 5 d1 1cc 0 6 d1 1d1 1 6 d1 1d7 2 6 d1 1dd 3 6 d1 1e3 4 6 d1 1e9 5 6 d1 1ef 6 6 d1 1f5 7 6 d1 1fb 8 6 d1 1a1 9 6 d1 1a7 a 6 d1 1ad b 6 d1 1b3 c 6 d1 1b9 d 6 d1 1bf e 6 d1 1c5 f 6 d1 1cb 0 7 d1 1d1 1 7 d1 1d8 2 7 d1 1df 3 7 d1 1e6 4 7 d1 1ed 5 7 d1 1f4 6 7 d1 1fb 7 7 d1 002 8 7 d1 199 9 7 d1 1a0 a 7 d1 1a7 b 7 d1 1ae c 7 d1 1b5 d 7 d1 1bc e 7 d1 1c3 f 7 d1 1ca 0 8 d1 1d1 1 8 d1 1c9 2 8 d1 1c1 3 8 d1 1b9 4 8 d1 1b1 5 8 d1 1a9 6 8 d1 1a1 7 8 d1 199 8 8 d1 011 9 8 d1 009 a 8 d1 001 b 8 d1 1f9 c 8 d1 1f1 d 8 d1 1e9 e 8 d1 1e1 f 8 d1 1d9 0 9 d1 1d1 1 9 d1 1ca 2 9 d1 1c3 3 9 d1 1bc 4 9 d1 1b5 5 9 d1 1ae 6 9 d1 1a7 7 9 d1 1a0 8 9 d1 009 9 9 d1 002 a 9 d1 1fb b 9 d1 1f4 c 9 d1 1ed d 9 d1 1e6 e 9 d1 1df f 9 d1 1d8 0 a d1 1d1 1 a d1 1cb 2 a d1 1c5 3 a d1 1bf 4 a d1 1b9 5 a d1 1b3 6 a d1 1ad 7 a d1 1a7 8 a d1 001 9 a d1 1fb a a d1 1f5 b a d1 1ef c a d1 1e9 d a d1 1e3 e a d1 1dd f a d1 1d7 0 b d1 1d1 1 b d1 1cc 2 b d1 1c7 3 b d1 1c2 4 b d1 1bd 5 b d1 1b8 6 b d1 1b3 7 b d1 1ae 8 b d1 1f9 9 b d1 1f4 a b d1 1ef b b d1 1ea c b d1 1e5 d b d1 1e0 e b d1 1db f b d1 1d6 0 c d1 1d1 1 c d1 1cd 2 c d1 1c9 3 c d1 1c5 4 c d1 1c1 5 c d1 1bd 6 c d1 1b9 7 c d1 1b5 8 c d1 1f1 9 c d1 1ed a c d1 1e9 b c d1 1e5 c c d1 1e1 d c d1 1dd e c d1 1d9 f c d1 1d5 0 d d1 1d1 1 d d1 1ce 2 d d1 1cb 3 d d1 1c8 4 d d1 1c5 5 d d1 1c2 6 d d1 1bf 7 d d1 1bc 8 d d1 1e9 9 d d1 1e6 a d d1 1e3 b d d1 1e0 c d d1 1dd d d d1 1da e d d1 1d7 f d d1 1d4 0 e d1 1d1 1 e d1 1cf 2 e d1 1cd 3 e d1 1cb 4 e d1 1c9 5 e d1 1c7 6 e d1 1c5 7 e d1 1c3 8 e d1 1e1 9 e d1 1df a e d1 1dd b e d1 1db c e d1 1d9 d e d1 1d7 e e d1 1d5 f e d1 1d3 0 f d1 1d1 1 f d1 1d0 2 f d1 1cf 3 f d1 1ce 4 f d1 1cd 5 f d1 1cc 6 f d1 1cb 7 f d1 1ca 8 f d1 1d9 9 f d1 1d8 a f d1 1d7 b f d1 1d6 c f d1 1d5 d f d1 1d4 e f d1 1d3 f f d1 1d2 0 0 d2 1d2 1 0 d2 1d2 2 0 d2 1d2 3 0 d2 1d2 4 0 d2 1d2 5 0 d2 1d2 6 0 d2 1d2 7 0 d2 1d2 8 0 d2 1d2 9 0 d2 1d2 a 0 d2 1d2 b 0 d2 1d2 c 0 d2 1d2 d 0 d2 1d2 e 0 d2 1d2 f 0 d2 1d2 0 1 d2 1d2 1 1 d2 1d3 2 1 d2 1d4 3 1 d2 1d5 4 1 d2 1d6 5 1 d2 1d7 6 1 d2 1d8 7 1 d2 1d9 8 1 d2 1ca 9 1 d2 1cb a 1 d2 1cc b 1 d2 1cd c 1 d2 1ce d 1 d2 1cf e 1 d2 1d0 f 1 d2 1d1 0 2 d2 1d2 1 2 d2 1d4 2 2 d2 1d6 3 2 d2 1d8 4 2 d2 1da 5 2 d2 1dc 6 2 d2 1de 7 2 d2 1e0 8 2 d2 1c2 9 2 d2 1c4 a 2 d2 1c6 b 2 d2 1c8 c 2 d2 1ca d 2 d2 1cc e 2 d2 1ce f 2 d2 1d0 0 3 d2 1d2 1 3 d2 1d5 2 3 d2 1d8 3 3 d2 1db 4 3 d2 1de 5 3 d2 1e1 6 3 d2 1e4 7 3 d2 1e7 8 3 d2 1ba 9 3 d2 1bd a 3 d2 1c0 b 3 d2 1c3 c 3 d2 1c6 d 3 d2 1c9 e 3 d2 1cc f 3 d2 1cf 0 4 d2 1d2 1 4 d2 1d6 2 4 d2 1da 3 4 d2 1de 4 4 d2 1e2 5 4 d2 1e6 6 4 d2 1ea 7 4 d2 1ee 8 4 d2 1b2 9 4 d2 1b6 a 4 d2 1ba b 4 d2 1be c 4 d2 1c2 d 4 d2 1c6 e 4 d2 1ca f 4 d2 1ce 0 5 d2 1d2 1 5 d2 1d7 2 5 d2 1dc 3 5 d2 1e1 4 5 d2 1e6 5 5 d2 1eb 6 5 d2 1f0 7 5 d2 1f5 8 5 d2 1aa 9 5 d2 1af a 5 d2 1b4 b 5 d2 1b9 c 5 d2 1be d 5 d2 1c3 e 5 d2 1c8 f 5 d2 1cd 0 6 d2 1d2 1 6 d2 1d8 2 6 d2 1de 3 6 d2 1e4 4 6 d2 1ea 5 6 d2 1f0 6 6 d2 1f6 7 6 d2 1fc 8 6 d2 1a2 9 6 d2 1a8 a 6 d2 1ae b 6 d2 1b4 c 6 d2 1ba d 6 d2 1c0 e 6 d2 1c6 f 6 d2 1cc 0 7 d2 1d2 1 7 d2 1d9 2 7 d2 1e0 3 7 d2 1e7 4 7 d2 1ee 5 7 d2 1f5 6 7 d2 1fc 7 7 d2 003 8 7 d2 19a 9 7 d2 1a1 a 7 d2 1a8 b 7 d2 1af c 7 d2 1b6 d 7 d2 1bd e 7 d2 1c4 f 7 d2 1cb 0 8 d2 1d2 1 8 d2 1ca 2 8 d2 1c2 3 8 d2 1ba 4 8 d2 1b2 5 8 d2 1aa 6 8 d2 1a2 7 8 d2 19a 8 8 d2 012 9 8 d2 00a a 8 d2 002 b 8 d2 1fa c 8 d2 1f2 d 8 d2 1ea e 8 d2 1e2 f 8 d2 1da 0 9 d2 1d2 1 9 d2 1cb 2 9 d2 1c4 3 9 d2 1bd 4 9 d2 1b6 5 9 d2 1af 6 9 d2 1a8 7 9 d2 1a1 8 9 d2 00a 9 9 d2 003 a 9 d2 1fc b 9 d2 1f5 c 9 d2 1ee d 9 d2 1e7 e 9 d2 1e0 f 9 d2 1d9 0 a d2 1d2 1 a d2 1cc 2 a d2 1c6 3 a d2 1c0 4 a d2 1ba 5 a d2 1b4 6 a d2 1ae 7 a d2 1a8 8 a d2 002 9 a d2 1fc a a d2 1f6 b a d2 1f0 c a d2 1ea d a d2 1e4 e a d2 1de f a d2 1d8 0 b d2 1d2 1 b d2 1cd 2 b d2 1c8 3 b d2 1c3 4 b d2 1be 5 b d2 1b9 6 b d2 1b4 7 b d2 1af 8 b d2 1fa 9 b d2 1f5 a b d2 1f0 b b d2 1eb c b d2 1e6 d b d2 1e1 e b d2 1dc f b d2 1d7 0 c d2 1d2 1 c d2 1ce 2 c d2 1ca 3 c d2 1c6 4 c d2 1c2 5 c d2 1be 6 c d2 1ba 7 c d2 1b6 8 c d2 1f2 9 c d2 1ee a c d2 1ea b c d2 1e6 c c d2 1e2 d c d2 1de e c d2 1da f c d2 1d6 0 d d2 1d2 1 d d2 1cf 2 d d2 1cc 3 d d2 1c9 4 d d2 1c6 5 d d2 1c3 6 d d2 1c0 7 d d2 1bd 8 d d2 1ea 9 d d2 1e7 a d d2 1e4 b d d2 1e1 c d d2 1de d d d2 1db e d d2 1d8 f d d2 1d5 0 e d2 1d2 1 e d2 1d0 2 e d2 1ce 3 e d2 1cc 4 e d2 1ca 5 e d2 1c8 6 e d2 1c6 7 e d2 1c4 8 e d2 1e2 9 e d2 1e0 a e d2 1de b e d2 1dc c e d2 1da d e d2 1d8 e e d2 1d6 f e d2 1d4 0 f d2 1d2 1 f d2 1d1 2 f d2 1d0 3 f d2 1cf 4 f d2 1ce 5 f d2 1cd 6 f d2 1cc 7 f d2 1cb 8 f d2 1da 9 f d2 1d9 a f d2 1d8 b f d2 1d7 c f d2 1d6 d f d2 1d5 e f d2 1d4 f f d2 1d3 0 0 d3 1d3 1 0 d3 1d3 2 0 d3 1d3 3 0 d3 1d3 4 0 d3 1d3 5 0 d3 1d3 6 0 d3 1d3 7 0 d3 1d3 8 0 d3 1d3 9 0 d3 1d3 a 0 d3 1d3 b 0 d3 1d3 c 0 d3 1d3 d 0 d3 1d3 e 0 d3 1d3 f 0 d3 1d3 0 1 d3 1d3 1 1 d3 1d4 2 1 d3 1d5 3 1 d3 1d6 4 1 d3 1d7 5 1 d3 1d8 6 1 d3 1d9 7 1 d3 1da 8 1 d3 1cb 9 1 d3 1cc a 1 d3 1cd b 1 d3 1ce c 1 d3 1cf d 1 d3 1d0 e 1 d3 1d1 f 1 d3 1d2 0 2 d3 1d3 1 2 d3 1d5 2 2 d3 1d7 3 2 d3 1d9 4 2 d3 1db 5 2 d3 1dd 6 2 d3 1df 7 2 d3 1e1 8 2 d3 1c3 9 2 d3 1c5 a 2 d3 1c7 b 2 d3 1c9 c 2 d3 1cb d 2 d3 1cd e 2 d3 1cf f 2 d3 1d1 0 3 d3 1d3 1 3 d3 1d6 2 3 d3 1d9 3 3 d3 1dc 4 3 d3 1df 5 3 d3 1e2 6 3 d3 1e5 7 3 d3 1e8 8 3 d3 1bb 9 3 d3 1be a 3 d3 1c1 b 3 d3 1c4 c 3 d3 1c7 d 3 d3 1ca e 3 d3 1cd f 3 d3 1d0 0 4 d3 1d3 1 4 d3 1d7 2 4 d3 1db 3 4 d3 1df 4 4 d3 1e3 5 4 d3 1e7 6 4 d3 1eb 7 4 d3 1ef 8 4 d3 1b3 9 4 d3 1b7 a 4 d3 1bb b 4 d3 1bf c 4 d3 1c3 d 4 d3 1c7 e 4 d3 1cb f 4 d3 1cf 0 5 d3 1d3 1 5 d3 1d8 2 5 d3 1dd 3 5 d3 1e2 4 5 d3 1e7 5 5 d3 1ec 6 5 d3 1f1 7 5 d3 1f6 8 5 d3 1ab 9 5 d3 1b0 a 5 d3 1b5 b 5 d3 1ba c 5 d3 1bf d 5 d3 1c4 e 5 d3 1c9 f 5 d3 1ce 0 6 d3 1d3 1 6 d3 1d9 2 6 d3 1df 3 6 d3 1e5 4 6 d3 1eb 5 6 d3 1f1 6 6 d3 1f7 7 6 d3 1fd 8 6 d3 1a3 9 6 d3 1a9 a 6 d3 1af b 6 d3 1b5 c 6 d3 1bb d 6 d3 1c1 e 6 d3 1c7 f 6 d3 1cd 0 7 d3 1d3 1 7 d3 1da 2 7 d3 1e1 3 7 d3 1e8 4 7 d3 1ef 5 7 d3 1f6 6 7 d3 1fd 7 7 d3 004 8 7 d3 19b 9 7 d3 1a2 a 7 d3 1a9 b 7 d3 1b0 c 7 d3 1b7 d 7 d3 1be e 7 d3 1c5 f 7 d3 1cc 0 8 d3 1d3 1 8 d3 1cb 2 8 d3 1c3 3 8 d3 1bb 4 8 d3 1b3 5 8 d3 1ab 6 8 d3 1a3 7 8 d3 19b 8 8 d3 013 9 8 d3 00b a 8 d3 003 b 8 d3 1fb c 8 d3 1f3 d 8 d3 1eb e 8 d3 1e3 f 8 d3 1db 0 9 d3 1d3 1 9 d3 1cc 2 9 d3 1c5 3 9 d3 1be 4 9 d3 1b7 5 9 d3 1b0 6 9 d3 1a9 7 9 d3 1a2 8 9 d3 00b 9 9 d3 004 a 9 d3 1fd b 9 d3 1f6 c 9 d3 1ef d 9 d3 1e8 e 9 d3 1e1 f 9 d3 1da 0 a d3 1d3 1 a d3 1cd 2 a d3 1c7 3 a d3 1c1 4 a d3 1bb 5 a d3 1b5 6 a d3 1af 7 a d3 1a9 8 a d3 003 9 a d3 1fd a a d3 1f7 b a d3 1f1 c a d3 1eb d a d3 1e5 e a d3 1df f a d3 1d9 0 b d3 1d3 1 b d3 1ce 2 b d3 1c9 3 b d3 1c4 4 b d3 1bf 5 b d3 1ba 6 b d3 1b5 7 b d3 1b0 8 b d3 1fb 9 b d3 1f6 a b d3 1f1 b b d3 1ec c b d3 1e7 d b d3 1e2 e b d3 1dd f b d3 1d8 0 c d3 1d3 1 c d3 1cf 2 c d3 1cb 3 c d3 1c7 4 c d3 1c3 5 c d3 1bf 6 c d3 1bb 7 c d3 1b7 8 c d3 1f3 9 c d3 1ef a c d3 1eb b c d3 1e7 c c d3 1e3 d c d3 1df e c d3 1db f c d3 1d7 0 d d3 1d3 1 d d3 1d0 2 d d3 1cd 3 d d3 1ca 4 d d3 1c7 5 d d3 1c4 6 d d3 1c1 7 d d3 1be 8 d d3 1eb 9 d d3 1e8 a d d3 1e5 b d d3 1e2 c d d3 1df d d d3 1dc e d d3 1d9 f d d3 1d6 0 e d3 1d3 1 e d3 1d1 2 e d3 1cf 3 e d3 1cd 4 e d3 1cb 5 e d3 1c9 6 e d3 1c7 7 e d3 1c5 8 e d3 1e3 9 e d3 1e1 a e d3 1df b e d3 1dd c e d3 1db d e d3 1d9 e e d3 1d7 f e d3 1d5 0 f d3 1d3 1 f d3 1d2 2 f d3 1d1 3 f d3 1d0 4 f d3 1cf 5 f d3 1ce 6 f d3 1cd 7 f d3 1cc 8 f d3 1db 9 f d3 1da a f d3 1d9 b f d3 1d8 c f d3 1d7 d f d3 1d6 e f d3 1d5 f f d3 1d4 0 0 d4 1d4 1 0 d4 1d4 2 0 d4 1d4 3 0 d4 1d4 4 0 d4 1d4 5 0 d4 1d4 6 0 d4 1d4 7 0 d4 1d4 8 0 d4 1d4 9 0 d4 1d4 a 0 d4 1d4 b 0 d4 1d4 c 0 d4 1d4 d 0 d4 1d4 e 0 d4 1d4 f 0 d4 1d4 0 1 d4 1d4 1 1 d4 1d5 2 1 d4 1d6 3 1 d4 1d7 4 1 d4 1d8 5 1 d4 1d9 6 1 d4 1da 7 1 d4 1db 8 1 d4 1cc 9 1 d4 1cd a 1 d4 1ce b 1 d4 1cf c 1 d4 1d0 d 1 d4 1d1 e 1 d4 1d2 f 1 d4 1d3 0 2 d4 1d4 1 2 d4 1d6 2 2 d4 1d8 3 2 d4 1da 4 2 d4 1dc 5 2 d4 1de 6 2 d4 1e0 7 2 d4 1e2 8 2 d4 1c4 9 2 d4 1c6 a 2 d4 1c8 b 2 d4 1ca c 2 d4 1cc d 2 d4 1ce e 2 d4 1d0 f 2 d4 1d2 0 3 d4 1d4 1 3 d4 1d7 2 3 d4 1da 3 3 d4 1dd 4 3 d4 1e0 5 3 d4 1e3 6 3 d4 1e6 7 3 d4 1e9 8 3 d4 1bc 9 3 d4 1bf a 3 d4 1c2 b 3 d4 1c5 c 3 d4 1c8 d 3 d4 1cb e 3 d4 1ce f 3 d4 1d1 0 4 d4 1d4 1 4 d4 1d8 2 4 d4 1dc 3 4 d4 1e0 4 4 d4 1e4 5 4 d4 1e8 6 4 d4 1ec 7 4 d4 1f0 8 4 d4 1b4 9 4 d4 1b8 a 4 d4 1bc b 4 d4 1c0 c 4 d4 1c4 d 4 d4 1c8 e 4 d4 1cc f 4 d4 1d0 0 5 d4 1d4 1 5 d4 1d9 2 5 d4 1de 3 5 d4 1e3 4 5 d4 1e8 5 5 d4 1ed 6 5 d4 1f2 7 5 d4 1f7 8 5 d4 1ac 9 5 d4 1b1 a 5 d4 1b6 b 5 d4 1bb c 5 d4 1c0 d 5 d4 1c5 e 5 d4 1ca f 5 d4 1cf 0 6 d4 1d4 1 6 d4 1da 2 6 d4 1e0 3 6 d4 1e6 4 6 d4 1ec 5 6 d4 1f2 6 6 d4 1f8 7 6 d4 1fe 8 6 d4 1a4 9 6 d4 1aa a 6 d4 1b0 b 6 d4 1b6 c 6 d4 1bc d 6 d4 1c2 e 6 d4 1c8 f 6 d4 1ce 0 7 d4 1d4 1 7 d4 1db 2 7 d4 1e2 3 7 d4 1e9 4 7 d4 1f0 5 7 d4 1f7 6 7 d4 1fe 7 7 d4 005 8 7 d4 19c 9 7 d4 1a3 a 7 d4 1aa b 7 d4 1b1 c 7 d4 1b8 d 7 d4 1bf e 7 d4 1c6 f 7 d4 1cd 0 8 d4 1d4 1 8 d4 1cc 2 8 d4 1c4 3 8 d4 1bc 4 8 d4 1b4 5 8 d4 1ac 6 8 d4 1a4 7 8 d4 19c 8 8 d4 014 9 8 d4 00c a 8 d4 004 b 8 d4 1fc c 8 d4 1f4 d 8 d4 1ec e 8 d4 1e4 f 8 d4 1dc 0 9 d4 1d4 1 9 d4 1cd 2 9 d4 1c6 3 9 d4 1bf 4 9 d4 1b8 5 9 d4 1b1 6 9 d4 1aa 7 9 d4 1a3 8 9 d4 00c 9 9 d4 005 a 9 d4 1fe b 9 d4 1f7 c 9 d4 1f0 d 9 d4 1e9 e 9 d4 1e2 f 9 d4 1db 0 a d4 1d4 1 a d4 1ce 2 a d4 1c8 3 a d4 1c2 4 a d4 1bc 5 a d4 1b6 6 a d4 1b0 7 a d4 1aa 8 a d4 004 9 a d4 1fe a a d4 1f8 b a d4 1f2 c a d4 1ec d a d4 1e6 e a d4 1e0 f a d4 1da 0 b d4 1d4 1 b d4 1cf 2 b d4 1ca 3 b d4 1c5 4 b d4 1c0 5 b d4 1bb 6 b d4 1b6 7 b d4 1b1 8 b d4 1fc 9 b d4 1f7 a b d4 1f2 b b d4 1ed c b d4 1e8 d b d4 1e3 e b d4 1de f b d4 1d9 0 c d4 1d4 1 c d4 1d0 2 c d4 1cc 3 c d4 1c8 4 c d4 1c4 5 c d4 1c0 6 c d4 1bc 7 c d4 1b8 8 c d4 1f4 9 c d4 1f0 a c d4 1ec b c d4 1e8 c c d4 1e4 d c d4 1e0 e c d4 1dc f c d4 1d8 0 d d4 1d4 1 d d4 1d1 2 d d4 1ce 3 d d4 1cb 4 d d4 1c8 5 d d4 1c5 6 d d4 1c2 7 d d4 1bf 8 d d4 1ec 9 d d4 1e9 a d d4 1e6 b d d4 1e3 c d d4 1e0 d d d4 1dd e d d4 1da f d d4 1d7 0 e d4 1d4 1 e d4 1d2 2 e d4 1d0 3 e d4 1ce 4 e d4 1cc 5 e d4 1ca 6 e d4 1c8 7 e d4 1c6 8 e d4 1e4 9 e d4 1e2 a e d4 1e0 b e d4 1de c e d4 1dc d e d4 1da e e d4 1d8 f e d4 1d6 0 f d4 1d4 1 f d4 1d3 2 f d4 1d2 3 f d4 1d1 4 f d4 1d0 5 f d4 1cf 6 f d4 1ce 7 f d4 1cd 8 f d4 1dc 9 f d4 1db a f d4 1da b f d4 1d9 c f d4 1d8 d f d4 1d7 e f d4 1d6 f f d4 1d5 0 0 d5 1d5 1 0 d5 1d5 2 0 d5 1d5 3 0 d5 1d5 4 0 d5 1d5 5 0 d5 1d5 6 0 d5 1d5 7 0 d5 1d5 8 0 d5 1d5 9 0 d5 1d5 a 0 d5 1d5 b 0 d5 1d5 c 0 d5 1d5 d 0 d5 1d5 e 0 d5 1d5 f 0 d5 1d5 0 1 d5 1d5 1 1 d5 1d6 2 1 d5 1d7 3 1 d5 1d8 4 1 d5 1d9 5 1 d5 1da 6 1 d5 1db 7 1 d5 1dc 8 1 d5 1cd 9 1 d5 1ce a 1 d5 1cf b 1 d5 1d0 c 1 d5 1d1 d 1 d5 1d2 e 1 d5 1d3 f 1 d5 1d4 0 2 d5 1d5 1 2 d5 1d7 2 2 d5 1d9 3 2 d5 1db 4 2 d5 1dd 5 2 d5 1df 6 2 d5 1e1 7 2 d5 1e3 8 2 d5 1c5 9 2 d5 1c7 a 2 d5 1c9 b 2 d5 1cb c 2 d5 1cd d 2 d5 1cf e 2 d5 1d1 f 2 d5 1d3 0 3 d5 1d5 1 3 d5 1d8 2 3 d5 1db 3 3 d5 1de 4 3 d5 1e1 5 3 d5 1e4 6 3 d5 1e7 7 3 d5 1ea 8 3 d5 1bd 9 3 d5 1c0 a 3 d5 1c3 b 3 d5 1c6 c 3 d5 1c9 d 3 d5 1cc e 3 d5 1cf f 3 d5 1d2 0 4 d5 1d5 1 4 d5 1d9 2 4 d5 1dd 3 4 d5 1e1 4 4 d5 1e5 5 4 d5 1e9 6 4 d5 1ed 7 4 d5 1f1 8 4 d5 1b5 9 4 d5 1b9 a 4 d5 1bd b 4 d5 1c1 c 4 d5 1c5 d 4 d5 1c9 e 4 d5 1cd f 4 d5 1d1 0 5 d5 1d5 1 5 d5 1da 2 5 d5 1df 3 5 d5 1e4 4 5 d5 1e9 5 5 d5 1ee 6 5 d5 1f3 7 5 d5 1f8 8 5 d5 1ad 9 5 d5 1b2 a 5 d5 1b7 b 5 d5 1bc c 5 d5 1c1 d 5 d5 1c6 e 5 d5 1cb f 5 d5 1d0 0 6 d5 1d5 1 6 d5 1db 2 6 d5 1e1 3 6 d5 1e7 4 6 d5 1ed 5 6 d5 1f3 6 6 d5 1f9 7 6 d5 1ff 8 6 d5 1a5 9 6 d5 1ab a 6 d5 1b1 b 6 d5 1b7 c 6 d5 1bd d 6 d5 1c3 e 6 d5 1c9 f 6 d5 1cf 0 7 d5 1d5 1 7 d5 1dc 2 7 d5 1e3 3 7 d5 1ea 4 7 d5 1f1 5 7 d5 1f8 6 7 d5 1ff 7 7 d5 006 8 7 d5 19d 9 7 d5 1a4 a 7 d5 1ab b 7 d5 1b2 c 7 d5 1b9 d 7 d5 1c0 e 7 d5 1c7 f 7 d5 1ce 0 8 d5 1d5 1 8 d5 1cd 2 8 d5 1c5 3 8 d5 1bd 4 8 d5 1b5 5 8 d5 1ad 6 8 d5 1a5 7 8 d5 19d 8 8 d5 015 9 8 d5 00d a 8 d5 005 b 8 d5 1fd c 8 d5 1f5 d 8 d5 1ed e 8 d5 1e5 f 8 d5 1dd 0 9 d5 1d5 1 9 d5 1ce 2 9 d5 1c7 3 9 d5 1c0 4 9 d5 1b9 5 9 d5 1b2 6 9 d5 1ab 7 9 d5 1a4 8 9 d5 00d 9 9 d5 006 a 9 d5 1ff b 9 d5 1f8 c 9 d5 1f1 d 9 d5 1ea e 9 d5 1e3 f 9 d5 1dc 0 a d5 1d5 1 a d5 1cf 2 a d5 1c9 3 a d5 1c3 4 a d5 1bd 5 a d5 1b7 6 a d5 1b1 7 a d5 1ab 8 a d5 005 9 a d5 1ff a a d5 1f9 b a d5 1f3 c a d5 1ed d a d5 1e7 e a d5 1e1 f a d5 1db 0 b d5 1d5 1 b d5 1d0 2 b d5 1cb 3 b d5 1c6 4 b d5 1c1 5 b d5 1bc 6 b d5 1b7 7 b d5 1b2 8 b d5 1fd 9 b d5 1f8 a b d5 1f3 b b d5 1ee c b d5 1e9 d b d5 1e4 e b d5 1df f b d5 1da 0 c d5 1d5 1 c d5 1d1 2 c d5 1cd 3 c d5 1c9 4 c d5 1c5 5 c d5 1c1 6 c d5 1bd 7 c d5 1b9 8 c d5 1f5 9 c d5 1f1 a c d5 1ed b c d5 1e9 c c d5 1e5 d c d5 1e1 e c d5 1dd f c d5 1d9 0 d d5 1d5 1 d d5 1d2 2 d d5 1cf 3 d d5 1cc 4 d d5 1c9 5 d d5 1c6 6 d d5 1c3 7 d d5 1c0 8 d d5 1ed 9 d d5 1ea a d d5 1e7 b d d5 1e4 c d d5 1e1 d d d5 1de e d d5 1db f d d5 1d8 0 e d5 1d5 1 e d5 1d3 2 e d5 1d1 3 e d5 1cf 4 e d5 1cd 5 e d5 1cb 6 e d5 1c9 7 e d5 1c7 8 e d5 1e5 9 e d5 1e3 a e d5 1e1 b e d5 1df c e d5 1dd d e d5 1db e e d5 1d9 f e d5 1d7 0 f d5 1d5 1 f d5 1d4 2 f d5 1d3 3 f d5 1d2 4 f d5 1d1 5 f d5 1d0 6 f d5 1cf 7 f d5 1ce 8 f d5 1dd 9 f d5 1dc a f d5 1db b f d5 1da c f d5 1d9 d f d5 1d8 e f d5 1d7 f f d5 1d6 0 0 d6 1d6 1 0 d6 1d6 2 0 d6 1d6 3 0 d6 1d6 4 0 d6 1d6 5 0 d6 1d6 6 0 d6 1d6 7 0 d6 1d6 8 0 d6 1d6 9 0 d6 1d6 a 0 d6 1d6 b 0 d6 1d6 c 0 d6 1d6 d 0 d6 1d6 e 0 d6 1d6 f 0 d6 1d6 0 1 d6 1d6 1 1 d6 1d7 2 1 d6 1d8 3 1 d6 1d9 4 1 d6 1da 5 1 d6 1db 6 1 d6 1dc 7 1 d6 1dd 8 1 d6 1ce 9 1 d6 1cf a 1 d6 1d0 b 1 d6 1d1 c 1 d6 1d2 d 1 d6 1d3 e 1 d6 1d4 f 1 d6 1d5 0 2 d6 1d6 1 2 d6 1d8 2 2 d6 1da 3 2 d6 1dc 4 2 d6 1de 5 2 d6 1e0 6 2 d6 1e2 7 2 d6 1e4 8 2 d6 1c6 9 2 d6 1c8 a 2 d6 1ca b 2 d6 1cc c 2 d6 1ce d 2 d6 1d0 e 2 d6 1d2 f 2 d6 1d4 0 3 d6 1d6 1 3 d6 1d9 2 3 d6 1dc 3 3 d6 1df 4 3 d6 1e2 5 3 d6 1e5 6 3 d6 1e8 7 3 d6 1eb 8 3 d6 1be 9 3 d6 1c1 a 3 d6 1c4 b 3 d6 1c7 c 3 d6 1ca d 3 d6 1cd e 3 d6 1d0 f 3 d6 1d3 0 4 d6 1d6 1 4 d6 1da 2 4 d6 1de 3 4 d6 1e2 4 4 d6 1e6 5 4 d6 1ea 6 4 d6 1ee 7 4 d6 1f2 8 4 d6 1b6 9 4 d6 1ba a 4 d6 1be b 4 d6 1c2 c 4 d6 1c6 d 4 d6 1ca e 4 d6 1ce f 4 d6 1d2 0 5 d6 1d6 1 5 d6 1db 2 5 d6 1e0 3 5 d6 1e5 4 5 d6 1ea 5 5 d6 1ef 6 5 d6 1f4 7 5 d6 1f9 8 5 d6 1ae 9 5 d6 1b3 a 5 d6 1b8 b 5 d6 1bd c 5 d6 1c2 d 5 d6 1c7 e 5 d6 1cc f 5 d6 1d1 0 6 d6 1d6 1 6 d6 1dc 2 6 d6 1e2 3 6 d6 1e8 4 6 d6 1ee 5 6 d6 1f4 6 6 d6 1fa 7 6 d6 000 8 6 d6 1a6 9 6 d6 1ac a 6 d6 1b2 b 6 d6 1b8 c 6 d6 1be d 6 d6 1c4 e 6 d6 1ca f 6 d6 1d0 0 7 d6 1d6 1 7 d6 1dd 2 7 d6 1e4 3 7 d6 1eb 4 7 d6 1f2 5 7 d6 1f9 6 7 d6 000 7 7 d6 007 8 7 d6 19e 9 7 d6 1a5 a 7 d6 1ac b 7 d6 1b3 c 7 d6 1ba d 7 d6 1c1 e 7 d6 1c8 f 7 d6 1cf 0 8 d6 1d6 1 8 d6 1ce 2 8 d6 1c6 3 8 d6 1be 4 8 d6 1b6 5 8 d6 1ae 6 8 d6 1a6 7 8 d6 19e 8 8 d6 016 9 8 d6 00e a 8 d6 006 b 8 d6 1fe c 8 d6 1f6 d 8 d6 1ee e 8 d6 1e6 f 8 d6 1de 0 9 d6 1d6 1 9 d6 1cf 2 9 d6 1c8 3 9 d6 1c1 4 9 d6 1ba 5 9 d6 1b3 6 9 d6 1ac 7 9 d6 1a5 8 9 d6 00e 9 9 d6 007 a 9 d6 000 b 9 d6 1f9 c 9 d6 1f2 d 9 d6 1eb e 9 d6 1e4 f 9 d6 1dd 0 a d6 1d6 1 a d6 1d0 2 a d6 1ca 3 a d6 1c4 4 a d6 1be 5 a d6 1b8 6 a d6 1b2 7 a d6 1ac 8 a d6 006 9 a d6 000 a a d6 1fa b a d6 1f4 c a d6 1ee d a d6 1e8 e a d6 1e2 f a d6 1dc 0 b d6 1d6 1 b d6 1d1 2 b d6 1cc 3 b d6 1c7 4 b d6 1c2 5 b d6 1bd 6 b d6 1b8 7 b d6 1b3 8 b d6 1fe 9 b d6 1f9 a b d6 1f4 b b d6 1ef c b d6 1ea d b d6 1e5 e b d6 1e0 f b d6 1db 0 c d6 1d6 1 c d6 1d2 2 c d6 1ce 3 c d6 1ca 4 c d6 1c6 5 c d6 1c2 6 c d6 1be 7 c d6 1ba 8 c d6 1f6 9 c d6 1f2 a c d6 1ee b c d6 1ea c c d6 1e6 d c d6 1e2 e c d6 1de f c d6 1da 0 d d6 1d6 1 d d6 1d3 2 d d6 1d0 3 d d6 1cd 4 d d6 1ca 5 d d6 1c7 6 d d6 1c4 7 d d6 1c1 8 d d6 1ee 9 d d6 1eb a d d6 1e8 b d d6 1e5 c d d6 1e2 d d d6 1df e d d6 1dc f d d6 1d9 0 e d6 1d6 1 e d6 1d4 2 e d6 1d2 3 e d6 1d0 4 e d6 1ce 5 e d6 1cc 6 e d6 1ca 7 e d6 1c8 8 e d6 1e6 9 e d6 1e4 a e d6 1e2 b e d6 1e0 c e d6 1de d e d6 1dc e e d6 1da f e d6 1d8 0 f d6 1d6 1 f d6 1d5 2 f d6 1d4 3 f d6 1d3 4 f d6 1d2 5 f d6 1d1 6 f d6 1d0 7 f d6 1cf 8 f d6 1de 9 f d6 1dd a f d6 1dc b f d6 1db c f d6 1da d f d6 1d9 e f d6 1d8 f f d6 1d7 0 0 d7 1d7 1 0 d7 1d7 2 0 d7 1d7 3 0 d7 1d7 4 0 d7 1d7 5 0 d7 1d7 6 0 d7 1d7 7 0 d7 1d7 8 0 d7 1d7 9 0 d7 1d7 a 0 d7 1d7 b 0 d7 1d7 c 0 d7 1d7 d 0 d7 1d7 e 0 d7 1d7 f 0 d7 1d7 0 1 d7 1d7 1 1 d7 1d8 2 1 d7 1d9 3 1 d7 1da 4 1 d7 1db 5 1 d7 1dc 6 1 d7 1dd 7 1 d7 1de 8 1 d7 1cf 9 1 d7 1d0 a 1 d7 1d1 b 1 d7 1d2 c 1 d7 1d3 d 1 d7 1d4 e 1 d7 1d5 f 1 d7 1d6 0 2 d7 1d7 1 2 d7 1d9 2 2 d7 1db 3 2 d7 1dd 4 2 d7 1df 5 2 d7 1e1 6 2 d7 1e3 7 2 d7 1e5 8 2 d7 1c7 9 2 d7 1c9 a 2 d7 1cb b 2 d7 1cd c 2 d7 1cf d 2 d7 1d1 e 2 d7 1d3 f 2 d7 1d5 0 3 d7 1d7 1 3 d7 1da 2 3 d7 1dd 3 3 d7 1e0 4 3 d7 1e3 5 3 d7 1e6 6 3 d7 1e9 7 3 d7 1ec 8 3 d7 1bf 9 3 d7 1c2 a 3 d7 1c5 b 3 d7 1c8 c 3 d7 1cb d 3 d7 1ce e 3 d7 1d1 f 3 d7 1d4 0 4 d7 1d7 1 4 d7 1db 2 4 d7 1df 3 4 d7 1e3 4 4 d7 1e7 5 4 d7 1eb 6 4 d7 1ef 7 4 d7 1f3 8 4 d7 1b7 9 4 d7 1bb a 4 d7 1bf b 4 d7 1c3 c 4 d7 1c7 d 4 d7 1cb e 4 d7 1cf f 4 d7 1d3 0 5 d7 1d7 1 5 d7 1dc 2 5 d7 1e1 3 5 d7 1e6 4 5 d7 1eb 5 5 d7 1f0 6 5 d7 1f5 7 5 d7 1fa 8 5 d7 1af 9 5 d7 1b4 a 5 d7 1b9 b 5 d7 1be c 5 d7 1c3 d 5 d7 1c8 e 5 d7 1cd f 5 d7 1d2 0 6 d7 1d7 1 6 d7 1dd 2 6 d7 1e3 3 6 d7 1e9 4 6 d7 1ef 5 6 d7 1f5 6 6 d7 1fb 7 6 d7 001 8 6 d7 1a7 9 6 d7 1ad a 6 d7 1b3 b 6 d7 1b9 c 6 d7 1bf d 6 d7 1c5 e 6 d7 1cb f 6 d7 1d1 0 7 d7 1d7 1 7 d7 1de 2 7 d7 1e5 3 7 d7 1ec 4 7 d7 1f3 5 7 d7 1fa 6 7 d7 001 7 7 d7 008 8 7 d7 19f 9 7 d7 1a6 a 7 d7 1ad b 7 d7 1b4 c 7 d7 1bb d 7 d7 1c2 e 7 d7 1c9 f 7 d7 1d0 0 8 d7 1d7 1 8 d7 1cf 2 8 d7 1c7 3 8 d7 1bf 4 8 d7 1b7 5 8 d7 1af 6 8 d7 1a7 7 8 d7 19f 8 8 d7 017 9 8 d7 00f a 8 d7 007 b 8 d7 1ff c 8 d7 1f7 d 8 d7 1ef e 8 d7 1e7 f 8 d7 1df 0 9 d7 1d7 1 9 d7 1d0 2 9 d7 1c9 3 9 d7 1c2 4 9 d7 1bb 5 9 d7 1b4 6 9 d7 1ad 7 9 d7 1a6 8 9 d7 00f 9 9 d7 008 a 9 d7 001 b 9 d7 1fa c 9 d7 1f3 d 9 d7 1ec e 9 d7 1e5 f 9 d7 1de 0 a d7 1d7 1 a d7 1d1 2 a d7 1cb 3 a d7 1c5 4 a d7 1bf 5 a d7 1b9 6 a d7 1b3 7 a d7 1ad 8 a d7 007 9 a d7 001 a a d7 1fb b a d7 1f5 c a d7 1ef d a d7 1e9 e a d7 1e3 f a d7 1dd 0 b d7 1d7 1 b d7 1d2 2 b d7 1cd 3 b d7 1c8 4 b d7 1c3 5 b d7 1be 6 b d7 1b9 7 b d7 1b4 8 b d7 1ff 9 b d7 1fa a b d7 1f5 b b d7 1f0 c b d7 1eb d b d7 1e6 e b d7 1e1 f b d7 1dc 0 c d7 1d7 1 c d7 1d3 2 c d7 1cf 3 c d7 1cb 4 c d7 1c7 5 c d7 1c3 6 c d7 1bf 7 c d7 1bb 8 c d7 1f7 9 c d7 1f3 a c d7 1ef b c d7 1eb c c d7 1e7 d c d7 1e3 e c d7 1df f c d7 1db 0 d d7 1d7 1 d d7 1d4 2 d d7 1d1 3 d d7 1ce 4 d d7 1cb 5 d d7 1c8 6 d d7 1c5 7 d d7 1c2 8 d d7 1ef 9 d d7 1ec a d d7 1e9 b d d7 1e6 c d d7 1e3 d d d7 1e0 e d d7 1dd f d d7 1da 0 e d7 1d7 1 e d7 1d5 2 e d7 1d3 3 e d7 1d1 4 e d7 1cf 5 e d7 1cd 6 e d7 1cb 7 e d7 1c9 8 e d7 1e7 9 e d7 1e5 a e d7 1e3 b e d7 1e1 c e d7 1df d e d7 1dd e e d7 1db f e d7 1d9 0 f d7 1d7 1 f d7 1d6 2 f d7 1d5 3 f d7 1d4 4 f d7 1d3 5 f d7 1d2 6 f d7 1d1 7 f d7 1d0 8 f d7 1df 9 f d7 1de a f d7 1dd b f d7 1dc c f d7 1db d f d7 1da e f d7 1d9 f f d7 1d8 0 0 d8 1d8 1 0 d8 1d8 2 0 d8 1d8 3 0 d8 1d8 4 0 d8 1d8 5 0 d8 1d8 6 0 d8 1d8 7 0 d8 1d8 8 0 d8 1d8 9 0 d8 1d8 a 0 d8 1d8 b 0 d8 1d8 c 0 d8 1d8 d 0 d8 1d8 e 0 d8 1d8 f 0 d8 1d8 0 1 d8 1d8 1 1 d8 1d9 2 1 d8 1da 3 1 d8 1db 4 1 d8 1dc 5 1 d8 1dd 6 1 d8 1de 7 1 d8 1df 8 1 d8 1d0 9 1 d8 1d1 a 1 d8 1d2 b 1 d8 1d3 c 1 d8 1d4 d 1 d8 1d5 e 1 d8 1d6 f 1 d8 1d7 0 2 d8 1d8 1 2 d8 1da 2 2 d8 1dc 3 2 d8 1de 4 2 d8 1e0 5 2 d8 1e2 6 2 d8 1e4 7 2 d8 1e6 8 2 d8 1c8 9 2 d8 1ca a 2 d8 1cc b 2 d8 1ce c 2 d8 1d0 d 2 d8 1d2 e 2 d8 1d4 f 2 d8 1d6 0 3 d8 1d8 1 3 d8 1db 2 3 d8 1de 3 3 d8 1e1 4 3 d8 1e4 5 3 d8 1e7 6 3 d8 1ea 7 3 d8 1ed 8 3 d8 1c0 9 3 d8 1c3 a 3 d8 1c6 b 3 d8 1c9 c 3 d8 1cc d 3 d8 1cf e 3 d8 1d2 f 3 d8 1d5 0 4 d8 1d8 1 4 d8 1dc 2 4 d8 1e0 3 4 d8 1e4 4 4 d8 1e8 5 4 d8 1ec 6 4 d8 1f0 7 4 d8 1f4 8 4 d8 1b8 9 4 d8 1bc a 4 d8 1c0 b 4 d8 1c4 c 4 d8 1c8 d 4 d8 1cc e 4 d8 1d0 f 4 d8 1d4 0 5 d8 1d8 1 5 d8 1dd 2 5 d8 1e2 3 5 d8 1e7 4 5 d8 1ec 5 5 d8 1f1 6 5 d8 1f6 7 5 d8 1fb 8 5 d8 1b0 9 5 d8 1b5 a 5 d8 1ba b 5 d8 1bf c 5 d8 1c4 d 5 d8 1c9 e 5 d8 1ce f 5 d8 1d3 0 6 d8 1d8 1 6 d8 1de 2 6 d8 1e4 3 6 d8 1ea 4 6 d8 1f0 5 6 d8 1f6 6 6 d8 1fc 7 6 d8 002 8 6 d8 1a8 9 6 d8 1ae a 6 d8 1b4 b 6 d8 1ba c 6 d8 1c0 d 6 d8 1c6 e 6 d8 1cc f 6 d8 1d2 0 7 d8 1d8 1 7 d8 1df 2 7 d8 1e6 3 7 d8 1ed 4 7 d8 1f4 5 7 d8 1fb 6 7 d8 002 7 7 d8 009 8 7 d8 1a0 9 7 d8 1a7 a 7 d8 1ae b 7 d8 1b5 c 7 d8 1bc d 7 d8 1c3 e 7 d8 1ca f 7 d8 1d1 0 8 d8 1d8 1 8 d8 1d0 2 8 d8 1c8 3 8 d8 1c0 4 8 d8 1b8 5 8 d8 1b0 6 8 d8 1a8 7 8 d8 1a0 8 8 d8 018 9 8 d8 010 a 8 d8 008 b 8 d8 000 c 8 d8 1f8 d 8 d8 1f0 e 8 d8 1e8 f 8 d8 1e0 0 9 d8 1d8 1 9 d8 1d1 2 9 d8 1ca 3 9 d8 1c3 4 9 d8 1bc 5 9 d8 1b5 6 9 d8 1ae 7 9 d8 1a7 8 9 d8 010 9 9 d8 009 a 9 d8 002 b 9 d8 1fb c 9 d8 1f4 d 9 d8 1ed e 9 d8 1e6 f 9 d8 1df 0 a d8 1d8 1 a d8 1d2 2 a d8 1cc 3 a d8 1c6 4 a d8 1c0 5 a d8 1ba 6 a d8 1b4 7 a d8 1ae 8 a d8 008 9 a d8 002 a a d8 1fc b a d8 1f6 c a d8 1f0 d a d8 1ea e a d8 1e4 f a d8 1de 0 b d8 1d8 1 b d8 1d3 2 b d8 1ce 3 b d8 1c9 4 b d8 1c4 5 b d8 1bf 6 b d8 1ba 7 b d8 1b5 8 b d8 000 9 b d8 1fb a b d8 1f6 b b d8 1f1 c b d8 1ec d b d8 1e7 e b d8 1e2 f b d8 1dd 0 c d8 1d8 1 c d8 1d4 2 c d8 1d0 3 c d8 1cc 4 c d8 1c8 5 c d8 1c4 6 c d8 1c0 7 c d8 1bc 8 c d8 1f8 9 c d8 1f4 a c d8 1f0 b c d8 1ec c c d8 1e8 d c d8 1e4 e c d8 1e0 f c d8 1dc 0 d d8 1d8 1 d d8 1d5 2 d d8 1d2 3 d d8 1cf 4 d d8 1cc 5 d d8 1c9 6 d d8 1c6 7 d d8 1c3 8 d d8 1f0 9 d d8 1ed a d d8 1ea b d d8 1e7 c d d8 1e4 d d d8 1e1 e d d8 1de f d d8 1db 0 e d8 1d8 1 e d8 1d6 2 e d8 1d4 3 e d8 1d2 4 e d8 1d0 5 e d8 1ce 6 e d8 1cc 7 e d8 1ca 8 e d8 1e8 9 e d8 1e6 a e d8 1e4 b e d8 1e2 c e d8 1e0 d e d8 1de e e d8 1dc f e d8 1da 0 f d8 1d8 1 f d8 1d7 2 f d8 1d6 3 f d8 1d5 4 f d8 1d4 5 f d8 1d3 6 f d8 1d2 7 f d8 1d1 8 f d8 1e0 9 f d8 1df a f d8 1de b f d8 1dd c f d8 1dc d f d8 1db e f d8 1da f f d8 1d9 0 0 d9 1d9 1 0 d9 1d9 2 0 d9 1d9 3 0 d9 1d9 4 0 d9 1d9 5 0 d9 1d9 6 0 d9 1d9 7 0 d9 1d9 8 0 d9 1d9 9 0 d9 1d9 a 0 d9 1d9 b 0 d9 1d9 c 0 d9 1d9 d 0 d9 1d9 e 0 d9 1d9 f 0 d9 1d9 0 1 d9 1d9 1 1 d9 1da 2 1 d9 1db 3 1 d9 1dc 4 1 d9 1dd 5 1 d9 1de 6 1 d9 1df 7 1 d9 1e0 8 1 d9 1d1 9 1 d9 1d2 a 1 d9 1d3 b 1 d9 1d4 c 1 d9 1d5 d 1 d9 1d6 e 1 d9 1d7 f 1 d9 1d8 0 2 d9 1d9 1 2 d9 1db 2 2 d9 1dd 3 2 d9 1df 4 2 d9 1e1 5 2 d9 1e3 6 2 d9 1e5 7 2 d9 1e7 8 2 d9 1c9 9 2 d9 1cb a 2 d9 1cd b 2 d9 1cf c 2 d9 1d1 d 2 d9 1d3 e 2 d9 1d5 f 2 d9 1d7 0 3 d9 1d9 1 3 d9 1dc 2 3 d9 1df 3 3 d9 1e2 4 3 d9 1e5 5 3 d9 1e8 6 3 d9 1eb 7 3 d9 1ee 8 3 d9 1c1 9 3 d9 1c4 a 3 d9 1c7 b 3 d9 1ca c 3 d9 1cd d 3 d9 1d0 e 3 d9 1d3 f 3 d9 1d6 0 4 d9 1d9 1 4 d9 1dd 2 4 d9 1e1 3 4 d9 1e5 4 4 d9 1e9 5 4 d9 1ed 6 4 d9 1f1 7 4 d9 1f5 8 4 d9 1b9 9 4 d9 1bd a 4 d9 1c1 b 4 d9 1c5 c 4 d9 1c9 d 4 d9 1cd e 4 d9 1d1 f 4 d9 1d5 0 5 d9 1d9 1 5 d9 1de 2 5 d9 1e3 3 5 d9 1e8 4 5 d9 1ed 5 5 d9 1f2 6 5 d9 1f7 7 5 d9 1fc 8 5 d9 1b1 9 5 d9 1b6 a 5 d9 1bb b 5 d9 1c0 c 5 d9 1c5 d 5 d9 1ca e 5 d9 1cf f 5 d9 1d4 0 6 d9 1d9 1 6 d9 1df 2 6 d9 1e5 3 6 d9 1eb 4 6 d9 1f1 5 6 d9 1f7 6 6 d9 1fd 7 6 d9 003 8 6 d9 1a9 9 6 d9 1af a 6 d9 1b5 b 6 d9 1bb c 6 d9 1c1 d 6 d9 1c7 e 6 d9 1cd f 6 d9 1d3 0 7 d9 1d9 1 7 d9 1e0 2 7 d9 1e7 3 7 d9 1ee 4 7 d9 1f5 5 7 d9 1fc 6 7 d9 003 7 7 d9 00a 8 7 d9 1a1 9 7 d9 1a8 a 7 d9 1af b 7 d9 1b6 c 7 d9 1bd d 7 d9 1c4 e 7 d9 1cb f 7 d9 1d2 0 8 d9 1d9 1 8 d9 1d1 2 8 d9 1c9 3 8 d9 1c1 4 8 d9 1b9 5 8 d9 1b1 6 8 d9 1a9 7 8 d9 1a1 8 8 d9 019 9 8 d9 011 a 8 d9 009 b 8 d9 001 c 8 d9 1f9 d 8 d9 1f1 e 8 d9 1e9 f 8 d9 1e1 0 9 d9 1d9 1 9 d9 1d2 2 9 d9 1cb 3 9 d9 1c4 4 9 d9 1bd 5 9 d9 1b6 6 9 d9 1af 7 9 d9 1a8 8 9 d9 011 9 9 d9 00a a 9 d9 003 b 9 d9 1fc c 9 d9 1f5 d 9 d9 1ee e 9 d9 1e7 f 9 d9 1e0 0 a d9 1d9 1 a d9 1d3 2 a d9 1cd 3 a d9 1c7 4 a d9 1c1 5 a d9 1bb 6 a d9 1b5 7 a d9 1af 8 a d9 009 9 a d9 003 a a d9 1fd b a d9 1f7 c a d9 1f1 d a d9 1eb e a d9 1e5 f a d9 1df 0 b d9 1d9 1 b d9 1d4 2 b d9 1cf 3 b d9 1ca 4 b d9 1c5 5 b d9 1c0 6 b d9 1bb 7 b d9 1b6 8 b d9 001 9 b d9 1fc a b d9 1f7 b b d9 1f2 c b d9 1ed d b d9 1e8 e b d9 1e3 f b d9 1de 0 c d9 1d9 1 c d9 1d5 2 c d9 1d1 3 c d9 1cd 4 c d9 1c9 5 c d9 1c5 6 c d9 1c1 7 c d9 1bd 8 c d9 1f9 9 c d9 1f5 a c d9 1f1 b c d9 1ed c c d9 1e9 d c d9 1e5 e c d9 1e1 f c d9 1dd 0 d d9 1d9 1 d d9 1d6 2 d d9 1d3 3 d d9 1d0 4 d d9 1cd 5 d d9 1ca 6 d d9 1c7 7 d d9 1c4 8 d d9 1f1 9 d d9 1ee a d d9 1eb b d d9 1e8 c d d9 1e5 d d d9 1e2 e d d9 1df f d d9 1dc 0 e d9 1d9 1 e d9 1d7 2 e d9 1d5 3 e d9 1d3 4 e d9 1d1 5 e d9 1cf 6 e d9 1cd 7 e d9 1cb 8 e d9 1e9 9 e d9 1e7 a e d9 1e5 b e d9 1e3 c e d9 1e1 d e d9 1df e e d9 1dd f e d9 1db 0 f d9 1d9 1 f d9 1d8 2 f d9 1d7 3 f d9 1d6 4 f d9 1d5 5 f d9 1d4 6 f d9 1d3 7 f d9 1d2 8 f d9 1e1 9 f d9 1e0 a f d9 1df b f d9 1de c f d9 1dd d f d9 1dc e f d9 1db f f d9 1da 0 0 da 1da 1 0 da 1da 2 0 da 1da 3 0 da 1da 4 0 da 1da 5 0 da 1da 6 0 da 1da 7 0 da 1da 8 0 da 1da 9 0 da 1da a 0 da 1da b 0 da 1da c 0 da 1da d 0 da 1da e 0 da 1da f 0 da 1da 0 1 da 1da 1 1 da 1db 2 1 da 1dc 3 1 da 1dd 4 1 da 1de 5 1 da 1df 6 1 da 1e0 7 1 da 1e1 8 1 da 1d2 9 1 da 1d3 a 1 da 1d4 b 1 da 1d5 c 1 da 1d6 d 1 da 1d7 e 1 da 1d8 f 1 da 1d9 0 2 da 1da 1 2 da 1dc 2 2 da 1de 3 2 da 1e0 4 2 da 1e2 5 2 da 1e4 6 2 da 1e6 7 2 da 1e8 8 2 da 1ca 9 2 da 1cc a 2 da 1ce b 2 da 1d0 c 2 da 1d2 d 2 da 1d4 e 2 da 1d6 f 2 da 1d8 0 3 da 1da 1 3 da 1dd 2 3 da 1e0 3 3 da 1e3 4 3 da 1e6 5 3 da 1e9 6 3 da 1ec 7 3 da 1ef 8 3 da 1c2 9 3 da 1c5 a 3 da 1c8 b 3 da 1cb c 3 da 1ce d 3 da 1d1 e 3 da 1d4 f 3 da 1d7 0 4 da 1da 1 4 da 1de 2 4 da 1e2 3 4 da 1e6 4 4 da 1ea 5 4 da 1ee 6 4 da 1f2 7 4 da 1f6 8 4 da 1ba 9 4 da 1be a 4 da 1c2 b 4 da 1c6 c 4 da 1ca d 4 da 1ce e 4 da 1d2 f 4 da 1d6 0 5 da 1da 1 5 da 1df 2 5 da 1e4 3 5 da 1e9 4 5 da 1ee 5 5 da 1f3 6 5 da 1f8 7 5 da 1fd 8 5 da 1b2 9 5 da 1b7 a 5 da 1bc b 5 da 1c1 c 5 da 1c6 d 5 da 1cb e 5 da 1d0 f 5 da 1d5 0 6 da 1da 1 6 da 1e0 2 6 da 1e6 3 6 da 1ec 4 6 da 1f2 5 6 da 1f8 6 6 da 1fe 7 6 da 004 8 6 da 1aa 9 6 da 1b0 a 6 da 1b6 b 6 da 1bc c 6 da 1c2 d 6 da 1c8 e 6 da 1ce f 6 da 1d4 0 7 da 1da 1 7 da 1e1 2 7 da 1e8 3 7 da 1ef 4 7 da 1f6 5 7 da 1fd 6 7 da 004 7 7 da 00b 8 7 da 1a2 9 7 da 1a9 a 7 da 1b0 b 7 da 1b7 c 7 da 1be d 7 da 1c5 e 7 da 1cc f 7 da 1d3 0 8 da 1da 1 8 da 1d2 2 8 da 1ca 3 8 da 1c2 4 8 da 1ba 5 8 da 1b2 6 8 da 1aa 7 8 da 1a2 8 8 da 01a 9 8 da 012 a 8 da 00a b 8 da 002 c 8 da 1fa d 8 da 1f2 e 8 da 1ea f 8 da 1e2 0 9 da 1da 1 9 da 1d3 2 9 da 1cc 3 9 da 1c5 4 9 da 1be 5 9 da 1b7 6 9 da 1b0 7 9 da 1a9 8 9 da 012 9 9 da 00b a 9 da 004 b 9 da 1fd c 9 da 1f6 d 9 da 1ef e 9 da 1e8 f 9 da 1e1 0 a da 1da 1 a da 1d4 2 a da 1ce 3 a da 1c8 4 a da 1c2 5 a da 1bc 6 a da 1b6 7 a da 1b0 8 a da 00a 9 a da 004 a a da 1fe b a da 1f8 c a da 1f2 d a da 1ec e a da 1e6 f a da 1e0 0 b da 1da 1 b da 1d5 2 b da 1d0 3 b da 1cb 4 b da 1c6 5 b da 1c1 6 b da 1bc 7 b da 1b7 8 b da 002 9 b da 1fd a b da 1f8 b b da 1f3 c b da 1ee d b da 1e9 e b da 1e4 f b da 1df 0 c da 1da 1 c da 1d6 2 c da 1d2 3 c da 1ce 4 c da 1ca 5 c da 1c6 6 c da 1c2 7 c da 1be 8 c da 1fa 9 c da 1f6 a c da 1f2 b c da 1ee c c da 1ea d c da 1e6 e c da 1e2 f c da 1de 0 d da 1da 1 d da 1d7 2 d da 1d4 3 d da 1d1 4 d da 1ce 5 d da 1cb 6 d da 1c8 7 d da 1c5 8 d da 1f2 9 d da 1ef a d da 1ec b d da 1e9 c d da 1e6 d d da 1e3 e d da 1e0 f d da 1dd 0 e da 1da 1 e da 1d8 2 e da 1d6 3 e da 1d4 4 e da 1d2 5 e da 1d0 6 e da 1ce 7 e da 1cc 8 e da 1ea 9 e da 1e8 a e da 1e6 b e da 1e4 c e da 1e2 d e da 1e0 e e da 1de f e da 1dc 0 f da 1da 1 f da 1d9 2 f da 1d8 3 f da 1d7 4 f da 1d6 5 f da 1d5 6 f da 1d4 7 f da 1d3 8 f da 1e2 9 f da 1e1 a f da 1e0 b f da 1df c f da 1de d f da 1dd e f da 1dc f f da 1db 0 0 db 1db 1 0 db 1db 2 0 db 1db 3 0 db 1db 4 0 db 1db 5 0 db 1db 6 0 db 1db 7 0 db 1db 8 0 db 1db 9 0 db 1db a 0 db 1db b 0 db 1db c 0 db 1db d 0 db 1db e 0 db 1db f 0 db 1db 0 1 db 1db 1 1 db 1dc 2 1 db 1dd 3 1 db 1de 4 1 db 1df 5 1 db 1e0 6 1 db 1e1 7 1 db 1e2 8 1 db 1d3 9 1 db 1d4 a 1 db 1d5 b 1 db 1d6 c 1 db 1d7 d 1 db 1d8 e 1 db 1d9 f 1 db 1da 0 2 db 1db 1 2 db 1dd 2 2 db 1df 3 2 db 1e1 4 2 db 1e3 5 2 db 1e5 6 2 db 1e7 7 2 db 1e9 8 2 db 1cb 9 2 db 1cd a 2 db 1cf b 2 db 1d1 c 2 db 1d3 d 2 db 1d5 e 2 db 1d7 f 2 db 1d9 0 3 db 1db 1 3 db 1de 2 3 db 1e1 3 3 db 1e4 4 3 db 1e7 5 3 db 1ea 6 3 db 1ed 7 3 db 1f0 8 3 db 1c3 9 3 db 1c6 a 3 db 1c9 b 3 db 1cc c 3 db 1cf d 3 db 1d2 e 3 db 1d5 f 3 db 1d8 0 4 db 1db 1 4 db 1df 2 4 db 1e3 3 4 db 1e7 4 4 db 1eb 5 4 db 1ef 6 4 db 1f3 7 4 db 1f7 8 4 db 1bb 9 4 db 1bf a 4 db 1c3 b 4 db 1c7 c 4 db 1cb d 4 db 1cf e 4 db 1d3 f 4 db 1d7 0 5 db 1db 1 5 db 1e0 2 5 db 1e5 3 5 db 1ea 4 5 db 1ef 5 5 db 1f4 6 5 db 1f9 7 5 db 1fe 8 5 db 1b3 9 5 db 1b8 a 5 db 1bd b 5 db 1c2 c 5 db 1c7 d 5 db 1cc e 5 db 1d1 f 5 db 1d6 0 6 db 1db 1 6 db 1e1 2 6 db 1e7 3 6 db 1ed 4 6 db 1f3 5 6 db 1f9 6 6 db 1ff 7 6 db 005 8 6 db 1ab 9 6 db 1b1 a 6 db 1b7 b 6 db 1bd c 6 db 1c3 d 6 db 1c9 e 6 db 1cf f 6 db 1d5 0 7 db 1db 1 7 db 1e2 2 7 db 1e9 3 7 db 1f0 4 7 db 1f7 5 7 db 1fe 6 7 db 005 7 7 db 00c 8 7 db 1a3 9 7 db 1aa a 7 db 1b1 b 7 db 1b8 c 7 db 1bf d 7 db 1c6 e 7 db 1cd f 7 db 1d4 0 8 db 1db 1 8 db 1d3 2 8 db 1cb 3 8 db 1c3 4 8 db 1bb 5 8 db 1b3 6 8 db 1ab 7 8 db 1a3 8 8 db 01b 9 8 db 013 a 8 db 00b b 8 db 003 c 8 db 1fb d 8 db 1f3 e 8 db 1eb f 8 db 1e3 0 9 db 1db 1 9 db 1d4 2 9 db 1cd 3 9 db 1c6 4 9 db 1bf 5 9 db 1b8 6 9 db 1b1 7 9 db 1aa 8 9 db 013 9 9 db 00c a 9 db 005 b 9 db 1fe c 9 db 1f7 d 9 db 1f0 e 9 db 1e9 f 9 db 1e2 0 a db 1db 1 a db 1d5 2 a db 1cf 3 a db 1c9 4 a db 1c3 5 a db 1bd 6 a db 1b7 7 a db 1b1 8 a db 00b 9 a db 005 a a db 1ff b a db 1f9 c a db 1f3 d a db 1ed e a db 1e7 f a db 1e1 0 b db 1db 1 b db 1d6 2 b db 1d1 3 b db 1cc 4 b db 1c7 5 b db 1c2 6 b db 1bd 7 b db 1b8 8 b db 003 9 b db 1fe a b db 1f9 b b db 1f4 c b db 1ef d b db 1ea e b db 1e5 f b db 1e0 0 c db 1db 1 c db 1d7 2 c db 1d3 3 c db 1cf 4 c db 1cb 5 c db 1c7 6 c db 1c3 7 c db 1bf 8 c db 1fb 9 c db 1f7 a c db 1f3 b c db 1ef c c db 1eb d c db 1e7 e c db 1e3 f c db 1df 0 d db 1db 1 d db 1d8 2 d db 1d5 3 d db 1d2 4 d db 1cf 5 d db 1cc 6 d db 1c9 7 d db 1c6 8 d db 1f3 9 d db 1f0 a d db 1ed b d db 1ea c d db 1e7 d d db 1e4 e d db 1e1 f d db 1de 0 e db 1db 1 e db 1d9 2 e db 1d7 3 e db 1d5 4 e db 1d3 5 e db 1d1 6 e db 1cf 7 e db 1cd 8 e db 1eb 9 e db 1e9 a e db 1e7 b e db 1e5 c e db 1e3 d e db 1e1 e e db 1df f e db 1dd 0 f db 1db 1 f db 1da 2 f db 1d9 3 f db 1d8 4 f db 1d7 5 f db 1d6 6 f db 1d5 7 f db 1d4 8 f db 1e3 9 f db 1e2 a f db 1e1 b f db 1e0 c f db 1df d f db 1de e f db 1dd f f db 1dc 0 0 dc 1dc 1 0 dc 1dc 2 0 dc 1dc 3 0 dc 1dc 4 0 dc 1dc 5 0 dc 1dc 6 0 dc 1dc 7 0 dc 1dc 8 0 dc 1dc 9 0 dc 1dc a 0 dc 1dc b 0 dc 1dc c 0 dc 1dc d 0 dc 1dc e 0 dc 1dc f 0 dc 1dc 0 1 dc 1dc 1 1 dc 1dd 2 1 dc 1de 3 1 dc 1df 4 1 dc 1e0 5 1 dc 1e1 6 1 dc 1e2 7 1 dc 1e3 8 1 dc 1d4 9 1 dc 1d5 a 1 dc 1d6 b 1 dc 1d7 c 1 dc 1d8 d 1 dc 1d9 e 1 dc 1da f 1 dc 1db 0 2 dc 1dc 1 2 dc 1de 2 2 dc 1e0 3 2 dc 1e2 4 2 dc 1e4 5 2 dc 1e6 6 2 dc 1e8 7 2 dc 1ea 8 2 dc 1cc 9 2 dc 1ce a 2 dc 1d0 b 2 dc 1d2 c 2 dc 1d4 d 2 dc 1d6 e 2 dc 1d8 f 2 dc 1da 0 3 dc 1dc 1 3 dc 1df 2 3 dc 1e2 3 3 dc 1e5 4 3 dc 1e8 5 3 dc 1eb 6 3 dc 1ee 7 3 dc 1f1 8 3 dc 1c4 9 3 dc 1c7 a 3 dc 1ca b 3 dc 1cd c 3 dc 1d0 d 3 dc 1d3 e 3 dc 1d6 f 3 dc 1d9 0 4 dc 1dc 1 4 dc 1e0 2 4 dc 1e4 3 4 dc 1e8 4 4 dc 1ec 5 4 dc 1f0 6 4 dc 1f4 7 4 dc 1f8 8 4 dc 1bc 9 4 dc 1c0 a 4 dc 1c4 b 4 dc 1c8 c 4 dc 1cc d 4 dc 1d0 e 4 dc 1d4 f 4 dc 1d8 0 5 dc 1dc 1 5 dc 1e1 2 5 dc 1e6 3 5 dc 1eb 4 5 dc 1f0 5 5 dc 1f5 6 5 dc 1fa 7 5 dc 1ff 8 5 dc 1b4 9 5 dc 1b9 a 5 dc 1be b 5 dc 1c3 c 5 dc 1c8 d 5 dc 1cd e 5 dc 1d2 f 5 dc 1d7 0 6 dc 1dc 1 6 dc 1e2 2 6 dc 1e8 3 6 dc 1ee 4 6 dc 1f4 5 6 dc 1fa 6 6 dc 000 7 6 dc 006 8 6 dc 1ac 9 6 dc 1b2 a 6 dc 1b8 b 6 dc 1be c 6 dc 1c4 d 6 dc 1ca e 6 dc 1d0 f 6 dc 1d6 0 7 dc 1dc 1 7 dc 1e3 2 7 dc 1ea 3 7 dc 1f1 4 7 dc 1f8 5 7 dc 1ff 6 7 dc 006 7 7 dc 00d 8 7 dc 1a4 9 7 dc 1ab a 7 dc 1b2 b 7 dc 1b9 c 7 dc 1c0 d 7 dc 1c7 e 7 dc 1ce f 7 dc 1d5 0 8 dc 1dc 1 8 dc 1d4 2 8 dc 1cc 3 8 dc 1c4 4 8 dc 1bc 5 8 dc 1b4 6 8 dc 1ac 7 8 dc 1a4 8 8 dc 01c 9 8 dc 014 a 8 dc 00c b 8 dc 004 c 8 dc 1fc d 8 dc 1f4 e 8 dc 1ec f 8 dc 1e4 0 9 dc 1dc 1 9 dc 1d5 2 9 dc 1ce 3 9 dc 1c7 4 9 dc 1c0 5 9 dc 1b9 6 9 dc 1b2 7 9 dc 1ab 8 9 dc 014 9 9 dc 00d a 9 dc 006 b 9 dc 1ff c 9 dc 1f8 d 9 dc 1f1 e 9 dc 1ea f 9 dc 1e3 0 a dc 1dc 1 a dc 1d6 2 a dc 1d0 3 a dc 1ca 4 a dc 1c4 5 a dc 1be 6 a dc 1b8 7 a dc 1b2 8 a dc 00c 9 a dc 006 a a dc 000 b a dc 1fa c a dc 1f4 d a dc 1ee e a dc 1e8 f a dc 1e2 0 b dc 1dc 1 b dc 1d7 2 b dc 1d2 3 b dc 1cd 4 b dc 1c8 5 b dc 1c3 6 b dc 1be 7 b dc 1b9 8 b dc 004 9 b dc 1ff a b dc 1fa b b dc 1f5 c b dc 1f0 d b dc 1eb e b dc 1e6 f b dc 1e1 0 c dc 1dc 1 c dc 1d8 2 c dc 1d4 3 c dc 1d0 4 c dc 1cc 5 c dc 1c8 6 c dc 1c4 7 c dc 1c0 8 c dc 1fc 9 c dc 1f8 a c dc 1f4 b c dc 1f0 c c dc 1ec d c dc 1e8 e c dc 1e4 f c dc 1e0 0 d dc 1dc 1 d dc 1d9 2 d dc 1d6 3 d dc 1d3 4 d dc 1d0 5 d dc 1cd 6 d dc 1ca 7 d dc 1c7 8 d dc 1f4 9 d dc 1f1 a d dc 1ee b d dc 1eb c d dc 1e8 d d dc 1e5 e d dc 1e2 f d dc 1df 0 e dc 1dc 1 e dc 1da 2 e dc 1d8 3 e dc 1d6 4 e dc 1d4 5 e dc 1d2 6 e dc 1d0 7 e dc 1ce 8 e dc 1ec 9 e dc 1ea a e dc 1e8 b e dc 1e6 c e dc 1e4 d e dc 1e2 e e dc 1e0 f e dc 1de 0 f dc 1dc 1 f dc 1db 2 f dc 1da 3 f dc 1d9 4 f dc 1d8 5 f dc 1d7 6 f dc 1d6 7 f dc 1d5 8 f dc 1e4 9 f dc 1e3 a f dc 1e2 b f dc 1e1 c f dc 1e0 d f dc 1df e f dc 1de f f dc 1dd 0 0 dd 1dd 1 0 dd 1dd 2 0 dd 1dd 3 0 dd 1dd 4 0 dd 1dd 5 0 dd 1dd 6 0 dd 1dd 7 0 dd 1dd 8 0 dd 1dd 9 0 dd 1dd a 0 dd 1dd b 0 dd 1dd c 0 dd 1dd d 0 dd 1dd e 0 dd 1dd f 0 dd 1dd 0 1 dd 1dd 1 1 dd 1de 2 1 dd 1df 3 1 dd 1e0 4 1 dd 1e1 5 1 dd 1e2 6 1 dd 1e3 7 1 dd 1e4 8 1 dd 1d5 9 1 dd 1d6 a 1 dd 1d7 b 1 dd 1d8 c 1 dd 1d9 d 1 dd 1da e 1 dd 1db f 1 dd 1dc 0 2 dd 1dd 1 2 dd 1df 2 2 dd 1e1 3 2 dd 1e3 4 2 dd 1e5 5 2 dd 1e7 6 2 dd 1e9 7 2 dd 1eb 8 2 dd 1cd 9 2 dd 1cf a 2 dd 1d1 b 2 dd 1d3 c 2 dd 1d5 d 2 dd 1d7 e 2 dd 1d9 f 2 dd 1db 0 3 dd 1dd 1 3 dd 1e0 2 3 dd 1e3 3 3 dd 1e6 4 3 dd 1e9 5 3 dd 1ec 6 3 dd 1ef 7 3 dd 1f2 8 3 dd 1c5 9 3 dd 1c8 a 3 dd 1cb b 3 dd 1ce c 3 dd 1d1 d 3 dd 1d4 e 3 dd 1d7 f 3 dd 1da 0 4 dd 1dd 1 4 dd 1e1 2 4 dd 1e5 3 4 dd 1e9 4 4 dd 1ed 5 4 dd 1f1 6 4 dd 1f5 7 4 dd 1f9 8 4 dd 1bd 9 4 dd 1c1 a 4 dd 1c5 b 4 dd 1c9 c 4 dd 1cd d 4 dd 1d1 e 4 dd 1d5 f 4 dd 1d9 0 5 dd 1dd 1 5 dd 1e2 2 5 dd 1e7 3 5 dd 1ec 4 5 dd 1f1 5 5 dd 1f6 6 5 dd 1fb 7 5 dd 000 8 5 dd 1b5 9 5 dd 1ba a 5 dd 1bf b 5 dd 1c4 c 5 dd 1c9 d 5 dd 1ce e 5 dd 1d3 f 5 dd 1d8 0 6 dd 1dd 1 6 dd 1e3 2 6 dd 1e9 3 6 dd 1ef 4 6 dd 1f5 5 6 dd 1fb 6 6 dd 001 7 6 dd 007 8 6 dd 1ad 9 6 dd 1b3 a 6 dd 1b9 b 6 dd 1bf c 6 dd 1c5 d 6 dd 1cb e 6 dd 1d1 f 6 dd 1d7 0 7 dd 1dd 1 7 dd 1e4 2 7 dd 1eb 3 7 dd 1f2 4 7 dd 1f9 5 7 dd 000 6 7 dd 007 7 7 dd 00e 8 7 dd 1a5 9 7 dd 1ac a 7 dd 1b3 b 7 dd 1ba c 7 dd 1c1 d 7 dd 1c8 e 7 dd 1cf f 7 dd 1d6 0 8 dd 1dd 1 8 dd 1d5 2 8 dd 1cd 3 8 dd 1c5 4 8 dd 1bd 5 8 dd 1b5 6 8 dd 1ad 7 8 dd 1a5 8 8 dd 01d 9 8 dd 015 a 8 dd 00d b 8 dd 005 c 8 dd 1fd d 8 dd 1f5 e 8 dd 1ed f 8 dd 1e5 0 9 dd 1dd 1 9 dd 1d6 2 9 dd 1cf 3 9 dd 1c8 4 9 dd 1c1 5 9 dd 1ba 6 9 dd 1b3 7 9 dd 1ac 8 9 dd 015 9 9 dd 00e a 9 dd 007 b 9 dd 000 c 9 dd 1f9 d 9 dd 1f2 e 9 dd 1eb f 9 dd 1e4 0 a dd 1dd 1 a dd 1d7 2 a dd 1d1 3 a dd 1cb 4 a dd 1c5 5 a dd 1bf 6 a dd 1b9 7 a dd 1b3 8 a dd 00d 9 a dd 007 a a dd 001 b a dd 1fb c a dd 1f5 d a dd 1ef e a dd 1e9 f a dd 1e3 0 b dd 1dd 1 b dd 1d8 2 b dd 1d3 3 b dd 1ce 4 b dd 1c9 5 b dd 1c4 6 b dd 1bf 7 b dd 1ba 8 b dd 005 9 b dd 000 a b dd 1fb b b dd 1f6 c b dd 1f1 d b dd 1ec e b dd 1e7 f b dd 1e2 0 c dd 1dd 1 c dd 1d9 2 c dd 1d5 3 c dd 1d1 4 c dd 1cd 5 c dd 1c9 6 c dd 1c5 7 c dd 1c1 8 c dd 1fd 9 c dd 1f9 a c dd 1f5 b c dd 1f1 c c dd 1ed d c dd 1e9 e c dd 1e5 f c dd 1e1 0 d dd 1dd 1 d dd 1da 2 d dd 1d7 3 d dd 1d4 4 d dd 1d1 5 d dd 1ce 6 d dd 1cb 7 d dd 1c8 8 d dd 1f5 9 d dd 1f2 a d dd 1ef b d dd 1ec c d dd 1e9 d d dd 1e6 e d dd 1e3 f d dd 1e0 0 e dd 1dd 1 e dd 1db 2 e dd 1d9 3 e dd 1d7 4 e dd 1d5 5 e dd 1d3 6 e dd 1d1 7 e dd 1cf 8 e dd 1ed 9 e dd 1eb a e dd 1e9 b e dd 1e7 c e dd 1e5 d e dd 1e3 e e dd 1e1 f e dd 1df 0 f dd 1dd 1 f dd 1dc 2 f dd 1db 3 f dd 1da 4 f dd 1d9 5 f dd 1d8 6 f dd 1d7 7 f dd 1d6 8 f dd 1e5 9 f dd 1e4 a f dd 1e3 b f dd 1e2 c f dd 1e1 d f dd 1e0 e f dd 1df f f dd 1de 0 0 de 1de 1 0 de 1de 2 0 de 1de 3 0 de 1de 4 0 de 1de 5 0 de 1de 6 0 de 1de 7 0 de 1de 8 0 de 1de 9 0 de 1de a 0 de 1de b 0 de 1de c 0 de 1de d 0 de 1de e 0 de 1de f 0 de 1de 0 1 de 1de 1 1 de 1df 2 1 de 1e0 3 1 de 1e1 4 1 de 1e2 5 1 de 1e3 6 1 de 1e4 7 1 de 1e5 8 1 de 1d6 9 1 de 1d7 a 1 de 1d8 b 1 de 1d9 c 1 de 1da d 1 de 1db e 1 de 1dc f 1 de 1dd 0 2 de 1de 1 2 de 1e0 2 2 de 1e2 3 2 de 1e4 4 2 de 1e6 5 2 de 1e8 6 2 de 1ea 7 2 de 1ec 8 2 de 1ce 9 2 de 1d0 a 2 de 1d2 b 2 de 1d4 c 2 de 1d6 d 2 de 1d8 e 2 de 1da f 2 de 1dc 0 3 de 1de 1 3 de 1e1 2 3 de 1e4 3 3 de 1e7 4 3 de 1ea 5 3 de 1ed 6 3 de 1f0 7 3 de 1f3 8 3 de 1c6 9 3 de 1c9 a 3 de 1cc b 3 de 1cf c 3 de 1d2 d 3 de 1d5 e 3 de 1d8 f 3 de 1db 0 4 de 1de 1 4 de 1e2 2 4 de 1e6 3 4 de 1ea 4 4 de 1ee 5 4 de 1f2 6 4 de 1f6 7 4 de 1fa 8 4 de 1be 9 4 de 1c2 a 4 de 1c6 b 4 de 1ca c 4 de 1ce d 4 de 1d2 e 4 de 1d6 f 4 de 1da 0 5 de 1de 1 5 de 1e3 2 5 de 1e8 3 5 de 1ed 4 5 de 1f2 5 5 de 1f7 6 5 de 1fc 7 5 de 001 8 5 de 1b6 9 5 de 1bb a 5 de 1c0 b 5 de 1c5 c 5 de 1ca d 5 de 1cf e 5 de 1d4 f 5 de 1d9 0 6 de 1de 1 6 de 1e4 2 6 de 1ea 3 6 de 1f0 4 6 de 1f6 5 6 de 1fc 6 6 de 002 7 6 de 008 8 6 de 1ae 9 6 de 1b4 a 6 de 1ba b 6 de 1c0 c 6 de 1c6 d 6 de 1cc e 6 de 1d2 f 6 de 1d8 0 7 de 1de 1 7 de 1e5 2 7 de 1ec 3 7 de 1f3 4 7 de 1fa 5 7 de 001 6 7 de 008 7 7 de 00f 8 7 de 1a6 9 7 de 1ad a 7 de 1b4 b 7 de 1bb c 7 de 1c2 d 7 de 1c9 e 7 de 1d0 f 7 de 1d7 0 8 de 1de 1 8 de 1d6 2 8 de 1ce 3 8 de 1c6 4 8 de 1be 5 8 de 1b6 6 8 de 1ae 7 8 de 1a6 8 8 de 01e 9 8 de 016 a 8 de 00e b 8 de 006 c 8 de 1fe d 8 de 1f6 e 8 de 1ee f 8 de 1e6 0 9 de 1de 1 9 de 1d7 2 9 de 1d0 3 9 de 1c9 4 9 de 1c2 5 9 de 1bb 6 9 de 1b4 7 9 de 1ad 8 9 de 016 9 9 de 00f a 9 de 008 b 9 de 001 c 9 de 1fa d 9 de 1f3 e 9 de 1ec f 9 de 1e5 0 a de 1de 1 a de 1d8 2 a de 1d2 3 a de 1cc 4 a de 1c6 5 a de 1c0 6 a de 1ba 7 a de 1b4 8 a de 00e 9 a de 008 a a de 002 b a de 1fc c a de 1f6 d a de 1f0 e a de 1ea f a de 1e4 0 b de 1de 1 b de 1d9 2 b de 1d4 3 b de 1cf 4 b de 1ca 5 b de 1c5 6 b de 1c0 7 b de 1bb 8 b de 006 9 b de 001 a b de 1fc b b de 1f7 c b de 1f2 d b de 1ed e b de 1e8 f b de 1e3 0 c de 1de 1 c de 1da 2 c de 1d6 3 c de 1d2 4 c de 1ce 5 c de 1ca 6 c de 1c6 7 c de 1c2 8 c de 1fe 9 c de 1fa a c de 1f6 b c de 1f2 c c de 1ee d c de 1ea e c de 1e6 f c de 1e2 0 d de 1de 1 d de 1db 2 d de 1d8 3 d de 1d5 4 d de 1d2 5 d de 1cf 6 d de 1cc 7 d de 1c9 8 d de 1f6 9 d de 1f3 a d de 1f0 b d de 1ed c d de 1ea d d de 1e7 e d de 1e4 f d de 1e1 0 e de 1de 1 e de 1dc 2 e de 1da 3 e de 1d8 4 e de 1d6 5 e de 1d4 6 e de 1d2 7 e de 1d0 8 e de 1ee 9 e de 1ec a e de 1ea b e de 1e8 c e de 1e6 d e de 1e4 e e de 1e2 f e de 1e0 0 f de 1de 1 f de 1dd 2 f de 1dc 3 f de 1db 4 f de 1da 5 f de 1d9 6 f de 1d8 7 f de 1d7 8 f de 1e6 9 f de 1e5 a f de 1e4 b f de 1e3 c f de 1e2 d f de 1e1 e f de 1e0 f f de 1df 0 0 df 1df 1 0 df 1df 2 0 df 1df 3 0 df 1df 4 0 df 1df 5 0 df 1df 6 0 df 1df 7 0 df 1df 8 0 df 1df 9 0 df 1df a 0 df 1df b 0 df 1df c 0 df 1df d 0 df 1df e 0 df 1df f 0 df 1df 0 1 df 1df 1 1 df 1e0 2 1 df 1e1 3 1 df 1e2 4 1 df 1e3 5 1 df 1e4 6 1 df 1e5 7 1 df 1e6 8 1 df 1d7 9 1 df 1d8 a 1 df 1d9 b 1 df 1da c 1 df 1db d 1 df 1dc e 1 df 1dd f 1 df 1de 0 2 df 1df 1 2 df 1e1 2 2 df 1e3 3 2 df 1e5 4 2 df 1e7 5 2 df 1e9 6 2 df 1eb 7 2 df 1ed 8 2 df 1cf 9 2 df 1d1 a 2 df 1d3 b 2 df 1d5 c 2 df 1d7 d 2 df 1d9 e 2 df 1db f 2 df 1dd 0 3 df 1df 1 3 df 1e2 2 3 df 1e5 3 3 df 1e8 4 3 df 1eb 5 3 df 1ee 6 3 df 1f1 7 3 df 1f4 8 3 df 1c7 9 3 df 1ca a 3 df 1cd b 3 df 1d0 c 3 df 1d3 d 3 df 1d6 e 3 df 1d9 f 3 df 1dc 0 4 df 1df 1 4 df 1e3 2 4 df 1e7 3 4 df 1eb 4 4 df 1ef 5 4 df 1f3 6 4 df 1f7 7 4 df 1fb 8 4 df 1bf 9 4 df 1c3 a 4 df 1c7 b 4 df 1cb c 4 df 1cf d 4 df 1d3 e 4 df 1d7 f 4 df 1db 0 5 df 1df 1 5 df 1e4 2 5 df 1e9 3 5 df 1ee 4 5 df 1f3 5 5 df 1f8 6 5 df 1fd 7 5 df 002 8 5 df 1b7 9 5 df 1bc a 5 df 1c1 b 5 df 1c6 c 5 df 1cb d 5 df 1d0 e 5 df 1d5 f 5 df 1da 0 6 df 1df 1 6 df 1e5 2 6 df 1eb 3 6 df 1f1 4 6 df 1f7 5 6 df 1fd 6 6 df 003 7 6 df 009 8 6 df 1af 9 6 df 1b5 a 6 df 1bb b 6 df 1c1 c 6 df 1c7 d 6 df 1cd e 6 df 1d3 f 6 df 1d9 0 7 df 1df 1 7 df 1e6 2 7 df 1ed 3 7 df 1f4 4 7 df 1fb 5 7 df 002 6 7 df 009 7 7 df 010 8 7 df 1a7 9 7 df 1ae a 7 df 1b5 b 7 df 1bc c 7 df 1c3 d 7 df 1ca e 7 df 1d1 f 7 df 1d8 0 8 df 1df 1 8 df 1d7 2 8 df 1cf 3 8 df 1c7 4 8 df 1bf 5 8 df 1b7 6 8 df 1af 7 8 df 1a7 8 8 df 01f 9 8 df 017 a 8 df 00f b 8 df 007 c 8 df 1ff d 8 df 1f7 e 8 df 1ef f 8 df 1e7 0 9 df 1df 1 9 df 1d8 2 9 df 1d1 3 9 df 1ca 4 9 df 1c3 5 9 df 1bc 6 9 df 1b5 7 9 df 1ae 8 9 df 017 9 9 df 010 a 9 df 009 b 9 df 002 c 9 df 1fb d 9 df 1f4 e 9 df 1ed f 9 df 1e6 0 a df 1df 1 a df 1d9 2 a df 1d3 3 a df 1cd 4 a df 1c7 5 a df 1c1 6 a df 1bb 7 a df 1b5 8 a df 00f 9 a df 009 a a df 003 b a df 1fd c a df 1f7 d a df 1f1 e a df 1eb f a df 1e5 0 b df 1df 1 b df 1da 2 b df 1d5 3 b df 1d0 4 b df 1cb 5 b df 1c6 6 b df 1c1 7 b df 1bc 8 b df 007 9 b df 002 a b df 1fd b b df 1f8 c b df 1f3 d b df 1ee e b df 1e9 f b df 1e4 0 c df 1df 1 c df 1db 2 c df 1d7 3 c df 1d3 4 c df 1cf 5 c df 1cb 6 c df 1c7 7 c df 1c3 8 c df 1ff 9 c df 1fb a c df 1f7 b c df 1f3 c c df 1ef d c df 1eb e c df 1e7 f c df 1e3 0 d df 1df 1 d df 1dc 2 d df 1d9 3 d df 1d6 4 d df 1d3 5 d df 1d0 6 d df 1cd 7 d df 1ca 8 d df 1f7 9 d df 1f4 a d df 1f1 b d df 1ee c d df 1eb d d df 1e8 e d df 1e5 f d df 1e2 0 e df 1df 1 e df 1dd 2 e df 1db 3 e df 1d9 4 e df 1d7 5 e df 1d5 6 e df 1d3 7 e df 1d1 8 e df 1ef 9 e df 1ed a e df 1eb b e df 1e9 c e df 1e7 d e df 1e5 e e df 1e3 f e df 1e1 0 f df 1df 1 f df 1de 2 f df 1dd 3 f df 1dc 4 f df 1db 5 f df 1da 6 f df 1d9 7 f df 1d8 8 f df 1e7 9 f df 1e6 a f df 1e5 b f df 1e4 c f df 1e3 d f df 1e2 e f df 1e1 f f df 1e0 0 0 e0 1e0 1 0 e0 1e0 2 0 e0 1e0 3 0 e0 1e0 4 0 e0 1e0 5 0 e0 1e0 6 0 e0 1e0 7 0 e0 1e0 8 0 e0 1e0 9 0 e0 1e0 a 0 e0 1e0 b 0 e0 1e0 c 0 e0 1e0 d 0 e0 1e0 e 0 e0 1e0 f 0 e0 1e0 0 1 e0 1e0 1 1 e0 1e1 2 1 e0 1e2 3 1 e0 1e3 4 1 e0 1e4 5 1 e0 1e5 6 1 e0 1e6 7 1 e0 1e7 8 1 e0 1d8 9 1 e0 1d9 a 1 e0 1da b 1 e0 1db c 1 e0 1dc d 1 e0 1dd e 1 e0 1de f 1 e0 1df 0 2 e0 1e0 1 2 e0 1e2 2 2 e0 1e4 3 2 e0 1e6 4 2 e0 1e8 5 2 e0 1ea 6 2 e0 1ec 7 2 e0 1ee 8 2 e0 1d0 9 2 e0 1d2 a 2 e0 1d4 b 2 e0 1d6 c 2 e0 1d8 d 2 e0 1da e 2 e0 1dc f 2 e0 1de 0 3 e0 1e0 1 3 e0 1e3 2 3 e0 1e6 3 3 e0 1e9 4 3 e0 1ec 5 3 e0 1ef 6 3 e0 1f2 7 3 e0 1f5 8 3 e0 1c8 9 3 e0 1cb a 3 e0 1ce b 3 e0 1d1 c 3 e0 1d4 d 3 e0 1d7 e 3 e0 1da f 3 e0 1dd 0 4 e0 1e0 1 4 e0 1e4 2 4 e0 1e8 3 4 e0 1ec 4 4 e0 1f0 5 4 e0 1f4 6 4 e0 1f8 7 4 e0 1fc 8 4 e0 1c0 9 4 e0 1c4 a 4 e0 1c8 b 4 e0 1cc c 4 e0 1d0 d 4 e0 1d4 e 4 e0 1d8 f 4 e0 1dc 0 5 e0 1e0 1 5 e0 1e5 2 5 e0 1ea 3 5 e0 1ef 4 5 e0 1f4 5 5 e0 1f9 6 5 e0 1fe 7 5 e0 003 8 5 e0 1b8 9 5 e0 1bd a 5 e0 1c2 b 5 e0 1c7 c 5 e0 1cc d 5 e0 1d1 e 5 e0 1d6 f 5 e0 1db 0 6 e0 1e0 1 6 e0 1e6 2 6 e0 1ec 3 6 e0 1f2 4 6 e0 1f8 5 6 e0 1fe 6 6 e0 004 7 6 e0 00a 8 6 e0 1b0 9 6 e0 1b6 a 6 e0 1bc b 6 e0 1c2 c 6 e0 1c8 d 6 e0 1ce e 6 e0 1d4 f 6 e0 1da 0 7 e0 1e0 1 7 e0 1e7 2 7 e0 1ee 3 7 e0 1f5 4 7 e0 1fc 5 7 e0 003 6 7 e0 00a 7 7 e0 011 8 7 e0 1a8 9 7 e0 1af a 7 e0 1b6 b 7 e0 1bd c 7 e0 1c4 d 7 e0 1cb e 7 e0 1d2 f 7 e0 1d9 0 8 e0 1e0 1 8 e0 1d8 2 8 e0 1d0 3 8 e0 1c8 4 8 e0 1c0 5 8 e0 1b8 6 8 e0 1b0 7 8 e0 1a8 8 8 e0 020 9 8 e0 018 a 8 e0 010 b 8 e0 008 c 8 e0 000 d 8 e0 1f8 e 8 e0 1f0 f 8 e0 1e8 0 9 e0 1e0 1 9 e0 1d9 2 9 e0 1d2 3 9 e0 1cb 4 9 e0 1c4 5 9 e0 1bd 6 9 e0 1b6 7 9 e0 1af 8 9 e0 018 9 9 e0 011 a 9 e0 00a b 9 e0 003 c 9 e0 1fc d 9 e0 1f5 e 9 e0 1ee f 9 e0 1e7 0 a e0 1e0 1 a e0 1da 2 a e0 1d4 3 a e0 1ce 4 a e0 1c8 5 a e0 1c2 6 a e0 1bc 7 a e0 1b6 8 a e0 010 9 a e0 00a a a e0 004 b a e0 1fe c a e0 1f8 d a e0 1f2 e a e0 1ec f a e0 1e6 0 b e0 1e0 1 b e0 1db 2 b e0 1d6 3 b e0 1d1 4 b e0 1cc 5 b e0 1c7 6 b e0 1c2 7 b e0 1bd 8 b e0 008 9 b e0 003 a b e0 1fe b b e0 1f9 c b e0 1f4 d b e0 1ef e b e0 1ea f b e0 1e5 0 c e0 1e0 1 c e0 1dc 2 c e0 1d8 3 c e0 1d4 4 c e0 1d0 5 c e0 1cc 6 c e0 1c8 7 c e0 1c4 8 c e0 000 9 c e0 1fc a c e0 1f8 b c e0 1f4 c c e0 1f0 d c e0 1ec e c e0 1e8 f c e0 1e4 0 d e0 1e0 1 d e0 1dd 2 d e0 1da 3 d e0 1d7 4 d e0 1d4 5 d e0 1d1 6 d e0 1ce 7 d e0 1cb 8 d e0 1f8 9 d e0 1f5 a d e0 1f2 b d e0 1ef c d e0 1ec d d e0 1e9 e d e0 1e6 f d e0 1e3 0 e e0 1e0 1 e e0 1de 2 e e0 1dc 3 e e0 1da 4 e e0 1d8 5 e e0 1d6 6 e e0 1d4 7 e e0 1d2 8 e e0 1f0 9 e e0 1ee a e e0 1ec b e e0 1ea c e e0 1e8 d e e0 1e6 e e e0 1e4 f e e0 1e2 0 f e0 1e0 1 f e0 1df 2 f e0 1de 3 f e0 1dd 4 f e0 1dc 5 f e0 1db 6 f e0 1da 7 f e0 1d9 8 f e0 1e8 9 f e0 1e7 a f e0 1e6 b f e0 1e5 c f e0 1e4 d f e0 1e3 e f e0 1e2 f f e0 1e1 0 0 e1 1e1 1 0 e1 1e1 2 0 e1 1e1 3 0 e1 1e1 4 0 e1 1e1 5 0 e1 1e1 6 0 e1 1e1 7 0 e1 1e1 8 0 e1 1e1 9 0 e1 1e1 a 0 e1 1e1 b 0 e1 1e1 c 0 e1 1e1 d 0 e1 1e1 e 0 e1 1e1 f 0 e1 1e1 0 1 e1 1e1 1 1 e1 1e2 2 1 e1 1e3 3 1 e1 1e4 4 1 e1 1e5 5 1 e1 1e6 6 1 e1 1e7 7 1 e1 1e8 8 1 e1 1d9 9 1 e1 1da a 1 e1 1db b 1 e1 1dc c 1 e1 1dd d 1 e1 1de e 1 e1 1df f 1 e1 1e0 0 2 e1 1e1 1 2 e1 1e3 2 2 e1 1e5 3 2 e1 1e7 4 2 e1 1e9 5 2 e1 1eb 6 2 e1 1ed 7 2 e1 1ef 8 2 e1 1d1 9 2 e1 1d3 a 2 e1 1d5 b 2 e1 1d7 c 2 e1 1d9 d 2 e1 1db e 2 e1 1dd f 2 e1 1df 0 3 e1 1e1 1 3 e1 1e4 2 3 e1 1e7 3 3 e1 1ea 4 3 e1 1ed 5 3 e1 1f0 6 3 e1 1f3 7 3 e1 1f6 8 3 e1 1c9 9 3 e1 1cc a 3 e1 1cf b 3 e1 1d2 c 3 e1 1d5 d 3 e1 1d8 e 3 e1 1db f 3 e1 1de 0 4 e1 1e1 1 4 e1 1e5 2 4 e1 1e9 3 4 e1 1ed 4 4 e1 1f1 5 4 e1 1f5 6 4 e1 1f9 7 4 e1 1fd 8 4 e1 1c1 9 4 e1 1c5 a 4 e1 1c9 b 4 e1 1cd c 4 e1 1d1 d 4 e1 1d5 e 4 e1 1d9 f 4 e1 1dd 0 5 e1 1e1 1 5 e1 1e6 2 5 e1 1eb 3 5 e1 1f0 4 5 e1 1f5 5 5 e1 1fa 6 5 e1 1ff 7 5 e1 004 8 5 e1 1b9 9 5 e1 1be a 5 e1 1c3 b 5 e1 1c8 c 5 e1 1cd d 5 e1 1d2 e 5 e1 1d7 f 5 e1 1dc 0 6 e1 1e1 1 6 e1 1e7 2 6 e1 1ed 3 6 e1 1f3 4 6 e1 1f9 5 6 e1 1ff 6 6 e1 005 7 6 e1 00b 8 6 e1 1b1 9 6 e1 1b7 a 6 e1 1bd b 6 e1 1c3 c 6 e1 1c9 d 6 e1 1cf e 6 e1 1d5 f 6 e1 1db 0 7 e1 1e1 1 7 e1 1e8 2 7 e1 1ef 3 7 e1 1f6 4 7 e1 1fd 5 7 e1 004 6 7 e1 00b 7 7 e1 012 8 7 e1 1a9 9 7 e1 1b0 a 7 e1 1b7 b 7 e1 1be c 7 e1 1c5 d 7 e1 1cc e 7 e1 1d3 f 7 e1 1da 0 8 e1 1e1 1 8 e1 1d9 2 8 e1 1d1 3 8 e1 1c9 4 8 e1 1c1 5 8 e1 1b9 6 8 e1 1b1 7 8 e1 1a9 8 8 e1 021 9 8 e1 019 a 8 e1 011 b 8 e1 009 c 8 e1 001 d 8 e1 1f9 e 8 e1 1f1 f 8 e1 1e9 0 9 e1 1e1 1 9 e1 1da 2 9 e1 1d3 3 9 e1 1cc 4 9 e1 1c5 5 9 e1 1be 6 9 e1 1b7 7 9 e1 1b0 8 9 e1 019 9 9 e1 012 a 9 e1 00b b 9 e1 004 c 9 e1 1fd d 9 e1 1f6 e 9 e1 1ef f 9 e1 1e8 0 a e1 1e1 1 a e1 1db 2 a e1 1d5 3 a e1 1cf 4 a e1 1c9 5 a e1 1c3 6 a e1 1bd 7 a e1 1b7 8 a e1 011 9 a e1 00b a a e1 005 b a e1 1ff c a e1 1f9 d a e1 1f3 e a e1 1ed f a e1 1e7 0 b e1 1e1 1 b e1 1dc 2 b e1 1d7 3 b e1 1d2 4 b e1 1cd 5 b e1 1c8 6 b e1 1c3 7 b e1 1be 8 b e1 009 9 b e1 004 a b e1 1ff b b e1 1fa c b e1 1f5 d b e1 1f0 e b e1 1eb f b e1 1e6 0 c e1 1e1 1 c e1 1dd 2 c e1 1d9 3 c e1 1d5 4 c e1 1d1 5 c e1 1cd 6 c e1 1c9 7 c e1 1c5 8 c e1 001 9 c e1 1fd a c e1 1f9 b c e1 1f5 c c e1 1f1 d c e1 1ed e c e1 1e9 f c e1 1e5 0 d e1 1e1 1 d e1 1de 2 d e1 1db 3 d e1 1d8 4 d e1 1d5 5 d e1 1d2 6 d e1 1cf 7 d e1 1cc 8 d e1 1f9 9 d e1 1f6 a d e1 1f3 b d e1 1f0 c d e1 1ed d d e1 1ea e d e1 1e7 f d e1 1e4 0 e e1 1e1 1 e e1 1df 2 e e1 1dd 3 e e1 1db 4 e e1 1d9 5 e e1 1d7 6 e e1 1d5 7 e e1 1d3 8 e e1 1f1 9 e e1 1ef a e e1 1ed b e e1 1eb c e e1 1e9 d e e1 1e7 e e e1 1e5 f e e1 1e3 0 f e1 1e1 1 f e1 1e0 2 f e1 1df 3 f e1 1de 4 f e1 1dd 5 f e1 1dc 6 f e1 1db 7 f e1 1da 8 f e1 1e9 9 f e1 1e8 a f e1 1e7 b f e1 1e6 c f e1 1e5 d f e1 1e4 e f e1 1e3 f f e1 1e2 0 0 e2 1e2 1 0 e2 1e2 2 0 e2 1e2 3 0 e2 1e2 4 0 e2 1e2 5 0 e2 1e2 6 0 e2 1e2 7 0 e2 1e2 8 0 e2 1e2 9 0 e2 1e2 a 0 e2 1e2 b 0 e2 1e2 c 0 e2 1e2 d 0 e2 1e2 e 0 e2 1e2 f 0 e2 1e2 0 1 e2 1e2 1 1 e2 1e3 2 1 e2 1e4 3 1 e2 1e5 4 1 e2 1e6 5 1 e2 1e7 6 1 e2 1e8 7 1 e2 1e9 8 1 e2 1da 9 1 e2 1db a 1 e2 1dc b 1 e2 1dd c 1 e2 1de d 1 e2 1df e 1 e2 1e0 f 1 e2 1e1 0 2 e2 1e2 1 2 e2 1e4 2 2 e2 1e6 3 2 e2 1e8 4 2 e2 1ea 5 2 e2 1ec 6 2 e2 1ee 7 2 e2 1f0 8 2 e2 1d2 9 2 e2 1d4 a 2 e2 1d6 b 2 e2 1d8 c 2 e2 1da d 2 e2 1dc e 2 e2 1de f 2 e2 1e0 0 3 e2 1e2 1 3 e2 1e5 2 3 e2 1e8 3 3 e2 1eb 4 3 e2 1ee 5 3 e2 1f1 6 3 e2 1f4 7 3 e2 1f7 8 3 e2 1ca 9 3 e2 1cd a 3 e2 1d0 b 3 e2 1d3 c 3 e2 1d6 d 3 e2 1d9 e 3 e2 1dc f 3 e2 1df 0 4 e2 1e2 1 4 e2 1e6 2 4 e2 1ea 3 4 e2 1ee 4 4 e2 1f2 5 4 e2 1f6 6 4 e2 1fa 7 4 e2 1fe 8 4 e2 1c2 9 4 e2 1c6 a 4 e2 1ca b 4 e2 1ce c 4 e2 1d2 d 4 e2 1d6 e 4 e2 1da f 4 e2 1de 0 5 e2 1e2 1 5 e2 1e7 2 5 e2 1ec 3 5 e2 1f1 4 5 e2 1f6 5 5 e2 1fb 6 5 e2 000 7 5 e2 005 8 5 e2 1ba 9 5 e2 1bf a 5 e2 1c4 b 5 e2 1c9 c 5 e2 1ce d 5 e2 1d3 e 5 e2 1d8 f 5 e2 1dd 0 6 e2 1e2 1 6 e2 1e8 2 6 e2 1ee 3 6 e2 1f4 4 6 e2 1fa 5 6 e2 000 6 6 e2 006 7 6 e2 00c 8 6 e2 1b2 9 6 e2 1b8 a 6 e2 1be b 6 e2 1c4 c 6 e2 1ca d 6 e2 1d0 e 6 e2 1d6 f 6 e2 1dc 0 7 e2 1e2 1 7 e2 1e9 2 7 e2 1f0 3 7 e2 1f7 4 7 e2 1fe 5 7 e2 005 6 7 e2 00c 7 7 e2 013 8 7 e2 1aa 9 7 e2 1b1 a 7 e2 1b8 b 7 e2 1bf c 7 e2 1c6 d 7 e2 1cd e 7 e2 1d4 f 7 e2 1db 0 8 e2 1e2 1 8 e2 1da 2 8 e2 1d2 3 8 e2 1ca 4 8 e2 1c2 5 8 e2 1ba 6 8 e2 1b2 7 8 e2 1aa 8 8 e2 022 9 8 e2 01a a 8 e2 012 b 8 e2 00a c 8 e2 002 d 8 e2 1fa e 8 e2 1f2 f 8 e2 1ea 0 9 e2 1e2 1 9 e2 1db 2 9 e2 1d4 3 9 e2 1cd 4 9 e2 1c6 5 9 e2 1bf 6 9 e2 1b8 7 9 e2 1b1 8 9 e2 01a 9 9 e2 013 a 9 e2 00c b 9 e2 005 c 9 e2 1fe d 9 e2 1f7 e 9 e2 1f0 f 9 e2 1e9 0 a e2 1e2 1 a e2 1dc 2 a e2 1d6 3 a e2 1d0 4 a e2 1ca 5 a e2 1c4 6 a e2 1be 7 a e2 1b8 8 a e2 012 9 a e2 00c a a e2 006 b a e2 000 c a e2 1fa d a e2 1f4 e a e2 1ee f a e2 1e8 0 b e2 1e2 1 b e2 1dd 2 b e2 1d8 3 b e2 1d3 4 b e2 1ce 5 b e2 1c9 6 b e2 1c4 7 b e2 1bf 8 b e2 00a 9 b e2 005 a b e2 000 b b e2 1fb c b e2 1f6 d b e2 1f1 e b e2 1ec f b e2 1e7 0 c e2 1e2 1 c e2 1de 2 c e2 1da 3 c e2 1d6 4 c e2 1d2 5 c e2 1ce 6 c e2 1ca 7 c e2 1c6 8 c e2 002 9 c e2 1fe a c e2 1fa b c e2 1f6 c c e2 1f2 d c e2 1ee e c e2 1ea f c e2 1e6 0 d e2 1e2 1 d e2 1df 2 d e2 1dc 3 d e2 1d9 4 d e2 1d6 5 d e2 1d3 6 d e2 1d0 7 d e2 1cd 8 d e2 1fa 9 d e2 1f7 a d e2 1f4 b d e2 1f1 c d e2 1ee d d e2 1eb e d e2 1e8 f d e2 1e5 0 e e2 1e2 1 e e2 1e0 2 e e2 1de 3 e e2 1dc 4 e e2 1da 5 e e2 1d8 6 e e2 1d6 7 e e2 1d4 8 e e2 1f2 9 e e2 1f0 a e e2 1ee b e e2 1ec c e e2 1ea d e e2 1e8 e e e2 1e6 f e e2 1e4 0 f e2 1e2 1 f e2 1e1 2 f e2 1e0 3 f e2 1df 4 f e2 1de 5 f e2 1dd 6 f e2 1dc 7 f e2 1db 8 f e2 1ea 9 f e2 1e9 a f e2 1e8 b f e2 1e7 c f e2 1e6 d f e2 1e5 e f e2 1e4 f f e2 1e3 0 0 e3 1e3 1 0 e3 1e3 2 0 e3 1e3 3 0 e3 1e3 4 0 e3 1e3 5 0 e3 1e3 6 0 e3 1e3 7 0 e3 1e3 8 0 e3 1e3 9 0 e3 1e3 a 0 e3 1e3 b 0 e3 1e3 c 0 e3 1e3 d 0 e3 1e3 e 0 e3 1e3 f 0 e3 1e3 0 1 e3 1e3 1 1 e3 1e4 2 1 e3 1e5 3 1 e3 1e6 4 1 e3 1e7 5 1 e3 1e8 6 1 e3 1e9 7 1 e3 1ea 8 1 e3 1db 9 1 e3 1dc a 1 e3 1dd b 1 e3 1de c 1 e3 1df d 1 e3 1e0 e 1 e3 1e1 f 1 e3 1e2 0 2 e3 1e3 1 2 e3 1e5 2 2 e3 1e7 3 2 e3 1e9 4 2 e3 1eb 5 2 e3 1ed 6 2 e3 1ef 7 2 e3 1f1 8 2 e3 1d3 9 2 e3 1d5 a 2 e3 1d7 b 2 e3 1d9 c 2 e3 1db d 2 e3 1dd e 2 e3 1df f 2 e3 1e1 0 3 e3 1e3 1 3 e3 1e6 2 3 e3 1e9 3 3 e3 1ec 4 3 e3 1ef 5 3 e3 1f2 6 3 e3 1f5 7 3 e3 1f8 8 3 e3 1cb 9 3 e3 1ce a 3 e3 1d1 b 3 e3 1d4 c 3 e3 1d7 d 3 e3 1da e 3 e3 1dd f 3 e3 1e0 0 4 e3 1e3 1 4 e3 1e7 2 4 e3 1eb 3 4 e3 1ef 4 4 e3 1f3 5 4 e3 1f7 6 4 e3 1fb 7 4 e3 1ff 8 4 e3 1c3 9 4 e3 1c7 a 4 e3 1cb b 4 e3 1cf c 4 e3 1d3 d 4 e3 1d7 e 4 e3 1db f 4 e3 1df 0 5 e3 1e3 1 5 e3 1e8 2 5 e3 1ed 3 5 e3 1f2 4 5 e3 1f7 5 5 e3 1fc 6 5 e3 001 7 5 e3 006 8 5 e3 1bb 9 5 e3 1c0 a 5 e3 1c5 b 5 e3 1ca c 5 e3 1cf d 5 e3 1d4 e 5 e3 1d9 f 5 e3 1de 0 6 e3 1e3 1 6 e3 1e9 2 6 e3 1ef 3 6 e3 1f5 4 6 e3 1fb 5 6 e3 001 6 6 e3 007 7 6 e3 00d 8 6 e3 1b3 9 6 e3 1b9 a 6 e3 1bf b 6 e3 1c5 c 6 e3 1cb d 6 e3 1d1 e 6 e3 1d7 f 6 e3 1dd 0 7 e3 1e3 1 7 e3 1ea 2 7 e3 1f1 3 7 e3 1f8 4 7 e3 1ff 5 7 e3 006 6 7 e3 00d 7 7 e3 014 8 7 e3 1ab 9 7 e3 1b2 a 7 e3 1b9 b 7 e3 1c0 c 7 e3 1c7 d 7 e3 1ce e 7 e3 1d5 f 7 e3 1dc 0 8 e3 1e3 1 8 e3 1db 2 8 e3 1d3 3 8 e3 1cb 4 8 e3 1c3 5 8 e3 1bb 6 8 e3 1b3 7 8 e3 1ab 8 8 e3 023 9 8 e3 01b a 8 e3 013 b 8 e3 00b c 8 e3 003 d 8 e3 1fb e 8 e3 1f3 f 8 e3 1eb 0 9 e3 1e3 1 9 e3 1dc 2 9 e3 1d5 3 9 e3 1ce 4 9 e3 1c7 5 9 e3 1c0 6 9 e3 1b9 7 9 e3 1b2 8 9 e3 01b 9 9 e3 014 a 9 e3 00d b 9 e3 006 c 9 e3 1ff d 9 e3 1f8 e 9 e3 1f1 f 9 e3 1ea 0 a e3 1e3 1 a e3 1dd 2 a e3 1d7 3 a e3 1d1 4 a e3 1cb 5 a e3 1c5 6 a e3 1bf 7 a e3 1b9 8 a e3 013 9 a e3 00d a a e3 007 b a e3 001 c a e3 1fb d a e3 1f5 e a e3 1ef f a e3 1e9 0 b e3 1e3 1 b e3 1de 2 b e3 1d9 3 b e3 1d4 4 b e3 1cf 5 b e3 1ca 6 b e3 1c5 7 b e3 1c0 8 b e3 00b 9 b e3 006 a b e3 001 b b e3 1fc c b e3 1f7 d b e3 1f2 e b e3 1ed f b e3 1e8 0 c e3 1e3 1 c e3 1df 2 c e3 1db 3 c e3 1d7 4 c e3 1d3 5 c e3 1cf 6 c e3 1cb 7 c e3 1c7 8 c e3 003 9 c e3 1ff a c e3 1fb b c e3 1f7 c c e3 1f3 d c e3 1ef e c e3 1eb f c e3 1e7 0 d e3 1e3 1 d e3 1e0 2 d e3 1dd 3 d e3 1da 4 d e3 1d7 5 d e3 1d4 6 d e3 1d1 7 d e3 1ce 8 d e3 1fb 9 d e3 1f8 a d e3 1f5 b d e3 1f2 c d e3 1ef d d e3 1ec e d e3 1e9 f d e3 1e6 0 e e3 1e3 1 e e3 1e1 2 e e3 1df 3 e e3 1dd 4 e e3 1db 5 e e3 1d9 6 e e3 1d7 7 e e3 1d5 8 e e3 1f3 9 e e3 1f1 a e e3 1ef b e e3 1ed c e e3 1eb d e e3 1e9 e e e3 1e7 f e e3 1e5 0 f e3 1e3 1 f e3 1e2 2 f e3 1e1 3 f e3 1e0 4 f e3 1df 5 f e3 1de 6 f e3 1dd 7 f e3 1dc 8 f e3 1eb 9 f e3 1ea a f e3 1e9 b f e3 1e8 c f e3 1e7 d f e3 1e6 e f e3 1e5 f f e3 1e4 0 0 e4 1e4 1 0 e4 1e4 2 0 e4 1e4 3 0 e4 1e4 4 0 e4 1e4 5 0 e4 1e4 6 0 e4 1e4 7 0 e4 1e4 8 0 e4 1e4 9 0 e4 1e4 a 0 e4 1e4 b 0 e4 1e4 c 0 e4 1e4 d 0 e4 1e4 e 0 e4 1e4 f 0 e4 1e4 0 1 e4 1e4 1 1 e4 1e5 2 1 e4 1e6 3 1 e4 1e7 4 1 e4 1e8 5 1 e4 1e9 6 1 e4 1ea 7 1 e4 1eb 8 1 e4 1dc 9 1 e4 1dd a 1 e4 1de b 1 e4 1df c 1 e4 1e0 d 1 e4 1e1 e 1 e4 1e2 f 1 e4 1e3 0 2 e4 1e4 1 2 e4 1e6 2 2 e4 1e8 3 2 e4 1ea 4 2 e4 1ec 5 2 e4 1ee 6 2 e4 1f0 7 2 e4 1f2 8 2 e4 1d4 9 2 e4 1d6 a 2 e4 1d8 b 2 e4 1da c 2 e4 1dc d 2 e4 1de e 2 e4 1e0 f 2 e4 1e2 0 3 e4 1e4 1 3 e4 1e7 2 3 e4 1ea 3 3 e4 1ed 4 3 e4 1f0 5 3 e4 1f3 6 3 e4 1f6 7 3 e4 1f9 8 3 e4 1cc 9 3 e4 1cf a 3 e4 1d2 b 3 e4 1d5 c 3 e4 1d8 d 3 e4 1db e 3 e4 1de f 3 e4 1e1 0 4 e4 1e4 1 4 e4 1e8 2 4 e4 1ec 3 4 e4 1f0 4 4 e4 1f4 5 4 e4 1f8 6 4 e4 1fc 7 4 e4 000 8 4 e4 1c4 9 4 e4 1c8 a 4 e4 1cc b 4 e4 1d0 c 4 e4 1d4 d 4 e4 1d8 e 4 e4 1dc f 4 e4 1e0 0 5 e4 1e4 1 5 e4 1e9 2 5 e4 1ee 3 5 e4 1f3 4 5 e4 1f8 5 5 e4 1fd 6 5 e4 002 7 5 e4 007 8 5 e4 1bc 9 5 e4 1c1 a 5 e4 1c6 b 5 e4 1cb c 5 e4 1d0 d 5 e4 1d5 e 5 e4 1da f 5 e4 1df 0 6 e4 1e4 1 6 e4 1ea 2 6 e4 1f0 3 6 e4 1f6 4 6 e4 1fc 5 6 e4 002 6 6 e4 008 7 6 e4 00e 8 6 e4 1b4 9 6 e4 1ba a 6 e4 1c0 b 6 e4 1c6 c 6 e4 1cc d 6 e4 1d2 e 6 e4 1d8 f 6 e4 1de 0 7 e4 1e4 1 7 e4 1eb 2 7 e4 1f2 3 7 e4 1f9 4 7 e4 000 5 7 e4 007 6 7 e4 00e 7 7 e4 015 8 7 e4 1ac 9 7 e4 1b3 a 7 e4 1ba b 7 e4 1c1 c 7 e4 1c8 d 7 e4 1cf e 7 e4 1d6 f 7 e4 1dd 0 8 e4 1e4 1 8 e4 1dc 2 8 e4 1d4 3 8 e4 1cc 4 8 e4 1c4 5 8 e4 1bc 6 8 e4 1b4 7 8 e4 1ac 8 8 e4 024 9 8 e4 01c a 8 e4 014 b 8 e4 00c c 8 e4 004 d 8 e4 1fc e 8 e4 1f4 f 8 e4 1ec 0 9 e4 1e4 1 9 e4 1dd 2 9 e4 1d6 3 9 e4 1cf 4 9 e4 1c8 5 9 e4 1c1 6 9 e4 1ba 7 9 e4 1b3 8 9 e4 01c 9 9 e4 015 a 9 e4 00e b 9 e4 007 c 9 e4 000 d 9 e4 1f9 e 9 e4 1f2 f 9 e4 1eb 0 a e4 1e4 1 a e4 1de 2 a e4 1d8 3 a e4 1d2 4 a e4 1cc 5 a e4 1c6 6 a e4 1c0 7 a e4 1ba 8 a e4 014 9 a e4 00e a a e4 008 b a e4 002 c a e4 1fc d a e4 1f6 e a e4 1f0 f a e4 1ea 0 b e4 1e4 1 b e4 1df 2 b e4 1da 3 b e4 1d5 4 b e4 1d0 5 b e4 1cb 6 b e4 1c6 7 b e4 1c1 8 b e4 00c 9 b e4 007 a b e4 002 b b e4 1fd c b e4 1f8 d b e4 1f3 e b e4 1ee f b e4 1e9 0 c e4 1e4 1 c e4 1e0 2 c e4 1dc 3 c e4 1d8 4 c e4 1d4 5 c e4 1d0 6 c e4 1cc 7 c e4 1c8 8 c e4 004 9 c e4 000 a c e4 1fc b c e4 1f8 c c e4 1f4 d c e4 1f0 e c e4 1ec f c e4 1e8 0 d e4 1e4 1 d e4 1e1 2 d e4 1de 3 d e4 1db 4 d e4 1d8 5 d e4 1d5 6 d e4 1d2 7 d e4 1cf 8 d e4 1fc 9 d e4 1f9 a d e4 1f6 b d e4 1f3 c d e4 1f0 d d e4 1ed e d e4 1ea f d e4 1e7 0 e e4 1e4 1 e e4 1e2 2 e e4 1e0 3 e e4 1de 4 e e4 1dc 5 e e4 1da 6 e e4 1d8 7 e e4 1d6 8 e e4 1f4 9 e e4 1f2 a e e4 1f0 b e e4 1ee c e e4 1ec d e e4 1ea e e e4 1e8 f e e4 1e6 0 f e4 1e4 1 f e4 1e3 2 f e4 1e2 3 f e4 1e1 4 f e4 1e0 5 f e4 1df 6 f e4 1de 7 f e4 1dd 8 f e4 1ec 9 f e4 1eb a f e4 1ea b f e4 1e9 c f e4 1e8 d f e4 1e7 e f e4 1e6 f f e4 1e5 0 0 e5 1e5 1 0 e5 1e5 2 0 e5 1e5 3 0 e5 1e5 4 0 e5 1e5 5 0 e5 1e5 6 0 e5 1e5 7 0 e5 1e5 8 0 e5 1e5 9 0 e5 1e5 a 0 e5 1e5 b 0 e5 1e5 c 0 e5 1e5 d 0 e5 1e5 e 0 e5 1e5 f 0 e5 1e5 0 1 e5 1e5 1 1 e5 1e6 2 1 e5 1e7 3 1 e5 1e8 4 1 e5 1e9 5 1 e5 1ea 6 1 e5 1eb 7 1 e5 1ec 8 1 e5 1dd 9 1 e5 1de a 1 e5 1df b 1 e5 1e0 c 1 e5 1e1 d 1 e5 1e2 e 1 e5 1e3 f 1 e5 1e4 0 2 e5 1e5 1 2 e5 1e7 2 2 e5 1e9 3 2 e5 1eb 4 2 e5 1ed 5 2 e5 1ef 6 2 e5 1f1 7 2 e5 1f3 8 2 e5 1d5 9 2 e5 1d7 a 2 e5 1d9 b 2 e5 1db c 2 e5 1dd d 2 e5 1df e 2 e5 1e1 f 2 e5 1e3 0 3 e5 1e5 1 3 e5 1e8 2 3 e5 1eb 3 3 e5 1ee 4 3 e5 1f1 5 3 e5 1f4 6 3 e5 1f7 7 3 e5 1fa 8 3 e5 1cd 9 3 e5 1d0 a 3 e5 1d3 b 3 e5 1d6 c 3 e5 1d9 d 3 e5 1dc e 3 e5 1df f 3 e5 1e2 0 4 e5 1e5 1 4 e5 1e9 2 4 e5 1ed 3 4 e5 1f1 4 4 e5 1f5 5 4 e5 1f9 6 4 e5 1fd 7 4 e5 001 8 4 e5 1c5 9 4 e5 1c9 a 4 e5 1cd b 4 e5 1d1 c 4 e5 1d5 d 4 e5 1d9 e 4 e5 1dd f 4 e5 1e1 0 5 e5 1e5 1 5 e5 1ea 2 5 e5 1ef 3 5 e5 1f4 4 5 e5 1f9 5 5 e5 1fe 6 5 e5 003 7 5 e5 008 8 5 e5 1bd 9 5 e5 1c2 a 5 e5 1c7 b 5 e5 1cc c 5 e5 1d1 d 5 e5 1d6 e 5 e5 1db f 5 e5 1e0 0 6 e5 1e5 1 6 e5 1eb 2 6 e5 1f1 3 6 e5 1f7 4 6 e5 1fd 5 6 e5 003 6 6 e5 009 7 6 e5 00f 8 6 e5 1b5 9 6 e5 1bb a 6 e5 1c1 b 6 e5 1c7 c 6 e5 1cd d 6 e5 1d3 e 6 e5 1d9 f 6 e5 1df 0 7 e5 1e5 1 7 e5 1ec 2 7 e5 1f3 3 7 e5 1fa 4 7 e5 001 5 7 e5 008 6 7 e5 00f 7 7 e5 016 8 7 e5 1ad 9 7 e5 1b4 a 7 e5 1bb b 7 e5 1c2 c 7 e5 1c9 d 7 e5 1d0 e 7 e5 1d7 f 7 e5 1de 0 8 e5 1e5 1 8 e5 1dd 2 8 e5 1d5 3 8 e5 1cd 4 8 e5 1c5 5 8 e5 1bd 6 8 e5 1b5 7 8 e5 1ad 8 8 e5 025 9 8 e5 01d a 8 e5 015 b 8 e5 00d c 8 e5 005 d 8 e5 1fd e 8 e5 1f5 f 8 e5 1ed 0 9 e5 1e5 1 9 e5 1de 2 9 e5 1d7 3 9 e5 1d0 4 9 e5 1c9 5 9 e5 1c2 6 9 e5 1bb 7 9 e5 1b4 8 9 e5 01d 9 9 e5 016 a 9 e5 00f b 9 e5 008 c 9 e5 001 d 9 e5 1fa e 9 e5 1f3 f 9 e5 1ec 0 a e5 1e5 1 a e5 1df 2 a e5 1d9 3 a e5 1d3 4 a e5 1cd 5 a e5 1c7 6 a e5 1c1 7 a e5 1bb 8 a e5 015 9 a e5 00f a a e5 009 b a e5 003 c a e5 1fd d a e5 1f7 e a e5 1f1 f a e5 1eb 0 b e5 1e5 1 b e5 1e0 2 b e5 1db 3 b e5 1d6 4 b e5 1d1 5 b e5 1cc 6 b e5 1c7 7 b e5 1c2 8 b e5 00d 9 b e5 008 a b e5 003 b b e5 1fe c b e5 1f9 d b e5 1f4 e b e5 1ef f b e5 1ea 0 c e5 1e5 1 c e5 1e1 2 c e5 1dd 3 c e5 1d9 4 c e5 1d5 5 c e5 1d1 6 c e5 1cd 7 c e5 1c9 8 c e5 005 9 c e5 001 a c e5 1fd b c e5 1f9 c c e5 1f5 d c e5 1f1 e c e5 1ed f c e5 1e9 0 d e5 1e5 1 d e5 1e2 2 d e5 1df 3 d e5 1dc 4 d e5 1d9 5 d e5 1d6 6 d e5 1d3 7 d e5 1d0 8 d e5 1fd 9 d e5 1fa a d e5 1f7 b d e5 1f4 c d e5 1f1 d d e5 1ee e d e5 1eb f d e5 1e8 0 e e5 1e5 1 e e5 1e3 2 e e5 1e1 3 e e5 1df 4 e e5 1dd 5 e e5 1db 6 e e5 1d9 7 e e5 1d7 8 e e5 1f5 9 e e5 1f3 a e e5 1f1 b e e5 1ef c e e5 1ed d e e5 1eb e e e5 1e9 f e e5 1e7 0 f e5 1e5 1 f e5 1e4 2 f e5 1e3 3 f e5 1e2 4 f e5 1e1 5 f e5 1e0 6 f e5 1df 7 f e5 1de 8 f e5 1ed 9 f e5 1ec a f e5 1eb b f e5 1ea c f e5 1e9 d f e5 1e8 e f e5 1e7 f f e5 1e6 0 0 e6 1e6 1 0 e6 1e6 2 0 e6 1e6 3 0 e6 1e6 4 0 e6 1e6 5 0 e6 1e6 6 0 e6 1e6 7 0 e6 1e6 8 0 e6 1e6 9 0 e6 1e6 a 0 e6 1e6 b 0 e6 1e6 c 0 e6 1e6 d 0 e6 1e6 e 0 e6 1e6 f 0 e6 1e6 0 1 e6 1e6 1 1 e6 1e7 2 1 e6 1e8 3 1 e6 1e9 4 1 e6 1ea 5 1 e6 1eb 6 1 e6 1ec 7 1 e6 1ed 8 1 e6 1de 9 1 e6 1df a 1 e6 1e0 b 1 e6 1e1 c 1 e6 1e2 d 1 e6 1e3 e 1 e6 1e4 f 1 e6 1e5 0 2 e6 1e6 1 2 e6 1e8 2 2 e6 1ea 3 2 e6 1ec 4 2 e6 1ee 5 2 e6 1f0 6 2 e6 1f2 7 2 e6 1f4 8 2 e6 1d6 9 2 e6 1d8 a 2 e6 1da b 2 e6 1dc c 2 e6 1de d 2 e6 1e0 e 2 e6 1e2 f 2 e6 1e4 0 3 e6 1e6 1 3 e6 1e9 2 3 e6 1ec 3 3 e6 1ef 4 3 e6 1f2 5 3 e6 1f5 6 3 e6 1f8 7 3 e6 1fb 8 3 e6 1ce 9 3 e6 1d1 a 3 e6 1d4 b 3 e6 1d7 c 3 e6 1da d 3 e6 1dd e 3 e6 1e0 f 3 e6 1e3 0 4 e6 1e6 1 4 e6 1ea 2 4 e6 1ee 3 4 e6 1f2 4 4 e6 1f6 5 4 e6 1fa 6 4 e6 1fe 7 4 e6 002 8 4 e6 1c6 9 4 e6 1ca a 4 e6 1ce b 4 e6 1d2 c 4 e6 1d6 d 4 e6 1da e 4 e6 1de f 4 e6 1e2 0 5 e6 1e6 1 5 e6 1eb 2 5 e6 1f0 3 5 e6 1f5 4 5 e6 1fa 5 5 e6 1ff 6 5 e6 004 7 5 e6 009 8 5 e6 1be 9 5 e6 1c3 a 5 e6 1c8 b 5 e6 1cd c 5 e6 1d2 d 5 e6 1d7 e 5 e6 1dc f 5 e6 1e1 0 6 e6 1e6 1 6 e6 1ec 2 6 e6 1f2 3 6 e6 1f8 4 6 e6 1fe 5 6 e6 004 6 6 e6 00a 7 6 e6 010 8 6 e6 1b6 9 6 e6 1bc a 6 e6 1c2 b 6 e6 1c8 c 6 e6 1ce d 6 e6 1d4 e 6 e6 1da f 6 e6 1e0 0 7 e6 1e6 1 7 e6 1ed 2 7 e6 1f4 3 7 e6 1fb 4 7 e6 002 5 7 e6 009 6 7 e6 010 7 7 e6 017 8 7 e6 1ae 9 7 e6 1b5 a 7 e6 1bc b 7 e6 1c3 c 7 e6 1ca d 7 e6 1d1 e 7 e6 1d8 f 7 e6 1df 0 8 e6 1e6 1 8 e6 1de 2 8 e6 1d6 3 8 e6 1ce 4 8 e6 1c6 5 8 e6 1be 6 8 e6 1b6 7 8 e6 1ae 8 8 e6 026 9 8 e6 01e a 8 e6 016 b 8 e6 00e c 8 e6 006 d 8 e6 1fe e 8 e6 1f6 f 8 e6 1ee 0 9 e6 1e6 1 9 e6 1df 2 9 e6 1d8 3 9 e6 1d1 4 9 e6 1ca 5 9 e6 1c3 6 9 e6 1bc 7 9 e6 1b5 8 9 e6 01e 9 9 e6 017 a 9 e6 010 b 9 e6 009 c 9 e6 002 d 9 e6 1fb e 9 e6 1f4 f 9 e6 1ed 0 a e6 1e6 1 a e6 1e0 2 a e6 1da 3 a e6 1d4 4 a e6 1ce 5 a e6 1c8 6 a e6 1c2 7 a e6 1bc 8 a e6 016 9 a e6 010 a a e6 00a b a e6 004 c a e6 1fe d a e6 1f8 e a e6 1f2 f a e6 1ec 0 b e6 1e6 1 b e6 1e1 2 b e6 1dc 3 b e6 1d7 4 b e6 1d2 5 b e6 1cd 6 b e6 1c8 7 b e6 1c3 8 b e6 00e 9 b e6 009 a b e6 004 b b e6 1ff c b e6 1fa d b e6 1f5 e b e6 1f0 f b e6 1eb 0 c e6 1e6 1 c e6 1e2 2 c e6 1de 3 c e6 1da 4 c e6 1d6 5 c e6 1d2 6 c e6 1ce 7 c e6 1ca 8 c e6 006 9 c e6 002 a c e6 1fe b c e6 1fa c c e6 1f6 d c e6 1f2 e c e6 1ee f c e6 1ea 0 d e6 1e6 1 d e6 1e3 2 d e6 1e0 3 d e6 1dd 4 d e6 1da 5 d e6 1d7 6 d e6 1d4 7 d e6 1d1 8 d e6 1fe 9 d e6 1fb a d e6 1f8 b d e6 1f5 c d e6 1f2 d d e6 1ef e d e6 1ec f d e6 1e9 0 e e6 1e6 1 e e6 1e4 2 e e6 1e2 3 e e6 1e0 4 e e6 1de 5 e e6 1dc 6 e e6 1da 7 e e6 1d8 8 e e6 1f6 9 e e6 1f4 a e e6 1f2 b e e6 1f0 c e e6 1ee d e e6 1ec e e e6 1ea f e e6 1e8 0 f e6 1e6 1 f e6 1e5 2 f e6 1e4 3 f e6 1e3 4 f e6 1e2 5 f e6 1e1 6 f e6 1e0 7 f e6 1df 8 f e6 1ee 9 f e6 1ed a f e6 1ec b f e6 1eb c f e6 1ea d f e6 1e9 e f e6 1e8 f f e6 1e7 0 0 e7 1e7 1 0 e7 1e7 2 0 e7 1e7 3 0 e7 1e7 4 0 e7 1e7 5 0 e7 1e7 6 0 e7 1e7 7 0 e7 1e7 8 0 e7 1e7 9 0 e7 1e7 a 0 e7 1e7 b 0 e7 1e7 c 0 e7 1e7 d 0 e7 1e7 e 0 e7 1e7 f 0 e7 1e7 0 1 e7 1e7 1 1 e7 1e8 2 1 e7 1e9 3 1 e7 1ea 4 1 e7 1eb 5 1 e7 1ec 6 1 e7 1ed 7 1 e7 1ee 8 1 e7 1df 9 1 e7 1e0 a 1 e7 1e1 b 1 e7 1e2 c 1 e7 1e3 d 1 e7 1e4 e 1 e7 1e5 f 1 e7 1e6 0 2 e7 1e7 1 2 e7 1e9 2 2 e7 1eb 3 2 e7 1ed 4 2 e7 1ef 5 2 e7 1f1 6 2 e7 1f3 7 2 e7 1f5 8 2 e7 1d7 9 2 e7 1d9 a 2 e7 1db b 2 e7 1dd c 2 e7 1df d 2 e7 1e1 e 2 e7 1e3 f 2 e7 1e5 0 3 e7 1e7 1 3 e7 1ea 2 3 e7 1ed 3 3 e7 1f0 4 3 e7 1f3 5 3 e7 1f6 6 3 e7 1f9 7 3 e7 1fc 8 3 e7 1cf 9 3 e7 1d2 a 3 e7 1d5 b 3 e7 1d8 c 3 e7 1db d 3 e7 1de e 3 e7 1e1 f 3 e7 1e4 0 4 e7 1e7 1 4 e7 1eb 2 4 e7 1ef 3 4 e7 1f3 4 4 e7 1f7 5 4 e7 1fb 6 4 e7 1ff 7 4 e7 003 8 4 e7 1c7 9 4 e7 1cb a 4 e7 1cf b 4 e7 1d3 c 4 e7 1d7 d 4 e7 1db e 4 e7 1df f 4 e7 1e3 0 5 e7 1e7 1 5 e7 1ec 2 5 e7 1f1 3 5 e7 1f6 4 5 e7 1fb 5 5 e7 000 6 5 e7 005 7 5 e7 00a 8 5 e7 1bf 9 5 e7 1c4 a 5 e7 1c9 b 5 e7 1ce c 5 e7 1d3 d 5 e7 1d8 e 5 e7 1dd f 5 e7 1e2 0 6 e7 1e7 1 6 e7 1ed 2 6 e7 1f3 3 6 e7 1f9 4 6 e7 1ff 5 6 e7 005 6 6 e7 00b 7 6 e7 011 8 6 e7 1b7 9 6 e7 1bd a 6 e7 1c3 b 6 e7 1c9 c 6 e7 1cf d 6 e7 1d5 e 6 e7 1db f 6 e7 1e1 0 7 e7 1e7 1 7 e7 1ee 2 7 e7 1f5 3 7 e7 1fc 4 7 e7 003 5 7 e7 00a 6 7 e7 011 7 7 e7 018 8 7 e7 1af 9 7 e7 1b6 a 7 e7 1bd b 7 e7 1c4 c 7 e7 1cb d 7 e7 1d2 e 7 e7 1d9 f 7 e7 1e0 0 8 e7 1e7 1 8 e7 1df 2 8 e7 1d7 3 8 e7 1cf 4 8 e7 1c7 5 8 e7 1bf 6 8 e7 1b7 7 8 e7 1af 8 8 e7 027 9 8 e7 01f a 8 e7 017 b 8 e7 00f c 8 e7 007 d 8 e7 1ff e 8 e7 1f7 f 8 e7 1ef 0 9 e7 1e7 1 9 e7 1e0 2 9 e7 1d9 3 9 e7 1d2 4 9 e7 1cb 5 9 e7 1c4 6 9 e7 1bd 7 9 e7 1b6 8 9 e7 01f 9 9 e7 018 a 9 e7 011 b 9 e7 00a c 9 e7 003 d 9 e7 1fc e 9 e7 1f5 f 9 e7 1ee 0 a e7 1e7 1 a e7 1e1 2 a e7 1db 3 a e7 1d5 4 a e7 1cf 5 a e7 1c9 6 a e7 1c3 7 a e7 1bd 8 a e7 017 9 a e7 011 a a e7 00b b a e7 005 c a e7 1ff d a e7 1f9 e a e7 1f3 f a e7 1ed 0 b e7 1e7 1 b e7 1e2 2 b e7 1dd 3 b e7 1d8 4 b e7 1d3 5 b e7 1ce 6 b e7 1c9 7 b e7 1c4 8 b e7 00f 9 b e7 00a a b e7 005 b b e7 000 c b e7 1fb d b e7 1f6 e b e7 1f1 f b e7 1ec 0 c e7 1e7 1 c e7 1e3 2 c e7 1df 3 c e7 1db 4 c e7 1d7 5 c e7 1d3 6 c e7 1cf 7 c e7 1cb 8 c e7 007 9 c e7 003 a c e7 1ff b c e7 1fb c c e7 1f7 d c e7 1f3 e c e7 1ef f c e7 1eb 0 d e7 1e7 1 d e7 1e4 2 d e7 1e1 3 d e7 1de 4 d e7 1db 5 d e7 1d8 6 d e7 1d5 7 d e7 1d2 8 d e7 1ff 9 d e7 1fc a d e7 1f9 b d e7 1f6 c d e7 1f3 d d e7 1f0 e d e7 1ed f d e7 1ea 0 e e7 1e7 1 e e7 1e5 2 e e7 1e3 3 e e7 1e1 4 e e7 1df 5 e e7 1dd 6 e e7 1db 7 e e7 1d9 8 e e7 1f7 9 e e7 1f5 a e e7 1f3 b e e7 1f1 c e e7 1ef d e e7 1ed e e e7 1eb f e e7 1e9 0 f e7 1e7 1 f e7 1e6 2 f e7 1e5 3 f e7 1e4 4 f e7 1e3 5 f e7 1e2 6 f e7 1e1 7 f e7 1e0 8 f e7 1ef 9 f e7 1ee a f e7 1ed b f e7 1ec c f e7 1eb d f e7 1ea e f e7 1e9 f f e7 1e8 0 0 e8 1e8 1 0 e8 1e8 2 0 e8 1e8 3 0 e8 1e8 4 0 e8 1e8 5 0 e8 1e8 6 0 e8 1e8 7 0 e8 1e8 8 0 e8 1e8 9 0 e8 1e8 a 0 e8 1e8 b 0 e8 1e8 c 0 e8 1e8 d 0 e8 1e8 e 0 e8 1e8 f 0 e8 1e8 0 1 e8 1e8 1 1 e8 1e9 2 1 e8 1ea 3 1 e8 1eb 4 1 e8 1ec 5 1 e8 1ed 6 1 e8 1ee 7 1 e8 1ef 8 1 e8 1e0 9 1 e8 1e1 a 1 e8 1e2 b 1 e8 1e3 c 1 e8 1e4 d 1 e8 1e5 e 1 e8 1e6 f 1 e8 1e7 0 2 e8 1e8 1 2 e8 1ea 2 2 e8 1ec 3 2 e8 1ee 4 2 e8 1f0 5 2 e8 1f2 6 2 e8 1f4 7 2 e8 1f6 8 2 e8 1d8 9 2 e8 1da a 2 e8 1dc b 2 e8 1de c 2 e8 1e0 d 2 e8 1e2 e 2 e8 1e4 f 2 e8 1e6 0 3 e8 1e8 1 3 e8 1eb 2 3 e8 1ee 3 3 e8 1f1 4 3 e8 1f4 5 3 e8 1f7 6 3 e8 1fa 7 3 e8 1fd 8 3 e8 1d0 9 3 e8 1d3 a 3 e8 1d6 b 3 e8 1d9 c 3 e8 1dc d 3 e8 1df e 3 e8 1e2 f 3 e8 1e5 0 4 e8 1e8 1 4 e8 1ec 2 4 e8 1f0 3 4 e8 1f4 4 4 e8 1f8 5 4 e8 1fc 6 4 e8 000 7 4 e8 004 8 4 e8 1c8 9 4 e8 1cc a 4 e8 1d0 b 4 e8 1d4 c 4 e8 1d8 d 4 e8 1dc e 4 e8 1e0 f 4 e8 1e4 0 5 e8 1e8 1 5 e8 1ed 2 5 e8 1f2 3 5 e8 1f7 4 5 e8 1fc 5 5 e8 001 6 5 e8 006 7 5 e8 00b 8 5 e8 1c0 9 5 e8 1c5 a 5 e8 1ca b 5 e8 1cf c 5 e8 1d4 d 5 e8 1d9 e 5 e8 1de f 5 e8 1e3 0 6 e8 1e8 1 6 e8 1ee 2 6 e8 1f4 3 6 e8 1fa 4 6 e8 000 5 6 e8 006 6 6 e8 00c 7 6 e8 012 8 6 e8 1b8 9 6 e8 1be a 6 e8 1c4 b 6 e8 1ca c 6 e8 1d0 d 6 e8 1d6 e 6 e8 1dc f 6 e8 1e2 0 7 e8 1e8 1 7 e8 1ef 2 7 e8 1f6 3 7 e8 1fd 4 7 e8 004 5 7 e8 00b 6 7 e8 012 7 7 e8 019 8 7 e8 1b0 9 7 e8 1b7 a 7 e8 1be b 7 e8 1c5 c 7 e8 1cc d 7 e8 1d3 e 7 e8 1da f 7 e8 1e1 0 8 e8 1e8 1 8 e8 1e0 2 8 e8 1d8 3 8 e8 1d0 4 8 e8 1c8 5 8 e8 1c0 6 8 e8 1b8 7 8 e8 1b0 8 8 e8 028 9 8 e8 020 a 8 e8 018 b 8 e8 010 c 8 e8 008 d 8 e8 000 e 8 e8 1f8 f 8 e8 1f0 0 9 e8 1e8 1 9 e8 1e1 2 9 e8 1da 3 9 e8 1d3 4 9 e8 1cc 5 9 e8 1c5 6 9 e8 1be 7 9 e8 1b7 8 9 e8 020 9 9 e8 019 a 9 e8 012 b 9 e8 00b c 9 e8 004 d 9 e8 1fd e 9 e8 1f6 f 9 e8 1ef 0 a e8 1e8 1 a e8 1e2 2 a e8 1dc 3 a e8 1d6 4 a e8 1d0 5 a e8 1ca 6 a e8 1c4 7 a e8 1be 8 a e8 018 9 a e8 012 a a e8 00c b a e8 006 c a e8 000 d a e8 1fa e a e8 1f4 f a e8 1ee 0 b e8 1e8 1 b e8 1e3 2 b e8 1de 3 b e8 1d9 4 b e8 1d4 5 b e8 1cf 6 b e8 1ca 7 b e8 1c5 8 b e8 010 9 b e8 00b a b e8 006 b b e8 001 c b e8 1fc d b e8 1f7 e b e8 1f2 f b e8 1ed 0 c e8 1e8 1 c e8 1e4 2 c e8 1e0 3 c e8 1dc 4 c e8 1d8 5 c e8 1d4 6 c e8 1d0 7 c e8 1cc 8 c e8 008 9 c e8 004 a c e8 000 b c e8 1fc c c e8 1f8 d c e8 1f4 e c e8 1f0 f c e8 1ec 0 d e8 1e8 1 d e8 1e5 2 d e8 1e2 3 d e8 1df 4 d e8 1dc 5 d e8 1d9 6 d e8 1d6 7 d e8 1d3 8 d e8 000 9 d e8 1fd a d e8 1fa b d e8 1f7 c d e8 1f4 d d e8 1f1 e d e8 1ee f d e8 1eb 0 e e8 1e8 1 e e8 1e6 2 e e8 1e4 3 e e8 1e2 4 e e8 1e0 5 e e8 1de 6 e e8 1dc 7 e e8 1da 8 e e8 1f8 9 e e8 1f6 a e e8 1f4 b e e8 1f2 c e e8 1f0 d e e8 1ee e e e8 1ec f e e8 1ea 0 f e8 1e8 1 f e8 1e7 2 f e8 1e6 3 f e8 1e5 4 f e8 1e4 5 f e8 1e3 6 f e8 1e2 7 f e8 1e1 8 f e8 1f0 9 f e8 1ef a f e8 1ee b f e8 1ed c f e8 1ec d f e8 1eb e f e8 1ea f f e8 1e9 0 0 e9 1e9 1 0 e9 1e9 2 0 e9 1e9 3 0 e9 1e9 4 0 e9 1e9 5 0 e9 1e9 6 0 e9 1e9 7 0 e9 1e9 8 0 e9 1e9 9 0 e9 1e9 a 0 e9 1e9 b 0 e9 1e9 c 0 e9 1e9 d 0 e9 1e9 e 0 e9 1e9 f 0 e9 1e9 0 1 e9 1e9 1 1 e9 1ea 2 1 e9 1eb 3 1 e9 1ec 4 1 e9 1ed 5 1 e9 1ee 6 1 e9 1ef 7 1 e9 1f0 8 1 e9 1e1 9 1 e9 1e2 a 1 e9 1e3 b 1 e9 1e4 c 1 e9 1e5 d 1 e9 1e6 e 1 e9 1e7 f 1 e9 1e8 0 2 e9 1e9 1 2 e9 1eb 2 2 e9 1ed 3 2 e9 1ef 4 2 e9 1f1 5 2 e9 1f3 6 2 e9 1f5 7 2 e9 1f7 8 2 e9 1d9 9 2 e9 1db a 2 e9 1dd b 2 e9 1df c 2 e9 1e1 d 2 e9 1e3 e 2 e9 1e5 f 2 e9 1e7 0 3 e9 1e9 1 3 e9 1ec 2 3 e9 1ef 3 3 e9 1f2 4 3 e9 1f5 5 3 e9 1f8 6 3 e9 1fb 7 3 e9 1fe 8 3 e9 1d1 9 3 e9 1d4 a 3 e9 1d7 b 3 e9 1da c 3 e9 1dd d 3 e9 1e0 e 3 e9 1e3 f 3 e9 1e6 0 4 e9 1e9 1 4 e9 1ed 2 4 e9 1f1 3 4 e9 1f5 4 4 e9 1f9 5 4 e9 1fd 6 4 e9 001 7 4 e9 005 8 4 e9 1c9 9 4 e9 1cd a 4 e9 1d1 b 4 e9 1d5 c 4 e9 1d9 d 4 e9 1dd e 4 e9 1e1 f 4 e9 1e5 0 5 e9 1e9 1 5 e9 1ee 2 5 e9 1f3 3 5 e9 1f8 4 5 e9 1fd 5 5 e9 002 6 5 e9 007 7 5 e9 00c 8 5 e9 1c1 9 5 e9 1c6 a 5 e9 1cb b 5 e9 1d0 c 5 e9 1d5 d 5 e9 1da e 5 e9 1df f 5 e9 1e4 0 6 e9 1e9 1 6 e9 1ef 2 6 e9 1f5 3 6 e9 1fb 4 6 e9 001 5 6 e9 007 6 6 e9 00d 7 6 e9 013 8 6 e9 1b9 9 6 e9 1bf a 6 e9 1c5 b 6 e9 1cb c 6 e9 1d1 d 6 e9 1d7 e 6 e9 1dd f 6 e9 1e3 0 7 e9 1e9 1 7 e9 1f0 2 7 e9 1f7 3 7 e9 1fe 4 7 e9 005 5 7 e9 00c 6 7 e9 013 7 7 e9 01a 8 7 e9 1b1 9 7 e9 1b8 a 7 e9 1bf b 7 e9 1c6 c 7 e9 1cd d 7 e9 1d4 e 7 e9 1db f 7 e9 1e2 0 8 e9 1e9 1 8 e9 1e1 2 8 e9 1d9 3 8 e9 1d1 4 8 e9 1c9 5 8 e9 1c1 6 8 e9 1b9 7 8 e9 1b1 8 8 e9 029 9 8 e9 021 a 8 e9 019 b 8 e9 011 c 8 e9 009 d 8 e9 001 e 8 e9 1f9 f 8 e9 1f1 0 9 e9 1e9 1 9 e9 1e2 2 9 e9 1db 3 9 e9 1d4 4 9 e9 1cd 5 9 e9 1c6 6 9 e9 1bf 7 9 e9 1b8 8 9 e9 021 9 9 e9 01a a 9 e9 013 b 9 e9 00c c 9 e9 005 d 9 e9 1fe e 9 e9 1f7 f 9 e9 1f0 0 a e9 1e9 1 a e9 1e3 2 a e9 1dd 3 a e9 1d7 4 a e9 1d1 5 a e9 1cb 6 a e9 1c5 7 a e9 1bf 8 a e9 019 9 a e9 013 a a e9 00d b a e9 007 c a e9 001 d a e9 1fb e a e9 1f5 f a e9 1ef 0 b e9 1e9 1 b e9 1e4 2 b e9 1df 3 b e9 1da 4 b e9 1d5 5 b e9 1d0 6 b e9 1cb 7 b e9 1c6 8 b e9 011 9 b e9 00c a b e9 007 b b e9 002 c b e9 1fd d b e9 1f8 e b e9 1f3 f b e9 1ee 0 c e9 1e9 1 c e9 1e5 2 c e9 1e1 3 c e9 1dd 4 c e9 1d9 5 c e9 1d5 6 c e9 1d1 7 c e9 1cd 8 c e9 009 9 c e9 005 a c e9 001 b c e9 1fd c c e9 1f9 d c e9 1f5 e c e9 1f1 f c e9 1ed 0 d e9 1e9 1 d e9 1e6 2 d e9 1e3 3 d e9 1e0 4 d e9 1dd 5 d e9 1da 6 d e9 1d7 7 d e9 1d4 8 d e9 001 9 d e9 1fe a d e9 1fb b d e9 1f8 c d e9 1f5 d d e9 1f2 e d e9 1ef f d e9 1ec 0 e e9 1e9 1 e e9 1e7 2 e e9 1e5 3 e e9 1e3 4 e e9 1e1 5 e e9 1df 6 e e9 1dd 7 e e9 1db 8 e e9 1f9 9 e e9 1f7 a e e9 1f5 b e e9 1f3 c e e9 1f1 d e e9 1ef e e e9 1ed f e e9 1eb 0 f e9 1e9 1 f e9 1e8 2 f e9 1e7 3 f e9 1e6 4 f e9 1e5 5 f e9 1e4 6 f e9 1e3 7 f e9 1e2 8 f e9 1f1 9 f e9 1f0 a f e9 1ef b f e9 1ee c f e9 1ed d f e9 1ec e f e9 1eb f f e9 1ea 0 0 ea 1ea 1 0 ea 1ea 2 0 ea 1ea 3 0 ea 1ea 4 0 ea 1ea 5 0 ea 1ea 6 0 ea 1ea 7 0 ea 1ea 8 0 ea 1ea 9 0 ea 1ea a 0 ea 1ea b 0 ea 1ea c 0 ea 1ea d 0 ea 1ea e 0 ea 1ea f 0 ea 1ea 0 1 ea 1ea 1 1 ea 1eb 2 1 ea 1ec 3 1 ea 1ed 4 1 ea 1ee 5 1 ea 1ef 6 1 ea 1f0 7 1 ea 1f1 8 1 ea 1e2 9 1 ea 1e3 a 1 ea 1e4 b 1 ea 1e5 c 1 ea 1e6 d 1 ea 1e7 e 1 ea 1e8 f 1 ea 1e9 0 2 ea 1ea 1 2 ea 1ec 2 2 ea 1ee 3 2 ea 1f0 4 2 ea 1f2 5 2 ea 1f4 6 2 ea 1f6 7 2 ea 1f8 8 2 ea 1da 9 2 ea 1dc a 2 ea 1de b 2 ea 1e0 c 2 ea 1e2 d 2 ea 1e4 e 2 ea 1e6 f 2 ea 1e8 0 3 ea 1ea 1 3 ea 1ed 2 3 ea 1f0 3 3 ea 1f3 4 3 ea 1f6 5 3 ea 1f9 6 3 ea 1fc 7 3 ea 1ff 8 3 ea 1d2 9 3 ea 1d5 a 3 ea 1d8 b 3 ea 1db c 3 ea 1de d 3 ea 1e1 e 3 ea 1e4 f 3 ea 1e7 0 4 ea 1ea 1 4 ea 1ee 2 4 ea 1f2 3 4 ea 1f6 4 4 ea 1fa 5 4 ea 1fe 6 4 ea 002 7 4 ea 006 8 4 ea 1ca 9 4 ea 1ce a 4 ea 1d2 b 4 ea 1d6 c 4 ea 1da d 4 ea 1de e 4 ea 1e2 f 4 ea 1e6 0 5 ea 1ea 1 5 ea 1ef 2 5 ea 1f4 3 5 ea 1f9 4 5 ea 1fe 5 5 ea 003 6 5 ea 008 7 5 ea 00d 8 5 ea 1c2 9 5 ea 1c7 a 5 ea 1cc b 5 ea 1d1 c 5 ea 1d6 d 5 ea 1db e 5 ea 1e0 f 5 ea 1e5 0 6 ea 1ea 1 6 ea 1f0 2 6 ea 1f6 3 6 ea 1fc 4 6 ea 002 5 6 ea 008 6 6 ea 00e 7 6 ea 014 8 6 ea 1ba 9 6 ea 1c0 a 6 ea 1c6 b 6 ea 1cc c 6 ea 1d2 d 6 ea 1d8 e 6 ea 1de f 6 ea 1e4 0 7 ea 1ea 1 7 ea 1f1 2 7 ea 1f8 3 7 ea 1ff 4 7 ea 006 5 7 ea 00d 6 7 ea 014 7 7 ea 01b 8 7 ea 1b2 9 7 ea 1b9 a 7 ea 1c0 b 7 ea 1c7 c 7 ea 1ce d 7 ea 1d5 e 7 ea 1dc f 7 ea 1e3 0 8 ea 1ea 1 8 ea 1e2 2 8 ea 1da 3 8 ea 1d2 4 8 ea 1ca 5 8 ea 1c2 6 8 ea 1ba 7 8 ea 1b2 8 8 ea 02a 9 8 ea 022 a 8 ea 01a b 8 ea 012 c 8 ea 00a d 8 ea 002 e 8 ea 1fa f 8 ea 1f2 0 9 ea 1ea 1 9 ea 1e3 2 9 ea 1dc 3 9 ea 1d5 4 9 ea 1ce 5 9 ea 1c7 6 9 ea 1c0 7 9 ea 1b9 8 9 ea 022 9 9 ea 01b a 9 ea 014 b 9 ea 00d c 9 ea 006 d 9 ea 1ff e 9 ea 1f8 f 9 ea 1f1 0 a ea 1ea 1 a ea 1e4 2 a ea 1de 3 a ea 1d8 4 a ea 1d2 5 a ea 1cc 6 a ea 1c6 7 a ea 1c0 8 a ea 01a 9 a ea 014 a a ea 00e b a ea 008 c a ea 002 d a ea 1fc e a ea 1f6 f a ea 1f0 0 b ea 1ea 1 b ea 1e5 2 b ea 1e0 3 b ea 1db 4 b ea 1d6 5 b ea 1d1 6 b ea 1cc 7 b ea 1c7 8 b ea 012 9 b ea 00d a b ea 008 b b ea 003 c b ea 1fe d b ea 1f9 e b ea 1f4 f b ea 1ef 0 c ea 1ea 1 c ea 1e6 2 c ea 1e2 3 c ea 1de 4 c ea 1da 5 c ea 1d6 6 c ea 1d2 7 c ea 1ce 8 c ea 00a 9 c ea 006 a c ea 002 b c ea 1fe c c ea 1fa d c ea 1f6 e c ea 1f2 f c ea 1ee 0 d ea 1ea 1 d ea 1e7 2 d ea 1e4 3 d ea 1e1 4 d ea 1de 5 d ea 1db 6 d ea 1d8 7 d ea 1d5 8 d ea 002 9 d ea 1ff a d ea 1fc b d ea 1f9 c d ea 1f6 d d ea 1f3 e d ea 1f0 f d ea 1ed 0 e ea 1ea 1 e ea 1e8 2 e ea 1e6 3 e ea 1e4 4 e ea 1e2 5 e ea 1e0 6 e ea 1de 7 e ea 1dc 8 e ea 1fa 9 e ea 1f8 a e ea 1f6 b e ea 1f4 c e ea 1f2 d e ea 1f0 e e ea 1ee f e ea 1ec 0 f ea 1ea 1 f ea 1e9 2 f ea 1e8 3 f ea 1e7 4 f ea 1e6 5 f ea 1e5 6 f ea 1e4 7 f ea 1e3 8 f ea 1f2 9 f ea 1f1 a f ea 1f0 b f ea 1ef c f ea 1ee d f ea 1ed e f ea 1ec f f ea 1eb 0 0 eb 1eb 1 0 eb 1eb 2 0 eb 1eb 3 0 eb 1eb 4 0 eb 1eb 5 0 eb 1eb 6 0 eb 1eb 7 0 eb 1eb 8 0 eb 1eb 9 0 eb 1eb a 0 eb 1eb b 0 eb 1eb c 0 eb 1eb d 0 eb 1eb e 0 eb 1eb f 0 eb 1eb 0 1 eb 1eb 1 1 eb 1ec 2 1 eb 1ed 3 1 eb 1ee 4 1 eb 1ef 5 1 eb 1f0 6 1 eb 1f1 7 1 eb 1f2 8 1 eb 1e3 9 1 eb 1e4 a 1 eb 1e5 b 1 eb 1e6 c 1 eb 1e7 d 1 eb 1e8 e 1 eb 1e9 f 1 eb 1ea 0 2 eb 1eb 1 2 eb 1ed 2 2 eb 1ef 3 2 eb 1f1 4 2 eb 1f3 5 2 eb 1f5 6 2 eb 1f7 7 2 eb 1f9 8 2 eb 1db 9 2 eb 1dd a 2 eb 1df b 2 eb 1e1 c 2 eb 1e3 d 2 eb 1e5 e 2 eb 1e7 f 2 eb 1e9 0 3 eb 1eb 1 3 eb 1ee 2 3 eb 1f1 3 3 eb 1f4 4 3 eb 1f7 5 3 eb 1fa 6 3 eb 1fd 7 3 eb 000 8 3 eb 1d3 9 3 eb 1d6 a 3 eb 1d9 b 3 eb 1dc c 3 eb 1df d 3 eb 1e2 e 3 eb 1e5 f 3 eb 1e8 0 4 eb 1eb 1 4 eb 1ef 2 4 eb 1f3 3 4 eb 1f7 4 4 eb 1fb 5 4 eb 1ff 6 4 eb 003 7 4 eb 007 8 4 eb 1cb 9 4 eb 1cf a 4 eb 1d3 b 4 eb 1d7 c 4 eb 1db d 4 eb 1df e 4 eb 1e3 f 4 eb 1e7 0 5 eb 1eb 1 5 eb 1f0 2 5 eb 1f5 3 5 eb 1fa 4 5 eb 1ff 5 5 eb 004 6 5 eb 009 7 5 eb 00e 8 5 eb 1c3 9 5 eb 1c8 a 5 eb 1cd b 5 eb 1d2 c 5 eb 1d7 d 5 eb 1dc e 5 eb 1e1 f 5 eb 1e6 0 6 eb 1eb 1 6 eb 1f1 2 6 eb 1f7 3 6 eb 1fd 4 6 eb 003 5 6 eb 009 6 6 eb 00f 7 6 eb 015 8 6 eb 1bb 9 6 eb 1c1 a 6 eb 1c7 b 6 eb 1cd c 6 eb 1d3 d 6 eb 1d9 e 6 eb 1df f 6 eb 1e5 0 7 eb 1eb 1 7 eb 1f2 2 7 eb 1f9 3 7 eb 000 4 7 eb 007 5 7 eb 00e 6 7 eb 015 7 7 eb 01c 8 7 eb 1b3 9 7 eb 1ba a 7 eb 1c1 b 7 eb 1c8 c 7 eb 1cf d 7 eb 1d6 e 7 eb 1dd f 7 eb 1e4 0 8 eb 1eb 1 8 eb 1e3 2 8 eb 1db 3 8 eb 1d3 4 8 eb 1cb 5 8 eb 1c3 6 8 eb 1bb 7 8 eb 1b3 8 8 eb 02b 9 8 eb 023 a 8 eb 01b b 8 eb 013 c 8 eb 00b d 8 eb 003 e 8 eb 1fb f 8 eb 1f3 0 9 eb 1eb 1 9 eb 1e4 2 9 eb 1dd 3 9 eb 1d6 4 9 eb 1cf 5 9 eb 1c8 6 9 eb 1c1 7 9 eb 1ba 8 9 eb 023 9 9 eb 01c a 9 eb 015 b 9 eb 00e c 9 eb 007 d 9 eb 000 e 9 eb 1f9 f 9 eb 1f2 0 a eb 1eb 1 a eb 1e5 2 a eb 1df 3 a eb 1d9 4 a eb 1d3 5 a eb 1cd 6 a eb 1c7 7 a eb 1c1 8 a eb 01b 9 a eb 015 a a eb 00f b a eb 009 c a eb 003 d a eb 1fd e a eb 1f7 f a eb 1f1 0 b eb 1eb 1 b eb 1e6 2 b eb 1e1 3 b eb 1dc 4 b eb 1d7 5 b eb 1d2 6 b eb 1cd 7 b eb 1c8 8 b eb 013 9 b eb 00e a b eb 009 b b eb 004 c b eb 1ff d b eb 1fa e b eb 1f5 f b eb 1f0 0 c eb 1eb 1 c eb 1e7 2 c eb 1e3 3 c eb 1df 4 c eb 1db 5 c eb 1d7 6 c eb 1d3 7 c eb 1cf 8 c eb 00b 9 c eb 007 a c eb 003 b c eb 1ff c c eb 1fb d c eb 1f7 e c eb 1f3 f c eb 1ef 0 d eb 1eb 1 d eb 1e8 2 d eb 1e5 3 d eb 1e2 4 d eb 1df 5 d eb 1dc 6 d eb 1d9 7 d eb 1d6 8 d eb 003 9 d eb 000 a d eb 1fd b d eb 1fa c d eb 1f7 d d eb 1f4 e d eb 1f1 f d eb 1ee 0 e eb 1eb 1 e eb 1e9 2 e eb 1e7 3 e eb 1e5 4 e eb 1e3 5 e eb 1e1 6 e eb 1df 7 e eb 1dd 8 e eb 1fb 9 e eb 1f9 a e eb 1f7 b e eb 1f5 c e eb 1f3 d e eb 1f1 e e eb 1ef f e eb 1ed 0 f eb 1eb 1 f eb 1ea 2 f eb 1e9 3 f eb 1e8 4 f eb 1e7 5 f eb 1e6 6 f eb 1e5 7 f eb 1e4 8 f eb 1f3 9 f eb 1f2 a f eb 1f1 b f eb 1f0 c f eb 1ef d f eb 1ee e f eb 1ed f f eb 1ec 0 0 ec 1ec 1 0 ec 1ec 2 0 ec 1ec 3 0 ec 1ec 4 0 ec 1ec 5 0 ec 1ec 6 0 ec 1ec 7 0 ec 1ec 8 0 ec 1ec 9 0 ec 1ec a 0 ec 1ec b 0 ec 1ec c 0 ec 1ec d 0 ec 1ec e 0 ec 1ec f 0 ec 1ec 0 1 ec 1ec 1 1 ec 1ed 2 1 ec 1ee 3 1 ec 1ef 4 1 ec 1f0 5 1 ec 1f1 6 1 ec 1f2 7 1 ec 1f3 8 1 ec 1e4 9 1 ec 1e5 a 1 ec 1e6 b 1 ec 1e7 c 1 ec 1e8 d 1 ec 1e9 e 1 ec 1ea f 1 ec 1eb 0 2 ec 1ec 1 2 ec 1ee 2 2 ec 1f0 3 2 ec 1f2 4 2 ec 1f4 5 2 ec 1f6 6 2 ec 1f8 7 2 ec 1fa 8 2 ec 1dc 9 2 ec 1de a 2 ec 1e0 b 2 ec 1e2 c 2 ec 1e4 d 2 ec 1e6 e 2 ec 1e8 f 2 ec 1ea 0 3 ec 1ec 1 3 ec 1ef 2 3 ec 1f2 3 3 ec 1f5 4 3 ec 1f8 5 3 ec 1fb 6 3 ec 1fe 7 3 ec 001 8 3 ec 1d4 9 3 ec 1d7 a 3 ec 1da b 3 ec 1dd c 3 ec 1e0 d 3 ec 1e3 e 3 ec 1e6 f 3 ec 1e9 0 4 ec 1ec 1 4 ec 1f0 2 4 ec 1f4 3 4 ec 1f8 4 4 ec 1fc 5 4 ec 000 6 4 ec 004 7 4 ec 008 8 4 ec 1cc 9 4 ec 1d0 a 4 ec 1d4 b 4 ec 1d8 c 4 ec 1dc d 4 ec 1e0 e 4 ec 1e4 f 4 ec 1e8 0 5 ec 1ec 1 5 ec 1f1 2 5 ec 1f6 3 5 ec 1fb 4 5 ec 000 5 5 ec 005 6 5 ec 00a 7 5 ec 00f 8 5 ec 1c4 9 5 ec 1c9 a 5 ec 1ce b 5 ec 1d3 c 5 ec 1d8 d 5 ec 1dd e 5 ec 1e2 f 5 ec 1e7 0 6 ec 1ec 1 6 ec 1f2 2 6 ec 1f8 3 6 ec 1fe 4 6 ec 004 5 6 ec 00a 6 6 ec 010 7 6 ec 016 8 6 ec 1bc 9 6 ec 1c2 a 6 ec 1c8 b 6 ec 1ce c 6 ec 1d4 d 6 ec 1da e 6 ec 1e0 f 6 ec 1e6 0 7 ec 1ec 1 7 ec 1f3 2 7 ec 1fa 3 7 ec 001 4 7 ec 008 5 7 ec 00f 6 7 ec 016 7 7 ec 01d 8 7 ec 1b4 9 7 ec 1bb a 7 ec 1c2 b 7 ec 1c9 c 7 ec 1d0 d 7 ec 1d7 e 7 ec 1de f 7 ec 1e5 0 8 ec 1ec 1 8 ec 1e4 2 8 ec 1dc 3 8 ec 1d4 4 8 ec 1cc 5 8 ec 1c4 6 8 ec 1bc 7 8 ec 1b4 8 8 ec 02c 9 8 ec 024 a 8 ec 01c b 8 ec 014 c 8 ec 00c d 8 ec 004 e 8 ec 1fc f 8 ec 1f4 0 9 ec 1ec 1 9 ec 1e5 2 9 ec 1de 3 9 ec 1d7 4 9 ec 1d0 5 9 ec 1c9 6 9 ec 1c2 7 9 ec 1bb 8 9 ec 024 9 9 ec 01d a 9 ec 016 b 9 ec 00f c 9 ec 008 d 9 ec 001 e 9 ec 1fa f 9 ec 1f3 0 a ec 1ec 1 a ec 1e6 2 a ec 1e0 3 a ec 1da 4 a ec 1d4 5 a ec 1ce 6 a ec 1c8 7 a ec 1c2 8 a ec 01c 9 a ec 016 a a ec 010 b a ec 00a c a ec 004 d a ec 1fe e a ec 1f8 f a ec 1f2 0 b ec 1ec 1 b ec 1e7 2 b ec 1e2 3 b ec 1dd 4 b ec 1d8 5 b ec 1d3 6 b ec 1ce 7 b ec 1c9 8 b ec 014 9 b ec 00f a b ec 00a b b ec 005 c b ec 000 d b ec 1fb e b ec 1f6 f b ec 1f1 0 c ec 1ec 1 c ec 1e8 2 c ec 1e4 3 c ec 1e0 4 c ec 1dc 5 c ec 1d8 6 c ec 1d4 7 c ec 1d0 8 c ec 00c 9 c ec 008 a c ec 004 b c ec 000 c c ec 1fc d c ec 1f8 e c ec 1f4 f c ec 1f0 0 d ec 1ec 1 d ec 1e9 2 d ec 1e6 3 d ec 1e3 4 d ec 1e0 5 d ec 1dd 6 d ec 1da 7 d ec 1d7 8 d ec 004 9 d ec 001 a d ec 1fe b d ec 1fb c d ec 1f8 d d ec 1f5 e d ec 1f2 f d ec 1ef 0 e ec 1ec 1 e ec 1ea 2 e ec 1e8 3 e ec 1e6 4 e ec 1e4 5 e ec 1e2 6 e ec 1e0 7 e ec 1de 8 e ec 1fc 9 e ec 1fa a e ec 1f8 b e ec 1f6 c e ec 1f4 d e ec 1f2 e e ec 1f0 f e ec 1ee 0 f ec 1ec 1 f ec 1eb 2 f ec 1ea 3 f ec 1e9 4 f ec 1e8 5 f ec 1e7 6 f ec 1e6 7 f ec 1e5 8 f ec 1f4 9 f ec 1f3 a f ec 1f2 b f ec 1f1 c f ec 1f0 d f ec 1ef e f ec 1ee f f ec 1ed 0 0 ed 1ed 1 0 ed 1ed 2 0 ed 1ed 3 0 ed 1ed 4 0 ed 1ed 5 0 ed 1ed 6 0 ed 1ed 7 0 ed 1ed 8 0 ed 1ed 9 0 ed 1ed a 0 ed 1ed b 0 ed 1ed c 0 ed 1ed d 0 ed 1ed e 0 ed 1ed f 0 ed 1ed 0 1 ed 1ed 1 1 ed 1ee 2 1 ed 1ef 3 1 ed 1f0 4 1 ed 1f1 5 1 ed 1f2 6 1 ed 1f3 7 1 ed 1f4 8 1 ed 1e5 9 1 ed 1e6 a 1 ed 1e7 b 1 ed 1e8 c 1 ed 1e9 d 1 ed 1ea e 1 ed 1eb f 1 ed 1ec 0 2 ed 1ed 1 2 ed 1ef 2 2 ed 1f1 3 2 ed 1f3 4 2 ed 1f5 5 2 ed 1f7 6 2 ed 1f9 7 2 ed 1fb 8 2 ed 1dd 9 2 ed 1df a 2 ed 1e1 b 2 ed 1e3 c 2 ed 1e5 d 2 ed 1e7 e 2 ed 1e9 f 2 ed 1eb 0 3 ed 1ed 1 3 ed 1f0 2 3 ed 1f3 3 3 ed 1f6 4 3 ed 1f9 5 3 ed 1fc 6 3 ed 1ff 7 3 ed 002 8 3 ed 1d5 9 3 ed 1d8 a 3 ed 1db b 3 ed 1de c 3 ed 1e1 d 3 ed 1e4 e 3 ed 1e7 f 3 ed 1ea 0 4 ed 1ed 1 4 ed 1f1 2 4 ed 1f5 3 4 ed 1f9 4 4 ed 1fd 5 4 ed 001 6 4 ed 005 7 4 ed 009 8 4 ed 1cd 9 4 ed 1d1 a 4 ed 1d5 b 4 ed 1d9 c 4 ed 1dd d 4 ed 1e1 e 4 ed 1e5 f 4 ed 1e9 0 5 ed 1ed 1 5 ed 1f2 2 5 ed 1f7 3 5 ed 1fc 4 5 ed 001 5 5 ed 006 6 5 ed 00b 7 5 ed 010 8 5 ed 1c5 9 5 ed 1ca a 5 ed 1cf b 5 ed 1d4 c 5 ed 1d9 d 5 ed 1de e 5 ed 1e3 f 5 ed 1e8 0 6 ed 1ed 1 6 ed 1f3 2 6 ed 1f9 3 6 ed 1ff 4 6 ed 005 5 6 ed 00b 6 6 ed 011 7 6 ed 017 8 6 ed 1bd 9 6 ed 1c3 a 6 ed 1c9 b 6 ed 1cf c 6 ed 1d5 d 6 ed 1db e 6 ed 1e1 f 6 ed 1e7 0 7 ed 1ed 1 7 ed 1f4 2 7 ed 1fb 3 7 ed 002 4 7 ed 009 5 7 ed 010 6 7 ed 017 7 7 ed 01e 8 7 ed 1b5 9 7 ed 1bc a 7 ed 1c3 b 7 ed 1ca c 7 ed 1d1 d 7 ed 1d8 e 7 ed 1df f 7 ed 1e6 0 8 ed 1ed 1 8 ed 1e5 2 8 ed 1dd 3 8 ed 1d5 4 8 ed 1cd 5 8 ed 1c5 6 8 ed 1bd 7 8 ed 1b5 8 8 ed 02d 9 8 ed 025 a 8 ed 01d b 8 ed 015 c 8 ed 00d d 8 ed 005 e 8 ed 1fd f 8 ed 1f5 0 9 ed 1ed 1 9 ed 1e6 2 9 ed 1df 3 9 ed 1d8 4 9 ed 1d1 5 9 ed 1ca 6 9 ed 1c3 7 9 ed 1bc 8 9 ed 025 9 9 ed 01e a 9 ed 017 b 9 ed 010 c 9 ed 009 d 9 ed 002 e 9 ed 1fb f 9 ed 1f4 0 a ed 1ed 1 a ed 1e7 2 a ed 1e1 3 a ed 1db 4 a ed 1d5 5 a ed 1cf 6 a ed 1c9 7 a ed 1c3 8 a ed 01d 9 a ed 017 a a ed 011 b a ed 00b c a ed 005 d a ed 1ff e a ed 1f9 f a ed 1f3 0 b ed 1ed 1 b ed 1e8 2 b ed 1e3 3 b ed 1de 4 b ed 1d9 5 b ed 1d4 6 b ed 1cf 7 b ed 1ca 8 b ed 015 9 b ed 010 a b ed 00b b b ed 006 c b ed 001 d b ed 1fc e b ed 1f7 f b ed 1f2 0 c ed 1ed 1 c ed 1e9 2 c ed 1e5 3 c ed 1e1 4 c ed 1dd 5 c ed 1d9 6 c ed 1d5 7 c ed 1d1 8 c ed 00d 9 c ed 009 a c ed 005 b c ed 001 c c ed 1fd d c ed 1f9 e c ed 1f5 f c ed 1f1 0 d ed 1ed 1 d ed 1ea 2 d ed 1e7 3 d ed 1e4 4 d ed 1e1 5 d ed 1de 6 d ed 1db 7 d ed 1d8 8 d ed 005 9 d ed 002 a d ed 1ff b d ed 1fc c d ed 1f9 d d ed 1f6 e d ed 1f3 f d ed 1f0 0 e ed 1ed 1 e ed 1eb 2 e ed 1e9 3 e ed 1e7 4 e ed 1e5 5 e ed 1e3 6 e ed 1e1 7 e ed 1df 8 e ed 1fd 9 e ed 1fb a e ed 1f9 b e ed 1f7 c e ed 1f5 d e ed 1f3 e e ed 1f1 f e ed 1ef 0 f ed 1ed 1 f ed 1ec 2 f ed 1eb 3 f ed 1ea 4 f ed 1e9 5 f ed 1e8 6 f ed 1e7 7 f ed 1e6 8 f ed 1f5 9 f ed 1f4 a f ed 1f3 b f ed 1f2 c f ed 1f1 d f ed 1f0 e f ed 1ef f f ed 1ee 0 0 ee 1ee 1 0 ee 1ee 2 0 ee 1ee 3 0 ee 1ee 4 0 ee 1ee 5 0 ee 1ee 6 0 ee 1ee 7 0 ee 1ee 8 0 ee 1ee 9 0 ee 1ee a 0 ee 1ee b 0 ee 1ee c 0 ee 1ee d 0 ee 1ee e 0 ee 1ee f 0 ee 1ee 0 1 ee 1ee 1 1 ee 1ef 2 1 ee 1f0 3 1 ee 1f1 4 1 ee 1f2 5 1 ee 1f3 6 1 ee 1f4 7 1 ee 1f5 8 1 ee 1e6 9 1 ee 1e7 a 1 ee 1e8 b 1 ee 1e9 c 1 ee 1ea d 1 ee 1eb e 1 ee 1ec f 1 ee 1ed 0 2 ee 1ee 1 2 ee 1f0 2 2 ee 1f2 3 2 ee 1f4 4 2 ee 1f6 5 2 ee 1f8 6 2 ee 1fa 7 2 ee 1fc 8 2 ee 1de 9 2 ee 1e0 a 2 ee 1e2 b 2 ee 1e4 c 2 ee 1e6 d 2 ee 1e8 e 2 ee 1ea f 2 ee 1ec 0 3 ee 1ee 1 3 ee 1f1 2 3 ee 1f4 3 3 ee 1f7 4 3 ee 1fa 5 3 ee 1fd 6 3 ee 000 7 3 ee 003 8 3 ee 1d6 9 3 ee 1d9 a 3 ee 1dc b 3 ee 1df c 3 ee 1e2 d 3 ee 1e5 e 3 ee 1e8 f 3 ee 1eb 0 4 ee 1ee 1 4 ee 1f2 2 4 ee 1f6 3 4 ee 1fa 4 4 ee 1fe 5 4 ee 002 6 4 ee 006 7 4 ee 00a 8 4 ee 1ce 9 4 ee 1d2 a 4 ee 1d6 b 4 ee 1da c 4 ee 1de d 4 ee 1e2 e 4 ee 1e6 f 4 ee 1ea 0 5 ee 1ee 1 5 ee 1f3 2 5 ee 1f8 3 5 ee 1fd 4 5 ee 002 5 5 ee 007 6 5 ee 00c 7 5 ee 011 8 5 ee 1c6 9 5 ee 1cb a 5 ee 1d0 b 5 ee 1d5 c 5 ee 1da d 5 ee 1df e 5 ee 1e4 f 5 ee 1e9 0 6 ee 1ee 1 6 ee 1f4 2 6 ee 1fa 3 6 ee 000 4 6 ee 006 5 6 ee 00c 6 6 ee 012 7 6 ee 018 8 6 ee 1be 9 6 ee 1c4 a 6 ee 1ca b 6 ee 1d0 c 6 ee 1d6 d 6 ee 1dc e 6 ee 1e2 f 6 ee 1e8 0 7 ee 1ee 1 7 ee 1f5 2 7 ee 1fc 3 7 ee 003 4 7 ee 00a 5 7 ee 011 6 7 ee 018 7 7 ee 01f 8 7 ee 1b6 9 7 ee 1bd a 7 ee 1c4 b 7 ee 1cb c 7 ee 1d2 d 7 ee 1d9 e 7 ee 1e0 f 7 ee 1e7 0 8 ee 1ee 1 8 ee 1e6 2 8 ee 1de 3 8 ee 1d6 4 8 ee 1ce 5 8 ee 1c6 6 8 ee 1be 7 8 ee 1b6 8 8 ee 02e 9 8 ee 026 a 8 ee 01e b 8 ee 016 c 8 ee 00e d 8 ee 006 e 8 ee 1fe f 8 ee 1f6 0 9 ee 1ee 1 9 ee 1e7 2 9 ee 1e0 3 9 ee 1d9 4 9 ee 1d2 5 9 ee 1cb 6 9 ee 1c4 7 9 ee 1bd 8 9 ee 026 9 9 ee 01f a 9 ee 018 b 9 ee 011 c 9 ee 00a d 9 ee 003 e 9 ee 1fc f 9 ee 1f5 0 a ee 1ee 1 a ee 1e8 2 a ee 1e2 3 a ee 1dc 4 a ee 1d6 5 a ee 1d0 6 a ee 1ca 7 a ee 1c4 8 a ee 01e 9 a ee 018 a a ee 012 b a ee 00c c a ee 006 d a ee 000 e a ee 1fa f a ee 1f4 0 b ee 1ee 1 b ee 1e9 2 b ee 1e4 3 b ee 1df 4 b ee 1da 5 b ee 1d5 6 b ee 1d0 7 b ee 1cb 8 b ee 016 9 b ee 011 a b ee 00c b b ee 007 c b ee 002 d b ee 1fd e b ee 1f8 f b ee 1f3 0 c ee 1ee 1 c ee 1ea 2 c ee 1e6 3 c ee 1e2 4 c ee 1de 5 c ee 1da 6 c ee 1d6 7 c ee 1d2 8 c ee 00e 9 c ee 00a a c ee 006 b c ee 002 c c ee 1fe d c ee 1fa e c ee 1f6 f c ee 1f2 0 d ee 1ee 1 d ee 1eb 2 d ee 1e8 3 d ee 1e5 4 d ee 1e2 5 d ee 1df 6 d ee 1dc 7 d ee 1d9 8 d ee 006 9 d ee 003 a d ee 000 b d ee 1fd c d ee 1fa d d ee 1f7 e d ee 1f4 f d ee 1f1 0 e ee 1ee 1 e ee 1ec 2 e ee 1ea 3 e ee 1e8 4 e ee 1e6 5 e ee 1e4 6 e ee 1e2 7 e ee 1e0 8 e ee 1fe 9 e ee 1fc a e ee 1fa b e ee 1f8 c e ee 1f6 d e ee 1f4 e e ee 1f2 f e ee 1f0 0 f ee 1ee 1 f ee 1ed 2 f ee 1ec 3 f ee 1eb 4 f ee 1ea 5 f ee 1e9 6 f ee 1e8 7 f ee 1e7 8 f ee 1f6 9 f ee 1f5 a f ee 1f4 b f ee 1f3 c f ee 1f2 d f ee 1f1 e f ee 1f0 f f ee 1ef 0 0 ef 1ef 1 0 ef 1ef 2 0 ef 1ef 3 0 ef 1ef 4 0 ef 1ef 5 0 ef 1ef 6 0 ef 1ef 7 0 ef 1ef 8 0 ef 1ef 9 0 ef 1ef a 0 ef 1ef b 0 ef 1ef c 0 ef 1ef d 0 ef 1ef e 0 ef 1ef f 0 ef 1ef 0 1 ef 1ef 1 1 ef 1f0 2 1 ef 1f1 3 1 ef 1f2 4 1 ef 1f3 5 1 ef 1f4 6 1 ef 1f5 7 1 ef 1f6 8 1 ef 1e7 9 1 ef 1e8 a 1 ef 1e9 b 1 ef 1ea c 1 ef 1eb d 1 ef 1ec e 1 ef 1ed f 1 ef 1ee 0 2 ef 1ef 1 2 ef 1f1 2 2 ef 1f3 3 2 ef 1f5 4 2 ef 1f7 5 2 ef 1f9 6 2 ef 1fb 7 2 ef 1fd 8 2 ef 1df 9 2 ef 1e1 a 2 ef 1e3 b 2 ef 1e5 c 2 ef 1e7 d 2 ef 1e9 e 2 ef 1eb f 2 ef 1ed 0 3 ef 1ef 1 3 ef 1f2 2 3 ef 1f5 3 3 ef 1f8 4 3 ef 1fb 5 3 ef 1fe 6 3 ef 001 7 3 ef 004 8 3 ef 1d7 9 3 ef 1da a 3 ef 1dd b 3 ef 1e0 c 3 ef 1e3 d 3 ef 1e6 e 3 ef 1e9 f 3 ef 1ec 0 4 ef 1ef 1 4 ef 1f3 2 4 ef 1f7 3 4 ef 1fb 4 4 ef 1ff 5 4 ef 003 6 4 ef 007 7 4 ef 00b 8 4 ef 1cf 9 4 ef 1d3 a 4 ef 1d7 b 4 ef 1db c 4 ef 1df d 4 ef 1e3 e 4 ef 1e7 f 4 ef 1eb 0 5 ef 1ef 1 5 ef 1f4 2 5 ef 1f9 3 5 ef 1fe 4 5 ef 003 5 5 ef 008 6 5 ef 00d 7 5 ef 012 8 5 ef 1c7 9 5 ef 1cc a 5 ef 1d1 b 5 ef 1d6 c 5 ef 1db d 5 ef 1e0 e 5 ef 1e5 f 5 ef 1ea 0 6 ef 1ef 1 6 ef 1f5 2 6 ef 1fb 3 6 ef 001 4 6 ef 007 5 6 ef 00d 6 6 ef 013 7 6 ef 019 8 6 ef 1bf 9 6 ef 1c5 a 6 ef 1cb b 6 ef 1d1 c 6 ef 1d7 d 6 ef 1dd e 6 ef 1e3 f 6 ef 1e9 0 7 ef 1ef 1 7 ef 1f6 2 7 ef 1fd 3 7 ef 004 4 7 ef 00b 5 7 ef 012 6 7 ef 019 7 7 ef 020 8 7 ef 1b7 9 7 ef 1be a 7 ef 1c5 b 7 ef 1cc c 7 ef 1d3 d 7 ef 1da e 7 ef 1e1 f 7 ef 1e8 0 8 ef 1ef 1 8 ef 1e7 2 8 ef 1df 3 8 ef 1d7 4 8 ef 1cf 5 8 ef 1c7 6 8 ef 1bf 7 8 ef 1b7 8 8 ef 02f 9 8 ef 027 a 8 ef 01f b 8 ef 017 c 8 ef 00f d 8 ef 007 e 8 ef 1ff f 8 ef 1f7 0 9 ef 1ef 1 9 ef 1e8 2 9 ef 1e1 3 9 ef 1da 4 9 ef 1d3 5 9 ef 1cc 6 9 ef 1c5 7 9 ef 1be 8 9 ef 027 9 9 ef 020 a 9 ef 019 b 9 ef 012 c 9 ef 00b d 9 ef 004 e 9 ef 1fd f 9 ef 1f6 0 a ef 1ef 1 a ef 1e9 2 a ef 1e3 3 a ef 1dd 4 a ef 1d7 5 a ef 1d1 6 a ef 1cb 7 a ef 1c5 8 a ef 01f 9 a ef 019 a a ef 013 b a ef 00d c a ef 007 d a ef 001 e a ef 1fb f a ef 1f5 0 b ef 1ef 1 b ef 1ea 2 b ef 1e5 3 b ef 1e0 4 b ef 1db 5 b ef 1d6 6 b ef 1d1 7 b ef 1cc 8 b ef 017 9 b ef 012 a b ef 00d b b ef 008 c b ef 003 d b ef 1fe e b ef 1f9 f b ef 1f4 0 c ef 1ef 1 c ef 1eb 2 c ef 1e7 3 c ef 1e3 4 c ef 1df 5 c ef 1db 6 c ef 1d7 7 c ef 1d3 8 c ef 00f 9 c ef 00b a c ef 007 b c ef 003 c c ef 1ff d c ef 1fb e c ef 1f7 f c ef 1f3 0 d ef 1ef 1 d ef 1ec 2 d ef 1e9 3 d ef 1e6 4 d ef 1e3 5 d ef 1e0 6 d ef 1dd 7 d ef 1da 8 d ef 007 9 d ef 004 a d ef 001 b d ef 1fe c d ef 1fb d d ef 1f8 e d ef 1f5 f d ef 1f2 0 e ef 1ef 1 e ef 1ed 2 e ef 1eb 3 e ef 1e9 4 e ef 1e7 5 e ef 1e5 6 e ef 1e3 7 e ef 1e1 8 e ef 1ff 9 e ef 1fd a e ef 1fb b e ef 1f9 c e ef 1f7 d e ef 1f5 e e ef 1f3 f e ef 1f1 0 f ef 1ef 1 f ef 1ee 2 f ef 1ed 3 f ef 1ec 4 f ef 1eb 5 f ef 1ea 6 f ef 1e9 7 f ef 1e8 8 f ef 1f7 9 f ef 1f6 a f ef 1f5 b f ef 1f4 c f ef 1f3 d f ef 1f2 e f ef 1f1 f f ef 1f0 0 0 f0 1f0 1 0 f0 1f0 2 0 f0 1f0 3 0 f0 1f0 4 0 f0 1f0 5 0 f0 1f0 6 0 f0 1f0 7 0 f0 1f0 8 0 f0 1f0 9 0 f0 1f0 a 0 f0 1f0 b 0 f0 1f0 c 0 f0 1f0 d 0 f0 1f0 e 0 f0 1f0 f 0 f0 1f0 0 1 f0 1f0 1 1 f0 1f1 2 1 f0 1f2 3 1 f0 1f3 4 1 f0 1f4 5 1 f0 1f5 6 1 f0 1f6 7 1 f0 1f7 8 1 f0 1e8 9 1 f0 1e9 a 1 f0 1ea b 1 f0 1eb c 1 f0 1ec d 1 f0 1ed e 1 f0 1ee f 1 f0 1ef 0 2 f0 1f0 1 2 f0 1f2 2 2 f0 1f4 3 2 f0 1f6 4 2 f0 1f8 5 2 f0 1fa 6 2 f0 1fc 7 2 f0 1fe 8 2 f0 1e0 9 2 f0 1e2 a 2 f0 1e4 b 2 f0 1e6 c 2 f0 1e8 d 2 f0 1ea e 2 f0 1ec f 2 f0 1ee 0 3 f0 1f0 1 3 f0 1f3 2 3 f0 1f6 3 3 f0 1f9 4 3 f0 1fc 5 3 f0 1ff 6 3 f0 002 7 3 f0 005 8 3 f0 1d8 9 3 f0 1db a 3 f0 1de b 3 f0 1e1 c 3 f0 1e4 d 3 f0 1e7 e 3 f0 1ea f 3 f0 1ed 0 4 f0 1f0 1 4 f0 1f4 2 4 f0 1f8 3 4 f0 1fc 4 4 f0 000 5 4 f0 004 6 4 f0 008 7 4 f0 00c 8 4 f0 1d0 9 4 f0 1d4 a 4 f0 1d8 b 4 f0 1dc c 4 f0 1e0 d 4 f0 1e4 e 4 f0 1e8 f 4 f0 1ec 0 5 f0 1f0 1 5 f0 1f5 2 5 f0 1fa 3 5 f0 1ff 4 5 f0 004 5 5 f0 009 6 5 f0 00e 7 5 f0 013 8 5 f0 1c8 9 5 f0 1cd a 5 f0 1d2 b 5 f0 1d7 c 5 f0 1dc d 5 f0 1e1 e 5 f0 1e6 f 5 f0 1eb 0 6 f0 1f0 1 6 f0 1f6 2 6 f0 1fc 3 6 f0 002 4 6 f0 008 5 6 f0 00e 6 6 f0 014 7 6 f0 01a 8 6 f0 1c0 9 6 f0 1c6 a 6 f0 1cc b 6 f0 1d2 c 6 f0 1d8 d 6 f0 1de e 6 f0 1e4 f 6 f0 1ea 0 7 f0 1f0 1 7 f0 1f7 2 7 f0 1fe 3 7 f0 005 4 7 f0 00c 5 7 f0 013 6 7 f0 01a 7 7 f0 021 8 7 f0 1b8 9 7 f0 1bf a 7 f0 1c6 b 7 f0 1cd c 7 f0 1d4 d 7 f0 1db e 7 f0 1e2 f 7 f0 1e9 0 8 f0 1f0 1 8 f0 1e8 2 8 f0 1e0 3 8 f0 1d8 4 8 f0 1d0 5 8 f0 1c8 6 8 f0 1c0 7 8 f0 1b8 8 8 f0 030 9 8 f0 028 a 8 f0 020 b 8 f0 018 c 8 f0 010 d 8 f0 008 e 8 f0 000 f 8 f0 1f8 0 9 f0 1f0 1 9 f0 1e9 2 9 f0 1e2 3 9 f0 1db 4 9 f0 1d4 5 9 f0 1cd 6 9 f0 1c6 7 9 f0 1bf 8 9 f0 028 9 9 f0 021 a 9 f0 01a b 9 f0 013 c 9 f0 00c d 9 f0 005 e 9 f0 1fe f 9 f0 1f7 0 a f0 1f0 1 a f0 1ea 2 a f0 1e4 3 a f0 1de 4 a f0 1d8 5 a f0 1d2 6 a f0 1cc 7 a f0 1c6 8 a f0 020 9 a f0 01a a a f0 014 b a f0 00e c a f0 008 d a f0 002 e a f0 1fc f a f0 1f6 0 b f0 1f0 1 b f0 1eb 2 b f0 1e6 3 b f0 1e1 4 b f0 1dc 5 b f0 1d7 6 b f0 1d2 7 b f0 1cd 8 b f0 018 9 b f0 013 a b f0 00e b b f0 009 c b f0 004 d b f0 1ff e b f0 1fa f b f0 1f5 0 c f0 1f0 1 c f0 1ec 2 c f0 1e8 3 c f0 1e4 4 c f0 1e0 5 c f0 1dc 6 c f0 1d8 7 c f0 1d4 8 c f0 010 9 c f0 00c a c f0 008 b c f0 004 c c f0 000 d c f0 1fc e c f0 1f8 f c f0 1f4 0 d f0 1f0 1 d f0 1ed 2 d f0 1ea 3 d f0 1e7 4 d f0 1e4 5 d f0 1e1 6 d f0 1de 7 d f0 1db 8 d f0 008 9 d f0 005 a d f0 002 b d f0 1ff c d f0 1fc d d f0 1f9 e d f0 1f6 f d f0 1f3 0 e f0 1f0 1 e f0 1ee 2 e f0 1ec 3 e f0 1ea 4 e f0 1e8 5 e f0 1e6 6 e f0 1e4 7 e f0 1e2 8 e f0 000 9 e f0 1fe a e f0 1fc b e f0 1fa c e f0 1f8 d e f0 1f6 e e f0 1f4 f e f0 1f2 0 f f0 1f0 1 f f0 1ef 2 f f0 1ee 3 f f0 1ed 4 f f0 1ec 5 f f0 1eb 6 f f0 1ea 7 f f0 1e9 8 f f0 1f8 9 f f0 1f7 a f f0 1f6 b f f0 1f5 c f f0 1f4 d f f0 1f3 e f f0 1f2 f f f0 1f1 0 0 f1 1f1 1 0 f1 1f1 2 0 f1 1f1 3 0 f1 1f1 4 0 f1 1f1 5 0 f1 1f1 6 0 f1 1f1 7 0 f1 1f1 8 0 f1 1f1 9 0 f1 1f1 a 0 f1 1f1 b 0 f1 1f1 c 0 f1 1f1 d 0 f1 1f1 e 0 f1 1f1 f 0 f1 1f1 0 1 f1 1f1 1 1 f1 1f2 2 1 f1 1f3 3 1 f1 1f4 4 1 f1 1f5 5 1 f1 1f6 6 1 f1 1f7 7 1 f1 1f8 8 1 f1 1e9 9 1 f1 1ea a 1 f1 1eb b 1 f1 1ec c 1 f1 1ed d 1 f1 1ee e 1 f1 1ef f 1 f1 1f0 0 2 f1 1f1 1 2 f1 1f3 2 2 f1 1f5 3 2 f1 1f7 4 2 f1 1f9 5 2 f1 1fb 6 2 f1 1fd 7 2 f1 1ff 8 2 f1 1e1 9 2 f1 1e3 a 2 f1 1e5 b 2 f1 1e7 c 2 f1 1e9 d 2 f1 1eb e 2 f1 1ed f 2 f1 1ef 0 3 f1 1f1 1 3 f1 1f4 2 3 f1 1f7 3 3 f1 1fa 4 3 f1 1fd 5 3 f1 000 6 3 f1 003 7 3 f1 006 8 3 f1 1d9 9 3 f1 1dc a 3 f1 1df b 3 f1 1e2 c 3 f1 1e5 d 3 f1 1e8 e 3 f1 1eb f 3 f1 1ee 0 4 f1 1f1 1 4 f1 1f5 2 4 f1 1f9 3 4 f1 1fd 4 4 f1 001 5 4 f1 005 6 4 f1 009 7 4 f1 00d 8 4 f1 1d1 9 4 f1 1d5 a 4 f1 1d9 b 4 f1 1dd c 4 f1 1e1 d 4 f1 1e5 e 4 f1 1e9 f 4 f1 1ed 0 5 f1 1f1 1 5 f1 1f6 2 5 f1 1fb 3 5 f1 000 4 5 f1 005 5 5 f1 00a 6 5 f1 00f 7 5 f1 014 8 5 f1 1c9 9 5 f1 1ce a 5 f1 1d3 b 5 f1 1d8 c 5 f1 1dd d 5 f1 1e2 e 5 f1 1e7 f 5 f1 1ec 0 6 f1 1f1 1 6 f1 1f7 2 6 f1 1fd 3 6 f1 003 4 6 f1 009 5 6 f1 00f 6 6 f1 015 7 6 f1 01b 8 6 f1 1c1 9 6 f1 1c7 a 6 f1 1cd b 6 f1 1d3 c 6 f1 1d9 d 6 f1 1df e 6 f1 1e5 f 6 f1 1eb 0 7 f1 1f1 1 7 f1 1f8 2 7 f1 1ff 3 7 f1 006 4 7 f1 00d 5 7 f1 014 6 7 f1 01b 7 7 f1 022 8 7 f1 1b9 9 7 f1 1c0 a 7 f1 1c7 b 7 f1 1ce c 7 f1 1d5 d 7 f1 1dc e 7 f1 1e3 f 7 f1 1ea 0 8 f1 1f1 1 8 f1 1e9 2 8 f1 1e1 3 8 f1 1d9 4 8 f1 1d1 5 8 f1 1c9 6 8 f1 1c1 7 8 f1 1b9 8 8 f1 031 9 8 f1 029 a 8 f1 021 b 8 f1 019 c 8 f1 011 d 8 f1 009 e 8 f1 001 f 8 f1 1f9 0 9 f1 1f1 1 9 f1 1ea 2 9 f1 1e3 3 9 f1 1dc 4 9 f1 1d5 5 9 f1 1ce 6 9 f1 1c7 7 9 f1 1c0 8 9 f1 029 9 9 f1 022 a 9 f1 01b b 9 f1 014 c 9 f1 00d d 9 f1 006 e 9 f1 1ff f 9 f1 1f8 0 a f1 1f1 1 a f1 1eb 2 a f1 1e5 3 a f1 1df 4 a f1 1d9 5 a f1 1d3 6 a f1 1cd 7 a f1 1c7 8 a f1 021 9 a f1 01b a a f1 015 b a f1 00f c a f1 009 d a f1 003 e a f1 1fd f a f1 1f7 0 b f1 1f1 1 b f1 1ec 2 b f1 1e7 3 b f1 1e2 4 b f1 1dd 5 b f1 1d8 6 b f1 1d3 7 b f1 1ce 8 b f1 019 9 b f1 014 a b f1 00f b b f1 00a c b f1 005 d b f1 000 e b f1 1fb f b f1 1f6 0 c f1 1f1 1 c f1 1ed 2 c f1 1e9 3 c f1 1e5 4 c f1 1e1 5 c f1 1dd 6 c f1 1d9 7 c f1 1d5 8 c f1 011 9 c f1 00d a c f1 009 b c f1 005 c c f1 001 d c f1 1fd e c f1 1f9 f c f1 1f5 0 d f1 1f1 1 d f1 1ee 2 d f1 1eb 3 d f1 1e8 4 d f1 1e5 5 d f1 1e2 6 d f1 1df 7 d f1 1dc 8 d f1 009 9 d f1 006 a d f1 003 b d f1 000 c d f1 1fd d d f1 1fa e d f1 1f7 f d f1 1f4 0 e f1 1f1 1 e f1 1ef 2 e f1 1ed 3 e f1 1eb 4 e f1 1e9 5 e f1 1e7 6 e f1 1e5 7 e f1 1e3 8 e f1 001 9 e f1 1ff a e f1 1fd b e f1 1fb c e f1 1f9 d e f1 1f7 e e f1 1f5 f e f1 1f3 0 f f1 1f1 1 f f1 1f0 2 f f1 1ef 3 f f1 1ee 4 f f1 1ed 5 f f1 1ec 6 f f1 1eb 7 f f1 1ea 8 f f1 1f9 9 f f1 1f8 a f f1 1f7 b f f1 1f6 c f f1 1f5 d f f1 1f4 e f f1 1f3 f f f1 1f2 0 0 f2 1f2 1 0 f2 1f2 2 0 f2 1f2 3 0 f2 1f2 4 0 f2 1f2 5 0 f2 1f2 6 0 f2 1f2 7 0 f2 1f2 8 0 f2 1f2 9 0 f2 1f2 a 0 f2 1f2 b 0 f2 1f2 c 0 f2 1f2 d 0 f2 1f2 e 0 f2 1f2 f 0 f2 1f2 0 1 f2 1f2 1 1 f2 1f3 2 1 f2 1f4 3 1 f2 1f5 4 1 f2 1f6 5 1 f2 1f7 6 1 f2 1f8 7 1 f2 1f9 8 1 f2 1ea 9 1 f2 1eb a 1 f2 1ec b 1 f2 1ed c 1 f2 1ee d 1 f2 1ef e 1 f2 1f0 f 1 f2 1f1 0 2 f2 1f2 1 2 f2 1f4 2 2 f2 1f6 3 2 f2 1f8 4 2 f2 1fa 5 2 f2 1fc 6 2 f2 1fe 7 2 f2 000 8 2 f2 1e2 9 2 f2 1e4 a 2 f2 1e6 b 2 f2 1e8 c 2 f2 1ea d 2 f2 1ec e 2 f2 1ee f 2 f2 1f0 0 3 f2 1f2 1 3 f2 1f5 2 3 f2 1f8 3 3 f2 1fb 4 3 f2 1fe 5 3 f2 001 6 3 f2 004 7 3 f2 007 8 3 f2 1da 9 3 f2 1dd a 3 f2 1e0 b 3 f2 1e3 c 3 f2 1e6 d 3 f2 1e9 e 3 f2 1ec f 3 f2 1ef 0 4 f2 1f2 1 4 f2 1f6 2 4 f2 1fa 3 4 f2 1fe 4 4 f2 002 5 4 f2 006 6 4 f2 00a 7 4 f2 00e 8 4 f2 1d2 9 4 f2 1d6 a 4 f2 1da b 4 f2 1de c 4 f2 1e2 d 4 f2 1e6 e 4 f2 1ea f 4 f2 1ee 0 5 f2 1f2 1 5 f2 1f7 2 5 f2 1fc 3 5 f2 001 4 5 f2 006 5 5 f2 00b 6 5 f2 010 7 5 f2 015 8 5 f2 1ca 9 5 f2 1cf a 5 f2 1d4 b 5 f2 1d9 c 5 f2 1de d 5 f2 1e3 e 5 f2 1e8 f 5 f2 1ed 0 6 f2 1f2 1 6 f2 1f8 2 6 f2 1fe 3 6 f2 004 4 6 f2 00a 5 6 f2 010 6 6 f2 016 7 6 f2 01c 8 6 f2 1c2 9 6 f2 1c8 a 6 f2 1ce b 6 f2 1d4 c 6 f2 1da d 6 f2 1e0 e 6 f2 1e6 f 6 f2 1ec 0 7 f2 1f2 1 7 f2 1f9 2 7 f2 000 3 7 f2 007 4 7 f2 00e 5 7 f2 015 6 7 f2 01c 7 7 f2 023 8 7 f2 1ba 9 7 f2 1c1 a 7 f2 1c8 b 7 f2 1cf c 7 f2 1d6 d 7 f2 1dd e 7 f2 1e4 f 7 f2 1eb 0 8 f2 1f2 1 8 f2 1ea 2 8 f2 1e2 3 8 f2 1da 4 8 f2 1d2 5 8 f2 1ca 6 8 f2 1c2 7 8 f2 1ba 8 8 f2 032 9 8 f2 02a a 8 f2 022 b 8 f2 01a c 8 f2 012 d 8 f2 00a e 8 f2 002 f 8 f2 1fa 0 9 f2 1f2 1 9 f2 1eb 2 9 f2 1e4 3 9 f2 1dd 4 9 f2 1d6 5 9 f2 1cf 6 9 f2 1c8 7 9 f2 1c1 8 9 f2 02a 9 9 f2 023 a 9 f2 01c b 9 f2 015 c 9 f2 00e d 9 f2 007 e 9 f2 000 f 9 f2 1f9 0 a f2 1f2 1 a f2 1ec 2 a f2 1e6 3 a f2 1e0 4 a f2 1da 5 a f2 1d4 6 a f2 1ce 7 a f2 1c8 8 a f2 022 9 a f2 01c a a f2 016 b a f2 010 c a f2 00a d a f2 004 e a f2 1fe f a f2 1f8 0 b f2 1f2 1 b f2 1ed 2 b f2 1e8 3 b f2 1e3 4 b f2 1de 5 b f2 1d9 6 b f2 1d4 7 b f2 1cf 8 b f2 01a 9 b f2 015 a b f2 010 b b f2 00b c b f2 006 d b f2 001 e b f2 1fc f b f2 1f7 0 c f2 1f2 1 c f2 1ee 2 c f2 1ea 3 c f2 1e6 4 c f2 1e2 5 c f2 1de 6 c f2 1da 7 c f2 1d6 8 c f2 012 9 c f2 00e a c f2 00a b c f2 006 c c f2 002 d c f2 1fe e c f2 1fa f c f2 1f6 0 d f2 1f2 1 d f2 1ef 2 d f2 1ec 3 d f2 1e9 4 d f2 1e6 5 d f2 1e3 6 d f2 1e0 7 d f2 1dd 8 d f2 00a 9 d f2 007 a d f2 004 b d f2 001 c d f2 1fe d d f2 1fb e d f2 1f8 f d f2 1f5 0 e f2 1f2 1 e f2 1f0 2 e f2 1ee 3 e f2 1ec 4 e f2 1ea 5 e f2 1e8 6 e f2 1e6 7 e f2 1e4 8 e f2 002 9 e f2 000 a e f2 1fe b e f2 1fc c e f2 1fa d e f2 1f8 e e f2 1f6 f e f2 1f4 0 f f2 1f2 1 f f2 1f1 2 f f2 1f0 3 f f2 1ef 4 f f2 1ee 5 f f2 1ed 6 f f2 1ec 7 f f2 1eb 8 f f2 1fa 9 f f2 1f9 a f f2 1f8 b f f2 1f7 c f f2 1f6 d f f2 1f5 e f f2 1f4 f f f2 1f3 0 0 f3 1f3 1 0 f3 1f3 2 0 f3 1f3 3 0 f3 1f3 4 0 f3 1f3 5 0 f3 1f3 6 0 f3 1f3 7 0 f3 1f3 8 0 f3 1f3 9 0 f3 1f3 a 0 f3 1f3 b 0 f3 1f3 c 0 f3 1f3 d 0 f3 1f3 e 0 f3 1f3 f 0 f3 1f3 0 1 f3 1f3 1 1 f3 1f4 2 1 f3 1f5 3 1 f3 1f6 4 1 f3 1f7 5 1 f3 1f8 6 1 f3 1f9 7 1 f3 1fa 8 1 f3 1eb 9 1 f3 1ec a 1 f3 1ed b 1 f3 1ee c 1 f3 1ef d 1 f3 1f0 e 1 f3 1f1 f 1 f3 1f2 0 2 f3 1f3 1 2 f3 1f5 2 2 f3 1f7 3 2 f3 1f9 4 2 f3 1fb 5 2 f3 1fd 6 2 f3 1ff 7 2 f3 001 8 2 f3 1e3 9 2 f3 1e5 a 2 f3 1e7 b 2 f3 1e9 c 2 f3 1eb d 2 f3 1ed e 2 f3 1ef f 2 f3 1f1 0 3 f3 1f3 1 3 f3 1f6 2 3 f3 1f9 3 3 f3 1fc 4 3 f3 1ff 5 3 f3 002 6 3 f3 005 7 3 f3 008 8 3 f3 1db 9 3 f3 1de a 3 f3 1e1 b 3 f3 1e4 c 3 f3 1e7 d 3 f3 1ea e 3 f3 1ed f 3 f3 1f0 0 4 f3 1f3 1 4 f3 1f7 2 4 f3 1fb 3 4 f3 1ff 4 4 f3 003 5 4 f3 007 6 4 f3 00b 7 4 f3 00f 8 4 f3 1d3 9 4 f3 1d7 a 4 f3 1db b 4 f3 1df c 4 f3 1e3 d 4 f3 1e7 e 4 f3 1eb f 4 f3 1ef 0 5 f3 1f3 1 5 f3 1f8 2 5 f3 1fd 3 5 f3 002 4 5 f3 007 5 5 f3 00c 6 5 f3 011 7 5 f3 016 8 5 f3 1cb 9 5 f3 1d0 a 5 f3 1d5 b 5 f3 1da c 5 f3 1df d 5 f3 1e4 e 5 f3 1e9 f 5 f3 1ee 0 6 f3 1f3 1 6 f3 1f9 2 6 f3 1ff 3 6 f3 005 4 6 f3 00b 5 6 f3 011 6 6 f3 017 7 6 f3 01d 8 6 f3 1c3 9 6 f3 1c9 a 6 f3 1cf b 6 f3 1d5 c 6 f3 1db d 6 f3 1e1 e 6 f3 1e7 f 6 f3 1ed 0 7 f3 1f3 1 7 f3 1fa 2 7 f3 001 3 7 f3 008 4 7 f3 00f 5 7 f3 016 6 7 f3 01d 7 7 f3 024 8 7 f3 1bb 9 7 f3 1c2 a 7 f3 1c9 b 7 f3 1d0 c 7 f3 1d7 d 7 f3 1de e 7 f3 1e5 f 7 f3 1ec 0 8 f3 1f3 1 8 f3 1eb 2 8 f3 1e3 3 8 f3 1db 4 8 f3 1d3 5 8 f3 1cb 6 8 f3 1c3 7 8 f3 1bb 8 8 f3 033 9 8 f3 02b a 8 f3 023 b 8 f3 01b c 8 f3 013 d 8 f3 00b e 8 f3 003 f 8 f3 1fb 0 9 f3 1f3 1 9 f3 1ec 2 9 f3 1e5 3 9 f3 1de 4 9 f3 1d7 5 9 f3 1d0 6 9 f3 1c9 7 9 f3 1c2 8 9 f3 02b 9 9 f3 024 a 9 f3 01d b 9 f3 016 c 9 f3 00f d 9 f3 008 e 9 f3 001 f 9 f3 1fa 0 a f3 1f3 1 a f3 1ed 2 a f3 1e7 3 a f3 1e1 4 a f3 1db 5 a f3 1d5 6 a f3 1cf 7 a f3 1c9 8 a f3 023 9 a f3 01d a a f3 017 b a f3 011 c a f3 00b d a f3 005 e a f3 1ff f a f3 1f9 0 b f3 1f3 1 b f3 1ee 2 b f3 1e9 3 b f3 1e4 4 b f3 1df 5 b f3 1da 6 b f3 1d5 7 b f3 1d0 8 b f3 01b 9 b f3 016 a b f3 011 b b f3 00c c b f3 007 d b f3 002 e b f3 1fd f b f3 1f8 0 c f3 1f3 1 c f3 1ef 2 c f3 1eb 3 c f3 1e7 4 c f3 1e3 5 c f3 1df 6 c f3 1db 7 c f3 1d7 8 c f3 013 9 c f3 00f a c f3 00b b c f3 007 c c f3 003 d c f3 1ff e c f3 1fb f c f3 1f7 0 d f3 1f3 1 d f3 1f0 2 d f3 1ed 3 d f3 1ea 4 d f3 1e7 5 d f3 1e4 6 d f3 1e1 7 d f3 1de 8 d f3 00b 9 d f3 008 a d f3 005 b d f3 002 c d f3 1ff d d f3 1fc e d f3 1f9 f d f3 1f6 0 e f3 1f3 1 e f3 1f1 2 e f3 1ef 3 e f3 1ed 4 e f3 1eb 5 e f3 1e9 6 e f3 1e7 7 e f3 1e5 8 e f3 003 9 e f3 001 a e f3 1ff b e f3 1fd c e f3 1fb d e f3 1f9 e e f3 1f7 f e f3 1f5 0 f f3 1f3 1 f f3 1f2 2 f f3 1f1 3 f f3 1f0 4 f f3 1ef 5 f f3 1ee 6 f f3 1ed 7 f f3 1ec 8 f f3 1fb 9 f f3 1fa a f f3 1f9 b f f3 1f8 c f f3 1f7 d f f3 1f6 e f f3 1f5 f f f3 1f4 0 0 f4 1f4 1 0 f4 1f4 2 0 f4 1f4 3 0 f4 1f4 4 0 f4 1f4 5 0 f4 1f4 6 0 f4 1f4 7 0 f4 1f4 8 0 f4 1f4 9 0 f4 1f4 a 0 f4 1f4 b 0 f4 1f4 c 0 f4 1f4 d 0 f4 1f4 e 0 f4 1f4 f 0 f4 1f4 0 1 f4 1f4 1 1 f4 1f5 2 1 f4 1f6 3 1 f4 1f7 4 1 f4 1f8 5 1 f4 1f9 6 1 f4 1fa 7 1 f4 1fb 8 1 f4 1ec 9 1 f4 1ed a 1 f4 1ee b 1 f4 1ef c 1 f4 1f0 d 1 f4 1f1 e 1 f4 1f2 f 1 f4 1f3 0 2 f4 1f4 1 2 f4 1f6 2 2 f4 1f8 3 2 f4 1fa 4 2 f4 1fc 5 2 f4 1fe 6 2 f4 000 7 2 f4 002 8 2 f4 1e4 9 2 f4 1e6 a 2 f4 1e8 b 2 f4 1ea c 2 f4 1ec d 2 f4 1ee e 2 f4 1f0 f 2 f4 1f2 0 3 f4 1f4 1 3 f4 1f7 2 3 f4 1fa 3 3 f4 1fd 4 3 f4 000 5 3 f4 003 6 3 f4 006 7 3 f4 009 8 3 f4 1dc 9 3 f4 1df a 3 f4 1e2 b 3 f4 1e5 c 3 f4 1e8 d 3 f4 1eb e 3 f4 1ee f 3 f4 1f1 0 4 f4 1f4 1 4 f4 1f8 2 4 f4 1fc 3 4 f4 000 4 4 f4 004 5 4 f4 008 6 4 f4 00c 7 4 f4 010 8 4 f4 1d4 9 4 f4 1d8 a 4 f4 1dc b 4 f4 1e0 c 4 f4 1e4 d 4 f4 1e8 e 4 f4 1ec f 4 f4 1f0 0 5 f4 1f4 1 5 f4 1f9 2 5 f4 1fe 3 5 f4 003 4 5 f4 008 5 5 f4 00d 6 5 f4 012 7 5 f4 017 8 5 f4 1cc 9 5 f4 1d1 a 5 f4 1d6 b 5 f4 1db c 5 f4 1e0 d 5 f4 1e5 e 5 f4 1ea f 5 f4 1ef 0 6 f4 1f4 1 6 f4 1fa 2 6 f4 000 3 6 f4 006 4 6 f4 00c 5 6 f4 012 6 6 f4 018 7 6 f4 01e 8 6 f4 1c4 9 6 f4 1ca a 6 f4 1d0 b 6 f4 1d6 c 6 f4 1dc d 6 f4 1e2 e 6 f4 1e8 f 6 f4 1ee 0 7 f4 1f4 1 7 f4 1fb 2 7 f4 002 3 7 f4 009 4 7 f4 010 5 7 f4 017 6 7 f4 01e 7 7 f4 025 8 7 f4 1bc 9 7 f4 1c3 a 7 f4 1ca b 7 f4 1d1 c 7 f4 1d8 d 7 f4 1df e 7 f4 1e6 f 7 f4 1ed 0 8 f4 1f4 1 8 f4 1ec 2 8 f4 1e4 3 8 f4 1dc 4 8 f4 1d4 5 8 f4 1cc 6 8 f4 1c4 7 8 f4 1bc 8 8 f4 034 9 8 f4 02c a 8 f4 024 b 8 f4 01c c 8 f4 014 d 8 f4 00c e 8 f4 004 f 8 f4 1fc 0 9 f4 1f4 1 9 f4 1ed 2 9 f4 1e6 3 9 f4 1df 4 9 f4 1d8 5 9 f4 1d1 6 9 f4 1ca 7 9 f4 1c3 8 9 f4 02c 9 9 f4 025 a 9 f4 01e b 9 f4 017 c 9 f4 010 d 9 f4 009 e 9 f4 002 f 9 f4 1fb 0 a f4 1f4 1 a f4 1ee 2 a f4 1e8 3 a f4 1e2 4 a f4 1dc 5 a f4 1d6 6 a f4 1d0 7 a f4 1ca 8 a f4 024 9 a f4 01e a a f4 018 b a f4 012 c a f4 00c d a f4 006 e a f4 000 f a f4 1fa 0 b f4 1f4 1 b f4 1ef 2 b f4 1ea 3 b f4 1e5 4 b f4 1e0 5 b f4 1db 6 b f4 1d6 7 b f4 1d1 8 b f4 01c 9 b f4 017 a b f4 012 b b f4 00d c b f4 008 d b f4 003 e b f4 1fe f b f4 1f9 0 c f4 1f4 1 c f4 1f0 2 c f4 1ec 3 c f4 1e8 4 c f4 1e4 5 c f4 1e0 6 c f4 1dc 7 c f4 1d8 8 c f4 014 9 c f4 010 a c f4 00c b c f4 008 c c f4 004 d c f4 000 e c f4 1fc f c f4 1f8 0 d f4 1f4 1 d f4 1f1 2 d f4 1ee 3 d f4 1eb 4 d f4 1e8 5 d f4 1e5 6 d f4 1e2 7 d f4 1df 8 d f4 00c 9 d f4 009 a d f4 006 b d f4 003 c d f4 000 d d f4 1fd e d f4 1fa f d f4 1f7 0 e f4 1f4 1 e f4 1f2 2 e f4 1f0 3 e f4 1ee 4 e f4 1ec 5 e f4 1ea 6 e f4 1e8 7 e f4 1e6 8 e f4 004 9 e f4 002 a e f4 000 b e f4 1fe c e f4 1fc d e f4 1fa e e f4 1f8 f e f4 1f6 0 f f4 1f4 1 f f4 1f3 2 f f4 1f2 3 f f4 1f1 4 f f4 1f0 5 f f4 1ef 6 f f4 1ee 7 f f4 1ed 8 f f4 1fc 9 f f4 1fb a f f4 1fa b f f4 1f9 c f f4 1f8 d f f4 1f7 e f f4 1f6 f f f4 1f5 0 0 f5 1f5 1 0 f5 1f5 2 0 f5 1f5 3 0 f5 1f5 4 0 f5 1f5 5 0 f5 1f5 6 0 f5 1f5 7 0 f5 1f5 8 0 f5 1f5 9 0 f5 1f5 a 0 f5 1f5 b 0 f5 1f5 c 0 f5 1f5 d 0 f5 1f5 e 0 f5 1f5 f 0 f5 1f5 0 1 f5 1f5 1 1 f5 1f6 2 1 f5 1f7 3 1 f5 1f8 4 1 f5 1f9 5 1 f5 1fa 6 1 f5 1fb 7 1 f5 1fc 8 1 f5 1ed 9 1 f5 1ee a 1 f5 1ef b 1 f5 1f0 c 1 f5 1f1 d 1 f5 1f2 e 1 f5 1f3 f 1 f5 1f4 0 2 f5 1f5 1 2 f5 1f7 2 2 f5 1f9 3 2 f5 1fb 4 2 f5 1fd 5 2 f5 1ff 6 2 f5 001 7 2 f5 003 8 2 f5 1e5 9 2 f5 1e7 a 2 f5 1e9 b 2 f5 1eb c 2 f5 1ed d 2 f5 1ef e 2 f5 1f1 f 2 f5 1f3 0 3 f5 1f5 1 3 f5 1f8 2 3 f5 1fb 3 3 f5 1fe 4 3 f5 001 5 3 f5 004 6 3 f5 007 7 3 f5 00a 8 3 f5 1dd 9 3 f5 1e0 a 3 f5 1e3 b 3 f5 1e6 c 3 f5 1e9 d 3 f5 1ec e 3 f5 1ef f 3 f5 1f2 0 4 f5 1f5 1 4 f5 1f9 2 4 f5 1fd 3 4 f5 001 4 4 f5 005 5 4 f5 009 6 4 f5 00d 7 4 f5 011 8 4 f5 1d5 9 4 f5 1d9 a 4 f5 1dd b 4 f5 1e1 c 4 f5 1e5 d 4 f5 1e9 e 4 f5 1ed f 4 f5 1f1 0 5 f5 1f5 1 5 f5 1fa 2 5 f5 1ff 3 5 f5 004 4 5 f5 009 5 5 f5 00e 6 5 f5 013 7 5 f5 018 8 5 f5 1cd 9 5 f5 1d2 a 5 f5 1d7 b 5 f5 1dc c 5 f5 1e1 d 5 f5 1e6 e 5 f5 1eb f 5 f5 1f0 0 6 f5 1f5 1 6 f5 1fb 2 6 f5 001 3 6 f5 007 4 6 f5 00d 5 6 f5 013 6 6 f5 019 7 6 f5 01f 8 6 f5 1c5 9 6 f5 1cb a 6 f5 1d1 b 6 f5 1d7 c 6 f5 1dd d 6 f5 1e3 e 6 f5 1e9 f 6 f5 1ef 0 7 f5 1f5 1 7 f5 1fc 2 7 f5 003 3 7 f5 00a 4 7 f5 011 5 7 f5 018 6 7 f5 01f 7 7 f5 026 8 7 f5 1bd 9 7 f5 1c4 a 7 f5 1cb b 7 f5 1d2 c 7 f5 1d9 d 7 f5 1e0 e 7 f5 1e7 f 7 f5 1ee 0 8 f5 1f5 1 8 f5 1ed 2 8 f5 1e5 3 8 f5 1dd 4 8 f5 1d5 5 8 f5 1cd 6 8 f5 1c5 7 8 f5 1bd 8 8 f5 035 9 8 f5 02d a 8 f5 025 b 8 f5 01d c 8 f5 015 d 8 f5 00d e 8 f5 005 f 8 f5 1fd 0 9 f5 1f5 1 9 f5 1ee 2 9 f5 1e7 3 9 f5 1e0 4 9 f5 1d9 5 9 f5 1d2 6 9 f5 1cb 7 9 f5 1c4 8 9 f5 02d 9 9 f5 026 a 9 f5 01f b 9 f5 018 c 9 f5 011 d 9 f5 00a e 9 f5 003 f 9 f5 1fc 0 a f5 1f5 1 a f5 1ef 2 a f5 1e9 3 a f5 1e3 4 a f5 1dd 5 a f5 1d7 6 a f5 1d1 7 a f5 1cb 8 a f5 025 9 a f5 01f a a f5 019 b a f5 013 c a f5 00d d a f5 007 e a f5 001 f a f5 1fb 0 b f5 1f5 1 b f5 1f0 2 b f5 1eb 3 b f5 1e6 4 b f5 1e1 5 b f5 1dc 6 b f5 1d7 7 b f5 1d2 8 b f5 01d 9 b f5 018 a b f5 013 b b f5 00e c b f5 009 d b f5 004 e b f5 1ff f b f5 1fa 0 c f5 1f5 1 c f5 1f1 2 c f5 1ed 3 c f5 1e9 4 c f5 1e5 5 c f5 1e1 6 c f5 1dd 7 c f5 1d9 8 c f5 015 9 c f5 011 a c f5 00d b c f5 009 c c f5 005 d c f5 001 e c f5 1fd f c f5 1f9 0 d f5 1f5 1 d f5 1f2 2 d f5 1ef 3 d f5 1ec 4 d f5 1e9 5 d f5 1e6 6 d f5 1e3 7 d f5 1e0 8 d f5 00d 9 d f5 00a a d f5 007 b d f5 004 c d f5 001 d d f5 1fe e d f5 1fb f d f5 1f8 0 e f5 1f5 1 e f5 1f3 2 e f5 1f1 3 e f5 1ef 4 e f5 1ed 5 e f5 1eb 6 e f5 1e9 7 e f5 1e7 8 e f5 005 9 e f5 003 a e f5 001 b e f5 1ff c e f5 1fd d e f5 1fb e e f5 1f9 f e f5 1f7 0 f f5 1f5 1 f f5 1f4 2 f f5 1f3 3 f f5 1f2 4 f f5 1f1 5 f f5 1f0 6 f f5 1ef 7 f f5 1ee 8 f f5 1fd 9 f f5 1fc a f f5 1fb b f f5 1fa c f f5 1f9 d f f5 1f8 e f f5 1f7 f f f5 1f6 0 0 f6 1f6 1 0 f6 1f6 2 0 f6 1f6 3 0 f6 1f6 4 0 f6 1f6 5 0 f6 1f6 6 0 f6 1f6 7 0 f6 1f6 8 0 f6 1f6 9 0 f6 1f6 a 0 f6 1f6 b 0 f6 1f6 c 0 f6 1f6 d 0 f6 1f6 e 0 f6 1f6 f 0 f6 1f6 0 1 f6 1f6 1 1 f6 1f7 2 1 f6 1f8 3 1 f6 1f9 4 1 f6 1fa 5 1 f6 1fb 6 1 f6 1fc 7 1 f6 1fd 8 1 f6 1ee 9 1 f6 1ef a 1 f6 1f0 b 1 f6 1f1 c 1 f6 1f2 d 1 f6 1f3 e 1 f6 1f4 f 1 f6 1f5 0 2 f6 1f6 1 2 f6 1f8 2 2 f6 1fa 3 2 f6 1fc 4 2 f6 1fe 5 2 f6 000 6 2 f6 002 7 2 f6 004 8 2 f6 1e6 9 2 f6 1e8 a 2 f6 1ea b 2 f6 1ec c 2 f6 1ee d 2 f6 1f0 e 2 f6 1f2 f 2 f6 1f4 0 3 f6 1f6 1 3 f6 1f9 2 3 f6 1fc 3 3 f6 1ff 4 3 f6 002 5 3 f6 005 6 3 f6 008 7 3 f6 00b 8 3 f6 1de 9 3 f6 1e1 a 3 f6 1e4 b 3 f6 1e7 c 3 f6 1ea d 3 f6 1ed e 3 f6 1f0 f 3 f6 1f3 0 4 f6 1f6 1 4 f6 1fa 2 4 f6 1fe 3 4 f6 002 4 4 f6 006 5 4 f6 00a 6 4 f6 00e 7 4 f6 012 8 4 f6 1d6 9 4 f6 1da a 4 f6 1de b 4 f6 1e2 c 4 f6 1e6 d 4 f6 1ea e 4 f6 1ee f 4 f6 1f2 0 5 f6 1f6 1 5 f6 1fb 2 5 f6 000 3 5 f6 005 4 5 f6 00a 5 5 f6 00f 6 5 f6 014 7 5 f6 019 8 5 f6 1ce 9 5 f6 1d3 a 5 f6 1d8 b 5 f6 1dd c 5 f6 1e2 d 5 f6 1e7 e 5 f6 1ec f 5 f6 1f1 0 6 f6 1f6 1 6 f6 1fc 2 6 f6 002 3 6 f6 008 4 6 f6 00e 5 6 f6 014 6 6 f6 01a 7 6 f6 020 8 6 f6 1c6 9 6 f6 1cc a 6 f6 1d2 b 6 f6 1d8 c 6 f6 1de d 6 f6 1e4 e 6 f6 1ea f 6 f6 1f0 0 7 f6 1f6 1 7 f6 1fd 2 7 f6 004 3 7 f6 00b 4 7 f6 012 5 7 f6 019 6 7 f6 020 7 7 f6 027 8 7 f6 1be 9 7 f6 1c5 a 7 f6 1cc b 7 f6 1d3 c 7 f6 1da d 7 f6 1e1 e 7 f6 1e8 f 7 f6 1ef 0 8 f6 1f6 1 8 f6 1ee 2 8 f6 1e6 3 8 f6 1de 4 8 f6 1d6 5 8 f6 1ce 6 8 f6 1c6 7 8 f6 1be 8 8 f6 036 9 8 f6 02e a 8 f6 026 b 8 f6 01e c 8 f6 016 d 8 f6 00e e 8 f6 006 f 8 f6 1fe 0 9 f6 1f6 1 9 f6 1ef 2 9 f6 1e8 3 9 f6 1e1 4 9 f6 1da 5 9 f6 1d3 6 9 f6 1cc 7 9 f6 1c5 8 9 f6 02e 9 9 f6 027 a 9 f6 020 b 9 f6 019 c 9 f6 012 d 9 f6 00b e 9 f6 004 f 9 f6 1fd 0 a f6 1f6 1 a f6 1f0 2 a f6 1ea 3 a f6 1e4 4 a f6 1de 5 a f6 1d8 6 a f6 1d2 7 a f6 1cc 8 a f6 026 9 a f6 020 a a f6 01a b a f6 014 c a f6 00e d a f6 008 e a f6 002 f a f6 1fc 0 b f6 1f6 1 b f6 1f1 2 b f6 1ec 3 b f6 1e7 4 b f6 1e2 5 b f6 1dd 6 b f6 1d8 7 b f6 1d3 8 b f6 01e 9 b f6 019 a b f6 014 b b f6 00f c b f6 00a d b f6 005 e b f6 000 f b f6 1fb 0 c f6 1f6 1 c f6 1f2 2 c f6 1ee 3 c f6 1ea 4 c f6 1e6 5 c f6 1e2 6 c f6 1de 7 c f6 1da 8 c f6 016 9 c f6 012 a c f6 00e b c f6 00a c c f6 006 d c f6 002 e c f6 1fe f c f6 1fa 0 d f6 1f6 1 d f6 1f3 2 d f6 1f0 3 d f6 1ed 4 d f6 1ea 5 d f6 1e7 6 d f6 1e4 7 d f6 1e1 8 d f6 00e 9 d f6 00b a d f6 008 b d f6 005 c d f6 002 d d f6 1ff e d f6 1fc f d f6 1f9 0 e f6 1f6 1 e f6 1f4 2 e f6 1f2 3 e f6 1f0 4 e f6 1ee 5 e f6 1ec 6 e f6 1ea 7 e f6 1e8 8 e f6 006 9 e f6 004 a e f6 002 b e f6 000 c e f6 1fe d e f6 1fc e e f6 1fa f e f6 1f8 0 f f6 1f6 1 f f6 1f5 2 f f6 1f4 3 f f6 1f3 4 f f6 1f2 5 f f6 1f1 6 f f6 1f0 7 f f6 1ef 8 f f6 1fe 9 f f6 1fd a f f6 1fc b f f6 1fb c f f6 1fa d f f6 1f9 e f f6 1f8 f f f6 1f7 0 0 f7 1f7 1 0 f7 1f7 2 0 f7 1f7 3 0 f7 1f7 4 0 f7 1f7 5 0 f7 1f7 6 0 f7 1f7 7 0 f7 1f7 8 0 f7 1f7 9 0 f7 1f7 a 0 f7 1f7 b 0 f7 1f7 c 0 f7 1f7 d 0 f7 1f7 e 0 f7 1f7 f 0 f7 1f7 0 1 f7 1f7 1 1 f7 1f8 2 1 f7 1f9 3 1 f7 1fa 4 1 f7 1fb 5 1 f7 1fc 6 1 f7 1fd 7 1 f7 1fe 8 1 f7 1ef 9 1 f7 1f0 a 1 f7 1f1 b 1 f7 1f2 c 1 f7 1f3 d 1 f7 1f4 e 1 f7 1f5 f 1 f7 1f6 0 2 f7 1f7 1 2 f7 1f9 2 2 f7 1fb 3 2 f7 1fd 4 2 f7 1ff 5 2 f7 001 6 2 f7 003 7 2 f7 005 8 2 f7 1e7 9 2 f7 1e9 a 2 f7 1eb b 2 f7 1ed c 2 f7 1ef d 2 f7 1f1 e 2 f7 1f3 f 2 f7 1f5 0 3 f7 1f7 1 3 f7 1fa 2 3 f7 1fd 3 3 f7 000 4 3 f7 003 5 3 f7 006 6 3 f7 009 7 3 f7 00c 8 3 f7 1df 9 3 f7 1e2 a 3 f7 1e5 b 3 f7 1e8 c 3 f7 1eb d 3 f7 1ee e 3 f7 1f1 f 3 f7 1f4 0 4 f7 1f7 1 4 f7 1fb 2 4 f7 1ff 3 4 f7 003 4 4 f7 007 5 4 f7 00b 6 4 f7 00f 7 4 f7 013 8 4 f7 1d7 9 4 f7 1db a 4 f7 1df b 4 f7 1e3 c 4 f7 1e7 d 4 f7 1eb e 4 f7 1ef f 4 f7 1f3 0 5 f7 1f7 1 5 f7 1fc 2 5 f7 001 3 5 f7 006 4 5 f7 00b 5 5 f7 010 6 5 f7 015 7 5 f7 01a 8 5 f7 1cf 9 5 f7 1d4 a 5 f7 1d9 b 5 f7 1de c 5 f7 1e3 d 5 f7 1e8 e 5 f7 1ed f 5 f7 1f2 0 6 f7 1f7 1 6 f7 1fd 2 6 f7 003 3 6 f7 009 4 6 f7 00f 5 6 f7 015 6 6 f7 01b 7 6 f7 021 8 6 f7 1c7 9 6 f7 1cd a 6 f7 1d3 b 6 f7 1d9 c 6 f7 1df d 6 f7 1e5 e 6 f7 1eb f 6 f7 1f1 0 7 f7 1f7 1 7 f7 1fe 2 7 f7 005 3 7 f7 00c 4 7 f7 013 5 7 f7 01a 6 7 f7 021 7 7 f7 028 8 7 f7 1bf 9 7 f7 1c6 a 7 f7 1cd b 7 f7 1d4 c 7 f7 1db d 7 f7 1e2 e 7 f7 1e9 f 7 f7 1f0 0 8 f7 1f7 1 8 f7 1ef 2 8 f7 1e7 3 8 f7 1df 4 8 f7 1d7 5 8 f7 1cf 6 8 f7 1c7 7 8 f7 1bf 8 8 f7 037 9 8 f7 02f a 8 f7 027 b 8 f7 01f c 8 f7 017 d 8 f7 00f e 8 f7 007 f 8 f7 1ff 0 9 f7 1f7 1 9 f7 1f0 2 9 f7 1e9 3 9 f7 1e2 4 9 f7 1db 5 9 f7 1d4 6 9 f7 1cd 7 9 f7 1c6 8 9 f7 02f 9 9 f7 028 a 9 f7 021 b 9 f7 01a c 9 f7 013 d 9 f7 00c e 9 f7 005 f 9 f7 1fe 0 a f7 1f7 1 a f7 1f1 2 a f7 1eb 3 a f7 1e5 4 a f7 1df 5 a f7 1d9 6 a f7 1d3 7 a f7 1cd 8 a f7 027 9 a f7 021 a a f7 01b b a f7 015 c a f7 00f d a f7 009 e a f7 003 f a f7 1fd 0 b f7 1f7 1 b f7 1f2 2 b f7 1ed 3 b f7 1e8 4 b f7 1e3 5 b f7 1de 6 b f7 1d9 7 b f7 1d4 8 b f7 01f 9 b f7 01a a b f7 015 b b f7 010 c b f7 00b d b f7 006 e b f7 001 f b f7 1fc 0 c f7 1f7 1 c f7 1f3 2 c f7 1ef 3 c f7 1eb 4 c f7 1e7 5 c f7 1e3 6 c f7 1df 7 c f7 1db 8 c f7 017 9 c f7 013 a c f7 00f b c f7 00b c c f7 007 d c f7 003 e c f7 1ff f c f7 1fb 0 d f7 1f7 1 d f7 1f4 2 d f7 1f1 3 d f7 1ee 4 d f7 1eb 5 d f7 1e8 6 d f7 1e5 7 d f7 1e2 8 d f7 00f 9 d f7 00c a d f7 009 b d f7 006 c d f7 003 d d f7 000 e d f7 1fd f d f7 1fa 0 e f7 1f7 1 e f7 1f5 2 e f7 1f3 3 e f7 1f1 4 e f7 1ef 5 e f7 1ed 6 e f7 1eb 7 e f7 1e9 8 e f7 007 9 e f7 005 a e f7 003 b e f7 001 c e f7 1ff d e f7 1fd e e f7 1fb f e f7 1f9 0 f f7 1f7 1 f f7 1f6 2 f f7 1f5 3 f f7 1f4 4 f f7 1f3 5 f f7 1f2 6 f f7 1f1 7 f f7 1f0 8 f f7 1ff 9 f f7 1fe a f f7 1fd b f f7 1fc c f f7 1fb d f f7 1fa e f f7 1f9 f f f7 1f8 0 0 f8 1f8 1 0 f8 1f8 2 0 f8 1f8 3 0 f8 1f8 4 0 f8 1f8 5 0 f8 1f8 6 0 f8 1f8 7 0 f8 1f8 8 0 f8 1f8 9 0 f8 1f8 a 0 f8 1f8 b 0 f8 1f8 c 0 f8 1f8 d 0 f8 1f8 e 0 f8 1f8 f 0 f8 1f8 0 1 f8 1f8 1 1 f8 1f9 2 1 f8 1fa 3 1 f8 1fb 4 1 f8 1fc 5 1 f8 1fd 6 1 f8 1fe 7 1 f8 1ff 8 1 f8 1f0 9 1 f8 1f1 a 1 f8 1f2 b 1 f8 1f3 c 1 f8 1f4 d 1 f8 1f5 e 1 f8 1f6 f 1 f8 1f7 0 2 f8 1f8 1 2 f8 1fa 2 2 f8 1fc 3 2 f8 1fe 4 2 f8 000 5 2 f8 002 6 2 f8 004 7 2 f8 006 8 2 f8 1e8 9 2 f8 1ea a 2 f8 1ec b 2 f8 1ee c 2 f8 1f0 d 2 f8 1f2 e 2 f8 1f4 f 2 f8 1f6 0 3 f8 1f8 1 3 f8 1fb 2 3 f8 1fe 3 3 f8 001 4 3 f8 004 5 3 f8 007 6 3 f8 00a 7 3 f8 00d 8 3 f8 1e0 9 3 f8 1e3 a 3 f8 1e6 b 3 f8 1e9 c 3 f8 1ec d 3 f8 1ef e 3 f8 1f2 f 3 f8 1f5 0 4 f8 1f8 1 4 f8 1fc 2 4 f8 000 3 4 f8 004 4 4 f8 008 5 4 f8 00c 6 4 f8 010 7 4 f8 014 8 4 f8 1d8 9 4 f8 1dc a 4 f8 1e0 b 4 f8 1e4 c 4 f8 1e8 d 4 f8 1ec e 4 f8 1f0 f 4 f8 1f4 0 5 f8 1f8 1 5 f8 1fd 2 5 f8 002 3 5 f8 007 4 5 f8 00c 5 5 f8 011 6 5 f8 016 7 5 f8 01b 8 5 f8 1d0 9 5 f8 1d5 a 5 f8 1da b 5 f8 1df c 5 f8 1e4 d 5 f8 1e9 e 5 f8 1ee f 5 f8 1f3 0 6 f8 1f8 1 6 f8 1fe 2 6 f8 004 3 6 f8 00a 4 6 f8 010 5 6 f8 016 6 6 f8 01c 7 6 f8 022 8 6 f8 1c8 9 6 f8 1ce a 6 f8 1d4 b 6 f8 1da c 6 f8 1e0 d 6 f8 1e6 e 6 f8 1ec f 6 f8 1f2 0 7 f8 1f8 1 7 f8 1ff 2 7 f8 006 3 7 f8 00d 4 7 f8 014 5 7 f8 01b 6 7 f8 022 7 7 f8 029 8 7 f8 1c0 9 7 f8 1c7 a 7 f8 1ce b 7 f8 1d5 c 7 f8 1dc d 7 f8 1e3 e 7 f8 1ea f 7 f8 1f1 0 8 f8 1f8 1 8 f8 1f0 2 8 f8 1e8 3 8 f8 1e0 4 8 f8 1d8 5 8 f8 1d0 6 8 f8 1c8 7 8 f8 1c0 8 8 f8 038 9 8 f8 030 a 8 f8 028 b 8 f8 020 c 8 f8 018 d 8 f8 010 e 8 f8 008 f 8 f8 000 0 9 f8 1f8 1 9 f8 1f1 2 9 f8 1ea 3 9 f8 1e3 4 9 f8 1dc 5 9 f8 1d5 6 9 f8 1ce 7 9 f8 1c7 8 9 f8 030 9 9 f8 029 a 9 f8 022 b 9 f8 01b c 9 f8 014 d 9 f8 00d e 9 f8 006 f 9 f8 1ff 0 a f8 1f8 1 a f8 1f2 2 a f8 1ec 3 a f8 1e6 4 a f8 1e0 5 a f8 1da 6 a f8 1d4 7 a f8 1ce 8 a f8 028 9 a f8 022 a a f8 01c b a f8 016 c a f8 010 d a f8 00a e a f8 004 f a f8 1fe 0 b f8 1f8 1 b f8 1f3 2 b f8 1ee 3 b f8 1e9 4 b f8 1e4 5 b f8 1df 6 b f8 1da 7 b f8 1d5 8 b f8 020 9 b f8 01b a b f8 016 b b f8 011 c b f8 00c d b f8 007 e b f8 002 f b f8 1fd 0 c f8 1f8 1 c f8 1f4 2 c f8 1f0 3 c f8 1ec 4 c f8 1e8 5 c f8 1e4 6 c f8 1e0 7 c f8 1dc 8 c f8 018 9 c f8 014 a c f8 010 b c f8 00c c c f8 008 d c f8 004 e c f8 000 f c f8 1fc 0 d f8 1f8 1 d f8 1f5 2 d f8 1f2 3 d f8 1ef 4 d f8 1ec 5 d f8 1e9 6 d f8 1e6 7 d f8 1e3 8 d f8 010 9 d f8 00d a d f8 00a b d f8 007 c d f8 004 d d f8 001 e d f8 1fe f d f8 1fb 0 e f8 1f8 1 e f8 1f6 2 e f8 1f4 3 e f8 1f2 4 e f8 1f0 5 e f8 1ee 6 e f8 1ec 7 e f8 1ea 8 e f8 008 9 e f8 006 a e f8 004 b e f8 002 c e f8 000 d e f8 1fe e e f8 1fc f e f8 1fa 0 f f8 1f8 1 f f8 1f7 2 f f8 1f6 3 f f8 1f5 4 f f8 1f4 5 f f8 1f3 6 f f8 1f2 7 f f8 1f1 8 f f8 000 9 f f8 1ff a f f8 1fe b f f8 1fd c f f8 1fc d f f8 1fb e f f8 1fa f f f8 1f9 0 0 f9 1f9 1 0 f9 1f9 2 0 f9 1f9 3 0 f9 1f9 4 0 f9 1f9 5 0 f9 1f9 6 0 f9 1f9 7 0 f9 1f9 8 0 f9 1f9 9 0 f9 1f9 a 0 f9 1f9 b 0 f9 1f9 c 0 f9 1f9 d 0 f9 1f9 e 0 f9 1f9 f 0 f9 1f9 0 1 f9 1f9 1 1 f9 1fa 2 1 f9 1fb 3 1 f9 1fc 4 1 f9 1fd 5 1 f9 1fe 6 1 f9 1ff 7 1 f9 000 8 1 f9 1f1 9 1 f9 1f2 a 1 f9 1f3 b 1 f9 1f4 c 1 f9 1f5 d 1 f9 1f6 e 1 f9 1f7 f 1 f9 1f8 0 2 f9 1f9 1 2 f9 1fb 2 2 f9 1fd 3 2 f9 1ff 4 2 f9 001 5 2 f9 003 6 2 f9 005 7 2 f9 007 8 2 f9 1e9 9 2 f9 1eb a 2 f9 1ed b 2 f9 1ef c 2 f9 1f1 d 2 f9 1f3 e 2 f9 1f5 f 2 f9 1f7 0 3 f9 1f9 1 3 f9 1fc 2 3 f9 1ff 3 3 f9 002 4 3 f9 005 5 3 f9 008 6 3 f9 00b 7 3 f9 00e 8 3 f9 1e1 9 3 f9 1e4 a 3 f9 1e7 b 3 f9 1ea c 3 f9 1ed d 3 f9 1f0 e 3 f9 1f3 f 3 f9 1f6 0 4 f9 1f9 1 4 f9 1fd 2 4 f9 001 3 4 f9 005 4 4 f9 009 5 4 f9 00d 6 4 f9 011 7 4 f9 015 8 4 f9 1d9 9 4 f9 1dd a 4 f9 1e1 b 4 f9 1e5 c 4 f9 1e9 d 4 f9 1ed e 4 f9 1f1 f 4 f9 1f5 0 5 f9 1f9 1 5 f9 1fe 2 5 f9 003 3 5 f9 008 4 5 f9 00d 5 5 f9 012 6 5 f9 017 7 5 f9 01c 8 5 f9 1d1 9 5 f9 1d6 a 5 f9 1db b 5 f9 1e0 c 5 f9 1e5 d 5 f9 1ea e 5 f9 1ef f 5 f9 1f4 0 6 f9 1f9 1 6 f9 1ff 2 6 f9 005 3 6 f9 00b 4 6 f9 011 5 6 f9 017 6 6 f9 01d 7 6 f9 023 8 6 f9 1c9 9 6 f9 1cf a 6 f9 1d5 b 6 f9 1db c 6 f9 1e1 d 6 f9 1e7 e 6 f9 1ed f 6 f9 1f3 0 7 f9 1f9 1 7 f9 000 2 7 f9 007 3 7 f9 00e 4 7 f9 015 5 7 f9 01c 6 7 f9 023 7 7 f9 02a 8 7 f9 1c1 9 7 f9 1c8 a 7 f9 1cf b 7 f9 1d6 c 7 f9 1dd d 7 f9 1e4 e 7 f9 1eb f 7 f9 1f2 0 8 f9 1f9 1 8 f9 1f1 2 8 f9 1e9 3 8 f9 1e1 4 8 f9 1d9 5 8 f9 1d1 6 8 f9 1c9 7 8 f9 1c1 8 8 f9 039 9 8 f9 031 a 8 f9 029 b 8 f9 021 c 8 f9 019 d 8 f9 011 e 8 f9 009 f 8 f9 001 0 9 f9 1f9 1 9 f9 1f2 2 9 f9 1eb 3 9 f9 1e4 4 9 f9 1dd 5 9 f9 1d6 6 9 f9 1cf 7 9 f9 1c8 8 9 f9 031 9 9 f9 02a a 9 f9 023 b 9 f9 01c c 9 f9 015 d 9 f9 00e e 9 f9 007 f 9 f9 000 0 a f9 1f9 1 a f9 1f3 2 a f9 1ed 3 a f9 1e7 4 a f9 1e1 5 a f9 1db 6 a f9 1d5 7 a f9 1cf 8 a f9 029 9 a f9 023 a a f9 01d b a f9 017 c a f9 011 d a f9 00b e a f9 005 f a f9 1ff 0 b f9 1f9 1 b f9 1f4 2 b f9 1ef 3 b f9 1ea 4 b f9 1e5 5 b f9 1e0 6 b f9 1db 7 b f9 1d6 8 b f9 021 9 b f9 01c a b f9 017 b b f9 012 c b f9 00d d b f9 008 e b f9 003 f b f9 1fe 0 c f9 1f9 1 c f9 1f5 2 c f9 1f1 3 c f9 1ed 4 c f9 1e9 5 c f9 1e5 6 c f9 1e1 7 c f9 1dd 8 c f9 019 9 c f9 015 a c f9 011 b c f9 00d c c f9 009 d c f9 005 e c f9 001 f c f9 1fd 0 d f9 1f9 1 d f9 1f6 2 d f9 1f3 3 d f9 1f0 4 d f9 1ed 5 d f9 1ea 6 d f9 1e7 7 d f9 1e4 8 d f9 011 9 d f9 00e a d f9 00b b d f9 008 c d f9 005 d d f9 002 e d f9 1ff f d f9 1fc 0 e f9 1f9 1 e f9 1f7 2 e f9 1f5 3 e f9 1f3 4 e f9 1f1 5 e f9 1ef 6 e f9 1ed 7 e f9 1eb 8 e f9 009 9 e f9 007 a e f9 005 b e f9 003 c e f9 001 d e f9 1ff e e f9 1fd f e f9 1fb 0 f f9 1f9 1 f f9 1f8 2 f f9 1f7 3 f f9 1f6 4 f f9 1f5 5 f f9 1f4 6 f f9 1f3 7 f f9 1f2 8 f f9 001 9 f f9 000 a f f9 1ff b f f9 1fe c f f9 1fd d f f9 1fc e f f9 1fb f f f9 1fa 0 0 fa 1fa 1 0 fa 1fa 2 0 fa 1fa 3 0 fa 1fa 4 0 fa 1fa 5 0 fa 1fa 6 0 fa 1fa 7 0 fa 1fa 8 0 fa 1fa 9 0 fa 1fa a 0 fa 1fa b 0 fa 1fa c 0 fa 1fa d 0 fa 1fa e 0 fa 1fa f 0 fa 1fa 0 1 fa 1fa 1 1 fa 1fb 2 1 fa 1fc 3 1 fa 1fd 4 1 fa 1fe 5 1 fa 1ff 6 1 fa 000 7 1 fa 001 8 1 fa 1f2 9 1 fa 1f3 a 1 fa 1f4 b 1 fa 1f5 c 1 fa 1f6 d 1 fa 1f7 e 1 fa 1f8 f 1 fa 1f9 0 2 fa 1fa 1 2 fa 1fc 2 2 fa 1fe 3 2 fa 000 4 2 fa 002 5 2 fa 004 6 2 fa 006 7 2 fa 008 8 2 fa 1ea 9 2 fa 1ec a 2 fa 1ee b 2 fa 1f0 c 2 fa 1f2 d 2 fa 1f4 e 2 fa 1f6 f 2 fa 1f8 0 3 fa 1fa 1 3 fa 1fd 2 3 fa 000 3 3 fa 003 4 3 fa 006 5 3 fa 009 6 3 fa 00c 7 3 fa 00f 8 3 fa 1e2 9 3 fa 1e5 a 3 fa 1e8 b 3 fa 1eb c 3 fa 1ee d 3 fa 1f1 e 3 fa 1f4 f 3 fa 1f7 0 4 fa 1fa 1 4 fa 1fe 2 4 fa 002 3 4 fa 006 4 4 fa 00a 5 4 fa 00e 6 4 fa 012 7 4 fa 016 8 4 fa 1da 9 4 fa 1de a 4 fa 1e2 b 4 fa 1e6 c 4 fa 1ea d 4 fa 1ee e 4 fa 1f2 f 4 fa 1f6 0 5 fa 1fa 1 5 fa 1ff 2 5 fa 004 3 5 fa 009 4 5 fa 00e 5 5 fa 013 6 5 fa 018 7 5 fa 01d 8 5 fa 1d2 9 5 fa 1d7 a 5 fa 1dc b 5 fa 1e1 c 5 fa 1e6 d 5 fa 1eb e 5 fa 1f0 f 5 fa 1f5 0 6 fa 1fa 1 6 fa 000 2 6 fa 006 3 6 fa 00c 4 6 fa 012 5 6 fa 018 6 6 fa 01e 7 6 fa 024 8 6 fa 1ca 9 6 fa 1d0 a 6 fa 1d6 b 6 fa 1dc c 6 fa 1e2 d 6 fa 1e8 e 6 fa 1ee f 6 fa 1f4 0 7 fa 1fa 1 7 fa 001 2 7 fa 008 3 7 fa 00f 4 7 fa 016 5 7 fa 01d 6 7 fa 024 7 7 fa 02b 8 7 fa 1c2 9 7 fa 1c9 a 7 fa 1d0 b 7 fa 1d7 c 7 fa 1de d 7 fa 1e5 e 7 fa 1ec f 7 fa 1f3 0 8 fa 1fa 1 8 fa 1f2 2 8 fa 1ea 3 8 fa 1e2 4 8 fa 1da 5 8 fa 1d2 6 8 fa 1ca 7 8 fa 1c2 8 8 fa 03a 9 8 fa 032 a 8 fa 02a b 8 fa 022 c 8 fa 01a d 8 fa 012 e 8 fa 00a f 8 fa 002 0 9 fa 1fa 1 9 fa 1f3 2 9 fa 1ec 3 9 fa 1e5 4 9 fa 1de 5 9 fa 1d7 6 9 fa 1d0 7 9 fa 1c9 8 9 fa 032 9 9 fa 02b a 9 fa 024 b 9 fa 01d c 9 fa 016 d 9 fa 00f e 9 fa 008 f 9 fa 001 0 a fa 1fa 1 a fa 1f4 2 a fa 1ee 3 a fa 1e8 4 a fa 1e2 5 a fa 1dc 6 a fa 1d6 7 a fa 1d0 8 a fa 02a 9 a fa 024 a a fa 01e b a fa 018 c a fa 012 d a fa 00c e a fa 006 f a fa 000 0 b fa 1fa 1 b fa 1f5 2 b fa 1f0 3 b fa 1eb 4 b fa 1e6 5 b fa 1e1 6 b fa 1dc 7 b fa 1d7 8 b fa 022 9 b fa 01d a b fa 018 b b fa 013 c b fa 00e d b fa 009 e b fa 004 f b fa 1ff 0 c fa 1fa 1 c fa 1f6 2 c fa 1f2 3 c fa 1ee 4 c fa 1ea 5 c fa 1e6 6 c fa 1e2 7 c fa 1de 8 c fa 01a 9 c fa 016 a c fa 012 b c fa 00e c c fa 00a d c fa 006 e c fa 002 f c fa 1fe 0 d fa 1fa 1 d fa 1f7 2 d fa 1f4 3 d fa 1f1 4 d fa 1ee 5 d fa 1eb 6 d fa 1e8 7 d fa 1e5 8 d fa 012 9 d fa 00f a d fa 00c b d fa 009 c d fa 006 d d fa 003 e d fa 000 f d fa 1fd 0 e fa 1fa 1 e fa 1f8 2 e fa 1f6 3 e fa 1f4 4 e fa 1f2 5 e fa 1f0 6 e fa 1ee 7 e fa 1ec 8 e fa 00a 9 e fa 008 a e fa 006 b e fa 004 c e fa 002 d e fa 000 e e fa 1fe f e fa 1fc 0 f fa 1fa 1 f fa 1f9 2 f fa 1f8 3 f fa 1f7 4 f fa 1f6 5 f fa 1f5 6 f fa 1f4 7 f fa 1f3 8 f fa 002 9 f fa 001 a f fa 000 b f fa 1ff c f fa 1fe d f fa 1fd e f fa 1fc f f fa 1fb 0 0 fb 1fb 1 0 fb 1fb 2 0 fb 1fb 3 0 fb 1fb 4 0 fb 1fb 5 0 fb 1fb 6 0 fb 1fb 7 0 fb 1fb 8 0 fb 1fb 9 0 fb 1fb a 0 fb 1fb b 0 fb 1fb c 0 fb 1fb d 0 fb 1fb e 0 fb 1fb f 0 fb 1fb 0 1 fb 1fb 1 1 fb 1fc 2 1 fb 1fd 3 1 fb 1fe 4 1 fb 1ff 5 1 fb 000 6 1 fb 001 7 1 fb 002 8 1 fb 1f3 9 1 fb 1f4 a 1 fb 1f5 b 1 fb 1f6 c 1 fb 1f7 d 1 fb 1f8 e 1 fb 1f9 f 1 fb 1fa 0 2 fb 1fb 1 2 fb 1fd 2 2 fb 1ff 3 2 fb 001 4 2 fb 003 5 2 fb 005 6 2 fb 007 7 2 fb 009 8 2 fb 1eb 9 2 fb 1ed a 2 fb 1ef b 2 fb 1f1 c 2 fb 1f3 d 2 fb 1f5 e 2 fb 1f7 f 2 fb 1f9 0 3 fb 1fb 1 3 fb 1fe 2 3 fb 001 3 3 fb 004 4 3 fb 007 5 3 fb 00a 6 3 fb 00d 7 3 fb 010 8 3 fb 1e3 9 3 fb 1e6 a 3 fb 1e9 b 3 fb 1ec c 3 fb 1ef d 3 fb 1f2 e 3 fb 1f5 f 3 fb 1f8 0 4 fb 1fb 1 4 fb 1ff 2 4 fb 003 3 4 fb 007 4 4 fb 00b 5 4 fb 00f 6 4 fb 013 7 4 fb 017 8 4 fb 1db 9 4 fb 1df a 4 fb 1e3 b 4 fb 1e7 c 4 fb 1eb d 4 fb 1ef e 4 fb 1f3 f 4 fb 1f7 0 5 fb 1fb 1 5 fb 000 2 5 fb 005 3 5 fb 00a 4 5 fb 00f 5 5 fb 014 6 5 fb 019 7 5 fb 01e 8 5 fb 1d3 9 5 fb 1d8 a 5 fb 1dd b 5 fb 1e2 c 5 fb 1e7 d 5 fb 1ec e 5 fb 1f1 f 5 fb 1f6 0 6 fb 1fb 1 6 fb 001 2 6 fb 007 3 6 fb 00d 4 6 fb 013 5 6 fb 019 6 6 fb 01f 7 6 fb 025 8 6 fb 1cb 9 6 fb 1d1 a 6 fb 1d7 b 6 fb 1dd c 6 fb 1e3 d 6 fb 1e9 e 6 fb 1ef f 6 fb 1f5 0 7 fb 1fb 1 7 fb 002 2 7 fb 009 3 7 fb 010 4 7 fb 017 5 7 fb 01e 6 7 fb 025 7 7 fb 02c 8 7 fb 1c3 9 7 fb 1ca a 7 fb 1d1 b 7 fb 1d8 c 7 fb 1df d 7 fb 1e6 e 7 fb 1ed f 7 fb 1f4 0 8 fb 1fb 1 8 fb 1f3 2 8 fb 1eb 3 8 fb 1e3 4 8 fb 1db 5 8 fb 1d3 6 8 fb 1cb 7 8 fb 1c3 8 8 fb 03b 9 8 fb 033 a 8 fb 02b b 8 fb 023 c 8 fb 01b d 8 fb 013 e 8 fb 00b f 8 fb 003 0 9 fb 1fb 1 9 fb 1f4 2 9 fb 1ed 3 9 fb 1e6 4 9 fb 1df 5 9 fb 1d8 6 9 fb 1d1 7 9 fb 1ca 8 9 fb 033 9 9 fb 02c a 9 fb 025 b 9 fb 01e c 9 fb 017 d 9 fb 010 e 9 fb 009 f 9 fb 002 0 a fb 1fb 1 a fb 1f5 2 a fb 1ef 3 a fb 1e9 4 a fb 1e3 5 a fb 1dd 6 a fb 1d7 7 a fb 1d1 8 a fb 02b 9 a fb 025 a a fb 01f b a fb 019 c a fb 013 d a fb 00d e a fb 007 f a fb 001 0 b fb 1fb 1 b fb 1f6 2 b fb 1f1 3 b fb 1ec 4 b fb 1e7 5 b fb 1e2 6 b fb 1dd 7 b fb 1d8 8 b fb 023 9 b fb 01e a b fb 019 b b fb 014 c b fb 00f d b fb 00a e b fb 005 f b fb 000 0 c fb 1fb 1 c fb 1f7 2 c fb 1f3 3 c fb 1ef 4 c fb 1eb 5 c fb 1e7 6 c fb 1e3 7 c fb 1df 8 c fb 01b 9 c fb 017 a c fb 013 b c fb 00f c c fb 00b d c fb 007 e c fb 003 f c fb 1ff 0 d fb 1fb 1 d fb 1f8 2 d fb 1f5 3 d fb 1f2 4 d fb 1ef 5 d fb 1ec 6 d fb 1e9 7 d fb 1e6 8 d fb 013 9 d fb 010 a d fb 00d b d fb 00a c d fb 007 d d fb 004 e d fb 001 f d fb 1fe 0 e fb 1fb 1 e fb 1f9 2 e fb 1f7 3 e fb 1f5 4 e fb 1f3 5 e fb 1f1 6 e fb 1ef 7 e fb 1ed 8 e fb 00b 9 e fb 009 a e fb 007 b e fb 005 c e fb 003 d e fb 001 e e fb 1ff f e fb 1fd 0 f fb 1fb 1 f fb 1fa 2 f fb 1f9 3 f fb 1f8 4 f fb 1f7 5 f fb 1f6 6 f fb 1f5 7 f fb 1f4 8 f fb 003 9 f fb 002 a f fb 001 b f fb 000 c f fb 1ff d f fb 1fe e f fb 1fd f f fb 1fc 0 0 fc 1fc 1 0 fc 1fc 2 0 fc 1fc 3 0 fc 1fc 4 0 fc 1fc 5 0 fc 1fc 6 0 fc 1fc 7 0 fc 1fc 8 0 fc 1fc 9 0 fc 1fc a 0 fc 1fc b 0 fc 1fc c 0 fc 1fc d 0 fc 1fc e 0 fc 1fc f 0 fc 1fc 0 1 fc 1fc 1 1 fc 1fd 2 1 fc 1fe 3 1 fc 1ff 4 1 fc 000 5 1 fc 001 6 1 fc 002 7 1 fc 003 8 1 fc 1f4 9 1 fc 1f5 a 1 fc 1f6 b 1 fc 1f7 c 1 fc 1f8 d 1 fc 1f9 e 1 fc 1fa f 1 fc 1fb 0 2 fc 1fc 1 2 fc 1fe 2 2 fc 000 3 2 fc 002 4 2 fc 004 5 2 fc 006 6 2 fc 008 7 2 fc 00a 8 2 fc 1ec 9 2 fc 1ee a 2 fc 1f0 b 2 fc 1f2 c 2 fc 1f4 d 2 fc 1f6 e 2 fc 1f8 f 2 fc 1fa 0 3 fc 1fc 1 3 fc 1ff 2 3 fc 002 3 3 fc 005 4 3 fc 008 5 3 fc 00b 6 3 fc 00e 7 3 fc 011 8 3 fc 1e4 9 3 fc 1e7 a 3 fc 1ea b 3 fc 1ed c 3 fc 1f0 d 3 fc 1f3 e 3 fc 1f6 f 3 fc 1f9 0 4 fc 1fc 1 4 fc 000 2 4 fc 004 3 4 fc 008 4 4 fc 00c 5 4 fc 010 6 4 fc 014 7 4 fc 018 8 4 fc 1dc 9 4 fc 1e0 a 4 fc 1e4 b 4 fc 1e8 c 4 fc 1ec d 4 fc 1f0 e 4 fc 1f4 f 4 fc 1f8 0 5 fc 1fc 1 5 fc 001 2 5 fc 006 3 5 fc 00b 4 5 fc 010 5 5 fc 015 6 5 fc 01a 7 5 fc 01f 8 5 fc 1d4 9 5 fc 1d9 a 5 fc 1de b 5 fc 1e3 c 5 fc 1e8 d 5 fc 1ed e 5 fc 1f2 f 5 fc 1f7 0 6 fc 1fc 1 6 fc 002 2 6 fc 008 3 6 fc 00e 4 6 fc 014 5 6 fc 01a 6 6 fc 020 7 6 fc 026 8 6 fc 1cc 9 6 fc 1d2 a 6 fc 1d8 b 6 fc 1de c 6 fc 1e4 d 6 fc 1ea e 6 fc 1f0 f 6 fc 1f6 0 7 fc 1fc 1 7 fc 003 2 7 fc 00a 3 7 fc 011 4 7 fc 018 5 7 fc 01f 6 7 fc 026 7 7 fc 02d 8 7 fc 1c4 9 7 fc 1cb a 7 fc 1d2 b 7 fc 1d9 c 7 fc 1e0 d 7 fc 1e7 e 7 fc 1ee f 7 fc 1f5 0 8 fc 1fc 1 8 fc 1f4 2 8 fc 1ec 3 8 fc 1e4 4 8 fc 1dc 5 8 fc 1d4 6 8 fc 1cc 7 8 fc 1c4 8 8 fc 03c 9 8 fc 034 a 8 fc 02c b 8 fc 024 c 8 fc 01c d 8 fc 014 e 8 fc 00c f 8 fc 004 0 9 fc 1fc 1 9 fc 1f5 2 9 fc 1ee 3 9 fc 1e7 4 9 fc 1e0 5 9 fc 1d9 6 9 fc 1d2 7 9 fc 1cb 8 9 fc 034 9 9 fc 02d a 9 fc 026 b 9 fc 01f c 9 fc 018 d 9 fc 011 e 9 fc 00a f 9 fc 003 0 a fc 1fc 1 a fc 1f6 2 a fc 1f0 3 a fc 1ea 4 a fc 1e4 5 a fc 1de 6 a fc 1d8 7 a fc 1d2 8 a fc 02c 9 a fc 026 a a fc 020 b a fc 01a c a fc 014 d a fc 00e e a fc 008 f a fc 002 0 b fc 1fc 1 b fc 1f7 2 b fc 1f2 3 b fc 1ed 4 b fc 1e8 5 b fc 1e3 6 b fc 1de 7 b fc 1d9 8 b fc 024 9 b fc 01f a b fc 01a b b fc 015 c b fc 010 d b fc 00b e b fc 006 f b fc 001 0 c fc 1fc 1 c fc 1f8 2 c fc 1f4 3 c fc 1f0 4 c fc 1ec 5 c fc 1e8 6 c fc 1e4 7 c fc 1e0 8 c fc 01c 9 c fc 018 a c fc 014 b c fc 010 c c fc 00c d c fc 008 e c fc 004 f c fc 000 0 d fc 1fc 1 d fc 1f9 2 d fc 1f6 3 d fc 1f3 4 d fc 1f0 5 d fc 1ed 6 d fc 1ea 7 d fc 1e7 8 d fc 014 9 d fc 011 a d fc 00e b d fc 00b c d fc 008 d d fc 005 e d fc 002 f d fc 1ff 0 e fc 1fc 1 e fc 1fa 2 e fc 1f8 3 e fc 1f6 4 e fc 1f4 5 e fc 1f2 6 e fc 1f0 7 e fc 1ee 8 e fc 00c 9 e fc 00a a e fc 008 b e fc 006 c e fc 004 d e fc 002 e e fc 000 f e fc 1fe 0 f fc 1fc 1 f fc 1fb 2 f fc 1fa 3 f fc 1f9 4 f fc 1f8 5 f fc 1f7 6 f fc 1f6 7 f fc 1f5 8 f fc 004 9 f fc 003 a f fc 002 b f fc 001 c f fc 000 d f fc 1ff e f fc 1fe f f fc 1fd 0 0 fd 1fd 1 0 fd 1fd 2 0 fd 1fd 3 0 fd 1fd 4 0 fd 1fd 5 0 fd 1fd 6 0 fd 1fd 7 0 fd 1fd 8 0 fd 1fd 9 0 fd 1fd a 0 fd 1fd b 0 fd 1fd c 0 fd 1fd d 0 fd 1fd e 0 fd 1fd f 0 fd 1fd 0 1 fd 1fd 1 1 fd 1fe 2 1 fd 1ff 3 1 fd 000 4 1 fd 001 5 1 fd 002 6 1 fd 003 7 1 fd 004 8 1 fd 1f5 9 1 fd 1f6 a 1 fd 1f7 b 1 fd 1f8 c 1 fd 1f9 d 1 fd 1fa e 1 fd 1fb f 1 fd 1fc 0 2 fd 1fd 1 2 fd 1ff 2 2 fd 001 3 2 fd 003 4 2 fd 005 5 2 fd 007 6 2 fd 009 7 2 fd 00b 8 2 fd 1ed 9 2 fd 1ef a 2 fd 1f1 b 2 fd 1f3 c 2 fd 1f5 d 2 fd 1f7 e 2 fd 1f9 f 2 fd 1fb 0 3 fd 1fd 1 3 fd 000 2 3 fd 003 3 3 fd 006 4 3 fd 009 5 3 fd 00c 6 3 fd 00f 7 3 fd 012 8 3 fd 1e5 9 3 fd 1e8 a 3 fd 1eb b 3 fd 1ee c 3 fd 1f1 d 3 fd 1f4 e 3 fd 1f7 f 3 fd 1fa 0 4 fd 1fd 1 4 fd 001 2 4 fd 005 3 4 fd 009 4 4 fd 00d 5 4 fd 011 6 4 fd 015 7 4 fd 019 8 4 fd 1dd 9 4 fd 1e1 a 4 fd 1e5 b 4 fd 1e9 c 4 fd 1ed d 4 fd 1f1 e 4 fd 1f5 f 4 fd 1f9 0 5 fd 1fd 1 5 fd 002 2 5 fd 007 3 5 fd 00c 4 5 fd 011 5 5 fd 016 6 5 fd 01b 7 5 fd 020 8 5 fd 1d5 9 5 fd 1da a 5 fd 1df b 5 fd 1e4 c 5 fd 1e9 d 5 fd 1ee e 5 fd 1f3 f 5 fd 1f8 0 6 fd 1fd 1 6 fd 003 2 6 fd 009 3 6 fd 00f 4 6 fd 015 5 6 fd 01b 6 6 fd 021 7 6 fd 027 8 6 fd 1cd 9 6 fd 1d3 a 6 fd 1d9 b 6 fd 1df c 6 fd 1e5 d 6 fd 1eb e 6 fd 1f1 f 6 fd 1f7 0 7 fd 1fd 1 7 fd 004 2 7 fd 00b 3 7 fd 012 4 7 fd 019 5 7 fd 020 6 7 fd 027 7 7 fd 02e 8 7 fd 1c5 9 7 fd 1cc a 7 fd 1d3 b 7 fd 1da c 7 fd 1e1 d 7 fd 1e8 e 7 fd 1ef f 7 fd 1f6 0 8 fd 1fd 1 8 fd 1f5 2 8 fd 1ed 3 8 fd 1e5 4 8 fd 1dd 5 8 fd 1d5 6 8 fd 1cd 7 8 fd 1c5 8 8 fd 03d 9 8 fd 035 a 8 fd 02d b 8 fd 025 c 8 fd 01d d 8 fd 015 e 8 fd 00d f 8 fd 005 0 9 fd 1fd 1 9 fd 1f6 2 9 fd 1ef 3 9 fd 1e8 4 9 fd 1e1 5 9 fd 1da 6 9 fd 1d3 7 9 fd 1cc 8 9 fd 035 9 9 fd 02e a 9 fd 027 b 9 fd 020 c 9 fd 019 d 9 fd 012 e 9 fd 00b f 9 fd 004 0 a fd 1fd 1 a fd 1f7 2 a fd 1f1 3 a fd 1eb 4 a fd 1e5 5 a fd 1df 6 a fd 1d9 7 a fd 1d3 8 a fd 02d 9 a fd 027 a a fd 021 b a fd 01b c a fd 015 d a fd 00f e a fd 009 f a fd 003 0 b fd 1fd 1 b fd 1f8 2 b fd 1f3 3 b fd 1ee 4 b fd 1e9 5 b fd 1e4 6 b fd 1df 7 b fd 1da 8 b fd 025 9 b fd 020 a b fd 01b b b fd 016 c b fd 011 d b fd 00c e b fd 007 f b fd 002 0 c fd 1fd 1 c fd 1f9 2 c fd 1f5 3 c fd 1f1 4 c fd 1ed 5 c fd 1e9 6 c fd 1e5 7 c fd 1e1 8 c fd 01d 9 c fd 019 a c fd 015 b c fd 011 c c fd 00d d c fd 009 e c fd 005 f c fd 001 0 d fd 1fd 1 d fd 1fa 2 d fd 1f7 3 d fd 1f4 4 d fd 1f1 5 d fd 1ee 6 d fd 1eb 7 d fd 1e8 8 d fd 015 9 d fd 012 a d fd 00f b d fd 00c c d fd 009 d d fd 006 e d fd 003 f d fd 000 0 e fd 1fd 1 e fd 1fb 2 e fd 1f9 3 e fd 1f7 4 e fd 1f5 5 e fd 1f3 6 e fd 1f1 7 e fd 1ef 8 e fd 00d 9 e fd 00b a e fd 009 b e fd 007 c e fd 005 d e fd 003 e e fd 001 f e fd 1ff 0 f fd 1fd 1 f fd 1fc 2 f fd 1fb 3 f fd 1fa 4 f fd 1f9 5 f fd 1f8 6 f fd 1f7 7 f fd 1f6 8 f fd 005 9 f fd 004 a f fd 003 b f fd 002 c f fd 001 d f fd 000 e f fd 1ff f f fd 1fe 0 0 fe 1fe 1 0 fe 1fe 2 0 fe 1fe 3 0 fe 1fe 4 0 fe 1fe 5 0 fe 1fe 6 0 fe 1fe 7 0 fe 1fe 8 0 fe 1fe 9 0 fe 1fe a 0 fe 1fe b 0 fe 1fe c 0 fe 1fe d 0 fe 1fe e 0 fe 1fe f 0 fe 1fe 0 1 fe 1fe 1 1 fe 1ff 2 1 fe 000 3 1 fe 001 4 1 fe 002 5 1 fe 003 6 1 fe 004 7 1 fe 005 8 1 fe 1f6 9 1 fe 1f7 a 1 fe 1f8 b 1 fe 1f9 c 1 fe 1fa d 1 fe 1fb e 1 fe 1fc f 1 fe 1fd 0 2 fe 1fe 1 2 fe 000 2 2 fe 002 3 2 fe 004 4 2 fe 006 5 2 fe 008 6 2 fe 00a 7 2 fe 00c 8 2 fe 1ee 9 2 fe 1f0 a 2 fe 1f2 b 2 fe 1f4 c 2 fe 1f6 d 2 fe 1f8 e 2 fe 1fa f 2 fe 1fc 0 3 fe 1fe 1 3 fe 001 2 3 fe 004 3 3 fe 007 4 3 fe 00a 5 3 fe 00d 6 3 fe 010 7 3 fe 013 8 3 fe 1e6 9 3 fe 1e9 a 3 fe 1ec b 3 fe 1ef c 3 fe 1f2 d 3 fe 1f5 e 3 fe 1f8 f 3 fe 1fb 0 4 fe 1fe 1 4 fe 002 2 4 fe 006 3 4 fe 00a 4 4 fe 00e 5 4 fe 012 6 4 fe 016 7 4 fe 01a 8 4 fe 1de 9 4 fe 1e2 a 4 fe 1e6 b 4 fe 1ea c 4 fe 1ee d 4 fe 1f2 e 4 fe 1f6 f 4 fe 1fa 0 5 fe 1fe 1 5 fe 003 2 5 fe 008 3 5 fe 00d 4 5 fe 012 5 5 fe 017 6 5 fe 01c 7 5 fe 021 8 5 fe 1d6 9 5 fe 1db a 5 fe 1e0 b 5 fe 1e5 c 5 fe 1ea d 5 fe 1ef e 5 fe 1f4 f 5 fe 1f9 0 6 fe 1fe 1 6 fe 004 2 6 fe 00a 3 6 fe 010 4 6 fe 016 5 6 fe 01c 6 6 fe 022 7 6 fe 028 8 6 fe 1ce 9 6 fe 1d4 a 6 fe 1da b 6 fe 1e0 c 6 fe 1e6 d 6 fe 1ec e 6 fe 1f2 f 6 fe 1f8 0 7 fe 1fe 1 7 fe 005 2 7 fe 00c 3 7 fe 013 4 7 fe 01a 5 7 fe 021 6 7 fe 028 7 7 fe 02f 8 7 fe 1c6 9 7 fe 1cd a 7 fe 1d4 b 7 fe 1db c 7 fe 1e2 d 7 fe 1e9 e 7 fe 1f0 f 7 fe 1f7 0 8 fe 1fe 1 8 fe 1f6 2 8 fe 1ee 3 8 fe 1e6 4 8 fe 1de 5 8 fe 1d6 6 8 fe 1ce 7 8 fe 1c6 8 8 fe 03e 9 8 fe 036 a 8 fe 02e b 8 fe 026 c 8 fe 01e d 8 fe 016 e 8 fe 00e f 8 fe 006 0 9 fe 1fe 1 9 fe 1f7 2 9 fe 1f0 3 9 fe 1e9 4 9 fe 1e2 5 9 fe 1db 6 9 fe 1d4 7 9 fe 1cd 8 9 fe 036 9 9 fe 02f a 9 fe 028 b 9 fe 021 c 9 fe 01a d 9 fe 013 e 9 fe 00c f 9 fe 005 0 a fe 1fe 1 a fe 1f8 2 a fe 1f2 3 a fe 1ec 4 a fe 1e6 5 a fe 1e0 6 a fe 1da 7 a fe 1d4 8 a fe 02e 9 a fe 028 a a fe 022 b a fe 01c c a fe 016 d a fe 010 e a fe 00a f a fe 004 0 b fe 1fe 1 b fe 1f9 2 b fe 1f4 3 b fe 1ef 4 b fe 1ea 5 b fe 1e5 6 b fe 1e0 7 b fe 1db 8 b fe 026 9 b fe 021 a b fe 01c b b fe 017 c b fe 012 d b fe 00d e b fe 008 f b fe 003 0 c fe 1fe 1 c fe 1fa 2 c fe 1f6 3 c fe 1f2 4 c fe 1ee 5 c fe 1ea 6 c fe 1e6 7 c fe 1e2 8 c fe 01e 9 c fe 01a a c fe 016 b c fe 012 c c fe 00e d c fe 00a e c fe 006 f c fe 002 0 d fe 1fe 1 d fe 1fb 2 d fe 1f8 3 d fe 1f5 4 d fe 1f2 5 d fe 1ef 6 d fe 1ec 7 d fe 1e9 8 d fe 016 9 d fe 013 a d fe 010 b d fe 00d c d fe 00a d d fe 007 e d fe 004 f d fe 001 0 e fe 1fe 1 e fe 1fc 2 e fe 1fa 3 e fe 1f8 4 e fe 1f6 5 e fe 1f4 6 e fe 1f2 7 e fe 1f0 8 e fe 00e 9 e fe 00c a e fe 00a b e fe 008 c e fe 006 d e fe 004 e e fe 002 f e fe 000 0 f fe 1fe 1 f fe 1fd 2 f fe 1fc 3 f fe 1fb 4 f fe 1fa 5 f fe 1f9 6 f fe 1f8 7 f fe 1f7 8 f fe 006 9 f fe 005 a f fe 004 b f fe 003 c f fe 002 d f fe 001 e f fe 000 f f fe 1ff 0 0 ff 1ff 1 0 ff 1ff 2 0 ff 1ff 3 0 ff 1ff 4 0 ff 1ff 5 0 ff 1ff 6 0 ff 1ff 7 0 ff 1ff 8 0 ff 1ff 9 0 ff 1ff a 0 ff 1ff b 0 ff 1ff c 0 ff 1ff d 0 ff 1ff e 0 ff 1ff f 0 ff 1ff 0 1 ff 1ff 1 1 ff 000 2 1 ff 001 3 1 ff 002 4 1 ff 003 5 1 ff 004 6 1 ff 005 7 1 ff 006 8 1 ff 1f7 9 1 ff 1f8 a 1 ff 1f9 b 1 ff 1fa c 1 ff 1fb d 1 ff 1fc e 1 ff 1fd f 1 ff 1fe 0 2 ff 1ff 1 2 ff 001 2 2 ff 003 3 2 ff 005 4 2 ff 007 5 2 ff 009 6 2 ff 00b 7 2 ff 00d 8 2 ff 1ef 9 2 ff 1f1 a 2 ff 1f3 b 2 ff 1f5 c 2 ff 1f7 d 2 ff 1f9 e 2 ff 1fb f 2 ff 1fd 0 3 ff 1ff 1 3 ff 002 2 3 ff 005 3 3 ff 008 4 3 ff 00b 5 3 ff 00e 6 3 ff 011 7 3 ff 014 8 3 ff 1e7 9 3 ff 1ea a 3 ff 1ed b 3 ff 1f0 c 3 ff 1f3 d 3 ff 1f6 e 3 ff 1f9 f 3 ff 1fc 0 4 ff 1ff 1 4 ff 003 2 4 ff 007 3 4 ff 00b 4 4 ff 00f 5 4 ff 013 6 4 ff 017 7 4 ff 01b 8 4 ff 1df 9 4 ff 1e3 a 4 ff 1e7 b 4 ff 1eb c 4 ff 1ef d 4 ff 1f3 e 4 ff 1f7 f 4 ff 1fb 0 5 ff 1ff 1 5 ff 004 2 5 ff 009 3 5 ff 00e 4 5 ff 013 5 5 ff 018 6 5 ff 01d 7 5 ff 022 8 5 ff 1d7 9 5 ff 1dc a 5 ff 1e1 b 5 ff 1e6 c 5 ff 1eb d 5 ff 1f0 e 5 ff 1f5 f 5 ff 1fa 0 6 ff 1ff 1 6 ff 005 2 6 ff 00b 3 6 ff 011 4 6 ff 017 5 6 ff 01d 6 6 ff 023 7 6 ff 029 8 6 ff 1cf 9 6 ff 1d5 a 6 ff 1db b 6 ff 1e1 c 6 ff 1e7 d 6 ff 1ed e 6 ff 1f3 f 6 ff 1f9 0 7 ff 1ff 1 7 ff 006 2 7 ff 00d 3 7 ff 014 4 7 ff 01b 5 7 ff 022 6 7 ff 029 7 7 ff 030 8 7 ff 1c7 9 7 ff 1ce a 7 ff 1d5 b 7 ff 1dc c 7 ff 1e3 d 7 ff 1ea e 7 ff 1f1 f 7 ff 1f8 0 8 ff 1ff 1 8 ff 1f7 2 8 ff 1ef 3 8 ff 1e7 4 8 ff 1df 5 8 ff 1d7 6 8 ff 1cf 7 8 ff 1c7 8 8 ff 03f 9 8 ff 037 a 8 ff 02f b 8 ff 027 c 8 ff 01f d 8 ff 017 e 8 ff 00f f 8 ff 007 0 9 ff 1ff 1 9 ff 1f8 2 9 ff 1f1 3 9 ff 1ea 4 9 ff 1e3 5 9 ff 1dc 6 9 ff 1d5 7 9 ff 1ce 8 9 ff 037 9 9 ff 030 a 9 ff 029 b 9 ff 022 c 9 ff 01b d 9 ff 014 e 9 ff 00d f 9 ff 006 0 a ff 1ff 1 a ff 1f9 2 a ff 1f3 3 a ff 1ed 4 a ff 1e7 5 a ff 1e1 6 a ff 1db 7 a ff 1d5 8 a ff 02f 9 a ff 029 a a ff 023 b a ff 01d c a ff 017 d a ff 011 e a ff 00b f a ff 005 0 b ff 1ff 1 b ff 1fa 2 b ff 1f5 3 b ff 1f0 4 b ff 1eb 5 b ff 1e6 6 b ff 1e1 7 b ff 1dc 8 b ff 027 9 b ff 022 a b ff 01d b b ff 018 c b ff 013 d b ff 00e e b ff 009 f b ff 004 0 c ff 1ff 1 c ff 1fb 2 c ff 1f7 3 c ff 1f3 4 c ff 1ef 5 c ff 1eb 6 c ff 1e7 7 c ff 1e3 8 c ff 01f 9 c ff 01b a c ff 017 b c ff 013 c c ff 00f d c ff 00b e c ff 007 f c ff 003 0 d ff 1ff 1 d ff 1fc 2 d ff 1f9 3 d ff 1f6 4 d ff 1f3 5 d ff 1f0 6 d ff 1ed 7 d ff 1ea 8 d ff 017 9 d ff 014 a d ff 011 b d ff 00e c d ff 00b d d ff 008 e d ff 005 f d ff 002 0 e ff 1ff 1 e ff 1fd 2 e ff 1fb 3 e ff 1f9 4 e ff 1f7 5 e ff 1f5 6 e ff 1f3 7 e ff 1f1 8 e ff 00f 9 e ff 00d a e ff 00b b e ff 009 c e ff 007 d e ff 005 e e ff 003 f e ff 001 0 f ff 1ff 1 f ff 1fe 2 f ff 1fd 3 f ff 1fc 4 f ff 1fb 5 f ff 1fa 6 f ff 1f9 7 f ff 1f8 8 f ff 007 9 f ff 006 a f ff 005 b f ff 004 c f ff 003 d f ff 002 e f ff 001 f f ff 000 iverilog-12_0/ivtest/gold/mcl2.gold000066400000000000000000000440001435245347300173140ustar00rootroot000000000000000 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 0 0 0000 1 0 1fe8 2 0 1fd0 3 0 1fb8 4 0 1fa0 5 0 1f88 6 0 1f70 7 0 1f58 8 0 00c0 9 0 00a8 a 0 0090 b 0 0078 c 0 0060 d 0 0048 e 0 0030 f 0 0018 0 1 1fdf 1 1 1fc7 2 1 1faf 3 1 1f97 4 1 1f7f 5 1 1f67 6 1 1f4f 7 1 1f37 8 1 009f 9 1 0087 a 1 006f b 1 0057 c 1 003f d 1 0027 e 1 000f f 1 1ff7 0 2 1fbe 1 2 1fa6 2 2 1f8e 3 2 1f76 4 2 1f5e 5 2 1f46 6 2 1f2e 7 2 1f16 8 2 007e 9 2 0066 a 2 004e b 2 0036 c 2 001e d 2 0006 e 2 1fee f 2 1fd6 0 3 1f9d 1 3 1f85 2 3 1f6d 3 3 1f55 4 3 1f3d 5 3 1f25 6 3 1f0d 7 3 1ef5 8 3 005d 9 3 0045 a 3 002d b 3 0015 c 3 1ffd d 3 1fe5 e 3 1fcd f 3 1fb5 0 4 1f7c 1 4 1f64 2 4 1f4c 3 4 1f34 4 4 1f1c 5 4 1f04 6 4 1eec 7 4 1ed4 8 4 003c 9 4 0024 a 4 000c b 4 1ff4 c 4 1fdc d 4 1fc4 e 4 1fac f 4 1f94 0 5 1f5b 1 5 1f43 2 5 1f2b 3 5 1f13 4 5 1efb 5 5 1ee3 6 5 1ecb 7 5 1eb3 8 5 001b 9 5 0003 a 5 1feb b 5 1fd3 c 5 1fbb d 5 1fa3 e 5 1f8b f 5 1f73 0 6 1f3a 1 6 1f22 2 6 1f0a 3 6 1ef2 4 6 1eda 5 6 1ec2 6 6 1eaa 7 6 1e92 8 6 1ffa 9 6 1fe2 a 6 1fca b 6 1fb2 c 6 1f9a d 6 1f82 e 6 1f6a f 6 1f52 0 7 1f19 1 7 1f01 2 7 1ee9 3 7 1ed1 4 7 1eb9 5 7 1ea1 6 7 1e89 7 7 1e71 8 7 1fd9 9 7 1fc1 a 7 1fa9 b 7 1f91 c 7 1f79 d 7 1f61 e 7 1f49 f 7 1f31 0 8 0108 1 8 00f0 2 8 00d8 3 8 00c0 4 8 00a8 5 8 0090 6 8 0078 7 8 0060 8 8 01c8 9 8 01b0 a 8 0198 b 8 0180 c 8 0168 d 8 0150 e 8 0138 f 8 0120 0 9 00e7 1 9 00cf 2 9 00b7 3 9 009f 4 9 0087 5 9 006f 6 9 0057 7 9 003f 8 9 01a7 9 9 018f a 9 0177 b 9 015f c 9 0147 d 9 012f e 9 0117 f 9 00ff 0 a 00c6 1 a 00ae 2 a 0096 3 a 007e 4 a 0066 5 a 004e 6 a 0036 7 a 001e 8 a 0186 9 a 016e a a 0156 b a 013e c a 0126 d a 010e e a 00f6 f a 00de 0 b 00a5 1 b 008d 2 b 0075 3 b 005d 4 b 0045 5 b 002d 6 b 0015 7 b 1ffd 8 b 0165 9 b 014d a b 0135 b b 011d c b 0105 d b 00ed e b 00d5 f b 00bd 0 c 0084 1 c 006c 2 c 0054 3 c 003c 4 c 0024 5 c 000c 6 c 1ff4 7 c 1fdc 8 c 0144 9 c 012c a c 0114 b c 00fc c c 00e4 d c 00cc e c 00b4 f c 009c 0 d 0063 1 d 004b 2 d 0033 3 d 001b 4 d 0003 5 d 1feb 6 d 1fd3 7 d 1fbb 8 d 0123 9 d 010b a d 00f3 b d 00db c d 00c3 d d 00ab e d 0093 f d 007b 0 e 0042 1 e 002a 2 e 0012 3 e 1ffa 4 e 1fe2 5 e 1fca 6 e 1fb2 7 e 1f9a 8 e 0102 9 e 00ea a e 00d2 b e 00ba c e 00a2 d e 008a e e 0072 f e 005a 0 f 0021 1 f 0009 2 f 1ff1 3 f 1fd9 4 f 1fc1 5 f 1fa9 6 f 1f91 7 f 1f79 8 f 00e1 9 f 00c9 a f 00b1 b f 0099 c f 0081 d f 0069 e f 0051 f f 0039 iverilog-12_0/ivtest/gold/mem1-vlog95.gold000066400000000000000000000017051435245347300204460ustar00rootroot00000000000000WARNING: vlog95.v:24: $readmemb: The behaviour for reg[...] mem[N:0]; $readmemb("...", mem); changed in the 1364-2005 standard. To avoid ambiguity, use mem[0:N] or explicit range parameters $readmemb("...", mem, start, stop);. Defaulting to 1364-2005 behavior. mem[ 0] = 000100 mem[ 1] = 000200 mem[ 2] = 000400 mem[ 3] = 000801 mem[ 4] = 001000 mem[ 5] = 002000 mem[ 6] = 004000 mem[ 7] = 008000 mem[ 8] = 010000 mem[ 9] = 020000 mem[ 10] = 040000 mem[ 11] = 080000 mem[ 12] = 100000 mem[ 13] = 200002 mem[ 14] = 400000 mem[ 15] = 800000 0 000100 1 000200 2 000400 3 000801 4 001000 5 002000 6 004000 7 008000 8 010000 9 020000 10 040000 11 080000 12 100000 13 200002 14 400000 15 800000 iverilog-12_0/ivtest/gold/mem1.gold000066400000000000000000000017161435245347300173250ustar00rootroot00000000000000WARNING: ./ivltests/mem1.v:42: $readmemb: The behaviour for reg[...] mem[N:0]; $readmemb("...", mem); changed in the 1364-2005 standard. To avoid ambiguity, use mem[0:N] or explicit range parameters $readmemb("...", mem, start, stop);. Defaulting to 1364-2005 behavior. mem[ 0] = 000100 mem[ 1] = 000200 mem[ 2] = 000400 mem[ 3] = 000801 mem[ 4] = 001000 mem[ 5] = 002000 mem[ 6] = 004000 mem[ 7] = 008000 mem[ 8] = 010000 mem[ 9] = 020000 mem[ 10] = 040000 mem[ 11] = 080000 mem[ 12] = 100000 mem[ 13] = 200002 mem[ 14] = 400000 mem[ 15] = 800000 0 000100 1 000200 2 000400 3 000801 4 001000 5 002000 6 004000 7 008000 8 010000 9 020000 10 040000 11 080000 12 100000 13 200002 14 400000 15 800000 iverilog-12_0/ivtest/gold/monitor.gold000066400000000000000000000005371435245347300201550ustar00rootroot00000000000000 0 clk=0 5 clk=1 10 clk=0 15 clk=1 20 clk=0 25 clk=1 30 clk=0 35 clk=1 40 clk=0 45 clk=1 50 clk=0 55 clk=1 60 clk=0 iverilog-12_0/ivtest/gold/monitor2.gold000066400000000000000000000000551435245347300202320ustar00rootroot00000000000000Time = 0 a = 0 Time = 1 a = 1 Time = 2 a = 0 iverilog-12_0/ivtest/gold/monitor3.gold000066400000000000000000000003411435245347300202310ustar00rootroot00000000000000 0: x=0.000000, y=0.000000 1: x=1.000000, y=0.000000 2: x=1.000000, y=2.000000 3: x=1.500000, y=2.000000 4: x=1.500000, y=5.100000 iverilog-12_0/ivtest/gold/multi_bit_strength.gold000066400000000000000000000002131435245347300223630ustar00rootroot00000000000000All three lines should match: ----------------------------- St0_Pu1_Pu1_St0 (reference) St0_Pu1_Pu1_St0 (display) St0_Pu1_Pu1_St0 (swrite) iverilog-12_0/ivtest/gold/multi_bit_strength_std.gold000066400000000000000000000002171435245347300232410ustar00rootroot00000000000000All three lines should match: ----------------------------- St0_Pu1_Pu1_St0 (reference) {St0,Pu1,Pu1,St0} (display) {St0,Pu1,Pu1,St0} (swrite) iverilog-12_0/ivtest/gold/negvalue.gold000066400000000000000000000000221435245347300202610ustar00rootroot00000000000000 8 (should be 8) iverilog-12_0/ivtest/gold/neq1.gold000066400000000000000000000006441435245347300173310ustar00rootroot00000000000000a=0 0 1 0 1 0 1 2 0 1 3 0 1 4 0 1 5 0 1 6 0 1 7 0 1 a=1 0 0 1 1 1 0 2 0 1 3 0 1 4 0 1 5 0 1 6 0 1 7 0 1 a=2 0 0 1 1 0 1 2 1 0 3 0 1 4 0 1 5 0 1 6 0 1 7 0 1 a=3 0 0 1 1 0 1 2 0 1 3 1 0 4 0 1 5 0 1 6 0 1 7 0 1 a=4 0 0 1 1 0 1 2 0 1 3 0 1 4 1 0 5 0 1 6 0 1 7 0 1 a=5 0 0 1 1 0 1 2 0 1 3 0 1 4 0 1 5 1 0 6 0 1 7 0 1 a=6 0 0 1 1 0 1 2 0 1 3 0 1 4 0 1 5 0 1 6 1 0 7 0 1 iverilog-12_0/ivtest/gold/nested_func.gold000066400000000000000000000000711435245347300207540ustar00rootroot00000000000000sum of 2 to 5 = 14 sum of 3 to 6 = 18 sum of 4 to 7 = 22 iverilog-12_0/ivtest/gold/nested_func_std.gold000066400000000000000000000001241435245347300216250ustar00rootroot00000000000000sum of 2 to 5 = 14 sum of 3 to 6 = 18 sum of 4 to 7 = 22 iverilog-12_0/ivtest/gold/nested_impl_event1.gold000066400000000000000000000001101435245347300222360ustar00rootroot00000000000000Triggered 1 at 30 Triggered 2 at 50 Triggered 1 at 60 Triggered 2 at 70 iverilog-12_0/ivtest/gold/nested_impl_event2.gold000066400000000000000000000001621435245347300222460ustar00rootroot00000000000000./ivltests/nested_impl_event2.v:9: warning: @* found no sensitivities so it will never trigger. Triggered 1 at 30 iverilog-12_0/ivtest/gold/packed_dims_invalid_class.gold000066400000000000000000000031721435245347300236220ustar00rootroot00000000000000ivltests/packed_dims_invalid_class.v:10: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_class.v:4: error: An unsized dimension is not allowed here. ivltests/packed_dims_invalid_class.v:12: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_class.v:14: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:14 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_class.v:5: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:5 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_class.v:16: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:16 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_class.v:18: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:18 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_class.v:6: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:6 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_class.v:20: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_class.v:20 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_class.v:22: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_class.v:7: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_class.v:24: error: A queue dimension is not allowed here. 13 error(s) during elaboration. iverilog-12_0/ivtest/gold/packed_dims_invalid_module.gold000066400000000000000000000053301435245347300240000ustar00rootroot00000000000000ivltests/packed_dims_invalid_module.v:15: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:16: error: An unsized dimension is not allowed here. ivltests/packed_dims_invalid_module.v:17: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:4: error: An unsized dimension is not allowed here. ivltests/packed_dims_invalid_module.v:19: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:19 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_module.v:5: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:5 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_module.v:21: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:21 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_module.v:5: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:5 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_module.v:23: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:23 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_module.v:6: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:6 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_module.v:25: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:25 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_module.v:6: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:6 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_module.v:27: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:28: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:29: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:7: error: A queue dimension is not allowed here. ivltests/packed_dims_invalid_module.v:10: error: An unsized dimension is not allowed here. ivltests/packed_dims_invalid_module.v:11: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:11 : This size expression violates the rule: 'sd0 ivltests/packed_dims_invalid_module.v:12: error: Dimension size must be greater than zero. ivltests/packed_dims_invalid_module.v:12 : This size expression violates the rule: -('sd1) ivltests/packed_dims_invalid_module.v:13: error: A queue dimension is not allowed here. 20 error(s) during elaboration. iverilog-12_0/ivtest/gold/param-width-ivl.gold000066400000000000000000000000231435245347300214610ustar00rootroot000000000000001001 1001 0101 101 iverilog-12_0/ivtest/gold/param-width.gold000066400000000000000000000000211435245347300206670ustar00rootroot000000000000001001 001 0101 01 iverilog-12_0/ivtest/gold/param_test1.gold000066400000000000000000000007761435245347300207130ustar00rootroot00000000000000OKAY: dat = 00000000, exp_dat = 0 OKAY: dat = 00000001, exp_dat = 1 OKAY: dat = 00000002, exp_dat = 2 OKAY: dat = 00000003, exp_dat = 3 OKAY: dat = 00000004, exp_dat = 4 OKAY: dat = 00000005, exp_dat = 5 OKAY: dat = 00000006, exp_dat = 6 OKAY: dat = 00000007, exp_dat = 7 OKAY: dat = 00000008, exp_dat = 8 OKAY: dat = 00000009, exp_dat = 9 OKAY: dat = 0000000a, exp_dat = a OKAY: dat = 0000000b, exp_dat = b OKAY: dat = 0000000c, exp_dat = c OKAY: dat = 0000000d, exp_dat = d OKAY: dat = 0000000e, exp_dat = e iverilog-12_0/ivtest/gold/param_test2.gold000066400000000000000000000000671435245347300207050ustar00rootroot00000000000000foo = ffffffffffffffffffffffffffffffffffffffffffffffff iverilog-12_0/ivtest/gold/param_test3.gold000066400000000000000000000002221435245347300206770ustar00rootroot00000000000000./ivltests/param_test3.v:25: warning: ignoring 3 extra parameter override(s) for instance 'am' of module 'm' which expects 0 parameter(s). PASSED iverilog-12_0/ivtest/gold/parameter_type-ivl.gold000066400000000000000000000002441435245347300222720ustar00rootroot00000000000000Implicit real: -1.00000 Implicit integer: -1 Unsigned: 255 Signed: -1 Real: -1.00000 Real time: -1.00000 Integer: -1 Time: 18446744073709551615 iverilog-12_0/ivtest/gold/parameter_type-vlog95.gold000066400000000000000000000002531435245347300226250ustar00rootroot00000000000000Implicit real: -1.00000 Implicit integer: -1 Unsigned: 255 Signed: -1 Real: -1.00000 Real time: -1.00000 Integer: -1 Time: 18446744073709551615 iverilog-12_0/ivtest/gold/parameter_type.gold000066400000000000000000000002221435245347300214760ustar00rootroot00000000000000Implicit real: -1 Implicit integer: -1 Unsigned: 255 Signed: -1 Real: -1 Real time: -1 Integer: -1 Time: 18446744073709551615 iverilog-12_0/ivtest/gold/pic-vlog95.gold000066400000000000000000000207601435245347300203640ustar00rootroot00000000000000Clearing SRAM. SYNTHETIC PIC 2.0. This is TEST #9 WARNING: vlog95.v:283: $readmemh(contrib/TEST9.ROM): Too many words in the file for the requested range [0:511]. 50: portc changes to: 00 50: portb changes to: 00 1650: portb changes to: 07 2150: portb changes to: 09 2650: portb changes to: 0c 3150: portb changes to: 0e 3650: portb changes to: 11 4150: portb changes to: 13 4650: portb changes to: 16 5150: portb changes to: 18 5650: portb changes to: 1b 6150: portb changes to: 1d 6650: portb changes to: 20 7150: portb changes to: 22 7650: portb changes to: 25 8150: portb changes to: 27 8650: portb changes to: 2a 9150: portb changes to: 2c 9650: portb changes to: 2f 10150: portb changes to: 31 10650: portb changes to: 34 11150: portb changes to: 36 12350: portc changes to: 01 12550: portb changes to: 3d 13050: portb changes to: 3e 13550: portb changes to: 3f 14050: portb changes to: 41 14550: portb changes to: 42 15050: portb changes to: 43 15550: portb changes to: 44 16050: portb changes to: 46 16550: portb changes to: 47 17050: portb changes to: 48 17550: portb changes to: 49 18050: portb changes to: 4b 18550: portb changes to: 4c 19050: portb changes to: 4d 19550: portb changes to: 4e 20050: portb changes to: 50 20550: portb changes to: 51 21050: portb changes to: 52 21550: portb changes to: 53 22050: portb changes to: 55 23250: portc changes to: 02 23450: portb changes to: 58 23950: portb changes to: 59 24450: portb changes to: 5a 25450: portb changes to: 5b 26450: portb changes to: 5c 26950: portb changes to: 5d 27950: portb changes to: 5e 28450: portb changes to: 5f 29450: portb changes to: 60 30450: portb changes to: 61 30950: portb changes to: 62 31950: portb changes to: 63 32450: portb changes to: 64 34150: portc changes to: 03 34350: portb changes to: 66 35850: portb changes to: 67 37350: portb changes to: 68 38850: portb changes to: 69 40850: portb changes to: 6a 42350: portb changes to: 6b 43850: portb changes to: 6c 45050: portc changes to: 04 45250: portb changes to: 6d 48750: portb changes to: 6e 51750: portb changes to: 6f 55950: portc changes to: 05 56150: portb changes to: 70 58150: portb changes to: 71 64650: portb changes to: 72 66850: portc changes to: 06 77750: portc changes to: 07 77950: portb changes to: 73 88650: portc changes to: 00 88850: portb changes to: 74 89350: portb changes to: 76 89850: portb changes to: 79 90350: portb changes to: 7b 90850: portb changes to: 7e 91350: portb changes to: 80 91850: portb changes to: 83 92350: portb changes to: 85 92850: portb changes to: 88 93350: portb changes to: 8a 93850: portb changes to: 8d 94350: portb changes to: 8f 94850: portb changes to: 92 95350: portb changes to: 94 95850: portb changes to: 97 96350: portb changes to: 99 96850: portb changes to: 9c 97350: portb changes to: 9e 97850: portb changes to: a1 98350: portb changes to: a3 99550: portc changes to: 01 99750: portb changes to: aa 100250: portb changes to: ab 100750: portb changes to: ac 101250: portb changes to: ae 101750: portb changes to: af 102250: portb changes to: b0 102750: portb changes to: b1 103250: portb changes to: b3 103750: portb changes to: b4 104250: portb changes to: b5 104750: portb changes to: b6 105250: portb changes to: b8 105750: portb changes to: b9 106250: portb changes to: ba 106750: portb changes to: bb 107250: portb changes to: bd 107750: portb changes to: be 108250: portb changes to: bf 108750: portb changes to: c0 109250: portb changes to: c2 110450: portc changes to: 02 110650: portb changes to: c5 111150: portb changes to: c6 111650: portb changes to: c7 112650: portb changes to: c8 113650: portb changes to: c9 114150: portb changes to: ca 115150: portb changes to: cb 115650: portb changes to: cc 116650: portb changes to: cd 117650: portb changes to: ce 118150: portb changes to: cf 119150: portb changes to: d0 119650: portb changes to: d1 121350: portc changes to: 03 121550: portb changes to: d3 122050: portb changes to: d4 124050: portb changes to: d5 125550: portb changes to: d6 127050: portb changes to: d7 128550: portb changes to: d8 130050: portb changes to: d9 132250: portc changes to: 04 132450: portb changes to: da 134950: portb changes to: db 138450: portb changes to: dc 141450: portb changes to: dd 143150: portc changes to: 05 147850: portb changes to: de 154050: portc changes to: 06 154250: portb changes to: df 164950: portc changes to: 07 175850: portc changes to: 00 176050: portb changes to: e0 176550: portb changes to: e2 177050: portb changes to: e5 177550: portb changes to: e7 178050: portb changes to: ea 178550: portb changes to: ec 179050: portb changes to: ef 179550: portb changes to: f1 180050: portb changes to: f4 180550: portb changes to: f6 181050: portb changes to: f9 181550: portb changes to: fb 182050: portb changes to: fe 182550: portb changes to: 00 183050: portb changes to: 03 183550: portb changes to: 05 184050: portb changes to: 08 184550: portb changes to: 0a 185050: portb changes to: 0d 185550: portb changes to: 0f 186750: portc changes to: 01 186950: portb changes to: 16 187450: portb changes to: 17 187950: portb changes to: 18 188450: portb changes to: 1a 188950: portb changes to: 1b 189450: portb changes to: 1c 189950: portb changes to: 1d 190450: portb changes to: 1f 190950: portb changes to: 20 191450: portb changes to: 21 191950: portb changes to: 22 192450: portb changes to: 24 192950: portb changes to: 25 193450: portb changes to: 26 193950: portb changes to: 27 194450: portb changes to: 29 194950: portb changes to: 2a 195450: portb changes to: 2b 195950: portb changes to: 2c 196450: portb changes to: 2e 197650: portc changes to: 02 197850: portb changes to: 31 198350: portb changes to: 32 198850: portb changes to: 33 199850: portb changes to: 34 Maximum cycles (2000) Exceeded. Halting simulation. iverilog-12_0/ivtest/gold/pic.gold000066400000000000000000000207701435245347300172420ustar00rootroot00000000000000Clearing SRAM. SYNTHETIC PIC 2.0. This is TEST #9 WARNING: ./contrib/pic.v:2046: $readmemh(contrib/TEST9.ROM): Too many words in the file for the requested range [0:511]. 50: portc changes to: 00 50: portb changes to: 00 1650: portb changes to: 07 2150: portb changes to: 09 2650: portb changes to: 0c 3150: portb changes to: 0e 3650: portb changes to: 11 4150: portb changes to: 13 4650: portb changes to: 16 5150: portb changes to: 18 5650: portb changes to: 1b 6150: portb changes to: 1d 6650: portb changes to: 20 7150: portb changes to: 22 7650: portb changes to: 25 8150: portb changes to: 27 8650: portb changes to: 2a 9150: portb changes to: 2c 9650: portb changes to: 2f 10150: portb changes to: 31 10650: portb changes to: 34 11150: portb changes to: 36 12350: portc changes to: 01 12550: portb changes to: 3d 13050: portb changes to: 3e 13550: portb changes to: 3f 14050: portb changes to: 41 14550: portb changes to: 42 15050: portb changes to: 43 15550: portb changes to: 44 16050: portb changes to: 46 16550: portb changes to: 47 17050: portb changes to: 48 17550: portb changes to: 49 18050: portb changes to: 4b 18550: portb changes to: 4c 19050: portb changes to: 4d 19550: portb changes to: 4e 20050: portb changes to: 50 20550: portb changes to: 51 21050: portb changes to: 52 21550: portb changes to: 53 22050: portb changes to: 55 23250: portc changes to: 02 23450: portb changes to: 58 23950: portb changes to: 59 24450: portb changes to: 5a 25450: portb changes to: 5b 26450: portb changes to: 5c 26950: portb changes to: 5d 27950: portb changes to: 5e 28450: portb changes to: 5f 29450: portb changes to: 60 30450: portb changes to: 61 30950: portb changes to: 62 31950: portb changes to: 63 32450: portb changes to: 64 34150: portc changes to: 03 34350: portb changes to: 66 35850: portb changes to: 67 37350: portb changes to: 68 38850: portb changes to: 69 40850: portb changes to: 6a 42350: portb changes to: 6b 43850: portb changes to: 6c 45050: portc changes to: 04 45250: portb changes to: 6d 48750: portb changes to: 6e 51750: portb changes to: 6f 55950: portc changes to: 05 56150: portb changes to: 70 58150: portb changes to: 71 64650: portb changes to: 72 66850: portc changes to: 06 77750: portc changes to: 07 77950: portb changes to: 73 88650: portc changes to: 00 88850: portb changes to: 74 89350: portb changes to: 76 89850: portb changes to: 79 90350: portb changes to: 7b 90850: portb changes to: 7e 91350: portb changes to: 80 91850: portb changes to: 83 92350: portb changes to: 85 92850: portb changes to: 88 93350: portb changes to: 8a 93850: portb changes to: 8d 94350: portb changes to: 8f 94850: portb changes to: 92 95350: portb changes to: 94 95850: portb changes to: 97 96350: portb changes to: 99 96850: portb changes to: 9c 97350: portb changes to: 9e 97850: portb changes to: a1 98350: portb changes to: a3 99550: portc changes to: 01 99750: portb changes to: aa 100250: portb changes to: ab 100750: portb changes to: ac 101250: portb changes to: ae 101750: portb changes to: af 102250: portb changes to: b0 102750: portb changes to: b1 103250: portb changes to: b3 103750: portb changes to: b4 104250: portb changes to: b5 104750: portb changes to: b6 105250: portb changes to: b8 105750: portb changes to: b9 106250: portb changes to: ba 106750: portb changes to: bb 107250: portb changes to: bd 107750: portb changes to: be 108250: portb changes to: bf 108750: portb changes to: c0 109250: portb changes to: c2 110450: portc changes to: 02 110650: portb changes to: c5 111150: portb changes to: c6 111650: portb changes to: c7 112650: portb changes to: c8 113650: portb changes to: c9 114150: portb changes to: ca 115150: portb changes to: cb 115650: portb changes to: cc 116650: portb changes to: cd 117650: portb changes to: ce 118150: portb changes to: cf 119150: portb changes to: d0 119650: portb changes to: d1 121350: portc changes to: 03 121550: portb changes to: d3 122050: portb changes to: d4 124050: portb changes to: d5 125550: portb changes to: d6 127050: portb changes to: d7 128550: portb changes to: d8 130050: portb changes to: d9 132250: portc changes to: 04 132450: portb changes to: da 134950: portb changes to: db 138450: portb changes to: dc 141450: portb changes to: dd 143150: portc changes to: 05 147850: portb changes to: de 154050: portc changes to: 06 154250: portb changes to: df 164950: portc changes to: 07 175850: portc changes to: 00 176050: portb changes to: e0 176550: portb changes to: e2 177050: portb changes to: e5 177550: portb changes to: e7 178050: portb changes to: ea 178550: portb changes to: ec 179050: portb changes to: ef 179550: portb changes to: f1 180050: portb changes to: f4 180550: portb changes to: f6 181050: portb changes to: f9 181550: portb changes to: fb 182050: portb changes to: fe 182550: portb changes to: 00 183050: portb changes to: 03 183550: portb changes to: 05 184050: portb changes to: 08 184550: portb changes to: 0a 185050: portb changes to: 0d 185550: portb changes to: 0f 186750: portc changes to: 01 186950: portb changes to: 16 187450: portb changes to: 17 187950: portb changes to: 18 188450: portb changes to: 1a 188950: portb changes to: 1b 189450: portb changes to: 1c 189950: portb changes to: 1d 190450: portb changes to: 1f 190950: portb changes to: 20 191450: portb changes to: 21 191950: portb changes to: 22 192450: portb changes to: 24 192950: portb changes to: 25 193450: portb changes to: 26 193950: portb changes to: 27 194450: portb changes to: 29 194950: portb changes to: 2a 195450: portb changes to: 2b 195950: portb changes to: 2c 196450: portb changes to: 2e 197650: portc changes to: 02 197850: portb changes to: 31 198350: portb changes to: 32 198850: portb changes to: 33 199850: portb changes to: 34 Maximum cycles (2000) Exceeded. Halting simulation. iverilog-12_0/ivtest/gold/pr1002.gold000066400000000000000000000010501435245347300174010ustar00rootroot00000000000000datain = 4095 dataout = 1023 expected = 1023 ... CHECK PASSED datain = 0 dataout = 0 expected = 0 ... CHECK PASSED datain = 8191 dataout = 2047 expected = 2047 ... CHECK PASSED datain = 4096 dataout = 1024 expected = 1024 ... CHECK PASSED datain = -4097 dataout = -1025 expected = -1025 ... CHECK PASSED datain = -8192 dataout = -2048 expected = -2048 ... CHECK PASSED datain = -1 dataout = -1 expected = -1 ... CHECK PASSED datain = -4096 dataout = -1024 expected = -1024 ... CHECK PASSED TEST PASSED :-) iverilog-12_0/ivtest/gold/pr1002_std.gold000066400000000000000000000010601435245347300202540ustar00rootroot00000000000000datain = 4095 dataout = 1023 expected = 1023 ... CHECK PASSED datain = 0 dataout = 0 expected = 0 ... CHECK PASSED datain = 8191 dataout = 2047 expected = 2047 ... CHECK PASSED datain = 4096 dataout = 1024 expected = 1024 ... CHECK PASSED datain = -4097 dataout = -1025 expected = -1025 ... CHECK PASSED datain = -8192 dataout = -2048 expected = -2048 ... CHECK PASSED datain = -1 dataout = -1 expected = -1 ... CHECK PASSED datain = -4096 dataout = -1024 expected = -1024 ... CHECK PASSED TEST PASSED :-) iverilog-12_0/ivtest/gold/pr1002a.gold000066400000000000000000000011531435245347300175460ustar00rootroot00000000000000datain = x dataout = X expected = X ... CHECK PASSED datain = 4095 dataout = 16380 expected = 16380 ... CHECK PASSED datain = 0 dataout = 0 expected = 0 ... CHECK PASSED datain = 8191 dataout = 32764 expected = 32764 ... CHECK PASSED datain = 4096 dataout = 16384 expected = 16384 ... CHECK PASSED datain = -4097 dataout = -16388 expected = -16388 ... CHECK PASSED datain = -8192 dataout = -32768 expected = -32768 ... CHECK PASSED datain = -1 dataout = -4 expected = -4 ... CHECK PASSED datain = -4096 dataout = -16384 expected = -16384 ... CHECK PASSED TEST PASSED :-) iverilog-12_0/ivtest/gold/pr1002a_std.gold000066400000000000000000000011641435245347300204220ustar00rootroot00000000000000datain = x dataout = X expected = X ... CHECK PASSED datain = 4095 dataout = 16380 expected = 16380 ... CHECK PASSED datain = 0 dataout = 0 expected = 0 ... CHECK PASSED datain = 8191 dataout = 32764 expected = 32764 ... CHECK PASSED datain = 4096 dataout = 16384 expected = 16384 ... CHECK PASSED datain = -4097 dataout = -16388 expected = -16388 ... CHECK PASSED datain = -8192 dataout = -32768 expected = -32768 ... CHECK PASSED datain = -1 dataout = -4 expected = -4 ... CHECK PASSED datain = -4096 dataout = -16384 expected = -16384 ... CHECK PASSED TEST PASSED :-) iverilog-12_0/ivtest/gold/pr1008.gold000066400000000000000000000000301435245347300174040ustar00rootroot00000000000000b = x b = 0 b = 1 b = 0 iverilog-12_0/ivtest/gold/pr1026.gold000066400000000000000000000026611435245347300174200ustar00rootroot00000000000000index= 0, foo=00000000000000000000000000000001 index= 1, foo=00000000000000000000000000000010 index= 2, foo=00000000000000000000000000000100 index= 3, foo=00000000000000000000000000001000 index= 4, foo=00000000000000000000000000010000 index= 5, foo=00000000000000000000000000100000 index= 6, foo=00000000000000000000000001000000 index= 7, foo=00000000000000000000000010000000 index= 8, foo=00000000000000000000000100000000 index= 9, foo=00000000000000000000001000000000 index=10, foo=00000000000000000000010000000000 index=11, foo=00000000000000000000100000000000 index=12, foo=00000000000000000001000000000000 index=13, foo=00000000000000000010000000000000 index=14, foo=00000000000000000100000000000000 index=15, foo=00000000000000001000000000000000 index=16, foo=00000000000000010000000000000000 index=17, foo=00000000000000100000000000000000 index=18, foo=00000000000001000000000000000000 index=19, foo=00000000000010000000000000000000 index=20, foo=00000000000100000000000000000000 index=21, foo=00000000001000000000000000000000 index=22, foo=00000000010000000000000000000000 index=23, foo=00000000100000000000000000000000 index=24, foo=00000001000000000000000000000000 index=25, foo=00000010000000000000000000000000 index=26, foo=00000100000000000000000000000000 index=27, foo=00001000000000000000000000000000 index=28, foo=00010000000000000000000000000000 index=29, foo=00100000000000000000000000000000 index=30, foo=01000000000000000000000000000000 iverilog-12_0/ivtest/gold/pr1033.gold000066400000000000000000000004421435245347300174110ustar00rootroot000000000000007ffffff5 7ffffffa = 7ffffff5 7ffffff6 7ffffffb = 7ffffff6 7ffffff7 7ffffffc = 7ffffff7 7ffffff8 7ffffffd = 7ffffff8 7ffffff9 7ffffffe = 7ffffff9 7ffffffa 7fffffff = 7ffffffa 7ffffffb 80000000 = 80000000 7ffffffc 80000001 = 80000001 7ffffffd 80000002 = 80000002 7ffffffe 80000003 = 80000003 iverilog-12_0/ivtest/gold/pr1065.gold000066400000000000000000000000601435245347300174120ustar00rootroot00000000000000Execution started. BBCDBBCD Execution finished. iverilog-12_0/ivtest/gold/pr1077.gold000066400000000000000000000000361435245347300174200ustar00rootroot00000000000000one y = x one y = 1 one y = 1 iverilog-12_0/ivtest/gold/pr1403406.gold000066400000000000000000000001441435245347300176430ustar00rootroot00000000000000Time scale of (top) is 1s / 1s Time scale of (other) is 1ms / 1ms Time scale of (other2) is 1s / 1s iverilog-12_0/ivtest/gold/pr1403406a.gold000066400000000000000000000001501435245347300200010ustar00rootroot00000000000000Time scale of (top) is 1ns / 1ns Time scale of (other) is 1ms / 1ms Time scale of (other2) is 1ns / 1ns iverilog-12_0/ivtest/gold/pr1403406b.gold000066400000000000000000000003541435245347300200100ustar00rootroot00000000000000Command File: Warning: default timescale is being set multiple times. : using the last valid +timescale found. Time scale of (top) is 1ns / 1ps Time scale of (other) is 1ms / 1ms Time scale of (other2) is 1ns / 1ps iverilog-12_0/ivtest/gold/pr1476440.gold000066400000000000000000000000711435245347300176520ustar00rootroot00000000000000tval = 0 tval = 2 tval = 6 tval = 10 tval = 14 tval = 18 iverilog-12_0/ivtest/gold/pr1492075.gold000066400000000000000000000005251435245347300176600ustar00rootroot00000000000000clkb=0 at 0 clkb=1 at 900 clkb=0 at 2100 clkb=1 at 2900 clkb=0 at 4100 clkb=1 at 4900 clkb=0 at 6100 clkb=1 at 6900 clkb=0 at 8100 clkb=1 at 8900 clkb=0 at 10100 iverilog-12_0/ivtest/gold/pr1494799.gold000066400000000000000000000003301435245347300176710ustar00rootroot00000000000000a = ffffb -5 b = 00000 0 c = 0000008 8 z = 1ffffff, -1, 1111111111111111111111111 y = 1ffffff, -1, 1111111111111111111111111 w = 1ffffff, -1, 1111111111111111111111111 1 1 1 1 iverilog-12_0/ivtest/gold/pr1574175.gold000066400000000000000000000000571435245347300176620ustar00rootroot00000000000000Both of these should be the same (3): 3, 3 iverilog-12_0/ivtest/gold/pr1587669.gold000066400000000000000000000022211435245347300176710ustar00rootroot00000000000000time=0: em=x, pz=0, p=00000 time=1000: em=1, pz=0, p=00000 time=10000: em=1, pz=0, p=00001 time=11000: em=0, pz=0, p=00001 time=20000: em=0, pz=0, p=00010 time=21000: em=1, pz=0, p=00010 time=21000: em=0, pz=0, p=00010 time=30000: em=0, pz=0, p=00011 time=40000: em=0, pz=0, p=00100 time=50000: em=0, pz=0, p=00101 time=60000: em=0, pz=0, p=00110 time=70000: em=0, pz=0, p=00111 time=80000: em=0, pz=0, p=01000 time=90000: em=0, pz=0, p=01001 time=100000: em=0, pz=0, p=01010 time=110000: em=0, pz=0, p=01011 time=120000: em=0, pz=0, p=01100 time=130000: em=0, pz=0, p=01101 time=140000: em=0, pz=0, p=01110 time=150000: em=0, pz=0, p=01111 time=160000: em=0, pz=0, p=10000 time=170000: em=0, pz=0, p=10001 time=180000: em=0, pz=0, p=10010 time=190000: em=0, pz=0, p=10011 time=200000: em=0, pz=0, p=10100 time=210000: em=0, pz=0, p=10101 time=220000: em=0, pz=0, p=10110 time=230000: em=0, pz=0, p=10111 time=240000: em=0, pz=0, p=11000 time=250000: em=0, pz=0, p=11001 time=260000: em=0, pz=0, p=11010 time=270000: em=0, pz=0, p=11011 time=280000: em=0, pz=0, p=11100 time=290000: em=0, pz=0, p=11101 time=300000: em=0, pz=0, p=11110 time=310000: em=0, pz=0, p=11111 iverilog-12_0/ivtest/gold/pr1589497.gold000066400000000000000000000001761435245347300177010ustar00rootroot00000000000000mydata = -5 mydata = -4 mydata = -3 mydata = -2 mydata = -1 mydata = 0 mydata = 1 mydata = 2 mydata = 3 mydata = 4 mydata = 5 iverilog-12_0/ivtest/gold/pr1623097.gold000066400000000000000000000010561435245347300176600ustar00rootroot00000000000000 0 clk=0, data=1111, clear=1111, state=0000 10 clk=0, data=1111, clear=0000, state=0000 20 clk=1, data=1111, clear=0000, state=0000 21 clk=1, data=1111, clear=0000, state=1111 30 clk=0, data=1111, clear=0010, state=1101 40 clk=0, data=1010, clear=0000, state=1101 50 clk=1, data=1010, clear=0000, state=1101 51 clk=1, data=1010, clear=0000, state=1010 60 clk=0, data=1010, clear=0000, state=1010 iverilog-12_0/ivtest/gold/pr1628288.gold000066400000000000000000000012301435245347300176610ustar00rootroot00000000000000 Reading bit 7 Reading bit 6 Reading bit 5 Reading bit 4 Reading bit 3 Reading bit 2 Reading bit 1 Reading bit 0 Read(0) 01010101 from the bit stream. Reading bit 7 Reading bit 6 Reading bit 5 Reading bit 4 Reading bit 3 Reading bit 2 Reading bit 1 Reading bit 0 Read(1) 10101010 from the bit stream. Reading bit 7 Reading bit 6 Reading bit 5 Reading bit 4 Reading bit 3 Reading bit 2 Reading bit 1 Reading bit 0 Read(2) 01010101 from the bit stream. Reading bit 7 Reading bit 6 Reading bit 5 Reading bit 4 Reading bit 3 Reading bit 2 Reading bit 1 Reading bit 0 Read(3) 10101010 from the bit stream. iverilog-12_0/ivtest/gold/pr1628300.gold000066400000000000000000000000351435245347300176440ustar00rootroot00000000000000sin(2) is not really 3.14159 iverilog-12_0/ivtest/gold/pr1629683.gold000066400000000000000000000001151435245347300176620ustar00rootroot00000000000000Printing the byte 01010101 with a header. Bad - 1x01010101, ok - 1x01010101. iverilog-12_0/ivtest/gold/pr1632861.gold000066400000000000000000000002571435245347300176610ustar00rootroot00000000000000At 1 value is 0000000000 At 2 value is 00000xxxxx At 3 value is 1111111111 At 4 value is 00000xxxxx At 5 value is 0000000000 At 6 value is 00xxxxxxxx At 7 value is 0000000000 iverilog-12_0/ivtest/gold/pr1634526.gold000066400000000000000000000002031435245347300176500ustar00rootroot00000000000000Working: This (255) should be 255. Broken: This (255) should be 255 Broken: This (255) should be 255. started with 256. iverilog-12_0/ivtest/gold/pr1636409.gold000066400000000000000000000003041435245347300176540ustar00rootroot00000000000000fail=x0x0, good=x0x0, en=0 at 1 fail=0000, good=0000, en=0 at 2 fail=0000, good=0000, en=1 at 11 fail=0101, good=0101, en=1 at 12 fail=1010, good=1010, en=0 at 31 fail=0000, good=0000, en=0 at 32 iverilog-12_0/ivtest/gold/pr1638985.gold000066400000000000000000000001371435245347300176730ustar00rootroot00000000000000Hello, World Positive x is 1.000000 -1.0 * x is -1.000000 0.0 - x is -1.000000 -x is -1.000000 iverilog-12_0/ivtest/gold/pr1639060.gold000066400000000000000000000000561435245347300176540ustar00rootroot000000000000001. The result is 10.0 2. The result is 10.0 iverilog-12_0/ivtest/gold/pr1639064.gold000066400000000000000000000001441435245347300176560ustar00rootroot000000000000001. The value is 100 2. The value is 100 3. The value is 100 4. The value is 100 5. The value is 100 iverilog-12_0/ivtest/gold/pr1639064b.gold000066400000000000000000000001661435245347300200240ustar00rootroot000000000000001. The value is 100000000 2. The value is 100000000 3. The value is 100 4. The value is 100 5. The value is 276447232 iverilog-12_0/ivtest/gold/pr1639968.gold000066400000000000000000000001701435245347300176720ustar00rootroot00000000000000 0 rf[0] is ffff ffff 10 rf[0] is 0000 0000 20 rf[0] is beef beef iverilog-12_0/ivtest/gold/pr1639971.gold000066400000000000000000000001761435245347300176720ustar00rootroot00000000000000 0 rf and slice: ffff f 10 rf and slice: 0000 0 20 rf and slice: beef f iverilog-12_0/ivtest/gold/pr1645277.gold000066400000000000000000000000461435245347300176620ustar00rootroot00000000000000expected 5; got 5 iverilog-12_0/ivtest/gold/pr1645518.gold000066400000000000000000000006011435245347300176550ustar00rootroot00000000000000 0 A = x B = x C = x D = x, eSeg = x 10 A = 0 B = 0 C = 0 D = 0, eSeg = x 12 A = 0 B = 0 C = 0 D = 0, eSeg = 1 20 A = 0 B = 0 C = 0 D = 1, eSeg = 1 22 A = 0 B = 0 C = 0 D = 1, eSeg = 0 30 A = 0 B = 0 C = 1 D = 0, eSeg = 0 32 A = 0 B = 0 C = 1 D = 0, eSeg = 1 iverilog-12_0/ivtest/gold/pr1648365.gold000066400000000000000000000001341435245347300176610ustar00rootroot00000000000000 0 w0=xxxxxxxx, w1=xxxxxxxx 31 w0=19999999, w1=2aaaaaaa iverilog-12_0/ivtest/gold/pr1661640.gold000066400000000000000000000002251435245347300176510ustar00rootroot00000000000000Hello world! Hello world! hello1; escaped NL: Hello world! 0048656c6c6f20776f726c64210a hello2; octal NL: Hello world! 0048656c6c6f20776f726c64210a iverilog-12_0/ivtest/gold/pr1661640_std.gold000066400000000000000000000002261435245347300205240ustar00rootroot00000000000000Hello world! Hello world! hello1; escaped NL: Hello world! 0048656c6c6f20776f726c64210a hello2; octal NL: Hello world! 0048656c6c6f20776f726c64210a iverilog-12_0/ivtest/gold/pr1664684.gold000066400000000000000000000001621435245347300176640ustar00rootroot00000000000000 0 x x0 x 0 40 0 00 0 0 iverilog-12_0/ivtest/gold/pr1687193.gold000066400000000000000000000005431435245347300176670ustar00rootroot00000000000000 Line 1 matches 3 args: 00000000 00000001 00000002 Line 2 matches 3 args: 00000003 00000004 00000005 Line 3 matches 2 args: 00000006 00000007 00000005 Line 4 matches 0 args: 00000006 00000007 00000005 Line 5 matches 3 args: 00000009 0000000a 0000000b iverilog-12_0/ivtest/gold/pr1688717.gold000066400000000000000000000002041435245347300176640ustar00rootroot00000000000000Orig = 123456, Second = 34, Minus Indexed = 34, Plus Indexed = 34 Orig = 123456, Second = 34, Minus Indexed = 34, Plus Indexed = 34 iverilog-12_0/ivtest/gold/pr1698499.gold000066400000000000000000000001451435245347300177000ustar00rootroot00000000000000reset reset done OK: 662372300238342615234 * -6 + -662372300237642615234 == -4636606101667698306638 iverilog-12_0/ivtest/gold/pr1698658.gold000066400000000000000000000000521435245347300176720ustar00rootroot00000000000000The time is 0 uS The time is 1 uS iverilog-12_0/ivtest/gold/pr1698659.gold000066400000000000000000000002241435245347300176740ustar00rootroot00000000000000top var is (0) top.lwr var is (1) top.lwr.elwr var is (0) Up reference to me (0) Up reference to parent (1) Up reference is (1) othertop var is (1) iverilog-12_0/ivtest/gold/pr1698820-v10.gold000066400000000000000000000002361435245347300202710ustar00rootroot00000000000000The variable is 10 The variable is 01010 The variable is 12 The variable is 0a The variable is 10 The variable is 01010 The variable is 12 The variable is 0a iverilog-12_0/ivtest/gold/pr1698820-vlog95.gold000066400000000000000000000003431435245347300210070ustar00rootroot00000000000000The variable is 10 The variable is 01010 The variable is 12 The variable is 0a The variable is 10 The variable is 01010 The variable is 12 The variable is 0a WARNING: vlog95.v:25: could not close MCD STDOUT (0x1) in $fclose(). iverilog-12_0/ivtest/gold/pr1698820.gold000066400000000000000000000003611435245347300176640ustar00rootroot00000000000000The variable is 10 The variable is 01010 The variable is 12 The variable is 0a The variable is 10 The variable is 01010 The variable is 12 The variable is 0a WARNING: ./ivltests/pr1698820.v:17: could not close MCD STDOUT (0x1) in $fclose(). iverilog-12_0/ivtest/gold/pr1699444.gold000066400000000000000000000000541435245347300176660ustar00rootroot00000000000000Output a slash \. Output a double slash \\. iverilog-12_0/ivtest/gold/pr1699519.gold000066400000000000000000000002121435245347300176650ustar00rootroot00000000000000Checking h and H: a5, a5 Checking x and X: a5, a5 Checking g and G: 1.23457e+09, 1.23457E+09 Checking e and E: 1.234568e+09, 1.234568E+09 iverilog-12_0/ivtest/gold/pr1701855.gold000066400000000000000000000002711435245347300176550ustar00rootroot00000000000000Time scale of (top) is 1us / 1ns Time scale of (top) is 1us / 1ns Time scale of (top.dut) is 10ns / 10ps Time scale of (top.dut.dut) is 1ns / 10ps Time scale of (othertop) is 1ms / 1us iverilog-12_0/ivtest/gold/pr1701855b.gold000066400000000000000000000017231435245347300200220ustar00rootroot00000000000000Time scale of (dummy) is 100ns / 100ps Time scale of (dummy.ipval) is 100ns / 100ps Time scale of (top) is 1us / 1ns Time scale of (top.ipval) is 1us / 1ns Time scale of (top.spval) is 1us / 1ns Time scale of (top.rpval) is 1us / 1ns Time scale of (top.evt) is 1us / 1ns Time scale of (top.rgval) is 1us / 1ns Time scale of (top.rgval[0:0]) is 1us / 1ns Time scale of (top.rgarr) is 1us / 1ns Time scale of (top.rgarr[0]) is 1us / 1ns Time scale of (top.wval) is 1us / 1ns Time scale of (top.wval[0:0]) is 1us / 1ns Time scale of (top.warr) is 1us / 1ns Time scale of (top.warr[0]) is 1us / 1ns Time scale of (top.ival) is 1us / 1ns Time scale of (top.ival[1:1]) is 1us / 1ns Time scale of (top.rval) is 1us / 1ns Time scale of (top.rarr) is 1us / 1ns Time scale of (top.rarr[0]) is 1us / 1ns Time scale of (top.tval) is 1us / 1ns Time scale of (top.blk) is 1us / 1ns Time scale of (top.frk) is 1us / 1ns Time scale of (top.tsk) is 1us / 1ns Time scale of (top.fnc) is 1us / 1ns iverilog-12_0/ivtest/gold/pr1701889.gold000066400000000000000000000013361435245347300176670ustar00rootroot00000000000000----- Using real times ----- The time one unit ago was : 0 The time one unit ago was : 0 The time now is : 1 One time unit from now it will be: 2 The time at 20 will be : 20 The time at 40 will be : 40 ----- Using integer times ----- The time one unit ago was : 100 The time one unit ago was : 100 The time now is : 101 One time unit from now it will be: 102 The time at 120 will be : 120 The time at 140 will be : 140 iverilog-12_0/ivtest/gold/pr1701890-ivl.gold000066400000000000000000000000521435245347300204410ustar00rootroot00000000000000rval1=1.00000 rval2=2.00000 rtval=1.00000 iverilog-12_0/ivtest/gold/pr1701890.gold000066400000000000000000000000301435245347300176450ustar00rootroot00000000000000rval1=1 rval2=2 rtval=1 iverilog-12_0/ivtest/gold/pr1702593.gold000066400000000000000000000000461435245347300176550ustar00rootroot00000000000000The value is -1.00 The value is -1.00 iverilog-12_0/ivtest/gold/pr1703120.gold000066400000000000000000000010321435245347300176340ustar00rootroot00000000000000--- Printing as real --- 1/0 is 0.000000. (Should be 0 -- x prints as 0) 1/0.0 is inf. (Should be inf) 1.0/0 is inf. (Should be inf) 1.0/0.0 is inf. (should be inf) 1/integer zero is 0.000000. (Should be 0 -- x prints as 0) 1/real zero is inf. (should be inf) 1.0/integer zero is inf. (Should be inf) 1.0/real zero is inf. --- Printing as integer --- 1/0 is x (Should be x) 1/0.0 is inf 1.0/0 is inf 1.0/0.0 is inf 1/integer zero is x. (Should be x) 1/real zero is inf. 1.0/integer zero is inf. 1.0/real zero is inf. iverilog-12_0/ivtest/gold/pr1704726a-v10.gold000066400000000000000000000024061435245347300204240ustar00rootroot00000000000000./ivltests/pr1704726a.v:8: error: duplicate definition for parameter 'name_pp' in 'top'. ./ivltests/pr1704726a.v:11: error: parameter and localparam in 'top' have the same name 'name_pl'. ./ivltests/pr1704726a.v:14: error: localparam and parameter in 'top' have the same name 'name_lp'. ./ivltests/pr1704726a.v:17: error: duplicate definition for localparam 'name_ll' in 'top'. ./ivltests/pr1704726a.v:24: error: genvar 'name_vv' has already been declared. ./ivltests/pr1704726a.v:23: the previous declaration is here. ./ivltests/pr1704726a.v:33: error: duplicate definition for task 'name_tt' in 'top'. ./ivltests/pr1704726a.v:43: error: duplicate definition for task 'name_tt' in 'top' (generate). ./ivltests/pr1704726a.v:39: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726a.v:57: error: duplicate definition for function 'name_ff' in 'top'. ./ivltests/pr1704726a.v:69: error: duplicate definition for function 'name_ff' in 'top' (generate). ./ivltests/pr1704726a.v:64: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726a.v:81: error: duplicate definition for named event 'name_ee' in 'top'. ./ivltests/pr1704726a.v:87: error: duplicate definition for specparam 'name_ss' in 'top'. iverilog-12_0/ivtest/gold/pr1704726a.gold000066400000000000000000000040521435245347300200170ustar00rootroot00000000000000./ivltests/pr1704726a.v:8: error: 'name_pp' has already been declared in this scope. ./ivltests/pr1704726a.v:7: : It was declared here as a parameter. ./ivltests/pr1704726a.v:11: error: 'name_pl' has already been declared in this scope. ./ivltests/pr1704726a.v:10: : It was declared here as a parameter. ./ivltests/pr1704726a.v:14: error: 'name_lp' has already been declared in this scope. ./ivltests/pr1704726a.v:13: : It was declared here as a parameter. ./ivltests/pr1704726a.v:17: error: 'name_ll' has already been declared in this scope. ./ivltests/pr1704726a.v:16: : It was declared here as a parameter. ./ivltests/pr1704726a.v:24: error: 'name_vv' has already been declared in this scope. ./ivltests/pr1704726a.v:23: : It was declared here as a genvar. ./ivltests/pr1704726a.v:33: error: 'name_tt' has already been declared in this scope. ./ivltests/pr1704726a.v:30: : It was declared here as a task. ./ivltests/pr1704726a.v:43: error: 'name_tt' has already been declared in this scope. ./ivltests/pr1704726a.v:40: : It was declared here as a task. ./ivltests/pr1704726a.v:39: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726a.v:57: error: 'name_ff' has already been declared in this scope. ./ivltests/pr1704726a.v:53: : It was declared here as a function. ./ivltests/pr1704726a.v:64: error: 'task_blk' has already been declared in this scope. ./ivltests/pr1704726a.v:39: : It was declared here as a generate block. ./ivltests/pr1704726a.v:69: error: 'name_ff' has already been declared in this scope. ./ivltests/pr1704726a.v:65: : It was declared here as a function. ./ivltests/pr1704726a.v:64: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726a.v:81: error: 'name_ee' has already been declared in this scope. ./ivltests/pr1704726a.v:80: : It was declared here as an event. ./ivltests/pr1704726a.v:87: error: 'name_ss' has already been declared in this scope. ./ivltests/pr1704726a.v:86: : It was declared here as a parameter. iverilog-12_0/ivtest/gold/pr1704726c-v10.gold000066400000000000000000000153411435245347300204300ustar00rootroot00000000000000./ivltests/pr1704726c.v:517: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:527: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:538: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:551: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:559: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:569: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:577: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:584: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:589: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:4: error: parameter and genvar in 'top' have the same name 'name_v'. ./ivltests/pr1704726c.v:5: error: localparam and genvar in 'top' have the same name 'name_lpv'. ./ivltests/pr1704726c.v:46: error: task and parameter in 'top' have the same name 'name_t'. ./ivltests/pr1704726c.v:60: error: task and genvar in 'top' have the same name 'name_tv'. ./ivltests/pr1704726c.v:68: error: function and parameter in 'top' have the same name 'name_f'. ./ivltests/pr1704726c.v:77: error: function and task in 'top' have the same name 'name_ft'. ./ivltests/pr1704726c.v:92: error: function and genvar in 'top' have the same name 'name_fv'. ./ivltests/pr1704726c.v:101: error: module instance and parameter in 'top' have the same name 'name_i'. ./ivltests/pr1704726c.v:107: error: module instance and task in 'top' have the same name 'name_it'. ./ivltests/pr1704726c.v:114: error: module instance and function in 'top' have the same name 'name_if'. ./ivltests/pr1704726c.v:123: error: module instance and genvar in 'top' have the same name 'name_iv'. ./ivltests/pr1704726c.v:127: error: module instance and module instance in 'top' have the same name 'name_ii'. ./ivltests/pr1704726c.v:133: error: named block and parameter in 'top' have the same name 'name_b'. ./ivltests/pr1704726c.v:141: error: named block and task in 'top' have the same name 'name_bt'. ./ivltests/pr1704726c.v:150: error: named block and function in 'top' have the same name 'name_bf'. ./ivltests/pr1704726c.v:161: error: named block and genvar in 'top' have the same name 'name_bv'. ./ivltests/pr1704726c.v:167: error: named block and module instance in 'top' have the same name 'name_bi'. ./ivltests/pr1704726c.v:175: error: named block and sequential block in 'top' have the same name 'name_bb'. ./ivltests/pr1704726c.v:183: error: named event and parameter in 'top' have the same name 'name_e'. ./ivltests/pr1704726c.v:215: error: named event and sequential block in 'top' have the same name 'name_eb'. ./ivltests/pr1704726c.v:196: error: named event and function in 'top' have the same name 'name_ef'. ./ivltests/pr1704726c.v:209: error: named event and module instance in 'top' have the same name 'name_ei'. ./ivltests/pr1704726c.v:189: error: named event and task in 'top' have the same name 'name_et'. ./ivltests/pr1704726c.v:205: error: named event and genvar in 'top' have the same name 'name_ev'. ./ivltests/pr1704726c.v:226: error: generate "loop" and parameter in 'top' have the same name 'name_gl'. ./ivltests/pr1704726c.v:236: error: generate "loop" and task in 'top' have the same name 'name_glt'. ./ivltests/pr1704726c.v:247: error: generate "loop" and function in 'top' have the same name 'name_glf'. ./ivltests/pr1704726c.v:260: error: generate "loop" and genvar in 'top' have the same name 'name_glv'. ./ivltests/pr1704726c.v:268: error: generate "loop" and module instance in 'top' have the same name 'name_gli'. ./ivltests/pr1704726c.v:278: error: generate "loop" and sequential block in 'top' have the same name 'name_glb'. ./ivltests/pr1704726c.v:286: error: generate "loop" and named event in 'top' have the same name 'name_gle'. ./ivltests/pr1704726c.v:298: error: generate "loop" and generate block in 'top' have the same name 'name_glgl'. ./ivltests/pr1704726c.v:308: error: generate "if" and parameter in 'top' have the same name 'name_gi'. ./ivltests/pr1704726c.v:318: error: generate "if" and task in 'top' have the same name 'name_git'. ./ivltests/pr1704726c.v:329: error: generate "if" and function in 'top' have the same name 'name_gif'. ./ivltests/pr1704726c.v:342: error: generate "if" and genvar in 'top' have the same name 'name_giv'. ./ivltests/pr1704726c.v:350: error: generate "if" and module instance in 'top' have the same name 'name_gii'. ./ivltests/pr1704726c.v:360: error: generate "if" and sequential block in 'top' have the same name 'name_gib'. ./ivltests/pr1704726c.v:368: error: generate "if" and named event in 'top' have the same name 'name_gie'. ./ivltests/pr1704726c.v:380: error: generate "if" and generate block in 'top' have the same name 'name_gigi'. ./ivltests/pr1704726c.v:390: error: generate "case" and parameter in 'top' have the same name 'name_gc'. ./ivltests/pr1704726c.v:405: error: generate "case" and task in 'top' have the same name 'name_gct'. ./ivltests/pr1704726c.v:421: error: generate "case" and function in 'top' have the same name 'name_gcf'. ./ivltests/pr1704726c.v:439: error: generate "case" and genvar in 'top' have the same name 'name_gcv'. ./ivltests/pr1704726c.v:452: error: generate "case" and module instance in 'top' have the same name 'name_gci'. ./ivltests/pr1704726c.v:467: error: generate "case" and sequential block in 'top' have the same name 'name_gcb'. ./ivltests/pr1704726c.v:480: error: generate "case" and named event in 'top' have the same name 'name_gce'. ./ivltests/pr1704726c.v:502: error: generate "case" and generate block in 'top' have the same name 'name_gcgc'. ./ivltests/pr1704726c.v:517: error: generate "block" and parameter in 'top' have the same name 'name_gb'. ./ivltests/pr1704726c.v:527: error: generate "block" and task in 'top' have the same name 'name_gbt'. ./ivltests/pr1704726c.v:538: error: generate "block" and function in 'top' have the same name 'name_gbf'. ./ivltests/pr1704726c.v:551: error: generate "block" and genvar in 'top' have the same name 'name_gbv'. ./ivltests/pr1704726c.v:559: error: generate "block" and module instance in 'top' have the same name 'name_gbi'. ./ivltests/pr1704726c.v:569: error: generate "block" and sequential block in 'top' have the same name 'name_gbb'. ./ivltests/pr1704726c.v:577: error: generate "block" and named event in 'top' have the same name 'name_gbe'. ./ivltests/pr1704726c.v:589: error: generate "block" and generate block in 'top' have the same name 'name_gbgb'. 57 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr1704726c.gold000066400000000000000000000232371435245347300200270ustar00rootroot00000000000000./ivltests/pr1704726c.v:24: error: 'name_v' has already been declared in this scope. ./ivltests/pr1704726c.v:4: : It was declared here as a parameter. ./ivltests/pr1704726c.v:32: error: 'name_lpv' has already been declared in this scope. ./ivltests/pr1704726c.v:5: : It was declared here as a parameter. ./ivltests/pr1704726c.v:46: error: 'name_t' has already been declared in this scope. ./ivltests/pr1704726c.v:7: : It was declared here as a parameter. ./ivltests/pr1704726c.v:60: error: 'name_tv' has already been declared in this scope. ./ivltests/pr1704726c.v:54: : It was declared here as a genvar. ./ivltests/pr1704726c.v:68: error: 'name_f' has already been declared in this scope. ./ivltests/pr1704726c.v:8: : It was declared here as a parameter. ./ivltests/pr1704726c.v:77: error: 'name_ft' has already been declared in this scope. ./ivltests/pr1704726c.v:74: : It was declared here as a task. ./ivltests/pr1704726c.v:92: error: 'name_fv' has already been declared in this scope. ./ivltests/pr1704726c.v:86: : It was declared here as a genvar. ./ivltests/pr1704726c.v:101: error: 'name_i' has already been declared in this scope. ./ivltests/pr1704726c.v:9: : It was declared here as a parameter. ./ivltests/pr1704726c.v:107: error: 'name_it' has already been declared in this scope. ./ivltests/pr1704726c.v:104: : It was declared here as a task. ./ivltests/pr1704726c.v:114: error: 'name_if' has already been declared in this scope. ./ivltests/pr1704726c.v:110: : It was declared here as a function. ./ivltests/pr1704726c.v:123: error: 'name_iv' has already been declared in this scope. ./ivltests/pr1704726c.v:117: : It was declared here as a genvar. ./ivltests/pr1704726c.v:127: error: 'name_ii' has already been declared in this scope. ./ivltests/pr1704726c.v:126: : It was declared here as an instance name. ./ivltests/pr1704726c.v:133: error: 'name_b' has already been declared in this scope. ./ivltests/pr1704726c.v:10: : It was declared here as a parameter. ./ivltests/pr1704726c.v:141: error: 'name_bt' has already been declared in this scope. ./ivltests/pr1704726c.v:138: : It was declared here as a task. ./ivltests/pr1704726c.v:150: error: 'name_bf' has already been declared in this scope. ./ivltests/pr1704726c.v:146: : It was declared here as a function. ./ivltests/pr1704726c.v:161: error: 'name_bv' has already been declared in this scope. ./ivltests/pr1704726c.v:155: : It was declared here as a genvar. ./ivltests/pr1704726c.v:167: error: 'name_bi' has already been declared in this scope. ./ivltests/pr1704726c.v:166: : It was declared here as an instance name. ./ivltests/pr1704726c.v:175: error: 'name_bb' has already been declared in this scope. ./ivltests/pr1704726c.v:172: : It was declared here as a named block. ./ivltests/pr1704726c.v:183: error: 'name_e' has already been declared in this scope. ./ivltests/pr1704726c.v:15: : It was declared here as a parameter. ./ivltests/pr1704726c.v:189: error: 'name_et' has already been declared in this scope. ./ivltests/pr1704726c.v:186: : It was declared here as a task. ./ivltests/pr1704726c.v:196: error: 'name_ef' has already been declared in this scope. ./ivltests/pr1704726c.v:192: : It was declared here as a function. ./ivltests/pr1704726c.v:205: error: 'name_ev' has already been declared in this scope. ./ivltests/pr1704726c.v:199: : It was declared here as a genvar. ./ivltests/pr1704726c.v:209: error: 'name_ei' has already been declared in this scope. ./ivltests/pr1704726c.v:208: : It was declared here as an instance name. ./ivltests/pr1704726c.v:215: error: 'name_eb' has already been declared in this scope. ./ivltests/pr1704726c.v:212: : It was declared here as a named block. ./ivltests/pr1704726c.v:226: error: 'name_gl' has already been declared in this scope. ./ivltests/pr1704726c.v:11: : It was declared here as a parameter. ./ivltests/pr1704726c.v:236: error: 'name_glt' has already been declared in this scope. ./ivltests/pr1704726c.v:232: : It was declared here as a task. ./ivltests/pr1704726c.v:247: error: 'name_glf' has already been declared in this scope. ./ivltests/pr1704726c.v:242: : It was declared here as a function. ./ivltests/pr1704726c.v:260: error: 'name_glv' has already been declared in this scope. ./ivltests/pr1704726c.v:253: : It was declared here as a genvar. ./ivltests/pr1704726c.v:268: error: 'name_gli' has already been declared in this scope. ./ivltests/pr1704726c.v:266: : It was declared here as an instance name. ./ivltests/pr1704726c.v:278: error: 'name_glb' has already been declared in this scope. ./ivltests/pr1704726c.v:274: : It was declared here as a named block. ./ivltests/pr1704726c.v:286: error: 'name_gle' has already been declared in this scope. ./ivltests/pr1704726c.v:284: : It was declared here as an event. ./ivltests/pr1704726c.v:298: error: 'name_glgl' has already been declared in this scope. ./ivltests/pr1704726c.v:293: : It was declared here as a generate block. ./ivltests/pr1704726c.v:308: error: 'name_gi' has already been declared in this scope. ./ivltests/pr1704726c.v:12: : It was declared here as a parameter. ./ivltests/pr1704726c.v:318: error: 'name_git' has already been declared in this scope. ./ivltests/pr1704726c.v:314: : It was declared here as a task. ./ivltests/pr1704726c.v:329: error: 'name_gif' has already been declared in this scope. ./ivltests/pr1704726c.v:324: : It was declared here as a function. ./ivltests/pr1704726c.v:342: error: 'name_giv' has already been declared in this scope. ./ivltests/pr1704726c.v:335: : It was declared here as a genvar. ./ivltests/pr1704726c.v:350: error: 'name_gii' has already been declared in this scope. ./ivltests/pr1704726c.v:348: : It was declared here as an instance name. ./ivltests/pr1704726c.v:360: error: 'name_gib' has already been declared in this scope. ./ivltests/pr1704726c.v:356: : It was declared here as a named block. ./ivltests/pr1704726c.v:368: error: 'name_gie' has already been declared in this scope. ./ivltests/pr1704726c.v:366: : It was declared here as an event. ./ivltests/pr1704726c.v:380: error: 'name_gigi' has already been declared in this scope. ./ivltests/pr1704726c.v:375: : It was declared here as a generate block. ./ivltests/pr1704726c.v:391: error: 'name_gc' has already been declared in this scope. ./ivltests/pr1704726c.v:13: : It was declared here as a parameter. ./ivltests/pr1704726c.v:406: error: 'name_gct' has already been declared in this scope. ./ivltests/pr1704726c.v:401: : It was declared here as a task. ./ivltests/pr1704726c.v:422: error: 'name_gcf' has already been declared in this scope. ./ivltests/pr1704726c.v:416: : It was declared here as a function. ./ivltests/pr1704726c.v:440: error: 'name_gcv' has already been declared in this scope. ./ivltests/pr1704726c.v:432: : It was declared here as a genvar. ./ivltests/pr1704726c.v:453: error: 'name_gci' has already been declared in this scope. ./ivltests/pr1704726c.v:450: : It was declared here as an instance name. ./ivltests/pr1704726c.v:468: error: 'name_gcb' has already been declared in this scope. ./ivltests/pr1704726c.v:463: : It was declared here as a named block. ./ivltests/pr1704726c.v:481: error: 'name_gce' has already been declared in this scope. ./ivltests/pr1704726c.v:478: : It was declared here as an event. ./ivltests/pr1704726c.v:503: error: 'name_gcgc' has already been declared in this scope. ./ivltests/pr1704726c.v:493: : It was declared here as a generate block. ./ivltests/pr1704726c.v:517: error: 'name_gb' has already been declared in this scope. ./ivltests/pr1704726c.v:14: : It was declared here as a parameter. ./ivltests/pr1704726c.v:517: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:527: error: 'name_gbt' has already been declared in this scope. ./ivltests/pr1704726c.v:523: : It was declared here as a task. ./ivltests/pr1704726c.v:527: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:538: error: 'name_gbf' has already been declared in this scope. ./ivltests/pr1704726c.v:533: : It was declared here as a function. ./ivltests/pr1704726c.v:538: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:551: error: 'name_gbv' has already been declared in this scope. ./ivltests/pr1704726c.v:544: : It was declared here as a genvar. ./ivltests/pr1704726c.v:551: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:559: error: 'name_gbi' has already been declared in this scope. ./ivltests/pr1704726c.v:557: : It was declared here as an instance name. ./ivltests/pr1704726c.v:559: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:569: error: 'name_gbb' has already been declared in this scope. ./ivltests/pr1704726c.v:565: : It was declared here as a named block. ./ivltests/pr1704726c.v:569: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:577: error: 'name_gbe' has already been declared in this scope. ./ivltests/pr1704726c.v:575: : It was declared here as an event. ./ivltests/pr1704726c.v:577: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:584: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726c.v:589: error: 'name_gbgb' has already been declared in this scope. ./ivltests/pr1704726c.v:584: : It was declared here as a generate block. ./ivltests/pr1704726c.v:589: warning: Anachronistic use of named begin/end to surround generate schemes. iverilog-12_0/ivtest/gold/pr1704726d-v10.gold000066400000000000000000000023131435245347300204240ustar00rootroot00000000000000./ivltests/pr1704726d.v:82: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726d.v:12: error: signal and parameter in 'top' have the same name 'name0_s'. ./ivltests/pr1704726d.v:21: error: signal and genvar in 'top' have the same name 'name0_v'. ./ivltests/pr1704726d.v:27: error: signal and task in 'top' have the same name 'name1_st'. ./ivltests/pr1704726d.v:34: error: signal and function in 'top' have the same name 'name2_sf'. ./ivltests/pr1704726d.v:38: error: signal and module instance in 'top' have the same name 'name3_si'. ./ivltests/pr1704726d.v:44: error: signal and sequential block in 'top' have the same name 'name4_sb'. ./ivltests/pr1704726d.v:48: error: signal and named event in 'top' have the same name 'name5_se'. ./ivltests/pr1704726d.v:57: error: signal and generate block in 'top' have the same name 'name6_sgl'. ./ivltests/pr1704726d.v:65: error: signal and generate block in 'top' have the same name 'name7_sgi'. ./ivltests/pr1704726d.v:78: error: signal and generate block in 'top' have the same name 'name8_sgc'. ./ivltests/pr1704726d.v:86: error: signal and generate block in 'top' have the same name 'name9_sgb'. 11 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr1704726d.gold000066400000000000000000000035151435245347300200250ustar00rootroot00000000000000./ivltests/pr1704726d.v:12: error: 'name0_s' has already been declared in this scope. ./ivltests/pr1704726d.v:4: : It was declared here as a parameter. ./ivltests/pr1704726d.v:21: error: 'name0_v' has already been declared in this scope. ./ivltests/pr1704726d.v:15: : It was declared here as a genvar. ./ivltests/pr1704726d.v:27: error: 'name1_st' has already been declared in this scope. ./ivltests/pr1704726d.v:24: : It was declared here as a task. ./ivltests/pr1704726d.v:34: error: 'name2_sf' has already been declared in this scope. ./ivltests/pr1704726d.v:30: : It was declared here as a function. ./ivltests/pr1704726d.v:38: error: 'name3_si' has already been declared in this scope. ./ivltests/pr1704726d.v:37: : It was declared here as an instance name. ./ivltests/pr1704726d.v:44: error: 'name4_sb' has already been declared in this scope. ./ivltests/pr1704726d.v:41: : It was declared here as a named block. ./ivltests/pr1704726d.v:48: error: 'name5_se' has already been declared in this scope. ./ivltests/pr1704726d.v:47: : It was declared here as an event. ./ivltests/pr1704726d.v:57: error: 'name6_sgl' has already been declared in this scope. ./ivltests/pr1704726d.v:53: : It was declared here as a generate block. ./ivltests/pr1704726d.v:65: error: 'name7_sgi' has already been declared in this scope. ./ivltests/pr1704726d.v:61: : It was declared here as a generate block. ./ivltests/pr1704726d.v:78: error: 'name8_sgc' has already been declared in this scope. ./ivltests/pr1704726d.v:70: : It was declared here as a generate block. ./ivltests/pr1704726d.v:82: warning: Anachronistic use of named begin/end to surround generate schemes. ./ivltests/pr1704726d.v:86: error: 'name9_sgb' has already been declared in this scope. ./ivltests/pr1704726d.v:82: : It was declared here as a generate block. iverilog-12_0/ivtest/gold/pr1719055.gold000066400000000000000000000012371435245347300176610ustar00rootroot00000000000000 *** module array_assign ************************************** 10 ar_reg=1 w_assign=1 10 ar_reg[0]=3'b001 ar_reg[1]=3'b001 10 as_wr=5'b00001 10 ar_reg=1 w_assign=1 10 ar_reg[0]=3'b001 ar_reg[1]=3'b001 10 as_wr=5'b00001 20 ar_reg=0 w_assign=0 20 ar_reg[0]=3'b000 ar_reg[1]=3'b000 20 as_wr=5'b00000 20 ar_reg=0 w_assign=0 20 ar_reg[0]=3'b000 ar_reg[1]=3'b000 20 as_wr=5'b00000 iverilog-12_0/ivtest/gold/pr1723367.gold000066400000000000000000000052101435245347300176550ustar00rootroot00000000000000./ivltests/pr1723367.v:132: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:140: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:141: warning: Scalar port ``b'' has a vectored net declaration [15:0]. ./ivltests/pr1723367.v:149: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:157: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:168: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:176: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:177: warning: Scalar port ``b'' has a vectored net declaration [15:0]. ./ivltests/pr1723367.v:185: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:193: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:204: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:214: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:215: warning: Scalar port ``b'' has a vectored net declaration [31:0]. ./ivltests/pr1723367.v:247: warning: Scalar port ``a'' has a vectored net declaration [15:0]. ./ivltests/pr1723367.v:255: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:256: warning: Scalar port ``b'' has a vectored net declaration [31:0]. ./ivltests/pr1723367.v:283: warning: Scalar port ``a'' has a vectored net declaration [15:0]. ./ivltests/pr1723367.v:291: warning: Scalar port ``a'' has a vectored net declaration [7:0]. ./ivltests/pr1723367.v:292: warning: Scalar port ``b'' has a vectored net declaration [15:0]. ./ivltests/pr1723367.v:308: warning: Scalar port ``a'' has a vectored net declaration [15:0]. sum[ 1] = 0101010101100000 sum[ 2] = 0101010101100000 sum[ 3] = 0101010101100000 sum[ 4] = 0101010101100000 sum[ 5] = 0101010101100000 sum[ 6] = 0101010101100000 sum[ 7] = 0101010101100000 sum[ 8] = 0101010101100000 sum[ 9] = 0101010101100000 sum[ 10] = 0101010101100000 sum[ 11] = 0101010101100000 sum[ 12] = 0101010101100000 sum[ 13] = 0101010101100000 sum[ 14] = 0101010101100000 sum[ 15] = 0101010101100000 sum[ 16] = 0101010101100000 sum[ 17] = 0101010101100000 sum[ 18] = 0101010101100000 sum[ 19] = 0101010101100000 sum[ 20] = 0101010101100000 sum[ 21] = 0101010101100000 sum[ 22] = 0101010101100000 sum[ 23] = 0101010101100000 iverilog-12_0/ivtest/gold/pr1735836.gold000066400000000000000000000001541435245347300176630ustar00rootroot00000000000000 0 out=z 1 out=1 2 out=2 3 out=z iverilog-12_0/ivtest/gold/pr1741212.gold000066400000000000000000000016501435245347300176460ustar00rootroot00000000000000cos(MATH_PI_OVER_3): 0.500000 sin(MATH_PI_OVER_3): 0.866025 sign(-10): 1.000000 realmax(MATH_PI,MATH_E): 3.141593 realmin(MATH_PI,MATH_E): 2.718282 mod(MATH_PI,MATH_E): 0.423311 ceil(-MATH_PI): -3.000000 ceil(4.0): 4.000000 ceil(3.99999999999999): 4.000000 pow(MATH_PI,2): 9.869604 gaussian(1.0,1.0): 0.694156 round(MATH_PI): 3.000000 trunc(-MATH_PI): -3.000000 ceil(-MATH_PI): -3.000000 floor(MATH_PI): 3.000000 round(e): 3.000000 ceil(-e): -2.000000 exp(MATH_PI): 23.140693 log2(MATH_PI): 1.651496 log_base(pow(2,32),2): 32.000000 ln(0.1): -2.302585 cbrt(7): 1.912931 cos(6.2831853071): -1.000000 sin(-6.2831853071): 0.000000 sinh(2.7182818284): 7.544137 cosh(6.2831853071): 267.746761 arctan_xy(-4,3): 2.498092 arctan(MATH_PI): 1.262627 arctan(-MATH_E/2): -0.936472 arctan(MATH_PI_OVER_2): 1.003885 arctan(1/7) = 0.141897 arctan(3/79) = 0.037956 pi/4 ?= 0.785398 arcsin(1.0): 1.570796 cos(pi/2): 0.000000 arccos(cos(pi/2)): 1.570796 iverilog-12_0/ivtest/gold/pr1746848.gold000066400000000000000000000002141435245347300176650ustar00rootroot00000000000000i= 4 i= 3 i= 2 i= 1 i= 0 j= 4 j= 3 j= 2 j= 1 j= 0 iverilog-12_0/ivtest/gold/pr1752823a.gold000066400000000000000000000000361435245347300200160ustar00rootroot00000000000000+0=0.000000 and -0=-0.000000. iverilog-12_0/ivtest/gold/pr1752823b.gold000066400000000000000000000000621435245347300200160ustar00rootroot00000000000000+0=0.000000, -0=-0.000000, inf=inf and minf=-inf. iverilog-12_0/ivtest/gold/pr1758122.gold000066400000000000000000000000361435245347300176530ustar00rootroot00000000000000x + x = x 0 + 2 = 2 1 + 3 = 4 iverilog-12_0/ivtest/gold/pr1758135.gold000066400000000000000000000000101435245347300176470ustar00rootroot000000000000001 2 3 4 iverilog-12_0/ivtest/gold/pr1770199.gold000066400000000000000000000000261435245347300176620ustar00rootroot00000000000000The strength is: Pu1: iverilog-12_0/ivtest/gold/pr1771903.gold000066400000000000000000000001661435245347300176610ustar00rootroot00000000000000Real :1.23456: has a width of 1. Parameter real :1.23456: has a width of 1. Real constant :1.23456: has a width of 1. iverilog-12_0/ivtest/gold/pr1780480.gold000066400000000000000000000000371435245347300176560ustar00rootroot000000000000000 a(0) 20 a(1) 40 a(0) 60 a(1) iverilog-12_0/ivtest/gold/pr1787394a.gold000066400000000000000000000002521435245347300200310ustar00rootroot00000000000000These should all produce: x StL x StL ----------- c=x(StL), d=x(StL), b=0, nctl=0, pctl=x c=x(StL), d=x(StL), b=0, nctl=x, pctl=x c=x(StH), d=x(StH), b=1, nctl=x, pctl=x iverilog-12_0/ivtest/gold/pr1787423.gold000066400000000000000000000000521435245347300176570ustar00rootroot0000000000000000 11 00 11 0 11 00 00 11 1 00 11 00 11 0 iverilog-12_0/ivtest/gold/pr1792108.gold000066400000000000000000000002311435245347300176520ustar00rootroot00000000000000 0 y1 = x, y2 = x, y3 = x, a = x 1 y1 = 1, y2 = 1, y3 = 1, a = 1 2 y1 = 0, y2 = 0, y3 = 0, a = 0 iverilog-12_0/ivtest/gold/pr1792152.gold000066400000000000000000000001101435245347300176450ustar00rootroot00000000000000./ivltests/pr1792152.v:2: warning: Choosing typ expression. 2 iverilog-12_0/ivtest/gold/pr1792734.gold000066400000000000000000000005111435245347300176600ustar00rootroot00000000000000 7'dx: xxxxxxx, 7'dz: zzzzzzz, 7'd?: zzzzzzz 'dx: xxxxxxx, 'dz: zzzzzzz, 'd?: zzzzzzz 2'dx: 00000xx, 2'dz: 00000zz, 2'd?: 00000zz 7'sdx: xxxxxxx, 7'sdz: zzzzzzz, 7'sd?: zzzzzzz 'sdx: xxxxxxx, 'sdz: zzzzzzz, 'sd?: zzzzzzz 2'sdx: xxxxxxx, 2'sdz: zzzzzzz, 2'sd?: zzzzzzz 7'dx_: xxxxxxx, 7'dz_: zzzzzzz, 7'd?_: zzzzzzz iverilog-12_0/ivtest/gold/pr1793157.gold000066400000000000000000000000301435245347300176540ustar00rootroot00000000000000x1: abcde; x2: ffffffff iverilog-12_0/ivtest/gold/pr1793749.gold000066400000000000000000000000601435245347300176660ustar00rootroot00000000000000 9 32 9 9 iverilog-12_0/ivtest/gold/pr1793749b.gold000066400000000000000000000000701435245347300200310ustar00rootroot00000000000000i, j, k, l: '10100', '11110100', '11110100', '11110100' iverilog-12_0/ivtest/gold/pr1795005a.gold000066400000000000000000000000301435245347300200070ustar00rootroot00000000000000< : N <=: Y > : N >=: Y iverilog-12_0/ivtest/gold/pr1795005b.gold000066400000000000000000000000301435245347300200100ustar00rootroot00000000000000< : N <=: N > : Y >=: Y iverilog-12_0/ivtest/gold/pr1799904.gold000066400000000000000000000002221435245347300176650ustar00rootroot0000000000000000000000 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000000 00000001 00000002 00000003 00000004 00000005 00000006 00000007 iverilog-12_0/ivtest/gold/pr1804877.gold000066400000000000000000000000661435245347300176670ustar00rootroot00000000000000String is test_counter String is test_counter iverilog-12_0/ivtest/gold/pr1805837.gold000066400000000000000000000001151435245347300176570ustar00rootroot00000000000000Should be: x01 x10 x0z x1z xz1 xz0 x0z0 xxx x01 x10 x0z x1z xz1 xz0 x0z0 xxx iverilog-12_0/ivtest/gold/pr1819452-vlog95.gold000066400000000000000000000014401435245347300210020ustar00rootroot00000000000000Found: in_0 currently at byte 5 Found: in_1 currently at byte 10 Found: in_2 currently at byte 15 Found: in_3 currently at byte 20 Found: in_4 currently at byte 25 Found: in_5 currently at byte 30 Found: in_6 currently at byte 35 Found: in_7 currently at byte 40 Found: in_8 currently at byte 45 Found: in_9 currently at byte 50 Found: in_10 currently at byte 56 Found: in_0 currently at byte 5 Found: in_0 currently at byte 5 Found: 10 currently at byte 56 Found: in_10 currently at byte 56 WARNING: vlog95.v:40: invalid file descriptor (0xffffffff) given to $fseek. Check fseek EOF = -1 WARNING: vlog95.v:42: invalid file descriptor (0xffffffff) given to $ftell. Check ftell EOF = -1 WARNING: vlog95.v:44: invalid file descriptor (0xffffffff) given to $rewind. Check rewind EOF = -1 iverilog-12_0/ivtest/gold/pr1819452.gold000066400000000000000000000015121435245347300176570ustar00rootroot00000000000000Found: in_0 currently at byte 5 Found: in_1 currently at byte 10 Found: in_2 currently at byte 15 Found: in_3 currently at byte 20 Found: in_4 currently at byte 25 Found: in_5 currently at byte 30 Found: in_6 currently at byte 35 Found: in_7 currently at byte 40 Found: in_8 currently at byte 45 Found: in_9 currently at byte 50 Found: in_10 currently at byte 56 Found: in_0 currently at byte 5 Found: in_0 currently at byte 5 Found: 10 currently at byte 56 Found: in_10 currently at byte 56 WARNING: ./ivltests/pr1819452.v:34: invalid file descriptor (0xffffffff) given to $fseek. Check fseek EOF = -1 WARNING: ./ivltests/pr1819452.v:37: invalid file descriptor (0xffffffff) given to $ftell. Check ftell EOF = -1 WARNING: ./ivltests/pr1819452.v:40: invalid file descriptor (0xffffffff) given to $rewind. Check rewind EOF = -1 iverilog-12_0/ivtest/gold/pr1820472.gold000066400000000000000000000002001435245347300176420ustar00rootroot00000000000000out[0]: zz0110 out[1]: 000010 out[2]: xx01xx out[3]: xx10xx out[1]-0: xxxxxx out[1]-1: 000010 out[1]-2: xx01xx out[1]-3: xx10xx iverilog-12_0/ivtest/gold/pr1823732.gold000066400000000000000000000000761435245347300176570ustar00rootroot00000000000000i is '1'; j is '111'; k is '0' runtime ; j is '111'; k is '0' iverilog-12_0/ivtest/gold/pr1828642.gold000066400000000000000000000000601435245347300176550ustar00rootroot0000000000000001 02 03 04 11 12 13 14 21 22 23 24 31 32 33 34 iverilog-12_0/ivtest/gold/pr1830834.gold000066400000000000000000000004311435245347300176530ustar00rootroot00000000000000SORRY: ./ivltests/pr1830834.v:22: currently only simple signals or constant expressions may be passed to $strobe. NOTE: You can work around this by assigning the desired expression to an intermediate net (using a continuous assignment) and passing that net to $strobe. iverilog-12_0/ivtest/gold/pr1831724.gold000066400000000000000000000000631435245347300176530ustar00rootroot00000000000000tmp1: '0000000xxx000000'; tmp2: '0000000xxx000000' iverilog-12_0/ivtest/gold/pr1833024.gold000066400000000000000000000144001435245347300176460ustar00rootroot00000000000000./ivltests/pr1833024.v:43: error: can not select part of scalar: a ./ivltests/pr1833024.v:44: error: can not select part of scalar: a ./ivltests/pr1833024.v:45: error: can not select part of scalar: a ./ivltests/pr1833024.v:46: error: can not select part of scalar: a ./ivltests/pr1833024.v:10: error: can not select part of scalar: svar ./ivltests/pr1833024.v:10: error: Unable to elaborate r-value: svar['sd0] ./ivltests/pr1833024.v:11: error: can not select part of scalar: svar ./ivltests/pr1833024.v:11: error: Unable to elaborate r-value: svar['sd0:'sd0] ./ivltests/pr1833024.v:12: error: can not select part of scalar: svar ./ivltests/pr1833024.v:12: error: Unable to elaborate r-value: svar['sd0+:'sd1] ./ivltests/pr1833024.v:13: error: can not select part of scalar: svar ./ivltests/pr1833024.v:13: error: Unable to elaborate r-value: svar['sd0-:'sd1] ./ivltests/pr1833024.v:15: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:15: error: Unable to elaborate r-value: sarr['sd0]['sd0] ./ivltests/pr1833024.v:16: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:16: error: Unable to elaborate r-value: sarr['sd0]['sd0:'sd0] ./ivltests/pr1833024.v:17: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:17: error: Unable to elaborate r-value: sarr['sd0]['sd0+:'sd1] ./ivltests/pr1833024.v:18: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:18: error: Unable to elaborate r-value: sarr['sd0]['sd0-:'sd1] ./ivltests/pr1833024.v:20: error: can not select part of scalar: wsbslv ./ivltests/pr1833024.v:21: error: can not select part of scalar: wspslv ./ivltests/pr1833024.v:22: error: can not select part of scalar: wsuplv ./ivltests/pr1833024.v:23: error: can not select part of scalar: wsdolv ./ivltests/pr1833024.v:25: error: can not select part of scalar array word: wsarr[0] ./ivltests/pr1833024.v:26: error: can not select part of scalar array word: wsarr[0] ./ivltests/pr1833024.v:27: error: can not select part of scalar array word: wsarr[0] ./ivltests/pr1833024.v:28: error: can not select part of scalar array word: wsarr[0] ./ivltests/pr1833024.v:30: error: can not select part of scalar: wsbstr ./ivltests/pr1833024.v:31: error: can not select part of scalar: wspstr ./ivltests/pr1833024.v:32: error: can not select part of scalar: wsuptr ./ivltests/pr1833024.v:33: error: can not select part of scalar: wsdotr ./ivltests/pr1833024.v:35: error: can not select part of scalar: wsbstr ./ivltests/pr1833024.v:35: error: Failed to elaborate port expression. ./ivltests/pr1833024.v:35: error: can not select part of scalar: wspstr ./ivltests/pr1833024.v:35: error: Failed to elaborate port expression. ./ivltests/pr1833024.v:35: error: can not select part of scalar: wsuptr ./ivltests/pr1833024.v:35: error: Failed to elaborate port expression. ./ivltests/pr1833024.v:35: error: can not select part of scalar: wsdotr ./ivltests/pr1833024.v:35: error: Failed to elaborate port expression. ./ivltests/pr1833024.v:36: error: can not select part of scalar: wsbstr ./ivltests/pr1833024.v:36: error: Output port expression must support continuous assignment. ./ivltests/pr1833024.v:36: : Port 1 (arg1) of submod2 is connected to wsbstr['sd0] ./ivltests/pr1833024.v:36: error: can not select part of scalar: wspstr ./ivltests/pr1833024.v:36: error: Output port expression must support continuous assignment. ./ivltests/pr1833024.v:36: : Port 2 (arg2) of submod2 is connected to wspstr['sd0:'sd0] ./ivltests/pr1833024.v:36: error: can not select part of scalar: wsuptr ./ivltests/pr1833024.v:36: error: Output port expression must support continuous assignment. ./ivltests/pr1833024.v:36: : Port 3 (arg3) of submod2 is connected to wsuptr['sd0+:'sd1] ./ivltests/pr1833024.v:36: error: can not select part of scalar: wsdotr ./ivltests/pr1833024.v:36: error: Output port expression must support continuous assignment. ./ivltests/pr1833024.v:36: : Port 4 (arg4) of submod2 is connected to wsdotr['sd0-:'sd1] ./ivltests/pr1833024.v:37: error: can not select part of scalar: wsbstr ./ivltests/pr1833024.v:37: error: Inout port expression must support continuous assignment. ./ivltests/pr1833024.v:37: : Port 1 (arg1) of submod3 is connected to wsbstr['sd0] ./ivltests/pr1833024.v:37: error: can not select part of scalar: wspstr ./ivltests/pr1833024.v:37: error: Inout port expression must support continuous assignment. ./ivltests/pr1833024.v:37: : Port 2 (arg2) of submod3 is connected to wspstr['sd0:'sd0] ./ivltests/pr1833024.v:37: error: can not select part of scalar: wsuptr ./ivltests/pr1833024.v:37: error: Inout port expression must support continuous assignment. ./ivltests/pr1833024.v:37: : Port 3 (arg3) of submod3 is connected to wsuptr['sd0+:'sd1] ./ivltests/pr1833024.v:37: error: can not select part of scalar: wsdotr ./ivltests/pr1833024.v:37: error: Inout port expression must support continuous assignment. ./ivltests/pr1833024.v:37: : Port 4 (arg4) of submod3 is connected to wsdotr['sd0-:'sd1] ./ivltests/pr1833024.v:51: error: can not select part of scalar: svar ./ivltests/pr1833024.v:52: error: can not select part of scalar: svar ./ivltests/pr1833024.v:53: error: can not select part of scalar: svar ./ivltests/pr1833024.v:54: error: can not select part of scalar: svar ./ivltests/pr1833024.v:56: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:57: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:58: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:59: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:61: error: can not select part of scalar: sout ./ivltests/pr1833024.v:62: error: can not select part of scalar: sout ./ivltests/pr1833024.v:63: error: can not select part of scalar: sout ./ivltests/pr1833024.v:64: error: can not select part of scalar: sout ./ivltests/pr1833024.v:66: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:67: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:68: error: can not select part of scalar array word: sarr[32'sd0] ./ivltests/pr1833024.v:69: error: can not select part of scalar array word: sarr[32'sd0] 72 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr1841300.gold000066400000000000000000000002101435245347300176340ustar00rootroot00000000000000./ivltests/pr1841300.v:15: warning: Scalar port ``l'' has a vectored net declaration [4:0]. a is '14'; b is 'fffffff4'; c is 'fffffff4' iverilog-12_0/ivtest/gold/pr1845683.gold000066400000000000000000000000651435245347300176660ustar00rootroot00000000000000res1: '00101010'; res2: '00101010'; res3: '00101010' iverilog-12_0/ivtest/gold/pr1851310.gold000066400000000000000000000000521435245347300176420ustar00rootroot00000000000000Flag1 = 1, FlagI = 1 Flag1 = 0, FlagI = 0 iverilog-12_0/ivtest/gold/pr1855504.gold000066400000000000000000000000421435245347300176520ustar00rootroot00000000000000op1 = 0da0, op2 = 0a, prod = 0640 iverilog-12_0/ivtest/gold/pr1861212.gold000066400000000000000000000001331435245347300176440ustar00rootroot00000000000000Real value is 3.300000 at 0 Real value is 4.577600 at 1000 Real value is -4.000000 at 2000 iverilog-12_0/ivtest/gold/pr1862744b.gold000066400000000000000000000115411435245347300200260ustar00rootroot00000000000000./ivltests/pr1862744b.v:56: warning: condition expression of for-loop is constant. ./ivltests/pr1862744b.v:59: warning: condition expression of for-loop is constant. ./ivltests/pr1862744b.v:119: error: always process does not have any delay. ./ivltests/pr1862744b.v:119: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:104: warning: always process may not have any delay. ./ivltests/pr1862744b.v:104: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:103: error: always process does not have any delay. ./ivltests/pr1862744b.v:103: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:102: error: always process does not have any delay. ./ivltests/pr1862744b.v:102: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:95: warning: always process may not have any delay. ./ivltests/pr1862744b.v:95: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:89: warning: always process may not have any delay. ./ivltests/pr1862744b.v:89: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:86: warning: always process may not have any delay. ./ivltests/pr1862744b.v:86: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:83: error: always process does not have any delay. ./ivltests/pr1862744b.v:83: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:80: warning: always process may not have any delay. ./ivltests/pr1862744b.v:80: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:77: error: always process does not have any delay. ./ivltests/pr1862744b.v:77: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:74: error: always process does not have any delay. ./ivltests/pr1862744b.v:74: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:71: warning: always process may not have any delay. ./ivltests/pr1862744b.v:71: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:68: error: always process does not have any delay. ./ivltests/pr1862744b.v:68: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:65: error: always process does not have any delay. ./ivltests/pr1862744b.v:65: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:62: error: always process does not have any delay. ./ivltests/pr1862744b.v:62: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:59: error: always process does not have any delay. ./ivltests/pr1862744b.v:59: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:56: error: always process does not have any delay. ./ivltests/pr1862744b.v:56: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:53: warning: always process may not have any delay. ./ivltests/pr1862744b.v:53: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:50: error: always process does not have any delay. ./ivltests/pr1862744b.v:50: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:47: error: always process does not have any delay. ./ivltests/pr1862744b.v:47: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:44: warning: always process may not have any delay. ./ivltests/pr1862744b.v:44: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:41: error: always process does not have any delay. ./ivltests/pr1862744b.v:41: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:38: error: always process does not have any delay. ./ivltests/pr1862744b.v:38: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:35: warning: always process may not have any delay. ./ivltests/pr1862744b.v:35: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:32: warning: always process may not have any delay. ./ivltests/pr1862744b.v:32: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:29: warning: always process may not have any delay. ./ivltests/pr1862744b.v:29: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:26: error: always process does not have any delay. ./ivltests/pr1862744b.v:26: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:23: error: always process does not have any delay. ./ivltests/pr1862744b.v:23: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:20: error: always process does not have any delay. ./ivltests/pr1862744b.v:20: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:17: warning: always process may not have any delay. ./ivltests/pr1862744b.v:17: : A runtime infinite loop may be possible. ./ivltests/pr1862744b.v:14: error: always process does not have any delay. ./ivltests/pr1862744b.v:14: : A runtime infinite loop will occur. ./ivltests/pr1862744b.v:11: error: always process does not have any delay. ./ivltests/pr1862744b.v:11: : A runtime infinite loop will occur. Elaboration failed iverilog-12_0/ivtest/gold/pr1864110a-ivl.gold000066400000000000000000000000211435245347300205710ustar00rootroot000000000000003.00000 -3.00000 iverilog-12_0/ivtest/gold/pr1864110a.gold000066400000000000000000000000051435245347300200030ustar00rootroot000000000000003 -3 iverilog-12_0/ivtest/gold/pr1864110b-ivl.gold000066400000000000000000000000631435245347300206000ustar00rootroot00000000000000-3.00000 3.00000 -4.00000 4.00000 -6.00000 6.00000 iverilog-12_0/ivtest/gold/pr1864110b.gold000066400000000000000000000000171435245347300200070ustar00rootroot00000000000000-3 3 -4 4 -6 6 iverilog-12_0/ivtest/gold/pr1864110c.gold000066400000000000000000000000461435245347300200120ustar00rootroot000000000000000 0000000000000000 2 3fffffffffffffff iverilog-12_0/ivtest/gold/pr1864115-ivl.gold000066400000000000000000000001121435245347300204360ustar00rootroot000000000000000.00000 0 0.00000 2.00000 4611686018427387904 2.00000 iverilog-12_0/ivtest/gold/pr1864115.gold000066400000000000000000000000621435245347300176520ustar00rootroot000000000000000 0 0 2 4611686018427387904 2 iverilog-12_0/ivtest/gold/pr1866215.gold000066400000000000000000000012351435245347300176600ustar00rootroot00000000000000./ivltests/pr1866215.v:31: warning: Port 1 (CH) of C expects 7 bits, got 6. ./ivltests/pr1866215.v:31: : Padding 1 high bits of the port. ./ivltests/pr1866215.v:31: warning: Port 3 (SH) of C expects 8 bits, got 7. ./ivltests/pr1866215.v:31: : Padding 1 high bits of the port. ./ivltests/pr1866215.v:15: warning: Port 1 (CH) of B expects 6 bits, got 7. ./ivltests/pr1866215.v:15: : Padding 1 high bits of the expression. ./ivltests/pr1866215.v:15: warning: Port 3 (SH) of B expects 7 bits, got 8. ./ivltests/pr1866215.v:15: : Padding 1 high bits of the expression. C1H=33, {C1L, CL}={1555555, zzzzzzZ5}, S1H=66, {S1L, SL}={2aaaaaa, zzzzzzZa} iverilog-12_0/ivtest/gold/pr1866215b.gold000066400000000000000000000012021435245347300200140ustar00rootroot00000000000000./ivltests/pr1866215b.v:26: warning: Port 1 (CH) of C expects 7 bits, got 6. ./ivltests/pr1866215b.v:26: : Padding 1 high bits of the port. ./ivltests/pr1866215b.v:26: warning: Port 3 (SH) of C expects 8 bits, got 7. ./ivltests/pr1866215b.v:26: : Padding 1 high bits of the port. ./ivltests/pr1866215b.v:10: warning: Port 1 (CH) of B expects 6 bits, got 16. ./ivltests/pr1866215b.v:10: : Pruning 10 high bits of the expression. ./ivltests/pr1866215b.v:10: warning: Port 3 (SH) of B expects 7 bits, got 16. ./ivltests/pr1866215b.v:10: : Pruning 9 high bits of the expression. CH=3f, CL=55555555, SH=7f, SL=aaaaaaaa iverilog-12_0/ivtest/gold/pr1867161a.gold000066400000000000000000000001241435245347300200160ustar00rootroot00000000000000Value[0]: 2 Value[1]: 3 Value[2]: 4 Value[3]: 5 Value[4]: 6 Value[5]: 7 Value[6]: 8 iverilog-12_0/ivtest/gold/pr1867161b.gold000066400000000000000000000002041435245347300200160ustar00rootroot00000000000000 0 8 1 8 1 9 2 9 2 10 3 10 iverilog-12_0/ivtest/gold/pr1873372.gold000066400000000000000000000000631435245347300176600ustar00rootroot00000000000000big: 1e+20, small: 1e-20, precision: 0.12345678900 iverilog-12_0/ivtest/gold/pr1876798.gold000066400000000000000000000000101435245347300176670ustar00rootroot000000000000000 1 2 3 iverilog-12_0/ivtest/gold/pr1885847.gold000066400000000000000000000000101435245347300176620ustar00rootroot00000000000000P3 = 32 iverilog-12_0/ivtest/gold/pr1887168.gold000066400000000000000000000004541435245347300176740ustar00rootroot00000000000000 3 3 4 3 3 4 -3 -3 -4 -3 -3 -4 3 3 4 3 3 4 3 3 4 -3 -3 -4 -3 -3 -4 3 3 4 1 2 0 1 2 0 -1 -2 0 1 2 0 -1 -2 0 1 2 0 1 2 0 -1 -2 0 1 2 0 -1 -2 0 iverilog-12_0/ivtest/gold/pr1898983.gold000066400000000000000000000000441435245347300176760ustar00rootroot00000000000000In top.sm[0] at 1 In top.sm[1] at 2 iverilog-12_0/ivtest/gold/pr1903343.gold000066400000000000000000000000241435245347300176450ustar00rootroot00000000000000OK: 256 Main: 4 iverilog-12_0/ivtest/gold/pr1912112.gold000066400000000000000000000000551435245347300176430ustar00rootroot00000000000000The `test definition is: `define Hello World iverilog-12_0/ivtest/gold/pr1936363.gold000066400000000000000000000000361435245347300176600ustar00rootroot00000000000000 x x 42 21 x x iverilog-12_0/ivtest/gold/pr1949025.gold000066400000000000000000000001151435245347300176550ustar00rootroot000000000000000 00000040 1 00000020 2 00000010 3 00000008 4 00000004 5 00000002 6 00000001 iverilog-12_0/ivtest/gold/pr1960545.gold000066400000000000000000000000071435245347300176550ustar00rootroot00000000000000B is 1 iverilog-12_0/ivtest/gold/pr1960548.gold000066400000000000000000000000041435245347300176550ustar00rootroot00000000000000B`x iverilog-12_0/ivtest/gold/pr1960558.gold000066400000000000000000000000221435245347300176560ustar00rootroot00000000000000expected 1; got 1 iverilog-12_0/ivtest/gold/pr1960575.gold000066400000000000000000000000221435245347300176550ustar00rootroot00000000000000expected x; got x iverilog-12_0/ivtest/gold/pr1960596.gold000066400000000000000000000000721435245347300176650ustar00rootroot00000000000000expected 32'h55555552; got 32'h55555552 expected 1; got 1 iverilog-12_0/ivtest/gold/pr1960619.gold000066400000000000000000000012651435245347300176660ustar00rootroot00000000000000./ivltests/pr1960619.v:26: warning: Scalar port ``l'' has a vectored net declaration [7:0]. ./ivltests/pr1960619.v:26: warning: Scalar port ``r'' has a vectored net declaration [7:0]. ./ivltests/pr1960619.v:14: warning: Scalar port ``l'' has a vectored net declaration [4:0]. ./ivltests/pr1960619.v:32: warning: Scalar port ``l'' has a vectored net declaration [31:0]. ./ivltests/pr1960619.v:47: warning: Scalar port ``l'' has a vectored net declaration [31:0]. ./ivltests/pr1960619.v:20: warning: Scalar port ``l'' has a vectored net declaration [7:0]. ./ivltests/pr1960619.v:20: warning: Scalar port ``r'' has a vectored net declaration [7:0]. a is 14; b is fffffff4; c is 14; d is fffffff4 iverilog-12_0/ivtest/gold/pr1963240.gold000066400000000000000000000000641435245347300176530ustar00rootroot00000000000000expected 52; got 52 expected fffffff7; got fffffff7 iverilog-12_0/ivtest/gold/pr1963962-fsv.gold000066400000000000000000000001721435245347300204620ustar00rootroot00000000000000VCD info: dumpfile work/dumptest.vcd opened for output. VCD warning: $dumpvars: Package ($unit) is not dumpable with VCD. iverilog-12_0/ivtest/gold/pr1963962.gold000066400000000000000000000000701435245347300176630ustar00rootroot00000000000000VCD info: dumpfile work/dumptest.vcd opened for output. iverilog-12_0/ivtest/gold/pr1985582.gold000066400000000000000000000006701435245347300176730ustar00rootroot00000000000000 0 0.00 0, 0 0.00 0, 0 0.00, 0 0.00, 0 0.00, 0 0.000 1000 1.00 1, 1000 1.00 1, 600 0.60, 600 0.60, 600 0.60, 1 0.600 1000 1.00 1, 1000 1.00 1, 1200 1.20, 1200 1.20, 1200 1.20, 1 1.200 2000 2.00 2, 2000 2.00 2, 1800 1.80, 1800 1.80, 1800 1.80, 2 1.800 2000 2.00 2, 2000 2.00 2, 2400 2.40, 2400 2.40, 2400 2.40, 2 2.400 iverilog-12_0/ivtest/gold/pr1985582_std.gold000066400000000000000000000014741435245347300205500ustar00rootroot00000000000000 0 0.00 0, 0 0.00 0, 0 0.00, 0 0.00, 0 0.00, 0 0 1000 1.00 1, 1000 1.00 1, 600 0.60, 600 0.60, 600 0.60, 1 0.6 1000 1.00 1, 1000 1.00 1, 1200 1.20, 1200 1.20, 1200 1.20, 1 1.2 2000 2.00 2, 2000 2.00 2, 1800 1.80, 1800 1.80, 1800 1.80, 2 1.8 2000 2.00 2, 2000 2.00 2, 2400 2.40, 2400 2.40, 2400 2.40, 2 2.4 iverilog-12_0/ivtest/gold/pr1993479.gold000066400000000000000000000005411435245347300176740ustar00rootroot00000000000000 0 10100101 10100101 -1 0100101x 0100101x -2 100101xx 100101xx -3 00101xxx 00101xxx -4 0101xxxx 0101xxxx -5 101xxxxx 101xxxxx -6 01xxxxxx 01xxxxxx -7 1xxxxxxx 1xxxxxxx 1 x1010010 x1010010 0 10100101 10100101 -1 0100101x 0100101x -2 100101xx 100101xx -3 00101xxx 00101xxx -4 0101xxxx 0101xxxx -5 101xxxxx 101xxxxx -6 01xxxxxx 01xxxxxx iverilog-12_0/ivtest/gold/pr2001162.gold000066400000000000000000000010041435245347300176310ustar00rootroot00000000000000./ivltests/pr2001162.v:36: warning: Scalar port ``l'' has a vectored net declaration [31:0]. ./ivltests/pr2001162.v:36: warning: Scalar port ``r'' has a vectored net declaration [31:0]. test2 increment; reading counter as 0 test1 increment; reading counter as 1 test2 increment; reading counter as 2 test1 increment; reading counter as 3 test2 increment; reading counter as 4 test1 increment; reading counter as 5 test2 increment; reading counter as 6 test1 increment; reading counter as 7 time 52; the counter is 8 iverilog-12_0/ivtest/gold/pr2001162_std.gold000066400000000000000000000005121435245347300205060ustar00rootroot00000000000000test1 increment; reading counter as 0 test2 increment; reading counter as 1 test1 increment; reading counter as 2 test2 increment; reading counter as 3 test1 increment; reading counter as 4 test2 increment; reading counter as 5 test1 increment; reading counter as 6 test2 increment; reading counter as 7 time 52; the counter is 8 iverilog-12_0/ivtest/gold/pr2029336.gold000066400000000000000000000001371435245347300176540ustar00rootroot00000000000000# x = 1073741824 # x = 2147483648 # x = 4294967296 0 1073741824 2147483648 4294967296 iverilog-12_0/ivtest/gold/pr2039694.gold000066400000000000000000000005261435245347300176660ustar00rootroot00000000000000testcase_defparam.test_defparam_a.U_test foo = 2 testcase_defparam.test_defparam_b.U_test foo = 2 testcase_defparam.test_defparam_c.U_test foo = 2 testcase_inline.test_inline_a.U_test foo = 2 testcase_inline.test_inline_b.U_test foo = 2 testcase_inline.test_inline_c.U_test foo = 2 iverilog-12_0/ivtest/gold/pr2043585.gold000066400000000000000000000005601435245347300176560ustar00rootroot00000000000000./ivltests/pr2043585.v:27: warning: @* is sensitive to all 4 words in array 'Data'. ./ivltests/pr2043585.v:28: warning: @* is sensitive to all 4 words in array 'Data'. ./ivltests/pr2043585.v:29: warning: @* is sensitive to all 4 words in array 'Data'. ./ivltests/pr2043585.v:30: warning: @* is sensitive to all 4 words in array 'Data'. 0 1 2 3 1 2 3 0 2 3 0 1 3 0 1 2 iverilog-12_0/ivtest/gold/pr2043585_std.gold000066400000000000000000000000361435245347300205260ustar00rootroot000000000000001 2 3 1 2 3 0 2 3 0 1 3 0 1 2 iverilog-12_0/ivtest/gold/pr2053944.gold000066400000000000000000000000061435245347300176510ustar00rootroot00000000000000 1 2 iverilog-12_0/ivtest/gold/pr2076391.gold000066400000000000000000000000551435245347300176560ustar00rootroot00000000000000iindex[0] = -1 rindex[0] = -1 windex[0] = -1 iverilog-12_0/ivtest/gold/pr2091455.gold000066400000000000000000000000741435245347300176550ustar00rootroot00000000000000I am in main.X, case foo=2 I am in main.genblk1, case foo=2 iverilog-12_0/ivtest/gold/pr2119622.gold000066400000000000000000000001131435245347300176440ustar00rootroot000000000000001 << 32 = 0000000000000000000000000000000100000000000000000000000000000000 iverilog-12_0/ivtest/gold/pr2132552.gold000066400000000000000000000000461435245347300176460ustar00rootroot000000000000000 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 iverilog-12_0/ivtest/gold/pr2136787.gold000066400000000000000000000000541435245347300176630ustar00rootroot00000000000000a = 1010 b = 0000 y = 11111010 z = 11111010 iverilog-12_0/ivtest/gold/pr2138682.gold000066400000000000000000000002201435245347300176520ustar00rootroot00000000000000Block 0 value = 7 Block 1 value = 6 Block 2 value = 5 Block 3 value = 4 Block 4 value = 3 Block 5 value = 2 Block 6 value = 1 Block 7 value = 0 iverilog-12_0/ivtest/gold/pr2138979b.gold000066400000000000000000000003261435245347300200340ustar00rootroot00000000000000a = 10110110 b = 10010010 yuu = 0000000010110110 zuu = 0000000010110110 yus = 0000000010110110 zus = 0000000010110110 ysu = 0000000010110110 zsu = 0000000010110110 yss = 1111111110110110 zss = 1111111110110110 iverilog-12_0/ivtest/gold/pr2138979c.gold000066400000000000000000000000671435245347300200370ustar00rootroot00000000000000a = 10110110 y = 1111111110110110 z = 1111111110110110 iverilog-12_0/ivtest/gold/pr2138979d.gold000066400000000000000000004634741435245347300200570ustar00rootroot00000000000000sel = 0 a = 10000001 b = 00001001 c = 100011 y_mux_uu = 0000000000001001 y_mux_us = 0000000000001001 y_mux_su = 0000000000001001 y_mux_ss = 0000000000001001 z_mux_uu = 0000000000001001 z_mux_us = 0000000000001001 z_mux_su = 0000000000001001 z_mux_ss = 0000000000001001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011100 y_sgn_s = 0000000000011100 z_sgn_u = 1111111111011100 z_sgn_s = 0000000000011100 y_add_uu = 0000000010100100 y_add_us = 0000000010100100 y_add_su = 0000000010100100 y_add_ss = 1111111101100100 z_add_uu = 0000000010100100 z_add_us = 0000000010100100 z_add_su = 0000000010100100 z_add_ss = 1111111101100100 y_sub_uu = 0000000001011110 y_sub_us = 0000000001011110 y_sub_su = 0000000001011110 y_sub_ss = 1111111110011110 z_sub_uu = 0000000001011110 z_sub_us = 0000000001011110 z_sub_su = 0000000001011110 z_sub_ss = 1111111110011110 y_mul_uu = 0001000110100011 y_mul_us = 0001000110100011 y_mul_su = 0001000110100011 y_mul_ss = 0000111001100011 z_mul_uu = 0001000110100011 z_mul_us = 0001000110100011 z_mul_su = 0001000110100011 z_mul_ss = 0000111001100011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10001101 b = 01100101 c = 010010 y_mux_uu = 0000000010001101 y_mux_us = 0000000010001101 y_mux_su = 0000000010001101 y_mux_ss = 1111111110001101 z_mux_uu = 0000000010001101 z_mux_us = 0000000010001101 z_mux_su = 0000000010001101 z_mux_ss = 1111111110001101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101101 y_sgn_s = 1111111111101101 z_sgn_u = 1111111111101101 z_sgn_s = 1111111111101101 y_add_uu = 0000000010011111 y_add_us = 0000000010011111 y_add_su = 0000000010011111 y_add_ss = 1111111110011111 z_add_uu = 0000000010011111 z_add_us = 0000000010011111 z_add_su = 0000000010011111 z_add_ss = 1111111110011111 y_sub_uu = 0000000001111011 y_sub_us = 0000000001111011 y_sub_su = 0000000001111011 y_sub_ss = 1111111101111011 z_sub_uu = 0000000001111011 z_sub_us = 0000000001111011 z_sub_su = 0000000001111011 z_sub_ss = 1111111101111011 y_mul_uu = 0000100111101010 y_mul_us = 0000100111101010 y_mul_su = 0000100111101010 y_mul_ss = 1111011111101010 z_mul_uu = 0000100111101010 z_mul_us = 0000100111101010 z_mul_su = 0000100111101010 z_mul_ss = 1111011111101010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00001101 b = 01110110 c = 111101 y_mux_uu = 0000000000001101 y_mux_us = 0000000000001101 y_mux_su = 0000000000001101 y_mux_ss = 0000000000001101 z_mux_uu = 0000000000001101 z_mux_us = 0000000000001101 z_mux_su = 0000000000001101 z_mux_ss = 0000000000001101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000010 y_sgn_s = 0000000000000010 z_sgn_u = 1111111111000010 z_sgn_s = 0000000000000010 y_add_uu = 0000000001001010 y_add_us = 0000000001001010 y_add_su = 0000000001001010 y_add_ss = 0000000000001010 z_add_uu = 0000000001001010 z_add_us = 0000000001001010 z_add_su = 0000000001001010 z_add_ss = 0000000000001010 y_sub_uu = 1111111111010000 y_sub_us = 1111111111010000 y_sub_su = 1111111111010000 y_sub_ss = 0000000000010000 z_sub_uu = 1111111111010000 z_sub_us = 1111111111010000 z_sub_su = 1111111111010000 z_sub_ss = 0000000000010000 y_mul_uu = 0000001100011001 y_mul_us = 0000001100011001 y_mul_su = 0000001100011001 y_mul_ss = 1111111111011001 z_mul_uu = 0000001100011001 z_mul_us = 0000001100011001 z_mul_su = 0000001100011001 z_mul_ss = 1111111111011001 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 0 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 1 a = 10001100 b = 11111001 c = 000110 y_mux_uu = 0000000010001100 y_mux_us = 0000000010001100 y_mux_su = 0000000010001100 y_mux_ss = 1111111110001100 z_mux_uu = 0000000010001100 z_mux_us = 0000000010001100 z_mux_su = 0000000010001100 z_mux_ss = 1111111110001100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111001 y_sgn_s = 1111111111111001 z_sgn_u = 1111111111111001 z_sgn_s = 1111111111111001 y_add_uu = 0000000010010010 y_add_us = 0000000010010010 y_add_su = 0000000010010010 y_add_ss = 1111111110010010 z_add_uu = 0000000010010010 z_add_us = 0000000010010010 z_add_su = 0000000010010010 z_add_ss = 1111111110010010 y_sub_uu = 0000000010000110 y_sub_us = 0000000010000110 y_sub_su = 0000000010000110 y_sub_ss = 1111111110000110 z_sub_uu = 0000000010000110 z_sub_us = 0000000010000110 z_sub_su = 0000000010000110 z_sub_ss = 1111111110000110 y_mul_uu = 0000001101001000 y_mul_us = 0000001101001000 y_mul_su = 0000001101001000 y_mul_ss = 1111110101001000 z_mul_uu = 0000001101001000 z_mul_us = 0000001101001000 z_mul_su = 0000001101001000 z_mul_ss = 1111110101001000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10101010 b = 11100101 c = 110111 y_mux_uu = 0000000010101010 y_mux_us = 0000000010101010 y_mux_su = 0000000010101010 y_mux_ss = 1111111110101010 z_mux_uu = 0000000010101010 z_mux_us = 0000000010101010 z_mux_su = 0000000010101010 z_mux_ss = 1111111110101010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001000 y_sgn_s = 0000000000001000 z_sgn_u = 1111111111001000 z_sgn_s = 0000000000001000 y_add_uu = 0000000011100001 y_add_us = 0000000011100001 y_add_su = 0000000011100001 y_add_ss = 1111111110100001 z_add_uu = 0000000011100001 z_add_us = 0000000011100001 z_add_su = 0000000011100001 z_add_ss = 1111111110100001 y_sub_uu = 0000000001110011 y_sub_us = 0000000001110011 y_sub_su = 0000000001110011 y_sub_ss = 1111111110110011 z_sub_uu = 0000000001110011 z_sub_us = 0000000001110011 z_sub_su = 0000000001110011 z_sub_ss = 1111111110110011 y_mul_uu = 0010010010000110 y_mul_us = 0010010010000110 y_mul_su = 0010010010000110 y_mul_ss = 0000001100000110 z_mul_uu = 0010010010000110 z_mul_us = 0010010010000110 z_mul_su = 0010010010000110 z_mul_ss = 0000001100000110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10001111 b = 11110010 c = 001110 y_mux_uu = 0000000011110010 y_mux_us = 0000000011110010 y_mux_su = 0000000011110010 y_mux_ss = 1111111111110010 z_mux_uu = 0000000011110010 z_mux_us = 0000000011110010 z_mux_su = 0000000011110010 z_mux_ss = 1111111111110010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110001 y_sgn_s = 1111111111110001 z_sgn_u = 1111111111110001 z_sgn_s = 1111111111110001 y_add_uu = 0000000010011101 y_add_us = 0000000010011101 y_add_su = 0000000010011101 y_add_ss = 1111111110011101 z_add_uu = 0000000010011101 z_add_us = 0000000010011101 z_add_su = 0000000010011101 z_add_ss = 1111111110011101 y_sub_uu = 0000000010000001 y_sub_us = 0000000010000001 y_sub_su = 0000000010000001 y_sub_ss = 1111111110000001 z_sub_uu = 0000000010000001 z_sub_us = 0000000010000001 z_sub_su = 0000000010000001 z_sub_ss = 1111111110000001 y_mul_uu = 0000011111010010 y_mul_us = 0000011111010010 y_mul_su = 0000011111010010 y_mul_ss = 1111100111010010 z_mul_uu = 0000011111010010 z_mul_us = 0000011111010010 z_mul_su = 0000011111010010 z_mul_ss = 1111100111010010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 11000101 b = 01011100 c = 111101 y_mux_uu = 0000000001011100 y_mux_us = 0000000001011100 y_mux_su = 0000000001011100 y_mux_ss = 0000000001011100 z_mux_uu = 0000000001011100 z_mux_us = 0000000001011100 z_mux_su = 0000000001011100 z_mux_ss = 0000000001011100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000010 y_sgn_s = 0000000000000010 z_sgn_u = 1111111111000010 z_sgn_s = 0000000000000010 y_add_uu = 0000000100000010 y_add_us = 0000000100000010 y_add_su = 0000000100000010 y_add_ss = 1111111111000010 z_add_uu = 0000000100000010 z_add_us = 0000000100000010 z_add_su = 0000000100000010 z_add_ss = 1111111111000010 y_sub_uu = 0000000010001000 y_sub_us = 0000000010001000 y_sub_su = 0000000010001000 y_sub_ss = 1111111111001000 z_sub_uu = 0000000010001000 z_sub_us = 0000000010001000 z_sub_su = 0000000010001000 z_sub_ss = 1111111111001000 y_mul_uu = 0010111011110001 y_mul_us = 0010111011110001 y_mul_su = 0010111011110001 y_mul_ss = 0000000010110001 z_mul_uu = 0010111011110001 z_mul_us = 0010111011110001 z_mul_su = 0010111011110001 z_mul_ss = 0000000010110001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01100101 b = 01100011 c = 001010 y_mux_uu = 0000000001100101 y_mux_us = 0000000001100101 y_mux_su = 0000000001100101 y_mux_ss = 0000000001100101 z_mux_uu = 0000000001100101 z_mux_us = 0000000001100101 z_mux_su = 0000000001100101 z_mux_ss = 0000000001100101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110101 y_sgn_s = 1111111111110101 z_sgn_u = 1111111111110101 z_sgn_s = 1111111111110101 y_add_uu = 0000000001101111 y_add_us = 0000000001101111 y_add_su = 0000000001101111 y_add_ss = 0000000001101111 z_add_uu = 0000000001101111 z_add_us = 0000000001101111 z_add_su = 0000000001101111 z_add_ss = 0000000001101111 y_sub_uu = 0000000001011011 y_sub_us = 0000000001011011 y_sub_su = 0000000001011011 y_sub_ss = 0000000001011011 z_sub_uu = 0000000001011011 z_sub_us = 0000000001011011 z_sub_su = 0000000001011011 z_sub_ss = 0000000001011011 y_mul_uu = 0000001111110010 y_mul_us = 0000001111110010 y_mul_su = 0000001111110010 y_mul_ss = 0000001111110010 z_mul_uu = 0000001111110010 z_mul_us = 0000001111110010 z_mul_su = 0000001111110010 z_mul_ss = 0000001111110010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00100000 b = 10101010 c = 011101 y_mux_uu = 0000000010101010 y_mux_us = 0000000010101010 y_mux_su = 0000000010101010 y_mux_ss = 1111111110101010 z_mux_uu = 0000000010101010 z_mux_us = 0000000010101010 z_mux_su = 0000000010101010 z_mux_ss = 1111111110101010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100010 y_sgn_s = 1111111111100010 z_sgn_u = 1111111111100010 z_sgn_s = 1111111111100010 y_add_uu = 0000000000111101 y_add_us = 0000000000111101 y_add_su = 0000000000111101 y_add_ss = 0000000000111101 z_add_uu = 0000000000111101 z_add_us = 0000000000111101 z_add_su = 0000000000111101 z_add_ss = 0000000000111101 y_sub_uu = 0000000000000011 y_sub_us = 0000000000000011 y_sub_su = 0000000000000011 y_sub_ss = 0000000000000011 z_sub_uu = 0000000000000011 z_sub_us = 0000000000000011 z_sub_su = 0000000000000011 z_sub_ss = 0000000000000011 y_mul_uu = 0000001110100000 y_mul_us = 0000001110100000 y_mul_su = 0000001110100000 y_mul_ss = 0000001110100000 z_mul_uu = 0000001110100000 z_mul_us = 0000001110100000 z_mul_su = 0000001110100000 z_mul_ss = 0000001110100000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00010011 b = 00001101 c = 010011 y_mux_uu = 0000000000001101 y_mux_us = 0000000000001101 y_mux_su = 0000000000001101 y_mux_ss = 0000000000001101 z_mux_uu = 0000000000001101 z_mux_us = 0000000000001101 z_mux_su = 0000000000001101 z_mux_ss = 0000000000001101 y_eql_uu = 1 y_eql_us = 1 y_eql_su = 1 y_eql_ss = 1 z_eql_uu = 1 z_eql_us = 1 z_eql_su = 1 z_eql_ss = 1 y_neq_uu = 0 y_neq_us = 0 y_neq_su = 0 y_neq_ss = 0 z_neq_uu = 0 z_neq_us = 0 z_neq_su = 0 z_neq_ss = 0 y_sgn_u = 1111111111101100 y_sgn_s = 1111111111101100 z_sgn_u = 1111111111101100 z_sgn_s = 1111111111101100 y_add_uu = 0000000000100110 y_add_us = 0000000000100110 y_add_su = 0000000000100110 y_add_ss = 0000000000100110 z_add_uu = 0000000000100110 z_add_us = 0000000000100110 z_add_su = 0000000000100110 z_add_ss = 0000000000100110 y_sub_uu = 0000000000000000 y_sub_us = 0000000000000000 y_sub_su = 0000000000000000 y_sub_ss = 0000000000000000 z_sub_uu = 0000000000000000 z_sub_us = 0000000000000000 z_sub_su = 0000000000000000 z_sub_ss = 0000000000000000 y_mul_uu = 0000000101101001 y_mul_us = 0000000101101001 y_mul_su = 0000000101101001 y_mul_ss = 0000000101101001 z_mul_uu = 0000000101101001 z_mul_us = 0000000101101001 z_mul_su = 0000000101101001 z_mul_ss = 0000000101101001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 1 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 1 sel = 1 a = 11010101 b = 00000010 c = 101110 y_mux_uu = 0000000011010101 y_mux_us = 0000000011010101 y_mux_su = 0000000011010101 y_mux_ss = 1111111111010101 z_mux_uu = 0000000011010101 z_mux_us = 0000000011010101 z_mux_su = 0000000011010101 z_mux_ss = 1111111111010101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010001 y_sgn_s = 0000000000010001 z_sgn_u = 1111111111010001 z_sgn_s = 0000000000010001 y_add_uu = 0000000100000011 y_add_us = 0000000100000011 y_add_su = 0000000100000011 y_add_ss = 1111111111000011 z_add_uu = 0000000100000011 z_add_us = 0000000100000011 z_add_su = 0000000100000011 z_add_ss = 1111111111000011 y_sub_uu = 0000000010100111 y_sub_us = 0000000010100111 y_sub_su = 0000000010100111 y_sub_ss = 1111111111100111 z_sub_uu = 0000000010100111 z_sub_us = 0000000010100111 z_sub_su = 0000000010100111 z_sub_ss = 1111111111100111 y_mul_uu = 0010011001000110 y_mul_us = 0010011001000110 y_mul_su = 0010011001000110 y_mul_ss = 0000001100000110 z_mul_uu = 0010011001000110 z_mul_us = 0010011001000110 z_mul_su = 0010011001000110 z_mul_ss = 0000001100000110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11001111 b = 00100011 c = 001010 y_mux_uu = 0000000011001111 y_mux_us = 0000000011001111 y_mux_su = 0000000011001111 y_mux_ss = 1111111111001111 z_mux_uu = 0000000011001111 z_mux_us = 0000000011001111 z_mux_su = 0000000011001111 z_mux_ss = 1111111111001111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110101 y_sgn_s = 1111111111110101 z_sgn_u = 1111111111110101 z_sgn_s = 1111111111110101 y_add_uu = 0000000011011001 y_add_us = 0000000011011001 y_add_su = 0000000011011001 y_add_ss = 1111111111011001 z_add_uu = 0000000011011001 z_add_us = 0000000011011001 z_add_su = 0000000011011001 z_add_ss = 1111111111011001 y_sub_uu = 0000000011000101 y_sub_us = 0000000011000101 y_sub_su = 0000000011000101 y_sub_ss = 1111111111000101 z_sub_uu = 0000000011000101 z_sub_us = 0000000011000101 z_sub_su = 0000000011000101 z_sub_ss = 1111111111000101 y_mul_uu = 0000100000010110 y_mul_us = 0000100000010110 y_mul_su = 0000100000010110 y_mul_ss = 1111111000010110 z_mul_uu = 0000100000010110 z_mul_us = 0000100000010110 z_mul_su = 0000100000010110 z_mul_ss = 1111111000010110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00111100 b = 11110010 c = 001010 y_mux_uu = 0000000011110010 y_mux_us = 0000000011110010 y_mux_su = 0000000011110010 y_mux_ss = 1111111111110010 z_mux_uu = 0000000011110010 z_mux_us = 0000000011110010 z_mux_su = 0000000011110010 z_mux_ss = 1111111111110010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110101 y_sgn_s = 1111111111110101 z_sgn_u = 1111111111110101 z_sgn_s = 1111111111110101 y_add_uu = 0000000001000110 y_add_us = 0000000001000110 y_add_su = 0000000001000110 y_add_ss = 0000000001000110 z_add_uu = 0000000001000110 z_add_us = 0000000001000110 z_add_su = 0000000001000110 z_add_ss = 0000000001000110 y_sub_uu = 0000000000110010 y_sub_us = 0000000000110010 y_sub_su = 0000000000110010 y_sub_ss = 0000000000110010 z_sub_uu = 0000000000110010 z_sub_us = 0000000000110010 z_sub_su = 0000000000110010 z_sub_ss = 0000000000110010 y_mul_uu = 0000001001011000 y_mul_us = 0000001001011000 y_mul_su = 0000001001011000 y_mul_ss = 0000001001011000 z_mul_uu = 0000001001011000 z_mul_us = 0000001001011000 z_mul_su = 0000001001011000 z_mul_ss = 0000001001011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11011000 b = 01111000 c = 001001 y_mux_uu = 0000000011011000 y_mux_us = 0000000011011000 y_mux_su = 0000000011011000 y_mux_ss = 1111111111011000 z_mux_uu = 0000000011011000 z_mux_us = 0000000011011000 z_mux_su = 0000000011011000 z_mux_ss = 1111111111011000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110110 y_sgn_s = 1111111111110110 z_sgn_u = 1111111111110110 z_sgn_s = 1111111111110110 y_add_uu = 0000000011100001 y_add_us = 0000000011100001 y_add_su = 0000000011100001 y_add_ss = 1111111111100001 z_add_uu = 0000000011100001 z_add_us = 0000000011100001 z_add_su = 0000000011100001 z_add_ss = 1111111111100001 y_sub_uu = 0000000011001111 y_sub_us = 0000000011001111 y_sub_su = 0000000011001111 y_sub_ss = 1111111111001111 z_sub_uu = 0000000011001111 z_sub_us = 0000000011001111 z_sub_su = 0000000011001111 z_sub_ss = 1111111111001111 y_mul_uu = 0000011110011000 y_mul_us = 0000011110011000 y_mul_su = 0000011110011000 y_mul_ss = 1111111010011000 z_mul_uu = 0000011110011000 z_mul_us = 0000011110011000 z_mul_su = 0000011110011000 z_mul_ss = 1111111010011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10110110 b = 11000110 c = 101110 y_mux_uu = 0000000010110110 y_mux_us = 0000000010110110 y_mux_su = 0000000010110110 y_mux_ss = 1111111110110110 z_mux_uu = 0000000010110110 z_mux_us = 0000000010110110 z_mux_su = 0000000010110110 z_mux_ss = 1111111110110110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010001 y_sgn_s = 0000000000010001 z_sgn_u = 1111111111010001 z_sgn_s = 0000000000010001 y_add_uu = 0000000011100100 y_add_us = 0000000011100100 y_add_su = 0000000011100100 y_add_ss = 1111111110100100 z_add_uu = 0000000011100100 z_add_us = 0000000011100100 z_add_su = 0000000011100100 z_add_ss = 1111111110100100 y_sub_uu = 0000000010001000 y_sub_us = 0000000010001000 y_sub_su = 0000000010001000 y_sub_ss = 1111111111001000 z_sub_uu = 0000000010001000 z_sub_us = 0000000010001000 z_sub_su = 0000000010001000 z_sub_ss = 1111111111001000 y_mul_uu = 0010000010110100 y_mul_us = 0010000010110100 y_mul_su = 0010000010110100 y_mul_ss = 0000010100110100 z_mul_uu = 0010000010110100 z_mul_us = 0010000010110100 z_mul_su = 0010000010110100 z_mul_ss = 0000010100110100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00101010 b = 00001011 c = 110001 y_mux_uu = 0000000000001011 y_mux_us = 0000000000001011 y_mux_su = 0000000000001011 y_mux_ss = 0000000000001011 z_mux_uu = 0000000000001011 z_mux_us = 0000000000001011 z_mux_su = 0000000000001011 z_mux_ss = 0000000000001011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001110 y_sgn_s = 0000000000001110 z_sgn_u = 1111111111001110 z_sgn_s = 0000000000001110 y_add_uu = 0000000001011011 y_add_us = 0000000001011011 y_add_su = 0000000001011011 y_add_ss = 0000000000011011 z_add_uu = 0000000001011011 z_add_us = 0000000001011011 z_add_su = 0000000001011011 z_add_ss = 0000000000011011 y_sub_uu = 1111111111111001 y_sub_us = 1111111111111001 y_sub_su = 1111111111111001 y_sub_ss = 0000000000111001 z_sub_uu = 1111111111111001 z_sub_us = 1111111111111001 z_sub_su = 1111111111111001 z_sub_ss = 0000000000111001 y_mul_uu = 0000100000001010 y_mul_us = 0000100000001010 y_mul_su = 0000100000001010 y_mul_ss = 1111110110001010 z_mul_uu = 0000100000001010 z_mul_us = 0000100000001010 z_mul_su = 0000100000001010 z_mul_ss = 1111110110001010 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 0 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 1 a = 01001111 b = 00111011 c = 111010 y_mux_uu = 0000000001001111 y_mux_us = 0000000001001111 y_mux_su = 0000000001001111 y_mux_ss = 0000000001001111 z_mux_uu = 0000000001001111 z_mux_us = 0000000001001111 z_mux_su = 0000000001001111 z_mux_ss = 0000000001001111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000101 y_sgn_s = 0000000000000101 z_sgn_u = 1111111111000101 z_sgn_s = 0000000000000101 y_add_uu = 0000000010001001 y_add_us = 0000000010001001 y_add_su = 0000000010001001 y_add_ss = 0000000001001001 z_add_uu = 0000000010001001 z_add_us = 0000000010001001 z_add_su = 0000000010001001 z_add_ss = 0000000001001001 y_sub_uu = 0000000000010101 y_sub_us = 0000000000010101 y_sub_su = 0000000000010101 y_sub_ss = 0000000001010101 z_sub_uu = 0000000000010101 z_sub_us = 0000000000010101 z_sub_su = 0000000000010101 z_sub_ss = 0000000001010101 y_mul_uu = 0001000111100110 y_mul_us = 0001000111100110 y_mul_su = 0001000111100110 y_mul_ss = 1111111000100110 z_mul_uu = 0001000111100110 z_mul_us = 0001000111100110 z_mul_su = 0001000111100110 z_mul_ss = 1111111000100110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00010101 b = 11110001 c = 011001 y_mux_uu = 0000000011110001 y_mux_us = 0000000011110001 y_mux_su = 0000000011110001 y_mux_ss = 1111111111110001 z_mux_uu = 0000000011110001 z_mux_us = 0000000011110001 z_mux_su = 0000000011110001 z_mux_ss = 1111111111110001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100110 y_sgn_s = 1111111111100110 z_sgn_u = 1111111111100110 z_sgn_s = 1111111111100110 y_add_uu = 0000000000101110 y_add_us = 0000000000101110 y_add_su = 0000000000101110 y_add_ss = 0000000000101110 z_add_uu = 0000000000101110 z_add_us = 0000000000101110 z_add_su = 0000000000101110 z_add_ss = 0000000000101110 y_sub_uu = 1111111111111100 y_sub_us = 1111111111111100 y_sub_su = 1111111111111100 y_sub_ss = 1111111111111100 z_sub_uu = 1111111111111100 z_sub_us = 1111111111111100 z_sub_su = 1111111111111100 z_sub_ss = 1111111111111100 y_mul_uu = 0000001000001101 y_mul_us = 0000001000001101 y_mul_su = 0000001000001101 y_mul_ss = 0000001000001101 z_mul_uu = 0000001000001101 z_mul_us = 0000001000001101 z_mul_su = 0000001000001101 z_mul_ss = 0000001000001101 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 1 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 1 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 1 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 1 sel = 0 a = 01001100 b = 10011111 c = 001111 y_mux_uu = 0000000010011111 y_mux_us = 0000000010011111 y_mux_su = 0000000010011111 y_mux_ss = 1111111110011111 z_mux_uu = 0000000010011111 z_mux_us = 0000000010011111 z_mux_su = 0000000010011111 z_mux_ss = 1111111110011111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110000 y_sgn_s = 1111111111110000 z_sgn_u = 1111111111110000 z_sgn_s = 1111111111110000 y_add_uu = 0000000001011011 y_add_us = 0000000001011011 y_add_su = 0000000001011011 y_add_ss = 0000000001011011 z_add_uu = 0000000001011011 z_add_us = 0000000001011011 z_add_su = 0000000001011011 z_add_ss = 0000000001011011 y_sub_uu = 0000000000111101 y_sub_us = 0000000000111101 y_sub_su = 0000000000111101 y_sub_ss = 0000000000111101 z_sub_uu = 0000000000111101 z_sub_us = 0000000000111101 z_sub_su = 0000000000111101 z_sub_ss = 0000000000111101 y_mul_uu = 0000010001110100 y_mul_us = 0000010001110100 y_mul_su = 0000010001110100 y_mul_ss = 0000010001110100 z_mul_uu = 0000010001110100 z_mul_us = 0000010001110100 z_mul_su = 0000010001110100 z_mul_ss = 0000010001110100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10110111 b = 10011111 c = 011100 y_mux_uu = 0000000010011111 y_mux_us = 0000000010011111 y_mux_su = 0000000010011111 y_mux_ss = 1111111110011111 z_mux_uu = 0000000010011111 z_mux_us = 0000000010011111 z_mux_su = 0000000010011111 z_mux_ss = 1111111110011111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100011 y_sgn_s = 1111111111100011 z_sgn_u = 1111111111100011 z_sgn_s = 1111111111100011 y_add_uu = 0000000011010011 y_add_us = 0000000011010011 y_add_su = 0000000011010011 y_add_ss = 1111111111010011 z_add_uu = 0000000011010011 z_add_us = 0000000011010011 z_add_su = 0000000011010011 z_add_ss = 1111111111010011 y_sub_uu = 0000000010011011 y_sub_us = 0000000010011011 y_sub_su = 0000000010011011 y_sub_ss = 1111111110011011 z_sub_uu = 0000000010011011 z_sub_us = 0000000010011011 z_sub_su = 0000000010011011 z_sub_ss = 1111111110011011 y_mul_uu = 0001010000000100 y_mul_us = 0001010000000100 y_mul_su = 0001010000000100 y_mul_ss = 1111100000000100 z_mul_uu = 0001010000000100 z_mul_us = 0001010000000100 z_mul_su = 0001010000000100 z_mul_ss = 1111100000000100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10001001 b = 01001001 c = 010000 y_mux_uu = 0000000010001001 y_mux_us = 0000000010001001 y_mux_su = 0000000010001001 y_mux_ss = 1111111110001001 z_mux_uu = 0000000010001001 z_mux_us = 0000000010001001 z_mux_su = 0000000010001001 z_mux_ss = 1111111110001001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101111 y_sgn_s = 1111111111101111 z_sgn_u = 1111111111101111 z_sgn_s = 1111111111101111 y_add_uu = 0000000010011001 y_add_us = 0000000010011001 y_add_su = 0000000010011001 y_add_ss = 1111111110011001 z_add_uu = 0000000010011001 z_add_us = 0000000010011001 z_add_su = 0000000010011001 z_add_ss = 1111111110011001 y_sub_uu = 0000000001111001 y_sub_us = 0000000001111001 y_sub_su = 0000000001111001 y_sub_ss = 1111111101111001 z_sub_uu = 0000000001111001 z_sub_us = 0000000001111001 z_sub_su = 0000000001111001 z_sub_ss = 1111111101111001 y_mul_uu = 0000100010010000 y_mul_us = 0000100010010000 y_mul_su = 0000100010010000 y_mul_ss = 1111100010010000 z_mul_uu = 0000100010010000 z_mul_us = 0000100010010000 z_mul_su = 0000100010010000 z_mul_ss = 1111100010010000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01010001 b = 10010110 c = 001100 y_mux_uu = 0000000001010001 y_mux_us = 0000000001010001 y_mux_su = 0000000001010001 y_mux_ss = 0000000001010001 z_mux_uu = 0000000001010001 z_mux_us = 0000000001010001 z_mux_su = 0000000001010001 z_mux_ss = 0000000001010001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110011 y_sgn_s = 1111111111110011 z_sgn_u = 1111111111110011 z_sgn_s = 1111111111110011 y_add_uu = 0000000001011101 y_add_us = 0000000001011101 y_add_su = 0000000001011101 y_add_ss = 0000000001011101 z_add_uu = 0000000001011101 z_add_us = 0000000001011101 z_add_su = 0000000001011101 z_add_ss = 0000000001011101 y_sub_uu = 0000000001000101 y_sub_us = 0000000001000101 y_sub_su = 0000000001000101 y_sub_ss = 0000000001000101 z_sub_uu = 0000000001000101 z_sub_us = 0000000001000101 z_sub_su = 0000000001000101 z_sub_ss = 0000000001000101 y_mul_uu = 0000001111001100 y_mul_us = 0000001111001100 y_mul_su = 0000001111001100 y_mul_ss = 0000001111001100 z_mul_uu = 0000001111001100 z_mul_us = 0000001111001100 z_mul_su = 0000001111001100 z_mul_ss = 0000001111001100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 11001000 b = 01110111 c = 111101 y_mux_uu = 0000000001110111 y_mux_us = 0000000001110111 y_mux_su = 0000000001110111 y_mux_ss = 0000000001110111 z_mux_uu = 0000000001110111 z_mux_us = 0000000001110111 z_mux_su = 0000000001110111 z_mux_ss = 0000000001110111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000010 y_sgn_s = 0000000000000010 z_sgn_u = 1111111111000010 z_sgn_s = 0000000000000010 y_add_uu = 0000000100000101 y_add_us = 0000000100000101 y_add_su = 0000000100000101 y_add_ss = 1111111111000101 z_add_uu = 0000000100000101 z_add_us = 0000000100000101 z_add_su = 0000000100000101 z_add_ss = 1111111111000101 y_sub_uu = 0000000010001011 y_sub_us = 0000000010001011 y_sub_su = 0000000010001011 y_sub_ss = 1111111111001011 z_sub_uu = 0000000010001011 z_sub_us = 0000000010001011 z_sub_su = 0000000010001011 z_sub_ss = 1111111111001011 y_mul_uu = 0010111110101000 y_mul_us = 0010111110101000 y_mul_su = 0010111110101000 y_mul_ss = 0000000010101000 z_mul_uu = 0010111110101000 z_mul_us = 0010111110101000 z_mul_su = 0010111110101000 z_mul_ss = 0000000010101000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 01111110 b = 01101101 c = 111001 y_mux_uu = 0000000001101101 y_mux_us = 0000000001101101 y_mux_su = 0000000001101101 y_mux_ss = 0000000001101101 z_mux_uu = 0000000001101101 z_mux_us = 0000000001101101 z_mux_su = 0000000001101101 z_mux_ss = 0000000001101101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000110 y_sgn_s = 0000000000000110 z_sgn_u = 1111111111000110 z_sgn_s = 0000000000000110 y_add_uu = 0000000010110111 y_add_us = 0000000010110111 y_add_su = 0000000010110111 y_add_ss = 0000000001110111 z_add_uu = 0000000010110111 z_add_us = 0000000010110111 z_add_su = 0000000010110111 z_add_ss = 0000000001110111 y_sub_uu = 0000000001000101 y_sub_us = 0000000001000101 y_sub_su = 0000000001000101 y_sub_ss = 0000000010000101 z_sub_uu = 0000000001000101 z_sub_us = 0000000001000101 z_sub_su = 0000000001000101 z_sub_ss = 0000000010000101 y_mul_uu = 0001110000001110 y_mul_us = 0001110000001110 y_mul_su = 0001110000001110 y_mul_ss = 1111110010001110 z_mul_uu = 0001110000001110 z_mul_us = 0001110000001110 z_mul_su = 0001110000001110 z_mul_ss = 1111110010001110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11010011 b = 10000101 c = 111000 y_mux_uu = 0000000011010011 y_mux_us = 0000000011010011 y_mux_su = 0000000011010011 y_mux_ss = 1111111111010011 z_mux_uu = 0000000011010011 z_mux_us = 0000000011010011 z_mux_su = 0000000011010011 z_mux_ss = 1111111111010011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000111 y_sgn_s = 0000000000000111 z_sgn_u = 1111111111000111 z_sgn_s = 0000000000000111 y_add_uu = 0000000100001011 y_add_us = 0000000100001011 y_add_su = 0000000100001011 y_add_ss = 1111111111001011 z_add_uu = 0000000100001011 z_add_us = 0000000100001011 z_add_su = 0000000100001011 z_add_ss = 1111111111001011 y_sub_uu = 0000000010011011 y_sub_us = 0000000010011011 y_sub_su = 0000000010011011 y_sub_ss = 1111111111011011 z_sub_uu = 0000000010011011 z_sub_us = 0000000010011011 z_sub_su = 0000000010011011 z_sub_ss = 1111111111011011 y_mul_uu = 0010111000101000 y_mul_us = 0010111000101000 y_mul_su = 0010111000101000 y_mul_ss = 0000000101101000 z_mul_uu = 0010111000101000 z_mul_us = 0010111000101000 z_mul_su = 0010111000101000 z_mul_ss = 0000000101101000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01001001 b = 00111111 c = 101010 y_mux_uu = 0000000001001001 y_mux_us = 0000000001001001 y_mux_su = 0000000001001001 y_mux_ss = 0000000001001001 z_mux_uu = 0000000001001001 z_mux_us = 0000000001001001 z_mux_su = 0000000001001001 z_mux_ss = 0000000001001001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010101 y_sgn_s = 0000000000010101 z_sgn_u = 1111111111010101 z_sgn_s = 0000000000010101 y_add_uu = 0000000001110011 y_add_us = 0000000001110011 y_add_su = 0000000001110011 y_add_ss = 0000000000110011 z_add_uu = 0000000001110011 z_add_us = 0000000001110011 z_add_su = 0000000001110011 z_add_ss = 0000000000110011 y_sub_uu = 0000000000011111 y_sub_us = 0000000000011111 y_sub_su = 0000000000011111 y_sub_ss = 0000000001011111 z_sub_uu = 0000000000011111 z_sub_us = 0000000000011111 z_sub_su = 0000000000011111 z_sub_ss = 0000000001011111 y_mul_uu = 0000101111111010 y_mul_us = 0000101111111010 y_mul_su = 0000101111111010 y_mul_ss = 1111100110111010 z_mul_uu = 0000101111111010 z_mul_us = 0000101111111010 z_mul_su = 0000101111111010 z_mul_ss = 1111100110111010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10000110 b = 10001110 c = 011100 y_mux_uu = 0000000010001110 y_mux_us = 0000000010001110 y_mux_su = 0000000010001110 y_mux_ss = 1111111110001110 z_mux_uu = 0000000010001110 z_mux_us = 0000000010001110 z_mux_su = 0000000010001110 z_mux_ss = 1111111110001110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100011 y_sgn_s = 1111111111100011 z_sgn_u = 1111111111100011 z_sgn_s = 1111111111100011 y_add_uu = 0000000010100010 y_add_us = 0000000010100010 y_add_su = 0000000010100010 y_add_ss = 1111111110100010 z_add_uu = 0000000010100010 z_add_us = 0000000010100010 z_add_su = 0000000010100010 z_add_ss = 1111111110100010 y_sub_uu = 0000000001101010 y_sub_us = 0000000001101010 y_sub_su = 0000000001101010 y_sub_ss = 1111111101101010 z_sub_uu = 0000000001101010 z_sub_us = 0000000001101010 z_sub_su = 0000000001101010 z_sub_ss = 1111111101101010 y_mul_uu = 0000111010101000 y_mul_us = 0000111010101000 y_mul_su = 0000111010101000 y_mul_ss = 1111001010101000 z_mul_uu = 0000111010101000 z_mul_us = 0000111010101000 z_mul_su = 0000111010101000 z_mul_ss = 1111001010101000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00100110 b = 01110011 c = 100011 y_mux_uu = 0000000001110011 y_mux_us = 0000000001110011 y_mux_su = 0000000001110011 y_mux_ss = 0000000001110011 z_mux_uu = 0000000001110011 z_mux_us = 0000000001110011 z_mux_su = 0000000001110011 z_mux_ss = 0000000001110011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011100 y_sgn_s = 0000000000011100 z_sgn_u = 1111111111011100 z_sgn_s = 0000000000011100 y_add_uu = 0000000001001001 y_add_us = 0000000001001001 y_add_su = 0000000001001001 y_add_ss = 0000000000001001 z_add_uu = 0000000001001001 z_add_us = 0000000001001001 z_add_su = 0000000001001001 z_add_ss = 0000000000001001 y_sub_uu = 0000000000000011 y_sub_us = 0000000000000011 y_sub_su = 0000000000000011 y_sub_ss = 0000000001000011 z_sub_uu = 0000000000000011 z_sub_us = 0000000000000011 z_sub_su = 0000000000000011 z_sub_ss = 0000000001000011 y_mul_uu = 0000010100110010 y_mul_us = 0000010100110010 y_mul_su = 0000010100110010 y_mul_ss = 1111101110110010 z_mul_uu = 0000010100110010 z_mul_us = 0000010100110010 z_mul_su = 0000010100110010 z_mul_ss = 1111101110110010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 10110011 b = 01011111 c = 000100 y_mux_uu = 0000000010110011 y_mux_us = 0000000010110011 y_mux_su = 0000000010110011 y_mux_ss = 1111111110110011 z_mux_uu = 0000000010110011 z_mux_us = 0000000010110011 z_mux_su = 0000000010110011 z_mux_ss = 1111111110110011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111011 y_sgn_s = 1111111111111011 z_sgn_u = 1111111111111011 z_sgn_s = 1111111111111011 y_add_uu = 0000000010110111 y_add_us = 0000000010110111 y_add_su = 0000000010110111 y_add_ss = 1111111110110111 z_add_uu = 0000000010110111 z_add_us = 0000000010110111 z_add_su = 0000000010110111 z_add_ss = 1111111110110111 y_sub_uu = 0000000010101111 y_sub_us = 0000000010101111 y_sub_su = 0000000010101111 y_sub_ss = 1111111110101111 z_sub_uu = 0000000010101111 z_sub_us = 0000000010101111 z_sub_su = 0000000010101111 z_sub_ss = 1111111110101111 y_mul_uu = 0000001011001100 y_mul_us = 0000001011001100 y_mul_su = 0000001011001100 y_mul_ss = 1111111011001100 z_mul_uu = 0000001011001100 z_mul_us = 0000001011001100 z_mul_su = 0000001011001100 z_mul_ss = 1111111011001100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11001011 b = 11100110 c = 011010 y_mux_uu = 0000000011001011 y_mux_us = 0000000011001011 y_mux_su = 0000000011001011 y_mux_ss = 1111111111001011 z_mux_uu = 0000000011001011 z_mux_us = 0000000011001011 z_mux_su = 0000000011001011 z_mux_ss = 1111111111001011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100101 y_sgn_s = 1111111111100101 z_sgn_u = 1111111111100101 z_sgn_s = 1111111111100101 y_add_uu = 0000000011100101 y_add_us = 0000000011100101 y_add_su = 0000000011100101 y_add_ss = 1111111111100101 z_add_uu = 0000000011100101 z_add_us = 0000000011100101 z_add_su = 0000000011100101 z_add_ss = 1111111111100101 y_sub_uu = 0000000010110001 y_sub_us = 0000000010110001 y_sub_su = 0000000010110001 y_sub_ss = 1111111110110001 z_sub_uu = 0000000010110001 z_sub_us = 0000000010110001 z_sub_su = 0000000010110001 z_sub_ss = 1111111110110001 y_mul_uu = 0001010010011110 y_mul_us = 0001010010011110 y_mul_su = 0001010010011110 y_mul_ss = 1111101010011110 z_mul_uu = 0001010010011110 z_mul_us = 0001010010011110 z_mul_su = 0001010010011110 z_mul_ss = 1111101010011110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11101101 b = 11011010 c = 100101 y_mux_uu = 0000000011101101 y_mux_us = 0000000011101101 y_mux_su = 0000000011101101 y_mux_ss = 1111111111101101 z_mux_uu = 0000000011101101 z_mux_us = 0000000011101101 z_mux_su = 0000000011101101 z_mux_ss = 1111111111101101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011010 y_sgn_s = 0000000000011010 z_sgn_u = 1111111111011010 z_sgn_s = 0000000000011010 y_add_uu = 0000000100010010 y_add_us = 0000000100010010 y_add_su = 0000000100010010 y_add_ss = 1111111111010010 z_add_uu = 0000000100010010 z_add_us = 0000000100010010 z_add_su = 0000000100010010 z_add_ss = 1111111111010010 y_sub_uu = 0000000011001000 y_sub_us = 0000000011001000 y_sub_su = 0000000011001000 y_sub_ss = 0000000000001000 z_sub_uu = 0000000011001000 z_sub_us = 0000000011001000 z_sub_su = 0000000011001000 z_sub_ss = 0000000000001000 y_mul_uu = 0010001001000001 y_mul_us = 0010001001000001 y_mul_su = 0010001001000001 y_mul_ss = 0000001000000001 z_mul_uu = 0010001001000001 z_mul_us = 0010001001000001 z_mul_su = 0010001001000001 z_mul_ss = 0000001000000001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11011111 b = 01111001 c = 000100 y_mux_uu = 0000000011011111 y_mux_us = 0000000011011111 y_mux_su = 0000000011011111 y_mux_ss = 1111111111011111 z_mux_uu = 0000000011011111 z_mux_us = 0000000011011111 z_mux_su = 0000000011011111 z_mux_ss = 1111111111011111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111011 y_sgn_s = 1111111111111011 z_sgn_u = 1111111111111011 z_sgn_s = 1111111111111011 y_add_uu = 0000000011100011 y_add_us = 0000000011100011 y_add_su = 0000000011100011 y_add_ss = 1111111111100011 z_add_uu = 0000000011100011 z_add_us = 0000000011100011 z_add_su = 0000000011100011 z_add_ss = 1111111111100011 y_sub_uu = 0000000011011011 y_sub_us = 0000000011011011 y_sub_su = 0000000011011011 y_sub_ss = 1111111111011011 z_sub_uu = 0000000011011011 z_sub_us = 0000000011011011 z_sub_su = 0000000011011011 z_sub_ss = 1111111111011011 y_mul_uu = 0000001101111100 y_mul_us = 0000001101111100 y_mul_su = 0000001101111100 y_mul_ss = 1111111101111100 z_mul_uu = 0000001101111100 z_mul_us = 0000001101111100 z_mul_su = 0000001101111100 z_mul_ss = 1111111101111100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00101010 b = 10101011 c = 001110 y_mux_uu = 0000000010101011 y_mux_us = 0000000010101011 y_mux_su = 0000000010101011 y_mux_ss = 1111111110101011 z_mux_uu = 0000000010101011 z_mux_us = 0000000010101011 z_mux_su = 0000000010101011 z_mux_ss = 1111111110101011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110001 y_sgn_s = 1111111111110001 z_sgn_u = 1111111111110001 z_sgn_s = 1111111111110001 y_add_uu = 0000000000111000 y_add_us = 0000000000111000 y_add_su = 0000000000111000 y_add_ss = 0000000000111000 z_add_uu = 0000000000111000 z_add_us = 0000000000111000 z_add_su = 0000000000111000 z_add_ss = 0000000000111000 y_sub_uu = 0000000000011100 y_sub_us = 0000000000011100 y_sub_su = 0000000000011100 y_sub_ss = 0000000000011100 z_sub_uu = 0000000000011100 z_sub_us = 0000000000011100 z_sub_su = 0000000000011100 z_sub_ss = 0000000000011100 y_mul_uu = 0000001001001100 y_mul_us = 0000001001001100 y_mul_su = 0000001001001100 y_mul_ss = 0000001001001100 z_mul_uu = 0000001001001100 z_mul_us = 0000001001001100 z_mul_su = 0000001001001100 z_mul_ss = 0000001001001100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10011010 b = 11111101 c = 000011 y_mux_uu = 0000000011111101 y_mux_us = 0000000011111101 y_mux_su = 0000000011111101 y_mux_ss = 1111111111111101 z_mux_uu = 0000000011111101 z_mux_us = 0000000011111101 z_mux_su = 0000000011111101 z_mux_ss = 1111111111111101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111100 y_sgn_s = 1111111111111100 z_sgn_u = 1111111111111100 z_sgn_s = 1111111111111100 y_add_uu = 0000000010011101 y_add_us = 0000000010011101 y_add_su = 0000000010011101 y_add_ss = 1111111110011101 z_add_uu = 0000000010011101 z_add_us = 0000000010011101 z_add_su = 0000000010011101 z_add_ss = 1111111110011101 y_sub_uu = 0000000010010111 y_sub_us = 0000000010010111 y_sub_su = 0000000010010111 y_sub_ss = 1111111110010111 z_sub_uu = 0000000010010111 z_sub_us = 0000000010010111 z_sub_su = 0000000010010111 z_sub_ss = 1111111110010111 y_mul_uu = 0000000111001110 y_mul_us = 0000000111001110 y_mul_su = 0000000111001110 y_mul_ss = 1111111011001110 z_mul_uu = 0000000111001110 z_mul_us = 0000000111001110 z_mul_su = 0000000111001110 z_mul_ss = 1111111011001110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 01001110 b = 01100111 c = 001010 y_mux_uu = 0000000001100111 y_mux_us = 0000000001100111 y_mux_su = 0000000001100111 y_mux_ss = 0000000001100111 z_mux_uu = 0000000001100111 z_mux_us = 0000000001100111 z_mux_su = 0000000001100111 z_mux_ss = 0000000001100111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110101 y_sgn_s = 1111111111110101 z_sgn_u = 1111111111110101 z_sgn_s = 1111111111110101 y_add_uu = 0000000001011000 y_add_us = 0000000001011000 y_add_su = 0000000001011000 y_add_ss = 0000000001011000 z_add_uu = 0000000001011000 z_add_us = 0000000001011000 z_add_su = 0000000001011000 z_add_ss = 0000000001011000 y_sub_uu = 0000000001000100 y_sub_us = 0000000001000100 y_sub_su = 0000000001000100 y_sub_ss = 0000000001000100 z_sub_uu = 0000000001000100 z_sub_us = 0000000001000100 z_sub_su = 0000000001000100 z_sub_ss = 0000000001000100 y_mul_uu = 0000001100001100 y_mul_us = 0000001100001100 y_mul_su = 0000001100001100 y_mul_ss = 0000001100001100 z_mul_uu = 0000001100001100 z_mul_us = 0000001100001100 z_mul_su = 0000001100001100 z_mul_ss = 0000001100001100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00111000 b = 01111001 c = 111000 y_mux_uu = 0000000001111001 y_mux_us = 0000000001111001 y_mux_su = 0000000001111001 y_mux_ss = 0000000001111001 z_mux_uu = 0000000001111001 z_mux_us = 0000000001111001 z_mux_su = 0000000001111001 z_mux_ss = 0000000001111001 y_eql_uu = 1 y_eql_us = 1 y_eql_su = 1 y_eql_ss = 0 z_eql_uu = 1 z_eql_us = 1 z_eql_su = 1 z_eql_ss = 0 y_neq_uu = 0 y_neq_us = 0 y_neq_su = 0 y_neq_ss = 1 z_neq_uu = 0 z_neq_us = 0 z_neq_su = 0 z_neq_ss = 1 y_sgn_u = 1111111111000111 y_sgn_s = 0000000000000111 z_sgn_u = 1111111111000111 z_sgn_s = 0000000000000111 y_add_uu = 0000000001110000 y_add_us = 0000000001110000 y_add_su = 0000000001110000 y_add_ss = 0000000000110000 z_add_uu = 0000000001110000 z_add_us = 0000000001110000 z_add_su = 0000000001110000 z_add_ss = 0000000000110000 y_sub_uu = 0000000000000000 y_sub_us = 0000000000000000 y_sub_su = 0000000000000000 y_sub_ss = 0000000001000000 z_sub_uu = 0000000000000000 z_sub_us = 0000000000000000 z_sub_su = 0000000000000000 z_sub_ss = 0000000001000000 y_mul_uu = 0000110001000000 y_mul_us = 0000110001000000 y_mul_su = 0000110001000000 y_mul_ss = 1111111001000000 z_mul_uu = 0000110001000000 z_mul_us = 0000110001000000 z_mul_su = 0000110001000000 z_mul_ss = 1111111001000000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 0 a = 10010011 b = 00000100 c = 011001 y_mux_uu = 0000000000000100 y_mux_us = 0000000000000100 y_mux_su = 0000000000000100 y_mux_ss = 0000000000000100 z_mux_uu = 0000000000000100 z_mux_us = 0000000000000100 z_mux_su = 0000000000000100 z_mux_ss = 0000000000000100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100110 y_sgn_s = 1111111111100110 z_sgn_u = 1111111111100110 z_sgn_s = 1111111111100110 y_add_uu = 0000000010101100 y_add_us = 0000000010101100 y_add_su = 0000000010101100 y_add_ss = 1111111110101100 z_add_uu = 0000000010101100 z_add_us = 0000000010101100 z_add_su = 0000000010101100 z_add_ss = 1111111110101100 y_sub_uu = 0000000001111010 y_sub_us = 0000000001111010 y_sub_su = 0000000001111010 y_sub_ss = 1111111101111010 z_sub_uu = 0000000001111010 z_sub_us = 0000000001111010 z_sub_su = 0000000001111010 z_sub_ss = 1111111101111010 y_mul_uu = 0000111001011011 y_mul_us = 0000111001011011 y_mul_su = 0000111001011011 y_mul_ss = 1111010101011011 z_mul_uu = 0000111001011011 z_mul_us = 0000111001011011 z_mul_su = 0000111001011011 z_mul_ss = 1111010101011011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01001101 b = 11011001 c = 101101 y_mux_uu = 0000000001001101 y_mux_us = 0000000001001101 y_mux_su = 0000000001001101 y_mux_ss = 0000000001001101 z_mux_uu = 0000000001001101 z_mux_us = 0000000001001101 z_mux_su = 0000000001001101 z_mux_ss = 0000000001001101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010010 y_sgn_s = 0000000000010010 z_sgn_u = 1111111111010010 z_sgn_s = 0000000000010010 y_add_uu = 0000000001111010 y_add_us = 0000000001111010 y_add_su = 0000000001111010 y_add_ss = 0000000000111010 z_add_uu = 0000000001111010 z_add_us = 0000000001111010 z_add_su = 0000000001111010 z_add_ss = 0000000000111010 y_sub_uu = 0000000000100000 y_sub_us = 0000000000100000 y_sub_su = 0000000000100000 y_sub_ss = 0000000001100000 z_sub_uu = 0000000000100000 z_sub_us = 0000000000100000 z_sub_su = 0000000000100000 z_sub_ss = 0000000001100000 y_mul_uu = 0000110110001001 y_mul_us = 0000110110001001 y_mul_su = 0000110110001001 y_mul_ss = 1111101001001001 z_mul_uu = 0000110110001001 z_mul_us = 0000110110001001 z_mul_su = 0000110110001001 z_mul_ss = 1111101001001001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 11001010 b = 10110110 c = 010101 y_mux_uu = 0000000010110110 y_mux_us = 0000000010110110 y_mux_su = 0000000010110110 y_mux_ss = 1111111110110110 z_mux_uu = 0000000010110110 z_mux_us = 0000000010110110 z_mux_su = 0000000010110110 z_mux_ss = 1111111110110110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101010 y_sgn_s = 1111111111101010 z_sgn_u = 1111111111101010 z_sgn_s = 1111111111101010 y_add_uu = 0000000011011111 y_add_us = 0000000011011111 y_add_su = 0000000011011111 y_add_ss = 1111111111011111 z_add_uu = 0000000011011111 z_add_us = 0000000011011111 z_add_su = 0000000011011111 z_add_ss = 1111111111011111 y_sub_uu = 0000000010110101 y_sub_us = 0000000010110101 y_sub_su = 0000000010110101 y_sub_ss = 1111111110110101 z_sub_uu = 0000000010110101 z_sub_us = 0000000010110101 z_sub_su = 0000000010110101 z_sub_ss = 1111111110110101 y_mul_uu = 0001000010010010 y_mul_us = 0001000010010010 y_mul_su = 0001000010010010 y_mul_ss = 1111101110010010 z_mul_uu = 0001000010010010 z_mul_us = 0001000010010010 z_mul_su = 0001000010010010 z_mul_ss = 1111101110010010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00000100 b = 11110111 c = 101001 y_mux_uu = 0000000011110111 y_mux_us = 0000000011110111 y_mux_su = 0000000011110111 y_mux_ss = 1111111111110111 z_mux_uu = 0000000011110111 z_mux_us = 0000000011110111 z_mux_su = 0000000011110111 z_mux_ss = 1111111111110111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010110 y_sgn_s = 0000000000010110 z_sgn_u = 1111111111010110 z_sgn_s = 0000000000010110 y_add_uu = 0000000000101101 y_add_us = 0000000000101101 y_add_su = 0000000000101101 y_add_ss = 1111111111101101 z_add_uu = 0000000000101101 z_add_us = 0000000000101101 z_add_su = 0000000000101101 z_add_ss = 1111111111101101 y_sub_uu = 1111111111011011 y_sub_us = 1111111111011011 y_sub_su = 1111111111011011 y_sub_ss = 0000000000011011 z_sub_uu = 1111111111011011 z_sub_us = 1111111111011011 z_sub_su = 1111111111011011 z_sub_ss = 0000000000011011 y_mul_uu = 0000000010100100 y_mul_us = 0000000010100100 y_mul_su = 0000000010100100 y_mul_ss = 1111111110100100 z_mul_uu = 0000000010100100 z_mul_us = 0000000010100100 z_mul_su = 0000000010100100 z_mul_ss = 1111111110100100 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 0 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 0 a = 10001000 b = 00101000 c = 101101 y_mux_uu = 0000000000101000 y_mux_us = 0000000000101000 y_mux_su = 0000000000101000 y_mux_ss = 0000000000101000 z_mux_uu = 0000000000101000 z_mux_us = 0000000000101000 z_mux_su = 0000000000101000 z_mux_ss = 0000000000101000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010010 y_sgn_s = 0000000000010010 z_sgn_u = 1111111111010010 z_sgn_s = 0000000000010010 y_add_uu = 0000000010110101 y_add_us = 0000000010110101 y_add_su = 0000000010110101 y_add_ss = 1111111101110101 z_add_uu = 0000000010110101 z_add_us = 0000000010110101 z_add_su = 0000000010110101 z_add_ss = 1111111101110101 y_sub_uu = 0000000001011011 y_sub_us = 0000000001011011 y_sub_su = 0000000001011011 y_sub_ss = 1111111110011011 z_sub_uu = 0000000001011011 z_sub_us = 0000000001011011 z_sub_su = 0000000001011011 z_sub_ss = 1111111110011011 y_mul_uu = 0001011111101000 y_mul_us = 0001011111101000 y_mul_su = 0001011111101000 y_mul_ss = 0000100011101000 z_mul_uu = 0001011111101000 z_mul_us = 0001011111101000 z_mul_su = 0001011111101000 z_mul_ss = 0000100011101000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00101110 b = 00001000 c = 011100 y_mux_uu = 0000000000101110 y_mux_us = 0000000000101110 y_mux_su = 0000000000101110 y_mux_ss = 0000000000101110 z_mux_uu = 0000000000101110 z_mux_us = 0000000000101110 z_mux_su = 0000000000101110 z_mux_ss = 0000000000101110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100011 y_sgn_s = 1111111111100011 z_sgn_u = 1111111111100011 z_sgn_s = 1111111111100011 y_add_uu = 0000000001001010 y_add_us = 0000000001001010 y_add_su = 0000000001001010 y_add_ss = 0000000001001010 z_add_uu = 0000000001001010 z_add_us = 0000000001001010 z_add_su = 0000000001001010 z_add_ss = 0000000001001010 y_sub_uu = 0000000000010010 y_sub_us = 0000000000010010 y_sub_su = 0000000000010010 y_sub_ss = 0000000000010010 z_sub_uu = 0000000000010010 z_sub_us = 0000000000010010 z_sub_su = 0000000000010010 z_sub_ss = 0000000000010010 y_mul_uu = 0000010100001000 y_mul_us = 0000010100001000 y_mul_su = 0000010100001000 y_mul_ss = 0000010100001000 z_mul_uu = 0000010100001000 z_mul_us = 0000010100001000 z_mul_su = 0000010100001000 z_mul_ss = 0000010100001000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 00101001 b = 00011100 c = 000110 y_mux_uu = 0000000000101001 y_mux_us = 0000000000101001 y_mux_su = 0000000000101001 y_mux_ss = 0000000000101001 z_mux_uu = 0000000000101001 z_mux_us = 0000000000101001 z_mux_su = 0000000000101001 z_mux_ss = 0000000000101001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111001 y_sgn_s = 1111111111111001 z_sgn_u = 1111111111111001 z_sgn_s = 1111111111111001 y_add_uu = 0000000000101111 y_add_us = 0000000000101111 y_add_su = 0000000000101111 y_add_ss = 0000000000101111 z_add_uu = 0000000000101111 z_add_us = 0000000000101111 z_add_su = 0000000000101111 z_add_ss = 0000000000101111 y_sub_uu = 0000000000100011 y_sub_us = 0000000000100011 y_sub_su = 0000000000100011 y_sub_ss = 0000000000100011 z_sub_uu = 0000000000100011 z_sub_us = 0000000000100011 z_sub_su = 0000000000100011 z_sub_ss = 0000000000100011 y_mul_uu = 0000000011110110 y_mul_us = 0000000011110110 y_mul_su = 0000000011110110 y_mul_ss = 0000000011110110 z_mul_uu = 0000000011110110 z_mul_us = 0000000011110110 z_mul_su = 0000000011110110 z_mul_ss = 0000000011110110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00111101 b = 01100110 c = 110000 y_mux_uu = 0000000001100110 y_mux_us = 0000000001100110 y_mux_su = 0000000001100110 y_mux_ss = 0000000001100110 z_mux_uu = 0000000001100110 z_mux_us = 0000000001100110 z_mux_su = 0000000001100110 z_mux_ss = 0000000001100110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001111 y_sgn_s = 0000000000001111 z_sgn_u = 1111111111001111 z_sgn_s = 0000000000001111 y_add_uu = 0000000001101101 y_add_us = 0000000001101101 y_add_su = 0000000001101101 y_add_ss = 0000000000101101 z_add_uu = 0000000001101101 z_add_us = 0000000001101101 z_add_su = 0000000001101101 z_add_ss = 0000000000101101 y_sub_uu = 0000000000001101 y_sub_us = 0000000000001101 y_sub_su = 0000000000001101 y_sub_ss = 0000000001001101 z_sub_uu = 0000000000001101 z_sub_us = 0000000000001101 z_sub_su = 0000000000001101 z_sub_ss = 0000000001001101 y_mul_uu = 0000101101110000 y_mul_us = 0000101101110000 y_mul_su = 0000101101110000 y_mul_ss = 1111110000110000 z_mul_uu = 0000101101110000 z_mul_us = 0000101101110000 z_mul_su = 0000101101110000 z_mul_ss = 1111110000110000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 10111010 b = 01011110 c = 111010 y_mux_uu = 0000000010111010 y_mux_us = 0000000010111010 y_mux_su = 0000000010111010 y_mux_ss = 1111111110111010 z_mux_uu = 0000000010111010 z_mux_us = 0000000010111010 z_mux_su = 0000000010111010 z_mux_ss = 1111111110111010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000101 y_sgn_s = 0000000000000101 z_sgn_u = 1111111111000101 z_sgn_s = 0000000000000101 y_add_uu = 0000000011110100 y_add_us = 0000000011110100 y_add_su = 0000000011110100 y_add_ss = 1111111110110100 z_add_uu = 0000000011110100 z_add_us = 0000000011110100 z_add_su = 0000000011110100 z_add_ss = 1111111110110100 y_sub_uu = 0000000010000000 y_sub_us = 0000000010000000 y_sub_su = 0000000010000000 y_sub_ss = 1111111111000000 z_sub_uu = 0000000010000000 z_sub_us = 0000000010000000 z_sub_su = 0000000010000000 z_sub_ss = 1111111111000000 y_mul_uu = 0010101000100100 y_mul_us = 0010101000100100 y_mul_su = 0010101000100100 y_mul_ss = 0000000110100100 z_mul_uu = 0010101000100100 z_mul_us = 0010101000100100 z_mul_su = 0010101000100100 z_mul_ss = 0000000110100100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00011010 b = 10111001 c = 110111 y_mux_uu = 0000000000011010 y_mux_us = 0000000000011010 y_mux_su = 0000000000011010 y_mux_ss = 0000000000011010 z_mux_uu = 0000000000011010 z_mux_us = 0000000000011010 z_mux_su = 0000000000011010 z_mux_ss = 0000000000011010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001000 y_sgn_s = 0000000000001000 z_sgn_u = 1111111111001000 z_sgn_s = 0000000000001000 y_add_uu = 0000000001010001 y_add_us = 0000000001010001 y_add_su = 0000000001010001 y_add_ss = 0000000000010001 z_add_uu = 0000000001010001 z_add_us = 0000000001010001 z_add_su = 0000000001010001 z_add_ss = 0000000000010001 y_sub_uu = 1111111111100011 y_sub_us = 1111111111100011 y_sub_su = 1111111111100011 y_sub_ss = 0000000000100011 z_sub_uu = 1111111111100011 z_sub_us = 1111111111100011 z_sub_su = 1111111111100011 z_sub_ss = 0000000000100011 y_mul_uu = 0000010110010110 y_mul_us = 0000010110010110 y_mul_su = 0000010110010110 y_mul_ss = 1111111100010110 z_mul_uu = 0000010110010110 z_mul_us = 0000010110010110 z_mul_su = 0000010110010110 z_mul_ss = 1111111100010110 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 0 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 0 a = 11000000 b = 00100110 c = 110110 y_mux_uu = 0000000000100110 y_mux_us = 0000000000100110 y_mux_su = 0000000000100110 y_mux_ss = 0000000000100110 z_mux_uu = 0000000000100110 z_mux_us = 0000000000100110 z_mux_su = 0000000000100110 z_mux_ss = 0000000000100110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001001 y_sgn_s = 0000000000001001 z_sgn_u = 1111111111001001 z_sgn_s = 0000000000001001 y_add_uu = 0000000011110110 y_add_us = 0000000011110110 y_add_su = 0000000011110110 y_add_ss = 1111111110110110 z_add_uu = 0000000011110110 z_add_us = 0000000011110110 z_add_su = 0000000011110110 z_add_ss = 1111111110110110 y_sub_uu = 0000000010001010 y_sub_us = 0000000010001010 y_sub_su = 0000000010001010 y_sub_ss = 1111111111001010 z_sub_uu = 0000000010001010 z_sub_us = 0000000010001010 z_sub_su = 0000000010001010 z_sub_ss = 1111111111001010 y_mul_uu = 0010100010000000 y_mul_us = 0010100010000000 y_mul_su = 0010100010000000 y_mul_ss = 0000001010000000 z_mul_uu = 0010100010000000 z_mul_us = 0010100010000000 z_mul_su = 0010100010000000 z_mul_ss = 0000001010000000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11011100 b = 10000110 c = 111000 y_mux_uu = 0000000011011100 y_mux_us = 0000000011011100 y_mux_su = 0000000011011100 y_mux_ss = 1111111111011100 z_mux_uu = 0000000011011100 z_mux_us = 0000000011011100 z_mux_su = 0000000011011100 z_mux_ss = 1111111111011100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000111 y_sgn_s = 0000000000000111 z_sgn_u = 1111111111000111 z_sgn_s = 0000000000000111 y_add_uu = 0000000100010100 y_add_us = 0000000100010100 y_add_su = 0000000100010100 y_add_ss = 1111111111010100 z_add_uu = 0000000100010100 z_add_us = 0000000100010100 z_add_su = 0000000100010100 z_add_ss = 1111111111010100 y_sub_uu = 0000000010100100 y_sub_us = 0000000010100100 y_sub_su = 0000000010100100 y_sub_ss = 1111111111100100 z_sub_uu = 0000000010100100 z_sub_us = 0000000010100100 z_sub_su = 0000000010100100 z_sub_ss = 1111111111100100 y_mul_uu = 0011000000100000 y_mul_us = 0011000000100000 y_mul_su = 0011000000100000 y_mul_ss = 0000000100100000 z_mul_uu = 0011000000100000 z_mul_us = 0011000000100000 z_mul_su = 0011000000100000 z_mul_ss = 0000000100100000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 11011011 b = 11001111 c = 111001 y_mux_uu = 0000000011001111 y_mux_us = 0000000011001111 y_mux_su = 0000000011001111 y_mux_ss = 1111111111001111 z_mux_uu = 0000000011001111 z_mux_us = 0000000011001111 z_mux_su = 0000000011001111 z_mux_ss = 1111111111001111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000110 y_sgn_s = 0000000000000110 z_sgn_u = 1111111111000110 z_sgn_s = 0000000000000110 y_add_uu = 0000000100010100 y_add_us = 0000000100010100 y_add_su = 0000000100010100 y_add_ss = 1111111111010100 z_add_uu = 0000000100010100 z_add_us = 0000000100010100 z_add_su = 0000000100010100 z_add_ss = 1111111111010100 y_sub_uu = 0000000010100010 y_sub_us = 0000000010100010 y_sub_su = 0000000010100010 y_sub_ss = 1111111111100010 z_sub_uu = 0000000010100010 z_sub_us = 0000000010100010 z_sub_su = 0000000010100010 z_sub_ss = 1111111111100010 y_mul_uu = 0011000011000011 y_mul_us = 0011000011000011 y_mul_su = 0011000011000011 y_mul_ss = 0000000100000011 z_mul_uu = 0011000011000011 z_mul_us = 0011000011000011 z_mul_su = 0011000011000011 z_mul_ss = 0000000100000011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 01100001 b = 00010111 c = 100001 y_mux_uu = 0000000000010111 y_mux_us = 0000000000010111 y_mux_su = 0000000000010111 y_mux_ss = 0000000000010111 z_mux_uu = 0000000000010111 z_mux_us = 0000000000010111 z_mux_su = 0000000000010111 z_mux_ss = 0000000000010111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011110 y_sgn_s = 0000000000011110 z_sgn_u = 1111111111011110 z_sgn_s = 0000000000011110 y_add_uu = 0000000010000010 y_add_us = 0000000010000010 y_add_su = 0000000010000010 y_add_ss = 0000000001000010 z_add_uu = 0000000010000010 z_add_us = 0000000010000010 z_add_su = 0000000010000010 z_add_ss = 0000000001000010 y_sub_uu = 0000000001000000 y_sub_us = 0000000001000000 y_sub_su = 0000000001000000 y_sub_ss = 0000000010000000 z_sub_uu = 0000000001000000 z_sub_us = 0000000001000000 z_sub_su = 0000000001000000 z_sub_ss = 0000000010000000 y_mul_uu = 0000110010000001 y_mul_us = 0000110010000001 y_mul_su = 0000110010000001 y_mul_ss = 1111010001000001 z_mul_uu = 0000110010000001 z_mul_us = 0000110010000001 z_mul_su = 0000110010000001 z_mul_ss = 1111010001000001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01010000 b = 11110101 c = 110101 y_mux_uu = 0000000011110101 y_mux_us = 0000000011110101 y_mux_su = 0000000011110101 y_mux_ss = 1111111111110101 z_mux_uu = 0000000011110101 z_mux_us = 0000000011110101 z_mux_su = 0000000011110101 z_mux_ss = 1111111111110101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001010 y_sgn_s = 0000000000001010 z_sgn_u = 1111111111001010 z_sgn_s = 0000000000001010 y_add_uu = 0000000010000101 y_add_us = 0000000010000101 y_add_su = 0000000010000101 y_add_ss = 0000000001000101 z_add_uu = 0000000010000101 z_add_us = 0000000010000101 z_add_su = 0000000010000101 z_add_ss = 0000000001000101 y_sub_uu = 0000000000011011 y_sub_us = 0000000000011011 y_sub_su = 0000000000011011 y_sub_ss = 0000000001011011 z_sub_uu = 0000000000011011 z_sub_us = 0000000000011011 z_sub_su = 0000000000011011 z_sub_ss = 0000000001011011 y_mul_uu = 0001000010010000 y_mul_us = 0001000010010000 y_mul_su = 0001000010010000 y_mul_ss = 1111110010010000 z_mul_uu = 0001000010010000 z_mul_us = 0001000010010000 z_mul_su = 0001000010010000 z_mul_ss = 1111110010010000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11000001 b = 11000101 c = 011000 y_mux_uu = 0000000011000001 y_mux_us = 0000000011000001 y_mux_su = 0000000011000001 y_mux_ss = 1111111111000001 z_mux_uu = 0000000011000001 z_mux_us = 0000000011000001 z_mux_su = 0000000011000001 z_mux_ss = 1111111111000001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100111 y_sgn_s = 1111111111100111 z_sgn_u = 1111111111100111 z_sgn_s = 1111111111100111 y_add_uu = 0000000011011001 y_add_us = 0000000011011001 y_add_su = 0000000011011001 y_add_ss = 1111111111011001 z_add_uu = 0000000011011001 z_add_us = 0000000011011001 z_add_su = 0000000011011001 z_add_ss = 1111111111011001 y_sub_uu = 0000000010101001 y_sub_us = 0000000010101001 y_sub_su = 0000000010101001 y_sub_ss = 1111111110101001 z_sub_uu = 0000000010101001 z_sub_us = 0000000010101001 z_sub_su = 0000000010101001 z_sub_ss = 1111111110101001 y_mul_uu = 0001001000011000 y_mul_us = 0001001000011000 y_mul_su = 0001001000011000 y_mul_ss = 1111101000011000 z_mul_uu = 0001001000011000 z_mul_us = 0001001000011000 z_mul_su = 0001001000011000 z_mul_ss = 1111101000011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01110011 b = 11101100 c = 001010 y_mux_uu = 0000000001110011 y_mux_us = 0000000001110011 y_mux_su = 0000000001110011 y_mux_ss = 0000000001110011 z_mux_uu = 0000000001110011 z_mux_us = 0000000001110011 z_mux_su = 0000000001110011 z_mux_ss = 0000000001110011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110101 y_sgn_s = 1111111111110101 z_sgn_u = 1111111111110101 z_sgn_s = 1111111111110101 y_add_uu = 0000000001111101 y_add_us = 0000000001111101 y_add_su = 0000000001111101 y_add_ss = 0000000001111101 z_add_uu = 0000000001111101 z_add_us = 0000000001111101 z_add_su = 0000000001111101 z_add_ss = 0000000001111101 y_sub_uu = 0000000001101001 y_sub_us = 0000000001101001 y_sub_su = 0000000001101001 y_sub_ss = 0000000001101001 z_sub_uu = 0000000001101001 z_sub_us = 0000000001101001 z_sub_su = 0000000001101001 z_sub_ss = 0000000001101001 y_mul_uu = 0000010001111110 y_mul_us = 0000010001111110 y_mul_su = 0000010001111110 y_mul_ss = 0000010001111110 z_mul_uu = 0000010001111110 z_mul_us = 0000010001111110 z_mul_su = 0000010001111110 z_mul_ss = 0000010001111110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10101000 b = 10101001 c = 100001 y_mux_uu = 0000000010101001 y_mux_us = 0000000010101001 y_mux_su = 0000000010101001 y_mux_ss = 1111111110101001 z_mux_uu = 0000000010101001 z_mux_us = 0000000010101001 z_mux_su = 0000000010101001 z_mux_ss = 1111111110101001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011110 y_sgn_s = 0000000000011110 z_sgn_u = 1111111111011110 z_sgn_s = 0000000000011110 y_add_uu = 0000000011001001 y_add_us = 0000000011001001 y_add_su = 0000000011001001 y_add_ss = 1111111110001001 z_add_uu = 0000000011001001 z_add_us = 0000000011001001 z_add_su = 0000000011001001 z_add_ss = 1111111110001001 y_sub_uu = 0000000010000111 y_sub_us = 0000000010000111 y_sub_su = 0000000010000111 y_sub_ss = 1111111111000111 z_sub_uu = 0000000010000111 z_sub_us = 0000000010000111 z_sub_su = 0000000010000111 z_sub_ss = 1111111111000111 y_mul_uu = 0001010110101000 y_mul_us = 0001010110101000 y_mul_su = 0001010110101000 y_mul_ss = 0000101010101000 z_mul_uu = 0001010110101000 z_mul_us = 0001010110101000 z_mul_su = 0001010110101000 z_mul_ss = 0000101010101000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 11100110 b = 10011111 c = 101010 y_mux_uu = 0000000010011111 y_mux_us = 0000000010011111 y_mux_su = 0000000010011111 y_mux_ss = 1111111110011111 z_mux_uu = 0000000010011111 z_mux_us = 0000000010011111 z_mux_su = 0000000010011111 z_mux_ss = 1111111110011111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010101 y_sgn_s = 0000000000010101 z_sgn_u = 1111111111010101 z_sgn_s = 0000000000010101 y_add_uu = 0000000100010000 y_add_us = 0000000100010000 y_add_su = 0000000100010000 y_add_ss = 1111111111010000 z_add_uu = 0000000100010000 z_add_us = 0000000100010000 z_add_su = 0000000100010000 z_add_ss = 1111111111010000 y_sub_uu = 0000000010111100 y_sub_us = 0000000010111100 y_sub_su = 0000000010111100 y_sub_ss = 1111111111111100 z_sub_uu = 0000000010111100 z_sub_us = 0000000010111100 z_sub_su = 0000000010111100 z_sub_ss = 1111111111111100 y_mul_uu = 0010010110111100 y_mul_us = 0010010110111100 y_mul_su = 0010010110111100 y_mul_ss = 0000001000111100 z_mul_uu = 0010010110111100 z_mul_us = 0010010110111100 z_mul_su = 0010010110111100 z_mul_ss = 0000001000111100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10001101 b = 10011110 c = 111000 y_mux_uu = 0000000010011110 y_mux_us = 0000000010011110 y_mux_su = 0000000010011110 y_mux_ss = 1111111110011110 z_mux_uu = 0000000010011110 z_mux_us = 0000000010011110 z_mux_su = 0000000010011110 z_mux_ss = 1111111110011110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000111 y_sgn_s = 0000000000000111 z_sgn_u = 1111111111000111 z_sgn_s = 0000000000000111 y_add_uu = 0000000011000101 y_add_us = 0000000011000101 y_add_su = 0000000011000101 y_add_ss = 1111111110000101 z_add_uu = 0000000011000101 z_add_us = 0000000011000101 z_add_su = 0000000011000101 z_add_ss = 1111111110000101 y_sub_uu = 0000000001010101 y_sub_us = 0000000001010101 y_sub_su = 0000000001010101 y_sub_ss = 1111111110010101 z_sub_uu = 0000000001010101 z_sub_us = 0000000001010101 z_sub_su = 0000000001010101 z_sub_ss = 1111111110010101 y_mul_uu = 0001111011011000 y_mul_us = 0001111011011000 y_mul_su = 0001111011011000 y_mul_ss = 0000001110011000 z_mul_uu = 0001111011011000 z_mul_us = 0001111011011000 z_mul_su = 0001111011011000 z_mul_ss = 0000001110011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11001000 b = 11001010 c = 010011 y_mux_uu = 0000000011001000 y_mux_us = 0000000011001000 y_mux_su = 0000000011001000 y_mux_ss = 1111111111001000 z_mux_uu = 0000000011001000 z_mux_us = 0000000011001000 z_mux_su = 0000000011001000 z_mux_ss = 1111111111001000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101100 y_sgn_s = 1111111111101100 z_sgn_u = 1111111111101100 z_sgn_s = 1111111111101100 y_add_uu = 0000000011011011 y_add_us = 0000000011011011 y_add_su = 0000000011011011 y_add_ss = 1111111111011011 z_add_uu = 0000000011011011 z_add_us = 0000000011011011 z_add_su = 0000000011011011 z_add_ss = 1111111111011011 y_sub_uu = 0000000010110101 y_sub_us = 0000000010110101 y_sub_su = 0000000010110101 y_sub_ss = 1111111110110101 z_sub_uu = 0000000010110101 z_sub_us = 0000000010110101 z_sub_su = 0000000010110101 z_sub_ss = 1111111110110101 y_mul_uu = 0000111011011000 y_mul_us = 0000111011011000 y_mul_su = 0000111011011000 y_mul_ss = 1111101111011000 z_mul_uu = 0000111011011000 z_mul_us = 0000111011011000 z_mul_su = 0000111011011000 z_mul_ss = 1111101111011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11000111 b = 10110110 c = 111010 y_mux_uu = 0000000011000111 y_mux_us = 0000000011000111 y_mux_su = 0000000011000111 y_mux_ss = 1111111111000111 z_mux_uu = 0000000011000111 z_mux_us = 0000000011000111 z_mux_su = 0000000011000111 z_mux_ss = 1111111111000111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000101 y_sgn_s = 0000000000000101 z_sgn_u = 1111111111000101 z_sgn_s = 0000000000000101 y_add_uu = 0000000100000001 y_add_us = 0000000100000001 y_add_su = 0000000100000001 y_add_ss = 1111111111000001 z_add_uu = 0000000100000001 z_add_us = 0000000100000001 z_add_su = 0000000100000001 z_add_ss = 1111111111000001 y_sub_uu = 0000000010001101 y_sub_us = 0000000010001101 y_sub_su = 0000000010001101 y_sub_ss = 1111111111001101 z_sub_uu = 0000000010001101 z_sub_us = 0000000010001101 z_sub_su = 0000000010001101 z_sub_ss = 1111111111001101 y_mul_uu = 0010110100010110 y_mul_us = 0010110100010110 y_mul_su = 0010110100010110 y_mul_ss = 0000000101010110 z_mul_uu = 0010110100010110 z_mul_us = 0010110100010110 z_mul_su = 0010110100010110 z_mul_ss = 0000000101010110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10111001 b = 10010010 c = 110100 y_mux_uu = 0000000010010010 y_mux_us = 0000000010010010 y_mux_su = 0000000010010010 y_mux_ss = 1111111110010010 z_mux_uu = 0000000010010010 z_mux_us = 0000000010010010 z_mux_su = 0000000010010010 z_mux_ss = 1111111110010010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001011 y_sgn_s = 0000000000001011 z_sgn_u = 1111111111001011 z_sgn_s = 0000000000001011 y_add_uu = 0000000011101101 y_add_us = 0000000011101101 y_add_su = 0000000011101101 y_add_ss = 1111111110101101 z_add_uu = 0000000011101101 z_add_us = 0000000011101101 z_add_su = 0000000011101101 z_add_ss = 1111111110101101 y_sub_uu = 0000000010000101 y_sub_us = 0000000010000101 y_sub_su = 0000000010000101 y_sub_ss = 1111111111000101 z_sub_uu = 0000000010000101 z_sub_us = 0000000010000101 z_sub_su = 0000000010000101 z_sub_ss = 1111111111000101 y_mul_uu = 0010010110010100 y_mul_us = 0010010110010100 y_mul_su = 0010010110010100 y_mul_ss = 0000001101010100 z_mul_uu = 0010010110010100 z_mul_us = 0010010110010100 z_mul_su = 0010010110010100 z_mul_ss = 0000001101010100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10000110 b = 11111010 c = 110010 y_mux_uu = 0000000010000110 y_mux_us = 0000000010000110 y_mux_su = 0000000010000110 y_mux_ss = 1111111110000110 z_mux_uu = 0000000010000110 z_mux_us = 0000000010000110 z_mux_su = 0000000010000110 z_mux_ss = 1111111110000110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001101 y_sgn_s = 0000000000001101 z_sgn_u = 1111111111001101 z_sgn_s = 0000000000001101 y_add_uu = 0000000010111000 y_add_us = 0000000010111000 y_add_su = 0000000010111000 y_add_ss = 1111111101111000 z_add_uu = 0000000010111000 z_add_us = 0000000010111000 z_add_su = 0000000010111000 z_add_ss = 1111111101111000 y_sub_uu = 0000000001010100 y_sub_us = 0000000001010100 y_sub_su = 0000000001010100 y_sub_ss = 1111111110010100 z_sub_uu = 0000000001010100 z_sub_us = 0000000001010100 z_sub_su = 0000000001010100 z_sub_ss = 1111111110010100 y_mul_uu = 0001101000101100 y_mul_us = 0001101000101100 y_mul_su = 0001101000101100 y_mul_ss = 0000011010101100 z_mul_uu = 0001101000101100 z_mul_us = 0001101000101100 z_mul_su = 0001101000101100 z_mul_ss = 0000011010101100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10111101 b = 10000100 c = 100100 y_mux_uu = 0000000010000100 y_mux_us = 0000000010000100 y_mux_su = 0000000010000100 y_mux_ss = 1111111110000100 z_mux_uu = 0000000010000100 z_mux_us = 0000000010000100 z_mux_su = 0000000010000100 z_mux_ss = 1111111110000100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011011 y_sgn_s = 0000000000011011 z_sgn_u = 1111111111011011 z_sgn_s = 0000000000011011 y_add_uu = 0000000011100001 y_add_us = 0000000011100001 y_add_su = 0000000011100001 y_add_ss = 1111111110100001 z_add_uu = 0000000011100001 z_add_us = 0000000011100001 z_add_su = 0000000011100001 z_add_ss = 1111111110100001 y_sub_uu = 0000000010011001 y_sub_us = 0000000010011001 y_sub_su = 0000000010011001 y_sub_ss = 1111111111011001 z_sub_uu = 0000000010011001 z_sub_us = 0000000010011001 z_sub_su = 0000000010011001 z_sub_ss = 1111111111011001 y_mul_uu = 0001101010010100 y_mul_us = 0001101010010100 y_mul_su = 0001101010010100 y_mul_ss = 0000011101010100 z_mul_uu = 0001101010010100 z_mul_us = 0001101010010100 z_mul_su = 0001101010010100 z_mul_ss = 0000011101010100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10101001 b = 10100001 c = 001110 y_mux_uu = 0000000010100001 y_mux_us = 0000000010100001 y_mux_su = 0000000010100001 y_mux_ss = 1111111110100001 z_mux_uu = 0000000010100001 z_mux_us = 0000000010100001 z_mux_su = 0000000010100001 z_mux_ss = 1111111110100001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110001 y_sgn_s = 1111111111110001 z_sgn_u = 1111111111110001 z_sgn_s = 1111111111110001 y_add_uu = 0000000010110111 y_add_us = 0000000010110111 y_add_su = 0000000010110111 y_add_ss = 1111111110110111 z_add_uu = 0000000010110111 z_add_us = 0000000010110111 z_add_su = 0000000010110111 z_add_ss = 1111111110110111 y_sub_uu = 0000000010011011 y_sub_us = 0000000010011011 y_sub_su = 0000000010011011 y_sub_ss = 1111111110011011 z_sub_uu = 0000000010011011 z_sub_us = 0000000010011011 z_sub_su = 0000000010011011 z_sub_ss = 1111111110011011 y_mul_uu = 0000100100111110 y_mul_us = 0000100100111110 y_mul_su = 0000100100111110 y_mul_ss = 1111101100111110 z_mul_uu = 0000100100111110 z_mul_us = 0000100100111110 z_mul_su = 0000100100111110 z_mul_ss = 1111101100111110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00001011 b = 11101111 c = 001001 y_mux_uu = 0000000000001011 y_mux_us = 0000000000001011 y_mux_su = 0000000000001011 y_mux_ss = 0000000000001011 z_mux_uu = 0000000000001011 z_mux_us = 0000000000001011 z_mux_su = 0000000000001011 z_mux_ss = 0000000000001011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110110 y_sgn_s = 1111111111110110 z_sgn_u = 1111111111110110 z_sgn_s = 1111111111110110 y_add_uu = 0000000000010100 y_add_us = 0000000000010100 y_add_su = 0000000000010100 y_add_ss = 0000000000010100 z_add_uu = 0000000000010100 z_add_us = 0000000000010100 z_add_su = 0000000000010100 z_add_ss = 0000000000010100 y_sub_uu = 0000000000000010 y_sub_us = 0000000000000010 y_sub_su = 0000000000000010 y_sub_ss = 0000000000000010 z_sub_uu = 0000000000000010 z_sub_us = 0000000000000010 z_sub_su = 0000000000000010 z_sub_ss = 0000000000000010 y_mul_uu = 0000000001100011 y_mul_us = 0000000001100011 y_mul_su = 0000000001100011 y_mul_ss = 0000000001100011 z_mul_uu = 0000000001100011 z_mul_us = 0000000001100011 z_mul_su = 0000000001100011 z_mul_ss = 0000000001100011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01110101 b = 10001111 c = 101011 y_mux_uu = 0000000010001111 y_mux_us = 0000000010001111 y_mux_su = 0000000010001111 y_mux_ss = 1111111110001111 z_mux_uu = 0000000010001111 z_mux_us = 0000000010001111 z_mux_su = 0000000010001111 z_mux_ss = 1111111110001111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010100 y_sgn_s = 0000000000010100 z_sgn_u = 1111111111010100 z_sgn_s = 0000000000010100 y_add_uu = 0000000010100000 y_add_us = 0000000010100000 y_add_su = 0000000010100000 y_add_ss = 0000000001100000 z_add_uu = 0000000010100000 z_add_us = 0000000010100000 z_add_su = 0000000010100000 z_add_ss = 0000000001100000 y_sub_uu = 0000000001001010 y_sub_us = 0000000001001010 y_sub_su = 0000000001001010 y_sub_ss = 0000000010001010 z_sub_uu = 0000000001001010 z_sub_us = 0000000001001010 z_sub_su = 0000000001001010 z_sub_ss = 0000000010001010 y_mul_uu = 0001001110100111 y_mul_us = 0001001110100111 y_mul_su = 0001001110100111 y_mul_ss = 1111011001100111 z_mul_uu = 0001001110100111 z_mul_us = 0001001110100111 z_mul_su = 0001001110100111 z_mul_ss = 1111011001100111 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10101110 b = 10011011 c = 010010 y_mux_uu = 0000000010011011 y_mux_us = 0000000010011011 y_mux_su = 0000000010011011 y_mux_ss = 1111111110011011 z_mux_uu = 0000000010011011 z_mux_us = 0000000010011011 z_mux_su = 0000000010011011 z_mux_ss = 1111111110011011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101101 y_sgn_s = 1111111111101101 z_sgn_u = 1111111111101101 z_sgn_s = 1111111111101101 y_add_uu = 0000000011000000 y_add_us = 0000000011000000 y_add_su = 0000000011000000 y_add_ss = 1111111111000000 z_add_uu = 0000000011000000 z_add_us = 0000000011000000 z_add_su = 0000000011000000 z_add_ss = 1111111111000000 y_sub_uu = 0000000010011100 y_sub_us = 0000000010011100 y_sub_su = 0000000010011100 y_sub_ss = 1111111110011100 z_sub_uu = 0000000010011100 z_sub_us = 0000000010011100 z_sub_su = 0000000010011100 z_sub_ss = 1111111110011100 y_mul_uu = 0000110000111100 y_mul_us = 0000110000111100 y_mul_su = 0000110000111100 y_mul_ss = 1111101000111100 z_mul_uu = 0000110000111100 z_mul_us = 0000110000111100 z_mul_su = 0000110000111100 z_mul_ss = 1111101000111100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00101101 b = 01001011 c = 000010 y_mux_uu = 0000000001001011 y_mux_us = 0000000001001011 y_mux_su = 0000000001001011 y_mux_ss = 0000000001001011 z_mux_uu = 0000000001001011 z_mux_us = 0000000001001011 z_mux_su = 0000000001001011 z_mux_ss = 0000000001001011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111101 y_sgn_s = 1111111111111101 z_sgn_u = 1111111111111101 z_sgn_s = 1111111111111101 y_add_uu = 0000000000101111 y_add_us = 0000000000101111 y_add_su = 0000000000101111 y_add_ss = 0000000000101111 z_add_uu = 0000000000101111 z_add_us = 0000000000101111 z_add_su = 0000000000101111 z_add_ss = 0000000000101111 y_sub_uu = 0000000000101011 y_sub_us = 0000000000101011 y_sub_su = 0000000000101011 y_sub_ss = 0000000000101011 z_sub_uu = 0000000000101011 z_sub_us = 0000000000101011 z_sub_su = 0000000000101011 z_sub_ss = 0000000000101011 y_mul_uu = 0000000001011010 y_mul_us = 0000000001011010 y_mul_su = 0000000001011010 y_mul_ss = 0000000001011010 z_mul_uu = 0000000001011010 z_mul_us = 0000000001011010 z_mul_su = 0000000001011010 z_mul_ss = 0000000001011010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00001101 b = 11101100 c = 011000 y_mux_uu = 0000000011101100 y_mux_us = 0000000011101100 y_mux_su = 0000000011101100 y_mux_ss = 1111111111101100 z_mux_uu = 0000000011101100 z_mux_us = 0000000011101100 z_mux_su = 0000000011101100 z_mux_ss = 1111111111101100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100111 y_sgn_s = 1111111111100111 z_sgn_u = 1111111111100111 z_sgn_s = 1111111111100111 y_add_uu = 0000000000100101 y_add_us = 0000000000100101 y_add_su = 0000000000100101 y_add_ss = 0000000000100101 z_add_uu = 0000000000100101 z_add_us = 0000000000100101 z_add_su = 0000000000100101 z_add_ss = 0000000000100101 y_sub_uu = 1111111111110101 y_sub_us = 1111111111110101 y_sub_su = 1111111111110101 y_sub_ss = 1111111111110101 z_sub_uu = 1111111111110101 z_sub_us = 1111111111110101 z_sub_su = 1111111111110101 z_sub_ss = 1111111111110101 y_mul_uu = 0000000100111000 y_mul_us = 0000000100111000 y_mul_su = 0000000100111000 y_mul_ss = 0000000100111000 z_mul_uu = 0000000100111000 z_mul_us = 0000000100111000 z_mul_su = 0000000100111000 z_mul_ss = 0000000100111000 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 1 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 1 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 1 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 1 sel = 1 a = 10000110 b = 01000001 c = 111011 y_mux_uu = 0000000010000110 y_mux_us = 0000000010000110 y_mux_su = 0000000010000110 y_mux_ss = 1111111110000110 z_mux_uu = 0000000010000110 z_mux_us = 0000000010000110 z_mux_su = 0000000010000110 z_mux_ss = 1111111110000110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000100 y_sgn_s = 0000000000000100 z_sgn_u = 1111111111000100 z_sgn_s = 0000000000000100 y_add_uu = 0000000011000001 y_add_us = 0000000011000001 y_add_su = 0000000011000001 y_add_ss = 1111111110000001 z_add_uu = 0000000011000001 z_add_us = 0000000011000001 z_add_su = 0000000011000001 z_add_ss = 1111111110000001 y_sub_uu = 0000000001001011 y_sub_us = 0000000001001011 y_sub_su = 0000000001001011 y_sub_ss = 1111111110001011 z_sub_uu = 0000000001001011 z_sub_us = 0000000001001011 z_sub_su = 0000000001001011 z_sub_ss = 1111111110001011 y_mul_uu = 0001111011100010 y_mul_us = 0001111011100010 y_mul_su = 0001111011100010 y_mul_ss = 0000001001100010 z_mul_uu = 0001111011100010 z_mul_us = 0001111011100010 z_mul_su = 0001111011100010 z_mul_ss = 0000001001100010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 01010011 b = 01010110 c = 011011 y_mux_uu = 0000000001010110 y_mux_us = 0000000001010110 y_mux_su = 0000000001010110 y_mux_ss = 0000000001010110 z_mux_uu = 0000000001010110 z_mux_us = 0000000001010110 z_mux_su = 0000000001010110 z_mux_ss = 0000000001010110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100100 y_sgn_s = 1111111111100100 z_sgn_u = 1111111111100100 z_sgn_s = 1111111111100100 y_add_uu = 0000000001101110 y_add_us = 0000000001101110 y_add_su = 0000000001101110 y_add_ss = 0000000001101110 z_add_uu = 0000000001101110 z_add_us = 0000000001101110 z_add_su = 0000000001101110 z_add_ss = 0000000001101110 y_sub_uu = 0000000000111000 y_sub_us = 0000000000111000 y_sub_su = 0000000000111000 y_sub_ss = 0000000000111000 z_sub_uu = 0000000000111000 z_sub_us = 0000000000111000 z_sub_su = 0000000000111000 z_sub_ss = 0000000000111000 y_mul_uu = 0000100011000001 y_mul_us = 0000100011000001 y_mul_su = 0000100011000001 y_mul_ss = 0000100011000001 z_mul_uu = 0000100011000001 z_mul_us = 0000100011000001 z_mul_su = 0000100011000001 z_mul_ss = 0000100011000001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00000100 b = 01110011 c = 011000 y_mux_uu = 0000000001110011 y_mux_us = 0000000001110011 y_mux_su = 0000000001110011 y_mux_ss = 0000000001110011 z_mux_uu = 0000000001110011 z_mux_us = 0000000001110011 z_mux_su = 0000000001110011 z_mux_ss = 0000000001110011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111100111 y_sgn_s = 1111111111100111 z_sgn_u = 1111111111100111 z_sgn_s = 1111111111100111 y_add_uu = 0000000000011100 y_add_us = 0000000000011100 y_add_su = 0000000000011100 y_add_ss = 0000000000011100 z_add_uu = 0000000000011100 z_add_us = 0000000000011100 z_add_su = 0000000000011100 z_add_ss = 0000000000011100 y_sub_uu = 1111111111101100 y_sub_us = 1111111111101100 y_sub_su = 1111111111101100 y_sub_ss = 1111111111101100 z_sub_uu = 1111111111101100 z_sub_us = 1111111111101100 z_sub_su = 1111111111101100 z_sub_ss = 1111111111101100 y_mul_uu = 0000000001100000 y_mul_us = 0000000001100000 y_mul_su = 0000000001100000 y_mul_ss = 0000000001100000 z_mul_uu = 0000000001100000 z_mul_us = 0000000001100000 z_mul_su = 0000000001100000 z_mul_ss = 0000000001100000 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 1 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 1 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 1 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 1 sel = 0 a = 10111000 b = 00111001 c = 100101 y_mux_uu = 0000000000111001 y_mux_us = 0000000000111001 y_mux_su = 0000000000111001 y_mux_ss = 0000000000111001 z_mux_uu = 0000000000111001 z_mux_us = 0000000000111001 z_mux_su = 0000000000111001 z_mux_ss = 0000000000111001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011010 y_sgn_s = 0000000000011010 z_sgn_u = 1111111111011010 z_sgn_s = 0000000000011010 y_add_uu = 0000000011011101 y_add_us = 0000000011011101 y_add_su = 0000000011011101 y_add_ss = 1111111110011101 z_add_uu = 0000000011011101 z_add_us = 0000000011011101 z_add_su = 0000000011011101 z_add_ss = 1111111110011101 y_sub_uu = 0000000010010011 y_sub_us = 0000000010010011 y_sub_su = 0000000010010011 y_sub_ss = 1111111111010011 z_sub_uu = 0000000010010011 z_sub_us = 0000000010010011 z_sub_su = 0000000010010011 z_sub_ss = 1111111111010011 y_mul_uu = 0001101010011000 y_mul_us = 0001101010011000 y_mul_su = 0001101010011000 y_mul_ss = 0000011110011000 z_mul_uu = 0001101010011000 z_mul_us = 0001101010011000 z_mul_su = 0001101010011000 z_mul_ss = 0000011110011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00101011 b = 10000001 c = 001000 y_mux_uu = 0000000000101011 y_mux_us = 0000000000101011 y_mux_su = 0000000000101011 y_mux_ss = 0000000000101011 z_mux_uu = 0000000000101011 z_mux_us = 0000000000101011 z_mux_su = 0000000000101011 z_mux_ss = 0000000000101011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110111 y_sgn_s = 1111111111110111 z_sgn_u = 1111111111110111 z_sgn_s = 1111111111110111 y_add_uu = 0000000000110011 y_add_us = 0000000000110011 y_add_su = 0000000000110011 y_add_ss = 0000000000110011 z_add_uu = 0000000000110011 z_add_us = 0000000000110011 z_add_su = 0000000000110011 z_add_ss = 0000000000110011 y_sub_uu = 0000000000100011 y_sub_us = 0000000000100011 y_sub_su = 0000000000100011 y_sub_ss = 0000000000100011 z_sub_uu = 0000000000100011 z_sub_us = 0000000000100011 z_sub_su = 0000000000100011 z_sub_ss = 0000000000100011 y_mul_uu = 0000000101011000 y_mul_us = 0000000101011000 y_mul_su = 0000000101011000 y_mul_ss = 0000000101011000 z_mul_uu = 0000000101011000 z_mul_us = 0000000101011000 z_mul_su = 0000000101011000 z_mul_ss = 0000000101011000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 10100001 b = 00011111 c = 000100 y_mux_uu = 0000000010100001 y_mux_us = 0000000010100001 y_mux_su = 0000000010100001 y_mux_ss = 1111111110100001 z_mux_uu = 0000000010100001 z_mux_us = 0000000010100001 z_mux_su = 0000000010100001 z_mux_ss = 1111111110100001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111011 y_sgn_s = 1111111111111011 z_sgn_u = 1111111111111011 z_sgn_s = 1111111111111011 y_add_uu = 0000000010100101 y_add_us = 0000000010100101 y_add_su = 0000000010100101 y_add_ss = 1111111110100101 z_add_uu = 0000000010100101 z_add_us = 0000000010100101 z_add_su = 0000000010100101 z_add_ss = 1111111110100101 y_sub_uu = 0000000010011101 y_sub_us = 0000000010011101 y_sub_su = 0000000010011101 y_sub_ss = 1111111110011101 z_sub_uu = 0000000010011101 z_sub_us = 0000000010011101 z_sub_su = 0000000010011101 z_sub_ss = 1111111110011101 y_mul_uu = 0000001010000100 y_mul_us = 0000001010000100 y_mul_su = 0000001010000100 y_mul_ss = 1111111010000100 z_mul_uu = 0000001010000100 z_mul_us = 0000001010000100 z_mul_su = 0000001010000100 z_mul_ss = 1111111010000100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10010110 b = 00010100 c = 010010 y_mux_uu = 0000000000010100 y_mux_us = 0000000000010100 y_mux_su = 0000000000010100 y_mux_ss = 0000000000010100 z_mux_uu = 0000000000010100 z_mux_us = 0000000000010100 z_mux_su = 0000000000010100 z_mux_ss = 0000000000010100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101101 y_sgn_s = 1111111111101101 z_sgn_u = 1111111111101101 z_sgn_s = 1111111111101101 y_add_uu = 0000000010101000 y_add_us = 0000000010101000 y_add_su = 0000000010101000 y_add_ss = 1111111110101000 z_add_uu = 0000000010101000 z_add_us = 0000000010101000 z_add_su = 0000000010101000 z_add_ss = 1111111110101000 y_sub_uu = 0000000010000100 y_sub_us = 0000000010000100 y_sub_su = 0000000010000100 y_sub_ss = 1111111110000100 z_sub_uu = 0000000010000100 z_sub_us = 0000000010000100 z_sub_su = 0000000010000100 z_sub_ss = 1111111110000100 y_mul_uu = 0000101010001100 y_mul_us = 0000101010001100 y_mul_su = 0000101010001100 y_mul_ss = 1111100010001100 z_mul_uu = 0000101010001100 z_mul_us = 0000101010001100 z_mul_su = 0000101010001100 z_mul_ss = 1111100010001100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10110001 b = 01010101 c = 101101 y_mux_uu = 0000000001010101 y_mux_us = 0000000001010101 y_mux_su = 0000000001010101 y_mux_ss = 0000000001010101 z_mux_uu = 0000000001010101 z_mux_us = 0000000001010101 z_mux_su = 0000000001010101 z_mux_ss = 0000000001010101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010010 y_sgn_s = 0000000000010010 z_sgn_u = 1111111111010010 z_sgn_s = 0000000000010010 y_add_uu = 0000000011011110 y_add_us = 0000000011011110 y_add_su = 0000000011011110 y_add_ss = 1111111110011110 z_add_uu = 0000000011011110 z_add_us = 0000000011011110 z_add_su = 0000000011011110 z_add_ss = 1111111110011110 y_sub_uu = 0000000010000100 y_sub_us = 0000000010000100 y_sub_su = 0000000010000100 y_sub_ss = 1111111111000100 z_sub_uu = 0000000010000100 z_sub_us = 0000000010000100 z_sub_su = 0000000010000100 z_sub_ss = 1111111111000100 y_mul_uu = 0001111100011101 y_mul_us = 0001111100011101 y_mul_su = 0001111100011101 y_mul_ss = 0000010111011101 z_mul_uu = 0001111100011101 z_mul_us = 0001111100011101 z_mul_su = 0001111100011101 z_mul_ss = 0000010111011101 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11110101 b = 10101101 c = 100111 y_mux_uu = 0000000011110101 y_mux_us = 0000000011110101 y_mux_su = 0000000011110101 y_mux_ss = 1111111111110101 z_mux_uu = 0000000011110101 z_mux_us = 0000000011110101 z_mux_su = 0000000011110101 z_mux_ss = 1111111111110101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011000 y_sgn_s = 0000000000011000 z_sgn_u = 1111111111011000 z_sgn_s = 0000000000011000 y_add_uu = 0000000100011100 y_add_us = 0000000100011100 y_add_su = 0000000100011100 y_add_ss = 1111111111011100 z_add_uu = 0000000100011100 z_add_us = 0000000100011100 z_add_su = 0000000100011100 z_add_ss = 1111111111011100 y_sub_uu = 0000000011001110 y_sub_us = 0000000011001110 y_sub_su = 0000000011001110 y_sub_ss = 0000000000001110 z_sub_uu = 0000000011001110 z_sub_us = 0000000011001110 z_sub_su = 0000000011001110 z_sub_ss = 0000000000001110 y_mul_uu = 0010010101010011 y_mul_us = 0010010101010011 y_mul_su = 0010010101010011 y_mul_ss = 0000000100010011 z_mul_uu = 0010010101010011 z_mul_us = 0010010101010011 z_mul_su = 0010010101010011 z_mul_ss = 0000000100010011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 10100111 b = 11100111 c = 111001 y_mux_uu = 0000000011100111 y_mux_us = 0000000011100111 y_mux_su = 0000000011100111 y_mux_ss = 1111111111100111 z_mux_uu = 0000000011100111 z_mux_us = 0000000011100111 z_mux_su = 0000000011100111 z_mux_ss = 1111111111100111 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000110 y_sgn_s = 0000000000000110 z_sgn_u = 1111111111000110 z_sgn_s = 0000000000000110 y_add_uu = 0000000011100000 y_add_us = 0000000011100000 y_add_su = 0000000011100000 y_add_ss = 1111111110100000 z_add_uu = 0000000011100000 z_add_us = 0000000011100000 z_add_su = 0000000011100000 z_add_ss = 1111111110100000 y_sub_uu = 0000000001101110 y_sub_us = 0000000001101110 y_sub_su = 0000000001101110 y_sub_ss = 1111111110101110 z_sub_uu = 0000000001101110 z_sub_us = 0000000001101110 z_sub_su = 0000000001101110 z_sub_ss = 1111111110101110 y_mul_uu = 0010010100101111 y_mul_us = 0010010100101111 y_mul_su = 0010010100101111 y_mul_ss = 0000001001101111 z_mul_uu = 0010010100101111 z_mul_us = 0010010100101111 z_mul_su = 0010010100101111 z_mul_ss = 0000001001101111 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11011011 b = 11001001 c = 010001 y_mux_uu = 0000000011011011 y_mux_us = 0000000011011011 y_mux_su = 0000000011011011 y_mux_ss = 1111111111011011 z_mux_uu = 0000000011011011 z_mux_us = 0000000011011011 z_mux_su = 0000000011011011 z_mux_ss = 1111111111011011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101110 y_sgn_s = 1111111111101110 z_sgn_u = 1111111111101110 z_sgn_s = 1111111111101110 y_add_uu = 0000000011101100 y_add_us = 0000000011101100 y_add_su = 0000000011101100 y_add_ss = 1111111111101100 z_add_uu = 0000000011101100 z_add_us = 0000000011101100 z_add_su = 0000000011101100 z_add_ss = 1111111111101100 y_sub_uu = 0000000011001010 y_sub_us = 0000000011001010 y_sub_su = 0000000011001010 y_sub_ss = 1111111111001010 z_sub_uu = 0000000011001010 z_sub_us = 0000000011001010 z_sub_su = 0000000011001010 z_sub_ss = 1111111111001010 y_mul_uu = 0000111010001011 y_mul_us = 0000111010001011 y_mul_su = 0000111010001011 y_mul_ss = 1111110110001011 z_mul_uu = 0000111010001011 z_mul_us = 0000111010001011 z_mul_su = 0000111010001011 z_mul_ss = 1111110110001011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00101010 b = 11111010 c = 000101 y_mux_uu = 0000000000101010 y_mux_us = 0000000000101010 y_mux_su = 0000000000101010 y_mux_ss = 0000000000101010 z_mux_uu = 0000000000101010 z_mux_us = 0000000000101010 z_mux_su = 0000000000101010 z_mux_ss = 0000000000101010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111010 y_sgn_s = 1111111111111010 z_sgn_u = 1111111111111010 z_sgn_s = 1111111111111010 y_add_uu = 0000000000101111 y_add_us = 0000000000101111 y_add_su = 0000000000101111 y_add_ss = 0000000000101111 z_add_uu = 0000000000101111 z_add_us = 0000000000101111 z_add_su = 0000000000101111 z_add_ss = 0000000000101111 y_sub_uu = 0000000000100101 y_sub_us = 0000000000100101 y_sub_su = 0000000000100101 y_sub_ss = 0000000000100101 z_sub_uu = 0000000000100101 z_sub_us = 0000000000100101 z_sub_su = 0000000000100101 z_sub_ss = 0000000000100101 y_mul_uu = 0000000011010010 y_mul_us = 0000000011010010 y_mul_su = 0000000011010010 y_mul_ss = 0000000011010010 z_mul_uu = 0000000011010010 z_mul_us = 0000000011010010 z_mul_su = 0000000011010010 z_mul_ss = 0000000011010010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 01111100 b = 01110010 c = 111110 y_mux_uu = 0000000001111100 y_mux_us = 0000000001111100 y_mux_su = 0000000001111100 y_mux_ss = 0000000001111100 z_mux_uu = 0000000001111100 z_mux_us = 0000000001111100 z_mux_su = 0000000001111100 z_mux_ss = 0000000001111100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000001 y_sgn_s = 0000000000000001 z_sgn_u = 1111111111000001 z_sgn_s = 0000000000000001 y_add_uu = 0000000010111010 y_add_us = 0000000010111010 y_add_su = 0000000010111010 y_add_ss = 0000000001111010 z_add_uu = 0000000010111010 z_add_us = 0000000010111010 z_add_su = 0000000010111010 z_add_ss = 0000000001111010 y_sub_uu = 0000000000111110 y_sub_us = 0000000000111110 y_sub_su = 0000000000111110 y_sub_ss = 0000000001111110 z_sub_uu = 0000000000111110 z_sub_us = 0000000000111110 z_sub_su = 0000000000111110 z_sub_ss = 0000000001111110 y_mul_uu = 0001111000001000 y_mul_us = 0001111000001000 y_mul_su = 0001111000001000 y_mul_ss = 1111111100001000 z_mul_uu = 0001111000001000 z_mul_us = 0001111000001000 z_mul_su = 0001111000001000 z_mul_ss = 1111111100001000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01101111 b = 10000110 c = 110000 y_mux_uu = 0000000010000110 y_mux_us = 0000000010000110 y_mux_su = 0000000010000110 y_mux_ss = 1111111110000110 z_mux_uu = 0000000010000110 z_mux_us = 0000000010000110 z_mux_su = 0000000010000110 z_mux_ss = 1111111110000110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001111 y_sgn_s = 0000000000001111 z_sgn_u = 1111111111001111 z_sgn_s = 0000000000001111 y_add_uu = 0000000010011111 y_add_us = 0000000010011111 y_add_su = 0000000010011111 y_add_ss = 0000000001011111 z_add_uu = 0000000010011111 z_add_us = 0000000010011111 z_add_su = 0000000010011111 z_add_ss = 0000000001011111 y_sub_uu = 0000000000111111 y_sub_us = 0000000000111111 y_sub_su = 0000000000111111 y_sub_ss = 0000000001111111 z_sub_uu = 0000000000111111 z_sub_us = 0000000000111111 z_sub_su = 0000000000111111 z_sub_ss = 0000000001111111 y_mul_uu = 0001010011010000 y_mul_us = 0001010011010000 y_mul_su = 0001010011010000 y_mul_ss = 1111100100010000 z_mul_uu = 0001010011010000 z_mul_us = 0001010011010000 z_mul_su = 0001010011010000 z_mul_ss = 1111100100010000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01000000 b = 00101000 c = 110110 y_mux_uu = 0000000000101000 y_mux_us = 0000000000101000 y_mux_su = 0000000000101000 y_mux_ss = 0000000000101000 z_mux_uu = 0000000000101000 z_mux_us = 0000000000101000 z_mux_su = 0000000000101000 z_mux_ss = 0000000000101000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001001 y_sgn_s = 0000000000001001 z_sgn_u = 1111111111001001 z_sgn_s = 0000000000001001 y_add_uu = 0000000001110110 y_add_us = 0000000001110110 y_add_su = 0000000001110110 y_add_ss = 0000000000110110 z_add_uu = 0000000001110110 z_add_us = 0000000001110110 z_add_su = 0000000001110110 z_add_ss = 0000000000110110 y_sub_uu = 0000000000001010 y_sub_us = 0000000000001010 y_sub_su = 0000000000001010 y_sub_ss = 0000000001001010 z_sub_uu = 0000000000001010 z_sub_us = 0000000000001010 z_sub_su = 0000000000001010 z_sub_ss = 0000000001001010 y_mul_uu = 0000110110000000 y_mul_us = 0000110110000000 y_mul_su = 0000110110000000 y_mul_ss = 1111110110000000 z_mul_uu = 0000110110000000 z_mul_us = 0000110110000000 z_mul_su = 0000110110000000 z_mul_ss = 1111110110000000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11000000 b = 01110100 c = 111001 y_mux_uu = 0000000011000000 y_mux_us = 0000000011000000 y_mux_su = 0000000011000000 y_mux_ss = 1111111111000000 z_mux_uu = 0000000011000000 z_mux_us = 0000000011000000 z_mux_su = 0000000011000000 z_mux_ss = 1111111111000000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000110 y_sgn_s = 0000000000000110 z_sgn_u = 1111111111000110 z_sgn_s = 0000000000000110 y_add_uu = 0000000011111001 y_add_us = 0000000011111001 y_add_su = 0000000011111001 y_add_ss = 1111111110111001 z_add_uu = 0000000011111001 z_add_us = 0000000011111001 z_add_su = 0000000011111001 z_add_ss = 1111111110111001 y_sub_uu = 0000000010000111 y_sub_us = 0000000010000111 y_sub_su = 0000000010000111 y_sub_ss = 1111111111000111 z_sub_uu = 0000000010000111 z_sub_us = 0000000010000111 z_sub_su = 0000000010000111 z_sub_ss = 1111111111000111 y_mul_uu = 0010101011000000 y_mul_us = 0010101011000000 y_mul_su = 0010101011000000 y_mul_ss = 0000000111000000 z_mul_uu = 0010101011000000 z_mul_us = 0010101011000000 z_mul_su = 0010101011000000 z_mul_ss = 0000000111000000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 00111100 b = 00101010 c = 100010 y_mux_uu = 0000000000101010 y_mux_us = 0000000000101010 y_mux_su = 0000000000101010 y_mux_ss = 0000000000101010 z_mux_uu = 0000000000101010 z_mux_us = 0000000000101010 z_mux_su = 0000000000101010 z_mux_ss = 0000000000101010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011101 y_sgn_s = 0000000000011101 z_sgn_u = 1111111111011101 z_sgn_s = 0000000000011101 y_add_uu = 0000000001011110 y_add_us = 0000000001011110 y_add_su = 0000000001011110 y_add_ss = 0000000000011110 z_add_uu = 0000000001011110 z_add_us = 0000000001011110 z_add_su = 0000000001011110 z_add_ss = 0000000000011110 y_sub_uu = 0000000000011010 y_sub_us = 0000000000011010 y_sub_su = 0000000000011010 y_sub_ss = 0000000001011010 z_sub_uu = 0000000000011010 z_sub_us = 0000000000011010 z_sub_su = 0000000000011010 z_sub_ss = 0000000001011010 y_mul_uu = 0000011111111000 y_mul_us = 0000011111111000 y_mul_su = 0000011111111000 y_mul_ss = 1111100011111000 z_mul_uu = 0000011111111000 z_mul_us = 0000011111111000 z_mul_su = 0000011111111000 z_mul_ss = 1111100011111000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 11100001 b = 00010111 c = 000011 y_mux_uu = 0000000011100001 y_mux_us = 0000000011100001 y_mux_su = 0000000011100001 y_mux_ss = 1111111111100001 z_mux_uu = 0000000011100001 z_mux_us = 0000000011100001 z_mux_su = 0000000011100001 z_mux_ss = 1111111111100001 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111100 y_sgn_s = 1111111111111100 z_sgn_u = 1111111111111100 z_sgn_s = 1111111111111100 y_add_uu = 0000000011100100 y_add_us = 0000000011100100 y_add_su = 0000000011100100 y_add_ss = 1111111111100100 z_add_uu = 0000000011100100 z_add_us = 0000000011100100 z_add_su = 0000000011100100 z_add_ss = 1111111111100100 y_sub_uu = 0000000011011110 y_sub_us = 0000000011011110 y_sub_su = 0000000011011110 y_sub_ss = 1111111111011110 z_sub_uu = 0000000011011110 z_sub_us = 0000000011011110 z_sub_su = 0000000011011110 z_sub_ss = 1111111111011110 y_mul_uu = 0000001010100011 y_mul_us = 0000001010100011 y_mul_su = 0000001010100011 y_mul_ss = 1111111110100011 z_mul_uu = 0000001010100011 z_mul_us = 0000001010100011 z_mul_su = 0000001010100011 z_mul_ss = 1111111110100011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 10000110 b = 00100101 c = 000001 y_mux_uu = 0000000010000110 y_mux_us = 0000000010000110 y_mux_su = 0000000010000110 y_mux_ss = 1111111110000110 z_mux_uu = 0000000010000110 z_mux_us = 0000000010000110 z_mux_su = 0000000010000110 z_mux_ss = 1111111110000110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111111110 y_sgn_s = 1111111111111110 z_sgn_u = 1111111111111110 z_sgn_s = 1111111111111110 y_add_uu = 0000000010000111 y_add_us = 0000000010000111 y_add_su = 0000000010000111 y_add_ss = 1111111110000111 z_add_uu = 0000000010000111 z_add_us = 0000000010000111 z_add_su = 0000000010000111 z_add_ss = 1111111110000111 y_sub_uu = 0000000010000101 y_sub_us = 0000000010000101 y_sub_su = 0000000010000101 y_sub_ss = 1111111110000101 z_sub_uu = 0000000010000101 z_sub_us = 0000000010000101 z_sub_su = 0000000010000101 z_sub_ss = 1111111110000101 y_mul_uu = 0000000010000110 y_mul_us = 0000000010000110 y_mul_su = 0000000010000110 y_mul_ss = 1111111110000110 z_mul_uu = 0000000010000110 z_mul_us = 0000000010000110 z_mul_su = 0000000010000110 z_mul_ss = 1111111110000110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 01011010 b = 00000111 c = 101100 y_mux_uu = 0000000001011010 y_mux_us = 0000000001011010 y_mux_su = 0000000001011010 y_mux_ss = 0000000001011010 z_mux_uu = 0000000001011010 z_mux_us = 0000000001011010 z_mux_su = 0000000001011010 z_mux_ss = 0000000001011010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010011 y_sgn_s = 0000000000010011 z_sgn_u = 1111111111010011 z_sgn_s = 0000000000010011 y_add_uu = 0000000010000110 y_add_us = 0000000010000110 y_add_su = 0000000010000110 y_add_ss = 0000000001000110 z_add_uu = 0000000010000110 z_add_us = 0000000010000110 z_add_su = 0000000010000110 z_add_ss = 0000000001000110 y_sub_uu = 0000000000101110 y_sub_us = 0000000000101110 y_sub_su = 0000000000101110 y_sub_ss = 0000000001101110 z_sub_uu = 0000000000101110 z_sub_us = 0000000000101110 z_sub_su = 0000000000101110 z_sub_ss = 0000000001101110 y_mul_uu = 0000111101111000 y_mul_us = 0000111101111000 y_mul_su = 0000111101111000 y_mul_ss = 1111100011111000 z_mul_uu = 0000111101111000 z_mul_us = 0000111101111000 z_mul_su = 0000111101111000 z_mul_ss = 1111100011111000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01110001 b = 00111011 c = 110110 y_mux_uu = 0000000000111011 y_mux_us = 0000000000111011 y_mux_su = 0000000000111011 y_mux_ss = 0000000000111011 z_mux_uu = 0000000000111011 z_mux_us = 0000000000111011 z_mux_su = 0000000000111011 z_mux_ss = 0000000000111011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001001 y_sgn_s = 0000000000001001 z_sgn_u = 1111111111001001 z_sgn_s = 0000000000001001 y_add_uu = 0000000010100111 y_add_us = 0000000010100111 y_add_su = 0000000010100111 y_add_ss = 0000000001100111 z_add_uu = 0000000010100111 z_add_us = 0000000010100111 z_add_su = 0000000010100111 z_add_ss = 0000000001100111 y_sub_uu = 0000000000111011 y_sub_us = 0000000000111011 y_sub_su = 0000000000111011 y_sub_ss = 0000000001111011 z_sub_uu = 0000000000111011 z_sub_us = 0000000000111011 z_sub_su = 0000000000111011 z_sub_ss = 0000000001111011 y_mul_uu = 0001011111010110 y_mul_us = 0001011111010110 y_mul_su = 0001011111010110 y_mul_ss = 1111101110010110 z_mul_uu = 0001011111010110 z_mul_us = 0001011111010110 z_mul_su = 0001011111010110 z_mul_ss = 1111101110010110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 10011110 b = 01011100 c = 010101 y_mux_uu = 0000000010011110 y_mux_us = 0000000010011110 y_mux_su = 0000000010011110 y_mux_ss = 1111111110011110 z_mux_uu = 0000000010011110 z_mux_us = 0000000010011110 z_mux_su = 0000000010011110 z_mux_ss = 1111111110011110 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101010 y_sgn_s = 1111111111101010 z_sgn_u = 1111111111101010 z_sgn_s = 1111111111101010 y_add_uu = 0000000010110011 y_add_us = 0000000010110011 y_add_su = 0000000010110011 y_add_ss = 1111111110110011 z_add_uu = 0000000010110011 z_add_us = 0000000010110011 z_add_su = 0000000010110011 z_add_ss = 1111111110110011 y_sub_uu = 0000000010001001 y_sub_us = 0000000010001001 y_sub_su = 0000000010001001 y_sub_ss = 1111111110001001 z_sub_uu = 0000000010001001 z_sub_us = 0000000010001001 z_sub_su = 0000000010001001 z_sub_ss = 1111111110001001 y_mul_uu = 0000110011110110 y_mul_us = 0000110011110110 y_mul_su = 0000110011110110 y_mul_ss = 1111011111110110 z_mul_uu = 0000110011110110 z_mul_us = 0000110011110110 z_mul_su = 0000110011110110 z_mul_ss = 1111011111110110 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10100000 b = 01110010 c = 110100 y_mux_uu = 0000000001110010 y_mux_us = 0000000001110010 y_mux_su = 0000000001110010 y_mux_ss = 0000000001110010 z_mux_uu = 0000000001110010 z_mux_us = 0000000001110010 z_mux_su = 0000000001110010 z_mux_ss = 0000000001110010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001011 y_sgn_s = 0000000000001011 z_sgn_u = 1111111111001011 z_sgn_s = 0000000000001011 y_add_uu = 0000000011010100 y_add_us = 0000000011010100 y_add_su = 0000000011010100 y_add_ss = 1111111110010100 z_add_uu = 0000000011010100 z_add_us = 0000000011010100 z_add_su = 0000000011010100 z_add_ss = 1111111110010100 y_sub_uu = 0000000001101100 y_sub_us = 0000000001101100 y_sub_su = 0000000001101100 y_sub_ss = 1111111110101100 z_sub_uu = 0000000001101100 z_sub_us = 0000000001101100 z_sub_su = 0000000001101100 z_sub_ss = 1111111110101100 y_mul_uu = 0010000010000000 y_mul_us = 0010000010000000 y_mul_su = 0010000010000000 y_mul_ss = 0000010010000000 z_mul_uu = 0010000010000000 z_mul_us = 0010000010000000 z_mul_su = 0010000010000000 z_mul_ss = 0000010010000000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 00001101 b = 01001011 c = 111001 y_mux_uu = 0000000000001101 y_mux_us = 0000000000001101 y_mux_su = 0000000000001101 y_mux_ss = 0000000000001101 z_mux_uu = 0000000000001101 z_mux_us = 0000000000001101 z_mux_su = 0000000000001101 z_mux_ss = 0000000000001101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111000110 y_sgn_s = 0000000000000110 z_sgn_u = 1111111111000110 z_sgn_s = 0000000000000110 y_add_uu = 0000000001000110 y_add_us = 0000000001000110 y_add_su = 0000000001000110 y_add_ss = 0000000000000110 z_add_uu = 0000000001000110 z_add_us = 0000000001000110 z_add_su = 0000000001000110 z_add_ss = 0000000000000110 y_sub_uu = 1111111111010100 y_sub_us = 1111111111010100 y_sub_su = 1111111111010100 y_sub_ss = 0000000000010100 z_sub_uu = 1111111111010100 z_sub_us = 1111111111010100 z_sub_su = 1111111111010100 z_sub_ss = 0000000000010100 y_mul_uu = 0000001011100101 y_mul_us = 0000001011100101 y_mul_su = 0000001011100101 y_mul_ss = 1111111110100101 z_mul_uu = 0000001011100101 z_mul_us = 0000001011100101 z_mul_su = 0000001011100101 z_mul_ss = 1111111110100101 y_ltn_uu = 1 y_ltn_us = 1 y_ltn_su = 1 y_ltn_ss = 0 z_ltn_uu = 1 z_ltn_us = 1 z_ltn_su = 1 z_ltn_ss = 0 y_leq_uu = 1 y_leq_us = 1 y_leq_su = 1 y_leq_ss = 0 z_leq_uu = 1 z_leq_us = 1 z_leq_su = 1 z_leq_ss = 0 sel = 0 a = 11111101 b = 01111011 c = 001111 y_mux_uu = 0000000001111011 y_mux_us = 0000000001111011 y_mux_su = 0000000001111011 y_mux_ss = 0000000001111011 z_mux_uu = 0000000001111011 z_mux_us = 0000000001111011 z_mux_su = 0000000001111011 z_mux_ss = 0000000001111011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110000 y_sgn_s = 1111111111110000 z_sgn_u = 1111111111110000 z_sgn_s = 1111111111110000 y_add_uu = 0000000100001100 y_add_us = 0000000100001100 y_add_su = 0000000100001100 y_add_ss = 0000000000001100 z_add_uu = 0000000100001100 z_add_us = 0000000100001100 z_add_su = 0000000100001100 z_add_ss = 0000000000001100 y_sub_uu = 0000000011101110 y_sub_us = 0000000011101110 y_sub_su = 0000000011101110 y_sub_ss = 1111111111101110 z_sub_uu = 0000000011101110 z_sub_us = 0000000011101110 z_sub_su = 0000000011101110 z_sub_ss = 1111111111101110 y_mul_uu = 0000111011010011 y_mul_us = 0000111011010011 y_mul_su = 0000111011010011 y_mul_ss = 1111111111010011 z_mul_uu = 0000111011010011 z_mul_us = 0000111011010011 z_mul_su = 0000111011010011 z_mul_ss = 1111111111010011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 1 a = 11100011 b = 00011101 c = 110001 y_mux_uu = 0000000011100011 y_mux_us = 0000000011100011 y_mux_su = 0000000011100011 y_mux_ss = 1111111111100011 z_mux_uu = 0000000011100011 z_mux_us = 0000000011100011 z_mux_su = 0000000011100011 z_mux_ss = 1111111111100011 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111001110 y_sgn_s = 0000000000001110 z_sgn_u = 1111111111001110 z_sgn_s = 0000000000001110 y_add_uu = 0000000100010100 y_add_us = 0000000100010100 y_add_su = 0000000100010100 y_add_ss = 1111111111010100 z_add_uu = 0000000100010100 z_add_us = 0000000100010100 z_add_su = 0000000100010100 z_add_ss = 1111111111010100 y_sub_uu = 0000000010110010 y_sub_us = 0000000010110010 y_sub_su = 0000000010110010 y_sub_ss = 1111111111110010 z_sub_uu = 0000000010110010 z_sub_us = 0000000010110010 z_sub_su = 0000000010110010 z_sub_ss = 1111111111110010 y_mul_uu = 0010101101110011 y_mul_us = 0010101101110011 y_mul_su = 0010101101110011 y_mul_ss = 0000000110110011 z_mul_uu = 0010101101110011 z_mul_us = 0010101101110011 z_mul_su = 0010101101110011 z_mul_ss = 0000000110110011 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 10010101 b = 11100000 c = 101101 y_mux_uu = 0000000011100000 y_mux_us = 0000000011100000 y_mux_su = 0000000011100000 y_mux_ss = 1111111111100000 z_mux_uu = 0000000011100000 z_mux_us = 0000000011100000 z_mux_su = 0000000011100000 z_mux_ss = 1111111111100000 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010010 y_sgn_s = 0000000000010010 z_sgn_u = 1111111111010010 z_sgn_s = 0000000000010010 y_add_uu = 0000000011000010 y_add_us = 0000000011000010 y_add_su = 0000000011000010 y_add_ss = 1111111110000010 z_add_uu = 0000000011000010 z_add_us = 0000000011000010 z_add_su = 0000000011000010 z_add_ss = 1111111110000010 y_sub_uu = 0000000001101000 y_sub_us = 0000000001101000 y_sub_su = 0000000001101000 y_sub_ss = 1111111110101000 z_sub_uu = 0000000001101000 z_sub_us = 0000000001101000 z_sub_su = 0000000001101000 z_sub_ss = 1111111110101000 y_mul_uu = 0001101000110001 y_mul_us = 0001101000110001 y_mul_su = 0001101000110001 y_mul_ss = 0000011111110001 z_mul_uu = 0001101000110001 z_mul_us = 0001101000110001 z_mul_su = 0001101000110001 z_mul_ss = 0000011111110001 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 11111000 b = 10001101 c = 010010 y_mux_uu = 0000000010001101 y_mux_us = 0000000010001101 y_mux_su = 0000000010001101 y_mux_ss = 1111111110001101 z_mux_uu = 0000000010001101 z_mux_us = 0000000010001101 z_mux_su = 0000000010001101 z_mux_ss = 1111111110001101 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101101 y_sgn_s = 1111111111101101 z_sgn_u = 1111111111101101 z_sgn_s = 1111111111101101 y_add_uu = 0000000100001010 y_add_us = 0000000100001010 y_add_su = 0000000100001010 y_add_ss = 0000000000001010 z_add_uu = 0000000100001010 z_add_us = 0000000100001010 z_add_su = 0000000100001010 z_add_ss = 0000000000001010 y_sub_uu = 0000000011100110 y_sub_us = 0000000011100110 y_sub_su = 0000000011100110 y_sub_ss = 1111111111100110 z_sub_uu = 0000000011100110 z_sub_us = 0000000011100110 z_sub_su = 0000000011100110 z_sub_ss = 1111111111100110 y_mul_uu = 0001000101110000 y_mul_us = 0001000101110000 y_mul_su = 0001000101110000 y_mul_ss = 1111111101110000 z_mul_uu = 0001000101110000 z_mul_us = 0001000101110000 z_mul_su = 0001000101110000 z_mul_ss = 1111111101110000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 1 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 1 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 1 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 1 sel = 0 a = 01000110 b = 10001100 c = 010000 y_mux_uu = 0000000010001100 y_mux_us = 0000000010001100 y_mux_su = 0000000010001100 y_mux_ss = 1111111110001100 z_mux_uu = 0000000010001100 z_mux_us = 0000000010001100 z_mux_su = 0000000010001100 z_mux_ss = 1111111110001100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111101111 y_sgn_s = 1111111111101111 z_sgn_u = 1111111111101111 z_sgn_s = 1111111111101111 y_add_uu = 0000000001010110 y_add_us = 0000000001010110 y_add_su = 0000000001010110 y_add_ss = 0000000001010110 z_add_uu = 0000000001010110 z_add_us = 0000000001010110 z_add_su = 0000000001010110 z_add_ss = 0000000001010110 y_sub_uu = 0000000000110110 y_sub_us = 0000000000110110 y_sub_su = 0000000000110110 y_sub_ss = 0000000000110110 z_sub_uu = 0000000000110110 z_sub_us = 0000000000110110 z_sub_su = 0000000000110110 z_sub_ss = 0000000000110110 y_mul_uu = 0000010001100000 y_mul_us = 0000010001100000 y_mul_su = 0000010001100000 y_mul_ss = 0000010001100000 z_mul_uu = 0000010001100000 z_mul_us = 0000010001100000 z_mul_su = 0000010001100000 z_mul_ss = 0000010001100000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 01101010 b = 10000100 c = 101010 y_mux_uu = 0000000001101010 y_mux_us = 0000000001101010 y_mux_su = 0000000001101010 y_mux_ss = 0000000001101010 z_mux_uu = 0000000001101010 z_mux_us = 0000000001101010 z_mux_su = 0000000001101010 z_mux_ss = 0000000001101010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111010101 y_sgn_s = 0000000000010101 z_sgn_u = 1111111111010101 z_sgn_s = 0000000000010101 y_add_uu = 0000000010010100 y_add_us = 0000000010010100 y_add_su = 0000000010010100 y_add_ss = 0000000001010100 z_add_uu = 0000000010010100 z_add_us = 0000000010010100 z_add_su = 0000000010010100 z_add_ss = 0000000001010100 y_sub_uu = 0000000001000000 y_sub_us = 0000000001000000 y_sub_su = 0000000001000000 y_sub_ss = 0000000010000000 z_sub_uu = 0000000001000000 z_sub_us = 0000000001000000 z_sub_su = 0000000001000000 z_sub_ss = 0000000010000000 y_mul_uu = 0001000101100100 y_mul_us = 0001000101100100 y_mul_su = 0001000101100100 y_mul_ss = 1111011011100100 z_mul_uu = 0001000101100100 z_mul_us = 0001000101100100 z_mul_su = 0001000101100100 z_mul_ss = 1111011011100100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 01100000 b = 10111010 c = 001011 y_mux_uu = 0000000010111010 y_mux_us = 0000000010111010 y_mux_su = 0000000010111010 y_mux_ss = 1111111110111010 z_mux_uu = 0000000010111010 z_mux_us = 0000000010111010 z_mux_su = 0000000010111010 z_mux_ss = 1111111110111010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110100 y_sgn_s = 1111111111110100 z_sgn_u = 1111111111110100 z_sgn_s = 1111111111110100 y_add_uu = 0000000001101011 y_add_us = 0000000001101011 y_add_su = 0000000001101011 y_add_ss = 0000000001101011 z_add_uu = 0000000001101011 z_add_us = 0000000001101011 z_add_su = 0000000001101011 z_add_ss = 0000000001101011 y_sub_uu = 0000000001010101 y_sub_us = 0000000001010101 y_sub_su = 0000000001010101 y_sub_ss = 0000000001010101 z_sub_uu = 0000000001010101 z_sub_us = 0000000001010101 z_sub_su = 0000000001010101 z_sub_ss = 0000000001010101 y_mul_uu = 0000010000100000 y_mul_us = 0000010000100000 y_mul_su = 0000010000100000 y_mul_ss = 0000010000100000 z_mul_uu = 0000010000100000 z_mul_us = 0000010000100000 z_mul_su = 0000010000100000 z_mul_ss = 0000010000100000 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 0 a = 00100101 b = 00110010 c = 100010 y_mux_uu = 0000000000110010 y_mux_us = 0000000000110010 y_mux_su = 0000000000110010 y_mux_ss = 0000000000110010 z_mux_uu = 0000000000110010 z_mux_us = 0000000000110010 z_mux_su = 0000000000110010 z_mux_ss = 0000000000110010 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111011101 y_sgn_s = 0000000000011101 z_sgn_u = 1111111111011101 z_sgn_s = 0000000000011101 y_add_uu = 0000000001000111 y_add_us = 0000000001000111 y_add_su = 0000000001000111 y_add_ss = 0000000000000111 z_add_uu = 0000000001000111 z_add_us = 0000000001000111 z_add_su = 0000000001000111 z_add_ss = 0000000000000111 y_sub_uu = 0000000000000011 y_sub_us = 0000000000000011 y_sub_su = 0000000000000011 y_sub_ss = 0000000001000011 z_sub_uu = 0000000000000011 z_sub_us = 0000000000000011 z_sub_su = 0000000000000011 z_sub_ss = 0000000001000011 y_mul_uu = 0000010011101010 y_mul_us = 0000010011101010 y_mul_su = 0000010011101010 y_mul_ss = 1111101110101010 z_mul_uu = 0000010011101010 z_mul_us = 0000010011101010 z_mul_su = 0000010011101010 z_mul_ss = 1111101110101010 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 sel = 1 a = 00010100 b = 00111101 c = 001011 y_mux_uu = 0000000000010100 y_mux_us = 0000000000010100 y_mux_su = 0000000000010100 y_mux_ss = 0000000000010100 z_mux_uu = 0000000000010100 z_mux_us = 0000000000010100 z_mux_su = 0000000000010100 z_mux_ss = 0000000000010100 y_eql_uu = 0 y_eql_us = 0 y_eql_su = 0 y_eql_ss = 0 z_eql_uu = 0 z_eql_us = 0 z_eql_su = 0 z_eql_ss = 0 y_neq_uu = 1 y_neq_us = 1 y_neq_su = 1 y_neq_ss = 1 z_neq_uu = 1 z_neq_us = 1 z_neq_su = 1 z_neq_ss = 1 y_sgn_u = 1111111111110100 y_sgn_s = 1111111111110100 z_sgn_u = 1111111111110100 z_sgn_s = 1111111111110100 y_add_uu = 0000000000011111 y_add_us = 0000000000011111 y_add_su = 0000000000011111 y_add_ss = 0000000000011111 z_add_uu = 0000000000011111 z_add_us = 0000000000011111 z_add_su = 0000000000011111 z_add_ss = 0000000000011111 y_sub_uu = 0000000000001001 y_sub_us = 0000000000001001 y_sub_su = 0000000000001001 y_sub_ss = 0000000000001001 z_sub_uu = 0000000000001001 z_sub_us = 0000000000001001 z_sub_su = 0000000000001001 z_sub_ss = 0000000000001001 y_mul_uu = 0000000011011100 y_mul_us = 0000000011011100 y_mul_su = 0000000011011100 y_mul_ss = 0000000011011100 z_mul_uu = 0000000011011100 z_mul_us = 0000000011011100 z_mul_su = 0000000011011100 z_mul_ss = 0000000011011100 y_ltn_uu = 0 y_ltn_us = 0 y_ltn_su = 0 y_ltn_ss = 0 z_ltn_uu = 0 z_ltn_us = 0 z_ltn_su = 0 z_ltn_ss = 0 y_leq_uu = 0 y_leq_us = 0 y_leq_su = 0 y_leq_ss = 0 z_leq_uu = 0 z_leq_us = 0 z_leq_su = 0 z_leq_ss = 0 iverilog-12_0/ivtest/gold/pr2146620.gold000066400000000000000000000000201435245347300176370ustar00rootroot00000000000000 0 128 0 128 iverilog-12_0/ivtest/gold/pr2146620b.gold000066400000000000000000000000141435245347300200040ustar00rootroot000000000000005 4 3 2 1 0 iverilog-12_0/ivtest/gold/pr2146824.gold000066400000000000000000000000051435245347300176500ustar00rootroot00000000000000'hfe iverilog-12_0/ivtest/gold/pr2152011.gold000066400000000000000000000002401435245347300176320ustar00rootroot00000000000000 0 144857 199758 130608 -19650 -157705 -197825 -115095 39109 169027 193978 98468 -58190 -178713 -188254 -80889 76709 186670 180708 62527 iverilog-12_0/ivtest/gold/pr2159630.gold000066400000000000000000000000361435245347300176530ustar00rootroot00000000000000Var -4 vs signed(concat) -4 iverilog-12_0/ivtest/gold/pr2169870.gold000066400000000000000000000000501435245347300176560ustar00rootroot000000000000000 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 iverilog-12_0/ivtest/gold/pr2248925.gold000066400000000000000000000000051435245347300176550ustar00rootroot000000000000001500 iverilog-12_0/ivtest/gold/pr2251119.gold000066400000000000000000000000471435245347300176500ustar00rootroot00000000000000PASSED: 1100 < 1000 false branch taken iverilog-12_0/ivtest/gold/pr2251119_std.gold000066400000000000000000000000561435245347300205220ustar00rootroot00000000000000PASSED: 1100 < 1000 false branch taken iverilog-12_0/ivtest/gold/pr2272468.gold000066400000000000000000000014001435245347300176540ustar00rootroot00000000000000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 iverilog-12_0/ivtest/gold/pr243.gold000066400000000000000000000261041435245347300173360ustar00rootroot00000000000000 TIME:state:out1:out2 0: 0: 0: 0 10: 0: 0: 1 30: 1: 0: 0 40: 2: 0: 0 50: 3: 0: 0 60: 4: 0: 0 70: 5: 0: 0 80: 6: 1: 0 90: 7: 1: 0 100: 8: 1: 0 110: 9: 1: 0 120: 10: 1: 0 130: 11: 1: 0 140: 12: 1: 0 150: 13: 1: 0 160: 14: 1: 0 170: 15: 1: 0 180: 16: 1: 0 190: 17: 1: 0 200: 18: 1: 0 210: 19: 1: 0 220: 20: 1: 0 230: 21: 1: 0 240: 22: 1: 0 250: 23: 1: 0 260: 24: 1: 0 270: 25: 1: 0 280: 26: 1: 0 290: 27: 1: 0 300: 28: 1: 0 310: 29: 1: 0 320: 30: 1: 0 330: 31: 1: 0 340: 32: 1: 0 350: 33: 1: 0 360: 34: 1: 0 370: 35: 1: 0 380: 36: 1: 0 390: 37: 1: 0 400: 38: 1: 0 410: 39: 1: 0 420: 40: 1: 0 430: 41: 1: 0 440: 42: 1: 0 450: 43: 1: 0 460: 44: 1: 0 470: 45: 1: 0 480: 46: 1: 0 490: 47: 1: 0 500: 48: 1: 0 510: 49: 1: 0 520: 50: 1: 0 530: 51: 1: 0 540: 52: 1: 0 550: 53: 1: 0 560: 54: 1: 0 570: 55: 1: 0 580: 56: 1: 0 590: 57: 1: 0 600: 58: 1: 0 610: 59: 1: 0 620: 60: 1: 0 630: 61: 1: 0 640: 62: 1: 0 650: 63: 1: 0 660: 64: 1: 0 670: 65: 1: 0 680: 66: 1: 0 690: 67: 1: 0 700: 68: 1: 0 710: 69: 1: 0 720: 70: 1: 0 730: 71: 1: 0 740: 72: 1: 0 750: 73: 1: 0 760: 74: 1: 0 770: 75: 1: 0 780: 76: 1: 0 790: 77: 1: 0 800: 78: 1: 0 810: 79: 1: 0 820: 80: 1: 0 830: 81: 1: 0 840: 82: 1: 0 850: 83: 1: 0 860: 84: 1: 0 870: 85: 1: 0 880: 86: 1: 0 890: 87: 1: 0 900: 88: 1: 0 910: 89: 1: 0 920: 90: 1: 0 930: 91: 1: 0 940: 92: 1: 0 950: 93: 1: 0 960: 94: 1: 0 970: 95: 1: 0 980: 96: 1: 0 990: 97: 1: 0 1000: 98: 1: 0 1010: 99: 1: 0 1020: 100: 1: 0 1030: 101: 1: 0 1040: 102: 1: 0 1050: 103: 1: 0 1060: 104: 1: 0 1070: 105: 1: 0 1080: 106: 1: 0 1090: 107: 1: 0 1100: 108: 1: 0 1110: 109: 1: 0 1120: 110: 1: 0 1130: 111: 1: 0 1140: 112: 1: 0 1150: 113: 1: 0 1160: 114: 1: 0 1170: 115: 1: 0 1180: 116: 1: 0 1190: 117: 1: 0 1200: 118: 1: 0 1210: 119: 1: 0 1220: 120: 1: 0 1230: 121: 1: 0 1240: 122: 1: 0 1250: 123: 1: 0 1260: 124: 1: 0 1270: 125: 1: 0 1280: 126: 1: 0 1290: 127: 1: 0 1300: 128: 1: 0 1310: 129: 1: 0 1320: 130: 1: 0 1330: 131: 1: 0 1340: 132: 1: 0 1350: 133: 1: 0 1360: 134: 1: 0 1370: 135: 1: 0 1380: 136: 1: 0 1390: 137: 1: 0 1400: 138: 1: 0 1410: 139: 1: 0 1420: 140: 1: 0 1430: 141: 1: 0 1440: 142: 1: 0 1450: 143: 1: 0 1460: 144: 1: 0 1470: 145: 1: 0 1480: 146: 1: 0 1490: 147: 1: 0 1500: 148: 1: 0 1510: 149: 1: 0 1520: 150: 1: 0 1530: 151: 1: 0 1540: 152: 1: 0 1550: 153: 1: 0 1560: 154: 1: 0 1570: 155: 1: 0 1580: 156: 1: 0 1590: 157: 1: 0 1600: 158: 1: 0 1610: 159: 1: 0 1620: 160: 1: 0 1630: 161: 1: 0 1640: 162: 1: 0 1650: 163: 1: 0 1660: 164: 1: 0 1670: 165: 1: 0 1680: 166: 1: 0 1690: 167: 1: 0 1700: 168: 1: 0 1710: 169: 1: 0 1720: 170: 1: 0 1730: 171: 1: 0 1740: 172: 1: 0 1750: 173: 1: 0 1760: 174: 1: 0 1770: 175: 1: 0 1780: 176: 1: 0 1790: 177: 1: 0 1800: 178: 1: 0 1810: 179: 1: 0 1820: 180: 1: 0 1830: 181: 1: 0 1840: 182: 1: 0 1850: 183: 1: 0 1860: 184: 1: 0 1870: 185: 1: 0 1880: 186: 1: 0 1890: 187: 1: 0 1900: 188: 1: 0 1910: 189: 1: 0 1920: 190: 1: 0 1930: 191: 1: 0 1940: 192: 1: 0 1950: 193: 1: 0 1960: 194: 1: 0 1970: 195: 1: 0 1980: 196: 1: 0 1990: 197: 1: 0 2000: 198: 1: 0 2010: 199: 1: 0 2020: 200: 1: 0 2030: 201: 1: 0 2040: 202: 1: 0 2050: 203: 1: 0 2060: 204: 1: 0 2070: 205: 1: 0 2080: 206: 1: 0 2090: 207: 1: 0 2100: 208: 1: 0 2110: 209: 1: 0 2120: 210: 1: 0 2130: 211: 1: 0 2140: 212: 1: 0 2150: 213: 1: 0 2160: 214: 1: 0 2170: 215: 1: 0 2180: 216: 1: 0 2190: 217: 1: 0 2200: 218: 1: 0 2210: 219: 1: 0 2220: 220: 1: 0 2230: 221: 1: 0 2240: 222: 1: 0 2250: 223: 1: 0 2260: 224: 1: 0 2270: 225: 1: 0 2280: 226: 1: 0 2290: 227: 1: 0 2300: 228: 1: 0 2310: 229: 1: 0 2320: 230: 1: 0 2330: 231: 1: 0 2340: 232: 1: 0 2350: 233: 1: 0 2360: 234: 1: 0 2370: 235: 1: 0 2380: 236: 1: 0 2390: 237: 1: 0 2400: 238: 1: 0 2410: 239: 1: 0 2420: 240: 1: 0 2430: 241: 1: 0 2440: 242: 1: 0 2450: 243: 1: 0 2460: 244: 1: 0 2470: 245: 1: 0 2480: 246: 1: 0 2490: 247: 1: 0 2500: 248: 1: 0 2510: 249: 1: 0 2520: 250: 1: 0 2530: 251: 1: 0 2540: 252: 1: 0 2550: 253: 1: 0 2560: 254: 1: 0 2570: 255: 1: 0 2580: 256: 1: 0 2590: 257: 1: 0 2600: 258: 1: 0 2610: 259: 1: 0 2620: 260: 1: 0 2630: 261: 1: 0 2640: 262: 1: 0 2650: 263: 1: 0 2660: 264: 1: 0 2670: 265: 1: 0 2680: 266: 1: 0 2690: 267: 1: 0 2700: 268: 1: 0 2710: 269: 1: 0 2720: 270: 1: 0 2730: 271: 1: 0 2740: 272: 1: 0 2750: 273: 1: 0 2760: 274: 1: 0 2770: 275: 1: 0 2780: 276: 1: 0 2790: 277: 1: 0 2800: 278: 1: 0 2810: 279: 1: 0 2820: 280: 1: 0 2830: 281: 1: 0 2840: 282: 1: 0 2850: 283: 1: 0 2860: 284: 1: 0 2870: 285: 1: 0 2880: 286: 1: 0 2890: 287: 1: 0 2900: 288: 1: 0 2910: 289: 1: 0 2920: 290: 1: 0 2930: 291: 1: 0 2940: 292: 1: 0 2950: 293: 1: 0 2960: 294: 1: 0 2970: 295: 1: 0 2980: 296: 1: 0 2990: 297: 1: 0 3000: 298: 1: 0 3010: 299: 1: 0 3020: 300: 1: 0 3030: 301: 1: 0 3040: 302: 1: 0 3050: 303: 1: 0 3060: 304: 1: 0 3070: 305: 1: 0 3080: 306: 1: 0 3090: 307: 1: 0 3100: 308: 1: 0 3110: 309: 1: 0 3120: 310: 1: 0 3130: 311: 1: 0 3140: 312: 1: 0 3150: 313: 1: 0 3160: 314: 1: 0 3170: 315: 1: 0 3180: 316: 1: 0 3190: 317: 1: 0 3200: 318: 1: 0 3210: 319: 1: 0 3220: 320: 1: 0 3230: 321: 1: 0 3240: 322: 1: 0 3250: 323: 1: 0 3260: 324: 1: 0 3270: 325: 1: 0 3280: 326: 1: 0 3290: 327: 1: 0 3300: 328: 1: 0 3310: 329: 1: 0 3320: 330: 1: 0 3330: 331: 1: 0 3340: 332: 1: 0 3350: 333: 1: 0 3360: 334: 1: 0 3370: 335: 1: 0 3380: 336: 1: 0 3390: 337: 1: 0 3400: 338: 1: 0 3410: 339: 1: 0 3420: 340: 1: 0 3430: 341: 1: 0 3440: 342: 1: 0 3450: 343: 1: 0 3460: 344: 1: 0 3470: 345: 1: 0 3480: 346: 1: 0 3490: 347: 1: 0 3500: 348: 1: 0 3510: 349: 1: 0 3520: 350: 1: 0 3530: 351: 1: 0 3540: 352: 1: 0 3550: 353: 1: 0 3560: 354: 1: 0 3570: 355: 1: 0 3580: 356: 1: 0 3590: 357: 1: 0 3600: 358: 1: 0 3610: 359: 1: 0 3620: 360: 1: 0 3630: 361: 1: 0 3640: 362: 1: 0 3650: 363: 1: 0 3660: 364: 1: 0 3670: 365: 1: 0 3680: 366: 1: 0 3690: 367: 1: 0 3700: 368: 1: 0 3710: 369: 1: 0 3720: 370: 1: 0 3730: 371: 1: 0 3740: 372: 1: 0 3750: 373: 1: 0 3760: 374: 1: 0 3770: 375: 1: 0 3780: 376: 1: 0 3790: 377: 1: 0 3800: 378: 1: 0 3810: 379: 1: 0 3820: 380: 1: 0 3830: 381: 1: 0 3840: 382: 1: 0 3850: 383: 1: 0 3860: 384: 1: 0 3870: 385: 1: 0 3880: 386: 1: 0 3890: 387: 1: 0 3900: 388: 1: 0 3910: 389: 1: 0 3920: 390: 1: 0 3930: 391: 1: 1 3940: 392: 1: 1 3950: 393: 1: 1 3960: 394: 1: 1 3970: 395: 1: 1 3980: 396: 1: 1 3990: 397: 1: 1 4000: 398: 1: 1 4010: 399: 1: 1 4020: 400: 1: 1 4030: 401: 1: 1 4040: 402: 1: 1 4050: 403: 1: 1 4060: 404: 1: 1 4070: 405: 1: 1 4080: 406: 1: 1 4090: 407: 1: 1 4100: 408: 1: 1 4110: 409: 1: 1 4120: 410: 1: 1 4130: 411: 1: 1 4140: 412: 1: 1 4150: 413: 1: 1 4160: 414: 1: 1 4170: 415: 1: 1 4180: 416: 1: 1 4190: 417: 1: 1 4200: 418: 1: 1 4210: 419: 1: 1 4220: 420: 1: 1 4230: 421: 1: 1 4240: 422: 1: 1 4250: 423: 1: 1 4260: 424: 1: 1 4270: 425: 1: 1 4280: 426: 1: 1 4290: 427: 1: 1 4300: 428: 1: 1 4310: 429: 1: 1 4320: 430: 1: 1 4330: 431: 1: 1 4340: 432: 1: 1 4350: 433: 1: 1 4360: 434: 1: 1 4370: 435: 1: 1 4380: 436: 1: 1 4390: 437: 1: 1 4400: 438: 1: 1 4410: 439: 1: 1 4420: 440: 1: 1 4430: 441: 1: 1 4440: 442: 1: 1 4450: 443: 1: 1 4460: 444: 1: 1 4470: 445: 1: 1 4480: 446: 1: 1 4490: 447: 1: 1 4500: 448: 1: 1 4510: 449: 1: 1 4520: 450: 1: 1 4530: 451: 1: 1 4540: 452: 1: 1 4550: 453: 1: 1 4560: 454: 1: 1 4570: 455: 1: 1 4580: 456: 1: 1 4590: 457: 1: 1 4600: 458: 1: 1 4610: 459: 1: 1 4620: 460: 1: 1 4630: 461: 1: 1 4640: 462: 1: 1 4650: 463: 1: 1 4660: 464: 1: 1 4670: 465: 1: 1 4680: 466: 1: 1 4690: 467: 1: 1 4700: 468: 1: 1 4710: 469: 1: 1 4720: 470: 1: 1 4730: 471: 1: 1 4740: 472: 1: 1 4750: 473: 1: 1 4760: 474: 1: 1 4770: 475: 1: 1 4780: 476: 1: 1 4790: 477: 1: 1 4800: 478: 1: 1 4810: 479: 1: 1 4820: 480: 1: 1 4830: 481: 1: 1 4840: 482: 1: 1 4850: 483: 1: 1 4860: 484: 1: 1 4870: 485: 1: 1 4880: 486: 1: 1 4890: 487: 1: 1 4900: 488: 1: 1 4910: 489: 1: 1 4920: 490: 1: 1 4930: 491: 1: 1 4940: 492: 1: 1 4950: 493: 1: 1 4960: 494: 1: 1 4970: 495: 1: 1 4980: 496: 1: 1 4990: 497: 1: 1 5000: 498: 1: 1 5010: 499: 1: 1 5020: 500: 1: 1 5030: 501: 1: 1 5040: 502: 1: 1 5050: 503: 1: 1 5060: 504: 1: 1 5070: 505: 1: 1 5080: 506: 1: 1 5090: 507: 1: 1 5100: 508: 1: 1 5110: 509: 1: 1 5120: 510: 1: 1 5130: 511: 1: 1 5140: 0: 0: 0 iverilog-12_0/ivtest/gold/pr243_std.gold000066400000000000000000000451121435245347300202100ustar00rootroot00000000000000 TIME:state:out1:out2 0: 0: 0: 0 10: 0: 0: 1 30: 1: 0: 0 40: 2: 0: 0 50: 3: 0: 0 60: 4: 0: 0 70: 5: 0: 0 80: 6: 1: 0 90: 7: 1: 0 100: 8: 1: 0 110: 9: 1: 0 120: 10: 1: 0 130: 11: 1: 0 140: 12: 1: 0 150: 13: 1: 0 160: 14: 1: 0 170: 15: 1: 0 180: 16: 1: 0 190: 17: 1: 0 200: 18: 1: 0 210: 19: 1: 0 220: 20: 1: 0 230: 21: 1: 0 240: 22: 1: 0 250: 23: 1: 0 260: 24: 1: 0 270: 25: 1: 0 280: 26: 1: 0 290: 27: 1: 0 300: 28: 1: 0 310: 29: 1: 0 320: 30: 1: 0 330: 31: 1: 0 340: 32: 1: 0 350: 33: 1: 0 360: 34: 1: 0 370: 35: 1: 0 380: 36: 1: 0 390: 37: 1: 0 400: 38: 1: 0 410: 39: 1: 0 420: 40: 1: 0 430: 41: 1: 0 440: 42: 1: 0 450: 43: 1: 0 460: 44: 1: 0 470: 45: 1: 0 480: 46: 1: 0 490: 47: 1: 0 500: 48: 1: 0 510: 49: 1: 0 520: 50: 1: 0 530: 51: 1: 0 540: 52: 1: 0 550: 53: 1: 0 560: 54: 1: 0 570: 55: 1: 0 580: 56: 1: 0 590: 57: 1: 0 600: 58: 1: 0 610: 59: 1: 0 620: 60: 1: 0 630: 61: 1: 0 640: 62: 1: 0 650: 63: 1: 0 660: 64: 1: 0 670: 65: 1: 0 680: 66: 1: 0 690: 67: 1: 0 700: 68: 1: 0 710: 69: 1: 0 720: 70: 1: 0 730: 71: 1: 0 740: 72: 1: 0 750: 73: 1: 0 760: 74: 1: 0 770: 75: 1: 0 780: 76: 1: 0 790: 77: 1: 0 800: 78: 1: 0 810: 79: 1: 0 820: 80: 1: 0 830: 81: 1: 0 840: 82: 1: 0 850: 83: 1: 0 860: 84: 1: 0 870: 85: 1: 0 880: 86: 1: 0 890: 87: 1: 0 900: 88: 1: 0 910: 89: 1: 0 920: 90: 1: 0 930: 91: 1: 0 940: 92: 1: 0 950: 93: 1: 0 960: 94: 1: 0 970: 95: 1: 0 980: 96: 1: 0 990: 97: 1: 0 1000: 98: 1: 0 1010: 99: 1: 0 1020: 100: 1: 0 1030: 101: 1: 0 1040: 102: 1: 0 1050: 103: 1: 0 1060: 104: 1: 0 1070: 105: 1: 0 1080: 106: 1: 0 1090: 107: 1: 0 1100: 108: 1: 0 1110: 109: 1: 0 1120: 110: 1: 0 1130: 111: 1: 0 1140: 112: 1: 0 1150: 113: 1: 0 1160: 114: 1: 0 1170: 115: 1: 0 1180: 116: 1: 0 1190: 117: 1: 0 1200: 118: 1: 0 1210: 119: 1: 0 1220: 120: 1: 0 1230: 121: 1: 0 1240: 122: 1: 0 1250: 123: 1: 0 1260: 124: 1: 0 1270: 125: 1: 0 1280: 126: 1: 0 1290: 127: 1: 0 1300: 128: 1: 0 1310: 129: 1: 0 1320: 130: 1: 0 1330: 131: 1: 0 1340: 132: 1: 0 1350: 133: 1: 0 1360: 134: 1: 0 1370: 135: 1: 0 1380: 136: 1: 0 1390: 137: 1: 0 1400: 138: 1: 0 1410: 139: 1: 0 1420: 140: 1: 0 1430: 141: 1: 0 1440: 142: 1: 0 1450: 143: 1: 0 1460: 144: 1: 0 1470: 145: 1: 0 1480: 146: 1: 0 1490: 147: 1: 0 1500: 148: 1: 0 1510: 149: 1: 0 1520: 150: 1: 0 1530: 151: 1: 0 1540: 152: 1: 0 1550: 153: 1: 0 1560: 154: 1: 0 1570: 155: 1: 0 1580: 156: 1: 0 1590: 157: 1: 0 1600: 158: 1: 0 1610: 159: 1: 0 1620: 160: 1: 0 1630: 161: 1: 0 1640: 162: 1: 0 1650: 163: 1: 0 1660: 164: 1: 0 1670: 165: 1: 0 1680: 166: 1: 0 1690: 167: 1: 0 1700: 168: 1: 0 1710: 169: 1: 0 1720: 170: 1: 0 1730: 171: 1: 0 1740: 172: 1: 0 1750: 173: 1: 0 1760: 174: 1: 0 1770: 175: 1: 0 1780: 176: 1: 0 1790: 177: 1: 0 1800: 178: 1: 0 1810: 179: 1: 0 1820: 180: 1: 0 1830: 181: 1: 0 1840: 182: 1: 0 1850: 183: 1: 0 1860: 184: 1: 0 1870: 185: 1: 0 1880: 186: 1: 0 1890: 187: 1: 0 1900: 188: 1: 0 1910: 189: 1: 0 1920: 190: 1: 0 1930: 191: 1: 0 1940: 192: 1: 0 1950: 193: 1: 0 1960: 194: 1: 0 1970: 195: 1: 0 1980: 196: 1: 0 1990: 197: 1: 0 2000: 198: 1: 0 2010: 199: 1: 0 2020: 200: 1: 0 2030: 201: 1: 0 2040: 202: 1: 0 2050: 203: 1: 0 2060: 204: 1: 0 2070: 205: 1: 0 2080: 206: 1: 0 2090: 207: 1: 0 2100: 208: 1: 0 2110: 209: 1: 0 2120: 210: 1: 0 2130: 211: 1: 0 2140: 212: 1: 0 2150: 213: 1: 0 2160: 214: 1: 0 2170: 215: 1: 0 2180: 216: 1: 0 2190: 217: 1: 0 2200: 218: 1: 0 2210: 219: 1: 0 2220: 220: 1: 0 2230: 221: 1: 0 2240: 222: 1: 0 2250: 223: 1: 0 2260: 224: 1: 0 2270: 225: 1: 0 2280: 226: 1: 0 2290: 227: 1: 0 2300: 228: 1: 0 2310: 229: 1: 0 2320: 230: 1: 0 2330: 231: 1: 0 2340: 232: 1: 0 2350: 233: 1: 0 2360: 234: 1: 0 2370: 235: 1: 0 2380: 236: 1: 0 2390: 237: 1: 0 2400: 238: 1: 0 2410: 239: 1: 0 2420: 240: 1: 0 2430: 241: 1: 0 2440: 242: 1: 0 2450: 243: 1: 0 2460: 244: 1: 0 2470: 245: 1: 0 2480: 246: 1: 0 2490: 247: 1: 0 2500: 248: 1: 0 2510: 249: 1: 0 2520: 250: 1: 0 2530: 251: 1: 0 2540: 252: 1: 0 2550: 253: 1: 0 2560: 254: 1: 0 2570: 255: 1: 0 2580: 256: 1: 0 2590: 257: 1: 0 2600: 258: 1: 0 2610: 259: 1: 0 2620: 260: 1: 0 2630: 261: 1: 0 2640: 262: 1: 0 2650: 263: 1: 0 2660: 264: 1: 0 2670: 265: 1: 0 2680: 266: 1: 0 2690: 267: 1: 0 2700: 268: 1: 0 2710: 269: 1: 0 2720: 270: 1: 0 2730: 271: 1: 0 2740: 272: 1: 0 2750: 273: 1: 0 2760: 274: 1: 0 2770: 275: 1: 0 2780: 276: 1: 0 2790: 277: 1: 0 2800: 278: 1: 0 2810: 279: 1: 0 2820: 280: 1: 0 2830: 281: 1: 0 2840: 282: 1: 0 2850: 283: 1: 0 2860: 284: 1: 0 2870: 285: 1: 0 2880: 286: 1: 0 2890: 287: 1: 0 2900: 288: 1: 0 2910: 289: 1: 0 2920: 290: 1: 0 2930: 291: 1: 0 2940: 292: 1: 0 2950: 293: 1: 0 2960: 294: 1: 0 2970: 295: 1: 0 2980: 296: 1: 0 2990: 297: 1: 0 3000: 298: 1: 0 3010: 299: 1: 0 3020: 300: 1: 0 3030: 301: 1: 0 3040: 302: 1: 0 3050: 303: 1: 0 3060: 304: 1: 0 3070: 305: 1: 0 3080: 306: 1: 0 3090: 307: 1: 0 3100: 308: 1: 0 3110: 309: 1: 0 3120: 310: 1: 0 3130: 311: 1: 0 3140: 312: 1: 0 3150: 313: 1: 0 3160: 314: 1: 0 3170: 315: 1: 0 3180: 316: 1: 0 3190: 317: 1: 0 3200: 318: 1: 0 3210: 319: 1: 0 3220: 320: 1: 0 3230: 321: 1: 0 3240: 322: 1: 0 3250: 323: 1: 0 3260: 324: 1: 0 3270: 325: 1: 0 3280: 326: 1: 0 3290: 327: 1: 0 3300: 328: 1: 0 3310: 329: 1: 0 3320: 330: 1: 0 3330: 331: 1: 0 3340: 332: 1: 0 3350: 333: 1: 0 3360: 334: 1: 0 3370: 335: 1: 0 3380: 336: 1: 0 3390: 337: 1: 0 3400: 338: 1: 0 3410: 339: 1: 0 3420: 340: 1: 0 3430: 341: 1: 0 3440: 342: 1: 0 3450: 343: 1: 0 3460: 344: 1: 0 3470: 345: 1: 0 3480: 346: 1: 0 3490: 347: 1: 0 3500: 348: 1: 0 3510: 349: 1: 0 3520: 350: 1: 0 3530: 351: 1: 0 3540: 352: 1: 0 3550: 353: 1: 0 3560: 354: 1: 0 3570: 355: 1: 0 3580: 356: 1: 0 3590: 357: 1: 0 3600: 358: 1: 0 3610: 359: 1: 0 3620: 360: 1: 0 3630: 361: 1: 0 3640: 362: 1: 0 3650: 363: 1: 0 3660: 364: 1: 0 3670: 365: 1: 0 3680: 366: 1: 0 3690: 367: 1: 0 3700: 368: 1: 0 3710: 369: 1: 0 3720: 370: 1: 0 3730: 371: 1: 0 3740: 372: 1: 0 3750: 373: 1: 0 3760: 374: 1: 0 3770: 375: 1: 0 3780: 376: 1: 0 3790: 377: 1: 0 3800: 378: 1: 0 3810: 379: 1: 0 3820: 380: 1: 0 3830: 381: 1: 0 3840: 382: 1: 0 3850: 383: 1: 0 3860: 384: 1: 0 3870: 385: 1: 0 3880: 386: 1: 0 3890: 387: 1: 0 3900: 388: 1: 0 3910: 389: 1: 0 3920: 390: 1: 0 3930: 391: 1: 1 3940: 392: 1: 1 3950: 393: 1: 1 3960: 394: 1: 1 3970: 395: 1: 1 3980: 396: 1: 1 3990: 397: 1: 1 4000: 398: 1: 1 4010: 399: 1: 1 4020: 400: 1: 1 4030: 401: 1: 1 4040: 402: 1: 1 4050: 403: 1: 1 4060: 404: 1: 1 4070: 405: 1: 1 4080: 406: 1: 1 4090: 407: 1: 1 4100: 408: 1: 1 4110: 409: 1: 1 4120: 410: 1: 1 4130: 411: 1: 1 4140: 412: 1: 1 4150: 413: 1: 1 4160: 414: 1: 1 4170: 415: 1: 1 4180: 416: 1: 1 4190: 417: 1: 1 4200: 418: 1: 1 4210: 419: 1: 1 4220: 420: 1: 1 4230: 421: 1: 1 4240: 422: 1: 1 4250: 423: 1: 1 4260: 424: 1: 1 4270: 425: 1: 1 4280: 426: 1: 1 4290: 427: 1: 1 4300: 428: 1: 1 4310: 429: 1: 1 4320: 430: 1: 1 4330: 431: 1: 1 4340: 432: 1: 1 4350: 433: 1: 1 4360: 434: 1: 1 4370: 435: 1: 1 4380: 436: 1: 1 4390: 437: 1: 1 4400: 438: 1: 1 4410: 439: 1: 1 4420: 440: 1: 1 4430: 441: 1: 1 4440: 442: 1: 1 4450: 443: 1: 1 4460: 444: 1: 1 4470: 445: 1: 1 4480: 446: 1: 1 4490: 447: 1: 1 4500: 448: 1: 1 4510: 449: 1: 1 4520: 450: 1: 1 4530: 451: 1: 1 4540: 452: 1: 1 4550: 453: 1: 1 4560: 454: 1: 1 4570: 455: 1: 1 4580: 456: 1: 1 4590: 457: 1: 1 4600: 458: 1: 1 4610: 459: 1: 1 4620: 460: 1: 1 4630: 461: 1: 1 4640: 462: 1: 1 4650: 463: 1: 1 4660: 464: 1: 1 4670: 465: 1: 1 4680: 466: 1: 1 4690: 467: 1: 1 4700: 468: 1: 1 4710: 469: 1: 1 4720: 470: 1: 1 4730: 471: 1: 1 4740: 472: 1: 1 4750: 473: 1: 1 4760: 474: 1: 1 4770: 475: 1: 1 4780: 476: 1: 1 4790: 477: 1: 1 4800: 478: 1: 1 4810: 479: 1: 1 4820: 480: 1: 1 4830: 481: 1: 1 4840: 482: 1: 1 4850: 483: 1: 1 4860: 484: 1: 1 4870: 485: 1: 1 4880: 486: 1: 1 4890: 487: 1: 1 4900: 488: 1: 1 4910: 489: 1: 1 4920: 490: 1: 1 4930: 491: 1: 1 4940: 492: 1: 1 4950: 493: 1: 1 4960: 494: 1: 1 4970: 495: 1: 1 4980: 496: 1: 1 4990: 497: 1: 1 5000: 498: 1: 1 5010: 499: 1: 1 5020: 500: 1: 1 5030: 501: 1: 1 5040: 502: 1: 1 5050: 503: 1: 1 5060: 504: 1: 1 5070: 505: 1: 1 5080: 506: 1: 1 5090: 507: 1: 1 5100: 508: 1: 1 5110: 509: 1: 1 5120: 510: 1: 1 5130: 511: 1: 1 iverilog-12_0/ivtest/gold/pr245.gold000066400000000000000000000140301435245347300173330ustar00rootroot00000000000000 TIME:IOD 0ns:000 10ns:001 20ns:002 30ns:003 40ns:004 50ns:005 60ns:006 70ns:007 80ns:008 90ns:009 100ns:00a 110ns:00b 120ns:00c 130ns:00d 140ns:00e 150ns:00f 160ns:010 170ns:011 180ns:012 190ns:013 200ns:014 210ns:015 220ns:016 230ns:017 240ns:018 250ns:019 260ns:01a 270ns:01b 280ns:01c 290ns:01d 300ns:01e 310ns:01f 320ns:020 330ns:021 340ns:022 350ns:023 360ns:024 370ns:025 380ns:026 390ns:027 400ns:028 410ns:029 420ns:02a 430ns:02b 440ns:02c 450ns:02d 460ns:02e 470ns:02f 480ns:030 490ns:031 500ns:032 510ns:033 520ns:034 530ns:035 540ns:036 550ns:037 560ns:038 570ns:039 580ns:03a 590ns:03b 600ns:03c 610ns:03d 620ns:03e 630ns:03f 640ns:040 650ns:041 660ns:042 670ns:043 680ns:044 690ns:045 700ns:046 710ns:047 720ns:048 730ns:049 740ns:04a 750ns:04b 760ns:04c 770ns:04d 780ns:04e 790ns:04f 800ns:050 810ns:051 820ns:052 830ns:053 840ns:054 850ns:055 860ns:056 870ns:057 880ns:058 890ns:059 900ns:05a 910ns:05b 920ns:05c 930ns:05d 940ns:05e 950ns:05f 960ns:060 970ns:061 980ns:062 990ns:063 1000ns:064 1010ns:065 1020ns:066 1030ns:067 1040ns:068 1050ns:069 1060ns:06a 1070ns:06b 1080ns:06c 1090ns:06d 1100ns:06e 1110ns:06f 1120ns:070 1130ns:071 1140ns:072 1150ns:073 1160ns:074 1170ns:075 1180ns:076 1190ns:077 1200ns:078 1210ns:079 1220ns:07a 1230ns:07b 1240ns:07c 1250ns:07d 1260ns:07e 1270ns:07f 1280ns:080 1290ns:081 1300ns:082 1310ns:083 1320ns:084 1330ns:085 1340ns:086 1350ns:087 1360ns:088 1370ns:089 1380ns:08a 1390ns:08b 1400ns:08c 1410ns:08d 1420ns:08e 1430ns:08f 1440ns:090 1450ns:091 1460ns:092 1470ns:093 1480ns:094 1490ns:095 1500ns:096 1510ns:097 1520ns:098 1530ns:099 1540ns:09a 1550ns:09b 1560ns:09c 1570ns:09d 1580ns:09e 1590ns:09f 1600ns:0a0 1610ns:0a1 1620ns:0a2 1630ns:0a3 1640ns:0a4 1650ns:0a5 1660ns:0a6 1670ns:0a7 1680ns:0a8 1690ns:0a9 1700ns:0aa 1710ns:0ab 1720ns:0ac 1730ns:0ad 1740ns:0ae 1750ns:0af 1760ns:0b0 1770ns:0b1 1780ns:0b2 1790ns:0b3 1800ns:0b4 1810ns:0b5 1820ns:0b6 1830ns:0b7 1840ns:0b8 1850ns:0b9 1860ns:0ba 1870ns:0bb 1880ns:0bc 1890ns:0bd 1900ns:0be 1910ns:0bf 1920ns:0c0 1930ns:0c1 1940ns:0c2 1950ns:0c3 1960ns:0c4 1970ns:0c5 1980ns:0c6 1990ns:0c7 2000ns:0c8 2010ns:0c9 2020ns:0ca 2030ns:0cb 2040ns:0cc 2050ns:0cd 2060ns:0ce 2070ns:0cf 2080ns:0d0 2090ns:0d1 2100ns:0d2 2110ns:0d3 2120ns:0d4 2130ns:0d5 2140ns:0d6 2150ns:0d7 2160ns:0d8 2170ns:0d9 2180ns:0da 2190ns:0db 2200ns:0dc 2210ns:0dd 2220ns:0de 2230ns:0df 2240ns:0e0 2250ns:0e1 2260ns:0e2 2270ns:0e3 2280ns:0e4 2290ns:0e5 2300ns:0e6 2310ns:0e7 2320ns:0e8 2330ns:0e9 2340ns:0ea 2350ns:0eb 2360ns:0ec 2370ns:0ed 2380ns:0ee 2390ns:0ef 2400ns:0f0 2410ns:0f1 2420ns:0f2 2430ns:0f3 2440ns:0f4 2450ns:0f5 2460ns:0f6 2470ns:0f7 2480ns:0f8 2490ns:0f9 2500ns:0fa 2510ns:0fb 2520ns:0fc 2530ns:0fd 2540ns:0fe 2550ns:0ff 2560ns:100 2570ns:101 2580ns:102 2590ns:103 2600ns:104 2610ns:105 2620ns:106 2630ns:107 2640ns:108 2650ns:109 2660ns:10a 2670ns:10b 2680ns:10c 2690ns:10d 2700ns:10e 2710ns:10f 2720ns:110 2730ns:111 2740ns:112 2750ns:113 2760ns:114 2770ns:115 2780ns:116 2790ns:117 2800ns:118 2810ns:119 2820ns:11a 2830ns:11b 2840ns:11c 2850ns:11d 2860ns:11e 2870ns:11f 2880ns:120 2890ns:121 2900ns:122 2910ns:123 2920ns:124 2930ns:125 2940ns:126 2950ns:127 2960ns:128 2970ns:129 2980ns:12a 2990ns:12b 3000ns:12c 3010ns:12d 3020ns:12e 3030ns:12f 3040ns:130 3050ns:131 3060ns:132 3070ns:133 3080ns:134 3090ns:135 3100ns:136 3110ns:137 3120ns:138 3130ns:139 3140ns:13a 3150ns:13b 3160ns:13c 3170ns:13d 3180ns:13e 3190ns:13f 3200ns:140 3210ns:141 3220ns:142 3230ns:143 3240ns:144 3250ns:145 3260ns:146 3270ns:147 3280ns:148 3290ns:149 3300ns:14a 3310ns:14b 3320ns:14c 3330ns:14d 3340ns:14e 3350ns:14f 3360ns:150 3370ns:151 3380ns:152 3390ns:153 3400ns:154 3410ns:155 3420ns:156 3430ns:157 3440ns:158 3450ns:159 3460ns:15a 3470ns:15b 3480ns:15c 3490ns:15d 3500ns:15e 3510ns:15f 3520ns:160 3530ns:161 3540ns:162 3550ns:163 3560ns:164 3570ns:165 3580ns:166 3590ns:167 3600ns:168 3610ns:169 3620ns:16a 3630ns:16b 3640ns:16c 3650ns:16d 3660ns:16e 3670ns:16f 3680ns:170 3690ns:171 3700ns:172 3710ns:173 3720ns:174 3730ns:175 3740ns:176 3750ns:177 3760ns:178 3770ns:179 3780ns:17a 3790ns:17b 3800ns:17c 3810ns:17d 3820ns:17e 3830ns:17f 3840ns:180 3850ns:181 3860ns:182 3870ns:183 3880ns:184 3890ns:185 3900ns:186 3910ns:187 3920ns:188 3930ns:189 3940ns:18a 3950ns:18b 3960ns:18c 3970ns:18d 3980ns:18e 3990ns:18f 4000ns:190 4010ns:191 4020ns:192 4030ns:193 4040ns:194 4050ns:195 4060ns:196 4070ns:197 4080ns:198 4090ns:199 4100ns:19a 4110ns:19b 4120ns:19c 4130ns:19d 4140ns:19e 4150ns:19f 4160ns:1a0 4170ns:1a1 4180ns:1a2 4190ns:1a3 4200ns:1a4 4210ns:1a5 4220ns:1a6 4230ns:1a7 4240ns:1a8 4250ns:1a9 4260ns:1aa 4270ns:1ab 4280ns:1ac 4290ns:1ad 4300ns:1ae 4310ns:1af 4320ns:1b0 4330ns:1b1 4340ns:1b2 4350ns:1b3 4360ns:1b4 4370ns:1b5 4380ns:1b6 4390ns:1b7 4400ns:1b8 4410ns:1b9 4420ns:1ba 4430ns:1bb 4440ns:1bc 4450ns:1bd 4460ns:1be 4470ns:1bf 4480ns:1c0 4490ns:1c1 4500ns:1c2 4510ns:1c3 4520ns:1c4 4530ns:1c5 4540ns:1c6 4550ns:1c7 4560ns:1c8 4570ns:1c9 4580ns:1ca 4590ns:1cb 4600ns:1cc 4610ns:1cd 4620ns:1ce 4630ns:1cf 4640ns:1d0 4650ns:1d1 4660ns:1d2 4670ns:1d3 4680ns:1d4 4690ns:1d5 4700ns:1d6 4710ns:1d7 4720ns:1d8 4730ns:1d9 4740ns:1da 4750ns:1db 4760ns:1dc 4770ns:1dd 4780ns:1de 4790ns:1df 4800ns:1e0 4810ns:1e1 4820ns:1e2 4830ns:1e3 4840ns:1e4 4850ns:1e5 4860ns:1e6 4870ns:1e7 4880ns:1e8 4890ns:1e9 4900ns:1ea 4910ns:1eb 4920ns:1ec 4930ns:1ed 4940ns:1ee 4950ns:1ef 4960ns:1f0 4970ns:1f1 4980ns:1f2 4990ns:1f3 5000ns:1f4 5010ns:1f5 5020ns:1f6 5030ns:1f7 5040ns:1f8 5050ns:1f9 5060ns:1fa 5070ns:1fb 5080ns:1fc 5090ns:1fd 5100ns:1fe 5110ns:1ff 5120ns:200 iverilog-12_0/ivtest/gold/pr2486350.gold000066400000000000000000000000561435245347300176570ustar00rootroot00000000000000simtime= 10000000000000000 (2386f26fc10000) iverilog-12_0/ivtest/gold/pr2509349a-msys2.gold000077500000000000000000000005421435245347300211020ustar00rootroot00000000000000WARNING: ./ivltests/pr2509349a.v:10: $readmempath could not find directory "/tmp"! WARNING: ./ivltests/pr2509349a.v:10: $readmempath could not find directory "/no_dir"! WARNING: ./ivltests/pr2509349a.v:10: $readmempath could not find directory "no_dir2"! WARNING: ./ivltests/pr2509349a.v:10: $readmempath's path element "vsim" is not a directory! PASSED iverilog-12_0/ivtest/gold/pr2509349a-vlog95.gold000066400000000000000000000003421435245347300211450ustar00rootroot00000000000000WARNING: vlog95.v:17: $readmempath could not find directory "/no_dir"! WARNING: vlog95.v:17: $readmempath could not find directory "no_dir2"! WARNING: vlog95.v:17: $readmempath's path element "vsim" is not a directory! PASSED iverilog-12_0/ivtest/gold/pr2509349a.gold000066400000000000000000000004171435245347300200250ustar00rootroot00000000000000WARNING: ./ivltests/pr2509349a.v:10: $readmempath could not find directory "/no_dir"! WARNING: ./ivltests/pr2509349a.v:10: $readmempath could not find directory "no_dir2"! WARNING: ./ivltests/pr2509349a.v:10: $readmempath's path element "vsim" is not a directory! PASSED iverilog-12_0/ivtest/gold/pr2509349b-vlog95.gold000066400000000000000000000002771435245347300211550ustar00rootroot00000000000000WARNING: vlog95.v:14: $readmempath's argument (vpiReg) is not a valid string. WARNING: vlog95.v:17: $readmempath's argument contains non-printable characters. "tes\002" iverilog-12_0/ivtest/gold/pr2509349b.gold000066400000000000000000000003511435245347300200230ustar00rootroot00000000000000WARNING: ./ivltests/pr2509349b.v:5: $readmempath's argument (vpiReg) is not a valid string. WARNING: ./ivltests/pr2509349b.v:8: $readmempath's argument contains non-printable characters. "tes\002" iverilog-12_0/ivtest/gold/pr2580730.gold000066400000000000000000000004161435245347300176540ustar00rootroot00000000000000dl:ls32b- 1 ps rl:ls32b- 2 ps rg:ls32b- 3 ps ar:ls32b- 4 ps ps:ls32b- 5 ps dl:gt32b- 1000000000000 ps rl:gt32b- 2000000000000 ps rg:gt32b- 3000000000000 ps ar:gt32b- 4000000000000 ps ps:gt32b- 5000000000000 ps iverilog-12_0/ivtest/gold/pr2590274.gold000066400000000000000000000003051435245347300176550ustar00rootroot00000000000000warning: Found both default and `timescale based delays. Use : -Wtimescale to find the module(s) with no `timescale. The time in w_time is: 1.000000e-09 The time in wo_time is: 1.000000e+00 iverilog-12_0/ivtest/gold/pr2715558.gold000066400000000000000000000006101435245347300176600ustar00rootroot00000000000000sup1_sup0 resulted in: x sup1_str0 resulted in: x sup1_pl0 resulted in: x sup1_we0 resulted in: x str1_sup0 resulted in: x str1_str0 resulted in: x str1_pl0 resulted in: x str1_we0 resulted in: x pl1_sup0 resulted in: x pl1_str0 resulted in: x pl1_pl0 resulted in: x pl1_we0 resulted in: x we1_sup0 resulted in: x we1_str0 resulted in: x we1_pl0 resulted in: x we1_we0 resulted in: x iverilog-12_0/ivtest/gold/pr2715558b.gold000066400000000000000000000006101435245347300200220ustar00rootroot00000000000000sup1_sup0 resulted in: x sup1_str0 resulted in: 1 sup1_pl0 resulted in: 1 sup1_we0 resulted in: 1 str1_sup0 resulted in: 0 str1_str0 resulted in: x str1_pl0 resulted in: 1 str1_we0 resulted in: 1 pl1_sup0 resulted in: 0 pl1_str0 resulted in: 0 pl1_pl0 resulted in: x pl1_we0 resulted in: 1 we1_sup0 resulted in: 0 we1_str0 resulted in: 0 we1_pl0 resulted in: 0 we1_we0 resulted in: x iverilog-12_0/ivtest/gold/pr2715748.gold000066400000000000000000000001571435245347300176670ustar00rootroot00000000000000Real -1, Realtime 1 Real as int -1, Realtime as int 1 Real net 2 Real net as int 2 Passed %f put Passed %d put iverilog-12_0/ivtest/gold/pr2785294.gold000066400000000000000000000003341435245347300176670ustar00rootroot00000000000000 0 BS = 0, PS = 0, AR = 0 2 BS = 1, PS = 0, AR = 0 10 BS = 1, PS = 1, AR = 0 11 BS = 1, PS = 3, AR = 0 18 BS = 1, PS = 3, AR = 1 iverilog-12_0/ivtest/gold/pr2794144.gold000066400000000000000000000004661435245347300176670ustar00rootroot00000000000000./ivltests/pr2794144.v:8: error: '~' '|' is not a valid expression. Please use operator '~|' instead. ./ivltests/pr2794144.v:9: error: '~' '&' is not a valid expression. Please use operator '~&' instead. ./ivltests/pr2794144.v:10: error: '~' '^' is not a valid expression. Please use operator '~^' instead. iverilog-12_0/ivtest/gold/pr2800985b-vlog95.gold000066400000000000000000000005661435245347300211560ustar00rootroot00000000000000ERROR: vlog95.v:18: $ferror's fd (first) argument must be numeric. ERROR: vlog95.v:19: $ferror requires a second (register) argument. ERROR: vlog95.v:20: $ferror's second argument must be a reg (>=640 bits). ERROR: vlog95.v:21: $ferror's second argument must have 640 bit or more. ERROR: vlog95.v:22: $ferror takes two arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/pr2800985b.gold000066400000000000000000000007201435245347300200230ustar00rootroot00000000000000ERROR: ./ivltests/pr2800985b.v:11: $ferror's fd (first) argument must be numeric. ERROR: ./ivltests/pr2800985b.v:12: $ferror requires a second (register) argument. ERROR: ./ivltests/pr2800985b.v:13: $ferror's second argument must be a reg (>=640 bits). ERROR: ./ivltests/pr2800985b.v:14: $ferror's second argument must have 640 bit or more. ERROR: ./ivltests/pr2800985b.v:15: $ferror takes two arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/pr2809288.gold000066400000000000000000000001641435245347300176700ustar00rootroot00000000000000./ivltests/pr2809288.v:5: error: genvar is missing for generate "loop" variable 'i'. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr2815398a.gold000066400000000000000000000001431435245347300200250ustar00rootroot00000000000000./ivltests/pr2815398a.v:65: warning: returning 'bx for out of bounds array access dummy[7]. PASSED iverilog-12_0/ivtest/gold/pr2815398b.gold000066400000000000000000000016111435245347300200270ustar00rootroot00000000000000./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[8]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[9]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[10]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[11]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[12]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[13]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[14]. ./ivltests/pr2815398b.v:39: warning: ignoring out of bounds l-value array access arr[15]. ./ivltests/pr2815398b.v:26: warning: ignoring out of bounds l-value array access arr[20]. ./ivltests/pr2815398b.v:27: warning: ignoring out of bounds l-value array access arr[-1]. PASSED iverilog-12_0/ivtest/gold/pr2823414.gold000066400000000000000000000001411435245347300176460ustar00rootroot00000000000000./ivltests/pr2823414.v:10: error: Enable of unknown task ``fail_at_line_10''. Elaboration failed iverilog-12_0/ivtest/gold/pr2842621.gold000066400000000000000000000003111435245347300176460ustar00rootroot00000000000000 1 2 The result for $fdisplay( 1, ...) is 3 The result for $fwrite( 1, ...) is 4 The $fstrobe( 1, ...) ran. 3 4 PASSED iverilog-12_0/ivtest/gold/pr2848986.gold000066400000000000000000000005751435245347300177060ustar00rootroot00000000000000./ivltests/pr2848986.v:6: error: An event 'evt' can not be a user function argument. ./ivltests/pr2848986.v:6: internal error: Failed to synthesize expression: top.func() ./ivltests/pr2848986.v:25: error: An event 'evt' can not be a user function argument. ./ivltests/pr2848986.v:26: error: An event 'evt' can not be a user task argument. 4 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr2859628.vcd.gold000066400000000000000000000005651435245347300204530ustar00rootroot00000000000000$date Sun May 15 18:19:07 2022 $end $version Icarus Verilog $end $timescale 1s $end $scope module top $end $upscope $end $scope module top $end $var reg 4 ! \array[0] [3:0] $end $upscope $end $scope module top $end $var reg 4 " \array[1] [3:0] $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall $end #0 $dumpvars bx " bx ! $end #1 iverilog-12_0/ivtest/gold/pr2877564.gold000066400000000000000000000001571435245347300176740ustar00rootroot00000000000000./ivltests/pr2877564.v:2: error: Unable to bind parameter `ASDF' in `testbench' 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr2924354.gold000066400000000000000000000000641435245347300176570ustar00rootroot00000000000000foo=1, bar=1 foo=1, bar=1 foo=1, bar=1 foo=1, bar=1 iverilog-12_0/ivtest/gold/pr2972866.gold000066400000000000000000000001541435245347300176720ustar00rootroot000000000000000.000000 x 0 0.690000 0 0 10.000000 0 1 10.730000 1 1 20.000000 1 0 20.690000 0 0 Simulation ran correctly. iverilog-12_0/ivtest/gold/pr2976242c.gold000066400000000000000000000015571435245347300200350ustar00rootroot00000000000000./ivltests/pr2976242c.v:43: error: Port `out` of module `io_real_to_vec` is declared as a real inout port. ./ivltests/pr2976242c.v:11: error: Cannot connect an arrayed instance of module vec_to_real to real signal r_vec. ./ivltests/pr2976242c.v:14: error: When automatically converting a real port of an arrayed instance to a bit signal ./ivltests/pr2976242c.v:14: : the signal width (5) must be an integer multiple of the instance count (2). ./ivltests/pr2976242c.v:15: error: An arrayed instance of arr_real cannot have a real port (port 1 : out) connected to a real signal (r_arr). ./ivltests/pr2976242c.v:18: error: Cannot automatically connect bit based inout port 1 (out) of module io_vec_to_real to real signal r_io. ./ivltests/pr2976242c.v:21: error: No support for connecting real inout ports (port 1 (out) of module io_real_to_vec). 6 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr298.gold000066400000000000000000000000111435245347300173350ustar00rootroot0000000000000000 00 11 iverilog-12_0/ivtest/gold/pr3015421-fsv.gold000066400000000000000000000000631435245347300204350ustar00rootroot00000000000000./ivltests/pr3015421.v:12: syntax error I give up. iverilog-12_0/ivtest/gold/pr3015421.gold000066400000000000000000000002201435245347300176340ustar00rootroot00000000000000./ivltests/pr3015421.v:7: syntax error ./ivltests/pr3015421.v:7: error: Syntax error defining function. ./ivltests/pr3015421.v:16: syntax error iverilog-12_0/ivtest/gold/pr3039548.gold000066400000000000000000000000661435245347300176640ustar00rootroot0000000000000000000001100000000010000000 00000001100000000010000000 iverilog-12_0/ivtest/gold/pr3054101a.gold000066400000000000000000000004671435245347300200100ustar00rootroot00000000000000a[s0]: x b[s0]: x a[s1]: x b[s1]: x a[s2]: x b[s2]: x c[s3]: 1 d[s3]: 0 c[s4]: 1 d[s4]: 0 ap[s0]: x bp[s0]: x ap[s1]: x bp[s1]: x ap[s2]: x bp[s2]: x cp[s3]: 1 dp[s3]: 0 cp[s4]: 1 dp[s4]: 0 ar[s0]: x br[s0]: x ar[s1]: x br[s1]: x ar[s2]: x br[s2]: x cr[s3]: 1 dr[s3]: 0 cr[s4]: 1 dr[s4]: 0 Compare tests passed iverilog-12_0/ivtest/gold/pr3054101c.gold000066400000000000000000000006571435245347300200130ustar00rootroot00000000000000a[s0+:2]: 0x b[s0+:2]: 1x a[s1+:2]: 0x b[s1+:2]: 1x a[s2+:2]: 0x b[s2+:2]: 1x c[s3+:2]: x1 d[s3+:2]: x0 c[s4+:2]: x1 d[s4+:2]: x0 ap[s0+:2]: 0x bp[s0+:2]: 1x ap[s1+:2]: 0x bp[s1+:2]: 1x ap[s2+:2]: 0x bp[s2+:2]: 1x cp[s3+:2]: x1 dp[s3+:2]: x0 cp[s4+:2]: x1 dp[s4+:2]: x0 ar[s0+:2]: 0x br[s0+:2]: 1x ar[s1+:2]: 0x br[s1+:2]: 1x ar[s2+:2]: 0x br[s2+:2]: 1x cr[s3+:2]: x1 dr[s3+:2]: x0 cr[s4+:2]: x1 dr[s4+:2]: x0 Compare tests passed iverilog-12_0/ivtest/gold/pr3054101e.gold000066400000000000000000000006571435245347300200150ustar00rootroot00000000000000a[s0-:2]: 0x b[s0-:2]: 1x a[s1-:2]: 0x b[s1-:2]: 1x a[s2-:2]: 0x b[s2-:2]: 1x c[s3-:2]: x1 d[s3-:2]: x0 c[s4-:2]: x1 d[s4-:2]: x0 ap[s0-:2]: 0x bp[s0-:2]: 1x ap[s1-:2]: 0x bp[s1-:2]: 1x ap[s2-:2]: 0x bp[s2-:2]: 1x cp[s3-:2]: x1 dp[s3-:2]: x0 cp[s4-:2]: x1 dp[s4-:2]: x0 ar[s0-:2]: 0x br[s0-:2]: 1x ar[s1-:2]: 0x br[s1-:2]: 1x ar[s2-:2]: 0x br[s2-:2]: 1x cr[s3-:2]: x1 dr[s3-:2]: x0 cr[s4-:2]: x1 dr[s4-:2]: x0 Compare tests passed iverilog-12_0/ivtest/gold/pr3054101g.gold000066400000000000000000000001761435245347300200130ustar00rootroot00000000000000a[s0]: xx a[s1]: xx a[s2]: xx c[s3]: 11 c[s4]: 11 ar[s0]: xx ar[s1]: xx ar[s2]: xx cr[s3]: 11 cr[s4]: 11 Compare tests passed iverilog-12_0/ivtest/gold/pr3064375.gold000066400000000000000000000012121435245347300176520ustar00rootroot00000000000000CLK 0 RST 1 Reg1 x Reg2 x CLK 1 RST 1 Reg1 0 Reg2 x CLK 0 RST 1 Reg1 0 Reg2 0 CLK 1 RST 1 Reg1 0 Reg2 0 CLK 0 RST 0 Reg1 0 Reg2 0 CLK 1 RST 0 Reg1 1 Reg2 0 CLK 0 RST 0 Reg1 1 Reg2 1 CLK 1 RST 0 Reg1 0 Reg2 1 CLK 0 RST 0 Reg1 0 Reg2 0 CLK 1 RST 0 Reg1 1 Reg2 0 CLK 0 RST 0 Reg1 1 Reg2 1 CLK 1 RST 0 Reg1 0 Reg2 1 CLK 0 RST 0 Reg1 0 Reg2 0 CLK 1 RST 0 Reg1 1 Reg2 0 CLK 0 RST 0 Reg1 1 Reg2 1 CLK 1 RST 0 Reg1 0 Reg2 1 CLK 0 RST 0 Reg1 0 Reg2 0 CLK 1 RST 0 Reg1 1 Reg2 0 CLK 0 RST 0 Reg1 1 Reg2 1 CLK 1 RST 0 Reg1 0 Reg2 1 CLK 0 RST 0 Reg1 0 Reg2 0 CLK 1 RST 0 Reg1 1 Reg2 0 CLK 0 RST 0 Reg1 1 Reg2 1 CLK 1 RST 0 Reg1 0 Reg2 1 CLK 0 RST 0 Reg1 0 Reg2 0 iverilog-12_0/ivtest/gold/pr3149494.gold000066400000000000000000000000241435245347300176600ustar00rootroot00000000000000x = 1 y = 111111111 iverilog-12_0/ivtest/gold/pr3190941.gold000066400000000000000000000004331435245347300176550ustar00rootroot00000000000000./ivltests/pr3190941.v:9: error: expression not valid in assign l-value: 4'bxxxx ./ivltests/pr3190941.v:9: error: Output port expression must support continuous assignment. ./ivltests/pr3190941.v:9: : Port 1 (x) of m1 is connected to {4'bxxxx, y} 2 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr3194155.gold000066400000000000000000000003131435245347300176530ustar00rootroot00000000000000./ivltests/pr3194155.v:13: warning: input port x is coerced to inout. ./ivltests/pr3194155.v:14: warning: input port x is coerced to inout. x(1) : 0 x(2) : 1 x(3) : 0 x(4) : 0 x(5) : 0 y : 0 z : 0 iverilog-12_0/ivtest/gold/pr3194155_std.gold000066400000000000000000000000771435245347300205340ustar00rootroot00000000000000x(1) : 0 x(2) : 1 x(3) : 0 x(4) : 0 x(5) : 0 y : 0 z : 0 iverilog-12_0/ivtest/gold/pr3366217a.gold000066400000000000000000000002001435245347300200070ustar00rootroot00000000000000./ivltests/pr3366217a.v:3: error: Enumeration name some0 has a value that is too large 32'sd100. 2 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr3366217b.gold000066400000000000000000000004451435245347300200230ustar00rootroot00000000000000./ivltests/pr3366217b.v:3: error: Enumeration name nega has a negative value. ./ivltests/pr3366217b.v:3: error: Enumeration name b has an inferred value that overflowed. ./ivltests/pr3366217b.v:3: error: Enumeration name c has an inferred value that overflowed. 4 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr3366217c.gold000066400000000000000000000003271435245347300200230ustar00rootroot00000000000000./ivltests/pr3366217c.v:3: error: Enumeration name b has an inferred value that overflowed. ./ivltests/pr3366217c.v:3: error: Enumeration name c has an inferred value that overflowed. 3 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr3366217d.gold000066400000000000000000000032561435245347300200300ustar00rootroot00000000000000./ivltests/pr3366217d.v:3: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:4: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:5: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:6: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:6: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:7: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:8: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:9: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:10: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:10: error: Undefined value used in enum name sequence. ./ivltests/pr3366217d.v:13: error: Zero count used in enum name sequence. ./ivltests/pr3366217d.v:14: error: Zero count used in enum name sequence. ./ivltests/pr3366217d.v:17: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:18: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:19: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:20: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:20: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:21: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:22: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:23: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:24: error: Negative value used in enum name sequence. ./ivltests/pr3366217d.v:24: error: Negative value used in enum name sequence. iverilog-12_0/ivtest/gold/pr3366217f.gold000066400000000000000000000001541435245347300200240ustar00rootroot00000000000000First: -1 Second: -2 Third: -3 Wrapped: -1 Wrapped: -3 As integer: -3 Compile: -1 iverilog-12_0/ivtest/gold/pr3366217g.gold000066400000000000000000000003341435245347300200250ustar00rootroot00000000000000./ivltests/pr3366217g.v:3: error: Enumeration name blue and green have the same value: 32'sd2 ./ivltests/pr3366217g.v:4: error: Enumeration name third and first have the same value: 32'sd2 3 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr3441576.gold000066400000000000000000000001401435245347300176530ustar00rootroot00000000000000./ivltests/pr3441576.v:3: warning: @* found no sensitivities so it will never trigger. foo is x iverilog-12_0/ivtest/gold/pr3499807.gold000066400000000000000000000001211435245347300176640ustar00rootroot00000000000000 0 0 x x 100 0 0 x 200 0 0 0 iverilog-12_0/ivtest/gold/pr3515542.gold000066400000000000000000000007631435245347300176610ustar00rootroot00000000000000./ivltests/pr3515542.v:5: error: Unbased SystemVerilog literal cannot have a size. ./ivltests/pr3515542.v:6: error: Unbased SystemVerilog literal cannot have a size. ./ivltests/pr3515542.v:7: error: Unbased SystemVerilog literal cannot have a size. ./ivltests/pr3515542.v:8: error: Unbased SystemVerilog literal cannot have a size. ./ivltests/pr3515542.v:9: error: Unbased SystemVerilog literal cannot have a size. ./ivltests/pr3515542.v:10: error: Unbased SystemVerilog literal cannot have a size. iverilog-12_0/ivtest/gold/pr3522653.gold000066400000000000000000000002621435245347300176540ustar00rootroot0000000000000000000000000000000000000000000001 1 11111111111111111111111111111111 4294967295 00000000000000000000000000000001 1 11111111111111111111111111111111 -1 iverilog-12_0/ivtest/gold/pr3527694.gold000066400000000000000000000011061435245347300176640ustar00rootroot00000000000000top.test1.not1.test2_0 big_width: 00000012 top.test1.not1.test2_1 big_width: 00000012 top.test2_top big_width: 00000012 top.test1.not1.test2_0.test3_0 wide: 00000012, width1:00000012, width2:00000012 top.test1.not1.test2_0.test3_1 wide: 00000012, width1:00000012, width2:00000012 top.test1.not1.test2_1.test3_0 wide: 00000012, width1:00000012, width2:00000012 top.test1.not1.test2_1.test3_1 wide: 00000012, width1:00000012, width2:00000012 top.test2_top.test3_0 wide: 00000012, width1:00000012, width2:00000012 top.test2_top.test3_1 wide: 00000012, width1:00000012, width2:00000012 iverilog-12_0/ivtest/gold/pr3571573.gold000066400000000000000000000000071435245347300176560ustar00rootroot00000000000000zzz01z iverilog-12_0/ivtest/gold/pr377.gold000066400000000000000000000000201435245347300173330ustar00rootroot000000000000000 1 2 3 0 1 2 3 iverilog-12_0/ivtest/gold/pr434.gold000066400000000000000000000011301435245347300173300ustar00rootroot00000000000000 0 reset0=x, reset1=x, reset2=x, reset3=x 10 reset0=0, reset1=0, reset2=0, reset3=0 75 reset0=1, reset1=0, reset2=0, reset3=0 105 reset0=0, reset1=0, reset2=0, reset3=0 165 reset0=0, reset1=1, reset2=0, reset3=0 195 reset0=0, reset1=0, reset2=0, reset3=0 225 reset0=0, reset1=0, reset2=1, reset3=0 255 reset0=0, reset1=0, reset2=0, reset3=0 285 reset0=0, reset1=0, reset2=0, reset3=1 315 reset0=0, reset1=0, reset2=0, reset3=0 iverilog-12_0/ivtest/gold/pr487.gold000066400000000000000000000001341435245347300173430ustar00rootroot00000000000000async_wrport[ 1] --> 1 async_wrport[ 2] --> 1 async_wrport[ 3] --> 0 async_wrport[ 4] --> 0 iverilog-12_0/ivtest/gold/pr492.gold000066400000000000000000000002701435245347300173400ustar00rootroot00000000000000000 000 001 fff 002 ffe 003 ffd 004 ffc 005 ffb 006 ffa 007 ff9 008 ff8 009 ff7 00a ff6 00b ff5 00c ff4 00d ff3 00e ff2 00f ff1 010 ff0 011 fef 012 fee 013 fed 014 fec 015 feb 016 fea iverilog-12_0/ivtest/gold/pr498b.gold000066400000000000000000000001431435245347300175070ustar00rootroot00000000000000./ivltests/pr498b.v:23: error: parameter `foo` not found in `main`. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/pr522.gold000066400000000000000000000001321435245347300173270ustar00rootroot00000000000000 ***** simple block disable PASSED ***** ***** complex block & loop disable PASSED ***** iverilog-12_0/ivtest/gold/pr524.gold000066400000000000000000000001531435245347300173340ustar00rootroot00000000000000 0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0 iverilog-12_0/ivtest/gold/pr527.gold000066400000000000000000000021501435245347300173360ustar00rootroot00000000000000 expecting junk,junkbus to be 1 at T=1 then changing to 0 at T=2 then junk is 0 from T=3 to T=11, while junkbus changes to 2 at T=5 and remains 2 through to T=16 junk changes to 2 at T=12 then 2 from T=13 to T=14 then changing to 3 at T=15 then 3 from T=16 on junkbus changes to 3 at T=17 and remains 3 from then on time: 0, a: 01, junk: 01, junkbus: 01 time: 1, a: 01, junk: 01, junkbus: 01 time: 2, a: 01, junk: 00, junkbus: 00 time: 3, a: 01, junk: 00, junkbus: 00 time: 4, a: 01, junk: 00, junkbus: 00 time: 5, a: 10, junk: 00, junkbus: 10 time: 6, a: 10, junk: 00, junkbus: 10 time: 7, a: 10, junk: 00, junkbus: 10 time: 8, a: 10, junk: 00, junkbus: 10 time: 9, a: 10, junk: 00, junkbus: 10 time: 10, a: 10, junk: 00, junkbus: 10 time: 11, a: 10, junk: 00, junkbus: 10 time: 12, a: 10, junk: 10, junkbus: 10 time: 13, a: 10, junk: 10, junkbus: 10 time: 14, a: 10, junk: 10, junkbus: 10 time: 15, a: 11, junk: 11, junkbus: 10 time: 16, a: 11, junk: 11, junkbus: 10 time: 17, a: 11, junk: 11, junkbus: 11 time: 18, a: 11, junk: 11, junkbus: 11 time: 19, a: 11, junk: 11, junkbus: 11 --------- force test passed --------- iverilog-12_0/ivtest/gold/pr528.gold000066400000000000000000000010671435245347300173450ustar00rootroot00000000000000 0 0 x x 50 0 0 0 5000 1 0 0 5050 1 1 1 10000 0 1 1 10050 0 0 0 15000 1 0 0 15050 1 1 1 20000 0 1 1 20050 0 0 0 25000 1 0 0 25050 1 1 1 30000 0 1 1 30050 0 0 0 35000 1 0 0 35050 1 1 1 40000 0 1 1 40050 0 0 0 45000 1 0 0 45050 1 1 1 50000 0 1 1 iverilog-12_0/ivtest/gold/pr528b.gold000066400000000000000000000010671435245347300175070ustar00rootroot00000000000000 0 0 x x 50 0 0 0 5000 1 0 0 5050 1 1 1 10000 0 1 1 10050 0 0 0 15000 1 0 0 15050 1 1 1 20000 0 1 1 20050 0 0 0 25000 1 0 0 25050 1 1 1 30000 0 1 1 30050 0 0 0 35000 1 0 0 35050 1 1 1 40000 0 1 1 40050 0 0 0 45000 1 0 0 45050 1 1 1 50000 0 1 1 iverilog-12_0/ivtest/gold/pr530.gold000066400000000000000000000000501435245347300173250ustar00rootroot00000000000000here in top, time: 0.000000ns iverilog-12_0/ivtest/gold/pr531a.gold000066400000000000000000000034541435245347300175020ustar00rootroot00000000000000 time addr maddr m0 m1 m2 m3 m4 m5 m6 m7 ---- ---- ----- ---- ---- ---- ---- ---- ---- ---- ---- 0 0000 1000 1000 0001 0010 0011 0100 0101 0110 0111 100 0001 0001 1000 0001 0010 0011 0100 0101 0110 0111 200 0010 0010 1000 0001 0010 0011 0100 0101 0110 0111 300 0011 0011 1000 0001 0010 0011 0100 0101 0110 0111 400 0100 0100 1000 0001 0010 0011 0100 0101 0110 0111 500 0101 0101 1000 0001 0010 0011 0100 0101 0110 0111 600 0110 0110 1000 0001 0010 0011 0100 0101 0110 0111 700 0111 0111 1000 0001 0010 0011 0100 0101 0110 0111 800 1000 xxxx 1000 0001 0010 0011 0100 0101 0110 0111 900 001x xxxx 1000 0001 0010 0011 0100 0101 0110 0111 1000 01x0 xxxx 1000 0001 0010 0011 0100 0101 0110 0111 1100 0x01 xxxx 1000 0001 0010 0011 0100 0101 0110 0111 1200 0000 1000 1000 0001 0010 0011 0100 0101 0110 0111 1300 0000 1001 1001 0001 0010 0011 0100 0101 0110 0111 1400 0011 0011 1001 0001 0010 0011 0100 0101 0110 0111 1500 0011 1010 1001 0001 0010 1010 0100 0101 0110 0111 1600 0110 0110 1001 0001 0010 1010 0100 0101 0110 0111 1700 0110 1011 1001 0001 0010 1010 0100 0101 1011 0111 1800 1000 xxxx 1001 0001 0010 1010 0100 0101 1011 0111 2000 010x xxxx 1001 0001 0010 1010 0100 0101 1011 0111 2200 00x1 xxxx 1001 0001 0010 1010 0100 0101 1011 0111 2400 0x10 xxxx 1001 0001 0010 1010 0100 0101 1011 0111 2600 xxxx xxxx 1001 0001 0010 1010 0100 0101 1011 0111 Finish at time 2800 iverilog-12_0/ivtest/gold/pr532.gold000066400000000000000000000021501435245347300173320ustar00rootroot00000000000000 time ix vix vec ---- ---- --- -------- 0 0000 0 00000000 100 0001 0 00000000 200 0010 0 00000000 300 0011 0 00000000 400 0100 0 00000000 500 0101 0 00000000 600 0110 0 00000000 700 0111 0 00000000 800 1000 x 00000000 900 001x x 00000000 1000 01x0 x 00000000 1100 0x01 x 00000000 1200 0000 0 00000000 1300 0000 1 00000001 1400 0000 0 00000000 1500 0011 0 00000000 1600 0011 1 00001000 1700 0011 0 00000000 1800 0110 0 00000000 1900 0110 1 01000000 2000 0110 0 00000000 2100 1000 x 00000000 2400 010x x 00000000 2700 00x1 x 00000000 3000 0x10 x 00000000 3300 xxxx x 00000000 Finish at time 3600 iverilog-12_0/ivtest/gold/pr533.gold000066400000000000000000000002541435245347300173360ustar00rootroot00000000000000x,x,x = ( x | ( xxxxx == xxxxx ) ) ? 0 : 1 0,0,0 = ( 1 | ( xxxxx == xxxxx ) ) ? 0 : 1 0,0,0 = ( 1 | ( 00000 == 00000 ) ) ? 0 : 1 0,0,0 = ( 0 | ( 00000 == 00000 ) ) ? 0 : 1 iverilog-12_0/ivtest/gold/pr534.gold000066400000000000000000000004541435245347300173410ustar00rootroot00000000000000 ==> CHECK THIS DISPLAY ==> pci_clk_period: 15 pci_clk_period: 1500 after setting timeformat: pci_clk_period: 15 pci_clk_period: 15.00ns ********************************************** ****** time representation test OK ******* ********************************************** iverilog-12_0/ivtest/gold/pr538.gold000066400000000000000000000002251435245347300173410ustar00rootroot00000000000000 ********************************************** ********** timescale test PASSED ************* ********************************************** iverilog-12_0/ivtest/gold/pr540.gold000066400000000000000000000003301435245347300173270ustar00rootroot00000000000000 ***** simple block disable PASSED ***** ***** block with loop disable PASSED ***** ***** forked block disable PASSED ***** ***** task with loop disable PASSED ***** ***** task with forked block disable PASSED **** iverilog-12_0/ivtest/gold/pr540b.gold000066400000000000000000000004661435245347300175030ustar00rootroot00000000000000Check disable: ***** simple block PASSED ***** ***** block with loop PASSED ***** ***** forked block PASSED ***** ***** task with loop PASSED ***** ***** task with forked block PASSED ***** ***** one forked block PASSED ***** ***** the other forked block PASSED ***** iverilog-12_0/ivtest/gold/pr540c.gold000066400000000000000000000000401435245347300174700ustar00rootroot00000000000000***** disable test PASSED ***** iverilog-12_0/ivtest/gold/pr541.gold000066400000000000000000000003101435245347300173260ustar00rootroot00000000000000000000[5:0] = - 000[2:0] 111111[5:0] = - 001[2:0] 111110[5:0] = - 010[2:0] 111101[5:0] = - 011[2:0] 111100[5:0] = - 100[2:0] 111011[5:0] = - 101[2:0] 111010[5:0] = - 110[2:0] 111001[5:0] = - 111[2:0] iverilog-12_0/ivtest/gold/pr542.gold000066400000000000000000000000461435245347300173350ustar00rootroot00000000000000d_pm_in_dac_st = 1 d_pm_in_dac_st = 1 iverilog-12_0/ivtest/gold/pr544.gold000066400000000000000000000012051435245347300173350ustar00rootroot00000000000000 0 Pu:0/0 St:0/0 Y:z,HiZ 100 Pu:0/x St:0/0 Y:x,PuL 200 Pu:0/0 St:0/x Y:x,StL 300 Pu:1/x St:0/0 Y:x,PuH 400 Pu:0/0 St:1/x Y:x,StH 500 Pu:0/1 St:0/0 Y:0,Pu0 600 Pu:0/0 St:0/1 Y:0,St0 700 Pu:1/1 St:0/0 Y:1,Pu1 800 Pu:0/0 St:1/1 Y:1,St1 900 Pu:x/1 St:0/0 Y:x,PuX 1000 Pu:0/0 St:x/1 Y:x,StX 1100 Pu:0/1 St:0/x Y:0,650 1200 Pu:x/1 St:0/x Y:x,65X 1300 Pu:1/1 St:1/x Y:1,651 1400 Pu:x/1 St:1/x Y:x,56X iverilog-12_0/ivtest/gold/pr547.gold000066400000000000000000000000171435245347300173400ustar00rootroot00000000000000A = 3ff, b = x iverilog-12_0/ivtest/gold/pr556.gold000066400000000000000000000204001435245347300173360ustar00rootroot00000000000000The random number is 36 The random number is -127 The random number is -247 The random number is -157 The random number is 13 The random number is 141 The random number is -155 The random number is -238 The random number is 1 The random number is 13 The random number is 118 The random number is 61 The random number is 237 The random number is 140 The random number is 249 The random number is -58 The random number is -59 The random number is -86 The random number is 229 The random number is -137 The random number is -238 The random number is 143 The random number is 242 The random number is -50 The random number is -24 The random number is -59 The random number is 92 The random number is -67 The random number is -211 The random number is -155 The random number is -157 The random number is 10 The random number is -128 The random number is 32 The random number is 170 The random number is -99 The random number is -106 The random number is -237 The random number is -243 The random number is -173 The random number is 107 The random number is -43 The random number is -254 The random number is -82 The random number is 29 The random number is -49 The random number is 35 The random number is 10 The random number is -54 The random number is -196 The random number is 242 The random number is 138 The random number is 65 The random number is -40 The random number is 120 The random number is -119 The random number is 235 The random number is 182 The random number is 198 The random number is 174 The random number is -68 The random number is 42 The random number is -245 The random number is -143 The random number is 133 The random number is 79 The random number is -197 The random number is 58 The random number is -130 The random number is 21 The random number is 241 The random number is 217 The random number is 98 The random number is 76 The random number is 159 The random number is 143 The random number is 248 The random number is -73 The random number is -97 The random number is -164 The random number is -165 The random number is 137 The random number is -183 The random number is -48 The random number is -41 The random number is -175 The random number is 150 The random number is 12 The random number is -62 The random number is 200 The random number is -137 The random number is 61 The random number is 18 The random number is -130 The random number is 109 The random number is 57 The random number is 31 The random number is -45 The random number is 133 The random number is -136 The random number is 91 The random number is 73 The random number is -193 The random number is 42 The random number is 88 The random number is -122 The random number is -114 The random number is -100 The random number is 250 The random number is -218 The random number is 115 The random number is -93 The random number is -209 The random number is -77 The random number is -161 The random number is 68 The random number is 247 The random number is -53 The random number is -26 The random number is 90 The random number is 41 The random number is -19 The random number is -38 The random number is -155 The random number is -75 The random number is -33 The random number is 121 The random number is 68 The random number is -48 The random number is 42 The random number is 171 The random number is 14 The random number is 220 The random number is -102 The random number is -3 The random number is -61 The random number is 86 The random number is 78 The random number is -153 The random number is -246 The random number is 182 The random number is -200 The random number is 121 The random number is -72 The random number is 148 The random number is 147 The random number is -252 The random number is -167 The random number is 219 The random number is -179 The random number is 217 The random number is -147 The random number is -138 The random number is 202 The random number is 182 The random number is 149 The random number is -186 The random number is 4 The random number is 247 The random number is 105 The random number is -76 The random number is 136 The random number is 40 The random number is -211 The random number is -57 The random number is -210 The random number is -248 The random number is 28 The random number is -3 The random number is 41 The random number is -228 The random number is 134 The random number is -38 The random number is -195 The random number is 102 The random number is -144 The random number is -141 The random number is 186 The random number is 94 The random number is 250 The random number is 213 The random number is -230 The random number is -71 The random number is 55 The random number is 150 The random number is 192 The random number is 38 The random number is -74 The random number is 125 The random number is 220 The random number is 134 The random number is 120 The random number is 126 The random number is -37 The random number is -49 The random number is 121 The random number is -6 The random number is -159 The random number is 23 The random number is -95 The random number is 134 The random number is -176 The random number is 245 The random number is -203 The random number is -215 The random number is 193 The random number is -59 The random number is -104 The random number is 75 The random number is -141 The random number is -20 The random number is -118 The random number is 78 The random number is -88 The random number is 169 The random number is -95 The random number is 14 The random number is -26 The random number is -97 The random number is 42 The random number is 42 The random number is -115 The random number is 158 The random number is -200 The random number is -135 The random number is 200 The random number is 202 The random number is 19 The random number is 107 The random number is -57 The random number is 182 The random number is 186 The random number is 196 The random number is 185 The random number is 146 The random number is -76 The random number is 127 The random number is -122 The random number is 250 The random number is -14 The random number is 50 The random number is -67 The random number is 132 The random number is -28 The random number is 202 The random number is 169 The random number is -95 The random number is 142 The random number is -5 The random number is -245 The random number is -17 The random number is 201 The random number is 54 The random number is -139 The random number is -113 The random number is 107 iverilog-12_0/ivtest/gold/pr569.gold000066400000000000000000000000311435245347300173400ustar00rootroot00000000000000010101010101010101010101 iverilog-12_0/ivtest/gold/pr572.gold000066400000000000000000000000751435245347300173420ustar00rootroot00000000000000at 10: toplevel event triggered at 25: local event triggered iverilog-12_0/ivtest/gold/pr584.gold000066400000000000000000000000171435245347300173410ustar00rootroot0000000000000020 20 20 20 20 iverilog-12_0/ivtest/gold/pr584_std.gold000066400000000000000000000000741435245347300202160ustar00rootroot00000000000000 20 20 20 20 20 iverilog-12_0/ivtest/gold/pr590.gold000066400000000000000000000004261435245347300173420ustar00rootroot00000000000000 starting the testbench out: 0000, in: 0000 10..................clock tickling out: 0011, in: 0010 30..................clock tickling 50..................clock tickling 70..................clock tickling iverilog-12_0/ivtest/gold/pr594.gold000066400000000000000000000003221435245347300173410ustar00rootroot00000000000000RSData=30 RSData=48 RSData=31 RSData=64 RSData=32 RSData=6a RSData=33 RSData=69 RSData=34 RSData=6b RSData=20 RSData=35 RSData=52 RSData=36 RSData=69 RSData=37 RSData=6b RSData=38 RSData=64 RSData=39 RSData=5b iverilog-12_0/ivtest/gold/pr596.gold000066400000000000000000000006711435245347300173520ustar00rootroot00000000000000out=0000 out=0100 out=0101 out=0111 out=0011 out=0111 out=0010 out=0101 out=0110 out=0001 out=0011 out=0110 out=0000 out=0001 out=0010 out=0100 out=0000 out=0100 out=0101 out=0111 out=0011 out=0111 out=0010 out=0101 out=0110 out=0001 out=0011 out=0110 out=0000 out=0001 out=0010 out=0100 out=0000 out=0100 out=0101 out=0111 out=0011 out=0111 out=0010 out=0101 out=0110 out=0001 out=0011 out=0110 out=0000 out=0001 out=0010 out=0100 out=0000 iverilog-12_0/ivtest/gold/pr622.gold000066400000000000000000000000201435245347300173240ustar00rootroot00000000000000macro FOO = bar iverilog-12_0/ivtest/gold/pr632.gold000066400000000000000000000003701435245347300173350ustar00rootroot00000000000000a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 a1[0]=0 a1[0]=1 iverilog-12_0/ivtest/gold/pr639.gold000066400000000000000000000007501435245347300173460ustar00rootroot00000000000000integer & real periods: 'd15 'd15 integer & real periods (15.00, 15.20): 't15.00ns 't15.20ns ......... 15.2 should be displayed as 15.20 in its timeformat. integer & real periods: 'b1111 'b1111 integer & real periods: 'hf 'hf $time is in ns time (1, 1h): 'd1, 't1.00ns, 'h1 $simtime is in 10 ps simtime (100, 64h): 'd100, 't100.00ns, 'h64 ********************************************** ****** time precision test PASSED ******* ********************************************** iverilog-12_0/ivtest/gold/pr673.gold000066400000000000000000000001001435245347300173310ustar00rootroot00000000000000init right right 10 10 bye. iverilog-12_0/ivtest/gold/pr693.gold000066400000000000000000000002601435245347300173420ustar00rootroot00000000000000in=0000; co/sum = 0/0 in=0001; co/sum = 0/1 in=0010; co/sum = 0/1 in=0011; co/sum = 1/0 in=0100; co/sum = 0/1 in=0101; co/sum = 1/0 in=0110; co/sum = 1/0 in=0111; co/sum = 1/1 iverilog-12_0/ivtest/gold/pr729.gold000066400000000000000000000000651435245347300173450ustar00rootroot00000000000000p_real=1.234500, v_real=1.234500, v_real_x2=2.469000 iverilog-12_0/ivtest/gold/pr751.gold000066400000000000000000000003161435245347300173370ustar00rootroot00000000000000./ivltests/pr751.v:10: warning: @* is sensitive to all bits in 'in[0:3]'. 0 xxxx[xx]: x 10 0100[xx]: x 20 0100[00]: 0 30 0100[01]: 1 iverilog-12_0/ivtest/gold/pr751_std.gold000066400000000000000000000002041435245347300202050ustar00rootroot00000000000000 0 xxxx[xx]: x 10 0100[xx]: x 20 0100[00]: 0 30 0100[01]: 1 iverilog-12_0/ivtest/gold/pr812.gold000066400000000000000000000001541435245347300173350ustar00rootroot00000000000000tp = 10.000000, tp2 = 10.000000 tp == 10, (expected) tp = 1 in top tp = 10.000000, tp2 = 10.000000 iverilog-12_0/ivtest/gold/pr820.gold000066400000000000000000000442501435245347300173410ustar00rootroot00000000000000 10 waddr wdata 0 0 raddr rdata 14 x 20 waddr wdata 1 3 raddr rdata 15 x 30 waddr wdata 2 6 raddr rdata 0 x 40 waddr wdata 3 9 raddr rdata 1 0 50 waddr wdata 4 12 raddr rdata 2 3 60 waddr wdata 5 15 raddr rdata 3 6 70 waddr wdata 6 18 raddr rdata 4 9 80 waddr wdata 7 21 raddr rdata 5 12 90 waddr wdata 8 24 raddr rdata 6 15 100 waddr wdata 9 27 raddr rdata 7 18 110 waddr wdata 10 30 raddr rdata 8 21 120 waddr wdata 11 33 raddr rdata 9 24 130 waddr wdata 12 36 raddr rdata 10 27 140 waddr wdata 13 39 raddr rdata 11 30 150 waddr wdata 14 42 raddr rdata 12 33 160 waddr wdata 15 45 raddr rdata 13 36 170 waddr wdata 0 48 raddr rdata 14 39 180 waddr wdata 1 51 raddr rdata 15 42 190 waddr wdata 2 54 raddr rdata 0 45 200 waddr wdata 3 57 raddr rdata 1 48 210 waddr wdata 4 60 raddr rdata 2 51 220 waddr wdata 5 63 raddr rdata 3 54 230 waddr wdata 6 66 raddr rdata 4 57 240 waddr wdata 7 69 raddr rdata 5 60 250 waddr wdata 8 72 raddr rdata 6 63 260 waddr wdata 9 75 raddr rdata 7 66 270 waddr wdata 10 78 raddr rdata 8 69 280 waddr wdata 11 81 raddr rdata 9 72 290 waddr wdata 12 84 raddr rdata 10 75 300 waddr wdata 13 87 raddr rdata 11 78 310 waddr wdata 14 90 raddr rdata 12 81 320 waddr wdata 15 93 raddr rdata 13 84 330 waddr wdata 0 96 raddr rdata 14 87 340 waddr wdata 1 99 raddr rdata 15 90 350 waddr wdata 2 102 raddr rdata 0 93 360 waddr wdata 3 105 raddr rdata 1 96 370 waddr wdata 4 108 raddr rdata 2 99 380 waddr wdata 5 111 raddr rdata 3 102 390 waddr wdata 6 114 raddr rdata 4 105 400 waddr wdata 7 117 raddr rdata 5 108 410 waddr wdata 8 120 raddr rdata 6 111 420 waddr wdata 9 123 raddr rdata 7 114 430 waddr wdata 10 126 raddr rdata 8 117 440 waddr wdata 11 129 raddr rdata 9 120 450 waddr wdata 12 132 raddr rdata 10 123 460 waddr wdata 13 135 raddr rdata 11 126 470 waddr wdata 14 138 raddr rdata 12 129 480 waddr wdata 15 141 raddr rdata 13 132 490 waddr wdata 0 144 raddr rdata 14 135 500 waddr wdata 1 147 raddr rdata 15 138 510 waddr wdata 2 150 raddr rdata 0 141 520 waddr wdata 3 153 raddr rdata 1 144 530 waddr wdata 4 156 raddr rdata 2 147 540 waddr wdata 5 159 raddr rdata 3 150 550 waddr wdata 6 162 raddr rdata 4 153 560 waddr wdata 7 165 raddr rdata 5 156 570 waddr wdata 8 168 raddr rdata 6 159 580 waddr wdata 9 171 raddr rdata 7 162 590 waddr wdata 10 174 raddr rdata 8 165 600 waddr wdata 11 177 raddr rdata 9 168 610 waddr wdata 12 180 raddr rdata 10 171 620 waddr wdata 13 183 raddr rdata 11 174 630 waddr wdata 14 186 raddr rdata 12 177 640 waddr wdata 15 189 raddr rdata 13 180 650 waddr wdata 0 192 raddr rdata 14 183 660 waddr wdata 1 195 raddr rdata 15 186 670 waddr wdata 2 198 raddr rdata 0 189 680 waddr wdata 3 201 raddr rdata 1 192 690 waddr wdata 4 204 raddr rdata 2 195 700 waddr wdata 5 207 raddr rdata 3 198 710 waddr wdata 6 210 raddr rdata 4 201 720 waddr wdata 7 213 raddr rdata 5 204 730 waddr wdata 8 216 raddr rdata 6 207 740 waddr wdata 9 219 raddr rdata 7 210 750 waddr wdata 10 222 raddr rdata 8 213 760 waddr wdata 11 225 raddr rdata 9 216 770 waddr wdata 12 228 raddr rdata 10 219 780 waddr wdata 13 231 raddr rdata 11 222 790 waddr wdata 14 234 raddr rdata 12 225 800 waddr wdata 15 237 raddr rdata 13 228 810 waddr wdata 0 240 raddr rdata 14 231 820 waddr wdata 1 243 raddr rdata 15 234 830 waddr wdata 2 246 raddr rdata 0 237 840 waddr wdata 3 249 raddr rdata 1 240 850 waddr wdata 4 252 raddr rdata 2 243 860 waddr wdata 5 255 raddr rdata 3 246 870 waddr wdata 6 2 raddr rdata 4 249 880 waddr wdata 7 5 raddr rdata 5 252 890 waddr wdata 8 8 raddr rdata 6 255 900 waddr wdata 9 11 raddr rdata 7 2 910 waddr wdata 10 14 raddr rdata 8 5 920 waddr wdata 11 17 raddr rdata 9 8 930 waddr wdata 12 20 raddr rdata 10 11 940 waddr wdata 13 23 raddr rdata 11 14 950 waddr wdata 14 26 raddr rdata 12 17 960 waddr wdata 15 29 raddr rdata 13 20 970 waddr wdata 0 32 raddr rdata 14 23 980 waddr wdata 1 35 raddr rdata 15 26 990 waddr wdata 2 38 raddr rdata 0 29 1000 waddr wdata 3 41 raddr rdata 1 32 1010 waddr wdata 4 44 raddr rdata 2 35 1020 waddr wdata 5 47 raddr rdata 3 38 1030 waddr wdata 6 50 raddr rdata 4 41 1040 waddr wdata 7 53 raddr rdata 5 44 1050 waddr wdata 8 56 raddr rdata 6 47 1060 waddr wdata 9 59 raddr rdata 7 50 1070 waddr wdata 10 62 raddr rdata 8 53 1080 waddr wdata 11 65 raddr rdata 9 56 1090 waddr wdata 12 68 raddr rdata 10 59 1100 waddr wdata 13 71 raddr rdata 11 62 1110 waddr wdata 14 74 raddr rdata 12 65 1120 waddr wdata 15 77 raddr rdata 13 68 1130 waddr wdata 0 80 raddr rdata 14 71 1140 waddr wdata 1 83 raddr rdata 15 74 1150 waddr wdata 2 86 raddr rdata 0 77 1160 waddr wdata 3 89 raddr rdata 1 80 1170 waddr wdata 4 92 raddr rdata 2 83 1180 waddr wdata 5 95 raddr rdata 3 86 1190 waddr wdata 6 98 raddr rdata 4 89 1200 waddr wdata 7 101 raddr rdata 5 92 1210 waddr wdata 8 104 raddr rdata 6 95 1220 waddr wdata 9 107 raddr rdata 7 98 1230 waddr wdata 10 110 raddr rdata 8 101 1240 waddr wdata 11 113 raddr rdata 9 104 1250 waddr wdata 12 116 raddr rdata 10 107 1260 waddr wdata 13 119 raddr rdata 11 110 1270 waddr wdata 14 122 raddr rdata 12 113 1280 waddr wdata 15 125 raddr rdata 13 116 1290 waddr wdata 0 128 raddr rdata 14 119 1300 waddr wdata 1 131 raddr rdata 15 122 1310 waddr wdata 2 134 raddr rdata 0 125 1320 waddr wdata 3 137 raddr rdata 1 128 1330 waddr wdata 4 140 raddr rdata 2 131 1340 waddr wdata 5 143 raddr rdata 3 134 1350 waddr wdata 6 146 raddr rdata 4 137 1360 waddr wdata 7 149 raddr rdata 5 140 1370 waddr wdata 8 152 raddr rdata 6 143 1380 waddr wdata 9 155 raddr rdata 7 146 1390 waddr wdata 10 158 raddr rdata 8 149 1400 waddr wdata 11 161 raddr rdata 9 152 1410 waddr wdata 12 164 raddr rdata 10 155 1420 waddr wdata 13 167 raddr rdata 11 158 1430 waddr wdata 14 170 raddr rdata 12 161 1440 waddr wdata 15 173 raddr rdata 13 164 1450 waddr wdata 0 176 raddr rdata 14 167 1460 waddr wdata 1 179 raddr rdata 15 170 1470 waddr wdata 2 182 raddr rdata 0 173 1480 waddr wdata 3 185 raddr rdata 1 176 1490 waddr wdata 4 188 raddr rdata 2 179 1500 waddr wdata 5 191 raddr rdata 3 182 1510 waddr wdata 6 194 raddr rdata 4 185 1520 waddr wdata 7 197 raddr rdata 5 188 1530 waddr wdata 8 200 raddr rdata 6 191 1540 waddr wdata 9 203 raddr rdata 7 194 1550 waddr wdata 10 206 raddr rdata 8 197 1560 waddr wdata 11 209 raddr rdata 9 200 1570 waddr wdata 12 212 raddr rdata 10 203 1580 waddr wdata 13 215 raddr rdata 11 206 1590 waddr wdata 14 218 raddr rdata 12 209 1600 waddr wdata 15 221 raddr rdata 13 212 1610 waddr wdata 0 224 raddr rdata 14 215 1620 waddr wdata 1 227 raddr rdata 15 218 1630 waddr wdata 2 230 raddr rdata 0 221 1640 waddr wdata 3 233 raddr rdata 1 224 1650 waddr wdata 4 236 raddr rdata 2 227 1660 waddr wdata 5 239 raddr rdata 3 230 1670 waddr wdata 6 242 raddr rdata 4 233 1680 waddr wdata 7 245 raddr rdata 5 236 1690 waddr wdata 8 248 raddr rdata 6 239 1700 waddr wdata 9 251 raddr rdata 7 242 1710 waddr wdata 10 254 raddr rdata 8 245 1720 waddr wdata 11 1 raddr rdata 9 248 1730 waddr wdata 12 4 raddr rdata 10 251 1740 waddr wdata 13 7 raddr rdata 11 254 1750 waddr wdata 14 10 raddr rdata 12 1 1760 waddr wdata 15 13 raddr rdata 13 4 1770 waddr wdata 0 16 raddr rdata 14 7 1780 waddr wdata 1 19 raddr rdata 15 10 1790 waddr wdata 2 22 raddr rdata 0 13 1800 waddr wdata 3 25 raddr rdata 1 16 1810 waddr wdata 4 28 raddr rdata 2 19 1820 waddr wdata 5 31 raddr rdata 3 22 1830 waddr wdata 6 34 raddr rdata 4 25 1840 waddr wdata 7 37 raddr rdata 5 28 1850 waddr wdata 8 40 raddr rdata 6 31 1860 waddr wdata 9 43 raddr rdata 7 34 1870 waddr wdata 10 46 raddr rdata 8 37 1880 waddr wdata 11 49 raddr rdata 9 40 1890 waddr wdata 12 52 raddr rdata 10 43 1900 waddr wdata 13 55 raddr rdata 11 46 1910 waddr wdata 14 58 raddr rdata 12 49 1920 waddr wdata 15 61 raddr rdata 13 52 1930 waddr wdata 0 64 raddr rdata 14 55 1940 waddr wdata 1 67 raddr rdata 15 58 1950 waddr wdata 2 70 raddr rdata 0 61 1960 waddr wdata 3 73 raddr rdata 1 64 1970 waddr wdata 4 76 raddr rdata 2 67 1980 waddr wdata 5 79 raddr rdata 3 70 1990 waddr wdata 6 82 raddr rdata 4 73 2000 waddr wdata 7 85 raddr rdata 5 76 2010 waddr wdata 8 88 raddr rdata 6 79 2020 waddr wdata 9 91 raddr rdata 7 82 2030 waddr wdata 10 94 raddr rdata 8 85 2040 waddr wdata 11 97 raddr rdata 9 88 2050 waddr wdata 12 100 raddr rdata 10 91 2060 waddr wdata 13 103 raddr rdata 11 94 2070 waddr wdata 14 106 raddr rdata 12 97 2080 waddr wdata 15 109 raddr rdata 13 100 2090 waddr wdata 0 112 raddr rdata 14 103 2100 waddr wdata 1 115 raddr rdata 15 106 2110 waddr wdata 2 118 raddr rdata 0 109 2120 waddr wdata 3 121 raddr rdata 1 112 2130 waddr wdata 4 124 raddr rdata 2 115 2140 waddr wdata 5 127 raddr rdata 3 118 2150 waddr wdata 6 130 raddr rdata 4 121 2160 waddr wdata 7 133 raddr rdata 5 124 2170 waddr wdata 8 136 raddr rdata 6 127 2180 waddr wdata 9 139 raddr rdata 7 130 2190 waddr wdata 10 142 raddr rdata 8 133 2200 waddr wdata 11 145 raddr rdata 9 136 2210 waddr wdata 12 148 raddr rdata 10 139 2220 waddr wdata 13 151 raddr rdata 11 142 2230 waddr wdata 14 154 raddr rdata 12 145 2240 waddr wdata 15 157 raddr rdata 13 148 2250 waddr wdata 0 160 raddr rdata 14 151 2260 waddr wdata 1 163 raddr rdata 15 154 2270 waddr wdata 2 166 raddr rdata 0 157 2280 waddr wdata 3 169 raddr rdata 1 160 2290 waddr wdata 4 172 raddr rdata 2 163 2300 waddr wdata 5 175 raddr rdata 3 166 2310 waddr wdata 6 178 raddr rdata 4 169 2320 waddr wdata 7 181 raddr rdata 5 172 2330 waddr wdata 8 184 raddr rdata 6 175 2340 waddr wdata 9 187 raddr rdata 7 178 2350 waddr wdata 10 190 raddr rdata 8 181 2360 waddr wdata 11 193 raddr rdata 9 184 2370 waddr wdata 12 196 raddr rdata 10 187 2380 waddr wdata 13 199 raddr rdata 11 190 2390 waddr wdata 14 202 raddr rdata 12 193 2400 waddr wdata 15 205 raddr rdata 13 196 2410 waddr wdata 0 208 raddr rdata 14 199 2420 waddr wdata 1 211 raddr rdata 15 202 2430 waddr wdata 2 214 raddr rdata 0 205 2440 waddr wdata 3 217 raddr rdata 1 208 2450 waddr wdata 4 220 raddr rdata 2 211 2460 waddr wdata 5 223 raddr rdata 3 214 2470 waddr wdata 6 226 raddr rdata 4 217 2480 waddr wdata 7 229 raddr rdata 5 220 2490 waddr wdata 8 232 raddr rdata 6 223 2500 waddr wdata 9 235 raddr rdata 7 226 2510 waddr wdata 10 238 raddr rdata 8 229 2520 waddr wdata 11 241 raddr rdata 9 232 2530 waddr wdata 12 244 raddr rdata 10 235 2540 waddr wdata 13 247 raddr rdata 11 238 2550 waddr wdata 14 250 raddr rdata 12 241 2560 waddr wdata 15 253 raddr rdata 13 244 2570 waddr wdata 0 0 raddr rdata 14 247 2580 waddr wdata 1 3 raddr rdata 15 250 2590 waddr wdata 2 6 raddr rdata 0 253 2600 waddr wdata 3 9 raddr rdata 1 0 2610 waddr wdata 4 12 raddr rdata 2 3 2620 waddr wdata 5 15 raddr rdata 3 6 2630 waddr wdata 6 18 raddr rdata 4 9 2640 waddr wdata 7 21 raddr rdata 5 12 2650 waddr wdata 8 24 raddr rdata 6 15 2660 waddr wdata 9 27 raddr rdata 7 18 2670 waddr wdata 10 30 raddr rdata 8 21 2680 waddr wdata 11 33 raddr rdata 9 24 2690 waddr wdata 12 36 raddr rdata 10 27 2700 waddr wdata 13 39 raddr rdata 11 30 2710 waddr wdata 14 42 raddr rdata 12 33 2720 waddr wdata 15 45 raddr rdata 13 36 2730 waddr wdata 0 48 raddr rdata 14 39 2740 waddr wdata 1 51 raddr rdata 15 42 2750 waddr wdata 2 54 raddr rdata 0 45 2760 waddr wdata 3 57 raddr rdata 1 48 2770 waddr wdata 4 60 raddr rdata 2 51 2780 waddr wdata 5 63 raddr rdata 3 54 2790 waddr wdata 6 66 raddr rdata 4 57 2800 waddr wdata 7 69 raddr rdata 5 60 2810 waddr wdata 8 72 raddr rdata 6 63 2820 waddr wdata 9 75 raddr rdata 7 66 2830 waddr wdata 10 78 raddr rdata 8 69 2840 waddr wdata 11 81 raddr rdata 9 72 2850 waddr wdata 12 84 raddr rdata 10 75 2860 waddr wdata 13 87 raddr rdata 11 78 2870 waddr wdata 14 90 raddr rdata 12 81 2880 waddr wdata 15 93 raddr rdata 13 84 2890 waddr wdata 0 96 raddr rdata 14 87 2900 waddr wdata 1 99 raddr rdata 15 90 2910 waddr wdata 2 102 raddr rdata 0 93 2920 waddr wdata 3 105 raddr rdata 1 96 2930 waddr wdata 4 108 raddr rdata 2 99 2940 waddr wdata 5 111 raddr rdata 3 102 2950 waddr wdata 6 114 raddr rdata 4 105 2960 waddr wdata 7 117 raddr rdata 5 108 2970 waddr wdata 8 120 raddr rdata 6 111 2980 waddr wdata 9 123 raddr rdata 7 114 2990 waddr wdata 10 126 raddr rdata 8 117 3000 waddr wdata 11 129 raddr rdata 9 120 iverilog-12_0/ivtest/gold/pr902.gold000066400000000000000000000000401435245347300173270ustar00rootroot00000000000000 0 0 0 0 iverilog-12_0/ivtest/gold/pr905.gold000066400000000000000000000000661435245347300173420ustar00rootroot0000000000000000000063 00000000143 00000000000000000000000001100011 iverilog-12_0/ivtest/gold/pr910-vlog95.gold000066400000000000000000000003151435245347300204560ustar00rootroot00000000000000./ivltests/pr910.v:27: vlog95 warning: Duplicate name (cin) found for nexus (b) ./ivltests/pr910.v:27: vlog95 warning: Duplicate name (cin) found for nexus (b) 0000 00 1000 00 0000 00 1000 00 0000 00 iverilog-12_0/ivtest/gold/pr910.gold000066400000000000000000000000551435245347300173340ustar00rootroot000000000000000000 00 1000 00 0000 00 1000 00 0000 00 iverilog-12_0/ivtest/gold/pr923.gold000066400000000000000000000012651435245347300173440ustar00rootroot00000000000000 0 p1=x p2=StX 5 p1=1 p2=StX 10 p1=0 p2=St0 15 p1=1 p2=St0 20 p1=0 p2=St0 25 p1=1 p2=St0 30 p1=0 p2=St0 35 p1=1 p2=St0 40 p1=0 p2=St0 45 p1=1 p2=St0 50 p1=0 p2=St0 55 p1=1 p2=St0 60 p1=0 p2=St0 65 p1=1 p2=St0 70 p1=0 p2=St0 75 p1=1 p2=St0 80 p1=0 p2=St0 85 p1=1 p2=St0 90 p1=0 p2=St0 95 p1=1 p2=St0 100 p1=0 p2=St0 iverilog-12_0/ivtest/gold/pr938.gold000066400000000000000000000001561435245347300173500ustar00rootroot00000000000000A B S out 0 0 0 --> 0 1 0 0 --> 1 0 1 0 --> 0 1 1 0 --> 1 0 0 1 --> 0 1 0 1 --> 0 0 1 1 --> 1 1 1 1 --> 1 iverilog-12_0/ivtest/gold/pr979.gold000066400000000000000000000005451435245347300173570ustar00rootroot000000000000000.250000 0011111111010000000000000000000000000000000000000000000000000000 0.250000 0.500000 0011111111100000000000000000000000000000000000000000000000000000 0.500000 neg reals don't work -0.250000 1011111111010000000000000000000000000000000000000000000000000000 -0.250000 -0.500000 1011111111100000000000000000000000000000000000000000000000000000 -0.500000 iverilog-12_0/ivtest/gold/pr985.gold000066400000000000000000000001171435245347300173470ustar00rootroot00000000000000GRANDCHILD parameters are: 00000008 10 1f CHILD parameters are: 00000008 10 1f iverilog-12_0/ivtest/gold/pr987.gold000066400000000000000000000002551435245347300173540ustar00rootroot00000000000000./ivltests/pr987.v:12: warning: wait expression is constant false. ./ivltests/pr987.v:12: : The statement will block permanently. Test thread runs. Test thread runs. iverilog-12_0/ivtest/gold/pr987_std.gold000066400000000000000000000000441435245347300202220ustar00rootroot00000000000000Test thread runs. Test thread runs. iverilog-12_0/ivtest/gold/pr991.gold000066400000000000000000000000121435245347300173360ustar00rootroot000000000000000 0 1 0 1 iverilog-12_0/ivtest/gold/pr993.gold000066400000000000000000000035161435245347300173540ustar00rootroot00000000000000length= 1, length_bits= 1 ( 1) length= 2, length_bits= 2 ( 2) length= 3, length_bits= 3 ( 3) length= 4, length_bits= 3 ( 3) length= 5, length_bits= 4 ( 4) length= 6, length_bits= 5 ( 5) length= 7, length_bits= 6 ( 6) length= 8, length_bits= 6 ( 6) length= 9, length_bits= 7 ( 7) length= 10, length_bits= 8 ( 8) length= 11, length_bits= 8 ( 8) length= 12, length_bits= 9 ( 9) length= 13, length_bits= 10 ( 10) length= 14, length_bits= 11 ( 11) length= 15, length_bits= 11 ( 11) length= 16, length_bits= 12 ( 12) length= 17, length_bits= 13 ( 13) length= 18, length_bits= 14 ( 14) length= 19, length_bits= 14 ( 14) length= 20, length_bits= 15 ( 15) length= 21, length_bits= 16 ( 16) length= 22, length_bits= 16 ( 16) length= 23, length_bits= 17 ( 17) length= 24, length_bits= 18 ( 18) length= 25, length_bits= 19 ( 19) length= 26, length_bits= 19 ( 19) length= 27, length_bits= 20 ( 20) length= 28, length_bits= 21 ( 21) length= 29, length_bits= 22 ( 22) length= 30, length_bits= 22 ( 22) length= 31, length_bits= 23 ( 23) length= 32, length_bits= 24 ( 24) length= 33, length_bits= 24 ( 24) length= 34, length_bits= 25 ( 25) length= 35, length_bits= 26 ( 26) length= 36, length_bits= 27 ( 27) length= 37, length_bits= 27 ( 27) length= 38, length_bits= 28 ( 28) length= 39, length_bits= 29 ( 29) length= 40, length_bits= 30 ( 30) length= 41, length_bits= 30 ( 30) length= 42, length_bits= 31 ( 31) length= 43, length_bits= 32 ( 32) length= 44, length_bits= 32 ( 32) length= 45, length_bits= 33 ( 33) length= 46, length_bits= 34 ( 34) length= 47, length_bits= 35 ( 35) length= 48, length_bits= 35 ( 35) length= 49, length_bits= 36 ( 36) length= 50, length_bits= 37 ( 37) length= 51, length_bits= 38 ( 38) length= 52, length_bits= 38 ( 38) length= 53, length_bits= 39 ( 39) length= 54, length_bits= 40 ( 40) length= 55, length_bits= 40 ( 40) iverilog-12_0/ivtest/gold/pr995.gold000066400000000000000000000055001435245347300173510ustar00rootroot00000000000000Start sequence: seed=00000001 seed=00010dce result=80010e00 seed=1c5983f7 result=9c598438 seed=c35937cc result=43593986 seed=2e130a5d result=ae130c5c seed=e723057a result=672307ce seed=e3cc94b3 result=63cc97c7 seed=63132a58 result=e3132cc6 seed=79d76079 result=f9d762f3 seed=e1d765e6 result=61d767c3 seed=2f8f472f result=af8f485f seed=a38863a4 result=23886547 seed=44eb1e55 result=c4eb2089 seed=3f269b12 result=bf269c7e seed=22dc176b result=a2dc1845 seed=2eda2fb0 result=aeda305d seed=c8d41ff1 result=48d42191 seed=b76dd0fe result=376dd36e seed=478b4167 result=c78b428f seed=9e3c9a7c result=1e3c9d3c seed=64dc014d result=e4dc02c9 seed=f18af3aa result=718af5e3 seed=6e4ec123 result=ee4ec2dc seed=16027008 result=9602722c seed=2fac1e69 result=afac205f seed=08c8af16 result=88c8b011 seed=e8ae529f result=68ae55d1 seed=80693c54 result=00693f00 seed=68a99345 result=e8a994d1 seed=ff8a6f42 result=7f8a71ff seed=18c371db result=98c37231 seed=33254b60 result=b3254c66 Start sequence: seed=00000002 seed=00021b9b result=80021c00 seed=38b1fa20 result=b8b1fc71 seed=6a58eba1 result=ea58ecd4 seed=98ccdcee result=18ccdf31 seed=a0330097 result=20330340 seed=e07623ec result=607625c0 seed=e259bffd result=6259c1c4 seed=909b969a result=109b9921 seed=49d76b53 result=c9d76c93 seed=7d472878 result=fd472afa seed=17818019 result=9781822f seed=e64dd906 result=664ddbcc seed=396217cf result=b9621872 seed=069193c4 result=8691940d seed=3ad847f5 result=bad84875 seed=62ce1032 result=e2ce12c5 seed=a607820b result=2607854c seed=d7a8b1d0 result=57a8b3af seed=f4edf391 result=74edf5e9 seed=2b7b681e result=ab7b6a56 seed=7e39e607 result=fe39e8fc seed=eb128e9c result=6b1291d6 seed=bdb61eed result=3db6217b seed=4955ccca result=c955ce92 seed=e1e53fc3 result=61e541c3 seed=c893f628 result=4893f991 seed=18242609 result=98242830 seed=50e9ea36 result=d0e9eca1 seed=966b4b3f result=166b4d2c seed=31fc7474 result=b1fc7663 seed=4d8724e5 result=cd87269b Start sequence: seed=00000001 seed=00010dce result=80010e00 seed=1c5983f7 result=9c598438 seed=c35937cc result=43593986 seed=2e130a5d result=ae130c5c seed=e723057a result=672307ce seed=e3cc94b3 result=63cc97c7 seed=63132a58 result=e3132cc6 seed=79d76079 result=f9d762f3 seed=e1d765e6 result=61d767c3 seed=2f8f472f result=af8f485f seed=a38863a4 result=23886547 seed=44eb1e55 result=c4eb2089 seed=3f269b12 result=bf269c7e seed=22dc176b result=a2dc1845 seed=2eda2fb0 result=aeda305d seed=c8d41ff1 result=48d42191 seed=b76dd0fe result=376dd36e seed=478b4167 result=c78b428f seed=9e3c9a7c result=1e3c9d3c seed=64dc014d result=e4dc02c9 seed=f18af3aa result=718af5e3 seed=6e4ec123 result=ee4ec2dc seed=16027008 result=9602722c seed=2fac1e69 result=afac205f seed=08c8af16 result=88c8b011 seed=e8ae529f result=68ae55d1 seed=80693c54 result=00693f00 seed=68a99345 result=e8a994d1 seed=ff8a6f42 result=7f8a71ff seed=18c371db result=98c37231 seed=33254b60 result=b3254c66 iverilog-12_0/ivtest/gold/queue_fail-vlog95.gold000066400000000000000000000113221435245347300217220ustar00rootroot00000000000000ERROR: vlog95.v:24: $q_initialize requires four arguments. ERROR: vlog95.v:25: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:26: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:27: $q_initialize's first argument must be numeric (<= 32 bits). ERROR: vlog95.v:27: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:28: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: vlog95.v:29: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: vlog95.v:30: $q_initialize's second argument must be numeric (<= 32 bits). ERROR: vlog95.v:30: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: vlog95.v:31: $q_initialize requires a fourth (variable) argument. ERROR: vlog95.v:32: $q_initialize's third argument must be numeric (<= 32 bits). ERROR: vlog95.v:32: $q_initialize requires a fourth (variable) argument. ERROR: vlog95.v:33: $q_initialize's fourth argument must be a 32 bit variable. ERROR: vlog95.v:34: $q_initialize's fourth (variable) argument must be 32 bits. ERROR: vlog95.v:35: $q_initialize takes four arguments. Found 1 extra argument. ERROR: vlog95.v:36: $q_add requires four arguments. ERROR: vlog95.v:37: $q_add requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:38: $q_add requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:39: $q_add's first argument must be numeric (<= 32 bits). ERROR: vlog95.v:39: $q_add requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:40: $q_add requires a third (<= 32 bit numeric) argument. ERROR: vlog95.v:41: $q_add's second argument must be numeric (<= 32 bits). ERROR: vlog95.v:41: $q_add requires a third (<= 32 bit numeric) argument. ERROR: vlog95.v:42: $q_add requires a fourth (variable) argument. ERROR: vlog95.v:43: $q_add's third argument must be numeric (<= 32 bits). ERROR: vlog95.v:43: $q_add requires a fourth (variable) argument. ERROR: vlog95.v:44: $q_add's fourth (variable) argument must be 32 bits. ERROR: vlog95.v:45: $q_add takes four arguments. Found 1 extra argument. ERROR: vlog95.v:46: $q_remove requires four arguments. ERROR: vlog95.v:47: $q_remove requires a second (variable) argument. ERROR: vlog95.v:48: $q_remove requires a second (variable) argument. ERROR: vlog95.v:49: $q_remove's first argument must be numeric (<= 32 bits). ERROR: vlog95.v:49: $q_remove requires a second (variable) argument. ERROR: vlog95.v:50: $q_remove requires a third (variable) argument. ERROR: vlog95.v:51: $q_remove's second argument must be a 32 bit variable. ERROR: vlog95.v:51: $q_remove requires a third (variable) argument. ERROR: vlog95.v:52: $q_remove requires a fourth (variable) argument. ERROR: vlog95.v:53: $q_remove's third argument must be a 32 bit variable. ERROR: vlog95.v:53: $q_remove requires a fourth (variable) argument. ERROR: vlog95.v:54: $q_remove's fourth (variable) argument must be 32 bits. ERROR: vlog95.v:55: $q_remove's second (variable) argument must be 32 bits. ERROR: vlog95.v:55: $q_remove's third (variable) argument must be 32 bits. ERROR: vlog95.v:56: $q_remove takes four arguments. Found 1 extra argument. ERROR: vlog95.v:57: $q_full requires a second (variable) argument. ERROR: vlog95.v:58: $q_full requires a second (variable) argument. ERROR: vlog95.v:59: $q_full's first argument must be numeric (<= 32 bits). ERROR: vlog95.v:59: $q_full requires a second (variable) argument. ERROR: vlog95.v:60: $q_full's second (variable) argument must be 32 bits. ERROR: vlog95.v:61: $q_full takes two arguments. Found 1 extra argument. ERROR: vlog95.v:62: $q_exam requires four arguments. ERROR: vlog95.v:63: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:64: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:65: $q_exam's first argument must be numeric (<= 32 bits). ERROR: vlog95.v:65: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: vlog95.v:66: $q_exam requires a third (variable) argument. ERROR: vlog95.v:67: $q_exam requires a third (variable) argument. ERROR: vlog95.v:68: $q_exam's second argument must be numeric (<= 32 bits). ERROR: vlog95.v:68: $q_exam requires a third (variable) argument. ERROR: vlog95.v:69: $q_exam requires a fourth (variable) argument. ERROR: vlog95.v:70: $q_exam's third (variable) argument must have at least 32 bits. ERROR: vlog95.v:70: $q_exam requires a fourth (variable) argument. ERROR: vlog95.v:71: $q_exam's third argument must be a variable. ERROR: vlog95.v:71: $q_exam requires a fourth (variable) argument. ERROR: vlog95.v:72: $q_exam's fourth (variable) argument must be 32 bits. ERROR: vlog95.v:73: $q_exam takes two arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/queue_fail.gold000066400000000000000000000133511435245347300206030ustar00rootroot00000000000000ERROR: ./ivltests/queue_fail.v:7: $q_initialize requires four arguments. ERROR: ./ivltests/queue_fail.v:8: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:9: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:10: $q_initialize's first argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:10: $q_initialize requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:11: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:12: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:13: $q_initialize's second argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:13: $q_initialize requires a third (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:14: $q_initialize requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:15: $q_initialize's third argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:15: $q_initialize requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:16: $q_initialize's fourth argument must be a 32 bit variable. ERROR: ./ivltests/queue_fail.v:17: $q_initialize's fourth (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:18: $q_initialize takes four arguments. Found 1 extra argument. ERROR: ./ivltests/queue_fail.v:20: $q_add requires four arguments. ERROR: ./ivltests/queue_fail.v:21: $q_add requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:22: $q_add requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:23: $q_add's first argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:23: $q_add requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:24: $q_add requires a third (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:25: $q_add's second argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:25: $q_add requires a third (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:26: $q_add requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:27: $q_add's third argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:27: $q_add requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:28: $q_add's fourth (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:29: $q_add takes four arguments. Found 1 extra argument. ERROR: ./ivltests/queue_fail.v:31: $q_remove requires four arguments. ERROR: ./ivltests/queue_fail.v:32: $q_remove requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:33: $q_remove requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:34: $q_remove's first argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:34: $q_remove requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:35: $q_remove requires a third (variable) argument. ERROR: ./ivltests/queue_fail.v:36: $q_remove's second argument must be a 32 bit variable. ERROR: ./ivltests/queue_fail.v:36: $q_remove requires a third (variable) argument. ERROR: ./ivltests/queue_fail.v:37: $q_remove requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:38: $q_remove's third argument must be a 32 bit variable. ERROR: ./ivltests/queue_fail.v:38: $q_remove requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:39: $q_remove's fourth (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:40: $q_remove's second (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:40: $q_remove's third (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:41: $q_remove takes four arguments. Found 1 extra argument. ERROR: ./ivltests/queue_fail.v:43: $q_full requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:44: $q_full requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:45: $q_full's first argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:45: $q_full requires a second (variable) argument. ERROR: ./ivltests/queue_fail.v:46: $q_full's second (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:47: $q_full takes two arguments. Found 1 extra argument. ERROR: ./ivltests/queue_fail.v:49: $q_exam requires four arguments. ERROR: ./ivltests/queue_fail.v:50: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:51: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:52: $q_exam's first argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:52: $q_exam requires a second (<= 32 bit numeric) argument. ERROR: ./ivltests/queue_fail.v:53: $q_exam requires a third (variable) argument. ERROR: ./ivltests/queue_fail.v:54: $q_exam requires a third (variable) argument. ERROR: ./ivltests/queue_fail.v:55: $q_exam's second argument must be numeric (<= 32 bits). ERROR: ./ivltests/queue_fail.v:55: $q_exam requires a third (variable) argument. ERROR: ./ivltests/queue_fail.v:56: $q_exam requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:57: $q_exam's third (variable) argument must have at least 32 bits. ERROR: ./ivltests/queue_fail.v:57: $q_exam requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:58: $q_exam's third argument must be a variable. ERROR: ./ivltests/queue_fail.v:58: $q_exam requires a fourth (variable) argument. ERROR: ./ivltests/queue_fail.v:59: $q_exam's fourth (variable) argument must be 32 bits. ERROR: ./ivltests/queue_fail.v:60: $q_exam takes two arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/queue_stat.gold000066400000000000000000000016131435245347300206410ustar00rootroot00000000000000----- INIT ----- Queue statistics at time 0 0, x, 0, x, x, x ----- ADD ----- Queue statistics at time 0 1, x, 1, x, 0, 0 ----- ADD ----- Queue statistics at time 1 2, 1, 2, x, 1, 0 ----- ADD ----- Queue statistics at time 2 3, 1, 3, x, 2, 1 ----- REMOVE ----- Queue statistics at time 3 2, 1, 3, 3, 2, 2 Queue statistics at time 4 2, 1, 3, 3, 3, 2 ----- ADD ----- Queue statistics at time 5 3, 1, 3, 3, 4, 2 ----- REMOVE TWO ----- Queue statistics at time 6 1, 1, 3, 3, 1, 3 ----- REMOVE ----- Queue statistics at time 7 0, 1, 3, 2, x, 3 ----- ADD ----- Queue statistics at time 8 1, 2, 3, 2, 0, 2 ----- REMOVE ----- Queue statistics at time 9 0, 2, 3, 1, x, 3 ----- ADD ----- Queue statistics at time 16 1, 3, 3, 1, 0, 2 ----- ADD ----- Queue statistics at time 17 2, 2, 3, 1, 1, 2 ----- ADD ----- Queue statistics at time 18 3, 2, 3, 1, 2, 2 PASSED iverilog-12_0/ivtest/gold/random.gold000066400000000000000000000214501435245347300177430ustar00rootroot0000000000000012153524 c0895e81 8484d609 b1f05663 06b97b0d 46df998d b2c28465 89375212 00f3e301 06d7cd0d 3b23f176 1e8dcd3d 76d457ed 462df78c 7cfde9f9 e33724c6 e2f784c5 d513d2aa 72aff7e5 bbd27277 8932d612 47ecdb8f 793069f2 e77696ce f4007ae8 e2ca4ec5 2e58495c de8e28bd 96ab582d b2a72665 b1ef6263 0573870a c03b2280 10642120 557845aa cecccc9d cb203e96 8983b813 86bc380d a9a7d653 359fdd6b eaa62ad5 81174a02 d7563eae 0effe91d e7c572cf 11844923 0509650a e5730aca 9e314c3c 7968bdf2 452e618a 20c4b341 ec4b34d8 3c20f378 c48a1289 75c50deb 5b0265b6 634bf9c6 571513ae de7502bc 150fdd2a 85d79a0b b897be71 42f24185 27f2554f 9dcc603b 1d06333a bf23327e 0aaa4b15 78d99bf1 6c9c4bd9 31230762 2635fb4c 4fa1559f 47b9a18f 7c6da9f8 dbcd60b7 cfc4569f ae7d945c adcbc05b 44de3789 a4ae3249 e8233ed0 ebfec0d7 a8c7fc51 4b212f96 061d7f0c e12ccec2 6457edc8 bb825a77 1ef2ed3d 090cdb12 bf05007e 36e5816d 1cd9e739 0fd28f1f e9ebf6d3 42d92f85 bc148878 2dda595b 248b4b49 9ff2ae3f 150caf2a 2c156358 c33f3886 c71a0c8e ce2ff29c 7d3599fa 937dbc26 39961773 d18bb4a3 9799a82f d9d292b3 afd8565f 22290d44 7bf8fdf7 e59b36cb f3091ae6 2d28db5a 14cfc129 f682e2ed ed536cda b29fb665 da8ae2b5 efbe94df 3cf11979 2231ff44 e8740cd0 15090b2a 55f6adab 076fcf0e 6e5daddc cd5ebc9a fedf72fd e1f102c3 2b0eed56 2779e94e b3d97667 8531340a 5b6fb9b6 9c0e8a38 3cd18779 dc2bc4b8 4a74bf94 49c65d93 823f2c04 acb7ca59 6dcb69db a6fcde4d 6cb0b7d9 b6a4266d bb45e276 653b49ca 5b172db6 4a937195 a3071a46 02749b04 7bd261f7 34980769 da6ebab4 44018d88 147cd928 9690042d e3c530c7 975c9c2e 8477e408 0e41451c fea7a6fd 149e0729 8e37901c 43356786 ed3408da 9eb7c63d 334ea766 b855c470 b9f50473 5d7199ba 2f3ab35e 7d4779fa 6a8e05d5 8d24f61a dcf000b9 1b876137 4b273796 603921c0 13259f26 db461ab6 3e99837d 6e5f0fdc 43615786 3c03ff78 3f5a9b7e ed8d80db e7c3b6cf 3ced2b79 fd28e4fa b0bcee61 0b940917 d0f578a1 43779186 a8639650 7a8c59f5 9ab48835 949a8a29 60b175c1 e2e574c5 cc01b498 25b27b4b b98c4273 f622e6ec c550168a 2758d14e d44b80a8 549efda9 d0ca8ca1 070bb90e f33466e6 cfd6c09f 152fb52a 155a1d2a c6b5f48d 4f75ff9e 9c6de638 bccfa879 6464e3c8 652345ca 09ff4113 35a0c96b e3b7aec7 5b0bddb6 5d059dba 6216abc4 5c8295b9 492fd392 da269ab4 3fbb3b7f c3339086 7d6df5fa f92794f2 19452132 dece5ebd 424fcd84 f249a4e4 6543cfca 54a879a9 d095a8a1 4765a98e fd8b6afb 85e51e0b f78290ef 64c83dc9 1b60e536 bab14875 c7e8568f 35cdbf6b 4465e788 d73fb4ae 4df3819b 493e4592 1444df28 9684e02d 25b75f4b e169b0c2 8f1cf61e 06b3050d 7679fdec 0c039d18 68ae1bd1 c3761c86 a0c02441 9dbf643b 6c44f9d8 29efe953 ab196256 adac225b f166fae2 8273e204 39ac0373 ec50b4d8 093e4d12 dc0344b8 9c811239 f287b6e5 d0c5dca1 15890f2b 40905d81 641b85c8 13b55527 50d5f9a1 8f8c6e1f 82223a04 2c2d2358 cb5c8096 0a6e9314 8919b412 cb227096 d8ace2b1 2ac2d555 f6c38eed 158b2b2b 7ab11bf5 56b403ad 93c12227 4249ff84 d3a8e4a7 f3d7a6e7 dcef90b9 a4da5649 6de5bbdb 64ba0fc9 2883b151 d0bc5ea1 1546dd2a 7d2a45fa a2e62045 41a10583 be75427c b9461472 ff4f3cfe b455f268 b7dfaa6f 43460d86 782321f0 1c719738 20769140 94097628 7b0da9f6 e2bf1ac5 602831c0 3a625f74 1cde7139 d86a6ab0 1e1c873c 1521932a 3124d362 0aec3515 f0b14ee1 0be29d17 a18bee43 64b5e3c9 c3360486 1297cb25 60f69dc1 c69da28d ad67e25a 03d62707 165b7b2c 060a5d0c b8ade671 9de17c3b 5b60e5b6 fbdfc2f7 cf14ce9e ae78585c 2ab8f755 902a3a20 d00b12a0 39600972 da3d8cb4 6e8af5dd 86dcf00d 25b0994b bccc4279 cf63da9e fef064fd bde0d27b 47e2738f 81c39a03 71c129e3 0e92431d 58f93db1 22119f44 ca9cbc95 f01d34e0 f6a178ed 297a1552 7c1e5bf8 46dcb78d a95fc452 4219e784 236afd46 c63a928c 48487d90 0beac117 352d616a 427b5784 d55bbcaa 3e6f0f7c b0520260 5d4a4dba c5a1608b d31dfea6 92831e25 19058332 d10504a2 a48f7c49 8a64b014 9ec9c03d 25f2034b ae68305c 23907547 433e9786 9caf7a39 da058ab4 6851e5d0 9622502c 467c458c 03e9b707 b522406a 0895f911 746affe8 a5e79e4b 39e48173 76295bec 11fe0523 520eefa4 64e165c9 9ca70439 ef8372df ea5814d4 33836567 4ea0419d 583125b0 41103982 24d2bf49 ecb91ad9 1000b720 8e054c1c 49b16f93 71b461e3 954b822a e471f8c8 aed72e5d 1d3f9d3a 4226a984 95a9a82b 1c8d7f39 897f1c12 a97f0052 2c848959 e82b96d0 b759ea6e 4bf52997 6d8b87db 535277a6 5d85d3bb 80797c00 87e44c0f b4e8d669 8653620c 2ca81959 62fd49c5 67d735cf 4839e590 a8e4d851 b4f9a469 3b83cd77 2523654a ec3758d8 4ddd4d9b e20e9ac4 5c78b1b8 dbe6f2b7 c378ee86 984d5a30 3bed5377 5ad6c7b5 6a15f5d4 03878707 3b0b9776 74a1ade9 45e28b8b 00f25f01 6d808bdb c0764280 611d9fc2 e2ecdac5 9827fa30 d7b2e4af b302da66 57fbb9af f4d86ee9 7c41aff8 8376ac06 f78576ef 70ef37e1 cab47c95 f7723eee 304e4d60 f29c5ee5 9420ea28 322f7d64 14b43729 f0eeaee1 bbbc5277 3715156e 40aaf581 6a9fb9d5 3437d568 786271f0 d57800aa 079fc30f f8dc48f1 be9bbc7d 472e958e f161dce2 1e664d3c d4b5e6a9 77ebb1ef ade7d05b d7a23caf 25029b4a 5cd20db9 098e2d13 09c83513 32dc4165 28c62751 db983ab7 cc981099 9d12083a b8ea3a71 317c0762 f2356ae4 1513dd2a beda447d 2cee5f59 72c3a3e5 76de6bed e4a800c9 a0aecc41 57c1d1af eda71cdb e696e8cd 38139f70 8326d406 d14820a2 5e983dbd b555de6a 6e3d47dc a86c5e50 bd86f47b 929d5825 bc3f8478 7b7b89f6 ae23ce5c 11cc9b23 3cb3ab79 644605c8 ddd146bb 870cee0e b9879473 0671030c e70f98ce 6a1a61d4 acecdc59 5ca26fb9 d9b8c0b3 7a4fbff4 baf4e275 066cf10c 9cfc7a39 01729302 8aecbe15 02fbf905 271c434e 013f2902 5c7951b8 847fb208 46e7538d d7b48eaf 747331e8 48590990 7af6abf5 a620904c 3d82bd7b a005a640 12a90325 86ebb60d b87c1070 16cbf92d 94ded829 5e2551bc 987b0830 60272dc0 28766950 d0cf6aa1 26bf3f4d faf32ef5 7a87aff5 aeeacc5d ca481294 b558a66a 5e6065bc dc4308b8 cf309c9e fd7906fa 23400b46 83fa6407 c9cbbc93 aada7455 5bd3dbb7 22d5f145 b1800a63 ac93e059 9372ce26 b4497668 8f63e41e c838f490 2d19a55a 0e43851c 5c9967b9 55861fab 6826d9d0 37b9656f 6c6a6dd8 a2cc8845 46d6a78d 45f3238b 7e2491fc 6e1e1fdc d27f0aa4 0c978d19 52b533a5 9f398e3e f98bc0f3 ac782c58 62056bc4 2e36435c 033a4506 cd1d509a 0c161918 e2f066c5 5515d1aa 0d12031a 61dbd5c3 5934e9b2 0633630c f4f00ee9 61dafdc3 75ad73eb 7c2db9f8 792c03f2 4483ad89 378c736f 0de14b1b d6a128ad 344dc168 92f91225 67e857cf 55dd8dab 8d94d21b c03b3e80 2ed6d95d 412dfd82 82344204 2ba7a557 1b368b36 196a0332 bce32879 f24baee4 8b42ec16 d57fecaa 605065c0 9759882e 4665378c b8c0c271 7dfe8ffb 5e5421bc ee7068dc 0bec5717 e0e004c1 75fb21eb 5a9d3bb5 c4fd2e89 c7b2e28f dff6f6bf d8462ab0 e9b49ad3 eb1d02d6 c144cc82 0d63751a 38e6a771 eb8804d7 87628e0e f8c714f1 66861dcd 02bd4305 0e3aeb1c 4c18c798 f67088ec 9541d62a b2d14a65 1b920537 81fa3603 ff729efe feaddcfd 9f7a0e3e f43a34e8 ba603874 580989b0 8361dc06 09164d12 b46afc68 e2ba00c5 ff202efe 1b0f0d36 799f09f3 7dddabfb b58d7c6b 0bcbbf17 87d0360f 8a47b614 1500052a d3666ea6 ea7626d4 e5ac10cb b587c26b 0277eb04 fa4832f4 468b618d f0ea70e1 42e3bd85 dc9974b9 e4df16c9 b05f8e60 a3643246 1e74cb3c 1b855f37 2c0c5558 39d65773 8778d20e 6e6d23dc 183fc330 6845f5d0 0073e500 21820f43 7c6e91f8 d0b99aa1 29c01f53 4c588f98 2fef3d5f c3be9287 fd5f5afa 1699d12d b8760270 b5b4e86b 98d73831 892fc012 0650df0c 06db6b0d 0acd1315 20310740 4a638d94 2a1ba354 c0620280 098d1513 e1e386c3 f695deed ee4ee6dc bc781078 13d40d27 afed265f 11c05b23 5596ebab 1c421738 11534d22 64f2bdc9 e3eb4cc7 c1406282 6754d7ce e38e22c7 927fa424 6da36fdb 84651408 3ac26f75 5ad31db5 8d7d721a 1c2a1338 c1233a82 ac05a058 a85a6a50 d1889aa3 5243e3a4 32c3df65 753c17ea 03703906 aa138054 adf3405b e455f0c8 24673948 9bf8f237 7c1df3f8 da8932b5 28d6a951 41aed583 4d9ee39b 1aa0dd35 581653b0 fddf82fb 278dbb4f 984da630 8c38c418 ee8118dd a36ae846 30e20f61 ac974859 2af17355 178b972f 85ce500b ef1deade e9d22cd3 1445b128 74dc69e9 2c577958 6aa4a1d5 61dbe5c3 6a2c13d4 52397da4 3f25ef7e 6b299dd6 87eec80f c1b04483 506aefa0 c10f0482 5fe3cbbf 22eadb45 bbbc3e77 229d0b45 ba941075 fc670af8 63323bc6 3601596c a84e5850 18bd6331 ce10fe9c de325cbc d7e31eaf 872d2c0e b4e46669 d95b40b2 ef209ede c2e87485 555c0faa 1407f128 610ed5c2 4d20099a 69e751d3 dd111aba fdeb7cfb c5cf728b 61114dc2 e64828cc 38e61371 4f49019e 309cdb61 bde3487b df9bd0bf c881bc91 e06098c0 2ca96359 bf53b47e 2a1d7354 a8e2e251 a4de2849 73fa7de7 123aaf24 41b5d583 adee005b 5cdea1b9 4afebf95 bb934a77 f8da1af1 732c5fe6 d7e1aeaf 0238e104 89646012 7e29b3fc d5ba48ab e203f0c4 1ffb813f e13256c2 398a1973 2d4d9b5a d066e4a0 ff73cafe 3a096b74 5d86b7bb 7132bbe2 f16948e2 eff34cdf cc13e298 4fdbed9f 0817cb10 791189f2 5ee97bbd 55bc27ab 5a0a0fb4 aa08ac54 44e79b89 89b5d413 560c91ac 1ae40335 1df61f3b 9aa02435 17a98d2f 1a619934 aae0a255 de7302bc f964fef2 d3fe36a7 e0f280c1 f23316e4 a0b8a241 b4c16c69 fd52d8fa e69dd0cd 7fcff3ff dac986b5 f42082e8 a5955c4b 89042e12 1b978f37 574e1dae fc4ca4f8 90184e20 ed1b50da 913e0222 763355ec 9535122a 3d7f5b7a 0f1e511e f4a1dae9 f5a4f2eb 05b4f70b b704e26e af455e5e 3e502d7c 22c03145 c5cb548b 094bd312 1bf8bd37 c1c3d683 f0ab00e1 674fdfce a5365c4a 6acd73d5 669907cd f204eee4 fa328cf4 766153ec 0d623f1a f1a32ee3 f62484ec 79c681f3 1687472d 2e138d5c 6e8d45dd f612c8ec c7d87a8f 7fdbb3ff 3c338578 55f6b9ab 13d1f727 7dca0ffb 09dfc313 06499b0c 5db797bb f361cae6 a4d83a49 35557b6a 8570f60a 8c06d218 4b1ce996 84e32609 1725712e dee9d4bd 33638966 bb062876 3a982575 c7b43a8f 4ad39595 3da8cd7b be43ea7c b7f4306f e4824cc9 e4d820c9 5a3761b4 6d48a5da d6aea8ad 6fcff1df 06b0e30d 384d4170 41bd6783 a8c6c451 027a8d04 c0467280 fcf504f9 0379ed06 e5063aca iverilog-12_0/ivtest/gold/readmem-error-vlog95.gold000066400000000000000000000044621435245347300223530ustar00rootroot00000000000000WARNING: vlog95.v:20: $readmemb's file name argument (vpiReg) is not a valid string. WARNING: vlog95.v:21: $readmemb's file name argument (vpiIntegerVar) is not a valid string. WARNING: vlog95.v:26: $readmemb's file name argument contains non-printable characters. "ivltests/readmemb.tx\002" WARNING: vlog95.v:29: $readmemb's third argument (start address) is a real value. WARNING: vlog95.v:33: $readmemb's fourth argument (finish address) is a real value. ERROR: vlog95.v:36: $readmemb: Start address -1 is out of bounds for memory 'top.array[0:7]'! ERROR: vlog95.v:38: $readmemb: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: vlog95.v:40: $readmemb: Finish address 8 is out of bounds for memory 'top.array[0:7]'! ERROR: vlog95.v:42: $readmemb: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: vlog95.v:45: $readmemb(ivltests/readmemb.txt): Too many words in the file for the requested range [0:6]. WARNING: vlog95.v:48: $readmemb(ivltests/readmemb.txt): Not enough words in the file for the requested range [-1:7]. ERROR: vlog95.v:51: $readmemb(ivltests/readmem-error.txt): Invalid input character: u WARNING: vlog95.v:53: $readmemh's file name argument (vpiReg) is not a valid string. WARNING: vlog95.v:54: $readmemh's file name argument (vpiIntegerVar) is not a valid string. WARNING: vlog95.v:59: $readmemh's file name argument contains non-printable characters. "ivltests/readmemh.tx\002" WARNING: vlog95.v:62: $readmemh's third argument (start address) is a real value. WARNING: vlog95.v:66: $readmemh's fourth argument (finish address) is a real value. ERROR: vlog95.v:69: $readmemh: Start address -1 is out of bounds for memory 'top.array[0:7]'! ERROR: vlog95.v:71: $readmemh: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: vlog95.v:73: $readmemh: Finish address 8 is out of bounds for memory 'top.array[0:7]'! ERROR: vlog95.v:75: $readmemh: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: vlog95.v:78: $readmemh(ivltests/readmemh.txt): Too many words in the file for the requested range [0:6]. WARNING: vlog95.v:81: $readmemh(ivltests/readmemh.txt): Not enough words in the file for the requested range [-1:7]. ERROR: vlog95.v:84: $readmemh(ivltests/readmem-error.txt): Invalid input character: u iverilog-12_0/ivtest/gold/readmem-error.gold000066400000000000000000000054251435245347300212300ustar00rootroot00000000000000WARNING: ./ivltests/readmem-error.v:18: $readmemb's file name argument (vpiReg) is not a valid string. WARNING: ./ivltests/readmem-error.v:19: $readmemb's file name argument (vpiIntegerVar) is not a valid string. WARNING: ./ivltests/readmem-error.v:33: $readmemb's file name argument contains non-printable characters. "ivltests/readmemb.tx\002" WARNING: ./ivltests/readmem-error.v:38: $readmemb's third argument (start address) is a real value. WARNING: ./ivltests/readmem-error.v:49: $readmemb's fourth argument (finish address) is a real value. ERROR: ./ivltests/readmem-error.v:59: $readmemb: Start address -1 is out of bounds for memory 'top.array[0:7]'! ERROR: ./ivltests/readmem-error.v:67: $readmemb: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: ./ivltests/readmem-error.v:75: $readmemb: Finish address 8 is out of bounds for memory 'top.array[0:7]'! ERROR: ./ivltests/readmem-error.v:83: $readmemb: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: ./ivltests/readmem-error.v:93: $readmemb(ivltests/readmemb.txt): Too many words in the file for the requested range [0:6]. WARNING: ./ivltests/readmem-error.v:105: $readmemb(ivltests/readmemb.txt): Not enough words in the file for the requested range [-1:7]. ERROR: ./ivltests/readmem-error.v:118: $readmemb(ivltests/readmem-error.txt): Invalid input character: u WARNING: ./ivltests/readmem-error.v:123: $readmemh's file name argument (vpiReg) is not a valid string. WARNING: ./ivltests/readmem-error.v:124: $readmemh's file name argument (vpiIntegerVar) is not a valid string. WARNING: ./ivltests/readmem-error.v:138: $readmemh's file name argument contains non-printable characters. "ivltests/readmemh.tx\002" WARNING: ./ivltests/readmem-error.v:143: $readmemh's third argument (start address) is a real value. WARNING: ./ivltests/readmem-error.v:154: $readmemh's fourth argument (finish address) is a real value. ERROR: ./ivltests/readmem-error.v:164: $readmemh: Start address -1 is out of bounds for memory 'top.array[0:7]'! ERROR: ./ivltests/readmem-error.v:172: $readmemh: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: ./ivltests/readmem-error.v:180: $readmemh: Finish address 8 is out of bounds for memory 'top.array[0:7]'! ERROR: ./ivltests/readmem-error.v:188: $readmemh: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: ./ivltests/readmem-error.v:198: $readmemh(ivltests/readmemh.txt): Too many words in the file for the requested range [0:6]. WARNING: ./ivltests/readmem-error.v:210: $readmemh(ivltests/readmemh.txt): Not enough words in the file for the requested range [-1:7]. ERROR: ./ivltests/readmem-error.v:223: $readmemh(ivltests/readmem-error.txt): Invalid input character: u iverilog-12_0/ivtest/gold/readmem-invalid-vlog95.gold000066400000000000000000000022621435245347300226440ustar00rootroot00000000000000ERROR: vlog95.v:14: $readmemb requires two arguments. ERROR: vlog95.v:15: $readmemb's first argument must be a file name (string). ERROR: vlog95.v:15: $readmemb requires a second (memory) argument. ERROR: vlog95.v:16: $readmemb requires a second (memory) argument. ERROR: vlog95.v:17: $readmemb's second argument must be a memory. ERROR: vlog95.v:18: $readmemb's third argument must be a start address (numeric). ERROR: vlog95.v:19: $readmemb's fourth argument must be a finish address (numeric). ERROR: vlog95.v:20: $readmemb takes at most four arguments. Found 1 extra argument. ERROR: vlog95.v:21: $readmemh requires two arguments. ERROR: vlog95.v:22: $readmemh's first argument must be a file name (string). ERROR: vlog95.v:22: $readmemh requires a second (memory) argument. ERROR: vlog95.v:23: $readmemh requires a second (memory) argument. ERROR: vlog95.v:24: $readmemh's second argument must be a memory. ERROR: vlog95.v:25: $readmemh's third argument must be a start address (numeric). ERROR: vlog95.v:26: $readmemh's fourth argument must be a finish address (numeric). ERROR: vlog95.v:27: $readmemh takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/readmem-invalid.gold000066400000000000000000000030241435245347300215160ustar00rootroot00000000000000ERROR: ./ivltests/readmem-invalid.v:5: $readmemb requires two arguments. ERROR: ./ivltests/readmem-invalid.v:6: $readmemb's first argument must be a file name (string). ERROR: ./ivltests/readmem-invalid.v:6: $readmemb requires a second (memory) argument. ERROR: ./ivltests/readmem-invalid.v:7: $readmemb requires a second (memory) argument. ERROR: ./ivltests/readmem-invalid.v:8: $readmemb's second argument must be a memory. ERROR: ./ivltests/readmem-invalid.v:9: $readmemb's third argument must be a start address (numeric). ERROR: ./ivltests/readmem-invalid.v:10: $readmemb's fourth argument must be a finish address (numeric). ERROR: ./ivltests/readmem-invalid.v:11: $readmemb takes at most four arguments. Found 1 extra argument. ERROR: ./ivltests/readmem-invalid.v:13: $readmemh requires two arguments. ERROR: ./ivltests/readmem-invalid.v:14: $readmemh's first argument must be a file name (string). ERROR: ./ivltests/readmem-invalid.v:14: $readmemh requires a second (memory) argument. ERROR: ./ivltests/readmem-invalid.v:15: $readmemh requires a second (memory) argument. ERROR: ./ivltests/readmem-invalid.v:16: $readmemh's second argument must be a memory. ERROR: ./ivltests/readmem-invalid.v:17: $readmemh's third argument must be a start address (numeric). ERROR: ./ivltests/readmem-invalid.v:18: $readmemh's fourth argument must be a finish address (numeric). ERROR: ./ivltests/readmem-invalid.v:19: $readmemh takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/real5.gold000066400000000000000000000000731435245347300174710ustar00rootroot00000000000000max foo period( posedge FOOCLK:0.050ns, 40000 : 0.000ns ); iverilog-12_0/ivtest/gold/real_concat_invalid1.gold000066400000000000000000000045141435245347300225260ustar00rootroot00000000000000ivltests/real_concat_invalid1.v:5: error: concatenation operand can not be real: 2.00000 ivltests/real_concat_invalid1.v:5: error: concatenation operand can not be real: 1.00000 ivltests/real_concat_invalid1.v:5: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:5: error: Unable to elaborate r-value: {2.00000, 1.00000} ivltests/real_concat_invalid1.v:6: error: concatenation operand can not be real: rvar1 ivltests/real_concat_invalid1.v:6: error: concatenation operand can not be real: rvar2 ivltests/real_concat_invalid1.v:6: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:6: error: Unable to elaborate r-value: {rvar1, rvar2} ivltests/real_concat_invalid1.v:8: error: concatenation operand can not be real: 2.00000 ivltests/real_concat_invalid1.v:8: error: concatenation operand can not be real: 1.00000 ivltests/real_concat_invalid1.v:8: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:8: error: Unable to elaborate r-value: {2.00000, 1.00000} ivltests/real_concat_invalid1.v:9: error: concatenation operand can not be real: rvar1 ivltests/real_concat_invalid1.v:9: error: concatenation operand can not be real: rvar2 ivltests/real_concat_invalid1.v:9: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:9: error: Unable to elaborate r-value: {rvar1, rvar2} ivltests/real_concat_invalid1.v:11: error: concatenation operand can no be real: wrcon5 ivltests/real_concat_invalid1.v:11: error: concatenation operand can no be real: wrcon6 ivltests/real_concat_invalid1.v:14: error: concatenation operand can not be real: 2.00000 ivltests/real_concat_invalid1.v:14: error: concatenation operand can not be real: 1.00000 ivltests/real_concat_invalid1.v:14: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:15: error: concatenation operand can not be real: rvar1 ivltests/real_concat_invalid1.v:15: error: concatenation operand can not be real: rvar2 ivltests/real_concat_invalid1.v:15: error: Concatenation may not have zero width in this context. ivltests/real_concat_invalid1.v:17: error: concatenation operand can not be real: rvar1 ivltests/real_concat_invalid1.v:17: error: concatenation operand can not be real: rvar2 26 error(s) during elaboration. iverilog-12_0/ivtest/gold/real_concat_invalid2.gold000066400000000000000000000006131435245347300225230ustar00rootroot00000000000000ivltests/real_concat_invalid2.v:5: error: concatenation operand can not be real: 2.00000 ivltests/real_concat_invalid2.v:5: error: concatenation operand can not be real: 1.00000 ivltests/real_concat_invalid2.v:4: error: concatenation operand can not be real: ivltests/real_concat_invalid2.v:4: error: concatenation operand can not be real: 5 error(s) during elaboration. iverilog-12_0/ivtest/gold/real_delay.gold000066400000000000000000000002241435245347300205600ustar00rootroot000000000000000.000 00000000 000 00000000 00000000 1.200 00000000 000 00000000 11111111 1.230 00000000 000 11111111 11111111 1.234 11111111 111 11111111 11111111 iverilog-12_0/ivtest/gold/real_events.gold000066400000000000000000000002361435245347300207710ustar00rootroot00000000000000val = 1.000000 val = 2.000000 val1 = 1.100000 val2 = 1.200000 val1 = 2.100000 val2 = 2.200000 val1 = 2.100000 val2 = 2.200000 val1 = 3.100000 val2 = 3.200000 iverilog-12_0/ivtest/gold/real_invalid_ops.gold000066400000000000000000000130261435245347300217750ustar00rootroot00000000000000./ivltests/real_invalid_ops.v:6: error: & operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:6: error: Unable to elaborate r-value: &(var1) ./ivltests/real_invalid_ops.v:7: error: | operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:7: error: Unable to elaborate r-value: |(var1) ./ivltests/real_invalid_ops.v:8: error: ^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:8: error: Unable to elaborate r-value: ^(var1) ./ivltests/real_invalid_ops.v:9: error: ~& operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:9: error: Unable to elaborate r-value: A(var1) ./ivltests/real_invalid_ops.v:10: error: ~| operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:10: error: Unable to elaborate r-value: N(var1) ./ivltests/real_invalid_ops.v:11: error: ~^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:11: error: Unable to elaborate r-value: X(var1) ./ivltests/real_invalid_ops.v:12: error: ~^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:12: error: Unable to elaborate r-value: X(var1) ./ivltests/real_invalid_ops.v:14: error: & operator may not have REAL operands. ./ivltests/real_invalid_ops.v:14: error: Unable to elaborate r-value: (var1)&(var2) ./ivltests/real_invalid_ops.v:15: error: | operator may not have REAL operands. ./ivltests/real_invalid_ops.v:15: error: Unable to elaborate r-value: (var1)|(var2) ./ivltests/real_invalid_ops.v:16: error: ^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:16: error: Unable to elaborate r-value: (var1)^(var2) ./ivltests/real_invalid_ops.v:17: error: ~& operator may not have REAL operands. ./ivltests/real_invalid_ops.v:17: error: Unable to elaborate r-value: (var1)A(var2) ./ivltests/real_invalid_ops.v:18: error: ~| operator may not have REAL operands. ./ivltests/real_invalid_ops.v:18: error: Unable to elaborate r-value: (var1)O(var2) ./ivltests/real_invalid_ops.v:19: error: ~^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:19: error: Unable to elaborate r-value: (var1)X(var2) ./ivltests/real_invalid_ops.v:20: error: ~^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:20: error: Unable to elaborate r-value: (var1)X(var2) ./ivltests/real_invalid_ops.v:22: error: === operator may not have REAL or STRING operands. ./ivltests/real_invalid_ops.v:22: error: Unable to elaborate r-value: (var1)===(var2) ./ivltests/real_invalid_ops.v:23: error: !== operator may not have REAL or STRING operands. ./ivltests/real_invalid_ops.v:23: error: Unable to elaborate r-value: (var1)!==(var2) ./ivltests/real_invalid_ops.v:25: error: <<(<) operator may not have REAL operands. ./ivltests/real_invalid_ops.v:25: error: Unable to elaborate r-value: (var1)<<(var2) ./ivltests/real_invalid_ops.v:26: error: <<(<) operator may not have REAL operands. ./ivltests/real_invalid_ops.v:26: error: Unable to elaborate r-value: (var1)<<(var2) ./ivltests/real_invalid_ops.v:27: error: >> operator may not have REAL operands. ./ivltests/real_invalid_ops.v:27: error: Unable to elaborate r-value: (var1)>>(var2) ./ivltests/real_invalid_ops.v:28: error: >>> operator may not have REAL operands. ./ivltests/real_invalid_ops.v:28: error: Unable to elaborate r-value: (var1)>>>(var2) ./ivltests/real_invalid_ops.v:30: error: Concatenation operand can not be real: var1 ./ivltests/real_invalid_ops.v:30: error: Unable to elaborate r-value: {var1} ./ivltests/real_invalid_ops.v:31: error: Concatenation repeat expression can not be REAL. ./ivltests/real_invalid_ops.v:31: error: Concatenation operand can not be real: var1 ./ivltests/real_invalid_ops.v:31: error: Unable to elaborate r-value: {2.00000{var1}} ./ivltests/real_invalid_ops.v:40: error: & operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:41: error: | operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:42: error: ^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:43: error: ~& operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:44: error: ~| operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:45: error: ~^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:46: error: ~^ operator may not have a REAL operand. ./ivltests/real_invalid_ops.v:48: error: & operator may not have REAL operands. ./ivltests/real_invalid_ops.v:49: error: | operator may not have REAL operands. ./ivltests/real_invalid_ops.v:50: error: ^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:51: error: ~& operator may not have REAL operands. ./ivltests/real_invalid_ops.v:52: error: ~| operator may not have REAL operands. ./ivltests/real_invalid_ops.v:53: error: ~^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:54: error: ~^ operator may not have REAL operands. ./ivltests/real_invalid_ops.v:56: error: === operator may not have REAL or STRING operands. ./ivltests/real_invalid_ops.v:57: error: !== operator may not have REAL or STRING operands. ./ivltests/real_invalid_ops.v:59: error: <<(<) operator may not have REAL operands. ./ivltests/real_invalid_ops.v:60: error: <<(<) operator may not have REAL operands. ./ivltests/real_invalid_ops.v:61: error: >> operator may not have REAL operands. ./ivltests/real_invalid_ops.v:62: error: >>> operator may not have REAL operands. ./ivltests/real_invalid_ops.v:64: error: Concatenation operand can not be real: var1 ./ivltests/real_invalid_ops.v:65: error: Concatenation repeat expression can not be REAL. ./ivltests/real_invalid_ops.v:65: error: Concatenation operand can not be real: var1 68 error(s) during elaboration. iverilog-12_0/ivtest/gold/real_select_invalid.gold000066400000000000000000000164471435245347300224650ustar00rootroot00000000000000ivltests/real_select_invalid.v:10: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:10: error: Unable to elaborate r-value: rpar['sd0] ivltests/real_select_invalid.v:11: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:11: error: Unable to elaborate r-value: rpar['sd0:'sd0] ivltests/real_select_invalid.v:12: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:12: error: Unable to elaborate r-value: rpar['sd0+:'sd1] ivltests/real_select_invalid.v:13: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:13: error: Unable to elaborate r-value: rpar['sd0-:'sd1] ivltests/real_select_invalid.v:15: error: can not select part of real: rvar ivltests/real_select_invalid.v:15: error: Unable to elaborate r-value: rvar['sd0] ivltests/real_select_invalid.v:16: error: can not select part of real: rvar ivltests/real_select_invalid.v:16: error: Unable to elaborate r-value: rvar['sd0:'sd0] ivltests/real_select_invalid.v:17: error: can not select part of real: rvar ivltests/real_select_invalid.v:17: error: Unable to elaborate r-value: rvar['sd0+:'sd1] ivltests/real_select_invalid.v:18: error: can not select part of real: rvar ivltests/real_select_invalid.v:18: error: Unable to elaborate r-value: rvar['sd0-:'sd1] ivltests/real_select_invalid.v:20: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:20: error: Unable to elaborate r-value: rarr['sd0]['sd0] ivltests/real_select_invalid.v:21: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:21: error: Unable to elaborate r-value: rarr['sd0]['sd0:'sd0] ivltests/real_select_invalid.v:22: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:22: error: Unable to elaborate r-value: rarr['sd0]['sd0+:'sd1] ivltests/real_select_invalid.v:23: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:23: error: Unable to elaborate r-value: rarr['sd0]['sd0-:'sd1] ivltests/real_select_invalid.v:25: error: can not select part of real: wrbslv ivltests/real_select_invalid.v:26: error: can not select part of real: wrpslv ivltests/real_select_invalid.v:27: error: can not select part of real: wruplv ivltests/real_select_invalid.v:28: error: can not select part of real: wrdolv ivltests/real_select_invalid.v:30: error: can not select part of real array word: wrarr[0] ivltests/real_select_invalid.v:31: error: can not select part of real array word: wrarr[0] ivltests/real_select_invalid.v:32: error: can not select part of real array word: wrarr[0] ivltests/real_select_invalid.v:33: error: can not select part of real array word: wrarr[0] ivltests/real_select_invalid.v:35: error: can not select part of real: wrbstr ivltests/real_select_invalid.v:36: error: can not select part of real: wrpstr ivltests/real_select_invalid.v:37: error: can not select part of real: wruptr ivltests/real_select_invalid.v:38: error: can not select part of real: wrdotr ivltests/real_select_invalid.v:40: error: can not select part of real: wrbstr ivltests/real_select_invalid.v:40: internal error: Port expression too complicated for elaboration. ivltests/real_select_invalid.v:40: error: can not select part of real: wrpstr ivltests/real_select_invalid.v:40: internal error: Port expression too complicated for elaboration. ivltests/real_select_invalid.v:40: error: can not select part of real: wruptr ivltests/real_select_invalid.v:40: internal error: Port expression too complicated for elaboration. ivltests/real_select_invalid.v:40: error: can not select part of real: wrdotr ivltests/real_select_invalid.v:40: internal error: Port expression too complicated for elaboration. ivltests/real_select_invalid.v:41: error: can not select part of real: wrbstr ivltests/real_select_invalid.v:41: error: Output port expression must support continuous assignment. ivltests/real_select_invalid.v:41: : Port of submod2 is arg1 ivltests/real_select_invalid.v:41: error: can not select part of real: wrpstr ivltests/real_select_invalid.v:41: error: Output port expression must support continuous assignment. ivltests/real_select_invalid.v:41: : Port of submod2 is arg2 ivltests/real_select_invalid.v:41: error: can not select part of real: wruptr ivltests/real_select_invalid.v:41: error: Output port expression must support continuous assignment. ivltests/real_select_invalid.v:41: : Port of submod2 is arg3 ivltests/real_select_invalid.v:41: error: can not select part of real: wrdotr ivltests/real_select_invalid.v:41: error: Output port expression must support continuous assignment. ivltests/real_select_invalid.v:41: : Port of submod2 is arg4 ivltests/real_select_invalid.v:42: error: can not select part of real: wrbstr ivltests/real_select_invalid.v:42: error: Inout port expression must support continuous assignment. ivltests/real_select_invalid.v:42: : Port of submod3 is arg1 ivltests/real_select_invalid.v:42: error: can not select part of real: wrpstr ivltests/real_select_invalid.v:42: error: Inout port expression must support continuous assignment. ivltests/real_select_invalid.v:42: : Port of submod3 is arg2 ivltests/real_select_invalid.v:42: error: can not select part of real: wruptr ivltests/real_select_invalid.v:42: error: Inout port expression must support continuous assignment. ivltests/real_select_invalid.v:42: : Port of submod3 is arg3 ivltests/real_select_invalid.v:42: error: can not select part of real: wrdotr ivltests/real_select_invalid.v:42: error: Inout port expression must support continuous assignment. ivltests/real_select_invalid.v:42: : Port of submod3 is arg4 ivltests/real_select_invalid.v:45: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:46: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:47: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:48: error: can not select part of real parameter: rpar ivltests/real_select_invalid.v:50: error: can not select part of real: rvar ivltests/real_select_invalid.v:51: error: can not select part of real: rvar ivltests/real_select_invalid.v:52: error: can not select part of real: rvar ivltests/real_select_invalid.v:53: error: can not select part of real: rvar ivltests/real_select_invalid.v:55: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:56: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:57: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:58: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:60: error: can not select part of real: rout ivltests/real_select_invalid.v:61: error: can not select part of real: rout ivltests/real_select_invalid.v:62: error: can not select part of real: rout ivltests/real_select_invalid.v:63: error: can not select part of real: rout ivltests/real_select_invalid.v:65: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:66: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:67: error: can not select part of real array word: rarr['sd0] ivltests/real_select_invalid.v:68: error: can not select part of real array word: rarr['sd0] 76 error(s) during elaboration. iverilog-12_0/ivtest/gold/recursive_func.gold000066400000000000000000000001541435245347300215030ustar00rootroot00000000000000factorial 3 = 6 factorial 4 = 24 factorial 5 = 120 factorial 6 = 720 factorial 7 = 5040 factorial 8 = 40320 iverilog-12_0/ivtest/gold/recursive_func_const.gold000066400000000000000000000000631435245347300227100ustar00rootroot00000000000000factorial 3 = 6 factorial 4 = 24 factorial 5 = 120 iverilog-12_0/ivtest/gold/recursive_task.gold000066400000000000000000000005131435245347300215110ustar00rootroot00000000000000intermediate value = 1 intermediate value = 1 intermediate value = 1 intermediate value = 2 intermediate value = 2 intermediate value = 2 intermediate value = 6 intermediate value = 6 intermediate value = 6 intermediate value = 24 intermediate value = 24 intermediate value = 120 factorial 3 = 6 factorial 4 = 24 factorial 5 = 120 iverilog-12_0/ivtest/gold/resetall-fsv.gold000066400000000000000000000010151435245347300210650ustar00rootroot00000000000000warning: Some design elements have no explicit time unit and/or : time precision. This may cause confusing timing results. : Affected design elements are: : -- module top_default declared here: ./ivltests/resetall.v:1 : -- module top_resetall declared here: ./ivltests/resetall.v:20 Time scale of (top_default) is 1s / 1s Time scale of (top_timescale) is 1ns / 1ns Time scale of (top_resetall) is 1s / 1s Time scale of (top_timescale2) is 1ms / 1ms Time scale of (top_timescale3) is 1us / 1us iverilog-12_0/ivtest/gold/resetall-v10.gold000066400000000000000000000013441435245347300207020ustar00rootroot00000000000000./ivltests/resetall.v:12: warning: Some modules have no timescale. This may cause ./ivltests/resetall.v:12: : confusing timing results. Affected modules are: ./ivltests/resetall.v:12: : -- module top_default declared here: ./ivltests/resetall.v:1 ./ivltests/resetall.v:26: warning: Some modules have no timescale. This may cause ./ivltests/resetall.v:26: : confusing timing results. Affected modules are: ./ivltests/resetall.v:26: : -- module top_resetall declared here: ./ivltests/resetall.v:20 Time scale of (top_default) is 1s / 1s Time scale of (top_timescale) is 1ns / 1ns Time scale of (top_resetall) is 1s / 1s Time scale of (top_timescale2) is 1ms / 1ms Time scale of (top_timescale3) is 1us / 1us iverilog-12_0/ivtest/gold/resetall.gold000066400000000000000000000007251435245347300203000ustar00rootroot00000000000000warning: Some modules have no timescale. This may cause : confusing timing results. Affected modules are: : -- module top_default declared here: ./ivltests/resetall.v:1 : -- module top_resetall declared here: ./ivltests/resetall.v:20 Time scale of (top_default) is 1s / 1s Time scale of (top_timescale) is 1ns / 1ns Time scale of (top_resetall) is 1s / 1s Time scale of (top_timescale2) is 1ms / 1ms Time scale of (top_timescale3) is 1us / 1us iverilog-12_0/ivtest/gold/resetall2.gold000066400000000000000000000001271435245347300203560ustar00rootroot00000000000000Time scale of (top_timescale) is 1us / 1us Time scale of (top_timescale2) is 1ns / 1ns iverilog-12_0/ivtest/gold/resetall2_std.gold000066400000000000000000000001331435245347300212250ustar00rootroot00000000000000Time scale of (top_timescale) is 1us / 1us Time scale of (top_timescale2) is 1ns / 1ns iverilog-12_0/ivtest/gold/rtran.gold000066400000000000000000000142201435245347300176060ustar00rootroot00000000000000a = z b = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = 0 b = z a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Pu0) t12(St0 Pu0) t13(Pu0 We0) t14(We0 Me0) t15(HiZ HiZ) t21(Su0 Pu0) t22(St0 Pu0) t23(Pu0 We0) t24(We0 Me0) t25(HiZ HiZ) t31(Su0 Pu0) t32(St0 Pu0) t33(Pu0 We0) t34(We0 Me0) t35(HiZ HiZ) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 We0) t44(We0 Me0) t45(HiZ HiZ) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 1 b = z a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Pu1) t12(Su1 Pu1) t13(Su1 Pu1) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Pu1) t22(St1 Pu1) t23(St1 Pu1) t24(St1 Pu1) t25(St1 Pu1) t31(Pu1 We1) t32(Pu1 We1) t33(Pu1 We1) t34(Pu1 We1) t35(Pu1 We1) t41(We1 Me1) t42(We1 Me1) t43(We1 Me1) t44(We1 Me1) t45(We1 Me1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = x b = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 750) t42(St0 650) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 750) t52(St0 650) t53(Pu0 530) t54(We0 320) t55(HiZ HiZ) a = 1 b = x a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 751) t15(Su1 751) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 651) t25(St1 651) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 531) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 321) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu0 Su0) t12(Pu0 St0) t13(We0 Pu0) t14(Me0 We0) t15(HiZ HiZ) t21(Pu0 Su0) t22(Pu0 St0) t23(We0 Pu0) t24(Me0 We0) t25(HiZ HiZ) t31(Pu0 Su0) t32(Pu0 St0) t33(We0 Pu0) t34(Me0 We0) t35(HiZ HiZ) t41(Pu0 Su0) t42(Pu0 St0) t43(We0 Pu0) t44(Me0 We0) t45(HiZ HiZ) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = x b = 0 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(750 Su0) t42(650 St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(750 Su0) t52(650 St0) t53(530 Pu0) t54(320 We0) t55(HiZ HiZ) a = 0 b = 0 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 Pu1) t25(St1 Pu1) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 We1) t41(Pu0 Su0) t42(Pu0 St0) t43(WeX Pu0) t44(We1 We0) t45(We1 Me1) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = z b = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu1 Su1) t12(Pu1 Su1) t13(Pu1 Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Pu1 St1) t22(Pu1 St1) t23(Pu1 St1) t24(Pu1 St1) t25(Pu1 St1) t31(We1 Pu1) t32(We1 Pu1) t33(We1 Pu1) t34(We1 Pu1) t35(We1 Pu1) t41(Me1 We1) t42(Me1 We1) t43(Me1 We1) t44(Me1 We1) t45(Me1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(751 Su1) t15(751 Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(651 St1) t25(651 St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(531 Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(321 We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = 0 b = 1 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(Pu1 St1) t25(Pu1 St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(We1 Pu1) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 WeX) t44(We0 We1) t45(Me1 We1) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 1 b = 1 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/rtranif0.gold000066400000000000000000000620001435245347300202040ustar00rootroot00000000000000a = z b = z en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = z en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = z en = 0 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = z en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX HiZ) t12(67X HiZ) t13(57X HiZ) t14(37X HiZ) t15(SuH HiZ) t21(76X HiZ) t22(StX HiZ) t23(56X HiZ) t24(36X HiZ) t25(StH HiZ) t31(75X HiZ) t32(65X HiZ) t33(PuX HiZ) t34(35X HiZ) t35(PuH HiZ) t41(73X HiZ) t42(63X HiZ) t43(53X HiZ) t44(WeX HiZ) t45(WeH HiZ) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = 0 b = z en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 PuL) t12(St0 PuL) t13(Pu0 WeL) t14(We0 MeL) t15(HiZ HiZ) t21(Su0 PuL) t22(St0 PuL) t23(Pu0 WeL) t24(We0 MeL) t25(HiZ HiZ) t31(Su0 PuL) t32(St0 PuL) t33(Pu0 WeL) t34(We0 MeL) t35(HiZ HiZ) t41(Su0 PuL) t42(St0 PuL) t43(Pu0 WeL) t44(We0 MeL) t45(HiZ HiZ) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = z en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 PuL) t12(St0 PuL) t13(Pu0 WeL) t14(We0 MeL) t15(HiZ HiZ) t21(Su0 PuL) t22(St0 PuL) t23(Pu0 WeL) t24(We0 MeL) t25(HiZ HiZ) t31(Su0 PuL) t32(St0 PuL) t33(Pu0 WeL) t34(We0 MeL) t35(HiZ HiZ) t41(Su0 PuL) t42(St0 PuL) t43(Pu0 WeL) t44(We0 MeL) t45(HiZ HiZ) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = z en = 0 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Pu0) t12(St0 Pu0) t13(Pu0 We0) t14(We0 Me0) t15(HiZ HiZ) t21(Su0 Pu0) t22(St0 Pu0) t23(Pu0 We0) t24(We0 Me0) t25(HiZ HiZ) t31(Su0 Pu0) t32(St0 Pu0) t33(Pu0 We0) t34(We0 Me0) t35(HiZ HiZ) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 We0) t44(We0 Me0) t45(HiZ HiZ) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 0 b = z en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 HiZ) t12(St0 HiZ) t13(Pu0 HiZ) t14(We0 HiZ) t15(HiZ HiZ) t21(Su0 HiZ) t22(St0 HiZ) t23(Pu0 HiZ) t24(We0 HiZ) t25(HiZ HiZ) t31(Su0 HiZ) t32(St0 HiZ) t33(Pu0 HiZ) t34(We0 HiZ) t35(HiZ HiZ) t41(Su0 HiZ) t42(St0 HiZ) t43(Pu0 HiZ) t44(We0 HiZ) t45(HiZ HiZ) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 1 b = z en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 PuH) t12(Su1 PuH) t13(Su1 PuH) t14(Su1 PuH) t15(Su1 PuH) t21(St1 PuH) t22(St1 PuH) t23(St1 PuH) t24(St1 PuH) t25(St1 PuH) t31(Pu1 WeH) t32(Pu1 WeH) t33(Pu1 WeH) t34(Pu1 WeH) t35(Pu1 WeH) t41(We1 MeH) t42(We1 MeH) t43(We1 MeH) t44(We1 MeH) t45(We1 MeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 PuH) t12(Su1 PuH) t13(Su1 PuH) t14(Su1 PuH) t15(Su1 PuH) t21(St1 PuH) t22(St1 PuH) t23(St1 PuH) t24(St1 PuH) t25(St1 PuH) t31(Pu1 WeH) t32(Pu1 WeH) t33(Pu1 WeH) t34(Pu1 WeH) t35(Pu1 WeH) t41(We1 MeH) t42(We1 MeH) t43(We1 MeH) t44(We1 MeH) t45(We1 MeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 0 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Pu1) t12(Su1 Pu1) t13(Su1 Pu1) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Pu1) t22(St1 Pu1) t23(St1 Pu1) t24(St1 Pu1) t25(St1 Pu1) t31(Pu1 We1) t32(Pu1 We1) t33(Pu1 We1) t34(Pu1 We1) t35(Pu1 We1) t41(We1 Me1) t42(We1 Me1) t43(We1 Me1) t44(We1 Me1) t45(We1 Me1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 HiZ) t12(Su1 HiZ) t13(Su1 HiZ) t14(Su1 HiZ) t15(Su1 HiZ) t21(St1 HiZ) t22(St1 HiZ) t23(St1 HiZ) t24(St1 HiZ) t25(St1 HiZ) t31(Pu1 HiZ) t32(Pu1 HiZ) t33(Pu1 HiZ) t34(Pu1 HiZ) t35(Pu1 HiZ) t41(We1 HiZ) t42(We1 HiZ) t43(We1 HiZ) t44(We1 HiZ) t45(We1 HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = x en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = x en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = x en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ SuX) t12(HiZ 67X) t13(HiZ 57X) t14(HiZ 37X) t15(HiZ SuH) t21(HiZ 76X) t22(HiZ StX) t23(HiZ 56X) t24(HiZ 36X) t25(HiZ StH) t31(HiZ 75X) t32(HiZ 65X) t33(HiZ PuX) t34(HiZ 35X) t35(HiZ PuH) t41(HiZ 73X) t42(HiZ 63X) t43(HiZ 53X) t44(HiZ WeX) t45(HiZ WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = x b = x en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 0 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 0 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 750) t42(St0 650) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 750) t52(St0 650) t53(Pu0 530) t54(We0 320) t55(HiZ HiZ) a = 0 b = x en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 SuX) t12(St0 67X) t13(Pu0 57X) t14(We0 37X) t15(HiZ SuH) t21(Su0 76X) t22(St0 StX) t23(Pu0 56X) t24(We0 36X) t25(HiZ StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(We0 35X) t35(HiZ PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(HiZ WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 1 b = x en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = 1 b = x en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = 1 b = x en = 0 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 751) t15(Su1 751) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 651) t25(St1 651) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 531) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 321) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = 1 b = x en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(Pu1 75X) t32(Pu1 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(We1 73X) t42(We1 63X) t43(We1 53X) t44(We1 WeX) t45(We1 WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = z b = 0 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuL Su0) t12(PuL St0) t13(WeL Pu0) t14(MeL We0) t15(HiZ HiZ) t21(PuL Su0) t22(PuL St0) t23(WeL Pu0) t24(MeL We0) t25(HiZ HiZ) t31(PuL Su0) t32(PuL St0) t33(WeL Pu0) t34(MeL We0) t35(HiZ HiZ) t41(PuL Su0) t42(PuL St0) t43(WeL Pu0) t44(MeL We0) t45(HiZ HiZ) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = z b = 0 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuL Su0) t12(PuL St0) t13(WeL Pu0) t14(MeL We0) t15(HiZ HiZ) t21(PuL Su0) t22(PuL St0) t23(WeL Pu0) t24(MeL We0) t25(HiZ HiZ) t31(PuL Su0) t32(PuL St0) t33(WeL Pu0) t34(MeL We0) t35(HiZ HiZ) t41(PuL Su0) t42(PuL St0) t43(WeL Pu0) t44(MeL We0) t45(HiZ HiZ) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = z b = 0 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu0 Su0) t12(Pu0 St0) t13(We0 Pu0) t14(Me0 We0) t15(HiZ HiZ) t21(Pu0 Su0) t22(Pu0 St0) t23(We0 Pu0) t24(Me0 We0) t25(HiZ HiZ) t31(Pu0 Su0) t32(Pu0 St0) t33(We0 Pu0) t34(Me0 We0) t35(HiZ HiZ) t41(Pu0 Su0) t42(Pu0 St0) t43(We0 Pu0) t44(Me0 We0) t45(HiZ HiZ) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = z b = 0 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su0) t12(HiZ St0) t13(HiZ Pu0) t14(HiZ We0) t15(HiZ HiZ) t21(HiZ Su0) t22(HiZ St0) t23(HiZ Pu0) t24(HiZ We0) t25(HiZ HiZ) t31(HiZ Su0) t32(HiZ St0) t33(HiZ Pu0) t34(HiZ We0) t35(HiZ HiZ) t41(HiZ Su0) t42(HiZ St0) t43(HiZ Pu0) t44(HiZ We0) t45(HiZ HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = x b = 0 en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 0 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(750 Su0) t42(650 St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(750 Su0) t52(650 St0) t53(530 Pu0) t54(320 We0) t55(HiZ HiZ) a = x b = 0 en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su0) t12(67X St0) t13(57X Pu0) t14(37X We0) t15(SuH HiZ) t21(76X Su0) t22(StX St0) t23(56X Pu0) t24(36X We0) t25(StH HiZ) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X We0) t35(PuH HiZ) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH HiZ) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 0 b = 0 en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 0 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 35X) t15(Su1 PuH) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 35X) t25(St1 PuH) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 WeH) t41(53X Su0) t42(53X St0) t43(WeX Pu0) t44(We1 We0) t45(We1 MeH) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = 1 b = 0 en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 35X) t15(Su1 PuH) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 35X) t25(St1 PuH) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 WeH) t41(53X Su0) t42(53X St0) t43(WeX Pu0) t44(We1 We0) t45(We1 MeH) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = 1 b = 0 en = 0 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 Pu1) t25(St1 Pu1) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 We1) t41(Pu0 Su0) t42(Pu0 St0) t43(WeX Pu0) t44(We1 We0) t45(We1 Me1) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = 1 b = 0 en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su0) t12(Su1 St0) t13(Su1 Pu0) t14(Su1 We0) t15(Su1 HiZ) t21(St1 Su0) t22(St1 St0) t23(St1 Pu0) t24(St1 We0) t25(St1 HiZ) t31(Pu1 Su0) t32(Pu1 St0) t33(Pu1 Pu0) t34(Pu1 We0) t35(Pu1 HiZ) t41(We1 Su0) t42(We1 St0) t43(We1 Pu0) t44(We1 We0) t45(We1 HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = z b = 1 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuH Su1) t12(PuH Su1) t13(PuH Su1) t14(PuH Su1) t15(PuH Su1) t21(PuH St1) t22(PuH St1) t23(PuH St1) t24(PuH St1) t25(PuH St1) t31(WeH Pu1) t32(WeH Pu1) t33(WeH Pu1) t34(WeH Pu1) t35(WeH Pu1) t41(MeH We1) t42(MeH We1) t43(MeH We1) t44(MeH We1) t45(MeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuH Su1) t12(PuH Su1) t13(PuH Su1) t14(PuH Su1) t15(PuH Su1) t21(PuH St1) t22(PuH St1) t23(PuH St1) t24(PuH St1) t25(PuH St1) t31(WeH Pu1) t32(WeH Pu1) t33(WeH Pu1) t34(WeH Pu1) t35(WeH Pu1) t41(MeH We1) t42(MeH We1) t43(MeH We1) t44(MeH We1) t45(MeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu1 Su1) t12(Pu1 Su1) t13(Pu1 Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Pu1 St1) t22(Pu1 St1) t23(Pu1 St1) t24(Pu1 St1) t25(Pu1 St1) t31(We1 Pu1) t32(We1 Pu1) t33(We1 Pu1) t34(We1 Pu1) t35(We1 Pu1) t41(Me1 We1) t42(Me1 We1) t43(Me1 We1) t44(Me1 We1) t45(Me1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su1) t12(HiZ Su1) t13(HiZ Su1) t14(HiZ Su1) t15(HiZ Su1) t21(HiZ St1) t22(HiZ St1) t23(HiZ St1) t24(HiZ St1) t25(HiZ St1) t31(HiZ Pu1) t32(HiZ Pu1) t33(HiZ Pu1) t34(HiZ Pu1) t35(HiZ Pu1) t41(HiZ We1) t42(HiZ We1) t43(HiZ We1) t44(HiZ We1) t45(HiZ We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(WeH We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = 1 en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(WeH We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = 1 en = 0 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(751 Su1) t15(751 Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(651 St1) t25(651 St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(531 Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(321 We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = 1 en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X Pu1) t32(65X Pu1) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X We1) t42(63X We1) t43(53X We1) t44(WeX We1) t45(WeH We1) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = 0 b = 1 en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(35X Su1) t15(PuH Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(35X St1) t25(PuH St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(WeH Pu1) t41(Su0 53X) t42(St0 53X) t43(Pu0 WeX) t44(We0 We1) t45(MeH We1) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = 1 en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(35X Su1) t15(PuH Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(35X St1) t25(PuH St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(WeH Pu1) t41(Su0 53X) t42(St0 53X) t43(Pu0 WeX) t44(We0 We1) t45(MeH We1) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = 1 en = 0 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(Pu1 St1) t25(Pu1 St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(We1 Pu1) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 WeX) t44(We0 We1) t45(Me1 We1) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 0 b = 1 en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su1) t12(St0 Su1) t13(Pu0 Su1) t14(We0 Su1) t15(HiZ Su1) t21(Su0 St1) t22(St0 St1) t23(Pu0 St1) t24(We0 St1) t25(HiZ St1) t31(Su0 Pu1) t32(St0 Pu1) t33(Pu0 Pu1) t34(We0 Pu1) t35(HiZ Pu1) t41(Su0 We1) t42(St0 We1) t43(Pu0 We1) t44(We0 We1) t45(HiZ We1) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 1 b = 1 en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 0 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/rtranif1.gold000066400000000000000000000620001435245347300202050ustar00rootroot00000000000000a = z b = z en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = z en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = z en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX HiZ) t12(67X HiZ) t13(57X HiZ) t14(37X HiZ) t15(SuH HiZ) t21(76X HiZ) t22(StX HiZ) t23(56X HiZ) t24(36X HiZ) t25(StH HiZ) t31(75X HiZ) t32(65X HiZ) t33(PuX HiZ) t34(35X HiZ) t35(PuH HiZ) t41(73X HiZ) t42(63X HiZ) t43(53X HiZ) t44(WeX HiZ) t45(WeH HiZ) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = x b = z en = 1 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX PuX) t12(67X PuX) t13(57X 35X) t14(37X 25X) t15(SuH PuH) t21(76X PuX) t22(StX PuX) t23(56X 35X) t24(36X 25X) t25(StH PuH) t31(75X 53X) t32(65X 53X) t33(PuX WeX) t34(35X 23X) t35(PuH WeH) t41(73X 52X) t42(63X 52X) t43(53X 32X) t44(WeX MeX) t45(WeH MeH) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = 0 b = z en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 PuL) t12(St0 PuL) t13(Pu0 WeL) t14(We0 MeL) t15(HiZ HiZ) t21(Su0 PuL) t22(St0 PuL) t23(Pu0 WeL) t24(We0 MeL) t25(HiZ HiZ) t31(Su0 PuL) t32(St0 PuL) t33(Pu0 WeL) t34(We0 MeL) t35(HiZ HiZ) t41(Su0 PuL) t42(St0 PuL) t43(Pu0 WeL) t44(We0 MeL) t45(HiZ HiZ) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = z en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 PuL) t12(St0 PuL) t13(Pu0 WeL) t14(We0 MeL) t15(HiZ HiZ) t21(Su0 PuL) t22(St0 PuL) t23(Pu0 WeL) t24(We0 MeL) t25(HiZ HiZ) t31(Su0 PuL) t32(St0 PuL) t33(Pu0 WeL) t34(We0 MeL) t35(HiZ HiZ) t41(Su0 PuL) t42(St0 PuL) t43(Pu0 WeL) t44(We0 MeL) t45(HiZ HiZ) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = z en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 HiZ) t12(St0 HiZ) t13(Pu0 HiZ) t14(We0 HiZ) t15(HiZ HiZ) t21(Su0 HiZ) t22(St0 HiZ) t23(Pu0 HiZ) t24(We0 HiZ) t25(HiZ HiZ) t31(Su0 HiZ) t32(St0 HiZ) t33(Pu0 HiZ) t34(We0 HiZ) t35(HiZ HiZ) t41(Su0 HiZ) t42(St0 HiZ) t43(Pu0 HiZ) t44(We0 HiZ) t45(HiZ HiZ) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 0 b = z en = 1 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Pu0) t12(St0 Pu0) t13(Pu0 We0) t14(We0 Me0) t15(HiZ HiZ) t21(Su0 Pu0) t22(St0 Pu0) t23(Pu0 We0) t24(We0 Me0) t25(HiZ HiZ) t31(Su0 Pu0) t32(St0 Pu0) t33(Pu0 We0) t34(We0 Me0) t35(HiZ HiZ) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 We0) t44(We0 Me0) t45(HiZ HiZ) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 1 b = z en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 PuH) t12(Su1 PuH) t13(Su1 PuH) t14(Su1 PuH) t15(Su1 PuH) t21(St1 PuH) t22(St1 PuH) t23(St1 PuH) t24(St1 PuH) t25(St1 PuH) t31(Pu1 WeH) t32(Pu1 WeH) t33(Pu1 WeH) t34(Pu1 WeH) t35(Pu1 WeH) t41(We1 MeH) t42(We1 MeH) t43(We1 MeH) t44(We1 MeH) t45(We1 MeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 PuH) t12(Su1 PuH) t13(Su1 PuH) t14(Su1 PuH) t15(Su1 PuH) t21(St1 PuH) t22(St1 PuH) t23(St1 PuH) t24(St1 PuH) t25(St1 PuH) t31(Pu1 WeH) t32(Pu1 WeH) t33(Pu1 WeH) t34(Pu1 WeH) t35(Pu1 WeH) t41(We1 MeH) t42(We1 MeH) t43(We1 MeH) t44(We1 MeH) t45(We1 MeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 HiZ) t12(Su1 HiZ) t13(Su1 HiZ) t14(Su1 HiZ) t15(Su1 HiZ) t21(St1 HiZ) t22(St1 HiZ) t23(St1 HiZ) t24(St1 HiZ) t25(St1 HiZ) t31(Pu1 HiZ) t32(Pu1 HiZ) t33(Pu1 HiZ) t34(Pu1 HiZ) t35(Pu1 HiZ) t41(We1 HiZ) t42(We1 HiZ) t43(We1 HiZ) t44(We1 HiZ) t45(We1 HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 1 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Pu1) t12(Su1 Pu1) t13(Su1 Pu1) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Pu1) t22(St1 Pu1) t23(St1 Pu1) t24(St1 Pu1) t25(St1 Pu1) t31(Pu1 We1) t32(Pu1 We1) t33(Pu1 We1) t34(Pu1 We1) t35(Pu1 We1) t41(We1 Me1) t42(We1 Me1) t43(We1 Me1) t44(We1 Me1) t45(We1 Me1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = x en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = x en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ SuX) t12(HiZ 67X) t13(HiZ 57X) t14(HiZ 37X) t15(HiZ SuH) t21(HiZ 76X) t22(HiZ StX) t23(HiZ 56X) t24(HiZ 36X) t25(HiZ StH) t31(HiZ 75X) t32(HiZ 65X) t33(HiZ PuX) t34(HiZ 35X) t35(HiZ PuH) t41(HiZ 73X) t42(HiZ 63X) t43(HiZ 53X) t44(HiZ WeX) t45(HiZ WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = z b = x en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuX SuX) t12(PuX 67X) t13(35X 57X) t14(25X 37X) t15(PuH SuH) t21(PuX 76X) t22(PuX StX) t23(35X 56X) t24(25X 36X) t25(PuH StH) t31(53X 75X) t32(53X 65X) t33(WeX PuX) t34(23X 35X) t35(WeH PuH) t41(52X 73X) t42(52X 63X) t43(32X 53X) t44(MeX WeX) t45(MeH WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = x b = x en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 1 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 SuX) t12(St0 67X) t13(Pu0 57X) t14(We0 37X) t15(HiZ SuH) t21(Su0 76X) t22(St0 StX) t23(Pu0 56X) t24(We0 36X) t25(HiZ StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(We0 35X) t35(HiZ PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(HiZ WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 1 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 SuX) t12(St0 67X) t13(PuX 57X) t14(35X 37X) t15(PuH SuH) t21(Su0 76X) t22(St0 StX) t23(PuX 56X) t24(35X 36X) t25(PuH StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(WeX 35X) t35(WeH PuH) t41(Su0 750) t42(St0 650) t43(Pu0 53X) t44(We0 WeX) t45(MeH WeH) t51(Su0 750) t52(St0 650) t53(Pu0 530) t54(We0 320) t55(HiZ HiZ) a = 1 b = x en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = 1 b = x en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 WeH) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = 1 b = x en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(Pu1 75X) t32(Pu1 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(We1 73X) t42(We1 63X) t43(We1 53X) t44(We1 WeX) t45(We1 WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = 1 b = x en = 1 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 751) t15(Su1 751) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 651) t25(St1 651) t31(PuX 75X) t32(PuX 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 531) t41(53X 73X) t42(53X 63X) t43(WeX 53X) t44(We1 WeX) t45(We1 321) t51(PuL SuL) t52(PuL StL) t53(WeL PuL) t54(MeL WeL) t55(HiZ HiZ) a = z b = 0 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuL Su0) t12(PuL St0) t13(WeL Pu0) t14(MeL We0) t15(HiZ HiZ) t21(PuL Su0) t22(PuL St0) t23(WeL Pu0) t24(MeL We0) t25(HiZ HiZ) t31(PuL Su0) t32(PuL St0) t33(WeL Pu0) t34(MeL We0) t35(HiZ HiZ) t41(PuL Su0) t42(PuL St0) t43(WeL Pu0) t44(MeL We0) t45(HiZ HiZ) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = z b = 0 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuL Su0) t12(PuL St0) t13(WeL Pu0) t14(MeL We0) t15(HiZ HiZ) t21(PuL Su0) t22(PuL St0) t23(WeL Pu0) t24(MeL We0) t25(HiZ HiZ) t31(PuL Su0) t32(PuL St0) t33(WeL Pu0) t34(MeL We0) t35(HiZ HiZ) t41(PuL Su0) t42(PuL St0) t43(WeL Pu0) t44(MeL We0) t45(HiZ HiZ) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = z b = 0 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su0) t12(HiZ St0) t13(HiZ Pu0) t14(HiZ We0) t15(HiZ HiZ) t21(HiZ Su0) t22(HiZ St0) t23(HiZ Pu0) t24(HiZ We0) t25(HiZ HiZ) t31(HiZ Su0) t32(HiZ St0) t33(HiZ Pu0) t34(HiZ We0) t35(HiZ HiZ) t41(HiZ Su0) t42(HiZ St0) t43(HiZ Pu0) t44(HiZ We0) t45(HiZ HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = z b = 0 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu0 Su0) t12(Pu0 St0) t13(We0 Pu0) t14(Me0 We0) t15(HiZ HiZ) t21(Pu0 Su0) t22(Pu0 St0) t23(We0 Pu0) t24(Me0 We0) t25(HiZ HiZ) t31(Pu0 Su0) t32(Pu0 St0) t33(We0 Pu0) t34(Me0 We0) t35(HiZ HiZ) t41(Pu0 Su0) t42(Pu0 St0) t43(We0 Pu0) t44(Me0 We0) t45(HiZ HiZ) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = x b = 0 en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su0) t12(67X St0) t13(57X Pu0) t14(37X We0) t15(SuH HiZ) t21(76X Su0) t22(StX St0) t23(56X Pu0) t24(36X We0) t25(StH HiZ) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X We0) t35(PuH HiZ) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH HiZ) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 1 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su0) t12(67X St0) t13(57X PuX) t14(37X 35X) t15(SuH PuH) t21(76X Su0) t22(StX St0) t23(56X PuX) t24(36X 35X) t25(StH PuH) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X WeX) t35(PuH WeH) t41(750 Su0) t42(650 St0) t43(53X Pu0) t44(WeX We0) t45(WeH MeH) t51(750 Su0) t52(650 St0) t53(530 Pu0) t54(320 We0) t55(HiZ HiZ) a = 0 b = 0 en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 1 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 35X) t15(Su1 PuH) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 35X) t25(St1 PuH) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 WeH) t41(53X Su0) t42(53X St0) t43(WeX Pu0) t44(We1 We0) t45(We1 MeH) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = 1 b = 0 en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 35X) t15(Su1 PuH) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 35X) t25(St1 PuH) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 WeH) t41(53X Su0) t42(53X St0) t43(WeX Pu0) t44(We1 We0) t45(We1 MeH) t51(PuL Su0) t52(PuL St0) t53(WeL Pu0) t54(MeL We0) t55(HiZ HiZ) a = 1 b = 0 en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su0) t12(Su1 St0) t13(Su1 Pu0) t14(Su1 We0) t15(Su1 HiZ) t21(St1 Su0) t22(St1 St0) t23(St1 Pu0) t24(St1 We0) t25(St1 HiZ) t31(Pu1 Su0) t32(Pu1 St0) t33(Pu1 Pu0) t34(Pu1 We0) t35(Pu1 HiZ) t41(We1 Su0) t42(We1 St0) t43(We1 Pu0) t44(We1 We0) t45(We1 HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = 1 b = 0 en = 1 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su0) t12(Su1 St0) t13(Su1 PuX) t14(Su1 Pu1) t15(Su1 Pu1) t21(St1 Su0) t22(St1 St0) t23(St1 PuX) t24(St1 Pu1) t25(St1 Pu1) t31(PuX Su0) t32(PuX St0) t33(Pu1 Pu0) t34(Pu1 WeX) t35(Pu1 We1) t41(Pu0 Su0) t42(Pu0 St0) t43(WeX Pu0) t44(We1 We0) t45(We1 Me1) t51(Pu0 Su0) t52(Pu0 St0) t53(We0 Pu0) t54(Me0 We0) t55(HiZ HiZ) a = z b = 1 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuH Su1) t12(PuH Su1) t13(PuH Su1) t14(PuH Su1) t15(PuH Su1) t21(PuH St1) t22(PuH St1) t23(PuH St1) t24(PuH St1) t25(PuH St1) t31(WeH Pu1) t32(WeH Pu1) t33(WeH Pu1) t34(WeH Pu1) t35(WeH Pu1) t41(MeH We1) t42(MeH We1) t43(MeH We1) t44(MeH We1) t45(MeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(PuH Su1) t12(PuH Su1) t13(PuH Su1) t14(PuH Su1) t15(PuH Su1) t21(PuH St1) t22(PuH St1) t23(PuH St1) t24(PuH St1) t25(PuH St1) t31(WeH Pu1) t32(WeH Pu1) t33(WeH Pu1) t34(WeH Pu1) t35(WeH Pu1) t41(MeH We1) t42(MeH We1) t43(MeH We1) t44(MeH We1) t45(MeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su1) t12(HiZ Su1) t13(HiZ Su1) t14(HiZ Su1) t15(HiZ Su1) t21(HiZ St1) t22(HiZ St1) t23(HiZ St1) t24(HiZ St1) t25(HiZ St1) t31(HiZ Pu1) t32(HiZ Pu1) t33(HiZ Pu1) t34(HiZ Pu1) t35(HiZ Pu1) t41(HiZ We1) t42(HiZ We1) t43(HiZ We1) t44(HiZ We1) t45(HiZ We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Pu1 Su1) t12(Pu1 Su1) t13(Pu1 Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Pu1 St1) t22(Pu1 St1) t23(Pu1 St1) t24(Pu1 St1) t25(Pu1 St1) t31(We1 Pu1) t32(We1 Pu1) t33(We1 Pu1) t34(We1 Pu1) t35(We1 Pu1) t41(Me1 We1) t42(Me1 We1) t43(Me1 We1) t44(Me1 We1) t45(Me1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 en = z a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(WeH We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = 1 en = x a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(WeH We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = x b = 1 en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X Pu1) t32(65X Pu1) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X We1) t42(63X We1) t43(53X We1) t44(WeX We1) t45(WeH We1) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = x b = 1 en = 1 a1(SuX) a2(PuX) a3(WeX) a4(MeX) a5(SmX) a6(SmX) a7(SmX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(751 Su1) t15(751 Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(651 St1) t25(651 St1) t31(75X PuX) t32(65X PuX) t33(PuX Pu1) t34(35X Pu1) t35(531 Pu1) t41(73X 53X) t42(63X 53X) t43(53X WeX) t44(WeX We1) t45(321 We1) t51(SuL PuL) t52(StL PuL) t53(PuL WeL) t54(WeL MeL) t55(HiZ HiZ) a = 0 b = 1 en = z a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(35X Su1) t15(PuH Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(35X St1) t25(PuH St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(WeH Pu1) t41(Su0 53X) t42(St0 53X) t43(Pu0 WeX) t44(We0 We1) t45(MeH We1) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = 1 en = x a1(Su0) a2(PuL) a3(WeL) a4(MeL) a5(SmL) a6(SmL) a7(SmL) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(35X Su1) t15(PuH Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(35X St1) t25(PuH St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(WeH Pu1) t41(Su0 53X) t42(St0 53X) t43(Pu0 WeX) t44(We0 We1) t45(MeH We1) t51(Su0 PuL) t52(St0 PuL) t53(Pu0 WeL) t54(We0 MeL) t55(HiZ HiZ) a = 0 b = 1 en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su1) t12(St0 Su1) t13(Pu0 Su1) t14(We0 Su1) t15(HiZ Su1) t21(Su0 St1) t22(St0 St1) t23(Pu0 St1) t24(We0 St1) t25(HiZ St1) t31(Su0 Pu1) t32(St0 Pu1) t33(Pu0 Pu1) t34(We0 Pu1) t35(HiZ Pu1) t41(Su0 We1) t42(St0 We1) t43(Pu0 We1) t44(We0 We1) t45(HiZ We1) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 0 b = 1 en = 1 a1(Su0) a2(Pu0) a3(We0) a4(Me0) a5(Sm0) a6(Sm0) a7(Sm0) t11(Su0 Su1) t12(St0 Su1) t13(PuX Su1) t14(Pu1 Su1) t15(Pu1 Su1) t21(Su0 St1) t22(St0 St1) t23(PuX St1) t24(Pu1 St1) t25(Pu1 St1) t31(Su0 PuX) t32(St0 PuX) t33(Pu0 Pu1) t34(WeX Pu1) t35(We1 Pu1) t41(Su0 Pu0) t42(St0 Pu0) t43(Pu0 WeX) t44(We0 We1) t45(Me1 We1) t51(Su0 Pu0) t52(St0 Pu0) t53(Pu0 We0) t54(We0 Me0) t55(HiZ HiZ) a = 1 b = 1 en = z a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = x a1(Su1) a2(PuH) a3(WeH) a4(MeH) a5(SmH) a6(SmH) a7(SmH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 1 a1(Su1) a2(Pu1) a3(We1) a4(Me1) a5(Sm1) a6(Sm1) a7(Sm1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/scan-invalid.gold000066400000000000000000000017701435245347300210360ustar00rootroot00000000000000ERROR: ./ivltests/scan-invalid.v:10: $sscanf requires at least three argument. ERROR: ./ivltests/scan-invalid.v:11: $sscanf's first argument must be a register or a string. ERROR: ./ivltests/scan-invalid.v:12: $sscanf requires at least three argument. ERROR: ./ivltests/scan-invalid.v:13: $sscanf argument 3 (a vpiModule) is not assignable. ERROR: ./ivltests/scan-invalid.v:14: $sscanf argument 3 (a vpiNet) is not assignable. ERROR: ./ivltests/scan-invalid.v:15: $sscanf argument 4 (a vpiNet) is not assignable. ERROR: ./ivltests/scan-invalid.v:20: $fscanf requires at least three argument. ERROR: ./ivltests/scan-invalid.v:21: $fscanf's first argument (fd) must be numeric. ERROR: ./ivltests/scan-invalid.v:22: $fscanf requires at least three argument. ERROR: ./ivltests/scan-invalid.v:23: $fscanf argument 3 (a vpiModule) is not assignable. ERROR: ./ivltests/scan-invalid.v:24: $fscanf argument 3 (a vpiNet) is not assignable. ERROR: ./ivltests/scan-invalid.v:25: $fscanf argument 4 (a vpiNet) is not assignable. iverilog-12_0/ivtest/gold/scoped_events.gold000066400000000000000000000002171435245347300213220ustar00rootroot00000000000000generate block 1 triggered generate block 2 triggered generate block 3 triggered generate block 4 triggered block 5 triggered task 6 triggered iverilog-12_0/ivtest/gold/sdf1.gold000066400000000000000000000002571435245347300173220ustar00rootroot00000000000000 0 A=x, B=x, Q=x 10 A=1, B=1, Q=x 13 A=1, B=1, Q=0 20 A=1, B=0, Q=0 23 A=1, B=0, Q=1 iverilog-12_0/ivtest/gold/sdf5.gold000066400000000000000000000004031435245347300173170ustar00rootroot00000000000000 0 D=0, Q=x, clk=0 10 D=0, Q=x, clk=1 13 D=0, Q=0, clk=1 20 D=1, Q=0, clk=0 30 D=1, Q=0, clk=1 33 D=1, Q=1, clk=1 40 D=1, Q=1, clk=0 iverilog-12_0/ivtest/gold/sdf6.gold000066400000000000000000000010611435245347300173210ustar00rootroot00000000000000 0 d=0, clk=0, set=0, clr=0, q=x 10 d=1, clk=0, set=0, clr=0, q=x 20 d=1, clk=0, set=1, clr=0, q=x 24 d=1, clk=0, set=1, clr=0, q=1 30 d=1, clk=0, set=0, clr=0, q=1 40 d=1, clk=0, set=0, clr=1, q=1 43 d=1, clk=0, set=0, clr=1, q=0 50 d=1, clk=0, set=0, clr=0, q=0 60 d=1, clk=1, set=0, clr=0, q=0 66 d=1, clk=1, set=0, clr=0, q=1 70 d=0, clk=1, set=0, clr=0, q=1 iverilog-12_0/ivtest/gold/sdf7.gold000066400000000000000000000004731435245347300173300ustar00rootroot00000000000000 0 A=x, B=x, Q=x 10 A=1, B=1, Q=x 13 A=1, B=1, Q=0 20 A=1, B=0, Q=0 21 A=1, B=0, Q=1 30 A=1, B=1, Q=1 33 A=1, B=1, Q=0 40 A=0, B=1, Q=0 41 A=0, B=1, Q=1 iverilog-12_0/ivtest/gold/sdf8.gold000066400000000000000000000002571435245347300173310ustar00rootroot00000000000000 0 A=x, B=1, Q=x 10 A=1, B=1, Q=x 13 A=1, B=1, Q=0 20 A=0, B=1, Q=0 22 A=0, B=1, Q=1 iverilog-12_0/ivtest/gold/sel_rval_bit_ob.gold000066400000000000000000000236701435245347300216160ustar00rootroot00000000000000./ivltests/sel_rval_bit_ob.v:60: warning: Constant bit select [32] is after pvar0[31:0]. ./ivltests/sel_rval_bit_ob.v:60: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:65: warning: Constant bit select [-1] is before pvar0[31:0]. ./ivltests/sel_rval_bit_ob.v:65: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:70: warning: Constant undefined bit select [1'bx] for parameter 'pvar0'. ./ivltests/sel_rval_bit_ob.v:70: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:75: warning: Constant undefined bit select [1'bz] for parameter 'pvar0'. ./ivltests/sel_rval_bit_ob.v:75: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:89: warning: Constant bit select [32] is after pvar1[31:0]. ./ivltests/sel_rval_bit_ob.v:89: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:94: warning: Constant bit select [-1] is before pvar1[31:0]. ./ivltests/sel_rval_bit_ob.v:94: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:99: warning: Constant undefined bit select [1'bx] for parameter 'pvar1'. ./ivltests/sel_rval_bit_ob.v:99: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:104: warning: Constant undefined bit select [1'bz] for parameter 'pvar1'. ./ivltests/sel_rval_bit_ob.v:104: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:118: warning: Constant bit select [32] is after pvar2[31:0]. ./ivltests/sel_rval_bit_ob.v:118: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:123: warning: Constant bit select [-1] is before pvar2[31:0]. ./ivltests/sel_rval_bit_ob.v:123: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:128: warning: Constant undefined bit select [1'bx] for parameter 'pvar2'. ./ivltests/sel_rval_bit_ob.v:128: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:133: warning: Constant undefined bit select [1'bz] for parameter 'pvar2'. ./ivltests/sel_rval_bit_ob.v:133: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:142: warning: Constant bit select [4] is after pvar3[3:0]. ./ivltests/sel_rval_bit_ob.v:142: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:147: warning: Constant bit select [-1] is before pvar3[3:0]. ./ivltests/sel_rval_bit_ob.v:147: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:152: warning: Constant undefined bit select [1'bx] for parameter 'pvar3'. ./ivltests/sel_rval_bit_ob.v:152: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:157: warning: Constant undefined bit select [1'bz] for parameter 'pvar3'. ./ivltests/sel_rval_bit_ob.v:157: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:166: warning: Constant bit select [5] is after pvar4[4:1]. ./ivltests/sel_rval_bit_ob.v:166: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:171: warning: Constant bit select [0] is before pvar4[4:1]. ./ivltests/sel_rval_bit_ob.v:171: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:176: warning: Constant undefined bit select [1'bx] for parameter 'pvar4'. ./ivltests/sel_rval_bit_ob.v:176: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:181: warning: Constant undefined bit select [1'bz] for parameter 'pvar4'. ./ivltests/sel_rval_bit_ob.v:181: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:190: warning: Constant bit select [0] is after pvar5[1:4]. ./ivltests/sel_rval_bit_ob.v:190: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:195: warning: Constant bit select [5] is before pvar5[1:4]. ./ivltests/sel_rval_bit_ob.v:195: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:200: warning: Constant undefined bit select [1'bx] for parameter 'pvar5'. ./ivltests/sel_rval_bit_ob.v:200: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:205: warning: Constant undefined bit select [1'bz] for parameter 'pvar5'. ./ivltests/sel_rval_bit_ob.v:205: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:215: warning: Constant bit select [5] is after vector rvar[4:1]. ./ivltests/sel_rval_bit_ob.v:215: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:220: warning: Constant bit select [0] is before vector rvar[4:1]. ./ivltests/sel_rval_bit_ob.v:220: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:225: warning: Constant bit select [1'bx] is undefined for vector 'rvar'. ./ivltests/sel_rval_bit_ob.v:225: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:230: warning: Constant bit select [1'bz] is undefined for vector 'rvar'. ./ivltests/sel_rval_bit_ob.v:230: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:239: warning: Constant bit select [0] is after vector rvar2[1:4]. ./ivltests/sel_rval_bit_ob.v:239: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:244: warning: Constant bit select [5] is before vector rvar2[1:4]. ./ivltests/sel_rval_bit_ob.v:244: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:249: warning: Constant bit select [1'bx] is undefined for vector 'rvar2'. ./ivltests/sel_rval_bit_ob.v:249: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:254: warning: Constant bit select [1'bz] is undefined for vector 'rvar2'. ./ivltests/sel_rval_bit_ob.v:254: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:264: warning: Constant bit select [5] is after array word ravar[][4:1]. ./ivltests/sel_rval_bit_ob.v:264: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:269: warning: Constant bit select [0] is before array word ravar[][4:1]. ./ivltests/sel_rval_bit_ob.v:269: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:274: warning: Constant bit select [1'bx] is undefined for array word 'ravar[]'. ./ivltests/sel_rval_bit_ob.v:274: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:279: warning: Constant bit select [1'bz] is undefined for array word 'ravar[]'. ./ivltests/sel_rval_bit_ob.v:279: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:288: warning: Constant bit select [0] is after array word ravar2[][1:4]. ./ivltests/sel_rval_bit_ob.v:288: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:293: warning: Constant bit select [5] is before array word ravar2[][1:4]. ./ivltests/sel_rval_bit_ob.v:293: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:298: warning: Constant bit select [1'bx] is undefined for array word 'ravar2[]'. ./ivltests/sel_rval_bit_ob.v:298: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:303: warning: Constant bit select [1'bz] is undefined for array word 'ravar2[]'. ./ivltests/sel_rval_bit_ob.v:303: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:313: warning: Constant bit select [5] is after vector wvar[4:1]. ./ivltests/sel_rval_bit_ob.v:313: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:318: warning: Constant bit select [0] is before vector wvar[4:1]. ./ivltests/sel_rval_bit_ob.v:318: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:323: warning: Constant bit select [1'bx] is undefined for vector 'wvar'. ./ivltests/sel_rval_bit_ob.v:323: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:328: warning: Constant bit select [1'bz] is undefined for vector 'wvar'. ./ivltests/sel_rval_bit_ob.v:328: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:337: warning: Constant bit select [0] is after vector wvar2[1:4]. ./ivltests/sel_rval_bit_ob.v:337: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:342: warning: Constant bit select [5] is before vector wvar2[1:4]. ./ivltests/sel_rval_bit_ob.v:342: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:347: warning: Constant bit select [1'bx] is undefined for vector 'wvar2'. ./ivltests/sel_rval_bit_ob.v:347: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:352: warning: Constant bit select [1'bz] is undefined for vector 'wvar2'. ./ivltests/sel_rval_bit_ob.v:352: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:362: warning: Constant bit select [5] is after array word wavar[][4:1]. ./ivltests/sel_rval_bit_ob.v:362: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:367: warning: Constant bit select [0] is before array word wavar[][4:1]. ./ivltests/sel_rval_bit_ob.v:367: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:372: warning: Constant bit select [1'bx] is undefined for array word 'wavar[]'. ./ivltests/sel_rval_bit_ob.v:372: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:377: warning: Constant bit select [1'bz] is undefined for array word 'wavar[]'. ./ivltests/sel_rval_bit_ob.v:377: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:386: warning: Constant bit select [0] is after array word wavar2[][1:4]. ./ivltests/sel_rval_bit_ob.v:386: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:391: warning: Constant bit select [5] is before array word wavar2[][1:4]. ./ivltests/sel_rval_bit_ob.v:391: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:397: warning: Constant bit select [1'bx] is undefined for array word 'wavar2[]'. ./ivltests/sel_rval_bit_ob.v:397: : Replacing select with a constant 1'bx. ./ivltests/sel_rval_bit_ob.v:403: warning: Constant bit select [1'bz] is undefined for array word 'wavar2[]'. ./ivltests/sel_rval_bit_ob.v:403: : Replacing select with a constant 1'bx. PASSED iverilog-12_0/ivtest/gold/sel_rval_part_ob.gold000066400000000000000000000512751435245347300220100ustar00rootroot00000000000000./ivltests/sel_rval_part_ob.v:57: warning: Part select pvar0[33:32] is selecting after the parameter pvar0[31:0]. ./ivltests/sel_rval_part_ob.v:57: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:62: warning: Part select pvar0[32:31] is selecting after the parameter pvar0[31:0]. ./ivltests/sel_rval_part_ob.v:62: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:68: warning: Part select [-1:-2] is selecting before the parameter pvar0[31:0]. ./ivltests/sel_rval_part_ob.v:68: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:73: warning: Part select [0:-1] is selecting before the parameter pvar0[31:0]. ./ivltests/sel_rval_part_ob.v:73: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:79: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar0'. ./ivltests/sel_rval_part_ob.v:79: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:85: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar0'. ./ivltests/sel_rval_part_ob.v:85: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:91: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar0'. ./ivltests/sel_rval_part_ob.v:91: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:97: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar0'. ./ivltests/sel_rval_part_ob.v:97: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:112: warning: Part select pvar1[33:32] is selecting after the parameter pvar1[31:0]. ./ivltests/sel_rval_part_ob.v:112: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:117: warning: Part select pvar1[32:31] is selecting after the parameter pvar1[31:0]. ./ivltests/sel_rval_part_ob.v:117: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:123: warning: Part select [-1:-2] is selecting before the parameter pvar1[31:0]. ./ivltests/sel_rval_part_ob.v:123: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:128: warning: Part select [0:-1] is selecting before the parameter pvar1[31:0]. ./ivltests/sel_rval_part_ob.v:128: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:134: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar1'. ./ivltests/sel_rval_part_ob.v:134: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:140: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar1'. ./ivltests/sel_rval_part_ob.v:140: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:146: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar1'. ./ivltests/sel_rval_part_ob.v:146: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:152: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar1'. ./ivltests/sel_rval_part_ob.v:152: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:167: warning: Part select pvar2[33:32] is selecting after the parameter pvar2[31:0]. ./ivltests/sel_rval_part_ob.v:167: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:172: warning: Part select pvar2[32:31] is selecting after the parameter pvar2[31:0]. ./ivltests/sel_rval_part_ob.v:172: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:178: warning: Part select [-1:-2] is selecting before the parameter pvar2[31:0]. ./ivltests/sel_rval_part_ob.v:178: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:183: warning: Part select [0:-1] is selecting before the parameter pvar2[31:0]. ./ivltests/sel_rval_part_ob.v:183: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:189: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar2'. ./ivltests/sel_rval_part_ob.v:189: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:195: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar2'. ./ivltests/sel_rval_part_ob.v:195: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:201: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar2'. ./ivltests/sel_rval_part_ob.v:201: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:207: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar2'. ./ivltests/sel_rval_part_ob.v:207: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:217: warning: Part select pvar3[5:4] is selecting after the parameter pvar3[3:0]. ./ivltests/sel_rval_part_ob.v:217: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:222: warning: Part select pvar3[4:3] is selecting after the parameter pvar3[3:0]. ./ivltests/sel_rval_part_ob.v:222: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:228: warning: Part select [-1:-2] is selecting before the parameter pvar3[3:0]. ./ivltests/sel_rval_part_ob.v:228: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:233: warning: Part select [0:-1] is selecting before the parameter pvar3[3:0]. ./ivltests/sel_rval_part_ob.v:233: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:239: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar3'. ./ivltests/sel_rval_part_ob.v:239: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:245: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar3'. ./ivltests/sel_rval_part_ob.v:245: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:251: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar3'. ./ivltests/sel_rval_part_ob.v:251: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:257: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar3'. ./ivltests/sel_rval_part_ob.v:257: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:267: warning: Part select pvar4[6:5] is selecting after the parameter pvar4[4:1]. ./ivltests/sel_rval_part_ob.v:267: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:272: warning: Part select pvar4[5:4] is selecting after the parameter pvar4[4:1]. ./ivltests/sel_rval_part_ob.v:272: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:278: warning: Part select [0:-1] is selecting before the parameter pvar4[4:1]. ./ivltests/sel_rval_part_ob.v:278: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:283: warning: Part select [1:0] is selecting before the parameter pvar4[4:1]. ./ivltests/sel_rval_part_ob.v:283: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:289: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar4'. ./ivltests/sel_rval_part_ob.v:289: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:295: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar4'. ./ivltests/sel_rval_part_ob.v:295: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:301: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar4'. ./ivltests/sel_rval_part_ob.v:301: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:307: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar4'. ./ivltests/sel_rval_part_ob.v:307: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:317: warning: Part select pvar5[-1:0] is selecting after the parameter pvar5[1:4]. ./ivltests/sel_rval_part_ob.v:317: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:322: warning: Part select pvar5[0:1] is selecting after the parameter pvar5[1:4]. ./ivltests/sel_rval_part_ob.v:322: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:328: warning: Part select [5:6] is selecting before the parameter pvar5[1:4]. ./ivltests/sel_rval_part_ob.v:328: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:333: warning: Part select [4:5] is selecting before the parameter pvar5[1:4]. ./ivltests/sel_rval_part_ob.v:333: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:339: warning: Undefined part select [1'bx:'sd1] for parameter 'pvar5'. ./ivltests/sel_rval_part_ob.v:339: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:345: warning: Undefined part select ['sd1:1'bx] for parameter 'pvar5'. ./ivltests/sel_rval_part_ob.v:345: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:351: warning: Undefined part select [1'bz:'sd1] for parameter 'pvar5'. ./ivltests/sel_rval_part_ob.v:351: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:357: warning: Undefined part select ['sd1:1'bz] for parameter 'pvar5'. ./ivltests/sel_rval_part_ob.v:357: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:368: warning: Part select [6:5] is selecting after the vector rvar[4:1]. ./ivltests/sel_rval_part_ob.v:368: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:373: warning: Part select [5:4] is selecting after the vector rvar[4:1]. ./ivltests/sel_rval_part_ob.v:373: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:378: warning: Part select [0:-1] is selecting before the vector rvar[4:1]. ./ivltests/sel_rval_part_ob.v:378: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:383: warning: Part select [1:0] is selecting before the vector rvar[4:1]. ./ivltests/sel_rval_part_ob.v:383: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:388: warning: Undefined part select [1'bx:'sd1] for vector 'rvar'. ./ivltests/sel_rval_part_ob.v:388: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:393: warning: Undefined part select ['sd1:1'bx] for vector 'rvar'. ./ivltests/sel_rval_part_ob.v:393: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:398: warning: Undefined part select [1'bz:'sd1] for vector 'rvar'. ./ivltests/sel_rval_part_ob.v:398: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:403: warning: Undefined part select ['sd1:1'bz] for vector 'rvar'. ./ivltests/sel_rval_part_ob.v:403: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:412: warning: Part select [-1:0] is selecting after the vector rvar2[1:4]. ./ivltests/sel_rval_part_ob.v:412: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:417: warning: Part select [0:1] is selecting after the vector rvar2[1:4]. ./ivltests/sel_rval_part_ob.v:417: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:423: warning: Part select [5:6] is selecting before the vector rvar2[1:4]. ./ivltests/sel_rval_part_ob.v:423: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:428: warning: Part select [4:5] is selecting before the vector rvar2[1:4]. ./ivltests/sel_rval_part_ob.v:428: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:434: warning: Undefined part select [1'bx:'sd1] for vector 'rvar2'. ./ivltests/sel_rval_part_ob.v:434: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:440: warning: Undefined part select ['sd1:1'bx] for vector 'rvar2'. ./ivltests/sel_rval_part_ob.v:440: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:446: warning: Undefined part select [1'bz:'sd1] for vector 'rvar2'. ./ivltests/sel_rval_part_ob.v:446: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:451: warning: Undefined part select ['sd1:1'bz] for vector 'rvar2'. ./ivltests/sel_rval_part_ob.v:451: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:461: warning: Part select [6:5] is selecting after the array word ravar[][4:1]. ./ivltests/sel_rval_part_ob.v:461: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:466: warning: Part select [5:4] is selecting after the array word ravar[][4:1]. ./ivltests/sel_rval_part_ob.v:466: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:472: warning: Part select [0:-1] is selecting before the array word ravar[][4:1]. ./ivltests/sel_rval_part_ob.v:472: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:477: warning: Part select [1:0] is selecting before the array word ravar[][4:1]. ./ivltests/sel_rval_part_ob.v:477: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:483: warning: Undefined part select [1'bx:'sd1] for array word 'ravar[]'. ./ivltests/sel_rval_part_ob.v:483: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:489: warning: Undefined part select ['sd1:1'bx] for array word 'ravar[]'. ./ivltests/sel_rval_part_ob.v:489: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:495: warning: Undefined part select [1'bz:'sd1] for array word 'ravar[]'. ./ivltests/sel_rval_part_ob.v:495: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:500: warning: Undefined part select ['sd1:1'bz] for array word 'ravar[]'. ./ivltests/sel_rval_part_ob.v:500: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:509: warning: Part select [-1:0] is selecting after the array word ravar2[][1:4]. ./ivltests/sel_rval_part_ob.v:509: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:514: warning: Part select [0:1] is selecting after the array word ravar2[][1:4]. ./ivltests/sel_rval_part_ob.v:514: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:520: warning: Part select [5:6] is selecting before the array word ravar2[][1:4]. ./ivltests/sel_rval_part_ob.v:520: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:525: warning: Part select [4:5] is selecting before the array word ravar2[][1:4]. ./ivltests/sel_rval_part_ob.v:525: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:531: warning: Undefined part select [1'bx:'sd1] for array word 'ravar2[]'. ./ivltests/sel_rval_part_ob.v:531: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:537: warning: Undefined part select ['sd1:1'bx] for array word 'ravar2[]'. ./ivltests/sel_rval_part_ob.v:537: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:543: warning: Undefined part select [1'bz:'sd1] for array word 'ravar2[]'. ./ivltests/sel_rval_part_ob.v:543: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:549: warning: Undefined part select ['sd1:1'bz] for array word 'ravar2[]'. ./ivltests/sel_rval_part_ob.v:549: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:560: warning: Part select [6:5] is selecting after the vector wvar[4:1]. ./ivltests/sel_rval_part_ob.v:560: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:565: warning: Part select [5:4] is selecting after the vector wvar[4:1]. ./ivltests/sel_rval_part_ob.v:565: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:570: warning: Part select [0:-1] is selecting before the vector wvar[4:1]. ./ivltests/sel_rval_part_ob.v:570: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:575: warning: Part select [1:0] is selecting before the vector wvar[4:1]. ./ivltests/sel_rval_part_ob.v:575: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:580: warning: Undefined part select [1'bx:'sd1] for vector 'wvar'. ./ivltests/sel_rval_part_ob.v:580: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:585: warning: Undefined part select ['sd1:1'bx] for vector 'wvar'. ./ivltests/sel_rval_part_ob.v:585: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:590: warning: Undefined part select [1'bz:'sd1] for vector 'wvar'. ./ivltests/sel_rval_part_ob.v:590: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:595: warning: Undefined part select ['sd1:1'bz] for vector 'wvar'. ./ivltests/sel_rval_part_ob.v:595: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:604: warning: Part select [-1:0] is selecting after the vector wvar2[1:4]. ./ivltests/sel_rval_part_ob.v:604: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:609: warning: Part select [0:1] is selecting after the vector wvar2[1:4]. ./ivltests/sel_rval_part_ob.v:609: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:614: warning: Part select [5:6] is selecting before the vector wvar2[1:4]. ./ivltests/sel_rval_part_ob.v:614: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:619: warning: Part select [4:5] is selecting before the vector wvar2[1:4]. ./ivltests/sel_rval_part_ob.v:619: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:624: warning: Undefined part select [1'bx:'sd1] for vector 'wvar2'. ./ivltests/sel_rval_part_ob.v:624: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:629: warning: Undefined part select ['sd1:1'bx] for vector 'wvar2'. ./ivltests/sel_rval_part_ob.v:629: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:634: warning: Undefined part select [1'bz:'sd1] for vector 'wvar2'. ./ivltests/sel_rval_part_ob.v:634: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:639: warning: Undefined part select ['sd1:1'bz] for vector 'wvar2'. ./ivltests/sel_rval_part_ob.v:639: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:649: warning: Part select [6:5] is selecting after the array word wavar[][4:1]. ./ivltests/sel_rval_part_ob.v:649: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:654: warning: Part select [5:4] is selecting after the array word wavar[][4:1]. ./ivltests/sel_rval_part_ob.v:654: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:660: warning: Part select [0:-1] is selecting before the array word wavar[][4:1]. ./ivltests/sel_rval_part_ob.v:660: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:665: warning: Part select [1:0] is selecting before the array word wavar[][4:1]. ./ivltests/sel_rval_part_ob.v:665: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:671: warning: Undefined part select [1'bx:'sd1] for array word 'wavar[]'. ./ivltests/sel_rval_part_ob.v:671: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:677: warning: Undefined part select ['sd1:1'bx] for array word 'wavar[]'. ./ivltests/sel_rval_part_ob.v:677: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:683: warning: Undefined part select [1'bz:'sd1] for array word 'wavar[]'. ./ivltests/sel_rval_part_ob.v:683: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:689: warning: Undefined part select ['sd1:1'bz] for array word 'wavar[]'. ./ivltests/sel_rval_part_ob.v:689: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:699: warning: Part select [-1:0] is selecting after the array word wavar2[][1:4]. ./ivltests/sel_rval_part_ob.v:699: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:705: warning: Part select [0:1] is selecting after the array word wavar2[][1:4]. ./ivltests/sel_rval_part_ob.v:705: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:711: warning: Part select [5:6] is selecting before the array word wavar2[][1:4]. ./ivltests/sel_rval_part_ob.v:711: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:717: warning: Part select [4:5] is selecting before the array word wavar2[][1:4]. ./ivltests/sel_rval_part_ob.v:717: : Replacing the out of bound bits with 'bx. ./ivltests/sel_rval_part_ob.v:723: warning: Undefined part select [1'bx:'sd1] for array word 'wavar2[]'. ./ivltests/sel_rval_part_ob.v:723: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:729: warning: Undefined part select ['sd1:1'bx] for array word 'wavar2[]'. ./ivltests/sel_rval_part_ob.v:729: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:735: warning: Undefined part select [1'bz:'sd1] for array word 'wavar2[]'. ./ivltests/sel_rval_part_ob.v:735: : Replacing select with a constant 'bx. ./ivltests/sel_rval_part_ob.v:741: warning: Undefined part select ['sd1:1'bz] for array word 'wavar2[]'. ./ivltests/sel_rval_part_ob.v:741: : Replacing select with a constant 'bx. PASSED iverilog-12_0/ivtest/gold/select3.gold000066400000000000000000000003001435245347300200140ustar00rootroot00000000000000dut[00] = 0 dut[01] = 1 dut[02] = 0 dut[03] = 1 dut[04] = 0 dut[05] = 1 dut[06] = 0 dut[07] = 1 dut[08] = 1 dut[09] = 0 dut[0a] = 1 dut[0b] = 0 dut[0c] = 1 dut[0d] = 0 dut[0e] = 1 dut[0f] = 0 iverilog-12_0/ivtest/gold/sf_countbits_fail.gold000066400000000000000000000026271435245347300221650ustar00rootroot00000000000000./ivltests/sf_countbits_fail.v:6: error: constant function $countbits() does not support a single argument. ./ivltests/sf_countbits_fail.v:7: error: constant function $countbits() does not support a single argument. ./ivltests/sf_countbits_fail.v:8: error: constant function $countbits() does not support a single argument. ./ivltests/sf_countbits_fail.v:9: error: constant function $countbits() does not support a string argument (1). ./ivltests/sf_countbits_fail.v:10: error: constant function $countbits() does not support a string argument (2). ./ivltests/sf_countbits_fail.v:11: error: constant function $countbits() does not support a string argument (3). ERROR: ./ivltests/sf_countbits_fail.v:6: The first argument to $countbits() must be numeric. ERROR: ./ivltests/sf_countbits_fail.v:6: $countbits() requires at least one control bit argument. ERROR: ./ivltests/sf_countbits_fail.v:7: The first argument to $countbits() must be numeric. ERROR: ./ivltests/sf_countbits_fail.v:7: $countbits() requires at least one control bit argument. ERROR: ./ivltests/sf_countbits_fail.v:8: $countbits() requires at least one control bit argument. ERROR: ./ivltests/sf_countbits_fail.v:9: The first argument to $countbits() must be numeric. ERROR: ./ivltests/sf_countbits_fail.v:10: Control bit argument 1 to $countbits() must be numeric. ERROR: ./ivltests/sf_countbits_fail.v:11: Control bit argument 2 to $countbits() must be numeric. iverilog-12_0/ivtest/gold/sf_countones_fail.gold000066400000000000000000000010161435245347300221570ustar00rootroot00000000000000./ivltests/sf_countones_fail.v:7: error: constant function $countones() does not support a string argument (1). ./ivltests/sf_countones_fail.v:8: error: constant function $countones() does not support two arguments. ERROR: ./ivltests/sf_countones_fail.v:6: $countones's argument must be numeric. ERROR: ./ivltests/sf_countones_fail.v:7: $countones's argument must be numeric. ERROR: ./ivltests/sf_countones_fail.v:8: $countones takes a single numeric argument. Found 1 extra argument. iverilog-12_0/ivtest/gold/sf_isunknown_fail.gold000066400000000000000000000010161435245347300221750ustar00rootroot00000000000000./ivltests/sf_isunknown_fail.v:7: error: constant function $isunknown() does not support a string argument (1). ./ivltests/sf_isunknown_fail.v:8: error: constant function $isunknown() does not support two arguments. ERROR: ./ivltests/sf_isunknown_fail.v:6: $isunknown's argument must be numeric. ERROR: ./ivltests/sf_isunknown_fail.v:7: $isunknown's argument must be numeric. ERROR: ./ivltests/sf_isunknown_fail.v:8: $isunknown takes a single numeric argument. Found 1 extra argument. iverilog-12_0/ivtest/gold/sf_onehot0_fail.gold000066400000000000000000000007701435245347300215240ustar00rootroot00000000000000./ivltests/sf_onehot0_fail.v:7: error: constant function $onehot0() does not support a string argument (1). ./ivltests/sf_onehot0_fail.v:8: error: constant function $onehot0() does not support two arguments. ERROR: ./ivltests/sf_onehot0_fail.v:6: $onehot0's argument must be numeric. ERROR: ./ivltests/sf_onehot0_fail.v:7: $onehot0's argument must be numeric. ERROR: ./ivltests/sf_onehot0_fail.v:8: $onehot0 takes a single numeric argument. Found 1 extra argument. iverilog-12_0/ivtest/gold/sf_onehot_fail.gold000066400000000000000000000007551435245347300214470ustar00rootroot00000000000000./ivltests/sf_onehot_fail.v:7: error: constant function $onehot() does not support a string argument (1). ./ivltests/sf_onehot_fail.v:8: error: constant function $onehot() does not support two arguments. ERROR: ./ivltests/sf_onehot_fail.v:6: $onehot's argument must be numeric. ERROR: ./ivltests/sf_onehot_fail.v:7: $onehot's argument must be numeric. ERROR: ./ivltests/sf_onehot_fail.v:8: $onehot takes a single numeric argument. Found 1 extra argument. iverilog-12_0/ivtest/gold/shellho1.gold000066400000000000000000000003131435245347300201750ustar00rootroot00000000000000Running first test. PASS! top.memory.memory[0] set correctly. top.memory.memory[0] = f Running second test. top.memory.memory[1] = f PASS! top.memory.memory[1] set correctly. top.memory.memory[1] = f iverilog-12_0/ivtest/gold/shift1.gold000066400000000000000000000000331435245347300176530ustar00rootroot0000000000000002 55 55 80 00 00 02 55 55 iverilog-12_0/ivtest/gold/shift5.gold000066400000000000000000000000531435245347300176610ustar00rootroot00000000000000PASS: 32'sh80000000 >>> 6'd32 = 0xffffffff iverilog-12_0/ivtest/gold/signed10.gold000066400000000000000000000000411435245347300200660ustar00rootroot00000000000000foo=-2 bar=254 $signed(bar)=-2 iverilog-12_0/ivtest/gold/signed12.gold000066400000000000000000000000111435245347300200650ustar00rootroot0000000000000011111111 iverilog-12_0/ivtest/gold/signed4.gold000066400000000000000000000001021435245347300200070ustar00rootroot00000000000000x = 3 (should be 3) y = -3 (should be -3) x = 253 (should be 253) iverilog-12_0/ivtest/gold/sp2.inv000066400000000000000000000000251435245347300170310ustar00rootroot00000000000000# captured from: fo iverilog-12_0/ivtest/gold/specify3.gold000066400000000000000000000015341435245347300202110ustar00rootroot00000000000000 10 a=0, b=0, fast=0, q=0 20 a=1, b=0, fast=0, q=0 24 a=1, b=0, fast=0, q=1 30 a=0, b=0, fast=0, q=1 34 a=0, b=0, fast=0, q=0 40 a=0, b=1, fast=0, q=0 44 a=0, b=1, fast=0, q=1 50 a=0, b=0, fast=0, q=1 54 a=0, b=0, fast=0, q=0 60 a=1, b=0, fast=0, q=0 64 a=1, b=0, fast=0, q=1 70 a=1, b=0, fast=1, q=1 80 a=1, b=1, fast=1, q=1 81 a=1, b=1, fast=1, q=0 90 a=1, b=0, fast=1, q=0 91 a=1, b=0, fast=1, q=1 100 a=0, b=0, fast=1, q=1 101 a=0, b=0, fast=1, q=0 110 a=1, b=0, fast=1, q=0 111 a=1, b=0, fast=1, q=1 iverilog-12_0/ivtest/gold/specify4.gold000066400000000000000000000004731435245347300202130ustar00rootroot00000000000000 10 q=0, d=0, c=1 15 q=0, d=0, c=0 20 q=0, d=0, c=1 25 q=0, d=1, c=0 30 q=0, d=1, c=1 33 q=1, d=1, c=1 35 q=1, d=0, c=0 40 q=1, d=0, c=1 42 q=0, d=0, c=1 iverilog-12_0/ivtest/gold/specify5.gold000066400000000000000000000007541435245347300202160ustar00rootroot00000000000000 0.00 ns - cdn=x, cp=0, d=1, qr=x, qp=x 10.00 ns - cdn=0, cp=0, d=1, qr=x, qp=x 10.30 ns - cdn=0, cp=0, d=1, qr=0, qp=0 20.00 ns - cdn=1, cp=0, d=1, qr=0, qp=0 30.00 ns - cdn=1, cp=1, d=1, qr=0, qp=0 30.60 ns - cdn=1, cp=1, d=1, qr=1, qp=1 40.00 ns - cdn=1, cp=0, d=0, qr=1, qp=1 50.00 ns - cdn=1, cp=1, d=0, qr=1, qp=1 50.70 ns - cdn=1, cp=1, d=0, qr=0, qp=0 60.00 ns - cdn=1, cp=0, d=1, qr=0, qp=0 70.00 ns - cdn=1, cp=1, d=1, qr=0, qp=0 70.60 ns - cdn=1, cp=1, d=1, qr=1, qp=1 iverilog-12_0/ivtest/gold/stask_parm2.gold000066400000000000000000000102631435245347300207110ustar00rootroot00000000000000{a, b} == 00000000 {a, b} == 00000001 {a, b} == 00000010 {a, b} == 00000011 {a, b} == 00000100 {a, b} == 00000101 {a, b} == 00000110 {a, b} == 00000111 {a, b} == 00001000 {a, b} == 00001001 {a, b} == 00001010 {a, b} == 00001011 {a, b} == 00001100 {a, b} == 00001101 {a, b} == 00001110 {a, b} == 00010000 {a, b} == 00010001 {a, b} == 00010010 {a, b} == 00010011 {a, b} == 00010100 {a, b} == 00010101 {a, b} == 00010110 {a, b} == 00010111 {a, b} == 00011000 {a, b} == 00011001 {a, b} == 00011010 {a, b} == 00011011 {a, b} == 00011100 {a, b} == 00011101 {a, b} == 00011110 {a, b} == 00100000 {a, b} == 00100001 {a, b} == 00100010 {a, b} == 00100011 {a, b} == 00100100 {a, b} == 00100101 {a, b} == 00100110 {a, b} == 00100111 {a, b} == 00101000 {a, b} == 00101001 {a, b} == 00101010 {a, b} == 00101011 {a, b} == 00101100 {a, b} == 00101101 {a, b} == 00101110 {a, b} == 00110000 {a, b} == 00110001 {a, b} == 00110010 {a, b} == 00110011 {a, b} == 00110100 {a, b} == 00110101 {a, b} == 00110110 {a, b} == 00110111 {a, b} == 00111000 {a, b} == 00111001 {a, b} == 00111010 {a, b} == 00111011 {a, b} == 00111100 {a, b} == 00111101 {a, b} == 00111110 {a, b} == 01000000 {a, b} == 01000001 {a, b} == 01000010 {a, b} == 01000011 {a, b} == 01000100 {a, b} == 01000101 {a, b} == 01000110 {a, b} == 01000111 {a, b} == 01001000 {a, b} == 01001001 {a, b} == 01001010 {a, b} == 01001011 {a, b} == 01001100 {a, b} == 01001101 {a, b} == 01001110 {a, b} == 01010000 {a, b} == 01010001 {a, b} == 01010010 {a, b} == 01010011 {a, b} == 01010100 {a, b} == 01010101 {a, b} == 01010110 {a, b} == 01010111 {a, b} == 01011000 {a, b} == 01011001 {a, b} == 01011010 {a, b} == 01011011 {a, b} == 01011100 {a, b} == 01011101 {a, b} == 01011110 {a, b} == 01100000 {a, b} == 01100001 {a, b} == 01100010 {a, b} == 01100011 {a, b} == 01100100 {a, b} == 01100101 {a, b} == 01100110 {a, b} == 01100111 {a, b} == 01101000 {a, b} == 01101001 {a, b} == 01101010 {a, b} == 01101011 {a, b} == 01101100 {a, b} == 01101101 {a, b} == 01101110 {a, b} == 01110000 {a, b} == 01110001 {a, b} == 01110010 {a, b} == 01110011 {a, b} == 01110100 {a, b} == 01110101 {a, b} == 01110110 {a, b} == 01110111 {a, b} == 01111000 {a, b} == 01111001 {a, b} == 01111010 {a, b} == 01111011 {a, b} == 01111100 {a, b} == 01111101 {a, b} == 01111110 {a, b} == 10000000 {a, b} == 10000001 {a, b} == 10000010 {a, b} == 10000011 {a, b} == 10000100 {a, b} == 10000101 {a, b} == 10000110 {a, b} == 10000111 {a, b} == 10001000 {a, b} == 10001001 {a, b} == 10001010 {a, b} == 10001011 {a, b} == 10001100 {a, b} == 10001101 {a, b} == 10001110 {a, b} == 10010000 {a, b} == 10010001 {a, b} == 10010010 {a, b} == 10010011 {a, b} == 10010100 {a, b} == 10010101 {a, b} == 10010110 {a, b} == 10010111 {a, b} == 10011000 {a, b} == 10011001 {a, b} == 10011010 {a, b} == 10011011 {a, b} == 10011100 {a, b} == 10011101 {a, b} == 10011110 {a, b} == 10100000 {a, b} == 10100001 {a, b} == 10100010 {a, b} == 10100011 {a, b} == 10100100 {a, b} == 10100101 {a, b} == 10100110 {a, b} == 10100111 {a, b} == 10101000 {a, b} == 10101001 {a, b} == 10101010 {a, b} == 10101011 {a, b} == 10101100 {a, b} == 10101101 {a, b} == 10101110 {a, b} == 10110000 {a, b} == 10110001 {a, b} == 10110010 {a, b} == 10110011 {a, b} == 10110100 {a, b} == 10110101 {a, b} == 10110110 {a, b} == 10110111 {a, b} == 10111000 {a, b} == 10111001 {a, b} == 10111010 {a, b} == 10111011 {a, b} == 10111100 {a, b} == 10111101 {a, b} == 10111110 {a, b} == 11000000 {a, b} == 11000001 {a, b} == 11000010 {a, b} == 11000011 {a, b} == 11000100 {a, b} == 11000101 {a, b} == 11000110 {a, b} == 11000111 {a, b} == 11001000 {a, b} == 11001001 {a, b} == 11001010 {a, b} == 11001011 {a, b} == 11001100 {a, b} == 11001101 {a, b} == 11001110 {a, b} == 11010000 {a, b} == 11010001 {a, b} == 11010010 {a, b} == 11010011 {a, b} == 11010100 {a, b} == 11010101 {a, b} == 11010110 {a, b} == 11010111 {a, b} == 11011000 {a, b} == 11011001 {a, b} == 11011010 {a, b} == 11011011 {a, b} == 11011100 {a, b} == 11011101 {a, b} == 11011110 {a, b} == 11100000 {a, b} == 11100001 {a, b} == 11100010 {a, b} == 11100011 {a, b} == 11100100 {a, b} == 11100101 {a, b} == 11100110 {a, b} == 11100111 {a, b} == 11101000 {a, b} == 11101001 {a, b} == 11101010 {a, b} == 11101011 {a, b} == 11101100 {a, b} == 11101101 {a, b} == 11101110 iverilog-12_0/ivtest/gold/stime.gold000066400000000000000000000003601435245347300176010ustar00rootroot00000000000000$simtime: 4026531840, $time: 4026531840, $stime: 4026531840 $simtime: 4294967296, $time: 4294967296, $stime: 0 $simtime: 8321499136, $time: 8321499136, $stime: 4026531840 iverilog-12_0/ivtest/gold/string10.gold000066400000000000000000000011731435245347300201320ustar00rootroot00000000000000============================ >|This is a test| *|This is a test| *|This is a test| >| 65| *| 65| >|16706| *|16706| >| 4276803| *| 4276803| >|1094861636| *|1094861636| >|01000001| *|01000001| >|01000001010000100100001101000100| *|01000001010000100100001101000100| >|01000001010000100100001101000100010010000100100101001010010010110100110001001101010011100100111101010000010100010101001001010011| *|01000001010000100100001101000100010010000100100101001010010010110100110001001101010011100100111101010000010100010101001001010011| >|41| *|41| >|41424344| *|41424344| >|4142434448494a4b4c4d4e4f50515253| *|4142434448494a4b4c4d4e4f50515253| iverilog-12_0/ivtest/gold/string11.gold000066400000000000000000000000171435245347300201270ustar00rootroot00000000000000bytes=4142430a iverilog-12_0/ivtest/gold/string4.gold000066400000000000000000000000121435245347300200440ustar00rootroot00000000000000 hi Mes1 iverilog-12_0/ivtest/gold/string5.gold000066400000000000000000000000411435245347300200470ustar00rootroot00000000000000 Hello world of Verilog iverilog-12_0/ivtest/gold/string7.gold000066400000000000000000000007011435245347300200540ustar00rootroot00000000000000============================ myReg8 = 65 >|A| *|A| ============================ myReg40 = "12345" >|12345| *|12345| >|5| *|5| ============================ myReg40r = "12345" >|12345| *|12345| >|1| *|1| ============================ myReg39r = "12345" >|12345| *|12345| >|b| *|b| ============================ myReg14 = 65 >| A| *| A| ============================ myReg14 = 33*356+65 >|!A| *|!A| ============================ myInt = 65 >| A| *| A| iverilog-12_0/ivtest/gold/string8.gold000066400000000000000000000002061435245347300200550ustar00rootroot00000000000000============================ myReg14 = 33*256+65 >|!A| *|!A| >|!| *|!| ============================ myReg16 = 33*512+65*2 >|!A| *|!A| iverilog-12_0/ivtest/gold/string9.gold000066400000000000000000000005761435245347300200700ustar00rootroot00000000000000============================ myReg8 = 65 >|A| *|A| ============================ myReg40 = "12345" >|5| *|5| >|5| *|5| ============================ myReg40r = "12345" >|5| *|5| >|1| *|1| ============================ myReg39r = "12345" >|5| *|5| >|b| *|b| ============================ myReg14 = 33*256+65 >|A| *|A| >|!| *|!| ============================ myInt = 66*256 + 65 >|A| *|A| iverilog-12_0/ivtest/gold/string_events.gold000066400000000000000000000002101435245347300213440ustar00rootroot00000000000000str = hello str = world str1 = hello1 str2 = hello2 str1 = world1 str2 = world2 str1 = world1 str2 = world2 str1 = hello1 str2 = hello2 iverilog-12_0/ivtest/gold/struct_invalid_member.gold000066400000000000000000000007761435245347300230540ustar00rootroot00000000000000./ivltests/struct_invalid_member.v:9: syntax error ./ivltests/struct_invalid_member.v:9: error: Error in struct/union member. ./ivltests/struct_invalid_member.v:10: syntax error ./ivltests/struct_invalid_member.v:10: error: Error in struct/union member. ./ivltests/struct_invalid_member.v:11: syntax error ./ivltests/struct_invalid_member.v:11: error: Error in struct/union member. ./ivltests/struct_invalid_member.v:12: syntax error ./ivltests/struct_invalid_member.v:12: error: Error in struct/union member. iverilog-12_0/ivtest/gold/struct_line_info.gold000066400000000000000000000004511435245347300220270ustar00rootroot00000000000000./ivltests/struct_line_info.v:7: error: Member r of packed struct/union must be packed. ./ivltests/struct_line_info.v:12: error: Member r of packed struct/union must be packed. ./ivltests/struct_line_info.v:17: error: Member r of packed struct/union must be packed. 3 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_default_port_value3.gold000066400000000000000000000003571435245347300231450ustar00rootroot00000000000000./ivltests/sv_default_port_value3.v:3: error: A reference to a wire or reg (`v') is not allowed in a constant expression. ./ivltests/sv_default_port_value3.v:3: error: Failed to elaborate port default value. 2 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_deferred_assert1.gold000066400000000000000000000023261435245347300224160ustar00rootroot00000000000000./ivltests/sv_deferred_assert1.v:8: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:9: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:10: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:11: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:12: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:13: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:14: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert1.v:16: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. iverilog-12_0/ivtest/gold/sv_deferred_assert2.gold000066400000000000000000000023261435245347300224170ustar00rootroot00000000000000./ivltests/sv_deferred_assert2.v:8: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:9: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:10: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:11: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:12: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:13: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:14: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assert2.v:16: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. iverilog-12_0/ivtest/gold/sv_deferred_assume1.gold000066400000000000000000000023261435245347300224120ustar00rootroot00000000000000./ivltests/sv_deferred_assume1.v:8: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:9: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:10: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:11: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:12: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:13: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:14: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume1.v:16: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. iverilog-12_0/ivtest/gold/sv_deferred_assume2.gold000066400000000000000000000023261435245347300224130ustar00rootroot00000000000000./ivltests/sv_deferred_assume2.v:8: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:9: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:10: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:11: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:12: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:13: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:14: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. ./ivltests/sv_deferred_assume2.v:16: sorry: Deferred assertions are not supported. Try -gno-assertions or -gsupported-assertions to turn this message off. iverilog-12_0/ivtest/gold/sv_end_label_fail.gold000066400000000000000000000030621435245347300220720ustar00rootroot00000000000000./ivltests/sv_end_label_fail.v:4: error: block end label `b_label_f` doesn't match block name `b_label`. ./ivltests/sv_end_label_fail.v:7: error: fork end label `fj_label_f` doesn't match fork name `fj_label`. ./ivltests/sv_end_label_fail.v:10: error: fork end label `fja_label_f` doesn't match fork name `fja_label`. ./ivltests/sv_end_label_fail.v:13: error: fork end label `fjn_label_f` doesn't match fork name `fjn_label`. ./ivltests/sv_end_label_fail.v:16: error: task end label `t_label_f` doesn't match task name `t_label`. ./ivltests/sv_end_label_fail.v:19: error: task end label `twa_label_f` doesn't match task name `twa_label`. ./ivltests/sv_end_label_fail.v:23: error: function end label `fn_label_f` doesn't match function name `fn_label`. ./ivltests/sv_end_label_fail.v:26: error: function end label `fa_label_f` doesn't match function name `fa_label`. ./ivltests/sv_end_label_fail.v:28: error: module end label `top_f` doesn't match module name `top`. ./ivltests/sv_end_label_fail.v:38: error: block end label `g_label_f` doesn't match block name `g_label`. ./ivltests/sv_end_label_fail.v:40: error: module end label `extra_f` doesn't match module name `extra`. ./ivltests/sv_end_label_fail.v:43: error: package end label `pkg_f` doesn't match package name `pkg`. ./ivltests/sv_end_label_fail.v:47: error: class end label `foo_f` doesn't match class name `foo`. ./ivltests/sv_end_label_fail.v:48: error: program end label `pgm_f` doesn't match program name `pgm`. ./ivltests/sv_end_label_fail.v:64: error: primitive end label `pinv_f` doesn't match primitive name `pinv`. iverilog-12_0/ivtest/gold/sv_end_labels_bad.gold000066400000000000000000000003341435245347300220670ustar00rootroot00000000000000./ivltests/sv_end_labels_bad.v:14: error: block end label `dummy_label_bad` doesn't match block name `dummy_label`. ./ivltests/sv_end_labels_bad.v:16: error: module end label `test_bad` doesn't match module name `test`. iverilog-12_0/ivtest/gold/sv_end_labels_unnamed.gold000066400000000000000000000003751435245347300227750ustar00rootroot00000000000000./ivltests/sv_end_labels_unnamed.v:7: error: Unnamed block must not have end label. ./ivltests/sv_end_labels_unnamed.v:11: error: Unnamed block must not have end label. ./ivltests/sv_end_labels_unnamed.v:14: error: Unnamed fork must not have end label. iverilog-12_0/ivtest/gold/sv_foreach8.gold000066400000000000000000000002771435245347300206760ustar00rootroot00000000000000 0 0 0 1 0 2 0 3 1 0 1 1 1 2 1 3 PASSED iverilog-12_0/ivtest/gold/sv_immediate_assert-vlog95.gold000066400000000000000000000003561435245347300236370ustar00rootroot00000000000000ERROR: vlog95.v:24: Time: 0 Scope: test Check 4 : this should be displayed Check 5 : this should be displayed ERROR: vlog95.v:32: Time: 0 Scope: test Check 7 : this should be displayed Check 8 : this should be displayed iverilog-12_0/ivtest/gold/sv_immediate_assert.gold000066400000000000000000000004351435245347300225120ustar00rootroot00000000000000ERROR: ./ivltests/sv_immediate_assert.v:7: Time: 0 Scope: test Check 4 : this should be displayed Check 5 : this should be displayed ERROR: ./ivltests/sv_immediate_assert.v:11: Time: 0 Scope: test Check 7 : this should be displayed Check 8 : this should be displayed iverilog-12_0/ivtest/gold/sv_immediate_assume-vlog95.gold000066400000000000000000000003561435245347300236330ustar00rootroot00000000000000ERROR: vlog95.v:24: Time: 0 Scope: test Check 4 : this should be displayed Check 5 : this should be displayed ERROR: vlog95.v:32: Time: 0 Scope: test Check 7 : this should be displayed Check 8 : this should be displayed iverilog-12_0/ivtest/gold/sv_immediate_assume.gold000066400000000000000000000004351435245347300225060ustar00rootroot00000000000000ERROR: ./ivltests/sv_immediate_assume.v:7: Time: 0 Scope: test Check 4 : this should be displayed Check 5 : this should be displayed ERROR: ./ivltests/sv_immediate_assume.v:11: Time: 0 Scope: test Check 7 : this should be displayed Check 8 : this should be displayed iverilog-12_0/ivtest/gold/sv_macro2.gold000066400000000000000000000000301435245347300203450ustar00rootroot00000000000000left side: "right side" iverilog-12_0/ivtest/gold/sv_macro3.gold000066400000000000000000000000521435245347300203520ustar00rootroot00000000000000` my_prefix_my_suffix my_prefix_my_suffix iverilog-12_0/ivtest/gold/sv_new_array_error.gold000066400000000000000000000002151435245347300223670ustar00rootroot00000000000000./ivltests/sv_new_array_error.v:3: error: The new array constructor may only be used in an assignment to a dynamic array. Elaboration failed iverilog-12_0/ivtest/gold/sv_pkg_class.gold000066400000000000000000000000421435245347300211330ustar00rootroot00000000000000This is class 2. This is class 1. iverilog-12_0/ivtest/gold/sv_queue_parray.gold000066400000000000000000000036341435245347300217010ustar00rootroot00000000000000./ivltests/sv_queue_parray.v:35: Warning: skipping delete(0) on empty queue. ./ivltests/sv_queue_parray.v:39: Warning: pop_front() on empty queue. ./ivltests/sv_queue_parray.v:45: Warning: pop_back() on empty queue. ./ivltests/sv_queue_parray.v:56: Warning: skipping out of range delete(3) on queue of size 3. ./ivltests/sv_queue_parray.v:57: Warning: skipping queue delete() with negative index. ./ivltests/sv_queue_parray.v:58: Warning: skipping queue delete() with undefined index. ./ivltests/sv_queue_parray.v:132: Warning: cannot assign to a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:133: Warning: cannot assign to an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:134: Warning: assigning to queue[4] is outside of size (3). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:137: Warning: cannot assign to a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:139: Warning: cannot assign to an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:141: Warning: assigning to queue[4] is outside of size (3). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:153: Warning: cannot insert at a negative queue index (-1). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:154: Warning: cannot insert at an undefined queue index. 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray.v:155: Warning: inserting to queue[5] is outside of size (4). 40'b0000000000000000000000000000000000001010 was not added. PASSED iverilog-12_0/ivtest/gold/sv_queue_parray_bounded.gold000066400000000000000000000023001435245347300233660ustar00rootroot00000000000000./ivltests/sv_queue_parray_bounded.v:61: Warning: Array pattern assignment has more elements (4) than bounded queue 'q_tst' supports (3). Only using first 3 elements. ./ivltests/sv_queue_parray_bounded.v:38: Warning: push_back(40'b0000000000000000000000000000000001100100) skipped for already full bounded queue [3]. ./ivltests/sv_queue_parray_bounded.v:45: Warning: push_front(40'b0000000000000000000000000000000000000101) removed 40'b0000000000000000000000000000000000000011 from already full bounded queue [3]. ./ivltests/sv_queue_parray_bounded.v:46: Warning: assigning to queue[3] is outside bound (3). 40'b0000000000000000000000000000000000000011 was not added. ./ivltests/sv_queue_parray_bounded.v:53: Warning: inserting to queue[3] is outside bound (3). 40'b0000000000000000000000000000000000001010 was not added. ./ivltests/sv_queue_parray_bounded.v:54: Warning: insert(1, 40'b0000000000000000000000000000000000000010) removed 40'b0000000000000000000000000000000000000010 from already full bounded queue [3]. ./ivltests/sv_queue_parray_bounded.v:69: Warning: queue is bounded to have at most 3 elements, source has 4 elements. PASSED iverilog-12_0/ivtest/gold/sv_queue_parray_fail.gold000066400000000000000000000014511435245347300226670ustar00rootroot00000000000000./ivltests/sv_queue_parray_fail.v:7: error: queue bound must be positive (-1). ./ivltests/sv_queue_parray_fail.v:8: error: queue bound must be defined. ./ivltests/sv_queue_parray_fail.v:9: error: A reference to a wire or reg (`bound') is not allowed in a constant expression. ./ivltests/sv_queue_parray_fail.v:9: error: queue bound must be constant. ./ivltests/sv_queue_parray_fail.v:12: error: size() method takes no arguments ./ivltests/sv_queue_parray_fail.v:13: error: pop_front() method takes no arguments ./ivltests/sv_queue_parray_fail.v:14: error: pop_back() method takes no arguments ./ivltests/sv_queue_parray_fail.v:15: error: push_front() method requires a single argument. ./ivltests/sv_queue_parray_fail.v:16: error: push_back() method requires a single argument. 9 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_queue_real.gold000066400000000000000000000027121435245347300213220ustar00rootroot00000000000000./ivltests/sv_queue_real.v:32: Warning: skipping delete(0) on empty queue. ./ivltests/sv_queue_real.v:36: Warning: pop_front() on empty queue. ./ivltests/sv_queue_real.v:42: Warning: pop_back() on empty queue. ./ivltests/sv_queue_real.v:53: Warning: skipping out of range delete(3) on queue of size 3. ./ivltests/sv_queue_real.v:54: Warning: skipping queue delete() with negative index. ./ivltests/sv_queue_real.v:55: Warning: skipping queue delete() with undefined index. ./ivltests/sv_queue_real.v:129: Warning: cannot assign to a negative queue index (-1). 10 was not added. ./ivltests/sv_queue_real.v:130: Warning: cannot assign to an undefined queue index. 10 was not added. ./ivltests/sv_queue_real.v:131: Warning: assigning to queue[4] is outside of size (3). 10 was not added. ./ivltests/sv_queue_real.v:134: Warning: cannot assign to a negative queue index (-1). 10 was not added. ./ivltests/sv_queue_real.v:136: Warning: cannot assign to an undefined queue index. 10 was not added. ./ivltests/sv_queue_real.v:138: Warning: assigning to queue[4] is outside of size (3). 10 was not added. ./ivltests/sv_queue_real.v:150: Warning: cannot insert at a negative queue index (-1). 10 was not added. ./ivltests/sv_queue_real.v:151: Warning: cannot insert at an undefined queue index. 10 was not added. ./ivltests/sv_queue_real.v:152: Warning: inserting to queue[5] is outside of size (4). 10 was not added. PASSED iverilog-12_0/ivtest/gold/sv_queue_real_bounded.gold000066400000000000000000000015561435245347300230270ustar00rootroot00000000000000./ivltests/sv_queue_real_bounded.v:58: Warning: Array pattern assignment has more elements (4) than bounded queue 'q_tst' supports (3). Only using first 3 elements. ./ivltests/sv_queue_real_bounded.v:35: Warning: push_back(100) skipped for already full bounded queue [3]. ./ivltests/sv_queue_real_bounded.v:42: Warning: push_front(0.5) removed 3 from already full bounded queue [3]. ./ivltests/sv_queue_real_bounded.v:43: Warning: assigning to queue[3] is outside bound (3). 3 was not added. ./ivltests/sv_queue_real_bounded.v:50: Warning: inserting to queue[3] is outside bound (3). 10 was not added. ./ivltests/sv_queue_real_bounded.v:51: Warning: insert(1, 2) removed 2 from already full bounded queue [3]. ./ivltests/sv_queue_real_bounded.v:66: Warning: queue is bounded to have at most 3 elements, source has 4 elements. PASSED iverilog-12_0/ivtest/gold/sv_queue_real_fail.gold000066400000000000000000000014261435245347300223160ustar00rootroot00000000000000./ivltests/sv_queue_real_fail.v:4: error: queue bound must be positive (-1). ./ivltests/sv_queue_real_fail.v:5: error: queue bound must be defined. ./ivltests/sv_queue_real_fail.v:6: error: A reference to a wire or reg (`bound') is not allowed in a constant expression. ./ivltests/sv_queue_real_fail.v:6: error: queue bound must be constant. ./ivltests/sv_queue_real_fail.v:9: error: size() method takes no arguments ./ivltests/sv_queue_real_fail.v:10: error: pop_front() method takes no arguments ./ivltests/sv_queue_real_fail.v:11: error: pop_back() method takes no arguments ./ivltests/sv_queue_real_fail.v:12: error: push_front() method requires a single argument. ./ivltests/sv_queue_real_fail.v:13: error: push_back() method requires a single argument. 9 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_queue_string.gold000066400000000000000000000032051435245347300217030ustar00rootroot00000000000000./ivltests/sv_queue_string.v:32: Warning: skipping delete(0) on empty queue. ./ivltests/sv_queue_string.v:36: Warning: pop_front() on empty queue. ./ivltests/sv_queue_string.v:42: Warning: pop_back() on empty queue. ./ivltests/sv_queue_string.v:53: Warning: skipping out of range delete(3) on queue of size 3. ./ivltests/sv_queue_string.v:54: Warning: skipping queue delete() with negative index. ./ivltests/sv_queue_string.v:55: Warning: skipping queue delete() with undefined index. ./ivltests/sv_queue_string.v:129: Warning: cannot assign to a negative queue index (-1). "Will not write" was not added. ./ivltests/sv_queue_string.v:130: Warning: cannot assign to an undefined queue index. "Will not write" was not added. ./ivltests/sv_queue_string.v:131: Warning: assigning to queue[4] is outside of size (3). "Will not write" was not added. ./ivltests/sv_queue_string.v:134: Warning: cannot assign to a negative queue index (-1). "Will not write" was not added. ./ivltests/sv_queue_string.v:136: Warning: cannot assign to an undefined queue index. "Will not write" was not added. ./ivltests/sv_queue_string.v:138: Warning: assigning to queue[4] is outside of size (3). "Will not write" was not added. ./ivltests/sv_queue_string.v:150: Warning: cannot insert at a negative queue index (-1). "Will not be added" was not added. ./ivltests/sv_queue_string.v:151: Warning: cannot insert at an undefined queue index. "Will not be added" was not added. ./ivltests/sv_queue_string.v:152: Warning: inserting to queue[5] is outside of size (4). "Will not be added" was not added. PASSED iverilog-12_0/ivtest/gold/sv_queue_string_bounded.gold000066400000000000000000000017241435245347300234070ustar00rootroot00000000000000./ivltests/sv_queue_string_bounded.v:58: Warning: Array pattern assignment has more elements (4) than bounded queue 'q_tst' supports (3). Only using first 3 elements. ./ivltests/sv_queue_string_bounded.v:35: Warning: push_back("This will not be added") skipped for already full bounded queue [3]. ./ivltests/sv_queue_string_bounded.v:42: Warning: push_front("I say,") removed "!" from already full bounded queue [3]. ./ivltests/sv_queue_string_bounded.v:43: Warning: assigning to queue[3] is outside bound (3). "Will not be added" was not added. ./ivltests/sv_queue_string_bounded.v:50: Warning: inserting to queue[3] is outside bound (3). "Will not be added" was not added. ./ivltests/sv_queue_string_bounded.v:51: Warning: insert(1, "to you") removed "World" from already full bounded queue [3]. ./ivltests/sv_queue_string_bounded.v:67: Warning: queue is bounded to have at most 3 elements, source has 4 elements. PASSED iverilog-12_0/ivtest/gold/sv_queue_string_fail.gold000066400000000000000000000014501435245347300226760ustar00rootroot00000000000000./ivltests/sv_queue_string_fail.v:4: error: queue bound must be positive (-1). ./ivltests/sv_queue_string_fail.v:5: error: queue bound must be defined. ./ivltests/sv_queue_string_fail.v:6: error: A reference to a wire or reg (`bound') is not allowed in a constant expression. ./ivltests/sv_queue_string_fail.v:6: error: queue bound must be constant. ./ivltests/sv_queue_string_fail.v:9: error: size() method takes no arguments ./ivltests/sv_queue_string_fail.v:10: error: pop_front() method takes no arguments ./ivltests/sv_queue_string_fail.v:11: error: pop_back() method takes no arguments ./ivltests/sv_queue_string_fail.v:12: error: push_front() method requires a single argument. ./ivltests/sv_queue_string_fail.v:13: error: push_back() method requires a single argument. 9 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_queue_vec.gold000066400000000000000000000034471435245347300211620ustar00rootroot00000000000000./ivltests/sv_queue_vec.v:32: Warning: skipping delete(0) on empty queue. ./ivltests/sv_queue_vec.v:36: Warning: pop_front() on empty queue. ./ivltests/sv_queue_vec.v:42: Warning: pop_back() on empty queue. ./ivltests/sv_queue_vec.v:53: Warning: skipping out of range delete(3) on queue of size 3. ./ivltests/sv_queue_vec.v:54: Warning: skipping queue delete() with negative index. ./ivltests/sv_queue_vec.v:55: Warning: skipping queue delete() with undefined index. ./ivltests/sv_queue_vec.v:129: Warning: cannot assign to a negative queue index (-1). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:130: Warning: cannot assign to an undefined queue index. 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:131: Warning: assigning to queue[4] is outside of size (3). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:134: Warning: cannot assign to a negative queue index (-1). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:136: Warning: cannot assign to an undefined queue index. 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:138: Warning: assigning to queue[4] is outside of size (3). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:150: Warning: cannot insert at a negative queue index (-1). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:151: Warning: cannot insert at an undefined queue index. 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec.v:152: Warning: inserting to queue[5] is outside of size (4). 32'b00000000000000000000000000001010 was not added. PASSED iverilog-12_0/ivtest/gold/sv_queue_vec_bounded.gold000066400000000000000000000021631435245347300226540ustar00rootroot00000000000000./ivltests/sv_queue_vec_bounded.v:58: Warning: Array pattern assignment has more elements (4) than bounded queue 'q_tst' supports (3). Only using first 3 elements. ./ivltests/sv_queue_vec_bounded.v:35: Warning: push_back(32'b00000000000000000000000001100100) skipped for already full bounded queue [3]. ./ivltests/sv_queue_vec_bounded.v:42: Warning: push_front(32'b00000000000000000000000000000101) removed 32'b00000000000000000000000000000011 from already full bounded queue [3]. ./ivltests/sv_queue_vec_bounded.v:43: Warning: assigning to queue[3] is outside bound (3). 32'b00000000000000000000000000000011 was not added. ./ivltests/sv_queue_vec_bounded.v:50: Warning: inserting to queue[3] is outside bound (3). 32'b00000000000000000000000000001010 was not added. ./ivltests/sv_queue_vec_bounded.v:51: Warning: insert(1, 32'b00000000000000000000000000000010) removed 32'b00000000000000000000000000000010 from already full bounded queue [3]. ./ivltests/sv_queue_vec_bounded.v:66: Warning: queue is bounded to have at most 3 elements, source has 4 elements. PASSED iverilog-12_0/ivtest/gold/sv_queue_vec_fail.gold000066400000000000000000000014151435245347300221460ustar00rootroot00000000000000./ivltests/sv_queue_vec_fail.v:4: error: queue bound must be positive (-1). ./ivltests/sv_queue_vec_fail.v:5: error: queue bound must be defined. ./ivltests/sv_queue_vec_fail.v:6: error: A reference to a wire or reg (`bound') is not allowed in a constant expression. ./ivltests/sv_queue_vec_fail.v:6: error: queue bound must be constant. ./ivltests/sv_queue_vec_fail.v:9: error: size() method takes no arguments ./ivltests/sv_queue_vec_fail.v:10: error: pop_front() method takes no arguments ./ivltests/sv_queue_vec_fail.v:11: error: pop_back() method takes no arguments ./ivltests/sv_queue_vec_fail.v:12: error: push_front() method requires a single argument. ./ivltests/sv_queue_vec_fail.v:13: error: push_back() method requires a single argument. 9 error(s) during elaboration. iverilog-12_0/ivtest/gold/sv_root_class.gold000066400000000000000000000000421435245347300213350ustar00rootroot00000000000000This is class 2. This is class 1. iverilog-12_0/ivtest/gold/sv_root_func.gold000066400000000000000000000000401435245347300211610ustar00rootroot00000000000000this is func 2. this is func 1. iverilog-12_0/ivtest/gold/sv_root_task.gold000066400000000000000000000000401435245347300211700ustar00rootroot00000000000000This is task 2. This is task 1. iverilog-12_0/ivtest/gold/sv_timeunit_prec3a.gold000066400000000000000000000020711435245347300222640ustar00rootroot00000000000000Time scale of (check_100s) is 100s / 100s Time scale of (check_10s) is 10s / 10s Time scale of (check_1s) is 1s / 1s Time scale of (check_100ms) is 100ms / 100ms Time scale of (check_10ms) is 10ms / 10ms Time scale of (check_1ms) is 1ms / 1ms Time scale of (check_100us) is 100us / 100us Time scale of (check_10us) is 10us / 10us Time scale of (check_1us) is 1us / 1us Time scale of (check_100ns) is 100ns / 100ns Time scale of (check_10ns) is 10ns / 10ns Time scale of (check_1ns) is 1ns / 1ns Time scale of (check_100ps) is 100ps / 100ps Time scale of (check_10ps) is 10ps / 10ps Time scale of (check_1ps) is 1ps / 1ps Time scale of (check_100fs) is 100fs / 100fs Time scale of (check_10fs) is 10fs / 10fs Time scale of (check_1fs) is 1fs / 1fs Time scale of (check_tu) is 10us / 1us Time scale of (check_tp) is 100us / 10us Time scale of (check_tup) is 10us / 10us Time scale of (check_tpu) is 10us / 10us Time scale of (check_tu_d) is 10us / 1us Time scale of (check_tp_d) is 100us / 10us Time scale of (check_tup_d) is 10us / 10us Time scale of (check_tpu_d) is 10us / 10us iverilog-12_0/ivtest/gold/sv_timeunit_prec3b.gold000066400000000000000000000006111435245347300222630ustar00rootroot00000000000000Time scale of (check_tu_nest) is 10us / 1us Time scale of (check_tp_nest) is 100us / 10us Time scale of (check_tup_nest) is 10us / 10us Time scale of (check_tpu_nest) is 10us / 10us Time scale of (check_tu_nest.nested) is 100us / 1us Time scale of (check_tp_nest.nested) is 100us / 1us Time scale of (check_tup_nest.nested) is 100us / 1us Time scale of (check_tpu_nest.nested) is 100us / 1us iverilog-12_0/ivtest/gold/sv_timeunit_prec3c.gold000066400000000000000000000001161435245347300222640ustar00rootroot00000000000000Time scale of (gtp_ltu1) is 1ns / 10ps Time scale of (gtp_ltu2) is 1us / 10ps iverilog-12_0/ivtest/gold/sv_timeunit_prec3d.gold000066400000000000000000000001151435245347300222640ustar00rootroot00000000000000Time scale of (gtu_ltp1) is 10s / 10ps Time scale of (gtu_ltp2) is 10s / 1ns iverilog-12_0/ivtest/gold/sv_timeunit_prec4a.gold000066400000000000000000000015001435245347300222610ustar00rootroot00000000000000Time scale of (check_100s) is 100s / 100s Time scale of (check_10s) is 10s / 10s Time scale of (check_1s) is 1s / 1s Time scale of (check_100ms) is 100ms / 100ms Time scale of (check_10ms) is 10ms / 10ms Time scale of (check_1ms) is 1ms / 1ms Time scale of (check_100us) is 100us / 100us Time scale of (check_10us) is 10us / 10us Time scale of (check_1us) is 1us / 1us Time scale of (check_100ns) is 100ns / 100ns Time scale of (check_10ns) is 10ns / 10ns Time scale of (check_1ns) is 1ns / 1ns Time scale of (check_100ps) is 100ps / 100ps Time scale of (check_10ps) is 10ps / 10ps Time scale of (check_1ps) is 1ps / 1ps Time scale of (check_100fs) is 100fs / 100fs Time scale of (check_10fs) is 10fs / 10fs Time scale of (check_1fs) is 1fs / 1fs Time scale of (check_tup) is 10us / 10us Time scale of (check_tup_d) is 10us / 10us iverilog-12_0/ivtest/gold/sv_timeunit_prec4b.gold000066400000000000000000000001431435245347300222640ustar00rootroot00000000000000Time scale of (check_tup_nest) is 10us / 10us Time scale of (check_tup_nest.nested) is 100us / 1us iverilog-12_0/ivtest/gold/sv_timeunit_prec_fail1-v10.gold000066400000000000000000000033441435245347300235240ustar00rootroot00000000000000./ivltests/sv_timeunit_prec_fail1a.v:15: error: repeat timeunit does not match the initial module timeunit declaration. ./ivltests/sv_timeunit_prec_fail1a.v:21: error: repeat timeprecision does not match the initial module timeprecision declaration. ./ivltests/sv_timeunit_prec_fail1a.v:27: error: repeat timeunit found and the initial module timeunit is missing. ./ivltests/sv_timeunit_prec_fail1a.v:33: error: repeat timeprecision found and the initial module timeprecision is missing. ./ivltests/sv_timeunit_prec_fail1a.v:40: error: repeat timeprecision found and the initial module timeprecision is missing. ./ivltests/sv_timeunit_prec_fail1a.v:47: error: repeat timeunit found and the initial module timeunit is missing. ./ivltests/sv_timeunit_prec_fail1a.v:53: Invalid timeunit constant (1st digit). ./ivltests/sv_timeunit_prec_fail1a.v:54: Invalid timeprecision constant (1st digit). ./ivltests/sv_timeunit_prec_fail1a.v:56: Invalid timeunit constant (number of zeros). ./ivltests/sv_timeunit_prec_fail1a.v:57: Invalid timeprecision constant (number of zeros). ./ivltests/sv_timeunit_prec_fail1a.v:59: Invalid timeunit scale '2s'. ./ivltests/sv_timeunit_prec_fail1a.v:60: Invalid timeprecision scale '2s'. ./ivltests/sv_timeunit_prec_fail1a.v:63: Invalid timeunit constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail1a.v:64: Invalid timeprecision constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail1b.v:5: error: a timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1c.v:6: error: a timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1d.v:5: error: a timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1e.v:5: error: a timeprecision is missing or is too large! iverilog-12_0/ivtest/gold/sv_timeunit_prec_fail1.gold000066400000000000000000000040451435245347300231170ustar00rootroot00000000000000./ivltests/sv_timeunit_prec_fail1a.v:9: error: Repeat timeunit does not match the initial timeunit for this scope. ./ivltests/sv_timeunit_prec_fail1a.v:10: error: Repeat timeprecision does not match the initial timeprecision for this scope. ./ivltests/sv_timeunit_prec_fail1a.v:15: error: Repeat timeunit does not match the initial timeunit for this scope. ./ivltests/sv_timeunit_prec_fail1a.v:21: error: Repeat timeprecision does not match the initial timeprecision for this scope. ./ivltests/sv_timeunit_prec_fail1a.v:27: error: Repeat timeunit found and the initial timeunit for this scope is missing. ./ivltests/sv_timeunit_prec_fail1a.v:33: error: Repeat timeprecision found and the initial timeprecision for this scope is missing. ./ivltests/sv_timeunit_prec_fail1a.v:40: error: Repeat timeprecision found and the initial timeprecision for this scope is missing. ./ivltests/sv_timeunit_prec_fail1a.v:47: error: Repeat timeunit found and the initial timeunit for this scope is missing. ./ivltests/sv_timeunit_prec_fail1a.v:53: error: Invalid timeunit constant (1st digit). ./ivltests/sv_timeunit_prec_fail1a.v:54: error: Invalid timeprecision constant (1st digit). ./ivltests/sv_timeunit_prec_fail1a.v:56: error: Invalid timeunit constant (number of zeros). ./ivltests/sv_timeunit_prec_fail1a.v:57: error: Invalid timeprecision constant (number of zeros). ./ivltests/sv_timeunit_prec_fail1a.v:59: error: Invalid timeunit scale '2s'. ./ivltests/sv_timeunit_prec_fail1a.v:60: error: Invalid timeprecision scale '2s'. ./ivltests/sv_timeunit_prec_fail1a.v:63: error: Invalid timeunit constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail1a.v:64: error: Invalid timeprecision constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail1b.v:4: error: A timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1c.v:4: error: A timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1d.v:5: error: A timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail1e.v:5: error: A timeprecision is missing or is too large! iverilog-12_0/ivtest/gold/sv_timeunit_prec_fail2-v10.gold000066400000000000000000000034501435245347300235230ustar00rootroot00000000000000./ivltests/sv_timeunit_prec_fail2a.v:13: error: repeat timeunit does not match the initial module timeunit declaration. ./ivltests/sv_timeunit_prec_fail2a.v:13: error: repeat timeprecision does not match the initial module timeprecision declaration. ./ivltests/sv_timeunit_prec_fail2a.v:14: error: repeat timeunit does not match the initial module timeunit declaration. ./ivltests/sv_timeunit_prec_fail2a.v:15: error: repeat timeprecision does not match the initial module timeprecision declaration. ./ivltests/sv_timeunit_prec_fail2a.v:21: error: repeat timeunit found and the initial module timeunit is missing. ./ivltests/sv_timeunit_prec_fail2a.v:21: error: repeat timeprecision found and the initial module timeprecision is missing. ./ivltests/sv_timeunit_prec_fail2a.v:27: error: repeat timeprecision found and the initial module timeprecision is missing. ./ivltests/sv_timeunit_prec_fail2a.v:33: error: repeat timeunit found and the initial module timeunit is missing. ./ivltests/sv_timeunit_prec_fail2a.v:39: Invalid timeunit constant (1st digit). ./ivltests/sv_timeunit_prec_fail2a.v:39: Invalid timeprecision constant (1st digit). ./ivltests/sv_timeunit_prec_fail2a.v:41: Invalid timeunit constant (number of zeros). ./ivltests/sv_timeunit_prec_fail2a.v:41: Invalid timeprecision constant (number of zeros). ./ivltests/sv_timeunit_prec_fail2a.v:43: Invalid timeunit scale '2s'. ./ivltests/sv_timeunit_prec_fail2a.v:43: Invalid timeprecision scale '2s'. ./ivltests/sv_timeunit_prec_fail2a.v:46: Invalid timeunit constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail2a.v:46: Invalid timeprecision constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail2b.v:5: error: a timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail2c.v:4: error: a timeprecision is missing or is too large! iverilog-12_0/ivtest/gold/sv_timeunit_prec_fail2.gold000066400000000000000000000041401435245347300231140ustar00rootroot00000000000000./ivltests/sv_timeunit_prec_fail2a.v:8: error: Repeat timeunit does not match the initial timeunit for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:8: error: Repeat timeprecision does not match the initial timeprecision for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:13: error: Repeat timeunit does not match the initial timeunit for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:13: error: Repeat timeprecision does not match the initial timeprecision for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:14: error: Repeat timeunit does not match the initial timeunit for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:15: error: Repeat timeprecision does not match the initial timeprecision for this scope. ./ivltests/sv_timeunit_prec_fail2a.v:21: error: Repeat timeunit found and the initial timeunit for this scope is missing. ./ivltests/sv_timeunit_prec_fail2a.v:21: error: Repeat timeprecision found and the initial timeprecision for this scope is missing. ./ivltests/sv_timeunit_prec_fail2a.v:27: error: Repeat timeprecision found and the initial timeprecision for this scope is missing. ./ivltests/sv_timeunit_prec_fail2a.v:33: error: Repeat timeunit found and the initial timeunit for this scope is missing. ./ivltests/sv_timeunit_prec_fail2a.v:39: error: Invalid timeunit constant (1st digit). ./ivltests/sv_timeunit_prec_fail2a.v:39: error: Invalid timeprecision constant (1st digit). ./ivltests/sv_timeunit_prec_fail2a.v:41: error: Invalid timeunit constant (number of zeros). ./ivltests/sv_timeunit_prec_fail2a.v:41: error: Invalid timeprecision constant (number of zeros). ./ivltests/sv_timeunit_prec_fail2a.v:43: error: Invalid timeunit scale '2s'. ./ivltests/sv_timeunit_prec_fail2a.v:43: error: Invalid timeprecision scale '2s'. ./ivltests/sv_timeunit_prec_fail2a.v:46: error: Invalid timeunit constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail2a.v:46: error: Invalid timeprecision constant ('_' is not supported). ./ivltests/sv_timeunit_prec_fail2b.v:4: error: A timeprecision is missing or is too large! ./ivltests/sv_timeunit_prec_fail2c.v:5: error: A timeprecision is missing or is too large! iverilog-12_0/ivtest/gold/sv_unit1b.gold000066400000000000000000000002111435245347300203650ustar00rootroot00000000000000test1 macro1 = 1 test1 macro2 = 12 test1 macro3 = 13 test1 wire = 1 test2 macro1 = 21 test2 macro2 = 12 test2 macro3 = 13 test2 wire = 1 iverilog-12_0/ivtest/gold/sv_unit1c.gold000066400000000000000000000002071435245347300203730ustar00rootroot00000000000000test1 macro1 = 1 test1 macro2 = 12 test1 macro3 = 13 test1 wire = 1 test2 macro1 = 1 test2 macro2 = 2 test2 macro3 = 23 test2 wire = z iverilog-12_0/ivtest/gold/sv_unit2b.gold000066400000000000000000000003361435245347300203760ustar00rootroot00000000000000hello from unit 1 hello1 from unit 1 hello2 from c1 hello1 from unit 1 hello2 from m1 hello3 from unit 1 hello4 from m2 hello1 from unit 1 hello2 from c1 hello1 from unit 2 hello2 from m3 hello3 from unit 2 hello4 from m4 iverilog-12_0/ivtest/gold/sv_unit3b.gold000066400000000000000000000004021435245347300203710ustar00rootroot00000000000000 101 from unit1 100 from c1 101 from unit1 112 from m1 103 from unit1 124 from m2 101 from unit1 100 from c1 201 from unit2 232 from m3 203 from unit2 244 from m4 iverilog-12_0/ivtest/gold/sv_wildcard_import4.gold000066400000000000000000000011161435245347300224370ustar00rootroot00000000000000./ivltests/sv_wildcard_import4.v:24: error: 'p1' has already been imported into this scope from package 'my_package'. ./ivltests/sv_wildcard_import4.v:25: error: 'p2' has already been imported into this scope from package 'my_package'. ./ivltests/sv_wildcard_import4.v:27: error: 'word' has already been imported into this scope from package 'my_package'. ./ivltests/sv_wildcard_import4.v:29: error: 'v' has already been imported into this scope from package 'my_package'. ./ivltests/sv_wildcard_import4.v:31: error: 'e' has already been imported into this scope from package 'my_package'. iverilog-12_0/ivtest/gold/sv_wildcard_import5.gold000066400000000000000000000015601435245347300224430ustar00rootroot00000000000000./ivltests/sv_wildcard_import5.v:50: error: Ambiguous use of 'word'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:53: error: Ambiguous use of 'e'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:53: error: Ambiguous use of 'v'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:53: error: Ambiguous use of 'p1'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:53: error: Ambiguous use of 'p2'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:54: error: Ambiguous use of 'f'. It is exported by both 'my_package1' and by 'my_package2'. ./ivltests/sv_wildcard_import5.v:54: error: Ambiguous use of 'h'. It is exported by both 'my_package1' and by 'my_package2'. iverilog-12_0/ivtest/gold/switch_primitives.gold000066400000000000000000000015321435245347300222360ustar00rootroot00000000000000x x x x x x x x StX StX StX StX StX StX ------------------ 0 0 0 z 0 z 0 z St0 HiZ St0 HiZ St0 HiZ 0 1 1 z 1 z 1 z St1 HiZ St1 HiZ St1 HiZ 0 x x z x z x z StX HiZ StX HiZ StX HiZ 0 z x z z z z z StX HiZ HiZ HiZ HiZ HiZ ------------------ 1 0 z 0 z 0 z 0 HiZ St0 HiZ St0 HiZ St0 1 1 z 1 z 1 z 1 HiZ St1 HiZ St1 HiZ St1 1 x z x z x z x HiZ StX HiZ StX HiZ StX 1 z z x z z z z HiZ StX HiZ HiZ HiZ HiZ ------------------ x 0 x x x x x x StL StL StL StL StL StL x 1 x x x x x x StH StH StH StH StH StH x x x x x x x x StX StX StX StX StX StX x z x x z z z z StX StX HiZ HiZ HiZ HiZ ------------------ z 0 x x x x x x StL StL StL StL StL StL z 1 x x x x x x StH StH StH StH StH StH z x x x x x x x StX StX StX StX StX StX z z x x z z z z StX StX HiZ HiZ HiZ HiZ iverilog-12_0/ivtest/gold/swrite-vlog95.gold000066400000000000000000000012361435245347300211230ustar00rootroot00000000000000WARNING: vlog95.v:171: %l currently unsupported $swrite<%l>. WARNING: vlog95.v:173: %L currently unsupported $swrite<%L>. WARNING: vlog95.v:223: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: vlog95.v:225: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: vlog95.v:241: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: vlog95.v:243: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: vlog95.v:245: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: vlog95.v:255: missing argument for $sformat<%s>. WARNING: vlog95.v:257: $sformat has 1 extra argument(s). All tests passed. iverilog-12_0/ivtest/gold/swrite.gold000066400000000000000000000014011435245347300177720ustar00rootroot00000000000000WARNING: ./ivltests/swrite.v:210: %l currently unsupported $swrite<%l>. WARNING: ./ivltests/swrite.v:212: %L currently unsupported $swrite<%L>. WARNING: ./ivltests/swrite.v:275: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: ./ivltests/swrite.v:277: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: ./ivltests/swrite.v:299: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: ./ivltests/swrite.v:301: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: ./ivltests/swrite.v:304: $swrite returned a value with an embedded NULL (see %u/%z). WARNING: ./ivltests/swrite.v:318: missing argument for $sformat<%s>. WARNING: ./ivltests/swrite.v:320: $sformat has 1 extra argument(s). All tests passed. iverilog-12_0/ivtest/gold/sys_func_as_task.gold000066400000000000000000000002641435245347300220210ustar00rootroot00000000000000./ivltests/sys_func_as_task.v:7: Warning: Calling system function $sscanf() as a task. ./ivltests/sys_func_as_task.v:7: The functions return value will be ignored. PASSED iverilog-12_0/ivtest/gold/sys_func_task_error-fsv.gold000066400000000000000000000007121435245347300233410ustar00rootroot00000000000000./ivltests/sys_func_task_error.v:7: Error: System task/function $this_icarus_call_should_not_exist() is not defined by any module. ./ivltests/sys_func_task_error.v:10: Warning: Calling system function $sscanf() as a task. ./ivltests/sys_func_task_error.v:10: The functions return value will be ignored. ./ivltests/sys_func_task_error.v:12: Error: $display() is a system task, it cannot be called as a function. vsim: Program not runnable, 2 errors. iverilog-12_0/ivtest/gold/sys_func_task_error-vlog95.gold000066400000000000000000000004711435245347300236720ustar00rootroot00000000000000vlog95.v:14: Error: System task/function $this_icarus_call_should_not_exist() is not defined by any module. vlog95.v:16: Error: $sscanf() is a system function, it cannot be called as a task. vlog95.v:17: Error: $display() is a system task, it cannot be called as a function. vsim: Program not runnable, 3 errors. iverilog-12_0/ivtest/gold/sys_func_task_error.gold000066400000000000000000000006001435245347300225410ustar00rootroot00000000000000./ivltests/sys_func_task_error.v:7: Error: System task/function $this_icarus_call_should_not_exist() is not defined by any module. ./ivltests/sys_func_task_error.v:10: Error: $sscanf() is a system function, it cannot be called as a task. ./ivltests/sys_func_task_error.v:12: Error: $display() is a system task, it cannot be called as a function. vsim: Program not runnable, 3 errors. iverilog-12_0/ivtest/gold/tern3.gold000066400000000000000000000000501435245347300175070ustar00rootroot00000000000000(Start) (Start) $bits == 40 $bits == 40 iverilog-12_0/ivtest/gold/tern5.gold000066400000000000000000000003101435245347300175100ustar00rootroot0000000000000000: foo = 01x01x01x 01: foo = 000111xxx 0x: foo = 0xxx1xxxx 11: foo = 000111xxx 1x: foo = 000111xxx 00: foo = 01x01x01x 01: foo = 000111xxx 0x: foo = 0xxx1xxxx 11: foo = 000111xxx 1x: foo = 000111xxx iverilog-12_0/ivtest/gold/test_disphob.gold000066400000000000000000000013741435245347300211550ustar00rootroot00000000000000============================ myReg14 = 65 >| 65| *| 65| *| 65| >|0041| *|0041| *|0041| >|00101| *|00101| *|00101| >|00000001000001| *|00000001000001| *|00000001000001| ============================ myInt = -10 >| -10| *| -10| >|fffffff6| *|fffffff6| >|37777777766| *|37777777766| >|11111111111111111111111111110110| *|11111111111111111111111111110110| ============================ myReg32 = -10 >|4294967286| *|4294967286| >|fffffff6| *|fffffff6| >|37777777766| *|37777777766| >|11111111111111111111111111110110| *|11111111111111111111111111110110| ============================ myInt = 65 >| 65| *| 65| >|00000041| *|00000041| >|00000000101| *|00000000101| >|00000000000000000000000001000001| *|00000000000000000000000001000001| iverilog-12_0/ivtest/gold/test_dispwided.gold000066400000000000000000000274001435245347300214770ustar00rootroot00000000000000value= 1 value= 2 value= 4 value= 8 value= 16 value= 32 value= 64 value= 128 value= 256 value= 512 value= 1024 value= 2048 value= 4096 value= 8192 value= 16384 value= 32768 value= 65536 value= 131072 value= 262144 value= 524288 value= 1048576 value= 2097152 value= 4194304 value= 8388608 value= 16777216 value= 33554432 value= 67108864 value= 134217728 value= 268435456 value= 536870912 value= 1073741824 value= 2147483648 value= 4294967296 value= 8589934592 value= 17179869184 value= 34359738368 value= 68719476736 value= 137438953472 value= 274877906944 value= 549755813888 value= 1099511627776 value= 2199023255552 value= 4398046511104 value= 8796093022208 value= 17592186044416 value= 35184372088832 value= 70368744177664 value= 140737488355328 value= 281474976710656 value= 562949953421312 value= 1125899906842624 value= 2251799813685248 value= 4503599627370496 value= 9007199254740992 value= 18014398509481984 value= 36028797018963968 value= 72057594037927936 value= 144115188075855872 value= 288230376151711744 value= 576460752303423488 value= 1152921504606846976 value= 2305843009213693952 value= 4611686018427387904 value= 9223372036854775808 value= 18446744073709551616 value= 36893488147419103232 value= 73786976294838206464 value= 147573952589676412928 value= 295147905179352825856 value= 590295810358705651712 value= 1180591620717411303424 value= 2361183241434822606848 value= 4722366482869645213696 value= 9444732965739290427392 value= 18889465931478580854784 value= 37778931862957161709568 value= 75557863725914323419136 value= 151115727451828646838272 value= 302231454903657293676544 value= 604462909807314587353088 value= 1208925819614629174706176 value= 2417851639229258349412352 value= 4835703278458516698824704 value= 9671406556917033397649408 value= 19342813113834066795298816 value= 38685626227668133590597632 value= 77371252455336267181195264 value= 154742504910672534362390528 value= 309485009821345068724781056 value= 618970019642690137449562112 value= 1237940039285380274899124224 value= 2475880078570760549798248448 value= 4951760157141521099596496896 value= 9903520314283042199192993792 value= 19807040628566084398385987584 value= 39614081257132168796771975168 value= 79228162514264337593543950336 value= 158456325028528675187087900672 value= 316912650057057350374175801344 value= 633825300114114700748351602688 value= 1267650600228229401496703205376 value= 2535301200456458802993406410752 value= 5070602400912917605986812821504 value= 10141204801825835211973625643008 value= 20282409603651670423947251286016 value= 40564819207303340847894502572032 value= 81129638414606681695789005144064 value= 162259276829213363391578010288128 value= 324518553658426726783156020576256 value= 649037107316853453566312041152512 value= 1298074214633706907132624082305024 value= 2596148429267413814265248164610048 value= 5192296858534827628530496329220096 value= 10384593717069655257060992658440192 value= 20769187434139310514121985316880384 value= 41538374868278621028243970633760768 value= 83076749736557242056487941267521536 value= 166153499473114484112975882535043072 value= 332306998946228968225951765070086144 value= 664613997892457936451903530140172288 value= 1329227995784915872903807060280344576 value= 2658455991569831745807614120560689152 value= 5316911983139663491615228241121378304 value= 10633823966279326983230456482242756608 value= 21267647932558653966460912964485513216 value= 42535295865117307932921825928971026432 value= 85070591730234615865843651857942052864 value=-170141183460469231731687303715884105728 value= -1 value= -2 value= -4 value= -8 value= -16 value= -32 value= -64 value= -128 value= -256 value= -512 value= -1024 value= -2048 value= -4096 value= -8192 value= -16384 value= -32768 value= -65536 value= -131072 value= -262144 value= -524288 value= -1048576 value= -2097152 value= -4194304 value= -8388608 value= -16777216 value= -33554432 value= -67108864 value= -134217728 value= -268435456 value= -536870912 value= -1073741824 value= -2147483648 value= -4294967296 value= -8589934592 value= -17179869184 value= -34359738368 value= -68719476736 value= -137438953472 value= -274877906944 value= -549755813888 value= -1099511627776 value= -2199023255552 value= -4398046511104 value= -8796093022208 value= -17592186044416 value= -35184372088832 value= -70368744177664 value= -140737488355328 value= -281474976710656 value= -562949953421312 value= -1125899906842624 value= -2251799813685248 value= -4503599627370496 value= -9007199254740992 value= -18014398509481984 value= -36028797018963968 value= -72057594037927936 value= -144115188075855872 value= -288230376151711744 value= -576460752303423488 value= -1152921504606846976 value= -2305843009213693952 value= -4611686018427387904 value= -9223372036854775808 value= -18446744073709551616 value= -36893488147419103232 value= -73786976294838206464 value= -147573952589676412928 value= -295147905179352825856 value= -590295810358705651712 value= -1180591620717411303424 value= -2361183241434822606848 value= -4722366482869645213696 value= -9444732965739290427392 value= -18889465931478580854784 value= -37778931862957161709568 value= -75557863725914323419136 value= -151115727451828646838272 value= -302231454903657293676544 value= -604462909807314587353088 value= -1208925819614629174706176 value= -2417851639229258349412352 value= -4835703278458516698824704 value= -9671406556917033397649408 value= -19342813113834066795298816 value= -38685626227668133590597632 value= -77371252455336267181195264 value= -154742504910672534362390528 value= -309485009821345068724781056 value= -618970019642690137449562112 value= -1237940039285380274899124224 value= -2475880078570760549798248448 value= -4951760157141521099596496896 value= -9903520314283042199192993792 value= -19807040628566084398385987584 value= -39614081257132168796771975168 value= -79228162514264337593543950336 value= -158456325028528675187087900672 value= -316912650057057350374175801344 value= -633825300114114700748351602688 value= -1267650600228229401496703205376 value= -2535301200456458802993406410752 value= -5070602400912917605986812821504 value= -10141204801825835211973625643008 value= -20282409603651670423947251286016 value= -40564819207303340847894502572032 value= -81129638414606681695789005144064 value= -162259276829213363391578010288128 value= -324518553658426726783156020576256 value= -649037107316853453566312041152512 value= -1298074214633706907132624082305024 value= -2596148429267413814265248164610048 value= -5192296858534827628530496329220096 value= -10384593717069655257060992658440192 value= -20769187434139310514121985316880384 value= -41538374868278621028243970633760768 value= -83076749736557242056487941267521536 value= -166153499473114484112975882535043072 value= -332306998946228968225951765070086144 value= -664613997892457936451903530140172288 value= -1329227995784915872903807060280344576 value= -2658455991569831745807614120560689152 value= -5316911983139663491615228241121378304 value= -10633823966279326983230456482242756608 value= -21267647932558653966460912964485513216 value= -42535295865117307932921825928971026432 value= -85070591730234615865843651857942052864 value=-170141183460469231731687303715884105728 iverilog-12_0/ivtest/gold/test_extended.gold000066400000000000000000000005411435245347300213200ustar00rootroot00000000000000============================ myReg8 = 65 >| 65| *| 65| *| 65| ============================ myReg14 = -10 >|16374| *|16374| *|16374| ============================ myReg14 = 65 >1| 65| *1| 65| >2|65| *2|65| >3| 65| *3| 65| >4| 65| *4|00000065| *4| 65| >5| 65| *5|065| *5| 65| ============================ myReg14 = 1000 >|1000| *|1000| iverilog-12_0/ivtest/gold/test_va_math.gold000066400000000000000000000235051435245347300211440ustar00rootroot00000000000000Using +0 = 0.000000, -0 = -0.000000, nan = nan, inf = inf and -inf = -inf. NaN != comparison works correctly. NaN == comparison works correctly. --- Checking the $sqrt function --- The square root of 2.0 is 1.414214. The square root of 1.0 is 1.000000. The square root of 0.0 is 0.000000. The square root of -0.0 is -0.000000. The square root of -1.0 is nan. The square root of inf is inf. The square root of -inf is nan. The square root of nan is nan. --- Checking the $ln function --- The natural log of 10.0 is 2.302585. The natural log of 1.0 is 0.000000. The natural log of 0.5 is -0.693147. The natural log of 0.0 is -inf. The natural log of -0.0 is -inf. The natural log of -1.0 is nan. The natural log of inf is inf. The natural log of -inf is nan. The natural log of nan is nan. --- Checking the $log10 function --- The log base 10 of 10.0 is 1.000000. The log base 10 of 1.0 is 0.000000. The log base 10 of 0.5 is -0.301030. The log base 10 of 0.0 is -inf. The log base 10 of -0.0 is -inf. The log base 10 of -1.0 is nan. The log base 10 of inf is inf. The log base 10 of -inf is nan. The log base 10 of nan is nan. --- Checking the $exp function --- The exponential of 1.0 is 2.718282. The exponential of 0.0 is 1.000000. The exponential of -0.0 is 1.000000. The exponential of -1.0 is 0.367879. The exponential of inf is inf. The exponential of -inf is 0.000000. The exponential of nan is nan. --- Checking the $abs function --- The absolute value of 1.0 is 1.000000. The absolute value of 0.0 is 0.000000. The absolute value of -0.0 is 0.000000. The absolute value of -1.0 is 1.000000. The absolute value of inf is inf. The absolute value of -inf is inf. The absolute value of nan is nan. --- Checking the $ceil function --- The ceiling of 2.1 is 3.000000. The ceiling of 0.5 is 1.000000. The ceiling of -0.5 is 0.000000. The ceiling of -1.1 is -1.000000. The ceiling of inf is inf. The ceiling of -inf is -inf. The ceiling of nan is nan. --- Checking the $floor function --- The floor of 2.1 is 2.000000. The floor of 0.5 is 0.000000. The floor of -0.5 is -1.000000. The floor of -1.1 is -2.000000. The floor of inf is inf. The floor of -inf is -inf. The floor of nan is nan. --- Checking the $sin function --- The sin of 4.0 is -0.756802. The sin of 1.0 is 0.841471. The sin of 0.0 is 0.000000. The sin of -0.0 is -0.000000. The sin of -1.0 is -0.841471. The sin of -4.0 is 0.756802. The sin of inf is nan. The sin of -inf is nan. The sin of nan is nan. --- Checking the $cos function --- The cos of 4.0 is -0.653644. The cos of 1.0 is 0.540302. The cos of 0.0 is 1.000000. The cos of -0.0 is 1.000000. The cos of -1.0 is 0.540302. The cos of -4.0 is -0.653644. The cos of inf is nan. The cos of -inf is nan. The cos of nan is nan. --- Checking the $tan function --- The tan of 4.0 is 1.157821. The tan of 1.0 is 1.557408. The tan of 0.0 is 0.000000. The tan of -0.0 is -0.000000. The tan of -1.0 is -1.557408. The tan of -4.0 is -1.157821. The tan of pi/2 is 1.633e+16. The tan of -pi/2 is -1.633e+16. The tan of inf is nan. The tan of -inf is nan. The tan of nan is nan. --- Checking the $asin function --- The asin of 1.1 is nan. The asin of 1.0 is 1.570796. The asin of 0.5 is 0.523599. The asin of 0.0 is 0.000000. The asin of -0.0 is -0.000000. The asin of -0.5 is -0.523599. The asin of -1.0 is -1.570796. The asin of -1.1 is nan. The asin of inf is nan. The asin of -inf is nan. The asin of nan is nan. --- Checking the $acos function --- The acos of 1.1 is nan. The acos of 1.0 is 0.000000. The acos of 0.5 is 1.047198. The acos of 0.0 is 1.570796. The acos of -0.0 is 1.570796. The acos of -0.5 is 2.094395. The acos of -1.0 is 3.141593. The acos of -1.1 is nan. The acos of inf is nan. The acos of -inf is nan. The acos of nan is nan. --- Checking the $atan function --- The atan of 2.0 is 1.107149. The atan of 0.5 is 0.463648. The atan of 0.0 is 0.000000. The atan of -0.0 is -0.000000. The atan of -0.5 is -0.463648. The atan of -2.0 is -1.107149. The atan of inf is 1.570796. The atan of -inf is -1.570796. The atan of nan is nan. --- Checking the $sinh function --- The sinh of 2.0 is 3.626860. The sinh of 1.0 is 1.175201. The sinh of 0.5 is 0.521095. The sinh of 0.0 is 0.000000. The sinh of -0.0 is -0.000000. The sinh of -0.5 is -0.521095. The sinh of -1.0 is -1.175201. The sinh of -2.0 is -3.626860. The sinh of inf is inf. The sinh of -inf is -inf. The sinh of nan is nan. --- Checking the $cosh function --- The cosh of 2.0 is 3.762196. The cosh of 1.0 is 1.543081. The cosh of 0.5 is 1.127626. The cosh of 0.0 is 1.000000. The cosh of -0.0 is 1.000000. The cosh of -0.5 is 1.127626. The cosh of -1.0 is 1.543081. The cosh of -2.0 is 3.762196. The cosh of inf is inf. The cosh of -inf is inf. The cosh of nan is nan. --- Checking the $tanh function --- The tanh of 2.0 is 0.964028. The tanh of 1.0 is 0.761594. The tanh of 0.5 is 0.462117. The tanh of 0.0 is 0.000000. The tanh of -0.0 is -0.000000. The tanh of -0.5 is -0.462117. The tanh of -1.0 is -0.761594. The tanh of -2.0 is -0.964028. The tanh of inf is 1.000000. The tanh of -inf is -1.000000. The tanh of nan is nan. --- Checking the $asinh function --- The asinh of 2.0 is 1.443635. The asinh of 1.0 is 0.881374. The asinh of 0.5 is 0.481212. The asinh of 0.0 is 0.000000. The asinh of -0.0 is -0.000000. The asinh of -0.5 is -0.481212. The asinh of -1.0 is -0.881374. The asinh of -2.0 is -1.443635. The asinh of inf is inf. The asinh of -inf is -inf. The asinh of nan is nan. --- Checking the $acosh function --- The acosh of 2.0 is 1.316958. The acosh of 1.0 is 0.000000. The acosh of 0.5 is nan. The acosh of 0 is nan. The acosh of -0 is nan. The acosh of -0.5 is nan. The acosh of -1.0 is nan. The acosh of -2.0 is nan. The acosh of inf is inf. The acosh of -inf is nan. The acosh of nan is nan. --- Checking the $atanh function --- The atanh of 2.0 is nan. The atanh of 1.0 is inf. The atanh of 0.5 is 0.549306. The atanh of 0.0 is 0.000000. The atanh of -0.0 is -0.000000. The atanh of -0.5 is -0.549306. The atanh of -1.0 is -inf. The atanh of -2.0 is nan. The atanh of inf is nan. The atanh of -inf is nan. The atanh of nan is nan. --- Checking the $min function --- The minimum of 1.0 and 2.0 is 1.000000. The minimum of 2.0 and 1.0 is 1.000000. The minimum of 1.0 and -1.0 is -1.000000. The minimum of -1.0 and -2.0 is -2.000000. The minimum of 2.0 and inf is 2.000000. The minimum of inf and 2.0 is 2.000000. The minimum of 2.0 and -inf is -inf. The minimum of -inf and 2.0 is -inf. The minimum of 2.0 and nan is 2.000000. The minimum of nan and 2.0 is 2.000000. --- Checking the $max function --- The maximum of 1.0 and 2.0 is 2.000000. The maximum of 2.0 and 1.0 is 2.000000. The maximum of 1.0 and -1.0 is 1.000000. The maximum of -1.0 and -2.0 is -1.000000. The maximum of 2.0 and inf is inf. The maximum of inf and 2.0 is inf. The maximum of 2.0 and -inf is 2.000000. The maximum of -inf and 2.0 is 2.000000. The maximum of 2.0 and nan is 2.000000. The maximum of nan and 2.0 is 2.000000. --- Checking the $pow function --- 0.0 to the power of 0.0 is 1.000000. 1.0 to the power of 0.0 is 1.000000. -1.0 to the power of 0.0 is 1.000000. 0.0 to the power of 1.0 is 0.000000. 1.0 to the power of 1.0 is 1.000000. -1.0 to the power of 1.0 is -1.000000. 8.0 to the power of 1/3 is 2.000000. 8.0 to the power of -1/3 is 0.500000. 2.0 to the power of 3.0 is 8.000000. 2.0 to the power of 5000 is inf. -2.0 to the power of 5001 is -inf. 2.0 to the power of -5000 is 0.000000. inf to the power of 0.0 is 1.000000. -inf to the power of 0.0 is 1.000000. inf to the power of 1.0 is inf. -inf to the power of 1.0 is -inf. inf to the power of 2.0 is inf. -inf to the power of 2.0 is inf. 1.0 to the power of inf is 1.000000. -1.0 to the power of inf is 1.000000. 0.5 to the power of inf is 0.000000. 2.0 to the power of inf is inf. 1.0 to the power of -inf is 1.000000. -1.0 to the power of -inf is 1.000000. 0.5 to the power of -inf is inf. 2.0 to the power of -inf is 0.000000. -1.0 to the power of -1/3 is nan. 1.0 to the power of nan is 1.000000. nan to the power of 1.0 is nan. nan to the power of 0.0 is 1.000000. nan to the power of nan is nan. --- Checking the $atan2 function --- The atan of 0.0/ 0.0 is 0.000000. The atan of -0.0/ 0.0 is -0.000000. The atan of 0.0/-0.0 is 3.141593. The atan of -0.0/-0.0 is -3.141593. The atan of 0.0/ 1.0 is 0.000000. The atan of 1.0/ 0.0 is 1.570796. The atan of 1.0/ 1.0 is 0.785398. The atan of 0.0/-1.0 is 3.141593. The atan of -1.0/ 0.0 is -1.570796. The atan of -1.0/-1.0 is -2.356194. The atan of inf/ 0.0 is 1.570796. The atan of 0.0/ inf is 0.000000. The atan of inf/ inf is 0.785398. The atan of -inf/ 0.0 is -1.570796. The atan of 0.0/-inf is 3.141593. The atan of -inf/-inf is -2.356194. The atan of nan/ 0.0 is nan. The atan of nan/ 1.0 is nan. The atan of 1.0/ nan is nan. --- Checking the $hypot function --- The distance to ( 0.0, 0.0) is 0.000000. The distance to ( 2.0, 0.0) is 2.000000. The distance to ( -2.0, 0.0) is 2.000000. The distance to ( 0.0, 2.0) is 2.000000. The distance to ( 0.0, -2.0) is 2.000000. The distance to ( inf, 0.0) is inf. The distance to ( 0.0, inf) is inf. The distance to ( -inf, 0.0) is inf. The distance to ( nan, 0.0) is nan. The distance to ( 0.0, nan) is nan. --- Checking the mathematical constants --- Pi is 3.1415926535897931. 2*Pi is 6.2831853071795862. Pi/2 is 1.5707963267948966. Pi/4 is 0.7853981633974483. 1/Pi is 0.3183098861837907. 2/Pi is 0.6366197723675814. 2/sqrt(Pi) is 1.1283791670955126. e is 2.7182818284590451. log2(e) is 1.4426950408889634. log10(e) is 0.4342944819032518. loge(2) is 0.6931471805599453. loge(10) is 2.3025850929940459. sqrt(2) is 1.4142135623730951. 1/sqrt(2) is 0.7071067811865476. iverilog-12_0/ivtest/gold/test_vams_math.gold000066400000000000000000000234531435245347300215060ustar00rootroot00000000000000Using +0 = 0.000000, -0 = -0.000000, nan = nan, inf = inf and -inf = -inf. NaN != comparison works correctly. NaN == comparison works correctly. --- Checking the sqrt function --- The square root of 2.0 is 1.414214. The square root of 1.0 is 1.000000. The square root of 0.0 is 0.000000. The square root of -0.0 is -0.000000. The square root of -1.0 is nan. The square root of inf is inf. The square root of -inf is nan. The square root of nan is nan. --- Checking the ln function --- The natural log of 10.0 is 2.302585. The natural log of 1.0 is 0.000000. The natural log of 0.5 is -0.693147. The natural log of 0.0 is -inf. The natural log of -0.0 is -inf. The natural log of -1.0 is nan. The natural log of inf is inf. The natural log of -inf is nan. The natural log of nan is nan. --- Checking the log function --- The log base 10 of 10.0 is 1.000000. The log base 10 of 1.0 is 0.000000. The log base 10 of 0.5 is -0.301030. The log base 10 of 0.0 is -inf. The log base 10 of -0.0 is -inf. The log base 10 of -1.0 is nan. The log base 10 of inf is inf. The log base 10 of -inf is nan. The log base 10 of nan is nan. --- Checking the exp function --- The exponential of 1.0 is 2.718282. The exponential of 0.0 is 1.000000. The exponential of -0.0 is 1.000000. The exponential of -1.0 is 0.367879. The exponential of inf is inf. The exponential of -inf is 0.000000. The exponential of nan is nan. --- Checking the abs function --- The absolute value of 1.0 is 1.000000. The absolute value of 0.0 is 0.000000. The absolute value of -0.0 is 0.000000. The absolute value of -1.0 is 1.000000. The absolute value of inf is inf. The absolute value of -inf is inf. The absolute value of nan is nan. --- Checking the ceil function --- The ceiling of 2.1 is 3.000000. The ceiling of 0.5 is 1.000000. The ceiling of -0.5 is 0.000000. The ceiling of -1.1 is -1.000000. The ceiling of inf is inf. The ceiling of -inf is -inf. The ceiling of nan is nan. --- Checking the floor function --- The floor of 2.1 is 2.000000. The floor of 0.5 is 0.000000. The floor of -0.5 is -1.000000. The floor of -1.1 is -2.000000. The floor of inf is inf. The floor of -inf is -inf. The floor of nan is nan. --- Checking the sin function --- The sin of 4.0 is -0.756802. The sin of 1.0 is 0.841471. The sin of 0.0 is 0.000000. The sin of -0.0 is -0.000000. The sin of -1.0 is -0.841471. The sin of -4.0 is 0.756802. The sin of inf is nan. The sin of -inf is nan. The sin of nan is nan. --- Checking the cos function --- The cos of 4.0 is -0.653644. The cos of 1.0 is 0.540302. The cos of 0.0 is 1.000000. The cos of -0.0 is 1.000000. The cos of -1.0 is 0.540302. The cos of -4.0 is -0.653644. The cos of inf is nan. The cos of -inf is nan. The cos of nan is nan. --- Checking the tan function --- The tan of 4.0 is 1.157821. The tan of 1.0 is 1.557408. The tan of 0.0 is 0.000000. The tan of -0.0 is -0.000000. The tan of -1.0 is -1.557408. The tan of -4.0 is -1.157821. The tan of pi/2 is 1.633e+16. The tan of -pi/2 is -1.633e+16. The tan of inf is nan. The tan of -inf is nan. The tan of nan is nan. --- Checking the asin function --- The asin of 1.1 is nan. The asin of 1.0 is 1.570796. The asin of 0.5 is 0.523599. The asin of 0.0 is 0.000000. The asin of -0.0 is -0.000000. The asin of -0.5 is -0.523599. The asin of -1.0 is -1.570796. The asin of -1.1 is nan. The asin of inf is nan. The asin of -inf is nan. The asin of nan is nan. --- Checking the acos function --- The acos of 1.1 is nan. The acos of 1.0 is 0.000000. The acos of 0.5 is 1.047198. The acos of 0.0 is 1.570796. The acos of -0.0 is 1.570796. The acos of -0.5 is 2.094395. The acos of -1.0 is 3.141593. The acos of -1.1 is nan. The acos of inf is nan. The acos of -inf is nan. The acos of nan is nan. --- Checking the atan function --- The atan of 2.0 is 1.107149. The atan of 0.5 is 0.463648. The atan of 0.0 is 0.000000. The atan of -0.0 is -0.000000. The atan of -0.5 is -0.463648. The atan of -2.0 is -1.107149. The atan of inf is 1.570796. The atan of -inf is -1.570796. The atan of nan is nan. --- Checking the sinh function --- The sinh of 2.0 is 3.626860. The sinh of 1.0 is 1.175201. The sinh of 0.5 is 0.521095. The sinh of 0.0 is 0.000000. The sinh of -0.0 is -0.000000. The sinh of -0.5 is -0.521095. The sinh of -1.0 is -1.175201. The sinh of -2.0 is -3.626860. The sinh of inf is inf. The sinh of -inf is -inf. The sinh of nan is nan. --- Checking the cosh function --- The cosh of 2.0 is 3.762196. The cosh of 1.0 is 1.543081. The cosh of 0.5 is 1.127626. The cosh of 0.0 is 1.000000. The cosh of -0.0 is 1.000000. The cosh of -0.5 is 1.127626. The cosh of -1.0 is 1.543081. The cosh of -2.0 is 3.762196. The cosh of inf is inf. The cosh of -inf is inf. The cosh of nan is nan. --- Checking the tanh function --- The tanh of 2.0 is 0.964028. The tanh of 1.0 is 0.761594. The tanh of 0.5 is 0.462117. The tanh of 0.0 is 0.000000. The tanh of -0.0 is -0.000000. The tanh of -0.5 is -0.462117. The tanh of -1.0 is -0.761594. The tanh of -2.0 is -0.964028. The tanh of inf is 1.000000. The tanh of -inf is -1.000000. The tanh of nan is nan. --- Checking the asinh function --- The asinh of 2.0 is 1.443635. The asinh of 1.0 is 0.881374. The asinh of 0.5 is 0.481212. The asinh of 0.0 is 0.000000. The asinh of -0.0 is -0.000000. The asinh of -0.5 is -0.481212. The asinh of -1.0 is -0.881374. The asinh of -2.0 is -1.443635. The asinh of inf is inf. The asinh of -inf is -inf. The asinh of nan is nan. --- Checking the acosh function --- The acosh of 2.0 is 1.316958. The acosh of 1.0 is 0.000000. The acosh of 0.5 is nan. The acosh of 0 is nan. The acosh of -0 is nan. The acosh of -0.5 is nan. The acosh of -1.0 is nan. The acosh of -2.0 is nan. The acosh of inf is inf. The acosh of -inf is nan. The acosh of nan is nan. --- Checking the atanh function --- The atanh of 2.0 is nan. The atanh of 1.0 is inf. The atanh of 0.5 is 0.549306. The atanh of 0.0 is 0.000000. The atanh of -0.0 is -0.000000. The atanh of -0.5 is -0.549306. The atanh of -1.0 is -inf. The atanh of -2.0 is nan. The atanh of inf is nan. The atanh of -inf is nan. The atanh of nan is nan. --- Checking the min function --- The minimum of 1.0 and 2.0 is 1.000000. The minimum of 2.0 and 1.0 is 1.000000. The minimum of 1.0 and -1.0 is -1.000000. The minimum of -1.0 and -2.0 is -2.000000. The minimum of 2.0 and inf is 2.000000. The minimum of inf and 2.0 is 2.000000. The minimum of 2.0 and -inf is -inf. The minimum of -inf and 2.0 is -inf. The minimum of 2.0 and nan is 2.000000. The minimum of nan and 2.0 is 2.000000. --- Checking the max function --- The maximum of 1.0 and 2.0 is 2.000000. The maximum of 2.0 and 1.0 is 2.000000. The maximum of 1.0 and -1.0 is 1.000000. The maximum of -1.0 and -2.0 is -1.000000. The maximum of 2.0 and inf is inf. The maximum of inf and 2.0 is inf. The maximum of 2.0 and -inf is 2.000000. The maximum of -inf and 2.0 is 2.000000. The maximum of 2.0 and nan is 2.000000. The maximum of nan and 2.0 is 2.000000. --- Checking the pow function --- 0.0 to the power of 0.0 is 1.000000. 1.0 to the power of 0.0 is 1.000000. -1.0 to the power of 0.0 is 1.000000. 0.0 to the power of 1.0 is 0.000000. 1.0 to the power of 1.0 is 1.000000. -1.0 to the power of 1.0 is -1.000000. 8.0 to the power of 1/3 is 2.000000. 8.0 to the power of -1/3 is 0.500000. 2.0 to the power of 3.0 is 8.000000. 2.0 to the power of 5000 is inf. -2.0 to the power of 5001 is -inf. 2.0 to the power of -5000 is 0.000000. inf to the power of 0.0 is 1.000000. -inf to the power of 0.0 is 1.000000. inf to the power of 1.0 is inf. -inf to the power of 1.0 is -inf. inf to the power of 2.0 is inf. -inf to the power of 2.0 is inf. 1.0 to the power of inf is 1.000000. -1.0 to the power of inf is 1.000000. 0.5 to the power of inf is 0.000000. 2.0 to the power of inf is inf. 1.0 to the power of -inf is 1.000000. -1.0 to the power of -inf is 1.000000. 0.5 to the power of -inf is inf. 2.0 to the power of -inf is 0.000000. -1.0 to the power of -1/3 is nan. 1.0 to the power of nan is 1.000000. nan to the power of 1.0 is nan. nan to the power of 0.0 is 1.000000. nan to the power of nan is nan. --- Checking the atan2 function --- The atan of 0.0/ 0.0 is 0.000000. The atan of -0.0/ 0.0 is -0.000000. The atan of 0.0/-0.0 is 3.141593. The atan of -0.0/-0.0 is -3.141593. The atan of 0.0/ 1.0 is 0.000000. The atan of 1.0/ 0.0 is 1.570796. The atan of 1.0/ 1.0 is 0.785398. The atan of 0.0/-1.0 is 3.141593. The atan of -1.0/ 0.0 is -1.570796. The atan of -1.0/-1.0 is -2.356194. The atan of inf/ 0.0 is 1.570796. The atan of 0.0/ inf is 0.000000. The atan of inf/ inf is 0.785398. The atan of -inf/ 0.0 is -1.570796. The atan of 0.0/-inf is 3.141593. The atan of -inf/-inf is -2.356194. The atan of nan/ 0.0 is nan. The atan of nan/ 1.0 is nan. The atan of 1.0/ nan is nan. --- Checking the hypot function --- The distance to ( 0.0, 0.0) is 0.000000. The distance to ( 2.0, 0.0) is 2.000000. The distance to ( -2.0, 0.0) is 2.000000. The distance to ( 0.0, 2.0) is 2.000000. The distance to ( 0.0, -2.0) is 2.000000. The distance to ( inf, 0.0) is inf. The distance to ( 0.0, inf) is inf. The distance to ( -inf, 0.0) is inf. The distance to ( nan, 0.0) is nan. The distance to ( 0.0, nan) is nan. --- Checking the mathematical constants --- Pi is 3.1415926535897931. 2*Pi is 6.2831853071795862. Pi/2 is 1.5707963267948966. Pi/4 is 0.7853981633974483. 1/Pi is 0.3183098861837907. 2/Pi is 0.6366197723675814. 2/sqrt(Pi) is 1.1283791670955126. e is 2.7182818284590451. log2(e) is 1.4426950408889634. log10(e) is 0.4342944819032518. loge(2) is 0.6931471805599453. loge(10) is 2.3025850929940459. sqrt(2) is 1.4142135623730951. 1/sqrt(2) is 0.7071067811865476. iverilog-12_0/ivtest/gold/test_width.gold000066400000000000000000000023171435245347300206420ustar00rootroot00000000000000============================ myReg14 = -10 >|16374| *|16374| *|16374| *|16374| ============================ myReg14 = 65 >| 65| *| 65| *| 65| >|65| *|65| >|0041| *|0041| >|41| *|41| >|00101| *|00101| >|101| *|101| >|00000001000001| *|00000001000001| >|1000001| *|1000001| >| A| *| A| >|A| *|A| ============================ myInt = -10 >| -10| *| -10| *| -10| >|-10| *|-10| >|fffffff6| *|fffffff6| *|fffffff6| >|37777777766| *|37777777766| *|37777777766| >|11111111111111111111111111110110| *|11111111111111111111111111110110| *|11111111111111111111111111110110| ============================ myReg32 = -10 >|4294967286| *|4294967286| *|4294967286| *|4294967286| >|fffffff6| *|fffffff6| *|fffffff6| >|37777777766| *|37777777766| *|37777777766| ============================ myInt = 65 >| 65| *| 65| *| 65| >|65| *|65| >|00000041| *|00000041| >|41| *|41| >|00000000101| *|00000000101| >|101| *|101| >|00000000000000000000000001000001| *|00000000000000000000000001000001| >|1000001| *|1000001| *| A| >| A| *|A| >|A| ============================ Print " A" *| A| >| A| >| A| ============================ Print $time *| 0| >| 0| *|0| >|0| iverilog-12_0/ivtest/gold/time6c.gold000066400000000000000000000001161435245347300176460ustar00rootroot00000000000000 3 3.4 set out1 == 1 4 3.6 set out2 == 1 iverilog-12_0/ivtest/gold/time7.gold000066400000000000000000000013571435245347300175140ustar00rootroot00000000000000 << BEGIN >> @ 0 - no count @ 0 - no count @ 1 - no count @ 2 - no count @ 3 - no count @ 4 - no count @ 5 - no count @ 6 - no count @ 7 - no count @ 8 - no count @ 9 - no count @ 10 - no count @ 11 - no count @ 12 - no count @ 13 - no count @ 14 - no count @ 15 - no count @ 16 - no count @ 17 - no count @ 18 - no count @ 19 - no count @ 20 - no count @ 21 - no count @ 22 - no count @ 23 - no count @ 24 - Got ONE @ 25 - no count @ 26 - no count @ 27 - no count @ 28 - Got ONE @ 29 - no count @ 30 - no count @ 31 - no count @ 32 - no count @ 33 - no count @ 34 - no count @ 35 - no count @ 36 - no count @ 37 - no count @ 38 - no count @ 39 - no count @ 40 - no count @ 41 - no count @ 42 - no count @ 43 - no count @ 44 - no count << END >> OK iverilog-12_0/ivtest/gold/timeform1.gold000066400000000000000000000001431435245347300203620ustar00rootroot00000000000000$time = 3 (unformatted) $time = 0.003000ns (-6,6) $time = 0.0ns (-6,1) iverilog-12_0/ivtest/gold/timeform2.gold000066400000000000000000000000661435245347300203670ustar00rootroot00000000000000time within module: 1.000ns time within task: 1.000ns iverilog-12_0/ivtest/gold/tran.gold000066400000000000000000000142201435245347300174240ustar00rootroot00000000000000a = z b = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = z a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 St0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 St0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 St0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = z a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 St1) t12(Su1 St1) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 760) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 760) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(Su0 760) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = x a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 761) t14(Su1 761) t15(Su1 761) t21(StX 76X) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(St0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(St0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = x b = 0 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(760 Su0) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(760 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(760 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su0) t12(Su1 StX) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(StX Su0) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(St0 Su0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = z b = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St1 Su1) t12(St1 Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(761 Su1) t14(761 Su1) t15(761 Su1) t21(76X StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = 1 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su1) t12(StX Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(Su0 StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Su0 St0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 1 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/tranif0.gold000066400000000000000000000620001435245347300200220ustar00rootroot00000000000000a = z b = z en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = z en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = z en = 0 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = z en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX HiZ) t12(67X HiZ) t13(57X HiZ) t14(37X HiZ) t15(SuH HiZ) t21(76X HiZ) t22(StX HiZ) t23(56X HiZ) t24(36X HiZ) t25(StH HiZ) t31(75X HiZ) t32(65X HiZ) t33(PuX HiZ) t34(35X HiZ) t35(PuH HiZ) t41(73X HiZ) t42(63X HiZ) t43(53X HiZ) t44(WeX HiZ) t45(WeH HiZ) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = 0 b = z en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 StL) t12(St0 StL) t13(Pu0 PuL) t14(We0 WeL) t15(HiZ HiZ) t21(Su0 StL) t22(St0 StL) t23(Pu0 PuL) t24(We0 WeL) t25(HiZ HiZ) t31(Su0 StL) t32(St0 StL) t33(Pu0 PuL) t34(We0 WeL) t35(HiZ HiZ) t41(Su0 StL) t42(St0 StL) t43(Pu0 PuL) t44(We0 WeL) t45(HiZ HiZ) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = z en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 StL) t12(St0 StL) t13(Pu0 PuL) t14(We0 WeL) t15(HiZ HiZ) t21(Su0 StL) t22(St0 StL) t23(Pu0 PuL) t24(We0 WeL) t25(HiZ HiZ) t31(Su0 StL) t32(St0 StL) t33(Pu0 PuL) t34(We0 WeL) t35(HiZ HiZ) t41(Su0 StL) t42(St0 StL) t43(Pu0 PuL) t44(We0 WeL) t45(HiZ HiZ) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = z en = 0 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 St0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 St0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 St0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = z en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 HiZ) t12(St0 HiZ) t13(Pu0 HiZ) t14(We0 HiZ) t15(HiZ HiZ) t21(Su0 HiZ) t22(St0 HiZ) t23(Pu0 HiZ) t24(We0 HiZ) t25(HiZ HiZ) t31(Su0 HiZ) t32(St0 HiZ) t33(Pu0 HiZ) t34(We0 HiZ) t35(HiZ HiZ) t41(Su0 HiZ) t42(St0 HiZ) t43(Pu0 HiZ) t44(We0 HiZ) t45(HiZ HiZ) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 1 b = z en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 StH) t12(Su1 StH) t13(Su1 StH) t14(Su1 StH) t15(Su1 StH) t21(St1 StH) t22(St1 StH) t23(St1 StH) t24(St1 StH) t25(St1 StH) t31(Pu1 PuH) t32(Pu1 PuH) t33(Pu1 PuH) t34(Pu1 PuH) t35(Pu1 PuH) t41(We1 WeH) t42(We1 WeH) t43(We1 WeH) t44(We1 WeH) t45(We1 WeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 StH) t12(Su1 StH) t13(Su1 StH) t14(Su1 StH) t15(Su1 StH) t21(St1 StH) t22(St1 StH) t23(St1 StH) t24(St1 StH) t25(St1 StH) t31(Pu1 PuH) t32(Pu1 PuH) t33(Pu1 PuH) t34(Pu1 PuH) t35(Pu1 PuH) t41(We1 WeH) t42(We1 WeH) t43(We1 WeH) t44(We1 WeH) t45(We1 WeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 0 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 St1) t12(Su1 St1) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 HiZ) t12(Su1 HiZ) t13(Su1 HiZ) t14(Su1 HiZ) t15(Su1 HiZ) t21(St1 HiZ) t22(St1 HiZ) t23(St1 HiZ) t24(St1 HiZ) t25(St1 HiZ) t31(Pu1 HiZ) t32(Pu1 HiZ) t33(Pu1 HiZ) t34(Pu1 HiZ) t35(Pu1 HiZ) t41(We1 HiZ) t42(We1 HiZ) t43(We1 HiZ) t44(We1 HiZ) t45(We1 HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = x en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = x en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = x en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ SuX) t12(HiZ 67X) t13(HiZ 57X) t14(HiZ 37X) t15(HiZ SuH) t21(HiZ 76X) t22(HiZ StX) t23(HiZ 56X) t24(HiZ 36X) t25(HiZ StH) t31(HiZ 75X) t32(HiZ 65X) t33(HiZ PuX) t34(HiZ 35X) t35(HiZ PuH) t41(HiZ 73X) t42(HiZ 63X) t43(HiZ 53X) t44(HiZ WeX) t45(HiZ WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = x b = x en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 0 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 75X) t32(St0 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 75X) t32(St0 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 0 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 760) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 760) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(Su0 760) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = x en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 SuX) t12(St0 67X) t13(Pu0 57X) t14(We0 37X) t15(HiZ SuH) t21(Su0 76X) t22(St0 StX) t23(Pu0 56X) t24(We0 36X) t25(HiZ StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(We0 35X) t35(HiZ PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(HiZ WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 1 b = x en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(StX 76X) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 1 b = x en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(StX 76X) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 1 b = x en = 0 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 761) t14(Su1 761) t15(Su1 761) t21(StX 76X) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 1 b = x en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(Pu1 75X) t32(Pu1 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(We1 73X) t42(We1 63X) t43(We1 53X) t44(We1 WeX) t45(We1 WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = z b = 0 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StL Su0) t12(StL St0) t13(PuL Pu0) t14(WeL We0) t15(HiZ HiZ) t21(StL Su0) t22(StL St0) t23(PuL Pu0) t24(WeL We0) t25(HiZ HiZ) t31(StL Su0) t32(StL St0) t33(PuL Pu0) t34(WeL We0) t35(HiZ HiZ) t41(StL Su0) t42(StL St0) t43(PuL Pu0) t44(WeL We0) t45(HiZ HiZ) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = z b = 0 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StL Su0) t12(StL St0) t13(PuL Pu0) t14(WeL We0) t15(HiZ HiZ) t21(StL Su0) t22(StL St0) t23(PuL Pu0) t24(WeL We0) t25(HiZ HiZ) t31(StL Su0) t32(StL St0) t33(PuL Pu0) t34(WeL We0) t35(HiZ HiZ) t41(StL Su0) t42(StL St0) t43(PuL Pu0) t44(WeL We0) t45(HiZ HiZ) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = z b = 0 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(St0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(St0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = z b = 0 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su0) t12(HiZ St0) t13(HiZ Pu0) t14(HiZ We0) t15(HiZ HiZ) t21(HiZ Su0) t22(HiZ St0) t23(HiZ Pu0) t24(HiZ We0) t25(HiZ HiZ) t31(HiZ Su0) t32(HiZ St0) t33(HiZ Pu0) t34(HiZ We0) t35(HiZ HiZ) t41(HiZ Su0) t42(HiZ St0) t43(HiZ Pu0) t44(HiZ We0) t45(HiZ HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = x b = 0 en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X Su0) t32(65X St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(WeH WeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X Su0) t32(65X St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(WeH WeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 0 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(760 Su0) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(760 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(760 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = x b = 0 en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su0) t12(67X St0) t13(57X Pu0) t14(37X We0) t15(SuH HiZ) t21(76X Su0) t22(StX St0) t23(56X Pu0) t24(36X We0) t25(StH HiZ) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X We0) t35(PuH HiZ) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH HiZ) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 0 b = 0 en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 0 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su0) t12(Su1 StX) t13(Su1 56X) t14(Su1 36X) t15(Su1 StH) t21(StX Su0) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X Su0) t32(65X St0) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(We1 WeH) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 1 b = 0 en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su0) t12(Su1 StX) t13(Su1 56X) t14(Su1 36X) t15(Su1 StH) t21(StX Su0) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X Su0) t32(65X St0) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(We1 WeH) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 1 b = 0 en = 0 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su0) t12(Su1 StX) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(StX Su0) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(St0 Su0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su0) t12(Su1 St0) t13(Su1 Pu0) t14(Su1 We0) t15(Su1 HiZ) t21(St1 Su0) t22(St1 St0) t23(St1 Pu0) t24(St1 We0) t25(St1 HiZ) t31(Pu1 Su0) t32(Pu1 St0) t33(Pu1 Pu0) t34(Pu1 We0) t35(Pu1 HiZ) t41(We1 Su0) t42(We1 St0) t43(We1 Pu0) t44(We1 We0) t45(We1 HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = z b = 1 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StH Su1) t12(StH Su1) t13(StH Su1) t14(StH Su1) t15(StH Su1) t21(StH St1) t22(StH St1) t23(StH St1) t24(StH St1) t25(StH St1) t31(PuH Pu1) t32(PuH Pu1) t33(PuH Pu1) t34(PuH Pu1) t35(PuH Pu1) t41(WeH We1) t42(WeH We1) t43(WeH We1) t44(WeH We1) t45(WeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StH Su1) t12(StH Su1) t13(StH Su1) t14(StH Su1) t15(StH Su1) t21(StH St1) t22(StH St1) t23(StH St1) t24(StH St1) t25(StH St1) t31(PuH Pu1) t32(PuH Pu1) t33(PuH Pu1) t34(PuH Pu1) t35(PuH Pu1) t41(WeH We1) t42(WeH We1) t43(WeH We1) t44(WeH We1) t45(WeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St1 Su1) t12(St1 Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su1) t12(HiZ Su1) t13(HiZ Su1) t14(HiZ Su1) t15(HiZ Su1) t21(HiZ St1) t22(HiZ St1) t23(HiZ St1) t24(HiZ St1) t25(HiZ St1) t31(HiZ Pu1) t32(HiZ Pu1) t33(HiZ Pu1) t34(HiZ Pu1) t35(HiZ Pu1) t41(HiZ We1) t42(HiZ We1) t43(HiZ We1) t44(HiZ We1) t45(HiZ We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = 1 en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = 1 en = 0 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(761 Su1) t14(761 Su1) t15(761 Su1) t21(76X StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = 1 en = 1 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X Pu1) t32(65X Pu1) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X We1) t42(63X We1) t43(53X We1) t44(WeX We1) t45(WeH We1) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = 0 b = 1 en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su1) t12(StX Su1) t13(56X Su1) t14(36X Su1) t15(StH Su1) t21(Su0 StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(Su0 65X) t32(St0 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(Su0 63X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH We1) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = 1 en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su1) t12(StX Su1) t13(56X Su1) t14(36X Su1) t15(StH Su1) t21(Su0 StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(Su0 65X) t32(St0 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(Su0 63X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH We1) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = 1 en = 0 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su1) t12(StX Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(Su0 StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Su0 St0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 1 en = 1 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su1) t12(St0 Su1) t13(Pu0 Su1) t14(We0 Su1) t15(HiZ Su1) t21(Su0 St1) t22(St0 St1) t23(Pu0 St1) t24(We0 St1) t25(HiZ St1) t31(Su0 Pu1) t32(St0 Pu1) t33(Pu0 Pu1) t34(We0 Pu1) t35(HiZ Pu1) t41(Su0 We1) t42(St0 We1) t43(Pu0 We1) t44(We0 We1) t45(HiZ We1) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 1 b = 1 en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 0 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 1 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/tranif1.gold000066400000000000000000000620001435245347300200230ustar00rootroot00000000000000a = z b = z en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = z en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ HiZ) t12(HiZ HiZ) t13(HiZ HiZ) t14(HiZ HiZ) t15(HiZ HiZ) t21(HiZ HiZ) t22(HiZ HiZ) t23(HiZ HiZ) t24(HiZ HiZ) t25(HiZ HiZ) t31(HiZ HiZ) t32(HiZ HiZ) t33(HiZ HiZ) t34(HiZ HiZ) t35(HiZ HiZ) t41(HiZ HiZ) t42(HiZ HiZ) t43(HiZ HiZ) t44(HiZ HiZ) t45(HiZ HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = z en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = z en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = z en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX HiZ) t12(67X HiZ) t13(57X HiZ) t14(37X HiZ) t15(SuH HiZ) t21(76X HiZ) t22(StX HiZ) t23(56X HiZ) t24(36X HiZ) t25(StH HiZ) t31(75X HiZ) t32(65X HiZ) t33(PuX HiZ) t34(35X HiZ) t35(PuH HiZ) t41(73X HiZ) t42(63X HiZ) t43(53X HiZ) t44(WeX HiZ) t45(WeH HiZ) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = x b = z en = 1 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX StX) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X StX) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = z en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 StL) t12(St0 StL) t13(Pu0 PuL) t14(We0 WeL) t15(HiZ HiZ) t21(Su0 StL) t22(St0 StL) t23(Pu0 PuL) t24(We0 WeL) t25(HiZ HiZ) t31(Su0 StL) t32(St0 StL) t33(Pu0 PuL) t34(We0 WeL) t35(HiZ HiZ) t41(Su0 StL) t42(St0 StL) t43(Pu0 PuL) t44(We0 WeL) t45(HiZ HiZ) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = z en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 StL) t12(St0 StL) t13(Pu0 PuL) t14(We0 WeL) t15(HiZ HiZ) t21(Su0 StL) t22(St0 StL) t23(Pu0 PuL) t24(We0 WeL) t25(HiZ HiZ) t31(Su0 StL) t32(St0 StL) t33(Pu0 PuL) t34(We0 WeL) t35(HiZ HiZ) t41(Su0 StL) t42(St0 StL) t43(Pu0 PuL) t44(We0 WeL) t45(HiZ HiZ) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = z en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 HiZ) t12(St0 HiZ) t13(Pu0 HiZ) t14(We0 HiZ) t15(HiZ HiZ) t21(Su0 HiZ) t22(St0 HiZ) t23(Pu0 HiZ) t24(We0 HiZ) t25(HiZ HiZ) t31(Su0 HiZ) t32(St0 HiZ) t33(Pu0 HiZ) t34(We0 HiZ) t35(HiZ HiZ) t41(Su0 HiZ) t42(St0 HiZ) t43(Pu0 HiZ) t44(We0 HiZ) t45(HiZ HiZ) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 0 b = z en = 1 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 St0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 St0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 St0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = z en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 StH) t12(Su1 StH) t13(Su1 StH) t14(Su1 StH) t15(Su1 StH) t21(St1 StH) t22(St1 StH) t23(St1 StH) t24(St1 StH) t25(St1 StH) t31(Pu1 PuH) t32(Pu1 PuH) t33(Pu1 PuH) t34(Pu1 PuH) t35(Pu1 PuH) t41(We1 WeH) t42(We1 WeH) t43(We1 WeH) t44(We1 WeH) t45(We1 WeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 StH) t12(Su1 StH) t13(Su1 StH) t14(Su1 StH) t15(Su1 StH) t21(St1 StH) t22(St1 StH) t23(St1 StH) t24(St1 StH) t25(St1 StH) t31(Pu1 PuH) t32(Pu1 PuH) t33(Pu1 PuH) t34(Pu1 PuH) t35(Pu1 PuH) t41(We1 WeH) t42(We1 WeH) t43(We1 WeH) t44(We1 WeH) t45(We1 WeH) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 HiZ) t12(Su1 HiZ) t13(Su1 HiZ) t14(Su1 HiZ) t15(Su1 HiZ) t21(St1 HiZ) t22(St1 HiZ) t23(St1 HiZ) t24(St1 HiZ) t25(St1 HiZ) t31(Pu1 HiZ) t32(Pu1 HiZ) t33(Pu1 HiZ) t34(Pu1 HiZ) t35(Pu1 HiZ) t41(We1 HiZ) t42(We1 HiZ) t43(We1 HiZ) t44(We1 HiZ) t45(We1 HiZ) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = z en = 1 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 St1) t12(Su1 St1) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = x en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = x en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = x en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ SuX) t12(HiZ 67X) t13(HiZ 57X) t14(HiZ 37X) t15(HiZ SuH) t21(HiZ 76X) t22(HiZ StX) t23(HiZ 56X) t24(HiZ 36X) t25(HiZ StH) t31(HiZ 75X) t32(HiZ 65X) t33(HiZ PuX) t34(HiZ 35X) t35(HiZ PuH) t41(HiZ 73X) t42(HiZ 63X) t43(HiZ 53X) t44(HiZ WeX) t45(HiZ WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = z b = x en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StX SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(StX 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = x en = 1 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX SuX) t12(67X 67X) t13(57X 57X) t14(37X 37X) t15(SuH SuH) t21(76X 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X 75X) t32(65X 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH WeH) t51(SuL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = x en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 75X) t32(St0 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 75X) t32(St0 65X) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 SuX) t12(St0 67X) t13(Pu0 57X) t14(We0 37X) t15(HiZ SuH) t21(Su0 76X) t22(St0 StX) t23(Pu0 56X) t24(We0 36X) t25(HiZ StH) t31(Su0 75X) t32(St0 65X) t33(Pu0 PuX) t34(We0 35X) t35(HiZ PuH) t41(Su0 73X) t42(St0 63X) t43(Pu0 53X) t44(We0 WeX) t45(HiZ WeH) t51(Su0 SuL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = x en = 1 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 SuX) t12(StX 67X) t13(56X 57X) t14(36X 37X) t15(StH SuH) t21(Su0 76X) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(Su0 760) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(Su0 760) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(Su0 760) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = x en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(StX 76X) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 1 b = x en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(StX 76X) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 WeH) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 1 b = x en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 SuX) t12(Su1 67X) t13(Su1 57X) t14(Su1 37X) t15(Su1 SuH) t21(St1 76X) t22(St1 StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(Pu1 75X) t32(Pu1 65X) t33(Pu1 PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(We1 73X) t42(We1 63X) t43(We1 53X) t44(We1 WeX) t45(We1 WeH) t51(HiZ SuL) t52(HiZ StL) t53(HiZ PuL) t54(HiZ WeL) t55(HiZ HiZ) a = 1 b = x en = 1 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 SuX) t12(Su1 67X) t13(Su1 761) t14(Su1 761) t15(Su1 761) t21(StX 76X) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(65X 75X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(63X 73X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(StL SuL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = z b = 0 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StL Su0) t12(StL St0) t13(PuL Pu0) t14(WeL We0) t15(HiZ HiZ) t21(StL Su0) t22(StL St0) t23(PuL Pu0) t24(WeL We0) t25(HiZ HiZ) t31(StL Su0) t32(StL St0) t33(PuL Pu0) t34(WeL We0) t35(HiZ HiZ) t41(StL Su0) t42(StL St0) t43(PuL Pu0) t44(WeL We0) t45(HiZ HiZ) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = z b = 0 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StL Su0) t12(StL St0) t13(PuL Pu0) t14(WeL We0) t15(HiZ HiZ) t21(StL Su0) t22(StL St0) t23(PuL Pu0) t24(WeL We0) t25(HiZ HiZ) t31(StL Su0) t32(StL St0) t33(PuL Pu0) t34(WeL We0) t35(HiZ HiZ) t41(StL Su0) t42(StL St0) t43(PuL Pu0) t44(WeL We0) t45(HiZ HiZ) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = z b = 0 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su0) t12(HiZ St0) t13(HiZ Pu0) t14(HiZ We0) t15(HiZ HiZ) t21(HiZ Su0) t22(HiZ St0) t23(HiZ Pu0) t24(HiZ We0) t25(HiZ HiZ) t31(HiZ Su0) t32(HiZ St0) t33(HiZ Pu0) t34(HiZ We0) t35(HiZ HiZ) t41(HiZ Su0) t42(HiZ St0) t43(HiZ Pu0) t44(HiZ We0) t45(HiZ HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = z b = 0 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(St0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(St0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = x b = 0 en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X Su0) t32(65X St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(WeH WeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(75X Su0) t32(65X St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(WeH WeH) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su0) t12(67X St0) t13(57X Pu0) t14(37X We0) t15(SuH HiZ) t21(76X Su0) t22(StX St0) t23(56X Pu0) t24(36X We0) t25(StH HiZ) t31(75X Su0) t32(65X St0) t33(PuX Pu0) t34(35X We0) t35(PuH HiZ) t41(73X Su0) t42(63X St0) t43(53X Pu0) t44(WeX We0) t45(WeH HiZ) t51(SuL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = x b = 0 en = 1 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su0) t12(67X StX) t13(57X 56X) t14(37X 36X) t15(SuH StH) t21(76X Su0) t22(StX StX) t23(56X 56X) t24(36X 36X) t25(StH StH) t31(760 Su0) t32(St0 St0) t33(PuX PuX) t34(35X 35X) t35(PuH PuH) t41(760 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(WeH WeH) t51(760 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 0 b = 0 en = 1 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su0) t12(St0 St0) t13(Pu0 Pu0) t14(We0 We0) t15(HiZ HiZ) t21(Su0 Su0) t22(St0 St0) t23(Pu0 Pu0) t24(We0 We0) t25(HiZ HiZ) t31(Su0 Su0) t32(St0 St0) t33(Pu0 Pu0) t34(We0 We0) t35(HiZ HiZ) t41(Su0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(We0 We0) t45(HiZ HiZ) t51(Su0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 0 en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su0) t12(Su1 StX) t13(Su1 56X) t14(Su1 36X) t15(Su1 StH) t21(StX Su0) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X Su0) t32(65X St0) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(We1 WeH) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 1 b = 0 en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su0) t12(Su1 StX) t13(Su1 56X) t14(Su1 36X) t15(Su1 StH) t21(StX Su0) t22(StX StX) t23(St1 56X) t24(St1 36X) t25(St1 StH) t31(65X Su0) t32(65X St0) t33(PuX PuX) t34(Pu1 35X) t35(Pu1 PuH) t41(63X Su0) t42(63X St0) t43(53X Pu0) t44(WeX WeX) t45(We1 WeH) t51(StL Su0) t52(StL St0) t53(PuL Pu0) t54(WeL We0) t55(HiZ HiZ) a = 1 b = 0 en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su0) t12(Su1 St0) t13(Su1 Pu0) t14(Su1 We0) t15(Su1 HiZ) t21(St1 Su0) t22(St1 St0) t23(St1 Pu0) t24(St1 We0) t25(St1 HiZ) t31(Pu1 Su0) t32(Pu1 St0) t33(Pu1 Pu0) t34(Pu1 We0) t35(Pu1 HiZ) t41(We1 Su0) t42(We1 St0) t43(We1 Pu0) t44(We1 We0) t45(We1 HiZ) t51(HiZ Su0) t52(HiZ St0) t53(HiZ Pu0) t54(HiZ We0) t55(HiZ HiZ) a = 1 b = 0 en = 1 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su0) t12(Su1 StX) t13(Su1 St1) t14(Su1 St1) t15(Su1 St1) t21(StX Su0) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(St0 Su0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(St0 Su0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(St0 Su0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = z b = 1 en = z a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StH Su1) t12(StH Su1) t13(StH Su1) t14(StH Su1) t15(StH Su1) t21(StH St1) t22(StH St1) t23(StH St1) t24(StH St1) t25(StH St1) t31(PuH Pu1) t32(PuH Pu1) t33(PuH Pu1) t34(PuH Pu1) t35(PuH Pu1) t41(WeH We1) t42(WeH We1) t43(WeH We1) t44(WeH We1) t45(WeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = x a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(StH Su1) t12(StH Su1) t13(StH Su1) t14(StH Su1) t15(StH Su1) t21(StH St1) t22(StH St1) t23(StH St1) t24(StH St1) t25(StH St1) t31(PuH Pu1) t32(PuH Pu1) t33(PuH Pu1) t34(PuH Pu1) t35(PuH Pu1) t41(WeH We1) t42(WeH We1) t43(WeH We1) t44(WeH We1) t45(WeH We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 0 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(HiZ Su1) t12(HiZ Su1) t13(HiZ Su1) t14(HiZ Su1) t15(HiZ Su1) t21(HiZ St1) t22(HiZ St1) t23(HiZ St1) t24(HiZ St1) t25(HiZ St1) t31(HiZ Pu1) t32(HiZ Pu1) t33(HiZ Pu1) t34(HiZ Pu1) t35(HiZ Pu1) t41(HiZ We1) t42(HiZ We1) t43(HiZ We1) t44(HiZ We1) t45(HiZ We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = z b = 1 en = 1 a1(HiZ) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(St1 Su1) t12(St1 Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = x b = 1 en = z a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = 1 en = x a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(WeH We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = x b = 1 en = 0 a1(SuX) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(SuX Su1) t12(67X Su1) t13(57X Su1) t14(37X Su1) t15(SuH Su1) t21(76X St1) t22(StX St1) t23(56X St1) t24(36X St1) t25(StH St1) t31(75X Pu1) t32(65X Pu1) t33(PuX Pu1) t34(35X Pu1) t35(PuH Pu1) t41(73X We1) t42(63X We1) t43(53X We1) t44(WeX We1) t45(WeH We1) t51(SuL HiZ) t52(StL HiZ) t53(PuL HiZ) t54(WeL HiZ) t55(HiZ HiZ) a = x b = 1 en = 1 a1(SuX) a2(StX) a3(StX) a4(StX) a5(StX) a6(StX) a7(StX) t11(SuX Su1) t12(67X Su1) t13(761 Su1) t14(761 Su1) t15(761 Su1) t21(76X StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(75X 65X) t32(65X 65X) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(73X 63X) t42(63X 63X) t43(53X 53X) t44(WeX WeX) t45(We1 We1) t51(SuL StL) t52(StL StL) t53(PuL PuL) t54(WeL WeL) t55(HiZ HiZ) a = 0 b = 1 en = z a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su1) t12(StX Su1) t13(56X Su1) t14(36X Su1) t15(StH Su1) t21(Su0 StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(Su0 65X) t32(St0 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(Su0 63X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH We1) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = 1 en = x a1(Su0) a2(StL) a3(StL) a4(StL) a5(StL) a6(StL) a7(StL) t11(Su0 Su1) t12(StX Su1) t13(56X Su1) t14(36X Su1) t15(StH Su1) t21(Su0 StX) t22(StX StX) t23(56X St1) t24(36X St1) t25(StH St1) t31(Su0 65X) t32(St0 65X) t33(PuX PuX) t34(35X Pu1) t35(PuH Pu1) t41(Su0 63X) t42(St0 63X) t43(Pu0 53X) t44(WeX WeX) t45(WeH We1) t51(Su0 StL) t52(St0 StL) t53(Pu0 PuL) t54(We0 WeL) t55(HiZ HiZ) a = 0 b = 1 en = 0 a1(Su0) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su0 Su1) t12(St0 Su1) t13(Pu0 Su1) t14(We0 Su1) t15(HiZ Su1) t21(Su0 St1) t22(St0 St1) t23(Pu0 St1) t24(We0 St1) t25(HiZ St1) t31(Su0 Pu1) t32(St0 Pu1) t33(Pu0 Pu1) t34(We0 Pu1) t35(HiZ Pu1) t41(Su0 We1) t42(St0 We1) t43(Pu0 We1) t44(We0 We1) t45(HiZ We1) t51(Su0 HiZ) t52(St0 HiZ) t53(Pu0 HiZ) t54(We0 HiZ) t55(HiZ HiZ) a = 0 b = 1 en = 1 a1(Su0) a2(St0) a3(St0) a4(St0) a5(St0) a6(St0) a7(St0) t11(Su0 Su1) t12(StX Su1) t13(St1 Su1) t14(St1 Su1) t15(St1 Su1) t21(Su0 StX) t22(StX StX) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Su0 St0) t32(St0 St0) t33(PuX PuX) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(Su0 St0) t42(St0 St0) t43(Pu0 Pu0) t44(WeX WeX) t45(We1 We1) t51(Su0 St0) t52(St0 St0) t53(Pu0 Pu0) t54(We0 We0) t55(HiZ HiZ) a = 1 b = 1 en = z a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = x a1(Su1) a2(StH) a3(StH) a4(StH) a5(StH) a6(StH) a7(StH) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 0 a1(Su1) a2(HiZ) a3(HiZ) a4(HiZ) a5(HiZ) a6(HiZ) a7(HiZ) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) a = 1 b = 1 en = 1 a1(Su1) a2(St1) a3(St1) a4(St1) a5(St1) a6(St1) a7(St1) t11(Su1 Su1) t12(Su1 Su1) t13(Su1 Su1) t14(Su1 Su1) t15(Su1 Su1) t21(St1 St1) t22(St1 St1) t23(St1 St1) t24(St1 St1) t25(St1 St1) t31(Pu1 Pu1) t32(Pu1 Pu1) t33(Pu1 Pu1) t34(Pu1 Pu1) t35(Pu1 Pu1) t41(We1 We1) t42(We1 We1) t43(We1 We1) t44(We1 We1) t45(We1 We1) t51(HiZ HiZ) t52(HiZ HiZ) t53(HiZ HiZ) t54(HiZ HiZ) t55(HiZ HiZ) iverilog-12_0/ivtest/gold/two_state_display.gold000066400000000000000000000013731435245347300222230ustar00rootroot00000000000000Vec: 9 Bit: 0 Byte: 0 Short: 0 Int: 0 Long: 0 Monitor results: Time: 0 Bit: 0 Byte: 0 Short: 0 Int: 0 Long: 0 Time: 1 Bit: 1 Byte: 0 Short: 0 Int: 0 Long: 0 Time: 2 Bit: 1 Byte: 1 Short: 0 Int: 0 Long: 0 Time: 3 Bit: 1 Byte: 1 Short: 1 Int: 0 Long: 0 Time: 4 Bit: 1 Byte: 1 Short: 1 Int: 1 Long: 0 Time: 5 Bit: 1 Byte: 1 Short: 1 Int: 1 Long: 1 iverilog-12_0/ivtest/gold/udp_bx.gold000066400000000000000000000003741435245347300177460ustar00rootroot00000000000000 0 CL = 0, D = 1, Q = 0 10 CL = x, D = 1, Q = x 20 CL = 0, D = 1, Q = 0 30 CL = x, D = 1, Q = x 40 CL = 1, D = 1, Q = x 50 CL = 1, D = 1, Q = 1 iverilog-12_0/ivtest/gold/undef.gold000066400000000000000000000001331435245347300175570ustar00rootroot00000000000000./ivltests/undef.v:23: warning: macro a undefined (and assumed null) at this point. PASSED iverilog-12_0/ivtest/gold/unnamed_generate_block.gold000066400000000000000000000000101435245347300231230ustar00rootroot000000000000000 1 2 3 iverilog-12_0/ivtest/gold/urand.gold000066400000000000000000000024761435245347300176030ustar00rootroot00000000000000 0 0 2450863396 2450863396 1082744449 1082744449 75814409 75814409 837834339 837834339 2260302605 2260302605 3336542605 3336542605 851608677 851608677 154620434 154620434 2163467009 2163467009 2262289677 2262289677 3139694966 3139694966 2660093245 2660093245 4141111277 4141111277 3324901260 3324901260 4244498937 4244498937 1664558278 1664558278 1660388549 1660388549 1427362474 1427362474 4071618533 4071618533 1003647607 1003647607 154326546 154326546 3354188687 3354188687 4180699634 4180699634 1735825102 1735825102 1946188520 1946188520 1657425605 1657425605 2925021532 2925021532 1586374845 1586374845 380327981 380327981 849815141 849815141 837771875 837771875 2238940938 2238940938 1077617280 1077617280 2422481184 2422481184 3581429162 3581429162 1322044573 1322044573 1260404374 1260404374 159627283 159627283 112998413 112998413 698865235 698865235 3047153003 3047153003 1789274837 1789274837 18303490 18303490 1465269934 1465269934 2399136029 2399136029 1740993231 1740993231 2441365795 2441365795 2231985418 2231985418 1702038218 1702038218 506547260 506547260 4184391154 4184391154 3308151178 3308151178 2697245505 2697245505 1816868056 1816868056 3156276088 3156276088 1149899401 1149899401 4123332075 4123332075 3674367414 3674367414 3813407174 3813407174 3608482734 3608482734 iverilog-12_0/ivtest/gold/urand_r.gold000066400000000000000000000011631435245347300201140ustar00rootroot00000000000000 0 9 4 0 3 8 13 3 0 8 12 10 16 13 16 6 5 16 3 0 13 16 6 7 6 11 6 1 3 8 4 9 14 5 4 0 2 12 7 0 5 9 6 9 8 6 2 16 13 10 7 12 4 16 14 15 14 iverilog-12_0/ivtest/gold/uwire_fail.gold000066400000000000000000000001701435245347300206050ustar00rootroot00000000000000./ivltests/uwire_fail.v:5: error: Unresolved net/uwire two cannot have multiple drivers. 1 error(s) during elaboration. iverilog-12_0/ivtest/gold/vcd-dup.log.gold000066400000000000000000000003761435245347300206110ustar00rootroot00000000000000VCD info: dumpfile work/vcd-dup.vcd opened for output. VCD warning: skipping signal test.m2.c1, it was previously included. VCD warning: ignoring signals in previously scanned scope test.m1. VCD warning: $dumpvars ignored, previously called at simtime 0 iverilog-12_0/ivtest/gold/vcd-dup.vcd.gold000066400000000000000000000030271435245347300206000ustar00rootroot00000000000000$date Sun May 15 15:15:18 2022 $end $version Icarus Verilog $end $timescale 1s $end $scope module test $end $var wire 1 ! c2 $end $var wire 1 " c1 $end $var reg 1 # a $end $var reg 1 $ b1 $end $var reg 1 % b2 $end $scope module m1 $end $var wire 1 # a $end $var wire 1 $ b $end $var wire 1 " c $end $var wire 1 & c2 $end $var wire 1 ' c1 $end $upscope $end $scope module m2 $end $var wire 1 # a $end $var wire 1 % b $end $var wire 1 ! c $end $var wire 1 ( c2 $end $var wire 1 ) c1 $end $upscope $end $scope task set $end $var reg 3 * bits [2:0] $end $var reg 1 + t1 $end $upscope $end $upscope $end $scope module test $end $scope module m1 $end $scope module mm1 $end $var wire 1 , c1 $end $upscope $end $upscope $end $upscope $end $scope module test $end $scope module m1 $end $scope module mm1 $end $var wire 1 - a $end $var wire 1 ' c $end $upscope $end $scope module mm2 $end $var wire 1 . a $end $var wire 1 & c $end $var wire 1 / c1 $end $upscope $end $upscope $end $upscope $end $enddefinitions $end $comment Show the parameter values. $end $dumpall $end #0 $dumpvars x/ x. 0- 1, x+ bx * 1) x( 1' x& x% x$ 0# x" x! $end #1 0+ b0 * #2 0" 0! 1& 1/ 1( 0. 0$ 0% #4 b1 * #5 1! 0( 1% #7 b10 * #8 1" 0! 0& 0/ 1( 1. 1$ 0% #9 $dumpoff x/ x. x- x, x+ bx * x) x( x' x& x% x$ x# x" x! $end #15 $dumpon 0/ 1. 0- 1, 0+ b100 * 1) 0( 1' 0& 0% 0$ 1# 1" 1! $end #16 1+ b101 * #17 0! 0) 1% #19 b110 * #20 0" 1! 0' 0, 1) 1- 1$ 0% #22 b111 * #23 0! 0) 1% #25 b0 * #26 1' 1, 1& 1/ 1) 1( 0- 0. 0# 0$ 0% #27 $dumpall 1/ 0. 0- 1, 1+ b0 * 1) 1( 1' 1& 0% 0$ 0# 0" 0! $end #28 iverilog-12_0/ivtest/gold/vector.gold000066400000000000000000000031621435245347300177650ustar00rootroot00000000000000foo40= 0 foo04= 0 foo51= 0 foo15= 0 foo40= 1 foo04= 1 foo51= 1 foo15= 1 foo40= 2 foo04= 2 foo51= 2 foo15= 2 foo40= 3 foo04= 3 foo51= 3 foo15= 3 foo40= 4 foo04= 4 foo51= 4 foo15= 4 foo40= 5 foo04= 5 foo51= 5 foo15= 5 foo40= 6 foo04= 6 foo51= 6 foo15= 6 foo40= 7 foo04= 7 foo51= 7 foo15= 7 foo40= 8 foo04= 8 foo51= 8 foo15= 8 foo40= 9 foo04= 9 foo51= 9 foo15= 9 foo40= 10 foo04= 10 foo51= 10 foo15= 10 iverilog-12_0/ivtest/gold/vhdl_concurrent_assert.gold000066400000000000000000000001161435245347300232370ustar00rootroot00000000000000** Note: this assert should be fired (ivltests/vhdl_concurrent_assert.vhd:32) iverilog-12_0/ivtest/gold/vhdl_image_attr.gold000066400000000000000000000004171435245347300216140ustar00rootroot00000000000000** Note: integer'image test: 10 (ivltests/vhdl_image_attr.vhd:38) ** Note: real'image test: 12.340000 (ivltests/vhdl_image_attr.vhd:39) ** Note: character'image test: 'o' (ivltests/vhdl_image_attr.vhd:40) ** Note: time'image test: 10 ns (ivltests/vhdl_image_attr.vhd:41) iverilog-12_0/ivtest/gold/vhdl_lfcr.gold000066400000000000000000000001021435245347300204150ustar00rootroot00000000000000** Note: first line after LFrafter CR (ivltests/vhdl_lfcr.vhd:32) iverilog-12_0/ivtest/gold/vhdl_mux2.gold000066400000000000000000000000061435245347300203650ustar00rootroot000000000000001 0 1 iverilog-12_0/ivtest/gold/vhdl_now.gold000066400000000000000000000002601435245347300202770ustar00rootroot00000000000000** Note: reporting sim time: 5 (ivltests/vhdl_now.vhd:34) ** Note: reporting sim time: 15 (ivltests/vhdl_now.vhd:34) ** Note: reporting sim time: 25 (ivltests/vhdl_now.vhd:34) iverilog-12_0/ivtest/gold/vhdl_procedure.gold000066400000000000000000000006501435245347300214670ustar00rootroot00000000000000** Note: before rising_edge (ivltests/vhdl_procedure.vhd:38) ** Note: after rising_edge (ivltests/vhdl_procedure.vhd:44) ** Note: before rising_edge (ivltests/vhdl_procedure.vhd:38) ** Note: after rising_edge (ivltests/vhdl_procedure.vhd:44) ** Note: before rising_edge (ivltests/vhdl_procedure.vhd:38) ** Note: Procedure executed (ivltests/vhdl_procedure.vhd:33) ** Note: after rising_edge (ivltests/vhdl_procedure.vhd:44) iverilog-12_0/ivtest/gold/vhdl_report.gold000066400000000000000000000012271435245347300210130ustar00rootroot00000000000000** Error: procedure 1 (ivltests/vhdl_report_pkg.vhd:35) ** Error: Assertion violation. (ivltests/vhdl_report_pkg.vhd:38) ** Note: procedure 2 (ivltests/vhdl_report_pkg.vhd:40) ** Note: Assertion violation. (ivltests/vhdl_report_pkg.vhd:43) ** Warning: procedure 3 (ivltests/vhdl_report_pkg.vhd:46) ** Note: normal report (ivltests/vhdl_report.vhd:36) ** Error: report with severity (ivltests/vhdl_report.vhd:40) ** Error: Assertion violation. (ivltests/vhdl_report.vhd:44) ** Note: assert with report (ivltests/vhdl_report.vhd:47) ** Note: Assertion violation. (ivltests/vhdl_report.vhd:52) ** Failure: assert with report & severity (ivltests/vhdl_report.vhd:56) iverilog-12_0/ivtest/gold/vhdl_string.gold000066400000000000000000000005361435245347300210100ustar00rootroot00000000000000** Note: (ivltests/vhdl_string.vhd:34) ** Note: " (ivltests/vhdl_string.vhd:35) ** Note: test (ivltests/vhdl_string.vhd:36) ** Note: VHDL (ivltests/vhdl_string.vhd:37) ** Note: brackets test (ivltests/vhdl_string.vhd:39) ** Note: multiple brackets test (ivltests/vhdl_string.vhd:40) ** Note: "quotation " marks " test" (ivltests/vhdl_string.vhd:41) iverilog-12_0/ivtest/gold/vhdl_test3.gold000066400000000000000000000012061435245347300205370ustar00rootroot00000000000000input = 0000, output=0000000000000001 input = 0001, output=0000000000000010 input = 0010, output=0000000000000011 input = 0011, output=0000000000000100 input = 0100, output=0000000000000101 input = 0101, output=0000000000000110 input = 0110, output=0000000000000111 input = 0111, output=0000000000001000 input = 1000, output=0000000000001001 input = 1001, output=0000000000001010 input = 1010, output=0000000000001011 input = 1011, output=0000000000001100 input = 1100, output=0000000000001101 input = 1101, output=0000000000001110 input = 1110, output=0000000000001111 input = 1111, output=0000000000010000 input = 0000, output=0000000000000001 iverilog-12_0/ivtest/gold/vhdl_time.gold000066400000000000000000000005071435245347300204360ustar00rootroot00000000000000 140 a changed at 0 a changed at 50 a changed at 550 a changed at 750 a changed at 850 a changed at 1650 a changed at 1660 a changed at 1680 a changed at 1780 iverilog-12_0/ivtest/gold/vhdl_wait.gold000066400000000000000000000001771435245347300204470ustar00rootroot00000000000000** Note: final wait test (ivltests/vhdl_wait.vhd:33) ** Note: wait 1 completed (ivltests/vhdl_wait.vhd:39) wait 1 acknowledged iverilog-12_0/ivtest/gold/wait3.gold000066400000000000000000000002411435245347300175050ustar00rootroot00000000000000starting 0 x0 100 00 200 10 201 11 301 01 302 00 timeout iverilog-12_0/ivtest/gold/warn_opt_sys_tf-vlog95.gold000066400000000000000000000020431435245347300230230ustar00rootroot00000000000000SORRY: vlog95.v:14: $getpattern() is not available in Icarus Verilog. SORRY: vlog95.v:15: $input() is not available in Icarus Verilog. SORRY: vlog95.v:16: $key() is not available in Icarus Verilog. SORRY: vlog95.v:17: $nokey() is not available in Icarus Verilog. SORRY: vlog95.v:18: $list() is not available in Icarus Verilog. SORRY: vlog95.v:19: $log() is not available in Icarus Verilog. SORRY: vlog95.v:20: $nolog() is not available in Icarus Verilog. SORRY: vlog95.v:21: $save() is not available in Icarus Verilog. SORRY: vlog95.v:22: $restart() is not available in Icarus Verilog. SORRY: vlog95.v:23: $incsave() is not available in Icarus Verilog. SORRY: vlog95.v:24: $scale() is not available in Icarus Verilog. SORRY: vlog95.v:25: $scope() is not available in Icarus Verilog. SORRY: vlog95.v:26: $showscopes() is not available in Icarus Verilog. SORRY: vlog95.v:27: $showvars() is not available in Icarus Verilog. SORRY: vlog95.v:28: $sreadmemb() is not available in Icarus Verilog. SORRY: vlog95.v:29: $sreadmemh() is not available in Icarus Verilog. iverilog-12_0/ivtest/gold/warn_opt_sys_tf.gold000066400000000000000000000025401435245347300217020ustar00rootroot00000000000000SORRY: ./ivltests/warn_opt_sys_tf.v:7: $getpattern() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:8: $input() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:9: $key() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:10: $nokey() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:11: $list() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:12: $log() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:13: $nolog() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:14: $save() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:15: $restart() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:16: $incsave() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:17: $scale() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:18: $scope() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:19: $showscopes() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:20: $showvars() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:21: $sreadmemb() is not available in Icarus Verilog. SORRY: ./ivltests/warn_opt_sys_tf.v:22: $sreadmemh() is not available in Icarus Verilog. iverilog-12_0/ivtest/gold/wild_cmp_err.gold000066400000000000000000000005471435245347300211350ustar00rootroot00000000000000./ivltests/wild_cmp_err.v:2: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err.v:3: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err.v:4: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err.v:5: error: !=? operator may only have INTEGRAL operands. 4 error(s) during elaboration. iverilog-12_0/ivtest/gold/wild_cmp_err2.gold000066400000000000000000000037061435245347300212170ustar00rootroot00000000000000./ivltests/wild_cmp_err2.v:9: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:9: error: Unable to elaborate r-value: (rl)w(rv) ./ivltests/wild_cmp_err2.v:10: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:10: error: Unable to elaborate r-value: (lv)w(rl) ./ivltests/wild_cmp_err2.v:11: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:11: error: Unable to elaborate r-value: (rl)W(rv) ./ivltests/wild_cmp_err2.v:12: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:12: error: Unable to elaborate r-value: (lv)W(rl) ./ivltests/wild_cmp_err2.v:13: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:13: error: Unable to elaborate r-value: (st)w(rv) ./ivltests/wild_cmp_err2.v:14: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:14: error: Unable to elaborate r-value: (lv)w(st) ./ivltests/wild_cmp_err2.v:15: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:15: error: Unable to elaborate r-value: (st)W(rv) ./ivltests/wild_cmp_err2.v:16: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:16: error: Unable to elaborate r-value: (lv)W(st) ./ivltests/wild_cmp_err2.v:19: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:20: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:21: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:22: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:23: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:24: error: ==? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:25: error: !=? operator may only have INTEGRAL operands. ./ivltests/wild_cmp_err2.v:26: error: !=? operator may only have INTEGRAL operands. 24 error(s) during elaboration. iverilog-12_0/ivtest/gold/wiresl2.gold000066400000000000000000000000701435245347300200450ustar00rootroot00000000000000out=01 out=02 out=04 out=08 out=10 out=20 out=40 out=80 iverilog-12_0/ivtest/gold/writemem-error-vlog95.gold000066400000000000000000000033021435245347300225620ustar00rootroot00000000000000WARNING: vlog95.v:22: $writememb's file name argument (vpiReg) is not a valid string. WARNING: vlog95.v:23: $writememb's file name argument (vpiIntegerVar) is not a valid string. WARNING: vlog95.v:30: $writememb's file name argument contains non-printable characters. "work/writemem.tx\002" WARNING: vlog95.v:33: $writememb's third argument (start address) is a real value. WARNING: vlog95.v:38: $writememb's fourth argument (finish address) is a real value. ERROR: vlog95.v:42: $writememb: Start address -1 is out of bounds for memory 'top.check[0:7]'! ERROR: vlog95.v:46: $writememb: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: vlog95.v:50: $writememb: Finish address 8 is out of bounds for memory 'top.check[0:7]'! ERROR: vlog95.v:54: $writememb: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: vlog95.v:63: $writememh's file name argument (vpiReg) is not a valid string. WARNING: vlog95.v:64: $writememh's file name argument (vpiIntegerVar) is not a valid string. WARNING: vlog95.v:71: $writememh's file name argument contains non-printable characters. "work/writemem.tx\002" WARNING: vlog95.v:74: $writememh's third argument (start address) is a real value. WARNING: vlog95.v:79: $writememh's fourth argument (finish address) is a real value. ERROR: vlog95.v:83: $writememh: Start address -1 is out of bounds for memory 'top.check[0:7]'! ERROR: vlog95.v:87: $writememh: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: vlog95.v:91: $writememh: Finish address 8 is out of bounds for memory 'top.check[0:7]'! ERROR: vlog95.v:95: $writememh: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! iverilog-12_0/ivtest/gold/writemem-error.gold000066400000000000000000000041101435245347300214350ustar00rootroot00000000000000WARNING: ./ivltests/writemem-error.v:15: $writememb's file name argument (vpiReg) is not a valid string. WARNING: ./ivltests/writemem-error.v:16: $writememb's file name argument (vpiIntegerVar) is not a valid string. WARNING: ./ivltests/writemem-error.v:32: $writememb's file name argument contains non-printable characters. "work/writemem.tx\002" WARNING: ./ivltests/writemem-error.v:37: $writememb's third argument (start address) is a real value. WARNING: ./ivltests/writemem-error.v:49: $writememb's fourth argument (finish address) is a real value. ERROR: ./ivltests/writemem-error.v:60: $writememb: Start address -1 is out of bounds for memory 'top.check[0:7]'! ERROR: ./ivltests/writemem-error.v:70: $writememb: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: ./ivltests/writemem-error.v:80: $writememb: Finish address 8 is out of bounds for memory 'top.check[0:7]'! ERROR: ./ivltests/writemem-error.v:90: $writememb: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! WARNING: ./ivltests/writemem-error.v:117: $writememh's file name argument (vpiReg) is not a valid string. WARNING: ./ivltests/writemem-error.v:118: $writememh's file name argument (vpiIntegerVar) is not a valid string. WARNING: ./ivltests/writemem-error.v:134: $writememh's file name argument contains non-printable characters. "work/writemem.tx\002" WARNING: ./ivltests/writemem-error.v:139: $writememh's third argument (start address) is a real value. WARNING: ./ivltests/writemem-error.v:151: $writememh's fourth argument (finish address) is a real value. ERROR: ./ivltests/writemem-error.v:162: $writememh: Start address -1 is out of bounds for memory 'top.check[0:7]'! ERROR: ./ivltests/writemem-error.v:172: $writememh: Start address 7 is out of bounds for memory 'top.array2[8:15]'! ERROR: ./ivltests/writemem-error.v:182: $writememh: Finish address 8 is out of bounds for memory 'top.check[0:7]'! ERROR: ./ivltests/writemem-error.v:192: $writememh: Finish address 16 is out of bounds for memory 'top.array2[8:15]'! iverilog-12_0/ivtest/gold/writemem-invalid-vlog95.gold000066400000000000000000000023021435245347300230560ustar00rootroot00000000000000ERROR: vlog95.v:14: $writememb requires two arguments. ERROR: vlog95.v:15: $writememb's first argument must be a file name (string). ERROR: vlog95.v:15: $writememb requires a second (memory) argument. ERROR: vlog95.v:16: $writememb requires a second (memory) argument. ERROR: vlog95.v:17: $writememb's second argument must be a memory. ERROR: vlog95.v:18: $writememb's third argument must be a start address (numeric). ERROR: vlog95.v:19: $writememb's fourth argument must be a finish address (numeric). ERROR: vlog95.v:20: $writememb takes at most four arguments. Found 1 extra argument. ERROR: vlog95.v:21: $writememh requires two arguments. ERROR: vlog95.v:22: $writememh's first argument must be a file name (string). ERROR: vlog95.v:22: $writememh requires a second (memory) argument. ERROR: vlog95.v:23: $writememh requires a second (memory) argument. ERROR: vlog95.v:24: $writememh's second argument must be a memory. ERROR: vlog95.v:25: $writememh's third argument must be a start address (numeric). ERROR: vlog95.v:26: $writememh's fourth argument must be a finish address (numeric). ERROR: vlog95.v:27: $writememh takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/gold/writemem-invalid.gold000066400000000000000000000030661435245347300217430ustar00rootroot00000000000000ERROR: ./ivltests/writemem-invalid.v:5: $writememb requires two arguments. ERROR: ./ivltests/writemem-invalid.v:6: $writememb's first argument must be a file name (string). ERROR: ./ivltests/writemem-invalid.v:6: $writememb requires a second (memory) argument. ERROR: ./ivltests/writemem-invalid.v:7: $writememb requires a second (memory) argument. ERROR: ./ivltests/writemem-invalid.v:8: $writememb's second argument must be a memory. ERROR: ./ivltests/writemem-invalid.v:9: $writememb's third argument must be a start address (numeric). ERROR: ./ivltests/writemem-invalid.v:10: $writememb's fourth argument must be a finish address (numeric). ERROR: ./ivltests/writemem-invalid.v:11: $writememb takes at most four arguments. Found 1 extra argument. ERROR: ./ivltests/writemem-invalid.v:13: $writememh requires two arguments. ERROR: ./ivltests/writemem-invalid.v:14: $writememh's first argument must be a file name (string). ERROR: ./ivltests/writemem-invalid.v:14: $writememh requires a second (memory) argument. ERROR: ./ivltests/writemem-invalid.v:15: $writememh requires a second (memory) argument. ERROR: ./ivltests/writemem-invalid.v:16: $writememh's second argument must be a memory. ERROR: ./ivltests/writemem-invalid.v:17: $writememh's third argument must be a start address (numeric). ERROR: ./ivltests/writemem-invalid.v:18: $writememh's fourth argument must be a finish address (numeric). ERROR: ./ivltests/writemem-invalid.v:19: $writememh takes at most four arguments. Found 1 extra argument. iverilog-12_0/ivtest/ivltests/000077500000000000000000000000001435245347300165425ustar00rootroot00000000000000iverilog-12_0/ivtest/ivltests/abstime.v000066400000000000000000000015751435245347300203650ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass; real result; initial begin pass = 1'b1; result = $abstime; if (result != 0.0) begin $display("FAILED at time 0, expected 0.0, got %g", result); pass = 1'b0; end #10; result = $abstime; if ($abs(result-10e-9) > result*1e-9) begin $display("FAILED at time 10ns, expected 1e-8, got %g", result); pass = 1'b0; end #999990; result = $abstime; if ($abs(result-0.001) > result*1e-9) begin $display("FAILED at time 1ms, expected 0.001, got %g", result); pass = 1'b0; end `ifdef __ICARUS_UNSIZED__ #9999000000; `else #9999000000.0; `endif result = $abstime; if ($abs(result-10.0) > result*1e-9) begin $display("FAILED at time 10s, expected 10.0, got %g", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/addsr.v000066400000000000000000000023451435245347300200320ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test caught a problem with the addition with different size * operands was an operand of the shift. */ module main; reg [3:0] a; reg [4:0] result, b; initial begin a = 5; b = 6; result = (a + b) >> 1; if (result !== 5) begin $display("FAILED: result === %b", result); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/addwide.v000066400000000000000000000016411435245347300203340ustar00rootroot00000000000000// (c) Alex.Perry@qm.com - 2002, Quantum Magnetics Inc, San Diego CA // This source file is licensed under the GNU public license version 2.0 // All other rights reserved. // NOTE: This test catches addition of wide (>16 bits) constants // to wide vectors. -- Steve Williams module source ( C, h ); output [ 0:0] C; output [11:0] h; reg [ 0:0] C; reg [11:0] h; reg [21:0] l; parameter kh = 3; parameter kl = 21'd364066; parameter wl = 21'h100000; initial #5 begin C <= 0; l <= 0; h <= 0; end always #10 C = ~C; always @(posedge C) begin if ( l >= wl ) begin l <= l + kl - wl; h <= h + kh + 1; end else begin l <= l + kl; h <= h + kh; end end endmodule module bench; wire [ 0:0] clock; wire [11:0] h; source dut ( .C(clock), .h(h) ); initial #85 begin if ( h == 13 ) begin $display ( "%7d", h ); $display ("PASSED"); end else begin $display ( "%7d = FAIL", h ); end $finish; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.10A.v000066400000000000000000000021321435245347300207710ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always event_trigger ; module main ; event one_event ; always @(one_event) begin # 1; $display("saw event"); end initial begin #1 ; #1 ; #1 ; $finish ; end always -> one_event ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.11A.v000066400000000000000000000026171435245347300210020ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always begin some_statements ; end module main ; reg [3:0] value1,value2,value3; always begin #5 ; value1 = 1; end initial begin value1 = 0; value2 = 0; if(value1 != 0) begin $display("FAILED - 3.1.11A always begin statement end"); value2 = 1; end #6; if(value1 != 1) begin $display("FAILED - 3.1.11A always begin statement end"); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.11B.v000066400000000000000000000030021435245347300207700ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always begin : id block_defines some_statements ; end module main ; reg [3:0] value1,value2,value3; always begin : block_id reg [3:0] value4 ; value4 = 1; #5 ; value1 = value4; end initial begin value1 = 0; value2 = 0; if(value1 != 0) begin $display("FAILED - 3.1.11B always begin : id defines statement end"); value2 = 1; end #6; if(value1 != 1) begin $display("FAILED - 3.1.11B always begin : id defines statement end"); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.12A.v000066400000000000000000000032621435245347300210000ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always fork parallel_statements join module main ; reg [3:0] value1,value2,value3; always fork #5 value1 = 1 ; #8 value1 = 2; join initial begin value1 = 0; value2 = 0; #4 ; if(value1 != 0) begin $display("FAILED - 3.1.12A always fork statements join (0)"); value2 = 1; end #2 ; if(value1 != 1) begin $display("FAILED - 3.1.12A always fork statements join (1)"); value2 = 1; end #3 ; if(value1 != 2) begin $display("FAILED - 3.1.12A always fork statements join (2)"); value2 = 1; end #5 ; if(value1 != 1) begin $display("FAILED - 3.1.12A always fork statements join (3)"); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.12B.v000066400000000000000000000033271435245347300210030ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always fork : id parallel_statements join module main ; reg [3:0] value1,value2,value3; always fork : fork_id #5 value1 = 1 ; #10 value1 = 2; join initial begin value1 = 0; value2 = 0; #4 ; if(value1 != 0) begin $display("FAILED - 3.1.12B always fork : id statements join (0)"); value2 = 1; end #2 ; if(value1 != 1) begin $display("FAILED - 3.1.12B always fork : id statements join (1)"); value2 = 1; end #5 ; if(value1 != 2) begin $display("FAILED - 3.1.12B always fork : id statements join (2)"); value2 = 1; end #5 ; if(value1 != 1) begin $display("FAILED - 3.1.12B always fork : id statements join (3)"); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.12C.v000066400000000000000000000035721435245347300210060ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always fork : id block_decl parallel_statements join module main ; reg [3:0] value1,value2,value3; always fork : fork_id reg [3:0] value4 ; #5 begin value4 = 0; value1 = value4 + 1 ; end #10 value1 = value4 + 2; join initial begin value1 = 0; value2 = 0; #4 ; if(value1 != 0) begin $display("FAILED - 3.1.12C always fork : id block_decl statements join (0)"); value2 = 1; end #2 ; if(value1 != 1) begin $display("FAILED - 3.1.12C always fork : id block_decl statements join (1)"); value2 = 1; end #5 ; if(value1 != 2) begin $display("FAILED - 3.1.12C always fork : id block_decl statements join (2)"); value2 = 1; end #5 ; if(value1 != 1) begin $display("FAILED - 3.1.12C always fork : id block_decl statements join (3)"); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.1A.v000066400000000000000000000023431435245347300207150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always 3.1.1A always reg_lvalue = constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; always begin #0; #0; #0; end always value1 = 4'h5 ; initial if(value1 != 4'h5) $display("FAILED - 3.1.1A always reg_lvalue = constant\n"); else begin $display("PASSED\n"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.1B.v000066400000000000000000000023201435245347300207110ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always 3.1.1B always reg_lvalue = boolean_expression ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'b1) $display("FAILED - 3.1.1B always reg_lvalue = boolean_expression\n"); else begin $display("PASSED\n"); $finish; end always value1 = 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1C.v000066400000000000000000000025121435245347300207150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate 3.1.1C always reg_lvalue = # delay_value constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # delay_value constant"); #15 ; if(value1 !== 4'h5) $display("FAILED - always reg_lvalue = # delay_value constant"); else begin $display("PASSED\n"); $finish ; end end always value1 = # 10 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1D.v000066400000000000000000000025421435245347300207210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = # delay_value boolean_expression // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # delay_value boolean_expression\n"); #15 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue = # delay_value boolean_expression\n"); else begin $display("PASSED\n"); $finish ; end end always value1 = # 10 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1E.v000066400000000000000000000026571435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = # (mintypmax_expression) constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 3; /* Wait till here to verify didn't see 2ns delay! */ if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # (mintypmax_expression) constant \n"); #12 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue = # (mintypmax_expression) constant \n"); else begin $display("PASSED\n"); $finish ; end end always value1 = # (2:10:17) 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1F.v000066400000000000000000000027001435245347300207170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = # (mintypmax_expression) boolean_exp ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 3; /* Wait till here to verify didn't see 2ns delay! */ if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # (mintypmax_expression) boolean_exp \n"); #12 ; if(value1 != 4'b1) $display("FAILED - always reg_lvalue = # (mintypmax_expression) boolean_exp \n"); else begin $display("PASSED\n"); $finish ; end end always value1 = # (2:10:17) 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1G.v000066400000000000000000000026441435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = @ event_identifier constant // D: There is a dependency here between this and event keyword and -> module main ; reg [3:0] value1 ; event event_ident ; initial begin # 5 -> event_ident ; end initial begin if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue = @ event_identifier constant\n"); #10 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue = @ event_identifier constant\n"); else begin $display("PASSED\n"); $finish ; end end always value1 = @ event_ident 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1H.v000066400000000000000000000027131435245347300207250ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = @ event_identifier boolean_expression // D: There is a dependency here between this and event keyword and -> module main ; reg [3:0] value1 ; event event_ident ; initial begin # 5 -> event_ident ; end initial begin if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue = @ event_identifier boolean_expression\n"); #10 ; if(value1 != 4'b1) $display("FAILED - always reg_lvalue = @ event_identifier boolean_expression\n"); else begin $display("PASSED\n"); $finish ; end end always value1 = @ event_ident 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1I.v000066400000000000000000000032471435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = @ (event_expression) constant // module main ; reg [3:0] value1 ; reg event_var ; initial begin # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b0 ; # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b1 ; #5 ; end initial begin // Should be xxxx at initial time if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue = @ (event_expression) constant \n"); # 6 ; if(value1 != 4'h5) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue = @ event_identifier boolean_expression\n"); # 5 ; if(value1 != 4'h5) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue = @ event_identifier boolean_expression\n"); begin $display("PASSED\n"); $finish ; end end always value1 = @ (event_var) 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1J.v000066400000000000000000000032611435245347300207260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = @ (event_expression) boolean_expr // module main ; reg [3:0] value1 ; reg event_var ; initial begin # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b0 ; # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b1 ; #5 ; end initial begin // Should be xxxx at initial time if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue = @ (event_expression) boolean_expr\n"); # 6 ; if(value1 != 4'h1) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue = @ (event_expression) boolean_expr\n"); # 5 ; if(value1 != 4'h1) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue = @ (event_expression) boolean_expr\n"); begin $display("PASSED\n"); $finish ; end end always value1 = @ (event_var) 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.1K.v000066400000000000000000000026631435245347300207340ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue = @ event_identifier constant // D: There is a dependency here between this and event keyword and -> module main ; reg [3:0] value1 ; event event_ident ; initial begin # 5 -> event_ident ; end initial begin if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue = @ event_identifier constant\n"); #10 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue = @ event_identifier constant\n"); else begin $display("PASSED\n"); $finish ; end end always value1 = repeat ( 5 ) @ event_ident 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2A.v000066400000000000000000000022661435245347300207220ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always 3.1.2A always reg_lvalue <= constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'h5) $display("FAILED - 3.1.2A always reg_lvalue = constant\n"); else begin $display("PASSED\n"); $finish; end always value1 <= 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2B.v000066400000000000000000000023221435245347300207140ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always 3.1.2B always reg_lvalue <= boolean_expression ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'b1) $display("FAILED - 3.1.2B always reg_lvalue = boolean_expression\n"); else begin $display("PASSED\n"); $finish; end always value1 <= 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2C.v000066400000000000000000000025351435245347300207230ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate 3.1.2C always reg_lvalue = # delay_value constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 1; if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # delay_value constant"); #15 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue = # delay_value constant"); else begin $display("PASSED\n"); $finish ; end end always value1 <= # 10 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2D.v000066400000000000000000000025501435245347300207210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate 3.1.2D always reg_lvalue = # delay_value boolean_expr ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin if(value1 !== 4'hx) $display("FAILED - always reg_lvalue = # delay_value boolean_expr"); #15 ; if(value1 != 4'b1) $display("FAILED - always reg_lvalue = # delay_value boolean_expr"); else begin $display("PASSED\n"); $finish ; end end always value1 <= # 10 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2E.v000066400000000000000000000026721435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate 3.1.2E always reg_lvalue <= # (mintypmax_expression) constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 3; /* Wait till here to verify didn't see 2ns delay! */ if(value1 !== 4'hx) $display("FAILED - always reg_lvalue <= # (mintypmax_expression) constant \n"); #12 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue <= # (mintypmax_expression) constant \n"); else begin $display("PASSED\n"); $finish ; end end always value1 <= # (2:10:17) 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2F.v000066400000000000000000000026521435245347300207260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue <= # (mintypmax_expression) boolean_expr ; // D: This guy doesn't stop.. module main ; reg [3:0] value1 ; initial begin # 3; /* Wait till here to verify didn't see 2ns delay! */ if(value1 !== 4'hx) $display("FAILED - always reg_lvalue <= # (mintypmax_expression) boolean_expr \n"); #12 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue <= # (mintypmax_expression) boolean_expr \n"); else begin $display("PASSED\n"); $finish ; end end always value1 <= # (2:10:17) 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2G.v000066400000000000000000000026501435245347300207250ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue <= @ event_identifier constant // D: There is a dependency here between this and event keyword and -> module main ; reg [3:0] value1 ; event event_ident ; initial begin # 5 -> event_ident ; end initial begin if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue <= @ event_identifier constant\n"); #10 ; if(value1 != 4'h5) $display("FAILED - always reg_lvalue <= @ event_identifier constant\n"); else begin $display("PASSED\n"); $finish ; end end always value1 <= @ event_ident 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2H.v000066400000000000000000000027171435245347300207320ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue <= @ event_identifier boolean_expression // D: There is a dependency here between this and event keyword and -> module main ; reg [3:0] value1 ; event event_ident ; initial begin # 5 -> event_ident ; end initial begin if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue <= @ event_identifier boolean_expression\n"); #10 ; if(value1 != 4'b1) $display("FAILED - always reg_lvalue <= @ event_identifier boolean_expression\n"); else begin $display("PASSED\n"); $finish ; end end always value1 <= @ event_ident 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.2I.v000066400000000000000000000032551435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always reg_lvalue <= @ (event_expression) constant // module main ; reg [3:0] value1 ; reg event_var ; initial begin # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b0 ; # 2 ; value1 = 5'h 0 ; # 3 ; event_var = 1'b1 ; #5 ; end initial begin // Should be xxxx at initial time if(value1 !== 4'bxxxx) $display("FAILED - always reg_lvalue <= @ (event_expression) constant \n"); # 6 ; if(value1 != 4'h5) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue <= @ event_identifier boolean_expression\n"); # 5 ; if(value1 != 4'h5) // Time 5 should see a change of 0 to 1 $display("FAILED - always reg_lvalue <= @ event_identifier boolean_expression\n"); begin $display("PASSED\n"); $finish ; end end always value1 <= @ (event_var) 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3A.v000066400000000000000000000022731435245347300207210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always assign reg_lvalue = constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'h5) $display("FAILED - 3.1.3A always assign reg_lvalue = constant\n"); else begin $display("PASSED\n"); $finish; end always assign value1 = 4'h5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3B.v000066400000000000000000000023211435245347300207140ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always assign reg_lvalue = boolean_expression ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'h1) $display("FAILED - 3.1.3B always assign reg_lvalue = boolean_expr\n"); else begin $display("PASSED\n"); $finish; end always assign value1 = 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3B2.v000066400000000000000000000026551435245347300210100ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always assign reg_lvalue = boolean_expression ; // D: Note that initial has to be before always to execute! // SJW - This is a fixed version of always3.1.3B that actually runs. // Save the original always3.1.3B as a compile-only test as // there are syntax differences that the compiler might as well // have tested module main ; reg [3:0] value1 ; initial begin #3 if(value1 != 4'h1) $display("FAILED - 3.1.3B always assign reg_lvalue = boolean_expr"); else $display("PASSED"); $finish; end always #2 assign value1 = 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3C.v000066400000000000000000000023211435245347300207150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always assign reg_lvalue = boolean_expression ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial if(value1 != 4'h1) $display("FAILED - 3.1.3B always assign reg_lvalue = boolean_expr\n"); else begin $display("PASSED\n"); $finish; end always assign value1 = 1'b1 && 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3D.v000066400000000000000000000022431435245347300207210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = constant ; // D: No dependancy module main ; reg [3:0] value1 ; initial begin #15; if(value1 != 4'h5) $display("FAILED - 3.1.3D always force reg_lvalue = constant;\n"); else begin $display("PASSED\n"); $finish; end end always force value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3D2.v000066400000000000000000000024271435245347300210070ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = constant ; // D: No dependancy // SJW - Fix to actually run. Save the existing always3.1.3D.v, as it // has slightly different syntax that may as well be tested. module main ; reg [3:0] value1 ; initial begin #15; if(value1 !== 4'h5) $display("FAILED - 3.1.3D always force reg_lvalue = constant;"); else $display("PASSED"); $finish; end always #10 force value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3E.v000066400000000000000000000023221435245347300207200ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = boolean_expr ; // D: This is an infinite loop - thus compile only module main ; reg [3:0] value1 ; initial begin #15; if(value1 != 4'b1) $display("FAILED - 3.1.3E always force reg_lvalue = boolean_expr;\n"); else begin $display("PASSED\n"); $finish; end end always force value1 = 1'b1 & 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3E2.v000066400000000000000000000023641435245347300210100ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = boolean_expr ; // D: This is an infinite loop - thus compile only // SJW - rework from akways3.1.3E to make it runnable. module main ; reg [3:0] value1 ; initial begin #15; if(value1 !== 4'b1) $display("FAILED - 3.1.3E always force reg_lvalue = boolean_expr;"); else $display("PASSED"); $finish; end always #10 force value1 = 1'b1 & 1'b1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3F.v000066400000000000000000000022441435245347300207240ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = constant ; // D: No dependancy module main ; wire [3:0] value1 ; initial begin #15; if(value1 != 4'h5) $display("FAILED - 3.1.3F always force net_lvalue = constant;\n"); else begin $display("PASSED\n"); $finish; end end always force value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3F2.v000066400000000000000000000025171435245347300210110ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force reg_lvalue = constant ; // D: No dependancy // // SJW - This is adjusted from always3.1.3F to be actually runnable. // Without a delay in the always statement, there would be an // infinite loop that blocks execution. module main ; wire [3:0] value1 ; initial begin #15; if(value1 !== 4'h5) $display("FAILED - 3.1.3F always force net_lvalue = constant;"); else $display("PASSED"); $finish; end always #10 force value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3G.v000066400000000000000000000022641435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always force net_lvalue = boolean_expr ; // D: No dependancy module main ; wire [3:0] value1 ; initial begin #15; if(value1 != 4'h5) $display("FAILED - 3.1.3G always force net_lvalue = boolean_expr;\n"); else begin $display("PASSED\n"); $finish; end end always force value1 = 1'b1 && 1'b1; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3H.v000066400000000000000000000022151435245347300207240ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always release reg_lvalue ; // D: No dependancy module main ; reg [3:0] value1 ; initial begin #15; if(value1 != 4'h5) $display("FAILED - 3.1.3H always release rev_lvalue;\n"); else begin $display("PASSED\n"); $finish; end end always release value1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.3J.v000066400000000000000000000022161435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always release net_lvalue ; // D: No dependancy module main ; wire [3:0] value1 ; initial begin #15; if(value1 != 4'h5) $display("FAILED - 3.1.3H always release net_lvalue;\n"); else begin $display("PASSED\n"); $finish; end end always release value1 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4A.v000066400000000000000000000021121435245347300207120ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # delay_value ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 20 ; $display("PASSED\n"); $finish; end always # 10 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4B.v000066400000000000000000000026341435245347300207240ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # delay_value reg_lvalue = constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 1; if(value1 != 4'bxxxx) $display("FAILED - 3.1.4B - initial value not xxxx;\n"); #15 ; if(value1 != 4'h5) $display("FAILED - 3.1.4B - always # delay_value reg_lvalue = constant\n"); else begin $display("PASSED\n"); $finish; end end always # 10 value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4C.v000066400000000000000000000033571435245347300207300ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # delay_value reg_lvalue = boolean_expr ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; reg err ; initial begin err = 0; # 1; if(value1 !== 4'bxxxx) begin $display("FAILED - 3.1.4C - initial value not xxxx;\n"); err = 1; end #10 ; if(value1 != 4'h5) begin $display("FAILED - 3.1.4C - always # delay_value reg_lvalue = boolean_expr\n"); err = 1; end #10 ; if(value1 != 4'hA) begin $display("FAILED - 3.1.4C - always # delay_value reg_lvalue = boolean_expr\n"); err = 1; end if (err == 0) $display("PASSED\n"); $finish; end always # 10 value1 = ~value1; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4D.v000066400000000000000000000021331435245347300207200ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # (mintypmax_dly) reg_lvalue ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin #30; $display("PASSED\n"); $finish; end always # (3:10:15) ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4E.v000066400000000000000000000030401435245347300207170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # (mintypmax_dly) reg_lvalue = constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; reg err ; initial begin err = 0; # 1; if(value1 !== 4'bxxxx) begin $display("FAILED - 3.1.4E - initial value not xxxx;\n"); err = 1; end #15 ; if(value1 != 4'h5) begin $display("FAILED - 3.1.4E - always # mintypmax_dly reg_lvalue = constant\n"); err = 1; end if (err == 0) $display("PASSED\n"); $finish; end always # (3:10:15) value1 = 4'h5; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4F.v000066400000000000000000000031031435245347300207200ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always # (mintypmax_dly) reg_lvalue = boolean_expr ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin # 1; if(value1 != 4'bxxxx) $display("FAILED - 3.1.4F - initial value not xxxx;\n"); #10 ; if(value1 != 4'h5) $display("FAILED - 3.1.4F - always # (mintypmax_dly) reg_lvalue = boolean_expr\n"); #10 ; if(value1 != 4'hA) $display("FAILED - 3.1.4F - always # (mintypmax_dly) reg_lvalue = boolean_expr\n"); else begin $display("PASSED\n"); end $finish; end always # 10 value1 = ~value1; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4G.v000066400000000000000000000021131435245347300207210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always @ (event_expression) ; // D: module main ; reg [3:0] value1 ; initial begin # 10 ; value1 = 4'h5; # 10 ; $display("PASSED\n"); $finish; end always @ (value1) ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4H.v000066400000000000000000000027231435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always @ (event_expr) reg_lvalue = constant ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1,value2 ; initial begin # 1; if(value1 != 4'bxxxx) $display("FAILED - 3.1.4H - initial value not xxxx;\n"); value2 = 4'h1; // Cause @ to execute. #15 ; if(value1 != 4'h5) $display("FAILED - 3.1.4H - always @ (event_expression) reg_lvalue = constant ;\n"); else begin $display("PASSED\n"); $finish; end end always @ (value2) value1 = ~value1; endmodule iverilog-12_0/ivtest/ivltests/always3.1.4I.v000066400000000000000000000032061435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always @ (event_expression) reg_lvalue = boolean_expr ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1,value2; initial begin # 1; if(value1 != 4'bxxxx) $display("FAILED - 3.1.4I - initial value not xxxx;\n"); value2 = 4'b1; #10 ; if(value1 != 4'h5) $display("FAILED - 3.1.4I - always @ (event_expression) reg_lvalue = boolean_expr;\n"); value2 = 4'b0; #10 ; if(value1 != 4'hA) $display("FAILED - 3.1.4I - always @ (event_expression) reg_lvalue = boolean_expr;\n"); else begin $display("PASSED\n"); end $finish; end always # 10 value1 = ~value1; endmodule iverilog-12_0/ivtest/ivltests/always3.1.5A.v000066400000000000000000000025221435245347300207200ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( constant) statement ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5A always if ( constant) statement \n"); else $display("PASSED"); $finish; end always if( 1'b1) begin # 1; value1 = value1 + 1; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.5B.v000066400000000000000000000024471435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( constant) statement else ; module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5B always if ( constant) statementelse ;"); else $display("PASSED"); $finish; end always if( 1'b1) begin # 1; value1 = value1 + 1; end else ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.5C.v000066400000000000000000000025001435245347300207160ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( constant) statement_1 else statement_2 ; module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5C always if ( constant) statementelse ;"); else $display("PASSED"); $finish; end always if( 1'b1) begin # 1; value1 = value1 + 1; end else value1 = 0 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.5D.v000066400000000000000000000025411435245347300207240ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( boolean_expr ) statement ; // D: Note that initial has to be before always to execute! module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5D always if ( bool_expr) statement \n"); else $display("PASSED"); $finish; end always if( 1'b1 && 1'b1 ) begin # 1; value1 = value1 + 1; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.5E.v000066400000000000000000000024601435245347300207250ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( bool_expr) statement else ; module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5E always if ( bool_expr) statementelse ;"); else $display("PASSED"); $finish; end always if( 1'b1 & 1'b1) begin # 1; value1 = value1 + 1; end else ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.5F.v000066400000000000000000000025111435245347300207230ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always if ( bool_expr) statement_1 else statement_2 ; module main ; reg [3:0] value1 ; initial begin value1 = 0; # 5 ; if(value1 != 4'd4) $display("FAILED - always 3.1.5F always if ( bool_expr) statementelse ;"); else $display("PASSED"); $finish; end always if( 1'b1 | 1'b1) begin # 1; value1 = value1 + 1; end else value1 = 0 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.6A.v000066400000000000000000000051101435245347300207150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always case ( reg_value) case_item1; case_item2; case_item3; endcase // D: module main ; reg [3:0] value1,value2,value3; initial begin #0; value3 = 0; #3 ; // t=3 value1 = 4'b0000 ; // Picked up at time 4 #5 ; // check at time 8 if(value2 != 4'b0) begin $display("FAILED - always3.1.6A - case 0 at %t",$time); value3 = 1; end #1 ; // Picked up at time 10 value1 = 4'b0001 ; // Set at time 9. #5 ; // Check at time 14 if(value2 != 4'b0001) begin $display("FAILED - always3.1.6A - case 1 at %t",$time); value3 = 1; end #1; // Picked up at time 16 value1 = 4'b0010; // Changed at time 15. #5; // Check at time 20... if(value2 != 4'b0010) begin $display("FAILED - always3.1.6A - case 2 at %t",$time); value3 = 1; end #10; if(value3 == 0) $display("PASSED"); $finish; end always case (value1) 4'b0000: begin #3 ; value2 = 4'b0000 ; #3 ; end 4'b0001: begin #3 ; value2 = 4'b0001 ; #3 ; end 4'b0010: begin #3 ; value2 = 4'b0010 ; #3 ; end default: #2 ; endcase endmodule iverilog-12_0/ivtest/ivltests/always3.1.6B.v000066400000000000000000000050611435245347300207230ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always casex ( reg_value) case_item1; case_item2; case_item3; endcase // D: module main ; reg [3:0] value1,value2,value3; initial begin #0; value3 = 0; #1 ; // t=3 value1 = 4'b0000 ; // Picked up at time 6 #9 ; // check at time 10 if(value2 != 4'b0) begin $display("FAILED - always3.1.6B - casex 0 at %t",$time); value3 = 1; end #1 ; // Picked up at time 12 value1 = 4'b0011 ; // Set at time 11. #5 ; // Check at time 16 if(value2 != 4'b0001) begin $display("FAILED - always3.1.6B - casex 1 at %t",$time); value3 = 1; end #1; // Picked up at time 16 value1 = 4'b0100; // Changed at time 15. #5; // Check at time 20... if(value2 != 4'b0010) begin $display("FAILED - always3.1.6B - casex 2 at %t",$time); value3 = 1; end #10; if(value3 == 0) $display("PASSED"); $finish; end always casex (value1) 4'b0000: begin #3 ; value2 = 4'b0000 ; #3 ; end 4'b00x1: begin #3 ; value2 = 4'b0001 ; #3 ; end 4'b0100: begin #3 ; value2 = 4'b0010 ; #3 ; end endcase endmodule iverilog-12_0/ivtest/ivltests/always3.1.6C.v000066400000000000000000000065311435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always casez ( reg_value) case_item1; case_item2; case_item3; endcase // D: module main ; reg [3:0] value1,value2,value3; initial begin #0; // $dumpfile("test.vcd"); // $dumpvars(0,main); value3 = 0; #3 ; // t=3 value1 = 4'b0000 ; // Picked up at time 4 #5 ; // check at time 8 $display("check == 0000:at time=%t value2=%h",$time,value2); if(value2 != 4'b0) begin $display("FAILED - always3.1.6C - casez 0 at %t",$time); value3 = 1; end #1 ; // Picked up at time 10 value1 = 4'b00z1 ; // Set at time 9. #5 ; // Check at time 14 $display("check == 0001:at time=%t value2=%h",$time,value2); if(value2 != 4'b0001) begin $display("FAILED - always3.1.6C - casez z1 at %t",$time); value3 = 1; end #1; // Picked up at time 16 value1 = 4'b0100; // Changed at time 15. #5; // Check at time 20... $display("check == 0010:at time=%t value2=%h",$time,value2); if(value2 != 4'b0010) begin $display("FAILED - always3.1.6C - casez 4 at %t",$time); value3 = 1; end #10; if(value3 == 0) $display("PASSED"); $finish; end always begin $display("Entering case at time=%t value1=%b",$time,value1); casez (value1) 4'b0000: begin #3 ; value2 = 4'b0000 ; $display("case0000: at time=%t",$time); #3 ; end 4'b00z1: begin #3 ; value2 = 4'b0001 ; $display("case00z1: at time=%t",$time); #3 ; end 4'b0100: begin #3 ; value2 = 4'b0010 ; $display("case100: at time=%t",$time); #3 ; end default: begin #2 ; $display("default: %t",$time); end endcase $display("Leaving case at time=%t",$time); end endmodule iverilog-12_0/ivtest/ivltests/always3.1.6D.v000066400000000000000000000037151435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always case ( reg_value) case_item1; case_item2; case_item3; endcase // D: // time value1 value2 // xxxx xxxx // 1 0000 // 2 0000 // 3 0001 // 4 0001 // 5 0010 // 6 0010 module main ; reg [3:0] value1,value2,value3; initial begin #1 ; #2 if (value2 != 0) begin $display("FAILED == at time 3, %b != 0", value2); $finish; end #2 if (value2 != 1) begin $display("FAILED == at time 5, %b != 1", value2); $finish; end #2 if (value2 != 2) begin $display("FAILED == at time 7, %b != 2", value2); $finish; end $display("PASSED"); $finish; end initial begin #1 value1 = 4'b0000; #2 value1 = 4'b0001; #2 value1 = 4'b0010; end always case (value1) 4'b0000 : begin value2 = 4'b0000 ; #2 ; end 4'b0001 : begin value2 = 4'b0001 ; #2 ; end 4'b0010 : begin value2 = 4'b0010 ; #2 ; end 4'bxxxx : #2 ; default : begin $display("FAILED -- unexpected value1===%b", value1); $finish; end endcase endmodule iverilog-12_0/ivtest/ivltests/always3.1.7A.v000066400000000000000000000033461435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always forever statement ; module main ; reg [3:0] value1,value2,value3; initial begin value1 = 0; // Time 0 assignemnt value2 = 0; #6 ; if(value1 != 4'h1) begin $display("FAILED - 3.1.7A always forever (1) "); value2 = 1; end #5 ; if(value1 != 4'h2) begin $display("FAILED - 3.1.7A always forever (2) "); value2 = 1; end #5 ; if(value1 != 4'h3) begin $display("FAILED - 3.1.7A always forever (3) "); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish; end always forever begin #5 ; value1 = value1 + 1; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.7B.v000066400000000000000000000033741435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always repeat (expression) statement ; module main ; reg [3:0] value1,value2,value3; initial begin value1 = 0; // Time 0 assignemnt value2 = 0; #6 ; if(value1 != 4'h1) begin $display("FAILED - 3.1.7B always forever (1) "); value2 = 1; end #5 ; if(value1 != 4'h2) begin $display("FAILED - 3.1.7B always forever (2) "); value2 = 1; end #5 ; if(value1 != 4'h3) begin $display("FAILED - 3.1.7B always forever (3) "); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish; end always repeat(3) begin #5 ; value1 = value1 + 1; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.7C.v000066400000000000000000000034411435245347300207250ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always while (boolean_expression ) statement ; module main ; reg [3:0] value1,value2,value3; initial begin value1 = 0; // Time 0 assignemnt value2 = 0; #6 ; if(value1 != 4'h1) begin $display("FAILED - 3.1.7C always while (1'b1 )") ; value2 = 1; end #5 ; if(value1 != 4'h2) begin $display("FAILED - 3.1.7C always while (1'b1) "); value2 = 1; end #5 ; if(value1 != 4'h3) begin $display("FAILED - 3.1.7C always while (1'b1) "); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish; end always while (1'b1 && 1'b1) begin #5 ; value1 = value1 + 1; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.7D.v000066400000000000000000000033061435245347300207260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always for (expr1;boolean_expr;expr2) statement ; module main ; reg [3:0] value1,value2,value3; initial begin value1 = 0; // Time 0 assignemnt value2 = 0; #6 ; if(value1 != 4'h1) begin $display("FAILED - 3.1.7D always for (1)") ; value2 = 1; end #5 ; if(value1 != 4'h2) begin $display("FAILED - 3.1.7D always for (2) "); value2 = 1; end #5 ; if(value1 != 4'h3) begin $display("FAILED - 3.1.7D always for (3) "); value2 = 1; end if(value2 == 0) $display("PASSED"); $finish; end always for(value1 = 0; value1 <= 5; value1 = value1 + 1) #5 ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.8A.v000066400000000000000000000035721435245347300207310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always wait (expression ) reg_lvalue = constant ; module main ; reg [3:0] value1,value2,value3; always wait (value1 == 4'h3) begin value2 = 3 ; #1 ; end initial begin value1 = 0; value2 = 0; value3 = 0; #2 ; if(value2 != 0) begin $display("FAILED - 3.1.8A always wait (expr) reg_lval = const (1);"); value3 = 1; end value1 = 1; #2 ; if(value2 != 0) begin $display("FAILED - 3.1.8A always wait (expr) reg_lval = const (2);"); value3 = 1; end value1 = 2; #2 ; if(value2 != 0) begin $display("FAILED - 3.1.8A always wait (expr) reg_lval = const (3);"); value3 = 1; end value1 = 4'h3; #2; if(value2 != 3) begin $display("FAILED - 3.1.8A always wait (expr) reg_lval = const (4);"); value3 = 1; end #10; if(value3 == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/always3.1.9A.v000066400000000000000000000021211435245347300207170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always disable task_identifier ; module main ; reg [3:0] value1 ; task foo ; value1 = #1 1; endtask initial begin value1 = 0; #2 ; $display("value = %d",value1); #1 ; $finish ; end always disable foo ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.9B.v000066400000000000000000000020551435245347300207260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always disable block_identifier ; module main ; reg [3:0] value1 ; always begin : block_id #1 ; $display("Hi there"); $finish ; end always disable block_id ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.9C.v000066400000000000000000000022711435245347300207270ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always #1 disable task_identifier ; module main ; reg [3:0] value1 ; task foo ; value1 = #2 1; endtask initial begin value1 = 1'b0; #5; foo ; #4 ; if(value1 === 1'b0) $display("PASSED"); else $display("FAILED - always3.1.9C always #2 disable foo"); $finish ; end always #6 disable foo ; endmodule iverilog-12_0/ivtest/ivltests/always3.1.9D.v000066400000000000000000000023521435245347300207300ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always disable block_identifier ; module main ; reg [3:0] value1 ; always begin : block_id #4 ; value1 = 1; $finish ; end initial begin value1 = 0; #5; if(value1 === 1'b0) $display("PASSED"); else $display("FAILED - always3.1.9D always #1 disable block_id"); #1; $finish ; end always #3 disable block_id ; endmodule iverilog-12_0/ivtest/ivltests/always4A.v000066400000000000000000000002731435245347300204200ustar00rootroot00000000000000module top; // A join_any will always take the shortest path always fork #0; #1; join_any initial begin $display("FAILED"); #1; $finish; end endmodule iverilog-12_0/ivtest/ivltests/always4B.v000066400000000000000000000002741435245347300204220ustar00rootroot00000000000000module top; // A join_any will always take the shortest path always fork #2; #1; join_none initial begin $display("FAILED"); #1; $finish; end endmodule iverilog-12_0/ivtest/ivltests/always_comb.v000066400000000000000000000026671435245347300212440ustar00rootroot00000000000000module top; reg y, a, b, flip, hidden; reg pass; function f_and (input i1, i2); reg partial; begin partial = i1 & i2; f_and = partial | hidden; end endfunction reg intr; always_comb begin intr = flip; y = f_and(a, b) ^ intr; end initial begin pass = 1'b1; flip = 1'b0; hidden = 1'b0; a = 1'b0; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b0; b = 1'b1; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b1, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b1; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b1, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b1; b = 1'b1; #1; if (y !== 1'b1) begin $display("FAILED: a=1'b1, b=1'b1, hidden=1'b0, expected 1'b1, got %b", y); pass = 1'b0; end hidden = 1'b0; a = 1'b0; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end hidden = 1'b1; a = 1'b0; b = 1'b0; #1; if (y !== 1'b1) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b1, expected 1'b1, got %b", y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_comb_fail.v000066400000000000000000000001761435245347300222300ustar00rootroot00000000000000module top; reg q, d; always_comb begin #0 q = d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_comb_fail3.v000066400000000000000000000002151435245347300223050ustar00rootroot00000000000000module top; reg q, d; event foo; always_comb begin @foo q = d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_comb_fail4.v000066400000000000000000000006201435245347300223060ustar00rootroot00000000000000module top; reg a, b; reg q, d; event foo; always_comb begin q = d; fork $display("fork/join 1"); join fork $display("fork/join_any 1"); join_any fork $display("fork/join_none 1"); join_none a <= @foo 1'b1; @(b) a <= repeat(2) @foo 1'b0; wait (!a) $display("wait"); end initial #1 $display("Expect compile errors!"); endmodule iverilog-12_0/ivtest/ivltests/always_comb_no_sens.v000066400000000000000000000006131435245347300227550ustar00rootroot00000000000000module test; reg passed; logic y; always_comb begin y = 1'b0; end initial begin passed = 1'b1; if (y !== 1'bx) begin $display("FAILED: expected 1'bx, got %b", y); passed = 1'b0; end #1; if (y !== 1'b0) begin $display("FAILED: expected 1'b0, got %b", y); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_comb_rfunc.v000066400000000000000000000017371435245347300224360ustar00rootroot00000000000000module top; logic passed; logic [7:0] value; integer ones; function automatic integer count_by_one(input integer start); if (start) count_by_one = (value[start] ? 1 : 0) + count_ones(start-1); else count_by_one = value[start] ? 1 : 0; endfunction function automatic integer count_ones(input integer start); if (start) count_ones = (value[start] ? 1 : 0) + count_by_one(start-1); else count_ones = value[start] ? 1 : 0; endfunction always_comb ones = count_ones(7); initial begin passed = 1'b1; value = 8'b0000_0000; #1; if (ones !== 0) begin $display("Expected 0, got %d", ones); passed = 1'b0; end value = 8'b0011_1100; #1; if (ones !== 4) begin $display("Expected 4, got %d", ones); passed = 1'b0; end value = 8'b1011_1101; #1; if (ones !== 6) begin $display("Expected 6, got %d", ones); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_comb_trig.v000066400000000000000000000024171435245347300222620ustar00rootroot00000000000000module top; reg a, q, qb; reg pass; always_comb q = a !== 1'bx; always_comb qb = a === 1'bx; initial begin pass = 1'b1; #0; // This second delay is needed for vlog95 since it uses #0 to create // the T0 trigger. vvp also needs it since it puts the event in the // inactive queue just like a #0 delay. #0; if (q !== 1'b0) begin $display("Expected q = 1'b0 with the default 1'bx input, got %b", q); pass = 1'b0; end if (qb !== 1'b1) begin $display("Expected qb = 1'b1 with the default 1'bx input, got %b", qb); pass = 1'b0; end #1; a = 1'b0; #0; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'b0 input, got %b", q); pass = 1'b0; end #1; a = 1'b1; #0; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'b1 input, got %b", q); pass = 1'b0; end #1; a = 1'bz; #0; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'bz input, got %b", q); pass = 1'b0; end #1; a = 1'bx; #0; if (q !== 1'b0) begin $display("Expected q = 1'b0 with an explicit 1'bx input, got %b", q); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_comb_warn.v000066400000000000000000000026351435245347300222660ustar00rootroot00000000000000module top; reg a; reg q, d; event foo; real rl; int ar []; int start = 0; int stop = 1; int step = 1; int done = 0; task a_task; real trl; event tevt; reg tvr; $display("user task"); endtask always_comb begin: blk_name event int1, int2; real intrl; q <= d; -> foo; rl = 0.0; rl <= 1.0; ar = new [2]; for (int idx = start; idx < stop; idx += step) $display("For: %0d", idx); for (int idx = 0; done; idx = done + 1) $display("Should never run!"); for (int idx = 0; idx; done = done + 1) $display("Should never run!"); for (int idx = 0; idx; {done, idx} = done + 1) $display("Should never run!"); for (int idx = 0; idx; idx <<= 1) $display("Should never run!"); for (int idx = 0; idx; idx = idx << 1) $display("Should never run!"); $display("array size: %0d", ar.size()); ar.delete(); $display("array size: %0d", ar.size()); a_task; assign a = 1'b0; deassign a; do $display("do/while"); while (a); force a = 1'b1; release a; while(a) begin $display("while"); a = 1'b0; end repeat(2) $display("repeat"); disable out_name; forever begin $display("forever"); disable blk_name; // This one should not generate a warning end end initial #1 $display("Expect compile warnings!\nPASSED"); initial begin: out_name #2 $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/always_ff.v000066400000000000000000000013711435245347300207060ustar00rootroot00000000000000module top; reg q, clk, d; reg pass; always_ff @(posedge clk) begin q <= d; end initial begin pass = 1'b1; #1; if (q !== 1'bx) begin $display("FAILED: initally expected 1'bx, got %b", q); pass = 1'b0; end d = 1'b0; clk = 1'b1; #1; if (q !== 1'b0) begin $display("FAILED: clock in a 0 expected 1'b0, got %b", q); pass = 1'b0; end d = 1'b1; clk = 1'b0; #1; if (q !== 1'b0) begin $display("FAILED: no clock change expected 1'b0, got %b", q); pass = 1'b0; end clk = 1'b1; #1; if (q !== 1'b1) begin $display("FAILED: clock in a 1 expected 1'b1, got %b", q); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_ff_fail.v000066400000000000000000000002211435245347300216720ustar00rootroot00000000000000module top; reg q, clk, d; always_ff @(posedge clk) begin #0 q <= d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_ff_fail2.v000066400000000000000000000002231435245347300217560ustar00rootroot00000000000000module top; reg q, clk, d; always_ff begin q <= d; @(posedge clk); end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_ff_fail3.v000066400000000000000000000002401435245347300217560ustar00rootroot00000000000000module top; reg q, clk, d; event foo; always_ff @(posedge clk) begin @foo q <= d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_ff_fail4.v000066400000000000000000000006511435245347300217650ustar00rootroot00000000000000module top; reg a, b; reg q, d; reg clk; event foo; always_ff @(posedge clk) begin q <= d; fork $display("fork/join 1"); join fork $display("fork/join_any 1"); join_any fork $display("fork/join_none 1"); join_none a <= @foo 1'b1; @(b) a <= repeat(2) @foo 1'b0; wait (!a) $display("wait"); end initial #1 $display("Expect compile errors!"); endmodule iverilog-12_0/ivtest/ivltests/always_ff_no_sens.v000066400000000000000000000001551435245347300224310ustar00rootroot00000000000000module test; logic y; always_ff begin y = 1'b0; end initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/always_ff_warn.v000066400000000000000000000027301435245347300217350ustar00rootroot00000000000000module top; reg a; reg q, d; reg clk; event foo; real rl; int ar []; int start = 0; int stop = 1; int step = 1; int done = 0; task a_task; real trl; event tevt; reg tvr; $display("user task"); endtask always_ff @(posedge clk) begin: blk_name event int1, int2; real intrl; q = d; -> foo; rl = 0.0; rl <= 1.0; ar = new [2]; for (int idx = start; idx < stop; idx += step) $display("For: %0d", idx); for (int idx = 0; done; idx = done + 1) $display("Should never run!"); for (int idx = 0; idx; done = done + 1) $display("Should never run!"); for (int idx = 0; idx; {done, idx} = done + 1) $display("Should never run!"); for (int idx = 0; idx; idx <<= 1) $display("Should never run!"); for (int idx = 0; idx; idx = idx << 1) $display("Should never run!"); $display("array size: %0d", ar.size()); ar.delete(); $display("array size: %0d", ar.size()); a_task; assign a = 1'b0; deassign a; do $display("do/while"); while (a); force a = 1'b1; release a; while(a) begin $display("while"); a = 1'b0; end repeat(2) $display("repeat"); disable out_name; forever begin $display("forever"); disable blk_name; // This one should not generate a warning end end initial begin #1 clk = 1'b1; #0 $display("Expect compile warnings!\nPASSED"); end initial begin: out_name #2 $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/always_ff_warn_sens.v000066400000000000000000000024551435245347300227710ustar00rootroot00000000000000module top; reg q1, q2, q3, q4, q5, q6, q7, d; reg clk; reg [5:4] rst; integer i; // The compiler should warn that clk is missing an edge keyword. always_ff @(clk) begin q1 <= d; end // The compiler should warn that rst is missing an edge keyword. always_ff @(posedge clk or rst[4]) begin if (rst[4]) q2 <= 1'b0; else q2 <= d; end // The compiler should warn that rst is missing an edge keyword. always_ff @(posedge clk or rst[i]) begin if (rst[i]) q3 <= 1'b0; else q3 <= d; end // The compiler should warn that rst is missing an edge keyword. always_ff @(posedge clk or !rst) begin if (!rst) q4 <= 1'b0; else q4 <= d; end // The compiler should warn that rst is missing an edge keyword. always_ff @(posedge clk or ~rst[4]) begin if (~rst[4]) q5 <= 1'b0; else q5 <= d; end // The compiler should warn that rst is missing an edge keyword. always_ff @(posedge clk or &rst) begin if (&rst) q6 <= 1'b0; else q6 <= d; end // The compiler should warn that rst is not a single bit. always_ff @(posedge clk or posedge rst) begin if (rst) q7 <= 1'b0; else q7 <= d; end initial begin $display("Expect compile warnings!\nPASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_latch.v000066400000000000000000000032071435245347300214060ustar00rootroot00000000000000module top; reg y, a, b, flip, hidden, en; reg pass; function f_and (input i1, i2); reg partial; begin partial = i1 & i2; f_and = partial | hidden; end endfunction reg intr; always_latch begin if (en) begin intr = flip; y <= f_and(a, b) ^ intr; end end initial begin pass = 1'b1; en = 1'b1; flip = 1'b0; hidden = 1'b0; a = 1'b0; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b0; b = 1'b1; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b1, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b1; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b1, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end a = 1'b1; b = 1'b1; #1; if (y !== 1'b1) begin $display("FAILED: a=1'b1, b=1'b1, hidden=1'b0, expected 1'b1, got %b", y); pass = 1'b0; end hidden = 1'b0; a = 1'b0; b = 1'b0; #1; if (y !== 1'b0) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b0, expected 1'b0, got %b", y); pass = 1'b0; end hidden = 1'b1; a = 1'b0; b = 1'b0; #1; if (y !== 1'b1) begin $display("FAILED: a=1'b0, b=1'b0, hidden=1'b1, expected 1'b1, got %b", y); pass = 1'b0; end en = 1'b0; hidden = 1'b0; #1; if (y !== 1'b1) begin $display("FAILED: en=1'b0, expected 1'b1, got %b", y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_latch_fail.v000066400000000000000000000002141435245347300223740ustar00rootroot00000000000000module top; reg q, en, d; always_latch begin if (en) #0 q <= d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_latch_fail3.v000066400000000000000000000002331435245347300224600ustar00rootroot00000000000000module top; reg q, en, d; event foo; always_latch begin if (en) @foo q <= d; end initial $display("Expected compile failure!"); endmodule iverilog-12_0/ivtest/ivltests/always_latch_fail4.v000066400000000000000000000006221435245347300224630ustar00rootroot00000000000000module top; reg a, b; reg q, d; event foo; always_latch begin q <= d; fork $display("fork/join 1"); join fork $display("fork/join_any 1"); join_any fork $display("fork/join_none 1"); join_none a <= @foo 1'b1; @(b) a <= repeat(2) @foo 1'b0; wait (!a) $display("wait"); end initial #1 $display("Expect compile errors!"); endmodule iverilog-12_0/ivtest/ivltests/always_latch_no_sens.v000066400000000000000000000001601435245347300231250ustar00rootroot00000000000000module test; logic y; always_latch begin y = 1'b0; end initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/always_latch_trig.v000066400000000000000000000020731435245347300224330ustar00rootroot00000000000000module top; reg a, enb, q; reg pass; always_latch if (enb !== 1'b1) q <= a !== 1'bx; initial begin pass = 1'b1; #1; if (q !== 1'b0) begin $display("Expected q = 1'b0 with the default 1'bx input, got %b", q); pass = 1'b0; end a = 1'b0; #1; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'b0 input, got %b", q); pass = 1'b0; end a = 1'b1; #1; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'b1 input, got %b", q); pass = 1'b0; end a = 1'bz; #1; if (q !== 1'b1) begin $display("Expected q = 1'b1 with an explicit 1'bz input, got %b", q); pass = 1'b0; end a = 1'bx; #1; if (q !== 1'b0) begin $display("Expected q = 1'b0 with an explicit 1'bx input, got %b", q); pass = 1'b0; end enb = 1'b1; a = 1'bz; #1; if (q !== 1'b0) begin $display("Expected q = 1'b0 with an enb = 1'b1, got %b", q); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/always_latch_warn.v000066400000000000000000000026351435245347300224410ustar00rootroot00000000000000module top; reg a; reg q, d; event foo; real rl; int ar []; int start = 0; int stop = 1; int step = 1; int done = 0; task a_task; real trl; event tevt; reg tvr; $display("user task"); endtask always_latch begin: blk_name event int1, int2; real intrl; q = d; -> foo; rl = 0.0; rl <= 1.0; ar = new [2]; for (int idx = start; idx < stop; idx += step) $display("For: %0d", idx); for (int idx = 0; done; idx = done + 1) $display("Should never run!"); for (int idx = 0; idx; done = done + 1) $display("Should never run!"); for (int idx = 0; idx; {done, idx} = done + 1) $display("Should never run!"); for (int idx = 0; idx; idx <<= 1) $display("Should never run!"); for (int idx = 0; idx; idx = idx << 1) $display("Should never run!"); $display("array size: %0d", ar.size()); ar.delete(); $display("array size: %0d", ar.size()); a_task; assign a = 1'b0; deassign a; do $display("do/while"); while (a); force a = 1'b1; release a; while(a) begin $display("while"); a = 1'b0; end repeat(2) $display("repeat"); disable out_name; forever begin $display("forever"); disable blk_name; // This one should not generate a warning end end initial #1 $display("Expect compile warnings!\nPASSED"); initial begin: out_name #2 $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/always_star_array_lval.v000066400000000000000000000014601435245347300234770ustar00rootroot00000000000000// This test was written to catch spurious "internal error" messages generated // by the compiler, so uses a gold file for checking. module test(); reg [7:0] Reg[0:3]; reg [7:0] Val0 = 255; reg [7:0] Val1 = 1; reg [7:0] Val2 = 2; reg [7:0] Val3 = 3; always @* begin Reg[0] = Val0; Reg[1] = Val1; Reg[2] = Val2; Reg[3] = Val3; end initial begin Val0 <= 0; // To make sure this triggers at T0 for SystemVerilog #1 $display("%0d %0d %0d %0d", Reg[0], Reg[1], Reg[2], Reg[3]); Val0 = 4; #1 $display("%0d %0d %0d %0d", Reg[0], Reg[1], Reg[2], Reg[3]); Val1 = 5; #1 $display("%0d %0d %0d %0d", Reg[0], Reg[1], Reg[2], Reg[3]); Val2 = 6; #1 $display("%0d %0d %0d %0d", Reg[0], Reg[1], Reg[2], Reg[3]); Val3 = 7; #1 $display("%0d %0d %0d %0d", Reg[0], Reg[1], Reg[2], Reg[3]); end endmodule iverilog-12_0/ivtest/ivltests/analog1.v000066400000000000000000000012741435245347300202570ustar00rootroot00000000000000nature Voltage; units = "V"; access = V; idt_nature = Flux; abstol = 1e-6; endnature nature Flux; units = "Wb"; access = Phi; ddt_nature = Voltage; abstol = 1e-9; endnature discipline voltage; potential Voltage; enddiscipline module main; real value; voltage out; analog V(out) <+ abs(value); initial begin value = 1.0; #1 if (V(out) != abs(value)) begin $display("FAILED -- value=%g, res=%g", value, V(out)); $finish; end value = -1.0; #1 if (V(out) != abs(value)) begin $display("FAILED -- value=%g, res=%f", value, V(out)); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/analog2.v000066400000000000000000000020751435245347300202600ustar00rootroot00000000000000nature Voltage; units = "V"; access = V; idt_nature = Flux; abstol = 1e-6; endnature discipline voltage; potential Voltage; enddiscipline nature Flux; units = "Wb"; access = Phi; ddt_nature = Voltage; abstol = 1e-9; endnature `timescale 1s/1s module main; real value; voltage in, out; analog V(out) <+ transition(value, 0, 4); initial begin value = 0.0; #10 if (V(out) != value) begin $display("FAILED -- value=%g, res=%g", value, V(out)); $finish; end // Halfway through the rise time, the output should have // half the input. value = 2.0; //#2 if (V(out) != value/2) begin #2 if (abs(V(out) - value/2) > 1e-6) begin $display("FAILED -- value=%g, value/2=%g, res=%f", value, value/2, V(out)); $finish; end // After the full transition time, the output should match // the input. #2 if (V(out) != value) begin $display("FAILED -- value=%g, res=%f", value, V(out)); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/andnot1.v000066400000000000000000000026471435245347300203060ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* andnot1.v * This tests types. */ module main; reg a, b, c; wire d = a & !b; // change from !b to ~b and everything is fine reg [2:0] tmp; reg ref; initial begin // Do an exaustive scan of the possible values. for (tmp = 0 ; tmp < 4 ; tmp = tmp + 1) begin a = tmp[0]; b = tmp[1]; c = a & ~b; #1 if (c != d) begin $display("FAILED -- a=%b, b=%b, c=%b, d=%b", a, b, c, d); $finish; end end // for (tmp = 0 ; tmp < 4 ; tmp = tmp + 1) $display("PASSED"); end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/arith-unknown.v000066400000000000000000000011641435245347300215370ustar00rootroot00000000000000// Ensure the compiler doesn't perform some invalid optimisations. module test(); reg [3:0] unknown; reg [3:0] result; reg failed; initial begin failed = 0; unknown = 4'bx101; result = unknown + 0; $display("%b", result); if (result !== 4'bxxxx) failed = 1; result = (unknown >> 1) + 0; $display("%b", result); if (result !== 4'bxxxx) failed = 1; result = unknown - 0; $display("%b", result); if (result !== 4'bxxxx) failed = 1; result = unknown * 0; $display("%b", result); if (result !== 4'bxxxx) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array4.v000066400000000000000000000010401435245347300201260ustar00rootroot00000000000000module test; parameter width = 16; localparam count = 1< into a constant array select. // This is needed to make the following work as expected. $dumpfile("work/array_dump.vcd"); for (lp = 0; lp < 3; lp = lp+1) $dumpvars(0, array[lp]); #1; array[0] = 8'hff; array[1] = 8'h00; array[2] = 8'h55; end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select1.v000066400000000000000000000063051435245347300225110ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of blocking procedural assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg array1[2:1]; reg array2[1:0]; `ifndef VLOG95 real array3[2:1]; real array4[1:0]; `endif integer index; reg failed; initial begin failed = 0; array1[1] = 1'b0; array1[2] = 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array1[0] = 1'b1; // Constant out of bounds select may be an error `endif $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; array1[1] = 1'b0; array1[2] = 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array1[3] = 1'b1; // Constant out of bounds select may be an error `endif $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; array2[0] = 1'b0; array2[1] = 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array2['bx] = 1'b1; // Constant undefined out of bounds select may be an error `endif $display("array = %b %b", array2[1], array2[0]); if ((array2[0] !== 1'b0) || (array2[1] !== 1'b0)) failed = 1; index = 0; array1[1] = 1'b0; array1[2] = 1'b0; array1[index] = 1'b1; $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; index = 3; array1[1] = 1'b0; array1[2] = 1'b0; array1[index] = 1'b1; $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; index = 'bx; array2[0] = 1'b0; array2[1] = 1'b0; array2[index] = 1'b1; $display("array = %b %b", array2[1], array2[0]); if ((array2[0] !== 1'b0) || (array2[1] !== 1'b0)) failed = 1; `ifndef VLOG95 array3[1] = 0.0; array3[2] = 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array3[0] = 1.0; // Constant out of bounds select may be an error `endif $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; array3[1] = 0.0; array3[2] = 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array3[3] = 1.0; // Constant out of bounds select may be an error `endif $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; array4[0] = 0.0; array4[1] = 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array4['bx] = 1.0; // Constant undefined out of bounds select may be an error `endif $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; index = 0; array3[1] = 0.0; array3[2] = 0.0; array3[index] = 1.0; $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; index = 3; array3[1] = 0.0; array3[2] = 0.0; array3[index] = 1.0; $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; index = 'bx; array4[0] = 0.0; array4[1] = 0.0; array4[index] = 1.0; $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select2.v000066400000000000000000000064211435245347300225110ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of non-blocking procedural assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg array1[2:1]; reg array2[1:0]; `ifndef VLOG95 real array3[2:1]; real array4[1:0]; `endif integer index; reg failed; initial begin failed = 0; array1[1] <= 1'b0; array1[2] <= 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array1[0] <= 1'b1; // Constant out of bounds select may be an error `endif #1 $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; array1[1] <= 1'b0; array1[2] <= 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array1[3] <= 1'b1; // Constant out of bounds select may be an error `endif #1 $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; array2[0] <= 1'b0; array2[1] <= 1'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array2['bx] <= 1'b1; // Constant undefined out of bounds select may be an error `endif #1 $display("array = %b %b", array2[1], array2[0]); if ((array2[0] !== 1'b0) || (array2[1] !== 1'b0)) failed = 1; index = 0; array1[1] <= 1'b0; array1[2] <= 1'b0; array1[index] <= 1'b1; #1 $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; index = 3; array1[1] <= 1'b0; array1[2] <= 1'b0; array1[index] <= 1'b1; #1 $display("array = %b %b", array1[2], array1[1]); if ((array1[1] !== 1'b0) || (array1[2] !== 1'b0)) failed = 1; index = 'bx; array2[0] <= 1'b0; array2[1] <= 1'b0; array2[index] <= 1'b1; #1 $display("array = %b %b", array2[1], array2[0]); if ((array2[0] !== 1'b0) || (array2[1] !== 1'b0)) failed = 1; `ifndef VLOG95 array3[1] <= 0.0; array3[2] <= 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array3[0] <= 1.0; // Constant out of bounds select may be an error `endif #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; array3[1] <= 0.0; array3[2] <= 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array3[3] <= 1.0; // Constant out of bounds select may be an error `endif #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; array4[0] <= 0.0; array4[1] <= 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST array4['bx] <= 1.0; // Constant undefined out of bounds select may be an error `endif #1 $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; index = 0; array3[1] <= 0.0; array3[2] <= 0.0; array3[index] <= 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; index = 3; array3[1] <= 0.0; array3[2] <= 0.0; array3[index] <= 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; index = 'bx; array4[0] <= 0.0; array4[1] <= 0.0; array4[index] <= 1.0; #1 $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select3a.v000066400000000000000000000054031435245347300226520ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of procedural continuous (reg) assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg [1:0] array1[2:1]; reg [1:0] array2[1:0]; reg [1:0] var1; `ifndef VLOG95 real array3[2:1]; real array4[1:0]; real var2; `endif reg failed; initial begin failed = 0; array1[1] = 2'd0; array1[2] = 2'd0; array2[0] = 2'd0; array2[1] = 2'd0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[0] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; deassign array1[0]; `endif assign array1[1] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd1) || (array1[2] !== 2'd0)) failed = 1; deassign array1[1]; assign array1[2] = var1; var1 = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd1)) failed = 1; var1 = 2'd2; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd2)) failed = 1; deassign array1[2]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[3] = var1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; deassign array1[3]; assign array2['bx] = 2'd1; #1 $display("array = %h %h", array2[1], array2[0]); if ((array2[0] !== 2'd0) || (array2[1] !== 2'd0)) failed = 1; deassign array2['bx]; `endif `ifndef VLOG95 array3[1] = 0.0; array3[2] = 0.0; array4[0] = 0.0; array4[1] = 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array3[0] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; deassign array3[0]; `endif assign array3[1] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 1.0) || (array3[2] != 0.0)) failed = 1; deassign array3[1]; assign array3[2] = var2; var2 = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 1.0)) failed = 1; var2 = 2.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 2.0)) failed = 1; deassign array3[2]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array3[3] = var2; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; deassign array3[3]; assign array4['bx] = 1.0; #1 $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; deassign array4['bx]; `endif `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select3b.v000066400000000000000000000004261435245347300226530ustar00rootroot00000000000000// Check behaviour with variable array indices on LHS of procedural // continuous (reg) assignment. This should be rejected by the compiler. module top; reg array1[2:1]; integer index = 1; initial begin assign array1[index] = 1'b1; deassign array1[index]; end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select3c.v000066400000000000000000000055211435245347300226550ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of procedural continuous (reg) assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg [1:0] array1[2:1]; reg [1:0] array2[1:0]; reg [1:0] var1; `ifndef VLOG95 real array3[2:1]; real array4[1:0]; real var2; `endif reg failed; initial begin failed = 0; array1[1] = 2'd0; array1[2] = 2'd0; array2[0] = 2'd0; array2[1] = 2'd0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[0] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; deassign array1[0]; `endif /* This is not supported at present assign array1[1] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd1) || (array1[2] !== 2'd0)) failed = 1; deassign array1[1]; assign array1[2] = var1; var1 = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd1)) failed = 1; var1 = 2'd2; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd2)) failed = 1; deassign array1[2]; */ `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[3] = var1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; deassign array1[3]; assign array2['bx] = 2'd1; #1 $display("array = %h %h", array2[1], array2[0]); if ((array2[0] !== 2'd0) || (array2[1] !== 2'd0)) failed = 1; deassign array2['bx]; `endif `ifndef VLOG95 array3[1] = 0.0; array3[2] = 0.0; array4[0] = 0.0; array4[1] = 0.0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array3[0] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; deassign array3[0]; `endif /* This is not supported at present assign array3[1] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 1.0) || (array3[2] != 0.0)) failed = 1; deassign array3[1]; assign array3[2] = var2; var2 = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 1.0)) failed = 1; var2 = 2.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 2.0)) failed = 1; deassign array3[2]; */ `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array3[3] = var2; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; deassign array3[3]; assign array4['bx] = 1.0; #1 $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; deassign array4['bx]; `endif `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select4a.v000066400000000000000000000054131435245347300226540ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of procedural continuous (net) assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `define SUPPORT_REAL_NETS_IN_IVTEST `endif module top; wire [1:0] array1[2:1]; wire [1:0] array2[1:0]; reg [1:0] var1; assign array1[1] = 2'd0; assign array1[2] = 2'd0; assign array2[0] = 2'd0; assign array2[1] = 2'd0; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real array3[2:1]; wire real array4[1:0]; real var2; assign array3[1] = 0.0; assign array3[2] = 0.0; assign array4[0] = 0.0; assign array4[1] = 0.0; `endif reg failed; initial begin failed = 0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force array1[0] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; release array1[0]; `endif force array1[1] = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd1) || (array1[2] !== 2'd0)) failed = 1; release array1[1]; force array1[2] = var1; var1 = 2'd1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd1)) failed = 1; var1 = 2'd2; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd2)) failed = 1; release array1[2]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force array1[3] = var1; #1 $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd0) || (array1[2] !== 2'd0)) failed = 1; release array1[3]; force array2['bx] = 2'd1; #1 $display("array = %h %h", array2[1], array2[0]); if ((array2[0] !== 2'd0) || (array2[1] !== 2'd0)) failed = 1; release array2['bx]; `endif `ifdef SUPPORT_REAL_NETS_IN_IVTEST force array3[0] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; release array3[0]; force array3[1] = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 1.0) || (array3[2] != 0.0)) failed = 1; release array3[1]; force array3[2] = var2; var2 = 1.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 1.0)) failed = 1; var2 = 2.0; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 2.0)) failed = 1; release array3[2]; force array3[3] = var2; #1 $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 0.0) || (array3[2] != 0.0)) failed = 1; release array3[3]; force array4['bx] = 1.0; #1 $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 0.0)) failed = 1; release array4['bx]; `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select4b.v000066400000000000000000000004251435245347300226530ustar00rootroot00000000000000// Check behaviour with variable array indices on LHS of procedural // continuous (net) assignment. This should be rejected by the compiler. module top; wire array1[2:1]; integer index = 1; initial begin force array1[index] = 1'b1; release array1[index]; end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select5.v000066400000000000000000000027631435245347300225210ustar00rootroot00000000000000// Check behaviour with out-of-range and undefined array indices // on LHS of continuous assignment. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `define SUPPORT_REAL_NETS_IN_IVTEST `endif module top; wire [1:0] array1[2:1]; wire [1:0] array2[1:0]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[0] = 2'd0; `endif assign array1[1] = 2'd1; assign array1[2] = 2'd2; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array1[3] = 2'd3; `endif assign array2[0] = 2'd0; assign array2[1] = 2'd1; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign array2['bx] = 2'd2; `endif `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real array3[2:1]; wire real array4[1:0]; assign array3[0] = 0.0; assign array3[1] = 1.0; assign array3[2] = 2.0; assign array3[3] = 3.0; assign array4[0] = 0.0; assign array4[1] = 1.0; assign array4['bx] = 2.0; `endif reg failed; initial begin #1 failed = 0; $display("array = %h %h", array1[2], array1[1]); if ((array1[1] !== 2'd1) || (array1[2] !== 2'd2)) failed = 1; $display("array = %h %h", array2[1], array2[0]); if ((array2[0] !== 2'd0) || (array2[1] !== 2'd1)) failed = 1; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("array = %0g %0g", array3[2], array3[1]); if ((array3[1] != 1.0) || (array3[2] != 2.0)) failed = 1; $display("array = %0g %0g", array4[1], array4[0]); if ((array4[0] != 0.0) || (array4[1] != 1.0)) failed = 1; `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_lval_select6.v000066400000000000000000000062221435245347300225140ustar00rootroot00000000000000// tests using array elements as indices/selects in an array lval select `timescale 1ns/100ps module tb; reg [7:0] a[7:0]; real r[7:0]; wire [2:0] idx[7:0]; genvar g; for (g = 0; g < 8; g=g+1) assign idx[g] = g; reg pass; integer i; initial begin pass = 1'b1; // zero everything out for (i = 0; i < 8; i = i + 1) begin a[i] = 8'h0; r[i] = 0.0; end // test using one in a part select a[1][idx[1]*4 +: 4] = 4'ha; if (a[1] != 8'ha0) begin $display("FAILED part select, expected a0, got %x", a[1]); pass = 1'b0; end // test using one in an index a[idx[2]] = 8'hbc; if (a[2] != 8'hbc) begin $display("FAILED word index, expected bc, got %x", a[2]); pass = 1'b0; end // and now both... a[idx[3]][idx[0]*4 +: 4] = 4'hd; if (a[3] != 8'h0d) begin $display("FAILED word index and part select, expected 0d, got %x", a[3]); pass = 1'b0; end // non-blocking, in part select a[4][idx[1]*4 +: 4] <= 4'he; if (a[4] != 8'h00) begin $display("FAILED NB assign with part select 1, expected 00, got %x", a[4]); pass = 1'b0; end #0.1; if (a[4] != 8'he0) begin $display("FAILED NB assign with part select 2, expected e0, got %x", a[4]); pass = 1'b0; end // non-blocking, in index a[idx[5]] <= 8'h12; if (a[5] != 8'h00) begin $display("FAILED NB assign with word index 1, expected 00, got %x", a[4]); pass = 1'b0; end #0.1; if (a[5] != 8'h12) begin $display("FAILED NB assign with word index 2, expected 12, got %x", a[4]); pass = 1'b0; end // non-blocking, index and part select a[idx[6]][idx[0]*4 +: 4] <= 4'h3; if (a[6] != 8'h00) begin $display("FAILED NB assign with both 1, expected 00, got %x", a[4]); pass = 1'b0; end #0.1; if (a[6] != 8'h03) begin $display("FAILED NB assign with both 2, expected 03, got %x", a[4]); pass = 1'b0; end // NB, both, with a delay a[idx[7]][idx[1]*4 +: 4] <= #(idx[1]) 4'h4; #0.1; if (a[7] != 8'h00) begin $display("FAILED NB assign with both and delay 1, expected 00, got %x", a[4]); pass = 1'b0; end #1.1; if (a[7] != 8'h40) begin $display("FAILED NB assign with both and delay 2, expected 40, got %x", a[4]); pass = 1'b0; end // real array index r[idx[0]] = 1.1; if (r[0] != 1.1) begin $display("FAILED real word, expected 1.0, got %f", r[0]); pass = 1'b0; end // NB to real array r[idx[1]] <= 2.2; if (r[1] != 0.0) begin $display("FAILED NB assign real word 1, expected 0.0 got %f", r[1]); pass = 1'b0; end #0.1; if (r[1] != 2.2) begin $display("FAILED NB assign real word 2, expected 2.2 got %f", r[1]); pass = 1'b0; end // NB to real array with delay r[idx[2]] <= #(idx[2]) 3.3; #1.1; if (r[2] != 0.0) begin $display("FAILED NB assign with delay to real word 1, expected 0.0 got %f", r[1]); pass = 1'b0; end #1.0; if (r[2] != 3.3) begin $display("FAILED NB assign with delay to real word 2, expected 3.3 got %f", r[1]); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_packed.v000066400000000000000000000033361435245347300213630ustar00rootroot00000000000000// Check that packed arrays of all sorts get elaborated without an error and // that the resulting type has the right packed width. package p; typedef logic [2:0] vector; endpackage module test; typedef bit bit2; typedef logic [1:0] vector; bit2 [1:0] b; vector [2:0] l; p::vector [3:0] scoped_pa; typedef enum logic [7:0] { A } E; typedef E [1:0] EP; typedef EP [2:0] EPP; E e; EP ep1; E [1:0] ep2; EP [2:0] epp1; EPP epp2; EPP [3:0] eppp; enum logic [7:0] { B } [1:0] ep3; typedef struct packed { longint x; } S1; typedef struct packed { time t; integer i; logic [1:0] x; bit [3:0] y; int z; shortint w; E e; EP ep; S1 s; } S2; localparam S_SIZE = 64 + 32 + 2 + 4 + 32 + 16 + 8 + 8*2 + 64; typedef S2 [3:0] SP; typedef SP [9:0] SPP; S2 s; SP sp1; S2 [3:0] sp2; SP [9:0] spp1; SPP spp2; SPP [1:0] sppp; struct packed { S2 s; } [3:0] sp3; bit failed = 1'b0; initial begin // Packed arrays of basic types failed |= $bits(b) !== 2; failed |= $bits(l) !== 2 * 3; failed |= $bits(scoped_pa) !== 3 * 4; // Packed arrays of enums failed |= $bits(e) !== 8; failed |= $bits(ep1) !== $bits(e) * 2; failed |= $bits(ep2) !== $bits(ep1); failed |= $bits(ep3) !== $bits(ep1); failed |= $bits(epp1) !== $bits(ep1) * 3; failed |= $bits(epp2) !== $bits(epp1); failed |= $bits(eppp) !== $bits(epp1) * 4; // Packed arrays of structs failed |= $bits(s) !== S_SIZE; failed |= $bits(sp1) !== $bits(s) * 4; failed |= $bits(sp2) !== $bits(sp1); failed |= $bits(sp3) !== $bits(sp1); failed |= $bits(spp1) !== $bits(sp1) * 10; failed |= $bits(spp1) !== $bits(spp2); failed |= $bits(sppp) !== $bits(spp1) * 2; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_packed_2d.v000066400000000000000000000044641435245347300217530ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test different ways of accessing a 2D packed array. module array_packed_2d(); reg [1:4][7:0] vec; reg [4:1][7:0] vec2; integer i; initial begin // test 1: assign using variable index for(i = 1; i <= 4; i = i + 1) vec[i] = i * 2; // display whole vector $display("%h", vec); // $display using variable index for(i = 1; i <= 4; i = i + 1) $display(vec[i]); // $display using constant index $display(vec[1]); $display(vec[2]); $display(vec[3]); $display(vec[4]); // test 2: assign using a constant index vec[1] = 2; vec[2] = 4; vec[3] = 6; vec[4] = 8; // display whole vector $display("%h", vec); // $display using variable index for(i = 1; i <= 4; i = i + 1) $display(vec[i]); // $display using constant index $display(vec[1]); $display(vec[2]); $display(vec[3]); $display(vec[4]); ////////////////////////////////////////// // test 1: assign using variable index for(i = 1; i <= 4; i = i + 1) vec2[i] = i * 2; // display whole vector $display("%h", vec2); // $display using variable index for(i = 1; i <= 4; i = i + 1) $display(vec2[i]); // $display using constant index $display(vec2[1]); $display(vec2[2]); $display(vec2[3]); $display(vec2[4]); // test 2: assign using a constant index vec2[1] = 2; vec2[2] = 4; vec2[3] = 6; vec2[4] = 8; // display whole vector $display("%h", vec2); // $display using variable index for(i = 1; i <= 4; i = i + 1) $display(vec2[i]); // $display using constant index $display(vec2[1]); $display(vec2[2]); $display(vec2[3]); $display(vec2[4]); end endmodule iverilog-12_0/ivtest/ivltests/array_packed_sysfunct.v000066400000000000000000000177401435245347300233250ustar00rootroot00000000000000// This tests system functions operationg on packed arrays // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // parameters for array sizes localparam WA = 4; localparam WB = 6; localparam WC = 8; function int wdt (input int i); wdt = 2 + 2*i; endfunction // 2D packed arrays logic [WA-1:0] [WB-1:0] [WC-1:0] abg; // big endian array logic [0:WA-1] [0:WB-1] [0:WC-1] alt; // little endian array // error counter bit err = 0; // indexing variable int i; initial begin // big endian // full array if ($dimensions(abg) != 3) begin $display("FAILED -- $dimensions(abg) = %0d", $dimensions(abg)); err=1; end; if ($bits (abg) != WA*WB*WC) begin $display("FAILED -- $bits (abg) = %0d", $bits (abg)); err=1; end; for (i=1; i<=3; i=i+1) begin if ($left (abg , i) != wdt(i )-1) begin $display("FAILED -- $left (abg , %0d) = %0d", i, $left (abg , i)); err=1; end; if ($right (abg , i) != 0 ) begin $display("FAILED -- $right (abg , %0d) = %0d", i, $right (abg , i)); err=1; end; if ($low (abg , i) != 0 ) begin $display("FAILED -- $low (abg , %0d) = %0d", i, $low (abg , i)); err=1; end; if ($high (abg , i) != wdt(i )-1) begin $display("FAILED -- $high (abg , %0d) = %0d", i, $high (abg , i)); err=1; end; if ($increment(abg , i) != 1 ) begin $display("FAILED -- $increment(abg , %0d) = %0d", i, $increment(abg , i)); err=1; end; if ($size (abg , i) != wdt(i ) ) begin $display("FAILED -- $size (abg , %0d) = %0d", i, $size (abg , i)); err=1; end; end // half array if ($dimensions(abg[1:0]) != 3) begin $display("FAILED -- $dimensions(abg[1:0]) = %0d", $dimensions(abg[1:0])); err=1; end; if ($bits (abg[1:0]) != 2*WB*WC) begin $display("FAILED -- $bits (abg[1:0]) = %0d", $bits (abg[1:0])); err=1; end; for (i=1; i<=3; i=i+1) begin if ($left (abg[1:0], i) != wdt(i )-1) begin $display("FAILED -- $left (abg[1:0], %0d) = %0d", i, $left (abg[1:0], i)); err=1; end; if ($right (abg[1:0], i) != 0 ) begin $display("FAILED -- $right (abg[1:0], %0d) = %0d", i, $right (abg[1:0], i)); err=1; end; if ($low (abg[1:0], i) != 0 ) begin $display("FAILED -- $low (abg[1:0], %0d) = %0d", i, $low (abg[1:0], i)); err=1; end; if ($high (abg[1:0], i) != wdt(i )-1) begin $display("FAILED -- $high (abg[1:0], %0d) = %0d", i, $high (abg[1:0], i)); err=1; end; if ($increment(abg[1:0], i) != 1 ) begin $display("FAILED -- $increment(abg[1:0], %0d) = %0d", i, $increment(abg[1:0], i)); err=1; end; if ($size (abg[1:0], i) != wdt(i ) ) begin $display("FAILED -- $size (abg[1:0], %0d) = %0d", i, $size (abg[1:0], i)); err=1; end; end // single array element if ($dimensions(abg[0]) != 2) begin $display("FAILED -- $dimensions(abg[0]) = %0d", $dimensions(abg[0])); err=1; end; if ($bits (abg[0]) != WB*WC) begin $display("FAILED -- $bits (abg[0]) = %0d", $bits (abg[0])); err=1; end; for (i=1; i<=2; i=i+1) begin if ($left (abg[0] , i) != wdt(i+1)-1) begin $display("FAILED -- $left (abg[0] , %0d) = %0d", i, $left (abg[0] , i)); err=1; end; if ($right (abg[0] , i) != 0 ) begin $display("FAILED -- $right (abg[0] , %0d) = %0d", i, $right (abg[0] , i)); err=1; end; if ($low (abg[0] , i) != 0 ) begin $display("FAILED -- $low (abg[0] , %0d) = %0d", i, $low (abg[0] , i)); err=1; end; if ($high (abg[0] , i) != wdt(i+1)-1) begin $display("FAILED -- $high (abg[0] , %0d) = %0d", i, $high (abg[0] , i)); err=1; end; if ($increment(abg[0] , i) != 1 ) begin $display("FAILED -- $increment(abg[0] , %0d) = %0d", i, $increment(abg[0] , i)); err=1; end; if ($size (abg[0] , i) != wdt(i+1) ) begin $display("FAILED -- $size (abg[0] , %0d) = %0d", i, $size (abg[0] , i)); err=1; end; end // little endian // full array if ($dimensions(alt) != 3) begin $display("FAILED -- $dimensions(alt) = %0d", $dimensions(alt)); err=1; end; if ($bits (alt) != WA*WB*WC) begin $display("FAILED -- $bits (alt) = %0d", $bits (alt)); err=1; end; for (i=1; i<=3; i=i+1) begin if ($left (alt , i) != 0 ) begin $display("FAILED -- $left (alt , %0d) = %0d", i, $left (alt , i)); err=1; end; if ($right (alt , i) != wdt(i )-1) begin $display("FAILED -- $right (alt , %0d) = %0d", i, $right (alt , i)); err=1; end; if ($low (alt , i) != 0 ) begin $display("FAILED -- $low (alt , %0d) = %0d", i, $low (alt , i)); err=1; end; if ($high (alt , i) != wdt(i )-1) begin $display("FAILED -- $high (alt , %0d) = %0d", i, $high (alt , i)); err=1; end; if ($increment(alt , i) != -1 ) begin $display("FAILED -- $increment(alt , %0d) = %0d", i, $increment(alt , i)); err=1; end; if ($size (alt , i) != wdt(i ) ) begin $display("FAILED -- $size (alt , %0d) = %0d", i, $size (alt , i)); err=1; end; end // half array if ($dimensions(alt[0:1]) != 3) begin $display("FAILED -- $dimensions(alt[0:1]) = %0d", $dimensions(alt[0:1])); err=1; end; if ($bits (alt[0:1]) != 2*WB*WC) begin $display("FAILED -- $bits (alt[0:1]) = %0d", $bits (alt[0:1])); err=1; end; for (i=1; i<=3; i=i+1) begin if ($left (alt[0:1], i) != 0 ) begin $display("FAILED -- $left (alt[0:1], %0d) = %0d", i, $left (alt[0:1], i)); err=1; end; if ($right (alt[0:1], i) != wdt(i )-1) begin $display("FAILED -- $right (alt[0:1], %0d) = %0d", i, $right (alt[0:1], i)); err=1; end; if ($low (alt[0:1], i) != 0 ) begin $display("FAILED -- $low (alt[0:1], %0d) = %0d", i, $low (alt[0:1], i)); err=1; end; if ($high (alt[0:1], i) != wdt(i )-1) begin $display("FAILED -- $high (alt[0:1], %0d) = %0d", i, $high (alt[0:1], i)); err=1; end; if ($increment(alt[0:1], i) != -1 ) begin $display("FAILED -- $increment(alt[0:1], %0d) = %0d", i, $increment(alt[0:1], i)); err=1; end; if ($size (alt[0:1], i) != wdt(i ) ) begin $display("FAILED -- $size (alt[0:1], %0d) = %0d", i, $size (alt[0:1], i)); err=1; end; end // single array element if ($dimensions(alt[0]) != 2) begin $display("FAILED -- $dimensions(alt) = %0d", $dimensions(alt)); err=1; end; if ($bits (alt[0]) != WB*WC) begin $display("FAILED -- $bits (alt) = %0d", $bits (alt)); err=1; end; for (i=1; i<=2; i=i+1) begin if ($left (alt[0] , i) != 0 ) begin $display("FAILED -- $left (alt[0] , %0d) = %0d", i, $left (alt[0] , i)); err=1; end; if ($right (alt[0] , i) != wdt(i+1)-1) begin $display("FAILED -- $right (alt[0] , %0d) = %0d", i, $right (alt[0] , i)); err=1; end; if ($low (alt[0] , i) != 0 ) begin $display("FAILED -- $low (alt[0] , %0d) = %0d", i, $low (alt[0] , i)); err=1; end; if ($high (alt[0] , i) != wdt(i+1)-1) begin $display("FAILED -- $high (alt[0] , %0d) = %0d", i, $high (alt[0] , i)); err=1; end; if ($increment(alt[0] , i) != -1 ) begin $display("FAILED -- $increment(alt[0] , %0d) = %0d", i, $increment(alt[0] , i)); err=1; end; if ($size (alt[0] , i) != wdt(i+1) ) begin $display("FAILED -- $size (alt[0] , %0d) = %0d", i, $size (alt[0] , i)); err=1; end; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/array_packed_value_list.v000066400000000000000000000073631435245347300236160ustar00rootroot00000000000000// This tests assigning value lists to packed arrays // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // parameters for array sizes localparam WA = 4; localparam WB = 4; // 2D packed arrays logic [WA-1:0] [WB-1:0] abg0, abg1, abg2, abg3, abg4, abg5, abg6, abg7, abg8, abg9; // big endian array logic [0:WA-1] [0:WB-1] alt0, alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8, alt9; // little endian array // error counter bit err = 0; initial begin abg0 = '{ 3 ,2 ,1, 0 }; abg1 = '{0:4, 1:5, 2:6, 3:7}; abg2 = '{default:13}; abg3 = '{2:15, default:13}; abg4 = '{WA { {WB/2 {2'b10}} }}; abg5 = '{WA { {3'b101, {WB/2-1{2'b10}}} }}; abg6 = '{WA { {WB/2-1{2'b10}} }}; abg7 [WA/2-1:0 ] = '{WA/2{ {WB/2 {2'b10}} }}; abg8 [WA -1:WA/2] = '{WA/2{ {WB/2 {2'b01}} }}; abg9 = '{err+0, err+1, err+2, err+3}; // check if (abg0 !== 16'b0011_0010_0001_0000) begin $display("FAILED -- abg0 = 'b%b", abg0); err=1; end if (abg1 !== 16'b0111_0110_0101_0100) begin $display("FAILED -- abg1 = 'b%b", abg1); err=1; end if (abg2 !== 16'b1101_1101_1101_1101) begin $display("FAILED -- abg2 = 'b%b", abg2); err=1; end if (abg3 !== 16'b1101_1111_1101_1101) begin $display("FAILED -- abg3 = 'b%b", abg3); err=1; end if (abg4 !== 16'b1010_1010_1010_1010) begin $display("FAILED -- abg4 = 'b%b", abg4); err=1; end if (abg5 !== 16'b0110_0110_0110_0110) begin $display("FAILED -- abg5 = 'b%b", abg5); err=1; end if (abg6 !== 16'b0010_0010_0010_0010) begin $display("FAILED -- abg6 = 'b%b", abg6); err=1; end if (abg7 !== 16'bxxxx_xxxx_1010_1010) begin $display("FAILED -- abg7 = 'b%b", abg7); err=1; end if (abg8 !== 16'b1010_1010_xxxx_xxxx) begin $display("FAILED -- abg8 = 'b%b", abg8); err=1; end if (abg9 !== 16'b0000_0001_0010_0011) begin $display("FAILED -- abg9 = 'b%b", abg9); err=1; end alt0 = '{ 3 ,2 ,1, 0 }; alt1 = '{0:4, 1:5, 2:6, 3:7}; alt2 = '{default:13}; alt3 = '{2:15, default:13}; alt4 = '{WA { {WB/2 {2'b10}} }}; alt5 = '{WA { {3'b101, {WB/2-1{2'b10}}} }}; alt6 = '{WA { {WB/2-1{2'b10}} }}; alt7 [0 :WA/2-1] = '{WA/2{ {WB/2 {2'b10}} }}; alt8 [WA/2:WA -1] = '{WA/2{ {WB/2 {2'b01}} }}; alt9 = '{err+0, err+1, err+2, err+3}; // check if (alt0 !== 16'b0011_0010_0001_0000) begin $display("FAILED -- alt0 = 'b%b", alt0); err=1; end if (alt1 !== 16'b0100_0101_0110_0111) begin $display("FAILED -- alt1 = 'b%b", alt1); err=1; end if (alt2 !== 16'b1101_1101_1101_1101) begin $display("FAILED -- alt2 = 'b%b", alt2); err=1; end if (alt3 !== 16'b1101_1101_1111_1101) begin $display("FAILED -- alt3 = 'b%b", alt3); err=1; end if (alt4 !== 16'b1010_1010_1010_1010) begin $display("FAILED -- alt4 = 'b%b", alt4); err=1; end if (alt5 !== 16'b0110_0110_0110_0110) begin $display("FAILED -- alt5 = 'b%b", alt5); err=1; end if (alt6 !== 16'b0010_0010_0010_0010) begin $display("FAILED -- alt6 = 'b%b", alt6); err=1; end if (alt7 !== 16'b1010_1010_xxxx_xxxx) begin $display("FAILED -- alt7 = 'b%b", alt7); err=1; end if (alt8 !== 16'bxxxx_xxxx_1010_1010) begin $display("FAILED -- alt8 = 'b%b", alt8); err=1; end if (alt9 !== 16'b0000_0001_0010_0011) begin $display("FAILED -- alt9 = 'b%b", alt9); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/array_packed_write_read.v000066400000000000000000000574451435245347300236020ustar00rootroot00000000000000// This tests unalligned write/read access to packed arrays // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // parameters for array sizes localparam WA = 4; localparam WB = 4; // 2D packed array parameters // localparam [WA-1:0] [WB-1:0] param_bg = {WA*WB{1'b1}}; // 2D packed arrays logic [WA-1:0] [WB-1:0] abg0, abg1, abg2, abg3, abg4, abg5, abg6, abg7, abg8, abg9; // big endian array logic [0:WA-1] [0:WB-1] alt0, alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8, alt9; // little endian array logic [WA*WB:0] a1d0, a1d1, a1d2, a1d3, a1d4, a1d5, a1d6, a1d7, a1d8, a1d9; // 1D array logic signed [WA-1:0] [WB-1:0] asg0, asg1, asg2, asg3, asg4, asg5, asg6, asg7, asg8, asg9; // signed big endian array // error counter bit err = 0; initial begin // test write to array LHS=RHS abg0 = {WA*WB{1'bx}}; abg1 = {WA*WB{1'bx}}; abg1 = {WA *WB +0{1'b1}}; abg2 = {WA*WB{1'bx}}; abg2 [WA/2-1:0 ] = {WA/2*WB +0{1'b1}}; abg3 = {WA*WB{1'bx}}; abg3 [WA -1:WA/2] = {WA/2*WB +0{1'b1}}; abg4 = {WA*WB{1'bx}}; abg4 [ 0 ] = {1 *WB +0{1'b1}}; abg5 = {WA*WB{1'bx}}; abg5 [WA -1 ] = {1 *WB +0{1'b1}}; abg6 = {WA*WB{1'bx}}; abg6 [ 0 ][WB/2-1:0 ] = {1 *WB/2+0{1'b1}}; abg7 = {WA*WB{1'bx}}; abg7 [WA -1 ][WB -1:WB/2] = {1 *WB/2+0{1'b1}}; abg8 = {WA*WB{1'bx}}; abg8 [ 0 ][ 0 ] = {1 *1 +0{1'b1}}; abg9 = {WA*WB{1'bx}}; abg9 [WA -1 ][WB -1 ] = {1 *1 +0{1'b1}}; // check if (abg0 !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- abg0 = 'b%b", abg0); err=1; end if (abg1 !== 16'b1111_1111_1111_1111) begin $display("FAILED -- L=R -- abg1 = 'b%b", abg1); err=1; end if (abg2 !== 16'bxxxx_xxxx_1111_1111) begin $display("FAILED -- L=R -- abg2 = 'b%b", abg2); err=1; end if (abg3 !== 16'b1111_1111_xxxx_xxxx) begin $display("FAILED -- L=R -- abg3 = 'b%b", abg3); err=1; end if (abg4 !== 16'bxxxx_xxxx_xxxx_1111) begin $display("FAILED -- L=R -- abg4 = 'b%b", abg4); err=1; end if (abg5 !== 16'b1111_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- abg5 = 'b%b", abg5); err=1; end if (abg6 !== 16'bxxxx_xxxx_xxxx_xx11) begin $display("FAILED -- L=R -- abg6 = 'b%b", abg6); err=1; end if (abg7 !== 16'b11xx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- abg7 = 'b%b", abg7); err=1; end if (abg8 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L=R -- abg8 = 'b%b", abg8); err=1; end if (abg9 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- abg9 = 'b%b", abg9); err=1; end // test write to array LHSR -- abg0 = 'b%b", abg0); err=1; end if (abg1 !== 16'b0111_1111_1111_1111) begin $display("FAILED -- L>R -- abg1 = 'b%b", abg1); err=1; end if (abg2 !== 16'bxxxx_xxxx_0111_1111) begin $display("FAILED -- L>R -- abg2 = 'b%b", abg2); err=1; end if (abg3 !== 16'b0111_1111_xxxx_xxxx) begin $display("FAILED -- L>R -- abg3 = 'b%b", abg3); err=1; end if (abg4 !== 16'bxxxx_xxxx_xxxx_0111) begin $display("FAILED -- L>R -- abg4 = 'b%b", abg4); err=1; end if (abg5 !== 16'b0111_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- abg5 = 'b%b", abg5); err=1; end if (abg6 !== 16'bxxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R -- abg6 = 'b%b", abg6); err=1; end if (abg7 !== 16'b01xx_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- abg7 = 'b%b", abg7); err=1; end //if (abg8 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L>R -- abg8 = 'b%b", abg8); err=1; end //if (abg9 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- abg9 = 'b%b", abg9); err=1; end // test write to array LHS=RHS alt0 = {WA*WB{1'bx}}; alt1 = {WA*WB{1'bx}}; alt1 = {WA *WB +0{1'b1}}; alt2 = {WA*WB{1'bx}}; alt2 [0 :WA/2-1] = {WA/2*WB +0{1'b1}}; alt3 = {WA*WB{1'bx}}; alt3 [WA/2:WA -1] = {WA/2*WB +0{1'b1}}; alt4 = {WA*WB{1'bx}}; alt4 [0 ] = {1 *WB +0{1'b1}}; alt5 = {WA*WB{1'bx}}; alt5 [ WA -1] = {1 *WB +0{1'b1}}; alt6 = {WA*WB{1'bx}}; alt6 [0 ][0 :WB/2-1] = {1 *WB/2+0{1'b1}}; alt7 = {WA*WB{1'bx}}; alt7 [ WA -1][WB/2:WB -1] = {1 *WB/2+0{1'b1}}; alt8 = {WA*WB{1'bx}}; alt8 [0 ][0 ] = {1 *1 +0{1'b1}}; alt9 = {WA*WB{1'bx}}; alt9 [ WA -1][ WB -1] = {1 *1 +0{1'b1}}; // check if (alt0 !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- alt0 = 'b%b", alt0); err=1; end if (alt1 !== 16'b1111_1111_1111_1111) begin $display("FAILED -- L=R -- alt1 = 'b%b", alt1); err=1; end if (alt2 !== 16'b1111_1111_xxxx_xxxx) begin $display("FAILED -- L=R -- alt2 = 'b%b", alt2); err=1; end if (alt3 !== 16'bxxxx_xxxx_1111_1111) begin $display("FAILED -- L=R -- alt3 = 'b%b", alt3); err=1; end if (alt4 !== 16'b1111_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- alt4 = 'b%b", alt4); err=1; end if (alt5 !== 16'bxxxx_xxxx_xxxx_1111) begin $display("FAILED -- L=R -- alt5 = 'b%b", alt5); err=1; end if (alt6 !== 16'b11xx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- alt6 = 'b%b", alt6); err=1; end if (alt7 !== 16'bxxxx_xxxx_xxxx_xx11) begin $display("FAILED -- L=R -- alt7 = 'b%b", alt7); err=1; end if (alt8 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L=R -- alt8 = 'b%b", alt8); err=1; end if (alt9 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L=R -- alt9 = 'b%b", alt9); err=1; end // test write to array LHSR -- alt0 = 'b%b", alt0); err=1; end if (alt1 !== 16'b0111_1111_1111_1111) begin $display("FAILED -- L>R -- alt1 = 'b%b", alt1); err=1; end if (alt2 !== 16'b0111_1111_xxxx_xxxx) begin $display("FAILED -- L>R -- alt2 = 'b%b", alt2); err=1; end if (alt3 !== 16'bxxxx_xxxx_0111_1111) begin $display("FAILED -- L>R -- alt3 = 'b%b", alt3); err=1; end if (alt4 !== 16'b0111_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- alt4 = 'b%b", alt4); err=1; end if (alt5 !== 16'bxxxx_xxxx_xxxx_0111) begin $display("FAILED -- L>R -- alt5 = 'b%b", alt5); err=1; end if (alt6 !== 16'b01xx_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- alt6 = 'b%b", alt6); err=1; end if (alt7 !== 16'bxxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R -- alt7 = 'b%b", alt7); err=1; end //if (alt8 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- L>R -- alt8 = 'b%b", alt8); err=1; end //if (alt9 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L>R -- alt9 = 'b%b", alt9); err=1; end // assign a constant value to the array abg1 = {WA*WB{1'b1}}; abg2 = {WA*WB{1'b1}}; abg3 = {WA*WB{1'b1}}; abg4 = {WA*WB{1'b1}}; abg5 = {WA*WB{1'b1}}; abg6 = {WA*WB{1'b1}}; abg7 = {WA*WB{1'b1}}; abg8 = {WA*WB{1'b1}}; abg9 = {WA*WB{1'b1}}; // test read from array LHS=RHS a1d1 = {WA*WB+1{1'bx}}; a1d1[WA *WB -1+0:0] = abg1 ; a1d2 = {WA*WB+1{1'bx}}; a1d2[WA/2*WB -1+0:0] = abg2 [WA/2-1:0 ] ; a1d3 = {WA*WB+1{1'bx}}; a1d3[WA/2*WB -1+0:0] = abg3 [WA -1:WA/2] ; a1d4 = {WA*WB+1{1'bx}}; a1d4[1 *WB -1+0:0] = abg4 [ 0 ] ; a1d5 = {WA*WB+1{1'bx}}; a1d5[1 *WB -1+0:0] = abg5 [WA -1 ] ; a1d6 = {WA*WB+1{1'bx}}; a1d6[1 *WB/2-1+0:0] = abg6 [ 0 ][WB/2-1:0 ]; a1d7 = {WA*WB+1{1'bx}}; a1d7[1 *WB/2-1+0:0] = abg7 [WA -1 ][WB -1:WB/2]; a1d8 = {WA*WB+1{1'bx}}; a1d8[1 *1 -1+0:0] = abg8 [ 0 ][ 0 ]; a1d9 = {WA*WB+1{1'bx}}; a1d9[1 *1 -1+0:0] = abg9 [WA -1 ][WB -1 ]; // check if (a1d1 !== 17'bx_1111_1111_1111_1111) begin $display("FAILED -- L=R BE -- a1d1 = 'b%b", a1d1); err=1; end if (a1d2 !== 17'bx_xxxx_xxxx_1111_1111) begin $display("FAILED -- L=R BE -- a1d2 = 'b%b", a1d2); err=1; end if (a1d3 !== 17'bx_xxxx_xxxx_1111_1111) begin $display("FAILED -- L=R BE -- a1d3 = 'b%b", a1d3); err=1; end if (a1d4 !== 17'bx_xxxx_xxxx_xxxx_1111) begin $display("FAILED -- L=R BE -- a1d4 = 'b%b", a1d4); err=1; end if (a1d5 !== 17'bx_xxxx_xxxx_xxxx_1111) begin $display("FAILED -- L=R BE -- a1d5 = 'b%b", a1d5); err=1; end if (a1d6 !== 17'bx_xxxx_xxxx_xxxx_xx11) begin $display("FAILED -- L=R BE -- a1d6 = 'b%b", a1d6); err=1; end if (a1d7 !== 17'bx_xxxx_xxxx_xxxx_xx11) begin $display("FAILED -- L=R BE -- a1d7 = 'b%b", a1d7); err=1; end if (a1d8 !== 17'bx_xxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L=R BE -- a1d8 = 'b%b", a1d8); err=1; end if (a1d9 !== 17'bx_xxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- L=R BE -- a1d9 = 'b%b", a1d9); err=1; end // test read from array LHS>RHS a1d1 = {WA*WB+1{1'bx}}; a1d1[WA *WB -1+1:0] = abg1 ; a1d2 = {WA*WB+1{1'bx}}; a1d2[WA/2*WB -1+1:0] = abg2 [WA/2-1:0 ] ; a1d3 = {WA*WB+1{1'bx}}; a1d3[WA/2*WB -1+1:0] = abg3 [WA -1:WA/2] ; a1d4 = {WA*WB+1{1'bx}}; a1d4[1 *WB -1+1:0] = abg4 [ 0 ] ; a1d5 = {WA*WB+1{1'bx}}; a1d5[1 *WB -1+1:0] = abg5 [WA -1 ] ; a1d6 = {WA*WB+1{1'bx}}; a1d6[1 *WB/2-1+1:0] = abg6 [ 0 ][WB/2-1:0 ]; a1d7 = {WA*WB+1{1'bx}}; a1d7[1 *WB/2-1+1:0] = abg7 [WA -1 ][WB -1:WB/2]; a1d8 = {WA*WB+1{1'bx}}; a1d8[1 *1 -1+1:0] = abg8 [ 0 ][ 0 ]; a1d9 = {WA*WB+1{1'bx}}; a1d9[1 *1 -1+1:0] = abg9 [WA -1 ][WB -1 ]; // check if (a1d1 !== 17'b0_1111_1111_1111_1111) begin $display("FAILED -- L>R BE -- a1d1 = 'b%b", a1d1); err=1; end if (a1d2 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- L>R BE -- a1d2 = 'b%b", a1d2); err=1; end if (a1d3 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- L>R BE -- a1d3 = 'b%b", a1d3); err=1; end if (a1d4 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- L>R BE -- a1d4 = 'b%b", a1d4); err=1; end if (a1d5 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- L>R BE -- a1d5 = 'b%b", a1d5); err=1; end if (a1d6 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- L>R BE -- a1d6 = 'b%b", a1d6); err=1; end if (a1d7 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- L>R BE -- a1d7 = 'b%b", a1d7); err=1; end if (a1d8 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R BE -- a1d8 = 'b%b", a1d8); err=1; end if (a1d9 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R BE -- a1d9 = 'b%b", a1d9); err=1; end // test read from array LHSR LE -- a1d1 = 'b%b", a1d1); err=1; end if (a1d2 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- L>R LE -- a1d2 = 'b%b", a1d2); err=1; end if (a1d3 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- L>R LE -- a1d3 = 'b%b", a1d3); err=1; end if (a1d4 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- L>R LE -- a1d4 = 'b%b", a1d4); err=1; end if (a1d5 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- L>R LE -- a1d5 = 'b%b", a1d5); err=1; end if (a1d6 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- L>R LE -- a1d6 = 'b%b", a1d6); err=1; end if (a1d7 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- L>R LE -- a1d7 = 'b%b", a1d7); err=1; end if (a1d8 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R LE -- a1d8 = 'b%b", a1d8); err=1; end if (a1d9 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- L>R LE -- a1d9 = 'b%b", a1d9); err=1; end // test read from array LHS (real, index=0, thr.), expected 1.0, got %s", res); pass = 1'b0; end $sformat(res, "%3.1f", rarr[index]); if (res != "1.0") begin $display("Failed &A<> (real, index=0, sig.), expected 1.0, got %s", res); pass = 1'b0; end if (rarr[index] != 1.0) begin $display("Failed var select (real, index=0), expected 1.0"); pass = 1'b0; end $sformat(res, "%3b", arr[index+base]); if (res != "001") begin $display("Failed &A<> (reg, index=0, thr.), expected 001, got %s", res); pass = 1'b0; end $sformat(res, "%3b", arr[index]); if (res != "001") begin $display("Failed &A<> (reg, index=0, sig.), expected 001, got %s", res); pass = 1'b0; end if (arr[index] != 3'b001) begin $display("Failed var select (reg, index=0), expected 3'b001"); pass = 1'b0; end // Check an undefined array word select. index = 'bx; $sformat(res, "%3.1f", rarr[index+base]); if (res != "0.0") begin $display("Failed &A<> (real, index=x, thr.), expected 0.0, got %s", res); pass = 1'b0; end $sformat(res, "%3.1f", rarr[index]); if (res != "0.0") begin $display("Failed &A<> (real, index=x, sig.), expected 0.0, got %s", res); pass = 1'b0; end if (rarr[index] != 0.0) begin $display("Failed var select (real, index=x), expected 0.0"); pass = 1'b0; end $sformat(res, "%3b", arr[index+base]); if (res != "xxx") begin $display("Failed &A<> (reg, index=x, thr.), expected xxx, got %s", res); pass = 1'b0; end $sformat(res, "%3b", arr[index]); if (res != "xxx") begin $display("Failed &A<> (reg, index=x, sig.), expected xxx, got %s", res); pass = 1'b0; end if (arr[index] != 3'bxxx) begin $display("Failed var select (reg, index=x), expected 3'bxxx"); pass = 1'b0; end // Check a before the array word select. index = -1; $sformat(res, "%3.1f", rarr[index+base]); if (res != "0.0") begin $display("Failed &A<> (real, index=-1, thr.), expected 0.0, got %s", res); pass = 1'b0; end $sformat(res, "%3.1f", rarr[index]); if (res != "0.0") begin $display("Failed &A<> (real, index=-1, sig.), expected 0.0, got %s", res); pass = 1'b0; end if (rarr[index] != 0.0) begin $display("Failed var select (real, index=-1), expected 0.0"); pass = 1'b0; end $sformat(res, "%3b", arr[index+base]); if (res != "xxx") begin $display("Failed &A<> (reg, index=-1, thr.), expected xxx, got %s", res); pass = 1'b0; end $sformat(res, "%3b", arr[index]); if (res != "xxx") begin $display("Failed &A<> (reg, index=-1, sig.), expected xxx, got %s", res); pass = 1'b0; end if (arr[index] != 3'bxxx) begin $display("Failed var select (reg, index=-1), expected 3'bxxx"); pass = 1'b0; end // Check an after the array word select. index = 2; $sformat(res, "%3.1f", rarr[index+base]); if (res != "0.0") begin $display("Failed &A<> (real, index=2, thr.), expected 0.0, got %s", res); pass = 1'b0; end $sformat(res, "%3.1f", rarr[index]); if (res != "0.0") begin $display("Failed &A<> (real, index=2, sig.), expected 0.0, got %s", res); pass = 1'b0; end if (rarr[index] != 0.0) begin $display("Failed var select (real, index=2), expected 0.0"); pass = 1'b0; end $sformat(res, "%3b", arr[index+base]); if (res != "xxx") begin $display("Failed &A<> (reg, index=2, thr.), expected xxx, got %s", res); pass = 1'b0; end $sformat(res, "%3b", arr[index]); if (res != "xxx") begin $display("Failed &A<> (reg, index=2, sig.), expected xxx, got %s", res); pass = 1'b0; end if (arr[index] != 3'bxxx) begin $display("Failed var select (reg, index=2), expected 3'bxxx"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_size.v000066400000000000000000000010331435245347300210760ustar00rootroot00000000000000module test; parameter width = 16; localparam count = 1< // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for array querying functions for unpacked arrays // (IEEE Std 1800-2012 7.11) module array_unpacked_sysfunct(); bit [7:0] bit_darray []; //bit bit_darray []; // not available yet bit [7:0] array [2:4]; bit [7:0] reverse_array[5:3]; bit [2:8] packed_array; bit [4:1] reverse_packed_array; initial begin string test_msg = "13 characters"; bit_darray = new[5]; if($left(bit_darray) != 0 || $right(bit_darray) != 4) begin $display("FAILED 1"); $finish(); end if($left(array) != 2 || $right(array) != 4) begin $display("FAILED 2"); $finish(); end if($left(reverse_array) != 5 || $right(reverse_array) != 3) begin $display("FAILED 3"); $finish(); end if($left(test_msg) != 0 || $right(test_msg) != 12) begin $display("FAILED 4"); $finish(); end if($left(packed_array) != 2 || $right(packed_array) != 8) begin $display("FAILED 5"); $finish(); end if($left(reverse_packed_array) != 4 || $right(reverse_packed_array) != 1) begin $display("FAILED 6"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/array_word_check.v000066400000000000000000000005321435245347300222370ustar00rootroot00000000000000module top; reg [7:0] array [1:0]; reg \array[0] ; reg \array[1] ; integer idx; initial begin $dumpfile("work/dup.vcd"); $dumpvars(0, array[0]); idx = 1; $dumpvars(0, array[idx]); $dumpvars(0, top); array[0] = 8'd0; #1 array[0] = 8'd1; #1 \array[0] = 1'b1; \array[1] = 1'b0; end endmodule iverilog-12_0/ivtest/ivltests/array_word_width.v000066400000000000000000000002331435245347300222770ustar00rootroot00000000000000module top; reg [15:0] array [1:0]; initial begin array[1] = 15'd48; // This should display 0003 $displayh(array[1]>>4); end endmodule iverilog-12_0/ivtest/ivltests/array_word_width2.v000066400000000000000000000005141435245347300223630ustar00rootroot00000000000000module top; wire [3:0] array [1:0]; integer sel; assign array[0] = 4'h0; assign array[1] = 4'h1; initial begin #1; $display(" %h %h", array[0], array[1]); // This is only a problem for a wire (net array)! sel = 0; $display(" %h %h", array[sel], array[sel+1]); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign3.2A.v000066400000000000000000000036461435245347300205520ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate assign identifier = expression ; module main ; wire a; wire [31:0] b; wire [15:0] c; reg [31:0] val; reg error; assign a = val [0]; // Pull single bit assign b = val; // full variable assign c = val[31:16]; // Top portion bit select initial begin error = 0; if(a != 1'bx) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(b != 32'bx) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(c != 16'bx) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end #1 ; val = 32'h87654321; #1 ; if(a != 1'b1) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(b != 32'h87654321) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(c != 16'h8765) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(error == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/assign3.2B.v000066400000000000000000000036611435245347300205500ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate assign { ident0, ident1 } = expression ; module main ; wire a; wire [30:0] b; wire [14:0] c; reg [31:0] val; reg error; assign {b,a} = val; // full variable assign {c,a} = val[31:16]; // Top portion bit select initial begin error = 0; if(a != 1'bx) begin $display("FAILED - assign 3.2B assign ident = expr"); error = 1; end if(b != 31'bx) begin $display("FAILED - assign 3.2B assign ident = expr"); error = 1; end if(c != 14'bx) begin $display("FAILED - assign 3.2B assign ident = expr"); error = 1; end #1 ; val = 32'h87654321; #1 ; if(a != 1'b1) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(b != (32'h87654321) >> 1) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(c != (16'h8765) >> 1) begin $display("FAILED - 3.2A assign ident = expr"); error = 1; end if(error == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/assign3.2C.v000066400000000000000000000035241435245347300205470ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate assign procedural assign ident = expr; module main ; reg [31:0] value; reg control; reg clock; reg error; always @(posedge clock) value = 3; always @(control) if(control) assign value = 2; else deassign value ; // Setup a clock generator. always begin #2; clock = ~clock; end initial begin clock = 0; error = 0; # 3; if(value != 3) begin $display("FAILED - assign3.2C - procedural assignment(1)"); error = 1; end # 2; control = 1; # 1; if(value != 2) begin $display("FAILED - assign3.2C - procedural assignment(2)"); error = 1; end # 3 ; control = 0; # 2; if(value != 3) begin $display("FAILED - assign3.2C - procedural assignment(3)"); error = 1; end if(error == 0) $display ("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/assign3.2D.v000066400000000000000000000035751435245347300205560ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate assign procedural assign {ident1,ident0} = expr; module main ; reg a,b,c,d; reg control; reg clock; reg error; always @(posedge clock) {a,b,c,d} = 4'h3; always @(control) if(control) assign {a,b,c,d} = 4'h2; else deassign {a,b,c,d} ; // Setup a clock generator. always begin #2; clock = ~clock; end initial begin clock = 0; error = 0; # 3; if({a,b,c,d} !== 3) begin $display("FAILED - assign3.2D - procedural assignment(1)"); error = 1; end # 2; control = 1; # 1; if({a,b,c,d} !== 2) begin $display("FAILED - assign3.2D - procedural assignment(2)"); error = 1; end # 3 ; control = 0; # 2; if({a,b,c,d} !== 3) begin $display("FAILED - assign3.2D - procedural assignment(3)"); error = 1; end if(error == 0) $display ("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/assign3.2E.v000066400000000000000000000037151435245347300205530ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate assign procedural assign {ident[1],ident[0]} = expr ERR; module main ; reg [31:0] value; reg control; reg clock; reg error; always @(posedge clock) {value[3],value[2],value[1],value[0]} = 3; always @(control) if(control) assign {value[3],value[2],value[1],value[0]} = 4'h2; else deassign {value[3],value[2],value[1],value[0]} ; // Setup a clock generator. always begin #2; clock = ~clock; end initial begin clock = 0; error = 0; # 3; if(value != 3) begin $display("FAILED - assign3.2E - procedural assignment(1)"); error = 1; end # 2; control = 1; # 1; if(value != 2) begin $display("FAILED - assign3.2E - procedural assignment(2)"); error = 1; end # 3 ; control = 0; # 2; if(value != 3) begin $display("FAILED - assign3.2E - procedural assignment(3)"); error = 1; end if(error == 0) $display ("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/assign_add.v000066400000000000000000000005441435245347300210300ustar00rootroot00000000000000/* * assign_sum * Demonstrate continuous assign of a sum. */ module main; reg [8:0] A, B; wire [9:0] sum = A + B; initial begin A = 51; B = 39; #1 $display("%b + %b = %b", A, B, sum); if (sum !== 90) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/assign_deassign_pv.v000066400000000000000000000031161435245347300226000ustar00rootroot00000000000000module test; reg fail = 1'b0; reg [3:0] bus = 4'b0; initial begin // Check the initial value. if (bus !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", bus); fail = 1'b1; end // Check a bit assign and verify a normal bit assign does nothing. #1 assign bus[0] = 1'b1; bus[0] = 1'bz; if (bus !== 4'b0001) begin $display("FAILED: assign of bus[0], got %b, expected 0001.", bus); fail = 1'b1; end // Check a part assign. #1 assign bus[3:2] = 2'b11; if (bus !== 4'b1101) begin $display("FAILED: assign of bus[3:2], got %b, expected 1101.", bus); fail = 1'b1; end // Check that we can change an unassigned bit. #1 bus[1] = 1'bz; if (bus !== 4'b11z1) begin $display("FAILED: assignment of bus[1], got %b, expected 11z1.", bus); fail = 1'b1; end // Check a bit deassign. #1 deassign bus[0]; bus = 4'b000z; if (bus !== 4'b110z) begin $display("FAILED: deassign of bus[0], got %b, expected 110z.", bus); fail = 1'b1; end // Check a part deassign (we keep the old value if not changed). #1 deassign bus[3:2]; bus[3] = 1'b0; if (bus !== 4'b010z) begin $display("FAILED: deassign of bus[3:2], got %b, expected 010z.", bus); fail = 1'b1; end // Check an assign from the upper thread bits >= 8. #1 assign bus[2:1] = 2'bx1; if (bus !== 4'b0x1z) begin $display("FAILED: assign of bus[2:1], got %b, expected 0x1z.", bus); fail = 1'b1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_delay.v000066400000000000000000000025421435245347300213760ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test captures the essence of PR#40, namely the possibility * that the continuous assign from a reg to a wire may have a delay. */ module test; wire a; reg b; assign #10 a = b; initial begin b = 0; # 20 b = 1; # 5 if (a !== 0) begin $display("FAILED -- a is %b", a); $finish; end # 6 if (a !== 1) begin $display("FAILED -- a is %b, should be 1", a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_deq.v000066400000000000000000000027141435245347300210520ustar00rootroot00000000000000/* * Copyright (c) 2000 Steven Wilson (stevew@homeaddress.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test looks for == operation in a continuous assignment. */ module test; integer a; integer b; wire result; integer error; assign result = (a == b); initial begin a = 0; b = 0; error = 0; #5 ; if( result !== 1'b1) error =1; a = 1; #5; if( result !== 1'b0) error =1; b = 1; #5 ; if( result !== 1'b1) error =1; a = 1002; b = 1001; #5 ; if( result !== 1'b0) error =1; a = 1001; #5 ; if( result !== 1'b1) error =1; if(error === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_ge.v000066400000000000000000000027141435245347300206740ustar00rootroot00000000000000/* * Copyright (c) 2000 Steven Wilson (stevew@homeaddress.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test looks for >= operation in a continuous assignment. */ module test; integer a; integer b; wire result; integer error; assign result = (a >= b); initial begin a = 0; b = 0; error = 0; #5 ; if( result !== 1'b1) error =1; a = 1; #5; if( result !== 1'b1) error =1; b = 1; #5 ; if( result !== 1'b1) error =1; a = 1001; b = 1002; #5 ; if( result !== 1'b0) error =1; a = 1003; #5 ; if( result !== 1'b1) error =1; if(error === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_le.v000066400000000000000000000027141435245347300207010ustar00rootroot00000000000000/* * Copyright (c) 2000 Steven Wilson (stevew@homeaddress.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test looks for <= operation in a continuous assignment. */ module test; integer a; integer b; wire result; integer error; assign result = (a <= b); initial begin a = 0; b = 0; error = 0; #5 ; if( result !== 1'b1) error =1; a = 1; #5; if( result !== 1'b0) error =1; b = 1; #5 ; if( result !== 1'b1) error =1; a = 1001; b = 1002; #5 ; if( result !== 1'b1) error =1; a = 1003; #5 ; if( result !== 1'b0) error =1; if(error === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_mem1.v000066400000000000000000000022541435245347300211370ustar00rootroot00000000000000/* * Copyright (c) 2000 Chris Lattner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This isn't computationally complicated, but can trip up a vvm * code generation error. */ module test; reg [15:0] is[1:0]; reg [4:0] i; initial begin i = 0; is[0] = i; // Notice the different widths. if (is[0] !== 16'd0) begin $display("FAILED -- is[0] --> %b", is[0]); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_mem2.v000066400000000000000000000021731435245347300211400ustar00rootroot00000000000000/* * Copyright (c) 2000 Chris Lattner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; reg [31:0] buff[256*2*2-1:0]; reg [31:0] x; initial begin buff[0] = 0; x = 256; buff[x+0] = 1234; if (buff[0] != 0) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_nb1.v000066400000000000000000000025301435245347300207550ustar00rootroot00000000000000/* * Copyright (c) 2000 Peter monta (pmonta@pacbell.net) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // Reworked by SDW to be self checking module main; reg [7:0] x; reg [7:0] y; reg [2:0] i; // Was a wire.. reg error; initial begin #5; x[i] <= #1 0; y[i] = 0; end initial begin error = 0; #1; i = 1; #7; if(x[i] !== 1'b0) begin $display("FAILED - x[1] != 0"); error = 1; end if(y[i] !== 1'b0) begin $display("FAILED - y[1] != 0"); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_nb2.v000066400000000000000000000025771435245347300207710ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Catch problems with non-zero lsb values in l-value expressions. */ module main; reg [7:1] a = 6'b111111; reg [7:1] b = 6'b000010; integer q; reg [7:1] x; reg PCLK = 1; always @(posedge PCLK) for (q=1; q<=7; q=q+1) x[q] <= #1 a[q] & b[q]; always #5 PCLK = !PCLK; initial begin // $dumpfile("dump.vcd"); // $dumpvars(0, main); #50 $display("done: x=%b", x); if (x !== 6'b000010) $display("FAILED -- x = %b", x); else $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/assign_neq.v000066400000000000000000000027141435245347300210640ustar00rootroot00000000000000/* * Copyright (c) 2000 Steven Wilson (stevew@homeaddress.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test looks for != operation in a continuous assignment. */ module test; integer a; integer b; wire result; integer error; assign result = (a != b); initial begin a = 0; b = 0; error = 0; #5 ; if( result === 1'b1) error =1; a = 1; #5; if( result === 1'b0) error =1; b = 1; #5 ; if( result === 1'b1) error =1; a = 1002; b = 1001; #5 ; if( result === 1'b0) error =1; a = 1001; #5 ; if( result === 1'b1) error =1; if(error === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_op_after_cmp1.v000066400000000000000000000010411435245347300230100ustar00rootroot00000000000000// Check that a assignment operator on an integer array entry with an immediate // index works if it happes after a comparison that sets vvp flag 4 to 0. module test; logic [7:0] x[10]; logic a = 1'b0; initial begin x[0] = 10; if (a == 0) begin // Make sure that this update happens, even though the compare above // cleared set vvp flag 4 x[0] += 1; end if (x[0] == 11) begin $display("PASSED"); end else begin $display("FAILED. Expected 11, got %0d", x[0]); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_after_cmp2.v000066400000000000000000000007621435245347300230220ustar00rootroot00000000000000// Check that a assignment operator on a dynamic part select of an vector works // if it happes after a comparison that sets vvp flag 4 to 0. module test; logic [7:0] a = 8'h0; initial begin if (a == 0) begin // Make sure that this update happens, even though the compare above // cleared set vvp flag 4 a[a+:1] += 1; end if (a == 1) begin $display("PASSED"); end else begin $display("FAILED. Expected 1, got %0d", a); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_after_cmp3.v000066400000000000000000000010421435245347300230130ustar00rootroot00000000000000// Check that a assignment operator on an real array entry with an immediate // index works if it happes after a comparison that sets vvp flag 4 to 0. module test; real r[1:0]; logic a = 1'b0; initial begin r[0] = 8.0; if (a == 0) begin // Make sure that this update happens, even though the compare above // cleared set vvp flag 4 r[0] *= 2.0; end if (r[0] == 16.0) begin $display("PASSED"); end else begin $display("FAILED. Expected %f, got %f", 16.0, r[0]); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_concat.v000066400000000000000000000005731435245347300222470ustar00rootroot00000000000000module test(); reg [3:0] count; reg carry; reg failed = 0; integer i; initial begin {carry, count} = 0; for (i = 0; i < 32; i += 1) begin $display("%b %b", carry, count); if (count !== i[3:0]) failed = 1; if (carry !== i[4]) failed = 1; {carry, count} += 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/assign_op_oob.v000066400000000000000000000016721435245347300215600ustar00rootroot00000000000000// Check that the assignment operator is supported for out-of-bounds indices. // The write should be skipped, but side effects of the right-hand side // expression should still get evaluated. module test; // Check that wider than 32 works logic [39:0] a[1:0]; integer i; logic [39:0] j = 0; function logic [39:0] f; j++; return j; endfunction initial begin a[0] = 23; a[1] = 42; // Immediate out-of-bounds indices a[-1] += f(); a[2] += f(); a['hx] += f(); // Variable out-of-bounds indices i = -1; a[i] += f(); i = 2; a[i] += f(); i = 'hx; a[i] += f(); // Check that the in-bounds elements do not get affected by out-of-bounds // updates. Check that the left-hand side of the operator assignment gets // evaluated. if (a[0] == 23 && a[1] == 42 && j == 6) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_real_array.v000066400000000000000000000010771435245347300231210ustar00rootroot00000000000000// Check that assignment operators on real arrays are supported. module test; real r[1:0]; integer i = 1; initial begin // Immediate index r[0] = 8.0; r[0] += 1.0; r[0] -= 2.0; r[0] *= 3.0; r[0] /= 7.0; r[0]++; r[0]--; // Variable index r[i] = 8.0; r[i] += 1.0; r[i] -= 2.0; r[i] *= 3.0; r[i] /= 7.0; r[i]++; r[i]--; if (r[0] == 3.0 && r[1] == 3.0) begin $display("PASSED"); end else begin $display("FAILED. Expected %f, got %f and %f", 3.0, r[0], r[1]); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_real_array_oob.v000066400000000000000000000016371435245347300237620ustar00rootroot00000000000000// Check that the assignment operator is supported for out-of-bounds indices on // real arrays. The write should be skipped, but side effects of the right-hand // side expression should still get evaluated. module test; real a[1:0]; integer i; real r = 0; function real f; r += 0.125; return r; endfunction initial begin a[0] = 23.0; a[1] = 42.0; // Immediate out-of-bounds indices a[-1] += f(); a[2] += f(); a['hx] += f(); // Variable out-of-bounds indices i = -1; a[i] += f(); i = 2; a[i] += f(); i = 'hx; a[i] += f(); // Check that the in-bounds elements do not get affected by out-of-bounds // updates. Check that the left-hand side of the operator assignment gets // evaluated. if (a[0] == 23.0 && a[1] == 42.0 && r == 0.75) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/assign_op_type.v000066400000000000000000000010161435245347300217520ustar00rootroot00000000000000module test(); reg signed [3:0] a; reg [7:0] b; reg signed [7:0] c; reg signed [7:0] d; reg signed [7:0] e; reg failed = 0; initial begin a = -1; b = 4; c = 4; d = 4; e = 4; b += a; c += a; {d} += a; e[7:0] += a; $display("%0d", b); if (b !== 19) failed = 1; $display("%0d", c); if (c !== 3) failed = 1; $display("%0d", d); if (d !== 19) failed = 1; $display("%0d", e); if (e !== 19) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib.v000066400000000000000000000012411435245347300202140ustar00rootroot00000000000000// This test program is mostly about the parser parsing the attribute // attached to the main.dut.Q reg below. module main; reg CK; always begin #10 CK = 0; #10 CK = 1; end reg [3:0] D; wire [3:0] Q; test dut (.Q(Q), .D(D), .CK(CK)); initial begin D = 0; @(posedge CK) #1 $display("Q=%b, D=%b", Q, D); if (Q !== D) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main module test (Q, D, CK); output [3:0] Q; input [3:0] D; input CK; (* REGISTER_DUPLICATION = "no" *) reg [3:0] Q; always @(posedge CK) Q <= D; endmodule // test iverilog-12_0/ivtest/ivltests/attrib01_module.v000066400000000000000000000007101435245347300217220ustar00rootroot00000000000000(* this_is_module_bar *) module bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output reg out; always @(posedge clk) if (rst) out <= 1'd0; else out <= ~inp; endmodule (* this_is_module_foo *) module foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; bar bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib02_port_decl.v000066400000000000000000000010111435245347300224040ustar00rootroot00000000000000module bar(clk, rst, inp, out); (* this_is_clock = 1 *) input wire clk; (* this_is_reset = 1 *) input wire rst; input wire inp; (* an_output_register = 1*) output reg out; always @(posedge clk) if (rst) out <= 1'd0; else out <= ~inp; endmodule module foo(clk, rst, inp, out); (* this_is_the_master_clock *) input wire clk; input wire rst; input wire inp; output wire out; bar bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib03_parameter.v000066400000000000000000000011001435245347300224110ustar00rootroot00000000000000module bar(clk, rst, inp, out); (* bus_width *) parameter WIDTH = 2; (* an_attribute_on_localparam = 55 *) localparam INCREMENT = 5; input wire clk; input wire rst; input wire [WIDTH-1:0] inp; output reg [WIDTH-1:0] out; always @(posedge clk) if (rst) out <= 0; else out <= inp + INCREMENT; endmodule module foo(clk, rst, inp, out); input wire clk; input wire rst; input wire [7:0] inp; output wire [7:0] out; bar # (.WIDTH(8)) bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib04_net_var.v000066400000000000000000000011111435245347300220720ustar00rootroot00000000000000module bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output reg out; (* this_is_a_prescaler *) reg [7:0] counter; (* temp_wire *) wire out_val; always @(posedge clk) counter <= counter + 1; assign out_val = inp ^ counter[4]; always @(posedge clk) if (rst) out <= 1'd0; else out <= out_val; endmodule module foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; bar bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib05_port_conn.v000066400000000000000000000010521435245347300224420ustar00rootroot00000000000000module bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output reg out; always @(posedge clk) if (rst) out <= 1'd0; else out <= ~inp; endmodule module foo(clk, rst, inp, out_a, out_b); input wire clk; input wire rst; input wire inp; output wire out_a; output wire out_b; bar bar_instance_1 ( (* this_is_clock *) .clk(clk), .rst(rst), .inp(inp), .out(out_a) ); bar bar_instance_2 ( clk, (* this_is_reset *) rst, inp, out_b ); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib06_operator_suffix.v000066400000000000000000000010341435245347300236610ustar00rootroot00000000000000module bar(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; input wire [7:0] inp_b; output reg [7:0] out; always @(posedge clk) if (rst) out <= 0; else out <= inp_a + (* ripple_adder *) inp_b; endmodule module foo(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; input wire [7:0] inp_b; output wire [7:0] out; bar bar_instance (clk, rst, inp_a, inp_b, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib07_func_call.v000066400000000000000000000007011435245347300223710ustar00rootroot00000000000000module foo(clk, rst, inp_a, inp_b, out); input wire clk; input wire rst; input wire [7:0] inp_a; input wire [7:0] inp_b; output reg [7:0] out; function [7:0] do_add; input [7:0] inp_a; input [7:0] inp_b; do_add = inp_a + inp_b; endfunction always @(posedge clk) if (rst) out <= 0; else out <= do_add (* combinational_adder *) (inp_a, inp_b); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib08_mod_inst.v000066400000000000000000000006661435245347300222720ustar00rootroot00000000000000module bar(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output reg out; always @(posedge clk) if (rst) out <= 1'd0; else out <= ~inp; endmodule module foo(clk, rst, inp, out); input wire clk; input wire rst; input wire inp; output wire out; (* my_module_instance = 99 *) bar bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib09_case.v000066400000000000000000000010231435245347300213560ustar00rootroot00000000000000module bar(clk, rst, inp, out); input wire clk; input wire rst; input wire [1:0] inp; output reg [1:0] out; always @(inp) (* full_case, parallel_case *) case(inp) 2'd0: out <= 2'd3; 2'd1: out <= 2'd2; 2'd2: out <= 2'd1; 2'd3: out <= 2'd0; endcase endmodule module foo(clk, rst, inp, out); input wire clk; input wire rst; input wire [1:0] inp; output wire [1:0] out; bar bar_instance (clk, rst, inp, out); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/attrib_expr.v000066400000000000000000000040011435245347300212470ustar00rootroot00000000000000// Check that all types of constant expression are supported for attributes module test; localparam [7:0] x = 1; // Binary operators (* attr = x + x *) reg attr0; (* attr = x - x *) reg attr1; (* attr = x * x *) reg attr2; (* attr = x / x *) reg attr3; (* attr = x % x *) reg attr4; (* attr = x == x *) reg attr5; (* attr = x != x *) reg attr6; (* attr = x === x *) reg attr7; (* attr = x !== x *) reg attr8; (* attr = x && x *) reg attr9; (* attr = x || x *) reg attr10; (* attr = x ** x *) reg attr11; (* attr = x < x *) reg attr12; (* attr = x <= x *) reg attr13; (* attr = x > x *) reg attr14; (* attr = x >= x *) reg attr15; (* attr = x & x *) reg attr16; (* attr = x | x *) reg attr17; (* attr = x ^ x *) reg attr18; (* attr = x ^~ x *) reg attr19; (* attr = x >> x *) reg attr20; (* attr = x << x *) reg attr21; (* attr = x >>> x *) reg attr22; (* attr = x <<< x *) reg attr23; // Unary operators (* attr = +x *) reg attr24; (* attr = -x *) reg attr25; (* attr = !x *) reg attr26; (* attr = ~x *) reg attr27; (* attr = &x *) reg attr28; (* attr = ~&x *) reg attr29; (* attr = |x *) reg attr30; (* attr = ~|x *) reg attr31; (* attr = ^x *) reg attr32; (* attr = ~^x *) reg attr33; // Ternary operator (* attr = x ? x : x *) reg attr34; // Concat (* attr = {x,x} *) reg attr35; (* attr = {3{x}} *) reg attr36; // Part select (* attr = x[0] *) reg attr37; (* attr = x[1:0] *) reg attr38; (* attr = x[0+:1] *) reg attr39; (* attr = x[1-:1] *) reg attr40; // Parenthesis (* attr = (x) *) reg attr41; // Literals (* attr = 10 *) reg attr42; (* attr = 32'h20 *) reg attr43; (* attr = "test" *) reg attr44; // System function (* attr = $clog2(10) *) reg attr45; // Function function fn; input x; fn = x*2; endfunction (* attr = fn(10) *) reg attr46; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/automatic_error1.v000066400000000000000000000001771435245347300222160ustar00rootroot00000000000000module automatic_error(); task automatic auto_task; reg local; local = 1; endtask initial auto_task.local = 0; endmodule iverilog-12_0/ivtest/ivltests/automatic_error10.v000066400000000000000000000002141435245347300222660ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block force global = local; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error11.v000066400000000000000000000003341435245347300222720ustar00rootroot00000000000000`begin_keywords "1364-2005" module automatic_error(); task automatic auto_task; integer local; begin $monitor("%0d", local); #1 local = 0; #1 local = 1; end endtask initial auto_task; endmodule `end_keywords iverilog-12_0/ivtest/ivltests/automatic_error12.v000066400000000000000000000003101435245347300222650ustar00rootroot00000000000000`begin_keywords "1364-2005" module automatic_error(); task automatic auto_task; integer local; begin local = 1; $strobe("%0d", local); end endtask initial auto_task; endmodule `end_keywords iverilog-12_0/ivtest/ivltests/automatic_error13.v000066400000000000000000000003141435245347300222720ustar00rootroot00000000000000`begin_keywords "1364-2005" module automatic_error(); task automatic auto_task; integer local; begin local = 1; $fstrobe(1, "%0d", local); end endtask initial auto_task; endmodule `end_keywords iverilog-12_0/ivtest/ivltests/automatic_error14.v000066400000000000000000000004571435245347300223030ustar00rootroot00000000000000// Check that it is not possible to perform non-blocking assignments to fields // of structs with automatic lifetime. module test; task automatic auto_task; struct packed { logic x; } s; s.x <= 10; $display("FAILED"); endtask initial begin auto_task; end endmodule iverilog-12_0/ivtest/ivltests/automatic_error15.v000066400000000000000000000004551435245347300223020ustar00rootroot00000000000000// Check that it is not possible to perform non-blocking assignments to a class // object variable with automatic lifetime. module test; class C; endclass task automatic auto_task; C c1, c2; c1 <= c2; $display("FAILED"); endtask initial begin auto_task; end endmodule iverilog-12_0/ivtest/ivltests/automatic_error16.v000066400000000000000000000005421435245347300223000ustar00rootroot00000000000000// Check that an expression is correctly detected to contain an automatic // variable if the variable is in a SystemVerilog size cast expression. module automatic_error; reg g; task automatic auto_task; reg l; begin: block assign g = 1'(l); end endtask initial begin auto_task; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/automatic_error17.v000066400000000000000000000005351435245347300223030ustar00rootroot00000000000000// Check that an expression is correctly detected to contain an automatic // variable if the variable is in a SystemVerilog sign cast expression. module test; reg g; task automatic auto_task; reg l; begin: block assign g = signed'(l); end endtask initial begin auto_task; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/automatic_error18.v000066400000000000000000000005321435245347300223010ustar00rootroot00000000000000// Check that an expression is correctly detected to contain an automatic // variable if the variable is in a SystemVerilog type cast expression. module test; reg g; task automatic auto_task; reg l; begin: block assign g = reg'(l); end endtask initial begin auto_task; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/automatic_error2.v000066400000000000000000000001671435245347300222160ustar00rootroot00000000000000module automatic_error(); task automatic auto_task; reg local; begin:block local <= #1 0; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error3.v000066400000000000000000000002701435245347300222120ustar00rootroot00000000000000`begin_keywords "1364-2005" module automatic_error(); reg global; task automatic auto_task; begin:block reg local; global <= @(local) 0; end endtask endmodule `end_keywords iverilog-12_0/ivtest/ivltests/automatic_error4.v000066400000000000000000000002121435245347300222070ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block @(local || global); end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error5.v000066400000000000000000000002151435245347300222130ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block assign local = global; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error6.v000066400000000000000000000002061435245347300222140ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block deassign local; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error7.v000066400000000000000000000002151435245347300222150ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block assign global = local; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error8.v000066400000000000000000000002141435245347300222150ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block force local = global; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_error9.v000066400000000000000000000002051435245347300222160ustar00rootroot00000000000000module automatic_error(); reg global; task automatic auto_task; reg local; begin:block release local; end endtask endmodule iverilog-12_0/ivtest/ivltests/automatic_events.v000066400000000000000000000017461435245347300223130ustar00rootroot00000000000000module automatic_events(); reg [5:1] any; integer i; initial begin any = 5'b00000; #200; for (i = 1; i <= 5; i = i + 1) begin #10 any[i] = 1; #10 any[i] = 0; end end task automatic report_events; input integer n; reg [5:1] pos; reg [5:1] neg; integer i; integer j; begin #n; pos = 5'b00000; neg = 5'b00000; fork for (i = 1; i <= 5; i = i + 1) begin #10 neg[i] = 1; #10 pos[i] = 1; #10 neg[i] = 0; #10 pos[i] = 0; end for (j = 1; j <= 20; j = j + 1) begin @( any[1] or posedge pos[1] or negedge neg[1] or any[2] or posedge pos[2] or negedge neg[2] or any[3] or posedge pos[3] or negedge neg[3] or any[4] or posedge pos[4] or negedge neg[4] or any[5] or posedge pos[5] or negedge neg[5] ); #n $display("task %0d triggered: %b %b %b %4d", n, any, pos, neg, $time); end join end endtask initial begin fork report_events(1); report_events(2); join $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/automatic_events2.v000066400000000000000000000020111435245347300223570ustar00rootroot00000000000000module automatic_events(); reg [5:1] any; integer k; initial begin any = 5'b00000; #200; for (k = 1; k <= 5; k = k + 1) begin #10 any[k] = 1; #10 any[k] = 0; end end task automatic report_events; input integer n; begin:task_body reg [5:1] pos; reg [5:1] neg; #n; pos = 5'b00000; neg = 5'b00000; fork:task_threads integer i; integer j; for (i = 1; i <= 5; i = i + 1) begin #10 neg[i] = 1; #10 pos[i] = 1; #10 neg[i] = 0; #10 pos[i] = 0; end for (j = 1; j <= 20; j = j + 1) begin @( any[1] or posedge pos[1] or negedge neg[1] or any[2] or posedge pos[2] or negedge neg[2] or any[3] or posedge pos[3] or negedge neg[3] or any[4] or posedge pos[4] or negedge neg[4] or any[5] or posedge pos[5] or negedge neg[5] ); #n $display("task %0d triggered: %b %b %b %4d", n, any, pos, neg, $time); end join end endtask initial begin fork report_events(1); report_events(2); join $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/automatic_events3.v000066400000000000000000000024671435245347300223770ustar00rootroot00000000000000module automatic_events3(); reg [1:0] Source; initial begin Source[0] = 1'b0; forever begin #20 Source[0] = 1'b1; #20 Source[0] = 1'b0; end end initial begin Source[1] = 1'b0; #15; forever begin #10 Source[1] = 1'bx; #10 Source[1] = 1'b1; #10 Source[1] = 1'bx; #10 Source[1] = 1'b0; end end task automatic ReportPosEdge0; begin @(posedge Source[0]); $display("Time %t : Source[0] rise", $time); end endtask task automatic ReportNegEdge0; begin @(negedge Source[0]); $display("Time %t : Source[0] fall", $time); end endtask task automatic ReportAnyEdge0; time t; begin @(Source[0]) t = $time; #1 $display("Time %t : Source[0] edge", t); end endtask task automatic ReportPosEdge1; begin @(posedge Source[1]); $display("Time %t : Source[1] rise", $time); end endtask task automatic ReportNegEdge1; begin @(negedge Source[1]); $display("Time %t : Source[1] fall", $time); end endtask task automatic ReportAnyEdge1; time t; begin @(Source[1]) t = $time; #1 $display("Time %t : Source[1] edge", t); end endtask initial begin #1; fork repeat(2) ReportPosEdge0; repeat(2) ReportNegEdge0; repeat(4) ReportAnyEdge0; repeat(4) ReportPosEdge1; repeat(4) ReportNegEdge1; repeat(8) ReportAnyEdge1; join $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/automatic_task.v000066400000000000000000000011511435245347300217370ustar00rootroot00000000000000module automatic_task(); task automatic fill_array; input [7:0] value; reg [7:0] array[3:0]; event step; fork begin #10 array[0] = value; ->step; #10 array[1] = array[0]; ->step; #10 array[2] = array[1]; ->step; #10 array[3] = array[2]; ->step; end begin @step $display(array[0], array[1], array[2], array[3]); @step $display(array[0], array[1], array[2], array[3]); @step $display(array[0], array[1], array[2], array[3]); @step $display(array[0], array[1], array[2], array[3]); end join endtask initial #1 fill_array(1); initial #2 fill_array(2); endmodule iverilog-12_0/ivtest/ivltests/automatic_task2.v000066400000000000000000000011321435245347300220200ustar00rootroot00000000000000module automatic_task(); task automatic fill_array; input [7:0] value; reg [7:0] array[3:0]; integer i; fork begin #10 array[0] = value; #10 array[1] = array[0]; #10 array[2] = array[1]; #10 array[3] = array[2]; end begin @(array[0]) $display(array[0], array[1], array[2], array[3]); @(array[1]) $display(array[0], array[1], array[2], array[3]); @(array[2]) $display(array[0], array[1], array[2], array[3]); @(array[3]) $display(array[0], array[1], array[2], array[3]); end join endtask initial #1 fill_array(1); initial #2 fill_array(2); endmodule iverilog-12_0/ivtest/ivltests/automatic_task3.v000066400000000000000000000006711435245347300220300ustar00rootroot00000000000000module automatic_task(); reg [7:0] array[3:0]; task automatic fill_array; input [7:0] value; integer i, j; fork for (i = 0; i < 4; i = i + 1) begin #10 array[i] = value; end for (j = 0; j < 4; j = j + 1) begin @(array[j]) $display(array[0], array[1], array[2], array[3]); @(array[j]) $display(array[0], array[1], array[2], array[3]); end join endtask initial #1 fill_array(1); initial #2 fill_array(2); endmodule iverilog-12_0/ivtest/ivltests/basicexpr.v000066400000000000000000000034411435245347300207130ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic reg form // // module basicreg ( clk, d, q); input clk, d; output [2:0] q; reg [2:0] q; always @(posedge clk) begin q <= d + d; end endmodule module test ; reg clk, d; wire [2:0] q; basicreg u_reg (clk,d,q); initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); clk = 0; d = 0; # 1; clk = 1; # 1; if (q !== 3'b0) begin $display("FAILED - Q isn't 0 on first edge"); $finish; end d = 1; # 1; clk = 0; # 1; if (q !== 3'b0) begin $display("FAILED - Q isn't 0 after first falling edge"); $finish; end # 1; clk = 1; # 1; if (q !== 3'b010) begin #1 ; $display("FAILED - Q isn't 2 2nd raising edge"); $finish; end # 1; clk = 0; # 1; if (q !== 3'b010) begin $display("FAILED - Q isn't 2 after 2nd falling edge"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basicexpr2.v000066400000000000000000000026371435245347300210030ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic expression assign with add // // module adder (q,a,b ); input a,b; output [1:0] q; assign q = {1'b0,a} +{1'b0,b}; endmodule module test ; reg d; wire [1:0] q; adder u_add (.q(q),.a(d),.b(d)); (* ivl_synthesis_off *) initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); d = 0; # 1; if (q !== 2'b0) begin $display("FAILED - Q isn't 0 "); $finish; end #1 ; d = 1; # 1; if (q !== 2'b10) begin $display("FAILED - Q isn't 2 "); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basicexpr3.v000066400000000000000000000026341435245347300210010ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic expression assign with add // // module mul (q,a,b ); input a,b; output [1:0] q; assign q = {1'b0,a} * {1'b0,b}; endmodule module test ; reg d; wire [1:0] q; mul u_mul (.q(q),.a(d),.b(d)); (* ivl_synthesis_off *) initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); d = 0; # 1; if (q !== 2'b0) begin $display("FAILED - Q isn't 0 "); $finish; end #1 ; d = 1; # 1; if (q !== 2'b01) begin $display("FAILED - Q isn't 2 "); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basicexpr4.v000066400000000000000000000026241435245347300210010ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic expression assign with add // // module adder (q,a,b ); input a,b; output [1:0] q; assign q = a + b; endmodule module test ; reg d; wire [1:0] q; adder u_add (.q(q),.a(d),.b(d)); (* ivl_synthesis_off *) initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); d = 0; # 1; if (q !== 2'b0) begin $display("FAILED - Q isn't 0 "); $finish; end #1 ; d = 1; # 1; if (q !== 2'b10) begin $display("FAILED - Q isn't 2 "); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basiclatch.v000066400000000000000000000032621435245347300210310ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic latch form // // module basiclatch ( clk, d, q); input clk, d; output q; reg q; always @ (clk or d) if(~clk) q = d; endmodule module tbench ; reg clk, d; basiclatch u_reg (clk,d,q); initial begin clk = 0; d = 0; #1 ; if(q !== 0) begin $display("FAILED - initial value not 0"); $finish; end #1 ; clk = 1; # 1; d = 1; # 1; if(q !== 0) begin $display("FAILED - Didn't latch initial 0"); $finish; end #1 clk = 0; # 1; if(q !== 1) begin $display("FAILED - Didn't pass 1 after latch dropped"); $finish; end #1 clk = 1; # 1; d = 0; # 1; if(q !== 1) begin $display("FAILED - Didn't latch 1 after latch dropped"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basicreg.v000066400000000000000000000033431435245347300205130ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth of basic reg form // // module basicreg ( clk, d, q); input clk, d; output q; reg q; (* ivl_synthesis_on *) always @(posedge clk) q <= d; endmodule module tbench ; reg clk, d; basicreg u_reg (clk,d,q); (* ivl_synthesis_off *) initial begin clk = 0; d = 0; # 1; clk = 1; # 1; if (q !== 0) begin $display("FAILED - Q isn't 0 on first edge"); $finish; end d = 1; # 1; clk = 0; # 1; if (q !== 0) begin $display("FAILED - Q isn't 0 after first falling edge"); $finish; end # 1; d = 1; clk = 1; # 1; if (q !== 1) begin $display("FAILED - Q isn't 1 2nd raising edge"); $finish; end # 1; clk = 0; # 1; if (q !== 1) begin $display("FAILED - Q isn't 1 after 2nd falling edge"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/basicstate.v000066400000000000000000000040331435245347300210530ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: synth basic state machine form // // module sm ( clk,rst,st); input clk,rst; output [1:0] st; reg [1:0] st; always @(posedge clk or posedge rst) if (rst) st <= 2'b0; else case (st) 2'b00: st <= 2'b01; 2'b01: st <= 2'b11; 2'b11: st <= 2'b10; 2'b10: st <= 2'b00; endcase endmodule module test ; reg clk,rst; wire [1:0] st; sm u_sm ( clk,rst,st); always #5 clk = ~clk; initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); clk = 0; rst = 1; @(posedge clk); #1 ; rst = 0; if(st !== 2'b00) begin $display("FAILED - SM didn't initialize"); $finish; end @(posedge clk); #1 ; if(st !== 2'b01) begin $display("FAILED - SM didn't xsn to 01"); $finish; end @(posedge clk); #1 ; if(st !== 2'b11) begin $display("FAILED - SM didn't xsn to 11"); $finish; end @(posedge clk); #1 ; if(st !== 2'b10) begin $display("FAILED - SM didn't xsn to 10"); $finish; end @(posedge clk); #1 ; if(st !== 2'b00) begin $display("FAILED - SM didn't xsn to 00"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/basicstate2.v000066400000000000000000000041231435245347300211350ustar00rootroot00000000000000// // Copyright (c) 2002 Steven Wilson (steve@ka6s.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Synth 2nd basic sm form // // module sm ( clk,rst,st); input clk,rst; output [1:0] st; reg [1:0] st,next_st; always @(posedge clk or posedge rst) if (rst) st <= 2'b0; else st <= next_st; always @(st) case (st) 2'b00: next_st <= 2'b01; 2'b01: next_st <= 2'b11; 2'b11: next_st <= 2'b10; 2'b10: next_st <= 2'b00; endcase endmodule module test ; reg clk,rst; wire [1:0] st; sm u_sm ( clk,rst,st); always #5 clk = ~clk; initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); clk = 0; rst = 1; @(posedge clk); #1 ; rst = 0; if(st !== 2'b00) begin $display("FAILED - SM didn't initialize"); $finish; end @(posedge clk); #1 ; if(st !== 2'b01) begin $display("FAILED - SM didn't xsn to 01"); $finish; end @(posedge clk); #1 ; if(st !== 2'b11) begin $display("FAILED - SM didn't xsn to 11"); $finish; end @(posedge clk); #1 ; if(st !== 2'b10) begin $display("FAILED - SM didn't xsn to 10"); $finish; end @(posedge clk); #1 ; if(st !== 2'b00) begin $display("FAILED - SM didn't xsn to 00"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/big_int.v000066400000000000000000000070401435245347300203450ustar00rootroot00000000000000// Note: when __ICARUS_UNSIZED__ is not defined, this test assumes integers // are 32 bits wide. module main(); reg [34:0] my_reg; reg error; reg [34:0] ref_val; reg [34:0] ref_val2; reg [7:0] count; initial begin error = 0; // Create reference value that is bigger than 32 bits... ref_val = 0; ref_val[0] = 1; ref_val[34] = 1; $display("*:%d", ref_val); ref_val2 = 35'h7ffffffff; $display("*:%d", ref_val2); // Trivial test to see that small unsized integers still work. my_reg = 100; if (my_reg != 'h64) begin error = 1; $display("Error: expected 100"); end my_reg = 17179869185; $display("1:%d", my_reg); `ifdef __ICARUS_UNSIZED__ // Ordinary compilers will truncate unsized integer // constants to 32bits. Icarus Verilog is more generous. if (my_reg !== 35'h4_00000001) begin error = 1; $display("Error: expected 17179869185"); end `else // Unsized integers bigger than 32 bits are truncated... // Value below has bit 34 and bit 0 set to '1' if (my_reg != 1) begin error = 1; $display("Error: expected 1"); end `endif // Another unsized integer, but this time 'd specifier... my_reg = 'd17179869184; $display("2:%d", my_reg); `ifdef __ICARUS_UNSIZED__ // Ordinary compilers will truncate unsized integer // constants to 32bits. Icarus Verilog is more generous. if (my_reg !== 35'h4_00000000) begin error = 1; $display("Error: expected 17179869184"); end `else if (my_reg != 0) begin error = 1; $display("Error: expected 1"); end `endif // This should finally work! my_reg = 35'sd17179869185; $display("3:%d", my_reg); if (my_reg != ref_val) begin error = 1; $display("Error: expected 17179869185"); end // This should work too. my_reg = 35'd 17179869185; $display("4:%d", my_reg); if (my_reg != ref_val) begin error = 1; $display("Error: expected 17179869185"); end // Overflow... my_reg = 35'd 34359738369; $display("5:%d", my_reg); if (my_reg != 1) begin error = 1; $display("Error: expected 1"); end // Just no overflow my_reg = 35'd 34359738367; $display("6:%d", my_reg); if (my_reg != ref_val2) begin error = 1; $display("Error: expected 34359738367"); end `ifdef __ICARUS_UNSIZED__ // Since Icarus Verilog doesn't truncate constant values, // the whole idea of truncating then sign-extending the result // to go into the wide reg does not apply. So skip this // test. `else // Unsized integers bigger than 32 bits are truncated... // Here all the bits are set. Since there is no 'd prefix, // it will be sign extended later on. my_reg = 17179869183; $display("7:%d", my_reg); if (my_reg != ref_val2) begin error = 1; $display("Error: expected 34359738367"); end `endif // Unsized integers bigger than 32 bits are truncated... // Here all the bits are set. Since there *IS* a 'd prefix // it will NOT be sign extended later on. my_reg = 'd17179869183; $display("8:%d", my_reg); `ifdef __ICARUS_UNSIZED__ if (my_reg != 'd17179869183) begin error = 1; $display("Error: expected 'd17179869183"); end `else if (my_reg != 'd4294967295) begin error = 1; $display("Error: expected 4294967295"); end `endif if (error==1) begin $display("FAILED"); end else begin $display("PASSED"); end $finish; end endmodule iverilog-12_0/ivtest/ivltests/binary_nand.v000066400000000000000000000032421435245347300212160ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Binary ~& (nand) operator. module main; reg A, B; reg result1; wire result2 = A ~& B; initial begin A = 0; B = 0; #1 result1 = A ~& B; if (result1 !== 1'b1) begin $display("FAILED"); $finish; end if (result2 !== 1'b1) begin $display("FAILED"); $finish; end A = 1; #1 result1 = A ~& B; if (result1 !== 1'b1) begin $display("FAILED"); $finish; end if (result2 !== 1'b1) begin $display("FAILED"); $finish; end B = 1; #1 result1 = A ~& B; if (result1 !== 1'b0) begin $display("FAILED"); $finish; end if (result2 !== 1'b0) begin $display("FAILED"); $finish; end A = 0; #1 result1 = A ~& B; if (result1 !== 1'b1) begin $display("FAILED"); $finish; end if (result2 !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/binary_nor.v000066400000000000000000000032411435245347300210730ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Binary ~| (nor) operator. module main; reg A, B; reg result1; wire result2 = A ~| B; initial begin A = 0; B = 0; #1 result1 = A ~| B; if (result1 !== 1'b1) begin $display("FAILED"); $finish; end if (result2 !== 1'b1) begin $display("FAILED"); $finish; end A = 1; #1 result1 = A ~| B; if (result1 !== 1'b0) begin $display("FAILED"); $finish; end if (result2 !== 1'b0) begin $display("FAILED"); $finish; end B = 1; #1 result1 = A ~| B; if (result1 !== 1'b0) begin $display("FAILED"); $finish; end if (result2 !== 1'b0) begin $display("FAILED"); $finish; end A = 0; #1 result1 = A ~| B; if (result1 !== 1'b0) begin $display("FAILED"); $finish; end if (result2 !== 1'b0) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bitp1.v000066400000000000000000000013121435245347300177450ustar00rootroot00000000000000module test; bit b; bit [9:0] b10; bit signed bs; bit unsigned bu; bit signed [6:0] bs7; bit unsigned [5:0] bu6; initial begin b = 1; b10 = 100; bs = 0; bu = 1; bs7 = -17; bu6 = 21; #1; if (b * b10 !== 100) begin $display ("FAILED 1"); $finish; end if (bs * b10 !== 0) begin $display ("FAILED 2" ); $finish; end if (bu * b10 !== 100) begin $display ("FAILED 3"); $finish; end if (bs7 * 1 !== -17) begin $display ("FAILED 4"); $finish; end if (bu6 * b !== 21) begin $display ("FAILED 5"); $finish; end $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bits.v000066400000000000000000000011311435245347300176660ustar00rootroot00000000000000module main; reg foo_reg; byte foo_byte; int foo_int; shortint foo_shortint; longint foo_longint; initial begin if ($bits(foo_reg) != 1) begin $display("FAILED"); $finish; end if ($bits(foo_byte) != 8) begin $display("FAILED"); $finish; end if ($bits(foo_int) != 32) begin $display("FAILED"); $finish; end if ($bits(foo_shortint) != 16) begin $display("FAILED"); $finish; end if ($bits(foo_longint) != 64) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bits2.v000066400000000000000000000017621435245347300177620ustar00rootroot00000000000000module main; reg foo_reg; byte foo_byte; int foo_int; shortint foo_shortint; longint foo_longint; bit foo_bit; bit [13:0] foo14_bit; logic foo_logic; logic [10:0] foo11_logic; initial begin if ($bits(foo_reg) != 1) begin $display("FAILED"); $finish; end if ($bits(foo_byte) != 8) begin $display("FAILED"); $finish; end if ($bits(foo_int) != 32) begin $display("FAILED"); $finish; end if ($bits(foo_shortint) != 16) begin $display("FAILED"); $finish; end if ($bits(foo_longint) != 64) begin $display("FAILED"); $finish; end if ($bits(foo_bit) != 1) begin $display("FAILED"); $finish; end if ($bits(foo14_bit) != 14) begin $display("FAILED"); $finish; end if ($bits(foo_logic) != 1) begin $display("FAILED"); $finish; end if ($bits(foo11_logic) != 11) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bits3.v000066400000000000000000000012411435245347300177530ustar00rootroot00000000000000// Check that passing a data type to $bits works as expected module test; bit failed = 1'b0; `define check(type, value) \ if ($bits(type) !== value) begin \ $display("FAILED: $bits(", `"type`", ") is %0d", $bits(type), " expected %0d", value); \ failed = 1'b1; \ end typedef int T1; typedef int T2[3:0]; initial begin `check(reg, 1); `check(logic, 1); `check(bit, 1); `check(logic [3:0], 4); `check(byte, 8); `check(shortint, 16); `check(int, 32); `check(longint, 64); `check(struct packed { int x; shortint y; }, 32 + 16); `check(T1, 32); `check(T2, 4 * 32); if (failed == 1'b0) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/bitsel.v000066400000000000000000000002311435245347300202070ustar00rootroot00000000000000module m; reg [15:8] r; integer i; initial begin r = 8'b01101001; for (i = 8; i <= 15; i = i + 1) $display(r[i]); end endmodule iverilog-12_0/ivtest/ivltests/bitsel10.v000066400000000000000000000022401435245347300203520ustar00rootroot00000000000000module main; wire [7:0] bus; reg [7:0] HiZ; assign bus = HiZ; reg E; reg D; reg CLK; BUFT drv (bus[0], D, E, CLK); bufif0 drv0 (bus[0], D, E); initial begin HiZ = 8'hzz; D = 1; E = 1; CLK = 0; #1 CLK = 1; #1 if (bus !== 8'bzzzzzzz1) begin $display("FAILED"); $finish; end if (drv.D !== D) begin $display("FAILED (D)"); $finish; end E = 0; #1 if (bus !== 8'bzzzzzzz1) begin $display("FAILED"); $finish; end D = 0; CLK = 0; #1 CLK = 1; if (drv.D !== D) begin $display("FAILED (D)"); $finish; end #1 D = 1; #1 if (bus !== 8'bzzzzzzz1) begin $display("FAILED"); $finish; end if (drv.D !== D) begin $display("FAILED (D)"); $finish; end $display("bus=%b, D=%b, drv.D=%b, E=%b, drv.save=%b", bus, D, drv.D, E, drv.save); $display("PASSED"); end // initial begin endmodule // main module BUFT(inout wire TO, input wire D, input wire E, input wire CLK); reg save; assign TO = E? save : 2'bz; always @(posedge CLK) save <= D; endmodule // BUFT iverilog-12_0/ivtest/ivltests/bitsel2.v000066400000000000000000000023301435245347300202730ustar00rootroot00000000000000/* * Copyright (c) 2000 Steve Wilson (stevew@home.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This checks bit select from/to vectors with odd bit arrangements. */ module test; reg [1:4] a; reg [4:1] b; integer i; initial begin a = 4'b1100; for (i = 1 ; i <= 4 ; i = i + 1) b[i] = a[i]; $display("a=%b, b=%b", a, b); if (b !== 4'b0011) begin $display("FAILED -- b == %b", b); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bitsel3.v000066400000000000000000000023301435245347300202740ustar00rootroot00000000000000/* * Copyright (c) 2000 Steve Wilson (stevew@home.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This checks bit select from/to vectors with odd bit arrangements. */ module test; reg [4:1] a; reg [1:4] b; integer i; initial begin a = 4'b1100; for (i = 1 ; i <= 4 ; i = i + 1) b[i] = a[i]; $display("a=%b, b=%b", a, b); if (b !== 4'b0011) begin $display("FAILED -- b == %b", b); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bitsel4.v000066400000000000000000000027401435245347300203020ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Bit select of a net (a wire) using the index of a for loop. */ module main; // Make a vector of bits, an array of functors in practice, and // create a net that hooks to that array backwards. reg [4:0] vect = 5'b10100; wire [4:0] tmp = { vect[0], vect[1], vect[2], vect[3], vect[4] }; reg [2:0] idx; initial begin #1 $display("vect=%b, tmp=%b", vect, tmp); for (idx = 0 ; idx < 5 ; idx = idx + 1) begin $display("idx=%d: vect=%b, tmp=%b", idx, vect[idx], tmp[idx]); if (tmp[idx] !== vect[4-idx]) begin $display("FAILED"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bitsel5.v000066400000000000000000000027411435245347300203040ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Bit select of a net (a wire) using the index of a for loop. */ module main; // Make a vector of bits, an array of functors in practice, and // create a net that hooks to that array backwards. reg [5:1] vect = 5'b10100; wire [5:1] tmp = { vect[1], vect[2], vect[3], vect[4], vect[5] }; reg [2:0] idx; initial begin #1 $display("vect=%b, tmp=%b", vect, tmp); for (idx = 1 ; idx <= 5 ; idx = idx + 1) begin $display("idx=%d: vect=%b, tmp=%b", idx, vect[idx], tmp[idx]); if (tmp[idx] !== vect[6-idx]) begin $display("FAILED"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bitsel6.v000066400000000000000000000046311435245347300203050ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test was inspired by PR#539. We check that the calculated bit * select of a net in a continuous assignment gets bits in the right * order and position. The trick here is that the bits are numbered * from MSB to LSB. */ module main; reg [0:63] target0 = 64'h0040200000000000; reg [1:64] target1 = 64'h0040200000000000; reg [6:0] idx; wire mux0 = target0[idx]; wire mux1 = target1[idx+1]; initial begin $display( "Using constant indices:" ); $display( " %b=v[ 9]", target0[ 9] ); if (target0[9] !== 1'b1) begin $display("FAILED -- target0[9] != 1"); $finish; end $display( " %b=v[18]", target0[18] ); if (target0[18] !== 1'b1) begin $display("FAILED -- target0[18] != 1"); $finish; end $display( " %b=v[45]", target0[45] ); if (target0[45] !== 1'b0) begin $display("FAILED -- target0[45] != 0"); $finish; end $display( " %b=v[54]", target0[54] ); if (target0[54] !== 1'b0) begin $display("FAILED -- target0[54] != 0"); $finish; end $display( "Using calcuated indices:" ); for (idx = 0 ; idx < 64 ; idx = idx + 1) begin #1 $display("target0[%2d]=%b, mux0=%b", idx, target0[idx], mux0); $display("target1[%2d]=%b, mux1=%b", idx+1, target1[idx+1], mux1); if (target0[idx] !== mux0) begin $display("FAILED -- target0[idx] != mux0"); $finish; end if (target1[idx+1] !== mux1) begin $display("FAILED -- target1[idx+1] != mux1"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bitsel7.v000066400000000000000000000046371435245347300203140ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test was inspired by PR#539. We check that the calculated bit * select of a net in a continuous assignment gets bits in the right * order and position. The trick here is that the bits are numbered * from MSB to LSB. */ module main; reg [63:0] target0 = 64'h0040_2000_0000_0000; reg [64:1] target1 = 64'h0040_2000_0000_0000; reg [6:0] idx; wire mux0 = target0[idx]; wire mux1 = target1[idx+1]; initial begin $display( "Using constant indices:" ); $display( " %b=v[45]", target0[45] ); if (target0[45] !== 1'b1) begin $display("FAILED -- target0[45] != 1"); $finish; end $display( " %b=v[54]", target0[54] ); if (target0[54] !== 1'b1) begin $display("FAILED -- target0[54] != 1"); $finish; end $display( " %b=v[18]", target0[18] ); if (target0[18] !== 1'b0) begin $display("FAILED -- target0[18] != 0"); $finish; end $display( " %b=v[ 9]", target0[9] ); if (target0[9] !== 1'b0) begin $display("FAILED -- target0[ 9] != 0"); $finish; end $display( "Using calcuated indices:" ); for (idx = 0 ; idx < 64 ; idx = idx + 1) begin #1 $display("target0[%2d]=%b, mux0=%b", idx, target0[idx], mux0); $display("target1[%2d]=%b, mux1=%b", idx+1, target1[idx+1], mux1); if (target0[idx] !== mux0) begin $display("FAILED -- target0[idx] != mux0"); $finish; end if (target1[idx+1] !== mux1) begin $display("FAILED -- target1[idx+1] != mux1"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/bitsel8.v000066400000000000000000000023701435245347300203050ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test was derived from PR615.v **/ module main(); parameter INIT_00 = 32'hffffffff; reg [4:0] c; initial begin c = 0; $display("%b",INIT_00[c]); if (INIT_00[c] !== 1'b1) begin $display("FAILED"); $finish; end c = 1; $display("%b",INIT_00[c]); if (INIT_00[c] !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bitsel9.v000066400000000000000000000027231435245347300203100ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test was derived from PR617.v **/ module main(); parameter INIT_00 = 32'hffffffff; reg [17:0] t; reg [8:0] c; initial begin t = {17'd0,INIT_00[0]}<<1; $display("%b",t); if (t !== 18'b00_0000_0000_0000_0010) begin $display("FAILED"); $finish; end c = 0; t = {17'd0,INIT_00[c]}<<1; $display("%b",t); if (t !== 18'b00_0000_0000_0000_0010) begin $display("FAILED"); $finish; end c = 16; t = {17'd0,INIT_00[c]}<<1; $display("%b",t); if (t !== 18'b00_0000_0000_0000_0010) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bitwidth.v000066400000000000000000000023521435245347300205510ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; wire [31:0] A; wire [24:0] B; reg [15:0] C; assign A = B; assign B = C; initial begin C = 0; #1 if (A !== 32'h0) begin $display("FAILED -- A === %h", A); $finish; end C = -1; #1 if (A !== 32'h00_00_ff_ff) begin $display("FAILED -- A == %h instead of 0000ffff", A); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/bitwidth2.v000066400000000000000000000002541435245347300206320ustar00rootroot00000000000000module ternary; wire [5:0] a; wire [6:0] b; wire c; wire [5:0] d = c ? a : b; initial begin $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/bitwidth3.v000066400000000000000000000032431435245347300206340ustar00rootroot00000000000000/* * Copyright (c) 2004 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main(); reg [4:0] sum; initial begin // Self-determined expressions take their size from the // operands. The compiler should thus make the constant // expression below exactly 4 bits wide. $display("Should be 0001: %b", 4'd7 + 4'd10); if ($bits(4'd7 + 4'd10) != 4) begin $display("FAILED -- bit width should be 4: %d", $bits(4'd7 + 4'd10)); $finish; end // When assigning to an l-value, the expression, and // by extension the operands, take on the width of the // left side. This expansion should be passed all the // way down the expression. sum = 4'd7 + 4'd10; $display("Should be 10001: %b", sum); if (sum !== 5'b1_0001) begin $display("FAILED -- expression truncated?"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/blankport.v000066400000000000000000000032241435245347300207260ustar00rootroot00000000000000// // Copyright (c) 1999 Stephan Boettcher (stephan@nevis1.nevis.columbia.edu) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - PR 204 report - validates correct use of blank ports. module none; reg x; endmodule // none module empty(); reg x; endmodule // none module one (a); input a; reg x; endmodule // one module two (a, b); input a, b; reg x; endmodule // two module three (a, b, c); input a, b, c; reg x; endmodule // two module main; wire w1, w2, w3, w4, w5, w6, w7, w8, w9; none U1 (); empty U2 (); one U3 (); one U4 (w1); one U5 (.a(w2)); two U6 (); two U7 (,); two U8 (w3,); two U9 (,w4); two Ua (w5,w6); two Ub (.a(w7)); two Uc (.b(w8)); two Ud (.b(w8),.a(w9)); three Ue (); //three Uf (,); //XXXX I doubt this is legal... ? three Ug (,,); initial $display("PASSED"); endmodule // main iverilog-12_0/ivtest/ivltests/block_only_with_var_def.v000066400000000000000000000002611435245347300236040ustar00rootroot00000000000000module a; initial begin : b reg x; end initial fork : c reg x; join initial begin a.b.x = 1'b0; a.c.x = 1'b1; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/blocking_repeat_ec.v000066400000000000000000000016271435245347300225360ustar00rootroot00000000000000module top; reg pass = 1'b1; integer count; reg clk = 0, in = 0; reg result; always #10 clk = ~clk; always #20 in = ~in; initial begin count = 3; result = repeat(count) @(posedge clk) in; if ($simtime != 30 && result != 1'b0) begin $display("Failed blocking repeat(3) at %0t, expected 1'b0, got %b", $simtime, result); pass = 1'b0; end #15; count = 0; result = repeat(count) @(posedge clk) in; if ($simtime != 45 && result != 1'b1) begin $display("Failed blocking repeat(0) at %0t, expected 1'b1, got %b", $simtime, result); pass = 1'b0; end #20; count = -1; result = repeat(count) @(posedge clk) in; if ($simtime != 55 && result != 1'b0) begin $display("Failed blocking repeat(0) at %0t, expected 1'b0, got %b", $simtime, result); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/blocksynth1.v000066400000000000000000000024361435245347300211770ustar00rootroot00000000000000/* * blocksyn1.v * This tests synthesis where statements in a block override previous * statements in a block and also uses other previous statements in the * block. Note in this example that the flag assignment is completely * overruled by the conditional that is directly after it. */ module main; reg [1:0] out; reg flag; reg [1:0] sel; (* ivl_synthesis_on, ivl_combinational *) always @* begin case (sel) 2'b00: out = 2'b11; 2'b01: out = 2'b10; 2'b10: out = 2'b01; 2'b11: out = 2'b00; endcase // case(sel) // This flag is completely overridden by the contintional, so // the synthesizer should drop it. flag = 1'b0; if (out == 2'b00) flag = 1'b1; else flag = 1'b0; end reg [2:0] idx; reg test; (* ivl_synthesis_off *) initial begin for (idx = 0 ; idx < 7 ; idx = idx + 1) begin sel = idx[1:0]; #1 if (out !== ~sel) begin $display("FAILED -- sel=%b, out=%b, flag=%b", sel, out, flag); $finish; end test = (out == 2'b00)? 1'b1 : 1'b0; if (test !== flag) begin $display("FAILED -- test=%b, sel=%b, out=%b, flag=%b", test, sel, out, flag); $finish; end end // for (idx = 0 ; idx < 7 ; idx = idx + 1) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/blocksynth2.v000066400000000000000000000025311435245347300211740ustar00rootroot00000000000000/* * blocksyn1.v * This tests synthesis where statements in a block override previous * statements in a block and also uses other previous statements in the * block. Note in this example that the flag assignment is completely * overruled by the conditional that is directly after it. */ module main; reg [1:0] out; reg flag; reg [1:0] sel; (* ivl_synthesis_on, ivl_combinational *) always @* begin out = 2'b00; case (sel) 2'b00: out = 2'b11; 2'b01: out = 2'b10; 2'b10: out = 2'b01; // out for sel==2'b11 should be inherited from previous statement endcase // case(sel) // This flag is completely overridden by the conditional, so // the synthesizer should drop it. flag = 1'b0; if (out == 2'b00) flag = 1'b1; else flag = 1'b0; end reg [2:0] idx; reg test; (* ivl_synthesis_off *) initial begin for (idx = 0 ; idx < 7 ; idx = idx + 1) begin sel = idx[1:0]; #1 if (out !== ~sel) begin $display("FAILED -- sel=%b, out=%b, flag=%b", sel, out, flag); $finish; end test = (out == 2'b00)? 1'b1 : 1'b0; if (test !== flag) begin $display("FAILED -- test=%b, sel=%b, out=%b, flag=%b", test, sel, out, flag); $finish; end end // for (idx = 0 ; idx < 7 ; idx = idx + 1) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/blocksynth3.v000066400000000000000000000024461435245347300212020ustar00rootroot00000000000000/* * blocksyn1.v * This tests synthesis where statements in a block override previous * statements in a block and also uses other previous statements in the * block. Note in this example that the flag assignment is completely * overruled by the conditional that is directly after it. */ module main; reg [1:0] out; reg flag; reg [1:0] sel; (* ivl_synthesis_on, ivl_combinational *) always @* begin out = 2'b00; case (sel) 2'b00: out = 2'b11; 2'b01: out = 2'b10; 2'b10: out = 2'b01; endcase // case(sel) // This flag is overridded by the true clause, so the // synthesizer should move the first assignment to the // else clause of the if. flag = 1'b0; if (out == 2'b00) flag = 1'b1; end reg [2:0] idx; reg test; (* ivl_synthesis_off *) initial begin for (idx = 0 ; idx < 7 ; idx = idx + 1) begin sel = idx[1:0]; #1 if (out !== ~sel) begin $display("FAILED -- sel=%b, out=%b, flag=%b", sel, out, flag); $finish; end test = (out == 2'b00)? 1'b1 : 1'b0; if (test !== flag) begin $display("FAILED -- test=%b, sel=%b, out=%b, flag=%b", test, sel, out, flag); $finish; end end // for (idx = 0 ; idx < 7 ; idx = idx + 1) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/bnot.v000066400000000000000000000022711435245347300176750ustar00rootroot00000000000000module test; reg a,b; integer x; initial begin x=10; // ok a=x; // fails at run time with // vvm_func.cc:49: failed assertion `v.nbits == p.nbits' // Abort (core dumped) b = ~x; if (b === 1'b1) $display("PASSED"); else $display("FAILED --- b = %b", b); end // initial begin endmodule // test /* * Copyright (c) 2000 Gerard A. Allan (gaa@ee.ed.ac.uk) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ iverilog-12_0/ivtest/ivltests/bool1.v000066400000000000000000000024741435245347300177540ustar00rootroot00000000000000/* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the bool type used as an index to a for loop, and in a * few other minor cases. */ module main; reg bool [31:0] idx; reg logic [7:0] tmp; initial begin idx = 7; tmp = 7; $display("Dispay of 7s: %d, %d", idx, tmp); for (idx = 0 ; idx < 17 ; idx = idx + 1) begin tmp = idx[7:0]; if (tmp != idx[7:0]) begin $display("FAILED -- %b != %b", tmp, idx[7:0]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/br1000.v000066400000000000000000000007371435245347300176440ustar00rootroot00000000000000module loop(); reg [3:0] a; reg [3:0] b; reg [3:0] c; reg [3:0] d; integer i; always @* begin for (i = 0; i < 4; i = i + 1) begin b[i] = a[i]; $display("process 1 : %0d %b", i, b); end end always @* begin for (i = 0; i < 4; i = i + 1) begin d[i] = c[i]; $display("process 2 : %0d %b", i, d); end end initial begin #0; a = 5; #0; c = 6; #0; if ((b === 5) && (c === 6)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1001.v000066400000000000000000000003441435245347300176370ustar00rootroot00000000000000module submod(inout a); endmodule module topmod(); wand x; wor y; submod m1(.a(x)); submod m2(.a(y)); initial begin if ((x === 1'bz) && (y === 1'bz)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1003a.v000066400000000000000000000007321435245347300200030ustar00rootroot00000000000000timeunit 100ps / 10ps; class testclass; task delay(output [63:0] t); begin $printtimescale(top); $printtimescale; #5ns t = $time; end endtask endclass module top(); timeunit 1ns / 1ps; testclass tc; reg [63:0] t1; reg [63:0] t2; initial begin $printtimescale; tc = new; tc.delay(t1); t2 = $time; $display("%0d %0d", t1, t2); if ((t1 === 50) && (t2 === 5)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1003b.v000066400000000000000000000006241435245347300200040ustar00rootroot00000000000000timeunit 100ps / 10ps; task delay(output [63:0] t); begin $printtimescale(top); $printtimescale; #5ns t = $time; end endtask module top(); timeunit 1ns / 1ps; reg [63:0] t1; reg [63:0] t2; initial begin $printtimescale; delay(t1); t2 = $time; $display("%0d %0d", t1, t2); if ((t1 === 50) && (t2 === 5)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1003c.v000066400000000000000000000006361435245347300200100ustar00rootroot00000000000000timeunit 100ps / 10ps; function [63:0] delay(input dummy); begin $printtimescale(top); $printtimescale; delay = 5ns; end endfunction module top(); timeunit 1ns / 1ps; reg [63:0] t1; reg [63:0] t2; initial begin $printtimescale; t1 = delay(0); t2 = 5ns; $display("%0d %0d", t1, t2); if ((t1 === 50) && (t2 === 5)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1003d.v000066400000000000000000000007361435245347300200120ustar00rootroot00000000000000timeunit 100ps / 10ps; package testpackage; task delay(output [63:0] t); begin $printtimescale(top); $printtimescale; #5ns t = $time; end endtask endpackage module top(); timeunit 1ns / 1ps; import testpackage::delay; reg [63:0] t1; reg [63:0] t2; initial begin $printtimescale; delay(t1); t2 = $time; $display("%0d %0d", t1, t2); if ((t1 === 50) && (t2 === 5)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1004.v000066400000000000000000000006021435245347300176370ustar00rootroot00000000000000package foobar; class aclass; bit tested = 0; task test; begin $display("Testing classes in packages"); tested = 1; end endtask endclass aclass bar = new; endpackage module test; import foobar::*; initial begin bar.test; if (bar.tested) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1005.v000066400000000000000000000011251435245347300176410ustar00rootroot00000000000000class aclass; reg [3:0] q[$]; endclass module test; aclass a; reg [3:0] d; reg failed = 0; initial begin a = new; a.q.push_back(4'd1); a.q.push_back(4'd2); a.q.push_back(4'd3); a.q.push_back(4'd4); d = a.q.pop_front(); $display("%h", d); if (d !== 4'd1) failed = 1; d = a.q.pop_front(); $display("%h", d); if (d !== 4'd2) failed = 1; d = a.q.pop_front(); $display("%h", d); if (d !== 4'd3) failed = 1; d = a.q.pop_front(); $display("%h", d); if (d !== 4'd4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br1006.v000066400000000000000000000007401435245347300176440ustar00rootroot00000000000000module dut( input wire [3:0] i, output wire [3:0] o ); assign o = i; specify (i[3:0] => o[3:0]) = (1, 1); endspecify endmodule module top(); reg [3:0] i; wire [3:0] o; dut dut(i, o); reg failed = 0; initial begin $monitor($time,,i,,o); #1 i = 4'd1; #0 if (o !== 4'bx) failed = 1; #1 i = 4'd2; #0 if (o !== 4'd1) failed = 1; #1; #0 if (o !== 4'd2) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br1007.v000066400000000000000000000012461435245347300176470ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module test(); reg [4:1] value; reg failed; initial begin failed = 0; value = 4'b0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST value[5] = 1'b1; `endif $display("%b", value); if (value !== 4'b0000) failed = 1; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST value[5:5] = 1'b1; `endif $display("%b", value); if (value !== 4'b0000) failed = 1; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST value[5:4] = 2'b11; `else value[4] = 1'b1; `endif $display("%b", value); if (value !== 4'b1000) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br1008.v000066400000000000000000000002641435245347300176470ustar00rootroot00000000000000 module test(); wire [3:0] a = 4'd0; wire signed [3:0] b[1:0]; assign b[0] = $signed(a); initial begin $display("b = [%b %b]", b[1], b[0]); end endmodule iverilog-12_0/ivtest/ivltests/br1015a.v000066400000000000000000000006141435245347300200050ustar00rootroot00000000000000module test(); function parity(input bit_array[3:0]); integer i; begin parity = 0; for (i = 0; i < 4; i = i + 1) begin $display("%b", bit_array[i]); parity ^= bit_array[i]; end end endfunction reg a[3:0]; reg p; initial begin a[0] = 1; a[1] = 0; a[2] = 1; a[3] = 1; p = parity(a); if (p === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1015b.v000066400000000000000000000006141435245347300200060ustar00rootroot00000000000000module test(); function parity(input bit_array[3:0]); integer i; begin parity = 0; for (i = 0; i < 4; i = i + 1) begin $display("%b", bit_array[i]); parity ^= bit_array[i]; end end endfunction reg a[3:0]; reg p; initial begin a[0] = 1; a[1] = 0; a[2] = 1; a[3] = 1; p = parity(a); if (p === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1019.v000066400000000000000000000006241435245347300176510ustar00rootroot00000000000000module sub(input [3:0] value); wire [3:0] array[1:0]; reg [3:0] monitor; assign array[0] = $unsigned(value); always @(array[0]) begin monitor = array[0]; end endmodule module top; wire [3:0] value; sub sub1(value); sub sub2(value); initial begin force value = 5; #0; if ((sub1.monitor === 5) && (sub2.monitor === 5)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br1025.v000066400000000000000000000005411435245347300176440ustar00rootroot00000000000000function int f (int arg); begin:b // comment to remove bug int i; f = 0; for (i=0; iRHS -- array_bg0 = 'b%b", array_bg0); err=err+1; end if (array_bg1 !== 16'b0111_1111_1111_1111) begin $display("FAILED -- LHS>RHS -- array_bg1 = 'b%b", array_bg1); err=err+1; end if (array_bg2 !== 16'bxxxx_xxxx_0111_1111) begin $display("FAILED -- LHS>RHS -- array_bg2 = 'b%b", array_bg2); err=err+1; end if (array_bg3 !== 16'b0111_1111_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_bg3 = 'b%b", array_bg3); err=err+1; end if (array_bg4 !== 16'bxxxx_xxxx_xxxx_0111) begin $display("FAILED -- LHS>RHS -- array_bg4 = 'b%b", array_bg4); err=err+1; end if (array_bg5 !== 16'b0111_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_bg5 = 'b%b", array_bg5); err=err+1; end if (array_bg6 !== 16'bxxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS -- array_bg6 = 'b%b", array_bg6); err=err+1; end if (array_bg7 !== 16'b01xx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_bg7 = 'b%b", array_bg7); err=err+1; end //if (array_bg8 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- LHS>RHS -- array_bg8 = 'b%b", array_bg8); err=err+1; end //if (array_bg9 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_bg9 = 'b%b", array_bg9); err=err+1; end // test write to array LHS=RHS array_lt0 = {WA*WB{1'bx}}; array_lt1 = {WA*WB{1'bx}}; array_lt1 = {WA *WB +0{1'b1}}; array_lt2 = {WA*WB{1'bx}}; array_lt2 [0 :WA/2-1] = {WA/2*WB +0{1'b1}}; array_lt3 = {WA*WB{1'bx}}; array_lt3 [WA/2:WA -1] = {WA/2*WB +0{1'b1}}; array_lt4 = {WA*WB{1'bx}}; array_lt4 [0 ] = {1 *WB +0{1'b1}}; array_lt5 = {WA*WB{1'bx}}; array_lt5 [ WA -1] = {1 *WB +0{1'b1}}; array_lt6 = {WA*WB{1'bx}}; array_lt6 [0 ][0 :WB/2-1] = {1 *WB/2+0{1'b1}}; array_lt7 = {WA*WB{1'bx}}; array_lt7 [ WA -1][WB/2:WB -1] = {1 *WB/2+0{1'b1}}; array_lt8 = {WA*WB{1'bx}}; array_lt8 [0 ][0 ] = {1 *1 +0{1'b1}}; array_lt9 = {WA*WB{1'bx}}; array_lt9 [ WA -1][ WB -1] = {1 *1 +0{1'b1}}; // check if (array_lt0 !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS=RHS -- array_lt0 = 'b%b", array_lt0); err=err+1; end if (array_lt1 !== 16'b1111_1111_1111_1111) begin $display("FAILED -- LHS=RHS -- array_lt1 = 'b%b", array_lt1); err=err+1; end if (array_lt2 !== 16'b1111_1111_xxxx_xxxx) begin $display("FAILED -- LHS=RHS -- array_lt2 = 'b%b", array_lt2); err=err+1; end if (array_lt3 !== 16'bxxxx_xxxx_1111_1111) begin $display("FAILED -- LHS=RHS -- array_lt3 = 'b%b", array_lt3); err=err+1; end if (array_lt4 !== 16'b1111_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS=RHS -- array_lt4 = 'b%b", array_lt4); err=err+1; end if (array_lt5 !== 16'bxxxx_xxxx_xxxx_1111) begin $display("FAILED -- LHS=RHS -- array_lt5 = 'b%b", array_lt5); err=err+1; end if (array_lt6 !== 16'b11xx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS=RHS -- array_lt6 = 'b%b", array_lt6); err=err+1; end if (array_lt7 !== 16'bxxxx_xxxx_xxxx_xx11) begin $display("FAILED -- LHS=RHS -- array_lt7 = 'b%b", array_lt7); err=err+1; end if (array_lt8 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS=RHS -- array_lt8 = 'b%b", array_lt8); err=err+1; end if (array_lt9 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- LHS=RHS -- array_lt9 = 'b%b", array_lt9); err=err+1; end // test write to array LHSRHS -- array_lt0 = 'b%b", array_lt0); err=err+1; end if (array_lt1 !== 16'b0111_1111_1111_1111) begin $display("FAILED -- LHS>RHS -- array_lt1 = 'b%b", array_lt1); err=err+1; end if (array_lt2 !== 16'b0111_1111_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_lt2 = 'b%b", array_lt2); err=err+1; end if (array_lt3 !== 16'bxxxx_xxxx_0111_1111) begin $display("FAILED -- LHS>RHS -- array_lt3 = 'b%b", array_lt3); err=err+1; end if (array_lt4 !== 16'b0111_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_lt4 = 'b%b", array_lt4); err=err+1; end if (array_lt5 !== 16'bxxxx_xxxx_xxxx_0111) begin $display("FAILED -- LHS>RHS -- array_lt5 = 'b%b", array_lt5); err=err+1; end if (array_lt6 !== 16'b01xx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_lt6 = 'b%b", array_lt6); err=err+1; end if (array_lt7 !== 16'bxxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS -- array_lt7 = 'b%b", array_lt7); err=err+1; end //if (array_lt8 !== 16'b1xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- LHS>RHS -- array_lt8 = 'b%b", array_lt8); err=err+1; end //if (array_lt9 !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- LHS>RHS -- array_lt9 = 'b%b", array_lt9); err=err+1; end // assign a constant value to the array array_bg1 = {WA*WB{1'b1}}; array_bg2 = {WA*WB{1'b1}}; array_bg3 = {WA*WB{1'b1}}; array_bg4 = {WA*WB{1'b1}}; array_bg5 = {WA*WB{1'b1}}; array_bg6 = {WA*WB{1'b1}}; array_bg7 = {WA*WB{1'b1}}; array_bg8 = {WA*WB{1'b1}}; array_bg9 = {WA*WB{1'b1}}; // test read from array LHS=RHS array_1d1 = {WA*WB+1{1'bx}}; array_1d1[WA *WB -1+0:0] = array_bg1 ; array_1d2 = {WA*WB+1{1'bx}}; array_1d2[WA/2*WB -1+0:0] = array_bg2 [WA/2-1:0 ] ; array_1d3 = {WA*WB+1{1'bx}}; array_1d3[WA/2*WB -1+0:0] = array_bg3 [WA -1:WA/2] ; array_1d4 = {WA*WB+1{1'bx}}; array_1d4[1 *WB -1+0:0] = array_bg4 [ 0 ] ; array_1d5 = {WA*WB+1{1'bx}}; array_1d5[1 *WB -1+0:0] = array_bg5 [WA -1 ] ; array_1d6 = {WA*WB+1{1'bx}}; array_1d6[1 *WB/2-1+0:0] = array_bg6 [ 0 ][WB/2-1:0 ]; array_1d7 = {WA*WB+1{1'bx}}; array_1d7[1 *WB/2-1+0:0] = array_bg7 [WA -1 ][WB -1:WB/2]; array_1d8 = {WA*WB+1{1'bx}}; array_1d8[1 *1 -1+0:0] = array_bg8 [ 0 ][ 0 ]; array_1d9 = {WA*WB+1{1'bx}}; array_1d9[1 *1 -1+0:0] = array_bg9 [WA -1 ][WB -1 ]; // check if (array_1d1 !== 17'bx_1111_1111_1111_1111) begin $display("FAILED -- LHS=RHS BE -- array_1d1 = 'b%b", array_1d1); err=err+1; end if (array_1d2 !== 17'bx_xxxx_xxxx_1111_1111) begin $display("FAILED -- LHS=RHS BE -- array_1d2 = 'b%b", array_1d2); err=err+1; end if (array_1d3 !== 17'bx_xxxx_xxxx_1111_1111) begin $display("FAILED -- LHS=RHS BE -- array_1d3 = 'b%b", array_1d3); err=err+1; end if (array_1d4 !== 17'bx_xxxx_xxxx_xxxx_1111) begin $display("FAILED -- LHS=RHS BE -- array_1d4 = 'b%b", array_1d4); err=err+1; end if (array_1d5 !== 17'bx_xxxx_xxxx_xxxx_1111) begin $display("FAILED -- LHS=RHS BE -- array_1d5 = 'b%b", array_1d5); err=err+1; end if (array_1d6 !== 17'bx_xxxx_xxxx_xxxx_xx11) begin $display("FAILED -- LHS=RHS BE -- array_1d6 = 'b%b", array_1d6); err=err+1; end if (array_1d7 !== 17'bx_xxxx_xxxx_xxxx_xx11) begin $display("FAILED -- LHS=RHS BE -- array_1d7 = 'b%b", array_1d7); err=err+1; end if (array_1d8 !== 17'bx_xxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- LHS=RHS BE -- array_1d8 = 'b%b", array_1d8); err=err+1; end if (array_1d9 !== 17'bx_xxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- LHS=RHS BE -- array_1d9 = 'b%b", array_1d9); err=err+1; end // test read from array LHS>RHS array_1d1 = {WA*WB+1{1'bx}}; array_1d1[WA *WB -1+1:0] = array_bg1 ; array_1d2 = {WA*WB+1{1'bx}}; array_1d2[WA/2*WB -1+1:0] = array_bg2 [WA/2-1:0 ] ; array_1d3 = {WA*WB+1{1'bx}}; array_1d3[WA/2*WB -1+1:0] = array_bg3 [WA -1:WA/2] ; array_1d4 = {WA*WB+1{1'bx}}; array_1d4[1 *WB -1+1:0] = array_bg4 [ 0 ] ; array_1d5 = {WA*WB+1{1'bx}}; array_1d5[1 *WB -1+1:0] = array_bg5 [WA -1 ] ; array_1d6 = {WA*WB+1{1'bx}}; array_1d6[1 *WB/2-1+1:0] = array_bg6 [ 0 ][WB/2-1:0 ]; array_1d7 = {WA*WB+1{1'bx}}; array_1d7[1 *WB/2-1+1:0] = array_bg7 [WA -1 ][WB -1:WB/2]; array_1d8 = {WA*WB+1{1'bx}}; array_1d8[1 *1 -1+1:0] = array_bg8 [ 0 ][ 0 ]; array_1d9 = {WA*WB+1{1'bx}}; array_1d9[1 *1 -1+1:0] = array_bg9 [WA -1 ][WB -1 ]; // check if (array_1d1 !== 17'b0_1111_1111_1111_1111) begin $display("FAILED -- LHS>RHS BE -- array_1d1 = 'b%b", array_1d1); err=err+1; end if (array_1d2 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- LHS>RHS BE -- array_1d2 = 'b%b", array_1d2); err=err+1; end if (array_1d3 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- LHS>RHS BE -- array_1d3 = 'b%b", array_1d3); err=err+1; end if (array_1d4 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- LHS>RHS BE -- array_1d4 = 'b%b", array_1d4); err=err+1; end if (array_1d5 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- LHS>RHS BE -- array_1d5 = 'b%b", array_1d5); err=err+1; end if (array_1d6 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- LHS>RHS BE -- array_1d6 = 'b%b", array_1d6); err=err+1; end if (array_1d7 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- LHS>RHS BE -- array_1d7 = 'b%b", array_1d7); err=err+1; end if (array_1d8 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS BE -- array_1d8 = 'b%b", array_1d8); err=err+1; end if (array_1d9 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS BE -- array_1d9 = 'b%b", array_1d9); err=err+1; end // test read from array LHSRHS LE -- array_1d1 = 'b%b", array_1d1); err=err+1; end if (array_1d2 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- LHS>RHS LE -- array_1d2 = 'b%b", array_1d2); err=err+1; end if (array_1d3 !== 17'bx_xxxx_xxx0_1111_1111) begin $display("FAILED -- LHS>RHS LE -- array_1d3 = 'b%b", array_1d3); err=err+1; end if (array_1d4 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- LHS>RHS LE -- array_1d4 = 'b%b", array_1d4); err=err+1; end if (array_1d5 !== 17'bx_xxxx_xxxx_xxx0_1111) begin $display("FAILED -- LHS>RHS LE -- array_1d5 = 'b%b", array_1d5); err=err+1; end if (array_1d6 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- LHS>RHS LE -- array_1d6 = 'b%b", array_1d6); err=err+1; end if (array_1d7 !== 17'bx_xxxx_xxxx_xxxx_x011) begin $display("FAILED -- LHS>RHS LE -- array_1d7 = 'b%b", array_1d7); err=err+1; end if (array_1d8 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS LE -- array_1d8 = 'b%b", array_1d8); err=err+1; end if (array_1d9 !== 17'bx_xxxx_xxxx_xxxx_xx01) begin $display("FAILED -- LHS>RHS LE -- array_1d9 = 'b%b", array_1d9); err=err+1; end // test read from array LHS // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for bug report #942: VHDL function bodies in arch declaration not // supported module br942_test(); logic clk, rst, q; e dut(clk, rst, q); initial begin rst = 1; clk = 0; #1; clk = 1; #1; rst = 0; clk = 0; if(q !== 1'b0) begin $display("FAILED 1"); $finish(); end #1; clk = 1; #1; clk = 0; if(q !== 1'b1) begin $display("FAILED 2"); $finish(); end #1; clk = 1; #1; if(q !== 1'b0) begin $display("FAILED 3"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br942.vhd000066400000000000000000000007731435245347300201160ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity e is port ( clk : in std_logic; rst : in std_logic; q : out std_logic); end e; architecture a of e is signal r : std_logic; function invert ( i : std_logic) return std_logic is begin return not i; end invert; begin q <= r; process(clk) begin if rising_edge(clk) then if rst = '1' then r <= '0'; else r <= invert(r); end if; end if; end process; end a; iverilog-12_0/ivtest/ivltests/br943_944.v000066400000000000000000000025331435245347300201770ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for bug reports: // #943: VHDL enum values not available outside of switch statements // #944: VHDL enum type declaration generates syntax errors module bg943_test(); logic clk, rst, q; e dut(clk, rst, q); initial begin clk = 0; rst = 1; #1; clk = 1; #1; if(q !== 1'b0) begin $display("FAILED 1"); $finish(); end #1; clk = 0; rst = 0; #1; clk = 1; #1; if(q !== 1'b1) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br943_944.vhd000066400000000000000000000010241435245347300205050ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity e is port ( clk : in std_logic; rst : in std_logic; q : out std_logic); end e; architecture a of e is type t is (one, zero); signal r : t; begin q <= '1' when r = one else '0'; process(clk) begin if rising_edge(clk) then if rst = '1' then r <= zero; else case r is when zero => r <= one; when others => r <= zero; end case; end if; end if; end process; end a; iverilog-12_0/ivtest/ivltests/br946.v000066400000000000000000000003031435245347300175730ustar00rootroot00000000000000module test(); integer src; reg dst; initial begin assign dst = src; src = 1; #1 $display(dst); if (dst === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br947.v000066400000000000000000000012221435245347300175750ustar00rootroot00000000000000// Regression test for SF bug 947 : Procedural continuous assignment // affects other structural connections to source vector. `timescale 1ns/1ps module test(); wire delay0; wire delay1; wire delay2; reg select; reg out; assign #100 delay0 = 1; assign #100 delay1 = delay0; assign #100 delay2 = delay1; always @(select) begin if (select) assign out = delay2; else assign out = delay0; end initial begin $monitor($time,, delay0,, delay1,, delay2,, out); select = 0; #250; select = 1; #300; if ((delay0 == 1) && (delay1 == 1) && (delay2 == 1) && (out == 1)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br948.v000066400000000000000000000037261435245347300176110ustar00rootroot00000000000000module top; reg pass; reg in; reg pout; wire out; function invert; input in; // When this is a named block the compiler creates a fork/join to // create the new scope. The problem with this is that of_EXEC_UFUNC // opcode does not work correctly since the vthread_run(child) call // returns when the join is executed which then copies the return value // before the function body code has actually run. This causes the // results to be delayed by one call. Does this need to be split into // two functions. One that acts like fork and copies the input values // and one that acts like join and returns the function result? // It appears that procedural user function calls work correctly since // they use fork/join to call the user function. // Both V0.9 and development have this problem. begin: block_name invert = ~in; $display("Function should return %b when given %b.", invert, in); end endfunction assign out = invert(in); initial begin pass = 1'b1; in = 1'b0; #1; if (out !== 1'b1) begin $display("CA result was %b when given %b, expect 1'b1.", out, in); pass = 1'b0; end pout = invert(in); if (pout !== 1'b1) begin $display("Result was %b when given %b, expect 1'b1.", pout, in); pass = 1'b0; end in = 1'b1; #1; if (out !== 1'b0) begin $display("CA result was %b when given %b, expect 1'b0.", out, in); pass = 1'b0; end pout = invert(in); if (pout !== 1'b0) begin $display("Result was %b when given %b, expect 1'b0.", pout, in); pass = 1'b0; end in = 1'bz; #1; if (out !== 1'bx) begin $display("CA result was %b when given %b, expect 1'bx.", out, in); pass = 1'b0; end pout = invert(in); if (pout !== 1'bx) begin $display("Result was %b when given %b, expect 1'bx.", pout, in); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br955.v000066400000000000000000000043311435245347300176000ustar00rootroot00000000000000`timescale 1 ps / 1 ps module mux_2_to_1 ( input sel_i, input [1:0] dat_i, output dat_o ); assign dat_o = sel_i && dat_i[1] || ~sel_i && dat_i[0]; endmodule module mux_n_to_1 #( parameter sel_w = 4, parameter n_inputs = 2**sel_w ) ( input [n_inputs-1:0] inputs_i, input [sel_w-1:0] sel_i, output output_o ); genvar i,j; generate if(sel_w == 1) begin mux_2_to_1 mux_simple ( .sel_i(sel_i), .dat_i(inputs_i), .dat_o(output_o) ); end else begin wire [n_inputs-2:0] inter_w; for(i=0; i Z) = (0.1, 0.2); (EN => Z) = (0.3, 0.4); endspecify endmodule module ckt (out, in, en); output out; input in, en; TBUF_X2 dut (.A ( in ) , .EN ( en ) , .Z ( out ) ) ; endmodule module top; wire out; reg in, en; ckt dut(out, in, en); initial begin $monitor($realtime,,out,"=",in,,en); $sdf_annotate("ivltests/br960a.sdf", dut); in = 1'b0; en = 1'b0; $display("Max (X->Z)"); // X -> Z = max(enable)) #10; en = 1'b1; $display("Fall (Z->0)"); // Z -> 0 = tf(enable) #10; en = 1'b0; $display("Rise (0->Z)"); // 0 -> Z = tr(enable) #5; in = 1'b1; #5; en = 1'b1; $display("Rise (Z->1)"); // Z -> 1 = tr(enable) #10; en = 1'b0; $display("Fall (1->Z)"); // 1 -> Z = tf(enable) #10; end endmodule iverilog-12_0/ivtest/ivltests/br960b.sdf000066400000000000000000000003001435245347300202350ustar00rootroot00000000000000(DELAYFILE (TIMESCALE 1ns) (CELL (CELLTYPE "TBUF_X2") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Z (0.2) (0.3) (0.4)) (IOPATH EN Z (1.2) (1.3) (1.4)) )) ) ) iverilog-12_0/ivtest/ivltests/br960b.v000066400000000000000000000016631435245347300177430ustar00rootroot00000000000000`timescale 1ns/10ps module TBUF_X2 (A, EN, Z); input A; input EN; output Z; bufif1(Z, A, EN); specify (A => Z) = (0.1, 0.2); (EN => Z) = (0.3, 0.4); endspecify endmodule module ckt (out, in, en); output out; input in, en; TBUF_X2 dut (.A ( in ) , .EN ( en ) , .Z ( out ) ) ; endmodule module top; wire out; reg in, en; ckt dut(out, in, en); initial begin $monitor($realtime,,out,"=",in,,en); $sdf_annotate("ivltests/br960b.sdf", dut); in = 1'b0; en = 1'b0; $display("Max (X->Z)"); // X -> Z = max(enable)) #10; en = 1'b1; $display("Fall (Z->0)"); // Z -> 0 = tf(enable) #10; en = 1'b0; $display("To High-Z (0->Z)"); // 0 -> Z = to High-Z #5; in = 1'b1; #5; en = 1'b1; $display("Rise (Z->1)"); // Z -> 1 = tr(enable) #10; en = 1'b0; $display("To High-Z (1->Z)"); // 1 -> Z = to High-Z #10; end endmodule iverilog-12_0/ivtest/ivltests/br960c.sdf000066400000000000000000000003301435245347300202410ustar00rootroot00000000000000(DELAYFILE (TIMESCALE 1ns) (CELL (CELLTYPE "TBUF_X2") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Z () () (0.2) (0.3) (0.4) (0.5)) (IOPATH EN Z () () (1.2) (1.3) (1.4) (1.5)) )) ) ) iverilog-12_0/ivtest/ivltests/br960c.v000066400000000000000000000014431435245347300177400ustar00rootroot00000000000000`timescale 1ns/10ps module TBUF_X2 (A, EN, Z); input A; input EN; output Z; bufif1(Z, A, EN); specify (A => Z) = (0.1, 0.2); (EN => Z) = (0.3, 0.4); endspecify endmodule module ckt (out, in, en); output out; input in, en; TBUF_X2 dut (.A ( in ) , .EN ( en ) , .Z ( out ) ) ; endmodule module top; wire out; reg in, en; ckt dut(out, in, en); initial begin $monitor($realtime,,out,"=",in,,en); $sdf_annotate("ivltests/br960c.sdf", dut); in = 1'b0; en = 1'b0; $display("Max (X->Z)"); // X -> Z = max(enable)) #10; en = 1'b1; $display("Z->0"); #10; en = 1'b0; $display("0->Z"); #5; in = 1'b1; #5; en = 1'b1; $display("Z->1"); #10; en = 1'b0; $display("1->Z"); #10; end endmodule iverilog-12_0/ivtest/ivltests/br960d.sdf000066400000000000000000000002501435245347300202430ustar00rootroot00000000000000(DELAYFILE (TIMESCALE 1ns) (CELL (CELLTYPE "TBUF_X2") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Z (0.2)) (IOPATH EN Z (1.2)) )) ) ) iverilog-12_0/ivtest/ivltests/br960d.v000066400000000000000000000016531435245347300177440ustar00rootroot00000000000000`timescale 1ns/10ps module TBUF_X2 (A, EN, Z); input A; input EN; output Z; bufif1(Z, A, EN); specify (A => Z) = (0.1, 0.2); (EN => Z) = (0.3, 0.4); endspecify endmodule module ckt (out, in, en); output out; input in, en; TBUF_X2 dut (.A ( in ) , .EN ( en ) , .Z ( out ) ) ; endmodule module top; wire out; reg in, en; ckt dut(out, in, en); initial begin $monitor($realtime,,out,"=",in,,en); $sdf_annotate("ivltests/br960d.sdf", dut); in = 1'b0; en = 1'b0; $display("Max (X->Z)"); // X -> Z = max(enable)) #10; en = 1'b1; $display("Fall (Z->0)"); // Z -> 0 = tr(enable) #10; en = 1'b0; $display("Rise (0->Z)"); // 0 -> Z = tr(enable) #5; in = 1'b1; #5; en = 1'b1; $display("Rise (Z->1)"); // Z -> 1 = tr(enable) #10; en = 1'b0; $display("Fall (1->Z)"); // 1 -> Z = tr(enable) #10; end endmodule iverilog-12_0/ivtest/ivltests/br961.v000066400000000000000000000004301435245347300175710ustar00rootroot00000000000000module test; localparam w = 8; function [w-1:0] copy; input [w-1:0] w; begin copy = w; end endfunction reg [w-1:0] value; initial begin value = copy(21); $display("%d", value); if (value === 21) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br961a.v000066400000000000000000000002151435245347300177330ustar00rootroot00000000000000// Check the compiler fails gracefully module test; function [w-1:0] copy; input [w-1:0] z; begin copy = z; end endfunction endmodule iverilog-12_0/ivtest/ivltests/br962.v000066400000000000000000000015121435245347300175740ustar00rootroot00000000000000// Regression test for br962 - based on test case provided in bug report module qtest; parameter width = 32; parameter depth = 32; reg [width-1:0] values[$]; reg [$clog2(depth)+width-1:0] sum1; reg [$clog2(depth)+width-1:0] sum2; task new_sample; input [width-1:0] data; int i; begin reg [width-1:0] popped; if (values.size >= depth) sum1 = sum1 - values.pop_back(); sum1 = sum1 + data; values.push_front(data); sum2 = 0; for (i = 0; i < values.size; i++) begin sum2 = sum2 + values[i]; end $display("sum1 = %d sum2 = %d", sum1, sum2); if (sum1 !== sum2) begin $display("FAILED"); $finish; end end endtask initial begin sum1 = 0; repeat (2*depth) new_sample({$random}); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br963.v000066400000000000000000000015601435245347300176000ustar00rootroot00000000000000// Regression test for br962 - based on test case provided in bug report module qtest; parameter width = 32; parameter depth = 32; reg [width-1:0] values[$]; reg [$clog2(depth)+width-1:0] sum1; reg [$clog2(depth)+width-1:0] sum2; task new_sample; input [width-1:0] data; int i; begin reg [width-1:0] popped; if (values.size >= depth) begin : foo popped = values.pop_back(); sum1 = sum1 - popped; end sum1 = sum1 + data; values.push_front(data); sum2 = 0; for (i = 0; i < values.size; i++) begin sum2 = sum2 + values[i]; end $display("sum1 = %d sum2 = %d", sum1, sum2); if (sum1 !== sum2) begin $display("FAILED"); $finish; end end endtask initial begin sum1 = 0; repeat (2*depth) new_sample({$random}); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br965.v000066400000000000000000000005441435245347300176030ustar00rootroot00000000000000module top; wire [2:0] value = 2; shim shim( .bit0(value[0]), .bit1(value[1]), .bit2(value[2]) ); endmodule module shim( inout wire bit0, inout wire bit1, inout wire bit2 ); wire [2:0] value = {bit2, bit1, bit0}; initial begin #1 $display(value); if (value === 2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br967.v000066400000000000000000000003241435245347300176010ustar00rootroot00000000000000module test(); integer count = 0; initial begin repeat (10.4) begin count = count + 1; $display(count); end if (count === 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br968.v000066400000000000000000000022401435245347300176010ustar00rootroot00000000000000module top; reg passed; reg [7:0] val; reg signed [7:0] sval; real rval; initial begin passed = 1'b1; val = 8'hff; sval = 8'hff; /* Check a constant unsigned value cast to signed. */ rval = $itor($signed(8'hff)); if (rval != -1.0) begin $display("Failed unsigned constant cast to signed conversion, ", "expected -1.0, got %g.", rval); passed = 1'b0; end /* Check an unsigned variable cast to signed. */ rval = $itor($signed(val)); if (rval != -1.0) begin $display("Failed unsigned variable cast to signed conversion, ", "expected -1.0, got %g.", rval); passed = 1'b0; end /* Check a constant signed value. */ rval = $itor(8'shff); if (rval != -1.0) begin $display("Failed signed constant conversion, ", "expected -1.0, got %g.", rval); passed = 1'b0; end /* Check a variable signed value. */ rval = $itor(sval); if (rval != -1.0) begin $display("Failed signed variable conversion, ", "expected -1.0, got %g.", rval); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br971.v000066400000000000000000000005771435245347300176060ustar00rootroot00000000000000// Icarus doesn't properly support variable expressions on the right hand // side of a procedural CA - see bug 605. module test(); reg [1:0] addr; reg [3:0] memory[3:0]; reg [3:0] data; initial begin assign data = memory[addr]; addr = 1; memory[addr] = 2; #0 $display("%d", data); if (data === 2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br972.v000066400000000000000000000006371435245347300176040ustar00rootroot00000000000000module test(); reg in; wire out; assign out = out | in; reg failed; initial begin #1 in = 0; #0 $display("out = %b", out); if (out !== 1'bx) failed = 1; #1 in = 1; #0 $display("out = %b", out); if (out !== 1'b1) failed = 1; #1 in = 0; #0 $display("out = %b", out); if (out !== 1'b1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br973.v000066400000000000000000000005101435245347300175730ustar00rootroot00000000000000// Regression test for bug #973 module test(); typedef enum bit { A0, A1 } A; typedef enum logic { B0, B1 } B; typedef enum reg { C0, C1 } C; A enum1; B enum2; C enum3; initial begin if ($bits(enum1) == 1 && $bits(enum2) == 1 && $bits(enum3) == 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br974a.v000066400000000000000000000010101435245347300177310ustar00rootroot00000000000000typedef logic data_t; module dut(i, o); input data_t i; output data_t o; always @* o = i; endmodule module test(); data_t i, o; dut dut(i, o); reg failed = 0; initial begin i = 1'b0; #0 $display(i,,o); if (o !== 1'b0) failed = 1; i = 1'b1; #0 $display(i,,o); if (o !== 1'b1) failed = 1; i = 1'bx; #0 $display(i,,o); if (o !== 1'bx) failed = 1; i = 1'bz; #0 $display(i,,o); if (o !== 1'bz) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br974b.v000066400000000000000000000005221435245347300177410ustar00rootroot00000000000000module dut(i, o); input logic [3:0] i; output logic [3:0] o; always @* o = i; endmodule module test(); logic [3:0] i, o; dut dut(i, o); reg failed = 0; initial begin i = 4'b01xz; #0 $display("%b %b", i, o); if (o !== 4'b01xz) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br974c.v000066400000000000000000000005571435245347300177520ustar00rootroot00000000000000module dut(i, o); input [3:0] i; output [3:0] o; wire logic [3:0] i; reg [3:0] o; always @* o = i; endmodule module test(); logic [3:0] i, o; dut dut(i, o); reg failed = 0; initial begin i = 4'b01xz; #0 $display("%b %b", i, o); if (o !== 4'b01xz) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br975.v000066400000000000000000000004001435245347300175730ustar00rootroot00000000000000// Test error handling for duplicate variable declarations. module bug(); typedef struct packed { logic value; } data_t; typedef enum { A, B } enum_t; wire w1; wire w1; data_t d1; data_t d1; enum_t e1; enum_t e1; reg r1; reg r1; endmodule iverilog-12_0/ivtest/ivltests/br977.v000066400000000000000000000002661435245347300176070ustar00rootroot00000000000000`define DECLAREINT(name, i) integer name=i module foo(); `DECLAREINT(bar, 2); initial begin if (bar === 2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br978.v000066400000000000000000000003751435245347300176110ustar00rootroot00000000000000module test(); wire [15:0] data = 8; wire [15:0] result; assign result = data + $ivlh_to_unsigned(8, 16); initial begin #1 $display("result = %0d", result); if (result === 16) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br979.v000066400000000000000000000006551435245347300176130ustar00rootroot00000000000000`define my_macro(a,b) localparam `` i``a``b``j = 8'h``a``b; \ \ module test(); `my_macro(0,1) `my_macro( 2, 3) `my_macro( 4 , 5 ) reg failed = 0; initial begin $display("%h", i01j); if (i01j !== 8'h01) failed = 1; $display("%h", i23j); if (i23j !== 8'h23) failed = 1; $display("%h", i45j); if (i45j !== 8'h45) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br982.v000066400000000000000000000002751435245347300176030ustar00rootroot00000000000000module example; task simple_task; input in; output out; begin out = in; end endtask reg x = 0; initial begin simple_task(x); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br982a.v000066400000000000000000000003031435245347300177340ustar00rootroot00000000000000module example; function simple_func; input in; begin simple_func = in; end endfunction reg x = 0; initial begin x = simple_func(x,x); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br982b.v000066400000000000000000000003011435245347300177330ustar00rootroot00000000000000module example; task simple_task; input in; output out; begin out = in; end endtask reg x = 0; initial begin simple_task(x,x,x); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br985.v000066400000000000000000000023641435245347300176070ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA module br985_test; logic [3:0] sel; logic value, spi_sdo; bug3 dut(sel, value, spi_sdo); initial begin int i; sel = 4'b0000; #1 if(spi_sdo !== 1'b1) begin $display("FAILED"); $finish(); end for(i = 1; i < 16; i = i + 1) begin sel = i; #1 if(spi_sdo !== 1'b0) begin $display("FAILED"); $finish(); end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br985.vhd000066400000000000000000000006211435245347300201150ustar00rootroot00000000000000-- Reduced test case, bug originally found in 4DSP's fmc110_ctrl.vhd library ieee; use ieee.std_logic_1164.all; entity bug3 is port ( sel : in std_logic_vector(3 downto 0); value : in std_logic; spi_sdo : out std_logic ); end bug3; architecture bug3_syn of bug3 is begin -- no problem if the "not" is taken out spi_sdo <= not or_reduce(sel); end bug3_syn; iverilog-12_0/ivtest/ivltests/br986.v000066400000000000000000000017521435245347300176100ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA module br987_test; logic clk_i, clk_ib, clk_o; bug3 dut(clk_i, clk_ib, clk_o); initial begin // it is enough to have the test unit compiled $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br986.vhd000066400000000000000000000015151435245347300201210ustar00rootroot00000000000000-- Reduced test case, bug originally found in 4DSP's fmc110_ctrl.vhd library ieee; use ieee.std_logic_1164.all; entity bug3 is port ( clk1_i : in std_logic; clk1_ib : in std_logic; clk1_o : out std_logic ); end bug3; architecture bug3_syn of bug3 is component IBUFDS generic ( DIFF_TERM : boolean := FALSE ); port( O : out std_logic; I : in std_logic; IB : in std_logic ); end component; begin ibufds1 : ibufds generic map ( DIFF_TERM => TRUE -- change to "1" and vhdlpp is happy ) port map ( i => clk1_i, ib => clk1_ib, o => clk1_o ); end bug3_syn; entity ibufds is generic ( DIFF_TERM : boolean := FALSE ); port ( i : in std_logic; ib : in std_logic; o : out std_logic ); end ibufds; architecture ibufds_sim of ibufds is begin o <= i; end ibufds_sim; iverilog-12_0/ivtest/ivltests/br987.v000066400000000000000000000017611435245347300176110ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA module br987_test; logic clk, trig, data_o; bug5 dut(clk, trig, data_o); initial begin trig = 1; clk = 0; #1 clk = ~clk; #1 clk = ~clk; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br987.vhd000066400000000000000000000006101435245347300201150ustar00rootroot00000000000000-- Reduced test case, bug originally found in 4DSP's fmc110_ads5400_ctrl.vhd entity bug5 is port ( clk : in std_logic; trig : in std_logic; data_o : out std_logic ); end bug5; architecture bug5_syn of bug5 is begin dummy:process(clk) begin if (trig = '1') then --data_o <= '1'; -- uncomment this and everythings's OK end if; end process dummy; end bug5_syn; iverilog-12_0/ivtest/ivltests/br988.v000066400000000000000000000003661435245347300176120ustar00rootroot00000000000000module test(); parameter P = 1'b1; generate if (P) begin : outer begin : inner reg [1:0] a = 2; end end endgenerate initial begin if (outer.inner.a == 2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br990.v000066400000000000000000000003641435245347300176010ustar00rootroot00000000000000module dut #(parameter a = 1, b = 2, c = 3) (); initial begin $display("%0d %0d %0d", a, b, c); if (b === 2) $display("PASSED"); else $display("FAILED"); end endmodule module top(); dut #(.a(4), .b(), .c(5)) dut(); endmodule iverilog-12_0/ivtest/ivltests/br991a.v000066400000000000000000000007721435245347300177460ustar00rootroot00000000000000module test(); reg clk; reg [1:0] state; always begin case (state) 0 : state = 1; 1 : state = 2; default : /* do nothing */ ; endcase @(posedge clk); end reg failed = 0; initial begin clk = 0; state = 0; #1 clk = 1; #1 clk = 0; if (state !== 1) failed = 1; #1 clk = 1; #1 clk = 0; if (state !== 2) failed = 1; #1 clk = 1; #1 clk = 0; if (state !== 2) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br991b.v000066400000000000000000000004411435245347300177400ustar00rootroot00000000000000// These don't do anything useful, but check for compiler errors. module test(); integer i; always begin for (i = 0; i < 10; i = i + 1) ; end always begin repeat (1) ; end always begin while (1) ; end always begin do ; while (1); end always begin forever ; end endmodule iverilog-12_0/ivtest/ivltests/br993a.v000066400000000000000000000013071435245347300177430ustar00rootroot00000000000000module br993a(); reg clk; reg a; reg b; reg [1:0] q; (* ivl_synthesis_on *) always @(posedge clk) begin q <= 0; if (a) q <= 1; if (b) q <= 2; end (* ivl_synthesis_off *) reg failed; initial begin clk = 0; a = 0; b = 0; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd0) failed = 1; a = 1; b = 0; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd1) failed = 1; a = 1; b = 1; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd2) failed = 1; a = 0; b = 1; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd2) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br993b.v000066400000000000000000000014371435245347300177500ustar00rootroot00000000000000module br993a(); reg clk; reg a; reg b; reg [1:0] q; (* ivl_synthesis_on *) always @(posedge clk) begin if (a) q <= 1; if (b) q <= 2; end (* ivl_synthesis_off *) reg failed; initial begin clk = 0; a = 1; b = 1; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd2) failed = 1; a = 0; b = 0; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd2) failed = 1; a = 1; b = 0; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd1) failed = 1; a = 0; b = 0; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd1) failed = 1; a = 0; b = 1; #1 clk = 1; #1 clk = 0; $display("%d", q); if (q !== 2'd2) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br994.v000066400000000000000000000010311435245347300175750ustar00rootroot00000000000000module test(); reg clk; reg sel; reg [7:0] a; reg [6:0] b; reg [5:0] q; (* ivl_synthesis_on *) always @(posedge clk) begin if (sel) q <= b; else q <= a; end (* ivl_synthesis_off *) reg failed; initial begin a = 'haa; b = 'hbb; clk = 0; sel = 0; #1 clk = 1; #1 clk = 0; $display("%h", q); if (q !== 6'h2a) failed = 1; sel = 1; #1 clk = 1; #1 clk = 0; $display("%h", q); if (q !== 6'h3b) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br995.v000066400000000000000000000007601435245347300176060ustar00rootroot00000000000000module dpram #( parameter aw=8, parameter dw=8 ) (input clka, clkb, wena, input [aw-1:0] addra, addrb, input [dw-1:0] dina, output [dw-1:0] doutb ); // minimalist dual-port RAM model, hope most tools can synthesize it localparam sz=(32'b1<= |1'bx. module bug(); wire y = 1'b1 >= 1'bx; initial begin #0 $display("%b", y); if (y !== 1'bx) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh142.v000066400000000000000000000001271435245347300202410ustar00rootroot00000000000000module test(); parameter y = 1; parameter a = 0; parameter x = y ? a : b; endmodule iverilog-12_0/ivtest/ivltests/br_gh15.v000066400000000000000000000004411435245347300201570ustar00rootroot00000000000000// Regression test for GitHub issue 15 : Icarus does undef propagation of // const adds incorrectly module bug(); wire [3:0] y; assign y = 4'bxx00 + 2'b00; initial begin #0 $display("%b", y); if (y === 4'bxxxx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh152.v000066400000000000000000000000761435245347300202450ustar00rootroot00000000000000module d(); nand n2(w1, nand n1(w2); endmodule iverilog-12_0/ivtest/ivltests/br_gh156.v000066400000000000000000000005741435245347300202540ustar00rootroot00000000000000 // // This tests that the parameter and localparam show up in the vcd dump. // module main; parameter [3:0] foo = 4'd5; localparam [3:0] bar = 7; parameter real PI = 3.14; wire [3:0] bat = foo + bar; wire real tau = 2.0 * PI; initial begin $dumpfile("work/br_gh156.vcd"); $dumpvars(0, main); #1 $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh157.v000066400000000000000000000002051435245347300202440ustar00rootroot00000000000000module dut(); localparam x = 2; initial $display("%0d", x); endmodule module test(); dut dut(); defparam dut.x = 1; endmodule iverilog-12_0/ivtest/ivltests/br_gh162.v000066400000000000000000000002701435245347300202420ustar00rootroot00000000000000module test(); localparam value = {16384{4'b1001}}; wire [65535:0] q = value; initial begin if (q === value) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh163.v000066400000000000000000000002221435245347300202400ustar00rootroot00000000000000module m; task t1; input make_me_crash i; begin end endtask task t2; input integer i; begin end endtask endmodule iverilog-12_0/ivtest/ivltests/br_gh164a.v000066400000000000000000000014651435245347300204140ustar00rootroot00000000000000module test; bit [7:0] mema[]; bit [7:0] memb[]; reg failed = 0; initial begin mema = new[4] ('{8'd1,8'd2,8'd3,8'd4}); $display("%x %x %x %x", mema[0], mema[1], mema[2], mema[3]); memb = new[4] (mema); $display("%x %x %x %x", memb[0], memb[1], memb[2], memb[3]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4) failed = 1; memb = new[5] (memb); $display("%x %x %x %x %x", memb[0], memb[1], memb[2], memb[3], memb[4]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4 || memb[4] !== 8'b0) failed = 1; memb = new[3] (memb); $display("%x %x %x", memb[0], memb[1], memb[2]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh164b.v000066400000000000000000000014651435245347300204150ustar00rootroot00000000000000module test; reg [7:0] mema[]; reg [7:0] memb[]; reg failed = 0; initial begin mema = new[4] ('{8'd1,8'd2,8'd3,8'd4}); $display("%x %x %x %x", mema[0], mema[1], mema[2], mema[3]); memb = new[4] (mema); $display("%x %x %x %x", memb[0], memb[1], memb[2], memb[3]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4) failed = 1; memb = new[5] (memb); $display("%x %x %x %x %x", memb[0], memb[1], memb[2], memb[3], memb[4]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4 || memb[4] !== 8'bx) failed = 1; memb = new[3] (memb); $display("%x %x %x", memb[0], memb[1], memb[2]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh164c.v000066400000000000000000000014511435245347300204110ustar00rootroot00000000000000module test; int mema[]; int memb[]; reg failed = 0; initial begin mema = new[4] ('{8'd1,8'd2,8'd3,8'd4}); $display("%x %x %x %x", mema[0], mema[1], mema[2], mema[3]); memb = new[4] (mema); $display("%x %x %x %x", memb[0], memb[1], memb[2], memb[3]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4) failed = 1; memb = new[5] (memb); $display("%x %x %x %x %x", memb[0], memb[1], memb[2], memb[3], memb[4]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3 || memb[3] !== 8'd4 || memb[4] !== 8'b0) failed = 1; memb = new[3] (memb); $display("%x %x %x", memb[0], memb[1], memb[2]); if (memb[0] !== 8'd1 || memb[1] !== 8'd2 || memb[2] !== 8'd3) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh164d.v000066400000000000000000000014171435245347300204140ustar00rootroot00000000000000module test; real mema[]; real memb[]; reg failed = 0; initial begin mema = new[4] ('{1.5,2.5,3.5,4.5}); $display("%f %f %f %f", mema[0], mema[1], mema[2], mema[3]); memb = new[4] (mema); $display("%f %f %f %f", memb[0], memb[1], memb[2], memb[3]); if (memb[0] != 1.5 || memb[1] != 2.5 || memb[2] != 3.5 || memb[3] != 4.5) failed = 1; memb = new[5] (memb); $display("%f %f %f %f %f", memb[0], memb[1], memb[2], memb[3], memb[4]); if (memb[0] != 1.5 || memb[1] != 2.5 || memb[2] != 3.5 || memb[3] != 4.5 || memb[4] != 0.0) failed = 1; memb = new[3] (memb); $display("%f %f %f", memb[0], memb[1], memb[2]); if (memb[0] != 1.5 || memb[1] != 2.5 || memb[2] != 3.5) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh164e.v000066400000000000000000000014221435245347300204110ustar00rootroot00000000000000module test; string mema[]; string memb[]; reg failed = 0; initial begin mema = new[4] ('{"A","B","C","D"}); $display("%s %s %s %s", mema[0], mema[1], mema[2], mema[3]); memb = new[4] (mema); $display("%s %s %s %s", memb[0], memb[1], memb[2], memb[3]); if (memb[0] != "A" || memb[1] != "B" || memb[2] != "C" || memb[3] != "D") failed = 1; memb = new[5] (memb); $display("%s %s %s %s %s", memb[0], memb[1], memb[2], memb[3], memb[4]); if (memb[0] != "A" || memb[1] != "B" || memb[2] != "C" || memb[3] != "D" || memb[4] != "") failed = 1; memb = new[3] (memb); $display("%s %s %s", memb[0], memb[1], memb[2]); if (memb[0] != "A" || memb[1] != "B" || memb[2] != "C") failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh165.v000066400000000000000000000006401435245347300202460ustar00rootroot00000000000000module test; task automatic foo(input int id); #1000 $display("task %0d finished at time %0t", id, $time); endtask initial begin $display("main thread started at time %0t", $time); fork #1 foo(1); #2 foo(2); join_none #5; $display("main thread continued at time %0t", $time); fork #1 foo(3); #2 foo(4); join_any $display("main thread finished at time %0t", $time); end endmodule iverilog-12_0/ivtest/ivltests/br_gh167a.v000066400000000000000000000003431435245347300204110ustar00rootroot00000000000000class my_class; task run_test(); $display("PASSED"); endtask endclass class extended_class extends my_class; endclass module test(); extended_class obj; initial begin obj = new(); obj.run_test(); end endmodule iverilog-12_0/ivtest/ivltests/br_gh167b.v000066400000000000000000000003431435245347300204120ustar00rootroot00000000000000class my_class; task run_test(); $display("PASSED"); endtask endclass module test(); class extended_class extends my_class; endclass extended_class obj; initial begin obj = new(); obj.run_test(); end endmodule iverilog-12_0/ivtest/ivltests/br_gh175.v000066400000000000000000000045261435245347300202560ustar00rootroot00000000000000 module dut (output reg[31:0] size, output reg signed [31:0] ival, output reg [31:0] hval); parameter string foo = "1234"; string tmp; real rval; initial begin size = foo.len(); ival = foo.atoi(); hval = foo.atohex(); rval = foo.atoreal(); tmp = foo; $display("foo=%0s, tmp=%0s", foo, tmp); if (tmp != foo) begin $display("FAILED"); $finish; end $display("rval=%f", rval); if (rval != ival) begin $display("FAILED -- rval=%f, ival=%0d", rval, ival); $finish; end end endmodule // dut module main; wire [31:0] dut0_size, dut1_size, dut2_size; wire signed [31:0] dut0_ival, dut1_ival, dut2_ival; wire unsigned [31:0] dut0_hval, dut1_hval, dut2_hval; // Instantate module with string parameter, use default value. dut dut0 (dut0_size, dut0_ival, dut0_hval); // Instantate module with string parameter, use override value. dut #(.foo("12345")) dut1 (dut1_size, dut1_ival, dut1_hval); // Instantate module with string parameter, use defparam value. defparam dut2.foo = "123456"; dut dut2 (dut2_size, dut2_ival, dut2_hval); initial begin #100 ; $display("dut0_size=%0d", dut0_size); if (dut0_size !== 4) begin $display("FAILED"); $finish; end $display("dut1_size=%0d", dut1_size); if (dut1_size !== 5) begin $display("FAILED"); $finish; end $display("dut2_size=%0d", dut2_size); if (dut2_size !== 6) begin $display("FAILED"); $finish; end $display("dut0_ival=%0d", dut0_ival); if (dut0_ival !== 1234) begin $display("FAILED"); $finish; end $display("dut1_ival=%0d", dut1_ival); if (dut1_ival !== 12345) begin $display("FAILED"); $finish; end $display("dut2_ival=%0d", dut2_ival); if (dut2_ival !== 123456) begin $display("FAILED"); $finish; end $display("dut0_hval=%0h", dut0_hval); if (dut0_hval !== 32'h1234) begin $display("FAILED"); $finish; end $display("dut1_hval=%0h", dut1_hval); if (dut1_hval !== 32'h12345) begin $display("FAILED"); $finish; end $display("dut2_hval=%0h", dut2_hval); if (dut2_hval !== 32'h123456) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh177a.v000066400000000000000000000015221435245347300204120ustar00rootroot00000000000000 class test_t; enum bit [1:0] { X, Y } foo; task go; foo = X; $display("test_t.foo=%b (X==0)", foo); if (foo !== X) begin $display("FAILED"); $finish; end foo = Y; $display("test_t.foo=%b (Y==1)", foo); if (foo !== Y) begin $display("FAILED"); $finish; end endtask endclass // test_t module main; typedef enum bit [1:0] { X, Y } xy_t; xy_t foo; initial begin foo = Y; $display("foo=%b (Y==1)", foo); if (foo !== Y) begin $display("FAILED"); $finish; end foo = X; $display("foo=%b (X==0)", foo); if (foo !== X) begin $display("FAILED"); $finish; end end test_t bar; initial begin bar = new; bar.go(); end initial begin #1 $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh177b.v000066400000000000000000000015501435245347300204140ustar00rootroot00000000000000 class test_t; typedef enum bit [1:0] { U, V } uv_t; uv_t foo; task go; foo = U; $display("test_t.foo=%b (U==0)", foo); if (foo !== U) begin $display("FAILED"); $finish; end foo = V; $display("test_t.foo=%b (V==1)", foo); if (foo !== V) begin $display("FAILED"); $finish; end endtask endclass // test_t module main; typedef enum bit [1:0] { X, Y } xy_t; xy_t foo; initial begin foo = Y; $display("foo=%b (Y==1)", foo); if (foo !== Y) begin $display("FAILED"); $finish; end foo = X; $display("foo=%b (X==0)", foo); if (foo !== X) begin $display("FAILED"); $finish; end end test_t bar; initial begin bar = new; bar.go(); end initial begin #1 $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh18.v000066400000000000000000000004311435245347300201610ustar00rootroot00000000000000// Regression test for GitHub issue 18 : Icarus does undef propagation of // const multiplies incorrectly. module bug(); wire [3:0] y = 4'b0 * 4'bx; initial begin #0 $display("%b", y); if (y === 4'bxxxx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh19.v000066400000000000000000000004411435245347300201630ustar00rootroot00000000000000// Regression test for GitHub issue 19 : Icarus only using the lowest 32 // bits of right shift operand. module bug(); wire [3:0] y = 4'b1 << 33'h100000000; initial begin #0 $display("%b", y); if (y === 4'b0000) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh194.v000066400000000000000000000011331435245347300202460ustar00rootroot00000000000000 module string_example; function int example( string my_string ); if( my_string[1] != 8'h65 ) begin return 1; end else begin return 0; end endfunction // example string test_string; initial begin test_string = "Hello, World"; if (test_string[0] !== 8'h48) begin $display("FAILED -- test+string[0] = %h", test_string[0]); $finish; end if (example(test_string) === 1) begin $display("FAILED -- example(test_string) returned error."); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br_gh198.v000066400000000000000000000031071435245347300202550ustar00rootroot00000000000000module octal(); reg [5:0] var1; reg [4:0] var2; initial begin var1 = 6'o00; $displayo($signed(var1)); var1 = 6'o01; $displayo($signed(var1)); var1 = 6'o02; $displayo($signed(var1)); var1 = 6'o03; $displayo($signed(var1)); var1 = 6'o04; $displayo($signed(var1)); var1 = 6'o05; $displayo($signed(var1)); var1 = 6'o06; $displayo($signed(var1)); var1 = 6'o07; $displayo($signed(var1)); var1 = 6'o10; $displayo($signed(var1)); var1 = 6'o20; $displayo($signed(var1)); var1 = 6'o30; $displayo($signed(var1)); var1 = 6'o40; $displayo($signed(var1)); var1 = 6'o50; $displayo($signed(var1)); var1 = 6'o60; $displayo($signed(var1)); var1 = 6'o70; $displayo($signed(var1)); var1 = 6'o17; $displayo($signed(var1)); var1 = 6'o26; $displayo($signed(var1)); var1 = 6'o35; $displayo($signed(var1)); var1 = 6'o44; $displayo($signed(var1)); var1 = 6'o53; $displayo($signed(var1)); var1 = 6'o62; $displayo($signed(var1)); var1 = 6'o71; $displayo($signed(var1)); $display(""); var2 = 6'o00; $displayo($signed(var2)); var2 = 6'o01; $displayo($signed(var2)); var2 = 6'o02; $displayo($signed(var2)); var2 = 6'o03; $displayo($signed(var2)); var2 = 6'o04; $displayo($signed(var2)); var2 = 6'o05; $displayo($signed(var2)); var2 = 6'o06; $displayo($signed(var2)); var2 = 6'o07; $displayo($signed(var2)); var2 = 6'o10; $displayo($signed(var2)); var2 = 6'o20; $displayo($signed(var2)); var2 = 6'o30; $displayo($signed(var2)); var2 = 6'o17; $displayo($signed(var2)); var2 = 6'o26; $displayo($signed(var2)); var2 = 6'o35; $displayo($signed(var2)); end endmodule iverilog-12_0/ivtest/ivltests/br_gh199a.v000066400000000000000000000013571435245347300204240ustar00rootroot00000000000000module bug(); reg [31:0] n1, d1, q1, m1; reg [63:0] n2, d2, q2, m2; initial begin n1 = 32'h8000_0000; d1 = 32'hFFFF_FFFF; q1 = $signed(n1) / $signed(d1); $display("32 bit quotient = 0x%08h;", q1); m1 = $signed(n1) % $signed(d1); $display("32 bit modulus = 0x%08h;", m1); n2 = 64'h8000_0000_0000_0000; d2 = 64'hFFFF_FFFF_FFFF_FFFF; q2 = $signed(n2) / $signed(d2); $display("64 bit quotient = 0x%016h;", q2); m2 = $signed(n2) % $signed(d2); $display("64 bit modulus = 0x%016h;", m2); if ((q1 === 32'h8000_0000) && (q2 === 64'h8000_0000_0000_0000) && (m1 === 32'h0000_0000) && (m2 === 64'h0000_0000_0000_0000)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh199b.v000066400000000000000000000014461435245347300204240ustar00rootroot00000000000000module bug(); localparam signed [31:0] n1 = 32'h8000_0000; localparam signed [31:0] d1 = 32'hFFFF_FFFF; localparam signed [31:0] q1 = n1 / d1; localparam signed [31:0] m1 = n1 % d1; localparam signed [63:0] n2 = 64'h8000_0000_0000_0000; localparam signed [63:0] d2 = 64'hFFFF_FFFF_FFFF_FFFF; localparam signed [63:0] q2 = n2 / d2; localparam signed [63:0] m2 = n2 % d2; initial begin $display("32 bit quotient = 0x%08h;", q1); $display("32 bit modulus = 0x%08h;", m1); $display("64 bit quotient = 0x%016h;", q2); $display("64 bit modulus = 0x%016h;", m2); if ((q1 === 32'h8000_0000) && (q2 === 64'h8000_0000_0000_0000) && (m1 === 32'h0000_0000) && (m2 === 64'h0000_0000_0000_0000)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh19a.v000066400000000000000000000004621435245347300203270ustar00rootroot00000000000000// Regression test for GitHub issue 19 : Icarus only using the lowest 32 // bits of right shift operand (run-time test) module bug(); reg a; reg y; initial begin a = 1; y = 1 >> {a, 64'b0}; $display("%b", y); if (y === 1'b0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh19b.v000066400000000000000000000004551435245347300203320ustar00rootroot00000000000000// Regression test for GitHub issue 19 : Icarus only using the lowest 32 // bits of right shift operand (run-time test) module bug(); wire a = 1; wire y = 1 >> {a, 64'b0}; initial begin #0 $display("%b", y); if (y === 1'b0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh209.v000066400000000000000000000002221435245347300202410ustar00rootroot00000000000000module test(); integer f; initial begin f = $fopen("work/br_gh209.dat"); $fwrite(f, "%c%c%c%c", 8'h00, 8'h01, 8'h02, 8'h03); end endmodule iverilog-12_0/ivtest/ivltests/br_gh219.v000066400000000000000000000006341435245347300202510ustar00rootroot00000000000000module Main(); logic[2:0] a = 3'b111; logic signed[2:0] a_signed = 3'b111; logic[2:0] b = 0; logic[3:0] c0; logic[3:0] c1; initial begin c0 = 4'($signed(a)) + b; c1 = 4'(a_signed) + b; $display("c0: %b", c0); $display("c1: %b", c1); if (c0 === 4'b1111 && c1 === 4'b1111) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh22.v000066400000000000000000000004411435245347300201550ustar00rootroot00000000000000// Regression test for GitHub issue 22 module bug(); reg [1:0] a; reg [2:0] b; wire [3:0] y; assign y = {a >> {22{b}}, a << (0 <<< b)}; initial begin b = 7; a = 3; #1 $display("%b", y); if (y === 4'b0011) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh220.v000066400000000000000000000003511435245347300202350ustar00rootroot00000000000000module Main(); logic[4:0] r5; initial begin r5 = 5'(3'd7 + 3'd6); $display("r5 = %b, %d", r5, r5); if (r5 === 5'b01101) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh224.v000066400000000000000000000005401435245347300202410ustar00rootroot00000000000000package MyPackage; typedef enum logic [1:0] { A = 2'b00, B = 2'b01, C = 2'b10 } MyEnum; endpackage module test(); import MyPackage::*; localparam MyB = B; localparam C = 4; initial begin $display("B = %0d", MyB); $display("C = %0d", C); if (MyB === 1 && C === 4) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh226.v000066400000000000000000000004041435245347300202420ustar00rootroot00000000000000module test(); struct packed { logic [15:0] value; } data; initial begin data.value[7:0] = 8'h55; data.value[15:8] = 8'haa; if (data !== 16'haa55) begin $display("FAILED -- data=%h", data); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh230.v000066400000000000000000000001511435245347300202340ustar00rootroot00000000000000module test(); reg [7:0] array[3:0][3:0]; initial begin $dumpvars(0, array[0][0][0]); end endmodule iverilog-12_0/ivtest/ivltests/br_gh231.v000066400000000000000000000004071435245347300202410ustar00rootroot00000000000000module bug; reg [4:0] a = 5'b01010; reg failed = 0; initial begin foreach (a[i]) begin $display("Value of a[%0d]=%0d", i, a[i]); if (a[i] !== i[0]) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh243.v000066400000000000000000000005101435245347300202370ustar00rootroot00000000000000module test(); bit [3:0] array[15:0]; reg failed = 0; integer i; initial begin for (i = 0; i < 16; i++) begin array[i] = i; end for (i = 0; i < 16; i++) begin $display("%b", array[i]); if (array[i] != i) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh244a.v000066400000000000000000000007041435245347300204060ustar00rootroot00000000000000module test; wire [63:0] out; reg [5:0] in; integer i = 0; assign out = 2 ** in; reg failed = 0; initial begin for (i = 0; i < 64; i = i + 1) begin in = i; #10; $display("%d: %b", i, out); if (out !== 64'd1 << i) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh244b.v000066400000000000000000000006631435245347300204130ustar00rootroot00000000000000module test; reg [63:0] out; reg [5:0] in; integer i = 0; reg failed = 0; initial begin for (i = 0; i < 64; i = i + 1) begin in = i; out = 2 ** in; $display("%d: %b", i, out); if (out !== 64'd1 << i) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh25a.v000066400000000000000000000004731435245347300203260ustar00rootroot00000000000000// Regression test for GitHub issue 25 // This should result in a compile-time error when the language generation // is 1364-2005 or earlier. function test(input i); begin test = i; end endfunction module tb; initial begin if (test(1)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh25b.v000066400000000000000000000005351435245347300203260ustar00rootroot00000000000000// Regression test for GitHub issue 25 // This should result in a compile-time error when the language generation // is 1364-2005 or earlier. task test(input i, output o); begin o = i; end endtask module tb; reg passed = 0; initial begin test(1, passed); if (passed) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh26.v000066400000000000000000000003761435245347300201700ustar00rootroot00000000000000// Regression test for GitHub issue 26 // This is invalid code and should result in a compile-time error module tb; wire [3:0] a, y; test uut (.a(a), .y(y)); endmodule module test(a, b, y); input [3:0] a; output [3:0] y; assign y = a; endmodule iverilog-12_0/ivtest/ivltests/br_gh265.v000066400000000000000000000001601435245347300202440ustar00rootroot00000000000000module test(); typedef bit [3:0] array_t[]; array_t array; initial begin array = 8'd1 << 4; end endmodule iverilog-12_0/ivtest/ivltests/br_gh277a.v000066400000000000000000000005361435245347300204170ustar00rootroot00000000000000module dut; function y(input x); y = x; endfunction reg a, b; reg c, d; always @* begin c = y(a); d = y(b); end endmodule module tb; dut dut(); initial begin #1 dut.a = 0; #1 dut.b = 1; #1 $display(dut.a,,dut.b,,dut.c,,dut.d); if (dut.c === 0 && dut.d === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh277b.v000066400000000000000000000006351435245347300204200ustar00rootroot00000000000000module dut; reg a, b, c; reg d; function z(input x, input y); z = x + y; endfunction function y(input x); y = z(x, b) + z(x, c); endfunction always_comb begin d = y(a); end endmodule module tb; dut dut(); initial begin #1 dut.a = 0; #1 dut.b = 0; #1 dut.c = 1; #1 $display(dut.a,,dut.b,,dut.c,,dut.d); if (dut.d === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh28.v000066400000000000000000000005731435245347300201710ustar00rootroot00000000000000// Regression test for GitHub issue #28 : Insufficient string escaping // when writing vvp script. module tb; wire [63:0] y; \test_str="hello" uut (y); initial begin #1 $display("%s", y); if (y === "hello") $display("PASSED"); else $display("FAILED"); end endmodule module \test_str="hello" (output [63:0] \port="y" ); assign \port="y" = "hello"; endmodule iverilog-12_0/ivtest/ivltests/br_gh280.v000066400000000000000000000006611435245347300202470ustar00rootroot00000000000000module enumtestcase(); typedef enum logic { STATE_A, STATE_B } t_STATE; t_STATE state; bit select; reg failed = 0; initial begin select = 0; state = select ? STATE_B : STATE_A; $display(state); if (state != STATE_A) failed = 1; select = 1; state = select ? STATE_B : STATE_A; $display(state); if (state != STATE_B) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh281.v000066400000000000000000000007331435245347300202500ustar00rootroot00000000000000 module main; int variable = 0; // A void function returns no value, so can be called // like a task, but without a warning about unused // results. function void test_incr(input int arg); variable = variable + arg; endfunction // test_incr initial begin variable = 0; test_incr(5); if (variable !== 5) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh281b.v000066400000000000000000000007341435245347300204130ustar00rootroot00000000000000 module main; int variable = 0; // A void function returns no value, so can be called // like a task, but without a warning about unused // results. It does not have to take any arguments. function void test_incr(); variable = variable + 1; endfunction // test_incr initial begin variable = 0; test_incr(); if (variable !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh283a.v000066400000000000000000000005541435245347300204140ustar00rootroot00000000000000module bug(); reg [31:0] d; reg [31:0] x; reg [31:0] y; reg [31:0] z; initial begin d = 32'hffff0000; x = 32'hffffffff << d; y = 32'hffffffff >> d; z = 32'hffffffff >>> d; $display("%h", x); $display("%h", y); $display("%h", z); if (x === 32'd0 && y === 32'd0 && z === 32'd0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh283b.v000066400000000000000000000005711435245347300204140ustar00rootroot00000000000000module bug(); reg [64:0] d; reg [31:0] x; reg [31:0] y; reg [31:0] z; initial begin d = 65'h1_0000_0000_0000_0000; x = 32'hffffffff << d; y = 32'hffffffff >> d; z = 32'hffffffff >>> d; $display("%h", x); $display("%h", y); $display("%h", z); if (x === 32'd0 && y === 32'd0 && z === 32'd0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh283c.v000066400000000000000000000005741435245347300204200ustar00rootroot00000000000000module bug(); reg d; reg [31:0] x; reg [31:0] y; reg [31:0] z; initial begin d = 1; x = 32'hffffffff << {d, 64'd0}; y = 32'hffffffff >> {d, 64'd0}; z = 32'hffffffff >>> {d, 64'd0}; $display("%h", x); $display("%h", y); $display("%h", z); if (x === 32'd0 && y === 32'd0 && z === 32'd0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh289a.v000066400000000000000000000006621435245347300204220ustar00rootroot00000000000000package pkg; typedef enum logic [3:0] { ABC = 4'h1 } enum_t; typedef struct packed { enum_t item; } w_enum; typedef struct packed { logic [3:0] item; } w_logic; typedef union packed { w_enum el1; w_logic el2; } foo_t; endpackage module main(); import pkg::*; foo_t val; initial begin val.el1.item = ABC; if (val.el2.item === 4'h1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh289b.v000066400000000000000000000004561435245347300204240ustar00rootroot00000000000000package p; localparam a = 1, b = 2; typedef enum { A = a, B = b } enum_t; endpackage module a(); localparam a = 3, b = 4; import p::*; enum_t e; initial begin e = A; $display(e); if (e === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh289c.v000066400000000000000000000004671435245347300204270ustar00rootroot00000000000000package p; localparam a = 1, b = 2; typedef logic [b:a] vector_t; endpackage module a(); localparam a = 1, b = 4; import p::*; vector_t v; initial begin:blk v = ~0; $display("%b", v); if (v === 2'b11) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh289d.v000066400000000000000000000003441435245347300204220ustar00rootroot00000000000000module p #(parameter a = 1, b = 2) (); typedef logic [b:a] vector_t; vector_t v; initial begin v = ~0; #b $display("%m %0d %0d %b", a, b, v); end endmodule module m; p #(1,2) p1(); p #(1,4) p2(); endmodule iverilog-12_0/ivtest/ivltests/br_gh30.v000066400000000000000000000003641435245347300201600ustar00rootroot00000000000000// Regression test for GitHub issue #30 : failed assertion in eval_tree.cc module bug(); wire [3:0] y; assign y = 1 * (1 ? (1.0 * 0) : 1); initial begin if (y === 4'd0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh306a.v000066400000000000000000000006271435245347300204110ustar00rootroot00000000000000module counter(out, clk, reset); parameter WIDTH = 8; output [WIDTH-1 : 0] out; input clk, reset; reg [WIDTH-1 : 0] out; wire clk, reset; (* ivl_synthesis_on *) always @(posedge clk) out <= out + 1; always @(posedge reset) assign out = 0; always @(negedge reset) deassign out; (* ivl_synthesis_off *) initial $display("PASSED"); endmodule // counter iverilog-12_0/ivtest/ivltests/br_gh306b.v000066400000000000000000000006251435245347300204100ustar00rootroot00000000000000module counter(out, clk, reset); parameter WIDTH = 8; output [WIDTH-1 : 0] out; input clk, reset; reg [WIDTH-1 : 0] out; wire clk, reset; (* ivl_synthesis_on *) always @(posedge clk) out <= out + 1; always @(posedge reset) force out = 0; always @(negedge reset) release out; (* ivl_synthesis_off *) initial $display("PASSED"); endmodule // counter iverilog-12_0/ivtest/ivltests/br_gh307.v000066400000000000000000000012611435245347300202440ustar00rootroot00000000000000 typedef struct packed { logic b; } single_bit; typedef struct packed { single_bit b1; single_bit b2; } two_bits; module simple(input two_bits b2in, output two_bits b2out); assign b2out.b1.b = b2in.b1.b; endmodule // simple module main; two_bits src; wire two_bits dst; simple copy(src, dst); assign dst.b2.b = src.b2.b; initial begin src.b1.b = 1'b1; src.b2.b = 1'b0; #1 ; // Let values settle. $display("src=%b (s.b. 10), dst=%b (s.b. 10)", src, dst); if (src !== 2'b10 || dst !== 2'b10) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh309.v000066400000000000000000000003231435245347300202440ustar00rootroot00000000000000module test(); `define TEST_MACRO(arg) arg reg [3:0] value; initial begin value = `TEST_MACRO({2'b01, 2'b10}); if (value === 4'b0110) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh315.v000066400000000000000000000050541435245347300202470ustar00rootroot00000000000000`timescale 1ns/1ns module hct74245( input dir, input nOE, inout [7:0] A, inout [7:0] B, output [7:0] C // Added to demonstrate that a straight dependency timing works correctly ); // HCT typical @ 5v according to https://assets.nexperia.com/documents/data-sheet/74HC_HCT245.pdf specify (A *> C) = 100; // This delay works OK (A *> B) = 10; // The rest of these delays do not work (B *> A) = 10; // not respected (dir *> A) = 16;// not respected (dir *> B) = 16;// not respected (nOE *> A) = 16;// not respected (nOE *> B) = 16;// not respected endspecify assign A=nOE? 8'bzzzzzzzz : dir?8'bzzzzzzzz:B; assign B=nOE? 8'bzzzzzzzz : dir?A:8'bzzzzzzzz; assign C=A; // THIS IS DELAYED BY 100 // HAVE TO USE THIS APPROACH TO MAKE TIMINGS WORK AT ALL // assign #16 A=nOE? 8'bzzzzzzzz :dir?8'bzzzzzzzz:B; // assign #16 B=nOE? 8'bzzzzzzzz :dir?A: 8'bzzzzzzzz; endmodule module tb(); tri [7:0]A; tri [7:0]B; tri [7:0]C; // 'C' IS NOT PART OF ORIGINAL DESIGN - HOWEVER THIS TIMING IS RESPECTED COS THERE ARE NO CONDITIONALS IN THE ASSIGNMENT reg [7:0] Vb=8'b00000000; reg [7:0] Va=8'b11111111; reg dir; reg nOE; assign B=Vb; assign A=Va; hct74245 buf245(.A, .B, .dir, .nOE); integer timer; reg failed = 0; initial begin $display("disable output , set dir a->b"); dir <= 1; // A->B nOE <= 1; Va=8'b11111111; Vb=8'bzzzzzzzz; #50 // time to settle // NOW throw outputs on and time how long it takes for expected output to appear. // It should take 16 to propagate from nOE -> B but the change is instantaneous $display("enable output - B will change immediately"); timer=$time; nOE <= 0; wait(B === 8'b11111111); if ($time - timer < 16) begin $display("%6d", $time, " ERROR TOO QUICK - EXPECTED nOE->B = 16ns - BUT TOOK %-d", ($time - timer)); failed = 1; end else $display("%6d", $time, " OK - TOOK %-d", ($time - timer)); #50 // settle // Change data in - This should take 10 to propagate A->B but is instantaneous $display("change A - B will change immediately (but C is delayed as expected by 100)"); Va=8'b00000000; timer=$time; nOE <= 0; wait(B === 8'b00000000); if ($time - timer < 10) begin $display("%6d", $time, " ERROR TOO QUICK - EXPECTED A->B = 10ns - BUT TOOK %-d", ($time - timer)); failed = 1; end else $display("%6d", $time, " OK - TOOK %-d", ($time - timer)); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh316a.v000066400000000000000000000007771435245347300204200ustar00rootroot00000000000000module dut(input EN, input I, output O); assign O = EN ? I : 1'bz; specify (I => O) = (2); (EN *> O) = (4); endspecify endmodule module test(); reg EN; reg I; tri O; pulldown(O); dut dut(EN, I, O); reg failed = 0; initial begin $monitor($time,,EN,,I,,O); EN = 0; #4; #0 if (O !== 0) failed = 1; #1 I = 1; #1 EN = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh316b.v000066400000000000000000000016531435245347300204130ustar00rootroot00000000000000module dut(input EN1, input I1, output O1, input EN2, input I2, output O2); assign O1 = EN1 ? I1 : 1'bz; assign O2 = EN2 ? I2 : 1'bz; specify (I1 => O1) = (2); (EN1 *> O1) = (4); (I2 => O2) = (3); (EN2 *> O2) = (4); endspecify endmodule module test(); reg EN1; reg EN2; reg I1; reg I2; tri O; pulldown(O); dut dut(EN1, I1, O, EN2, I2, O); reg failed = 0; initial begin $monitor($time,,EN1,,I1,,EN2,,I2,,O); EN1 = 0; EN2 = 0; #4; #0 if (O !== 0) failed = 1; I1 = 1; I2 = 1; #1; EN1 = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; I1 = 0; #1; #0 if (O !== 1) failed = 1; #1; #0 if (O !== 0) failed = 1; EN1 = 0; EN2 = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; I2 = 0; #2; #0 if (O !== 1) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh316c.v000066400000000000000000000017401435245347300204110ustar00rootroot00000000000000module dut(input EN, input DIR, inout A, inout B); assign A = EN && DIR == 0 ? B : 1'bz; assign B = EN && DIR == 1 ? A : 1'bz; specify (A => B) = (2); (B => A) = (3); (EN => A) = (4); (EN => B) = (4); endspecify endmodule module test(); wire EN1; wire EN2; wire I1; wire I2; tri O; pulldown(O); dut dut1(EN1, 1'b1, I1, O); dut dut2(EN2, 1'b0, O, I2); reg failed = 0; initial begin $monitor($time,,EN1,,I1,,EN2,,I2,,O); force EN1 = 0; force EN2 = 0; #4; #0 if (O !== 0) failed = 1; force I1 = 1; force I2 = 1; #1; force EN1 = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; force I1 = 0; #1; #0 if (O !== 1) failed = 1; #1; #0 if (O !== 0) failed = 1; force EN1 = 0; force EN2 = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; force I2 = 0; #2; #0 if (O !== 1) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh33.v000066400000000000000000000007311435245347300201610ustar00rootroot00000000000000// Regression test for GitHub issue #33. module tb; reg [3:0] mem [0:15] [0:15]; task cycle; input [3:0] a, b, c; reg [3:0] tmp; begin tmp = mem[a][b]; mem[a][b] = c; $display("a=%d, b=%d, c=%d -> old=%d, new=%d", a, b, c, tmp, mem[a][b]); end endtask initial begin cycle( 7, 0, 1); cycle(15, 0, 2); cycle( 7, 0, 3); cycle(15, 0, 4); end endmodule iverilog-12_0/ivtest/ivltests/br_gh330.v000066400000000000000000001075011435245347300202440ustar00rootroot00000000000000module naughty_module( input clk, input [71:0] pzw, input [95:0] xy_d, input [23:0] pbit, output [95:0] xas, output [95:0] yas ); initial $display("PASSED"); function [3:0] xa; input pbit; input [1:0] ix_in; input [1:0] iy_in; input [3:0] pzw; begin xa = {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h0} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h1} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h4} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h5} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h0} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h4} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h3} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h7} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h2} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h3} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h6} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h7} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h1} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h5} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h2} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h6} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h2} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h6} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h1} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h5} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h2} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h3} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h6} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h7} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h3} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h7} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h0} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h4} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h0} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h1} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h4} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h5} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h0} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h1} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h4} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h5} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h0} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h4} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h3} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h7} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h2} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h3} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h6} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h7} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h1} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h5} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h2} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h6} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h2} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h6} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h1} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h5} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h2} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h3} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h6} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h7} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h3} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h7} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h0} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h4} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h0} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h1} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h4} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h5} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h7} ? 4'h3 : 4'h0; end endfunction function [3:0] ya; input pbit; input [1:0] ix_in; input [1:0] iy_in; input [3:0] pzw; begin ya = {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h2} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h3} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h6} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h0, 3'h7} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h2} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h6} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h1, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h1} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h5} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h2, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h0} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h1} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h4} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h5} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h0, 2'h3, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h3} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h0, 3'h7} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h1, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h2, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h0} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h4} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h1, 2'h3, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h0} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h4} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h0, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h1, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h2, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h3} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h2, 2'h3, 3'h7} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h0} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h1} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h4} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h5} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h0, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h1} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h5} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h1, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h2} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h6} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h2, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h2} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h3} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h6} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h0, 2'h3, 2'h3, 3'h7} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h2} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h3} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h6} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h0, 3'h7} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h2} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h6} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h1, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h1} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h5} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h2, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h0} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h1} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h4} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h5} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h0, 2'h3, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h2} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h3} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h6} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h0, 3'h7} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h2} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h6} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h1, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h1} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h5} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h2, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h0} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h1} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h4} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h5} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h1, 2'h3, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h0} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h2} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h3} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h4} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h6} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h0, 3'h7} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h0} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h2} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h3} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h4} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h6} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h1, 3'h7} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h0} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h1} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h3} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h4} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h5} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h2, 3'h7} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h0} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h1} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h3} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h4} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h5} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h2, 2'h3, 3'h7} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h0} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h1} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h2} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h3} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h4} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h5} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h6} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h0, 3'h7} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h0} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h1} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h2} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h3} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h4} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h5} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h6} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h1, 3'h7} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h0} ? 4'h5 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h1} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h2} ? 4'h8 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h3} ? 4'h7 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h4} ? 4'h4 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h5} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h6} ? 4'h1 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h2, 3'h7} ? 4'h2 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h0} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h1} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h2} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h3} ? 4'h9 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h4} ? 4'h6 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h5} ? 4'h3 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h6} ? 4'h0 : {pbit, ix_in, iy_in, pzw} == {1'h1, 2'h3, 2'h3, 3'h7} ? 4'h0 : 4'h0; end endfunction reg [95:0] r_xa; reg [95:0] r_ya; always @(posedge clk) begin r_xa[ 3: 0] <= xa(pbit[ 0], xy_d[ 1: 0], xy_d[ 3: 2], pzw[ 2: 0]); r_xa[ 7: 4] <= xa(pbit[ 1], xy_d[ 5: 4], xy_d[ 7: 6], pzw[ 5: 3]); r_xa[11: 8] <= xa(pbit[ 2], xy_d[ 9: 8], xy_d[11:10], pzw[ 8: 6]); r_xa[15: 12] <= xa(pbit[ 3], xy_d[13:12], xy_d[15:14], pzw[11: 9]); r_xa[19: 16] <= xa(pbit[ 4], xy_d[17:16], xy_d[19:18], pzw[14:12]); r_xa[23: 20] <= xa(pbit[ 5], xy_d[21:20], xy_d[23:22], pzw[17:15]); r_xa[27: 24] <= xa(pbit[ 6], xy_d[25:24], xy_d[27:26], pzw[20:18]); r_xa[31: 28] <= xa(pbit[ 7], xy_d[29:28], xy_d[31:30], pzw[23:21]); r_xa[35: 32] <= xa(pbit[ 8], xy_d[33:32], xy_d[35:34], pzw[26:24]); r_xa[39: 36] <= xa(pbit[ 9], xy_d[37:36], xy_d[39:38], pzw[29:27]); r_xa[43: 40] <= xa(pbit[10], xy_d[41:40], xy_d[43:42], pzw[32:30]); r_xa[47: 44] <= xa(pbit[11], xy_d[45:44], xy_d[47:46], pzw[35:33]); r_xa[51: 48] <= xa(pbit[12], xy_d[49:48], xy_d[51:50], pzw[38:36]); r_xa[55: 52] <= xa(pbit[13], xy_d[53:52], xy_d[55:54], pzw[41:39]); r_xa[59: 56] <= xa(pbit[14], xy_d[57:56], xy_d[59:58], pzw[44:42]); r_xa[63: 60] <= xa(pbit[15], xy_d[61:60], xy_d[63:62], pzw[47:45]); r_xa[67: 64] <= xa(pbit[16], xy_d[65:64], xy_d[67:66], pzw[50:48]); r_xa[71: 68] <= xa(pbit[17], xy_d[69:68], xy_d[71:70], pzw[53:51]); r_xa[75: 72] <= xa(pbit[18], xy_d[73:72], xy_d[75:74], pzw[56:54]); r_xa[79: 76] <= xa(pbit[19], xy_d[77:76], xy_d[79:78], pzw[59:57]); r_xa[83: 80] <= xa(pbit[20], xy_d[81:80], xy_d[83:82], pzw[62:60]); r_xa[87: 84] <= xa(pbit[21], xy_d[85:84], xy_d[87:86], pzw[65:63]); r_xa[91: 88] <= xa(pbit[22], xy_d[89:88], xy_d[91:90], pzw[68:66]); r_xa[95: 92] <= xa(pbit[23], xy_d[93:92], xy_d[95:94], pzw[71:69]); r_ya[ 3: 0] <= ya(pbit[ 0], xy_d[ 1: 0], xy_d[ 3: 2], pzw[ 2: 0]); r_ya[ 7: 4] <= ya(pbit[ 1], xy_d[ 5: 4], xy_d[ 7: 6], pzw[ 5: 3]); r_ya[11: 8] <= ya(pbit[ 2], xy_d[ 9: 8], xy_d[11:10], pzw[ 8: 6]); r_ya[15: 12] <= ya(pbit[ 3], xy_d[13:12], xy_d[15:14], pzw[11: 9]); r_ya[19: 16] <= ya(pbit[ 4], xy_d[17:16], xy_d[19:18], pzw[14:12]); r_ya[23: 20] <= ya(pbit[ 5], xy_d[21:20], xy_d[23:22], pzw[17:15]); r_ya[27: 24] <= ya(pbit[ 6], xy_d[25:24], xy_d[27:26], pzw[20:18]); r_ya[31: 28] <= ya(pbit[ 7], xy_d[29:28], xy_d[31:30], pzw[23:21]); r_ya[35: 32] <= ya(pbit[ 8], xy_d[33:32], xy_d[35:34], pzw[26:24]); r_ya[39: 36] <= ya(pbit[ 9], xy_d[37:36], xy_d[39:38], pzw[29:27]); r_ya[43: 40] <= ya(pbit[10], xy_d[41:40], xy_d[43:42], pzw[32:30]); r_ya[47: 44] <= ya(pbit[11], xy_d[45:44], xy_d[47:46], pzw[35:33]); r_ya[51: 48] <= ya(pbit[12], xy_d[49:48], xy_d[51:50], pzw[38:36]); r_ya[55: 52] <= ya(pbit[13], xy_d[53:52], xy_d[55:54], pzw[41:39]); r_ya[59: 56] <= ya(pbit[14], xy_d[57:56], xy_d[59:58], pzw[44:42]); r_ya[63: 60] <= ya(pbit[15], xy_d[61:60], xy_d[63:62], pzw[47:45]); r_ya[67: 64] <= ya(pbit[16], xy_d[65:64], xy_d[67:66], pzw[50:48]); r_ya[71: 68] <= ya(pbit[17], xy_d[69:68], xy_d[71:70], pzw[53:51]); r_ya[75: 72] <= ya(pbit[18], xy_d[73:72], xy_d[75:74], pzw[56:54]); r_ya[79: 76] <= ya(pbit[19], xy_d[77:76], xy_d[79:78], pzw[59:57]); r_ya[83: 80] <= ya(pbit[20], xy_d[81:80], xy_d[83:82], pzw[62:60]); r_ya[87: 84] <= ya(pbit[21], xy_d[85:84], xy_d[87:86], pzw[65:63]); r_ya[91: 88] <= ya(pbit[22], xy_d[89:88], xy_d[91:90], pzw[68:66]); r_ya[95: 92] <= ya(pbit[23], xy_d[93:92], xy_d[95:94], pzw[71:69]); end assign xas = r_xa; assign yas = r_ya; endmodule iverilog-12_0/ivtest/ivltests/br_gh337.v000066400000000000000000000010751435245347300202520ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif module test(); int x2; int z2; function int y2(int x); endfunction `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire int w2 = y2(x2); `else wire integer w2 = 0; `endif integer x4; integer z4; function integer y4(integer x); endfunction wire integer w4 = y4(x4); initial begin #1; $display(w2); z2 = y2(x2); $display(z2); $display(w4); z4 = y4(x4); $display(z4); if (w2 === 0 && z2 === 0 && w4 === 'bx && z4 === 'bx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh345.v000066400000000000000000000056701435245347300202560ustar00rootroot00000000000000// Based on https://github.com/YosysHQ/yosys/blob/master/tests/various/const_func.v // // ISC License // // Copyright (C) 2012 - 2020 Claire Wolf // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. module Example(outA, outB, outC, outD); parameter OUTPUT = "FOO"; output wire [23:0] outA; output wire [23:0] outB; output reg outC, outD; function automatic [23:0] flip; input [23:0] inp; flip = ~inp; endfunction generate if (flip(OUTPUT) == flip("BAR")) assign outA = OUTPUT; else assign outA = 0; case (flip(OUTPUT)) flip("FOO"): assign outB = OUTPUT; flip("BAR"): assign outB = 0; flip("BAZ"): assign outB = "HI"; endcase genvar i; initial outC = 0; for (i = 0; i != flip(flip(OUTPUT[15:8])); i = i + 1) if (i + 1 == flip(flip("O"))) initial #1 outC = 1; endgenerate integer j; initial begin outD = 1; for (j = 0; j != flip(flip(OUTPUT[15:8])); j = j + 1) if (j + 1 == flip(flip("O"))) outD = 0; end endmodule module top(out); wire [23:0] a1, a2, a3, a4; wire [23:0] b1, b2, b3, b4; wire c1, c2, c3, c4; wire d1, d2, d3, d4; Example e1(a1, b1, c1, d1); Example #("FOO") e2(a2, b2, c2, d2); Example #("BAR") e3(a3, b3, c3, d3); Example #("BAZ") e4(a4, b4, c4, d4); output wire [24 * 8 - 1 + 4 :0] out; assign out = { a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4}; initial begin #2; $display("%h %h %h %h", a1, a2, a3, a4); $display("%h %h %h %h", b1, b2, b3, b4); $display(c1,,c2,,c3,,c4); $display(d1,,d2,,d3,,d4); if((a1 === 0) && (a2 === 0) && (a3 === "BAR") && (a4 === 0) && (b1 === "FOO") && (b2 === "FOO") && (b3 === 0) && (b4 === "HI") && (c1 === 1) && (c2 === 1) && (c3 === 0) && (c4 === 0) && (d1 === 0) && (d2 === 0) && (d3 === 1) && (d4 === 1)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh356a.v000066400000000000000000000007661435245347300204220ustar00rootroot00000000000000module dut(input EN, input I, inout O); assign O = EN ? I : 1'bz; specify (I => O) = (2); (EN *> O) = (4); endspecify endmodule module test(); reg EN; reg I; tri0 O; dut dut(EN, I, O); reg failed = 0; initial begin $monitor($time,,EN,,I,,O); EN = 0; #4; #0 if (O !== 0) failed = 1; #1 I = 1; #1 EN = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh356b.v000066400000000000000000000010041435245347300204050ustar00rootroot00000000000000module dut(input EN, input I, inout O); assign O = EN ? I : 1'bz; specify (I => O) = (2); (EN *> O) = (4); endspecify endmodule module test(); reg EN; reg I; tri O; pulldown(O); dut dut(EN, I, O); reg failed = 0; initial begin $monitor($time,,EN,,I,,O); EN = 0; #4; #0 if (O !== 0) failed = 1; #1 I = 1; #1 EN = 1; #3; #0 if (O !== 0) failed = 1; #1; #0 if (O !== 1) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh361.v000066400000000000000000000014061435245347300202450ustar00rootroot00000000000000module a(); // Need to add enumerations to packages. typedef enum logic[4:0] { EXC_A = 0, EXC_B = 1, EXC_C = 2 } exc_code_t; // Need to search up the parent scope searching for the enum definition. function exc_code_t func1(bit inx); exc_code_t rVal; case(inx) 1 : rVal = EXC_C; 0: rVal = EXC_B; default: rVal = EXC_A; endcase return(rVal); endfunction exc_code_t exc_code; initial begin // Need to compare the base enumeration definition to check compatibility. exc_code = func1(1'b1); if(exc_code== EXC_C) begin $display("PASSED"); $finish; end $display("FAILED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br_gh365.v000066400000000000000000000010651435245347300202520ustar00rootroot00000000000000module tb(); typedef enum logic [1:0] { IDLE = 0, RESET = 1, START = 2, WAITFOR = 3 } stateType; stateType state; string workingString = "WORKING"; initial begin $display("DIRECT ASSIGNED STRING is ", workingString); #10; state = IDLE; end string state_txt; always @* begin case(state) IDLE : state_txt = "IDLE"; RESET : state_txt = "RST"; START : state_txt = "STRT"; WAITFOR : state_txt = "WAIT"; endcase $display("Controller's new state is %s",state_txt); end endmodule iverilog-12_0/ivtest/ivltests/br_gh366.v000066400000000000000000000002101435245347300202420ustar00rootroot00000000000000`define PATH /usr/local/bin/ `define STRINGIFY(x) `"x`" module test(); initial begin $display( `STRINGIFY(`PATH) ); end endmodule iverilog-12_0/ivtest/ivltests/br_gh368.v000066400000000000000000000007601435245347300202560ustar00rootroot00000000000000module top; task test_task; begin fork begin $display("Process #1"); #20 $display("Process #1 -- completes"); end begin // Here's a timeout task. It should only complete if // something in process #1 fails to complete. As such, // it operates as a failsafe. #1 $display("Process #2"); #200 $display("Process #2 -- completes"); end join_any; disable fork; $display("Test task completes"); end endtask initial test_task; endmodule iverilog-12_0/ivtest/ivltests/br_gh37.v000066400000000000000000000004451435245347300201670ustar00rootroot00000000000000// Regression test for GitHub issue #37 module test; wire [5:0] a; wire [15:0] y; assign a = ~0; assign y = 1 ? ~a >>> 5 : 0; initial begin #10 $display("%b", y); if (y === 16'b1111111111111110) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh374.v000066400000000000000000000003311435245347300202450ustar00rootroot00000000000000`define OPT1_DISPLAY $display("opt1"); `define OPT2_DISPLAY $display("opt2"); `define INDIRECT_OPT(OPTN) ```OPTN``_DISPLAY module t; initial begin `INDIRECT_OPT(OPT1) `INDIRECT_OPT(OPT2) end endmodule iverilog-12_0/ivtest/ivltests/br_gh377.v000066400000000000000000000000571435245347300202550ustar00rootroot00000000000000module test(); parameter name = 1; endmodule iverilog-12_0/ivtest/ivltests/br_gh383a.v000066400000000000000000000007371435245347300204200ustar00rootroot00000000000000module test; logic [7:0] i, x[], y[], z[]; initial begin x = new [4]; for (i = 0; i < 4; i = i + 1) x[i] = 1 + i; y = x; z = new [4](x); for (i = 0; i < 4; i = i + 1) y[i] = 4 - i; for (i = 0; i < 4; i = i + 1) z[i] = 8 - i; // Expected output: // 1 2 3 4 // 4 3 2 1 // 8 7 6 5 $display(x[0],,x[1],,x[2],,x[3]); $display(y[0],,y[1],,y[2],,y[3]); $display(z[0],,z[1],,z[2],,z[3]); end endmodule iverilog-12_0/ivtest/ivltests/br_gh383b.v000066400000000000000000000007351435245347300204170ustar00rootroot00000000000000module test; bit [7:0] i, x[], y[], z[]; initial begin x = new [4]; for (i = 0; i < 4; i = i + 1) x[i] = 1 + i; y = x; z = new [4](x); for (i = 0; i < 4; i = i + 1) y[i] = 4 - i; for (i = 0; i < 4; i = i + 1) z[i] = 8 - i; // Expected output: // 1 2 3 4 // 4 3 2 1 // 8 7 6 5 $display(x[0],,x[1],,x[2],,x[3]); $display(y[0],,y[1],,y[2],,y[3]); $display(z[0],,z[1],,z[2],,z[3]); end endmodule iverilog-12_0/ivtest/ivltests/br_gh383c.v000066400000000000000000000012671435245347300204210ustar00rootroot00000000000000module test; string x[], y[], z[]; string src[0:7]; int i; initial begin src[0] = "a"; src[1] = "b"; src[2] = "c"; src[3] = "d"; src[4] = "e"; src[5] = "f"; src[6] = "g"; src[7] = "h"; x = new [4]; for (i = 0; i < 4; i = i + 1) x[i] = src[i]; y = x; z = new [4](x); for (i = 0; i < 4; i = i + 1) y[i] = src[3 - i]; for (i = 0; i < 4; i = i + 1) z[i] = src[7 - i]; // Expected output: // a b c d // d c b a // h g f e $display(x[0],,x[1],,x[2],,x[3]); $display(y[0],,y[1],,y[2],,y[3]); $display(z[0],,z[1],,z[2],,z[3]); end endmodule iverilog-12_0/ivtest/ivltests/br_gh383d.v000066400000000000000000000013551435245347300204200ustar00rootroot00000000000000module test; real x[], y[], z[]; real src[0:7]; int i; initial begin src[0] = 1.0; src[1] = 2.0; src[2] = 3.0; src[3] = 4.0; src[4] = 5.0; src[5] = 6.0; src[6] = 7.0; src[7] = 8.0; x = new [4]; for (i = 0; i < 4; i = i + 1) x[i] = src[i]; y = x; z = new [4](x); for (i = 0; i < 4; i = i + 1) y[i] = src[3 - i]; for (i = 0; i < 4; i = i + 1) z[i] = src[7 - i]; // Expected output: // 1.00000 2.00000 3.00000 4.00000 // 4.00000 3.00000 2.00000 1.00000 // 8.00000 7.00000 6.00000 5.00000 $display(x[0],,x[1],,x[2],,x[3]); $display(y[0],,y[1],,y[2],,y[3]); $display(z[0],,z[1],,z[2],,z[3]); end endmodule iverilog-12_0/ivtest/ivltests/br_gh386a.v000066400000000000000000000005051435245347300204140ustar00rootroot00000000000000module test(); typedef enum logic [8:0] { ILLEGAL, IA, IB } inst_t; inst_t ipb_inst; typedef struct packed { inst_t inst; logic iw; } ipb_data_t; ipb_data_t ipb_d; initial begin ipb_d.inst = IA; ipb_inst = ipb_d.inst; if (ipb_inst === IA) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh386b.v000066400000000000000000000005211435245347300204130ustar00rootroot00000000000000module test(); typedef enum logic [8:0] { ILLEGAL, IA, IB } inst_t; inst_t ipb_inst; typedef struct packed { inst_t inst; logic iw; } ipb_data_t; ipb_data_t ipb_d; assign ipb_inst = ipb_d.inst; initial begin ipb_d.inst = IA; #1; if (ipb_inst === IA) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh386c.v000066400000000000000000000001561435245347300204200ustar00rootroot00000000000000module test(); typedef enum { a, b, c } enum_type; enum_type enum_value; assign enum_value = 1; endmodule iverilog-12_0/ivtest/ivltests/br_gh386d.v000066400000000000000000000004531435245347300204210ustar00rootroot00000000000000// Test that cast to enum works in continuous assignments module test(); typedef enum { a, b, c } enum_type; enum_type enum_value; assign enum_value = enum_type'(1); initial begin if (enum_value == b) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/br_gh388.v000066400000000000000000000011751435245347300202610ustar00rootroot00000000000000package test_pkg; class uvm_object; function new (); print("new uvm_object"); endfunction : new virtual function void print (string str); $display (str); endfunction : print endclass : uvm_object class uvm_report_object extends uvm_object; function new (); print("new uvm_report_object"); endfunction : new endclass : uvm_report_object endpackage : test_pkg module m; import test_pkg::*; uvm_report_object r_0; uvm_object u_0; initial begin : test #100; u_0 = new(); r_0 = new(); u_0.print("u_0"); r_0.print("r_0"); end : test endmodule : m iverilog-12_0/ivtest/ivltests/br_gh390a.v000066400000000000000000000020451435245347300204100ustar00rootroot00000000000000package test_pkg; virtual class uvm_void; endclass : uvm_void class uvm_object extends uvm_void; function new (string name = "uvm_object"); $display("uvm_object::new(%s)", name); // XXXX m_name = name; endfunction : new virtual function void print (); $display ("uvm_object::Print: m_name=%s", m_name); endfunction : print string m_name; endclass : uvm_object class uvm_report_object extends uvm_object; function new (string name = "uvm_report_object"); // super.new must be the first statement in a constructor. // If it is not, generate an error. $display("uvm_report_object::new"); super.new (name); $display("uvm_report_object::new"); endfunction : new endclass : uvm_report_object endpackage : test_pkg module m; import test_pkg::*; uvm_object u0; uvm_report_object u1; initial begin : test #100; $display ("Hello World"); u0 = new (); u0.print(); u1 = new (); u1.print(); end : test endmodule : m iverilog-12_0/ivtest/ivltests/br_gh390b.v000066400000000000000000000015421435245347300204120ustar00rootroot00000000000000package test_pkg; virtual class uvm_void; endclass : uvm_void class uvm_object extends uvm_void; string m_name; function new (string name = "uvm_object"); $display("uvm_object::new(%s)", name); // XXXX m_name = name; endfunction : new virtual function void print (); $display ("uvm_object::Print: m_name=%s", m_name); endfunction : print endclass : uvm_object class uvm_report_object extends uvm_object; function new (string name = "uvm_report_object"); super.new (name); endfunction : new endclass : uvm_report_object endpackage : test_pkg module m; import test_pkg::*; uvm_object u0; uvm_report_object u1; initial begin : test #100; $display ("Hello World"); u0 = new (); u0.print(); u1 = new (); u1.print(); end : test endmodule : m iverilog-12_0/ivtest/ivltests/br_gh391.v000066400000000000000000000013071435245347300202500ustar00rootroot00000000000000package test_pkg; class uvm_phase; function void print(string str); $display(str); endfunction endclass : uvm_phase class uvm_component; virtual function void build_phase(uvm_phase phase); phase.print("building"); endfunction : build_phase virtual task run_phase(uvm_phase phase); phase.print("running"); endtask : run_phase virtual task run_all(); uvm_phase p0; p0 = new(); this.build_phase(p0); this.run_phase(p0); endtask : run_all endclass : uvm_component endpackage : test_pkg module m; import test_pkg::*; uvm_component u0; initial begin : test u0 = new(); u0.run_all(); end : test endmodule : m iverilog-12_0/ivtest/ivltests/br_gh4.v000066400000000000000000000002641435245347300201000ustar00rootroot00000000000000program test; class a; function new(string str); $display(str); endfunction endclass // a initial begin a m_a; m_a = new("PASSED"); end endprogram iverilog-12_0/ivtest/ivltests/br_gh411.v000066400000000000000000000002001435245347300202300ustar00rootroot00000000000000module test(); function void do_nothing(); ; endfunction initial begin do_nothing(); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh412.v000066400000000000000000000004331435245347300202410ustar00rootroot00000000000000module top; int mbx[$]; initial begin $display("mbx.size() == %0d", mbx.size()); wait(mbx.size()); $display("mbx.size() == %0d", mbx.size()); $display("PASSED"); end initial begin #100 $display ("Push an item"); mbx.push_back(1); end endmodule iverilog-12_0/ivtest/ivltests/br_gh414.v000066400000000000000000000013111435245347300202370ustar00rootroot00000000000000 module tb; string txt_i, txt_r, txt_h; int val_i; int val_h; real val_r; initial begin txt_i = "123"; txt_r = "1.25"; txt_h = "dead"; val_i = txt_i.atoi(); val_r = txt_r.atoreal(); val_h = txt_h.atohex(); $display("txt_i=%s, val_i=%0d", txt_i, val_i); if (val_i !== 123) begin $display("FAILED"); $finish; end $display("txt_r=%s, val_r=%0f", txt_r, val_r); if (val_r != 1.25) begin $display("FAILED"); $finish; end $display("txt_h=%s, val_h=%0h", txt_h, val_h); if (val_h !== 'hdead) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/br_gh418.v000066400000000000000000000005101435245347300202430ustar00rootroot00000000000000module m; reg [31:0] count = 0; function void func1(); count++; if (count < 10) func2(); endfunction function void func2(); count++; if (count < 10) func1(); endfunction initial begin func1(); if (count == 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh433.v000066400000000000000000000010771435245347300202510ustar00rootroot00000000000000module top; reg passed; int q[$]; initial begin passed = 1'b1; q.push_front(10); q.pop_back(); // This should emit a warning if (q.size() != 0) begin $display("FAILED: pop_back() did not pop value when called as a task."); passed = 1'b0; end q.delete(); q.push_front(20); q.pop_front(); // This should emit a warning if (q.size() != 0) begin $display("FAILED: pop_front() did not pop value when called as a task."); passed = 1'b0; end q.size(); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh435.v000066400000000000000000000002021435245347300202400ustar00rootroot00000000000000`define display_passed \ initial begin // comment \ $display("PASSED"); \ end module test(); `display_passed endmodule iverilog-12_0/ivtest/ivltests/br_gh436.v000066400000000000000000000015461435245347300202550ustar00rootroot00000000000000 // This program should emit: // m_argv[0] = str0 // LARGE: 4 // LARGE: 4 (2) // m_argv[1] = str1 // LARGE: 4 // LARGE: 4 (2) // module m; string m_argv [$]; function int size_function(input string val); size_function = val.len(); endfunction // size_function initial begin m_argv.push_back ("str0"); m_argv.push_back ("str1"); foreach (m_argv[i]) begin $display("m_argv[%0d] = %s", i, m_argv[i]); if(m_argv[i].len() >= 2) begin $display ("LARGE: %0d", m_argv[i].len()); end else begin $display("FAILED: m_argv[i].len() == %0d", m_argv[i].len()); end if(size_function(m_argv[i]) >= 2) begin $display ("LARGE: %0d (2)", size_function(m_argv[i])); end else begin $display("FAILED: size_function(m_argv[i]) == %0d", size_function(m_argv[i])); end end end endmodule : m iverilog-12_0/ivtest/ivltests/br_gh437.v000066400000000000000000000006111435245347300202460ustar00rootroot00000000000000package ivl_uvm_pkg; virtual class uvm_test; task ok; $display("PASSED"); endtask endclass : uvm_test endpackage : ivl_uvm_pkg package test_pkg; import ivl_uvm_pkg::*; class sanity_test extends uvm_test; endclass : sanity_test endpackage : test_pkg module m; import test_pkg::*; sanity_test obj; initial begin obj = new; obj.ok; end endmodule : m iverilog-12_0/ivtest/ivltests/br_gh440.v000066400000000000000000000024601435245347300202440ustar00rootroot00000000000000package t; class c; virtual function create (string name=""); return null; // Error: logic returning a null endfunction endclass : c endpackage module m; import t::*; int idx, idx2; c carr [0:1][0:3]; class c2; static c sval; c val; c arr [0:1]; task check; if (sval == null) $display("Empty"); // Okay if (val == null) $display("Empty"); // Okay if (arr[0] == null) $display("Empty"); // Okay endtask endclass // An implicit logic return type is given a NULL function tmp(); return null; // Error: logic returning a null endfunction c cls; logic val; initial begin idx = 0; idx2 = 0; if (cls == null) $display("Empty"); // Okay if (carr[0][0] == null) $display("Empty"); // Okay if (carr[idx][idx2] == null) $display("Empty"); // Okay if (0 == null) $display("Empty"); // Error: logic comp null val = 1|null; // Error: logic binop null val = 1< triggerA; end always @(triggerA) begin countA = countA + 1; end always_comb begin $display("%0t: B", $time); o2 = i1; o3 = i2; -> triggerB; end always @(triggerB) begin countB = countB + 1; end initial begin #1 i1 = 1; #1 i2 = 1; #1; if (countA === 2 && countB === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh508b.v000066400000000000000000000006311435245347300204110ustar00rootroot00000000000000module test; event i1, i2, i3; integer countA, countB; always @(i1 or i2) begin $display("%0t: A", $time); countA = countA + 1; end always @(i2 or i3) begin $display("%0t: B", $time); countB = countB + 1; end initial begin countA = 0; countB = 0; #1 ->i1; #1 ->i2; #1 ->i3; #1; if (countA === 2 && countB === 2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh515.v000066400000000000000000000006131435245347300202450ustar00rootroot00000000000000module test; reg [7:0] array[7:0]; reg [2:0] index; reg [7:0] value; reg failed = 0; initial begin array[0] = 1; index = 7; value = array[index + 1]; $display("%h", value); if (value !== 8'bx) failed = 1; value = array[index + 3'd1]; $display("%h", value); if (value !== 8'd1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh527.v000066400000000000000000000006541435245347300202550ustar00rootroot00000000000000typedef struct packed { union packed { logic[2:0] a; logic[2:0] b; } u; } s1; module top(); s1 source; logic result; logic failed = 0; initial begin source.u.a = 3'b000; result = | source.u.b; if (result !== 1'b0) failed = 1; source.u.a = 3'b001; result = | source.u.b; if (result !== 1'b1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh530.v000066400000000000000000000001351435245347300202410ustar00rootroot00000000000000module dut(a,); input wire a; endmodule module top; wire a; dut i(.*); endmodule iverilog-12_0/ivtest/ivltests/br_gh531.v000066400000000000000000000022331435245347300202430ustar00rootroot00000000000000module top; function automatic [2:1] f1(input [3:0] i); begin f1[0] = i[0]; f1[1] = i[1]; f1[2] = i[2]; f1[3] = i[3]; end endfunction function automatic [3:0] f2(input [2:1] i); begin f2[0] = i[0]; f2[1] = i[1]; f2[2] = i[2]; f2[3] = i[3]; end endfunction function automatic [2:1] f3(input [3:0] i); begin f3[1:0] = i[1:0]; f3[3:2] = i[3:2]; end endfunction function automatic [3:0] f4(input [2:1] i); begin f4[1:0] = i[1:0]; f4[3:2] = i[3:2]; end endfunction function automatic [2:1] f5(input [3:0] i); reg [2:1] tmp; begin tmp[3:0] = 4'b0000; tmp[3:0] |= i[3:0]; f5 = tmp; end endfunction function automatic [3:0] f6(input [2:1] i); reg [3:0] tmp; begin tmp[3:0] = 4'b0000; tmp[3:0] |= i[3:0]; f6 = tmp; end endfunction localparam C1 = f1(4'b0011); localparam C2 = f2(2'b01); localparam C3 = f3(4'b0011); localparam C4 = f4(2'b01); localparam C5 = f5(4'b0011); localparam C6 = f6(2'b01); initial begin $display("C1 %b", C1); $display("C2 %b", C2); $display("C3 %b", C3); $display("C4 %b", C4); $display("C5 %b", C5); $display("C6 %b", C6); end endmodule iverilog-12_0/ivtest/ivltests/br_gh533.v000066400000000000000000000002511435245347300202430ustar00rootroot00000000000000module top; genvar i; for (i = 100; i < 101; i = i + 1) for (i = 100; i < 101; i = i + 1) initial $display("%b %0d", i, $bits(i)); endmodule iverilog-12_0/ivtest/ivltests/br_gh540.v000066400000000000000000000031111435245347300202370ustar00rootroot00000000000000module top( pi_wi, // port implicit, wire implicit pi_ws, // port implicit, wire signed pi_wu, // port implicit, wire unsigned ps_wi, // port signed, wire implicit ps_ws, // port signed, wire signed ps_wu, // port signed, wire unsigned pu_wi, // port unsigned, wire implicit pu_ws, // port unsigned, wire signed pu_wu // port unsigned, wire unsigned ); output pi_wi; output pi_ws; output pi_wu; output signed ps_wi; output signed ps_ws; output signed ps_wu; output unsigned pu_wi; output unsigned pu_ws; output unsigned pu_wu; wire pi_wi = 1'b1; wire ps_wi = 1'b1; wire pu_wi = 1'b1; wire signed pi_ws = 1'b1; wire signed ps_ws = 1'b1; wire signed pu_ws = 1'b1; wire unsigned pi_wu = 1'b1; wire unsigned ps_wu = 1'b1; wire unsigned pu_wu = 1'b1; reg [1:0] value; reg failed = 0; initial begin #1; value = pi_wi; $display("%b", value); if (value !== 2'b01) failed = 1; value = pi_ws; $display("%b", value); if (value !== 2'b11) failed = 1; value = pi_wu; $display("%b", value); if (value !== 2'b01) failed = 1; value = ps_wi; $display("%b", value); if (value !== 2'b11) failed = 1; value = ps_ws; $display("%b", value); if (value !== 2'b11) failed = 1; value = ps_wu; $display("%b", value); if (value !== 2'b11) failed = 1; value = pu_wi; $display("%b", value); if (value !== 2'b01) failed = 1; value = pu_ws; $display("%b", value); if (value !== 2'b11) failed = 1; value = pu_wu; $display("%b", value); if (value !== 2'b01) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh553.v000066400000000000000000000006321435245347300202500ustar00rootroot00000000000000module dut; integer id; endmodule module test; dut inst[4]; integer i; reg failed = 0; initial begin inst[0].id = 0; inst[1].id = 1; inst[2].id = 2; inst[3].id = 3; if (inst[0].id !== 0) failed = 1; if (inst[1].id !== 1) failed = 1; if (inst[2].id !== 2) failed = 1; if (inst[3].id !== 3) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh556.v000066400000000000000000000003211435245347300202460ustar00rootroot00000000000000module test; wire real array[1:0]; reg [7:0] index; real value; initial begin index = 3; value = array[index]; if (value == 0.0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh567.v000066400000000000000000000005211435245347300202520ustar00rootroot00000000000000module test; wire [7:0] val[3:0]; genvar i; for (i = 3; i >= 0; i = i - 1) begin assign val[i] = i; end integer j; reg failed = 0; initial begin for (j = 3; j >= 0; j = j - 1) begin $display(val[j]); if (val[j] != j) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh568.v000066400000000000000000000005131435245347300202540ustar00rootroot00000000000000module test; wire [7:0] val[3:0]; genvar i; for (i = 3; i >= 0; i--) begin assign val[i] = i; end integer j; reg failed = 0; initial begin for (j = 3; j >= 0; j = j - 1) begin $display(val[j]); if (val[j] != j) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh6.v000066400000000000000000000005621435245347300201030ustar00rootroot00000000000000// Adapted from test case supplied in github issue #6 module bug(); reg a; wire y; assign y = |(-a); reg failed = 0; initial begin a = 0; #1 $display("a = %b y = %b", a, y); if (y !== 0) failed = 1; a = 1; #1 $display("a = %b y = %b", a, y); if (y !== 1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh60a.v000066400000000000000000000002431435245347300203200ustar00rootroot00000000000000// Regression test for GitHub issue #60 part 1 - sized numeric constants // must have size greater than zero. module test(); localparam Value = 0'b0; endmodule iverilog-12_0/ivtest/ivltests/br_gh62.v000066400000000000000000000006301435245347300201610ustar00rootroot00000000000000// Regression test for GitHub issue #62 : assert on invalid verilog input module test(); reg [15:0] memory[3:0]; reg [15:0] vector; reg [3:0] value; initial begin value = memory[0][0]; value = memory[0][0][3:0]; value = memory[0][0][0 +: 4]; value = memory[0][0][4 -: 4]; value = vector[0][0]; value = vector[0][3:0]; value = vector[0][0 +: 4]; value = vector[0][4 -: 4]; end endmodule iverilog-12_0/ivtest/ivltests/br_gh621.v000066400000000000000000000022211435245347300202400ustar00rootroot00000000000000`timescale 1ns / 1ps module test(); localparam period = 20; reg clk; reg rst; reg [4:0] waddr; reg [31:0] wdata; reg wvalid; reg wready; always begin clk = 1'b0; #(period/2); clk = 1'b1; #(period/2); end always @(posedge clk) begin if (rst) wready <= 1'b0; else if (!wready && wvalid) wready <= 1'b1; end genvar b; for (b = 0; b < 4; b = b + 1) begin : BYTE_BRAM_GEN wire [7:0] data_in; reg [7:0] byte_ram [31:0]; assign data_in = wdata[b*8 +: 8]; always @(posedge clk) begin if (wvalid && wready) byte_ram[waddr] <= data_in; end end wire [7:0] my_byte = BYTE_BRAM_GEN[0].byte_ram[0]; task automatic wait_for_wready; begin : waiting @(posedge wready); // wait for rising edge end endtask task init_memory; begin @(posedge clk); waddr <= 0; wdata <= 1; wvalid <= 1'b1; wait_for_wready; @(posedge clk); @(posedge clk); $display("my_byte %h", my_byte); if (my_byte === 8'h01) $display("PASSED"); else $display("FAILED"); end endtask initial begin wdata = 32'd0; wvalid = 1'b0; rst = 1'b1; #period; rst = 1'b0; init_memory; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/br_gh632.v000066400000000000000000000004721435245347300202500ustar00rootroot00000000000000module tb(); reg [15:0] array[1:0]; reg [3:0] shift_distance; wire [15:0] shifted_value; assign shifted_value = array[0] >> shift_distance; initial begin array[0] = 16'h1234; shift_distance = 4; #0; if (shifted_value === 16'h0123) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh632b.v000066400000000000000000000010601435245347300204040ustar00rootroot00000000000000module tb(); reg inputs[1:0]; reg out; always @* begin if (inputs[1]) out = inputs[0]; end reg failed; (* ivl_synthesis_off *) initial begin failed = 0; #1 inputs[1] = 1; #1 inputs[0] = 0; #1 $display(inputs[1],,inputs[0],,out); if (out !== 0) failed = 1; #1 inputs[1] = 0; #1 inputs[0] = 1; #1 $display(inputs[1],,inputs[0],,out); if (out !== 0) failed = 1; #1 inputs[1] = 1; #1 $display(inputs[1],,inputs[0],,out); if (out !== 1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh632c.v000066400000000000000000000010071435245347300204060ustar00rootroot00000000000000module tb(); reg [7:0] in[1:0]; wire [7:0] out[1:0]; assign out[0] = $clog2(in[0]); assign out[1] = $clog2(in[1]); reg failed; initial begin failed = 0; #1 in[0] = 1; #1 $display("%0d -> %0d", in[0],out[0]); if (out[0] !== 0) failed = 1; #1 in[1] = 2; #1 $display("%0d -> %0d", in[1],out[1]); if (out[1] !== 1) failed = 1; #1 in[0] = 3; #1 $display("%0d -> %0d", in[0],out[0]); if (out[0] !== 2) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh661a.v000066400000000000000000000014221435245347300204070ustar00rootroot00000000000000module test; localparam NOM_COUNT = 1000; localparam MIN_COUNT = NOM_COUNT - 200; localparam MAX_COUNT = NOM_COUNT + 200; integer histogram[255:0]; integer i; reg [7:0] value; reg failed; initial begin failed = 0; for (i = 0; i < 256; i++) begin histogram[i] = 0; end for (i = 0; i < 256*NOM_COUNT; i = i + 1) begin value = $urandom_range(32'hffffffff, 32'h0) >> 24; histogram[value] += 1; end for (i = 0; i < 256; i++) begin if (histogram[i] < MIN_COUNT) begin $display("Bin %3d count %0d", i, histogram[i]); failed = 1; end if (histogram[i] > MAX_COUNT) begin $display("Bin %3d count %0d", i, histogram[i]); failed = 1; end end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh661b.v000066400000000000000000000016541435245347300204170ustar00rootroot00000000000000module test; localparam NOM_COUNT = 1000; localparam MIN_COUNT = NOM_COUNT - 200; localparam MAX_COUNT = NOM_COUNT + 200; integer histogram[255:0]; integer i; reg [31:0] value; reg failed; initial begin failed = 0; for (i = 0; i < 256; i++) begin histogram[i] = 0; end for (i = 0; i < 256*NOM_COUNT; i = i + 1) begin value = $urandom_range(32'h1ff, 32'h100) - 32'h100; if (value[31:8] != 0) begin $display("Random value %h not in range", value + 32'h100); $display("FAILED"); $finish(0); end histogram[value] += 1; end for (i = 0; i < 256; i++) begin if (histogram[i] < MIN_COUNT) begin $display("Bin %3d count %0d", i, histogram[i]); failed = 1; end if (histogram[i] > MAX_COUNT) begin $display("Bin %3d count %0d", i, histogram[i]); failed = 1; end end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh672.v000066400000000000000000000010631435245347300202510ustar00rootroot00000000000000module top; logic clk = 0; int cnt = 0; always @(posedge clk) begin fork begin #(10*2); // Wait 10 clock periods cnt++; end join_none end initial begin $display("Starting test"); repeat (100) begin #1 clk = 1; #1 clk = 0; end #(10*2); // Wait 10 clock periods $display("cnt = %0d", cnt); if (cnt === 100) $display("PASSED"); else $display("FAILED"); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/br_gh674.v000066400000000000000000000010661435245347300202560ustar00rootroot00000000000000module test(); function integer array_value(input integer idx); reg [31:0] local_array[1:-1]; integer i; begin for (i = -2; i <= 2; i = i + 1) local_array[i] = i; array_value = local_array[idx]; end endfunction localparam avm2 = array_value(-2); localparam avm1 = array_value(-1); localparam av0 = array_value(0); localparam avp1 = array_value(1); localparam avp2 = array_value(2); initial begin if (avm2 === 'bx && avm1 === -1 && av0 === 0 && avp1 === 1 && avp2 === 'bx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh699.v000066400000000000000000000003511435245347300202610ustar00rootroot00000000000000 // This should generate an error reporting the undef_func, but not segfault. module test1; function [31:0] func1 (input [31:0] x); return undef_func(x); endfunction : func1 localparam X = func1(1); endmodule : test1 iverilog-12_0/ivtest/ivltests/br_gh7.v000066400000000000000000000005001435245347300200740ustar00rootroot00000000000000// Regression test for GitHub issue 7 : Undef propagation in power operator. module bug(); reg [3:0] a; reg [3:0] y; reg failed = 0; initial begin a = 4'd1 / 4'd0; y = 4'd2 ** a; $display("%b", a); $display("%b", y); if (y !== 4'bxxxx) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh72a.v000066400000000000000000000007111435245347300203230ustar00rootroot00000000000000module modname; `define macro1(arg1=d1) $display(`"arg1`"); `define macro2(arg1=d1, arg2=d2) $display(`"arg1 arg2`"); initial begin `macro1() // Works `macro1(1) // Works `macro2() // Cause wrong number of arguments error `macro2(1) // Cause wrong number of arguments error `macro2(1,2) // Works `macro2(,) // Works `macro2(1,) // Works `macro2(1,2) // Works `macro2(,2) // Works end endmodule iverilog-12_0/ivtest/ivltests/br_gh72b.v000066400000000000000000000002671435245347300203320ustar00rootroot00000000000000module modname; `define macro1(arg1) $display(`"arg1`"); `define macro2(arg1=d1, arg2) $display(`"arg1 arg2`"); initial begin `macro1(1) `macro2(1,2) end endmodule iverilog-12_0/ivtest/ivltests/br_gh72b_fail.v000066400000000000000000000005261435245347300213230ustar00rootroot00000000000000module modname; `define macro1(arg1) $display(`"arg1`"); `define macro2(arg1=d1, arg2) $display(`"arg1 arg2`"); initial begin `macro1(1,2) // should fail `macro1(,2) // should fail `macro2() // should fail `macro2(1) // should fail `macro2(1,2,3) // should fail end endmodule iverilog-12_0/ivtest/ivltests/br_gh732.v000066400000000000000000000010011435245347300202360ustar00rootroot00000000000000`timescale 1ns/1ps module Buffer(output Y, input A); specparam Delay = 0.1; assign #Delay Y = A; endmodule module Buffer1(output Y, input A); Buffer inst(.Y(Y), .A(A)); endmodule module Buffer2(output Y, input A); Buffer inst(.Y(Y), .A(A)); endmodule `timescale 1ps/1ps module dut(); reg n1; wire n2; wire n3; Buffer1 b1(.A(n1), .Y(n2)); Buffer2 b2(.A(n2), .Y(n3)); initial begin $monitor("%t %b %b %b", $time, n1, n2, n3); #1000 n1 = 0; #1000 n1 = 1; #1000 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/br_gh756.v000066400000000000000000000003011435245347300202460ustar00rootroot00000000000000module dut(input [3:0] x); initial begin $display("%b", x); if (x === 4'b1111) $display("PASSED"); else $display("FAILED"); end endmodule module test; dut dut('1); endmodule iverilog-12_0/ivtest/ivltests/br_gh782a.v000066400000000000000000000012071435245347300204140ustar00rootroot00000000000000module test; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); `include "ivltests/br_gh782a.vi" // single line comment $display("File %s line %0d", `__FILE__, `__LINE__); `include "ivltests/br_gh782a.vi" /* another single line comment */ $display("File %s line %0d", `__FILE__, `__LINE__); `include "ivltests/br_gh782a.vi" /* multi-line comment */ $display("File %s line %0d", `__FILE__, `__LINE__); `include "ivltests/br_gh782a.vi" /* single */ /* and multi-line comment */ $display("File %s line %0d", `__FILE__, `__LINE__); end endmodule iverilog-12_0/ivtest/ivltests/br_gh782a.vi000066400000000000000000000000771435245347300205710ustar00rootroot00000000000000 $display("Included file %s line %0d", `__FILE__, `__LINE__); iverilog-12_0/ivtest/ivltests/br_gh782b.v000066400000000000000000000022111435245347300204110ustar00rootroot00000000000000/* comment */ `timescale /* comment */ // comment /* comment */ 1 /* comment */ // comment /* comment */ s /* comment */ // comment /* comment */ / /* comment */ // comment /* comment */ 100 /* comment */ // comment /* comment */ ms /* comment */ // comment module t1; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); $printtimescale; end endmodule `timescale 100 ms / 10 ms // single line comment module t2; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); $printtimescale; end endmodule `timescale 10us/1us /* another single line comment */ module t3; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); $printtimescale; end endmodule `timescale 1ns/1ps /* multi-line comment */ module t4; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); $printtimescale; end endmodule `timescale 1ps/1fs /* single */ /* and multi-line comment */ module t5; initial begin $display("File %s line %0d", `__FILE__, `__LINE__); $printtimescale; end endmodule iverilog-12_0/ivtest/ivltests/br_gh782c.v000066400000000000000000000016651435245347300204260ustar00rootroot00000000000000module top; reg pass; highz dutz(); pulllow dut0(); pullhigh dut1(); initial begin pass = 1'b1; #10; if (pass) $display("PASSED"); end endmodule module highz(in); input in; initial #1 if (in !== 1'bz) begin $display("FAILED: high-Z of floating input port (%b)", in); top.pass = 1'b0; end endmodule /* comment */ `unconnected_drive /* comment */ pull0 /* comment */ // comment module pulllow(in); input in; initial #1 if (in !== 1'b0) begin $display("FAILED: pull0 of floating input port (%b)", in); top.pass = 1'b0; end endmodule /* comment */ `nounconnected_drive /* comment */ // comment /* comment */`unconnected_drive/* comment */ /* comment */pull1/* comment */ module pullhigh(in); input in; initial #1 if (in !== 1'b1) begin $display("FAILED: pull1 of floating input port (%b)", in); top.pass = 1'b0; end endmodule /* comment */`nounconnected_drive/* comment */ iverilog-12_0/ivtest/ivltests/br_gh782d.v000066400000000000000000000006351435245347300204230ustar00rootroot00000000000000// This is just a syntax test. /* comment */ `resetall /* comment */ // comment /* comment */ `celldefine /* comment */ // comment module cell1; endmodule /* comment */ `endcelldefine /* comment */ // comment /* comment */`resetall/* comment */ /* comment */`celldefine/* comment */ module cell2; endmodule /* comment */`endcelldefine/* comment */ module test; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/br_gh782e.v000066400000000000000000000006411435245347300204210ustar00rootroot00000000000000// This is just a syntax test. /* comment */ `begin_keywords /* comment */ // comment /* comment */ "1364-2005" /* comment */ // comment module m1; endmodule /* comment */ `end_keywords /* comment */ // comment /* comment */`begin_keywords/* comment */ /* comment */"1364-2005"/* comment */ module m2; endmodule /* comment */`end_keywords/* comment */ module test; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/br_gh782f.v000066400000000000000000000004651435245347300204260ustar00rootroot00000000000000// This is just a syntax test. /* comment */ `default_nettype /* comment */ // comment /* comment */ wire /* comment */ // comment module m1; endmodule /* comment */`default_nettype/* comment */ /* comment */tri0/* comment */ module m2; endmodule module test; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/br_gh788.v000066400000000000000000000002361435245347300202620ustar00rootroot00000000000000module test(); task print_hex; input n; reg [7:0] n; begin $display("%h", n); end endtask initial begin print_hex(66); end endmodule iverilog-12_0/ivtest/ivltests/br_gh79.v000066400000000000000000000004731435245347300201760ustar00rootroot00000000000000module test(); reg [3:0] BadNumber; initial begin BadNumber = 4'b_; BadNumber = 4'b_1; BadNumber = 4'b1_; BadNumber = 4'o_; BadNumber = 4'o_1; BadNumber = 4'o1_; BadNumber = 4'd_; BadNumber = 4'd_1; BadNumber = 4'd1_; BadNumber = 4'h_; BadNumber = 4'h_1; BadNumber = 4'h1_; end endmodule iverilog-12_0/ivtest/ivltests/br_gh793.v000066400000000000000000000005521435245347300202570ustar00rootroot00000000000000// Check that $signed/$unsigned works when being combinatorially assigned with a // delay and the target of the function is a net without any drivers. module top (); wire [7:0] a; wire signed [7:0] b; assign #1 b = $signed(a); initial begin #10 if (b === 8'hzz) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/br_gh8.v000066400000000000000000000013501435245347300201010ustar00rootroot00000000000000// Regression test for GitHub issue 8 : Signedness handling in binary // bitwise operations of constants. module bug(); localparam value1 = 4'sb1010 | 4'sb0000; localparam value2 = 4'sb1010 + 4'sb0000; localparam value3 = ~4'sb0101; localparam value4 = -4'sb0101; reg signed [4:0] result; reg failed = 0; initial begin result = value1; $display("%b", result); if (result !== 5'b11010) failed = 1; result = value2; $display("%b", result); if (result !== 5'b11010) failed = 1; result = value3; $display("%b", result); if (result !== 5'b11010) failed = 1; result = value4; $display("%b", result); if (result !== 5'b11011) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh801.v000066400000000000000000000004441435245347300202450ustar00rootroot00000000000000 module main; initial begin int idx; idx = 1; for ( ; idx < 5 ; idx += 1) begin $display("... %02d", idx); end if (idx !== 5) begin $display("FAILED -- idx=%0d", idx); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh801b.v000066400000000000000000000006021435245347300204030ustar00rootroot00000000000000 module main; initial begin int idx; for (idx = 1 ; idx < 5 ; ) begin $display("... %02d", idx); idx += 1; end if (idx !== 5) begin $display("FAILED -- idx=%0d", idx); $finish; end idx = 2; for ( ; idx < 5 ; ) begin $display("... %02d", idx); idx += 1; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/br_gh9.v000066400000000000000000000011211435245347300200760ustar00rootroot00000000000000// Regression test for GitHub issue 9 : Efficiency of verinum and vpp_net // pow() functions. module bug(); reg [5:0] ra; reg [5:0] ry; wire [5:0] wa = 3; wire [5:0] wy = wa ** 123456789; localparam [5:0] pa = 3; localparam [5:0] py = pa ** 123456789; reg failed = 0; initial begin #0; ra = 3; ry = ra ** 123456789; $display("%b", ry); if (ry !== 6'b110011) failed = 1; $display("%b", wy); if (wy !== 6'b110011) failed = 1; $display("%b", py); if (py !== 6'b110011) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99a.v000066400000000000000000000004021435245347300203310ustar00rootroot00000000000000module test(); wire [7:0] value; wire pass; assign value[3:0] = 4'd2; assign pass = (value === 8'bzzzz0010); initial begin #2 $display("%b %b", value, pass); if (pass === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99b.v000066400000000000000000000004061435245347300203360ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = value1 + 8'd1; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99c.v000066400000000000000000000004221435245347300203350ustar00rootroot00000000000000module test(); wire signed [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = abs(value1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99d.v000066400000000000000000000005151435245347300203410ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = value1 + 0.0; initial begin // value1 gets cast to real, so 'z' bits are converted to '0'. #2 $display("%b %b", value1, value2); if (value2 === 8'b00000010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99e.v000066400000000000000000000005221435245347300203400ustar00rootroot00000000000000module test(); wire [7:0] value1; wire bit [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = value1; initial begin // value1 gets cast to 2-state, so 'z' bits are converted to '0'. #2 $display("%b %b", value1, value2); if (value2 === 8'b00000010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99f.v000066400000000000000000000004611435245347300203430ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = $itor(value1); initial begin // 'z' bits are converted to '0'. #2 $display("%b %b", value1, value2); if (value2 === 8'b00000010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99g.v000066400000000000000000000004171435245347300203450ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; buf buffer[7:0](value2, value1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bxxxx0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99h.v000066400000000000000000000004171435245347300203460ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; not buffer[7:0](value2, value1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bxxxx1101) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99i.v000066400000000000000000000004301435245347300203420ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; bufif1 buffer[7:0](value2, value1, 1'b1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bxxxx0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99j.v000066400000000000000000000004261435245347300203500ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; nmos buffer[7:0](value2, value1, 1'b1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bzzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99k.v000066400000000000000000000004341435245347300203500ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; cmos buffer[7:0](value2, value1, 1'b1, 1'b0); initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bzzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99l.v000066400000000000000000000004151435245347300203500ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign value2 = value1 | 8'd1; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bxxxx0011) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99m.v000066400000000000000000000004111435245347300203450ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign #1 value2 = value1; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bzzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99o.v000066400000000000000000000004001435245347300203450ustar00rootroot00000000000000module test(); wire [7:0] value1; wire value2; assign value1[3:0] = 4'd2; assign value2 = |value1; initial begin #2 $display("%b %b", value1, value2); if (value2 === 1'b1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99p.v000066400000000000000000000004271435245347300203570ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [9:0] value2; assign value1[3:0] = 4'd2; assign value2 = {1'b0, value1, 1'b1}; initial begin #2 $display("%b %b", value1, value2); if (value2 === 10'b0zzzz00101) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99q.v000066400000000000000000000004261435245347300203570ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [15:0] value2; assign value1[3:0] = 4'd2; assign value2 = {2{value1}}; initial begin #2 $display("%b %b", value1, value2); if (value2 === 16'bzzzz0010zzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99r.v000066400000000000000000000004221435245347300203540ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [9:0] value2; assign value1[3:0] = 4'd2; assign value2 = $signed(value1); initial begin #2 $display("%b %b", value1, value2); if (value2 === 10'bzzzzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99s.v000066400000000000000000000004241435245347300203570ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign value1[3:0] = 4'd2; assign (weak1,weak0) value2 = value1; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'bzzzz0010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99t.v000066400000000000000000000005271435245347300203640ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign (strong1,weak0) value1[3:0] = 4'b1010; nmos buffer[7:0](value2, value1, 1'b1); assign (strong1,weak0) value2 = 8'b00110011; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'b00111011) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99u.v000066400000000000000000000005351435245347300203640ustar00rootroot00000000000000module test(); wire [7:0] value1; wire [7:0] value2; assign (strong1,weak0) value1[3:0] = 4'b1010; cmos buffer[7:0](value2, value1, 1'b1, 1'b0); assign (strong1,weak0) value2 = 8'b00110011; initial begin #2 $display("%b %b", value1, value2); if (value2 === 8'b00111011) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99v.v000066400000000000000000000005561435245347300203700ustar00rootroot00000000000000module test(); wire [7:0] value1; reg [7:0] value2; reg clk; assign value1[3:0] = 4'b1010; always @(posedge clk) begin value2 <= value1; end (* ivl_synthesis_off *) initial begin #1 clk = 0; #1 clk = 1; #1 clk = 0; $display("%b %b", value1, value2); if (value2 === 8'bzzzz1010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99w.v000066400000000000000000000005521435245347300203650ustar00rootroot00000000000000module test(); wire [7:0] value1; reg [7:0] value2; reg en; assign value1[3:0] = 4'b1010; always @* begin if (en) value2 <= value1; end (* ivl_synthesis_off *) initial begin #1 en = 0; #1 en = 1; #1 en = 0; $display("%b %b", value1, value2); if (value2 === 8'bzzzz1010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_gh99x.v000066400000000000000000000006661435245347300203740ustar00rootroot00000000000000module test(); wire [7:0] value1; reg [7:0] value2; reg clk; assign value1[3:0] = 4'b1010; always @(posedge clk) begin value2[3:0] <= value1; end (* ivl_synthesis_off *) initial begin #1 clk = 0; #1 clk = 1; #1 clk = 0; $display("%b %b", value1, value2); `ifdef __ICARUS_SYNTH__ if (value2 === 8'bzzzz1010) `else if (value2 === 8'bxxxx1010) `endif $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20150315.v000066400000000000000000000005301435245347300206430ustar00rootroot00000000000000// Regression test for bug reported by Niels Moeller on // 15-Mar-2015 via the iverilog-devel mailing list. module test(); wire [7:0] my_net; assign my_net[3:0] = 1; assign my_net[7:4] = 2; initial begin #1 $monitor("At time %0t, field 1 = %h, field 2 = %h", $time, my_net[3:0], my_net[7:4]); #1 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20150315b.v000066400000000000000000000004141435245347300210060ustar00rootroot00000000000000// Regression test for bug reported by Niels Moeller on // 15-Mar-2015 via the iverilog-devel mailing list. // Unpacked structs are not supported yet, but should // be handled gracefully. module test(); typedef struct { logic value; } data_t; data_t d; endmodule iverilog-12_0/ivtest/ivltests/br_ml20150321.v000066400000000000000000000023501435245347300206420ustar00rootroot00000000000000// Regression test for bug reported by Niels Moeller on 21-Mar-2015 via // iverilog-devel mailing list. Extended to cover similar problems. This // is just testing compiler error recovery. module test(); integer array[3:0]; integer i1; always @* begin for (i1 = 0; i1 < 4; i1 = i1 + 1) begin array[i1] = undeclared; end end integer i2; always @* begin for (i2 = 0; i2 < 4; i2 = i2 + 1) begin undeclared = array[i2]; end end integer i3; always @* begin for (i3 = undeclared; i3 < 4; i3 = i3 + 1) begin array[i3] = i3; end end integer i4; always @* begin for (i4 = 0; i4 < undeclared; i4 = i4 + 1) begin array[i4] = i4; end end integer i5; always @* begin for (i5 = 0; i5 < 4; i5 = i5 + undeclared) begin array[i5] = i5; end end integer i6; always @* begin i6 = 0; while (i6 < undeclared) begin array[i6] = i6; i6 = i6 + 1; end end integer i7; always @* begin i7 = 0; while (i7 < 4) begin array[i7] = undeclared; i7 = i7 + 1; end end integer i8; always @* begin i8 = 0; repeat (undeclared) begin array[i8] = i8; i8 = i8 + 1; end end integer i9; always @* begin i9 = 0; repeat (4) begin array[i9] = undeclared; i9 = i9 + 1; end end endmodule iverilog-12_0/ivtest/ivltests/br_ml20150424.v000066400000000000000000000004501435245347300206450ustar00rootroot00000000000000// Regression test for bug reported by Orson on 24-Apr-15 via iverilog_devel. module test(); localparam value = $ivlh_to_unsigned((1000 / ($signed(13'd50))), 12); initial begin $display("%d", value); if (value === 20) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20171017.v000066400000000000000000000003561435245347300206530ustar00rootroot00000000000000module test(output [7:0] dataout[1:0]); assign dataout[0] = 8'h55; assign dataout[1] = 8'haa; initial begin #0; if (dataout[0] === 8'h55 && dataout[1] === 8'haa) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20180227.v000066400000000000000000000001571435245347300206550ustar00rootroot00000000000000module test(); string str; reg [127:0] bitstr; initial begin str = "hello"; bitstr = str; end endmodule iverilog-12_0/ivtest/ivltests/br_ml20180309a.v000066400000000000000000000005511435245347300210150ustar00rootroot00000000000000module test(); string str1 = "abcd"; string str2 = "efgh"; typedef logic [31:0] vector; vector data[1:0]; initial begin data[0] = vector'(str1); data[1] = vector'(str2); $display("%s %s", data[0], data[1]); if (data[0] === "abcd" && data[1] === "efgh") $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20180309b.v000066400000000000000000000005471435245347300210230ustar00rootroot00000000000000module test(); string str1 = "abcd"; string str2 = "efgh"; typedef bit [31:0] vector; vector data[1:0]; initial begin data[0] = vector'(str1); data[1] = vector'(str2); $display("%s %s", data[0], data[1]); if (data[0] === "abcd" && data[1] === "efgh") $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20181012a.v000066400000000000000000000000541435245347300210030ustar00rootroot00000000000000module test(); reg [0] illegal; endmodule iverilog-12_0/ivtest/ivltests/br_ml20181012b.v000066400000000000000000000000531435245347300210030ustar00rootroot00000000000000module test(); reg [] illegal; endmodule iverilog-12_0/ivtest/ivltests/br_ml20181012c.v000066400000000000000000000000541435245347300210050ustar00rootroot00000000000000module test(); reg [$] illegal; endmodule iverilog-12_0/ivtest/ivltests/br_ml20181012d.v000066400000000000000000000000531435245347300210050ustar00rootroot00000000000000module test(); reg illegal[0]; endmodule iverilog-12_0/ivtest/ivltests/br_ml20190806a.v000066400000000000000000000007471435245347300210270ustar00rootroot00000000000000primitive latch(q, e, d); output q; input e; input d; reg q; initial q = 1'b0; table // e d | q | q+ | 1 1 : ? : 1 ; 1 0 : ? : 0 ; 0 ? : ? : - ; endtable endprimitive module test(); wire q; reg e; reg d; reg r; latch latch(q, e, d); always @(q) begin r = q; end initial begin #1; // check that the always process executed before the initial process if (r === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20190806b.v000066400000000000000000000007731435245347300210270ustar00rootroot00000000000000primitive latch(q, e, d); output q; input e; input d; reg q; table // e d | q | q+ | 1 1 : ? : 1 ; 1 0 : ? : 0 ; 0 ? : ? : - ; endtable endprimitive module test(); wire q; reg e; reg d; reg r; latch latch(q, e, d); always @(q) begin r = 1; end initial begin #1; $display("%b %b", q, r); // the 'x' should propagate to q before the start of simulation if (r === 1'bx && q === 1'bx) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20190814.sdf000066400000000000000000000013441435245347300211660ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "3.0" ) (DESIGN "top") (DATE "Tue Aug 13 18:03:42 2019") (VENDOR "XILINX") (PROGRAM "Vivado") (VERSION "2019.1") (DIVIDER /) (TIMESCALE 1ps) (CELL (CELLTYPE "BUFGCE") (INSTANCE clk_IBUF_BUFG_inst) (DELAY (PATHPULSEPERCENT (30.0)) (ABSOLUTE (IOPATH I O (40.0:47.0:47.0) (40.0:47.0:47.0)) ) ) (TIMINGCHECK (SETUPHOLD (posedge CE) (posedge I) (84.0:275.0:275.0) (0.0:0.0:0.0)) (SETUPHOLD (negedge CE) (posedge I) (84.0:275.0:275.0) (0.0:0.0:0.0)) (PERIOD (posedge I) (1499.0:1499.0:1499.0)) (PERIOD (negedge I) (1499.0:1499.0:1499.0)) (WIDTH (negedge CE) (550.0:550.0:550.0)) (WIDTH (posedge CE) (550.0:550.0:550.0)) ) ) ) iverilog-12_0/ivtest/ivltests/br_ml20190814.v000066400000000000000000000006651435245347300206640ustar00rootroot00000000000000`timescale 1ns/1ps module BUFGCE( output O, input I, input CE ); bufif1(O, I, CE); specify (I => O) = (0.1, 0.2); (CE => O) = (0.3, 0.4); endspecify endmodule module dut( output out, input in, input en ); BUFGCE clk_IBUF_BUFG_inst(.O(out), .I(in), .CE(en)); endmodule module top; wire out; reg in, en; dut dut(out, in, en); initial begin $sdf_annotate("ivltests/br_ml20190814.sdf", dut); end endmodule iverilog-12_0/ivtest/ivltests/br_ml20191221.v000066400000000000000000000004021435245347300206420ustar00rootroot00000000000000module test; integer i; class myclass; integer j; function void init(); j = i; endfunction endclass myclass c; initial begin i = 1; c = new; c.init(); if (c.j === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_mw20171108.v000066400000000000000000000017511435245347300206670ustar00rootroot00000000000000module bug(); function signed [31:0] fpreal( input real in ); real m; real r; begin m = 1 << 16; r = in * m; fpreal = $rtoi(r); end endfunction function signed [31:0] fpdiv( input signed [31:0] a, input signed [31:0] b ); reg signed [47:0] r; begin r = a << 16; fpdiv = r / b; end endfunction function signed [31:0] fpmul( input signed [31:0] a, input signed [31:0] b ); reg signed [47:0] r; begin r = a * b; fpmul = r >>> 16; end endfunction function signed [31:0] fppow( input signed [31:0] a, input real b ); real ar; real r; begin ar = $itor(a) / (1 << 16); r = ar ** b; fppow = fpreal(r); end endfunction wire signed [31:0] a = 1 << 16; wire signed [31:0] b = 4 << 16; wire signed [31:0] c = fpdiv(a, b); wire signed [31:0] d = fppow(c, 2.0); initial begin #1 $display("(%0f / %0f)**2.0 = %0f", a / 65536.0, b / 65536.0, d / 65536.0); if (d === 32'h0000_1000) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/br_mw20200501.v000066400000000000000000000003531435245347300206520ustar00rootroot00000000000000module test(); reg [9:0] buffer[$]; reg [9:0] out; initial begin buffer.push_back(3); out = buffer.pop_front(); $display("out = %0d", out); if (out === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/bufif.v000066400000000000000000000043461435245347300200330ustar00rootroot00000000000000// Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * This module implements what essentially amounts to an array of DFF * devices with output enable. This test checks the operation of the * bufif0 and bufif1 devices. */ module grayGap (ad, clk, read, write); output [31:0] ad; input clk, read, write; reg [15:0] regff; bufif0 ad_drv [31:0] (ad, {16'b0, regff}, read); always @(posedge clk) if (write) regff = ad[15:0]; endmodule module main; wire [31:0] ad; reg clk, read, write; reg [31:0] ad_val; reg ad_en; bufif1 ad_drv[31:0] (ad, ad_val, ad_en); grayGap test (ad, clk, read, write); always #10 clk = ~clk; initial begin clk = 1; read = 1; write = 0; $monitor($time, "ad=%b", ad); // Set up to write a value into the grayGap register. @(negedge clk) ad_val = 32'haaaa_aaaa; read = 1; write = 1; ad_en = 1; // The posedge has passed, now set up to read that value // out. Turn all the drivers off for a moment, to see that the // line becomes tri-state... @(negedge clk) ad_en = 0; write = 0; // Now read the value. #1 read = 0; #1 $display("Wrote %h, got %h", ad_val, ad); if (ad !== 32'b0000_0000_0000_0000_1010_1010_1010_1010) begin $display("FAILED -- ad is %b", ad); $finish; end #2 read = 1; $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/busbug.v000066400000000000000000000003471435245347300202240ustar00rootroot00000000000000module busbug (); reg x,y,z; initial begin x=1'b0; y=1'b0; z=1'b1; $display("%b%b=%b", x ^ y, x ^ (y ^ z), {x ^ y, x ^ (y ^ z)} ); end endmodule iverilog-12_0/ivtest/ivltests/ca_64delay.v000066400000000000000000000026671435245347300206570ustar00rootroot00000000000000/* * Verify that the continuous assignments support a delay that is * greater than 32 bits. The top delays are in seconds and the other * delays are in ps. The second delays all require more than 32 bits * to work correctly. They will use the /d version. */ `timescale 1s/1s module gt32b; wire real rlval; wire rval; wire aval[1:0]; wire [7:0] psval; assign #1 rlval = 1.0; assign #2 rval = 1'b1; assign #3 aval[0] = 1'b0; assign #4 psval[1] = 1'b1; initial begin $timeformat(-12, 0, " ps", 16); #1; $display("dl:gt32b- %t", $realtime); end always @(rlval) begin $display("rl:gt32b- %t", $realtime); end always @(rval) begin $display("rg:gt32b- %t", $realtime); end always @(aval[0]) begin $display("ar:gt32b- %t", $realtime); end always @(psval) begin $display("ps:gt32b- %t", $realtime); end endmodule `timescale 1ps/1ps module ls32b; wire real rlval; wire rval; wire aval[1:0]; wire [7:0] psval; assign #1 rlval = 1.0; assign #2 rval = 1'b1; assign #3 aval[0] = 1'b0; assign #4 psval[1] = 1'b1; initial begin #1; $display("dl:ls32b- %t", $realtime); end always @(rlval) begin $display("rl:ls32b- %t", $realtime); end always @(rval) begin $display("rg:ls32b- %t", $realtime); end always @(aval[0]) begin $display("ar:ls32b- %t", $realtime); end always @(psval) begin $display("ps:ls32b- %t", $realtime); end endmodule iverilog-12_0/ivtest/ivltests/ca_force.v000066400000000000000000000020331435245347300204700ustar00rootroot00000000000000module top; reg pass; reg in; wire ca; assign ca = in; initial begin pass = 1'b1; if (ca !== 1'bx || in !== 1'bx) begin $display("Failed T0 check, in %b, ca %b", in, ca); pass = 1'b0; end in = 1'b0; #1; if (ca !== 1'b0 || in !== 1'b0) begin $display("Failed 0 check, in %b, ca %b", in, ca); pass = 1'b0; end in = 1'b1; #1; if (ca !== 1'b1 || in !== 1'b1) begin $display("Failed 1 check, in %b, ca %b", in, ca); pass = 1'b0; end force ca = 1'b0; #1; if (ca !== 1'b0 || in !== 1'b1) begin $display("Failed force 0 check, in %b, ca %b", in, ca); pass = 1'b0; end in = 1'bx; #1; if (ca !== 1'b0 || in !== 1'bx) begin $display("Failed change a check, in %b, ca %b", in, ca); pass = 1'b0; end force ca = 1'b1; #1; if (ca !== 1'b1 || in !== 1'bx) begin $display("Failed force 1 check, in %b, ca %b", in, ca); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_func.v000066400000000000000000000005311435245347300203260ustar00rootroot00000000000000module example(); reg [7:0] scale, a, b; wire [7:0] c; function [7:0] scaled; input [7:0] value; begin scaled = value * scale; end endfunction assign c = scaled(a) + scaled(b); initial begin #1 a = 2; #1 scale = 2; #1 b = 3; #1 $display(c); if (c === 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_mult.v000066400000000000000000000003461435245347300203600ustar00rootroot00000000000000module top; real in; wire signed [31:0] tmp; assign tmp = $rtoi(in*2.0); initial begin for (in=-1.0; in <= 1.0; in=in+1.0) begin #1 $display(tmp, " %.5f", in); end //$display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_pow_signed.v000066400000000000000000000015221435245347300215320ustar00rootroot00000000000000module top; reg passed = 1'b1; reg signed [15:0] a, b; /* Currently the result can only be as big as a native long! */ wire signed [31:0] r = a ** b; initial begin a = 5; b = 2; #1 if (r != 25) begin $display("Failed: 5 ** 2 gave %d, expected 25", r); passed = 1'b0; end a = -5; b = 3; #1 if (r != -125) begin $display("Failed: -5 ** 3 gave %d, expected -125", r); passed = 1'b0; end a = 2; b = 30; #1 if (r != 1_073_741_824) begin $display("Failed: 2 ** 30 gave %d, expected 1,073,741,824", r); passed = 1'b0; end a = -2; b = 31; #1 if (r != -2_147_483_648) begin $display("Failed: -2 ** 31 gave %d, expected -2,147,483,648", r); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_pow_synth.v000066400000000000000000000011651435245347300214310ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [2:0] in; real rin; wire out, rout; assign out = ('d4 == in**2'd2); assign rout = (4.0 == rin**2); initial begin in = 'd0; rin = 0.0; #1 if (out != 1'b0 && rout != 1'b0) begin $display("FAILED 0/0.0 check"); pass = 1'b0; end #1 in = 'd1; rin = 1.0; #1 if (out != 1'b0 && rout != 1'b0) begin $display("FAILED 1/1.0 check"); pass = 1'b0; end #1 in = 'd2; rin = 2.0; #1 if (out != 1'b1 && rout != 1'b1) begin $display("FAILED 2/2.0 check"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_pow_unsigned.v000066400000000000000000000017761435245347300221100ustar00rootroot00000000000000module top; reg passed = 1'b1; reg [199:0] a, b; wire [199:0] r; assign #1 r = a ** b; initial begin a = 'd5; b = 'd2; // A simple test. #2; if (r != 'd25) begin $display("Failed: 5 ** 2 gave %d, expected 25", r); passed = 1'b0; end b = 'd55; // A 128 bit value. #2; if (r != 200'd277555756156289135105907917022705078125) begin $display("Failed: 5 ** 55\n gave %0d", r); $display(" expected 277555756156289135105907917022705078125"); passed = 1'b0; end b = 'd86; // A 200 bit value. #2; if (r != 200'd1292469707114105741986576081359316958696581423282623291015625) begin $display("Failed: 5 ** 55\n gave %0d", r); $display(" expected 1292469707114105741986576081359316958696581423282623291015625"); passed = 1'b0; end if (r != 'd5**'d86) begin $display("Failed: compile-time/run-time value mismatch."); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_real_logical.v000066400000000000000000000134611435245347300220160ustar00rootroot00000000000000module top; parameter parg0 = 0.0; parameter parg1 = 1.0; parameter parg2 = 2.0; parameter pargi = 1.0/0.0; // Inf. parameter pargn = $sqrt(-1.0); // NaN. real arg0, arg1, arg2, argi, argn; reg pass; wire r_p0_b = !parg0; wire r_p1_b = !parg1; wire r_p2_b = !parg2; wire r_pi_b = !pargi; wire r_pn_b = !pargn; wire r_0_b = !arg0; wire r_1_b = !arg1; wire r_2_b = !arg2; wire r_i_b = !argi; wire r_n_b = !argn; wire r_p01_a = parg0 && parg1; wire r_p02_a = parg0 && parg2; wire r_p12_a = parg1 && parg2; wire r_01_a = arg0 && arg1; wire r_02_a = arg0 && arg2; wire r_12_a = arg1 && arg2; wire r_p00_o = parg0 || 0; wire r_p01_o = parg0 || parg1; wire r_p02_o = parg0 || parg2; wire r_00_o = arg0 || 0; wire r_01_o = arg0 || arg1; wire r_02_o = arg0 || arg2; wire r_p0_t = parg0 ? 1'b1 : 1'b0; wire r_p1_t = parg1 ? 1'b1 : 1'b0; wire r_p2_t = parg2 ? 1'b1 : 1'b0; wire r_pi_t = pargi ? 1'b1 : 1'b0; wire r_pn_t = pargn ? 1'b1 : 1'b0; wire r_0_t = arg0 ? 1'b1 : 1'b0; wire r_1_t = arg1 ? 1'b1 : 1'b0; wire r_2_t = arg2 ? 1'b1 : 1'b0; wire r_i_t = argi ? 1'b1 : 1'b0; wire r_n_t = argn ? 1'b1 : 1'b0; initial begin pass = 1'b1; arg0 = 0.0; arg1 = 1.0; arg2 = 2.0; argi = 1.0/0.0; // Inf. argn = $sqrt(-1.0); // NaN. #1; /* Check ! on a constant real value. */ if (r_p0_b !== 1'b1) begin $display("Failed: CA constant !0.0, expected 1'b1, got %b", r_p0_b); pass = 1'b0; end if (r_p1_b !== 1'b0) begin $display("Failed: CA constant !1.0, expected 1'b0, got %b", r_p1_b); pass = 1'b0; end if (r_p2_b !== 1'b0) begin $display("Failed: CA constant !2.0, expected 1'b0, got %b", r_p2_b); pass = 1'b0; end if (r_pi_b !== 1'b0) begin $display("Failed: CA constant !Inf, expected 1'b0, got %b", r_pi_b); pass = 1'b0; end if (r_pn_b !== 1'b0) begin $display("Failed: CA constant !NaN, expected 1'b0, got %b", r_pn_b); pass = 1'b0; end /* Check ! on a real variable. */ if (r_0_b !== 1'b1) begin $display("Failed: !0.0, expected 1'b1, got %b", r_0_b); pass = 1'b0; end if (r_1_b !== 1'b0) begin $display("Failed: !1.0, expected 1'b0, got %b", r_1_b); pass = 1'b0; end if (r_2_b !== 1'b0) begin $display("Failed: !2.0, expected 1'b0, got %b", r_2_b); pass = 1'b0; end if (r_i_b !== 1'b0) begin $display("Failed: !Inf, expected 1'b0, got %b", r_i_b); pass = 1'b0; end if (r_n_b !== 1'b0) begin $display("Failed: !NaN, expected 1'b0, got %b", r_n_b); pass = 1'b0; end /* Check && on a constant real value. */ if (r_p01_a !== 1'b0) begin $display("Failed: constant 0.0 && 1.0, expected 1'b0, got %b", r_p01_a); pass = 1'b0; end if (r_p02_a !== 1'b0) begin $display("Failed: constant 0.0 && 2.0, expected 1'b0, got %b", r_p02_a); pass = 1'b0; end if (r_p12_a !== 1'b1) begin $display("Failed: constant 1.0 && 2.0, expected 1'b1, got %b", r_p12_a); pass = 1'b0; end /* Check && on a real variable. */ if (r_01_a !== 1'b0) begin $display("Failed: 0.0 && 1.0, expected 1'b0, got %b", r_01_a); pass = 1'b0; end if (r_02_a !== 1'b0) begin $display("Failed: 0.0 && 2.0, expected 1'b0, got %b", r_02_a); pass = 1'b0; end if (r_12_a !== 1'b1) begin $display("Failed: 1.0 && 2.0, expected 1'b1, got %b", r_12_a); pass = 1'b0; end /* Check || on a constant real value. */ if (r_p00_o !== 1'b0) begin $display("Failed: constant 0.0 || 0, expected 1'b0, got %b", r_p00_o); pass = 1'b0; end if (r_p01_o !== 1'b1) begin $display("Failed: constant 0.0 || 1.0, expected 1'b1, got %b", r_p01_o); pass = 1'b0; end if (r_p02_o !== 1'b1) begin $display("Failed: constant 0.0 || 2.0, expected 1'b1, got %b", r_p02_o); pass = 1'b0; end /* Check || on a real variable. */ if (r_00_o !== 1'b0) begin $display("Failed: 0.0 || 0, expected 1'b0, got %b", r_00_o); pass = 1'b0; end if (r_01_o !== 1'b1) begin $display("Failed: 0.0 || 1.0, expected 1'b1, got %b", r_01_o); pass = 1'b0; end if (r_02_o !== 1'b1) begin $display("Failed: 0.0 || 2.0, expected 1'b1, got %b", r_02_o); pass = 1'b0; end /* Check the ternary with a constant real cond. value. */ if (r_p0_t !== 1'b0) begin $display("Failed: constant 0.0 ? ..., expected 1'b0, got %b", r_p0_t); pass = 1'b0; end if (r_p1_t !== 1'b1) begin $display("Failed: constant 1.0 ? ..., expected 1'b1, got %b", r_p1_t); pass = 1'b0; end if (r_p2_t !== 1'b1) begin $display("Failed: constant 2.0 ? ..., expected 1'b1, got %b", r_p2_t); pass = 1'b0; end if (r_pi_t !== 1'b1) begin $display("Failed: constant Inf ? ..., expected 1'b1, got %b", r_pi_t); pass = 1'b0; end if (r_pn_t !== 1'b1) begin $display("Failed: constant NaN ? ..., expected 1'b1, got %b", r_pn_t); pass = 1'b0; end /* Check the ternary with a real cond. variable. */ if (r_0_t !== 1'b0) begin $display("Failed: 0.0 ? ..., expected 1'b0, got %b", r_0_t); pass = 1'b0; end if (r_1_t !== 1'b1) begin $display("Failed: 1.0 ? ..., expected 1'b1, got %b", r_1_t); pass = 1'b0; end if (r_2_t !== 1'b1) begin $display("Failed: 2.0 ? ..., expected 1'b1, got %b", r_2_t); pass = 1'b0; end if (r_i_t !== 1'b1) begin $display("Failed: Inf ? ..., expected 1'b1, got %b", r_i_t); pass = 1'b0; end if (r_n_t !== 1'b1) begin $display("Failed: NaN ? ..., expected 1'b1, got %b", r_n_t); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ca_time.v000066400000000000000000000004251435245347300203330ustar00rootroot00000000000000`timescale 1ns/1ns module top; reg itrig = 1'b0; wire [31:0] tm, stm; assign tm = itrig * $time; assign stm = itrig * $stime; initial begin $monitor(tm,, stm); #1 itrig = 1'b1; #1 itrig = 1'b0; #1 itrig = 1'b1; #1 itrig = 1'b0; end endmodule iverilog-12_0/ivtest/ivltests/ca_time_real.v000066400000000000000000000003541435245347300213370ustar00rootroot00000000000000`timescale 1ns/1ns module top; real rtrig = 0.0; wire real rtm; assign rtm = rtrig * $realtime; initial begin $monitor(rtm); #1 rtrig = 1.0; #1 rtrig = 0.0; #1 rtrig = 1.0; #1 rtrig = 0.0; end endmodule iverilog-12_0/ivtest/ivltests/ca_time_smtm.v000066400000000000000000000003641435245347300213750ustar00rootroot00000000000000`timescale 1ns/1ns module top; reg itrig = 1'b0; wire [31:0] smtm; assign smtm = itrig * $simtime; initial begin $monitor(smtm); #1 itrig = 1'b1; #1 itrig = 1'b0; #1 itrig = 1'b1; #1 itrig = 1'b0; end endmodule iverilog-12_0/ivtest/ivltests/ca_var_delay.v000066400000000000000000000037171435245347300213520ustar00rootroot00000000000000`timescale 1ns/100ps module top; reg pass = 1'b1; integer idelay = 2; real rdelay = 2.0; real rin = 1.0; reg ctl = 1'b1; wire outr, outi, muxr, muxi; wire real rout; reg in = 1'b1; assign #(idelay) outi = in; assign #(rdelay) outr = ~in; assign #(rdelay) rout = rin; assign #(idelay) muxi = ctl ? in : 1'b0; assign #(rdelay) muxr = ctl ? ~in : 1'b1; initial begin // Wait for everything to settle including the delay value! #2.1; if (outi !== 1'b1 || outr !== 1'b0 || rout != 1.0) begin $display("FAILED: initial value, expected 1'b1/1'b0/1.0, got %b/%b/%f", outi, outr, rout); pass = 1'b0; end if (muxi !== 1'b1 || muxr !== 1'b0) begin $display("FAILED: initial value (mux), expected 1'b1/1'b0, got %b/%b", muxi, muxr); pass = 1'b0; end in = 1'b0; rin = 2.0; #1.9; if (outi !== 1'b1 || outr !== 1'b0 || rout != 1.0) begin $display("FAILED: mid value, expected 1'b1/1'b0/1.0, got %b/%b/%f", outi, outr, rout); pass = 1'b0; end if (muxi !== 1'b1 || muxr !== 1'b0) begin $display("FAILED: mid value (mux), expected 1'b1/1'b0, got %b/%b", muxi, muxr); pass = 1'b0; end #0.2; if (outi !== 1'b0 || outr !== 1'b1 || rout != 2.0) begin $display("FAILED: final value, expected 1'b0/1'b1/2.0, got %b/%b/%f", outi, outr, rout); pass = 1'b0; end if (muxi !== 1'b0 || muxr !== 1'b1) begin $display("FAILED: final value (mux), expected 1'b0/1'b1, got %b/%b", muxi, muxr); pass = 1'b0; end idelay = 3; in = 1'b1; #2.9; if (outi !== 1'b0) begin $display("FAILED: initial change, expected 1'b0, got %b", outi); pass = 1'b0; end #0.2; if (outi !== 1'b1) begin $display("FAILED: initial change, expected 1'b1, got %b", outi); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/case1.v000066400000000000000000000010141435245347300177210ustar00rootroot00000000000000module main; reg [3:0] cond; reg [2:0] t; always @* case (cond&4'b1110) 'h0: t = 7; 'h2: t = 6; 'h4: t = 5; 'h6: t = 4; 'h8: t = 3; 'ha: t = 2; 'hc: t = 1; 'he: t = 0; endcase integer i; initial begin for (i = 0 ; i < 8 ; i = i + 1) begin cond = i << 1; #1 if (t !== (7 - i)) begin $display("FAILED -- i=%d, cond=%b, t=%b", i, cond, t); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case2.v000066400000000000000000000011351435245347300177260ustar00rootroot00000000000000module main; reg [3:0] cond; reg [2:0] t, q; always @* begin case (cond&4'b1110) 'h0: t = 7; 'h2: t = 6; 'h4: t = 5; 'h6: t = 4; 'h8: t = 3; 'ha: t = 2; 'hc: t = 1; 'he: t = 0; endcase // case(cond&4'b1110) q = ~t; end // always @ * integer i; initial begin for (i = 0 ; i < 8 ; i = i + 1) begin cond = i << 1; #1 if (q !== ( 3'b111 & ~(7 - i))) begin $display("FAILED -- i=%d, cond=%b, q=%b", i, cond, q); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case3.8A.v000066400000000000000000000032321435245347300201760ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate case/endcase - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) case (val1 & val2 ) 3'b000: result = 0; 3'b001: result = 1 ; 3'b010: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; #1 if(result !==0) begin $display("FAILED case 3.8A - case (expr) lab1: "); error = 1; end val1 = 3'b001; val2 = 3'b011; #1 if(result !==1) begin $display("FAILED case 3.8A - case (expr) lab2: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 #1 if(result !==1) begin $display("FAILED case 3.8A - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case3.8B.v000066400000000000000000000032251435245347300202010ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate case/endcase w/ label list - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) case (val1 & val2 ) 3'b000,3'b001: result = 0; 3'b101: result = 1 ; 3'b110,3'b111,3'b100: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; #1 if(result !==0) begin $display("FAILED case 3.8B - case (expr) lab1: "); error = 1; end val1 = 3'b101; val2 = 3'b111; #1 if(result !==1) begin $display("FAILED case 3.8B - case (expr) lab2: "); error = 1; end val1 = 3'b110; #1 if(result !==2) begin $display("FAILED case 3.8B - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case3.8C.v000066400000000000000000000032631435245347300202040ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate case/endcase w/ null_statement - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) case (val1 & val2 ) 3'b000,3'b001: result = 0; 3'b101: ; 3'b011: result = 1; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; #1 if(result !==0) begin $display("FAILED case 3.8C - case (expr) lab1: "); error = 1; end val1 = 3'b111; val2 = 3'b011; #1 if(result !==1) begin $display("FAILED case 3.8C - case (expr) lab2: "); error = 1; end val2 = 3'b101; // Should activate null statement and get no action #1 if(result !==1) begin $display("FAILED case 3.8C - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case3.8D.v000066400000000000000000000037451435245347300202120ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate case with labels of x and z. Should be match module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 ) case (val1) 3'b000: result = 0; 3'b001: result = 1 ; 3'b010: result = 2; 3'bx11: result = 4; 3'bz11: result = 5; endcase initial begin error = 0; #1; val1 = 3'b0; #1; if(result !== 0) begin $display("FAILED case 3.8D - case (expr) lab1: "); error = 1; end #1; val1 = 3'b001; #1; if(result !== 1) begin $display("FAILED case 3.8D - case (expr) lab2: "); error = 1; end #1 ; val1 = 3'b010; #1; if(result !== 2) begin $display("FAILED case 3.8D - case (expr) lab3: "); error = 1; end #1 ; val1 = 3'bz11; #1; if(result !== 5) begin $display("FAILED case 3.8D - case (expr) lab5: "); error = 1; end #1 ; val1 = 3'bx11; #1; if(result !== 4) begin $display("FAILED case 3.8D - case (expr) lab4: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case3.v000066400000000000000000000011351435245347300177270ustar00rootroot00000000000000module switch (q,a,b,c,d,sel); input a,b,c,d; input [1:0] sel; output q; reg q; always @ * case (sel) 2'b00: q = a; 2'b01: q = b; 2'b10: q = c; 2'b11: q = d; endcase endmodule module test ; reg [1:0] sel; reg a,b,c,d; wire q; switch u_switch (q,a,b,c,d,sel); initial begin a = 0; b = 0; c = 0; d = 0; sel = 2'b00; #1; if(q !== 1'b0) begin $display("FAILED"); $finish; end a = 1; #1; if(q !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/case4.v000066400000000000000000000022331435245347300177300ustar00rootroot00000000000000/* * This tests the synthesis of a very sparse case statement. The * combinational case statement below specifies only two of 256 * possible selections, with all the remaining left to the default. * What's more, all the inputs to the MUX are constant, giving * even further opportunity for optimization. */ module main; reg [7:0] val; reg [7:0] out; (* ivl_combinational *) always @ (val) begin case (val) 8'h2a: out = 8'h40 ; 8'h1f: out = 8'h20 ; default: out = 8'h04 ; endcase end integer idx; (* ivl_synthesis_off *) initial begin for (idx = 0 ; idx < 256 ; idx = idx + 1) begin val <= idx; #1 ; if (val == 8'h2a) begin if (out !== 8'h40) begin $display("FAILED -- val=%h, out=%h (%b)", val, out, out); $finish; end end else if (val == 8'h1f) begin if (out !== 8'h20) begin $display("FAILED -- val=%h, out=%h (%b)", val, out, out); $finish; end end else if (out !== 8'h04) begin $display("FAILED -- val=%h, out=%h (%b)", val, out, out); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/case5-syn-fail.v000066400000000000000000000022301435245347300214460ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This tests the synthesis of a case statement that has an empty case. */ module main; reg clk, bit, foo; // Synchronous device that toggles whenever enabled by a high bit. always @(posedge clk) case (bit) 1'b0: ; 1'b1: foo <= ~foo; endcase // case(bit) (* ivl_synthesis_off *) always begin #5 clk = 1; #5 clk = 0; end (* ivl_synthesis_off *) initial begin clk = 0; bit = 0; foo = 0; # 6 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 0 || foo !== 0) begin $display("FAILED"); $finish; end #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 0 || foo !== 0) begin $display("FAILED"); $finish; end bit <= 1; #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 1 || foo !== 1) begin $display("FAILED"); $finish; end #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 1 || foo !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/case5.v000066400000000000000000000023271435245347300177350ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This tests the synthesis of a case statement that has an empty case. */ module main; reg clk, bit, foo, clr; // Synchronous device that toggles whenever enabled by a high bit. always @(posedge clk or posedge clr) if (clr) foo = 0; else case (bit) 1'b0: ; 1'b1: foo <= ~foo; endcase // case(bit) (* ivl_synthesis_off *) always begin #5 clk = 1; #5 clk = 0; end (* ivl_synthesis_off *) initial begin clk = 0; bit = 0; clr = 1; # 6 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 0 || foo !== 0) begin $display("FAILED"); $finish; end clr = 0; #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 0 || foo !== 0) begin $display("FAILED"); $finish; end bit <= 1; #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 1 || foo !== 1) begin $display("FAILED"); $finish; end #10 $display("clk=%b, bit=%b, foo=%b", clk, bit, foo); if (bit !== 1 || foo !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/case6.v000066400000000000000000000013371435245347300177360ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This tests the synthesis of a case statement that has an empty case. */ module main; reg bit, foo; // Combinational device that sends 1 or 0 to foo, to follow bit. always @* begin foo = 0; case (bit) 1'b0: ; 1'b1: foo = 1; endcase // case(bit) end (* ivl_synthesis_off *) initial begin bit = 0; # 6 $display("bit=%b, foo=%b", bit, foo); if (bit !== 0 || foo !== 0) begin $display("FAILED"); $finish; end bit <= 1; #10 $display("bit=%b, foo=%b", bit, foo); if (bit !== 1 || foo !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/case7.v000066400000000000000000000017671435245347300177460ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This tests the synthesis of a case statement that has an empty case. */ module main; reg bit, foo, bar; // Combinational device that sends 1 or 0 to foo, to follow bit. // This tests the special situation that the case condition only sets // some of the bits that the case as a whole sets. This is OK if // the bits that are sometimes not set are covered elsewhere. always @* begin foo = 0; bar = 0; case (bit) 1'b0: bar = 1; 1'b1: foo = 1; endcase // case(bit) end (* ivl_synthesis_off *) initial begin bit = 0; # 6 $display("bit=%b, foo=%b, bar=%b", bit, foo, bar); if (bit !== 0 || foo !== 0 || bar !== 1) begin $display("FAILED"); $finish; end bit <= 1; #10 $display("bit=%b, foo=%b, bar=%b", bit, foo, bar); if (bit !== 1 || foo !== 1 || bar !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/case_priority.v000066400000000000000000000007311435245347300216060ustar00rootroot00000000000000`timescale 10ns/1ps module main; logic [1:0] counter = 2'b00; logic clk = 1'b0; initial forever #1 clk <= ~clk; always @(posedge clk) begin counter <= counter + 2'd1; priority case (counter) 2'd0: $display("case 0"); 2'd1: $display("case 1"); 2'd3: $display("case 3"); endcase // priority case (counter) if (counter == 2'd3) begin $display("PASSED"); $finish(0); end end endmodule iverilog-12_0/ivtest/ivltests/case_unique.v000066400000000000000000000007271435245347300212400ustar00rootroot00000000000000`timescale 10ns/1ps module main; logic [1:0] counter = 2'b00; logic clk = 1'b0; initial forever #1 clk <= ~clk; always @(posedge clk) begin counter <= counter + 2'd1; unique case (counter) 2'd0: $display("case 0"); 2'd1: $display("case 1"); 2'd3: $display("case 3"); endcase // priority case (counter) if (counter == 2'd3) begin $display("PASSED"); $finish(0); end end endmodule iverilog-12_0/ivtest/ivltests/case_wo_default.v000066400000000000000000000014551435245347300220620ustar00rootroot00000000000000 module test (output reg [1:0] foo, input wire foo_en1, foo_en2 /* */); always @* begin foo = 0; case (1'b1) foo_en1 : foo = 1; foo_en2 : foo = 2; endcase end endmodule // test module main; wire [1:0] foo; reg foo_en1, foo_en2; test dut (.foo(foo), .foo_en1(foo_en1), .foo_en2(foo_en2)); task fail; begin $display("FAILED -- foo=%b, foo_en1=%b, foo_en2=%b", foo, foo_en1, foo_en2); $finish; end endtask // fail initial begin foo_en1 = 0; foo_en2 = 0; #1 if (foo !== 2'd0) fail; foo_en2 = 1; #1 if (foo !== 2'd2) fail; foo_en1 = 1; #1 if (foo !== 2'd1) fail; foo_en2 = 0; #1 if (foo !== 2'd1) fail; $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/casesynth1.v000066400000000000000000000057431435245347300210240ustar00rootroot00000000000000/* * Copyright (c) 2006 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: casesynth1.v,v 1.1 2006/01/01 01:01:31 stevewilliams Exp $" */ module main; reg clk, rst, set; reg [3:0] out, load; reg [1:0] op; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) if (rst) begin out <= 0; end else if (set) begin out <= load; end else case (op) 2'b01: /* increment */ out <= out + 1; 2'b10: /* decrement */ out <= out - 1; 2'b11: /* Invert */ out <= ~out; /* Other ops cause out to not change. */ endcase // case(mod) (* ivl_synthesis_off *) initial begin /* Test rst behavior. */ op = 2'b00; rst = 1; set = 0; load = 0; clk = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b0000) begin $display("FAILED -- out=%b (reset)", out); $finish; end /* Test set behavior */ rst = 0; set = 1; load = 4'b0100; #1 clk = 1; #1 clk = 0; if (out !== 4'b0100) begin $display("FAILED -- out=%b (load)", out); $finish; end /* Test increment behavior */ op = 2'b01; rst = 0; set = 0; load = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b0101) begin $display("FAILED -- out=%b (increment 1)", out); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b0110) begin $display("FAILED -- out=%b (increment 2)", out); $finish; end /* Test invert behavior */ op = 2'b11; #1 clk = 1; #1 clk = 0; if (out !== 4'b1001) begin $display("FAILED == out=%b (invert)", out); $finish; end /* Test NO-OP behavior */ op = 2'b00; #1 clk = 1; #1 clk = 0; if (out !== 4'b1001) begin $display("FAILED -- out=%b (noop)", out); $finish; end /* Test decrement behavior */ op = 2'b10; #1 clk = 1; #1 clk = 0; if (out !== 4'b1000) begin $display("FAILED -- out=%b (decrement 1)", out); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b0111) begin $display("FAILED -- out=%b (decrement 2)", out); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/casesynth2.v000066400000000000000000000064501435245347300210210ustar00rootroot00000000000000/* * Copyright (c) 2006 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: casesynth2.v,v 1.1 2006/01/01 02:26:18 stevewilliams Exp $" */ module main; reg clk, rst, set; reg [3:0] out, load; reg carry; reg [1:0] op; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) if (rst) begin out <= 0; carry <= 0; end else if (set) begin out <= load; carry <= 0; end else case (op) 2'b01: /* increment */ {carry, out} <= {carry, out} + 1; 2'b10: /* decrement */ {carry, out} <= {carry, out} - 1; 2'b11: /* Invert */ out <= ~out; /* Other ops cause out to not change. */ endcase // case(mod) (* ivl_synthesis_off *) initial begin /* Test rst behavior. */ op = 2'b00; rst = 1; set = 0; load = 0; clk = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b0000 || carry !== 1'b0) begin $display("FAILED -- out=%b, carry=%b (reset)", out, carry); $finish; end /* Test set behavior */ rst = 0; set = 1; load = 4'b1110; #1 clk = 1; #1 clk = 0; if (out !== 4'b1110 || carry !== 1'b0) begin $display("FAILED -- out=%b, carry=%b (load)", out, carry); $finish; end /* Test increment behavior */ op = 2'b01; rst = 0; set = 0; load = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b1111 || carry !== 1'b0) begin $display("FAILED -- out=%b, carry=%b (increment 1)", out, carry); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b0000 || carry !== 1'b1) begin $display("FAILED -- out=%b, carry=%b (increment 2)", out, carry); $finish; end /* Test invert behavior */ op = 2'b11; #1 clk = 1; #1 clk = 0; if (out !== 4'b1111 || carry !== 1'b1) begin $display("FAILED == out=%b, carry=%b (invert)", out, carry); $finish; end /* Test NO-OP behavior */ op = 2'b00; #1 clk = 1; #1 clk = 0; if (out !== 4'b1111 || carry !== 1'b1) begin $display("FAILED -- out=%b, carry=%b (noop)", out, carry); $finish; end /* Test decrement behavior */ op = 2'b10; #1 clk = 1; #1 clk = 0; if (out !== 4'b1110) begin $display("FAILED -- out=%b, carry=%b (decrement 1)", out, carry); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b1101) begin $display("FAILED -- out=%b, carry=%b (decrement 2)", out, carry); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/casesynth3.v000066400000000000000000000061731435245347300210240ustar00rootroot00000000000000/* * Copyright (c) 2006 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: casesynth3.v,v 1.1 2006/01/21 21:53:09 stevewilliams Exp $" */ /* * This case tests the handling very wide (but sparse) case statements. */ module main; reg clk, rst, set; reg [3:0] out, load; reg [10:0] op; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) if (rst) begin out <= 0; end else if (set) begin out <= load; end else case (op) 10'b0000000001: /* increment */ out <= out + 1; 10'b1000000000: /* decrement */ out <= out - 1; 10'b1000000001: /* Invert */ out <= ~out; /* Other ops cause out to not change. */ endcase // case(mod) (* ivl_synthesis_off *) initial begin /* Test rst behavior. */ op = 10'b0000000000; rst = 1; set = 0; load = 0; clk = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b0000) begin $display("FAILED -- out=%b (reset)", out); $finish; end /* Test set behavior */ rst = 0; set = 1; load = 4'b0100; #1 clk = 1; #1 clk = 0; if (out !== 4'b0100) begin $display("FAILED -- out=%b (load)", out); $finish; end /* Test increment behavior */ op = 10'b0000000001; rst = 0; set = 0; load = 0; #1 clk = 1; #1 clk = 0; if (out !== 4'b0101) begin $display("FAILED -- out=%b (increment 1)", out); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b0110) begin $display("FAILED -- out=%b (increment 2)", out); $finish; end /* Test invert behavior */ op = 10'b1000000001; #1 clk = 1; #1 clk = 0; if (out !== 4'b1001) begin $display("FAILED == out=%b (invert)", out); $finish; end /* Test NO-OP behavior */ op = 10'b0000000000; #1 clk = 1; #1 clk = 0; if (out !== 4'b1001) begin $display("FAILED -- out=%b (noop)", out); $finish; end /* Test decrement behavior */ op = 10'b1000000000; #1 clk = 1; #1 clk = 0; if (out !== 4'b1000) begin $display("FAILED -- out=%b (decrement 1)", out); $finish; end #1 clk = 1; #1 clk = 0; if (out !== 4'b0111) begin $display("FAILED -- out=%b (decrement 2)", out); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/casesynth4.v000066400000000000000000000021001435245347300210070ustar00rootroot00000000000000 module test (output reg a, output reg b, input wire [1:0] sel, input wire d /* */); always @* begin b = d; case (sel) 0: begin a = 0; b = 1; end 1: begin a = 1; b = 0; end default: begin a = d; end endcase // case (sel) end // always @ * endmodule // test module main; reg [1:0] sel; reg d; wire a, b; test dut (.a(a), .b(b), .sel(sel), .d(d)); initial begin d = 0; sel = 0; #1 if (a!==0 || b!==1) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end sel = 1; #1 if (a!==1 || b!==0) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end sel = 2; #1 if (a!==0 || b!==0) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end d = 1; #1 if (a!==1 || b!==1) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/casesynth5.v000066400000000000000000000021431435245347300210170ustar00rootroot00000000000000 module test (output reg a, output reg b, input wire [1:0] sel, input wire d /* */); always @* begin b = d; case (sel) 0: begin a = 0; b = 1; end 1: begin a = 1; //b = 0; // Pick up input from d instead. end default: begin a = d; end endcase // case (sel) end // always @ * endmodule // test module main; reg [1:0] sel; reg d; wire a, b; test dut (.a(a), .b(b), .sel(sel), .d(d)); initial begin d = 0; sel = 0; #1 if (a!==0 || b!==1) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end sel = 1; #1 if (a!==1 || b!==0) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end sel = 2; #1 if (a!==0 || b!==0) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end d = 1; #1 if (a!==1 || b!==1) begin $display("FAILED -- sel=%b, d=%b, a=%b, b=%b", sel, d, a, b); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/casesynth6.v000066400000000000000000000052031435245347300210200ustar00rootroot00000000000000 module test (output reg [4:0] q, input wire [31:0] sel /* */); always @* begin casez (sel) 32'b1zzz_zzzz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd0; 32'b01zz_zzzz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd1; 32'b001z_zzzz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd2; 32'b0001_zzzz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd3; 32'b0000_1zzz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd4; 32'b0000_01zz_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd5; 32'b0000_001z_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd6; 32'b0000_0001_zzzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd7; 32'b0000_0000_1zzz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd8; 32'b0000_0000_01zz_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd9; 32'b0000_0000_001z_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd10; 32'b0000_0000_0001_zzzz__zzzz_zzzz_zzzz_zzzz: q = 5'd11; 32'b0000_0000_0000_1zzz__zzzz_zzzz_zzzz_zzzz: q = 5'd12; 32'b0000_0000_0000_01zz__zzzz_zzzz_zzzz_zzzz: q = 5'd13; 32'b0000_0000_0000_001z__zzzz_zzzz_zzzz_zzzz: q = 5'd14; 32'b0000_0000_0000_0001__zzzz_zzzz_zzzz_zzzz: q = 5'd15; 32'b0000_0000_0000_0000__1zzz_zzzz_zzzz_zzzz: q = 5'd16; 32'b0000_0000_0000_0000__01zz_zzzz_zzzz_zzzz: q = 5'd17; 32'b0000_0000_0000_0000__001z_zzzz_zzzz_zzzz: q = 5'd18; 32'b0000_0000_0000_0000__0001_zzzz_zzzz_zzzz: q = 5'd19; 32'b0000_0000_0000_0000__0000_1zzz_zzzz_zzzz: q = 5'd20; 32'b0000_0000_0000_0000__0000_01zz_zzzz_zzzz: q = 5'd21; 32'b0000_0000_0000_0000__0000_001z_zzzz_zzzz: q = 5'd22; 32'b0000_0000_0000_0000__0000_0001_zzzz_zzzz: q = 5'd23; 32'b0000_0000_0000_0000__0000_0000_1zzz_zzzz: q = 5'd24; 32'b0000_0000_0000_0000__0000_0000_01zz_zzzz: q = 5'd25; 32'b0000_0000_0000_0000__0000_0000_001z_zzzz: q = 5'd26; 32'b0000_0000_0000_0000__0000_0000_0001_zzzz: q = 5'd27; 32'b0000_0000_0000_0000__0000_0000_0000_1zzz: q = 5'd28; 32'b0000_0000_0000_0000__0000_0000_0000_01zz: q = 5'd29; 32'b0000_0000_0000_0000__0000_0000_0000_001z: q = 5'd30; 32'b0000_0000_0000_0000__0000_0000_0000_0001: q = 5'd31; default: q = 5'd0; endcase end // always @ * endmodule // test module main; reg [31:0] sel; wire [4:0] q; test dut (.q(q), .sel(sel)); integer idx; integer rept; reg [31:0] mask, setb; initial begin sel = 0; #1 if (q !== 5'd0) begin $display("FAILED -- sel=%b, q=%b", sel, q); $finish; end for (idx = 0 ; idx < 32 ; idx = idx+1) begin mask = 32'h7fff_ffff >> idx; setb = mask + 32'd1; for (rept = 0 ; rept < 4 ; rept = rept+1) begin sel = setb | (mask & $random); #1 if (q !== idx[4:0]) begin $display("FAILED -- sel=%b, q=%b, idx=%0d", sel, q, idx); $finish; end end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/casesynth7.v000066400000000000000000000011351435245347300210210ustar00rootroot00000000000000// Incomplete case statements in asynchronous logic are dangerous in // synthesisable code, as in real hardware the inferred latch will be // sensitive to glitches as the case select value changes. Check that // the compiler outputs a warning for this. module mux( input wire [2:0] sel, input wire [2:0] i1, input wire [2:0] i2, input wire [2:0] i3, input wire [2:0] i4, output reg [2:0] o ); (* ivl_synthesis_on *) always @* begin case (sel) 0 : o = 0; 1 : o = i1; 2 : o = i2; 3 : o = i3; 4 : o = i4; endcase end (* ivl_synthesis_off *) initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/casesynth8.v000066400000000000000000000011361435245347300210230ustar00rootroot00000000000000// We don't (currently) support a case statement where both the case select // and one or more case items are variables in asynchronous logic synthesis. // Check the compiler handles and rejects this code. module mux( input wire [2:0] sel, input wire [2:0] i1, input wire [2:0] i2, input wire [2:0] i3, input wire [2:0] i4, input wire [2:0] i5, output reg [2:0] o ); (* ivl_synthesis_on *) always @* begin case (sel) 0 : o = 0; 1 : o = i1; 2 : o = i2; 3 : o = i3; i5 : o = i4; default: o = 3'bx; endcase end (* ivl_synthesis_off *) initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/casesynth9.v000066400000000000000000000012411435245347300210210ustar00rootroot00000000000000module mux( input wire [1:0] sel, input wire [2:0] i0, input wire [2:0] i1, input wire [2:0] i2, input wire [2:0] i3, input wire [2:0] i4, output reg [2:0] o ); always @* begin case (sel) 0 : o = i0; 1 : o = i1; 2 : o = i2; 3 : o = i3; 2 : o = i4; endcase end endmodule module test(); reg [1:0] sel; wire [2:0] out; mux mux(sel, 3'd0, 3'd1, 3'd2, 3'd3, 3'd4, out); reg failed; (* ivl_synthesis_off *) initial begin failed = 0; sel = 0; repeat (4) begin #1 $display("%d : %b", sel, out); if (out !== sel) failed = 1; sel = sel + 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/casex3.9A.v000066400000000000000000000032401435245347300203660ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casex/endcase w/ known labels - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casex (val1 & val2 ) 3'b000: result = 0; 3'b001: result = 1 ; 3'b010: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; if(result !=0) begin $display("FAILED case 3.9A - case (expr) lab1: "); error = 1; end val1 = 3'b001; val2 = 3'b011; if(result !=1) begin $display("FAILED case 3.9A - case (expr) lab2: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED case 3.9A - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casex3.9B.v000066400000000000000000000033061435245347300203720ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casex/endcase X in case(expr) - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casex (val1 & val2 ) 3'b000: result = 0; 3'b001: result = 1 ; 3'b010: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0x0; if(result !=0) begin $display("FAILED case 3.9B - casex (expr contains x) lab1: "); error = 1; end val1 = 3'b001; val2 = 3'b0x1; if(result !=1) begin $display("FAILED case 3.9B - casex (expr contains x) lab2: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED case 3.9B - casex (expr contains x) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casex3.9C.v000066400000000000000000000032131435245347300203700ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casex/endcase - label w/ X no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casex (val1 & val2 ) 3'b000: result = 0; 3'b0x1: result = 1 ; 3'b010: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; if(result !=0) begin $display("FAILED casex 3.9C - label w/ x: "); error = 1; end val1 = 3'b001; val2 = 3'b011; if(result !=1) begin $display("FAILED casex 3.9C - label w/ x: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED casex 3.9C - label w/ x "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casex3.9D.v000066400000000000000000000032641435245347300203770ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casex/endcase w/ null_statement - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casex (val1 & val2 ) 3'b000,3'b001: result = 0; 3'b10x: ; 3'b001: result = 1; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; if(result !=0) begin $display("FAILED casex 3.9D - lab w/ null expr: "); error = 1; end val1 = 3'b001; val2 = 3'b011; if(result !=1) begin $display("FAILED casex 3.9D - lab w/ null expr: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b010 val2 = 3'b010; if(result !=1) begin $display("FAILED casex 3.9D - lab w/ null expr: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casex3.9E.v000066400000000000000000000032711435245347300203760ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casex/endcase w/ null_statement as default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casex (val1 & val2 ) 3'b000,3'b001: result = 0; 3'b11x: result = 2; 3'b001: result = 1; default result = 3; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; if(result !=0) begin $display("FAILED casex 3.9E - default: "); error = 1; end val1 = 3'b001; val2 = 3'b011; if(result !=1) begin $display("FAILED casex 3.9E - default: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b010 val2 = 3'b010; if(result !=3) begin $display("FAILED casex 3.9E - default: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casex_synth.v000066400000000000000000000015201435245347300212570ustar00rootroot00000000000000/* */ module main; reg [1:0] sel, in; reg [1:0] out; (* ivl_combinational *) always @* casex (sel) 2'b0?: out = 2'b10; 2'b10: out = in[0]; 2'b11: out = in[1]; endcase // casex(sel) (* ivl_synthesis_off *) initial begin in = 2'b10; sel = 0; #1 if (out !== 2'b10) begin $display("FAILED -- sel=%b, out=%b", sel, out); $finish; end sel = 1; #1 if (out !== 2'b10) begin $display("FAILED -- sel=%b, out=%b", sel, out); $finish; end sel = 2; #1 if (out !== 2'b00) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end sel = 3; #1 if (out !== 2'b01) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casez3.10A.v000066400000000000000000000032461435245347300204460ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casez/endcase w/ known labels - no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 or val2) casez (val1 & val2 ) 3'b000: result = 0; 3'b001: result = 1 ; 3'b010: result = 2; endcase initial begin error = 0; val1 = 3'b0; val2 = 3'b0; if(result !=0) begin $display("FAILED casez 3.10A - case (expr) lab1: "); error = 1; end val1 = 3'b001; val2 = 3'b011; if(result !=1) begin $display("FAILED casez 3.10A - case (expr) lab2: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED casez 3.10A - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casez3.10B.v000066400000000000000000000031601435245347300204420ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casez/endcase w/ z in expr no default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 ) casez (val1) 3'b000: result = 0; 3'b010: result = 1 ; 3'b110: result = 2; endcase initial begin error = 0; val1 = 3'b0z0 ; if(result !=0) begin $display("FAILED casez 3.10B - case (expr) lab1: "); error = 1; end val1 = 3'b01z; if(result !=1) begin $display("FAILED casez 3.10B - case (expr) lab2: "); error = 1; end val1 = 3'b111; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED casez 3.10B - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casez3.10C.v000066400000000000000000000032021435245347300204400ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casez/endcase w/ z in label - no match case module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 ) casez (val1) 5'b0000z: result = 0; 5'b001z0: result = 1 ; 5'b01zz0: result = 2; endcase initial begin error = 0; val1 = 5'b0000z ; if(result !=0) begin $display("FAILED casez 3.10C - case (expr) lab1: "); error = 1; end val1 = 5'b001z0; if(result !=1) begin $display("FAILED casez 3.10C - case (expr) lab2: "); error = 1; end val1 = 5'b1zzzz; // Should get no-action - expr = 3'b011 if(result !=1) begin $display("FAILED casez 3.10C - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casez3.10D.v000066400000000000000000000032121435245347300204420ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casez/endcase w/ default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 ) casez (val1) 5'b0000z: result = 0; 5'b001z0: result = 1 ; 5'b01zz0: result = 2; default: result = 4; endcase initial begin error = 0; val1 = 5'b0000z ; if(result !=0) begin $display("FAILED casez 3.10D - case (expr) lab1: "); error = 1; end val1 = 5'b001z0; if(result !=1) begin $display("FAILED casez 3.10D - case (expr) lab2: "); error = 1; end val1 = 5'b1zzzz; // Should get no-action - expr = 3'b011 if(result !=4) begin $display("FAILED casez 3.10D - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/casez3.10E.v000066400000000000000000000032121435245347300204430ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate casez/endcase w/ default module main (); reg error; reg [2:0] val1,val2; reg [2:0] result ; always @( val1 ) casez (val1) 5'b0000z: result = 0; 5'b001?0: result = 1 ; 5'b01?z0: result = 2; default: result = 4; endcase initial begin error = 0; val1 = 5'b0000z ; if(result !=0) begin $display("FAILED casez 3.10D - case (expr) lab1: "); error = 1; end val1 = 5'b001z0; if(result !=1) begin $display("FAILED casez 3.10D - case (expr) lab2: "); error = 1; end val1 = 5'b1zzzz; // Should get no-action - expr = 3'b011 if(result !=4) begin $display("FAILED casez 3.10D - case (expr) lab1: "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/cast_int.v000066400000000000000000000044411435245347300205400ustar00rootroot00000000000000module top; reg pass = 1'b1; real in, bin; wire [7:0] out = in; wire signed [34:0] big = bin; initial begin // $monitor(in,, out,, bin,, big); bin = 8589934592.5; // 2**33+0.5 overflows a 32 bit long. #1; if (big !== 35'sd8589934593) begin $display("Failed: multiword check, expected 8589934593, got %d", big); pass = 1'b0; end if (out !== 'b0) begin $display("Failed: initial value, expected 8'b0, got %b", out); pass = 1'b0; end in = 0.499999; bin = -25.5; // This test a different branch (small result -> big vec.). #1; if (big !== -26) begin $display("Failed: small value multiword check, expected -26, got %d", out); pass = 1'b0; end if (out !== 8'b0) begin $display("Failed: rounding value (down, +), expected 8'b0, got %b", out); pass = 1'b0; end in = -0.499999; #1; if (out !== 8'b0) begin $display("Failed: rounding value (down, -), expected 8'b0, got %b", out); pass = 1'b0; end in = 0.5; #1; if (out !== 8'b01) begin $display("Failed: rounding value (up, +), expected 8'b01, got %b", out); pass = 1'b0; end in = -0.5; #1; if (out !== 8'b11111111) begin $display("Failed: rounding value (up, -), expected 8'b11111111, got %b", out); pass = 1'b0; end in = 256.0; #1; if (out !== 8'b0) begin $display("Failed: overflow expected 8'b0, got %b", out); pass = 1'b0; end in = 511.0; #1; if (out !== 8'b11111111) begin $display("Failed: pruning expected 8'b11111111, got %b", out); pass = 1'b0; end in = 1.0/0.0; #1; if (out !== 8'bxxxxxxxx) begin $display("Failed: +inf expected 8'bxxxxxxxx, got %b", out); pass = 1'b0; end in = -1.0/0.0; #1; if (out !== 8'bxxxxxxxx) begin $display("Failed: -inf expected 8'bxxxxxxxx, got %b", out); pass = 1'b0; end in = $sqrt(-1.0); #1; if (out !== 8'bxxxxxxxx) begin $display("Failed: nan expected 8'bxxxxxxxx, got %b", out); pass = 1'b0; end in = 8589934720.5; #1; if (out !== 129) begin $display("Failed: overflow value expected 129, got %d", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cast_int_ams.v000066400000000000000000000004731435245347300214010ustar00rootroot00000000000000module top; reg pass = 1'b1; real in; wire [7:0] out = in; initial begin // $monitor(in,, out); in = sqrt(-1.0); #1; if (out !== 8'bxxxxxxxx) begin $display("Failed: nan expected 8'bxxxxxxxx, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cast_real.v000066400000000000000000000033271435245347300206730ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test casting integers to real module cast_real(); int i; logic [3:0] l; logic signed [3:0] sl; real a, b, c, d, e; initial begin // Initalization using an integer variable i = 5; a = real'(i); // ..and logic l = 4'b1010; b = real'(l); sl = 4'b1010; c = real'(sl); // Initialization using an integer constant d = real'(11); e = real'(-7); if (a != 5.0) begin $display("FAILED #1 a = %f", a); $finish(); end if (b != 10.0) begin $display("FAILED #2 b = %f", b); $finish(); end if (c != -6.0) begin $display("FAILED #3 c = %f", c); $finish(); end if (d != 11.0) begin $display("FAILED #4 d = %f", d); $finish(); end if (e != -7.0) begin $display("FAILED #5 e = %f", e); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cast_real_signed.v000066400000000000000000000013071435245347300222200ustar00rootroot00000000000000module top; reg pass = 1'b1; reg signed [7:0] in; wire real out = in; initial begin // $monitor(in,, out); #1; if (out != 0.0) begin $display("Failed: initial value, expected 0.0, got %g", out); pass = 1'b0; end in = 0; #1; if (out != 0.0) begin $display("Failed: 0 value, expected 0.0, got %g", out); pass = 1'b0; end in = 1; #1; if (out != 1.0) begin $display("Failed: 1 value, expected 1.0, got %g", out); pass = 1'b0; end in = -1; #1; if (out != -1.0) begin $display("Failed: -1 value, expected -1.0, got %g", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cast_real_unsigned.v000066400000000000000000000013031435245347300225570ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [7:0] in; wire real out = in; initial begin // $monitor(in,, out); #1; if (out != 0.0) begin $display("Failed: initial value, expected 0.0, got %g", out); pass = 1'b0; end in = 0; #1; if (out != 0.0) begin $display("Failed: 0 value, expected 0.0, got %g", out); pass = 1'b0; end in = 1; #1; if (out != 1.0) begin $display("Failed: 1 value, expected 1.0, got %g", out); pass = 1'b0; end in = -1; #1; if (out != 255.0) begin $display("Failed: -1 value, expected -255.0, got %g", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cfunc_assign_op_mixed.v000066400000000000000000000047701435245347300232670ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_REAL_MODULUS_IN_IVTEST `endif module test(); function integer add2(input integer x); begin x += 2.0; add2 = x; end endfunction function integer sub2(input integer x); begin x -= 2.0; sub2 = x; end endfunction function integer mul2(input integer x); begin x *= 2.0; mul2 = x; end endfunction function integer div2(input integer x); begin x /= 2.0; div2 = x; end endfunction function integer mod2(input integer x); begin `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST x %= 2.0; `else x %= 2; `endif mod2 = x; end endfunction localparam add2_5 = add2(5); localparam sub2_5 = sub2(5); localparam mul2_5 = mul2(5); localparam div2_5 = div2(5); localparam mod2_5 = mod2(5); function integer add3(input integer x); begin add3 = x; add3 += 3.0; end endfunction function integer sub3(input integer x); begin sub3 = x; sub3 -= 3.0; end endfunction function integer mul3(input integer x); begin mul3 = x; mul3 *= 3.0; end endfunction function integer div3(input integer x); begin div3 = x; div3 /= 3.0; end endfunction function integer mod3(input integer x); begin mod3 = x; `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST mod3 %= 3.0; `else mod3 %= 3; `endif end endfunction localparam add3_5 = add3(5); localparam sub3_5 = sub3(5); localparam mul3_5 = mul3(5); localparam div3_5 = div3(5); localparam mod3_5 = mod3(5); reg failed = 0; initial begin $display("add2_5 = %0f", add2_5); if (add2_5 != add2(5)) failed = 1; if (add2_5 != 7) failed = 1; $display("sub2_5 = %0f", sub2_5); if (sub2_5 != sub2(5)) failed = 1; if (sub2_5 != 3) failed = 1; $display("mul2_5 = %0f", mul2_5); if (mul2_5 != mul2(5)) failed = 1; if (mul2_5 != 10) failed = 1; $display("div2_5 = %0f", div2_5); if (div2_5 != div2(5)) failed = 1; if (div2_5 != 2) failed = 1; $display("mod2_5 = %0f", mod2_5); if (mod2_5 != mod2(5)) failed = 1; if (mod2_5 != 1) failed = 1; $display("add3_5 = %0f", add3_5); if (add3_5 != add3(5)) failed = 1; if (add3_5 != 8) failed = 1; $display("sub3_5 = %0f", sub3_5); if (sub3_5 != sub3(5)) failed = 1; if (sub3_5 != 2) failed = 1; $display("mul3_5 = %0f", mul3_5); if (mul3_5 != mul3(5)) failed = 1; if (mul3_5 != 15) failed = 1; $display("div3_5 = %0f", div3_5); if (div3_5 != div3(5)) failed = 1; if (div3_5 != 1) failed = 1; $display("mod3_5 = %0f", mod3_5); if (mod3_5 != mod3(5)) failed = 1; if (mod3_5 != 2) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cfunc_assign_op_pv.v000066400000000000000000000176141435245347300226070ustar00rootroot00000000000000module test(); function [31:0] pre_inc(input [31:0] x); begin ++x[23:8]; pre_inc = x; end endfunction function [31:0] pre_dec(input [31:0] x); begin --x[23:8]; pre_dec = x; end endfunction function [31:0] post_inc(input [31:0] x); begin x[23:8]++; post_inc = x; end endfunction function [31:0] post_dec(input [31:0] x); begin x[23:8]--; post_dec = x; end endfunction localparam pre_inc_5 = pre_inc({8'h55, 16'd5, 8'haa}); localparam pre_dec_5 = pre_dec({8'h55, 16'd5, 8'haa}); localparam post_inc_5 = post_inc({8'h55, 16'd5, 8'haa}); localparam post_dec_5 = post_dec({8'h55, 16'd5, 8'haa}); function [31:0] add2(input [31:0] x); begin x[23:8] += 2; add2 = x; end endfunction function [31:0] sub2(input [31:0] x); begin x[23:8] -= 2; sub2 = x; end endfunction function [31:0] mul2(input [31:0] x); begin x[23:8] *= 2; mul2 = x; end endfunction function [31:0] div2(input [31:0] x); begin x[23:8] /= 2; div2 = x; end endfunction function [31:0] mod2(input [31:0] x); begin x[23:8] %= 2; mod2 = x; end endfunction function [31:0] and6(input [31:0] x); begin x[23:8] &= 16'h6666; and6 = x; end endfunction function [31:0] or6(input [31:0] x); begin x[23:8] |= 16'h6666; or6 = x; end endfunction function [31:0] xor6(input [31:0] x); begin x[23:8] ^= 16'h6666; xor6 = x; end endfunction function [31:0] lsl2(input [31:0] x); begin x[23:8] <<= 2; lsl2 = x; end endfunction function [31:0] lsr2(input [31:0] x); begin x[23:8] >>= 2; lsr2 = x; end endfunction function [31:0] asl2(input [31:0] x); begin x[23:8] <<<= 2; asl2 = x; end endfunction function [31:0] asr2(input [31:0] x); begin x[23:8] >>>= 2; asr2 = x; end endfunction localparam add2_5 = add2({8'h55, 16'd5, 8'haa}); localparam sub2_5 = sub2({8'h55, 16'd5, 8'haa}); localparam mul2_5 = mul2({8'h55, 16'd5, 8'haa}); localparam div2_5 = div2({8'h55, 16'd5, 8'haa}); localparam mod2_5 = mod2({8'h55, 16'd5, 8'haa}); localparam and6_f = and6(32'h55ffffaa); localparam or6_0 = or6(32'h550000aa); localparam xor6_f = xor6(32'h55ffffaa); localparam lsl2_p25 = lsl2({8'h55, 16'sd25, 8'haa}); localparam lsr2_m25 = lsr2({8'h55, -16'sd25, 8'haa}); localparam asl2_m25 = asl2({8'h55, -16'sd25, 8'haa}); localparam asr2_m25 = asr2({8'h55, -16'sd25, 8'haa}); function [31:0] add3(input [31:0] x); begin add3 = x; add3[23:8] += 3; end endfunction function [31:0] sub3(input [31:0] x); begin sub3 = x; sub3[23:8] -= 3; end endfunction function [31:0] mul3(input [31:0] x); begin mul3 = x; mul3[23:8] *= 3; end endfunction function [31:0] div3(input [31:0] x); begin div3 = x; div3[23:8] /= 3; end endfunction function [31:0] mod3(input [31:0] x); begin mod3 = x; mod3[23:8] %= 3; end endfunction function [31:0] and9(input [31:0] x); begin and9 = x; and9[23:8] &= 16'h9999; end endfunction function [31:0] or9(input [31:0] x); begin or9 = x; or9[23:8] |= 16'h9999; end endfunction function [31:0] xor9(input [31:0] x); begin xor9 = x; xor9[23:8] ^= 16'h9999; end endfunction function [31:0] lsl3(input [31:0] x); begin lsl3 = x; lsl3[23:8] <<= 3; end endfunction function [31:0] lsr3(input [31:0] x); begin lsr3 = x; lsr3[23:8] >>= 3; end endfunction function [31:0] asl3(input [31:0] x); begin asl3 = x; asl3[23:8] <<<= 3; end endfunction function [31:0] asr3(input [31:0] x); begin asr3 = x; asr3[23:8] >>>= 3; end endfunction localparam add3_5 = add3({8'h55, 16'd5, 8'haa}); localparam sub3_5 = sub3({8'h55, 16'd5, 8'haa}); localparam mul3_5 = mul3({8'h55, 16'd5, 8'haa}); localparam div3_5 = div3({8'h55, 16'd5, 8'haa}); localparam mod3_5 = mod3({8'h55, 16'd5, 8'haa}); localparam and9_f = and9(32'h55ffffaa); localparam or9_0 = or9(32'h550000aa); localparam xor9_f = xor9(32'h55ffffaa); localparam lsl3_p25 = lsl3({8'h55, 16'sd25, 8'haa}); localparam lsr3_m25 = lsr3({8'h55, -16'sd25, 8'haa}); localparam asl3_m25 = asl3({8'h55, -16'sd25, 8'haa}); localparam asr3_m25 = asr3({8'h55, -16'sd25, 8'haa}); reg failed = 0; initial begin $display("pre_inc_5 = %0h", pre_inc_5); if (pre_inc_5 !== pre_inc({8'h55, 16'd5, 8'haa})) failed = 1; if (pre_inc_5 !== 32'h550006aa) failed = 1; $display("pre_dec_5 = %0h", pre_dec_5); if (pre_dec_5 !== pre_dec({8'h55, 16'd5, 8'haa})) failed = 1; if (pre_dec_5 !== 32'h550004aa) failed = 1; $display("post_inc_5 = %0h", post_inc_5); if (post_inc_5 !== post_inc({8'h55, 16'd5, 8'haa})) failed = 1; if (post_inc_5 !== 32'h550006aa) failed = 1; $display("post_dec_5 = %0h", post_dec_5); if (post_dec_5 !== post_dec({8'h55, 16'd5, 8'haa})) failed = 1; if (post_dec_5 !== 32'h550004aa) failed = 1; $display("add2_5 = %0h", add2_5); if (add2_5 !== add2({8'h55, 16'd5, 8'haa})) failed = 1; if (add2_5 !== 32'h550007aa) failed = 1; $display("sub2_5 = %0h", sub2_5); if (sub2_5 !== sub2({8'h55, 16'd5, 8'haa})) failed = 1; if (sub2_5 !== 32'h550003aa) failed = 1; $display("mul2_5 = %0h", mul2_5); if (mul2_5 !== mul2({8'h55, 16'd5, 8'haa})) failed = 1; if (mul2_5 !== 32'h55000aaa) failed = 1; $display("div2_5 = %0h", div2_5); if (div2_5 !== div2({8'h55, 16'd5, 8'haa})) failed = 1; if (div2_5 !== 32'h550002aa) failed = 1; $display("mod2_5 = %0h", mod2_5); if (mod2_5 !== mod2({8'h55, 16'd5, 8'haa})) failed = 1; if (mod2_5 !== 32'h550001aa) failed = 1; $display("and6_f = %h", and6_f); if (and6_f !== and6(32'h55ffffaa)) failed = 1; if (and6_f !== 32'h556666aa) failed = 1; $display(" or6_0 = %h", or6_0); if (or6_0 !== or6(32'h550000aa)) failed = 1; if (or6_0 !== 32'h556666aa) failed = 1; $display("xor6_f = %h", xor6_f); if (xor6_f !== xor6(32'h55ffffaa)) failed = 1; if (xor6_f !== 32'h559999aa) failed = 1; $display("lsl2_p25 = %0h", lsl2_p25); if (lsl2_p25 !== lsl2({8'h55, 16'sd25, 8'haa})) failed = 1; if (lsl2_p25 !== 32'h550064aa) failed = 1; $display("lsr2_m25 = %0h", lsr2_m25); if (lsr2_m25 !== lsr2({8'h55, -16'sd25, 8'haa})) failed = 1; if (lsr2_m25 !== 32'h553ff9aa) failed = 1; $display("asl2_m25 = %0h", asl2_m25); if (asl2_m25 !== asl2({8'h55, -16'sd25, 8'haa})) failed = 1; if (asl2_m25 !== 32'h55ff9caa) failed = 1; $display("asr2_m25 = %0h", asr2_m25); if (asr2_m25 !== asr2({8'h55, -16'sd25, 8'haa})) failed = 1; if (asr2_m25 !== 32'h553ff9aa) failed = 1; $display("add3_5 = %0h", add3_5); if (add3_5 !== add3({8'h55, 16'd5, 8'haa})) failed = 1; if (add3_5 !== 32'h550008aa) failed = 1; $display("sub3_5 = %0h", sub3_5); if (sub3_5 !== sub3({8'h55, 16'd5, 8'haa})) failed = 1; if (sub3_5 !== 32'h550002aa) failed = 1; $display("mul3_5 = %0h", mul3_5); if (mul3_5 !== mul3({8'h55, 16'd5, 8'haa})) failed = 1; if (mul3_5 !== 32'h55000faa) failed = 1; $display("div3_5 = %0h", div3_5); if (div3_5 !== div3({8'h55, 16'd5, 8'haa})) failed = 1; if (div3_5 !== 32'h550001aa) failed = 1; $display("mod3_5 = %0h", mod3_5); if (mod3_5 !== mod3({8'h55, 16'd5, 8'haa})) failed = 1; if (mod3_5 !== 32'h550002aa) failed = 1; $display("and9_f = %h", and9_f); if (and9_f !== and9(32'h55ffffaa)) failed = 1; if (and9_f !== 32'h559999aa) failed = 1; $display(" or9_0 = %h", or9_0); if (or9_0 !== or9(32'h550000aa)) failed = 1; if (or9_0 !== 32'h559999aa) failed = 1; $display("xor9_f = %h", xor9_f); if (xor9_f !== xor9(32'h55ffffaa)) failed = 1; if (xor9_f !== 32'h556666aa) failed = 1; $display("lsl3_p25 = %0h", lsl3_p25); if (lsl3_p25 !== lsl3({8'h55, 16'sd25, 8'haa})) failed = 1; if (lsl3_p25 !== 32'h5500c8aa) failed = 1; $display("lsr3_m25 = %0h", lsr3_m25); if (lsr3_m25 !== lsr3({8'h55, -16'sd25, 8'haa})) failed = 1; if (lsr3_m25 !== 32'h551ffcaa) failed = 1; $display("asl3_m25 = %0h", asl3_m25); if (asl3_m25 !== asl3({8'h55, -16'sd25, 8'haa})) failed = 1; if (asl3_m25 !== 32'h55ff38aa) failed = 1; $display("asr3_m25 = %0h", asr3_m25); if (asr3_m25 !== asr3({8'h55, -16'sd25, 8'haa})) failed = 1; if (asr3_m25 !== 32'h551ffcaa) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cfunc_assign_op_real.v000066400000000000000000000070361435245347300231020ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_REAL_MODULUS_IN_IVTEST `endif module test(); function real pre_inc(input real x); begin ++x; pre_inc = x; end endfunction function real pre_dec(input real x); begin --x; pre_dec = x; end endfunction function real post_inc(input real x); begin x++; post_inc = x; end endfunction function real post_dec(input real x); begin x--; post_dec = x; end endfunction localparam pre_inc_5 = pre_inc(5); localparam pre_dec_5 = pre_dec(5); localparam post_inc_5 = post_inc(5); localparam post_dec_5 = post_dec(5); function real add2(input real x); begin x += 2; add2 = x; end endfunction function real sub2(input real x); begin x -= 2; sub2 = x; end endfunction function real mul2(input real x); begin x *= 2; mul2 = x; end endfunction function real div2(input real x); begin x /= 2; div2 = x; end endfunction `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST function real mod2(input real x); begin x %= 2; mod2 = x; end endfunction `endif localparam add2_5 = add2(5); localparam sub2_5 = sub2(5); localparam mul2_5 = mul2(5); localparam div2_5 = div2(5); `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST localparam mod2_5 = mod2(5); `endif function real add3(input real x); begin add3 = x; add3 += 3; end endfunction function real sub3(input real x); begin sub3 = x; sub3 -= 3; end endfunction function real mul3(input real x); begin mul3 = x; mul3 *= 3; end endfunction function real div4(input real x); begin div4 = x; div4 /= 4; end endfunction `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST function real mod3(input real x); begin mod3 = x; mod3 %= 3; end endfunction `endif localparam add3_5 = add3(5); localparam sub3_5 = sub3(5); localparam mul3_5 = mul3(5); localparam div4_5 = div4(5); `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST localparam mod3_5 = mod3(5); `endif reg failed = 0; initial begin $display("pre_inc_5 = %0f", pre_inc_5); if (pre_inc_5 != pre_inc(5)) failed = 1; if (pre_inc_5 != 6.0) failed = 1; $display("pre_dec_5 = %0f", pre_dec_5); if (pre_dec_5 != pre_dec(5)) failed = 1; if (pre_dec_5 != 4.0) failed = 1; $display("post_inc_5 = %0f", post_inc_5); if (post_inc_5 != post_inc(5)) failed = 1; if (post_inc_5 != 6.0) failed = 1; $display("post_dec_5 = %0f", post_dec_5); if (post_dec_5 != post_dec(5)) failed = 1; if (post_dec_5 != 4.0) failed = 1; $display("add2_5 = %0f", add2_5); if (add2_5 != add2(5)) failed = 1; if (add2_5 != 7.0) failed = 1; $display("sub2_5 = %0f", sub2_5); if (sub2_5 != sub2(5)) failed = 1; if (sub2_5 != 3.0) failed = 1; $display("mul2_5 = %0f", mul2_5); if (mul2_5 != mul2(5)) failed = 1; if (mul2_5 != 10.0) failed = 1; $display("div2_5 = %0f", div2_5); if (div2_5 != div2(5)) failed = 1; if (div2_5 != 2.5) failed = 1; `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST $display("mod2_5 = %0f", mod2_5); if (mod2_5 != mod2(5)) failed = 1; if (mod2_5 != 1.0) failed = 1; `endif $display("add3_5 = %0f", add3_5); if (add3_5 != add3(5)) failed = 1; if (add3_5 != 8.0) failed = 1; $display("sub3_5 = %0f", sub3_5); if (sub3_5 != sub3(5)) failed = 1; if (sub3_5 != 2.0) failed = 1; $display("mul3_5 = %0f", mul3_5); if (mul3_5 != mul3(5)) failed = 1; if (mul3_5 != 15.0) failed = 1; $display("div4_5 = %0f", div4_5); if (div4_5 != div4(5)) failed = 1; if (div4_5 != 1.25) failed = 1; `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST $display("mod3_5 = %0f", mod3_5); if (mod3_5 != mod3(5)) failed = 1; if (mod3_5 != 2.0) failed = 1; `endif if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cfunc_assign_op_vec.v000066400000000000000000000150141435245347300227270ustar00rootroot00000000000000module test(); function integer pre_inc(input integer x); begin ++x; pre_inc = x; end endfunction function integer pre_dec(input integer x); begin --x; pre_dec = x; end endfunction function integer post_inc(input integer x); begin x++; post_inc = x; end endfunction function integer post_dec(input integer x); begin x--; post_dec = x; end endfunction localparam pre_inc_5 = pre_inc(5); localparam pre_dec_5 = pre_dec(5); localparam post_inc_5 = post_inc(5); localparam post_dec_5 = post_dec(5); function integer add2(input integer x); begin x += 2; add2 = x; end endfunction function integer sub2(input integer x); begin x -= 2; sub2 = x; end endfunction function integer mul2(input integer x); begin x *= 2; mul2 = x; end endfunction function integer div2(input integer x); begin x /= 2; div2 = x; end endfunction function integer mod2(input integer x); begin x %= 2; mod2 = x; end endfunction function [3:0] and6(input [3:0] x); begin x &= 4'h6; and6 = x; end endfunction function [3:0] or6(input [3:0] x); begin x |= 4'h6; or6 = x; end endfunction function [3:0] xor6(input [3:0] x); begin x ^= 4'h6; xor6 = x; end endfunction function integer lsl2(input integer x); begin x <<= 2; lsl2 = x; end endfunction function integer lsr2(input integer x); begin x >>= 2; lsr2 = x; end endfunction function integer asl2(input integer x); begin x <<<= 2; asl2 = x; end endfunction function integer asr2(input integer x); begin x >>>= 2; asr2 = x; end endfunction localparam add2_5 = add2(5); localparam sub2_5 = sub2(5); localparam mul2_5 = mul2(5); localparam div2_5 = div2(5); localparam mod2_5 = mod2(5); localparam and6_f = and6(4'hf); localparam or6_0 = or6(4'h0); localparam xor6_f = xor6(4'hf); localparam lsl2_p25 = lsl2( 25); localparam lsr2_m25 = lsr2(-25); localparam asl2_m25 = asl2(-25); localparam asr2_m25 = asr2(-25); function integer add3(input integer x); begin add3 = x; add3 += 3; end endfunction function integer sub3(input integer x); begin sub3 = x; sub3 -= 3; end endfunction function integer mul3(input integer x); begin mul3 = x; mul3 *= 3; end endfunction function integer div3(input integer x); begin div3 = x; div3 /= 3; end endfunction function integer mod3(input integer x); begin mod3 = x; mod3 %= 3; end endfunction function [3:0] and9(input [3:0] x); begin and9 = x; and9 &= 4'h9; end endfunction function [3:0] or9(input [3:0] x); begin or9 = x; or9 |= 4'h9; end endfunction function [3:0] xor9(input [3:0] x); begin xor9 = x; xor9 ^= 4'h9; end endfunction function integer lsl3(input integer x); begin lsl3 = x; lsl3 <<= 3; end endfunction function integer lsr3(input integer x); begin lsr3 = x; lsr3 >>= 3; end endfunction function integer asl3(input integer x); begin asl3 = x; asl3 <<<= 3; end endfunction function integer asr3(input integer x); begin asr3 = x; asr3 >>>= 3; end endfunction localparam add3_5 = add3(5); localparam sub3_5 = sub3(5); localparam mul3_5 = mul3(5); localparam div3_5 = div3(5); localparam mod3_5 = mod3(5); localparam and9_f = and9(4'hf); localparam or9_0 = or9(4'h0); localparam xor9_f = xor9(4'hf); localparam lsl3_p25 = lsl3( 25); localparam lsr3_m25 = lsr3(-25); localparam asl3_m25 = asl3(-25); localparam asr3_m25 = asr3(-25); reg failed = 0; initial begin $display("pre_inc_5 = %0d", pre_inc_5); if (pre_inc_5 !== pre_inc(5)) failed = 1; if (pre_inc_5 !== 6) failed = 1; $display("pre_dec_5 = %0d", pre_dec_5); if (pre_dec_5 !== pre_dec(5)) failed = 1; if (pre_dec_5 !== 4) failed = 1; $display("post_inc_5 = %0d", post_inc_5); if (post_inc_5 !== post_inc(5)) failed = 1; if (post_inc_5 !== 6) failed = 1; $display("post_dec_5 = %0d", post_dec_5); if (post_dec_5 !== post_dec(5)) failed = 1; if (post_dec_5 !== 4) failed = 1; $display("add2_5 = %0d", add2_5); if (add2_5 !== add2(5)) failed = 1; if (add2_5 !== 7) failed = 1; $display("sub2_5 = %0d", sub2_5); if (sub2_5 !== sub2(5)) failed = 1; if (sub2_5 !== 3) failed = 1; $display("mul2_5 = %0d", mul2_5); if (mul2_5 !== mul2(5)) failed = 1; if (mul2_5 !== 10) failed = 1; $display("div2_5 = %0d", div2_5); if (div2_5 !== div2(5)) failed = 1; if (div2_5 !== 2) failed = 1; $display("mod2_5 = %0d", mod2_5); if (mod2_5 !== mod2(5)) failed = 1; if (mod2_5 !== 1) failed = 1; $display("and6_f = %h", and6_f); if (and6_f !== and6(4'hf)) failed = 1; if (and6_f !== 4'h6) failed = 1; $display("or6_0 = %h", or6_0); if (or6_0 !== or6(4'h0)) failed = 1; if (or6_0 !== 4'h6) failed = 1; $display("xor6_f = %h", xor6_f); if (xor6_f !== xor6(4'hf)) failed = 1; if (xor6_f !== 4'h9) failed = 1; $display("lsl2_p25 = %0d", lsl2_p25); if (lsl2_p25 !== lsl2( 25)) failed = 1; if (lsl2_p25 !== 100) failed = 1; $display("lsr2_m25 = %0h", lsr2_m25); if (lsr2_m25 !== lsr2(-25)) failed = 1; if (lsr2_m25 !== 32'h3ffffff9) failed = 1; $display("asl2_m25 = %0d", asl2_m25); if (asl2_m25 !== asl2(-25)) failed = 1; if (asl2_m25 !== -100) failed = 1; $display("asr2_m25 = %0d", asr2_m25); if (asr2_m25 !== asr2(-25)) failed = 1; if (asr2_m25 !== -7) failed = 1; $display("add3_5 = %0d", add3_5); if (add3_5 !== add3(5)) failed = 1; if (add3_5 !== 8) failed = 1; $display("sub3_5 = %0d", sub3_5); if (sub3_5 !== sub3(5)) failed = 1; if (sub3_5 !== 2) failed = 1; $display("mul3_5 = %0d", mul3_5); if (mul3_5 !== mul3(5)) failed = 1; if (mul3_5 !== 15) failed = 1; $display("div3_5 = %0d", div3_5); if (div3_5 !== div3(5)) failed = 1; if (div3_5 !== 1) failed = 1; $display("mod3_5 = %0d", mod3_5); if (mod3_5 !== mod3(5)) failed = 1; if (mod3_5 !== 2) failed = 1; $display("and9_f = %h", and9_f); if (and9_f !== and9(4'hf)) failed = 1; if (and9_f !== 4'h9) failed = 1; $display("or9_0 = %h", or9_0); if (or9_0 !== or9(4'h0)) failed = 1; if (or9_0 !== 4'h9) failed = 1; $display("xor9_f = %h", xor9_f); if (xor9_f !== xor9(4'hf)) failed = 1; if (xor9_f !== 4'h6) failed = 1; $display("lsl3_p25 = %0d", lsl3_p25); if (lsl3_p25 !== lsl3( 25)) failed = 1; if (lsl3_p25 !== 200) failed = 1; $display("lsr3_m25 = %0h", lsr3_m25); if (lsr3_m25 !== lsr3(-25)) failed = 1; if (lsr3_m25 !== 32'h1ffffffc) failed = 1; $display("asl3_m25 = %0d", asl3_m25); if (asl3_m25 !== asl3(-25)) failed = 1; if (asl3_m25 !== -200) failed = 1; $display("asr3_m25 = %0d", asr3_m25); if (asr3_m25 !== asr3(-25)) failed = 1; if (asr3_m25 !== -4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/check_constant_1.v000066400000000000000000000001151435245347300221340ustar00rootroot00000000000000module top_module(); integer Value1; parameter Value2 = Value1; endmodule iverilog-12_0/ivtest/ivltests/check_constant_10.v000066400000000000000000000004101435245347300222120ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[N:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_11.v000066400000000000000000000004101435245347300222130ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[N][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_12.v000066400000000000000000000004101435245347300222140ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:N]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_13.v000066400000000000000000000004101435245347300222150ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[N:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_14.v000066400000000000000000000004101435245347300222160ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:N] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_15.v000066400000000000000000000004101435245347300222170ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][N:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_16.v000066400000000000000000000004101435245347300222200ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[N][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_17.v000066400000000000000000000004101435245347300222210ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[N][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:N]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_18.v000066400000000000000000000004101435245347300222220ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][N:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_19.v000066400000000000000000000004101435245347300222230ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:N] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_2.v000066400000000000000000000002511435245347300221360ustar00rootroot00000000000000module sub_module(); parameter Value1 = 0; endmodule module top_module(); integer Value2; sub_module sub_module(); defparam sub_module.Value1 = Value2; endmodule iverilog-12_0/ivtest/ivltests/check_constant_20.v000066400000000000000000000004101435245347300222130ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[N:0] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_3.v000066400000000000000000000001501435245347300221350ustar00rootroot00000000000000module top_module(); integer Value1; integer Value2 = Value1; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/check_constant_4.v000066400000000000000000000001211435245347300221340ustar00rootroot00000000000000module top_module(); integer N; (* attr = N *) initial $display(N); endmodule iverilog-12_0/ivtest/ivltests/check_constant_5.v000066400000000000000000000004101435245347300221360ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:N] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_6.v000066400000000000000000000004101435245347300221370ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [N:0] In, output reg [7:0] Out ); wire [7:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_7.v000066400000000000000000000004101435245347300221400ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:N] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_8.v000066400000000000000000000004101435245347300221410ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [N:0] Array[7:0]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/check_constant_9.v000066400000000000000000000004101435245347300221420ustar00rootroot00000000000000module top_module( input wire [2:0] N, input wire [7:0] In, output reg [7:0] Out ); wire [7:0] Array[7:N]; assign Array[0][0] = In[0]; assign Array[0][7:1] = In[7:1]; initial begin Out[0] = Array[0][0]; Out[7:1] = Array[0][7:1]; end endmodule iverilog-12_0/ivtest/ivltests/clkgen_bit.v000066400000000000000000000010621435245347300210310ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas * * The test checks the module bit ouput type accepts default * initialization value. */ module clkgen(output bit clk = 0); initial begin #100; disable checking; disable gen; $display ("PASSED"); $finish; end initial begin fork gen; checking; join end task gen; forever #10 clk = ~clk; endtask task checking; forever begin #1; if (clk ==! 1'b0 && clk ==! 1'b1 ) begin $display ("FAILED!"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/clkgen_logic.v000066400000000000000000000011611435245347300213500ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas * * The test checks the module logic ouput type accepts default * initialization value. If no default value is given to logic output * type then this test fails. */ module clkgen(output logic clk = 0); initial begin #100; disable checking; disable gen; $display ("PASSED"); $finish; end initial begin fork gen; checking; join end task gen; forever #10 clk = ~clk; endtask task checking; forever begin #1; if (clk === 1'bx ) begin $display ("FAILED!"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/clkgen_net.v000066400000000000000000000012541435245347300210440ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas * * The test checks that an unspecified output type is elaborated as Net. * If an intial value is given to an unspecified ouput type it does * not compile. */ module clkgen(output clk); logic iclk = 'x; assign clk = iclk; initial begin #100; disable checking; disable gen; $display ("PASSED"); $finish; end initial begin fork checking; gen; join end task gen; begin iclk = 0; forever #10 iclk = ~iclk; end endtask task checking; forever begin #1; if (clk === 1'bx ) begin $display ("FAILED!"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/clkgen_reg.v000066400000000000000000000011531435245347300210310ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas * * The test checks the module reg ouput type accepts default * initialization value. If no default value is given to reg output * type then this test fails. */ module clkgen(output reg clk = 0); initial begin #100; disable checking; disable gen; $display ("PASSED"); $finish; end initial begin fork gen; checking; join end task gen; forever #10 clk = ~clk; endtask task checking; forever begin #1; if (clk === 1'bx ) begin $display ("FAILED!"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/clog2-signal.v000066400000000000000000000002211435245347300212050ustar00rootroot00000000000000module top; integer in; initial begin in = 2; if ($clog2(in) != 1) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/clog2.v000066400000000000000000000233301435245347300177400ustar00rootroot00000000000000// Still need to check real wires and what they return! module top; // Any unsized negative value will be 32 bits or more! parameter pm1 = $clog2(-1); parameter prm1 = $clog2(-1.0); parameter prm30 = $clog2(-(2**31-1)); parameter prm31 = $clog2(-(2**31)); parameter prm32 = $clog2(-(33'sd2**32)); parameter prm67 = $clog2(-(68'sd2**67)); parameter p0 = $clog2(0); parameter p1 = $clog2(1); parameter p2 = $clog2(2); parameter p3 = $clog2(3); parameter p4 = $clog2(4); parameter p5 = $clog2(5); parameter p8 = $clog2(8); parameter p8r = $clog2(8.49999); parameter p128 = $clog2(129'h100000000000000000000000000000000); parameter p128p = $clog2(129'sd2**128); // These all return 'bx. parameter pminf = $clog2(-1.0/0.0); // -Inf parameter pinf = $clog2(1.0/0.0); // +Inf parameter px = $clog2('bx); reg [$clog2(8)-1:0] reg8 = 'b0; reg pass = 1'b1; integer result; reg [128:0] in; wire [7:0] out = $clog2(in); real rin; wire [7:0] rout = $clog2(rin); wire real rin2 = rin * 2.0; wire [7:0] rout2 = $clog2(rin2); initial begin /* Test the elab_pexpr implementation. */ if ($bits(reg8) !== 3) begin $display("Failed register size, expected 3, got %d", $bits(reg8)); pass = 1'b0; end if (pm1 !== 32) begin $display("Failed with param. -1, expected 32, got %d", pm1); pass = 1'b0; end if (prm1 !== 32) begin $display("Failed with param. -1.0, expected 32, got %d", prm1); pass = 1'b0; end if (prm30 !== 32) begin $display("Failed with param. -(2**30-1), expected 32, got %d", prm30); pass = 1'b0; end if (prm31 !== 32) begin $display("Failed with param. -(2**31), expected 32, got %d", prm31); pass = 1'b0; end if (prm32 !== 32) begin $display("Failed with param. -(2**32), expected 32, got %d", prm32); pass = 1'b0; end if (prm67 !== 67) begin $display("Failed with param. -(2**67), expected 67, got %d", prm67); pass = 1'b0; end if (p0 !== 0) begin $display("Failed with param. 0, expected 0, got %d", p0); pass = 1'b0; end if (p1 !== 0) begin $display("Failed with param. 1, expected 0, got %d", p1); pass = 1'b0; end if (p2 !== 1) begin $display("Failed with param. 2, expected 1, got %d", p2); pass = 1'b0; end if (p3 !== 2) begin $display("Failed with param. 3, expected 2, got %d", p3); pass = 1'b0; end if (p4 !== 2) begin $display("Failed with param. 4, expected 2, got %d", p4); pass = 1'b0; end if (p5 !== 3) begin $display("Failed with param. 5, expected 3, got %d", p5); pass = 1'b0; end if (p8 !== 3) begin $display("Failed with param. 8, expected 3, got %d", p8); pass = 1'b0; end if (p8r !== 3) begin $display("Failed with param. 8 (real), expected 3, got %d", p8r); pass = 1'b0; end if (p128 !== 128) begin $display("Failed with param. 129'h10...0, expected 128, got %d", p128); pass = 1'b0; end if (p128p !== 128) begin $display("Failed with param. 2**128, expected 128, got %d", p128p); pass = 1'b0; end if (pinf !== 32'bx) begin $display("Failed with param. Inf, expected 32'bx, got %b", pinf); pass = 1'b0; end if (pminf !== 32'bx) begin $display("Failed with param. -Inf, expected 32'bx, got %b", pminf); pass = 1'b0; end if (px !== 32'bx) begin $display("Failed with param. `bx, expected 32'bx, got %b", px); pass = 1'b0; end /* Test the eval_tree implementation. */ // Any unsized negative value will be 32 bits or more! result = $clog2(-1); if (result !== 32) begin $display("Failed with -1, expected 32, got %d", result); pass = 1'b0; end result = $clog2(-1.0); if (result !== 32) begin $display("Failed with -1.0, expected 32, got %d", result); pass = 1'b0; end result = $clog2(-(2**31)); if (result !== 32) begin $display("Failed with -(2**31), expected 32, got %d", result); pass = 1'b0; end result = $clog2(-(33'sd2**32)); if (result !== 32) begin $display("Failed with -(2**32), expected 32, got %d", result); pass = 1'b0; end result = $clog2(-(68'sd2**67)); if (result !== 67) begin $display("Failed with -(2**67), expected 67, got %d", result); pass = 1'b0; end result = $clog2(0); if (result !== 0) begin $display("Failed with 0, expected 0, got %d", result); pass = 1'b0; end result = $clog2(1); if (result !== 0) begin $display("Failed with 1, expected 0, got %d", result); pass = 1'b0; end result = $clog2(2); if (result !== 1) begin $display("Failed with 2, expected 1, got %d", result); pass = 1'b0; end result = $clog2(3); if (result !== 2) begin $display("Failed with 3, expected 2, got %d", result); pass = 1'b0; end result = $clog2(4); if (result !== 2) begin $display("Failed with 4, expected 2, got %d", result); pass = 1'b0; end result = $clog2(5); if (result !== 3) begin $display("Failed with 5, expected 3, got %d", result); pass = 1'b0; end result = $clog2(8); if (result !== 3) begin $display("Failed with 8, expected 3, got %d", result); pass = 1'b0; end result = $clog2(8.1); if (result !== 3) begin $display("Failed with 8.1, expected 3, got %d", result); pass = 1'b0; end result = $clog2(8.49999); if (result !== 3) begin $display("Failed with 8.49999, expected 3, got %d", result); pass = 1'b0; end result = $clog2(8.5); if (result !== 4) begin $display("Failed with 8.5, expected 4, got %d", result); pass = 1'b0; end result = $clog2(129'h100000000000000000000000000000000); if (result !== 128) begin $display("Failed with 129'h10...0, expected 128, got %d", result); pass = 1'b0; end result = $clog2(129'sd2**128); if (result !== 128) begin $display("Failed with 2**128, expected 128, got %d", result); pass = 1'b0; end result = $clog2(1.0/0.0); // Inf if (result !== 32'bx) begin $display("Failed with Inf, expected 32'bx, got %b", result); pass = 1'b0; end result = $clog2(-1.0/0.0); // -Inf if (result !== 32'bx) begin $display("Failed with -Inf, expected 32'bx, got %b", result); pass = 1'b0; end result = $clog2('bx); if (result !== 32'bx) begin $display("Failed with `bx, expected 32'bx, got %b", result); pass = 1'b0; end /* Test the CA statements and the vpi implementation. */ in = -1; // This is not an unsized value ('in' is 129 bits)! #1 if (out != 129) begin $display("Failed CA with -1, expected 129, got %d", out); pass = 1'b0; end in = 0; #1 if (out !== 0) begin $display("Failed CA with 0, expected 0, got %d", out); pass = 1'b0; end in = 1; #1 if (out !== 0) begin $display("Failed CA with 1, expected 0, got %d", out); pass = 1'b0; end in = 2; #1 if (out !== 1) begin $display("Failed CA with 2, expected 1, got %d", out); pass = 1'b0; end in = 3; #1 if (out !== 2) begin $display("Failed CA with 3, expected 2, got %d", out); pass = 1'b0; end in = 4; #1 if (out !== 2) begin $display("Failed CA with 4, expected 2, got %d", out); pass = 1'b0; end in = 5; #1 if (out !== 3) begin $display("Failed CA with 5, expected 3, got %d", out); pass = 1'b0; end in = 8; #1 if (out !== 3) begin $display("Failed CA with 8, expected 3, got %d", out); pass = 1'b0; end rin = -1.0; // This is an unsized value (reals are unsized)! #1 if (rout !== 32 && rout2 !== 32) begin $display("Failed CA with -1.0, expected 32/32, got %d/%d", rout, rout2); pass = 1'b0; end rin = 8.1; #1 if (rout !== 3 && rout2 !== 4) begin $display("Failed CA with 8.1, expected 3/4, got %d/%d", rout, rout2); pass = 1'b0; end rin = 8.49999; #1 if (rout !== 3 && rout2 !== 4) begin $display("Failed CA with 8.49999, expected 3/4, got %d/%d", rout, rout2); pass = 1'b0; end rin = 8.5; #1 if (rout !== 4 && rout2 !== 5) begin $display("Failed CA with 8.5, expected 4/5, got %d/%d", rout, rout2); pass = 1'b0; end in = 129'h100000000000000000000000000000000; #1 if (out !== 128) begin $display("Failed CA with 129'h10...0, expected 128, got %d", out); pass = 1'b0; end in = 2**128; #1 if (out !== 128) begin $display("Failed CA with 2**128, expected 128, got %d", out); pass = 1'b0; end in = 'bx; #1 if (out !== 8'bx) begin $display("Failed CA with 'bx, expected 8'bx, got %b", out); pass = 1'b0; end rin = 1.0/0.0; #1 if (rout !== 8'bx && rout2 !== 8'bx) begin $display("Failed CA with Inf, expected 8'bx/8'bx got %b/%b", rout, rout2); pass = 1'b0; end rin = -1.0/0.0; #1 if (rout !== 8'bx && rout2 !== 8'bx) begin $display("Failed CA with -Inf, expected 8'bx/8'bx got %b/%b", rout, rout2); pass = 1'b0; end /* Check that the result is sign extended correctly. */ // Compile time generated. in = $clog2(1.0/0.0); if (in !== 129'bx) begin $display("Failed sign extended Inf (C), expected 129'bx got %b", in); pass = 1'b0; end // Run time generated. rin = 1.0; in = $clog2(rin/0.0); if (in !== 129'bx) begin $display("Failed sign extended Inf (RT), expected 129'bx got %b", in); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cmdline_parm1.v000066400000000000000000000005171435245347300214470ustar00rootroot00000000000000/* * This program tests the simple parameter override from the command * line. This program should be compiled with the -Pmain.foo=2 argument. */ module main; parameter foo = 1; initial begin if (foo != 2) begin $display("FAILED: %m.foo = %d", foo); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cmos.v000066400000000000000000000017311435245347300176740ustar00rootroot00000000000000module top; reg nctl, pctl, b; wire a, c; initial begin $monitor(a,c,,"%v",a,,"%v",c,,b,,nctl,,pctl); b = 0; nctl = 0; pctl = 1; #1 nctl = 1; pctl = 0; #1 nctl = 1; pctl = 1; #1 nctl = 0; pctl = 0; #1 nctl = 1'bx; pctl = 0; #1 nctl = 1; pctl = 1'bx; #1 nctl = 1'bx; pctl = 1; #1 nctl = 0; pctl = 1'bx; #1 nctl = 1'bx; pctl = 1'bx; #1 b = 1; nctl = 0; pctl = 1; #1 nctl = 1; pctl = 0; #1 nctl = 1; pctl = 1; #1 nctl = 0; pctl = 0; #1 nctl = 1'bx; pctl = 0; #1 nctl = 1; pctl = 1'bx; #1 nctl = 1'bx; pctl = 1; #1 nctl = 0; pctl = 1'bx; #1 nctl = 1'bx; pctl = 1'bx; #1 b = 1'bx; nctl = 0; pctl = 1; #1 b = 1'bx; nctl = 1; pctl = 0; #1 b = 1'bx; nctl = 1'bx; pctl = 1'bx; #1 b = 1'bz; nctl = 0; pctl = 1; #1 b = 1'bz; nctl = 1; pctl = 0; #1 b = 1'bz; nctl = 1'bx; pctl = 1'bx; end nmos n1 (a, b, nctl); pmos p1 (a, b, pctl); cmos c1 (c, b, nctl, pctl); endmodule iverilog-12_0/ivtest/ivltests/cmpi.v000066400000000000000000000017751435245347300176730ustar00rootroot00000000000000 module main; reg [7:0] val; initial begin val = 120; if (8'd5 < val) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (8'd5 <= val) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (8'd121 > val) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (8'd121 >= val) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (val > 8'd5) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (val >= 8'd5) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (val < 8'd121) begin $display("OK"); end else begin $display("FAILED"); $finish; end if (val <= 8'd121) begin $display("OK"); end else begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/comment1.v000066400000000000000000000001151435245347300204510ustar00rootroot00000000000000/* )* */ /* (* /* *) */ module test(); initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/comp1000.v000066400000000000000000002102431435245347300201720ustar00rootroot00000000000000// // Copyright (c) 2000 Paul Campbell (paul@verifarm.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module compl1000; reg [158:143]r0; reg [128:104]r1; reg [200:173]r2; reg [165:162]r3; reg [150:129]r4; reg [123:93]r5; reg [55:54]r6; reg [24:3]r7; reg [109:93]r8; reg [30:14]r9; reg [184:174]r10; reg [59:30]r11; reg [153:124]r12; reg [248:221]r13; reg [258:250]r14; reg [158:147]r15; reg [54:48]r16; reg [159:136]r17; reg [214:187]r18; reg [60:29]r19; reg [71:71]r20; reg [177:169]r21; reg [219:205]r22; reg [24:21]r23; reg [153:141]r24; reg [85:54]r25; reg [227:202]r26; reg [251:237]r27; reg [98:73]r28; reg [24:0]r29; reg [166:135]r30; reg [184:183]r31; reg [219:189]r32; reg [81:54]r33; reg [164:148]r34; reg [170:158]r35; reg [171:168]r36; reg [255:226]r37; reg [197:191]r38; reg [113:105]r39; reg [221:198]r40; reg [135:104]r41; reg [153:143]r42; reg [281:253]r43; reg [101:76]r44; reg [24:12]r45; reg [217:203]r46; reg [244:218]r47; reg [128:111]r48; reg [136:107]r49; reg [260:242]r50; reg [157:156]r51; reg [242:220]r52; reg [278:255]r53; reg [196:194]r54; reg [148:121]r55; reg [71:63]r56; reg [166:157]r57; reg [200:180]r58; reg [230:199]r59; reg [212:191]r60; reg [264:248]r61; reg [136:124]r62; reg [131:117]r63; reg [148:126]r64; reg [51:30]r65; reg [166:140]r66; reg [166:143]r67; reg [44:27]r68; reg [259:248]r69; reg [167:143]r70; reg [210:189]r71; reg [73:50]r72; reg [225:205]r73; reg [255:240]r74; reg [208:194]r75; reg [222:217]r76; reg [217:189]r77; reg [100:83]r78; reg [275:255]r79; reg [39:34]r80; reg [98:72]r81; reg [55:25]r82; reg [246:240]r83; reg [170:157]r84; reg [218:198]r85; reg [225:223]r86; reg [186:172]r87; reg [241:213]r88; reg [263:238]r89; reg [272:253]r90; reg [105:103]r91; reg [211:209]r92; reg [89:82]r93; reg [30:9]r94; reg [246:241]r95; reg [170:147]r96; reg [229:224]r97; reg [107:83]r98; reg [60:54]r99; reg [154:154]r100; reg [105:97]r101; reg [127:104]r102; reg [219:190]r103; reg [114:98]r104; reg [267:251]r105; reg [169:145]r106; reg [64:45]r107; reg [227:224]r108; reg [186:176]r109; reg [101:84]r110; reg [219:194]r111; reg [11:9]r112; reg [236:222]r113; reg [271:240]r114; reg [232:218]r115; reg [78:74]r116; reg [191:191]r117; reg [242:227]r118; reg [135:108]r119; reg [24:15]r120; reg [250:233]r121; reg [125:102]r122; reg [165:140]r123; reg [63:63]r124; reg [235:206]r125; reg [264:237]r126; reg [241:234]r127; reg [188:188]r128; reg [71:59]r129; reg [181:170]r130; reg [106:83]r131; reg [245:229]r132; reg [239:219]r133; reg [10:8]r134; reg [45:45]r135; reg [23:22]r136; reg [197:178]r137; reg [57:50]r138; reg [264:253]r139; reg [53:36]r140; reg [187:164]r141; reg [153:140]r142; reg [235:226]r143; reg [236:228]r144; reg [262:238]r145; reg [76:55]r146; reg [49:25]r147; reg [191:163]r148; reg [197:170]r149; reg [151:143]r150; reg [126:122]r151; reg [188:173]r152; reg [93:78]r153; reg [175:175]r154; reg [249:247]r155; reg [214:200]r156; reg [60:43]r157; reg [263:233]r158; reg [54:34]r159; reg [202:184]r160; reg [250:240]r161; reg [99:80]r162; reg [175:165]r163; reg [189:188]r164; reg [52:38]r165; reg [74:48]r166; reg [232:202]r167; reg [24:13]r168; reg [209:180]r169; reg [173:147]r170; reg [264:243]r171; reg [115:99]r172; reg [94:91]r173; reg [195:188]r174; reg [36:33]r175; reg [136:114]r176; reg [82:56]r177; reg [204:173]r178; reg [116:111]r179; reg [124:103]r180; reg [76:71]r181; reg [178:163]r182; reg [156:149]r183; reg [124:110]r184; reg [240:220]r185; reg [164:151]r186; reg [133:104]r187; reg [59:46]r188; reg [47:42]r189; reg [219:189]r190; reg [99:87]r191; reg [86:73]r192; reg [222:191]r193; reg [23:7]r194; reg [239:238]r195; reg [240:222]r196; reg [27:4]r197; reg [191:160]r198; reg [106:84]r199; reg [22:8]r200; reg [204:191]r201; reg [133:115]r202; reg [225:207]r203; reg [126:95]r204; reg [161:147]r205; reg [193:164]r206; reg [69:61]r207; reg [130:116]r208; reg [142:124]r209; reg [50:20]r210; reg [175:154]r211; reg [102:87]r212; reg [114:85]r213; reg [225:223]r214; reg [131:127]r215; reg [24:19]r216; reg [84:84]r217; reg [223:223]r218; reg [171:159]r219; reg [76:47]r220; reg [162:139]r221; reg [67:41]r222; reg [88:74]r223; reg [60:44]r224; reg [114:104]r225; reg [142:141]r226; reg [262:236]r227; reg [16:12]r228; reg [66:51]r229; reg [40:24]r230; reg [150:141]r231; reg [209:199]r232; reg [152:148]r233; reg [162:147]r234; reg [82:80]r235; reg [245:214]r236; reg [35:12]r237; reg [18:3]r238; reg [270:246]r239; reg [183:170]r240; reg [122:121]r241; reg [60:42]r242; reg [99:91]r243; reg [61:51]r244; reg [154:150]r245; reg [5:3]r246; reg [275:246]r247; reg [113:92]r248; reg [136:118]r249; reg [94:71]r250; reg [104:91]r251; reg [169:139]r252; reg [22:14]r253; reg [255:236]r254; reg [213:186]r255; initial begin r0 = 32'h3d24; r1 = 32'h70fd; r2 = 32'h47aa; r3 = 32'h39ed; r4 = 32'h2ca3; r5 = 32'he68; r6 = 32'h1160; r7 = 32'h5636; r8 = 32'h2305; r9 = 32'h1257; r10 = 32'h4e74; r11 = 32'h3835; r12 = 32'h3857; r13 = 32'h3f6f; r14 = 32'h7b33; r15 = 32'h2f37; r16 = 32'h10a; r17 = 32'h6cff; r18 = 32'h3f3; r19 = 32'h70e2; r20 = 32'h4cb3; r21 = 32'h510; r22 = 32'h1837; r23 = 32'h425; r24 = 32'h1488; r25 = 32'h5731; r26 = 32'h1388; r27 = 32'h6ee0; r28 = 32'h559b; r29 = 32'h4bff; r30 = 32'h180e; r31 = 32'h1252; r32 = 32'h52d4; r33 = 32'h4576; r34 = 32'h36f1; r35 = 32'h6246; r36 = 32'h7aaf; r37 = 32'h37fb; r38 = 32'h4272; r39 = 32'h62fd; r40 = 32'h6cbb; r41 = 32'h4825; r42 = 32'h25c7; r43 = 32'h19da; r44 = 32'h5ace; r45 = 32'h794f; r46 = 32'h5ebb; r47 = 32'h5cd0; r48 = 32'h4209; r49 = 32'h38de; r50 = 32'h7502; r51 = 32'h2c8c; r52 = 32'h378f; r53 = 32'h5252; r54 = 32'hb5d; r55 = 32'h561; r56 = 32'h4504; r57 = 32'h180f; r58 = 32'h6672; r59 = 32'h52f7; r60 = 32'h10c7; r61 = 32'h4ce9; r62 = 32'h569; r63 = 32'h72b3; r64 = 32'h4df0; r65 = 32'h1a72; r66 = 32'h2846; r67 = 32'h70e5; r68 = 32'h3008; r69 = 32'h2003; r70 = 32'h6009; r71 = 32'h6cb5; r72 = 32'h5e8b; r73 = 32'h668b; r74 = 32'h487; r75 = 32'h4eca; r76 = 32'h241e; r77 = 32'h451a; r78 = 32'h2c06; r79 = 32'h3ebf; r80 = 32'h5590; r81 = 32'h22c; r82 = 32'h9b; r83 = 32'h347; r84 = 32'h2c92; r85 = 32'h3db6; r86 = 32'hf44; r87 = 32'h391a; r88 = 32'h1237; r89 = 32'h6ff2; r90 = 32'h6cc5; r91 = 32'hca7; r92 = 32'h152a; r93 = 32'h8eb; r94 = 32'h4c43; r95 = 32'h6277; r96 = 32'h7b1; r97 = 32'h7cc8; r98 = 32'h63a2; r99 = 32'h1a62; r100 = 32'h165; r101 = 32'h48d8; r102 = 32'h399e; r103 = 32'h5975; r104 = 32'h40ae; r105 = 32'h3d61; r106 = 32'h39ab; r107 = 32'h69f; r108 = 32'h2801; r109 = 32'h1828; r110 = 32'h298d; r111 = 32'h661e; r112 = 32'h52d9; r113 = 32'h3bc0; r114 = 32'h5cb7; r115 = 32'h7fac; r116 = 32'h7e76; r117 = 32'hf93; r118 = 32'h4165; r119 = 32'h3b68; r120 = 32'h4258; r121 = 32'h54b2; r122 = 32'h2378; r123 = 32'h6186; r124 = 32'h547a; r125 = 32'h7b5c; r126 = 32'h4115; r127 = 32'h68b6; r128 = 32'h554f; r129 = 32'h4550; r130 = 32'hcfc; r131 = 32'h3f55; r132 = 32'h5f7d; r133 = 32'h40d2; r134 = 32'h3aa8; r135 = 32'h7b56; r136 = 32'h575c; r137 = 32'h687f; r138 = 32'h702c; r139 = 32'h1cee; r140 = 32'h362d; r141 = 32'h73d2; r142 = 32'h39c8; r143 = 32'h5003; r144 = 32'h4d1a; r145 = 32'h2472; r146 = 32'h1b4e; r147 = 32'h5852; r148 = 32'h3bf2; r149 = 32'h1c41; r150 = 32'h5b37; r151 = 32'h1462; r152 = 32'h17a1; r153 = 32'h825; r154 = 32'h6384; r155 = 32'h432c; r156 = 32'h7c70; r157 = 32'h2b94; r158 = 32'h5456; r159 = 32'h7887; r160 = 32'h802; r161 = 32'h18e2; r162 = 32'h244c; r163 = 32'h6c55; r164 = 32'h770a; r165 = 32'h224a; r166 = 32'h6aa0; r167 = 32'h1070; r168 = 32'h62cd; r169 = 32'h4fbe; r170 = 32'h2f01; r171 = 32'h1952; r172 = 32'h5a5b; r173 = 32'h656e; r174 = 32'h5b2e; r175 = 32'h6586; r176 = 32'h538d; r177 = 32'h471a; r178 = 32'h2a57; r179 = 32'h6fd2; r180 = 32'h2fbd; r181 = 32'h4418; r182 = 32'h3233; r183 = 32'h3821; r184 = 32'h5048; r185 = 32'h1824; r186 = 32'h61e0; r187 = 32'h4f33; r188 = 32'h76c5; r189 = 32'h2ceb; r190 = 32'h127f; r191 = 32'h7103; r192 = 32'h6d02; r193 = 32'h6856; r194 = 32'h58b; r195 = 32'h59fb; r196 = 32'h30c3; r197 = 32'h1397; r198 = 32'h6cfd; r199 = 32'h42da; r200 = 32'h1f39; r201 = 32'h26f4; r202 = 32'h5922; r203 = 32'h2f61; r204 = 32'h5c44; r205 = 32'h656; r206 = 32'h2837; r207 = 32'h7bc1; r208 = 32'h7168; r209 = 32'h7a91; r210 = 32'h53ca; r211 = 32'h54c4; r212 = 32'h6091; r213 = 32'h7371; r214 = 32'h37d0; r215 = 32'h6bd; r216 = 32'h2687; r217 = 32'h5e88; r218 = 32'h2f85; r219 = 32'h4f31; r220 = 32'h692f; r221 = 32'h1eba; r222 = 32'h2407; r223 = 32'h1d42; r224 = 32'h4d87; r225 = 32'h7085; r226 = 32'h68b1; r227 = 32'h6cdf; r228 = 32'h315f; r229 = 32'h4711; r230 = 32'h138; r231 = 32'h28ad; r232 = 32'h44d8; r233 = 32'h6dfb; r234 = 32'h2d88; r235 = 32'h3eb4; r236 = 32'h3f9e; r237 = 32'h7be1; r238 = 32'h575c; r239 = 32'h53ca; r240 = 32'h2de5; r241 = 32'h61ad; r242 = 32'h3d9f; r243 = 32'h41c0; r244 = 32'h1124; r245 = 32'h22a2; r246 = 32'h7986; r247 = 32'h4c4e; r248 = 32'h5094; r249 = 32'h128; r250 = 32'h396a; r251 = 32'h38be; r252 = 32'h3567; r253 = 32'h2c57; r254 = 32'h4d66; r255 = 32'h345b; #10; r201 = $stime; #10; r153 = ( ~ ( r189)); #10; r200 = (3'h7 !== r2); #10; r186 = r155; #10; r208 = (((((( ( + ( (((16'h46d9 || r190) - $time) > (r127 >= (2'h0 !== r81))))) || ( | ( r150))) > r11) !== ((20'h617c * ( & ( r207))) > (r158 && (31'h6f3f - 19'h3eb3)))) * 17'h5321) - 25'h116f) ^ ((((($stime === r219) <= ($stime | (r43 < ((($stime ^ (( ( & ( ( ( & ( 26'h3af4)) | ( | ( 12'h8c7))))) && (r97 | 7'h3)) && 17'h7a8a)) == 9'h84) + ((18'h7e64 >= r240) >= r111))))) ^ 8'ha9) ^ ( - ( r15))) & (( ( & ( $time)) == r235) >= (( ( | ( r90)) || (r56 & r182)) !== r72)))); #10; r175 = (($time / ((15'h7f3d === ( ( & ( r1)) == r2)) >= ((9'h78 % ( ( ^ ( ( - ( (r164 & (2'h2 >= (((((6'h1f == 28'h4032) / ( | ( 16'h5821))) | 28'h7b43) >= (r191 & $stime)) < ( + ( ((2'h3 % (12'hf20 - 16'h2734)) ? ( + ( (16'h1317 && 31'h16ee))) : (r137 < (6'h27 >= 3'h2)))))))))))) & ((( ( - ( (r169 ? ((r155 != 31'h60f0) >= ((r166 % (15'h587f - 30'h5197)) < r187)) : (((23'h220b <= 20'h46a) & (29'h584 > (10'h17 - 19'h53b7))) != ( & ( ( | ( (9'h1d0 <= 2'h0))))))))) ? r92 : ((($time <= 27'h6600) < (5'h13 ^ r99)) <= ( ! ( (((17'h2640 ? 2'h1 : r189) > $time) >= r248))))) ? (3'h2 - (9'h97 == ( ^ ( 4'h5)))) : ((1'h0 ? ( ( ! ( r34)) && ((r61 >= r73) == ((r184 === (19'h2c6c != 19'h34df)) | ( ~ ( r72))))) : 19'h64ff) >= (( ( ! ( (r24 !== ((7'h2b >= 1'h1) && ( ~ ( 4'he)))))) <= ( ^ ( r86))) / 12'hff3))) % (r35 < ( - ( 13'h8b9)))))) && r67))) - (((8'h12 !== (14'h2d97 <= ((r183 !== (((((r19 | r178) | (32'h743d != (r199 > ((28'h6bbb - 9'hc1) / ( + ( 18'h25d4)))))) | r255) < ( ( | ( (r12 | ((r255 % (30'h5e7b >= 11'h753)) < ( ( ~ ( 29'hc71)) || (20'h1ffc <= 17'h7cc5)))))) !== ((r181 * (((11'h18f || 17'h7265) ? 29'h485f : 4'he) == ( ( ~ ( 14'h1c84)) + 23'h298c))) || (((20'h79b3 ? (25'h1681 * 4'h9) : (12'ha6e * 26'h3ed1)) <= (r84 | (1'h1 % 2'h3))) ^ (r0 < ( ( ! ( 10'h336)) % (10'h149 / 3'h4))))))) || (r184 <= 26'h55e8))) ? 5'h17 : ( & ( (1'h0 >= r248)))))) + r191) | r65)); #10; r28 = ( ( ! ( ($time <= r162))) !== r91); #10; r125 = ($stime === ( - ( r231))); #10; r237 = r93; #10; r150 = (( ( - ( r183)) & ( ~ ( (23'h3dd8 === $time)))) > r75); #10; r59 = (23'h7ddf * $stime); #10; r157 = (3'h4 + (r27 | ( ^ ( (r175 ^ 8'h7b))))); #10; r65 = r109; #10; r241 = r88; #10; r96 = 7'h62; #10; r229 = (r248 + (r37 >= $time)); #10; r112 = r160; #10; r73 = 26'h5f00; #10; r72 = r17; #10; r2 = ( ( | ( (r124 + (( ( | ( (7'hf && (r196 ? r84 : ( ( & ( r51)) / r215))))) <= r7) <= ( | ( (r250 + ((20'h6268 % r214) / r19)))))))) * ( ( ! ( ((r249 % ($stime && (r140 * ( - ( ((r104 / 4'h4) <= (( ( + ( r250)) - ( | ( r68))) & ( ~ ( $time))))))))) || (r96 > (23'h4f58 < r185))))) !== 27'h5720)); #10; r66 = r133; #10; r199 = ( & ( (r2 % ( ^ ( ( - ( ( - ( r20))))))))); #10; r47 = r109; #10; r55 = (r96 / (r204 | ( + ( (((14'h519 / ((32'h2b24 ? ( ( | ( ( ^ ( r184)))) * (r123 < r123)) : ((((((r37 - (5'h13 == 10'h211)) == ( ! ( $time))) * 19'h76aa) >= ( ( | ( r211)) != r116)) ^ ( + ( 10'h25c))) ? (31'h68d3 !== (28'h6b7 ? ((($stime || ( + ( 25'h7c9a))) | (r74 === ( & ( 31'h28e9)))) % ( + ( ((1'h0 && 28'h6335) | ( - ( 13'h130c)))))) : 1'h0)) : ((r115 || ( | ( ( ( ~ ( r133)) && ((23'h30d3 ^ 32'h4295) % (18'h417d >= 22'h51c3)))))) && (((23'h7803 != ( ( ! ( 14'h1906)) ^ (19'h837 > 2'h2))) * (r198 <= (23'h1ee0 <= r55))) >= $stime)))) < ( ( ^ ( ((16'h5ded | (r217 / 17'h171e)) || 1'h0))) > r250))) < (8'h89 && (r15 | ( - ( r224))))) !== (((r244 === (((r229 <= 28'h441b) - ( ( | ( ((r244 - ((29'h24d7 != 17'h334f) == (8'h9f ^ 32'h3180))) ^ ( ^ ( (r238 * (21'h5f35 / 20'h5115))))))) * ( ( + ( ( - ( ( ~ ( (19'h79a9 ^ 24'h5d6a))))))) % r113))) > (((((r92 * (r232 * (22'h261f <= 14'h2bc3))) & (((20'h309a & 22'h7de2) && r181) < ((19'h7534 | 29'h18ae) > r188))) == ((((13'h46f && 25'h1d09) % r161) - ( ^ ( 30'h7cd8))) + ( - ( ((22'h6d8b || 29'h3b) ^ (21'h24f3 > 8'h7f)))))) | (r59 && (r191 >= ( ( & ( (12'h473 & 7'h69))) <= ((30'h162e !== 27'h1a0d) | 18'h5c9a))))) & (r182 - (( ( ~ ( (23'h70cb * (24'h246d > 2'h1)))) - (( ( & ( 26'h6e6c)) == 28'h21af) !== 8'h6f)) % (4'h4 >= r168)))))) != (( ( ~ ( r31)) && ( ( + ( r130)) / r96)) > 19'h1be5)) / ( ~ ( ( + ( ( ( ! ( (((r154 ? (r253 !== ( | ( (1'h0 % 22'h7fd4)))) : ((r133 > (29'h70f ? 6'h3a : 19'hff4)) === 26'h9dd)) <= r109) != 4'h2))) * ( & ( 4'h4))))))))))))); #10; r70 = r113; #10; r111 = ( ! ( ( ( ^ ( ( - ( ( | ( ( | ( ((r207 * ((((r224 !== (15'h2f78 < 32'h5844)) > (r246 === ( + ( ( ! ( r150)))))) >= r24) && 2'h1)) * r208))))))))) || ( ( ^ ( ((((r144 % r39) < ( - ( ((9'h103 + ( ( & ( ( ~ ( (r176 || (2'h1 ^ 3'h1)))))) ? $stime : r132)) ^ ( + ( (27'h3a07 ? ( ( ^ ( r12)) && ( ( & ( r164)) - ( + ( (2'h0 > 29'h1ec3))))) : r114))))))) && r126) && ((15'h4051 !== (r0 >= 27'h7733)) ^ (((22'h3da3 | ( ( & ( ( ^ ( r90)))) & 2'h1)) / 2'h1) === (r51 % r189)))))) !== (r252 == 4'h5))))); #10; r162 = 6'h25; #10; r183 = ( ( - ( (r110 ? ( ^ ( ( ( + ( ((26'h7b30 != 7'h4c) - r124))) * $time))) : ( + ( (r178 * r22)))))) ^ ((r155 && r52) < (r118 ^ ( ( | ( ( ( ! ( (24'h35fc ^ ((( ( & ( ((r53 - r49) >= 5'ha))) ? r251 : r162) <= 21'h5575) ? (r163 != (( ( ~ ( r203)) - r130) + r153)) : r97)))) == (((r154 | ( ! ( (r105 | r241)))) !== ((18'h6bbe + ( ^ ( (r193 !== ( ^ ( r26)))))) == 6'h1d)) - ((((((((11'h11f || 7'h25) ? r117 : (3'h4 > 19'h2c65)) + ((29'h1842 | 18'h1c77) + ( | ( 13'h19b)))) == $stime) != 11'h491) - 18'h69a8) & (((r206 ? ( - ( (30'hd83 ^ (30'h7ac6 | 2'h2)))) : (((10'h9d && 32'h5721) === $time) !== (r190 === (9'hd9 / 27'h2d)))) && (r232 || (r76 > ( + ( 25'hd8b))))) < $stime)) == r191))))) + $time)))); #10; r30 = r66; #10; r60 = (22'h3eec ^ (11'h1dd ^ 9'h113)); #10; r229 = ( ~ ( 5'hc)); #10; r180 = ( ^ ( ( & ( r127)))); #10; r30 = r124; #10; r149 = ( - ( (30'h743 === ((((((13'hc2 * (( ( & ( 30'h12da)) + 26'h7fc3) + ($stime ? ( ( ~ ( 27'h75f6)) | (r62 !== ( - ( 21'h3b14)))) : r238))) !== (r248 == 30'h7a43)) || 22'hfbe) * $stime) ? r240 : r4) >= (12'hd38 ^ (r147 + ((r36 - 23'h1ed1) ? ((r123 >= ( ( ~ ( (( ( + ( ( ~ ( (15'h32ce / 32'h6ae6))))) | 12'hf22) > $stime))) ? (((r200 == ($stime && r86)) >= (( ( & ( (1'h0 <= 22'h4156))) != 2'h3) === ((r118 && r106) * r249))) || 16'h629a) : (28'h6bec !== r65))) % ((21'h5864 * 2'h0) % $time)) : ((( ( & ( ( ~ ( ( ~ ( (((17'h19fd != 2'h1) > (23'h4f5d & 26'h14e6)) >= ( & ( r236))))))))) === ( ( ^ ( ((r146 && ( ( + ( 26'h40d8)) % (11'h5ba ? 16'h7254 : 32'h7877))) != 22'h3cba))) !== ( ( - ( ( ! ( r162)))) / 2'h3))) != ( ^ ( (r135 & ( ~ ( (((26'hc01 !== r252) || ((4'hd | 8'h62) > ( & ( 16'h4d14)))) == 18'h6094))))))) & (( ( ~ ( r147)) > r72) !== 13'h1f75))))))))); #10; r173 = 5'h0; #10; r103 = $time; #10; r239 = $time; #10; r23 = r22; #10; r77 = ((13'h16b3 == ( & ( r9))) / ( - ( ($time && 5'h1c)))); #10; r132 = ((r22 >= (r212 ^ (((($stime === ((r241 % (( ( | ( ($time % ((11'h4b7 && 2'h3) >= ( ! ( 32'h71f5)))))) - $stime) ? (r98 && 2'h3) : ( ^ ( (21'h384f === 27'h85))))) <= ( ! ( (20'h4d8 <= $time))))) !== (r147 == (r51 / r226))) | r15) / r114))) ? r208 : (( ( ~ ( ( + ( $stime)))) != r7) == ( ( - ( ( ! ( ( ( - ( ( ( & ( ((( ( ~ ( 22'h2cd1)) != (((14'h176d <= 29'h32ef) + (16'h23d1 != 2'h1)) * ((1'h0 ^ 14'hf5b) + r98))) || r212) === (r154 ? 5'h4 : ((((6'h18 !== 4'h7) / (27'h2c4d & 14'h1ea)) > ( | ( $time))) > (( ( + ( 22'h2996)) !== 32'h70cf) && (r135 - r79))))))) | (r98 / r221)))) + ( ^ ( (r198 !== (9'h10d === 7'h11))))))))) - ( ~ ( 30'h1aa4))))); #10; r43 = (28'h3e31 != ( - ( ((r204 ? ( ~ ( r214)) : r7) && 16'h2745)))); #10; r161 = ($stime % (( ( | ( (r185 % ( ^ ( r104))))) % ($time * (((r170 | 17'h229d) ? ((($stime >= (23'h16aa & (r64 != ((r100 & (r61 | $stime)) === r136)))) === 27'h349d) ? ((( ( & ( 4'h8)) ? ( + ( r122)) : ( ! ( ( ^ ( r70))))) > ( ~ ( r159))) + r79) : (7'h72 ^ (r55 / ( + ( ( | ( ( ^ ( ( ( ~ ( (23'h7fda + 10'h17))) * ( - ( r1)))))))))))) : ( ! ( ( ( - ( $stime)) % ( ~ ( 5'h2)))))) >= ( ( ^ ( r226)) * r107)))) <= 31'h78c1)); #10; r132 = ((1'h0 === r227) != 24'h6058); #10; r128 = 3'h1; #10; r15 = 19'h5239; #10; r17 = 15'ha01; #10; r77 = ((r242 === r221) * (r179 !== r249)); #10; r87 = (32'h57ec | r63); #10; r116 = r136; #10; r20 = r148; #10; r53 = 30'h6650; #10; r140 = r198; #10; r246 = ($stime / ( ( | ( $stime)) / ( ( ! ( ( + ( r215)))) & 20'h3e0e))); #10; r69 = r246; #10; r172 = r163; #10; r94 = r157; #10; r107 = $stime; #10; r74 = ( + ( ( - ( $time)))); #10; r130 = r195; #10; r197 = (29'ha48 > ((((r121 ^ r165) <= r124) & r226) ^ ((((((r79 * ( ( ~ ( (4'h7 != ( ~ ( r188))))) ^ r70)) & ( ( & ( ((r140 - ( ( ! ( ((32'h6c24 >= 7'h2d) == (2'h1 || 32'h1866)))) || 29'h16f1)) > (2'h1 || ( + ( ($stime == (r68 | 11'h34b)))))))) == r193)) !== r211) | r227) % (r16 == (r10 && (r229 / 4'hc)))) + (r242 ^ r117)))); #10; r130 = (20'h23ae | 18'h14b8); #10; r136 = 9'h20; #10; r249 = 15'h1805; #10; r224 = 1'h0; #10; r47 = r200; #10; r153 = 21'h2587; #10; r137 = 29'h4926; #10; r241 = ( | ( (r228 ? ((((27'h60f7 < ( ^ ( ( ( ^ ( ( - ( (r82 / 8'hb9))))) & ( ( ^ ( r124)) >= (r222 ^ (($stime ^ ( & ( ( ! ( 8'h30))))) * r146))))))) == r4) | ($time % (1'h0 / ( | ( (( ( | ( ( ^ ( ((( ( ^ ( 29'h3ca3)) / (8'h37 == 26'h3dbc)) + ((30'h160b >= 23'h7433) ^ r114)) >= (18'h2332 ? (20'h14e1 / (18'h1626 && 28'h64b1)) : r88)))))) < r219) ^ ( ( - ( ( & ( ( + ( ( ( ! ( (25'h7e80 | 5'h14))) > ( - ( (16'h12d2 || 9'h1c2)))))))))) ? $time : $stime))))))) !== r104) : ((((r252 || r121) | ((6'h37 == (((17'h697e === r43) + (18'h44f4 % 5'h1a)) ? r117 : r30)) < $stime)) + ((((r167 ? ( | ( (r87 + ( ! ( (19'h6a46 < r109)))))) : ( ! ( 16'hb75))) == 32'h4122) | r99) / (((15'h25b8 === ( ^ ( r158))) == ( ( ~ ( 23'h693a)) - ( | ( ( ^ ( r249)))))) / (r168 ? ( ( ^ ( r95)) - $time) : r204)))) * (r139 !== 24'h3813))))); #10; r166 = ( ( - ( ((r111 === r215) && r112))) | ((((($stime != r97) / ((22'h6297 != (((20'h58b | (r76 ? $time : (r57 > (( ( - ( 22'h52e5)) - (14'h105e === 4'hc)) ^ ( & ( (28'h7a38 || 14'h3a92))))))) | (23'h2ee7 / (r70 + r159))) > 17'h862)) >= (24'h4bd6 > $stime))) < (((((22'h38cf * r181) - ( + ( (r36 == r49)))) !== 18'h15e4) & r185) ^ ( ^ ( 19'h2b9c)))) == ( & ( r150))) == ( & ( r137)))); #10; r236 = ( ( + ( ((((((r148 || ( ( ~ ( ( - ( ( ~ ( r254)))))) != (6'h20 <= r133))) > 26'h163c) !== ( & ( (($time === r13) != 15'h637b)))) === 24'h7118) < ( + ( r42))) / r251))) ? (r43 % (6'h2 === ( + ( r209)))) : ($stime == ( + ( r82)))); #10; r35 = 32'h194c; #10; r242 = 12'h485; #10; r163 = r152; #10; r143 = (r53 >= ((r240 || 4'h8) / r146)); #10; r32 = r221; #10; r161 = (((((r79 || 17'h2a79) % $time) !== ($stime + (9'h164 > (r94 * 18'h8a0)))) | (((r104 ^ ((r190 > r53) + $time)) >= r217) > r32)) - r130); #10; r10 = ( & ( ((( ( ! ( r18)) > r102) & ((7'h2c > $time) || (r33 < ( ! ( ($stime - (((18'h2403 && (((2'h3 <= 7'h46) & r199) + (r138 == ( ( + ( (25'h643f !== 6'h1))) + r82)))) ^ (( ( + ( ( ! ( ((21'h2864 && 4'h9) || (22'h1c12 == 9'he3)))))) || ( ( - ( ((31'h23bf ^ 11'h44f) !== (21'h2257 || 20'h3d63)))) !== (r128 < ( ! ( (21'h49bf + 25'h936)))))) !== ((($stime ^ ( + ( (7'h52 != 23'h5ce2)))) * ((26'h33f0 | 2'h3) % ( ( ~ ( 24'hafc)) !== r32))) != (r219 == 28'h20f3)))) != r20))))))) | 16'h3a6a))); #10; r15 = (24'h31d2 != r30); #10; r210 = (r97 | ((8'h4 || r34) ^ (r72 == 11'h724))); #10; r214 = ((((( ( ~ ( ( ( & ( 23'h74ba)) > (r92 + (r77 + 4'h1))))) == r26) || ($time != ((12'heb1 < ( ^ ( ((17'h21be - ($stime >= ((r174 - r230) >= (((30'h1aa7 % 29'h622f) + ( ! ( 12'h297))) ^ (15'h4020 && r79))))) === r159)))) != $time))) * ((((13'h836 ^ ( ( | ( ((r120 && ( + ( ( + ( ((8'he + 30'h2a02) !== r44)))))) % 27'h4d2c))) | ( & ( (r238 | r214))))) !== (26'h327a != (4'h5 === ( ( ! ( ( & ( ( & ( (((13'h1896 & 22'h33) % ( + ( 29'h63e4))) + r148))))))) == $time)))) / r173) / ( - ( r12)))) / r109) && (23'h44f8 > ( ( ! ( $time)) + r205))); #10; r182 = ( ( ~ ( 28'h4852)) === 11'h1d2); #10; r11 = ( ^ ( ( ! ( (r142 && ( & ( ((r127 <= r51) - 32'h6ebd)))))))); #10; r221 = 9'h20; #10; r97 = ($time + (11'he8 != (( ( ! ( ($time ^ 2'h3))) % (((r175 - (31'h5de9 + 2'h2)) / r70) <= r189)) % ( ( | ( ((r1 || ( ( & ( (5'h11 >= ((7'h3c <= r198) > 16'h5796)))) | 28'h32a)) ^ ((r221 & (($time ^ ((((r220 % (20'h6874 + 4'h0)) !== r219) + 14'h1bd8) / 30'h7574)) + r251)) < (19'h11a4 > r61))))) === ( - ( (((r253 + 30'h72b5) < r68) && (((15'h6bf0 > r153) < $stime) !== 6'h20)))))))); #10; r205 = (((24'h1906 != (( ( ~ ( ( | ( ( - ( $stime)))))) == r74) / 18'h6640)) === r94) + (((27'h1683 == (14'h13fa < ( & ( r72)))) > r48) * (((((r173 == (4'hd | ((13'ha23 && 1'h1) <= ( ! ( (9'h1ea ? ( ~ ( 16'h4ec3)) : ( ( ! ( ( ~ ( (27'h3b76 == 18'h6606))))) * ( ( - ( (23'h3f36 ^ 27'h1521))) % r231)))))))) & ( ( - ( 14'he7b)) <= ( | ( ( - ( 12'h1d)))))) + r168) <= r217) >= $stime))); #10; r231 = (r213 | (((30'h7dd6 && r127) == (r109 | 29'h1794)) != r130)); #10; r150 = ( - ( $stime)); #10; r116 = (r139 > (( ( | ( r219)) <= (29'h25ec && ( ! ( 4'h9)))) / ( ( ~ ( r79)) > (r25 ^ 1'h1)))); #10; r56 = 24'h6d7b; #10; r214 = ( ! ( ( + ( r90)))); #10; r207 = 19'h5602; #10; r116 = ( ( + ( r130)) <= ( ( ^ ( 6'ha)) < r200)); #10; r220 = (((15'h5ceb + 6'h25) === ( ~ ( 11'h1dd))) < r161); #10; r10 = r63; #10; r63 = $time; #10; r214 = r201; #10; r225 = $stime; #10; r58 = r103; #10; r78 = ( ( ! ( ( ! ( r28)))) <= ( ( & ( ( ~ ( ( - ( (r165 && r66))))))) >= ( ~ ( 6'hd)))); #10; r243 = 1'h0; #10; r25 = ((((21'h9f5 == ((((r24 >= r227) || ( ^ ( (r63 === ( & ( (r92 >= 21'hc2d))))))) < (32'h71e6 % r124)) - 25'h51f4)) && ( ~ ( 5'h17))) != ((r138 || (8'h91 === ( & ( (( ( | ( ( | ( r186)))) | r196) !== r186))))) && r103)) + 12'h5cf); #10; r175 = (r171 * r99); #10; r193 = ( ~ ( 29'h5007)); #10; r141 = r64; #10; r22 = (5'h11 + ( - ( ((26'h2b69 ^ $stime) <= (((r129 < (((( ( ! ( 7'h23)) + (4'h5 === (6'h35 >= 24'h20d7))) || (( ( & ( r226)) & (16'h6572 >= (r173 ^ 18'h2888))) - $stime)) ? $stime : 15'hb3d) * ( ! ( ( | ( r3)))))) < (( ( & ( ((( ( - ( ( ( ~ ( r109)) % ( ^ ( ( + ( 2'h3))))))) >= ($stime < r136)) ? 7'h5b : ( & ( ( & ( (((18'h71e * 8'haa) <= (22'h651b - 26'h499e)) | r83)))))) === r134))) == (((20'h65de & (r227 % 7'h63)) > ( + ( r213))) >= ((9'h18b == 16'h7f14) && ((( ( | ( r78)) < ( ( ~ ( (27'h3ae8 + 31'h566b))) + ($stime >= (16'h55d9 % 17'h7bb4)))) < 28'h3f8b) <= ((r132 != (( ( ^ ( 29'h5761)) ? (6'h5 != 3'h5) : r21) !== r23)) === (2'h0 === r235)))))) == (r49 && ( ! ( 9'h11a))))) < r188))))); #10; r49 = ( ^ ( (((((25'h4e96 === r46) && r73) > ( ^ ( ( | ( ( ( | ( 10'h1b2)) & ((r159 - ( ( & ( r109)) / $time)) >= 14'h1323))))))) - r165) % (r28 > r247)))); #10; r4 = 30'h3703; #10; r165 = r95; #10; r39 = ( + ( (r224 == r178))); #10; r248 = $stime; #10; r209 = ((12'h657 | ($stime ^ ( ^ ( (r198 != ((22'h1825 + r140) === 26'h5d53)))))) == ( ~ ( (( ( & ( ((r21 % (($time | ( ( ! ( (r6 == (((21'h2c09 == 3'h5) == (4'h7 ? 18'h3c25 : 25'h3224)) !== (r13 !== (16'h68df <= 20'haf4)))))) % 9'hc5)) >= $time)) ? 8'hef : (r247 & (r180 ^ ((((16'h31e9 - ($stime & 10'h1bc)) && (18'h7f94 | ($time ? r16 : ((5'hb ? 29'h7896 : 19'h5aba) ^ (19'h52e0 === 1'h0))))) == (((24'h201f !== ( | ( ( ! ( 5'h1f))))) || ( ~ ( ( ~ ( r100))))) / ((r60 ? (r99 || (9'h6 ? 10'h2fe : 27'h72e7)) : (r234 <= (11'h74b % 30'h6ba6))) > ( & ( ((29'h4113 !== 29'h4226) && (5'h1e > 15'h3bb0))))))) != ( ( + ( ((1'h1 - 1'h1) >= (r31 * ($time ? 22'h7283 : (10'h25c == 1'h0)))))) & (r57 === (9'h1e9 < r56))))))))) >= 7'h17) != r163)))); #10; r1 = (r78 % r79); #10; r101 = ( ( ! ( (((r143 - 30'h78e0) / (14'h1c2e - (((( ( ~ ( 27'h5102)) !== 23'h5656) * ( + ( (r127 >= (((((31'h4150 == 9'h7f) ? (21'h40b0 >= 1'h1) : 20'h7e04) >= ( | ( 31'h6fed))) ? ( ( + ( r11)) && (15'h1543 && (8'h45 < 24'h382b))) : r189) > (r201 <= r171)))))) && ($stime > r42)) && ( & ( 14'h39ec))))) == r110))) === ((($time / ( - ( ( ! ( ( + ( 1'h1))))))) & r199) !== 12'h112)); #10; r111 = $time; #10; r58 = r34; #10; r1 = (21'h4628 & (r206 >= r167)); #10; r130 = (( ( ^ ( r212)) + r148) !== ((r51 !== ( + ( ( ~ ( ((8'h68 == $stime) > ( & ( $time)))))))) || 6'h0)); #10; r12 = (( ( & ( ( ( - ( (((r233 && (r155 || r64)) > (r224 != ((19'h1e80 * (24'h7122 & ( ( ! ( r79)) | (r81 >= r68)))) != 11'h3de))) ? ((r139 > (21'h58b4 < (($time - ($time | 1'h0)) === (((14'hf05 | 9'h90) ? (r180 - ( - ( ( ~ ( 4'h3))))) : ( - ( 12'h8e9))) >= ((9'h195 > ((13'h19a8 < 23'h5a73) && 7'h21)) && $stime))))) ^ r46) : ((r171 !== ((((9'h120 != (2'h0 % ( + ( r237)))) & ( ! ( 3'h6))) || (( ( & ( (31'h7 || 23'h777a))) !== ( - ( (r102 + (1'h0 + 26'h4b6a))))) & $time)) * r78)) !== ( ^ ( $stime)))))) != 13'haee))) ? r59 : (29'h3976 / r181)) % r221); #10; r246 = r187; #10; r122 = 32'h7516; #10; r63 = r192; #10; r68 = 21'h5966; #10; r221 = (( ( - ( (r154 === 2'h3))) && ( ( ~ ( ( - ( $stime)))) > $stime)) ^ ((27'h464f <= r132) < 24'h4012)); #10; r179 = r107; #10; r15 = 26'h1958; #10; r27 = (r197 != r242); #10; r251 = (2'h1 <= 7'h69); #10; r252 = (r50 <= r231); #10; r228 = r192; #10; r181 = r218; #10; r129 = ((r187 & (($time || (r85 > ( ~ ( r13)))) > 32'h2b02)) | ($stime !== ( ( ^ ( r164)) + ( ^ ( ( & ( ((((((( ( - ( 9'h133)) - r240) && 10'h1e0) <= 12'h481) >= ( ( ~ ( (r78 !== (r132 | r63)))) % ( + ( ( - ( ((r159 & ( & ( 29'h376e))) >= ((1'h1 || 30'h4e92) && (19'h1691 & 26'h2629))))))))) * (r200 == ((r202 > (((r83 % (14'h2086 == 12'h1ca)) > ( & ( r246))) <= (((6'h7 + 23'h27fb) ? (1'h0 !== 15'h3dbc) : $time) - (r117 <= (9'hcb != 19'h31ef))))) ? 2'h0 : ( ( - ( 8'hb7)) || r65)))) ? ((r92 != ( ( - ( ( ( ! ( 25'hc76)) && 17'h27e3))) >= ($time == (r196 ? (((19'h842 != 17'h44a4) && ( ^ ( 3'h3))) / r124) : 1'h1)))) * ( ^ ( r17))) : (10'h300 <= (($time | (r161 !== $time)) - r55))) & ( + ( ( + ( $time)))))))))))); #10; r69 = (( ( ! ( r209)) != 27'h73e0) / 30'h5ff5); #10; r36 = ( ^ ( (($stime % 22'h7f73) / ( ! ( (r60 / r187)))))); #10; r195 = r61; #10; r148 = ( ! ( ((r1 != r174) & r111))); #10; r61 = r232; #10; r86 = (11'h627 / (( ( | ( r110)) < ( ^ ( 25'he53))) > (((( ( & ( (20'h1ed3 - 4'h9))) < ( ^ ( ( & ( 15'h48a3))))) | ((r73 % r163) && (((($stime !== ((r195 || ((18'h61d8 | (2'h2 + 32'h6491)) ? ((9'h1bd & 21'hdab) * (16'h597b == 5'h15)) : 27'h1e00)) & r87)) ? ((16'h6477 | r71) > ( ( ! ( 17'h49a5)) == r179)) : (( ( - ( ( ( ! ( ( & ( 26'h2396)))) + (19'h3d37 & (30'h1edf === 18'h2788))))) && (((r165 != 14'h13b0) ? r203 : $time) >= (r242 + r68))) <= r147)) ? ( ~ ( $time)) : (r189 + r151)) >= 8'h98))) === 25'h4203) ? $time : ((29'h133a ^ ( - ( (r137 !== 6'h1d)))) || ((( ( + ( r50)) || ((r216 === 32'h7fe7) >= (9'h13d >= r229))) && ( + ( 19'h2336))) & r246))))); #10; r19 = (r85 | (24'h5e3d ^ ( ^ ( (r246 == (18'h6068 & ( & ( r152)))))))); #10; r4 = ( + ( $time)); #10; r152 = ((( ( - ( r140)) | ((1'h0 ? (1'h1 && r199) : (( ( + ( r212)) == r72) * ((r4 !== 5'h3) > (($stime >= 31'h742c) <= (13'h131c < r213))))) > (r246 || ((r116 < (((r189 < ( & ( ($stime === ( ( ^ ( r100)) | r189))))) !== ((r96 | ( ( ^ ( (r40 & r20))) * r167)) - (((r219 || 5'ha) === r185) != 20'h34fd))) | 17'h2d95)) + (( ( + ( (r114 % 25'hab5))) <= (( ( | ( r206)) || ( & ( ((18'h2670 & ( + ( ( & ( 14'h24d9))))) ? (14'h3df < (r253 | 19'h514e)) : (r5 * ((29'h88e != 15'h202c) <= (25'h7dd4 || 21'h4915))))))) === 7'h7d)) === 32'h2450))))) / r139) >= ( ^ ( ( ( ^ ( ( | ( 31'hc9a)))) >= 27'h5ce1)))); #10; r83 = r149; #10; r106 = (((r142 + (18'hff6 - r189)) ? ( & ( (r109 && 30'hb4f))) : ( - ( ( | ( ( | ( r115))))))) <= r180); #10; r227 = ( ! ( ( ! ( ($stime / ((r194 * 26'h6311) === ((r105 % r76) != ((r79 != (1'h0 || (((2'h3 >= ( ^ ( 4'h4))) - 23'h5b50) > r48))) ^ 27'h702)))))))); #10; r38 = r32; #10; r177 = (r151 ^ ( & ( r53))); #10; r132 = r245; #10; r135 = ( + ( (r141 - ((r169 != r178) !== ( | ( (r241 != ( & ( ((r102 & ( ~ ( ( ! ( r18))))) ^ r25)))))))))); #10; r121 = ( | ( 18'h61eb)); #10; r253 = (((r123 >= 13'h18f9) & 26'h1e42) === ( + ( (r185 < r245)))); #10; r58 = r52; #10; r1 = (( ( - ( 21'h3df1)) === r43) && r195); #10; r180 = ( ( | ( ( + ( 23'h51f6)))) | $time); #10; r147 = r50; #10; r212 = (r48 / ( | ( ( ( - ( ( & ( (r78 & r199))))) ^ (((r190 != ( & ( (r11 * (( ( - ( (($stime <= ((5'hd ? 11'h55e : 21'h7496) === (6'h23 % 15'h406b))) || r52))) / $time) > 18'h68f1))))) - ((($stime == r49) & r191) > (( ( ^ ( (13'h11e6 - 2'h0))) === (((8'h77 > ((( ( & ( 18'h6c31)) + r247) + (r154 < ( ! ( 15'h2dda)))) >= ( ( - ( $time)) ^ ((4'h0 * 19'h3e9c) | r11)))) != (r70 != ((((18'h2d84 != 2'h3) != r202) / ((29'hf27 !== 29'h5512) + r43)) !== (18'h1db < ( & ( r221)))))) / r255)) || ( + ( (r32 + (r106 - r168))))))) || $time))))); #10; r140 = (r210 - ((((r91 >= 25'h6118) & r15) >= $time) - (((((23'h4c9c ? r228 : ( ( + ( 27'h4433)) == (r117 == ((($stime | (($stime | ( & ( 23'h52a9))) === (r138 || r157))) === r106) * (r190 != $stime))))) | ( + ( r200))) - 28'h7a48) === 12'h1be) / ((r45 - ($stime + 4'h2)) != (( ( + ( (27'h7bf7 | (((27'h1e92 % 5'h17) ? 17'h4f68 : r240) >= ( + ( ( ( & ( ( - ( ((27'h6ca1 | 4'h5) ? (1'h0 ? 15'h551a : 19'h3554) : (2'h1 ^ 24'h62bd)))))) > ( ~ ( r248))))))))) ^ r123) * r183))))); #10; r116 = ((($time * (7'hd !== $stime)) >= 12'h528) + 2'h2); #10; r16 = r182; #10; r188 = ( - ( 15'haa4)); #10; r235 = ($stime ? ( ~ ( (30'h4340 > $stime))) : r134); #10; r206 = (21'h355e && 16'h3c42); #10; r32 = ( - ( (22'h3162 < ((r236 === 17'h4e9f) != ( ~ ( r231)))))); #10; r2 = 4'h4; #10; r227 = ( - ( ( ~ ( r70)))); #10; r123 = r227; #10; r52 = 11'h62c; #10; r187 = ( & ( (28'h554a !== r129))); #10; r15 = ( ! ( ( - ( ((14'h23b | ((24'h5d96 < ( ( ^ ( r81)) % ((26'h13a2 - (((10'h2d4 <= (((7'h1d < 23'h784b) <= 2'h0) <= r41)) % ( ( - ( r76)) >= (7'h54 || ((20'h667a * 7'h4a) != (16'h3c25 | 18'h732))))) ? (r125 ? ( ( ^ ( (r6 == (32'h1414 + 30'h61ef)))) & (r75 != 27'h17c1)) : (r157 - ($stime / ( ( ^ ( 1'h1)) ? ( ! ( 22'h5660)) : r112)))) : (r244 & ((1'h0 >= r112) === ((r203 >= r3) + ( ( | ( 12'h2a8)) < (30'h838 + 17'hb72))))))) - r84))) | ( ( ^ ( ((23'h151 / ( ( ~ ( ( ( ^ ( ((6'h29 - 11'h624) % $stime))) + ( ! ( ((32'h5711 ? 3'h6 : 28'h4941) % (19'haad === 12'h299))))))) + 14'h340c)) ^ 12'he4f))) !== r64))) | (( ( | ( ( ( ! ( ( ( & ( ( ( | ( ( | ( 9'h1a2)))) / ( ^ ( (11'h15b ? (r141 == $time) : ( | ( r242)))))))) == (24'h338 == r170)))) !== 20'h28f8))) <= (((r75 >= ( ~ ( ((( ( & ( 16'h5800)) && ( ~ ( r186))) & ((r215 / r60) <= (((32'h1ce6 | 15'h3e47) <= (1'h0 <= 29'h3f9c)) !== ((23'h5d5d <= 23'ha77) | (9'h20 < 22'h43a4))))) % ((9'h39 + r179) || r82))))) - ( ~ ( r243))) > $stime)) ? ((r105 > (r217 + 27'h2e68)) ? r223 : r81) : r31)))))); #10; r228 = r194; #10; r187 = 7'h29; #10; r109 = ( ( ^ ( ((13'h1f6 >= r210) + r112))) > r235); #10; r121 = 13'h5bb; #10; r213 = ((r30 * 18'h2845) === ( ! ( r237))); #10; r180 = ((r241 | (((r106 - (( ( + ( ( ~ ( ( + ( 28'he39)))))) !== ( - ( (($stime | ($stime != (((r139 % r97) !== r94) >= r251))) ^ r45)))) | r97)) === (r79 < ((r109 * 2'h0) !== ( & ( 27'h3293))))) / (((r238 + 15'h60cb) == ((( ( + ( ( | ( r65)))) <= ( & ( 29'h7fa4))) > (($stime | (((r24 < ( - ( 10'h116))) % ((($stime >= (14'h2dac | 4'h2)) / (5'h1 && (11'h68e != 12'hfd))) | r57)) - r252)) ? 30'h2533 : r239)) < r117)) === r175))) % 25'h5022); #10; r7 = (( ( | ( (15'h7910 && ( & ( (r66 <= r105)))))) < (29'h6770 % ( ^ ( r24)))) + (r27 - (($time * (( ( ~ ( ( ( & ( r72)) || ( ~ ( ((16'h613e ? (6'h18 + r105) : ((r58 ^ ( ( - ( 1'h0)) > (15'hd9d | 12'h8d8))) > ($time === r11))) + ((r60 + r170) >= (30'h109b ^ ( - ( ( + ( (19'h3346 ? 12'hf5 : 21'h2119))))))))))))) < 5'hf) - $time)) !== ( ~ ( ((r246 >= (((r90 - 14'h34ad) != ( | ( 25'h6134))) && ( ( ! ( ( ( | ( ( | ( (r152 | r232))))) | ( ~ ( (r196 || r35)))))) || ( - ( ( & ( ((r73 >= ( & ( $time))) || ( - ( (23'h1d25 !== ( + ( (20'h672d === 24'h194b)))))))))))))) == ( ( & ( r34)) !== (r30 / ( & ( (( ( ^ ( 17'h6d41)) ? ( + ( ( ~ ( (11'h77f || ((1'h0 - 31'h185d) == (28'h1b96 ^ 15'h2a2a))))))) : $stime) != ((19'h7835 == ( ! ( 32'h4eb6))) || ( ! ( (( ( ^ ( $time)) ^ ( + ( (16'h1f16 + 22'h17f)))) == r118))))))))))))))); #10; r21 = 24'h1fe8; #10; r145 = (( ( - ( 17'h64a4)) !== ((r131 > (r109 | ( ( ~ ( 14'hd50)) + (r228 !== (( ( ~ ( ((29'hc3f - (( ( | ( 27'h6286)) <= 18'h6b93) === 31'h2432)) && ($stime || ( ( | ( 23'h35a)) <= 32'h496))))) && r113) == r175))))) <= r252)) && r171); #10; r210 = ( - ( (r171 != (r235 > r32)))); #10; r212 = ( & ( ( ~ ( ((r90 != r45) & 11'h491))))); #10; r158 = ( - ( 14'h3cb)); #10; r152 = (r137 == ( & ( ( + ( ( ~ ( 18'h3802))))))); #10; r152 = r114; #10; r28 = (r72 % r210); #10; r69 = ( & ( ( ( - ( ( ~ ( (( ( ^ ( (((((22'h7b4e < ( ( & ( (7'hb > 31'h50d8))) ^ (4'hb / (17'h3b5d == 7'hf)))) & r220) % (8'h4e < ( ! ( 18'h2d17)))) - r130) * (16'h4fd5 * ((( ( ^ ( 24'h716d)) && ( ! ( r221))) >= $stime) == (31'h4a6f > ((r24 & ( ( ^ ( 30'h309)) <= (29'h475 == 28'h2d97))) >= ( & ( ((30'h151f <= 22'h6762) * 17'h646b)))))))))) - ( ( | ( r45)) * r211)) == ((r114 / $stime) === (21'h2915 != ( ~ ( ( ! ( $time))))))))))) == ((r197 || 27'h73e0) <= 14'h3d7)))); #10; r60 = (( ( | ( r187)) == ( ( - ( r55)) + (((11'h335 > (r232 != r5)) == (r89 ? ( ( | ( $time)) !== r6) : ((22'h6cc5 && (9'h161 <= $stime)) <= $stime))) <= r123))) / (((( ( ~ ( $stime)) >= ( | ( r221))) < ( - ( r115))) !== ( ( ! ( (( ( ^ ( (( ( & ( r95)) + (13'h49d < ( | ( 18'h1a82)))) !== ((r78 != (r34 >= ( ( ! ( (14'h588 | 16'h507))) && (1'h1 > 12'hbfd)))) && (r91 + r249))))) !== ( ^ ( ( ( | ( r205)) == r71)))) == 15'h113d))) === 32'h60ad)) / ( + ( ( - ( 15'h7b84)))))); #10; r213 = ( ( + ( 3'h0)) / (8'hc6 < r26)); #10; r27 = 19'h54d6; #10; r235 = (10'h2ce || (14'h18b5 * ((($stime & ( ( ~ ( ( ^ ( (((((r39 ? ($stime % 7'h68) : ( ( ^ ( 7'h38)) || (14'h99b % 24'h613f))) != (r116 < r163)) | r154) ? ( - ( 22'h2d1e)) : 12'hf49) - ((((((19'hee0 + 25'h4274) === r189) + 21'h1c66) * 25'h2b72) && ( ~ ( (( ( ~ ( 18'h4339)) & 6'h3e) % ( + ( (10'h218 | 19'h4ea1))))))) == ( ( - ( r117)) | ( ( | ( r118)) | (r63 !== ( + ( ( ~ ( 27'h3763))))))))))))) < r82)) & r142) == ( + ( (23'h74ab && ( ~ ( r108)))))))); #10; r3 = 24'h3a7b; #10; r60 = ( ( ! ( 22'h5ca)) | ( ! ( (r38 / (r0 ^ ((30'h7151 ^ ( ( + ( 1'h0)) ^ (4'hc || (r49 > (14'h1287 % ( | ( (3'h2 !== (((26'h1516 != 4'ha) + 19'h7343) < (r225 * ( & ( 27'h380d)))))))))))) < r55)))))); #10; r209 = $stime; #10; r88 = 30'h47b0; #10; r190 = ( ( - ( r25)) != (r230 % r145)); #10; r242 = (((r31 ^ r98) ^ (( ( | ( r110)) < ((( ( - ( ((( ( | ( (r147 != r193))) | 15'h2197) && ( ~ ( ((((9'h1b / 3'h6) - (16'h66b5 !== 13'h15aa)) <= (r188 || (24'h1e3f >= 30'h41da))) <= (r181 / ((11'h317 - 30'h7563) <= (32'h1a3a && 8'h20))))))) * $stime))) ? ( & ( ( & ( 21'h5bc5)))) : (3'h2 - 10'h332)) % r29) <= r182)) == r131)) ^ (24'h3d27 && (28'h3b13 !== 20'h1322))); #10; r227 = 23'h11c3; #10; r242 = ((21'h5910 == (19'h6d6f - ( ! ( ( | ( r100)))))) <= ( + ( (r208 - ( ( ^ ( ( & ( ( ~ ( r170)))))) / (((r216 && r115) != (r68 ? (1'h1 * r149) : 2'h3)) && r233)))))); #10; r178 = r186; #10; r44 = ( ( - ( r213)) && ((r59 % r72) / r65)); #10; r26 = ( - ( r97)); #10; r120 = $time; #10; r251 = r73; #10; r78 = 25'h4661; #10; r105 = ((27'h3d8e | r115) || 19'h65b7); #10; r212 = (11'h727 > r67); #10; r198 = r128; #10; r59 = ( + ( r140)); #10; r125 = 19'h6ff4; #10; r99 = ( ( + ( r41)) === 30'h295e); #10; r197 = r17; #10; r5 = (r172 === r139); #10; r252 = (((17'h64d7 ^ 4'hd) + ( ( | ( ((13'h19cb && r127) % ( + ( (25'h69d4 >= ( + ( 17'h956)))))))) > (((( ( ~ ( 18'h5835)) | ((((r63 | 22'h33eb) < 19'h7c40) | 22'h1c7e) % ( ( - ( (r77 >= ($stime ? 21'h1762 : (((4'ha > 14'h2fb0) < 16'h2d72) | ( - ( ( ! ( 32'h2f02))))))))) + ( + ( ( ( ~ ( (r60 ? $time : r244))) >= 28'h67c5)))))) <= (r106 & 32'h28a6)) != r242) / 6'h39))) == ( & ( 9'h1e2))); #10; r58 = r119; #10; r102 = 17'h597e; #10; r148 = r206; #10; r22 = (r194 ^ ( | ( 26'h249c))); #10; r133 = (((r34 | (20'h12d2 === r166)) != ($stime !== ( ^ ( (($time == r53) == ( - ( 4'h6))))))) !== ( ~ ( 5'h13))); #10; r182 = r102; #10; r165 = ((r60 / r30) % r33); #10; r20 = ( ( + ( r17)) != r90); #10; r102 = (((r105 - (20'h3e12 < 24'h5669)) > (((21'h12ed != ( ( | ( (r82 > ( ( ! ( ( & ( (r187 < ( + ( ((12'haa1 === 4'h8) + (32'h2954 % 11'h3be))))))))) + (21'h74de * 3'h4))))) - ( ~ ( 16'h6332)))) / ((r178 || ( - ( 30'h6f10))) | 31'h5072)) ? ( ( ~ ( (( ( ~ ( (r197 >= $time))) >= r254) > (r51 ^ 5'h5)))) !== ((((r82 > ((r40 != (r68 < ((((23'ha77 * 20'h39dc) * (31'h87c / 16'h5e84)) | (32'h666b % (13'haac >= 31'h757c))) === 6'h5))) || (r254 <= ((((7'h3c / r179) + r196) != r61) !== ((11'h27e - r0) <= (($stime >= r0) / 15'h2676)))))) !== r49) * ( - ( ((r106 && ( ~ ( 23'h50ed))) >= (11'h77e < ( ^ ( ( ~ ( 2'h1))))))))) !== $time)) : ((r242 >= ($time !== (r169 > (18'h129 == 32'h4fe8)))) < ( & ( (((32'h925 || r56) ? r180 : 18'h5ecc) === (( ( - ( 14'h23fa)) & (r203 == ( | ( (17'h78cf <= ( - ( (r223 | ((1'h1 < 14'h251f) ? 5'h1c : (28'h52ce >= 27'h1c52)))))))))) - r233))))))) <= (( ( ~ ( ( ^ ( ($stime / r49))))) + r27) !== $time)); #10; r21 = ((r8 ? 2'h1 : (( ( ~ ( (r82 + $time))) < r44) | r98)) / r188); #10; r4 = r126; #10; r91 = 11'h2c3; #10; r113 = 18'h3ed2; #10; r47 = r29; #10; r128 = ( ( | ( 9'h35)) ^ 27'h35ad); #10; r120 = r110; #10; r54 = ((r68 !== ( ! ( r28))) == (25'h571a & ( ( - ( ((r161 & 23'h6f59) !== ((r150 || 18'h6a2f) | 5'h19)))) || ( ~ ( ( ~ ( ( ( ~ ( $stime)) ^ r68)))))))); #10; r246 = ((23'h18f0 ^ r230) + ((((18'h4781 ^ r148) > (((r247 - 2'h3) == $stime) >= ((((r170 || (r209 !== ((6'h18 % r248) === r170))) > r2) || ((((4'h5 + ((( ( + ( 4'h9)) & (31'h206f <= 32'h74e0)) <= ($time / (12'ha4e !== 12'h1b8))) > $stime)) === ($time > (((r98 <= r156) | r171) || ( - ( ((2'h0 > 29'h52a5) - r155)))))) & (r80 ^ $stime)) == r118)) == ((r122 % ( ( ^ ( 9'h61)) === ( ^ ( ( & ( r57)))))) ^ ((((r168 || ((r149 > (r65 - ( | ( 16'h3096)))) >= $stime)) < ( | ( (20'h30d5 - r250)))) != (((( ( | ( 8'h72)) ^ r193) < ( & ( (17'h13cf ^ (18'h57e0 <= 5'h1d))))) * r163) * (9'h1ff === ($time | 29'h1f07)))) > ($stime || ( | ( ( ^ ( ($stime > (r182 >= $time)))))))))))) === ((32'h7235 + ( + ( r63))) != (25'h5617 !== r193))) > (26'h3b84 <= r37))); #10; r61 = ((( ( + ( ( - ( ( | ( (9'h123 < ((((r131 == $stime) !== r221) ^ $time) >= (26'h7d2b && (16'h4c88 === 28'h630e)))))))))) / (29'h2ad5 <= ( + ( ((r198 * ((r25 * (r33 + 4'h9)) <= r172)) != ((r173 >= 27'h16a3) < (r24 != 10'h27d))))))) & ($time / ($stime && ( + ( (23'h2212 ? (r86 <= ( ^ ( (10'h2f2 > (r126 / 30'hc28))))) : (r16 | ( - ( ( + ( (r0 <= (((14'h3e2f <= r129) < r115) !== ( - ( r156))))))))))))))) || 20'h118); #10; r132 = ( ^ ( r44)); #10; r100 = (r14 == ( | ( ((r236 != r163) & $stime)))); #10; r46 = (30'hc90 - r136); #10; r99 = (r38 + (r75 && ( ^ ( 1'h1)))); #10; r110 = ((5'h1c + 12'hd0d) ? (( ( ! ( r29)) | ( ~ ( (5'h4 < (8'h1a != 9'h11))))) == r103) : ( & ( ((((r69 & ( & ( ( & ( r222))))) % ((6'h39 < ( + ( 10'hd3))) === r11)) ? (r252 === 6'h25) : ( ^ ( (( ( ! ( 20'h774a)) | 30'h2641) | ( | ( (((5'h4 !== r29) == ((r204 ^ r33) || 14'h465)) > (r161 <= r169)))))))) >= r231)))); #10; r227 = (r186 ^ (($stime / ( - ( ((((30'h5a52 != (( ( ! ( 8'h49)) === (r202 | 8'h31)) == r148)) <= ( - ( (11'h388 & 11'h6fb)))) === r104) < r226)))) + 1'h1)); #10; r62 = 19'h4ab; #10; r231 = r234; #10; r111 = (r230 * $time); #10; r25 = $time; #10; r186 = ( ( ! ( ( | ( $time)))) ^ r243); #10; r235 = r235; #10; r38 = ( & ( (( ( ! ( ( ! ( 15'h298c)))) / (((r103 % (5'ha >= r102)) ^ 16'h6162) / 24'h2416)) < ( ( - ( r135)) && ( & ( r148)))))); #10; r49 = ((( ( ~ ( $time)) < (r116 % 23'h2cb1)) > (20'h4454 ? ( | ( (21'h198e | $stime))) : r116)) ^ (r55 ? r252 : ( ! ( (r154 ? ( ^ ( 16'h6adc)) : (23'h284 > (( ( - ( ( - ( 27'h2f79)))) <= r130) <= (( ( | ( ( ~ ( $stime)))) !== ((r25 ^ r1) === r199)) !== ($stime > ( ( & ( 23'h2b4)) < (r247 || 10'h190))))))))))); #10; r169 = (((r12 | r195) > $stime) * ( ( + ( ( - ( (r20 >= (13'h508 === 18'h11fc)))))) || ( ! ( 18'h2923)))); #10; r199 = $time; #10; r224 = ( ~ ( ((23'h4d5 & r216) && r228))); #10; r46 = 23'h79a5; #10; r94 = 6'h1e; #10; r46 = r181; #10; r103 = (( ( ~ ( (((8'he6 - r129) < ((r204 + (10'h139 % r112)) < r75)) | ((r96 >= 25'h4652) != (r216 * r46))))) > ( ! ( ((20'h7cc1 < 19'h1460) || r74)))) & r190); #10; r61 = ( ( & ( (r33 < (r53 <= r38)))) !== r135); #10; r12 = ( + ( (( ( ! ( $stime)) || 3'h7) + (( ( ~ ( (3'h4 + ((r189 ? (30'hc61 > ( - ( (7'h21 ? ((((29'h5467 | 3'h2) || (31'h2f57 >= 11'h760)) ^ ((4'h0 & 16'h5c22) * 7'h39)) === ( + ( $time))) : (21'h546f > (1'h1 | ( ( - ( 4'h5)) * ( - ( 26'h144))))))))) : ( ! ( r186))) === r251)))) + r49) | r241)))); #10; r173 = ( - ( r247)); #10; r65 = $time; #10; r57 = 10'h120; #10; r230 = ( ( ~ ( (r203 * r115))) ? r16 : ( ~ ( ( ^ ( r204))))); #10; r201 = (r58 <= r7); #10; r63 = r217; #10; r93 = (17'h70ab - ( ( ~ ( 5'hd)) ^ (( ( ~ ( ((( ( & ( ((17'h63e4 % ((((19'h70fc * 10'h1fa) === 23'h5ba5) - 25'h830) ^ r254)) - 1'h0))) != ( ^ ( (((( ( - ( r27)) & r177) % r226) / 8'h24) * r209)))) | 30'h1439) != 22'h7b4b))) / (r51 + r174)) <= ( + ( r65))))); #10; r243 = 8'heb; #10; r97 = ( ( & ( ((r126 % 15'h4856) < ( + ( r14))))) !== r25); #10; r233 = 18'h5ffb; #10; r157 = (r172 >= 29'h2fdf); #10; r22 = ( | ( 5'hd)); #10; r231 = r89; #10; r144 = 26'hd4f; #10; r83 = $stime; #10; r108 = 12'hbe2; #10; r45 = (r215 === (( ( + ( 30'h2e06)) <= r205) == (( ( | ( r142)) !== 13'h1108) == ( ( - ( ( ^ ( r253)))) == 31'h19c2)))); #10; r22 = r84; #10; r251 = ((( ( & ( ( ! ( r75)))) <= r183) * r79) < ((1'h0 !== 29'h11fc) !== r124)); #10; r216 = (r168 && ( + ( r70))); #10; r104 = (28'h322b ? $time : (r71 - ((r27 ? ( ( ! ( 18'h42a9)) < ($time === (12'hfca * (13'haae <= ( ( + ( ( - ( r86)))) + ( ( ^ ( 3'h3)) == r20)))))) : r86) | ((((22'h689 + ((11'h164 ? r93 : (31'h5fb0 / ( ~ ( ((((13'h228 === 30'h1aac) && (32'h6fa6 / 13'hce9)) - ((2'h0 & 14'h32e3) < (5'h5 > 9'h1f4))) && 14'h2bcb))))) % (17'h2ebf ? 2'h3 : ( & ( r237))))) <= ((r84 * ( ( | ( r121)) || r158)) * r54)) / ( ! ( r74))) != r209)))); #10; r195 = (r229 ^ (r139 - ( ( ! ( ( - ( r80)))) !== ((10'h17b >= (r243 > (r164 != 2'h1))) < 5'hd)))); #10; r234 = (r252 ^ (((r76 | r123) / r202) && r219)); #10; r235 = ( | ( r121)); #10; r163 = ( ( ! ( $time)) != (2'h3 ? r30 : (r38 % 26'h781f))); #10; r118 = ( & ( r48)); #10; r27 = ( | ( ( ! ( r110)))); #10; r226 = (r163 * 20'h3fca); #10; r170 = (r217 && r180); #10; r22 = ((r234 > 27'h2e9d) / 6'h35); #10; r158 = (1'h1 === 9'h122); #10; r83 = r244; #10; r189 = r11; #10; r233 = ( & ( (4'h6 <= (((r254 / r74) + (r104 < ((31'h6871 !== ( ( ^ ( (r235 === $time))) ? (($time % r158) && (23'h4695 > ( ~ ( 9'h165)))) : r225)) || (( ( + ( r138)) - r213) < (r43 ^ ( | ( r91))))))) >= ($time + (r186 ? 27'h3860 : r182)))))); #10; r29 = (((((5'hf + (r171 == $stime)) !== (30'h4076 === (((11'h1e2 <= (17'h234d || ( | ( 20'h6b6b)))) < r173) || 24'h400b))) | r90) % (22'h620b <= ((5'h4 * 19'h67f7) > r168))) & ( + ( $stime))); #10; r251 = r250; #10; r192 = r214; #10; r126 = r114; #10; r91 = (25'h4e2b + ((((r213 || ( ! ( (r79 % r144)))) !== (r251 ^ r127)) % 5'h1) == ( ( ^ ( 7'h2e)) * r254))); #10; r156 = 23'h3c0; #10; r224 = r158; #10; r255 = (( ( ! ( ( & ( ( | ( r88)))))) == r179) >= (r137 || 31'h4d5f)); #10; r69 = (((r77 || 15'h4f09) ^ ((( ( ~ ( ((r190 ? 4'h6 : ((r135 && ((r151 || 13'hb64) - ( ! ( (r38 % r115))))) != r54)) | ((((r8 + ( ( ~ ( ((22'h50de >= 4'h5) || (10'h3af !== 10'h188)))) < (((13'h8ac * 28'h65db) ^ ( - ( 32'h108))) - ((14'h13c7 == 28'h60f6) !== r253)))) < ($time - ((r11 & ( - ( (17'h29f6 == 25'h56c9)))) == (5'hb > r51)))) <= r88) < 15'h7b0f)))) * ( - ( r197))) & ( ( - ( r234)) >= ((((12'h529 < ((20'h486a <= (8'hbb == (r4 !== r114))) > ((r68 == 1'h0) - ((r172 ^ r108) >= ( ( ~ ( (22'h5e34 + 25'h35ec))) == r26))))) ? (r30 * ( ! ( (r65 != (((r105 | 3'h3) - ((3'h5 - 10'h315) - 25'h4df9)) | ((9'h1e6 ^ 21'h2aa2) - ((13'h17bb >= 21'h7f98) == $time))))))) : 17'h7c99) / ((r174 | ((r61 != (r233 == ( + ( ( ( | ( 20'h6357)) !== r173))))) != r219)) % (24'h6372 === ( | ( (((((15'h5a99 / 19'h2862) || (4'h0 & 28'h5982)) == r65) && $time) / (( ( + ( (12'h15f + 8'h97))) < r96) != (r100 <= (r142 >= 3'h3))))))))) * (( ( - ( (r30 !== ( | ( ((((2'h0 | 9'h61) && (14'h3841 && 11'h620)) !== (r236 / r38)) && r68)))))) & r95) ^ ( ~ ( r92)))))) < ( + ( (r76 === $stime))))) == ( ! ( ( ^ ( (((31'h5d2f >= r92) - (($stime >= r103) < ((r128 | 23'h22f1) % (20'h47b3 < ($time === ( | ( r180))))))) / 25'hb6e)))))); #10; r233 = ((r44 >= ( ! ( ( & ( (21'h38fd || (r106 % (r184 & ( ~ ( (r158 & r174))))))))))) / (7'h38 % (r100 & ((r11 - r201) ? (r130 + ( ^ ( $stime))) : (( ( ~ ( (1'h1 ^ r76))) - ( & ( (3'h0 >= ( ( & ( r50)) != ($stime | r49)))))) + (30'h6282 * 29'hfe6)))))); #10; r214 = (30'h1532 / ((((r137 && (r27 - $time)) | ((r222 >= ((r101 ? ( & ( (( ( + ( r93)) & ( ~ ( ( ~ ( ((12'ha8d && 10'h1b2) > r62)))))) + ( ~ ( r201))))) : r235) !== (($stime ^ ( | ( r92))) & (20'h3e39 > ((32'h39ff - (r181 === r17)) || r160))))) ^ (32'h4120 * ( - ( (22'h7d08 < ((32'h74fd != (( ( - ( 4'he)) >= ((23'h7cee <= r20) & ( + ( (20'h4711 / 32'h1bb6))))) + ((((21'h2fec === 13'hd08) === 7'h22) <= ( ( ! ( 17'h6a6)) == r109)) | ((9'h1c + (1'h0 | 29'h4e54)) >= $time)))) - 29'h5ff4))))))) !== r237) / 10'h256)); #10; r26 = (27'h3abb & ($stime * r112)); #10; r28 = (r212 < 4'hd); #10; r128 = r109; #10; r59 = $time; #10; r180 = r37; #10; r109 = 6'h10; #10; r80 = (r0 > r215); #10; r26 = 2'h1; #10; r185 = (7'h76 !== ((((r221 - (((r159 !== ( ~ ( 16'h110b))) || (r133 % $stime)) & (r66 - 30'h5f20))) !== 8'h99) - r170) == (25'h345f !== (r78 ^ ( ( + ( ( ^ ( ( - ( (r196 ^ $time))))))) !== (5'h1 && (10'hee - (19'h4256 ^ r246)))))))); #10; r146 = 26'h1c07; #10; r69 = ( + ( r129)); #10; r187 = (((r245 | ( & ( 6'h32))) == 28'h34e2) || r128); #10; r38 = $stime; #10; r233 = ( ^ ( 18'h57d6)); #10; r174 = (22'h93b !== 20'h10d4); #10; r150 = ( ( ^ ( r156)) && (((( ( | ( r211)) != r229) + (r249 - ((r17 ? ( + ( ( ~ ( (( ( ! ( ( & ( 31'h6a65)))) || r174) && r229))))) : (r109 - r100)) | (((31'h15d == (12'h2b & ( ( ! ( r246)) + $time))) <= r14) >= ((30'h34b2 != r120) - (((((r100 === (r251 ^ 22'h665)) ? ((19'h2712 || r233) - ((8'h17 * 32'h4a8) * (12'h98c % 11'h480))) : r56) > (r104 ^ r14)) - ( ~ ( ( - ( ( ( | ( (4'h2 !== 29'h34bc))) != ( & ( r57)))))))) >= ( ^ ( r63)))))))) && 7'h66) !== 14'h1b9f)); #10; r162 = r235; #10; r172 = (r216 > ($time > (28'h5158 % r196))); #10; r184 = (( ( - ( r45)) != (((r130 >= ( ! ( (r19 === $stime)))) > (14'h520 / ( ^ ( 15'h5fdb)))) && $time)) === ( & ( (r242 && ( ^ ( (((r120 * r148) <= ((r231 < r248) | r48)) != r187))))))); #10; r17 = 11'h50b; #10; r55 = (12'h425 !== $time); #10; r153 = r221; #10; r74 = 29'h4919; #10; r117 = r42; #10; r28 = $time; #10; r32 = (r204 ? ((r140 >= $time) > (r15 % ( | ( ((9'h109 * r58) * r240))))) : ( ( & ( ((5'h8 / r5) ? 3'h2 : r72))) > (3'h0 - ( ^ ( r104))))); #10; r11 = (r105 | ((r67 >= (((((11'h6cc == 20'h5279) - (((( ( ^ ( 2'h0)) >= (25'h262e % (((1'h1 ^ 4'h5) < (32'h34e3 + 32'h3f3f)) ^ r81))) !== (3'h1 - r162)) & ( ( + ( ( ! ( r171)))) === ((r95 && 3'h1) % 11'h241))) < $time)) / 14'h3e43) - r219) - 5'h0)) % ((22'h6f46 < ( ( ^ ( ( ! ( ((15'h4328 == (9'h7a < r234)) > r75))))) && r179)) && ( & ( (r174 * r120)))))); #10; r152 = ( ( & ( r53)) % (r193 - ((((r106 % r173) && r85) / $time) * ( - ( r82))))); #10; r181 = r166; #10; r189 = 23'h5062; #10; r129 = 12'h998; #10; r39 = 32'h51e9; #10; r16 = (($time % 12'h63f) + r134); #10; r223 = 12'h62; #10; r51 = (( ( ^ ( 9'h6b)) & ( ! ( (28'h7eb0 | (r13 > (((r131 % (r176 != ((21'h7647 === ((22'h4cf1 ^ r217) * ( ( + ( 15'h40e1)) / r15))) ^ r191))) / ($stime || ( ( & ( ( ( - ( 7'h51)) <= ((19'h3479 > ((11'h518 > 25'h3c63) | (11'h243 ? 14'h3d56 : 11'h19e))) == (((25'h42 == 29'h4a37) > r19) * r255))))) && r196))) % r91)))))) + r104); #10; r177 = (22'h187d + (23'h2808 < ((r46 >= ( - ( 8'hef))) & ((20'h68db != ( - ( r158))) + r185)))); #10; r194 = $stime; #10; r219 = r208; #10; r94 = r73; #10; r61 = ((r25 - 26'h3cec) && ( - ( (r171 & r51)))); #10; r249 = (17'h1cad > $stime); #10; r238 = (((r100 === r94) ? ((( ( + ( 31'h39d9)) == r226) === (r220 + $time)) === ( ^ ( ( ( ^ ( 20'h5654)) != ((r147 + ( | ( r163))) - $stime))))) : ((28'ha75 >= (19'h59e0 - 32'h11eb)) > 25'h2ad6)) > 6'h32); #10; r176 = r71; #10; r239 = ( & ( (r64 ? ( - ( 25'h3d72)) : r249))); #10; r34 = ((((((r153 == r230) && (( ( ^ ( ((r127 != (((28'h4dc6 != ( ! ( ( ! ( 18'h3da9))))) - ( ! ( ((9'h12e % 4'h0) <= (19'h2020 | 20'h2df2))))) & r166)) != 24'h3de8))) === (((r106 == ( ( & ( ( ~ ( r47)))) % ( ~ ( ((r127 || r121) - (r238 !== (1'h1 >= 17'h5887))))))) - ( & ( (12'h8b2 <= 17'hb10)))) + ( + ( $time)))) ? 19'h55b5 : ( | ( ( ^ ( ( ! ( (r147 ? (24'h3adc && 20'h2e20) : (r121 % ((( ( ~ ( 15'h1caa)) <= r178) <= (r238 ? ( ! ( 27'h4907)) : (27'h1b95 && 19'h699e))) <= r225))))))))))) / r224) / r141) != ( + ( r154))) * (( ( ^ ( r176)) + 1'h0) || r214)); #10; r195 = ( ( ! ( (20'h568d / ( ( | ( ( ( | ( (((r179 && ( ~ ( ( ( & ( ((14'h31b8 + 13'hab0) != 14'h758))) & ( ! ( 4'h6)))))) < (11'h7d9 % ( ! ( (21'h59ed != r91))))) - $stime))) + r10))) - r23)))) * 12'h86); #10; r198 = ((r185 == (24'h38c1 & (29'h636c != ( - ( (((r236 >= ( & ( r244))) >= ( ( - ( ($time & ( + ( r76))))) ? 17'h7d27 : ( - ( 28'h42b0)))) - ( + ( (19'hb62 === ((8'hc9 && ( ^ ( r143))) || (23'h13e0 !== (((17'h5c98 < r59) === (r141 >= ( ( ^ ( 27'h5389)) || (8'h5c != 10'h2ba)))) <= r136)))))))))))) < ((((23'h68e8 >= r212) ? (r115 < ( ( ^ ( ( ^ ( $stime)))) & (((((4'h7 ? ((r7 - $time) & (17'h6c4b > (26'h1d90 !== (22'h6c66 < 6'h2f)))) : 26'h1f77) >= (20'h5a16 > ( ^ ( ( ^ ( ((11'h2f1 > 10'h3f7) ^ ( - ( 32'h719e))))))))) - $time) == 24'h11e0) * ( ( + ( r122)) - 5'h6)))) : r221) >= ( | ( ( + ( (14'h2a24 - (16'h6dd0 >= 25'h1376))))))) > r54)); #10; r79 = (( ( + ( ( ( + ( (((((20'h5369 && r249) ? (((r87 == (((5'h0 ? 14'h2f85 : 14'h1dae) / 30'h3c96) !== ((18'h7d54 >= 27'h19b) / (32'h6e73 != 32'h6d1e)))) === 15'h25af) * ( + ( ( | ( (((24'h4069 !== 23'h5c26) && r36) && ( ! ( 29'h4aa6)))))))) : 9'h14e) / (9'h19b !== ( ( & ( $stime)) + 8'hb2))) || ((( ( | ( ((((26'h6ff8 ? 4'h9 : 10'h23d) ? (15'h1a1e || 17'h6cd9) : (11'h689 === 9'h1ac)) != 24'h16e8) == ( ( + ( r140)) & $time)))) & (30'h3029 > (4'ha * (r208 * ((8'h8b <= 27'h63d4) < r215))))) * (r123 > 3'h3)) | (27'h527f + r177))) + (19'h722e <= 6'h27)))) | (r183 >= ((7'h6a % ((10'h9e !== (r8 || ( ( ~ ( (r75 == (r104 !== ( & ( 7'h23)))))) != ((r222 / ( | ( 26'h1023))) !== $stime)))) > (r255 | $stime))) % ( ! ( 23'h34ec))))))) == (( ( - ( 21'h6210)) * r195) !== ((28'h4979 > r232) | r22))) ^ (r125 * (r212 ^ (r10 != (((r201 >= 9'h39) < (( ( ~ ( (31'h2ca8 && ((18'h7958 - (((31'h50bf == 7'h73) === (10'h184 < 7'h0)) || ( & ( r100)))) + 17'h3580)))) >= ((r69 !== (r86 - (( ( & ( $time)) | ( & ( ( - ( 22'h5f1b))))) > ( ~ ( $time))))) ? 29'h6b06 : ((r236 >= 1'h1) < r25))) && 19'h2808)) === $time))))); #10; r100 = (((r202 <= ( ~ ( r244))) == (r147 ? ( ( & ( (( ( | ( r167)) == r42) == r141))) + ( ( + ( ( + ( (((r254 ? $time : 18'h1c54) | r79) >= ((r25 === r206) != (r38 % r148))))))) * (7'h67 >= r127))) : ( + ( ((( ( + ( (12'h4f9 !== ( | ( r221))))) == ((r156 && (11'h216 | (((22'h66d5 || ((22'h1dd4 - 25'hd54) & (26'h133f | 12'h270))) * ( ( ! ( (23'h6438 > 6'h5))) ? ( ( - ( 7'h7b)) & r203) : ((23'h5cb4 ^ 28'h1157) <= (32'h4b39 + 23'h3ce5)))) <= (((30'h76b5 ? r69 : (24'h216b != 28'h41db)) | ( + ( r123))) * ($stime !== ((28'hf8e >= 22'h7349) > r202)))))) ^ ((r9 != r99) || ( & ( (r224 >= r134)))))) || r56) ^ r235))))) ? r79 : ( ( ^ ( ((15'h2d1e !== ((((5'h11 >= $stime) | 6'h2a) * ((27'hfa0 < ( ~ ( ( | ( ( ~ ( r156))))))) & (11'hb2 * r48))) === r166)) == ( + ( (((r136 || ( + ( ((( ( - ( 5'h1b)) == ( ( + ( (19'h2300 / 10'h2df))) <= 2'h0)) ^ ( ( ! ( ( - ( 10'hd2)))) / (((27'h3b64 * 16'h3f17) - (10'h3d4 | 5'h18)) == r74))) * r112)))) < 28'h4d35) * ( | ( ( ( ! ( (29'h355f <= ( ! ( r124))))) | ((r221 | ( - ( ((r23 + r167) > ( ! ( r106)))))) % r22)))))))))) ^ ( ! ( ((r246 & 27'h151c) >= 5'h1e))))); #10; r54 = 10'h1cf; #10; r51 = ((r132 >= ( | ( (r228 && 24'h35b3)))) / 3'h7); #10; r43 = (r28 > ( - ( (r24 % ((r100 & (r249 % r181)) ? 28'h6c6d : (26'h6a62 && (r47 > ((13'haae != (r63 == ( ! ( ((((r48 || 4'h4) ^ (r249 >= (18'h3348 ? 30'h2e36 : 23'hf79))) / ( & ( r72))) ^ ((r147 || (r217 >= (29'h77b4 >= 14'h585))) >= ( ^ ( 10'h1ba)))))))) % ((( ( + ( ( - ( $stime)))) | $stime) > 30'h2161) % ($time % (( ( ~ ( ( & ( 5'h3)))) == r206) || r203))))))))))); #10; r49 = ( + ( (( ( ^ ( (32'h73e8 <= ((13'h372 < ((r196 / ( ! ( ( ( - ( (r29 / (17'h609c && 6'h2f)))) / r103)))) && ((r245 + 21'h5feb) === (r195 < (r240 % ((((23'h27da + 26'hc96) == ( & ( 25'h7a84))) >= ( ( - ( 29'h33a4)) !== (5'he * 3'h0))) % (( ( + ( 1'h0)) ^ (18'h6e7e != 30'h3fba)) & $stime))))))) * 16'h88f)))) * 10'h3fb) < ((($stime % 26'h3cd3) * ((((r63 !== 32'h1ea4) + (13'hd6c != 3'h4)) < (($time > 31'h6440) + ((r51 && ( ( ! ( r108)) == (r28 % 10'h25e))) ^ r75))) - 22'h20d8)) & 10'h396)))); #10; r248 = 23'h1af5; #10; r125 = 17'h1787; #10; r156 = $time; #10; r200 = (($stime ? 20'h295e : r19) != r135); #10; r209 = (( ( ~ ( (((((r97 + r9) - 12'h97a) - r11) > ((((r69 == ( ~ ( (r37 / ( & ( (((26'h2658 == 3'h1) && (12'h375 && 11'h76f)) * r35))))))) != 10'h290) % (r169 && ( ! ( ( + ( (($time % (r31 % (r216 | (13'h4f9 * 11'hd9)))) / r216))))))) * r94)) / (r8 + r209)))) < 1'h0) > ( | ( r166))); #10; r165 = (9'hd2 - r156); #10; r126 = 7'h15; #10; r90 = ((r171 != ( ( ~ ( ((((20'h4f9f <= (r116 & r103)) >= ((r111 % 15'h61e6) == r145)) == $stime) == 29'h475b))) && ( - ( (r207 ? r100 : ( ( - ( ( ! ( 9'hd0)))) / ( | ( $time)))))))) / r85); #10; r82 = 26'h4010; #10; r112 = r191; #10; r222 = 9'h31; #10; r185 = (( ( ~ ( ( & ( ($stime != (( ( | ( (1'h1 ^ $time))) != r163) < (((r136 === (r43 % $stime)) == r192) <= ( + ( (r211 ^ (20'h60aa != ( ^ ( (( ( ^ ( (4'h1 <= 20'h42af))) ? ( ! ( (1'h1 - 16'h105))) : (16'h18a6 && 10'h379)) | r63)))))))))))))) && (r71 ^ 30'h3a7e)) >= r52); #10; r63 = (( ( ! ( 19'h71d2)) || r72) && r82); #10; r67 = r122; #10; r201 = (r110 ^ ( | ( ($stime ? ((r117 - 4'h5) && ( ( - ( (r35 / (18'h7494 == (22'h463d % ( & ( 22'h302e))))))) / (r141 % ((4'h2 | (r78 * 19'h741d)) <= ( + ( ($stime != 16'h441e))))))) : r252)))); #10; r14 = 8'h25; #10; r227 = ( ( ! ( (((( ( ! ( (((12'ha44 - 13'h5b3) ? ((r235 || ((((8'he9 ? 27'h1dce : 10'h4a) !== ( - ( 32'h4efe))) !== 24'h5642) > r86)) <= (7'h76 % ((((5'h1e | 28'h60ab) != (13'hd0a + 21'h76b8)) === ((19'h402 % 20'h77e0) || r205)) + r145))) : r242) == ( ! ( ( ( | ( ( | ( (r120 <= ( ( & ( 8'h25)) - $time)))))) > ( | ( ( ( - ( r5)) ? 11'h276 : ( ( ^ ( 31'hbc7)) <= r90)))))))))) - ( - ( (((( ( + ( r232)) && $stime) & $time) * r150) ? r41 : ( | ( ((18'h22f3 / 4'h6) == (r76 ? ( ( | ( ($stime && (5'h18 <= 12'h483)))) & $stime) : ((((9'h54 <= 32'h2f44) | (3'h5 <= 16'h57af)) > 30'h3427) < $time))))))))) - (( ( | ( ( ( ~ ( ( ! ( ((r235 > r232) ^ ( ^ ( ( | ( ( - ( 3'h0))))))))))) && r240))) + r116) - ( ( ^ ( ( ! ( r19)))) % (r176 != r71)))) ? (r82 != 19'h5d16) : ((((r247 + (r124 - ((10'h13b > r155) === (r73 / $stime)))) < r246) / ((r9 - r190) + ((r25 ^ ((25'h720b / ( ( | ( ((19'h3f50 && 4'h8) & (30'h1773 || 5'h13)))) > (r150 | 19'h5393))) || ((r12 >= (((17'h434d === 8'hd9) * 29'h5a0b) > r21)) & r129))) * ( ( - ( r99)) == r227)))) < (22'h791f <= 5'h1b))) + r18))) && ((8'h71 == 3'h7) !== r85)); #10; r112 = $stime; #10; r9 = ( ^ ( (r91 !== ( + ( ((r23 >= r175) | (((14'h144a + ((3'h6 * (r67 || ((( ( | ( (2'h2 != 22'h5093))) && 17'h18af) + (32'h3d27 > 9'h11)) - (((12'h474 && $time) != ((13'h1f06 * 4'he) == (6'h20 + 20'h106))) ? ( ! ( ( & ( ( - ( 18'h7b24)))))) : r173)))) != 6'h15)) + 4'h1) & $time))))))); #10; r143 = 14'h2865; #10; r123 = 6'h3d; #10; r68 = (10'h296 * ( ^ ( ( ( + ( ((((((26'h6a45 - ( - ( ((27'h5a8b ^ (r216 || (19'h67a3 + 16'h4b36))) ^ ( + ( 2'h3)))))) && 14'h1816) || r144) * ( - ( r153))) / r192) ^ ((r128 * r13) & ( | ( r212)))))) != ((11'h5f0 ^ 9'h17e) == ((27'h62f3 > r48) | r84)))))); #10; r233 = r38; #10; r11 = r39; #10; r138 = (( ( - ( 25'h745)) === (23'h560d >= ( | ( ( ~ ( r208)))))) ^ (((r193 % r112) % (25'h2df3 === 30'h2e15)) || r198)); #10; r122 = 24'h62ec; #10; r255 = 24'h4ba0; #10; r107 = (((r202 || ((19'h6de4 | 18'h4463) | (7'h7 + (2'h0 % ( - ( ( ! ( ( ( ^ ( (r46 !== ((29'h1a74 ^ ( ( - ( 7'h69)) != ( ! ( 15'h777)))) - (((9'h90 / 29'h787c) && (29'h2626 !== 10'h11c)) | (5'hb == ( ! ( 14'h2aec)))))))) || r224))))))))) <= ((($stime % r96) || (( ( & ( ( ( ^ ( ((((((8'hc5 < 30'h3fbc) ? r59 : (26'h6bb6 !== 20'h4c53)) & ( ( ~ ( 32'h1e0d)) != ( - ( 14'h85c)))) !== ((r245 ? 18'h5cb8 : (6'h8 | 31'h321c)) != ((15'h260b - 18'h4db3) >= (18'h4dd >= 16'h703b)))) % r225) < r158))) + 22'h6c04))) >= (r216 + $time)) ? (((r243 | ( ~ ( ( ^ ( 3'h4))))) < ((((26'h5eda ? $time : (r243 + 32'h15fb)) != 31'h1d73) < ((r52 <= r10) < (((31'h5a7c === (r163 & (10'h2e4 >= 29'h1549))) || r119) != ($time !== r184)))) || ( ^ ( ( ( ~ ( (((12'h669 ^ (25'h5139 | 22'h54d2)) & r123) !== 7'h56))) != r7))))) / (r81 | 8'h39)) : ( ! ( r60)))) ? ( ^ ( r135)) : r94)) / 21'h5e3f); #10; r80 = ((r16 ? r183 : ($time <= r178)) / ( + ( ( ( | ( ((r54 !== r222) + (( ( ~ ( ( + ( 3'h3)))) && ((((((( ( ! ( 2'h1)) != (23'h4dc1 || 25'h6418)) & ((15'h3134 + 2'h1) * (4'h4 ? 29'h7aeb : 24'h1db3))) || r131) < r248) + ($time & ( | ( r78)))) | ((((8'he9 || ((28'h64f2 != 31'h5ecb) == (5'h10 !== 16'h7020))) || (((20'h1b88 % 27'h7c75) - (1'h0 === 5'h0)) % ( | ( (12'h4b9 & 19'h5c3b))))) - (17'he76 <= 2'h3)) / ( ~ ( r73)))) <= (17'h386e | (r194 % ( - ( ( ! ( ($time - r125))))))))) > 15'h7f04)))) === 13'h1828)))); #10; r37 = (($stime == ((r41 !== ( | ( 27'h1da6))) === (r35 === ( & ( 27'h2564))))) || ((16'h512e ? r184 : $stime) & 25'h56a4)); #10; r96 = ( - ( ( ~ ( r31)))); #10; r246 = $stime; #10; r251 = 28'h62ae; #10; r143 = r4; #10; r123 = (r86 - $time); #10; r65 = r247; #10; r188 = r248; #10; r89 = ( ( & ( r73)) & r43); #10; r185 = 1'h1; #10; r45 = (( ( | ( ( ^ ( 24'h1a2d)))) !== r2) <= ( + ( 22'h7447))); #10; r92 = (($stime % ( ^ ( (((r236 ? (((((10'h240 ? 22'h7a0d : r163) * 20'h71a2) >= ( ( - ( r186)) < ((r104 * (((27'h7436 === 20'hbfb) || (13'h1d62 | 26'h6221)) != ((29'h823 && 6'h34) ^ r170))) % ( ( - ( r11)) % (((32'h611e / 31'h3c4c) + ( & ( 20'h30a4))) - ((12'h85b == 26'hfd9) < 22'h74bb)))))) | (24'h4b4e > ( ! ( ( | ( (( ( + ( (29'h63b9 >= 31'h5396))) < (28'h24a0 & (4'h5 | 6'h1c))) | ( - ( ((13'h6a7 & 5'h3) >= ( | ( 1'h0)))))))))))) % (r164 === r50)) : 13'h25d) == 19'h4390) || r105)))) | r180); #10; r23 = (5'h5 ^ ( ! ( $stime))); #10; r8 = ($time ? (32'h605f >= ((r233 > ( ~ ( ( ( ^ ( (r28 * 26'h48ea))) ^ (((16'h617e & (10'he4 / r234)) ? 29'h1e10 : ( ( & ( 11'h22)) | $stime)) * ( | ( ( - ( ((r200 | r159) == ((r226 < ((22'h50da ^ r22) >= (19'h5845 > ( + ( 16'h3e29))))) !== (( ( ! ( (29'h34fe && 6'hc))) !== ((26'h35c4 < 20'h5230) * (30'h14f8 === 6'he))) < (((10'hc9 >= 12'h616) / (24'h6357 ^ 29'he15)) >= 31'h2b58))))))))))))) - ( ( ^ ( 10'h2af)) == ((32'h50d6 < 24'h30c0) > 22'h570e)))) : r232); #10; r245 = (r165 === (r147 === r18)); #10; r57 = ( - ( r200)); #10; r208 = ( | ( (r75 > 5'h2))); #10; r153 = ( + ( r49)); #10; r80 = ( ( - ( (r204 === ((4'h8 <= 14'h3eda) / r161)))) % ( ( | ( 17'h27bf)) != r40)); #10; r230 = ((r196 & ((28'h44ec / r235) - ( ( | ( r84)) ^ ( | ( r199))))) & ( ( - ( (r215 % ((21'h63b8 < (r247 || ((9'h1b4 - 5'he) ? r129 : (((7'h48 / r63) < 30'h6df7) <= $time)))) - (r161 <= r141))))) == $time)); #10; r58 = r227; $displayb("r0 = ",r0); $displayb("r1 = ",r1); $displayb("r2 = ",r2); $displayb("r3 = ",r3); $displayb("r4 = ",r4); $displayb("r5 = ",r5); $displayb("r6 = ",r6); $displayb("r7 = ",r7); $displayb("r8 = ",r8); $displayb("r9 = ",r9); $displayb("r10 = ",r10); $displayb("r11 = ",r11); $displayb("r12 = ",r12); $displayb("r13 = ",r13); $displayb("r14 = ",r14); $displayb("r15 = ",r15); $displayb("r16 = ",r16); $displayb("r17 = ",r17); $displayb("r18 = ",r18); $displayb("r19 = ",r19); $displayb("r20 = ",r20); $displayb("r21 = ",r21); $displayb("r22 = ",r22); $displayb("r23 = ",r23); $displayb("r24 = ",r24); $displayb("r25 = ",r25); $displayb("r26 = ",r26); $displayb("r27 = ",r27); $displayb("r28 = ",r28); $displayb("r29 = ",r29); $displayb("r30 = ",r30); $displayb("r31 = ",r31); $displayb("r32 = ",r32); $displayb("r33 = ",r33); $displayb("r34 = ",r34); $displayb("r35 = ",r35); $displayb("r36 = ",r36); $displayb("r37 = ",r37); $displayb("r38 = ",r38); $displayb("r39 = ",r39); $displayb("r40 = ",r40); $displayb("r41 = ",r41); $displayb("r42 = ",r42); $displayb("r43 = ",r43); $displayb("r44 = ",r44); $displayb("r45 = ",r45); $displayb("r46 = ",r46); $displayb("r47 = ",r47); $displayb("r48 = ",r48); $displayb("r49 = ",r49); $displayb("r50 = ",r50); $displayb("r51 = ",r51); $displayb("r52 = ",r52); $displayb("r53 = ",r53); $displayb("r54 = ",r54); $displayb("r55 = ",r55); $displayb("r56 = ",r56); $displayb("r57 = ",r57); $displayb("r58 = ",r58); $displayb("r59 = ",r59); $displayb("r60 = ",r60); $displayb("r61 = ",r61); $displayb("r62 = ",r62); $displayb("r63 = ",r63); $displayb("r64 = ",r64); $displayb("r65 = ",r65); $displayb("r66 = ",r66); $displayb("r67 = ",r67); $displayb("r68 = ",r68); $displayb("r69 = ",r69); $displayb("r70 = ",r70); $displayb("r71 = ",r71); $displayb("r72 = ",r72); $displayb("r73 = ",r73); $displayb("r74 = ",r74); $displayb("r75 = ",r75); $displayb("r76 = ",r76); $displayb("r77 = ",r77); $displayb("r78 = ",r78); $displayb("r79 = ",r79); $displayb("r80 = ",r80); $displayb("r81 = ",r81); $displayb("r82 = ",r82); $displayb("r83 = ",r83); $displayb("r84 = ",r84); $displayb("r85 = ",r85); $displayb("r86 = ",r86); $displayb("r87 = ",r87); $displayb("r88 = ",r88); $displayb("r89 = ",r89); $displayb("r90 = ",r90); $displayb("r91 = ",r91); $displayb("r92 = ",r92); $displayb("r93 = ",r93); $displayb("r94 = ",r94); $displayb("r95 = ",r95); $displayb("r96 = ",r96); $displayb("r97 = ",r97); $displayb("r98 = ",r98); $displayb("r99 = ",r99); $displayb("r100 = ",r100); $displayb("r101 = ",r101); $displayb("r102 = ",r102); $displayb("r103 = ",r103); $displayb("r104 = ",r104); $displayb("r105 = ",r105); $displayb("r106 = ",r106); $displayb("r107 = ",r107); $displayb("r108 = ",r108); $displayb("r109 = ",r109); $displayb("r110 = ",r110); $displayb("r111 = ",r111); $displayb("r112 = ",r112); $displayb("r113 = ",r113); $displayb("r114 = ",r114); $displayb("r115 = ",r115); $displayb("r116 = ",r116); $displayb("r117 = ",r117); $displayb("r118 = ",r118); $displayb("r119 = ",r119); $displayb("r120 = ",r120); $displayb("r121 = ",r121); $displayb("r122 = ",r122); $displayb("r123 = ",r123); $displayb("r124 = ",r124); $displayb("r125 = ",r125); $displayb("r126 = ",r126); $displayb("r127 = ",r127); $displayb("r128 = ",r128); $displayb("r129 = ",r129); $displayb("r130 = ",r130); $displayb("r131 = ",r131); $displayb("r132 = ",r132); $displayb("r133 = ",r133); $displayb("r134 = ",r134); $displayb("r135 = ",r135); $displayb("r136 = ",r136); $displayb("r137 = ",r137); $displayb("r138 = ",r138); $displayb("r139 = ",r139); $displayb("r140 = ",r140); $displayb("r141 = ",r141); $displayb("r142 = ",r142); $displayb("r143 = ",r143); $displayb("r144 = ",r144); $displayb("r145 = ",r145); $displayb("r146 = ",r146); $displayb("r147 = ",r147); $displayb("r148 = ",r148); $displayb("r149 = ",r149); $displayb("r150 = ",r150); $displayb("r151 = ",r151); $displayb("r152 = ",r152); $displayb("r153 = ",r153); $displayb("r154 = ",r154); $displayb("r155 = ",r155); $displayb("r156 = ",r156); $displayb("r157 = ",r157); $displayb("r158 = ",r158); $displayb("r159 = ",r159); $displayb("r160 = ",r160); $displayb("r161 = ",r161); $displayb("r162 = ",r162); $displayb("r163 = ",r163); $displayb("r164 = ",r164); $displayb("r165 = ",r165); $displayb("r166 = ",r166); $displayb("r167 = ",r167); $displayb("r168 = ",r168); $displayb("r169 = ",r169); $displayb("r170 = ",r170); $displayb("r171 = ",r171); $displayb("r172 = ",r172); $displayb("r173 = ",r173); $displayb("r174 = ",r174); $displayb("r175 = ",r175); $displayb("r176 = ",r176); $displayb("r177 = ",r177); $displayb("r178 = ",r178); $displayb("r179 = ",r179); $displayb("r180 = ",r180); $displayb("r181 = ",r181); $displayb("r182 = ",r182); $displayb("r183 = ",r183); $displayb("r184 = ",r184); $displayb("r185 = ",r185); $displayb("r186 = ",r186); $displayb("r187 = ",r187); $displayb("r188 = ",r188); $displayb("r189 = ",r189); $displayb("r190 = ",r190); $displayb("r191 = ",r191); $displayb("r192 = ",r192); $displayb("r193 = ",r193); $displayb("r194 = ",r194); $displayb("r195 = ",r195); $displayb("r196 = ",r196); $displayb("r197 = ",r197); $displayb("r198 = ",r198); $displayb("r199 = ",r199); $displayb("r200 = ",r200); $displayb("r201 = ",r201); $displayb("r202 = ",r202); $displayb("r203 = ",r203); $displayb("r204 = ",r204); $displayb("r205 = ",r205); $displayb("r206 = ",r206); $displayb("r207 = ",r207); $displayb("r208 = ",r208); $displayb("r209 = ",r209); $displayb("r210 = ",r210); $displayb("r211 = ",r211); $displayb("r212 = ",r212); $displayb("r213 = ",r213); $displayb("r214 = ",r214); $displayb("r215 = ",r215); $displayb("r216 = ",r216); $displayb("r217 = ",r217); $displayb("r218 = ",r218); $displayb("r219 = ",r219); $displayb("r220 = ",r220); $displayb("r221 = ",r221); $displayb("r222 = ",r222); $displayb("r223 = ",r223); $displayb("r224 = ",r224); $displayb("r225 = ",r225); $displayb("r226 = ",r226); $displayb("r227 = ",r227); $displayb("r228 = ",r228); $displayb("r229 = ",r229); $displayb("r230 = ",r230); $displayb("r231 = ",r231); $displayb("r232 = ",r232); $displayb("r233 = ",r233); $displayb("r234 = ",r234); $displayb("r235 = ",r235); $displayb("r236 = ",r236); $displayb("r237 = ",r237); $displayb("r238 = ",r238); $displayb("r239 = ",r239); $displayb("r240 = ",r240); $displayb("r241 = ",r241); $displayb("r242 = ",r242); $displayb("r243 = ",r243); $displayb("r244 = ",r244); $displayb("r245 = ",r245); $displayb("r246 = ",r246); $displayb("r247 = ",r247); $displayb("r248 = ",r248); $displayb("r249 = ",r249); $displayb("r250 = ",r250); $displayb("r251 = ",r251); $displayb("r252 = ",r252); $displayb("r253 = ",r253); $displayb("r254 = ",r254); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/comp1001.v000066400000000000000000002125401435245347300201750ustar00rootroot00000000000000// // Copyright (c) 2000 Paul Campbell (paul@verifarm.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module compl1001; reg [104:86]r0; reg [261:230]r1; reg [101:78]r2; reg [216:215]r3; reg [140:123]r4; reg [70:53]r5; reg [150:150]r6; reg [143:133]r7; reg [261:239]r8; reg [228:211]r9; reg [273:244]r10; reg [42:21]r11; reg [137:130]r12; reg [103:96]r13; reg [257:239]r14; reg [230:205]r15; reg [216:212]r16; reg [64:40]r17; reg [156:155]r18; reg [103:94]r19; reg [216:204]r20; reg [170:165]r21; reg [25:22]r22; reg [125:105]r23; reg [57:32]r24; reg [261:250]r25; reg [32:13]r26; reg [251:246]r27; reg [210:209]r28; reg [121:119]r29; reg [57:55]r30; reg [255:253]r31; reg [196:174]r32; reg [26:26]r33; reg [216:215]r34; reg [238:224]r35; reg [212:207]r36; reg [32:11]r37; reg [89:60]r38; reg [246:237]r39; reg [50:25]r40; reg [43:29]r41; reg [94:66]r42; reg [235:222]r43; reg [213:190]r44; reg [102:81]r45; reg [211:208]r46; reg [108:91]r47; reg [189:188]r48; reg [97:84]r49; reg [108:90]r50; reg [124:116]r51; reg [113:92]r52; reg [278:254]r53; reg [98:94]r54; reg [43:42]r55; reg [191:178]r56; reg [230:211]r57; reg [250:233]r58; reg [236:229]r59; reg [65:34]r60; reg [155:132]r61; reg [32:18]r62; reg [253:253]r63; reg [243:215]r64; reg [133:109]r65; reg [133:124]r66; reg [66:51]r67; reg [94:75]r68; reg [31:23]r69; reg [230:214]r70; reg [75:55]r71; reg [209:196]r72; reg [200:181]r73; reg [101:92]r74; reg [43:34]r75; reg [228:211]r76; reg [171:169]r77; reg [112:86]r78; reg [257:252]r79; reg [214:214]r80; reg [279:254]r81; reg [149:149]r82; reg [80:53]r83; reg [140:117]r84; reg [265:238]r85; reg [277:251]r86; reg [71:45]r87; reg [56:38]r88; reg [95:91]r89; reg [271:242]r90; reg [187:174]r91; reg [176:171]r92; reg [100:88]r93; reg [273:242]r94; reg [137:111]r95; reg [148:144]r96; reg [168:159]r97; reg [269:254]r98; reg [149:145]r99; reg [202:176]r100; reg [37:26]r101; reg [62:37]r102; reg [47:36]r103; reg [195:176]r104; reg [124:93]r105; reg [8:4]r106; reg [170:161]r107; reg [150:129]r108; reg [54:40]r109; reg [86:64]r110; reg [132:111]r111; reg [224:224]r112; reg [262:232]r113; reg [27:14]r114; reg [99:97]r115; reg [234:214]r116; reg [66:52]r117; reg [178:173]r118; reg [83:52]r119; reg [67:58]r120; reg [110:82]r121; reg [255:232]r122; reg [41:19]r123; reg [67:45]r124; reg [179:178]r125; reg [173:151]r126; reg [35:20]r127; reg [168:155]r128; reg [129:112]r129; reg [47:29]r130; reg [199:186]r131; reg [217:190]r132; reg [241:212]r133; reg [256:233]r134; reg [129:116]r135; reg [168:157]r136; reg [230:211]r137; reg [261:248]r138; reg [39:27]r139; reg [137:135]r140; reg [169:142]r141; reg [103:79]r142; reg [118:118]r143; reg [156:154]r144; reg [234:208]r145; reg [154:131]r146; reg [211:183]r147; reg [74:65]r148; reg [161:145]r149; reg [58:51]r150; reg [268:253]r151; reg [193:175]r152; reg [148:120]r153; reg [169:138]r154; reg [213:210]r155; reg [119:103]r156; reg [104:83]r157; reg [212:193]r158; reg [172:172]r159; reg [206:182]r160; reg [176:159]r161; reg [172:153]r162; reg [119:110]r163; reg [75:53]r164; reg [5:5]r165; reg [238:226]r166; reg [258:230]r167; reg [95:74]r168; reg [231:216]r169; reg [252:248]r170; reg [98:79]r171; reg [191:166]r172; reg [161:154]r173; reg [67:67]r174; reg [214:207]r175; reg [204:198]r176; reg [131:118]r177; reg [212:181]r178; reg [258:248]r179; reg [141:116]r180; reg [201:198]r181; reg [108:78]r182; reg [83:72]r183; reg [81:69]r184; reg [144:140]r185; reg [174:154]r186; reg [191:171]r187; reg [48:27]r188; reg [260:251]r189; reg [69:47]r190; reg [259:246]r191; reg [167:162]r192; reg [245:237]r193; reg [67:49]r194; reg [133:108]r195; reg [224:213]r196; reg [126:108]r197; reg [230:208]r198; reg [80:59]r199; reg [136:120]r200; reg [62:44]r201; reg [206:198]r202; reg [284:254]r203; reg [184:158]r204; reg [32:13]r205; reg [233:220]r206; reg [69:59]r207; reg [46:34]r208; reg [181:156]r209; reg [105:100]r210; reg [240:228]r211; reg [51:48]r212; reg [149:144]r213; reg [201:190]r214; reg [234:215]r215; reg [212:188]r216; reg [98:79]r217; reg [237:214]r218; reg [105:96]r219; reg [10:7]r220; reg [134:105]r221; reg [192:162]r222; reg [202:180]r223; reg [50:31]r224; reg [50:26]r225; reg [181:166]r226; reg [146:117]r227; reg [118:93]r228; reg [222:202]r229; reg [135:114]r230; reg [78:51]r231; reg [260:231]r232; reg [172:142]r233; reg [58:32]r234; reg [245:232]r235; reg [51:46]r236; reg [198:167]r237; reg [217:217]r238; reg [130:121]r239; reg [130:111]r240; reg [28:0]r241; reg [87:79]r242; reg [60:58]r243; reg [59:53]r244; reg [200:178]r245; reg [81:67]r246; reg [110:104]r247; reg [233:211]r248; reg [139:129]r249; reg [262:254]r250; reg [177:175]r251; reg [262:236]r252; reg [111:94]r253; reg [230:218]r254; reg [191:164]r255; initial begin r0 = 32'h2eec; r1 = 32'h1584; r2 = 32'h47e5; r3 = 32'h587f; r4 = 32'hab8; r5 = 32'h71e9; r6 = 32'h4e49; r7 = 32'h6794; r8 = 32'h5c8e; r9 = 32'h1a61; r10 = 32'h55df; r11 = 32'h2da5; r12 = 32'h3d89; r13 = 32'h76ab; r14 = 32'h6d8e; r15 = 32'h66ed; r16 = 32'hc57; r17 = 32'h615c; r18 = 32'h29c0; r19 = 32'h7ed1; r20 = 32'h11c7; r21 = 32'h5f7a; r22 = 32'h59cc; r23 = 32'h36df; r24 = 32'h6217; r25 = 32'h35da; r26 = 32'h2827; r27 = 32'h418b; r28 = 32'h6fb; r29 = 32'h7839; r30 = 32'h114b; r31 = 32'h4ca3; r32 = 32'h3e6d; r33 = 32'h6e1d; r34 = 32'h5d63; r35 = 32'h3797; r36 = 32'h5a38; r37 = 32'h6969; r38 = 32'h8bb; r39 = 32'h716b; r40 = 32'hc42; r41 = 32'h6ac3; r42 = 32'h46ea; r43 = 32'h3a78; r44 = 32'h2b9c; r45 = 32'h2fa6; r46 = 32'hcbc; r47 = 32'h45e6; r48 = 32'h3e4b; r49 = 32'h646; r50 = 32'h4ce2; r51 = 32'h76e9; r52 = 32'h53d4; r53 = 32'h327; r54 = 32'h5359; r55 = 32'h35be; r56 = 32'h7c89; r57 = 32'h747c; r58 = 32'h6b9a; r59 = 32'h1864; r60 = 32'h6996; r61 = 32'h2f40; r62 = 32'h3d86; r63 = 32'h5b1b; r64 = 32'h1ca; r65 = 32'h1216; r66 = 32'hd10; r67 = 32'h649e; r68 = 32'h7727; r69 = 32'h59e1; r70 = 32'h48a8; r71 = 32'h521f; r72 = 32'h2928; r73 = 32'h2423; r74 = 32'h126b; r75 = 32'h4707; r76 = 32'h5fd4; r77 = 32'h3b16; r78 = 32'h300c; r79 = 32'h7c6a; r80 = 32'h2b87; r81 = 32'h78c; r82 = 32'hd80; r83 = 32'h4c4c; r84 = 32'h757b; r85 = 32'h4487; r86 = 32'h3e6c; r87 = 32'h3496; r88 = 32'hd19; r89 = 32'h5098; r90 = 32'h2a4f; r91 = 32'hdd6; r92 = 32'h3e02; r93 = 32'h38f8; r94 = 32'h4f6f; r95 = 32'h71ba; r96 = 32'h3adc; r97 = 32'h5a68; r98 = 32'h4884; r99 = 32'hd4a; r100 = 32'h68dd; r101 = 32'h33c8; r102 = 32'h127; r103 = 32'h5ae8; r104 = 32'h5818; r105 = 32'h4679; r106 = 32'h44f9; r107 = 32'h9; r108 = 32'h748a; r109 = 32'h2074; r110 = 32'h1593; r111 = 32'h4ab1; r112 = 32'h3be4; r113 = 32'h6c27; r114 = 32'h7331; r115 = 32'hab0; r116 = 32'h416; r117 = 32'h2213; r118 = 32'h41d; r119 = 32'h429e; r120 = 32'h1ea0; r121 = 32'h3827; r122 = 32'h46dd; r123 = 32'h6c97; r124 = 32'h6497; r125 = 32'h6ada; r126 = 32'h3b1c; r127 = 32'h4eb7; r128 = 32'h7779; r129 = 32'h7c0a; r130 = 32'h2d59; r131 = 32'h1b54; r132 = 32'h42b2; r133 = 32'h397; r134 = 32'h1151; r135 = 32'h58fe; r136 = 32'h9ea; r137 = 32'h2dbe; r138 = 32'h172d; r139 = 32'h4e38; r140 = 32'h1015; r141 = 32'h337; r142 = 32'h676c; r143 = 32'h6cf3; r144 = 32'h2338; r145 = 32'h170f; r146 = 32'h318e; r147 = 32'h79ce; r148 = 32'h18fc; r149 = 32'h3643; r150 = 32'h7986; r151 = 32'h6b10; r152 = 32'h7f4; r153 = 32'h7520; r154 = 32'h4fdd; r155 = 32'h3b61; r156 = 32'h49ae; r157 = 32'h365d; r158 = 32'h60a6; r159 = 32'h2c4b; r160 = 32'h117b; r161 = 32'h7f4; r162 = 32'h525; r163 = 32'h3475; r164 = 32'h23fe; r165 = 32'h71c5; r166 = 32'h443e; r167 = 32'h1599; r168 = 32'h7b77; r169 = 32'h11ea; r170 = 32'h6d9f; r171 = 32'h564a; r172 = 32'h64cd; r173 = 32'h22d8; r174 = 32'h3bad; r175 = 32'h1b68; r176 = 32'h615d; r177 = 32'h473a; r178 = 32'h282f; r179 = 32'h1d5e; r180 = 32'h5985; r181 = 32'h378d; r182 = 32'h5fbd; r183 = 32'h3522; r184 = 32'h6bef; r185 = 32'h2d7c; r186 = 32'h7fe6; r187 = 32'h3cea; r188 = 32'h659d; r189 = 32'h28f9; r190 = 32'hc24; r191 = 32'h40af; r192 = 32'h2eb9; r193 = 32'h6b1f; r194 = 32'h4581; r195 = 32'h3a63; r196 = 32'h381a; r197 = 32'h42cb; r198 = 32'h5105; r199 = 32'h55f1; r200 = 32'h3596; r201 = 32'h6f4; r202 = 32'h58e6; r203 = 32'h78f8; r204 = 32'h310a; r205 = 32'h5ace; r206 = 32'h146f; r207 = 32'ha48; r208 = 32'h422a; r209 = 32'h17a3; r210 = 32'h62ac; r211 = 32'h3518; r212 = 32'h7709; r213 = 32'h786c; r214 = 32'h63db; r215 = 32'h240d; r216 = 32'h3967; r217 = 32'h6332; r218 = 32'h3d92; r219 = 32'h6fec; r220 = 32'h3cbe; r221 = 32'h6c27; r222 = 32'h75af; r223 = 32'h3e19; r224 = 32'h410b; r225 = 32'h6e83; r226 = 32'h1004; r227 = 32'h4ad7; r228 = 32'h365d; r229 = 32'h5720; r230 = 32'h5abf; r231 = 32'h5b3e; r232 = 32'hd1f; r233 = 32'h7cd4; r234 = 32'h159b; r235 = 32'h52fb; r236 = 32'h3f25; r237 = 32'h2292; r238 = 32'h5fc9; r239 = 32'h69ca; r240 = 32'h5d77; r241 = 32'h7f3f; r242 = 32'h189c; r243 = 32'h3cb5; r244 = 32'h2ee1; r245 = 32'h6755; r246 = 32'h1ef7; r247 = 32'h370a; r248 = 32'h2b36; r249 = 32'h743a; r250 = 32'h1b77; r251 = 32'hf1d; r252 = 32'h5f68; r253 = 32'h455e; r254 = 32'h415f; r255 = 32'h52c2; #10; r73 = r189; #10; r132 = 11'h783; #10; r86 = ( ( & ( (14'h1136 ^ ((25'hd6c == $time) * r2)))) != 26'h1ef2); #10; r246 = ( | ( 22'h6337)); #10; r35 = (r155 * ((r190 > (((((((r127 % ( | ( r81))) & r150) | r11) !== (((r207 <= (22'h4d2b ? ((r158 == ( - ( r219))) | 13'hdae) : r43)) != ((r97 > ((r240 != ((26'h259a * 13'h465) >= (5'h2 * 11'h7ed))) % (((12'h279 < 28'h3026) || 4'h1) && r111))) & ( ! ( ( ! ( (16'h7a99 <= 4'h6))))))) & 26'h5fa4)) && (((r15 | (( ( | ( ( ~ ( (r235 && 31'h2eeb))))) / r90) !== r56)) <= ((22'h640f !== r182) <= (31'h1b37 !== ( ( | ( (((9'hc9 / 32'h7c3b) - (8'ha6 - 3'h2)) == ((12'h36b - 9'h171) < ( + ( 23'h425)))))) % r72)))) + $time)) > r1) !== 18'h6d7b)) >= 28'h6e25)); #10; r144 = 4'h9; #10; r206 = ( ( | ( 12'h4ff)) | 17'h43ef); #10; r138 = $time; #10; r74 = 22'h38ad; #10; r49 = r2; #10; r50 = ((31'h744c ? ((r164 && r191) >= 16'h6c50) : ((r137 / ((1'h0 ^ ((r169 >= (((20'h5ab3 == ( & ( ( & ( (21'hb12 < (7'h16 || 10'h24e))))))) != r155) - ( | ( ( + ( ( ( ! ( r166)) % (26'h296c > 32'h62ed)))))))) === ( + ( ( | ( r187)))))) - r92)) * r99)) >= r189); #10; r150 = ((12'h24d != r248) / ( & ( (((r34 - ( ! ( 20'h40cd))) === (((7'h52 > (25'h7f1d || 1'h1)) && 5'h12) ? ( ^ ( (r61 && ( ~ ( ( ( + ( ( ! ( (r73 <= ( | ( ( ( & ( 28'h57c)) / (24'h60a8 < 28'h7acc))))))))) | (8'h61 < ( ! ( (r184 === ( ~ ( (r72 == (15'h508 / 24'h5073)))))))))))))) : r24)) | r86)))); #10; r73 = ( ( + ( ( ( ~ ( ((((20'h23e2 === ((11'h649 ^ 21'hfee) | ((r35 % 30'h856) <= r67))) !== ((r183 || (((r19 / (15'h304d + 25'h523a)) && 17'h7692) - r178)) - (((((25'h34f5 || r199) === r255) <= r12) !== (((((5'hb / 5'h11) == (5'h17 | 24'h408)) / (r255 ^ r181)) && ( & ( 14'h2e37))) === ((17'h1e79 <= r84) / (r0 !== ( ^ ( (26'h587b <= 20'h7403))))))) >= ( - ( r184))))) !== ( - ( r248))) === $time))) * 12'h5))) || r191); #10; r134 = (1'h1 === 24'h12a0); #10; r214 = 30'h3839; #10; r255 = 30'h242b; #10; r7 = 9'h132; #10; r130 = r65; #10; r64 = r162; #10; r174 = ((r91 <= (r231 + ( - ( 1'h1)))) <= ((((r93 <= (r183 / ( ( & ( ( ^ ( ( ^ ( 1'h1)))))) <= r75))) * 12'ha95) & r27) | ((((((20'hf1f === ((r175 >= 20'h3632) | ((r109 & (r88 < r248)) < 10'h2e5))) & r37) % $stime) || ( ( + ( ( ! ( r160)))) & r17)) > ( ( | ( (r124 & ( - ( ( - ( (22'hd2b != ( ! ( r196)))))))))) && r84)) | (r51 / 16'h5f0d)))); #10; r41 = ( ( ^ ( ( ( ^ ( ((3'h6 >= (r215 & (31'h3d8b && ( ^ ( 5'h11))))) <= $time))) & ( & ( r7))))) * ( ( - ( (12'he7e ? ( + ( ((3'h2 ^ r250) & (r214 <= (r19 - r249))))) : (r140 | r104)))) || r250)); #10; r195 = 9'h1ac; #10; r242 = 21'h527c; #10; r143 = ((((((r68 ? (6'h1e ? ( ^ ( 26'h4f04)) : ( - ( ( ( - ( $time)) - (( ( + ( r96)) !== (r185 / 6'h22)) ? r133 : r2))))) : r20) * ((28'h20ec % r109) / ( + ( ( ( & ( 1'h0)) | (13'h13f1 === ((r96 - r204) * ( | ( 1'h0))))))))) === ((23'h4c6b / (20'h7a3b === r184)) == (( ( ! ( ( ( + ( (((7'h59 ? ((3'h4 <= 13'had1) | 15'h1a5c) : r123) % $stime) == ( + ( (((15'h74fe === 2'h0) == ( + ( 3'h0))) <= ((26'h2e1 | 8'h3b) + (16'h76a4 == 26'h645a)))))))) + ( + ( ((r123 & (r37 != (r211 >= (21'hcee < 18'h2845)))) >= (27'h5efd ^ r116))))))) | ((25'h4cd6 + r74) ? r115 : ((r133 - ((r198 ? r55 : (($stime % 17'h38a5) | $time)) === ( ~ ( r217)))) ? (r250 !== 19'h49e1) : ( ! ( r15))))) == r224))) - ((r244 > (r229 - ( & ( (( ( + ( r244)) != ( ! ( ((29'h6d1b === 10'h364) - ((17'h43c9 & ( + ( r238))) == r113))))) % 30'h7539))))) & ( | ( 23'h4205)))) | 5'h19) <= ( ! ( r92))); #10; r74 = r232; #10; r31 = ( ( ~ ( r181)) && ( - ( 7'h8))); #10; r75 = (6'h10 === r188); #10; r75 = ( ( & ( $stime)) + ( - ( ((( ( | ( (16'h1c8a % 32'h503f))) ? ((r161 ^ r59) == ( ! ( ( - ( (((r191 === r182) == ( ( + ( ( | ( r168)))) > ( ( | ( 1'h1)) * (( ( ^ ( 32'h2923)) != (14'h3cd7 * 24'h1162)) > (25'h7bc2 - 6'hd))))) - r31)))))) : ((4'hd & ( ^ ( (r130 - ((r96 === r154) == (32'h2fba >= ( | ( 4'h3)))))))) >= ( & ( (((r253 !== 18'h4189) >= (11'h679 < r133)) * r109))))) != $time) !== ( ( ~ ( (((21'h5dd3 / (10'h22e ^ (( ( ! ( ( + ( ( & ( (21'h5c32 * 12'h7e))))))) - ((((16'h132e || 23'hf58) <= 21'h1302) ^ ((2'h1 | 4'hb) - r113)) & (r207 || 24'h1190))) || ((r224 && r246) > 7'h19)))) % ( ( ~ ( r150)) - ((1'h1 & 24'h7aa2) | ($stime !== r24)))) >= 14'h29de))) !== ( + ( 10'h207))))))); #10; r195 = 4'h7; #10; r129 = r208; #10; r152 = r144; #10; r9 = (( ( ! ( ( & ( (r39 >= r176))))) - 5'h6) ^ 12'h837); #10; r159 = ( + ( ((r132 <= (((( ( + ( (24'h5c17 + r12))) == 24'h3ca7) > r164) >= ( ( ^ ( r114)) > r126)) < ((r0 & ( ~ ( (22'h7ece <= (((2'h3 % (r90 + ( ( + ( 6'h1)) | $stime))) | r51) !== (27'h1d94 == (r189 & r252))))))) ? 2'h0 : r110))) <= ((r124 % r178) <= ( ( & ( $time)) - (((r22 == 27'h4da6) != 19'h14be) ^ (r155 / r52))))))); #10; r92 = (28'h4175 + ( - ( ((( ( ~ ( (4'hf % (($stime ? 5'hf : ((((4'h8 | (r118 !== 10'h222)) != ($time / r53)) ? ( ~ ( r49)) : ((r251 > r162) - r163)) == 17'h72a0)) && (16'h486b === r203))))) + r130) + 14'h3094) ? (((r153 | 12'h53b) + (((r97 ^ (28'h6257 > 4'h5)) !== ( & ( ( ( ^ ( ( | ( ( & ( 13'h1537)))))) != ((18'h18c7 != r154) & r105))))) != r241)) - r193) : ((14'hcba !== (r26 | ($time && ((22'h643d ^ ( ( ~ ( r117)) < (r206 === ( ^ ( ( ! ( ( ! ( (11'h3b3 >= 27'h6d33)))))))))) / 6'h2c)))) > ((25'h6f8d >= 26'h4258) == ( ( & ( (( ( ! ( ( ~ ( ( ( | ( 32'h41ba)) + ( ( ! ( 14'h2b91)) + r190)))))) <= (26'h5532 + 14'h12cb)) == (r232 % ((21'h2891 / r76) + ( + ( ( ( & ( ((8'h43 <= 24'h19c2) > ( & ( 25'h70d2))))) + ((31'h65e0 !== (10'h18a ^ 1'h1)) < r191))))))))) / ((16'h16d0 ? 26'h5ce4 : (r66 ? ( ! ( r127)) : ((((((18'h6d90 ^ 19'h2911) % (18'h5898 * 3'h0)) && $stime) !== ( ( & ( ( ~ ( 25'h56ef)))) - ( | ( r124)))) * ( | ( ( ! ( (r62 ? r238 : (22'h5c72 <= 28'h4c3))))))) != ( | ( 22'h388d))))) | (((( ( + ( r248)) !== ((r240 % 30'h5a83) - r4)) + 31'h131) || r147) & ((r36 | (((((15'h5184 > 29'h7846) + 15'h4959) ^ (r123 * r200)) / ($time & ( + ( (8'hc8 & 9'h1db))))) > 5'hd)) / ((r86 > 29'h4da1) !== r118))))))))))); #10; r222 = (r106 * 32'h1826); #10; r88 = ( ( ! ( ((((r249 != 18'h6b91) > ( ! ( ((r65 == r236) & 7'h59)))) ? r146 : ((r162 === $time) <= r135)) > (( ( + ( 32'h2513)) !== r252) || r147)))) <= ((32'h371b == r72) < 5'h1f)); #10; r131 = r22; #10; r48 = ( ( & ( (((( ( - ( ((r9 - 30'h63a0) * r22))) | ( - ( r212))) ^ 10'h1d5) === ( ^ ( 14'h2dbb))) % (9'h178 % (r241 !== ( ( | ( ( ~ ( (((21'h280 !== ((29'h1c0a - (1'h0 + 2'h3)) / (26'h2be2 * (r98 && ( & ( 22'hac0)))))) | (17'h5864 || r147)) <= (r51 ? ( ^ ( r226)) : (r15 != ( | ( (8'hb6 && 6'h34)))))))))) < (9'h1bb != r114))))))) === r208); #10; r217 = ( | ( (r7 || ((r98 === (r212 === ( ( ! ( $time)) | (6'h3 + 23'h6819)))) / (r154 >= ( & ( r135))))))); #10; r145 = ((7'h5d > r79) != ( - ( r98))); #10; r22 = ( ~ ( 22'h43eb)); #10; r115 = r221; #10; r239 = (r198 !== (10'h79 !== (12'h444 ^ ((r204 && r214) % ( ~ ( r7)))))); #10; r170 = ((r185 % 25'h5b50) - r104); #10; r139 = (( ( ^ ( (((29'h158a && r170) ? r64 : 26'h4955) - (r100 >= r61)))) * r136) | r122); #10; r78 = 7'h10; #10; r72 = r70; #10; r145 = ( | ( (8'h86 && r159))); #10; r123 = $stime; #10; r220 = ( ! ( ( ~ ( ((((r79 === 12'hd3) && r55) % ((r1 <= ((r226 % (( ( | ( r107)) != r227) < (($stime < r242) != ( ! ( ( ( ! ( 29'h6b4e)) * (r221 || ( ( ! ( 29'h162a)) > 25'h45be)))))))) !== ((( ( ! ( ( | ( (r179 <= $stime))))) && 20'h7a52) & r249) < 29'h58eb))) & 25'h4a32)) == (r63 == r136)))))); #10; r31 = 32'h3c62; #10; r216 = (r148 != r198); #10; r140 = r215; #10; r227 = ((r246 ? $stime : r163) && (((( ( ~ ( r157)) + 13'h1de6) / 2'h1) !== (($time <= (r195 & ( ^ ( r121)))) && ( ( ~ ( r165)) * ((r124 !== 13'h9f1) && (r226 == (r79 <= ((r188 | ((((r70 >= (29'h4a7 % 2'h3)) < ((8'hba >= 4'h5) || 24'h394b)) !== r140) + $time)) / r68))))))) && r193)); #10; r168 = 2'h3; #10; r208 = r211; #10; r196 = ((((r227 < 24'h299e) != 10'hac) && (((r16 && ((r10 ? ($time / $stime) : r229) >= ( & ( (( ( | ( ( ( | ( 15'h5c9d)) / ( ^ ( (r242 !== r117)))))) && r200) <= ( & ( ( + ( ( ! ( r228))))))))))) - (7'h2c != (( ( & ( 17'hd65)) ^ $time) + (r82 >= r124)))) ? ( ^ ( r222)) : ( & ( ( ^ ( ((r146 != $stime) ^ ( ! ( (r4 % ( ^ ( r114)))))))))))) ^ r88); #10; r200 = 12'h3e9; #10; r158 = (24'h2147 - 4'h4); #10; r72 = r219; #10; r101 = ( | ( (r104 + r252))); #10; r98 = (27'h401a ^ ( | ( ( ( ~ ( 13'h74a)) * (( ( ^ ( r121)) ? 5'hf : ( ( ^ ( 17'h6a2d)) % 2'h3)) != (r43 === (32'h2ec9 % ( - ( ( ~ ( (($time !== ((21'h583a + ( & ( r117))) * r30)) <= r167)))))))))))); #10; r57 = ( ^ ( r87)); #10; r54 = ( ( + ( ((( ( - ( r109)) ? 6'h9 : r99) - 28'h6c8c) + ((((((25'h46be && 14'h16f3) > r158) / r249) % (r168 || (r95 === ( + ( (((((r204 % $stime) <= ( + ( (27'hb65 != 6'h1b)))) <= ((r139 && (11'h577 || 27'h5dbd)) + 1'h1)) || ((((13'h9d1 !== 22'h14cf) | (26'h101a + 23'h31a9)) | ((7'h4b - 26'h63f8) | (30'ha4d * 32'h760))) < ( ( ^ ( 3'h1)) < r111))) < (((r215 & 32'h4838) / ( ( ^ ( (24'h2d6f || 28'h4fde))) && ((4'hb <= 9'h24) & r112))) | (r97 === (r76 < 8'h76))))))))) ^ ( ^ ( ((26'h3743 || ( ( - ( ( ! ( ((3'h4 * ((7'h66 !== 32'h4200) & 14'h2b24)) ? ( - ( r57)) : 21'h6ef))))) <= r70)) | ((r159 <= r181) - ( ( + ( (r36 || (r49 != (r185 === ( ^ ( ( ! ( 10'h2dc))))))))) === r150)))))) >= ( | ( ( ( & ( ( ! ( 22'h416f)))) !== (r137 + ( | ( $time)))))))))) ^ r148); #10; r44 = (11'h11 || 13'h99d); #10; r213 = r254; #10; r101 = 31'h6ed; #10; r190 = ( ^ ( r133)); #10; r222 = (32'h2008 >= 24'h68a3); #10; r12 = r13; #10; r235 = ( + ( (r42 / $stime))); #10; r50 = ( ( ^ ( ((r251 <= ((27'h6eee > ( & ( (($time ? r43 : $time) !== (7'h36 !== ((((((23'h6f4 != 26'h7c8b) & (32'h5eeb < 25'h6227)) | $stime) * (((29'h6a61 === 11'h6bf) & (30'h6956 / 21'h637d)) > r209)) + ( | ( (($time % (22'h3516 ? 11'h405 : 6'h5)) % (11'h49d >= (4'he ^ 17'h9e1)))))) + r82)))))) & r152)) * ((((((r53 & r240) != ((((r146 === ((14'h1ccc - r221) % 1'h0)) !== ((( ( | ( 23'h24bd)) & r79) >= (26'h2a62 / 23'h59d6)) !== r94)) < ( ( ! ( ( ~ ( ((26'h1762 / 12'h3bb) === ( ~ ( 20'h2582))))))) > r104)) * r190)) != (21'h5a98 >= r53)) && ($time * 13'h1dc3)) / $time) - r217)))) < (( ( - ( ( + ( (2'h2 !== r32))))) != ( ( ~ ( ( & ( (r130 != ((29'hc97 - $time) ^ ( - ( r18)))))))) - r102)) + r33)); #10; r224 = r199; #10; r74 = 31'he64; #10; r92 = ((( ( ^ ( ((r138 ? (((((r82 == (r128 * (r32 % (15'h7083 <= r219)))) > ( + ( ( ~ ( 31'h75c7))))) && $time) <= 2'h3) | 23'h7c7b) : r20) + ((25'h4238 >= (( ( ~ ( r30)) < r97) ? (((((24'h5cda + r34) === 31'h60c9) != r72) == 11'h5c8) | (r92 / r77)) : (r26 != r174))) % (( ( + ( (((13'h507 + $time) < (r230 < r79)) / (( ( - ( ( & ( (21'h77de >= 21'h595c))))) & (6'h29 == r159)) == r120)))) ? (( ( ^ ( ($stime % ( & ( (r44 ^ 19'h4868)))))) || 29'h425) != ((((((27'h3be5 <= 21'h73b3) >= 5'h1e) - ( ! ( (24'h14b5 | 12'h81f)))) != (((31'h6c1a >= 7'h66) != (21'h2b37 * 5'hc)) | 26'h1e08)) ? $time : ((r238 && 9'he4) | $time)) / $time)) : ($stime || 10'h2af)) | 30'h6f3b))))) != ( & ( ( & ( (30'h2102 - (r214 ^ (r148 != r173)))))))) || r12) + $time); #10; r20 = (r109 ? (((((r205 * r142) - ($time && (14'h12d7 & (25'h300a ^ $stime)))) != 8'h46) || ( ~ ( ( ( + ( ( ~ ( ($stime < ( ! ( ( ^ ( (r127 + r51)))))))))) == (r175 % ( ! ( (((r70 == r189) > (((r1 !== 9'h40) != (5'h3 !== r198)) + (r221 ^ 30'h283b))) || 29'h1a0c)))))))) + (((r220 + (26'h5440 != (2'h1 == 6'h2e))) & r219) & 28'h5a06)) : (14'h1a0a < 6'h15)); #10; r253 = ( ! ( 32'h3419)); #10; r95 = 16'h3cbd; #10; r49 = 2'h1; #10; r17 = (r251 <= r61); #10; r151 = 4'h7; #10; r136 = (r253 || ((r68 <= 30'h5ad3) != (3'h0 % ( + ( 27'h5cc2))))); #10; r35 = (r153 & (r74 | ( ( & ( r94)) <= r72))); #10; r120 = (30'h3c55 + ((r48 || r173) & r231)); #10; r214 = ( ( & ( (r168 % ((((28'h55b2 ^ ( ( ! ( 8'h4b)) === 11'h221)) < r217) != ( ( ~ ( ((r213 / ( + ( ( ( | ( (((18'h5f95 * 8'h91) || (7'h17 & 16'h8ab)) && r127))) == 16'h5aae)))) * ( + ( ((r109 == ((((18'h3972 + 25'h7165) == (4'h4 >= 7'h58)) * (6'h2a - (28'h4a9a + 16'h768d))) != (r130 !== ((11'h36b < 17'h7bb9) / 31'h65db)))) ? ( | ( r139)) : ( - ( 28'h5d29)))))))) !== (((15'h7581 < 5'hd) + ((((20'h61ac ^ r219) < 1'h0) | (r79 ^ r25)) * (r90 < $time))) - ( ^ ( ( - ( (( ( + ( ( + ( r130)))) == (( ( ~ ( r200)) >= 24'h433) < 1'h1)) + 17'h7ce2)))))))) ^ (( ( & ( ((r161 + ( & ( ( ( ^ ( r63)) * (((r201 & (13'h1fa9 || 2'h3)) * ( ^ ( r103))) * r28))))) | 1'h1))) === $stime) > ( ^ ( ( ! ( r165))))))))) >= ((( ( | ( 3'h6)) | r66) | 5'h8) ? ( - ( r24)) : (r227 / ( ^ ( ((( ( ~ ( (((r63 * ( ( & ( (r92 / (24'h565a + 12'h647)))) - (r124 < r138))) || ( - ( (18'h1d84 | ((r186 - 28'h4f76) | ( ( - ( 4'h5)) != 25'h57d1)))))) ^ ((r196 >= ( | ( r186))) ? ((32'h15b6 & (26'h458a > ( ! ( r103)))) / r171) : r99)))) || (($stime - (((((r64 | r129) / 18'h31eb) | $stime) & (1'h0 / r226)) != ( + ( r173)))) != r3)) % (r109 >= 9'h119)) + (((((20'hf4b ? ( & ( (16'h394b > ($time * ( + ( (16'h480 === 32'h42fb))))))) : 24'h56a7) ? 22'h5ab9 : r136) === 14'h2f0a) <= r83) % r134))))))); #10; r223 = (r227 ^ ( ! ( ((28'heb ? ( + ( (r213 | (20'h18bc >= r78)))) : ( & ( 10'h333))) | ((r132 != r21) - (r23 | r235)))))); #10; r70 = $time; #10; r76 = (r49 / (((( ( - ( r188)) && r46) <= (r73 * r159)) || (r109 ^ ( & ( 13'h12a8)))) / (( ( - ( $stime)) > (r165 / ((25'h7b9e * ( - ( ( ^ ( (((r28 + (r247 > ( - ( (2'h0 % 10'h360))))) % 13'h48d) ? (29'h6a6f - 27'h5199) : 22'h2db7)))))) < 17'h6a8e))) >= ( ^ ( ( - ( 5'h3))))))); #10; r184 = ( & ( ( & ( r95)))); #10; r244 = ( | ( (12'hb7 / 9'hb9))); #10; r239 = 19'h7f7c; #10; r246 = (r224 != ((($time < 11'h493) !== (18'h148b - r178)) == (7'h4c < (r198 && ( | ( ((((((r140 & ( ~ ( (( ( - ( 15'h988)) | r21) || ( ( ^ ( 11'h5c4)) <= (20'h7942 >= 15'hca5)))))) % r6) && (($stime + 6'h16) > ( & ( 13'h76d)))) > ( ( - ( r13)) >= ( ( + ( 13'hc6a)) / (r247 * r180)))) >= (7'h20 || (( ( ! ( (((12'haae > 10'h15a) && 16'h4261) > r16))) & ((r100 / (r60 + (r99 / (27'h2093 - 8'hd5)))) - r234)) & ( ( ! ( $time)) === $stime)))) >= r31))))))); #10; r208 = r57; #10; r120 = 26'h5f9c; #10; r176 = 5'h2; #10; r205 = ( ^ ( 31'h6209)); #10; r219 = (1'h0 * ( | ( r56))); #10; r9 = 19'h2d05; #10; r112 = ( ( ~ ( ( + ( ( ^ ( r163)))))) <= ( - ( ( | ( (r78 % ( ( + ( ( ! ( $time)))) != (31'h4aff * r79)))))))); #10; r163 = r143; #10; r20 = (((r127 | 17'h3217) ^ r11) || (8'ha2 != (r189 === r201))); #10; r45 = ((r171 ^ ( ! ( (r42 === 5'he)))) >= 13'h1b72); #10; r72 = ( ( | ( ( + ( r110)))) - 10'h189); #10; r238 = $stime; #10; r234 = r199; #10; r247 = r34; #10; r138 = r206; #10; r245 = ( | ( r167)); #10; r253 = (( ( | ( 14'h394d)) != (( ( ^ ( (((10'h1c6 == r212) ? ( + ( ( ~ ( r148)))) : r51) ? ( ( ^ ( $time)) < r233) : (7'h3c ^ ( ^ ( 17'h7cde)))))) !== ( ( | ( r155)) !== r64)) <= r224)) % (( ( + ( (r79 === ((1'h1 <= (r81 / r68)) + (r139 != ((r180 ? ( + ( ( ! ( ( ~ ( r46)))))) : (r171 % r237)) * r102)))))) % ( ^ ( ( | ( r78))))) <= (17'h2b1f ^ ((17'h3160 ^ r59) > (((6'h3 + $time) * ((7'h3f !== $stime) ^ 3'h2)) ^ ((r181 > (r221 | (((r187 != ( - ( (((14'h3871 - 31'h1261) < (8'had / 6'ha)) & r192)))) || $time) ? ( + ( r154)) : $stime))) + ( & ( 21'hfbf)))))))); #10; r193 = ( & ( 15'h1a54)); #10; r143 = r132; #10; r161 = ($time & ( ~ ( (r107 ^ $stime)))); #10; r47 = r197; #10; r72 = ((($time == 14'h3eb9) !== r242) < 12'hee0); #10; r167 = ( ( ! ( ( + ( r50)))) + ( ^ ( (r231 * ((6'h26 <= ( ( ~ ( ( ( + ( ( - ( ((( ( + ( (2'h1 != 19'h3fa5))) === ((6'h11 % 4'h1) / (10'h37a / 30'h1e1c))) * 9'h1b6) != ( ( & ( (8'h22 === 2'h1))) * $stime)))))) * 13'h1daa))) * r192)) === 26'h5f03))))); #10; r99 = ( ~ ( ( ~ ( r218)))); #10; r66 = ( ( ~ ( ((( ( ^ ( ((11'h73f ? ($stime === ( ~ ( r187))) : ((((20'h4125 + $stime) | r85) == r13) === ((22'h47f0 & (r164 % ( & ( ( + ( (23'h1879 + 19'h28f2))))))) >= 4'hf))) * $stime))) === ( ^ ( 29'h67cf))) || ( | ( r240))) > ( - ( (r78 + (23'h272f && (r132 != (( ( & ( (($stime === (((16'hed3 * 1'h0) < $time) && ((6'h2 / 9'h101) ? (21'h637d - 26'h4190) : r63))) * ((((9'haf & 14'h2ce7) ? (2'h2 & 9'h197) : 9'hd5) <= ( ( + ( 27'h32c1)) && (9'h147 - 5'h11))) >= (r159 == (r200 <= 28'h3218)))))) ^ ( - ( ( + ( (r202 ? ( ( - ( 14'h190e)) % ((16'hffb >= 26'ha6d) + (23'h3a46 | 3'h4))) : r83)))))) % r246))))))))) ? ( ( ! ( ( ^ ( ((r117 === r65) & (r92 & r196)))))) / ((((((16'h4c37 !== ((r124 * r17) < (r161 + ((r55 === ( ( ~ ( r209)) & 10'h3fc)) % ( ( & ( ((7'h2f + 18'h274a) * (31'h4de5 < 12'hb26)))) >= ( ^ ( ((14'h3161 >= 25'h7632) * (25'h2a76 * 8'he))))))))) > ( ! ( ((10'h390 - r60) % (((13'h649 + ( - ( r187))) !== r61) | 19'h40eb))))) >= (19'h49d9 <= r1)) & (( ( & ( r174)) == r111) / 18'h4732)) - ( ( ! ( ( | ( (r232 > r110))))) + (r73 < $stime))) <= r163)) : ( ^ ( ( ! ( ((((r195 | ( ( | ( 22'h41f9)) ? (23'h754e / 6'h28) : (25'h7d32 == (4'h6 < 5'h1f)))) & ( | ( ( ( ! ( r87)) - r71)))) - ( ^ ( r179))) | ( ( & ( (3'h2 > $stime))) + ( ! ( r165))))))))); #10; r9 = (26'h2a2e != 15'h83d); #10; r125 = 15'h6f76; #10; r245 = ( | ( 28'h74c2)); #10; r157 = r203; #10; r166 = ((21'h29d6 != (($time - r242) == ( ( & ( (((11'h323 && ( ~ ( (1'h1 + ((r68 / (((13'h18c8 + 15'h2554) % r147) === (9'h40 === (4'he || 1'h0)))) ^ ($time & r189)))))) | 30'h4919) <= r151))) < (r137 ? (r50 % (( ( - ( $time)) >= 19'hbdc) * r216)) : ( ( ~ ( (6'h3d | $stime))) <= 1'h0))))) <= ( ( - ( r229)) >= 22'h3540)); #10; r138 = r246; #10; r163 = 32'h357d; #10; r251 = ( & ( ( - ( r85)))); #10; r83 = ((23'h34a0 <= r246) === 11'h66b); #10; r183 = (r152 || (($time ? (21'h6ca4 > 28'h650) : r140) != ($stime !== 27'h1214))); #10; r171 = 32'h6d44; #10; r180 = 9'h180; #10; r167 = (r199 ? ( | ( r212)) : 23'h3844); #10; r221 = 12'h1b; #10; r198 = (r72 ? ( ! ( r4)) : ( - ( r213))); #10; r97 = ( & ( 14'h290e)); #10; r164 = 5'h3; #10; r33 = ((($stime || (7'h9 >= 9'h1bf)) < 14'hb12) < ((r246 / ((r116 ? 20'h1b7c : ((r189 + 17'h6013) - $time)) % $stime)) == (r100 ^ ( ( ~ ( (r189 !== r96))) & r40)))); #10; r154 = ( ( - ( ((26'h562a && r20) && (r167 | ( ( & ( (r219 | (r185 ? (r114 || ($time / r206)) : (1'h0 < $stime))))) ^ 21'h4aae))))) / ( ~ ( (r253 % ($stime * 15'h5c88))))); #10; r25 = (r5 & r139); #10; r205 = ( ( ! ( ( ! ( 29'h4196)))) && ((13'h19ed != (r149 != (24'h3ba0 !== ((r142 != (30'h3f71 || r189)) - ((((r109 / ((8'h1b % ( ( | ( r115)) === ( & ( ( | ( 30'h3325)))))) || ( + ( 6'h6)))) !== r180) || 26'h3874) - ((((15'h26a5 - ((((10'h36c % 18'h1c8) && (3'h0 <= 1'h0)) !== ( & ( (30'h1ae9 - 29'h35cf)))) > 23'h24e9)) || ( & ( (r194 * r105)))) & $stime) % ( ! ( (( ( + ( ( | ( r76)))) | ( ( ! ( ((3'h5 - 10'h2ec) + (32'h73bf & 20'h6da1)))) <= r79)) / r48))))))))) % r32)); #10; r180 = ( ( | ( ((12'hc2a % ( + ( (((4'he < r151) >= ( ! ( r53))) >= (((( ( ! ( ((7'h1a ? ((21'h60e7 / 26'h652f) / ( ! ( 16'h3871))) : (29'h69c9 && (29'h415d >= 15'h4e98))) && (((27'h4d27 === 5'h11) == (5'h7 / 27'h23f2)) > ( + ( ( ~ ( 18'h3e82)))))))) != ( ( ! ( ( ( - ( r245)) != r141))) < (((r169 && 18'h2377) * ((19'hf5c && 21'h6ee0) || 2'h3)) / r178))) * ((((((16'h46dc >= 13'h54) >= (17'h793b >= 25'h35db)) < ((27'h7f99 > 23'h7718) != (12'hc9e == 3'h3))) || ( ( & ( (17'h2856 !== 18'h357))) * r241)) && ( ( ~ ( ((12'hfd6 * 14'h2446) / r102))) || ( ^ ( (r18 ? r25 : r123))))) == 5'h13)) ^ r185) | r245))))) !== (((r52 && ($time == r43)) !== ((14'h101e < ( ( + ( ( & ( ( ( + ( r195)) !== r50))))) || ( - ( 20'h140)))) != ((r48 != (r78 >= 6'h1c)) | (9'h8c ^ ( | ( 29'h4eb7)))))) < (((r199 + 11'h4f4) || r190) != 19'h5fcb))))) !== (((($time == ( + ( 4'hf))) / ( + ( (24'h4ff8 * ( ( ! ( ( - ( (((((r11 | (11'h26b - 6'h39)) ^ r52) & (($stime % (15'h3778 == 15'h3a4a)) % $stime)) ? ( ^ ( (r49 > r191))) : ( ^ ( ( & ( ((15'h721d >= 11'h498) !== 13'h113c)))))) == r247))))) !== 15'h3ec5))))) === r154) | ( & ( ((31'h5377 && ((r11 || ((((r70 > (r202 !== r43)) ? (r221 >= (((r255 == $stime) < ( | ( ( - ( 23'h36a7))))) != (13'h1664 !== 32'h669a))) : r32) | (((7'h56 && 5'h1b) && (r106 == r168)) !== ( & ( ((22'h15c7 && (r210 ^ ( - ( 30'h3a9c)))) ^ (((6'h12 | 1'h0) - (24'h3128 * 26'h265)) === (31'h947 | (28'h7be5 & 31'h336f)))))))) & ((r91 + ( + ( 17'h1d47))) & (( ( | ( 28'h2f2)) && ( ^ ( 26'h663d))) <= ( ~ ( ( ! ( ( ! ( (19'h5235 % (19'h3511 - 32'h5628)))))))))))) || (13'h82e | (r15 || (20'h145c != ( ( & ( r228)) == ( ( - ( (((2'h3 ? 10'h31f : 8'h32) + ( & ( 13'h567))) % ( ( ^ ( 5'h2)) <= r117)))) != (r138 == ( & ( 14'h2b3a)))))))))) && (8'h99 ^ ( & ( (((((r157 + (30'h3c00 || $stime)) / r106) === ($stime !== ( + ( ((9'h1b1 > ((19'h62e4 * 22'h2f20) - r190)) / 25'h38aa))))) != r200) % 1'h1))))))))); #10; r29 = ( + ( 8'h46)); #10; r70 = (r45 ? ((2'h0 > ( & ( ((((28'h54b0 != ((r240 <= r248) - ((r123 <= 20'h4d70) ^ (r183 == (r182 == ( + ( ( + ( (11'h50f && 24'h6d05)))))))))) == (9'h45 % ( & ( (20'h5daa | (((( ( + ( 7'h66)) && (23'h2117 && 5'h15)) ? r134 : 14'h2f50) > r236) != r231)))))) ? 8'hbc : ( ( ! ( (( ( | ( ((r70 * (18'h58fb ? r227 : (19'h4843 <= 23'h461d))) === ( ( + ( (7'h30 ? 13'h163e : 8'hb2))) & ((16'h7ef || 18'hef9) > (28'h3502 < 25'h15a7)))))) - 9'h1ad) - (((r129 | r81) > r41) || (r76 <= 17'h6b6e))))) & ( | ( r125)))) < ( + ( r6)))))) | ((r75 === (4'h3 !== (24'h4381 <= r157))) + r112)) : r244); #10; r146 = (( ( + ( ( ( - ( 16'h6078)) + (r112 - ( | ( 26'h4c17)))))) <= (( ( - ( ((r203 | (((12'h954 ? ($stime | ( ! ( ( - ( ($time && (9'h1b3 !== 19'h3078))))))) : $time) == 19'h4592) >= ( ( - ( $stime)) > ( - ( 12'h242))))) >= ( | ( ( ( & ( 32'h6a4c)) <= r3)))))) * (6'h14 == ( | ( r84)))) * (((((((11'h412 - r64) === ( | ( ((r141 || ( ^ ( ($time !== $time)))) ^ ( ~ ( $stime)))))) * r242) ? (31'h4adf | (r170 && (($stime * (r75 ^ (4'h3 < 23'h1faa))) >= 14'h2445))) : ( + ( r186))) === r215) % r60) % ( ( & ( (4'h0 || $time))) ^ r179)))) > r82); #10; r219 = ( | ( (9'h14b * ( ^ ( ($stime ^ 12'h40c)))))); #10; r164 = ( + ( ( - ( 5'h18)))); #10; r197 = (r243 % (( ( & ( r105)) && 25'h3a96) * (23'h1425 | $stime))); #10; r50 = (((r217 & r223) !== $time) + r81); #10; r185 = (5'h6 | (r31 >= r194)); #10; r133 = (r210 / r112); #10; r203 = $stime; #10; r178 = (14'h258f <= 14'h1fb1); #10; r235 = ((12'h62a == ((r235 - r30) ^ 11'h49b)) ? ( & ( 13'h1647)) : r237); #10; r46 = (r241 !== (((((13'h1466 === ( ~ ( (((r106 - r139) >= ( ^ ( r97))) + 12'h69d)))) >= ( & ( ((r94 ^ r251) <= 10'h389)))) && 28'h116b) <= ( | ( ((( ( ! ( ((20'h14cc != ( & ( r45))) != r97))) + $time) == (( ( + ( ( ~ ( (11'h166 % (r79 ^ 15'h4c0a)))))) % ((27'h4742 + (r109 !== ( ! ( (r238 >= ((13'h1bc2 ? 27'h21ab : 12'h85d) / r65)))))) ? (( ( - ( 22'h3a77)) && (r24 === (( ( + ( 24'h42f9)) <= (17'h1d1c >= 30'hed9)) - ( - ( 31'h3f78))))) <= (r57 * (r252 !== r239))) : r117)) % r175)) === r66)))) ? ((r105 - r24) >= ( & ( 6'h3f))) : ( ~ ( ((((r27 || ((r72 != r105) === 30'h5332)) <= r58) < $time) > (r11 ^ ( & ( 28'h5de6)))))))); #10; r14 = r60; #10; r158 = 3'h0; #10; r92 = 16'h5cb0; #10; r168 = (22'h238a == ((29'h737d % ((($stime || (r170 & ((((30'h2570 ? r246 : (r90 == (((2'h2 <= 11'hb6) > (20'h333a ? 3'h0 : 19'h4cae)) ? 8'he0 : ((16'h63a % 19'h22bd) - 12'h78c)))) != (r152 ? (r232 ? (((29'h7a19 >= 28'h28d5) ? (12'hdd9 + 19'h6d4d) : 16'h2ab9) ^ (r196 / (5'h6 >= 31'h55a4))) : r35) : r73)) <= (20'h4ff2 - ( - ( ( + ( ( | ( 3'h0)))))))) % 5'h15))) * r34) !== $time)) || ( & ( 17'h1c43)))); #10; r31 = ( + ( ((3'h6 ^ ( ^ ( (r30 * r118)))) % ( ( - ( ((r131 <= r109) | ( ( - ( ($time % ( ! ( 1'h1))))) + $time)))) / r228)))); #10; r227 = r113; #10; r69 = ( + ( ( | ( ((r175 * r252) >= 32'h458))))); #10; r160 = r171; #10; r99 = r171; #10; r26 = ($time >= (14'h3a77 ^ r235)); #10; r188 = (( ( ! ( 19'hce0)) ^ (r32 ? (($stime <= (r90 * 15'h5bc5)) < r45) : (30'h7f25 == ( ( & ( ( ( ~ ( ((r137 / 22'h505) && r114))) || r72))) != r210)))) === (r220 | r130)); #10; r210 = r221; #10; r241 = ( ( + ( r24)) + 10'h16e); #10; r24 = ( + ( (3'h1 + 27'h6ef2))); #10; r104 = ( + ( ( ~ ( r45)))); #10; r39 = 12'h75f; #10; r136 = ( - ( 5'h18)); #10; r186 = $stime; #10; r202 = 3'h6; #10; r216 = 25'h70bd; #10; r208 = r211; #10; r143 = ( + ( (r114 < r197))); #10; r118 = ((r187 * r55) <= ( & ( ( - ( ( - ( ((( ( ~ ( 14'h3306)) % (((15'h67f + ($stime ^ ($stime % ( ^ ( ((11'h82 < 18'h7222) ^ ( + ( 25'h1c3b)))))))) - (($stime <= ( ! ( ( ( | ( (29'h166e % 7'h22))) >= 21'h608)))) <= ( ^ ( ($time > r232))))) | r5)) > 2'h2) !== r89)))))))); #10; r234 = 9'h1f5; #10; r254 = r6; #10; r39 = ( & ( $stime)); #10; r238 = ((15'h7bb7 >= 29'h70ec) & 22'hf47); #10; r65 = ((1'h1 - r123) + 12'h583); #10; r27 = (r221 == (r115 < r95)); #10; r204 = ( | ( 19'h10b)); #10; r232 = (r78 / ( ~ ( (((((8'hfa < r34) * ( + ( (r91 != ($time + (3'h2 ? (21'h3c7a / r249) : (r205 * ((r71 % r26) && r39)))))))) | (1'h0 >= 21'h4545)) != 31'h1e16) !== (((5'hc / $time) == 27'h150d) !== 5'h1))))); #10; r213 = (r116 || ( ( ~ ( 9'h1cc)) !== (((23'h10fb == (((((21'h5703 * $time) >= ((29'h1274 !== ( ( - ( 11'h56d)) | ( & ( ( + ( (6'h2 + 17'h129b))))))) >= ((( ( - ( r163)) > ((23'h2857 != 30'h64e4) / 5'h5)) || (((23'h7345 <= 21'hdf7) == r154) | r189)) > r117))) > (( ( + ( ( + ( r118)))) / 26'h7e4) <= ( + ( ( - ( ( + ( (( ( ^ ( 16'h3752)) & (11'h2b && 4'he)) != ( & ( r63))))))))))) < ( ( ^ ( r82)) == ( ( ^ ( (( ( + ( $time)) ? ( ( ~ ( $stime)) > r142) : (13'h19ae | ((25'hced != 12'h2ff) !== 30'h290b))) && (r108 > r38)))) || (29'h7ef2 | r0)))) * $stime)) == ($time ? r49 : ((30'h1631 != (r225 - r55)) - (27'h3be0 ^ ($time ? 14'h2bb1 : r25))))) | 9'h1b9))); #10; r198 = ($stime <= ((2'h0 || (r230 * r145)) || ((r31 !== 20'h7fd3) !== (r98 % ( ~ ( ( + ( (r110 <= $time))))))))); #10; r8 = 19'h16e0; #10; r145 = r147; #10; r125 = r193; #10; r182 = 1'h0; #10; r253 = ((10'h2de <= (25'h4a1d & r188)) < r181); #10; r44 = (24'h2e9a * (((( ( | ( ((r29 & r182) == r131))) / (15'h6295 | 3'h7)) > 14'had2) & r100) & (((7'h1b !== $time) % ((( ( - ( ( ( & ( ( + ( (r208 | ( & ( ( + ( (1'h0 + 30'h6481)))))))))) / 10'h170))) != r170) === ((r216 && 20'h7e5a) || ((r115 && ( ~ ( ( & ( (r68 | (r149 < (r233 < r186)))))))) | r213))) || 15'h789)) && (r59 !== 8'hfc)))); #10; r229 = ( + ( r72)); #10; r155 = 19'h69ae; #10; r56 = r65; #10; r84 = $stime; #10; r76 = $stime; #10; r235 = ((( ( ! ( r97)) | (29'h463 >= (( ( - ( r73)) | (r115 + $stime)) % 5'h15))) & ((r67 * ((( ( + ( ( ~ ( ( | ( (2'h0 !== ( + ( (((6'h37 === 20'h7815) - (8'h25 & 26'h1ee9)) != 26'h152d)))))))))) % (r128 || (r140 * ( - ( ((1'h0 > r41) == 17'h2448)))))) !== (12'h312 * ( ( ! ( r17)) > 6'h36))) + ((r172 ^ r139) / ( & ( r127))))) || 29'h6f45)) ? (((r63 ^ ((($stime === 15'h3fb7) != (( ( ~ ( ((( ( ~ ( r77)) != ($time <= ( | ( (19'h51cb != 19'hea0))))) ^ ( | ( (((27'h7fb1 ^ 22'h2e65) !== 8'h56) !== r60)))) + (8'h5b === (((10'h93 == r244) <= (14'h2620 && 3'h5)) <= ((22'h77e0 >= 13'hb60) && ( ^ ( ( ~ ( 20'h754a)))))))))) % ((((r106 & r242) | (9'h1a <= 17'h67c)) + ((r119 ^ (r206 < (r194 + (1'h1 <= 4'ha)))) ^ ( ~ ( r34)))) | ( & ( $stime)))) + ( ~ ( (r166 != 13'h147d))))) * ( - ( ( ( ~ ( 3'h0)) % ( ! ( r53))))))) ? (r102 == 3'h7) : (r60 * ( ( & ( ((r30 > (r33 <= ( | ( $stime)))) ? ((r17 <= ( ( - ( 22'h7b0a)) ? ( & ( (( ( - ( ( & ( 3'h0)))) & (r90 != (3'h1 !== 7'h2c))) / (((5'h14 ? 9'h1f : 21'h5421) & 27'h6fd6) || ( - ( r105)))))) : ((7'h52 + (r82 & (20'h218f !== (19'hca5 > 28'h7ddb)))) && ( | ( 15'h5da5))))) === 2'h1) : r187))) || 15'h3aa5))) & r178) : 16'h50d3); #10; r104 = r197; #10; r173 = 31'h818; #10; r205 = (((r254 >= ( & ( (r51 || 10'h2bd)))) | ((12'h778 ? (4'h3 && ((r82 == r40) < ((r68 <= ( ! ( ($time % r254)))) - ( ^ ( ( - ( r179))))))) : (((r196 ^ ( ! ( ( + ( r61))))) == (18'h6246 < r0)) !== ( | ( 23'h7fe)))) ^ r0)) & ( ( & ( ( | ( (10'h31a ? ((15'h5a76 != ((r49 > ( ( | ( (r106 % (( ( ~ ( 28'h4fd6)) - ( + ( 29'h7066))) > ((27'hc41 === 28'hd4b) | (6'h2d & 8'h64)))))) && ((r242 <= 24'h2822) | $stime))) && r169)) != $stime) : r56))))) ^ ( | ( (r180 ^ r203))))); #10; r237 = (((((4'h5 - ( ^ ( (((((((6'h27 ? ((2'h0 & 25'h3301) < (6'h25 | 9'h1ec)) : r223) | 31'h65e1) >= ((((31'h4659 + 17'h5965) < ( | ( 11'h631))) !== ( ~ ( $time))) * (($time / (10'h7d && 1'h1)) ^ 3'h1))) & 15'h5e87) ^ ( ( ^ ( r233)) && ( | ( 24'h3d10)))) == r49) > ( - ( 2'h0)))))) - 5'h8) && 32'h3aa2) ? r27 : 27'h7c25) ? (25'h6fc1 !== (r8 & (((r82 >= 27'h5432) === ((25'h1d79 < ( ^ ( 22'h53a7))) < r44)) / 2'h1))) : (r98 <= ((18'h56be === 13'h1971) % (r188 | r126)))); #10; r72 = (r29 / ((4'ha - (( ( - ( ((r110 == (r68 != r28)) && 23'h1d5d))) !== $time) & ( ! ( ((32'h122 >= r161) | 16'h36a9))))) < $stime)); #10; r215 = r150; #10; r32 = (23'h22ba & r68); #10; r251 = ((((((((( ( & ( ((( ( + ( r230)) || ( ~ ( (10'h214 - 8'hca)))) & 29'h64fb) * r148))) <= $stime) == $time) - ((((((r247 >= r170) > ((r209 - r248) | ( ( - ( 15'h2d06)) ? 1'h1 : (14'h2f73 | 25'h3e87)))) % ( ( | ( r170)) > (r2 === ($stime > $time)))) !== r98) / ( + ( ( | ( r156))))) + ( + ( 30'h1f05)))) != r171) === (23'h16f4 & (((( ( + ( ( ( + ( ((10'h176 % 27'h709d) !== r155))) || ( ^ ( ( ( & ( 8'hbc)) != ( ^ ( 18'h426a)))))))) === r80) !== 23'h72f3) != r118) ^ (r122 - ( ! ( (r57 * (25'h14f1 === (r168 / r149))))))))) | (r65 / $time)) == r250) ? r193 : r163) && 32'h1880); #10; r16 = ( - ( ( - ( ( - ( r182)))))); #10; r82 = r63; #10; r173 = 30'h254b; #10; r120 = (14'hd78 ^ r193); #10; r133 = ((r37 != r131) ^ r221); #10; r215 = ((25'hb1f || ( ( & ( (((((r198 | ((28'h6191 / 4'h2) > ( & ( ((((25'h4f79 | 26'h5a16) ^ (3'h2 > 21'h51e3)) * 21'h31e8) >= (r25 / 26'h3a40)))))) !== (r33 % ( - ( (((((15'h2a8c % 1'h0) + 32'h5653) + r172) || $time) ^ 23'h5215))))) == r173) != (23'h1aaa == (13'hccb ? r24 : (r86 && ((( ( ! ( (r126 !== (28'h2588 == 29'h7d09)))) == (24'h10c2 > 22'h5f23)) || ( ! ( ( - ( r16))))) % ( ( & ( r0)) ^ r129)))))) <= 3'h0))) - r115)) && ( ^ ( ( + ( ( ^ ( $stime))))))); #10; r98 = r156; #10; r129 = (((r44 <= (((r14 > ( - ( r236))) < ((23'h5704 > (r163 === ((r136 != ( ( | ( 16'h7a29)) >= 21'h19b8)) !== (31'h53bd <= r38)))) != ( & ( 24'h332a)))) > (((((((r75 >= 23'h659f) !== (29'h2824 > r29)) <= ( + ( r103))) - (r69 * ((r222 != ( & ( r11))) <= $time))) || (r252 - r29)) >= (9'h0 != 30'h7bb1)) || ( ^ ( (r204 != r33)))))) + $time) & (( ( ~ ( r161)) == 18'h371b) - ( ( + ( ( + ( ( + ( ($stime > 10'h349))))))) == $time))); #10; r224 = (25'h3bb6 ^ ((r169 !== ( + ( (($time <= r231) ? 12'h7e7 : ( ( ^ ( ( ~ ( r186)))) >= ( ~ ( ((r202 && ( & ( (11'h3f4 > (r148 < 24'h6a71))))) <= r104)))))))) == (((2'h2 % (((r226 < 2'h3) | (((2'h0 + (8'h1 || 7'h52)) !== ((r234 | ((( ( ! ( 12'h2fa)) + 23'h54ed) >= ( ! ( ( - ( 6'h1e))))) >= r230)) != 20'h7209)) - (14'hc55 % (r243 != r235)))) & (10'h110 > r103))) == ( ! ( r102))) || $time))); #10; r15 = r135; #10; r18 = r148; #10; r179 = 13'h807; #10; r144 = r116; #10; r100 = r116; #10; r44 = $time; #10; r133 = 8'h67; #10; r119 = $time; #10; r155 = ( ! ( ( + ( r55)))); #10; r241 = (r252 == ($time || r154)); #10; r162 = 21'h4542; #10; r154 = 25'h3c0a; #10; r172 = ( & ( r130)); #10; r152 = ( ~ ( r25)); #10; r229 = r1; #10; r238 = $stime; #10; r180 = 21'h942; #10; r231 = r199; #10; r39 = r247; #10; r46 = (23'h5bc != 3'h0); #10; r166 = ( | ( ( | ( (13'h8cd ^ (((r12 || ( ( | ( 10'h14b)) && 12'h430)) === r195) & (30'h28c0 % ( ~ ( 27'h521b))))))))); #10; r23 = r20; #10; r102 = ( ( | ( r216)) | 27'h7337); #10; r223 = ((1'h0 > $time) % r228); #10; r42 = ( ^ ( ((r181 === r129) && ((r204 !== ((r112 ^ ( ( | ( 9'h199)) <= (r75 == ( ( ! ( 28'h5b63)) < ( ~ ( ((r96 <= (((15'h6ad0 !== 13'h5a1) <= ( ~ ( 24'h2def))) == ( ( ^ ( 24'h146e)) / (28'h13b1 >= 11'h94)))) || ( + ( (( ( ! ( 27'h51f3)) > ( & ( 10'h2c7))) - ( ^ ( ( ! ( 1'h0)))))))))))))) == ( ( ^ ( (( ( ^ ( (((32'h4dc3 - (r216 - 27'h503c)) <= 11'h1fd) | ( | ( r46))))) && 22'h5f72) === r74))) !== (r190 / ((r33 || ( | ( ( ( + ( r53)) !== (28'h1cb9 || ( ( | ( (1'h1 && 27'h699))) * ( & ( (16'h3dd0 === 17'h5fae))))))))) ^ ( | ( 12'h1de))))))) < r38)))); #10; r174 = ( & ( 12'h666)); #10; r79 = ((r135 && r189) != ( | ( r186))); #10; r150 = (3'h3 * ((r251 !== ((9'h1ef - $stime) - (( ( - ( ( - ( r49)))) || r241) == ((( ( - ( 32'h4db1)) == ((r247 !== ((($stime + ((16'h42ad != 23'h2b27) ? r203 : (17'h2b91 % 27'h7fd3))) + ( ( & ( ( | ( 12'ha1b)))) !== ((21'h4286 % 22'h536e) ^ 16'h6608))) ? $stime : 14'h380a)) | ( ~ ( ((r115 & ((r16 + (30'h5605 & 17'h245)) - 19'h4ee4)) !== 14'h899))))) != ( ( ! ( r204)) >= (r58 + ((1'h0 === 8'h8b) + ((((9'h10 === r7) / r217) <= 5'ha) * r254))))) == ( ( & ( 6'hd)) && 11'h440))))) ^ ( - ( (r27 & ((r177 === (r226 != $stime)) | 9'hf)))))); #10; r248 = r209; #10; r5 = r51; #10; r21 = 12'h97c; #10; r51 = ( ( | ( ( ! ( (r174 > ( ( - ( 8'h2a)) >= ( ( + ( (( ( ~ ( r65)) + 8'h41) ^ 28'h7bc3))) / (13'hf60 * r126)))))))) >= ( ( - ( $stime)) <= ((r14 ^ (r25 >= 10'h344)) & ( ( - ( 21'h2549)) <= ((22'h7049 > 4'hd) ^ r172))))); #10; r158 = (r89 !== (( ( ^ ( ((r215 <= r205) * ((r142 % 15'hce6) < r253)))) | r84) + ( & ( (r75 > ( - ( ( ( ! ( ( | ( (r183 > 26'h7d82))))) >= ( ~ ( (((r79 % ((r124 === ((r168 * ( ~ ( 19'h6332))) <= ( + ( ( + ( 32'h4365)))))) & ( ( ! ( ( - ( ( + ( 31'h67f5)))))) && r70))) >= (1'h1 & ( ( | ( ( ! ( $time)))) != ( & ( 7'h57))))) + r71))))))))))); #10; r180 = ((r27 ? ($time - ( - ( ( ^ ( r86))))) : r20) - (( ( ~ ( (( ( ~ ( (30'h1d1e == ($time == (23'h196b === r86))))) & (21'h7750 >= ( ( ~ ( ( ( ! ( ($stime == 25'h47c6))) % ($stime && r93)))) / ($stime && ((r237 || r84) ^ ( | ( ( + ( r121))))))))) % ( - ( ( ( + ( r158)) + r54)))))) == ( ( | ( 16'h315f)) >= ((((( ( + ( ( ~ ( r74)))) + 20'h7b7f) || ( & ( ( + ( 23'h4708))))) | (( ( & ( (4'h6 === r209))) || 13'h9c8) / r229)) ^ ( | ( ((4'hf ? 24'h4865 : 16'h6051) > (10'h250 <= 16'h354))))) || (r139 === (6'h3e <= 16'h59a))))) || (r80 ? (($time != ( ~ ( ( ~ ( (r243 ? ((28'h741c % r164) + ( & ( ((( ( & ( r252)) || 26'h14dd) && r76) % r123)))) : 12'h35b)))))) ? (18'h36a6 === r202) : (((((27'h473b | r219) * r121) | (r30 >= (( ( ! ( 21'h52b8)) != (3'h0 <= (r38 % (((4'hf === 17'h45ca) % ( - ( 15'haa3))) === ((20'h6ddf > 31'h6ad1) !== $stime))))) < r48))) > r110) >= 6'h3d)) : r163))); #10; r72 = (( ( ~ ( ( ( ~ ( ( ( - ( ( & ( ( ^ ( r217)))))) | (r180 == r234)))) <= 24'h480a))) % $stime) !== (24'h5c74 > ((r244 | ( ( ~ ( (((((23'h971 / ( | ( (13'h121f <= ( ( - ( 28'h6b51)) >= (12'hcfc || 2'h1)))))) ? ((r11 | ( - ( 32'h450d))) > r254) : ( ~ ( $stime))) + (r74 & r104)) || ( - ( r235))) | ((12'hafb % r158) - 17'h7d6b)))) ^ r225)) ? ( ! ( ( ~ ( ((((((((((29'h532 <= 16'h3d4b) ? r138 : r213) || (16'h52cf > (10'hc9 + 1'h1))) || $time) >= 16'h2a91) | ( & ( ( ^ ( r43))))) < ( ^ ( ( | ( (r91 | 2'h3)))))) / r186) * ($time / (r182 != r171))) < (( ( ! ( 19'hf53)) % r173) ^ r90)))))) : $stime))); #10; r162 = (13'h1684 !== 20'h5bae); #10; r125 = $time; #10; r65 = ((21'h5040 % ( & ( (r168 / (r250 * r214))))) <= (21'h5bf != ( ~ ( $time)))); #10; r132 = 14'h1f62; #10; r35 = ( ! ( ( - ( (((((((8'h0 % ((( ( - ( ((17'h4f6 || 23'h241d) * (24'h3ec2 <= 31'h7ec8)))) / $time) >= (r114 & r213)) == (10'h33f === r79))) ? ( ~ ( 16'h7540)) : ($stime || ((r144 - 20'h7607) !== ( & ( 6'h7))))) == ( ( ~ ( ( ^ ( (r251 / ( ( ~ ( $stime)) < (((12'hcdd & 7'h6f) && (18'h7be < 16'h51a7)) || ( ( ! ( 31'h5b74)) ^ r127)))))))) + r254)) - r158) === ( | ( 11'h317))) ^ (r88 - ( ^ ( (( ( ^ ( r179)) | ((r137 <= r77) === ($stime == ( ( + ( (r190 !== ( ! ( 24'h667d))))) ^ $time)))) / r135))))) | (((r151 || ( ^ ( $stime))) >= r38) == (((( ( + ( ( ( - ( 3'h5)) > (((((11'h7ed > 23'h4848) + (12'hbf8 / 5'hb)) ^ r115) && ((32'h4a9d | (30'h66c5 & 30'h3e62)) >= 22'h14fe)) > (((r54 | (19'h3af4 ? 20'h63c8 : 3'h6)) | ((5'h19 | 2'h0) >= ( ~ ( 2'h2)))) === ( ( ^ ( ( ~ ( 5'h1d)))) != (r8 == (27'h69be % 32'h3b05)))))))) > 17'h6896) <= $time) * 9'h17e) >= (r253 | r11)))))))); #10; r42 = 16'hf15; #10; r139 = ((( ( & ( (14'h3f9d === ( ^ ( 21'h5f2f))))) + 2'h2) % 22'h5b3c) !== ( | ( ((( ( ! ( r51)) / r88) ? 9'h1a3 : $stime) > 9'h194)))); #10; r8 = ( ( & ( 20'h40b8)) ? ( ( + ( (( ( + ( ($time | ((3'h4 <= r197) == r234)))) != r4) - (r114 * 23'h46dc)))) % r68) : r172); #10; r181 = ( - ( ($stime % (23'h1d8f && ( - ( ( ( ^ ( $time)) | (r108 & r26)))))))); #10; r159 = (((18'h535a % r30) * r65) >= ((( ( & ( ((((((r105 || 31'h4634) * ((r174 == (r61 || ( & ( ( + ( 6'he)))))) <= r233)) / $stime) || (((20'h55e8 * 20'h57da) != 27'h10ab) && (((( ( ^ ( (25'h574b != 25'h59bb))) % ((5'h13 === 17'h4256) !== (28'h5ecc !== 1'h1))) <= ( | ( r173))) !== $stime) || (( ( ! ( ($time >= (12'h42c | 23'h60eb)))) % (($stime >= 14'h23de) == r219)) > r65)))) && (18'h7c43 !== r96)) != (( ( - ( ( ( - ( ((r100 ? ( & ( r142)) : ( - ( r30))) === r236))) < ( ! ( r38))))) | $stime) - (( ( | ( r68)) < ( ^ ( (29'h6ea5 === ((((10'h243 === 31'h625f) > ( ~ ( 26'h75a))) - r95) <= ( | ( (r92 === $stime)))))))) > ( & ( ($stime >= r76)))))))) | r92) ^ (10'h2f2 !== $stime)) >= r103)); #10; r35 = (31'h1e3a * 13'h289); #10; r50 = ( ( + ( ( ( - ( 13'h1945)) & ( | ( ( ! ( r128))))))) * (((($stime >= 7'h61) || (((( ( ! ( (r180 > r44))) * (($stime >= (( ( + ( r106)) == ( ~ ( 32'h59e7))) || 5'h9)) && 13'hcd)) < ( ( & ( 15'h5791)) === ( + ( ($time - (((( ( ~ ( 30'h6092)) & r184) + 31'h27e1) == ((31'h1dfa + 7'h68) != ( ~ ( 22'h10ab)))) & (16'h30ab / r158))))))) ? 12'hcb7 : (31'h4c6d !== (26'h4e33 < ((20'h1dcd / ((( ( & ( (23'h3c7c < 4'h6))) % ( ( | ( 18'h6b37)) / (31'h56e7 - 9'h1b5))) - r174) >= 12'h281)) !== (r100 * r11))))) ^ r201)) * ( | ( 21'h41a0))) <= r130)); #10; r17 = ( & ( ( + ( r76)))); #10; r99 = ( ~ ( ((((r50 + (((r49 / (($stime * $stime) >= ( | ( r137)))) > (r27 <= 9'h151)) / ((((((r222 > r101) % r93) + ( ^ ( (3'h2 || ( - ( 28'h2340)))))) == ( ( ^ ( (r62 | (r201 === $time)))) <= 18'h6c9e)) > ( | ( r235))) <= ( ( ^ ( (((22'h402 | 12'h9b) | r92) * (r181 / ((r17 & $time) > r160))))) != r20)))) & (((r109 >= ((r237 == ( ( + ( ((((27'h7c62 > 5'h10) || 28'h4e87) | ((17'h62af === 21'h4f4) < ( ! ( 22'h4838)))) >= $stime))) && 23'h2eb3)) ^ ( ( ^ ( (r112 < (r212 > 6'h3d)))) ^ ((( ( + ( 8'hcc)) && 22'h6bf5) >= (r109 <= (((8'h3a == 25'h11d) == 19'h19b8) / ( & ( $time))))) ^ (32'h174d % 31'h75c7))))) / ((r37 >= ( ( ! ( ( ~ ( (r0 <= ((r215 * 27'h649a) + 20'h7c51)))))) < r221)) !== ( ^ ( r159)))) === r133)) + (23'h38d1 ? ((($stime ? ( - ( ( - ( ( ( & ( ($time < r66))) ? r170 : (( ( ^ ( ((20'h6ff5 * 26'h4341) - r78))) / r196) < r246)))))) : ( ( + ( ( ( | ( ( ^ ( 18'h3e9)))) ? r129 : r245))) % ( ! ( r128)))) / $time) * r156) : 16'h1426)) == 9'h114))); #10; r102 = ( ^ ( ( ^ ( ((r211 ^ (r229 === r249)) < (((r17 * r174) * r229) <= ( ( & ( 26'h56cf)) || $time))))))); #10; r7 = r109; #10; r195 = (r100 - r246); #10; r248 = ( ! ( ((r14 === (((r120 > ( ( | ( r100)) !== ( ! ( 2'h2)))) > (( ( & ( 6'h18)) % ( | ( 1'h0))) && ( + ( r251)))) / ( ~ ( ((r233 - 24'h7a6a) / r56))))) === ( ( - ( r104)) != ( ^ ( 1'h0)))))); #10; r160 = r14; #10; r164 = r57; #10; r26 = ( ~ ( r63)); #10; r20 = 27'h7948; #10; r33 = (((r235 > ( ( + ( ((22'h4078 % 28'h43d5) ^ ( ( | ( ( + ( r216)))) == r196)))) || (((14'h3a11 - $stime) == ((r45 - 5'h5) ^ ( ~ ( ( ( + ( (((((11'h70b | 19'h604f) > (29'h2b8 * 4'h8)) ^ r130) && ( ( & ( (13'h2b5 - 14'h34f9))) ^ ($stime < 10'ha5))) < r19))) * (((( ( ^ ( (7'h51 === 9'h7d))) / ( & ( r242))) * ( + ( (r120 * (31'h3f97 != 27'h5c58))))) & 6'h2f) < ( ( & ( r148)) ^ ( + ( 14'hfd5))))))))) == ( ! ( r231))))) + r248) && ((r48 | (r187 | (r221 == ((r42 & r204) == r140)))) < r15)); #10; r221 = (16'h49d1 || (r58 + ( ( + ( ( ^ ( r240)))) > r5))); #10; r245 = ($time | $time); #10; r80 = r72; #10; r47 = $stime; #10; r43 = r104; #10; r128 = r105; #10; r253 = r67; #10; r145 = r81; #10; r126 = 15'h9eb; #10; r24 = r162; #10; r233 = $time; #10; r182 = ( ! ( (($time ^ (r171 === 11'h452)) - r95))); #10; r94 = r219; #10; r231 = (((((r234 == r75) - ( ^ ( $time))) | ( ( & ( ((((( ( + ( ((((19'h3cbc != 29'h50b3) === r179) === $time) >= 31'h7c7b))) > ( ( & ( ((r174 & (3'h0 - 18'h4c8f)) / 23'h16fc))) !== ( | ( ( ^ ( ((32'h1b5c * 24'h1c03) > r120))))))) || (( ( ^ ( r53)) != ((((8'hec <= 9'h169) !== $stime) === ( ( - ( 16'h304e)) < (26'h3834 <= 18'h58bc))) ? 25'h6ca3 : 27'h60a2)) >= 7'h74)) - $stime) !== ( ( & ( (r193 <= r106))) && ( & ( ((9'hc || r173) != r85))))) / ( ~ ( ((r82 / 25'h5809) <= ((r166 % (10'he3 - ( ! ( ( ( ~ ( ( + ( 21'h5ea1)))) ? 32'h6caa : $stime))))) === (($time !== 15'h2f0c) > ((r134 && r13) & r131))))))))) < ((19'h706d && ($time & (($time === 18'h786a) <= 13'h1ed6))) ? (r176 == r217) : (r15 < (19'h4b23 ^ 20'h3584))))) ? 19'h46f1 : 16'h10bc) ^ (28'h57a5 >= ( | ( $stime)))); #10; r64 = (((( ( & ( ((((19'h1c36 >= 27'h1fc7) ^ r191) <= 18'h479f) && ((((((17'h38f5 / 16'h7871) > r19) < ( ^ ( ( ( ! ( r255)) <= ((r196 / $time) ? ( & ( r91)) : $stime))))) - (15'hc67 ^ ( ( ! ( (( ( | ( 10'h2bd)) == (9'hba > 4'h8)) + r104))) >= ( & ( r46))))) !== ( ( & ( r158)) - (( ( & ( 27'h5bca)) ^ ( ~ ( r185))) === (r208 | ( ! ( (((31'h3393 && 24'h16f4) <= (14'he7a / 15'h3c50)) & r73))))))) != ( ( ! ( 5'h14)) >= ( ( ^ ( 25'h2f7f)) / r25)))))) + ((7'h32 ^ (( ( + ( ((((r171 == ( - ( (24'h24c9 != 27'h188c)))) % (21'h1cd3 !== ((21'h4f82 !== 5'h5) !== (30'h592c && 31'h4d6)))) & ( ( | ( 32'h10e6)) * (r51 < (2'h3 && ( ! ( 9'hb5)))))) >= ((( ( - ( r100)) + (r94 < (4'h9 - 19'h7687))) / 30'h3d99) < ((22'h1717 <= (30'h7a58 ? 23'h26de : (2'h3 * 32'h15f2))) + r226))))) || r220) ^ r147)) & r163)) && 25'h4a4b) === r71) | 13'h13da); #10; r247 = ((r64 >= (6'h6 - 30'h1466)) < 10'h89); #10; r80 = 19'h4198; #10; r186 = r249; #10; r95 = r153; #10; r32 = 17'h76a7; #10; r81 = ((r230 & r127) >= ( ( ^ ( r166)) == (20'h625d % r106))); #10; r150 = r47; #10; r16 = ( ( ! ( ( - ( r127)))) == (20'h2d74 ^ ((( ( & ( ( + ( ($time === ( | ( r121))))))) - r238) | ((26'h7f81 | r147) || (16'h564f & r121))) | 29'h30a3))); #10; r159 = 7'h5; #10; r50 = r178; #10; r198 = (( ( ! ( $stime)) <= 30'h3341) >= ( ~ ( (14'h2cc8 && ((((r238 === ( - ( ((18'h3731 || (21'h6044 > r225)) + $stime)))) && $stime) < ( ( - ( ( & ( ( ( + ( ( ~ ( 31'h5c4f)))) * r224))))) / (( ( | ( 17'h3bc0)) / r141) & r154))) ^ ((r176 + ((18'h3d71 === r214) ^ ((($stime >= r179) | ( + ( 6'h28))) % ((r91 + ((r10 <= ($stime % ( ! ( $stime)))) & (( ( & ( (24'h274b + 5'h1e))) == 30'h4efa) - (r23 > r185)))) !== (((r236 <= ( ~ ( ($time ? (20'h6978 > 25'he4c) : (29'h18de | 13'h19a7))))) & (($time > ((27'h7cd5 || 10'h2d1) / ( | ( 7'h69)))) != (((18'h6172 | 19'h59d4) == (30'h4c9b && 19'h2001)) !== ((15'h73ea % 20'h1953) ? r244 : r76)))) % (r143 ? (r59 > ( ^ ( r141))) : ((19'h13f7 < ( ^ ( (26'h7eda ^ 1'h1)))) != r136))))))) && $stime)))))); #10; r100 = (((($stime ? r212 : ((r115 >= 13'hd24) === (( ( & ( ( + ( (( ( + ( r7)) != ((((17'h3105 ^ 16'h5f7b) != 28'h7cd2) && 7'h2) / ((r122 ? (20'h5bb0 != 26'h66d1) : (32'h251d * 30'h1913)) === r221))) / 4'h6))))) ? ((r54 && (24'h50eb / 3'h0)) - (r249 | r87)) : (( ( ^ ( ( ( ~ ( ( - ( ((18'h165 !== 18'h7eb7) || (29'h26d4 && 5'h6)))))) && (r36 <= (r140 % ((13'h1b93 && 10'h97) - (9'he6 % 10'h30e))))))) * ( ! ( ((((4'h3 && (14'h151b || 32'h7a7e)) * r208) % ( ^ ( r215))) < ( ^ ( 29'h2bb1)))))) + ((r123 <= 29'h381e) >= ((r177 <= $time) && 22'h6707)))) > r183))) <= (((30'h2485 > (7'h5b * (((r8 != 27'h4ad2) & r75) == r104))) & ((r222 + r255) + 2'h1)) > 7'h48)) < r195) & (r232 + ( - ( ( | ( 5'hc)))))); #10; r111 = $time; #10; r220 = ( ( & ( 32'h47c4)) != ( ( ~ ( (($stime <= $stime) >= (r22 !== ( ( | ( 15'h82b)) | r125))))) - 20'h65a5)); #10; r103 = ((r212 & (r10 != (2'h2 | (r201 - ( ! ( ( ^ ( (r100 && (r69 % (r86 + 25'h2418))))))))))) % ((5'h5 || 3'h7) & (( ( + ( ( & ( (r236 + ((r25 & ( & ( ( ( ~ ( (29'h682e + ( ~ ( (23'h4ffa % 5'h7)))))) == 32'h6eb2)))) < r202)))))) == ( ^ ( 7'h56))) % (32'h14d5 + ( - ( ((3'h7 | ((((( ( - ( 27'h237d)) != ( | ( ( | ( 25'h1e5a))))) ^ ( ( ^ ( (r244 === (28'h502d - 32'h2e48)))) / (r147 < r167))) && r42) > (( ( ^ ( (((18'h3679 === 24'h3b03) * (1'h1 - 17'h6b4)) | 3'h1))) != r141) < ( ( + ( 30'h1484)) & ( | ( (((6'h3b === 20'h4cb9) % (23'h7809 !== 5'h7)) > 23'h79ca)))))) <= ( ( ! ( r254)) - r79))) <= ( ( + ( (r25 && $time))) % ((((22'h51e6 && (r206 * $stime)) !== r38) | r148) - r127))))))))); #10; r55 = r221; #10; r206 = r156; #10; r180 = ( ~ ( 16'h2225)); #10; r67 = ( + ( (((r203 && r69) === r123) != r202))); #10; r75 = (( ( | ( ( ( | ( r9)) < (11'h3d9 === ( ! ( ( ( ^ ( r99)) === r224))))))) == 28'h2fb6) && ((30'h8c3 - r134) < 23'h5849)); #10; r217 = (18'h2761 % (r56 | (($time < (20'h6ce0 * ( - ( (r235 * (( ( - ( ( | ( ((((6'h3a + 29'h3b2e) == 12'h6d5) + r79) > (r156 && ((26'h257f == 2'h2) || (9'h72 == 16'h41d9)))))))) * ( ( ! ( ((r48 - ( + ( (2'h3 + 14'hb38)))) ? r166 : r136))) !== ( | ( ( + ( r74)))))) != ($stime > ((26'h39cb !== r112) % ( ( - ( r124)) == r221))))))))) < r23))); #10; r14 = (r167 <= ( ! ( (r106 >= r22)))); #10; r254 = (r246 + ((((r132 && ((( ( + ( 6'h0)) < r228) === (25'h5358 === ($stime % 15'h7d8d))) == r28)) || $stime) ^ (r24 * ( ^ ( 13'h402)))) && ( ( | ( ((r100 + $time) === r249))) != ((19'h52e8 - 16'ha15) & (((1'h0 <= 23'h39c8) % ((19'h3f6b > ($time & r181)) >= r47)) + (( ( + ( ( | ( 2'h2)))) === r63) == r48)))))); #10; r231 = $stime; #10; r198 = ((13'he17 === (( ( ~ ( ( ^ ( (r249 === ( | ( ((( ( ~ ( ( | ( ( ( ! ( 24'h53e3)) & (21'h3e5d != 22'h7f09)))))) >= r72) == r147) > ( & ( ( ~ ( (7'h5c == r217))))))))))))) != r206) && ( ( - ( ( & ( (r203 / r196))))) & ($stime ^ ((7'hf && 6'h13) < 31'h2e8e))))) <= ((r29 >= r103) == 29'h4b73)); #10; r208 = (r245 * 21'h176); #10; r232 = ( ! ( ( ^ ( (r195 <= r240))))); #10; r120 = $stime; #10; r25 = $stime; #10; r36 = (( ( | ( ( - ( ( ( | ( r63)) & (( ( | ( 10'h279)) % ($stime != r51)) != ((( ( ! ( r108)) ? (r28 && (r75 / 13'h302)) : ( | ( (r19 == 27'h2750)))) - (r135 + r97)) || $stime))))))) && ( & ( 29'h78e2))) >= 9'h9c); #10; r126 = 27'h5db1; #10; r7 = 27'h61d3; #10; r254 = ( ^ ( 6'h32)); #10; r76 = r9; #10; r106 = r11; #10; r115 = ((r69 > r37) && (r35 == r169)); #10; r190 = r31; #10; r39 = ( + ( (15'h2c29 ? r216 : ((13'h928 != ((r216 | r94) / ( ! ( (r8 !== (r209 & 8'hc6)))))) + 29'h1e5d)))); #10; r77 = r166; #10; r211 = r156; #10; r229 = (8'h6d >= ( ~ ( $time))); #10; r219 = ((r171 ? r116 : 25'h2ba2) | r103); #10; r178 = ( ( - ( (( ( - ( (r111 || r145))) ? ((( ( & ( r207)) + (r100 + (r85 / (29'h7a89 == 29'h73df)))) != (r191 === 30'h24b3)) >= (r163 == ((r136 % ( ( | ( (11'h78f && ( | ( (2'h1 >= ( ( - ( 10'h1d4)) > (7'h39 % 26'h14d3)))))))) + r43)) / ($stime >= r192)))) : (r211 === 10'h381)) != ( - ( 6'h1f))))) > (r63 !== ( ~ ( (r71 / 15'h32a7))))); #10; r235 = ($stime === r52); #10; r181 = ( ! ( (( ( & ( (r72 | ((r82 - (r122 - r110)) / 3'h1)))) > (1'h0 != ( & ( r117)))) % r35))); #10; r115 = 31'h222c; #10; r21 = 10'hbc; #10; r202 = (( ( & ( $time)) > ((r141 || (28'h91 || ( - ( 25'ha3e)))) || ((r78 & ((r252 > ( ~ ( 2'h1))) > (r235 ^ $stime))) && ( & ( 9'hbc))))) == $time); #10; r255 = ( & ( 30'h67f1)); #10; r65 = 13'h342; #10; r208 = ( & ( (9'h148 !== ((((r86 - r205) | 16'h10c7) + $stime) / (r145 / ( ^ ( ( & ( 24'h4f19))))))))); #10; r25 = (r242 ? ( ( | ( (((((9'hab + (r120 & ((( ( + ( ( - ( r5)))) ? r90 : r232) % ( ( | ( (11'h6ec ? r150 : r41))) && 22'h5c1a)) !== ((12'hd86 * ((4'h5 + r76) * $stime)) != ((( ( | ( 28'h378b)) === 5'h11) != r235) >= 5'hb))))) != (((r232 !== ((r240 * r116) * ( ^ ( (((18'h6629 < 31'h6fe7) * (28'h76b ^ 11'h18d)) > 32'h79d2))))) % (17'h4ad6 ? r19 : 29'h25f7)) | 28'h695e)) <= r176) !== 3'h2) === (9'h14f !== ((r71 % ( - ( (r82 > ((6'h1b ^ ( & ( 22'h355c))) | 21'h4af7))))) != ( + ( (( ( & ( ( ( + ( $stime)) | r247))) <= 12'h5ff) | 5'h1a)))))))) < r124) : ( + ( 25'h1324))); #10; r216 = 16'h6943; #10; r223 = $time; #10; r182 = r155; #10; r64 = (r73 - 31'h2134); #10; r254 = 9'hfb; #10; r180 = ( ( & ( ((r246 < (( ( ! ( r9)) <= r190) >= r25)) % (r150 != 6'hf)))) + 13'h1361); #10; r26 = (( ( | ( r12)) | r21) - ( ~ ( ( ( ~ ( r129)) % (r99 < (r227 != (17'h1614 && ((r18 >= ((r85 % (r91 | r23)) <= 21'h2add)) === ( ( - ( r175)) === 15'h60cd))))))))); #10; r58 = (((26'h4eb6 >= r67) & ( ( - ( ((($stime < ( ^ ( 24'h5968))) != ( ( & ( ( ^ ( r173)))) <= (($stime * (( ( + ( ((r216 > $stime) & r144))) || r153) & ( | ( ( ^ ( $stime)))))) <= 22'h5feb))) % ( ( ^ ( r192)) + ( + ( 9'h140)))))) | 16'h6670)) === ( ! ( ( - ( ( - ( ( ( | ( ( + ( ( + ( r128)))))) / ((( ( - ( (4'h3 !== r13))) | r212) >= (r48 + (18'h2621 != ( ( ! ( (6'h2b | r84))) / ((( ( ! ( ( - ( 1'h1)))) + r38) && ( ! ( r39))) == 21'h46a))))) != $stime))))))))); #10; r227 = 4'ha; #10; r151 = r208; #10; r180 = (((r193 || r112) & (r198 !== r202)) | r46); #10; r81 = (((r224 <= 27'h4c16) ? ((r96 == ((($time % (r59 && r245)) !== 28'h5b91) < ( | ( ( ^ ( 22'h78)))))) + 30'h1c62) : (r225 < ((18'h2d37 < ( ( ~ ( ( ^ ( 25'h73f9)))) == 4'h5)) ? ((r158 & r216) - (r243 !== r243)) : 24'h2bb7))) > 1'h1); #10; r143 = r52; #10; r222 = (( ( ^ ( r10)) + (22'h3a15 && ( ( ^ ( r163)) < 4'h8))) != ( ! ( ((r119 % ((r184 || ((((((18'h62e0 ? ((r123 > r7) * ( ^ ( r81))) : ( + ( ( & ( r60))))) === ( ^ ( (2'h2 ? ((18'h261a - 14'h226f) !== (10'h88 / 25'h5b0e)) : ((16'h4605 * 22'h6ac6) == 14'h32ee))))) % ((r135 * 25'h303b) && 13'h143b)) % r94) & ( ^ ( r16))) * ( - ( ((((((r183 & r178) && ( ( ! ( 19'h2f4b)) * (31'h7e35 + 12'h73e))) > (((18'h5c0c === 28'hb1c) > (1'h1 || 5'h1a)) ^ r54)) ? r222 : 25'h54cf) | (r131 - (r248 & r78))) == 18'h5932))))) % r73)) < r194)))); #10; r241 = $stime; #10; r4 = ( ( & ( r125)) <= (r41 ? ((23'h312d != r35) > r184) : ((19'h2838 + r31) == 25'h25bc))); #10; r65 = r4; #10; r68 = r86; #10; r46 = 2'h2; #10; r123 = ((((r247 || ($stime | r248)) ? ( ~ ( ($time & (r73 === r43)))) : 5'h16) > 25'h4e87) == r2); #10; r177 = $time; #10; r15 = ( ^ ( r236)); #10; r236 = 25'hdf4; #10; r186 = ( ( ^ ( (r163 % ((r186 ^ ( ( ! ( $stime)) * $time)) && r104)))) | 21'h3b98); #10; r238 = (r170 + 1'h0); #10; r167 = r11; #10; r47 = ( ~ ( (r164 !== (27'h2b93 | 19'h3f3)))); #10; r152 = 13'h1ae6; #10; r136 = 11'h27f; #10; r87 = r50; #10; r44 = (r105 && ( ~ ( (((( ( | ( $stime)) / ( - ( 21'h58a3))) * 18'h2973) > ( ( - ( $time)) ? (((15'h3f4c ^ (r180 - ((r233 * $stime) !== r28))) | 15'h4cb7) - (r234 * ( ( ^ ( 7'h4d)) > (((r200 && 23'h14a0) != r159) <= ((( ( & ( ( ~ ( $time)))) - r226) | 16'h45eb) - r22))))) : r232)) === r165)))); #10; r85 = (r147 > r18); #10; r231 = ((8'h94 ^ 4'h5) ? (((r200 || ((($stime & r75) && 11'h0) & 32'h44a8)) || r49) - ( ^ ( (r204 | r161)))) : ( ( + ( (14'h1ec9 === ( - ( ( & ( (16'h1ac3 == r40)))))))) <= (( ( - ( r196)) % ( | ( ((30'h5eb9 | ( ( ^ ( ( ^ ( (((((15'ha3e + 3'h1) & r235) & (31'ha50 ^ ( + ( 21'h1246)))) != 4'ha) != ( ^ ( (6'h11 != r84)))))))) / ( ( ~ ( (r199 - ((((19'h6553 + 29'h2692) - 11'h87) & r215) != r247)))) & r129))) <= 10'h2d8)))) ^ (r63 == r161)))); #10; r243 = ( + ( ( ! ( ( ! ( ($stime >= r141))))))); #10; r225 = ((r227 ^ ( ^ ( (((r211 != r246) != 1'h0) / ((r151 / (r189 - ((2'h0 ? ( | ( ((17'h15be != 25'h57cd) || r18))) : r130) <= r133))) > ( ( - ( r177)) & r100)))))) ^ (30'h29af ? r155 : r154)); #10; r188 = r9; #10; r20 = 7'h30; #10; r47 = r47; #10; r58 = r172; #10; r25 = 14'h2732; #10; r120 = r209; #10; r234 = r122; #10; r109 = 32'h6179; #10; r220 = $stime; #10; r62 = 20'hf98; #10; r123 = 30'h434c; #10; r157 = ((9'hdf !== r221) != (r158 ^ 27'h7b5b)); #10; r118 = r28; #10; r225 = $stime; #10; r144 = (r5 == ( ( & ( $time)) < ( ( + ( 19'h1ed0)) != 2'h1))); #10; r134 = ( ^ ( 4'h6)); #10; r6 = ( - ( 21'h63eb)); #10; r81 = ( + ( ((((( ( + ( (($stime != (( ( - ( (30'h417 * 9'hd2))) !== (r98 && (31'h2b9b >= ( - ( ( | ( 4'h2))))))) / ( ! ( 21'h3fae)))) * r7))) !== ( ! ( r89))) + (32'h6ea2 + r41)) % (6'h2b === ($stime - ((12'h589 || 3'h4) | (((31'h73e9 ? ( ( | ( ( ( - ( r222)) >= ($time + (13'h126a * 30'h491b))))) ? r80 : ( ! ( ( ( + ( (20'h15ba >= 20'ha2))) >= (1'h0 === 32'h7b25))))) : ( + ( ( ( + ( r171)) / 14'h2d54)))) === 20'h2b36) ^ r30))))) !== ( ( ^ ( (r242 - $time))) && ( | ( r56)))) * ( ( + ( ( ! ( 6'h35)))) >= (r1 - r197))))); #10; r156 = 18'h31e3; #10; r11 = ( ~ ( r46)); #10; r140 = r153; #10; r230 = $time; #10; r221 = ( ( ! ( 4'hb)) >= 11'h400); #10; r228 = 10'haa; #10; r125 = ((17'h2e5c > ( ~ ( (r130 - r65)))) > ((r27 - (((r7 == ( | ( (((r242 || ( ~ ( r127))) * ( + ( ((((r163 >= (18'h76bb == 3'h1)) & r140) ? (r137 == ((19'h1a8 && 20'h4b97) == 22'h44f5)) : r210) ? ($time / 23'h2b69) : r56)))) <= (16'h5540 + ( ! ( r90))))))) !== r76) & ( ! ( (r21 < 31'hbd9))))) + r248)); #10; r160 = ((25'h1e99 & ( - ( (((r104 & (r27 | (((17'h320e || r91) - (r111 != 31'h23ab)) !== r116))) % (( ( ! ( r132)) <= 21'h7a3d) || (((r78 != ( ( ! ( ( ~ ( ( ! ( ( ( ^ ( 8'h8)) != 3'h6))))))) < ((((r197 == $time) + ( | ( ( ^ ( 17'h4d54))))) && 6'h9) - ( ^ ( (( ( ! ( 7'h48)) % ( ! ( 8'h7e))) != (24'h38e3 || r47))))))) + r108) >= r183))) ^ r103)))) && 20'h1ff0); $displayb("r0 = ",r0); $displayb("r1 = ",r1); $displayb("r2 = ",r2); $displayb("r3 = ",r3); $displayb("r4 = ",r4); $displayb("r5 = ",r5); $displayb("r6 = ",r6); $displayb("r7 = ",r7); $displayb("r8 = ",r8); $displayb("r9 = ",r9); $displayb("r10 = ",r10); $displayb("r11 = ",r11); $displayb("r12 = ",r12); $displayb("r13 = ",r13); $displayb("r14 = ",r14); $displayb("r15 = ",r15); $displayb("r16 = ",r16); $displayb("r17 = ",r17); $displayb("r18 = ",r18); $displayb("r19 = ",r19); $displayb("r20 = ",r20); $displayb("r21 = ",r21); $displayb("r22 = ",r22); $displayb("r23 = ",r23); $displayb("r24 = ",r24); $displayb("r25 = ",r25); $displayb("r26 = ",r26); $displayb("r27 = ",r27); $displayb("r28 = ",r28); $displayb("r29 = ",r29); $displayb("r30 = ",r30); $displayb("r31 = ",r31); $displayb("r32 = ",r32); $displayb("r33 = ",r33); $displayb("r34 = ",r34); $displayb("r35 = ",r35); $displayb("r36 = ",r36); $displayb("r37 = ",r37); $displayb("r38 = ",r38); $displayb("r39 = ",r39); $displayb("r40 = ",r40); $displayb("r41 = ",r41); $displayb("r42 = ",r42); $displayb("r43 = ",r43); $displayb("r44 = ",r44); $displayb("r45 = ",r45); $displayb("r46 = ",r46); $displayb("r47 = ",r47); $displayb("r48 = ",r48); $displayb("r49 = ",r49); $displayb("r50 = ",r50); $displayb("r51 = ",r51); $displayb("r52 = ",r52); $displayb("r53 = ",r53); $displayb("r54 = ",r54); $displayb("r55 = ",r55); $displayb("r56 = ",r56); $displayb("r57 = ",r57); $displayb("r58 = ",r58); $displayb("r59 = ",r59); $displayb("r60 = ",r60); $displayb("r61 = ",r61); $displayb("r62 = ",r62); $displayb("r63 = ",r63); $displayb("r64 = ",r64); $displayb("r65 = ",r65); $displayb("r66 = ",r66); $displayb("r67 = ",r67); $displayb("r68 = ",r68); $displayb("r69 = ",r69); $displayb("r70 = ",r70); $displayb("r71 = ",r71); $displayb("r72 = ",r72); $displayb("r73 = ",r73); $displayb("r74 = ",r74); $displayb("r75 = ",r75); $displayb("r76 = ",r76); $displayb("r77 = ",r77); $displayb("r78 = ",r78); $displayb("r79 = ",r79); $displayb("r80 = ",r80); $displayb("r81 = ",r81); $displayb("r82 = ",r82); $displayb("r83 = ",r83); $displayb("r84 = ",r84); $displayb("r85 = ",r85); $displayb("r86 = ",r86); $displayb("r87 = ",r87); $displayb("r88 = ",r88); $displayb("r89 = ",r89); $displayb("r90 = ",r90); $displayb("r91 = ",r91); $displayb("r92 = ",r92); $displayb("r93 = ",r93); $displayb("r94 = ",r94); $displayb("r95 = ",r95); $displayb("r96 = ",r96); $displayb("r97 = ",r97); $displayb("r98 = ",r98); $displayb("r99 = ",r99); $displayb("r100 = ",r100); $displayb("r101 = ",r101); $displayb("r102 = ",r102); $displayb("r103 = ",r103); $displayb("r104 = ",r104); $displayb("r105 = ",r105); $displayb("r106 = ",r106); $displayb("r107 = ",r107); $displayb("r108 = ",r108); $displayb("r109 = ",r109); $displayb("r110 = ",r110); $displayb("r111 = ",r111); $displayb("r112 = ",r112); $displayb("r113 = ",r113); $displayb("r114 = ",r114); $displayb("r115 = ",r115); $displayb("r116 = ",r116); $displayb("r117 = ",r117); $displayb("r118 = ",r118); $displayb("r119 = ",r119); $displayb("r120 = ",r120); $displayb("r121 = ",r121); $displayb("r122 = ",r122); $displayb("r123 = ",r123); $displayb("r124 = ",r124); $displayb("r125 = ",r125); $displayb("r126 = ",r126); $displayb("r127 = ",r127); $displayb("r128 = ",r128); $displayb("r129 = ",r129); $displayb("r130 = ",r130); $displayb("r131 = ",r131); $displayb("r132 = ",r132); $displayb("r133 = ",r133); $displayb("r134 = ",r134); $displayb("r135 = ",r135); $displayb("r136 = ",r136); $displayb("r137 = ",r137); $displayb("r138 = ",r138); $displayb("r139 = ",r139); $displayb("r140 = ",r140); $displayb("r141 = ",r141); $displayb("r142 = ",r142); $displayb("r143 = ",r143); $displayb("r144 = ",r144); $displayb("r145 = ",r145); $displayb("r146 = ",r146); $displayb("r147 = ",r147); $displayb("r148 = ",r148); $displayb("r149 = ",r149); $displayb("r150 = ",r150); $displayb("r151 = ",r151); $displayb("r152 = ",r152); $displayb("r153 = ",r153); $displayb("r154 = ",r154); $displayb("r155 = ",r155); $displayb("r156 = ",r156); $displayb("r157 = ",r157); $displayb("r158 = ",r158); $displayb("r159 = ",r159); $displayb("r160 = ",r160); $displayb("r161 = ",r161); $displayb("r162 = ",r162); $displayb("r163 = ",r163); $displayb("r164 = ",r164); $displayb("r165 = ",r165); $displayb("r166 = ",r166); $displayb("r167 = ",r167); $displayb("r168 = ",r168); $displayb("r169 = ",r169); $displayb("r170 = ",r170); $displayb("r171 = ",r171); $displayb("r172 = ",r172); $displayb("r173 = ",r173); $displayb("r174 = ",r174); $displayb("r175 = ",r175); $displayb("r176 = ",r176); $displayb("r177 = ",r177); $displayb("r178 = ",r178); $displayb("r179 = ",r179); $displayb("r180 = ",r180); $displayb("r181 = ",r181); $displayb("r182 = ",r182); $displayb("r183 = ",r183); $displayb("r184 = ",r184); $displayb("r185 = ",r185); $displayb("r186 = ",r186); $displayb("r187 = ",r187); $displayb("r188 = ",r188); $displayb("r189 = ",r189); $displayb("r190 = ",r190); $displayb("r191 = ",r191); $displayb("r192 = ",r192); $displayb("r193 = ",r193); $displayb("r194 = ",r194); $displayb("r195 = ",r195); $displayb("r196 = ",r196); $displayb("r197 = ",r197); $displayb("r198 = ",r198); $displayb("r199 = ",r199); $displayb("r200 = ",r200); $displayb("r201 = ",r201); $displayb("r202 = ",r202); $displayb("r203 = ",r203); $displayb("r204 = ",r204); $displayb("r205 = ",r205); $displayb("r206 = ",r206); $displayb("r207 = ",r207); $displayb("r208 = ",r208); $displayb("r209 = ",r209); $displayb("r210 = ",r210); $displayb("r211 = ",r211); $displayb("r212 = ",r212); $displayb("r213 = ",r213); $displayb("r214 = ",r214); $displayb("r215 = ",r215); $displayb("r216 = ",r216); $displayb("r217 = ",r217); $displayb("r218 = ",r218); $displayb("r219 = ",r219); $displayb("r220 = ",r220); $displayb("r221 = ",r221); $displayb("r222 = ",r222); $displayb("r223 = ",r223); $displayb("r224 = ",r224); $displayb("r225 = ",r225); $displayb("r226 = ",r226); $displayb("r227 = ",r227); $displayb("r228 = ",r228); $displayb("r229 = ",r229); $displayb("r230 = ",r230); $displayb("r231 = ",r231); $displayb("r232 = ",r232); $displayb("r233 = ",r233); $displayb("r234 = ",r234); $displayb("r235 = ",r235); $displayb("r236 = ",r236); $displayb("r237 = ",r237); $displayb("r238 = ",r238); $displayb("r239 = ",r239); $displayb("r240 = ",r240); $displayb("r241 = ",r241); $displayb("r242 = ",r242); $displayb("r243 = ",r243); $displayb("r244 = ",r244); $displayb("r245 = ",r245); $displayb("r246 = ",r246); $displayb("r247 = ",r247); $displayb("r248 = ",r248); $displayb("r249 = ",r249); $displayb("r250 = ",r250); $displayb("r251 = ",r251); $displayb("r252 = ",r252); $displayb("r253 = ",r253); $displayb("r254 = ",r254); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/comp1001_fail3.v000066400000000000000000000021571435245347300212540ustar00rootroot00000000000000/* * This is a reduced example from comp1001 to demonstrate a problem * in the Icarus Verilog code generator. If the left && argument is * replaced with a single 1'b1 which should be logically equivalent * this will work correctly. It appears that the width of the * expression is being calculated incorrectly. */ module top; reg [119:110] r163; reg [192:162] r222; initial begin r163 = 10'h17d; r222 = (1'b1 + (22'h3a15 && ((^r163) < 4'h8))) != 1'bx; // ... the subexpression ^r163 is the 1-bit value 1'b1 // = (1'b1 + (22'h3a15 && ((1'b1) < 4'h8))) != 1'bx // ... the operands of && are self determined, but the widths of the // operands of < must match // = (1'b1 + (22'h3a15 && (4'h1 < 4'h8))) != 1'bx // ... The && is a 1'bit result. // = (1'b1 + 1'b1) != 1'bx // ... Operands of != are sized to max of i and j, namely 1 in this case. // = 1'b0 != 1'bx // = 1'bx // ... but the result is 31 bits, so the result is... // = 31'b0x if (r222 !== 31'b0x) $display("FAILED -- r222=%b", r222); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/comp1001_fail4.v000066400000000000000000000012011435245347300212420ustar00rootroot00000000000000/* * This is a reduced example from comp1001 to demonstrate a problem * in the Icarus Verilog code generator. If one addition argument is * replaced with a 1-bit register (instead of the constant 1'b1), * evaluation is postponed to vvp, which works correctly. It appears * that the width of the adder is calculated incorrectly when part * of a comparison, but only in constant-propagation mode. */ module top; reg [30:0] r2; reg r1=1; initial begin r2 = (1'b1+1'b1) != 1'bx; // r2 = (1'b1+r1) != 1'bx; $displayb("r2 = ",r2); if (r2 !== 31'b0x) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/comp1001_fail5.v000066400000000000000000000007571435245347300212620ustar00rootroot00000000000000module top; reg passed; reg [7:0] res; reg zero; reg one; initial begin passed = 1'b1; zero = 1'b0; one = 1'b1; // res = 1'b1 ? !1'b0/1'b0 : 1'b0; res = !1'b0/1'b0; if (res !== 8'bx) begin $display("FAILED: compiler."); passed = 1'b0; end // res = one ? !1'b0/zero : zero; res = !1'b0/zero; if (res !== 8'bx) begin $display("FAILED: run-time."); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/compare_bool_reg.v000066400000000000000000000002401435245347300222230ustar00rootroot00000000000000module main; reg bool [31:0] idx; initial begin idx = 0; if (idx < 17) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/complex_lidx.v000066400000000000000000000010011435245347300214100ustar00rootroot00000000000000module main; parameter MAP = 16'h0123; parameter VAL = 32'h44_33_22_11; wire [31:0] value; generate genvar m, n; for (m = 0 ; m < 4 ; m = m+1) begin : drv for (n = 0 ; n < 8 ; n = n+1) begin : drv_n assign value[8*MAP[4*m +: 4] + n] = VAL[8*m+n +: 1]; end end endgenerate initial begin #1 $display("value = %h", value); if (value !== 32'h11_22_33_44) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/con_tri.v000066400000000000000000000041171435245347300203710ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the ability to resolve resolve tri-state drivers onto a single * signal. Use multiple continuous assignments to a wire to create * multiple drivers, and use the ?: operator to tri-state the driven * value based on the sel value. */ module main; wire [1:0] out; reg [1:0] sel = 2'bzz; reg [1:0] v0 = 0; reg [1:0] v1 = 1; reg [1:0] v2 = 2; reg [1:0] v3 = 3; assign out = (sel == 2'b00)? v0 : 2'bz; assign out = (sel == 2'b01)? v1 : 2'bz; assign out = (sel == 2'b10)? v2 : 2'bz; assign out = (sel == 2'b11)? v3 : 2'bz; initial begin #1 if (out !== 2'bxx) begin $display("FAILED -- sel==%b, out==%b", sel, out); $finish; end sel = 0; #1 if (out !== 2'b00) begin $display("FAILED -- sel==%b, out==%b, v0==%b", sel, out, v0); $finish; end sel = 1; #1 if (out !== 2'b01) begin $display("FAILED -- sel==%b, out==%b", sel, out); $finish; end sel = 2; #1 if (out !== 2'b10) begin $display("FAILED -- sel==%b, out==%b", sel, out); $finish; end sel = 3; #1 if (out !== 2'b11) begin $display("FAILED -- sel==%b, out==%b", sel, out); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/concat1.v000066400000000000000000000025461435245347300202700ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test that the repeat expression of a concatenation can have * a parameter expression in it. */ module test; parameter addrbits=10; parameter HiAdrsBitVal = { 1'b1, { (addrbits-1) { 1'b0 } } }; initial begin if ($sizeof(HiAdrsBitVal) != 10) begin $display("FAILED -- $sizeof(HiAdrsBitVal) is %d", $sizeof(HiAdrsBitVal)); $finish; end $display("HiAdrsBitVal=%b, size=%d", HiAdrsBitVal, $sizeof(HiAdrsBitVal)); $display("PASSED"); end // initial begin endmodule // test iverilog-12_0/ivtest/ivltests/concat2.v000066400000000000000000000027651435245347300202740ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This tests that parameters can be used in concatenations if * the expression it represents has definite width. This test * is based on PR#282. */ module t; parameter SET = 1'b1, CLR = 1'b0, S1 = 2'd1, HINC = 3'd4; //bit signif 12:11, 10 , 9 , 8 , 7, 6 , 5 , 4 , 3 ,2:0 parameter x = {S1,CLR,CLR,CLR,CLR,SET,SET,CLR,CLR,HINC }; initial begin $display("x=%b, $sizeof(x)=%d", x, $sizeof(x)); if (x !== 13'b0100001100100) begin $display("FAILED -- x is %b", x); $finish; end if ($sizeof(x) != 13) begin $display("FAILED -- x is %d'b%b", $sizeof(x), x); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/concat3.v000066400000000000000000000214701435245347300202670ustar00rootroot00000000000000// Explore how procedural concatenations work in various contexts. // Some of the checks are specific to the 1364-2005 standard. // // Cary R. cygcary@yahoo.com module main; reg pass; reg [31:0] a_c, b_c, c_c, d_c, a_r, b_r, c_r, d_r; reg [127:0] y_c; integer seed, fres; // These will have the following value depending on the order. // 1 = LSB->MSB, 2 = MSB->LSB, 3 = indeterminate. integer sorder, uorder; initial begin pass = 1'b1; /********** * Try to find the order using $random. **********/ // Start from a known place. seed = 0; y_c = {$random(seed), $random(seed), $random(seed), $random(seed)}; a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Make the reference values in a known order. seed = 0; a_r = $random(seed); b_r = $random(seed); c_r = $random(seed); d_r = $random(seed); if (a_c === a_r && b_c === b_r && c_c === c_r && d_c == d_r) begin $display("Concatenation of system functions is LSB -> MSB."); sorder = 1; end else if (a_c === d_r && b_c === c_r && c_c === b_r && d_c == a_r) begin $display("Concatenation of system functions is MSB -> LSB."); sorder = 2; end else if ((a_c === a_r || a_c === b_r || a_c === c_r || a_c == d_r) && (b_c === a_r || b_c === b_r || b_c === c_r || b_c == d_r) && (c_c === a_r || c_c === b_r || c_c === c_r || c_c == d_r) && (d_c === a_r || d_c === b_r || d_c === c_r || d_c == d_r)) begin $display("Concatenation of system functions is indeterminate."); $display(" check:",, d_c,, c_c,, b_c,, a_c); $display(" ref.:",, d_r,, c_r,, b_r,, a_r); sorder = 3; end else begin $display("FAILED: system function concatenation order."); $display(" check:",, d_c,, c_c,, b_c,, a_c); $display(" ref.:",, d_r,, c_r,, b_r,, a_r); pass = 1'b0; end /********** * Try to find the order using ufunc(). **********/ // Start from a known place. fres = 0; y_c = {ufunc(0), ufunc(0), ufunc(0), ufunc(0)}; a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Make the reference values in a known order. fres = 0; a_r = ufunc(0); b_r = ufunc(0); c_r = ufunc(0); d_r = ufunc(0); if (a_c === a_r && b_c === b_r && c_c === c_r && d_c == d_r) begin $display("Concatenation of user functions is LSB -> MSB."); uorder = 1; end else if (a_c === d_r && b_c === c_r && c_c === b_r && d_c == a_r) begin $display("Concatenation of user functions is MSB -> LSB."); uorder = 2; end else if ((a_c === a_r || a_c === b_r || a_c === c_r || a_c == d_r) && (b_c === a_r || b_c === b_r || b_c === c_r || b_c == d_r) && (c_c === a_r || c_c === b_r || c_c === c_r || c_c == d_r) && (d_c === a_r || d_c === b_r || d_c === c_r || d_c == d_r)) begin $display("Concatenation of user functions is indeterminate."); $display(" check:",, d_c,, c_c,, b_c,, a_c); $display(" ref.:",, d_r,, c_r,, b_r,, a_r); uorder = 3; end else begin $display("FAILED: user function concatenation order."); $display(" check:",, d_c,, c_c,, b_c,, a_c); $display(" ref.:",, d_r,, c_r,, b_r,, a_r); pass = 1'b0; end if (sorder != uorder) begin $display("WARNING: system functions and user functions have a ", "different order."); end /********** * Check to see if extra system functions are called and ignored. * We do not care about the order for this test. **********/ // Start from a known place. seed = 0; // You must run the extra $random(), but drop the result. c_c = {$random(seed), $random(seed), $random(seed), $random(seed), $random(seed), $random(seed)}; a_c = $random(seed); // Make the reference values in a known order. seed = 0; a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); if (a_c !== a_r) begin $display("FAILED: extra system functions in a concat. are not run."); pass = 1'b0; end /********** * Check to see if extra user functions are called and ignored. * We do not care about the order for this test. **********/ // Start from a known place. fres = 0; y_c = {ufunc(0), ufunc(0), ufunc(0), ufunc(0), ufunc(0), ufunc(0)}; if (fres != 6) begin $display("FAILED: extra user functions in a concat. are not run."); pass = 1'b0; end // Icarus handles this in a different way so check it as well. // Start from a known place. fres = 0; y_c = check_64({ufunc(0), ufunc(0), ufunc(0)}); if (fres != 3) begin $display("FAILED: extra ufunc in a concat. as an argument are not run."); pass = 1'b0; end /********** * Check to see if a system function replicated 0 times is done correctly. **********/ // Start from a known place. seed = 0; // You must run the zero replication system call and then ignore it. a_c = {{0{$random(seed)}}, $random(seed)}; a_c = $random(seed); // Make a reference value. seed = 0; a_r = $random(seed); a_r = $random(seed); a_r = $random(seed); if (a_c !== a_r) begin $display("FAILED: zero repl. system functions in a concat. are not run."); pass = 1'b0; end /********** * Check to see if a user function replicated 0 times is done correctly. **********/ // Start from a known place. fres = 0; // You must run the zero replication user call and then ignore it. a_c = {{0{ufunc(0)}}, ufunc(0)}; if (fres != 2) begin $display("FAILED: zero repl. user functions in a concat. are not run."); pass = 1'b0; end /********** * Check a simple replication of $random(). **********/ // Start from a known place. seed = 0; // This must run $random() only once. y_c = {4{$random(seed)}}; a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Start from a known place. seed = 0; a_r = $random(seed); b_r = a_r; c_r = a_r; d_r = a_r; if (a_c !== a_r || b_c !== b_r || c_c !== c_r || d_c !== d_r) begin $display("FAILED $random() replication, each replication is different."); pass = 1'b0; end /********** * Check a replication of ufunc(). **********/ // Start from a known place. fres = 0; // This must run ufunc() only once. y_c = {4{ufunc(0)}}; a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Start from a known place. fres = 0; a_r = ufunc(0); b_r = a_r; c_r = a_r; d_r = a_r; if (a_c !== a_r || b_c !== b_r || c_c !== c_r || d_c !== d_r) begin $display("FAILED ufunc() replication, each replication is different."); pass = 1'b0; end /* * A concatenation as an argument needs to pad or select as needed. * We only check ufunc since it should be the same as $random and * it has been tested above. */ /********** * Check that a concat is zero extended. **********/ // Start from a known place. fres = 0; y_c = check_64({ufunc(1)}); a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Start from a known place. fres = 0; a_r = ufunc(1); b_r = 32'h0; c_r = 32'h0; d_r = 32'h0; if (a_c !== a_r || b_c !== b_r || c_c !== c_r || d_c !== d_r) begin $display("FAILED padded user function concatenation."); $displayh(" check:",, d_c,, c_c,, b_c,, a_c); $displayh(" ref.:",, d_r,, c_r,, b_r,, a_r); pass = 1'b0; end /********** * Check that a $signed concat is sign extended. **********/ // Start from a known place. fres = 0; y_c = check_64($signed({ufunc(1)})); a_c = y_c[31:0]; b_c = y_c[63:32]; c_c = y_c[95:64]; d_c = y_c[127:96]; // Start from a known place. fres = 0; a_r = ufunc(1); b_r = 32'hffffffff; c_r = 32'h0; d_r = 32'h0; if (a_c !== a_r || b_c !== b_r || c_c !== c_r || d_c !== d_r) begin $display("FAILED sign padded user function concatenation."); $displayh(" check:",, d_c,, c_c,, b_c,, a_c); $displayh(" ref.:",, d_r,, c_r,, b_r,, a_r); pass = 1'b0; end if (pass) $display("PASSED"); end function [63:0] check_64; input [63:0] in; check_64 = in; endfunction // This user function has a side effect (fres) so the result is call // order dependent. function integer ufunc; input in; begin if (in) fres = fres - 1; else fres = fres + 1; ufunc = fres; end endfunction endmodule iverilog-12_0/ivtest/ivltests/concat4.v000066400000000000000000000010721435245347300202640ustar00rootroot00000000000000module top; // These should create two ufunc calls each and the zero replication one // will not be connected to anything. wire [31:0] var1 = {{0{ufunc(0)}}, ufunc(0)}; wire [31:0] var2 = {ufunc(0), {0{ufunc(0)}}}; integer fres; initial begin #1; if (fres != 4) $display("FAILED, expected fres = 4, got %0d", fres); else $display("PASSED"); end function integer ufunc; input in; begin if (fres === 32'bx) fres = 0; if (in) fres = fres - 1; else fres = fres + 1; ufunc = fres; end endfunction endmodule iverilog-12_0/ivtest/ivltests/concat_zero_wid_fail.v000066400000000000000000000002071435245347300230740ustar00rootroot00000000000000module top; reg [7:0] result; initial begin result = {{0{1'b1}}}; // This fails concatination has zero width. end endmodule iverilog-12_0/ivtest/ivltests/concat_zero_wid_fail2.v000066400000000000000000000004161435245347300231600ustar00rootroot00000000000000module top; reg [2:0] bar = 1; wire [3:0] foo; assign foo = { 1'b1, 0 ? 3'd0 : bar[2:0] }; initial begin #1 if (foo !== 4'b1001) begin $display("FAILED bar=%b, foo=%b", bar, foo); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cond_band.v000066400000000000000000000021101435245347300206320ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test some subtleties of bitwise and and if condition expressions. */ module test; reg [31:0] c; initial begin c = 13; if (c & 4) begin $display("PASSED"); $finish; end $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/cond_wide.v000066400000000000000000000022441435245347300206660ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This progam catches the case where the truth value is really the * reduction-OR of the condition expression, and not just the low bit. */ module test; reg [1:0] foo = 2'b10; initial #1 begin while (foo) begin $display("PASSED"); $finish; end $display("FAILED -- foo = %b", foo); end endmodule // test iverilog-12_0/ivtest/ivltests/cond_wide2.v000066400000000000000000000026371435245347300207560ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module foo; reg [2:0] cond; reg test; initial begin cond = 0; test = cond ? 1'b1 : 1'b0; if (test !== 1'b0) begin $display("FAILED -- cond=%b, test=%b", cond, test); $finish; end cond = 1; test = cond ? 1'b1 : 1'b0; if (test !== 1) begin $display("FAILED -- cond=%b, test=%b", cond, test); $finish; end cond = 2; test = cond ? 1'b1 : 1'b0; if (test !== 1) begin $display("FAILED -- cond=%b, test=%b", cond, test); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/condit1.v000066400000000000000000000017331435245347300202760ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This tests the synthesis of a case statement that has an empty case. */ module main; reg bit, foo, bar; // Combinational device that sends 1 or 0 to foo, to follow bit. // This tests the special situation that the if condition only sets // some of the bits that the process as a whole sets. This is OK if // the bits that are sometimes not set are covered elsewhere. always @* begin foo = 0; bar = 0; if (bit) foo = 1; else bar = 1; end (* ivl_synthesis_off *) initial begin bit = 0; # 6 $display("bit=%b, foo=%b, bar=%b", bit, foo, bar); if (bit !== 0 || foo !== 0 || bar !== 1) begin $display("FAILED"); $finish; end bit <= 1; #10 $display("bit=%b, foo=%b, bar=%b", bit, foo, bar); if (bit !== 1 || foo !== 1 || bar !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/conditsynth1.v000066400000000000000000000022711435245347300213620ustar00rootroot00000000000000module main; reg [2:0] Q; reg clk, clr, up, down; (*ivl_synthesis_off *) initial begin clk = 0; up = 0; down = 0; clr = 1; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED"); $finish; end up = 1; clr = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b010) begin $display("FAILED"); $finish; end up = 0; down = 1; #1 clk = 1; #1 clk = 0; if (Q !== 3'b001) begin $display("FAILED"); $finish; end down = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b001) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end /* * This statement models a snythesizable UP/DOWN counter. The up * and down cases are enabled by up and down signals. If both * signals are absent, the synthesizer should take the implicit * case that Q <= Q; */ (* ivl_synthesis_on *) always @(posedge clk, posedge clr) if (clr) begin Q <= 0; end else begin if (up) Q <= Q + 1; else if (down) Q <= Q - 1; end endmodule // main iverilog-12_0/ivtest/ivltests/conditsynth2.v000066400000000000000000000030021435245347300213540ustar00rootroot00000000000000module main; reg [2:0] Q; reg clk, clr, up, down; reg flag; (*ivl_synthesis_off *) initial begin clk = 0; up = 0; down = 0; clr = 1; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED"); $finish; end if (flag !== 0) begin $display("FAILED"); $finish; end up = 1; clr = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b010) begin $display("FAILED"); $finish; end if (flag !== 0) begin $display("FAILED"); $finish; end up = 0; down = 1; #1 clk = 1; #1 clk = 0; if (Q !== 3'b001) begin $display("FAILED"); $finish; end if (flag !== 0) begin $display("FAILED"); $finish; end down = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b001) begin $display("FAILED"); $finish; end if (flag !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end /* * This statement models a snythesizable UP/DOWN counter. The up * and down cases are enabled by up and down signals. If both * signals are absent, the synthesizer should take the implicit * case that Q <= Q; */ (* ivl_synthesis_on *) always @(posedge clk, posedge clr) if (clr) begin Q <= 0; flag <= 0; end else begin if (up) Q <= Q + 1; else if (down) Q <= Q - 1; else flag <= 1; end endmodule // main iverilog-12_0/ivtest/ivltests/conditsynth3.v000066400000000000000000000024001435245347300213560ustar00rootroot00000000000000module main; reg [2:0] Q; reg clk, clr, up; (*ivl_synthesis_off *) initial begin clk = 0; up = 0; clr = 1; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED"); $finish; end up = 1; clr = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b010) begin $display("FAILED"); $finish; end up = 0; #1 clk = 1; #1 clk = 0; if (Q !== 3'b010) begin $display("FAILED"); $finish; end clr = 1; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end /* * This statement models a snythesizable UP counter. The up * count is enabled by the up signal. The clr is an asynchronous * clear input. * * NOTE: This is bad style. Bad, bad style. It comes from a * customer's customer, so I try to support it, but I'll moan * about it. Much better (and clearer) is: * * if (clr) * Q <= 0; * else * Q <= Q+1; */ (* ivl_synthesis_on *) always @(posedge clk, posedge clr) begin if (up) Q = Q + 1; if (clr) Q = 0; end endmodule // main iverilog-12_0/ivtest/ivltests/const.v000066400000000000000000000031531435245347300200610ustar00rootroot00000000000000// // Copyright (c) 1999 Paul Bain (pdbain@adm.org) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - PR122 - Const define without length specification causes error. `timescale 1ns/1ns module main( clk, dat ); parameter dat_width =32; input clk; output [dat_width-1:0] dat; reg [dat_width-1:0] dat; reg [32-1:0] exp_dat; reg error; initial begin exp_dat = 0; dat = 0; end initial begin dat = #1 'h00010203; exp_dat = #1 'h0010203; error = 0; #10; for (exp_dat = 0; exp_dat != 4'hf; exp_dat = exp_dat + 1) begin dat = exp_dat; #1 if(dat !== exp_dat) begin $display("ERROR: dat = %h, exp_dat = %h",dat,exp_dat); error = 1; end else $display("Okay: dat = %h, exp_dat = %h",dat,exp_dat); end if(error === 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/const2.v000066400000000000000000000025431435245347300201450ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test checks that signed comparisons of constants work * properly in conditional expressions. These cases are of * interest because they are evaluated at compile time, so * that dead code can be skipped. */ module main; initial begin if ((0 < -255) || (0 > 255)) begin $display("FAILED -- expression evaluated true"); $finish; end if ((0 <= -255) || (0 >= 255)) begin $display("FAILED -- expression evaluated true"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/const3.v000066400000000000000000000024431435245347300201450ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [7:0] testr; wire [7:0] testw = {-5'd1, -3'sd1}; initial begin #1 testr = {-5'd1, -3'sd1}; if (testr !== 8'b11111_111) begin $display("FAILED -- testr=%b", testr); $finish; end if (testw !== 8'b11111_111) begin $display("FAILED -- testw=%b", testw); $finish; end $display("testr=%b", testr); $display("testw=%b", testw); $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/const4.v000066400000000000000000000025541435245347300201510ustar00rootroot00000000000000// // Test the number format insanity // module test; integer err; reg [31:0] i; // Ugly specification initial begin i = 659; i = 'h 837FF; i = 'o7460; i = 4'b1001; i = 5 'D 3; i = 3'b01x; i = 12'hx; i = 16'hz; i = -8 'd 6; i = 4 'shf; i = -4 'sd15; end //always @(i) $display("%0t:\ti = %d", $time, i); // Potential ambiguities initial begin err = 0; i = # 9 1'd0; i = # 9_7 'D 3; #100; if (i != 'd3) begin $display("'d3 != %0d", i); err = 1; end i = # 1 'h 123; #100; if (i != 'h123) begin $display("'h123 != %0h", i); err = 1; end i = #(5 'D 3) 'D 3; #100; if (i != 'd3) begin $display("'d3 != %0d", i); err = 1; end i = # 93 'h 837FF; #100; if (i != 'h837ff) begin $display("'h837ff != %0h", i); err = 1; end i = # 33 20 'h 837ff - 1; #100; if (i != 'h837fe) begin $display("'h837fe != %0h", i); err = 1; end i = # 69 - 20 'd 255 + 20'd1; #100; if (i[19:0] != 20'hf_ff_02) begin $display("- 'd254 != %0d (%h)", i, i); err = 1; end i = #(27 - 20)'d 254 + 1; #100; if (i != 10'd255) begin $display("'d255 != %0d", i); err = 1; end i = # 97.4 'h abcd; #100; if (i != 'habcd) begin $display("'abcd != %0h", i); err = 1; end if (err) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constadd.v000066400000000000000000000022311435245347300205260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate constant addition in vector range, and rhs. // // module main (); reg ['d4 + 'b110 : 0] val1; reg [10'h1+ 'd9 : 0 ] val2 ; initial begin val1 = 11'h1 + 'd4; val2 = 11'h2 + 6; if((val1 === 11'h5) && (val2 === 11'h8)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/constadd2.v000066400000000000000000000021321435245347300206100ustar00rootroot00000000000000// // Copyright (c) 2001 Stephan Gehring // // (Modified by Stephan Williams to include PASS/FAIL messages.) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg [7:0] x; initial begin x = 'h4000 + 'hzz; // iverilog doesn't like 'hzz if (x !== 8'hxx) begin $display("FAILED -- x = %b", x); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constadd3.v000066400000000000000000000003071435245347300206130ustar00rootroot00000000000000module test; integer i; initial begin i = 7+1; if (i != 8) $display ("FAILED -- i = %0d != 8", i); else $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constconcat1.v000066400000000000000000000037251435245347300213370ustar00rootroot00000000000000module test(); wire a; tri0 b; tri1 c; tri1 d; tri0 e; wire f; wire g; wire h; wire i; tri1 j; tri0 k; wire l; tri0 m; tri1 n; assign d = 1'b0; assign e = 1'b1; assign f = 1'b0; assign f = 1'b1; assign g = 1'b1; assign g = 1'b0; assign (strong1,strong0) h = 1'b0; assign ( weak1, weak0) h = 1'b1; assign ( weak1, weak0) i = 1'b0; assign (strong1,strong0) i = 1'b1; assign (pull1,pull0) j = 1'b0; assign (pull1,pull0) k = 1'b1; wire [1:0] A = {1'b1, a}; wire [1:0] B = {1'b1, b}; wire [1:0] C = {1'b1, c}; wire [1:0] D = {1'b1, d}; wire [1:0] E = {1'b1, e}; wire [1:0] F = {1'b1, f}; wire [1:0] G = {1'b1, g}; wire [1:0] H = {1'b1, h}; wire [1:0] I = {1'b1, i}; wire [1:0] J = {1'b1, j}; wire [1:0] K = {1'b1, k}; wire [1:0] L = {1'b1, l}; wire [1:0] M = {1'b1, m}; wire [1:0] N = {1'b1, n}; reg failed; initial begin failed = 0; #1; $display("A = %b, expect 1z", A); if (A !== 2'b1z) failed = 1; $display("B = %b, expect 10", B); if (B !== 2'b10) failed = 1; $display("C = %b, expect 11", C); if (C !== 2'b11) failed = 1; $display("D = %b, expect 10", D); if (D !== 2'b10) failed = 1; $display("E = %b, expect 11", E); if (E !== 2'b11) failed = 1; $display("F = %b, expect 1x", F); if (F !== 2'b1x) failed = 1; $display("G = %b, expect 1x", G); if (G !== 2'b1x) failed = 1; $display("H = %b, expect 10", H); if (H !== 2'b10) failed = 1; $display("I = %b, expect 11", I); if (I !== 2'b11) failed = 1; $display("J = %b, expect 1x", J); if (J !== 2'b1x) failed = 1; $display("K = %b, expect 1x", K); if (K !== 2'b1x) failed = 1; force l = 1'b0; #1; $display("L = %b, expect 10", L); if (L !== 2'b10) failed = 1; force l = 1'b1; #1; $display("L = %b, expect 11", L); if (L !== 2'b11) failed = 1; force m = 1'b1; #1; $display("M = %b, expect 11", M); if (M !== 2'b11) failed = 1; force n = 1'b0; #1; $display("N = %b, expect 10", N); if (N !== 2'b10) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constconcat2.v000066400000000000000000000040071435245347300213320ustar00rootroot00000000000000module test(); wire a; supply0 b; supply1 c; supply1 d; supply0 e; wire f; wire g; wire h; wire i; supply1 j; supply0 k; wire l; supply0 m; supply1 n; assign d = 1'b0; assign e = 1'b1; assign f = 1'b0; assign f = 1'b1; assign g = 1'b1; assign g = 1'b0; assign (strong1,strong0) h = 1'b0; assign ( weak1, weak0) h = 1'b1; assign ( weak1, weak0) i = 1'b0; assign (strong1,strong0) i = 1'b1; assign (supply1,supply0) j = 1'b0; assign (supply1,supply0) k = 1'b1; wire [1:0] A = {1'b1, a}; wire [1:0] B = {1'b1, b}; wire [1:0] C = {1'b1, c}; wire [1:0] D = {1'b1, d}; wire [1:0] E = {1'b1, e}; wire [1:0] F = {1'b1, f}; wire [1:0] G = {1'b1, g}; wire [1:0] H = {1'b1, h}; wire [1:0] I = {1'b1, i}; wire [1:0] J = {1'b1, j}; wire [1:0] K = {1'b1, k}; wire [1:0] L = {1'b1, l}; wire [1:0] M = {1'b1, m}; wire [1:0] N = {1'b1, n}; reg failed; initial begin failed = 0; #1; $display("A = %b, expect 1z", A); if (A !== 2'b1z) failed = 1; $display("B = %b, expect 10", B); if (B !== 2'b10) failed = 1; $display("C = %b, expect 11", C); if (C !== 2'b11) failed = 1; $display("D = %b, expect 11", D); if (D !== 2'b11) failed = 1; $display("E = %b, expect 10", E); if (E !== 2'b10) failed = 1; $display("F = %b, expect 1x", F); if (F !== 2'b1x) failed = 1; $display("G = %b, expect 1x", G); if (G !== 2'b1x) failed = 1; $display("H = %b, expect 10", H); if (H !== 2'b10) failed = 1; $display("I = %b, expect 11", I); if (I !== 2'b11) failed = 1; $display("J = %b, expect 1x", J); if (J !== 2'b1x) failed = 1; $display("K = %b, expect 1x", K); if (K !== 2'b1x) failed = 1; force l = 1'b0; #1; $display("L = %b, expect 10", L); if (L !== 2'b10) failed = 1; force l = 1'b1; #1; $display("L = %b, expect 11", L); if (L !== 2'b11) failed = 1; force m = 1'b1; #1; $display("M = %b, expect 11", M); if (M !== 2'b11) failed = 1; force n = 1'b0; #1; $display("N = %b, expect 10", N); if (N !== 2'b10) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc1.v000066400000000000000000000017501435245347300210170ustar00rootroot00000000000000module constfunc1(); function integer median; input integer a; input integer b; input integer c; begin if (a < b) begin if (a < c) median = (b < c) ? b : c; else median = a; end else begin if (a < c) median = a; else median = (b < c) ? c : b; end end endfunction localparam value1 = median(1, 2, 3); localparam value2 = median(1, 3, 2); localparam value3 = median(2, 1, 3); localparam value4 = median(2, 3, 1); localparam value5 = median(3, 1, 2); localparam value6 = median(3, 2, 1); initial begin $display("value 1 = %0d", value1); $display("value 2 = %0d", value2); $display("value 3 = %0d", value3); $display("value 4 = %0d", value4); $display("value 5 = %0d", value5); $display("value 6 = %0d", value6); if ((value1 === 2) && (value2 === 2) && (value3 === 2) && (value4 === 2) && (value5 === 2) && (value6 === 2)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc10.v000066400000000000000000000006631435245347300211010ustar00rootroot00000000000000// Test forever statements inside a constant function module constfunc10(); function [31:0] pow2(input [5:0] x); begin:body pow2 = 1; forever begin:loop if (x == 0) disable body; pow2 = 2 * pow2; x = x - 1; disable loop; pow2 = 0; end end endfunction localparam val = pow2(8); initial begin $display("%0d", val); if (val === 256) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc11.v000066400000000000000000000012071435245347300210750ustar00rootroot00000000000000// Test repeat statements inside a constant function module constfunc11(); function [31:0] pow2(input [5:0] x); begin:body pow2 = 1; repeat (x) begin pow2 = 2 * pow2; end end endfunction localparam val0 = pow2(0); localparam val1 = pow2(1); localparam val2 = pow2(2); localparam val3 = pow2(3); reg failed; initial begin failed = 0; $display("%0d", val0); if (val0 !== 1) failed = 1; $display("%0d", val1); if (val1 !== 2) failed = 1; $display("%0d", val2); if (val2 !== 4) failed = 1; $display("%0d", val3); if (val3 !== 8) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc12.v000066400000000000000000000074001435245347300210770ustar00rootroot00000000000000// Test case statements inside a constant function module constfunc12(); function [1:0] onehot_to_binary(input [3:1] x); case (x) default : onehot_to_binary = 0; 3'b001 : onehot_to_binary = 1; 3'b010 : onehot_to_binary = 2; 3'b100 : onehot_to_binary = 3; endcase endfunction function [1:0] find_first_one(input [3:1] x); casez (x) 3'b1?? : find_first_one = 3; 3'b01? : find_first_one = 2; 3'b001 : find_first_one = 1; default : find_first_one = 0; endcase endfunction function [1:0] find_first_zero(input [3:1] x); casex (x) 3'b0zz : find_first_zero = 3; 3'b10x : find_first_zero = 2; 3'b110 : find_first_zero = 1; default : find_first_zero = 0; endcase endfunction function [1:0] match_real_value(input real x); case (x) 1.0 : match_real_value = 1; 2.0 : match_real_value = 2; 3.0 : match_real_value = 3; default : match_real_value = 0; endcase endfunction localparam otb0 = onehot_to_binary(3'b000); localparam otb1 = onehot_to_binary(3'b001); localparam otb2 = onehot_to_binary(3'b010); localparam otb3 = onehot_to_binary(3'b100); localparam otb4 = onehot_to_binary(3'b101); localparam otb5 = onehot_to_binary(3'b10z); localparam otb6 = onehot_to_binary(3'bx01); localparam ffo0 = find_first_one(3'b000); localparam ffo1 = find_first_one(3'b001); localparam ffo2 = find_first_one(3'b01x); localparam ffo3 = find_first_one(3'b1xx); localparam ffo4 = find_first_one(3'bxx1); localparam ffo5 = find_first_one(3'b00z); localparam ffo6 = find_first_one(3'b0zz); localparam ffo7 = find_first_one(3'bzzz); localparam ffz0 = find_first_zero(3'b111); localparam ffz1 = find_first_zero(3'b110); localparam ffz2 = find_first_zero(3'b10x); localparam ffz3 = find_first_zero(3'b0xx); localparam ffz4 = find_first_zero(3'bzzz); localparam ffz5 = find_first_zero(3'b11x); localparam ffz6 = find_first_zero(3'b1xx); localparam ffz7 = find_first_zero(3'bxxx); localparam mrv0 = match_real_value(0.0); localparam mrv1 = match_real_value(1.0); localparam mrv2 = match_real_value(2.0); localparam mrv3 = match_real_value(3.0); localparam mrv4 = match_real_value(4.0); reg failed = 0; initial begin $display("%d", otb0); if (otb0 !== 2'd0) failed = 1; $display("%d", otb1); if (otb1 !== 2'd1) failed = 1; $display("%d", otb2); if (otb2 !== 2'd2) failed = 1; $display("%d", otb3); if (otb3 !== 2'd3) failed = 1; $display("%d", otb4); if (otb4 !== 2'd0) failed = 1; $display("%d", otb5); if (otb5 !== 2'd0) failed = 1; $display("%d", otb6); if (otb6 !== 2'd0) failed = 1; $display(""); $display("%d", ffo0); if (ffo0 !== 2'd0) failed = 1; $display("%d", ffo1); if (ffo1 !== 2'd1) failed = 1; $display("%d", ffo2); if (ffo2 !== 2'd2) failed = 1; $display("%d", ffo3); if (ffo3 !== 2'd3) failed = 1; $display("%d", ffo4); if (ffo4 !== 2'd0) failed = 1; $display("%d", ffo5); if (ffo5 !== 2'd1) failed = 1; $display("%d", ffo6); if (ffo6 !== 2'd2) failed = 1; $display("%d", ffo7); if (ffo7 !== 2'd3) failed = 1; $display(""); $display("%d", ffz0); if (ffz0 !== 2'd0) failed = 1; $display("%d", ffz1); if (ffz1 !== 2'd1) failed = 1; $display("%d", ffz2); if (ffz2 !== 2'd2) failed = 1; $display("%d", ffz3); if (ffz3 !== 2'd3) failed = 1; $display("%d", ffz4); if (ffz4 !== 2'd3) failed = 1; $display("%d", ffz5); if (ffz5 !== 2'd1) failed = 1; $display("%d", ffz6); if (ffz6 !== 2'd2) failed = 1; $display("%d", ffz7); if (ffz7 !== 2'd3) failed = 1; $display(""); $display("%d", mrv0); if (mrv0 !== 2'd0) failed = 1; $display("%d", mrv1); if (mrv1 !== 2'd1) failed = 1; $display("%d", mrv2); if (mrv2 !== 2'd2) failed = 1; $display("%d", mrv3); if (mrv3 !== 2'd3) failed = 1; $display("%d", mrv4); if (mrv4 !== 2'd0) failed = 1; $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc13.v000066400000000000000000000046701435245347300211060ustar00rootroot00000000000000// Test mixed type/width case expressions inside a constant function module constfunc13(); function [2:0] lookup1(input signed [2:0] value); begin case (value) 4'sb0100 : lookup1 = 1; 3'sb100 : lookup1 = 2; 2'sb10 : lookup1 = 3; default : lookup1 = 4; endcase $display("case = %d", lookup1); end endfunction function [2:0] lookup2(input signed [2:0] value); begin case (value) 4'b1100 : lookup2 = 1; 3'sb100 : lookup2 = 2; 2'sb10 : lookup2 = 3; default : lookup2 = 4; endcase $display("case = %d", lookup2); end endfunction function [2:0] lookup3(input real value); begin case (value) 4'b0001 : lookup3 = 1; 3'sb010 : lookup3 = 2; 2'sb11 : lookup3 = 3; default : lookup3 = 4; endcase $display("case = %d", lookup3); end endfunction function [2:0] lookup4(input signed [2:0] value); begin case (value) 4'b0110 : lookup4 = 1; 3'sb110 : lookup4 = 2; -1.0 : lookup4 = 3; default : lookup4 = 4; endcase $display("case = %d", lookup4); end endfunction localparam res11 = lookup1(3'sb100); localparam res12 = lookup1(3'sb110); localparam res13 = lookup1(3'sb010); localparam res21 = lookup2(3'sb100); localparam res22 = lookup2(3'sb010); localparam res23 = lookup2(3'sb110); localparam res31 = lookup3( 1.0); localparam res32 = lookup3( 2.0); localparam res33 = lookup3(-1.0); localparam res34 = lookup3( 1.5); localparam res41 = lookup4(3'sb110); localparam res42 = lookup4(3'sb111); localparam res43 = lookup4(3'sb011); reg failed = 0; initial begin $display("case = %d", res11); if (res11 != 2) failed = 1; $display("case = %d", res12); if (res12 != 3) failed = 1; $display("case = %d", res13); if (res13 != 4) failed = 1; $display(""); $display("case = %d", res21); if (res21 != 2) failed = 1; $display("case = %d", res22); if (res22 != 3) failed = 1; $display("case = %d", res23); if (res23 != 4) failed = 1; $display(""); $display("case = %d", res31); if (res31 != 1) failed = 1; $display("case = %d", res32); if (res32 != 2) failed = 1; $display("case = %d", res33); if (res33 != 3) failed = 1; $display("case = %d", res34); if (res34 != 4) failed = 1; $display(""); $display("case = %d", res41); if (res41 != 2) failed = 1; $display("case = %d", res42); if (res42 != 3) failed = 1; $display("case = %d", res43); if (res43 != 4) failed = 1; $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc14.v000066400000000000000000000020251435245347300210770ustar00rootroot00000000000000// Test concatenation inside a constant function module constfunc14(); function [7:0] concat1(input [7:0] value); reg [3:0] tmp1; reg [3:0] tmp2; begin {tmp1, tmp2} = {value[3:0], value[7:4]}; {concat1[3:0], concat1[7:4]} = {tmp2, tmp1}; end endfunction function [7:0] concat2(input [7:0] value); reg [2:0] tmp1; reg [3:0] tmp2; begin {tmp1, tmp2} = {value[3:0], value[7:4]}; {concat2[3:0], concat2[7:4]} = {tmp2, tmp1}; end endfunction function [7:0] concat3(input [7:0] value); reg signed [2:0] tmp1; reg signed [2:0] tmp2; begin {tmp1, tmp2} = {value[2:0], value[6:4]}; concat3[7:4] = tmp1; concat3[3:0] = tmp2; end endfunction localparam res1 = concat1(8'h5a); localparam res2 = concat2(8'h5a); localparam res3 = concat3(8'h5a); reg failed = 0; initial begin $display("%h", res1); if (res1 !== 8'ha5) failed = 1; $display("%h", res2); if (res2 !== 8'ha2) failed = 1; $display("%h", res3); if (res3 !== 8'h2d) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc15.v000066400000000000000000000025331435245347300211040ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif // Test array variables inside a constant function module constfunc14(); function [7:0] concat1(input [7:0] value); reg [3:0] tmp[1:2]; begin {tmp[1], tmp[2]} = {value[3:0], value[7:4]}; {concat1[3:0], concat1[7:4]} = {tmp[2], tmp[1]}; end endfunction function [7:0] concat2(input [7:0] value); reg [3:0] tmp[1:2]; begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST {tmp[1], tmp[3]} = {value[3:0], value[7:4]}; {concat2[3:0], concat2[7:4]} = {tmp[3], tmp[1]}; `else {tmp[1]} = {value[3:0]}; {concat2[3:0], concat2[7:4]} = {4'bxxxx, tmp[1]}; `endif end endfunction function [7:0] concat3(input [7:0] value); reg [3:0] tmp[1:2]; begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST {tmp['bx], tmp[1]} = {value[3:0], value[7:4]}; {concat3[3:0], concat3[7:4]} = {tmp['bx], tmp[1]}; `else {tmp[1]} = {value[7:4]}; {concat3[3:0], concat3[7:4]} = {4'bxxxx, tmp[1]}; `endif end endfunction localparam res1 = concat1(8'ha5); localparam res2 = concat2(8'ha5); localparam res3 = concat2(8'ha5); reg failed = 0; initial begin $display("%h", res1); if (res1 !== 8'h5a) failed = 1; $display("%h", res2); if (res2 !== 8'h5x) failed = 1; $display("%h", res3); if (res3 !== 8'h5x) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc2.v000066400000000000000000000014551435245347300210220ustar00rootroot00000000000000module constfunc2(); function integer factorial; input integer n; begin if (n > 1) factorial = n * factorial(n - 1); else factorial = n; end endfunction localparam value1 = factorial(1); localparam value2 = factorial(2); localparam value3 = factorial(3); localparam value4 = factorial(4); localparam value5 = factorial(5); localparam value6 = factorial(6); initial begin $display("value 1 = %0d", value1); $display("value 2 = %0d", value2); $display("value 3 = %0d", value3); $display("value 4 = %0d", value4); $display("value 5 = %0d", value5); $display("value 6 = %0d", value6); if ((value1 === 1) && (value2 === 2) && (value3 === 6) && (value4 === 24) && (value5 === 120) && (value6 === 720)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc3.v000066400000000000000000000034201435245347300210150ustar00rootroot00000000000000// Test binary operators in constant functions module constfunc3(); function [7:0] Add(input [7:0] l, input [7:0] r); Add = l + r; endfunction function [7:0] Mul(input [7:0] l, input [7:0] r); Mul = l * r; endfunction function [7:0] Div(input [7:0] l, input [7:0] r); Div = l / r; endfunction function [7:0] Pow(input [7:0] l, input [7:0] r); Pow = l ** r; endfunction function [7:0] And(input [7:0] l, input [7:0] r); And = l & r; endfunction function [7:0] Shift(input [7:0] l, input [7:0] r); Shift = l << r; endfunction function [7:0] Logic(input [7:0] l, input [7:0] r); begin Logic[0] = l[0] && r[0]; Logic[1] = l[1] && r[1]; Logic[2] = l[2] && r[2]; Logic[3] = l[3] && r[3]; Logic[4] = l[4] || r[4]; Logic[5] = l[5] || r[5]; Logic[6] = l[6] || r[6]; Logic[7] = l[7] || r[7]; end endfunction localparam [7:0] ResultAdd = Add(8'h0f, 8'h0f); localparam [7:0] ResultMul = Mul(8'h0f, 8'h0f); localparam [7:0] ResultDiv = Div(8'hf0, 8'h0f); localparam [7:0] ResultPow = Pow(8'h02, 8'h05); localparam [7:0] ResultAnd = And(8'h0f, 8'h55); localparam [7:0] ResultShift = Shift(8'h55, 8'h03); localparam [7:0] ResultLogic = Logic(8'h33, 8'h55); reg failed; initial begin failed = 0; $display("%h", ResultAdd); $display("%h", ResultMul); $display("%h", ResultDiv); $display("%h", ResultPow); $display("%h", ResultAnd); $display("%h", ResultShift); $display("%h", ResultLogic); if (ResultAdd !== 8'h1e) failed = 1; if (ResultMul !== 8'he1) failed = 1; if (ResultDiv !== 8'h10) failed = 1; if (ResultPow !== 8'h20) failed = 1; if (ResultAnd !== 8'h05) failed = 1; if (ResultShift !== 8'ha8) failed = 1; if (ResultLogic !== 8'h71) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc4.v000066400000000000000000000022341435245347300210200ustar00rootroot00000000000000// Test unary operators in constant functions module constfunc4(); function [7:0] LInv(input [7:0] x); LInv = ~x; endfunction function [7:0] LNeg(input [7:0] x); LNeg = -x; endfunction function real RNeg(input real x); RNeg = -x; endfunction function LAnd(input [7:0] x); LAnd = &x; endfunction function LNot(input [7:0] x); LNot = !x; endfunction function RNot(input real x); RNot = !x; endfunction localparam [7:0] ResultLInv = LInv(8'h0f); localparam [7:0] ResultLNeg = LNeg(8'h0f); localparam real ResultRNeg = RNeg(15.0); localparam ResultLAnd = LAnd(8'hff); localparam ResultLNot = LNot(8'h00); localparam ResultRNot = RNot(0.0); reg failed; initial begin failed = 0; $display("%h", ResultLInv); $display("%h", ResultLNeg); $display("%g", ResultRNeg); $display("%b", ResultLAnd); $display("%b", ResultLNot); $display("%b", ResultRNot); if (ResultLNeg !== 8'hf1) failed = 1; if (ResultRNeg != -15.0) failed = 1; if (ResultLAnd !== 1'b1) failed = 1; if (ResultLNot !== 1'b1) failed = 1; if (ResultRNot !== 1'b1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc4_ams.v000066400000000000000000000014171435245347300216620ustar00rootroot00000000000000// Test unary operators in constant functions module constfunc4(); function [7:0] LAbs(input signed [7:0] x); LAbs = abs(x); endfunction function real RAbs(input real x); RAbs = abs(x); endfunction localparam [7:0] ResultLAb1 = LAbs(8'sh01); localparam [7:0] ResultLAb2 = LAbs(8'shff); localparam real ResultRAb1 = RAbs( 2.0); localparam real ResultRAb2 = RAbs(-2.0); reg failed; initial begin failed = 0; $display("%h", ResultLAb1); $display("%h", ResultLAb2); $display("%g", ResultRAb1); $display("%g", ResultRAb2); if (ResultLAb1 !== 8'h01) failed = 1; if (ResultLAb2 !== 8'h01) failed = 1; if (ResultRAb1 != 2.0) failed = 1; if (ResultRAb2 != 2.0) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc5.v000066400000000000000000000010221435245347300210130ustar00rootroot00000000000000// Test concatenation operator in constant functions module constfunc5(); function [23:0] Concat(input [3:0] a, input [3:0] b); Concat = {2{a, 4'hf, b}}; endfunction localparam [23:0] Result1 = Concat(4'h5, 4'ha); localparam [23:0] Result2 = Concat(4'ha, 4'h5); reg failed; initial begin failed = 0; $display("%h", Result1); $display("%h", Result2); if (Result1 !== 24'h5fa5fa) failed = 1; if (Result2 !== 24'haf5af5) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc6.v000066400000000000000000000022171435245347300210230ustar00rootroot00000000000000// Test system function calls in constant functions module constfunc6(); function [7:0] clog2(input [7:0] a); clog2 = $clog2(a); endfunction function real log10(input [7:0] a); log10 = $log10(a); endfunction function real sqrt(input real a); sqrt = $sqrt(a); endfunction function real pow_i(input [7:0] a, input [7:0] b); pow_i = $pow(a, b); endfunction function real pow_r(input real a, input real b); pow_r = $pow(a, b); endfunction localparam [7:0] clog2Result = clog2(25); localparam real log10Result = log10(100); localparam real sqrtResult = sqrt(25.0); localparam [7:0] powIResult = pow_i(4, 3); localparam real powRResult = pow_r(4.0, 3.0); reg failed; initial begin failed = 0; $display("%0d", clog2Result); $display("%0g", log10Result); $display("%0g", sqrtResult); $display("%0d", powIResult); $display("%0g", powRResult); if (clog2Result !== 8'd5) failed = 1; if (log10Result != 2.0) failed = 1; if ( sqrtResult != 5.0) failed = 1; if ( powIResult !== 8'd64) failed = 1; if ( powRResult != 64.0) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc6_ams.v000066400000000000000000000026051435245347300216640ustar00rootroot00000000000000// Test system function calls in constant functions module constfunc6(); function signed [7:0] abs_i(input signed [7:0] a); abs_i = $abs(a); endfunction function real abs_r(input real a); abs_r = $abs(a); endfunction function [7:0] min_i(input [7:0] a, input [7:0] b); min_i = $min(a, b); endfunction function [7:0] max_i(input [7:0] a, input [7:0] b); max_i = $max(a, b); endfunction function real min_r(input real a, input real b); min_r = $min(a, b); endfunction function real max_r(input real a, input real b); max_r = $max(a, b); endfunction localparam [7:0] absIResult = abs_i(-25); localparam [7:0] minIResult = min_i(25, 30); localparam [7:0] maxIResult = max_i(25, 30); localparam real absRResult = abs_r(-25.0); localparam real minRResult = min_r(25.0, 30.0); localparam real maxRResult = max_r(25.0, 30.0); reg failed; initial begin failed = 0; $display("%0d", absIResult); $display("%0g", absRResult); $display("%0d", minIResult); $display("%0g", minRResult); $display("%0d", maxIResult); $display("%0g", maxRResult); if ( absIResult !== 8'd25) failed = 1; if ( absRResult != 25.0) failed = 1; if ( minIResult !== 8'd25) failed = 1; if ( minRResult != 25.0) failed = 1; if ( maxIResult !== 8'd30) failed = 1; if ( maxRResult != 30.0) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc7.v000066400000000000000000000126361435245347300210320ustar00rootroot00000000000000// Check assignment operations in constant functions. module constfunc7(); function real i_to_r(input signed [3:0] value); i_to_r = value + 0.5; endfunction function signed [3:0] r_to_i(input real value); r_to_i = value; endfunction function real u_to_r(input [3:0] value); u_to_r = value + 0.5; endfunction function [3:0] r_to_u(input real value); r_to_u = value; endfunction function [3:0] i_to_u(input signed [3:0] value); i_to_u = value; endfunction function signed [3:0] u_to_i(input [3:0] value); u_to_i = value; endfunction function [5:0] si_to_lu(input signed [3:0] value); si_to_lu = value; endfunction function signed [5:0] su_to_li(input [3:0] value); su_to_li = value; endfunction function [3:0] li_to_su(input signed [5:0] value); li_to_su = value; endfunction function signed [3:0] lu_to_si(input [5:0] value); lu_to_si = value; endfunction localparam i_to_r_res1 = i_to_r(-9); localparam i_to_r_res2 = i_to_r(-8); localparam i_to_r_res3 = i_to_r( 7); localparam i_to_r_res4 = i_to_r( 8); localparam r_to_i_res1 = r_to_i(-8.5); localparam r_to_i_res2 = r_to_i(-7.5); localparam r_to_i_res3 = r_to_i( 6.5); localparam r_to_i_res4 = r_to_i( 7.5); localparam u_to_r_res1 = u_to_r(-1); localparam u_to_r_res2 = u_to_r( 1); localparam u_to_r_res3 = u_to_r(15); localparam u_to_r_res4 = u_to_r(17); localparam r_to_u_res1 = r_to_u(-0.5); localparam r_to_u_res2 = r_to_u( 0.5); localparam r_to_u_res3 = r_to_u(14.5); localparam r_to_u_res4 = r_to_u(16.5); localparam i_to_u_res1 = i_to_u(-9); localparam i_to_u_res2 = i_to_u(-8); localparam i_to_u_res3 = i_to_u( 7); localparam i_to_u_res4 = i_to_u( 8); localparam u_to_i_res1 = u_to_i(-1); localparam u_to_i_res2 = u_to_i( 1); localparam u_to_i_res3 = u_to_i(15); localparam u_to_i_res4 = u_to_i(17); localparam si_to_lu_res1 = si_to_lu(-9); localparam si_to_lu_res2 = si_to_lu(-8); localparam si_to_lu_res3 = si_to_lu( 7); localparam si_to_lu_res4 = si_to_lu( 8); localparam su_to_li_res1 = su_to_li(-1); localparam su_to_li_res2 = su_to_li( 1); localparam su_to_li_res3 = su_to_li(15); localparam su_to_li_res4 = su_to_li(17); localparam li_to_su_res1 = li_to_su(-9); localparam li_to_su_res2 = li_to_su(-8); localparam li_to_su_res3 = li_to_su( 7); localparam li_to_su_res4 = li_to_su( 8); localparam lu_to_si_res1 = lu_to_si(-1); localparam lu_to_si_res2 = lu_to_si( 1); localparam lu_to_si_res3 = lu_to_si(15); localparam lu_to_si_res4 = lu_to_si(17); reg failed; initial begin failed = 0; $display("%0g", i_to_r_res1); if (i_to_r_res1 != 7.5) failed = 1; $display("%0g", i_to_r_res2); if (i_to_r_res2 != -7.5) failed = 1; $display("%0g", i_to_r_res3); if (i_to_r_res3 != 7.5) failed = 1; $display("%0g", i_to_r_res4); if (i_to_r_res4 != -7.5) failed = 1; $display(""); $display("%0d", r_to_i_res1); if (r_to_i_res1 !== 7) failed = 1; $display("%0d", r_to_i_res2); if (r_to_i_res2 !== -8) failed = 1; $display("%0d", r_to_i_res3); if (r_to_i_res3 !== 7) failed = 1; $display("%0d", r_to_i_res4); if (r_to_i_res4 !== -8) failed = 1; $display(""); $display("%0g", u_to_r_res1); if (u_to_r_res1 != 15.5) failed = 1; $display("%0g", u_to_r_res2); if (u_to_r_res2 != 1.5) failed = 1; $display("%0g", u_to_r_res3); if (u_to_r_res3 != 15.5) failed = 1; $display("%0g", u_to_r_res4); if (u_to_r_res4 != 1.5) failed = 1; $display(""); $display("%0d", r_to_u_res1); if (r_to_u_res1 !== 15) failed = 1; $display("%0d", r_to_u_res2); if (r_to_u_res2 !== 1) failed = 1; $display("%0d", r_to_u_res3); if (r_to_u_res3 !== 15) failed = 1; $display("%0d", r_to_u_res4); if (r_to_u_res4 !== 1) failed = 1; $display(""); $display("%0d", i_to_u_res1); if (i_to_u_res1 !== 7) failed = 1; $display("%0d", i_to_u_res2); if (i_to_u_res2 !== 8) failed = 1; $display("%0d", i_to_u_res3); if (i_to_u_res3 !== 7) failed = 1; $display("%0d", i_to_u_res4); if (i_to_u_res4 !== 8) failed = 1; $display(""); $display("%0d", u_to_i_res1); if (u_to_i_res1 !== -1) failed = 1; $display("%0d", u_to_i_res2); if (u_to_i_res2 !== 1) failed = 1; $display("%0d", u_to_i_res3); if (u_to_i_res3 !== -1) failed = 1; $display("%0d", u_to_i_res4); if (u_to_i_res4 !== 1) failed = 1; $display(""); $display("%0d", si_to_lu_res1); if (si_to_lu_res1 !== 7) failed = 1; $display("%0d", si_to_lu_res2); if (si_to_lu_res2 !== 56) failed = 1; $display("%0d", si_to_lu_res3); if (si_to_lu_res3 !== 7) failed = 1; $display("%0d", si_to_lu_res4); if (si_to_lu_res4 !== 56) failed = 1; $display(""); $display("%0d", su_to_li_res1); if (su_to_li_res1 !== 15) failed = 1; $display("%0d", su_to_li_res2); if (su_to_li_res2 !== 1) failed = 1; $display("%0d", su_to_li_res3); if (su_to_li_res3 !== 15) failed = 1; $display("%0d", su_to_li_res4); if (su_to_li_res4 !== 1) failed = 1; $display(""); $display("%0d", li_to_su_res1); if (li_to_su_res1 !== 7) failed = 1; $display("%0d", li_to_su_res2); if (li_to_su_res2 !== 8) failed = 1; $display("%0d", li_to_su_res3); if (li_to_su_res3 !== 7) failed = 1; $display("%0d", li_to_su_res4); if (li_to_su_res4 !== 8) failed = 1; $display(""); $display("%0d", lu_to_si_res1); if (lu_to_si_res1 !== -1) failed = 1; $display("%0d", lu_to_si_res2); if (lu_to_si_res2 !== 1) failed = 1; $display("%0d", lu_to_si_res3); if (lu_to_si_res3 !== -1) failed = 1; $display("%0d", lu_to_si_res4); if (lu_to_si_res4 !== 1) failed = 1; $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc8.v000066400000000000000000000015611435245347300210260ustar00rootroot00000000000000// Check variable initialisation in constant functions. module constfunc8(); function real uninitialised_r(input dummy); real value; uninitialised_r = value; endfunction function [7:0] uninitialised_2(input dummy); reg bool [5:0] value; uninitialised_2 = {1'b1, value, 1'b1}; endfunction function [7:0] uninitialised_4(input dummy); reg [5:0] value; uninitialised_4 = {1'b1, value, 1'b1}; endfunction localparam result_r = uninitialised_r(0); localparam result_2 = uninitialised_2(0); localparam result_4 = uninitialised_4(0); reg failed; initial begin failed = 0; $display("%0g", result_r); if (result_r != 0.0) failed = 1; $display("%b", result_2); if (result_2 !== 8'b10000001) failed = 1; $display("%b", result_4); if (result_4 !== 8'b1xxxxxx1) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/constfunc9.v000066400000000000000000000006651435245347300210330ustar00rootroot00000000000000// Test disable statements inside a constant function module constfunc10(); function [31:0] pow2(input [5:0] x); begin:body pow2 = 1; while (1) begin:loop if (x == 0) disable body; pow2 = 2 * pow2; x = x - 1; disable loop; pow2 = 0; end end endfunction localparam val = pow2(8); initial begin $display("%0d", val); if (val === 256) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/constmult.v000066400000000000000000000022141435245347300207600ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate constant multiplication in array define. // // module main (); reg [5 * 2: 0] val1; reg [10'h1 * 10: 0 ] val2 ; initial begin val1 = 11'h1 * 5; val2 = 11'h2 * 4; if((val1 === 11'h5) && (val2 === 11'h8)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/consttern.v000066400000000000000000000003071435245347300207500ustar00rootroot00000000000000module rega(A); input [0:0] A; endmodule module test(A); input [0:0] A; rega a (.A(A[(5 > 4 ? 0 : 1) : 0])); rega b (.A(A[(4 < 5 ? 0 : 1) : 0])); initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/contrib8.1.v000066400000000000000000000022301435245347300206150ustar00rootroot00000000000000// Copyright (C) 1999 Motorola, Inc. // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // 9/7/99 - SDW - Added if(!a) FAILED else PASSED module blahblah (); parameter foo = 1; reg [31:0] a; initial begin test(a); if(a != 1) $display("FAILED - contrib 8.1 foo not passed into task - bad scope"); else $display("PASSED"); end task test; output blah; begin blah = foo; end endtask // test endmodule // blahblah iverilog-12_0/ivtest/ivltests/contrib8.2.v000066400000000000000000000027641435245347300206320ustar00rootroot00000000000000/* * Copyright (c) 1998 Philips Semiconductors (Stefan.Thiede@sv.sc.philips.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // 9/7/99 - SDW - Added a PASSED message - no functional checking needed module test(); wire [1:0] a; wire [9:0] b; wire [0:9] d; a a1(.a(c)); b b1(.a(a[0])); c ci(.a({a, b})); d d1(.a({d[0:9], a[1:0]}), .d(c)); f f(a); a a3(a[1]); a a4({a[1]}); g g({a,b}); e e(); initial $display("PASSED"); endmodule module a(a); input a; endmodule module b(.a(b)); input b; endmodule module c(.a({b, c}), ); input [10:0] b; input c; endmodule module d(.a({b, c}), d); input [10:0] b; input c, d; endmodule module e(); endmodule module f({a, b}); input a, b; endmodule module g(a); input [11:0] a; endmodule iverilog-12_0/ivtest/ivltests/contrib8.3.v000066400000000000000000000020561435245347300206250ustar00rootroot00000000000000/* * Copyright (c) 1998 Philips Semiconductors (Stefan.Thiede@sv.sc.philips.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test(); MUX_REG_8x8 PAGE_REG_B3 ( .CLK (CLK), /* .IN (DATA_RES[31:24]), .OUT (PAGE[31:24]), .EN_IN (EN_B3), .EN_OUT (PAGE_SEL), */ .TC (), .TD (), .TQ ()); endmodule iverilog-12_0/ivtest/ivltests/contrib8.4.v000066400000000000000000000017251435245347300206300ustar00rootroot00000000000000/* * Copyright (c) Peter Monta (pmonta@halibut.imedia.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; wire [4:0] a; reg [4:0] b; initial b = {5{a[4]}}; // b = {5{1'b0}}; // this works initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/contrib8.5.v000066400000000000000000000040601435245347300206240ustar00rootroot00000000000000// // Copyright (c) 1999 Steve Wilson (stevew@home.com) // Based on code contributed by Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate XOR op using non-blocking assignment // module main; reg [7:0] a; reg b; reg c; reg error; initial begin #1; error = 0; for(a = 0; a <= 8'h1; a = a + 1) begin b = 0; #1 ; if(a) begin if(!c) begin $display("FAILED - XOR a=%b,b=%b,c=%b",a,b,c); error = 1; end end if(!a) begin if(c) begin $display("FAILED - XOR a=%b,b=%b,c=%b",a,b,c); error = 1; end end b = 1; #1 ; if(!a) begin if(!c) begin $display("FAILED - XOR a=%b,b=%b,c=%b",a,b,c); error = 1; end end if(a) begin if(c) begin $display("FAILED - XOR a=%b,b=%b,c=%b",a,b,c); error = 1; end end end if(!error) $display("PASSED"); end always @(a or b) c <= a ^ b; endmodule iverilog-12_0/ivtest/ivltests/countdrivers1.v000066400000000000000000000150201435245347300215370ustar00rootroot00000000000000module test(); wire n0; wire n1; wire n2; wire n3; wire n4; wand n5; wor n6; assign n1 = 1'b0; assign n2 = 1'b1; assign n3 = 1'bx; assign n4 = 1'b0; assign n4 = 1'b0; assign n4 = 1'b1; assign n4 = 1'b1; assign n4 = 1'b1; assign n4 = 1'bx; assign n5 = 1'b0; assign n5 = 1'b0; assign n5 = 1'b0; assign n5 = 1'b1; assign n5 = 1'b1; assign n5 = 1'bx; assign n6 = 1'b0; assign n6 = 1'b1; assign n6 = 1'b1; assign n6 = 1'bx; assign n6 = 1'bx; assign n6 = 1'bx; integer multi; integer forced; integer countD; integer count0; integer count1; integer countX; reg failed = 0; task check_results; input integer expected_multi; input integer expected_forced; input integer expected_countD; input integer expected_count0; input integer expected_count1; input integer expected_countX; begin $write("multi = %0d ", multi); if (multi !== expected_multi) failed = 1; if (expected_forced != -1) begin $write("forced = %0d ", forced); if (forced !== expected_forced) failed = 1; end if (expected_countD != -1) begin $write("countD = %0d ", countD); if (countD !== expected_countD) failed = 1; end if (expected_count0 != -1) begin $write("count0 = %0d ", count0); if (count0 !== expected_count0) failed = 1; end if (expected_count1 != -1) begin $write("count1 = %0d ", count1); if (count1 !== expected_count1) failed = 1; end if (expected_countX != -1) begin $write("countX = %0d ", countX); if (countX !== expected_countX) failed = 1; end $write("\n"); end endtask initial begin #0; // wait for initial values to propagate // test undriven net multi = $countdrivers(n0); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n0, forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n0, forced, countD); check_results(0, 0, 0, -1, -1, -1); multi = $countdrivers(n0, forced, countD, count0); check_results(0, 0, 0, 0, -1, -1); multi = $countdrivers(n0, forced, countD, count0, count1); check_results(0, 0, 0, 0, 0, -1); multi = $countdrivers(n0, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); force n0 = 1'bx; multi = $countdrivers(n0, forced, countD, count0, count1, countX); check_results(0, 1, 0, 0, 0, 0); // test net driven to 0 multi = $countdrivers(n1); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n1, forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n1, forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n1, forced, countD, count0); check_results(0, 0, 1, 1, -1, -1); multi = $countdrivers(n1, forced, countD, count0, count1); check_results(0, 0, 1, 1, 0, -1); multi = $countdrivers(n1, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); force n1 = 1'bx; multi = $countdrivers(n1, forced, countD, count0, count1, countX); check_results(0, 1, 1, 1, 0, 0); // test net driven to 1 multi = $countdrivers(n2); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n2, forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n2, forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n2, forced, countD, count0); check_results(0, 0, 1, 0, -1, -1); multi = $countdrivers(n2, forced, countD, count0, count1); check_results(0, 0, 1, 0, 1, -1); multi = $countdrivers(n2, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); force n2 = 1'bx; multi = $countdrivers(n2, forced, countD, count0, count1, countX); check_results(0, 1, 1, 0, 1, 0); // test net driven to X multi = $countdrivers(n3); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n3, forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n3, forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n3, forced, countD, count0); check_results(0, 0, 1, 0, -1, -1); multi = $countdrivers(n3, forced, countD, count0, count1); check_results(0, 0, 1, 0, 0, -1); multi = $countdrivers(n3, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 0, 1); force n3 = 1'bx; multi = $countdrivers(n3, forced, countD, count0, count1, countX); check_results(0, 1, 1, 0, 0, 1); // test multi-driven net multi = $countdrivers(n4); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n4, forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n4, forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n4, forced, countD, count0); check_results(1, 0, 6, 2, -1, -1); multi = $countdrivers(n4, forced, countD, count0, count1); check_results(1, 0, 6, 2, 3, -1); multi = $countdrivers(n4, forced, countD, count0, count1, countX); check_results(1, 0, 6, 2, 3, 1); force n4 = 1'bx; multi = $countdrivers(n4, forced, countD, count0, count1, countX); check_results(1, 1, 6, 2, 3, 1); // test wire and multi = $countdrivers(n5); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n5, forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n5, forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n5, forced, countD, count0); check_results(1, 0, 6, 3, -1, -1); multi = $countdrivers(n5, forced, countD, count0, count1); check_results(1, 0, 6, 3, 2, -1); multi = $countdrivers(n5, forced, countD, count0, count1, countX); check_results(1, 0, 6, 3, 2, 1); force n5 = 1'bx; multi = $countdrivers(n5, forced, countD, count0, count1, countX); check_results(1, 1, 6, 3, 2, 1); // test wire or multi = $countdrivers(n6); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n6, forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n6, forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n6, forced, countD, count0); check_results(1, 0, 6, 1, -1, -1); multi = $countdrivers(n6, forced, countD, count0, count1); check_results(1, 0, 6, 1, 2, -1); multi = $countdrivers(n6, forced, countD, count0, count1, countX); check_results(1, 0, 6, 1, 2, 3); force n6 = 1'bx; multi = $countdrivers(n6, forced, countD, count0, count1, countX); check_results(1, 1, 6, 1, 2, 3); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/countdrivers2.v000066400000000000000000000153001435245347300215410ustar00rootroot00000000000000module test(); wire [1:0] n0 = 2'bzx; wire [1:0] n1 = 2'b0x; wire [1:0] n2 = 2'b1x; wire [1:0] n3 = 2'bxx; wire [1:0] n4 = 2'bxx; wand [1:0] n5 = 2'bxx; wor [1:0] n6 = 2'bxx; assign n4 = 2'b0x; assign n4 = 2'b0x; assign n4 = 2'b1x; assign n4 = 2'b1x; assign n4 = 2'b1x; assign n5 = 2'b0x; assign n5 = 2'b0x; assign n5 = 2'b0x; assign n5 = 2'b1x; assign n5 = 2'b1x; assign n6 = 2'b0x; assign n6 = 2'b1x; assign n6 = 2'b1x; assign n6 = 2'bxx; assign n6 = 2'bxx; reg [15:0] multi; reg [15:0] forced; reg [15:0] countD; reg [15:0] count0; reg [15:0] count1; reg [15:0] countX; reg failed = 0; task check_results; input integer expected_multi; input integer expected_forced; input integer expected_countD; input integer expected_count0; input integer expected_count1; input integer expected_countX; begin $write("multi = %0d ", multi); if (multi !== expected_multi) failed = 1; if (expected_forced != -1) begin $write("forced = %0d ", forced); if (forced !== expected_forced) failed = 1; end if (expected_countD != -1) begin $write("countD = %0d ", countD); if (countD !== expected_countD) failed = 1; end if (expected_count0 != -1) begin $write("count0 = %0d ", count0); if (count0 !== expected_count0) failed = 1; end if (expected_count1 != -1) begin $write("count1 = %0d ", count1); if (count1 !== expected_count1) failed = 1; end if (expected_countX != -1) begin $write("countX = %0d ", countX); if (countX !== expected_countX) failed = 1; end $write("\n"); end endtask initial begin #0; // wait for initial values to propagate // test undriven net multi = $countdrivers(n0[1]); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n0[1], forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n0[1], forced, countD); check_results(0, 0, 0, -1, -1, -1); multi = $countdrivers(n0[1], forced, countD, count0); check_results(0, 0, 0, 0, -1, -1); multi = $countdrivers(n0[1], forced, countD, count0, count1); check_results(0, 0, 0, 0, 0, -1); multi = $countdrivers(n0[1], forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); force n0 = 2'bxx; multi = $countdrivers(n0[1], forced, countD, count0, count1, countX); check_results(0, 1, 0, 0, 0, 0); // test net driven to 0 multi = $countdrivers(n1[1]); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n1[1], forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n1[1], forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n1[1], forced, countD, count0); check_results(0, 0, 1, 1, -1, -1); multi = $countdrivers(n1[1], forced, countD, count0, count1); check_results(0, 0, 1, 1, 0, -1); multi = $countdrivers(n1[1], forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); force n1 = 2'bxx; multi = $countdrivers(n1[1], forced, countD, count0, count1, countX); check_results(0, 1, 1, 1, 0, 0); // test net driven to 1 multi = $countdrivers(n2[1]); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n2[1], forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n2[1], forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n2[1], forced, countD, count0); check_results(0, 0, 1, 0, -1, -1); multi = $countdrivers(n2[1], forced, countD, count0, count1); check_results(0, 0, 1, 0, 1, -1); multi = $countdrivers(n2[1], forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); force n2 = 2'bxx; multi = $countdrivers(n2[1], forced, countD, count0, count1, countX); check_results(0, 1, 1, 0, 1, 0); // test net driven to X multi = $countdrivers(n3[1]); check_results(0, -1, -1, -1, -1, -1); multi = $countdrivers(n3[1], forced); check_results(0, 0, -1, -1, -1, -1); multi = $countdrivers(n3[1], forced, countD); check_results(0, 0, 1, -1, -1, -1); multi = $countdrivers(n3[1], forced, countD, count0); check_results(0, 0, 1, 0, -1, -1); multi = $countdrivers(n3[1], forced, countD, count0, count1); check_results(0, 0, 1, 0, 0, -1); multi = $countdrivers(n3[1], forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 0, 1); force n3 = 2'bxx; multi = $countdrivers(n3[1], forced, countD, count0, count1, countX); check_results(0, 1, 1, 0, 0, 1); // test multi-driven net multi = $countdrivers(n4[1]); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n4[1], forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n4[1], forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n4[1], forced, countD, count0); check_results(1, 0, 6, 2, -1, -1); multi = $countdrivers(n4[1], forced, countD, count0, count1); check_results(1, 0, 6, 2, 3, -1); multi = $countdrivers(n4[1], forced, countD, count0, count1, countX); check_results(1, 0, 6, 2, 3, 1); force n4 = 2'bxx; multi = $countdrivers(n4[1], forced, countD, count0, count1, countX); check_results(1, 1, 6, 2, 3, 1); // test wire and multi = $countdrivers(n5[1]); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n5[1], forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n5[1], forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n5[1], forced, countD, count0); check_results(1, 0, 6, 3, -1, -1); multi = $countdrivers(n5[1], forced, countD, count0, count1); check_results(1, 0, 6, 3, 2, -1); multi = $countdrivers(n5[1], forced, countD, count0, count1, countX); check_results(1, 0, 6, 3, 2, 1); force n5 = 2'bxx; multi = $countdrivers(n5[1], forced, countD, count0, count1, countX); check_results(1, 1, 6, 3, 2, 1); // test wire or multi = $countdrivers(n6[1]); check_results(1, -1, -1, -1, -1, -1); multi = $countdrivers(n6[1], forced); check_results(1, 0, -1, -1, -1, -1); multi = $countdrivers(n6[1], forced, countD); check_results(1, 0, 6, -1, -1, -1); multi = $countdrivers(n6[1], forced, countD, count0); check_results(1, 0, 6, 1, -1, -1); multi = $countdrivers(n6[1], forced, countD, count0, count1); check_results(1, 0, 6, 1, 2, -1); multi = $countdrivers(n6[1], forced, countD, count0, count1, countX); check_results(1, 0, 6, 1, 2, 3); force n6 = 2'bxx; multi = $countdrivers(n6[1], forced, countD, count0, count1, countX); check_results(1, 1, 6, 1, 2, 3); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/countdrivers3.v000066400000000000000000000115741435245347300215530ustar00rootroot00000000000000module ts_pad ( inout wire pad, input wire oe, input wire op ); assign pad = oe ? op : 1'bz; endmodule module test(); wire [1:0] bus; reg oe1 = 1'b0; reg oe2 = 1'b0; reg oe3 = 1'b0; reg oe4 = 1'b0; reg oe5 = 1'b0; reg oe6 = 1'b0; wire op1 = 1'b0; wire op2 = 1'b1; wire op3 = 1'b1; wire op4 = 1'b0; wire op5 = 1'bx; wire op6 = 1'bx; ts_pad pad1(bus[0], oe1, op1); ts_pad pad2(bus[1], oe2, op2); ts_pad pad3(bus[0], oe3, op3); ts_pad pad4(bus[1], oe4, op4); bufif1(bus[0], op5, oe5); bufif1(bus[1], op6, oe6); integer multi; integer forced; integer countD; integer count0; integer count1; integer countX; reg failed = 0; task check_results; input integer expected_multi; input integer expected_forced; input integer expected_countD; input integer expected_count0; input integer expected_count1; input integer expected_countX; begin $write("multi = %0d ", multi); if (multi !== expected_multi) failed = 1; if (expected_forced != -1) begin $write("forced = %0d ", forced); if (forced !== expected_forced) failed = 1; end if (expected_countD != -1) begin $write("countD = %0d ", countD); if (countD !== expected_countD) failed = 1; end if (expected_count0 != -1) begin $write("count0 = %0d ", count0); if (count0 !== expected_count0) failed = 1; end if (expected_count1 != -1) begin $write("count1 = %0d ", count1); if (count1 !== expected_count1) failed = 1; end if (expected_countX != -1) begin $write("countX = %0d ", countX); if (countX !== expected_countX) failed = 1; end $write("\n"); end endtask initial begin #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); $display(""); oe1 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); $display(""); oe2 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); $display(""); oe3 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); $display(""); oe4 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); $display(""); oe5 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); $display(""); oe6 = 1'b1; #1; multi = $countdrivers(bus[0], forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(bus[1], forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/countdrivers4.v000066400000000000000000000115321435245347300215460ustar00rootroot00000000000000module ts_pad ( inout wire pad, input wire oe, input wire op ); assign pad = oe ? op : 1'bz; endmodule module test(); wire bus0; wire bus1; reg oe1 = 1'b0; reg oe2 = 1'b0; reg oe3 = 1'b0; reg oe4 = 1'b0; reg oe5 = 1'b0; reg oe6 = 1'b0; wire op1 = 1'b0; wire op2 = 1'b1; wire op3 = 1'b1; wire op4 = 1'b0; wire op5 = 1'bx; wire op6 = 1'bx; ts_pad pad1(bus0, oe1, op1); ts_pad pad2(bus1, oe2, op2); ts_pad pad3(bus0, oe3, op3); ts_pad pad4(bus1, oe4, op4); bufif1(bus0, op5, oe5); bufif1(bus1, op6, oe6); integer multi; integer forced; integer countD; integer count0; integer count1; integer countX; reg failed = 0; task check_results; input integer expected_multi; input integer expected_forced; input integer expected_countD; input integer expected_count0; input integer expected_count1; input integer expected_countX; begin $write("multi = %0d ", multi); if (multi !== expected_multi) failed = 1; if (expected_forced != -1) begin $write("forced = %0d ", forced); if (forced !== expected_forced) failed = 1; end if (expected_countD != -1) begin $write("countD = %0d ", countD); if (countD !== expected_countD) failed = 1; end if (expected_count0 != -1) begin $write("count0 = %0d ", count0); if (count0 !== expected_count0) failed = 1; end if (expected_count1 != -1) begin $write("count1 = %0d ", count1); if (count1 !== expected_count1) failed = 1; end if (expected_countX != -1) begin $write("countX = %0d ", countX); if (countX !== expected_countX) failed = 1; end $write("\n"); end endtask initial begin #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); $display(""); oe1 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 0, 0, 0, 0); $display(""); oe2 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); $display(""); oe3 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); $display(""); oe4 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); $display(""); oe5 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 1, 0); $display(""); oe6 = 1'b1; #1; multi = $countdrivers(bus0, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(bus1, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad1.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); multi = $countdrivers(pad2.pad, forced, countD, count0, count1, countX); check_results(1, 0, 3, 1, 1, 1); $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/countdrivers5.v000066400000000000000000000126641435245347300215560ustar00rootroot00000000000000module test(); wire net1; wire net2; wire net3; wire net4; wire net5; reg src1; reg src2; reg src3; assign net1 = src1; assign net2 = src2; assign net3 = src3; tran(net4, net1); tran(net4, net2); tran(net5, net3); tran(net5, net4); integer multi; integer forced; integer countD; integer count0; integer count1; integer countX; reg failed = 0; task check_results; input integer expected_multi; input integer expected_forced; input integer expected_countD; input integer expected_count0; input integer expected_count1; input integer expected_countX; begin $write("multi = %0d ", multi); if (multi !== expected_multi) failed = 1; if (expected_forced != -1) begin $write("forced = %0d ", forced); if (forced !== expected_forced) failed = 1; end if (expected_countD != -1) begin $write("countD = %0d ", countD); if (countD !== expected_countD) failed = 1; end if (expected_count0 != -1) begin $write("count0 = %0d ", count0); if (count0 !== expected_count0) failed = 1; end if (expected_count1 != -1) begin $write("count1 = %0d ", count1); if (count1 !== expected_count1) failed = 1; end if (expected_countX != -1) begin $write("countX = %0d ", countX); if (countX !== expected_countX) failed = 1; end $write("\n"); end endtask initial begin src1 = 1'b0; src2 = 1'b0; src3 = 1'b0; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 3, 0, 0); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); $display(""); src1 = 1'b1; src2 = 1'b0; src3 = 1'b0; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 1, 1); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 0, 1); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 0, 1); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 0, 0, 3); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 0, 2); $display(""); src1 = 1'b1; src2 = 1'b1; src3 = 1'b0; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 1, 1); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 1, 1); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(1, 0, 2, 1, 0, 1); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 0, 0, 3); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 0, 2); $display(""); src1 = 1'b1; src2 = 1'b1; src3 = 1'b1; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 0, 3, 0); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); $display(""); src1 = 1'b1; src2 = 1'bz; src3 = 1'bz; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 0, 3, 0); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); $display(""); src1 = 1'bz; src2 = 1'b0; src3 = 1'bz; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(0, 0, 1, 1, 0, 0); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 3, 0, 0); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 2, 0, 0); $display(""); src1 = 1'bz; src2 = 1'bz; src3 = 1'b1; #1; multi = $countdrivers(net1, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(net2, forced, countD, count0, count1, countX); check_results(0, 0, 1, 0, 1, 0); multi = $countdrivers(net3, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); multi = $countdrivers(net4, forced, countD, count0, count1, countX); check_results(1, 0, 3, 0, 3, 0); multi = $countdrivers(net5, forced, countD, count0, count1, countX); check_results(1, 0, 2, 0, 2, 0); $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/cprop.v000066400000000000000000000031501435245347300200530ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test triggers constant propagation through AND gates. */ module main; wire a = 1'b0; wire b = 1'b1; wire c = 1'b1; wire d = 1'bx; wire out0, out1, out2, out3; and (out0, a, b); // Should be 0 and (out1, b, c); // Should be 1 and (out2, a, d); // Should be 0 because of a and (out3, b, d); // Should be x initial begin #0 if (out0 !== 1'b0) begin $display("FAILED -- out0 = %b", out0); $finish; end if (out1 !== 1'b1) begin $display("FAILED -- out1 = %b", out1); $finish; end if (out2 !== 1'b0) begin $display("FAILED -- out2 = %b", out2); $finish; end if (out3 !== 1'bx) begin $display("FAILED -- outx = %b", out3); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/credence20041209.v000066400000000000000000000034201435245347300213220ustar00rootroot00000000000000// Copyright C(O) 2004 Burnell G West // The following text may be utilized and / or reproduced by anybody for // any reason. // // verr.v // module verr (clk, vout); input clk; output vout; reg vout; real start_edge; real end_edge; wire trigger_en; wire [9:0] v_value; initial vout = 1'b0; always @( posedge clk) begin if (trigger_en) begin start_edge = ( v_value[0] * 1.95) + ( v_value[1] * 3.9 ) + ( v_value[2] * 7.8 ) + ( v_value[3] * 15.6 ) + ( v_value[4] * 31.2 ) + ( v_value[5] * 62.5 ) + ( v_value[6] * 125 ) + ( v_value[7] * 250 ) + ( v_value[8] * 0 ) + ( v_value[9] * 0 ) + 0; end_edge = start_edge + 100; // make pulse width = 1ns end else begin start_edge <= start_edge; end_edge <= end_edge; end end endmodule module vtest; wire vout0, vout1, vout2, vout3, vout4, vout5, vout6, vout7, vout8, vout9; wire vout10, vout11, vout12, vout13, vout14, vout15, vout16, vout17, vout18, vout19; reg clk, bit0; verr v0 (clk, vout0); verr v1 (clk, vout1); verr v2 (clk, vout2); verr v3 (clk, vout3); verr v4 (clk, vout4); verr v5 (clk, vout5); verr v6 (clk, vout6); verr v7 (clk, vout7); verr v8 (clk, vout8); verr v9 (clk, vout9); verr v10 (clk, vout10); verr v11 (clk, vout11); verr v12 (clk, vout12); verr v13 (clk, vout13); verr v14 (clk, vout14); verr v15 (clk, vout15); verr v16 (clk, vout16); verr v17 (clk, vout17); verr v18 (clk, vout18); verr v19 (clk, vout19); initial begin #10000 $display("This test doesn't check itself."); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/dangling_port.v000066400000000000000000000024541435245347300215650ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: dangling_port.v,v 1.1 2001/07/08 03:22:08 sib4 Exp $ // $Log: dangling_port.v,v $ // Revision 1.1 2001/07/08 03:22:08 sib4 // Test for PR#209 // // // Test for PR#209, VVP wrong nodangle of dangling port. module main; reg retval; reg a, b; function f; input dangle; begin f = retval; end endfunction initial begin #1 retval <= 1; #1 a <= f(0); #1 b <= f(1); #1 $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/dcomp1.v000066400000000000000000000023451435245347300201200ustar00rootroot00000000000000/* dcomp1.v - this is a fragment of a larger program, which would * dynamicly compute a more interesting value for the phdelay variable. * * It illustrates a problem in verilog-20010721 when computing * time values for use in behavioral delays. */ `timescale 1ps / 1ps module dcomp; time phdelay; parameter clk_period = 400; parameter phoffset = 4; time compdelay; reg internal_Clk, Clk; initial begin $monitor("%b %b %t %t %t", internal_Clk, Clk, phdelay, compdelay, $time); phdelay = 0; #2000; phdelay = 13; #2001; $finish(0); end // initial begin initial internal_Clk <= 0; always #(clk_period/2) internal_Clk = ~internal_Clk; always @(internal_Clk) begin // uncoment only one of the next four lines: // #(phdelay); // works // #(phdelay + phoffset); // fails compdelay = phdelay + phoffset; #(compdelay); // fails // compdelay = phdelay + 4; #(compdelay); // fails $display("got here"); Clk <= internal_Clk; // of course, this is what I really want... (but that's PR#105) // Clk <= #(phdelay + phoffset + clk_period/2) internal_Clk; end // always @ (internal_Clk) endmodule // dcomp iverilog-12_0/ivtest/ivltests/deassign3.4A.v000066400000000000000000000041111435245347300210510ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate deassign reg_ident; module main ; reg [31:0] value; reg [1:0] control; reg clock; reg error; always @(posedge clock) value = 3; always @(control) if(control == 1) assign value = 1; else if(control == 2) assign value = 2; else deassign value ; // Setup a clock generator. always begin #2; clock = ~clock; end initial begin clock = 0; error = 0; # 3; if(value != 3) begin $display("FAILED - deassign3.4A - procedural assignment(1)"); error = 1; end # 2; control = 1; # 1; if(value != 1) begin $display("FAILED - deassign3.4A - procedural assignment(2)"); error = 1; end # 1 ; control = 2; # 1 ; if(value != 2) begin $display("FAILED - deassign3.4A - procedural assignment(3)"); error = 1; end #1 ; control = 0; # 10; if(value != 3) begin $display("FAILED - deassign3.4A - procedural assignment(4)"); error = 1; end if(error == 0) $display ("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/dec2to4.vhd000066400000000000000000000011611435245347300205100ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity dec2to4 is port (sel: in std_logic_vector (1 downto 0); en: in std_logic; y: out std_logic_vector (0 to 3) ); end dec2to4; architecture dec2to4_rtl of dec2to4 is begin process (sel, en) begin if (en = '1') then case sel is when "00" => y <= "1000"; when "01" => y <= "0100"; when "10" => y <= "0010"; when "11" => y <= "0001"; when others => y <= "0000"; end case; else y <= "0000"; end if; end process; end dec2to4_rtl; iverilog-12_0/ivtest/ivltests/decl_assign1.v000066400000000000000000000023301435245347300212630ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module checks integer initialization syntax. */ module main; integer i = 8; time t = 0; initial begin #1 if (i !== 8) begin $display("FAILED -- i == %b", i); $finish; end if (t !== 0) begin $display("FAILED -- t == %b", t); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/def_nettype.v000066400000000000000000000251111435245347300212370ustar00rootroot00000000000000module all; reg pass; task automatic check; input sig; input val; input [32*8:1] name; begin if (sig !== val) begin $display("FAILED \"%0s\", expected %b, got %b", name, val, sig); pass = 1'b0; end end endtask initial begin pass = 1'b1; #100; if (pass) $display("PASSED"); end endmodule /* Check the wire net type. */ `default_nettype wire module top_wire; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wire(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'bx, "wire(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wire(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "wire(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'bx, "wire(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wire(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wire(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "wire(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "wire(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "wire(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wire(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "wire(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wire(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wire(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wire(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "wire(z,z)"); end endmodule /* Check the tri net type (should be identical to wire). */ `default_nettype tri module top_tri; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "tri(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "tri(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "tri(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "tri(z,z)"); end endmodule /* Check the tri0 net type (should be the same as tri except z,z is 0). */ `default_nettype tri0 module top_tri0; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri0(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri0(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri0(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "tri0(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri0(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri0(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri0(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "tri0(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri0(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri0(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri0(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "tri0(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri0(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri0(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri0(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'b0, "tri0(z,z)"); end endmodule /* Check the tri1 net type (should be the same as tri except z,z is 1). */ `default_nettype tri1 module top_tri1; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri1(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri1(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri1(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "tri1(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri1(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri1(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri1(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "tri1(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "tri1(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "tri1(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri1(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "tri1(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "tri1(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "tri1(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "tri1(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'b1, "tri1(z,z)"); end endmodule /* Check the wand net type. */ `default_nettype wand module top_wand; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wand(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'b0, "wand(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'b0, "wand(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "wand(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wand(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wand(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wand(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "wand(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wand(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "wand(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wand(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "wand(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wand(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wand(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wand(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "wand(z,z)"); end endmodule /* Check the triand net type (should be the same as wand). */ `default_nettype triand module top_triand; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "triand(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'b0, "triand(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'b0, "triand(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "triand(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'b0, "triand(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "triand(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'bx, "triand(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "triand(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'b0, "triand(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'bx, "triand(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "triand(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "triand(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "triand(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "triand(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "triand(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "triand(z,z)"); end endmodule /* Check the wor net type. */ `default_nettype wor module top_wor; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wor(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wor(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wor(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "wor(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'b1, "wor(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wor(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'b1, "wor(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "wor(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "wor(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wor(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wor(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "wor(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "wor(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "wor(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "wor(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "wor(z,z)"); end endmodule /* Check the trior net type (should be the same as wor). */ `default_nettype trior module top_trior; reg in0, in1; assign tmp = in0; assign tmp = in1; initial begin in0 = 1'b0; in1 = 1'b0; #1 all.check(tmp, 1'b0, "trior(0,0)"); in0 = 1'b0; in1 = 1'b1; #1 all.check(tmp, 1'b1, "trior(0,1)"); in0 = 1'b0; in1 = 1'bx; #1 all.check(tmp, 1'bx, "trior(0,x)"); in0 = 1'b0; in1 = 1'bz; #1 all.check(tmp, 1'b0, "trior(0,z)"); in0 = 1'b1; in1 = 1'b0; #1 all.check(tmp, 1'b1, "trior(1,0)"); in0 = 1'b1; in1 = 1'b1; #1 all.check(tmp, 1'b1, "trior(1,1)"); in0 = 1'b1; in1 = 1'bx; #1 all.check(tmp, 1'b1, "trior(1,x)"); in0 = 1'b1; in1 = 1'bz; #1 all.check(tmp, 1'b1, "trior(1,z)"); in0 = 1'bx; in1 = 1'b0; #1 all.check(tmp, 1'bx, "trior(x,0)"); in0 = 1'bx; in1 = 1'b1; #1 all.check(tmp, 1'b1, "trior(x,1)"); in0 = 1'bx; in1 = 1'bx; #1 all.check(tmp, 1'bx, "trior(x,x)"); in0 = 1'bx; in1 = 1'bz; #1 all.check(tmp, 1'bx, "trior(x,z)"); in0 = 1'bz; in1 = 1'b0; #1 all.check(tmp, 1'b0, "trior(z,0)"); in0 = 1'bz; in1 = 1'b1; #1 all.check(tmp, 1'b1, "trior(z,1)"); in0 = 1'bz; in1 = 1'bx; #1 all.check(tmp, 1'bx, "trior(z,x)"); in0 = 1'bz; in1 = 1'bz; #1 all.check(tmp, 1'bz, "trior(z,z)"); end endmodule iverilog-12_0/ivtest/ivltests/def_nettype_none.v000066400000000000000000000004271435245347300222610ustar00rootroot00000000000000/* * 1364-2001 19.2 "When the `default_nettype is set to none, all nets must be * explicitly declared. If a net is not explicitly declared, an error is * generated." */ module ok; reg a; assign b=a; endmodule `default_nettype none module bad; reg a; assign b=a; endmodule iverilog-12_0/ivtest/ivltests/define1.v000066400000000000000000000027521435245347300202520ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Play with defines a bit // `define NUM1 10 `define NUM2 4'b0001 `define NUM3 4'h4 `define WIDTH 4 module define1 ; reg [`WIDTH-1:0] val ; reg error; initial begin error = 0; val = `NUM1 ; if(val !== 10) begin error = 1; $display("FAILED - define NUM1 10 didn't"); end val = `NUM2 ; if(val !== 4'h1) begin error = 1; $display("FAILED - define NUM1 10 didn't"); end val = `NUM3 ; if(val !== 4'b0100) begin error = 1; $display("FAILED - define NUM1 10 didn't"); end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/defparam.v000066400000000000000000000037451435245347300205210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate defparam with list // module NameA (); parameter ident0 = 12; parameter ident1 = 20 ; wire [31:0] value0 = ident0; wire [31:0] value1 = ident1; endmodule module main (); defparam main.testmodA.ident0 = 15; // Validate single val defparam main.testmodB.ident1 = 16, // Validate list of vals main.testmodB.ident0 = 17; // Validate single val reg error; NameA testmodA (); NameA testmodB (); initial begin error = 0; # 1; if(main.testmodA.value0 !== 15) begin error = 1; $display("FAILED - defparam.v main.testmodA.value0 != 15"); end # 1; if(main.testmodA.value1 !== 20) begin error = 1; $display("FAILED - defparam.v main.testmodA.value1 != 20"); end # 1; if(main.testmodB.value0 !== 17) begin error = 1; $display("FAILED - defparam.v main.testmodB.value0 != 17"); end # 1; if(main.testmodB.value1 !== 16) begin error = 1; $display("FAILED - defparam.v main.testmodB.value1 != 16"); end # 1; if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/defparam2.v000066400000000000000000000017511435245347300205760ustar00rootroot00000000000000/* * This module demonstrates the ability to use a defparam to control * the instantation of an instance array, and to also control * parameter values within the instance array. */ module main; localparam wid = 5; reg [wid-1:0] clk; dut xx (.clk(clk)); // This defparam sets the desired with of the U instance vector. defparam main.xx.wid = wid; // These defparams set parameters within U instances. defparam main.xx.U[0].number = 0; defparam main.xx.U[1].number = 1; defparam main.xx.U[2].number = 2; defparam main.xx.U[3].number = 3; defparam main.xx.U[4].number = 4; initial begin clk = 0; #1 clk = 1; while (clk != 0) #1 clk = clk << 1; $finish(0); end endmodule // main module dut #(parameter wid = 1) (input [wid-1:0] clk); target U [wid-1:0] (.clk(clk)); endmodule // module target(input wire clk); parameter number = 999; always @(posedge clk) $display("%m: number=%0d", number); endmodule // target iverilog-12_0/ivtest/ivltests/defparam3.5.v000066400000000000000000000051331435245347300207400ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate defparam module module_a (out0,in0); input in0; output [5:0] out0; parameter [5:0] ident0 = 0; parameter [5:0] ident1 = 5'h11; reg [5:0] out0; // Basic MUX switches on in0 always @ (in0) begin if(in0) out0 = ident0; else out0 = ident1; end endmodule // module_a module module_b (out0,out1,in0,in1); input in0; input in1; output [5:0] out0; output [5:0] out1; module_a testmodA (.out0(out0),.in0(in0)); module_a testmodB (.out0(out1),.in0(in1)); endmodule // module_b module main (); reg in0,in1; reg error; wire [5:0] out0,out1; defparam NameB.testmodA.ident0 = 5'h4; defparam NameB.testmodB.ident0 = 5'h5; defparam NameB.testmodB.ident1 = 5'h6; module_b NameB (.out0(out0),.out1(out1), .in0(in0),.in1(in1)); initial begin error = 0; #1 ; in0 = 0; #1 ; if(out0 != 5'h11) begin $display("FAILED - defparam3.5A - Defparam testmodA.ident0"); $display("out0 = %h",out0); error = 1; end #1 ; in0 = 1; #1 ; if(out0 != 5'h4) begin $display("FAILED - defparam3.5A - Defparam testmodA.ident0"); error = 1; end #1; in1 = 0; #1; if(out0 != 5'h4) // Validate the 0 side didn't change! begin $display("FAILED - defparam3.5A - Defparam testmodA.ident0"); error = 1; end if(out1 != 5'h6) begin $display("FAILED - defparam3.5A - Defparam testmodB.ident1"); error = 1; end #1; in1 = 1; #1; if(out1 != 5'h5) begin $display("FAILED - defparam3.5A - Defparam testmodB.ident0"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/defparam3.v000066400000000000000000000020741435245347300205760ustar00rootroot00000000000000/* * This module demonstrates the ability to use a defparam to control * the instantation of an instance array, and to also control * parameter values within the instance array. */ module main; localparam wid = 5; reg [wid-1:0] clk; dut xx (.clk(clk)); // This defparam sets the desired with of the U instance vector. defparam main.xx.wid = wid; // These defparams set parameters within U instances. defparam main.xx.sub[0].U.number = 0; defparam main.xx.sub[1].U.number = 1; defparam main.xx.sub[2].U.number = 2; defparam main.xx.sub[3].U.number = 3; defparam main.xx.sub[4].U.number = 4; initial begin clk = 0; #1 clk = 1; while (clk != 0) #1 clk = clk << 1; $finish(0); end endmodule // main module dut #(parameter wid = 1) (input [wid-1:0] clk); genvar i; for (i = 0 ; i < wid ; i = i+1) begin : sub target U (.clk(clk[i])); end endmodule // module target(input wire clk); parameter number = 999; always @(posedge clk) $display("%m: number=%0d", number); endmodule // target iverilog-12_0/ivtest/ivltests/defparam4.v000066400000000000000000000021541435245347300205760ustar00rootroot00000000000000/* * This module demonstrates the ability to use a defparam to control * the instantation of an instance array, and to also control * parameter values within the instance array. */ module main; localparam wid = 5; reg [wid-1:0] clk; if (wid > 0) begin : D dut xx (.clk(clk)); end // This defparam sets the desired with of the U instance vector. defparam main.D.xx.wid = wid; // These defparams set parameters within U instances. defparam main.D.xx.sub[0].U.number = 0; defparam main.D.xx.sub[1].U.number = 1; defparam main.D.xx.sub[2].U.number = 2; defparam main.D.xx.sub[3].U.number = 3; defparam main.D.xx.sub[4].U.number = 4; initial begin clk = 0; #1 clk = 1; while (clk != 0) #1 clk = clk << 1; $finish(0); end endmodule // main module dut #(parameter wid = 1) (input [wid-1:0] clk); genvar i; for (i = 0 ; i < wid ; i = i+1) begin : sub target U (.clk(clk[i])); end endmodule // module target(input wire clk); parameter number = 999; always @(posedge clk) $display("%m: number=%0d", number); endmodule // target iverilog-12_0/ivtest/ivltests/delay.v000066400000000000000000000025211435245347300200270ustar00rootroot00000000000000`timescale 1ns/100ps module assign_test; reg clk; reg cat1; reg cat2; reg cat3; reg cat4; reg foo1; reg foo2; reg foo3; reg foo4; reg bar1; reg bar2; reg bar3; reg bar4; initial begin clk = 0; #100 $finish(0); end always begin clk = 0; #50; clk = 1; #50; end always @(posedge clk) begin cat1 = #1 1; cat2 = #1 1; cat3 = #1 1; cat4 = #1 1; foo1 = #1 1; foo2 = #1 1; foo3 = #1 1; foo4 = #1 1; bar1 <= #1 1; bar2 <= #1 1; bar3 <= #1 1; bar4 <= #1 1; end always @(cat1) $write("time=%0t, cat1=%0h\n", $time, cat1); always @(cat2) $write("time=%04d, cat2=%0h\n", $time, cat2); always @(cat3) $write("time=%04d, cat3=%0h\n", $time, cat3); always @(cat4) $write("time=%04d, cat4=%0h\n", $time, cat4); always @(foo1) $write("time=%04d, foo1=%0h\n", $time, foo1); always @(foo2) $write("time=%04d, foo2=%0h\n", $time, foo2); always @(foo3) $write("time=%04d, foo3=%0h\n", $time, foo3); always @(foo4) $write("time=%04d, foo4=%0h\n", $time, foo4); always @(bar1) $write("time=%04d, bar1=%0h\n", $time, bar1); always @(bar2) $write("time=%04d, bar2=%0h\n", $time, bar2); always @(bar3) $write("time=%04d, bar3=%0h\n", $time, bar3); always @(bar4) $write("time=%04d, bar4=%0h\n", $time, bar4); endmodule iverilog-12_0/ivtest/ivltests/delay2.v000066400000000000000000000030241435245347300201100ustar00rootroot00000000000000/* * This program is derived from iverilog issue # 1327436. */ `timescale 1ns/1ns module verilog_test (); reg [24:0] APAD; wire [24:0] AIN; initial begin // $dumpfile("dumpfile.vcd"); // $dumpvars; APAD=25'h1ffffff; #21 if (AIN !== APAD) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #79 APAD=25'h1555555; #19 if (AIN !== 25'h1ffffff) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #2 if (AIN !== 25'h1555555) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #79 APAD=25'h0aaaaaa; #19 if (AIN !== 25'h1555555) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #2 if (AIN !== 25'h0aaaaaa) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #79 APAD=25'h1555555; #19 if (AIN !== 25'h0aaaaaa) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #2 if (AIN !== 25'h1555555) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #79 APAD=25'h0aaaaaa; #19 if (AIN !== 25'h1555555) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end #2 if (AIN !== 25'h0aaaaaa) begin $display("FAILED -- APAD=%b, AIN=%b, time=%0t", APAD, AIN, $time); $finish; end $display("PASSED"); end assign #20 AIN= APAD; endmodule iverilog-12_0/ivtest/ivltests/delay3.v000066400000000000000000000024371435245347300201200ustar00rootroot00000000000000module main; reg [7:0] period; reg drive; wire trace; // This is the main point of the test. Non-constant delay expressions // should work here. assign #(period) trace = drive; initial begin period = 8; // Initially, set up a period=8 and get the trace to start // following the drive. #1 drive <= 1; #9 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // The drive should NOT change the trace before the period. drive <= 0; #7 if (trace !== 1'b1) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // Change the period. period = 6; // Now check that the new delay is taken. #1 drive <= 1; #5 if (trace !== 1'b0) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/delay4.v000066400000000000000000000024451435245347300201200ustar00rootroot00000000000000module main; reg [7:0] period; reg drive; wire trace; // This is the main point of the test. Non-constant delay expressions // should work here. assign #(period/3) trace = drive; initial begin period = 8*3; // Initially, set up a period=8 and get the trace to start // following the drive. #1 drive <= 1; #9 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // The drive should NOT change the trace before the period. drive <= 0; #7 if (trace !== 1'b1) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // Change the period. period = 6*3; // Now check that the new delay is taken. #1 drive <= 1; #5 if (trace !== 1'b0) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/delay5.v000066400000000000000000000024041435245347300201140ustar00rootroot00000000000000module main; time period; reg drive; // This is the main point of the test. Non-constant delay expressions // should work here. wire #(period/3) trace = drive; initial begin period = 8*3; // Initially, set up a period=8 and get the trace to start // following the drive. #1 drive <= 1; #9 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // The drive should NOT change the trace before the period. drive <= 0; #7 if (trace !== 1'b1) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end // Change the period. period = 6*3; // Now check that the new delay is taken. #1 drive <= 1; #5 if (trace !== 1'b0) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end #2 if (trace !== drive) begin $display("FAILED -- time=%0t, drive=%b, trace=%b", $time, drive, trace); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/delay_assign_nb.v000066400000000000000000000030611435245347300220520ustar00rootroot00000000000000// // Copyright (c) 2001 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * This program tests the behavior of a simple non-blocking assignment * with an internal delay. We can check that the value changes at the * right time and not the wrong time. */ module main ; reg a; initial begin a = 0; if (a !== 0) begin $display("FAILED -- a at 0 is %b", a); $finish; end a <= #2 1; if (a !== 0) begin $display("FAILED -- (0) a should still be 0 but is %b", a); $finish; end #1 if (a !== 0) begin $display("FAILED -- (1) a should still be 0 but is %b", a); $finish; end #2 if (a !== 1'b1) begin $display("FAILED -- a should now be 1, but is %b", a); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/delay_assign_nb2.v000066400000000000000000000025161435245347300221400ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * This function captures the correctness of a non-constant delay * that is internal to a non-blocking assignment. */ module main; reg [7:0] delay = 0; reg step; initial begin delay = 2; step = 0; step <= #(delay) 1; #1 if (step !== 0) begin $display("FAILED -- step=%b at time=1", step); $finish; end #2 if (step !== 1) begin $display("FAILED == step=%b at time=3", step); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/delay_var.v000066400000000000000000000022771435245347300207070ustar00rootroot00000000000000`begin_keywords "1364-2005" `timescale 1ns/100ps module top; parameter pdly = 1.2; real rdly = 1.3; integer idly = 1; reg in = 1'b0; wire gi, gf, gs, gt; wire #idly int = in; wire #1.1 first = in; wire #pdly second = in; wire #rdly third = in; buf #idly (gi, in); buf #1.1 (gf, in); buf #pdly (gs, in); buf #rdly (gt, in); initial begin $monitor($realtime,, int,, first,, second,, third,, gi,, gf,, gs,, gt); #0 in = 1'b1; #2 in = 1'b0; #4; rdly = -6.1; // Since we are at 6 this will not wrap. in = 1'b1; @(third or gt) $display("Large delay: ", $realtime); end initial #1.1 $display("Should be 1.1: ", $realtime); // This should be 1.1 initial #pdly $display("Should be 1.2: ", $realtime); // This should be 1.2 initial begin #0; // We need this so that rdly has a defined value. #rdly $display("Should be 1.3: ", $realtime); // This should be 1.3 end initial begin #0; // We need this so that rdly has a defined value. #idly $display("Should be 1.0: ", $realtime); // This should be 1.0 end endmodule `timescale 1ns/1ps module top2; initial #1.001 $display("Should be 1.001: ", $realtime); endmodule `end_keywords iverilog-12_0/ivtest/ivltests/delayed_comp_reduct.v000066400000000000000000000005021435245347300227210ustar00rootroot00000000000000module top; reg [4:0]cntr; wire done; wire allone; // A delayed comparison is only 1 bit wide. If this does not crash // the run time then the compiler is producing correct code. assign #1 done = cntr == 'd7; // The same for a reduction. assign #1 allone = &cntr; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/delayed_sfunc.v000066400000000000000000000007741435245347300215460ustar00rootroot00000000000000// This test is mostly to make sure valgrind cleans up correctly. `timescale 1ns/1ns module top; wire real rtm; wire [31:0] res1, res2; integer a = 10; assign #1 rtm = $realtime; assign #1 res1 = $clog2(a); lwr dut(res2, a); initial begin $monitor($realtime,, rtm, res1,, res2,, a); #5 a = 20; end endmodule module lwr(out, in); output [31:0] out; input [31:0] in; wire [31:0] out, in; assign out = $clog2(in); specify (in => out) = (1, 1); endspecify endmodule iverilog-12_0/ivtest/ivltests/deposit.v000066400000000000000000000060751435245347300204100ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: deposit.v,v 1.4 2001/11/22 04:36:33 sib4 Exp $ // Test for vpi_put_value() to properly propagate in structural context. module deposit_test; reg ck; reg start; initial start = 0; `ifdef RTL reg [3:0] cnt; wire cnt_tc = &cnt; always @(posedge ck) if (start | ~cnt_tc) cnt <= cnt + 1; `else // !ifdef RTL wire [3:0] cnt; wire [3:0] cnt_1; wire [3:0] cnt_c; wire cnt_tc; wire ne, e; and (cnt_tc, cnt[0], cnt[1], cnt[2], cnt[3]); not (ne, cnt_tc); or (e, ne, start); had A0 (cnt[0], 1'b1, cnt_c[0], cnt_1[0]); had A1 (cnt[1], cnt_c[0], cnt_c[1], cnt_1[1]); had A2 (cnt[2], cnt_c[1], cnt_c[2], cnt_1[2]); had A3 (cnt[3], cnt_c[2], cnt_c[3], cnt_1[3]); dffe C0 (ck, e, cnt_1[0], cnt[0]); dffe C1 (ck, e, cnt_1[1], cnt[1]); dffe C2 (ck, e, cnt_1[2], cnt[2]); dffe C3 (ck, e, cnt_1[3], cnt[3]); `endif // !ifdef RTL integer r0; initial r0 = 0; integer r1; initial r1 = 0; always begin #5 ck <= 0; #4; $display("%b %b %d %d", cnt, cnt_tc, r0, r1); if (cnt_tc === 1'b0) r0 = r0 + 1; if (cnt_tc === 1'b1) r1 = r1 + 1; #1 ck <= 1; end initial begin // $dumpfile("deposit.vcd"); // $dumpvars(0, deposit_test); #22; `ifdef RTL cnt <= 4'b 1010; `else $deposit(C0.Q, 1'b0); $deposit(C1.Q, 1'b1); $deposit(C2.Q, 1'b0); $deposit(C3.Q, 1'b1); `endif #1 if (cnt !== 4'b1010) $display("FAILED"); #99; $display("%d/%d", r0, r1); if (r0===5 && r1===5) $display("PASSED"); else $display("FAILED"); $finish; end endmodule `ifdef RTL `else module dffe (CK, E, D, Q); input CK, E, D; output Q; wire qq; UDP_dffe ff (qq, CK, E, D); buf #1 (Q, qq); endmodule primitive UDP_dffe (q, cp, e, d); output q; reg q; input cp, e, d; table (01) 1 1 : ? : 1 ; (01) 1 0 : ? : 0 ; * 0 ? : ? : - ; * ? 1 : 1 : - ; * ? 0 : 0 : - ; (1x) ? ? : ? : - ; (?0) ? ? : ? : - ; ? ? * : ? : - ; ? * ? : ? : - ; endtable endprimitive module had (A, B, C, S); input A, B; output C, S; xor s (S, A, B); and c (C, A, B); endmodule `endif // !ifdef RTL iverilog-12_0/ivtest/ivltests/deposit_wire.v000066400000000000000000000032701435245347300214300ustar00rootroot00000000000000// // Copyright (c) 2001 Steve Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * The $depost system task takes the inputs a depositible object and a * value to deposit. The $deposit works like a blocking assignment, so * the target takes the value right away. * * This example tests the $deposit on a wire object. What that means is * that the wire takes on the deposited value, but that value doesn't * stick if its normal input changes. */ module main ; reg in; wire test = in; initial begin in = 1'b0; #1 if (test !== 1'b0) begin $display("FAILED -- test starts out as %b", test); //$finish; end $deposit(test, 1'b1); #1 if (test !== 1'b1) begin $display("FAILED -- test after deposit is %b", test); $finish; end in = 1'bz; #1 if (test !== 1'bz) begin $display("FAILED -- test after input is %b", test); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/dff1.v000066400000000000000000000034751435245347300175620ustar00rootroot00000000000000// Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // This tests DFF-like behavior. The clocked always block acts like a // DFF, and if the -Fsynth flag to ivl is used, actually generates an // LPM_FF device. module main () ; reg clk; reg D, Q; always #10 clk = ~clk; always @(posedge clk) Q = D; initial begin clk = 0; D = 0; @(negedge clk) if (Q !== 1'b0) begin $display("FAILED: %b !== %b", Q, D); $finish; end D = 1; @(negedge clk) if (Q !== 1'b1) begin $display("FAILED: %b !== %b", Q, D); $finish; end D = 'bx; @(negedge clk) if (Q !== 1'bx) begin $display("FAILED: %b !== %b", Q, D); $finish; end D = 'bz; @(negedge clk) if (Q !== 1'bz) begin $display("FAILED: %b !== %b", Q, D); $finish; end $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/dffsynth.v000066400000000000000000000023561435245347300205640ustar00rootroot00000000000000module main; reg [3:0] count; reg CLOCK; reg RSTn, SETn; (* ivl_synthesis_off *) initial begin CLOCK = 0; RSTn = 0; SETn = 1; #1 CLOCK = 1; #1 CLOCK = 0; if (count !== 4'b0000) begin $display("FAILED -- initial reset doesn't"); $finish; end RSTn = 1; #1 CLOCK = 1; #1 CLOCK = 0; #1 CLOCK = 1; #1 CLOCK = 0; if (count !== 4'b0010) begin $display("FAILED -- count up is %b", count); $finish; end SETn = 0; #1 ; if (count !== 4'b1101) begin $display("FAILED -- Aset failed: count=%b", count); $finish; end SETn = 1; #1 CLOCK = 1; #1 CLOCK = 0; if (count !== 4'b1110) begin $display("FAILED -- Aset didn't release: count=%b", count); $finish; end RSTn = 0; #1 ; if (count !== 4'b0000) begin $display("FAILED -- Aclr failed: count=%b", count); $finish; end $display("PASSED"); $finish; end (* ivl_synthesis_on *) always @(posedge CLOCK or negedge RSTn or negedge SETn) begin if (!RSTn) count =0; //async clear else if (!SETn) count = 4'b1101; //async set else count = count + 1; end endmodule iverilog-12_0/ivtest/ivltests/dffsynth10.v000066400000000000000000000013011435245347300207120ustar00rootroot00000000000000module top(); reg CLK; reg [3:0] D; reg EN; reg [3:0] Q; always @(posedge CLK) begin if (EN) begin Q[1] <= D[1]; Q[2] <= ~D[2]; Q[3] <= D[3]; end end reg failed; (* ivl_synthesis_off *) initial begin failed = 0; $monitor("%b %b %b %b", CLK, EN, D, Q); CLK = 0; EN = 0; D = 4'b0000; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'bxxxx) failed = 1; EN = 1; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'b010x) failed = 1; EN = 0; D = 4'b1111; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'b010x) failed = 1; EN = 1; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'b101x) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/dffsynth11.v000066400000000000000000000014631435245347300207240ustar00rootroot00000000000000module top(); reg CLK; reg RST; reg [3:1] D; reg EN; reg [3:1] Q; always @(posedge CLK or posedge RST) begin if (RST) begin Q[1] <= 1'b0; Q[2] <= 1'b1; Q[3] <= 1'b0; end else if (EN) begin Q[1] <= D[1]; Q[2] <= ~D[2]; Q[3] <= D[3]; end end reg failed; (* ivl_synthesis_off *) initial begin failed = 0; $monitor("%b %b %b %b", CLK, EN, D, Q); CLK = 0; RST = 1; EN = 0; D = 3'b111; #1 CLK = 1; #1 CLK = 0; if (Q !== 3'b010) failed = 1; EN = 1; #1 CLK = 1; #1 CLK = 0; if (Q !== 3'b010) failed = 1; RST = 0; EN = 0; #1 CLK = 1; #1 CLK = 0; if (Q !== 3'b010) failed = 1; EN = 1; #1 CLK = 1; #1 CLK = 0; if (Q !== 3'b101) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/dffsynth2.v000066400000000000000000000014271435245347300206440ustar00rootroot00000000000000/* * This program tests the synthesis of small memories, including * aysnchronous read w/ synchronous write. */ module main; reg clk; reg Q, D; (* ivl_synthesys_on *) always @(negedge clk) Q <= D; (* ivl_synthesys_off *) initial begin clk = 1; D = 0; #2 clk = 0; #2 clk = 1; #2 if (Q !== 0) begin $display("FAILED -- initial setup D=%b, Q=%b", D, Q); $finish; end D = 1; #2 clk = 0; #2 if (Q !== 1) begin $display("FAILED -- negedge clk failed D=%b, Q=%b", D, Q); $finish; end D = 0; #2 clk = 1; #2 if (Q !== 1) begin $display("FAILED -- posedge clk tripped FF. D=%b, Q=%b", D, Q); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/dffsynth3.v000066400000000000000000000021651435245347300206450ustar00rootroot00000000000000module main; reg a, b, c; reg clk, rst, rnd; (* ivl_sinthesis_on *) always @(posedge clk or posedge rst) if (rst) begin a <= 0; b <= 0; c <= 0; end else if (rnd) begin a <= 0; b <= 0; end else begin {c, b, a} <= {c, b, a} + 3'b001; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 0; rnd = 0; #1 rst = 1; #1 rst = 0; if ({c,b,a} !== 3'b000) begin $display("FAILED - no async reset"); $finish; end #1 clk = 1; #1 clk = 0; if ({c,b,a} !== 3'b001) begin $display("FAILED - First clock failed. {%b,%b,%b}", c, b, a); $finish; end #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; if ({c,b,a} !== 3'b101) begin $display("FAILED - Fifth clock failed. {%b,%b,%b}", c, b, a); $finish; end rnd = 1; #1 clk = 1; #1 clk = 0; if ({c,b,a} !== 3'b100) begin $display("FAILED - rnd failed. {%b,%b,%b}", c, b, a); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/dffsynth4.v000066400000000000000000000015101435245347300206370ustar00rootroot00000000000000module main; reg clk; reg Q, D, ce; (* ivl_synthesis_on *) always @(posedge clk) if (ce) begin end else Q <= D; (* ivl_synthesis_off *) initial begin clk = 0; ce = 0; D = 0; #1 clk = 1; #1 clk = 0; if (Q !== 1'b0) begin $display("FAILED --- initial setup failed: Q=%b, D=%b, ce=%b", Q, D, ce); $finish; end ce = 1; D = 1; #1 clk = 1; #1 clk = 0; if (Q !== 1'b0) begin $display("FAILED --- disable didnot work: Q=%b, D=%b, ce=%b", Q, D, ce); $finish; end ce = 0; #1 clk = 1; #1 clk = 0; if (Q !== 1'b1) begin $display("FAILED --- disabled disable not OK: Q=%b, D=%b, ce=%b", Q, D, ce); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/dffsynth5.v000066400000000000000000000014201435245347300206400ustar00rootroot00000000000000 module DFF (output reg Q, input wire D, input wire CLK, input wire RST /* */); always @(posedge CLK or posedge RST) if (RST) Q <= 0; else Q <= D; endmodule // dut module main; wire q; reg d, clk, rst; DFF dut (.Q(q), .D(d), .CLK(clk), .RST(rst)); initial begin clk <= 1; d <= 1; #1 rst <= 1; #1 if (q !== 1'b0) begin $display("FAILED -- RST=%b, Q=%b", rst, q); $finish; end #1 rst <= 0; #1 if (q !== 1'b0) begin $display("FAILED -- RST=%b, Q=%b", rst, q); $finish; end #1 clk <= 0; #1 clk <= 1; #1 if (q !== d) begin $display("FAILED -- Q=%b, D=%b", q, d); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/dffsynth6.v000066400000000000000000000020411435245347300206410ustar00rootroot00000000000000 module DFF (output reg Q0, output reg [1:0] Q1, input wire D0, input wire [1:0] D1, input wire CLK, input wire RST /* */); always @(posedge CLK or posedge RST) if (RST) begin Q0 <= 0; Q1 <= 0; end else begin Q0 <= D0; Q1 <= D1; end endmodule // dut module main; wire q0; wire [1:0] q1; reg d0, clk, rst; reg [1:0] d1; DFF dut (.Q0(q0), .Q1(q1), .D0(d0), .D1(d1), .CLK(clk), .RST(rst)); initial begin clk <= 1; d0 <= 0; d1 <= 2; #1 rst <= 1; #1 if (q0 !== 1'b0 || q1 !== 1'b0) begin $display("FAILED -- RST=%b, Q0=%b, Q1=%b", rst, q0, q1); $finish; end #1 rst <= 0; #1 if (q0 !== 1'b0 || q1 !== 1'b0) begin $display("FAILED -- RST=%b, Q0=%b, Q1=%b", rst, q0, q1); $finish; end #1 clk <= 0; #1 clk <= 1; #1 if (q0 !== d0 || q1 !== d1) begin $display("FAILED -- Q0=%b Q1=%b, D0=%b D1=%b", q0, q1, d0, d1); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/dffsynth7.v000066400000000000000000000016461435245347300206540ustar00rootroot00000000000000module dff(); reg clk; reg rst; reg ce; reg [3:0] d; reg [3:0] q; always @(negedge clk or posedge rst) begin if (rst) q <= 4'b1001; else if (ce) q <= d; end (* ivl_synthesis_off *) reg failed = 0; initial begin $monitor("%b %b %b %b", rst, clk, d, q); clk = 1'b0; ce = 1'b0; rst = 1'b0; d = 4'b0110; #1; if (q !== 4'bxxxx) failed = 1; rst = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b1001) failed = 1; rst = 1'b0; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b1001) failed = 1; ce = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b0110) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule // dff iverilog-12_0/ivtest/ivltests/dffsynth8.v000066400000000000000000000016741435245347300206560ustar00rootroot00000000000000module dff(); reg clk; reg rst; reg ce; reg [3:0] s; reg [3:0] d; reg [3:0] q; always @(negedge clk or posedge rst) begin if (rst) q <= s; else if (ce) q <= d; end (* ivl_synthesis_off *) reg failed = 0; initial begin $monitor("%b %b %b %b", rst, clk, d, q); clk = 1'b0; ce = 1'b0; rst = 1'b0; s = 4'b1001; d = 4'b0110; #1; if (q !== 4'bxxxx) failed = 1; rst = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b1001) failed = 1; rst = 1'b0; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b1001) failed = 1; ce = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b1; #1; if (q !== 4'b1001) failed = 1; clk = 1'b0; #1; if (q !== 4'b0110) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule // dff iverilog-12_0/ivtest/ivltests/dffsynth9.v000066400000000000000000000014731435245347300206540ustar00rootroot00000000000000module top(); reg CLK; reg [3:0] D; reg EN1; reg EN2; reg EN3; reg [3:0] Q; always @(posedge CLK) begin if (EN1) Q[1] <= D[1]; if (EN2) Q[2] <= D[2]; if (EN3) Q[3] <= D[3]; end reg failed; (* ivl_synthesis_off *) initial begin failed = 0; $monitor("%b %b %b %b %b %b", CLK, EN1, EN2, EN3, D, Q); CLK = 0; EN1 = 0; EN2 = 0; EN3 = 0; D = 4'b0000; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'bxxxx) failed = 1; EN1 = 1; D = 4'b0000; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'bxx0x) failed = 1; EN1 = 0; EN2 = 1; D = 4'b1111; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'bx10x) failed = 1; EN2 = 0; EN3 = 1; D = 4'b0000; #1 CLK = 1; #1 CLK = 0; if (Q !== 4'b010x) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/disable3.6A.v000066400000000000000000000034211435245347300206640ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate defparam module main (); reg clock; reg q; reg reset; reg error; always @(posedge clock or posedge reset) begin : FF # 2; if(reset) q <= 0; else q <= ~q; end initial begin // Set reset to init f/f. error = 0; clock = 0; reset = 1; #4 ; if(q != 1'b0) begin $display("FAILED - disable3.6A - Flop didn't clear on clock & reset"); error = 1; end reset = 1'b0; clock = 1'b1; # 3; if(q != 1'b1) begin $display("FAILED - disable3.6A - Flop didn't set on clock"); error = 1; end clock = 1'b0; # 3; clock = 1'b1; // Now cause the toggle edge # 1; disable FF; // And disable the toggle event # 2; if(q != 1'b1) begin $display("FAILED - disable3.6A - Disable didn't stop FF toggle"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/disable3.6B.v000066400000000000000000000035321435245347300206700ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate defparam module main (); reg clock; reg q; reg reset; reg error; task task_a ; begin # 2; if(reset) q = 0; else q = ~q ; end endtask initial begin // Set reset to init f/f. error = 0; reset = 1; task_a ; // Same as posedge reset in previous test #4 ; if(q != 1'b0) begin $display("FAILED - disable3.6B - Flop didn't clear on clock & reset"); error = 1; end reset = 1'b0; task_a ; // First clock edge from orig test # 3; if(q != 1'b1) begin $display("FAILED - disable3.6B - Flop didn't set on clock"); error = 1; end # 3; fork task_a ; // Toggle f/f clock edge begin # 1; disable task_a; // And disable the toggle event end join if(q != 1'b1) begin $display("FAILED - disable3.6B - Disable task didn't stop toggle"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/disable_cleanup.v000066400000000000000000000006461435245347300220510ustar00rootroot00000000000000module bug(); reg clock = 0; always begin #1 clock = 1; #1 clock = 0; end integer count = 0; initial begin:counter forever begin repeat (2) @(posedge clock); count = count + 1; $display(count); end end initial begin repeat (5) @(posedge clock); disable counter; repeat (4) @(posedge clock); if (count === 2) $display("PASSED"); else $display("FAILED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/disable_fork.v000066400000000000000000000020511435245347300213530ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; initial begin fork :fork_label #100 disable fork_label; #200 begin $display("FAILED -- shouldn't get here"); $finish; end join $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/disable_fork_cmd.v000066400000000000000000000016511435245347300222030ustar00rootroot00000000000000module top; reg passed; reg [4:1] result; initial begin passed = 1'b1; result = 4'b0000; // Fork some processes and wait for the one with the least delay to finish. fork #3 result[3] = 1'b1; #4 result[4] = 1'b1; join_none fork #1 result[1] = 1'b1; #2 result[2] = 1'b1; join_any // Disable the rest of the forked processes. disable fork; // Only the 1st bit should be set. if (result !== 4'b0001) begin $display("More than one process ran before the disable fork: %b", result); passed = 1'b0; result = 4'b0001; end // Wait to make sure the disabled processes do not run at a later time. #10; // Only the 1st bit should still be set. if (result !== 4'b0001) begin $display("Processes ran to completion after being disabled: %b", result); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/disblock.v000066400000000000000000000022621435245347300205250ustar00rootroot00000000000000// // Copyright (c) 2002 Philip Blundell // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Disable within named block. // module m(); initial begin #10; $display("FAILED"); $finish; end task t; begin begin:wait_loop #1; while(1) begin #1; disable wait_loop; end // while(1) end // wait_loop end endtask initial begin t; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/disblock2.v000066400000000000000000000010121435245347300205770ustar00rootroot00000000000000module test; reg [1:0] result; initial begin $display("hello world, 'b%b", 1'b1); result = get_bytes(4'b0111); end function [1:0] get_bytes; input [3:0] in_byte_enable; reg my_byte; begin my_byte = 3; begin: while_block while (in_byte_enable[my_byte] == 1) begin $display("Byte enable is 'h%h", my_byte); if(my_byte == 0) disable while_block; my_byte = my_byte - 1; end end get_bytes = 2'b11; end endfunction endmodule iverilog-12_0/ivtest/ivltests/disp_dec.v000066400000000000000000000023111435245347300205000ustar00rootroot00000000000000/* * Copyright (c) 1998 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This demonstrates proper handling of unknown values in decimal output. */ module main(); initial begin $display("4'bxxxx = %d", 4'bxxxx); $display("4'bzzxx = %d", 4'bzzxx); $display("4'bzzzz = %d", 4'bzzzz); $display("4'b00zz = %d", 4'b00zz); $display("4'b0000 = %d", 4'b0000); $display("4'b0011 = %d", 4'b0011); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/disp_dec2.v000066400000000000000000000016551435245347300205740ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main (); initial begin $display("%0d (should be -1)", -1); end endmodule iverilog-12_0/ivtest/ivltests/disp_leading_z.v000066400000000000000000000021521435245347300217040ustar00rootroot00000000000000/* * Copyright (c) 1998 Purdea Andrei (purdeaandrei@yahoo.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This demonstrates proper handling of leading zeroes, and the %0b format. */ module main(); initial begin $display("|%b|", 10'b11); $display("|%0b|", 10'b11); $display("|%b|", 10'b0); $display("|%0b|", 10'b0); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/disp_parm.v000066400000000000000000000004201435245347300207030ustar00rootroot00000000000000/* From PR#516 */ module top (); parameter GEORGE = 8'd5; parameter HARRY = 10; initial begin #1; $display("decimal GEORGE: %0d, HARRY: %0d",GEORGE, HARRY); $display("binary GEORGE: 'b%0b, HARRY: 'b%0b",GEORGE, HARRY); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/disp_part.v000066400000000000000000000022671435245347300207250ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * The output from this program should be: * 1001 * 0100 * 0010 * 1001 * 1100 */ module main; reg [7:0] foo; initial begin foo = 8'b11001001; $display("%b", foo[3:0]); $display("%b", foo[4:1]); $display("%b", foo[5:2]); $display("%b", foo[6:3]); $display("%b", foo[7:4]); end endmodule // main iverilog-12_0/ivtest/ivltests/display_bug.v000066400000000000000000000013551435245347300212370ustar00rootroot00000000000000module main; typedef struct packed { logic [7:0] high; logic [7:0] low; } word; word [2] array; // word[0:1] exposes the bug as well word single; initial begin array[0].high = "a"; array[0].low = "b"; array[1].high = "c"; array[1].low = "d"; $display("%s", array[0]); // good $display("%s %s", array[0].high, array[0].low); $display("%s", array[1]); // good // the line below displays contents of array[0] instead of array[1] $display("%s %s", array[1].high, array[1].low); // below everything is fine single = array[0]; $display("%s", single); $display("%s %s", single.high, single.low); end endmodule iverilog-12_0/ivtest/ivltests/dotinid.v000066400000000000000000000025111435245347300203620ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: dotinid.v,v 1.1 2001/06/26 00:32:18 sib4 Exp $ // $Log: dotinid.v,v $ // Revision 1.1 2001/06/26 00:32:18 sib4 // Two new tests for identifier parsing/elaboration // // // IVL parser/elaboration test for escaped names with . module a; wire \a.b ; m \c.d (\a.b ); initial begin \c.d . \y.z <= 1'b1; #1; if (\a.b === 1'b1) $display("PASSED"); else $display("FAILED"); end endmodule module m(x); output x; reg \y.z ; assign x = \y.z ; endmodule iverilog-12_0/ivtest/ivltests/drive_strength.v000066400000000000000000000116241435245347300217640ustar00rootroot00000000000000/* * Copyright (c) 2000 Guy Hutchison (ghutchis@pacbell.net) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ //`define DEBUG `define BUG_FIX module drive_strength; // strength values (append 1/0 to each): // supply -> strong -> pull -> weak -> highz /* * Strength Value Table * 1--> supply | strong | pull | weak | highz * supply x | 0 | 0 | 0 | 0 * strong 1 | x | 0 | 0 | 0 * pull 1 | 1 | x | 0 | 0 * weak 1 | 1 | 1 | x | 0 * highz 1 | 1 | 1 | 1 | z */ wire su1su0, su1st0, su1pu0, su1we0, su1hz0; wire st1su0, st1st0, st1pu0, st1we0, st1hz0; wire pu1su0, pu1st0, pu1pu0, pu1we0, pu1hz0; wire we1su0, we1st0, we1pu0, we1we0, we1hz0; wire hz1su0, hz1st0, hz1pu0, hz1we0, hz1hz0; /* supply assignments */ assign (supply1, supply0) su1su0 = 1'b1; assign (supply1, supply0) su1st0 = 1'b1; assign (supply1, supply0) su1pu0 = 1'b1; assign (supply1, supply0) su1we0 = 1'b1; assign (supply1, supply0) su1hz0 = 1'b1; /* strong assignments */ assign (strong1, strong0) st1su0 = 1'b1; assign (strong1, strong0) st1st0 = 1'b1; assign (strong1, strong0) st1pu0 = 1'b1; assign (strong1, strong0) st1we0 = 1'b1; assign (strong1, strong0) st1hz0 = 1'b1; /* pull assignments */ assign (pull1, pull0) pu1su0 = 1'b1; assign (pull1, pull0) pu1st0 = 1'b1; assign (pull1, pull0) pu1pu0 = 1'b1; assign (pull1, pull0) pu1we0 = 1'b1; assign (pull1, pull0) pu1hz0 = 1'b1; /* weak assignments */ assign (weak1, weak0) we1su0 = 1'b1; assign (weak1, weak0) we1st0 = 1'b1; assign (weak1, weak0) we1pu0 = 1'b1; assign (weak1, weak0) we1we0 = 1'b1; assign (weak1, weak0) we1hz0 = 1'b1; /* highz assignments */ assign (highz1, strong0) hz1su0 = 1'b1; assign (highz1, strong0) hz1st0 = 1'b1; assign (highz1, strong0) hz1pu0 = 1'b1; assign (highz1, strong0) hz1we0 = 1'b1; assign (highz1, strong0) hz1hz0 = 1'b1; /* supply assignments */ assign (supply1, supply0) su1su0 = 1'b0; assign (supply1, supply0) st1su0 = 1'b0; assign (supply1, supply0) pu1su0 = 1'b0; assign (supply1, supply0) we1su0 = 1'b0; assign (supply1, supply0) hz1su0 = 1'b0; /* strong assignments */ assign (strong1, strong0) su1st0 = 1'b0; assign (strong1, strong0) st1st0 = 1'b0; assign (strong1, strong0) pu1st0 = 1'b0; assign (strong1, strong0) we1st0 = 1'b0; assign (strong1, strong0) hz1st0 = 1'b0; /* pull assignments */ assign (pull1, pull0) su1pu0 = 1'b0; assign (pull1, pull0) st1pu0 = 1'b0; assign (pull1, pull0) pu1pu0 = 1'b0; assign (pull1, pull0) we1pu0 = 1'b0; assign (pull1, pull0) hz1pu0 = 1'b0; /* weak assignments */ assign (weak1, weak0) su1we0 = 1'b0; assign (weak1, weak0) st1we0 = 1'b0; assign (weak1, weak0) pu1we0 = 1'b0; assign (weak1, weak0) we1we0 = 1'b0; assign (weak1, weak0) hz1we0 = 1'b0; /* highz assignments */ assign (strong1, highz0) su1hz0 = 1'b0; assign (strong1, highz0) st1hz0 = 1'b0; assign (strong1, highz0) pu1hz0 = 1'b0; assign (strong1, highz0) we1hz0 = 1'b0; assign (strong1, highz0) hz1hz0 = 1'b0; initial begin `ifdef DEBUG $dumpfile ("verilog.dump"); $dumpvars (0, drive_strength); `endif /* check all values for 1/x/0 */ #1; // Give things a chance to evaluate!!! if ((su1su0 !== 1'bx) || (su1st0 !== 1'b1) || (su1pu0 !== 1'b1) || (su1we0 !== 1'b1) || (su1hz0 !== 1'b1) || (st1su0 !== 1'b0) || (st1st0 !== 1'bx) || (st1pu0 !== 1'b1) || (st1we0 !== 1'b1) || (st1hz0 !== 1'b1) || (pu1su0 !== 1'b0) || (pu1st0 !== 1'b0) || (pu1pu0 !== 1'bx) || (pu1we0 !== 1'b1) || (pu1hz0 !== 1'b1) || (we1su0 !== 1'b0) || (we1st0 !== 1'b0) || (we1pu0 !== 1'b0) || (we1we0 !== 1'bx) || (we1hz0 !== 1'b1) || (hz1su0 !== 1'b0) || (hz1st0 !== 1'b0) || (hz1pu0 !== 1'b0) || (hz1we0 !== 1'b0) || (hz1hz0 !== 1'bz)) $display ("FAILED - drive_strength"); else $display ("PASSED"); #10; $finish; end // initial begin `ifdef BUG_FIX reg bug_fix; initial begin bug_fix = 0; #2; bug_fix = 1; #2; bug_fix = 0; end `endif // ifdef BUG_FIX endmodule iverilog-12_0/ivtest/ivltests/drive_strength1.v000066400000000000000000000062701435245347300220460ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests some tricky-to-compile strength syntax. Show that * gates can drive a wire with various strengths and be properly resolved. */ module main(); reg pullval; wire (weak0, weak1) value = pullval; reg en0, en1; /* This buffer will drive a strong 1 to value if en0 is 1, otherwise it will go HiZ. */ buf (highz0, strong1) drive0(value, en0); /* This inverter will drive a strong 0 to value if en1 is 1, otherwise is will go HiZ. */ not (strong0, highz1) drive1(value, en1); initial begin en0 = 0; en1 = 0; /* Make sure when the other drivers are disabled, the pullval can pull the value up or down. The gates should be HiZ. */ pullval = 1; #1 if (value !== 1'b1) begin $display("FAILED -- value is %b", value); $finish; end pullval = 0; #1 if (value !== 1'b0) begin $display("FAILED -- value is %b", value); $finish; end /* When en0 is 1, drive0 puts a strong 1 onto value so the pullval should not matter. */ en0 = 1; pullval = 1; #1 if (value !== 1'b1) begin $display("FAILED -- en0==%b en1==%b pull==%b value==%b", en0, en1, pullval, value); $finish; end pullval = 0; #1 if (value !== 1'b1) begin $display("FAILED -- en0==%b en1==%b pull=0%b value==%b", en0, en1, pullval, value); $finish; end /* When en1 is 1, drive1 puts a strong 0 onto value so the pullval should not matter. */ en0 = 0; en1 = 1; pullval = 1; #1 if (value !== 1'b0) begin $display("FAILED -- en0==%b en1==%b pull=0%b value==%b", en0, en1, pullval, value); $finish; end pullval = 0; #1 if (value !== 1'b0) begin $display("FAILED -- en0==%b en1==%b pull=0%b value==%b", en0, en1, pullval, value); $finish; end /* When both enables are 1, we have a double driven signal and the value should be x. */ en0 = 1; en1 = 1; pullval = 1; #1 if (value !== 1'bx) begin $display("FAILED -- en0==%b en1==%b pull=0%b value==%b", en0, en1, pullval, value); $finish; end pullval = 0; #1 if (value !== 1'bx) begin $display("FAILED -- en0==%b en1==%b pull=0%b value==%b", en0, en1, pullval, value); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/drive_strength2.v000066400000000000000000000027121435245347300220440ustar00rootroot00000000000000/* * Copyright (c) 2000 Yasuhisa Kato * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module drvz( clk, iA, iC, ioS ); input clk, iA, iC ; inout ioS ; assign ioS = (iC) ? iA : 'bz ; endmodule module main; reg clk, c ; initial begin clk = 0 ; forever #5 clk = ~clk ; end initial begin c = 0 ; #40 $finish(0); end wire a, b, s ; assign a = 'b0 ; assign b = 'b1 ; always @(posedge clk) c <= ~c ; drvz M ( clk, a, c, s ) ; drvz N ( clk, b, ~c, s ) ; // line(A) always @(posedge clk) $display("%b %b %b", s, a, b ); endmodule // expected output // 1 0 1 // 0 0 1 // 1 0 1 // 0 0 1 // ivl 0.3 result // x 0 1 // 0 0 1 // x 0 1 // 0 0 1 iverilog-12_0/ivtest/ivltests/drive_strength3.v000066400000000000000000000030601435245347300220420ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This tests the behavior of drive strength attached to a buf device. * The assign of a reg to the bit should override the value and give a * well defined result. */ module main; wire bit; PULLDOWN pd(bit); reg drv; assign bit = drv; initial begin drv = 0; #100 if (bit !== 1'b0) begin $display("FAILED -- 0 bit = %b", bit); $finish; end drv = 1; #100 if (bit !== 1'b1) begin $display("FAILED -- 1 bit = %b", bit); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main module PULLDOWN (O); output O; wire A; pulldown (A); buf (weak0,weak1) #(1,1) (O,A); endmodule `end_keywords iverilog-12_0/ivtest/ivltests/dummy7.v000066400000000000000000000041201435245347300201500ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Rowland * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module dummy7; `define ADDR1 16'h0011 `define ADDR2 16'h0022 `define ADDR81 8'h11 `define ADDR82 8'h22 reg [7:0] data1; reg [7:0] data2; reg [7:0] data3; reg [7:0] data4; reg [7:0] addr; reg [15:0] addr16; // use mod operator to convert literal to 8 bits - this works in verilogXL always @ (addr) case (addr) `ADDR1 %256 : data1 = 8'h11; `ADDR2 %256 : data1 = 8'h22; default : data1 = 8'h00; endcase // icarus like this always @ (addr) case (addr) `ADDR1 : data2 = 8'h11; `ADDR2 : data2 = 8'h22; default : data2 = 8'h00; endcase always @ (addr16) case (addr16) `ADDR1 : data3 = 8'h11; `ADDR2 : data3 = 8'h22; default : data3 = 8'h00; endcase always @ (addr) case (addr) `ADDR81 : data4 = 8'h11; `ADDR82 : data4 = 8'h22; default : data4 = 8'h00; endcase initial begin addr = 8'h00; addr16 = 16'h0000; #10; $display("should be 00 -- data1=%h data2=%h data3=%h data4=%h\n",data1,data2,data3,data4); addr = 8'h11; addr16 = 16'h0011; #10; $display("should be 11 -- data1=%h data2=%h data3=%h data4=%h\n",data1,data2,data3,data4); addr = 8'h22; addr16 = 16'h0022; #10; $display("should be 22 -- data1=%h data2=%h data3=%h data4=%h\n",data1,data2,data3,data4); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/dump_memword.v000066400000000000000000000002521435245347300214270ustar00rootroot00000000000000module top; reg [7:0] arr [4:-2]; initial begin $dumpfile("work/test.vcd"); $dumpvars(1, arr[4]); arr[4] = 8'h00; #1 arr[4] = 8'hff; end endmodule iverilog-12_0/ivtest/ivltests/dumpvars.v000066400000000000000000000026701435245347300205770ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: dumpvars.v,v 1.2 2007/12/06 02:31:10 stevewilliams Exp $ // $Log: dumpvars.v,v $ // Revision 1.2 2007/12/06 02:31:10 stevewilliams // Clean up work files (caryr) // // Revision 1.1 2001/07/08 02:56:25 sib4 // Test for PR#174 // // // Test if $dumpvars() accepts non-hierachical names module dumptest; submod u1(0); submod u2(1); initial begin $dumpfile("work/dumptest.vcd"); $dumpvars(0, dumptest.u1); $dumpvars(0, u2); $display("PASSED"); $finish; end endmodule module submod (b); input b; reg a; initial a = b; endmodule iverilog-12_0/ivtest/ivltests/edge.v000066400000000000000000000035611435245347300176420ustar00rootroot00000000000000module top; reg passed; reg pevt; reg evt; reg pedge; reg nedge; initial begin passed = 1'b1; #1; // Check X to 0 {pedge, nedge} = 2'b01; evt = 1'b0; #1; // Check 0 to X pevt = evt; {pedge, nedge} = 2'b10; evt = 1'bx; #1; // Check X to 1 pevt = evt; {pedge, nedge} = 2'b10; evt = 1'b1; #1; // Check 1 to X pevt = evt; {pedge, nedge} = 2'b01; evt = 1'bx; #1; // Check X to Z pevt = evt; {pedge, nedge} = 2'b00; evt = 1'bz; #1; // Check Z to X pevt = evt; {pedge, nedge} = 2'b00; evt = 1'bx; #1; // Check X to Z (again) pevt = evt; {pedge, nedge} = 2'b00; evt = 1'bz; #1; // Check Z to 0 pevt = evt; {pedge, nedge} = 2'b01; evt = 1'b0; #1; // Check 0 to Z pevt = evt; {pedge, nedge} = 2'b10; evt = 1'bz; #1; // Check Z to 1 pevt = evt; {pedge, nedge} = 2'b10; evt = 1'b1; #1; // Check 1 to Z pevt = evt; {pedge, nedge} = 2'b01; evt = 1'bz; #1; // Check Z to 1 (again) pevt = evt; {pedge, nedge} = 2'b10; evt = 1'b1; #1; // Check 1 to 0 pevt = evt; {pedge, nedge} = 2'b01; evt = 1'b0; #1; // Check 0 to 1 pevt = evt; {pedge, nedge} = 2'b10; evt = 1'b1; #1; if (passed) $display("PASSED"); end always @(posedge evt) begin if (!pedge) begin $display("Error: posedge detected for %b -> %b", pevt, evt); passed = 1'b0; end end always @(negedge evt) begin if (!nedge) begin $display("Error: negedge detected for %b -> %b", pevt, evt); passed = 1'b0; end end always @(edge evt) begin if (!nedge && !pedge) begin $display("Error: edge detected for %b -> %b", pevt, evt); passed = 1'b0; end end always @(evt) $display("Checking the %b -> %b event", pevt, evt); endmodule iverilog-12_0/ivtest/ivltests/eeq.v000066400000000000000000000033661435245347300175130ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: eeq.v,v 1.1 2001/06/26 01:07:15 sib4 Exp $ // $Log: eeq.v,v $ // Revision 1.1 2001/06/26 01:07:15 sib4 // new test for === and !== // // // Test for === amd !== in structural context. module eeq; reg [3:0] a, b; wire eeq = a === b; `ifdef DONT_TEST_NEE wire nee = ~(a === b); `else wire nee = a !== b; `endif reg err; always begin #2; $display("%b %b ===%b !==%b", a, b, eeq, nee); if (((a === b) !== eeq) || ((a !== b) !== nee)) err = 1; end initial begin err = 0; #1 a = 4'b zx10; b = 4'b zx10; #1; #1 a = 4'b 1x10; b = 4'b zx10; #1; #1 a = 4'b xz10; b = 4'b zx10; #1; #1 a = 4'b xz01; b = 4'b zx10; #1; #1 a = 4'b 0000; b = 4'b 0000; #1; #1 a = 4'b 1111; b = 4'b 1111; #1; #1 a = 4'b xxxx; b = 4'b xxxx; #1; #1 a = 4'b zzzz; b = 4'b zzzz; #1; #1; if (err) $display("FAILED"); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/else1.v000066400000000000000000000023011435245347300177360ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Basic ifdef test with else, no define // module ifdef1; reg error ; `ifdef NOCODE initial begin #20; error = 1; #20; end `else initial begin #20; error = 0; #20; end `endif initial begin #1; error = 1; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/else2.v000066400000000000000000000023551435245347300177500ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Compound ifdef test with else, exterior define // `define DOUBLE module ifdef1; reg error ; `ifdef DOUBLE `ifdef NOCODE initial begin #20; error = 1; #20; end `else initial begin #20; error = 0; #20; end `endif `endif initial begin #1; error = 1; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/else3.v000066400000000000000000000024411435245347300177450ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Compound ifdef test with else, exterior define // module ifdef1; reg error ; `ifdef DOUBLE initial begin #20; error = 1; #20; end `else `ifdef NOCODE initial begin #20; error = 1; #20; end `else initial begin #20; error = 0; #20; end `endif `endif initial begin #1; error = 1; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/elsif_test.v000066400000000000000000000021651435245347300210760ustar00rootroot00000000000000module elsif_test(); `define DEFINED integer i; initial begin i = 0; `ifdef DEFINED `ifdef DEFINED i = i + 1; `elsif DEFINED i = 100; `else i = 110; `endif `elsif DEFINED `ifdef DEFINED i = 120; `elsif DEFINED i = 130; `else i = 140; `endif `else `ifdef DEFINED i = 150; `elsif DEFINED i = 160; `else i = 170; `endif `endif `ifdef UNDEFINED `ifdef DEFINED i = 200; `elsif DEFINED i = 210; `else i = 220; `endif `elsif DEFINED `ifdef UNDEFINED i = 230; `elsif DEFINED i = i + 1; `else i = 240; `endif `else `ifdef UNDEFINED i = 250; `elsif DEFINED i = 260; `else i = 270; `endif `endif `ifdef UNDEFINED `ifdef UNDEFINED i = 300; `elsif UNDEFINED i = 310; `else i = 320; `endif `elsif UNDEFINED `ifdef UNDEFINED i = 330; `elsif UNDEFINED i = 340; `else i = 350; `endif `else `ifdef UNDEFINED i = 360; `elsif UNDEFINED i = 370; `else i = i + 1; `endif `endif if (i == 3) $display("PASSED"); else $display("Test FAILED: %d", i); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_atom2.v000066400000000000000000000006651435245347300220000ustar00rootroot00000000000000// Check that it is possible to declare an enum type with an atom2 type as the // base type. module test; enum byte { A } e1; enum shortint { B } e2; enum int { C } e3; enum longint { D } e4; initial begin if ($bits(e1) == 8 && $bits(e2) == 16 && $bits(e3) == 32 && $bits(e4) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_array.v000066400000000000000000000003211435245347300230540ustar00rootroot00000000000000// Check that using an array type as the base type for an enum results in an // error. module test; typedef logic T[1:0]; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_class.v000066400000000000000000000003121435245347300230430ustar00rootroot00000000000000// Check that using a class type as the base type for an enum results in an // error. class C; endclass module test; enum C { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_darray.v000066400000000000000000000003251435245347300232240ustar00rootroot00000000000000// Check that using a dynamic array type as the base type for an enum results in // an error. module test; typedef logic T[]; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_enum.v000066400000000000000000000003261435245347300227070ustar00rootroot00000000000000// Check that using an enum type as the base type for an enum results in an // error. module test; typedef enum { X } T; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_queue.v000066400000000000000000000003151435245347300230650ustar00rootroot00000000000000// Check that using a queue type as the base type for an enum results in an // error module test; typedef logic T[$]; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_range1.v000066400000000000000000000004601435245347300231170ustar00rootroot00000000000000// Check that using a type identifier that resolves to a type with a packed // dimensions together with another packed dimensions as the base type for an // enum results in an error. module test; typedef int T; enum T [1:0] { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_range2.v000066400000000000000000000004211435245347300231150ustar00rootroot00000000000000// Check that using a type identifier that resolves to a type with multiple // packed dimensions as the base type for an enum results in an error. module test; typedef bit [1:0][1:0] T; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_range3.v000066400000000000000000000003541435245347300231230ustar00rootroot00000000000000// Check that specifying a vector type with multiple packed dimensions as the // base type for an enum results in an error. module test; enum logic [1:0][1:0] { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_real1.v000066400000000000000000000002711435245347300227460ustar00rootroot00000000000000// Check that using a real type as the base type for an enum results in an // error. module test; enum real { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_real2.v000066400000000000000000000003111435245347300227420ustar00rootroot00000000000000// Check that using a real type as the base type for an enum results in an // error. module test; typedef real T; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_string1.v000066400000000000000000000002751435245347300233350ustar00rootroot00000000000000// Check that using a string type as the base type for an enum results in an // error. module test; enum string { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_string2.v000066400000000000000000000003151435245347300233310ustar00rootroot00000000000000// Check that using a string type as the base type for an enum results in an // error. module test; typedef string T; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_fail_struct.v000066400000000000000000000003451435245347300232700ustar00rootroot00000000000000// Check that using a struct type as the base type for an enum results in an // error. module test; typedef struct packed { int x; } T; enum T { A } e; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_base_integer.v000066400000000000000000000004501435245347300224030ustar00rootroot00000000000000// Check that it is possible to declare an enum type with the integer type as // the base type. module test; enum integer { A } E; initial begin if ($bits(E) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_none.v000066400000000000000000000004771435245347300217160ustar00rootroot00000000000000// Check that it is possible to declare an enum type without an explicit base // type. In this case the base type should default to `int`. module test; enum { A } E; initial begin if ($bits(E) == 32) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_range.v000066400000000000000000000026531435245347300220510ustar00rootroot00000000000000module test; // Test declaring the enum as a 3-bit logic. enum reg [2:0] { rstate[8] } reg_enum; enum bit [2:0] { bstate[8] } bit_enum; enum logic [2:0] { lstate[8] } log_enum; initial begin if ($bits(reg_enum) != 3) begin $display("FAILED -- $bits(reg_enum) == %0d", $bits(reg_enum)); $finish; end if ($bits(bit_enum) != 3) begin $display("FAILED -- $bits(bit_enum) == %0d", $bits(bit_enum)); $finish; end if ($bits(log_enum) != 3) begin $display("FAILED -- $bits(log_enum) == %0d", $bits(log_enum)); $finish; end if ($bits(rstate0) != 3) begin $display("FAILED -- $bits(rstate0) == %0d", $bits(rstate0)); $finish; end if ($bits(bstate0) != 3) begin $display("FAILED -- $bits(bstate0) == %0d", $bits(bstate0)); $finish; end if ($bits(lstate0) != 3) begin $display("FAILED -- $bits(lstate0) == %0d", $bits(lstate0)); $finish; end if (rstate0 !== 3'b000 || bstate0 !== 3'b000 || lstate0 !== 3'b000) begin $display("FAILED -- rstate0 == %b", rstate0); $finish; end if (rstate4 !== 3'b100 || bstate4 !== 3'b100 || lstate4 !== 3'b100) begin $display("FAILED -- rstate4 == %b", rstate4); $finish; end if (rstate7 !== 3'b111 || bstate7 !== 3'b111 || lstate7 !== 3'b111) begin $display("FAILED -- rstate7 == %b", rstate7); $finish; end $display ("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/enum_base_scalar.v000066400000000000000000000005731435245347300222210ustar00rootroot00000000000000// Check that it is possible to declare an enum type with a scalar vector type // as the base type. module test; enum reg { A } e1; enum logic { B } e2; enum bit { C } e3; initial begin if ($bits(e1) == 1 && $bits(e2) == 1 && $bits(e3) == 1) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_time.v000066400000000000000000000004261435245347300217070ustar00rootroot00000000000000// Check that it is possible to declare an enum type with the time type as the // base type. module test; enum time { A } E; initial begin if ($bits(E) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_typename1.v000066400000000000000000000005321435245347300226520ustar00rootroot00000000000000// Check that it is possible to declare an enum type with a type identifier that // resolves to an integer type as the base type. module test; typedef integer T; enum T { A } E; initial begin if ($bits(E) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_base_typename2.v000066400000000000000000000005131435245347300226520ustar00rootroot00000000000000// Check that it is possible to declare an enum type with a type identifier plus // packed dimensions as the the base type. module test; typedef bit T; enum T [31:0] { A } E; initial begin if ($bits(E) == 32) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_compatibility1.v000066400000000000000000000005751435245347300227160ustar00rootroot00000000000000// Check that enum types declared in a higher level scope are compatible between // different instances of a module. typedef enum integer { A } T; module M; T e; endmodule module test; M m1(); M m2(); initial begin m1.e = A; m2.e = m1.e; if (m2.e === A) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_compatibility2.v000066400000000000000000000006721435245347300227150ustar00rootroot00000000000000// Check that enum types explicitly imported from a package are compatible // between different instances of a module. package P; typedef enum integer { A } T; endpackage module M; import P::T; T e; endmodule module test; import P::A; M m1(); M m2(); initial begin m1.e = A; m2.e = m1.e; if (m2.e === A) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_compatibility3.v000066400000000000000000000006721435245347300227160ustar00rootroot00000000000000// Check that enum types implicitly imported from a package are compatible // between different instances of a module. package P; typedef enum integer { A } T; endpackage module M; import P::*; T e; endmodule module test; import P::*; M m1(); M m2(); initial begin m1.e = A; m2.e = m1.e; if (m2.e === A) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_compatibility_fail.v000066400000000000000000000005001435245347300236140ustar00rootroot00000000000000// Check that enums declared within a module are not compatible between // different instances of a module module M; enum integer { A } e; endmodule module test; M m1(); M m2(); initial begin // These are different types and not compatible m1.e = m2.e; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_dims_invalid.v000066400000000000000000000007561435245347300224270ustar00rootroot00000000000000// Check that all sorts of enum dimension declarations are handled correctly and // do not cause an assert or segfault. module test; // These are invalid enum logic [$] { A } a; enum logic [] { B } b; enum logic [-1] { C } c; enum logic [0] { D } d; enum logic [1:0][3:0] { E } e; // These are valid enum logic [0:2] { F } f; enum logic [2:0] { G } g; enum logic [-1:-2] { H } h; // These are valid as an extension in iverilog enum logic [16] { I } i; int x; endmodule iverilog-12_0/ivtest/ivltests/enum_elem_ranges.v000066400000000000000000000073161435245347300222450ustar00rootroot00000000000000module test; parameter SIZE = 3; parameter PVALUE = 12; localparam LVALUE = 88; enum byte unsigned { UVAL[256] } unsignedbyte_enum; enum byte { SVAL[100] } signedbyte_enum; enum { ADD = 10, SUB[5], JMP[6:8]} E1; // page 28 LRM enum { REGISTER[2] = 1, REGISTER[2:4] = 10 } vr; // page 28 LRM enum { P[5] = 12 /*PVALUE*/, Q, S[3] = 88/*LVALUE*/} par_enum; initial begin // 1. Default anonymous enum data type should be int // don't know yet how to quickly check this // // 1. Checking initialisations // // a. If the first name is not assigned it should be zero if (UVAL0 !== 8'h0 || SVAL0 !== 8'h0) begin $display ("FAILED - First un-assigned element of enum type was not zero"); $finish; end // b. Checking initials E1 and vr if (ADD != 10 || REGISTER0 != 1) begin $display ("FAILED - First initialised elements of enums E1 and vr were not elaborated properly"); $finish; end // A name without a value is automatically assigned and increment of the value of the // previous name (Section 4.10 LRM) // c. checking initial values for SUB (0-4) in E1 if (SUB0 != 11 || SUB1 != 12 || SUB2 != 13 || SUB3 != 14 || SUB4 != 15) begin $display ("FAILED - Initialised elements SUB (0-4) in enum E1 were not elaborated properly"); $finish; end // c. checking initial values for JMP (6-8) in E1 if (JMP6 != 16 || JMP7 != 17 || JMP8 != 18) begin $display ("FAILED - Initialised elements (6-8) JMP in enum E1 were not elaborated properly"); $finish; end // c. checking initial values in vr if (REGISTER1 != 2 || REGISTER2 != 10 || REGISTER3 != 11 || REGISTER4 != 12) begin $display ("FAILED - Initialised elements REGISTER (1-4) in enum vr were not elaborated properly"); $finish; end // c. checking hand-picked values in unsignedbyte_enum if (UVAL23 != 23 || UVAL91 != 91 || UVAL138 != 138 || UVAL207 != 207) begin $display ("FAILED - Initialised some UVAL in enum unsignedbyte_enum were not elaborated properly"); $display ("UVAL23 = %0d, UVAL91 = %0d, UVAL138 = %0d, UVAL207 = %0d", UVAL23, UVAL91, UVAL138, UVAL207); $finish; end // c. checking hand-picked values in signedbyte_enum if (SVAL7 != 7 || SVAL19 != 19 || SVAL87 != 87) begin $display ("FAILED - Initialised some SVAL in enum signedbyte_enum were not elaborated properly"); $display ("SVAL7 = %0d, SVAL19 = %0d, SVAL87 = %0d", SVAL7, UVAL91, SVAL19, SVAL87); $finish; end // c. checking final values in unsignedbyte_enum and signedbyte_enum if (UVAL255 != 255 || SVAL99 != 99) begin $display ("FAILED - Initialised final values UVAL and SVAL did not elaborate properly"); $display ("UVAL255 = %0d, SVAL99 = %0d", UVAL255, SVAL99); $finish; end // constants elaborated from parameter if (P0 != PVALUE+0 || P1 != PVALUE+1 || P2 != PVALUE+2 || P3 != PVALUE+3 || P4 != PVALUE + 4 || Q != PVALUE+5) begin $display ("FAILED - Initialised values P in par_enum were not elaborated properly"); $finish; end // constants elaborated from localparam if (S0 != LVALUE+0 || S1 != LVALUE+1 || S2 != LVALUE+2) begin $display ("FAILED - Initialised values S in par_enum were not elaborated properly"); $finish; end #1; // checking num method if (unsignedbyte_enum.num != 256 || signedbyte_enum.num != 100 || E1.num != 9 || vr.num != 5 || par_enum.num != 9) begin $display ("FAILED - The num method does not report as expected"); $finish; end $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_in_class.v000066400000000000000000000016321435245347300215520ustar00rootroot00000000000000// Check that when a enum type is declared inside a class that the enum is // properly installed in the scope and the enum items are available. // // Also check that when using a typedef of a enum inside a class that the enum // is not elaborated inside the class and it is possible to have a enum with the // same names inside the class scope. module test; typedef enum integer { A = 1 } e1_t; class C; typedef enum integer { A = 10 } e2_t; e1_t e1; e2_t e2; function new(); e1 = test.A; e2 = A; endfunction function void set(e2_t new_e2); e2 = new_e2; endfunction endclass C c; initial begin c = new; c.e1 = A; c.set(c.e2); // Not yet supported // c.e2 = C::A; c.e2 = c.A; // Check that they have the numerical value from the right scope if (c.e1 == 1 && c.e2 == 10) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_in_class_name_coll.v000066400000000000000000000003411435245347300235570ustar00rootroot00000000000000// Check that the enum names are added to the lexor scope of the class and // name collisions with other symbols are reported as errors. module test; class C; enum { A = 10 } e; typedef int A; endclass endmodule iverilog-12_0/ivtest/ivltests/enum_in_struct.v000066400000000000000000000005301435245347300217650ustar00rootroot00000000000000// Check that when a enum type is declared inside a struct that the enum is // properly installed in the scope and the enum items are available module test; struct packed { enum integer { A } e; } s; initial begin s.e = A; if (s.e == A) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_line_info.v000066400000000000000000000007341435245347300217230ustar00rootroot00000000000000// Checks that the line and file information is correctly attached to a enum // data type and will be used when printing an error message about the enum. module test; // Direct enum logic { A, B = A } e1; // Used in a struct typedef enum logic { C, D = C } enum1_type; // Used as a signal type typedef enum logic { E, F = E } enum2_type; // Unreferenced typedef enum logic { G, H = G } enum3_type; struct packed { enum1_type e; } s; enum2_type e2; endmodule iverilog-12_0/ivtest/ivltests/enum_method_signed1.v000066400000000000000000000061251435245347300226530ustar00rootroot00000000000000// Check that the signedness of methods on the built-in enum type is handled // correctly when calling the method with parenthesis. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end int unsigned x = 10; int y = 10; int z; enum shortint { A = -1, B = -2, C = -3 } es; enum bit [15:0] { X = 65535, Y = 65534, Z = 65533 } eu; initial begin es = B; eu = Y; // These all evaluate as signed `check($signed(eu.first()) < 0) `check(es.first() < 0) `check($signed(eu.last()) < 0) `check(es.last() < 0) `check($signed(eu.prev()) < 0) `check(es.prev() < 0) `check($signed(eu.next()) < 0) `check(es.next() < 0) // These all evaluate as unsigned `check(eu.first() > 0) `check({es.first()} > 0) `check($unsigned(es.first()) > 0) `check(es.first() > 16'h0) `check(eu.last() > 0) `check({es.last()} > 0) `check($unsigned(es.last()) > 0) `check(es.last() > 16'h0) `check(eu.prev() > 0) `check({es.prev()} > 0) `check($unsigned(es.prev()) > 0) `check(es.prev() > 16'h0) `check(eu.next() > 0) `check({es.next()} > 0) `check($unsigned(es.next()) > 0) `check(es.next() > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = eu.first() + x; `check(z === 65545) z = eu.first() + y; `check(z === 65545) z = eu.last() + x; `check(z === 65543) z = eu.last() + y; `check(z === 65543) z = eu.prev() + x; `check(z === 65545) z = eu.prev() + y; `check(z === 65545) z = eu.next() + x; `check(z === 65543) z = eu.next() + y; `check(z === 65543) z = es.first() + x; `check(z === 65545) z = es.first() + y; `check(z === 9) z = es.last() + x; `check(z === 65543) z = es.last() + y; `check(z === 7) z = es.prev() + x; `check(z === 65545) z = es.prev() + y; `check(z === 9) z = es.next() + x; `check(z === 65543) z = es.next() + y; `check(z === 7) // For ternary operators if one operand is unsigned the result is unsigend z = x ? eu.first() : x; `check(z === 65535) z = x ? eu.first() : y; `check(z === 65535) z = x ? eu.last() : x; `check(z === 65533) z = x ? eu.last() : y; `check(z === 65533) z = x ? eu.prev() : x; `check(z === 65535) z = x ? eu.prev() : y; `check(z === 65535) z = x ? eu.next() : x; `check(z === 65533) z = x ? eu.next() : y; `check(z === 65533) z = x ? es.first() : x; `check(z === 65535) z = x ? es.first() : y; `check(z === -1) z = x ? es.last() : x; `check(z === 65533) z = x ? es.last() : y; `check(z === -3) z = x ? es.prev() : x; `check(z === 65535) z = x ? es.prev() : y; `check(z === -1) z = x ? es.next() : x; `check(z === 65533) z = x ? es.next() : y; `check(z === -3) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_method_signed2.v000066400000000000000000000013271435245347300226530ustar00rootroot00000000000000// Check that the signedness of methods on the built-in enum type is handled // correctly when calling the function with parenthesis and passing the result // to a system function. module test; enum shortint { A = -1, B = -2, C = -3 } es; enum bit [15:0] { X = 65535, Y = 65534, Z = 65533 } eu; string s; initial begin es = B; eu = Y; s = $sformatf("%0d %0d %0d %0d %0d %0d %0d %0d", es.first(), es.last(), es.prev(), es.next(), eu.first(), eu.last(), eu.prev(), eu.next()); if (s == "-1 -3 -1 -3 65535 65533 65535 65533") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/enum_method_signed3.v000066400000000000000000000057501435245347300226600ustar00rootroot00000000000000// Check that the signedness of methods on the built-in enum type is handled // correctly when calling the method without parenthesis. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end int unsigned x = 10; int y = 10; int z; enum shortint { A = -1, B = -2, C = -3 } es; enum bit [15:0] { X = 65535, Y = 65534, Z = 65533 } eu; initial begin es = B; eu = Y; // These all evaluate as signed `check($signed(eu.first) < 0) `check(es.first < 0) `check($signed(eu.last) < 0) `check(es.last < 0) `check($signed(eu.prev) < 0) `check(es.prev < 0) `check($signed(eu.next) < 0) `check(es.next < 0) // These all evaluate as unsigned `check(eu.first > 0) `check({es.first} > 0) `check($unsigned(es.first) > 0) `check(es.first > 16'h0) `check(eu.last > 0) `check({es.last} > 0) `check($unsigned(es.last) > 0) `check(es.last > 16'h0) `check(eu.prev > 0) `check({es.prev} > 0) `check($unsigned(es.prev) > 0) `check(es.prev > 16'h0) `check(eu.next > 0) `check({es.next} > 0) `check($unsigned(es.next) > 0) `check(es.next > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = eu.first + x; `check(z === 65545) z = eu.first + y; `check(z === 65545) z = eu.last + x; `check(z === 65543) z = eu.last + y; `check(z === 65543) z = eu.prev + x; `check(z === 65545) z = eu.prev + y; `check(z === 65545) z = eu.next + x; `check(z === 65543) z = eu.next + y; `check(z === 65543) z = es.first + x; `check(z === 65545) z = es.first + y; `check(z === 9) z = es.last + x; `check(z === 65543) z = es.last + y; `check(z === 7) z = es.prev + x; `check(z === 65545) z = es.prev + y; `check(z === 9) z = es.next + x; `check(z === 65543) z = es.next + y; `check(z === 7) // For ternary operators if one operand is unsigned the result is unsigend z = x ? eu.first : x; `check(z === 65535) z = x ? eu.first : y; `check(z === 65535) z = x ? eu.last : x; `check(z === 65533) z = x ? eu.last : y; `check(z === 65533) z = x ? eu.prev : x; `check(z === 65535) z = x ? eu.prev : y; `check(z === 65535) z = x ? eu.next : x; `check(z === 65533) z = x ? eu.next : y; `check(z === 65533) z = x ? es.first : x; `check(z === 65535) z = x ? es.first : y; `check(z === -1) z = x ? es.last : x; `check(z === 65533) z = x ? es.last : y; `check(z === -3) z = x ? es.prev : x; `check(z === 65535) z = x ? es.prev : y; `check(z === -1) z = x ? es.next : x; `check(z === 65533) z = x ? es.next : y; `check(z === -3) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_method_signed4.v000066400000000000000000000013121435245347300226470ustar00rootroot00000000000000// Check that the signedness of methods on the built-in enum type is handled // correctly when calling the function without parenthesis and passing the // result to a system function. module test; enum shortint { A = -1, B = -2, C = -3 } es; enum bit [15:0] { X = 65535, Y = 65534, Z = 65533 } eu; string s; initial begin es = B; eu = Y; s = $sformatf("%0d %0d %0d %0d %0d %0d %0d %0d", es.first, es.last, es.prev, es.next, eu.first, eu.last, eu.prev, eu.next); if (s == "-1 -3 -1 -3 65535 65533 65535 65533") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/enum_next.v000066400000000000000000000022711435245347300207350ustar00rootroot00000000000000/* * This program tests that enumeration value first/last/next * methods work properly. The .next method requires some run-time * support for enumeration. */ module main; enum { RED, GREEN = 2, BLUE } color1; initial begin color1 = RED; $display("color1.first == %0d", color1.first); $display("color1.last == %0d", color1.last); $display("color1.num == %0d", color1.num); $display("color1.next == %0d", color1.next); color1 = color1.next; if (color1 != GREEN || color1 !== 2) begin $display("FAILED -- should be %0d, got %0d", GREEN, color1); $finish; end color1 = color1.next; if (color1 != BLUE || color1 !== 3 || color1 != color1.last) begin $display("FAILED -- should be %0d, got %0d", BLUE, color1); $finish; end color1 = color1.prev; if (color1 != GREEN || color1 !== 2) begin $display("FAILED -- should be %0d, got %0d", GREEN, color1); $finish; end color1 = color1.prev; if (color1 != RED || color1 !== 0 || color1 != color1.first) begin $display("FAILED -- should be %0d, got %0d", RED, color1); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/enum_order.v000066400000000000000000000004531435245347300210720ustar00rootroot00000000000000// Verify that enums can reference items from enums declared before them module test; enum logic { A = 1 } a; enum logic { B = A } b; enum logic { C = B } c; initial begin if (A == B && A == C) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/enum_ports.v000066400000000000000000000032601435245347300211250ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests enum as a port type. typedef enum integer { var_presence, var_identif, var_1, var_2, var_3, var_rst, var_4, var_5, var_whatever } t_var; module enum_ports(input wire t_var var_i, output t_var var_o, output reg is_var_rst); initial begin var_o = var_presence; end always @(var_i) begin if(var_i == var_rst) is_var_rst = 1'b1; else is_var_rst = 1'b0; end endmodule module test_unit(); t_var var_in, var_out; reg result; enum_ports dut(var_in, var_out, result); initial begin #1; if(var_out !== var_presence) begin $display("FAILED 1"); $finish(); end var_in = var_1; #1; if(result !== 1'b0) begin $display("FAILED 2"); $finish(); end var_in = var_rst; #1 if(result !== 1'b1) begin $display("FAILED 3"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_test1.v000066400000000000000000000174621435245347300210270ustar00rootroot00000000000000module test; parameter PVALUE = 12; localparam LVALUE = 88; enum byte unsigned { UVAL[256] } unsignedbyte_enum; enum byte { SVAL[100] } signedbyte_enum; enum { ADD = 10, SUB[5], JMP[6:8]} E1; // page 28 LRM enum { REGISTER[2] = 1, REGISTER[2:4] = 10 } vr; // page 28 LRM enum { P[5] = PVALUE, Q, S[3] = LVALUE} par_enum; enum reg [2:0] { state[8] } bin_enum; enum integer {IDLE, XX='bx, XY='b01, YY='b10, XZ = 32'h1x2z3xxz} next_state; int i; initial begin // 1. Default anonymous enum data type should be int // don't know yet how to quickly check this // // 1. Checking initialisations // // a. If the first name is not assigned it should be zero if (UVAL0 !== 8'h0 || SVAL0 !== 8'h0) begin $display ("FAILED - First un-assigned element of enum type was not zero"); $finish; end // b. Checking initials E1 and vr if (ADD != 10 || REGISTER0 != 1) begin $display ("FAILED - First initialised elements of enums E1 and vr were not elaborated properly"); $finish; end // A name without a value is automatically assigned and increment of the value of the // previous name (Section 4.10 LRM) // c. checking initial values for SUB (0-4) in E1 if (SUB0 != 11 || SUB1 != 12 || SUB2 != 13 || SUB3 != 14 || SUB4 != 15) begin $display ("FAILED - Initialised elements SUB (0-4) in enum E1 were not elaborated properly"); $finish; end // c. checking initial values for JMP (6-8) in E1 if (JMP6 != 16 || JMP7 != 17 || JMP8 != 18) begin $display ("FAILED - Initialised elements (6-8) JMP in enum E1 were not elaborated properly"); $finish; end // c. checking initial values in vr if (REGISTER1 != 2 || REGISTER2 != 10 || REGISTER3 != 11 || REGISTER4 != 12) begin $display ("FAILED - Initialised elements REGISTER (1-4) in enum vr were not elaborated properly"); $finish; end // c. checking hand-picked values in unsignedbyte_enum if (UVAL23 != 23 || UVAL91 != 91 || UVAL138 != 138 || UVAL207 != 207) begin $display ("FAILED - Initialised some UVAL in enum unsignedbyte_enum were not elaborated properly"); $display ("UVAL23 = %0d, UVAL91 = %0d, UVAL138 = %0d, UVAL207 = %0d", UVAL23, UVAL91, UVAL138, UVAL207); $finish; end // c. checking hand-picked values in signedbyte_enum if (SVAL7 != 7 || SVAL19 != 19 || SVAL87 != 87) begin $display ("FAILED - Initialised some SVAL in enum signedbyte_enum were not elaborated properly"); $display ("SVAL7 = %0d, SVAL19 = %0d, SVAL87 = %0d", SVAL7, UVAL91, SVAL19, SVAL87); $finish; end // c. checking final values in unsignedbyte_enum and signedbyte_enum if (UVAL255 != 255 || SVAL99 != 99) begin $display ("FAILED - Initialised final values UVAL and SVAL did not elaborate properly"); $display ("UVAL255 = %0d, SVAL99 = %0d", UVAL255, SVAL99); $finish; end // d. checking xz values in next_state if (XX !== 'bx || XZ !== 32'h1x2z3xxz) begin $display ("FAILED - Initialised x,z values in next_state did not elaborate properly"); $finish; end // e. constants elaborated from parameter if (P0 != PVALUE+0 || P1 != PVALUE+1 || P2 != PVALUE+2 || P3 != PVALUE+3 || P4 != PVALUE + 4 || Q != PVALUE+5) begin $display ("FAILED - Initialised values P in par_enum were not elaborated properly"); $finish; end // f. constants elaborated from localparam if (S0 != LVALUE+0 || S1 != LVALUE+1 || S2 != LVALUE+2) begin $display ("FAILED - Initialised values S in par_enum were not elaborated properly"); $finish; end #1; // g. checking num method if (unsignedbyte_enum.num != 256 || signedbyte_enum.num != 100 || E1.num != 9 || vr.num != 5 || par_enum.num != 9 ) begin $display ("FAILED - The num method does not report as expected"); $finish; end // h. checking first method if (unsignedbyte_enum.first != 0 || signedbyte_enum.first != 0 || E1.first != 10 || vr.first != 1 || par_enum.first != PVALUE ) begin $display ("FAILED - The first method does not report as expected"); $finish; end // i. checking last method if (unsignedbyte_enum.last != 255 || signedbyte_enum.last != 99 || E1.last != 18 || vr.last != 12 || par_enum.last != LVALUE+2 ) begin $display ("FAILED - The last method does not report as expected"); $finish; end // checking the next method on unsignedbyte_enum unsignedbyte_enum = unsignedbyte_enum.first; for (i=1; i<=255; i=i+1) begin unsignedbyte_enum = unsignedbyte_enum.next; if (unsignedbyte_enum != i) begin $display ("FAILED - The next method does not report as expected for unsignedbyte_enum"); $finish; end end unsignedbyte_enum = unsignedbyte_enum.next; // checking wrap to the first element for signedbyte_enum if (unsignedbyte_enum != unsignedbyte_enum.first) begin $display ("FAILED - The next method did not wrap to the first element for unsignedbyte_enum"); $finish; end // checking the next method on signedbyte_enum signedbyte_enum = signedbyte_enum.first; for (i=1; i<100; i=i+1) begin signedbyte_enum = signedbyte_enum.next; if (signedbyte_enum != i) begin $display ("FAILED - The next method does not report as expected for signedbyte_enum"); $finish; end end signedbyte_enum = signedbyte_enum.next; // checking wrap to the first element for signedbyte_enum if (signedbyte_enum != signedbyte_enum.first) begin $display ("FAILED - The next method did not wrap to the first element for signedbyte_enum"); $finish; end // checking the next method on E1 E1 = E1.first; for (i=E1.first; i<= E1.last; i=i+1) begin if (E1 != i) begin $display ("FAILED - The next method does not report as expected for E1"); $finish; end E1 = E1.next; end // checking wrap to the first element in E1 if (E1 != E1.first) begin $display ("FAILED - The next method did not wrap to the first element for E1"); $finish; end // checking the next method on vr, manual walk vr = vr.first; vr = vr.next; if (vr != 2) begin $display ("FAILED - The next method does not report as expected for vr in element REGISTER1"); $finish; end vr = vr.next; if (vr != 10) begin $display ("FAILED - The next method does not report as expected for vr in element REGISTER2"); $finish; end vr = vr.next; if (vr != 11) begin $display ("FAILED - The next method does not report as expected for vr in element REGISTER3"); $finish; end vr = vr.next; if (vr != 12) begin $display ("FAILED - The next method does not report as expected for vr in element REGISTER4"); $finish; end // checking wrap to the first element in vr vr = vr.next; if (vr != vr.first) begin $display ("FAILED - The next method did not wrap to the first element for vr"); $finish; end // checking the next method for bin_enum bin_enum = bin_enum.first; for (i=bin_enum.first; i<= bin_enum.last; i = i+1) begin if (bin_enum != i) begin $display ("FAILED - The next method does not report as expected for bin_enum"); $finish; end bin_enum = bin_enum.next; end // checking wrap to the first element in bin_enum if (bin_enum != bin_enum.first) begin $display ("FAILED - The next method did not wrap to the first element for bin_enum"); $finish; end $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_test2.v000066400000000000000000000002721435245347300210170ustar00rootroot00000000000000module top; // This will compile. enum integer {IDLE, UNKNOWN='bx} en1; // This is failing to compile. enum integer {VAL, XX=32'bx} en2; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test3.v000066400000000000000000000005001435245347300210120ustar00rootroot00000000000000module top; // This should be okay (the trimmed bits match the enum MSB). enum reg[3:0] {VAL1, XX1='bxxxxx} en1; // But these should fail because the trimmed bits do not match the enum MSB. enum reg[3:0] {VAL2, XX2='b0xxxx} en2; enum reg[3:0] {VAL3, XX3='b0xxxxx} en3; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test4.v000066400000000000000000000001741435245347300210220ustar00rootroot00000000000000module top; enum bit [3:0] {first, second, third, fourth, last = -4'sd1} my_type; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test5.v000066400000000000000000000004311435245347300210170ustar00rootroot00000000000000module top; // This should be okay because the size matches. enum reg[3:0] {VAL1, XX1=4'bxxxx} en1; // But these should fail because the size is wrong. enum reg[3:0] {VAL2, XX2=3'bxxx} en2; enum reg[3:0] {VAL3, XX3=5'bxxxxx} en3; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test6.v000066400000000000000000000002201435245347300210140ustar00rootroot00000000000000module top; // This should fail because XX4 is not given a constant. enum {VAL4, XX4 = $time} en4; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test7.v000066400000000000000000000002371435245347300210250ustar00rootroot00000000000000module top; // This should fail because XX5 is given an undefined constant (2-state). enum {VAL5, XX5 = 'bx} en5; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/enum_test8.v000066400000000000000000000003731435245347300210270ustar00rootroot00000000000000module top; localparam enum_start = 2'd1; // This is an expression so the value just has to fit. enum logic [3:0] { first = enum_start + 2'd0, second = enum_start + 2'd1} my_enum; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/enum_value_expr.v000066400000000000000000000015221435245347300221270ustar00rootroot00000000000000module test; parameter PVALUE = 12; localparam LVALUE = 88; enum { P[5] = PVALUE, Q, S[3] = LVALUE } par_enum; initial begin // constants elaborated from parameter if (P0 != PVALUE+0 || P1 != PVALUE+1 || P2 != PVALUE+2 || P3 != PVALUE+3 || P4 != PVALUE + 4 || Q != PVALUE+5) begin $display ("FAILED - Initialised values P in par_enum were not elaborated properly"); $finish; end // constants elaborated from localparam if (S0 != LVALUE+0 || S1 != LVALUE+1 || S2 != LVALUE+2) begin $display ("FAILED - Initialised values S in par_enum were not elaborated properly"); $finish; end #1; // checking num method if ( par_enum.num != 9) begin $display ("FAILED - The num method does not report as expected"); $finish; end $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/enum_values.v000066400000000000000000000014211435245347300212520ustar00rootroot00000000000000/* * This program tests that enumeration values work and are * implicitly translated to integer values. */ module main; enum { RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, BLACK = 10, WHITE = 'd11 } color1; int var1; initial begin color1 = RED; var1 = RED; $display("color1 = %0d, var1 = %0d", color1, var1); if (color1 !== 0) begin $display("FAILED"); $finish; end if (var1 !== 0) begin $display("FAILED"); $finish; end color1 = GREEN; var1 = GREEN; $display("color1 = %0d, var1 = %0d", color1, var1); if (color1 !== 3) begin $display("FAILED"); $finish; end if (var1 !== 3) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/enumsystem.vhd000066400000000000000000000042051435245347300214570ustar00rootroot00000000000000------------------------------------------------------------------------------ -- Author: Oswaldo Cadenas -- Date: September 27 2011 -- -- Summary: This system runs an internal counter 0,1,2, ..., 7, 0, 1, -- and also accepts an enable signal -- it generates an output y (4 bits) as: -- if (e = 0) y = 0000 -- if (e = 1) then -- y = 1000 when counter is 0 -- y = 0100 when counter is 1 -- y = 0010 when counter is 2 -- y = 0001 when counter is 3 -- y = 1111 other count -- internaly the design uses some enumartion arguments for decoding and encoding --------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity enumsystem is port (clk, reset: in std_logic; en: in std_logic; -- enable y: out std_logic_vector (0 to 3) ); -- decoded output end enumsystem; architecture enumsystem_rtl of enumsystem is type States is (zero, one, two, three, other); signal mystate: States; signal Counter: std_logic_vector (2 downto 0); begin SmallCounter : process (clk, reset) begin if ( clk'event and clk = '1') then if (reset = '1') then Counter <= (others => '0'); else Counter <= Counter + 1; end if; end if; end process; encoding_process: process (Counter) begin case Counter is when "000" => mystate <= zero; when "001" => mystate <= one; when "010" => mystate <= two; when "011" => mystate <= three; when others => mystate <= other; end case; end process; decoding_process: process (mystate, en) begin if (en = '1') then case mystate is when zero => y <= "1000"; when one => y <= "0100"; when two => y <= "0010"; when three => y <= "0001"; when others => y <= "1111"; end case; else y <= "0000"; end if; end process; end enumsystem_rtl; iverilog-12_0/ivtest/ivltests/eofmt_percent.v000066400000000000000000000001311435245347300215560ustar00rootroot00000000000000module top; initial $display("The following should be a single percent: %"); endmodule iverilog-12_0/ivtest/ivltests/eq.v000066400000000000000000000013111435245347300173320ustar00rootroot00000000000000// Trigger breakage of Icarus Verilog CVS 2004-06-18 // $ iverilog netnet.v // netnet.v:7: internal error: pin(3) out of bounds(3) // netnet.v:7: : typeid=6NetNet // ivl: netlist.cc:208: Link &NetObj::pin (unsigned int): Assertion `idx < npins_' failed. // $ // Larry Doolittle `timescale 1ns / 1ns module netnet(); reg [2:0] s; wire s_ones; assign s_ones = (s==7); initial begin s = 3'b111; #1 if (s_ones !== 1) begin $display("FAILED -- %b==7 returns %b", s, s_ones); $finish; end s = 3'b011; #1 if (s_ones !== 0) begin $display("FAILED -- %b==7 returns %b", s, s_ones); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/escape1.v000066400000000000000000000032401435245347300202510ustar00rootroot00000000000000// // Copyright (c) 2001 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Tests defparam \$ in module name and if() module test (); parameter init = 16'h1234; reg [15:0] rcv; initial begin #10; rcv = init ; $display("Init value is %h",rcv); end endmodule module \$I178 (); defparam \$I178 .a.init = 16'h0040; defparam \$I178 .b.init = 16'h0041; defparam \$I178 .c.init = 16'h0042; test a (); test b (); test c (); reg error; initial begin error = 0; #20; if(\$I178 .a.rcv !== 16'h0040) begin $display("FAILED"); error = 1; end if(\$I178 .b.rcv !== 16'h0041) begin $display("FAILED"); error = 1; end if(\$I178 .c.rcv !== 16'h0042) begin $display("FAILED"); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/escape2a.v000066400000000000000000000007351435245347300204210ustar00rootroot00000000000000module part1 ( \6A_A , \6Y_A , VCC , GND , \6A_B , \6Y_B , \6A_C , \6Y_C , \6A_D , \6Y_D , \6A_E , // note: there is not a space character before the nl below \6Y_E ) ; input \6A_A ; output \6Y_A ; input VCC ; input GND ; input \6A_B ; output \6Y_B ; input \6A_C ; output \6Y_C ; input \6A_D ; output \6Y_D ; input \6A_E ; output \6Y_E ; assign \6Y_A = ~\6A_A ; assign \6Y_B = ~\6A_B ; assign \6Y_C = ~\6A_C ; assign \6Y_D = ~\6A_D ; assign \6Y_E = ~\6A_E ; endmodule iverilog-12_0/ivtest/ivltests/escape2b.v000066400000000000000000000010001435245347300204040ustar00rootroot00000000000000module part2 ( \6A_A , \6Y_A , VCC , GND , \6A_B , \6Y_B , \6A_C , \6Y_C , \6A_D , \6Y_D , \6A_E , // note: there is not a space character before the nl below // no space character after nl also \6Y_E ) ; input \6A_A ; output \6Y_A ; input VCC ; input GND ; input \6A_B ; output \6Y_B ; input \6A_C ; output \6Y_C ; input \6A_D ; output \6Y_D ; input \6A_E ; output \6Y_E ; assign \6Y_A = ~\6A_A ; assign \6Y_B = ~\6A_B ; assign \6Y_C = ~\6A_C ; assign \6Y_D = ~\6A_D ; assign \6Y_E = ~\6A_E ; endmodule iverilog-12_0/ivtest/ivltests/escape2c.v000066400000000000000000000007101435245347300204140ustar00rootroot00000000000000module part3 ( \6A_A , \6Y_A , VCC , GND , \6A_B , \6Y_B , \6A_C , \6Y_C , \6A_D , \6Y_D , \6A_E , // note: with space before the nl below \6Y_E ) ; input \6A_A ; output \6Y_A ; input VCC ; input GND ; input \6A_B ; output \6Y_B ; input \6A_C ; output \6Y_C ; input \6A_D ; output \6Y_D ; input \6A_E ; output \6Y_E ; assign \6Y_A = ~\6A_A ; assign \6Y_B = ~\6A_B ; assign \6Y_C = ~\6A_C ; assign \6Y_D = ~\6A_D ; assign \6Y_E = ~\6A_E ; endmodule iverilog-12_0/ivtest/ivltests/escape3.v000066400000000000000000000031611435245347300202550ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This tests the rule in section 2.7.1: * "Neither the leading backslash character nor the terminating * white space is considered to be part of the identifier. There- * fore, an escaped identifier \cpu3 is treated the same as a * non escaped identifier cpu3." * * The cpu3 and \cpu3 notations are for the same object. */ module top; reg \cpu3 ; initial begin cpu3 = 1; $display("cpu3 == %b", \cpu3 ); if (top.\cpu3 !== cpu3) begin $display("FAILED -- top.\\cpu3 !== cpu3"); $finish; end if (\top .cpu3 !== \cpu3 ) begin $display("FAILED -- \\top .cpu3 !== cpu3"); $finish; end if (top.\cpu3 !== 1) begin $display("FAILED -- top.\\cpu3 !== 1"); $finish; end $display("PASSED"); end endmodule // top iverilog-12_0/ivtest/ivltests/escape4.v000066400000000000000000000024551435245347300202630ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff @chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module top; reg \bot.r ; bot bot(); initial begin #1; \bot.r = 1; #1; $display("\\bot.r == %b", \bot.r ); $display("bot.r == %b", bot.r ); if (\bot.r !== 1) begin $display("FAILED -- \\bot.r !== 1"); $finish; end if (bot.r !== 0) begin $display("FAILED -- bot.r !== 0"); $finish; end $display("PASSED"); end endmodule // top module bot; reg r; initial begin r = 0; end endmodule iverilog-12_0/ivtest/ivltests/escape4b.v000066400000000000000000000025751435245347300204300ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff @chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module top; reg [1:0] \bot.m [1:0]; bot bot(); initial begin #1; \bot.m [0] = 2'b11; #1; $display("\\bot.m [0] == %b", \bot.m [0]); $display("bot.m[0] == %b", bot.m[0] ); if (\bot.m [0] !== 2'b11) begin $display("FAILED -- \\bot.m [0] !== 2'b11"); $finish; end if (bot.m[0] !== 2'b00) begin $display("FAILED -- bot.m[0] !== 2'b00"); $finish; end $display("PASSED"); end endmodule // top module bot; reg [1:0] m[1:0]; initial begin m[0] = 2'b00; end endmodule iverilog-12_0/ivtest/ivltests/escaped_macro_name.v000066400000000000000000000007111435245347300225150ustar00rootroot00000000000000`define simple "simple name" `define \escaped "escaped name" `define \`name "backtick name" `define \` "backtick" `define \quote (x) `"`\`"x`\`"`" `define \`\`" "escaped quote" module test(); initial begin $display(`simple); $display(`\simple ); $display(`escaped); $display(`\escaped ); $display(`\`name ); $display(`\` ); $display(`quote(text)); $display(`\quote (text)); $display(`\`\`" ); end endmodule iverilog-12_0/ivtest/ivltests/event2.v000066400000000000000000000020311435245347300201300ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This checks that event name scope is searched properly. */ module a; event FOO; task b; ->FOO; endtask // b initial @FOO $display("PASSED"); initial #1 b; endmodule // a iverilog-12_0/ivtest/ivltests/event3.15.v000066400000000000000000000034461435245347300203700ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Event list_of_event_identifiers, -> event_identifier. // module main (); reg [31:0] v1,v2,v3; reg error; event event_1, event_2; always @ event_1 begin v1 = v1 + 1; end always @ event_2 begin v2 = 1; end initial begin error = 0; v1 = 0; v2 = 0; v3 = 0; // $dumpfile("test.vcd"); // $dumpvars(0,main); #(5); -> event_1; v3 = 1; #1 ; // Need delay here or race with always schedule if(v1 !== 1) begin $display("FAILED - event3.15 event1 trigger didn't occur"); error = 1; end #5 -> event_2; #1 ; if(v2 !== 1) begin $display("FAILED - event3.15 event2 trigger didn't occur"); error = 1; end v3 = 2; #5 -> event_1; #1 ; if(v1 !== 2) begin $display("FAILED - event3.15 event1 trigger didn't occur"); error = 1; end v3 = 3; #5 ; if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/event3.v000066400000000000000000000010741435245347300201370ustar00rootroot00000000000000module et1; reg [31:0] a; reg [31:0] b; wire [31:0] x; reg [31:0] y; event e1; initial begin // $dumpvars; $monitor ("T=", $time, ", a=", a, ", b=", b, ", x=", x, ", y=", y); #200 $finish(0); end initial begin a = 10; b = 20; #10 a = 30; #10 b = 40; #10 a = 50; -> et1.m1.e2; #10 b = 60; -> et1.m1.e2; #10 a = 70; -> et1.m1.e2; b = 80; #10 a = 90; end always @e1 begin y <= b; end m m1 (a,x); endmodule module m (a,x); input [31:0] a; output [31:0] x; reg [31:0] x; event e2; always @e2 begin #1 x <= a; #2 -> et1.e1; end endmodule iverilog-12_0/ivtest/ivltests/event_array.v000066400000000000000000000014011435245347300212440ustar00rootroot00000000000000module event_array_test(); event my_event[3:0]; integer event_count[3:0]; generate genvar i; for (i = 0; i < 4; i = i + 1) begin always @(my_event[i]) begin $display("Got event %d", i); event_count[i] = event_count[i] + 1; end end endgenerate initial begin event_count[0] = 0; event_count[1] = 0; event_count[2] = 0; event_count[3] = 0; #1 ->my_event[0]; #1 ->my_event[1]; #1 ->my_event[2]; #1 ->my_event[3]; #1 ->my_event[1]; #1 ->my_event[2]; #1 ->my_event[3]; #1 ->my_event[2]; #1 ->my_event[3]; #1 ->my_event[3]; #1; if ((event_count[0] === 1) && (event_count[1] === 2) && (event_count[2] === 3) && (event_count[3] === 4)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/event_list.v000066400000000000000000000036411435245347300211110ustar00rootroot00000000000000// // Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Check support for event lists with named events. // module main (); reg flag1, flag2, flag12; event event_1, event_2; always @ event_1 flag1 = ~flag1; always @ event_2 flag2 = ~flag2; always @(event_1 or event_2) flag12 = ~flag12; initial begin flag1 = 0; flag2 = 0; flag12 = 0; #1 -> event_1; #1 if (flag1 !== 1) begin $display("FAILED -- event_1 didn't trigger flag1"); $finish; end if (flag2 !== 0) begin $display("FAILED -- event_1 DID trigger flag2"); $finish; end if (flag12 !== 1) begin $display("FAILED -- event_1 didn't trigger flag12"); $finish; end flag1 = 0; flag2 = 0; flag12 = 0; #1 -> event_2; #1 if (flag1 !== 0) begin $display("FAILED -- event_2 DID trigger flag1"); $finish; end if (flag2 !== 1) begin $display("FAILED -- event_2 didn't trigger flag2"); $finish; end if (flag12 !== 1) begin $display("FAILED -- event_1 didn't trigger flag12"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/event_list2.v000066400000000000000000000040301435245347300211640ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program combines two events with an event or. The tricky part * for the vvp target is that there is a mix of posedge and negedge * events. */ module ndFF ( nset, reset, Q ); input nset; // clk negedge set Q=1 input reset; // reset posedge set Q=0 output Q ; // Q output reg Q ; always @(negedge nset or posedge reset) begin if (nset ==1'b0) Q = 1'b1; else if (reset==1'b1) Q = 1'b0; end endmodule module main; reg nset, reset; wire Q; ndFF dut(nset, reset, Q); initial begin #0 nset = 1; reset = 1; #1 nset = 0; #1 if (Q !== 1'b1) begin $display("FAILED (a) nset=%b, reset=%b, Q=%b", nset, reset, Q); $finish; end nset = 1; #1 if (Q !== 1'b1) begin $display("FAILED (b) nset=%b, reset=%b, Q=%b", nset, reset, Q); $finish; end reset = 0; #1 if (Q !== 1'b1) begin $display("FAILED (c) nset=%b, reset=%b, Q=%b", nset, reset, Q); $finish; end reset = 1; #1 if (Q !== 1'b0) begin $display("FAILED (d) nset=%b, reset=%b, Q=%b", nset, reset, Q); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/event_list3.v000066400000000000000000000023401435245347300211670ustar00rootroot00000000000000/* * Copyright (c) 2001 Juergen Urban * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module sensitivity_list (); parameter ii = 4; reg CLK; reg A; reg [ii-1:0] B,C; initial begin #30; C <= {ii{1'b0}}; #60; $finish(0); end always begin CLK = 1'b0; #10; CLK = 1'b1; #10; $display ($time); end always @(A or C) begin A = 1'b0; $display ("combinatorial process ", A, " time:",$time); A = 1'b1; $display ("combinatorial process ", A, " time:",$time); B = A+C; end endmodule iverilog-12_0/ivtest/ivltests/extend.v000066400000000000000000000061751435245347300202310ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test tests simple zero-extend of small r-values into large * l-values. * * Correction and extensions by EML; 2007-11-15 */ module main; reg [3:0] y; reg signed xs; reg x; reg fail; initial begin fail = 0; x = 1'b0; y = x; if (y !== 4'b0000) begin $display("FAILED 1 -- x=%b, y=%b", x, y); fail = 1; end x = 1'b1; y = x; if (y !== 4'b0001) begin $display("FAILED 2 -- x=%b, y=%b", x, y); fail = 1; end // x is a 1-bit unsigned reg; it zero-extends when assigned to y x = 1'bx; y = x; if (y !== 4'b000x) begin $display("FAILED 3 -- x=%b, y=%b", x, y); fail = 1; end // x is a 1-bit unsigned reg; it zero-extends when assigned to y x = 1'bz; y = x; if (y !== 4'b000z) begin $display("FAILED 4 -- x=%b, y=%b", x, y); fail = 1; end // xs is a 1-bit signed reg; it top-bit-extends when assigned to y xs = 1'bx; y = xs; if (y !== 4'bxxxx) begin $display("FAILED 5 -- xs=%b, y=%b", xs, y); fail = 1; end // xs is a 1-bit signed reg; it top-bit-extends when assigned to y xs = 1'bz; y = xs; if (y !== 4'bzzzz) begin $display("FAILED 6 -- xs=%b, y=%b", xs, y); fail = 1; end // 'bx is an unsized unsigned constant; it X-extends to the size of // the expression it is in y = 'bx; if (y !== 4'bxxxx) begin $display("FAILED 7 -- y=%b", y); fail = 1; end // 'bz is an unsized unsigned constant; it Z-extends to the size of // the expression it is in y = 'bz; if (y !== 4'bzzzz) begin $display("FAILED 8 -- y=%b", y); fail = 1; end // this is the only case in which a constant pads to the left with // X's. 4'bx is 4-bit unsigned, but it is specified with fewer than 4 // bits y = 4'bx; if (y !== 4'bxxxx) begin $display("FAILED 9 -- y=%b", y); fail = 1; end // this is the only case in which a constant pads to the left with // Z's. 4'bz is 4-bit unsigned, but it is specified with fewer than 4 // bits y = 4'bz; if (y !== 4'bzzzz) begin $display("FAILED 10 -- y=%b", y); fail = 1; end if (!fail) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/extra_semicolon.v000066400000000000000000000001061435245347300221210ustar00rootroot00000000000000module top; initial begin $display("PASSED"); end; endmodule; iverilog-12_0/ivtest/ivltests/fatal_et_al.v000066400000000000000000000003611435245347300211640ustar00rootroot00000000000000module top; initial begin #1 $info("This is the $info message."); #1 $warning("This is the $warning message."); #1 $error("This is the $error message."); #1 $display("Check that the messages are correct."); end endmodule iverilog-12_0/ivtest/ivltests/fatal_et_al2.v000066400000000000000000000004341435245347300212470ustar00rootroot00000000000000module top; initial begin #1 $info("This is the $info message."); #1 $warning("This is the $warning message."); #1 $error("This is the $error message."); #1 $fatal(0, "This is the $fatal message."); #1 $display("FAILED: This should not print."); end endmodule iverilog-12_0/ivtest/ivltests/fdisplay1.v000066400000000000000000000025371435245347300206340ustar00rootroot00000000000000/* Copyright (C) 2000 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ /* fdisplay1 - test $fwrite and $fdisplay system tasks without using $fopen * * NB: this may need a little tweaking, as I'm not sure that all verilogs * have the predefined $fdisplay descriptors 2 and 3 matching what * vpi_mcd_printf provides. */ module fdisplay1; integer fp; reg [7:0] a; initial begin $display("message to stdout (from $display)\n"); $fwrite(1, "another message (via fwrite) "); $fdisplay(1,"to stdout\n (via fdisplay)"); #5 a = 8'h5a; $fwrite(1, "a = %b at %0t\n", a, $time); $finish(0); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/fdisplay2.v000066400000000000000000000024731435245347300206340ustar00rootroot00000000000000/* Copyright (C) 2000 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ /* fdisplay2 - test $fopen and $fdisplay system tasks */ module fdisplay2; integer fp, dfp; reg [7:0] a; initial begin fp = $fopen("work/fdisplay2.out"); if(fp != 2 && fp != 4 && fp != 8 && fp != 16 && fp != 32 && fp != 64) begin $display("FAILED fopen fp=%d", fp); $finish; end $fwrite(fp, "hello, world\n"); a = 8'hac; //$fdisplay(1|fp, "a = %h; x: %b\n", a, a^8'h0f); dfp = 1|fp; $fdisplay(dfp, "a = 'h%h = 'b%b", a, a); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/fdisplay3.v000066400000000000000000000021601435245347300206260ustar00rootroot00000000000000/* Copyright (C) 2000 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ /* fdisplay3 - check that $fdisplay rejects bogus first arguments */ module fdisplay3; initial begin // This error is now caught at compile time so this message will not // be printed. // // $display("expect compile or runtime error from bad $fdisplay args:"); $fdisplay(fdisplay3, "bogus message"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/fdisplay_fail_fd.v000066400000000000000000000002041435245347300222040ustar00rootroot00000000000000module top; initial begin // This will fail at run time. $fdisplay(32'h8000_000f, "write to invalid FD"); end endmodule iverilog-12_0/ivtest/ivltests/fdisplay_fail_mcd.v000066400000000000000000000002051435245347300223570ustar00rootroot00000000000000module top; initial begin // This will fail at run time. $fdisplay(32'h4000_0000, "write to invalid MCD"); end endmodule iverilog-12_0/ivtest/ivltests/ff_dual_enable.v000066400000000000000000000022561435245347300216440ustar00rootroot00000000000000 module test (input wire clk, output reg foo, bar, input wire foo_valid, foo_in, input wire bar_valid, bar_in /* */); always @(posedge clk) begin if (foo_valid) foo <= foo_in; if (bar_valid) bar <= bar_in; end endmodule // test module main; reg clk; wire foo, bar; reg foo_valid, foo_in; reg bar_valid, bar_in; test dut (.clk(clk), .foo(foo), .bar(bar), .foo_valid(foo_valid), .bar_valid(bar_valid), .foo_in(foo_in), .bar_in(bar_in)); task fail; begin $display("FAILED -- foo/bar=%b/%b, foo/bar_valid=%b/%b, foo/bar_in=%b/%b", foo, bar, foo_valid, bar_valid, foo_in, bar_in); $finish; end endtask // fail initial begin clk = 0; foo_valid = 1; bar_valid = 1; foo_in = 0; bar_in = 0; #1 clk = 1; #1 clk = 0; if (foo !== 0 || bar !== 0) fail; bar_in = 1; #1 clk = 1; #1 clk = 0; if (foo !== 0 || bar !== 1) fail; foo_in = 1; bar_in = 0; foo_valid = 1; bar_valid = 0; #1 clk = 1; #1 clk = 0; if (foo !== 1 || bar !== 1) fail; $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/fileio.v000066400000000000000000000010771435245347300202050ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [20*8-1:0] var; integer fp, code; initial begin fp = $fopenr("read"); if (fp != 0) $display("Read of empty file failed."); fp = $fopenw("work/test.txt"); $fdisplay(fp, "From the write."); $fclose(fp); fp = $fopena("work/test.txt"); $fdisplay(fp, "From the append."); $fclose(fp); fp = $fopenr("work/test.txt"); code = $fgets(var, fp); $display("%0s", var[20*8-1:8]); code = $fgets(var, fp); $display("%0s", var[20*8-1:8]); $fclose(fp); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/fileline.v000066400000000000000000000007541435245347300205260ustar00rootroot00000000000000/* * P1800/D8 22.13 * "`__FILE__ expands to the name of the current input file, in the form of a * string literal." */ module aaa; initial begin #1; $display(`__FILE__); end endmodule /* * P1800/D8 22.13 * "`__LINE__ expands to the current input line number, in the form of * a simple decimal number." */ module bbb; initial begin #2; if(`__LINE__ !== 21 || `__LINE__ !== 22) begin $display("FAIL"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fileline2.v000066400000000000000000000012411435245347300206000ustar00rootroot00000000000000/* * P1800/D8 22.13 * "A `line directive changes `__LINE__, and may change `__FILE__ as well." */ module aaa; reg pass; `define printfl(x) $display("%0d -> %s:%0d", x, `__FILE__, `__LINE__) initial begin #0 pass = 1; `line 1000 "./ivltests/fileline2.v" 0 if(`__LINE__ !== 1000) begin $display("FAIL"); pass = 0; end `printfl(1); `line 2000 "imaginary-include-file" 1 if(`__LINE__ !== 2000) begin $display("FAIL"); pass = 0; end `printfl(2); `line 3000 "./ivltests/fileline2.v" 2 if(`__LINE__ !== 3000) begin $display("FAIL"); pass = 0; end `printfl(3); if(pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/final.v000066400000000000000000000004131435245347300200200ustar00rootroot00000000000000module t; reg [7:0] x = 1; initial #5 x = 2; always @(x) #5 x = 3; final begin if (x == 3) $display("x =%d, PASSED", x); $finish(0); $display("FAILED! Executed past $finish in final block!"); end endmodule module t2; final $display("t2 final"); endmodule iverilog-12_0/ivtest/ivltests/final2.v000066400000000000000000000001541435245347300201040ustar00rootroot00000000000000module t; final $display("Final in %m"); endmodule module t2; final $display("Final in %m"); endmodule iverilog-12_0/ivtest/ivltests/first_last_num.v000066400000000000000000000012661435245347300217670ustar00rootroot00000000000000/* * This program tests that enumeration value first/last/num * methods work properly. */ module main; enum byte { RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, BLACK = 10, WHITE = 'd11 } color1; initial begin color1 = RED; $display("color1.first == %0d", color1.first); $display("color1.last == %0d", color1.last); $display("color1.num == %0d", color1.num); if (color1.first !== RED) begin $display("FAILED"); $finish; end if (color1.last !== WHITE) begin $display("FAILED"); $finish; end if (color1.num !== 8) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/fopen1.v000066400000000000000000000044031435245347300201220ustar00rootroot00000000000000/* Copyright (C) 2000 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ // SDW - reworked a bit to account for the fact that it HAS to be /* fopen1 - test $fopen system task */ module fopen1; reg [31:0] fp; reg error ; initial begin fp = $fopen("work/fopen1.out"); case(fp) 32'h0000_0001: error = 1; 32'h0000_0002: error = 0; 32'h0000_0004: error = 1; 32'h0000_0008: error = 1; 32'h0000_0010: error = 1; 32'h0000_0020: error = 1; 32'h0000_0040: error = 1; 32'h0000_0080: error = 1; 32'h0000_0100: error = 1; 32'h0000_0200: error = 1; 32'h0000_0400: error = 1; 32'h0000_0800: error = 1; 32'h0000_1000: error = 1; 32'h0000_2000: error = 1; 32'h0000_4000: error = 1; 32'h0000_8000: error = 1; 32'h0001_0000: error = 1; 32'h0002_0000: error = 1; 32'h0004_0000: error = 1; 32'h0008_0000: error = 1; 32'h0010_0000: error = 1; 32'h0020_0000: error = 1; 32'h0040_0000: error = 1; 32'h0080_0000: error = 1; 32'h0100_0000: error = 1; 32'h0200_0000: error = 1; 32'h0400_0000: error = 1; 32'h0800_0000: error = 1; 32'h1000_0000: error = 1; 32'h2000_0000: error = 1; 32'h4000_0000: error = 1; 32'h8000_0000: error = 1; default: error = 1; // std_io! endcase $display("fp = %b",fp); if(error == 0) $display("PASSED"); else $display("FAILED"); $fclose(fp); $finish; end endmodule iverilog-12_0/ivtest/ivltests/fopen2.v000066400000000000000000000020551435245347300201240ustar00rootroot00000000000000/* fopen2 - test $fopen and $fclose system tasks */ module fopen2; integer fp1, fp2, fp3, fp4; integer dfp; reg error; reg [31:0] foo; initial begin error = 0; fp1 = $fopen("work/fopen2.out1"); checkfp(fp1); dfp = fp1|1; $fdisplay(dfp, "fp1=%d", fp1); fp2 = $fopen("work/fopen2.out2"); checkfp(fp2); dfp = fp2|1; $fdisplay(dfp, "fp2=%d", fp2); fp3 = $fopen("work/fopen2.out3"); checkfp(fp3); dfp = fp3|1; $fdisplay(dfp, "fp3=%d", fp3); $fclose(fp2); fp4 = $fopen("work/fopen2.out4"); checkfp(fp4); dfp = fp4|1; $fdisplay(dfp, "fp4=%d", fp4); $fclose(fp1); $fclose(fp2); $fclose(fp3); $fclose(fp4); if(error == 0) $display("PASSED"); end // initial begin task checkfp; input [31:0] fp; begin if(fp != 2 && fp != 4 && fp != 8 && fp != 16 && fp != 32 && fp != 64) begin $display("FAILED fopen fp=%d", fp); error = 1; end end endtask // checkfp endmodule iverilog-12_0/ivtest/ivltests/for3.16A.v000066400000000000000000000023351435245347300201330ustar00rootroot00000000000000// // Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // for3.16A - Template 1 - for(val1=0; val1 <= expr ; val1 = val1 + 1) some_action // module test ; reg [3:0] val1; reg [3:0] val2; initial begin val2 = 0; for(val1 = 0; val1 <= 4'ha; val1 = val1+1) begin val2 = val2 + 1; end if(val2 === 4'hb) $display("PASSED"); else begin $display("FAILED val2 s/b 4'ha, but is %h",val2); end end endmodule iverilog-12_0/ivtest/ivltests/for_loop_synth.v000066400000000000000000000017461435245347300220050ustar00rootroot00000000000000 module test #(parameter inputs = 8) (output reg [inputs-1:0] Q, input wire [inputs-1:0] D, input wire [inputs-1:0] I); // This should synthesize to an unrolled version of the // for loop. integer j; always @* begin for (j = 0 ; j < inputs ; j = j+1) begin if (I[j]) Q[j] = ~D[j]; else Q[j] = D[j]; end end endmodule // test module main; wire [7:0] Q; reg [7:0] D, I; test dut (.Q(Q), .D(D), .I(I)); (* ivl_synthesis_off *) initial begin D = 0; I = 0; #1 if (Q !== 8'h00) begin $display("FAILED -- Q=%b, D=%b, I=%b", Q, D, I); $finish; end D = 'h55; I = 'h55; #1 if (Q !== 8'h00) begin $display("FAILED -- Q=%b, D=%b, I=%b", Q, D, I); $finish; end D = 'h55; I = 'haa; #1 if (Q !== 8'hff) begin $display("FAILED -- Q=%b, D=%b, I=%b", Q, D, I); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/for_loop_synth2.v000066400000000000000000000017451435245347300220660ustar00rootroot00000000000000 module test #(parameter inputs = 8) (output reg [inputs-1:0] Q, input wire [inputs-1:0] D, input wire [inputs-1:0] I); // This should synthesize to an unrolled version of the // for loop. integer j; always @* begin for (j = 0 ; j < inputs ; j += 1) begin if (I[j]) Q[j] = ~D[j]; else Q[j] = D[j]; end end endmodule // test module main; wire [7:0] Q; reg [7:0] D, I; test dut (.Q(Q), .D(D), .I(I)); (* ivl_synthesis_off *) initial begin D = 0; I = 0; #1 if (Q !== 8'h00) begin $display("FAILED -- Q=%h, D=%h, I=%h", Q, D, I); $finish; end D = 'h55; I = 'h55; #1 if (Q !== 8'h00) begin $display("FAILED -- Q=%h, D=%h, I=%h", Q, D, I); $finish; end D = 'h55; I = 'haa; #1 if (Q !== 8'hff) begin $display("FAILED -- Q=%h, D=%h, I=%h", Q, D, I); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/force1.v000066400000000000000000000032601435245347300201110ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams (steve at icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA module main; reg [3:0] val_drv = 4'b0101; wire [3:0] val; buf val_buf[3:0] (val, val_drv); initial begin #50 if (val !== val_drv) begin $display("FAILED -- initial val %b !== %b", val, val_drv); $finish; end force val = 4'b1010; #1 if (val !== 4'b1010) begin $display("FAILED -- force 1010 failed, val=%b", val); $finish; end // Use force to "lift" the driver. force val = 4'bzzzz; if (val !== 4'bzzzz) begin $display("FAILED -- force z failed, val=%b", val); $finish; end release val; #1 if (val !== 4'b0101) begin $display("FAILED -- unforced val = %b", val); $finish; end val_drv = 4'b1010; #1 if (val !== 4'b1010) begin $display("FAILED -- val_drv=%b, val=%b", val_drv, val); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/force2.v000066400000000000000000000032251435245347300201130ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams (steve at icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA module main; reg [3:0] val_drv = 4'b0101; wire [3:0] val = val_drv; initial begin #50 if (val !== val_drv) begin $display("FAILED -- initial val %b !== %b", val, val_drv); $finish; end force val = 4'b1010; #1 if (val !== 4'b1010) begin $display("FAILED -- force 1010 failed, val=%b", val); $finish; end // Use force to "lift" the driver. force val = 4'bzzzz; if (val !== 4'bzzzz) begin $display("FAILED -- force z failed, val=%b", val); $finish; end release val; #1 if (val !== 4'b0101) begin $display("FAILED -- unforced val = %b", val); $finish; end val_drv = 4'b1010; #1 if (val !== 4'b1010) begin $display("FAILED -- val_drv=%b, val=%b", val_drv, val); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/force3.17A.v000066400000000000000000000021701435245347300204410ustar00rootroot00000000000000// // Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // force3.17A - Template 1 - force reg_lvalue = constant. // module test ; reg [3:0] val1; reg [3:0] val2; initial begin val2 = 0; #50 ; if(val2 !== 4'b1010) $display("FAILED"); else $display("PASSED"); end initial begin #20; force val2 = 4'b1010; end endmodule iverilog-12_0/ivtest/ivltests/force3.17B.v000066400000000000000000000022111435245347300204360ustar00rootroot00000000000000// // Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // force3.17A - Template 1 - force reg_lvalue = constant. // module test ; reg [3:0] val1; reg [3:0] val2; initial begin val2 = 0; val1 = 2; #50 ; if(val2 !== 4'b0001) $display("FAILED"); else $display("PASSED"); end initial begin #20; force val2 = (val1 == 2); end endmodule iverilog-12_0/ivtest/ivltests/force3.17C.v000066400000000000000000000021741435245347300204470ustar00rootroot00000000000000// // Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // force3.17A - Template 1 - force net_lvalue = constant. // module test ; reg [3:0] val1; reg [3:0] val2; wire [3:0] val3; initial begin #50 ; if(val3 !== 4'b1010) $display("FAILED"); else $display("PASSED"); end initial begin #20; force val3 = 4'b1010; end endmodule iverilog-12_0/ivtest/ivltests/force_lval_part.v000066400000000000000000000010341435245347300220710ustar00rootroot00000000000000module top; reg pass; reg [3:0] value; reg [3:0] in; initial begin pass = 1'b1; value = 4'b1001; if (value !== 4'b1001) begin $display("Failed: initial value, expected 4'b1001, got %b", value); pass = 1'b0; end in = 4'bzx10; // This should work since it is really the whole value. force value[0 +: 4] = in; if (value !== 4'bzx10) begin $display("Failed: force value, expected 4'bzx10, got %b", value); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/force_release_reg_pv.v000066400000000000000000000032011435245347300230650ustar00rootroot00000000000000module test; reg fail = 1'b0; reg [3:0] bus = 4'b0; wire [3:0] val = bus; // to check the propagated value is correct initial begin // Check the initial value. #1 if (val !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", val); fail = 1; end // Check a bit force and verify a normal bit assign does nothing. #1 force bus[0] = 1'b1; bus[0] = 1'bz; #1 if (val !== 4'b0001) begin $display("FAILED: force of bus[0], got %b, expected 0001.", val); fail = 1'b1; end // Check a part force #1 force bus[3:2] = 2'b11; #1 if (val !== 4'b1101) begin $display("FAILED: force of bus[3:2], got %b, expected 1101.", val); fail = 1'b1; end // Check that we can change an unforced bit. #1 bus[1] = 1'bz; #1 if (val !== 4'b11z1) begin $display("FAILED: assignment of bus[1], got %b, expected 11z1.", val); fail = 1'b1; end #1 bus[1] = 1'b0; // Check a bit release. #1 release bus[0]; bus = 4'b000z; #1 if (val !== 4'b110z) begin $display("FAILED: release of bus[0], got %b, expected 110z.", val); fail = 1'b1; end // Check a part release. #1 release bus[3:2]; bus[3] = 1'b0; #1 if (val !== 4'b010z) begin $display("FAILED: release of bus[3:2], got %b, expected 010z.", val); fail = 1'b1; end // Check a force from the upper thread bits (>=8). #1 force bus[2:1] = 2'bx1; #1 if (val !== 4'b0x1z) begin $display("FAILED: force of bus[2:1], got %b, expected 0x1z.", val); fail = 1'b1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/force_release_wire8_pv.v000066400000000000000000000031661435245347300233600ustar00rootroot00000000000000module test; reg fail = 1'b0; reg [3:0] in = 4'b0; wire [3:0] bus; wire [3:0] val; assign (pull1, pull0) bus = in; assign val = bus; initial begin // Check the initial value. #1 if (val !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", val); fail = 1'b1; end // Check a bit force and verify a normal bit assign does nothing. #1 force bus[0] = 1'b1; #1 in[0] = 1'bz; #1 if (val !== 4'b0001) begin $display("FAILED: force of bus[0], got %b, expected 0001.", val); fail = 1'b1; end // Check a part force. #1 force bus[3:2] = 2'b11; #1 if (val !== 4'b1101) begin $display("FAILED: force of bus[3:2], got %b, expected 1101.", val); fail = 1'b1; end // Check that we can change an unforced bit. #1 in[1] = 1'bz; #1 if (val !== 4'b11z1) begin $display("FAILED: assignment of bus[1], got %b, expected 11z1.", val); fail = 1'b1; end #1 in[1] = 1'b0; // Check a bit release. #1 release bus[0]; #1 if (val !== 4'b110z) begin $display("FAILED: release of bus[0], got %b, expected 110z.", val); fail = 1'b1; end // Check a part release. #1 release bus[3:2]; #1 if (val !== 4'b000z) begin $display("FAILED: release of bus[3:2], got %b, expected 000z.", val); fail = 1'b1; end // Check a force from the upper thread bits (>= 8). #1 force bus[2:1] = 2'bx1; #1 if (val !== 4'b0x1z) begin $display("FAILED: force of bus[2:1], got %b, expected 0x1z.", val); fail = 1'b1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/force_release_wire_pv.v000066400000000000000000000031671435245347300232710ustar00rootroot00000000000000module test; reg fail = 1'b0; reg [3:0] in = 4'b0; wire [3:0] bus = in; wire [3:0] val = bus; // to check the propagated value is correct initial begin // Check the initial value. #1 if (val !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", val); fail = 1'b1; end // Check a bit froce and verify a normal bit assign does nothing. #1 force bus[0] = 1'b1; #1 in[0] = 1'bz; #1 if (val !== 4'b0001) begin $display("FAILED: force of bus[0], got %b, expected 0001.", val); fail = 1'b1; end // Check a part force. #1 force bus[3:2] = 2'b11; #1 if (val !== 4'b1101) begin $display("FAILED: force of bus[3:2], got %b, expected 1101.", val); fail = 1'b1; end // Check that we can change an unforced bit. #1 in[1] = 1'bz; #1 if (val !== 4'b11z1) begin $display("FAILED: assignment of bus[1], got %b, expected 11z1.", val); fail = 1'b1; end #1 in[1] = 1'b0; // Check a bit release. #1 release bus[0]; #1 if (val !== 4'b110z) begin $display("FAILED: release of bus[0], got %b, expected 110z.", val); fail = 1'b1; end // Check a part release. #1 release bus[3:2]; #1 if (val !== 4'b000z) begin $display("FAILED: release of bus[3:2], got %b, expected 000z.", val); fail = 1'b1; end // Check a force from the upper thread bits (>= 8). #1 force bus[2:1] = 2'bx1; #1 if (val !== 4'b0x1z) begin $display("FAILED: force of bus[2:1], got %b, expected 0x1z.", val); fail = 1'b1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/forgen.vhd000066400000000000000000000023531435245347300205300ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; -- This is a simple test of the initialization assignment for -- signals. We also let a generic into the test. entity test is generic (width : integer := 4); port (clk : in std_logic; src0, src1 : in std_logic_vector (width-1 downto 0); dst : out std_logic_vector (width-1 downto 0)); end test; library ieee; use ieee.std_logic_1164.all; entity reg_xor is port (clk : in std_logic; src0, src1 : in std_logic; dst : out std_logic); end reg_xor; architecture operation of test is component reg_xor port (clk : in std_logic; src0, src1 : in std_logic; dst : out std_logic); end component; begin vec: for idx in width-1 downto 0 generate slice: reg_xor port map (clk => clk, src0 => src0(idx), src1 => src1(idx), dst => dst(idx)); end generate vec; end operation; architecture operation of reg_xor is signal tmp : std_logic; begin tmp <= src0 xor src1; step: process (clk) begin -- process step if clk'event and clk = '1' then -- rising clock edge dst <= tmp; end if; end process step; end operation; iverilog-12_0/ivtest/ivltests/fork1.v000066400000000000000000000025211435245347300177530ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate 3 way fork. Bug report 228. module test; reg a,b,c; reg error; initial begin error = 0; fork a = 1; b = 0; c = 1; join if(a !== 1) begin $display("FAILED - a not set to 1"); error = 1; end if(b !== 0) begin $display("FAILED - b not set to 0"); error = 1; end if(c !== 1) begin $display("FAILED - c not set to 1"); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fork3.19A.v000066400000000000000000000034621435245347300203130ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate fork template 1 module main ; reg [3:0] value1,value2 ; reg [3:0] ret1,ret2 ; reg error; always @(value1 or value2) begin fork #10 ret1 = value1; #22 ret2 = value2; join end initial begin error = 0; #1 ; value1 = 1; value2 = 2; ret1 = 0; ret2 = 0; #12; if(ret1 !== 1) begin $display("FAILED - force3.19A first statement didn't execute(1)"); error = 1; end if(ret2 !== 0) begin $display("FAILED - force3.19A second stmt executed? is %d sb %d", 1'b0,ret2); error = 1; end #10; if(ret1 !== 1) begin $display("FAILED -fork3.19A First statement problem sb 1, is %d",ret1); error = 1; end if(ret2 !== 2) begin $display("FAILED -fork3.19A First statement problem sb 2, is %d",ret1); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fork3.19B.v000066400000000000000000000034711435245347300203140ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate fork template 2 module main ; reg [3:0] value1,value2 ; reg [3:0] ret1,ret2 ; reg error; always @(value1 or value2) begin fork #10 ret1 = value1; @(ret1) #12 ret2 = value2; join end initial begin error = 0; #1; value1 = 1; value2 = 2; ret1 = 0; ret2 = 0; #12; if(ret1 !== 1) begin $display("FAILED - force3.19B first statement didn't execute(1)"); error = 1; end if(ret2 !== 0) begin $display("FAILED - force3.19B second stmt executed? is %d sb %d", 1'b0,ret2); error = 1; end #10; if(ret1 !== 1) begin $display("FAILED -fork3.19B First statement problem sb 1, is %d",ret1); error = 1; end if(ret2 !== 2) begin $display("FAILED -fork3.19B First statement problem sb 2, is %d",ret1); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fork_join_any.v000066400000000000000000000012721435245347300215620ustar00rootroot00000000000000/* * This is a simple test for the for...join_any syntax. There is a * fork statement to start a bunch of threads. We wait for none of * them and instead watch them progress with the master thread. */ module main; int flag; initial begin flag = 0; fork # 10 flag = 10; # 20 flag = 20; # 30 flag = 30; join_any #5 if (flag != 10) begin $display("FAILED -- flag=%d (s.b. 10)", flag); $finish; end #10 if (flag != 20) begin $display("FAILED -- flag=%d (s.b. 20)", flag); $finish; end #10 if (flag != 30) begin $display("FAILED -- flag=%d (s.b. 30)", flag); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fork_join_dis.v000066400000000000000000000052261435245347300215550ustar00rootroot00000000000000module top; reg [1:0] a, b, c, d, e; reg passed; initial begin a = 2'b00; b = 2'b00; c = 2'b00; d = 2'b00; e = 2'b00; passed =1'b1; #2; // Check that only the first process has run so far. if (a !== 2'b01) begin $display("First process in named fork has not run: %b", a); passed = 1'b0; end if (b !== 2'b01) begin $display("First process in named block has not run: %b", b); passed = 1'b0; end if (c !== 2'b01) begin $display("First process in parent ending has not run: %b", c); passed = 1'b0; end if (d !== 2'b01) begin $display("First process in parent alive has not run: %b", d); passed = 1'b0; end if (e !== 2'b01) begin $display("First process in parent ending (disable) has not run: %b", e); passed = 1'b0; end // This external lexical disable should disable the second process even // though the parent has already ended. disable top.be_name; #2; // Check that the second process only runs for the parent ending // and alive cases. if (a !== 2'b01) begin $display("Second process in named fork ran: %b", a); passed = 1'b0; end if (b !== 2'b01) begin $display("Second process in named block ran: %b", b); passed = 1'b0; end if (c !== 2'b11) begin $display("Second process in parent ending has not run: %b", c); passed = 1'b0; end if (d !== 2'b11) begin $display("Second process in parent alive has not run: %b", d); passed = 1'b0; end if (e !== 2'b01) begin $display("Second process in parent ending (disable) ran: %b", e); passed = 1'b0; end if (passed) $display("PASSED"); end // Verify that disabling a named fork kills any detached processes. initial begin fork: fa_name #1 a[0] = 1'b1; #3 a[1] = 1'b1; join_any disable fa_name; end // Verify that disabling a named block kills any detached processes. initial begin: bb_name fork #1 b[0] = 1'b1; #3 b[1] = 1'b1; join_any disable bb_name; end // Verify that a detached process survives the parent ending. initial begin fork #1 c[0] = 1'b1; #3 c[1] = 1'b1; join_any end // Verify that a detached process runs if the parent is still alive. initial begin fork #1 d[0] = 1'b1; #3 d[1] = 1'b1; join_any #4; end // Verify that a detached process survives the parent ending, but can // still be disabled lexically by disabling the block that started it. initial begin: be_name fork #1 e[0] = 1'b1; #3 e[1] = 1'b1; join_any end endmodule iverilog-12_0/ivtest/ivltests/fork_join_none.v000066400000000000000000000014411435245347300217300ustar00rootroot00000000000000/* * This is a simple test for the for...join_none syntax. There is a * fork statement to start a bunch of threads. We wait for none of * them and instead watch them progress with the master thread. */ module main; int flag; initial begin flag = 0; fork # 10 flag = 10; # 20 flag = 20; # 30 flag = 30; join_none #5 if (flag != 0) begin $display("FAILED -- flag=%d (s.b. 0)", flag); $finish; end #10 if (flag != 10) begin $display("FAILED -- flag=%d (s.b. 10)", flag); $finish; end #10 if (flag != 20) begin $display("FAILED -- flag=%d (s.b. 20)", flag); $finish; end #10 if (flag != 30) begin $display("FAILED -- flag=%d (s.b. 30)", flag); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/format.v000066400000000000000000000003661435245347300202260ustar00rootroot00000000000000module test; wire [10:0] a = 7'd 16; initial begin #1; $display(">%0d<", a); $display(">%4d<", a); $display(">%h<", a); $display(">%4h<", a); $display("%d, %d", a); end endmodule iverilog-12_0/ivtest/ivltests/fr47.v000066400000000000000000000005311435245347300175120ustar00rootroot00000000000000// Regression test for feature request #47 module test(); function [15:0] add; input [15:0] a; input [15:0] b; begin add = a + b; end endfunction reg [15:0] result; initial begin result = add(1, add(4, 2)); $display("(1+(4+2)) = %d", result); if (result === 7) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/fr49.v000066400000000000000000000003641435245347300175200ustar00rootroot00000000000000// Check that a SystemVerilog do/while loop works correctly. module top; int i; initial begin i = 0; do begin i += 1; $display("The value of i is %0d", i); end while (i < 2); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fread-error.v000066400000000000000000000006521435245347300211440ustar00rootroot00000000000000module top; integer res, ival; reg [7:0] rg; reg [7:0] mem [3:0]; initial begin res = $fread(ival, 1); // 1st arg. must be a reg. or memory. res = $fread(rg); // Too few argument. res = $fread(mem, "a"); // Not a valid fd. res = $fread(mem, 1, "a"); // Not a valid start. res = $fread(mem, 1, 0, "a"); // Not a valid count. res = $fread(mem, 1, 0, 2, 3); // Too many argument. end endmodule iverilog-12_0/ivtest/ivltests/fread.txt000066400000000000000000000000471435245347300203650ustar00rootroot00000000000000ab01zy01234567890123456789012345678901 iverilog-12_0/ivtest/ivltests/fread.v000066400000000000000000000116151435245347300200160ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; localparam string = "ab"; localparam rg_res = string & 9'h1ff; reg passed; integer fd, res; reg [8:0] rg; reg [7:0] mem [31:0]; initial begin passed = 1'b1; fd = $fopen("ThisFileDoesNotExist.txt", "r"); res = $fread(rg, fd); // Try to read from an invalid fd. if (res != 0) begin $display("$fread (register fd) count is wrong, expected 0, got %0d", res); passed = 1'b0; end if (rg !== 9'bx) begin $display("$fread (register fd) value is wrong, expected 9'bx, got %b", rg); passed = 1'b0; end fd = $fopen("ivltests/fread.txt", "r"); res = $fread(mem, fd, -1); // Try an invalid start if (res != 0) begin $display("$fread (mem. start) count is wrong, expected 0, got %0d", res); passed = 1'b0; end if (mem[0] !== 8'bx) begin $display("$fread (mem. start[0]) value is wrong, expected 8'bx, got %b", mem[0]); passed = 1'b0; end if (mem[15] !== 8'bx) begin $display("$fread (mem. start[15]) value is wrong, expected 8'bx, got %b", mem[15]); passed = 1'b0; end if (mem[31] !== 8'bx) begin $display("$fread (mem. start[31]) value is wrong, expected 8'bx, got %b", mem[31]); passed = 1'b0; end // Check $fread with a register value. res = $fread(rg, fd); // Load with the lower nine bits of "ab". if (res != 2) begin $display("$fread (register) count is wrong, expected 2, got %0d", res); passed = 1'b0; end if (rg !== rg_res) begin $display("$fread (register) value is wrong, expected %b, got %b", rg_res, rg); passed = 1'b0; end // Check $fread with a memory. res = $fread(mem, fd, 0, 2); // Load 0 with "0" and 1 with "1". if (res != 2) begin $display("$fread (mem. 1) count is wrong, expected 2, got %0d", res); passed = 1'b0; end if (mem[0] !== "0") begin $display("$fread (mem. 1[0]) value is wrong, expected %b, got %b", "0", mem[0]); passed = 1'b0; end if (mem[1] !== "1") begin $display("$fread (mem. 1[1]) value is wrong, expected %b, got %b", "1", mem[1]); passed = 1'b0; end res = $fread(mem, fd, 31); // Load 31 with "z". if (res != 1) begin $display("$fread (mem. 2) count is wrong, expected 1, got %0d", res); passed = 1'b0; end if (mem[31] !== "z") begin $display("$fread (mem. 2[31]) value is wrong, expected %b, got %b", "z", mem[31]); passed = 1'b0; end res = $fread(mem, fd, 31, 2); // Load 31 with "y" and warns. if (res != 1) begin $display("$fread (mem. 3) count is wrong, expected 1, got %0d", res); passed = 1'b0; end if (mem[31] !== "y") begin $display("$fread (mem. 3[31]) value is wrong, expected %b, got %b", "y", mem[31]); passed = 1'b0; end res = $fread(mem, fd); // Load with repeated "0" .. "9" pattern. if (res != 32) begin $display("$fread (mem. 4) count is wrong, expected 32, got %0d", res); passed = 1'b0; end // Just check the end values and a value in the middle (15). if (mem[0] !== "0") begin $display("$fread (mem. 4[0]) value is wrong, expected %b, got %b", "0", mem[0]); passed = 1'b0; end if (mem[15] !== "5") begin $display("$fread (mem. 4[15]) value is wrong, expected %b, got %b", "5", mem[15]); passed = 1'b0; end if (mem[31] !== "1") begin $display("$fread (mem. 4[31]) value is wrong, expected %b, got %b", "1", mem[31]); passed = 1'b0; end // This only gets the trailing new line. rg = 9'bx; res = $fread(rg, fd); if (res != 1) begin $display("$fread (EOL) count is wrong, expected 1, got %0d", res); passed = 1'b0; end if (rg !== 9'h0xx) begin $display("$fread (EOL value is wrong, expected 9'b0xx, got %b", rg); passed = 1'b0; end // There are no bits left so this array should be the same. res = $fread(mem, fd); if (res != 0) begin $display("$fread (mem. EOL) count is wrong, expected 0, got %0d", res); passed = 1'b0; end // Just check the end values and a value in the middle (15). if (mem[0] !== "0") begin $display("$fread (mem. EOL[0]) value is wrong, expected %b, got %b", "0", mem[0]); passed = 1'b0; end if (mem[15] !== "5") begin $display("$fread (mem. EOL[15]) value is wrong, expected %b, got %b", "5", mem[15]); passed = 1'b0; end if (mem[31] !== "1") begin $display("$fread (mem. EOL[31]) value is wrong, expected %b, got %b", "1", mem[31]); passed = 1'b0; end $fclose(fd); if (passed) $display("PASSED"); else $display("FAILED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/fscanf_u.v000066400000000000000000000207051435245347300205210ustar00rootroot00000000000000module top; reg [15:0] out_16; reg [31:0] in_32, in_32x, ck_32, ck_32x, out_32, out_32x; reg [63:0] out_64; integer res, fd; reg passed; initial begin passed = 1'b1; // Check that a normal 32 bit %u works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #1 returned %d", res); passed = 1'b0; end else if (ck_32 !== out_32) begin $display("FAILED: #1 %b !== %b", ck_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #1 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 32/64 bit %u works as expected. Do the write as // two 32 bit values to make sure the word order is correct. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; ck_32x = 32'b00010000_00100000_00110000_01000000; $fwrite(fd, "%u", in_32x); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_64); if (res !== 1) $display("FAILED: $fscanf() #2a returned %d", res); else if ({ck_32x,ck_32} !== out_64) begin $display("FAILED: #2a %b !== %b", {ck_32x,ck_32}, out_64); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2a EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64/64 bit %u works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; in_32x = 32'b0001000x_0010000x_0011000x_0100000x; ck_32x = 32'b00010000_00100000_00110000_01000000; $fwrite(fd, "%u", {in_32x,in_32}); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_64); if (res !== 1) $display("FAILED: $fscanf() #2b returned %d", res); else if ({ck_32x,ck_32} !== out_64) begin $display("FAILED: #2b %b !== %b", {ck_32x,ck_32}, out_64); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2b EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64/32 bit %u works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; in_32x = 32'b0001000x_0010000x_0011000x_0100000x; ck_32x = 32'b00010000_00100000_00110000_01000000; $fwrite(fd, "%u", {in_32x,in_32}); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u%u", out_32,out_32x); if (res !== 2) $display("FAILED: $fscanf() #2c returned %d", res); else if ({ck_32x,ck_32} !== {out_32x, out_32}) begin $display("FAILED: #2c %b !== %b", {ck_32x,ck_32}, {out_32x,out_32}); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2c EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 16 bit %u works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_16); if (res !== 1) begin $display("FAILED: $fscanf() #3 returned %d", res); passed = 1'b0; end else if (ck_32[15:0] !== out_16) begin $display("FAILED: #3 %b !== %b", ck_32[15:0], out_16); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #3 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 16 bit %u works as expected even with a 32 bit variable. // All 32 bits are read but we truncate and zero fill the result. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%16u", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #4 returned %d", res); passed = 1'b0; end else if (ck_32[15:0] !== out_32) begin $display("FAILED: #4 %b !== %b", ck_32[15:0], out_32); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #4 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 32 bit %u works with a 64 bit variable when sized. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%32u", out_64); if (res !== 1) begin $display("FAILED: $fscanf() #5 returned %d", res); passed = 1'b0; end else if (ck_32 !== out_64) begin $display("FAILED: #5 %b !== %b", ck_32, out_64); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #5 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that by default one element is suppressed. fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%u", in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*u%u", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #6 returned %d", res); passed = 1'b0; end else if (ck_32 !== out_32) begin $display("FAILED: #6 %b !== %b", ck_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #6 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that multiple elements can be suppressed (exact count). fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%u%u", in_32x, in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*64u%u", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #7 returned %d", res); passed = 1'b0; end else if (ck_32 !== out_32) begin $display("FAILED: #7 %b !== %b", ck_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #7 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that multiple elements can be suppressed (minimum count). fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%u%u", in_32x, in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*33u%u", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #8 returned %d", res); passed = 1'b0; end else if (ck_32 !== out_32) begin $display("FAILED: #8 %b !== %b", ck_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #8 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fscanf_u_warn.v000066400000000000000000000077761435245347300215650ustar00rootroot00000000000000module top; reg [31:0] in_32, ck_32, out_32, out_32x; reg [63:0] out_64; integer res, fd; reg passed; initial begin passed = 1'b1; // Check that a normal 32 bit %u catches missing bytes. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%c%c", in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #1 returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %u catches missing bytes (1/4). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%c%c", in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2a returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %u catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2b returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %u catches missing bytes (3/4). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u%c%c", in_32, in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2c returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 32 bit %u suppression catches missing bytes. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%c%c", in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #3 returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a multiple read %u catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; ck_32 = 32'b00001000_00100000_10100000_10001110; $fwrite(fd, "%u%c%c", in_32, in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%u%u", out_32, out_32x); if (res !== 1) begin $display("FAILED: $fscanf() #4 returned %d (%b)", res, out_32x); passed = 1'b0; end else begin if (ck_32 !== out_32) begin $display("FAILED: $fscanf() #4 %b !== %b", ck_32, out_32); passed = 1'b0; end if (out_32x !== 32'bx) begin $display("FAILED: $fscanf() #4 %b !== 32'bx", out_32x); passed = 1'b0; end end res = $fscanf(fd, "%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #4 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a suppression/read %u catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u%c%c", in_32, in_32[15:8], in_32[7:0]); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); out_32 = 32'bx; res = $fscanf(fd, "%*u%u", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #5 returned %d (%b)", res, out_32); passed = 1'b0; end else if (out_32 !== 32'bx) begin $display("FAILED: $fscanf() #5 %b !== 32'bx", out_32); passed = 1'b0; end $fclose(fd); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fscanf_z.v000066400000000000000000000174021435245347300205260ustar00rootroot00000000000000module top; reg [15:0] out_16; reg [31:0] in_32, in_32x, out_32, out_32x; reg [63:0] out_64; integer res, fd; reg passed; initial begin passed = 1'b1; // Check that a normal 32 bit %z works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #1 returned %d", res); passed = 1'b0; end else if (in_32 !== out_32) begin $display("FAILED: #1 %b !== %b", in_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #1 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 32/64 bit %z works as expected. Do the write as // two 32 bit values to make sure the word order is correct. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z", in_32x); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_64); if (res !== 1) $display("FAILED: $fscanf() #2a returned %d", res); else if ({in_32x,in_32} !== out_64) begin $display("FAILED: #2a %b !== %b", {in_32x,in_32}, out_64); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2a EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64/64 bit %z works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z", {in_32x,in_32}); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_64); if (res !== 1) $display("FAILED: $fscanf() #2b returned %d", res); else if ({in_32x,in_32} !== out_64) begin $display("FAILED: #2b %b !== %b", {in_32x,in_32}, out_64); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2b EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64/32 bit %z works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z", {in_32x,in_32}); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z%z", out_32,out_32x); if (res !== 2) $display("FAILED: $fscanf() #2c returned %d", res); else if ({in_32x,in_32} !== {out_32x, out_32}) begin $display("FAILED: #2c %b !== %b", {in_32x,in_32}, {out_32x,out_32}); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #2c EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 16 bit %z works as expected. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_16); if (res !== 1) begin $display("FAILED: $fscanf() #3 returned %d", res); passed = 1'b0; end else if (in_32[15:0] !== out_16) begin $display("FAILED: #3 %b !== %b", in_32[15:0], out_16); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #3 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 16 bit %z works as expected even with a 32 bit variable. // All 32 bits are read but we truncate and zero fill the result. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%16z", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #4 returned %d", res); passed = 1'b0; end else if (in_32[15:0] !== out_32) begin $display("FAILED: #4 %b !== %b", in_32[15:0], out_32); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #4 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a 32 bit %z works with a 64 bit variable when sized. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%32z", out_64); if (res !== 1) begin $display("FAILED: $fscanf() #5 returned %d", res); passed = 1'b0; end else if (in_32 !== out_64) begin $display("FAILED: #5 %b !== %b", in_32, out_64); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #5 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that by default one element is suppressed. fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z", in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*z%z", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #6 returned %d", res); passed = 1'b0; end else if (in_32 !== out_32) begin $display("FAILED: #6 %b !== %b", in_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #6 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that multiple elements can be suppressed (exact count). fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z%z", in_32x, in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*64z%z", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #7 returned %d", res); passed = 1'b0; end else if (in_32 !== out_32) begin $display("FAILED: #7 %b !== %b", in_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #7 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that multiple elements can be suppressed (minimum count). fd = $fopen("work/test_fscanf.bin", "wb"); in_32x = 32'b0001000x_0010000x_0011000x_0100000x; $fwrite(fd, "%z%z", in_32x, in_32x); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*33z%z", out_32); if (res !== 1) begin $display("FAILED: $fscanf() #8 returned %d", res); passed = 1'b0; end else if (in_32 !== out_32) begin $display("FAILED: #8 %b !== %b", in_32, out_32); passed = 1'b0; end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #8 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/fscanf_z_warn.v000066400000000000000000000075121435245347300215560ustar00rootroot00000000000000module top; reg [31:0] in_32, out_32, out_32x; reg [63:0] out_64; integer res, fd; reg passed; initial begin passed = 1'b1; // Check that a normal 32 bit %z catches missing bytes. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #1 returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %z catches missing bytes (1/4). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2a returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %z catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2b returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 64 bit %z catches missing bytes (3/4). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z%u", in_32, in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z", out_64); if (res !== -1) begin $display("FAILED: $fscanf() #2c returned %d (%b)", res, out_64); passed = 1'b0; end $fclose(fd); // Check that a normal 32 bit %z suppression catches missing bytes. fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%u", in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%*z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #3 returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a multiple read %z catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z%u", in_32, in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); res = $fscanf(fd, "%z%z", out_32, out_32x); if (res !== 1) begin $display("FAILED: $fscanf() #4 returned %d (%b)", res, out_32x); passed = 1'b0; end else begin if (in_32 !== out_32) begin $display("FAILED: $fscanf() #4 %b !== %b", in_32, out_32); passed = 1'b0; end if (out_32x !== 32'bx) begin $display("FAILED: $fscanf() #4 %b !== 32'bx", out_32x); passed = 1'b0; end end res = $fscanf(fd, "%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #4 EOF returned %d (%b)", res, out_32); passed = 1'b0; end $fclose(fd); // Check that a suppression/read %z catches missing bytes (1/2). fd = $fopen("work/test_fscanf.bin", "wb"); in_32 = 32'b000x100z_001z000x_101xxxzz_100z111x; $fwrite(fd, "%z%u", in_32, in_32); $fclose(fd); fd = $fopen("work/test_fscanf.bin", "rb"); out_32 = 32'bx; res = $fscanf(fd, "%*z%z", out_32); if (res !== -1) begin $display("FAILED: $fscanf() #5 returned %d (%b)", res, out_32); passed = 1'b0; end else if (out_32 !== 32'bx) begin $display("FAILED: $fscanf() #5 %b !== 32'bx", out_32); passed = 1'b0; end $fclose(fd); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/full_case.v000066400000000000000000000013521435245347300206670ustar00rootroot00000000000000/* */ module main; reg [1:0] sel, in; reg [1:0] out; (* ivl_combinational *) always @* (* ivl_full_case *) case (sel) 2'b01: out = 2'b10; 2'b10: out = in[0]; 2'b11: out = in[1]; endcase // casex(sel) (* ivl_synthesis_off *) initial begin in = 2'b10; sel = 1; #1 if (out !== 2'b10) begin $display("FAILED -- sel=%b, out=%b", sel, out); $finish; end sel = 2; #1 if (out !== 2'b00) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end sel = 3; #1 if (out !== 2'b01) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/full_case2.v000066400000000000000000000013661435245347300207560ustar00rootroot00000000000000/* */ module main; reg [1:0] sel, in; reg [1:0] out; (* ivl_combinational *) always @* begin (* ivl_full_case *) case (sel) 2'b01: out = 2'b10; 2'b10: out = in[0]; 2'b11: out = in[1]; endcase // casex(sel) end (* ivl_synthesis_off *) initial begin in = 2'b10; sel = 1; #1 if (out !== 2'b10) begin $display("FAILED -- sel=%b, out=%b", sel, out); $finish; end sel = 2; #1 if (out !== 2'b00) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end sel = 3; #1 if (out !== 2'b01) begin $display("FAILED -- sel=%b, in=%b, out=%b", sel, in, out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/func_init_var1.v000066400000000000000000000021211435245347300216340ustar00rootroot00000000000000module test(); function integer accumulate1(input integer value); static int acc = 1; acc = acc + value; return acc; endfunction function automatic integer accumulate2(input integer value); int acc = 1; acc = acc + value; return acc; endfunction localparam value1 = accumulate1(2); localparam value2 = accumulate1(3); localparam value3 = accumulate2(2); localparam value4 = accumulate2(3); integer value; reg failed = 0; initial begin $display("%d", value1); if (value1 !== 3) failed = 1; $display("%d", value2); if (value2 !== 4) failed = 1; $display("%d", value3); if (value3 !== 3) failed = 1; $display("%d", value4); if (value4 !== 4) failed = 1; value = accumulate1(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate1(3); $display("%d", value); if (value !== 6) failed = 1; value = accumulate2(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate2(3); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/func_init_var2.v000066400000000000000000000022071435245347300216420ustar00rootroot00000000000000module static test(); function integer accumulate1(input integer value); begin:blk static int acc = 1; acc = acc + value; return acc; end endfunction function automatic integer accumulate2(input integer value); begin:blk automatic int acc = 1; acc = acc + value; return acc; end endfunction localparam value1 = accumulate1(2); localparam value2 = accumulate1(3); localparam value3 = accumulate2(2); localparam value4 = accumulate2(3); integer value; initial begin static reg failed = 0; $display("%d", value1); if (value1 !== 3) failed = 1; $display("%d", value2); if (value2 !== 4) failed = 1; $display("%d", value3); if (value3 !== 3) failed = 1; $display("%d", value4); if (value4 !== 4) failed = 1; value = accumulate1(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate1(3); $display("%d", value); if (value !== 6) failed = 1; value = accumulate2(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate2(3); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/func_init_var3.v000066400000000000000000000021301435245347300216360ustar00rootroot00000000000000module automatic test(); function static integer accumulate1(input integer value); static int acc = 1; acc = acc + value; return acc; endfunction function integer accumulate2(input integer value); int acc = 1; acc = acc + value; return acc; endfunction localparam value1 = accumulate1(2); localparam value2 = accumulate1(3); localparam value3 = accumulate2(2); localparam value4 = accumulate2(3); integer value; reg failed = 0; initial begin $display("%d", value1); if (value1 !== 3) failed = 1; $display("%d", value2); if (value2 !== 4) failed = 1; $display("%d", value3); if (value3 !== 3) failed = 1; $display("%d", value4); if (value4 !== 4) failed = 1; value = accumulate1(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate1(3); $display("%d", value); if (value !== 6) failed = 1; value = accumulate2(2); $display("%d", value); if (value !== 3) failed = 1; value = accumulate2(3); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/func_void_in_expr_fail.v000066400000000000000000000004301435245347300234210ustar00rootroot00000000000000// Check that an error is reported when a void function is used in an expression module test; function void f; endfunction initial begin int x; x = f() + 1; // This should fail, void function can not be used in expression $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/function1.v000066400000000000000000000022711435245347300206410ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This example catches the case of a unser defined function that is * a parameter to a system task. */ module main; function [15:0] sum; input [15:0] a; input [15:0] b; sum = a + b; endfunction // sum initial begin $display("%h = sum(%h, %h)", sum(3,5), 16'd3, 16'd5); $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function10.v000066400000000000000000000022211435245347300207140ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Andrei Purdea (andrei@purdea.ro) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; // Test that functions without parantheses for port-list, // and without any declarations compile successfully. // Valid according to IEEE1800-2005. // IEEE1364-2005 requires at least one declaration. function void empty_function; endfunction initial begin empty_function(); end endmodule iverilog-12_0/ivtest/ivltests/function11.v000066400000000000000000000017321435245347300207230ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Andrei Purdea (andrei@purdea.ro) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // The below test is expected to fail with a combilation error. module main; function void bla(); return 10; endfunction endmodule iverilog-12_0/ivtest/ivltests/function12.v000066400000000000000000000024161435245347300207240ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Andrei Purdea (andrei@purdea.ro) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // This test checks that returning from a void function works correctly. module main; int res = 123; function void bla(); int i; for (i=0;i<10;i=i+1) begin res = i; $display("loop %d", i); if (i == 5) begin return; end end endfunction initial begin bla(); if (res == 5) begin $display("PASS"); end else begin $display("FAIL"); end end endmodule iverilog-12_0/ivtest/ivltests/function2.v000066400000000000000000000007131435245347300206410ustar00rootroot00000000000000/* * This program handles the case of a system task within a user * defined function. */ module main; reg [31:0] tmp1; reg [31:0] tmp2; function [31:0] test; input [31:0] op1; $write("op1 = %h\n", op1); endfunction initial begin tmp1 = 'hdeadbeef; tmp2 = test(tmp1); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/function3.11B.v000066400000000000000000000031221435245347300211610ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate function w/ single input module main (); reg [31:0] val1,val2 ; reg error; function [31:0] myfunc ; input [31:0] in1 ; myfunc = in1 ; endfunction initial begin error = 0; val1 = myfunc(32'h0) ; if(val1 != 32'h0) begin $display("FAILED - function3.11B - func(lit) != lit "); error = 1; end val2 = 32'h12345678 ; val1 = myfunc(val2); if(val1 != val2) begin $display("FAILED - function3.11B - func(reg var) != reg var "); error = 1; end if(myfunc(32'h10101010) != 32'h10101010) begin $display("FAILED - function3.11B - if(func(reg var) != reg var) "); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function3.11C.v000066400000000000000000000033131435245347300211640ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate function called from within function module main (); reg [31:0] val1,val2 ; reg error; function [31:0] myfunc2 ; input [31:0] in2 ; myfunc2 = in2; endfunction function [31:0] myfunc1 ; input [31:0] in1 ; myfunc1 = myfunc2(in1) ; endfunction initial begin error = 0; val1 = myfunc1(32'h0) ; if(val1 != 32'h0) begin $display("FAILED - function3.11C - function called from funct(1)"); error = 1; end val2 = 32'h12345678 ; val1 = myfunc1(val2); if(val1 != val2) begin $display("FAILED - function3.11C - function called from funct(2)"); error = 1; end if(myfunc1(32'h10101010) != 32'h10101010) begin $display("FAILED - function3.11C - function called from funct(3)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function3.11D.v000066400000000000000000000027541435245347300211750ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate function within a continuous assignment module main (); reg error; reg [3:0] val2; function [3:0] myfunc ; input [31:0] in1 ; myfunc = in1; endfunction wire [3:0] val1; assign val1 = myfunc(val2); initial begin error = 0; val2 = 4'h0; # 1 ; if(val1 !== 4'b0) begin $display("FAILED - function3.11D - function within continuous assign(1)"); error = 1; end val2 = 32'h8; # 1 ; if(val1 !== val2) begin $display("FAILED - function3.11D - function within continuous assign(2)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function3.11E.v000066400000000000000000000021441435245347300211670ustar00rootroot00000000000000// // Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // function3.11E - Validate calling a task in a function causes an error. // module test ; task foo2; $display("insided foo2"); endtask function [31:0] foo; input [31:0] a; foo = a; foo2; endfunction reg [31:0] b; initial begin $display("hi"); b = foo(123); end endmodule iverilog-12_0/ivtest/ivltests/function3.11F.v000066400000000000000000000034651435245347300211770ustar00rootroot00000000000000// // Copyright (c) 1999 Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // 9/7/99 - SDW - Modified by instantiating Peter's module into a // self-checking structure. Moved bar=result inside // begin clause in function. // // SDW - Validate function contains a register module main (); reg [1:0] val1; reg val2; reg error; function bar; input [1:0] arg; reg result; begin result = |arg; bar = result; end endfunction initial begin error = 0; val2 = bar(2'b01); if(val2 != 1) begin $display("FAILED function 3.11F - register within a function(1)"); error = 1; end val1 = 2'b11 ; val2 = bar(val1) ; if(val2 != 1) begin $display("FAILED function 3.11F - register within a function(2)"); error = 1; end val2 = bar(2'b00); if(val2 != 0) begin $display("FAILED function 3.11F - register within a function(2)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function3.v000066400000000000000000000034411435245347300206430ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program checks that a function execution that includes part * selects properly evaluates expressions. This is inspired by PR#95. */ module main; wire [3:0] a = 4'h1; wire [3:0] b = 4'h3; reg [1:0] got1, got2; reg [7:0] line; initial begin line = 8'h30; #1; // Need some delay for the assignments to run. got1 = { (b[3:0] == line[7:4]), (a[3:0] == line[3:0]) }; got2 = test(a, b, line); $display("a=%b, b=%b, line=%b, got1=%b, got2=%b", a, b, line, got1, got2); if (got1 !== 2'b10) begin $display("FAILED -- got1 is wrong: %b !== 2'b10", got1); $finish; end if (got1 !== got2) begin $display("FAILED -- got2 is incorrect: %b !== %b", got1, got2); $finish; end $display("PASSED"); $finish; end function [1:0] test; input [3:0] a, b; input [7:0] line; test = { (b == line[7:4]), (a[3:0] == line[3:0]) }; endfunction // test endmodule // main iverilog-12_0/ivtest/ivltests/function4.v000066400000000000000000000025741435245347300206520ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This problem shows the case of a function with no input ports, * and also a function with a parameter (not a port). * * A function without an argument is an error, so this should fail. */ module main; function [3:0] test; parameter a = 3; reg [a:0] out; begin out = a; test[3:0] = out[3:0]; end endfunction reg [3:0] tmp; initial begin tmp = test(); if (tmp !== 4'b0011) begin $display("FAILED -- tmp == %b", tmp); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/function5.v000066400000000000000000000014001435245347300206360ustar00rootroot00000000000000// Submitted as PR184 by Matt Welland module test; wire foo; reg [1:49] bar; function foobar; input [1:49] a; begin foobar = a[1] & a[2] & a[3] & a[4] & a[5] & a[6] & a[7] & a[8] & a[9] & a[10] & a[11] & a[12] & a[13] & a[14] & a[15] & a[16] & a[17] & a[18] & a[19] & a[20] & a[21] & a[22] & a[23] & a[24] & a[25] & a[26] & a[27] & a[28] & a[29] & a[30] & a[31] & a[32] & a[33] & a[34] & a[35] & a[36] & a[37] & a[38] & a[39] & a[40] & a[41] & a[42] & a[43] & a[44] & a[45] & a[46] & a[47] & a[48] & a[49] ; end endfunction assign foo = foobar( bar ); endmodule iverilog-12_0/ivtest/ivltests/function6.v000066400000000000000000000005261435245347300206470ustar00rootroot00000000000000module test; function f_0; input i; begin f_0 = f_1(i); end endfunction function f_1; input i; begin f_1 = !i; end endfunction wire w = f_0(1'b0); initial begin #1; if ( w !== 1'b1) $display ("FAILED w (%b) !== 1'b1", w); else $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/function7.v000066400000000000000000000013001435245347300206370ustar00rootroot00000000000000module test; parameter BYTES = 2; localparam mxbit = BYTES*8-1; function integer clog2; input value; integer value; for (clog2=0; value>0; clog2=clog2+1) value = value >> 1; endfunction // This is not recognized as a constant function call! localparam cntrw = clog2(mxbit); integer tmp; initial begin tmp = mxbit; $display("The maximum bit is %0d and uses a %0d bit counter", mxbit, cntrw); $display("clog2 does works here! Got %0d, should be %0d.", clog2(mxbit), clog2(tmp)); if (cntrw !== clog2(tmp)) begin $display("FAILED -- cntrw=%0d", cntrw); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/function8.v000066400000000000000000000025561435245347300206560ustar00rootroot00000000000000// Test constant functions. module main; localparam BYTESIZE = 8; localparam STRLEN = 4; function [STRLEN*BYTESIZE - 1 : 0] bits2text; input [STRLEN-1:0] use_map; integer idx; begin bits2text = 0; for (idx = 0 ; idx < STRLEN ; idx = idx+1) begin bits2text[(idx*BYTESIZE) +: BYTESIZE] = (use_map[idx] == 1'b0)? "1" : "0"; end end endfunction localparam [STRLEN*BYTESIZE - 1 : 0] str0010 = bits2text(4'b0010); localparam [STRLEN*BYTESIZE - 1 : 0] str0100 = bits2text(4'b0100); localparam [STRLEN*BYTESIZE - 1 : 0] str0011 = bits2text(4'b0011); localparam [STRLEN*BYTESIZE - 1 : 0] str1100 = bits2text(4'b1100); reg [STRLEN*BYTESIZE - 1 : 0] tmp; initial begin tmp = bits2text(4'b0010); if (tmp !== str0010) begin $display("FAILED -- str0010=%h, expect %h", str0010, tmp); $finish; end tmp = bits2text(4'b0100); if (tmp !== str0100) begin $display("FAILED -- str0100=%h, expect %h", str0100, tmp); $finish; end tmp = bits2text(4'b0011); if (tmp !== str0011) begin $display("FAILED -- str0011=%h, expect %h", str0011, tmp); $finish; end tmp = bits2text(4'b1100); if (tmp !== str1100) begin $display("FAILED -- str1100=%h, expect %h", str1100, tmp); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/function9.v000066400000000000000000000025721435245347300206550ustar00rootroot00000000000000module main; localparam BYTESIZE = 8; localparam STRLEN = 4; localparam [15:0] CHAR = "10"; function [STRLEN*BYTESIZE - 1 : 0] bits2text; input [STRLEN-1:0] use_map; integer idx; begin bits2text = 0; for (idx = 0 ; idx < STRLEN ; idx = idx+1) begin bits2text[(idx*BYTESIZE) +: BYTESIZE] = CHAR[BYTESIZE*use_map[idx] +: BYTESIZE]; end end endfunction localparam [STRLEN*BYTESIZE - 1 : 0] str0010 = bits2text(4'b0010); localparam [STRLEN*BYTESIZE - 1 : 0] str0100 = bits2text(4'b0100); localparam [STRLEN*BYTESIZE - 1 : 0] str0011 = bits2text(4'b0011); localparam [STRLEN*BYTESIZE - 1 : 0] str1100 = bits2text(4'b1100); reg [STRLEN*BYTESIZE - 1 : 0] tmp; initial begin tmp = bits2text(4'b0010); if (tmp !== str0010) begin $display("FAILED -- str0010=%h, expect %h", str0010, tmp); $finish; end tmp = bits2text(4'b0100); if (tmp !== str0100) begin $display("FAILED -- str0100=%h, expect %h", str0100, tmp); $finish; end tmp = bits2text(4'b0011); if (tmp !== str0011) begin $display("FAILED -- str0011=%h, expect %h", str0011, tmp); $finish; end tmp = bits2text(4'b1100); if (tmp !== str1100) begin $display("FAILED -- str1100=%h, expect %h", str1100, tmp); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/function_exp.v000066400000000000000000000021661435245347300214370ustar00rootroot00000000000000/* * Copyright (c) 2000 Peter monta (pmonta@pacbell.net) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; function [3:0] foo; input [3:0] x; begin foo = ~x + 1; end endfunction reg [3:0] x; wire [3:0] y; assign y = foo(x); initial begin x = 4'b0110; #1; if (y==4'b1010) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/ga_and.v000066400000000000000000000030611435245347300201420ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate and gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! and foo [15:0] (out,a,b); always @(a or b) rslt = a & b; initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA And a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_mod.v000066400000000000000000000034751435245347300201700ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate that arrays spread across the input range of an arrayed // module instantiation are supported. // module my_and (out,a,b); input [3:0] a,b; output [3:0] out; and u0 (out[0],a[0],b[0]); and u1 (out[1],a[1],b[1]); and u2 (out[2],a[2],b[2]); and u3 (out[3],a[3],b[3]); endmodule module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! my_and foo [0:3] (out,a,b); always @(a or b) rslt = a & b; initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA And a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_mod1.v000066400000000000000000000032311435245347300202370ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate that an array of modules in supported. // module my_and (out,a,b); input a,b; output out; and u0 (out,a,b); endmodule module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! my_and foo [0:15] (out,a,b); always @(a or b) rslt = a & b; initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA And a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_mod2.v000066400000000000000000000030661435245347300202460ustar00rootroot00000000000000// // Copyright (c) 2004 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; reg C; reg [1:0] in; wire [1:0] out; DFF u [1:0] (out, in, C); initial begin C <= 0; in <= 2'b00; #10 C <= 1; #10 if (out !== 2'b00) begin $display("FAILED -- out=%b, in=%b", out, in); $finish; end C <= 0; in <= 2'b10; #10 C <= 1; #10 if (out !== 2'b10) begin $display("FAILED -- out=%b, in=%b", out, in); $finish; end C <= 0; in <= 2'b01; #10 C <= 1; #10 if (out !== 2'b01) begin $display("FAILED -- out=%b, in=%b", out, in); $finish; end $display("PASSED"); end // initial begin endmodule // main module DFF(output reg Q, input D, input C); always @(posedge C) Q <= D; endmodule // DFF iverilog-12_0/ivtest/ivltests/ga_nand.v000066400000000000000000000030671435245347300203260ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate NAND gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! nand foo [15:0] (out,a,b); always @(a or b) rslt = ~(a & b); initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA NAND a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_nor.v000066400000000000000000000030611435245347300201760ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate NOR gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! nor foo [15:0] (out,a,b); always @(a or b) rslt = ~(a | b); initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'h8000; a = (a << 1) ) begin // { for(b = 16'h8000; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA NOR a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_or.v000066400000000000000000000030531435245347300200210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate OR gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! or foo [15:0] (out,a,b); always @(a or b) rslt = a | b; initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'h8000; a = (a << 1) ) begin // { for(b = 16'h8000; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA OR a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_xnor.v000066400000000000000000000031741435245347300203730ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate XNOR gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! xnor foo [15:0] (out,a,b); // This is the computed value used to determine if the gate is sane. always @(a or b) rslt = ~(a ^ b); initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA XNOR a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/ga_xor.v000066400000000000000000000031661435245347300202160ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate XOR gate vector // module main; reg globvar; wire [15:0] out; reg [15:0] a,b, rslt; reg error; // The test gate goes HERE! xor foo [15:0] (out,a,b); // This is the computed value used to determine if the gate is sane. always @(a or b) rslt = a ^ b; initial begin // { error = 0; # 1; for(a = 16'h1; a != 16'hffff; a = (a << 1) | 1) begin // { for(b = 16'hffff; b !== 16'h0; b = b >> 1) begin // { #1 ; if(out !== rslt) begin // { $display("FAILED - GA XOR a=%h,b=%h,expct=%h - rcvd=%h", a,b,rslt,out); error = 1; end // } end // } end // } if( error == 0) $display("PASSED"); end // } endmodule // main iverilog-12_0/ivtest/ivltests/galan.v000066400000000000000000000030261435245347300200140ustar00rootroot00000000000000/* Steve, I have small 8bit CPU working in Iverilog, it works if I change a line similar to the one below in the test case to assign result = (data[0] | data[1]) ? 1:0; using the test case below I get, elab_net.cc:1368: failed assertion `expr_sig->pin_count() == 1' when compiling using the standard "verilog bug.v" (verilog-20000519) This works fine in XL. Regards Gerard. PS thanks for fixing the $monitor function. It works as XL, as long as I pipe the output through uniq (./stimexe | uniq) */ module stim; wire [1:0] data; wire result; assign result = data ? 1:0; initial $display("PASSED"); endmodule // stim /* * Copyright (c) 2000 Gerard A. Allan (gaa@ee.ed.ac.uk) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ iverilog-12_0/ivtest/ivltests/gate_connect1.v000066400000000000000000000007701435245347300214470ustar00rootroot00000000000000// Test behaviour when a multi-bit expression is used as the input of // a single instance of a primitive gate. The standard is quiet about // this, but the consensus among other simulators is that the LSB of // the expression is used. module top; reg [1:0] in; wire [2:0] out; buf buf1(out[0], 1); buf buf2(out[1], 2'b01); buf buf3(out[2], in[1:0]); initial begin in = 1; #1 $display("out = %b", out); if (out === 3'b111) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/gate_connect2.v000066400000000000000000000007061435245347300214470ustar00rootroot00000000000000// Test behaviour when a multi-bit expression is used as the input of // a singleton array of a primitive gate. The standard is explicit // that this should be treated as an error. module top; reg [1:0] in; wire [2:0] out; buf buf1[0:0](out[0], 1); buf buf2[0:0](out[1], 2'b01); buf buf3[0:0](out[2], in[1:0]); initial begin in = 1; #1 $display("out = %b", out); // this should have failed at compile time $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/gen_case_opt1.v000066400000000000000000000004101435245347300214330ustar00rootroot00000000000000module top; parameter NAME = "test"; wire i = 0; generate case(NAME) "test" : assign i = 1'b1; default : ; endcase endgenerate initial begin #1 if (i !== 1'bx) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/gen_case_opt2.v000066400000000000000000000004071435245347300214420ustar00rootroot00000000000000module top; parameter NAME = "def"; wire i = 0; generate case(NAME) "test" : assign i = 1'b1; default : ; endcase endgenerate initial begin #1 if (i !== 1'b0) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/gen_case_opt3.v000066400000000000000000000004311435245347300214400ustar00rootroot00000000000000module top; parameter NAME = "skip"; wire i = 0; generate case(NAME) "test" : assign i = 1'b1; "skip" : ; default : ; endcase endgenerate initial begin #1 if (i !== 1'b0) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/generate_case.v000066400000000000000000000020071435245347300215150ustar00rootroot00000000000000module main; wire [2:0] value1, value2, value3, value4; dut #( .select(1) ) dut1(value1); dut #( .select(2) ) dut2(value2); dut #( .select(3) ) dut3(value3); dut #( .select(4) ) dut4(value4); initial begin #1 $display("value1=%d, value2=%d, value3=%d, value4=%d", value1, value2, value3, value4); if (value1 !== 1) begin $display("FAILED -- value1=%b", value1); $finish; end if (value2 !== 2) begin $display("FAILED -- value2=%b", value2); $finish; end if (value3 !== 3) begin $display("FAILED -- value3=%b", value3); $finish; end if (value4 !== 7) begin $display("FAILED -- value4=%b", value4); $finish; end $display("PASSED"); end endmodule // main module dut(output wire [2:0] value); parameter select = 0; case (select) 0: assign value = 0; 1: assign value = 1; 2: assign value = 2; 3: assign value = 3; default: assign value = 7; endcase // case endcase endmodule // dut iverilog-12_0/ivtest/ivltests/generate_case2.v000066400000000000000000000023521435245347300216020ustar00rootroot00000000000000module main; wire [2:0] value1, value2, value3, value4; dut #( .select(1) ) dut1(value1); dut #( .select(2) ) dut2(value2); dut #( .select(3) ) dut3(value3); dut #( .select(4) ) dut4(value4); initial begin #1 $display("value1=%d, value2=%d, value3=%d, value4=%d", value1, value2, value3, value4); if (value1 !== 1) begin $display("FAILED -- value1=%b", value1); $finish; end if (value2 !== 2) begin $display("FAILED -- value2=%b", value2); $finish; end if (value3 !== 3) begin $display("FAILED -- value3=%b", value3); $finish; end if (value4 !== 7) begin $display("FAILED -- value4=%b", value4); $finish; end $display("PASSED"); end endmodule // main module dut(output wire [2:0] value); parameter select = 0; case (select) 0: begin function [2:0] funfun; input integer in; funfun = in; endfunction // funfun assign value = funfun(select); end 1: begin function [2:0] funfun; input integer in; funfun = in; endfunction // funfun assign value = funfun(1); end 2: assign value = 2; 3: assign value = 3; default: assign value = 7; endcase // case endcase endmodule // dut iverilog-12_0/ivtest/ivltests/generate_case3.v000066400000000000000000000010341435245347300215770ustar00rootroot00000000000000module main; parameter COND = 1; parameter SEL = 0; parameter VAL0 = 0; parameter VAL1 = 1; parameter VAL2 = 2; wire [3:0] foo; if (COND) begin case (SEL) 0: assign foo = VAL0; 1: assign foo = VAL1; 2: assign foo = VAL2; endcase // case (SEL) end else begin assign foo = 'bx; end initial begin #1 $display("foo = %b", foo); if (foo !== VAL0) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/generate_module.v000066400000000000000000000003571435245347300220750ustar00rootroot00000000000000// Check that declaring a module inside a generate block is an error module test #( parameter A = 1 ); generate if (A) begin // Error module inner; initial $display("FAILED"); endmodule end endgenerate endmodule iverilog-12_0/ivtest/ivltests/generate_multi_loop.v000066400000000000000000000043131435245347300227670ustar00rootroot00000000000000`begin_keywords "1364-2005" module generate_multi_loop(); reg [31:0] input_value; wire [31:0] output_value; generate genvar i; genvar j; for (i = 0; i < 4; i = i + 1) begin:byte wire [7:0] byte_value; for (j = 0; j < 8; j = j + 1) begin:bit wire bit_value; buf buffer(bit_value, input_value[i*8+j]); assign byte_value[j] = bit_value; end assign output_value[i*8+7:i*8] = byte_value; end endgenerate initial begin input_value = 32'h12345678; #1; $write("byte_value ="); $write(" %b", byte[3].byte_value); $write(" %b", byte[2].byte_value); $write(" %b", byte[1].byte_value); $write(" %b", byte[0].byte_value); $write("\n"); $write("bit_value = "); $write("%b", byte[3].bit[7].bit_value); $write("%b", byte[3].bit[6].bit_value); $write("%b", byte[3].bit[5].bit_value); $write("%b", byte[3].bit[4].bit_value); $write("%b", byte[3].bit[3].bit_value); $write("%b", byte[3].bit[2].bit_value); $write("%b", byte[3].bit[1].bit_value); $write("%b", byte[3].bit[0].bit_value); $write(" "); $write("%b", byte[2].bit[7].bit_value); $write("%b", byte[2].bit[6].bit_value); $write("%b", byte[2].bit[5].bit_value); $write("%b", byte[2].bit[4].bit_value); $write("%b", byte[2].bit[3].bit_value); $write("%b", byte[2].bit[2].bit_value); $write("%b", byte[2].bit[1].bit_value); $write("%b", byte[2].bit[0].bit_value); $write(" "); $write("%b", byte[1].bit[7].bit_value); $write("%b", byte[1].bit[6].bit_value); $write("%b", byte[1].bit[5].bit_value); $write("%b", byte[1].bit[4].bit_value); $write("%b", byte[1].bit[3].bit_value); $write("%b", byte[1].bit[2].bit_value); $write("%b", byte[1].bit[1].bit_value); $write("%b", byte[1].bit[0].bit_value); $write(" "); $write("%b", byte[0].bit[7].bit_value); $write("%b", byte[0].bit[6].bit_value); $write("%b", byte[0].bit[5].bit_value); $write("%b", byte[0].bit[4].bit_value); $write("%b", byte[0].bit[3].bit_value); $write("%b", byte[0].bit[2].bit_value); $write("%b", byte[0].bit[1].bit_value); $write("%b", byte[0].bit[0].bit_value); $write("\n"); if (output_value == input_value) $display("Test passed"); else $display("Test FAILED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/generate_specify.v000066400000000000000000000003521435245347300222450ustar00rootroot00000000000000// Check that a specify block inside a generate block is an error module test #( parameter A = 1 ); generate if (A) begin specify // Error endspecify end endgenerate initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/generate_specparam.v000066400000000000000000000003531435245347300225570ustar00rootroot00000000000000// Check that declaring a specparam inside a generate block is an error module test #( parameter A = 1 ); generate if (A) begin specparam x = 10; // Error end endgenerate initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/generate_timeunit.v000066400000000000000000000003531435245347300224420ustar00rootroot00000000000000// Check that declaring a timeunit inside a generate block is an error module test #( parameter A = 1 ); generate if (A) begin timeunit 10ns/1ns; // Error end endgenerate initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/genloop.v000066400000000000000000000016241435245347300203770ustar00rootroot00000000000000/* * This is a simple test of a generate loop. */ module main; parameter SIZE = 4; wire [SIZE:0] cin; reg [SIZE-1:0] a, b; wire [SIZE-1:0] q; // This generates a ripple adder by using a generate loop to // instantiate an array of half-adders. genvar i; assign cin[0] = 0; for (i=0 ; i 0; i -= 1) begin initial array2[i] = i; end for (genvar i = 1; i < 16; i *= 2) begin initial array3[i] = i; end for (genvar i = 16; i > 0; i /= 2) begin initial array4[i] = i; end for (genvar i = 10; i > 0; i %= 2) begin initial array5[i] = i; end for (genvar i = 1; i < 16; i <<= 1) begin initial array6[i] = i; end for (genvar i = 16; i > 0; i >>= 1) begin initial array7[i] = i; end for (genvar i = 16; i > 0; i >>>= 1) begin initial array8[i] = i; end for (genvar i = 0; i < 4; i |= i + 1) begin initial array9[i] = i; end for (genvar i = 7; i > 0; i &= i - 1) begin initial array10[i] = i; end for (genvar i = 0; i < 4; i ^= i + 1) begin initial array11[i] = i; end `define check(a) if (a[i] !== i) begin \ failed = 1; \ $display("FAILED(%d): Expected %0d, got %0d.", `__LINE__, i, a[i]); \ end integer i; reg failed = 1'b0; initial begin #1 for (i = 0; i < 4; i = i + 1) begin `check(array1) end for (i = 4; i > 0; i = i - 1) begin `check(array2) end for (i = 1; i < 16; i = i * 2) begin `check(array3) end for (i = 16; i > 0; i = i / 2) begin `check(array4) end for (i = 10; i != 0; i = i % 2) begin `check(array5) end for (i = 1; i < 16; i = i << 2) begin `check(array6) end for (i = 16; i > 0; i = i >> 2) begin `check(array7) end for (i = 16; i > 0; i = i >>> 2) begin `check(array8) end for (i = 1; i < 4; i = i | (i + 1)) begin `check(array9) end for (i = 7; i > 0; i = i & (i - 1)) begin `check(array10) end for (i = 0; i < 4; i = i ^ (i + 1)) begin `check(array11) end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/genvar_inc_dec.v000066400000000000000000000016221435245347300216600ustar00rootroot00000000000000module test(); integer array1[0:3]; integer array2[1:4]; integer array3[0:3]; integer array4[1:4]; integer i; reg failed; for (genvar i = 0; i < 4; ++i) begin initial array1[i] = i; end for (genvar i = 4; i > 0; --i) begin initial array2[i] = i; end for (genvar i = 0; i < 4; i++) begin initial array3[i] = i; end for (genvar i = 4; i > 0; i--) begin initial array4[i] = i; end initial begin #1 failed = 0; for (i = 0; i < 4; ++i) begin $display(array1[i]); if (array1[i] !== i) failed = 1; end for (i = 1; i < 5; ++i) begin $display(array2[i]); if (array2[i] !== i) failed = 1; end for (i = 0; i < 4; ++i) begin $display(array3[i]); if (array3[i] !== i) failed = 1; end for (i = 1; i < 5; ++i) begin $display(array4[i]); if (array4[i] !== i) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/genvar_scopes.v000066400000000000000000000017751435245347300216010ustar00rootroot00000000000000module genvar_scopes(); // This test is designed to check that genvars can be declared // within a generate block and do not collide with genvars of // the same name declared in the enclosing scope. genvar i; genvar j; reg [1:0] a[1:0]; wire [1:0] b[1:0]; wire [1:0] c[1:0]; wire [1:0] d[1:0]; for (i = 0; i < 2; i = i + 1) begin for (j = 0; j < 2; j = j + 1) begin assign b[i][j] = a[i][j]; end end for (i = 0; i < 2; i = i + 1) begin genvar j; for (j = 0; j < 2; j = j + 1) begin assign c[i][j] = a[i][j]; end end for (j = 0; j < 2; j = j + 1) begin genvar k; for (k = 0; k < 2; k = k + 1) begin assign d[j][k] = a[j][k]; end end initial begin a[0] = 2'b01; a[1] = 2'b10; #1; $display("%b %b", b[0], b[1]); $display("%b %b", c[0], c[1]); $display("%b %b", d[0], d[1]); if ((b[0] === 2'b01) && (b[1] === 2'b10) && (c[0] === 2'b01) && (c[1] === 2'b10) && (d[0] === 2'b01) && (d[1] === 2'b10)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/gh161a.v000066400000000000000000000016661435245347300177310ustar00rootroot00000000000000 module test(); typedef struct packed { logic [31:0] sub_local; } row_entry_t; typedef struct packed { logic [31:0] row_local; row_entry_t sub; row_entry_t [1:0] sub_list; } row_t; row_t main; initial begin main.row_local = 32'hCAFE; main.sub.sub_local = 32'h00000001; main.sub_list[0].sub_local = 32'hACE; main.sub_list[1].sub_local = 32'hECA; $display("main=0x%08X", main); if (main !== 128'h0000cafe0000000100000eca00000ace) begin $display("FAILED -- main != 128'h0000cafe0000000100000eca00000ace"); $finish; end $display("main.row_local=0x%08X", main.row_local); $display("main.sub=0x%08X", main.sub); //$display("0x%08X", main.sub.sub_local); //$display("0x%08X", main.sub_list[0].sub_local); $display("PASSED"); $finish(); end endmodule iverilog-12_0/ivtest/ivltests/gh161b.v000066400000000000000000000027301435245347300177230ustar00rootroot00000000000000 module test(); typedef struct packed { logic [31:0] sub_local; } row_entry_t; typedef struct packed { logic [31:0] row_local; row_entry_t sub; row_entry_t [1:0] sub_list; } row_t; row_t main; initial begin main.row_local = 32'hCAFE; main.sub.sub_local = 32'h00000001; main.sub_list[0].sub_local = 32'hACE; main.sub_list[1].sub_local = 32'hECA; $display("main=0x%08X", main); if (main !== 128'h0000cafe0000000100000eca00000ace) begin $display("FAILED -- main != 128'h0000cafe0000000100000eca00000ace"); $finish; end $display("main.row_local=0x%08X", main.row_local); $display("main.sub=0x%08X", main.sub); $display("main.sub.sub_local=0x%08X", main.sub.sub_local); if (main.sub.sub_local !== 32'h00000001) begin $display("FAILED -- main.sub.sub_local != 32'h00000001"); $finish; end $display("main.sub_list[0].sub_local=0x%08X", main.sub_list[0].sub_local); if (main.sub_list[0].sub_local !== 32'hACE) begin $display("FAILED -- main.sub.sub_local != 32'h00000ace"); $finish; end $display("main.sub_list[1].sub_local=0x%08X", main.sub_list[1].sub_local); if (main.sub_list[1].sub_local !== 32'hECA) begin $display("FAILED -- main.sub.sub_local != 32'h00000eca"); $finish; end $display("PASSED"); $finish(); end endmodule iverilog-12_0/ivtest/ivltests/gxor.vhd000066400000000000000000000016151435245347300202270ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity gxor is port (a, b: in std_logic; z : out std_logic); end gxor; architecture gxor_rtl of gxor is begin z <= a xor b; end architecture gxor_rtl; library ieee; use ieee.std_logic_1164.all; entity gxor_reduce is generic (half_width: integer := 4); port (a: in std_logic_vector (2*half_width-1 downto 0); ar: out std_logic); end gxor_reduce; architecture gxor_reduce_rtl of gxor_reduce is component gxor is port (a, b: in std_logic; z : out std_logic); end component; --type path is array (0 to size/2) of std_logic; signal x_int: std_logic_vector (2*half_width downto 0); begin x_int(2*half_width) <= '0'; -- MSB gen_xor: for i in 2*half_width downto 1 generate each_gate: gxor port map (a => x_int(i), b => a(i-1), z => x_int(i-1) ); end generate; ar <= x_int(0); end architecture gxor_reduce_rtl; iverilog-12_0/ivtest/ivltests/hello1.v000066400000000000000000000020731435245347300201170ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This trivial test has triggered problems with the empty parameter * is encountered. The output should be: "Hello, World." */ module main; initial begin $display("Hello,",,"World."); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/hier_ref_error.v000066400000000000000000000001531435245347300217240ustar00rootroot00000000000000module hier_ref_error(); task my_task; begin:block end endtask initial my_task.missing = 0; endmodule iverilog-12_0/ivtest/ivltests/hierspace.v000066400000000000000000000025341435245347300207000ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: hierspace.v,v 1.1 2001/06/26 00:32:18 sib4 Exp $ // $Log: hierspace.v,v $ // Revision 1.1 2001/06/26 00:32:18 sib4 // Two new tests for identifier parsing/elaboration // // // IVL parser test for hierarchical names. module a; wire b ; m inst (b); initial begin #1 inst.x <= 1'b0; #1 inst .x <= 1'bx; #1 inst. x <= 1'bz; #1 inst . x <= 1'b1; #1; if (b === 1'b1) $display("PASSED"); else $display("FAILED"); end endmodule module m (x); output x; reg x; endmodule iverilog-12_0/ivtest/ivltests/ibit_test.v000066400000000000000000000052501435245347300207210ustar00rootroot00000000000000// Three basic tests in here: // 1. bit must be initialised before any initial or always block // 2. assignments to (unsigned) bits with random numbers // 3. assignments to (unsigned) bits with random values including X and Z module ibit_test; parameter TRIALS = 100; parameter MAX = 32768; reg unsigned [14:0] ar; // should it be "reg unsigned [7:0] aw"? reg unsigned [14:0] ar_xz; // same as above here? reg unsigned [14:0] ar_expected; // and here bit unsigned [14:0] bu; bit unsigned [14:0] bu_xz; integer i; assign bu = ar; assign bu_xz = ar_xz; // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 15'b0 | bu_xz != 15'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // random numbers for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to bits: %b", bu); $finish; end end # 1; // with 'x injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to bits (when 'x): %b", bu); $finish; end end # 1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [15:0] xz_inject (input reg unsigned [15:0] value); // should it be "input unsigned [15:0]" instead? integer i, temp; begin temp = {$random} % MAX; for (i=0; i<15; i=i+1) begin if (temp[i] == 1'b1) begin temp = $random % MAX; if (temp <= 0) value[i] = 1'bx; // 'x noise else value[i] = 1'bz; // 'z noise end end xz_inject = value; end endfunction // this function returns bit positions with either X or Z to 0 for an input value function [15:0] xz_expected (input reg unsigned [15:0] value_xz); // should it be "input unsigned [15:0] instead? integer i; begin for (i=0; i<15; i=i+1) begin if (value_xz[i] === 1'bx || value_xz[i] === 1'bz ) value_xz[i] = 1'b0; // forced to zero end xz_expected = value_xz; end endfunction endmodule iverilog-12_0/ivtest/ivltests/ibyte_test.v000066400000000000000000000051331435245347300211060ustar00rootroot00000000000000// Three basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (unsigned) bytes with random numbers // 3. assignments to (unsigned) bytes with random values including X and Z module ibyte_test; parameter TRIALS = 100; parameter MAX = 256; reg [7:0] ar; // should it be "reg unsigned [7:0] aw"? reg [7:0] ar_xz; // same as above here? reg [7:0] ar_expected; // and here byte unsigned bu; byte unsigned bu_xz; integer i; assign bu = ar; assign bu_xz = ar_xz; // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 8'b0 | bu_xz != 8'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // random numbers for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // with 'x injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x): %b", bu); $finish; end end # 1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [7:0] xz_inject (input [7:0] value); // should it be "input unsigned [7:0]" instead? integer i, temp; begin temp = {$random} % MAX; for (i=0; i<8; i=i+1) begin if (temp[i] == 1'b1) begin temp = $random % MAX; if (temp <= 0) value[i] = 1'bx; // 'x noise else value[i] = 1'bz; // 'z noise end end xz_inject = value; end endfunction // this function returns bit positions with either X or Z to 0 for an input value function [7:0] xz_expected (input [7:0] value_xz); // should it be "input unsigned [7:0] instead? integer i; begin for (i=0; i<8; i=i+1) begin if (value_xz[i] === 1'bx || value_xz[i] === 1'bz ) value_xz[i] = 1'b0; // forced to zero end xz_expected = value_xz; end endfunction endmodule iverilog-12_0/ivtest/ivltests/idiv1.v000066400000000000000000000050751435245347300177540ustar00rootroot00000000000000// // Copyright (c) 1999 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Test the divide (/) operator module top () ; reg [7:0] a, b, result; wire [7:0] wa, wb, wresult; assign wa = a; assign wb = b; assign wresult = wa / wb; always @(a or b) result = a / b; initial begin #1 a = 0; b = 1; # 1; if( result !== 8'b0) begin $display("FAILED - Divide 0/1 reg assign failed - is %b",result); $finish; end if( wresult !== 8'b0) begin $display("FAILED - Divide 0/1 wire assign failed - is %b",wresult); $finish; end #1 a = 1; #1 if( result !== 8'b1) begin $display("FAILED - Divide 1/1 reg assign failed - is %b",result); $finish; end if( wresult !== 8'b1) begin $display("FAILED - Divide 1/1 wire assign failed - is %b",wresult); $finish; end #1 a = 5; b = 2; #1 if( result !== 8'd2) begin $display("FAILED - Divide 5/2 reg assign failed - is %b",result); $finish; end if( wresult !== 8'd2) begin $display("FAILED - Divide 5/2 wire assign failed - is %b",wresult); $finish; end #1 a = 8'd255; b = 5; #1 if( result !== 51) begin $display("FAILED - Divide 255/5 reg assign failed - is %b",result); $finish; end if( wresult !== 51) begin $display("FAILED - Divide 255/5 wire assign failed - is %b",wresult); $finish; end #1 a = 1'bx; b = 3; #1 if( result !== 8'bxxxx_xxxx) begin $display("FAILED - Divide x/3 reg assign failed - is %b",result); $finish; end if( wresult !== 8'bxxxx_xxxx) begin $display("FAILED - Divide x/3 wire assign failed - is %b",wresult); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/idiv2.v000066400000000000000000000025661435245347300177570ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This is a check of the implementation of division and multiplication * within more complex expressions. */ module test; task mod; input [31:0] a; input [15:0] b; output [31:0] out; begin out = a-(a/b)*b; end endtask reg [31:0] result,c, nl; initial begin c = 13; nl = 3; mod(c, nl, result); $display("13 %% 3 = %d", result); if (result !== 32'h00_00_00_01) begin $display("FAILED -- result is %b", result); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/idiv3.v000066400000000000000000000021271435245347300177510ustar00rootroot00000000000000/* * Copyright (c) 2002 Simon Denman * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // // File: DivBug.v // Author: Simon Denman // Created: 28/3/02 // Description: integer division bug test module DivBug ; integer intX, intY; initial begin intX = -8; intY = intX / 8; $display("%5d %5d", intX, intY); end endmodule iverilog-12_0/ivtest/ivltests/if_part_no_else.v000066400000000000000000000021561435245347300220650ustar00rootroot00000000000000 module test (output reg [1:0] foo, input wire in0, en0, input wire in1, en1 /* */); localparam foo_default = 2'b00; always @* begin foo = foo_default; if (en0) foo[0] = in0; if (en1) foo[1] = in1; end endmodule // test module main; wire [1:0] foo; reg in0, en0; reg in1, en1; test dut (.foo(foo), .in0(in0), .in1(in1), .en0(en0), .en1(en1)); initial begin in0 = 1; in1 = 1; en0 = 0; en1 = 0; #1 if (foo !== 2'b00) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b", foo, in1, in0, en1, en0); $finish; end en0 = 1; #1 if (foo !== 2'b01) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b", foo, in1, in0, en1, en0); $finish; end en0 = 0; en1 = 1; #1 if (foo !== 2'b10) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b", foo, in1, in0, en1, en0); $finish; end en0 = 1; en1 = 1; #1 if (foo !== 2'b11) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b", foo, in1, in0, en1, en0); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/if_part_no_else2.v000066400000000000000000000036301435245347300221450ustar00rootroot00000000000000 module test (output reg [1:0] foo, input wire [1:0] addr, input wire in0, in1, input wire en0, en1 /* */); localparam foo_default = 2'b00; always @* begin foo = foo_default; case (addr) 0: if (en0) foo[0] = in0; 1: if (en1) foo[1] = in1; 2: foo = {in1, in0}; default: foo = 0; endcase end endmodule // test module main; wire [1:0] foo; reg [1:0] addr; reg in0, in1; reg en0, en1; test dut(.foo(foo), .addr(addr), .in0(in0), .in1(in1), .en0(en0), .en1(en1)); initial begin in0 = 1; in1 = 1; en0 = 1; en1 = 1; addr = 3; #1 if (foo !== 2'b00) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b, addr=%b", foo, in1, in0, en1, en0, addr); $finish; end addr = 0; #1 if (foo !== 2'b01) begin $display("FAILED -- foo=%b, in=%b%b, addr=%b", foo, in1, in0, addr); $finish; end addr = 1; #1 if (foo !== 2'b10) begin $display("FAILED -- foo=%b, in=%b%b, addr=%b", foo, in1, in0, addr); $finish; end addr = 2; #1 if (foo !== 2'b11) begin $display("FAILED -- foo=%b, in=%b%b, addr=%b", foo, in1, in0, addr); $finish; end en0 = 0; en1 = 0; addr = 3; #1 if (foo !== 2'b00) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b, addr=%b", foo, in1, in0, en1, en0, addr); $finish; end addr = 0; #1 if (foo !== 2'b00) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b, addr=%b", foo, in1, in0, en1, en0, addr); $finish; end addr = 1; #1 if (foo !== 2'b00) begin $display("FAILED -- foo=%b, in=%b%b, addr=%b", foo, in1, in0, addr); $finish; end addr = 2; #1 if (foo !== 2'b11) begin $display("FAILED -- foo=%b, in=%b%b, en=%b%b, addr=%b", foo, in1, in0, en1, en0, addr); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ifdef1.v000066400000000000000000000021511435245347300200660ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Basic ifdef test // module ifdef1; reg error ; `ifdef NOCODE initial begin #20; error = 1; #20; end `endif initial begin #1; error = 0; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ifdef2.v000066400000000000000000000022051435245347300200670ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Basic ifdef test with define // `define NOCODE module ifdef2; reg error ; `ifdef NOCODE initial begin #20; error = 0; #20; end `endif initial begin #1; error = 1; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ifdef3.v000066400000000000000000000023001435245347300200640ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Compound ifdef (two) with interior not defined // `define DOUBLE module ifdef1; reg error ; `ifdef DOUBLE `ifdef NOCODE initial begin #20; error = 1; #20; end `endif // NOCODE `endif // DOUBLE initial begin #1; error = 0; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ifdef4.v000066400000000000000000000023021435245347300200670ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Compount ifdef test with 2 defines // `define DOUBLE `define NOCODE module ifdef2; reg error ; `ifdef DOUBLE `ifdef NOCODE initial begin #20; error = 0; #20; end `endif // NOCODE `endif // DOUBLE initial begin #1; error = 1; #40; if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ifdef_fail.v000066400000000000000000000001451435245347300210010ustar00rootroot00000000000000module if_fail_test(); `ifdef `ifndef `elsif `else `endif initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/iint_test.v000066400000000000000000000051531435245347300207370ustar00rootroot00000000000000// Three basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (unsigned) bytes with random numbers // 3. assignments to (unsigned) bytes with random values including X and Z module ibyte_test; parameter TRIALS = 100; parameter MAX = 'h7fffffff; reg [31:0] ar; // should it be "reg unsigned [7:0] aw"? reg [31:0] ar_xz; // same as above here? reg [31:0] ar_expected; // and here int unsigned bu; int unsigned bu_xz; integer i; assign bu = ar; assign bu_xz = ar_xz; // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 32'b0 | bu_xz != 32'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // random numbers for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // with 'x injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x): %b", bu); $finish; end end # 1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [31:0] xz_inject (input [31:0] value); // should it be "input unsigned [7:0]" instead? integer i, temp; begin temp = {$random} % MAX; for (i=0; i<32; i=i+1) begin if (temp[i] == 1'b1) begin temp = $random % MAX; if (temp <= 0) value[i] = 1'bx; // 'x noise else value[i] = 1'bz; // 'z noise end end xz_inject = value; end endfunction // this function returns bit positions with either X or Z to 0 for an input value function [31:0] xz_expected (input [31:0] value_xz); // should it be "input unsigned [7:0] instead? integer i; begin for (i=0; i<32; i=i+1) begin if (value_xz[i] === 1'bx || value_xz[i] === 1'bz ) value_xz[i] = 1'b0; // forced to zero end xz_expected = value_xz; end endfunction endmodule iverilog-12_0/ivtest/ivltests/ilongint_test.v000066400000000000000000000051741435245347300216220ustar00rootroot00000000000000// Three basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (unsigned) bytes with random numbers // 3. assignments to (unsigned) bytes with random values including X and Z module ibyte_test; parameter TRIALS = 100; parameter MAX = 'h7fffffff_ffffffff; reg [63:0] ar; // should it be "reg unsigned [7:0] aw"? reg [63:0] ar_xz; // same as above here? reg [63:0] ar_expected; // and here longint unsigned bu; longint unsigned bu_xz; integer i; assign bu = ar; assign bu_xz = ar_xz; // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 64'b0 | bu_xz != 64'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // random numbers for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // with 'x injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x): %b", bu); $finish; end end # 1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [63:0] xz_inject (input [63:0] value); // should it be "input unsigned [7:0]" instead? integer i, temp; begin temp = {$random} % MAX; for (i=0; i<64; i=i+1) begin if (temp[i] == 1'b1) begin temp = $random % MAX; if (temp <= 0) value[i] = 1'bx; // 'x noise else value[i] = 1'bz; // 'z noise end end xz_inject = value; end endfunction // this function returns bit positions with either X or Z to 0 for an input value function [63:0] xz_expected (input [63:0] value_xz); // should it be "input unsigned [7:0] instead? integer i; begin for (i=0; i<64; i=i+1) begin if (value_xz[i] === 1'bx || value_xz[i] === 1'bz ) value_xz[i] = 1'b0; // forced to zero end xz_expected = value_xz; end endfunction endmodule iverilog-12_0/ivtest/ivltests/implicit-port1.v000066400000000000000000000006661435245347300216160ustar00rootroot00000000000000// test basic implicit ports work module m(input a, output b, output c); assign b = a; assign c = ~a; endmodule module top; reg a; wire b, d; m foo(.a, .b, .c(d)); initial begin a = 0; #1 if (b !== a || d !== ~a) begin $display("FAILED -- a=%b, b=%b, d=%b", a, b, d); end #1 a = 1; #1 if (b !== a || d !== ~a) begin $display("FAILED -- a=%b, b=%b, d=%b", a, b, d); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit-port2.v000066400000000000000000000002521435245347300216060ustar00rootroot00000000000000// test that if the signal doesn't exist, an error is thrown module m(input a, output b); assign b = a; endmodule module top; reg a; // wire b; m foo(.a, .b); endmodule iverilog-12_0/ivtest/ivltests/implicit-port3.v000066400000000000000000000002611435245347300216070ustar00rootroot00000000000000// test that if the port doesn't exist, an error is thrown module m(input a, output b); assign b = a; endmodule module top; reg a; wire b; wire c; m foo(.a, .b, .c); endmodule iverilog-12_0/ivtest/ivltests/implicit-port4.v000066400000000000000000000006641435245347300216170ustar00rootroot00000000000000// test that .* implicit ports work module m(input a, output b, output c); assign b = a; assign c = ~a; endmodule module top; reg a; wire b, d; m foo(.*, .c(d)); initial begin a = 0; #1 if (b !== a || d !== ~a) begin $display("FAILED -- a=%b, b=%b, d=%b", a, b, d); end #1 a = 1; #1 if (b !== a || d !== ~a) begin $display("FAILED -- a=%b, b=%b, d=%b", a, b, d); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit-port5.v000066400000000000000000000007541435245347300216200ustar00rootroot00000000000000// test that .* implicit ports work with override module m(input a, output b, output c); assign b = a; assign c = ~a; endmodule module top; reg a; reg x; wire b, d; m foo(.a(x), .*, .c(d)); initial begin a = 0; x = 1; #1 if (b !== x || d !== ~x) begin $display("FAILED -- a=%b, x=%b, b=%b, d=%b", a, x, b, d); end #1 a = 1; #1 if (b !== x || d !== ~x) begin $display("FAILED -- a=%b, x=%b, b=%b, d=%b", a, x, b, d); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit-port6.v000066400000000000000000000002461435245347300216150ustar00rootroot00000000000000// test that if the signal doesn't exist, an error is thrown module m(input a, output b); assign b = a; endmodule module top; reg a; // wire b; m foo(.*); endmodule iverilog-12_0/ivtest/ivltests/implicit-port7.v000066400000000000000000000013431435245347300216150ustar00rootroot00000000000000// test that .* implicit ports work with override module m(input a, output b, output c, output d, output e); assign b = a; assign c = ~a; assign d = ~a; assign e = ~a; endmodule module top; reg a; reg x; wire b, d; m foo(.a(x), .e(), .*, .c(d), .d()); m foo2(.a(x), .d(), .*, .c(), .e()); m foo3(.a(x), .*, .d(), .c(), .e()); m foo4(.*, .a(x), .d(), .c(), .e()); m foo5(.a(x), .d(), .c(), .*, .e()); m foo6(.a(x), .d(), .c(), .e(), .*); initial begin a = 0; x = 1; #1 if (b !== x || d !== ~x) begin $display("FAILED -- a=%b, x=%b, b=%b, d=%b", a, x, b, d); end #1 a = 1; #1 if (b !== x || d !== ~x) begin $display("FAILED -- a=%b, x=%b, b=%b, d=%b", a, x, b, d); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit1.v000066400000000000000000000015771435245347300206360ustar00rootroot00000000000000/* * From PR#379 */ `define IDLE 2'b00 `define COUNT 2'b01 `define DONE 2'b10 module Counter56 (POR, CLK, VoltageOK, ChargeDone ); input POR; input CLK; input VoltageOK; output ChargeDone; reg [1:0] CounterState, nextCounterState; wire [8:0] nextMinuteCounter; always @(posedge CLK or negedge POR) if (!POR) CounterState = 2'b00; else CounterState = nextCounterState; always @(VoltageOK or CounterReset) // CounterReset should make an error casez (CounterState) `IDLE: begin nextCounterState = (VoltageOK) ? `COUNT : `IDLE; end `COUNT: begin nextCounterState = (VoltageOK) ? `COUNT : `IDLE; end `DONE: begin nextCounterState = `DONE; end default: begin nextCounterState = 2'bxx; end endcase endmodule iverilog-12_0/ivtest/ivltests/implicit_cast1.v000066400000000000000000000142731435245347300216450ustar00rootroot00000000000000// Test implicit casts during procedural blocking assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); dst_r = src_r; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = src_u2; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = src_s2; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = src_u4; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = src_s4; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = src_ux; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = src_sx; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); dst_u2s = src_r; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = src_u2; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = src_s2; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = src_u4; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = src_s4; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = src_ux; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = src_sx; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); dst_s2s = src_r; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = src_u2; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = src_s2; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = src_u4; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = src_s4; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = src_ux; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = src_sx; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); dst_u2l = src_r; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = src_u2; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l = src_s2; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = src_u4; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l = src_s4; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = src_ux; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; dst_u2l = src_sx; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); dst_s2l = src_r; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = src_u2; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l = src_s2; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = src_u4; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l = src_s4; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = src_ux; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; dst_s2l = src_sx; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); dst_u4s = src_r; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = src_u2; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = src_s2; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = src_u4; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = src_s4; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = src_ux; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = src_sx; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); dst_s4s = src_r; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = src_u2; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = src_s2; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = src_u4; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = src_s4; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = src_ux; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = src_sx; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); dst_u4l = src_r; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = src_u2; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l = src_s2; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = src_u4; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l = src_s4; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = src_ux; $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; dst_u4l = src_sx; $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); dst_s4l = src_r; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = src_u2; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l = src_s2; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = src_u4; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l = src_s4; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = src_ux; $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; dst_s4l = src_sx; $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast10.v000066400000000000000000000170321435245347300217210ustar00rootroot00000000000000// Test implicit casts during task input assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; task cp_r(output real dst, input real src); dst = src; endtask task cp_u2s(output bit unsigned [3:0] dst, input bit unsigned [3:0] src); dst = src; endtask task cp_s2s(output bit signed [3:0] dst, input bit signed [3:0] src); dst = src; endtask task cp_u2l(output bit unsigned [11:0] dst, input bit unsigned [11:0] src); dst = src; endtask task cp_s2l(output bit signed [11:0] dst, input bit signed [11:0] src); dst = src; endtask task cp_u4s(output logic unsigned [3:0] dst, input logic unsigned [3:0] src); dst = src; endtask task cp_s4s(output logic signed [3:0] dst, input logic signed [3:0] src); dst = src; endtask task cp_u4l(output logic unsigned [11:0] dst, input logic unsigned [11:0] src); dst = src; endtask task cp_s4l(output logic signed [11:0] dst, input logic signed [11:0] src); dst = src; endtask bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); cp_r(dst_r, src_r); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_r(dst_r, src_u2); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_r(dst_r, src_s2); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_r(dst_r, src_u4); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_r(dst_r, src_s4); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_r(dst_r, src_ux); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_r(dst_r, src_sx); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); cp_u2s(dst_u2s, src_r); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u2s(dst_u2s, src_u2); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_u2s(dst_u2s, src_s2); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u2s(dst_u2s, src_u4); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_u2s(dst_u2s, src_s4); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u2s(dst_u2s, src_ux); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_u2s(dst_u2s, src_sx); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); cp_s2s(dst_s2s, src_r); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_s2s(dst_s2s, src_u2); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s2s(dst_s2s, src_s2); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_s2s(dst_s2s, src_u4); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s2s(dst_s2s, src_s4); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_s2s(dst_s2s, src_ux); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s2s(dst_s2s, src_sx); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); cp_u2l(dst_u2l, src_r); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u2l(dst_u2l, src_u2); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; cp_u2l(dst_u2l, src_s2); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u2l(dst_u2l, src_u4); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; cp_u2l(dst_u2l, src_s4); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u2l(dst_u2l, src_ux); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; cp_u2l(dst_u2l, src_sx); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); cp_s2l(dst_s2l, src_r); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_s2l(dst_s2l, src_u2); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; cp_s2l(dst_s2l, src_s2); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_s2l(dst_s2l, src_u4); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; cp_s2l(dst_s2l, src_s4); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_s2l(dst_s2l, src_ux); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; cp_s2l(dst_s2l, src_sx); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); cp_u4s(dst_u4s, src_r); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u4s(dst_u4s, src_u2); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_u4s(dst_u4s, src_s2); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u4s(dst_u4s, src_u4); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_u4s(dst_u4s, src_s4); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u4s(dst_u4s, src_ux); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_u4s(dst_u4s, src_sx); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); cp_s4s(dst_s4s, src_r); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_s4s(dst_s4s, src_u2); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s4s(dst_s4s, src_s2); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_s4s(dst_s4s, src_u4); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s4s(dst_s4s, src_s4); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_s4s(dst_s4s, src_ux); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s4s(dst_s4s, src_sx); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); cp_u4l(dst_u4l, src_r); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u4l(dst_u4l, src_u2); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; cp_u4l(dst_u4l, src_s2); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u4l(dst_u4l, src_u4); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; cp_u4l(dst_u4l, src_s4); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u4l(dst_u4l, src_ux); $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; cp_u4l(dst_u4l, src_sx); $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); cp_s4l(dst_s4l, src_r); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_s4l(dst_s4l, src_u2); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; cp_s4l(dst_s4l, src_s2); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_s4l(dst_s4l, src_u4); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; cp_s4l(dst_s4l, src_s4); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_s4l(dst_s4l, src_ux); $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; cp_s4l(dst_s4l, src_sx); $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast11.v000066400000000000000000000160461435245347300217260ustar00rootroot00000000000000// Test implicit casts during task output assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; task cp_r(output real dst, input real src); dst = src; endtask task cp_u2(output bit unsigned [7:0] dst, input bit unsigned [7:0] src); dst = src; endtask task cp_s2(output bit signed [7:0] dst, input bit signed [7:0] src); dst = src; endtask task cp_u4(output logic unsigned [7:0] dst, input logic unsigned [7:0] src); dst = src; endtask task cp_s4(output logic signed [7:0] dst, input logic signed [7:0] src); dst = src; endtask bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); cp_r (dst_r, src_r); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_u2(dst_r, src_u2); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_s2(dst_r, src_s2); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_u4(dst_r, src_u4); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_s4(dst_r, src_s4); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; cp_u4(dst_r, src_ux); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; cp_s4(dst_r, src_sx); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); cp_r (dst_u2s, src_r); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u2(dst_u2s, src_u2); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_s2(dst_u2s, src_s2); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u4(dst_u2s, src_u4); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_s4(dst_u2s, src_s4); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; cp_u4(dst_u2s, src_ux); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; cp_s4(dst_u2s, src_sx); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); cp_r (dst_s2s, src_r); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_u2(dst_s2s, src_u2); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s2(dst_s2s, src_s2); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_u4(dst_s2s, src_u4); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s4(dst_s2s, src_s4); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; cp_u4(dst_s2s, src_ux); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; cp_s4(dst_s2s, src_sx); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); cp_r (dst_u2l, src_r); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u2(dst_u2l, src_u2); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; cp_s2(dst_u2l, src_s2); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u4(dst_u2l, src_u4); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; cp_s4(dst_u2l, src_s4); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; cp_u4(dst_u2l, src_ux); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; cp_s4(dst_u2l, src_sx); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); cp_r (dst_s2l, src_r); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_u2(dst_s2l, src_u2); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; cp_s2(dst_s2l, src_s2); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_u4(dst_s2l, src_u4); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; cp_s4(dst_s2l, src_s4); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; cp_u4(dst_s2l, src_ux); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; cp_s4(dst_s2l, src_sx); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); cp_r (dst_u4s, src_r); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u2(dst_u4s, src_u2); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_s2(dst_u4s, src_s2); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u4(dst_u4s, src_u4); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_s4(dst_u4s, src_s4); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; cp_u4(dst_u4s, src_ux); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; cp_s4(dst_u4s, src_sx); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); cp_r (dst_s4s, src_r); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_u2(dst_s4s, src_u2); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s2(dst_s4s, src_s2); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_u4(dst_s4s, src_u4); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s4(dst_s4s, src_s4); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; cp_u4(dst_s4s, src_ux); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; cp_s4(dst_s4s, src_sx); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); cp_r (dst_u4l, src_r); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u2(dst_u4l, src_u2); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; cp_s2(dst_u4l, src_s2); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u4(dst_u4l, src_u4); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; cp_s4(dst_u4l, src_s4); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; cp_u4(dst_u4l, src_ux); $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; cp_s4(dst_u4l, src_sx); $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); cp_r (dst_s4l, src_r); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_u2(dst_s4l, src_u2); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; cp_s2(dst_s4l, src_s2); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_u4(dst_s4l, src_u4); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; cp_s4(dst_s4l, src_s4); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; cp_u4(dst_s4l, src_ux); $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; cp_s4(dst_s4l, src_sx); $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast12.v000066400000000000000000000255441435245347300217320ustar00rootroot00000000000000// Test implicit casts during module input assignments. `ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif `ifdef SUPPORT_REAL_NETS_IN_IVTEST module cp_r(output wire real dst, input wire real src); assign dst = src; endmodule `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST module cp_u2s(output wire bit unsigned [3:0] dst, input wire bit unsigned [3:0] src); assign dst = src; endmodule module cp_s2s(output wire bit signed [3:0] dst, input wire bit signed [3:0] src); assign dst = src; endmodule module cp_u2l(output wire bit unsigned [11:0] dst, input wire bit unsigned [11:0] src); assign dst = src; endmodule module cp_s2l(output wire bit signed [11:0] dst, input wire bit signed [11:0] src); assign dst = src; endmodule `endif module cp_u4s(output wire logic unsigned [3:0] dst, input wire logic unsigned [3:0] src); assign dst = src; endmodule module cp_s4s(output wire logic signed [3:0] dst, input wire logic signed [3:0] src); assign dst = src; endmodule module cp_u4l(output wire logic unsigned [11:0] dst, input wire logic unsigned [11:0] src); assign dst = src; endmodule module cp_s4l(output wire logic signed [11:0] dst, input wire logic signed [11:0] src); assign dst = src; endmodule module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real dst1_r; wire real dst2_r; wire real dst3_r; wire real dst4_r; wire real dst5_r; wire real dst6_r; wire real dst7_r; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire bit unsigned [3:0] dst1_u2s; wire bit unsigned [3:0] dst2_u2s; wire bit unsigned [3:0] dst3_u2s; wire bit unsigned [3:0] dst4_u2s; wire bit unsigned [3:0] dst5_u2s; wire bit unsigned [3:0] dst6_u2s; wire bit unsigned [3:0] dst7_u2s; wire bit signed [3:0] dst1_s2s; wire bit signed [3:0] dst2_s2s; wire bit signed [3:0] dst3_s2s; wire bit signed [3:0] dst4_s2s; wire bit signed [3:0] dst5_s2s; wire bit signed [3:0] dst6_s2s; wire bit signed [3:0] dst7_s2s; wire bit unsigned [11:0] dst1_u2l; wire bit unsigned [11:0] dst2_u2l; wire bit unsigned [11:0] dst3_u2l; wire bit unsigned [11:0] dst4_u2l; wire bit unsigned [11:0] dst5_u2l; wire bit unsigned [11:0] dst6_u2l; wire bit unsigned [11:0] dst7_u2l; wire bit signed [11:0] dst1_s2l; wire bit signed [11:0] dst2_s2l; wire bit signed [11:0] dst3_s2l; wire bit signed [11:0] dst4_s2l; wire bit signed [11:0] dst5_s2l; wire bit signed [11:0] dst6_s2l; wire bit signed [11:0] dst7_s2l; `endif wire logic unsigned [3:0] dst1_u4s; wire logic unsigned [3:0] dst2_u4s; wire logic unsigned [3:0] dst3_u4s; wire logic unsigned [3:0] dst4_u4s; wire logic unsigned [3:0] dst5_u4s; wire logic unsigned [3:0] dst6_u4s; wire logic unsigned [3:0] dst7_u4s; wire logic signed [3:0] dst1_s4s; wire logic signed [3:0] dst2_s4s; wire logic signed [3:0] dst3_s4s; wire logic signed [3:0] dst4_s4s; wire logic signed [3:0] dst5_s4s; wire logic signed [3:0] dst6_s4s; wire logic signed [3:0] dst7_s4s; wire logic unsigned [11:0] dst1_u4l; wire logic unsigned [11:0] dst2_u4l; wire logic unsigned [11:0] dst3_u4l; wire logic unsigned [11:0] dst4_u4l; wire logic unsigned [11:0] dst5_u4l; wire logic unsigned [11:0] dst6_u4l; wire logic unsigned [11:0] dst7_u4l; wire logic signed [11:0] dst1_s4l; wire logic signed [11:0] dst2_s4l; wire logic signed [11:0] dst3_s4l; wire logic signed [11:0] dst4_s4l; wire logic signed [11:0] dst5_s4l; wire logic signed [11:0] dst6_s4l; wire logic signed [11:0] dst7_s4l; `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_r(dst1_r, src_r); cp_r cp2_r(dst2_r, src_u2); cp_r cp3_r(dst3_r, src_s2); cp_r cp4_r(dst4_r, src_u4); cp_r cp5_r(dst5_r, src_s4); cp_r cp6_r(dst6_r, src_ux); cp_r cp7_r(dst7_r, src_sx); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2s cp1_u2s(dst1_u2s, src_r); cp_u2s cp2_u2s(dst2_u2s, src_u2); cp_u2s cp3_u2s(dst3_u2s, src_s2); cp_u2s cp4_u2s(dst4_u2s, src_u4); cp_u2s cp5_u2s(dst5_u2s, src_s4); cp_u2s cp6_u2s(dst6_u2s, src_ux); cp_u2s cp7_u2s(dst7_u2s, src_sx); cp_s2s cp1_s2s(dst1_s2s, src_r); cp_s2s cp2_s2s(dst2_s2s, src_u2); cp_s2s cp3_s2s(dst3_s2s, src_s2); cp_s2s cp4_s2s(dst4_s2s, src_u4); cp_s2s cp5_s2s(dst5_s2s, src_s4); cp_s2s cp6_s2s(dst6_s2s, src_ux); cp_s2s cp7_s2s(dst7_s2s, src_sx); cp_u2l cp1_u2l(dst1_u2l, src_r); cp_u2l cp2_u2l(dst2_u2l, src_u2); cp_u2l cp3_u2l(dst3_u2l, src_s2); cp_u2l cp4_u2l(dst4_u2l, src_u4); cp_u2l cp5_u2l(dst5_u2l, src_s4); cp_u2l cp6_u2l(dst6_u2l, src_ux); cp_u2l cp7_u2l(dst7_u2l, src_sx); cp_s2l cp1_s2l(dst1_s2l, src_r); cp_s2l cp2_s2l(dst2_s2l, src_u2); cp_s2l cp3_s2l(dst3_s2l, src_s2); cp_s2l cp4_s2l(dst4_s2l, src_u4); cp_s2l cp5_s2l(dst5_s2l, src_s4); cp_s2l cp6_s2l(dst6_s2l, src_ux); cp_s2l cp7_s2l(dst7_s2l, src_sx); `endif cp_u4s cp1_u4s(dst1_u4s, src_r); cp_u4s cp2_u4s(dst2_u4s, src_u2); cp_u4s cp3_u4s(dst3_u4s, src_s2); cp_u4s cp4_u4s(dst4_u4s, src_u4); cp_u4s cp5_u4s(dst5_u4s, src_s4); cp_u4s cp6_u4s(dst6_u4s, src_ux); cp_u4s cp7_u4s(dst7_u4s, src_sx); cp_s4s cp1_s4s(dst1_s4s, src_r); cp_s4s cp2_s4s(dst2_s4s, src_u2); cp_s4s cp3_s4s(dst3_s4s, src_s2); cp_s4s cp4_s4s(dst4_s4s, src_u4); cp_s4s cp5_s4s(dst5_s4s, src_s4); cp_s4s cp6_s4s(dst6_s4s, src_ux); cp_s4s cp7_s4s(dst7_s4s, src_sx); cp_u4l cp1_u4l(dst1_u4l, src_r); cp_u4l cp2_u4l(dst2_u4l, src_u2); cp_u4l cp3_u4l(dst3_u4l, src_s2); cp_u4l cp4_u4l(dst4_u4l, src_u4); cp_u4l cp5_u4l(dst5_u4l, src_s4); cp_u4l cp6_u4l(dst6_u4l, src_ux); cp_u4l cp7_u4l(dst7_u4l, src_sx); cp_s4l cp1_s4l(dst1_s4l, src_r); cp_s4l cp2_s4l(dst2_s4l, src_u2); cp_s4l cp3_s4l(dst3_s4l, src_s2); cp_s4l cp4_s4l(dst4_s4l, src_u4); cp_s4l cp5_s4l(dst5_s4l, src_s4); cp_s4l cp6_s4l(dst6_s4l, src_ux); cp_s4l cp7_s4l(dst7_s4l, src_sx); bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; #1; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; `endif $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast13.v000066400000000000000000000257341435245347300217340ustar00rootroot00000000000000// Test implicit casts during module output assignments. `ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif `ifdef SUPPORT_REAL_NETS_IN_IVTEST module cp_r(output wire real dst, input wire real src); assign dst = src; endmodule `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST module cp_u2(output wire bit unsigned [7:0] dst, input wire bit unsigned [7:0] src); assign dst = src; endmodule module cp_s2(output wire bit signed [7:0] dst, input wire bit signed [7:0] src); assign dst = src; endmodule `endif module cp_u4(output wire logic unsigned [7:0] dst, input wire logic unsigned [7:0] src); assign dst = src; endmodule module cp_s4(output wire logic signed [7:0] dst, input wire logic signed [7:0] src); assign dst = src; endmodule module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real dst1_r; wire real dst2_r; wire real dst3_r; wire real dst4_r; wire real dst5_r; wire real dst6_r; wire real dst7_r; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire bit unsigned [3:0] dst1_u2s; wire bit unsigned [3:0] dst2_u2s; wire bit unsigned [3:0] dst3_u2s; wire bit unsigned [3:0] dst4_u2s; wire bit unsigned [3:0] dst5_u2s; wire bit unsigned [3:0] dst6_u2s; wire bit unsigned [3:0] dst7_u2s; wire bit signed [3:0] dst1_s2s; wire bit signed [3:0] dst2_s2s; wire bit signed [3:0] dst3_s2s; wire bit signed [3:0] dst4_s2s; wire bit signed [3:0] dst5_s2s; wire bit signed [3:0] dst6_s2s; wire bit signed [3:0] dst7_s2s; wire bit unsigned [11:0] dst1_u2l; wire bit unsigned [11:0] dst2_u2l; wire bit unsigned [11:0] dst3_u2l; wire bit unsigned [11:0] dst4_u2l; wire bit unsigned [11:0] dst5_u2l; wire bit unsigned [11:0] dst6_u2l; wire bit unsigned [11:0] dst7_u2l; wire bit signed [11:0] dst1_s2l; wire bit signed [11:0] dst2_s2l; wire bit signed [11:0] dst3_s2l; wire bit signed [11:0] dst4_s2l; wire bit signed [11:0] dst5_s2l; wire bit signed [11:0] dst6_s2l; wire bit signed [11:0] dst7_s2l; `endif wire logic unsigned [3:0] dst1_u4s; wire logic unsigned [3:0] dst2_u4s; wire logic unsigned [3:0] dst3_u4s; wire logic unsigned [3:0] dst4_u4s; wire logic unsigned [3:0] dst5_u4s; wire logic unsigned [3:0] dst6_u4s; wire logic unsigned [3:0] dst7_u4s; wire logic signed [3:0] dst1_s4s; wire logic signed [3:0] dst2_s4s; wire logic signed [3:0] dst3_s4s; wire logic signed [3:0] dst4_s4s; wire logic signed [3:0] dst5_s4s; wire logic signed [3:0] dst6_s4s; wire logic signed [3:0] dst7_s4s; wire logic unsigned [11:0] dst1_u4l; wire logic unsigned [11:0] dst2_u4l; wire logic unsigned [11:0] dst3_u4l; wire logic unsigned [11:0] dst4_u4l; wire logic unsigned [11:0] dst5_u4l; wire logic unsigned [11:0] dst6_u4l; wire logic unsigned [11:0] dst7_u4l; wire logic signed [11:0] dst1_s4l; wire logic signed [11:0] dst2_s4l; wire logic signed [11:0] dst3_s4l; wire logic signed [11:0] dst4_s4l; wire logic signed [11:0] dst5_s4l; wire logic signed [11:0] dst6_s4l; wire logic signed [11:0] dst7_s4l; `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_r(dst1_r, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_r(dst2_r, src_u2); cp_s2 cp3_r(dst3_r, src_s2); `endif cp_u4 cp4_r(dst4_r, src_u4); cp_s4 cp5_r(dst5_r, src_s4); cp_u4 cp6_r(dst6_r, src_ux); cp_s4 cp7_r(dst7_r, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_u2s(dst1_u2s, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_u2s(dst2_u2s, src_u2); cp_s2 cp3_u2s(dst3_u2s, src_s2); `endif cp_u4 cp4_u2s(dst4_u2s, src_u4); cp_s4 cp5_u2s(dst5_u2s, src_s4); cp_u4 cp6_u2s(dst6_u2s, src_ux); cp_s4 cp7_u2s(dst7_u2s, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_s2s(dst1_s2s, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_s2s(dst2_s2s, src_u2); cp_s2 cp3_s2s(dst3_s2s, src_s2); `endif cp_u4 cp4_s2s(dst4_s2s, src_u4); cp_s4 cp5_s2s(dst5_s2s, src_s4); cp_u4 cp6_s2s(dst6_s2s, src_ux); cp_s4 cp7_s2s(dst7_s2s, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_u2l(dst1_u2l, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_u2l(dst2_u2l, src_u2); cp_s2 cp3_u2l(dst3_u2l, src_s2); `endif cp_u4 cp4_u2l(dst4_u2l, src_u4); cp_s4 cp5_u2l(dst5_u2l, src_s4); cp_u4 cp6_u2l(dst6_u2l, src_ux); cp_s4 cp7_u2l(dst7_u2l, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_s2l(dst1_s2l, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_s2l(dst2_s2l, src_u2); cp_s2 cp3_s2l(dst3_s2l, src_s2); `endif cp_u4 cp4_s2l(dst4_s2l, src_u4); cp_s4 cp5_s2l(dst5_s2l, src_s4); cp_u4 cp6_s2l(dst6_s2l, src_ux); cp_s4 cp7_s2l(dst7_s2l, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_u4s(dst1_u4s, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_u4s(dst2_u4s, src_u2); cp_s2 cp3_u4s(dst3_u4s, src_s2); `endif cp_u4 cp4_u4s(dst4_u4s, src_u4); cp_s4 cp5_u4s(dst5_u4s, src_s4); cp_u4 cp6_u4s(dst6_u4s, src_ux); cp_s4 cp7_u4s(dst7_u4s, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_s4s(dst1_s4s, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_s4s(dst2_s4s, src_u2); cp_s2 cp3_s4s(dst3_s4s, src_s2); `endif cp_u4 cp4_s4s(dst4_s4s, src_u4); cp_s4 cp5_s4s(dst5_s4s, src_s4); cp_u4 cp6_s4s(dst6_s4s, src_ux); cp_s4 cp7_s4s(dst7_s4s, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_u4l(dst1_u4l, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_u4l(dst2_u4l, src_u2); cp_s2 cp3_u4l(dst3_u4l, src_s2); `endif cp_u4 cp4_u4l(dst4_u4l, src_u4); cp_s4 cp5_u4l(dst5_u4l, src_s4); cp_u4 cp6_u4l(dst6_u4l, src_ux); cp_s4 cp7_u4l(dst7_u4l, src_sx); `ifdef SUPPORT_REAL_NETS_IN_IVTEST cp_r cp1_s4l(dst1_s4l, src_r); `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST cp_u2 cp2_s4l(dst2_s4l, src_u2); cp_s2 cp3_s4l(dst3_s4l, src_s2); `endif cp_u4 cp4_s4l(dst4_s4l, src_u4); cp_s4 cp5_s4l(dst5_s4l, src_s4); cp_u4 cp6_s4l(dst6_s4l, src_ux); cp_s4 cp7_s4l(dst7_s4l, src_sx); bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; #1; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; `endif $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast2.v000066400000000000000000000146731435245347300216520ustar00rootroot00000000000000// Test implicit casts during procedural non-blocking assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); dst_r <= src_r; #1 $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r <= src_u2; #1 $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r <= src_s2; #1 $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r <= src_u4; #1 $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r <= src_s4; #1 $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r <= src_ux; #1 $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r <= src_sx; #1 $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); dst_u2s <= src_r; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s <= src_u2; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s <= src_s2; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s <= src_u4; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s <= src_s4; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s <= src_ux; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s <= src_sx; #1 $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); dst_s2s <= src_r; #1 $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s <= src_u2; #1 $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s <= src_s2; #1 $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s <= src_u4; #1 $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s <= src_s4; #1 $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s <= src_ux; #1 $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s <= src_sx; #1 $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); dst_u2l <= src_r; #1 $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l <= src_u2; #1 $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l <= src_s2; #1 $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l <= src_u4; #1 $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l <= src_s4; #1 $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l <= src_ux; #1 $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; dst_u2l <= src_sx; #1 $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); dst_s2l <= src_r; #1 $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l <= src_u2; #1 $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l <= src_s2; #1 $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l <= src_u4; #1 $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l <= src_s4; #1 $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l <= src_ux; #1 $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; dst_s2l <= src_sx; #1 $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); dst_u4s <= src_r; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s <= src_u2; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s <= src_s2; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s <= src_u4; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s <= src_s4; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s <= src_ux; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s <= src_sx; #1 $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); dst_s4s <= src_r; #1 $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s <= src_u2; #1 $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s <= src_s2; #1 $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s <= src_u4; #1 $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s <= src_s4; #1 $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s <= src_ux; #1 $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s <= src_sx; #1 $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); dst_u4l <= src_r; #1 $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l <= src_u2; #1 $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l <= src_s2; #1 $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l <= src_u4; #1 $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l <= src_s4; #1 $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l <= src_ux; #1 $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; dst_u4l <= src_sx; #1 $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); dst_s4l <= src_r; #1 $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l <= src_u2; #1 $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l <= src_s2; #1 $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l <= src_u4; #1 $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l <= src_s4; #1 $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l <= src_ux; #1 $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; dst_s4l <= src_sx; #1 $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast3.v000066400000000000000000000151741435245347300216500ustar00rootroot00000000000000// Test implicit casts during procedural continuous (reg) assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); assign dst_r = src_r; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; assign dst_r = src_u2; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; assign dst_r = src_s2; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; assign dst_r = src_u4; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; assign dst_r = src_s4; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; assign dst_r = src_ux; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; assign dst_r = src_sx; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); assign dst_u2s = src_r; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; assign dst_u2s = src_u2; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; assign dst_u2s = src_s2; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; assign dst_u2s = src_u4; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; assign dst_u2s = src_s4; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; assign dst_u2s = src_ux; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; assign dst_u2s = src_sx; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); assign dst_s2s = src_r; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; assign dst_s2s = src_u2; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; assign dst_s2s = src_s2; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; assign dst_s2s = src_u4; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; assign dst_s2s = src_s4; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; assign dst_s2s = src_ux; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; assign dst_s2s = src_sx; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); assign dst_u2l = src_r; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; assign dst_u2l = src_u2; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; assign dst_u2l = src_s2; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; assign dst_u2l = src_u4; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; assign dst_u2l = src_s4; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; assign dst_u2l = src_ux; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; assign dst_u2l = src_sx; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); assign dst_s2l = src_r; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; assign dst_s2l = src_u2; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; assign dst_s2l = src_s2; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; assign dst_s2l = src_u4; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; assign dst_s2l = src_s4; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; assign dst_s2l = src_ux; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; assign dst_s2l = src_sx; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); assign dst_u4s = src_r; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; assign dst_u4s = src_u2; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; assign dst_u4s = src_s2; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; assign dst_u4s = src_u4; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; assign dst_u4s = src_s4; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; assign dst_u4s = src_ux; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; assign dst_u4s = src_sx; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); assign dst_s4s = src_r; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; assign dst_s4s = src_u2; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; assign dst_s4s = src_s2; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; assign dst_s4s = src_u4; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; assign dst_s4s = src_s4; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; assign dst_s4s = src_ux; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; assign dst_s4s = src_sx; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); assign dst_u4l = src_r; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; assign dst_u4l = src_u2; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; assign dst_u4l = src_s2; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; assign dst_u4l = src_u4; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; assign dst_u4l = src_s4; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; assign dst_u4l = src_ux; $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; assign dst_u4l = src_sx; $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); assign dst_s4l = src_r; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; assign dst_s4l = src_u2; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; assign dst_s4l = src_s2; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; assign dst_s4l = src_u4; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; assign dst_s4l = src_s4; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; assign dst_s4l = src_ux; $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; assign dst_s4l = src_sx; $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast4.v000066400000000000000000000156061435245347300216510ustar00rootroot00000000000000// Test implicit casts during procedural continuous (net) assignments. `ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real dst_r; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire bit unsigned [3:0] dst_u2s; wire bit signed [3:0] dst_s2s; wire bit unsigned [11:0] dst_u2l; wire bit signed [11:0] dst_s2l; `endif wire logic unsigned [3:0] dst_u4s; wire logic signed [3:0] dst_s4s; wire logic unsigned [11:0] dst_u4l; wire logic signed [11:0] dst_s4l; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("cast to real"); force dst_r = src_r; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; force dst_r = src_u2; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; force dst_r = src_s2; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; force dst_r = src_u4; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; force dst_r = src_s4; $display("%g", dst_r); if (dst_r != -7.0) failed = 1; force dst_r = src_ux; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; force dst_r = src_sx; $display("%g", dst_r); if (dst_r != 7.0) failed = 1; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST $display("cast to small unsigned bit"); force dst_u2s = src_r; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; force dst_u2s = src_u2; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; force dst_u2s = src_s2; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; force dst_u2s = src_u4; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; force dst_u2s = src_s4; $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; force dst_u2s = src_ux; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; force dst_u2s = src_sx; $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); force dst_s2s = src_r; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; force dst_s2s = src_u2; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; force dst_s2s = src_s2; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; force dst_s2s = src_u4; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; force dst_s2s = src_s4; $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; force dst_s2s = src_ux; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; force dst_s2s = src_sx; $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); force dst_u2l = src_r; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; force dst_u2l = src_u2; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; force dst_u2l = src_s2; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; force dst_u2l = src_u4; $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; force dst_u2l = src_s4; $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; force dst_u2l = src_ux; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; force dst_u2l = src_sx; $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); force dst_s2l = src_r; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; force dst_s2l = src_u2; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; force dst_s2l = src_s2; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; force dst_s2l = src_u4; $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; force dst_s2l = src_s4; $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; force dst_s2l = src_ux; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; force dst_s2l = src_sx; $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; `endif $display("cast to small unsigned logic"); force dst_u4s = src_r; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; force dst_u4s = src_u2; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; force dst_u4s = src_s2; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; force dst_u4s = src_u4; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; force dst_u4s = src_s4; $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; force dst_u4s = src_ux; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; force dst_u4s = src_sx; $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); force dst_s4s = src_r; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; force dst_s4s = src_u2; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; force dst_s4s = src_s2; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; force dst_s4s = src_u4; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; force dst_s4s = src_s4; $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; force dst_s4s = src_ux; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; force dst_s4s = src_sx; $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); force dst_u4l = src_r; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; force dst_u4l = src_u2; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; force dst_u4l = src_s2; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; force dst_u4l = src_u4; $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; force dst_u4l = src_s4; $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; force dst_u4l = src_ux; $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; force dst_u4l = src_sx; $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); force dst_s4l = src_r; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; force dst_s4l = src_u2; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; force dst_s4l = src_s2; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; force dst_s4l = src_u4; $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; force dst_s4l = src_s4; $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; force dst_s4l = src_ux; $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; force dst_s4l = src_sx; $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast5.v000066400000000000000000000200431435245347300216410ustar00rootroot00000000000000// Test implicit casts during net declaration assignments. `ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real dst1_r = src_r; wire real dst2_r = src_u2; wire real dst3_r = src_s2; wire real dst4_r = src_u4; wire real dst5_r = src_s4; wire real dst6_r = src_ux; wire real dst7_r = src_sx; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire bit unsigned [3:0] dst1_u2s = src_r; wire bit unsigned [3:0] dst2_u2s = src_u2; wire bit unsigned [3:0] dst3_u2s = src_s2; wire bit unsigned [3:0] dst4_u2s = src_u4; wire bit unsigned [3:0] dst5_u2s = src_s4; wire bit unsigned [3:0] dst6_u2s = src_ux; wire bit unsigned [3:0] dst7_u2s = src_sx; wire bit signed [3:0] dst1_s2s = src_r; wire bit signed [3:0] dst2_s2s = src_u2; wire bit signed [3:0] dst3_s2s = src_s2; wire bit signed [3:0] dst4_s2s = src_u4; wire bit signed [3:0] dst5_s2s = src_s4; wire bit signed [3:0] dst6_s2s = src_ux; wire bit signed [3:0] dst7_s2s = src_sx; wire bit unsigned [11:0] dst1_u2l = src_r; wire bit unsigned [11:0] dst2_u2l = src_u2; wire bit unsigned [11:0] dst3_u2l = src_s2; wire bit unsigned [11:0] dst4_u2l = src_u4; wire bit unsigned [11:0] dst5_u2l = src_s4; wire bit unsigned [11:0] dst6_u2l = src_ux; wire bit unsigned [11:0] dst7_u2l = src_sx; wire bit signed [11:0] dst1_s2l = src_r; wire bit signed [11:0] dst2_s2l = src_u2; wire bit signed [11:0] dst3_s2l = src_s2; wire bit signed [11:0] dst4_s2l = src_u4; wire bit signed [11:0] dst5_s2l = src_s4; wire bit signed [11:0] dst6_s2l = src_ux; wire bit signed [11:0] dst7_s2l = src_sx; `endif wire logic unsigned [3:0] dst1_u4s = src_r; wire logic unsigned [3:0] dst2_u4s = src_u2; wire logic unsigned [3:0] dst3_u4s = src_s2; wire logic unsigned [3:0] dst4_u4s = src_u4; wire logic unsigned [3:0] dst5_u4s = src_s4; wire logic unsigned [3:0] dst6_u4s = src_ux; wire logic unsigned [3:0] dst7_u4s = src_sx; wire logic signed [3:0] dst1_s4s = src_r; wire logic signed [3:0] dst2_s4s = src_u2; wire logic signed [3:0] dst3_s4s = src_s2; wire logic signed [3:0] dst4_s4s = src_u4; wire logic signed [3:0] dst5_s4s = src_s4; wire logic signed [3:0] dst6_s4s = src_ux; wire logic signed [3:0] dst7_s4s = src_sx; wire logic unsigned [11:0] dst1_u4l = src_r; wire logic unsigned [11:0] dst2_u4l = src_u2; wire logic unsigned [11:0] dst3_u4l = src_s2; wire logic unsigned [11:0] dst4_u4l = src_u4; wire logic unsigned [11:0] dst5_u4l = src_s4; wire logic unsigned [11:0] dst6_u4l = src_ux; wire logic unsigned [11:0] dst7_u4l = src_sx; wire logic signed [11:0] dst1_s4l = src_r; wire logic signed [11:0] dst2_s4l = src_u2; wire logic signed [11:0] dst3_s4l = src_s2; wire logic signed [11:0] dst4_s4l = src_u4; wire logic signed [11:0] dst5_s4l = src_s4; wire logic signed [11:0] dst6_s4l = src_ux; wire logic signed [11:0] dst7_s4l = src_sx; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; #1; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; `endif $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast6.v000066400000000000000000000222411435245347300216440ustar00rootroot00000000000000// Test implicit casts during continuous assignments. `ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `define SUPPORT_TWO_STATE_NETS_IN_IVTEST `endif module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real dst1_r; wire real dst2_r; wire real dst3_r; wire real dst4_r; wire real dst5_r; wire real dst6_r; wire real dst7_r; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST wire bit unsigned [3:0] dst1_u2s; wire bit unsigned [3:0] dst2_u2s; wire bit unsigned [3:0] dst3_u2s; wire bit unsigned [3:0] dst4_u2s; wire bit unsigned [3:0] dst5_u2s; wire bit unsigned [3:0] dst6_u2s; wire bit unsigned [3:0] dst7_u2s; wire bit signed [3:0] dst1_s2s; wire bit signed [3:0] dst2_s2s; wire bit signed [3:0] dst3_s2s; wire bit signed [3:0] dst4_s2s; wire bit signed [3:0] dst5_s2s; wire bit signed [3:0] dst6_s2s; wire bit signed [3:0] dst7_s2s; wire bit unsigned [11:0] dst1_u2l; wire bit unsigned [11:0] dst2_u2l; wire bit unsigned [11:0] dst3_u2l; wire bit unsigned [11:0] dst4_u2l; wire bit unsigned [11:0] dst5_u2l; wire bit unsigned [11:0] dst6_u2l; wire bit unsigned [11:0] dst7_u2l; wire bit signed [11:0] dst1_s2l; wire bit signed [11:0] dst2_s2l; wire bit signed [11:0] dst3_s2l; wire bit signed [11:0] dst4_s2l; wire bit signed [11:0] dst5_s2l; wire bit signed [11:0] dst6_s2l; wire bit signed [11:0] dst7_s2l; `endif wire logic unsigned [3:0] dst1_u4s; wire logic unsigned [3:0] dst2_u4s; wire logic unsigned [3:0] dst3_u4s; wire logic unsigned [3:0] dst4_u4s; wire logic unsigned [3:0] dst5_u4s; wire logic unsigned [3:0] dst6_u4s; wire logic unsigned [3:0] dst7_u4s; wire logic signed [3:0] dst1_s4s; wire logic signed [3:0] dst2_s4s; wire logic signed [3:0] dst3_s4s; wire logic signed [3:0] dst4_s4s; wire logic signed [3:0] dst5_s4s; wire logic signed [3:0] dst6_s4s; wire logic signed [3:0] dst7_s4s; wire logic unsigned [11:0] dst1_u4l; wire logic unsigned [11:0] dst2_u4l; wire logic unsigned [11:0] dst3_u4l; wire logic unsigned [11:0] dst4_u4l; wire logic unsigned [11:0] dst5_u4l; wire logic unsigned [11:0] dst6_u4l; wire logic unsigned [11:0] dst7_u4l; wire logic signed [11:0] dst1_s4l; wire logic signed [11:0] dst2_s4l; wire logic signed [11:0] dst3_s4l; wire logic signed [11:0] dst4_s4l; wire logic signed [11:0] dst5_s4l; wire logic signed [11:0] dst6_s4l; wire logic signed [11:0] dst7_s4l; `ifdef SUPPORT_REAL_NETS_IN_IVTEST assign dst1_r = src_r; assign dst2_r = src_u4; assign dst3_r = src_s4; assign dst4_r = src_u2; assign dst5_r = src_s2; assign dst6_r = src_ux; assign dst7_r = src_sx; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST assign dst1_u2s = src_r; assign dst2_u2s = src_u4; assign dst3_u2s = src_s4; assign dst4_u2s = src_u2; assign dst5_u2s = src_s2; assign dst6_u2s = src_ux; assign dst7_u2s = src_sx; assign dst1_s2s = src_r; assign dst2_s2s = src_u4; assign dst3_s2s = src_s4; assign dst4_s2s = src_u2; assign dst5_s2s = src_s2; assign dst6_s2s = src_ux; assign dst7_s2s = src_sx; assign dst1_u2l = src_r; assign dst2_u2l = src_u4; assign dst3_u2l = src_s4; assign dst4_u2l = src_u2; assign dst5_u2l = src_s2; assign dst6_u2l = src_ux; assign dst7_u2l = src_sx; assign dst1_s2l = src_r; assign dst2_s2l = src_u4; assign dst3_s2l = src_s4; assign dst4_s2l = src_u2; assign dst5_s2l = src_s2; assign dst6_s2l = src_ux; assign dst7_s2l = src_sx; `endif assign dst1_u4s = src_r; assign dst2_u4s = src_u4; assign dst3_u4s = src_s4; assign dst4_u4s = src_u2; assign dst5_u4s = src_s2; assign dst6_u4s = src_ux; assign dst7_u4s = src_sx; assign dst1_s4s = src_r; assign dst2_s4s = src_u4; assign dst3_s4s = src_s4; assign dst4_s4s = src_u2; assign dst5_s4s = src_s2; assign dst6_s4s = src_ux; assign dst7_s4s = src_sx; assign dst1_u4l = src_r; assign dst2_u4l = src_u4; assign dst3_u4l = src_s4; assign dst4_u4l = src_u2; assign dst5_u4l = src_s2; assign dst6_u4l = src_ux; assign dst7_u4l = src_sx; assign dst1_s4l = src_r; assign dst2_s4l = src_u4; assign dst3_s4l = src_s4; assign dst4_s4l = src_u2; assign dst5_s4l = src_s2; assign dst6_s4l = src_ux; assign dst7_s4l = src_sx; bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; #1; `ifdef SUPPORT_REAL_NETS_IN_IVTEST $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; `endif `ifdef SUPPORT_TWO_STATE_NETS_IN_IVTEST $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; `endif $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast7.v000066400000000000000000000201731435245347300216470ustar00rootroot00000000000000// Test implicit casts during parameter declarations. module implicit_cast(); localparam real src_r = -7; localparam bit unsigned [7:0] src_u2 = 7; localparam bit signed [7:0] src_s2 = -7; localparam logic unsigned [7:0] src_u4 = 7; localparam logic signed [7:0] src_s4 = -7; localparam logic unsigned [7:0] src_ux = 8'bx0z00111; localparam logic signed [7:0] src_sx = 8'bx0z00111; localparam real dst1_r = src_r; localparam real dst2_r = src_u4; localparam real dst3_r = src_s4; localparam real dst4_r = src_u2; localparam real dst5_r = src_s2; localparam real dst6_r = src_ux; localparam real dst7_r = src_sx; localparam bit unsigned [3:0] dst1_u2s = src_r; localparam bit unsigned [3:0] dst2_u2s = src_u4; localparam bit unsigned [3:0] dst3_u2s = src_s4; localparam bit unsigned [3:0] dst4_u2s = src_u2; localparam bit unsigned [3:0] dst5_u2s = src_s2; localparam bit unsigned [3:0] dst6_u2s = src_ux; localparam bit unsigned [3:0] dst7_u2s = src_sx; localparam bit signed [3:0] dst1_s2s = src_r; localparam bit signed [3:0] dst2_s2s = src_u4; localparam bit signed [3:0] dst3_s2s = src_s4; localparam bit signed [3:0] dst4_s2s = src_u2; localparam bit signed [3:0] dst5_s2s = src_s2; localparam bit signed [3:0] dst6_s2s = src_ux; localparam bit signed [3:0] dst7_s2s = src_sx; localparam bit unsigned [11:0] dst1_u2l = src_r; localparam bit unsigned [11:0] dst2_u2l = src_u4; localparam bit unsigned [11:0] dst3_u2l = src_s4; localparam bit unsigned [11:0] dst4_u2l = src_u2; localparam bit unsigned [11:0] dst5_u2l = src_s2; localparam bit unsigned [11:0] dst6_u2l = src_ux; localparam bit unsigned [11:0] dst7_u2l = src_sx; localparam bit signed [11:0] dst1_s2l = src_r; localparam bit signed [11:0] dst2_s2l = src_u4; localparam bit signed [11:0] dst3_s2l = src_s4; localparam bit signed [11:0] dst4_s2l = src_u2; localparam bit signed [11:0] dst5_s2l = src_s2; localparam bit signed [11:0] dst6_s2l = src_ux; localparam bit signed [11:0] dst7_s2l = src_sx; localparam logic unsigned [3:0] dst1_u4s = src_r; localparam logic unsigned [3:0] dst2_u4s = src_u4; localparam logic unsigned [3:0] dst3_u4s = src_s4; localparam logic unsigned [3:0] dst4_u4s = src_u2; localparam logic unsigned [3:0] dst5_u4s = src_s2; localparam logic unsigned [3:0] dst6_u4s = src_ux; localparam logic unsigned [3:0] dst7_u4s = src_sx; localparam logic signed [3:0] dst1_s4s = src_r; localparam logic signed [3:0] dst2_s4s = src_u4; localparam logic signed [3:0] dst3_s4s = src_s4; localparam logic signed [3:0] dst4_s4s = src_u2; localparam logic signed [3:0] dst5_s4s = src_s2; localparam logic signed [3:0] dst6_s4s = src_ux; localparam logic signed [3:0] dst7_s4s = src_sx; localparam logic unsigned [11:0] dst1_u4l = src_r; localparam logic unsigned [11:0] dst2_u4l = src_u4; localparam logic unsigned [11:0] dst3_u4l = src_s4; localparam logic unsigned [11:0] dst4_u4l = src_u2; localparam logic unsigned [11:0] dst5_u4l = src_s2; localparam logic unsigned [11:0] dst6_u4l = src_ux; localparam logic unsigned [11:0] dst7_u4l = src_sx; localparam logic signed [11:0] dst1_s4l = src_r; localparam logic signed [11:0] dst2_s4l = src_u4; localparam logic signed [11:0] dst3_s4l = src_s4; localparam logic signed [11:0] dst4_s4l = src_u2; localparam logic signed [11:0] dst5_s4l = src_s2; localparam logic signed [11:0] dst6_s4l = src_ux; localparam logic signed [11:0] dst7_s4l = src_sx; bit failed; initial begin failed = 0; $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast8.v000066400000000000000000000167371435245347300216630ustar00rootroot00000000000000// Test implicit casts during function input assignments. module implicit_cast(); real src_r; bit unsigned [7:0] src_u2; bit signed [7:0] src_s2; logic unsigned [7:0] src_u4; logic signed [7:0] src_s4; logic unsigned [7:0] src_ux; logic signed [7:0] src_sx; real dst_r; bit unsigned [3:0] dst_u2s; bit signed [3:0] dst_s2s; bit unsigned [11:0] dst_u2l; bit signed [11:0] dst_s2l; logic unsigned [3:0] dst_u4s; logic signed [3:0] dst_s4s; logic unsigned [11:0] dst_u4l; logic signed [11:0] dst_s4l; function real cp_r(input real val); cp_r = val; endfunction function bit unsigned [3:0] cp_u2s(input bit unsigned [3:0] val); cp_u2s = val; endfunction function bit signed [3:0] cp_s2s(input bit signed [3:0] val); cp_s2s = val; endfunction function bit unsigned [11:0] cp_u2l(input bit unsigned [11:0] val); cp_u2l = val; endfunction function bit signed [11:0] cp_s2l(input bit signed [11:0] val); cp_s2l = val; endfunction function logic unsigned [3:0] cp_u4s(input logic unsigned [3:0] val); cp_u4s = val; endfunction function logic signed [3:0] cp_s4s(input logic signed [3:0] val); cp_s4s = val; endfunction function logic unsigned [11:0] cp_u4l(input logic unsigned [11:0] val); cp_u4l = val; endfunction function logic signed [11:0] cp_s4l(input logic signed [11:0] val); cp_s4l = val; endfunction bit failed; initial begin failed = 0; src_r = -7; src_u2 = 7; src_s2 = -7; src_u4 = 7; src_s4 = -7; src_ux = 8'bx0z00111; src_sx = 8'bx0z00111; $display("cast to real"); dst_r = cp_r(src_r); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = cp_r(src_u2); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = cp_r(src_s2); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = cp_r(src_u4); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = cp_r(src_s4); $display("%g", dst_r); if (dst_r != -7.0) failed = 1; dst_r = cp_r(src_ux); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; dst_r = cp_r(src_sx); $display("%g", dst_r); if (dst_r != 7.0) failed = 1; $display("cast to small unsigned bit"); dst_u2s = cp_u2s(src_r); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = cp_u2s(src_u2); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = cp_u2s(src_s2); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = cp_u2s(src_u4); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = cp_u2s(src_s4); $display("%d", dst_u2s); if (dst_u2s !== 4'd9) failed = 1; dst_u2s = cp_u2s(src_ux); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; dst_u2s = cp_u2s(src_sx); $display("%d", dst_u2s); if (dst_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); dst_s2s = cp_s2s(src_r); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = cp_s2s(src_u2); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = cp_s2s(src_s2); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = cp_s2s(src_u4); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = cp_s2s(src_s4); $display("%d", dst_s2s); if (dst_s2s !== -4'sd7) failed = 1; dst_s2s = cp_s2s(src_ux); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; dst_s2s = cp_s2s(src_sx); $display("%d", dst_s2s); if (dst_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); dst_u2l = cp_u2l(src_r); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = cp_u2l(src_u2); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l = cp_u2l(src_s2); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = cp_u2l(src_u4); $display("%d", dst_u2l); if (dst_u2l !== 12'd7) failed = 1; dst_u2l = cp_u2l(src_s4); $display("%d", dst_u2l); if (dst_u2l !== 12'd4089) failed = 1; dst_u2l = cp_u2l(src_ux); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; dst_u2l = cp_u2l(src_sx); $display("%b", dst_u2l); if (dst_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); dst_s2l = cp_s2l(src_r); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = cp_s2l(src_u2); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l = cp_s2l(src_s2); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = cp_s2l(src_u4); $display("%d", dst_s2l); if (dst_s2l !== 12'sd7) failed = 1; dst_s2l = cp_s2l(src_s4); $display("%d", dst_s2l); if (dst_s2l !== -12'sd7) failed = 1; dst_s2l = cp_s2l(src_ux); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; dst_s2l = cp_s2l(src_sx); $display("%b", dst_s2l); if (dst_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); dst_u4s = cp_u4s(src_r); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = cp_u4s(src_u2); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = cp_u4s(src_s2); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = cp_u4s(src_u4); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = cp_u4s(src_s4); $display("%d", dst_u4s); if (dst_u4s !== 4'd9) failed = 1; dst_u4s = cp_u4s(src_ux); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; dst_u4s = cp_u4s(src_sx); $display("%d", dst_u4s); if (dst_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); dst_s4s = cp_s4s(src_r); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = cp_s4s(src_u2); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = cp_s4s(src_s2); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = cp_s4s(src_u4); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = cp_s4s(src_s4); $display("%d", dst_s4s); if (dst_s4s !== -4'sd7) failed = 1; dst_s4s = cp_s4s(src_ux); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; dst_s4s = cp_s4s(src_sx); $display("%d", dst_s4s); if (dst_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); dst_u4l = cp_u4l(src_r); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = cp_u4l(src_u2); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l = cp_u4l(src_s2); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = cp_u4l(src_u4); $display("%d", dst_u4l); if (dst_u4l !== 12'd7) failed = 1; dst_u4l = cp_u4l(src_s4); $display("%d", dst_u4l); if (dst_u4l !== 12'd4089) failed = 1; dst_u4l = cp_u4l(src_ux); $display("%b", dst_u4l); if (dst_u4l !== 12'b0000x0z00111) failed = 1; dst_u4l = cp_u4l(src_sx); $display("%b", dst_u4l); if (dst_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); dst_s4l = cp_s4l(src_r); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = cp_s4l(src_u2); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l = cp_s4l(src_s2); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = cp_s4l(src_u4); $display("%d", dst_s4l); if (dst_s4l !== 12'sd7) failed = 1; dst_s4l = cp_s4l(src_s4); $display("%d", dst_s4l); if (dst_s4l !== -12'sd7) failed = 1; dst_s4l = cp_s4l(src_ux); $display("%b", dst_s4l); if (dst_s4l !== 12'b0000x0z00111) failed = 1; dst_s4l = cp_s4l(src_sx); $display("%b", dst_s4l); if (dst_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/implicit_cast9.v000066400000000000000000000201071435245347300216460ustar00rootroot00000000000000// Test implicit casts during constant function input assignments. module implicit_cast(); localparam real src_r = -7; localparam bit unsigned [7:0] src_u2 = 7; localparam bit signed [7:0] src_s2 = -7; localparam logic unsigned [7:0] src_u4 = 7; localparam logic signed [7:0] src_s4 = -7; localparam logic unsigned [7:0] src_ux = 8'bx0z00111; localparam logic signed [7:0] src_sx = 8'bx0z00111; function real cp_r(input real val); cp_r = val; endfunction function bit unsigned [3:0] cp_u2s(input bit unsigned [3:0] val); cp_u2s = val; endfunction function bit signed [3:0] cp_s2s(input bit signed [3:0] val); cp_s2s = val; endfunction function bit unsigned [11:0] cp_u2l(input bit unsigned [11:0] val); cp_u2l = val; endfunction function bit signed [11:0] cp_s2l(input bit signed [11:0] val); cp_s2l = val; endfunction function logic unsigned [3:0] cp_u4s(input logic unsigned [3:0] val); cp_u4s = val; endfunction function logic signed [3:0] cp_s4s(input logic signed [3:0] val); cp_s4s = val; endfunction function logic unsigned [11:0] cp_u4l(input logic unsigned [11:0] val); cp_u4l = val; endfunction function logic signed [11:0] cp_s4l(input logic signed [11:0] val); cp_s4l = val; endfunction localparam dst1_r = cp_r(src_r); localparam dst2_r = cp_r(src_u4); localparam dst3_r = cp_r(src_s4); localparam dst4_r = cp_r(src_u2); localparam dst5_r = cp_r(src_s2); localparam dst6_r = cp_r(src_ux); localparam dst7_r = cp_r(src_sx); localparam dst1_u2s = cp_u2s(src_r); localparam dst2_u2s = cp_u2s(src_u4); localparam dst3_u2s = cp_u2s(src_s4); localparam dst4_u2s = cp_u2s(src_u2); localparam dst5_u2s = cp_u2s(src_s2); localparam dst6_u2s = cp_u2s(src_ux); localparam dst7_u2s = cp_u2s(src_sx); localparam dst1_s2s = cp_s2s(src_r); localparam dst2_s2s = cp_s2s(src_u4); localparam dst3_s2s = cp_s2s(src_s4); localparam dst4_s2s = cp_s2s(src_u2); localparam dst5_s2s = cp_s2s(src_s2); localparam dst6_s2s = cp_s2s(src_ux); localparam dst7_s2s = cp_s2s(src_sx); localparam dst1_u2l = cp_u2l(src_r); localparam dst2_u2l = cp_u2l(src_u4); localparam dst3_u2l = cp_u2l(src_s4); localparam dst4_u2l = cp_u2l(src_u2); localparam dst5_u2l = cp_u2l(src_s2); localparam dst6_u2l = cp_u2l(src_ux); localparam dst7_u2l = cp_u2l(src_sx); localparam dst1_s2l = cp_s2l(src_r); localparam dst2_s2l = cp_s2l(src_u4); localparam dst3_s2l = cp_s2l(src_s4); localparam dst4_s2l = cp_s2l(src_u2); localparam dst5_s2l = cp_s2l(src_s2); localparam dst6_s2l = cp_s2l(src_ux); localparam dst7_s2l = cp_s2l(src_sx); localparam dst1_u4s = cp_u4s(src_r); localparam dst2_u4s = cp_u4s(src_u4); localparam dst3_u4s = cp_u4s(src_s4); localparam dst4_u4s = cp_u4s(src_u2); localparam dst5_u4s = cp_u4s(src_s2); localparam dst6_u4s = cp_u4s(src_ux); localparam dst7_u4s = cp_u4s(src_sx); localparam dst1_s4s = cp_s4s(src_r); localparam dst2_s4s = cp_s4s(src_u4); localparam dst3_s4s = cp_s4s(src_s4); localparam dst4_s4s = cp_s4s(src_u2); localparam dst5_s4s = cp_s4s(src_s2); localparam dst6_s4s = cp_s4s(src_ux); localparam dst7_s4s = cp_s4s(src_sx); localparam dst1_u4l = cp_u4l(src_r); localparam dst2_u4l = cp_u4l(src_u4); localparam dst3_u4l = cp_u4l(src_s4); localparam dst4_u4l = cp_u4l(src_u2); localparam dst5_u4l = cp_u4l(src_s2); localparam dst6_u4l = cp_u4l(src_ux); localparam dst7_u4l = cp_u4l(src_sx); localparam dst1_s4l = cp_s4l(src_r); localparam dst2_s4l = cp_s4l(src_u4); localparam dst3_s4l = cp_s4l(src_s4); localparam dst4_s4l = cp_s4l(src_u2); localparam dst5_s4l = cp_s4l(src_s2); localparam dst6_s4l = cp_s4l(src_ux); localparam dst7_s4l = cp_s4l(src_sx); bit failed; initial begin failed = 0; $display("cast to real"); $display("%g", dst1_r); if (dst1_r != -7.0) failed = 1; $display("%g", dst2_r); if (dst2_r != 7.0) failed = 1; $display("%g", dst3_r); if (dst3_r != -7.0) failed = 1; $display("%g", dst4_r); if (dst4_r != 7.0) failed = 1; $display("%g", dst5_r); if (dst5_r != -7.0) failed = 1; $display("%g", dst6_r); if (dst6_r != 7.0) failed = 1; $display("%g", dst7_r); if (dst7_r != 7.0) failed = 1; $display("cast to small unsigned bit"); $display("%d", dst1_u2s); if (dst1_u2s !== 4'd9) failed = 1; $display("%d", dst2_u2s); if (dst2_u2s !== 4'd7) failed = 1; $display("%d", dst3_u2s); if (dst3_u2s !== 4'd9) failed = 1; $display("%d", dst4_u2s); if (dst4_u2s !== 4'd7) failed = 1; $display("%d", dst5_u2s); if (dst5_u2s !== 4'd9) failed = 1; $display("%d", dst6_u2s); if (dst6_u2s !== 4'd7) failed = 1; $display("%d", dst7_u2s); if (dst7_u2s !== 4'd7) failed = 1; $display("cast to small signed bit"); $display("%d", dst1_s2s); if (dst1_s2s !== -4'sd7) failed = 1; $display("%d", dst2_s2s); if (dst2_s2s !== 4'sd7) failed = 1; $display("%d", dst3_s2s); if (dst3_s2s !== -4'sd7) failed = 1; $display("%d", dst4_s2s); if (dst4_s2s !== 4'sd7) failed = 1; $display("%d", dst5_s2s); if (dst5_s2s !== -4'sd7) failed = 1; $display("%d", dst6_s2s); if (dst6_s2s !== 4'sd7) failed = 1; $display("%d", dst7_s2s); if (dst7_s2s !== 4'sd7) failed = 1; $display("cast to large unsigned bit"); $display("%d", dst1_u2l); if (dst1_u2l !== 12'd4089) failed = 1; $display("%d", dst2_u2l); if (dst2_u2l !== 12'd7) failed = 1; $display("%d", dst3_u2l); if (dst3_u2l !== 12'd4089) failed = 1; $display("%d", dst4_u2l); if (dst4_u2l !== 12'd7) failed = 1; $display("%d", dst5_u2l); if (dst5_u2l !== 12'd4089) failed = 1; $display("%b", dst6_u2l); if (dst6_u2l !== 12'b000000000111) failed = 1; $display("%b", dst7_u2l); if (dst7_u2l !== 12'b000000000111) failed = 1; $display("cast to large signed bit"); $display("%d", dst1_s2l); if (dst1_s2l !== -12'sd7) failed = 1; $display("%d", dst2_s2l); if (dst2_s2l !== 12'sd7) failed = 1; $display("%d", dst3_s2l); if (dst3_s2l !== -12'sd7) failed = 1; $display("%d", dst4_s2l); if (dst4_s2l !== 12'sd7) failed = 1; $display("%d", dst5_s2l); if (dst5_s2l !== -12'sd7) failed = 1; $display("%b", dst6_s2l); if (dst6_s2l !== 12'b000000000111) failed = 1; $display("%b", dst7_s2l); if (dst7_s2l !== 12'b000000000111) failed = 1; $display("cast to small unsigned logic"); $display("%d", dst1_u4s); if (dst1_u4s !== 4'd9) failed = 1; $display("%d", dst2_u4s); if (dst2_u4s !== 4'd7) failed = 1; $display("%d", dst3_u4s); if (dst3_u4s !== 4'd9) failed = 1; $display("%d", dst4_u4s); if (dst4_u4s !== 4'd7) failed = 1; $display("%d", dst5_u4s); if (dst5_u4s !== 4'd9) failed = 1; $display("%d", dst6_u4s); if (dst6_u4s !== 4'd7) failed = 1; $display("%d", dst7_u4s); if (dst7_u4s !== 4'd7) failed = 1; $display("cast to small signed logic"); $display("%d", dst1_s4s); if (dst1_s4s !== -4'sd7) failed = 1; $display("%d", dst2_s4s); if (dst2_s4s !== 4'sd7) failed = 1; $display("%d", dst3_s4s); if (dst3_s4s !== -4'sd7) failed = 1; $display("%d", dst4_s4s); if (dst4_s4s !== 4'sd7) failed = 1; $display("%d", dst5_s4s); if (dst5_s4s !== -4'sd7) failed = 1; $display("%d", dst6_s4s); if (dst6_s4s !== 4'sd7) failed = 1; $display("%d", dst7_s4s); if (dst7_s4s !== 4'sd7) failed = 1; $display("cast to large unsigned logic"); $display("%d", dst1_u4l); if (dst1_u4l !== 12'd4089) failed = 1; $display("%d", dst2_u4l); if (dst2_u4l !== 12'd7) failed = 1; $display("%d", dst3_u4l); if (dst3_u4l !== 12'd4089) failed = 1; $display("%d", dst4_u4l); if (dst4_u4l !== 12'd7) failed = 1; $display("%d", dst5_u4l); if (dst5_u4l !== 12'd4089) failed = 1; $display("%b", dst6_u4l); if (dst6_u4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_u4l); if (dst7_u4l !== 12'bxxxxx0z00111) failed = 1; $display("cast to large signed logic"); $display("%d", dst1_s4l); if (dst1_s4l !== -12'sd7) failed = 1; $display("%d", dst2_s4l); if (dst2_s4l !== 12'sd7) failed = 1; $display("%d", dst3_s4l); if (dst3_s4l !== -12'sd7) failed = 1; $display("%d", dst4_s4l); if (dst4_s4l !== 12'sd7) failed = 1; $display("%d", dst5_s4l); if (dst5_s4l !== -12'sd7) failed = 1; $display("%b", dst6_s4l); if (dst6_s4l !== 12'b0000x0z00111) failed = 1; $display("%b", dst7_s4l); if (dst7_s4l !== 12'bxxxxx0z00111) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/inc_dec_stmt.v000066400000000000000000000005651435245347300213720ustar00rootroot00000000000000module main; int foo; initial begin foo = 1; foo ++; ++ foo; if (foo !== 3) begin $display("FAILED -- foo=%0d", foo); $finish; end foo --; -- foo; if (foo !== 1) begin $display("FAILED -- foo=%0d", foo); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/include1.v000066400000000000000000000016071435245347300204410ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - include a single file // `include "ivltests/else3.v" iverilog-12_0/ivtest/ivltests/include2.v000066400000000000000000000016161435245347300204420ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - include a two levels deep // `include "ivltests/include1.v" iverilog-12_0/ivtest/ivltests/include3.v000066400000000000000000000016211435245347300204370ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - include is three levels deep // `include "ivltests/include2.v" iverilog-12_0/ivtest/ivltests/indef_width_concat.v000066400000000000000000000001321435245347300225400ustar00rootroot00000000000000module top; parameter pval = 1; initial $display("Concat: %d", {pval, 2}); endmodule iverilog-12_0/ivtest/ivltests/initmod.v000066400000000000000000000043241435245347300203770ustar00rootroot00000000000000/* * Copyright (c) 2000 Yasuhisa Kato * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module busm ( clk, iB, oB ); input clk ; input [3:0] iB ; output [3:0] oB ; reg [3:0] r ; assign oB = r ; always @(posedge clk) r <= iB ; endmodule module main; reg a, b, c, d ; reg clk ; initial begin clk = 0 ; forever #5 clk = ~clk ; end initial begin a = 0 ; c = 0 ; #100 $finish(0); end wire e0, f0, g0, h0 ; wire e, f, g, h ; wire [3:0] ii, oo ; always @(posedge clk) a <= ~a ; always @(posedge clk) b <= a ; always @(posedge clk) c <= c ^ a ; always @(posedge clk) d <= ~c ; assign ii = {a, b, c, d} ; assign {e0, f0, g0, h0} = oo ; busm M0 ( clk, ii, oo ); busm M1 ( clk, {a,b,c,d}, {e,f,g,h} ); always @(posedge clk) $display("%h %h %h %h : %b : %h %h %h %h : %b : %h %h %h %h", a, b, c, d, M0.r, e0, f0, g0, h0, M1.r, e, f, g, h ); endmodule // expecting result // 0 x 0 x : xxxx : z z z z : xxxx : z z z z // 1 0 0 1 : 0z0z : 0 z 0 z : 0z0z : 0 z 0 z // 0 1 1 1 : 1001 : 1 0 0 1 : 1001 : 1 0 0 1 // 1 0 1 0 : 0111 : 0 1 1 1 : 0111 : 0 1 1 1 // 0 1 0 0 : 1010 : 1 0 1 0 : 1010 : 1 0 1 0 // 1 0 0 1 : 0100 : 0 1 0 0 : 0100 : 0 1 0 0 // 0 1 1 1 : 1001 : 1 0 0 1 : 1001 : 1 0 0 1 // 1 0 1 0 : 0111 : 0 1 1 1 : 0111 : 0 1 1 1 // 0 1 0 0 : 1010 : 1 0 1 0 : 1010 : 1 0 1 0 // 1 0 0 1 : 0100 : 0 1 0 0 : 0100 : 0 1 0 0 iverilog-12_0/ivtest/ivltests/initmod2.v000066400000000000000000000065421435245347300204650ustar00rootroot00000000000000/* * Copyright (c) 2000 Yasuhisa Kato * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // Modified my stevew@home.com to be self-checking per the comments. module main; reg clk ; initial begin clk = 0 ; forever #5 clk = ~clk ; end initial #20 $finish; wire w, ww, wr, w1, wwr, ww1, wr1, wwro, ww1o, wr1o ; reg r, rw ; reg error; // z <- (z) = z assign ww = w ; // z <- (z) = z assign wr = r ; // x <- (z) = x assign w1 = 'b1 ; // 1 <- (z) = 1 assign wwr = w & r ; // x <- z & x assign ww1 = w & 'b1 ; // x <- z & 1 assign wr1 = r & 'b1 ; // x <- x & 1 assign wwro= w | r ; // x <- z | x assign ww1o= w | 'b1 ; // 1 <- z | 1 assign wr1o= r | 'b1 ; // 1 <- x | 1 always @(posedge clk) rw <= w ; // x <- (x) = z always @(posedge clk) begin #1; $display("%b %b %b %b %b %b %b : %b %b %b : %b %b", w, ww, wr, w1, wwr, ww1, wr1, wwro, ww1o, wr1o, r, rw ); end initial begin error = 0; #19; if(ww !== 1'bz) begin error = 1; $display("FAILED - ww s/b z, is %h",ww); end if(wr !== 1'bx) begin error = 1; $display("FAILED - wr s/b x, is %h",wr); end if(w1 !== 1'b1) begin error = 1; $display("FAILED - wr s/b 1, is %h",wr); end if(wwr !== 1'bx) begin error = 1; $display("FAILED - wwr s/b x, is %h",wwr); end if(ww1 !== 1'bx) begin error = 1; $display("FAILED - ww1 s/b x, is %h",ww1); end if(wr1 !== 1'bx) begin error = 1; $display("FAILED - wr1 s/b x, is %h",wr1); end if(wwro !== 1'bx) begin error = 1; $display("FAILED - wwro s/b 1, is %h",wwro); end if(wr1o !== 1'b1) begin error = 1; $display("FAILED - wr1o s/b 1, is %h",wr1o); end if(r !== 1'bx) begin error = 1; $display("FAILED - r s/b x, is %h",r); end if(r !== 1'bx) begin error = 1; $display("FAILED - r s/b x, is %h",r); end if(rw !== 1'bz) begin error = 1; $display("FAILED - rw s/b z, is %h",r); end if(error === 0) $display("PASSED"); $finish(0); end endmodule // *Initial Value Test* // expected output - This according to XL // z z x 1 x x x : x 1 1 : x x // z z x 1 x x x : x 1 1 : x z // ivl current result // z z x 1 x z x : x 1 1 : x x // z z x 1 x z x : x 1 1 : x z iverilog-12_0/ivtest/ivltests/inout.v000066400000000000000000000047221435245347300200740ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate inout with id(a,a) inout a; definition. module id(a,a); inout a; endmodule module top (); wire b,c; id i1(b,c); reg a, error, ena_a,ena_b; assign c = ena_a ? a : 1'bz; assign b = ena_b ? a : 1'bz; initial begin error = 0; ena_a = 1'b0; ena_b = 1'b0; #1 ; ena_a = 1'b1; #1 ; a= 0; #1; if(b !== 1'b0) begin error = 1; $display("FAILED - b init value not 1'b0 a=%b,b=%b,c=%b",a,b,c); end if(c !== 1'b0) begin error = 1; $display("FAILED - c init value not 1'b0 a=%b,b=%b,c=%b",a,b,c); end #1 ; a= 1; #1; if(b !== 1'b1) begin error = 1; $display("FAILED - b init value not 1'b1 a=%b,b=%b,c=%b",a,b,c); end if(c !== 1'b1) begin error = 1; $display("FAILED - c init value not 1'b1 a=%b,b=%b,c=%b",a,b,c); end #1 ; ena_a = 1'b0; #1 ; ena_b = 1'b1; #1 ; a= 0; #1; if(b !== 1'b0) begin error = 1; $display("FAILED - b init value not 1'b0 a=%b,b=%b,c=%b",a,b,c); end if(c !== 1'b0) begin error = 1; $display("FAILED - c init value not 1'b0 a=%b,b=%b,c=%b",a,b,c); end #1 ; a= 1; #1; if(b !== 1'b1) begin error = 1; $display("FAILED - b init value not 1'b1 a=%b,b=%b,c=%b",a,b,c); end if(c !== 1'b1) begin error = 1; $display("FAILED - c init value not 1'b1 a=%b,b=%b,c=%b",a,b,c); end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/inout2.v000066400000000000000000000016031435245347300201510ustar00rootroot00000000000000/* * This test deminstrates a complication in the handling of a vector * as a unit, instead of breaking it out. The problem is with the * legal inout expression that takes one bit of the vector. That * leads to a driver to the input of a part select, and also the * other way around. Yikes. */ module main; reg [1:0] drv = 2'b0z; wire [1:0] a = drv; reg en; bi dut0(a[0], en); initial begin en <= 0; #1 $display("drv=%b en=%b, a=%b (should be 0z)", drv, en, a); if (a !== 2'b0z) begin $display("FAILED"); $finish; end en <= 1; #1 $display("drv=%b en=%b, a=%b (should be 01)", drv, en, a); if (a !== 2'b01) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule // main module bi (inout a, input en); reg val = 1; assign a = en? val : 1'bz; endmodule // bi iverilog-12_0/ivtest/ivltests/inout3.v000066400000000000000000000010351435245347300201510ustar00rootroot00000000000000module main; wire qh = 1'bz; wire [1:0] Q; reg [2:0] D; buft a({qh,Q}, D); reg x; //assign D[0] = x; initial begin D = 3'bzz0; #1 $display("Q=%b, D=%b", Q, D); if (Q !== 2'bz0) begin $display("FAILED"); $finish; end D[0] = 1; #1 $display("Q=%b, D=%b", Q, D); if (Q !== 2'bz1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main module buft(inout [2:0] T, input [2:0] D); assign T = D; endmodule // buft iverilog-12_0/ivtest/ivltests/inout4.v000066400000000000000000000014221435245347300201520ustar00rootroot00000000000000module main; wire [31:0] DB; reg E; X2 U (.DB(DB[31:8]), .E(E)); Y1 V (.DB(DB[7:0]), .E(E)); initial begin E = 0; #1 if (DB !== 32'hzzzzzzzz) begin $display("FAILED -- DB=%b", DB); $finish; end E = 1; #1 if (DB !== 32'h9zzzzz87) begin $display("FAILED -- DB=%b", DB); $finish; end $display("PASSED"); end // initial begin endmodule // main module X2(inout wire [31:8] DB, input wire E); X1 uu (.DB(DB[31:28]), .E(E)); endmodule // X2 module X1(inout wire [31:28] DB, input wire E); wire foo = DB[31:28]; assign DB[31:28] = E? 4'b1001 : 4'bzzzz; endmodule // sub module Y1(inout wire [7:0] DB, input wire E); wire foo = DB[7:0]; assign DB[7:0] = E? 8'h87 : 8'hzz; endmodule // sub iverilog-12_0/ivtest/ivltests/inside_synth.v000066400000000000000000000021541435245347300214330ustar00rootroot00000000000000/* * This tests the latching of an output that isn't really an output, * but an intermediate symbol that is only used in some clauses. */ module main; reg [15:0] out, a; reg [7:0] b; reg cy; reg with_carry; (* ivl_combinational *) always @(with_carry, a, b, cy) if (with_carry) begin {cy, out[7:0]} = {1'b0, a[7:0]} + {1'b0, b[7:0]}; out[15:8] = a[15:8] + {7'b0, cy}; end else begin out = a + {8'h00, b}; end (* ivl_synthesis_off *) initial begin a = 16'h00fe; b = 8'h00; with_carry = 0; #1 if (out !== 16'h00fe) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end with_carry = 1; #1 if (out !== 16'h00fe) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end b = 2; #1 if (out !== 16'h0100) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end with_carry = 0; #1 if (out !== 16'h0100) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/inside_synth2.v000066400000000000000000000023761435245347300215230ustar00rootroot00000000000000module main; reg [7:0] th2, init; reg carry, clk, rst, foo; (* ivl_synthesis_on *) always @(posedge clk) begin if (rst) begin th2 <= 0; carry <= 1; foo <= 0; // This causes foo to be an output to the block. end else begin if (carry) {carry, th2} <= {1'b0, init}; else {carry, th2} <= {1'b0, th2} + 9'h1; end end (* ivl_synthesis_off *) initial begin rst = 1; clk = 0; init = 8'hfe; $monitor("clk=%b: rst=%b, th2=%h, carry=%b", clk, rst, th2, carry); #1 clk = 1; #1 clk = 0; if (foo !== 0) begin $display("FAILED -- foo=%b", foo); $finish; end rst = 0; #1 clk = 1; #1 clk = 0; #1 clk = 1; #1 clk = 0; if (th2 !== 8'hff) begin $display("FAILED -- th2=%h (1)", th2); $finish; end #1 clk = 1; #1 clk = 0; if (th2 !== 8'h00) begin $display("FAILED == th2=%h", th2); $finish; end if (carry !== 1) begin $display("FAILED -- carry=%b, th2=%h", carry, th2); $finish; end #1 clk = 1; #1 clk = 0; if (th2 !== 8'hfe) begin $display("FAILED -- th2=%h", th2); $finish; end #1 $strobe("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/inside_synth3.v000066400000000000000000000022321435245347300215130ustar00rootroot00000000000000/* * This tests the latching of an output that isn't really an output, * but an intermediate symbol that is only used in some clauses. */ module main; reg [15:0] out, a; reg [7:0] b; reg cy; reg with_carry; (* ivl_combinational *) always @(with_carry, a, b, cy) case (with_carry) 1'b1: begin {cy, out[7:0]} = {1'b0, a[7:0]} + {1'b0, b[7:0]}; out[15:8] = a[15:8] + {7'b0, cy}; end 1'b0: begin out = a + {8'h00, b}; end endcase (* ivl_synthesis_off *) initial begin a = 16'h00fe; b = 8'h00; with_carry = 0; #1 if (out !== 16'h00fe) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end with_carry = 1; #1 if (out !== 16'h00fe) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end b = 2; #1 if (out !== 16'h0100) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end with_carry = 0; #1 if (out !== 16'h0100) begin $display("FAILED -- a=%h, b=%h, out=%h", a, b, out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/int_not_signext.v000066400000000000000000000010561435245347300221460ustar00rootroot00000000000000module top; reg [47:0] out1, out2, out3, out4, out5; integer i; initial begin for (i=-1 ; i<2; i=i+1) begin // i is signed so should it be sign extended? out1 = 48'd16 + i; // I would have expected this to be the same as (i+0) below! out2 = 48'd16 + (i); // All the rest of these are sign extended? out3 = 48'd16 + (i+0); out4 = 48'sd16 + i; out5 = 48'd16 + (i-1); $display("16 + %2d = %10d, %10d, %2d, %2d, -1 = %2d", i, out1, out2, out3, out4, out5); end end endmodule iverilog-12_0/ivtest/ivltests/int_param.v000066400000000000000000000013541435245347300207060ustar00rootroot00000000000000module main; localparam int int_lparm = 11; parameter int int_param = 10; int int_var; initial begin if (int_lparm != 11) begin $display("FAILED: int_lparm=%b", int_lparm); $finish; end if ($bits(int_lparm) != 32) begin $display("FAILED: $bits(int_lparm) = %d", $bits(int_lparm)); $finish; end if (int_param != 10) begin $display("FAILED: int_param=%b", int_param); $finish; end if ($bits(int_param) != 32) begin $display("FAILED: $bits(int_param) = %d", $bits(int_param)); $finish; end int_var = int_param; if (int_var != 10) begin $display("FAILED: int_var=%b", int_var); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/integer1lt.v000066400000000000000000000030671435245347300210150ustar00rootroot00000000000000/* * integer1 - a verilog test for integer conditionals * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module integer1lt; integer a; integer b; reg error; initial begin error = 0; a = 2; if(a < 2) begin $display("FAILED 2 < 2"); error = 1; end a = 3; if(a < 2) begin $display("FAILED 3 < 2"); error = 1; end a = 1; if(a < 2) begin b = 1; end else begin $display("FAILED 1 < 2"); error = 1; end b = 0; for(a = 0; a < 5; a = a + 1) begin b = b + a; end // for (a = 0; a < 5; a = a + 1) if(b != 10) begin $display("FAILED forloop b=%d expected 10", b); error = 1; end if(error == 0) $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/integer2le.v000066400000000000000000000047201435245347300207740ustar00rootroot00000000000000/* * integer2le - a verilog test for integer less-or-equal conditional <= * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module integer2le; integer a; integer b; integer c; reg error; initial begin error = 0; a = 1; if(a <= 2) begin b = 1; end else begin $display("FAILED 1 <= 2"); error = 1; end a = 2; if(a <= 2) begin b = 1; end else begin $display("FAILED 2 <= 2"); error = 1; end a = 3; if(a <= 2) begin $display("FAILED 3 <= 2"); error = 1; end c = 0; a = 10; for(b = 0; a <= 5; b = b + 1) begin b = b + a; c = c + 1; if(c > 10) begin $display("FAILED (infinite loop) a=%d b=%d", a, b); error = 1; $finish; end end if(b != 0) begin $display("FAILED forloop a=%d b=%d", a, b); error = 1; end if(a != 10) begin $display("FAILED forloop a=%d b=%d", a, b); error = 1; end b = 0; c = 0; for(a = 0; a <= 5; a = a + 1) begin b = b + a; c = c + 1; if(c > 10) begin $display("FAILED (infinite loop) a=%d b=%d", a, b); error = 1; $finish; end end if(b != 15) begin $display("FAILED forloop b=%d expected 15", b); error = 1; end if(error == 0) $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/integer3gt.v000066400000000000000000000030661435245347300210110ustar00rootroot00000000000000/* * integer3gt - a verilog test for integer greater-than conditional > * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module integer3gt; integer a; integer b; reg error; initial begin error = 0; a = 1; if(a > 2) begin $display("FAILED 1 > 2"); error = 1; end // if (a < 2) a = 2; if(a > 2) begin $display("FAILED 2 > 2"); error = 1; end a = 3; if(a > 2) begin b = 1; end else begin $display("FAILED 3 > 2"); error = 1; end b = 0; for(a = 10; a > 5; a = a - 1) begin b = b + a; end if(b != 40) begin $display("FAILED forloop b=%d expected 40", b); error = 1; end if(error == 0) $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/integer4ge.v000066400000000000000000000031221435245347300207640ustar00rootroot00000000000000/* * integer4ge - a verilog test for integer greater-or-equal conditional >= * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module integer4ge; integer a; integer b; reg error; initial begin error = 0; a = 1; if(a >= 2) begin $display("FAILED 1 >= 2"); error = 1; end a = 2; if(a >= 2) begin b = 1; end else begin $display("FAILED 2 >= 2"); error = 1; end a = 3; if(a >= 2) begin b = 1; end else begin $display("FAILED 3 >= 2"); error = 1; end b = 0; for(a = 10; a >= 5; a = a - 1) begin b = b + a; end if(b != 45) begin $display("FAILED forloop b=%d expected 45", b); error = 1; end if(error == 0) $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/integer5.v000066400000000000000000000026231435245347300204560ustar00rootroot00000000000000/* * integer4ge - a verilog test for integer greater-or-equal conditional >= * * Copyright (C) 2000 Steve Wilson stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ `timescale 100s/1s module test; reg [3:0] result; reg error; integer num1; wire [3:0] result1; assign result1 = 1 + (num1 /4); initial begin error = 0; num1 = 32'h24 ; result = 1 + (num1 / 4); #1; if(result !== 4'ha) begin $display("FAILED - division didn't work s/b A, is %h",result); error = 1; end if(result1 !== 4'ha) begin $display("FAILED - assign division didn't work s/b A, is %h",result1); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ishortint_test.v000066400000000000000000000051571435245347300220230ustar00rootroot00000000000000// Three basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (unsigned) bytes with random numbers // 3. assignments to (unsigned) bytes with random values including X and Z module ibyte_test; parameter TRIALS = 100; parameter MAX = 'h7fff; reg [15:0] ar; // should it be "reg unsigned [7:0] aw"? reg [15:0] ar_xz; // same as above here? reg [15:0] ar_expected; // and here shortint unsigned bu; shortint unsigned bu_xz; integer i; assign bu = ar; assign bu_xz = ar_xz; // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 16'b0 | bu_xz != 16'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // random numbers for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // with 'x injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< TRIALS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x): %b", bu); $finish; end end # 1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [7:0] xz_inject (input [7:0] value); // should it be "input unsigned [7:0]" instead? integer i, temp; begin temp = {$random} % MAX; for (i=0; i<16; i=i+1) begin if (temp[i] == 1'b1) begin temp = $random % MAX; if (temp <= 0) value[i] = 1'bx; // 'x noise else value[i] = 1'bz; // 'z noise end end xz_inject = value; end endfunction // this function returns bit positions with either X or Z to 0 for an input value function [15:0] xz_expected (input [15:0] value_xz); // should it be "input unsigned [7:0] instead? integer i; begin for (i=0; i<16; i=i+1) begin if (value_xz[i] === 1'bx || value_xz[i] === 1'bz ) value_xz[i] = 1'b0; // forced to zero end xz_expected = value_xz; end endfunction endmodule iverilog-12_0/ivtest/ivltests/issue576.v000066400000000000000000000005201435245347300203200ustar00rootroot00000000000000 // This example is rediculous, but legal. However, Icarus Verilog will print // various warnings about this. The warnings are OK, but Issue#576 saw this // program assert, which is worse. module test; function void fun; begin $display("PASSED"); $finish; end endfunction // fun always_comb fun; endmodule iverilog-12_0/ivtest/ivltests/itor_rtoi.v000066400000000000000000000106021435245347300207420ustar00rootroot00000000000000/* * This does not check that $itor() and $rtoi() can actually be called in * a constant context (e.g. a parameter assignment). This was done so that * older version of Icarus Verilog will still run this code to verify that * the values are converted correctly. Also some of the results are not * defined in the standard so we use a gold file instead of pass/fail test * to make it easier to check other simulators. */ module top; integer ival; real rval; initial begin $display("Testing $itor() in a constant context."); // Check various integer values. rval = $itor(10); $display(" $itor(10) = %g", rval); rval = $itor(1'bx); $display(" $itor(1'bx) = %g", rval); rval = $itor(1'bz); $display(" $itor(1'bx) = %g", rval); // Check various real values. rval = $itor(10.4); $display(" $itor(10.4) = %g", rval); rval = $itor(10.5); $display(" $itor(10.5) = %g", rval); rval = $itor(-1.4); $display(" $itor(-1.4) = %g", rval); rval = $itor(-1.5); $display(" $itor(-1.5) = %g", rval); rval = $itor(0.0/0.0); $display(" $itor(NaN) = %g", rval); rval = $itor(1.0/0.0); $display(" $itor(+inf) = %g", rval); rval = $itor(-1.0/0.0); $display(" $itor(-inf) = %g", rval); $display(""); $display("Testing $itor() in a variable context."); // Check various integer values. ival = 10; rval = $itor(ival); $display(" $itor(10) = %g", rval); ival = 1'bx; rval = $itor(ival); $display(" $itor(1'bx) = %g", rval); ival = 1'bx; rval = $itor(ival); $display(" $itor(1'bx) = %g", rval); // Check various real values. rval = 10.4; rval = $itor(rval); $display(" $itor(10.4) = %g", rval); rval = 10.5; rval = $itor(rval); $display(" $itor(10.5) = %g", rval); rval = -1.4; rval = $itor(rval); $display(" $itor(-1.4) = %g", rval); rval = -1.5; rval = $itor(rval); $display(" $itor(-1.5) = %g", rval); rval = 0.0/0.0; rval = $itor(rval); $display(" $itor(NaN) = %g", rval); rval = 1.0/0.0; rval = $itor(rval); $display(" $itor(+inf) = %g", rval); rval = -1.0/0.0; rval = $itor(rval); $display(" $itor(-inf) = %g", rval); $display(""); $display("Testing $rtoi() in a constant context."); // Check for truncation of a positive value. ival = $rtoi(1.1); $display(" $rtoi(1.1) = %0d", ival); ival = $rtoi(1.9); $display(" $rtoi(1.9) = %0d", ival); // Check for truncation of a negative value. ival = $rtoi(-1.1); $display(" $rtoi(-1.1) = %0d", ival); ival = $rtoi(-1.9); $display(" $rtoi(-1.9) = %0d", ival); // Check a value larger than an integer is truncated. ival = $rtoi((33'b1<<32)+0.0); $display(" Overflow(0) = %0d", ival); ival = $rtoi((33'b1<<32)+1.0); $display(" Overflow(1) = %0d", ival); // Check NaN, +/- infinity. ival = $rtoi(0.0/0.0); $display(" $rtoi(NaN) = %0d", ival); ival = $rtoi(1.0/0.0); $display(" $rtoi(+inf) = %0d", ival); ival = $rtoi(-1.0/0.0); $display(" $rtoi(-inf) = %0d", ival); // Check various integer values. ival = $rtoi(1); $display(" $rtoi(1) = %0d", ival); ival = $rtoi(1'bx); $display(" $rtoi(1'bx) = %0d", ival); ival = $rtoi(1'bz); $display(" $rtoi(1'bz) = %0d", ival); $display(""); $display("Testing $rtoi() in a variable context."); // Check for truncation of a positive value. rval = 1.1; ival = $rtoi(rval); $display(" $rtoi(1.1) = %0d", ival); rval = 1.9; ival = $rtoi(rval); $display(" $rtoi(1.9) = %0d", ival); // Check for truncation of a negative value. rval = -1.1; ival = $rtoi(rval); $display(" $rtoi(-1.1) = %0d", ival); rval = -1.9; ival = $rtoi(rval); $display(" $rtoi(-1.9) = %0d", ival); // Check a value larger than an integer is truncated. rval = (33'b1<<32)+0.0; ival = $rtoi(rval); $display(" Overflow(0) = %0d", ival); rval = (33'b1<<32)+1.0; ival = $rtoi(rval); $display(" Overflow(1) = %0d", ival); // Check NaN, +/- infinity. rval = 0.0/0.0; ival = $rtoi(rval); $display(" $rtoi(NaN) = %0d", ival); rval = 1.0/0.0; ival = $rtoi(rval); $display(" $rtoi(+inf) = %0d", ival); rval = -1.0/0.0; ival = $rtoi(rval); $display(" $rtoi(-inf) = %0d", ival); // Check various integer values. ival = 1; ival = $rtoi(ival); $display(" $rtoi(1) = %0d", ival); ival = 1'bx; ival = $rtoi(ival); $display(" $rtoi(1'bx) = %0d", ival); ival = 1'bz; ival = $rtoi(ival); $display(" $rtoi(1'bz) = %0d", ival); end endmodule iverilog-12_0/ivtest/ivltests/iuint1.v000066400000000000000000000027271435245347300201520ustar00rootroot00000000000000module main; int unsigned foo, bar = 10; int signed foos, bars = 10; int unsigned wire_sum; int wire_sums; assign wire_sum = foo + bar; assign wire_sums = foos + bars; function int unsigned sum(input int unsigned a, b); sum = a + b; endfunction function int unsigned sums(input int signed a, b); sums = a + b; endfunction initial begin foo = 9; $display("%0d * %0d = %0d", foo, bar, foo * bar); $display("sum(%0d,%0d) = %0d", foo, bar, sum(foo,bar)); if (foo !== 9 || bar !== 10) begin $display("FAILED"); $finish; end if (foo*bar !== 90) begin $display("FAILED"); $finish; end if (sum(foo,bar) !== 19) begin $display("FAILED"); $finish; end foos = -7; $display("%0d * %0d = %0d", foos, bars, foos * bars); $display("sums(%0d,%0d) = %0d", foos, bars, sums(foos,bars)); if (foos !== -7 || bars !== 10) begin $display("FAILED"); $finish; end if (foos*bars !== -70) begin $display("FAILED"); $finish; end if (sums(foos,bars) !== 3) begin $display("FAILED"); $finish; end #0; // allow CAs to propagate $display("wire_sum = %0d", wire_sum); $display("wire_sums = %0d", wire_sums); if (wire_sum !== 19) begin $display("FAILED"); $finish; end if (wire_sums !== 3) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ivlh_event.v000066400000000000000000000005241435245347300210750ustar00rootroot00000000000000module main; reg a, b; always @(a or b) begin if ($ivlh_attribute_event(a)) $display("%0t: EVENT on a", $time); if ($ivlh_attribute_event(b)) $display("%0t: EVENT on b", $time); end initial begin #1 a <= 1; #1 b <= 1; #1 a <= 0; #1 b <= 0; #1 $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/ivlh_rising_falling.v000066400000000000000000000031111435245347300227360ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for $ivlh_{rising,falling}_edge VPI functions // (mostly used by the VHDL frontend). module main; reg a, b; always @(a or b) begin if ($ivlh_rising_edge(a)) $display("%0t: rising_edge(a)", $time); if ($ivlh_falling_edge(a)) $display("%0t: falling_edge(a)", $time); if ($ivlh_rising_edge(b)) $display("%0t: rising_edge(b)", $time); if ($ivlh_falling_edge(b)) $display("%0t: falling_edge(b)", $time); end initial begin #1 a <= 1; #1 b <= 1; #1 a <= 0; #1 b <= 0; #1 a <= 0; // nothing should be detected #1 b <= 0; #1 a <= 1; #1 b <= 1; #1 a <= 1; // nothing should be detected #1 b <= 1; #1 a <= 0; #1 b <= 0; #1 $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/ivlh_textio.v000066400000000000000000000116461435245347300212770ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for VHDL std.textio & ieee.std_logic_textio functions implemented using VPI. `timescale 1ns/1ns typedef enum integer { false, true } boolean; typedef enum integer { read_mode , write_mode , append_mode } file_open_kind; module vhdl_textio_test; string line; int file; string str; bit [3:0][7:0] str_lim; real r; int in; integer i; byte by; time t; boolean boo; logic l; logic [7:0] lv; bit bi; bit [7:0] biv; initial begin static string filename = "vpi_textio_text.tmp"; // values to be saved str = "test_string"; str_lim = "TEST"; r = -2.5e3; in = 120; i = -12; by = 8'h1f; t = 100ns; boo = true; l = 1'bx; lv = 8'b110101xz; bi = 1'b0; biv = 8'b10111001; // write test $ivlh_file_open(file, filename, write_mode); $ivlh_write(line, str, 0); // standard format $ivlh_write(line, " ", 0); $ivlh_write(line, str_lim, 4); // string format $ivlh_write(line, " ", 0); $ivlh_write(line, r, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, in, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, i, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, by, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, t, 2); // time format // this will be intentionally skipped during the read test $ivlh_write(line, " ", 0); $ivlh_write(line, l, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, lv, 0); if(line != "test_string TEST -2500.000000 120 -12 31 100 ns X 110101XZ") begin $display("FAILED 1"); $finish(); end $ivlh_writeline(file, line); // writeline should clear the written string if(line != "") begin $display("FAILED 2"); $finish(); end $ivlh_write(line, boo, 1); // boolean format $ivlh_write(line, " ", 0); $ivlh_write(line, l, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, lv, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, bi, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, biv, 0); $ivlh_write(line, " ", 0); $ivlh_write(line, biv, 3); // hex format if(line != "TRUE X 110101XZ 0 10111001 B9") begin $display("FAILED 3"); $finish(); end $ivlh_writeline(file, line); $fclose(file); // reset variables str = ""; r = 0; in = 0; i = 0; by = 0; t = 0s; boo = false; l = 0; lv = 0; bi = 0; biv = 0; // read test $ivlh_file_open(file, filename, read_mode ); $ivlh_readline(file, line); $ivlh_read(line, str, 0); // standard format $ivlh_read(line, str_lim, 4); // string format $ivlh_read(line, r, 0); $ivlh_read(line, in, 0); $ivlh_read(line, i, 0); $ivlh_read(line, by, 0); $ivlh_read(line, t, 2); // time format $ivlh_readline(file, line); $ivlh_read(line, boo, 1); // boolean format $ivlh_read(line, l, 0); $ivlh_read(line, lv, 0); $ivlh_read(line, bi, 0); $ivlh_read(line, biv, 0); $ivlh_read(line, biv, 3); // hex format $fclose(file); // compare read and expected values if(str != "test_string") begin $display("FAILED 5"); $finish(); end if(str_lim != "TEST") begin $display("FAILED 6"); $finish(); end if(r != -2.5e3) begin $display("FAILED 7"); $finish(); end if(in !== 120) begin $display("FAILED 8"); $finish(); end if(i !== -12) begin $display("FAILED 9"); $finish(); end if(by !== 8'h1f) begin $display("FAILED 10"); $finish(); end if(t != 100ns) begin $display("FAILED 11"); $finish(); end if(boo !== true) begin $display("FAILED 12"); $finish(); end if(l !== 1'bx) begin $display("FAILED 13"); $finish(); end if(lv !== 8'b110101xz) begin $display("FAILED 14"); $finish(); end if(bi !== 1'b0) begin $display("FAILED 15"); $finish(); end if(biv !== 8'b10111001) begin $display("FAILED 16"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/l_equiv.v000066400000000000000000000076331435245347300204060ustar00rootroot00000000000000module top; real rval1, rval2; reg val1, val2; reg [3:0] wval1, wval2; reg [1:0] wres; reg res; reg pass; initial begin pass = 1'b1; val1 = 1'b0; val2 = 1'b0; res = val1 <-> val2; if (res !== 1'b1) begin $display("FAILED: 1'b0 <-> 1'b0 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'b1; res = val1 <-> val2; if (res !== 1'b0) begin $display("FAILED: 1'b0 <-> 1'b1 returned %b not 1'b0", res); pass = 1'b0; end val2 = 1'bx; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'b1; val2 = 1'b0; res = val1 <-> val2; if (res !== 1'b0) begin $display("FAILED: 1'b1 <-> 1'b0 returned %b not 1'b0", res); pass = 1'b0; end val2 = 1'b1; res = val1 <-> val2; if (res !== 1'b1) begin $display("FAILED: 1'b1 <-> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bx; val2 = 1'b0; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b1 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bx; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bz; val2 = 1'b0; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b1 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bx; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end rval1 = 0.0; val2 = 1'b0; res = rval1 <-> val2; if (res !== 1'b1) begin $display("FAILED: 0.0 <-> 1'b0 returned %b not 1'b1", res); pass = 1'b0; end val1 = 1'b0; rval2 = 2.0; res = val1 <-> rval2; if (res !== 1'b0) begin $display("FAILED: 1'b0 <-> 2.0 returned %b not 1'b0", res); pass = 1'b0; end rval1 = 2.0; val2 = 1'bx; res = rval1 <-> val2; if (res !== 1'bx) begin $display("FAILED: 2.0 <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end rval1 = -5.0; rval2 = 2.0; res = rval1 <-> rval2; if (res !== 1'b1) begin $display("FAILED: -5.0 <-> -2.0 returned %b not 1'b1", res); pass = 1'b0; end wval1 = 4'b0110; wval2 = 4'b1001; wres = wval1 <-> wval2; if (wres !== 2'b01) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b01", wres); pass = 1'b0; end wres = $signed(wval1 <-> wval2); if (wres !== 2'b11) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b11", wres); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/l_equiv_ca.v000066400000000000000000000074301435245347300210440ustar00rootroot00000000000000module top; wire res, ler0, ler1, ler2, ler3; wire [1:0] lew, lews; real rval1, rval2; reg val1, val2; reg [3:0] wval1, wval2; reg pass; assign res = val1 <-> val2; assign lew = wval1 <-> wval2; assign lews = $signed(wval1 <-> wval2); assign ler0 = rval1 <-> val2; assign ler1 = val1 <-> rval2; assign ler2 = rval1 <-> val2; assign ler3 = rval1 <-> rval2; initial begin pass = 1'b1; val1 = 1'b0; val2 = 1'b0; #1; if (res !== 1'b1) begin $display("FAILED: 1'b0 <-> 1'b0 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'b1; #1; if (res !== 1'b0) begin $display("FAILED: 1'b0 <-> 1'b1 returned %b not 1'b0", res); pass = 1'b0; end val2 = 1'bx; #1; if (res !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; #1; if (res !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'b1; val2 = 1'b0; #1; if (res !== 1'b0) begin $display("FAILED: 1'b1 <-> 1'b0 returned %b not 1'b0", res); pass = 1'b0; end val2 = 1'b1; #1; if (res !== 1'b1) begin $display("FAILED: 1'b1 <-> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; #1; if (res !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; #1; if (res !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bx; val2 = 1'b0; #1; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; #1; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b1 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bx; #1; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; #1; if (res !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bz; val2 = 1'b0; #1; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; #1; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b1 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bx; #1; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; #1; if (res !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bz returned %b not 1'bx", res); pass = 1'b0; end rval1 = 0.0; val2 = 1'b0; #1; if (ler0 !== 1'b1) begin $display("FAILED: 0.0 <-> 1'b0 returned %b not 1'b1", ler0); pass = 1'b0; end val1 = 1'b0; rval2 = 2.0; #1; if (ler1 !== 1'b0) begin $display("FAILED: 1'b0 <-> 2.0 returned %b not 1'b0", ler1); pass = 1'b0; end rval1 = 2.0; val2 = 1'bx; #1; if (ler2 !== 1'bx) begin $display("FAILED: 2.0 <-> 1'bx returned %b not 1'bx", ler2); pass = 1'b0; end rval1 = -5.0; rval2 = 2.0; #1; if (ler3 !== 1'b1) begin $display("FAILED: -5.0 <-> -2.0 returned %b not 1'b1", ler3); pass = 1'b0; end wval1 = 4'b0110; wval2 = 4'b1001; #1; if (lew !== 2'b01) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b01", lew); pass = 1'b0; end if (lews !== 2'b11) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b11", lews); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/l_equiv_const.v000066400000000000000000000072551435245347300216140ustar00rootroot00000000000000module top; parameter le0 = 1'b0 <-> 1'b0; // 1'b1 parameter le1 = 1'b0 <-> 1'b1; // 1'b0 parameter le2 = 1'b0 <-> 1'bz; // 1'bx parameter le3 = 1'b0 <-> 1'bx; // 1'bx parameter le4 = 1'b1 <-> 1'b0; // 1'b0 parameter le5 = 1'b1 <-> 1'b1; // 1'b1 parameter le6 = 1'b1 <-> 1'bz; // 1'bx parameter le7 = 1'b1 <-> 1'bx; // 1'bx parameter le8 = 1'bz <-> 1'b0; // 1'bx parameter le9 = 1'bz <-> 1'b1; // 1'bx parameter lea = 1'bz <-> 1'bz; // 1'bx parameter leb = 1'bz <-> 1'bx; // 1'bx parameter lec = 1'bx <-> 1'b0; // 1'bx parameter led = 1'bx <-> 1'b1; // 1'bx parameter lee = 1'bx <-> 1'bz; // 1'bx parameter lef = 1'bx <-> 1'bx; // 1'bx parameter [1:0] lew = 4'b0110 <-> 4'b1001; // 2'b01 parameter [1:0] lews = $signed(4'b0110 <-> 4'b1001); // 2'b11 parameter ler0 = 0.0 <-> 1'b0; // 1'b1 parameter ler1 = 1'b0 <-> 2.0; // 1'b0 parameter ler2 = 2.0 <-> 1'bx; // 1'bx parameter ler3 = -5.0 <-> 2.0; // 1'b1 reg pass; initial begin pass = 1'b1; if (le0 !== 1'b1) begin $display("FAILED: 1'b0 <-> 1'b0 returned %b not 1'b1", le0); pass = 1'b0; end if (le1 !== 1'b0) begin $display("FAILED: 1'b0 <-> 1'b1 returned %b not 1'b0", le1); pass = 1'b0; end if (le2 !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bz returned %b not 1'bx", le2); pass = 1'b0; end if (le3 !== 1'bx) begin $display("FAILED: 1'b0 <-> 1'bx returned %b not 1'bx", le3); pass = 1'b0; end if (le4 !== 1'b0) begin $display("FAILED: 1'b1 <-> 1'b0 returned %b not 1'b0", le4); pass = 1'b0; end if (le5 !== 1'b1) begin $display("FAILED: 1'b1 <-> 1'b1 returned %b not 1'b1", le5); pass = 1'b0; end if (le6 !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bz returned %b not 1'bx", le6); pass = 1'b0; end if (le7 !== 1'bx) begin $display("FAILED: 1'b1 <-> 1'bx returned %b not 1'bx", le7); pass = 1'b0; end if (le8 !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b0 returned %b not 1'bx", le8); pass = 1'b0; end if (le9 !== 1'bx) begin $display("FAILED: 1'bz <-> 1'b1 returned %b not 1'bx", le9); pass = 1'b0; end if (lea !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bz returned %b not 1'bx", lea); pass = 1'b0; end if (leb !== 1'bx) begin $display("FAILED: 1'bz <-> 1'bx returned %b not 1'bx", leb); pass = 1'b0; end if (lec !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b0 returned %b not 1'bx", lec); pass = 1'b0; end if (led !== 1'bx) begin $display("FAILED: 1'bx <-> 1'b0 returned %b not 1'bx", led); pass = 1'b0; end if (lee !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bz returned %b not 1'bx", lee); pass = 1'b0; end if (lef !== 1'bx) begin $display("FAILED: 1'bx <-> 1'bx returned %b not 1'bx", lef); pass = 1'b0; end if (ler0 !== 1'b1) begin $display("FAILED: 0.0 <-> 1'b0 returned %b not 1'b1", ler0); pass = 1'b0; end if (ler1 !== 1'b0) begin $display("FAILED: 1'b0 <-> 2.0 returned %b not 1'b1", ler1); pass = 1'b0; end if (ler2 !== 1'bx) begin $display("FAILED: 2.0 <-> 1'bx returned %b not 1'b1", ler2); pass = 1'b0; end if (ler3 !== 1'b1) begin $display("FAILED: -5.0 <-> 2.0 returned %b not 1'b1", ler3); pass = 1'b0; end if (lew !== 2'b01) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b01", lew); pass = 1'b0; end if (lews !== 2'b11) begin $display("FAILED: 4'b0110 <-> 4'b1001 returned %b not 2'b11", lews); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/l_impl.v000066400000000000000000000053601435245347300202110ustar00rootroot00000000000000module top; reg val1, val2; reg res ; reg pass; initial begin pass = 1'b1; val1 = 1'b0; val2 = 1'b0; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'b0 -> 1'b0 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'b1; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'b0 -> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'b0 -> 1'bx returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bz; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'b0 -> 1'bz returned %b not 1'b1", res); pass = 1'b0; end val1 = 1'b1; val2 = 1'b0; res = val1 -> val2; if (res !== 1'b0) begin $display("FAILED: 1'b1 -> 1'b0 returned %b not 1'b0", res); pass = 1'b0; end val2 = 1'b1; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'b1 -> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'b1 -> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'b1 -> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bx; val2 = 1'b0; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx -> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'bx -> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx -> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bx -> 1'bz returned %b not 1'bx", res); pass = 1'b0; end val1 = 1'bz; val2 = 1'b0; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz -> 1'b0 returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'b1; res = val1 -> val2; if (res !== 1'b1) begin $display("FAILED: 1'bz -> 1'b1 returned %b not 1'b1", res); pass = 1'b0; end val2 = 1'bx; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz -> 1'bx returned %b not 1'bx", res); pass = 1'b0; end val2 = 1'bz; res = val1 -> val2; if (res !== 1'bx) begin $display("FAILED: 1'bz -> 1'bz returned %b not 1'bx", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/land2.v000066400000000000000000000044151435245347300177350ustar00rootroot00000000000000/* * land2 - a verilog test for logical and operator && in boolean context * * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.com) * Modified by SDW to self test. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module land2; reg Clk; reg a; reg b; reg c; reg error; wire q; wire q_calc; tand tand_m(q, q_calc, a, b, c); initial Clk = 0; always #10 Clk = ~Clk; always @(posedge Clk) begin #1; if(q != q_calc) begin $display("FAILED - expr && using %b%b%b is %b s/b %b", a, b, c, q,q_calc); error = 1; end end reg [3:0] bvec; integer xa; integer xb; integer xc; initial begin bvec = 4'bzx10 ; error = 0; for(xa = 0; xa <= 3; xa = xa + 1) for(xb = 0; xb <= 3; xb = xb + 1) for(xc = 0; xc <= 3; xc = xc + 1) begin @(posedge Clk) a = bvec[xa]; b = bvec[xb]; c = bvec[xc]; end // for (var3 = 0; var3 <= 3; var3 = var3 + 1) if(error == 0 ) $display("PASSED"); $finish; end endmodule module tand(q, q_calc, a, b, c); output q; output q_calc; input a; input b; input c; wire q = ( (a===b) && (b===c) ); reg q_calc; always @(a or b or c) begin if(a === b) begin if( b === c) q_calc = 1'b1; else q_calc = 1'b0; end else q_calc = 1'b0; end endmodule // foo iverilog-12_0/ivtest/ivltests/land3.v000066400000000000000000000046451435245347300177430ustar00rootroot00000000000000/* * land3 - a verilog test for logical and operator && in a conditional. * * Copyright (C) 1999 Stephen G. Tell * Portions inspired by qmark.v by Steven Wilson (stevew@home.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, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ module land3; reg Clk; reg a; reg b; reg c; reg error; wire q; wire q_calc; tand tand_m(q,q_calc, a, b, c); initial Clk = 0; always #10 Clk = ~Clk; always @(posedge Clk) begin #1 ; if(q != q_calc) begin $display("FAILED - Cond && failed for vect %b%b%b - was %b, s/b %b", a,b,c,q,q_calc); error = 1; end end reg [3:0] bvec; integer xa, xb, xc; initial begin error = 0; bvec = 4'bzx10 ; for(xa = 0; xa < 4; xa = xa + 1) for(xb = 0; xb < 4; xb = xb + 1) for(xc = 0; xc < 4; xc = xc + 1) begin @(posedge Clk) a = bvec[xa]; b = bvec[xb]; c = bvec[xc]; end // for (var3 = 0; var3 <= 3; var3 = var3 + 1) @(posedge Clk) ; @(posedge Clk) ; if(error == 0) $display("PASSED"); $finish; end endmodule module tand(q, q_calc, a, b, c); output q; output q_calc; input a; input b; input c; reg q; reg q_calc; always @(a or b or c) begin if(a===b && b===c) q <= 1; else q <= 0; end // always @ (a or b or c) // Added to allow 2nd calculation // We use the if (a === b) formulation - it's part // of the base set that is need to do ANY tests.. always @(a or b or c) begin if( a===b) begin if(b === c) q_calc = 1'b1; else q_calc = 1'b0; end else q_calc = 1'b0; end endmodule // foo iverilog-12_0/ivtest/ivltests/land4.v000066400000000000000000000026341435245347300177400ustar00rootroot00000000000000// // Copyright (c) 2002 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; reg ena, wea; reg enb, web; reg clk; reg out = 0; always @(posedge clk) begin if ((ena == 1) && (wea == 1) && (enb == 1) && (web == 1)) out <= 1; end initial begin clk = 0; ena = 0; enb = 0; wea = 0; web = 0; $monitor("clk=%b: ena=%b, enb=%b, wea=%b, web=%b --> out=%b", clk, ena, enb, wea, web, out); #1 clk = 1; #1 clk = 0; ena = 1; enb = 1; #1 clk = 1; #1 clk = 0; wea = 1; web = 1; #1 clk = 1; #1 clk = 0; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/land5.v000066400000000000000000000007321435245347300177360ustar00rootroot00000000000000module main; reg [1:0] a, b; reg flag; (* ivl_combinational *) always @(a, b) flag = a && b; (* ivl_synthesis_off *) initial begin a = 1; b = 0; #1 if (flag !== 0) begin $display("FAILED -- a=%b, b=%b, flag=%b", a, b, flag); $finish; end b = 2; #1 if (flag !== 1) begin $display("FAILED -- a=%b, b=%b, flag=%b", a, b, flag); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/landor1.v000066400000000000000000000004111435245347300202650ustar00rootroot00000000000000module test; reg [1:0] r1, r2; initial begin r1 = 2'd2; r2 = 2'd0; if (r1 || r2) $display("PASSED"); else $display("FAILED"); r1 = 2'd2; r2 = 2'd1; if (r1 && r2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/lcatsynth.v000066400000000000000000000013201435245347300207360ustar00rootroot00000000000000module main; reg q0, q1, clk, clr; (* ivl_synthesis_on *) always @(posedge clk, posedge clr) if (clr) begin //q0 <= 0; //q1 <= 0; {q0, q1} <= 2'b00; end else begin {q1, q0} <= {q1, q0} + 1; end (* ivl_synthesis_off *) initial begin clk = 0; clr = 1; #1 clk = 1; #1 clk = 0; if ({q1,q0} !== 2'b00) begin $display("FAILED"); $finish; end clr = 0; #1 clk = 1; #1 clk = 0; if ({q1,q0} !== 2'b01) begin $display("FAILED"); $finish; end #1 clk = 1; #1 clk = 0; if ({q1,q0} !== 2'b10) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/ldelay1.v000066400000000000000000000030371435245347300202670ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: ldelay1.v,v 1.2 2007/12/06 02:31:10 stevewilliams Exp $ // Test for delays in structural logic. Inertial delays module test; wire q; reg a, b; and #6 (q, a, b); task ok; input qq; reg error; begin if (q !== qq) begin error = 1; $display("%0d: FAILED: q=%b, expect %b", $time, q, qq); end end endtask initial begin ok.error = 0; // $dumpvars; a <= 0; b <= 1; #5 ok(1'b x); #2 ok(1'b 0); a <= 1; #5 ok(1'b 0); #2 ok(1'b 1); a <= 0; #3 ok(1'b 1); a <= 1; #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); if (!ok.error) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ldelay2.v000066400000000000000000000024651435245347300202740ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: ldelay2.v,v 1.2 2007/12/06 02:31:10 stevewilliams Exp $ // Test for delays in structural logic. Inertial delays suppress event. module test; wire q; reg a, b; xor #1 (q, a, b); reg error; initial begin error = 0; #2; @(q); error = 1; $display("%0d: FAILED: q=%b", $time, q); end initial begin // $dumpvars; a = 0; b = 1; #3; a = 1; b = 0; #2; a = 0; b = 1; #3; if (!error) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ldelay3.v000066400000000000000000000032451435245347300202720ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: ldelay3.v,v 1.2 2007/12/06 02:31:10 stevewilliams Exp $ // Test for delays in structural logic. timescale `timescale 1ns/100ps module test; wire q; reg a, b; gate gg (q, a, b); task ok; input qq; reg error; begin if (q !== qq) begin error = 1; $display("%0d: FAILED: q=%b, expect %b", $time, q, qq); end end endtask initial begin ok.error = 0; // $dumpvars; a <= 0; b <= 1; #5.5 ok(1'b x); #0.1 ok(1'b 0); a <= 1; #5.5 ok(1'b 0); #0.1 ok(1'b 1); a <= 0; #3 ok(1'b 1); a <= 1; #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); #1 ok(1'b 1); if (!ok.error) $display("PASSED"); end endmodule `timescale 1ps/1ps module gate(q, a, b); output q; input a, b; and #5555 (q, a, b); endmodule iverilog-12_0/ivtest/ivltests/ldelay4.v000066400000000000000000000034771435245347300203020ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: ldelay4.v,v 1.3 2007/12/06 02:31:10 stevewilliams Exp $ // Test for delays in structural logic. Differential clock receiver UDP. module test; wire q, e; reg a, b; drec #1 rec(q, a, b); edet det (e, q); reg error; initial begin error = 0; #2; forever @(e) if (e !== 1'bx) begin // Fail on anything other then x. error = 1; $display("%0d: FAILED: e=%b", $time, e); end end always @(q) $display("%d: q=%b", $time, q); initial begin // $dumpvars; a = 0; b = 1; #3; a = 1; b = 0; #2; a = 0; b = 1; #3; if (!error) $display("PASSED"); end endmodule // differential receiver primitive drec (q, a, b); output q; input a, b; table 1 0 : 1 ; 0 1 : 0 ; endtable endprimitive // flag any edges to or from 'bx primitive edet (q, i); output q; input i; reg q; table (?x) : ? : 1; (x?) : ? : 0; endtable endprimitive iverilog-12_0/ivtest/ivltests/ldelay5.v000066400000000000000000000025031435245347300202700ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: ldelay5.v,v 1.1 2001/12/26 23:45:57 sib4 Exp $ // Test for delays in structural logic. Multiple UDP instances. module test; wire [1:2] q, a, b; drec U1(q[1], a[1], b[1]); drec U2(q[2], a[2], b[2]); initial $display("PASSED"); endmodule module drec (q, a, b); output q; input a, b; U_drec #1 U(q, a, b); endmodule primitive U_drec (q, a, b); output q; input a, b; table 1 0 : 1 ; 0 1 : 0 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/lh_catadd.v000066400000000000000000000024271435245347300206410ustar00rootroot00000000000000/* * Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; wire [3:0] a = 7, b = 13 ; wire [3:0] sum ; wire carry ; assign {carry,sum} = a + b ; initial begin #1 if (carry !== 1'b1) begin $display("FAILED: carry === %b", carry); $finish; end if (sum !== 4'b0100) begin $display("FAILED: sum === %b", sum); $finish; end $display("Correct results {carry,sum} === %b,%b", carry, sum); $display("PASSED"); end endmodule /* test */ iverilog-12_0/ivtest/ivltests/lh_memcat.v000066400000000000000000000034741435245347300206720ustar00rootroot00000000000000module main; reg clk, rst, done; wire [31:0] x; reg [3:0] a; reg [23:0] in, out; reg [2:0] a_fifo_cam_indices[3:0], lt_fifo_cam_indices[3:0]; // Debug signals to see 'em under signalscan // -- iverilog generates a warning here wire [2:0] db0_a_fifo_cam_indices = a_fifo_cam_indices[0]; // generate a clock always #10 clk = ~clk; // -- iverilog generates a warning here assign x[31:0] = { 28'hfffffff, (~a[3:0] + 4'd1) }; initial begin $display ("\n<< BEGIN >>"); rst = 1'b0; a[3:0] = 4'b0101; // -- iverilog internal value is not dealt with correctly (see value out[23:0] = ( rst ? 24'o7654_3210 : in[23:0] ); casex ( done ) // -- iverilog generate errors - "could not match signal" 1'b1: { a_fifo_cam_indices[3], a_fifo_cam_indices[2], a_fifo_cam_indices[1], a_fifo_cam_indices[0] } = {3'b000, lt_fifo_cam_indices[3], lt_fifo_cam_indices[2], lt_fifo_cam_indices[1]}; 1'b0: { a_fifo_cam_indices[3], a_fifo_cam_indices[2], a_fifo_cam_indices[1], a_fifo_cam_indices[0] } = { lt_fifo_cam_indices[3], lt_fifo_cam_indices[2], lt_fifo_cam_indices[1], lt_fifo_cam_indices[0]}; endcase $display ("\n<< END >>"); $finish(0); end // Waves definition // initial // begin // $dumpfile("out.dump"); // $dumpvars(0, main); // end endmodule // main iverilog-12_0/ivtest/ivltests/lh_memcat2.v000066400000000000000000000035731435245347300207540ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program demonstrates the mixing of reg and memories in l-value * contatenations. */ module main; reg [3:0] mem [2:0]; reg a, b; initial begin mem[0] = 0; mem[1] = 0; mem[2] = 0; {b, mem[1], a} = 6'b0_0000_1; if (a !== 1'b1) begin $display("FAILED -- a = %b", a); $finish; end if (mem[1] !== 4'b0000) begin $display("FAILED -- mem[1] = %b", mem[1]); $finish; end if (b !== 1'b0) begin $display("FAILED -- b = %b", b); $finish; end {b, mem[1], a} = 6'b0_1111_0; if (a !== 1'b0) begin $display("FAILED -- a = %b", a); $finish; end if (mem[0] !== 4'b0000) begin $display("FAILED -- mem[0] - %b", mem[0]); $finish; end if (mem[1] !== 4'b1111) begin $display("FAILED -- mem[1] = %b", mem[1]); $finish; end if (b !== 1'b0) begin $display("FAILED -- b = %b", b); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/lh_memcat3.v000066400000000000000000000036171435245347300207540ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program demonstrates the mixing of reg and memories in l-value * contatenations. */ module main; reg [3:0] mem [2:0]; reg a, b; initial begin mem[0] = 0; mem[1] = 0; mem[2] = 0; {b, mem[1], a} <= 6'b0_0000_1; #1 if (a !== 1'b1) begin $display("FAILED -- a = %b", a); $finish; end if (mem[1] !== 4'b0000) begin $display("FAILED -- mem[1] = %b", mem[1]); $finish; end if (b !== 1'b0) begin $display("FAILED -- b = %b", b); $finish; end {b, mem[1], a} <= 6'b0_1111_0; #1 if (a !== 1'b0) begin $display("FAILED -- a = %b", a); $finish; end if (mem[0] !== 4'b0000) begin $display("FAILED -- mem[0] - %b", mem[0]); $finish; end if (mem[1] !== 4'b1111) begin $display("FAILED -- mem[1] = %b", mem[1]); $finish; end if (b !== 1'b0) begin $display("FAILED -- b = %b", b); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/lh_varindx.v000066400000000000000000000026131435245347300210710ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate left hand variable index module main ; reg [3:0] a,b; reg c; reg error; always @(c or b) a[b] = c; initial begin #1 ; a = 4'b1111; error = 0; b = 1'b0; c = 1'b0; #1 ; if(a != 4'b1110) begin $display("FAILED - var index - a = %b, [b] = %d, c=%b",a,b,c); error = 1; end #1 ; b = 1; #1 ; if(a != 4'b1100) begin $display("FAILED - var index - a = %b, [b] = %d, c=%b",a,b,c); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/lh_varindx2.v000066400000000000000000000030031435245347300211450ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program is designed to test non-constant bit selects in the * concatenated l-value of procedural assignment. */ module main; reg [3:0] vec; reg a; integer i; initial begin vec = 4'b0000; a = 0; if (vec !== 4'b0000) begin $display("FAILED -- initialized vec to %b", vec); $finish; end for (i = 0 ; i < 4 ; i = i + 1) begin { a, vec[i] } = i; end if (vec !== 4'b1010) begin $display("FAILED == vec (%b) is not 1010", vec); $finish; end if (a !== 1'b1) begin $display("FAILED -- a (%b) is not 1", a); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/lh_varindx3.v000066400000000000000000000030071435245347300211520ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program is designed to test non-constant bit selects in the * concatenated l-value of procedural assignment. */ module main; reg [3:0] vec; reg a; integer i; initial begin vec = 4'b0000; a = 0; if (vec !== 4'b0000) begin $display("FAILED -- initialized vec to %b", vec); $finish; end for (i = 0 ; i < 4 ; i = i + 1) begin { a, vec[i] } = 2'b11; end if (vec !== 4'b1111) begin $display("FAILED == vec (%b) is not 1111", vec); $finish; end if (a !== 1'b1) begin $display("FAILED -- a (%b) is not 1", a); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/lh_varindx4.v000066400000000000000000000030121435245347300211470ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program is designed to test non-constant bit selects in the * concatenated l-value of procedural assignment. */ module main; reg [3:0] vec; reg a; integer i; initial begin vec = 4'b0000; a = 0; if (vec !== 4'b0000) begin $display("FAILED -- initialized vec to %b", vec); $finish; end for (i = 0 ; i < 4 ; i = i + 1) begin #1 { a, vec[i] } <= i; end #1 if (vec !== 4'b1010) begin $display("FAILED == vec (%b) is not 1010", vec); $finish; end if (a !== 1'b1) begin $display("FAILED -- a (%b) is not 1", a); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/lh_varindx5.v000066400000000000000000000030161435245347300211540ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program is designed to test non-constant bit selects in the * concatenated l-value of procedural assignment. */ module main; reg [3:0] vec; reg a; integer i; initial begin vec = 4'b0000; a = 0; if (vec !== 4'b0000) begin $display("FAILED -- initialized vec to %b", vec); $finish; end for (i = 0 ; i < 4 ; i = i + 1) begin #1 { a, vec[i] } <= 2'b11; end #1 if (vec !== 4'b1111) begin $display("FAILED == vec (%b) is not 1111", vec); $finish; end if (a !== 1'b1) begin $display("FAILED -- a (%b) is not 1", a); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/line_directive.v000066400000000000000000000006341435245347300217210ustar00rootroot00000000000000module test(); `define MACRO \ $display("file %s line %0d", \ `__FILE__, `__LINE__); initial begin $display("file %s line %0d", `__FILE__, `__LINE__); `line 1 "real_source.v" 0 $display("file %s line %0d", `__FILE__, `__LINE__); `include "line_directive_inc.v" $display("file %s line %0d", `__FILE__, `__LINE__); `MACRO $display("file %s line %0d", `__FILE__, `__LINE__); end endmodule iverilog-12_0/ivtest/ivltests/line_directive_inc.v000066400000000000000000000000661435245347300225510ustar00rootroot00000000000000 $display("file %s line %0d", `__FILE__, `__LINE__); iverilog-12_0/ivtest/ivltests/localparam_implicit.v000066400000000000000000000010441435245347300227350ustar00rootroot00000000000000// Check that all parameters in a parameter port list after a `localparam` get // elaborated as localparams, until the next `parameter`. module a #( parameter A = 1, B = 2, localparam C = 3, D = 4, parameter E = 5 ); initial begin if (A == 10 && B == 20 && C == 3 && D == 4 && E == 50) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module b; a #( .A(10), .B(20), // Cannot override localparam .C(30), // Cannot override localparam .D(40), .E(50) ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/localparam_implicit2.v000066400000000000000000000010401435245347300230130ustar00rootroot00000000000000// Check that all parameters in a parameter port list after a `localparam` get // elaborated as localparams, until the next `parameter`. module a #( parameter A = 1, B = 2, localparam C = 3, D = 4, parameter E = 5 ); initial begin if (A == 10 && B == 20 && C == 3 && D == 4 && E == 50) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module b; a #( .A(10), .B(20), .C(30), // This will cause an error .D(40), // This will cause an error .E(50) ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/localparam_implicit3.v000066400000000000000000000011231435245347300230160ustar00rootroot00000000000000// Check that all parameters in a parameter port list after a `localparam` get // elaborated as localparams, until the next `parameter`. Check that this is the // case even when the data type of the parameter is redefined. module a #( parameter A = 1, B = 2, localparam C = 3, real D = 4, parameter E = 5 ); initial begin if (A == 10 && B == 20 && C == 3 && D == 4 && E == 50) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module b; a #( .A(10), .B(20), .D(40), // This will cause an error .E(50) ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/localparam_query.v000066400000000000000000000030631435245347300222730ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for array query functions applied to localparams. module lparam_query; localparam const_param = 16'b0001110111001111; initial begin if($left(const_param) !== 15) begin $display("FAILED 1"); $finish(); end if($right(const_param) !== 0) begin $display("FAILED 2"); $finish(); end if($high(const_param) !== 15) begin $display("FAILED 3"); $finish(); end if($low(const_param) !== 0) begin $display("FAILED 4"); $finish(); end if($increment(const_param) !== 1) begin $display("FAILED 5"); $finish(); end if($size(const_param) !== 16) begin $display("FAILED 6"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/localparam_type.v000066400000000000000000000011361435245347300221060ustar00rootroot00000000000000module top; localparam irparam = -1.0; localparam iiparam = -1; localparam [7:0] uparam = -1.0; localparam signed [7:0] sparam = -1.0; localparam real rparam = -1; localparam realtime rtparam = -1; localparam integer iparam = -1.0; localparam time tparam = -1.0; initial begin $display("Implicit real: ", irparam); $display("Implicit integer: ", iiparam); $display("Unsigned: ", uparam); $display("Signed: ", sparam); $display("Real: ", rparam); $display("Real time: ", rtparam); $display("Integer: ", iparam); $display("Time: ", tparam); end endmodule iverilog-12_0/ivtest/ivltests/localparam_type2.v000066400000000000000000000143761435245347300222020ustar00rootroot00000000000000module test(); localparam signed snv1 = 4'd1; localparam signed [2:0] s3v1 = 4'd1; localparam signed [3:0] s4v1 = 4'd1; localparam signed [4:0] s5v1 = 4'd1; localparam signed snv15 = 4'd15; localparam signed [2:0] s3v15 = 4'd15; localparam signed [3:0] s4v15 = 4'd15; localparam signed [4:0] s5v15 = 4'd15; localparam signed snvm1 = -4'sd1; localparam signed [2:0] s3vm1 = -4'sd1; localparam signed [3:0] s4vm1 = -4'sd1; localparam signed [4:0] s5vm1 = -4'sd1; localparam signed snrm1 = -1.0; localparam signed [2:0] s3rm1 = -1.0; localparam signed [3:0] s4rm1 = -1.0; localparam signed [4:0] s5rm1 = -1.0; localparam nnv1 = 4'd1; localparam [2:0] u3v1 = 4'd1; localparam [3:0] u4v1 = 4'd1; localparam [4:0] u5v1 = 4'd1; localparam nnv15 = 4'd15; localparam [2:0] u3v15 = 4'd15; localparam [3:0] u4v15 = 4'd15; localparam [4:0] u5v15 = 4'd15; localparam nnvm1 = -4'sd1; localparam [2:0] u3vm1 = -4'sd1; localparam [3:0] u4vm1 = -4'sd1; localparam [4:0] u5vm1 = -4'sd1; localparam nnrm1 = -1.0; localparam [2:0] u3rm1 = -1.0; localparam [3:0] u4rm1 = -1.0; localparam [4:0] u5rm1 = -1.0; reg fail = 0; reg match; initial begin match = ($bits(snv1) == 4) && (snv1 === 1); $display("snv1 : %2d (%0d`b%b) %c", snv1, $bits(snv1), snv1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3v1) == 3) && (s3v1 === 1); $display("s3v1 : %2d (%0d`b%b) %c", s3v1 , $bits(s3v1), s3v1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4v1) == 4) && (s4v1 === 1); $display("s4v1 : %2d (%0d`b%b) %c", s4v1 , $bits(s4v1), s4v1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5v1) == 5) && (s5v1 === 1); $display("s5v1 : %2d (%0d`b%b) %c", s5v1 , $bits(s5v1), s5v1, match ? " " : "*"); fail = fail || !match; match = ($bits(snv15) == 4) && (snv15 === -1); $display("snv15 : %2d (%0d`b%b) %c", snv15, $bits(snv15), snv15, match ? " " : "*"); fail = fail || !match; match = ($bits(s3v15) == 3) && (s3v15 === -1); $display("s3v15 : %2d (%0d`b%b) %c", s3v15, $bits(s3v15), s3v15, match ? " " : "*"); fail = fail || !match; match = ($bits(s4v15) == 4) && (s4v15 === -1); $display("s4v15 : %2d (%0d`b%b) %c", s4v15, $bits(s4v15), s4v15, match ? " " : "*"); fail = fail || !match; match = ($bits(s5v15) == 5) && (s5v15 === 15); $display("s5v15 : %2d (%0d`b%b) %c", s5v15, $bits(s5v15), s5v15, match ? " " : "*"); fail = fail || !match; match = ($bits(snvm1) == 4) && (snvm1 === -1); $display("snvm1 : %2d (%0d`b%b) %c", snvm1, $bits(snvm1), snvm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3vm1) == 3) && (s3vm1 === -1); $display("s3vm1 : %2d (%0d`b%b) %c", s3vm1, $bits(s3vm1), s3vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4vm1) == 4) && (s4vm1 === -1); $display("s4vm1 : %2d (%0d`b%b) %c", s4vm1, $bits(s4vm1), s4vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5vm1) == 5) && (s5vm1 === -1); $display("s5vm1 : %2d (%0d`b%b) %c", s5vm1, $bits(s5vm1), s5vm1, match ? " " : "*"); fail = fail || !match; match = (snrm1 == -1); $display("snrm1 : %4.1f %c", snrm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3rm1) == 3) && (s3rm1 === -1); $display("s3rm1 : %2d (%0d`b%b) %c", s3rm1, $bits(s3rm1), s3rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4rm1) == 4) && (s4rm1 === -1); $display("s4rm1 : %2d (%0d`b%b) %c", s4rm1, $bits(s4rm1), s4rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5rm1) == 5) && (s5rm1 === -1); $display("s5rm1 : %2d (%0d`b%b) %c", s5rm1, $bits(s5rm1), s5rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(nnv1) == 4) && (nnv1 === 1); $display("nnv1 : %2d (%0d`b%b) %c", nnv1, $bits(nnv1), nnv1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3v1) == 3) && (u3v1 === 1); $display("u3v1 : %2d (%0d`b%b) %c", u3v1 , $bits(u3v1), u3v1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4v1) == 4) && (u4v1 === 1); $display("u4v1 : %2d (%0d`b%b) %c", u4v1 , $bits(u4v1), u4v1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5v1) == 5) && (u5v1 === 1); $display("u5v1 : %2d (%0d`b%b) %c", u5v1 , $bits(u5v1), u5v1, match ? " " : "*"); fail = fail || !match; match = ($bits(nnv15) == 4) && (nnv15 === 15); $display("nnv15 : %2d (%0d`b%b) %c", nnv15, $bits(nnv15), nnv15, match ? " " : "*"); fail = fail || !match; match = ($bits(u3v15) == 3) && (u3v15 === 7); $display("u3v15 : %2d (%0d`b%b) %c", u3v15, $bits(u3v15), u3v15, match ? " " : "*"); fail = fail || !match; match = ($bits(u4v15) == 4) && (u4v15 === 15); $display("u4v15 : %2d (%0d`b%b) %c", u4v15, $bits(u4v15), u4v15, match ? " " : "*"); fail = fail || !match; match = ($bits(u5v15) == 5) && (u5v15 === 15); $display("u5v15 : %2d (%0d`b%b) %c", u5v15, $bits(u5v15), u5v15, match ? " " : "*"); fail = fail || !match; match = ($bits(nnvm1) == 4) && (nnvm1 === -1); $display("nnvm1 : %2d (%0d`b%b) %c", nnvm1, $bits(nnvm1), nnvm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3vm1) == 3) && (u3vm1 === 7); $display("u3vm1 : %2d (%0d`b%b) %c", u3vm1, $bits(u3vm1), u3vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4vm1) == 4) && (u4vm1 === 15); $display("u4vm1 : %2d (%0d`b%b) %c", u4vm1, $bits(u4vm1), u4vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5vm1) == 5) && (u5vm1 === 31); $display("u5vm1 : %2d (%0d`b%b) %c", u5vm1, $bits(u5vm1), u5vm1, match ? " " : "*"); fail = fail || !match; match = (nnrm1 == -1.0); $display("nnrm1 : %4.1f %c", nnrm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3rm1) == 3) && (u3rm1 === 7); $display("u3rm1 : %2d (%0d`b%b) %c", u3rm1, $bits(u3rm1), u3rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4rm1) == 4) && (u4rm1 === 15); $display("u4rm1 : %2d (%0d`b%b) %c", u4rm1, $bits(u4rm1), u4rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5rm1) == 5) && (u5rm1 === 31); $display("u5rm1 : %2d (%0d`b%b) %c", u5rm1, $bits(u5rm1), u5rm1, match ? " " : "*"); fail = fail || !match; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/logical_short_circuit.v000066400000000000000000000042731435245347300233120ustar00rootroot00000000000000module test; // The SystemVerilog standard requires that the right side of a logical operator // is not evaluated under certain conditions. // For && if the left hand side is false the right hand side is not evalualted // For || if the left hand side is true the right hand side is not evalualted wire a0 = 1'b0; wire a1 = 1'b1; wire ax = 1'bx; wire az = 1'bz; integer b; logic [1:0] c; bit failed = 1'b0; initial begin // AND with first parameter 1'b0 b = 0; c = 2'b00; if (a0 && b++ && ++b) c = 2'b01; failed |= b !== 0; failed |= c !== 2'b00; c = a0 && b++ && ++b; failed |= b !== 0; failed |= c !== 2'b00; // AND with first parameter 1'b1 b = 0; c = 2'b00; if (a1 && b++ && ++b) c = 2'b01; failed |= b !== 1; failed |= c !== 2'b00; c = a1 && b++ && ++b; failed |= b !== 3; failed |= c !== 2'b01; // AND with first parameter 1'bz b = 0; c = 2'b00; if (az && b++ && ++b) c = 2'b01; failed |= b !== 1; failed |= c !== 2'b00; c = az && b++ && ++b; failed |= b !== 3; failed |= c !== 2'b0x; // AND with first parameter 1'bz b = 0; c = 0; if (ax && b++ && ++b) c = 2'b01; failed |= b !== 1; failed |= c !== 2'b00; c = ax && b++ && ++b; failed |= b !== 3; failed |= c !== 2'b0x; // OR with first parameter 1'b0 b = 0; c = 0; if (a0 || b++ || ++b) c = 2'b01; failed |= b !== 2; failed |= c !== 2'b01; c = a0 || b++ || ++b; failed |= b !== 3; failed |= c !== 2'b01; // OR with first parameter 1'b1 b = 0; c = 2'b00; if (a1 || b++ || ++b) c = 2'b01; failed |= b !== 0; failed |= c !== 2'b01; c = a1 || b++ || ++b; failed |= b !== 0; failed |= c !== 2'b01; // OR with first parameter 1'bz b = 0; c = 2'b00; if (az || b++ || ++b) c = 2'b01; failed |= b !== 2; failed |= c !== 2'b01; b = 0; c = az || b++; failed |= b !== 1; failed |= c !== 2'b0x; // OR with first parameter 1'bz b = 0; c = 0; if (ax || b++ || ++b) c = 2'b01; failed |= b !== 2; failed |= c !== 2'b01; b = 0; c = ax || b++; failed |= b !== 1; failed |= c !== 2'b0x; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/logp2.v000066400000000000000000000015241435245347300177560ustar00rootroot00000000000000module test; logic b; logic [9:0] b10; logic signed bs; logic unsigned bu; logic signed [6:0] bs7; logic unsigned [5:0] bu6; initial begin b = 1; b10 = 100; bs = 0; bu = 1; bs7 = -17; bu6 = 21; #1; if (b * b10 !== 100) begin $display ("FAILED 1"); $finish; end if (bs * b10 !== 0) begin $display ("FAILED 2" ); $finish; end if (bu * b10 !== 100) begin $display ("FAILED 3"); $finish; end if (bs7 * 1 !== -17) begin $display ("FAILED 4"); $finish; end if (bu6 * b !== 21) begin $display ("FAILED 5"); $finish; end #1; bu6 = 6'bx1100z; if (bu6 * 1'b1 !== 6'bxxxxxx) begin $display ("FAILED 6"); $finish; end $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/long_div.v000066400000000000000000000011171435245347300205320ustar00rootroot00000000000000module test(); reg [31:0] a, b; reg [65:0] a_l, b_l; wire [31:0] result = a / b; wire [31:0] mod = a % b; wire [65:0] result_l = a_l / b_l; wire [65:0] mod_l = a_l % b_l; initial begin a = 'h1; b = 'h1; a_l = 'h1; b_l = 'h1; #1; // Need some delay for the calculations to run. // b_l = 'h0; // This will now fail with an error. $display("Using normal math routines."); $display("Result: %0d\nModulus: %h", result, mod); $display("\nUsing wide math routines."); $display("Result: %0d\nModulus: %h", result_l, mod_l); end endmodule iverilog-12_0/ivtest/ivltests/macro2.v000066400000000000000000000003201435245347300201070ustar00rootroot00000000000000`define TBMESS(str) $display("PAS%s", str ); // 1364-2001 S19.3 "The text macro facility is not affected by the compiler // directive `resetall." `resetall module main; initial `TBMESS("SED") endmodule iverilog-12_0/ivtest/ivltests/macro_args.v000066400000000000000000000001451435245347300210460ustar00rootroot00000000000000`ifndef FOO `define FOO `define BAR(x) `endif module macro_args(); macro_args_sub sub(); endmodule iverilog-12_0/ivtest/ivltests/macro_args_sub.v000066400000000000000000000000541435245347300217160ustar00rootroot00000000000000module macro_args_sub(); `BAR(0) endmodule iverilog-12_0/ivtest/ivltests/macro_redefinition.v000066400000000000000000000001501435245347300225650ustar00rootroot00000000000000module test(); `define MACRO 1 `define MACRO 1 `define MACRO 2 `undef MACRO `define MACRO 1 endmodule iverilog-12_0/ivtest/ivltests/macro_replacement.v000066400000000000000000000001501435245347300224050ustar00rootroot00000000000000module test(); `define MACRO 1 `define MACRO 1 `define MACRO 2 `undef MACRO `define MACRO 1 endmodule iverilog-12_0/ivtest/ivltests/macro_str_esc.v000066400000000000000000000013551435245347300215600ustar00rootroot00000000000000`define DEF1 "string1" `define DEF2 "string2\"" `define DEF3 a\b `define DEF4(a) a module top; initial begin $display("Using ``celldefine gives: %s", ``celldefine); $display("Plain ``celldefine gives: ", ``celldefine); $display("Using `DEF1 gives: %s", `DEF1); $display("Using ``DEF1 gives: %s", ``DEF1); $display("Plain ``DEF1 gives: ", ``DEF1); $display("Using `DEF2 gives: %s", `DEF2); $display("Using ``DEF2 gives: %s", ``DEF2); $display("Plain ``DEF2 gives: ", ``DEF2); $display("Using ``DEF3 gives: %s", ``DEF3); $display("Plain ``DEF3 gives: ", ``DEF3); $display("Using ``DEF4(\"tmp\") gives: %s", ``DEF4("tmp")); $display("Plain ``DEF4(\"tmp\") gives: ", ``DEF4("tmp")); end endmodule iverilog-12_0/ivtest/ivltests/macro_with_args.v000066400000000000000000000027511435245347300221060ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker // This file may be freely copied for any purpose. module macro_with_args(); `define forward_and_reverse(str1,str2,str3) /* comment */ \ $write("%0s", str1); /* comment */ \ $write(".."); /* comment */ \ $write("%0s", str3); /* comment */ \ $write("%0s", str2); /* comment */ \ $write("%0s", str3); /* comment */ \ $write(".."); /* comment */ \ $write("%0s", str1); /* comment */ \ $write("\n") `define sqr( x ) (x * x) // comment `define sum( a /* comment */ , b /* comment */ ) /* comment */ \ (a + b) `define sumsqr( a // comment , b // comment ) \ `sum ( \ `sqr(a) \ , \ `sqr(b) \ ) `define no_args (a,b,c) `define null1 // null `define null2 integer value; reg [79:0] astr, bstr, cstr; initial begin `forward_and_reverse("first"," first,last ","last"); $sformat(astr, "(a%s)", ``null1); $sformat(bstr, " %s ", ``no_args); $sformat(cstr, "(c%s)", ``null2); `forward_and_reverse // comment ( // comment astr // comment , // comment bstr // comment , // comment cstr // comment ); // comment value = `sumsqr(3,4); $display("sumsqr(3,4) = %1d", value); if (value != `sqr(5)) $display("sumsqr expansion failed"); value = `sumsqr ( (2 + 3) /* 5 */ , (4 + 8) /* 12 */ ); $display("sumsqr(5,12) = %1d", value); if (value != `sqr(13)) $display("sumsqr expansion failed"); end endmodule iverilog-12_0/ivtest/ivltests/macsub.v000066400000000000000000000004231435245347300202020ustar00rootroot00000000000000module test(); integer j; integer jel; integer x; integer xel; `define A(j) (jel == 1 && j == 2) `define B(j) (jel \ == 1 && \ j == 2) initial begin j = 0; jel = 1; x = 2; xel = 3; if(`A(x) && `B(x)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/mangle.v000066400000000000000000000023551435245347300202010ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: mangle.v,v 1.1 2001/06/19 13:52:13 ka6s Exp $ // $Log: mangle.v,v $ // Revision 1.1 2001/06/19 13:52:13 ka6s // Added 4 tests from Stephan Boettcher // // // Test of \escaped identifiers module mangle; reg \abc ; reg \`~!-_=+\|[]{};:'"",./<>? ; reg cde ; initial begin abc <= 1; \`~!-_=+\|[]{};:'"",./<>? <= 1; \cde <= 1; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/mangle_1.v000066400000000000000000000024651435245347300204230ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: mangle_1.v,v 1.1 2001/06/19 13:52:13 ka6s Exp $ // $Log: mangle_1.v,v $ // Revision 1.1 2001/06/19 13:52:13 ka6s // Added 4 tests from Stephan Boettcher // // Test of \escaped identifiers module a; wire \a.b ; m \c.d (\a.b ); initial begin \c.d . \y.z <= 1'b1; #1; if (\a.b === 1'b1) $display("PASSED"); else $display("FAILED"); end endmodule module m(x); output x; reg \y.z ; assign x = \y.z ; endmodule iverilog-12_0/ivtest/ivltests/many_drivers.v000066400000000000000000000101151435245347300214310ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: many_drivers.v,v 1.2 2001/07/21 02:30:44 stevewilliams Exp $ // $Log: many_drivers.v,v $ // Revision 1.2 2001/07/21 02:30:44 stevewilliams // Get the expected blended values right. // // Revision 1.1 2001/07/18 01:22:26 sib4 // test for nets with many drivers // module test; reg [66:0] in; wire out; buf (out, in[ 0]); buf (out, in[ 1]); buf (out, in[ 2]); buf (out, in[ 3]); buf (out, in[ 4]); buf (out, in[ 5]); buf (out, in[ 6]); buf (out, in[ 7]); buf (out, in[ 8]); buf (out, in[ 9]); buf (out, in[10]); buf (out, in[11]); buf (out, in[12]); buf (out, in[13]); buf (out, in[14]); buf (out, in[15]); buf (out, in[16]); buf (out, in[17]); buf (out, in[18]); buf (out, in[19]); buf (out, in[20]); buf (out, in[21]); buf (out, in[22]); buf (out, in[23]); buf (out, in[24]); buf (out, in[25]); buf (out, in[26]); buf (out, in[27]); buf (out, in[28]); buf (out, in[29]); buf (out, in[30]); buf (out, in[31]); buf (out, in[32]); buf (out, in[33]); buf (out, in[34]); buf (out, in[35]); buf (out, in[36]); buf (out, in[37]); buf (out, in[38]); buf (out, in[39]); buf (out, in[40]); buf (out, in[41]); buf (out, in[42]); buf (out, in[43]); buf (out, in[44]); buf (out, in[45]); buf (out, in[46]); buf (out, in[47]); buf (out, in[48]); buf (out, in[49]); buf (out, in[50]); buf (out, in[51]); buf (out, in[52]); buf (out, in[53]); buf (out, in[54]); buf (out, in[55]); buf (out, in[56]); buf (out, in[57]); buf (out, in[58]); buf (out, in[59]); buf (out, in[60]); buf (out, in[61]); buf (out, in[62]); buf (out, in[63]); buf (out, in[64]); buf (out, in[65]); buf (out, in[66]); reg err; // Verilog-XL yields out=x for all but the first two initial begin err = 0; in = 67'b0; #1 $display("in=%b out=%b", in, out); if (out!==1'b0) err = 1; in = ~67'b0; #1 $display("in=%b out=%b", in, out); if (out!==1'b1) err = 1; in = 67'bz; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'bx; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'h 5_55555555_55555555; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = ~67'h 5_55555555_55555555; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'h 0_xxxxxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = ~67'h 0_xxxxxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'h x_xxxxxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = ~67'h x_xxxxxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'h x_55555555_55555555; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = ~67'h x_55555555_55555555; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = 67'h 1_ffffxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; in = ~67'h 1_ffffxxxx_00000000; #1 $display("in=%b out=%b", in, out); if (out!==1'bx) err = 1; if (err) $display("FAILED"); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/mcl1.v000066400000000000000000000043311435245347300175660ustar00rootroot00000000000000/* * Copyright (c) 2001 Eric Brombaugh * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // test_simple.v - testbench for simple.mcl behavioral output // 01-22-01 E. Brombaugh /* * The ``simple'' module was generated by the synopsis module compiler * and is typical of the modules it generates. The testbench was hand * coded. This file was merged into a single file using the Verilog * preprocessor. */ `timescale 1ns / 10 ps module simple( y, a, b, c ); input [3:0] a; input [3:0] b; input [7:0] c; output [8:0] y; wire dpa_zero, dpa_one; wire [8:0] y_1_; assign dpa_zero= 1024'h0; assign dpa_one= 1024'h1; /* simple.mcl:4 module simple (y, a, b, c); */ /* simple.mcl:6 input signed [3:0] a, b; */ /* simple.mcl:7 input signed [7:0] c; */ /* simple.mcl:9 y = a*b+c; */ assign y_1_= ((a[2:0]-(a[3]<<3))*(b[2:0]-(b[3]<<3))+(c[6:0]-(c[7]<<7))); /* simple.mcl:5 output signed [8:0] y; */ assign y = y_1_[8:0]; /* simple.mcl:4 module simple (y, a, b, c); */ /* simple.mcl:9 y = a*b+c; */ /*User Defined Aliases */ endmodule module test_simple; reg [15:0] count; reg clk; reg [3:0] a, b; reg [7:0] c; wire [8:0] y; simple u1(y, a, b, c); initial begin count = 0; clk = 0; a = 0; b = 0; c = 0; end always #10 clk = ~clk; always @(posedge clk) begin a = count[3:0]; b = count[7:4]; c = count[15:8]; #10 $display("%h %h %h %h", a, b, c, y); count = count + 1; if(count == 0) $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/mcl2.v000066400000000000000000000046101435245347300175670ustar00rootroot00000000000000// test_mis.v - Testbench for mis.bvrl // 01-22-01 E. Brombaugh /* * Copyright (c) 2001 Eric Brombaugh * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * The mis'' module was generated by the synopsis module compiler * and is typical of the modules it generates. The testbench was hand * coded. This file was merged into a single file using the Verilog * preprocessor. */ `timescale 1ns / 10 ps module mis( y, a, b ); input [3:0] a; input [3:0] b; output [12:0] y; wire dpa_zero, dpa_one; wire [5:0] const__1_24_; wire [7:0] C0; wire [6:0] const__2_33_; wire [7:0] C1; wire [12:0] y_1_; assign dpa_zero= 1024'h0; assign dpa_one= 1024'h1; assign const__1_24_=- 1024'h18; assign const__2_33_=- 1024'h21; /* mis.mcl:4 module mis (y, a, b); */ /* mis.mcl:5 input signed [3:0] a, b; */ /* mis.mcl:10 C0 = -24; */ assign C0= ((const__1_24_[4:0]-(const__1_24_[5]<<5))); /* mis.mcl:11 C1 = -33; */ assign C1= ((const__2_33_[5:0]-(const__2_33_[6]<<6))); /* mis.mcl:13 y = C0*a + C1*b; */ assign y_1_= ((C0[6:0]-(C0[7]<<7))*(a[2:0]-(a[3]<<3))+ (C1[6:0]-(C1[7]<<7))*(b[2:0]-(b[3]<<3))); /* mis.mcl:6 output signed [12:0] y; */ assign y = y_1_[12:0]; /* mis.mcl:4 module mis (y, a, b); */ /* mis.mcl:13 y = C0*a + C1*b; */ /*User Defined Aliases */ endmodule module test_mis; reg [10:0] count; reg clk; reg [3:0] a, b; wire [12:0] y; mis u1(y, a, b); initial begin count = 0; clk = 0; a = 0; b = 0; end always #10 clk = ~clk; always @(posedge clk) begin a = count[3:0]; b = count[7:4]; #10 $display("%h %h %h", a, b, y); count = count + 1; if(count == 0) $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/mem1.dat000066400000000000000000000006601435245347300200750ustar00rootroot0000000000000000000000_00000001_00000000 00000000_00000010_00000000 00000000_00000100_00000000 00000000_00001000_00000001 00000000_00010000_00000000 00000000_00100000_00000000 00000000_01000000_00000000 00000000_10000000_00000000 00000001_00000000_00000000 00000010_00000000_00000000 00000100_00000000_00000000 00001000_00000000_00000000 00010000_00000000_00000000 00100000_00000000_00000010 01000000_00000000_00000000 10000000_00000000_00000000 iverilog-12_0/ivtest/ivltests/mem1.v000066400000000000000000000034741435245347300176000ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Log: mem1.v,v $ * Revision 1.2 2001/01/29 17:26:06 ka6s * Check in fixes contributed by Paul Campbell (Thanks Paul) * */ `define CLK 10 module main; reg [31:0] counter; integer i; reg [23:0] testvec [15:0]; reg clk; wire [23:0] data; reg write; initial begin write = 0; counter = 0; clk = 0; $readmemb("ivltests/mem1.dat", testvec, 0); for (i = 0; i < 16; i = i + 1) begin $write("mem[%d] = %x\n", i, testvec[i]); end end always begin #`CLK clk = ~clk; end assign data = (write) ? testvec[counter] : 24'bz; always @ (posedge clk) begin begin write = 1; #1 ; $write("%d %x\n", counter, data); write = 0; counter = counter + 1; if (counter == 16) $finish(0); end end endmodule iverilog-12_0/ivtest/ivltests/mem2port.v000066400000000000000000000024661435245347300205060ustar00rootroot00000000000000/* * Bug report: * * From: Hendrik * Subject: gEDA: Pass array element into module in iverilog 0.5 * To: geda-dev@seul.org * Date: Mon, 10 Sep 2001 11:53:04 +0800 */ module top; reg [6:0] x[2:0]; speak i0 (x[0], x[1], x[2]); initial begin #10 x[0] = 0; x[1] = 0; x[2] = 0; #100 x[0] = 1; #100 x[0] = 0; x[1] = 1; #100 x[1] = 0; x[2] = 1; #100 $finish; end endmodule module speak(x1, x2, x3); input [6:0] x1, x2, x3; always #100 $display ("%d: x1=%d, x2=%d, x3=%d", $time, x1, x2, x3); integer errors; initial begin errors = 0; #100 if (x1 !== 7'b0 || x2 !== 7'b0 || x3 !== 7'b0) begin errors = errors + 1; $display("FAILED"); end #100 if (x1 !== 7'b1 || x2 !== 7'b0 || x3 !== 7'b0) begin errors = errors + 1; $display("FAILED"); end #100 if (x1 !== 7'b0 || x2 !== 7'b1 || x3 !== 7'b0) begin errors = errors + 1; $display("FAILED"); end #100 if (x1 !== 7'b0 || x2 !== 7'b0 || x3 !== 7'b1) begin errors = errors + 1; $display("FAILED"); end if (errors === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/memassign.v000066400000000000000000000052151435245347300207170ustar00rootroot00000000000000// // Copyright (c) 1999 David Leask (david.leask@ctam.com.au) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Modified to be self checking /* ** The problem: ** Reading in a series of bytes, one per clock, to create a ** large vector which holds the bytes in a parallel form. */ module demo_assign_problem; reg [7:0] mem_buffer [0:3]; wire [31:0] big_word; reg error; reg [31:0] myconst; integer i; assign big_word[ 31: 24] = mem_buffer[0]; assign big_word[ 23: 16] = mem_buffer[1]; assign big_word[ 15: 8] = mem_buffer[2]; assign big_word[ 7: 0] = mem_buffer[3]; initial begin error = 0; for (i = 0; i < 4; i = i+1) mem_buffer[i] = 0; #50; mem_buffer[0] = 8'h12; #50; myconst = 32'h12_00_00_00; if(big_word !== 32'h12_00_00_00) begin $display("FAILED -Memory assign - expect %h, but have %h", myconst,big_word); error = 1; end #100 ; mem_buffer[1] = 8'h34; #50; myconst = 32'h12_34_00_00; if(big_word !== 32'h12_34_00_00) begin $display("FAILED -Memory assign - expect %h, but have %h", myconst,big_word); error = 1; end #100 ; mem_buffer[2] = 8'h56; #50; myconst = 32'h12_34_56_00; if(big_word !== 32'h12_34_56_00) begin $display("FAILED -Memory assign - expect %h, but have %h", myconst,big_word); error = 1; end #100; mem_buffer[3] = 8'h78; #50; myconst = 32'h12_34_56_00; if(big_word !== 32'h12_34_56_78) begin $display("FAILED - Memory assign - expect %h, but have %h", myconst,big_word); error = 1; end #100; mem_buffer[0] = 8'hab; #50; myconst = 32'hab_34_56_00; if(big_word !== 32'hab_34_56_78) begin $display("FAILED - Memory assign - expect %h, but have %h", myconst,big_word); error = 1; end #100; if (error ===0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/memidx.v000066400000000000000000000044251435245347300202210ustar00rootroot00000000000000/*********************************************************************** Array access test cases Copyright (C) 2001 Eric LaForest, ecl@pet.dhs.org Licenced under GPL ***********************************************************************/ module wire_test_case (array_out, clock, reset); output [15:0] array_out; input clock, reset; reg [3:0] readptr; reg [15:0] body [15:0]; wire [15:0] array_out; assign array_out = body[readptr]; // reg [15:0] array_out; // always @(readptr or body[readptr]) begin // array_out <= body[readptr]; // end always @(posedge clock) begin if (reset == 0) begin readptr <= 16'h0000; body[0] <= 16'h0001; // Fibonnacci body[1] <= 16'h0002; body[2] <= 16'h0003; body[3] <= 16'h0005; body[4] <= 16'h0008; body[5] <= 16'h000D; body[6] <= 16'h0015; end else begin readptr <= readptr + 16'h0001; end end endmodule module always_test_case (array_out, clock, reset); output [15:0] array_out; input clock, reset; reg [3:0] readptr; reg [15:0] body [15:0]; // wire [15:0] array_out; // assign array_out = body[readptr]; reg [15:0] array_out; always @(readptr or body[readptr]) begin array_out <= body[readptr]; end always @(posedge clock) begin if (reset == 0) begin readptr <= 16'h0000; body[0] <= 16'h0001; // Fibonnacci body[1] <= 16'h0002; body[2] <= 16'h0003; body[3] <= 16'h0005; body[4] <= 16'h0008; body[5] <= 16'h000D; body[6] <= 16'h0015; end else begin readptr <= readptr + 16'h0001; end end endmodule module BENCH (); wire [15:0] array_out1, array_out2; reg clock, reset; integer count; integer errors; wire_test_case usingwire (array_out1, clock, reset); always_test_case usingalways (array_out2, clock, reset); initial begin // $dumpfile("waves.vcd"); // $dumpvars(0, BENCH); clock <= 0; reset <= 0; count <= 0; #1000; if (errors == 0) $display("PASSED"); $finish; end always begin # 10 clock <= ~clock; end always @(posedge clock) begin count <= count + 1; case (count) 10: begin reset <= 1; end endcase end initial errors = 0; always @(negedge clock) if (array_out1 !== array_out2) begin $display("FAILED: %b !== %b", array_out1, array_out2); errors = errors + 1; end endmodule iverilog-12_0/ivtest/ivltests/memidx2.v000066400000000000000000000003611435245347300202760ustar00rootroot00000000000000// Memory test for index bug module main (); reg [7:0] mem [0:64]; reg [7:0] val_reg; wire [7:0] val_wire; // Works ok assign val_wire = mem[67]; initial begin // This should generate an error. val_reg = mem; end endmodule iverilog-12_0/ivtest/ivltests/memidxrng.v000066400000000000000000000032141435245347300207230ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif /* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: memidxrng.v,v 1.1 2001/09/29 05:03:41 sib4 Exp $ // $Log: memidxrng.v,v $ // Revision 1.1 2001/09/29 05:03:41 sib4 // add memidxrng.v: memory address range check // module memidxrng; reg mem[12:2]; reg [7:0] i; integer errs = 0; initial begin for (i=0; i<255; i=i+1) mem[i] <= ^i; #1; for (i=0; i<17; i=i+1) $display("mem[%d] = %b \%b", i, mem[i], ^i); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST if (mem[13] !== 1'bx) begin $display("FAILED: mem[13] = %b, expect x", mem[14]); errs = errs + 1; end if (mem[1] !== 1'bx) begin $display("FAILED: mem[1] = %b, expect x", mem[1]); errs = errs + 1; end `endif if (errs===0) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/meminit.v000066400000000000000000000025351435245347300204000ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program checks that the initial value of a memory is x. The * verilog standard clearly states that reg values must start as x * values, and implies that memories are the same. */ module main; reg [3:0] mem [0:1] ; initial begin if (mem[0] !== 4'bxxxx) begin $display("FAILED -- mem[0] == %b", mem[0]); $finish; end if (mem[1] !== 4'bxxxx) begin $display("FAILED -- mem[1] == %b", mem[1]); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/meminit2.v000066400000000000000000000025301435245347300204550ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program checks that the initial value of a memory is x. The * verilog standard clearly states that reg values must start as x * values, and implies that memories are the same. */ module main; integer mem [0:1] ; initial begin if (mem[0] !== 32'hxxxx) begin $display("FAILED -- mem[0] == %b", mem[0]); $finish; end if (mem[1] !== 32'hxxxx) begin $display("FAILED -- mem[1] == %b", mem[1]); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/memport_bs.v000066400000000000000000000051171435245347300211040ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif /* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: memport_bs.v,v 1.1 2001/10/13 03:35:01 sib4 Exp $ // $Log: memport_bs.v,v $ // Revision 1.1 2001/10/13 03:35:01 sib4 // PR#303 memport_bs.v // module pr303; reg [3:0] mem [2:5]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] m1 = mem[1]; `else wire [3:0] m1 = 4'bxxxx; `endif wire [3:0] m2 = mem[2]; wire [3:0] m3 = mem[3]; wire [3:0] m4 = mem[4]; wire [3:0] m5 = mem[5]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] m6 = mem[6]; `else wire [3:0] m6 = 4'bxxxx; `endif reg [2:0] a; reg [3:0] e; initial begin e = 0; for (a=0; a<7; a=a+1) mem[a] <= a; #1; if ( m1 !== 4'hx) begin e=e+1; $display("FAILED m1=%b", m1 ); end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST if (mem[1] !== 4'hx) begin e=e+1; $display("FAILED mem[1]=%b", mem[1]); end `endif if ( m2 !== 4'h2) begin e=e+1; $display("FAILED m2=%b", m2 ); end if (mem[2] !== 4'h2) begin e=e+1; $display("FAILED mem[2]=%b", mem[2]); end if ( m3 !== 4'h3) begin e=e+1; $display("FAILED m3=%b", m3 ); end if (mem[3] !== 4'h3) begin e=e+1; $display("FAILED mem[3]=%b", mem[3]); end if ( m4 !== 4'h4) begin e=e+1; $display("FAILED m4=%b", m4 ); end if (mem[4] !== 4'h4) begin e=e+1; $display("FAILED mem[4]=%b", mem[4]); end if ( m5 !== 4'h5) begin e=e+1; $display("FAILED m5=%b", m5 ); end if (mem[5] !== 4'h5) begin e=e+1; $display("FAILED mem[5]=%b", mem[5]); end if ( m6 !== 4'hx) begin e=e+1; $display("FAILED m6=%b", m6 ); end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST if (mem[6] !== 4'hx) begin e=e+1; $display("FAILED mem[6]=%b", mem[6]); end `endif if (e===0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/memref.v000066400000000000000000000007051435245347300202060ustar00rootroot00000000000000/* * Check simple scope up-reference of memories. */ module main; reg [7:0] foo [0:5]; integer idx; task showstring; begin for (idx = 0 ; idx < 6 ; idx = idx+1) begin $write("%c", foo[idx]); end $display; end endtask // showstring initial begin foo[0] = "P"; foo[1] = "A"; foo[2] = "S"; foo[3] = "S"; foo[4] = "E"; foo[5] = "D"; showstring; end endmodule // main iverilog-12_0/ivtest/ivltests/memsynth1.v000066400000000000000000000044451435245347300206650ustar00rootroot00000000000000/* * This program tests the synthesis of small memories, including * aysnchronous read w/ synchronous write. */ module main; reg [3:0] mem [1:0], D; reg rst, clk, wr, wadr, radr; /* * This implements the synchronous write port to the memory. */ (* ivl_synthesis_on *) always @(posedge clk) if (rst) begin mem[0] <= 0; mem[1] <= 0; end else if (wr) begin mem[wadr] <= D; end /* This is the asynchronous read port from the memory. */ wire [3:0] Q = mem[radr]; (* ivl_synthesis_off *) initial begin rst = 0; clk = 0; wadr = 0; radr = 0; wr = 0; #1 clk = 1; #1 clk = 0; // Make sure reset works. rst = 1; #1 clk = 1; #1 clk = 0; #1 if (mem[0] !== 0 || mem[1] !== 0) begin $display("FAILED -- Reset 1: mem[0]=%b, mem[1]=%b", mem[0], mem[1]); $finish; end radr = 0; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end radr = 1; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end rst = 0; #1 clk = 1; #1 clk = 0; // Make sure memory remembers value. if (mem[0] !== 0 || mem[1] !== 0) begin $display("FAILED -- Reset 2: mem[0]=%b, mem[1]=%b", mem[0], mem[1]); $finish; end D = 7; wr = 1; #1 clk = 1; #1 clk = 0; // Make sure write works. if (mem[0] !== 7 || mem[1] !== 0) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end D = 2; wadr = 1; #1 clk = 1; #1 clk = 0; // Make sure write works. if (mem[0] !== 7 || mem[1] !== 2) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end radr = 0; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end wr = 0; D = 5; // Make sure memory remembers written values. if (mem[0] !== 7 || mem[1] !== 2) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/memsynth2.v000066400000000000000000000046161435245347300206660ustar00rootroot00000000000000/* * This program tests the synthesis of small memories, including * aysnchronous read w/ synchronous write. */ module main; reg [1:0] mem; reg D; reg rst, clk, wr, wadr, radr; /* * This implements the synchronous write port to the memory. * Asynchronous reset? In this case, yes, even though that is * not normally the case for RAM devices. */ (* ivl_synthesis_on *) always @(posedge clk or posedge rst) if (rst) begin mem[0] <= 0; mem[1] <= 0; end else if (wr) begin mem[wadr] <= D; end else begin end /* This is the asynchronous read port from the memory. */ wire Q = mem[radr]; (* ivl_synthesis_off *) initial begin rst = 0; clk = 0; wadr = 0; radr = 0; wr = 0; #1 clk = 1; #1 clk = 0; // Make sure reset works. rst = 1; #1 if (mem[0] !== 0 || mem[1] !== 0) begin $display("FAILED -- Reset: mem[0]=%b, mem[1]=%b", mem[0], mem[1]); $finish; end radr = 0; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end radr = 1; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end rst = 0; #1 clk = 1; #1 clk = 0; // Make sure memory remembers value. if (mem[0] !== 0 || mem[1] !== 0) begin $display("FAILED -- Reset: mem[0]=%b, mem[1]=%b", mem[0], mem[1]); $finish; end D = 1; wr = 1; #1 clk = 1; #1 clk = 0; // Make sure write works. if (mem[0] !== 1 || mem[1] !== 0) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end D = 0; wadr = 1; #1 clk = 1; #1 clk = 0; // Make sure write works. if (mem[0] !== 1 || mem[1] !== 0) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end radr = 0; #1 if (Q !== mem[radr]) begin $display("FAILED -- mem[%b] = %b, Q=%b", radr, mem[radr], Q); $finish; end wr = 0; D = 1; // Make sure memory remembers written values. if (mem[0] !== 1 || mem[1] !== 0) begin $display("FAILED -- write D=%b: mem[0]=%b, mem[1]=%b", D, mem[0], mem[1]); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/memsynth3.v000066400000000000000000000025341435245347300206640ustar00rootroot00000000000000`begin_keywords "1364-2005" module main; reg [3:0] foo, bar; reg [1:0] adr; reg bit, rst, clk; reg load_enable, write_enable; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) if (rst) begin foo <= 0; end else if (load_enable) begin foo <= bar; end else if (write_enable) begin foo[adr] <= bit; end (* ivl_synthesis_off *) initial begin rst = 1; clk = 0; bar = 4'bzzzz; load_enable = 0; write_enable = 0; #1 clk = 1; #1 clk = 0; if (foo !== 4'b0000) begin $display("FAILED -- reset foo=%b", foo); $finish; end rst = 0; bar = 4'b1001; load_enable = 1; write_enable = 0; #1 clk = 1; #1 clk = 0; if (foo !== bar) begin $display("FAILED -- load foo=%b, bar=%b", foo, bar); $finish; end load_enable = 0; write_enable = 0; #1 clk = 1; #1 clk = 0; if (foo !== 4'b1001) begin $display("FAILED -- foo=%b after clk", foo); $finish; end adr = 1; bit = 1; load_enable = 0; write_enable = 1; #1 clk = 1; #1 clk = 0; if (foo !== 4'b1011) begin $display("FAILED -- foo=%b, adr=%b, bit=%b", foo, adr, bit); $finish; end $display("PASSED"); $finish; end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/memsynth4.v000066400000000000000000000012041435245347300206560ustar00rootroot00000000000000module main; reg clk; reg mem[1:0]; reg clr; (* ivl_synthesis_on *) always @(posedge clk) if (clr) begin mem[1] <= 1; mem[0] <= 0; end else begin mem[1] <= ~mem[1]; mem[0] <= ~mem[0]; end (* ivl_synthesis_off *) initial begin clk = 0; clr = 1; #1 clk = 1; #1 clk = 0; if (mem[0] !== 0 || mem[1] !== 1) begin $display("FAILED -- clr"); $finish; end clr = 0; #1 clk = 1; #1 clk = 0; if (mem[0] !== 1 || mem[1] !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/memsynth5.v000066400000000000000000000020351435245347300206620ustar00rootroot00000000000000module main; reg [7:0] mem [7:0], D; reg [2:0] radr, wadr; reg wr, rst, clk; /* * This implements the synchronous write port to the memory. */ always @(posedge clk) if (rst) begin mem[0] <= 0; mem[1] <= 0; mem[2] <= 0; mem[3] <= 8'h33; mem[5] <= 8'h55; mem[6] <= 0; mem[7] <= 0; end else if (wr) begin mem[wadr] <= D; end // This is the asynchronous read port from the memory. wire[7:0] Q = mem[radr]; initial begin wr = 0; rst = 1; clk = 0; #1 clk = 1; #1 clk = 0; radr = 3; #1 if (Q !== 8'h33) begin $display("FAILED -- mem[3] == 'b%b", Q); $finish; end radr = 5; #1 if (Q !== 8'h55) begin $display("FAILED == mem[5] == 'b%b", Q); $finish; end wadr = 4; wr = 1; rst = 0; D = 'h44; #1 clk = 1; #1 clk = 0; radr = 4; #1 if (Q !== 8'h44) begin $display("FAILED -- mem[4] == 'b%b", Q); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/memsynth6.v000066400000000000000000000014031435245347300206610ustar00rootroot00000000000000module main; reg [7:0] mem [7:0], D; reg [3:0] radr, wadr; reg wr, clk; /* * This implements the synchronous write port to the memory. */ always @(posedge clk) if (wr) mem[wadr] <= D; // This is the asynchronous read port from the memory. wire[7:0] Q = mem[radr]; (* ivl_synthesis_off *) initial begin wr = 0; clk = 0; #1 clk = 1; #1 clk = 0; for (wadr = 0 ; wadr < 8 ; wadr = wadr+1) begin wr = 1; D = { 2{wadr} }; #1 clk = 1; #1 clk = 0; end wr = 0; for (radr = 0 ; radr < 8 ; radr = radr+1) begin #1 if (Q !== {2{radr}}) begin $display("FAILED -- mem[%d] == 'b%b", radr, Q); $finish; end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/memsynth7.v000066400000000000000000000027561435245347300206760ustar00rootroot00000000000000module main; reg [7:0] a; reg [2:0] adr, w_adr; reg rst, clk, ae, wr; (* ivl_synthesis_on *) always @(posedge clk) if (rst) begin a <= 8'b00000000; adr <= 3'b000; end else if (ae) begin adr <= w_adr; end else if (wr) begin adr <= adr + 1; a[adr] <= 1; end (* ivl_synthesis_off *) initial begin clk = 0; wr = 0; ae = 0; rst = 1; #1 clk = 1; #1 clk = 0; if (a !== 8'b0000_0000 || adr !== 3'b000) begin $display("FAILED - reset - a=%b, adr=%b", a, adr); $finish; end rst = 0; #1 clk = 1; #1 clk = 0; if (a !== 8'b0000_0000 || adr !== 3'b000) begin $display("FAILED - pause - a=%b, adr=%b", a, adr); $finish; end wr = 1; #1 clk = 1; #1 clk = 0; if (a !== 8'b0000_0001 || adr !== 3'b001) begin $display("FAILED - wr 1 - a=%b, adr=%b", a, adr); $finish; end #1 clk = 1; #1 clk = 0; if (a !== 8'b0000_0011 || adr !== 3'b010) begin $display("FAILED - wr 2 - a=%b, adr=%b", a, adr); $finish; end ae = 1; w_adr = 4; #1 clk = 1; #1 clk = 0; if (a !== 8'b0000_0011 || adr !== 3'b100) begin $display("FAILED - ae - a=%b, adr=%b", a, adr); $finish; end ae = 0; #1 clk = 1; #1 clk = 0; if (a !== 8'b0001_0011 || adr !== 3'b101) begin $display("FAILED - ae - a=%b, adr=%b", a, adr); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/memsynth8.v000066400000000000000000000010431435245347300206630ustar00rootroot00000000000000module main; reg [7:0] mem; reg [2:0] addr; reg out; reg clk; (* ivl_synthesis_on *) always @(posedge clk) out <= mem[addr]; integer idx; (* ivl_synthesis_off *) initial begin mem = 8'hca; addr = 0; clk = 0; for (idx = 0 ; idx < 8 ; idx = idx+1) begin addr = idx[2:0]; #1 clk = 1; #1 clk = 0; if (out !== mem[idx]) begin $display("FAILED -- mem[%d] = %b", idx, out); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/memsynth9.v000066400000000000000000000020641435245347300206700ustar00rootroot00000000000000module main; parameter CACHE_RAM = 128; parameter ADR_WIDTH = 7; reg [31:0] buff[0:CACHE_RAM], data_o, data_i; reg [ADR_WIDTH-1:0] addr; reg clk, rst, wr; (* ivl_synthesis_on *) always @(posedge clk) if (wr) buff[addr] <= data_i; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) begin if (rst) data_o <= 32'h0; else if (wr) data_o <= data_i; else data_o <= buff[addr]; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 0; wr = 1; for (addr = 0 ; addr < 64 ; addr = addr+1) begin data_i <= addr; #1 clk = 1; #1 clk = 0; if (data_o !== data_i) begin $display("FAILED -- write addr=0x%h, data_o=%h", addr, data_o); $finish; end end wr = 0; data_i = 32'hx; for (addr = 0 ; addr < 64 ; addr = addr+1) begin #1 clk = 1; #1 clk = 0; if (data_o !== addr) begin $display("FAILED -- read addr=0x%h, data_o=%h", addr, data_o); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/mhead_task.v000066400000000000000000000020361435245347300210320ustar00rootroot00000000000000// // Copyright (c) 1999 Steve Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate fork template 2 module main; initial begin other_main.passed; end endmodule // main module other_main; task passed; $display("PASSED"); endtask // passed endmodule iverilog-12_0/ivtest/ivltests/mix_reset.v000066400000000000000000000022241435245347300207300ustar00rootroot00000000000000module main; reg [7:0] data_i; reg [2:0] addr; reg clk, rst, wr; reg [7:0] data_o, buff[0:7]; (* ivl_synthesis_on *) always @(posedge clk or posedge rst) begin if (rst) data_o <= 8'h0; else if (wr) begin buff[addr] <= data_i; data_o <= data_i; end else data_o <= buff[addr]; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 1; wr = 1; addr = 0; data_i = 8'hff; #1 clk = 1; #1 clk = 0; if (data_o !== 8'h00) begin $display("FAILED -- reset data_o=%b", data_o); $finish; end rst = 0; wr = 1; for (addr = 0; addr < 7; addr = addr+1) begin data_i = addr; #1 clk = 1; #1 clk = 0; if (data_o !== data_i) begin $display("FAILED -- write data_i=%h, data_o=%h", data_i, data_o); $finish; end end wr = 0; data_i = 8'hff; for (addr = 0 ; addr < 7; addr = addr+1) begin #1 clk = 1; #1 clk = 0; if (data_o !== {5'b00000, addr}) begin $display("FAILED -- read addr=%h, data_o=%h", addr, data_o); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/mixed_type_div_mod.v000066400000000000000000000017651435245347300226120ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_REAL_MODULUS_IN_IVTEST `endif module top; reg pass; real result; initial begin pass = 1'b1; // This should turn into a just a load of 0.5. result = 1/2.0; if (result != 0.5) begin $display("Failed: int/real, expected 0.5, got %g", result); pass = 1'b0; end // This should turn into a just a load of 0.5. result = 1.0/2; if (result != 0.5) begin $display("Failed: real/int, expected 0.5, got %g", result); pass = 1'b0; end `ifdef SUPPORT_REAL_MODULUS_IN_IVTEST // This should turn into a just a load of 1.0. result = 1%2.0; if (result != 1.0) begin $display("Failed: int%%real, expected 1.0, got %g", result); pass = 1'b0; end // This should turn into a just a load of 1.0. result = 1.0%2; if (result != 1.0) begin $display("Failed: real%%int, expected 1.0, got %g", result); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/mixed_width_case.v000066400000000000000000000036311435245347300222340ustar00rootroot00000000000000module mixed_width_case(); function [2:0] lookup1(input signed [2:0] value); begin case (value) 4'sb0100 : lookup1 = 1; 3'sb100 : lookup1 = 2; 2'sb10 : lookup1 = 3; default : lookup1 = 4; endcase $display("case = %d", lookup1); end endfunction function [2:0] lookup2(input signed [2:0] value); begin case (value) 4'b1100 : lookup2 = 1; 3'sb100 : lookup2 = 2; 2'sb10 : lookup2 = 3; default : lookup2 = 4; endcase $display("case = %d", lookup2); end endfunction function [2:0] lookup3(input real value); begin case (value) 4'b0001 : lookup3 = 1; 3'sb010 : lookup3 = 2; 2'sb11 : lookup3 = 3; default : lookup3 = 4; endcase $display("case = %d", lookup3); end endfunction function [2:0] lookup4(input signed [2:0] value); begin case (value) 4'b0110 : lookup4 = 1; 3'sb110 : lookup4 = 2; -1.0 : lookup4 = 3; default : lookup4 = 4; endcase $display("case = %d", lookup4); end endfunction reg [2:0] result; reg failed = 0; initial begin result = lookup1(3'sb100); if ( result != 2) failed = 1; result = lookup1(3'sb110); if ( result != 3) failed = 1; result = lookup1(3'sb010); if ( result != 4) failed = 1; $display(""); result = lookup2(3'sb100); if ( result != 2) failed = 1; result = lookup2(3'sb010); if ( result != 3) failed = 1; result = lookup2(3'sb110); if ( result != 4) failed = 1; $display(""); result = lookup3( 1.0); if ( result != 1) failed = 1; result = lookup3( 2.0); if ( result != 2) failed = 1; result = lookup3(-1.0); if ( result != 3) failed = 1; result = lookup3( 1.5); if ( result != 4) failed = 1; $display(""); result = lookup4(3'sb110); if ( result != 2) failed = 1; result = lookup4(3'sb111); if ( result != 3) failed = 1; result = lookup4(3'sb011); if ( result != 4) failed = 1; $display(""); if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/mod_inst_pkg.v000066400000000000000000000030031435245347300214020ustar00rootroot00000000000000package fooPkg; localparam FOO = 5; endpackage package barPkg; function int get_size ( input int x ); return x + 3; endfunction endpackage package bazPkg; typedef int baz; endpackage /* IEEE 1800-2012 A.1.2 says: module_nonansi_header ::= { attribute_instance } module_keyword [ lifetime ] module_identifier { package_import_declaration } [ parameter_port_list ] list_of_ports ; module_ansi_header ::= { attribute_instance } module_keyword [ lifetime ] module_identifier { package_import_declaration } [ parameter_port_list ] [ list_of_port_declarations ] ; This allows for the importing of packages during module definition which can be used in the parameter and port lists. */ module foo // Testing comman separated imports import fooPkg::*, barPkg::*; // Testing multiple import statements import bazPkg::*; #( parameter FOO_PARAM = FOO ) ( input [get_size(7)-1:0] inport ); baz value = 11; initial begin if ($bits(inport) != 10) begin $display("FAILED -- function import in module declaration failed (%d)", $bits(inport)); $finish; end if (value != 11) begin $display("FAILED -- Something is wrong with typedef import (%d)", value); $finish; end if (FOO_PARAM != 5) begin $display("FAILED -- Something is wrong with paramater imports (%d)", FOO_PARAM); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/modparam.v000066400000000000000000000066061435245347300205410ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate parameter passing override in module declaration. // // Build a single line of storage - Note it's // module reg32 (clk,we, din, dout); parameter WIDTH=32; input we; input clk; input [WIDTH-1:0] din; output [WIDTH-1:0] dout; reg [WIDTH-1:0] store; always @(posedge clk) if(we) store <= din; assign dout = store ; endmodule module memory(clk, we, addr, din, dout); parameter WIDTH=8; input clk; input we; input [1:0] addr; input [WIDTH-1:0] din; output [WIDTH-1:0] dout; reg [WIDTH-1:0] dout; wire [WIDTH-1:0] dout0,dout1,dout2,dout3; reg we0,we1,we2,we3; reg32 #(WIDTH) reg0 (.clk(clk),.we(we0),.din(din[WIDTH-1:0]), .dout(dout0[WIDTH-1:0])); reg32 #(WIDTH) reg1 (.clk(clk),.we(we1),.din(din[WIDTH-1:0]), .dout(dout1[WIDTH-1:0])); reg32 #(WIDTH) reg2 (.clk(clk),.we(we2),.din(din[WIDTH-1:0]), .dout(dout2[WIDTH-1:0])); reg32 #(WIDTH) reg3 (.clk(clk),.we(we3),.din(din[WIDTH-1:0]), .dout(dout3[WIDTH-1:0])); // // Build we decode // always @(addr or we) case (addr) 2'b00: begin we0 = we; we1 = 0; we2 = 0; we3 = 0; end 2'b01: begin we0 = 0; we1 = we; we2 = 0; we3 = 0; end 2'b10: begin we0 = 0; we1 = 0; we2 = we; we3 = 0; end 2'b11: begin we0 = 0; we1 = 0; we2 = 0; we3 = we; end endcase // // Connect dout to register output // always @(addr or dout0 or dout1 or dout2 or dout3) case (addr) 2'b00: dout = dout0; 2'b01: dout = dout1; 2'b10: dout = dout2; 2'b11: dout = dout3; endcase endmodule module top; parameter WIDTH=8; reg clk; reg we; reg [1:0] addr; reg [WIDTH-1:0] din; reg error; wire [WIDTH-1:0] dout; memory mem (clk, we, addr, din, dout); initial begin // $dumpfile("test.vcd"); // $dumpvars(0,top.mem.reg0); clk = 0; error =0; #3; we = 1; addr = 0; din = 32'b0_00; #10; addr = 1; din = 32'h1; #10; addr = 2; din = 32'h2; #10; addr = 3; din = 32'h3; #10; we = 0; addr = 0; #1; if(dout[7:0] !== 8'h00) begin $display("FAILED - Ram[0] not 0, is %h",dout[7:0]); error = 1; end if(error == 0) $display("PASSED"); $finish ; end always #(5) clk = ~clk; endmodule iverilog-12_0/ivtest/ivltests/module3.12A.v000066400000000000000000000033751435245347300206330ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate various module formats // Template 1 module mod1 ; endmodule // Template 2 module mod2 (); endmodule // Template 3 module mod3 (a,b); input a; input b; endmodule //Template 4 - module mod4 (ident1,out1); input [31:0] ident1; output [31:0] out1; wire [31:0] out1 = ident1; endmodule module main (); wire [31:0] out1,out2; reg [31:0] val1,val2; reg error; mod4 inst1 (val1,out1); // Ordered port list mod4 inst2 (.ident1(val2),.out1(out2)); // List by portname initial begin error = 0; val1 = 32'h11223344; #1 if(out1 != 32'h11223344) begin $display("FAILED - module 3.12A - Ordered module port list failed"); error = 1; end val2 = 32'h44332211; #1 if(out2 != 32'h44332211) begin $display("FAILED -module 3.12A -named module port list (.x(a)) failed"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/module3.12B.v000066400000000000000000000021751435245347300206310ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate various module formats module foo(a); output a; wire a = 1'b1 ; endmodule module main; wire b; foo foo1 (.a()); foo foo2 (.a(b)); initial if(!b) $display("FAILED - 3.12B - Module with output only failed"); else $display("PASSED"); endmodule // main iverilog-12_0/ivtest/ivltests/module3.12C.v000066400000000000000000000021661435245347300206320ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate module a(),b(); module foo(a); output a; wire a = 1'b1 ; endmodule module main; wire b; foo foo1 (.a()), foo2 (.a(b)); initial if(!b) $display("FAILED - 3.12C - Module with output only failed"); else $display("PASSED"); endmodule // main iverilog-12_0/ivtest/ivltests/module_inout_port_list_def.v000066400000000000000000000004701435245347300243520ustar00rootroot00000000000000// Check that it is an error to specify a default value for inout port // declarations. module M ( inout [31:0] x, y = 1 // inout ports do not support default values ); initial begin $display("FAILED"); end endmodule module test; wire [31:0] x, y; M i_m ( .x(x), .y(y) ); endmodule iverilog-12_0/ivtest/ivltests/module_inout_port_type.v000066400000000000000000000003611435245347300235410ustar00rootroot00000000000000// Check Verilog types on a module inout port. In Verilog this is an error, but // in SystemVerilog it is supported module test ( inout reg a, inout time b, inout integer c ); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_input_port_list_def.v000066400000000000000000000010071435245347300243500ustar00rootroot00000000000000// Check that it is possible to specify a default port value for each port in a // input port declaration list. module M ( input [31:0] x = 1, y = 2 ); `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d): %s, expected %0h got %0h", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end reg failed = 1'b0; initial begin `check(x, 1) `check(y, 2) if (!failed) begin $display("PASSED"); end end endmodule module test; M i_m (); endmodule iverilog-12_0/ivtest/ivltests/module_input_port_type.v000066400000000000000000000003611435245347300235420ustar00rootroot00000000000000// Check Verilog types on a module input port. In Verilog this is an error, but // in SystemVerilog it is supported module test ( input reg a, input time b, input integer c ); initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_atom2_fail.v000066400000000000000000000005401435245347300240370ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as an atom2 typed variable. Even // if the size of the packed dimensions matches that of the size of the atom2 // type. module test(x); output [15:0] x; shortint x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_enum1.v000066400000000000000000000006071435245347300230530ustar00rootroot00000000000000// Check that it is possible to declare the data type for a enum type module // port separately from the direction for non-ANSI style port declarations. // declarations. typedef enum integer { A, B } T; module test(x); output x; T x; initial begin if ($bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_enum2.v000066400000000000000000000005551435245347300230560ustar00rootroot00000000000000// Check that it is possible to declare the data type for a enum type module // port before the direction for non-ANSI style port declarations. typedef enum integer { A, B } T; module test(x); T x; output x; initial begin if ($bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_enum_fail.v000066400000000000000000000005671435245347300237720ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a enum typed variable. Even if // the size of the packed dimensions matches that of the size of the enum type. typedef enum integer { A, B } T; module test(x); output [31:0] x; T x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail1.v000066400000000000000000000002641435245347300230210ustar00rootroot00000000000000// Check that declaring multiple non-ANSI module ports with the same name is an // error. Even if they both have an implicit type. module test(x); input x; input x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail10.v000066400000000000000000000003131435245347300230740ustar00rootroot00000000000000// Check that declaring a non-ANSI module port with an explicit type for a // signal that was previously declared as a real variable is an error. module test(x); real x; output integer x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail11.v000066400000000000000000000003421435245347300230770ustar00rootroot00000000000000// Check that declaring multiple non-ANSI module ports with an implicit type and // the same name is an error. Even if the signal was previously declared as a // net. module test(x); wire x; input x; input x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail12.v000066400000000000000000000003711435245347300231020ustar00rootroot00000000000000// Check that declaring multiple non-ANSI module ports with an implicit type and // the same name is an error. Even if the signal was previously declared as a // integer typed net. module test(x); wire integer x; input x; input x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail13.v000066400000000000000000000003101435245347300230740ustar00rootroot00000000000000// Check that declaring multiple non-ANSI module output ports with an explicit // type is an error. Even if the types are the same. module test(x); output integer x; output integer x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail2.v000066400000000000000000000002731435245347300230220ustar00rootroot00000000000000// Check that declaring a net multiple times for a signal that was previously // declared as a non-ANSI module port is an error. module test(x); input x; wire x; wire x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail3.v000066400000000000000000000002771435245347300230270ustar00rootroot00000000000000// Check that declaring a variable multiple times for a signal that was // previously declared as a non-ANSI module port is an error. module test(x); output x; reg x; reg x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail4.v000066400000000000000000000002771435245347300230300ustar00rootroot00000000000000// Check that declaring both a net and a variable for a signal that was // previously declared as a non-ANSI module port is an error. module test(x); input x; wire x; reg x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail5.v000066400000000000000000000003701435245347300230230ustar00rootroot00000000000000// Check that declaring an integer typed non-ANSI module port for signal that // was previously declared as a net is an error. Even if the types for both // declarations are the same. module test(x); wire integer x; input integer x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail6.v000066400000000000000000000003721435245347300230260ustar00rootroot00000000000000// Check that declaring an integer typed net for a signal that was previously // declared as a non-ANSI module port is an error. Even if the types for both // declarations are the same. module test(x); input integer x; wire integer x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail7.v000066400000000000000000000003611435245347300230250ustar00rootroot00000000000000// Check that declaring a real typed variable for a signal that was previously // declared as a non-ANSI module port is an error. Even if the types for both // declarations are the same. module test(x); output real x; real x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail8.v000066400000000000000000000003611435245347300230260ustar00rootroot00000000000000// Check that declaring a real typed non-ANSI module port for a signal that was // previously declared as a variable is an error. Even if the types for both // declarations are the same. module test(x); real x; output real x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_fail9.v000066400000000000000000000003121435245347300230230ustar00rootroot00000000000000// Check that declaring an integer typed variable for a signal that was previously // declared as a real typed non-ANSI module port is an error. module test(x); output real x; integer x; endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_int1.v000066400000000000000000000007601435245347300227010ustar00rootroot00000000000000// Check that it is possible to declare the data type for an atom2 type module // port separately from the direction for non-ANSI style port declarations. // declarations. module test(x, y, z, w); output x; output y; output z; output w; byte x; shortint y; int z; longint w; initial begin if ($bits(x) == 8 && $bits(y) == 16 && $bits(z) == 32 && $bits(w) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_int2.v000066400000000000000000000007261435245347300227040ustar00rootroot00000000000000// Check that it is possible to declare the data type for an atom2 type module // port before the direction for non-ANSI style port declarations. module test(x, y, z, w); byte x; shortint y; int z; longint w; output x; output y; output z; output w; initial begin if ($bits(x) == 8 && $bits(y) == 16 && $bits(z) == 32 && $bits(w) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_integer1.v000066400000000000000000000005631435245347300235450ustar00rootroot00000000000000// Check that it is possible to declare the data type for an integer type module // port separately from the direction for non-ANSI style port declarations. // declarations. module test(x); output x; integer x; initial begin if ($bits(x) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_integer2.v000066400000000000000000000005311435245347300235410ustar00rootroot00000000000000// Check that it is possible to declare the data type for an integer type module // port before the direction for non-ANSI style port declarations. module test(x); integer x; output x; initial begin if ($bits(x) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_integer_fail.v000066400000000000000000000005431435245347300244550ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as an integer typed variable. // Even if the size of the packed dimensions matches that of the size of the // integer type. module test(x); output [31:0] x; integer x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_parray1.v000066400000000000000000000006261435245347300234060ustar00rootroot00000000000000// Check that it is possible to declare the data type for a packed array module // port separately from the direction for non-ANSI style port declarations. // declarations. typedef logic [3:0] T1; typedef T1 [7:0] T2; module test(x); output x; T2 x; initial begin if ($bits(x) == $bits(T2)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_parray2.v000066400000000000000000000005741435245347300234110ustar00rootroot00000000000000// Check that it is possible to declare the data type for a packed array module // port before the direction for non-ANSI style port declarations. typedef logic [3:0] T1; typedef T1 [7:0] T2; module test(x); T2 x; output x; initial begin if ($bits(x) == $bits(T2)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_parray_fail.v000066400000000000000000000006161435245347300243170ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a packed array typed variable. // Even if the size of the packed dimensions matches that of the size of the // packed array. typedef reg [7:0] T1; typedef T1 [3:0] T2; module test(x); output [31:0] x; T2 x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_real1.v000066400000000000000000000005321435245347300230270ustar00rootroot00000000000000// Check that it is possible to declare the data type for a real type module // port separately from the direction for non-ANSI style port declarations. // declarations. module test(x); output x; real x; initial begin if (x == 0.0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_real2.v000066400000000000000000000005001435245347300230230ustar00rootroot00000000000000// Check that it is possible to declare the data type for a real type module // port before the direction for non-ANSI style port declarations. module test(x); real x; output x; initial begin if (x == 0.0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_real_fail.v000066400000000000000000000003751435245347300237460ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a real typed variable. module test(x); output [3:0] x; real x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_struct1.v000066400000000000000000000006421435245347300234320ustar00rootroot00000000000000// Check that it is possible to declare the data type for a struct type module // port separately from the direction for non-ANSI style port declarations. // declarations. typedef struct packed { reg [31:0] x; reg [7:0] y; } T; module test(x); output x; T x; initial begin if ($bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_struct2.v000066400000000000000000000006101435245347300234260ustar00rootroot00000000000000// Check that it is possible to declare the data type for a struct type module // port before the direction for non-ANSI style port declarations. typedef struct packed { reg [31:0] x; reg [7:0] y; } T; module test(x); T x; output x; initial begin if ($bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_struct_fail.v000066400000000000000000000006311435245347300243420ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a packed struct typed // variable. Even if the size of the packed dimensions matches that of the size // of the struct. typedef struct packed { reg [31:0] x; reg [7:0] y; } T; module test(x); output [47:0] x; T x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_time1.v000066400000000000000000000005401435245347300230410ustar00rootroot00000000000000// Check that it is possible to declare the data type for a time type module // port separately from the direction for non-ANSI style port declarations. // declarations. module test(x); output x; time x; initial begin if ($bits(x) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_time2.v000066400000000000000000000005061435245347300230440ustar00rootroot00000000000000// Check that it is possible to declare the data type for a time type module // port before the direction for non-ANSI style port declarations. module test(x); time x; output x; initial begin if ($bits(x) == 64) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_time_fail.v000066400000000000000000000005261435245347300237570ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a time typed variable. Even if // the size of the packed dimensions matches that of the size of the time type. module test(x); output [63:0] x; time x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_vec1.v000066400000000000000000000005541435245347300226650ustar00rootroot00000000000000// Check that it is possible to declare the data type for a vector type module // port separately from the direction for non-ANSI style port declarations. // declarations. module test(x); output [7:0] x; reg [7:0] x; initial begin if ($bits(x) == 8) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_vec2.v000066400000000000000000000005221435245347300226610ustar00rootroot00000000000000// Check that it is possible to declare the data type for a vector type module // port before the direction for non-ANSI style port declarations. module test(x); reg [7:0] x; output [7:0] x; initial begin if ($bits(x) == 8) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_vec_fail1.v000066400000000000000000000004721435245347300236570ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a vector typed variable and // the size of the packed dimensions do not match. module test(x); output [3:0] x; reg [7:0] x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_vec_fail2.v000066400000000000000000000004501435245347300236540ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port without implicit // packed dimensions if it is later redeclared as a vector typed variable and // the vector type is not a scalar. module test(x); output x; reg [7:0] x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_nonansi_vec_fail3.v000066400000000000000000000004411435245347300236550ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI module port with implicit // packed dimensions if it is later redeclared as a vector typed variable and // the vector type is a scalar. module test(x); output [7:0] x; reg x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_output_port_list_def.v000066400000000000000000000010111435245347300245440ustar00rootroot00000000000000// Check that it is possible to specify a default port value for each port in a // output port declaration list. module M ( output [31:0] x = 1, y = 2 ); `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d): %s, expected %0h got %0h", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end reg failed = 1'b0; initial begin `check(x, 1) `check(y, 2) if (!failed) begin $display("PASSED"); end end endmodule module test; M i_m (); endmodule iverilog-12_0/ivtest/ivltests/module_output_port_sv_var1.v000066400000000000000000000011571435245347300243470ustar00rootroot00000000000000// Check that ANSI output ports that have a SystemVerilog data type are // elaborated as variables and be assigned a value. typedef struct packed { int x; } T1; typedef enum { A } T2; typedef T1 [1:0] T3; module test ( output reg a, output reg [1:0] b, output integer c, output time d, output bit e, output logic f, output shortint g, output int h, output longint i, output real r, output T1 x, output T2 y, output T3 z ); initial begin a = '0; b = '0; c = '0; d = '0; e = '0; f = '0; g = '0; h = '0; r = 0.0; x = '0; y = A; z = '0; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_output_port_sv_var2.v000066400000000000000000000011271435245347300243450ustar00rootroot00000000000000// Check that non-ANSI output ports that have a SystemVerilog data type are // elaborated as variables and be assigned a value. typedef struct packed { int x; } T1; typedef enum { A } T2; typedef T1 [1:0] T3; module test1; output reg a; output reg [1:0] b; output integer c; output time d; output bit e; output logic f; output shortint g; output int h; output longint i; output real r; output T1 x; output T2 y; output T3 z; initial begin a = '0; b = '0; c = '0; d = '0; e = '0; f = '0; g = '0; h = '0; r = 0.0; x = '0; y = A; z = '0; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_output_port_var1.v000066400000000000000000000005201435245347300236300ustar00rootroot00000000000000// Check that ANSI output ports that have a Verilog data type are elaborated as // variables and be assigned a value. module test ( output reg a, output reg [1:0] b, output reg signed [1:0] c, output integer d, output time e ); initial begin a = 0; b = 0; c = 0; d = 0; e = 0; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_output_port_var2.v000066400000000000000000000005071435245347300236360ustar00rootroot00000000000000// Check that non-ANSI output ports that have a Verilog data type are elaborated // as variables and be assigned a value. module test; output reg a; output reg [1:0] b; output reg signed [1:0] c; output integer d; output time e; initial begin a = 0; b = 0; c = 0; d = 0; e = 0; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/module_port_range_mismatch.v000066400000000000000000000004501435245347300243220ustar00rootroot00000000000000// Check that range mismatches between port direction and data type are detected // for module ports. An error should be reported and no crash should occur. module test; input [1:0] x; wire [3:0] x; wire [3:0] y; assign y = x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/module_port_shortreal.v000066400000000000000000000005611435245347300233470ustar00rootroot00000000000000// Check that shortreal module ports are supported module M ( input shortreal in, output shortreal out ); assign out = in * 10.1; endmodule module test; shortreal r; M m ( .in (1.23), .out (r) ); initial begin #1 if (r == 12.423) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_port_typedef_array1.v000066400000000000000000000010771435245347300242660ustar00rootroot00000000000000// Check that an array type identifier used for a module port is elaborated in // the correct scope. localparam A = 2; localparam B = 4; typedef logic [A-1:0] T[B]; module test ( input T x ); localparam A = 5; localparam B = 10; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check($size(x, 1), 4); `check($size(x, 2), 2); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/module_port_typedef_vector.v000066400000000000000000000007741435245347300243740ustar00rootroot00000000000000// Check that a packed array type identifier used for a module port is // elaborated in the correct scope. localparam A = 2; typedef logic [A-1:0] T; module test ( input T x ); localparam A = 5; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check($bits(x), 2); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/modulus.v000066400000000000000000000041351435245347300204240ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate Modulus operator module top; reg [7:0] a,b; wire [7:0] wa,wb; reg [7:0] result; wire [7:0] wresult; reg [15:0] work; reg error; assign wa = a; assign wresult = work % a; always @ (work or wa) result = work % a; initial begin error = 0; /* Try mod div by 0 */ #1; a = 0; work = 16'd1235; #1; if(wresult !== 8'hxx) begin $display("FAILED - wire 1235 mod 0: wresult = %h",wresult); error =1; end if(result !== 8'hxx) begin $display("FAILED - reg 1235 mod 0: result = %h",result); error =1; end #1; a = 8'd10; #1; if(wresult !== 8'h05) begin $display("FAILED - wire 1235 mod 10: wresult = %h",wresult); error =1; end if(result !== 8'h05) begin $display("FAILED - reg 1235 mod 10: result = %h",result); error =1; end #1; a = 8'b0000_x001; #1; if(wresult !== 8'bxxxx_xxxx) begin $display("FAILED - wire 1235 mod 10: wresult = %h",wresult); error =1; end if(result !== 8'bxxxx_xxxx) begin $display("FAILED - reg 1235 mod 10: result = %h",result); error =1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/modulus2.v000066400000000000000000000025111435245347300205020ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests the behavioral modulus operator, to make sure it * works at least minimally. */ module main; reg [15:0] a, b, c; initial begin a = 1; b = 1; c = a % b; if (c !== 16'd0) begin $display("FAILED -- 1 %% 1 == 'b%b", c); $finish; end a = 9; b = 8; c = a % b; if (c !== 16'd1) begin $display("FAILED -- 9 %% 8 == 'b%b", c); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/monitor.v000066400000000000000000000020671435245347300204250ustar00rootroot00000000000000// Copyright (c) 2001 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // This trivial program shows that the $monitor system task really does // seem to work. module main; reg clk = 0; always #5 clk = ~clk; initial begin $monitor($time,, "clk=%b", clk); #61 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/monitor2.v000066400000000000000000000020151435245347300205000ustar00rootroot00000000000000/* I seem to have found a problem with the $monitor task/events. (this is probably related to bug 399) The problem only seems to arise in vvp mode and not in vvm. Problem: $monitor seems to lose both the first and last time steps. A complete copy of the run follows with source appended at the end. (The correct output from vvm is shown in the last run) This file compiles and produces the problem. jungle_geo@hotmail.com */ /* bubba> uname -a Linux bubba 2.2.15-4mdk #1 Wed May 10 15:31:30 CEST 2000 i686 unknown bubba> iverilog -V Icarus Verilog version 0.6 Copyright 1998-2002 Stephen Williams $Name: $ bubba> iverilog -Wall -tvvp stim.v bubba> a.out Time = 1 a = 1 bubba> iverilog -Wall -tvvm stim.v bubba> a.out Time = 0 a = 0 Time = 1 a = 1 Time = 2 a = 0 */ // -------------------------------------------------------------------------stim module stim; reg a; initial begin a = 0; #1 a = 1; #1 a = 0; end initial begin $monitor("Time = %0d a = %b", $time, a); end endmodule iverilog-12_0/ivtest/ivltests/monitor3.v000066400000000000000000000020411435245347300205000ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; real x, y; initial begin $monitor("%t: x=%f, y=%f", $time, x, y); #1 x = 1.0; #1 y = 2.0; #1 x = 1.5; #1 y = 5.1; #1 $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/mult1.v000066400000000000000000000056411435245347300200010ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - multiply operator module top () ; reg [3:0] a,b; wire [3:0] wa,wb; reg [7:0] result; wire [8:0] wresult; assign wa = a; assign wb = b; assign wresult = wa * wb; always @(a or b) result = a * b; initial begin #1; a = 0; b = 0; # 1; if( result !== 8'b0) begin $display("FAILED - Mult 0*0 reg assign failed - is %b",result); $finish; end if( wresult !== 9'b0) begin $display("FAILED - Mult 0*0 wire assign failed - is %b",result); $finish; end #1; a = 1; #1; if( result !== 8'b0) begin $display("FAILED - Mult 0*1 reg assign failed - is %b",result); $finish; end if( wresult !== 9'b0) begin $display("FAILED - Mult 0*1 wire assign failed - is %b",result); $finish; end #1; b = 1; #1; if( result !== 8'b1) begin $display("FAILED - Mult 1*1 reg assign failed - is %b",result); $finish; end if( wresult !== 9'b1) begin $display("FAILED - Mult 1*1 wire assign failed - is %b",result); $finish; end #1; a = 2; #1; if( result !== 8'h2) begin $display("FAILED - Mult 2*1 reg assign failed - is %b",result); $finish; end if( wresult !== 9'h2) begin $display("FAILED - Mult 2*1 wire assign failed - is %b",result); $finish; end #1; a = 2; b = 3; #1; if( result !== 8'h6) begin $display("FAILED - Mult 2*3 reg assign failed - is %b",result); $finish; end if( wresult !== 9'h6) begin $display("FAILED - Mult 2*3 wire assign failed - is %b",result); $finish; end #1; a = 1'bx; b = 3; #1; if( result !== 8'bxxxx_xxxx) begin $display("FAILED - Mult 2*x reg assign failed - is %b",result); $finish; end if( wresult !== 9'bx_xxxx_xxxx) begin $display("FAILED - Mult 2*x wire assign failed - is %b",wresult); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/mult16.v000066400000000000000000000077641435245347300200770ustar00rootroot00000000000000// // Copyright (c) 1999 Thomas Coonan (tcoonan@mindspring.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // **** Here's a simple, sequential multiplier. Very simple, unsigned.. // Not very well tested, play with testbench, use at your own risk, blah blah blah.. // // // Unsigned 16-bit multiply (multiply two 16-bit inputs to get a 32-bit output) // // Present data and assert start synchronous with clk. // Assert start for ONLY one cycle. // Wait N cycles for answer (at most). Answer will remain stable until next start. // You may use DONE signal as handshake. // // Written by tom coonan // module mult16 (clk, resetb, start, done, ain, bin, yout); parameter N = 16; input clk; input resetb; input start; // Register the ain and bin inputs (they can change afterwards) //input [N-1:0] ain; //input [N-1:0] bin; //output [2*N-1:0] yout; input [15:0] ain; input [15:0] bin; output [31:0] yout; output done; //reg [2*N-1:0] a; //reg [N-1:0] b; //reg [2*N-1:0] yout; reg [31:0] a; reg [15:0] b; reg [31:0] yout; reg done; always @(posedge clk or negedge resetb) begin if (~resetb) begin a <= 0; b <= 0; yout <= 0; done <= 1'b1; end else begin // Load will register the input and clear the counter. if (start) begin a <= ain; b <= bin; yout <= 0; done <= 0; end else begin // Go until b is zero if (~done) begin if (b != 0) begin // If '1' then add a to sum if (b[0]) begin yout <= yout + a; end b <= b >> 1; a <= a << 1; $display ("a = %h, b = %h, yout = %h", a,b,yout); end else begin done <= 1'b1; end end end end end endmodule module mul16; reg clk, resetb, start; reg [15:0] a; reg [15:0] b; wire [31:0] y; wire done; mult16 mult16inst (clk, resetb, start, done, a, b, y); initial begin clk = 0; forever begin #10 clk = ~clk; end end initial begin resetb = 0; #30 resetb = 1; end integer num_errors; parameter MAX_TRIALS = 10; initial begin // $dumpfile ("multdiv.vcd"); // $dumpvars (0,a); // $dumpvars (0,b); // $dumpvars (0,y); // $dumpvars (0,resetb); // $dumpvars (0,done); num_errors = 0; #100; // Do a bunch of random multiplies repeat (MAX_TRIALS) begin test_multiply ($random, $random); end // Special cases test_multiply ($random, 1); test_multiply (1, $random); test_multiply ($random, 0); test_multiply (0, $random); $display ("Done. %0d Errors", num_errors); #800; $finish; end task test_multiply; input [15:0] aarg; input [15:0] barg; integer expected_answer; begin if (~done) begin $display ("Multiplier is Busy!!"); end else begin @(negedge clk); start = 1; a = aarg; b = barg; @(negedge clk) start = 0; @(posedge done); expected_answer = a*b; $display ("%0d * %0d = %0h, Reality = %0h", a, b, y, expected_answer); if (y !== expected_answer) begin $display (" FAILURE!"); num_errors = num_errors + 1; end end end endtask endmodule iverilog-12_0/ivtest/ivltests/mult2.v000066400000000000000000000044761435245347300200070ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test some multiply values for an 18*18-->36 multiply. */ module main; wire [35:0] p; reg [17:0] a, b; reg clk, ce, reset; parameter MAX_TRIALS = 1000; integer idx; MULT18X18S dut (p, a, b, clk, ce, reset); initial begin clk <= 0; ce <= 1; reset <= 1; a <= 0; b <= 0; #5 clk <= 1; #5 clk <= 0; if (p !== 36'h0) begin $display("FAILED -- reset p=%h", p); $finish; end reset <= 0; /* A magical value I know failed at one time. */ a <= 18'h3ff82; b <= 18'h04000; #5 clk <= 1; #5 clk <= 0; if (p !== 36'hfffe08000) begin $display("FAILED -- %h * %h --> %h", a, b, p); $finish; end for (idx = 0 ; idx < MAX_TRIALS ; idx = idx + 1) begin a <= $random; b <= $random; #5 clk <= 1; #5 clk <= 0; if ($signed(p) !== ($signed(a) * $signed(b))) begin $display("FAILED == %h * %h --> %h", a, b, p); $finish; end end // for (idx = 0 ; idx < `MAX_TRIALS ; idx = idx + 1) $display("PASSED"); end // initial begin endmodule // main module MULT18X18S (output reg [35:0] P, input [17:0] A, input [17:0] B, input C, CE, R); wire [35:0] a_in = { {18{A[17]}}, A[17:0] }; wire [35:0] b_in = { {18{B[17]}}, B[17:0] }; wire [35:0] p_in; reg [35:0] p_out; assign p_in = a_in * b_in; always @(posedge C) if (R) P <= 36'b0; else if (CE) P <= p_in; endmodule iverilog-12_0/ivtest/ivltests/multi_bit_strength.v000066400000000000000000000006371435245347300226450ustar00rootroot00000000000000`timescale 1ns/1ps module top; parameter length = 17; reg [length*8-1:0] result; wire [3:0] net; assign (pull1, strong0) net = 4'b0110; initial begin #1; $swrite(result, "%v", net); $display("All three lines should match:"); $display("-----------------------------"); $display("St0_Pu1_Pu1_St0 (reference)"); $display("%v (display)\n%0s (swrite)", net, result); end endmodule iverilog-12_0/ivtest/ivltests/multi_driver_delay.v000066400000000000000000000016241435245347300226170ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1; reg [3:0] ia = 4'd1, ib = 4'd2; wire [2:0] icon, irep; /* Integer concatenation. */ assign #1 icon = {ib[1:0], ia[0]}; // 5 /* Integer replication. */ assign #1 irep = {3{ia[0]}}; // 7 initial begin #0.9; if (icon !== 3'bx) begin pass = 1'b0; $display("Failed: concatenation is not delayed, expected 3'bx got %b.", icon); end if (irep !== 3'bx) begin pass = 1'b0; $display("Failed: replication is not delayed, expected 3'bx got %b.", irep); end #0.1; #0; if (icon !== 3'd5) begin pass = 1'b0; $display("Failed: concatenation has incorrect value, expected 3'd5 got %b.", icon); end if (irep !== 3'd7) begin pass = 1'b0; $display("Failed: replication has incorrect value, expected 3'd7 got %b.", irep); end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/multiply_large.v000066400000000000000000000062611435245347300217670ustar00rootroot00000000000000// // multiply_large.v // // Copyright (c) 2001 ajb // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // `define W (65) // any value past 32 will suffice module multiplier(a,b,sum); parameter N=1; input[N-1:0] a, b; output[N-1:0] sum; reg [(N-1)*2:0] tmp; integer i; always @(a or b) begin tmp = 0; for(i=0;i y <= i0; when others => y <= i1; end case; end process; end mux2to1_rtl; iverilog-12_0/ivtest/ivltests/muxtest.v000066400000000000000000000037161435245347300204510ustar00rootroot00000000000000module test ; wire a; reg sel,in0, in1; reg error; assign a = sel ? in1 : in0 ; initial begin error = 0; #1; sel = 0; in0 = 0; in1 = 0; #1; if(a !== 0) begin $display("FAILED - (1) Mux error sel=0, in0=in0=0 yet out != 0"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; in0 = 1; #1; if(a !== 1) begin $display("FAILED - (2) Mux error sel=0, in0=1,in1=0 yet out != 1"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; sel = 1; #1; if(a !== 0) begin $display("FAILED - (3) Mux error sel=1, in0=1,in1=0 yet out != 0"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; in1 = 1; #1; if(a !== 1) begin $display("FAILED - (5) Mux error sel=1, in0=1,in1=1 yet out != 1"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; in0 = 0; #1; if(a !== 1) begin $display("FAILED - (6) Mux error sel=1, in0=0,in1=1 yet out != 1"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; in1 = 0; sel = 1'bx; #1; if(a !== 0) begin $display("FAILED - (8) Mux error sel=X, in0=0,in1=0 yet out != 0"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end #1; in0 = 1; in1 = 1; sel = 1'bx; #1; if(a !== 1) begin $display("FAILED - (9) Mux error sel=X, in0=1,in1=1 yet out != 1"); $display("sel=%b,in0=%b,in1=%b,out=%b", sel,in0,in1,a); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/named_begin.v000066400000000000000000000001401435245347300211540ustar00rootroot00000000000000module top; initial begin : named_begin $display("PASSED"); end : named_begin endmodule iverilog-12_0/ivtest/ivltests/named_begin_fail.v000066400000000000000000000001371435245347300221550ustar00rootroot00000000000000module top; initial begin : named_begin $display("FAILED"); end : wrong_name endmodule iverilog-12_0/ivtest/ivltests/named_event_no_edges.v000066400000000000000000000006221435245347300230610ustar00rootroot00000000000000module top; event my_event; // The following two line should be an error // You can not take the edge of a named event. always @(posedge my_event) $display("Posedge event."); always @(negedge my_event) $display("Negedge event."); // This should work correctly. always @(my_event) $display("Any event edge."); initial begin #1 ->my_event; #1 $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/named_fork.v000066400000000000000000000001361435245347300210360ustar00rootroot00000000000000module top; initial fork : named_fork $display("PASSED"); join : named_fork endmodule iverilog-12_0/ivtest/ivltests/named_fork_fail.v000066400000000000000000000001371435245347300220320ustar00rootroot00000000000000module top; initial fork : named_begin $display("FAILED"); join : wrong_name endmodule iverilog-12_0/ivtest/ivltests/nb_array_pv.v000066400000000000000000000036501435245347300212370ustar00rootroot00000000000000module top; reg pass = 1'b1; integer delay; reg [3:0] in = 4'h0; reg [7:0] result [1:0]; initial begin result[0] <= #10 8'h00; if ($simtime != 0 || result[0] !== 8'bx) begin $display("Failed #10 blocked at %0t, expected 8'hxx, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 10 || result[0] !== 8'h00) begin $display("Failed #10 at %0t, expected 8'h00, got %h", $simtime, result[0]); pass = 1'b0; end result[0][8:5] <= #10 4'hb; @(result[0]); if ($simtime != 20 || result[0] !== 8'h60) begin $display("Failed MSB #10 at %0t, expected 8'h60, got %h", $simtime, result[0]); pass = 1'b0; end result[0][1:-2] <= #10 4'hb; @(result[0]); if ($simtime != 30 || result[0] !== 8'h62) begin $display("Failed LSB #10 at %0t, expected 8'h62, got %h", $simtime, result[0]); pass = 1'b0; end delay = 20; result[1] <= #delay 8'h00; if ($simtime != 30 || result[1] !== 8'bx) begin $display("Failed #delay blocked at %0t, expected 8'hxx, got %h", $simtime, result[1]); pass = 1'b0; end @(result[1]); if ($simtime != 50 || result[1] !== 8'h00) begin $display("Failed #delay at %0t, expected 8'h00, got %h", $simtime, result[1]); pass = 1'b0; end result[1][8:5] <= #delay 4'hb; @(result[1]); if ($simtime != 70 || result[1] !== 8'h60) begin $display("Failed MSB #delay at %0t, expected 8'h60, got %h", $simtime, result[1]); pass = 1'b0; end result[1][1:-2] <= #delay 4'hb; @(result[1]); if ($simtime != 90 || result[1] !== 8'h62) begin $display("Failed LSB #delay at %0t, expected 8'h62, got %h", $simtime, result[1]); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_assign.v000066400000000000000000000014541435245347300207000ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg pass = 1'b1; reg [1:0] var = 2'b0; real rvar = 0.0; integer delay = 3; initial begin // These should both happen at time 2. var <= #2 2'b01; rvar <= #2 1.0; #3 if (var !== 2'b01) begin $display("FAILED: constant delay (bits)"); pass = 1'b0; end if (rvar != 1.0) begin $display("FAILED: constant delay (real)"); pass = 1'b0; end // These should both happen at time 6. var <= #(delay) 2'b10; rvar <= #(delay) 2.0; #4 if (var !== 2'b10) begin $display("FAILED: calculated delay (bits)"); pass = 1'b0; end if (rvar != 2.0) begin $display("FAILED: calculated delay (real)"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/nb_delay.v000066400000000000000000000044151435245347300205120ustar00rootroot00000000000000/* * For a non-blocking delay the last NB assign in the same thread * at the same time must set the final result, but you are allowed * to have multiple assignments in the queue. */ module top; reg passed = 1'b1; reg out; real rout; integer delay; initial begin out <= 1'b1; out <= 1'b0; rout <= 0.0; rout <= 1.0; #1; if (out !== 1'b0) begin $display("FAILED: zero delay, expected 1'b0, got %b", out); passed = 1'b0; end if (rout != 1.0) begin $display("FAILED: zero delay (real), expected 1.0, got %f", rout); passed = 1'b0; end out <= #1 1'b0; out <= #1 1'b1; rout <= #1 0.0; rout <= #1 2.0; #2; if (out !== 1'b1) begin $display("FAILED: constant delay, expected 1'b1, got %b", out); passed = 1'b0; end if (rout != 2.0) begin $display("FAILED: constant delay (real), expected 2.0, got %f", rout); passed = 1'b0; end delay = 2; out <= #(delay) 1'b1; out <= #(delay) 1'b0; rout <= #(delay) 0.0; rout <= #(delay) 3.0; #(delay+1); if (out !== 1'b0) begin $display("FAILED: calculated delay, expected 1'b0, got %b", out); passed = 1'b0; end if (rout != 3.0) begin $display("FAILED: calculated delay (real), expected 3.0, got %f", rout); passed = 1'b0; end out <= #1 1'b1; out <= #3 1'b0; out <= #5 1'b1; rout <= #1 1.0; rout <= #3 3.0; rout <= #5 5.0; #2; if (out !== 1'b1) begin $display("FAILED: first delay, expected 1'b1, got %b", out); passed = 1'b0; end if (rout != 1.0) begin $display("FAILED: first delay (real), expected 1.0, got %f", rout); passed = 1'b0; end #2; if (out !== 1'b0) begin $display("FAILED: second delay, expected 1'b0, got %b", out); passed = 1'b0; end if (rout != 3.0) begin $display("FAILED: second delay (real), expected 3.0, got %f", rout); passed = 1'b0; end #2; if (out !== 1'b1) begin $display("FAILED: third delay, expected 1'b1, got %b", out); passed = 1'b0; end if (rout != 5.0) begin $display("FAILED: third delay (real), expected 5.0, got %f", rout); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_array.v000066400000000000000000000046351435245347300212050ustar00rootroot00000000000000module top; reg pass = 1'b1; integer count; reg [2:0] icount; reg clk = 0; reg [3:0] in = 4'h0; reg [3:0] result [1:0]; always #10 clk = ~clk; always #20 in = in + 4'h1; initial begin count = 3; result[0] <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result[0] !== 4'bx) begin $display("Failed repeat(3) blocked at %0t, expected 4'hx, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 50 || result[0] !== 4'h0) begin $display("Failed repeat(3) at %0t, expected 4'h0, got %h", $simtime, result[0]); pass = 1'b0; end #15; count = 0; result[0] <= repeat(count) @(posedge clk) in; @(result[0]); // Reals happen faster they can use an #0, vectors are slower. if ($simtime != 65 || result[0] !== 4'h3) begin $display("Failed repeat(0) at %0t, expected 4'h3, got %h", $simtime, result[0]); pass = 1'b0; end #20; count = -1; result[0] <= repeat(count) @(posedge clk) in; @(result[0]); // Reals happen faster they can use an #0, vectors are slower. if ($simtime != 85 || result[0] !== 4'h4) begin $display("Failed repeat(-1) at %0t, expected 4'h4, got %h", $simtime, result[0]); pass = 1'b0; end #20; result[0] <= @(posedge clk) 4'h0; result[0] <= @(posedge clk) in; // This one sets the final value. @(result[0]); if ($simtime != 110 || result[0] !== 4'h5) begin $display("Failed @ at %0t, expected 4'h5, got %h", $simtime, result[0]); pass = 1'b0; end icount = 3'd2; result[0] <= @(posedge clk) 4'h1; result[0] <= repeat(icount) @(posedge clk) 4'h2; result[0] <= repeat(3) @(posedge clk) 4'h3; @(result[0]); if ($simtime != 130 || result[0] !== 4'h1) begin $display("Failed first @ at %0t, expected 4'h1, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 150 || result[0] !== 4'h2) begin $display("Failed second @ at %0t, expected 4'h2, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 170 || result[0] !== 4'h3) begin $display("Failed third @ at %0t, expected 4'h3, got %h", $simtime, result[0]); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_array_pv.v000066400000000000000000000051331435245347300217040ustar00rootroot00000000000000// Check that non-blocking event control assignment to a part select on a vector // array works when using an immediate index. module top; reg pass = 1'b1; integer count; reg [2:0] icount; reg clk = 0; reg [3:0] in = 4'h0; reg [7:0] result [1:0]; always #10 clk = ~clk; always #20 in = in + 4'h1; initial begin count = 3; result[0][3:0] <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result[0] !== 8'bx) begin $display("Failed repeat(3) blocked at %0t, expected 8'hxx, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 50 || result[0] !== 8'hx0) begin $display("Failed repeat(3) at %0t, expected 8'hx0, got %h", $simtime, result[0]); pass = 1'b0; end #15; count = 0; result[0][7:4] <= repeat(count) @(posedge clk) in; @(result[0]); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 65 || result[0] !== 8'h30) begin $display("Failed repeat(0) at %0t, expected 8'h30, got %h", $simtime, result[0]); pass = 1'b0; end #20; count = -1; result[0][8:5] <= repeat(count) @(posedge clk) in; @(result[0]); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 85 || result[0] !== 8'h90) begin $display("Failed repeat(-1) at %0t, expected 8'h80, got %h", $simtime, result[0]); pass = 1'b0; end #20; result[0][7:4] <= @(posedge clk) 4'h0; result[0][7:4] <= @(posedge clk) in; // This one sets the final value. @(result[0]); if ($simtime != 110 || result[0] !== 8'h50) begin $display("Failed @ at %0t, expected 8'h50, got %h", $simtime, result[0]); pass = 1'b0; end icount = 3'd2; result[0][3:0] <= @(posedge clk) 4'h1; result[0][7:4] <= repeat(icount) @(posedge clk) 4'h2; result[0][1:-2] <= repeat(3) @(posedge clk) 4'h3; @(result[0]); if ($simtime != 130 || result[0] !== 8'h51) begin $display("Failed first @ at %0t, expected 8'h51, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 150 || result[0] !== 8'h21) begin $display("Failed second @ at %0t, expected 8'h21, got %h", $simtime, result[0]); pass = 1'b0; end @(result[0]); if ($simtime != 170 || result[0] !== 8'h20) begin $display("Failed third @ at %0t, expected 8'h20, got %h", $simtime, result[0]); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_array_pv2.v000066400000000000000000000052311435245347300217650ustar00rootroot00000000000000// Check that non-blocking event control assignment to a part select on a vector // array works when using a variable index. module top; reg pass = 1'b1; integer i = 0; integer j = 1; integer count; reg [2:0] icount; reg clk = 0; reg [3:0] in = 4'h0; reg [7:0] result [1:0]; always #10 clk = ~clk; always #20 in = in + 4'h1; initial begin count = 3; i = 0; result[j][i+:4] <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result[j] !== 8'bx) begin $display("Failed repeat(3) blocked at %0t, expected 8'hxx, got %h", $simtime, result[j]); pass = 1'b0; end @(result[j]); if ($simtime != 50 || result[j] !== 8'hx0) begin $display("Failed repeat(3) at %0t, expected 8'hx0, got %h", $simtime, result[j]); pass = 1'b0; end #15; count = 0; result[j][i+4+:4] <= repeat(count) @(posedge clk) in; @(result[j]); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 65 || result[j] !== 8'h30) begin $display("Failed repeat(0) at %0t, expected 8'h30, got %h", $simtime, result[j]); pass = 1'b0; end #20; count = -1; result[j][i+5+:4] <= repeat(count) @(posedge clk) in; @(result[j]); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 85 || result[j] !== 8'h90) begin $display("Failed repeat(-1) at %0t, expected 8'h80, got %h", $simtime, result[j]); pass = 1'b0; end #20; result[j][i+4+:4] <= @(posedge clk) 4'h0; result[j][i+4+:4] <= @(posedge clk) in; // This one sets the final value. @(result[j]); if ($simtime != 110 || result[j] !== 8'h50) begin $display("Failed @ at %0t, expected 8'h50, got %h", $simtime, result[j]); pass = 1'b0; end icount = 3'd2; result[j][i+:4] <= @(posedge clk) 4'h1; result[j][i+4+:4] <= repeat(icount) @(posedge clk) 4'h2; result[j][i+1-:4] <= repeat(3) @(posedge clk) 4'h3; @(result[j]); if ($simtime != 130 || result[j] !== 8'h51) begin $display("Failed first @ at %0t, expected 8'h51, got %h", $simtime, result[j]); pass = 1'b0; end @(result[j]); if ($simtime != 150 || result[j] !== 8'h21) begin $display("Failed second @ at %0t, expected 8'h21, got %h", $simtime, result[j]); pass = 1'b0; end @(result[j]); if ($simtime != 170 || result[j] !== 8'h20) begin $display("Failed third @ at %0t, expected 8'h20, got %h", $simtime, result[j]); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_concat.v000066400000000000000000000037301435245347300213310ustar00rootroot00000000000000// Check that non-blocking event control assignments to concatanations work as // expected. module test; reg failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED. %s: expected %b, got %b.", `"val`", exp, val); \ failed = 1'b1; \ end reg [3:0] x; reg [3:0] y; reg [3:0] z[1:0]; integer i = 0; event e; initial begin // Test all of // * vector // * vector part select // * array element // * array element part // Immediate index {z[1][1:0],z[0],y[1:0],x} <= @e 12'h5a5; #1 // Assignment must not occur until the event is triggered `check(z[1], 4'bxxxx) `check(z[0], 4'bxxxx) `check(y, 4'bxxxx) `check(x, 4'bxxxx) ->e; `check(z[1], 4'bxx01); `check(z[0], 4'b0110); `check(y, 4'bxx10); `check(x, 4'b0101); x = 4'hx; y = 4'hx; z[0] = 4'hx; z[1] = 4'hx; // Immediate index reverse order {x,y[1:0],z[0],z[1][1:0]} <= @e 12'ha5a; #1 `check(z[1], 4'bxxxx) `check(z[0], 4'bxxxx) `check(y, 4'bxxxx) `check(x, 4'bxxxx) ->e; `check(z[1], 4'bxx10); `check(z[0], 4'b0110); `check(y, 4'bxx01); `check(x, 4'b1010); x = 4'hx; y = 4'hx; z[0] = 4'hx; z[1] = 4'hx; // Variable index {z[i+1][i+:2],z[i],y[i+:2],x} <= @e 12'h5a5; #1 `check(z[1], 4'bxxxx) `check(z[0], 4'bxxxx) `check(y, 4'bxxxx) `check(x, 4'bxxxx) ->e; `check(z[1], 4'bxx01); `check(z[0], 4'b0110); `check(y, 4'bxx10); `check(x, 4'b0101); x = 4'hx; y = 4'hx; z[0] = 4'hx; z[1] = 4'hx; // Variable index reverse order {x,y[i+:2],z[i],z[i+1][i+:2]} <= @e 12'ha5a; #1 `check(z[1], 4'bxxxx) `check(z[0], 4'bxxxx) `check(y, 4'bxxxx) `check(x, 4'bxxxx) ->e; `check(z[1], 4'bxx10); `check(z[0], 4'b0110); `check(y, 4'bxx01); `check(x, 4'b1010); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_multi_ev.v000066400000000000000000000017251435245347300217100ustar00rootroot00000000000000// Check that non-blocking event control assignments with multiple events in the // event control expression are supported. module test; reg failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED. Expected %d, got %d.", exp, val); \ failed = 1'b1; \ end integer x = 0; event e1, e2, e3; initial begin // Any of them should trigger the event x <= @(e1 or e2 or e3) x + 1; #1 `check(x, 0); ->e1; `check(x, 1); x <= @(e1 or e2 or e3) x + 1; #1 `check(x, 1); ->e2; `check(x, 2); // Alternative syntax, but still the same behavior x <= @(e1, e2, e3) x + 1; #1 `check(x, 2); ->e3; `check(x, 3); // In combination with repeat x <= repeat(3) @(e1, e2, e3) x + 1; #1 `check(x, 3); ->e1; `check(x, 3); ->e2; `check(x, 3); ->e3; `check(x, 4); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_pv.v000066400000000000000000000045701435245347300205120ustar00rootroot00000000000000module top; reg pass = 1'b1; integer count; reg [2:0] icount; reg clk = 0; reg [3:0] in = 4'h0; reg [7:0] result; always #10 clk = ~clk; always #20 in = in + 4'h1; initial begin count = 3; result[3:0] <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result !== 8'bx) begin $display("Failed repeat(3) blocked at %0t, expected 8'hxx, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 50 || result !== 8'hx0) begin $display("Failed repeat(3) at %0t, expected 8'hx0, got %h", $simtime, result); pass = 1'b0; end #15; count = 0; result[7:4] <= repeat(count) @(posedge clk) in; @(result); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 65 || result !== 8'h30) begin $display("Failed repeat(0) at %0t, expected 8'h30, got %h", $simtime, result); pass = 1'b0; end #20; count = -1; result[8:5] <= repeat(count) @(posedge clk) in; @(result); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 85 || result !== 8'h90) begin $display("Failed repeat(-1) at %0t, expected 8'h80, got %h", $simtime, result); pass = 1'b0; end #20; result[7:4] <= @(posedge clk) 4'h0; result[7:4] <= @(posedge clk) in; // This one sets the final value. @(result); if ($simtime != 110 || result !== 8'h50) begin $display("Failed @ at %0t, expected 8'h50, got %h", $simtime, result); pass = 1'b0; end icount = 3'd2; result[3:0] <= @(posedge clk) 4'h1; result[7:4] <= repeat(icount) @(posedge clk) 4'h2; result[1:-2] <= repeat(3) @(posedge clk) 4'h3; @(result); if ($simtime != 130 || result !== 8'h51) begin $display("Failed first @ at %0t, expected 8'h51, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 150 || result !== 8'h21) begin $display("Failed second @ at %0t, expected 8'h21, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 170 || result !== 8'h20) begin $display("Failed third @ at %0t, expected 8'h20, got %h", $simtime, result); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_pv2.v000066400000000000000000000020311435245347300205620ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg pass = 1'b1; reg clk = 0; reg [7:0] result; reg [3:0] bit; always #10 clk = ~clk; initial begin // Since the bit is not defined this assignment will not happen. // We will check to verify this fact 1 time step after it should // happen (50). result[bit] <= repeat(3) @(posedge clk) 1'b0; if ($simtime != 0 || result !== 8'bx) begin $display("Failed repeat(3) blocked at %0t, expected 8'hxx, got %h", $simtime, result); pass = 1'b0; end #51; if (result !== 8'hxx) begin $display("Failed repeat(3) at %0t, expected 8'hxx, got %h", $simtime, result); pass = 1'b0; end bit = 0; result[bit] <= @(posedge clk) 4'h0; @(result) if ($simtime != 70 || result !== 8'bxxxxxxx0) begin $display("Failed repeat(3) at %0t, expected 8'bxxxxxxx0, got %h", $simtime, result); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/nb_ec_real.v000066400000000000000000000043531435245347300210070ustar00rootroot00000000000000module top; reg pass = 1'b1; integer count; reg [2:0] icount; reg clk = 0; real in = 0.0; real result = -1.0; always #10 clk = ~clk; always #20 in = in + 1.0; initial begin count = 3; result <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result != -1.0) begin $display("Failed repeat(3) blocked at %0t, expected -1.0, got %f", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 50 || result != 0.0) begin $display("Failed repeat(3) at %0t, expected 0.0, got %f", $simtime, result); pass = 1'b0; end #15; count = 0; result <= repeat(count) @(posedge clk) in; #0; // This may not work since there is no delay. if ($simtime != 65 || result != 3.0) begin $display("Failed repeat(0) at %0t, expected 3.0, got %f", $simtime, result); pass = 1'b0; end #20; count = -1; result <= repeat(count) @(posedge clk) in; #0; // This may not work since there is no delay. if ($simtime != 85 || result != 4.0) begin $display("Failed repeat(-1) at %0t, expected 4.0, got %f", $simtime, result); pass = 1'b0; end #20; result <= @(posedge clk) 0.0; result <= @(posedge clk) in; // This one sets the final value. @(result); if ($simtime != 110 || result != 5.0) begin $display("Failed @ at %0t, expected 5.0, got %f", $simtime, result); pass = 1'b0; end icount = 3'd2; result <= @(posedge clk) 1.0; result <= repeat(icount) @(posedge clk) 2.0; result <= repeat(3) @(posedge clk) 3.0; @(result); if ($simtime != 130 || result != 1.0) begin $display("Failed first @ at %0t, expected 1.0, got %f", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 150 || result != 2.0) begin $display("Failed second @ at %0t, expected 2.0, got %f", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 170 || result != 3.0) begin $display("Failed third @ at %0t, expected 3.0, got %f", $simtime, result); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nb_ec_vector.v000066400000000000000000000045001435245347300213600ustar00rootroot00000000000000module top; reg pass = 1'b1; integer count; reg [2:0] icount; reg clk = 0; reg [3:0] in = 4'h0; reg [3:0] result; always #10 clk = ~clk; always #20 in = in + 4'h1; initial begin count = 3; result <= repeat(count) @(posedge clk) in; if ($simtime != 0 || result !== 4'bx) begin $display("Failed repeat(3) blocked at %0t, expected 4'hx, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 50 || result !== 4'h0) begin $display("Failed repeat(3) at %0t, expected 4'h0, got %h", $simtime, result); pass = 1'b0; end #15; count = 0; result <= repeat(count) @(posedge clk) in; @(result); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 65 || result !== 4'h3) begin $display("Failed repeat(0) at %0t, expected 4'h3, got %h", $simtime, result); pass = 1'b0; end #20; count = -1; result <= repeat(count) @(posedge clk) in; @(result); // Reals happen faster so they can use an #0, vectors are slower. if ($simtime != 85 || result !== 4'h4) begin $display("Failed repeat(-1) at %0t, expected 4'h4, got %h", $simtime, result); pass = 1'b0; end #20; result <= @(posedge clk) 4'h0; result <= @(posedge clk) in; // This one sets the final value. @(result); if ($simtime != 110 || result !== 4'h5) begin $display("Failed @ at %0t, expected 4'h5, got %h", $simtime, result); pass = 1'b0; end icount = 3'd2; result <= @(posedge clk) 4'h1; result <= repeat(icount) @(posedge clk) 4'h2; result <= repeat(3) @(posedge clk) 4'h3; @(result); if ($simtime != 130 || result !== 4'h1) begin $display("Failed first @ at %0t, expected 4'h1, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 150 || result !== 4'h2) begin $display("Failed second @ at %0t, expected 4'h2, got %h", $simtime, result); pass = 1'b0; end @(result); if ($simtime != 170 || result !== 4'h3) begin $display("Failed third @ at %0t, expected 4'h3, got %h", $simtime, result); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/nblkorder.v000066400000000000000000000030631435245347300207150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validates Non-blocking order determinism IEEE1364-Draft, page 5-3, // SDW - section 5.4.1. module main (); reg x,clock; reg inval; reg error; always @(posedge clock) begin x <= ~inval; x <= inval; end initial begin clock = 0; error = 0; #1; inval = 0; #5 ; clock = 1; #1 ; if(x !== inval) begin $display("FAILED - parallel non-blocking assign s/b 0, is %b",x); error = 1; end #6 clock = 0; #1 ; inval = 1; #5 ; clock = 1; #1 ; if(x !== inval) begin $display("FAILED - parallel non-blocking assign s/b 1, is %b",x); error = 1; end #1 ; if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/nblkpush.v000066400000000000000000000033621435245347300205630ustar00rootroot00000000000000// // Copyright (c) 2001 Stephan Boettcher // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // Validates Non-blocking assignment propagation // $Id: nblkpush.v,v 1.2 2005/07/07 16:25:20 stevewilliams Exp $ // Update: This test has a race in it that makes it not valid. The // assumption that a blocking assign will push through the continuous // assignment before the thread doing the assign is allowed to advance // is not valid. This test only passes Verilog XL. Every other tool, // commercial or otherwise, seems to FAIL this test. Therefore, this // test should not be relied on. module test; reg a, b, c, d; wire ab = a & b; wire abc = ab | c; wire abcd = abc & d; initial begin a = 0; b = 1; c = 0; d = 1; #1; a = 1; if (abcd === 1) begin $display("PASSED"); $finish; end $display("FAILED ab=%b, abc=%b, abcd=%b", ab, abc, abcd); #1; if (abcd === 1) $display("abcd value changed late"); else $display("abcd value still wrong"); end endmodule iverilog-12_0/ivtest/ivltests/negative_genvar.v000066400000000000000000000005761435245347300221050ustar00rootroot00000000000000module negative_genvar; wire signed [3:0] value[-7:7]; genvar i; for (i = 7; i >= -7; i = i - 1) begin:genloop assign value[i] = i; end integer j; reg fail = 0; initial begin #0; for (j = -7; j <= 7; j = j + 1) begin $display("%d", value[j]); if (value[j] !== j) fail = 1; end if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/negvalue.v000066400000000000000000000002611435245347300205360ustar00rootroot00000000000000module negvalue; reg[7:0]reg1; initial begin reg1 <= -13 +21 ; #1 reg1 <= 0 -13 +21 ; end always@(reg1)begin $display("%d (should be 8)",reg1); end endmodule iverilog-12_0/ivtest/ivltests/neq1.v000066400000000000000000000012451435245347300175770ustar00rootroot00000000000000module main; reg [2:0] a; wire e0 = a==3'h0; wire n0 = a!=3'h0; wire e1 = a==3'h1; wire n1 = a!=3'h1; wire e2 = a==3'h2; wire n2 = a!=3'h2; wire e3 = a==3'h3; wire n3 = a!=3'h3; wire e4 = a==3'h4; wire n4 = a!=3'h4; wire e5 = a==3'h5; wire n5 = a!=3'h5; wire e6 = a==3'h6; wire n6 = a!=3'h6; wire e7 = a==3'h7; wire n7 = a!=3'h7; initial begin for (a=0; a<7; a=a+1) begin #1; $display("a=",a); $display(" 0 %d %d", e0, n0); $display(" 1 %d %d", e1, n1); $display(" 2 %d %d", e2, n2); $display(" 3 %d %d", e3, n3); $display(" 4 %d %d", e4, n4); $display(" 5 %d %d", e5, n5); $display(" 6 %d %d", e6, n6); $display(" 7 %d %d", e7, n7); end end endmodule iverilog-12_0/ivtest/ivltests/nested_func.v000066400000000000000000000006151435245347300212300ustar00rootroot00000000000000module nested_func(); function automatic real sum; input real a; input real b; begin sum = a + b; end endfunction real r1; real r2; real r3; initial begin r1 = sum(sum(2, 3), sum(4, 5)); r2 = sum(3, sum(4, sum(5, 6))); r3 = sum(sum(sum(4, 5), 6), 7); $display("sum of 2 to 5 = %0d", r1); $display("sum of 3 to 6 = %0d", r2); $display("sum of 4 to 7 = %0d", r3); end endmodule iverilog-12_0/ivtest/ivltests/nested_impl_event1.v000066400000000000000000000005031435245347300225140ustar00rootroot00000000000000module test(); reg a, b, c; always @* begin // always @(b or c) a = b; $display("Triggered 1 at %0t", $time); @* a = c; // @(c) $display("Triggered 2 at %0t", $time); end initial begin #10 a = 0; #10 a = 1; #10 b = 0; #10 b = 1; #10 c = 0; #10 c = 1; #10 c = 0; #10 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/nested_impl_event2.v000066400000000000000000000004051435245347300225160ustar00rootroot00000000000000module test(); reg a, b; always @* begin // always @(b) a = b; $display("Triggered 1 at %0t", $time); @*; $display("Triggered 2 at %0t", $time); end initial begin #10 a = 0; #10 a = 1; #10 b = 0; #10 b = 1; #10 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/net_class_fail.v000066400000000000000000000002541435245347300217000ustar00rootroot00000000000000// Check that declaring a net of a class type results in an error module test; class C; endclass wire C x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/net_darray_fail.v000066400000000000000000000002361435245347300220550ustar00rootroot00000000000000// Check that declaring a net of a dynamic array type results in an error module test; wire x[]; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/net_queue_fail.v000066400000000000000000000002271435245347300217170ustar00rootroot00000000000000// Check that declaring a net of a queue type results in an error module test; wire x[$]; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/net_string_fail.v000066400000000000000000000002321435245347300220750ustar00rootroot00000000000000// Check that declaring a net of string type results in an error module test; wire string x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/no_if_statement.v000066400000000000000000000000651435245347300221100ustar00rootroot00000000000000module top; reg var; always if (var); endmodule iverilog-12_0/ivtest/ivltests/no_timescale_in_module.v000066400000000000000000000000741435245347300234270ustar00rootroot00000000000000`timescale 1ns/1ps module top; `timescale 1us/1ns endmodule iverilog-12_0/ivtest/ivltests/non-polymorphic-abs.v000066400000000000000000000004461435245347300226350ustar00rootroot00000000000000// $abs should take a real argument and return a real result. module test(); localparam s = 0; localparam a = 1.5; localparam b = 1; localparam r = $abs((s ? a : b) / 2); initial begin $display("%g", r); if (r == 0.5) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/not_a_latch1.v000066400000000000000000000022571435245347300212730ustar00rootroot00000000000000 module test(input wire load, in, output reg out1, out2); (* ivl_combinational *) always @* begin out1 = 0; if (load) begin out1 = in; out2 = in; end else begin out2 = ~in; end end endmodule // test module test_bench; reg load; reg val; wire out1, out2; test DUT(.load(load), .in(val), .out1(out1), .out2(out2)); (* ivl_synthesis_off *) initial begin val = 0; load = 1; #1 ; if (out1 !== 0 || out2 !== 0) begin $display("FAILED -- load=%b, val=%b, out1=%b, out2=%b", load, val, out1, out2); $finish; end val = 1; #1 ; if (out1 !== 1 || out2 !== 1) begin $display("FAILED -- load=%b, val=%b, out1=%b, out2=%b", load, val, out1, out2); $finish; end load = 0; #1 ; if (out1 !== 0 || out2 !== 0) begin $display("FAILED -- load=%b, val=%b, out1=%b, out2=%b", load, val, out1, out2); $finish; end val = 0; #1 ; if (out1 !== 0 || out2 !== 1) begin $display("FAILED -- load=%b, val=%b, out1=%b, out2=%b", load, val, out1, out2); $finish; end $display("PASSED"); end // initial begin endmodule // test_bench iverilog-12_0/ivtest/ivltests/not_a_latch2.v000066400000000000000000000031141435245347300212650ustar00rootroot00000000000000 module test(input wire load, drain, input wire clk, data, output reg foo_nxt, bar_nxt); reg foo, bar; (* ivl_combinational *) always @* begin foo_nxt = foo; bar_nxt = bar; if (load) begin foo_nxt = data; bar_nxt = 1; end else if (drain) begin bar_nxt = 0; end end always @(posedge clk) begin foo <= foo_nxt; bar <= bar_nxt; end endmodule // test module main; reg clk, load, drain, data; wire foo, bar; test dut (.clk(clk), .load(load), .drain(drain), .data(data), .foo_nxt(foo), .bar_nxt(bar)); (* ivl_synthesis_off *) initial begin clk = 0; load = 1; drain = 0; data = 1; #1 clk = 1; #1 clk = 0; $display("%0t: load=%b, drain=%b, data=%b: foo=%b, bar=%b", $time, load, drain, data, foo, bar); if (foo !== 1 || bar !== 1) begin $display("FAILED -- foo=%b, bar=%b (1)", foo, bar); $finish; end data = 0; #1 clk = 1; #1 clk = 0; $display("%0t: load=%b, drain=%b, data=%b: foo=%b, bar=%b", $time, load, drain, data, foo, bar); if (foo !== 0 || bar !== 1) begin $display("FAILED -- foo=%b, bar=%b (2)", foo, bar); $finish; end load = 0; drain = 1; #1 ; if (foo !== 0 || bar !== 0) begin $display("FAILED -- foo=%b, bar=%b (3)", foo, bar); $finish; end #1 clk = 1; #1 clk = 0; $display("%0t: load=%b, drain=%b, data=%b: foo=%b, bar=%b", $time, load, drain, data, foo, bar); $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/npmos.v000066400000000000000000000035451435245347300200740ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; wire no, po; reg d, c; nmos n (no, d, c); pmos p (po, d, c); initial begin c = 0; d = 0; #1 if (no !== 1'bz) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'b0) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end d = 1; #1 if (no !== 1'bz) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'b1) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end c = 1; #1 if (no !== 1'b1) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'bz) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end d = 0; #1 if (no !== 1'b0) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'bz) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/npmos2.v000066400000000000000000000043361435245347300201550ustar00rootroot00000000000000// Copyright (c) 2001 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * This module implements what essentially amounts to an array of DFF * devices with output enable. This test checks the operation of the * pmos and nmos devices. */ module grayGap (ad, clk, read, write); output [31:0] ad; input clk, read, write; reg [15:0] regff; pmos ad_drv [31:0] (ad, {16'b0, regff}, read); always @(posedge clk) if (write) regff = ad[15:0]; endmodule module main; wire [31:0] ad; reg clk, read, write; reg [31:0] ad_val; reg ad_en; nmos ad_drv[31:0] (ad, ad_val, ad_en); grayGap test (ad, clk, read, write); always #10 clk = ~clk; initial begin clk = 1; read = 1; write = 0; $monitor($time, "ad=%b", ad); // Set up to write a value into the grayGap register. @(negedge clk) ad_val = 32'haaaa_aaaa; read = 1; write = 1; ad_en = 1; // The posedge has passed, now set up to read that value // out. Turn all the drivers off for a moment, to see that the // line becomes tri-state... @(negedge clk) ad_en = 0; write = 0; // Now read the value. #1 read = 0; #1 $display("Wrote %h, got %h", ad_val, ad); if (ad !== 32'b0000_0000_0000_0000_1010_1010_1010_1010) begin $display("FAILED -- ad is %b", ad); $finish; end #2 read = 1; $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/p_monta.v000066400000000000000000000014301435245347300203640ustar00rootroot00000000000000// From: Peter Monta // Subject: verilog: vvp bug, function or concat related? // Message-Id: <20010726071414.1CEF41C5@www.pmonta.com> // Date: Thu, 26 Jul 2001 00:14:14 -0700 (PDT) module main(); function [7:0] f; input [7:0] r; f = { r[0]^r[1]^r[2]^r[3]^r[7], r[3]^r[6]^r[7], r[2]^r[5]^r[6], r[1]^r[4]^r[5]^r[7], r[0]^r[3]^r[4]^r[6]^r[7], r[0]^r[1]^r[5]^r[6], r[1]^r[2]^r[3]^r[4]^r[5], r[0]^r[1]^r[2]^r[3]^r[4] }; endfunction reg [7:0] data_in; reg [7:0] r; reg start_in; initial begin data_in = 8'h23; r = 0; start_in = 0; #2; r <= #1 start_in ? 0 : f(data_in); #2; $display("%b",r); if (r === 8'b00101100) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/package_vec_part_select.v000066400000000000000000000006061435245347300235500ustar00rootroot00000000000000// Check that it is possible to do a part select on a vector declared in // package package P; reg [7:0] x = 8'h5a; reg [1:0][7:0] y = 16'h5af0; endpackage module test; initial begin if (P::x[3:0] == 4'ha && P::x[7:4] == 4'h5 && P::y[0] == 8'hf0 && P::y[1] == 8'h5a) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/packed_dims_invalid_class.v000066400000000000000000000005571435245347300240760ustar00rootroot00000000000000// Invalid packed dimensions // This should generate a error message and not crash during elaboration typedef logic [] T1; typedef logic [0] T2; typedef logic [-1] T3; typedef logic [$] T4; class C; logic [$] a; T1 b; T1 [$] c; logic [0] d; T2 e; T2 [0] f; logic [-1] g; T3 h; T3 [-1] i; logic [$] j; T4 k; T4 [$] l; endclass module test; endmodule iverilog-12_0/ivtest/ivltests/packed_dims_invalid_module.v000066400000000000000000000006611435245347300242520ustar00rootroot00000000000000// Invalid packed dimensions // This should generate a error message and not crash during elaboration typedef logic [] T1; typedef logic [0] T2; typedef logic [-1] T3; typedef logic [$] T4; module test ( input [] port_a, input [0] port_b, output [-1] port_c, output [$] port_d ); logic [$] a; T1 b; T1 [$] c; logic [0] d; T2 e; T2 [0] f; logic [-1] g; T3 h; T3 [-1] i; logic [$] j; T4 k; T4 [$] l; endmodule iverilog-12_0/ivtest/ivltests/packeda.v000066400000000000000000000044731435245347300203310ustar00rootroot00000000000000module top; // packed 2D array, arranged as 4 bytes of 8 bits each. logic [3:0][7:0] word32; int idx; int x; // Show a slice select in a continuous assignment wire [7:0] word1 = word32[1]; initial begin // Const slice select in l-values. word32[0] = 'h00; word32[1] = 'h11; word32[2] = 'h22; word32[3] = 'h33; if (word32 !== 'h33_22_11_00) begin $display("FAILED -- word32 = %h (1)", word32); $finish; end #1 if (word1 !== 8'h11) begin $display("FAILED -- word1 = %h", word1); $finish; end // Non-constant slice indices, l-value and r-value. for (idx = 0 ; idx < 4 ; idx = idx+1) word32[idx] = ~word32[idx]; if (word32 !== ~ 'h33_22_11_00) begin $display("FAILED -- word32 = %h (2)", word32); $finish; end word32[0][3:0] = 'h0; word32[1][3:0] = 'h1; word32[2][3:0] = 'h2; word32[3][3:0] = 'h3; word32[0][7:4] = 'h3; word32[1][7:4] = 'h2; word32[2][4 +: 4] = 'h1; word32[3][4 +: 4] = 'h0; if (word32 !== 'h03_12_21_30) begin $display("FAILED -- word32 = %h (3)", word32); $finish; end if (word32[1][7:4] !== word32[1][4 +: 4]) begin $display("FAILED -- word32[1][7:4]=%h, word32[1][4 +: 4]=%h", word32[1][7:4],word32[1][4 +: 4]); $finish; end x = 4; word32[1][x +: 4] = 'h2; if (word32[1][7:4] !== word32[1][x +: 4]) begin $display("FAILED -- word32[1][7:4]=%h, word32[1][4 +: 4]=%h", word32[1][7:4],word32[1][x +: 4]); $finish; end for (idx = 0 ; idx < 8 ; idx = idx+1) begin word32[0][idx] = idx[0]; word32[2][idx] = idx[0]; word32[1][idx] = ~idx[0]; word32[3][idx] = ~idx[0]; end if (word32 !== 'h55_aa_55_aa) begin $display("FAILED -- word32 = %h (4)", word32); $finish; end for (idx = 0 ; idx < 8 ; idx = idx+1) begin if (word32[0][idx] !== word32[2][idx]) begin $display("FAILED -- word32[0][%0d]=%b, word32[2][%0d]=%b", idx, word32[0][idx], idx, word32[2][idx]); $finish; end if (word32[1][idx] !== word32[3][idx]) begin $display("FAILED -- word32[1][%0d]=%b, word32[3][%0d]=%b", idx, word32[1][idx], idx, word32[3][idx]); $display("FAILED"); $finish; end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/packeda2.v000066400000000000000000000012541435245347300204050ustar00rootroot00000000000000module main; wire logic [3:0][7:0] foo; genvar idx; for (idx = 0 ; idx <= 3 ; idx = idx+1) begin: test test dut (.sum(foo[idx]), .a(idx)); end logic [7:0] tmp; initial begin #0; // avoid time-zero race for (tmp = 0 ; tmp <= 3 ; tmp = tmp+1) begin //if ($bits(foo[tmp]) !== 8) begin // $display("FAILED -- $bits = %d", $bits(foo[tmp])); // $finish; //end if (foo[tmp] !== (tmp+8'd5)) begin $display("FAILED -- foo[%d] = %b", tmp, foo[tmp]); $finish; end end $display("PASSED"); end endmodule // main module test (output logic[7:0] sum, input logic [7:0]a); assign sum = a + 8'd5; endmodule // test iverilog-12_0/ivtest/ivltests/par_mismatch.v000066400000000000000000000006071435245347300214030ustar00rootroot00000000000000module top; reg in; wire [7:0] out; lwr dut(out, in); initial begin $display("FAILED"); end endmodule module lwr(out, in); output [7:0] out; input in; assign out = {8{in}}; specify // It is an error to use a parallel connection here since the input // and output (source/destination) do not have the same width. (in => out) = 2; endspecify endmodule iverilog-12_0/ivtest/ivltests/param-extend.v000066400000000000000000000014151435245347300213170ustar00rootroot00000000000000module top(); localparam signed [31:0] SizedValue = -1; localparam UnsizedValue = -1; reg [35:0] Result; reg Failed; initial begin Failed = 0; // check for sign extension Result = SizedValue; $display("%h", Result); if (Result !== 36'hfffffffff) Failed = 1; Result = UnsizedValue; $display("%h", Result); if (Result !== 36'hfffffffff) Failed = 1; // check for zero extension Result = 'd0 + SizedValue; $display("%h", Result); if (Result !== 36'h0ffffffff) Failed = 1; Result = 'd0 + UnsizedValue; $display("%h", Result); `ifdef OLD_UNSIZED if (Result !== 36'hfffffffff) Failed = 1; `else if (Result !== 36'h0ffffffff) Failed = 1; `endif if (Failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param-width.v000066400000000000000000000006351435245347300211520ustar00rootroot00000000000000module param_width(); parameter a = 3'd4; parameter b = 3'd5; parameter c = 3'd4; parameter d = 3'd5; parameter [3:0] sum1 = a + b; parameter sum2 = a + b; parameter [3:0] sum3 = c + d; parameter sum4 = c + d; defparam c = 2'd2; defparam d = 2'd3; initial begin $display("%b", sum1); $display("%b", sum2); $display("%b", sum3); $display("%b", sum4); end endmodule iverilog-12_0/ivtest/ivltests/param_add.v000066400000000000000000000021201435245347300206340ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify addition in a param declaration */ module test; parameter A0 = 4'b0011 + 4'b0001 ; initial begin if(A0 !== 4'b0100) $display("FAILED - Addition in a param declaration."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_and.v000066400000000000000000000021471435245347300206570ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: This test is a first expression test inside a parameter declaration. */ module test; parameter A0 = 2'b10 & 2'b11 ; initial begin if(A0 !== 2'b10) $display("FAILED - A0 expression AND doesn't work."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_and2.v000066400000000000000000000021401435245347300207320ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify expression using logical and in a parameter declaration */ module test; parameter A0 = 2'b10 && 2'b01 ; initial begin if(A0 !== 1'b1) $display("FAILED - A0 expression && doesn't work."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_band.v000066400000000000000000000021351435245347300210160ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify expression using bit-wise and in a parameter declaration */ module test; parameter A0 = & 4'b1111; initial begin if(A0 !== 1'b1) $display("FAILED - bit-wise and in an expression ."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_binv.v000066400000000000000000000021401435245347300210440ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify bit vector inversion in a param declaration */ module test; parameter A0 = ~(4'b1010); initial begin if(A0 !== 4'b0101) $display("FAILED - Bit vector inversion in a param declaration."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_bor.v000066400000000000000000000021341435245347300206730ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify expression using bit-wise or in a parameter declaration */ module test; parameter A0 = | 4'b0001; initial begin if(A0 !== 1'b1) $display("FAILED - bit-wise and in an expression ."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_concat.v000066400000000000000000000017411435245347300213630ustar00rootroot00000000000000/* * Copyright (c) 2000 Peter Monta * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; parameter foo = { 2'b01, 2'b10 }; initial if (foo==4'b0110) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/param_eq3.v000066400000000000000000000021511435245347300206000ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: This verifies the bit equivalence expr in a parameter */ module test; parameter A0 = (3'b1zx === 3'b1zx); initial begin if(A0 !== 1'b1) $display("FAILED - Expression equivalence fails in a parameter."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_expr.v000066400000000000000000000021461435245347300210720ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: This test is a first expression test inside a parameter declaration. */ module test; parameter A0 = 2'b10 | 2'b01 ; initial begin if(A0 !== 2'b11) $display("FAILED - A0 expression OR doesn't work."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_mod.v000066400000000000000000000021131435245347300206650ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * SDW: Verify addition in a param declaration */ module test; parameter A0 = 4'b0011 % 4'b0010 ; initial begin if(A0 !== 4'b0001) $display("FAILED - Mod in a param declaration."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_select.v000066400000000000000000000027041435245347300213730ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests the ability to take bit and part selects * of parameters. This is actually not legal in Verilog, but * Icarus Verilog supports it anyhow, as do many (most?) other * Verilog compilers. */ module main; parameter vec = 16'b0000_1001_0111_1010; initial begin if (vec[0] !== 0) begin $display("FAILED -- %b[0] !== 0", vec); $finish; end if (vec[1] !== 1) begin $display("FAILED -- %b[1] !== 1", vec); $finish; end if (vec[3:1] !== 3'b101) begin $display("FAILED -- %b[3:1] !== b101", vec); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_select2.v000066400000000000000000000036271435245347300214620ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module checks that parameter bit select works * in parameter assignment expressions. */ module main; parameter value = 2'b10; parameter x = 0; parameter y = 1; parameter pa = value[0]; parameter pb = value[1]; parameter px = value[x]; parameter py = value[y]; initial begin if (pa !== value[0]) begin $display("FAILED -- pa == %b", pa); $finish; end if (pa !== 0) begin $display("FAILED -- pa == %b", pa); $finish; end if (pb !== value[1]) begin $display("FAILED -- pb == %b", pb); $finish; end if (pb !== 1) begin $display("FAILED -- pb == %b", pb); $finish; end if (px !== value[0]) begin $display("FAILED -- px == %b", px); $finish; end if (px !== 0) begin $display("FAILED -- px == %b", px); $finish; end if (py !== value[1]) begin $display("FAILED -- py == %b", py); $finish; end if (py !== 1) begin $display("FAILED -- py == %b", py); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/param_select3.v000066400000000000000000000020641435245347300214550ustar00rootroot00000000000000/* * This program demonstrates non-constant part selects * applied to a parameter value. */ module main; parameter foo = 32'h76543210; reg [3:0] tmp; reg [3:0] idx; initial begin if (foo[0 +: 4] !== 4'h0) begin $display("FAILED -- %b !== 0", foo[0 +: 4]); $finish; end if (foo[4 +: 4] !== 4'h1) begin $display("FAILED -- %b !== 1", foo[4 +: 4]); $finish; end if (foo[8 +: 4] !== 4'h2) begin $display("FAILED -- %b !== 2", foo[8 +: 4]); $finish; end if (foo[12+: 4] !== 4'h3) begin $display("FAILED -- %b !== 3", foo[12 +: 4]); $finish; end for (idx = 0 ; idx < 8 ; idx = idx + 1) begin tmp = foo[(idx*4) +: 4]; if (tmp !== idx) begin $display("FAILED -- %b !== %b", idx, tmp); $finish; end end for (idx = 0 ; idx < 8 ; idx = idx + 1) begin tmp = foo[(idx*4+3) -: 4]; if (tmp !== idx) begin $display("FAILED -- %b !== %b", idx, tmp); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/param_string.v000066400000000000000000000016541435245347300214250ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; parameter passed = "PASSED"; initial $display(passed); endmodule // main iverilog-12_0/ivtest/ivltests/param_tern.v000066400000000000000000000034201435245347300210600ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; parameter PARM08 = 8; parameter PARM04 = PARM08 >> 1; parameter PARM16 = PARM08 << 1; parameter PARM10 = ((PARM08 <=2) ? 1: ((PARM08 <=4) ? 2: ((PARM08 <=8) ? 3:4))); // this parameterized input compiles ok wire [PARM04 : 0] in04; wire [PARM16 : 0] in05; reg [PARM08 : 0] out00; reg [PARM04 : 0] out04; reg [PARM16 : 0] out05; // this parameterized doesn't compile, stack dump wire [PARM10:0] in99; initial begin if (PARM08 !== 8) begin $display("FAILED -- PARM08 == %b", PARM08); $finish; end if (PARM04 !== 4) begin $display("FAILED -- PARM04 == %b", PARM04); $finish; end if (PARM16 !== 16) begin $display("FAILED -- PARM16 == %b", PARM16); $finish; end if (PARM10 !== 3) begin $display("FAILED -- PARM10 == %b", PARM10); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/param_tern2.v000066400000000000000000000011121435245347300211360ustar00rootroot00000000000000/* * This example is a distillation of the essence of PR#993. * Or at least the essence that led to a bug report. */ module main; parameter [31:0] fifo_address = 32'hc0_00_00_00; reg [31:0] bar; reg flag; wire [31:0] foo = flag? fifo_address : bar; initial begin bar = ~fifo_address; flag = 1; #1 if (foo !== fifo_address) begin $display("FAILED"); $finish; end flag = 0; #1 if (foo !== bar) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/param_test1.v000066400000000000000000000032061435245347300211520ustar00rootroot00000000000000/* * Copyright (c) 2001 Peter Bain * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* This is based on PR#124. */ `timescale 1ns/1ns module paramtest(clk, dat); parameter dat_width = 32; input clk; output [dat_width-1:0] dat; reg [dat_width-1:0] dat; reg [4-1:0] exp_dat; parameter pay_init = 32'h01020304; parameter pay_inc = 32'h01010101; parameter cell_size = (53 * 8); parameter transfers = cell_size/dat_width + ((cell_size%dat_width)?1:0); initial begin exp_dat = 0; dat = 0; end initial begin #10; for (exp_dat = 0; exp_dat != 4'hf; exp_dat = exp_dat + 1) begin dat <= exp_dat; #1 if (dat !== exp_dat) begin $display("ERROR: dat = %h, exp_dat = %h", dat, exp_dat); end else begin $display("OKAY: dat = %h, exp_dat = %h", dat, exp_dat); end end end endmodule iverilog-12_0/ivtest/ivltests/param_test2.v000066400000000000000000000041171435245347300211550ustar00rootroot00000000000000/* * Copyright (c) 2001 Brendan J Simon * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ //**************************************************************************** // // MODULE : parameter_test // // DESCRIPTION : Test module to demonstrate parameter evaluation bug. // // AUTHOR : Brendan J Simon (brendan.simon@bigpond.com) // // DATE : Monday 5th January 2001. // // NOTES : It seems that Icarus Verilog 0.4 does not evaluate // moderately complex parameter statements properly. // //**************************************************************************** module parameter_test; parameter foo_size = 32 * 6; parameter foo_lsb = 0; `ifdef GOOD_CODE parameter foo_msb_temp = foo_lsb + foo_size; parameter foo_msb = foo_msb_temp - 1; `else parameter foo_msb = foo_lsb + foo_size - 1; `endif // These complex statements work; parameter temp0 = 1 + 2 + 3 + 4 + 5; parameter temp1 = 1 + 2 + 3 + 4 + 5 - 1; reg [foo_msb:foo_lsb] foo; integer i; initial begin for (i=0; i * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module m(a); input a; endmodule module n; wire a; m #(1,2,3) am(a); initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/param_test4.v000066400000000000000000000003241435245347300211530ustar00rootroot00000000000000module test; parameter parm1 = 0; parameter parm2 = parm1 == 0; initial begin // if got here then we compiled if (parm2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/param_times.v000066400000000000000000000025101435245347300212300ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test is inspired by (and tests) PR#12. The interesting aspect of * this is the multiply in the parameter passed to module foo instance yak. */ `define ONE 1 `define TWO 2 module foo(in,out); parameter blah = 2; input in; output out; initial begin if (blah != 4) begin $display("FAILED -- parameter override of blah failed: %d", blah); $finish; end $display("PASSED"); end endmodule module bar; foo #(`ONE * 2 + `TWO) yak (,); endmodule iverilog-12_0/ivtest/ivltests/param_vec.v000066400000000000000000000003371435245347300206710ustar00rootroot00000000000000module test; parameter [39:0] foo = 5; initial begin if ($bits(foo) != 40) begin $display("FAILED -- $bits(foo) == %d", $bits(foo)); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/param_vec2.v000066400000000000000000000023241435245347300207510ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Based on PR#557. */ module test (); parameter s_ack = 3; parameter [s_ack-1:0] Ack_Wait = 2'b 00, Ack_Rdy = 2'b 11, Ack_Err = 2'b 10; initial begin if ($bits(Ack_Wait) != 3) begin $display("FAILED -- $bits(Ack_Wait) == %0d (should be 3)", $bits(Ack_Wait)); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/parameter_1bit.v000066400000000000000000000010171435245347300216270ustar00rootroot00000000000000// Check that parameters with a implicit and 1-bit range type are handled correctly module test #( // This should get truncated to 1'b1 parameter [0:0] P = 2'b11 ); reg failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: `%s`, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check($bits(P), 1); `check(P + 1'b1, 1'b0); `check(P, 1'b1); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/parameter_in_generate1.v000066400000000000000000000010011435245347300233220ustar00rootroot00000000000000// Check whether it is possible to declare a parameter in a generate block // In Verilog this should fail, in SystemVerilog the parameter is elaborated as // localparam and the test should pass. module test; generate genvar i; for (i = 0; i < 2; i = i + 1) begin : loop parameter A = i; reg [A:0] r = A+1; end endgenerate initial begin if (loop[0].r == 1 && loop[1].r == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/parameter_in_generate2.v000066400000000000000000000004521435245347300233340ustar00rootroot00000000000000// Check that it is not possible to override parameters in generate blocks module test; generate genvar i; for (i = 0; i < 2; i = i + 1) begin : loop parameter A = i; reg [A:0] r = A+1; end endgenerate defparam loop[0].A = 10; defparam loop[1].A = 20; endmodule iverilog-12_0/ivtest/ivltests/parameter_no_default.v000066400000000000000000000005401435245347300231100ustar00rootroot00000000000000// SystemVerilog allows parameters without default values in the parameter port // list. Check that this is supported. The test should fail in Verilog mode. module a #( parameter A ); initial begin if (A == 1) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module test; a #(.A(1)) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_no_default_fail1.v000066400000000000000000000003641435245347300241700ustar00rootroot00000000000000// Check that not providing a value during module instantiation for a parameter // without a default value generates an error. module a #( parameter A ); initial begin $display("FAILED"); end endmodule module test; a i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_no_default_fail2.v000066400000000000000000000003401435245347300241630ustar00rootroot00000000000000// Check that parameters without default values outside the parameter port list // generate an error. module a; parameter A; initial begin $display("FAILED"); end endmodule module test; a #(.A(10)) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_no_default_toplvl.v000066400000000000000000000003731435245347300245140ustar00rootroot00000000000000// Check that modules with undefined parameters do not get picked as top-level // modules. module a #( parameter A ); initial $display("FAILED"); endmodule module b #( parameter B = 1 ); initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/parameter_omit1.v000066400000000000000000000005701435245347300220240ustar00rootroot00000000000000// Tests that it possible to omit the initial `parameter` keyword in a parameter // port list in SystemVerilog. In Verilog this is not allowed and should result // in an error. module a #(A = 1); initial begin if (A == 10) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module test; a #(.A(10)) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_omit2.v000066400000000000000000000006021435245347300220210ustar00rootroot00000000000000// Tests that it possible to omit the initial `parameter` keyword in a parameter // port list in SystemVerilog. In Verilog this is not allowed and should result // in an error. module a #(integer A = 1); initial begin if (A == 10) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module test; a #(.A(10.1)) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_omit3.v000066400000000000000000000007121435245347300220240ustar00rootroot00000000000000// Tests that it possible to omit the `parameter` keyword in a parameter port // list before changing the parameter type in SystemVerilog. In Verilog this is // not allowed and should result in an error. module a #(parameter real A = 1.0, integer B = 2); initial begin if (A == 10.1 && B == 20) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule module test; a #(.A(10.1), .B(20)) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_omit_invalid1.v000066400000000000000000000002651435245347300235330ustar00rootroot00000000000000// Check that implicit type in a parameter port list without `parameter` // generates an error. module test #([7:0] A = 1); initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/parameter_omit_invalid2.v000066400000000000000000000002661435245347300235350ustar00rootroot00000000000000// Check that implicit type in a parameter port list without `parameter` // generates an error. module test #(signed A = 1); initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/parameter_omit_invalid3.v000066400000000000000000000003561435245347300235360ustar00rootroot00000000000000// Check that declaring changing the parameter type to an implicit type without // the `parameter` keyword results in an error. module test #(parameter real A = 1.0, signed B = 2); initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid1.v000066400000000000000000000003631435245347300244010ustar00rootroot00000000000000// Check that trying to override a parameter that does not exist results in an // error module a #( parameter A = 1 ); initial begin $display("FAILED"); end endmodule module test; a #( .Z(10) // Error ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid2.v000066400000000000000000000004131435245347300243760ustar00rootroot00000000000000// Check that trying to override a parameter that does not exist results in an // error module a #( parameter A = 1 ); initial begin $display("FAILED"); end endmodule module test; a #( .A(10) ) i_a(); defparam i_a.Z = 10; // Error endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid3.v000066400000000000000000000003071435245347300244010ustar00rootroot00000000000000// Check that localparam can not be overridden module a; localparam A = 1; initial begin $display("FAILED"); end endmodule module test; a #( .A(10) // Error ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid4.v000066400000000000000000000003311435245347300243770ustar00rootroot00000000000000// Check that localparam can not be overridden by defparam module a; localparam A = 1; initial begin $display("FAILED"); end endmodule module test; a i_a(); defparam i_a.A = 10; // Error endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid5.v000066400000000000000000000005241435245347300244040ustar00rootroot00000000000000// Check that parameter declared in the module body can not be overridden if the // module has a parameter port list. module a #( parameter A = 1 ); // This behaves like a localparam parameter B = 1; initial begin $display("FAILED"); end endmodule module test; a #( .A(10), .B(20) // Error ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid6.v000066400000000000000000000005571435245347300244130ustar00rootroot00000000000000// Check that parameter declared in the module body can not be overridden by a // defparam if the module has a parameter port list. module a #(parameter A = 1); // This behaves like a localparam parameter B = 2; initial begin $display("FAILED"); end endmodule module test; a i_a(); defparam i_a.A = 10; defparam i_a.B = 20; // Error endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid7.v000066400000000000000000000003531435245347300244060ustar00rootroot00000000000000// Check that localparam declared in parameter port list can not be overridden module a #( localparam B = 2 ); initial begin $display("FAILED"); end endmodule module test; a #( .A(10) // Error ) i_a(); endmodule iverilog-12_0/ivtest/ivltests/parameter_override_invalid8.v000066400000000000000000000004001435245347300244000ustar00rootroot00000000000000// Check that localparam declared in parameter port list can not be overridden // by defparam module a #( localparam A = 1 ); initial begin $display("FAILED"); end endmodule module test; a i_a(); defparam i_a.A = 10; // Error endmodule iverilog-12_0/ivtest/ivltests/parameter_scalar.v000066400000000000000000000007731435245347300222450ustar00rootroot00000000000000// Check that parameters with a scalar type are handled correctly module test #( // This should get truncated to 1'b1 parameter bit P = 2'b11 ); bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: `%s`, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check($bits(P), 1); `check(P + 1'b1, 1'b0); `check(P, 1'b1); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/parameter_type.v000066400000000000000000000011261435245347300217520ustar00rootroot00000000000000module top; parameter irparam = -1.0; parameter iiparam = -1; parameter [7:0] uparam = -1.0; parameter signed [7:0] sparam = -1.0; parameter real rparam = -1; parameter realtime rtparam = -1; parameter integer iparam = -1.0; parameter time tparam = -1.0; initial begin $display("Implicit real: ", irparam); $display("Implicit integer: ", iiparam); $display("Unsigned: ", uparam); $display("Signed: ", sparam); $display("Real: ", rparam); $display("Real time: ", rtparam); $display("Integer: ", iparam); $display("Time: ", tparam); end endmodule iverilog-12_0/ivtest/ivltests/parameter_type2.v000066400000000000000000000143361435245347300220430ustar00rootroot00000000000000module test(); parameter signed snv1 = 4'd1; parameter signed [2:0] s3v1 = 4'd1; parameter signed [3:0] s4v1 = 4'd1; parameter signed [4:0] s5v1 = 4'd1; parameter signed snv15 = 4'd15; parameter signed [2:0] s3v15 = 4'd15; parameter signed [3:0] s4v15 = 4'd15; parameter signed [4:0] s5v15 = 4'd15; parameter signed snvm1 = -4'sd1; parameter signed [2:0] s3vm1 = -4'sd1; parameter signed [3:0] s4vm1 = -4'sd1; parameter signed [4:0] s5vm1 = -4'sd1; parameter signed snrm1 = -1.0; parameter signed [2:0] s3rm1 = -1.0; parameter signed [3:0] s4rm1 = -1.0; parameter signed [4:0] s5rm1 = -1.0; parameter nnv1 = 4'd1; parameter [2:0] u3v1 = 4'd1; parameter [3:0] u4v1 = 4'd1; parameter [4:0] u5v1 = 4'd1; parameter nnv15 = 4'd15; parameter [2:0] u3v15 = 4'd15; parameter [3:0] u4v15 = 4'd15; parameter [4:0] u5v15 = 4'd15; parameter nnvm1 = -4'sd1; parameter [2:0] u3vm1 = -4'sd1; parameter [3:0] u4vm1 = -4'sd1; parameter [4:0] u5vm1 = -4'sd1; parameter nnrm1 = -1.0; parameter [2:0] u3rm1 = -1.0; parameter [3:0] u4rm1 = -1.0; parameter [4:0] u5rm1 = -1.0; reg fail = 0; reg match; initial begin match = ($bits(snv1) == 4) && (snv1 === 1); $display("snv1 : %2d (%0d`b%b) %c", snv1, $bits(snv1), snv1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3v1) == 3) && (s3v1 === 1); $display("s3v1 : %2d (%0d`b%b) %c", s3v1 , $bits(s3v1), s3v1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4v1) == 4) && (s4v1 === 1); $display("s4v1 : %2d (%0d`b%b) %c", s4v1 , $bits(s4v1), s4v1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5v1) == 5) && (s5v1 === 1); $display("s5v1 : %2d (%0d`b%b) %c", s5v1 , $bits(s5v1), s5v1, match ? " " : "*"); fail = fail || !match; match = ($bits(snv15) == 4) && (snv15 === -1); $display("snv15 : %2d (%0d`b%b) %c", snv15, $bits(snv15), snv15, match ? " " : "*"); fail = fail || !match; match = ($bits(s3v15) == 3) && (s3v15 === -1); $display("s3v15 : %2d (%0d`b%b) %c", s3v15, $bits(s3v15), s3v15, match ? " " : "*"); fail = fail || !match; match = ($bits(s4v15) == 4) && (s4v15 === -1); $display("s4v15 : %2d (%0d`b%b) %c", s4v15, $bits(s4v15), s4v15, match ? " " : "*"); fail = fail || !match; match = ($bits(s5v15) == 5) && (s5v15 === 15); $display("s5v15 : %2d (%0d`b%b) %c", s5v15, $bits(s5v15), s5v15, match ? " " : "*"); fail = fail || !match; match = ($bits(snvm1) == 4) && (snvm1 === -1); $display("snvm1 : %2d (%0d`b%b) %c", snvm1, $bits(snvm1), snvm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3vm1) == 3) && (s3vm1 === -1); $display("s3vm1 : %2d (%0d`b%b) %c", s3vm1, $bits(s3vm1), s3vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4vm1) == 4) && (s4vm1 === -1); $display("s4vm1 : %2d (%0d`b%b) %c", s4vm1, $bits(s4vm1), s4vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5vm1) == 5) && (s5vm1 === -1); $display("s5vm1 : %2d (%0d`b%b) %c", s5vm1, $bits(s5vm1), s5vm1, match ? " " : "*"); fail = fail || !match; match = (snrm1 == -1); $display("snrm1 : %4.1f %c", snrm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s3rm1) == 3) && (s3rm1 === -1); $display("s3rm1 : %2d (%0d`b%b) %c", s3rm1, $bits(s3rm1), s3rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s4rm1) == 4) && (s4rm1 === -1); $display("s4rm1 : %2d (%0d`b%b) %c", s4rm1, $bits(s4rm1), s4rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(s5rm1) == 5) && (s5rm1 === -1); $display("s5rm1 : %2d (%0d`b%b) %c", s5rm1, $bits(s5rm1), s5rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(nnv1) == 4) && (nnv1 === 1); $display("nnv1 : %2d (%0d`b%b) %c", nnv1, $bits(nnv1), nnv1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3v1) == 3) && (u3v1 === 1); $display("u3v1 : %2d (%0d`b%b) %c", u3v1 , $bits(u3v1), u3v1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4v1) == 4) && (u4v1 === 1); $display("u4v1 : %2d (%0d`b%b) %c", u4v1 , $bits(u4v1), u4v1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5v1) == 5) && (u5v1 === 1); $display("u5v1 : %2d (%0d`b%b) %c", u5v1 , $bits(u5v1), u5v1, match ? " " : "*"); fail = fail || !match; match = ($bits(nnv15) == 4) && (nnv15 === 15); $display("nnv15 : %2d (%0d`b%b) %c", nnv15, $bits(nnv15), nnv15, match ? " " : "*"); fail = fail || !match; match = ($bits(u3v15) == 3) && (u3v15 === 7); $display("u3v15 : %2d (%0d`b%b) %c", u3v15, $bits(u3v15), u3v15, match ? " " : "*"); fail = fail || !match; match = ($bits(u4v15) == 4) && (u4v15 === 15); $display("u4v15 : %2d (%0d`b%b) %c", u4v15, $bits(u4v15), u4v15, match ? " " : "*"); fail = fail || !match; match = ($bits(u5v15) == 5) && (u5v15 === 15); $display("u5v15 : %2d (%0d`b%b) %c", u5v15, $bits(u5v15), u5v15, match ? " " : "*"); fail = fail || !match; match = ($bits(nnvm1) == 4) && (nnvm1 === -1); $display("nnvm1 : %2d (%0d`b%b) %c", nnvm1, $bits(nnvm1), nnvm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3vm1) == 3) && (u3vm1 === 7); $display("u3vm1 : %2d (%0d`b%b) %c", u3vm1, $bits(u3vm1), u3vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4vm1) == 4) && (u4vm1 === 15); $display("u4vm1 : %2d (%0d`b%b) %c", u4vm1, $bits(u4vm1), u4vm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5vm1) == 5) && (u5vm1 === 31); $display("u5vm1 : %2d (%0d`b%b) %c", u5vm1, $bits(u5vm1), u5vm1, match ? " " : "*"); fail = fail || !match; match = (nnrm1 == -1.0); $display("nnrm1 : %4.1f %c", nnrm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u3rm1) == 3) && (u3rm1 === 7); $display("u3rm1 : %2d (%0d`b%b) %c", u3rm1, $bits(u3rm1), u3rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u4rm1) == 4) && (u4rm1 === 15); $display("u4rm1 : %2d (%0d`b%b) %c", u4rm1, $bits(u4rm1), u4rm1, match ? " " : "*"); fail = fail || !match; match = ($bits(u5rm1) == 5) && (u5rm1 === 31); $display("u5rm1 : %2d (%0d`b%b) %c", u5rm1, $bits(u5rm1), u5rm1, match ? " " : "*"); fail = fail || !match; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/parpkg_test.v000066400000000000000000000012241435245347300212530ustar00rootroot00000000000000// This tests SystemVerilog packages // // This tests the elaboration infrastructure of packages in // SystemVerilog. It actually covers a fair number of features, // given the small size of the program: // // *) Parsing of package blocks and import statements // *) Manage scope of names in package // *) Actual references of imported names from packages. // package pkg; parameter int foo = 1; endpackage module test (); // import all from p1 import pkg::*; initial begin $display("pkg::foo = %0d", foo); if (foo != 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/parpkg_test2.v000066400000000000000000000012261435245347300213370ustar00rootroot00000000000000// This tests SystemVerilog packages // // This tests the elaboration infrastructure of packages in // SystemVerilog. It actually covers a fair number of features, // given the small size of the program: // // *) Parsing of package blocks and import statements // *) Manage scope of names in package // *) Actual references of imported names from packages. // package pkg; parameter int foo = 1; endpackage module test (); // import all from p1 import pkg::foo; initial begin $display("pkg::foo = %0d", foo); if (foo != 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/parpkg_test3.v000066400000000000000000000012421435245347300213360ustar00rootroot00000000000000// This tests SystemVerilog packages // // This tests the elaboration infrastructure of packages in // SystemVerilog. It actually covers a fair number of features, // given the small size of the program: // // *) Parsing of package blocks and import statements // *) Manage scope of names in package // *) Actual references of imported names from packages. // package pkg; parameter int foo = 1; endpackage module test (); // import all from p1 //import pkg::foo; initial begin $display("pkg::foo = %0d", pkg::foo); if (pkg::foo != 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/part_sel_port.v000066400000000000000000000024741435245347300216150ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test part selection in multidimensional packed ports assignment. module mod_test(output wire logic[1:8][7:0] out); assign out = "testTEST"; endmodule module mod_test2(output wire logic[1:8][7:0] out); assign out = "abcdefgh"; endmodule module mod_main; logic[1:16][7:0] test_string; mod_test dut(test_string[1:8]); mod_test2 dut2(test_string[9:16]); initial begin if(test_string !== "testTESTabcdefgh") begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/partselsynth.v000066400000000000000000000024051435245347300214720ustar00rootroot00000000000000module main; reg enable, bar_a, bar_b, val_in; reg [7:0] scon; reg val; //(* ivl_synthesis_on *) always @(val_in or bar_a or bar_b or scon[7:6] or enable) begin if (scon[7:6]==2'b10) begin val = 1'b1; end else if (enable) begin val = val_in; end else begin val = !bar_b & bar_a; end end (* ivl_synthesis_off *) initial begin val_in = 0; enable = 0; bar_b = 0; bar_a = 0; scon = 8'b10_000000; #1 if (val !== 1'b1) begin $display("FAILED -- scon=%b, val=%b", scon, val); $finish; end scon = 0; enable = 1; #1 if (val !== 1'b0) begin $display("FAILED -- scon=%b, enable=%b, val=%b", scon, enable, val); $finish; end val_in = 1; #1 if (val !== 1'b1) begin $display("FAILED -- scon=%b, enable=%b, val_in=%b, val=%b", scon, enable, val_in, val); $finish; end enable = 0; #1 if (val !== 1'b0) begin $display("FAILED -- scon=%b, enable=%b, val=%b", scon, enable, val); $finish; end bar_a = 1; #1 if (val !== 1'b1) begin $display("FAILED -- scon=%b, enable=%b, bar_a==%b, bar_b=%b, val=%b", scon, enable, bar_a, bar_b, val); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/patch1268.v000066400000000000000000000007361435245347300203570ustar00rootroot00000000000000// This is a regression test for the bug fixed in patch tracker #1268. module test(); reg [19:0] a[15:0]; reg [3:0] idx[3:1]; initial begin idx[1] = 2; idx[2] = 3; idx[3] = 4; a[idx[1]][idx[2]*4 +: 4] <= #(idx[3]) 4'ha; #4; $display("%h", a[2]); if (a[2] !== 20'hxxxxx) begin $display("FAILED"); $finish; end #1; $display("%h", a[2]); if (a[2] !== 20'hxaxxx) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pca1.v000066400000000000000000000031111435245347300175510ustar00rootroot00000000000000// Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: First test for Procedural continuous assignment module test; // // Define a procedural assignment based mux. // reg [1:0] sel; reg [1:0] out, a,b,c,d; reg error; always @ (sel) case (sel) 2'b00: assign out = a; 2'b01: assign out = b; 2'b10: assign out = c; 2'b11: assign out = d; endcase initial begin error = 0; #1 ; sel = 0; a = 0; #1; if(out !== 2'b00) begin $display("FAILED - Procedural assignment out != 0 (1)"); error =1; end #1; a = 1; #1; if(out !== 2'b01) begin $display("FAILED - Procedural assignment out != 1 (2)"); error =1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/plus_5.v000066400000000000000000000027231435245347300201440ustar00rootroot00000000000000/* * Verification test for increment/decrement operators * * Author: Prasad Joshi */ module main; logic la; logic lb; int ia; int ib; bit ba; bit bb; real ra; real rb; real rc; initial begin /* logic tests */ la = 0; #1 lb = ++la; #1 if (la != lb) begin $display("FAILED"); $finish; end ib = 15; #1 ia = ++ib; #1 if (ia != ib) begin $display("FAILED"); $finish; end ia = 15; #1 ib = ia++; #1 if (ia != 16 || ib != 15) begin $display("FAILED"); $finish; end ib = --ia; if (ib != ia) begin $display("FAILED"); $finish; end /* bit test */ ba = 0; #1 for (ia = 0; ia < 10; ia = ia + 1) begin bb = --ba; #1 if (bb != ba && !(bb == 1 || bb == 0)) begin $display("FAILED"); $finish; end end /* real decrement test */ ia = 15; ra = --ia; if (ra != ia) begin $display("FAILED"); $finish; end rb = 19.99; rc = rb - 2; ra = --rb; if (ra != rb) begin $display("FAILED"); $finish; end ra = rb--; if (ra == rb || rc != rb) begin $display("FAILED"); $finish; end /* real increment test */ ia = 15; ra = ++ia; if (ra != ia) begin $display("FAILED"); $finish; end rb = 19.99; rc = rb + 2; ra = ++rb; if (ra != rb) begin $display("FAILED"); $finish; end ra = rb++; if (ra == rb || rc != rb) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/plus_arg_string.v000066400000000000000000000005121435245347300221310ustar00rootroot00000000000000module main; string img; initial begin if (!$value$plusargs("img=%s", img)) begin $display("Specify image file with +img=."); $finish_and_return(1); end $display("Using image: %s", img); if (img != "test_image.file") $display("FAILED"); else $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/port-test2.v000066400000000000000000000026131435245347300207560ustar00rootroot00000000000000// This is a compile time test, // for various port declaration syntax options `define TEST3 // `define TEST3_X // unconnected ports `ifdef TEST3 module port_3 ( dummy_1, /* unconnected */, in[7:0], dummy_2, out[7:0], /* unconnected */ ); input [7:0] in; output [7:0] out; output dummy_1; output dummy_2; assign out = in; endmodule `endif // ifdef TEST_3 module port_test; reg [7:0] data; `ifdef TEST3 wire [7:0] out_3; reg pass_3; initial pass_3 = 1; port_3 dut_3 (, // unconnected dummy_1 `ifdef TEST3_X // This fails in verilog-XL with: // Error! Expression given for a null module port [Verilog-EXPNMP] // "port-test.v", 115: dut_3(, pass_3, data[7:0], , // out_3[7:0], ) pass_3, // dummy unconnected `else , // unconnected unconnected `endif data[7:0], , // unconnected dummy_2 out_3[7:0], // unconnected unconnected ); `endif initial begin data <= 1; #1; while (data != 0) begin $display ("%b", data); `ifdef TEST3 if (out_3 != data) begin $display("data=%b, out_2=%b, FAILED", data, out_3); pass_3 = 0; end `endif data <= data << 1; #1; end `ifdef TEST3 if (pass_3) $display("PASSED"); `endif $finish; end endmodule // port_test iverilog-12_0/ivtest/ivltests/port-test3.v000066400000000000000000000021641435245347300207600ustar00rootroot00000000000000/*********************************************************************** Incorrect direction non-detection test case Copyright (C) 2001 Eric LaForest, ecl@pet.dhs.org Licenced under GPL ***********************************************************************/ module CPU (data, address, rw, clock, reset); inout [15:0] data; output [15:0] address; // This should be an output really.... input rw; input clock, reset; reg [15:0] data, address; // XXX error on data reg rw; // error on rw // I presume these should not be allowed to occur.... always @(posedge clock) begin rw <= 1'b1; end always @(negedge clock) begin rw <= 1'b0; end endmodule module BENCH (); reg [15:0] address, data; reg rw, clock, reset; CPU fm (address, data, rw, clock, reset); initial begin clock <= 0; reset <= 1; #1000; $finish; end always begin # 10 clock <= ~clock; end endmodule iverilog-12_0/ivtest/ivltests/port-test4a.v000066400000000000000000000005721435245347300211230ustar00rootroot00000000000000/*********************************************************************** Duplicate input declaration test case Duplicate port declarations should generate an error ***********************************************************************/ module port_test4 ( a, // Input b, // Output ); input a; input a; output b; assign b=a; endmodule iverilog-12_0/ivtest/ivltests/port-test4b.v000066400000000000000000000005741435245347300211260ustar00rootroot00000000000000/*********************************************************************** Duplicate output declaration test case Duplicate port declarations should generate an error ***********************************************************************/ module port_test4 ( a, // Input b, // Output ); input a; output b; output b; assign b=a; endmodule iverilog-12_0/ivtest/ivltests/port-test5.v000066400000000000000000000030361435245347300207610ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg a, b; wire res; has_ports test(res, a, b); initial begin a = 0; b = 0; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a & b)) begin $display("FAILED"); $finish; end a = 1; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a & b)) begin $display("FAILED"); $finish; end b = 1; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a & b)) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main module has_ports (output reg o, input wire a, input wire b); always @* o <= a & b; endmodule // has_ports iverilog-12_0/ivtest/ivltests/port-test6.v000066400000000000000000000031061435245347300207600ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [7:0] a, b; wire [8:0] res; has_ports test(res, a, b); initial begin a = 0; b = 0; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a + b)) begin $display("FAILED"); $finish; end a = 10; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a + b)) begin $display("FAILED"); $finish; end b = 11; #1 $display("has_ports (%b, %b, %b)", res, a, b); if (res !== (a + b)) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main module has_ports (output reg [8:0] o, input wire [7:0] a, input wire [7:0] b); always @* o <= a + b; endmodule // has_ports iverilog-12_0/ivtest/ivltests/port-test7.v000066400000000000000000000014151435245347300207620ustar00rootroot00000000000000`define REG_DELAY 1 module ansireg(input clk, reset, input [7:0] d, output reg [7:0] q ); always @(posedge clk or posedge reset) if(reset) q <= #(`REG_DELAY) 8'h00; else q <= #(`REG_DELAY) d; endmodule module main; reg clk, reset; reg [7:0] d; wire [7:0] q; ansireg U(clk, reset, d, q); initial begin clk = 0; reset = 0; d = 'hff; #(2*`REG_DELAY) clk <= 1; #(2*`REG_DELAY) if (q !== d) begin $display("FAILED -- clk=%b, reset=%b, d=%b, q=%b", clk, reset, d, q); $finish; end reset <= 1; #(1 + `REG_DELAY) if (q !== 8'h00) begin $display("FAILED -- clk=%b, reset=%b, d=%b, q=%b", clk, reset, d, q); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/posedge.v000066400000000000000000000024761435245347300203700ustar00rootroot00000000000000// // Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // single bit positive events // module main (); reg flag1; reg event_1; always @ (posedge event_1) flag1 = ~flag1; initial begin event_1 = 1'b0; #1 flag1 = 0; #1 event_1 = 1'b1; #1 if (flag1 !== 1'b1) begin $display("FAILED -- 0->1 didn't trigger flag1"); $finish; end event_1 = 1'b0; #1 if (flag1 !== 1'b1) begin $display("FAILED -- 1->0 DID trigger flag1"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pow-ca.v000066400000000000000000000060751435245347300201270ustar00rootroot00000000000000module top; reg signed [7:0] neg = -2; reg signed [7:0] m1 = -1; reg signed [7:0] zero = 0; reg signed [7:0] one = 1; reg signed [7:0] pos = 2; reg signed [7:0] pose = 2; reg signed [7:0] poso = 3; reg signed [7:0] res; wire signed [7:0] neg_pose = neg**pose; wire signed [7:0] neg_poso = neg**poso; wire signed [7:0] m1_pose = m1**pose; wire signed [7:0] m1_poso = m1**poso; wire signed [7:0] zero_pos = zero**pos; wire signed [7:0] one_pos = one**pos; wire signed [7:0] pos_pos = pos**pos; wire signed [7:0] neg_zero = neg**zero; wire signed [7:0] m1_zero = m1**zero; wire signed [7:0] zero_zero = zero**zero; wire signed [7:0] one_zero = one**zero; wire signed [7:0] pos_zero = pos**zero; wire signed [7:0] neg_neg = neg**m1; wire signed [7:0] m1_nege = m1**neg; wire signed [7:0] m1_nego = m1**m1; wire signed [7:0] zero_neg = zero**m1; wire signed [7:0] one_neg = one**m1; wire signed [7:0] pos_neg = pos**m1; reg pass; initial begin pass = 1'b1; #1; /* Positive exponent. */ if (neg_pose !== 4) begin $display("Failed neg**pos even, got %d", neg_pose); pass = 1'b0; end if (neg_poso !== -8) begin $display("Failed neg**pos odd, got %d", neg_poso); pass = 1'b0; end if (m1_pose !== 1) begin $display("Failed -1**pos even, got %d", m1_pose); pass = 1'b0; end if (m1_poso !== -1) begin $display("Failed -1**pos odd, got %d", m1_poso); pass = 1'b0; end if (zero_pos !== 0) begin $display("Failed 0**pos, got %d", zero_pos); pass = 1'b0; end if (one_pos !== 1) begin $display("Failed 1**pos, got %d", one_pos); pass = 1'b0; end if (pos_pos !== 4) begin $display("Failed 1**pos, got %d", pos_pos); pass = 1'b0; end /* Zero exponent. */ if (neg_zero !== 1) begin $display("Failed neg**0, got %d", neg_zero); pass = 1'b0; end if (m1_zero !== 1) begin $display("Failed -1**0, got %d", m1_zero); pass = 1'b0; end if (zero_zero !== 1) begin $display("Failed 0**0, got %d", zero_zero); pass = 1'b0; end if (one_zero !== 1) begin $display("Failed 1**0, got %d", one_zero); pass = 1'b0; end if (pos_zero !== 1) begin $display("Failed pos**0, got %d", pos_zero); pass = 1'b0; end /* Negative exponent. */ if (neg_neg !== 0) begin $display("Failed neg**neg got %d", neg_neg); pass = 1'b0; end if (m1_nege !== 1) begin $display("Failed -1**neg (even) got %d", m1_nege); pass = 1'b0; end if (m1_nego !== -1) begin $display("Failed -1**neg (odd) got %d", m1_nego); pass = 1'b0; end if (zero_neg !== 'sbx) begin $display("Failed 0**neg (odd) got %d", zero_neg); pass = 1'b0; end if (one_neg !== 1) begin $display("Failed 1**neg got %d", one_neg); pass = 1'b0; end if (pos_neg !== 0) begin $display("Failed pos**neg got %d", pos_neg); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pow-const.v000066400000000000000000000052101435245347300206600ustar00rootroot00000000000000module top; parameter neg_pose = -2**2; parameter neg_poso = -2**3; parameter m1_pose = -1**2; parameter m1_poso = -1**3; parameter zero_pos = 0**2; parameter one_pos = 1**2; parameter pos_pos = 2**2; parameter neg_zero = -2**0; parameter m1_zero = -1**0; parameter zero_zero = 0**0; parameter one_zero = 1**0; parameter pos_zero = 2**0; parameter neg_neg = -2**-1; parameter m1_nege = -1**-2; parameter m1_nego = -1**-1; parameter zero_neg = 0**-1; parameter one_neg = 1**-1; parameter pos_neg = 2**-1; reg pass; initial begin pass = 1'b1; /* Positive exponent. */ if (neg_pose !== 4) begin $display("Failed neg**pos even, got %d", neg_pose); pass = 1'b0; end if (neg_poso !== -8) begin $display("Failed neg**pos odd, got %d", neg_poso); pass = 1'b0; end if (m1_pose !== 1) begin $display("Failed -1**pos even, got %d", m1_pose); pass = 1'b0; end if (m1_poso !== -1) begin $display("Failed -1**pos odd, got %d", m1_poso); pass = 1'b0; end if (zero_pos !== 0) begin $display("Failed 0**pos, got %d", zero_pos); pass = 1'b0; end if (one_pos !== 1) begin $display("Failed 1**pos, got %d", one_pos); pass = 1'b0; end if (pos_pos !== 4) begin $display("Failed 1**pos, got %d", pos_pos); pass = 1'b0; end /* Zero exponent. */ if (neg_zero !== 1) begin $display("Failed neg**0, got %d", neg_zero); pass = 1'b0; end if (m1_zero !== 1) begin $display("Failed -1**0, got %d", m1_zero); pass = 1'b0; end if (zero_zero !== 1) begin $display("Failed 0**0, got %d", zero_zero); pass = 1'b0; end if (one_zero !== 1) begin $display("Failed 1**0, got %d", one_zero); pass = 1'b0; end if (pos_zero !== 1) begin $display("Failed pos**0, got %d", pos_zero); pass = 1'b0; end /* Negative exponent. */ if (neg_neg !== 0) begin $display("Failed neg**neg got %d", neg_neg); pass = 1'b0; end if (m1_nege !== 1) begin $display("Failed -1**neg (even) got %d", m1_nege); pass = 1'b0; end if (m1_nego !== -1) begin $display("Failed -1**neg (odd) got %d", m1_nego); pass = 1'b0; end if (zero_neg !== 'sbx) begin $display("Failed 0**neg (odd) got %d", zero_neg); pass = 1'b0; end if (one_neg !== 1) begin $display("Failed 1**neg got %d", one_neg); pass = 1'b0; end if (pos_neg !== 0) begin $display("Failed pos**neg got %d", pos_neg); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pow-proc.v000066400000000000000000000050411435245347300204770ustar00rootroot00000000000000module top; reg pass; reg signed [7:0] neg = -2; reg signed [7:0] m1 = -1; reg signed [7:0] zero = 0; reg signed [7:0] one = 1; reg signed [7:0] pos = 2; reg signed [7:0] pose = 2; reg signed [7:0] poso = 3; reg signed [7:0] res; initial begin pass = 1'b1; #1; /* Positive exponent. */ res = neg**pose; if (res !== 4) begin $display("Failed neg**pos even, got %d", res); pass = 1'b0; end res = neg**poso; if (res !== -8) begin $display("Failed neg**pos odd, got %d", res); pass = 1'b0; end res = m1**pose; if (res !== 1) begin $display("Failed -1**pos even, got %d", res); pass = 1'b0; end res = m1**poso; if (res !== -1) begin $display("Failed -1**pos odd, got %d", res); pass = 1'b0; end res = zero**pos; if (res !== 0) begin $display("Failed 0**pos, got %d", res); pass = 1'b0; end res = one**pos; if (res !== 1) begin $display("Failed 1**pos, got %d", res); pass = 1'b0; end res = pos**pos; if (res !== 4) begin $display("Failed 1**pos, got %d", res); pass = 1'b0; end /* Zero exponent. */ res = neg**zero; if (res !== 1) begin $display("Failed neg**0, got %d", res); pass = 1'b0; end res = m1**zero; if (res !== 1) begin $display("Failed -1**0, got %d", res); pass = 1'b0; end res = zero**zero; if (res !== 1) begin $display("Failed 0**0, got %d", res); pass = 1'b0; end res = one**zero; if (res !== 1) begin $display("Failed 1**0, got %d", res); pass = 1'b0; end res = pos**zero; if (res !== 1) begin $display("Failed pos**0, got %d", res); pass = 1'b0; end /* Negative exponent. */ res = neg**m1; if (res !== 0) begin $display("Failed neg**neg got %d", res); pass = 1'b0; end res = m1**neg; if (res !== 1) begin $display("Failed -1**neg (even) got %d", res); pass = 1'b0; end res = m1**m1; if (res !== -1) begin $display("Failed -1**neg (odd) got %d", res); pass = 1'b0; end res = zero**m1; if (res !== 'sbx) begin $display("Failed 0**neg got %d", res); pass = 1'b0; end res = one**m1; if (res !== 1) begin $display("Failed 1**neg got %d", res); pass = 1'b0; end res = pos**m1; if (res !== 0) begin $display("Failed pos**neg got %d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pow_ca_signed.v000066400000000000000000000014311435245347300215310ustar00rootroot00000000000000`begin_keywords "1364-2005" module test(); reg signed [15:0] a; reg signed [7:0] b; reg signed [31:0] expect; wire signed [31:0] actual; reg signed [127:0] long_x; real real_x; assign actual = a ** b; initial begin for (a = -32768; a < 32767; a = a + 1) begin:outer_loop long_x = 1; for (b = 0; b < 127; b = b + 1) begin:inner_loop real_x = $itor(a) ** $itor(b); if (real_x < 0.0) real_x = -real_x; if (real_x >= 2.0**128.0) disable outer_loop; expect = long_x; #0; // wait for net propagation if (actual !== expect) begin $display("FAILED : %0d ** %0d = %0d not %0d", a, b, expect, actual); $finish; end long_x = long_x * a; end end $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pow_ca_unsigned.v000066400000000000000000000013001435245347300220670ustar00rootroot00000000000000`begin_keywords "1364-2005" module test(); reg [15:0] a; reg [7:0] b; reg [31:0] expect; wire [31:0] actual; reg [127:0] long_x; real real_x; assign actual = a ** b; initial begin for (a = 0; a < 65535; a = a + 1) begin:outer_loop long_x = 1; for (b = 0; b < 127; b = b + 1) begin:inner_loop real_x = $itor(a) ** $itor(b); if (real_x >= 2.0**128.0) disable outer_loop; expect = long_x; #0; // wait for net propagation if (actual !== expect) begin $display("FAILED : %0d ** %0d = %0d not %0d", a, b, expect, actual); $finish; end long_x = long_x * a; end end $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pow_reg_signed.v000066400000000000000000000013531435245347300217260ustar00rootroot00000000000000`begin_keywords "1364-2005" module test(); reg signed [15:0] a; reg signed [7:0] b; reg signed [31:0] expect; reg signed [31:0] actual; reg signed [127:0] long_x; real real_x; initial begin for (a = -32768; a < 32767; a = a + 1) begin:outer_loop long_x = 1; for (b = 0; b < 127; b = b + 1) begin:inner_loop real_x = $itor(a) ** $itor(b); if (real_x < 0.0) real_x = -real_x; if (real_x >= 2.0**128.0) disable outer_loop; expect = long_x; actual = a ** b; if (actual !== expect) begin $display("FAILED : %0d ** %0d = %0d not %0d", a, b, expect, actual); $finish; end long_x = long_x * a; end end $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pow_reg_unsigned.v000066400000000000000000000013001435245347300222610ustar00rootroot00000000000000`begin_keywords "1364-2005" module test(); reg [15:0] a; reg [7:0] b; reg [31:0] expect; reg [31:0] actual; reg [127:0] long_x; real real_x; initial begin for (a = 0; a < 65535; a = a + 1) begin:outer_loop long_x = 1; for (b = 0; b < 127; b = b + 1) begin:inner_loop real_x = $itor(a) ** $itor(b); if (real_x >= 2.0**128.0) disable outer_loop; expect = long_x; actual = a ** b; actual = a ** b; actual = a ** b; if (actual !== expect) begin $display("FAILED : %0d ** %0d = %0d not %0d", a, b, expect, actual); $finish; end long_x = long_x * a; end end $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pow_signed.v000066400000000000000000000016321435245347300210710ustar00rootroot00000000000000module top; reg pass; integer in1, in2, res; initial begin pass = 1'b1; in1 = 1; in2 = 2; res = in1 ** in2; if (res != 1) begin $display("Failed: 1 ** 2, expected 1, got %0d", res); pass = 1'b0; end in1 = 2; in2 = 3; res = in1 ** in2; if (res != 8) begin $display("Failed: 2 ** 3, expected 8, got %0d", res); pass = 1'b0; end in1 = -2; in2 = 2; res = in1 ** in2; if (res != 4) begin $display("Failed: -2 ** 2, expected 4, got %0d", res); pass = 1'b0; end in1 = -2; in2 = 3; res = in1 ** in2; if (res != -8) begin $display("Failed: -2 ** 3, expected -8, got %0d", res); pass = 1'b0; end in1 = 1; in2 = -1; res = in1 ** in2; if (res != 1) begin $display("Failed: 1 ** -1, expected 1, got %0d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pow_unsigned.v000066400000000000000000000017561435245347300214430ustar00rootroot00000000000000module top; reg passed = 1'b1; reg [199:0] r, a, b; initial begin a = 'd5; b = 'd2; // A simple test. r = a ** b; if (r != 'd25) begin $display("Failed: 5 ** 2 gave %d, expected 25", r); passed = 1'b0; end b = 'd55; // A 128 bit value. r = a ** b; if (r != 200'd277555756156289135105907917022705078125) begin $display("Failed: 5 ** 55\n gave %0d", r); $display(" expected 277555756156289135105907917022705078125"); passed = 1'b0; end b = 'd86; // A 200 bit value. r = a ** b; if (r != 200'd1292469707114105741986576081359316958696581423282623291015625) begin $display("Failed: 5 ** 55\n gave %0d", r); $display(" expected 1292469707114105741986576081359316958696581423282623291015625"); passed = 1'b0; end if (r != 'd5**'d86) begin $display("Failed: compile-time/run-time value mismatch."); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1000.v000066400000000000000000000007171435245347300176600ustar00rootroot00000000000000/* * Based on PR#1000. */ module foo20 (); /* This is reported to return the warning: warning: Ranges in localparam definition are not supported. The value is OK, and the compiler chooses a width that holds whatever value is there. */ localparam [65:0] foo = 0; initial begin if ($bits(foo) != 66) begin $display("FAILED -- $bits(foo) --> %0d", $bits(foo)); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1002.v000066400000000000000000000016571435245347300176660ustar00rootroot00000000000000module top ( ); reg signed [13:0] datain; wire signed [15:0] dataout; assign dataout = datain >>> 2; reg test_failed; initial begin test_failed = 0; #1 datain = 14'h0FFF; #1 datain = 14'h0000; #1 datain = 14'h1FFF; #1 datain = 14'h1000; #1 datain = 14'h2FFF; #1 datain = 14'h2000; #1 datain = 14'h3FFF; #1 datain = 14'h3000; #2; if (test_failed) $display("TEST FAILED :-("); else $display("TEST PASSED :-)"); end wire signed [15:0] expected_dataout; assign expected_dataout = ($signed({datain[13:2], 2'b0}) / 4) ; always @(dataout) if (expected_dataout != dataout) begin $display("datain = %d dataout = %h expected = %h ... CHECK FAILED", datain, dataout, expected_dataout); test_failed = 1; end else $display("datain = %d dataout = %d expected = %d ... CHECK PASSED", datain, dataout, expected_dataout); endmodule // top iverilog-12_0/ivtest/ivltests/pr1002a.v000066400000000000000000000016501435245347300200200ustar00rootroot00000000000000module top ( ); reg signed [13:0] datain; wire signed [15:0] dataout; assign dataout = datain <<< 2; reg test_failed; initial begin test_failed = 0; #1 datain = 14'h0FFF; #1 datain = 14'h0000; #1 datain = 14'h1FFF; #1 datain = 14'h1000; #1 datain = 14'h2FFF; #1 datain = 14'h2000; #1 datain = 14'h3FFF; #1 datain = 14'h3000; #2; if (test_failed) $display("TEST FAILED :-("); else $display("TEST PASSED :-)"); end wire signed [15:0] expected_dataout; assign expected_dataout = $signed({datain[13:0], 2'b0}); always @(dataout) if (expected_dataout != dataout) begin $display("datain = %d dataout = %d expected = %d ... CHECK FAILED", datain, dataout, expected_dataout); test_failed = 1; end else $display("datain = %d dataout = %d expected = %d ... CHECK PASSED", datain, dataout, expected_dataout); endmodule // top iverilog-12_0/ivtest/ivltests/pr1007.v000066400000000000000000000004571435245347300176700ustar00rootroot00000000000000`timescale 1 ps / 1 ps module main; initial begin #1; if ($realtime == 0) begin $display ("FAILED -- time == 0"); $finish; end if ($realtime != 1) begin $display ("FAILED -- time != 0"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1008.v000066400000000000000000000005401435245347300176620ustar00rootroot00000000000000/* * Based on PR#1008 */ `timescale 1 ps / 1 ps module star; reg a; reg b; initial begin $monitor("b = %b", b); #1; a = 1; #2; a = 0; #2; a = 1; end /* This generated the error: :0: internal error: NetProc::nex_output not implemented Before CVS 20040630 */ always @* begin b = #1 ~a; end endmodule // star iverilog-12_0/ivtest/ivltests/pr1022.v000066400000000000000000000005541435245347300176630ustar00rootroot00000000000000// based on PR#1022 module foo; wire [-1:0] fred; assign fred = 1; initial begin #1 if (fred[0] !== 1) begin $display("FAILED -- fred[0] = %b", fred[0]); $finish; end if (fred[-1] !== 0) begin $display("FAILED -- fred[-1] = %b", fred[-1]); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1024.v000066400000000000000000000002361435245347300176620ustar00rootroot00000000000000/* * Based on PR#1024 */ module test; initial begin wait(1) ; /* This is weird, but legal. */ $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/pr1026.v000066400000000000000000000005121435245347300176610ustar00rootroot00000000000000/* * This is based on PR#1026. */ module main; reg [4:0] index; reg [31:0] foo; initial begin for (index = 0 ; index < 31 ; index = index + 1) begin #1 $display("index=%d, foo=%b", index, foo); end $finish(0); end always @(*) begin foo = 32'b0; foo[index]=1'b1; end endmodule iverilog-12_0/ivtest/ivltests/pr1029.v000066400000000000000000000003371435245347300176710ustar00rootroot00000000000000/* * This is based on PR#1029 */ module main(); `define none `define fred eric `define bill main`none.eric reg [8*8:0] eric; initial begin eric = "PASSED"; $display("%0s",`bill); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/pr1032.v000066400000000000000000000020321435245347300176550ustar00rootroot00000000000000module test; reg d; wire bar; // Assign some value to bar with weak drive. assign (weak0, weak1) bar = d; // Whatever value is on bar, give that *strong* drive onto foo. // The strength of an assignment is its own, and does not come // from the strength contained in the r-value. tri0 foo = bar; initial begin d = 0; #1 if (d !== bar) begin $display("FAILED -- d=%b, bar=%b", d, bar); $finish; end if (d !== foo) begin $display("FAILED -- d=%b, foo=%b", d, foo); $finish; end d = 1; #1 if (d !== bar) begin $display("FAILED -- d=%b, bar=%b", d, bar); $finish; end if (d !== foo) begin $display("FAILED -- d=%b, foo=%b", d, foo); $finish; end d = 'bz; #1 if (d !== bar) begin $display("FAILED -- d=%b, bar=%b", d, bar); $finish; end if ('b0 !== foo) begin $display("FAILED -- d=%b, foo=%b", d, foo); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // test iverilog-12_0/ivtest/ivltests/pr1033.v000066400000000000000000000052511435245347300176640ustar00rootroot00000000000000/* * Test case showing the failure of the 'less than or equal' operator (note * that the 'greather than or equal' comparison also fails) on two signed * values. The 'foo' module defines inputs 'a' and 'b' as signed inputs, * then performs a LTE comparison of those two values in order to select the * smaller of the two as the result (via a mux). The generated output for * this test (via the display call) for icarus and a well known commercial * Verilog simulator are shown here. It is my belief that the commercial * simulator results reflect the correct behavior for a simulator. * Specifically, with signed numbers the value 32'h7fffffff represents the * maximum positive value while 32'h80000000 represents the minimum negative * value. Thus for Less Than or Equal comparison any negative value (ie * 32'h80000000) should evaluate to less than any positive value * (ie 32'h7fffffff). Note the difference in the last 4 comparisons between * the icarus results and the commercial results. The commercial results show * that the 32'h8000000? values are less than the 32'h7ffffff? values as is * expected. * * icarus commercial simulator * 7ffffff5 7ffffffa = 7ffffff5 # 7ffffff5 7ffffffa = 7ffffff5 * 7ffffff6 7ffffffb = 7ffffff6 # 7ffffff6 7ffffffb = 7ffffff6 * 7ffffff7 7ffffffc = 7ffffff7 # 7ffffff7 7ffffffc = 7ffffff7 * 7ffffff8 7ffffffd = 7ffffff8 # 7ffffff8 7ffffffd = 7ffffff8 * 7ffffff9 7ffffffe = 7ffffff9 # 7ffffff9 7ffffffe = 7ffffff9 * 7ffffffa 7fffffff = 7ffffffa # 7ffffffa 7fffffff = 7ffffffa * 7ffffffb 80000000 = 7ffffffb # 7ffffffb 80000000 = 80000000 * 7ffffffc 80000001 = 7ffffffc # 7ffffffc 80000001 = 80000001 * 7ffffffd 80000002 = 7ffffffd # 7ffffffd 80000002 = 80000002 * 7ffffffe 80000003 = 7ffffffe # 7ffffffe 80000003 = 80000003 * * iverilog -version: * Icarus Verilog version 0.7 ($Name: $) * * Compilation * iverilog -o iverilog.out * vvp iverilog.out */ module test (); reg clk; reg [31:0] a_dat; reg [31:0] b_dat; wire [31:0] result; initial begin clk <= 0; a_dat <= 32'h7fffFFF5; b_dat <= 32'h7fffFFFA; #500 $finish(0); end always #25 clk <= ~clk; always @(posedge clk) begin a_dat <= a_dat + 1; b_dat <= b_dat + 1; $display("%x %x = %x", a_dat, b_dat, result); end foo foo_test(.a(a_dat), .b(b_dat), .RESULT(result)); endmodule // test module foo(a, b, RESULT); input signed [31:0] a; input signed [31:0] b; output [31:0] RESULT; wire lessThanEqualTo; wire [31:0] mux; assign lessThanEqualTo=a<=b; assign mux=(lessThanEqualTo)?a:b; assign RESULT=mux; endmodule // foo iverilog-12_0/ivtest/ivltests/pr1065.v000066400000000000000000000012461435245347300176710ustar00rootroot00000000000000module test_file; reg [64:1] file_name; initial begin file_name = 64'h4242434442424344; end subtest1 subtest1(file_name); endmodule module subtest1(file_name); input [64:1] file_name; wire [64:1] file_name; integer outfile; initial #0 begin $display ("Execution started."); $display ("%s",file_name); // I don't know if the following line conforms to spec or not. outfile = $fopen({"work/",file_name}); $display ("Execution finished."); $fdisplay (outfile, "Recorded data in %s",file_name); $fclose (outfile); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1072.v000066400000000000000000000011001435245347300176540ustar00rootroot00000000000000/* * This test program catches the essence of PR#1072 */ module main; parameter WIDTH = 4; wire [19:0] foo = { 1<> 16; // PASS //assign foo[31:16] = bar >> 16; initial begin bar = 32'ha5a5_3f3f; #100; $display("foo[31:16] = %x bar = %x",foo[31:16],bar); //if(foo[31:16]==((bar & 32'hffffffff) >> 16)) if(foo[31:16] === 16'ha5a5) $display("PASS (%x)",foo[31:16]); else $display("FAIL (%x vs %x)",foo[31:16],((bar & 32'hffffffff) >> 16)); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1353345.v000066400000000000000000000021621435245347300201230ustar00rootroot00000000000000module main; parameter use_wid = 4; reg [use_wid-1:0] d; wire [use_wid-1:0] q; reg clk; B #(.wid(use_wid)) dut (.Q(q), .D(d), .C(clk)); initial begin clk = 0; d = 4'b0000; #1 clk = 1; #1 clk = 0; if (q !== 4'b0000) begin $display("FAILED -- d=%b, q=%b", d, q); $finish; end d = 4'b1111; #1 clk = 1; #1 clk = 0; if (q !== 4'b1111) begin $display("FAILED -- d=%b, q=%b", d, q); $finish; end $display("PASSED"); end endmodule // main /* * although the wid paramter is default to 3 in this module, the point * of this test is to have the instantiating module (main) give a * different value and have that value properly handlued in all the * situations of this module. */ module B #(parameter wid = 3) (output [wid-1:0] Q, input [wid-1:0] D, input C); // the override from main will cause this to be a width of 4. prim U [wid-1:0] (Q, D, C); //prim U [wid-1:0] (.Q(Q), .D(D), .C(C)); endmodule // B module prim(output reg Q, input D, C); always @(posedge C) Q <= D; endmodule // prim iverilog-12_0/ivtest/ivltests/pr1353345b.v000066400000000000000000000022061435245347300202640ustar00rootroot00000000000000module main; parameter use_wid = 4; reg [use_wid-1:0] d; wire [use_wid-1:0] q; reg clk; defparam dut.wid = use_wid; B dut (.Q(q), .D(d), .C(clk)); initial begin clk = 0; d = 4'b0000; #1 clk = 1; #1 clk = 0; if (q !== 4'b0000) begin $display("FAILED -- d=%b, q=%b", d, q); $finish; end d = 4'b1111; #1 clk = 1; #1 clk = 0; if (q !== 4'b1111) begin $display("FAILED -- d=%b, q=%b", d, q); $finish; end $display("PASSED"); end endmodule // main /* * although the wid paramter is default to 3 in this module, the point * of this test is to have the instantiating module (main) give a * different value and have that value properly handlued in all the * situations of this module. */ module B #(parameter wid = 3) (output [wid-1:0] Q, input [wid-1:0] D, input C); // the override from main will cause this to be a width of 4. prim U [wid-1:0] (Q, D, C); //prim U [wid-1:0] (.Q(Q), .D(D), .C(C)); endmodule // B module prim(output reg Q, input D, C); always @(posedge C) Q <= D; endmodule // prim iverilog-12_0/ivtest/ivltests/pr136.v000066400000000000000000000040611435245347300176050ustar00rootroot00000000000000//**************************************************************************** // // MODULE : parameter_multiply_test // // DESCRIPTION : Test module to demonstrate parameter multiplication bug. // // AUTHOR : Brendan J Simon (brendan.simon@bigpond.com) // // DATE : Tuesday 6th January 2001. // // NOTES : It seems that Icarus Verilog 0.4 does not evaluate // parameter multiplication properly. // The code compiles OK, but gives a runtime error of: // vpi_const.c:35: vpip_bits_to_dec_str: Assertion `nbits <= // 8*sizeof(val)' failed. // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: multiply in parameter //**************************************************************************** module parameter_multiply_test; parameter foo_size = 4 * 8; reg [31:0] testv; initial begin testv = foo_size; if(testv !== 32) begin $write("foo_size = %d\n", testv); $display("FAILED"); end else begin $write("foo_size = %d\n", testv); $display("PASSED"); end $finish; end endmodule //**************************************************************************** // EOF : parameter_multiply_test //**************************************************************************** iverilog-12_0/ivtest/ivltests/pr1367855.v000066400000000000000000000014351435245347300201400ustar00rootroot00000000000000// test.v program starts here // This program is based on iverilog report [ 1367855 ] vvp simulation error module test(); reg [3:0] S; mux m( .SEL(S) ); initial begin S=3; #100; S=2; #100; $display("PASSED"); $finish; end endmodule module mux(SEL); input [3:0] SEL; wire [3:0] SEL; integer offset; always @(SEL) begin offset = SEL[3] + SEL[0]*128 + SEL[2:1]*2; $display("MUX: SEL=%d offset=%b", SEL, offset); case (SEL) 'bxxxx: begin end 2: if (offset !== 'b00000000000000000000000000000010) begin $display("FAILED"); $finish; end 3: if (offset !== 'b00000000000000000000000010000010) begin $display("FAILED"); $finish; end default: begin $display("FAILED -- SEL=%b", SEL); $finish; end endcase end endmodule iverilog-12_0/ivtest/ivltests/pr1380261.v000066400000000000000000000014201435245347300201140ustar00rootroot00000000000000module bittest; reg signed [5:0] m; reg signed [7:0] n; reg signed [18:0] p; reg signed [8:0] s; reg b; reg signed c; reg d; always @(m, n, c) begin p <= m * n; // m and n are signed, so do signed multiply s <= m + b; // b is UNsigned, so do unsigned pad and add. d <= c == 1; // c and the literal 1 are signed, so do signed compare. end initial begin #10; m <= -25; n <= 29; b <= 1; c <= 1; #10; $display("p=%d s=%d d=%d", p, s, d); if (s !== 9'd40) begin $display("FAILED -- s='b%b", s); $finish; end if (p !== -19'd725) begin $display("FAILED == p='b%b", p); $finish; end if (d !== 0) begin $display("FAILED == d='b%b", d); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1388974.v000066400000000000000000000006621435245347300201460ustar00rootroot00000000000000module main; initial begin # 32 $display("PASSED"); $finish; end // This delay is 'h1_00000010. The idea here is if the delay is // only treated as 32 bits anywhere in the processing, then the // high bits are truncated, and it becomes 16, which is less then // the 32 above and we fail. initial begin # 4294967312 $display("FAILED -- time=%d", $time); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/pr1403406-1.cf000066400000000000000000000000231435245347300203700ustar00rootroot00000000000000+timescale+1ns/1ns iverilog-12_0/ivtest/ivltests/pr1403406-2.cf000066400000000000000000000000241435245347300203720ustar00rootroot00000000000000+timescale+1ns/1ps+ iverilog-12_0/ivtest/ivltests/pr1403406.v000066400000000000000000000004511435245347300201140ustar00rootroot00000000000000// Use the default timescale. module top; initial begin $printtimescale(top); $printtimescale(other); $printtimescale(other2); end endmodule `timescale 1ms/1ms // Use the given timescale. module other; endmodule `resetall // Use the default timescale. module other2; endmodule iverilog-12_0/ivtest/ivltests/pr1403406a.v000066400000000000000000000004511435245347300202550ustar00rootroot00000000000000// Use the default timescale. module top; initial begin $printtimescale(top); $printtimescale(other); $printtimescale(other2); end endmodule `timescale 1ms/1ms // Use the given timescale. module other; endmodule `resetall // Use the default timescale. module other2; endmodule iverilog-12_0/ivtest/ivltests/pr1403406b.v000066400000000000000000000004511435245347300202560ustar00rootroot00000000000000// Use the default timescale. module top; initial begin $printtimescale(top); $printtimescale(other); $printtimescale(other2); end endmodule `timescale 1ms/1ms // Use the given timescale. module other; endmodule `resetall // Use the default timescale. module other2; endmodule iverilog-12_0/ivtest/ivltests/pr142.v000066400000000000000000000030351435245347300176020ustar00rootroot00000000000000// // Copyright (c) 2001 Ed Schwartz (schwartz@r11.ricoh.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Verify PR142 - Added something to print PASSED.. module testit; reg clk; reg [2:0] cnt; always begin # 50 clk = ~clk; end // always begin task idle; input [15:0] waitcnt; begin: idletask // begin integer i; for (i=0; i < waitcnt; i = i + 1) begin @ (posedge clk); end // for (i=0; i < waitcnt; i = i + 1) end endtask // idle initial begin clk = 0; cnt = 0; $display ("One"); cnt = cnt + 1; idle(3); cnt = cnt + 1; $display ("Two"); if(cnt === 2) $display("PASSED"); else $display("FAILED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1421777.v000066400000000000000000000011431435245347300201260ustar00rootroot00000000000000/* * This is the essence of tracker id#1421777. The problem is the error * message around the "... dut.tmp" expression. This probram won't * compile while the reported bug still lives. */ module main; reg b; wire a; // The a.tmp is valid, but tricky because it is an implicit wire. wire foo = dut.tmp; X dut(a, b); initial begin b = 0; #1 $display("a=%b, tmp=%b", a, foo); if (a !== foo) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main module X(output a, input b); not (tmp, b); buf(a, tmp); endmodule // X iverilog-12_0/ivtest/ivltests/pr1444055.v000066400000000000000000000027541435245347300201310ustar00rootroot00000000000000module bts ( z , a , e); inout z ; wire z ; input a ; wire a ; input e ; wire e ; assign #4 z= ( (e==1'b1)? a : 1'bz ); endmodule module test(); reg [1:0] aa; wire [1:0] zz; reg [1:0] ee; bts sub1 (.z(zz[1]), .a(aa[1]), .e(ee[1])); bts sub0 (.z(zz[0]), .a(aa[0]), .e(ee[0])); initial begin // $dumpvars; ee=2'b00; aa=2'b00; #100; if (zz !== 2'bzz) begin $display("FAILED -- (1) All disabled, expected HiZ, got %b", zz); $finish; end aa=2'b11; #100; if (zz !== 2'bzz) begin $display("FAILED -- (2) All disabled, expected HiZ, got %b", zz); $finish; end aa=2'b00; #100; if (zz !== 2'bzz) begin $display("FAILED -- (3) All disabled, expected HiZ, got %b", zz); $finish; end aa=2'b11; #100; if (zz !== 2'bzz) begin $display("FAILED -- (4) All disabled, expected HiZ, got %b", zz); $finish; end ee=2'b11; aa=2'b00; #100; if (zz !== 2'b00) begin $display("FAILED -- (5) All enabled, expected 00, got %b", zz); $finish; end aa=2'b11; #100; if (zz !== 2'b11) begin $display("FAILED -- (6) All enabled, expected 11, got %b", zz); $finish; end aa=2'b00; #100; if (zz !== 2'b00) begin $display("FAILED -- (7) All enabled, expected 00, got %b", zz); $finish; end aa=2'b11; #100; if (zz !== 2'b11) begin $display("FAILED -- (8) All enabled, expected 11, got %b", zz); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1449749a.v000066400000000000000000000014371435245347300203060ustar00rootroot00000000000000/* * This tests the handling of signed/types parameters. This is a test * of the complaints from pr 1449749. */ module main; parameter foo = -2; parameter integer bar = -3; parameter signed [5:0] bat = -7; initial begin $display("foo=%d, bar=%d, tmp=%d", foo, bar, bat); if (foo >= 0) begin $display("FAILED -- -2 > 0"); $finish; end if (foo != -2) begin $display("FAILED"); $finish; end if (bar >= 0) begin $display("FAILED -- -3 > 0"); $finish; end if (bar != -3) begin $display("FAILED"); $finish; end if (bat >= 0) begin $display("FAILED -- -7 > 0"); $finish; end if (bat != -7) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1455873.v000066400000000000000000000004151435245347300201330ustar00rootroot00000000000000module main; reg [6:0] bar; wire [31:0] foo = {{25{1'b0}}, bar}; initial begin bar = 7'b1111111; #1 if (foo !== 32'h00_00_00_7f) begin $display("FAILED -- foo=%h", foo); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1465769.v000066400000000000000000000003541435245347300201420ustar00rootroot00000000000000module bug; reg [31:0] a; integer i; initial begin i=4; a=0; a[i*4+:2] = 2'b11; $display("%h",a); if (a !== 32'h00030000) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1467825.v000066400000000000000000000004701435245347300201340ustar00rootroot00000000000000`celldefine `suppress_faults `enable_portfaults `timescale 1ns / 10ps `delay_mode_path module test (Z, A, B); output Z; input A; input B; xor (Z, A, B); specify ifnone (A +=> Z) = (1.0,1.0); endspecify endmodule `disable_portfaults `nosuppress_faults `endcelldefine iverilog-12_0/ivtest/ivltests/pr1474283.v000066400000000000000000000013141435245347300201260ustar00rootroot00000000000000module test; reg [2:0] tmp1; integer tmp2; real tmp3; initial begin t1(tmp1, 1); if (tmp1 !== 2) begin $display("FAILED -- tmp1=%b", tmp1); $finish; end t2(tmp2, 4); if (tmp2 !== 6) begin $display("FAILED == tmp2=%d", tmp2); $finish; end t3(tmp3, 0.5); if (tmp3 != 2.0) begin $display("FAILED -- tmp3=%f", tmp3); $finish; end $display("PASSED"); end task t1(output [2:0] o, input [2:0] i); begin o = i + 1; end endtask // tt task t2(output integer o, input integer i); o = i + 2; endtask // t2 task t3(output real o, input real i); o = i + 1.5; endtask // t3 endmodule iverilog-12_0/ivtest/ivltests/pr1474316.v000066400000000000000000000005461435245347300201310ustar00rootroot00000000000000module test; wire [3:0] a; reg [1:0] b; assign a[0+:2] = b; assign a[3-:2] = b; initial begin b = 2'b01; #1 if (a !== 4'b0101) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end b=2'b10; #1 if (a !== 4'b1010) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1474318.v000066400000000000000000000003751435245347300201330ustar00rootroot00000000000000module test; wire [5:0] a; reg [3:0] b; assign a[1:0] = {{2'b0},b}; initial begin b = 4'b0110; #1 if (a !== 6'bzzzz10) begin $display("FAILED -- a=%b", a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1476440.v000066400000000000000000000004501435245347300201230ustar00rootroot00000000000000`timescale 1ns/10ps module test(); reg ck; integer cnt; real tval; initial begin ck <= 0; cnt <= 0; tval <= 0.0; end always #2 ck <= !ck; always @(posedge ck) begin cnt <= cnt + 1; tval <= $realtime; $display ("tval = %g", tval); if (cnt >= 5) begin $finish(0); end end endmodule // test iverilog-12_0/ivtest/ivltests/pr1477190.v000066400000000000000000000013021435245347300201230ustar00rootroot00000000000000module main; reg b, a; initial begin b = 0; a = 1; #1 if (b !== 0) begin $display("FAILED -- b starts out as %b", b); $finish; end force b = a; #1 if (b !== 1) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end a = 0; #1 if (b !== 0) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end a = 1; #1 release b; #1 a = 0; #1 if (b !== 1) begin $display("FAILED -- b=%b didnot hold value after release", b); $finish; end b = 0; if (b !== 0) begin $display("FAILED -- assign failed b=%b", b); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1478121.v000066400000000000000000000014121435245347300201200ustar00rootroot00000000000000`begin_keywords "1364-2005" module main; wire [1:0] di; reg [1:0] do; reg dir; wire [1:0] q; sub dut(.Q({q[0],q[1]}), .Di(di), .Do(do), .dir(dir)); initial begin dir = 0; do = 2'b10; #1 if (q !== 2'bzz) begin $display("FAILED -- q=%b, dir=%b", q, dir); $finish; end dir = 1; #1 if (q !== 2'b01) begin $display("FAILED -- q=%b, dir=%b, do=%b", q, dir, do); $finish; end if (di !== 2'b10) begin $display("FAILED -- di=%b, dir=%b, do=%b", di, dir, do); $finish; end $display("PASSED"); end endmodule // main module sub(inout [1:0]Q, output[1:0]Di, input [1:0]Do, input dir); assign Di = Q; assign Q = dir? Do : 2'bzz; endmodule // sub `end_keywords iverilog-12_0/ivtest/ivltests/pr1478988.v000066400000000000000000000010631435245347300201470ustar00rootroot00000000000000module main; reg [23:20] foo; wire [3:0] test = {foo[22:20] == 3'd0, foo[22:20]}; initial begin foo = 4'b1_000; #1 if (test !== 4'b1_000) begin $display("FAILED -- foo=%b, test=%b", foo, test); $finish; end foo = 4'b0_111; #1 if (test !== 4'b0_111) begin $display("FAILED -- foo=%b, test=%b", foo, test); $finish; end foo = 4'b0_000; #1 if (test !== 4'b1_000) begin $display("FAILED -- foo=%b, test=%b", foo, test); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1489568.v000066400000000000000000000007701435245347300201470ustar00rootroot00000000000000// pr1489568 module bug(); reg [15 : 0] in; reg sel; wire [31 : 0] result = { 16'd0, sel ? -in : in }; initial begin in = 2; sel = 0; #1 if (result !== 32'h0000_0002) begin $display("FAILED -- sel=%b, in=%h, result=%h", sel, in, result); $finish; end sel = 1; #1 if (result !== 32'h0000_fffe) begin $display("FAILED -- sel=%b, in=%h, result=%h", sel, in, result); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1489570.v000066400000000000000000000007241435245347300201370ustar00rootroot00000000000000module bug(); reg [95:0] e; reg [95:0] f; initial e = 96'd10; initial f = 96'hAAAAAAAAAAAAAAAAAAAAAAAA; wire [95:0] div = e / f ; wire [95:0] mod = e % f ; // also fails initial begin #1 $display("div=%h", div); $display("mod=%h", mod); if (div !== 96'd0) begin $display("FAILED"); $finish; end if (mod !== 96'd10) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1491355.v000066400000000000000000000007671435245347300201400ustar00rootroot00000000000000module main; real rval; wire [63:0] wbits = $realtobits(rval); reg [63:0] rbits; initial begin rval = 1.5; rbits = $realtobits(rval); #1 /* Let the wbits value propagate */ ; if (rbits !== 64'h3ff80000_00000000) begin $display("FAILED -- rbits=%h", rbits); $finish; end if (wbits !== rbits) begin $display("FAILED -- rval=%f, rbits=%h, wbits=%h", rval, rbits, wbits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1492075.v000066400000000000000000000014711435245347300201310ustar00rootroot00000000000000// -*- Mode: Verilog -*- // Filename : cnr_tb.v // Description : single row corner bender testbench // Author : // Created On : Thu Mar 23 16:23:01 2006 // Last Modified By: $Id: pr1492075.v,v 1.1 2006/06/02 05:01:52 stevewilliams Exp $ // Last Modified On: . // Status : Unknown, Use with caution! `timescale 1ns / 10ps module cnr_tb (); reg clkb; reg clocken; integer cntb; // clock generation clkb always @ (posedge clocken) begin for (cntb=0; cntb<5; cntb=cntb+1) begin #(10 + -2) clkb = 1; #(10 - -2) clkb = 0; end end // initial begin $monitor("clkb=%b at %t", clkb, $time); clkb = 1'b0; clocken = 0; #1 clocken = 1; #(10*20) clocken = 0; #100; $finish(0); end endmodule // cnr_tb iverilog-12_0/ivtest/ivltests/pr1494799.v000066400000000000000000000013331435245347300201450ustar00rootroot00000000000000 module math(a, b, c, z); input signed [19:0] a, b; input signed [24:0] c; output signed [24:0] z; assign z = a + b + c - (c >>> 1); endmodule module test(); reg signed [19:0] a, b; reg signed [24:0] z, c; wire signed [24:0] y; wire signed [24:0] w = a + b + c - (c >>> 1); math m(a,b,c,y); initial begin a = -5; $display("a = %x %d", a, a); b = 0; $display("b = %x %d", b, b); c = 8; $display("c = %x %d", c, c); z = a + b + c - (c >>> 1); #1 /* delay for things to settle. */; $display("z = %x, %d, %b", z, z, z); $display("y = %x, %d, %b", y, y, y); $display("w = %x, %d, %b", w, w, w); $display("%b %b %b %b", $is_signed(a), $is_signed(b), $is_signed(c), $is_signed(c >>> 1)); end endmodule iverilog-12_0/ivtest/ivltests/pr1508882.v000066400000000000000000000013471435245347300201370ustar00rootroot00000000000000/* * This test is based on pr1508882. The output from the test module * should produce a 5 bit result, and the widths of the vectors are * correct for that assumption. But if an implicit part select is * mitted in the assign out=tmp, then the vector widths can break. */ module main; reg [5:0] a, b; wire [4:0] sum; test dut (.out(sum), .a(a), .b(b)); wire [5:0] padded = {1'b0, sum}; initial begin a = 1; b = 7; #1 if (padded !== (a+b)) begin $display("FAILED -- sum=%0d, a=%0d, b=%0d", sum, a, b); $finish; end $display("PASSED"); end endmodule // main module test (output [4:0] out, input [5:0] a, b); wire [5:0] tmp = a + b; assign out = tmp; endmodule // test iverilog-12_0/ivtest/ivltests/pr1510724.v000066400000000000000000000015301435245347300201150ustar00rootroot00000000000000/* * This test is really about the defparam working so it just does a * simple test of the logic functionality (eveything in manyNands * is a two bit bus). */ module top; parameter count = 2; reg pass = 1'b1; wire [count-1:0] y; reg [count-1:0] a, b; manyNands nandArray(y, a, b); defparam nandArray.count = count; initial begin a = 2'b00; b = 2'b00; #1; if (y !== 2'b11) begin $display("FAILED: ~(2'b00 & 2'b00) should be 2'b11, got %b", y); pass = 1'b0; end a = 2'b11; b = 2'b11; #1; if (y !== 2'b00) begin $display("FAILED: ~(2'b11 & 2'b11) should be 2'b00, got %b", y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule module manyNands(y, a, b); parameter count = 3; output [count-1:0] y; input [count-1:0] a, b; assign y = ~(a & b); endmodule iverilog-12_0/ivtest/ivltests/pr1515168.v000066400000000000000000000005541435245347300201310ustar00rootroot00000000000000module extension_bug(); reg x; reg [3:0] a, b; initial begin x = 1'b1; a = ~1'b1; b = ~x; $display("a = %b", a); if (a !== 4'b1110) begin $display("FAILED"); $finish; end $display("b = %b", b); if (b !== 4'b1110) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1520314.v000066400000000000000000000012231435245347300201100ustar00rootroot00000000000000module kk_timing (A, B, C, D, E, F); input A, B, D, E, F; output C; wire A, B, D, E, F; reg C; wire [1:0] BL; wire [1:0] BL_X; assign BL[0] = E; assign BL_X[0] = F; wire BL_0 = BL[0] ; wire BL_X_0 = BL_X[0]; specify $setuphold(posedge A &&& B, BL[0], 0, 0, C,,,D, BL_X[0]); // line 14 compile fail iverilog_20060618 $setuphold(posedge A &&& B, BL_0 , 0, 0, C,,,D, BL_X[0]); // line 15 compile fail iverilog_20060618 $setuphold(posedge A &&& B, BL[0], 0, 0, C,,,D, BL_X_0 ); // line 16 compile pass iverilog_20060618 $setuphold(posedge A &&& B, BL_0 , 0, 0, C,,,D, BL_X_0 ); // line 17 compile pass iverilog_20060618 endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1522570.v000066400000000000000000000007741435245347300201300ustar00rootroot00000000000000module main; reg signed [5:0] GAIN = 2; reg signed [23:0] iir = -8; wire signed [23:0] iir_s1 = iir >>> 2; wire signed [23:0] iir_s2 = iir >>> GAIN; initial begin #1 /* Wait for inputs values to settle. */ ; if (iir_s1 !== -24'sd2) begin $display("FAILED -- s1 = %d (%h)", iir_s1, iir_s1); $finish; end if (iir_s2 !== -24'sd2) begin $display("FAILED -- s2 = %d (%h)", iir_s2, iir_s2); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1528093.v000066400000000000000000000004621435245347300201300ustar00rootroot00000000000000module main; real x; real y; real bar; initial begin x = 5.0; y = 10.0; bar = x % y; $display("bar=%f", bar); if (bar != 5.0) begin $display("FAILED -- x %% y --> %f (s.b. 5.0)", bar); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1530426.v000066400000000000000000000004631435245347300201220ustar00rootroot00000000000000module main; parameter N = 2**4; initial begin if (N != 16) begin $display("FAILED -- N = %u (%h)", N, N); $finish; end if (2**4 != 16) begin $display("FAILED -- 2**16 = %u", 2**16); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr1561597.v000066400000000000000000000003211435245347300201300ustar00rootroot00000000000000module evidence; reg [4:0] y = 5'h10; initial begin $display(y[4], y[1<<2]); if (y[1<<2] !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1565544.v000066400000000000000000000006761435245347300201410ustar00rootroot00000000000000module test (); wire [2:0] d [0:2]; reg [2:0] src[0:2]; genvar i; for (i = 0 ; i < 3 ; i = i+1) assign d[i] = src[i]; integer idx; initial begin for (idx = 0 ; idx < 3 ; idx = idx+1) src[idx] = idx; #1 for (idx = 0 ; idx < 3 ; idx = idx+1) if (d[idx] !== idx) begin $display("FAILED -- d[%0d] = %b", idx, d[idx]); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1565699b.v000066400000000000000000000013511435245347300203050ustar00rootroot00000000000000module test (); reg [2:0] in; wire Oand, Oor; dut #(.is_and(1)) dand (.O(Oand), .A(in[1]), .B(in[0])); dut #(.is_and(0)) dor (.O(Oor ), .A(in[1]), .B(in[0])); initial begin for (in = 0 ; in < 4 ; in = in+1) begin #1 /* settle time. */ ; if (Oand !== &in[1:0]) begin $display("FAILED -- in=%b, Oand=%b", in, Oand); $finish; end if (Oor !== |in[1:0]) begin $display("FAILED -- in=%b, Oor=%b", in, Oor); $finish; end end // for (in = 0 ; in < 4 ; in = in+1) $display("PASSED"); end endmodule module dut (output O, input A, input B); parameter is_and = 1; generate if (is_and) and g(O, A, B); else or g(O, A, B); endgenerate endmodule // dut iverilog-12_0/ivtest/ivltests/pr1570451.v000066400000000000000000000016071435245347300201250ustar00rootroot00000000000000module test; reg [1:0] bus; reg [1:0] skewed_bus; integer delay0; initial delay0 = 5; integer delay1; initial delay1 = 10; /* attempt to model skew across the bus using transport delays */ always @( bus[0] ) begin skewed_bus[0] <= #delay0 bus[0]; end always @( bus[1] ) begin skewed_bus[1] <= #delay1 bus[1]; end initial begin #1 bus = 2'b00; #11 if (skewed_bus !== 2'b00) begin $display("FAILED -- setup failed."); $finish; end bus = 2'b11; #4 if (skewed_bus !== 2'b00) begin $display("FAILED -- changed far too soon"); $finish; end #2 if (skewed_bus !== 2'b01) begin $display("FAILED -- partial change not right."); $finish; end #5 if (skewed_bus !== 2'b11) begin $display("FAILED -- final change not right"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1570451b.v000066400000000000000000000751431435245347300202750ustar00rootroot00000000000000module test; reg [7:0] bus; reg [7:0] skewed_bus; integer delay0; initial delay0 = 4; integer delay1; initial delay1 = 8; integer delay2; initial delay2 = 12; integer delay3; initial delay3 = 16; integer delay4; initial delay4 = 20; integer delay5; initial delay5 = 24; integer delay6; initial delay6 = 28; integer delay7; initial delay7 = 32; /* model skew across the bus using transport delays */ always @( bus[0] ) begin skewed_bus[0] <= #delay0 bus[0]; end always @( bus[1] ) begin skewed_bus[1] <= #delay1 bus[1]; end always @( bus[2] ) begin skewed_bus[2] <= #delay2 bus[2]; end always @( bus[3] ) begin skewed_bus[3] <= #delay3 bus[3]; end always @( bus[4] ) begin skewed_bus[4] <= #delay4 bus[4]; end always @( bus[5] ) begin skewed_bus[5] <= #delay5 bus[5]; end always @( bus[6] ) begin skewed_bus[6] <= #delay6 bus[6]; end always @( bus[7] ) begin skewed_bus[7] <= #delay7 bus[7]; end initial begin bus = {8{1'b0}}; #4; bus = 8'b00100100; #4; bus = 8'b10000001; #4; bus = 8'b00001001; #4; bus = 8'b01100011; #4; bus = 8'b00001101; #4; bus = 8'b10001101; #4; bus = 8'b01100101; #4; bus = 8'b00010010; #4; bus = 8'b00000001; #4; bus = 8'b00001101; #4; bus = 8'b01110110; #4; bus = 8'b00111101; #4; bus = 8'b11101101; #4; bus = 8'b10001100; #4; bus = 8'b11111001; #4; bus = 8'b11000110; #4; bus = 8'b11000101; #4; bus = 8'b10101010; #4; bus = 8'b11100101; #4; bus = 8'b01110111; #4; bus = 8'b00010010; #4; bus = 8'b10001111; #4; bus = 8'b11110010; #4; bus = 8'b11001110; #4; bus = 8'b11101000; #4; bus = 8'b11000101; #4; bus = 8'b01011100; #4; bus = 8'b10111101; #4; bus = 8'b00101101; #4; bus = 8'b01100101; #4; bus = 8'b01100011; #4; bus = 8'b00001010; #4; bus = 8'b10000000; #4; bus = 8'b00100000; #4; bus = 8'b10101010; #4; bus = 8'b10011101; #4; bus = 8'b10010110; #4; bus = 8'b00010011; #4; bus = 8'b00001101; #4; bus = 8'b01010011; #4; bus = 8'b01101011; #4; bus = 8'b11010101; #4; bus = 8'b00000010; #4; bus = 8'b10101110; #4; bus = 8'b00011101; #4; bus = 8'b11001111; #4; bus = 8'b00100011; #4; bus = 8'b00001010; #4; bus = 8'b11001010; #4; bus = 8'b00111100; #4; bus = 8'b11110010; #4; bus = 8'b10001010; #4; bus = 8'b01000001; #4; bus = 8'b11011000; #4; bus = 8'b01111000; #4; bus = 8'b10001001; #4; bus = 8'b11101011; #4; bus = 8'b10110110; #4; bus = 8'b11000110; #4; bus = 8'b10101110; #4; bus = 8'b10111100; #4; bus = 8'b00101010; #4; bus = 8'b00001011; #4; bus = 8'b01110001; #4; bus = 8'b10000101; #4; bus = 8'b01001111; #4; bus = 8'b00111011; #4; bus = 8'b00111010; #4; bus = 8'b01111110; #4; bus = 8'b00010101; #4; bus = 8'b11110001; #4; bus = 8'b11011001; #4; bus = 8'b01100010; #4; bus = 8'b01001100; #4; bus = 8'b10011111; #4; bus = 8'b10001111; #4; bus = 8'b11111000; #4; bus = 8'b10110111; #4; bus = 8'b10011111; #4; bus = 8'b01011100; #4; bus = 8'b01011011; #4; bus = 8'b10001001; #4; bus = 8'b01001001; #4; bus = 8'b11010000; #4; bus = 8'b11010111; #4; bus = 8'b01010001; #4; bus = 8'b10010110; #4; bus = 8'b00001100; #4; bus = 8'b11000010; #4; bus = 8'b11001000; #4; bus = 8'b01110111; #4; bus = 8'b00111101; #4; bus = 8'b00010010; #4; bus = 8'b01111110; #4; bus = 8'b01101101; #4; bus = 8'b00111001; #4; bus = 8'b00011111; #4; bus = 8'b11010011; #4; bus = 8'b10000101; #4; bus = 8'b01111000; #4; bus = 8'b01011011; #4; bus = 8'b01001001; #4; bus = 8'b00111111; #4; bus = 8'b00101010; #4; bus = 8'b01011000; #4; bus = 8'b10000110; #4; bus = 8'b10001110; #4; bus = 8'b10011100; #4; bus = 8'b11111010; #4; bus = 8'b00100110; #4; bus = 8'b01110011; #4; bus = 8'b10100011; #4; bus = 8'b00101111; #4; bus = 8'b10110011; #4; bus = 8'b01011111; #4; bus = 8'b01000100; #4; bus = 8'b11110111; #4; bus = 8'b11001011; #4; bus = 8'b11100110; #4; bus = 8'b01011010; #4; bus = 8'b00101001; #4; bus = 8'b11101101; #4; bus = 8'b11011010; #4; bus = 8'b01100101; #4; bus = 8'b10110101; #4; bus = 8'b11011111; #4; bus = 8'b01111001; #4; bus = 8'b01000100; end initial begin #2; if (skewed_bus !== 8'bxxxxxxxx) begin $write("FAILED -- expected xxxxxxxx "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxxxxxxx0) begin $write("FAILED -- expected xxxxxxx0 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxxxxxx00) begin $write("FAILED -- expected xxxxxx00 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxxxxx001) begin $write("FAILED -- expected xxxxx001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxxxx0101) begin $write("FAILED -- expected xxxx0101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxxx00001) begin $write("FAILED -- expected xxx00001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bxx000011) begin $write("FAILED -- expected xx000011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'bx0101001) begin $write("FAILED -- expected x0101001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000101) begin $write("FAILED -- expected 00000101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00001100) begin $write("FAILED -- expected 00001100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10101111) begin $write("FAILED -- expected 10101111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01000001) begin $write("FAILED -- expected 01000001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000000) begin $write("FAILED -- expected 00000000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110111) begin $write("FAILED -- expected 00110111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11001101) begin $write("FAILED -- expected 11001101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000100) begin $write("FAILED -- expected 00000100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00011101) begin $write("FAILED -- expected 00011101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00111100) begin $write("FAILED -- expected 00111100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01101011) begin $write("FAILED -- expected 01101011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00101100) begin $write("FAILED -- expected 00101100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01010111) begin $write("FAILED -- expected 01010111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10100001) begin $write("FAILED -- expected 10100001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11001110) begin $write("FAILED -- expected 11001110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11000111) begin $write("FAILED -- expected 11000111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11100010) begin $write("FAILED -- expected 11100010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10110110) begin $write("FAILED -- expected 10110110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111010) begin $write("FAILED -- expected 11111010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11000101) begin $write("FAILED -- expected 11000101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00011000) begin $write("FAILED -- expected 00011000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00101101) begin $write("FAILED -- expected 00101101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11000101) begin $write("FAILED -- expected 11000101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11101101) begin $write("FAILED -- expected 11101101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011101) begin $write("FAILED -- expected 11011101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011110) begin $write("FAILED -- expected 11011110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11100010) begin $write("FAILED -- expected 11100010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00100000) begin $write("FAILED -- expected 00100000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10101000) begin $write("FAILED -- expected 10101000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01100011) begin $write("FAILED -- expected 01100011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01000000) begin $write("FAILED -- expected 01000000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00001111) begin $write("FAILED -- expected 00001111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00101111) begin $write("FAILED -- expected 00101111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10110001) begin $write("FAILED -- expected 10110001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00010111) begin $write("FAILED -- expected 00010111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10011011) begin $write("FAILED -- expected 10011011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10000000) begin $write("FAILED -- expected 10000000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10011110) begin $write("FAILED -- expected 10011110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000011) begin $write("FAILED -- expected 00000011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01110101) begin $write("FAILED -- expected 01110101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001111) begin $write("FAILED -- expected 01001111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001110) begin $write("FAILED -- expected 01001110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10111010) begin $write("FAILED -- expected 10111010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000010) begin $write("FAILED -- expected 00000010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10001000) begin $write("FAILED -- expected 10001000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01101110) begin $write("FAILED -- expected 01101110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10001011) begin $write("FAILED -- expected 10001011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00010000) begin $write("FAILED -- expected 00010000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01111000) begin $write("FAILED -- expected 01111000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10100001) begin $write("FAILED -- expected 10100001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001001) begin $write("FAILED -- expected 01001001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10011010) begin $write("FAILED -- expected 10011010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011010) begin $write("FAILED -- expected 11011010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01101110) begin $write("FAILED -- expected 01101110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11000110) begin $write("FAILED -- expected 11000110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110100) begin $write("FAILED -- expected 00110100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11101111) begin $write("FAILED -- expected 11101111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10001011) begin $write("FAILED -- expected 10001011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111001) begin $write("FAILED -- expected 11111001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10101001) begin $write("FAILED -- expected 10101001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10100111) begin $write("FAILED -- expected 10100111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10010110) begin $write("FAILED -- expected 10010110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00101010) begin $write("FAILED -- expected 00101010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001011) begin $write("FAILED -- expected 01001011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00011101) begin $write("FAILED -- expected 00011101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111101) begin $write("FAILED -- expected 11111101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110000) begin $write("FAILED -- expected 00110000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110010) begin $write("FAILED -- expected 00110010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01011001) begin $write("FAILED -- expected 01011001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110111) begin $write("FAILED -- expected 00110111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001110) begin $write("FAILED -- expected 01001110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11101101) begin $write("FAILED -- expected 11101101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011011) begin $write("FAILED -- expected 11011011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001110) begin $write("FAILED -- expected 01001110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00010101) begin $write("FAILED -- expected 00010101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10111111) begin $write("FAILED -- expected 10111111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111001) begin $write("FAILED -- expected 11111001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10011000) begin $write("FAILED -- expected 10011000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10011001) begin $write("FAILED -- expected 10011001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11001011) begin $write("FAILED -- expected 11001011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01000100) begin $write("FAILED -- expected 01000100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00010010) begin $write("FAILED -- expected 00010010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11010100) begin $write("FAILED -- expected 11010100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01010110) begin $write("FAILED -- expected 01010110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011001) begin $write("FAILED -- expected 11011001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11000011) begin $write("FAILED -- expected 11000011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00001100) begin $write("FAILED -- expected 00001100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10000110) begin $write("FAILED -- expected 10000110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01011011) begin $write("FAILED -- expected 01011011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11110101) begin $write("FAILED -- expected 11110101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111101) begin $write("FAILED -- expected 11111101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00011011) begin $write("FAILED -- expected 00011011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00101111) begin $write("FAILED -- expected 00101111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01111000) begin $write("FAILED -- expected 01111000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01110101) begin $write("FAILED -- expected 01110101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00010011) begin $write("FAILED -- expected 00010011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00001001) begin $write("FAILED -- expected 00001001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01011010) begin $write("FAILED -- expected 01011010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10111110) begin $write("FAILED -- expected 10111110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11001000) begin $write("FAILED -- expected 11001000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01011010) begin $write("FAILED -- expected 01011010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01101110) begin $write("FAILED -- expected 01101110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00110100) begin $write("FAILED -- expected 00110100 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00001110) begin $write("FAILED -- expected 00001110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001011) begin $write("FAILED -- expected 01001011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00011111) begin $write("FAILED -- expected 00011111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10010011) begin $write("FAILED -- expected 10010011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10100011) begin $write("FAILED -- expected 10100011 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11110111) begin $write("FAILED -- expected 11110111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10101010) begin $write("FAILED -- expected 10101010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01100101) begin $write("FAILED -- expected 01100101 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00111111) begin $write("FAILED -- expected 00111111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b10110110) begin $write("FAILED -- expected 10110110 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b00000010) begin $write("FAILED -- expected 00000010 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11011111) begin $write("FAILED -- expected 11011111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01100001) begin $write("FAILED -- expected 01100001 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b01001000) begin $write("FAILED -- expected 01001000 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11111111) begin $write("FAILED -- expected 11111111 "); $display("received %b ", skewed_bus); $finish; end #4; if (skewed_bus !== 8'b11001001) begin $write("FAILED -- expected 11001001 "); $display("received %b ", skewed_bus); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1570635.v000066400000000000000000000022251435245347300201260ustar00rootroot00000000000000module test; reg [2:0] ptr; reg [2:0] size; reg [2:0] ptr_nxt; always @* begin ptr_nxt = ptr; if ( ptr + size > 3 ) begin ptr_nxt = ptr + size - 3; end else begin ptr_nxt = 0; end end initial begin #1; ptr = 2; size = 2; #1 $write("ptr_nxt=%0d ptr=%0d size=%0d", ptr_nxt, ptr, size); if ( ptr_nxt == 1 ) begin $display(" OK"); end else begin $display(" ERROR"); $finish; end ptr = 3; size = 4; #1 $write("ptr_nxt=%0d ptr=%0d size=%0d", ptr_nxt, ptr, size); if ( ptr_nxt == 4 ) begin $display(" OK"); end else begin $display(" ERROR"); $finish; end ptr = 3; size = 5; #1 $write("ptr_nxt=%0d ptr=%0d size=%0d", ptr_nxt, ptr, size); if ( ptr_nxt == 5 ) begin $display(" OK"); end else begin $display(" ERROR"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1570635b.v000066400000000000000000000010431435245347300202650ustar00rootroot00000000000000module test; // This example was adapted from: // DRAFT STANDARD VERILOG HARDWARE DESCRIPTION LANGUAGE // IEEE P1364-2005/D3, 1/7/04 // Section 4.4.2 "An example of an expression bit-length problem" // pg. 59 reg [15:0] a, b, answer; // 16-bit regs initial begin a = 16'h8000; b = 16'h8000; answer = (a + b + 0) >> 1; //will work correctly if ( answer != 16'h8000 ) begin $display("FAILED -- expected 16'h8000 received 16'h%h", answer); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1574175.v000066400000000000000000000005401435245347300201270ustar00rootroot00000000000000module top; integer correct, incorrect; reg [5:0] bits; initial begin bits = 32; incorrect = -180 + bits*(360.0/63.0); correct = bits*(360.0/63.0) - 180; $display("Both of these should be the same (3): %3d, %3d", incorrect, correct); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1581580.v000066400000000000000000000013711435245347300201300ustar00rootroot00000000000000module test; parameter SIZE = 2; reg [SIZE-1:0] d ; // data in reg c ; // latch control wire [SIZE-1:0] q ; // output unit_latch u_lat[SIZE-1:0] (.Q(q), .G(c), .D(d)); initial begin d = 0; c = 1; #1 if (q !== 2'b00) begin $display("FAILED -- Initial load failed."); $finish; end d = 2'b01; #1 if (q !== 2'b01) begin $display("FAILED -- Latch follow failed."); $finish; end c = 0; #1 d = 2'b10; #1 if (q !== 2'b01) begin $display("FAILED -- Latch hold failed."); $finish; end $display("PASSED"); $finish; end endmodule module unit_latch(output reg Q, input wire D, input wire G); always @* if (G) Q = D; endmodule // unit_latch iverilog-12_0/ivtest/ivltests/pr1587634.v000066400000000000000000000006211435245347300201330ustar00rootroot00000000000000// // Test the specify block (pr1587634) // `timescale 1 ns / 1 ps /* module top(); reg in; initial begin in = 0; #10 in = 1; end inv1 g1 (out, in); endmodule */ module inv1 (z, a); output z; input a; not g1(z, a); specify specparam tpd_a_z_lh = 0.400; specparam tpd_a_z_hl = 0.300:0.400:0.500; (a -=> z) = (tpd_a_z_lh, tpd_a_z_hl); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1587669.v000066400000000000000000000016651435245347300201540ustar00rootroot00000000000000`timescale 1ns/1ps module fail (); reg pz; reg [4:0] p; wire em, net0102; initial begin p = 0; pz = 0; $monitor("time=%0t", $time,": em=", em, ", pz=", pz, ", p=%b", p); while (p < 5'b11111) #10 p = p+1; #1; // avoid final race $finish(0); end nr1 I1 (em, net0102, pz, p[0]); nr2 I2 (net0102, p[1], p[2], p[3], p[4]); endmodule module nr1 (zn, a1, a2, a3); output zn; input a1, a2, a3; not G1(N1, a1); not G2(zn, N2); or G3(N2, N1, a2, a3); specify (a1 +=> zn) = (0.500, 0.500); (a2 -=> zn) = (0.500, 0.500); (a3 -=> zn) = (0.500, 0.500); endspecify endmodule module nr2 (zn, a1, a2, a3, a4); output zn; input a1, a2, a3, a4; or G1(N1, a1, a2, a3, a4); not G2(zn, N1); specify (a1 -=> zn) = (0.500, 0.500); (a2 -=> zn) = (0.500, 0.500); (a3 -=> zn) = (0.500, 0.500); (a4 -=> zn) = (0.500, 0.500); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1589497.v000066400000000000000000000005341435245347300201470ustar00rootroot00000000000000module test; reg signed [31:0] mydata; initial begin mydata = -6; repeat ( 11 ) begin add_one(mydata); $display("mydata = %0d", mydata); end $finish(0); end task add_one; inout signed [31:0] myotherdata; begin myotherdata = myotherdata + 1; end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1598445.v000066400000000000000000000012451435245347300201400ustar00rootroot00000000000000module test(); wire sig; reg en0, en1; pullup (sig); assign sig = en0 ? 1'b0 : 1'bz; assign sig = en1 ? 1'b1 : 1'bz; reg sig2; always @(sig) sig2 = sig; initial begin en0 = 0; en1 = 1; #1 en1 = 0; #1 if (sig2 !== 1'b1) begin $display("FAILED -- sig2=%b, sig=%b", sig2, sig); $finish; end force sig = 0; #1 if (sig2 !== 1'b0) begin $display("FAILED -- sig2=%b, sig=%b", sig2, sig); $finish; end release sig; #1 if (sig2 !== 1'b1) begin $display("FAILED -- sig2=%b, sig=%b", sig2, sig); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1601896.v000066400000000000000000000001631435245347300201310ustar00rootroot00000000000000module test; initial begin if(2) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1601898.v000066400000000000000000000003151435245347300201320ustar00rootroot00000000000000module test; initial begin main; $display("PASSED"); end task main; begin if(1) ; else begin $display("FAILED"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1603313.v000066400000000000000000000027151435245347300201200ustar00rootroot00000000000000/* * This program is explicitly placed in the public domain for any uses * whatsoever. */ module TestMultiplier(); reg clk; initial begin clk = 0; forever #0.5 clk = ~clk; end reg[5:0] left, right; wire[2:0] exp; Multiplier mul(clk, left, right, exp); parameter ONE = {3'b011, 3'b0}; // 1.000 * 2**(3 - bias of 3) == 1.000 always @ (posedge clk) begin left = ONE; right = ONE; #10 if (exp !== 3'b011) $display("FAIL: expected %b, got %b", 3'b011, exp); else $display("PASSED"); $finish(); end endmodule /** * A little bit of an incomplete floating-point multiplier. In/out format is * [5:3] specify biased exponent (and hidden bit), [2:0] specify fraction. * * @param left[5:0], right[5:0] * values being multiplied * @param exp[2:0] * exponent from product of left and right when put in the floating-point * format of left/right */ module Multiplier(clk, left, right, exp); input clk; input[5:0] left, right; output[2:0] exp; reg[2:0] exp; // IMPLEMENTATION wire signed[2:0] expl = left[5:3] - 3; wire signed[2:0] expr = right[5:3] - 3; /** Sum of unbiased exponents in operands. */ reg signed[3:0] sumExp; always @ (posedge clk) begin sumExp <= (expl + expr) < -2 // why can't I move -2 to the right-hand side? ? -3 : expl + expr; exp[2:0] <= sumExp + 3; end endmodule iverilog-12_0/ivtest/ivltests/pr1603918.v000066400000000000000000000031771435245347300201360ustar00rootroot00000000000000`timescale 1ns/1ns module top; wire q; reg a, b; initial begin // $dumpfile("test.lx2"); // Need to also use the -lxt2 flags on exe. // $dumpvars(0, top); // Initial value should be X is 1. #1 a = 1'b1; // Should be X is 1. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 a = 1'b0; // Correct: 1. #1 if (q !== 1'b1) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 a = 1'b1; // Should be X is 1. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 a = 1'bx; // Should be X is 1. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 a = 1'b1; // Should be X is 1. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 a = 1'bx; b = 1'b1; // Correct: X. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 b = 1'b0; // Correct: 1. #1 if (q !== 1'b1) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end #1 b = 1'b1; // Correct: X, but following #1 delay is missing. #1 if (q !== 1'bx) begin $display("FAILED -- %b nand %b --> %b", a, b, q); $finish; end $display("PASSED"); $finish; end nand dut (q, a, b); // nand dut (q, b, a); // This also produces incorrect results. endmodule iverilog-12_0/ivtest/ivltests/pr1609611.v000066400000000000000000000010221435245347300201150ustar00rootroot00000000000000module x; parameter bar0_low = 5'd16; // Register Space reg [31:bar0_low] base_address0; reg [31:0] ad_in_d; wire [0:5] hit_bar; wire a = |bar0_low; wire [31:0] e = ad_in_d[31:bar0_low]; wire b = (base_address0==e); wire d = b; assign hit_bar[0] = a ? d : 0; initial begin if ($bits(base_address0) != 16) begin $display("FAILED -- $bits(base_address0) = %0d", $bits(base_address0)); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1612693.v000066400000000000000000000004301435245347300201230ustar00rootroot00000000000000/* pr1612693.v */ module test (); reg [9:0] col; wire [9:0] xsize; // The setup for this expression caused an assertion at run time // according to pr1612693. wire vschg = (col == (xsize>>1)); initial begin #1 $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1623097.v000066400000000000000000000014131435245347300201250ustar00rootroot00000000000000/* pr1623097 */ `timescale 1ns/1ns module top; reg [3:0] state; reg [3:0] data; reg [3:0] clear; reg clk; genvar i; initial begin #0; // avoid time-0 race clk = 0; data = 4'b1111; clear = 4'b1111; $monitor($time,,"clk=%b, data=%b, clear=%b, state=%b", clk, data, clear, state); #10 clear = 4'b0000; #10 clk = 1; #10 clk = 0; clear = 4'b0010; #10 clear = 4'b0000; data = 4'b1010; #10 clk = 1; #10 clk = 0; end // This fails! generate for (i=0; i<4; i=i+1) begin:sm always @(posedge clk or posedge clear[i]) begin if (clear[i]) state[i] <= 1'b0; // Async. clear the flip bit. else begin state[i] <= #1 data[i]; end end end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr1625912.v000066400000000000000000000006511435245347300201260ustar00rootroot00000000000000/* PR1625912 */ /* * Substatuting in either of the commented out lines caused VVP to fail. */ module top; integer cnt; real result, win; initial begin cnt = -10; for (result=-10; result<=10; result=result+2) begin #1 if (result != cnt) begin $display("FAILED -- cnt=%0d, result=%f", cnt, result); end cnt = cnt + 2; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1628288.v000066400000000000000000000021461435245347300201400ustar00rootroot00000000000000// `define READ read_good module top; reg clk; reg dout; reg [7:0] data; integer lp; always #10 clk = ~clk; // Build a clock generator. always @(negedge clk) dout = ~dout; // Build a bit stream. initial begin clk = 0; dout = 0; @(negedge clk); for (lp=0; lp<4; lp=lp+1) begin #0 read_bad(data); $display("Read(%0d) %b from the bit stream.", lp, data); #20; // For the fun of it skip a clock. end #1 $finish(0); end // This one locks up on the third call. task read_bad; output [7:0] edata; integer i; reg [7:0] rddata; begin for(i=7; i>=0; i=i-1) begin @(posedge clk); $display(" Reading bit %0d", i); rddata[i] = dout; // <<--- This appears to be the problem line! end assign edata = rddata; end endtask // This one works fine. task read_good; output [7:0] edata; integer i; reg [7:0] edata; begin for(i=7; i>=0; i=i-1) begin @(posedge clk); $display(" Reading bit %0d", i); edata[i] = dout; end end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1628300.v000066400000000000000000000003051435245347300201140ustar00rootroot00000000000000module bug; function real sin; input x; real x; sin = 1.570794*x; endfunction real ax, ay; initial begin ax = 2.0; ay = sin(ax); $display("sin(%g) is not really %g", ax, ay); end endmodule iverilog-12_0/ivtest/ivltests/pr1629683.v000066400000000000000000000011501435245347300201320ustar00rootroot00000000000000`timescale 1ns/1ns module top; reg [7:0] data; reg [9:0] odata; reg sout, clk; integer lp; initial begin data = 8'h55; #0 $display("Printing the byte %b with a header.", data); $write("Bad - "); odata = 10'b1x00000000; odata[7:0] = data; send_byte(odata); // #0 send_byte(odata); // This fixes things, but should not be needed! $write(", ok - "); send_byte(odata); $display("."); #1 data = 0; #1 $finish(0); end // Print a byte of data. task send_byte; input [9:0] sndbyte; begin $write("%b", sndbyte); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1632861.v000066400000000000000000000005401435245347300201240ustar00rootroot00000000000000module test; reg[9:0] tst; initial begin #1 tst = 0; // This should set the register to 10'b00000xxxxx! #1 tst = 5'hxx; #1 tst = 10'h3ff; #1 tst = 10'b00000xxxxx; #1 tst = 0; #1 tst = 8'hxx; #1 tst = 0; #1 $finish(0); end always @(tst) begin $display("At %0t value is %b", $time, tst); end endmodule iverilog-12_0/ivtest/ivltests/pr1634526.v000066400000000000000000000007541435245347300201330ustar00rootroot00000000000000/* pr1634526.v */ module test; initial begin $display("Working: This (%0d) should be 255.", minus1(256)); // This crashes! $display("Broken: This (%0d) should be 255", minus1(2**8)); // And this gives the wrong result! $display("Broken: This (%0d) should be 255.", minus1(2**8-1+1)); $display(" started with %0d.", 2**8-1+1); $finish(0); end function integer minus1; input value; integer value; minus1 = value - 1; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1636409.v000066400000000000000000000011221435245347300201230ustar00rootroot00000000000000/* pr1636409 */ module top; wire [3:0] fail, good; wire eni; reg [2:0] rg; reg in, en, clk; assign #1 eni = en; assign #1 fail = (eni) ? {rg,in} : 'b0; assign #1 good = {4{eni}} & {rg,in}; always @(fail or good or eni) begin $strobe("fail=%b, good=%b, en=%b at %0t", fail, good, eni, $time); end always #10 clk = ~clk; always @(posedge clk) begin en = ~en; in = ~in; rg = ~rg; end initial begin // $dumpfile("results.vcd"); // $dumpvars(0, top); clk = 0; en = 0; in = 0; rg = 3'b101; #50 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1637208.v000066400000000000000000000016771435245347300201400ustar00rootroot00000000000000/* PR1637208 */ module main; reg clock; reg [31:0] pixel0; reg [31:0] mem [0:1]; always @(posedge clock) begin mem[0] <= pixel0; end always @(posedge clock) begin mem[1] <= mem[0]; end reg sel; wire [31:0] foo = sel? mem[1] : mem[0]; initial begin clock = 1; sel = 0; #1 pixel0 = 'h55555555; #1 clock = 0; #1 clock = 1; #1 pixel0 = 'haaaaaaaa; #1 clock = 0; #1 clock = 1; #1 if (mem[0] !== 32'haaaaaaaa) begin $display("FAILED -- mem[0] = %h", mem[0]); $finish; end if (mem[1] !== 32'h55555555) begin $display("FAILED == mem[1] = %h", mem[1]); $finish; end if (foo !== mem[0]) begin $display("FAILED -- mem[sel=0] != %h", foo); $finish; end sel = 1; #1 if (foo !== mem[1]) begin $display("FAILED -- mem[sel=1] != %h", foo); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1638985.v000066400000000000000000000004031435245347300201370ustar00rootroot00000000000000module main; real x; initial begin x = 1.0; $display("Hello, World"); $display("Positive x is %f", x); $display("-1.0 * x is %f", -1.0 * x); $display("0.0 - x is %f", 0.0 - x); $display("-x is %f", -x); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1639060.v000066400000000000000000000006431435245347300201260ustar00rootroot00000000000000// pr1639060 module top; real value; initial begin value = 10.0; // value = -10.0; print; end task print; real tmp; begin if (value < 0.0) tmp = value + 10.0; else tmp = value; $display("1. The result is %5.1f", tmp); // This line fails! tmp = (value < 0.0) ? value+10.0 : value; $display("2. The result is %5.1f", tmp); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1639064.v000066400000000000000000000005421435245347300201300ustar00rootroot00000000000000module top; reg value = 1; integer val = 100; initial begin $display("1. The value is %3d", value*100); $display("2. The value is %3.0f", value*100.0); $display("3. The value is %3.0f", 100); $display("4. The value is %3.0f", val); $display("5. The value is %3.0f", value*100); // This fails! $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1639064b.v000066400000000000000000000005651435245347300202770ustar00rootroot00000000000000module top; reg [31:0] value = 1000000; integer val = 100; initial begin $display("1. The value is %3d", value*100); $display("2. The value is %3.0f", value*100.0); $display("3. The value is %3.0f", 100); $display("4. The value is %3.0f", val); $display("5. The value is %3.0f", value*100000000); // This fails! $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1639968.v000066400000000000000000000006431435245347300201470ustar00rootroot00000000000000 module RegisterArrayBug01; reg [15:0] rf[0:7]; wire [15:0] rf_0 = rf[1]; initial begin $monitor($time,, "rf[0] is %h %h", rf[1], rf_0); rf[1] = 16'hffff; #10 rf[1] = 16'h0000; #10 rf[1] = 16'hbeef; #10 $finish(0); end endmodule /* System prints: 0 rf[0] is xxxx ffff 10 rf[0] is xxxx 0000 20 rf[0] is beef beef Expected is: 0 rf[0] is ffff ffff 10 rf[0] is 0000 0000 20 rf[0] is beef beef */ iverilog-12_0/ivtest/ivltests/pr1639971.v000066400000000000000000000006441435245347300201420ustar00rootroot00000000000000module RegisterArrayBug01; reg [15:0] rf[0:7]; wire [3:0] rf_0_slice0 = rf[0][3:0]; wire [15:0] rf_0 = rf[0]; initial begin $monitor($time,, "rf and slice: %h %h", rf_0, rf_0_slice0); rf[0] = 16'hffff; #10 rf[0] = 16'h0000; #10 rf[0] = 16'hbeef; #10 $finish(0); end endmodule /* Program fails to compile with result: elab_net.cc:1738: failed assertion `msb_ == 0' */ iverilog-12_0/ivtest/ivltests/pr1645277.v000066400000000000000000000003511435245347300201310ustar00rootroot00000000000000// pr1645277 module test; initial main; task main; integer foo; begin foo = 0; while(foo < 5) begin: inner foo = foo + 1; end $write("expected %d; got %d\n", 5, foo); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1645518.v000066400000000000000000000013511435245347300201300ustar00rootroot00000000000000/* PR1645518 */ module testBench; wire w1, w2, w3, w4, w5; binaryToESeg d (w1, w2, w3, w4, w5); test_bToESeg t (w1, w2, w3, w4, w5); endmodule module binaryToESeg (input A, B, C, D, output eSeg); nand #1 g1 (p1, C, ~D), g2 (p2, A, B), g3 (p3, ~B, ~D), g4 (p4, A, C), g5 (eSeg, p1, p2, p3, p4); endmodule // binaryToESeg module test_bToESeg (output reg A, B, C, D, input eSeg); initial // two slashes introduce a single line comment begin $monitor ($time,, "A = %b B = %b C = %b D = %b, eSeg = %b", A, B, C, D, eSeg); //waveform for simulating the nand lip lop #10 A = 0; B = 0; C = 0; D = 0; #10 D = 1; #10 C = 1; D = 0; #10 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1648365.v000066400000000000000000000015411435245347300201340ustar00rootroot00000000000000module ivitest; reg clock_1x, clock_2x; reg [31:1] w [0:1]; wire [31:1] w0 = w[0]; wire [31:1] w1 = w[1]; initial begin #0; //avoid time-0 race clock_1x = 0; clock_2x = 0; $monitor($time,,"w0=%h, w1=%h", w0, w1); #1; forever begin clock_1x = !clock_1x; clock_2x = !clock_2x; #5; clock_2x = !clock_2x; #5; end end reg phase; always @(clock_1x) begin phase = #1 clock_1x; end reg [31:1] u; always @(posedge clock_2x) begin u <= 'haaaaaaaa; end reg [31:1] v; always @(posedge clock_2x) begin v <= 'h99999999; if (phase) begin w[0] <= v; w[1] <= u; end end reg [31:1] x0, x1; always @(posedge clock_1x) begin x0 <= w[0]; x1 <= w[1]; end initial begin // $dumpfile( "test.vcd" ); // $dumpvars; #100; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1650842.v000066400000000000000000000011601435245347300201220ustar00rootroot00000000000000/* pr1650842 */ module test; initial main; task main; integer _$ID241, _$ID246, _$ID247, _$ID248, _$ID249, a; begin a = 0; _$ID241 = a; a = 9; _$ID246 = a; _$ID247 = 3; a = _$ID247; _$ID248 = _$ID246 + _$ID247 ; _$ID249 = _$ID248; a = _$ID249; if( a !== 12 ) begin $write("FAIL: expected 12; got %d\n", a); $display("_$ID241=%d", _$ID241); $display("_$ID246=%d", _$ID246); $display("_$ID247=%d", _$ID247); $display("_$ID248=%d", _$ID248); $display("_$ID249=%d", _$ID249); end else begin $write("PASSED\n"); end end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1657307.v000066400000000000000000000013351435245347300201310ustar00rootroot00000000000000module test; integer dindex[2:0]; integer cindex[2:0]; initial main; task main; integer index; begin dindex[0] = 3; dindex[1] = 4; dindex[2] = 5; cindex[0] = 1; cindex[1] = 2; cindex[2] = 3; index = get_index(3); $write("index is %0d\n", index); if (index !== 32) $display("FAILED"); else $display("PASSED"); end endtask function integer get_index; input rank; integer rank; integer i, sum, multiplier; begin multiplier = 1; sum = 0; for(i = rank-1; i >= 0; i = i-1) begin sum = sum + (cindex[i] * multiplier); multiplier = dindex[i] * multiplier; end get_index = sum-1; end endfunction endmodule // test iverilog-12_0/ivtest/ivltests/pr1661640.v000066400000000000000000000007761435245347300201340ustar00rootroot00000000000000// pr1661640.v module test; reg [112:1] hello1, hello2; initial begin hello1 = "Hello world!\n"; hello2 = "Hello world!\012"; main; end task main; begin $write ("%s\n", "Hello world!"); // Ok $write ("%s", "Hello world!\n"); // bad $write ("\nhello1; escaped NL:\n"); $write ("%0s", hello1); // bad $write ("%x", hello1); $write ("\nhello2; octal NL:\n"); $write ("%0s", hello2); // bad $write ("%x", hello2); $display(); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1662508.v000066400000000000000000000014231435245347300201260ustar00rootroot00000000000000// pr1662508.v `timescale 1ns / 1ns module ram( input clk, input we, input [9:0] addr, input [15:0] data, output [15:0] read_bus ); reg [15:0] ram[31:0]; assign read_bus = ram[addr[3:0]]; always @(posedge clk) if (we) ram[addr[3:0]] <= data; endmodule module ram_test; reg clk; reg fail=0; integer cc; initial begin for (cc = 0; cc < 33; cc=cc+1) begin clk = 0; #5; clk = 1; #5; end if (fail) $display("FAIL"); else $display("PASSED"); end reg we=0; reg [9:0] addr=0; reg [15:0] data=0; always @(posedge clk) begin addr <= cc; data <= cc*cc; we <= cc<16; end wire [15:0] read_bus; ram ram(clk, we, addr, data, read_bus); always @(negedge clk) if (~we) begin $display("%d %d", addr, read_bus); if (read_bus !== addr[3:0]*addr[3:0]) fail=1; end endmodule iverilog-12_0/ivtest/ivltests/pr1664684.v000066400000000000000000000010331435245347300201320ustar00rootroot00000000000000// pr1664684 module bug (rdo, rm, cpen, up14, rdi); output [31:0] rdo; input rm, cpen; input [31:0] up14, rdi; initial $monitor($time,,rdo,,rm,cpen,,up14,,rdi); assign rdo = (rm | cpen) ? up14 : rdi; endmodule module bench; reg [31:0] up14; wire [31:0] rdo; reg rm, cpen; tri0 [31:0] rdi; bug u1 (rdo, rm, cpen, up14, rdi); initial begin rm = 1'bX; cpen = 1'b0; up14 = 'hX; #40; up14 = 32'd0; rm = 1'b0; #40; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1675789.v000066400000000000000000000021041435245347300201420ustar00rootroot00000000000000module main; parameter NIBBLE = 4; reg [NIBBLE*4-1:0] array [1:0]; reg [3:0] word; integer idx; initial begin for (idx = 0 ; idx < 4 ; idx = idx+1) begin array[0][idx*NIBBLE +: 4] = +idx; array[1][idx*NIBBLE +: 4] = -idx; end if (array[0] !== 16'h3210) begin $display("FAILED -- array[0] = %h", array[0]); $finish; end word = array[0][7:4]; if (word !== 4'h1) begin $display("FAILED == array[0][7:4] = %h", word); $finish; end word = array[1][7:4]; if (word !== 4'hf) begin $display("FAILED == array[0][7:4] = %h", word); $finish; end for (idx = 0 ; idx < 4 ; idx = idx+1) begin word = array[0][idx*NIBBLE +: 4]; if (word !== idx) begin $display("FAILED == array[0][nibble=%d] = %h", idx, word); $finish; end word = array[1][idx*NIBBLE +: 4]; if (word !== - idx[3:0]) begin $display("FAILED == array[1][nibble=%d] = %h", idx, word); $finish; end end // for (idx = 0 ; idx < 4 ; idx += 1) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1675789b.v000066400000000000000000000016311435245347300203100ustar00rootroot00000000000000module main; parameter WORD_WID = 3; parameter WORD_CNT = 8; reg [WORD_WID-1: 0] mem [0:WORD_CNT-1], tmp; integer idx, jdx; initial begin for (idx = 0 ; idx < WORD_CNT ; idx = idx+1) mem[idx] = idx; for (idx = 0 ; idx < WORD_CNT ; idx = idx+1) begin tmp = idx; if (mem[idx][2:1] !== tmp[2:1]) begin $display("FAILED -= mem[%d][2:1]=%b, tmp[2:1]=%b", idx, mem[idx][2:1], tmp[2:1]); $finish; end if (mem[idx][1:0] !== tmp[1:0]) begin $display("FAILED -= mem[%d][1:0]=%b, tmp[1:0]=%b", idx, mem[idx][1:0], tmp[1:0]); $finish; end for (jdx = 0 ; jdx < WORD_WID ; jdx = jdx+1) if (mem[idx][jdx +:2] !== tmp[jdx +:2]) begin $display("FAILED -- mem[%d][%d +:2]=%b, tmp[%d +:2]=%b", idx, jdx, mem[idx][jdx+:2], jdx, tmp[jdx+:2]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1676071.v000066400000000000000000000022551435245347300201320ustar00rootroot00000000000000`begin_keywords "1364-2005" `timescale 1ns / 1ns module gentest; reg [7:0] a=0, b=0; wire co; wire [7:0] result; adder work(a, b, 1'b0, result, co); integer cc; initial begin for (cc=0; cc<10; cc=cc+1) begin a=a+1; #10; $display("%d %d %d", a, b, result); b=result; end if (b==55) $display("PASSED"); else $display("FAIL"); end endmodule module adder(a, b, ci, out, co); parameter SIZE=8; input [SIZE-1:0] a; input [SIZE-1:0] b; input ci; output [SIZE-1:0] out; output co; wire [SIZE:0] c; assign c[0] = ci; assign co = c[SIZE]; `ifdef NOGENERATE add1 bit0(a[0], b[0], c[0], out[0], c[0+1]); add1 bit1(a[1], b[1], c[1], out[1], c[1+1]); add1 bit2(a[2], b[2], c[2], out[2], c[2+1]); add1 bit3(a[3], b[3], c[3], out[3], c[3+1]); add1 bit4(a[4], b[4], c[4], out[4], c[4+1]); add1 bit5(a[5], b[5], c[5], out[5], c[5+1]); add1 bit6(a[6], b[6], c[6], out[6], c[6+1]); add1 bit7(a[7], b[7], c[7], out[7], c[7+1]); `else genvar i; generate for(i=0; i> shift; wire [3:0] ls = foo << shift; wire tr = 4'b0100 > (foo >> shift); initial begin foo = 4'b1001; shift = 0; #1 if (rs !== 4'b1001 || ls !== 4'b1001) begin $display("FAILED -- shift=%d, rs=%b, ls=%b", shift, rs, ls); $finish; end shift = 1; #1 if (rs !== 4'b0100 || ls !== 4'b0010 || tr !== 0) begin $display("FAILED -- shift=%d, rs=%b, ls=%b", shift, rs, ls); $finish; end shift = 2; #1 if (rs !== 4'b0010 || ls !== 4'b0100 || tr !== 1) begin $display("FAILED -- shift=%d, rs=%b, ls=%b", shift, rs, ls); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1694413.v000066400000000000000000000004131435245347300201240ustar00rootroot00000000000000module test (); parameter fuse_a_msb = 4; parameter fuse_q_msb = (2**(fuse_a_msb+1))-1; initial begin if (fuse_q_msb != 'h1f) begin $display("FAILED -- fuse_q_msb = %d", fuse_q_msb); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1694427.v000066400000000000000000000006601435245347300201350ustar00rootroot00000000000000module test (); reg[7:0] a; reg b; always @* begin b = 1'b0; case (a) 8'd66: b = 1'b1; default: ; endcase end initial begin a = 0; #1 if (b !== 0) begin $display("FAILED -- a=%h b=%b", a, b); $finish; end a = 66; #1 if (b !== 1) begin $display("FAILED -- a=%h b=%b", a, b); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1695257.v000066400000000000000000000004431435245347300201360ustar00rootroot00000000000000module test(CL, Q_data, D); parameter Bits = 84; input CL; output [Bits-1 : 0] Q_data; input [Bits-1 : 0] D; reg WENreg; reg ICGFlag; specify specparam taa = 1.0; if (WENreg && !ICGFlag) (CL *> (Q_data[0] : D[0])) = (taa, taa); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1695309.v000066400000000000000000000010521435245347300201310ustar00rootroot00000000000000module main; genvar i; parameter MSB = 7; wire [MSB:0] Z; reg [MSB:0] A, B; generate for (i = 0; i <= MSB; i = i+1) begin: or2 OR2 uor2 (.A(A[i]), .B(B[i]), .Z(Z[i])); end endgenerate initial begin for (A = 0 ; A < 'hff ; A = A+1) for (B = 0 ; B < 'hff ; B = B+1) #1 if (Z !== (A|B)) begin $display("FAILED -- A=%h, B=%h, Z=%h", A, B, Z); $finish; end $display("PASSED"); end endmodule module OR2 (Z, A, B); output Z; input A; input B; or (Z, A, B); endmodule iverilog-12_0/ivtest/ivltests/pr1695322.v000066400000000000000000000006131435245347300201260ustar00rootroot00000000000000module test (); wire [5:0] a [0:2]; b b(.a(a[0])); initial begin #1 if (a[0] !== 5) begin $display("FAILED -- a[0] == %d", a[0]); $finish; end if (a[1] !== 6'bzzzzzz) begin $display("FAILED -- a[1] == %h", a[1]); $finish; end $display("PASSED"); end // initial begin endmodule module b (output wire [5:0] a); assign a = 5; endmodule iverilog-12_0/ivtest/ivltests/pr1695334.v000066400000000000000000000005001435245347300201240ustar00rootroot00000000000000module test(); parameter BITS = 4; parameter C = 1; wire [BITS-1:0] a; reg [BITS-1:0] a_bc; assign a = a_bc - 2*C; initial begin a_bc = 9; #1 if (a !== 7) begin $display("FAILED -- a_bc=%d, a=%d", a_bc, a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1696137.v000066400000000000000000000010671435245347300201370ustar00rootroot00000000000000//// //// The following was written to illustrate a bug in iverilog. //// In particular, this little lovely produces a 202 MB vvp file. //// module ExplodedArrays1; reg [7:0] data [0:25600-1]; integer idx; initial begin for (idx = 0 ; idx < 25600 ; idx = idx+1) data[idx] = idx[7:0]; for (idx = 0 ; idx < 256 ; idx = idx+ 1) begin if (data[idx] !== idx) begin $display("FAILED -- data[%d] = %d (%h)", idx, data[idx], data[idx]); $finish; end end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1697250.v000066400000000000000000000006531435245347300201340ustar00rootroot00000000000000// pr1697250 module test(); wire active; reg [63:0] bus; assign active = ((|(bus)===0)?0:1); initial begin bus = 'haaaa; #1 if (active !== 1) begin $display("FAILED -- bus=%h, active=%b", bus, active); $finish; end bus = 0; #1 if (active !== 0) begin $display("FAILED == bus=%h, active=%b", bus, active); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1697732.v000066400000000000000000000006531435245347300201410ustar00rootroot00000000000000module main; reg [3:0] value; reg [2:0] addr; wire test_bit = value[addr] == 1; initial begin value = 'b0110; for (addr = 0 ; addr < 4 ; addr = addr+1) begin #1 if (test_bit !== value[addr]) begin $display("FAILED -- value[%d]=%b, test_bit=%b", addr, value[addr], test_bit); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr1698499.v000066400000000000000000000071671435245347300201630ustar00rootroot00000000000000module sysSimpleTest(); reg CLK; reg RST_N; initial begin #0 RST_N = 1'b0; #1; CLK = 1'b1; $display("reset"); #1; RST_N = 1'b1; $display("reset done"); end always begin #5; CLK = 1'b0 ; #5; CLK = 1'b1 ; end // register y reg [98 : 0] y; wire [98 : 0] y$D_IN; wire y$EN; // register z reg [98 : 0] z; wire [98 : 0] z$D_IN; wire z$EN; // remaining internal signals wire [98 : 0] IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT_0_AND__ETC___d29, IF_y_SLT_0_THEN_NEG_IF_y_SLT_0_THEN_NEG_y_0_EL_ETC___d28, IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_QUOT_IF_z_SLT_ETC___d30, IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_REM_IF_z_SLT__ETC___d31, x__h201, y__h141, z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d17; wire y_SLT_0___d33, z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d22, z_SLT_0___d32; // register y assign y$D_IN = 99'h0 ; assign y$EN = 1'b0 ; // register z assign z$EN = 1'b0 ; assign z$D_IN = 99'h0 ; // remaining internal signals assign IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT_0_AND__ETC___d29 = (y_SLT_0___d33 && !z_SLT_0___d32 || !y_SLT_0___d33 && z_SLT_0___d32) ? -IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_QUOT_IF_z_SLT_ETC___d30 : IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_QUOT_IF_z_SLT_ETC___d30 ; assign IF_y_SLT_0_THEN_NEG_IF_y_SLT_0_THEN_NEG_y_0_EL_ETC___d28 = y_SLT_0___d33 ? -IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_REM_IF_z_SLT__ETC___d31 : IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_REM_IF_z_SLT__ETC___d31 ; assign IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_QUOT_IF_z_SLT_ETC___d30 = x__h201 / y__h141 ; assign IF_y_SLT_0_THEN_NEG_y_0_ELSE_y_1_REM_IF_z_SLT__ETC___d31 = x__h201 % y__h141 ; assign x__h201 = y_SLT_0___d33 ? -y : y ; assign y_SLT_0___d33 = (y ^ 99'h4000000000000000000000000) < 99'h4000000000000000000000000 ; assign y__h141 = z_SLT_0___d32 ? -z : z ; assign z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d17 = z * IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT_0_AND__ETC___d29 ; assign z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d22 = z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d17 + IF_y_SLT_0_THEN_NEG_IF_y_SLT_0_THEN_NEG_y_0_EL_ETC___d28 == y ; assign z_SLT_0___d32 = (z ^ 99'h4000000000000000000000000) < 99'h4000000000000000000000000 ; // handling of inlined registers always@(posedge CLK) begin if (!RST_N) begin // y <= 1; // z <= 1; y <= 99'h7FFFFFF04A62A1453402211B2; z <= 99'h000000023E84321AAFCCC70C2; end else begin if (y$EN) y <= y$D_IN; if (z$EN) z <= z$D_IN; end end // synopsys translate_off initial begin y = 99'h2AAAAAAAAAAAAAAAAAAAAAAAA; z = 99'h2AAAAAAAAAAAAAAAAAAAAAAAA; end // synopsys translate_on // handling of system tasks // synopsys translate_off always@(negedge CLK) begin #0; if (RST_N) if (z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d22) $display("OK: %0d * %0d + %0d == %0d", $signed(z), $signed(IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT_0_AND__ETC___d29), $signed(IF_y_SLT_0_THEN_NEG_IF_y_SLT_0_THEN_NEG_y_0_EL_ETC___d28), $signed(y)); if (RST_N) if (!z_MUL_IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT__ETC___d22) $display("BAD: %0d * %0d + %0d != %0d", $signed(z), $signed(IF_y_SLT_0_AND_NOT_z_SLT_0_OR_NOT_y_SLT_0_AND__ETC___d29), $signed(IF_y_SLT_0_THEN_NEG_IF_y_SLT_0_THEN_NEG_y_0_EL_ETC___d28), $signed(y)); if (RST_N) $finish(32'd0); end // synopsys translate_on endmodule // sysSimpleTest iverilog-12_0/ivtest/ivltests/pr1698658.v000066400000000000000000000002731435245347300201470ustar00rootroot00000000000000`timescale 1ns/10ps module top; initial begin $timeformat(-6, 0, " uS", 8); #10 $display("The time is %t", $time); #1000 $display("The time is %t", $time); end endmodule iverilog-12_0/ivtest/ivltests/pr1698659.v000066400000000000000000000014131435245347300201450ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg topvar; initial begin topvar = 0; lwr.lowervar = 1; lwr.elwr.evenlowervar = 0; othertop.othertopvar = 1; #10 $display("%m var is (%b)", topvar); end lower lwr(); endmodule module lower; reg lowervar; initial begin #11 $display("%m var is (%b)", lowervar); end evenlower elwr(); endmodule module evenlower; reg evenlowervar; initial begin #12 $display("%m var is (%b)", evenlowervar); $display("Up reference to me (%b)", elwr.evenlowervar); $display("Up reference to parent (%b)", lwr.lowervar); $display("Up reference is (%b)", lower.lowervar); end endmodule module othertop; reg othertopvar; initial begin #20 $display("%m var is (%b)", othertopvar); end endmodule iverilog-12_0/ivtest/ivltests/pr1698820.v000066400000000000000000000010171435245347300201330ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [4:0] var; integer fp; initial begin var = 10; fp = 1; $fdisplay(fp, "The variable is ",var); $fdisplayb(fp, "The variable is ",var); $fdisplayo(fp, "The variable is ",var); $fdisplayh(fp, "The variable is ",var); $fwrite(fp, "The variable is ",var, "\n"); $fwriteb(fp, "The variable is ",var, "\n"); $fwriteo(fp, "The variable is ",var, "\n"); $fwriteh(fp, "The variable is ",var, "\n"); $fclose(fp); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1699444.v000066400000000000000000000001761435245347300201430ustar00rootroot00000000000000module top; initial begin $display("Output a slash \\."); $display("Output a double slash \\\\."); end endmodule iverilog-12_0/ivtest/ivltests/pr1699519.v000066400000000000000000000005241435245347300201430ustar00rootroot00000000000000module top; real rval; reg [7:0] rgval; initial begin rgval = 8'ha5; rval = 1234567890; $display("Checking h and H: %h, %H", rgval, rgval); $display("Checking x and X: %x, %X", rgval, rgval); $display("Checking g and G: %g, %G", rval, rval); $display("Checking e and E: %e, %E", rval, rval); end endmodule iverilog-12_0/ivtest/ivltests/pr1701855.v000066400000000000000000000013061435245347300201250ustar00rootroot00000000000000`timescale 1us/1ns module top; initial begin // This should print the following: // Time scale of (top) is 1us / 1ns // Time scale of (top) is 1us / 1ns // Time scale of (top.dut) is 10ns / 10ps // Time scale of (top.dut.dut) is 1ns / 10ps // Time scale of (othertop) is 1ms / 1us // But currently the precisions will all be 10ps the finest precision. $printtimescale; $printtimescale(); $printtimescale(dut); $printtimescale(dut.dut); $printtimescale(othertop); end lower dut(); endmodule `timescale 10ns/10ps module lower; evenlower dut(); endmodule `timescale 1ns/10ps module evenlower; endmodule `timescale 1ms/1us module othertop; endmodule iverilog-12_0/ivtest/ivltests/pr1701855b.v000066400000000000000000000033001435245347300202630ustar00rootroot00000000000000`timescale 100ns/100ps module dummy; parameter [1:0] ipval = 2; endmodule `timescale 1us/1ns module top; parameter [1:0] ipval = 2; parameter spval = "Help"; parameter rpval = 1.0; event evt; reg [1:0] rgval; reg rgarr [2:0]; wire [1:0] wval; wire warr [2:0]; integer ival; real rval; real rarr [2:0]; time tval; initial begin:blk $printtimescale(dummy); $printtimescale(dummy.ipval); // These should all print a timescale of 1us / 1ns. $printtimescale; $printtimescale(top.ipval); /* This does not currently work because Icarus does not know how * to keep the parameter reference in the part select. For now * it just returns a constant which the runtime will complain * does not have a vpiModule. */ // $printtimescale(top.ipval[0]); $printtimescale(top.spval); /* The same goes here. */ // $printtimescale(top.spval[0]); $printtimescale(top.rpval); $printtimescale(top.evt); $printtimescale(top.rgval); $printtimescale(top.rgval[0]); $printtimescale(top.rgarr); $printtimescale(top.rgarr[0]); $printtimescale(top.wval); $printtimescale(top.wval[0]); $printtimescale(top.warr); $printtimescale(top.warr[0]); $printtimescale(top.ival); $printtimescale(top.ival[1]); $printtimescale(top.rval); $printtimescale(top.rarr); $printtimescale(top.rarr[0]); $printtimescale(top.tval); $printtimescale(top.blk); $printtimescale(top.frk); $printtimescale(top.tsk); $printtimescale(top.fnc); end initial fork:frk $write(""); join task tsk; begin end endtask function integer fnc; input integer tmp; fnc = 2 * tmp; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1701889.v000066400000000000000000000020731435245347300201360ustar00rootroot00000000000000module top; time ioffset, ifuture; realtime offset, future; initial begin offset = 1.0; ioffset = 1; future = 20.0; ifuture = 120; #1; $display("----- Using real times -----"); $display("The time one unit ago was : %t", $realtime - 1.0); $display("The time one unit ago was : %t", $realtime - offset); $display("The time now is : %t", $realtime); $display("One time unit from now it will be: %t", $realtime + 1.0); $display("The time at 20 will be : %t", future); $display("The time at 40 will be : %t", 40.0); #100; $display("\n----- Using integer times -----"); $display("The time one unit ago was : %t", $time - 1); $display("The time one unit ago was : %t", $time - ioffset); $display("The time now is : %t", $time); $display("One time unit from now it will be: %t", $time + 1); $display("The time at 120 will be : %t", ifuture); $display("The time at 140 will be : %t", 140); end endmodule iverilog-12_0/ivtest/ivltests/pr1701890.v000066400000000000000000000002461435245347300201260ustar00rootroot00000000000000module top; real rval1=1.0, rval2=2.0; realtime rtval=1.0; initial begin $display("rval1=", rval1,,"rval2=", rval2,,"rtval=",rtval); end endmodule iverilog-12_0/ivtest/ivltests/pr1701921.v000066400000000000000000000006551435245347300201250ustar00rootroot00000000000000// pr1701921 module top; reg foo, bar; wire blend; assign blend = foo; assign blend = bar; initial begin bar = 1; // Bar explicitly has a 1 value, foo gets its initial x value. // Together, they should drive to an x value. #1 if (blend !== 1'bx) begin $display("FAILED -- blend=%b (foo=%b, bar=%b)", blend, foo, bar); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1702593.v000066400000000000000000000002211435245347300201200ustar00rootroot00000000000000module top; integer ival=-1; initial begin $display("The value is %5.2f", ival); $display("The value is %5.2f", -1); end endmodule iverilog-12_0/ivtest/ivltests/pr1703120.v000066400000000000000000000021761435245347300201160ustar00rootroot00000000000000module top; integer ival; real rval; initial begin $display("--- Printing as real ---"); $display("1/0 is %f. (Should be 0 -- x prints as 0)", 1/0); $display("1/0.0 is %f. (Should be inf)", 1/0.0); $display("1.0/0 is %f. (Should be inf)", 1.0/0); $display("1.0/0.0 is %f. (should be inf)", 1.0/0.0); // Moving these two lines before the previous four lines makes 1/0 print // a large number, but not inf! rval = 0.0; ival = 0; $display("1/integer zero is %f. (Should be 0 -- x prints as 0)", 1/ival); $display("1/real zero is %f. (should be inf)", 1/rval); $display("1.0/integer zero is %f. (Should be inf)", 1.0/ival); $display("1.0/real zero is %f.", 1.0/rval); $display("\n--- Printing as integer ---"); $display("1/0 is %d (Should be x)", 1/0); $display("1/0.0 is %d", 1/0.0); $display("1.0/0 is %d", 1.0/0); $display("1.0/0.0 is %d", 1.0/0.0); $display("1/integer zero is %d. (Should be x)", 1/ival); $display("1/real zero is %d.", 1/rval); $display("1.0/integer zero is %d.", 1.0/ival); $display("1.0/real zero is %d.", 1.0/rval); end endmodule iverilog-12_0/ivtest/ivltests/pr1703346.v000066400000000000000000000010711435245347300201210ustar00rootroot00000000000000module main; wire [1:0] foo [0:1]; assign (highz0, strong1) foo[0] = 2'b01; assign (strong0, highz1) foo[0] = 2'b01; assign (highz0, strong1) foo[1] = 2'b10; assign (strong0, highz1) foo[1] = 2'b10; initial begin #1 $display("foo[0] = %b, foo[1] = %b", foo[0], foo[1]); if (foo[0] !== 2'b01) begin $display("FAILED -- foo[0] = %b", foo[0]); $finish; end if (foo[1] !== 2'b10) begin $display("FAILED == foo[1] = %b", foo[1]); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1703959.v000066400000000000000000000005431435245347300201360ustar00rootroot00000000000000// pr1703959 module test(); ma ia (.IO(b), .ZI(c)); mb ib( .b({b}), .c({c})); // mb ib( .b(b), .c(c)); initial #10 $display("PASSED"); endmodule module ma(ZI,IO); inout ZI; inout IO; pmos (ZI, IO, 1'b0); // pmos (IO, ZI, 1'b0); endmodule module mb ( b, c); // input b; output b; input c; // inout b; // inout c; endmodule // mb iverilog-12_0/ivtest/ivltests/pr1704013.v000066400000000000000000000003521435245347300201120ustar00rootroot00000000000000module top; reg clk = 0; reg [1:0] in = 2'b00; wire [1:0] out; test t1 (clk, out, in); endmodule module test(clk, a, b); input clk; output a; input [1:0] b; reg [1:0] a; always @(posedge clk) begin a <= b; end endmodule iverilog-12_0/ivtest/ivltests/pr1704726a.v000066400000000000000000000032501435245347300202660ustar00rootroot00000000000000module top; /*********** * Check parameters. ***********/ // Check parameter/parameter name issues. parameter name_pp = 1; parameter name_pp = 0; parameter name_pl = 1; localparam name_pl = 0; localparam name_lp = 0; parameter name_lp = 1; localparam name_ll = 1; localparam name_ll = 0; /*********** * Check genvars. ***********/ // Check genvar/genvar name issues. genvar name_vv; genvar name_vv; /*********** * Check tasks. ***********/ // Check task/task name issues. task name_tt; $display("FAILED in task name_tt(a)"); endtask task name_tt; $display("FAILED in task name_tt(b)"); endtask // Check that task/task checks work in a generate block. generate begin: task_blk task name_tt; $display("FAILED in task name_tt(a)"); endtask task name_tt; $display("FAILED in task name_tt(b)"); endtask end endgenerate /*********** * Check functions. ***********/ // Check function/function name issues. function name_ff; input in; name_ff = in; endfunction function name_ff; input in; name_ff = 2*in; endfunction // Check that function/function checks work in a generate block. generate begin: task_blk function name_ff; input in; name_ff = in; endfunction function name_ff; input in; name_ff = 2*in; endfunction end endgenerate /*********** * Check named events ***********/ // Check named event/named event name issues. event name_ee; event name_ee; initial name_tt; specify specparam name_ss = 1; specparam name_ss = 0; endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1704726b.v000066400000000000000000000057001435245347300202710ustar00rootroot00000000000000module top; reg pass = 1'b1; parameter parm = 1; /*********** * Check generate tasks. ***********/ // Only one is created. generate if (parm) begin: name_ti task name_task; $display("OK in task from scope name_ti"); endtask end else begin: name_ti task name_task; begin $display("FAILED in task from scope name_ti"); pass = 1'b0; end endtask end endgenerate // Again only one is created. generate case (parm) 1: begin: name_tc task name_task; $display("OK in task from scope name_tc"); endtask end default: begin: name_tc task name_task; begin $display("FAILED in task from scope name_tc"); pass = 1'b0; end endtask end endcase endgenerate // Two are created, but they are in a different scope. genvar lpt; generate for (lpt = 0; lpt < 2; lpt = lpt + 1) begin: name_tf task name_task; $display("OK in task from scope name_tf[%0d]", lpt); endtask end endgenerate /*********** * Check functions. ***********/ // Only one is created. generate if (parm) begin: name_fi function name_func; input in; name_func = ~in; endfunction end else begin: name_fi function name_func; input in; name_func = in; endfunction end endgenerate // Again only one is created. generate case (parm) 1: begin: name_fc function name_func; input in; name_func = ~in; endfunction end default: begin: name_fc function name_func; input in; name_func = in; endfunction end endcase endgenerate // Two are created, but they are in a different scope. genvar lpf; generate for (lpf = 0; lpf < 2; lpf = lpf + 1) begin: name_ff function name_func; input in; name_func = (lpf % 2) ? in : ~in ; endfunction end endgenerate initial begin name_ti.name_task; name_tc.name_task; name_tf[0].name_task; name_tf[1].name_task; if (name_fi.name_func(1'b1) !== 1'b0) begin $display("FAILED in function from scope name_fi"); pass = 1'b0; end else $display("OK in function from scope name_fi"); if (name_fc.name_func(1'b1) !== 1'b0) begin $display("FAILED in function from scope name_fc"); pass = 1'b0; end else $display("OK in function from scope name_fc"); if (name_ff[0].name_func(1'b1) !== 1'b0) begin $display("FAILED in function from scope name_ff[0]"); pass = 1'b0; end else $display("OK in function from scope name_ff[0]"); if (name_ff[1].name_func(1'b1) !== 1'b1) begin $display("FAILED in function from scope name_ff[1]"); pass = 1'b0; end else $display("OK in function from scope name_ff[1]"); if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1704726c.v000066400000000000000000000310011435245347300202630ustar00rootroot00000000000000module top; parameter parm = 1; parameter name_v = 1; // genvar localparam name_lpv = 0; // genvar parameter name_t = 1; // task parameter name_f = 1; // function parameter name_i = 1; // module instance parameter name_b = 1; // named block parameter name_gl = 1; // generate block loop parameter name_gi = 1; // generate block if parameter name_gc = 1; // generate block case parameter name_gb = 1; // generate block parameter name_e = 1; // named event parameter name_s = 1; // signal wire [1:0] out; /*********** * Check genvars ***********/ // Check genvar/parameter name issues. genvar name_v; generate for (name_v = 0; name_v < 2; name_v = name_v + 1) begin assign out[name_v] = name_v; end endgenerate // Check genvar/localparam name issues. genvar name_lpv; generate for (name_lpv = 0; name_lpv < 2; name_lpv = name_lpv + 1) begin assign out[name_lpv] = name_lpv; end endgenerate // Check genvar/genvar name issues. // This is in a different file since this fails during parsing. /*********** * Check tasks. ***********/ // Check task/parameter name issues. task name_t; $display("FAILED in task name_t"); endtask // Check task/task name issues. // This is in a different file since this fails during parsing. // Check task/genvar name issues. genvar name_tv; generate for (name_tv = 0; name_tv < 2; name_tv = name_tv + 1) begin assign out[name_tv] = name_tv; end endgenerate task name_tv; $display("FAILED in task name_tv"); endtask /*********** * Check functions. ***********/ // Check function/parameter name issues. function name_f; input in; name_f = in; endfunction // Check function/task name issues. task name_ft; $display("FAILED in task name_ft"); endtask function name_ft; input in; name_tf = in; endfunction // Check function/function name issues. // This is in a different file since this fails during parsing. // Check function/genvar name issues. genvar name_fv; generate for (name_fv = 0; name_fv < 2; name_fv = name_fv + 1) begin assign out[name_fv] = name_fv; end endgenerate function name_fv; input in; name_fv = in; endfunction /*********** * Check module instances. ***********/ // Check modul instance/parameter name issues. test name_i(out[0]); // Check module instance/task name issues. task name_it; $display("FAILED in task name_it"); endtask test name_it(out[0]); // Check module instance/function name issues. function name_if; input in; name_if = in; endfunction test name_if(out[0]); // Check module instance/genvar name issues. genvar name_iv; generate for (name_iv = 0; name_iv < 2; name_iv = name_iv + 1) begin assign out[name_iv] = name_iv; end endgenerate test name_iv(out[1]); // Check module instance/module instance name issues. test name_ii(out[0]); test name_ii(out[1]); /*********** * Check named blocks. ***********/ // Check named block/parameter name issues. initial begin: name_b $display("FAILED in name_b"); end // Check named block/task name issues. task name_bt; $display("FAILED in task name_bt"); endtask initial begin: name_bt $display("FAILED in name_bt"); end // Check named block/function name issues. function name_bf; input in; name_bf = in; endfunction initial begin: name_bf $display("FAILED in name_bf"); end // Check named block/genvar name issues. genvar name_bv; generate for (name_bv = 0; name_bv < 2; name_bv = name_bv + 1) begin assign out[name_bv] = name_bv; end endgenerate initial begin: name_bv $display("FAILED in name_bv"); end // Check named block/module instance name issues. test name_bi(out[0]); initial begin: name_bi $display("FAILED in name_bi"); end // Check named block/named block name issues. initial begin: name_bb $display("FAILED in name_bb(a)"); end initial begin: name_bb $display("FAILED in name_bb(b)"); end /*********** * Check named events ***********/ // Check named event/parameter name issues. event name_e; // Check named event/task name issues. task name_et; $display("FAILED in task name_et"); endtask event name_et; // Check named event/function name issues. function name_ef; input in; name_ef = in; endfunction event name_ef; // Check named event/genvar name issues. genvar name_ev; generate for (name_ev = 0; name_ev < 2; name_ev = name_ev + 1) begin assign out[name_ev] = name_ev; end endgenerate event name_ev; // Check named event/module instance name issues. test name_ei(out[0]); event name_ei; // Check named event/named block name issues. initial begin: name_eb $display("FAILED in name_eb"); end event name_eb; // Check named event/named event name issues. // This is in a different file since this fails during parsing. /*********** * Check generate loop blocks ***********/ genvar i; // Check generate loop/parameter name issues. generate for (i = 0; i < 2; i = i + 1) begin: name_gl assign out[i] = i; end endgenerate // Check generate loop/task name issues. task name_glt; $display("FAILED in task name_glt"); endtask generate for (i = 0; i < 2; i = i + 1) begin: name_glt assign out[i] = i; end endgenerate // Check generate loop/function name issues. function name_glf; input in; name_glf = in; endfunction generate for (i = 0; i < 2; i = i + 1) begin: name_glf assign out[i] = i; end endgenerate // Check generate loop/genvar name issues. genvar name_glv; generate for (name_glv = 0; name_glv < 2; name_glv = name_glv + 1) begin assign out[name_glv] = name_glv; end endgenerate generate for (i = 0; i < 2; i = i + 1) begin: name_glv assign out[i] = i; end endgenerate // Check generate loop/module instance name issues. test name_gli(out[0]); generate for (i = 0; i < 2; i = i + 1) begin: name_gli assign out[i] = i; end endgenerate // Check generate loop/named block name issues. initial begin: name_glb $display("FAILED in name_glb"); end generate for (i = 0; i < 2; i = i + 1) begin: name_glb assign out[i] = i; end endgenerate // Check generate loop/named event name issues. event name_gle; generate for (i = 0; i < 2; i = i + 1) begin: name_gle assign out[i] = i; end endgenerate // Check generate loop/generate loop name issues. generate for (i = 0; i < 2; i = i + 1) begin: name_glgl assign out[i] = i; end endgenerate generate for (i = 0; i < 2; i = i + 1) begin: name_glgl assign out[i] = i; end endgenerate /*********** * Check generate if blocks ***********/ // Check generate if/parameter name issues. generate if (parm == 1) begin: name_gi assign out[1] = 1; end endgenerate // Check generate if/task name issues. task name_git; $display("FAILED in task name_git"); endtask generate if (parm == 1) begin: name_git assign out[1] = 1; end endgenerate // Check generate if/function name issues. function name_gif; input in; name_gif = in; endfunction generate if (parm == 1) begin: name_gif assign out[1] = 1; end endgenerate // Check generate if/genvar name issues. genvar name_giv; generate for (name_giv = 0; name_giv < 2; name_giv = name_giv + 1) begin assign out[name_giv] = name_giv; end endgenerate generate if (parm == 1) begin: name_giv assign out[1] = 1; end endgenerate // Check generate if/module instance name issues. test name_gii(out); generate if (parm == 1) begin: name_gii assign out[1] = 1; end endgenerate // Check generate if/named block name issues. initial begin: name_gib $display("FAILED in name_gib"); end generate if (parm == 1) begin: name_gib assign out[1] = 1; end endgenerate // Check generate if/named event name issues. event name_gie; generate if (parm == 1) begin: name_gie assign out[1] = 1; end endgenerate // Check generate if/generate if name issues. generate if (parm == 1) begin: name_gigi assign out[1] = 1; end endgenerate generate if (parm == 1) begin: name_gigi assign out[1] = 0; end endgenerate /*********** * Check generate case blocks ***********/ // Check generate case/parameter name issues. generate case (parm) 1: begin: name_gc assign out[1] = 1; end default: begin: name_gc assign out[1] = 0; end endcase endgenerate // Check generate case/task name issues. task name_gct; $display("FAILED in task name_gct"); endtask generate case (parm) 1: begin: name_gct assign out[1] = 1; end default: begin: name_gct assign out[1] = 0; end endcase endgenerate // Check generate case/function name issues. function name_gcf; input in; name_gcf = in; endfunction generate case (parm) 1: begin: name_gcf assign out[1] = 1; end default: begin: name_gcf assign out[1] = 0; end endcase endgenerate // Check generate case/genvar name issues. genvar name_gcv; generate for (name_gcv = 0; name_gcv < 2; name_gcv = name_gcv + 1) begin assign out[name_gcv] = name_gcv; end endgenerate generate case (parm) 1: begin: name_gcv assign out[1] = 1; end default: begin: name_gcv assign out[1] = 0; end endcase endgenerate // Check generate case/module instance name issues. test name_gci(out[0]); generate case (parm) 1: begin: name_gci assign out[1] = 1; end default: begin: name_gci assign out[1] = 0; end endcase endgenerate // Check generate case/named block name issues. initial begin: name_gcb $display("FAILED in name_gcb"); end generate case (parm) 1: begin: name_gcb assign out[1] = 1; end default: begin: name_gcb assign out[1] = 0; end endcase endgenerate // Check generate case/named event name issues. event name_gce; generate case (parm) 1: begin: name_gce assign out[1] = 1; end default: begin: name_gce assign out[1] = 0; end endcase endgenerate // Check generate case/generate case name issues. generate case (parm) 1: begin: name_gcgc assign out[1] = 1; end default: begin: name_gcgc assign out[1] = 0; end endcase endgenerate generate case (parm) 1: begin: name_gcgc assign out[1] = 1; end default: begin: name_gcgc assign out[1] = 0; end endcase endgenerate /*********** * Check generate blocks (from 1364-2001) ***********/ // Check generate block/parameter name issues. generate begin: name_gb assign out[0] = 0; end endgenerate // Check generate block/task name issues. task name_gbt; $display("FAILED in task name_gbt"); endtask generate begin: name_gbt assign out[0] = 0; end endgenerate // Check generate block/function name issues. function name_gbf; input in; name_gbf = in; endfunction generate begin: name_gbf assign out[0] = 0; end endgenerate // Check generate block/genvar name issues. genvar name_gbv; generate for (name_gbv = 0; name_gbv < 2; name_gbv = name_gbv + 1) begin assign out[name_gbv] = name_gbv; end endgenerate generate begin: name_gbv assign out[0] = 0; end endgenerate // Check generate block/module instance name issues. test name_gbi(out[0]); generate begin: name_gbi assign out[0] = 0; end endgenerate // Check generate block/named block name issues. initial begin: name_gbb $display("FAILED in name_gbb"); end generate begin: name_gbb assign out[0] = 0; end endgenerate // Check generate case/named event name issues. event name_gbe; generate begin: name_gbe assign out[0] = 0; end endgenerate // Check generate case/generate case name issues. generate begin: name_gbgb assign out[0] = 0; end endgenerate generate begin: name_gbgb assign out[0] = 0; end endgenerate initial $display("FAILED"); endmodule module test(out); output out; reg out = 1'b0; endmodule iverilog-12_0/ivtest/ivltests/pr1704726d.v000066400000000000000000000033731435245347300202770ustar00rootroot00000000000000module top; parameter parm = 1; parameter name0_s = 1; // signal wire [1:0] out; /*********** * Check signals ***********/ // Check signal/parameter name issues. wire name0_s; // Check signal/genvar name issues. genvar name0_v; generate for (name0_v = 0; name0_v < 2; name0_v = name0_v + 1) begin assign out[name0_v] = name0_v; end endgenerate wire name0_v; // Check signal/task name issues. task name1_st; $display("FAILED in task name1_st"); endtask wire name1_st; // Check signal/function name issues. function name2_sf; input in; name2_sf = in; endfunction wire name2_sf; // Check signal/module instance name issues. test name3_si(out[0]); wire name3_si; // Check signal/named block name issues. initial begin: name4_sb $display("FAILED in name4_sb"); end wire name4_sb; // Check signal/named event name issues. event name5_se; wire name5_se; // Check signal/generate loop name issues. genvar i; generate for (i = 0; i < 2 ; i = i + 1) begin: name6_sgl assign out[i] = i; end endgenerate wire name6_sgl; // Check signal/generate if name issues. generate if (parm == 1) begin: name7_sgi assign out[1] = 1; end endgenerate wire name7_sgi; // Check signal/generate case name issues. generate case (parm) 1: begin: name8_sgc assign out[1] = 1; end default: begin: name8_sgc assign out[1] = 0; end endcase endgenerate wire name8_sgc; // Check signal/generate block name issues. generate begin: name9_sgb assign out[0] = 0; end endgenerate wire name9_sgb; initial $display("FAILED"); endmodule module test(out); output out; reg out = 1'b0; endmodule iverilog-12_0/ivtest/ivltests/pr1705027.v000066400000000000000000000001341435245347300201160ustar00rootroot00000000000000module test(); // wire r; a ua ( .r ( !r )); endmodule module a ( r ); input r; endmodule iverilog-12_0/ivtest/ivltests/pr1716276.v000066400000000000000000000034151435245347300201330ustar00rootroot00000000000000/* This incorrect code causes iverilog 20070421 and earlier to dump core. $ iverilog -t null empty_param.v Segmentation Fault - core dumped */ module param_test (clk, reset_n, test_expr); parameter severity_level = 1; parameter width = 32; parameter property_type = 0; input clk, reset_n; input [width-1:0] test_expr; endmodule module empty_param; reg clk; reg [3:0] fsm; // An empty parameter like is easy to cause with an undefined macro // expanding to null param_test #( , 4) submod(clk, 1'b1, fsm); initial begin if (submod.severity_level !== 1) begin $display("FAILED -- severity_level = %d", submod.severity_level); $finish; end if (submod.width !== 4) begin $display("FAILED -- width = %d", submod.width); $finish; end if (submod.property_type !== 0) begin $display("FAILED -- property_type = %d", submod.property_type); $finish; end $display("PASSED"); $finish; end // initial begin endmodule /* Copyright (C) 1999 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * n * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * */ iverilog-12_0/ivtest/ivltests/pr1717361.v000066400000000000000000000006021435245347300201220ustar00rootroot00000000000000module adding; reg signed [20:0] s3, s4; reg signed [21:0] t1, t2; reg clk; initial begin clk=0; s3=+400000; s4=+200000; #10; clk=1; #10; $display("%d %d", t1, t2); clk=0; s3=-400000; s4=-200000; #10; clk=1; #10; $display("%d %d", t1, t2); $display("%s", (t1==t2) ? "PASSED" : "FAIL"); end always @(posedge clk) begin t1 <= s3 + 2*s4; t2 <= s3 + s4*2; end endmodule iverilog-12_0/ivtest/ivltests/pr1719055.v000066400000000000000000000027621435245347300201350ustar00rootroot00000000000000module array_assign(); parameter MSB = 1; integer ii; reg signed [2:0] ar_reg[0:MSB]; wire signed [4:0] as_wr; // compiled with "-g2 -g2x" // FAILED at this line assign as_wr = {{2{ar_reg[0][2]}},ar_reg[1]}; always @(as_wr) for(ii=0; ii<(MSB+1); ii=ii+1) begin $display(" %t ar_reg=%0d w_assign=%0d", $time, ar_reg[ii], as_wr); $display(" %t ar_reg[0]=3'b%3b ar_reg[1]=3'b%3b", $time, ar_reg[0], ar_reg[1]); $display(" %t as_wr=5'b%5b", $time, as_wr); end initial begin $display("\n*** module %m **************************************"); #10; for(ii=0; ii<(MSB+1); ii=ii+1) ar_reg[ii] <= 3'sd1; #10; for(ii=0; ii<(MSB+1); ii=ii+1) ar_reg[ii] <= 3'sd0; $display("\n\n"); end endmodule /* expected output - START module array_assign 10 ar_reg=1 w_assign=1 10 ar_reg[0]=3'b001 ar_reg[1]=3'b001 10 as_wr=5'b00001 10 ar_reg=1 w_assign=1 10 ar_reg[0]=3'b001 ar_reg[1]=3'b001 10 as_wr=5'b00001 20 ar_reg=0 w_assign=0 20 ar_reg[0]=3'b000 ar_reg[1]=3'b000 20 as_wr=5'b00000 20 ar_reg=0 w_assign=0 20 ar_reg[0]=3'b000 ar_reg[1]=3'b000 20 as_wr=5'b00000 expected output - END */ iverilog-12_0/ivtest/ivltests/pr1723367.v000066400000000000000000000210151435245347300201260ustar00rootroot00000000000000/** * Author: Evan Lavelle, Riverside Machines Ltd. * Version: 0.1 (2007-05-22) * Licence: This code is released into the public domain. * * Test implicit Verilog-95 style ports. According to 12.3.2 of the 2005 * LRM: * * "The port reference for each port in the list of ports at the top of each * module declaration can be one of the following: * * A simple identifier or escaped identifier * A bit-select of a vector declared within the module * A part-select of a vector declared within the module * A concatenation of any of the above * * The port expression is optional because ports can be defined that do not * connect to anything internal to the module." * * The expected output is: * * sum[ 1] = 0101010101100000 * sum[ 2] = 0101010101100000 * sum[ 3] = 0101010101100000 * sum[ 4] = 0101010101100000 * sum[ 5] = 0101010101100000 * sum[ 6] = 0101010101100000 * sum[ 7] = 0101010101100000 * sum[ 8] = 0101010101100000 * sum[ 9] = 0101010101100000 * sum[ 10] = 0101010101100000 * sum[ 11] = 0101010101100000 * sum[ 12] = 0101010101100000 * sum[ 13] = 0101010101100000 * sum[ 14] = 0101010101100000 * sum[ 15] = 0101010101100000 * sum[ 16] = 0101010101100000 * sum[ 17] = 0101010101100000 * sum[ 18] = 0101010101100000 * sum[ 19] = 0101010101100000 * sum[ 20] = 0101010101100000 * sum[ 21] = 0101010101100000 * sum[ 22] = 0101010101100000 * sum[ 23] = 0101010101100000 * */ module test; reg [15:0] sum[23:1]; wire [7:0] data = 1; wire dummy1, dummy2; wire [15:0] wire5, wire9, wire13, wire17, wire21; initial main; task main; integer i; begin for(i=1; i<=23; i=i+1) sum[i] = 'h555f; #2; sum[5] = wire5; sum[9] = wire9; sum[13] = wire13; sum[17] = wire17; sum[21] = wire21; for(i=1; i<=23; i=i+1) $display("sum[%d] = %b", i, sum[i]); end endtask m1 m1(); m2 m2(dummy1, dummy2); m3 m3(dummy1, , dummy2); m4 m4(data); m5 m5(data, wire5); m6 m6(dummy1, data); m7 m7(data, ); m8 m8 (data); m9 m9 (data, wire9); m10 m10( , data); m11 m11(data, ); m12 m12(data[0]); m13 m13(data[0], wire13); m14 m14( , data[0]); m15 m15(data[0], ); m16 m16(data); m17 m17(data, wire17); m18 m18(dummy1, data); m19 m19(data, ); m20 m20(data); m21 m21(data, wire21); m22 m22(dummy1, data); m23 m23(data, ); endmodule /* ---------------------------------------------------------------------------- * the test modules * ------------------------------------------------------------------------- */ // 95, no ports module m1; initial #1 test.sum[1] = test.sum[1] + test.data; endmodule // 95, two ports, but neither has an internal connection module m2(,); initial #1 test.sum[2] = test.sum[2] + test.data; endmodule // 95, three ports, but none have an internal connection module m3(,,); initial #1 test.sum[3] = test.sum[3] + test.data; endmodule /* ---------------------------------------------------------------------------- * 95, one and two ports, with implicit and simple identifiers * ------------------------------------------------------------------------- */ // 95, one implicit port, simple identifier module m4(a); input a; wire [7:0] a; initial #1 test.sum[4] = test.sum[4] + a; endmodule // 95, two implicit ports, simple identifiers module m5(a, b); input a; output b; wire [7:0] a; reg [15:0] b; initial #1 b <= test.sum[5] + a; endmodule // 95, two ports; the first has no internal connection; the second is implicit/ // simple module m6(,a); input a; wire [7:0] a; initial #1 test.sum[6] = test.sum[6] + a; endmodule // 95, two ports; the second has no internal connection; the first is implicit/ // simple module m7(a,); input a; wire [7:0] a; initial #1 test.sum[7] = test.sum[7] + a; endmodule /* ---------------------------------------------------------------------------- * 95, one and two ports, with implicit and extended identifiers * ------------------------------------------------------------------------- */ // 95, one implicit port, extended identifier module m8(\a ); input \a ; wire [7:0] \a ; initial #1 test.sum[8] = test.sum[8] + \a ; endmodule // 95, two implicit ports, extended identifiers module m9(\a , \b ); input \a ; output \b ; wire [7:0] \a ; reg [15:0] \b ; initial #1 \b = test.sum[9] + \a ; endmodule // 95, two ports; the first has no internal connection; the second is implicit/ // extended module m10(,\a ); input \a ; wire [7:0] \a ; initial #1 test.sum[10] = test.sum[10] + \a ; endmodule // 95, two ports; the second has no internal connection; the first is implicit/ // extended module m11(\a ,); input \a ; wire [7:0] \a ; initial #1 test.sum[11] = test.sum[11] + \a ; endmodule /* ---------------------------------------------------------------------------- * 95, one and two ports, with implicit and vector bit-select ports * ------------------------------------------------------------------------- */ // 95, one implicit port, vector bit-select module m12(a[0]); input a; wire [7:0] a; initial #1 test.sum[12] = test.sum[12] + {test.data[7:1], a[0]}; endmodule // 95, two implicit ports, vector bit-selects. the output is actually a part // select, since ISE core dumps on the assign below, and doing anything // else in -95 is difficult module m13(a[0], b[15:0]); input a; output b; wire [7:0] a; reg [31:0] b; reg [15:0] temp; // assign test.wire13[15:1] = temp[15:1]; // drives the rest of wire13 initial begin #1 temp = test.sum[13] + {test.data[7:1], a[0]}; b = temp; // drives wire13[0] end endmodule // 95, two ports; the first has no internal connection; the second is implicit/ // vector bit-select module m14(,a[0]); input [7:0] a; initial #1 test.sum[14] = test.sum[14] + {test.data[7:1], a[0]}; endmodule // 95, two ports; the second has no internal connection; the first is implicit/ // vector bit-select module m15(a[0],); input [7:0] a; initial #1 test.sum[15] = test.sum[15] + {test.data[7:1], a[0]}; endmodule /* ---------------------------------------------------------------------------- * 95, one and two ports, with implicit and vector part-select ports * ------------------------------------------------------------------------- */ // 95, one implicit port, vector bit-select module m16(a[7:0]); input a; wire [15:0] a; initial #1 test.sum[16] = test.sum[16] + {8'h00, a[7:0]}; endmodule // 95, two implicit ports, vector bit-selects module m17(a[7:0], b[15:0]); input a; output b; wire [7:0] a; reg [31:0] b; initial #1 b[15:0] = test.sum[17] + a; endmodule // 95, two ports; the first has no internal connection; the second is implicit/ // vector part-select module m18(,a[7:0]); input [15:0] a; initial #1 test.sum[18] = test.sum[18] + {8'h00, a[7:0]}; endmodule // 95, two ports; the second has no internal connection; the first is implicit/ // vector part-select module m19(a[7:0],); input [15:0] a; // initial #1 test.sum[19] = test.sum[19] + a; initial #1 test.sum[19] = test.sum[19] + {8'h00, a[7:0]}; endmodule /* ---------------------------------------------------------------------------- * 95, one and two ports, with ports which are a concatenation of a bit select * and a 3-bit part select * ------------------------------------------------------------------------- */ // 95, one implicit port, concatenation module m20({a[7], a[6:0]}); input a; wire [15:0] a; initial #1 test.sum[20] = test.sum[20] + {8'h00, a[7:0]}; endmodule // 95, two implicit ports, concatenations module m21({a[7], a[6:0]}, {b[15], b[14:0]}); input a; output b; wire [7:0] a; reg [15:0] b; initial #1 b = test.sum[21] + {8'h00, a[7:0]}; endmodule // 95, two ports; the first has no internal connection; the second is implicit/ // concatenation module m22(,{a[7], a[6:0]}); input [15:0] a; initial #1 test.sum[22] = test.sum[22] + {8'h00, a[7:0]}; endmodule // 95, two ports; the second has no internal connection; the first is implicit/ // concatenation. note that both modelsim and ISE set the entire sum, and not // just the top 8 bits, to all x's for 'test.sum[23] = test.sum[23] + a' module m23({a[7], a[6:0]},); input a; wire [15:0] a; initial #1 test.sum[23] = test.sum[23] + a[7:0]; endmodule iverilog-12_0/ivtest/ivltests/pr1735724.v000066400000000000000000000003551435245347300201320ustar00rootroot00000000000000module test; parameter j=0; reg [3:0] in [7:0]; wire [3:0] out [7:0]; assign out[(j+1)*4 - 1 : j*4] = in[j]; // assign out[j] = in[j]; // This is what was probably wanted. initial $display("out[0]: %b", out[0]); endmodule iverilog-12_0/ivtest/ivltests/pr1735822.v000066400000000000000000000005641435245347300201330ustar00rootroot00000000000000module test(); reg [0:(8*6)-1] identstr= "PASSED"; reg [7:0] identdata= 8'b0; integer i; initial begin // $dumpfile("indexed_part.vcd"); // $dumpvars; end initial begin for (i=0; i<6; i=i+1) begin #10 identdata = identstr[i*8 +:8]; $write("%c", identdata); end $write("\n"); $finish; end endmodule // test iverilog-12_0/ivtest/ivltests/pr1735836.v000066400000000000000000000003351435245347300201340ustar00rootroot00000000000000module top; wire [1:0] out; reg [1:0] in1, in2; initial begin $monitor($time,,"out=%d", out); in1 = 2'd1; in2 = 2'd2; #1 force out = in1; #1 force out = in2; #1 release out; end endmodule iverilog-12_0/ivtest/ivltests/pr1740476b.v000066400000000000000000000012231435245347300202670ustar00rootroot00000000000000module main; wire [3:0] src [15:0]; wire [3:0] dst [15:0]; genvar i; for (i = 0 ; i < 16; i = i+1) begin:bb buffer u (.out(dst[i]), .in(src[i])); end for (i = 0 ; i < 16 ; i = i+1) begin:drv assign src[i] = i; end integer idx; initial begin #1 ; for (idx = 0 ; idx < 16 ; idx = idx+1) begin if (dst[idx] !== idx) begin $display("FAILED -- src[%0d]==%b, dst[%0d]==%b", idx, src[idx], idx, dst[idx]); $finish; end end $display("PASSED"); end endmodule // main module buffer (input wire [3:0] in, output wire [3:0] out); assign out = in; endmodule // buffer iverilog-12_0/ivtest/ivltests/pr1741212.v000066400000000000000000000330201435245347300201120ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This is a general recreation of the VHDL ieee.math_real package. */ // Constants for use below and for general reference // TODO: Bring it out to 12 (or more???) places beyond the decimal? `define MATH_E 2.7182818284 `define MATH_1_OVER_E 0.3678794411 `define MATH_PI 3.1415926536 `define MATH_2_PI 6.2831853071 `define MATH_1_OVER_PI 0.3183098861 `define MATH_PI_OVER_2 1.5707963267 `define MATH_PI_OVER_3 1.0471975511 `define MATH_PI_OVER_4 0.7853981633 `define MATH_3_PI_OVER_2 4.7123889803 `define MATH_LOG_OF_2 0.6931471805 `define MATH_LOG_OF_10 2.3025850929 `define MATH_LOG2_OF_E 1.4426950408 `define MATH_LOG10_OF_E 0.4342944819 `define MATH_SQRT_2 1.4142135623 `define MATH_1_OVER_SQRT_2 0.7071067811 `define MATH_SQRT_PI 1.7724538509 `define MATH_DEG_TO_RAD 0.0174532925 `define MATH_RAD_TO_DEG 57.2957795130 // The number of iterations to do for the Taylor series approximations `define EXPLOG_ITERATIONS 50 `define COS_ITERATIONS 13 module math ; /* Conversion Routines */ // Return the sign of a particular number. function real sign ; input real x ; begin sign = x < 0.0 ? 1.0 : 0.0 ; end endfunction // Return the trunc function of a number function real trunc ; input real x ; begin trunc = x - mod(x,1.0) ; end endfunction // Return the ceiling function of a number. function real ceil ; input real x ; real retval ; begin retval = mod(x,1.0) ; if( retval != 0.0 && x > 0.0 ) retval = x+1.0 ; else retval = x ; ceil = trunc(retval) ; end endfunction // Return the floor function of a number function real floor ; input real x ; real retval ; begin retval = mod(x,1.0) ; if( retval != 0.0 && x < 0.0 ) retval = x - 1.0 ; else retval = x ; floor = trunc(retval) ; end endfunction // Return the round function of a number function real round ; input real x ; real retval ; begin retval = x > 0.0 ? x + 0.5 : x - 0.5 ; round = trunc(retval) ; end endfunction // Return the fractional remainder of (x mod m) function real mod ; input real x ; input real m ; real retval ; begin retval = x ; if( retval > m ) begin while( retval > m ) begin retval = retval - m ; end end else begin while( retval < -m ) begin retval = retval + m ; end end mod = retval ; end endfunction // Return the max between two real numbers function real realmax ; input real x ; input real y ; begin realmax = x > y ? x : y ; end endfunction // Return the min between two real numbers function real realmin ; input real x ; input real y ; begin realmin = x > y ? y : x ; end endfunction /* Random Numbers */ // Generate Gaussian distributed variables function real gaussian ; input real mean ; input real var ; real u1, u2, v1, v2, s ; begin s = 1.0 ; while( s >= 1.0 ) begin // Two random numbers between 0 and 1 u1 = $random/pow(2.0,32) ; u2 = $random/pow(2.0,32) ; // Adjust to be between -1,1 v1 = 2.0*u1-1.0 ; v2 = 2.0*u2-1.0 ; // Polar mag squared s = v1*v1 + v2*v2 ; end gaussian = mean + sqrt(-2.0*log(s)/s) * v1 * sqrt(var) ; // gaussian2 = mean + sqrt(-2*log(s)/s)*v2 * sqrt(var) ; end endfunction /* Roots and Log Functions */ // Return the square root of a number function real sqrt ; input real x ; real retval ; begin // if( x == 0.0 ) retval = 0.0 ; // else retval = powr(x,0.5) ; // sqrt = retval ; sqrt = (x == 0.0) ? 0.0 : powr(x,0.5) ; end endfunction // Return the cube root of a number function real cbrt ; input real x ; real retval ; begin // if( x == 0.0 ) retval = 0.0 ; // else retval = powr(x,1.0/3.0) ; // cbrt = retval ; cbrt = (x == 0.0) ? 0.0 : powr(x,1.0/3.0) ; end endfunction // Return the absolute value of a real value function real abs ; input real x ; begin abs = (x > 0.0) ? x : -x ; end endfunction // Return a real value raised to an integer power function real pow ; input real b ; input integer x ; integer i ; integer absx ; real retval ; begin retval = 1.0 ; absx = abs(x) ; for( i = 0 ; i < absx ; i = i+1 ) begin retval = b*retval ; end pow = x < 0 ? (1.0/retval) : retval ; end endfunction // Return a real value raised to a real power function real powr ; input real b ; input real x ; begin powr = exp(x*log(b)) ; end endfunction // Return the evaluation of e^x where e is the natural logarithm base // NOTE: This is the Taylor series expansion of e^x function real exp ; input real x ; real retval ; integer i ; real nm1_fact ; real powm1 ; begin nm1_fact = 1.0 ; powm1 = 1.0 ; retval = 1.0 ; for( i = 1 ; i < `EXPLOG_ITERATIONS ; i = i + 1 ) begin powm1 = x*powm1 ; nm1_fact = nm1_fact * i ; retval = retval + powm1/nm1_fact ; end exp = retval ; end endfunction // Return the evaluation log(x) function real log ; input real x ; integer i ; real whole ; real xm1oxp1 ; real retval ; real newx ; begin retval = 0.0 ; whole = 0.0 ; newx = x ; while( newx > `MATH_E ) begin whole = whole + 1.0 ; newx = newx / `MATH_E ; end newx = x/pow(`MATH_E,whole) ; xm1oxp1 = (newx-1.0)/(newx+1.0) ; for( i = 0 ; i < `EXPLOG_ITERATIONS ; i = i + 1 ) begin retval = retval + pow(xm1oxp1,2*i+1)/(2.0*i+1.0) ; end log = whole+2.0*retval ; end endfunction // Return the evaluation ln(x) (same as log(x)) function real ln ; input real x ; begin ln = log(x) ; end endfunction // Return the evaluation log_2(x) function real log2 ; input real x ; begin log2 = log(x)/`MATH_LOG_OF_2 ; end endfunction function real log10 ; input real x ; begin log10 = log(x)/`MATH_LOG_OF_10 ; end endfunction function real log_base ; input real x ; input real b ; begin log_base = log(x)/log(b) ; end endfunction /* Trigonometric Functions */ // Internal function to reduce a value to be between [-pi:pi] function real reduce ; input real x ; real retval ; begin retval = x ; if( x > `MATH_PI ) begin while( retval >= `MATH_PI ) begin retval = retval - `MATH_PI ; end end else begin while( retval <= -`MATH_PI ) begin retval = retval + `MATH_PI ; end end reduce = retval ; end endfunction // Return the cos of a number in radians function real cos ; input real x ; integer i ; integer sign ; real newx ; real retval ; real xsqnm1 ; real twonm1fact ; begin newx = reduce(x) ; xsqnm1 = 1.0 ; twonm1fact = 1.0 ; retval = 1.0 ; for( i = 1 ; i < `COS_ITERATIONS ; i = i + 1 ) begin sign = -2*(i % 2)+1 ; xsqnm1 = xsqnm1*newx*newx ; twonm1fact = twonm1fact * (2.0*i) * (2.0*i-1.0) ; retval = retval + sign*(xsqnm1/twonm1fact) ; end cos = retval ; end endfunction // Return the sin of a number in radians function real sin ; input real x ; begin sin = cos(x - `MATH_PI_OVER_2) ; end endfunction // Return the tan of a number in radians function real tan ; input real x ; begin tan = sin(x) / cos(x) ; end endfunction // Return the arcsin in radians of a number function real arcsin ; input real x ; begin arcsin = 2.0*arctan(x/(1.0+sqrt(1.0-x*x))) ; end endfunction // Return the arccos in radians of a number function real arccos ; input real x ; begin arccos = `MATH_PI_OVER_2-arcsin(x) ; end endfunction // Return the arctan in radians of a number // TODO: Make sure this REALLY does work as it is supposed to! function real arctan ; input real x ; real retval ; real y ; real newx ; real twoiotwoip1 ; integer i ; integer mult ; begin retval = 1.0 ; twoiotwoip1 = 1.0 ; mult = 1 ; newx = abs(x) ; while( newx > 1.0 ) begin mult = mult*2 ; newx = newx/(1.0+sqrt(1.0+newx*newx)) ; end y = 1.0 ; for( i = 1 ; i < 2*`COS_ITERATIONS ; i = i + 1 ) begin y = y*((newx*newx)/(1+newx*newx)) ; twoiotwoip1 = twoiotwoip1 * (2.0*i)/(2.0*i+1.0) ; retval = retval + twoiotwoip1*y ; end retval = retval * (newx/(1+newx*newx)) ; retval = retval * mult ; arctan = (x > 0.0) ? retval : -retval ; end endfunction // Return the arctan in radians of a ratio x/y // TODO: Test to make sure this works as it is supposed to! function real arctan_xy ; input real x ; input real y ; real retval ; begin retval = 0.0 ; if( x < 0.0 ) retval = `MATH_PI - arctan(-abs(y)/x) ; else if( x > 0.0 ) retval = arctan(abs(y)/x) ; else if( x == 0.0 ) retval = `MATH_PI_OVER_2 ; arctan_xy = (y < 0.0) ? -retval : retval ; end endfunction /* Hyperbolic Functions */ // Return the sinh of a number function real sinh ; input real x ; begin sinh = (exp(x) - exp(-x))/2.0 ; end endfunction // Return the cosh of a number function real cosh ; input real x ; begin cosh = (exp(x) + exp(-x))/2.0 ; end endfunction // Return the tanh of a number function real tanh ; input real x ; real e2x ; begin e2x = exp(2.0*x) ; tanh = (e2x+1.0)/(e2x-1.0) ; end endfunction // Return the arcsinh of a number function real arcsinh ; input real x ; begin arcsinh = log(x+sqrt(x*x+1.0)) ; end endfunction // Return the arccosh of a number function real arccosh ; input real x ; begin arccosh = ln(x+sqrt(x*x-1.0)) ; end endfunction // Return the arctanh of a number function real arctanh ; input real x ; begin arctanh = 0.5*ln((1.0+x)/(1.0-x)) ; end endfunction initial begin $display( "cos(MATH_PI_OVER_3): %f", cos(`MATH_PI_OVER_3) ) ; $display( "sin(MATH_PI_OVER_3): %f", sin(`MATH_PI_OVER_3) ) ; $display( "sign(-10): %f", sign(-10) ) ; $display( "realmax(MATH_PI,MATH_E): %f", realmax(`MATH_PI,`MATH_E) ) ; $display( "realmin(MATH_PI,MATH_E): %f", realmin(`MATH_PI,`MATH_E) ) ; $display( "mod(MATH_PI,MATH_E): %f", mod(`MATH_PI,`MATH_E) ) ; $display( "ceil(-MATH_PI): %f", ceil(-`MATH_PI) ) ; $display( "ceil(4.0): %f", ceil(4.0) ) ; $display( "ceil(3.99999999999999): %f", ceil(3.99999999999999) ) ; $display( "pow(MATH_PI,2): %f", pow(`MATH_PI,2) ) ; $display( "gaussian(1.0,1.0): %f", gaussian(1.0,1.0) ) ; $display( "round(MATH_PI): %f", round(`MATH_PI) ) ; $display( "trunc(-MATH_PI): %f", trunc(-`MATH_PI) ) ; $display( "ceil(-MATH_PI): %f", ceil(-`MATH_PI) ) ; $display( "floor(MATH_PI): %f", floor(`MATH_PI) ) ; $display( "round(e): %f", round(`MATH_E)) ; $display( "ceil(-e): %f", ceil(-`MATH_E)) ; $display( "exp(MATH_PI): %f", exp(`MATH_PI) ) ; $display( "log2(MATH_PI): %f", log2(`MATH_PI) ) ; $display( "log_base(pow(2,32),2): %f", log_base(pow(2,32),2) ) ; $display( "ln(0.1): %f", log(0.1) ) ; $display( "cbrt(7): %f", cbrt(7) ) ; $display( "cos(%s): %f", ``MATH_2_PI, cos(20*`MATH_2_PI) ) ; $display( "sin(-%s): %f", ``MATH_2_PI, sin(-50*`MATH_2_PI) ) ; $display( "sinh(%s): %f", ``MATH_E, sinh(`MATH_E) ) ; $display( "cosh(%s): %f", ``MATH_2_PI, cosh(`MATH_2_PI) ) ; $display( "arctan_xy(-4,3): %f", arctan_xy(-4,3) ) ; $display( "arctan(MATH_PI): %f", arctan(`MATH_PI) ) ; $display( "arctan(-MATH_E/2): %f", arctan(-`MATH_E/2) ) ; $display( "arctan(MATH_PI_OVER_2): %f", arctan(`MATH_PI_OVER_2) ) ; $display( "arctan(1/7) = %f", arctan(1.0/7.0) ) ; $display( "arctan(3/79) = %f", arctan(3.0/79.0) ) ; $display( "pi/4 ?= %f", 5*arctan(1.0/7.0)+2*arctan(3.0/79.0) ) ; $display( "arcsin(1.0): %f", arcsin(1.0) ) ; $display( "cos(pi/2): %f", cos(`MATH_PI_OVER_2)) ; $display( "arccos(cos(pi/2)): %f", arccos(cos(`MATH_PI_OVER_2)) ) ; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1742910.v000066400000000000000000000004511435245347300201220ustar00rootroot00000000000000// pr1742910 module checktest(); parameter sum = 1'h1 + 1'h1; initial begin `ifdef __ICARUS_UNSIZED__ if (sum !== 2) begin `else if (sum !== 0) begin `endif $display("FAILED -- sum = %d", sum); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1745005.v000066400000000000000000000014111435245347300201150ustar00rootroot00000000000000`begin_keywords "1364-2005" // pr1745005 // module main; reg [31:0] ref; reg [3:0] addr; wire [3:0] out_net1 = ref[{addr,2'b00} +: 4]; wire [3:0] out_net2 = ref[{addr,2'b11} -: 4]; reg [3:0] out_reg; initial begin ref = 32'h76543210; for (addr = 0 ; addr < 8 ; addr = addr+1) begin #1 ; out_reg = ref[{addr,2'b00} +: 4]; if (out_reg !== addr) begin $display("FAILED -- addr=%d, out_reg=%b", addr, out_reg); $finish; end if (out_net1 !== addr) begin $display("FAILED -- addr=%d, out_net1=%b", addr, out_net1); $finish; end if (out_net2 !== addr) begin $display("FAILED -- addr=%d, out_net2=%b", addr, out_net2); $finish; end end $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1746401.v000066400000000000000000000006051435245347300201220ustar00rootroot00000000000000module test(); reg [1:0] array[1:0]; reg sign; reg clk = 1'b0; always @(posedge clk) sign = array[1][1]; initial begin array[0] = 1; array[1] = 2; #1 clk = 1; #1 if (sign !== 1'b1) begin $display("FAILED -- array[1][1] = %b, sign=%b", array[1][1], sign); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/pr1746848.v000066400000000000000000000004351435245347300201420ustar00rootroot00000000000000module forBug(); integer i; integer j; initial begin // This loop sets i=4 .. -1 which is an error for (i=4; i>-1; i=i-1) $display("i=%d",i); // This loop sets j=4 .. 0 which is correct. for (j=4; j>=0; j=j-1) $display("j=%d",j); end endmodule // forBug iverilog-12_0/ivtest/ivltests/pr1750870.v000066400000000000000000000005701435245347300201300ustar00rootroot00000000000000// pr1750870 module test (FUSE_Q); parameter fuse_a_msb = 4; parameter fuse_q_msb = (2**(fuse_a_msb+1))-1; input [fuse_q_msb:0] FUSE_Q; initial begin $display("fuse_q_msb = %d", fuse_q_msb); if ($bits(FUSE_Q) != 32) begin $display("FAILED -- $bits(FUSE_Q) = %d", $bits(FUSE_Q)); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1752353.v000066400000000000000000000006231435245347300201250ustar00rootroot00000000000000module test; reg [31:0] src; wire [7:0] tmp; subbuf U1 (.out(tmp), .in(src)); wire [31:0] dst = {24'h00_00_00, tmp}; initial begin src = 32'h11_22_33_44; #1 if (dst !== 32'h00_00_00_bb) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule module subbuf (output [31:0] out, input[31:0]in); assign out = ~in; endmodule // subbuf iverilog-12_0/ivtest/ivltests/pr1752823a.v000066400000000000000000000002321435245347300202640ustar00rootroot00000000000000module top; real zero, mzero; initial begin zero = 0.0; mzero = -1.0 * zero; $display("+0=%f and -0=%f.", zero, mzero); end endmodule iverilog-12_0/ivtest/ivltests/pr1752823b.v000066400000000000000000000003471435245347300202740ustar00rootroot00000000000000module top; real zero, mzero, inf, minf; initial begin zero = 0.0; mzero = -1.0 * zero; inf = 1/0.0; minf = -1 * inf; $display("+0=%f, -0=%f, inf=%f and minf=%f.", zero, mzero, inf, minf); end endmodule iverilog-12_0/ivtest/ivltests/pr1755593.v000066400000000000000000000025541435245347300201430ustar00rootroot00000000000000// pr1755593 module main; wire out; reg [4:0] data; reg [2:0] sel; test U1(out, data[0], data[1], data[2], data[3], sel[0], sel[1]); initial begin for (sel=0 ; sel<4 ; sel=sel+1) for (data=0 ; data<16 ; data=data+1) begin #1 if (out !== data[sel]) begin $display("FAILED -- data=%b, sel=%d", data, sel); $finish; end end $display("PASSED"); end endmodule // main module test (Z, D0, D1, D2, D3, E0, E1); output Z; input D0; input D1; input D2; input D3; input E0; input E1; u_test I48 (Z, D0, D1, D2, D3, E0, E1); endmodule primitive u_test (Z, D0, D1, D2, D3, E0, E1); output Z; input D0, D1, D2, D3, E0, E1; table 0 ? ? ? 0 0 : 0 ; 1 ? ? ? 0 0 : 1 ; ? 0 ? ? 1 0 : 0 ; ? 1 ? ? 1 0 : 1 ; ? ? 0 ? 0 1 : 0 ; ? ? 1 ? 0 1 : 1 ; ? ? ? 0 1 1 : 0 ; ? ? ? 1 1 1 : 1 ; 0 0 ? ? x 0 : 0 ; 1 1 ? ? x 0 : 1 ; ? ? 0 0 x 1 : 0 ; ? ? 1 1 x 1 : 1 ; 0 ? 0 ? 0 x : 0 ; 1 ? 1 ? 0 x : 1 ; ? 0 ? 0 1 x : 0 ; ? 1 ? 1 1 x : 1 ; 0 0 0 0 x x : 0 ; 1 1 1 1 x x : 1 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/pr1755629.v000066400000000000000000000011501435245347300201320ustar00rootroot00000000000000module test; parameter some = 4; wire [some-1:0] flag1; genvar i; generate for (i = 0; i < some; i = i + 1) begin : what wire [some-1:0] slice; end endgenerate generate for (i = 0; i < some; i = i + 1) begin : ab assign what[i].slice[i] = 1'b1; assign flag1[i] = &what[i].slice; end endgenerate integer idx; initial #1 begin for (idx = 0 ; idx < some ; idx = idx+1) begin if (flag1[idx] !== 1'bx) begin $display("FAILED -- flag1=%b", flag1); $finish; end end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1758122.v000066400000000000000000000013701435245347300201250ustar00rootroot00000000000000`begin_keywords "1364-2001-noconfig" // Copyright 2007, Martin Whitaker. // This code may be freely copied for any purpose. module gen_param_test(); localparam W = 3; localparam D = 3; reg [W-1:0] A[1:D]; reg [W-1:0] B[1:D]; wire [W-1:0] Y[1:D]; generate genvar j; for (j = 1; j <= D; j = j + 1) begin:sum adder #(W) instance(A[j], B[j], Y[j]); end endgenerate integer i; initial begin for (i = 1; i <= D; i = i + 1) begin A[i] = i - 1; B[i] = i + 1; end #1; for (i = 1; i <= D; i = i + 1) begin $display("%d + %d = %d", A[i-1], B[i-1], Y[i-1]); end end endmodule module adder #(parameter W = 1) ( input wire [W-1:0] A, input wire [W-1:0] B, output wire [W-1:0] Y ); assign Y = A + B; endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1758135.v000066400000000000000000000004661435245347300201360ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker. // This code may be freely copied for any purpose. module display_index_test(); reg [2:0] A[1:4]; integer i; initial begin for (i = 1; i <= 4; i = i + 1) begin A[i] = i; end for (i = 1; i <= 4; i = i + 1) begin $display("%d", A[i]); end end endmodule iverilog-12_0/ivtest/ivltests/pr1763333.v000066400000000000000000000000641435245347300201240ustar00rootroot00000000000000module test; wire s1; not(,s1); not(s1,); endmodule iverilog-12_0/ivtest/ivltests/pr1765789.v000066400000000000000000000006011435245347300201420ustar00rootroot00000000000000// pr1765789 module main; reg [32:0] addr = {1'b1, 32'h0040_0000 + 32'h8}; initial begin #1 ; if (addr !== 33'h1_0040_0008) begin $display("FAILED -- addr = %h", addr); $finish; end if ($bits({32'h0040_0000 + 32'h8}) !== 32) begin $display("FAILED -- bits count wrong"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1770199.v000066400000000000000000000004031435245347300201310ustar00rootroot00000000000000module top; wire net; assign (pull1, strong0) net = 1'b1; initial begin #1; // You can get the correct result by uncommenting the following line. // $display("The value is: %b.", net); $display("The strength is: %v:", net); end endmodule iverilog-12_0/ivtest/ivltests/pr1771903.v000066400000000000000000000005111435245347300201230ustar00rootroot00000000000000module top; parameter rval = 1.23456; real rlv = 1.23456; initial begin $display("Real :%g: has a width of %0d.", rlv, $bits(rlv)); $display("Parameter real :%g: has a width of %0d.", rval, $bits(rval)); $display("Real constant :%g: has a width of %0d.", 1.23456, $bits(1.23456)); end endmodule iverilog-12_0/ivtest/ivltests/pr1776485.v000066400000000000000000000011771435245347300201460ustar00rootroot00000000000000// pr1776485.v module vvp_fun_and; wire [7:0] ADC_gain; reg [7:0] force_low; wire [7:0] adc_gain_out = ADC_gain & ~force_low; UXO source(ADC_gain[5:0]); initial begin force_low = 0; #1 $display("ADC_gain = %b, acd_gain_out = %b", ADC_gain, adc_gain_out); if (ADC_gain !== 8'bzz_101010) begin $display("FAILED -- ADC_gain=%b", ADC_gain); $finish; end if (adc_gain_out !== 8'bxx_101010) begin $display("FAILED -- adc_gain_out=%b", adc_gain_out); $finish; end $display("PASSED"); end endmodule module UXO(output [5:0] gain); assign gain = 6'b101010; endmodule iverilog-12_0/ivtest/ivltests/pr1777103.v000066400000000000000000000006561435245347300201330ustar00rootroot00000000000000module test ( a, b); output a; output reg [31:0] b; reg [1:0] c; assign a = (b == {16{c}}); initial begin c = 2'b01; b = 32'h55555555; #1 if (a !== 1) begin $display("FAILED -- a=%b, b=%h, c=%b", a, b, c); $finish; end b = 32'haaaaaaaa; #1 if (a !== 0) begin $display("FAILED -- a=%b, b=%h, c=%b", a, b, c); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1780480.v000066400000000000000000000005751435245347300201350ustar00rootroot00000000000000// show bug in icarus verilog // this shouldn't crash, should it? `timescale 1ns/1ns module top (); reg [1:0] count; initial begin count = 0; #70 $finish(0); end always count = #20 count + 1; initial // It seems to be count[0] that does it here, // If I change it to count then everything works fine. $monitor("%0t\ta(%b)", $time, count[0]); endmodule iverilog-12_0/ivtest/ivltests/pr1784984.v000066400000000000000000000013571435245347300201510ustar00rootroot00000000000000// pr1784984 module signed_test; reg [31:0] a; initial begin a = (32'h80000000); a = a / 2; $display ("Current Value of a = %h", a); if (a !== 32'h40000000) begin $display("FAILED"); $finish; end a = a * 2; $display("Current value of a = %h", a); if (a !== 32'h80000000) begin $display("FAILED"); $finish; end a = (32'h80000000)/2; $display ("Current Value of a = %h", a); if (a !== 32'h40000000) begin $display("FAILED"); $finish; end a = (32'h40000000)*2; $display ("Current Value of a = %h", a); if (a !== 32'h80000000) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // signed_test iverilog-12_0/ivtest/ivltests/pr1787394a.v000066400000000000000000000015141435245347300203030ustar00rootroot00000000000000/* * This should produce x StL x StL * * When using both nmos and pmos you get the correct * result if only one of the control signals is X, but * when used individually you get StX not StL. This * appears to be a vec4 vs vec8 problem. R versions * give similar results. * * If both control inputs are X and the input is 0 the * value is calculated incorrectly. */ module top; reg nctl, pctl, b; wire c, d; initial begin $display("These should all produce:\nx StL x StL\n-----------"); $monitor("c=%b(%v), d=%b(%v), b=%b, nctl=%b, pctl=%b", c, c, d, d, b, nctl, pctl); b = 0; nctl = 0; pctl = 1'bx; #1 nctl = 1'bx; #1 b = 1; end nmos n1 (c, b, nctl); pmos p1 (c, b, pctl); pmos p2 (d, b, pctl); // bufif1 n1 (c, b, nctl); // bufif0 p1 (c, b, pctl); // bufif0 p2 (d, b, pctl); endmodule iverilog-12_0/ivtest/ivltests/pr1787394b.v000066400000000000000000000015141435245347300203040ustar00rootroot00000000000000/* * This should produce x StL x StL * * When using both nmos and pmos you get the correct * result if only one of the control signals is X, but * when used individually you get StX not StL. This * appears to be a vec4 vs vec8 problem. R versions * give similar results. * * If both control inputs are X and the input is 0 the * value is calculated incorrectly. */ module top; reg nctl, pctl, b; wire c, d; initial begin $display("These should all produce:\nx StL x StL\n-----------"); $monitor("c=%b(%v), d=%b(%v), b=%b, nctl=%b, pctl=%b", c, c, d, d, b, nctl, pctl); b = 0; nctl = 0; pctl = 1'bx; #1 nctl = 1'bx; #1 b = 1; end //nmos n1 (c, b, nctl); //pmos p1 (c, b, pctl); //pmos p2 (d, b, pctl); bufif1 n1 (c, b, nctl); bufif0 p1 (c, b, pctl); bufif0 p2 (d, b, pctl); endmodule iverilog-12_0/ivtest/ivltests/pr1787423.v000066400000000000000000000004501435245347300201310ustar00rootroot00000000000000module top; reg in; wire bf1, bf2, nt1, nt2, pd1, pd2, pu1, pu2; initial begin $monitor(bf1, bf2,, nt1, nt2,, pd1, pd2,, pu1, pu2,, in); in = 0; #1 in = 1; #1 in = 0; end buf (bf1, bf2, in); not (nt1, nt2, in); pulldown (pd1, pd2); pullup (pu1, pu2); endmodule iverilog-12_0/ivtest/ivltests/pr1787423b.v000066400000000000000000000040321435245347300202730ustar00rootroot00000000000000module top; reg pass = 1'b1; reg in; wire bf1, bf2, nt1, nt2, pd1, pd2, pu1, pu2; initial begin // $monitor(bf1, bf2,, nt1, nt2,, pd1, pd2,, pu1, pu2,, in); if (bf1 !== 1'bx && bf2 !== 1'bx) begin $display("Buffer failed, expected 2'bxx, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'bx && nt2 !== 1'bx) begin $display("Inverter (not) failed, expected 2'bxx, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end in = 1'b0; #1; if (bf1 !== 1'b0 && bf2 !== 1'b0) begin $display("Buffer failed, expected 2'b00, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'b1 && nt2 !== 1'b1) begin $display("Inverter (not) failed, expected 2'b11, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end in = 1'b1; #1; if (bf1 !== 1'b1 && bf2 !== 1'b1) begin $display("Buffer failed, expected 2'b11, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'b0 && nt2 !== 1'b0) begin $display("Inverter (not) failed, expected 2'b00, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end if (pass) $display("PASSED"); end buf (bf1, bf2, in); not (nt1, nt2, in); pulldown (pd1, pd2); pullup (pu1, pu2); endmodule iverilog-12_0/ivtest/ivltests/pr1787423b_std.v000066400000000000000000000040421435245347300211460ustar00rootroot00000000000000module top; reg pass = 1'b1; reg in; wire bf1, bf2, nt1, nt2, pd1, pd2, pu1, pu2; initial begin // $monitor(bf1, bf2,, nt1, nt2,, pd1, pd2,, pu1, pu2,, in); #1; if (bf1 !== 1'bx && bf2 !== 1'bx) begin $display("Buffer failed, expected 2'bxx, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'bx && nt2 !== 1'bx) begin $display("Inverter (not) failed, expected 2'bxx, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end in = 1'b0; #1; if (bf1 !== 1'b0 && bf2 !== 1'b0) begin $display("Buffer failed, expected 2'b00, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'b1 && nt2 !== 1'b1) begin $display("Inverter (not) failed, expected 2'b11, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end in = 1'b1; #1; if (bf1 !== 1'b1 && bf2 !== 1'b1) begin $display("Buffer failed, expected 2'b11, got %b%b", bf1, bf2); pass = 1'b0; end if (nt1 !== 1'b0 && nt2 !== 1'b0) begin $display("Inverter (not) failed, expected 2'b00, got %b%b", nt1, nt2); pass = 1'b0; end if (pd1 !== 1'b0 && pd2 !== 1'b0) begin $display("Pull down failed, expected 2'b00, got %b%b", pd1, pd2); pass = 1'b0; end if (pu1 !== 1'b1 && pu2 !== 1'b1) begin $display("Pull up failed, expected 2'b11, got %b%b", pu1, pu2); pass = 1'b0; end if (pass) $display("PASSED"); end buf (bf1, bf2, in); not (nt1, nt2, in); pulldown (pd1, pd2); pullup (pu1, pu2); endmodule iverilog-12_0/ivtest/ivltests/pr1787423c.v000066400000000000000000000007531435245347300203020ustar00rootroot00000000000000module top; wire net1, net2; reg [1:0] data; buf bus_drv[1:0] (net1, net2, data); initial begin data = 0; #1 $monitor(net1,,net2,,data); #1 if (net1 !== 1'b0) begin $display("FAILED"); $finish; end data = 3; #1 if (net1 !== 1'b1) begin $display("FAILED"); $finish; end data = 1; #1 if (net1 !== 1'bx) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr1792108.v000066400000000000000000000006661435245347300201360ustar00rootroot00000000000000`begin_keywords "1364-2005" module main; wire y1, y2, y3; reg a; initial begin $monitor($time , " y1 = %d, y2 = %d, y3 = %d, a = %d", y1, y2, y3, a); #1 a = 1; #1 a = 0; end sub s1(y1, y2, y3, a); endmodule // main module sub(y1, y2, y3, a); output y1, y2, y3; input a; reg y1, y2, y3; reg int; always @(*) begin y1 <= a; y2 <= y1; int <= a; y3 <= int; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1792152.v000066400000000000000000000001161435245347300201230ustar00rootroot00000000000000module top; parameter value = (1:2:3); initial $display(value); endmodule iverilog-12_0/ivtest/ivltests/pr1792734.v000066400000000000000000000017531435245347300201410ustar00rootroot00000000000000module top; reg [6:0] dx, dz, dz2; initial begin // Check the unsigned version. dx = 7'dx; dz = 7'dz; dz2 = 7'd?; $display(" 7'dx: %b", dx, ", 7'dz: %b", dz, ", 7'd?: %b", dz2); dx = 'dx; dz = 'dz; dz2 = 'd?; $display(" 'dx: %b", dx, ", 'dz: %b", dz, ", 'd?: %b", dz2); dx = 2'dx; dz = 2'dz; dz2 = 2'd?; $display(" 2'dx: %b", dx, ", 2'dz: %b", dz, ", 2'd?: %b", dz2); // Check the signed version. dx = 7'sdx; dz = 7'sdz; dz2 = 7'sd?; $display("7'sdx: %b", dx, ", 7'sdz: %b", dz, ", 7'sd?: %b", dz2); dx = 'sdx; dz = 'sdz; dz2 = 'sd?; $display(" 'sdx: %b", dx, ", 'sdz: %b", dz, ", 'sd?: %b", dz2); dx = 2'sdx; dz = 2'sdz; dz2 = 2'sd?; $display("2'sdx: %b", dx, ", 2'sdz: %b", dz, ", 2'sd?: %b", dz2); // Check the trailing underscore. dx = 7'dx_; dz = 7'dz__; dz2 = 7'd?___; $display("7'dx_: %b", dx, ", 7'dz_: %b", dz, ", 7'd?_: %b", dz2); end endmodule iverilog-12_0/ivtest/ivltests/pr1793157.v000066400000000000000000000002711435245347300201330ustar00rootroot00000000000000module test; reg [19:0] x1; initial main; task main; begin x1 = 20'habcde; $display("x1: %h; x2: %h", x1, (x1 - x1 - 1)); end endtask endmodule // test iverilog-12_0/ivtest/ivltests/pr1793749.v000066400000000000000000000010131435245347300201350ustar00rootroot00000000000000module test; reg [8:0] t1; initial main; function integer log2; input [31:0] arg; for (log2=0; arg > 0; log2=log2+1) arg = arg >> 1; endfunction // log2 task main; integer temp; begin t1 = 9'h0a5; temp = log2($unsigned(t1 - t1 - 1'b1)); $display("%d", temp); temp = log2($signed(t1 - t1 - 1'b1)); $display("%d", temp); temp = log2({t1 - t1 - 1'b1}); $display("%d", temp); temp = $bits(t1 - t1 - 1'b1); $display("%d", temp); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1793749b.v000066400000000000000000000004701435245347300203050ustar00rootroot00000000000000module test; reg [4:0] i; reg [7:0] j, k, l; initial main; task main; begin i = 5'h14; j = $signed(i); // works k = $signed(5'h14); // doesn't work l = 5'sh14; // works $display("i, j, k, l: '%b', '%b', '%b', '%b'", i, j, k, l); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1794362.v000066400000000000000000000016121435245347300201320ustar00rootroot00000000000000module shift; reg pass = 1'b1; integer i; reg [7:0] foo; parameter [2:0] ZERO = 0, THREE = 3; initial begin foo = 1'b1 << ZERO; if (foo != 'd1) begin $display("FAILED shift by ZERO, got %d expected 1", foo); pass = 1'b0; end foo = 1'b1 << THREE; if (foo != 'd8) begin $display("FAILED shift by THREE, got %d expected 8", foo); pass = 1'b0; end foo = 1'b1 << 3; if (foo != 'd8) begin $display("FAILED shift by 3, got %d expected 8", foo); pass = 1'b0; end foo = 1'b1 << 'd3; if (foo != 'd8) begin $display("FAILED shift by 'd3, got %d expected 8", foo); pass = 1'b0; end i = 'd3; foo = 1'b1 << i; if (foo != 'd8) begin $display("FAILED shift by variable set to 'd3, got %d expected 8", foo); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1795005a.v000066400000000000000000000006321435245347300202670ustar00rootroot00000000000000module test; reg [63:0] i, j; initial main; task main; integer k, l, m, n; begin i = 64'hffff_ffff_ffff_ffff; j = 64'hffff_ffff_ffff_ffff; k = $signed(i) < $signed(j); l = $signed(i) <= $signed(j); m = $signed(i) > $signed(j); n = $signed(i) >= $signed(j); $display("< : %s", k? "Y":"N"); $display("<=: %s", l? "Y":"N"); $display("> : %s", m? "Y":"N"); $display(">=: %s", n? "Y":"N"); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1795005b.v000066400000000000000000000006321435245347300202700ustar00rootroot00000000000000module test; reg [63:0] i, j; initial main; task main; integer k, l, m, n; begin i = 64'hffff_ffff_ffff_ffff; j = 64'hffff_ffff_ffff_fffe; k = $signed(i) < $signed(j); l = $signed(i) <= $signed(j); m = $signed(i) > $signed(j); n = $signed(i) >= $signed(j); $display("< : %s", k? "Y":"N"); $display("<=: %s", l? "Y":"N"); $display("> : %s", m? "Y":"N"); $display(">=: %s", n? "Y":"N"); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr1799904.v000066400000000000000000000012241435245347300201400ustar00rootroot00000000000000module test; reg clock; initial begin clock = 0; forever #5 clock = !clock; end wire [0:31] read_data1 [0:7]; reg [0:31] read_data2 [0:7]; assign read_data1[0] = 0; assign read_data1[1] = 1; assign read_data1[2] = 2; assign read_data1[3] = 3; assign read_data1[4] = 4; assign read_data1[5] = 5; assign read_data1[6] = 6; assign read_data1[7] = 7; always @(posedge clock) begin: we reg [3:0] x; for (x=0; x<8; x=x+1) begin read_data2[x[2:0]] <= read_data1[x[2:0]]; end end always @(posedge clock) begin: wg integer i; #1 for (i=0; i<8; i=i+1) begin $write("%x ", read_data2[i]); end $display; end initial begin #20; $finish(0); end endmodule // test iverilog-12_0/ivtest/ivltests/pr1804877.v000066400000000000000000000003571435245347300201420ustar00rootroot00000000000000module test; reg [128:1] str [0:0]; reg [31:0] idx; initial begin str[0] = "test_counter"; idx = 0; $write("String is %s\n", str[0]); // This works. $write("String is %s\n", str[idx]); // This fails. end endmodule iverilog-12_0/ivtest/ivltests/pr1805837.v000066400000000000000000000012301435245347300201260ustar00rootroot00000000000000module test(); wire [2:0] var1 = 3'bx01; // Incorrect results 101 vs x01. wire [2:0] var2 = 3'bx10; // Incorrect results 010 vs x10. wire [2:0] var3 = 3'bx0z; // Incorrect results zzz vs x0z. wire [2:0] var4 = 3'bx1z; // Incorrect results zzz vs x1z. wire [2:0] var5 = 3'bxz1; // Incorrect results 1z1 vs xz1. wire [2:0] var6 = 3'bxz0; // Incorrect results 0z0 vs xz0. wire [3:0] var7 = 4'bx0z0; // Incorrect results 0000 vs x0z0. wire [2:0] var8 = 3'bxxx; // This works correctly. initial begin $displayb("Should be:\nx01 x10 x0z x1z xz1 xz0 x0z0 xxx"); $strobeb (var1,, var2,, var3,, var4,, var5,, var6,, var7,, var8); end endmodule iverilog-12_0/ivtest/ivltests/pr1812297.v000066400000000000000000000007461435245347300201370ustar00rootroot00000000000000module ttop; reg tpass = 0, fpass = 0; task ttop; #1 tpass = 1; endtask initial begin ttop; #2; case ({tpass, fpass}) 2'b00: $display("FAILED - both task and function test"); 2'b01: $display("FAILED - task test"); 2'b10: $display("FAILED - function test"); 2'b11: $display("PASSED"); endcase end endmodule module ftop; function ftop; input a; ftop = ~a; endfunction initial if (ftop(0)) #1 ttop.fpass = 1; endmodule iverilog-12_0/ivtest/ivltests/pr1819452.txt000066400000000000000000000000701435245347300204770ustar00rootroot00000000000000in_0 in_1 in_2 in_3 in_4 in_5 in_6 in_7 in_8 in_9 in_10 iverilog-12_0/ivtest/ivltests/pr1819452.v000066400000000000000000000023111435245347300201250ustar00rootroot00000000000000module top; reg [8*80-1:0] str; integer fd, pos, result; initial begin fd = $fopen("ivltests/pr1819452.txt","rb"); result = $fgets(str, fd); while (!$feof(fd)) begin pos = $ftell(fd); $display("Found: %5s currently at byte %0d", str[8*10-1:8], pos); result = $fgets(str, fd); end result = $rewind(fd); result = $fgets(str, fd); pos = $ftell(fd); $display("Found: %5s currently at byte %0d", str[8*10-1:8], pos); result = $fseek(fd, 0, 0); result = $fgets(str, fd); pos = $ftell(fd); $display("Found: %5s currently at byte %0d", str[8*10-1:8], pos); result = $fseek(fd, -3, 2); result = $fgets(str, fd); pos = $ftell(fd); $display("Found: %5s currently at byte %0d", str[8*10-1:8], pos); result = $fseek(fd, -6, 1); result = $fgets(str, fd); pos = $ftell(fd); $display("Found: %5s currently at byte %0d", str[8*10-1:8], pos); result = $fseek(32'hffffffff, 0, 0); $display("Check fseek EOF = %0d", result); result = $ftell(32'hffffffff); $display("Check ftell EOF = %0d", result); result = $rewind(32'hffffffff); $display("Check rewind EOF = %0d", result); $fclose(fd); end endmodule iverilog-12_0/ivtest/ivltests/pr1820472.v000066400000000000000000000012141435245347300201200ustar00rootroot00000000000000module test; // parameter j=0; reg [5:0] j; reg [5:0] in [7:0]; wire [5:0] out [7:0]; assign out[0][1:0] = 2'b10; assign out[0][3:2] = 2'b01; assign out[1] = in[j]; // This uses the current j! assign out[2] = in[2]; assign out[3] = in[3]; initial begin j = 1; in[j] = 2'b10; in[2][3:2] = 2'b01; in[j+2][3:2] = 2'b10; #1; $display("out[0]: %b", out[0]); $display("out[1]: %b", out[1]); $display("out[2]: %b", out[2]); $display("out[3]: %b", out[3]); for (j=0; j<4; j=j+1) begin #0; // wait for change to propagate $display("out[1]-%0d: %b", j, out[1]); end end endmodule iverilog-12_0/ivtest/ivltests/pr1822658.v000066400000000000000000000002111435245347300201240ustar00rootroot00000000000000`define _variable 1 module top; initial begin if (`_variable == 1) $display("PASSED"); else $display("Fail"); end endmodule iverilog-12_0/ivtest/ivltests/pr1823732.v000066400000000000000000000007421435245347300201270ustar00rootroot00000000000000// // The output from the display should be: // i is '1'; j is '111'; k is '0' // module test; reg one = 1; reg i, k, kr; reg [2:0] j, jr; initial begin i = ($signed(3'b111) === 3'b111); j = $signed(3'b110) >>> 1; jr = $signed(3'b110) >>> one; k = (($signed(3'b110) >>> 1) === 3'b111); kr = (($signed(3'b110) >>> one) === 3'b111); $display("i is '%b'; j is '%b'; k is '%b'", i, j, k); $display("runtime ; j is '%b'; k is '%b'", jr, kr); end endmodule iverilog-12_0/ivtest/ivltests/pr1828642.v000066400000000000000000000011661435245347300201350ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker. // This code may be freely copied for any purpose. module generate_memory(); generate genvar b; for (b = 0; b < 4; b = b + 1) begin: Byte reg [7:0] Data[0:3]; end endgenerate integer i; initial begin for (i = 0; i < 4; i = i + 1) begin Byte[0].Data[i] = i*16 + 1; Byte[1].Data[i] = i*16 + 2; Byte[2].Data[i] = i*16 + 3; Byte[3].Data[i] = i*16 + 4; end for (i = 0; i < 4; i = i + 1) begin $display("%h", Byte[0].Data[i]); $display("%h", Byte[1].Data[i]); $display("%h", Byte[2].Data[i]); $display("%h", Byte[3].Data[i]); end end endmodule iverilog-12_0/ivtest/ivltests/pr183.v000066400000000000000000000004161435245347300176070ustar00rootroot00000000000000// Sample Code module main( stb, a ); input stb; output [1:0] a; wire [1:0] b; buf (a[0], b[0]); buf (a[1], b[1]); specify (posedge stb => (a[0]:1'bx)) = 1.0; (posedge stb => (a[1]:1'bx)) = 1.0; endspecify endmodule // main iverilog-12_0/ivtest/ivltests/pr1830834.v000066400000000000000000000013501435245347300201240ustar00rootroot00000000000000// Here are two examples of $strobe failing. It appears that thread data // is being cleaned up too soon for the $strobe to access it. module test; reg[4:0] j; reg [5:0] in [1:0]; wire [5:0] out; assign out = in[j]; // This uses the current j. initial begin in[1] = 6'b110001; j = 1; #1; // Need some delay for the calculations to run. $display("out: %b, in[%0d] %b:", out, j, in[j]); $display("out[3:0]: %b, in[%0d] %b:", out[j*1-1 +: 4], j, in[j]); // in[j] is what is failing. $strobe("out: %b, in[%0d] %b:", out, j, in[j]); // out[j... is what is failing. $strobe("out[3:0]: %b, in[%0d] %b:", out[j*1-1 +: 4], j, in[j]); // #1; // Adding this will work around the bug. end endmodule iverilog-12_0/ivtest/ivltests/pr1831724.v000066400000000000000000000002751435245347300201300ustar00rootroot00000000000000// pr1831724 module test; reg [15:0] tmp1, tmp2; initial begin tmp1 = 9'bxxx000000; tmp2 = {9'bxxx000000}; $display("tmp1: '%b'; tmp2: '%b'", tmp1, tmp2); end endmodule iverilog-12_0/ivtest/ivltests/pr1832097a.v000066400000000000000000000017131435245347300202730ustar00rootroot00000000000000module test; reg fail = 0; reg [3:0] in = 4'b0; wire [3:0] bus = in; initial begin #1; // Need some delay for the calculations to run. if (bus !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", bus); fail = 1; end #1 force bus[0] = 1'b1; #1 in[0] = 1'bz; if (bus !== 4'b0001) begin $display("FAILED: force of bus[0], got %b, expected 0001.", bus); fail = 1; end #1 force bus[3:2] = 2'b11; if (bus !== 4'b1101) begin $display("FAILED: force of bus[3:2], got %b, expected 1101.", bus); fail = 1; end #1 release bus[0]; if (bus !== 4'b110z) begin $display("FAILED: release of bus[0], got %b, expected 110z.", bus); fail = 1; end #1 release bus[3:2]; if (bus !== 4'b000z) begin $display("FAILED: release of bus[3:2], got %b, expected 000z.", bus); fail = 1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1832097b.v000066400000000000000000000016451435245347300203000ustar00rootroot00000000000000module test; reg fail = 0; reg [3:0] bus = 4'b0; initial begin if (bus !== 4'b0) begin $display("FAILED: initial value, got %b, expected 0000.", bus); fail = 1; end #1 force bus[0] = 1; bus[0] = 1'bz; if (bus !== 4'b0001) begin $display("FAILED: force of bus[0], got %b, expected 0001.", bus); fail = 1; end #1 force bus[3:2] = 2'b11; if (bus !== 4'b1101) begin $display("FAILED: force of bus[3:2], got %b, expected 1101.", bus); fail = 1; end #1 release bus[0]; bus = 4'b000z; #0; if (bus !== 4'b110z) begin $display("FAILED: release of bus[0], got %b, expected 110z.", bus); fail = 1; end #1 release bus[3:2]; bus[3] = 1'b0; if (bus !== 4'b010z) begin $display("FAILED: release of bus[3:2], got %b, expected 010z.", bus); fail = 1; end if (!fail) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1833024.v000066400000000000000000000041321435245347300201170ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg svar; reg sarr [1:0]; reg sout, stmp; wire wsarr [1:0]; wire wsbslv, wspslv, wsuplv, wsdolv; wire wsbstr, wspstr, wsuptr, wsdotr; wire wsbs = svar[0]; wire wsps = svar[0:0]; wire wsup = svar[0+:1]; wire wsdo = svar[0-:1]; wire wsabs = sarr[0][0]; wire wsaps = sarr[0][0:0]; wire wsaup = sarr[0][0+:1]; wire wsado = sarr[0][0-:1]; assign wsbslv[0] = svar; assign wspslv[0:0] = svar; assign wsuplv[0+:1] = svar; assign wsdolv[0-:1] = svar; assign wsarr[0][0] = svar; assign wsarr[0][0:0] = svar; assign wsarr[0][0+:1] = svar; assign wsarr[0][0-:1] = svar; tran(wsbstr[0], wsarr[1]); tran(wspstr[0:0], wsarr[1]); tran(wsuptr[0+:1], wsarr[1]); tran(wsdotr[0-:1], wsarr[1]); submod1 s1 (wsbstr[0], wspstr[0:0], wsuptr[0+:1], wsdotr[0-:1]); submod2 s2 (wsbstr[0], wspstr[0:0], wsuptr[0+:1], wsdotr[0-:1]); submod3 s3 (wsbstr[0], wspstr[0:0], wsuptr[0+:1], wsdotr[0-:1]); task stask; input a; reg local; begin local = a[0]; local = a[0:0]; local = a[0+:1]; local = a[0-:1]; end endtask initial begin stmp = svar[0]; stmp = svar[0:0]; stmp = svar[0+:1]; stmp = svar[0-:1]; stmp = sarr[0][0]; stmp = sarr[0][0:0]; stmp = sarr[0][0+:1]; stmp = sarr[0][0-:1]; sout[0] = 1'b0; sout[0:0] = 1'b0; sout[0+:1] = 1'b0; sout[0-:1] = 1'b0; sarr[0][0] = 1'b0; sarr[0][0:0] = 1'b0; sarr[0][0+:1] = 1'b0; sarr[0][0-:1] = 1'b0; end endmodule module submod1(arg1, arg2, arg3, arg4); input arg1, arg2, arg3, arg4; wire arg1, arg2, arg3, arg4; initial $display("In submod1 with %b, %b, %b, %b", arg1, arg2, arg3, arg4); endmodule module submod2(arg1, arg2, arg3, arg4); output arg1, arg2, arg3, arg4; wire arg1, arg2, arg3, arg4; initial $display("In submod2 with %b, %b, %b, %b", arg1, arg2, arg3, arg4); endmodule module submod3(arg1, arg2, arg3, arg4); inout arg1, arg2, arg3, arg4; wire arg1, arg2, arg3, arg4; initial $display("In submod3 with %b, %b, %b, %b", arg1, arg2, arg3, arg4); endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1833754.v000066400000000000000000000010001435245347300201200ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker. // This code may be freely copied for any purpose. module duplicate_names(); localparam up = 1; generate if (up) begin:block1 wire [2:0] count1; count_up counter(count1); end endgenerate initial begin:block1 reg [2:0] count2; #1 count2 = 4; #1 count2 = 5; #1 count2 = 6; #1 count2 = 7; end endmodule module count_up(output reg [2:0] count); initial begin #1 count = 0; #1 count = 1; #1 count = 2; #1 count = 3; end endmodule iverilog-12_0/ivtest/ivltests/pr1841300.v000066400000000000000000000006211435245347300201120ustar00rootroot00000000000000// PR1841300 // The output should be: // a is '14'; b is 'fffffff4'; c is 'fffffff4' module test; reg[4:0] a; reg [31:0] b, c; initial begin a = 5'b10100; b = $signed(a); c = $signed(_$Finv5(32'hab)); $display("a is '%h'; b is '%h'; c is '%h'", a, b, c); end function [4:0] _$Finv5; input l; reg [4:0] l; _$Finv5 = ~l; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1845683.v000066400000000000000000000011171435245347300201350ustar00rootroot00000000000000// PR1845683 /** * Author: Evan Lavelle * Company: Riverside Machines Ltd. * Date: 06/12/2007 * * Cver feature #1; signed arithmetic * * The correct output should be: * * res1: '00101010'; res2: '00101010'; res3: '00101010' * * Cver reports: * * res1: '10101010'; res2: '10101010'; res3: '10101010' */ module test; reg [7:0] res1, res2; reg signed [7:0] res3; initial begin res1 = 8'sb11001100 ^ 7'sb1100110; res2 = $signed(8'b11001100) ^ $signed(7'b1100110); res3 = $signed(8'b11001100) ^ $signed(7'b1100110); $display("res1: '%b'; res2: '%b'; res3: '%b'", res1, res2, res3); end endmodule iverilog-12_0/ivtest/ivltests/pr1851310.v000066400000000000000000000006771435245347300201270ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker. // This file may be freely copied for any purpose. module memory_monitor(); reg [7:0] Memory[0:15]; reg [3:0] Index; wire Flag1; wire FlagI; assign Flag1 = (Memory[1] == 0); assign FlagI = (Memory[Index] == 0); initial begin Index = 1; Memory[Index] = 0; #1 $display("Flag1 = %b, FlagI = %b", Flag1, FlagI); Memory[Index] = 1; #1 $display("Flag1 = %b, FlagI = %b", Flag1, FlagI); end endmodule iverilog-12_0/ivtest/ivltests/pr1855504.v000066400000000000000000000005341435245347300201300ustar00rootroot00000000000000// pr1855504 module mul_test(); reg [15:0] prod; reg [7:0] op2; reg [15:0] op1; initial begin op1 = 16'h0DA0; op2 = 8'h0A; prod = 16'h0000; end always begin prod <= op1[7:0] * op2; #5 $display("op1 = %h, op2 = %h, prod = %h", op1, op2, prod); #5 $finish(0); end endmodule // mul_test iverilog-12_0/ivtest/ivltests/pr1861212a.v000066400000000000000000000002641435245347300202620ustar00rootroot00000000000000module top2; real vo; initial begin vo = 3.3; #1000 vo = 4.5776; #1000 vo = -4; end always @(vo) $display("Real value is %f at %g", vo, $time); endmodule iverilog-12_0/ivtest/ivltests/pr1861212b.v000066400000000000000000000005701435245347300202630ustar00rootroot00000000000000module top; wire [63:0] vo; rcvr U1(vo); drvr U2(vo); endmodule module rcvr(input wire [63:0] vo); always @(vo) $display("Real value is %f at %g", $bitstoreal(vo), $time); endmodule module drvr(output wire [63:0] vo); real vint; assign vo = $realtobits(vint); initial begin vint = 3.3; #1000 vint = 4.5776; #1000 vint = -4; end endmodule iverilog-12_0/ivtest/ivltests/pr1861212c.v000066400000000000000000000005071435245347300202640ustar00rootroot00000000000000module top; wire real vo; rcvr U1(vo); drvr U2(vo); endmodule module rcvr(vo); input vo; wire real vo; always @(vo) $display("Real value is %f at %g", vo, $time); endmodule module drvr(vo); output vo; reg real vo; initial begin vo = 3.3; #1000 vo = 4.5776; #1000 vo = -4; end endmodule iverilog-12_0/ivtest/ivltests/pr1861212d.v000066400000000000000000000003771435245347300202720ustar00rootroot00000000000000module top; reg real vo; initial begin vo = 3.3; #1000 vo = 4.5776; #1000 vo = -4; end rcvr U1(vo); endmodule module rcvr(vo); input vo; wire real vo; always @(vo) $display("Real value is %f at %g", vo, $time); endmodule iverilog-12_0/ivtest/ivltests/pr1862744a.v000066400000000000000000000042051435245347300202740ustar00rootroot00000000000000module main; reg pass = 1'b1; reg v1 = 1'b0; reg v2 = 1'b0; reg v3 = 1'b0; reg v4 = 1'b0; reg v5 = 1'b0; reg v6 = 1'b0; reg v7 = 1'b0; reg v8 = 1'b0; reg v9 = 1'b0; reg v10 = 1'b0; reg v11 = 1'b0; reg v12 = 1'b0; reg cond = 1'b1; reg [1:0] cval = 2'b00; always #1 v1 = 1'b1; always v2 = #1 1'b1; always if (1'b1) #1 v3 = 1'b1; // This will pass since the else is optimized away! always if (1'b1) #1 v4 = 1'b1; else v4 = 1'b0; always if (cond) #1 v5 = 1'b1; else #1 v5 = 1'b0; always begin #1 v6 = 1'b1; end // 1 always begin #1; v7 = 1'b1; end // 2 always begin #0; #1 v8 = 1'b1; end // 3 always begin if (cond) #1 v9 = 1'b0; else v9 = 1'b0; #1 v9 = 1'b1; end // 4 always repeat(1) #1 v10 = 1'b1; always case(cval) 2'b00: #1 v11 = 1'b1; 2'b01: #1 v11 = 1'bx; default: #1 v11 = 1'bz; endcase always definite_delay; task definite_delay; #1 v12 = 1'b1; endtask initial begin #3; if (v1 != 1'b1) begin $display("Failed delayed assignment."); pass = 1'b0; end if (v2 != 1'b1) begin $display("Failed intra-assignment delay."); pass = 1'b0; end if (v3 != 1'b1) begin $display("Failed simple if statement."); pass = 1'b0; end if (v4 != 1'b1) begin $display("Failed constant if/else statement."); pass = 1'b0; end if (v5 != 1'b1) begin $display("Failed if/else statement."); pass = 1'b0; end if (v6 != 1'b1) begin $display("Failed block (1)."); pass = 1'b0; end if (v7 != 1'b1) begin $display("Failed block (2)."); pass = 1'b0; end if (v8 != 1'b1) begin $display("Failed block (3)."); pass = 1'b0; end if (v9 != 1'b1) begin $display("Failed block (4)."); pass = 1'b0; end if (v10 != 1'b1) begin $display("Failed repeat."); pass = 1'b0; end if (v11 != 1'b1) begin $display("Failed case."); pass = 1'b0; end if (v12 != 1'b1) begin $display("Failed task."); pass = 1'b0; end if (pass) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1862744b.v000066400000000000000000000053101435245347300202730ustar00rootroot00000000000000// Note: The for is translated to a begin/while is it tests the while. module main; reg val = 1'b0; reg cond = 1'b1; reg [1:0] cval; integer idx; integer dly = 1; // Simple assign (error). always val = 1'b1; // A zero delay assign (error). always #0 val = 1'b1; // A variable delay assign (warning). always #dly val = 1'b1; // Non-blocking assign (error). always val <= #1 1'b1; // No delay if (error). always if (cond) val = 1'b1; // No delay if/else (error). always if (cond) val = 1'b1; else val = 1'b0; // Delay if/no delay else (warning). always if (cond) #1 val = 1'b1; else val = 1'b0; // Delay if/no delay else (warning). always #0 if (cond) #1 val = 1'b1; else val = 1'b0; // No delay if/delay else (warning). always if (cond) val = 1'b1; else #1 val = 1'b0; // No delay forever (error). always forever val = 1'b1; // Zero delay forever (error). always forever #0 val = 1'b1; // Possible delay forever (warning). always forever if (cond) #1 val = 1'b1; else val = 1'b0; // No delay for (error). always for(idx=0; idx<1; idx=idx+1) val = 1'b1; // Zero delay for (error). always for(idx=0; idx<1; idx=idx+1) #0 val = 1'b1; // Possible delay for (warning). always for(idx=0; idx<1; idx=idx+1) if (cond) #1 val = 1'b1; else val = 1'b0; // Never run for (error). always for(idx=0; 0; idx=idx+1) #1 val = 1'b1; // Always run for (error). always for(idx=0; 1; idx=idx+1) #0 val = 1'b1; // An empty bock (error). always begin end // Block with no delay (error). always begin val = 1'b1; end // Block with zero delay (error). always begin #0 val = 1'b1; end // Block with zero delay (warning). always begin #0; if (cond) #1 val = 1'b1; else val = 1'b0; end // Never run repeat (error). always repeat(0) #1 val = 1'b1; // Always run repeat (error). always repeat(1) #0 val = 1'b1; // Possibly run repeat (warning). always repeat(cond) #1 val = 1'b1; // No wait (error). always wait(1) val = 1'b1; // May wait (warning). always wait(cond) val = 1'b1; // Not all paths covered (warning). always case(cval) 2'b00: #1 val = 1'b1; 2'b10: #1 val = 1'b1; endcase // Not all paths have delay (warning). always case(cval) 2'b00: #1 val = 1'b1; 2'b10: #1 val = 1'b1; default: #0 val = 1'b1; endcase // Check task calls (error, error, warning). always no_delay; always zero_delay; always possible_delay; task no_delay; val = 1'b1; endtask task zero_delay; #0 val = 1'b1; endtask task possible_delay; #dly val = 1'b1; endtask // Check a function call (error). always val = func(1'b1); function func; input in; func = in; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1864110a.v000066400000000000000000000003061435245347300202570ustar00rootroot00000000000000module top; wire real plus, minus; assign plus = 3.0; assign minus = -3.0; // This does not generate a Cr<>, so it core dumps. initial begin #1 $display(plus,, minus); end endmodule iverilog-12_0/ivtest/ivltests/pr1864110b.v000066400000000000000000000003261435245347300202620ustar00rootroot00000000000000module top; wire real minus; real in; assign minus = -in; // Should be arith/sub.r Cr<0>, initial begin $monitor(minus,, in); in = 3.0; #1 in = 4.0; #1 in = 6.0; end endmodule iverilog-12_0/ivtest/ivltests/pr1864110c.v000066400000000000000000000007131435245347300202630ustar00rootroot00000000000000module top; wire real result; reg [63:0] bits; // This generates incorrect code: // The .net/real temporary is not needed. // The .alias/real temporary is not needed. // The .sfunc should connect directly to the "results" net. // The .part is not needed and is causing a core dump. assign result = $bitstoreal(bits); initial begin $monitor("%g %h", result, bits); bits = 64'b0; #1 bits = {1'b0,{62{1'b1}}}; end endmodule iverilog-12_0/ivtest/ivltests/pr1864115.v000066400000000000000000000010521435245347300201220ustar00rootroot00000000000000module top; wire real result; wire [63:0] bits; real in; assign bits = $realtobits(in); // This generates incorrect code: // The .net/real temporary is not needed. // The .alias/real temporary is not needed. // The .sfunc should connect directly to the "results" net. // The .part is not needed and is causing a core dump. // // Once these are fixed it appears there is a concurrency issues assign result = $bitstoreal(bits); initial begin $monitor(result,, bits,, in); in = 0.0; #1 in = 2.0; end endmodule iverilog-12_0/ivtest/ivltests/pr1866215.v000066400000000000000000000013651435245347300201340ustar00rootroot00000000000000// pr1866215 module A (CH, CL, SH, SL); wire [31:6] S1L; wire [39:32] S1H; wire [31:6] C1L; wire [38:32] C1H; output [31:0] SL; output [31:0] CL; output [47:32] SH; output [47:32] CH; B B0 (C1H[38:32], {C1L[31:6], CL[5:0]}, S1H[39:32], {S1L[31:6], SL[5:0]}); initial begin #1 $display("C1H=%h, {C1L, CL}={%h, %h}, S1H=%h, {S1L, SL}={%h, %h}", C1H, C1L, CL, S1H, S1L, SL); end endmodule module B (CH, CL, SH, SL); output [37:32] CH; output [31:0] CL; output [38:32] SH; output [31:0] SL; C C0 (CH, CL, SH, SL); endmodule module C (CH, CL, SH, SL); output [38:32] CH; output [31:0] CL; output [39:32] SH; output [31:0] SL; assign CH = 6'h33; assign CL = 32'h55555555; assign SH = 7'h66; assign SL = 32'haaaaaaaa; endmodule iverilog-12_0/ivtest/ivltests/pr1866215b.v000066400000000000000000000010671435245347300202750ustar00rootroot00000000000000// pr1866215 module A (CH, CL, SH, SL); output [31:0] SL; output [31:0] CL; output [47:32] SH; output [47:32] CH; B B0 (CH, CL, SH, SL); assign SH = 'hff; assign SL = 32'haaaaaaaa; assign CH = 'hff; assign CL = 32'h55555555; endmodule module B (CH, CL, SH, SL); input [37:32] CH; input [31:0] CL; input [38:32] SH; input [31:0] SL; C C0 (CH, CL, SH, SL); endmodule module C (CH, CL, SH, SL); input [38:32] CH; input [31:0] CL; input [39:32] SH; input [31:0] SL; initial #1 $display("CH=%h, CL=%h, SH=%h, SL=%h", CH, CL, SH, SL); endmodule iverilog-12_0/ivtest/ivltests/pr1867161a.v000066400000000000000000000011351435245347300202710ustar00rootroot00000000000000module test; /* The base+b calculation uses %load/vp0 and this will cause invalid * results when the sum of base+b is larger than what will fit * in b. The addition is done at b's width. It appears that * %load/vp0 needs to be enhanced, or something else needs to * be used. * * The workaround is to make b large enough to access * the largest a index not a's range. */ parameter base = 8; reg [31:0] a[15:base]; reg [2:0] b; initial begin for (b=0; b<7; b=b+1) begin a[base+b] = 32'd2+b; $display("Value[%0d]: %1d", b, a[base+b]); end end endmodule iverilog-12_0/ivtest/ivltests/pr1867161b.v000066400000000000000000000004741435245347300202770ustar00rootroot00000000000000module test ( input rst ); reg [31:0] a[99-1:35]; reg [5:0] b; always @(b) begin a[35 + (b<<3)] <= #1 a[35 + (b<<3)] + 32'd1; end initial begin $monitor(a[35],, a[43]); a[35] = 32'd0; a[43] = 32'd8; b = 0; #2 b = 1; #2 b = 0; #2 b = 1; #2 b = 0; end endmodule iverilog-12_0/ivtest/ivltests/pr1867332.v000066400000000000000000000002411435245347300201250ustar00rootroot00000000000000module test ( input CL, input CSB ); reg a; specify specparam tps = 0.0; $setup(posedge CSB, edge[01,0x,x1,1x] CL, tps, a); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1868792.v000066400000000000000000000011651435245347300201460ustar00rootroot00000000000000module top; parameter amax = 9; reg [31:0] mem [amax:0]; integer i, tmp; integer fail [amax:0]; integer pass; initial begin pass = 1; for (i=0; i rl1; assign ge = rl2 >= rl1; assign lt = rl2 < rl1; assign le = rl2 <= rl1; initial begin rl1 = 0.0; rl2 = 0.0; #1 if ({eq,ne,gt,ge,lt,le} != 6'b100101) begin $display("Failed: expected %b, received %b", 6'b100101, {eq,ne,gt,ge,lt,le}); passed = 1'b0; end #1 rl2 = -1.0; #1 if ({eq,ne,gt,ge,lt,le} != 6'b010011) begin $display("Failed: expected %b, received %b", 6'b010011, {eq,ne,gt,ge,lt,le}); passed = 1'b0; end #1 rl2 = 1.0; #1 if ({eq,ne,gt,ge,lt,le} != 6'b011100) begin $display("Failed: expected %b, received %b", 6'b001100, {eq,ne,gt,ge,lt,le}); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1869772.v000066400000000000000000000004471435245347300201470ustar00rootroot00000000000000module top; reg [7:0] vec = 8'b10100101; reg passed = 1; function [3:0] copy; input [3:0] in; copy = in; endfunction initial begin if (copy(vec>>4) != 4'b1010) begin passed = 0; $display("Failed!"); end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1869781.v000066400000000000000000000011601435245347300201400ustar00rootroot00000000000000module dummy; integer i; integer foo_value; reg [1:0] foo_bit; initial begin i = 1; foo_value = 10; foo_bit[i] <= #foo_value 1'b0; /* NOTE: if you replace previous line either with: foo_bit[1] <= #foo_value 1'b0; or with: foo_bit[i] <= #10 1'b0; then "invalid opcode" is not shown */ #20 if (foo_bit[1] !== 1'b0) begin $display("FAILED -- foo_bit[1] = %b", foo_bit[1]); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1873146.v000066400000000000000000000004261435245347300201320ustar00rootroot00000000000000module test (a, b); output [31 : 0] a; input b; buf bufd[31:0] (a, b); initial#1 $display("PASSED"); specify specparam th = 0.9; // This incomplete set of specify cases needs to be handled. if (!b) (b *> a[0]) = (0); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1873372.v000066400000000000000000000003411435245347300201270ustar00rootroot00000000000000module top; wire real sml; wire real big; wire real prec; assign sml = 1e-20; assign big = 1e20; assign prec = 0.123456789; initial $display("big: %g, small: %g, precision: %0.11f", big, sml, prec); endmodule iverilog-12_0/ivtest/ivltests/pr1875866.v000066400000000000000000000005461435245347300201500ustar00rootroot00000000000000`timescale 1ns/1ns module test(); reg [4 : 0] A = 5'b0; reg CLK = 1'b0; integer pipe; initial begin #2000 if (A !== 0) $display("FAILED"); else $display("PASSED"); $finish; end always #20 CLK = !CLK; always @(posedge CLK) for(pipe = 2; pipe <= -1; pipe = pipe + 1) A<=A+1; endmodule // test iverilog-12_0/ivtest/ivltests/pr1875866b.v000066400000000000000000000006051435245347300203060ustar00rootroot00000000000000`timescale 1ns/1ns module test(); reg [4 : 0] A = 5'b0; reg CLK = 1'b0; parameter stages = 0; integer pipe; initial begin #2000 $display("PASSED"); $finish; end always #20 CLK = !CLK; always @(posedge CLK) for(pipe = 2; pipe <= stages -1; pipe = pipe + 1) begin $display("FAILED"); $finish; A<=A+1; end endmodule // test iverilog-12_0/ivtest/ivltests/pr1876798.v000066400000000000000000000010051435245347300201440ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be freely copied for any purpose. module scan_int_array(); integer f; integer i; integer n; integer v[0:3]; initial begin f = $fopen("work/temp.txt", "w"); for (i = 0; i < 4; i = i + 1) begin $fdisplay(f, "%d", i); end $fclose(f); f = $fopen("work/temp.txt", "r"); for (i = 0; i < 4; i = i + 1) begin n = $fscanf(f, " %d ", v[i]); end $fclose(f); for (i = 0; i < 4; i = i + 1) begin $display("%1d", v[i]); end end endmodule iverilog-12_0/ivtest/ivltests/pr1877740.v000066400000000000000000000007161435245347300201400ustar00rootroot00000000000000module top; reg pass = 1; initial begin if (4'sd2 < -2) begin $display("Failed for operator <"); pass = 0; end if (4'sd2 <= -2) begin $display("Failed for operator <="); pass = 0; end if (-2 > 4'sd2) begin $display("Failed for operator >"); pass = 0; end if (-2 >= 4'sd2) begin $display("Failed for operator >="); pass = 0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1877743.v000066400000000000000000000045071435245347300201450ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass = 1'b1; reg a, b, ci; wire co, s; adder dut(co, s, a, b, ci); initial begin // The initial value propagates in 1.6 nS. #1.59 check_result(1'bx, 1'bx, 1); #1 a = 0; b = 0; ci = 0; // 1.7 #1.69 check_result(1'bx, 1'b0, 2); // Check the a => s delays. #1 a = 1; b = 0; ci = 0; // 1.1 #1.09 check_result(1'b0, 1'b1, 3); #1 a = 0; b = 0; ci = 0; // 1.9 #1.89 check_result(1'b1, 1'b0, 4); // Check the b => s delays. #1 a = 0; b = 1; ci = 0; // 1.2 #1.19 check_result(1'b0, 1'b1, 5); #1 a = 0; b = 0; ci = 0; // 1.8 #1.79 check_result(1'b1, 1'b0, 6); // Check the ci => s delays. #1 a = 0; b = 0; ci = 1; // 1.3 #1.29 check_result(1'b0, 1'b1, 7); #1 a = 0; b = 0; ci = 0; // 1.7 #1.69 check_result(1'b1, 1'b0, 8); // Check the a => s delays (state-dependent). #1 a = 0; b = 1; ci = 0; #3 a = 1; b = 1; ci = 0; // 2.0 #1.99 check_result(1'b1, 1'b0, 9); #1 a = 0; b = 1; ci = 0; // 1.0 #0.99 check_result(1'b0, 1'b1, 10); #1 a = 0; b = 1; ci = 1; #3 a = 1; b = 1; ci = 1; // 1.4 #1.39 check_result(1'b0, 1'b1, 11); #1 a = 0; b = 1; ci = 1; // 1.6 #1.59 check_result(1'b1, 1'b0, 12); // Check the co delay. #1 a = 0; b = 1; ci = 0; #1.49; if (co !== 1'b1) begin $display("Failed initial value for co test, %b != 1'b1", co); pass = 1'b0; end #0.02; if (co !== 1'b0) begin $display("Failed final value for co test, %b != 1'b0", co); pass = 1'b0; end #10 if (pass) $display("PASSED"); end task check_result(input cur, input next, input integer num); begin if (s !== cur) begin $display("Failed initial value for test %0d, %b != %b", num, s, cur); pass = 1'b0; end #0.02; if (s !== next) begin $display("Failed final value for test %0d, %b != %b", num, s, next); pass = 1'b0; end end endtask endmodule module adder (co, s, a, b, ci); input a, b, ci; output co, s; assign {co, s} = a + b + ci; specify (a, b, ci => co) = 1.5; (ci => s) = (1.3, 1.7); if (b === 1'b1 && ci === 1'b0) (a => s) = (1, 2); if (b === 1'b1 && ci === 1'b1) (a => s) = (1.4, 1.6); ifnone (a => s) = (1.1, 1.9); ifnone (b => s) = (1.2, 1.8); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr1878909.v000066400000000000000000000006411435245347300201450ustar00rootroot00000000000000module test_top(); wire [3:0] test_val; test_mod test_mod0 [3:0]( .in_0(1'b1), .out_0(test_val) ); initial begin #1; if(test_val != 4'b0000) $display("Failed"); else $display("PASSED"); end endmodule module test_mod( in_0, out_0 ); input in_0; output out_0; function test; input moo; begin test = ~moo; end endfunction assign out_0 = test(in_0); endmodule iverilog-12_0/ivtest/ivltests/pr1879226.v000066400000000000000000000015011435245347300201320ustar00rootroot00000000000000`timescale 1ns/1ns module test; reg pass = 1; reg [3 : 0] A = 4'hf; wire [3 : 0] a_lls, a_lrs; reg signed [3 : 0] B = 7; wire signed [3 : 0] b_als, b_ars; assign a_lls = A<<4; assign a_lrs = A>>4; assign b_als = B<<<4; assign b_ars = B>>>4; initial begin #1; if (a_lls !== 4'b0) begin $display("FAILED assigning logical left shift"); pass = 0; end if (a_lrs !== 4'b0) begin $display("FAILED assigning logical right shift"); pass = 0; end if (b_als !== 4'b0) begin $display("FAILED assigning arithmetic left shift"); pass = 0; end if (b_ars !== 4'h0) begin $display("FAILED assigning arithmetic right shift (0)"); pass = 0; end #1 B = -8; #1; if (b_ars !== 4'hf) begin $display("FAILED assigning arithmetic right shift (1)"); pass = 0; end if (pass) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/pr1880003.v000066400000000000000000000012361435245347300201200ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; real ra = 1.0; wire real rufunc; assign #10 rufunc = rl_func(ra); initial begin #1 if (rufunc == 2.0) begin pass = 1'b0; $display("Real: user function value (%f) not delayed.", rufunc); end #8 if (rufunc == 2.0) begin pass = 1'b0; $display("Real: user function value (%f) not delayed.", rufunc); end #2; if (rufunc != 2.0) begin pass = 1'b0; $display("Real: user function value not delayed correctly."); end if (pass) $display("PASSED"); end function real rl_func; input real in; rl_func = in * 2.0; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1883052.v000066400000000000000000000010511435245347300201220ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; reg [3:0] ia = 4'd1, ib = 4'd2; wire signed [3:0] icon; assign #1 icon = {ib[1:0], ia[0]}; // Should give 5 after a delay. initial begin #0.9; if (icon !== 4'bx) begin pass = 1'b0; $display("concatenation value not delayed, expected 4'bx got %b.", icon); end #0.1; #0; if (icon !== 4'd5) begin pass = 1'b0; $display("concatenation value not correct, expected 4'd5 got %d.", icon); end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1883052b.v000066400000000000000000000036161435245347300202750ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; reg [3:0] ia = 4'd1; wire signed [3:0] iconstp, iconstm, isfunc, iufunc; wire [7:0] istring; /* Integer constant value. */ assign #1 iconstp = 2; // 2 assign #1 iconstm = -2; // -2 assign #1 istring = "0"; // "0" /* Integer System Function. */ assign #1 isfunc = $rtoi(2.0); // 2 /* Integer User Function. */ assign #1 iufunc = int_func(ia); // 2 initial begin // $monitor($realtime,, iconstp,, iconstm,, istring,, iufunc,, isfunc); #0.9; if (iconstp !== 4'bx) begin pass = 1'b0; $display("Integer: constant (positive) value not delayed."); end if (iconstm !== 4'bx) begin pass = 1'b0; $display("Integer: constant (negative) value not delayed."); end if (istring !== 8'bx) begin pass = 1'b0; $display("Integer: string value not delayed."); end if (isfunc !== 4'bx) begin pass = 1'b0; $display("Integer: system function value not delayed."); end if (iufunc !== 4'bx) begin pass = 1'b0; $display("Integer: user function value not delayed."); end #0.1; #0; if (iconstp !== 2) begin pass = 1'b0; $display("Integer: constant (positive) value not delayed correctly."); end if (iconstm !== -2) begin pass = 1'b0; $display("Integer: constant (negative) value not delayed correctly."); end if (istring !== "0") begin pass = 1'b0; $display("Integer: string value not delayed correctly."); end if (isfunc !== 2) begin pass = 1'b0; $display("Integer: system function value not delayed correctly."); end if (iufunc !== 2) begin pass = 1'b0; $display("Integer: user function value not delayed correctly."); end if (pass) $display("PASSED"); end function [31:0] int_func; input [31:0] in; int_func = in * 2; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1885847.v000066400000000000000000000004521435245347300201440ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be freely copied for any purpose. module localparam_sign(); localparam P1 = 16; localparam P2 = P1 * 2; submodule #(P2) submodule(); endmodule module submodule(); parameter P3 = 1; initial begin $display("P3 = %0d", P3); end endmodule iverilog-12_0/ivtest/ivltests/pr1887168.v000066400000000000000000000037401435245347300201450ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be freely copied for any purpose. module constant_integer_div_mod(); initial begin $display("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d", 31'd10 / 'd3, 31'd11 / 'd3, 31'd12 / 'd3, 31'sd10 / 3, 31'sd11 / 3, 31'sd12 / 3, -31'sd10 / 3, -31'sd11 / 3, -31'sd12 / 3, 31'sd10 / -3, 31'sd11 / -3, 31'sd12 / -3, -31'sd10 / -3, -31'sd11 / -3, -31'sd12 / -3); $display("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d", 65'd10 / 'd3, 65'd11 / 'd3, 65'd12 / 'd3, 65'sd10 / 3, 65'sd11 / 3, 65'sd12 / 3, -65'sd10 / 3, -65'sd11 / 3, -65'sd12 / 3, 65'sd10 / -3, 65'sd11 / -3, 65'sd12 / -3, -65'sd10 / -3, -65'sd11 / -3, -65'sd12 / -3); $display("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d", 31'd10 % 'd3, 31'd11 % 'd3, 31'd12 % 'd3, 31'sd10 % 3, 31'sd11 % 3, 31'sd12 % 3, -31'sd10 % 3, -31'sd11 % 3, -31'sd12 % 3, 31'sd10 % -3, 31'sd11 % -3, 31'sd12 % -3, -31'sd10 % -3, -31'sd11 % -3, -31'sd12 % -3); $display("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d", 65'd10 % 'd3, 65'd11 % 'd3, 65'd12 % 'd3, 65'sd10 % 3, 65'sd11 % 3, 65'sd12 % 3, -65'sd10 % 3, -65'sd11 % 3, -65'sd12 % 3, 65'sd10 % -3, 65'sd11 % -3, 65'sd12 % -3, -65'sd10 % -3, -65'sd11 % -3, -65'sd12 % -3); end endmodule iverilog-12_0/ivtest/ivltests/pr1892959.v000066400000000000000000000011531435245347300201450ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [1:0] in; wire out; function IS_NOT_ZERO; input [3:0] in; begin IS_NOT_ZERO = |in; end endfunction assign out = (IS_NOT_ZERO(in) == 1'b1); initial begin in = 2'b00; #1 if (out != 1'b0) begin $display("Failed for 2'b00 case."); pass = 1'b0; end in = 2'b01; #1 if (out != 1'b1) begin $display("Failed for 2'b01 case."); pass = 1'b0; end in = 2'b10; #1 if (out != 1'b1) begin $display("Failed for 2'b01 case."); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1892959b.v000066400000000000000000000017011435245347300203060ustar00rootroot00000000000000`define DEV_TYPE "DEVICE 2" module top; parameter device = `DEV_TYPE; wire res; function is_dev1; input[8*20:1] device; reg is_device; begin if ((device == "DEVICE1") || (device == "DEVICE 1")) is_device = 1; else is_device = 0; is_dev1 = is_device; end endfunction function is_dev2; input[8*20:1] device; reg is_device; begin if ((device == "DEVICE2") || (device == "DEVICE 2")) is_device = 1; else is_device = 0; is_dev2 = is_device; end endfunction function is_dev; input[8*20:1] device; reg is_device; begin // Changing this to a single item makes things work. if (is_dev1(device) || is_dev2(device)) is_device = 1; else is_device = 0; is_dev = is_device; end endfunction assign res = (is_dev(device) == 1) ? 1'b1 : 1'b0; initial #1 if (res == 1'b1) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr1898293.v000066400000000000000000000017621435245347300201500ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [1:0] rval = 2'b10; wire [1:0] wval = (wval > 0) ? 2'b01 : 2'b00; // This works as follows: // rlval starts are 0.0 which is not greater than 0.0 (false). // This sets rlval to 2.0 which is greater than 0.0 (true). // This then sets the value to 1.0 which is still true and stable. wire real rlval = (rlval > 0.0) ? 1.0 : 2.0; initial begin #1; if (rval != 2'b10) begin $display("FAILED initial value expected 2'b10, got %b.", rval); pass = 1'b0; end if (wval !== 2'b0x) begin $display("FAILED net value expected 2'b0x, got %b.", wval); pass = 1'b0; end if (rlval != 1.0) begin $display("FAILED net real value expected 1.0, got %f.", rlval); pass = 1'b0; end #1 assign rval = (rval > 0) ? 2'b01 : 2'b00; if (rval != 2'b01) begin $display("FAILED forced value expected 2'b01, got %b.", rval); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1898983.v000066400000000000000000000004651435245347300201550ustar00rootroot00000000000000module top; reg [1:0] in; subm sm [1:0](in); initial begin // This should trigger instance 0. in[0] = 0; #1 in[0] = 1; // This should trigger instance 1. in[1] = 0; #1 in[1] = 1; end endmodule module subm(input wire in); always @(posedge in) $display("In %m at %0t", $time); endmodule iverilog-12_0/ivtest/ivltests/pr1901125.v000066400000000000000000000004621435245347300201170ustar00rootroot00000000000000// pr1901125 module test(); function integer hallo (input integer x); hallo = x - 1; endfunction // hallo integer foo; initial begin foo = hallo(10); if (foo !== 9) begin $display("FAILED -- foo=%d", foo); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1903157.v000066400000000000000000000006621435245347300201300ustar00rootroot00000000000000module test; parameter DATA_DEPTH_A = 8; parameter DATA_DEPTH_B = 2**8; reg [(2**8)-1:0] data1 ; //this gets compiled reg [7:0] data2 [DATA_DEPTH_A-1:0]; // this gets compiled reg [DATA_DEPTH_A-1:0] data3 [7:0]; // this gets compiled reg [DATA_DEPTH_B-1:0] data4 [7:0]; // this gets compiled reg [7:0] data5 [(2**8)-1:0]; // results in compilation error reg [7:0] data6 [DATA_DEPTH_B-1:0]; // results in compilation error endmodule iverilog-12_0/ivtest/ivltests/pr1903324.v000066400000000000000000000012451435245347300201220ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [7:0] d_reg = 8'b10100101; wire [7:0] d_wire = 8'b01011010; test tstr(d_reg); test tstw(d_wire); initial begin #1; /* Check with a register. */ if (tstr.data_in_array[3] != d_reg) begin $display("FAILED: with a register value."); pass = 1'b0; end /* Check with a wire. */ if (tstw.data_in_array[3] != d_wire) begin $display("FAILED: with a net value."); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule module test(input [8:1] data_in) ; wire [7:0] data_in_array[4:3]; assign data_in_array[3] = data_in; assign data_in_array[4] = 8'b0; endmodule iverilog-12_0/ivtest/ivltests/pr1903343.v000066400000000000000000000012361435245347300201230ustar00rootroot00000000000000`timescale 1ns/10ps module top; // Comment out this line and the $display below to get elaboration to fail. integer max = 2 ** 2; initial begin test_ok; // test_fail; $display("Main: %3d", max); end // This works. task test_ok; integer max; begin max = 2 ** 8; $display("OK: %3d", max); end endtask /* * This is invalid syntax! You can not do an assignment in a block * level variable declaration (task, function, etc.). // And this is failing! It appears to be looking in the wrong scope. task test_fail; integer max = 2 ** 8; begin $display("Fail: %3d", max); end endtask */ endmodule iverilog-12_0/ivtest/ivltests/pr1903520.v000066400000000000000000000002471435245347300201210ustar00rootroot00000000000000module test(); wire [1:0] b; assign b[0] = 0; a a(~b[0]); endmodule module a(b); input b; initial #1 if (b) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr1907192.v000066400000000000000000000004601435245347300201270ustar00rootroot00000000000000module top; parameter cond = 1; parameter value = 25; parameter test = (cond) ? 5: 0; defparam dut.lwrval = (cond == 1) ? 6: (100/value) + 0.5; lower dut(); endmodule module lower; parameter lwrval = 4; initial if (lwrval != 6.0) $display("FAILED"); else $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr1909940.v000066400000000000000000000003031435245347300201260ustar00rootroot00000000000000module top; wire out; // wire in; // Adding this makes it compile. assign out = ~in; assign in = 1'b0; initial #1 if (out == 1'b1) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr1909940b.v000066400000000000000000000003761435245347300203020ustar00rootroot00000000000000module top; wire out; // wire in; // Adding this makes it compile. assign out = ~in; zero zzz(in); initial #1 if (out == 1'b1) $display("PASSED"); else $display("FAILED"); endmodule module zero(output wire foo); assign foo = 1'b0; endmodule iverilog-12_0/ivtest/ivltests/pr1912112.v000066400000000000000000000002121435245347300201060ustar00rootroot00000000000000`define world World `define test Hello `world module test; initial $display("The `test definition is: `define %s", ``test); endmodule iverilog-12_0/ivtest/ivltests/pr1912843.v000066400000000000000000000003121435245347300201220ustar00rootroot00000000000000`timescale 1ps / 1ps module test(); reg[31:0] arr[1:0]; initial begin arr[0] = 'd1; arr[1] = 'd5; if (arr[0] + 1 + 1 > 4) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1913918a.v000066400000000000000000000004041435245347300202710ustar00rootroot00000000000000// pr1913918 module test(); parameter a = 4'b1000; b b(a[3]); endmodule // test module b(c); input c; initial #1 begin if (c !== 1'b1) begin $display("FAILED -- c = %b", c); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1913918b.v000066400000000000000000000004101435245347300202670ustar00rootroot00000000000000// pr1913918b module test ( output a); parameter [9:1] b = 9'b0_0000_0010; assign a = b[1] ^ b[9]; initial #1 begin if (a !== 1'b0) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1913918c.v000066400000000000000000000004041435245347300202730ustar00rootroot00000000000000// pr1913918c module test ( output reg a); parameter [9:1] b = 9'b0_0000_0010; initial begin a = b[1] ^ b[9]; if (a !== 1'b0) begin $display("FAILED -- b=%b, a=%b", b, a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1913937.v000066400000000000000000000015551435245347300201410ustar00rootroot00000000000000/* This test checks two thing: * * The first is that the AND arguments are padded if one is * smaller than the other. This was causing an assert. * * The second is that the reduction operator does not pass * the expression width to its arguments. This will give an * incorrect result (01 vs 00). */ module test (); reg pass = 1'b1; reg [1:0] ra; wire [1:0] a; wire [3:0] b = 4'b1111; wire [3:0] c = 4'b1111; assign a = |((c & ~(1'b1<<9'h00)) & b); initial begin #1; if (a !== 2'b01) begin $display("FAILED: cont. assign, expected 2'b01, got %b", a); pass = 1'b0; end ra = |((c & ~(1'b1<<9'h00)) & b); if (ra !== 2'b01) begin $display("FAILED: proc. assign, expected 2'b01, got %b", ra); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1916261.v000066400000000000000000000010041435245347300201170ustar00rootroot00000000000000module top; reg pass = 1'b1; parameter one = 1'b1; parameter zero = 1'b0; wire [3:0] ca_tru = one ? 4'b0001 : 4'b0000; wire [3:0] ca_fal = zero ? 4'b0000 : 4'b0010; initial begin #1; if (ca_tru != 4'b0001) begin $display("FAILED: CA true expression (%b != 4'b0001)", ca_tru); pass = 1'b0; end if (ca_fal != 4'b0010) begin $display("FAILED: CA false expression (%b != 4'b0010)", ca_fal); pass = 1'b0; end if(pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1916261a.v000066400000000000000000000005321435245347300202650ustar00rootroot00000000000000module top; parameter one = 1'b1; parameter zero = 1'b0; // These should fail since a zero replication is invalid in this context. wire [3:0] ca_tru = one ? 4'b0001 : {0{1'b0}}; wire [3:0] ca_fal = zero ? {0{1'b0}} : 4'b0010; // We used to not check for this so just pass for that case initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr1921332.v000066400000000000000000000003001435245347300201100ustar00rootroot00000000000000module test (D); input D; prim p (a, D, D, D); endmodule primitive prim (Z, A, B, S); output Z; input A, B, S; table 0 0 x : 0 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/pr1924845.v000066400000000000000000000016051435245347300201350ustar00rootroot00000000000000module test; reg pass = 1'b1; parameter con = 1 * -2; parameter a = 1; parameter b = -2; parameter mul = a * b; parameter sum = a + b; parameter div = b / a; parameter sub = b - a; initial begin if (con != -2) begin $display("FAILED: constant mult. expected -2, got %d (%b)", con, con); pass = 1'b0; end if (mul != -2) begin $display("FAILED: multiplication expected -2, got %d (%b)", mul, mul); pass = 1'b0; end if (div != -2) begin $display("FAILED: division expected -2, got %d (%b)", div, div); pass = 1'b0; end if (sum != -1) begin $display("FAILED: summation expected -1, got %d (%b)", sum, sum); pass = 1'b0; end if (sub != -3) begin $display("FAILED: subtraction expected -3, got %d (%b)", sub, sub); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1925356.v000066400000000000000000000004571435245347300201370ustar00rootroot00000000000000module top; reg pass = 1'b0; integer lp; reg [7:0] ival = 8'b0; initial begin /* If `ival' is replaced by a literal `0' this works... */ for(lp = ival; lp < 5; lp = lp + 1) begin pass = 1'b1; end if(pass) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1925360.v000066400000000000000000000003111435245347300201170ustar00rootroot00000000000000`define MAC(i) $display(i); module top; initial begin if ("$display(in);" != ``MAC(in)) $display("FAILED: expected \"display(in);\", got \"`MAC(in)\""); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1925363a.v000066400000000000000000000003071435245347300202700ustar00rootroot00000000000000module top; parameter wid = 9; wire [31:0] apass; wire [31:0] afail; assign apass = {(wid-8){ 8'b0}}; // This will pass. assign afail = {(wid-16){8'b0}}; // and this will fail. endmodule iverilog-12_0/ivtest/ivltests/pr1925363b.v000066400000000000000000000003201435245347300202640ustar00rootroot00000000000000module top; parameter wid = 9; reg [31:0] rpass; reg [31:0] rfail; initial begin rpass = {(wid-8){ 8'b0}}; // This will pass rfail = {(wid-16){8'b0}}; // and this will fail. end endmodule iverilog-12_0/ivtest/ivltests/pr1932444.v000066400000000000000000000013411435245347300201240ustar00rootroot00000000000000module test; reg pass = 1'b1; reg array[1:0]; reg [7:0] delay[1:0]; integer i = 1, j = 0; initial begin delay[0] = 8'd4; delay[1] = 8'd6; array[j] <= #(delay[0]) 1'b0; array[i] <= #(delay[i]) 1'b1; #3; if (array[0] !== 1'bx) begin $display("FAILED: array[0] != 1'bx @ 3"); pass = 1'b0; end #2; if (array[0] !== 1'b0) begin $display("FAILED: array[0] != 1'b0 @ 5"); pass = 1'b0; end if (array[1] !== 1'bx) begin $display("FAILED: array[1] != 1'bx @ 5"); pass = 1'b0; end #2; if (array[1] !== 1'b1) begin $display("FAILED: array[1] != 1'b1 @ 7"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1934744.v000066400000000000000000000010451435245347300201320ustar00rootroot00000000000000// $ iverilog -Wall simpler.v -o simpler // $ vvp simpler // simpler:37: syntax error `timescale 1ns / 1ns module simpler; reg [1:0] cnt=0; wire result; defparam \Mcount_cnt_xor<3>11 .INIT = 4'hC; test_lut \Mcount_cnt_xor<3>11 ( .a0(cnt[0]), .a1(cnt[1]), .O(result) ); initial $display("PASSED"); endmodule module test_lut (output O, input a0, input a1); parameter INIT = 4'h0; reg tmp; always @(*) tmp = mux ( INIT, {a1, a0}); assign O = tmp; function mux; input [3:0] d; input [1:0] s; mux = d[s]; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1936363.v000066400000000000000000000013131435245347300201270ustar00rootroot00000000000000module tern; reg [13:0] fdbk_err_wide; // arithmetic saturation from 14 bits down to 13 bits, and drop lsb wire [11:0] fdbk_err = ((fdbk_err_wide[13:12]==2'b00) | (fdbk_err_wide[13:12]==2'b11)) ? fdbk_err_wide[12:1] : {fdbk_err_wide[13],{11{~fdbk_err_wide[13]}}}; initial begin #10; $display(fdbk_err_wide, fdbk_err); // 2008-03-04 snapshot prints x x, 2008-04-02 git prints x z // 01eb298228d0adce9d62818e21d47fb274af9060 is first "bad" commit #10; fdbk_err_wide = 42; #10; $display(fdbk_err_wide, fdbk_err); // everybody agrees this is 42 21 #10; fdbk_err_wide = 14'bxxxxxxxxxxxxxx; #10; // everybody agrees this is x x $display(fdbk_err_wide, fdbk_err); #10; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr1938138.v000066400000000000000000000001451435245347300201330ustar00rootroot00000000000000module a(); endmodule module test(); a a(); endmodule module a(); endmodule module b(); endmodule iverilog-12_0/ivtest/ivltests/pr1939165.v000066400000000000000000000036311435245347300201370ustar00rootroot00000000000000/* * Copyright (c) 2008 Gyorgy Jeney (nog@sdf.lonestar.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module fpu_li_s1(); parameter eh = 11; parameter [eh - 1:0] alap = 1023; parameter ih2 = 6; parameter fh = 7; parameter [fh - 1:0] falap = 63; localparam ih = 1 << ih2; localparam nh = (eh > fh ? eh : fh) + 1; wire [nh - 1:0] exp_norm; /* IVL compiles this fine but when trying to run it through vvp, it throws * this error: * * internal error: port 0 expects wid=11, got wid=12 * vvp: concat.cc:56: virtual void vvp_fun_concat::recv_vec4(vvp_net_ptr_t, const * vvp_vector4_t&): Assertion `0' failed. * Aborted * * This is a regression caused by this commit: * commit a914eda5eff8b088837432a6516584b6a075fcd6 * Author: Stephen Williams * Date: Tue Apr 8 20:50:36 2008 -0700 * * Get part select from vectored parameters correct. * * Parameters with vector descriptions that are not zero based and * are used in net contexts should generate the properly ranged * temporary signals. This causes subsequent part selects to work * out properly. */ assign exp_norm = alap - falap + ih; initial begin #1 $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1946411.v000066400000000000000000000003151435245347300201230ustar00rootroot00000000000000// pr1946411 module test(); localparam integer a = 99; initial begin if (a !== 99) begin $display("FAILED -- a = %d", a); $finish; end $display("PASSED\n"); end endmodule iverilog-12_0/ivtest/ivltests/pr1948110.v000066400000000000000000000013071435245347300201230ustar00rootroot00000000000000module top; reg pass = 1'b1; reg a, b; real c, d; initial begin c = 0.0; d = 1.0; a = 1'b0; b = 1'b0; assign c = 6/(2 - d*(b & ~a) + d*(a & ~b)); #1; if (c != 3.0) begin $display("FAILED, expected 3.0, got %f", c); pass = 1'b0; end a = 1'b1; b = 1'b0; assign c = 6/(2 - d*(b & ~a) + d*(a & ~b)); #1; if (c != 2.0) begin $display("FAILED, expected 2.0, got %f", c); pass = 1'b0; end a = 1'b0; b = 1'b1; assign c = 6/(2 - d*(b & ~a) + d*(a & ~b)); #1; if (c != 6.0) begin $display("FAILED, expected 6.0, got %f", c); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1948342.v000066400000000000000000000011401435245347300201250ustar00rootroot00000000000000module test; wire a; reg [20:0] b; assign a = ((b[20:4]) || (b[3] && b[2:0])) ? 1'b0 : 1'b1; initial begin b = 0; #1 if (a !== 1'b1) begin $display("FAILED -- b=%h, a=%b", b, a); $finish; end b = 8; #1 if (a !== 1'b1) begin $display("FAILED -- b=%h, a=%b", b, a); $finish; end b = 12; #1 if (a !== 1'b0) begin $display("FAILED -- b=%h, a=%b", b, a); $finish; end b = 16; #1 if (a !== 1'b0) begin $display("FAILED -- b=%h, a=%b", b, a); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1949025.v000066400000000000000000000002501435245347300201250ustar00rootroot00000000000000module main; reg [2:0] value; initial begin for(value = 0; value <= 6; value = value + 1) begin $displayh(value,, 1<<(6-value)); end end endmodule iverilog-12_0/ivtest/ivltests/pr1950282.v000066400000000000000000000003441435245347300201260ustar00rootroot00000000000000module test; function integer fn (input integer a, b, input integer c); fn = ((a > b) ? a : b) + c; endfunction initial begin if (fn(2, 4, 3) != 7) $display("Failed"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1956211.v000066400000000000000000000012541435245347300201250ustar00rootroot00000000000000module top; reg clk; reg pass = 1'b1; generate genvar n; for (n=0; n<4; n=n+1) begin : loop reg [n:0] r; always @(clk) r = n; end endgenerate initial begin clk = 0; #1; if (loop[0].r !== 0) begin $display("Failed generate instance 0"); pass = 1'b0; end if (loop[1].r !== 1) begin $display("Failed generate instance 1"); pass = 1'b0; end if (loop[2].r !== 2) begin $display("Failed generate instance 2"); pass = 1'b0; end if (loop[3].r !== 3) begin $display("Failed generate instance 3"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1958801.v000066400000000000000000000011121435245347300201250ustar00rootroot00000000000000// pr1958001 module s_cmpGe( in00, in01, out00 ); parameter bw_in00 = 32; parameter bw_in01 = 32; input signed [bw_in00-1:0] in00; input signed [bw_in01-1:0] in01; output out00; assign out00 = ( in00 >= in01 ); endmodule module x; reg signed [31:0] a; reg signed b; wire c; s_cmpGe #(32, 1) inst(a, b, c); initial begin b = 0; a = -1; #1; $display("%d >= %d = %d", a, b, c); if (c !== 0) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1960545.v000066400000000000000000000002471435245347300201330ustar00rootroot00000000000000module test; initial begin: A1 while(1 != 0) begin: A2 reg B; B = 1; $display("B is %d", B); disable A1; end end endmodule iverilog-12_0/ivtest/ivltests/pr1960548.v000066400000000000000000000001061435245347300201300ustar00rootroot00000000000000// pr1960548 module test; initial $display("B`x"); endmodule iverilog-12_0/ivtest/ivltests/pr1960558.v000066400000000000000000000003051435245347300201320ustar00rootroot00000000000000module test; initial begin: A1 reg[1:0] v2; v2 = 2'b0z; $write( "expected 1; got %0b\n", (($signed(v2) === 1'sbx) || ($signed(v2 + 1'b1) === 1'sbx))); end endmodule iverilog-12_0/ivtest/ivltests/pr1960575.v000066400000000000000000000001251435245347300201310ustar00rootroot00000000000000module test; initial $write("expected x; got %0b\n", 1'b0 ^ 1'bz); endmodule iverilog-12_0/ivtest/ivltests/pr1960596.v000066400000000000000000000002641435245347300201400ustar00rootroot00000000000000module test; initial begin $write("expected 32'h55555552; got 32'h%0h\n", (-(32'h9) / 32'h3)); $write("expected 1; got %0d\n", (-(32'h9) % 32'h3)); end endmodule iverilog-12_0/ivtest/ivltests/pr1960619.v000066400000000000000000000026771435245347300201460ustar00rootroot00000000000000module test; initial begin: A reg [4:0] a; reg [31:0] b, c, d; a = 5'h14; b = $signed(a); c = {_$Finv5(_$Fsub8(_$Fadd8((32'haa ^ (32'hcc & _$Fsll32(_$Fsrl32(_$Fsll32(32'h78, 32'h2), 32'h3), 32'h1))), 32'h69), (32'h50 * 32'h2)))}; d = $signed(_$Finv5(_$Fsub8(_$Fadd8((32'haa ^ (32'hcc & _$Fsll32(_$Fsrl32(_$Fsll32(32'h78, 32'h2), 32'h3), 32'h1))), 32'h69), (32'h50 * 32'h2)))); $write("a is %0h; b is %0h; c is %0h; d is %0h\n", a, b, c, d); end function [4:0] _$Finv5; input l; reg [4:0] l; _$Finv5 = ~l; endfunction function [7:0] _$Fsub8; input l,r; reg [7:0] l,r; _$Fsub8 = l-r; endfunction function [7:0] _$Fadd8; input l,r; reg [7:0] l,r; _$Fadd8 = l+r; endfunction function [31:0] _$Fsll32; input l,r; reg [31:0] l; integer r; begin if(r < 0) begin if(r + 32 <= 0) _$Fsll32 = 32'b0; else _$Fsll32 = l >> -r; end else if(r > 0) begin if(r >= 32) _$Fsll32 = 32'b0; else _$Fsll32 = l << r; end else _$Fsll32 = l; end endfunction function [31:0] _$Fsrl32; input l,r; reg [31:0] l; integer r; begin if(r < 0) begin if(r + 32 <= 0) _$Fsrl32 = 32'b0; else _$Fsrl32 = l << -r; end else if(r > 0) begin if(r >= 32) _$Fsrl32 = 32'b0; else _$Fsrl32 = l >> r; end else _$Fsrl32 = l; end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1960625.v000066400000000000000000000012671435245347300201350ustar00rootroot00000000000000module top; reg pass = 1'b1; generate genvar n; for (n=0; n<4; n=n+1) begin : loop reg [2:0] r = n; // This fails. // wire [2:0] r = n; // This works. end endgenerate initial begin #1; if (loop[0].r !== 0) begin $display("Failed generate instance 0"); pass = 1'b0; end if (loop[1].r !== 1) begin $display("Failed generate instance 1"); pass = 1'b0; end if (loop[2].r !== 2) begin $display("Failed generate instance 2"); pass = 1'b0; end if (loop[3].r !== 3) begin $display("Failed generate instance 3"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1960633.v000066400000000000000000000013301435245347300201230ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module main; reg [7:0] foo; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] below = foo[2:-1]; wire [3:0] above = foo[8:5]; wire [9:0] span = foo[8:-1]; `else wire [3:0] below = {foo[2:0], 1'bx}; wire [3:0] above = {1'bx, foo[7:5]}; wire [9:0] span = {1'bx, foo[7:0], 1'bx}; `endif initial begin foo = 'h55; #1 ; if (below !== 4'b101_x) begin $display("FAILED"); $finish; end if (above !== 4'bx_010) begin $display("FAILED"); $finish; end if (span !== 10'bx_01010101_x) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr1963240.v000066400000000000000000000005171435245347300201260ustar00rootroot00000000000000module test; reg [7:0] i8, j8; reg [31:0] i32; initial begin i8 = 32'hf7; j8 = 32'h3; i32 = $signed(i8 / j8); $write("expected %0h; got %0h\n", 8'h52, i32); i8 = 32'hf7; j8 = 32'h1; i32 = $signed(i8 / j8); $write("expected %0h; got %0h\n", 32'hffffff_f7, i32); end endmodule iverilog-12_0/ivtest/ivltests/pr1963960.v000066400000000000000000000024411435245347300201350ustar00rootroot00000000000000module top; integer chr, fd, code; reg [14*8:1] str; initial begin // Put a string into the file. fd = $fopen("work/test.txt", "w"); if (fd == 0) begin $display("Failed to open test file for writing!"); $finish; end $fdisplay(fd, "Hello World!"); $fclose(fd); // Now read it back and verify that $ungetc() and other things work. fd = $fopen("work/test.txt", "r"); if (fd == 0) begin $display("Failed to open test file for reading!"); $finish; end chr = $fgetc(fd); if (chr != "H") begin $display("Failed first character read!"); $finish; end code = $ungetc(chr, fd); if (code == -1) begin $display("Failed to ungetc() character!"); $finish; end chr = $fgetc(fd); if (chr != "H") begin $display("Failed first character reread!"); $finish; end code = $ungetc(chr, fd); if (code == -1) begin $display("Failed to ungetc() character (2)!"); $finish; end code = $fgets(str, fd); if (code == 0) begin $display("Failed to read characters!"); $finish; end if (str[13*8:9] != "Hello World!") begin $display("Read wrong characters!"); $finish; end $fclose(fd); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1963962.v000066400000000000000000000002151435245347300201340ustar00rootroot00000000000000module top; reg [256*8:1] name; initial begin name = "work/dumptest"; $dumpfile({name, ".vcd"}); $dumpvars; end endmodule iverilog-12_0/ivtest/ivltests/pr1971662a.v000066400000000000000000000002531435245347300202730ustar00rootroot00000000000000module top; parameter rep = 4'bx; reg [31:0] a; initial begin a = {rep{8'hab}}; // This should be a compilation error! $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1971662b.v000066400000000000000000000002251435245347300202730ustar00rootroot00000000000000module top; parameter rep = 4'bx; wire [31:0] b = {rep{8'hab}}; // This should be a compilation error. initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr1978358.v000066400000000000000000000016461435245347300201520ustar00rootroot00000000000000`begin_keywords "1364-2005" `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; reg [3:0] var = 4'b1001; // wire [3:0] var = 4'b1001; // parameter [3:0] var = 4'b1001; reg [3:0] part; reg [5:0] big; initial begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = var[1:-2]; // should be 01xx. if (part !== 4'b01xx) begin $display("part select [1:-2] failed, expected 4'b01xx, got %b", part); pass = 1'b0; end part = var[5:2]; // should be xx10. if (part !== 4'bxx10) begin $display("part select [5:2] failed, expected 4'bxx10, got %b", part); pass = 1'b0; end big = var[4:-1]; // should be x10100101x. if (big !== 6'bx1001x) begin $display("part select [4:-1] failed, expected 6'bx1001x, got %b", big); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1978358b.v000066400000000000000000000016461435245347300203140ustar00rootroot00000000000000`begin_keywords "1364-2005" `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; // reg [3:0] var = 4'b1001; wire [3:0] var = 4'b1001; // parameter [3:0] var = 4'b1001; reg [3:0] part; reg [5:0] big; initial begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = var[1:-2]; // should be 01xx. if (part !== 4'b01xx) begin $display("part select [1:-2] failed, expected 4'b01xx, got %b", part); pass = 1'b0; end part = var[5:2]; // should be xx10. if (part !== 4'bxx10) begin $display("part select [5:2] failed, expected 4'bxx10, got %b", part); pass = 1'b0; end big = var[4:-1]; // should be x10100101x. if (big !== 6'bx1001x) begin $display("part select [4:-1] failed, expected 6'bx1001x, got %b", big); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1978358c.v000066400000000000000000000016461435245347300203150ustar00rootroot00000000000000`begin_keywords "1364-2005" `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; // reg [3:0] var = 4'b1001; // wire [3:0] var = 4'b1001; parameter [3:0] var = 4'b1001; reg [3:0] part; reg [5:0] big; initial begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = var[1:-2]; // should be 01xx. if (part !== 4'b01xx) begin $display("part select [1:-2] failed, expected 4'b01xx, got %b", part); pass = 1'b0; end part = var[5:2]; // should be xx10. if (part !== 4'bxx10) begin $display("part select [5:2] failed, expected 4'bxx10, got %b", part); pass = 1'b0; end big = var[4:-1]; // should be x10100101x. if (big !== 6'bx1001x) begin $display("part select [4:-1] failed, expected 6'bx1001x, got %b", big); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1978358d.v000066400000000000000000000016571435245347300203200ustar00rootroot00000000000000`begin_keywords "1364-2005" `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; // reg [3:0] var = 4'b1001; // wire [3:0] var = 4'b1001; parameter [3:0] var = 4'b1001; reg [3:0] part; reg [5:0] big; initial begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = var[-2 +: 4]; // should be 01xx. if (part !== 4'b01xx) begin $display("part select [1:-2] failed, expected 4'b01xx, got %b", part); pass = 1'b0; end part = var[2 +: 4]; // should be xx10. if (part !== 4'bxx10) begin $display("part select [5:2] failed, expected 4'bxx10, got %b", part); pass = 1'b0; end big = var[-1 +: 6]; // should be x10100101x. if (big !== 6'bx1001x) begin $display("part select [4:-1] failed, expected 6'bx1001x, got %b", big); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr1983762.v000066400000000000000000000007221435245347300201370ustar00rootroot00000000000000module main; reg clk; localparam integer TEST = 100; print #("PASSED", TEST) foo (clk); initial begin clk = 0; #1 clk = 1; #1 $finish; end endmodule // main module print (input wire clk); parameter message = ""; parameter number = 0; always @(posedge clk) begin if (number !== 100) begin $display("FAILED -- number=%d\n", number); $finish; end $display("%s", message); end endmodule // print iverilog-12_0/ivtest/ivltests/pr1985582.v000066400000000000000000000007751435245347300201510ustar00rootroot00000000000000`timescale 1ns/1ps module top; realtime rtime; time itime; initial begin repeat (5) begin rtime = $realtime; itime = $time; $display("%4t %.2f %2d, %4t %0.2f %2d, %4t %.2f, %4t %0.2f, %4t %.2f,", $time, $time, $time, itime, itime, itime, $realtime, $realtime, rtime, rtime, rtm($realtime), rtm($realtime),, $time,, $realtime); #0.6; end end function real rtm; input real rin; rtm = rin; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1985582_std.v000066400000000000000000000007701435245347300210160ustar00rootroot00000000000000`timescale 1ns/1ps module top; realtime rtime; time itime; initial begin repeat (5) begin rtime = $realtime; itime = $time; $display("%t %.2f %2d, %t %0.2f %2d, %t %.2f, %t %0.2f, %t %.2f,", $time, $time, $time, itime, itime, itime, $realtime, $realtime, rtime, rtime, rtm($realtime), rtm($realtime),, $time,, $realtime); #0.6; end end function real rtm; input real rin; rtm = rin; endfunction endmodule iverilog-12_0/ivtest/ivltests/pr1988302.v000066400000000000000000000012601435245347300201300ustar00rootroot00000000000000module main; generate genvar i; for( i=0; i<4; i=i+2 ) begin : U reg [1:0] a; initial begin : V a = 2'b0; #10; a = i; end end endgenerate initial begin #5 ; if (U[0].a !== 2'd0) begin $display("FAILED -- U[0].a = %d", U[0].a); $finish; end if (U[2].a !== 2'd0) begin $display("FAILED -- U[2].a = %d", U[2].a); $finish; end #10 ; if (U[0].a !== 2'd0) begin $display("FAILED -- U[0].a = %d", U[0].a); $finish; end if (U[2].a !== 2'd2) begin $display("FAILED -- U[2].a = %d", U[2].a); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1988302b.v000066400000000000000000000013101435245347300202660ustar00rootroot00000000000000module main; generate genvar i; for( i=0; i<4; i=i+2 ) begin : U reg [1:0] a; initial begin : V a = 2'b0; #10; a = i; end end endgenerate initial begin #5 ; if (U[0].V.a !== 2'd0) begin $display("FAILED -- U[0].V.a = %d", U[0].V.a); $finish; end if (U[2].V.a !== 2'd0) begin $display("FAILED -- U[2].V.a = %d", U[2].V.a); $finish; end #10 ; if (U[0].V.a !== 2'd0) begin $display("FAILED -- U[0].V.a = %d", U[0].V.a); $finish; end if (U[2].V.a !== 2'd2) begin $display("FAILED -- U[2].V.a = %d", U[2].V.a); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr1988310.v000066400000000000000000000014151435245347300201310ustar00rootroot00000000000000module top; localparam A = 0; reg pass = 1'b1; generate if (A < 1) begin: gen task foo_task; reg x; begin x = 1'b0; #10; x = 1'b1; end endtask end else begin: gen task foo_task; reg x; begin x = 1'b1; #10; x = 1'b0; end endtask end endgenerate initial begin gen.foo_task; end initial begin #9 if (gen.foo_task.x !== 1'b0) begin $display("Failed: expected 1'b0, got %b", gen.foo_task.x); pass = 1'b0; end #2 if (gen.foo_task.x !== 1'b1) begin $display("Failed: expected 1'b1, got %b", gen.foo_task.x); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1990029.v000066400000000000000000000020501435245347300201250ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top(); reg pass = 1'b1; integer fp, i, n; reg [8:0] v; `ifndef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST reg [11:-4] w; `endif initial begin fp = $fopen("work/temp.txt", "w"); for (i = 0; i < 4; i = i + 1) begin $fdisplay(fp, "%d", i + 16'he020); end $fclose(fp); fp = $fopen("work/temp.txt", "r"); for (i = 0; i < 4; i = i + 1) begin v = 9'd0; // Use the following line and change the base in the a.out file // to -4 and the width to 16 to get correct functionality. //n = $fscanf(fp, " %d ", v[7:0]); // This uses the &PV<> `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST n = $fscanf(fp, " %d ", v[11:-4]); // This does not use &PV<> (bug) `else n = $fscanf(fp, " %d ", w); v = w[8:0]; `endif if (v != 2) begin $display("FAILED: iteration %d, got %b, expected 9'b000000010", i, v); pass = 1'b0; end end $fclose(fp); if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1990164.v000066400000000000000000000005051435245347300201300ustar00rootroot00000000000000module top; reg signed [7:0] test = -1; integer result; initial begin result = test[7:0]; // A part select is always unsigned (1364-2001 4.5.1)! if (result != 32'h0ff) begin $display("FAILED part selects are unsigned, got %h, expected 32'h0ff", result); end else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1990269.v000066400000000000000000000011711435245347300201360ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; reg [7:0] val; initial begin `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST val[3:-4] = 8'h6f; `else val[3:0] = 4'h6; `endif if (val !== 8'hx6) begin $display("FAILED underflow, got %h, expected 8'hx6", val); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST val[11:4] = 8'hfe; `else val[7:4] = 4'he; `endif if (val !== 8'he6) begin $display("FAILED overflow, got %h, expected 8'he6", val); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr1992244.v000066400000000000000000000004131435245347300201270ustar00rootroot00000000000000module top; wire [15:0] number =16'h20; wire shift_cmp = (number == (1 << 5)); initial begin #1; // Make sure things are settled. if (shift_cmp === 1'b1) $display("PASSED"); else $display("FAILED, got %b expected 1'b1", shift_cmp); end endmodule iverilog-12_0/ivtest/ivltests/pr1992729.v000066400000000000000000000012451435245347300201430ustar00rootroot00000000000000module main; function integer my_ceil; input number; real number; if (number > $rtoi(number)) my_ceil = $rtoi(number) + 1; else my_ceil = number; endfunction real tck; parameter CL_TIME = 13125; wire [31:0] result1 = my_ceil( CL_TIME/tck ); integer result2; initial begin tck = 2.0; result2 = my_ceil( CL_TIME/tck ); if (result2 !== 6563) begin $display("FAILED -- result2=%d", result2); $finish; end #1 if (result1 !== 6563) begin $display("FAILED -- result1=%d", result1); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr1993479.v000066400000000000000000000012171435245347300201450ustar00rootroot00000000000000/* * The base vpi_get() is not returning the correct result for * a signed value. There are obviously other problems as well. */ module top; reg [7:0] rval; reg signed [7:0] base; // This fails (no sign extension?). // reg signed [31:0] base; // This works on a 32 bit machine. // integer base; // And this works initial begin rval = 8'b10100101; for (base = 0; base > -8; base = base -1) begin $displayb("%3d %b ", base, rval[base +: 8], rval[base +: 8]); end $display; for (base = 0; base > -8; base = base -1) begin $displayb("%3d %b ", base+1, rval[base+1 +: 8], rval[base+1 +: 8]); end end endmodule iverilog-12_0/ivtest/ivltests/pr2001162.v000066400000000000000000000021241435245347300201050ustar00rootroot00000000000000`define PERIOD 10 module main; reg CLK; integer counter; initial begin // reset and clock generator counter = 0; CLK = 0; #2; // wait 2, and then... repeat(10) // generate 5 clock cycles #(`PERIOD/2) CLK = !CLK; $display("time %0t; the counter is %0d", $time, counter); $finish(0); end task test1; begin @(posedge CLK); $display("test1 increment; reading counter as %0d", counter); // the function call is necessary to get the problem counter = _$Fadd32(counter, 1'b1); end endtask task test2; begin @(posedge CLK); $display("test2 increment; reading counter as %0d", counter); counter = _$Fadd32(counter, 1'b1); end endtask function [31:0] _$Fadd32; input l,r; reg [31:0] l,r; _$Fadd32 = l+r; endfunction endmodule // main module trig1; always begin #`PERIOD; top.main.test1; end endmodule module trig2; always begin #`PERIOD; top.main.test2; end endmodule module top; main main(); trig1 trig1(); trig2 trig2(); endmodule iverilog-12_0/ivtest/ivltests/pr2002443.v000066400000000000000000000001561435245347300201130ustar00rootroot00000000000000`define MACRO(_param_,_def_) \ `ifdef _def_ \ module _param_ (); \ endmodule \ `endif `MACRO(FOFO, CFG_FOFO) iverilog-12_0/ivtest/ivltests/pr2011429.v000066400000000000000000000016621435245347300201220ustar00rootroot00000000000000`timescale 1 ps/1 ps // extracted from altera_mf.v module bug2011429; reg pass = 1'b1; reg [7:0] vco_tap; reg vco_c0_last_value; integer c_ph_val[0:5]; always @(vco_tap[c_ph_val[0]]) vco_c0_last_value = vco_tap[c_ph_val[0]]; initial begin vco_tap = 8'b10101010; c_ph_val[0] = 0; #1; if (vco_c0_last_value != 1'b0) begin $display("FAILED initial value, got %b", vco_c0_last_value); pass = 1'b0; end vco_tap = vco_tap >> 1; #1; if (vco_c0_last_value != 1'b1) begin $display("FAILED shifted value, got %b", vco_c0_last_value); pass = 1'b0; end c_ph_val[0] = 1; #1; if (vco_c0_last_value != 1'b0) begin $display("FAILED index change, got %b", vco_c0_last_value); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2013758.v000066400000000000000000000010711435245347300201230ustar00rootroot00000000000000// pr2013758 module test; reg reset; initial begin // $dumpfile( "test.vcd" ); // $dumpvars; reset = 0; #100; reset = 1; #100; reset = 0; #100 $display("PASSED"); $finish; end submod1 s1 (.reset(reset)); submod2 s2 (.reset(reset)); endmodule module submod1(input reset); wire reset2 = 1; assign reset2 = reset; endmodule module submod2(input reset); always #10 @(reset) if (reset === 1'bx) begin $display("FAILED -- X escaped into sibling module!"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr2014673.v000066400000000000000000000014161435245347300201230ustar00rootroot00000000000000// I ran this with "iverilog -y. bugreport.v -s bugreport && ./a.out" // on Icarus Verilog version 0.9.devel (s20080429) // and got "Bug observed: Got xxxxx, expected 0004b." // (some code taken from async_transmitter.v at http://www.fpga4fun.com) module bugreport; parameter ClkFrequency = 50000000; parameter Baud = 57600; parameter BaudGeneratorAccWidth = 16; wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4); wire [BaudGeneratorAccWidth:0] BaudGeneratorIncShouldBe = 17'h4b; initial #1 if (BaudGeneratorInc !== BaudGeneratorIncShouldBe) $display("FAILED -- Got %x, expected %x.",BaudGeneratorInc,BaudGeneratorIncShouldBe); else $display("PASSED"); endmodule // bugreport iverilog-12_0/ivtest/ivltests/pr2015466.v000066400000000000000000000015311435245347300201220ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker // This file may be freely copied for any purpose. No attribution required. module prXXX(); reg [3:0] value1; wire [1:0] value2; assign value2 = (value1 == 0) ? 0 : (value1 == 1) ? 1 : 2; initial begin value1 = 0; #1 if (value2 !== 0) begin $display("FAILED -- value1=%b, value2=%b", value1, value2); $finish; end value1 = 1; #1 if (value2 !== 1) begin $display("FAILED -- value1=%b, value2=%b", value1, value2); $finish; end value1 = 2; #1 if (value2 !== 2) begin $display("FAILED -- value1=%b, value2=%b", value1, value2); $finish; end value1 = 3; #1 if (value2 !== 2) begin $display("FAILED -- value1=%b, value2=%b", value1, value2); $finish; end $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr2018235a.v000066400000000000000000000014341435245347300202620ustar00rootroot00000000000000module test(); parameter N_CH = 1; reg pass = 1'b1; reg clk; reg [31:0] data[0: N_CH-1]; generate genvar i; for (i=0; iStart; #1 $display("%d %d", Value1, Value2); end endmodule iverilog-12_0/ivtest/ivltests/pr2076363.v000066400000000000000000000011561435245347300201300ustar00rootroot00000000000000module top; reg [10*8-1:0] str [2:0]; reg [31:0] idx [2:0]; reg [4*8-1:0] pvstr, pvstr2; reg [15:0] pvidx, pvidx2, pvbase; initial begin pvstr = "S"; pvstr2 = "SF"; pvidx = 'd2; pvidx2 = 'd8; pvbase = 'd0; str[0] = "FAIL"; str[1] = "PA"; str[2] = "ED"; idx[0] = 0; idx[1] = 1; idx[2] = 2; $write("%0s", str[idx[1]]); // This prints PA or FAIL. $write("%0s", pvstr[idx[0] +: 16]); // This adds an S. $write("%0s", pvstr2[pvidx2[pvbase +: 4] +: 8]); // This adds another S. $display("%0s", str[pvidx[pvbase +: 8]]); // This adds the ED. end endmodule iverilog-12_0/ivtest/ivltests/pr2076391.v000066400000000000000000000005611435245347300201300ustar00rootroot00000000000000module top; reg [40*8-1:0] result; integer iindex [1:0]; reg signed [15:0] rindex [1:0]; wire signed [15:0] windex [1:0]; assign windex[0] = -1; initial begin iindex[0] = -1; rindex[0] = -1; #1; $display("iindex[0] = %0d", iindex[0]); $display("rindex[0] = %0d", rindex[0]); $display("windex[0] = %0d", windex[0]); end endmodule iverilog-12_0/ivtest/ivltests/pr2076425.v000066400000000000000000000003221435245347300201210ustar00rootroot00000000000000module top; task delay; z.delay; endtask always begin delay; end initial begin #10 $display("PASSED"); $finish; end endmodule module z; task delay; #1; endtask endmodule iverilog-12_0/ivtest/ivltests/pr2085984.v000066400000000000000000000004301435245347300201330ustar00rootroot00000000000000module top; reg [1:0] a[3:0]; reg [2:0] b[7:0], c[2:0]; integer i; always @(b[c[0]]) a[2] <= b[c[0]]; initial begin for (i=0; i<8; i=i+1) b[i] = i; c[0] = 3'b001; #1; if (a[2] != 2'b01) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2091455.v000066400000000000000000000011541435245347300201250ustar00rootroot00000000000000/* * Based on Request id 2091455 in the iverilog Bugs database */ module main; parameter foo = 2; generate case (foo) 0: initial #1 $display("I am in %m, case foo=%0d", foo); 1: initial #1 $display("I am in %m, case foo=%0d", foo); 2: initial #1 $display("I am in %m, case foo=%0d", foo); endcase // case (foo) case (foo) 0: begin : X initial $display("I am in %m, case foo=%0d", foo); end 1: begin : X initial $display("I am in %m, case foo=%0d", foo); end 2: begin : X initial $display("I am in %m, case foo=%0d", foo); end endcase // case (foo) endgenerate endmodule // bug iverilog-12_0/ivtest/ivltests/pr2109179.v000066400000000000000000000007051435245347300201310ustar00rootroot00000000000000module t(); reg [1:0] f; reg [1:0] oszok; wire [2:0] vosz1; genvar i; generate for(i = 0; i < 4; i = i + 1) begin : reg_tomb_gen wire [2:0] vosz1; assign vosz1 = i - f + oszok + 1; initial begin #1; if(!i && vosz1 !== 0) begin $display("FAIL -- i=%b, f=%b, oszok=%b, vosz1=%b", i, f, oszok, vosz1); $finish; end end end endgenerate initial begin f = 3; oszok = 2; #2 $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2117473.v000066400000000000000000000005731435245347300201300ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be freely copied for any purpose. module multiply(); reg signed [31:0] A; reg signed [31:0] B; wire signed [63:0] Y; assign Y = A * B; initial begin A = -1; B = -1; #1 $display("(%0d)*(%0d) = %0d", A, B, Y); if (Y !== 64'd1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2117488.v000066400000000000000000000007051435245347300201330ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be freely copied for any purpose. module ternary_add(); reg Enable; reg [7:0] A; reg [7:0] B; reg C; wire [8:0] Y; assign Y = Enable ? A + B + C : 0; initial begin Enable = 1'b1; A = 8'd1; B = 8'd254; C = 1'd1; #1 $display("%0d + %0d + %0d = %0d", A, B, C, Y); if (Y !== 9'd256) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2119622.v000066400000000000000000000003451435245347300201230ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker // This file may be freely copied for any purpose module shift(); reg [5:0] S; wire [63:0] Y; assign Y = 1 << S; initial begin S = 32; #1 $display("1 << %0d = %b", S, Y); end endmodule iverilog-12_0/ivtest/ivltests/pr2121536.v000066400000000000000000000017761435245347300201310ustar00rootroot00000000000000module top(); reg pass = 1'b1; reg [31:0] in = 'bx; reg signed [31:0] sin = 'bx; wire [63:0] res; wire signed [63:0] sres; lower lwr(res, in); slower slwr(sres, sin); initial begin #1; if (res !== {32'b0, 32'bx}) begin $display("FAILED: unsigned output (%b)", res); pass = 1'b0; end if (lwr.lout !== {32'b0, 32'bx}) begin $display("FAILED: unsigned input (%b)", lwr.lout); pass = 1'b0; end if (sres !== 64'bx) begin $display("FAILED: signed output (%b)", sres); pass = 1'b0; end if (slwr.lout !== 64'bx) begin $display("FAILED: signed input (%b)", slwr.lout); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule module lower(lrtn, lin); output [31:0] lrtn; input [63:0] lin; wire [63:0] lout = lin; assign lrtn = lout[31:0]; endmodule module slower(lrtn, lin); output signed [31:0] lrtn; input signed[63:0] lin; wire signed [63:0] lout = lin; assign lrtn = lout[31:0]; endmodule iverilog-12_0/ivtest/ivltests/pr2121536b.v000066400000000000000000000017341435245347300202650ustar00rootroot00000000000000module top(); reg pass = 1'b1; reg [31:0] in = 'bx; reg signed [31:0] sin = 'bx; wire [63:0] res, sres; lower lwr(res, in); slower slwr(sres, sin); initial begin #1; if (res !== {32'b0, 32'bx}) begin $display("FAILED: unsigned output (%b)", res); pass = 1'b0; end if (lwr.lout !== {32'b0, 32'bx}) begin $display("FAILED: unsigned input (%b)", lwr.lout); pass = 1'b0; end if (sres !== 64'bx) begin $display("FAILED: signed output (%b)", sres); pass = 1'b0; end if (slwr.lout !== 64'bx) begin $display("FAILED: signed input (%b)", slwr.lout); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule module lower(lrtn, lin); output [31:0] lrtn; input [63:0] lin; wire [63:0] lout = lin; assign lrtn = lout[31:0]; endmodule module slower(lrtn, lin); output signed [31:0] lrtn; input [63:0] lin; wire [63:0] lout = lin; assign lrtn = lout[31:0]; endmodule iverilog-12_0/ivtest/ivltests/pr2123158.v000066400000000000000000000005711435245347300201230ustar00rootroot00000000000000module top; reg pass = 1'b1; wire real rval; real in; assign rval = in + 2; initial begin // $monitor(rval,, in); in = 0; #1 in = 1; #1 in = 2; #1 if (pass) $display("PASSED"); end always @(rval) begin if (rval != in + 2.0) begin $display("FAILED: expected %f, got %f", in + 2.0, rval); pass = 1'b0; end end endmodule iverilog-12_0/ivtest/ivltests/pr2123190.v000066400000000000000000000013051435245347300201130ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_REAL_NETS_IN_IVTEST `endif module top; reg pass = 1'b1; integer scale = 2, offset = 1; real rin; `ifdef SUPPORT_REAL_NETS_IN_IVTEST wire real ress = scale * rin; wire real reso = rin + offset; `endif initial begin `ifdef SUPPORT_REAL_NETS_IN_IVTEST #1 if (ress != 0.0 || reso != 1.0) begin $display("FAILED: initial value, expected 0.0/1.0, got %f/%f", ress, reso); pass = 1'b0; end rin = 2.0; #1 if (ress != 4.0 || reso != 3.0) begin $display("FAILED: rin=%f, scale=%f, expected 2.0/2.0, got %f/%f", rin, scale, ress, reso); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2132552.v000066400000000000000000000004771435245347300201260ustar00rootroot00000000000000module pr2132552(); task test_task; parameter depth = 16; parameter width = 8; reg [width-1:0] mem [depth-1:0]; integer i; begin for (i = 0; i < depth; i = i + 1) begin mem[i] = i; end for (i = 0; i < depth; i = i + 1) begin $display("%0d", mem[i]); end end endtask initial test_task; endmodule iverilog-12_0/ivtest/ivltests/pr2136787.v000066400000000000000000000011321435245347300201310ustar00rootroot00000000000000module signed_mux_bug(); reg s; reg [3:0] a, b; reg [7:0] y, z; initial begin // Example vector s = 1'b1; a = 4'b1010; b = 4'b0000; // Manually sign extend operands before multiplexer y = s ? {{4{a[3]}}, a} : {{4{b[3]}}, b}; // Use $signed() to sign extend operands before multiplexer // - Note that Icarus is not sign extending as expected z = s ? $signed(a) : $signed(b); // Display results $display("a = %b", a); $display("b = %b", b); $display("y = %b", y); $display("z = %b", z); // Finished $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr2138682.v000066400000000000000000000011731435245347300201320ustar00rootroot00000000000000module bug(); wire [2:0] Value1 = 0; generate genvar i; for (i = 0; i < 8; i = i + 1) begin:Block wire [2:0] Value2; assign Value2 = Value1 + 7 - i; end endgenerate initial begin #1; $display("Block 0 value = %0d", Block[0].Value2); $display("Block 1 value = %0d", Block[1].Value2); $display("Block 2 value = %0d", Block[2].Value2); $display("Block 3 value = %0d", Block[3].Value2); $display("Block 4 value = %0d", Block[4].Value2); $display("Block 5 value = %0d", Block[5].Value2); $display("Block 6 value = %0d", Block[6].Value2); $display("Block 7 value = %0d", Block[7].Value2); end endmodule iverilog-12_0/ivtest/ivltests/pr2138979.v000066400000000000000000000022111435245347300201350ustar00rootroot00000000000000// This program is based on pr2138979. In particular, the signed // expressions are sign-extended before the '|' is evaluated. This // behavior is verified by modelsim and ncverilog. (It appears that // gplcver gets this wrong.) module main; reg [7:0] a, b; wire [15:0] y; reg [15:0] z; // Use $signed() to sign extend operands before logic OR // - Note that Icarus Verilog is not sign extending as expected assign y = $signed(a) | $signed(b); initial begin a = 8'h55; b = 8'haa; z = $signed(a) | $signed(b); #1 if (y !== 16'hff_ff || y !== z) begin $display("FAILED -- a=%h, b=%h, y=%h, z=%h", a, b, y, z); $finish; end a = 8'haa; b = 8'h55; z = $signed(a) | $signed(b); #1 if (y !== 16'hff_ff || y !== z) begin $display("FAILED -- a=%h, b=%h, y=%h, z=%h", a, b, y, z); $finish; end a = 8'h7f; b = 8'h00; z = $signed(a) | $signed(b); #1 if (y !== 16'h00_7f || y !== z) begin $display("FAILED -- a=%h, b=%h, y=%h, z=%h", a, b, y, z); $finish; end $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr2138979b.v000066400000000000000000000034631435245347300203110ustar00rootroot00000000000000module signed_logic_operators_bug(); reg [7:0] a, b; wire [15:0] yuu, yus, ysu, yss; wire [15:0] zuu, zus, zsu, zss; initial begin // Example vector a = 8'b10110110; b = 8'b10010010; // Wait for results to be calculated #1; // Display results $display("a = %b", a); $display("b = %b", b); $display("yuu = %b", yuu); $display("zuu = %b", zuu); $display("yus = %b", yus); $display("zus = %b", zus); $display("ysu = %b", ysu); $display("zsu = %b", zsu); $display("yss = %b", yss); $display("zss = %b", zss); // Finished $finish(0); end // Calculate signed logical OR manually_extended_logical_or INST1(.a(a), .b(b), .yuu(yuu), .yus(yus), .ysu(ysu), .yss(yss)); signed_logical_or INST2(.a(a), .b(b), .yuu(zuu), .yus(zus), .ysu(zsu), .yss(zss)); endmodule module manually_extended_logical_or(a, b, yuu, yus, ysu, yss); input [7:0] a, b; output [15:0] yuu, yus, ysu, yss; // Manually zero or sign extend operands before logic OR // - Note the operands are zero extended in "yuu", "yus" and "ysu" // - The operands are sign extended in "yss" assign yuu = {{8{1'b0}}, a} | {{8{1'b0}}, b}; assign yus = {{8{1'b0}}, a} | {{8{1'b0}}, b}; assign ysu = {{8{1'b0}}, a} | {{8{1'b0}}, b}; assign yss = {{8{a[7]}}, a} | {{8{b[7]}}, b}; endmodule module signed_logical_or(a, b, yuu, yus, ysu, yss); input [7:0] a, b; output [15:0] yuu, yus, ysu, yss; // Note that the operation is only consider signed if ALL data operands are signed // - Therefore $signed(a) does NOT sign extend "a" in expression "ysu" // - But "a" and "b" are both sign extended before the OR in expression "yss" assign yuu = a | b ; assign yus = a | $signed(b); assign ysu = $signed(a) | b ; assign yss = $signed(a) | $signed(b); endmodule iverilog-12_0/ivtest/ivltests/pr2138979c.v000066400000000000000000000014121435245347300203020ustar00rootroot00000000000000module signed_assignment_bug(); reg [7:0] a; wire [15:0] y; wire [15:0] z; initial begin // Example vector a = 8'b10110110; // Wait for results to be calculated #1; // Display results $display("a = %b", a); $display("y = %b", y); $display("z = %b", z); // Finished $finish(0); end // Calculate signed logical OR manually_extended_assignment INST1(.a(a), .y(y)); signed_assignment INST2(.a(a), .y(z)); endmodule module manually_extended_assignment(a, y); input [7:0] a; output [15:0] y; // Manually sign extend before assignment assign y = {{8{a[7]}}, a}; endmodule module signed_assignment(a, y); input [7:0] a; output [15:0] y; // $signed() sign extends before assignment assign y = $signed(a); endmodule iverilog-12_0/ivtest/ivltests/pr2138979d.v000066400000000000000000000227621435245347300203160ustar00rootroot00000000000000module signed_logic_operators_bug(); reg sel; reg [7:0] a, b; reg [5:0] c; wire [15:0] y_mux_uu, y_mux_us, y_mux_su, y_mux_ss; wire y_eql_uu, y_eql_us, y_eql_su, y_eql_ss; wire y_neq_uu, y_neq_us, y_neq_su, y_neq_ss; wire [15:0] y_sgn_u, y_sgn_s; wire [15:0] y_add_uu, y_add_us, y_add_su, y_add_ss; wire [15:0] y_sub_uu, y_sub_us, y_sub_su, y_sub_ss; wire [15:0] y_mul_uu, y_mul_us, y_mul_su, y_mul_ss; wire y_ltn_uu, y_ltn_us, y_ltn_su, y_ltn_ss; wire y_leq_uu, y_leq_us, y_leq_su, y_leq_ss; wire [15:0] z_mux_uu, z_mux_us, z_mux_su, z_mux_ss; wire z_eql_uu, z_eql_us, z_eql_su, z_eql_ss; wire z_neq_uu, z_neq_us, z_neq_su, z_neq_ss; wire [15:0] z_sgn_u, z_sgn_s; wire [15:0] z_add_uu, z_add_us, z_add_su, z_add_ss; wire [15:0] z_sub_uu, z_sub_us, z_sub_su, z_sub_ss; wire [15:0] z_mul_uu, z_mul_us, z_mul_su, z_mul_ss; wire z_ltn_uu, z_ltn_us, z_ltn_su, z_ltn_ss; wire z_leq_uu, z_leq_us, z_leq_su, z_leq_ss; integer i; initial begin for (i = 0; i < 100; i = i + 1) begin // Example vector sel = $random; a = $random; b = $random; c = $random; // Wait for results to be calculated #1; // Display results $display("sel = %b", sel); $display("a = %b", a); $display("b = %b", b); $display("c = %b", c); $display("y_mux_uu = %b y_mux_us = %b y_mux_su = %b y_mux_ss = %b", y_mux_uu, y_mux_us, y_mux_su, y_mux_ss); $display("z_mux_uu = %b z_mux_us = %b z_mux_su = %b z_mux_ss = %b", z_mux_uu, z_mux_us, z_mux_su, z_mux_ss); $display("y_eql_uu = %b y_eql_us = %b y_eql_su = %b y_eql_ss = %b", y_eql_uu, y_eql_us, y_eql_su, y_eql_ss); $display("z_eql_uu = %b z_eql_us = %b z_eql_su = %b z_eql_ss = %b", z_eql_uu, z_eql_us, z_eql_su, z_eql_ss); $display("y_neq_uu = %b y_neq_us = %b y_neq_su = %b y_neq_ss = %b", y_neq_uu, y_neq_us, y_neq_su, y_neq_ss); $display("z_neq_uu = %b z_neq_us = %b z_neq_su = %b z_neq_ss = %b", z_neq_uu, z_neq_us, z_neq_su, z_neq_ss); $display("y_sgn_u = %b y_sgn_s = %b" , y_sgn_u, y_sgn_s); $display("z_sgn_u = %b z_sgn_s = %b" , z_sgn_u, z_sgn_s); $display("y_add_uu = %b y_add_us = %b y_add_su = %b y_add_ss = %b", y_add_uu, y_add_us, y_add_su, y_add_ss); $display("z_add_uu = %b z_add_us = %b z_add_su = %b z_add_ss = %b", z_add_uu, z_add_us, z_add_su, z_add_ss); $display("y_sub_uu = %b y_sub_us = %b y_sub_su = %b y_sub_ss = %b", y_sub_uu, y_sub_us, y_sub_su, y_sub_ss); $display("z_sub_uu = %b z_sub_us = %b z_sub_su = %b z_sub_ss = %b", z_sub_uu, z_sub_us, z_sub_su, z_sub_ss); $display("y_mul_uu = %b y_mul_us = %b y_mul_su = %b y_mul_ss = %b", y_mul_uu, y_mul_us, y_mul_su, y_mul_ss); $display("z_mul_uu = %b z_mul_us = %b z_mul_su = %b z_mul_ss = %b", z_mul_uu, z_mul_us, z_mul_su, z_mul_ss); $display("y_ltn_uu = %b y_ltn_us = %b y_ltn_su = %b y_ltn_ss = %b", y_ltn_uu, y_ltn_us, y_ltn_su, y_ltn_ss); $display("z_ltn_uu = %b z_ltn_us = %b z_ltn_su = %b z_ltn_ss = %b", z_ltn_uu, z_ltn_us, z_ltn_su, z_ltn_ss); $display("y_leq_uu = %b y_leq_us = %b y_leq_su = %b y_leq_ss = %b", y_leq_uu, y_leq_us, y_leq_su, y_leq_ss); $display("z_leq_uu = %b z_leq_us = %b z_leq_su = %b z_leq_ss = %b", z_leq_uu, z_leq_us, z_leq_su, z_leq_ss); end // Finished $finish(0); end // Manually sign extended operators manually_extended_operators INST1( sel, a, b, c, y_mux_uu, y_mux_us, y_mux_su, y_mux_ss, y_eql_uu, y_eql_us, y_eql_su, y_eql_ss, y_neq_uu, y_neq_us, y_neq_su, y_neq_ss, y_sgn_u, y_sgn_s, y_add_uu, y_add_us, y_add_su, y_add_ss, y_sub_uu, y_sub_us, y_sub_su, y_sub_ss, y_mul_uu, y_mul_us, y_mul_su, y_mul_ss, y_ltn_uu, y_ltn_us, y_ltn_su, y_ltn_ss, y_leq_uu, y_leq_us, y_leq_su, y_leq_ss ); // $signed() sign extended operators signed_operators INST2( sel, a, b, c, z_mux_uu, z_mux_us, z_mux_su, z_mux_ss, z_eql_uu, z_eql_us, z_eql_su, z_eql_ss, z_neq_uu, z_neq_us, z_neq_su, z_neq_ss, z_sgn_u, z_sgn_s, z_add_uu, z_add_us, z_add_su, z_add_ss, z_sub_uu, z_sub_us, z_sub_su, z_sub_ss, z_mul_uu, z_mul_us, z_mul_su, z_mul_ss, z_ltn_uu, z_ltn_us, z_ltn_su, z_ltn_ss, z_leq_uu, z_leq_us, z_leq_su, z_leq_ss ); endmodule module signed_operators( sel, a, b, c, mux_uu, mux_us, mux_su, mux_ss, eql_uu, eql_us, eql_su, eql_ss, neq_uu, neq_us, neq_su, neq_ss, sgn_u, sgn_s, add_uu, add_us, add_su, add_ss, sub_uu, sub_us, sub_su, sub_ss, mul_uu, mul_us, mul_su, mul_ss, ltn_uu, ltn_us, ltn_su, ltn_ss, leq_uu, leq_us, leq_su, leq_ss ); input sel; input [7:0] a, b; input [5:0] c; output [15:0] mux_uu, mux_us, mux_su, mux_ss; output eql_uu, eql_us, eql_su, eql_ss; output neq_uu, neq_us, neq_su, neq_ss; output [15:0] sgn_u, sgn_s; output [15:0] add_uu, add_us, add_su, add_ss; output [15:0] sub_uu, sub_us, sub_su, sub_ss; output [15:0] mul_uu, mul_us, mul_su, mul_ss; output ltn_uu, ltn_us, ltn_su, ltn_ss; output leq_uu, leq_us, leq_su, leq_ss; // Note that the operation is only consider signed if ALL data operands are signed // - Therefore $signed(a) does NOT sign extend "a" in expression "X_su" // - But "a" and "b" are both sign extended before the operation in expression "X_ss" assign mux_uu = sel ? a : b ; assign mux_us = sel ? a : $signed(b); assign mux_su = sel ? $signed(a) : b ; assign mux_ss = sel ? $signed(a) : $signed(b); assign eql_uu = a == c ; assign eql_us = a == $signed(c); assign eql_su = $signed(a) == c ; assign eql_ss = $signed(a) == $signed(c); assign neq_uu = a != c ; assign neq_us = a != $signed(c); assign neq_su = $signed(a) != c ; assign neq_ss = $signed(a) != $signed(c); assign sgn_u = ~$unsigned(c) ; assign sgn_s = ~$signed(c) ; assign add_uu = a + c ; assign add_us = a + $signed(c); assign add_su = $signed(a) + c ; assign add_ss = $signed(a) + $signed(c); assign sub_uu = a - c ; assign sub_us = a - $signed(c); assign sub_su = $signed(a) - c ; assign sub_ss = $signed(a) - $signed(c); assign mul_uu = a * c ; assign mul_us = a * $signed(c); assign mul_su = $signed(a) * c ; assign mul_ss = $signed(a) * $signed(c); assign ltn_uu = a < c ; assign ltn_us = a < $signed(c); assign ltn_su = $signed(a) < c ; assign ltn_ss = $signed(a) < $signed(c); assign leq_uu = a <= c ; assign leq_us = a <= $signed(c); assign leq_su = $signed(a) <= c ; assign leq_ss = $signed(a) <= $signed(c); endmodule module manually_extended_operators( sel, a, b, c, mux_uu, mux_us, mux_su, mux_ss, eql_uu, eql_us, eql_su, eql_ss, neq_uu, neq_us, neq_su, neq_ss, sgn_u, sgn_s, add_uu, add_us, add_su, add_ss, sub_uu, sub_us, sub_su, sub_ss, mul_uu, mul_us, mul_su, mul_ss, ltn_uu, ltn_us, ltn_su, ltn_ss, leq_uu, leq_us, leq_su, leq_ss ); input sel; input [7:0] a, b; input [5:0] c; output [15:0] mux_uu, mux_us, mux_su, mux_ss; output eql_uu, eql_us, eql_su, eql_ss; output neq_uu, neq_us, neq_su, neq_ss; output [15:0] sgn_u, sgn_s; output [15:0] add_uu, add_us, add_su, add_ss; output [15:0] sub_uu, sub_us, sub_su, sub_ss; output [15:0] mul_uu, mul_us, mul_su, mul_ss; output ltn_uu, ltn_us, ltn_su, ltn_ss; output leq_uu, leq_us, leq_su, leq_ss; // Manually zero or sign extend operands before the operation. // - Note the operands are zero extended in "X_uu", "X_us" and "X_su" // - The operands are sign extended in "X_ss" assign mux_uu = sel ? {{8{1'b0}}, a} : {{8{1'b0}}, b}; assign mux_us = sel ? {{8{1'b0}}, a} : {{8{1'b0}}, b}; assign mux_su = sel ? {{8{1'b0}}, a} : {{8{1'b0}}, b}; assign mux_ss = sel ? {{8{a[7]}}, a} : {{8{b[7]}}, b}; assign eql_uu = {a} == {{2{1'b0}}, c}; assign eql_us = {a} == {{2{1'b0}}, c}; assign eql_su = {a} == {{2{1'b0}}, c}; assign eql_ss = {a} == {{2{c[5]}}, c}; assign neq_uu = {a} != {{2{1'b0}}, c}; assign neq_us = {a} != {{2{1'b0}}, c}; assign neq_su = {a} != {{2{1'b0}}, c}; assign neq_ss = {a} != {{2{c[5]}}, c}; assign sgn_u = ~{{10{1'b0}}, c} ; assign sgn_s = ~{{10{c[5]}}, c} ; assign add_uu = {{8{1'b0}}, a} + {{10{1'b0}}, c}; assign add_us = {{8{1'b0}}, a} + {{10{1'b0}}, c}; assign add_su = {{8{1'b0}}, a} + {{10{1'b0}}, c}; assign add_ss = {{8{a[7]}}, a} + {{10{c[5]}}, c}; assign sub_uu = {{8{1'b0}}, a} - {{10{1'b0}}, c}; assign sub_us = {{8{1'b0}}, a} - {{10{1'b0}}, c}; assign sub_su = {{8{1'b0}}, a} - {{10{1'b0}}, c}; assign sub_ss = {{8{a[7]}}, a} - {{10{c[5]}}, c}; assign mul_uu = {{8{1'b0}}, a} * {{10{1'b0}}, c}; assign mul_us = {{8{1'b0}}, a} * {{10{1'b0}}, c}; assign mul_su = {{8{1'b0}}, a} * {{10{1'b0}}, c}; assign mul_ss = {{8{a[7]}}, a} * {{10{c[5]}}, c}; assign ltn_uu = {{8{1'b0}}, a} < {{10{1'b0}}, c}; assign ltn_us = {{8{1'b0}}, a} < {{10{1'b0}}, c}; assign ltn_su = {{8{1'b0}}, a} < {{10{1'b0}}, c}; assign ltn_ss = {c[5],{7{a[7]}}, a} < {a[7],{9{c[5]}}, c}; assign leq_uu = {{8{1'b0}}, a} <= {{10{1'b0}}, c}; assign leq_us = {{8{1'b0}}, a} <= {{10{1'b0}}, c}; assign leq_su = {{8{1'b0}}, a} <= {{10{1'b0}}, c}; assign leq_ss = {c[5],{7{a[7]}}, a} <= {a[7],{9{c[5]}}, c}; endmodule iverilog-12_0/ivtest/ivltests/pr2139593.v000066400000000000000000000007651435245347300201420ustar00rootroot00000000000000module top; tb #(1024) dut(); defparam dut.Y = 2048; endmodule module tb; reg pass = 1'b1; parameter Z = 256; parameter Y = 128; parameter B = $clog2(Z); localparam C = $clog2(Y); initial begin if (B !== 10) begin $display("FAILED: parameter value, expected 10, got %0d", B); pass = 1'b0; end if (C !== 11) begin $display("FAILED: localparam value, expected 11, got %0d", C); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2146620.v000066400000000000000000000003511435245347300201160ustar00rootroot00000000000000module bug(); integer i; integer j; reg [7:0] Value; initial begin for (i = 0; i < 2; i = i + 1) begin for (j = 0; j < 2; j = j + 1) begin Value = i * 256 + j * 128; $display(Value); end end end endmodule iverilog-12_0/ivtest/ivltests/pr2146620b.v000066400000000000000000000003071435245347300202610ustar00rootroot00000000000000module bug(); localparam Size = 24; reg [2:0] Value; integer n; initial begin for (n = 0; n < (Size/4); n = n + 1) begin Value = (Size/4) - n - 1; $display(Value); end end endmodule iverilog-12_0/ivtest/ivltests/pr2146620c.v000066400000000000000000000005041435245347300202610ustar00rootroot00000000000000module comp1001a; // extracted from comp1001.v, // Copyright (c) 2000 Paul Campbell (paul@verifarm.com) // GPLv2 or later blah blah blah reg [4:0] r170; initial begin r170 = (5'h1c % 25'h5b50) - 20'h05818; $displayb("r170 = ",r170); if (r170 == 5'b00100) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2146824.v000066400000000000000000000002041435245347300201210ustar00rootroot00000000000000module bug(); reg [9:0] i; reg [7:0] j; initial begin i = 10'h3ff; j = (i / 4) & 8'hfe; $display("'h%h", j); end endmodule iverilog-12_0/ivtest/ivltests/pr2148401.v000066400000000000000000000003141435245347300201140ustar00rootroot00000000000000module top; reg [79:0] data = 0; initial begin data = data + 80'h12345678901234567890; if (data !== 80'h12345678901234567890) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2152011.v000066400000000000000000000002451435245347300201070ustar00rootroot00000000000000module dupe; integer cc; reg signed [19:0] y; initial for (cc=0; cc<20; cc=cc+1) begin y = $floor(200000.0*$sin(cc*0.81)+0.5); $display("%7d", y); end endmodule iverilog-12_0/ivtest/ivltests/pr2159630.v000066400000000000000000000005771435245347300201350ustar00rootroot00000000000000module test(); parameter N_N = 3; reg signed [2*N_N-1:0] val_neg; reg signed [2*N_N-1:0] val_pos; initial begin val_neg = {{N_N+1{1'b1}},{N_N-1{1'b0}}}; val_pos = {{N_N+1{1'b0}},{N_N-1{1'b1}}}; #1 $display("Var %d vs signed(concat) %d", val_neg, $signed({{N_N+1{1'b1}},{N_N-1{1'b0}}})); $finish(0); end // initial begin endmodule // test iverilog-12_0/ivtest/ivltests/pr2166188.v000066400000000000000000000006161435245347300201350ustar00rootroot00000000000000module t(); parameter eh = 11; parameter mh = 52; parameter ih2 = 6; parameter fh = 7; localparam ih = 1 << ih2; reg [ih - 1:0] i_abs; reg at; reg [ih2 - 1:0] fls; wire [ih - 1:0] i_norm; assign i_norm = i_abs << (at ? ih - mh - 1 : fls); initial begin at = 1; fls = 123; i_abs = 'h123; #1; if(i_norm !== ('h123 << 11)) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2166311.v000066400000000000000000000046621435245347300201260ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass = 1'b1; wire [3:0] part_idx_up, part_idx_down, part_sel; wire [3:0] ps_array [1:0]; // Check the positive indexed part select. // assign part_idx_up[-1+:2] = 2'b01; // We do not currently support this! assign part_idx_up[1+:2] = 2'b01; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign part_idx_up[3+:2] = 2'b01; assign part_idx_up[5+:2] = 2'b01; // This should be skipped assign part_idx_up[7+:3] = 3'b001; // This should be skipped `else assign part_idx_up[3] = 1'b1; `endif // Check the negative indexed part select. // assign part_idx_down[0-:2] = 2'b10; // We do not currently support this! assign part_idx_down[2-:2] = 2'b10; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign part_idx_down[4-:2] = 2'b10; assign part_idx_down[6-:2] = 2'b10; // This should be skipped assign part_idx_down[9-:3] = 3'b100; // This should be skipped `else assign part_idx_down[3] = 1'b0; `endif // Check a normal constant part select. // assign part_sel[1:-1] = 2'b01; // We do not currently support this! assign part_sel[2:1] = 2'b01; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign part_sel[4:3] = 2'b01; assign part_sel[6:5] = 2'b01; // This should be skipped assign part_sel[9:7] = 3'b001; // This should be skipped `else assign part_sel[3] = 1'b1; `endif // Check a normal constant part select on an array. // assign ps_array[0][1:-1] = 2'b01; // We do not currently support this! assign ps_array[0][2:1] = 2'b01; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign ps_array[0][4:3] = 2'b01; assign ps_array[0][6:5] = 2'b01; // This should be skipped assign ps_array[0][9:7] = 3'b001; // This should be skipped `else assign ps_array[0][3] = 1'b1; `endif initial begin #1; if (part_idx_up !== 4'b101z) begin $display("Failed +: select, expected 4'b101z, got %b", part_idx_up); pass = 1'b0; end if (part_idx_down !== 4'b010z) begin $display("Failed -: select, expected 4'b010z, got %b", part_idx_down); pass = 1'b0; end if (part_sel !== 4'b101z) begin $display("Failed const. part select, expected 4'b101z, got %b", part_sel); pass = 1'b0; end if (ps_array[0] !== 4'b101z) begin $display("Failed array part select, expected 4'b101z, got %b", ps_array[0]); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2169870.v000066400000000000000000000004671435245347300201420ustar00rootroot00000000000000// Copyright 2008, Martin Whitaker. // This file may be copied freely for any purpose. No attribution required. module pr2169870(); task automatic count; integer i; begin i = 0; while (i < 10) begin #1 $display("%0d", i); i = i + 1; end end endtask initial count; initial count; endmodule iverilog-12_0/ivtest/ivltests/pr2172606.v000066400000000000000000000022201435245347300201160ustar00rootroot00000000000000module main; reg passed = 1'b1; wire out1; reg local_out; reg mode; assign out1 = mode ? 1'bz : local_out; pullup(out1); initial begin mode = 1'b1; local_out = 1'bx; // The pull up device sets the level. #1 if (out1 !== 1'b1) begin $display("FAILED test 1, expected 1'b1, got %b", out1); passed = 1'b0; end mode = 1'b0; local_out = 1'b0; // Set by local out. #1 if (out1 !== local_out) begin $display("FAILED test 1, expected %b, got %b", local_out, out1); passed = 1'b0; end local_out = 1'b1; // Set by local out. #1 if (out1 !== local_out) begin $display("FAILED test 1, expected %b, got %b", local_out, out1); passed = 1'b0; end local_out = 1'bx; // Set by local out. #1 if (out1 !== local_out) begin $display("FAILED test 1, expected %b, got %b", local_out, out1); passed = 1'b0; end local_out = 1'bz; // The pull up device sets the level. #1 if (out1 !== 1'b1) begin $display("FAILED test 1, expected 1'b1, got %b", out1); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2172606b.v000066400000000000000000000062511435245347300202700ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg passed = 1'b1; wire out, cout0, cout1; reg sel, in_1, in_0; reg pout; `ifdef __ICARUS__ // This is technically incorrect for 1'bz inputs. The standard // states that we should produce 1'bx for that case (idiotic)! localparam zz_blend = 1'bz; `else localparam zz_blend = 1'bx; `endif assign cout0 = sel ? 1'bz : in_0; assign cout1 = sel ? in_1: 1'bz; assign out = sel ? in_1: in_0; task automatic check; input bit, in_1, in_0; input [63:0] comment; begin if (sel === 1'b1) begin if (bit !== in_1) begin $display("FAILED: %0s sel = 1'b1, expected %b, got %b", comment, in_1, bit); passed = 1'b0; end end else if (sel === 1'b0) begin if (bit !== in_0) begin $display("FAILED: %0s sel = 1'b0, expected %b, got %b", comment, in_0, bit); passed = 1'b0; end end else begin if (in_0 === 1'bz && in_1 === 1'bz && bit !== zz_blend) begin $display("FAILED: %0s sel = 1'bx/z & ins = %b, expected 1'b%b, got %b", comment, in_0, zz_blend, bit); passed = 1'b0; end else if (in_0 === in_1 && in_0 !== bit) begin $display("FAILED: %0s sel = 1'bx/z & ins = %b, expected 1'b%b, got %b", comment, in_0, in_0, bit); passed = 1'b0; end else if (in_0 !== in_1 && bit !== 1'bx) begin $display("FAILED: %0s sel = 1'bx/z & %b %b, expected 1'bx, got %b", comment, in_1, in_0, bit); passed = 1'b0; end end end endtask // Check the 1 case as a constant Z always @(cout0) begin check(cout0, 1'bz, in_0, "CZ 1"); end // Check the 0 case as a constant Z always @(cout1) begin check(cout1, in_1, 1'bz, "CZ 0"); end // Check the continuous assign always @(out) begin check(out, in_1, in_0, "CA"); end // Check procedural assign. always @(sel, in_1, in_0) begin check(sel ? in_1 : in_0, in_1, in_0, "PR"); end initial begin #1 sel = 1'b1; #1 in_1 = 1'b0; #1 in_1 = 1'b1; #1 in_1 = 1'bz; #1 in_1 = 1'bx; #1 sel = 1'b0; #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 sel = 1'bx; #1 in_1 = 1'b0; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'b1; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'bz; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'bx; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 sel = 1'bz; #1 in_1 = 1'b0; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'b1; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'bz; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 in_1 = 1'bx; // #1 in_0 = 1'b0; #1 in_0 = 1'b1; #1 in_0 = 1'bz; #1 in_0 = 1'bx; #1 if (passed) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2181249.v000066400000000000000000000003201435245347300201200ustar00rootroot00000000000000module pr0; reg r; initial r = ( 1'b1 ? 1'b0 : 1'b0) ? 1'b0 : 1'b0; initial begin #1 if (r !== 1'b0) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2190323.v000066400000000000000000000011551435245347300201200ustar00rootroot00000000000000/* * This is a reduced example from comp1001 to demonstrate a problem * in Icarus Verilog. Since this fails using just the compiler this * appears to be a problem in the elaboration of the expression. * * The division should be done at the L-value width not at the * argument width. This is not the case for this example. */ module compl1001; reg [133:124]r66; initial begin // r66 = ((!1'b1) / ((18'h0 - (1'b1 + 1'b1)) <= 10'h000)); r66 = (!1'b1) / 1'b0; // This fails. // r66 = 1'b0 / 1'b0; // This passes. if (r66 !== 10'bx) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2201909.v000066400000000000000000000006621435245347300201250ustar00rootroot00000000000000module top; reg passed = 1'b1; real rvar [1:0]; initial begin #1; rvar[0] = -1.0; if (rvar[0] != -1.0) begin $display("Failed: real array[0], expected -1.0, got %g", rvar[0]); passed = 1'b0; end rvar[1] = 2.0; if (rvar[1] != 2.0) begin $display("Failed: real array[1], expected 2.0, got %g", rvar[1]); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2201909b.v000066400000000000000000000007001435245347300202600ustar00rootroot00000000000000module top; reg passed = 1'b1; realtime rvar [1:0]; initial begin #1; rvar[0] = -1.0; if (rvar[0] != -1.0) begin $display("Failed: real time array[0], expected -1.0, got %g", rvar[0]); passed = 1'b0; end rvar[1] = 2.0; if (rvar[1] != 2.0) begin $display("Failed: real time array[1], expected 2.0, got %g", rvar[1]); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2202706.v000066400000000000000000000013101435245347300201100ustar00rootroot00000000000000module top; reg passed; reg [63:0] wide; reg [31:0] norm; initial begin passed = 1'b1; if (! $value$plusargs("option=%h", wide)) begin $display("FAILED: Unable to read wide option"); passed = 1'b0; end if (wide !== 64'h0123456789abcdef) begin $display("FAILED: wide expected 64'h0123456789abcdef, got %h", wide); passed = 1'b0; end if (! $value$plusargs("option=%h", norm)) begin $display("FAILED: Unable to read normal option"); passed = 1'b0; end if (norm !== 32'h89abcdef) begin $display("FAILED: normal expected 32'h89abcdef, got %h", norm); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2202706b.v000066400000000000000000000007121435245347300202570ustar00rootroot00000000000000module top; reg passed; initial begin passed = 1'b1; if ($test$plusargs("opt") == 0) begin $display("Failed to find +opt"); passed = 1'b0; end if ($test$plusargs("option") == 0) begin $display("Failed to find +option"); passed = 1'b0; end if ($test$plusargs("options") != 0) begin $display("Failed, found +options"); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2202706c.v000066400000000000000000000200061435245347300202560ustar00rootroot00000000000000module top; reg passed; reg [9*8:1] check; reg [71:0] value; reg [7:0] nval; real rval; initial begin passed = 1'b1; // Look for the hex value using a runtime string. check = "hex=%h"; if (! $value$plusargs(check, value)) begin $display("FAILED: Unable to get hex value."); passed = 1'b0; end if (value !== 72'h0123456789abcdefxz) begin $display("FAILED: expected hex value 72'h0123456789abcdefxz, got %h", value); passed = 1'b0; end // Look for a hex (x) value. if (! $value$plusargs("hex=%x", value)) begin $display("FAILED: Unable to get hex value."); passed = 1'b0; end if (value !== 72'h0123456789abcdefxz) begin $display("FAILED: expected hex value 72'h0123456789abcdefxz, got %h", value); passed = 1'b0; end // Look for an octal value. if (! $value$plusargs("oct=%o", value)) begin $display("FAILED: Unable to get octal value."); passed = 1'b0; end if (value !== 72'o01234567xz) begin $display("FAILED: expected octal value 72'o01234567xz, got %o", value); passed = 1'b0; end // Look for a binary value. if (! $value$plusargs("bin=%b", value)) begin $display("FAILED: Unable to get binary value."); passed = 1'b0; end if (value !== 72'b0101xz) begin $display("FAILED: expected binary value 72'b0101xz, got %b", value); passed = 1'b0; end // Look for a negative binary value. if (! $value$plusargs("neg=%b", value)) begin $display("FAILED: Unable to get negative binary value."); passed = 1'b0; end if (value !== 72'hfffffffffffffffffc) begin $display("FAILED: expected binary value 72'hff...fc, got %h", value); passed = 1'b0; end // Look for a negative octal value. if (! $value$plusargs("neg=%o", value)) begin $display("FAILED: Unable to get negative octal value."); passed = 1'b0; end if (value !== 72'hffffffffffffffffc0) begin $display("FAILED: expected octal value 72'hff...fc0, got %h", value); passed = 1'b0; end // Look for a truncated negative hex value. if (! $value$plusargs("neg=%h", nval)) begin $display("FAILED: Unable to get negative hex value."); passed = 1'b0; end if (nval !== 8'h00) begin $display("FAILED: expected hex value 8'h00, got %h", nval); passed = 1'b0; end // Look for a bad binary value. if (! $value$plusargs("bad_num=%b", value)) begin $display("FAILED: Unable to get bad binary value."); passed = 1'b0; end if (value !== 'bx) begin $display("FAILED: expected bad binary value 'bx, got %d", value); passed = 1'b0; end // Look for a bad octal value. if (! $value$plusargs("bad_num=%o", value)) begin $display("FAILED: Unable to get bad octal value."); passed = 1'b0; end if (value !== 'bx) begin $display("FAILED: expected bad octal value 'bx, got %d", value); passed = 1'b0; end // Look for a bad hex value. if (! $value$plusargs("bad_num=%h", value)) begin $display("FAILED: Unable to get bad hex value."); passed = 1'b0; end if (value !== 'bx) begin $display("FAILED: expected bad hex value 'bx, got %d", value); passed = 1'b0; end // Look for a bad hex (x) value. if (! $value$plusargs("bad_num=%x", value)) begin $display("FAILED: Unable to get bad hex (x) value."); passed = 1'b0; end if (value !== 'bx) begin $display("FAILED: expected bad hex (x) value 'bx, got %d", value); passed = 1'b0; end // Look for a decimal value. if (! $value$plusargs("dec=%d", value)) begin $display("FAILED: Unable to get decimal value."); passed = 1'b0; end if (value !== 'd0123456789) begin $display("FAILED: expected decimal value 'd0123456789, got %d", value); passed = 1'b0; end // Look for a negative decimal value. if (! $value$plusargs("neg=%d", value)) begin $display("FAILED: Unable to get negative decimal value."); passed = 1'b0; end if (value !== -100) begin $display("FAILED: expected decimal value 72'hff...fc0, got %h", value); passed = 1'b0; end // Look for a bad decimal value. if (! $value$plusargs("bad_num=%d", value)) begin $display("FAILED: Unable to get bad decimal value."); passed = 1'b0; end if (value !== 'bx) begin $display("FAILED: expected bad decimal value 'bx, got %d", value); passed = 1'b0; end // Look for a decimal "x" value. if (! $value$plusargs("dec_x=%d", value)) begin $display("FAILED: Unable to get decimal \"x\" value."); passed = 1'b0; end if (value !== 'dx) begin $display("FAILED: expected decimal value 'dx, got %d", value); passed = 1'b0; end // Look for a decimal "z" value. if (! $value$plusargs("dec_z=%d", value)) begin $display("FAILED: Unable to get decimal \"z\" value."); passed = 1'b0; end if (value !== 'dz) begin $display("FAILED: expected decimal value 'dz, got %d", value); passed = 1'b0; end // Look for a real value. if (! $value$plusargs("real=%f", rval)) begin $display("FAILED: Unable to get real value."); passed = 1'b0; end if (rval != 12.3456789) begin $display("FAILED: expected real value 12.3456789, got %f", rval); passed = 1'b0; end // Look for a negative real value. if (! $value$plusargs("neg_real=%f", rval)) begin $display("FAILED: Unable to get a negative real value."); passed = 1'b0; end if (rval != -23456.0) begin $display("FAILED: expected negative real value -23456.0, got %f", rval); passed = 1'b0; end // Look for an infinite real value. if (! $value$plusargs("real_inf=%f", rval)) begin $display("FAILED: Unable to get infinite real value."); passed = 1'b0; end if (rval != 1.0/0.0) begin $display("FAILED: expected infinite real value Inf, got %f", rval); passed = 1'b0; end // Look for a bad real value. if (! $value$plusargs("bad_num=%f", rval)) begin $display("FAILED: Unable to get bad real value."); passed = 1'b0; end if (rval != 0.0) begin $display("FAILED: expected bad real value 0.0, got %f", rval); passed = 1'b0; end // Look for a warning real value. if (! $value$plusargs("warn_real=%f", rval)) begin $display("FAILED: Unable to get warning real value."); passed = 1'b0; end if (rval != 9.825) begin $display("FAILED: expected warning real value 9.825, got %f", rval); passed = 1'b0; end // Put a decimal value into a real based value. if (! $value$plusargs("dec=%d", rval)) begin $display("FAILED: Unable to get decimal (real) value."); passed = 1'b0; end if (rval != 123456789.0) begin $display("FAILED: expected decimal as real value 12...89.0, got %f", rval); passed = 1'b0; end // Put a negative decimal into a real based value. if (! $value$plusargs("neg=%d", rval)) begin $display("FAILED: Unable to get negative decimal (real) value."); passed = 1'b0; end if (rval != -100.0) begin $display("FAILED: expected decimal as real value -100, got %f", rval); passed = 1'b0; end // Put a real value into a bit based value. if (! $value$plusargs("real=%f", value)) begin $display("FAILED: Unable to get real (bit) value."); passed = 1'b0; end if (value !== 12) begin $display("FAILED: expected real as bit value 12, got %d", value); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2202846a.v000066400000000000000000000011631435245347300202640ustar00rootroot00000000000000module test (d, en, g, s, a); input [31:2] d; input en; output g, s, a; reg g, s, a; reg [31:21] r14; reg [2:0] r18; always @(d or r18 or r14 or en) begin casex ({d[31:12],r18[2:0],en}) {20'b1111_1111_0011_????_????, 3'b???, 1'b1} : s = 1'b1; {20'b1111_1111_0010_????_????, 3'b???, 1'b1} : g = 1'b1; {{r14[31:21], 9'b0_01??_????}, 3'b???, 1'b?} : a = 1'b1; {{r14[31:21], 9'b1_????_????}, 3'b???, 1'b?} : a = 1'b1; endcase end // Other tests check functionality so if this compiles it is fine. initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr2202846b.v000066400000000000000000000027171435245347300202730ustar00rootroot00000000000000module top; reg pass; reg [5:0] cond; reg [2:1] expr; integer result; always @(cond or expr) begin casex (cond) 6'b01_??10 : result = 1; {2'b10, 4'b??10} : result = 2; {expr, 4'b??01} : result = 3; {expr[2], 5'b0??11} : result = 4; {expr[2:1], 4'b??11} : result = 5; {expr, 4'b??00} : result = 6; default : result = 0; endcase end initial begin pass = 1'b1; cond = 6'b01_xx10; #1; if (result != 1) begin $display("Failed case expr 1 test, got expr %0d", result); pass = 1'b0; end cond = 6'b10_zz10; #1; if (result != 2) begin $display("Failed case expr 2 test, got expr %0d", result); pass = 1'b0; end expr = 2'b1?; cond = 6'b1x_xx01; #1; if (result != 3) begin $display("Failed case expr 3 test, got expr %0d", result); pass = 1'b0; end expr = 2'b0z; cond = 6'b00_xx11; #1; if (result != 4) begin $display("Failed case expr 4 test, got expr %0d", result); pass = 1'b0; end expr = 2'b?1; cond = 6'bx1_xx11; #1; if (result != 5) begin $display("Failed case expr 5 test, got expr %0d", result); pass = 1'b0; end expr = 2'b11; cond = 6'b11_xx00; #1; if (result != 6) begin $display("Failed case expr 6 test, got expr %0d", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2202846c.v000066400000000000000000000025651435245347300202750ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [5:0] cond; reg [2:1] expr; integer result; always @(cond or expr) begin casex (cond) 6'b01_??10 : result = 1; {2'b10, 4'b??10} : result = 2; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST {expr[1:0], 4'b??01} : result = 3; expr[11:6] : result = 4; `else {expr[1], 1'bx, 4'b??01} : result = 3; 6'bxxxxxx : result = 4; `endif default : result = 0; endcase end initial begin pass = 1'b1; expr = 2'b10; cond = 6'b01_xx10; #1 if (result != 1) begin $display("Failed case expr 1 test, got expr %0d", result); pass = 1'b0; end cond = 6'bxx_xxxx; #1 if (result != 1) begin $display("Failed case expr 1a test, got expr %0d", result); pass = 1'b0; end cond = 6'b10_zz10; #1 if (result != 2) begin $display("Failed case expr 2 test, got expr %0d", result); pass = 1'b0; end cond = 6'b0x_zz01; #1 if (result != 3) begin $display("Failed case expr 3 test, got expr %0d", result); pass = 1'b0; end cond = 6'b11_1111; #1 if (result != 4) begin $display("Failed case expr 1a test, got expr %0d", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2208681.v000066400000000000000000000003101435245347300201170ustar00rootroot00000000000000module top; reg [31:0] in; wire [31:0] out = (~in) + 1'b1 + 31'h1234; initial begin in = 'h0; #1 if (out !== 'h1234) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2215342.v000066400000000000000000000001421435245347300201120ustar00rootroot00000000000000`include "pr2215342_inc.v" // Include a file module top; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr2215342_inc.v000066400000000000000000000001151435245347300207430ustar00rootroot00000000000000/* Start with a comment to verify that the include comment * is correct. */ iverilog-12_0/ivtest/ivltests/pr2219441.v000066400000000000000000000017241435245347300201250ustar00rootroot00000000000000module top; reg passed; reg [1:0] sel; reg [1:0] A; wire [1:0] Z; parent parent(.sel(sel), .A(A), .Z(Z)); initial begin passed = 1'b1; sel = 2'b11; A = 2'b00; #1 if (Z !== 2'b00) begin $display("FAILED: selected, expected 2'b00, got %b", Z); passed = 1'b0; end A = 2'b10; #1 if (Z !== 2'b10) begin $display("FAILED: selected, expected 2'b10, got %b", Z); passed = 1'b0; end A = 2'b01; #1 if (Z !== 2'b01) begin $display("FAILED: selected, expected 2'b01, got %b", Z); passed = 1'b0; end sel = 2'b00; #1 if (Z !== 2'bzz) begin $display("FAILED: deselected, expected 2'bzz, got %b", Z); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule module parent(input[1:0] sel, input [1:0] A, inout [1:0] Z); child child[1:0](.sel(sel), .A(A), .Z(Z)); endmodule module child(input sel, input A, inout Z); assign Z = (sel) ? A : 1'bz; endmodule iverilog-12_0/ivtest/ivltests/pr2219441b.v000066400000000000000000000024621435245347300202670ustar00rootroot00000000000000module top; reg passed; reg [1:0] sel; reg [1:0] A; wire Z; parent parent(.sel(sel), .A(A), .Z(Z)); initial begin // $monitor("1: %b, 0: %b", parent.child[1].Z, parent.child[0].Z); passed = 1'b1; sel = 2'b11; A = 2'b00; #1 if (Z !== 1'b0) begin $display("FAILED: selected both, expected 1'b0, got %b", Z); passed = 1'b0; end A = 2'b11; #1 if (Z !== 1'b1) begin $display("FAILED: selected both, expected 1'b1, got %b", Z); passed = 1'b0; end A = 2'b10; #1 if (Z !== 1'bx) begin $display("FAILED: selected both, expected 1'bx, got %b", Z); passed = 1'b0; end sel = 2'b00; #1 if (Z !== 1'bz) begin $display("FAILED: deselected, expected 1'bz, got %b", Z); passed = 1'b0; end sel = 2'b10; #1 if (Z !== 1'b1) begin $display("FAILED: selected (1), expected 1'b1, got %b", Z); passed = 1'b0; end sel = 2'b01; #1 if (Z !== 1'b0) begin $display("FAILED: selected (0), expected 1'b0, got %b", Z); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule module parent(input[1:0] sel, input [1:0] A, inout Z); child child[1:0](.sel(sel), .A(A), .Z(Z)); endmodule module child(input sel, input A, inout Z); assign Z = (sel) ? A : 1'bz; endmodule iverilog-12_0/ivtest/ivltests/pr2224845.v000066400000000000000000000007761435245347300201370ustar00rootroot00000000000000`define VUG_PCREL(u, uch) ({ {(uch - 12 - 1 > 0 ? uch - 12 - 1 : 1){u[11]}}, \ u[10:0], 2'b00 }) module t(); parameter uch = 16; parameter u_hossz = 32; parameter u_prefix = 3; reg [u_hossz - u_prefix - 1:0] v_utas; reg [uch - 1:0] v_cim; wire [uch - 1:0] v_ugras_ide; assign v_ugras_ide = v_cim + `VUG_PCREL(v_utas, uch); initial begin v_utas = 'h0fff; v_cim = 'h7; #1; if(v_ugras_ide !== 'h3) $display("FAILED"); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr2224949.v000066400000000000000000000004111435245347300201260ustar00rootroot00000000000000module t(); wire [63:0] a; wire [63:0] b; assign a = 3; am dut(a, b); initial begin #1; if(b !== 2) $display("FAILED"); else $display("PASSED"); $finish; end endmodule module am( a, b ); input [15:0] a; output [15:0] b; assign b = a ^ 1; endmodule iverilog-12_0/ivtest/ivltests/pr2233180.v000066400000000000000000000013311435245347300201130ustar00rootroot00000000000000module bug04_integerDiv; reg passed; reg signed[31:0] reg0; reg signed[31:0] reg1; reg signed[31:0] rquot; wire signed[31:0] dividend=reg0; wire signed[31:0] divisor=reg1; wire signed[31:0] quotient; assign quotient= dividend/divisor; initial begin passed = 1'b1; reg0=32'h76c3625e; reg1=32'hffffffff; //BUG here: quotient==32'hxxxxxxxx, should be 32'h893c9da2 #1 if (quotient !== 32'h893c9da2) begin $display("Failed: CA division, expected 32'h893c9da2, got %h", quotient); passed = 1'b0; end rquot = reg0/reg1; if (rquot !== 32'h893c9da2) begin $display("Failed: division, expected 32'h893c9da2, got %h", rquot); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2233180b.v000066400000000000000000000050761435245347300202670ustar00rootroot00000000000000module top; reg passed; reg signed[31:0] m_one, m_two, zero, one, two; // Both argument positive. reg signed[31:0] rem; wire signed[31:0] wrem = two / one; // First argument negative. reg signed[31:0] rem1n; wire signed[31:0] wrem1n = m_two / one; // Second argument negative. reg signed[31:0] rem2n; wire signed[31:0] wrem2n = two / m_one; // Both arguments negative. reg signed[31:0] rembn; wire signed[31:0] wrembn = m_two / m_one; // Divide by zero. reg signed[31:0] remd0; wire signed[31:0] wremd0 = one / zero; initial begin passed = 1'b1; m_one = 32'hffffffff; m_two = 32'hfffffffe; zero = 32'h00000000; one = 32'h00000001; two = 32'h00000002; #1; // Both positive. if (wrem !== 32'h00000002) begin $display("Failed: CA divide, expected 32'h00...02, got %h", wrem); passed = 1'b0; end rem = two / one; if (rem !== 32'h00000002) begin $display("Failed: divide, expected 32'h00...02, got %h", rem); passed = 1'b0; end // First negative. if (wrem1n !== 32'hfffffffe) begin $display("Failed: CA divide (1n), expected 32'hff...fe, got %h", wrem1n); passed = 1'b0; end rem1n = m_two / one; if (rem1n !== 32'hfffffffe) begin $display("Failed: divide (1n), expected 32'hff...fe, got %h", rem1n); passed = 1'b0; end // Second negative. if (wrem2n !== 32'hfffffffe) begin $display("Failed: CA divide (2n), expected 32'hff...fe, got %h", wrem2n); passed = 1'b0; end rem2n = two / m_one; if (rem2n !== 32'hfffffffe) begin $display("Failed: divide (2n), expected 32'hff...fe, got %h", rem2n); passed = 1'b0; end // Both negative. if (wrembn !== 32'h00000002) begin $display("Failed: CA divide (bn), expected 32'h00...02, got %h", wrembn); passed = 1'b0; end rembn = m_two / m_one; if (rembn !== 32'h00000002) begin $display("Failed: divide (bn), expected 32'h00...02, got %h", rembn); passed = 1'b0; end // Divide by zero. if (wremd0 !== 32'hxxxxxxxx) begin $display("Failed: CA divide (d0), expected 32'hxx...xx, got %h", wremd0); passed = 1'b0; end remd0 = one / zero; if (remd0 !== 32'hxxxxxxxx) begin $display("Failed: divide (d0), expected 32'hxx...xx, got %h", remd0); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2233180c.v000066400000000000000000000054561435245347300202720ustar00rootroot00000000000000module top; reg passed; reg signed[95:0] m_one, m_two, zero, one, two; // Both argument positive. reg signed[95:0] rem; wire signed[95:0] wrem = two / one; // First argument negative. reg signed[95:0] rem1n; wire signed[95:0] wrem1n = m_two / one; // Second argument negative. reg signed[95:0] rem2n; wire signed[95:0] wrem2n = two / m_one; // Both arguments negative. reg signed[95:0] rembn; wire signed[95:0] wrembn = m_two / m_one; // Divide by zero. reg signed[95:0] remd0; wire signed[95:0] wremd0 = one / zero; initial begin passed = 1'b1; m_one = 96'hffffffffffffffffffffffff; m_two = 96'hfffffffffffffffffffffffe; zero = 96'h000000000000000000000000; one = 96'h000000000000000000000001; two = 96'h000000000000000000000002; #1; // Both positive. if (wrem !== 96'h000000000000000000000002) begin $display("Failed: CA divide, expected 96'h00...02, got %h", wrem); passed = 1'b0; end rem = two / one; if (rem !== 96'h000000000000000000000002) begin $display("Failed: divide, expected 96'h00...02, got %h", rem); passed = 1'b0; end // First negative. if (wrem1n !== 96'hfffffffffffffffffffffffe) begin $display("Failed: CA divide (1n), expected 96'hff...fe, got %h", wrem1n); passed = 1'b0; end rem1n = m_two / one; if (rem1n !== 96'hfffffffffffffffffffffffe) begin $display("Failed: divide (1n), expected 96'hff...fe, got %h", rem1n); passed = 1'b0; end // Second negative. if (wrem2n !== 96'hfffffffffffffffffffffffe) begin $display("Failed: CA divide (2n), expected 96'hff...fe, got %h", wrem2n); passed = 1'b0; end rem2n = two / m_one; if (rem2n !== 96'hfffffffffffffffffffffffe) begin $display("Failed: divide (2n), expected 96'hff...fe, got %h", rem2n); passed = 1'b0; end // Both negative. if (wrembn !== 96'h000000000000000000000002) begin $display("Failed: CA divide (bn), expected 96'h00...02, got %h", wrembn); passed = 1'b0; end rembn = m_two / m_one; if (rembn !== 96'h000000000000000000000002) begin $display("Failed: divide (bn), expected 96'h00...02, got %h", rembn); passed = 1'b0; end // Divide by zero. if (wremd0 !== 96'hxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("Failed: CA divide (d0), expected 96'hxx...xx, got %h", wremd0); passed = 1'b0; end remd0 = one / zero; if (remd0 !== 96'hxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("Failed: divide (d0), expected 96'hxx...xx, got %h", remd0); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2233192.v000066400000000000000000000013501435245347300201170ustar00rootroot00000000000000module bug05_integerRem; reg passed; reg signed[31:0] reg0; reg signed[31:0] reg1; reg signed[31:0] rrem; wire signed[31:0] dividend=reg0; wire signed[31:0] divisor=reg1; wire signed[31:0] remainder; assign remainder= dividend%divisor; initial begin passed = 1'b1; reg0=32'hffffffff; reg1=32'h0d1f0796; //BUG here: remainder==32'h06b26fdd, should be 32'hffffffff #1 if (remainder !== 32'hffffffff) begin $display("Failed: CA remainder, expected 32'hffffffff, got %h", remainder); passed = 1'b0; end rrem = reg0 % reg1; #1 if (rrem !== 32'hffffffff) begin $display("Failed: remainder, expected 32'hffffffff, got %h", rrem); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2233192b.v000066400000000000000000000051341435245347300202650ustar00rootroot00000000000000module top; reg passed; reg signed[31:0] m_one, m_two, zero, one, two; // Both argument positive. reg signed[31:0] rem; wire signed[31:0] wrem = one % two; // First argument negative. reg signed[31:0] rem1n; wire signed[31:0] wrem1n = m_one % two; // Second argument negative. reg signed[31:0] rem2n; wire signed[31:0] wrem2n = one % m_two; // Both arguments negative. reg signed[31:0] rembn; wire signed[31:0] wrembn = m_one % m_two; // Divide by zero. reg signed[31:0] remd0; wire signed[31:0] wremd0 = one % zero; initial begin passed = 1'b1; m_one = 32'hffffffff; m_two = 32'hfffffffe; zero = 32'h00000000; one = 32'h00000001; two = 32'h00000002; #1; // Both positive. if (wrem !== 32'h00000001) begin $display("Failed: CA remainder, expected 32'h00...01, got %h", wrem); passed = 1'b0; end rem = one % two; if (rem !== 32'h00000001) begin $display("Failed: remainder, expected 32'h00...01, got %h", rem); passed = 1'b0; end // First negative. if (wrem1n !== 32'hffffffff) begin $display("Failed: CA remainder (1n), expected 32'hff...ff, got %h", wrem1n); passed = 1'b0; end rem1n = m_one % two; if (rem1n !== 32'hffffffff) begin $display("Failed: remainder (1n), expected 32'hff...ff, got %h", rem1n); passed = 1'b0; end // Second negative. if (wrem2n !== 32'h00000001) begin $display("Failed: CA remainder (2n), expected 32'h00...01, got %h", wrem2n); passed = 1'b0; end rem2n = one % m_two; if (rem2n !== 32'h00000001) begin $display("Failed: remainder (2n), expected 32'h00...01, got %h", rem2n); passed = 1'b0; end // Both negative. if (wrembn !== 32'hffffffff) begin $display("Failed: CA remainder (bn), expected 32'hff...ff, got %h", wrembn); passed = 1'b0; end rembn = m_one % m_two; if (rembn !== 32'hffffffff) begin $display("Failed: remainder (bn), expected 32'hff...ff, got %h", rembn); passed = 1'b0; end // Divide by zero. if (wremd0 !== 32'hxxxxxxxx) begin $display("Failed: CA remainder (d0), expected 32'hxx...xx, got %h", wremd0); passed = 1'b0; end remd0 = one % zero; if (remd0 !== 32'hxxxxxxxx) begin $display("Failed: remainder (d0), expected 32'hxx...xx, got %h", remd0); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2233192c.v000066400000000000000000000055141435245347300202700ustar00rootroot00000000000000module top; reg passed; reg signed[95:0] m_one, m_two, zero, one, two; // Both argument positive. reg signed[95:0] rem; wire signed[95:0] wrem = one % two; // First argument negative. reg signed[95:0] rem1n; wire signed[95:0] wrem1n = m_one % two; // Second argument negative. reg signed[95:0] rem2n; wire signed[95:0] wrem2n = one % m_two; // Both arguments negative. reg signed[95:0] rembn; wire signed[95:0] wrembn = m_one % m_two; // Divide by zero. reg signed[95:0] remd0; wire signed[95:0] wremd0 = one % zero; initial begin passed = 1'b1; m_one = 96'hffffffffffffffffffffffff; m_two = 96'hfffffffffffffffffffffffe; zero = 96'h000000000000000000000000; one = 96'h000000000000000000000001; two = 96'h000000000000000000000002; #1; // Both positive. if (wrem !== 96'h000000000000000000000001) begin $display("Failed: CA remainder, expected 96'h00...01, got %h", wrem); passed = 1'b0; end rem = one % two; if (rem !== 96'h000000000000000000000001) begin $display("Failed: remainder, expected 96'h00...01, got %h", rem); passed = 1'b0; end // First negative. if (wrem1n !== 96'hffffffffffffffffffffffff) begin $display("Failed: CA remainder (1n), expected 96'hff...ff, got %h", wrem1n); passed = 1'b0; end rem1n = m_one % two; if (rem1n !== 96'hffffffffffffffffffffffff) begin $display("Failed: remainder (1n), expected 96'hff...ff, got %h", rem1n); passed = 1'b0; end // Second negative. if (wrem2n !== 96'h000000000000000000000001) begin $display("Failed: CA remainder (2n), expected 96'h00...01, got %h", wrem2n); passed = 1'b0; end rem2n = one % m_two; if (rem2n !== 96'h000000000000000000000001) begin $display("Failed: remainder (2n), expected 96'h00...01, got %h", rem2n); passed = 1'b0; end // Both negative. if (wrembn !== 96'hffffffffffffffffffffffff) begin $display("Failed: CA remainder (bn), expected 96'hff...ff, got %h", wrembn); passed = 1'b0; end rembn = m_one % m_two; if (rembn !== 96'hffffffffffffffffffffffff) begin $display("Failed: remainder (bn), expected 96'hff...ff, got %h", rembn); passed = 1'b0; end // Divide by zero. if (wremd0 !== 96'hxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("Failed: CA remainder (d0), expected 96'hxx...xx, got %h", wremd0); passed = 1'b0; end remd0 = one % zero; if (remd0 !== 96'hxxxxxxxxxxxxxxxxxxxxxxxx) begin $display("Failed: remainder (d0), expected 96'hxx...xx, got %h", remd0); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr224.v000066400000000000000000000013211435245347300175770ustar00rootroot00000000000000// Extracted from PR#224 module test; reg clk; reg [3:0] ack; task first; input [1:0] p; begin @(posedge clk); $display("got posedge clk"); `ifdef LINE_A //A: line below compiles under XL/NC - iverilog complains @(posedge ack[p]); $display("got posedge ack[p]"); `else //B: line below core dumps under vvp - OK under vvm @(posedge ack); $display("got posedge ack"); `endif @(posedge clk); $display("got posedge clk"); $display("PASSED"); $finish; end endtask initial #5 first(1); initial begin ack <= 0; clk <= 0; #10 clk <= 1; #10 ack <= 3; clk <= 0; #10 clk <= 1; #10 $display("FAILED"); $finish; end endmodule // test iverilog-12_0/ivtest/ivltests/pr2248925.v000066400000000000000000000001471435245347300201340ustar00rootroot00000000000000module bug(); time t1; initial begin t1 = 1000; $display("%0d", t1 + 1000 - 500); end endmodule iverilog-12_0/ivtest/ivltests/pr224a.v000066400000000000000000000000531435245347300177410ustar00rootroot00000000000000`define LINE_A `include "ivltests/pr224.v" iverilog-12_0/ivtest/ivltests/pr2251119.v000066400000000000000000000003741435245347300201230ustar00rootroot00000000000000module bug(); real t1; integer t2; initial begin t1 = 2000; t2 = 1000; if (0.55*t1 < t2) $display("FAILED: %0d < %0d true branch taken", 0.55*t1, t2); else $display("PASSED: %0d < %0d false branch taken", 0.55*t1, t2); end endmodule iverilog-12_0/ivtest/ivltests/pr2257003.v000066400000000000000000000004011435245347300201100ustar00rootroot00000000000000module inner (); initial a.dump; endmodule module outer (); inner i (); generate begin : a task dump; begin $display ("PASSED"); end endtask end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2257003b.v000066400000000000000000000003031435245347300202530ustar00rootroot00000000000000module test2 (); generate begin : a reg b; end endgenerate initial begin a.b = 1'b1; if (a.b) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2270035.v000066400000000000000000000003371435245347300201200ustar00rootroot00000000000000module test (); reg [30:0] a, b; initial begin b = 1; a = (0 << b); // $display ("a: %d", a); if (a !== 31'b0) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2272468.v000066400000000000000000000004311435245347300201270ustar00rootroot00000000000000module sub(); task task1; input [1023:0] a; input [1023:0] b; begin if (a + b > 1026'd2) $display(1); end endtask initial task1(1, 2); endmodule module top(); generate genvar i; for (i = 0; i < 256; i = i + 1) begin:block sub sub(); end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2276163.v000066400000000000000000000016601435245347300201300ustar00rootroot00000000000000// Adapted from test case submitted by Geoff Blackman module pr2276163(); function automatic integer f1; input integer in; f1 = in + 1; endfunction function integer f2; input integer in; f2 = in * 2; endfunction integer ret; initial begin ret = f1 ( f1 (1) ); if (ret !== 3) begin $display("FAILED: expected 3, got %0d", ret); $finish; end ret = f1 ( f2 (2) ); if (ret !== 5) begin $display("FAILED: expected 5, got %0d", ret); $finish; end ret = f2 ( f1 (3) ); if (ret !== 8) begin $display("FAILED: expected 8, got %0d", ret); $finish; end ret = f2 ( f2 (4) ); if (ret !== 16) begin $display("FAILED: expected 16, got %0d", ret); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2281479.v000066400000000000000000000015241435245347300201350ustar00rootroot00000000000000module top; reg passed; reg[1:0] in; integer where; always @(in) begin casez(in) 2'b10: where = 1; 2'bx?: where = 2; // MSB is X 2'b??: where = 3; // The same as default. endcase end initial begin passed = 1'b1; in = 2'b10; #1 if (where != 1) begin $display("FAILED 2'b10 case, found case %d", where); passed = 1'b0; end in = 2'bx0; #1 if (where != 2) begin $display("FAILED 2'bx? case (1), found case %d", where); passed = 1'b0; end in = 2'bx1; #1 if (where != 2) begin $display("FAILED 2'bx? case (2), found case %d", where); passed = 1'b0; end in = 2'b00; #1 if (where != 3) begin $display("FAILED 2'b?? case, found case %d", where); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2305307.v000066400000000000000000000032211435245347300201140ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg passed, in, expect, out; integer lp; initial begin passed = 1'b1; for (lp=0; lp < 3 ; lp = lp + 1) begin case (lp) 0: {in,expect} = 2'b00; 1: {in,expect} = 2'b11; 2: {in,expect} = 2'bzx; 3: {in,expect} = 2'bxx; endcase // Check the normal reductions. // These can fail be need a %buf opcode. out = ∈ if (out !== expect) begin $display("FAILED reduction & with input %b, expected %b, got %b", in, expect, out); passed = 1'b0; end out = |in; if (out !== expect) begin $display("FAILED reduction | with input %b, expected %b, got %b", in, expect, out); passed = 1'b0; end out = ^in; if (out !== expect) begin $display("FAILED reduction ^ with input %b, expected %b, got %b", in, expect, out); passed = 1'b0; end // Check the inverted reductions. out = ~∈ if (out !== ~expect) begin $display("FAILED reduction ~& with input %b, expected %b, got %b", in, ~expect, out); passed = 1'b0; end out = ~|in; if (out !== ~expect) begin $display("FAILED reduction ~| with input %b, expected %b, got %b", in, ~expect, out); passed = 1'b0; end out = ~^in; if (out !== ~expect) begin $display("FAILED reduction ~^ with input %b, expected %b, got %b", in, ~expect, out); passed = 1'b0; end end if (passed) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2305307b.v000066400000000000000000000032341435245347300202620ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg passed, in, expect; integer lp; wire rand = ∈ wire ror = |in; wire rxor = ^in; wire rnand = ~∈ wire rnor = ~|in; wire rxnor = ~^in; initial begin passed = 1'b1; for (lp=0; lp < 3 ; lp = lp + 1) begin case (lp) 0: {in,expect} = 2'b00; 1: {in,expect} = 2'b11; 2: {in,expect} = 2'bzx; 3: {in,expect} = 2'bxx; endcase #1; // Check the normal reductions. if (rand !== expect) begin $display("FAILED CA reduction & with input %b, expected %b, got %b", in, expect, rand); passed = 1'b0; end if (ror !== expect) begin $display("FAILED CA reduction | with input %b, expected %b, got %b", in, expect, ror); passed = 1'b0; end if (rxor !== expect) begin $display("FAILED CA reduction ^ with input %b, expected %b, got %b", in, expect, rxor); passed = 1'b0; end // Check the inverted reductions. if (rnand !== ~expect) begin $display("FAILED CA reduction ~& with input %b, expected %b, got %b", in, ~expect, rnand); passed = 1'b0; end if (rnor !== ~expect) begin $display("FAILED CA reduction ~| with input %b, expected %b, got %b", in, ~expect, rnor); passed = 1'b0; end if (rxnor !== ~expect) begin $display("FAILED CA reduction ~^ with input %b, expected %b, got %b", in, ~expect, rxnor); passed = 1'b0; end end if (passed) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2305307c.v000066400000000000000000000103761435245347300202700ustar00rootroot00000000000000module top; reg passed; parameter zero = 1'b0; parameter one = 1'b1; parameter highz = 1'bz; parameter undef = 1'bx; initial begin passed = 1'b1; if (&zero !== 1'b0) begin $display("FAILED const. reduction & with input 1'b0, expected 1'b0, ", " got %b", &zero); passed = 1'b0; end if (&one !== 1'b1) begin $display("FAILED const. reduction & with input 1'b1, expected 1'b1, ", " got %b", &one); passed = 1'b0; end if (&highz !== 1'bx) begin $display("FAILED const. reduction & with input 1'bz, expected 1'bx, ", " got %b", &highz); passed = 1'b0; end if (&undef !== 1'bx) begin $display("FAILED const. reduction & with input 1'bx, expected 1'bx, ", " got %b", &undef); passed = 1'b0; end if (|zero !== 1'b0) begin $display("FAILED const. reduction | with input 1'b0, expected 1'b0, ", " got %b", |zero); passed = 1'b0; end if (|one !== 1'b1) begin $display("FAILED const. reduction | with input 1'b1, expected 1'b1, ", " got %b", |one); passed = 1'b0; end if (|highz !== 1'bx) begin $display("FAILED const. reduction | with input 1'bz, expected 1'bx, ", " got %b", |highz); passed = 1'b0; end if (|undef !== 1'bx) begin $display("FAILED const. reduction | with input 1'bx, expected 1'bx, ", " got %b", |undef); passed = 1'b0; end if (^zero !== 1'b0) begin $display("FAILED const. reduction ^ with input 1'b0, expected 1'b0, ", " got %b", ^zero); passed = 1'b0; end if (^one !== 1'b1) begin $display("FAILED const. reduction ^ with input 1'b1, expected 1'b1, ", " got %b", ^one); passed = 1'b0; end if (^highz !== 1'bx) begin $display("FAILED const. reduction ^ with input 1'bz, expected 1'bx, ", " got %b", ^highz); passed = 1'b0; end if (^undef !== 1'bx) begin $display("FAILED const. reduction ^ with input 1'bx, expected 1'bx, ", " got %b", ^undef); passed = 1'b0; end if (~&zero !== 1'b1) begin $display("FAILED const. reduction ~& with input 1'b0, expected 1'b1, ", " got %b", ~&zero); passed = 1'b0; end if (~&one !== 1'b0) begin $display("FAILED const. reduction ~& with input 1'b1, expected 1'b0, ", " got %b", ~&one); passed = 1'b0; end if (~&highz !== 1'bx) begin $display("FAILED const. reduction ~& with input 1'bz, expected 1'bx, ", " got %b", ~&highz); passed = 1'b0; end if (~&undef !== 1'bx) begin $display("FAILED const. reduction ~& with input 1'bx, expected 1'bx, ", " got %b", ~&undef); passed = 1'b0; end if (~|zero !== 1'b1) begin $display("FAILED const. reduction ~| with input 1'b0, expected 1'b1, ", " got %b", ~|zero); passed = 1'b0; end if (~|one !== 1'b0) begin $display("FAILED const. reduction ~| with input 1'b1, expected 1'b0, ", " got %b", ~|one); passed = 1'b0; end if (~|highz !== 1'bx) begin $display("FAILED const. reduction ~| with input 1'bz, expected 1'bx, ", " got %b", ~|highz); passed = 1'b0; end if (~|undef !== 1'bx) begin $display("FAILED const. reduction ~| with input 1'bx, expected 1'bx, ", " got %b", ~|undef); passed = 1'b0; end if (~^zero !== 1'b1) begin $display("FAILED const. reduction ~^ with input 1'b0, expected 1'b1, ", " got %b", ~^zero); passed = 1'b0; end if (~^one !== 1'b0) begin $display("FAILED const. reduction ~^ with input 1'b1, expected 1'b0, ", " got %b", ~^one); passed = 1'b0; end if (~^highz !== 1'bx) begin $display("FAILED const. reduction ~^ with input 1'bz, expected 1'bx, ", " got %b", ~^highz); passed = 1'b0; end if (~^undef !== 1'bx) begin $display("FAILED const. reduction ~^ with input 1'bx, expected 1'bx, ", " got %b", ~^undef); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2306259.v000066400000000000000000000002731435245347300201270ustar00rootroot00000000000000module test (); generate if (1) begin initial begin : a integer i; i=0; $display("PASSED"); end end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2350934.v000066400000000000000000000017041435245347300201260ustar00rootroot00000000000000module test (); parameter param = 3; reg [2:0] dummy; initial dummy = block.f(0); generate if (param==1) begin : block function [2:0] f; input i; begin $display ("if param==1"); f = param; end endfunction end else if (param==2) begin : block function [2:0] f; input i; begin $display ("else if param==2"); f = param; end endfunction end endgenerate endmodule module top (); test #(1) a(); test #(2) b(); initial begin #1 if (a.dummy !== 1) begin $display("FAILED -- a.dummy = %d", a.dummy); $finish; end if (b.dummy !== 2) begin $display("FAILED -- b.dummy = %d", b.dummy); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr2350934b.v000066400000000000000000000024361435245347300202730ustar00rootroot00000000000000module test (); parameter param = 3; reg [2:0] dummy; initial dummy = block.f(0); generate case (param) 1, 2: if (param==1) begin : block function [2:0] f; input i; begin $display ("if param==1"); f = param; end endfunction end else begin : block function [2:0] f; input i; begin $display ("else if param==2"); f = param; end endfunction end 4: begin : block function [2:0] f; input i; begin $display ("if param==4"); f = param; end endfunction // f end endcase endgenerate endmodule module top (); test #(1) a(); test #(2) b(); test #(4) c(); initial begin #1 if (a.dummy !== 1) begin $display("FAILED -- a.dummy = %d", a.dummy); $finish; end if (b.dummy !== 2) begin $display("FAILED -- b.dummy = %d", b.dummy); $finish; end if (c.dummy !== 4) begin $display("FAILED -- c.dummy = %d", c.dummy); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr2350988.v000066400000000000000000000012651435245347300201410ustar00rootroot00000000000000module test (); parameter p = 0; reg dummy; initial dummy = block.f(0); generate case(1) p==0: begin : block function f; input i; begin $display("p == 0: %0s", p==0?"OK":"FAILED"); if (! (p==0)) $finish; end endfunction end default: begin : block function f; input i; begin $display("default: %0s", p!=0?"OK":"FAILED"); if (p==0) $finish; end endfunction end endcase endgenerate endmodule module top (); test #(0) a(); test #(1) b(); initial #1 $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr2352834.v000066400000000000000000000011041435245347300201210ustar00rootroot00000000000000module top; reg pass; reg [31:0] in2; integer in1; reg signed [128:0] res; initial begin pass = 1'b1; in1 = -2; in2 = 63; res = in1 ** in2; if (res !== -128'sd9223372036854775808) begin $display("Failed: -2 ** 65, expected -9223372036854775808, got %0d", res); pass = 1'b0; end in1 = -2; in2 = 65; res = in1 ** in2; if (res !== -128'sd36893488147419103232) begin $display("Failed: -2 ** 65, expected -36893488147419103232, got %0d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2355304.v000066400000000000000000000007051435245347300201220ustar00rootroot00000000000000module test (); parameter t=0; reg t_not, t_zero; generate if (!t) begin initial t_not = 1; end endgenerate generate if (t==0) begin initial t_zero = 1; end endgenerate initial begin #1 if (t_not !== 1) begin $display("FAILED -- t_not=%b", t_not); $finish; end if (t_zero !== 1) begin $display("FAILED -- t_zero=%b", t_zero); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2355304b.v000066400000000000000000000002661435245347300202660ustar00rootroot00000000000000module test2 (); reg [1:0] d; always @(posedge |d) begin $display ("PASSED"); end initial begin d=0; # 1; d=6'b01; end endmodule iverilog-12_0/ivtest/ivltests/pr2358264.v000066400000000000000000000011601435245347300201260ustar00rootroot00000000000000module test(); reg [13:0] a; reg b; reg c; always @(a or b) begin case ({1'b0,~b,a[3:0]}) 6'b00_0000 : begin c = 1'b1; end default : begin c = 1'b0; end endcase end initial begin #1 /* Wait for the always block above to get settled. */; a = 0; b = 0; #1 if (c !== 0) begin $display("FAILED - a=%b, b=%b, c=%b", a, b, c); $finish; end b = 1; #1 if (c !== 1) begin $display("FAILED - a=%b, b=%b, c=%b", a, b, c); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr2358848.v000066400000000000000000000046411435245347300201450ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module t(); reg passed; parameter ch = 14; parameter csek2 = 1; parameter offset = 10/0; localparam csek = 1 << csek2; wire [ch + csek2 - 1:0] cim_k; wire [csek - 1:0] up1, up2, up3, up4, up5, dwn1, dwn2, dwn3; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST // This checks the always above code. assign up1 = cim_k[(csek2 + ch)+:csek2]; // This checks the always above code. assign up2 = cim_k[(csek2 + ch + 2)+:csek2]; // This checks the always below code. assign up3 = cim_k[(csek2 + ch - 17)+:csek2]; // This checks that -4 goes into three bits not two. assign up4 = cim_k[(csek2 + ch - 18)+:csek2]; // This checks that an undef base gives 'bx out. assign up5 = cim_k[(csek2 + ch - offset)+:csek2]; // This checks the always above code. assign dwn1 = cim_k[(csek2 + ch + 2)-:csek2]; // This checks the always below code. assign dwn2 = cim_k[(csek2 + ch - 17)-:csek2]; // This checks that an undef base gives 'bx out. assign dwn3 = cim_k[(csek2 + ch - offset)-:csek2]; `else assign up1 = 2'b0x; assign up2 = 2'b0x; assign up3 = 2'b0x; assign up4 = 2'b0x; assign up5 = 2'b0x; assign dwn1 = 2'b0x; assign dwn2 = 2'b0x; assign dwn3 = 2'b0x; `endif initial begin #1; passed = 1'b1; if (cim_k !== 15'bz) begin $display("FAILED: cim_k should be 15'bz, got %b", cim_k); passed = 1'b0; end if (up1 !== 2'b0x) begin $display("FAILED: up1 should be 2'b0x, got %b", up1); passed = 1'b0; end if (up2 !== 2'b0x) begin $display("FAILED: up2 should be 2'b0x, got %b", up2); passed = 1'b0; end if (up3 !== 2'b0x) begin $display("FAILED: up3 should be 2'b0x, got %b", up3); passed = 1'b0; end if (up4 !== 2'b0x) begin $display("FAILED: up4 should be 2'b0x, got %b", up4); passed = 1'b0; end if (up5 !== 2'b0x) begin $display("FAILED: up5 should be 2'b0x, got %b", up5); passed = 1'b0; end if (dwn1 !== 2'b0x) begin $display("FAILED: dwn1 should be 2'b0x, got %b", dwn1); passed = 1'b0; end if (dwn2 !== 2'b0x) begin $display("FAILED: dwn2 should be 2'b0x, got %b", dwn2); passed = 1'b0; end if (dwn3 !== 2'b0x) begin $display("FAILED: dwn3 should be 2'b0x, got %b", dwn3); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2395378a.v000066400000000000000000000000771435245347300203040ustar00rootroot00000000000000module top; buf(strong0, highz1) #1 sclbuf0(iscl); endmodule iverilog-12_0/ivtest/ivltests/pr2395378b.v000066400000000000000000000000471435245347300203020ustar00rootroot00000000000000module top; buf sclbuf0(); endmodule iverilog-12_0/ivtest/ivltests/pr2395378c.v000066400000000000000000000000771435245347300203060ustar00rootroot00000000000000module top; not(strong0, highz1) #1 sclbuf0(iscl); endmodule iverilog-12_0/ivtest/ivltests/pr2395835.v000066400000000000000000000005121435245347300201330ustar00rootroot00000000000000module t(); reg passed = 1; task abc; input [7:0] a; begin if(a == 1) $display("OK"); else begin $display("FAILURE"); passed = 0; end end endtask reg [7:0] b; initial begin #1 ; abc(500 >> 8); b = 500 >> 8; abc(b); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2425055a.v000066400000000000000000000003631435245347300202640ustar00rootroot00000000000000module main; reg [31:0] a, b, c; initial begin a = 1; b = 1; b[2] = 1'bx; c = a << b; //$display( "a: %b, b: %b, c: %b", a, b, c ); if (c != 32'bx) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2425055b.v000066400000000000000000000017071435245347300202700ustar00rootroot00000000000000module top; reg pass; reg [1:0] in, shift, result; reg signed [1:0] ins; initial begin pass = 1'b1; in = 2'b01; shift = 2'bx1; result = in << shift; if (result !== 2'bxx) begin $display("Failed <<, expected 2'bxx, got %b", result); pass = 1'b0; end result = in <<< shift; if (result !== 2'bxx) begin $display("Failed <<<, expected 2'bxx, got %b", result); pass = 1'b0; end result = in >> shift; if (result !== 2'bxx) begin $display("Failed >>, expected 2'bxx, got %b", result); pass = 1'b0; end result = in >>> shift; if (result !== 2'bxx) begin $display("Failed >>>, expected 2'bxx, got %b", result); pass = 1'b0; end ins = 2'b10; result = ins >>> shift; if (result !== 2'bxx) begin $display("Failed >>> (signed), expected 2'bxx, got %b", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2425055c.v000066400000000000000000000017401435245347300202660ustar00rootroot00000000000000module top; reg pass; reg [1:0] in, shift, result; reg signed [1:0] ins; wire [1:0] ls = in << shift; wire [1:0] als = in <<< shift; wire [1:0] rs = in >> shift; wire [1:0] rs2 = in >>> shift; wire [1:0] ars = ins >> shift; initial begin pass = 1'b1; in = 2'b01; ins = 2'b10; shift = 2'bx1; #1 if (ls !== 2'bxx) begin $display("Failed << (CA), expected 2'bxx, got %b", ls); pass = 1'b0; end if (als !== 2'bxx) begin $display("Failed <<< (CA), expected 2'bxx, got %b", als); pass = 1'b0; end if (rs !== 2'bxx) begin $display("Failed >> (CA), expected 2'bxx, got %b", rs); pass = 1'b0; end if (rs2 !== 2'bxx) begin $display("Failed >>> (CA), expected 2'bxx, got %b", rs2); pass = 1'b0; end if (ars !== 2'bxx) begin $display("Failed >>> (signed, CA), expected 2'bxx, got %b", ars); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2428890.v000066400000000000000000000013041435245347300201310ustar00rootroot00000000000000module top; lower #(0, 0, 1) dut(); endmodule module lower; parameter one = 0; // This should be 'sd0 parameter two = 0; // This should be 'sd0 parameter three = 0; // This should be 'sd1 parameter local1 = one - two; // This should be 'sd0 // This line is not working correctly. // The 1 is not considered signed! // local1 + 1 is giving 'd1 not 'sd1. parameter local2 = local1+1-three; // This should be 'sd0 // Even this fails. // parameter local2 = local1+'sd1-three; // This should be 'sd0 initial begin // This should be 2 < -1. if (2 < local2-1) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2428890b.v000066400000000000000000000022671435245347300203040ustar00rootroot00000000000000module top; lower #(1, 2, 3) dut(); endmodule module lower; parameter one = 1; // This should be 'sd1 parameter two = 2; // This should be 'sd2 parameter three = 0; // This should be 'sd3 parameter local1 = one - two; // This should be -'sd1 parameter local_lt0 = local1 < 0; // This should be 'd1 parameter local_le0 = local1 <= 0; // This should be 'd1 parameter local_gt0 = local1 > 0; // This should be 'd0 parameter local_ge0 = local1 >= 0; // This should be 'd0 parameter local_0lt = 0 < local1; // This should be 'd1 parameter local_0le = 0 <= local1; // This should be 'd1 parameter local_0gt = 0 > local1; // This should be 'd0 parameter local_0ge = 0 >= local1; // This should be 'd0 reg err; initial begin err = 0; if (!local_lt0) err = 1; if (!local_le0) err = 1; if ( local_gt0) err = 1; if ( local_ge0) err = 1; if ( local_0lt) err = 1; if ( local_0le) err = 1; if (!local_0gt) err = 1; if (!local_0ge) err = 1; if (err == 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2428890c.v000066400000000000000000000015171435245347300203020ustar00rootroot00000000000000module top; lower #(1, 2, 3) dut(); endmodule module lower; parameter one = 1; // This should be 'sd1 parameter two = 2; // This should be 'sd2 parameter three = 0; // This should be 'sd3 parameter local1 = one - two; // This should be -'sd1 parameter local_t1 = local1 * 1; // This should be -'d1 parameter local_d1 = local1 / 1; // This should be -'d1 reg err; initial begin err = 0; if (local_t1 !== -1) err = 1; if (local_t1 > 0) err = 1; if (local_d1 !== -1) err = 1; if (local_d1 > 0) err = 1; if (! $is_signed(local_t1)) err = 1; if (! $is_signed(local_d1)) err = 1; if (! $is_signed(local1)) err = 1; if (err == 0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr243.v000066400000000000000000000032631435245347300176070ustar00rootroot00000000000000/* * Copyright (c) 2001 Uwe Bonnes * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ `define ADC_DATA_OFFSET 5 `define ADC_CHANELS 8*48 //`define ADC_CHANELS 348 module mymod (out1,out2,state,reset); input [8:0] state; input reset; output out1,out2; assign out1 = (state > `ADC_DATA_OFFSET) ? 1 : 0; assign out2 = (state > `ADC_CHANELS + `ADC_DATA_OFFSET +1)|| (reset); endmodule // mymod module t; reg [8:0] state; reg reset; wire out1,out2; mymod m1 (out1,out2,state,reset); initial begin //$timeformat(-9,0,"ns",5); $display(" TIME:state:out1:out2"); $monitor("%7t:%5d:%3d:%3d",$time,state,out1,out2); state =0; reset = 0; #10 reset=1; #20 reset=0; #5110 $finish(0); end always begin #10 if (reset) state = 0; else state=state+1; end endmodule // t iverilog-12_0/ivtest/ivltests/pr2434688.v000066400000000000000000000032151435245347300201360ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [7:0] in; reg [3:0] out; initial begin pass = 1'b1; in = 8'b10100101; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in[7:'dx]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select LSB is X, expected 4'bxxxx, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in['dx:0]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select MSB is X, expected 4'bxxxx, got %b", out); pass = 1'b0; end out = 4'b0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out[0] = in['dx]; `else out[0] = 1'bx; `endif if (out !== 4'b000x) begin $display("FAILED: bit select is X, expected 4'b000x, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in[7:'dz]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select LSB is Z, expected 4'bxxxx, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in['dz:0]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select MSB is Z, expected 4'bxxxx, got %b", out); pass = 1'b0; end out = 4'b0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out[0] = in['dz]; `else out[0] = 1'bx; `endif if (out !== 4'b000x) begin $display("FAILED: bit select is Z, expected 4'b000x, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2434688b.v000066400000000000000000000032131435245347300202760ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; parameter [7:0] in = 8'b10100101; reg [3:0] out; initial begin pass = 1'b1; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in[7:'dx]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select LSB is X, expected 4'bxxxx, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in['dx:0]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select MSB is X, expected 4'bxxxx, got %b", out); pass = 1'b0; end out = 4'b0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out[0] = in['dx]; `else out[0] = 1'bx; `endif if (out !== 4'b000x) begin $display("FAILED: bit select is X, expected 4'b000x, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in[7:'dz]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select LSB is Z, expected 4'bxxxx, got %b", out); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out = in['dz:0]; `else out = 4'bxxxx; `endif if (out !== 4'bxxxx) begin $display("FAILED: part select MSB is Z, expected 4'bxxxx, got %b", out); pass = 1'b0; end out = 4'b0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST out[0] = in['dz]; `else out[0] = 1'bx; `endif if (out !== 4'b000x) begin $display("FAILED: bit select is Z, expected 4'b000x, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr243_std.v000066400000000000000000000032741435245347300204630ustar00rootroot00000000000000/* * Copyright (c) 2001 Uwe Bonnes * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ `define ADC_DATA_OFFSET 5 `define ADC_CHANELS 8*48 //`define ADC_CHANELS 348 module mymod (out1,out2,state,reset); input [8:0] state; input reset; output out1,out2; assign out1 = (state > `ADC_DATA_OFFSET) ? 1 : 0; assign out2 = (state > `ADC_CHANELS + `ADC_DATA_OFFSET +1)|| (reset); endmodule // mymod module t; reg [8:0] state; reg reset; wire out1,out2; mymod m1 (out1,out2,state,reset); initial begin //$timeformat(-9,0,"ns",5); $display(" TIME:state:out1:out2"); $monitor("%t:%5d:%4d:%4d",$time,state,out1,out2); state =0; reset = 0; #10 reset=1; #20 reset=0; #5110 $finish; end always begin #10 if (reset) state = 0; else state=state+1; end endmodule // t iverilog-12_0/ivtest/ivltests/pr245.v000066400000000000000000000005621435245347300176100ustar00rootroot00000000000000/* * See pr245 in the ivtest test suite. */ `timescale 1ns/1ns module t; wire [11:0] iodata; integer i; initial begin $timeformat(-9,0,"ns",5); $display(" TIME:IOD"); $monitor( "%7t:%3x", $time,iodata); #0 force iodata =0; for (i=0; i<512;i=i+1) #10 force iodata =i; end // initial begin endmodule // t iverilog-12_0/ivtest/ivltests/pr2450244.v000066400000000000000000000013671435245347300201260ustar00rootroot00000000000000module main; parameter [15:0] a = 16'h8421; reg [3:0] b, c; reg pass; always @* begin b = a[c+:4]; // $display($time, " c: %d, b: %h", c, b); end initial begin pass = 1'b1; c = 0; #1 if (b !== 4'd1) begin $display("FAILED: c = 0, expected 1, got %0d", b); pass = 1'b0; end #9 c = 4; #1 if (b !== 4'd2) begin $display("FAILED: c = 4, expected 2, got %0d", b); pass = 1'b0; end #9 c = 8; #1 if (b !== 4'd4) begin $display("FAILED: c = 8, expected 4, got %0d", b); pass = 1'b0; end #9 c = 12; #1 if (b !== 4'd8) begin $display("FAILED: c = 12, expected 8, got %0d", b); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2453002.v000066400000000000000000000015121435245347300201110ustar00rootroot00000000000000module top; reg pass = 1'b1; parameter one = 1'b1; parameter zero = 1'b0; parameter udef = 1'bx; real rl1 = one ? 4 : 4.5; // 4.0 real rl2 = zero ? 4.0 : 5; // 5.0 real rl3 = udef ? 6 : 6.0; // 6.0 real rl4 = udef ? 7 : 7; // 7.0 initial begin #1; if (rl1 != 4.0) begin $display("FAILED: real expression one, expected 4.0, got %f", rl1); pass = 1'b0; end if (rl2 != 5.0) begin $display("FAILED: real expression two, expected 5.0, got %f)", rl2); pass = 1'b0; end if (rl3 != 6.0) begin $display("FAILED: real expression three, expected 6.0, got %f", rl3); pass = 1'b0; end if (rl4 != 7.0) begin $display("FAILED: real expression four, expected 7.0, got %f", rl4); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2453002b.v000066400000000000000000000017361435245347300202630ustar00rootroot00000000000000module top; reg pass = 1'b1; parameter one = 1'b1; parameter zero = 1'b0; parameter udef = 1'bx; reg [2:0] four = 3'd4; reg [2:0] five = 3'd5; reg [2:0] six = 3'd6; reg [2:0] seven = 3'd7; wire real rl1 = one ? four : 4.5; // 4.0 wire real rl2 = zero ? 4.0 : five; // 5.0 wire real rl3 = udef ? six : 6.0; // 6.0 wire real rl4 = udef ? seven : seven; // 7.0 initial begin #1; if (rl1 != 4.0) begin $display("FAILED: real expression one, expected 4.0, got %f", rl1); pass = 1'b0; end if (rl2 != 5.0) begin $display("FAILED: real expression two, expected 4.0, got %f", rl2); pass = 1'b0; end if (rl3 != 6.0) begin $display("FAILED: real expression three, expected 4.0, got %f", rl3); pass = 1'b0; end if (rl4 != 7.0) begin $display("FAILED: real expression four, expected 7.0, got %f", rl4); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2456943.v000066400000000000000000000002051435245347300201300ustar00rootroot00000000000000module top; wire real test; initial begin if (test != 0.0) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2459681.v000066400000000000000000000003011435245347300201270ustar00rootroot00000000000000module bug(); reg [7:0] memory[1:0]; reg index; initial begin index = 0; memory[~index] = 1; if (memory[1] === 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr245_std.v000066400000000000000000000005601435245347300204600ustar00rootroot00000000000000/* * See pr245 in the ivtest test suite. */ `timescale 1ns/1ns module t; wire [11:0] iodata; integer i; initial begin $timeformat(-9,0,"ns",7); $display(" TIME:IOD"); $monitor( "%t:%3x", $time,iodata); #0 force iodata =0; for (i=0; i<512;i=i+1) #10 force iodata =i; end // initial begin endmodule // t iverilog-12_0/ivtest/ivltests/pr2470181a.v000066400000000000000000000014201435245347300202570ustar00rootroot00000000000000module main; reg a, b, reset, pass; always @* a = b | reset; always @* begin b = 1'b0; #2; b = a; end initial begin pass = 1'b1; reset = 1'b1; #1 if(b !== 1'b0) begin $display("FAILED initial zero for 1'b1, got %b", b); pass = 1'b0; end #2 if(b !== 1'b1) begin $display("FAILED initial set to 1'b1, got %b", b); pass = 1'b0; end // Since b is already 1'b1 reset can not change a to zero. reset = 1'b0; #1 if(b !== 1'b1) begin $display("FAILED block of initial zero for 1'b0, got %b", b); pass = 1'b0; end #2 if(b !== 1'b1) begin $display("FAILED block of initial set to 1'b0, got %b", b); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2470181b.v000066400000000000000000000011501435245347300202600ustar00rootroot00000000000000`begin_keywords "1364-2005" module main; reg pass; reg a, b; always @* begin b = a; #2; b = 1'b0; end task check_bit; input bit; begin a = bit; #1 if (a !== b) begin $display("FAILED, expected %b, got %b", a, b); pass = 1'b0; end #2 if (b !== 1'b0) begin $display("FAILED return to zero, got %b", b); pass = 1'b0; end end endtask initial begin pass = 1'b1; check_bit(1'b1); check_bit(1'b0); check_bit(1'bx); check_bit(1'bz); if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2476430.v000066400000000000000000000174101435245347300201270ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass; reg [60*8-1:0] str, cmp; reg [7:0] bval; reg [15:0] oval, hval; integer dval; time tval; real rval; initial begin pass = 1'b1; // Check the %b conversion. bval = 8'b01101001; cmp = "1101001"; $sformat(str, "%0b", bval); if (str != cmp) begin $display("FAILED: %%0b, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "0000000001101001"; $sformat(str, "%016b", bval); if (str != cmp) begin $display("FAILED: %%016b, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "1101001 "; $sformat(str, "%-016b", bval); if (str != cmp) begin $display("FAILED: %%-016b, expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the %o conversion. oval = 16'o01234; cmp = "1234"; $sformat(str, "%0o", oval); if (str != cmp) begin $display("FAILED: %%0o, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "00001234"; $sformat(str, "%08o", oval); if (str != cmp) begin $display("FAILED: %%08o, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "1234 "; $sformat(str, "%-08o", oval); if (str != cmp) begin $display("FAILED: %%-08o, expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the %h conversion. hval = 16'h0abc; cmp = "abc"; $sformat(str, "%0h", hval); if (str != cmp) begin $display("FAILED: %%0h, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "00000abc"; $sformat(str, "%08h", hval); if (str != cmp) begin $display("FAILED: %%08h, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "abc "; $sformat(str, "%-08h", hval); if (str != cmp) begin $display("FAILED: %%-08h, expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the %c conversion. bval = "c"; cmp = "c"; $sformat(str, "%0c", bval); if (str != cmp) begin $display("FAILED: %%0c, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "000c"; $sformat(str, "%04c", bval); if (str != cmp) begin $display("FAILED: %%04c, expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the %d conversion. dval = 123; cmp = "00000123"; $sformat(str, "%08d", dval); if (str != cmp) begin $display("FAILED: %%08d, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "+0000123"; $sformat(str, "%+08d", dval); if (str != cmp) begin $display("FAILED: %%+08d, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " 123"; $sformat(str, "%d", dval); if (str != cmp) begin $display("FAILED: %%d, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "123 "; $sformat(str, "%-08d", dval); if (str != cmp) begin $display("FAILED: %%-08d, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "123"; $sformat(str, "%0d", dval); if (str != cmp) begin $display("FAILED: %%0d, expected %0s, got %0s", cmp, str); pass = 1'b0; end dval = -123; cmp = "-0000123"; $sformat(str, "%08d", dval); if (str != cmp) begin $display("FAILED: %%08d, expected %0s, got %0s", cmp, str); pass = 1'b0; end $sformat(str, "%+08d", dval); if (str != cmp) begin $display("FAILED: %%+08d, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " -123"; $sformat(str, "%d", dval); if (str != cmp) begin $display("FAILED: %%d, expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the %t conversion. tval = 100_000; cmp = "0010000000"; $sformat(str, "%010t", tval); if (str != cmp) begin $display("FAILED: %%010t, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " 10000000"; // Default width is 20. $sformat(str, "%t", tval); if (str != cmp) begin $display("FAILED: %%t, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "10000000 "; $sformat(str, "%-010t", tval); if (str != cmp) begin $display("FAILED: %%-010t, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "10000000"; $sformat(str, "%0t", tval); if (str != cmp) begin $display("FAILED: %%0t, expected %0s, got %0s", cmp, str); pass = 1'b0; end rval=100_000.25; cmp = "0010000025"; $sformat(str, "%010t", rval); if (str != cmp) begin $display("FAILED: %%010t (real), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " 10000025"; // Default width is 20. $sformat(str, "%t", rval); if (str != cmp) begin $display("FAILED: %%t (real), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "10000025 "; $sformat(str, "%-010t", rval); if (str != cmp) begin $display("FAILED: %%-010t (real), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "10000025"; $sformat(str, "%0t", rval); if (str != cmp) begin $display("FAILED: %%0t (real), expected %0s, got %0s", cmp, str); pass = 1'b0; end // Display in ns with 10ps resolution. $timeformat(-9, 2, " ns", 15); cmp = "000100000.00 ns"; $sformat(str, "%015t", tval); if (str != cmp) begin $display("FAILED: %%015t (w/$tf), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " 100000.00 ns"; $sformat(str, "%t", tval); if (str != cmp) begin $display("FAILED: %%t (w/$tf), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "100000.00 ns "; $sformat(str, "%-015t", tval); if (str != cmp) begin $display("FAILED: %%-015t (w/$tf), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "100000.00 ns"; $sformat(str, "%-0t", tval); if (str != cmp) begin $display("FAILED: %%-0t (w/$tf), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "000100000.25 ns"; $sformat(str, "%015t", rval); if (str != cmp) begin $display("FAILED: %%015t (w/$tf, rl), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = " 100000.25 ns"; $sformat(str, "%t", rval); if (str != cmp) begin $display("FAILED: %%t (w/$tf, rl), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "100000.25 ns "; $sformat(str, "%-015t", rval); if (str != cmp) begin $display("FAILED: %%-015t (w/$tf, rl), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "100000.25 ns"; $sformat(str, "%-0t", rval); if (str != cmp) begin $display("FAILED: %%-0t (w/$tf, rl), expected %0s, got %0s", cmp, str); pass = 1'b0; end // Check the real conversions (%e, %f, %g). If one works they all // they all work (uses system conversion). rval = 1.25; cmp = "000000001.250000"; $sformat(str, "%016.6f", rval); if (str != cmp) begin $display("FAILED: %%016.6f, expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "+00000001.250000"; $sformat(str, "%+016.6f", rval); if (str != cmp) begin $display("FAILED: %%+016.6f, expected %0s, got %0s", cmp, str); pass = 1'b0; end rval = -1.25; cmp = "-00000001.250000"; $sformat(str, "%016.6f", rval); if (str != cmp) begin $display("FAILED: %%016.6f (negative), expected %0s, got %0s", cmp, str); pass = 1'b0; end cmp = "-00000001.250000"; $sformat(str, "%+016.6f", rval); if (str != cmp) begin $display("FAILED: %%+016.6f (negative), expected %0s, got %0s", cmp, str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2486350.v000066400000000000000000000003561435245347300201320ustar00rootroot00000000000000`timescale 1 s / 1 fs module main; reg a; initial begin a = 1'b0; #10 ; $display("simtime=%d (%h)", $simtime, $simtime); a = 1'b1; end initial begin #100 $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/pr2503208.v000066400000000000000000000003711435245347300201170ustar00rootroot00000000000000module tb; parameter A = 34; parameter B = 17; parameter C = ((A+1)>>1) + (B-((A+1)>>1)); initial begin if (C !== 17) begin $display("FAILED -- C == %d (%b)", C, C); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr2509349.txt000066400000000000000000000000201435245347300204740ustar00rootroot000000000000000 1 2 3 4 5 6 7 iverilog-12_0/ivtest/ivltests/pr2509349a.v000066400000000000000000000010051435245347300202670ustar00rootroot00000000000000module top; reg pass; reg [7:0] idx; reg [7:0] mem [0:7]; initial begin pass = 1'b1; // Neither no_dir or no_dir2 should exist and vsim should be a file. $readmempath("/tmp:/no_dir:no_dir2:vsim:ivltests"); $readmemh("pr2509349.txt", mem); for (idx = 0; idx < 8; idx = idx + 1) begin if (mem[idx] !== idx) begin $display("Failed mem[%0d], expected %d, got %d", idx, idx, mem[idx]); pass = 1'b0; end end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2509349b.v000066400000000000000000000002231435245347300202710ustar00rootroot00000000000000module top; reg [79:0] str; initial begin $readmempath(str); str = "test"; str[7:0] = 'd2; $readmempath(str); end endmodule iverilog-12_0/ivtest/ivltests/pr2528915.v000066400000000000000000000003411435245347300201300ustar00rootroot00000000000000module mainp_tb; reg clk=0; integer usb_stream; // reg [15:0] out_usb_stream; always @(posedge clk) begin // This should generate an error, not crash. $fwrite(usb_stream, "%c", out_usb_stream[7:0]); end endmodule iverilog-12_0/ivtest/ivltests/pr2533175.v000066400000000000000000000005551435245347300201310ustar00rootroot00000000000000module pr2533175(); task fill_array; begin:block reg [7:0] array[3:0]; integer i; for (i = 0; i < 4; i = i + 1) begin array[i] = i; end for (i = 0; i < 4; i = i + 1) begin if (array[i] != i) begin $display("FAILED: %0d != %0d", array[i], i); $finish; end end $display("PASSED"); end endtask initial fill_array; endmodule iverilog-12_0/ivtest/ivltests/pr2579479.v000066400000000000000000000006011435245347300201420ustar00rootroot00000000000000// Based on pr2579479 module main; supply0 gnd; supply1 vdd; wire A,B; tranif1 uA(gnd, A, vdd); tranif1 uB(A, B, vdd); tranif1 uC(B, vdd, gnd); initial begin #1 $display("A=%d, B=%d", A,B); if ((A !== 1'b0) || (B !== 1'b0)) begin $display("FAILED -- A=%b, B=%b", A, B); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr2580730.v000066400000000000000000000026171435245347300201310ustar00rootroot00000000000000/* * Verify that the various non-blocking assignments support a delay * that is greater than 32 bits. The top delays are in seconds and * the other delays are in ps. The second delays all require more * than 32 bits to work correctly. They will use the /d version. */ `timescale 1s/1s module gt32b; real rlval; reg rval; reg aval[1:0]; reg [7:0] psval; initial begin $timeformat(-12, 0, " ps", 16); #1; $display("dl:gt32b- %t", $realtime); rlval <= #1 1.0; rval <= #2 1'b1; aval[0] <= #3 1'b0; psval[1] <= #4 1'b1; end always @(rlval) begin $display("rl:gt32b- %t", $realtime); end always @(rval) begin $display("rg:gt32b- %t", $realtime); end always @(aval[0]) begin $display("ar:gt32b- %t", $realtime); end always @(psval) begin $display("ps:gt32b- %t", $realtime); end endmodule `timescale 1ps/1ps module ls32b; real rlval; reg rval; reg aval[1:0]; reg [7:0] psval; initial begin #1; $display("dl:ls32b- %t", $realtime); rlval <= #1 1.0; rval <= #2 1'b1; aval[0] <= #3 1'b0; psval[1] <= #4 1'b1; end always @(rlval) begin $display("rl:ls32b- %t", $realtime); end always @(rval) begin $display("rg:ls32b- %t", $realtime); end always @(aval[0]) begin $display("ar:ls32b- %t", $realtime); end always @(psval) begin $display("ps:ls32b- %t", $realtime); end endmodule iverilog-12_0/ivtest/ivltests/pr2590274a.v000066400000000000000000000010601435245347300202650ustar00rootroot00000000000000// We want to print a warning if we find a delay that comes from the // default timescale (1s) and then one from a given timescale. // Basically we want to have either the case of no timescales or // timescales for all delays. module wo_time; reg in; wire #1 out = in; initial begin in = 1'b1; #2 $finish(0); end always @(out) $display("The time in %m is: %e", $abstime); endmodule `timescale 1ns/1ns module w_time; reg in; wire #1 out = in; initial in = 1'b1; always @(out) $display("The time in %m is: %e", $abstime); endmodule iverilog-12_0/ivtest/ivltests/pr2590274b.v000066400000000000000000000006361435245347300202760ustar00rootroot00000000000000// We want to print a warning if we find a delay that comes from the // default timescale (1s) and then one from a given timescale. // Basically we want to have either the case of no timescales or // timescales for all delays. module wo_time; initial #1 $display("The time in %m is: %e", $abstime); endmodule `timescale 1ns/1ns module w_time; initial #1 $display("The time in %m is: %e", $abstime); endmodule iverilog-12_0/ivtest/ivltests/pr2590274c.v000066400000000000000000000014271435245347300202760ustar00rootroot00000000000000// We want to print a warning if we find a delay that comes from the // default timescale (1s) and then one from a given timescale. // Basically we want to have either the case of no timescales or // timescales for all delays. module wo_time(out, in); output out; input in; buf(out, in); specify (in => out) = 1; endspecify endmodule module top; reg in; wire out_wo, out_w; wo_time wo(out_wo, in); w_time w(out_w, in); initial begin in = 1'b1; #2 $finish(0); end always @(out_wo) $display("The time in wo_time is: %e", $abstime); always @(out_w) $display("The time in w_time is: %e", $abstime); endmodule `timescale 1ns/1ns module w_time(out, in); output out; input in; buf(out, in); specify (in => out) = 1; endspecify endmodule iverilog-12_0/ivtest/ivltests/pr2593733.v000066400000000000000000000004551435245347300201360ustar00rootroot00000000000000`timescale 1 ps / 1 ps module use_wid_gt_zero_assert ( ); parameter width = 1; parameter option = "OFF"; reg [width-1:0] dst; initial begin dst = (option == "ON") ? {width{1'b1}} : {width{1'b0}}; if (dst === 1'b0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2597278.v000066400000000000000000000010161435245347300201400ustar00rootroot00000000000000module top; reg [1:0] q; reg [4:0] icim[1:0]; integer j; always @(q) begin /* * The following line had the muli problem, the other line has a * different problem. */ icim[0] <= #1 0 + 8 * (0 >> q); icim[1] <= #1 1 + 8 * (1 >> q); end initial begin q = 2'd1; #2; if (icim[0] !== 0) begin $display("FAILED"); $finish; end if (icim[1] !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2597278b.v000066400000000000000000000010171435245347300203030ustar00rootroot00000000000000module top; reg [1:0] q; wire [4:0] icim[1:0]; integer j; always @(q) begin /* * The following line had the muli problem, the other line has a * different problem. */ icim[0] <= #1 0 + 8 * (0 >> q); icim[1] <= #1 1 + 8 * (1 >> q); end initial begin q = 2'd1; #2; if (icim[0] !== 0) begin $display("FAILED"); $finish; end if (icim[1] !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2605006.v000066400000000000000000000006571435245347300201250ustar00rootroot00000000000000module test(); reg clk; reg [15:0] usb_shadow [0: 32]; initial begin usb_shadow[6'b0_00000] = 'b0101; usb_shadow[6'b1_00000] = 'b1001; clk = 0; if (usb_shadow[{!clk,5'b0}][15:2] !== 2) begin $display("FAILED"); $finish; end clk = 1; if (usb_shadow[{!clk,5'b0}][15:2] !== 1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/pr2673846.v000066400000000000000000000017751435245347300201500ustar00rootroot00000000000000module top; reg [39:0] x, x_inv_bug, temp_x; integer i, j; wire [39:0] res2 = {40 {1'd1}} / x; initial begin // Using this assignment instead of the procedural assignment below // will work with out asserting. // x = 1; // assign x_inv_bug = {40 {1'd1}} / x; temp_x = 2**31; for (i=30 ; i < 38; i=i+1) begin temp_x = temp_x << 1; for (j=0 ; j<3; j=j+1) begin x = temp_x + (j-1); $display(" // i,j,temp_x,x => %2d,%1d,%d,%h", i, j, temp_x, x); // The following statement is asserting and it looks to be a // problem in the division algorithm. This specific case is // likely only a 32 bit problem, but by scaling I'm sure this // could be made to trigger on a 64 bit machine. x_inv_bug = {40 {1'd1}} / x; #1 $display("x_inv_bug=%h, res2=%h", x_inv_bug, res2); if (x_inv_bug !== res2) begin $display("FAILED"); $finish; end end end // for (i=30 ; i < 38; i=i+1) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2688910.v000066400000000000000000000006121435245347300201330ustar00rootroot00000000000000module top; reg passed = 1'b1; reg [7:0] in; lwr dut(in); initial begin #1 in = 8'd1; #1 in = 8'd2; #1 if (passed) $display("PASSED"); end endmodule module lwr(input [7:0] xin); wire [7:0] x1 = {xin,{0{1'b0}}}; always @(x1) if (x1 != $time) begin $display("Failed at time %2d, expected %2d, got %2d", $time, $time, x1); top.passed = 1'b0; end endmodule iverilog-12_0/ivtest/ivltests/pr2709097.hex000066400000000000000000000000111435245347300204430ustar00rootroot000000000000000000000a iverilog-12_0/ivtest/ivltests/pr2709097.v000066400000000000000000000003441435245347300201350ustar00rootroot00000000000000module top; reg [31:0] mem[0:0]; initial begin $readmemh( "ivltests/pr2709097.hex", mem ); // $display("mem[0] = %d", mem[0]); if (mem[0] !== 10) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2715547.v000066400000000000000000000003301435245347300201250ustar00rootroot00000000000000module top; reg [31:0] mem [3:0]; initial begin mem[1] = {32{1'b1}}; mem[1][15] = 1'b0; if (mem[1] !== 32'hffff7fff) $display("Failed, got %h", mem[1]); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2715558.v000066400000000000000000000047441435245347300201440ustar00rootroot00000000000000// NOTE: This test program is WRONG, in that it ignores the fact // that continuous assigns drive with their own strength and drop // any strength that the r-value may have. module strength(); wire sup1; assign (supply0, supply1) sup1 = 1'b1; wire str1; assign (strong0, strong1) str1 = 1'b1; wire pl1; assign (pull0, pull1) pl1 = 1'b1; wire we1; assign (weak0, weak1) we1 = 1'b1; wire sup0; assign (supply0, supply1) sup0 = 1'b0; wire str0; assign (strong0, strong1) str0 = 1'b0; wire pl0; assign (pull0, pull1) pl0 = 1'b0; wire we0; assign (weak0, weak1) we0 = 1'b0; wire sup1_sup0; wire sup1_str0; wire sup1_pl0; wire sup1_we0; assign sup1_sup0 = sup1; assign sup1_sup0 = sup0; assign sup1_str0 = sup1; assign sup1_str0 = str0; assign sup1_pl0 = sup1; assign sup1_pl0 = pl0; assign sup1_we0 = sup1; assign sup1_we0 = we0; initial begin #1; $display("sup1_sup0 resulted in: %b", sup1_sup0); $display("sup1_str0 resulted in: %b", sup1_str0); $display("sup1_pl0 resulted in: %b", sup1_pl0); $display("sup1_we0 resulted in: %b", sup1_we0); end wire str1_sup0; wire str1_str0; wire str1_pl0; wire str1_we0; assign str1_sup0 = str1; assign str1_sup0 = sup0; assign str1_str0 = str1; assign str1_str0 = str0; assign str1_pl0 = str1; assign str1_pl0 = pl0; assign str1_we0 = str1; assign str1_we0 = we0; initial begin #2; $display("str1_sup0 resulted in: %b", str1_sup0); $display("str1_str0 resulted in: %b", str1_str0); $display("str1_pl0 resulted in: %b", str1_pl0); $display("str1_we0 resulted in: %b", str1_we0); end wire pl1_sup0; wire pl1_str0; wire pl1_pl0; wire pl1_we0; assign pl1_sup0 = pl1; assign pl1_sup0 = sup0; assign pl1_str0 = pl1; assign pl1_str0 = str0; assign pl1_pl0 = pl1; assign pl1_pl0 = pl0; assign pl1_we0 = pl1; assign pl1_we0 = we0; initial begin #3; $display("pl1_sup0 resulted in: %b", pl1_sup0); $display("pl1_str0 resulted in: %b", pl1_str0); $display("pl1_pl0 resulted in: %b", pl1_pl0); $display("pl1_we0 resulted in: %b", pl1_we0); end wire we1_sup0; wire we1_str0; wire we1_pl0; wire we1_we0; assign we1_sup0 = we1; assign we1_sup0 = sup0; assign we1_str0 = we1; assign we1_str0 = str0; assign we1_pl0 = we1; assign we1_pl0 = pl0; assign we1_we0 = we1; assign we1_we0 = we0; initial begin #4; $display("we1_sup0 resulted in: %b", we1_sup0); $display("we1_str0 resulted in: %b", we1_str0); $display("we1_pl0 resulted in: %b", we1_pl0); $display("we1_we0 resulted in: %b", we1_we0); end endmodule iverilog-12_0/ivtest/ivltests/pr2715558b.v000066400000000000000000000054011435245347300202750ustar00rootroot00000000000000/* The original test case submitted for pr2715558 should not have given the the results the bug reporter expected (see pr2986806). This is a reworked version that does give those results. */ module pr2715558b(); wire sup1_sup0; wire sup1_str0; wire sup1_pl0; wire sup1_we0; assign (supply0, supply1) sup1_sup0 = 1'b1; assign (supply0, supply1) sup1_sup0 = 1'b0; assign (supply0, supply1) sup1_str0 = 1'b1; assign (strong0, strong1) sup1_str0 = 1'b0; assign (supply0, supply1) sup1_pl0 = 1'b1; assign (pull0, pull1) sup1_pl0 = 1'b0; assign (supply0, supply1) sup1_we0 = 1'b1; assign (weak0, weak1) sup1_we0 = 1'b0; initial begin #1; $display("sup1_sup0 resulted in: %b", sup1_sup0); $display("sup1_str0 resulted in: %b", sup1_str0); $display("sup1_pl0 resulted in: %b", sup1_pl0); $display("sup1_we0 resulted in: %b", sup1_we0); end wire str1_sup0; wire str1_str0; wire str1_pl0; wire str1_we0; assign (strong0, strong1) str1_sup0 = 1'b1; assign (supply0, supply1) str1_sup0 = 1'b0; assign (strong0, strong1) str1_str0 = 1'b1; assign (strong0, strong1) str1_str0 = 1'b0; assign (strong0, strong1) str1_pl0 = 1'b1; assign (pull0, pull1) str1_pl0 = 1'b0; assign (strong0, strong1) str1_we0 = 1'b1; assign (weak0, weak1) str1_we0 = 1'b0; initial begin #1; $display("str1_sup0 resulted in: %b", str1_sup0); $display("str1_str0 resulted in: %b", str1_str0); $display("str1_pl0 resulted in: %b", str1_pl0); $display("str1_we0 resulted in: %b", str1_we0); end wire pl1_sup0; wire pl1_str0; wire pl1_pl0; wire pl1_we0; assign (pull0, pull1) pl1_sup0 = 1'b1; assign (supply0, supply1) pl1_sup0 = 1'b0; assign (pull0, pull1) pl1_str0 = 1'b1; assign (strong0, strong1) pl1_str0 = 1'b0; assign (pull0, pull1) pl1_pl0 = 1'b1; assign (pull0, pull1) pl1_pl0 = 1'b0; assign (pull0, pull1) pl1_we0 = 1'b1; assign (weak0, weak1) pl1_we0 = 1'b0; initial begin #1; $display("pl1_sup0 resulted in: %b", pl1_sup0); $display("pl1_str0 resulted in: %b", pl1_str0); $display("pl1_pl0 resulted in: %b", pl1_pl0); $display("pl1_we0 resulted in: %b", pl1_we0); end wire we1_sup0; wire we1_str0; wire we1_pl0; wire we1_we0; assign (weak0, weak1) we1_sup0 = 1'b1; assign (supply0, supply1) we1_sup0 = 1'b0; assign (weak0, weak1) we1_str0 = 1'b1; assign (strong0, strong1) we1_str0 = 1'b0; assign (weak0, weak1) we1_pl0 = 1'b1; assign (pull0, pull1) we1_pl0 = 1'b0; assign (weak0, weak1) we1_we0 = 1'b1; assign (weak0, weak1) we1_we0 = 1'b0; initial begin #1; $display("we1_sup0 resulted in: %b", we1_sup0); $display("we1_str0 resulted in: %b", we1_str0); $display("we1_pl0 resulted in: %b", we1_pl0); $display("we1_we0 resulted in: %b", we1_we0); end endmodule iverilog-12_0/ivtest/ivltests/pr2715748.v000066400000000000000000000013521435245347300201350ustar00rootroot00000000000000module top; integer res; real rvar [1:0]; realtime rtvar [1:0]; wire real rnet [1:0]; assign rnet[0] = 2.0; initial begin rvar[0] = -1.0; rtvar[0] = 1.0; #1; // Check the various get routines. $display("Real %g, Realtime %g", rvar[0], rtvar[0]); $display("Real as int %d, Realtime as int %d", rvar[0], rtvar[0]); $display("Real net %g", rnet[0]); $display("Real net as int %d", rnet[0]); // Check some put routines. res = $sscanf("3.5", "%f", rvar[1]); if (rvar[1] != 3.5) $display("Failed %%f put"); else $display("Passed %%f put"); res = $sscanf("4", "%d", rtvar[1]); if (rtvar[1] != 4.0) $display("Failed %%d put"); else $display("Passed %%d put"); end endmodule iverilog-12_0/ivtest/ivltests/pr2721213.v000066400000000000000000000001261435245347300201130ustar00rootroot00000000000000module top; task foo(); $display("PASSED"); endtask initial foo; endmodule iverilog-12_0/ivtest/ivltests/pr2722330a.v000066400000000000000000000025771435245347300202710ustar00rootroot00000000000000// Check that the >> and >>> operators with unsigned values. module top; parameter py = 8'b10101010 >> 3'b101; parameter pz = 8'b10101010 >>> 3'b101; reg passed; reg [7:0] a; reg [2:0] b; wire [7:0] wy, wz; reg [7:0] ry, rz; // Check CA code. assign wy = a >> b; assign wz = a >>> b; initial begin passed = 1'b1; // Example vector a = 8'b10101010; b = 3'b101; #1; // Check the parameter results. if (py !== 8'b00000101) begin $display("Failed param. >>, expected 8'b00000101, got %b", py); passed = 1'b0; end if (pz !== 8'b00000101) begin $display("Failed param. >>>, expected 8'b00000101, got %b", pz); passed = 1'b0; end // Check the procedural results. ry = a >> b; if (ry !== 8'b00000101) begin $display("Failed procedural >>, expected 8'b00000101, got %b", ry); passed = 1'b0; end rz = a >>> b; if (rz !== 8'b00000101) begin $display("Failed procedural >>>, expected 8'b00000101, got %b", rz); passed = 1'b0; end // Check the CA results. if (wy !== 8'b00000101) begin $display("Failed CA >>, expected 8'b00000101, got %b", wy); passed = 1'b0; end if (wz !== 8'b00000101) begin $display("Failed CA >>>, expected 8'b00000101, got %b", wz); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2722330b.v000066400000000000000000000024601435245347300202610ustar00rootroot00000000000000module top; parameter py = 8'sb10101010 >> 3'sb110; parameter pz = 8'sb10101010 >>> 3'sb110; reg passed; reg signed [7:0] ry, rz, a; wire signed [7:0] wy, wz; assign wy = a >> 3'sb110; assign wz = a >>> 3'sb110; initial begin passed = 1'b1; // Example vector a = 8'sb10101010; #1; // Check the parameter results. if (py !== 8'b00000010) begin $display("Failed parameter >>, expected 8'b00000010, got %b", py); passed = 1'b0; end if (pz !== 8'b11111110) begin $display("Failed parameter >>>, expected 8'b11111110, got %b", pz); passed = 1'b0; end // Check the procedural results. ry = a >> 3'sb110; if (ry !== 8'b00000010) begin $display("Failed procedural >>, expected 8'b00000010, got %b", ry); passed = 1'b0; end rz = a >>> 3'sb110; if (rz !== 8'b11111110) begin $display("Failed procedural >>>, expected 8'b11111110, got %b", rz); passed = 1'b0; end // Check the CA results. if (wy !== 8'b00000010) begin $display("Failed CA >>, expected 8'b00000010, got %b", wy); passed = 1'b0; end if (wz !== 8'b11111110) begin $display("Failed CA >>>, expected 8'111111110, got %b", wz); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2722339a.v000066400000000000000000000022641435245347300202730ustar00rootroot00000000000000module top; reg pass; reg [7:0] a, b; wire [15:0] ruu, rsu, rus, rss; reg signed [15:0] res; integer i; assign ruu = a / b; assign rsu = $signed(a) / b; assign rus = a / $signed(b); assign rss = $signed(a) / $signed(b); initial begin pass = 1'b1; // Run 1000 random vectors for (i = 0; i < 1000; i = i + 1) begin // Random vectors a = $random; b = $random; #1; // Check unsigned / unsigned. if (ruu !== a/b) begin $display("FAILED: u/u (%b/%b) gave %b, expected %b", a, b, ruu, a/b); pass = 1'b0; end // Check signed / unsigned. if (rsu !== a/b) begin $display("FAILED: s/u (%b/%b) gave %b, expected %b", a, b, rsu, a/b); pass = 1'b0; end // Check unsigned / signed. if (rus !== a/b) begin $display("FAILED: u/s (%b/%b) gave %b, expected %b", a, b, rus, a/b); pass = 1'b0; end // Check signed / signed. res = $signed(a)/$signed(b); if (rss !== res) begin $display("FAILED: s/s (%b/%b) gave %b, expected %b", a, b, rss, res); pass = 1'b0; end end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2722339b.v000066400000000000000000000023301435245347300202660ustar00rootroot00000000000000module top; reg pass; reg [7:0] a, b; wire [15:0] ruu, rsu, rus, rss; reg signed [15:0] res; integer i; assign ruu = a % b; assign rsu = $signed(a) % b; assign rus = a % $signed(b); assign rss = $signed(a) % $signed(b); initial begin pass = 1'b1; // Run 1000 random vectors for (i = 0; i < 1000; i = i + 1) begin // Random vectors a = $random; b = $random; #1; // Check unsigned % unsigned. if (ruu !== a%b) begin $display("FAILED: u%%u (%b%%%b) gave %b, expected %b", a, b, ruu, a%b); pass = 1'b0; end // Check signed % unsigned division. if (rsu !== a%b) begin $display("FAILED: s%%u (%b%%%b) gave %b, expected %b", a, b, rsu, a%b); pass = 1'b0; end // Check unsigned % signed division. if (rus !== a%b) begin $display("FAILED: u%%s (%b%%%b) gave %b, expected %b", a, b, rus, a%b); pass = 1'b0; end // Check signed % signed division. res = $signed(a)%$signed(b); if (rss !== res) begin $display("FAILED: s%%s (%b%%%b) gave %b, expected %b", a, b, rss, res); pass = 1'b0; end end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2723712.v000066400000000000000000000006071435245347300201250ustar00rootroot00000000000000module top; reg [7:0] a; reg [2:0] b; wire [7:0] y, z; assign y = a >> b; assign z = $signed(a) >> $signed(b); initial begin // Example vector a = 8'b10101010; b = 3'b101; #1; // Test for correctness if (y === z && y === 8'b00000101) $display("PASSED"); else $display("FAILED, expected 8'b00000101, got %b/%b", y, z); end endmodule iverilog-12_0/ivtest/ivltests/pr2725700a.v000066400000000000000000000024631435245347300202670ustar00rootroot00000000000000module top; reg pass; wire out; reg drive_val; reg oe_n; reg [1:0] pull_vec; bufif0 (out, drive_val, oe_n); assign (pull0, pull1) out = pull_vec[0]; initial begin pass = 1'b1; pull_vec = 2'b00; oe_n = 1'b0; // Drive is selected. drive_val = 1'b0; #1; if (out !== drive_val) begin $display("Failed to drive 0, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== drive_val) begin $display("Failed to drive 1, got %b", out); pass = 1'b0; end // The pull is selected (low). oe_n = 1'b1; drive_val = 1'b0; #1; if (out !== pull_vec[0]) begin $display("Failed pull #1, expected 1'b0, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== pull_vec[0]) begin $display("Failed pull #2, expected 1'b0, got %b", out); pass = 1'b0; end // The pull is selected (high). pull_vec = 2'b11; drive_val = 1'b0; #1; if (out !== pull_vec[0]) begin $display("Failed pull #3, expected 1'b1, got %b", out); pass = 1'b0; end drive_val = 1'b1; if (out !== pull_vec[0]) begin $display("Failed pull #4, expected 1'b1, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2725700b.v000066400000000000000000000025551435245347300202720ustar00rootroot00000000000000module top; reg pass; wire [1:0] out; reg [1:0] drive_val; reg [1:0] oe_n; reg [2:0] pull_vec; bufif0 bufs[1:0] (out, drive_val, oe_n); assign (pull0, pull1) out = pull_vec[1:0]; initial begin pass = 1'b1; pull_vec = 3'b000; oe_n = 2'b00; // Drive is selected. drive_val = 2'b00; #1; if (out !== drive_val) begin $display("Failed to drive 2'b00, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== drive_val) begin $display("Failed to drive 2'b11, got %b", out); pass = 1'b0; end // The pull is selected (low). oe_n = 2'b11; drive_val = 2'b00; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #1, expected 2'b00, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #2, expected 2'b00, got %b", out); pass = 1'b0; end // The pull is selected (high). pull_vec = 3'b111; drive_val = 2'b00; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #3, expected 2'b11, got %b", out); pass = 1'b0; end drive_val = 2'b11; if (out !== pull_vec[1:0]) begin $display("Failed pull #4, expected 2'b11, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2725700c.v000066400000000000000000000026261435245347300202720ustar00rootroot00000000000000module top; reg pass; wire [1:0] out; reg [1:0] drive_val; reg [1:0] oe_n; reg [2:0] pull_vec; reg [1:0] base; bufif0 bufs[1:0] (out, drive_val, oe_n); assign (pull0, pull1) out = pull_vec[base+:2]; initial begin pass = 1'b1; base = 2'b00; pull_vec = 3'b000; oe_n = 2'b00; // Drive is selected. drive_val = 2'b00; #1; if (out !== drive_val) begin $display("Failed to drive 2'b00, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== drive_val) begin $display("Failed to drive 2'b11, got %b", out); pass = 1'b0; end // The pull is selected (low). oe_n = 2'b11; drive_val = 2'b00; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #1, expected 2'b00, got %b", out); pass = 1'b0; end drive_val = 1'b1; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #2, expected 2'b00, got %b", out); pass = 1'b0; end // The pull is selected (high). pull_vec = 3'b111; drive_val = 2'b00; #1; if (out !== pull_vec[1:0]) begin $display("Failed pull #3, expected 2'b11, got %b", out); pass = 1'b0; end drive_val = 2'b11; if (out !== pull_vec[1:0]) begin $display("Failed pull #4, expected 2'b11, got %b", out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2728032.v000066400000000000000000000131461435245347300201270ustar00rootroot00000000000000module top; reg pass; time change; reg in; wire c1, c2a, c2b, c3; wire v1, v2, v3; const_1 d_c1(c1, in); const_2a d_c2a(c2a, in); const_2b d_c2b(c2b, in); const_3 d_c3(c3, in); var_1 d_v1(v1, in); // var_2 d_v2(v2, in); var_3 d_v3(v2, in); initial begin pass = 1'b1; #1000 in = 1'b0; #1000 in = 1'b1; #1000 in = 1'b0; #1000 in = 1'b1; #1000 in = 1'bx; #1000 in = 1'b0; #1000 in = 1'bx; #1000 in = 1'b1; #1000 in = 1'b0; #1000 if (pass) $display("PASSED"); end always @(in) change = $time; endmodule // All delays should be 200. module const_1 (output out, input in); assign #(200) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != 200) begin $display("Failed const_1 fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != 200) begin $display("Failed const_1 rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != 200) begin $display("Failed const_1 high-Z"); top.pass = 1'b0; end default: begin $display("FAILED const_1 default"); top.pass = 1'b0; end endcase end endmodule // Decay should also be 100. module const_2a (output out, input in); assign #(200, 100) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != 100) begin $display("Failed const_2a fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != 200) begin $display("Failed const_2a rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != 100) begin $display("Failed const_2a high-Z"); top.pass = 1'b0; end default: begin $display("FAILED const_2a default"); top.pass = 1'b0; end endcase end endmodule // Decay should also be 100. module const_2b (output out, input in); assign #(100, 200) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != 200) begin $display("Failed const_2b fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != 100) begin $display("Failed const_2b rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != 100) begin $display("Failed const_2b high-Z"); top.pass = 1'b0; end default: begin $display("FAILED const_2b default"); top.pass = 1'b0; end endcase end endmodule // All delays as given. module const_3 (output out, input in); assign #(100, 200, 300) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != 200) begin $display("Failed const_3 fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != 100) begin $display("Failed const_3 rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != 300) begin $display("Failed const_3 high-Z"); top.pass = 1'b0; end default: begin $display("FAILED const_3 default"); top.pass = 1'b0; end endcase end endmodule // All delays should be delay. module var_1 (output out, input in); time delay = 200; assign #(delay) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != delay) begin $display("Failed var_1 fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != delay) begin $display("Failed var_1 rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != delay) begin $display("Failed var_1 high-Z"); top.pass = 1'b0; end default: begin $display("FAILED var_1 default"); top.pass = 1'b0; end endcase end endmodule /* * We do not currently support calculating the decay time from the * variable rise and fall times. The compiler will print a message * and assert in the code generator. * * We need an a and b version to check both ways. * // Decay should be the minimum of rise and fall delay. module var_2 (output out, input in); time delayr = 100; time delayf = 200; assign #(delayr, delayf) out = ~in; function automatic real min_real(real a, real b); min_real = a < b ? a : b; endfunction always @(out) begin case (out) 1'b0: if ($time - top.change != delayf) begin $display("Failed var_2 fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != delayr) begin $display("Failed var_2 rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != min_real(delayf, delayr)) begin $display("Failed var_2 high-Z"); top.pass = 1'b0; end default: begin $display("FAILED var_2 default"); top.pass = 1'b0; end endcase end endmodule */ // All delays as given. module var_3 (output out, input in); time delayr = 100; time delayf = 200; time delayd = 300; assign #(delayr, delayf, delayd) out = (in === 1'bx) ? 1'bz : ~in; always @(out) begin case (out) 1'b0: if ($time - top.change != delayf) begin $display("Failed var_3 fall"); top.pass = 1'b0; end 1'b1: if ($time - top.change != delayr) begin $display("Failed var_3 rise"); top.pass = 1'b0; end 1'bz: if ($time - top.change != delayd) begin $display("Failed var_3 high-Z"); top.pass = 1'b0; end default: begin $display("FAILED var_3 default"); top.pass = 1'b0; end endcase end endmodule iverilog-12_0/ivtest/ivltests/pr2728547.v000066400000000000000000000016501435245347300201370ustar00rootroot00000000000000module top; parameter in = "First Second Third 15"; reg pass; integer res, arg4; reg [32*8:1] arg1, arg2, arg3; initial begin pass = 1'b1; res = $sscanf(in, "%s%s%s%d", arg1, arg2, arg3, arg4); if (res != 4) begin $display("FAILED: wrong number of arguments, expected 4, got %0d", res); pass = 1'b0; end if (arg1[5*8:1] !== "First") begin $display("FAILED: arg1, expected \"First\", got \"%0s\"", arg1); pass = 1'b0; end if (arg2[6*8:1] !== "Second") begin $display("FAILED: arg2, expected \"Second\", got \"%0s\"", arg2); pass = 1'b0; end if (arg3[5*8:1] !== "Third") begin $display("FAILED: arg3, expected \"Third\", got \"%0s\"", arg3); pass = 1'b0; end if (arg4 != 15) begin $display("FAILED: arg4, expected 15, got %0d", arg4); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2728812a.v000066400000000000000000000020041435245347300202650ustar00rootroot00000000000000`timescale 1ns/1ns module sum_test; reg clk; wire [10:0] s; initial begin clk = 0; forever #10 clk = ~clk; end sum #(5, 8) sum (clk, {8'd10,8'd20,8'd30,8'd40,8'd50}, s); initial begin $display("Starting..."); repeat (50) @(posedge clk); $display("sum = %d",s); if (s !== 150) $display("FAILED: expected 150, received %0d",s); else $display("PASSED"); $finish; end endmodule module sum #( parameter n = 4, parameter width = 8, parameter log_n = $clog2(n) ) ( input clk, input [n*width-1:0]addends, output reg [log_n+width-1:0] s ); generate if (n==1) always @(*) s = addends; else begin wire [$clog2(n/2)+width-1:0] a1; wire [$clog2(n-n/2)+width-1:0] a2; sum #(n/2, width) s0 (clk, addends[(n/2)*width-1:0], a1); sum #(n-n/2, width) s1 (clk, addends[n*width-1:(n/2)*width], a2); always @(posedge clk) s <= a1 + a2; end endgenerate endmodule // sum iverilog-12_0/ivtest/ivltests/pr2728812b.v000066400000000000000000000022141435245347300202710ustar00rootroot00000000000000`timescale 1ns/1ns // Run this with -pRECURSIVE_MOD_LIMIT=5 to keep the output file small. module sum_test; reg clk; wire [10:0] s; initial begin clk = 0; forever #10 clk = ~clk; end sum #(5, 8) sum (clk, {8'd10,8'd20,8'd30,8'd40,8'd50}, s); initial begin $display("Starting..."); repeat (50) @(posedge clk); $display("sum = %d",s); if (s !== 150) $display("FAILED: expected 150, received %0d",s); else $display("PASSED"); $finish; end endmodule module sum #( parameter n = 4, parameter width = 8, parameter log_n = $clog2(n) ) ( input clk, input [n*width-1:0]addends, output reg [log_n+width-1:0] s ); generate // This does not terminate and should fail after 100 loops. if (n==-1) always @(*) s = addends; else begin wire [$clog2(n/2)+width-1:0] a1; wire [$clog2(n-n/2)+width-1:0] a2; sum #(n/2, width) s0 (clk, addends[(n/2)*width-1:0], a1); sum #(n-n/2, width) s1 (clk, addends[n*width-1:(n/2)*width], a2); always @(posedge clk) s <= a1 + a2; end endgenerate endmodule // sum iverilog-12_0/ivtest/ivltests/pr2728812c.v000066400000000000000000000020001435245347300202630ustar00rootroot00000000000000`timescale 1ns/1ns module sum_test; reg clk; wire [10:0] s; initial begin clk = 0; forever #10 clk = ~clk; end sum #(5, 8) sum (clk, {8'd10,8'd20,8'd30,8'd40,8'd50}, s); initial begin $display("Starting..."); repeat (50) @(posedge clk); $display("sum = %d",s); if (s !== 150) $display("FAILED: expected 150, received %0d",s); else $display("PASSED"); $finish; end endmodule module sum #( parameter n = 4, parameter width = 8, parameter log_n = $clog2(n) ) ( input clk, input [n*width-1:0]addends, output reg [log_n+width-1:0] s ); // This should fail at the first recursion since this is not inside // a generate block. wire [$clog2(n/2)+width-1:0] a1; wire [$clog2(n-n/2)+width-1:0] a2; sum #(n/2, width) s0 (clk, addends[(n/2)*width-1:0], a1); sum #(n-n/2, width) s1 (clk, addends[n*width-1:(n/2)*width], a2); always @(posedge clk) s <= a1 + a2; endmodule // sum iverilog-12_0/ivtest/ivltests/pr273.v000066400000000000000000000027151435245347300176130ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@telocity.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Test non-constant bit selects - causes compile error right now module test; reg clk; reg [1:0] in0; reg [1:0] in1; reg sel0,sel1; wire [1:0] q; dff2 u1 (q,clk,in0[sel0],in1[sel1]); initial begin clk = 0; in0 = 2'b0; in1 = 2'b0; sel0 = 1'b0; sel1 = 1'b1; #8; $display("initial val =%x",q); #8; if(q == 2'b0) $display("PASSED"); else $display("FAILED"); $finish ; end always #5 clk = ~clk; endmodule // This is just a dual dff module dff2 (q,clk,d0,d1); input clk,d0,d1; output [1:0] q; reg [1:0] q; always @(posedge clk) q <= {d1,d0}; endmodule iverilog-12_0/ivtest/ivltests/pr2745281.v000066400000000000000000000010311435245347300201220ustar00rootroot00000000000000`define MERROR(code, msg) if (code == 0) begin $display(msg); end module top; integer return_code; integer msg_out; initial begin // This shows that the macro is okay for the simple case `MERROR(0, "This message works") // This one gives a syntax error. `MERROR($value$plusargs("msgOut=%d", msg_out), "This message does not work") // This was a workaround return_code = $value$plusargs("msgOut=%d", msg_out); `MERROR(return_code, "This last message works") $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2781595.v000066400000000000000000000030771435245347300201460ustar00rootroot00000000000000module xortest(out, a, b); output out; input a, b; parameter tdelay=2; wire a_, b_, i1, i2, i3; supply0 gnd; supply1 vdd; nmos #(tdelay) n5(a_, gnd, a); pmos #(tdelay) p5(a_, vdd, a); nmos #(tdelay) n6(b_, gnd, b); pmos #(tdelay) p6(b_, vdd, b); nmos #(tdelay) n1(out, i1, a); nmos #(tdelay) n2(i1, gnd, b); nmos #(tdelay) n3(out, i2, a_); nmos #(tdelay) n4(i2, gnd, b_); pmos #(tdelay) p1(out, i3, a); pmos #(tdelay) p2(out, i3, b); pmos #(tdelay) p3(i3, vdd, a_); pmos #(tdelay) p4(i3, vdd, b_); endmodule module testXor(); wire out; reg a, b; reg pass; xortest x1(out, a, b); initial begin pass = 1'b1; a=1;b=1; #100; $display("A=%b B=%b Out=%b",a,b,out); a=0;b=1; #100; $display("A=%b B=%b Out=%b",a,b,out); a=1;b=0; #100; $display("A=%b B=%b Out=%b",a,b,out); a=0;b=0; #100; $display("A=%b B=%b Out=%b",a,b,out); repeat (3) begin a=0;b=1; #100; $display("REP A=%b B=%b Out=%b",a,b,out); a=1;b=0; #100; $display("REP A=%b B=%b Out=%b",a,b,out); end a=1;b=1; #100; $display("A=%b B=%b Out=%b",a,b,out); a=0;b=1; #100; $display("A=%b B=%b Out=%b",a,b,out); a=1;b=0; #100; $display("A=%b B=%b Out=%b",a,b,out); a=0;b=0; #100; $display("A=%b B=%b Out=%b",a,b,out); if (pass) $display("PASSED"); end always @(out) begin // Wait for the value to settle. #10 if (out !== (a ^ b)) begin $display("Failed at %0t, expected %b, got %b, with a=%b, b=%b", $time, a ^ b, out, a, b); pass = 1'b0; end end endmodule iverilog-12_0/ivtest/ivltests/pr2785294.v000066400000000000000000000016001435245347300201340ustar00rootroot00000000000000module top; // The array code does not currently work because we need &APV<>! // Both &PV<> and &APV<> (when implemented) need to have bit // specific value change callbacks to function correctly. reg [7:0] array [1:0]; reg [7:0] bs, ps; integer idx; initial begin bs = 8'b0; ps = 8'b0; array[0] = 8'b0; $monitor($time," BS = ", bs[1], ", PS = ", ps[2:1], ", AR = ", array[0][1]); // This should only trigger the $monitor when bit 1 changes. for (idx = 0; idx < 8 ; idx = idx + 1) begin #1 bs[idx] = 1'b1; end // This should only trigger the $monitor when bit 1 or 2 changes. for (idx = 0; idx < 8 ; idx = idx + 1) begin #1 ps[idx] = 1'b1; end // This should only trigger the $monitor when bit 1 of array[0] changes.. for (idx = 0; idx < 8 ; idx = idx + 1) begin #1 array[0][idx] = 1'b1; end end endmodule iverilog-12_0/ivtest/ivltests/pr2788686.v000066400000000000000000000034051435245347300201510ustar00rootroot00000000000000module top; reg pass; reg [7:0] vec; integer off; time delay; event trig; initial begin pass = 1'b1; delay = 1; // Assign before the vector (constant delay). vec = 8'hff; off = -1; vec[off] <= #1 1'b0; #2 if (vec !== 8'hff) begin $display("Failed the before vector (C) test, expected 8'hff, got %h", vec); pass = 1'b0; end // Assign after the vector (constant delay). vec = 8'hff; off = 8; vec[off] <= #1 1'b0; #2 if (vec !== 8'hff) begin $display("Failed the after vector (C) test, expected 8'hff, got %h", vec); pass = 1'b0; end // Assign before the vector (variable delay). vec = 8'hff; off = -1; vec[off] <= #(delay) 1'b0; #2 if (vec !== 8'hff) begin $display("Failed the before vector (V) test, expected 8'hff, got %h", vec); pass = 1'b0; end // Assign after the vector (variable delay). vec = 8'hff; off = 8; vec[off] <= #(delay) 1'b0; #2 if (vec !== 8'hff) begin $display("Failed the after vector (V) test, expected 8'hff, got %h", vec); pass = 1'b0; end // Assign before the vector (event trigger). vec = 8'hff; off = -1; vec[off] <= @(trig) 1'b0; ->trig; #1 if (vec !== 8'hff) begin $display("Failed the before vector (E) test, expected 8'hff, got %h", vec); pass = 1'b0; end // Assign after the vector (event trigger). vec = 8'hff; off = 8; vec[off] <= @(trig) 1'b0; ->trig; #1 if (vec !== 8'hff) begin $display("Failed the after vector (V) test, expected 8'hff, got %h", vec); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2790236.v000066400000000000000000000005011435245347300201230ustar00rootroot00000000000000module test (a, b); output a; reg a = 1'b0; output reg b = 1'b1; endmodule module top; wire out1, out2; test dut(out1, out2); initial begin #1; if (out1 !== 1'b0 || out2 !== 1'b1) begin $display("Failed: expected 0:1, got %b:%b", out1, out2); end else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2792883.v000066400000000000000000000001631435245347300201410ustar00rootroot00000000000000module top; parameter WIDTH = dut.WIDTH; test dut(); endmodule module test; parameter WIDTH = 8; endmodule iverilog-12_0/ivtest/ivltests/pr2792897.v000066400000000000000000000003401435245347300201430ustar00rootroot00000000000000module top; parameter parm = 1.4; reg [31:0] str; initial begin $sformat(str, "R: %d", parm); if (str !== "R: 1") $display("FAILED: expected 'R: 1', got %s", str); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2792897_std.v000066400000000000000000000003401435245347300210150ustar00rootroot00000000000000module top; parameter parm = 1.4; reg [31:0] str; initial begin $sformat(str, "R: %d", parm); if (str !== " 1") $display("FAILED: expected ' 1', got %s", str); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2794144.v000066400000000000000000000003221435245347300201260ustar00rootroot00000000000000module top; reg res; reg [1:0] in; initial begin in = 2'b00; res = ~ |in; res = ~ ∈ res = ~ ^in; $display("FAILED: These expressions should be a syntax error."); end endmodule iverilog-12_0/ivtest/ivltests/pr2800985a.v000066400000000000000000000257721435245347300203100ustar00rootroot00000000000000/* * Do some run time checks with $ferror(). We can not count on the return * code or the strings to be the same on different machines so we can only * look for the existence of an error and call that good enough. We humans * can look at the full output to see if it is correct. */ module top; parameter work_file = "work/pr2800985.txt"; reg pass; integer errno, bfd, vfd, mcd, res; reg [639:0] result, str; /* * Tasks to check and clear the error state. */ task check_error; begin // Check that there was an error. if (errno == 0) begin $display(" FAILED: expected an error!"); pass = 1'b0; end clear_error; end endtask task clear_error; begin // Clear the error state. res = $ftell(vfd); errno = $ferror(vfd, result); if (errno != 0) begin $display("Failed to clear error state (%0s)", result); $finish; end end endtask initial begin pass = 1'b1; vfd = $fopen(work_file, "w+"); if (vfd == 0) begin errno = $ferror(vfd, result); $display("Failed to open required file %s (%0s).", work_file, result); $finish; end /* * $ferror() only takes a fd, so a valid MCD is not valid.. */ $display("Check a valid MCD."); errno = $ferror(1, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Basic $fopen() checking. */ $display("Opening a file that does not exist."); bfd = $fopen("FileDoesNotExist", "r"); $display(" $fopen returned: %h", bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * These do not work when the user has root privileges, so we need to * just skip them. * $display("Opening a file that we should not be able to write to."); bfd = $fopen("/FileDoesNotExist", "w"); $display(" $fopen returned: %h", bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; $display("Opening a file that we should not be able to write to (MCD)."); mcd = $fopen("/FileDoesNotExist"); $display(" $fopen returned: %h", mcd); errno = $ferror(mcd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; */ $display("Opening a directory we should not be able to write."); bfd = $fopen("/", "w"); $display(" $fopen returned: %h", bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fclose(). */ $display("Checking $fclose with fd 0 and -1."); bfd = 0; $fclose(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; $fclose(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fdisplay(), assume the b/h/o version work the same. */ $display("Checking $fdisplay with fd 0 and -1."); bfd = 0; $fdisplay(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; $fdisplay(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fwrite(), assume the b/h/o version work the same. */ $display("Checking $fwrite with fd 0 and -1."); bfd = 0; $fwrite(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; $fwrite(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fstrobe(), assume the b/h/o version work the same. */ $display("Checking $fstrobe with fd 0 and -1."); bfd = 0; $fstrobe(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; $fstrobe(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fgetc(). */ $display("Checking $fgetc with fd 0 and -1."); bfd = 0; res = $fgetc(bfd); $display(" $fgetc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fgetc(bfd); $display(" $fgetc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $ungetc(). */ $display("Checking $ungetc with fd 0 and -1 and char = EOF."); bfd = 0; res = $ungetc(0, bfd); $display(" $ungetc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $ungetc(0, bfd); $display(" $ungetc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; // This returns EOF (-1), but does not set errno. res = $ungetc(-1, vfd); $display(" $ungetc returned: %0d", res); errno = $ferror(vfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); if (res != -1 || errno != 0) begin $display(" Failed expected result (-1, 0), got (%0d, %0d).", res, errno); // It's OK if this returns a value in errno. if (res != -1) pass = 1'b0; clear_error; end /* * Check $fgets(). */ $display("Checking $fgets with fd 0 and -1."); bfd = 0; res = $fgets(str, bfd); $display(" $fgets returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fgets(str, bfd); $display(" $fgets returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fscanf(). */ $display("Checking $fscanf with fd 0 and -1."); bfd = 0; res = $fscanf(bfd, "%s", str); $display(" $fscanf returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fscanf(bfd, "%s", str); $display(" $fscanf returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fread(). */ $display("Checking $fread with fd 0 and -1."); bfd = 0; res = $fread(str, bfd); $display(" $fread returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fread(str, bfd); $display(" $fread returned: %0d, '%0s'", res, str); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $ftell(). */ $display("Checking $ftell with fd 0 and -1."); bfd = 0; res = $ftell(bfd); $display(" $ftell returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $ftell(bfd); $display(" $ftell returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fseek(). */ $display("Checking $fseek."); bfd = 0; res = $fseek(bfd, 0, 0); $display(" $fseek returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fseek(bfd, 0, 0); $display(" $fseek returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; // A valid fd, but an invalid operation. res = $fseek(vfd, 0, 4); $display(" $fseek returned: %0d", res); errno = $ferror(vfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $rewind(). */ $display("Checking $rewind with fd 0 and -1."); bfd = 0; res = $rewind(bfd); $display(" $rewind returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $rewind(bfd); $display(" $rewind returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fflush(). */ $display("Checking $fflush with fd 0 and -1."); bfd = 0; $fflush(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; $fflush(bfd); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $feof(). */ $display("Checking $feof with fd 0 and -1."); bfd = 0; res = $feof(bfd); $display(" $feof returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $feof(bfd); $display(" $feof returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; /* * Check $fputc() (Icarus specific). */ `ifdef __ICARUS__ $display("Checking $fputc with fd 0 and -1."); bfd = 0; res = $fputc(0, bfd); $display(" $fputc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; bfd = -1; res = $fputc(0, bfd); $display(" $fputc returned: %0d", res); errno = $ferror(bfd, result); $display(" $ferror returned: %0d, '%0s'", errno, result); check_error; `endif /* * Check that $fstrobe does not access a file after it is closed. */ $display("Checking $fstrobe after $fclose."); res = $rewind(vfd); if (res != 0) begin $display("Failed to rewind file"); $finish; end $fwrite(vfd, "test-"); $fstrobe(vfd, "FAILED"); $fclose(vfd); vfd = $fopen(work_file, "r"); if (vfd == 0) begin errno = $ferror(vfd, result); $display("Failed to open required file %s (%0s).", work_file, result); $finish; end res = $fgets(str, vfd); if (res == 0) begin errno = $ferror(vfd, result); $display("Failed to read back result (%0s)", result); str = "failed"; end if (str !== "test-") begin $display("$fstrobe was not skipped, expected 'test-', got '%0s'", str); pass = 1'b0; end $fclose(vfd); if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2800985b.v000066400000000000000000000007711435245347300203010ustar00rootroot00000000000000/* * Check $ferror() compile time errors. */ module top; integer errno, fd; reg [639:0] result; reg [63:0] sresult; initial begin fd = 0; errno = $ferror("string", result); // Invalid first argument. errno = $ferror(fd); // Missing second argument. errno = $ferror(fd, "string"); // Invalid second argument. errno = $ferror(fd, sresult); // Second argument is too small. errno = $ferror(fd, result, "xx"); // Extra arguments. end endmodule iverilog-12_0/ivtest/ivltests/pr2801134.v000066400000000000000000000025071435245347300201210ustar00rootroot00000000000000module top; parameter a_res = 16'b000001xx0xxx0xxx; parameter o_res = 16'b01xx1111x1xxx1xx; parameter x_res = 16'b01xx10xxxxxxxxxx; reg pass; reg [15:0] y, z, a, o, x; reg [127:0] yl, zl, al, ol, xl; initial begin pass = 1'b1; y = 16'b01xz01xz01xz01xz; z = 16'b00001111xxxxzzzz; yl = {8{y}}; zl = {8{z}}; // Check the & results a = y & z; if (a !== a_res) begin $display("FAILED: & test, expected %b, got %b", a_res, a); pass = 1'b0; end al = yl & zl; if (al !== {8{a_res}}) begin $display("FAILED: & (large) test, expected %b, got %b", {8{a_res}}, al); pass = 1'b0; end // Check the | results o = y | z; if (o !== o_res) begin $display("FAILED: | test, expected %b, got %b", o_res, o); pass = 1'b0; end ol = yl | zl; if (ol !== {8{o_res}}) begin $display("FAILED: | (large) test, expected %b, got %b", {8{o_res}}, ol); pass = 1'b0; end // Check the ^ results x = y ^ z; if (x !== x_res) begin $display("FAILED: | test, expected %b, got %b", x_res, x); pass = 1'b0; end xl = yl ^ zl; if (xl !== {8{x_res}}) begin $display("FAILED: ^ (large) test, expected %b, got %b", {8{x_res}}, xl); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2801662.v000066400000000000000000000007601435245347300201260ustar00rootroot00000000000000`timescale 1ns/1ps module test; reg in, pass; wire out; assign #(1?2:1) out = in; // assign #(1+1) out = in; initial begin pass = 1'b1; in = 1'b0; #1.999; if (out !== 1'bx) begin $display("Failed signal at begining, expected 1'bx, got %b", out); pass = 1'b0; end #0.002; if (out !== in) begin $display("Failed signal at end, expected %b, got %b", in, out); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2806449.v000066400000000000000000000006141435245347300201340ustar00rootroot00000000000000module top; reg[63:0] a; initial begin a = 64'h7fe8000000000000; // This used to fail because we printed floating point using // the default buffer which was only 256 bytes long. To fix // this the default size was changed to 512 bytes and this is // increased when needed (%400.300f, etc.). $display("%6.3f", $bitstoreal(a)); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2806474.v000066400000000000000000000036771435245347300201460ustar00rootroot00000000000000module top; reg pass; real a, b; integer i; wire real b1 = 42.0 + 10/100; wire real b2 = a + 10/100; wire real b3 = 42.0 + i/100; wire real b4 = a + i/100; initial begin pass = 1'b1; // Check the compiler for the whole expression. b = 42.0 + 10/100; if (b != 42.0) begin $display("FAILED: compiler constant, expected 42.0, got %6.1f", b); pass = 1'b0; end // Check the compiler for just the division. a = 42; b = a + 10/100; if (b != 42.0) begin $display("FAILED: compiler constant div., expected 42.0, got %6.1f", b); pass = 1'b0; end // Check the run time with a constant sum value (just the division). i = 10; b = 42.0 + i/100; if (b != 42.0) begin $display("FAILED: runtime constant real, expected 42.0, got %6.1f", b); pass = 1'b0; end // Check the original expression. b = a + i/100; if (b != 42.0) begin $display("FAILED: runtime, expected 42.0, got %6.1f", b); pass = 1'b0; end // Check the ternary operator with one clause needing to be converted. b = (i === 10) ? i/100 : 1.0; if (b != 0.0) begin $display("FAILED: runtime (ternary), expected 0.0, got %6.1f", b); pass = 1'b0; end b = |i; if (b != 1.0) begin $display("FAILED: runtime (reduction), expected 1.0, got %6.1f", b); pass = 1'b0; end // Check the continuous assigns. #1; if (b1 != 42.0) begin $display("FAILED: CA test 1, expected 42.0, got %6.1f", b1); pass = 1'b0; end if (b2 != 42.0) begin $display("FAILED: CA test 2, expected 42.0, got %6.1f", b2); pass = 1'b0; end if (b3 != 42.0) begin $display("FAILED: CA test 3, expected 42.0, got %6.1f", b3); pass = 1'b0; end if (b4 != 42.0) begin $display("FAILED: CA test 4, expected 42.0, got %6.1f", b4); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2809288.v000066400000000000000000000002401435245347300201330ustar00rootroot00000000000000module top; integer i = 0; generate for(i=0; i<4; i=i+1) begin:U reg [1:0] a = i; end endgenerate initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr2815398a.v000066400000000000000000000031111435245347300202730ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [2:0] res [0:7]; reg [2:0] in [0:7]; reg [7:0] dummy [0:6]; time run_time [0:7]; time exp_time [0:7]; integer i; initial begin pass = 1'b1; #1; // Initialize the input array. for (i=0; i<8; i=i+1) begin in[i] = i[2:0]; end #1; for (i=0; i<8; i=i+1) begin exp_time[i] = $time-1; end check; // We only have 6 dummy items, check that each triggers correctly. for (i=0; i<7; i=i+1) begin dummy[i] = 1'b0; #1; exp_time[i] = $time-1; check; end if (pass) $display("PASSED"); end // Check that the value and time are correct. task check; integer j; begin for (j=0; j<8; j=j+1) begin if (res[j] !== j[2:0]) begin $display("FAILED: index %0d value, at %2t, expexted %b, got %b.", j, $time, j[2:0], res[j]); pass = 1'b0; end if (run_time[j] !== exp_time[j]) begin $display("FAILED: index %0d time, at %2t, expexted %2t, got %2t.", j, $time, exp_time[j], run_time[j]); pass = 1'b0; end end end endtask genvar m; generate `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST for (m=0; m<=7; m=m+1) begin: idac_loop `else for (m=0; m<=6; m=m+1) begin: idac_loop `endif // This should complain that dummy[7] is out of bounds. always @ (in[m] or dummy[m]) begin res[m] = in[m]; run_time[m] = $time; end end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2815398a_std.v000066400000000000000000000031051435245347300211500ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [2:0] res [0:7]; reg [2:0] in [0:7]; reg [7:0] dummy [0:6]; time run_time [0:7]; time exp_time [0:7]; integer i; initial begin pass = 1'b1; #1; // Initialize the input array. for (i=0; i<8; i=i+1) begin in[i] = i[2:0]; end #1; for (i=0; i<8; i=i+1) begin exp_time[i] = $time-1; end check; // We only have 6 dummy items, check that each triggers correctly. for (i=0; i<7; i=i+1) begin dummy[i] = 1'b0; #1; exp_time[i] = $time-1; check; end if (pass) $display("PASSED"); end // Check that the value and time are correct. task check; integer j; begin for (j=0; j<8; j=j+1) begin if (res[j] !== j[2:0]) begin $display("FAILED: index %0d value, at %t, expexted %b, got %b.", j, $time, j[2:0], res[j]); pass = 1'b0; end if (run_time[j] !== exp_time[j]) begin $display("FAILED: index %0d time, at %t, expexted %t, got %t.", j, $time, exp_time[j], run_time[j]); pass = 1'b0; end end end endtask genvar m; generate `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST for (m=0; m<=7; m=m+1) begin: idac_loop `else for (m=0; m<=6; m=m+1) begin: idac_loop `endif // This should complain that dummy[7] is out of bounds. always @ (in[m] or dummy[m]) begin res[m] = in[m]; run_time[m] = $time; end end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2815398b.v000066400000000000000000000015511435245347300203020ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; wire [2:0] arr [0:7]; reg rarr [0:7]; integer i; initial begin pass = 1'b1; #1; for (i = 0; i <=7 ; i = i + 1) begin if (arr[i] !== i) begin $display("FAILED: index %1d, expected %1d, got %1d", i, i, arr[i]); pass = 1'b0; end end if (pass) $display("PASSED"); end // This should display a warning and just ignore the whole statement. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign arr[20] = 'b0; assign arr[-1] = 'b0; `endif genvar m; generate // This like above should warn when 8 <= m <= 15. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST for (m=0; m<=15; m=m+1) begin: arr_loop `else for (m=0; m<=7; m=m+1) begin: arr_loop `endif assign arr[m] = m; end endgenerate endmodule iverilog-12_0/ivtest/ivltests/pr2818823.v000066400000000000000000000014671435245347300201420ustar00rootroot00000000000000module top; parameter C1 = 1.0e-6; reg pass; real rval; real exp_result; initial begin pass = 1'b1; exp_result = -1000000.0; // Check with a constant and a parameter. rval = -1 / C1; if (rval != exp_result) begin $display ("FAILED: -1/%f gave %f, expected %f", C1, rval, exp_result); pass = 1'b0; end // Check with both constants. rval = -1 / 1.0e-6; if (rval != exp_result) begin $display ("FAILED: -1/1.0e-6 gave %f, expected %f", rval, exp_result); pass = 1'b0; end // Check with a positive value. exp_result = 1000000.0; rval = 1 / C1; if (rval != exp_result) begin $display ("FAILED: 1/%f gave %f, not expected %f", C1, rval, exp_result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2823414.v000066400000000000000000000003341435245347300201220ustar00rootroot00000000000000module top; initial begin `ifdef CAUSES_PROBLEM /* * C-Style comment in a skipped `ifdef is loosing the '\n'. */ `endif // This should report an error at line 10. fail_at_line_10(); end endmodule iverilog-12_0/ivtest/ivltests/pr2823711.v000066400000000000000000000012201435245347300201150ustar00rootroot00000000000000// The basic example is from 1364-2005 module top; reg pass; reg [3:0] a; reg [5:0] b; reg [15:0] c; initial begin pass = 1'b1; a = 4'hF; b = 6'hA; // Self-determined context so the width is the same as a (4 bits). c = { a**b }; if (c !== 16'h0001) begin $display("FAILED self-determined power, expected 0001, got %h", c); pass = 1'b0; end // The width is determined by a and c so use 16 bits here. c = a**b; if (c !== 16'hac61) begin $display("FAILED context-determined power, expected ac61, got %h", c); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2824189.txt000066400000000000000000000000021435245347300204760ustar00rootroot00000000000000a iverilog-12_0/ivtest/ivltests/pr2824189.v000066400000000000000000000012621435245347300201350ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg pass; reg [3:0] var; integer fd, code; initial begin pass = 1'b1; fd = $fopen("ivltests/pr2824189.txt", "r"); code = $fscanf(fd, "%x\n", var); if (code != 1) begin $display("Failed initial variable read count expected 1, got %d", code); pass = 1'b0; end if (var !== 4'ha) begin $display("Failed initial variable read value expected a, got %h", var); pass = 1'b0; end code = $fscanf(fd, "%x\n", var); if (code != -1) begin $display("Failed $fscanf() at EOF"); pass = 1'b0; end $fclose(fd); if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2829776.v000066400000000000000000000061541435245347300201510ustar00rootroot00000000000000module top; reg in1, in2, pass, checkc, checkg, checkp; wire outc, outg, outp; assign #400 outc = in1 | in2; or #400 g1(outg, in1, in2); my_or #400 g2(outp, in1, in2); initial begin // $monitor($time,,outc, outg, outp,, in1,, in2); pass = 1'b1; checkc = 1'b0; checkg = 1'b0; checkp = 1'b0; in1 = 1'b0; in2 = 1'b0; #100 in1 = 1'b1; #200 in2 = 1'b1; #199; // Check to see if the output changed early. if (outc !== 1'bz && outc !== 1'bx) begin $display("CA output changed early!"); pass = 1'b0; end if (outg !== 1'bz && outg !== 1'bx) begin $display("Gate output changed early!"); pass = 1'b0; end if (outp !== 1'bz && outp !== 1'bx) begin $display("UDP output changed early!"); pass = 1'b0; end #2; // Check to see if the output changed late. if (outc !== 1'b1) begin $display("CA output changed late!"); pass = 1'b0; checkc = 1'b1; end if (outg !== 1'b1) begin $display("Gate output changed late!"); pass = 1'b0; checkg = 1'b1; end if (outp !== 1'b1) begin $display("UDP output changed late!"); pass = 1'b0; checkp = 1'b1; end #198; // We need to execute the three if checks in parallel. fork if (checkc) begin if (outc === 1'bz || outc === 1'bx) begin #2; // Check to see if the output changed off of the wrong edge. if (outc === 1'b1) $display("CA output triggered off of in2 change instead of in1."); else $display("CA output triggered very late."); end end if (checkg) begin if (outg === 1'bz || outg === 1'bx) begin #2; // Check to see if the output changed off of the wrong edge. if (outg === 1'b1) $display("Gate output triggered off of in2 change instead of in1."); else $display("Gate output triggered very late."); end end if (checkp) begin if (outp === 1'bz || outp === 1'bx) begin #2; // Check to see if the output changed off of the wrong edge. if (outp === 1'b1) $display("UDP output triggered off of in2 change instead of in1."); else $display("UDP output triggered very late."); end end #2; // This keeps the passing case alligned with the fails. join // Generate a 399 wide negative pulse that should be skipped. in1 = 1'b0; in2 = 1'b0; #399; in1 = 1'b1; in2 = 1'b1; #2; // Check that the pulse did not propagate. if (outc !== 1'b1) begin $display("CA does not have inertial delay."); pass = 1'b0; end if (outg !== 1'b1) begin $display("Gate does not have inertial delay."); pass = 1'b0; end if (outp !== 1'b1) begin $display("UDP does not have inertial delay."); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule primitive my_or (out, in1, in2); output out; input in1, in2; table 0 0 : 0; 1 ? : 1; ? 1 : 1; endtable endprimitive iverilog-12_0/ivtest/ivltests/pr2829776b.v000066400000000000000000000023351435245347300203100ustar00rootroot00000000000000`timescale 1ns/1ps module top; reg pass; reg ina, inb; wire out; my_or dut(out, ina, inb); initial begin pass = 1'b1; ina = 1'b0; inb = 1'b0; #0.399 if (out !== 1'bx && out !== 1'bz) begin $display("FAILED: gate had incorrect delay, expected x/z, got %b.", out); pass = 1'b0; end #0.002 if (out !== 1'b0) begin $display("FAILED: gate had incorrect delay, expected 0, got %b.", out); pass = 1'b0; end // Check inertial delays. ina = 1'b1; #0.399 ina = 1'b0; #0.002 if (out !== 1'b0) begin $display("FAILED: inertial delay, expected 0, got %b.", out); pass = 1'b0; end // Check that this change is relative to the first edge. ina = 1'b1; #0.200; inb = 1'b1; #0.201; if (out !== 1'b1) begin $display("FAILED: double edge delay, expected 1, got %b.", out); pass = 1'b0; #0.200; if (out === 1'b1) begin $display("FAILED: double edge delay was off second edge."); end end if (pass) $display("PASSED"); end endmodule module my_or(out, ina, inb); output out; input ina, inb; or(out, ina, inb); specify (ina, inb *> out) = 0.4; endspecify endmodule iverilog-12_0/ivtest/ivltests/pr2832234.v000066400000000000000000000061641435245347300201310ustar00rootroot00000000000000/* * There are a number of problem that this example uncovers. * * It appears that the inverter connected to the ctl input of the * tranif gate is not getting the signal passed to it. It looks * like once the ctl signal is pulled into the island it can not * propagate the signal back out. The fix may be in the compiler * where we should only use the island port signal for the tranif * control instead of any signal that connects to the ctl net. * * When the ctl signal removes the connection between the two * nets they should self resolve. Is appears that when the ctl * signal is removed the nets stay at their current value. */ module top; reg pass; reg ctl, ctl2, in, in2; wire y1, y2, ctlb, y2b; assign y1 = in; pullup (weak1) (y2); tranif0 q1(y1, y2, ctl); assign y2 = ctl2 ? in2 : 1'bz; not q2(ctlb, ctl); not q3(y2b, y2); initial begin pass = 1'b1; // The tran gate is closed and both sides should track 'in'. ctl = 1'b0; ctl2 = 1'b0; in = 1'b1; #1; if (ctlb !== 1'b1) begin $display("Failed ctlb with ctl = 0, expected 1'b1, got %b", ctlb); pass = 1'b0; end if (y2 !== 1'b1) begin $display("Failed tran with ctl = 0, in = 1, expected 1'b1, got %b", y2); pass = 1'b0; end if (y2b !== 1'b0) begin $display("Failed y2b with ctl = 0, in = 1, expected 1'b0, got %b", y2b); pass = 1'b0; end in = 1'b0; #1; if (y2 !== 1'b0) begin $display("Failed tran with ctl = 0, in = 0, expected 1'b0, got %b", y2); pass = 1'b0; end if (y2b !== 1'b1) begin $display("Failed y2b with ctl = 0, in = 0, expected 1'b1, got %b", y2b); pass = 1'b0; end // The tran gate is open so y2 should go high (pullup). ctl = 1'b1; #1; if (ctlb !== 1'b0) begin $display("Failed ctlb with ctl = 1, expected 1'b0, got %b", ctlb); pass = 1'b0; end if (y2 !== 1'b1) begin $display("Failed tran with ctl = 1, expected 1'b1, got %b", y2); pass = 1'b0; end if (y2b !== 1'b0) begin $display("Failed y2b with ctl = 1, expected 1'b0, got %b", y2b); pass = 1'b0; end // Now try driving y2 from in2. ctl2 = 1'b1; in2 = 1'b1; #1; if (y2 !== 1'b1) begin $display("Failed tran with ctl2 = 1, in2 = 1, expected 1'b1, got %b", y2); pass = 1'b0; end if (y2b !== 1'b0) begin $display("Failed y2b with ctl2 = 1, in2 = 1, expected 1'b0, got %b", y2b); pass = 1'b0; end in2 = 1'b0; #1; if (y2 !== 1'b0) begin $display("Failed tran with ctl2 = 1, in2 = 0, expected 1'b0, got %b", y2); pass = 1'b0; end if (y2b !== 1'b1) begin $display("Failed y2b with ctl2 = 1, in2 = 0, expected 1'b1, got %b", y2b); pass = 1'b0; end // Now back to just a pullup on y2. ctl2 = 1'b0; #1; if (y2 !== 1'b1) begin $display("Failed tran with ctl2 = 0, expected 1'b1, got %b", y2); pass = 1'b0; end if (y2b !== 1'b0) begin $display("Failed y2b with ctl2 = 0, expected 1'b0, got %b", y2b); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2834340.v000066400000000000000000000017101435245347300201210ustar00rootroot00000000000000//`timescale 1ns/1ps module test; reg c1reg,c2reg; pulldown (weak0) pd1 (r1a,r1c,r1o); pulldown (weak0) pd2 (r2a,r2c,r2o); pulldown pd (r1a); pullup pu (r2a); wire c1 = c1reg; wire c2 = c2reg; SPDT_RELAY r1 (.COIL1(c1), .COIL2(c2), .ARM(r1a), .NC(r1c), .NO(r1o)); SPDT_RELAY r2 (.COIL1(c1), .COIL2(c2), .ARM(r2a), .NC(r2c), .NO(r2o)); initial begin c1reg = 0; c2reg = 0; repeat (16) begin c1reg = 1; #10; c1reg = 0; #10; end $display ("%t: Test passed.",$realtime); $display ("PASSED"); $finish; end endmodule module SPDT_RELAY (COIL1, COIL2, ARM, NC, NO); inout COIL1, COIL2, ARM, NC, NO; wire coil = ((COIL1===1'b1) && (COIL2===1'b0)) || ((COIL1===1'b0) && (COIL2===1'b1)); wire #1 dly_coil = coil; wire coil_on = coil & dly_coil; wire coil_off = !coil & !dly_coil; //assign NC = (coil_off) ? ARM : 1'bz; //assign NO = (coil_on) ? ARM : 1'bz; tranif1 t1 (ARM,NC,coil_off); tranif1 t2 (ARM,NO,coil_on); endmodule iverilog-12_0/ivtest/ivltests/pr2834340b.v000066400000000000000000000051541435245347300202710ustar00rootroot00000000000000`timescale 1ns/1ps module test; reg pass; reg c1reg,c2reg; wire rla, rlc, rlo; wire rha, rhc, rho; wire c1 = c1reg; wire c2 = c2reg; // Pull the pins opposite to the arm. pulldown pd1 (rla); pullup (weak1) pu1 (rlc,rlo); pulldown (weak0) pd2 (rhc,rho); pullup pu2 (rha); SPDT_RELAY rl (.COIL1(c1), .COIL2(c2), .ARM(rla), .NC(rlc), .NO(rlo)); SPDT_RELAY rh (.COIL1(c1), .COIL2(c2), .ARM(rha), .NC(rhc), .NO(rho)); initial begin pass = 1'b1; // Test both coil terminals low. c1reg = 0; c2reg = 0; #10; if (rla !== 1'b0 || rlo !== 1'b1 || rlc !== 1'b0) begin $display("Failed R1 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rla, rlc, rlo); pass = 1'b0; end if (rha !== 1'b1 || rho !== 1'b0 || rhc !== 1'b1) begin $display("Failed R2 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rha, rhc, rho); pass = 1'b0; end // Test c1 low and c2 high. c2reg = 1; #10; if (rla !== 1'b0 || rlo !== 1'b0 || rlc !== 1'b1) begin $display("Failed R1 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rla, rlc, rlo); pass = 1'b0; end if (rha !== 1'b1 || rho !== 1'b1 || rhc !== 1'b0) begin $display("Failed R2 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rha, rhc, rho); pass = 1'b0; end // Test both coil terminal high. c1reg = 1; #10; if (rla !== 1'b0 || rlo !== 1'b1 || rlc !== 1'b0) begin $display("Failed R1 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rla, rlc, rlo); pass = 1'b0; end if (rha !== 1'b1 || rho !== 1'b0 || rhc !== 1'b1) begin $display("Failed R2 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rha, rhc, rho); pass = 1'b0; end // Test c1 high and c2 low. c2reg = 0; #10; if (rla !== 1'b0 || rlo !== 1'b0 || rlc !== 1'b1) begin $display("Failed R1 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rla, rlc, rlo); pass = 1'b0; end if (rha !== 1'b1 || rho !== 1'b1 || rhc !== 1'b0) begin $display("Failed R2 coil (%b-%b), arm=%b, NC=%b, NO=%b", c1, c2, rha, rhc, rho); pass = 1'b0; end if (pass) $display ("PASSED"); $finish; end endmodule module SPDT_RELAY (COIL1, COIL2, ARM, NC, NO); inout COIL1, COIL2, ARM, NC, NO; wire coil = ((COIL1===1'b1) && (COIL2===1'b0)) || ((COIL1===1'b0) && (COIL2===1'b1)); wire #1 dly_coil = coil; wire coil_on = coil & dly_coil; wire coil_off = !coil & !dly_coil; tranif1 t1 (ARM,NC,coil_off); tranif1 t2 (ARM,NO,coil_on); endmodule iverilog-12_0/ivtest/ivltests/pr2835632a.v000066400000000000000000000767131435245347300203060ustar00rootroot00000000000000// This checks various constant selects using the indexed select operators // +: and -: for both big and little endian vectors. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; parameter base = -1; parameter [base+15:base] p_big = 16'h0123; parameter [base:base+15] p_ltl = 16'h3210; parameter p_base = 16'h0123; reg [base+15:base] big = 16'h0123; reg [base:base+15] ltl = 16'h3210; reg [base+15:base] big_l; reg [base:base+15] ltl_l; wire [base+15:base] w_big = 16'h0123; wire [base:base+15] w_ltl = 16'h3210; reg [3:0] big0, big1, big2, big3, ltl0, ltl1, ltl2, ltl3; reg [3:0] big0a, big3a, bigx, bigo, ltl0a, ltl3a, ltlx, ltlo; reg pass; /* * Check a constant +: as a CA R-value. */ `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcu_big3a = w_big[(base-1)+:4]; `else wire [3:0] wcu_big3a = {w_big[(base)+:3],1'bx}; `endif wire [3:0] wcu_big3 = w_big[(base)+:4]; wire [3:0] wcu_big2 = w_big[(base+4)+:4]; wire [3:0] wcu_big1 = w_big[(base+8)+:4]; wire [3:0] wcu_big0 = w_big[(base+12)+:4]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcu_big0a = w_big[(base+13)+:4]; wire [3:0] wcu_bigx = w_big[(1'bx)+:4]; wire [3:0] wcu_ltl3a = w_ltl[(base-1)+:4]; `else wire [3:0] wcu_big0a = {1'bx,w_big[(base+13)+:3]}; wire [3:0] wcu_bigx = 4'bxxxx; wire [3:0] wcu_ltl3a = {1'bx,w_ltl[(base)+:3]}; `endif wire [3:0] wcu_ltl3 = w_ltl[(base)+:4]; wire [3:0] wcu_ltl2 = w_ltl[(base+4)+:4]; wire [3:0] wcu_ltl1 = w_ltl[(base+8)+:4]; wire [3:0] wcu_ltl0 = w_ltl[(base+12)+:4]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcu_ltl0a = w_ltl[(base+13)+:4]; wire [3:0] wcu_ltlx = w_ltl[(1'bx)+:4]; `else wire [3:0] wcu_ltl0a = {w_ltl[(base+13)+:3],1'bx}; wire [3:0] wcu_ltlx = 4'bxxxx; `endif /* * Check a constant -: as a CA R-value. */ `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcd_big3a = w_big[(base+2)-:4]; `else wire [3:0] wcd_big3a = {w_big[(base+2)-:3],1'bx}; `endif wire [3:0] wcd_big3 = w_big[(base+3)-:4]; wire [3:0] wcd_big2 = w_big[(base+7)-:4]; wire [3:0] wcd_big1 = w_big[(base+11)-:4]; wire [3:0] wcd_big0 = w_big[(base+15)-:4]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcd_big0a = w_big[(base+16)-:4]; wire [3:0] wcd_bigx = w_big[(1'bx)-:4]; wire [3:0] wcd_ltl3a = w_ltl[(base+2)-:4]; `else wire [3:0] wcd_big0a = {1'bx,w_big[(base+15)-:3]}; wire [3:0] wcd_bigx = 4'bxxxx; wire [3:0] wcd_ltl3a = {1'bx,w_ltl[(base+2)-:3]}; `endif wire [3:0] wcd_ltl3 = w_ltl[(base+3)-:4]; wire [3:0] wcd_ltl2 = w_ltl[(base+7)-:4]; wire [3:0] wcd_ltl1 = w_ltl[(base+11)-:4]; wire [3:0] wcd_ltl0 = w_ltl[(base+15)-:4]; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST wire [3:0] wcd_ltl0a = w_ltl[(base+16)-:4]; wire [3:0] wcd_ltlx = w_ltl[(1'bx)-:4]; `else wire [3:0] wcd_ltl0a = {w_ltl[(base+15)-:3],1'bx}; wire [3:0] wcd_ltlx = 4'bxxxx; `endif /* * Check a constant +: as a CA L-value. */ wire [base+15:base] wcu_big_l; wire [base:base+15] wcu_ltl_l; assign wcu_big_l[(base)+:4] = 4'd3; assign wcu_big_l[(base+4)+:4] = 4'd2; assign wcu_big_l[(base+8)+:4] = 4'd1; assign wcu_big_l[(base+12)+:4] = 4'd0; assign wcu_ltl_l[(base)+:4] = 4'd3; assign wcu_ltl_l[(base+4)+:4] = 4'd2; assign wcu_ltl_l[(base+8)+:4] = 4'd1; assign wcu_ltl_l[(base+12)+:4] = 4'd0; /* * Check a constant -: as a CA L-value. */ wire [base+15:base] wcd_big_l; wire [base:base+15] wcd_ltl_l; assign wcd_big_l[(base+3)-:4] = 4'd3; assign wcd_big_l[(base+7)-:4] = 4'd2; assign wcd_big_l[(base+11)-:4] = 4'd1; assign wcd_big_l[(base+15)-:4] = 4'd0; assign wcd_ltl_l[(base+3)-:4] = 4'd3; assign wcd_ltl_l[(base+7)-:4] = 4'd2; assign wcd_ltl_l[(base+11)-:4] = 4'd1; assign wcd_ltl_l[(base+15)-:4] = 4'd0; /* * Check a constant +: and -: with a 'bx index as a CA L-value. */ wire [base+15:base] wcu_big_lx; wire [base:base+15] wcu_ltl_lx; wire [base+15:base] wcd_big_lx; wire [base:base+15] wcd_ltl_lx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign wcu_big_lx[(1'bx)+:4] = 4'hf; assign wcu_ltl_lx[(1'bx)+:4] = 4'hf; assign wcd_big_lx[(1'bx)-:4] = 4'hf; assign wcd_ltl_lx[(1'bx)-:4] = 4'hf; `endif /* * Check a constant +: and -: with out of bounds values as a CA L-value. */ wire [base+15:base] wcu_big_lo; wire [base:base+15] wcu_ltl_lo; wire [base+15:base] wcd_big_lo; wire [base:base+15] wcd_ltl_lo; // For now Icarus does not support before base selects in a CA L-value. // This test needs to be updated when this is added. // assign wcu_big_lo[(base-1)+:4] = 4'b011x; assign wcu_big_lo[(base)+:3] = 3'b011; assign wcu_big_lo[(base+3)+:10] = 10'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign wcu_big_lo[(base+13)+:4] = 4'bx001; assign wcu_ltl_lo[(base-1)+:4] = 4'bx001; `else assign wcu_big_lo[(base+13)+:3] = 3'b001; assign wcu_ltl_lo[(base)+:3] = 3'b001; `endif assign wcu_ltl_lo[(base+3)+:10] = 10'b0; assign wcu_ltl_lo[(base+13)+:3] = 3'b011; // assign wcu_ltl_lo[(base+13)+:4] = 4'b011x; // assign wcd_big_lo[(base+2)-:4] = 4'b011x; assign wcd_big_lo[(base+2)-:3] = 3'b011; assign wcd_big_lo[(base+12)-:10] = 10'b0; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign wcd_big_lo[(base+16)-:4] = 4'bx001; assign wcd_ltl_lo[(base+2)-:4] = 4'bx001; `else assign wcd_big_lo[(base+15)-:3] = 3'b001; assign wcd_ltl_lo[(base+2)-:3] = 3'b001; `endif assign wcd_ltl_lo[(base+12)-:10] = 10'b0; assign wcd_ltl_lo[(base+15)-:3] = 3'b011; // assign wcd_ltl_lo[(base+16)-:4] = 4'b011x; initial begin pass = 1'b1; #1; $displayh("p_big/big: %h, p_ltl/ltl: %h, base: %0d", p_big, p_ltl, base); /* * Check a constant +: on a parameter. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_big[%0d+:4]: ", base-1, p_big[(base-1)+:4], ", p_ltl[%0d+:4]: ", base-1, p_ltl[(base-1)+:4]); `else $displayb("p_big[%0d+:4]: ", base-1, {p_big[(base)+:3],1'bx}, ", p_ltl[%0d+:4]: ", base-1, {1'bx,p_ltl[(base)+:3]}); `endif $displayh("p_big[%0d+:4]: ", base, p_big[(base)+:4], ", p_ltl[%0d+:4]: ", base, p_ltl[(base)+:4]); $displayh("p_big[%0d+:4]: ", base+4, p_big[(base+4)+:4], ", p_ltl[%0d+:4]: ", base+4, p_ltl[(base+4)+:4]); $displayh("p_big[%0d+:4]: ", base+8, p_big[(base+8)+:4], ", p_ltl[%0d+:4]: ", base+8, p_ltl[(base+8)+:4]); $displayh("p_big[%0d+:4]: ", base+12, p_big[(base+12)+:4], ", p_ltl[%0d+:4]: ", base+12, p_ltl[(base+12)+:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_big[%0d+:4]: ", base+13, p_big[(base+13)+:4], ", p_ltl[%0d+:4]: ", base+13, p_ltl[(base+13)+:4]); $displayb("p_big[%0d+:4]: ", 1'bx, p_big[(1'bx)+:4], ", p_ltl[%0d+:4]: ", 1'bx, p_ltl[(1'bx)+:4]); `else $displayb("p_big[%0d+:4]: ", base+13, {1'bx,p_big[(base+13)+:3]}, ", p_ltl[%0d+:4]: ", base+13, {p_ltl[(base+13)+:3],1'bx}); $displayb("p_big[%0d+:4]: ", 1'bx, 4'bxxxx, ", p_ltl[%0d+:4]: ", 1'bx, 4'bxxxx); `endif if (p_big[ (base) +: 4] !== 4'd3 || p_big[ (base+4) +: 4] !== 4'd2 || p_big[(base+8) +: 4] !== 4'd1 || p_big[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_big[ (base-1) +: 4] !== 4'b011x || p_big[(base+13) +: 4] !== 4'bx000 || p_big[(1'bx) +: 4] !== 4'bxxxx) begin `else {p_big[ (base) +: 3],1'bx} !== 4'b011x || {1'bx,p_big[(base+13) +: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian parameter constant +: indexed select."); pass = 1'b0; end if (p_ltl[ (base) +: 4] !== 4'd3 || p_ltl[ (base+4) +: 4] !== 4'd2 || p_ltl[(base+8) +: 4] !== 4'd1 || p_ltl[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_ltl[ (base-1) +: 4] !== 4'bx001 || p_ltl[(base+13) +: 4] !== 4'b000x || p_ltl[(1'bx) +: 4] !== 4'bxxxx) begin `else {1'bx,p_ltl[ (base) +: 3]} !== 4'bx001 || {p_ltl[(base+13) +: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian parameter constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a parameter. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_big[%0d-:4]: ", base+2, p_big[(base+2)-:4], ", p_ltl[%0d-:4]: ", base+2, p_ltl[(base+2)-:4]); `else $displayb("p_big[%0d-:4]: ", base+2, {p_big[(base+2)-:3],1'bx}, ", p_ltl[%0d-:4]: ", base+2, {1'bx,p_ltl[(base+2)-:3]}); `endif $displayh("p_big[%0d-:4]: ", base+3, p_big[(base+3)-:4], ", p_ltl[%0d-:4]: ", base+3, p_ltl[(base+3)-:4]); $displayh("p_big[%0d-:4]: ", base+7, p_big[(base+7)-:4], ", p_ltl[%0d-:4]: ", base+7, p_ltl[(base+7)-:4]); $displayh("p_big[%0d-:4]: ", base+11, p_big[(base+11)-:4], ", p_ltl[%0d-:4]: ", base+11, p_ltl[(base+11)-:4]); $displayh("p_big[%0d-:4]: ", base+15, p_big[(base+15)-:4], ", p_ltl[%0d-:4]: ", base+15, p_ltl[(base+15)-:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_big[%0d-:4]: ", base+16, p_big[(base+16)-:4], ", p_ltl[%0d-:4]: ", base+16, p_ltl[(base+16)-:4]); $displayb("p_big[%0d-:4]: ", 1'bx, p_big[(1'bx)-:4], ", p_ltl[%0d-:4]: ", 1'bx, p_ltl[(1'bx)-:4]); `else $displayb("p_big[%0d-:4]: ", base+16, {1'bx,p_big[(base+15)-:3]}, ", p_ltl[%0d-:4]: ", base+16, {p_ltl[(base+15)-:3],1'bx}); $displayb("p_big[%0d-:4]: ", 1'bx, 4'bxxxx, ", p_ltl[%0d-:4]: ", 1'bx, 4'bxxxx); `endif if (p_big[ (base+3) -: 4] !== 4'd3 || p_big[ (base+7) -: 4] !== 4'd2 || p_big[(base+11) -: 4] !== 4'd1 || p_big[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_big[ (base+2) -: 4] !== 4'b011x || p_big[(base+16) -: 4] !== 4'bx000 || p_big[(1'bx) -: 4] !== 4'bxxxx) begin `else {p_big[ (base+2) -: 3],1'bx} !== 4'b011x || {1'bx,p_big[(base+15) -: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian parameter constant -: indexed select."); pass = 1'b0; end if (p_ltl[ (base+3) -: 4] !== 4'd3 || p_ltl[ (base+7) -: 4] !== 4'd2 || p_ltl[(base+11) -: 4] !== 4'd1 || p_ltl[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_ltl[ (base+2) -: 4] !== 4'bx001 || p_ltl[(base+16) -: 4] !== 4'b000x || p_ltl[(1'bx) -: 4] !== 4'bxxxx) begin `else {1'bx,p_ltl[ (base+2) -: 3]} !== 4'bx001 || {p_ltl[(base+15) -: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian parameter constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a parameter with out a width specification. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_base[-1+:4]: ", p_base[-1+:4]); `else $displayb("p_base[-1+:4]: ", {p_base[0+:3],1'bx}); `endif $displayh("p_base[0+:4]: ", p_base[0+:4]); $displayh("p_base[4+:4]: ", p_base[4+:4]); $displayh("p_base[8+:4]: ", p_base[8+:4]); $displayh("p_base[12+:4]: ", p_base[12+:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_base[13+:4]: ", p_base[13+:4]); $displayb("p_base[x+:4]: ", p_base[(1'bx)+:4]); `else $displayb("p_base[13+:4]: ", {1'bx,p_base[13+:3]}); $displayb("p_base[x+:4]: ", 4'bxxxx); `endif if (p_base[ 0 +: 4] !== 4'd3 || p_base[ 4 +: 4] !== 4'd2 || p_base[ 8 +: 4] !== 4'd1 || p_base[12 +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_base[-1 +: 4] !== 4'b011x || p_base[13 +: 4] !== 4'bx000 || p_base[1'bx +: 4] !== 4'bxxxx) begin `else {p_base[0 +: 3],1'bx} !== 4'b011x || {1'bx,p_base[13 +: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: base parameter constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a parameter with out a width specification. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_base[2-:4]: ", p_base[2-:4]); `else $displayb("p_base[2-:4]: ", {p_base[2-:3],1'bx}); `endif $displayh("p_base[3-:4]: ", p_base[3-:4]); $displayh("p_base[7-:4]: ", p_base[7-:4]); $displayh("p_base[11-:4]: ", p_base[11-:4]); $displayh("p_base[15-:4]: ", p_base[15-:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("p_base[16-:4]: ", p_base[16-:4]); $displayb("p_base[x-:4]: ", p_base[(1'bx)-:4]); `else $displayb("p_base[16-:4]: ", {1'bx,p_base[15-:3]}); $displayb("p_base[x-:4]: ", 4'bxxxx); `endif if (p_base[ 3 -: 4] !== 4'd3 || p_base[ 7 -: 4] !== 4'd2 || p_base[11 -: 4] !== 4'd1 || p_base[15 -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST p_base[ 2 -: 4] !== 4'b011x || p_base[16 -: 4] !== 4'bx000 || p_base[(1'bx) -: 4] !== 4'bxxxx) begin `else {p_base[ 2 -: 3],1'bx} !== 4'b011x || {1'bx,p_base[15 -: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: base parameter constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a register. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("big[%0d+:4]: ", base-1, big[(base-1)+:4], ", ltl[%0d+:4]: ", base-1, ltl[(base-1)+:4]); `else $displayb("big[%0d+:4]: ", base-1, {big[(base)+:3],1'bx}, ", ltl[%0d+:4]: ", base-1, {1'bx,ltl[(base)+:3]}); `endif $displayh("big[%0d+:4]: ", base, big[(base)+:4], ", ltl[%0d+:4]: ", base, ltl[(base)+:4]); $displayh("big[%0d+:4]: ", base+4, big[(base+4)+:4], ", ltl[%0d+:4]: ", base+4, ltl[(base+4)+:4]); $displayh("big[%0d+:4]: ", base+8, big[(base+8)+:4], ", ltl[%0d+:4]: ", base+8, ltl[(base+8)+:4]); $displayh("big[%0d+:4]: ",base+12, big[(base+12)+:4], ", ltl[%0d+:4]: ",base+12, ltl[(base+12)+:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("big[%0d+:4]: ",base+13, big[(base+13)+:4], ", ltl[%0d+:4]: ",base+13, ltl[(base+13)+:4]); $displayb("big[%0d+:4]: ",1'bx, big[(1'bx)+:4], ", ltl[%0d+:4]: ",1'bx, ltl[(1'bx)+:4]); `else $displayb("big[%0d+:4]: ",base+13, {1'bx,big[(base+13)+:3]}, ", ltl[%0d+:4]: ",base+13, {ltl[(base+13)+:3],1'bx}); $displayb("big[%0d+:4]: ",1'bx, 4'bxxxx, ", ltl[%0d+:4]: ",1'bx, 4'bxxxx); `endif if (big[ (base) +: 4] !== 4'd3 || big[ (base+4) +: 4] !== 4'd2 || big[(base+8) +: 4] !== 4'd1 || big[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big[ (base-1) +: 4] !== 4'b011x || big[(base+13) +: 4] !== 4'bx000 || big[(1'bx) +: 4] !== 4'bxxxx) begin `else {big[ (base) +: 3],1'bx} !== 4'b011x || {1'bx,big[(base+13) +: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian register constant +: indexed select."); pass = 1'b0; end if (ltl[ (base) +: 4] !== 4'd3 || ltl[ (base+4) +: 4] !== 4'd2 || ltl[(base+8) +: 4] !== 4'd1 || ltl[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST ltl[ (base-1) +: 4] !== 4'bx001 || ltl[(base+13) +: 4] !== 4'b000x || ltl[(1'bx) +: 4] !== 4'bxxxx) begin `else {1'bx,ltl[ (base) +: 3]} !== 4'bx001 || {ltl[(base+13) +: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian register constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a register. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("big[%0d-:4]: ", base+2, big[(base+2)-:4], ", ltl[%0d-:4]: ", base+2, ltl[(base+2)-:4]); `else $displayb("big[%0d-:4]: ", base+2, {big[(base+2)-:3],1'bx}, ", ltl[%0d-:4]: ", base+2, {1'bx,ltl[(base+2)-:3]}); `endif $displayh("big[%0d-:4]: ", base+3, big[(base+3)-:4], ", ltl[%0d-:4]: ", base+3, ltl[(base+3)-:4]); $displayh("big[%0d-:4]: ", base+7, big[(base+7)-:4], ", ltl[%0d-:4]: ", base+7, ltl[(base+7)-:4]); $displayh("big[%0d-:4]: ", base+11, big[(base+11)-:4], ", ltl[%0d-:4]: ", base+11, ltl[(base+11)-:4]); $displayh("big[%0d-:4]: ", base+15, big[(base+15)-:4], ", ltl[%0d-:4]: ", base+15, ltl[(base+15)-:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("big[%0d-:4]: ", base+16, big[(base+16)-:4], ", ltl[%0d-:4]: ", base+16, ltl[(base+16)-:4]); $displayb("big[%0d-:4]: ", 1'bx, big[(1'bx)-:4], ", ltl[%0d-:4]: ", 1'bx, ltl[(1'bx)-:4]); `else $displayb("big[%0d-:4]: ", base+16, {1'bx,big[(base+15)-:3]}, ", ltl[%0d-:4]: ", base+16, {ltl[(base+15)-:3],1'bx}); $displayb("big[%0d-:4]: ", 1'bx, 4'bxxxx, ", ltl[%0d-:4]: ", 1'bx, 4'bxxxx); `endif if (big[ (base+3) -: 4] !== 4'd3 || big[ (base+7) -: 4] !== 4'd2 || big[(base+11) -: 4] !== 4'd1 || big[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big[ (base+2) -: 4] !== 4'b011x || big[(base+16) -: 4] !== 4'bx000 || big[(1'bx) -: 4] !== 4'bxxxx) begin `else {big[ (base+2) -: 3],1'bx} !== 4'b011x || {1'bx,big[(base+15) -: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian register constant -: indexed select."); pass = 1'b0; end if (ltl[ (base+3) -: 4] !== 4'd3 || ltl[ (base+7) -: 4] !== 4'd2 || ltl[(base+11) -: 4] !== 4'd1 || ltl[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST ltl[ (base+2) -: 4] !== 4'bx001 || ltl[(base+16) -: 4] !== 4'b000x || ltl[(1'bx) -: 4] !== 4'bxxxx) begin `else {1'bx,ltl[ (base+2) -: 3]} !== 4'bx001 || {ltl[(base+15) -: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian register constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a wire. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("w_big[%0d+:4]: ", base-1, w_big[(base-1)+:4], ", w_ltl[%0d+:4]: ", base-1, w_ltl[(base-1)+:4]); `else $displayb("w_big[%0d+:4]: ", base-1, {w_big[(base)+:3],1'bx}, ", w_ltl[%0d+:4]: ", base-1, {1'bx,w_ltl[(base)+:3]}); `endif $displayh("w_big[%0d+:4]: ", base, w_big[(base)+:4], ", w_ltl[%0d+:4]: ", base, w_ltl[(base)+:4]); $displayh("w_big[%0d+:4]: ", base+4, w_big[(base+4)+:4], ", w_ltl[%0d+:4]: ", base+4, w_ltl[(base+4)+:4]); $displayh("w_big[%0d+:4]: ", base+8, w_big[(base+8)+:4], ", w_ltl[%0d+:4]: ", base+8, w_ltl[(base+8)+:4]); $displayh("w_big[%0d+:4]: ", base+12, w_big[(base+12)+:4], ", w_ltl[%0d+:4]: ", base+12, w_ltl[(base+12)+:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("w_big[%0d+:4]: ", base+13, w_big[(base+13)+:4], ", w_ltl[%0d+:4]: ", base+13, w_ltl[(base+13)+:4]); $displayb("w_big[%0d+:4]: ", 1'bx, w_big[(1'bx)+:4], ", w_ltl[%0d+:4]: ", 1'bx, w_ltl[(1'bx)+:4]); `else $displayb("w_big[%0d+:4]: ", base+13, {1'bx,w_big[(base+13)+:3]}, ", w_ltl[%0d+:4]: ", base+13, {w_ltl[(base+13)+:3],1'bx}); $displayb("w_big[%0d+:4]: ", 1'bx, 4'bxxxx, ", w_ltl[%0d+:4]: ", 1'bx, 4'bxxxx); `endif if (w_big[ (base) +: 4] !== 4'd3 || w_big[ (base+4) +: 4] !== 4'd2 || w_big[(base+8) +: 4] !== 4'd1 || w_big[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST w_big[ (base-1) +: 4] !== 4'b011x || w_big[(base+13) +: 4] !== 4'bx000 || w_big[(1'bx) +: 4] !== 4'bxxxx) begin `else {w_big[ (base) +: 3],1'bx} !== 4'b011x || {1'bx,w_big[(base+13) +: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian wire constant +: indexed select."); pass = 1'b0; end if (w_ltl[ (base) +: 4] !== 4'd3 || w_ltl[ (base+4) +: 4] !== 4'd2 || w_ltl[(base+8) +: 4] !== 4'd1 || w_ltl[(base+12) +: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST w_ltl[ (base-1) +: 4] !== 4'bx001 || w_ltl[(base+13) +: 4] !== 4'b000x || w_ltl[(1'bx) +: 4] !== 4'bxxxx) begin `else {1'bx,w_ltl[ (base) +: 3]} !== 4'bx001 || {w_ltl[(base+13) +: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian wire constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a wire. */ $display(); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("w_big[%0d-:4]: ", base+2, w_big[(base+2)-:4], ", w_ltl[%0d-:4]: ", base+2, w_ltl[(base+2)-:4]); `else $displayb("w_big[%0d-:4]: ", base+2, {w_big[(base+2)-:3],1'bx}, ", w_ltl[%0d-:4]: ", base+2, {1'bx,w_ltl[(base+2)-:3]}); `endif $displayh("w_big[%0d-:4]: ", base+3, w_big[(base+3)-:4], ", w_ltl[%0d-:4]: ", base+3, w_ltl[(base+3)-:4]); $displayh("w_big[%0d-:4]: ", base+7, w_big[(base+7)-:4], ", w_ltl[%0d-:4]: ", base+7, w_ltl[(base+7)-:4]); $displayh("w_big[%0d-:4]: ", base+11, w_big[(base+11)-:4], ", w_ltl[%0d-:4]: ", base+11, w_ltl[(base+11)-:4]); $displayh("w_big[%0d-:4]: ", base+15, w_big[(base+15)-:4], ", w_ltl[%0d-:4]: ", base+15, w_ltl[(base+15)-:4]); `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $displayb("w_big[%0d-:4]: ", base+16, w_big[(base+16)-:4], ", w_ltl[%0d-:4]: ", base+16, w_ltl[(base+16)-:4]); $displayb("w_big[%0d-:4]: ", 1'bx, w_big[(1'bx)-:4], ", w_ltl[%0d-:4]: ", 1'bx, w_ltl[(1'bx)-:4]); `else $displayb("w_big[%0d-:4]: ", base+16, {1'bx,w_big[(base+15)-:3]}, ", w_ltl[%0d-:4]: ", base+16, {w_ltl[(base+15)-:3],1'bx}); $displayb("w_big[%0d-:4]: ", 1'bx, 4'bxxxx, ", w_ltl[%0d-:4]: ", 1'bx, 4'bxxxx); `endif if (w_big[ (base+3) -: 4] !== 4'd3 || w_big[ (base+7) -: 4] !== 4'd2 || w_big[(base+11) -: 4] !== 4'd1 || w_big[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST w_big[ (base+2) -: 4] !== 4'b011x || w_big[(base+16) -: 4] !== 4'bx000 || w_big[(1'bx) -: 4] !== 4'bxxxx) begin `else {w_big[ (base+2) -: 3],1'bx} !== 4'b011x || {1'bx,w_big[(base+15) -: 3]} !== 4'bx000 || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: big endian wire constant -: indexed select."); pass = 1'b0; end if (w_ltl[ (base+3) -: 4] !== 4'd3 || w_ltl[ (base+7) -: 4] !== 4'd2 || w_ltl[(base+11) -: 4] !== 4'd1 || w_ltl[(base+15) -: 4] !== 4'd0 || `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST w_ltl[ (base+2) -: 4] !== 4'bx001 || w_ltl[(base+16) -: 4] !== 4'b000x || w_ltl[(1'bx) -: 4] !== 4'bxxxx) begin `else {1'bx,w_ltl[ (base+2) -: 3]} !== 4'bx001 || {w_ltl[(base+15) -: 3],1'bx} !== 4'b000x || 4'bxxxx !== 4'bxxxx) begin `endif $display("FAILED: little endian wire constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a CA R-value. */ $display(); $displayb("wcu_big3a: ", wcu_big3a, ", wcu_ltl3a: ", wcu_ltl3a); $displayh("wcu_big3: ", wcu_big3, ", wcu_ltl3: ", wcu_ltl3); $displayh("wcu_big2: ", wcu_big2, ", wcu_ltl2: ", wcu_ltl2); $displayh("wcu_big1: ", wcu_big1, ", wcu_ltl1: ", wcu_ltl1); $displayh("wcu_big0: ", wcu_big0, ", wcu_ltl0: ", wcu_ltl0); $displayb("wcu_big0a: ", wcu_big0a, ", wcu_ltl0a: ", wcu_ltl0a); $displayb("wcu_bigx: ", wcu_bigx, ", wcu_ltlx: ", wcu_ltlx); if (wcu_big3 !== 4'd3 || wcu_big2 !== 4'd2 || wcu_big1 !== 4'd1 || wcu_big0 !== 4'd0 || wcu_big3a !== 4'b011x || wcu_big0a !== 4'bx000 || wcu_bigx !== 4'bxxxx) begin $display("FAILED: big endian CA R-value constant +: indexed select."); pass = 1'b0; end if (wcu_ltl3 !== 4'd3 || wcu_ltl2 !== 4'd2 || wcu_ltl1 !== 4'd1 || wcu_ltl0 !== 4'd0 || wcu_ltl3a !== 4'bx001 || wcu_ltl0a !== 4'b000x || wcu_ltlx !== 4'bxxxx) begin $display("FAILED: little endian CA R-value constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a CA R-value. */ $display(); $displayb("wcd_big3a: ", wcd_big3a, ", wcd_ltl3a: ", wcd_ltl3a); $displayh("wcd_big3: ", wcd_big3, ", wcd_ltl3: ", wcd_ltl3); $displayh("wcd_big2: ", wcd_big2, ", wcd_ltl2: ", wcd_ltl2); $displayh("wcd_big1: ", wcd_big1, ", wcd_ltl1: ", wcd_ltl1); $displayh("wcd_big0: ", wcd_big0, ", wcd_ltl0: ", wcd_ltl0); $displayb("wcd_big0a: ", wcd_big0a, ", wcd_ltl0a: ", wcd_ltl0a); $displayb("wcd_bigx: ", wcd_bigx, ", wcd_ltlx: ", wcd_ltlx); if (wcd_big3 !== 4'd3 || wcd_big2 !== 4'd2 || wcd_big1 !== 4'd1 || wcd_big0 !== 4'd0 || wcd_big3a !== 4'b011x || wcd_big0a !== 4'bx000 || wcd_bigx !== 4'bxxxx) begin $display("FAILED: big endian CA R-value constant -: indexed select."); pass = 1'b0; end if (wcd_ltl3 !== 4'd3 || wcd_ltl2 !== 4'd2 || wcd_ltl1 !== 4'd1 || wcd_ltl0 !== 4'd0 || wcd_ltl3a !== 4'bx001 || wcd_ltl0a !== 4'b000x || wcd_ltlx !== 4'bxxxx) begin $display("FAILED: little endian CA R-value constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a simple L-value. */ $display(); big_l = 16'hxxxx; ltl_l = 16'hxxxx; big_l[(base)+:4] = 4'd3; ltl_l[(base)+:4] = 4'd3; big_l[(base+4)+:4] = 4'd2; ltl_l[(base+4)+:4] = 4'd2; big_l[(base+8)+:4] = 4'd1; ltl_l[(base+8)+:4] = 4'd1; big_l[(base+12)+:4] = 4'd0; ltl_l[(base+12)+:4] = 4'd0; $displayh("big_l[simple]: ", big_l, ", ltl_l[simple]: ", ltl_l); if (big_l !== big) begin $display("FAILED: big endian simple L-value constant +: indexed select."); pass = 1'b0; end if (ltl_l !== ltl) begin $display("FAILED: little endian simple L-value constant +: indexed select."); pass = 1'b0; end big_l = 16'hxxxx; ltl_l = 16'hxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big_l[(1'bx)+:4] = 4'd0; ltl_l[(1'bx)+:4] = 4'd0; `endif $displayh("big_l[1'bx]: ", big_l, ", ltl_l[1'bx]: ", ltl_l); if (big_l !== 16'hxxxx) begin $display("FAILED: big endian L-value constant 'bx index +: indexed select."); pass = 1'b0; end if (ltl_l !== 16'hxxxx) begin $display("FAILED: little endian L-value constant 'bx index +: indexed select."); pass = 1'b0; end big_l = 16'h0000; ltl_l = 16'h0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big_l[(base-1)+:4] = 4'b011x; ltl_l[(base-1)+:4] = 4'bx001; big_l[(base+13)+:4] = 4'bx001; ltl_l[(base+13)+:4] = 4'b011x; `else big_l[(base)+:3] = 3'b011; ltl_l[(base)+:3] = 3'b001; big_l[(base+13)+:3] = 3'b001; ltl_l[(base+13)+:3] = 3'b011; `endif $displayh("big_l[edge]: ", big_l, ", ltl_l[edge]: ", ltl_l); if (big_l !== 16'h2003) begin $display("FAILED: big endian edge L-value constant +: indexed select."); pass = 1'b0; end if (ltl_l !== 16'h2003) begin $display("FAILED: little endian edge L-value constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a simple L-value. */ $display(); big_l = 16'hxxxx; ltl_l = 16'hxxxx; big_l[(base+3)-:4] = 4'd3; ltl_l[(base+3)-:4] = 4'd3; big_l[(base+7)-:4] = 4'd2; ltl_l[(base+7)-:4] = 4'd2; big_l[(base+11)-:4] = 4'd1; ltl_l[(base+11)-:4] = 4'd1; big_l[(base+15)-:4] = 4'd0; ltl_l[(base+15)-:4] = 4'd0; $displayh("big_l: ", big_l, ", ltl_l: ", ltl_l); if (big_l !== big) begin $display("FAILED: big endian simple L-value constant -: indexed select."); pass = 1'b0; end if (ltl_l !== ltl) begin $display("FAILED: little endian simple L-value constant -: indexed select."); pass = 1'b0; end big_l = 16'hxxxx; ltl_l = 16'hxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big_l[(1'bx)-:4] = 4'd0; ltl_l[(1'bx)-:4] = 4'd0; `endif $displayh("big_l[1'bx]: ", big_l, ", ltl_l[1'bx]: ", ltl_l); if (big_l !== 16'hxxxx) begin $display("FAILED: big endian L-value constant 'bx index -: indexed select."); pass = 1'b0; end if (ltl_l !== 16'hxxxx) begin $display("FAILED: little endian L-value constant 'bx index -: indexed select."); pass = 1'b0; end big_l = 16'h0000; ltl_l = 16'h0000; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST big_l[(base+2)-:4] = 4'b011x; ltl_l[(base+2)-:4] = 4'bx001; big_l[(base+16)-:4] = 4'bx001; ltl_l[(base+16)-:4] = 4'b011x; `else big_l[(base+2)-:3] = 3'b011; ltl_l[(base+2)-:3] = 3'b001; big_l[(base+15)-:3] = 3'b001; ltl_l[(base+15)-:3] = 3'b011; `endif $displayh("big_l[edge]: ", big_l, ", ltl_l[edge]: ", ltl_l); if (big_l !== 16'h2003) begin $display("FAILED: big endian edge L-value constant -: indexed select."); pass = 1'b0; end if (ltl_l !== 16'h2003) begin $display("FAILED: little endian edge L-value constant -: indexed select."); pass = 1'b0; end /* * Check a constant +: on a CA L-value. */ $display(); $displayh("wcu_big_l: ", wcu_big_l, ", wcu_ltl_l: ", wcu_ltl_l); if (wcu_big_l !== big) begin $display("FAILED: big endian CA L-value constant +: indexed select."); pass = 1'b0; end if (wcu_ltl_l !== ltl) begin $display("FAILED: little endian CA L-value constant +: indexed select."); pass = 1'b0; end $displayh("wcu_big_lx: ", wcu_big_lx, ", wcu_ltl_lx: ", wcu_ltl_lx); if (wcu_big_lx !== 16'hzzzz) begin $display("FAILED: big endian CA L-value constant 'bx +: indexed select."); pass = 1'b0; end if (wcu_ltl_lx !== 16'hzzzz) begin $display("FAILED: little endian CA L-value constant 'bx +: indexed select."); pass = 1'b0; end $displayh("wcu_big_lo: ", wcu_big_lo, ", wcu_ltl_lo: ", wcu_ltl_lo); if (wcu_big_lo !== 16'h2003) begin $display("FAILED: big endian edge CA L-value constant +: indexed select."); pass = 1'b0; end if (wcu_ltl_lo !== 16'h2003) begin $display("FAILED: little endian edge CA L-value constant +: indexed select."); pass = 1'b0; end /* * Check a constant -: on a CA L-value. */ $display(); $displayh("wcd_big_l: ", wcd_big_l, ", wcd_ltl_l: ", wcd_ltl_l); if (wcd_big_l !== big) begin $display("FAILED: big endian CA L-value constant -: indexed select."); pass = 1'b0; end if (wcd_ltl_l !== ltl) begin $display("FAILED: little endian CA L-value constant -: indexed select."); pass = 1'b0; end $displayh("wcd_big_lx: ", wcd_big_lx, ", wcd_ltl_lx: ", wcd_ltl_lx); if (wcd_big_lx !== 16'hzzzz) begin $display("FAILED: big endian CA L-value constant 'bx -: indexed select."); pass = 1'b0; end if (wcd_ltl_lx !== 16'hzzzz) begin $display("FAILED: little endian CA L-value constant 'bx -: indexed select."); pass = 1'b0; end $displayh("wcd_big_lo: ", wcd_big_lo, ", wcd_ltl_lo: ", wcd_ltl_lo); if (wcd_big_lo !== 16'h2003) begin $display("FAILED: big endian edge CA L-value constant -: indexed select."); pass = 1'b0; end if (wcd_ltl_lo !== 16'h2003) begin $display("FAILED: little endian edge CA L-value constant -: indexed select."); pass = 1'b0; end /* * All done. */ if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2835632b.v000066400000000000000000000424231435245347300202760ustar00rootroot00000000000000// This checks various variable selects using the indexed select operators // +: and -: for both big and little endian vectors. module top; parameter base = -1; parameter [base+15:base] p_big = 16'h0123; parameter [base:base+15] p_ltl = 16'h3210; reg [base+15:base] big = 16'h0123; reg [base:base+15] ltl = 16'h3210; reg [base+15:base] bigr; reg [base:base+15] ltlr; wire [base+15:base] w_big = 16'h0123; wire [base:base+15] w_ltl = 16'h3210; integer a; reg [3:0] big0, big1, big2, big3, ltl0, ltl1, ltl2, ltl3; reg [3:0] big0a, big3a, bigx, ltl0a, ltl3a, ltlx; reg pass; /* * Check a variable +: as a CA R-value. */ wire [3:0] wvu_big = w_big[a+:4]; wire [3:0] wvu_ltl = w_ltl[a+:4]; /* * Check a variable -: as a CA R-value. */ wire [3:0] wvd_big = w_big[a-:4]; wire [3:0] wvd_ltl = w_ltl[a-:4]; initial begin pass = 1'b1; #1; $displayh("p_big/big: %h, p_ltl/ltl: %h, base: %0d", p_big, p_ltl, base); /* * Check a variable +: on a parameter. */ $display(); a = base-1; big3a = p_big[a+:4]; ltl3a = p_ltl[a+:4]; $displayb("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = base; big3 = p_big[a+:4]; ltl3 = p_ltl[a+:4]; $displayh("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = base+4; big2 = p_big[a+:4]; ltl2 = p_ltl[a+:4]; $displayh("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = base+8; big1 = p_big[a+:4]; ltl1 = p_ltl[a+:4]; $displayh("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = base+12; big0 = p_big[a+:4]; ltl0 = p_ltl[a+:4]; $displayh("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = base+13; big0a = p_big[a+:4]; ltl0a = p_ltl[a+:4]; $displayb("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); a = 1'bx; bigx = p_big[a+:4]; ltlx = p_ltl[a+:4]; $displayb("a==%0d; p_big[a+:4]: ", a, p_big[a+:4], ", p_ltl[a+:4]: ", p_ltl[a+:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian parameter variable +: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian parameter variable +: indexed select."); pass = 1'b0; end /* * Check a variable -: on a parameter. */ $display(); a = base+2; big3a = p_big[a-:4]; ltl3a = p_ltl[a-:4]; $displayb("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = base+3; big3 = p_big[a-:4]; ltl3 = p_ltl[a-:4]; $displayh("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = base+7; big2 = p_big[a-:4]; ltl2 = p_ltl[a-:4]; $displayh("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = base+11; big1 = p_big[a-:4]; ltl1 = p_ltl[a-:4]; $displayh("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = base+15; big0 = p_big[a-:4]; ltl0 = p_ltl[a-:4]; $displayh("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = base+16; big0a = p_big[a-:4]; ltl0a = p_ltl[a-:4]; $displayb("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); a = 1'bx; bigx = p_big[a-:4]; ltlx = p_ltl[a-:4]; $displayb("a== %0d; p_big[a-:4]: ", a, p_big[a-:4], ", p_ltl[a-:4]: ", p_ltl[a-:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian parameter variable -: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian parameter variable -: indexed select."); pass = 1'b0; end /* * Check a variable +: on a register. */ $display(); a = base-1; big3a = big[a+:4]; ltl3a = ltl[a+:4]; $displayb("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = base; big3 = big[a+:4]; ltl3 = ltl[a+:4]; $displayh("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = base+4; big2 = big[a+:4]; ltl2 = ltl[a+:4]; $displayh("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = base+8; big1 = big[a+:4]; ltl1 = ltl[a+:4]; $displayh("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = base+12; big0 = big[a+:4]; ltl0 = ltl[a+:4]; $displayh("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = base+13; big0a = big[a+:4]; ltl0a = ltl[a+:4]; $displayb("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); a = 1'bx; bigx = big[a+:4]; ltlx = ltl[a+:4]; $displayb("a==%0d; big[a+:4]: ", a, big[a+:4], ", ltl[a+:4]: ", ltl[a+:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian register variable +: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian register variable +: indexed select."); pass = 1'b0; end /* * Check a variable -: on a register. */ $display(); a = base+2; big3a = big[a-:4]; ltl3a = ltl[a-:4]; $displayb("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = base+3; big3 = big[a-:4]; ltl3 = ltl[a-:4]; $displayh("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = base+7; big2 = big[a-:4]; ltl2 = ltl[a-:4]; $displayh("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = base+11; big1 = big[a-:4]; ltl1 = ltl[a-:4]; $displayh("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = base+15; big0 = big[a-:4]; ltl0 = ltl[a-:4]; $displayh("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = base+16; big0a = big[a-:4]; ltl0a = ltl[a-:4]; $displayb("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); a = 1'bx; bigx = big[a-:4]; ltlx = ltl[a-:4]; $displayb("a== %0d; big[a-:4]: ", a, big[a-:4], ", ltl[a-:4]: ", ltl[a-:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian register variable -: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian register variable -: indexed select."); pass = 1'b0; end /* * Check a variable +: on a wire. */ $display(); a = base-1; big3a = w_big[a+:4]; ltl3a = w_ltl[a+:4]; $displayb("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = base; big3 = w_big[a+:4]; ltl3 = w_ltl[a+:4]; $displayh("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = base+4; big2 = w_big[a+:4]; ltl2 = w_ltl[a+:4]; $displayh("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = base+8; big1 = w_big[a+:4]; ltl1 = w_ltl[a+:4]; $displayh("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = base+12; big0 = w_big[a+:4]; ltl0 = w_ltl[a+:4]; $displayh("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = base+13; big0a = w_big[a+:4]; ltl0a = w_ltl[a+:4]; $displayb("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); a = 1'bx; bigx = w_big[a+:4]; ltlx = w_ltl[a+:4]; $displayb("a==%0d; w_big[a+:4]: ", a, w_big[a+:4], ", w_ltl[a+:4]: ", w_ltl[a+:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian wire variable +: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian wire variable +: indexed select."); pass = 1'b0; end /* * Check a variable -: on a wire. */ $display(); a = base+2; big3 = w_big[a-:4]; ltl3 = w_ltl[a-:4]; $displayb("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = base+3; big3 = w_big[a-:4]; ltl3 = w_ltl[a-:4]; $displayh("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = base+7; big2 = w_big[a-:4]; ltl2 = w_ltl[a-:4]; $displayh("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = base+11; big1 = w_big[a-:4]; ltl1 = w_ltl[a-:4]; $displayh("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = base+15; big0 = w_big[a-:4]; ltl0 = w_ltl[a-:4]; $displayh("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = base+16; big0a = w_big[a-:4]; ltl0a = w_ltl[a-:4]; $displayb("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); a = 1'bx; bigx = w_big[a-:4]; ltlx = w_ltl[a-:4]; $displayb("a== %0d; w_big[a-:4]: ", a, w_big[a-:4], ", w_ltl[a-:4]: ", w_ltl[a-:4]); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian wire variable -: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian wire variable -: indexed select."); pass = 1'b0; end /* * Check a variable +: on a CA R-value. */ $display(); a = base-1; #1; big3a = wvu_big; ltl3a = wvu_ltl; $displayb("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = base; #1; big3 = wvu_big; ltl3 = wvu_ltl; $displayh("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = base+4; #1; big2 = wvu_big; ltl2 = wvu_ltl; $displayh("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = base+8; #1; big1 = wvu_big; ltl1 = wvu_ltl; $displayh("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = base+12; #1; big0 = wvu_big; ltl0 = wvu_ltl; $displayh("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = base+13; #1; big0a = wvu_big; ltl0a = wvu_ltl; $displayb("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); a = 1'bx; #1; bigx = wvu_big; ltlx = wvu_ltl; $displayb("a==%0d; wvu_big: ", a, wvu_big, ", wvu_ltl: ", wvu_ltl); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian CA R-value variable +: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian CA R-value variable +: indexed select."); pass = 1'b0; end /* * Check a variable -: on a CA R-value. */ $display(); a = base+2; #1; big3a = wvd_big; ltl3a = wvd_ltl; $displayb("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = base+3; #1; big3 = wvd_big; ltl3 = wvd_ltl; $displayh("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = base+7; #1; big2 = wvd_big; ltl2 = wvd_ltl; $displayh("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = base+11; #1; big1 = wvd_big; ltl1 = wvd_ltl; $displayh("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = base+15; #1; big0 = wvd_big; ltl0 = wvd_ltl; $displayh("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = base+16; #1; big0a = wvd_big; ltl0a = wvd_ltl; $displayb("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); a = 1'bx; #1; bigx = wvd_big; ltlx = wvd_ltl; $displayb("a==%0d; wvd_big: ", a, wvd_big, ", wvd_ltl: ", wvd_ltl); if (big3 !== 4'd3 || big2 !== 4'd2 || big1 !== 4'd1 || big0 !== 4'd0 || big3a !== 4'b011x || big0a !== 4'bx000 || bigx !== 4'bxxxx) begin $display("FAILED: big endian CA R-value variable -: indexed select."); pass = 1'b0; end if (ltl3 !== 4'd3 || ltl2 !== 4'd2 || ltl1 !== 4'd1 || ltl0 !== 4'd0 || ltl3a !== 4'bx001 || ltl0a !== 4'b000x || ltlx !== 4'bxxxx) begin $display("FAILED: little endian CA R-value variable -: indexed select."); pass = 1'b0; end /* * Check a variable +: on a simple L-value. */ $display(); bigr = 16'hxxxx; ltlr = 16'hxxxx; a = base; bigr[(a)+:4] = 4'd3; ltlr[(a)+:4] = 4'd3; a = base+4; bigr[(a)+:4] = 4'd2; ltlr[(a)+:4] = 4'd2; a = base+8; bigr[(a)+:4] = 4'd1; ltlr[(a)+:4] = 4'd1; a = base+12; bigr[(a)+:4] = 4'd0; ltlr[(a)+:4] = 4'd0; $displayh("bigr[a+:4]: ", bigr, ", ltlr[a+:4]: ", ltlr); if (bigr !== big) begin $display("FAILED: big endian variable L-value +: indexed select."); pass = 1'b0; end if (ltlr !== ltl) begin $display("FAILED: little endian variable L-value +: indexed select."); pass = 1'b0; end bigr = 16'h0000; ltlr = 16'h0000; a = 'bx; bigr[(a)+:4] = 4'hf; ltlr[(a)+:4] = 4'hf; $displayh("bigr[a+='bx :4]: ", bigr, ", ltlr[a='bx +:4]: ", ltlr); if (bigr !== 16'h0000) begin $display("FAILED: big endian variable ('bx) L-value +: indexed select."); pass = 1'b0; end if (ltlr !== 16'h0000) begin $display("FAILED: little endian variable ('bx) L-value +: indexed select."); pass = 1'b0; end bigr = 16'h0000; ltlr = 16'h0000; a = base-1; bigr[(a)+:4] = 4'b011x; ltlr[(a)+:4] = 4'bx001; a = base+13; bigr[(a)+:4] = 4'bx001; ltlr[(a)+:4] = 4'b011x; $displayh("bigr[a=edge +:4]: ", bigr, ", ltlr[a=edge +:4]: ", ltlr); if (bigr !== 16'h2003) begin $display("FAILED: big endian edge L-value constant +: indexed select."); pass = 1'b0; end if (ltlr !== 16'h2003) begin $display("FAILED: little endian edge L-value constant +: indexed select."); pass = 1'b0; end /* * Check a variable -: on a simple L-value. */ $display(); bigr = 16'hxxxx; ltlr = 16'hxxxx; a = base+3; bigr[(a)-:4] = 4'd3; ltlr[(a)-:4] = 4'd3; a = base+7; bigr[(a)-:4] = 4'd2; ltlr[(a)-:4] = 4'd2; a = base+11; bigr[(a)-:4] = 4'd1; ltlr[(a)-:4] = 4'd1; a = base+15; bigr[(a)-:4] = 4'd0; ltlr[(a)-:4] = 4'd0; $displayh("bigr[a-:4]: ", bigr, ", ltlr[a-:4]: ", ltlr); if (bigr !== big) begin $display("FAILED: big endian variable L-value -: indexed select."); pass = 1'b0; end if (ltlr !== ltl) begin $display("FAILED: little endian variable L-value -: indexed select."); pass = 1'b0; end bigr = 16'h0000; ltlr = 16'h0000; a = 'bx; bigr[(a)-:4] = 4'hf; ltlr[(a)-:4] = 4'hf; $displayh("bigr[a='bx -:4]: ", bigr, ", ltlr[a='bx -:4]: ", ltlr); if (bigr !== 16'h0000) begin $display("FAILED: big endian variable ('bx) L-value -: indexed select."); pass = 1'b0; end if (ltlr !== 16'h0000) begin $display("FAILED: little endian variable ('bx) L-value -: indexed select."); pass = 1'b0; end bigr = 16'h0000; ltlr = 16'h0000; a = base+2; bigr[(a)-:4] = 4'b011x; ltlr[(a)-:4] = 4'bx001; a = base+16; bigr[(a)-:4] = 4'bx001; ltlr[(a)-:4] = 4'b011x; $displayh("bigr[a=edge -:4]: ", bigr, ", ltlr[a=edge -:4]: ", ltlr); if (bigr !== 16'h2003) begin $display("FAILED: big endian edge L-value constant -: indexed select."); pass = 1'b0; end if (ltlr !== 16'h2003) begin $display("FAILED: little endian edge L-value constant -: indexed select."); pass = 1'b0; end /* * All done. */ if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2837451.v000066400000000000000000000007661435245347300201410ustar00rootroot00000000000000module pr2837451(); // this code provides a regression test that exercises // vvp_fun_part_sa::recv_vec4_pv reg [3:0] a; wire [7:0] b; wire [3:0] c; wire [3:0] d; wire [3:0] e; assign b[5:2] = a; assign c = b[4:1]; assign d = b[5:2]; assign e = b[6:3]; initial begin a = 4'b0101; #1; $display("%b %b %b %b %b", a, b, c, d, e); if ((b === 8'bzz0101zz) && (c === 4'b101z) && (d === 4'b0101) && (e === 4'bz010)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2842185.v000066400000000000000000000003251435245347300201300ustar00rootroot00000000000000module pr2842185(); // check that dection of signal/genvar name collisions // observes scope boundaries. genvar i; task MyTask; integer i; begin $display("PASSED"); end endtask initial MyTask; endmodule iverilog-12_0/ivtest/ivltests/pr2842621.v000066400000000000000000000024201435245347300201210ustar00rootroot00000000000000// A zero value MCD should be allowed, but does it process the arguments? module top; integer mcd, test; initial begin test = 0; // Skipped, but function is called. #1; $display($stime); mcd = 0; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); $fflush(mcd); #1; $display($stime); mcd = 1; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); $fflush(mcd); // Skipped, but function is called. #1; $display($stime); mcd = 0; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); $fflush(mcd); #1; $display($stime); if (test != 6) $display("FAILED side effect test"); else $display("PASSED"); end function integer my_func; input incr; begin test = test + incr; my_func = test; end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr2842621_std.v000066400000000000000000000023541435245347300210010ustar00rootroot00000000000000// A zero value MCD should be allowed, but does it process the arguments? module top; integer mcd, test; initial begin test = 0; // Skipped, but function is called. #1; $display($stime); mcd = 0; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); #1; $display($stime); mcd = 1; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); $fflush(mcd); // Skipped, but function is called. #1; $display($stime); mcd = 0; $fstrobe(mcd, "The $fstrobe(%d, ...) ran.", mcd); $fdisplay(mcd, "The result for $fdisplay(%d, ...) is %d", mcd, my_func(1)); $fwrite(mcd, "The result for $fwrite(%d, ...) is %d\n", mcd, my_func(1)); #1; $display($stime); if (test != 6) $display("FAILED side effect test"); else $display("PASSED"); end function integer my_func; input incr; begin test = test + incr; my_func = test; end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr2848986.v000066400000000000000000000007521435245347300201530ustar00rootroot00000000000000module top; event evt; reg rval; // Call user function with event (continuous assign). wire wval = func(evt); function func; input arg; begin $display("FAILED func."); func = 1'bx; end endfunction task tsk; input arg; begin $display("FAILED task."); end endtask // Call user function with event (procedural) and user task. initial begin rval = func(evt); tsk(evt); end endmodule iverilog-12_0/ivtest/ivltests/pr2849783.v000066400000000000000000000013221435245347300201410ustar00rootroot00000000000000module pr2849783(); reg i; wire a, b, c, d; assign a = i; assign b = a; assign c = 1; assign d = c; reg pass; initial begin i = 1; pass = 1; #1 $display("%b %b", a, b); if ((a !== 1) || (b !== 1)) pass = 0; #1 force a = 0; #1 $display("%b %b", a, b); if ((a !== 0) || (b !== 0)) pass = 0; #1 release a; #1 $display("%b %b", a, b); if ((a !== 1) || (b !== 1)) pass = 0; #1 $display("%b %b", c, d); if ((c !== 1) || (d !== 1)) pass = 0; #1 force c = 0; #1 $display("%b %b", c, d); if ((c !== 0) || (d !== 0)) pass = 0; #1 release c; #1 $display("%b %b", c, d); if ((c !== 1) || (d !== 1)) pass = 0; if (pass) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2859628.v000066400000000000000000000006161435245347300201450ustar00rootroot00000000000000module top; reg [3:0] array [0:1]; initial begin $dumpfile("work/pr2859628.vcd"); $dumpvars(0, top); // This will complain that the array words have already been included! // They have not been since array words are only explicitly added. // The word/scope check code needs to be updated to ignore array words. $dumpvars(0, array[0], array[1]); #1; end endmodule iverilog-12_0/ivtest/ivltests/pr2865563.v000066400000000000000000000012151435245347300201340ustar00rootroot00000000000000module foo (); parameter CLOCK_FREQUENCY = 90e6; // CLOCK_PERIOD_BIT_WIDTH <= log2(90e6) // log2(90e6) = 26.423 parameter CLOCK_PERIOD_BIT_WIDTH = 26; // build something big enaugh to hold CLOCK_FREQUENCY x CLOCK_PERIOD_BIT_WIDTH sums. parameter CP_SUM_BIT_WIDTH = 2 * CLOCK_PERIOD_BIT_WIDTH; // // calculate a sane reset value. // wire [CLOCK_PERIOD_BIT_WIDTH-1:0] rst, rst2; assign rst = {1'd1, {CP_SUM_BIT_WIDTH-1 {1'd0}}} / CLOCK_FREQUENCY; assign rst2 = (52'd2**(CP_SUM_BIT_WIDTH-1)) / CLOCK_FREQUENCY; initial #1 if (rst == rst2) $display("PASSED"); else $display("FAILED"); endmodule // foo iverilog-12_0/ivtest/ivltests/pr2877555.v000066400000000000000000000004271435245347300201440ustar00rootroot00000000000000module testbench; // This should give us a vector of [-1:0] (A == 0). parameter A = $clog2(1); wire [A-1:0] x; wire [A-1:0] y = x; // Check to see that we got a two bit wide wire. initial if ($bits(x) == 2) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr2877564.v000066400000000000000000000001271435245347300201410ustar00rootroot00000000000000module testbench; foo #(ASDF) bar(); endmodule module foo #(parameter A=1); endmodule iverilog-12_0/ivtest/ivltests/pr2883958.v000066400000000000000000000035071435245347300201520ustar00rootroot00000000000000`timescale 1s/1s module test(outp, outm, outl, in); output outp, outm, outl; input in; // Check a primitive. assign #1 outp = ~in; // Check a multiplexer. assign #1 outm = in ? in : 1'b0; // Check a LPM. assign #1 outl = in === 1'b1; endmodule // This is not exactly the same as the original code, but it is effectively // the same and should test the same things that were failing. `timescale 1ns/100ps module top; reg in, passed; wire outp, outm, outl; test dut(outp, outm, outl, in); initial begin passed = 1'b1; #1100000000; if (outp !== 1'bx) begin $display("Failed initial prim. check, expected 1'bx, got %b.", outp); passed = 1'b0; end if (outm !== 1'bx) begin $display("Failed initial mux. check, expected 1'bx, got %b.", outm); passed = 1'b0; end if (outl !== 1'b0) begin $display("Failed initial LPM check, expected 1'b0, got %b.", outl); passed = 1'b0; end in = 0; #1100000000; if (outp !== 1'b1) begin $display("Failed in=0 prim. check, expected 1'b1, got %b.", outp); passed = 1'b0; end if (outm !== 1'b0) begin $display("Failed in=0 mux. check, expected 1'b0, got %b.", outm); passed = 1'b0; end if (outl !== 1'b0) begin $display("Failed in=0 LPM check, expected 1'b0, got %b.", outl); passed = 1'b0; end in = 1; #1100000000; if (outp !== 1'b0) begin $display("Failed in=1 prim. check, expected 1'b0, got %b.", outp); passed = 1'b0; end if (outm !== 1'b1) begin $display("Failed in=1 mux. check, expected 1'b1, got %b.", outm); passed = 1'b0; end if (outl !== 1'b1) begin $display("Failed in=1 LPM check, expected 1'b1, got %b.", outl); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2885048.v000066400000000000000000000011141435245347300201320ustar00rootroot00000000000000module bug; wire [7:0] r1; wire [7:0] r2; wire [7:0] r3; wire [7:0] r4; wire [7:0] r5; wire [7:0] r6; wire [7:0] r7; wire [7:0] r; function [7:0] fn; input [7:0] a; input [7:0] b; input [7:0] c; input [7:0] d; input [7:0] e; input [7:0] f; input [7:0] g; input [7:0] h; begin fn = a + b + c + d + e + f + g + h; end endfunction assign {r1, r2, r3, r4, r5, r6, r7} = 56'd257; assign r = fn(r1, r2, r3, r4, r5, r6, r7, 8'd0); initial begin #1 $display("r=%0d", r); if (r !== 8'd2) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2890322.v000066400000000000000000000005221435245347300201230ustar00rootroot00000000000000module pr2890322; reg [7:0] Array[0:1]; function [7:0] Sum; input [7:0] a; input [7:0] b; begin Sum = a + b; end endfunction wire [7:0] Result = Sum(Array[0], Array[1]); initial begin Array[0] = 1; Array[1] = 2; #1 $display(Result); if (Result === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2901556.v000066400000000000000000000014401435245347300201250ustar00rootroot00000000000000module top; integer lp; wire signed [5:0] in = lp[5:0]; // If these two are combined "$signed({1'b0,in[5]})" then this will work // as expected. wire [5:0] #1 base = (in + (in >>> 2)) >>> 2; wire signed [5:0] #1 fix = base + in[5]; // wire [5:0] base; // If this is missing the program will core dump! // wire signed [5:0] #1 fix = ((in + (in >>> 2)) >>> 2) + $signed({1'b0,in[5]}); wire [6:0] #1 res = in + fix; always @(*) $display("%0d: %d %d %d %d", $time, $signed(in), $signed(base), $signed(fix), $signed(res)); // It appears that the final calculation event is being lost for fix == -1. initial begin lp = -7; #5 lp = -5; #1 lp = -6; #5 if ($signed(res) !== -7) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2909386a.v000066400000000000000000000133111435245347300202770ustar00rootroot00000000000000// Check the power operator (compile time). module top; reg pass; integer res; initial begin pass = 1'b1; // Check the constant ** with various arguments (table 5-6 1364-2005). res = -3**'bx; if (res !== 'bx) begin $display("Failed: constant -3**'bx, expected 'bx, got %0d", res); pass = 1'b0; end res = -1**'bx; if (res !== 'bx) begin $display("Failed: constant -1**'bx, expected 'bx, got %0d", res); pass = 1'b0; end res = 0**'bx; if (res !== 'bx) begin $display("Failed: constant 0**'bx, expected 'bx, got %0d", res); pass = 1'b0; end res = 1**'bx; if (res !== 'bx) begin $display("Failed: constant 1**'bx, expected 'bx, got %0d", res); pass = 1'b0; end res = 3**'bx; if (res !== 'bx) begin $display("Failed: constant 3**'bx, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**-3; if (res !== 'bx) begin $display("Failed: constant 'bx**-3, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**-2; if (res !== 'bx) begin $display("Failed: constant 'bx**-2, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**-1; if (res !== 'bx) begin $display("Failed: constant 'bx**-1, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**0; if (res !== 'bx) begin $display("Failed: constant 'bx**0, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**1; if (res !== 'bx) begin $display("Failed: constant 'bx**1, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**2; if (res !== 'bx) begin $display("Failed: constant 'bx**2, expected 'bx, got %0d", res); pass = 1'b0; end res = 'bx**3; if (res !== 'bx) begin $display("Failed: constant 'bx**3, expected 'bx, got %0d", res); pass = 1'b0; end // Check the 1st line (rvalue is positive). res = -3**3; if (res !== -27) begin $display("Failed: constant -3**3, expected -27, got %0d", res); pass = 1'b0; end res = -3**2; if (res !== 9) begin $display("Failed: constant -3**2, expected 9, got %0d", res); pass = 1'b0; end res = -1**3; if (res !== -1) begin $display("Failed: constant -1**3, expected -1, got %0d", res); pass = 1'b0; end res = -1**2; if (res !== 1) begin $display("Failed: constant -1**2, expected 1, got %0d", res); pass = 1'b0; end res = 0**3; if (res !== 0) begin $display("Failed: constant 0**3, expected 0, got %0d", res); pass = 1'b0; end res = 0**2; if (res !== 0) begin $display("Failed: constant 0**2, expected 0, got %0d", res); pass = 1'b0; end res = 1**3; if (res !== 1) begin $display("Failed: constant 1**3, expected 1, got %0d", res); pass = 1'b0; end res = 1**2; if (res !== 1) begin $display("Failed: constant 1**2, expected 1, got %0d", res); pass = 1'b0; end res = 3**3; if (res !== 27) begin $display("Failed: constant 3**3, expected 27, got %0d", res); pass = 1'b0; end res = 3**2; if (res !== 9) begin $display("Failed: constant 3**2, expected 9, got %0d", res); pass = 1'b0; end // Check the 2nd line (rvalue is zero). res = -3**0; if (res !== 1) begin $display("Failed: constant -3**0, expected 1, got %0d", res); pass = 1'b0; end res = -2**0; if (res !== 1) begin $display("Failed: constant -2**0, expected 1, got %0d", res); pass = 1'b0; end res = -1**0; if (res !== 1) begin $display("Failed: constant -1**0, expected 1, got %0d", res); pass = 1'b0; end res = 0**0; if (res !== 1) begin $display("Failed: constant 0**0, expected 1, got %0d", res); pass = 1'b0; end res = 1**0; if (res !== 1) begin $display("Failed: constant 1**0, expected 1, got %0d", res); pass = 1'b0; end res = 2**0; if (res !== 1) begin $display("Failed: constant 2**0, expected 1, got %0d", res); pass = 1'b0; end res = 3**0; if (res !== 1) begin $display("Failed: constant 3**0, expected 1, got %0d", res); pass = 1'b0; end // Check the 3rd line (rvalue is negative). res = -2**-3; if (res !== 0) begin $display("Failed: constant -2**-3, expected 0, got %0d", res); pass = 1'b0; end res = -2**-2; if (res !== 0) begin $display("Failed: constant -2**-2, expected 0, got %0d", res); pass = 1'b0; end res = -1**-3; if (res !== -1) begin $display("Failed: constant -1**-3, expected -1, got %0d", res); pass = 1'b0; end res = -1**-2; if (res !== 1) begin $display("Failed: constant -1**-2, expected 1, got %0d", res); pass = 1'b0; end res = 0**-3; if (res !== 'bx) begin $display("Failed: constant 0**-3, expected 'bx, got %0d", res); pass = 1'b0; end res = 0**-2; if (res !== 'bx) begin $display("Failed: constant 0**-2, expected 'bx, got %0d", res); pass = 1'b0; end res = 1**-3; if (res !== 1) begin $display("Failed: constant 1**-3, expected 1, got %0d", res); pass = 1'b0; end res = 1**-2; if (res !== 1) begin $display("Failed: constant 1**-2, expected 1, got %0d", res); pass = 1'b0; end res = 2**-3; if (res !== 0) begin $display("Failed: constant 2**-3, expected 0, got %0d", res); pass = 1'b0; end res = 2**-2; if (res !== 0) begin $display("Failed: constant 2**-2, expected 0, got %0d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2909386b.v000066400000000000000000000144751435245347300203140ustar00rootroot00000000000000// Check the power operator (run time). module top; reg pass; integer res; reg signed [31:0] l, r; initial begin pass = 1'b1; // Check the constant ** with various arguments (table 5-6 1364-2005). l = -3; r = 'bx; res = l**r; if (res !== 'bx) begin $display("Failed: constant -3**'bx, expected 'bx, got %0d", res); pass = 1'b0; end l = -1; res = l**r; if (res !== 'bx) begin $display("Failed: constant -1**'bx, expected 'bx, got %0d", res); pass = 1'b0; end l = 0; res = l**r; if (res !== 'bx) begin $display("Failed: constant 0**'bx, expected 'bx, got %0d", res); pass = 1'b0; end l = 1; res = l**r; if (res !== 'bx) begin $display("Failed: constant 1**'bx, expected 'bx, got %0d", res); pass = 1'b0; end l = 3; res = l**r; if (res !== 'bx) begin $display("Failed: constant 3**'bx, expected 'bx, got %0d", res); pass = 1'b0; end l = 'bx; r=-3; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**-3, expected 'bx, got %0d", res); pass = 1'b0; end r=-2; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**-2, expected 'bx, got %0d", res); pass = 1'b0; end r=-1; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**-1, expected 'bx, got %0d", res); pass = 1'b0; end r=0; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**0, expected 'bx, got %0d", res); pass = 1'b0; end r=1; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**1, expected 'bx, got %0d", res); pass = 1'b0; end r=2; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**2, expected 'bx, got %0d", res); pass = 1'b0; end r=3; res = l**r; if (res !== 'bx) begin $display("Failed: constant 'bx**3, expected 'bx, got %0d", res); pass = 1'b0; end // Check the 1st line (rvalue is positive). l=-3; r=3; res = l**r; if (res !== -27) begin $display("Failed: constant -3**3, expected -27, got %0d", res); pass = 1'b0; end l=-3; r=2; res = l**r; if (res !== 9) begin $display("Failed: constant -3**2, expected 9, got %0d", res); pass = 1'b0; end l=-1; r=3; res = l**r; if (res !== -1) begin $display("Failed: constant -1**3, expected -1, got %0d", res); pass = 1'b0; end l=-1; r=2; res = l**r; if (res !== 1) begin $display("Failed: constant -1**2, expected 1, got %0d", res); pass = 1'b0; end l=0; r=3; res = l**r; if (res !== 0) begin $display("Failed: constant 0**3, expected 0, got %0d", res); pass = 1'b0; end l=0; r=2; res = l**r; if (res !== 0) begin $display("Failed: constant 0**2, expected 0, got %0d", res); pass = 1'b0; end l=1; r=3; res = l**r; if (res !== 1) begin $display("Failed: constant 1**3, expected 1, got %0d", res); pass = 1'b0; end l=1; r=2; res = l**r; if (res !== 1) begin $display("Failed: constant 1**2, expected 1, got %0d", res); pass = 1'b0; end l=3; r=3; res = l**r; if (res !== 27) begin $display("Failed: constant 3**3, expected 27, got %0d", res); pass = 1'b0; end l=3; r=2; res = l**r; if (res !== 9) begin $display("Failed: constant 3**2, expected 9, got %0d", res); pass = 1'b0; end // Check the 2nd line (rvalue is zero). l=-3; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant -3**0, expected 1, got %0d", res); pass = 1'b0; end l=-2; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant -2**0, expected 1, got %0d", res); pass = 1'b0; end l=-1; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant -1**0, expected 1, got %0d", res); pass = 1'b0; end l=0; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant 0**0, expected 1, got %0d", res); pass = 1'b0; end l=1; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant 1**0, expected 1, got %0d", res); pass = 1'b0; end l=2; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant 2**0, expected 1, got %0d", res); pass = 1'b0; end l=3; r=0; res = l**r; if (res !== 1) begin $display("Failed: constant 3**0, expected 1, got %0d", res); pass = 1'b0; end // Check the 3rd line (rvalue is negative). l=-2; r=-3; res = l**r; if (res !== 0) begin $display("Failed: constant -2**-3, expected 0, got %0d", res); pass = 1'b0; end l=-2; r=-2; res = l**r; if (res !== 0) begin $display("Failed: constant -2**-2, expected 0, got %0d", res); pass = 1'b0; end l=-1; r=-3; res = l**r; if (res !== -1) begin $display("Failed: constant -1**-3, expected -1, got %0d", res); pass = 1'b0; end l=-1; r=-2; res = l**r; if (res !== 1) begin $display("Failed: constant -1**-2, expected 1, got %0d", res); pass = 1'b0; end l=0; r=-3; res = l**r; if (res !== 'bx) begin $display("Failed: constant 0**-3, expected 'bx, got %0d", res); pass = 1'b0; end l=0; r=-2; res = l**r; if (res !== 'bx) begin $display("Failed: constant 0**-2, expected 'bx, got %0d", res); pass = 1'b0; end l=1; r=-3; res = l**r; if (res !== 1) begin $display("Failed: constant 1**-3, expected 1, got %0d", res); pass = 1'b0; end l=1; r=-2; res = l**r; if (res !== 1) begin $display("Failed: constant 1**-2, expected 1, got %0d", res); pass = 1'b0; end l=2; r=-3; res = l**r; if (res !== 0) begin $display("Failed: constant 2**-3, expected 0, got %0d", res); pass = 1'b0; end l=2; r=-2; res = l**r; if (res !== 0) begin $display("Failed: constant 2**-2, expected 0, got %0d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2909414.v000066400000000000000000000007151435245347300201320ustar00rootroot00000000000000module Top; generate genvar i; for (i = 0; i < 1; i = i + 1) begin Sub1 SubMod1(); end endgenerate endmodule module Sub1; wire [7:0] Value; Sub2 SubMod2(Value); defparam SubMod2.Width = 8; initial begin #1; $display("Value = %h", Value); if (Value === 8'hff) $display("PASSED"); else $display("FAILED"); end endmodule module Sub2(Out); parameter Width = 4; output [Width-1:0] Out; assign Out = {Width{1'b1}}; endmodule iverilog-12_0/ivtest/ivltests/pr2909555.v000066400000000000000000000015121435245347300201340ustar00rootroot00000000000000module top; reg pass; reg [8:0] a; wire [7:0] res_a; reg [6:0] b; wire [7:0] res_b; reg signed [6:0] c; wire [7:0] res_c; assign res_a = Copy(a); assign res_b = Copy(b); assign res_c = Copy(c); initial begin pass = 1'b1; a = 9'h101; b = -7'd1; c = -7'd1; #1; if (res_a !== 8'h01) begin $display("Failed to crop a vector, got %b.", res_a); pass = 1'b0; end if (res_b !== 8'h7f) begin $display("Failed to zero extend an unsigned vector, got %b.", res_b); pass = 1'b0; end if (res_c !== 8'hff) begin $display("Failed to sign extend a signed vector, got %b.", res_c); pass = 1'b0; end if (pass) $display("PASSED"); end function [7:0] Copy; input [7:0] Value; begin Copy = Value; end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr2913404.v000066400000000000000000000031211435245347300201160ustar00rootroot00000000000000module cast_large_real; reg [63:0] u64; reg signed [63:0] i64; reg [64:0] u65; reg signed [64:0] i65; real r; reg fail; initial begin fail = 0; u64 = {1'b1, 63'd0}; r = u64; $display("Convert u64 to real"); $display("Expect : %0f", 2.0**63); $display("Got : %0f", r); if (r != 2.0**63) fail = 1; u64 = r; $display("Convert real to u64"); $display("Expect : %0d", {1'b1, 63'd0}); $display("Got : %0d", u64); if (u64 != {1'b1, 63'd0}) fail = 1; i64 = {1'b1, 63'd0}; r = i64; $display("Convert i64 to real"); $display("Expect : %0f", -(2.0**63)); $display("Got : %0f", r); if (r != -(2.0**63)) fail = 1; i64 = r; $display("Convert real to i64"); $display("Expect : %0d", $signed({1'b1, 63'd0})); $display("Got : %0d", i64); if (i64 != {1'b1, 63'd0}) fail = 1; u65 = {1'b1, 64'd0}; r = u65; $display("Convert u65 to real"); $display("Expect : %0f", 2.0**64); $display("Got : %0f", r); if (r != 2.0**64) fail = 1; u65 = r; $display("Convert real to u65"); $display("Expect : %0d", {1'b1, 64'd0}); $display("Got : %0d", u65); if (u65 != {1'b1, 64'd0}) fail = 1; i65 = {1'b1, 64'd0}; r = i65; $display("Convert i65 to real"); $display("Expect : %0f", -(2.0**64)); $display("Got : %0f", r); if (r != -(2.0**64)) fail = 1; i65 = r; $display("Convert real to i65"); $display("Expect : %0d", $signed({1'b1, 64'd0})); $display("Got : %0d", i65); if (i65 != {1'b1, 64'd0}) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2913416.v000066400000000000000000000010231435245347300201200ustar00rootroot00000000000000module bug; reg pass; reg Select; reg signed [3:0] Delta; reg signed [5:0] Value; wire signed [5:0] Value_ca = (Select ? 12 : 8) + Delta; initial begin pass = 1'b1; Select = 1; Delta = -7; Value = (Select ? 12 : 8) + Delta; if (Value !== 5) begin $display("FAILED: procedural assign, expected 5, got %d", Value); pass = 1'b0; end #1; if (Value_ca !== 5) begin $display("FAILED: continuous assign, expected 5, got %d", Value_ca); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2913438a.v000066400000000000000000000010631435245347300202710ustar00rootroot00000000000000module bug; function [1:0] Copy; input [1:0] Value; begin Copy = Value; end endfunction integer i; integer j; reg [1:0] Expect; reg [1:0] Actual; reg Failed; initial begin Failed = 0; for (i = 0; i < 4; i = i + 1) begin for (j = 0; j < 4; j = j + 1) begin Expect = (i%2)*2 + (j%2); Actual = Copy((i%2)*2 + (j%2)); if (Actual !== Expect) begin $display("Failed: %0d,%0d expected %0d, got %0d", i, j, Expect, Actual); Failed = 1; end end end if (!Failed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2913438b.v000066400000000000000000000017661435245347300203040ustar00rootroot00000000000000module top; reg [6:0] ltl; reg signed [6:0] ltl_s; reg [15:0] big; reg result, pass; initial begin pass = 1'b1; // An unsigned value should be zero padded. ltl = 7'd127; result = test(ltl); if (result) begin $display("Failed: unsigned argument was sign extended"); pass = 1'b0; end // This should be evaluated in an eight bit context since the // function argument is eight bits. This will set the eight bit. result = test(ltl+7'd1); if (!result) begin $display("Failed: function width does not determines expression width."); pass = 1'b0; end // A signed value should be sign padded. ltl_s = -7'd1; result = test(ltl_s); if (!result) begin $display("Failed: signed argument was not sign extended"); pass = 1'b0; end if (pass) $display("PASSED"); end function test ; input signed [7:0] in; begin if (in[7]) test = 1'b1; else test = 1'b0; end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr2913927.v000066400000000000000000000203041435245347300201320ustar00rootroot00000000000000module top; // We expect bits for the zero or mone parameters. The // big test must also be at least , but Icarus currently // creates 48 bits. I personally think this is the correct behavior. parameter zero = 0; parameter mone = -1; parameter big = 'hffffffffffff; parameter max = 2**16; // We will call this many bits unlimited. reg pass; integer idx; initial begin pass = 1'b1; /* * Check with a bit select. */ $display("Checking the size with a bit select."); $display("------------------------------------"); // Test to see how far a decimal 0 is extended. begin: loop_zero for (idx = 0; idx < max; idx = idx + 1) begin if (zero[idx] !== 0) disable loop_zero; end end if (idx != max) begin $display("The size of a decimal 0 parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (zero[idx] !== 1'bx) begin $display(" Failed: after bit must be 1'bx, got %b.", zero[idx]); pass = 1'b0; end end else begin $display("The size of a decimal 0 parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (zero[idx] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", zero[idx]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (zero[idx] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", zero[idx]); pass = 1'b0; end // Test to see how far a decimal -1 is extended. begin: loop_mone for (idx = 0; idx < max; idx = idx + 1) begin if (mone[idx] !== 1) disable loop_mone; end end if (idx != max) begin $display("The size of a decimal -1 parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (mone[idx] !== 1'bx) begin $display(" Failed: after bit must be 1'bx, got %b", mone[idx]); pass = 1'b0; end end else begin $display("The size of a decimal -1 parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (mone[idx] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", mone[idx]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (mone[idx] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", mone[idx]); pass = 1'b0; end // Check to see if a parameter can be more than 32 bits (I expect // unlimited or 48 bits). If they exist the first 48 bits must be 1 // any remaining bits are 0. begin: loop_big for (idx = 0; idx < max; idx = idx + 1) begin if (big[idx] !== (idx < 48)) disable loop_big; end end if (idx != max) begin $display("The size of a big decimal parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (big[idx] !== 1'bx) begin $display(" Failed: after bit must be 1'bx, got %b", big[idx]); pass = 1'b0; end end else begin $display("The size of a big decimal parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 48) begin $display(" Warning: 48 bit unsized parameter was truncated to %0d bits", idx); end if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (big[idx] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", big[idx]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (big[idx] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", big[idx]); pass = 1'b0; end /* * Check with an indexed up select. */ $display(""); $display("Checking the size with an indexed part select."); $display("----------------------------------------------"); // Test to see how far a decimal 0 is extended. begin: loop_zero2 for (idx = 0; idx < max; idx = idx + 1) begin if (zero[idx+:1] !== 0) disable loop_zero2; end end if (idx != max) begin $display("The size of a decimal 0 parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (zero[idx+:1] !== 1'bx) begin $display(" Failed: after bit must be 1'bx, got %b", zero[idx+:1]); pass = 1'b0; end end else begin $display("The size of a decimal 0 parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (zero[idx+:1] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", zero[idx+:1]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (zero[idx+:1] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", zero[idx+:1]); pass = 1'b0; end // Test to see how far a decimal -1 is extended. begin: loop_mone2 for (idx = 0; idx < max; idx = idx + 1) begin if (mone[idx+:1] !== 1) disable loop_mone2; end end if (idx != max) begin $display("The size of a decimal -1 parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (mone[idx+:1] !== 1'bx) begin $display(" Failed: after bit must be 1'bx, got %b", mone[idx+:1]); pass = 1'b0; end end else begin $display("The size of a decimal -1 parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (mone[idx+:1] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", mone[idx+:1]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (mone[idx+:1] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", mone[idx+:1]); pass = 1'b0; end // Check to see if a parameter can be more than 32 bits (I expect // unlimited or 48 bits). If they exist the first 48 bits must be 1 // any remaining bits are 0. begin: loop_big2 for (idx = 0; idx < max; idx = idx + 1) begin if (big[idx+:1] !== (idx < 48)) disable loop_big2; end end if (idx != max) begin $display("The size of a big decimal parameter is %0d bits.", idx); // Check that after the parameter is 1'bx. if (big[idx+:1] !== 1'bx) begin $display("Failed: after bit must be 1'bx, got %b", big[idx+:1]); pass = 1'b0; end end else begin $display("The size of a big decimal parameter is unlimited."); end // An unsized parameter must be at least 32 bits. if (idx < 48) begin $display(" Warning: 48 bit unsized parameter was truncated to %0d bits", idx); end if (idx < 32) begin $display(" Failed: unsized parameter must be >= 32 bits, got %0d.", idx); pass = 1'b0; end // Check that before the parameter is 1'bx. idx = -1; if (big[idx+:1] !== 1'bx) begin $display(" Failed: before bit must be 1'bx, got %b.", big[idx+:1]); pass = 1'b0; end // Check that an undefined index gives 1'bx. idx = 'bx; if (big[idx+:1] !== 1'bx) begin $display(" Failed: undefined select must be 1'bx, got %b.", big[idx+:1]); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2918095.v000066400000000000000000000012141435245347300201320ustar00rootroot00000000000000module bug; reg pass; reg [7:0] a, b; real r; initial begin pass = 1'b1; a = 8'd255; b = 8'd255; if ((a + b) != 254.0) begin $display("FAILED: addition != real constant."); pass = 1'b0; end r = 254.0; if ((a + b) != r) begin $display("FAILED: addition != real variable."); pass = 1'b0; end if ((a * b) != 1.0) begin $display("FAILED: multiplication != real constant."); pass = 1'b0; end r = 1.0; if ((a * b) != r) begin $display("FAILED: multiplication != real variable."); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2922063.v000066400000000000000000000036531435245347300201310ustar00rootroot00000000000000module top; reg pass; integer val; initial begin pass = 1'b1; // Check ARS in a fully signed context. // All operands are signed. val = -1; val = 7'sd10 + (val >>> 1); if (val !== 9) begin $display("Failed ARS in signed context, got %d", val); pass = 1'b0; end // Check ARS in a cast signed context. // This is fully signed as well because of the cast. val = -1; val = $signed(7'd10) + (val >>> 1); if (val !== 9) begin $display("Failed ARS in cast signed context, got %d", val); pass = 1'b0; end // Check ARS in a self determined context. // The system function is a primary and should create a self-determined // context for the ARS. The addition is then done in an unsigned // context, but this should still give the correct result. // // The bug is that Icarus is not sign padding the ARS since the // addition is casting it to be unsigned. It should only be able to // cast the sign of the result not the actual ARS! This casting is // happening in suppress_binary_operand_sign_if_needed() defined in // elab_expr.cc. It looks like $signed and $unsigned need some way // to protect their argument self-determined context. val = -1; val = 7'd10 + $signed(val >>> 1); if (val !== 9) begin $display("Failed ARS in $signed context, got %d", val); pass = 1'b0; end // Check ARS in a different self determined context. // See comments above for $signed. val = -1; val = 7'd10 + $unsigned(val >>> 1); if (val !== 9) begin $display("Failed ARS in $unsigned context, got %d", val); pass = 1'b0; end // Check ARS in a different self determined context. val = -1; val = 7'd10 + {val >>> 1}; if (val !== 9) begin $display("Failed ARS in a concatenation context, got %d", val); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2922063a.v000066400000000000000000000040111435245347300202570ustar00rootroot00000000000000// This is the first part of a two-part test that checks that the argument to // a $signed or $unsigned function is treated as a self-determined expression. // This part performs tests where the argument is unsigned. module pr2922063a; reg [3:0] op1; reg [2:0] op2; reg [7:0] result; reg fail; task check_result; input [7:0] value; begin $write("Expected %b, got %b", value, result); if (result !== value) begin $write(" *"); fail = 1; end $write("\n"); end endtask initial begin fail = 0; $display("-- Addition tests --"); op1 = 4'b1111; op2 = 3'b111; result = 8'sd0 + $signed(op1 + op2); check_result(8'b00000110); result = 8'sd0 + $unsigned(op1 + op2); check_result(8'b00000110); op1 = 4'b1000; op2 = 3'b011; result = 8'sd0 + $signed(op1 + op2); check_result(8'b11111011); result = 8'sd0 + $unsigned(op1 + op2); check_result(8'b00001011); $display("-- Multiply tests --"); op1 = 4'b0101; op2 = 3'b100; result = 8'sd0 + $signed(op1 * op2); check_result(8'b00000100); result = 8'sd0 + $unsigned(op1 * op2); check_result(8'b00000100); op1 = 4'b0010; op2 = 3'b100; result = 8'sd0 + $signed(op1 * op2); check_result(8'b11111000); result = 8'sd0 + $unsigned(op1 * op2); check_result(8'b00001000); $display("-- Left ASR tests --"); op1 = 4'b1010; result = 8'sd0 + $signed(op1 <<< 1); check_result(8'b00000100); result = 8'sd0 + $unsigned(op1 <<< 1); check_result(8'b00000100); op1 = 4'b0101; result = 8'sd0 + $signed(op1 <<< 1); check_result(8'b11111010); result = 8'sd0 + $unsigned(op1 <<< 1); check_result(8'b00001010); $display("-- Right ASR tests --"); op1 = 4'b1010; result = 8'sd0 + $signed(op1 >>> 1); check_result(8'b00000101); result = 8'sd0 + $unsigned(op1 >>> 1); check_result(8'b00000101); op1 = 4'b1010; result = 8'sd0 + $signed(op1 >>> 0); check_result(8'b11111010); result = 8'sd0 + $unsigned(op1 >>> 0); check_result(8'b00001010); if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2922063b.v000066400000000000000000000040441435245347300202660ustar00rootroot00000000000000// This is the second part of a two-part test that checks that the argument to // a $signed or $unsigned function is treated as a self-determined expression. // This part performs tests where the argument is signed. module pr2922063b; reg signed [3:0] op1; reg signed [2:0] op2; reg [7:0] result; reg fail; task check_result; input [7:0] value; begin $write("Expected %b, got %b", value, result); if (result !== value) begin $write(" *"); fail = 1; end $write("\n"); end endtask initial begin fail = 0; $display("-- Addition tests --"); op1 = 4'b1111; op2 = 3'b111; result = 8'sd0 + $signed(op1 + op2); check_result(8'b11111110); result = 8'sd0 + $unsigned(op1 + op2); check_result(8'b00001110); op1 = 4'b1000; op2 = 3'b011; result = 8'sd0 + $signed(op1 + op2); check_result(8'b11111011); result = 8'sd0 + $unsigned(op1 + op2); check_result(8'b00001011); $display("-- Multiply tests --"); op1 = 4'b0101; op2 = 3'b100; result = 8'sd0 + $signed(op1 * op2); check_result(8'b11111100); result = 8'sd0 + $unsigned(op1 * op2); check_result(8'b00001100); op1 = 4'b0010; op2 = 3'b100; result = 8'sd0 + $signed(op1 * op2); check_result(8'b11111000); result = 8'sd0 + $unsigned(op1 * op2); check_result(8'b00001000); $display("-- Left ASR tests --"); op1 = 4'b1010; result = 8'sd0 + $signed(op1 <<< 1); check_result(8'b00000100); result = 8'sd0 + $unsigned(op1 <<< 1); check_result(8'b00000100); op1 = 4'b0101; result = 8'sd0 + $signed(op1 <<< 1); check_result(8'b11111010); result = 8'sd0 + $unsigned(op1 <<< 1); check_result(8'b00001010); $display("-- Right ASR tests --"); op1 = 4'b0101; result = 8'sd0 + $signed(op1 >>> 1); check_result(8'b00000010); result = 8'sd0 + $unsigned(op1 >>> 1); check_result(8'b00000010); op1 = 4'b1010; result = 8'sd0 + $signed(op1 >>> 1); check_result(8'b11111101); result = 8'sd0 + $unsigned(op1 >>> 1); check_result(8'b00001101); if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2924354.v000066400000000000000000000004561435245347300201340ustar00rootroot00000000000000module main; assign impl = 1; wire expl = 1; genvar i; for (i = 0; i < 4; i = i+1) begin : scope test dut(.foo(impl), .bar(expl)); end endmodule // main module test(input wire foo, bar); initial begin #1 $display("foo=%b, bar=%b", foo, bar); end endmodule // test iverilog-12_0/ivtest/ivltests/pr2929913.v000066400000000000000000000004301435245347300201320ustar00rootroot00000000000000`timescale 1ns/1ps module test; reg [3:0] fred[3:0]; initial begin $display("About to assign to array in initial block ..."); fred[0] = 0; $display("PASSED"); end task automatic wilma; wait (fred[0]); endtask endmodule iverilog-12_0/ivtest/ivltests/pr2930506.v000066400000000000000000000004521435245347300201240ustar00rootroot00000000000000`begin_keywords "1364-2005" module test; reg [800:1] string; integer code; real f; initial begin string = "1e1"; code = $sscanf(string, "%f", f); if (f != 10.0) $display("FAILED: got %f", f); else $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2937417.v000066400000000000000000000027601435245347300201400ustar00rootroot00000000000000module top; reg a, pass; wire x, y, ab; assign (weak1, weak0) x = (a === 1'b1) ? 1'b0 : 1'b1; assign y = a; // We need this since Icarus currently has a bug when forcing from // an expression (it only uses the value when the force ran). assign ab = ~a; tran (x, y); initial begin // $monitor ($realtime,, x,y,,a); pass = 1'b1; // Check matching values. #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed initial value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed same value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b1; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed same value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end // Now force and release the driving signal. #1 force a = 1'bx; #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed driver value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 release a; a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed driver value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end // Check that the other driver works. #1 a = 1'bz; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed alt. value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2937417b.v000066400000000000000000000043061435245347300203000ustar00rootroot00000000000000module top; reg a, pass; wire x, y, ab; assign (weak1, weak0) x = (a === 1'b1) ? 1'b0 : 1'b1; assign y = a; // We need this since Icarus currently has a bug when forcing from // an expression (it only uses the value when the force ran). assign ab = ~a; tran (x, y); initial begin // $monitor ($realtime,, x,y,,a); pass = 1'b1; // Check matching values. #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed initial value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed same value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b1; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed same value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end // Check force with opposite values. #1 force x = ab; #1 if ( x !== 1'b0 || y !== 1'bx) begin $display("Failed force value, expected 1'b0, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b0; #1 if ( x !== 1'b1 || y !== 1'bx) begin $display("Failed force value, expected 1'b1, 1'bx, got %b %b", x, y); pass = 1'b0; end // Now release. #1 release x; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed release value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b1; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed release value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end // Now force and release the driving signal. #1 force a = 1'bx; #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed driver value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 release a; a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed driver value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end // Check that the other driver works. #1 a = 1'bz; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed alt. value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2937417c.v000066400000000000000000000043061435245347300203010ustar00rootroot00000000000000module top; reg a, pass; wire x, y, ab; assign (weak1, weak0) x = (a === 1'b1) ? 1'b0 : 1'b1; assign y = a; // We need this since Icarus currently has a bug when forcing from // an expression (it only uses the value when the force ran). assign ab = ~a; tran (x, y); initial begin // $monitor ($realtime,, x,y,,a); pass = 1'b1; // Check matching values. #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed initial value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed same value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b1; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed same value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end // Check force with opposite values. #1 force x = ab; #1 if ( x !== 1'b0 || y !== 1'bx) begin $display("Failed force value, expected 1'b0, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b0; #1 if ( x !== 1'b1 || y !== 1'bx) begin $display("Failed force value, expected 1'b1, 1'bx, got %b %b", x, y); pass = 1'b0; end // Now release. #1 release x; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed release value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end #1 a = 1'b1; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed release value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end // Now force and release the driving signal. #1 force a = 1'bx; #1 if ( x !== 1'bx || y !== 1'bx) begin $display("Failed driver value, expected 1'bx, 1'bx, got %b %b", x, y); pass = 1'b0; end #1 release a; a = 1'b0; #1 if ( x !== 1'b0 || y !== 1'b0) begin $display("Failed driver value, expected 1'b0, 1'b0, got %b %b", x, y); pass = 1'b0; end // Check that the other driver works. #1 a = 1'bz; #1 if ( x !== 1'b1 || y !== 1'b1) begin $display("Failed alt. value, expected 1'b1, 1'b1, got %b %b", x, y); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2941939.v000066400000000000000000000012471435245347300201430ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass; reg a; reg p; wire y; supply1 vdd; supply0 gnd; tranif1 #(5) nmos_0(gnd, y, a); tranif0 #(5) pmos_0(y, vdd, a); initial begin $monitor($realtime,, y,, a); pass = 1'b1; p = 1'bx; a <= 1'b0; repeat (2) #10 a = ~a; #10; if (pass) $display("PASSED"); $finish; end always @(a) begin #4.99 if (y !== p) begin $display("Failed at %.2f (early), expected %b, got %b", $realtime, p, y); pass = 1'b0; end #0.02 if (y !== ~a) begin $display("Failed at %.2f (late), expected %b, got %b", $realtime, ~a, y); pass = 1'b0; end p = y; end endmodule iverilog-12_0/ivtest/ivltests/pr2943394.v000066400000000000000000000050231435245347300201340ustar00rootroot00000000000000module top; reg pass; reg [3:0] val; reg [3:0] pv_val; real rval; initial begin pass = 1'b1; // A release of an unforced variable should not change the variable. val = 4'b0110; release val; if (val !== 4'b0110) begin $display("Failed release of unforced sig, expected 4'b0110, got %b", val); pass = 1'b0; end // Verify that a force/release leaves the variable set correctly. force val = 4'b1001; release val; if (val !== 4'b1001) begin $display("Failed release of forced sig, expected 4'b1001, got %b", val); pass = 1'b0; end // A release of a currently unforced varaible should not change it. val = 4'b0110; release val; if (val !== 4'b0110) begin $display("Failed release of unforced sig(2), expected 4'b0110, got %b", val); pass = 1'b0; end // A release of an unforced variable should not change the variable. pv_val = 4'b1001; release pv_val[1]; if (pv_val !== 4'b1001) begin $display("Failed pv release of unforced sig, expected 4'b1001, got %b", pv_val); pass = 1'b0; end // Verify that a force/release leaves the variable set correctly. force pv_val[1] = 1'b1; release pv_val[2:0]; if (pv_val !== 4'b1011) begin $display("Failed pv release of forced sig, expected 4'b1011, got %b", pv_val); pass = 1'b0; end // A release of a currently unforced varaible should not change it. pv_val = 4'b1001; release pv_val[1]; if (pv_val !== 4'b1001) begin $display("Failed pv release of unforced sig(2), expected 4'b1001, got %b", pv_val); pass = 1'b0; end // A release of an unforced variable should not change the variable. rval = 1.0; release rval; if (rval != 1.0) begin $display("Failed release of unforced sig, expected 1.0, got %.1f", rval); pass = 1'b0; end // Verify that a force/release leaves the variable set correctly. force rval = 2.0; release rval; if (rval != 2.0) begin $display("Failed release of forced sig, expected 2.0, got %.1f", rval); pass = 1'b0; end // A release of a currently unforced varaible should not change it. rval = 1.0; release rval; if (rval != 1.0) begin $display("Failed release of unforced sig(2), expected 1.0, got %.1f", rval); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2951657.v000066400000000000000000000010221435245347300201300ustar00rootroot00000000000000module m; reg [15:0] x,y; initial begin y = 0; x <= 0; x <= 1; x <= 2; x <= 3; x <= 4; x <= 5; x <= 6; // Only this should cause an event, so y should become 1. #10 $display("x = %d (expect 6)", x); $display("y = %d (expect 1)", y); if (x !== 16'd6) begin $display("FAILED"); $finish; end if (y !== 16'd1) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end always @(x[0]) y <= y + 1; endmodule iverilog-12_0/ivtest/ivltests/pr2969724.v000066400000000000000000000012371435245347300201440ustar00rootroot00000000000000module top; reg pass; real rval; reg [7:0] res; initial begin pass = 1'b1; res = 6.0; if (res !== 8'd6) begin $display("Failed blocking assignment, expeted 6, got %d", res); pass = 1'b0; end // The compiler is generating bad code for a NB-assign with a real r-value. res <= 7.0; #1 if (res !== 8'd7) begin $display("Failed nonblocking assignment, expeted 7, got %d", res); pass = 1'b0; end rval = 8.0; res <= rval; #1 if (res !== 8'd8) begin $display("Failed nonblocking assignment, expeted 8, got %d", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2971207.v000066400000000000000000000066651435245347300201430ustar00rootroot00000000000000module top; reg pass, pass_f1, pass_f2, pass_f3, pass_f4, pass_f5; reg [8*30:1] res; initial begin pass = 1'b1; // Verify that the initial scope is correct. $swrite(res, "%m"); if (res != "top") begin $display("Failed initial, got \"%0s\"", res); pass = 1'b0; end // Test %m in a named begin. begin : my_begin $swrite(res, "%m"); if (res != "top.my_begin") begin $display("Failed named begin (1st), got \"%0s\"", res); pass = 1'b0; end begin : my_begin_begin // Test %m in a nested named begin. $swrite(res, "%m"); if (res != "top.my_begin.my_begin_begin") begin $display("Failed nested named begin, got \"%0s\"", res); pass = 1'b0; end end $swrite(res, "%m"); if (res != "top.my_begin") begin $display("Failed named begin (2nd), got \"%0s\"", res); pass = 1'b0; end // Test a named fork inside a named begin. pass_f1 = 1'b1; pass_f2 = 1'b1; fork : my_begin_fork begin $swrite(res, "%m"); if (res != "top.my_begin.my_begin_fork") begin $display("Failed after named begin/fork (1), got \"%0s\"", res); pass_f1 = 1'b0; end end begin $swrite(res, "%m"); if (res != "top.my_begin.my_begin_fork") begin $display("Failed after named begin/fork (2), got \"%0s\"", res); pass_f2 = 1'b0; end end join pass = pass & pass_f1 & pass_f2; $swrite(res, "%m"); if (res != "top.my_begin") begin $display("Failed named begin (3rd), got \"%0s\"", res); pass = 1'b0; end end // Verify that the scope is back to normal. $swrite(res, "%m"); if (res != "top") begin $display("Failed after named begin, got \"%0s\"", res); pass = 1'b0; end // Test %m in a named fork. pass_f1 = 1'b1; pass_f2 = 1'b1; pass_f3 = 1'b1; pass_f4 = 1'b1; pass_f5 = 1'b1; fork : my_fork begin $swrite(res, "%m"); if (res != "top.my_fork") begin $display("Failed after named fork (1), got \"%0s\"", res); pass_f1 = 1'b0; end end // Test a %m in a nested named begin. begin : my_fork_begin $swrite(res, "%m"); if (res != "top.my_fork.my_fork_begin") begin $display("Failed after named fork/begin, got \"%0s\"", res); pass_f4 = 1'b0; end end begin $swrite(res, "%m"); if (res != "top.my_fork") begin $display("Failed after named fork (2), got \"%0s\"", res); pass_f2 = 1'b0; end end fork : my_fork_fork begin $swrite(res, "%m"); if (res != "top.my_fork.my_fork_fork") begin $display("Failed after named fork/fork, got \"%0s\"", res); pass_f2 = 1'b0; end end join begin $swrite(res, "%m"); if (res != "top.my_fork") begin $display("Failed after named fork (3), got \"%0s\"", res); pass_f3 = 1'b0; end end join pass = pass & pass_f1 & pass_f2 & pass_f3; // Verify that the scope is back to normal. $swrite(res, "%m"); if (res != "top") begin $display("Failed final, got \"%0s\"", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2972866.sdf000066400000000000000000000005021435245347300204460ustar00rootroot00000000000000(DELAYFILE (TIMESCALE 1ns) (CELL (CELLTYPE "CLK_BUF") (INSTANCE L1) (DELAY (ABSOLUTE (IOPATH in out (0.12::0.25) (0.11::0.25)) ) ) ) (CELL (CELLTYPE "CLK_BUF") (INSTANCE L2) (DELAY (ABSOLUTE (IOPATH in out (0.20::0.48) (0.19::0.44)) ) ) ) ) iverilog-12_0/ivtest/ivltests/pr2972866.v000066400000000000000000000015761435245347300201530ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass, clk; wire out; initial begin $monitor("%f %b %b", $realtime, out, clk); pass = 1'b1; $sdf_annotate("ivltests/pr2972866.sdf", dut); clk = 1'b0; #10 clk = 1'b1; #10 clk = 1'b0; // Don't check for just PASSED since we are looking for modpath // problems (SDF WARNING)! #10 if (pass) $display("Simulation ran correctly."); end always @(out) if (out !== clk && $time != 0) begin $display("Failed to match, expected %b, got %b.", clk, out); pass = 1'b0; end ckt dut (out, clk); endmodule module ckt(clk_out, clk_in); output clk_out; input clk_in; wire clk_l1; CLK_BUF L1 (clk_l1, clk_in); CLK_BUF L2 (clk_out, clk_l1); endmodule module CLK_BUF(out, in); output out; input in; buf b1 (out, in); specify (in +=> out) = (0.1:0.1:0.1, 0.1:0.1:0.1); endspecify endmodule iverilog-12_0/ivtest/ivltests/pr2973532.v000066400000000000000000000004311435245347300201270ustar00rootroot00000000000000module pr2973532; wire [15:0] a; wire [7:0] b; wire [7:0] c; assign b[5:2] = 4'b1111; assign c = 8'b00000000; assign a = {b, c}; initial begin #1; $display("%b", a); if (a === 16'bzz1111zz00000000) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2974051.v000066400000000000000000000016071435245347300201320ustar00rootroot00000000000000// Extended version of original test case, covering part-driven operands // for all logical operations. module pr2974051; wire [7:0] a; wire [7:0] b; reg c; assign a[5:2] = 4'b0101; assign b[5:2] = 4'b1010; wire [7:0] d = c ? b : a; wire [7:0] e = a & b; wire [7:0] f = a | b; wire [7:0] g = a ^ b; wire [7:0] h = a; wire [7:0] i = ~a; reg fail; initial begin fail = 0; c = 0; #1 $display("%b", d); if (d !== 8'bzz0101zz) fail = 1; c = 1; #1 $display("%b", d); if (d !== 8'bzz1010zz) fail = 1; #1 $display("%b", e); if (e !== 8'bxx0000xx) fail = 1; #1 $display("%b", f); if (f !== 8'bxx1111xx) fail = 1; #1 $display("%b", g); if (g !== 8'bxx1111xx) fail = 1; #1 $display("%b", h); if (h !== 8'bzz0101zz) fail = 1; #1 $display("%b", i); if (i !== 8'bxx1010xx) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2974216.v000066400000000000000000000024461435245347300201370ustar00rootroot00000000000000// Verify that a zero width constant replication is handled correctly. module top; reg pass; reg [31:0] in_full; wire [31:0] pa_out_full, ca_out_full; reg [29:0] in_part; wire [31:0] pa_out_part, ca_out_part; initial begin pass = 1'b1; in_full = {16{2'b10}}; in_part = {15{2'b01}}; #1; if (pa_out_full !== 32'b10101010101010101010101010101010) begin $display("Failed: pa_out_full, got %b", pa_out_full); pass = 1'b1; end if (ca_out_full !== 32'b10101010101010101010101010101010) begin $display("Failed: ca_out_full, got %b", ca_out_full); pass = 1'b1; end if (pa_out_part !== 32'bxx010101010101010101010101010101) begin $display("Failed: pa_out_part, got %b", pa_out_part); pass = 1'b1; end if (ca_out_part !== 32'bzz010101010101010101010101010101) begin $display("Failed: ca_out_part, got %b", ca_out_part); pass = 1'b1; end if (pass) $display("PASSED"); end param #(32) full(pa_out_full, ca_out_full, in_full); param #(30) part(pa_out_part, ca_out_part, in_part); endmodule module param #(parameter width = 32) ( output reg [31:0] pa_out, output wire [31:0] ca_out, input [width-1:0] in); assign ca_out = {{32-width{1'bz}}, in}; always @* pa_out = {{32-width{1'bx}}, in}; endmodule iverilog-12_0/ivtest/ivltests/pr2974216b.v000066400000000000000000000025201435245347300202720ustar00rootroot00000000000000// Verify that a zero width signal replication is handled correctly. module top; reg pass; reg [31:0] in_full; wire [31:0] pa_out_full, ca_out_full; reg [29:0] in_part; wire [31:0] pa_out_part, ca_out_part; initial begin pass = 1'b1; in_full = {16{2'b10}}; in_part = {15{2'b01}}; #1; if (pa_out_full !== 32'b10101010101010101010101010101010) begin $display("Failed: pa_out_full, got %b", pa_out_full); pass = 1'b1; end if (ca_out_full !== 32'b10101010101010101010101010101010) begin $display("Failed: ca_out_full, got %b", ca_out_full); pass = 1'b1; end if (pa_out_part !== 32'bxx010101010101010101010101010101) begin $display("Failed: pa_out_part, got %b", pa_out_part); pass = 1'b1; end if (ca_out_part !== 32'bzz010101010101010101010101010101) begin $display("Failed: ca_out_part, got %b", ca_out_part); pass = 1'b1; end if (pass) $display("PASSED"); end param #(32) full(pa_out_full, ca_out_full, in_full); param #(30) part(pa_out_part, ca_out_part, in_part); endmodule module param #(parameter width = 32) ( output reg [31:0] pa_out, output wire [31:0] ca_out, input [width-1:0] in); wire z_pad = 1'bz; wire x_pad = 1'bx; assign ca_out = {{32-width{z_pad}}, in}; always @* pa_out = {{32-width{x_pad}}, in}; endmodule iverilog-12_0/ivtest/ivltests/pr2974294.v000066400000000000000000000006231435245347300201400ustar00rootroot00000000000000module pr2974294; reg [7:0] array[1:0]; wire [7:0] word; reg fail; assign word = array[0]; initial begin fail = 0; #0 $display("%b", word); if (word !== 8'bx) fail = 1; #1 $display("%b", word); if (word !== 8'bx) fail = 1; array[0] = 8'd0; #0 $display("%b", word); if (word !== 8'd0) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2976242.v000066400000000000000000000034351435245347300201370ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg pass; real rvar; wire [3:0] var; assign var = rvar; initial begin pass = 1'b1; rvar <= 1'b0; #1 rvar = 1'b1; #1 rvar = 2'b10; #1 rvar = 2'b11; #1 if (pass) $display("PASSED"); end real_to_bit u1(rvar); real_to_real u2(rvar); real_to_real u3[1:0](rvar); real_to_vec u4(rvar); real_to_vec u5[1:0](rvar); bit_to_real u6(var[0]); vec_to_real u7(var); vec_to_real u8[1:0](var); endmodule // Check a real value going to a single bit. module real_to_bit (input wire in); always @(in) if (in !== $stime%2) begin $display("Failed real_to_bit %m at %1d, got %b, expected %2b", $stime, in, $stime%2); top.pass = 1'b0; end endmodule // Check a real value going to a real wire. module real_to_real (input wire real in); always @(in) if (in != $stime) begin $display("Failed real_to_real %m at %1d, got %0d, expected %0d", $stime, in, $stime); top.pass = 1'b0; end endmodule // Check a real value going to multiple bit. module real_to_vec (input wire [3:0] in); always @(in) if (in !== $stime) begin $display("Failed real_to_vec %m at %1d, got %0d, expected %0d", $stime, in, $stime); top.pass = 1'b0; end endmodule // Check a single bit going to a real wire. module bit_to_real (input wire real in); always @(in) if (in != $stime%2) begin $display("Failed bit_to_real %m at %1d, got %0d, expected %0d", $stime, in, $stime%2); top.pass = 1'b0; end endmodule // Check a vector going to a real wire. module vec_to_real (input wire real in); always @(in) if (in != $stime) begin $display("Failed vec_to_real %m at %1d, got %0d, expected %0d", $stime, in, $stime); top.pass = 1'b0; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2976242b.v000066400000000000000000000035501435245347300202770ustar00rootroot00000000000000`timescale 1ns/100ps module top; reg pass; reg in; wire out_bit; wire [3:0] out_vec, out_arr; wire real r_bit, r_vec; wire real r_arr[1:0]; initial begin pass = 1'b1; in <= 1'b0; #1 in = 1'b1; #0.5 in = 1'b0; #0.5 in = 1'b1; #0.5 in = 1'b0; #0.5 in = 1'b1; #0.5 in = 1'b0; #0.5 in = 1'b1; #1 if (pass) $display("PASSED"); end real_to_xx u1(out_bit, in); always @(out_bit) if (out_bit !== ($stime % 2)) begin $display("Failed real_to_xx, got %b, expected %1b", out_bit, $stime%2); pass = 1'b0; end real_to_xx u2(out_vec, in); always @(out_vec) if (out_vec !== $stime) begin $display("Failed real_to_xx(vec), got %b, expected %2b", out_vec, $stime); pass = 1'b0; end real_to_xx u3[1:0](out_arr, in); always @(out_arr) #0.1 if ((out_arr[1:0] !== ($stime % 4)) && (out_arr[3:2] !== ($stime % 4))) begin $display("Failed real_to_xx[1:0], got %b, expected %2b%2b", out_arr, $stime%4, $stime%4); pass = 1'b0; end bit_to_real u4(r_bit, in); always @(r_bit) if (r_bit != ($stime % 2)) begin $display("Failed bit_to_real, got %f, expected %1b", r_bit, $stime%2); pass = 1'b0; end vec_to_real u5(r_vec, in); always @(r_vec) if (r_vec != $stime) begin $display("Failed vec_to_real, got %f, expected %1b", r_vec, $stime); pass = 1'b0; end endmodule // Check a real value going to a various things. module real_to_xx (output wire real out, input wire in); real rval; assign out = rval; always @(posedge in) rval = rval + 1; endmodule module bit_to_real (output wire out, input wire in); reg rval = 0; assign out = rval; always @(posedge in) rval = rval + 1; endmodule module vec_to_real (output wire [3:0] out, input wire in); reg [3:0] rval = 0; assign out = rval; always @(posedge in) rval = rval + 1; endmodule iverilog-12_0/ivtest/ivltests/pr2976242c.v000066400000000000000000000021421435245347300202740ustar00rootroot00000000000000`timescale 1ns/100ps module top; reg in; wire [3:0] vec; wire [4:0] bvec; wire real r_vec, r_arr, r_io; initial in <= 1'b0; // You cannot go to multiple real values (have multiple instances). vec_to_real u1[1:0](r_vec, in); // A real port cannot be used in an arrayed instance. arr_real u2a[1:0](bvec, in); arr_real u2b[1:0](r_arr, in); // You cannot connect a real to an inout port. io_vec_to_real u3(r_io, in); // You cannot have a inout port declared real. io_real_to_vec u4(vec, in); endmodule module vec_to_real (output wire [3:0] out, input wire in); reg [3:0] rval = 0; assign out = rval; always @(posedge in) rval = rval + 1; endmodule module arr_real(output wire real out, input wire in); real rval; assign out = rval; always @(posedge in) rval = rval + 1; endmodule module io_vec_to_real(inout wire [3:0] out, input wire in); reg [3:0] rval = 0; assign out = rval; always @(posedge in) rval = rval + 1; endmodule module io_real_to_vec(inout wire real out, input wire in); real rval; assign out = rval; always @(posedge in) rval = rval + 1; endmodule iverilog-12_0/ivtest/ivltests/pr298.v000066400000000000000000000024131435245347300176150ustar00rootroot00000000000000/* * Copyright (c) 2001 Philip Blundell * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ primitive p (Q, D); input D; output Q; reg Q; initial Q = 1'b0; table 0 : ? : 0; 1 : ? : 1; endtable endprimitive module m; reg D; wire Q; reg A; wire QQ; p(Q, D); buf(QQ, Q); initial begin // The #1 is needed here to allow the initial values to // settle. Without it, there is a time-0 race. #1 $display(QQ, Q); #10 D = 0; #15 $display(QQ, Q); #20 D = 1; #25 $display(QQ, Q); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr2985542.v000066400000000000000000000007661435245347300201460ustar00rootroot00000000000000module main; wire [3:0] b = 4'b1111; wire [3:0] c = 4'b1111; initial begin #0; // avoid time-0 race $display("%b", ((c & ~(1'b1<<9'h00)) & b)); // s.b. 1110 $display("%b", |((c & ~(1'b1<<9'h00)) & b)); // s.b. 1 if ( ((c & ~(1'b1<<9'h00)) & b) !== 4'b1110) begin $display("FAILED (1)"); $finish; end if (|((c & ~(1'b1<<9'h00)) & b) !== 1'b1) begin $display("FAILED (2)"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr2986497.v000066400000000000000000000006771435245347300201610ustar00rootroot00000000000000`begin_keywords "1364-2005" module top(arg); input [31:0] arg; wire [31:0] out_0; wire [31:0] out_1; reg [31:0] var; add dut_0 (var, var, out_0); add dut_1 (arg, var, out_1); endmodule module add(in0, in1, out); input [31:0] in0; input [31:0] in1; output reg [31:0] out; // This works if you explicitly specify the sensitivity list. always @* out = in0 + in1; endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr2986528.v000066400000000000000000000023461435245347300201470ustar00rootroot00000000000000// Icarus has a number of places where it can calculate %. module top; parameter out0 = 64'shF333333333333392 % 3'sd3; reg passed; wire signed [63:0] in; wire signed [2:0] const_w0; reg signed [63:0] out1; wire signed [63:0] out2; reg signed [63:0] out3; assign in = 64'hF333333333333392; assign const_w0 = 3'sd3; always @* begin out1 = (in % const_w0); end assign out2 = (in % const_w0); initial begin passed = 1'b1; #1; $display("Testing %0d %% %0d.", in, const_w0); // Check the parameter result. if (out0 !== -2) begin $display("Failed: constant %%, expected -2, got %0d.", out0); passed = 1'b0; end // Check the always result. if (out1 !== -2) begin $display("Failed: procedural %%, expected -2, got %0d.", out1); passed = 1'b0; end // Check the CA result. if (out2 !== -2) begin $display("Failed: CA %%, expected -2, got %0d.", out2); passed = 1'b0; end // Check a compile time constant result. out3 = 64'shF333333333333392 % 3'sd3; if (out3 !== -2) begin $display("Failed: CA %%, expected -2, got %0d.", out3); passed = 1'b0; end if (passed) $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr2991457.v000066400000000000000000000006261435245347300201430ustar00rootroot00000000000000module top; reg [3:0] val; initial begin val = 4'b1111; // The 'b0 should have a minimum size of integer width. This implies // that val should be zero extended before it is inverted. Making // this a false expression. See 1364-2005 (3.5.1 for width and 5.4 // for how the width is propagated. if (~val == 'b0) $display("Failed."); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr2991457b.v000066400000000000000000000011151435245347300202770ustar00rootroot00000000000000/* * This is interesting, and not completely intuitive. In the code * below, the variable "tmp" is assigned the value 4'bxxxx, then * compated with the unsized literal 'hx. Since 'hx is unsized, it * is padded to the width of an integer, and the padding is done * by extending the 'bx. But in the comparison, the unsigned "tmp" * is ZERO extended. Therefore, "tmp" and 'hx are NOT equal. */ module main; reg [3:0] tmp; initial begin tmp = 'hx; if (tmp !== 'hx) begin $display("PASSED"); $finish; end $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr2994193.v000066400000000000000000000036431435245347300201450ustar00rootroot00000000000000/* Crash.v - reproduces a simulation-time crash (PLI assertion failure) Copyright: Bluespec, Inc. 2010 License: GPLv2 or later Transcript: > uname -a Linux jnewbern-laptop 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:09:38 UTC 2010 x86_64 GNU/Linux > iverilog -V Icarus Verilog version 0.9.2 (v0_9_2) ... > iverilog -v -o crash -Wall Crash.v ... /usr/lib/ivl/system.sft: Processing System Function Table file. /usr/lib/ivl/v2005_math.sft: Processing System Function Table file. /usr/lib/ivl/va_math.sft: Processing System Function Table file. Using language generation: IEEE1364-2005,no-specify,xtypes,icarus-misc PARSING INPUT LOCATING TOP-LEVEL MODULES Crash ... done, 0 seconds. ELABORATING DESIGN ... done, 0 seconds. RUNNING FUNCTORS -F cprop ... -F nodangle ... ... 1 iterations deleted 0 dangling signals and 0 events. ... 2 iterations deleted 0 dangling signals and 1 events. CALCULATING ISLANDS ... done, 0 seconds. CODE GENERATION ... invoking target_design ... done, 0 seconds. STATISTICS lex_string: add_count=50 hit_count=17 > ./crash VCD info: dumpfile dump.vcd opened for output. VCD warning: $dumpvars ignored, previously called at simtime 0 vvp: vpi_priv.cc:165: PLI_INT32 vpi_free_object(__vpiHandle*): Assertion `ref' failed. Aborted */ module Crash(); // Create clock reg CLK; initial begin CLK = 1'b0; end always begin #5; CLK = 1'b1; #5; CLK = 1'b0; end // Setup dumpfile at startup initial begin $dumpfile("dump.vcd"); $dumpvars; end // Count cycles reg [7:0] counter; initial begin counter = 8'd0; end always @(posedge CLK) begin counter <= counter + 1; end // Call system tasks on particular cycles always@(posedge CLK) begin if (counter == 8'd2) $dumpvars; // repeated! if (counter >= 8'd200) begin $display("PASSED"); $finish(32'd0); end end endmodule iverilog-12_0/ivtest/ivltests/pr2998515.v000066400000000000000000000010241435245347300201360ustar00rootroot00000000000000module top; reg pass; reg signed [63:0] error; initial begin pass = 1'b1; error = 0; error = error + 64'h40000000; error = error + 64'h80000000; if (error !== 64'hc0000000) begin $display("FAILED immediate add, got %h", error); pass = 1'b0; end error = error + -64'sh40000000; error = error + -64'sh80000000; if (error !== 64'h00000000) begin $display("FAILED immediate add, got %h", error); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3011327.v000066400000000000000000000015631435245347300201200ustar00rootroot00000000000000module main; reg pass; genvar i; generate for( i=1; i<3; i=i+1 ) begin : U reg [1:0] x; end for( i=0; i<2; i=i+1 ) begin : V initial begin U[(i+1)%4].x = 2'd0; #5; U[(i+1)%4].x = i; end end endgenerate initial begin pass = 1'b1; #4; if (U[1].x != 2'd0) begin $display("Failed to clear U[1].x, got %b", U[1].x); pass = 1'b0; end if (U[2].x != 2'd0) begin $display("Failed to clear U[2].x, got %b", U[1].x); pass = 1'b0; end #2; if (U[1].x != 2'd0) begin $display("Failed to set U[1].x, expected 2'd0, got %b", U[1].x); pass = 1'b0; end if (U[2].x != 2'd1) begin $display("Failed to set U[2].x, expected 2'd1, got %b", U[1].x); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3012758.inc000066400000000000000000000000561435245347300204310ustar00rootroot00000000000000 initial begin $display("PASSED"); end iverilog-12_0/ivtest/ivltests/pr3012758.v000066400000000000000000000001231435245347300201200ustar00rootroot00000000000000`define TESTFILE "ivltests/pr3012758.inc" module top; `include `TESTFILE endmodule iverilog-12_0/ivtest/ivltests/pr3015421.v000066400000000000000000000007261435245347300201170ustar00rootroot00000000000000// This test verifies that an incorrect function and task definition // does not crash the compiler. module main(); // A number of errors here: int and return are not supported // (SystemVerilog), so the function definition will fail. The // return should also be inside the begin/end pair. function int pick; input myvar; begin end return 0 endfunction // This is a syntax error missing ';' on the task line. task foo endtask endmodule iverilog-12_0/ivtest/ivltests/pr3022502.v000066400000000000000000000017771435245347300201240ustar00rootroot00000000000000/* Verify that a tail recursive real ternary expression does not * overflow the available thread words. */ module top; reg pass; real vout; integer j; always @(j) begin vout = (j == 0) ? 0.0 : (j == 1) ? 0.1 : (j == 2) ? 0.2 : (j == 3) ? 0.3 : (j == 4) ? 0.4 : (j == 5) ? 0.5 : (j == 6) ? 0.6 : (j == 7) ? 0.7 : (j == 8) ? 0.8 : (j == 9) ? 0.9 : (j == 10) ? 1.0 : (j == 11) ? 1.1 : (j == 12) ? 1.2 : (j == 13) ? 1.3 : (j == 14) ? 1.4 : (j == 15) ? 1.5 : (j == 16) ? 1.6 : (j == 17) ? 1.7 : (j == 18) ? 1.8 : (j == 19) ? 1.9 : 0.0; end initial begin pass = 1'b1; for (j=0; j<20; j=j+1) begin #1; if (vout != j/10.0) begin $display("Failed: at %0d, got %f", j, vout); pass = 1'b0; end end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3024131.v000066400000000000000000000005641435245347300201150ustar00rootroot00000000000000// Verify that the width is only propagated for a vector multiply. // The second (real valued) multiply should not set the expression // width to 1. module top; integer Ival = 14; integer result; initial begin result = Ival * 216 * 140e-3; if (result !== 423) $display("Failed:, expected 423, got %0d", result); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3039548.v000066400000000000000000000004421435245347300201320ustar00rootroot00000000000000module check_this; reg [5:0] offset; reg [9:0] enablemask; initial begin enablemask = 10'b00000_00110; offset = 0; $display("%b", {enablemask, (16'h0 + 8'h80 + offset )}); $display("%b", {enablemask, (16'h0 + (8'h80 + offset))}); end endmodule // check_this iverilog-12_0/ivtest/ivltests/pr304.v000066400000000000000000000020231435245347300175760ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module stimulus; reg[9:0] foo; initial begin foo <= 0-155; #1000 if (foo !== 10'h365) begin $display("FAILED -- foo = %b", foo); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3044843.v000066400000000000000000000003351435245347300201250ustar00rootroot00000000000000module top; parameter ab = 8; parameter ch = 2; reg [63:0] r; initial begin r[0+:ab * ch] = 2; if (r !== 64'hxxxxxxxxxxxx0002) $display("Failed, got %h", r); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101a.v000066400000000000000000000177011435245347300202570ustar00rootroot00000000000000// Check the various variable bit selects (MSB > LSB). module top; parameter [4:1] ap = 4'h8; parameter [4:1] bp = 4'h7; parameter [0:-3] cp = 4'h8; parameter [0:-3] dp = 4'h7; reg passed; wire [4:1] a = 4'h8; wire [4:1] b = 4'h7; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [4:1] ar = 4'h8; reg [4:1] br = 4'h7; wire [0:-3] c = 4'h8; wire [0:-3] d = 4'h7; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [0:-3] cr = 4'h8; reg [0:-3] dr = 4'h7; wire res_a0 = a[s0]; wire res_b0 = b[s0]; wire res_a1 = a[s1]; wire res_b1 = b[s1]; wire res_a2 = a[s2]; wire res_b2 = b[s2]; wire res_c3 = c[s3]; wire res_d3 = d[s3]; wire res_c4 = c[s4]; wire res_d4 = d[s4]; reg [4:1] res_ab; reg [0:-3] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable bit selects of a net. $display("a[s0]: %b", a[s0]); if (a[s0] !== 1'bx) begin $display("Failed a[s0], expected 1'bx, got %b", a[s0]); passed = 1'b0; end $display("b[s0]: %b", b[s0]); if (b[s0] !== 1'bx) begin $display("Failed b[s0], expected 1'bx, got %b", b[s0]); passed = 1'b0; end $display("a[s1]: %b", a[s1]); if (a[s1] !== 1'bx) begin $display("Failed a[s1], expected 1'bx, got %b", a[s1]); passed = 1'b0; end $display("b[s1]: %b", b[s1]); if (b[s1] !== 1'bx) begin $display("Failed b[s1], expected 1'bx, got %b", b[s1]); passed = 1'b0; end $display("a[s2]: %b", a[s2]); if (a[s2] !== 1'bx) begin $display("Failed a[s2], expected 1'bx, got %b", a[s2]); passed = 1'b0; end $display("b[s2]: %b", b[s2]); if (b[s2] !== 1'bx) begin $display("Failed b[s2], expected 1'bx, got %b", b[s2]); passed = 1'b0; end $display("c[s3]: %b", c[s3]); if (c[s3] !== 1'b1) begin $display("Failed c[s3], expected 1'b1, got %b", c[s3]); passed = 1'b0; end $display("d[s3]: %b", d[s3]); if (d[s3] !== 1'b0) begin $display("Failed d[s3], expected 1'b0, got %b", d[s3]); passed = 1'b0; end $display("c[s4]: %b", c[s4]); if (c[s4] !== 1'b1) begin $display("Failed c[s4], expected 1'b1, got %b", c[s4]); passed = 1'b0; end $display("d[s4]: %b", d[s4]); if (d[s4] !== 1'b0) begin $display("Failed d[s4], expected 1'b0, got %b", d[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a parameter. $display("ap[s0]: %b", ap[s0]); if (ap[s0] !== 1'bx) begin $display("Failed ap[s0], expected 1'bx, got %b", ap[s0]); passed = 1'b0; end $display("bp[s0]: %b", bp[s0]); if (bp[s0] !== 1'bx) begin $display("Failed bp[s0], expected 1'bx, got %b", bp[s0]); passed = 1'b0; end $display("ap[s1]: %b", ap[s1]); if (ap[s1] !== 1'bx) begin $display("Failed ap[s1], expected 1'bx, got %b", ap[s1]); passed = 1'b0; end $display("bp[s1]: %b", bp[s1]); if (bp[s1] !== 1'bx) begin $display("Failed bp[s1], expected 1'bx, got %b", bp[s1]); passed = 1'b0; end $display("ap[s2]: %b", ap[s2]); if (ap[s2] !== 1'bx) begin $display("Failed ap[s2], expected 1'bx, got %b", ap[s2]); passed = 1'b0; end $display("bp[s2]: %b", bp[s2]); if (bp[s2] !== 1'bx) begin $display("Failed bp[s2], expected 1'bx, got %b", bp[s2]); passed = 1'b0; end $display("cp[s3]: %b", cp[s3]); if (cp[s3] !== 1'b1) begin $display("Failed cp[s3], expected 1'b1, got %b", cp[s3]); passed = 1'b0; end $display("dp[s3]: %b", dp[s3]); if (dp[s3] !== 1'b0) begin $display("Failed dp[s3], expected 1'b0, got %b", dp[s3]); passed = 1'b0; end $display("cp[s4]: %b", cp[s4]); if (cp[s4] !== 1'b1) begin $display("Failed cp[s4], expected 1'b1, got %b", cp[s4]); passed = 1'b0; end $display("dp[s4]: %b", dp[s4]); if (dp[s4] !== 1'b0) begin $display("Failed dp[s4], expected 1'b0, got %b", dp[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a reg. $display("ar[s0]: %b", ar[s0]); if (ar[s0] !== 1'bx) begin $display("Failed ar[s0], expected 1'bx, got %b", ar[s0]); passed = 1'b0; end $display("br[s0]: %b", br[s0]); if (br[s0] !== 1'bx) begin $display("Failed br[s0], expected 1'bx, got %b", br[s0]); passed = 1'b0; end $display("ar[s1]: %b", ar[s1]); if (ar[s1] !== 1'bx) begin $display("Failed ar[s1], expected 1'bx, got %b", ar[s1]); passed = 1'b0; end $display("br[s1]: %b", br[s1]); if (br[s1] !== 1'bx) begin $display("Failed br[s1], expected 1'bx, got %b", br[s1]); passed = 1'b0; end $display("ar[s2]: %b", ar[s2]); if (ar[s2] !== 1'bx) begin $display("Failed ar[s2], expected 1'bx, got %b", ar[s2]); passed = 1'b0; end $display("br[s2]: %b", br[s2]); if (br[s2] !== 1'bx) begin $display("Failed br[s2], expected 1'bx, got %b", br[s2]); passed = 1'b0; end $display("cr[s3]: %b", cr[s3]); if (cr[s3] !== 1'b1) begin $display("Failed cr[s3], expected 1'b1, got %b", cr[s3]); passed = 1'b0; end $display("dr[s3]: %b", dr[s3]); if (dr[s3] !== 1'b0) begin $display("Failed dr[s3], expected 1'b0, got %b", dr[s3]); passed = 1'b0; end $display("cr[s4]: %b", cr[s4]); if (cr[s4] !== 1'b1) begin $display("Failed cr[s4], expected 1'b1, got %b", cr[s4]); passed = 1'b0; end $display("dr[s4]: %b", dr[s4]); if (dr[s4] !== 1'b0) begin $display("Failed dr[s4], expected 1'b0, got %b", dr[s4]); passed = 1'b0; end // Check continuous assignment R-value variable bit selects. if (res_a0 !== 1'bx) begin $display("Failed res_a0, expected 1'bx, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 1'bx) begin $display("Failed res_b0, expected 1'bx, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 1'bx) begin $display("Failed res_a1, expected 1'bx, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 1'bx) begin $display("Failed res_b1, expected 1'bx, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 1'bx) begin $display("Failed res_a2, expected 1'bx, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 1'bx) begin $display("Failed res_b2, expected 1'bx, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 1'b1) begin $display("Failed res_c3, expected 1'b1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 1'b0) begin $display("Failed res_d3, expected 1'b0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 1'b1) begin $display("Failed res_c4, expected 1'b1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 1'b0) begin $display("Failed res_d4, expected 1'b0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable bit selects. res_ab = 4'bxxxx; res_ab[s0] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s0], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s1], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s2], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3] = 1'b0; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s3], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4] = 1'b0; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s4], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101b.v000066400000000000000000000177171435245347300202670ustar00rootroot00000000000000// Check the various variable bit selects (LSB > MSB). module top; parameter [-4:-1] ap = 4'h1; parameter [-4:-1] bp = 4'he; parameter [-3:0] cp = 4'h1; parameter [-3:0] dp = 4'he; reg passed; wire [-4:-1] a = 4'h1; wire [-4:-1] b = 4'he; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [-4:-1] ar = 4'h1; reg [-4:-1] br = 4'he; wire [-3:0] c = 4'h1; wire [-3:0] d = 4'he; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [-3:0] cr = 4'h1; reg [-3:0] dr = 4'he; wire res_a0 = a[s0]; wire res_b0 = b[s0]; wire res_a1 = a[s1]; wire res_b1 = b[s1]; wire res_a2 = a[s2]; wire res_b2 = b[s2]; wire res_c3 = c[s3]; wire res_d3 = d[s3]; wire res_c4 = c[s4]; wire res_d4 = d[s4]; reg [-4:-1] res_ab; reg [-3:0] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable bit selects of a net. $display("a[s0]: %b", a[s0]); if (a[s0] !== 1'bx) begin $display("Failed a[s0], expected 1'bx, got %b", a[s0]); passed = 1'b0; end $display("b[s0]: %b", b[s0]); if (b[s0] !== 1'bx) begin $display("Failed b[s0], expected 1'bx, got %b", b[s0]); passed = 1'b0; end $display("a[s1]: %b", a[s1]); if (a[s1] !== 1'bx) begin $display("Failed a[s1], expected 1'bx, got %b", a[s1]); passed = 1'b0; end $display("b[s1]: %b", b[s1]); if (b[s1] !== 1'bx) begin $display("Failed b[s1], expected 1'bx, got %b", b[s1]); passed = 1'b0; end $display("a[s2]: %b", a[s2]); if (a[s2] !== 1'bx) begin $display("Failed a[s2], expected 1'bx, got %b", a[s2]); passed = 1'b0; end $display("b[s2]: %b", b[s2]); if (b[s2] !== 1'bx) begin $display("Failed b[s2], expected 1'bx, got %b", b[s2]); passed = 1'b0; end $display("c[s3]: %b", c[s3]); if (c[s3] !== 1'b1) begin $display("Failed c[s3], expected 1'b1, got %b", c[s3]); passed = 1'b0; end $display("d[s3]: %b", d[s3]); if (d[s3] !== 1'b0) begin $display("Failed d[s3], expected 1'b0, got %b", d[s3]); passed = 1'b0; end $display("c[s4]: %b", c[s4]); if (c[s4] !== 1'b1) begin $display("Failed c[s4], expected 1'b1, got %b", c[s4]); passed = 1'b0; end $display("d[s4]: %b", d[s4]); if (d[s4] !== 1'b0) begin $display("Failed d[s4], expected 1'b0, got %b", d[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a parameter. $display("ap[s0]: %b", ap[s0]); if (ap[s0] !== 1'bx) begin $display("Failed ap[s0], expected 1'bx, got %b", ap[s0]); passed = 1'b0; end $display("bp[s0]: %b", bp[s0]); if (bp[s0] !== 1'bx) begin $display("Failed bp[s0], expected 1'bx, got %b", bp[s0]); passed = 1'b0; end $display("ap[s1]: %b", ap[s1]); if (ap[s1] !== 1'bx) begin $display("Failed ap[s1], expected 1'bx, got %b", ap[s1]); passed = 1'b0; end $display("bp[s1]: %b", bp[s1]); if (bp[s1] !== 1'bx) begin $display("Failed bp[s1], expected 1'bx, got %b", bp[s1]); passed = 1'b0; end $display("ap[s2]: %b", ap[s2]); if (ap[s2] !== 1'bx) begin $display("Failed ap[s2], expected 1'bx, got %b", ap[s2]); passed = 1'b0; end $display("bp[s2]: %b", bp[s2]); if (bp[s2] !== 1'bx) begin $display("Failed bp[s2], expected 1'bx, got %b", bp[s2]); passed = 1'b0; end $display("cp[s3]: %b", cp[s3]); if (cp[s3] !== 1'b1) begin $display("Failed cp[s3], expected 1'b1, got %b", cp[s3]); passed = 1'b0; end $display("dp[s3]: %b", dp[s3]); if (dp[s3] !== 1'b0) begin $display("Failed dp[s3], expected 1'b0, got %b", dp[s3]); passed = 1'b0; end $display("cp[s4]: %b", cp[s4]); if (cp[s4] !== 1'b1) begin $display("Failed cp[s4], expected 1'b1, got %b", cp[s4]); passed = 1'b0; end $display("dp[s4]: %b", dp[s4]); if (dp[s4] !== 1'b0) begin $display("Failed dp[s4], expected 1'b0, got %b", dp[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a reg. $display("ar[s0]: %b", ar[s0]); if (ar[s0] !== 1'bx) begin $display("Failed ar[s0], expected 1'bx, got %b", ar[s0]); passed = 1'b0; end $display("br[s0]: %b", br[s0]); if (br[s0] !== 1'bx) begin $display("Failed br[s0], expected 1'bx, got %b", br[s0]); passed = 1'b0; end $display("ar[s1]: %b", ar[s1]); if (ar[s1] !== 1'bx) begin $display("Failed ar[s1], expected 1'bx, got %b", ar[s1]); passed = 1'b0; end $display("br[s1]: %b", br[s1]); if (br[s1] !== 1'bx) begin $display("Failed br[s1], expected 1'bx, got %b", br[s1]); passed = 1'b0; end $display("ar[s2]: %b", ar[s2]); if (ar[s2] !== 1'bx) begin $display("Failed ar[s2], expected 1'bx, got %b", ar[s2]); passed = 1'b0; end $display("br[s2]: %b", br[s2]); if (br[s2] !== 1'bx) begin $display("Failed br[s2], expected 1'bx, got %b", br[s2]); passed = 1'b0; end $display("cr[s3]: %b", cr[s3]); if (cr[s3] !== 1'b1) begin $display("Failed cr[s3], expected 1'b1, got %b", cr[s3]); passed = 1'b0; end $display("dr[s3]: %b", dr[s3]); if (dr[s3] !== 1'b0) begin $display("Failed dr[s3], expected 1'b0, got %b", dr[s3]); passed = 1'b0; end $display("cr[s4]: %b", cr[s4]); if (cr[s4] !== 1'b1) begin $display("Failed cr[s4], expected 1'b1, got %b", cr[s4]); passed = 1'b0; end $display("dr[s4]: %b", dr[s4]); if (dr[s4] !== 1'b0) begin $display("Failed dr[s4], expected 1'b0, got %b", dr[s4]); passed = 1'b0; end // Check continuous assignment R-value variable bit selects. if (res_a0 !== 1'bx) begin $display("Failed res_a0, expected 1'bx, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 1'bx) begin $display("Failed res_b0, expected 1'bx, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 1'bx) begin $display("Failed res_a1, expected 1'bx, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 1'bx) begin $display("Failed res_b1, expected 1'bx, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 1'bx) begin $display("Failed res_a2, expected 1'bx, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 1'bx) begin $display("Failed res_b2, expected 1'bx, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 1'b1) begin $display("Failed res_c3, expected 1'b1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 1'b0) begin $display("Failed res_d3, expected 1'b0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 1'b1) begin $display("Failed res_c4, expected 1'b1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 1'b0) begin $display("Failed res_d4, expected 1'b0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable bit selects. res_ab = 4'bxxxx; res_ab[s0] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s0], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s1], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2] = 1'b0; if (res_ab !== 4'bxxxx) begin $display("Failed res_ab[s2], expected 4'bxxxx, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3] = 1'b0; if (res_cd !== 4'bxxx0) begin $display("Failed res_cd[s3], expected 4'bxxx0, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4] = 1'b0; if (res_cd !== 4'bxxx0) begin $display("Failed res_cd[s4], expected 4'bxxx0, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101c.v000066400000000000000000000211411435245347300202520ustar00rootroot00000000000000// Check the various variable indexed up selects (MSB > LSB). module top; parameter [4:1] ap = 4'h8; parameter [4:1] bp = 4'h7; parameter [0:-3] cp = 4'h8; parameter [0:-3] dp = 4'h7; reg passed; wire [4:1] a = 4'h8; wire [4:1] b = 4'h7; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [4:1] ar = 4'h8; reg [4:1] br = 4'h7; wire [0:-3] c = 4'h8; wire [0:-3] d = 4'h7; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [0:-3] cr = 4'h8; reg [0:-3] dr = 4'h7; wire [1:0] res_a0 = a[s0+:2]; wire [1:0] res_b0 = b[s0+:2]; wire [1:0] res_a1 = a[s1+:2]; wire [1:0] res_b1 = b[s1+:2]; wire [1:0] res_a2 = a[s2+:2]; wire [1:0] res_b2 = b[s2+:2]; wire [1:0] res_c3 = c[s3+:2]; wire [1:0] res_d3 = d[s3+:2]; wire [1:0] res_c4 = c[s4+:2]; wire [1:0] res_d4 = d[s4+:2]; reg [4:1] res_ab; reg [0:-3] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable index up selects of a net. $display("a[s0+:2]: %b", a[s0+:2]); if (a[s0+:2] !== 2'b0x) begin $display("Failed a[s0+:2], expected 2'b0x, got %b", a[s0+:2]); passed = 1'b0; end $display("b[s0+:2]: %b", b[s0+:2]); if (b[s0+:2] !== 2'b1x) begin $display("Failed b[s0+:2], expected 2'b1x, got %b", b[s0+:2]); passed = 1'b0; end $display("a[s1+:2]: %b", a[s1+:2]); if (a[s1+:2] !== 2'b0x) begin $display("Failed a[s1+:2], expected 2'b0x, got %b", a[s1+:2]); passed = 1'b0; end $display("b[s1+:2]: %b", b[s1+:2]); if (b[s1+:2] !== 2'b1x) begin $display("Failed b[s1+:2], expected 2'b1x, got %b", b[s1+:2]); passed = 1'b0; end $display("a[s2+:2]: %b", a[s2+:2]); if (a[s2+:2] !== 2'b0x) begin $display("Failed a[s2+:2], expected 2'b0x, got %b", a[s2+:2]); passed = 1'b0; end $display("b[s2+:2]: %b", b[s2+:2]); if (b[s2+:2] !== 2'b1x) begin $display("Failed b[s2+:2], expected 2'b1x, got %b", b[s2+:2]); passed = 1'b0; end $display("c[s3+:2]: %b", c[s3+:2]); if (c[s3+:2] !== 2'bx1) begin $display("Failed c[s3+:2], expected 2'bx1, got %b", c[s3+:2]); passed = 1'b0; end $display("d[s3+:2]: %b", d[s3+:2]); if (d[s3+:2] !== 2'bx0) begin $display("Failed d[s3+:2], expected 2'bx0, got %b", d[s3+:2]); passed = 1'b0; end $display("c[s4+:2]: %b", c[s4+:2]); if (c[s4+:2] !== 2'bx1) begin $display("Failed c[s4+:2], expected 2'bx1, got %b", c[s4+:2]); passed = 1'b0; end $display("d[s4+:2]: %b", d[s4+:2]); if (d[s4+:2] !== 2'bx0) begin $display("Failed d[s4+:2], expected 2'bx0, got %b", d[s4+:2]); passed = 1'b0; end // Check procedural R-value variable index up selects of a parameter. $display("ap[s0+:2]: %b", ap[s0+:2]); if (ap[s0+:2] !== 2'b0x) begin $display("Failed ap[s0+:2], expected 2'b0x, got %b", ap[s0+:2]); passed = 1'b0; end $display("bp[s0+:2]: %b", bp[s0+:2]); if (bp[s0+:2] !== 2'b1x) begin $display("Failed bp[s0+:2], expected 2'b1x, got %b", bp[s0+:2]); passed = 1'b0; end $display("ap[s1+:2]: %b", ap[s1+:2]); if (ap[s1+:2] !== 2'b0x) begin $display("Failed ap[s1+:2], expected 2'b0x, got %b", ap[s1+:2]); passed = 1'b0; end $display("bp[s1+:2]: %b", bp[s1+:2]); if (bp[s1+:2] !== 2'b1x) begin $display("Failed bp[s1+:2], expected 2'b1x, got %b", bp[s1+:2]); passed = 1'b0; end $display("ap[s2+:2]: %b", ap[s2+:2]); if (ap[s2+:2] !== 2'b0x) begin $display("Failed ap[s2+:2], expected 2'b0x, got %b", ap[s2+:2]); passed = 1'b0; end $display("bp[s2+:2]: %b", bp[s2+:2]); if (bp[s2+:2] !== 2'b1x) begin $display("Failed bp[s2+:2], expected 2'b1x, got %b", bp[s2+:2]); passed = 1'b0; end $display("cp[s3+:2]: %b", cp[s3+:2]); if (cp[s3+:2] !== 2'bx1) begin $display("Failed cp[s3+:2], expected 2'bx1, got %b", cp[s3+:2]); passed = 1'b0; end $display("dp[s3+:2]: %b", dp[s3+:2]); if (dp[s3+:2] !== 2'bx0) begin $display("Failed dp[s3+:2], expected 2'bx0, got %b", dp[s3+:2]); passed = 1'b0; end $display("cp[s4+:2]: %b", cp[s4+:2]); if (cp[s4+:2] !== 2'bx1) begin $display("Failed cp[s4+:2], expected 2'bx1, got %b", cp[s4+:2]); passed = 1'b0; end $display("dp[s4+:2]: %b", dp[s4+:2]); if (dp[s4+:2] !== 2'bx0) begin $display("Failed dp[s4+:2], expected 2'bx0, got %b", dp[s4+:2]); passed = 1'b0; end // Check procedural R-value variable index up selects of a reg. $display("ar[s0+:2]: %b", ar[s0+:2]); if (ar[s0+:2] !== 2'b0x) begin $display("Failed ar[s0+:2], expected 2'b0x, got %b", ar[s0+:2]); passed = 1'b0; end $display("br[s0+:2]: %b", br[s0+:2]); if (br[s0+:2] !== 2'b1x) begin $display("Failed br[s0+:2], expected 2'b1x, got %b", br[s0+:2]); passed = 1'b0; end $display("ar[s1+:2]: %b", ar[s1+:2]); if (ar[s1+:2] !== 2'b0x) begin $display("Failed ar[s1+:2], expected 2'b0x, got %b", ar[s1+:2]); passed = 1'b0; end $display("br[s1+:2]: %b", br[s1+:2]); if (br[s1+:2] !== 2'b1x) begin $display("Failed br[s1+:2], expected 2'b1x, got %b", br[s1+:2]); passed = 1'b0; end $display("ar[s2+:2]: %b", ar[s2+:2]); if (ar[s2+:2] !== 2'b0x) begin $display("Failed ar[s2+:2], expected 2'b0x, got %b", ar[s2+:2]); passed = 1'b0; end $display("br[s2+:2]: %b", br[s2+:2]); if (br[s2+:2] !== 2'b1x) begin $display("Failed br[s2+:2], expected 2'b1x, got %b", br[s2+:2]); passed = 1'b0; end $display("cr[s3+:2]: %b", cr[s3+:2]); if (cr[s3+:2] !== 2'bx1) begin $display("Failed cr[s3+:2], expected 2'bx1, got %b", cr[s3+:2]); passed = 1'b0; end $display("dr[s3+:2]: %b", dr[s3+:2]); if (dr[s3+:2] !== 2'bx0) begin $display("Failed dr[s3+:2], expected 2'bx0, got %b", dr[s3+:2]); passed = 1'b0; end $display("cr[s4+:2]: %b", cr[s4+:2]); if (cr[s4+:2] !== 2'bx1) begin $display("Failed cr[s4+:2], expected 2'bx1, got %b", cr[s4+:2]); passed = 1'b0; end $display("dr[s4+:2]: %b", dr[s4+:2]); if (dr[s4+:2] !== 2'bx0) begin $display("Failed dr[s4+:2], expected 2'bx0, got %b", dr[s4+:2]); passed = 1'b0; end // Check continuous assignment R-value variable index up selects. if (res_a0 !== 2'b0x) begin $display("Failed res_a0, expected 2'b0x, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 2'b1x) begin $display("Failed res_b0, expected 2'b1x, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 2'b0x) begin $display("Failed res_a1, expected 2'b0x, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 2'b1x) begin $display("Failed res_b1, expected 2'b1x, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 2'b0x) begin $display("Failed res_a2, expected 2'b0x, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 2'b1x) begin $display("Failed res_b2, expected 2'b1x, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 2'bx1) begin $display("Failed res_c3, expected 2'bx1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 2'bx0) begin $display("Failed res_d3, expected 2'bx0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 2'bx1) begin $display("Failed res_c4, expected 2'bx1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 2'bx0) begin $display("Failed res_d4, expected 2'bx0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable index up selects. res_ab = 4'bxxxx; res_ab[s0+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s0], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s1], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s2], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3+:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s3], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4+:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s4], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101d.v000066400000000000000000000212001435245347300202470ustar00rootroot00000000000000// Check the various variable indexed up selects (LSB > MSB). module top; parameter [-4:-1] ap = 4'he; parameter [-4:-1] bp = 4'h1; parameter [1:4] cp = 4'he; parameter [1:4] dp = 4'h1; reg passed; wire [-4:-1] a = 4'he; wire [-4:-1] b = 4'h1; wire signed [0:0] s0 = -1; wire signed [1:0] s1 = -1; wire signed [2:0] s2 = -1; reg [-4:-1] ar = 4'he; reg [-4:-1] br = 4'h1; wire [1:4] c = 4'he; wire [1:4] d = 4'h1; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [1:4] cr = 4'he; reg [1:4] dr = 4'h1; wire [1:0] res_a0 = a[s0+:2]; wire [1:0] res_b0 = b[s0+:2]; wire [1:0] res_a1 = a[s1+:2]; wire [1:0] res_b1 = b[s1+:2]; wire [1:0] res_a2 = a[s2+:2]; wire [1:0] res_b2 = b[s2+:2]; wire [1:0] res_c3 = c[s3+:2]; wire [1:0] res_d3 = d[s3+:2]; wire [1:0] res_c4 = c[s4+:2]; wire [1:0] res_d4 = d[s4+:2]; reg [-4:-1] res_ab; reg [1:4] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable index up selects of a net. $display("a[s0+:2]: %b", a[s0+:2]); if (a[s0+:2] !== 2'b0x) begin $display("Failed a[s0+:2], expected 2'b0x, got %b", a[s0+:2]); passed = 1'b0; end $display("b[s0+:2]: %b", b[s0+:2]); if (b[s0+:2] !== 2'b1x) begin $display("Failed b[s0+:2], expected 2'b1x, got %b", b[s0+:2]); passed = 1'b0; end $display("a[s1+:2]: %b", a[s1+:2]); if (a[s1+:2] !== 2'b0x) begin $display("Failed a[s1+:2], expected 2'b0x, got %b", a[s1+:2]); passed = 1'b0; end $display("b[s1+:2]: %b", b[s1+:2]); if (b[s1+:2] !== 2'b1x) begin $display("Failed b[s1+:2], expected 2'b1x, got %b", b[s1+:2]); passed = 1'b0; end $display("a[s2+:2]: %b", a[s2+:2]); if (a[s2+:2] !== 2'b0x) begin $display("Failed a[s2+:2], expected 2'b0x, got %b", a[s2+:2]); passed = 1'b0; end $display("b[s2+:2]: %b", b[s2+:2]); if (b[s2+:2] !== 2'b1x) begin $display("Failed b[s2+:2], expected 2'b1x, got %b", b[s2+:2]); passed = 1'b0; end $display("c[s3+:2]: %b", c[s3+:2]); if (c[s3+:2] !== 2'bx1) begin $display("Failed c[s3+:2], expected 2'bx1, got %b", c[s3+:2]); passed = 1'b0; end $display("d[s3+:2]: %b", d[s3+:2]); if (d[s3+:2] !== 2'bx0) begin $display("Failed d[s3+:2], expected 2'bx0, got %b", d[s3+:2]); passed = 1'b0; end $display("c[s4+:2]: %b", c[s4+:2]); if (c[s4+:2] !== 2'bx1) begin $display("Failed c[s4+:2], expected 2'bx1, got %b", c[s4+:2]); passed = 1'b0; end $display("d[s4+:2]: %b", d[s4+:2]); if (d[s4+:2] !== 2'bx0) begin $display("Failed d[s4+:2], expected 2'bx0, got %b", d[s4+:2]); passed = 1'b0; end // Check procedural R-value variable index up selects of a parameter. $display("ap[s0+:2]: %b", ap[s0+:2]); if (ap[s0+:2] !== 2'b0x) begin $display("Failed ap[s0+:2], expected 2'b0x, got %b", ap[s0+:2]); passed = 1'b0; end $display("bp[s0+:2]: %b", bp[s0+:2]); if (bp[s0+:2] !== 2'b1x) begin $display("Failed bp[s0+:2], expected 2'b1x, got %b", bp[s0+:2]); passed = 1'b0; end $display("ap[s1+:2]: %b", ap[s1+:2]); if (ap[s1+:2] !== 2'b0x) begin $display("Failed ap[s1+:2], expected 2'b0x, got %b", ap[s1+:2]); passed = 1'b0; end $display("bp[s1+:2]: %b", bp[s1+:2]); if (bp[s1+:2] !== 2'b1x) begin $display("Failed bp[s1+:2], expected 2'b1x, got %b", bp[s1+:2]); passed = 1'b0; end $display("ap[s2+:2]: %b", ap[s2+:2]); if (ap[s2+:2] !== 2'b0x) begin $display("Failed ap[s2+:2], expected 2'b0x, got %b", ap[s2+:2]); passed = 1'b0; end $display("bp[s2+:2]: %b", bp[s2+:2]); if (bp[s2+:2] !== 2'b1x) begin $display("Failed bp[s2+:2], expected 2'b1x, got %b", bp[s2+:2]); passed = 1'b0; end $display("cp[s3+:2]: %b", cp[s3+:2]); if (cp[s3+:2] !== 2'bx1) begin $display("Failed cp[s3+:2], expected 2'bx1, got %b", cp[s3+:2]); passed = 1'b0; end $display("dp[s3+:2]: %b", dp[s3+:2]); if (dp[s3+:2] !== 2'bx0) begin $display("Failed dp[s3+:2], expected 2'bx0, got %b", dp[s3+:2]); passed = 1'b0; end $display("cp[s4+:2]: %b", cp[s4+:2]); if (cp[s4+:2] !== 2'bx1) begin $display("Failed cp[s4+:2], expected 2'bx1, got %b", cp[s4+:2]); passed = 1'b0; end $display("dp[s4+:2]: %b", dp[s4+:2]); if (dp[s4+:2] !== 2'bx0) begin $display("Failed dp[s4+:2], expected 2'bx0, got %b", dp[s4+:2]); passed = 1'b0; end // Check procedural R-value variable index up selects of a reg. $display("ar[s0+:2]: %b", ar[s0+:2]); if (ar[s0+:2] !== 2'b0x) begin $display("Failed ar[s0+:2], expected 2'b0x, got %b", ar[s0+:2]); passed = 1'b0; end $display("br[s0+:2]: %b", br[s0+:2]); if (br[s0+:2] !== 2'b1x) begin $display("Failed br[s0+:2], expected 2'b1x, got %b", br[s0+:2]); passed = 1'b0; end $display("ar[s1+:2]: %b", ar[s1+:2]); if (ar[s1+:2] !== 2'b0x) begin $display("Failed ar[s1+:2], expected 2'b0x, got %b", ar[s1+:2]); passed = 1'b0; end $display("br[s1+:2]: %b", br[s1+:2]); if (br[s1+:2] !== 2'b1x) begin $display("Failed br[s1+:2], expected 2'b1x, got %b", br[s1+:2]); passed = 1'b0; end $display("ar[s2+:2]: %b", ar[s2+:2]); if (ar[s2+:2] !== 2'b0x) begin $display("Failed ar[s2+:2], expected 2'b0x, got %b", ar[s2+:2]); passed = 1'b0; end $display("br[s2+:2]: %b", br[s2+:2]); if (br[s2+:2] !== 2'b1x) begin $display("Failed br[s2+:2], expected 2'b1x, got %b", br[s2+:2]); passed = 1'b0; end $display("cr[s3+:2]: %b", cr[s3+:2]); if (cr[s3+:2] !== 2'bx1) begin $display("Failed cr[s3+:2], expected 2'bx1, got %b", cr[s3+:2]); passed = 1'b0; end $display("dr[s3+:2]: %b", dr[s3+:2]); if (dr[s3+:2] !== 2'bx0) begin $display("Failed dr[s3+:2], expected 2'bx0, got %b", dr[s3+:2]); passed = 1'b0; end $display("cr[s4+:2]: %b", cr[s4+:2]); if (cr[s4+:2] !== 2'bx1) begin $display("Failed cr[s4+:2], expected 2'bx1, got %b", cr[s4+:2]); passed = 1'b0; end $display("dr[s4+:2]: %b", dr[s4+:2]); if (dr[s4+:2] !== 2'bx0) begin $display("Failed dr[s4+:2], expected 2'bx0, got %b", dr[s4+:2]); passed = 1'b0; end // Check continuous assignment R-value variable index up selects. if (res_a0 !== 2'b0x) begin $display("Failed res_a0, expected 2'b0x, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 2'b1x) begin $display("Failed res_b0, expected 2'b1x, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 2'b0x) begin $display("Failed res_a1, expected 2'b0x, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 2'b1x) begin $display("Failed res_b1, expected 2'b1x, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 2'b0x) begin $display("Failed res_a2, expected 2'b0x, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 2'b1x) begin $display("Failed res_b2, expected 2'b1x, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 2'bx1) begin $display("Failed res_c3, expected 2'bx1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 2'bx0) begin $display("Failed res_d3, expected 2'bx0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 2'bx1) begin $display("Failed res_c4, expected 2'bx1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 2'bx0) begin $display("Failed res_d4, expected 2'bx0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable index up selects. res_ab = 4'bxxxx; res_ab[s0+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s0], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s1], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2+:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s2], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3+:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s3], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4+:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s4], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101e.v000066400000000000000000000211551435245347300202610ustar00rootroot00000000000000// Check the various variable indexed down selects (MSB > LSB). module top; parameter [4:1] ap = 4'h8; parameter [4:1] bp = 4'h7; parameter [0:-3] cp = 4'h8; parameter [0:-3] dp = 4'h7; reg passed; wire [4:1] a = 4'h8; wire [4:1] b = 4'h7; wire [0:0] s0 = 1; wire [1:0] s1 = 1; wire [2:0] s2 = 1; reg [4:1] ar = 4'h8; reg [4:1] br = 4'h7; wire [0:-3] c = 4'h8; wire [0:-3] d = 4'h7; wire [0:0] s3 = 1; wire [1:0] s4 = 1; reg [0:-3] cr = 4'h8; reg [0:-3] dr = 4'h7; wire [1:0] res_a0 = a[s0-:2]; wire [1:0] res_b0 = b[s0-:2]; wire [1:0] res_a1 = a[s1-:2]; wire [1:0] res_b1 = b[s1-:2]; wire [1:0] res_a2 = a[s2-:2]; wire [1:0] res_b2 = b[s2-:2]; wire [1:0] res_c3 = c[s3-:2]; wire [1:0] res_d3 = d[s3-:2]; wire [1:0] res_c4 = c[s4-:2]; wire [1:0] res_d4 = d[s4-:2]; reg [4:1] res_ab; reg [0:-3] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable index down selects of a net. $display("a[s0-:2]: %b", a[s1-:2]); if (a[s0-:2] !== 2'b0x) begin $display("Failed a[s0-:2], expected 2'b0x, got %b", a[s0-:2]); passed = 1'b0; end $display("b[s0-:2]: %b", b[s1-:2]); if (b[s0-:2] !== 2'b1x) begin $display("Failed b[s0-:2], expected 2'b1x, got %b", b[s0-:2]); passed = 1'b0; end $display("a[s1-:2]: %b", a[s1-:2]); if (a[s1-:2] !== 2'b0x) begin $display("Failed a[s1-:2], expected 2'b0x, got %b", a[s1-:2]); passed = 1'b0; end $display("b[s1-:2]: %b", b[s1-:2]); if (b[s1-:2] !== 2'b1x) begin $display("Failed b[s1-:2], expected 2'b1x, got %b", b[s1-:2]); passed = 1'b0; end $display("a[s2-:2]: %b", a[s2-:2]); if (a[s2-:2] !== 2'b0x) begin $display("Failed a[s2-:2], expected 2'b0x, got %b", a[s2-:2]); passed = 1'b0; end $display("b[s2-:2]: %b", b[s2-:2]); if (b[s2-:2] !== 2'b1x) begin $display("Failed b[s2-:2], expected 2'b1x, got %b", b[s2-:2]); passed = 1'b0; end $display("c[s3-:2]: %b", c[s3-:2]); if (c[s3-:2] !== 2'bx1) begin $display("Failed c[s3-:2], expected 2'bx1, got %b", c[s3-:2]); passed = 1'b0; end $display("d[s3-:2]: %b", d[s3-:2]); if (d[s3-:2] !== 2'bx0) begin $display("Failed d[s3-:2], expected 2'bx0, got %b", d[s3-:2]); passed = 1'b0; end $display("c[s4-:2]: %b", c[s4-:2]); if (c[s4-:2] !== 2'bx1) begin $display("Failed c[s4-:2], expected 2'bx1, got %b", c[s4-:2]); passed = 1'b0; end $display("d[s4-:2]: %b", d[s4-:2]); if (d[s4-:2] !== 2'bx0) begin $display("Failed d[s4-:2], expected 2'bx0, got %b", d[s4-:2]); passed = 1'b0; end // Check procedural R-value variable index down selects of a parameter. $display("ap[s0-:2]: %b", ap[s0-:2]); if (ap[s0-:2] !== 2'b0x) begin $display("Failed ap[s0-:2], expected 2'b0x, got %b", ap[s0-:2]); passed = 1'b0; end $display("bp[s0-:2]: %b", bp[s0-:2]); if (bp[s0-:2] !== 2'b1x) begin $display("Failed bp[s0-:2], expected 2'b1x, got %b", bp[s0-:2]); passed = 1'b0; end $display("ap[s1-:2]: %b", ap[s1-:2]); if (ap[s1-:2] !== 2'b0x) begin $display("Failed ap[s1-:2], expected 2'b0x, got %b", ap[s1-:2]); passed = 1'b0; end $display("bp[s1-:2]: %b", bp[s1-:2]); if (bp[s1-:2] !== 2'b1x) begin $display("Failed bp[s1-:2], expected 2'b1x, got %b", bp[s1-:2]); passed = 1'b0; end $display("ap[s2-:2]: %b", ap[s2-:2]); if (ap[s2-:2] !== 2'b0x) begin $display("Failed ap[s2-:2], expected 2'b0x, got %b", ap[s2-:2]); passed = 1'b0; end $display("bp[s2-:2]: %b", bp[s2-:2]); if (bp[s2-:2] !== 2'b1x) begin $display("Failed bp[s2-:2], expected 2'b1x, got %b", bp[s2-:2]); passed = 1'b0; end $display("cp[s3-:2]: %b", cp[s3-:2]); if (cp[s3-:2] !== 2'bx1) begin $display("Failed cp[s3-:2], expected 2'bx1, got %b", cp[s3-:2]); passed = 1'b0; end $display("dp[s3-:2]: %b", dp[s3-:2]); if (dp[s3-:2] !== 2'bx0) begin $display("Failed dp[s3-:2], expected 2'bx0, got %b", dp[s3-:2]); passed = 1'b0; end $display("cp[s4-:2]: %b", cp[s4-:2]); if (cp[s4-:2] !== 2'bx1) begin $display("Failed cp[s4-:2], expected 2'bx1, got %b", cp[s4-:2]); passed = 1'b0; end $display("dp[s4-:2]: %b", dp[s4-:2]); if (dp[s4-:2] !== 2'bx0) begin $display("Failed dp[s4-:2], expected 2'bx0, got %b", dp[s4-:2]); passed = 1'b0; end // Check procedural R-value variable index down selects of a reg. $display("ar[s0-:2]: %b", ar[s0-:2]); if (ar[s0-:2] !== 2'b0x) begin $display("Failed ar[s0-:2], expected 2'b0x, got %b", ar[s0-:2]); passed = 1'b0; end $display("br[s0-:2]: %b", br[s0-:2]); if (br[s0-:2] !== 2'b1x) begin $display("Failed br[s0-:2], expected 2'b1x, got %b", br[s0-:2]); passed = 1'b0; end $display("ar[s1-:2]: %b", ar[s1-:2]); if (ar[s1-:2] !== 2'b0x) begin $display("Failed ar[s1-:2], expected 2'b0x, got %b", ar[s1-:2]); passed = 1'b0; end $display("br[s1-:2]: %b", br[s1-:2]); if (br[s1-:2] !== 2'b1x) begin $display("Failed br[s1-:2], expected 2'b1x, got %b", br[s1-:2]); passed = 1'b0; end $display("ar[s2-:2]: %b", ar[s2-:2]); if (ar[s2-:2] !== 2'b0x) begin $display("Failed ar[s2-:2], expected 2'b0x, got %b", ar[s2-:2]); passed = 1'b0; end $display("br[s2-:2]: %b", br[s2-:2]); if (br[s2-:2] !== 2'b1x) begin $display("Failed br[s2-:2], expected 2'b1x, got %b", br[s2-:2]); passed = 1'b0; end $display("cr[s3-:2]: %b", cr[s3-:2]); if (cr[s3-:2] !== 2'bx1) begin $display("Failed cr[s3-:2], expected 2'bx1, got %b", cr[s3-:2]); passed = 1'b0; end $display("dr[s3-:2]: %b", dr[s3-:2]); if (dr[s3-:2] !== 2'bx0) begin $display("Failed dr[s3-:2], expected 2'bx0, got %b", dr[s3-:2]); passed = 1'b0; end $display("cr[s4-:2]: %b", cr[s4-:2]); if (cr[s4-:2] !== 2'bx1) begin $display("Failed cr[s4-:2], expected 2'bx1, got %b", cr[s4-:2]); passed = 1'b0; end $display("dr[s4-:2]: %b", dr[s4-:2]); if (dr[s4-:2] !== 2'bx0) begin $display("Failed dr[s4-:2], expected 2'bx0, got %b", dr[s4-:2]); passed = 1'b0; end // Check continuous assignment R-value variable index down selects. if (res_a0 !== 2'b0x) begin $display("Failed res_a0, expected 2'b0x, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 2'b1x) begin $display("Failed res_b0, expected 2'b1x, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 2'b0x) begin $display("Failed res_a1, expected 2'b0x, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 2'b1x) begin $display("Failed res_b1, expected 2'b1x, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 2'b0x) begin $display("Failed res_a2, expected 2'b0x, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 2'b1x) begin $display("Failed res_b2, expected 2'b1x, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 2'bx1) begin $display("Failed res_c3, expected 2'bx1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 2'bx0) begin $display("Failed res_d3, expected 2'bx0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 2'bx1) begin $display("Failed res_c4, expected 2'bx1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 2'bx0) begin $display("Failed res_d4, expected 2'bx0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable index down selects. res_ab = 4'bxxxx; res_ab[s0-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s0], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s1], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s2], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3-:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s3], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4-:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s4], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101f.v000066400000000000000000000211641435245347300202620ustar00rootroot00000000000000// Check the various variable indexed down selects (LSB > MSB). module top; parameter [-4:-1] ap = 4'he; parameter [-4:-1] bp = 4'h1; parameter [1:4] cp = 4'he; parameter [1:4] dp = 4'h1; reg passed; wire [-4:-1] a = 4'he; wire [-4:-1] b = 4'h1; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [-4:-1] ar = 4'he; reg [-4:-1] br = 4'h1; wire [1:4] c = 4'he; wire [1:4] d = 4'h1; wire [0:0] s3 = 1; wire [1:0] s4 = 1; reg [1:4] cr = 4'he; reg [1:4] dr = 4'h1; wire [1:0] res_a0 = a[s0-:2]; wire [1:0] res_b0 = b[s0-:2]; wire [1:0] res_a1 = a[s1-:2]; wire [1:0] res_b1 = b[s1-:2]; wire [1:0] res_a2 = a[s2-:2]; wire [1:0] res_b2 = b[s2-:2]; wire [1:0] res_c3 = c[s3-:2]; wire [1:0] res_d3 = d[s3-:2]; wire [1:0] res_c4 = c[s4-:2]; wire [1:0] res_d4 = d[s4-:2]; reg [-4:-1] res_ab; reg [1:4] res_cd; initial begin #1; passed = 1'b1; // Check procedural R-value variable index down selects of a net. $display("a[s0-:2]: %b", a[s1-:2]); if (a[s0-:2] !== 2'b0x) begin $display("Failed a[s0-:2], expected 2'b0x, got %b", a[s0-:2]); passed = 1'b0; end $display("b[s0-:2]: %b", b[s1-:2]); if (b[s0-:2] !== 2'b1x) begin $display("Failed b[s0-:2], expected 2'b1x, got %b", b[s0-:2]); passed = 1'b0; end $display("a[s1-:2]: %b", a[s1-:2]); if (a[s1-:2] !== 2'b0x) begin $display("Failed a[s1-:2], expected 2'b0x, got %b", a[s1-:2]); passed = 1'b0; end $display("b[s1-:2]: %b", b[s1-:2]); if (b[s1-:2] !== 2'b1x) begin $display("Failed b[s1-:2], expected 2'b1x, got %b", b[s1-:2]); passed = 1'b0; end $display("a[s2-:2]: %b", a[s2-:2]); if (a[s2-:2] !== 2'b0x) begin $display("Failed a[s2-:2], expected 2'b0x, got %b", a[s2-:2]); passed = 1'b0; end $display("b[s2-:2]: %b", b[s2-:2]); if (b[s2-:2] !== 2'b1x) begin $display("Failed b[s2-:2], expected 2'b1x, got %b", b[s2-:2]); passed = 1'b0; end $display("c[s3-:2]: %b", c[s3-:2]); if (c[s3-:2] !== 2'bx1) begin $display("Failed c[s3-:2], expected 2'bx1, got %b", c[s3-:2]); passed = 1'b0; end $display("d[s3-:2]: %b", d[s3-:2]); if (d[s3-:2] !== 2'bx0) begin $display("Failed d[s3-:2], expected 2'bx0, got %b", d[s3-:2]); passed = 1'b0; end $display("c[s4-:2]: %b", c[s4-:2]); if (c[s4-:2] !== 2'bx1) begin $display("Failed c[s4-:2], expected 2'bx1, got %b", c[s4-:2]); passed = 1'b0; end $display("d[s4-:2]: %b", d[s4-:2]); if (d[s4-:2] !== 2'bx0) begin $display("Failed d[s4-:2], expected 2'bx0, got %b", d[s4-:2]); passed = 1'b0; end // Check procedural R-value variable index down selects of a parameter. $display("ap[s0-:2]: %b", ap[s0-:2]); if (ap[s0-:2] !== 2'b0x) begin $display("Failed ap[s0-:2], expected 2'b0x, got %b", ap[s0-:2]); passed = 1'b0; end $display("bp[s0-:2]: %b", bp[s0-:2]); if (bp[s0-:2] !== 2'b1x) begin $display("Failed bp[s0-:2], expected 2'b1x, got %b", bp[s0-:2]); passed = 1'b0; end $display("ap[s1-:2]: %b", ap[s1-:2]); if (ap[s1-:2] !== 2'b0x) begin $display("Failed ap[s1-:2], expected 2'b0x, got %b", ap[s1-:2]); passed = 1'b0; end $display("bp[s1-:2]: %b", bp[s1-:2]); if (bp[s1-:2] !== 2'b1x) begin $display("Failed bp[s1-:2], expected 2'b1x, got %b", bp[s1-:2]); passed = 1'b0; end $display("ap[s2-:2]: %b", ap[s2-:2]); if (ap[s2-:2] !== 2'b0x) begin $display("Failed ap[s2-:2], expected 2'b0x, got %b", ap[s2-:2]); passed = 1'b0; end $display("bp[s2-:2]: %b", bp[s2-:2]); if (bp[s2-:2] !== 2'b1x) begin $display("Failed bp[s2-:2], expected 2'b1x, got %b", bp[s2-:2]); passed = 1'b0; end $display("cp[s3-:2]: %b", cp[s3-:2]); if (cp[s3-:2] !== 2'bx1) begin $display("Failed cp[s3-:2], expected 2'bx1, got %b", cp[s3-:2]); passed = 1'b0; end $display("dp[s3-:2]: %b", dp[s3-:2]); if (dp[s3-:2] !== 2'bx0) begin $display("Failed dp[s3-:2], expected 2'bx0, got %b", dp[s3-:2]); passed = 1'b0; end $display("cp[s4-:2]: %b", cp[s4-:2]); if (cp[s4-:2] !== 2'bx1) begin $display("Failed cp[s4-:2], expected 2'bx1, got %b", cp[s4-:2]); passed = 1'b0; end $display("dp[s4-:2]: %b", dp[s4-:2]); if (dp[s4-:2] !== 2'bx0) begin $display("Failed dp[s4-:2], expected 2'bx0, got %b", dp[s4-:2]); passed = 1'b0; end // Check procedural R-value variable index down selects of a reg. $display("ar[s0-:2]: %b", ar[s0-:2]); if (ar[s0-:2] !== 2'b0x) begin $display("Failed ar[s0-:2], expected 2'b0x, got %b", ar[s0-:2]); passed = 1'b0; end $display("br[s0-:2]: %b", br[s0-:2]); if (br[s0-:2] !== 2'b1x) begin $display("Failed br[s0-:2], expected 2'b1x, got %b", br[s0-:2]); passed = 1'b0; end $display("ar[s1-:2]: %b", ar[s1-:2]); if (ar[s1-:2] !== 2'b0x) begin $display("Failed ar[s1-:2], expected 2'b0x, got %b", ar[s1-:2]); passed = 1'b0; end $display("br[s1-:2]: %b", br[s1-:2]); if (br[s1-:2] !== 2'b1x) begin $display("Failed br[s1-:2], expected 2'b1x, got %b", br[s1-:2]); passed = 1'b0; end $display("ar[s2-:2]: %b", ar[s2-:2]); if (ar[s2-:2] !== 2'b0x) begin $display("Failed ar[s2-:2], expected 2'b0x, got %b", ar[s2-:2]); passed = 1'b0; end $display("br[s2-:2]: %b", br[s2-:2]); if (br[s2-:2] !== 2'b1x) begin $display("Failed br[s2-:2], expected 2'b1x, got %b", br[s2-:2]); passed = 1'b0; end $display("cr[s3-:2]: %b", cr[s3-:2]); if (cr[s3-:2] !== 2'bx1) begin $display("Failed cr[s3-:2], expected 2'bx1, got %b", cr[s3-:2]); passed = 1'b0; end $display("dr[s3-:2]: %b", dr[s3-:2]); if (dr[s3-:2] !== 2'bx0) begin $display("Failed dr[s3-:2], expected 2'bx0, got %b", dr[s3-:2]); passed = 1'b0; end $display("cr[s4-:2]: %b", cr[s4-:2]); if (cr[s4-:2] !== 2'bx1) begin $display("Failed cr[s4-:2], expected 2'bx1, got %b", cr[s4-:2]); passed = 1'b0; end $display("dr[s4-:2]: %b", dr[s4-:2]); if (dr[s4-:2] !== 2'bx0) begin $display("Failed dr[s4-:2], expected 2'bx0, got %b", dr[s4-:2]); passed = 1'b0; end // Check continuous assignment R-value variable index down selects. if (res_a0 !== 2'b0x) begin $display("Failed res_a0, expected 2'b0x, got %b", res_a0); passed = 1'b0; end if (res_b0 !== 2'b1x) begin $display("Failed res_b0, expected 2'b1x, got %b", res_b0); passed = 1'b0; end if (res_a1 !== 2'b0x) begin $display("Failed res_a1, expected 2'b0x, got %b", res_a1); passed = 1'b0; end if (res_b1 !== 2'b1x) begin $display("Failed res_b1, expected 2'b1x, got %b", res_b1); passed = 1'b0; end if (res_a2 !== 2'b0x) begin $display("Failed res_a2, expected 2'b0x, got %b", res_a2); passed = 1'b0; end if (res_b2 !== 2'b1x) begin $display("Failed res_b2, expected 2'b1x, got %b", res_b2); passed = 1'b0; end if (res_c3 !== 2'bx1) begin $display("Failed res_c3, expected 2'bx1, got %b", res_c3); passed = 1'b0; end if (res_d3 !== 2'bx0) begin $display("Failed res_d3, expected 2'bx0, got %b", res_d3); passed = 1'b0; end if (res_c4 !== 2'bx1) begin $display("Failed res_c4, expected 2'bx1, got %b", res_c4); passed = 1'b0; end if (res_d4 !== 2'bx0) begin $display("Failed res_d4, expected 2'bx0, got %b", res_d4); passed = 1'b0; end // Check procedural L-value variable index down selects. res_ab = 4'bxxxx; res_ab[s0-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s0], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s1-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s1], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_ab = 4'bxxxx; res_ab[s2-:2] = 2'b00; if (res_ab !== 4'bxxx0) begin $display("Failed res_ab[s2], expected 4'bxxx0, got %b", res_ab); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s3-:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s3], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end res_cd = 4'bxxxx; res_cd[s4-:2] = 2'b00; if (res_cd !== 4'b0xxx) begin $display("Failed res_cd[s4], expected 4'b0xxx, got %b", res_cd); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101g.v000066400000000000000000000151251435245347300202630ustar00rootroot00000000000000// Check the various variable array selects (small to large). module top; reg passed; wire [1:0] a [1:4]; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [1:0] ar [1:4]; wire [1:0] c [-3:0]; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [1:0] cr [-3:0]; wire [1:0] res_a0 = a[s0]; wire [1:0] res_a1 = a[s1]; wire [1:0] res_a2 = a[s2]; wire [1:0] res_c3 = c[s3]; wire [1:0] res_c4 = c[s4]; reg res_a [1:4]; reg res_c [-3:0]; assign a[1] = 2'd0; assign a[2] = 2'b1; assign a[3] = 2'd2; assign a[4] = 2'd3; assign c[-3] = 2'd0; assign c[-2] = 2'b1; assign c[-1] = 2'd2; assign c[0] = 2'd3; initial begin #1; passed = 1'b1; ar[1] = 2'd0; ar[2] = 2'b1; ar[3] = 2'd2; ar[4] = 2'd3; cr[-3] = 2'd0; cr[-2] = 2'b1; cr[-1] = 2'd2; cr[0] = 2'd3; // Check procedural R-value variable bit selects of a net. $display("a[s0]: %b", a[s0]); if (a[s0] !== 2'bxx) begin $display("Failed a[s0], expected 2'bxx, got %b", a[s0]); passed = 1'b0; end $display("a[s1]: %b", a[s1]); if (a[s1] !== 2'bxx) begin $display("Failed a[s1], expected 2'bxx, got %b", a[s1]); passed = 1'b0; end $display("a[s2]: %b", a[s2]); if (a[s2] !== 2'bxx) begin $display("Failed a[s2], expected 2'bxx, got %b", a[s2]); passed = 1'b0; end $display("c[s3]: %b", c[s3]); if (c[s3] !== 2'b11) begin $display("Failed c[s3], expected 2'b11, got %b", c[s3]); passed = 1'b0; end $display("c[s4]: %b", c[s4]); if (c[s4] !== 2'b11) begin $display("Failed c[s4], expected 2'b11, got %b", c[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a reg. $display("ar[s0]: %b", ar[s0]); if (ar[s0] !== 2'bxx) begin $display("Failed ar[s0], expected 2'bxx, got %b", ar[s0]); passed = 1'b0; end $display("ar[s1]: %b", ar[s1]); if (ar[s1] !== 2'bxx) begin $display("Failed ar[s1], expected 2'bxx, got %b", ar[s1]); passed = 1'b0; end $display("ar[s2]: %b", ar[s2]); if (ar[s2] !== 2'bxx) begin $display("Failed ar[s2], expected 2'bxx, got %b", ar[s2]); passed = 1'b0; end $display("cr[s3]: %b", cr[s3]); if (cr[s3] !== 2'b11) begin $display("Failed cr[s3], expected 2'b11, got %b", cr[s3]); passed = 1'b0; end $display("cr[s4]: %b", cr[s4]); if (cr[s4] !== 2'b11) begin $display("Failed cr[s4], expected 2'b11, got %b", cr[s4]); passed = 1'b0; end // Check continuous assignment R-value variable bit selects. if (res_a0 !== 2'bxx) begin $display("Failed res_a0, expected 2'bxx, got %b", res_a0); passed = 1'b0; end if (res_a1 !== 2'bxx) begin $display("Failed res_a1, expected 2'bxx, got %b", res_a1); passed = 1'b0; end if (res_a2 !== 2'bxx) begin $display("Failed res_a2, expected 2'bxx, got %b", res_a2); passed = 1'b0; end if (res_c3 !== 2'b11) begin $display("Failed res_c3, expected 2'b11, got %b", res_c3); passed = 1'b0; end if (res_c4 !== 2'b11) begin $display("Failed res_c4, expected 2'b11, got %b", res_c4); passed = 1'b0; end // Check procedural L-value variable bit selects. res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s0] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s1] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s2] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_c[-3] = 1'bx; res_c[-2] = 1'bx; res_c[-1] = 1'bx; res_c[0] = 1'bx; res_c[s3] = 1'b0; if (res_c[-3] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-3], got %b", res_c[-3]); passed = 1'b0; end if (res_c[-2] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-2], got %b", res_c[-2]); passed = 1'b0; end if (res_c[-1] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-1], got %b", res_c[-1]); passed = 1'b0; end if (res_c[0] !== 1'b0) begin $display("Failed res_c[s3], expected 1'b0 for [0], got %b", res_c[0]); passed = 1'b0; end res_c[-3] = 1'bx; res_c[-2] = 1'bx; res_c[-1] = 1'bx; res_c[0] = 1'bx; res_c[s4] = 1'b0; if (res_c[-3] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-3], got %b", res_c[-3]); passed = 1'b0; end if (res_c[-2] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-2], got %b", res_c[-2]); passed = 1'b0; end if (res_c[-1] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-1], got %b", res_c[-1]); passed = 1'b0; end if (res_c[0] !== 1'b0) begin $display("Failed res_c[s4], expected 1'b0 for [0], got %b", res_c[0]); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3054101h.v000066400000000000000000000151251435245347300202640ustar00rootroot00000000000000// Check the various variable array selects (large to small). module top; reg passed; wire [1:0] a [4:1]; wire [0:0] s0 = 0; wire [1:0] s1 = 0; wire [2:0] s2 = 0; reg [1:0] ar [4:1]; wire [1:0] c [0:-3]; wire [0:0] s3 = 0; wire [1:0] s4 = 0; reg [1:0] cr [0:-3]; wire [1:0] res_a0 = a[s0]; wire [1:0] res_a1 = a[s1]; wire [1:0] res_a2 = a[s2]; wire [1:0] res_c3 = c[s3]; wire [1:0] res_c4 = c[s4]; reg res_a [4:1]; reg res_c [0:-3]; assign a[1] = 2'd0; assign a[2] = 2'b1; assign a[3] = 2'd2; assign a[4] = 2'd3; assign c[-3] = 2'd0; assign c[-2] = 2'b1; assign c[-1] = 2'd2; assign c[0] = 2'd3; initial begin #1; passed = 1'b1; ar[1] = 2'd0; ar[2] = 2'b1; ar[3] = 2'd2; ar[4] = 2'd3; cr[-3] = 2'd0; cr[-2] = 2'b1; cr[-1] = 2'd2; cr[0] = 2'd3; // Check procedural R-value variable bit selects of a net. $display("a[s0]: %b", a[s0]); if (a[s0] !== 2'bxx) begin $display("Failed a[s0], expected 2'bxx, got %b", a[s0]); passed = 1'b0; end $display("a[s1]: %b", a[s1]); if (a[s1] !== 2'bxx) begin $display("Failed a[s1], expected 2'bxx, got %b", a[s1]); passed = 1'b0; end $display("a[s2]: %b", a[s2]); if (a[s2] !== 2'bxx) begin $display("Failed a[s2], expected 2'bxx, got %b", a[s2]); passed = 1'b0; end $display("c[s3]: %b", c[s3]); if (c[s3] !== 2'b11) begin $display("Failed c[s3], expected 2'b11, got %b", c[s3]); passed = 1'b0; end $display("c[s4]: %b", c[s4]); if (c[s4] !== 2'b11) begin $display("Failed c[s4], expected 2'b11, got %b", c[s4]); passed = 1'b0; end // Check procedural R-value variable bit selects of a reg. $display("ar[s0]: %b", ar[s0]); if (ar[s0] !== 2'bxx) begin $display("Failed ar[s0], expected 2'bxx, got %b", ar[s0]); passed = 1'b0; end $display("ar[s1]: %b", ar[s1]); if (ar[s1] !== 2'bxx) begin $display("Failed ar[s1], expected 2'bxx, got %b", ar[s1]); passed = 1'b0; end $display("ar[s2]: %b", ar[s2]); if (ar[s2] !== 2'bxx) begin $display("Failed ar[s2], expected 2'bxx, got %b", ar[s2]); passed = 1'b0; end $display("cr[s3]: %b", cr[s3]); if (cr[s3] !== 2'b11) begin $display("Failed cr[s3], expected 2'b11, got %b", cr[s3]); passed = 1'b0; end $display("cr[s4]: %b", cr[s4]); if (cr[s4] !== 2'b11) begin $display("Failed cr[s4], expected 2'b11, got %b", cr[s4]); passed = 1'b0; end // Check continuous assignment R-value variable bit selects. if (res_a0 !== 2'bxx) begin $display("Failed res_a0, expected 2'bxx, got %b", res_a0); passed = 1'b0; end if (res_a1 !== 2'bxx) begin $display("Failed res_a1, expected 2'bxx, got %b", res_a1); passed = 1'b0; end if (res_a2 !== 2'bxx) begin $display("Failed res_a2, expected 2'bxx, got %b", res_a2); passed = 1'b0; end if (res_c3 !== 2'b11) begin $display("Failed res_c3, expected 2'b11, got %b", res_c3); passed = 1'b0; end if (res_c4 !== 2'b11) begin $display("Failed res_c4, expected 2'b11, got %b", res_c4); passed = 1'b0; end // Check procedural L-value variable bit selects. res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s0] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s0], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s1] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s1], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_a[1] = 1'bx; res_a[2] = 1'bx; res_a[3] = 1'bx; res_a[4] = 1'bx; res_a[s2] = 1'b0; if (res_a[1] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [1], got %b", res_a[1]); passed = 1'b0; end if (res_a[2] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [2], got %b", res_a[2]); passed = 1'b0; end if (res_a[3] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [3], got %b", res_a[3]); passed = 1'b0; end if (res_a[4] !== 1'bx) begin $display("Failed res_a[s2], expected 1'bx for [4], got %b", res_a[4]); passed = 1'b0; end res_c[-3] = 1'bx; res_c[-2] = 1'bx; res_c[-1] = 1'bx; res_c[0] = 1'bx; res_c[s3] = 1'b0; if (res_c[-3] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-3], got %b", res_c[-3]); passed = 1'b0; end if (res_c[-2] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-2], got %b", res_c[-2]); passed = 1'b0; end if (res_c[-1] !== 1'bx) begin $display("Failed res_c[s3], expected 1'bx for [-1], got %b", res_c[-1]); passed = 1'b0; end if (res_c[0] !== 1'b0) begin $display("Failed res_c[s3], expected 1'b0 for [0], got %b", res_c[0]); passed = 1'b0; end res_c[-3] = 1'bx; res_c[-2] = 1'bx; res_c[-1] = 1'bx; res_c[0] = 1'bx; res_c[s4] = 1'b0; if (res_c[-3] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-3], got %b", res_c[-3]); passed = 1'b0; end if (res_c[-2] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-2], got %b", res_c[-2]); passed = 1'b0; end if (res_c[-1] !== 1'bx) begin $display("Failed res_c[s4], expected 1'bx for [-1], got %b", res_c[-1]); passed = 1'b0; end if (res_c[0] !== 1'b0) begin $display("Failed res_c[s4], expected 1'b0 for [0], got %b", res_c[0]); passed = 1'b0; end if (passed) $display("Compare tests passed"); end endmodule iverilog-12_0/ivtest/ivltests/pr3061015a.v000066400000000000000000000001771435245347300202600ustar00rootroot00000000000000module top; // This should be a compilation error. parameter PARAMB = PARAMB + 6; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3061015b.v000066400000000000000000000002301435245347300202470ustar00rootroot00000000000000module top; // This should be a compilation error. parameter PARAMB = PARAMA; parameter PARAMA = PARAMB; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3061015c.v000066400000000000000000000002061435245347300202530ustar00rootroot00000000000000module top; // This should be a compilation error. parameter real PARAMB = PARAMB + 1.0; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3064375.v000066400000000000000000000010001435245347300201150ustar00rootroot00000000000000module pr3064375; reg CLK; reg RST; reg Reg1; reg Reg2; initial begin CLK = 0; forever begin #5 CLK = 1; #5 CLK = 0; end end initial begin RST = 1; #20; RST = 0; #101; $finish(0); end always @(posedge CLK or posedge RST) begin if (RST) Reg1 <= 0; else Reg1 <= !Reg1; end always @(negedge CLK or posedge RST) begin if (RST) Reg2 <= 0; else Reg2 <= Reg1; end initial begin $monitor("CLK %b RST %b Reg1 %b Reg2 %b", CLK, RST, Reg1, Reg2); end endmodule iverilog-12_0/ivtest/ivltests/pr3064511.v000066400000000000000000000010051435245347300201120ustar00rootroot00000000000000module top; parameter param = -1; reg passed; wire [3:0] val = 11; wire [3:0] res = val + param; reg [3:0] rgval = 11; reg [3:0] rgres; initial begin passed = 1'b1; #1; if (res !== 10) begin $display("FAILED wire result, expected 10, got %d", res); passed = 1'b0; end rgres = rgval + param; if (rgres !== 10) begin $display("FAILED reg result, expected 10, got %d", rgres); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr307.v000066400000000000000000000005471435245347300176120ustar00rootroot00000000000000// (c) 2001 Kenji KISE ivl-bugs PR#307 module top; reg [63:0] in1,in2; reg [63:0] out; initial begin in1 = 64'hffffffffffffffff; in2 = 64'hfffffffffffffff7; out = in1 + in2; $display("%h + %h = %h", in1,in2,out); if (out === 64'hfffffffffffffff6) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3077640.v000066400000000000000000000012231435245347300201230ustar00rootroot00000000000000module top; reg pass; reg [7:0] val; reg signed [7:0] sval; initial begin pass = 1'b1; // An unsized number has an implicit width of integer width. val = $unsigned(-4); if (val !== 8'hfc) begin $display("Failed unsigned, expected 8'hfc, got %h", val); pass = 1'b0; end val = $unsigned(-4'sd4); if (val !== 8'h0c) begin $display("Failed sized unsigned, expected 8'h0c, got %h", val); pass = 1'b0; end sval = $signed(4'hc); if (sval !== -4) begin $display("Failed signed, expected -4, got %d", sval); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3078759.v000066400000000000000000000001431435245347300201370ustar00rootroot00000000000000module top; specify specparam s_int = -1; specparam s_real = -1.0; endspecify endmodule iverilog-12_0/ivtest/ivltests/pr307a.v000066400000000000000000000034501435245347300177470ustar00rootroot00000000000000// ivl-bugs PR#307 module top; reg [127:0] in1; reg [127:0] in2; wire [128:0] out1; reg [128:0] out2; assign out1 = in1 + in2; task r; integer errors; begin out2 = in1 + in2; $display("\n %h\n+ %h", in1,in2); $display("= %h", out1); $display("= %h", out2); if (out1 != out2) begin $display("MISMATCH"); errors = errors + 1; end end endtask initial begin r.errors = 0; in1 = 128'hffffffffffffffffffffffffffffffff; in2 = 128'hfffffffffffffffffffffffffffffff7; r; in1 = 128'hffffffffffffffffffffffffffffffff; in2 = 128'h00000000000000000000000000000001; r; in1 = 128'h00000000000000000000000000000001; in2 = 128'hffffffffffffffffffffffffffffffff; r; in1 = 128'h00000000000000000000000000000000; in2 = 128'hffffffffffffffffffffffffffffffff; r; in1 = 128'hffffffffffffffffffffffffffffffff; in2 = 128'hffffffffffffffffffffffffffffffff; r; in1 = 128'h00000000000000000000000000000000; in2 = 128'h00000000000000000000000000000000; r; in1 = 128'h80000000000000000000000000000000; in2 = 128'h80000000000000000000000000000000; r; in1 = 128'h08000000000000000000000000000000; in2 = 128'h08000000000000000000000000000000; r; in1 = 128'h00000000000000008000000000000000; in2 = 128'h00000000000000008000000000000000; r; in1 = 128'h55555555555555555555555555555555; in2 = 128'h55555555555555555555555555555555; r; in1 = 128'haaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; in2 = 128'haaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; r; if (r.errors) $display("FAILED: %d errors", r.errors); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3098439.v000066400000000000000000000064571435245347300201520ustar00rootroot00000000000000module test; reg pass; reg [8*40:1] str; integer s; reg [31:0] su; integer res; initial begin pass = 1'b1; s = 2000; su = 2000; res = s + (1 << 3) - 1; if (res !== 2007) begin $display("FAILED first term << (s), expected 2007, got %d", res); pass = 1'b0; end res = su + (1 << 3) - 1; if (res !== 2007) begin $display("FAILED first term << (su), expected 2007, got %d", res); pass = 1'b0; end res = s + (16 >> 1) - 1; if (res !== 2007) begin $display("FAILED first term >> (s), expected 2007, got %d", res); pass = 1'b0; end res = su + (16 >> 1) - 1; if (res !== 2007) begin $display("FAILED first term >> (su), expected 2007, got %d", res); pass = 1'b0; end res = (s + (1 << 3) - 1) * 16000; if (res !== 32112000) begin $display("FAILED second term << (s), expected 32112000, got %d", res); pass = 1'b0; end res = (su + (1 << 3) - 1) * 16000; if (res !== 32112000) begin $display("FAILED second term << (su), expected 32112000, got %d", res); pass = 1'b0; end res = (s + (16 >> 1) - 1) * 16000; if (res !== 32112000) begin $display("FAILED second term >> (s), expected 32112000, got %d", res); pass = 1'b0; end res = (su + (16 >> 1) - 1) * 16000; if (res !== 32112000) begin $display("FAILED second term >> (su), expected 32112000, got %d", res); pass = 1'b0; end $sformat(str, "%0d", s + (1 << 3) - 1); if (str[8*4:1] !== "2007" || str[8*40:8*4+1] !== 0) begin $display("FAILED first string << (s), expected \"2007\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", su + (1 << 3) - 1); if (str[8*4:1] !== "2007" || str[8*40:8*4+1] !== 0) begin $display("FAILED first string << (su), expected \"2007\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", s + (16 >> 1) - 1); if (str[8*4:1] !== "2007" || str[8*40:8*4+1] !== 0) begin $display("FAILED first string >> (s), expected \"2007\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", su + (16 >> 1) - 1); if (str[8*4:1] !== "2007" || str[8*40:8*4+1] !== 0) begin $display("FAILED first string >> (su), expected \"2007\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", (s + (1 << 3) - 1) * 16000); if (str[8*8:1] !== "32112000" || str[8*40:8*8+1] !== 0) begin $display("FAILED second string << (s), expected \"32112000\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", (su + (1 << 3) - 1) * 16000); if (str[8*8:1] !== "32112000" || str[8*40:8*8+1] !== 0) begin $display("FAILED second string << (su), expected \"32112000\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", (s + (16 >> 1) - 1) * 16000); if (str[8*8:1] !== "32112000" || str[8*40:8*8+1] !== 0) begin $display("FAILED second string >> (s), expected \"32112000\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", (su + (16 >> 1) -1) * 16000); if (str[8*8:1] !== "32112000" || str[8*40:8*8+1] !== 0) begin $display("FAILED second string >> (su), expected \"32112000\", got %s", str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3098439a.v000066400000000000000000000027311435245347300203020ustar00rootroot00000000000000// This file extends the original bug test case to explore all the // forms of a signed left shift that are treated as special cases. module test; reg pass; reg [8*40:1] str; integer s; initial begin pass = 1'b1; s = 1; $sformat(str, "%0d", ((0 << 1) + 1) * -1); if (str[8*2:1] !== "-1" || str[8*40:8*2+1] !== 0) begin $display("FAILED 1st test, expected \"-1\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((1 << 1) + 1) * -1); if (str[8*2:1] !== "-3" || str[8*40:8*2+1] !== 0) begin $display("FAILED 2nd test, expected \"-3\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((1 << s) + 1) * -1); if (str[8*2:1] !== "-3" || str[8*40:8*2+1] !== 0) begin $display("FAILED 3rd test, expected \"-3\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s << 1) + 1) * -1); if (str[8*2:1] !== "-3" || str[8*40:8*2+1] !== 0) begin $display("FAILED 4th test, expected \"-3\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s << 0) + 1) * -1); if (str[8*2:1] !== "-2" || str[8*40:8*2+1] !== 0) begin $display("FAILED 5th test, expected \"-2\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s << 64) + 1'sd1) * -1'sd1); if (str[8*2:1] !== "-1" || str[8*40:8*2+1] !== 0) begin $display("FAILED 6th test, expected \"-1\", got %s", str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3098439b.v000066400000000000000000000027221435245347300203030ustar00rootroot00000000000000// This file extends the original bug test case to explore all the // forms of a signed right shift that are treated as special cases. module test; reg pass; reg [8*40:1] str; integer s; initial begin pass = 1'b1; s = 1; $sformat(str, "%0d", ((0 >> 1) + 1) * -1); if (str[8*2:1] !== "-1" || str[8*40:8*2+1] !== 0) begin $display("FAILED 1st test, expected \"-1\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((2 >> 1) + 1) * -1); if (str[8*2:1] !== "-2" || str[8*40:8*2+1] !== 0) begin $display("FAILED 2nd test, expected \"-2\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((2 >> s) + 1) * -1); if (str[8*2:1] !== "-2" || str[8*40:8*2+1] !== 0) begin $display("FAILED 3rd test, expected \"-2\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s >> 1) + 1) * -1); if (str[8*2:1] !== "-1" || str[8*40:8*2+1] !== 0) begin $display("FAILED 4th test, expected \"-1\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s >> 0) + 1) * -1); if (str[8*2:1] !== "-2" || str[8*40:8*2+1] !== 0) begin $display("FAILED 5th test, expected \"-2\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", ((s >> 64) + 1) * -1); if (str[8*2:1] !== "-1" || str[8*40:8*2+1] !== 0) begin $display("FAILED 6th test, expected \"-1\", got %s", str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3103880.v000066400000000000000000000013321435245347300201200ustar00rootroot00000000000000module test; reg pass; reg [8*40:1] str; reg [15:0] v; initial begin pass = 1'b1; v = 2; $sformat(str, "%0d", (v + 2 - 1) * 1); if (str[8*1:1] !== "3" || str[8*40:8*1+1] !== 0) begin $display("FAILED 1st test, expected \"3\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", 'd1 - 'd2 + v); if (str[8*1:1] !== "1" || str[8*40:8*1+1] !== 0) begin $display("FAILED 2nd test, expected \"1\", got %s", str); pass = 1'b0; end $sformat(str, "%0d", v + (-1)); if (str[8*1:1] !== "1" || str[8*40:8*1+1] !== 0) begin $display("FAILED 3rd test, expected \"1\", got %s", str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3104254.v000066400000000000000000000021541435245347300201170ustar00rootroot00000000000000module test; reg signed [3:0] a; reg signed [3:0] b; reg [3:0] u; reg [3:0] r; reg fail; initial begin fail = 0; a = 4'b1000; b = 4'b0010; u = 4'b0001; r = ((a >>> 1) | b ) | u; $display("step 1 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((4'b1000 >>> 1) | b ) | u; $display("step 2 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((a >>> 1) | 4'b0010) | u; $display("step 3 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((a >>> 1) | b ) | 4'b0001; $display("step 4 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((4'b1000 >>> 1) | 4'b0010) | u; $display("step 5 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((a >>> 1) | 4'b0010) | 4'b0001; $display("step 6 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; r = ((4'b1000 >>> 1) | 4'b0010) | 4'b0001; $display("step 7 expected '0111', got '%b'", r); if (r !== 4'b0111) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3112073a.v000066400000000000000000000001711435245347300202530ustar00rootroot00000000000000module top; reg real [1:0] a; initial begin a[0] = 0.3; a[1] = 0.4; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr312.v000066400000000000000000000006111435245347300175760ustar00rootroot00000000000000module main; reg [1:0] x; reg [2:0] y; initial begin x = 1; y = {1'b0, x << 1}; if (y !== 3'b010) begin $display("FAILED -- y (%b) != 3'b010", y); $finish; end y = {1'b0, x << 2}; if (y !== 3'b000) begin $display("FAILED -- y (%b) != 3'b000", y); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr3149494.v000066400000000000000000000002761435245347300201410ustar00rootroot00000000000000module m; reg [4'b1111 + 4'b0001 >> 1:0] x; reg [4'b1111 + 1 >> 1:0] y; initial begin x = -1; y = -1; $display("x = %b", x); $display("y = %b", y); end endmodule iverilog-12_0/ivtest/ivltests/pr3190941.v000066400000000000000000000002321435245347300201220ustar00rootroot00000000000000module m1(output reg [7:0] x); endmodule module m2(input [3:0] y); endmodule module tb; wire [3:0] y; m1 foo({4'hx, y}); m2 bar(.y(y)); endmodule iverilog-12_0/ivtest/ivltests/pr3190948.v000066400000000000000000000001211435245347300201260ustar00rootroot00000000000000(* foo, bar=1 *) (* baz=1 *) module foo; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr3194155.v000066400000000000000000000004611435245347300201270ustar00rootroot00000000000000module foo(input x); parameter n = 0; pulldown p1(x); initial #n $display("x(%0d) : %b", n, x); endmodule module tb; wire y; wire z; foo #1 bar1(1'b0); foo #2 bar2(1'b1); foo #3 bar3(1'bz); foo #4 bar4(y); foo #5 bar5({z}); initial #6 $display("y : ", y); initial #7 $display("z : ", z); endmodule iverilog-12_0/ivtest/ivltests/pr3197861.v000066400000000000000000000005221435245347300201340ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [5:0] ivar; real var; initial begin ivar = 0; var = 157.0; // The following line is not being calculated correctly! var = var - 180*ivar[5]; if (var != 157.0) $display("Failed: This should be 157.0: ", var); else $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr3197917.v000066400000000000000000000007411435245347300201410ustar00rootroot00000000000000module top; reg [23:0] in1; reg [54:0] in2; initial begin in1 = 24'b111111000000111111000000; in2 = 55'b0000011111000001111100000111110000011111000001111100000; #1; if (dut.arg !== 96'b111111000000111111000000zzzzzzzzzzzzzzzzz0000011111000001111100000111110000011111000001111100000) begin $display("FAILED"); end else $display("PASSED"); end test dut(in1, in2); endmodule module test(arg[119:96], arg[78:24]); input [119:24] arg; endmodule iverilog-12_0/ivtest/ivltests/pr3270320.v000066400000000000000000000002121435245347300201060ustar00rootroot00000000000000module bug(); function [7:0] dup; input [7:0] i; begin dup = i; end endfunction wire [7:0] a; assign a = dup(missing); endmodule iverilog-12_0/ivtest/ivltests/pr3270320_ams.v000066400000000000000000000001031435245347300207450ustar00rootroot00000000000000module bug(); wire [7:0] b; assign b = $abs(missing); endmodule iverilog-12_0/ivtest/ivltests/pr3284821.v000066400000000000000000000007461435245347300201350ustar00rootroot00000000000000// Test that expression width calculation correctly treats right operand // of shift as unsigned regardless of its actual type. module test; reg pass; reg [8*20:1] str; reg signed [3:0] N; initial begin pass = 1'b1; N = -1; $sformat(str, "%0d", 1 << N); if (str[8*5:1] !== "32768" || str[8*20:8*5+1] !== 0) begin $display("FAILED test, expected \"32768\", got \"%0s\"", str); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3292735.v000066400000000000000000000004021435245347300201250ustar00rootroot00000000000000module table_out( input [1:0] a, (* rom_style = "distributed" *) output reg signed [9:0] phase ); always @(*) case (a) 2'd 0: phase = 0; 2'd 1: phase = 90; 2'd 2: phase = 180; 2'd 3: phase = 270; endcase initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr3296466a.v000066400000000000000000000003331435245347300202760ustar00rootroot00000000000000module top(); reg foo; tri [1:0] a; assign a[0] = foo; tran(a[0], a[1]); initial begin foo = 1'b1; #1 $display("%b", a); if (a === 2'b11) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3296466b.v000066400000000000000000000007611435245347300203040ustar00rootroot00000000000000module connect(inout [1:0] c); tran(c[0], c[1]); endmodule module top(); tri [3:0] a; reg dir; connect connect1(a[1:0]); connect connect2(a[2:1]); connect connect3(a[3:2]); assign a[0] = dir ? 1'bz : 1'b0; assign a[3] = dir ? 1'b1 : 1'bz; reg pass = 1; initial begin dir = 1'b0; #1 $display("%b", a); if (a !== 4'b0000) pass = 0; dir = 1'b1; #1 $display("%b", a); if (a !== 4'b1111) pass = 0; if (pass) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3296466c.v000066400000000000000000000004541435245347300203040ustar00rootroot00000000000000module top(); reg foo; reg bar; tri [1:0] a; tri [1:0] b; assign a[0] = foo; assign b[1] = bar; tran t[1:0](a, b); initial begin foo = 1'b1; bar = 1'b0; #1 $display("%b %b", a, b); if ((a === 2'b01) && (b === 2'b01)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3296466d.v000066400000000000000000000006101435245347300202770ustar00rootroot00000000000000module top(); reg foo; tri [1:0] a; tri [1:0] b; tri [3:0] c; assign a[0] = foo; tran t1(a[0], a[1]); tran t2(b[0], b[1]); tran t3[1:0](a, c[1:0]); tran t4[1:0](b, c[3:2]); tran t5(c[1], c[3]); initial begin foo = 1'b1; #1 $display("%b %b %b", a, b, c); if ((a === 2'b11) && (b === 2'b11) && (c === 4'b1111)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3306516.v000066400000000000000000000022711435245347300201240ustar00rootroot00000000000000// Must be run with -gspecify module top; reg passed; reg a, b; wire y; initial begin passed = 1'b1; a = 0; b = 1; #2 if (y !== 1'bx && y !== 1'bz) begin $display("Failed: Initial value, expected 1'bx, got %b", y); passed = 1'b0; end #2 if (y !== 1'b0) begin $display("Failed: Initial value propagation, expected 1'b0, got %b", y); passed = 1'b0; end a = 1; #2 if (y !== 1'b0) begin $display("Failed: to hold initial value, expected 1'b0, got %b", y); passed = 1'b0; end #2 if (y !== 1'b1) begin $display("Failed: Final value propagation, expected 1'b1, got %b", y); passed = 1'b0; end if (passed) $display("PASSED"); end my_and dut(y, a, b); endmodule module my_and(output wire y, input wire a, b); specify specparam ta = 1; specparam tb = 2; endspecify // A specparam is just like a parameter in this context. In reality // they can be overridden at run-time so the following should really // be an expression instead of just a constant 3, but for now 3 would // be acceptable. Specparams and the specify block need a major rework. assign #(ta+tb) y = a & b; endmodule iverilog-12_0/ivtest/ivltests/pr3309391.v000066400000000000000000000002571435245347300201320ustar00rootroot00000000000000module top; specify specparam Tdelay = 1.0; endspecify initial if (Tdelay != 1.0) $display("FAILED:, got %f", Tdelay); else $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366114.v000066400000000000000000000013161435245347300201230ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas * * The test checks that an unspecified output type is elaborated as Net. * If an intial value is given to an unspecified ouput type it does * not compile. */ module clkgen(output logic clk); logic iclk = 'x; assign clk = iclk; initial begin #100; disable checking; disable gen; $display ("PASSED"); $finish; end initial begin fork checking; gen; join end task gen; begin iclk = 0; forever #10 iclk = ~iclk; end endtask task checking; forever begin #1; if (clk === 1'bx ) begin $display ("FAILED!"); $finish; end end endtask endmodule iverilog-12_0/ivtest/ivltests/pr3366217a.v000066400000000000000000000002301435245347300202620ustar00rootroot00000000000000module top; // You can't have an over range value (compile time error). enum bit[4:0] {some[4] = 100} val; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366217b.v000066400000000000000000000002341435245347300202670ustar00rootroot00000000000000module top; // You can't have an under range value (compile time error). enum bit[1:0] {nega = -1, b , c} val; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366217c.v000066400000000000000000000002331435245347300202670ustar00rootroot00000000000000module top; // An implicit value cannot be over range (compile time error). enum bit[1:0] {a = 3, b , c} val; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366217d.v000066400000000000000000000013311435245347300202700ustar00rootroot00000000000000module top; // An undefined sequence value is an error. enum {udef[1'bx]} udef1; enum {udef1[1'bx:1]} udef2; enum {udef2[1:1'bx]} udef3; enum {udefb[1'bx:1'bx]} udef4; enum {uval[1'bx] = 1} uval1; enum {uval1[1'bx:1] = 1} uval2; enum {uval2[1:1'bx] = 1} uval3; enum {uvalb[1'bx:1'bx] = 1} uval4; // A zero sequence value is an error. enum {zdef[0]} zdef1; enum {zval[0] = 1} zval1; // A negative sequence value is an error. enum {ndef[-1]} ndef1; enum {ndef1[-1:0]} ndef2; enum {ndef2[0:-1]} ndef3; enum {ndefb[-1:-1]} ndef4; enum {nval[-1] = 1} nval1; enum {nval1[-1:0] = 1} nval2; enum {nval2[0:-1] = 1} nval3; enum {nvalb[-1:-1] = 1} nval4; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366217e.v000066400000000000000000000020031435245347300202660ustar00rootroot00000000000000module top; reg passed; // These should be OK enum {zdef1_[0:1]} zdef1; enum {zdef2_[1:0]} zdef2; enum {zdefb_[0:0]} zdef3; enum {zvalb_[0:0] = 1} zval1; initial begin passed = 1'b1; if (zdef1_0 !== 0) begin $display("FAILED: expected zdef1_0 to be 0, got %0d", zdef1_0); passed = 1'b0; end if (zdef1_1 !== 1) begin $display("FAILED: expected zdef1_1 to be 1, got %0d", zdef1_1); passed = 1'b0; end if (zdef2_1 !== 0) begin $display("FAILED: expected zdef2_1 to be 0, got %0d", zdef2_1); passed = 1'b0; end if (zdef2_0 !== 1) begin $display("FAILED: expected zdef2_0 to be 1, got %0d", zdef2_0); passed = 1'b0; end if (zdefb_0 !== 0) begin $display("FAILED: expected zdefb_0 to be 0, got %0d", zdefb_0); passed = 1'b0; end if (zvalb_0 !== 1) begin $display("FAILED: expected zvalb_0 to be 1, got %0d", zvalb_0); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3366217f.v000066400000000000000000000011571435245347300203000ustar00rootroot00000000000000module top; // This should be valid. The Icarus compiler keeps these as negatives, but // the run time doesn't support negative values. enum bit signed [7:0] {rn = -1, yn = -2, gn = -3} nl; integer val; initial begin nl = rn; $display("First: %d", nl); nl = nl.next; $display("Second: %d", nl); nl = nl.next; $display("Third: %d", nl); nl = nl.next; $display("Wrapped: %d", nl); nl = nl.prev; $display("Wrapped: %d", nl); val = nl; $display("As integer: %d", val); end // This should be a signed value! initial #1 $display("Compile: ", rn); endmodule iverilog-12_0/ivtest/ivltests/pr3366217g.v000066400000000000000000000002601435245347300202730ustar00rootroot00000000000000module top; // You can't have duplicate values! enum {red = 1, green, blue = 2} light; enum {first = 2, second = 1, third} nums; initial $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr3366217h.v000066400000000000000000000033631435245347300203030ustar00rootroot00000000000000module top; reg pass; enum bit signed [7:0] {a = 1, b = 2, c = 3, d = 4} enum_var; initial begin pass = 1'b1; // Add another test that a negative value is not valid. // Also an out of range value stays out of range. enum_var = a; if (enum_var !== enum_var.first) begin $display("FAILED: initialization, expected %d, got %d", a, enum_var); pass = 1'b0; end enum_var = enum_var.next; enum_var = enum_var.prev; enum_var = enum_var.next(); if (enum_var !== b) begin $display("FAILED: next(), expected %d, got %d", b, enum_var); pass = 1'b0; end enum_var = enum_var.next(0); if (enum_var !== b) begin $display("FAILED: next(0), expected %d, got %d", b, enum_var); pass = 1'b0; end enum_var = enum_var.next(1); if (enum_var !== c) begin $display("FAILED: next(1), expected %d, got %d", c, enum_var); pass = 1'b0; end enum_var = enum_var.next(2); if (enum_var !== a) begin $display("FAILED: next(2), expected %d, got %d", a, enum_var); pass = 1'b0; end enum_var = enum_var.prev(); if (enum_var !== d) begin $display("FAILED: prev(), expected %d, got %d", d, enum_var); pass = 1'b0; end enum_var = enum_var.prev(0); if (enum_var !== d) begin $display("FAILED: prev(0), expected %d, got %d", d, enum_var); pass = 1'b0; end enum_var = enum_var.prev(1); if (enum_var !== c) begin $display("FAILED: prev(1), expected %d, got %d", c, enum_var); pass = 1'b0; end enum_var = enum_var.prev(2); if (enum_var !== a) begin $display("FAILED: prev(2), expected %d, got %d", a, enum_var); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3366217i.v000066400000000000000000000023521435245347300203010ustar00rootroot00000000000000/* * Check that the initial value can be out of range and that the next()/prev() * enumeration methods do not change to a defined state. */ module top; reg pass; enum bit [3:0] {a2 = 1, b2 = 2, c2 = 3, d2 = 4} evar2; enum reg [3:0] {a4 = 1, b4 = 2, c4 = 3, d4 = 4} evar4; initial begin pass = 1'b1; if (evar2 !== 0) begin $display("Failed initial/2 value should be 0, got %d", evar2); pass = 1'b0; end if (evar4 !== 4'bx) begin $display("Failed initial/4 value should be 'bx, got %d", evar4); pass = 1'b0; end evar2 = evar2.next; if (evar2 !== 0) begin $display("Failed next/2 of an invalid value should be 0, got %d", evar2); pass = 1'b0; end evar4 = evar4.next; if (evar4 !== 4'bx) begin $display("Failed next/4 of an invalid value should be 0, got %d", evar4); pass = 1'b0; end evar2 = evar2.prev; if (evar2 !== 0) begin $display("Failed prev/2 of an invalid value should be 0, got %d", evar2); pass = 1'b0; end evar4 = evar4.prev; if (evar4 !== 4'bx) begin $display("Failed prev/4 of an invalid value should be 0, got %d", evar4); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3368642.v000066400000000000000000000015001435245347300201260ustar00rootroot00000000000000module bug; reg [3:0] r1; wire [3:0] w1; wire [3:0] w2; assign w1 = r1; assign w2 = w1; reg fail = 0; initial begin r1 = 0; #1 $display("%b %b %b", r1, w1, w2); if ((r1 !== 4'b0000) || (w1 !== 4'b0000) || (w2 !== 4'b0000)) fail = 1; force w1 = 4'bz; #1 $display("%b %b %b", r1, w1, w2); if ((r1 !== 4'b0000) || (w1 !== 4'bzzzz) || (w2 !== 4'bzzzz)) fail = 1; r1 = 1; #1 $display("%b %b %b", r1, w1, w2); if ((r1 !== 4'b0001) || (w1 !== 4'bzzzz) || (w2 !== 4'bzzzz)) fail = 1; release w1; #1 $display("%b %b %b", r1, w1, w2); if ((r1 !== 4'b0001) || (w1 !== 4'b0001) || (w2 !== 4'b0001)) fail = 1; r1 = 2; #1 $display("%b %b %b", r1, w1, w2); if ((r1 !== 4'b0010) || (w1 !== 4'b0010) || (w2 !== 4'b0010)) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr338.v000066400000000000000000000017731435245347300176200ustar00rootroot00000000000000// // Copyright (c) 2001 Stephan Gehring (stephan.gehring@@ieee.org) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Has a constant 'hzz that blows up icarus module Bug; reg [7:0] x; initial begin x = 'h4000 + 'hzz; // iverilog doesn't like 'hzz end endmodule iverilog-12_0/ivtest/ivltests/pr3390385.v000066400000000000000000000013721435245347300201340ustar00rootroot00000000000000module tb; reg [1:0] i, j; reg [3:0] x[0:2]; reg error; initial begin error = 0; i = 0; j = i++; if (i !== 2'b01 || j !== 2'b00) begin $display("FAILED j = i++ --> j=%b, i=%b", j, i); error = 1; end i = 0; x[0] = 4'dx; x[1] = 4'dx; x[i++] = 0; if (x[0] !== 4'd0 || x[1] !== 4'dx) begin $display("FAILED x[i++] = 0 --> x[0]=%b, x[1]=%b, i=%b", x[0], x[1], i); error = 1; end i = 0; x[0] = 1; x[i++] += 2; if (x[0] !== 4'd3) begin $display("FAILED x[0] should be 3, but it is %d.", x[0]); error = 1; end if (i !== 2'd1) begin $display("FAILED i should be 1, but it is %d.", i); error = 1; end if (error == 0) $display("PASSED"); end endmodule // tb iverilog-12_0/ivtest/ivltests/pr3390385b.v000066400000000000000000000013661435245347300203010ustar00rootroot00000000000000module tb; reg [1:0] i, j; reg [3:0] x[0:2]; reg error; initial begin error = 0; i = 0; j = i++; if (i !== 2'b01 || j !== 2'b00) begin $display("FAILED j = i++ --> j=%b, i=%b", j, i); error = 1; end i = 0; x[0] = 4'dx; x[1] = 4'dx; x[0] = 0; if (x[0] !== 4'd0 || x[1] !== 4'dx) begin $display("FAILED x[i++] = 0 --> x[0]=%b, x[1]=%b, i=%b", x[0], x[1], i); error = 1; end i = 0; x[0] = 1; x[0] += 2; if (x[0] !== 4'd3) begin $display("FAILED x[0] should be 3, but it is %d.", x[0]); error = 1; end if (i !== 2'd0) begin $display("FAILED i should be 1, but it is %d.", i); error = 1; end if (error == 0) $display("PASSED"); end endmodule // tb iverilog-12_0/ivtest/ivltests/pr3390385c.v000066400000000000000000000013761435245347300203030ustar00rootroot00000000000000module tb; reg [1:0] i, j; reg [3:0] x; reg error; initial begin error = 0; i = 0; j = i++; if (i !== 2'b01 || j !== 2'b00) begin $display("FAILED j = i++ --> j=%b, i=%b", j, i); error = 1; end i = 0; x[0] = 1'bx; x[1] = 1'bx; x[i++] = 1'b0; if (x[0] !== 1'b0 || x[1] !== 1'bx) begin $display("FAILED x[i++] = 0 --> x[0]=%b, x[1]=%b, i=%b", x[0], x[1], i); error = 1; end i = 0; x[0] = 1'b1; x[i++] += 1'b1; if (x[0] !== 1'b0) begin $display("FAILED x[0] should be 0, but it is %b.", x[0]); error = 1; end if (i !== 2'd1) begin $display("FAILED i should be 1, but it is %d.", i); error = 1; end if (error == 0) $display("PASSED"); end endmodule // tb iverilog-12_0/ivtest/ivltests/pr3390385d.v000066400000000000000000000013721435245347300203000ustar00rootroot00000000000000module tb; reg [1:0] i, j; reg [3:0] x; reg error; initial begin error = 0; i = 0; j = i++; if (i !== 2'b01 || j !== 2'b00) begin $display("FAILED j = i++ --> j=%b, i=%b", j, i); error = 1; end i = 0; x[0] = 1'bx; x[1] = 1'bx; x[0] = 1'b0; if (x[0] !== 1'b0 || x[1] !== 1'bx) begin $display("FAILED x[i++] = 0 --> x[0]=%b, x[1]=%b, i=%b", x[0], x[1], i); error = 1; end i = 0; x[0] = 1'b1; x[0] += 1'b1; if (x[0] !== 1'b0) begin $display("FAILED x[0] should be 0, but it is %b.", x[0]); error = 1; end if (i !== 2'd0) begin $display("FAILED i should be 1, but it is %d.", i); error = 1; end if (error == 0) $display("PASSED"); end endmodule // tb iverilog-12_0/ivtest/ivltests/pr3409749.v000066400000000000000000000022321435245347300201350ustar00rootroot00000000000000module top; reg pass = 1'b1; genvar lp; for (lp=1; lp <= 128; lp = lp + 1) begin: loop test #(lp) dut(); end initial #1000 if (pass) $display("PASSED"); endmodule module test; parameter wid = 62; localparam X = {4'b1000, {wid{1'b0}}}; localparam Y = {1'b1, {wid{1'b0}}}; reg [wid:0] y = Y; reg [wid+3:0] x = X; reg [3:0] res; initial begin #wid; // Wait for the x and y values to get assigned. res = X/Y; if (res !== 4'b1000) begin $display("Failed const. division for %3d, expected 4'b1000, got %b", wid, res); top.pass = 1'b0; end res = X/y; if (res !== 4'b1000) begin $display("Failed const. numerator for %3d, expected 4'b1000, got %b", wid, res); top.pass = 1'b0; end res = x/Y; if (res !== 4'b1000) begin $display("Failed const. denominator for %3d, expected 4'b1000, got %b", wid, res); top.pass = 1'b0; end res = x/y; if (res !== 4'b1000) begin $display("Failed variable division for %3d, expected 4'b1000, got %b", wid, res); top.pass = 1'b0; end end endmodule iverilog-12_0/ivtest/ivltests/pr3437290a.v000066400000000000000000000005311435245347300202660ustar00rootroot00000000000000module top; reg a, b, c, d, e; wor out; assign out = a; assign out = b; assign out = c; assign out = d; assign out = e; initial begin a = 1'b0; b = 1'b0; c = 1'b1; d = 1'b0; e = 1'b0; #1; if (out !== 1'b1) $display("FAILED: expected 1'b1, got %b", out); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3437290b.v000066400000000000000000000013001435245347300202620ustar00rootroot00000000000000module top; localparam wid = 7; localparam vec_wid = $clog2(wid+1)-1; reg pass; reg [vec_wid:0] mem [wid:0]; reg [wid:0] sel; wor [vec_wid:0] out; integer lp; genvar i; for (i = 0; i <= wid; i = i + 1) assign out = sel[i] ? mem[i] : {wid{1'b0}}; initial begin pass = 1'b1; for (lp = 0; lp <= wid; lp = lp + 1) begin mem[lp] = lp; end for (lp = 0; lp <= wid; lp = lp + 1) begin sel = 2**lp; #1; if (out !== mem[lp]) begin $display("FAILED: mem[%0d] %b != %b (%b)", lp, mem[lp], out, sel); pass = 1'b0; end else $display("OK: mem[%0d] %b (%b)", lp, out, sel); end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3437290c.v000066400000000000000000000005321435245347300202710ustar00rootroot00000000000000module top; reg a, b, c, d, e; wand out; assign out = a; assign out = b; assign out = c; assign out = d; assign out = e; initial begin a = 1'b1; b = 1'b0; c = 1'b1; d = 1'b1; e = 1'b1; #1; if (out !== 1'b0) $display("FAILED: expected 1'b1, got %b", out); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3441576.v000066400000000000000000000001401435245347300201230ustar00rootroot00000000000000module top; reg foo; always @* foo <= 0; initial #1 $display("foo is %b", foo); endmodule iverilog-12_0/ivtest/ivltests/pr3445452.v000066400000000000000000000012371435245347300201300ustar00rootroot00000000000000module task_time_arg; reg pass; integer result; task test_it1; realtime tmp; begin tmp = $realtime; go_busy(tmp); end endtask task test_it2; go_busy($realtime); endtask task go_busy; input delay; integer delay; result = delay; endtask // go_busy initial begin pass = 1'b1; #6 test_it1; if (result !== 6) begin $display("Failed: testit1, expected 6, got %d", result); pass = 1'b0; end #1 test_it2; if (result !== 7) begin $display("Failed: testit2, expected 7, got %d", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3452808.v000066400000000000000000000053631435245347300201370ustar00rootroot00000000000000/*********************************************************************** * * Copyright (C) 2011 Adrian Wise * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * *********************************************************************** * * This is a testbench exercising gate-level modelling of DTL gates, * distilled down (as a test-case) from a much larger design. * The gates can only pull down strongly to ground and have a weak * pull-up. * **********************************************************************/ `timescale 1 ns / 100 ps module dtl_inv (op, in1); output op; input in1; not (strong0, pull1) #16 not1 (op, in1); endmodule // dtl_inv module sr_latch (p, n); inout p; inout n; dtl_inv u_p1 ( .in1 ( n ) , .op ( p ) ); dtl_inv u_n1 ( .in1 ( p ) , .op ( n ) ); endmodule // sr_latch module dut (pp, nn); inout [1:0] pp; inout [1:0] nn; sr_latch u_l1 (pp[0], nn[0]); endmodule // dut module top; reg pass; reg x; wire [1:0] pp; wire [1:0] nn; dtl_inv u_pp0(.in1(~x), .op(pp[0])); dtl_inv u_nn0(.in1( x), .op(nn[0])); dut u_d1 (pp, nn); initial begin pass = 1'b1; x <= 2'd0; #100; $display("Expect: x = 0, pp = z0, nn = z1 p=0, n=1"); $display("Actual: x = %b, pp = %b, nn = %b p=%b, n=%b", x, pp, nn, u_d1.u_l1.p, u_d1.u_l1.n); if (x !== 1'b0) begin $display("Failed: expected x to be 0, got %b", x); pass = 1'b0; end if (pp !== 2'bz0) begin $display("Failed: expected pp to be z0, got %b", pp); pass = 1'b0; end if (nn !== 2'bz1) begin $display("Failed: expected nn to be z0, got %b", nn); pass = 1'b0; end if (u_d1.u_l1.p !== 1'b0) begin $display("Failed: expected p to be 0, got %b", u_d1.u_l1.p); pass = 1'b0; end if (u_d1.u_l1.n !== 1'b1) begin $display("Failed: expected n to be 1, got %b", u_d1.u_l1.n); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule // top iverilog-12_0/ivtest/ivltests/pr3462145.v000066400000000000000000000003401435245347300201200ustar00rootroot00000000000000module tb; reg [1:0] i; reg [3:0] x[0:2]; initial begin x[1] = 1; i = 1; x[i++] += 2; if (x[1] != 3) $display("FAILED: got %b", x[1]); else $display("PASSED"); end endmodule // tb iverilog-12_0/ivtest/ivltests/pr3465541.v000066400000000000000000000046741435245347300201410ustar00rootroot00000000000000/*********************************************************************** * * Copyright (C) 2011 Adrian Wise * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * *********************************************************************** * * This is a testbench exercising gate-level modelling of DTL gates, * distilled down (as a test-case) from a much larger design. * The gates can only pull down strongly to ground and have a weak * pull-up. * * This illustrates a problem in the git master branch as of 24 December * 2011, where a gate that does not pull-up strongly cannot drive a bit * of a bus (to either logic level), but can drive a single-bit wire * correctly. * * This is an extended version of the test case provided with the * bug report, to cover part selects with a non-zero base, and to * make the error checking a bit more robust. **********************************************************************/ `timescale 1 ns / 100 ps module dtl_inv (op, in1); output op; input in1; not (strong0, pull1) #16 not1 (op, in1); endmodule // dtl_inv module top; reg d; wire w; wire [1:0] b; reg pass; dtl_inv u_1 (.op(w), .in1(d)); dtl_inv u_2 (.op(b[0]), .in1(d)); dtl_inv u_3 (.op(b[1]), .in1(b[0])); initial begin pass = 1'b1; d = 1'b0; # 100; if ((w !== 1'b1) || (b[0] !== 1'b1) || (b[1] !== 1'b0)) begin $display("Failed (w !== b[0]): d = %b, w = %b, b = %b", d, w, b); pass = 1'b0; end d = 1'b1; # 100; if ((w !== 1'b0) || (b[0] !== 1'b0) || (b[1] !== 1'b1)) begin $display("Failed (w !== b[0]): d = %b, w = %b, b = %b", d, w, b); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule // top iverilog-12_0/ivtest/ivltests/pr3477107.v000066400000000000000000000013621435245347300201310ustar00rootroot00000000000000`begin_keywords "1364-2005" `timescale 1ns/1ns module test; reg fail = 0; task check; input [10*8:1] expect; reg [10*8:1] s; begin $swrite(s, "Time %t", $time); $write("%s", s); if (s === expect) $display(""); else begin $display(" != %s", expect); fail = 1; end end endtask initial begin $display("Test display formatting of time values"); $timeformat(-6, 3, " us", 20); fork #0000 check(" 0.000 us"); #0001 check(" 0.001 us"); #0010 check(" 0.010 us"); #0011 check(" 0.011 us"); #0100 check(" 0.100 us"); #0101 check(" 0.101 us"); #1000 check(" 1.000 us"); #1001 check(" 1.001 us"); join $display("%s", fail? "FAILED" : "PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr3499807.v000066400000000000000000000003421435245347300201410ustar00rootroot00000000000000module pr3499807(); supply0 gnd; wire net1; wire net2; tranif0 #(100) sw1(gnd, net1, gnd); tranif0 #(200) sw2(gnd, net2, gnd); initial begin $monitor($time,, gnd,, net1,, net2); #300; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr3515542.v000066400000000000000000000002161435245347300201220ustar00rootroot00000000000000module top; integer a; initial begin a = 15'1; a = 15'0; a = 15'x; a = 15'X; a = 15'z; a = 15'Z; end endmodule iverilog-12_0/ivtest/ivltests/pr3522653.v000066400000000000000000000004411435245347300201230ustar00rootroot00000000000000module test(); initial begin $display("%b", 'h00000001); $display("%d", 'h00000001); $display("%b", 'hffffffff); $display("%d", 'hffffffff); $display("%b", 'sh00000001); $display("%d", 'sh00000001); $display("%b", 'shffffffff); $display("%d", 'shffffffff); end endmodule iverilog-12_0/ivtest/ivltests/pr3527022.v000066400000000000000000000035511435245347300201230ustar00rootroot00000000000000module test #( parameter integer i1 = 1.0, i2 = 2, parameter [7:0] v1 = 3.0, v2 = 4, parameter real r1 = 5.0, r2 = 6, parameter u1 = 7.0, u2 = 8'd8 )( ); parameter integer i3 = 1.0, i4 = 2; parameter [7:0] v3 = 3.0, v4 = 4; parameter real r3 = 5.0, r4 = 6; parameter u3 = 7.0, u4 = 8'd8; localparam integer i5 = 1.0, i6 = 2; localparam [7:0] v5 = 3.0, v6 = 4; localparam real r5 = 5.0, r6 = 6; localparam u5 = 7.0, u6 = 8'd8; reg failed = 0; initial begin $display("%b", i1); $display("%b", i2); $display("%b", v1); $display("%b", v2); $display("%f", r1); $display("%f", r2); $display("%f", u1); $display("%b", u2); if (i1 !== 32'd1) failed = 1; if (i2 !== 32'd2) failed = 1; if (v1 !== 8'd3) failed = 1; if (v2 !== 8'd4) failed = 1; if (r1 != 5.0) failed = 1; if (r2 != 6.0) failed = 1; if (u1 != 7.0) failed = 1; if (u2 !== 8'd8) failed = 1; $display("%b", i3); $display("%b", i4); $display("%b", v3); $display("%b", v4); $display("%f", r3); $display("%f", r4); $display("%f", u3); $display("%b", u4); if (i3 !== 32'd1) failed = 1; if (i4 !== 32'd2) failed = 1; if (v3 !== 8'd3) failed = 1; if (v4 !== 8'd4) failed = 1; if (r3 != 5.0) failed = 1; if (r4 != 6.0) failed = 1; if (u3 != 7.0) failed = 1; if (u4 !== 8'd8) failed = 1; $display("%b", i5); $display("%b", i6); $display("%b", v5); $display("%b", v6); $display("%f", r5); $display("%f", r6); $display("%f", u5); $display("%b", u6); if (i5 !== 32'd1) failed = 1; if (i6 !== 32'd2) failed = 1; if (v5 !== 8'd3) failed = 1; if (v6 !== 8'd4) failed = 1; if (r5 != 5.0) failed = 1; if (r6 != 6.0) failed = 1; if (u5 != 7.0) failed = 1; if (u6 !== 8'd8) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3527694.v000066400000000000000000000035761435245347300201510ustar00rootroot00000000000000`timescale 1ns / 1ps module top; reg sys_clk; reg sys_reset; integer cnt, lastcnt; initial begin sys_clk = 1'b1; sys_reset = 1'b1; cnt = 0; lastcnt = 100; while(cnt < lastcnt) begin #5; sys_clk = 1'b0; #5; sys_clk = 1'b1; if(cnt > 10) begin sys_reset = 1'b0; end cnt = cnt + 1; end #20; $dumpflush; $finish(2); $stop(2); end test1 #( .WIDTH1(18), .WIDTH2(18) ) test1 ( .sys_clk(sys_clk), .sys_rst(sys_reset) ); test2 #( .WIDTH1(18), .WIDTH2(18) ) test2_top ( .sys_clk(sys_clk), .sys_rst(sys_reset) ); endmodule module test1 #( parameter WIDTH1 = 1, parameter WIDTH2 = 2 ) ( input sys_clk, input sys_rst ); wire [15:0] w1 = WIDTH1; wire [15:0] w2 = WIDTH2; generate if(WIDTH1 != 1) begin: not1 test2 #( .WIDTH1(18), .WIDTH2(18) ) test2_0 ( .sys_clk(sys_clk), .sys_rst(sys_rst) ); test2 #( .WIDTH1(18), .WIDTH2(18) ) test2_1 ( .sys_clk(sys_clk), .sys_rst(sys_rst) ); end endgenerate initial begin #40; $finish(0); end endmodule module test2 #( parameter WIDTH1 = 3, parameter WIDTH2 = 4 ) ( input sys_clk, input sys_rst ); localparam big_width = (WIDTH1 >= WIDTH2) ? WIDTH1 : WIDTH2; initial begin $display("%m big_width: %h", big_width); end wire [15:0] w1 = WIDTH1; wire [15:0] w2 = WIDTH2; wire [15:0] bigw = big_width; wire [31:0] out_data_a, out_data_b; test3 #( .WIDTH1(WIDTH1), .WIDTH2(WIDTH2) ) test3_0 ( .sys_clk(sys_clk), .sys_rst(sys_rst) ); test3 test3_1 ( .sys_clk(sys_clk), .sys_rst(sys_rst) ); defparam test3_1.WIDTH1 = WIDTH1; defparam test3_1.WIDTH2 = WIDTH2; endmodule module test3 (sys_clk, sys_rst); input sys_clk; input sys_rst; parameter WIDTH1 = 0; parameter WIDTH2 = 0; localparam big_width = (WIDTH1 >= WIDTH2) ? WIDTH1 : WIDTH2; wire [31:0] wide = big_width; wire [31:0] width1 = WIDTH1; wire [31:0] width2 = WIDTH2; initial begin $strobe("%m wide: %h, width1:%h, width2:%h", wide, width1, width2); end endmodule iverilog-12_0/ivtest/ivltests/pr3534333.v000066400000000000000000000007001435245347300201170ustar00rootroot00000000000000module pr3534333(); /* Check compiler accepts null statements in blocks */ integer count = 0; initial begin end initial begin (* my_attr = 0 *) ; end initial begin (* my_attr = 0 *) ; #1 count = count + 1; end initial begin #2 count = count + 1; (* my_attr = 0 *) ; end initial begin ; #3 count = count + 1; ; end initial begin #4;; if (count === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3534422.v000066400000000000000000000005461435245347300201260ustar00rootroot00000000000000module bug(); reg [3:0] flags = 4'b0000; generate genvar i; for (i = 1; i < 4; i = i + 1) begin:loop localparam j = i; if (j > 0) begin initial #1 flags[j] = 1'b1; end end endgenerate initial begin #2 $display("flags = %b", flags); if (flags === 4'b1110) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3539372.v000066400000000000000000000002611435245347300201310ustar00rootroot00000000000000module test; parameter x = "String with escaped backslash at end \\"; initial `ifdef __ICARUS__ $display("PASSED"); `else $display("Not Icarus\nPASSED"); `endif endmodule iverilog-12_0/ivtest/ivltests/pr3549328.v000066400000000000000000000004231435245347300201330ustar00rootroot00000000000000// Check compiler can handle zero widths in indexed // part selects. module bug(); localparam off1 = 1; localparam wid1 = 0; integer off2 = 1; integer wid2 = 0; wire [7:0] vector = 8'h55; wire part1 = |vector[off1 +: wid1]; wire part2 = |vector[off2 +: wid2]; endmodule iverilog-12_0/ivtest/ivltests/pr355.v000066400000000000000000000040501435245347300176060ustar00rootroot00000000000000/* * Copyright (c) 2001 Ted Bullen * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // This code is released to Steve Williams for the Icarus Verilog compiler // It can be used as desired ! // DEFINES `define NRBITS 4 // Number of bits in each operand // TOP MODULE module testFunction(); // SIGNAL DECLARATIONS reg clock; reg [`NRBITS-1:0] a_in; integer a_integer; integer myint; reg [`NRBITS:0] cycle_count; // Counts valid clock cycles // Initialize inputs initial begin clock = 1; cycle_count = 0; # (16*200+15) $display("PASSED"); $finish; end // Generate the clock always #100 clock = ~clock; // Simulate always @(negedge clock) begin cycle_count = cycle_count + 1; // Create inputs between 0 and all 1s a_in = cycle_count[`NRBITS-1:0]; myint = a_in; $display("a_in = %d, myint = %d", a_in, myint); // Convert the unsigned numbers to signed numbers a_integer = short_to_int(a_in); if (myint !== a_integer) begin $display("ERROR ! %d !== %d", myint, a_integer); $stop; end end // Function to convert a reg of `NRBITS // bits to a signed integer function integer short_to_int; input [`NRBITS-1:0] x; begin short_to_int = x; $display("\tshort_to_int(%b) = %b", x, short_to_int); end endfunction endmodule iverilog-12_0/ivtest/ivltests/pr3557493.v000066400000000000000000000017641435245347300201460ustar00rootroot00000000000000module m1(); parameter p = 0; endmodule module m2(); generate genvar i; for (i = 0; i < 2; i = i + 1) begin : Loop1 m1 m(); defparam m.p = 1 + i; end for (i = 2; i < 4; i = i + 1) begin : Loop2 m1 m(); defparam Loop2[i].m.p = 1 + i; end for (i = 4; i < 6; i = i + 1) begin : Loop3 m1 m(); defparam m2.Loop3[i].m.p = 1 + i; end endgenerate reg failed = 0; initial begin $display("Loop1[0].m.p = %0d", Loop1[0].m.p); if (Loop1[0].m.p !== 1) failed = 1; $display("Loop1[1].m.p = %0d", Loop1[1].m.p); if (Loop1[1].m.p !== 2) failed = 1; $display("Loop2[2].m.p = %0d", Loop2[2].m.p); if (Loop2[2].m.p !== 3) failed = 1; $display("Loop2[3].m.p = %0d", Loop2[3].m.p); if (Loop2[3].m.p !== 4) failed = 1; $display("Loop3[4].m.p = %0d", Loop3[4].m.p); if (Loop3[4].m.p !== 5) failed = 1; $display("Loop3[5].m.p = %0d", Loop3[5].m.p); if (Loop3[5].m.p !== 6) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3561350.v000066400000000000000000000005361435245347300201250ustar00rootroot00000000000000module pr3561350(); reg [31:0] source; reg [31:0] result; initial begin source = 10; // the following expression results in a compiler internal error result = (source * 2) + 2 + 3 + 4; // check we get the expected result when the bug has been fixed if (result === 29) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3563412.v000066400000000000000000000157241435245347300201330ustar00rootroot00000000000000module test; initial begin $display("Error: \"FloatTest.bsv\", line 234, column 24: (R0001)\n Mutually exclusive rules (from the ME sets [RL_action_l234c24] and\n [RL_action_l235c24, RL_action_l236c24, RL_action_l237c24, RL_action_l238c24,\n RL_action_l239c24, RL_action_l240c24, RL_action_l241c24, RL_action_l242c24,\n RL_action_l243c24, RL_action_l244c24, RL_action_l245c24, RL_action_l246c24,\n RL_action_l247c24, RL_action_l248c24, RL_action_l249c24, RL_action_l250c24,\n RL_action_l251c24, RL_action_l252c24, RL_action_l253c24, RL_action_l255c24,\n RL_action_l256c24, RL_action_l257c24, RL_action_l258c24, RL_action_l259c24,\n RL_action_l260c24, RL_action_l261c24, RL_action_l262c24, RL_action_l263c24,\n RL_action_l264c24, RL_action_l265c24, RL_action_l266c24, RL_action_l267c24,\n RL_action_l268c24, RL_action_l269c24, RL_action_l270c24, RL_action_l271c24,\n RL_action_l272c24, RL_action_l273c24, RL_action_l274c24, RL_action_l276c24,\n RL_action_l277c24, RL_action_l278c24, RL_action_l279c24, RL_action_l280c24,\n RL_action_l281c24, RL_action_l282c24, RL_action_l283c24, RL_action_l284c24,\n RL_action_l285c24, RL_action_l286c24, RL_action_l287c24, RL_action_l288c24,\n RL_action_l289c24, RL_action_l290c24, RL_action_l291c24, RL_action_l292c24,\n RL_action_l293c24, RL_action_l294c24, RL_action_l295c24, RL_action_l297c24,\n RL_action_l298c24, RL_action_l299c24, RL_action_l300c24, RL_action_l301c24,\n RL_action_l302c24, RL_action_l303c24, RL_action_l304c24, RL_action_l305c24,\n RL_action_l306c24, RL_action_l307c24, RL_action_l308c24, RL_action_l309c24,\n RL_action_l310c24, RL_action_l311c24, RL_action_l312c24, RL_action_l313c24,\n RL_action_l314c24, RL_action_l315c24, RL_action_l316c24, RL_action_l318c24,\n RL_action_l319c24, RL_action_l320c24, RL_action_l321c24, RL_action_l322c24,\n RL_action_l323c24, RL_action_l324c24, RL_action_l326c24, RL_action_l327c24,\n RL_action_l328c24, RL_action_l329c24, RL_action_l330c24, RL_action_l331c24,\n RL_action_l332c24, RL_action_l333c24, RL_action_l334c24, RL_action_l335c24,\n RL_action_l336c24, RL_action_l337c24, RL_action_l338c24, RL_action_l339c24,\n RL_action_l340c24, RL_action_l341c24, RL_action_l342c24, RL_action_l343c24,\n RL_action_l344c24, RL_action_l345c24, RL_action_l348c18, RL_action_l353c22,\n RL_action_l354c22, RL_action_l355c22, RL_action_l356c22, RL_action_l357c22,\n RL_action_l358c22, RL_action_l359c22, RL_action_l360c22, RL_action_l361c22,\n RL_action_l362c22, RL_action_l363c22, RL_action_l364c22, RL_action_l365c22,\n RL_action_l366c22, RL_action_l367c22, RL_action_l368c22, RL_action_l369c22,\n RL_action_l370c22, RL_action_l371c22, RL_action_l372c22, RL_action_l374c22,\n RL_action_l376c22, RL_action_l377c22, RL_action_l378c22, RL_action_l379c22,\n RL_action_l381c22, RL_action_l383c22, RL_action_l384c22, RL_action_l386c22,\n RL_action_l387c22, RL_action_l390c18, RL_action_l395c23, RL_action_l396c23,\n RL_action_l398c23, RL_action_l399c23, RL_action_l400c23, RL_action_l401c23,\n RL_action_l402c23, RL_action_l403c23, RL_action_l404c23, RL_action_l405c23,\n RL_action_l406c23, RL_action_l407c23, RL_action_l408c23, RL_action_l409c23,\n RL_action_l410c23, RL_action_l411c23, RL_action_l412c23, RL_action_l413c23,\n RL_action_l414c23, RL_action_l415c23, RL_action_l416c23, RL_action_l417c23,\n RL_action_l419c23, RL_action_l420c23, RL_action_l421c23, RL_action_l422c23,\n RL_action_l423c23, RL_action_l424c23, RL_action_l425c23, RL_action_l426c23,\n RL_action_l427c23, RL_action_l428c23, RL_action_l429c23, RL_action_l430c23,\n RL_action_l431c23, RL_action_l432c23, RL_action_l433c23, RL_action_l434c23,\n RL_action_l435c23, RL_action_l436c23, RL_action_l437c23, RL_action_l438c23,\n RL_action_l441c18, RL_action_l446c28, RL_action_l447c28, RL_action_l448c28,\n RL_action_l449c28, RL_action_l450c28, RL_action_l451c28, RL_action_l452c28,\n RL_action_l453c28, RL_action_l455c28, RL_action_l456c28, RL_action_l457c28,\n RL_action_l458c28, RL_action_l459c28, RL_action_l460c28, RL_action_l461c28,\n RL_action_l462c28, RL_action_l463c28, RL_action_l464c28, RL_action_l465c28,\n RL_action_l466c28, RL_action_l467c28, RL_action_l468c28, RL_action_l469c28,\n RL_action_l470c28, RL_action_l471c28, RL_action_l472c28, RL_action_l473c28,\n RL_action_l474c28, RL_action_l475c28, RL_action_l476c28, RL_action_l478c28,\n RL_action_l479c28, RL_action_l481c28, RL_action_l484c18, RL_action_l489c21,\n RL_action_l490c21, RL_action_l491c21, RL_action_l492c21, RL_action_l493c21,\n RL_action_l494c21, RL_action_l495c21, RL_action_l496c21, RL_action_l497c21,\n RL_action_l498c21, RL_action_l499c21, RL_action_l500c21, RL_action_l501c21,\n RL_action_l502c21, RL_action_l503c21, RL_action_l504c21, RL_action_l505c21,\n RL_action_l506c21, RL_action_l507c21, RL_action_l508c21, RL_action_l509c21,\n RL_action_l510c21, RL_action_l512c21, RL_action_l513c21, RL_action_l514c21,\n RL_action_l515c21, RL_action_l516c21, RL_action_l517c21, RL_action_l518c21,\n RL_action_l519c21, RL_action_l520c21, RL_action_l521c21, RL_action_l522c21,\n RL_action_l523c21, RL_action_l524c21, RL_action_l525c21, RL_action_l526c21,\n RL_action_l527c21, RL_action_l528c21, RL_action_l529c21, RL_action_l530c21,\n RL_action_l531c21, RL_action_l533c26, RL_action_l534c26, RL_action_l535c26,\n RL_action_l536c26, RL_action_l537c26, RL_action_l538c26, RL_action_l539c26,\n RL_action_l540c26, RL_action_l542c26, RL_action_l543c26, RL_action_l544c26,\n RL_action_l545c26, RL_action_l546c26, RL_action_l547c26, RL_action_l548c26,\n RL_action_l549c26, RL_action_l550c26, RL_action_l551c26, RL_action_l552c26,\n RL_action_l553c26, RL_action_l554c26, RL_action_l555c26, RL_action_l556c26,\n RL_action_l557c26, RL_action_l558c26, RL_action_l559c26, RL_action_l560c26,\n RL_action_l561c26, RL_action_l562c26, RL_action_l563c26, RL_action_l565c26,\n RL_action_l566c26, RL_action_l568c26, RL_action_l570c21, RL_action_l572c21,\n RL_action_l574c26, RL_action_l576c26, RL_action_l577c26, RL_action_l579c26,\n RL_action_l582c18, RL_action_l587c28, RL_action_l588c28, RL_action_l589c28,\n RL_action_l590c28, RL_action_l591c28, RL_action_l592c28, RL_action_l593c28,\n RL_action_l594c28, RL_action_l595c28, RL_action_l596c28, RL_action_l597c28,\n RL_action_l598c28, RL_action_l599c28, RL_action_l600c28, RL_action_l601c28,\n RL_action_l602c28, RL_action_l603c28, RL_action_l604c28, RL_action_l605c28,\n RL_action_l606c28, RL_action_l607c28, RL_action_l609c28, RL_action_l610c28,\n RL_action_l611c28, RL_action_l613c28, RL_action_l614c28, RL_action_l615c28,\n RL_action_l616c28, RL_action_l617c28, RL_action_l618c28, RL_action_l619c28,\n RL_action_l621c28, RL_action_l622c28, RL_action_l623c28, RL_action_l624c28,\n RL_action_l625c28, RL_action_l626c28, RL_action_l627c28, RL_action_l628c28,\n RL_action_l629c28, RL_action_l630c28, RL_action_l631c28, RL_action_l632c28,\n RL_action_l633c28, RL_action_l634c28, RL_action_l635c28, RL_action_l636c28,\n RL_action_l637c28, RL_action_l638c28, RL_action_l639c28, RL_action_l645c18,\n RL_action_l647c7] ) fired in the same clock cycle.\nPASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3571573.v000066400000000000000000000004251435245347300201320ustar00rootroot00000000000000module pr3571573; wire [6:1] top_io; data_test dut(.io(top_io)); initial begin #1 $display("%b", top_io); end endmodule module data_test(inout [6:1] io); wire [4:1] io1; wire io2; wire io3; assign io = {io3, io2, io1}; assign io1[3:2] = 2'b01; endmodule iverilog-12_0/ivtest/ivltests/pr3576165.v000066400000000000000000000013451435245347300201360ustar00rootroot00000000000000module top; reg pass; enum reg[0:0] { IDLE = 1'b0, BUSY = 1'b1 } state, next; initial begin pass = 1'b1; next = IDLE; if (state !== 1'bx) begin $display("FAILED initial state, got %b", state); pass = 1'b0; end #1; state = next; if (state !== 1'b0) begin $display("FAILED idle state, got %b", state); pass = 1'b0; end next = BUSY; #1; state <= next; if (state !== 1'b0) begin $display("FAILED still idle state, got %b", state); pass = 1'b0; end #1; if (state !== 1'b1) begin $display("FAILED busy state, got %b", state); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3582052.v000066400000000000000000000035351435245347300201310ustar00rootroot00000000000000module bug; reg [7:0] Data[0:3][0:15]; reg [7:0] Expect0; reg [7:0] Expect1; reg [7:0] Expect2; reg [7:0] Expect3; reg [7:0] Actual0; reg [7:0] Actual1; reg [7:0] Actual2; reg [7:0] Actual3; integer i; integer j; reg Failed = 0; initial begin for (i = 0; i < 4; i = i + 1) begin for (j = 0; j < 16; j = j + 1) begin Data[i][j] = (i << 4) + j; end end // this catches the original bug for (j = 0; j < 16; j = j + 1) begin Expect0 = 0*16 + j; Actual0 = Data[0][j]; Expect1 = 1*16 + j; Actual1 = Data[1][j]; Expect2 = 2*16 + j; Actual2 = Data[2][j]; Expect3 = 3*16 + j; Actual3 = Data[3][j]; $display("%h %h %h %h", Actual0, Actual1, Actual2, Actual3); if (Actual0 !== Expect0) Failed = 1; if (Actual1 !== Expect1) Failed = 1; if (Actual2 !== Expect2) Failed = 1; if (Actual3 !== Expect3) Failed = 1; end // extended tests to check the bug fix doesn't break anything else for (i = 0; i < 4; i = i + 1) begin Expect0 = i*16 + 0; Actual0 = Data[i][0]; Expect1 = i*16 + 3; Actual1 = Data[i][3]; Expect2 = i*16 + 6; Actual2 = Data[i][6]; Expect3 = i*16 + 9; Actual3 = Data[i][9]; $display("%h %h %h %h", Actual0, Actual1, Actual2, Actual3); if (Actual0 !== Expect0) Failed = 1; if (Actual1 !== Expect1) Failed = 1; if (Actual2 !== Expect2) Failed = 1; if (Actual3 !== Expect3) Failed = 1; end Expect0 = 0*16 + 0; Actual0 = Data[0][0]; Expect1 = 0*16 + 9; Actual1 = Data[0][9]; Expect2 = 3*16 + 0; Actual2 = Data[3][0]; Expect3 = 3*16 + 9; Actual3 = Data[3][9]; $display("%h %h %h %h", Actual0, Actual1, Actual2, Actual3); if (Actual0 !== Expect0) Failed = 1; if (Actual1 !== Expect1) Failed = 1; if (Actual2 !== Expect2) Failed = 1; if (Actual3 !== Expect3) Failed = 1; if (Failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr3587570.v000066400000000000000000000007211435245347300201350ustar00rootroot00000000000000primitive passthrough (o, i); input i; output o; table // i : o 1 : 1; 0 : 0; ? : 0; endtable endprimitive module test; reg i; wire o1, o1b, o2, o2b; initial begin i = 1'b0; #1; if ((o1 !== 1'b0) && (o1b !== 1'b1) && (o2 !== 1'b0) && (o2b !== 1'b1)) $display("FAILED"); else $display("PASSED"); end passthrough (o1, i); passthrough (o1b, !i); passthrough (o2, i); passthrough (o2b, ~i); endmodule iverilog-12_0/ivtest/ivltests/pr3592746.v000066400000000000000000000007571435245347300201470ustar00rootroot00000000000000module pr3592746(); reg Iteration; integer RepeatCount[1:0]; task RepeatTest; begin repeat(Iteration == 1 ? 3 : 2) begin $display("Iteration = %b", Iteration); RepeatCount[Iteration] = RepeatCount[Iteration] + 1; end end endtask initial begin RepeatCount[0] = 0; RepeatCount[1] = 0; Iteration = 0; RepeatTest; Iteration = 1; RepeatTest; if ((RepeatCount[0] == 2) && (RepeatCount[1] == 3)) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/pr377.v000066400000000000000000000004051435245347300176120ustar00rootroot00000000000000module dummy (.B(A[2:1])); input [2:1] A; always @(A) $display (A); endmodule module test (); reg [2:0] A; dummy dummy(A[1:0]); integer idx; initial begin for (idx = 0 ; idx <= 'h7 ; idx = idx+1) #1 A <= idx; #1 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr434.v000066400000000000000000000016321435245347300176070ustar00rootroot00000000000000/* * This tests is based on PR#434 */ `define VAR1 2 `define VAR2 5 module mctrl( reset0, reset1, reset2, reset3, clk, por); output reset0, reset1, reset2, reset3; input clk,por; reg [7:0] cnt; always @ (posedge por or posedge clk) if (por) cnt <= 0; else cnt <= cnt+1; assign reset0 = (cnt == `VAR1); assign reset1 = (cnt == `VAR2); assign reset2 = (cnt == `VAR1 + `VAR2); assign reset3 = (cnt == `VAR1 + `VAR2 + 2); endmodule `timescale 1ns/1ps module test(); reg clk,por; wire reset0, reset1, reset2, reset3; mctrl m1(reset0, reset1, reset2, reset3, clk, por); initial begin clk = 0; por = 0; $monitor($time,, "reset0=%b, reset1=%b, reset2=%b, reset3=%b", reset0, reset1, reset2, reset3); #1000 $finish(0); end always #15 clk = ~clk; initial begin #10 por = 1; #10 por = 0; end endmodule // test iverilog-12_0/ivtest/ivltests/pr445.v000066400000000000000000000001601435245347300176040ustar00rootroot00000000000000/* PR#445 */ module foo (); initial if (!(1'b0)) $display("PASSED"); else $display("FAILED"); endmodule iverilog-12_0/ivtest/ivltests/pr478.v000066400000000000000000000003111435245347300176100ustar00rootroot00000000000000/* * This is from iverilog issue # 1313453 * This point is that it should compile. */ module test `protect ( a ); // Input Declarations input a; `endprotect initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr487.v000066400000000000000000000005231435245347300176150ustar00rootroot00000000000000/* * This is the crux of PR487. */ module test(); parameter[1:4] async_wrport = 4'b1100; reg async_wri; reg[1:4] async_i; initial begin for(async_i=1;async_i<=4;async_i=async_i+1) begin async_wri=async_wrport[async_i]; $display("async_wrport[%d] --> %b", async_i, async_wri); end end endmodule iverilog-12_0/ivtest/ivltests/pr492.v000066400000000000000000000030101435245347300176030ustar00rootroot00000000000000/* * Copyright (c) 2002 Richard M. Myers * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ `timescale 10 ns/ 10 ns module top ; reg clk ; reg [11:0] x_os_integ, y_os_integ; reg [5:0] x_os, y_os; initial begin //$dumpfile("show_math.vcd"); //$dumpvars(1, top); clk = 1'h0 ; x_os = 6'h01; y_os = 6'h3f; x_os_integ = 12'h000; y_os_integ = 12'h000; end initial begin #60; forever #3 clk = ~clk ; // 16Mhz end always @( posedge clk ) begin // Integration period set above depending on configured modem speed. x_os_integ <= x_os_integ + {{6{x_os[5]}}, {x_os[5:0]}}; y_os_integ <= y_os_integ + {{6{y_os[5]}}, {y_os[5:0]}}; $display ("%x %x", x_os_integ, y_os_integ); end initial begin #200 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr498a.v000066400000000000000000000021771435245347300177670ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; test tt(); defparam tt.foo = 4; endmodule // main module test; parameter foo = 10; reg [foo-1:0] bar; initial begin if ($bits(bar) != 4) begin $display("FAILED -- $bits(bar) = %d", $bits(bar)); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/pr498b.v000066400000000000000000000020031435245347300177540ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; test tt(); defparam foo = 3; /* This should generate an error. */ endmodule // main module test; parameter foo = 10; reg [foo-1:0] bar; endmodule // test iverilog-12_0/ivtest/ivltests/pr508.v000066400000000000000000000005731435245347300176140ustar00rootroot00000000000000/* * This trivial example tickled PR508, where the thread * pointer in the event was uninitialized. This should * in general check the case of signaling events without * threads ever having waiting on it. */ module example; event my_event; initial -> my_event; reg [25:0] m26; wire [25:0] w26 = m26; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr509.v000066400000000000000000000002721435245347300176110ustar00rootroot00000000000000/* * Make sure the degenerate case that a wire is linked to itself * is handled properly. */ module example; wire w; assign w = w; initial $display("PASSED"); endmodule iverilog-12_0/ivtest/ivltests/pr509b.v000066400000000000000000000026251435245347300177570ustar00rootroot00000000000000module whoever_wrote_this_should_be_shot ( Q, D, G ); output Q; input D, G; wire Q_int; assign ( pull0, pull1 ) Q_int = Q_int; bufif1 buf_D ( Q_int, D, G ); buf buf_Q ( Q, Q_int ); endmodule module testbench; wire Q; reg D, G; whoever_wrote_this_should_be_shot uut ( Q, D, G ); initial begin D = 1'b0; forever #5 D = ~ D; end initial begin G = 1'b0; forever #27 G = ~ G; end initial begin $monitor( $time,,,G,,,D,,,Q ); // time 28: G=1, D=1, Q=1 #28 if (Q !== 1) begin $display("FAILED -- Q should be 1, is %b", Q); $finish; end // time 31: G=1, D=0, Q=0 #3 if (Q !== 0) begin $display("FAILED -- Q should be 0, is %b", Q); $finish; end // time 51: G=1, D=0, Q=0 #20 if (Q !== 0) begin $display("FAILED -- Q should be 0, is %b", Q); $finish; end // time 56: G=0, D=1, Q=0 #5 if (Q !== 0) begin $display("FAILED -- Q should be 0, is %b", Q); $finish; end // time 82: G=1, D=0, Q=0 #26 if (Q !== 0) begin $display("FAILED -- Q should be 0, is %b", Q); $finish; end // time 86: G=1, D=1, Q=1 #5 if (Q !== 1) begin $display("FAILED -- Q should be 1, is %b", Q); $finish; end #1000 $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr511.v000066400000000000000000000073521435245347300176100ustar00rootroot00000000000000/* * This test is derived from bug report PR#511. Mostly what it is * doing is checking the behavior of === and wait. */ `timescale 1 ps / 1 ps module I54; initial begin #500000 $display( "FAILED." ); $finish; end parameter I148 = 4096; integer I20; integer I57; integer I58; integer I137; time I106; time I95; time I97; time I122; time I142; time I67; time I25; time I83; time I128; time I10; time I12; time I73; time I159; reg I77; reg I108; reg I2; reg I81; reg I60; reg I114; reg I124; reg I41; reg I151; reg I43; reg [1:0] I68; reg [4*8-1:0] I138; reg [3:0] I71; reg [3:0] I149; reg [3:0] I6; reg [3:0] I76; reg I48; reg I61; reg I62; reg I49; reg I158; reg I85; reg [2:0] I84; reg [2:0] I30; reg I94; wire I69; wire I98; reg I115; reg I101; reg I14; reg I78; reg I131; reg I24; reg I52; reg I13; reg I132; reg I139; reg I107; wire I93; wire [3:0] I120; wire [3:0] I82; wire I38; wire I22; wire [1:0] I46; wire [2:0] I1; wire [4*8-1:0] I4; wire [3:0] I125; wire [3:0] I36; wire [3:0] I91; wire [3:0] I3; wire [3:0] I143; wire [1:0] I72; wire I34; wire I150; wire I40; wire [1:0] I51; reg [1:0] I39; reg [4-1:0] I70; wire I103; wire I29; wire I74; wire I144; reg I63; reg I15; reg I146; reg I110; reg I152; reg I129; reg I19; reg I112; reg I102; reg I156; reg I121; wire I23; wire [3:0] I118; wire [3:0] I86; wire I28; wire I65; wire [1:0] I79; wire [2:0] I17; wire [4*8-1:0] I133; wire [3:0] I27; wire [3:0] I99; wire [3:0] I135; wire [3:0] I90; wire [3:0] I35; wire [1:0] I55; wire I8; wire I126; wire I5; wire [1:0] I140; reg [1:0] I116; reg [4-1:0] I45; wire I105; wire I33; wire I75; wire I145; reg I64; reg I16; reg I147; reg I111; reg I153; reg I130; reg I21; reg I113; reg I104; reg I157; reg I123; wire I26; wire [3:0] I119; wire [3:0] I87; wire I32; wire I66; wire [1:0] I80; wire [2:0] I18; wire [4*8-1:0] I134; wire [3:0] I31; wire [3:0] I100; wire [3:0] I136; wire [3:0] I92; wire [3:0] I37; wire [1:0] I56; wire I9; wire I127; wire I7; wire [1:0] I141; reg [1:0] I117; reg [4-1:0] I47; wire [256:0] I59; wire [256:0] I50; wire [256:0] I88; wire [256:0] I154; wire [256:0] I89; wire [256:0] I155; assign I69 = I59[I20]; assign I98 = I50[I20]; assign I103 = I88[I57]; assign I29 = I154[I57]; assign I105 = I89[I58]; assign I33 = I155[I58]; wire I109 = ( ~ I94 ) & ( ~ I151 ); wire I96 = ( ~ I94 ) & ( I151 ); wire I42 = ( I94 ) & ( ~ I151 ); wire I44 = ( I94 ) & ( I151 ); always @( I114 ) begin I132 <= #I106 I114; I102 <= #I95 I114; I104 <= #I97 I114; end always @( I124 ) begin I139 <= #I106 I124; I156 <= #I95 I124; I157 <= #I97 I124; end initial begin I77 = 1'b0; #0 ; #(I142) I77 = 1'b1; forever #(I122/2) I77 = ~ I77; end initial begin I108 = 1'b0; #0 ; #(I25) I108 = 1'b1; forever #(I67/2) I108 = ~ I108; end initial begin I2 = 1'b0; #0 ; #(I128) I2 = 1'b1; forever #(I83/2) I2 = ~ I2; end initial begin I81 = 1'b0; #0 ; #(I12) I81 = 1'b1; forever #(I10/2) I81 = ~ I81; end initial begin I60 = 1'b0; #0 ; #(I159) I60 = 1'b1; forever #(I73/2) I60 = ~ I60; end initial begin I114 = 1'b1; #300000 ; @( posedge I81 ) ; @( posedge I81 ) ; #50 I114 = 1'b0; end initial begin I124 = 1'b1; #300000 ; @( posedge I60 ) ; @( posedge I60 ) ; #50 I124 = 1'b0; end initial begin : I53 I137 = 1600; I20 = 40; I57 = 0; I58 = 80; I106 = 150; I95 = 300; I97 = 0; I151 = 1'b0; I94 = 1'b0; I122 = 6400; I142 = 0; I67 = 6270; I25 = 0; I83 = 6400; I128 = 1000; I10 = 6270; I12 = 0; I73 = 6400; I159 = 1000; wait ( I114 === 1'b1 ); wait ( I114 === 1'b0 ); wait ( I124 === 1'b0 ); $display( "PASSED" ); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr513.v000066400000000000000000000003461435245347300176060ustar00rootroot00000000000000/* * Derived from PR#513 */ `timescale 1 ps / 1 ps module example; integer fd; initial begin #100 fd = $fopen( "work/example.dump" ); $fdisplay( fd ); #1000 $display( "PASSED" ); end endmodule iverilog-12_0/ivtest/ivltests/pr519.v000066400000000000000000000025371435245347300176200ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test is intended to be run with ``iverilog -S foo.v'', * and tests the situation addressed by pr#519. */ module main; reg [3:0] a, b, c, t; (* ivl_combinational *) always @(a, b) begin t = a + b; c = 4'd1 + ~t; end (* ivl_synthesis_off *) initial begin a = 1; for (b = 0 ; b < 4'hf ; b = b + 1) begin #1 if (c !== -(a + b)) begin $display("FAILED -- a=%b, b=%b, t=%b, c=%b", a, b, t, c); $finish; end end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr522.v000066400000000000000000000041031435245347300176010ustar00rootroot00000000000000/* * Copyright (c) 2002 Jane Skinner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // Icarus 0.6, snapshot 20020728 or snapshot 20010806 // ================================================== // -- confused by complex disables // // -- to run, incant // iverilog tt.v // vvp a.out // // Veriwell // ======== // -- OK // module top; integer loop_cntr, simple_fail, loop_fail; reg fred, abort; initial begin #1; simple_fail = 0; loop_fail = 0; fred = 0; abort = 1; #4; fred = 1; #4 if(simple_fail) $display("\n***** simple block disable FAILED *****"); else $display("\n***** simple block disable PASSED *****"); if(loop_fail) $display("***** complex block & loop disable FAILED *****\n"); else $display("***** complex block & loop disable PASSED *****\n"); $finish(0); end // simple block disable initial begin: block_name #2; disable block_name; simple_fail = 1; end // more complex: block disable inside for-loop initial begin #2; begin: configloop for (loop_cntr = 0; loop_cntr < 3; loop_cntr=loop_cntr+1) begin wait (fred); if (abort) begin disable configloop; end loop_fail = 1; end end // configloop block if (loop_fail) $display("\n\ttime: %0t, loop_cntr: %0d",$time,loop_cntr); end endmodule iverilog-12_0/ivtest/ivltests/pr524.v000066400000000000000000000003421435245347300176040ustar00rootroot00000000000000`timescale 1 ps / 1 ps module example; time delay; initial begin // delay = 64'bx; $display( "%T %b", $time, delay ); // #(64'bx) #delay $display( "%T", $time ); end endmodule iverilog-12_0/ivtest/ivltests/pr527.v000066400000000000000000000047101435245347300176120ustar00rootroot00000000000000// Icarus 0.6 AND snapshot 20020728 // ----------------------------- // (1) force to nets not supported // (2) comment the force statement and the release statement will cause // the compiler to fail silently (no messages, no a.out) // // Icarus snapshot 20020817 // ------------------------ // Runs fine IFF the whole of a bus is set, cannot force individual bits // (Fails with a rather incomprehensible error) // // To run this, incant: // iverilog tt.v // (adding -Wall doesn't help) // vvp a.out (if a.out is generated!) // // // Veriwell // --------- // Runs fine IFF the whole of a bus is set, cannot force individual bits // & crashes if a release of an individual bit is attempted. // // To run this, incant: // veridos tt.v (or use the GUI) // module top (); reg [31:0] ii; reg fail; reg [1:0] a; wire [1:0] junk = a; wire [1:0] junkbus = a; initial begin a = 2'b01; #5; a = 2'b10; #10; a = 2'b11; end initial begin #2; force junk = 0; force junkbus[0] = 0; #10; release junk; #5; release junkbus[0]; end initial begin $display(""); $display("expecting junk,junkbus to be 1 at T=1"); $display("then changing to 0 at T=2"); $display("then junk is 0 from T=3 to T=11, while"); $display("junkbus changes to 2 at T=5 and remains 2 through to T=16"); $display("junk changes to 2 at T=12"); $display("then 2 from T=13 to T=14"); $display("then changing to 3 at T=15"); $display("then 3 from T=16 on"); $display("junkbus changes to 3 at T=17 and remains 3 from then on"); $display(""); for(ii = 0; ii < 20; ii = ii + 1) begin #0; // avoid race // junk if((ii == 1) && (junk !== 1)) fail = 1; if((ii > 2) && (ii < 12) && (junk !== 0)) fail = 1; if((ii > 12) && (ii < 14) && (junk !== 2'b10)) fail = 1; if((ii > 15) && (junk !== 2'b11)) fail = 1; // junkbus if((ii == 1) && (junkbus !== 2'b01)) fail = 1; if((ii > 2) && (ii < 4) && (junkbus !== 2'b00)) fail = 1; if((ii > 5) && (ii < 17) && (junkbus !== 2'b10)) fail = 1; if((ii > 17) && (junkbus !== 2'b11)) fail = 1; $display("time: %0t, a: %b, junk: %b, junkbus: %b",$time,a,junk,junkbus); #1; end if(fail) $display("\n\t--------- force test failed ---------\n"); else $display("\n\t--------- force test passed ---------\n"); end endmodule iverilog-12_0/ivtest/ivltests/pr528.v000066400000000000000000000004671435245347300176200ustar00rootroot00000000000000`timescale 1 ps / 1 ps module tester; wire clko1, clko2; reg clk; assign #50 clko1 = clk & 1'b1; assign #50 clko2 = clk; initial clk = 1'b0; always #5000 clk = ~ clk; initial $monitor( "%T %b %b %b", $time, clk, clko1, clko2 ); initial #50001 $finish(0); endmodule iverilog-12_0/ivtest/ivltests/pr528b.v000066400000000000000000000015441435245347300177570ustar00rootroot00000000000000`timescale 1 ps / 1 ps module tester; wire clko1, clko2; reg clk1, clk2, f1, f2; ckmux uut ( clko1, clk1, clk2, f1, f2 ); assign #50 clko2 = clk1; initial begin f1 = 1'b0; f2 = 1'b1; end initial begin clk1 = 1'b0; forever #5000 clk1 = ~ clk1; end initial begin clk2 = 1'b0; forever #5100 clk2 = ~ clk2; end initial $monitor( "%T %b %b %b", $time, clk1, clko1, clko2 ); initial #50001 $finish(0); endmodule module ckmux ( clko1, clk1, clk2, f1, f2 ); output clko1; input clk1, clk2, f1, f2; reg dclk1ff; wire dclk1; initial begin dclk1ff = 1'b0; forever @( negedge clk1 ) dclk1ff <= #50 ~ dclk1ff; end assign #50 dclk1 = f2 ? dclk1ff : clk2; assign #50 clko1 = f1 ? dclk1 : clk1; endmodule iverilog-12_0/ivtest/ivltests/pr529.v000066400000000000000000000107111435245347300176120ustar00rootroot00000000000000`begin_keywords "1364-2005" // -- test force/release of: // a wire assigned to a reg // a wire with no assignment // a whole bus (assigned to a reg), // a single bit of a bus (assigned to a reg) // -- make sure the force/release is passed into the hierarchy // // -- run with // iverilog -Wall tt.v // vvp a.out // -- to see debug display statements, use // iverilog -Wall -DDISPLAY tt.v // module top (); reg [31:0] ii; reg bitfail, bitnafail, busfail, busbitfail; reg a; reg [1:0] b; wire bit = a; wire bitna; wire [1:0] bus = b; wire [1:0] ibus = b; wire subfail, subfailna; // call in a lower level module subtop U1 ( .subbit(bit), .subbus(bus), .subfail(subfail) ); subtop U2 ( .subbit(bitna), .subbus(bus), .subfail(subfailna) ); initial begin a = 1'b1; b = 2'b01; #5; b = 2'b10; #10; b = 2'b11; end initial begin #2; force bit = 0; force bitna = 0; force bus = 0; //$display("\n ****** force/release to ibus[0] commented; expect bit[0] failure ******* "); force ibus[0] = 0; #10; release bit; force bitna = 1; release bus; #5; release ibus[0]; end initial begin bitfail = 0; bitnafail = 0; busfail = 0; busbitfail = 0; `ifdef DISPLAY $display(""); $display("expecting bit, bus,ibus to be 1 at T=1"); $display("then changing to 0 at T=2"); $display("then bit and bus are 0 from T=3 to T=11, while"); $display("ibus changes to 2 at T=5 and remains 2 through to T=16"); $display("bit changes to 1 at T=12 and remains 1 from then on."); $display("bus changes to 2 at T=12"); $display("then 2 from T=13 to T=14"); $display("then changing to 3 at T=15"); $display("then 3 from T=16 on"); $display("ibus changes to 3 at T=17 and remains 3 from then on"); $display(""); `endif for(ii = 0; ii < 20; ii = ii + 1) begin // bit if((ii == 1) && (bit !== 1)) bitfail = 1; if((ii > 2) && (ii < 12) && (bit !== 0)) bitfail = 1; if((ii > 12) && (bit !== 1)) bitfail = 1; // bitna if((ii == 1) && (bitna !== 1'bz)) bitnafail = 1; if((ii > 2) && (ii < 12) && (bitna !== 0)) bitnafail = 1; if((ii > 12) && (bitna !== 1)) bitnafail = 1; // bus if((ii == 1) && (bus !== 1)) busfail = 1; if((ii > 2) && (ii < 12) && (bus !== 0)) busfail = 1; if((ii > 12) && (ii < 14) && (bus !== 2'b10)) busfail = 1; if((ii > 15) && (bus !== 2'b11)) busfail = 1; // ibus if((ii == 1) && (ibus !== 2'b01)) busbitfail = 1; if((ii > 2) && (ii < 4) && (ibus !== 2'b00)) busbitfail = 1; if((ii > 5) && (ii < 17) && (ibus !== 2'b10)) busbitfail = 1; if((ii > 17) && (ibus !== 2'b11)) busbitfail = 1; `ifdef DISPLAY $display("time: %0t, a: %b, bit: %b, bitna %b, b: %b, bus: %b, ibus: %b",$time,a,bit,bitna,b,bus,ibus); `endif #1; end if(bitfail || bitnafail || busfail || busbitfail || subfail || subfailna) begin $display("\n\t--------- force test failed ---------"); if(bitfail) $display("force to single wire assigned to a reg failed"); if(bitnafail) $display("force to single unassigned wire failed"); if(busfail) $display("force to whole of 2-bit bus failed"); if(busbitfail) $display("force to bit[0] of 2-bit bus failed"); if(!bitfail && !bitnafail && !busfail && !busbitfail) begin if(subfail) $display("force did not affect U1 hierarchy"); if(subfailna) $display("force did not affect U2 hierarchy"); end $display("\n"); end else $display("PASSED"); end endmodule module subtop( subbit, subbus, subfail ); input subbit; input [1:0] subbus; output subfail; reg subfail; reg [31:0] ii; initial begin subfail = 0; for(ii = 0; ii < 20; ii = ii + 1) begin // subbit if((ii == 1) && (subbit !== 1) && (subbit !== 1'bz)) subfail = 1; if((ii > 2) && (ii < 12) && (subbit !== 0)) subfail = 1; if((ii > 12) && (subbit !== 1)) subfail = 1; // subbus if((ii == 1) && (subbus !== 1)) subfail = 1; if((ii > 2) && (ii < 12) && (subbus !== 0)) subfail = 1; if((ii > 12) && (ii < 14) && (subbus !== 2'b10)) subfail = 1; if((ii > 15) && (subbus !== 2'b11)) subfail = 1; `ifdef DISPLAY $display("\t\t\t\t\ttime: %0t, subbit: %b, subbus: %b",$time,subbit,subbus); `endif #1; end end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/pr530a.v000066400000000000000000000002611435245347300177420ustar00rootroot00000000000000//`timescale 1ns/1ps module top; initial begin $timeformat(-9,6,"ns",20); $display("here"); $display("in top, time: %t",$time); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr530b.v000066400000000000000000000002571435245347300177500ustar00rootroot00000000000000`timescale 1ns/1ns module top; initial begin $timeformat(-9,6,"ns",20); $display("here"); $display("in top, time: %t",$time); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr530c.v000066400000000000000000000002571435245347300177510ustar00rootroot00000000000000`timescale 1ns/1ps module top; initial begin $timeformat(-9,6,"ns",20); $display("here"); $display("in top, time: %t",$time); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr531a.v000066400000000000000000000046471435245347300177570ustar00rootroot00000000000000module example; reg [3:0] mem [0:7]; reg [3:0] addr; wire [3:0] m0 = mem[0]; wire [3:0] m1 = mem[1]; wire [3:0] m2 = mem[2]; wire [3:0] m3 = mem[3]; wire [3:0] m4 = mem[4]; wire [3:0] m5 = mem[5]; wire [3:0] m6 = mem[6]; wire [3:0] m7 = mem[7]; wire [3:0] maddr = mem[addr]; initial begin $write( " " ); $display( "time addr maddr m0 m1 m2 m3 m4 m5 m6 m7" ); $write( " " ); $display( "---- ---- ----- ---- ---- ---- ---- ---- ---- ---- ----" ); $monitor( "%T %b %b %b %b %b %b %b %b %b %b", $time, addr, maddr, m0, m1, m2, m3, m4, m5, m6, m7 ); mem[0] = 8; mem[1] = 1; mem[2] = 2; mem[3] = 3; mem[4] = 4; mem[5] = 5; mem[6] = 6; mem[7] = 7; addr = 0; // 0 #100 addr = 1; // 100 #100 addr = 2; // 200 #100 addr = 3; // 300 #100 addr = 4; // 400 #100 addr = 5; // 500 #100 addr = 6; // 600 #100 addr = 7; // 700 #100 addr = 8; // 800 #100 addr = 4'b001x; // 900 #100 addr = 4'b01x0; // 1000 #100 addr = 4'b0x01; // 1100 #100 addr = 0; // 1200 #100 mem[addr] = 9; // 1300 #100 addr = 3; // 1400 #100 mem[addr] = 10; // 1500 #100 addr = 6; // 1600 #100 mem[addr] = 11; // 1700 #100 addr = 8; // 1800 #100 mem[addr] = 12; // 1900 #100 addr = 4'b010x; // 2000 #100 mem[addr] = 13; // 2100 #100 addr = 4'b00x1; // 2200 #100 mem[addr] = 14; // 2300 #100 addr = 4'b0x10; // 2400 #100 mem[addr] = 15; // 2500 #100 addr = 4'bxxxx; // 2600 #100 mem[addr] = 0; // 2700 #100 $display( "Finish at time %T", $time ); end endmodule iverilog-12_0/ivtest/ivltests/pr531b.v000066400000000000000000000046571435245347300177610ustar00rootroot00000000000000module example; reg [3:0] mem [0:7]; reg [3:0] addr; wire [3:0] m0 = mem[0]; wire [3:0] m1 = mem[1]; wire [3:0] m2 = mem[2]; wire [3:0] m3 = mem[3]; wire [3:0] m4 = mem[4]; wire [3:0] m5 = mem[5]; wire [3:0] m6 = mem[6]; wire [3:0] m7 = mem[7]; wire [3:0] maddr = mem[addr]; initial begin $write( " " ); $display( "time addr maddr m0 m1 m2 m3 m4 m5 m6 m7" ); $write( " " ); $display( "---- ---- ----- ---- ---- ---- ---- ---- ---- ---- ----" ); $monitor( "%T %b %b %b %b %b %b %b %b %b %b", $time, addr, maddr, m0, m1, m2, m3, m4, m5, m6, m7 ); mem[0] = 8; mem[1] = 1; mem[2] = 2; mem[3] = 3; mem[4] = 4; mem[5] = 5; mem[6] = 6; mem[7] = 7; addr = 0; // 0 #100 addr = 1; // 100 #100 addr = 2; // 200 #100 addr = 3; // 300 #100 addr = 4; // 400 #100 addr = 5; // 500 #100 addr = 6; // 600 #100 addr = 7; // 700 #100 addr = 8; // 800 #100 addr = 4'b001x; // 900 #100 addr = 4'b01x0; // 1000 #100 addr = 4'b0x01; // 1100 #100 addr = 0; // 1200 #100 mem[addr] <= 9; // 1300 #100 addr = 3; // 1400 #100 mem[addr] <= 10; // 1500 #100 addr = 6; // 1600 #100 mem[addr] <= 11; // 1700 #100 addr = 8; // 1800 #100 mem[addr] <= 12; // 1900 #100 addr = 4'b010x; // 2000 #100 mem[addr] <= 13; // 2100 #100 addr = 4'b00x1; // 2200 #100 mem[addr] <= 14; // 2300 #100 addr = 4'b0x10; // 2400 #100 mem[addr] <= 15; // 2500 #100 addr = 4'bxxxx; // 2600 #100 mem[addr] <= 0; // 2700 #100 $display( "Finish at time %T", $time ); end endmodule iverilog-12_0/ivtest/ivltests/pr532.v000066400000000000000000000043711435245347300176110ustar00rootroot00000000000000module example; reg [7:0] vec; reg [3:0] ix; wire vix = vec[ix]; initial begin $display( " time ix vix vec" ); $display( " ---- ---- --- --------" ); $monitor( "%T %b %b %b", $time, ix, vix, vec ); vec = 8'b00000000; ix = 0; // 0 #100 ix = 1; // 100 #100 ix = 2; // 200 #100 ix = 3; // 300 #100 ix = 4; // 400 #100 ix = 5; // 500 #100 ix = 6; // 600 #100 ix = 7; // 700 #100 ix = 8; // 800 #100 ix = 4'b001x; // 900 #100 ix = 4'b01x0; // 1000 #100 ix = 4'b0x01; // 1100 #100 ix = 0; // 1200 #100 vec[ix] = 1'b1; // 1300 #100 vec[ix] = 1'b0; // 1400 #100 ix = 3; // 1500 #100 vec[ix] = 1'b1; // 1600 #100 vec[ix] = 1'b0; // 1700 #100 ix = 6; // 1800 #100 vec[ix] = 1'b1; // 1900 #100 vec[ix] = 1'b0; // 2000 #100 ix = 8; // 2100 #100 vec[ix] = 1'b1; // 2200 #100 vec[ix] = 1'b0; // 2300 #100 ix = 4'b010x; // 2400 #100 vec[ix] = 1'b1; // 2500 #100 vec[ix] = 1'b0; // 2600 #100 ix = 4'b00x1; // 2700 #100 vec[ix] = 1'b1; // 2800 #100 vec[ix] = 1'b0; // 2900 #100 ix = 4'b0x10; // 3000 #100 vec[ix] = 1'b1; // 3100 #100 vec[ix] = 1'b0; // 3200 #100 ix = 4'bxxxx; // 3300 #100 vec[ix] = 1'b1; // 3400 #100 vec[ix] = 1'b0; // 3500 #100 $display( "Finish at time %T", $time ); end endmodule iverilog-12_0/ivtest/ivltests/pr532b.v000066400000000000000000000044111435245347300177460ustar00rootroot00000000000000module example; reg [7:0] vec; reg [3:0] ix; wire vix = vec[ix]; initial begin $display( " time ix vix vec" ); $display( " ---- ---- --- --------" ); $monitor( "%T %b %b %b", $time, ix, vix, vec ); vec = 8'b00000000; ix = 0; // 0 #100 ix = 1; // 100 #100 ix = 2; // 200 #100 ix = 3; // 300 #100 ix = 4; // 400 #100 ix = 5; // 500 #100 ix = 6; // 600 #100 ix = 7; // 700 #100 ix = 8; // 800 #100 ix = 4'b001x; // 900 #100 ix = 4'b01x0; // 1000 #100 ix = 4'b0x01; // 1100 #100 ix = 0; // 1200 #100 vec[ix] <= 1'b1; // 1300 #100 vec[ix] <= 1'b0; // 1400 #100 ix = 3; // 1500 #100 vec[ix] <= 1'b1; // 1600 #100 vec[ix] <= 1'b0; // 1700 #100 ix = 6; // 1800 #100 vec[ix] <= 1'b1; // 1900 #100 vec[ix] <= 1'b0; // 2000 #100 ix = 8; // 2100 #100 vec[ix] <= 1'b1; // 2200 #100 vec[ix] <= 1'b0; // 2300 #100 ix = 4'b010x; // 2400 #100 vec[ix] <= 1'b1; // 2500 #100 vec[ix] <= 1'b0; // 2600 #100 ix = 4'b00x1; // 2700 #100 vec[ix] <= 1'b1; // 2800 #100 vec[ix] <= 1'b0; // 2900 #100 ix = 4'b0x10; // 3000 #100 vec[ix] <= 1'b1; // 3100 #100 vec[ix] <= 1'b0; // 3200 #100 ix = 4'bxxxx; // 3300 #100 vec[ix] <= 1'b1; // 3400 #100 vec[ix] <= 1'b0; // 3500 #100 $display( "Finish at time %T", $time ); end endmodule iverilog-12_0/ivtest/ivltests/pr533.v000066400000000000000000000016231435245347300176070ustar00rootroot00000000000000module example; reg r, c, e; reg [4:0] a, b; wire d; assign d = ( r | ( a == b ) ) ? 1'b0 : 1'b1; // Change inputs at time n*100 initial begin #100 r = 1'bx; a = 5'bxxxxx; b = 5'bxxxxx; #100 r = 1'b1; a = 5'bxxxxx; b = 5'bxxxxx; #100 r = 1'b1; a = 5'b00000; b = 5'b00000; #100 r = 1'b0; a = 5'b00000; b = 5'b00000; #100 $finish(0); end // Store c and e at time n*100 + 25. // Note that the value assigned to c is exactly the same as // the continuous assignment RHS for d (assigned to e). initial #25 forever begin #100 c = ( r | ( a == b ) ) ? 1'b0 : 1'b1; e = d; end // Display all values at time n*100 + 50 initial #50 forever begin #100 $display( "%b,%b,%b = ( %b | ( %b == %b ) ) ? 0 : 1", c, d, e, r, a, b ); end endmodule iverilog-12_0/ivtest/ivltests/pr534.v000066400000000000000000000044141435245347300176110ustar00rootroot00000000000000/////////////////////////////////////////////////////////////////////////// // // To test: // (a) The use & representation of time variables // (b) The display of time variables // // Compile and run the program // iverilog tt_clean.v // vvp a.out // // VISUALLY INSPECT the displays. (There ain't no way to automate this) // /////////////////////////////////////////////////////////////////////////// `timescale 1 ns / 10 ps `define PCI_CLK_PERIOD 15.0 // 66 Mhz module top; reg PCI_Clk; reg fail; initial PCI_Clk <= 0; always #(`PCI_CLK_PERIOD/2) PCI_Clk <= ~PCI_Clk; initial begin fail = 0; $display("\n\t\t==> CHECK THIS DISPLAY ==>\n"); $display("pci_clk_period:\t\t\t %0d",`PCI_CLK_PERIOD); $display("pci_clk_period:\t\t\t %0t",`PCI_CLK_PERIOD); if($time !== 0) fail = 1; if (fail == 1) $display("$time=%0d (0)", $time); delay_pci(3); if($simtime !== 4500) fail = 1; if($time !== 45) fail = 1; if (fail == 1) $display("$time=%0d (45)", $time); #15; if($simtime !== 6000) fail = 1; if($time !== 60) fail = 1; #(`PCI_CLK_PERIOD); if($simtime !== 7500) fail = 1; if($time !== 75) fail = 1; #(`PCI_CLK_PERIOD *2); if($simtime !== 10500) fail = 1; if($time !== 105) fail = 1; $timeformat(-9,2,"ns",20); $display("after setting timeformat:"); $display("pci_clk_period:\t\t\t %0d",`PCI_CLK_PERIOD); $display("pci_clk_period:\t\t\t %0t",`PCI_CLK_PERIOD); delay_pci(3); if($simtime !== 15000) fail = 1; if($time !== 150) fail = 1; #15; if($simtime !== 16500) fail = 1; if($time !== 165) fail = 1; #(`PCI_CLK_PERIOD); if($simtime !== 18000) fail = 1; if($time !== 180) fail = 1; #(`PCI_CLK_PERIOD *2); if($simtime !== 21000) fail = 1; if($time !== 210) fail = 1; $display("\t\t**********************************************"); if(fail) $display("\t\t****** time representation test BAD *******"); else $display("\t\t****** time representation test OK *******"); $display("\t\t**********************************************\n"); $finish(0); end task delay_pci; input delta; integer delta; integer ii; begin #(`PCI_CLK_PERIOD * delta); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr538.v000066400000000000000000000024231435245347300176130ustar00rootroot00000000000000////////////////////////////////////////////////////////////////////////////// // // using `timescale, test rounding up to specified precision and // scaling to specified time unit // // run with // iverilog lrm_eg.v // vvp a.out // // (uncomment $display statements for help in debugging) // ////////////////////////////////////////////////////////////////////////////// `timescale 10 ns / 1 ns module test; reg set; parameter d = 1.55; reg fail; reg [7:0] ii; initial begin fail = 0; #d set = 0; //$display("time in units of 10ns: %0t, in ns: %0d, set: %0b",$time,ii,set); if((ii < 15) || (ii > 16)) fail = 1; #d set = 1; //$display("time in units of 10ns: %0t, in ns: %0d, set: %0b",$time,ii,set); if((ii < 31) || (ii > 32)) fail = 1; end initial begin //$dumpvars; for(ii = 0; ii < 50; ii = ii + 1) begin //$display("time in ns: %0d, set: %0b",ii,set); #0.1; end $display("\n\t\t**********************************************"); if(fail) $display("\t\t********** timescale test FAILED *************"); else $display("\t\t********** timescale test PASSED *************"); $display("\t\t**********************************************\n"); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr540.v000066400000000000000000000052751435245347300176140ustar00rootroot00000000000000// Icarus 0.6, snapshot 20020907 // ================================================== // -- confused by disables from within a fork -- vvp fails // // -- to run, incant // iverilog tt.v // vvp a.out module top; integer simple_fail, loop_fail, fork_fail, tlp_fail, tfk_fail; integer loop_cntr, tlp_cntr; reg fred, abort; initial begin #1; simple_fail = 0; loop_fail = 0; fork_fail = 0; tlp_fail = 0; tfk_fail = 0; fred = 0; abort = 1; #4; fred = 1; #4 if(simple_fail) $display("\n***** simple block disable FAILED *****"); else $display("\n***** simple block disable PASSED *****"); if(loop_fail) $display("***** block with loop disable FAILED *****"); else $display("***** block with loop disable PASSED *****"); if(fork_fail) $display("***** forked block disable FAILED *****"); else $display("***** forked block disable PASSED *****"); if(tlp_fail) $display("***** task with loop disable FAILED *****"); else $display("***** task with loop disable PASSED *****"); if(tfk_fail) $display("***** task with forked block disable FAILED ****\n"); else $display("***** task with forked block disable PASSED ****\n"); $finish(0); end // simple block disable initial begin: block_name #2; disable block_name; simple_fail = 1; end // more complex: block disable inside for-loop initial begin #2; begin: configloop for (loop_cntr = 0; loop_cntr < 3; loop_cntr=loop_cntr+1) begin wait (fred); if (abort) begin disable configloop; end loop_fail = 1; end end // configloop block if (loop_fail) $display("\n\ttime: %0t, loop_cntr: %0d",$time,loop_cntr); end // still more complex: disable from within a forked block initial begin #2; begin: forked_tasks fork begin #5; fork_fail = 1; end begin @(fred); disable forked_tasks; fork_fail = 1; end join fork_fail = 1; end //forked_tasks end // disables inside tasks initial begin task_with_loop; end initial begin task_with_fork; end task task_with_loop; begin #2; begin: configtlp for (tlp_cntr = 0; tlp_cntr < 3; tlp_cntr=tlp_cntr+1) begin wait (fred); if (abort) begin disable configtlp; end tlp_fail = 1; end end // configloop block end endtask // task_with_loop task task_with_fork; begin #2; begin: forked_tasks_in_task fork begin #5; tfk_fail = 1; end begin @(fred); disable forked_tasks_in_task; tfk_fail = 1; end join tfk_fail = 1; end //forked_tasks_in_task end endtask // task_with_fork endmodule iverilog-12_0/ivtest/ivltests/pr540b.v000066400000000000000000000102341435245347300177450ustar00rootroot00000000000000// Icarus 0.6, snapshot 20020907 // ================================================== // -- confused by disables from within a fork -- vvp fails // // -- to run, incant // iverilog tt.v // vvp a.out // // Veriwell // ======== // -- OK // module top; integer simple_fail, loop_fail, fork_fail, tlp_fail; integer tfk_fail, tfk2_fail, tfk3_fail; integer tfk2pos, tfk2nega, tfk2negb; integer tfk3pos, tfk3nega, tfk3negb; integer loop_cntr, tlp_cntr; reg fred, abort; initial begin #1; simple_fail = 0; loop_fail = 0; fork_fail = 0; tlp_fail = 0; tfk_fail = 0; tfk2_fail = 0; tfk2pos = 0; tfk2nega = 1; tfk2negb = 1; tfk3pos = 0; tfk3nega = 1; tfk3negb = 1; fred = 0; abort = 1; #4; fred = 1; #4 $display("Check disable:"); if(simple_fail) $display("***** simple block FAILED *****"); else $display("***** simple block PASSED *****"); if(loop_fail) $display("***** block with loop FAILED *****"); else $display("***** block with loop PASSED *****"); if(fork_fail) $display("***** forked block FAILED *****"); else $display("***** forked block PASSED *****"); if(tlp_fail) $display("***** task with loop FAILED *****"); else $display("***** task with loop PASSED *****"); if(tfk_fail) $display("***** task with forked block FAILED *****"); else $display("***** task with forked block PASSED *****"); if(tfk2_fail) $display("***** one forked block FAILED *****"); else $display("***** one forked block PASSED *****"); if(tfk3_fail) $display("***** the other forked block FAILED *****"); else $display("***** the other forked block PASSED *****"); $display(""); $finish(0); end // simple block disable initial begin: block_name #2; disable block_name; simple_fail = 1; end // more complex: block disable inside for-loop initial begin #2; begin: configloop for (loop_cntr = 0; loop_cntr < 3; loop_cntr=loop_cntr+1) begin wait (fred); if (abort) begin disable configloop; end loop_fail = 1; end end // configloop block if (loop_fail) $display("\n\ttime: %0t, loop_cntr: %0d",$time,loop_cntr); end // still more complex: disable from within a forked block initial begin #2; begin: forked_tasks fork begin #5; fork_fail = 1; end begin @(fred); disable forked_tasks; fork_fail = 1; end join fork_fail = 1; end //forked_tasks end // disables inside tasks initial begin task_with_loop; end initial begin task_with_fork; end initial begin task_with_fork2; if(tfk2pos || tfk2nega || tfk2negb) tfk2_fail = 1; end initial begin task_with_fork3; if(tfk3pos || tfk3nega || tfk3negb) tfk3_fail = 1; end task task_with_loop; begin #2; begin: configtlp for (tlp_cntr = 0; tlp_cntr < 3; tlp_cntr=tlp_cntr+1) begin wait (fred); if (abort) begin disable configtlp; end tlp_fail = 1; end end // configloop block end endtask // task_with_loop task task_with_fork; // disable block whick calls fork begin #2; begin: forked_tasks_in_task fork begin: alf #5; tfk_fail = 1; end begin: bet @(fred); disable forked_tasks_in_task; tfk_fail = 1; end join tfk_fail = 1; end //forked_tasks_in_task end endtask // task_with_fork task task_with_fork2; // disable *one* of the forked blocks begin #2; begin: forked_tasks_in_task2 fork begin: gam #5; tfk2pos = 1; end begin: delt @(fred); disable gam; tfk2nega = 0; end join tfk2negb = 0; end //forked_tasks_in_task end endtask // task_with_fork task task_with_fork3; // disable *one* of the forked blocks begin #2; begin: forked_tasks_in_task3 fork begin: eps #5; tfk3nega = 0; end begin: zet @(fred); disable zet; tfk3pos = 1; end join tfk3negb = 0; end //forked_tasks_in_task end endtask // task_with_fork endmodule iverilog-12_0/ivtest/ivltests/pr540c.v000066400000000000000000000011601435245347300177440ustar00rootroot00000000000000module top; integer fail; reg cmd, reset; initial begin #1; reset = 0; fail = 0; #1; cmd = 0; #2; reset = 1; #2; cmd = 1; #2; cmd = 0; #2; reset = 0; #2; reset = 1; #4; if(fail) $display("***** disable test FAILED *****"); else $display("***** disable test PASSED *****"); $finish(0); end always @(cmd) begin: command_block fork begin #0; // avoid fork race disable command_block_reset; end begin: command_block_reset @(reset); fail = 1; disable command_block; end join end endmodule iverilog-12_0/ivtest/ivltests/pr541.v000066400000000000000000000004241435245347300176040ustar00rootroot00000000000000module example; reg [2:0] rhs; wire [5:0] lhs = - rhs; integer ix; initial begin $monitor( "%b[5:0] = - %b[2:0]", lhs, rhs ); for ( ix = 0; ix <= 7; ix = ix + 1 ) begin rhs = ix; #100 ; end end endmodule iverilog-12_0/ivtest/ivltests/pr542.v000066400000000000000000000022071435245347300176060ustar00rootroot00000000000000/* * Copyright (c) 2002 Jane Skinner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* PR#542 */ module top; parameter[3:0] DAC = 8; wire d_pm_in_dac_st; reg [10:0] pm_next_st; assign d_pm_in_dac_st = (pm_next_st[DAC]); initial begin pm_next_st = 10'h100; #1; $display("d_pm_in_dac_st = %0b",d_pm_in_dac_st); $display("d_pm_in_dac_st = %0b",pm_next_st[DAC]); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr544.v000066400000000000000000000020371435245347300176110ustar00rootroot00000000000000module example; wire y; reg p01, p01g, s01, s01g; bufif1 (pull0, pull1 ) ( y, p01, p01g ); bufif1 (strong0, strong1) ( y, s01, s01g ); initial begin $monitor( "%T Pu:%b/%b St:%b/%b Y:%b,%v", $time, p01, p01g, s01, s01g, y, y ); { p01, p01g, s01, s01g } = 4'b0000; #100 { p01, p01g, s01, s01g } = 4'b0x00; #100 { p01, p01g, s01, s01g } = 4'b000x; #100 { p01, p01g, s01, s01g } = 4'b1x00; #100 { p01, p01g, s01, s01g } = 4'b001x; #100 { p01, p01g, s01, s01g } = 4'b0100; #100 { p01, p01g, s01, s01g } = 4'b0001; #100 { p01, p01g, s01, s01g } = 4'b1100; #100 { p01, p01g, s01, s01g } = 4'b0011; #100 { p01, p01g, s01, s01g } = 4'bx100; #100 { p01, p01g, s01, s01g } = 4'b00x1; #100 { p01, p01g, s01, s01g } = 4'b010x; #100 { p01, p01g, s01, s01g } = 4'bx10x; #100 { p01, p01g, s01, s01g } = 4'b111x; #100 { p01, p01g, s01, s01g } = 4'bx11x; #100 ; end endmodule iverilog-12_0/ivtest/ivltests/pr547.v000066400000000000000000000004761435245347300176210ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg [9:0] a; reg b; initial begin a = 10'h3ff; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST b = a[15]; `else b = 1'bx; `endif $display("A = %h, b = %b", a, b); end // initial begin endmodule // top iverilog-12_0/ivtest/ivltests/pr556.v000066400000000000000000000006721435245347300176170ustar00rootroot00000000000000/* * This test is from PR#556. * * The output should generate signed and unsigned values * from -256 to 256. Also, since the $random sequence is * repeatable, it should generate the *same* seqnence * every time the program is run. */ module test_ran; integer i,j; initial begin for (j=0;j<256;j=j+1) begin i = $random % 256; $display ("The random number is %d",i); end $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr564.v000066400000000000000000000025171435245347300176160ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Based on PR#564 */ module main( ); parameter [7:0] forwards = 8'b11110001; parameter [0:7] backwards = 8'b10001111; integer i; initial begin for (i = 0 ; i < 8 ; i = i + 1) begin $write("forwards[%0d] === %b, ", i, forwards[i]); $display("backwards[%0d] === %b", i, backwards[i]); if (forwards[i] !== backwards[i]) begin $display("FAILED -- forwards[%0d] !== backwards[%0d]", i, i); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr567.v000066400000000000000000000001501435245347300176100ustar00rootroot00000000000000module test; reg blah [63:0]; initial blah = 0; // This should generate an error message. endmodule iverilog-12_0/ivtest/ivltests/pr569.v000066400000000000000000000005341435245347300176200ustar00rootroot00000000000000/* * Derived from PR#569 */ module test(); parameter foo = 8'b01010101; parameter bar = {foo,{2{foo}}}; // fails // parameter tmp = {2{foo}}; // this + next line succeed // parameter bar = {foo,tmp}; reg[23:0] cnt; reg CLK; initial $monitor("%b", cnt); initial CLK = 0; initial cnt = bar; endmodule iverilog-12_0/ivtest/ivltests/pr572.v000066400000000000000000000016721435245347300176160ustar00rootroot00000000000000/* * Hierarchical event testcase * * Copyright (C) 2002 Charles Lepple * * 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. * * compilation options: none necessary */ `define TEST_HIERARCHICAL_EVENT // yields parse error when defined module top(); event toplevel_event; submodule sub(); initial #10 -> toplevel_event; endmodule // top module submodule(); event local_event; initial #25 -> local_event; always begin `ifdef TEST_HIERARCHICAL_EVENT @top.toplevel_event $display("at %0d: toplevel event triggered", $time); `endif @local_event $display("at %0d: local event triggered", $time); end endmodule // submodule // local variables: // verilog-simulator: "iverilog" // end: iverilog-12_0/ivtest/ivltests/pr572b.v000066400000000000000000000016741435245347300177620ustar00rootroot00000000000000/* * Hierarchical event testcase * * Copyright (C) 2002 Charles Lepple * * 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. * * compilation options: none necessary */ `define TEST_HIERARCHICAL_EVENT // yields parse error when defined module top(); event toplevel_event; submodule sub(); initial #10 -> toplevel_event; endmodule // top module submodule(); event local_event; initial #25 -> local_event; always begin `ifdef TEST_HIERARCHICAL_EVENT @(top.toplevel_event) $display("at %0d: toplevel event triggered", $time); `endif @local_event $display("at %0d: local event triggered", $time); end endmodule // submodule // local variables: // verilog-simulator: "iverilog" // end: iverilog-12_0/ivtest/ivltests/pr578.v000066400000000000000000000006331435245347300176200ustar00rootroot00000000000000module main; function [7:0] add; input [7:0] a, b; reg [8:0] tmp; begin tmp = a + b; if (tmp < 9'h100) add = tmp; else add = 8'hff; end endfunction // add reg[7:0] out; initial begin out = 1? add(8,9) : 0; if (out !== 8'd17) begin $display("FAILED -- out = %b", out); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr581.v000066400000000000000000000011701435245347300176070ustar00rootroot00000000000000module module1(clock,reset,result); input clock,reset; output result; reg result; always @ (posedge clock) if (reset) result <= 0; else result <= 1; endmodule // driver module main; reg clk,reset; reg data[1:3]; // ILLEGAL port connection NOT detected // to fix, use wire data_1,data_2,data_3; module1 inst1(clk,reset,data[1]); module1 inst2(clk,reset,data[2]); module1 inst3(clk,reset,data[3]); always #50 clk = ~clk; initial begin $monitor($time,"clk=%b,reset=%b,%b%b%b",clk,reset,data[1],data[2],data [3]); clk = 0; reset = 1; #200 reset = 0; #200 $display("driver timeout"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr584.v000066400000000000000000000010551435245347300176140ustar00rootroot00000000000000/* * This example is based on PR#584 in the bugs database. */ module main; reg clk; always #50 clk = ~clk; initial begin clk = 0; #100 $display("%d", 1e3*2e-2); $display("%d", 1e2*0.2); $display("%d", 1e1*2); // prints ok $display("%d", 1e0*20.0); // prints ok $display("%d", 1e-1*200.0); // bug -- some correctly report "20" and others report "0" // looks like implicit real2integer conversion for every factor in expression // problem caused by partial support of reals $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr585.v000066400000000000000000000006071435245347300176170ustar00rootroot00000000000000/* * Based on PR#585. */ module main(); reg [7:0] ram_temp; reg mem; initial begin ram_temp = 8'h08; mem = (ram_temp & 8'h08) >> 3; $write("Calculated: %b\nActually in mem: %b\n",((ram_temp & 8'h08) >> 3), mem); if (mem !== 1'b1) begin $display("FAILED == mem = %b", mem); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr587.v000066400000000000000000000016501435245347300176200ustar00rootroot00000000000000/* * The x in foo and bar should always have the same value. */ module foo(); wire x; reg clk; reg [7:0] counter; always #5 clk <= ~clk; assign x = 0; initial begin clk = 0; counter = 0; # 2600 $display("PASSED"); $finish; end always @(negedge clk) if (x !== u_bar.x) begin $display("FAILED -- x != u_bar.x"); $finish; end always @(posedge clk) begin counter <= counter + 1; if (counter == 32) force x = 0; else if (counter == 64) force x = 1; else if (counter == 96) force x = 0; else if (counter == 128) release x; $display("[foo %d] x = %d",counter, x); end bar u_bar( .clk(clk), .x(x)); endmodule module bar(clk, x); input clk; input x; reg [7:0] counter; initial counter = 0; always @(posedge clk) begin counter <= counter + 1; $display("[bar %d] x = %d",counter, x); end endmodule iverilog-12_0/ivtest/ivltests/pr590.v000066400000000000000000000013711435245347300176120ustar00rootroot00000000000000module ex1 ( clk, reset, insig, outsig ); input clk; input reset; input [3:0] insig; output [3:0] outsig; reg [3:0] outsig; //reg [3:0] val_q; always @ ( insig ) begin outsig = ~(4'hf << insig); $display("out: %b, in: %b",outsig,insig); end endmodule module main; reg clk; reg reset; reg [3:0] insig; wire [3:0] outsig; ex1 ex1( .clk(clk), .reset(reset), .insig(insig), .outsig(outsig)); initial begin $display ("\n starting the testbench\n"); // set the inital value to 0 clk = 1'b0; reset = 1; insig = 4'h0; #20 insig = 4'h2; end initial #71 $finish(0); always #10 clk = ~clk; always @(posedge clk) $display ($time, "..................clock tickling"); endmodule iverilog-12_0/ivtest/ivltests/pr594.v000066400000000000000000000004671435245347300176230ustar00rootroot00000000000000module test; parameter NBytes = 21; parameter Message = "0H1d2j3i4k 5R6i7k8d9["; // Message to send integer J; reg [7:0] RSData; initial begin for (J=(NBytes-1); J>=0; J=J-1) begin RSData = (Message>>(J*8)) & 8'hFF; $display("RSData=%h", RSData); end end endmodule // test iverilog-12_0/ivtest/ivltests/pr596.v000066400000000000000000000026361435245347300176250ustar00rootroot00000000000000`timescale 1ns/1ns module lfsr_test(); parameter SIZE = 4; reg clk, reset, ena; wire [SIZE-1:0] out; initial begin //{ clk = 0; reset = 0; ena = 1'bz; #15 reset = 0; #20 reset = 1; end //} initial begin //{ //$dumpfile("lfsr_test.vcd"); // Change filename as appropriate. //$dumpvars( 0, lfsr_test); $monitor("out=%b", out); end //} always clk = #10 ~clk; lfsr_counter LF( clk, reset, out ); initial #1000 $finish(0); endmodule // gray_code module lfsr_counter( clk, reset, out ); `define W 4 parameter WIDTH = `W; parameter TAP = `W'b1001; integer N; output [WIDTH-1:0] out; input clk, reset; wire [WIDTH-1:0] gc; reg [WIDTH-1:0] lfsr, next_lfsr; reg fb_lsb, fb; always @(posedge clk or negedge reset ) begin //{ if( reset == 1'b0 ) lfsr[WIDTH-1:0] <= `W'b0; else lfsr[WIDTH-1:0] <= next_lfsr[WIDTH-1:0]; end //} always @( lfsr ) begin //{ fb_lsb = ~| lfsr[WIDTH-2:0]; fb = lfsr[WIDTH-1] ^ fb_lsb; for( N=WIDTH; N>=0; N=N-1 ) if( TAP[N] == 1 ) next_lfsr[N] = lfsr[N-1] ^ fb; else next_lfsr[N] = lfsr[N-1]; next_lfsr[0] = fb; end //} assign out[WIDTH-1:0] = {1'b0, lfsr[WIDTH-1:1]}; //(1) //assign out[WIDTH-1:0] = lfsr[WIDTH-1:0]; //(2) //assign gc[WIDTH-1:0] = out[WIDTH-1:0] ^ {1'b0, out[WIDTH-1:1]}; //(3) endmodule // gray_counter iverilog-12_0/ivtest/ivltests/pr602.v000066400000000000000000000033141435245347300176030ustar00rootroot00000000000000/* * Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This is derived from pr602. */ module main; reg [1:0] a [3:0], x; integer i; initial begin a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3; // The index expressions of this parameter expression // should be evaluated to constants. $display("a[(1-1)+0] = %b", a[(1-1)+0]); $display("a[(2-1)+0] = %b", a[(2-1)+0]); x = a[(1-1)+0]; if (x !== 2'b00) begin $display("FAILED -- x == %b", x); $finish; end x = a[(2-1)+0]; if (x !== 2'b01) begin $display("FAILED -- x == %b", x); $finish; end x <= a[(1-1)+0]; #1 if (x !== 2'b00) begin $display("FAILED -- x == %b", x); $finish; end x <= a[(2-1)+0]; #1 if (x !== 2'b01) begin $display("FAILED -- x == %b", x); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr617.v000066400000000000000000000017221435245347300176120ustar00rootroot00000000000000module main(); parameter INIT_00 = 32'hffffffff; reg [17:0] t; reg [8:0] c; reg error ; initial begin error = 0; c = 0; $display("%b",INIT_00[c]); c = 1; $display("%b",INIT_00[c]); t = {17'd0,INIT_00[0]}<<1; if(t !== 17'b0_0000_0000_0000_0010) begin $display("FAILED - shift operation {17'd0,INIT_00[0]}<<1; %b",t); error = 1; end else $display("%b",t); c = 0; t = {17'd0,INIT_00[c]}<<1; if(t !== 17'b0_0000_0000_0000_0010) begin $display("FAILED - shift operation {17'd0,INIT_00[c]}<<1 %b",t); error = 1; end else $display("%b",t); c = 16; t = {17'd0,INIT_00[c]}<<1; if(t !== 17'b0_0000_0000_0000_0010) begin $display("FAILED - shift operation {17'd0,INIT_00[c]}<<1 %b",t); error = 1; end else $display("%b",t); if(error == 1) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr622.v000066400000000000000000000001761435245347300176100ustar00rootroot00000000000000`define FOO bar module foo; initial begin $display("macro FOO = %s", ``FOO); end endmodule iverilog-12_0/ivtest/ivltests/pr632.v000066400000000000000000000003151435245347300176040ustar00rootroot00000000000000`timescale 1ns/10ps module test; reg [15:0] a1; initial begin $monitor ("a1[0]=%b",a1[0]); for (a1 = 16'h01; a1 != 16'h1f; a1 = a1 + 1) begin #1; end end endmodule iverilog-12_0/ivtest/ivltests/pr639.v000066400000000000000000000110041435245347300176100ustar00rootroot00000000000000// Icarus 0.7, cvs files from Feb 2, 2003 // -------------------------------------- // // iverilog precision.v // or // iverilog -D DUMP precision.v // vvp a.out // // Use & display of real time periods with `timescale set to 1 ns / 10 ps // // $simtime keeps time in 10ps increments // $simtime cannot be displayed (yet) // $simtime can be used in comparisons -- compared to times in 10 ps units // $time should be $simtime-rounded-to-ns // $time displays according to `timescale and $timeformat // $time can be used in comparisons -- compared to times in 1 ns units // // Assuming that the simulation runs on units of 10ps, a clock which is set to // change value every (15.2 ns)/2 should change every 7.6 ns, i.e. 760*10ps. // // The dumpfile shows a timescale of 10ps; therefore, it should show the clock // changing every 760*10ps. It doesn't. The clock is changing every 700*10ps. // The checks on the clock using $simtime below verify that the dumpfile is // seeing what the simulation is, in fact, doing. // `timescale 1 ns / 10 ps `define PERIODI 15 `define PERIODR 15.2 module top; reg tick,clk, fail; reg [31:0] ii; `ifdef DUMP initial begin $dumpvars; end `endif initial begin $timeformat(-9, 2, "ns", 20); $display("integer & real periods: 'd%0d 'd%0d",`PERIODI,`PERIODR); $display("integer & real periods (15.00, 15.20): 't%0t 't%0t",`PERIODI,`PERIODR); $display("......... %s should be displayed as 15.20 in its timeformat.", ``PERIODR); $display("integer & real periods: 'b%0b 'b%0b",`PERIODI,`PERIODR); $display("integer & real periods: 'h%0h 'h%0h",`PERIODI,`PERIODR); clk = 0; tick = 0; fail = 0; #1; if($time === 1) $display("\t$time is in ns"); if($time === 100) $display("\t$time is in 10 ps"); $display("\ttime (1, 1h): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); if($simtime === 1) $display("\t$simtime is in ns"); if($simtime === 100) $display("\t$simtime is in 10 ps"); $display("\tsimtime (100, 64h): 'd%0d, 't%0t, 'h%0h",$simtime,$simtime,$simtime); #(`PERIODI - 1); tick = 1; if($time !== 15) begin fail = 1;$display("time (15, Fh): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 1500) begin fail=1; $display("simtime not 1500"); end #(`PERIODR); tick = 0; if($time !== 30) begin fail = 1; $display("time (30, 1Eh): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 3020) begin fail=1; $display("simtime not 3020"); end #(`PERIODR); tick = 1; if($time !== 45) begin fail = 1; $display("time (45, 2Dh): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 4540) begin fail=1; $display("simtime not 4540"); end #(`PERIODR); tick = 0; if($time !== 61) begin fail = 1; $display("time (61, 3Dh): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 6060) begin fail=1; $display("simtime not 6060"); end #(`PERIODR); tick = 1; if($time !== 76) begin fail = 1; $display("time (76, 4Ch): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 7580) begin fail=1; $display("simtime not 7580"); end #(`PERIODR); tick = 1; if($time !== 91) begin fail = 1; $display("time (91, 5Bh): 'd%0d, 't%0t, 'h%0h",$time,$time,$time); end if($simtime !== 9100) begin fail=1; $display("simtime not 9100"); end $display("\t\t**********************************************"); if(fail) $display("\t\t****** time precision test FAILED *******"); else $display("\t\t****** time precision test PASSED *******"); $display("\t\t**********************************************\n"); $finish(0); end initial begin for(ii = 0; ii < 1524; ii = ii + 1) begin #(0.01); if(($simtime == 659) && (clk !== 0)) begin fail=1; $display("time: 659, clk wrong"); end if(($simtime == 701) && (clk !== 0)) begin fail=1; $display("time: 701, clk wrong"); end if(($simtime == 759) && (clk !== 0)) begin fail=1; $display("time: 759, clk wrong"); end if(($simtime == 761) && (clk !== 1)) begin fail=1; $display("time: 761, clk wrong"); end if(($simtime == 1399) && (clk !== 1)) begin fail=1; $display("time: 1399, clk wrong"); end if(($simtime == 1401) && (clk !== 1)) begin fail=1; $display("time: 1401, clk wrong"); end if(($simtime == 1519) && (clk !== 1)) begin fail=1; $display("time: 1519, clk wrong"); end if(($simtime == 1521) && (clk !== 0)) begin fail=1; $display("time: 1521, clk wrong"); end end end always begin #(`PERIODR/2) clk <= ~clk; // clock should change as follows: // T (10ps) : clk // 0 : 0 // 760 : 1 // 1520 : 0 // 2280 : 1 // 3040 : 0 // etc. end endmodule iverilog-12_0/ivtest/ivltests/pr673.v000066400000000000000000000007471435245347300176220ustar00rootroot00000000000000module main; reg[63:0] period; initial begin if (period !== 'hx) $display ("init wrong"); if (period === 'hx) $display ("init right"); else $display ("init wrong 2: %h", period); end always @ (period) begin // if (period == 10) $display("%t hurrah!",$time); if (period !== 1'bx) $display ("right %t %d", $time,period); else $display("wrong %t %d",$time,period); end initial begin #10 period = $time; #30 $display("bye."); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr675.v000066400000000000000000000004721435245347300176170ustar00rootroot00000000000000module bug; wire a, b, c, d; assign c = 1'bx; assign a = 1'b1; assign b = 1'b0; assign d = 1'bx; wire e = {c,d} == {a,b}; initial begin #2 if ((e == 1'b1) || (e == 1'b0)) $display("FAILED -- abcde=%b%b%b%b%b", a, b, c, d, e); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr678.v000066400000000000000000000014641435245347300176240ustar00rootroot00000000000000module main; real foo; real bar; initial begin foo = 1.0; bar = 1.2; if (foo >= bar) begin $display("FAILED -- foo < bar?"); $finish; end if (foo >= 1.2) begin $display("FAILED -- foo < 1.2?"); $finish; end if (1.0 >= 1.2) begin $display("FAILED -- 1.0 < 1.2?"); $finish; end if (1 >= 1.2) begin $display("FAILED -- 1 < 1.2?"); $finish; end if (foo > bar) begin $display("FAILED -- foo < bar?"); $finish; end if (foo > 1.2) begin $display("FAILED -- foo < 1.2?"); $finish; end if (1.0 > 1.2) begin $display("FAILED -- 1.0 < 1.2?"); $finish; end if (1 > 1.2) begin $display("FAILED -- 1 < 1.2?"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr685.v000066400000000000000000000016331435245347300176200ustar00rootroot00000000000000module test (clk, in, out); input clk; input [15:0] in; output [4:0] out; reg [4:0] out; (* ivl_synthesis_on *) always @(posedge clk) begin // In PR#685, this caused an assertion with iverilog -S out = (in >= 16) ? 16 : in; end endmodule module main; reg clk; reg [15:0] value; wire [4:0] sat; test dut (clk, value, sat); (* ivl_synthesis_off *) initial begin value = 0; clk = 1; for (value = 0 ; value < 'h15 ; value = value+1) begin #1 clk = 0; #1 clk = 1; #1 if ((value > 16) && (sat !== 5'd16)) begin $display("FAILED -- value=%d, sat=%b", value, sat); $finish; end if ((value <= 16) && (value !== sat)) begin $display("FAILED -- value=%d, sat=%b", value, sat); $finish; end end // for (value = 0 ; value < 'h15 ; value = value+1) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr690.dat000066400000000000000000000000041435245347300201060ustar00rootroot000000000000000 1 iverilog-12_0/ivtest/ivltests/pr690.v000066400000000000000000000012741435245347300176150ustar00rootroot00000000000000module test(CLK, OE, A, OUT); parameter numAddr = 1; parameter numOut = 1; parameter wordDepth = 2; parameter MemFile = "ivltests/pr690.dat"; input CLK, OE; input [numAddr-1:0] A; output [numOut-1:0] OUT; reg [numOut-1:0] memory[wordDepth-1:0]; reg [numAddr-1:0] addr; initial begin // The whole point of this regression test is to check that // the file name argument can be a string parameter. $readmemb(MemFile,memory, 0); if (memory[0] !== 0) begin $display("FAILED -- memory[0] == %b", memory[0]); $finish; end if (memory[1] !== 1) begin $display("FAILED -- memory[1] == %b", memory[1]); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr693.v000066400000000000000000000011041435245347300176100ustar00rootroot00000000000000/* * Notice how the port direction and type are declared * together in each statement. */ module one_a(sum,co,a,b,ci); output reg sum; output reg co; input wire a; input wire b; input wire ci; always@(a or b or ci) begin sum = a ^ b ^ ci; co = a*b || a*ci || b*ci; end endmodule module main; wire sum, co; reg [3:0] in; one_a dut (sum, co, in[0], in[1], in[2]); initial begin in = 0; #1 for (in = 0 ; in[3] == 0 ; in = in + 1) begin #1 $display("in=%b; co/sum = %b/%b", in, co, sum); end end endmodule // main iverilog-12_0/ivtest/ivltests/pr699.v000066400000000000000000000007751435245347300176330ustar00rootroot00000000000000/* * Based on Request id 1313366 in the iverilog Bugs database, or * pr699 in the ivl-bugs database. */ module bug; wire a, b, c, d; assign c = 1'b0; assign a = 1'b0; assign b = 1'b0; assign d = c ? a : b; initial begin force b = 1'b1; #1 if (b !== 1'b1) begin $display("FAILED -- b = %b", b); $finish; end if (d !== 1'b1) begin $display("FAILED -- d = %b", d); $finish; end release b; $display("PASSED"); $finish; end endmodule // bug iverilog-12_0/ivtest/ivltests/pr699b.v000066400000000000000000000010471435245347300177660ustar00rootroot00000000000000/* * Based on Request id 1313366 in the iverilog Bugs database, or * pr699 in the ivl-bugs database. * Modified to force the comparison net. */ module bug; wire a, b, c, d; assign c = 1'b0; assign a = 1'b1; assign b = 1'b0; assign d = c ? a : b; initial begin force c = 1'b1; #1 if (c !== 1'b1) begin $display("FAILED -- b = %b", b); $finish; end if (d !== 1'b1) begin $display("FAILED -- d = %b", d); $finish; end release c; $display("PASSED"); $finish; end endmodule // bug iverilog-12_0/ivtest/ivltests/pr704.hex000066400000000000000000000001711435245347300201230ustar00rootroot00000000000000/* Stub data file for regression test pr704.v */ 10101010_10101010_10101010_10101010 01010101_01010101_01010101_01010101 iverilog-12_0/ivtest/ivltests/pr704.v000066400000000000000000000007231435245347300176070ustar00rootroot00000000000000/* PR#704 */ module foo; reg [80*8:1] filename; reg [31:0] memory[1:2048]; initial filename = "ivltests/pr704.hex"; initial begin $display("The filename is %0s", filename); $readmemb(filename, memory, 1); if (memory[1] !== 32'haa_aa_aa_aa) begin $display("FAILED"); $finish; end if (memory[2] !== 32'h55_55_55_55) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr707.v000066400000000000000000000007661435245347300176210ustar00rootroot00000000000000// // Test for PR#707, NULL UDP port connections // primitive mux (x, s, a, b, f); output x; input s, a, b, f; table // s a b f mux 0 1 ? ? : 1 ; // ? = 0 1 x 0 0 ? ? : 0 ; 1 ? 1 ? : 1 ; 1 ? 0 ? : 0 ; x 0 0 ? : 0 ; x 1 1 ? : 1 ; endtable endprimitive module test; reg r1, r2, r3; wire w1; initial begin r1 = 1'b0; r2 = 1'b0; r3 = 1'b0; // If it makes it here, the code compiled $display("PASSED"); end mux udp1(w1, r1, r2, r3, /* foo */); endmodule iverilog-12_0/ivtest/ivltests/pr708.v000066400000000000000000000005471435245347300176170ustar00rootroot00000000000000module test; parameter PARM = 1.5; reg r; initial begin case (PARM) 1.0 : r <= 'd1; 1.5 : r <= 'd0; 2.0 : r <= 'd1; default: r <= 1'bx; endcase #1; if (r !== 'd0) $display("FAILED %b != 0", r); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr710.v000066400000000000000000000005451435245347300176060ustar00rootroot00000000000000module main; reg [5:0] idx, mask; wire [5:0] foo = idx & mask; initial begin mask = 5'h1f; for (idx = 0 ; idx < 5 ; idx = idx+1) wait (foo == idx) begin $display("foo=%d, idx=%d", foo, idx); if (foo !== idx) begin $display("FAILED"); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr718.v000066400000000000000000000004701435245347300176130ustar00rootroot00000000000000// // Verifies disable terminates a forked forever. // module test; initial begin fork: F forever #10; disable F; join $display("PASSED"); $finish; end initial begin #20; $display("FAILED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr721.v000066400000000000000000000007741435245347300176140ustar00rootroot00000000000000module port_test(a); parameter p_w=1<<5; // 32 parameter c_w=p_w>>4;// 2 (<--- here) output [c_w-1:0] a; wire [c_w-1:0] a='h0; initial begin $display("p_w=%b, c_w=%b", p_w, c_w); if (c_w !== 2) begin $display("FAILED -- c_w == %b", c_w); $finish; end if ($bits(a) !== 2) begin $display("FAILED -- $bits(a) == %b", $bits(a)); $finish; end $display("PASSED"); end // initial begin endmodule module main; wire [1:0] a; port_test m (.a(a)); endmodule iverilog-12_0/ivtest/ivltests/pr722.v000066400000000000000000000005531435245347300176100ustar00rootroot00000000000000/* From PR#722 * If bounds checking is in a 16bit field, this will crash. */ module test; reg [65536 : 0] mem; integer i; initial begin i = 65536; mem[i] = 1; if (mem[i] !== 1) begin $display ("FAILED -- bit %0d (%b)", i, mem[i]); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr729.v000066400000000000000000000004471435245347300176210ustar00rootroot00000000000000module main; parameter p_real = 1.2345 ; parameter p_real_x2 = p_real * 2 ; // <-- here real v_real, v_real_x2 ; initial begin v_real = p_real ; v_real_x2 = p_real * 2 ; $display("p_real=%f, v_real=%f, v_real_x2=%f", p_real, v_real, v_real_x2) ; end endmodule iverilog-12_0/ivtest/ivltests/pr734.v000066400000000000000000000005371435245347300176150ustar00rootroot00000000000000/* * Test expressions with very wide reg variables. */ module test; parameter idx = 3584; // Anything lower works reg [69119:0] mem; reg r; initial begin mem[idx] = 1; r = mem >> idx; if (r !== 1) $display("FAILED r = %b", r); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr735.v000066400000000000000000000003311435245347300176060ustar00rootroot00000000000000module main; reg [1:-10] foo; initial begin foo = 12'b0000_0000_0100; if (foo[-7-1] !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/pr748.v000066400000000000000000000042111435245347300176130ustar00rootroot00000000000000module signed_multiplier_test; reg failed_flag = 0; reg signed [5:0] s_prod; wire [2:0] u_pos_two = 3'b010; wire signed [2:0] s_pos_two = 3'sb010; wire signed [2:0] s_neg_two = 3'sb110; wire s = 1'b1; // flag to indicate signed wire u = 1'b0; // flag to indicate unsigned initial begin // unsigned positive two as first argument of multiply #1 s_prod = u_pos_two * u_pos_two; check_mult(1,u,u_pos_two,u,u_pos_two,s_prod,6'sb000100); #1 s_prod = u_pos_two * s_pos_two; check_mult(2,u,u_pos_two,s,s_pos_two,s_prod,6'sb000100); // This makes an unsigned result. #1 s_prod = u_pos_two * s_neg_two; check_mult(3,u,u_pos_two,s,s_neg_two,s_prod,6'sb001100); // signed positive two as first argument of multiply #1 s_prod = s_pos_two * u_pos_two; check_mult(4,s,s_pos_two,u,u_pos_two,s_prod,6'sb000100); #1 s_prod = s_pos_two * s_pos_two; check_mult(5,s,s_pos_two,s,s_pos_two,s_prod,6'sb000100); #1 s_prod = s_pos_two * s_neg_two; check_mult(6,s,s_pos_two,s,s_neg_two,s_prod,6'sb111100); // signed negative two as first argument of multiply // This makes an unsigned result. #1 s_prod = s_neg_two * u_pos_two; check_mult(7,s,s_neg_two,u,u_pos_two,s_prod,6'sb001100); #1 s_prod = s_neg_two * s_pos_two; check_mult(8,s,s_neg_two,s,s_pos_two,s_prod,6'sb111100); #1 s_prod = s_neg_two * s_neg_two; check_mult(9,s,s_neg_two,s,s_neg_two,s_prod,6'sb000100); if (failed_flag == 0) $display("PASSED"); $finish; end task check_mult; input [31:0] idx; input signeda; input [ 2:0] arga; input signedb; input [ 2:0] argb; input [ 5:0] result,expected; if (result !== expected) begin failed_flag = 1; $write("failed: test %0d, ",idx); if (signeda) $write("3'sb%b",arga); else $write("3 'b%b",arga); $write(" * "); if (signedb) $write("3'sb%b",argb); else $write("3 'b%b",argb); $write(" = 6'sb%b (expected 6'sb%b)\n",result,expected); end endtask endmodule iverilog-12_0/ivtest/ivltests/pr751.v000066400000000000000000000004431435245347300176100ustar00rootroot00000000000000/* * From PR#751. * The (*) can get tangled with a contracted (* *) */ module tb; reg [1:0] sel; reg [0:3] in; reg out; always @(*) out = in[sel]; initial begin $monitor($time, " %b[%b]: %b", in, sel, out); #10 in = 4'b 0100; #10 sel = 0; #10 sel = 1; #10 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/pr757.v000066400000000000000000000005361435245347300176210ustar00rootroot00000000000000module main; reg [11:0] sum; wire [10:0] a = 11'b111_0000_0000; wire [10:0] b = 11'b000_0000_1111; initial begin #1 sum = $signed(a) + $signed(b); if (sum == 12'b1111_0000_1111) $display("PASSED"); else $display("failed: %b",sum); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr772.v000066400000000000000000000007551435245347300176210ustar00rootroot00000000000000/* * Based on bug report pr772. */ module err (); parameter kuku = "AAAAA"; reg reset_b,clk; initial begin reset_b = 0; repeat (10) @(posedge clk); #1 reset_b = 1; end initial begin clk = 1'b1; #3 forever #10 clk=~clk; end always @(posedge clk or negedge reset_b) if (!reset_b) begin end else begin if ((kuku=="RRRRR") || (kuku=="AAAAA") || (kuku=="BBBBB")) $display("PASSED"); else $display("FAILED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/pr809.v000066400000000000000000000012611435245347300176130ustar00rootroot00000000000000module main; wire [1:0] a2, b2; wire [2:0] a3, b3; target #(.WA(2), .WB(2)) u1 (a2, b2); target #(.WA(3), .WB(3)) u2 (a3, b3); initial begin $display("u1.WA=%d, $bits(u1.A)=%d", u1.WA, $bits(u1.A)); $display("u1.WB=%d, $bits(u1.A)=%d", u1.WB, $bits(u1.B)); if ($bits(u1.A) != 2) begin $display("FAILED -- $bits(u1.A) = %d", $bits(u1.A)); $finish; end if ($bits(u2.A) != 3) begin $display("FAILED -- $bits(u2.A) = %d", $bits(u2.A)); $finish; end $display("PASSED"); end endmodule // main module target #(parameter WA = 4, WB = 4) (input [WA-1:0] A, output [WB-1:0] B); assign B = A; endmodule // target iverilog-12_0/ivtest/ivltests/pr809b.v000066400000000000000000000012731435245347300177600ustar00rootroot00000000000000module main; wire [1:0] a2, b2; wire [2:0] a3, b3; target #(.WA(2), .WB(2)) u1 (a2, b2); target #(.WA(3), .WB(3)) u2 (a3, b3); initial begin $display("u1.WA=%d, $bits(u1.A)=%d", u1.WA, $bits(u1.A)); $display("u1.WB=%d, $bits(u1.A)=%d", u1.WB, $bits(u1.B)); if ($bits(u1.A) != 2) begin $display("FAILED -- $bits(u1.A) = %d", $bits(u1.A)); $finish; end if ($bits(u2.A) != 3) begin $display("FAILED -- $bits(u2.A) = %d", $bits(u2.A)); $finish; end $display("PASSED"); end endmodule // main module target #(parameter WA = 4, parameter WB = 4) (input [WA-1:0] A, output [WB-1:0] B); assign B = A; endmodule // target iverilog-12_0/ivtest/ivltests/pr810.v000066400000000000000000000017761435245347300176160ustar00rootroot00000000000000/* * See PR#810 in the test suite. */ `timescale 1 ns / 1 ps module RR64X1_4LA1 (); parameter I_AADR_01_DOA_01_T2 = 1.167000; parameter I_AADR_10_DOA_01_T2 = 1.176000; parameter taaa_d1 = ( I_AADR_01_DOA_01_T2 > I_AADR_10_DOA_01_T2 ) ? I_AADR_01_DOA_01_T2 : I_AADR_10_DOA_01_T2; parameter I_AADR_01_DOA_10_T2 = 1.276000; parameter I_AADR_10_DOA_10_T2 = 1.267000; parameter taaa_d0 = ( I_AADR_01_DOA_10_T2 > I_AADR_10_DOA_10_T2 ) ? I_AADR_01_DOA_10_T2 : I_AADR_10_DOA_10_T2; parameter taaa = ( taaa_d1 > taaa_d0 ) ? taaa_d1 : taaa_d0; initial begin if (taaa_d1 != I_AADR_10_DOA_01_T2) begin $display("FAILED -- taaa_d1=%f", taaa_d1); $finish; end if (taaa_d0 != I_AADR_01_DOA_10_T2) begin $display("FAILED -- taaa_d0=%f", taaa_d0); $finish; end if (taaa != taaa_d0) begin $display("FAILED -- taaa=%f", taaa); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/pr812.v000066400000000000000000000015041435245347300176050ustar00rootroot00000000000000//////////////////////////////////////////////////////////////////////// // Copyright 2003 University of Kentucky // // This file is released into the public domain //////////////////////////////////////////////////////////////////////// // // Top level module // module top(); parameter tp = 'd1; reg a; wire b; bot b1(b, a); initial begin a = 0; $display("tp = %d in top", tp); end endmodule // // bottom level module // `define div 0.100 module bot(a, b); input b; output a; real tp; // tp is overridden by tp parameter in top real tp2; assign a = b; initial begin tp = 1 / `div; tp2 = 1 / `div; $display("tp = %f, tp2 = %f", tp, tp2); if (tp != 10.0) $display("tp != 10.0. (tp = %f)", tp); else $display("tp == 10, (expected)"); #1 $display("tp = %f, tp2 = %f", tp, tp2); end endmodule iverilog-12_0/ivtest/ivltests/pr820.v000066400000000000000000000023751435245347300176130ustar00rootroot00000000000000/* Extracted from PR#820. */ module main(); wire clk; wire reset; reg [3:0] waddr, raddr; reg [7:0] wdata; wire [7:0] rdata; clk_reset_gen cg(clk, reset); ram_rw #(8,4) r(clk, waddr, wdata, 1'b1, raddr, rdata); initial begin waddr = 4'd0; raddr = 4'd14; wdata = 0; #3001; $finish(0); end always @(posedge clk) begin waddr <= #1 waddr + 1; raddr <= #1 raddr + 1; wdata <= #1 wdata + 3; end always @(posedge clk) $display($time,,"waddr wdata %d %d raddr rdata %d %d",waddr,wdata,raddr,rdata); endmodule module ram_rw(clk,waddr,wdata,we,raddr,rdata); parameter WDATA = 8; parameter WADDR = 11; input clk; input [(WADDR-1):0] waddr; input [(WDATA-1):0] wdata; input we; input [(WADDR-1):0] raddr; output [(WDATA-1):0] rdata; //local reg [(WDATA-1):0] mem[0:((1< %b", A, B, select, out); end end endmodule primitive prim_mux2( output out, input in1, input in0, input select); table //in1 in0 select : out 0 0 1 : 0; 1 1 ? : 1; 0 ? 1 : 0; 1 ? 1 : 1; ? 0 0 : 0; ? 1 0 : 1; endtable endprimitive iverilog-12_0/ivtest/ivltests/pr938b_std.v000066400000000000000000000012551435245347300206350ustar00rootroot00000000000000/* * This is derived from PR#938 in the test suite. */ `timescale 1ns/100ps module test; wire out; reg A, B, select; prim_mux2 mux (out, B, A, select); reg [3:0] cnt; initial begin $display("A B S out"); for (cnt = 0 ; cnt <= 'b0111 ; cnt = cnt + 1) begin A <= cnt[0]; B <= cnt[1]; select <= cnt[2]; #1 $display("%b %b %b --> %b", A, B, select, out); end end endmodule primitive prim_mux2( output out, input in1, input in0, input select); table //in1 in0 select : out 0 0 1 : 0; 1 1 ? : 1; 0 ? 1 : 0; 1 ? 1 : 1; ? 0 0 : 0; ? 1 0 : 1; endtable endprimitive iverilog-12_0/ivtest/ivltests/pr941.v000066400000000000000000000005711435245347300176130ustar00rootroot00000000000000/* * Based on PR#941. * This tests that trivial contant expressions passed as input to * user defined tasks will work. A possible bug would be that the * addition expression gets useless code generated. */ module test; task foo; input [16:0] in1; begin $display("%d", in1); $display("PASSED"); end endtask initial begin foo(16'h00 + 'h00); end endmodule iverilog-12_0/ivtest/ivltests/pr973.v000066400000000000000000000007561435245347300176250ustar00rootroot00000000000000module main; real foo; initial begin foo = 1.0; if (foo != 1.0) begin $display("FAILED: Simple assign works not. foo=%f", foo); $finish; end foo <= 1.5; if (foo != 1.0) begin $display("FAILED: nb assign works too fast. foo=%f", foo); $finish; end #1 if (foo != 1.5) begin $display("FAILED: nb assign works not. foo=%f", foo); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/pr978.v000066400000000000000000000006641435245347300176300ustar00rootroot00000000000000/* * This test is based on PR#978. * Check that user defined functions can have real-valued * results, and that the result gets properly returned. */ module test(); real m; function real dummy; input b; begin dummy=2.5; end endfunction initial begin m=dummy(0); if (m != 2.5) begin $display("FAILED: return result is %f", m); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/pr979.v000066400000000000000000000006141435245347300176240ustar00rootroot00000000000000module test(); real r; initial begin r=0.25; $write("%f %b %f\n",r, $realtobits(r), $bitstoreal($realtobits(r))); r=0.5; $write("%f %b %f\n",r, $realtobits(r), $bitstoreal($realtobits(r))); $display("neg reals don't work"); r=-0.25; $write("%f %b %f\n",r, $realtobits(r), $bitstoreal($realtobits(r))); r=-0.5; $write("%f %b %f\n",r, $realtobits(r), $bitstoreal($realtobits(r))); end endmodule iverilog-12_0/ivtest/ivltests/pr985.v000066400000000000000000000020021435245347300176120ustar00rootroot00000000000000`define ADDR_DEC_W 8 // Number of bits used to decode. `define ADDR_DEVICE0 `ADDR_DEC_W'h10 // Device 0 located at address 20xx_xxxxh `define ADDR_DEVICE1 `ADDR_DEC_W'h1F // Device 1 located at address 20xx_xxxxh module top ( ) ; // Instantiation of the module // child_module #(`ADDR_DEC_W, `ADDR_DEVICE0, `ADDR_DEVICE1) my_module ( ); initial begin #1 ; end endmodule module child_module ( ); // Parameters: parameter dec_addr_w = 4 ; parameter t0_addr = 4'd0 ; parameter t1_addr = 4'd0 ; // Instantiation of the grandchild module // grandchild_module #(dec_addr_w, t0_addr, t1_addr) my_grandchild_module ( ); initial begin $display ("CHILD parameters are: %h %h %h", dec_addr_w, t0_addr, t1_addr) ; end endmodule module grandchild_module ( ); // Parameters: parameter dec_addr_w = 4 ; parameter t0_addr = 4'd0 ; parameter t1_addr = 4'd0 ; initial begin $display ("GRANDCHILD parameters are: %h %h %h", dec_addr_w, t0_addr, t1_addr) ; end endmodule iverilog-12_0/ivtest/ivltests/pr987.v000066400000000000000000000007621435245347300176270ustar00rootroot00000000000000/* * This test program should cause the message "Hello, World" to * display twice. The first when the always thread runs and gets * stuck in the wait, and the second when the block is disabled, * and the alwas thread starts it over again. */ module main; always begin :restartable $display("Test thread runs."); wait (0); $display("FAILED: Should never get here."); end initial begin #10 disable restartable; #10 $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/pr990.v000066400000000000000000000005641435245347300176210ustar00rootroot00000000000000/* * This is a reuced version of PR#990, that captures the essence. * Or at least the bug being reported. */ module bug(); reg [31:0] x; wire y; assign y = x == 0; initial begin $display("y: %b", y); x = 0; #0; $display("y: %b", y); if (y === 1'b1) // if x is 0, then x==0 is 1. $display("PASSED"); else $display("FAILED"); end endmodule // bug iverilog-12_0/ivtest/ivltests/pr991.v000066400000000000000000000010221435245347300176100ustar00rootroot00000000000000/* * This test file is based on PR991. */ module bug(); wire _d1,_d2,test,test1,test2,test3; assign _d1 = 1; assign _d2 = 0; assign test = (_d1 && _d2) != 0; assign test1 = (_d1 && _d2) == 0; assign test2 = (_d1 && _d2) !== 0; assign test3 = (_d1 && _d2) === 0; initial begin #1; $displayb(_d2); // Should be 0 $displayb(test); // Should be 0 (1 && 0) != 0 --> 0 != 0 $displayb(test1); // Should be 1 $displayb(test2); // Should be 0 $displayb(test3); // Should be 1 end endmodule iverilog-12_0/ivtest/ivltests/pr993.v000066400000000000000000000013441435245347300176210ustar00rootroot00000000000000/* * This example is a distillation of the essence of PR#993. * Or at least the essence that led to a bug report. */ module main; integer length; wire [31:0] length_bits = ((length * 8 )/11)+(((length * 8 )%11) != 0); reg [31:0] length_bits2; initial begin for (length = 1 ; length < 56 ; length = length + 1) begin length_bits2 = ((length * 8 )/11)+(((length * 8 )%11) != 0); #1 $display("length=%3d, length_bits=%3d (%3d)", length, length_bits, length_bits2); if (length_bits != length_bits2) begin $display("FAILED - Expressions have different results."); $finish; end end // for (length = 1 ; length < 56 ; length = length + 1) $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/pr995.v000066400000000000000000000020421435245347300176170ustar00rootroot00000000000000/* * This test runs the random number generator to make sure * it follows the standard algorithm. It is based on the bug * report from PR#995. */ module pr995 (); integer seed; integer i; integer result; initial begin seed = 1; $display ("Start sequence: seed=%h", seed); result=$random(seed); $display ("seed=%h result=%h", seed, result); for (i=0; i<30; i=i+1) begin result=$random(seed); $display ("seed=%h result=%h", seed, result); end seed = 2; $display ("Start sequence: seed=%h", seed); result=$random(seed); $display ("seed=%h result=%h", seed, result); for (i=0; i<30; i=i+1) begin result=$random(seed); $display ("seed=%h result=%h", seed, result); end seed = 1; $display ("Start sequence: seed=%h", seed); result=$random(seed); $display ("seed=%h result=%h", seed, result); for (i=0; i<30; i=i+1) begin result=$random(seed); $display ("seed=%h result=%h", seed, result); end end endmodule // rand iverilog-12_0/ivtest/ivltests/prng.v000066400000000000000000000015071435245347300177020ustar00rootroot00000000000000// // Verifies that the PRNG seed streams are unique, well trys anyway. // module test; reg [31:0] rtn; reg [31:0] pseed, seed1, seed2; reg [31:0] mem1[3:0], mem2[3:0]; integer i; initial begin seed1 = 32'hcafe_babe; seed2 = 32'hdead_beef; // Isolated stream for (i = 0; i < 4; i = i + 1) begin mem1[i] = $random(seed1); end // Pull from multiple streams seed1 = 32'hcafe_babe; seed2 = 32'hdead_beef; for (i = 0; i < 4; i = i + 1) begin mem2[i] = $random(seed1); // pull more values from other pools rtn = $random(seed2); rtn = $random; end // Verify the seed1 streams match for (i = 0; i < 4; i = i + 1) begin if (mem1[i] != mem2[i]) begin $display("FAILED %0d: %x != %x", i, mem1[i], mem2[i]); $finish; end end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/program2.v000066400000000000000000000007521435245347300204660ustar00rootroot00000000000000// This program block demonstrates that initial and final blocks // work, and that program variables work as well. program main; int foo; int bar; initial begin bar = 1; for (foo = 1 ; foo < 10 ; ++foo) begin bar = bar * foo; $display("foo = %d, bar=%d", foo, bar); end end final begin if (foo !== 10 || bar !== 362_880) begin $display("FAILED -- foo=%d", foo); end else begin $display("PASSED"); end end endprogram // main iverilog-12_0/ivtest/ivltests/program2b.v000066400000000000000000000005511435245347300206250ustar00rootroot00000000000000program main; int foo; int bar; initial begin bar = 1; for (foo = 1 ; foo < 10 ; ++foo) begin bar <= bar * foo; #1 $display("foo = %d, bar=%d", foo, bar); end end final begin if (foo !== 10 || bar !== 362_880) begin $display("FAILED -- foo=%d", foo); end else $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/program3.v000066400000000000000000000012031435245347300204570ustar00rootroot00000000000000// This test program shows how programs can be contained by // modules, and can access variables in the context. module main; reg[7:0] shared; wire [7:0] not_shared = ~shared; program test1; initial shared <= 'h55; endprogram :test1 program test2; reg [7:0] tmp; final begin if (shared !== 'h55) begin $display("FAILED -- shared=%b is not correct", shared); $finish; end tmp = ~shared; if (not_shared !== 'haa || not_shared !== tmp) begin $display("FAILED -- not_shared is not correct", not_shared); $finish; end $display("PASSED"); end endprogram :test2 endmodule // main iverilog-12_0/ivtest/ivltests/program3a.v000066400000000000000000000011161435245347300206230ustar00rootroot00000000000000// This should generate an error module main; reg[7:0] shared; wire [7:0] not_shared = ~shared; program test1; initial shared = 'h55; // ERROR: only non-blocking assign allowed here. endprogram :test1 program test2; reg [7:0] tmp; final begin if (shared !== 'h55) begin $display("FAILED -- shared=%b is not correct", shared); $finish; end tmp = ~shared; if (not_shared !== 'haa) begin $display("FAILED == not_shared is not correct", not_shared); $finish; end $display("PASSED"); end endprogram :test2 endmodule // main iverilog-12_0/ivtest/ivltests/program3b.v000066400000000000000000000011151435245347300206230ustar00rootroot00000000000000// This should generate an error module main; reg[7:0] shared; wire [7:0] not_shared = ~shared; program test1; initial shared <= 'h55; endprogram :test1 program test2; reg [7:0] tmp; final begin if (shared !== 'h55) begin $display("FAILED -- shared=%b is not correct", shared); $finish; end tmp <= ~shared; // ERROR: only blocking assign in final block if (not_shared !== 'haa) begin $display("FAILED -- not_shared is not correct", not_shared); $finish; end $display("PASSED"); end endprogram :test2 endmodule // main iverilog-12_0/ivtest/ivltests/program4.v000066400000000000000000000010341435245347300204620ustar00rootroot00000000000000// This test program shows how programs can be instantiated // within another module. program test(input [7:0] sh1, input [7:0] sh2); final begin if (sh1 !== 'h55) begin $display("FAILED -- shared=%b is not correct", sh1); $finish; end if (sh2 !== 'haa) begin $display("FAILED -- sh2 not correct", sh2); $finish; end $display("PASSED"); end endprogram :test module main; reg[7:0] shared = 'h55; wire [7:0] not_shared = ~shared; test check(shared, not_shared); endmodule // main iverilog-12_0/ivtest/ivltests/program5a.v000066400000000000000000000002441435245347300206260ustar00rootroot00000000000000program main; reg foo; // It is NOT legal to nest modules in program blocks. module test; initial $display("FAILED"); endmodule // test endprogram // main iverilog-12_0/ivtest/ivltests/program5b.v000066400000000000000000000003611435245347300206270ustar00rootroot00000000000000module test(input wire foo); initial $display("FAILED", foo); final $display(foo); endmodule // test program main; reg foo = 1; // It is not legal to instantiate modules in program blocks test dut(foo); endprogram // main iverilog-12_0/ivtest/ivltests/program_hello.v000066400000000000000000000004351435245347300215650ustar00rootroot00000000000000// This is the most trivial example of a program block. // It contains only an initial statement and final statement, // and prints "PASSED" so the test bench knows that it works. program main (); initial $display("Hello, World."); final $display("PASSED"); endprogram : main iverilog-12_0/ivtest/ivltests/program_hello2.v000066400000000000000000000003311435245347300216420ustar00rootroot00000000000000// This trivial program is NOT valid. "always" blocks are not // valid in program blocks. program main (); initial $display("Hello, World."); always #1 $finish; final $display("FAILED"); endprogram : main iverilog-12_0/ivtest/ivltests/ptest001.v000066400000000000000000000025551435245347300203200ustar00rootroot00000000000000// // Copyright (c) 1999 Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; reg clk,reset; wire [3:0] a,b; swap s(clk,reset,a,b); initial begin clk = 0; reset = 0; #1; reset = 1; #1; reset = 0; #1; clk = 1; #5; clk = 0; if (a===4'd6 && b===4'd5) $display("PASSED"); else $display("FAILED"); end endmodule module swap(clk,reset,a,b); input clk,reset; output [3:0] a,b; reg [3:0] a,b; always @(posedge clk or posedge reset) if (reset) begin a <= #1 4'd5; b <= #1 4'd6; end else begin a <= #1 b; b <= #1 a; end endmodule iverilog-12_0/ivtest/ivltests/ptest002.v000066400000000000000000000020271435245347300203130ustar00rootroot00000000000000// // Copyright (c) 1999 Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; reg [3:0] b; wire [1:0] a; assign a = b[3:2] + 1; initial begin b = 4'b1011; #1; if (a===2'b11) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/ptest003.v000066400000000000000000000020671435245347300203200ustar00rootroot00000000000000// // Copyright (c) 1999 Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; parameter PARM = 2; reg [3:0] b; wire [1:0] a; assign a = b[3:(3-PARM+1)] + 1; initial begin b = 4'b1011; #1; if (a===2'b11) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/ptest004.v000066400000000000000000000020611435245347300203130ustar00rootroot00000000000000// // Copyright (c) 1999 Peter Monta (pmonta@imedia.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; wire [3:0] b; reg [1:0] a; reg c; assign b = c< e; `check(x, 4'b0100) // Partially oob at high and low side x = 'h0; x[4:-1] <= @e 6'b101010; -> e; `check(x, 4'b0101) // Partially oob at low side x = 'h0; x[0:-1] <= @e 2'b10; -> e; `check(x, 4'b0001) // Partially oob at high side x = 'h0; x[4:3] <= @e 2'b01; -> e; `check(x, 4'b1000) // Fully oob at low side x = 'h0; x[-1:-2] <= @e 2'b11; -> e; `check(x, 4'b0000) // Fully oob at high side x = 'h0; x[6:5] <= @e 2'b11; -> e; `check(x, 4'b0000) // Variable index // Within bounds i = 1; x = 'h0; x[i+:2] <= @e 2'b10; -> e; `check(x, 4'b0100) // Partially oob at high and low side i = -1; x = 'h0; x[i+:6] <= @e 6'b101010; -> e; `check(x, 4'b0101) // Partially oob at low side i = -1; x = 'h0; x[i+:2] <= @e 2'b10; -> e; `check(x, 4'b0001) // Partially oob at high side i = 3; x = 'h0; x[i+:2] <= @e 2'b01; -> e; `check(x, 4'b1000) // Fully oob at low side i = -2; x = 'h0; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'b0000) // Fully oob at high side i = 5; x = 'h0; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'b0000) // Undefined index i = 'hx; x = 'h0; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'b0000) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec2a.v000066400000000000000000000034241435245347300211510ustar00rootroot00000000000000// Check that blocking partial writes to a 2-state vector array element are // correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end bit [3:0] x[1:0]; integer i; initial begin // Immediate index // Within bounds x[0] = 'h0; x[0][2:1] = 2'b10; `check(x[0], 4'b0100) // Partially oob at high and low side x[0] = 'h0; x[0][4:-1] = 6'b101010; `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'h0; x[0][0:-1] = 2'b10; `check(x[0], 4'b0001) // Partially oob at high side x[0] = 'h0; x[0][4:3] = 2'b01; `check(x[0], 4'b1000) // Fully oob at low side x[0] = 'h0; x[0][-1:-2] = 2'b11; `check(x[0], 4'b0000) // Fully oob at high side x[0] = 'h0; x[0][6:5] = 2'b11; `check(x[0], 4'b0000) // Variable index // Within bounds i = 1; x[0] = 'h0; x[0][i+:2] = 2'b10; `check(x[0], 4'b0100) // Partially oob at high and low side i = -1; x[0] = 'h0; x[0][i+:6] = 6'b101010; `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'h0; x[0][i+:2] = 2'b10; `check(x[0], 4'b0001) // Partially oob at high side i = 3; x[0] = 'h0; x[0][i+:2] = 2'b01; `check(x[0], 4'b1000) // Fully oob at low side i = -2; x[0] = 'h0; x[0][i+:2] = 2'b11; `check(x[0], 4'b0000) // Fully oob at high side i = 5; x[0] = 'h0; x[0][i+:2] = 2'b11; `check(x[0], 4'b0000) // Undefined index i = 'hx; x[0] = 'h0; x[0][i+:2] = 2'b11; `check(x[0], 4'b0000) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec2a_nb.v000066400000000000000000000036031435245347300216270ustar00rootroot00000000000000// Check that non-blocking partial writes to a 2-state vector array element are // correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end bit [3:0] x[1:0]; integer i; initial begin // Immediate index // Within bounds x[0] = 'h0; x[0][2:1] <= 2'b10; #1 `check(x[0], 4'b0100) // Partially oob at high and low side x[0] = 'h0; x[0][4:-1] <= 6'b101010; #1 `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'h0; x[0][0:-1] <= 2'b10; #1 `check(x[0], 4'b0001) // Partially oob at high side x[0] = 'h0; x[0][4:3] <= 2'b01; #1 `check(x[0], 4'b1000) // Fully oob at low side x[0] = 'h0; x[0][-1:-2] <= 2'b11; #1 `check(x[0], 4'b0000) // Fully oob at high side x[0] = 'h0; x[0][6:5] <= 2'b11; #1 `check(x[0], 4'b0000) // Variable index // Within bounds i = 1; x[0] = 'h0; x[0][i+:2] = 2'b10; #1 `check(x[0], 4'b0100) // Partially oob at high and low side i = -1; x[0] = 'h0; x[0][i+:6] <= 6'b101010; #1 `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'h0; x[0][i+:2] <= 2'b10; #1 `check(x[0], 4'b0001) // Partially oob at high side i = 3; x[0] = 'h0; x[0][i+:2] <= 2'b01; #1 `check(x[0], 4'b1000) // Fully oob at low side i = -2; x[0] = 'h0; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'b0000) // Fully oob at high side i = 5; x[0] = 'h0; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'b0000) // Undefined index i = 'hx; x[0] = 'h0; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'b0000) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec2a_nb_ec.v000066400000000000000000000037571435245347300223100ustar00rootroot00000000000000// Check that non-blocking event controlled partial writes to a 2-state vector // array element are correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end bit [3:0] x[1:0]; integer i; event e; initial begin // Immediate index // Within bounds x[0] = 'h0; x[0][2:1] <= @e 2'b10; -> e; `check(x[0], 4'b0100) // Partially oob at high and low side x[0] = 'h0; x[0][4:-1] <= @e 6'b101010; -> e; `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'h0; x[0][0:-1] <= @e 2'b10; -> e; `check(x[0], 4'b0001) // Partially oob at high side x[0] = 'h0; x[0][4:3] <= @e 2'b01; -> e; `check(x[0], 4'b1000) // Fully oob at low side x[0] = 'h0; x[0][-1:-2] <= @e 2'b11; -> e; `check(x[0], 4'b0000) // Fully oob at high side x[0] = 'h0; x[0][6:5] <= @e 2'b11; -> e; `check(x[0], 4'b0000) // Variable index // Within bounds i = 1; x[0] = 'h0; x[0][i+:2] <= @e 2'b10; -> e; `check(x[0], 4'b0100) // Partially oob at high and low side i = -1; x[0] = 'h0; x[0][i+:6] <= @e 6'b101010; -> e; `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'h0; x[0][i+:2] <= @e 2'b10; -> e; `check(x[0], 4'b0001) // Partially oob at high side i = 3; x[0] = 'h0; x[0][i+:2] <= @e 2'b01; -> e; `check(x[0], 4'b1000) // Fully oob at low side i = -2; x[0] = 'h0; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'b0000) // Fully oob at high side i = 5; x[0] = 'h0; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'b0000) // Undefined index i = 'hx; x[0] = 'h0; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'b0000) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4.v000066400000000000000000000032201435245347300210040ustar00rootroot00000000000000// Check that blocking partial writes to a 4-state vector are correctly // handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x; integer i; initial begin // Immediate index // Within bounds x = 'hx; x[2:1] = 2'b10; `check(x, 4'bx10x) // Partially oob at high and low side x = 'hx; x[4:-1] = 6'b101010; `check(x, 4'b0101) // Partially oob at low side x = 'hx; x[0:-1] = 2'b10; `check(x, 4'bxxx1) // Partially oob at high side x = 'hx; x[4:3] = 2'b01; `check(x, 4'b1xxx) // Fully oob at low side x = 'hx; x[-1:-2] = 2'b11; `check(x, 4'bxxxx) // Fully oob at high side x = 'hx; x[6:5] = 2'b11; `check(x, 4'bxxxx) // Variable index // Within bounds i = 1; x = 'hx; x[i+:2] = 2'b10; `check(x, 4'bx10x) // Partially oob at high and low side i = -1; x = 'hx; x[i+:6] = 6'b101010; `check(x, 4'b0101) // Partially oob at low side i = -1; x = 'hx; x[i+:2] = 2'b10; `check(x, 4'bxxx1) // Partially oob at high side i = 3; x = 'hx; x[i+:2] = 2'b01; `check(x, 4'b1xxx) // Fully oob at low side i = -2; x = 'hx; x[i+:2] = 2'b11; `check(x, 4'bxxxx) // Fully oob at high side i = 5; x = 'hx; x[i+:2] = 2'b11; `check(x, 4'bxxxx) // Undefined index i = 'hx; x = 'hx; x[i+:2] = 2'b11; `check(x, 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4_nb.v000066400000000000000000000033641435245347300214740ustar00rootroot00000000000000// Check that non-blocking partial writes to a 4-state vector are correctly // handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x; integer i; initial begin // Immediate index // Within bounds x = 'hx; x[2:1] <= 2'b10; #1 `check(x, 4'bx10x) // Partially oob at high and low side x = 'hx; x[4:-1] <= 6'b101010; #1 `check(x, 4'b0101) // Partially oob at low side x = 'hx; x[0:-1] <= 2'b10; #1 `check(x, 4'bxxx1) // Partially oob at high side x = 'hx; x[4:3] <= 2'b01; #1 `check(x, 4'b1xxx) // Fully oob at low side x = 'hx; x[-1:-2] <= 2'b11; #1 `check(x, 4'bxxxx) // Fully oob at high side x = 'hx; x[6:5] <= 2'b11; #1 `check(x, 4'bxxxx) // Variable index // Within bounds i = 1; x = 'hx; x[i+:2] = 2'b10; `check(x, 4'bx10x) // Partially oob at high and low side i = -1; x = 'hx; x[i+:6] <= 6'b101010; #1 `check(x, 4'b0101) // Partially oob at low side i = -1; x = 'hx; x[i+:2] <= 2'b10; #1 `check(x, 4'bxxx1) // Partially oob at high side i = 3; x = 'hx; x[i+:2] <= 2'b01; #1 `check(x, 4'b1xxx) // Fully oob at low side i = -2; x = 'hx; x[i+:2] <= 2'b11; #1 `check(x, 4'bxxxx) // Fully oob at high side i = 5; x = 'hx; x[i+:2] <= 2'b11; #1 `check(x, 4'bxxxx) // Undefined index i = 'hx; x = 'hx; x[i+:2] <= 2'b11; #1 `check(x, 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4_nb_ec.v000066400000000000000000000035471435245347300221460ustar00rootroot00000000000000// Check that non-blocking event controlled partial writes to a 4-state vector // are correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x; integer i; event e; initial begin // Immediate index // Within bounds x = 'hx; x[2:1] <= @e 2'b10; -> e; `check(x, 4'bx10x) // Partially oob at high and low side x = 'hx; x[4:-1] <= @e 6'b101010; -> e; `check(x, 4'b0101) // Partially oob at low side x = 'hx; x[0:-1] <= @e 2'b10; -> e; `check(x, 4'bxxx1) // Partially oob at high side x = 'hx; x[4:3] <= @e 2'b01; -> e; `check(x, 4'b1xxx) // Fully oob at low side x = 'hx; x[-1:-2] <= @e 2'b11; -> e; `check(x, 4'bxxxx) // Fully oob at high side x = 'hx; x[6:5] <= @e 2'b11; -> e; `check(x, 4'bxxxx) // Variable index // Within bounds i = 1; x = 'hx; x[i+:2] <= @e 2'b10; -> e; `check(x, 4'bx10x) // Partially oob at high and low side i = -1; x = 'hx; x[i+:6] <= @e 6'b101010; -> e; `check(x, 4'b0101) // Partially oob at low side i = -1; x = 'hx; x[i+:2] <= @e 2'b10; -> e; `check(x, 4'bxxx1) // Partially oob at high side i = 3; x = 'hx; x[i+:2] <= @e 2'b01; -> e; `check(x, 4'b1xxx) // Fully oob at low side i = -2; x = 'hx; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'bxxxx) // Fully oob at high side i = 5; x = 'hx; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'bxxxx) // Undefined index i = 'hx; x = 'hx; x[i+:2] <= @e 2'b11; -> e; `check(x, 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4a.v000066400000000000000000000034301435245347300211500ustar00rootroot00000000000000// Check that blocking partial writes to a 4-state vector array element are // correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x[1:0]; integer i; initial begin // Immediate index // Within bounds x[0] = 'hx; x[0][2:1] = 2'b10; `check(x[0], 4'bx10x) // Partially oob at high and low side x[0] = 'hx; x[0][4:-1] = 6'b101010; `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'hx; x[0][0:-1] = 2'b10; `check(x[0], 4'bxxx1) // Partially oob at high side x[0] = 'hx; x[0][4:3] = 2'b01; `check(x[0], 4'b1xxx) // Fully oob at low side x[0] = 'hx; x[0][-1:-2] = 2'b11; `check(x[0], 4'bxxxx) // Fully oob at high side x[0] = 'hx; x[0][6:5] = 2'b11; `check(x[0], 4'bxxxx) // Variable index // Within bounds i = 1; x[0] = 'hx; x[0][i+:2] = 2'b10; `check(x[0], 4'bx10x) // Partially oob at high and low side i = -1; x[0] = 'hx; x[0][i+:6] = 6'b101010; `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'hx; x[0][i+:2] = 2'b10; `check(x[0], 4'bxxx1) // Partially oob at high side i = 3; x[0] = 'hx; x[0][i+:2] = 2'b01; `check(x[0], 4'b1xxx) // Fully oob at low side i = -2; x[0] = 'hx; x[0][i+:2] = 2'b11; `check(x[0], 4'bxxxx) // Fully oob at high side i = 5; x[0] = 'hx; x[0][i+:2] = 2'b11; `check(x[0], 4'bxxxx) // Undefined index i = 'hx; x[0] = 'hx; x[0][i+:2] = 2'b11; `check(x[0], 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4a_nb.v000066400000000000000000000036021435245347300216300ustar00rootroot00000000000000// Check that non-blocking partial writes to a 4-state vector array element are // correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x[1:0]; integer i; initial begin // Immediate index // Within bounds x[0] = 'hx; x[0][2:1] <= 2'b10; #1 `check(x[0], 4'bx10x) // Partially oob at high and low side x[0] = 'hx; x[0][4:-1] <= 6'b101010; #1 `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'hx; x[0][0:-1] <= 2'b10; #1 `check(x[0], 4'bxxx1) // Partially oob at high side x[0] = 'hx; x[0][4:3] <= 2'b01; #1 `check(x[0], 4'b1xxx) // Fully oob at low side x[0] = 'hx; x[0][-1:-2] <= 2'b11; #1 `check(x[0], 4'bxxxx) // Fully oob at high side x[0] = 'hx; x[0][6:5] <= 2'b11; #1 `check(x[0], 4'bxxxx) // Variable index // Within bounds i = 1; x[0] = 'hx; x[0][i+:2] <= 2'b10; #1 `check(x[0], 4'bx10x) // Partially oob at high and low side i = -1; x[0] = 'hx; x[0][i+:6] <= 6'b101010; #1 `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'hx; x[0][i+:2] <= 2'b10; #1 `check(x[0], 4'bxxx1) // Partially oob at high side i = 3; x[0] = 'hx; x[0][i+:2] <= 2'b01; #1 `check(x[0], 4'b1xxx) // Fully oob at low side i = -2; x[0] = 'hx; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'bxxxx) // Fully oob at high side i = 5; x[0] = 'hx; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'bxxxx) // Undefined index i = 5; x[0] = 'hx; x[0][i+:2] <= 2'b11; #1 `check(x[0], 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/pv_wr_vec4a_nb_ec.v000066400000000000000000000037571435245347300223120ustar00rootroot00000000000000// Check that non-blocking event controlled partial writes to a 4-state vector // array element are correctly handlded. module test; reg failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED. Got %b, expected %b.", val, exp); \ failed = 1'b1; \ end reg [3:0] x[1:0]; integer i; event e; initial begin // Immediate index // Within bounds x[0] = 'hx; x[0][2:1] <= @e 2'b10; -> e; `check(x[0], 4'bx10x) // Partially oob at high and low side x[0] = 'hx; x[0][4:-1] <= @e 6'b101010; -> e; `check(x[0], 4'b0101) // Partially oob at low side x[0] = 'hx; x[0][0:-1] <= @e 2'b10; -> e; `check(x[0], 4'bxxx1) // Partially oob at high side x[0] = 'hx; x[0][4:3] <= @e 2'b01; -> e; `check(x[0], 4'b1xxx) // Fully oob at low side x[0] = 'hx; x[0][-1:-2] <= @e 2'b11; -> e; `check(x[0], 4'bxxxx) // Fully oob at high side x[0] = 'hx; x[0][6:5] <= @e 2'b11; -> e; `check(x[0], 4'bxxxx) // Variable index // Within bounds i = 1; x[0] = 'hx; x[0][i+:2] <= @e 2'b10; -> e; `check(x[0], 4'bx10x) // Partially oob at high and low side i = -1; x[0] = 'hx; x[0][i+:6] <= @e 6'b101010; -> e; `check(x[0], 4'b0101) // Partially oob at low side i = -1; x[0] = 'hx; x[0][i+:2] <= @e 2'b10; -> e; `check(x[0], 4'bxxx1) // Partially oob at high side i = 3; x[0] = 'hx; x[0][i+:2] <= @e 2'b01; -> e; `check(x[0], 4'b1xxx) // Fully oob at low side i = -2; x[0] = 'hx; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'bxxxx) // Fully oob at high side i = 5; x[0] = 'hx; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'bxxxx) // Undefined index i = 'hx; x[0] = 'hx; x[0][i+:2] <= @e 2'b11; -> e; `check(x[0], 4'bxxxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/qmark.v000066400000000000000000000031611435245347300200450ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate the ? operator module main; reg globvar; reg [3:0] bvec,var1,var2,var3; reg cond, a,b,out1,out2; reg error; initial begin error = 0; bvec = 4'bzx10 ; for(var1 = 0; var1 <= 3; var1 = var1 + 1) for(var2 = 0; var2 <= 3; var2 = var2 + 1) for(var3 = 0; var3 <= 3; var3 = var3 + 1) begin cond = bvec[var1]; a = bvec[var2]; b = bvec[var3]; out1 = cond ? a: b ; if(cond) out2 = a ; else out2 = b; if(out1 != out2) begin $display("FAILED - %b %b %b %b %b",cond,a,b,out1,out2); error = 1; end end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/qmark1.v000066400000000000000000000050561435245347300201330ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate the ? operator - use [var] as bit selector also module main; reg globvar; reg [3:0] bvec,var1,var2,var3; reg cond, a,b,out1,out2; reg error; initial begin error = 0; bvec = 4'bzx10 ; for(var1 = 0; var1 <= 3; var1 = var1 + 1) for(var2 = 0; var2 <= 3; var2 = var2 + 1) for(var3 = 0; var3 <= 3; var3 = var3 + 1) begin // Tried both bvec[var1] and bvec[var1:var1] // but believe these HAVE to be a constant expression? if(var1 == 4'h0) cond = bvec[0]; else if(var1 == 4'h1) cond = bvec[1]; else if(var1 == 4'h2) cond = bvec[2]; else cond = bvec[3]; if (var2 == 4'h0) a = bvec[0]; else if (var2 == 4'h1) a = bvec[1]; else if (var2 == 4'h2) a = bvec[2]; else a = bvec[3]; if (var3 == 4'h0) a = bvec[0]; else if (var3 == 4'h1) a = bvec[1]; else if (var3 == 4'h2) a = bvec[2]; else a = bvec[3]; out1 = cond ? a: b ; if(cond) out2 = a ; else out2 = b; if(out1 != out2) begin $display("FAILED - qmark1 - %b %b %b %b %b", cond,a,b,out1,out2); error = 1; end end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/qmark3.v000066400000000000000000000034571435245347300201400ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate the ? operator module main; reg globvar; reg [3:0] bvec; reg [3:0] var1,var2,var3; reg cond, a,b,out1,out2; reg error; initial begin error = 0; bvec = 4'bzx10 ; for(var1 = 0;var1 <= 4'h3; var1 = var1+1) begin for(var2 = 0;var2 <= 4'h3;var2 = var2+1) begin for(var3= 0; var3 <= 4'h3;var3 = var3+1) begin cond = bvec[var1]; a = bvec[var2]; b = bvec[var3]; out1 = cond ? a: b ; if(cond) out2 = a ; else out2 = b; if(out1 != out2) begin $display("FAILED - qmark2 - %b %b %b %b %b", cond,a,b,out1,out2); error = 1; end end end end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/qmark5.v000066400000000000000000000026201435245347300201310ustar00rootroot00000000000000/* * Copyright (c) 1999 Daniel Nelsen (dhn@qedinc.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // SDW - Modified to say FAILED - or PASSED module main; reg [7:0] a ; reg x, y ; reg error; initial begin error = 0; for (a = 0; a < 32; a=a+1 ) begin // ternary operator is right associative x = a[0] ? a[1] : a[2] ? a[3] : a[4] ; y = a[0] ? a[1] : ( a[2] ? a[3] : a[4] ); if ( x != y ) begin $display( "FAILED a=%b, x=%b != y=%b", a[4:0], x, y ); error =1; end end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/qmark6.v000066400000000000000000000027071435245347300201400ustar00rootroot00000000000000/* * Copyright (c) 1999 Daniel Nelsen (dhn@qedinc.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [5:0] a ; reg error; // test ?: in continuous assignment with mix of constant // and non-constant inputs wire [3:0] val1 = a[4] ? a[3:0] : 4'd0 ; wire [3:0] val2 = a[4] ? 4'hf : ~a[3:0] ; initial begin error = 0; for (a = 0; a < 32; a=a+1 ) begin #1 ; // wait for change in a[] to propagate to val if (( a[4] && (( val1 != a[3:0] ) || ( val2 != 15 ))) || ( !a[4] && (( val1 != 0 ) || ( val2 != ~a[3:0] )))) begin $display( "FAILED a=%b, val1=%b, val2=%b", a[4:0], val1, val2 ); error = 1; end end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/queue.v000066400000000000000000000250451435245347300200630ustar00rootroot00000000000000module top; reg pass; integer res, status, job, value; initial begin pass = 1'b1; // Use id = 1, type = 1 (FIFO) and a size of 3. $q_initialize(1, 1, 3, status); if (status !== 0) begin $display("Failed to initialize queue, got %d", status); pass = 1'b0; end // Use id = 2, type = 2 (LIFO) and a size of 2. $q_initialize(2, 2, 2, status); if (status !== 0) begin $display("Failed to initialize queue, got %d", status); pass = 1'b0; end // Use id = 3, type = 0 (undefined) and a size of 10. $q_initialize(3, 0, 10, status); if (status !== 4) begin $display("Failed to find invalid queue type (0), got %d", status); pass = 1'b0; end // Use id = 3, type = 3 (undefined) and a size of 10. $q_initialize(3, 3, 10, status); if (status !== 4) begin $display("Failed to find invalid queue type (3), got %d", status); pass = 1'b0; end // Use id = 3, type = 1 (FIFO) and a size of 0. $q_initialize(3, 1, 0, status); if (status !== 5) begin $display("Failed to find invalid queue size (0), got %d", status); pass = 1'b0; end // Use id = 3, type = 1 (FIFO) and a size of -1. $q_initialize(3, 1, -1, status); if (status !== 5) begin $display("Failed to find invalid queue size (-1), got %d", status); pass = 1'b0; end // This is a duplicate, so will fail. $q_initialize(1, 2, 20, status); if (status !== 6) begin $display("Failed to report duplicate queue, got %d", status); pass = 1'b0; end // Try to add to an invalid queue. $q_add(3, 0, 0, status); if (status !== 2) begin $display("Failed to report invalid queue ($q_add), got %d", status); pass = 1'b0; end // Try to remove from an invalid queue. $q_remove(3, job, value, status); if (status !== 2) begin $display("Failed to report invalid queue ($q_remove), got %d", status); pass = 1'b0; end // Try to check the status of an invalid queue. res = $q_full(3, status); if (status !== 2) begin $display("Failed to report invalid queue ($q_full), got %d", status); pass = 1'b0; end // Try to examine an invalid queue. $q_exam(3, 1, value, status); if (status !== 2) begin $display("Failed to report invalid queue ($q_exam), got %d", status); pass = 1'b0; end /* * Check the LIFO code. */ // Add two element to the queue and check the queue state. $q_add(2, 1, 1, status); if (status !== 0) begin $display("Failed to add element 1 to the LIFO, got %d", status); pass = 1'b0; end res = $q_full(2, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (1), got %d (%d)", status, res); pass = 1'b0; end $q_add(2, 1, 2, status); if (status !== 0) begin $display("Failed to add element 2 to the LIFO, got %d", status); pass = 1'b0; end res = $q_full(2, status); if (status !== 0 || res !== 1) begin $display("Failed LIFO queue should be full, got %d (%d)", status, res); pass = 1'b0; end // Check some of the queue statistics. $q_exam(2, 1, value, status); if (status !== 0 || value !== 2) begin $display("Failed LIFO queue current length (full), got %d (%d)", status, value); pass = 1'b0; end $q_exam(2, 3, value, status); if (status !== 0 || value !== 2) begin $display("Failed LIFO queue maximum length (full), got %d (%d)", status, value); pass = 1'b0; end $q_exam(2, 5, value, status); if (status !== 0 || value !== 0) begin $display("Failed LIFO queue longest wait, got %d (%d)", status, value); pass = 1'b0; end // Adding a third element should return queue full. $q_add(2, 1, 3, status); if (status !== 1) begin $display("Failed to report the LIFO queue is full, got %d", status); pass = 1'b0; end // Now remove the elements from the queue. $q_remove(2, job, value, status); if (status !== 0 || job !== 1 || value !== 2) begin $display("Failed to remove element 2 from the LIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(2, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (2), got %d (%d)", status, res); pass = 1'b0; end $q_remove(2, job, value, status); if (status !== 0 || job !== 1 || value !== 1) begin $display("Failed to remove element 1 from the LIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(2, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (3), got %d (%d)", status, res); pass = 1'b0; end // Check some of the queue statistics. $q_exam(2, 1, value, status); if (status !== 0 || value !== 0) begin $display("Failed LIFO queue current length (empty), got %d (%d)", status, value); pass = 1'b0; end $q_exam(2, 3, value, status); if (status !== 0 || value !== 2) begin $display("Failed LIFO queue maximum length (empty), got %d (%d)", status, value); pass = 1'b0; end $q_exam(2, 4, value, status); if (status !== 0 || value !== 0) begin $display("Failed LIFO queue shortest wait, got %d (%d)", status, value); pass = 1'b0; end // Removing a third element should return queue empty. $q_remove(2, job, value, status); if (status !== 3) begin $display("Failed to report the LIFO queue is empty, got %d", status); pass = 1'b0; end /* * Check the FIFO code. */ // Add three element to the queue and check the queue state. $q_add(1, 2, 1, status); if (status !== 0) begin $display("Failed to add element 1 to the FIFO, got %d", status); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (4), got %d (%d)", status, res); pass = 1'b0; end $q_add(1, 2, 2, status); if (status !== 0) begin $display("Failed to add element 2 to the FIFO, got %d", status); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (5), got %d (%d)", status, res); pass = 1'b0; end $q_add(1, 2, 3, status); if (status !== 0) begin $display("Failed to add element 3 to the FIFO, got %d", status); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 1) begin $display("Failed FIFO queue should be full, got %d (%d)", status, res); pass = 1'b0; end // Check some of the queue statistics. $q_exam(1, 1, value, status); if (status !== 0 || value !== 3) begin $display("Failed FIFO queue current length (full), got %d (%d)", status, value); pass = 1'b0; end $q_exam(1, 3, value, status); if (status !== 0 || value !== 3) begin $display("Failed FIFO queue maximum length (full), got %d (%d)", status, value); pass = 1'b0; end $q_exam(1, 5, value, status); if (status !== 0 || value !== 0) begin $display("Failed FIFO queue longest wait, got %d (%d)", status, value); pass = 1'b0; end // Adding a fourth element should return queue full. $q_add(1, 2, 4, status); if (status !== 1) begin $display("Failed to report the FIFO queue is full, got %d", status); pass = 1'b0; end // Now remove some of the elements from the queue. $q_remove(1, job, value, status); if (status !== 0 || job !== 2 || value !== 1) begin $display("Failed to remove element 1 from the FIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (6), got %d (%d)", status, res); pass = 1'b0; end $q_remove(1, job, value, status); if (status !== 0 || job !== 2 || value !== 2) begin $display("Failed to remove element 2 from the FIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (7), got %d (%d)", status, res); pass = 1'b0; end // Now add an element to wrap around the end. $q_add(1, 2, 4, status); if (status !== 0) begin $display("Failed to add element 4 to the FIFO, got %d", status); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (8), got %d (%d)", status, res); pass = 1'b0; end // Now empty the queue. $q_remove(1, job, value, status); if (status !== 0 || job !== 2 || value !== 3) begin $display("Failed to remove element 3 from the FIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (9), got %d (%d)", status, res); pass = 1'b0; end $q_remove(1, job, value, status); if (status !== 0 || job !== 2 || value !== 4) begin $display("Failed to remove element 2 from the FIFO, got %d (%d,%d)", status, job, value); pass = 1'b0; end res = $q_full(1, status); if (status !== 0 || res !== 0) begin $display("Failed queue should not be full (A), got %d (%d)", status, res); pass = 1'b0; end // Check some of the queue statistics. $q_exam(1, 1, value, status); if (status !== 0 || value !== 0) begin $display("Failed FIFO queue current length (empty), got %d (%d)", status, value); pass = 1'b0; end $q_exam(1, 3, value, status); if (status !== 0 || value !== 3) begin $display("Failed FIFO queue maximum length (empty), got %d (%d)", status, value); pass = 1'b0; end $q_exam(1, 4, value, status); if (status !== 0 || value !== 0) begin $display("Failed FIFO queue shortest wait, got %d (%d)", status, value); pass = 1'b0; end // Removing a fifth element should return queue empty. $q_remove(1, job, value, status); if (status !== 3) begin $display("Failed to report the FIFO queue is empty, got %d", status); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/queue_fail.v000066400000000000000000000031041435245347300210460ustar00rootroot00000000000000module top; integer res, id, job, inform, status, code, value; reg [30:0] short_job, short_inform, short_stat; initial begin id = 1; $q_initialize(); $q_initialize(1); $q_initialize(id); $q_initialize("A name"); $q_initialize(id, 1); $q_initialize(id, 2); $q_initialize(id, "A type"); $q_initialize(id, 1, 20); $q_initialize(id, 1, "A size"); $q_initialize(id, 1, 20, "A status"); $q_initialize(id, 1, 20, short_stat); $q_initialize(id, 1, 20, status, "extra"); $q_add(); $q_add(1); $q_add(id); $q_add("A name"); $q_add(id, 1); $q_add(id, "A job"); $q_add(id, 1, 45); $q_add(id, 1, "An inform"); $q_add(id, 1, 45, short_stat); $q_add(id, 1, 45, status, "extra"); $q_remove(); $q_remove(1); $q_remove(id); $q_remove("A name"); $q_remove(id, job); $q_remove(id, "A job"); $q_remove(id, job, inform); $q_remove(id, job, "An inform"); $q_remove(id, job, inform, short_stat); $q_remove(id, short_job, short_inform, status); $q_remove(id, job, inform, status, "extra"); res = $q_full(1); res = $q_full(id); res = $q_full("A name"); res = $q_full(id, short_stat); res = $q_full(id, status, "extra"); $q_exam(); $q_exam(1); $q_exam(id); $q_exam("A name"); $q_exam(id, 1); $q_exam(id, code); $q_exam(id, "A code"); $q_exam(id, code, value); $q_exam(id, code, short_job); $q_exam(id, code, "A value"); $q_exam(id, code, value, short_stat); $q_exam(id, code, value, status, "extra"); end endmodule iverilog-12_0/ivtest/ivltests/queue_stat.v000066400000000000000000000141731435245347300211160ustar00rootroot00000000000000/* * I expect the following statistics results: * 0 x 0 x x x * 1 x 1 x 0 0 * 2 1 2 x 1 0 * 3 1 3 x 2 1 * 2 1 3 3 2 2 * 2 1 3 3 3 2 * 3 1 3 3 4 2 * 1 1 3 3 1 3 * 0 1 3 2 x 3 * 1 2 3 2 0 2 * 0 2 3 1 x 3 * 1 3 3 1 0 2 * 2 2 3 1 1 2 * 3 2 3 1 2 2 * * x implies there is no defined value for that statistic. */ module top; reg pass; integer res, status, value, value2; integer id, job, item; initial begin pass = 1'b1; id = 1; // Use id = 1, type = 1 (FIFO) and a size of 5. $display("----- INIT -----"); $q_initialize(id, 1, 5, status); if (status !== 0) begin $display("Failed to initialize queue, got %d", status); pass = 1'b0; end print_stats(id); // Add an element to the queue. job = 1; item = 10; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Add a second element to the queue. job = 1; item = 20; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Add a third element to the queue. job = 1; item = 30; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Remove an element from the queue. $display("----- REMOVE -----"); $q_remove(id, value, value2, status); if (status !== 0) begin $display("Failed to remove element from the queue, got %d", status); pass = 1'b0; end print_stats(id); #1 print_stats(id); #1; // Add a fourth element to the queue. job = 1; item = 30; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Remove two elements from the queue. $display("----- REMOVE TWO -----"); $q_remove(id, value, value2, status); if (status !== 0) begin $display("Failed to remove element (1) from the queue, got %d", status); pass = 1'b0; end $q_remove(id, value, value2, status); if (status !== 0) begin $display("Failed to remove element (2) from the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Remove an element from the queue. $display("----- REMOVE -----"); $q_remove(id, value, value2, status); if (status !== 0) begin $display("Failed to remove element from the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Add a fifth element to the queue. job = 1; item = 50; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Remove an element from the queue. $display("----- REMOVE -----"); $q_remove(id, value, value2, status); if (status !== 0) begin $display("Failed to remove element from the queue, got %d", status); pass = 1'b0; end print_stats(id); #7; // Add a sixth element to the queue. job = 1; item = 60; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Add a seventh element to the queue. job = 1; item = 70; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); #1; // Add a eight element to the queue. job = 1; item = 80; $display("----- ADD -----"); $q_add(id, job, item, status); if (status !== 0) begin $display("Failed to add element to the queue, got %d", status); pass = 1'b0; end print_stats(id); if (pass) $display("PASSED"); end task print_stats; input id; integer id; integer len, inter, max, short, long, avg, status; // Icarus uses a status code of 10 to indicate no statistics available. begin len = 32'bx; inter = 32'bx; max = 32'bx; short = 32'bx; long = 32'bx; avg = 32'bx; $display("Queue statistics at time %0d", $time); // Get the queue length. $q_exam(id, 1, len, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the length, status %0d", status); pass = 1'b0; end // Get the mean inter-arrival time. $q_exam(id, 2, inter, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the inter-arrival, status %0d", status); pass = 1'b0; end // Get the maximum length. $q_exam(id, 3, max, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the maximum length, status %0d", status); pass = 1'b0; end // Get the shortest wait time. $q_exam(id, 4, short, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the shortest wait time, status %0d", status); pass = 1'b0; end // Get the longest wait time. $q_exam(id, 5, long, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the longest wait time, status %0d", status); pass = 1'b0; end // Get the average wait time. $q_exam(id, 6, avg, status); if ((status !== 0) && (status !== 10)) begin $display(" Failed to get the average wait time, status %0d", status); pass = 1'b0; end $display(" %0d, %0d, %0d, %0d, %0d, %0d", len, inter, max, short, long, avg); end endtask endmodule iverilog-12_0/ivtest/ivltests/race.v000066400000000000000000000041011435245347300176370ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This sample demonstrates the post 20030904 Icarus Verilog feature * where combinational blocks with time-0 races against the rest of * the design can be resolved. * * The always @(foo) threads should be detected by the compiler as * combinational, and should be pushed to the front of the time-0 * scheduling queue. This causes the threads to enter the wait early * so that it can detect the change from x to 1 for its value. * * The program HAS a time-0 race according to the IEEE1364 standard, * but Icarus Verilog as an extension resolves this race intentionally * as described. */ module main; reg foo, bar; reg foo_ok = 0, bar_ok = 0; initial foo = 1; always @(foo) begin if (foo !== 1'b1) begin $display("FAILED --(foo = %b)", foo); $finish; end foo_ok = 1; end always @(bar) begin if (bar !== 1'b1) begin $display("FAILED --(bar = %b)", bar); $finish; end bar_ok = 1; end initial bar = 1; initial begin #1 if (foo_ok !== 1) begin $display("FAILED -- foo lost the race"); $finish; end if (bar_ok !== 1) begin $display("FAILED -- bar lost the race"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/ram16x1.v000066400000000000000000000031561435245347300201350ustar00rootroot00000000000000/* * Copyright (c) 1999 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // This example describes a 16x1 RAM that can be synthesized into // a CLB ram in a Xilinx FPGA. module ram16x1 (q, d, a, we, wclk); output q; input d; input [3:0] a; input we; input wclk; reg mem[15:0]; assign q = mem[a]; always @(posedge wclk) if (we) mem[a] = d; endmodule /* ram16x1 */ module main; wire q; reg d; reg [3:0] a; reg we, wclk; ram16x1 r1 (q, d, a, we, wclk); initial begin wclk = 0; we = 1; for (a = 0 ; a < 4'hf ; a = a + 1) begin d = a[0]; #1 wclk = 1; #1 wclk = 0; $display("r1[%h] == %b", a, q); end for (a = 0 ; a < 4'hf ; a = a + 1) #1 if (q !== a[0]) begin $display("FAILED -- mem[%h] !== %b", a, a[0]); $finish; end $display("PASSED"); end endmodule /* main */ iverilog-12_0/ivtest/ivltests/random.v000066400000000000000000000001751435245347300202140ustar00rootroot00000000000000module test; integer i; initial begin for (i = 0; i < 1000; i++) begin $display("%h", $random); end end endmodule iverilog-12_0/ivtest/ivltests/range1.v000066400000000000000000000030601435245347300201050ustar00rootroot00000000000000/* * Copyright (c) 2000 Nadim Shaikli * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /*************************************************** * * Problem: Core dump on 'out of range' error * search for 'thing[9]' * ***************************************************/ module main; reg clk; reg [3:0] sig; reg [7:0] thing; // generate a clock always #10 clk = ~clk; initial begin $display ("\n<< BEGIN >>"); case ( sig[3:0] ) 4'b0000: thing[0] = 1'b1; 4'b0010: thing[2] = 1'b1; 4'b0011: thing[9] = 1'b1; endcase // case( sig[3:0] ) $display ("<< END >>\n"); $finish; end // Waves definition // initial // begin // $dumpfile("out.dump"); // $dumpvars(0, main); // end endmodule // main iverilog-12_0/ivtest/ivltests/range2.v000066400000000000000000000003711435245347300201100ustar00rootroot00000000000000/* * This is frpm PR#138. It is supposed to generate an error. */ module bug; wire[1:0] dout; wire[1:0] din; assign dout = din[3:2]; /* foo.vl:9: bit/part select [3:2] out of range for bug.din */ endmodule iverilog-12_0/ivtest/ivltests/range3.v000066400000000000000000000020101435245347300201010ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Detect that b is declared as a scaler and a vector. */ module simple (a, b); input [7:0] a; output [7:0] b; reg b; // Error here! always @(a) begin b = a; end endmodule iverilog-12_0/ivtest/ivltests/readmem-error.txt000066400000000000000000000000111435245347300220340ustar00rootroot00000000000000uuuuuuuu iverilog-12_0/ivtest/ivltests/readmem-error.v000066400000000000000000000161061435245347300214760ustar00rootroot00000000000000module top; reg [24*8-1:0] str; real rval; reg [7:0] array [0:7]; reg [7:0] array2 [8:15]; reg [7:0] array3 [-1:7]; integer idx, istr; task clear_array; for (idx = 0; idx < 8; idx = idx + 1) begin array[idx] = 0; array2[idx+8] = 0; end endtask initial begin // An invalid string. $readmemb(str, array); $readmemb(istr, array); // Check a valid string. str = "ivltests/readmemb.txt"; $readmemb(str, array); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemb 1, expected %0d, got %0d", idx, idx+1, array[idx]); end end // Check a string with a non-printing character. str[7:0] = 'd2; $readmemb(str, array); // This should load, but will print a warning about the real. rval = 0.0; clear_array; $readmemb("ivltests/readmemb.txt", array, rval); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemb 2, expected %0d, got %0d", idx, idx+1, array[idx]); end end // This should load, but will print a warning about the real. rval = 7.0; clear_array; $readmemb("ivltests/readmemb.txt", array, 0, rval); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemb 3, expected %0d, got %0d", idx, idx+1, array[idx]); end end // These should not load the array. clear_array; $readmemb("ivltests/readmemb.txt", array, -1, 7); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== 0) begin $display("Failed: for index %0d of readmemb 4, expected 0, got %0d", idx, array[idx]); end end $readmemb("ivltests/readmemb.txt", array2, 7, 15); for (idx = 8; idx < 16; idx = idx + 1) begin if (array2[idx] !== 0) begin $display("Failed: for index %0d of readmemb 5, expected 0, got %0d", idx, array2[idx]); end end $readmemb("ivltests/readmemb.txt", array, 0, 8); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== 0) begin $display("Failed: for index %0d of readmemb 6, expected 0, got %0d", idx, array[idx]); end end $readmemb("ivltests/readmemb.txt", array2, 8, 16); for (idx = 8; idx < 16; idx = idx + 1) begin if (array2[idx] !== 0) begin $display("Failed: for index %0d of readmemb 7, expected 0, got %0d", idx, array2[idx]); end end // Check that a warning is printed if we have the wrong number of values. clear_array; $readmemb("ivltests/readmemb.txt", array, 0, 6); for (idx = 0; idx < 7; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemb 8, expected %0d, got %0d", idx, idx+1, array[idx]); end end if (array[7] !== 0) begin $display("Failed: for index 7 of readmemb 8, expected 0, got %0d", array[7]); end $readmemb("ivltests/readmemb.txt", array3, -1, 7); for (idx = -1; idx < 7; idx = idx + 1) begin if ($signed(array3[idx]) !== idx + 2) begin $display("Failed: for index %0d of readmemb 9, expected %0d, got %0d", idx, idx+2, array3[idx]); end end if (array3[7] !== 8'bx) begin $display("Failed: for index 7 of readmemb 9, expected 'dx, got %0d", array3[7]); end // Check what an invalid token returns. $readmemb("ivltests/readmem-error.txt", array); // An invalid string. str = 'bx; $readmemh(str, array); $readmemh(istr, array); // Check a valid string. str = "ivltests/readmemh.txt"; $readmemh(str, array); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemh 1, expected %0d, got %0d", idx, idx+1, array[idx]); end end // Check a string with a non-printing character. str[7:0] = 'd2; $readmemh(str, array); // This should load, but will print a warning about the real. rval = 0.0; clear_array; $readmemh("ivltests/readmemh.txt", array, rval); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemh 2, expected %0d, got %0d", idx, idx+1, array[idx]); end end // This should load, but will print a warning about the real. rval = 7.0; clear_array; $readmemh("ivltests/readmemh.txt", array, 0, rval); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemh 3, expected %0d, got %0d", idx, idx+1, array[idx]); end end // These should not load the array. clear_array; $readmemh("ivltests/readmemh.txt", array, -1, 7); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== 0) begin $display("Failed: for index %0d of readmemh 4, expected 0, got %0d", idx, array[idx]); end end $readmemh("ivltests/readmemh.txt", array2, 7, 15); for (idx = 8; idx < 16; idx = idx + 1) begin if (array2[idx] !== 0) begin $display("Failed: for index %0d of readmemh 5, expected 0, got %0d", idx, array2[idx]); end end $readmemh("ivltests/readmemh.txt", array, 0, 8); for (idx = 0; idx < 8; idx = idx + 1) begin if (array[idx] !== 0) begin $display("Failed: for index %0d of readmemh 6, expected 0, got %0d", idx, array[idx]); end end $readmemh("ivltests/readmemh.txt", array2, 8, 16); for (idx = 8; idx < 16; idx = idx + 1) begin if (array2[idx] !== 0) begin $display("Failed: for index %0d of readmemh 7, expected 0, got %0d", idx, array2[idx]); end end // Check that a warning is printed if we have the wrong number of values. clear_array; $readmemh("ivltests/readmemh.txt", array, 0, 6); for (idx = 0; idx < 7; idx = idx + 1) begin if (array[idx] !== idx + 1) begin $display("Failed: for index %0d of readmemh 8, expected %0d, got %0d", idx, idx+1, array[idx]); end end if (array[7] !== 0) begin $display("Failed: for index 7 of readmemh 8, expected 0, got %0d", array[7]); end $readmemh("ivltests/readmemh.txt", array3, -1, 7); for (idx = -1; idx < 7; idx = idx + 1) begin if ($signed(array3[idx]) !== idx + 2) begin $display("Failed: for index %0d of readmemh 9, expected %0d, got %0d", idx, idx+2, array3[idx]); end end if (array3[7] !== 8'bx) begin $display("Failed: for index 7 of readmemh 9, expected 'dx, got %0d", array3[7]); end // Check what an invalid token returns. $readmemh("ivltests/readmem-error.txt", array); end endmodule iverilog-12_0/ivtest/ivltests/readmem-invalid.v000066400000000000000000000012051435245347300217650ustar00rootroot00000000000000module top; reg [7:0] array [7:0]; initial begin $readmemb(); $readmemb(top); $readmemb("ivltests/readmemb.txt"); $readmemb("ivltests/readmemb.txt", top); $readmemb("ivltests/readmemb.txt", array, top); $readmemb("ivltests/readmemb.txt", array, 0, top); $readmemb("ivltests/readmemb.txt", array, 0, 7, top); $readmemh(); $readmemh(top); $readmemh("ivltests/readmemh.txt"); $readmemh("ivltests/readmemh.txt", top); $readmemh("ivltests/readmemh.txt", array, top); $readmemh("ivltests/readmemh.txt", array, 0, top); $readmemh("ivltests/readmemh.txt", array, 0, 7, top); end endmodule iverilog-12_0/ivtest/ivltests/readmemb.txt000066400000000000000000000001101435245347300210470ustar00rootroot0000000000000000000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000 iverilog-12_0/ivtest/ivltests/readmemb1.dat000066400000000000000000000001211435245347300210630ustar00rootroot000000000000000000_0000 00000001 000__0_0010 0000_0011 0000_0100 0000_0101 0000_0110 0000_0111 iverilog-12_0/ivtest/ivltests/readmemb1.v000066400000000000000000000026031435245347300205670ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Initial readmemb function - length of data = array size. // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; $readmemb("ivltests/readmemb1.dat",array); for(count = 0; count <= 7; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemb2.dat000066400000000000000000000000511435245347300210660ustar00rootroot000000000000000000_0000 00000001 000__0_0010 0000_0011 iverilog-12_0/ivtest/ivltests/readmemb2.v000066400000000000000000000032301435245347300205650ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemb function - data file length less than array // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; /* pre init the array to all zeroes. */ for(count = 0; count <= 7; count = count + 1) array[count] = 8'h0; $readmemb("ivltests/readmemb2.dat",array); for(count = 0; count <= 3; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(array[4] !== 8'h0) begin error = 1; $display("FAILED - array[4] == %h, s/b 0", array[count]); end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemb3.v000066400000000000000000000032271435245347300205740ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemb function - Only read part of data file // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; /* pre init the array to all zeroes. */ for(count = 0; count <= 7; count = count + 1) array[count] = 8'h0; $readmemb("ivltests/readmemb1.dat",array,0,3); for(count = 0; count <= 3; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(array[4] !== 8'h0) begin error = 1; $display("FAILED - array[4] == %h, s/b 0", array[count]); end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh.txt000066400000000000000000000000201435245347300210550ustar00rootroot000000000000001 2 3 4 5 6 7 8 iverilog-12_0/ivtest/ivltests/readmemh1.dat000066400000000000000000000000201435245347300210670ustar00rootroot000000000000000 1 2 3 4 5 6 7 iverilog-12_0/ivtest/ivltests/readmemh1.v000066400000000000000000000026031435245347300205750ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Initial readmemh function - length of data = array size. // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; $readmemh("ivltests/readmemh1.dat",array); for(count = 0; count <= 7; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh1a.dat000066400000000000000000000000311435245347300212320ustar00rootroot00000000000000@2 2 3 @0 0 1 @4 4 5 6 7 iverilog-12_0/ivtest/ivltests/readmemh1a.v000066400000000000000000000026041435245347300207370ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Initial readmemh function - length of data = array size. // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; $readmemh("ivltests/readmemh1a.dat",array); for(count = 0; count <= 7; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh2.dat000066400000000000000000000000101435245347300210670ustar00rootroot000000000000000 1 2 3 iverilog-12_0/ivtest/ivltests/readmemh2.v000066400000000000000000000032301435245347300205730ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemh function - data file length less than array // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; /* pre init the array to all zeroes. */ for(count = 0; count <= 7; count = count + 1) array[count] = 8'h0; $readmemh("ivltests/readmemh2.dat",array); for(count = 0; count <= 3; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(array[4] !== 8'h0) begin error = 1; $display("FAILED - array[4] == %h, s/b 0", array[count]); end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh3.v000066400000000000000000000032371435245347300206030ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemh function - Read less data than length of array // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; /* pre init the array to all zeroes. */ for(count = 0; count <= 7; count = count + 1) array[count] = 8'h0; $readmemh("ivltests/readmemh1.dat",array,0,3); for(count = 0; count <= 3; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(array[4] !== 8'h0) begin error = 1; $display("FAILED - array[4] == %h, s/b 0", array[count]); end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh4.dat000066400000000000000000000001121435245347300210740ustar00rootroot000000000000000 1 // Comments in the file 2 3 4 5 // And can have comments here too 6 7 iverilog-12_0/ivtest/ivltests/readmemh4.v000066400000000000000000000025641435245347300206060ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemh function - comments in data file // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; $readmemh("ivltests/readmemh4.dat",array); for(count = 0; count <= 7; count = count + 1) begin if(array[count[2:0]] !== count) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count],count); end end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/readmemh5.v000066400000000000000000000021651435245347300206040ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: readmemh function - Check that MEMNAME [ 0:x] caught as compile error // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin error = 0; /* pre init the array to all zeroes. */ $readmemh("ivltests/readmemh1.dat",array [0:7]); end endmodule iverilog-12_0/ivtest/ivltests/real.v000066400000000000000000000024321435245347300176550ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program checks that some basics of real value support work. */ module main; realtime x; real a3, a4; initial begin a3 = 0.3; a4 = 0.4; x = 2 * a4 + a3; $display("a3 = %f, a4 = %f, x = %f", a3, a4, x); if (x > 1.1001) begin $display("FAILED"); $finish; end if (x < 1.0999) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/real10.v000066400000000000000000000003471435245347300200210ustar00rootroot00000000000000module main; reg [3:0] tmp; initial begin tmp = 10.7; if (tmp !== 4'd11) begin $display("FAILED -- Incorrect rounding: tmp=%b", tmp); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/real11.v000066400000000000000000000011661435245347300200220ustar00rootroot00000000000000/* * This tests the case that a delay value is a calculated real value. */ module main; real test; wire [3:0] Q; reg [3:0] D; assign #(test/2.0) Q = D; initial begin test = 4.0; D = 1; #(test) if (Q !== 1) begin $display("FAILED -- %0t: Q=%d, D=%d", $time, Q, D); $finish; end D = 2; #(test/4) if (Q !== 1) begin $display("FAILED -- %0t: Q=%d, D=%d", $time, Q, D); $finish; end #(test/2) if (Q !== 2) begin $display("FAILED -- %0t: Q=%d, D=%d", $time, Q, D); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/real2.v000066400000000000000000000021551435245347300177410ustar00rootroot00000000000000// // Copyright (c) 2003 Steve Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; parameter offset = 7.0; time result; initial begin #9 result = $time + offset; $display("result = %d", result); if (result !== 64'd16) begin $display("FAILED -- incorrect result"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/real3.v000066400000000000000000000046061435245347300177450ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff @ chiaro.com) * * This source code is free software; rou 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 rour option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: real3.v,v 1.1 2003/03/07 05:29:41 stevewilliams Exp $ */ /* * Verifies some real values to make sure the real->double conversion * is properly handled and the values make it into vvp properly. * * http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html * */ module main; real r; reg errors; initial begin errors = 0; r = 1.0; if ($realtobits(r) != 64'h3FF0000000000000) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 1.1; if ($realtobits(r) != 64'h3FF199999999999a) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 3.3; if ($realtobits(r) != 64'h400A666666666666) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 5.5; if ($realtobits(r) != 64'h4016000000000000) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 1.0000000000_0000000001; if ($realtobits(r) != 64'h3FF0000000000000) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 3.1415926535_8979323846; if ($realtobits(r) != 64'h400921FB54442D18) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end r = 1234567890_1234567890.1; if ($realtobits(r) != 64'h43E56A95319D63E1) begin $display("%f != 'h%h", r, $realtobits(r)); $display("FAIL"); errors = 1; end if (errors === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real4.v000066400000000000000000000043041435245347300177410ustar00rootroot00000000000000// Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // Test basic functionality of convertion system VPI functions. // module test; integer err, i; real r; reg [63:0] b; parameter PI = 3.1415926535_8979323846_2643383279; initial begin err = 0; // // $rtoi() // i = $rtoi(0.1); if (i != 0) begin err = 1; $display("$rtoi(0.1): %0d != 0", i); end i = $rtoi(9.6); if (i != 9) begin err = 1; $display("$rtoi(9.6): %0d != 9", i); end // // $realtobits() // b = $realtobits(PI); if (b != 64'h400921FB54442D18) begin err = 1; $display("$realtobits(PI): 'h%x != 'h400921FB54442D18", b); end b = $realtobits(1.1); if (b != 64'h3ff199999999999a) begin err = 1; $display("$realtobits(1.1): 'h%x != 'h400921FB54442D18", b); end // // $bitstoreal() // r = $bitstoreal(64'h400921FB54442D18); if (r != PI) begin err = 1; $display("$realtobits(PI): %20.17f != %20.17f", r, PI); end r = $bitstoreal(64'h3FF4CCCCCCCCCCCD); if (r != 1.3) begin err = 1; $display("$realtobits(1.3): %20.17f != 1.3", r); end // // $itor() // r = $itor(1); if (r != 1.0) begin err = 1; $display("$itor(1): %20.1f != 1.0", r); end r = $itor(123456789); if (r != 123456789.0) begin err = 1; $display("$itor(123456789): %20.1f != 123456789.0", r); end if (err) $display("FAILED"); else $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/real5.v000066400000000000000000000003401435245347300177360ustar00rootroot00000000000000module main; parameter MAXPERFOOCLK = 40000; time fooclk_period; initial #50 $display("max foo period( posedge FOOCLK:%0.3f", $time/1000.0, "ns, %0d", MAXPERFOOCLK, " : %0.3f", fooclk_period/1000.0, "ns );"); endmodule iverilog-12_0/ivtest/ivltests/real6.v000066400000000000000000000006101435245347300177370ustar00rootroot00000000000000module main; real rfoo; reg [5:0] x, y; initial begin rfoo = 1.0; x = 5; y = 2; rfoo = rfoo + x%y; x = rfoo; $display("rfoo = %f, x=%d", rfoo, x); if (x !== 5'd2) begin $display("FAILED"); $finish; end if (rfoo != 2.0) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/real7.v000066400000000000000000000003541435245347300177450ustar00rootroot00000000000000// Verify that icarus can handle real compare versus int constant module test (); real myv; parameter myp = 1.0; initial begin myv = 1.0; if(myv <= 1) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/real8.v000066400000000000000000000062761435245347300177570ustar00rootroot00000000000000/* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* $Id: real8.v,v 1.1 2005/07/07 16:26:05 stevewilliams Exp $ */ /* * This test demonstrates (and checks) the handling of real values and * expressions in some ways that baseline IEEE1364-2001. Particularly, * reg and wire values with types, and nets able to carry real values * through delays. */ module main; // This is *not* valid baseline Verilog, but iverilog extensions // support this. These statements declare a real valued variable // and a real valued net. reg real target; wire real feedback; // The feedback should take the target value 10 time units // after any change in the target value. assign #(10) feedback = target; // The control value is calculated from the current target // and feedback values. This is recalculated whenever either // of the inputs change. wire real control = (feedback - target)/2.0; initial begin target = 16.0; // The target should, after this assignment, have a well // defined value 16, but the feedback should remain at NaN // for a while. #1 $display($time,,"target=%f, feedback=%f, control=%f", target, feedback, control); if (target != 16.0) begin $display("FAILED -- target value is not correct."); $finish; end // feedback is still undefined. // By now, the feedback as taken on a value, and the control // should have been calcluated. #10 $display($time,,"target=%f, feedback=%f, control=%f", target, feedback, control); if (feedback != 16.0) begin $display("FAILED -- feedback has wrong value."); $finish; end if (control != 0.0) begin $display("FAILED -- control has wrong value."); $finish; end target = 8.0; #9 $display($time,,"target=%f, feedback=%f, control=%f", target, feedback, control); if (feedback != 16.0) begin $display("FAILED -- feedback has wrong value."); $finish; end if (control != 4.0) begin $display("FAILED -- control has wrong value."); $finish; end #2 $display($time,,"target=%f, feedback=%f, control=%f", target, feedback, control); if (feedback != 8.0) begin $display("FAILED -- feedback has wrong value."); $finish; end if (control != 0.0) begin $display("FAILED -- control has wrong value."); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/real9.v000066400000000000000000000042041435245347300177450ustar00rootroot00000000000000/* real9.v * This tests comparison of a real variable with integer constants. */ module main; real value; parameter param = 2; initial begin value = 3.0; if (value < param) begin $display("FAILED -- %f < %d", value, param); $finish; end if (value < 2) begin $display("FAILED -- %f < 2", value); $finish; end if (value <= param) begin $display("FAILED -- %f <= %d", value, param); $finish; end if (value <= 2) begin $display("FAILED -- %f <= 2", value); $finish; end if (value == param) begin $display("FAILED -- %f == %d", value, param); $finish; end if (value == 2) begin $display("FAILED -- %f == 2", value); $finish; end if (param >= value) begin $display("FAILED -- %d >= %f", param, value); $finish; end if (2 >= value) begin $display("FAILED -- 2 >= %f", value); $finish; end value = 2.0; if (value < param) begin $display("FAILED -- %f < %d", value, param); $finish; end if (value < 2) begin $display("FAILED -- %f < 2", value); $finish; end if (value != param) begin $display("FAILED -- %f != %d", value, param); $finish; end if (value != 2) begin $display("FAILED -- %f != 2", value); $finish; end if (value > param) begin $display("FAILED -- %f > %d", value, param); $finish; end if (value > 2) begin $display("FAILED -- %f > 2", value); $finish; end value = 1.6; if (value == param) begin $display("FAILED -- %f == %d", value, param); $finish; end if (value == 2) begin $display("FAILED -- %f == 2", value); $finish; end if (value >= param) begin $display("FAILED -- %f >= %d", value, param); $finish; end if (value >= 2) begin $display("FAILED -- %f >= 2", value); $finish; end if (value > param) begin $display("FAILED -- %f > %d", value, param); $finish; end if (value > 2) begin $display("FAILED -- %f > 2", value); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/real_array.v000066400000000000000000000023121435245347300210500ustar00rootroot00000000000000module top; reg pass; real rarr [1:0]; real rat; integer i; wire real rmon = rarr[0]; wire real rmonv = rarr[i]; always @(rarr[0]) begin rat = rarr[0]; end initial begin pass = 1'b1; i = 0; rarr[0] = 1.125; #1; if (rmon != 1.125) begin $display("Failed CA at 0, expected 1.125, got %6.3f", rmon); pass = 1'b0; end if (rmonv != 1.125) begin $display("Failed CA (var) at 0, expected 1.125, got %6.3f", rmonv); pass = 1'b0; end if (rat != 1.125) begin $display("Failed @ at 0, expected 1.125, got %6.3f", rat); pass = 1'b0; end rarr[0] = 2.25; #1; if (rmon != 2.25) begin $display("Failed CA at 1, expected 2.250, got %6.3f", rmon); pass = 1'b0; end if (rmonv != 2.25) begin $display("Failed CA (var) at 1, expected 2.250, got %6.3f", rmonv); pass = 1'b0; end if (rat != 2.25) begin $display("Failed @ at 1, expected 2.250, got %6.3f", rat); pass = 1'b0; end i = 1; #1 if (rmonv != 0.0) begin $display("Failed CA (var) at 2, expected 0.000, got %6.3f", rmonv); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_array_multi_dim.v000066400000000000000000000012641435245347300231200ustar00rootroot00000000000000// Check that multi-dimensional real arrays are supported module test; reg failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("FAILED: `%s`, expected %f, got %f", `"expr`", val, expr); \ failed = 1'b1; \ end real r[3:0][1:0]; integer i; initial begin for (i = 0; i < 8; i = i + 1) begin r[i/2][i%2] = i / 8.0 - 0.5; end `check(r[0][0], -0.5); `check(r[0][1], -0.375); `check(r[1][0], -0.25); `check(r[1][1], -0.125); `check(r[2][0], 0.0); `check(r[2][1], 0.125); `check(r[3][0], 0.25); `check(r[3][1], 0.375); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/real_array_nb.v000066400000000000000000000053351435245347300215370ustar00rootroot00000000000000`timescale 1ns/100ps module top; reg pass; real rarr[0:3]; realtime del; reg signed [1:0] idx; integer count; event evt; initial begin pass = 1'b1; // Check the initial values. if (rarr[1] != 0.0) begin $display("FAILED initial value, expected 0.0, got %f", rarr[1]); pass = 1'b0; end // Check a negative index value. rarr[3] = 3.0; idx = -1; rarr[idx] <= 0.0; #0.1; if (rarr[3] != 3.0) begin $display("FAILED negative index 1, expected 3.0, got %f", rarr[3]); pass = 1'b0; end del = 1.0; rarr[idx] <= #(del) 0.0; #1.1; if (rarr[3] != 3.0) begin $display("FAILED negative index 2, expected 3.0, got %f", rarr[3]); pass = 1'b0; end count = 0; rarr[idx] <= repeat(count) @(evt) 0.0; #0.1; if (rarr[3] != 3.0) begin $display("FAILED negative index 3, expected 3.0, got %f", rarr[3]); pass = 1'b0; end // Check a non-blocking assignment. rarr[1] <= 2.0; if (rarr[1] != 0.0) begin $display("FAILED non-blocking assign 1, expected 0.0, got %f", rarr[1]); pass = 1'b0; end #0.1; if (rarr[1] != 2.0) begin $display("FAILED non-blocking assign 2, expected 2.0, got %f", rarr[1]); pass = 1'b0; end // Check a delayed non-blocking assignment. rarr[1] <= #2 3.0; #1.9; if (rarr[1] != 2.0) begin $display("FAILED delayed NB assign 1, expected 2.0, got %f", rarr[1]); pass = 1'b0; end #0.2; if (rarr[1] != 3.0) begin $display("FAILED delayed NB assign 2, expected 3.0, got %f", rarr[1]); pass = 1'b0; end // Check a variable delay non-blocking assignment. del = 3.0; rarr[1] <= #(del) 4.0; #2.9; if (rarr[1] != 3.0) begin $display("FAILED var. delay NB assign 1, expected 3.0, got %f", rarr[1]); pass = 1'b0; end #0.2; if (rarr[1] != 4.0) begin $display("FAILED var. delay NB assign 2, expected 4.0, got %f", rarr[1]); pass = 1'b0; end // Check a zero count event non-blocking assignment. rarr[1] <= repeat(count) @(evt) 5.0; #0.1; if (rarr[1] != 5.0) begin $display("FAILED NB EC count=0, expected 5.0, got %f", rarr[1]); pass = 1'b0; end // Check for an event non-blocking assignment. rarr[1] <= @(evt) 6.0; fork #1 ->evt; begin #0.9; if (rarr[1] != 5.0) begin $display("FAILED NB EC initial, expected 5.0, got %f", rarr[1]); pass = 1'b0; end #0.2; if (rarr[1] != 6.0) begin $display("FAILED NB EC final, expected 6.0, got %f", rarr[1]); pass = 1'b0; end end join if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_array_store_after_cmp.v000066400000000000000000000010141435245347300243020ustar00rootroot00000000000000// Check that a store to am entry of real typed array with an immediate index // works if it happes after a comparison that sets vvp flag 4 to 0. module test; integer a = 0; real r[1:0]; initial begin if (a == 0) begin // Make sure that this store happens, even though the compare above // cleared set vvp flag 4 r[0] = 1.23; end if (r[0] == 1.23) begin $display("PASSED"); end else begin $display("FAILED. Expected %f, got %f", 1.23, r[0]); end end endmodule iverilog-12_0/ivtest/ivltests/real_assign_deassign.v000066400000000000000000000021211435245347300230710ustar00rootroot00000000000000module test (); reg pass = 1'b1; reg d; real f = 0.0; always @(d) assign f = 0; initial begin // Verify the initial value. #1; if (f != 0.0) begin $display("Failed initial value, expected 0.0, got %f", f); pass = 1'b0; end // Verify the value can change. #1 f = 1.0; if (f != 1.0) begin $display("Failed value change, expected 1.0, got %f", f); pass = 1'b0; end // Verify that the assign changed the value and that a normal assign // is blocked. #1 d = 0; #1 f = 1.0; if (f != 0.0) begin $display("Failed assign holding, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the release holds the previous value. #1 deassign f; if (f != 0.0) begin $display("Failed release holding, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the value can be changed after a release. #1 f = 1.0; if (f != 1.0) begin $display("Failed release, expected 1.0, got %f", f); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_concat_invalid1.v000066400000000000000000000005541435245347300227760ustar00rootroot00000000000000module top; real rvar1, rvar2, rtmp; wire real wrcon3, wrcon4, wrcon5, wrcon6; wire real wrcon1 = {2.0, 1.0}; wire real wrcon2 = {rvar1, rvar2}; assign wrcon3 = {2.0, 1.0}; assign wrcon4 = {rvar1, rvar2}; assign {wrcon5, wrcon6} = 1.0; initial begin rtmp = {2.0, 1.0}; rtmp = {rvar1, rvar2}; {rvar1, rvar2} = rtmp; end endmodule iverilog-12_0/ivtest/ivltests/real_concat_invalid2.v000066400000000000000000000002371435245347300227750ustar00rootroot00000000000000module top; parameter real rpar1 = 1.0; parameter real rpar2 = 2.0; parameter real rparb = {rpar1, rpar2}; parameter real rpar = {2.0, 1.0}; endmodule iverilog-12_0/ivtest/ivltests/real_delay.sdf000066400000000000000000000003031435245347300213350ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (TIMESCALE 1ns) (CELL (CELLTYPE "gate_sdf") (INSTANCE dut_f) (DELAY (ABSOLUTE (IOPATH in out (1.134) (0.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/real_delay.v000066400000000000000000000127221435245347300210360ustar00rootroot00000000000000`timescale 1ns/1ps primitive not_u (out, in); output out; input in; table 0 : 1; 1 : 0; endtable endprimitive // Any instance of this gate will use the small time scale that was // in place when it was defined. module gate_sdf(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (0.5, 0.5); endspecify endmodule /* * Icarus does not currently support UDPs with a variable delay. * It also needs to support NULL decay delays, buf/not/etc. should * only allow two delays maximum. */ module top; initial begin $monitor("%.3f", $realtime,, sml_const.test, sml_var.test, sml_const.out_g, sml_const.out_u, sml_const.out_m, sml_const.out_s, sml_var.out_g, sml_var.out_u,, sml_const.out_f, med_const.out_f, lrg_const.out_f,, med_const.test, med_var.test, med_const.out_g, med_const.out_u, med_const.out_m, med_const.out_s, med_var.out_g, med_var.out_u,, lrg_const.test, lrg_var.test, lrg_const.out_g, lrg_const.out_u, lrg_const.out_m, lrg_const.out_s, lrg_var.out_g, lrg_var.out_u); #1.3 $finish(0); end endmodule /* * These should have a positive edge at 1234 time ticks. */ // Check that constant delays are scaled correctly. module sml_const; reg test, in; wire out_g, out_u, out_m, out_s, out_f; not #(1.134, 0) dut_g (out_g, in); not_u #(1.134, 0) dut_u (out_u, in); sml_inv dut_m (out_m, in); gate_sdf dut_f (out_f, in); sml_sdf dut_s (out_s, in); initial begin $sdf_annotate("ivltests/real_delay.sdf"); $sdf_annotate("ivltests/real_delay_sml.sdf"); in = 1'b1; in <= #0.1 1'b0; test = 1'b0; #1.234 test = 1'b1; end endmodule // Check that the specify delays are scaled correctly. module sml_inv(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (1.134, 0); endspecify endmodule // Check that the SDF delays scale correctly. module sml_sdf(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (0.5, 0.5); endspecify endmodule // Check that variable delays are scaled correctly. module sml_var; reg test, in; real dly, dly2, dly3; wire out_g, out_u; not #(dly2, dly3) dut_g (out_g, in); not_u #(dly2, dly3) dut_u (out_u, in); initial begin in = 1'b1; in <= #0.1 1'b0; dly = 1.234; dly2 = 1.134; dly3 = 0.0; test = 1'b0; #(dly) test = 1'b1; end endmodule `timescale 1ns/10ps /* * These should have a positive edge at 1230 time ticks. */ // Check that constant delays are scaled correctly. module med_const; reg test, in; wire out_g, out_u, out_m, out_s, out_f; not #(1.134, 0) dut_g (out_g, in); not_u #(1.134, 0) dut_u (out_u, in); med_inv dut_m (out_m, in); gate_sdf dut_f (out_f, in); med_sdf dut_s (out_s, in); initial begin $sdf_annotate("ivltests/real_delay.sdf"); $sdf_annotate("ivltests/real_delay_med.sdf"); in = 1'b1; in <= #0.1 1'b0; test = 1'b0; #1.234 test = 1'b1; end endmodule // Check that the specify delays are scaled correctly. module med_inv(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (1.134, 0); endspecify endmodule // Check that the SDF delays scale correctly. module med_sdf(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (0.5, 0.5); endspecify endmodule // Check that variable delays are scaled correctly. module med_var; reg test, in; real dly, dly2, dly3; wire out_g, out_u; not #(dly2, dly3) dut_g (out_g, in); not_u #(dly2, dly3) dut_u (out_u, in); initial begin in = 1'b1; in <= #0.1 1'b0; dly = 1.234; dly2 = 1.134; dly3 = 0.0; test = 1'b0; #(dly) test = 1'b1; end endmodule `timescale 1ns/100ps /* * These should have a positive edge at 1200 time ticks. */ // Check that constant delays are scaled correctly. module lrg_const; reg test, in; wire out_g, out_u, out_m, out_s, out_f; not #(1.134, 0) gate (out_g, in); not_u #(1.134, 0) dut_u (out_u, in); lrg_inv dut_m (out_m, in); gate_sdf dut_f (out_f, in); lrg_sdf dut_s (out_s, in); initial begin $sdf_annotate("ivltests/real_delay.sdf"); $sdf_annotate("ivltests/real_delay_lrg.sdf"); in = 1'b1; in <= #0.1 1'b0; test = 1'b0; #1.234 test = 1'b1; end endmodule // Check that the specify delays are scaled correctly. module lrg_inv(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (1.134, 0); endspecify endmodule // Check that the SDF delays scale correctly. module lrg_sdf(out, in); output out; input in; wire out, in; assign out = ~in; specify (in => out) = (0.5, 0.5); endspecify endmodule // Check that variable delays are scaled correctly. module lrg_var; reg test, in; real dly, dly2, dly3; wire out_g, out_u; not #(dly2, dly3) dut_g (out_g, in); not_u #(dly2, dly3) dut_u (out_u, in); initial begin in = 1'b1; in <= #0.1 1'b0; dly = 1.234; dly2 = 1.134; dly3 = 0.0; test = 1'b0; #(dly) test = 1'b1; end endmodule iverilog-12_0/ivtest/ivltests/real_delay_lrg.sdf000066400000000000000000000003021435245347300222000ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (TIMESCALE 1ns) (CELL (CELLTYPE "lrg_sdf") (INSTANCE dut_s) (DELAY (ABSOLUTE (IOPATH in out (1.134) (0.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/real_delay_med.sdf000066400000000000000000000003021435245347300221610ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (TIMESCALE 1ns) (CELL (CELLTYPE "med_sdf") (INSTANCE dut_s) (DELAY (ABSOLUTE (IOPATH in out (1.134) (0.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/real_delay_sml.sdf000066400000000000000000000003021435245347300222070ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (TIMESCALE 1ns) (CELL (CELLTYPE "sml_sdf") (INSTANCE dut_s) (DELAY (ABSOLUTE (IOPATH in out (1.134) (0.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/real_events.v000066400000000000000000000011551435245347300212420ustar00rootroot00000000000000module test(); real val; always @(val) begin $display("val = %f", val); end task automatic test_task(input integer delay, input real val1, input real val2); real val; fork begin @(val) $display("val%0d = %f", delay, val); @(val) $display("val%0d = %f", delay, val); end begin #delay; #2 val = val1; #2 val = val1; #2 val = val2; end join endtask initial begin #1 val = 1.0; #1 val = 1.0; #1 val = 2.0; fork test_task(1, 1.1, 2.1); test_task(2, 1.2, 2.2); join fork test_task(1, 2.1, 3.1); test_task(2, 2.2, 3.2); join #1 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/real_force_rel.v000066400000000000000000000037141435245347300217010ustar00rootroot00000000000000module test (); reg pass = 1'b1; reg d; real f = 0.0, z = 0.0, y = 1.0; always @(d) force f = z; initial begin // Verify the initial value. #1; if (f != 0.0) begin $display("Failed initial value, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the force changed the value and that a normal assign // is blocked. #1 d = 0; #1 f = 1.0; if (f != 0.0) begin $display("Failed force holding (normal), expected 0.0, got %f", f); pass = 1'b0; end // Verify that an assign does not change the value when forced. #1 assign f = y; if (f != 0.0) begin $display("Failed force holding (assign), expected 0.0, got %f", f); pass = 1'b0; end // Verify that a force will propagate. z = 1.0; #1; if (f != 1.0) begin $display("Failed force propagation, expected 1.0, got %f", f); pass = 1'b0; end // Verify that the release holds the previous value. #1 release f; if (f != 1.0) begin $display("Failed release holding, expected 1.0, got %f", f); pass = 1'b0; end // Verify that a release correctly breaks the variable link. #1 z = 0.0; if (f != 1.0) begin $display("Failed variable unlinking (force), expected 1.0, got %f", f); pass = 1'b0; end // Verify that a deassign holds the previous value. #1 deassign f; if (f != 1.0) begin $display("Failed deassign holding, expected 1.0, got %f", f); pass = 1'b0; end // Verify that a deassign correctly breaks the variable link. #1 y = 0.0; if (f != 1.0) begin $display("Failed variable unlinking (deassign), expected 1.0, got %f", f); pass = 1'b0; end // Verify that the value can be changed after a release and a deassign. #1 f = 2.0; if (f != 2.0) begin $display("Failed release, expected 2.0, got %f", f); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_invalid_ops.v000066400000000000000000000024701435245347300222460ustar00rootroot00000000000000module top; real var1, var2; reg [7:0] bvar; reg result; wire r_a = &var1; wire r_o = |var1; wire r_x = ^var1; wire r_na = ~&var1; wire r_no = ~|var1; wire r_xn1 = ~^var1; wire r_xn2 = ^~var1; wire r_b_a = var1 & var2; wire r_b_o = var1 | var2; wire r_b_x = var1 ^ var2; wire r_b_na = var1 ~& var2; wire r_b_no = var1 ~| var2; wire r_b_xn1 = var1 ~^ var2; wire r_b_xn2 = var1 ^~ var2; wire r_eeq = var1 === var2; wire r_neeq = var1 !== var2; wire r_ls = var1 << var2; wire r_als = var1 <<< var2; wire r_rs = var1 >> var2; wire r_ars = var1 >>> var2; wire r_con = {var1}; wire r_rep = {2.0{var1}}; initial begin var1 = 1.0; var2 = 2.0; #1; /* These should all fail in the compiler. */ result = &var1; result = |var1; result = ^var1; result = ~&var1; result = ~|var1; result = ~^var1; result = ^~var1; result = var1 & var2; result = var1 | var2; result = var1 ^ var2; result = var1 ~& var2; result = var1 ~| var2; result = var1 ~^ var2; result = var1 ^~ var2; result = var1 === var2; result = var1 !== var2; bvar = var1 << var2; bvar = var1 <<< var2; bvar = var1 >> var2; bvar = var1 >>> var2; bvar = {var1}; bvar = {2.0{var1}}; $display("Failed"); end endmodule iverilog-12_0/ivtest/ivltests/real_logical.v000066400000000000000000000133051435245347300213500ustar00rootroot00000000000000module top; parameter parg0 = 0.0; parameter parg1 = 1.0; parameter parg2 = 2.0; parameter pargi = 1.0/0.0; // Inf. parameter pargn = $sqrt(-1.0); // NaN. real arg0, arg1, arg2, argi, argn; reg result, pass; initial begin pass = 1'b1; arg0 = 0.0; arg1 = 1.0; arg2 = 2.0; argi = 1.0/0.0; // Inf. argn = $sqrt(-1.0); // NaN. /* Check ! on a constant real value. */ result = !parg0; if (result !== 1'b1) begin $display("Failed: constant !0.0, expected 1'b1, got %b", result); pass = 1'b0; end result = !parg1; if (result !== 1'b0) begin $display("Failed: constant !1.0, expected 1'b0, got %b", result); pass = 1'b0; end result = !parg2; if (result !== 1'b0) begin $display("Failed: constant !2.0, expected 1'b0, got %b", result); pass = 1'b0; end result = !pargi; if (result !== 1'b0) begin $display("Failed: constant !Inf, expected 1'b0, got %b", result); pass = 1'b0; end result = !pargn; if (result !== 1'b0) begin $display("Failed: constant !NaN, expected 1'b0, got %b", result); pass = 1'b0; end /* Check ! on a real variable. */ result = !arg0; if (result !== 1'b1) begin $display("Failed: !0.0, expected 1'b1, got %b", result); pass = 1'b0; end result = !arg1; if (result !== 1'b0) begin $display("Failed: !1.0, expected 1'b0, got %b", result); pass = 1'b0; end result = !arg2; if (result !== 1'b0) begin $display("Failed: !2.0, expected 1'b0, got %b", result); pass = 1'b0; end result = !argi; if (result !== 1'b0) begin $display("Failed: !Inf, expected 1'b0, got %b", result); pass = 1'b0; end result = !argn; if (result !== 1'b0) begin $display("Failed: !NaN, expected 1'b0, got %b", result); pass = 1'b0; end /* Check && on a constant real value. */ result = parg0 && parg1; if (result !== 1'b0) begin $display("Failed: constant 0.0 && 1.0, expected 1'b0, got %b", result); pass = 1'b0; end result = parg0 && parg2; if (result !== 1'b0) begin $display("Failed: constant 0.0 && 2.0, expected 1'b0, got %b", result); pass = 1'b0; end result = parg1 && parg2; if (result !== 1'b1) begin $display("Failed: constant 1.0 && 2.0, expected 1'b1, got %b", result); pass = 1'b0; end /* Check && on a real variable. */ result = arg0 && arg1; if (result !== 1'b0) begin $display("Failed: 0.0 && 1.0, expected 1'b0, got %b", result); pass = 1'b0; end result = arg0 && arg2; if (result !== 1'b0) begin $display("Failed: 0.0 && 2.0, expected 1'b0, got %b", result); pass = 1'b0; end result = arg1 && arg2; if (result !== 1'b1) begin $display("Failed: 1.0 && 2.0, expected 1'b1, got %b", result); pass = 1'b0; end /* Check || on a constant real value. */ result = parg0 || 0; if (result !== 1'b0) begin $display("Failed: constant 0.0 || 0, expected 1'b0, got %b", result); pass = 1'b0; end result = parg0 || parg1; if (result !== 1'b1) begin $display("Failed: constant 0.0 || 1.0, expected 1'b1, got %b", result); pass = 1'b0; end result = parg0 || parg2; if (result !== 1'b1) begin $display("Failed: constant 0.0 || 2.0, expected 1'b1, got %b", result); pass = 1'b0; end /* Check || on a real variable. */ result = arg0 || 0; if (result !== 1'b0) begin $display("Failed: 0.0 || 0, expected 1'b0, got %b", result); pass = 1'b0; end result = arg0 || arg1; if (result !== 1'b1) begin $display("Failed: 0.0 || 1.0, expected 1'b1, got %b", result); pass = 1'b0; end result = arg0 || arg2; if (result !== 1'b1) begin $display("Failed: 0.0 || 2.0, expected 1'b1, got %b", result); pass = 1'b0; end /* Check the ternary with a constant real cond. value. */ result = parg0 ? 1'b1 : 1'b0; if (result !== 1'b0) begin $display("Failed: constant 0.0 ? ..., expected 1'b0, got %b", result); pass = 1'b0; end result = parg1 ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: constant 1.0 ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = parg2 ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: constant 2.0 ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = pargi ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: constant Inf ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = pargn ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: constant NaN ? ..., expected 1'b1, got %b", result); pass = 1'b0; end /* Check the ternary with a real cond. variable. */ result = arg0 ? 1'b1 : 1'b0; if (result !== 1'b0) begin $display("Failed: 0.0 ? ..., expected 1'b0, got %b", result); pass = 1'b0; end result = arg1 ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: 1.0 ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = arg2 ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: 2.0 ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = argi ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: Inf ? ..., expected 1'b1, got %b", result); pass = 1'b0; end result = argn ? 1'b1 : 1'b0; if (result !== 1'b1) begin $display("Failed: NaN ? ..., expected 1'b1, got %b", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_mod_in_ca.v000066400000000000000000000014421435245347300216450ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; real ra = 1.0, rb = 2.0; wire real rmod; /* Real Power. */ assign #1 rmod = ra % rb; initial begin #0.9; if (rmod == 1.0) begin pass = 1'b0; $display("Real: modulus value not delayed."); end #0.1; #0; if (rmod != 1.0) begin pass = 1'b0; $display("Real: modulus value not correct, expected 1.0 got %g.", rmod); end #1 ra = 2.0; #2; if (rmod != 0.0) begin pass = 1'b0; $display("Real: modulus value not correct, expected 0.0 got %g.", rmod); end #1 rb = 4.0; #2; if (rmod != 2.0) begin pass = 1'b0; $display("Real: modulus value not correct, expected 2.0 got %g.", rmod); end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_op_fail.v000066400000000000000000000015361435245347300213520ustar00rootroot00000000000000module top; real ra = 1.0, rb = 1.0; wire real rdand, rdnand, rdor, rdnor, rdxor, rdxnor, rand, rnand, ror, rnor, rxor, rxnor, rls, rals, rrs, rars; wire [3:0] lsbr, alsbr, rsbr, arsbr; /* Test the reduction operators. */ assign rdand = &ra; assign rdnand = ~&ra; assign rdor = |ra; assign rdnor = ~|ra; assign rdxor = ^ra; assign rdxnor = ~^ra; /* Test the bit-wise operators. */ assign rand = ra & rb; assign rnand = ra ~& rb; assign ror = ra | rb; assign rnor = ra ~| rb; assign rxor = ra ^ rb; assign rxnor = ra ~^ rb; /* Test the shift operators. */ assign rls = ra << rb; assign rals = ra <<< rb; assign rrs = ra >> rb; assign rars = ra >>> rb; assign lsbr = 4'b1010 << rb; assign alsbr = 4'b1010 <<< rb; assign rsbr = 4'b1010 >> rb; assign arsbr = 4'b1010 >>> rb; endmodule iverilog-12_0/ivtest/ivltests/real_pulse_clean.v000066400000000000000000000012461435245347300222310ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; real in1, in2; wire real mult; /* A simple multiplier. */ assign #0.2 mult = in1*in2; initial begin #1; in1 = 1.0; in2 = 2.0; #1; if (mult != 2.0) begin $display("FAILED (1): expected 2.0 got %g", mult); pass = 0; end #1; in1 = 2.0; in2 = 1.0; #1; if (mult != 2.0) begin $display("FAILED (2): expected 2.0 got %g", mult); pass = 0; end #1; in1 = 1.0; in2 = 2.0; #1; if (mult != 2.0) begin $display("FAILED (3): expected 2.0 got %g", mult); pass = 0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_pwr_in_ca.v000066400000000000000000000021271435245347300216770ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; real ra = 1.0, rb = 2.0; wire real rpow; /* Real Power. */ assign #1 rpow = ra ** rb; initial begin #0.9; if (rpow == 1.0) begin pass = 1'b0; $display("Real: power value not delayed."); end #0.1; #0; if (rpow != 1.0) begin pass = 1'b0; $display("Real: power value not correct, expected 1.0 got %g.", rpow); end #1 ra = 2.0; #2; if (rpow != 4.0) begin pass = 1'b0; $display("Real: power value not correct, expected 4.0 got %g.", rpow); end #1 ra = 0.0; #2; if (rpow != 0.0) begin pass = 1'b0; $display("Real: power value not correct, expected 0.0 got %g.", rpow); end #1 ra = 10.0; #2; if (rpow != 100.0) begin pass = 1'b0; $display("Real: power value not correct, expected 100.0 got %g.", rpow); end #1 ra = 0.0; rb = -1.0; #2; $display("0.0 ** -1.0 = %g", rpow); #1 ra = -1.0; rb = 2.5; #2; $display("-1.0 ** 2.5 = %g", rpow); if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_reg_force_rel.v000066400000000000000000000021171435245347300225320ustar00rootroot00000000000000module test (); reg pass = 1'b1; reg d; real f = 0.0; always @(d) force f = 0.0; initial begin // Verify the initial value. #1; if (f != 0.0) begin $display("Failed initial value, expected 0.0, got %f", f); pass = 1'b0; end // Verify the value can change. #1 f = 1.0; if (f != 1.0) begin $display("Failed value change, expected 1.0, got %f", f); pass = 1'b0; end // Verify that the force changed the value and that a normal assign // is blocked. #1 d = 0; #1 f = 1.0; if (f != 0.0) begin $display("Failed force holding, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the release holds the previous value. #1 release f; if (f != 0.0) begin $display("Failed release holding, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the value can be changed after a release. #1 f = 1.0; if (f != 1.0) begin $display("Failed release, expected 1.0, got %f", f); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_select_invalid.v000066400000000000000000000043001435245347300227160ustar00rootroot00000000000000module top; parameter real rpar = 2.0; real rvar; real rarr [1:0]; real rout, rtmp; wire real wrarr [1:0]; wire real wrbslv, wrpslv, wruplv, wrdolv; wire real wrbstr, wrpstr, wruptr, wrdotr; wire real wrpbs = rpar[0]; wire real wrpps = rpar[0:0]; wire real wrpup = rpar[0+:1]; wire real wrpdo = rpar[0-:1]; wire real wrbs = rvar[0]; wire real wrps = rvar[0:0]; wire real wrup = rvar[0+:1]; wire real wrdo = rvar[0-:1]; wire real wrabs = rarr[0][0]; wire real wraps = rarr[0][0:0]; wire real wraup = rarr[0][0+:1]; wire real wrado = rarr[0][0-:1]; assign wrbslv[0] = rvar; assign wrpslv[0:0] = rvar; assign wruplv[0+:1] = rvar; assign wrdolv[0-:1] = rvar; assign wrarr[0][0] = rvar; assign wrarr[0][0:0] = rvar; assign wrarr[0][0+:1] = rvar; assign wrarr[0][0-:1] = rvar; tran(wrbstr[0], wrarr[1]); tran(wrpstr[0:0], wrarr[1]); tran(wruptr[0+:1], wrarr[1]); tran(wrdotr[0-:1], wrarr[1]); submod1 s1 (wrbstr[0], wrpstr[0:0], wruptr[0+:1], wrdotr[0-:1]); submod2 s2 (wrbstr[0], wrpstr[0:0], wruptr[0+:1], wrdotr[0-:1]); submod3 s3 (wrbstr[0], wrpstr[0:0], wruptr[0+:1], wrdotr[0-:1]); initial begin rtmp = rpar[0]; rtmp = rpar[0:0]; rtmp = rpar[0+:1]; rtmp = rpar[0-:1]; rtmp = rvar[0]; rtmp = rvar[0:0]; rtmp = rvar[0+:1]; rtmp = rvar[0-:1]; rtmp = rarr[0][0]; rtmp = rarr[0][0:0]; rtmp = rarr[0][0+:1]; rtmp = rarr[0][0-:1]; rout[0] = 2.0; rout[0:0] = 2.0; rout[0+:1] = 2.0; rout[0-:1] = 2.0; rarr[0][0] = 1.0; rarr[0][0:0] = 1.0; rarr[0][0+:1] = 1.0; rarr[0][0-:1] = 1.0; end endmodule module submod1(arg1, arg2, arg3, arg4); input arg1, arg2, arg3, arg4; wire real arg1, arg2, arg3, arg4; initial $display("In submod1 with %g, %g, %g, %g", arg1, arg2, arg3, arg4); endmodule module submod2(arg1, arg2, arg3, arg4); output arg1, arg2, arg3, arg4; real arg1, arg2, arg3, arg4; initial $display("In submod2 with %g, %g, %g, %g", arg1, arg2, arg3, arg4); endmodule module submod3(arg1, arg2, arg3, arg4); inout arg1, arg2, arg3, arg4; wire real arg1, arg2, arg3, arg4; initial $display("In submod3 with %g, %g, %g, %g", arg1, arg2, arg3, arg4); endmodule iverilog-12_0/ivtest/ivltests/real_wire_array.v000066400000000000000000000012051435245347300220760ustar00rootroot00000000000000module top; reg passed = 1'b1; real rval = 1.0; wire real rvar [1:0]; assign rvar[0] = -1.0; assign rvar[1] = 2.0*rval; initial begin #1; if (rvar[0] != -1.0) begin $display("Failed: real wire array[0], expected -1.0, got %g", rvar[0]); passed = 1'b0; end if (rvar[1] != 2.0) begin $display("Failed: real wire array[1], expected 2.0, got %g", rvar[1]); passed = 1'b0; end rval = 2.0; #1; if (rvar[1] != 4.0) begin $display("Failed: real wire array[1], expected 4.0, got %g", rvar[1]); passed = 1'b0; end if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/real_wire_force_rel.v000066400000000000000000000021201435245347300227150ustar00rootroot00000000000000module test (); reg pass = 1'b1; reg d; real a = 0.0; wire real f = a; always @(d) force f = 0.0; initial begin // Verify the initial value. #1; if (f != 0.0) begin $display("Failed initial value, expected 0.0, got %f", f); pass = 1'b0; end // Verify the value can change. #1 a = 1.0; if (f != 1.0) begin $display("Failed value change, expected 1.0, got %f", f); pass = 1'b0; end // Verify that the force changed the value and that the CA is blocked. #1 d = 0; #1 a = 1.0; if (f != 0.0) begin $display("Failed force holding, expected 0.0, got %f", f); pass = 1'b0; end // Verify that the release propagates the CA value. #1 release f; if (f != 1.0) begin $display("Failed release change, expected 1.0, got %f", f); pass = 1'b0; end // Verify that the value can be changed after a release. #1 a = 0.0; if (f != 0.0) begin $display("Failed release, expected 0.0, got %f", f); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/realtobits.v000066400000000000000000000043441435245347300211060ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Icarus Verilog declares that $realtobits shall return a 64bit * number that is the normalized IEEE754 encoding of the real value. * Whatever it takes to get that, it does. It should be easy in * general, as most modern processors think in IEEE754 floating point * anyhow. */ module main; real val; initial begin val = 0.0; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h0000000000000000) begin $display("FAILED"); $finish; end val = 1.0; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h3ff0000000000000) begin $display("FAILED"); $finish; end val = 0.5; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h3fe0000000000000) begin $display("FAILED"); $finish; end val = 1.5; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h3ff8000000000000) begin $display("FAILED"); $finish; end val = 1.125; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h3ff2000000000000) begin $display("FAILED"); $finish; end val = 2.6; $display("val=%f (%h)", val, $realtobits(val)); if ($realtobits(val) !== 64'h4004cccccccccccd) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/recursive_func1.v000066400000000000000000000012601435245347300220330ustar00rootroot00000000000000module recursive_func(); function automatic [15:0] factorial; input [15:0] n; begin factorial = (n > 1) ? factorial(n - 1) * n : n; end endfunction reg [15:0] r1; reg [15:0] r2; reg [15:0] r3; initial begin fork r1 = factorial(3); r2 = factorial(4); r3 = factorial(5); join $display("factorial 3 = %0d", r1); $display("factorial 4 = %0d", r2); $display("factorial 5 = %0d", r3); end wire [15:0] r4; wire [15:0] r5; wire [15:0] r6; assign r4 = factorial(6); assign r5 = factorial(7); assign r6 = factorial(8); initial begin #1; $display("factorial 6 = %0d", r4); $display("factorial 7 = %0d", r5); $display("factorial 8 = %0d", r6); end endmodule iverilog-12_0/ivtest/ivltests/recursive_func2.v000066400000000000000000000015111435245347300220330ustar00rootroot00000000000000// Check that recursive functions are supported when the `return` statement is // used. module recursive_func(); function automatic [15:0] factorial(input [15:0] n); if (n > 1) begin : recursion reg [15:0] result; result = factorial(n - 1) * n; return result; end return n; endfunction reg [15:0] r1; reg [15:0] r2; reg [15:0] r3; initial begin fork r1 = factorial(3); r2 = factorial(4); r3 = factorial(5); join $display("factorial 3 = %0d", r1); $display("factorial 4 = %0d", r2); $display("factorial 5 = %0d", r3); end wire [15:0] r4; wire [15:0] r5; wire [15:0] r6; assign r4 = factorial(6); assign r5 = factorial(7); assign r6 = factorial(8); initial begin #1; $display("factorial 6 = %0d", r4); $display("factorial 7 = %0d", r5); $display("factorial 8 = %0d", r6); end endmodule iverilog-12_0/ivtest/ivltests/recursive_func_const1.v000066400000000000000000000006751435245347300232520ustar00rootroot00000000000000// Check that constant recursive functions are supported. module recursive_func(); function automatic [15:0] factorial; input [15:0] n; begin factorial = (n > 1) ? factorial(n - 1) * n : n; end endfunction localparam F3 = factorial(3); localparam F4 = factorial(4); localparam F5 = factorial(5); initial begin $display("factorial 3 = %0d", F3); $display("factorial 4 = %0d", F4); $display("factorial 5 = %0d", F5); end endmodule iverilog-12_0/ivtest/ivltests/recursive_func_const2.v000066400000000000000000000007531435245347300232500ustar00rootroot00000000000000// Check that constant recursive functions are supported when the `return` // statement is used. module recursive_func(); function automatic [15:0] factorial(input [15:0] n); if (n > 1) begin return factorial(n - 1) * n; end return n; endfunction localparam F3 = factorial(3); localparam F4 = factorial(4); localparam F5 = factorial(5); initial begin $display("factorial 3 = %0d", F3); $display("factorial 4 = %0d", F4); $display("factorial 5 = %0d", F5); end endmodule iverilog-12_0/ivtest/ivltests/recursive_task.v000066400000000000000000000010311435245347300217550ustar00rootroot00000000000000module recursive_task(); task automatic factorial; input integer n; output integer f; integer t; fork begin if (n > 1) factorial(n - 1, t); else t = 1; #1 f = n * t; end begin @f $display("intermediate value = %0d", f); end join endtask integer r1; integer r2; integer r3; initial begin fork factorial(3, r1); factorial(4, r2); factorial(5, r3); join $display("factorial 3 = %0d", r1); $display("factorial 4 = %0d", r2); $display("factorial 5 = %0d", r3); end endmodule iverilog-12_0/ivtest/ivltests/redef_net_error.v000066400000000000000000000000621435245347300220730ustar00rootroot00000000000000module test; wire [7:0] value, value; endmodule iverilog-12_0/ivtest/ivltests/redef_reg_error.v000066400000000000000000000000611435245347300220610ustar00rootroot00000000000000module test; reg [7:0] value, value; endmodule iverilog-12_0/ivtest/ivltests/repeat1.v000066400000000000000000000042031435245347300202710ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program demonstrates a tricky aspect of the Verilog syntax. * The problem is with the repeat statement. In fact, there is a * question as to whether it is a repeat statement at all, or an * event statement with a repeat modifier. These are the possibilities: * * 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 ``repeat (5) @(posedge clk)'' * should be taken as a delay_or_event_control and the thread will * block until the 5th clk posedge. * * loop_statement ::= * repeat ( expression ) statement * * If *this* interpretation is used, then ``repeat (5)'' is the loop * head is used and the statement in the example is executed 5 times. * * These two interpretations both appear to be perfectly valid. However, * real tools use the loop_statement, so the standard must be considered * broken and this interpretation used. */ module main; reg clk = 1; always #5 clk = ~clk; initial #1 repeat (5) @(posedge clk) begin if ($time !== 10) begin $display("FAILED -- $time = %t", $time); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/repeat2.v000066400000000000000000000037071435245347300203020ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [3:0] test; initial begin /* A zero count repeat by it self is not allowed by the standard, test = {0{1'b1}}; if (test !== 4'b0000) begin $display("FAILED -- {0{1'b1} == %b", test); $finish; end but it can be used in a valid concatenation (1364-2005). */ test = {{0{1'b1}}, 1'b0}; if (test !== 4'b0000) begin $display("FAILED -- {0{1'b1} == %b", test); $finish; end test = {1{1'b1}}; if (test !== 4'b0001) begin $display("FAILED -- {1{1'b1} == %b", test); $finish; end test = {2{1'b1}}; if (test !== 4'b0011) begin $display("FAILED -- {2{1'b1} == %b", test); $finish; end test = {3{1'b1}}; if (test !== 4'b0111) begin $display("FAILED -- {3{1'b1} == %b", test); $finish; end test = {4{1'b1}}; if (test !== 4'b1111) begin $display("FAILED -- {4{1'b1} == %b", test); $finish; end test = {5{1'b1}}; if (test !== 4'b1111) begin $display("FAILED -- {5{1'b1} == %b", test); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/repeat_expr_probe.v000066400000000000000000000005441435245347300224410ustar00rootroot00000000000000module top; reg [2:0] delay; integer lp; initial begin lp = 0; delay = 3'b000; // The delay+4 expression was failing because probe_expr_width() was // not called before elab_and_eval() with an expression width of -1. repeat (delay+4) lp = lp + 1; if (lp != 4) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/repl_zero_wid_fail.v000066400000000000000000000002031435245347300225630ustar00rootroot00000000000000module top; reg [7:0] result; initial begin result = {0{1'b1}}; // This fails top level zero replication. end endmodule iverilog-12_0/ivtest/ivltests/repl_zero_wid_pass.v000066400000000000000000000006551435245347300226310ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [7:0] result; initial begin result = {{0{1'b1}}, 2'b11}; if (result != 8'h03) begin $display("FAILED: replication inside of concatenation"); pass = 1'b0; end result = {2{{0{1'b1}}, 2'b11}}; if (result != 8'h0f) begin $display("FAILED: replication inside of replication"); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/resetall.v000066400000000000000000000011131435245347300205400ustar00rootroot00000000000000module top_default; initial begin $printtimescale(top_default); $printtimescale(top_timescale); $printtimescale(top_resetall); $printtimescale(top_timescale2); $printtimescale(top_timescale3); end endmodule `resetall `timescale 1ns/1ns module top_timescale; reg a; initial a = 1'b1; endmodule `resetall `resetall module top_resetall; reg a; initial a = 1'b0; endmodule `resetall `timescale 1ms/1ms module top_timescale2; reg a; initial a = 1'b1; endmodule `resetall `timescale 1us/1us module top_timescale3; reg a; initial a = 1'bz; endmodule iverilog-12_0/ivtest/ivltests/resetall2.v000066400000000000000000000003561435245347300206320ustar00rootroot00000000000000`timescale 1us/1us module top_timescale; initial begin $printtimescale(top_timescale); $printtimescale(top_timescale2); end endmodule `resetall `timescale 1ns/1ns module top_timescale2; reg a; initial a = 1'b1; endmodule iverilog-12_0/ivtest/ivltests/resolv1.v000066400000000000000000000006201435245347300203220ustar00rootroot00000000000000module test; wire w; wire q; reg g; pullup(w); bufif1(w, 1'b1, g); pmos(q, w, 1'b0); bufif0(q, 1'b0, g); initial begin g = 1; #10 $display(q, w); // should print "11" #20 g = 0; // w changes from St1 to Pu1 #30 $display(q, w); // should print "01" if (q == 1'b0) $display("PASSED"); else $display("FAILED"); #40 $finish; end endmodule iverilog-12_0/ivtest/ivltests/rise_fall_decay1.v000066400000000000000000000042711435245347300221230ustar00rootroot00000000000000module test(); localparam [7:0] dly1 = 4; wire [7:0] dly2 = 3; reg [7:0] dly3 = 2; reg i; wire [6:1] o; assign #(dly1, dly2, dly3) o[1] = i; assign #(dly2, dly3, dly1) o[2] = i; assign #(dly3, dly1, dly2) o[3] = i; assign #(dly2-1, dly2-2, dly2-3) o[4] = i; assign #(dly3+1, dly3+2, dly3+3) o[5] = i; assign #(4, 3, 2) o[6] = i; function check(input o1, input o2, input o3, input o4, input o5, input o6); begin check = (o[1] == o1) && (o[2] == o2) && (o[3] == o3) && (o[4] == o4) && (o[5] == o5) && (o[6] == o6); end endfunction reg failed = 0; initial begin #1 $monitor($time,,i,,o[1],,o[2],,o[3],,o[4],,o[5],,o[6]); i = 1'b1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'b1, 1'b1, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'b1, 1'b1, 1'b1, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; i = 1'b0; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; i = 1'bx; #0 if (!check(1'b0, 1'b0, 1'b0, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'b0, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; i = 1'bz; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bx, 1'bx, 1'bz, 1'bx, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bx, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bz, 1'bz)) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rise_fall_decay2.v000066400000000000000000000043571435245347300221310ustar00rootroot00000000000000module test(); localparam [7:0] dly1 = 4; wire [7:0] dly2 = 3; reg [7:0] dly3 = 2; reg i; wire [6:1] o; nmos #(dly1, dly2, dly3) buf1(o[1], i, 1'b1); nmos #(dly2, dly3, dly1) buf2(o[2], i, 1'b1); nmos #(dly3, dly1, dly2) buf3(o[3], i, 1'b1); nmos #(dly2-1, dly2-2, dly2-3) buf4(o[4], i, 1'b1); nmos #(dly3+1, dly3+2, dly3+3) buf5(o[5], i, 1'b1); nmos #(4, 3, 2) buf6(o[6], i, 1'b1); function check(input o1, input o2, input o3, input o4, input o5, input o6); begin check = (o[1] == o1) && (o[2] == o2) && (o[3] == o3) && (o[4] == o4) && (o[5] == o5) && (o[6] == o6); end endfunction reg failed = 0; initial begin #1 $monitor($time,,i,,o[1],,o[2],,o[3],,o[4],,o[5],,o[6]); i = 1'b1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'b1, 1'b1, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'b1, 1'b1, 1'b1, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; i = 1'b0; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; i = 1'bx; #0 if (!check(1'b0, 1'b0, 1'b0, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'b0, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; i = 1'bz; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bx, 1'bx, 1'bz, 1'bx, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bx, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bz, 1'bz)) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rise_fall_delay1.v000066400000000000000000000035451435245347300221370ustar00rootroot00000000000000module test(); localparam [7:0] dly1 = 1; wire [7:0] dly2 = 2; reg [7:0] dly3 = 3; reg i; wire [6:1] o; assign #(dly1, dly2) o[1] = i; assign #(dly2, dly1) o[2] = i; assign #(dly1, dly3) o[3] = i; assign #(dly3, dly1) o[4] = i; assign #(dly2, dly3+1) o[5] = i; assign #(4, 2) o[6] = i; function check(input o1, input o2, input o3, input o4, input o5, input o6); begin check = (o[1] == o1) && (o[2] == o2) && (o[3] == o3) && (o[4] == o4) && (o[5] == o5) && (o[6] == o6); end endfunction reg failed = 0; initial begin #1 $monitor($time,,i,,o[1],,o[2],,o[3],,o[4],,o[5],,o[6]); i = 1'b1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'bx, 1'b1, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'bx, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; i = 1'b0; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; i = 1'bx; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; i = 1'bz; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bz, 1'bz)) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rise_fall_delay2.v000066400000000000000000000035611435245347300221360ustar00rootroot00000000000000module test(); localparam [7:0] dly1 = 1; wire [7:0] dly2 = 2; reg [7:0] dly3 = 3; reg i; wire [6:1] o; buf #(dly1, dly2) buf1(o[1], i); buf #(dly2, dly1) buf2(o[2], i); buf #(dly1, dly3) buf3(o[3], i); buf #(dly3, dly1) buf4(o[4], i); buf #(dly2, dly3+1) buf5(o[5], i); buf #(4, 2) buf6(o[6], i); function check(input o1, input o2, input o3, input o4, input o5, input o6); begin check = (o[1] == o1) && (o[2] == o2) && (o[3] == o3) && (o[4] == o4) && (o[5] == o5) && (o[6] == o6); end endfunction reg failed = 0; initial begin #1 $monitor($time,,i,,o[1],,o[2],,o[3],,o[4],,o[5],,o[6]); i = 1'b1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'bx, 1'b1, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'bx, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; i = 1'b0; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'b0, 1'b1, 1'b0, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0)) failed = 1; #1; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; i = 1'bx; #0 if (!check(1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'b0, 1'b0)) failed = 1; #1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; i = 1'bz; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bz, 1'bz)) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rise_fall_delay3.v000066400000000000000000000027711435245347300221410ustar00rootroot00000000000000module test(); localparam [7:0] dly1 = 1; wire [7:0] dly2 = 2; reg [7:0] dly3 = 3; reg en; wire i = 1; wire [6:1] o; tranif1 #(dly1, dly2) buf1(o[1], i, en); tranif1 #(dly2, dly1) buf2(o[2], i, en); tranif1 #(dly1, dly3) buf3(o[3], i, en); tranif1 #(dly3, dly1) buf4(o[4], i, en); tranif1 #(dly2, dly3+1) buf5(o[5], i, en); tranif1 #(4, 2) buf6(o[6], i, en); function check(input o1, input o2, input o3, input o4, input o5, input o6); begin check = (o[1] == o1) && (o[2] == o2) && (o[3] == o3) && (o[4] == o4) && (o[5] == o5) && (o[6] == o6); end endfunction reg failed = 0; initial begin #1 $monitor($time,,en,,o[1],,o[2],,o[3],,o[4],,o[5],,o[6]); en = 1'b1; #0 if (!check(1'bx, 1'bx, 1'bx, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'bx, 1'b1, 1'bx, 1'bx, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'bx, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'bx)) failed = 1; #1; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; en = 1'b0; #0 if (!check(1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'b1, 1'bz, 1'b1, 1'bz, 1'b1, 1'b1)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'b1, 1'bz, 1'b1, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'b1, 1'bz)) failed = 1; #1; #0 if (!check(1'bz, 1'bz, 1'bz, 1'bz, 1'bz, 1'bz)) failed = 1; #1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rl_pow.v000066400000000000000000000017471435245347300202440ustar00rootroot00000000000000`timescale 1us/100ns module top; reg pass = 1'b1; real ra, rb, rpow; initial begin ra = 1.0; rb = 2.0; rpow = ra ** rb; if (rpow != 1.0) begin pass = 1'b0; $display("Real: power value not correct, expected 1.0 got %g.", rpow); end ra = 2.0; rpow = ra ** rb; if (rpow != 4.0) begin pass = 1'b0; $display("Real: power value not correct, expected 4.0 got %g.", rpow); end ra = 0.0; rpow = ra ** rb; if (rpow != 0.0) begin pass = 1'b0; $display("Real: power value not correct, expected 0.0 got %g.", rpow); end ra = 10.0; rpow = ra ** rb; if (rpow != 100.0) begin pass = 1'b0; $display("Real: power value not correct, expected 100.0 got %g.", rpow); end ra = 0.0; rb = -1.0; rpow = ra ** rb; $display("0.0 ** -1.0 = %g", rpow); ra = -1.0; rb = 2.5; rpow = ra ** rb; $display("-1.0 ** 2.5 = %g", rpow); if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rnpmos.v000066400000000000000000000035471435245347300202600ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; wire no, po; reg d, c; rnmos n (no, d, c); rpmos p (po, d, c); initial begin c = 0; d = 0; #1 if (no !== 1'bz) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'b0) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end d = 1; #1 if (no !== 1'bz) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'b1) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end c = 1; #1 if (no !== 1'b1) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'bz) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end d = 0; #1 if (no !== 1'b0) begin $display("FAILED -- n (%b, %b, %b)", no, d, c); $finish; end if (po !== 1'bz) begin $display("FAILED -- p (%b, %b, %b)", po, d, c); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/rnpmos2.v000066400000000000000000000043401435245347300203320ustar00rootroot00000000000000// Copyright (c) 2001 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // /* * This module implements what essentially amounts to an array of DFF * devices with output enable. This test checks the operation of the * pmos and nmos devices. */ module grayGap (ad, clk, read, write); output [31:0] ad; input clk, read, write; reg [15:0] regff; rpmos ad_drv [31:0] (ad, {16'b0, regff}, read); always @(posedge clk) if (write) regff = ad[15:0]; endmodule module main; wire [31:0] ad; reg clk, read, write; reg [31:0] ad_val; reg ad_en; rnmos ad_drv[31:0] (ad, ad_val, ad_en); grayGap test (ad, clk, read, write); always #10 clk = ~clk; initial begin clk = 1; read = 1; write = 0; $monitor($time, "ad=%b", ad); // Set up to write a value into the grayGap register. @(negedge clk) ad_val = 32'haaaa_aaaa; read = 1; write = 1; ad_en = 1; // The posedge has passed, now set up to read that value // out. Turn all the drivers off for a moment, to see that the // line becomes tri-state... @(negedge clk) ad_en = 0; write = 0; // Now read the value. #1 read = 0; #1 $display("Wrote %h, got %h", ad_val, ad); if (ad !== 32'b0000_0000_0000_0000_1010_1010_1010_1010) begin $display("FAILED -- ad is %b", ad); $finish; end #2 read = 1; $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/rop.v000066400000000000000000000115721435245347300175370ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: rop.v,v 1.2 2001/06/20 00:04:09 ka6s Exp $ // $Log: rop.v,v $ // Revision 1.2 2001/06/20 00:04:09 ka6s // Updated the code to print out "PASSED" when appropriate. // // Revision 1.1 2001/06/19 13:52:13 ka6s // Added 4 tests from Stephan Boettcher // // // Test of === operator module rop; reg [2:0] a; reg b; reg error; initial begin error = 0; a = 3'b 10z; b = & a; $display(" & 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = | a; $display(" | 3'b%b === %b", a, b); if (b !== 1'b1) begin error = 1; $display("FAILED"); end b = ^ a; $display(" ^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ~& a; $display("~& 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ~| a; $display("~| 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ~^ a; $display("~^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end a = 3'b 0xz; b = & a; $display(" & 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = | a; $display(" | 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ^ a; $display(" ^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ~& a; $display("~& 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ~| a; $display("~| 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ~^ a; $display("~^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end a = 3'b 1xz; b = & a; $display(" & 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = | a; $display(" | 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ^ a; $display(" ^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ~& a; $display("~& 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end b = ~| a; $display("~| 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ~^ a; $display("~^ 3'b%b === %b", a, b); if (b !== 1'bx) begin $display("FAILED"); error = 1; end a = 3'b 000; b = & a; $display(" & 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = | a; $display(" | 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ^ a; $display(" ^ 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ~& a; $display("~& 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ~| a; $display("~| 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ~^ a; $display("~^ 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end a = 3'b 111; b = & a; $display(" & 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = | a; $display(" | 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ^ a; $display(" ^ 3'b%b === %b", a, b); if (b !== 1'b1) begin $display("FAILED"); error = 1; end b = ~& a; $display("~& 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ~| a; $display("~| 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end b = ~^ a; $display("~^ 3'b%b === %b", a, b); if (b !== 1'b0) begin $display("FAILED"); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rptconcat.v000066400000000000000000000022001435245347300207200ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate repeat concatenation literal behavior. // module test (); wire [7:0] result; assign result = {2{4'b1011}}; initial begin #1; if(result === 8'b10111011) $display("PASSED"); else $display("FAILED - {2{4'b1011}} s/b 8'b10111011 - is %b",result); end endmodule iverilog-12_0/ivtest/ivltests/rptconcat2.v000066400000000000000000000004021435245347300210040ustar00rootroot00000000000000module main(); reg [3:0] d, e; initial begin d <= {4{1'b1}}; e = {4{1'b1}}; #1; $display("%b %b",d,e); if (d !== e) begin $display("FAILED -- %b !== %b", d, e); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/rtran.v000066400000000000000000000066151435245347300200670ustar00rootroot00000000000000module test(); reg a, b; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; rtran t1(a1, a2); rtran t2(a2, a3); rtran t3(a3, a4); rtran t4(a4, a5); rtran t5(a5, a6); rtran t6(a6, a7); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; rtran t11(a11, b11); rtran t12(a12, b12); rtran t13(a13, b13); rtran t14(a14, b14); rtran t15(a15, b15); rtran t21(a21, b21); rtran t22(a22, b22); rtran t23(a23, b23); rtran t24(a24, b24); rtran t25(a25, b25); rtran t31(a31, b31); rtran t32(a32, b32); rtran t33(a33, b33); rtran t34(a34, b34); rtran t35(a35, b35); rtran t41(a41, b41); rtran t42(a42, b42); rtran t43(a43, b43); rtran t44(a44, b44); rtran t45(a45, b45); rtran t51(a51, b51); rtran t52(a52, b52); rtran t53(a53, b53); rtran t54(a54, b54); rtran t55(a55, b55); task display_strengths; input ta, tb; begin a = ta; b = tb; #1; $display("a = %b b = %b", a, b); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz); display_strengths(1'bx, 1'bz); display_strengths(1'b0, 1'bz); display_strengths(1'b1, 1'bz); display_strengths(1'bz, 1'bx); display_strengths(1'bx, 1'bx); display_strengths(1'b0, 1'bx); display_strengths(1'b1, 1'bx); display_strengths(1'bz, 1'b0); display_strengths(1'bx, 1'b0); display_strengths(1'b0, 1'b0); display_strengths(1'b1, 1'b0); display_strengths(1'bz, 1'b1); display_strengths(1'bx, 1'b1); display_strengths(1'b0, 1'b1); display_strengths(1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/rtranif0.v000066400000000000000000000131051435245347300204560ustar00rootroot00000000000000module test(); reg a, b, en; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; rtranif0 t1(a1, a2, en); rtranif0 t2(a2, a3, en); rtranif0 t3(a3, a4, en); rtranif0 t4(a4, a5, en); rtranif0 t5(a5, a6, en); rtranif0 t6(a6, a7, en); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; rtranif0 t11(a11, b11, en); rtranif0 t12(a12, b12, en); rtranif0 t13(a13, b13, en); rtranif0 t14(a14, b14, en); rtranif0 t15(a15, b15, en); rtranif0 t21(a21, b21, en); rtranif0 t22(a22, b22, en); rtranif0 t23(a23, b23, en); rtranif0 t24(a24, b24, en); rtranif0 t25(a25, b25, en); rtranif0 t31(a31, b31, en); rtranif0 t32(a32, b32, en); rtranif0 t33(a33, b33, en); rtranif0 t34(a34, b34, en); rtranif0 t35(a35, b35, en); rtranif0 t41(a41, b41, en); rtranif0 t42(a42, b42, en); rtranif0 t43(a43, b43, en); rtranif0 t44(a44, b44, en); rtranif0 t45(a45, b45, en); rtranif0 t51(a51, b51, en); rtranif0 t52(a52, b52, en); rtranif0 t53(a53, b53, en); rtranif0 t54(a54, b54, en); rtranif0 t55(a55, b55, en); task display_strengths; input ta, tb, ten; begin a = ta; b = tb; en = ten; #1; $display("a = %b b = %b en = %b", a, b, en); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz, 1'bz); display_strengths(1'bz, 1'bz, 1'bx); display_strengths(1'bz, 1'bz, 1'b0); display_strengths(1'bz, 1'bz, 1'b1); display_strengths(1'bx, 1'bz, 1'bz); display_strengths(1'bx, 1'bz, 1'bx); display_strengths(1'bx, 1'bz, 1'b0); display_strengths(1'bx, 1'bz, 1'b1); display_strengths(1'b0, 1'bz, 1'bz); display_strengths(1'b0, 1'bz, 1'bx); display_strengths(1'b0, 1'bz, 1'b0); display_strengths(1'b0, 1'bz, 1'b1); display_strengths(1'b1, 1'bz, 1'bz); display_strengths(1'b1, 1'bz, 1'bx); display_strengths(1'b1, 1'bz, 1'b0); display_strengths(1'b1, 1'bz, 1'b1); display_strengths(1'bz, 1'bx, 1'bz); display_strengths(1'bz, 1'bx, 1'bx); display_strengths(1'bz, 1'bx, 1'b0); display_strengths(1'bz, 1'bx, 1'b1); display_strengths(1'bx, 1'bx, 1'bz); display_strengths(1'bx, 1'bx, 1'bx); display_strengths(1'bx, 1'bx, 1'b0); display_strengths(1'bx, 1'bx, 1'b1); display_strengths(1'b0, 1'bx, 1'bz); display_strengths(1'b0, 1'bx, 1'bx); display_strengths(1'b0, 1'bx, 1'b0); display_strengths(1'b0, 1'bx, 1'b1); display_strengths(1'b1, 1'bx, 1'bz); display_strengths(1'b1, 1'bx, 1'bx); display_strengths(1'b1, 1'bx, 1'b0); display_strengths(1'b1, 1'bx, 1'b1); display_strengths(1'bz, 1'b0, 1'bz); display_strengths(1'bz, 1'b0, 1'bx); display_strengths(1'bz, 1'b0, 1'b0); display_strengths(1'bz, 1'b0, 1'b1); display_strengths(1'bx, 1'b0, 1'bz); display_strengths(1'bx, 1'b0, 1'bx); display_strengths(1'bx, 1'b0, 1'b0); display_strengths(1'bx, 1'b0, 1'b1); display_strengths(1'b0, 1'b0, 1'bz); display_strengths(1'b0, 1'b0, 1'bx); display_strengths(1'b0, 1'b0, 1'b0); display_strengths(1'b0, 1'b0, 1'b1); display_strengths(1'b1, 1'b0, 1'bz); display_strengths(1'b1, 1'b0, 1'bx); display_strengths(1'b1, 1'b0, 1'b0); display_strengths(1'b1, 1'b0, 1'b1); display_strengths(1'bz, 1'b1, 1'bz); display_strengths(1'bz, 1'b1, 1'bx); display_strengths(1'bz, 1'b1, 1'b0); display_strengths(1'bz, 1'b1, 1'b1); display_strengths(1'bx, 1'b1, 1'bz); display_strengths(1'bx, 1'b1, 1'bx); display_strengths(1'bx, 1'b1, 1'b0); display_strengths(1'bx, 1'b1, 1'b1); display_strengths(1'b0, 1'b1, 1'bz); display_strengths(1'b0, 1'b1, 1'bx); display_strengths(1'b0, 1'b1, 1'b0); display_strengths(1'b0, 1'b1, 1'b1); display_strengths(1'b1, 1'b1, 1'bz); display_strengths(1'b1, 1'b1, 1'bx); display_strengths(1'b1, 1'b1, 1'b0); display_strengths(1'b1, 1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/rtranif1.v000066400000000000000000000131051435245347300204570ustar00rootroot00000000000000module test(); reg a, b, en; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; rtranif1 t1(a1, a2, en); rtranif1 t2(a2, a3, en); rtranif1 t3(a3, a4, en); rtranif1 t4(a4, a5, en); rtranif1 t5(a5, a6, en); rtranif1 t6(a6, a7, en); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; rtranif1 t11(a11, b11, en); rtranif1 t12(a12, b12, en); rtranif1 t13(a13, b13, en); rtranif1 t14(a14, b14, en); rtranif1 t15(a15, b15, en); rtranif1 t21(a21, b21, en); rtranif1 t22(a22, b22, en); rtranif1 t23(a23, b23, en); rtranif1 t24(a24, b24, en); rtranif1 t25(a25, b25, en); rtranif1 t31(a31, b31, en); rtranif1 t32(a32, b32, en); rtranif1 t33(a33, b33, en); rtranif1 t34(a34, b34, en); rtranif1 t35(a35, b35, en); rtranif1 t41(a41, b41, en); rtranif1 t42(a42, b42, en); rtranif1 t43(a43, b43, en); rtranif1 t44(a44, b44, en); rtranif1 t45(a45, b45, en); rtranif1 t51(a51, b51, en); rtranif1 t52(a52, b52, en); rtranif1 t53(a53, b53, en); rtranif1 t54(a54, b54, en); rtranif1 t55(a55, b55, en); task display_strengths; input ta, tb, ten; begin a = ta; b = tb; en = ten; #1; $display("a = %b b = %b en = %b", a, b, en); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz, 1'bz); display_strengths(1'bz, 1'bz, 1'bx); display_strengths(1'bz, 1'bz, 1'b0); display_strengths(1'bz, 1'bz, 1'b1); display_strengths(1'bx, 1'bz, 1'bz); display_strengths(1'bx, 1'bz, 1'bx); display_strengths(1'bx, 1'bz, 1'b0); display_strengths(1'bx, 1'bz, 1'b1); display_strengths(1'b0, 1'bz, 1'bz); display_strengths(1'b0, 1'bz, 1'bx); display_strengths(1'b0, 1'bz, 1'b0); display_strengths(1'b0, 1'bz, 1'b1); display_strengths(1'b1, 1'bz, 1'bz); display_strengths(1'b1, 1'bz, 1'bx); display_strengths(1'b1, 1'bz, 1'b0); display_strengths(1'b1, 1'bz, 1'b1); display_strengths(1'bz, 1'bx, 1'bz); display_strengths(1'bz, 1'bx, 1'bx); display_strengths(1'bz, 1'bx, 1'b0); display_strengths(1'bz, 1'bx, 1'b1); display_strengths(1'bx, 1'bx, 1'bz); display_strengths(1'bx, 1'bx, 1'bx); display_strengths(1'bx, 1'bx, 1'b0); display_strengths(1'bx, 1'bx, 1'b1); display_strengths(1'b0, 1'bx, 1'bz); display_strengths(1'b0, 1'bx, 1'bx); display_strengths(1'b0, 1'bx, 1'b0); display_strengths(1'b0, 1'bx, 1'b1); display_strengths(1'b1, 1'bx, 1'bz); display_strengths(1'b1, 1'bx, 1'bx); display_strengths(1'b1, 1'bx, 1'b0); display_strengths(1'b1, 1'bx, 1'b1); display_strengths(1'bz, 1'b0, 1'bz); display_strengths(1'bz, 1'b0, 1'bx); display_strengths(1'bz, 1'b0, 1'b0); display_strengths(1'bz, 1'b0, 1'b1); display_strengths(1'bx, 1'b0, 1'bz); display_strengths(1'bx, 1'b0, 1'bx); display_strengths(1'bx, 1'b0, 1'b0); display_strengths(1'bx, 1'b0, 1'b1); display_strengths(1'b0, 1'b0, 1'bz); display_strengths(1'b0, 1'b0, 1'bx); display_strengths(1'b0, 1'b0, 1'b0); display_strengths(1'b0, 1'b0, 1'b1); display_strengths(1'b1, 1'b0, 1'bz); display_strengths(1'b1, 1'b0, 1'bx); display_strengths(1'b1, 1'b0, 1'b0); display_strengths(1'b1, 1'b0, 1'b1); display_strengths(1'bz, 1'b1, 1'bz); display_strengths(1'bz, 1'b1, 1'bx); display_strengths(1'bz, 1'b1, 1'b0); display_strengths(1'bz, 1'b1, 1'b1); display_strengths(1'bx, 1'b1, 1'bz); display_strengths(1'bx, 1'b1, 1'bx); display_strengths(1'bx, 1'b1, 1'b0); display_strengths(1'bx, 1'b1, 1'b1); display_strengths(1'b0, 1'b1, 1'bz); display_strengths(1'b0, 1'b1, 1'bx); display_strengths(1'b0, 1'b1, 1'b0); display_strengths(1'b0, 1'b1, 1'b1); display_strengths(1'b1, 1'b1, 1'bz); display_strengths(1'b1, 1'b1, 1'bx); display_strengths(1'b1, 1'b1, 1'b0); display_strengths(1'b1, 1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/sbyte_test.v000066400000000000000000000240731435245347300211240ustar00rootroot00000000000000// Ten basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (signed) bytes with random numbers // 3. assignments to (signed) bytes with random values including X and Z // 4. converting unsigned integers to signed bytes // 5. converting signed integers to signed bytes // 6. converting integers including X and Z states to signed bytes // 7. trying signed sums (procedural, function, task and module) // 8. trying signed mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to signed bytes (sign extension) module ms_add (input byte signed a, b, output byte signed sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter MAX = 'h7f; parameter LEN = 8; // variables used as golden references reg signed [LEN-1:0] ar; // holds numbers reg signed [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg signed [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // types to be tested byte signed bu; // holds numbers byte signed bu_xz; // 'x and 'z are attempted on this byte signed bresult; // hold results from sums and mults byte signed mcaresult; // this is permanently wired to a module byte signed mabresult; // this is permanently wired to a module integer i; // continuous assigments // type LHS type RHS // --------- --------- // byte 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation ms_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 8'b0 || bu_xz != 8'b0 || bresult !== 8'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving byte type with signed random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned bytes // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = $random % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to signed bytes // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random} % 2*(MAX+1); // full range as unsigned #1; force bu = ui; #1; if (bu !== ui[LEN-1:0]) begin $display ("FAILED - incorrect truncation from unsigned integer to byte: %b", bu); $finish; end end release bu; // converting signed integers to signed bytes // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random % MAX; #1; force bu = si; #1; if (bu !== si[LEN-1:0]) begin $display ("FAILED - incorrect truncation from signed integer to byte: %b mismatchs %b", bu, si[LEN-1:0]); $finish; end end release bu; // converting signed integers having 'x 'z values into type signed bytes // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si[LEN-1:0]); si = {si[31:LEN], ar_xz}; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to byte: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying signed sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % MAX; ar_xz = $random % MAX; #1; bresult = bu + bu_xz; #1; if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed bytes: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // invoking byte sum function if ( fs_sum (bu, bu_xz) !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed bytes in function"); $finish; end // invoking byte sum task ts_sum (bu, bu_xz, bresult); if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed bytes in task: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // checking byte sum from module if ( mcaresult !== s_sum(ar, ar_xz) || mabresult !== s_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of signed bytes from module"); $finish; end end // trying signed mults, forcing truncation for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ($random % MAX) << LEN/2; ar_xz = ($random % MAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; #1; if ( bresult !== s_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect product of signed bytes: %0d mismatchs %0d", bresult, s_mul(ar, ar_xz)); $finish; end // invoking byte mult function if ( fs_mul (bu, bu_xz) !== s_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect product of signed bytes in function"); $finish; end // invoking byte mult task ts_mul (bu, bu_xz, bresult); if ( bresult !== s_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect product of signed bytes in task: %0d mismatchs %0d", bresult, s_mul(ar, ar_xz)); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % MAX; ar_xz = $random % MAX; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on signed bytes"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on signed bytes"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on signed bytes"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on signed bytes"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on signed bytes"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on signed bytes"); $finish; end end // signed small number to signed byte for (i = 0; i < (1<sub.gen_block[0].trigger; #1 ->sub.gen_block[1].trigger; #1 ->sub.gen_block[2].trigger; #1 ->sub.gen_block[3].trigger; #1 ->sub.my_block.trigger; #1 ->sub.my_task.trigger; #1 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/sdf1.sdf000066400000000000000000000007321435245347300200770ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "XOR20") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf1.v000066400000000000000000000010141435245347300175620ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf1.sdf"); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf2.sdf000066400000000000000000000007351435245347300201030ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "XOR20") (INSTANCE dut/U1) (DELAY (ABSOLUTE (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf2.v000066400000000000000000000011531435245347300175670ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module plug(input A, input B, output Q); XOR20 U1(.A(A), .B(B), .Q(Q)); endmodule // plug module tb; reg a, b; wire q; plug dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf2.sdf"); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf3.sdf000066400000000000000000000007261435245347300201040ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "XOR20") (INSTANCE) (DELAY (ABSOLUTE (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf3.v000066400000000000000000000010221435245347300175630ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); initial $sdf_annotate("ivltests/sdf3.sdf"); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf4.sdf000066400000000000000000000007261435245347300201050ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "XOR20") (INSTANCE) (DELAY (ABSOLUTE (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf4.v000066400000000000000000000010211435245347300175630ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf4.sdf", dut); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf5.sdf000066400000000000000000000006621435245347300201050ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "sdf5") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "DFF") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH (posedge C) Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf5.v000066400000000000000000000010211435245347300175640ustar00rootroot00000000000000module DFF (input D, input C, output reg Q); always @(posedge C) Q <= D; specify (posedge C => (Q +: D)) = (1,1); endspecify endmodule `endcelldefine module tb; reg clk, d; wire q; DFF dut(.D(d), .C(clk), .Q(q)); initial begin clk = 0; d = 0; $monitor($time,, "D=%b, Q=%b, clk=%b", d, q, clk); $sdf_annotate("ivltests/sdf5.sdf"); #10 clk = 1; #10 clk = 0; d = 1; #10 clk = 1; #10 clk = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf6.sdf000066400000000000000000000007031435245347300201020ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "dff") (DATE "Today") (VENDOR "Icarus") (PROGRAM "Cary") (VERSION "1.0") (DIVIDER /) (VOLTAGE 2.7:2.7:2.7) (PROCESS "nom") (TEMPERATURE 27.0:27.0:27.0) (TIMESCALE 1ns) (CELL (CELLTYPE "dff") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH cdn q (2.0:2.0:2.0) (3.0:3.0:3.0)) (IOPATH sdn q (4.0:4.0:4.0) (5.0:5.0:5.0)) (IOPATH (posedge cp) q (6.0:6.0:6.0) (7.0:7.0:7.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf6.v000066400000000000000000000014311435245347300175720ustar00rootroot00000000000000module dff (q, d, cp, sdn, cdn); output q; input cp; input d; input sdn; input cdn; reg q; always @(posedge cp or negedge sdn or negedge cdn) begin if (~sdn) q <= 1; else if (~cdn) q <= 0; else q <= d; end specify if (sdn && cdn) (posedge cp => (q +: d)) = (1, 1); (negedge cdn => (q +: 1'b0)) = (1, 1); (negedge sdn => (q -: 1'b1)) = (1, 1); endspecify endmodule module test; reg d, clk, set, clr; dff dut(q, d, clk, ~set, ~clr); initial begin d=0; clk=0; set=0; clr=0; $monitor($time,, "d=%b, clk=%b, set=%b, clr=%b, q=%b", d, clk, set, clr, q); $sdf_annotate("ivltests/sdf6.sdf"); #10 d = 1; #10 set = 1; #10 set = 0; #10 clr = 1; #10 clr = 0; #10 clk = 1; #10 d = 0; end endmodule iverilog-12_0/ivtest/ivltests/sdf7.sdf000066400000000000000000000007051435245347300201050ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Mon Feb 9 17:54:11 2009") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL // C++ style comment (CELLTYPE "XOR20") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Q () (3.0:3.0:3.0)) (IOPATH B Q () (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf7.v000066400000000000000000000010761435245347300176000ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf7.sdf"); #10 ; a = 1; b = 1; #10 ; b = 0; #10 ; b = 1; #10 ; a = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf8.sdf000066400000000000000000000007241435245347300201070ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Tue Mar 30 13:04:55 PDT 2010") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00) (TIMESCALE 1ns) (CELL (CELLTYPE "XOR20") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH A Q (2.0) (3.0)) (IOPATH B Q () ()) ) ) ) (CELL (CELLTYPE "TIE_HIGH") (INSTANCE src) ) ) iverilog-12_0/ivtest/ivltests/sdf8.v000066400000000000000000000011461435245347300175770ustar00rootroot00000000000000`timescale 1ns / 1ps `celldefine // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine `celldefine module TIE_HIGH (output Q); buf(Q, 1'b1); endmodule `endcelldefine module tb; reg a; wire b, q; XOR20 dut(.A(a), .B(b), .Q(q)); TIE_HIGH src(.Q(b)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf8.sdf"); #10 ; a = 1; #10 ; a = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdf_del.sdf000066400000000000000000000004601435245347300206400ustar00rootroot00000000000000(DELAYFILE (SDFVERSION "3.0") (DESIGN "test") (VOLTAGE 3.70:3.30:3.00) (PROCESS "fast:typ:slow") (TEMPERATURE 25.00:55.00:100.00) (TIMESCALE 1ns) (CELL (CELLTYPE "my_buf") (INSTANCE dut) (DELAY (ABSOLUTE (IOPATH a z (1.0:2.0:3.0) (2.0:3.0:4.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf_del_max.v000066400000000000000000000013611435245347300211770ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg a, pass; wire z; time edge_time; always @(z) begin if ((z === 0) && (($time - edge_time) != 4)) begin $display("Falling took %d, expected 4", $time - edge_time); pass = 1'b0; end if ((z === 1) && (($time - edge_time) != 3)) begin $display("Rising took %d, expected 3", $time - edge_time); pass = 1'b0; end end initial begin pass = 1'b1; $sdf_annotate("ivltests/sdf_del.sdf", top); #10; edge_time = $time; a = 1'b0; #10; edge_time = $time; a = 1'b1; #10 if (pass) $display("PASSED"); end my_buf dut(z, a); endmodule module my_buf (output z, input a); buf (z, a); specify (a => z) = (0, 0); endspecify endmodule iverilog-12_0/ivtest/ivltests/sdf_del_min.v000066400000000000000000000013611435245347300211750ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg a, pass; wire z; time edge_time; always @(z) begin if ((z === 0) && (($time - edge_time) != 2)) begin $display("Falling took %d, expected 2", $time - edge_time); pass = 1'b0; end if ((z === 1) && (($time - edge_time) != 1)) begin $display("Rising took %d, expected 1", $time - edge_time); pass = 1'b0; end end initial begin pass = 1'b1; $sdf_annotate("ivltests/sdf_del.sdf", top); #10; edge_time = $time; a = 1'b0; #10; edge_time = $time; a = 1'b1; #10 if (pass) $display("PASSED"); end my_buf dut(z, a); endmodule module my_buf (output z, input a); buf (z, a); specify (a => z) = (0, 0); endspecify endmodule iverilog-12_0/ivtest/ivltests/sdf_del_typ.v000066400000000000000000000013611435245347300212260ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg a, pass; wire z; time edge_time; always @(z) begin if ((z === 0) && (($time - edge_time) != 3)) begin $display("Falling took %d, expected 3", $time - edge_time); pass = 1'b0; end if ((z === 1) && (($time - edge_time) != 2)) begin $display("Rising took %d, expected 2", $time - edge_time); pass = 1'b0; end end initial begin pass = 1'b1; $sdf_annotate("ivltests/sdf_del.sdf", top); #10; edge_time = $time; a = 1'b0; #10; edge_time = $time; a = 1'b1; #10 if (pass) $display("PASSED"); end my_buf dut(z, a); endmodule module my_buf (output z, input a); buf (z, a); specify (a => z) = (0, 0); endspecify endmodule iverilog-12_0/ivtest/ivltests/sdf_esc_id.sdf000066400000000000000000000007131435245347300213230ustar00rootroot00000000000000 /* C-style comments. */ (DELAYFILE (SDFVERSION "OVI 2.1") (DESIGN "xor_rtl") (DATE "Sun Apr 1 11:57:01 2007") (VENDOR "Icarus Test") (PROGRAM "Hand Coded") (VERSION "0.0") (DIVIDER /) (VOLTAGE 3.30:3.30:3.30) (PROCESS "nom_pvt") (TEMPERATURE 25.00:25.00:25.00) (TIMESCALE 1ns) (CELL (CELLTYPE "XOR20") (INSTANCE \&dut\[0\]) (DELAY (ABSOLUTE (IOPATH A Q (3.0:3.0:3.0) (3.0:3.0:3.0)) (IOPATH B Q (3.0:3.0:3.0) (3.0:3.0:3.0)) ) ) ) ) iverilog-12_0/ivtest/ivltests/sdf_esc_id.v000066400000000000000000000010271435245347300210130ustar00rootroot00000000000000`timescale 1ns / 1ps `celldefine // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 \&dut[0] (.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $sdf_annotate("ivltests/sdf_esc_id.sdf"); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/ivltests/sdw_always1.v000066400000000000000000000036551435245347300212000ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate always block instantiation. // // D: Test validate others versions of always block // D: including posedge, negedge. // // module main (); reg working; reg clock ; initial // Used to generate timing of events begin working = 0; clock = 0; #4 ; working = 0; #1 ; clock = 1; // 1ns between setting working and clock edge. #4 ; working = 0; #1 ; clock = 0; // 1ns between setting working and clock edge. #5 ; end always #2 working = 1 ; initial // This is the validation block begin # 3; // Check #2 always at 3ns if(!working) begin $display("FAILED - delayed always\n"); $finish ; end # 3; // Check posedge at 6 ns if(!working) begin $display("FAILED - posedge always\n"); $finish ; end # 7; // Check negedge at 11ns if(!working) begin $display("FAILED - posedge always\n"); $finish ; end $display("PASSED\n"); $finish; end always @ (posedge clock) working = 1; always @ (negedge clock) working = 1; endmodule iverilog-12_0/ivtest/ivltests/sdw_always2.v000066400000000000000000000057341435245347300212010ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Validate always with OR, posedge constructs. // // D: New test used to validate always @(value), and // D: always @(val1 or val2), and always @(posedge val1 or negedge val2) // D: statements. // // module main (); reg working; reg val1, val2, val3, val4, val5; reg clock ; reg test_var; initial // Used to generate timing of events begin val2 = 0; val3 = 0; val4 = 1; # 1; test_var = 1; # 1; val1 = 1; // Cause a change in val1 -> test_var to 0. # 2 ; // 4ns test_var = 1; # 1 ; // 5ns val2 = 1; // Cause posedge on val2 -> test_var to 0 # 2; // 7ns test_var = 1; # 1; // 8ns val4 = 0; // Cause negedge on val4 -> test_var to 0 # 2; // 10ns test_var = 1; # 1; // 11 ns val3 = 1; // Cause val3 change for always @(a or b) # 2; // 13 ns test_var = 1; # 1; // 14 ns val5 = 1; // Cause val5 cahnge for always @(a or b) # 2; // 16 ns end always @(val1) // Val1 changing clears test_var test_var = 0; always @(posedge val2 or negedge val4) test_var = 0; always @(val3 or val5) test_var = 0; initial // This is the validation block begin # 3; // 3 ns Check always @(val) if(test_var) begin $display("FAILED - always @(val) wrong \n"); $finish ; end # 3; // 6 ns Check posedge of always @(posedge val or negedge) if(test_var) begin $display("FAILED - posedge of always @(posedge or negedge) wrong \n"); $finish ; end # 3; // 9 ns Check negedge of always @(posedge val or negedge) if(test_var) begin $display("FAILED - negedge of always @(posedge or negedge) wrong \n"); $finish ; end # 3; // 12 ns Check a of always @(a or b) if(test_var) begin $display("FAILED - a of always @(a or b) wrong \n"); $finish ; end # 3; // 15 ns Check b of always @(a or b) if(test_var) begin $display("FAILED - b of always @(a or b) wrong \n"); $finish ; end $display("PASSED\n"); $finish; end always @ (posedge clock) working = 1; always @ (negedge clock) working = 1; endmodule iverilog-12_0/ivtest/ivltests/sdw_always3.v000066400000000000000000000061611435245347300211750ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - always block with @(value) and (posedge OR negedge) // // D: New test used to validate always @(value), and // D: always @(val1 or val2), and always @(posedge val1 or negedge val2) // D: statements. // // module main (); reg working; reg reset; reg clock ; reg test_var; initial // Used to generate timing of events begin clock = 0; reset = 0; // Nothing sent yet... #5 ; $display("time=%d, c=%b, r=%b, reg=%b",$time,clock,reset,test_var); reset = 1; // 5 ns #5 ; $display("time=%d, c=%b, r=%b, reg=%b",$time,clock,reset,test_var); reset = 0; // 10ns #5 ; $display("time=%d, c=%b, r=%b, reg=%b",$time,clock,reset,test_var); clock = 1; // 15 ns #5 ; $display("time=%d, c=%b, r=%b, reg=%b",$time,clock,reset,test_var); clock = 0; // 20 ns #5 ; // 25 ns $display("time=%d, c=%b, r=%b, reg=%b",$time,clock,reset,test_var); end // // This is the statement being verified... // // This LOOKS like a race between the posedge and the reset value // but is a standard method for reseting f/f's. // always @(posedge clock or posedge reset) if(reset) test_var = 0; else test_var = ~test_var; initial // This is the validation block begin # 3; // 3 ns Check always @(val) if(test_var != 1'bx) begin $display("FAILED - initial condition of reg variable not x\n"); $finish ; end # 5; // 8 ns Check posedge of always @(posedge val or negedge) if(test_var == 1'bx) begin $display("FAILED - Reset didn't reset var \n"); $finish ; end if(test_var == 1'b1) begin $display("FAILED - Reset set it to 1?? \n"); $finish ; end # 5; // 12 ns if(test_var == 1'bx) begin $display("FAILED - Reset didn't reset var \n"); $finish ; end if(test_var == 1'b1) begin $display("FAILED - Reset set it to 1?? \n"); $finish ; end # 5; // 17 ns - have received the clock by now if(test_var == 1'bx) begin $display("FAILED - The clock caused an x??\n"); $finish ; end if(test_var == 1'b0) begin $display("FAILED - The clock didn't have any effect?? \n"); $finish ; end # 30; $display("PASSED\n"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/sdw_array.v000066400000000000000000000054471435245347300207360ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Memory array instantiation, validation // // D: First do the declaration, and assignment of bit wide arrays // D: and 16 bit wide 4 deep arrays. Then assign values and validate // D: the assignment worked. module main(); reg mem_1 [1:0]; // Define 2 locations, each 1 bit in depth reg [15:0] mem_2 [3:0]; // Define a 16 bit wide array - 4 in depth reg [15:0] work16; reg work1; initial // Excitation block begin mem_1 [0] = 0; // Do the initial assignment of values mem_1 [1] = 1; mem_2 [0] = 16'h0; mem_2 [1] = 16'h1; mem_2 [2] = 16'h2; mem_2 [3] = 16'h3; #5 ; mem_1 [1] = mem_1 [0] ; // use the mem array on the rhs mem_2 [3] = mem_2 [0] ; #5; end initial // Validation block begin #1 ; // Validate initialization work1 = mem_1[0]; if(work1 != 0) begin $display("FAILED - mem_1 [0] init failed\n"); $finish ; end work1 = mem_1[1]; if(work1 != 1) begin $display("FAILED - mem_1 [1] init failed\n"); $finish ; end work16 = mem_2 [0]; if(work16 != 16'h0) begin $display("FAILED - mem_2 [0] init failed\n"); $finish ; end work16 = mem_2 [1]; if(work16 != 16'h1) begin $display("FAILED - mem_2 [1] init failed\n"); $finish ; end work16 = mem_2 [2]; if(work16 != 16'h2) begin $display("FAILED - mem_2 [2] init failed\n"); $finish ; end work16 = mem_2 [3]; if(work16 != 16'h3) begin $display("FAILED - mem_2 [3] init failed\n"); $finish ; end #5 ; work1 = mem_1[1]; if(work1 != 0) begin $display("FAILED - mem_1 [1] rhs assignment \n"); $finish ; end work16 = mem_2 [3]; if(work16 != 16'h0) begin $display("FAILED - mem_2 [3] rhs assignment\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_assign.v000066400000000000000000000033001435245347300210660ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Validation of assign construct // // D: Create a 32 bit vector and assign succesive values to // D: the Right hand side expression. Verify the result is // D: correct. // module main (); wire [31:0] result; reg [31:0] a,b ; assign result = a | b; initial // Excitation block begin a = 0; b = 0; # 5; a = 32'haaaaaaaa ; # 5; b = 32'h55555555 ; # 5 ; end initial // Validation block begin # 1; if(result != 32'h0) begin $display("FAILED - result not initialized\n"); $finish ; end # 5; if(result != 32'haaaaaaaa) begin $display("FAILED - result not updated\n"); $finish ; end # 5; if(result != 32'hffffffff) begin $display("FAILED - result not updated\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_dsbl.v000066400000000000000000000025071435245347300205360ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - validate named blocks/disable stmt // // D: This code verifies both named blocks and the disable statement // D: It is intended to be self checking. // module main (); reg working; reg timer; initial begin:my_block working = 1; #5; working = 1; #5; working = 1; #5; working = 0; #5; end initial begin #15; disable my_block; end initial begin #20; if(!working) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_force.v000066400000000000000000000026301435245347300207050ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Force stmt validation // // D: This code verifies the force statement // D: It is intended to be self checking. // module main (); reg working; reg timer; initial begin timer = 1; # 5; timer = 0; # 5 ; timer = 1; # 5 ; end initial begin working = 1; #2 ; // Validate that force occurs force timer = 0; if( timer == 1) working = 0; #10 ; // Validate that force stays in effect if( timer == 1) working = 0; end initial begin #20; if(!working) $display("FAILED\n"); else $display("PASSED\n"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_function1.v000066400000000000000000000024731435245347300215220ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Initial Function testing // // D: Instantiate a simple module that takes 1 input and doubles it. // module main (); reg [3:0] global_var; reg [3:0] result; function [3:0] my_func ; input [3:0] a; begin my_func = a + a; end endfunction initial begin global_var = 2; result = my_func(global_var); if(result !== 4) begin $display("FAILED - function didn't function!\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_function2.v000066400000000000000000000027101435245347300215150ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Function scope handling // // D: Validate scope handling of variables // module main (); reg [3:0] global_reg; reg [3:0] result; function [3:0] my_func ; input [3:0] a; reg [3:0] global_reg; begin global_reg = a + a; my_func = a + a; end endfunction initial begin global_reg = 2; result = my_func(global_reg); if(result != 4) begin $display("FAILED - function didn't function!\n"); $finish ; end if(global_reg != 2) begin $display("FAILED - function scope problem!\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_function3.v000066400000000000000000000030661435245347300215230ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: function calling function validated // // D: Instantiate a 2 functions, with the 2nd calling // D: the first. Validate the results are correct. // module main (); reg [3:0] global_reg; reg [3:0] result; // Instantiate the function to be called function [3:0] my_func_2; input [3:0] a; begin my_func_2 = a; end endfunction // This is the calling function function [3:0] my_func_1 ; input [3:0] a; begin my_func_1 = my_func_2(a) + my_func_2(a); // So call it twice! end endfunction initial begin global_reg = 2; result = my_func_1(global_reg); if(result != 4) begin $display("FAILED - function didn't function!\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_function4.v000066400000000000000000000025211435245347300215170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Function with if clause // // D: // module main (); reg [3:0] global_var; reg [3:0] result; // Interesting because 2 * 0 is 0 ;-) function [3:0] my_func ; input [3:0] a; begin if(a == 4'b0) my_func = 4'b0; else my_func = a + a; end endfunction initial begin global_var = 2; result = my_func(global_var); if(result != 4) begin $display("FAILED - function didn't function!\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_function5.v000066400000000000000000000025321435245347300215220ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Function with case // // D: // module main (); reg [3:0] global_var; reg [3:0] result; // Interesting because 2 * 0 is 0 ;-) function [3:0] my_func ; input [3:0] a; begin case(a) 4'b000: my_func = 4'b0; default: my_func = a + a; endcase end endfunction initial begin global_var = 2; result = my_func(global_var); if(result != 4) begin $display("FAILED - function didn't function!\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_instmod1.v000066400000000000000000000056231435245347300213520ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW: Instantiation of Modules: // // D: Instantiate two versions of a module containing a single // D: resetable f/f. Reset both - then feed 1 module with a clock // D: and validate that the output toggles. Feed the 2nd module // D: with a clock and validate that the 2nd output toggles. // // module test_mod (reset,clka,out); input reset; input clka; output out; reg out; always @(posedge clka or posedge reset) if(reset) out = 0; else begin out = ~out; $display("saw a clk at %d, out is %b\n",$time,out); end endmodule module main(); reg reset,clk_0,clk_1; wire out_0,out_1; test_mod module_1 (reset,clk_0,out_0); test_mod module_2 (reset,clk_1,out_1); initial begin clk_0 = 0; clk_1 = 0; #1 reset = 1; # 2; $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); // Validate that both out_0 and out_1 are reset if(out_0) begin $display("FAILED - out_0 not reset\n"); $finish ; end if(out_1) begin $display("FAILED - out_1 not reset\n"); $finish ; end reset = 0; $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); # 2; clk_0 = 1; # 2; // Wait so we don't worry about races. $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); if(!out_0) begin $display("FAILED - out_0 didn't set on clk_0\n"); $finish ; end if(out_1) begin $display("FAILED - out_1 set on wrong clk!\n"); $finish ; end clk_1 = 1; # 2; // Wait so we don't worry about races. $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); if(!out_1) begin $display("FAILED - out_1 didn't set on clk_1\n"); $finish ; end if(!out_0) begin $display("FAILED - out_0 changed due to clk_0\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_instmod2.v000066400000000000000000000053231435245347300213500ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW: Module instantiation with non-ordered port assignment // // D: Same as sdw_inst1 except using .net(net) port convention. // module test_mod (reset,clka,out); input reset; input clka; output out; reg out; always @(posedge clka or posedge reset) if(reset) out = 0; else out = ~out; endmodule module main(); reg reset,clk_0,clk_1; wire out_0,out_1; test_mod module_1 (.reset(reset),.clka(clk_0),.out(out_0)); test_mod module_2 (.reset(reset),.clka(clk_1),.out(out_1)); initial begin clk_0 = 0; clk_1 = 0; #1 reset = 1; # 2; $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); // Validate that both out_0 and out_1 are reset if(out_0) begin $display("FAILED - out_0 not reset\n"); $finish ; end if(out_1) begin $display("FAILED - out_1 not reset\n"); $finish ; end reset = 0; $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); # 2; clk_0 = 1; # 2; // Wait so we don't worry about races. $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); if(!out_0) begin $display("FAILED - out_0 didn't set on clk_0\n"); $finish ; end if(out_1) begin $display("FAILED - out_1 set on wrong clk!\n"); $finish ; end clk_1 = 1; # 2; // Wait so we don't worry about races. $display("time %d r=%b, c0=%b, c1=%b, o0=%b,o1=%b\n",$time,reset,clk_0, clk_1,out_0,out_1); if(!out_1) begin $display("FAILED - out_1 didn't set on clk_1\n"); $finish ; end if(!out_0) begin $display("FAILED - out_0 changed due to clk_0\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_int.v000066400000000000000000000043151435245347300204030ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Int type declaration/validation // // D: Assign a 16 bit vector to an int and observe the 0 extension. // D: Assign a 32 bit vector to an int and observer same value. // D: Add -1 + 1. Add 0 and -1...and observer correct values. module main(); reg [15:0] a; reg [31:0] b; integer result; integer int_a; integer int_b; initial // Excitation block begin a = 0; b = 0; result = 0; # 5; // Assign a shorter value a = 16'h1234; // should see 0 extension in result result = a; # 5; // Assign a 32 bit vector b = 32'h12345678 ; result = b; # 5; // Validate sum basic integer arithmetic int_a = -1 ; // pun intended! int_b = 1; result = int_a + int_b; # 5; int_a = 0; int_b = -1; result = int_a + int_b; end initial // Validation block begin #1 ; #5 ; if(result != 32'h00001234) begin $display("FAILED - Bit extend wrong\n"); $finish ; end #5 ; if(result != 32'h12345678) begin $display("FAILED - 32 bit assign wrong\n"); $finish ; end #5 ; if(result != 32'h00000000) begin $display("FAILED - -1 + 1 = %h\n",result); $finish ; end #5 ; if(result != 32'hffffffff) begin $display("FAILED - 0 - 1 = %h\n",result); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_lvalconcat.v000066400000000000000000000033541435245347300217410ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate that an lvalue concat can receive an assignment. // // D: Validate that an lvalue can be a concatenation. // module main (); reg a; reg b; reg working; initial begin working = 1; {a,b} = 2'b00 ; if( (a != 0) & (b != 0)) begin $display("FAILED {a,b} Expected 2'b00 - received %b%b",a,b); working = 0; end {a,b} = 2'b01 ; if( (a != 0) & (b != 1)) begin $display("FAILED {a,b} Expected 2'b01 - received %b%b",a,b); working = 0; end {a,b} = 2'b10 ; if( (a != 1) & (b != 0)) begin $display("FAILED {a,b} Expected 2'b10 - received %b%b",a,b); working = 0; end {a,b} = 2'b11 ; if( (a != 1) & (b != 1)) begin $display("FAILED {a,b} Expected 2'b11 - received %b%b",a,b); working = 0; end if(working) $display("PASSED\n"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_lvalconcat2.v000066400000000000000000000034121435245347300220160ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate a lval concat in a continuous assignment // // D: Validate that an lvalue can be a concatenation. // module main (); wire a, b; reg [1:0] c; reg working; assign {a,b} = c; initial begin working = 1; c = 2'b00 ; #1 if( (a !== 0) & (b !== 0)) begin $display("FAILED - {a,b} Expected 2'b00 - received %b%b",a,b); working = 0; end c = 2'b01 ; #1 if( (a !== 0) & (b !== 1)) begin $display("FAILED {a,b} Expected 2'b01 - received %b%b",a,b); working = 0; end c = 2'b10 ; #1 if( (a !== 1) & (b !== 0)) begin $display("FAILED {a,b} Expected 2'b10 - received %b%b",a,b); working = 0; end c = 2'b11 ; #1 if( (a !== 1) & (b !== 1)) begin $display("FAILED {a,b} Expected 2'b11 - received %b%b",a,b); working = 0; end #1 if(working) $display("PASSED\n"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_param1.v000066400000000000000000000030401435245347300207640ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Simple parameter declaration // // D: Declare a parameter value, then assign it to a variable. // D: Check the value of the variable. // module main(); parameter VAL_1 = 16'h0001; parameter VAL_2 = 16'h5432; reg [15:0] test_var; initial // Excitation block begin test_var = VAL_1 ; #5 ; test_var = VAL_2 ; #5 ; end initial // Validation block begin #1 ; if(test_var != 16'h0001) begin $display("FAILED - param 1st assign didn't work\n"); $finish ; end #5 ; if(test_var != 16'h5432) begin $display("FAILED - param 2nd assign didn't work\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_param2.v000066400000000000000000000026011435245347300207670ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Comma separated parameter def used as a width subscript // // // D: This validates that parameters can be used as literals // D: in the width subscript. // module main(); parameter VAL_1 = 5, VAL_2 = 0; reg [VAL_1: VAL_2] temp_var; initial // Excitation block begin temp_var = 6'h11; #5 ; end initial // Validation block begin #1 ; if(temp_var != 6'h11) begin $display("FAILED - parameter assignment didn't work\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_release.v000066400000000000000000000027721435245347300212360ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate release statement // // D: This code verifies the release statement. // D: It depends on the force statement being // D: functional! (Kinda have to - no way to // D: release if you haven't forced the issue. // D: It is intended to be self checking. // // By: Steve Wilson // module main (); reg working; reg timer; initial working = 1; initial begin #5 ; force working = 0; end initial begin #10; release working; // This releases the force #2 ; working = 1; // This allows a new value onto the reg. end initial begin #20; if(!working) $display("FAILED\n"); else $display("PASSED\n"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_stmt002.v000066400000000000000000000102341435245347300210170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Rewrite of stmt002_bassign.v from vbs test suite. // module main; reg [0:7] var1, var2; // Note the obtuse bit ordering. reg [3:0] var3; // A more sane ordering on a nibble boundary... reg var4; // Single bit. reg [2:9] var5; // Use a non-alligned, reversed bit - still 8 bits reg error; initial begin // First verify that all the defined variables are x's. error = 0; if(var1 !== 8'hxx) begin $display("FAILED - sdw_stmt002 - var1 not 8'hxx"); error = 1; end if(var2 !== 8'hxx) begin $display("FAILED - sdw_stmt002 -var2 not 8'hxx"); error = 1; end if(var3 !== 4'bx_xxx) begin $display("FAILED - sdw_stmt002 -var3 not 4'hx"); error = 1; end if(var4 !== 1'bx) begin $display("FAILED - sdw_stmt002 -var4 not 1'bx"); error = 1; end if(var5 !== 8'hxx) begin $display("FAILED - sdw_stmt002 -var5 not 8'hxx"); error = 1; end var1 = 8'b1001_0010; // Do some binary bits var2 = 255; // Fill it with decimal version of ff var3 = 4'hf; // hex var4 = 0; var5 = 8'h99; // Still 8 bits if(var1 != 8'h92) begin $display("FAILED - sdw_stmt002 - var1 not 8'h96"); error = 1; end if(var2 != 8'hff) begin $display("FAILED - sdw_stmt002 -var2 not 8'hff"); error = 1; end if(var3 != 4'b1111) begin $display("FAILED - sdw_stmt002 -var3 not 4'hf"); error = 1; end if(var4 != 1'b0) begin $display("FAILED - sdw_stmt002 -var4 not 1'b0"); error = 1; end if(var5 != 8'h99) begin $display("FAILED - sdw_stmt002 -var5 not 8'h99"); error = 1; end // Next - assign sub-portion of vector var1 [3:6] = var3; if(var1 != 8'h9e) begin $display("FAILED - sdw_stmt002 - subfield assign failed"); error = 1; end var3 = 4'o11; // Lets try octal now var4 = 1'b1; // And set that bit to 1, it WAS 0 var5 = 8'h66; // Invert it if(var3 != 4'b1001) begin $display("FAILED - sdw_stmt002 -var3 octal assign"); error = 1; end if(var4 != 1'b1) begin $display("FAILED - sdw_stmt002 -var4 not 1'b1"); error = 1; end if(var5 != 8'h66) begin $display("FAILED - sdw_stmt002 -var5 not 8'h66"); error = 1; end // 9e, 9 var3 = var1[4:7]; // Should be an 4'he var1[0:3] = var3[3:2]; // Now should give 8'hce if(var1 != 8'h3e) begin $display("FAILED - sdw_stmt002 - subfield assign(1) w/ 0 extension"); error = 1; end if(var3 != 4'b1110) begin $display("FAILED - sdw_stmt002 -subfield assign(2)"); error = 1; end var3 = var5; // 4 bit from 8 bit(4'h6) var5[5] = var4; // Set var5 to 8'h76 if(var3 != 4'h6) begin $display("FAILED - sdw_stmt002 - 4bit from 8 bit assign"); error = 1; end if(var5 != 8'h76) begin $display("FAILED - sdw_stmt002 - single sub-bit assign "); error = 1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sdw_task1.v000066400000000000000000000024261435245347300206350ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Verify task basic function with no values passed. // // D: Task validation. Notice that there are no values passed to this task. // // module main(); reg [3:0] global_reg; task dec_glob; begin global_reg = global_reg -1; end endtask initial begin global_reg = 2; dec_glob; if(global_reg != 1) begin $display("FAILED - task didn't modify global_reg\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sdw_task2.v000066400000000000000000000024411435245347300206330ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Verify task with I/O. // // D: Pass a task two values and modify a global variable. // module main(); reg [3:0] global_reg; task inc_glob; input [3:0] in_1; input [3:0] in_2; begin global_reg = in_1 + in_2 ; end endtask initial begin global_reg = 2; inc_glob(global_reg,global_reg); if(global_reg != 4) begin $display("FAILED - task didn't modify global_reg\n"); $finish ; end $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/sel_rval_bit_ob.v000066400000000000000000000305211435245347300220570ustar00rootroot00000000000000`begin_keywords "1364-2005" // Module to test the messages/results for out of bound R-value constant // bit selects. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg big_param; reg bit; integer idx; parameter pvar0 = 0; parameter pvar1 = 1; parameter pvar2 = -1; parameter pvar3 = 4'b0001; parameter [4:1] pvar4 = 4'b0001; parameter [1:4] pvar5 = 4'b0001; reg [4:1] rvar = 4'b0010; reg [1:4] rvar2 = 4'b0010; reg [4:1] ravar [2:1]; reg [1:4] ravar2 [2:1]; wire [4:1] wvar = 4'b0100; wire [1:4] wvar2 = 4'b0100; wire [4:1] wavar [2:1]; wire [1:4] wavar2 [2:1]; assign wavar[1] = 4'b1001; assign wavar[2] = 4'b1010; assign wavar2[1] = 4'b1001; assign wavar2[2] = 4'b1010; initial begin pass = 1'b1; ravar[1] = 4'b1101; ravar[2] = 4'b1110; ravar2[1] = 4'b1101; ravar2[2] = 4'b1110; #1; // Icarus supports an unlimited size for unsized parameters. The // following checks the 33rd bit to see if it is 1'bx. If so we // assume that the simulator only support 32 bit, otherwise we // modify our after check for unsized parameters to work (pass) // with a larger constant. big_param = 1'b1; idx = 32; if (pvar0[idx] === 1'bx) big_param = 1'b0; // Check a parameter with default size equal to 0. bit = pvar0[31]; // At end if (bit !== 1'b0) begin $display("Failed at end bit select of a parameter (0), got %b", bit); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar0[32]; // May be after if (bit !== (big_param ? 1'b0: 1'bx)) begin $display("Failed after bit select of a parameter (0), got %b", bit); pass = 1'b0; end bit = pvar0[-1]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (0), got %b", bit); pass = 1'b0; end bit = pvar0[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (0), got %b", bit); pass = 1'b0; end bit = pvar0[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (0), got %b", bit); pass = 1'b0; end `endif // Check a parameter with default size equal to 1. bit = pvar1[31]; // At end if (bit !== 1'b0) begin $display("Failed at end bit select of a parameter (1), got %b", bit); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar1[32]; // May be after if (bit !== (big_param ? 1'b0: 1'bx)) begin $display("Failed after bit select of a parameter (1), got %b", bit); pass = 1'b0; end bit = pvar1[-1]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (1), got %b", bit); pass = 1'b0; end bit = pvar1[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (1), got %b", bit); pass = 1'b0; end bit = pvar1[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (1), got %b", bit); pass = 1'b0; end `endif // Check a parameter with default size equal to -1. bit = pvar2[31]; // At end if (bit !== 1'b1) begin $display("Failed at end bit select of a parameter (-1), got %b", bit); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar2[32]; // May be after if (bit !== (big_param ? 1'b1: 1'bx)) begin $display("Failed after bit select of a parameter (-1), got %b", bit); pass = 1'b0; end bit = pvar2[-1]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (-1), got %b", bit); pass = 1'b0; end bit = pvar2[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (-1), got %b", bit); pass = 1'b0; end bit = pvar2[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (-1), got %b", bit); pass = 1'b0; end `endif // Check a parameter with size four from the value. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar3[4]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a parameter (3), got %b", bit); pass = 1'b0; end bit = pvar3[-1]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (3), got %b", bit); pass = 1'b0; end bit = pvar3[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (3), got %b", bit); pass = 1'b0; end bit = pvar3[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (3), got %b", bit); pass = 1'b0; end `endif // Check a parameter with size four from the range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar4[5]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a parameter (4), got %b", bit); pass = 1'b0; end bit = pvar4[0]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (4), got %b", bit); pass = 1'b0; end bit = pvar4[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (4), got %b", bit); pass = 1'b0; end bit = pvar4[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (4), got %b", bit); pass = 1'b0; end `endif // Check a parameter with size four from the range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = pvar5[0]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a parameter (5), got %b", bit); pass = 1'b0; end bit = pvar5[5]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a parameter (5), got %b", bit); pass = 1'b0; end bit = pvar5[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a parameter (5), got %b", bit); pass = 1'b0; end bit = pvar5[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a parameter (5), got %b", bit); pass = 1'b0; end `endif // Check a register with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = rvar[5]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a register, got %b", bit); pass = 1'b0; end bit = rvar[0]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a register, got %b", bit); pass = 1'b0; end bit = rvar[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a register, got %b", bit); pass = 1'b0; end bit = rvar[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a register, got %b", bit); pass = 1'b0; end `endif // Check a register with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = rvar2[0]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a register (2), got %b", bit); pass = 1'b0; end bit = rvar2[5]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a register (2), got %b", bit); pass = 1'b0; end bit = rvar2[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a register (2), got %b", bit); pass = 1'b0; end bit = rvar2[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a register (2), got %b", bit); pass = 1'b0; end `endif // Check an array word with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = ravar[1][5]; // After if (bit !== 1'bx) begin $display("Failed after bit select of an array word, got %b", bit); pass = 1'b0; end bit = ravar[1][0]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of an array word, got %b", bit); pass = 1'b0; end bit = ravar[1][1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of an array word, got %b", bit); pass = 1'b0; end bit = ravar[1][1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of an array word, got %b", bit); pass = 1'b0; end `endif // Check an array word with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = ravar2[1][0]; // After if (bit !== 1'bx) begin $display("Failed after bit select of an array word (2), got %b", bit); pass = 1'b0; end bit = ravar2[1][5]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of an array word (2), got %b", bit); pass = 1'b0; end bit = ravar2[1][1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of an array word (2), got %b", bit); pass = 1'b0; end bit = ravar2[1][1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of an array word (2), got %b", bit); pass = 1'b0; end `endif // Check a wire with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = wvar[5]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a wire, got %b", bit); pass = 1'b0; end bit = wvar[0]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a wire, got %b", bit); pass = 1'b0; end bit = wvar[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a wire, got %b", bit); pass = 1'b0; end bit = wvar[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a wire, got %b", bit); pass = 1'b0; end `endif // Check a wire with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = wvar2[0]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a wire (2), got %b", bit); pass = 1'b0; end bit = wvar2[5]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a wire (2), got %b", bit); pass = 1'b0; end bit = wvar2[1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a wire (2), got %b", bit); pass = 1'b0; end bit = wvar2[1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a wire (2), got %b", bit); pass = 1'b0; end `endif // Check a wire array word with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = wavar[1][5]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a wire array word, got %b", bit); pass = 1'b0; end bit = wavar[1][0]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a wire array word, got %b", bit); pass = 1'b0; end bit = wavar[1][1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a wire array word, got %b", bit); pass = 1'b0; end bit = wavar[1][1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a wire array word, got %b", bit); pass = 1'b0; end `endif // Check a wire array word with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST bit = wavar2[1][0]; // After if (bit !== 1'bx) begin $display("Failed after bit select of a wire array word (2), got %b", bit); pass = 1'b0; end bit = wavar2[1][5]; // Before if (bit !== 1'bx) begin $display("Failed before bit select of a wire array word (2), got %b", bit); pass = 1'b0; end bit = wavar2[1][1'bx]; // Undefined if (bit !== 1'bx) begin $display("Failed undefined bit select of a wire array word (2), got %b", bit); pass = 1'b0; end bit = wavar2[1][1'bz]; // High-Z if (bit !== 1'bx) begin $display("Failed high-Z bit select of a wire array word (2), got %b", bit); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/sel_rval_part_ob.v000066400000000000000000000601011435245347300222440ustar00rootroot00000000000000// Module to test the messages for out of bound R-value part selects. `ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg big_param; reg [1:0] part; integer idx; parameter pvar0 = 0; parameter pvar1 = 1; parameter pvar2 = -1; parameter pvar3 = 4'b0001; parameter [4:1] pvar4 = 4'b0001; parameter [1:4] pvar5 = 4'b0001; reg [4:1] rvar = 4'b1000; reg [1:4] rvar2 = 4'b1000; reg [4:1] ravar [2:1]; reg [1:4] ravar2 [2:1]; wire [4:1] wvar = 4'b1010; wire [1:4] wvar2 = 4'b1010; wire [4:1] wavar [2:1]; wire [1:4] wavar2 [2:1]; assign wavar[1] = 4'b0111; assign wavar[2] = 4'b1110; assign wavar2[1] = 4'b0111; assign wavar2[2] = 4'b1110; initial begin pass = 1'b1; ravar[1] = 4'b0111; ravar[2] = 4'b1110; ravar2[1] = 4'b0111; ravar2[2] = 4'b1110; #1; // Icarus supports an unlimited size for unsized parameters. The // following checks the 33rd bit to see if it is 1'bx. If so we // assume that the simulator only support 32 bit, otherwise we // modify our after check for unsized parameters to work (pass) // with a larger constant. big_param = 1'b1; idx = 32; if (pvar0[idx] === 1'bx) big_param = 1'b0; // Check a parameter with default size equal to 0. part = pvar0[31:30]; // At end if (part !== 2'b00) begin $display("Failed at end part select of a parameter (0), got %b", part); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar0[33:32]; // May be after all if (part !== (big_param ? 2'b00: 2'bxx)) begin $display("Failed after part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[32:31]; // May be partial after if (part !== (big_param ? 2'b00 : 2'bx0)) begin $display("Failed partial after part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[-1:-2]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[0:-1]; // Partial before if (part !== 2'b0x) begin $display("Failed partial before part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (0), got %b", part); pass = 1'b0; end part = pvar0[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (0), got %b", part); pass = 1'b0; end `endif // Check a parameter with default size equal to 1. part = pvar1[31:30]; // At end if (part !== 2'b00) begin $display("Failed at end part select of a parameter (1), got %b", part); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar1[33:32]; // May be after all if (part !== (big_param ? 2'b00: 2'bxx)) begin $display("Failed after part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[32:31]; // May be partial after if (part !== (big_param ? 2'b00 : 2'bx0)) begin $display("Failed partial after part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[-1:-2]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[0:-1]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (1), got %b", part); pass = 1'b0; end part = pvar1[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (1), got %b", part); pass = 1'b0; end `endif // Check a parameter with default size equal to -1. part = pvar2[31:30]; // At end if (part !== 2'b11) begin $display("Failed at end part select of a parameter (2), got %b", part); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar2[33:32]; // May be after all if (part !== (big_param ? 2'b11: 2'bxx)) begin $display("Failed after part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[32:31]; // May be partial after if (part !== (big_param ? 2'b11 : 2'bx1)) begin $display("Failed partial after part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[-1:-2]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[0:-1]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (2), got %b", part); pass = 1'b0; end part = pvar2[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (2), got %b", part); pass = 1'b0; end `endif // Check a parameter with size four from the value. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar3[5:4]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[4:3]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[-1:-2]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[0:-1]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (3), got %b", part); pass = 1'b0; end part = pvar3[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (3), got %b", part); pass = 1'b0; end `endif // Check a parameter with size four from the range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar4[6:5]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[5:4]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[0:-1]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[1:0]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (4), got %b", part); pass = 1'b0; end part = pvar4[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (4), got %b", part); pass = 1'b0; end `endif // Check a parameter with size four from the range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = pvar5[-1:0]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[0:1]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[5:6]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[4:5]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a parameter (5), got %b", part); pass = 1'b0; end part = pvar5[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a parameter (5), got %b", part); pass = 1'b0; end `endif // Check a register with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = rvar[6:5]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a register, got %b", part); pass = 1'b0; end part = rvar[5:4]; // Partial after if (part !== 2'bx1) begin $display("Failed partial after part select of a register, got %b", part); pass = 1'b0; end part = rvar[0:-1]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a register, got %b", part); pass = 1'b0; end part = rvar[1:0]; // Partial before if (part !== 2'b0x) begin $display("Failed partial before part select of a register, got %b", part); pass = 1'b0; end part = rvar[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a register, got %b", part); pass = 1'b0; end part = rvar[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a register, got %b", part); pass = 1'b0; end part = rvar[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a register, got %b", part); pass = 1'b0; end part = rvar[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a register, got %b", part); pass = 1'b0; end `endif // Check a register with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = rvar2[-1:0]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[0:1]; // Partial after if (part !== 2'bx1) begin $display("Failed partial after part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[5:6]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[4:5]; // Partial before if (part !== 2'b0x) begin $display("Failed partial before part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a register (2), got %b", part); pass = 1'b0; end part = rvar2[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a register (2), got %b", part); pass = 1'b0; end `endif // Check an array word with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = ravar[1][6:5]; // After all if (part !== 2'bxx) begin $display("Failed after part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][5:4]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][0:-1]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][1:0]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of an array word, got %b", part); pass = 1'b0; end part = ravar[1][1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of an array word, got %b", part); pass = 1'b0; end `endif // Check an array word with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = ravar2[1][-1:0]; // After all if (part !== 2'bxx) begin $display("Failed after part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][0:1]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][5:6]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][4:5]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of an array word (2), got %b", part); pass = 1'b0; end part = ravar2[1][1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of an array word (2), got %b", part); pass = 1'b0; end `endif // Check a wire with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = wvar[6:5]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a wire, got %b", part); pass = 1'b0; end part = wvar[5:4]; // Partial after if (part !== 2'bx1) begin $display("Failed partial after part select of a wire, got %b", part); pass = 1'b0; end part = wvar[0:-1]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a wire, got %b", part); pass = 1'b0; end part = wvar[1:0]; // Partial before if (part !== 2'b0x) begin $display("Failed partial before part select of a wire, got %b", part); pass = 1'b0; end part = wvar[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a wire, got %b", part); pass = 1'b0; end part = wvar[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a wire, got %b", part); pass = 1'b0; end part = wvar[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a wire, got %b", part); pass = 1'b0; end part = wvar[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a wire, got %b", part); pass = 1'b0; end `endif // Check a wire with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = wvar2[-1:0]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[0:1]; // Partial after if (part !== 2'bx1) begin $display("Failed partial after part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[5:6]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[4:5]; // Partial before if (part !== 2'b0x) begin $display("Failed partial before part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a wire (2), got %b", part); pass = 1'b0; end part = wvar2[1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a wire (2), got %b", part); pass = 1'b0; end `endif // Check a wire array word with range [4:1]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = wavar[1][6:5]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][5:4]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][0:-1]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][1:0]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a wire array word, got %b", part); pass = 1'b0; end part = wavar[1][1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a wire array word, got %b", part); pass = 1'b0; end `endif // Check a wire array word with range [1:4]. `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST part = wavar2[1][-1:0]; // After all if (part !== 2'bxx) begin $display("Failed after part select of a wire array word (2), got %b", part); pass = 1'b0; end part = wavar2[1][0:1]; // Partial after if (part !== 2'bx0) begin $display("Failed partial after part select of a wire array word (2),", " got %b", part); pass = 1'b0; end part = wavar2[1][5:6]; // Before all if (part !== 2'bxx) begin $display("Failed before part select of a wire array word (2), got %b", part); pass = 1'b0; end part = wavar2[1][4:5]; // Partial before if (part !== 2'b1x) begin $display("Failed partial before part select of a wire array word (2),", " got %b", part); pass = 1'b0; end part = wavar2[1][1'bx:1]; // Undefined 1st if (part !== 2'bxx) begin $display("Failed undefined 1st part select of a wire array word (2),", " got %b", part); pass = 1'b0; end part = wavar2[1][1:1'bx]; // Undefined 2nd if (part !== 2'bxx) begin $display("Failed undefined 2nd part select of a wire array word (2),", " got %b", part); pass = 1'b0; end part = wavar2[1][1'bz:1]; // High-Z 1st if (part !== 2'bxx) begin $display("Failed high-Z 1st part select of a wire array word (2), got %b", part); pass = 1'b0; end part = wavar2[1][1:1'bz]; // High-Z 2nd if (part !== 2'bxx) begin $display("Failed high-Z 2nd part select of a wire array word (2), got %b", part); pass = 1'b0; end `endif if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/select.v000066400000000000000000000030621435245347300202110ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the select of a memory word in a continuous assignment. */ module main; reg [1:0] a [3:0]; reg [1:0] s = 0; wire [1:0] b = a[s]; initial begin a[0] = 3; a[1] = 2; a[2] = 1; a[3] = 0; end initial begin #1 if (b !== 3) begin $display("FAILED -- s=%b, b=%b", s, b); $finish; end s = 1; #1 if (b !== 2) begin $display("FAILED -- s=%b, b=%b", s, b); $finish; end s = 2; #1 if (b !== 1) begin $display("FAILED -- s=%b, b=%b", s, b); $finish; end s = 3; #1 if (b !== 0) begin $display("FAILED -- s=%b, b=%b", s, b); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/select2.v000066400000000000000000000031451435245347300202750ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the select of a bit from a vector. */ module main; reg [3:0] a = 4'b0110; reg [1:0] s = 0; wire b = a[s]; initial begin #1 if (b !== 0) begin $display("FAILED -- a=%b, s=%b, b=%b", a, s, b); $finish; end s = 1; #1 if (b !== 1) begin $display("FAILED -- a=%b, s=%b, b=%b", a, s, b); $finish; end s = 2; #1 if (b !== 1) begin $display("FAILED -- a=%b, s=%b, b=%b", a, s, b); $finish; end s = 3; #1 if (b !== 0) begin $display("FAILED -- a=%b, s=%b, b=%b", a, s, b); $finish; end s = 2'bxx; #1 if (b !== 1'bx) begin $display("FAILED -- a=%b, s=%b, b=%b", a, s, b); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/select3.v000066400000000000000000000026421435245347300202770ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the select of a bit from a parameter. */ module test; reg [4:0] a; wire o; RAM dut(o, a[3:0]); defparam test.dut.INIT = 16'h55aa; initial begin for (a = 0 ; a[4] == 0 ; a = a + 1) begin #1 $display("dut[%h] = %b", a, o); end end endmodule // test module RAM (O, A); parameter INIT = 16'h0000; output O; input [3:0] A; reg mem [15:0]; reg [4:0] count; wire [3:0] adr; buf (O, mem[A]); initial begin for (count = 0; count < 16; count = count + 1) mem[count] <= INIT[count]; end endmodule iverilog-12_0/ivtest/ivltests/select4.v000066400000000000000000000006521435245347300202770ustar00rootroot00000000000000/* * part select in continuous assignment. */ `timescale 1ns/1ns module main; reg [3:0] src; wire foo = src[3:1] == 3'b101; integer idx; initial begin for (idx = 0 ; idx < 16 ; idx = idx+1) begin src = idx; #1 if (foo !== (src[3:1] == 3'b101)) begin $display("FAILED -- src=%b, foo=%b", src, foo); $finish; end end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/select5.v000066400000000000000000000021551435245347300203000ustar00rootroot00000000000000/* * This program demonstrates non-constant part selects * applied to a signal value. */ module main; wire [31:0] foo = 32'h76543210; reg [3:0] tmp; reg [3:0] idx; initial begin #1 /* Wait for initial assignments to settle. */ ; if (foo[0 +: 4] !== 4'h0) begin $display("FAILED -- %b !== 0", foo[0 +: 4]); $finish; end if (foo[4 +: 4] !== 4'h1) begin $display("FAILED -- %b !== 1", foo[4 +: 4]); $finish; end if (foo[8 +: 4] !== 4'h2) begin $display("FAILED -- %b !== 2", foo[8 +: 4]); $finish; end if (foo[12+: 4] !== 4'h3) begin $display("FAILED -- %b !== 3", foo[12 +: 4]); $finish; end for (idx = 0 ; idx < 8 ; idx = idx + 1) begin tmp = foo[(idx*4) +: 4]; if (tmp !== idx) begin $display("FAILED -- %b !== %b", idx, tmp); $finish; end end for (idx = 0 ; idx < 8 ; idx = idx + 1) begin tmp = foo[(idx*4+3) -: 4]; if (tmp !== idx) begin $display("FAILED -- %b !== %b", idx, tmp); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/select6.v000066400000000000000000000013331435245347300202760ustar00rootroot00000000000000module main; reg [7:0] mem [0:1]; initial begin mem[0] = 8'ha5; mem[1] = 8'hf0; if (mem[0] !== 8'ha5) begin $display("FAILED"); $finish; end if (mem[1] !== 8'hf0) begin $display("FAILED"); $finish; end if (mem[0][4+:4] !== 5'ha) begin $display("FAILED"); $finish; end if (mem[1][4+:4] !== 5'hf) begin $display("FAILED"); $finish; end mem[0][4 +: 4] <= 4'hc; #1 if (mem[0] !== 8'hc5) begin $display("FAILED"); $finish; end mem[1][4 +: 4] <= 4'h3; #1 if (mem[1] !== 8'h30) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/select7.v000066400000000000000000000013311435245347300202750ustar00rootroot00000000000000module main; reg [7:0] mem [0:1]; initial begin mem[0] = 8'ha5; mem[1] = 8'hf0; if (mem[0] !== 8'ha5) begin $display("FAILED"); $finish; end if (mem[1] !== 8'hf0) begin $display("FAILED"); $finish; end if (mem[0][4+:4] !== 5'ha) begin $display("FAILED"); $finish; end if (mem[1][4+:4] !== 5'hf) begin $display("FAILED"); $finish; end mem[0][4 +: 4] = 4'hc; #1 if (mem[0] !== 8'hc5) begin $display("FAILED"); $finish; end mem[1][4 +: 4] = 4'h3; #1 if (mem[1] !== 8'h30) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/select8.v000066400000000000000000000014021435245347300202750ustar00rootroot00000000000000module main; reg [7:0] mem [0:1]; integer off; initial begin mem[0] = 8'ha5; mem[1] = 8'hf0; off = 4; if (mem[0] !== 8'ha5) begin $display("FAILED"); $finish; end if (mem[1] !== 8'hf0) begin $display("FAILED"); $finish; end if (mem[0][off+:4] !== 5'ha) begin $display("FAILED"); $finish; end if (mem[1][off+:4] !== 5'hf) begin $display("FAILED"); $finish; end mem[0][off +: 4] = 4'hc; #1 if (mem[0] !== 8'hc5) begin $display("FAILED"); $finish; end mem[1][off +: 4] = 4'h3; #1 if (mem[1] !== 8'h30) begin $display("FAILED"); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/select_padding.v000066400000000000000000000023131435245347300216750ustar00rootroot00000000000000module top; reg pass; reg [7:0] in; reg [1:0] res; integer lp; initial begin pass = 1'b1; in = 8'b11100100; lp = 3; // lp[1:0] is being sign extended and that fails when the value mod 4 // is either 2 or 3! A bit/part select is always unsigned unless we use // The $signed function to cast it to signed! res = in[lp[1:0]*2 +: 2]; if (res !== 2'b11) begin $display("Failed expected 2'b11, got %b (%b:%d)", res, in, lp[1:0]*2); pass = 1'b0; end // This should give -2 for the index. res = in[$signed(lp[1:0])*2 +: 2]; if (res !== 2'bxx) begin $display("Failed expected 2'bxx, got %b (%b:%d)", res, in, $signed(lp[1:0])*2); pass = 1'b0; end lp = 6; // The same as above, but not at the start of the signal. res = in[lp[2:1]*2 +: 2]; if (res !== 2'b11) begin $display("Failed expected 2'b11, got %b (%b:%d)", res, in, lp[2:1]*2); pass = 1'b0; end res = in[$signed(lp[2:1])*2 +: 2]; if (res !== 2'bxx) begin $display("Failed expected 2'bxx, got %b (%b:%d)", res, in, $signed(lp[2:1])*2); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf1289.v000066400000000000000000000006651435245347300176740ustar00rootroot00000000000000module test1(); // bad initial begin reg a; for (int i=0;i<1;i++) a=1; end endmodule module test2(); // bad initial begin : block_name for (int i=0;i<1;i++) ; end endmodule module test3(); // bad reg a [1:0]; initial begin : block_name foreach (a[i]) ; end endmodule module test4(); // ok initial begin for (int i=0;i<1;i++) ; end endmodule module stub; initial #100 $display("PASSED"); endmodule // stub iverilog-12_0/ivtest/ivltests/sf_countbits.v000066400000000000000000000035751435245347300214450ustar00rootroot00000000000000module top; reg pass; integer result; reg [3:0] expr; reg bval; initial begin pass = 1'b1; result = $countbits(1'bx, 1'bx); if (result != 1) begin $display("FAILED: for 1'bx/x expected a count of 1, got %d", result); pass = 1'b0; end result = $countbits(2'bxx, 1'bx); if (result != 2) begin $display("FAILED: for 2'bxx/x expected a count of 2, got %d", result); pass = 1'b0; end result = $countbits(2'bxz, 1'bz, 1'bx); if (result != 2) begin $display("FAILED: for 2'bxz/zx expected a count of 2, got %d", result); pass = 1'b0; end result = $countbits(4'b01zx, 1'bz, 1'bx); if (result != 2) begin $display("FAILED: for 4'b01zx/zx expected a count of 2, got %d", result); pass = 1'b0; end result = $countbits(4'b01zx, 1'b0, 1'b1); if (result != 2) begin $display("FAILED: for 4'b01zx/01 expected a count of 2, got %d", result); pass = 1'b0; end bval = 1'b0; expr = 4'b1001; result = $countbits(expr, bval); if (result != 2) begin $display("FAILED: for 4'b1001/0 expected a count of 2, got %d", result); pass = 1'b0; end bval = 1'b1; result = $countbits(expr, bval); if (result != 2) begin $display("FAILED: for 4'b1001/1 expected a count of 2, got %d", result); pass = 1'b0; end result = $countbits(34'bzx00000000000000000000000000000000, 1'bz, 1'bx); if (result != 2) begin $display("FAILED: for 34'zx00000000000000000000000000000000/zx expected a count of 2, got %d", result); pass = 1'b0; end result = $countbits(34'bzxxz000000xz000000xz000000xz000000, 1'bz, 1'bx); if (result != 10) begin $display("FAILED: for 34'zxxz000000xz000000xz000000xz000000/zx expected a count of 10, got %d", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf_countbits_fail.v000066400000000000000000000004531435245347300224300ustar00rootroot00000000000000module top; integer result; initial begin result = $countbits(top); result = $countbits("a string"); result = $countbits(1'bx); result = $countbits("a string", 1'bx); result = $countbits(1'bx, "a string"); result = $countbits(1'bx, 1'bx, "a string"); end endmodule iverilog-12_0/ivtest/ivltests/sf_countones.v000066400000000000000000000026311435245347300214400ustar00rootroot00000000000000module top; reg pass; integer result; reg [3:0] expr; initial begin pass = 1'b1; result = $countones(1'b0); if (result != 0) begin $display("FAILED: for 1'b0 expected a count of 0, got %d", result); pass = 1'b0; end result = $countones(1'b1); if (result != 1) begin $display("FAILED: for 1'b1 expected a count of 1, got %d", result); pass = 1'b0; end result = $countones(2'b01); if (result != 1) begin $display("FAILED: for 2'b01 expected a count of 1, got %d", result); pass = 1'b0; end result = $countones(4'b0111); if (result != 3) begin $display("FAILED: for 4'b0111 expected a count of 3, got %d", result); pass = 1'b0; end expr = 4'b1100; result = $countones(expr); if (result != 2) begin $display("FAILED: for 4'b1100 expected a count of 2, got %d", result); pass = 1'b0; end result = $countones(34'b1100000000000000000000000000000001); if (result != 3) begin $display("FAILED: for 34'1100000000000000000000000000000001 expected a count of 3, got %d", result); pass = 1'b0; end result = $countones(34'b1111000000110000001100000011000000); if (result != 10) begin $display("FAILED: for 34'1111000000110000001100000011000000 expected a count of 10, got %d", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf_countones_fail.v000066400000000000000000000002541435245347300224320ustar00rootroot00000000000000module top; integer result; initial begin result = $countones(top); result = $countones("a string"); result = $countones(4'b001, 1'b0); end endmodule iverilog-12_0/ivtest/ivltests/sf_isunknown.v000066400000000000000000000030361435245347300214560ustar00rootroot00000000000000module top; reg pass; reg result; reg [3:0] expr; initial begin pass = 1'b1; result = $isunknown(1'b0); if (result != 0) begin $display("FAILED: for 1'b0 expected 0, got %b", result); pass = 1'b0; end result = $isunknown(1'b1); if (result != 0) begin $display("FAILED: for 1'b1 expected 0, got %b", result); pass = 1'b0; end result = $isunknown(2'b01); if (result != 0) begin $display("FAILED: for 2'b01 expected 0, got %b", result); pass = 1'b0; end result = $isunknown(4'b0x11); if (result != 1) begin $display("FAILED: for 4'b0x11 expected 1, got %b", result); pass = 1'b0; end expr = 4'b110x; result = $isunknown(expr); if (result != 1) begin $display("FAILED: for 4'b110x expected 1, got %b", result); pass = 1'b0; end result = $isunknown(34'bx100000000000000000000000000000001); if (result != 1) begin $display("FAILED: for 34'x100000000000000000000000000000001 expected 1, got %b", result); pass = 1'b0; end result = $isunknown(34'b100000000000000000000000000000000x); if (result != 1) begin $display("FAILED: for 34'100000000000000000000000000000000x expected 1, got %b", result); pass = 1'b0; end result = $isunknown(34'b1000000000000000000000000000000000); if (result != 0) begin $display("FAILED: for 34'1000000000000000000000000000000000 expected 0, got %b", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf_isunknown_fail.v000066400000000000000000000002501435245347300224440ustar00rootroot00000000000000module top; reg result; initial begin result = $isunknown(top); result = $isunknown("a string"); result = $isunknown(4'b001, 1'b0); end endmodule iverilog-12_0/ivtest/ivltests/sf_onehot.v000066400000000000000000000024611435245347300207200ustar00rootroot00000000000000module top; reg pass; reg result; reg [3:0] expr; initial begin pass = 1'b1; result = $onehot(1'b0); if (result != 0) begin $display("FAILED: for 1'b0 expected 0, got %b", result); pass = 1'b0; end result = $onehot(1'b1); if (result != 1) begin $display("FAILED: for 1'b1 expected 1, got %b", result); pass = 1'b0; end result = $onehot(2'b01); if (result != 1) begin $display("FAILED: for 2'b01 expected 1, got %b", result); pass = 1'b0; end result = $onehot(4'b0x11); if (result != 0) begin $display("FAILED: for 4'b0x11 expected 0, got %b", result); pass = 1'b0; end expr = 4'b1100; result = $onehot(expr); if (result != 0) begin $display("FAILED: for 4'b1100 expected 0, got %b", result); pass = 1'b0; end result = $onehot(34'b1100000000000000000000000000000001); if (result != 0) begin $display("FAILED: for 34'1100000000000000000000000000000001 expected 0, got %b", result); pass = 1'b0; end result = $onehot(34'b1000000000000000000000000000000000); if (result != 1) begin $display("FAILED: for 34'1000000000000000000000000000000000 expected 1, got %b", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf_onehot0.v000066400000000000000000000024701435245347300210000ustar00rootroot00000000000000module top; reg pass; reg result; reg [3:0] expr; initial begin pass = 1'b1; result = $onehot0(1'b0); if (result != 1) begin $display("FAILED: for 1'b0 expected 1, got %b", result); pass = 1'b0; end result = $onehot0(1'b1); if (result != 1) begin $display("FAILED: for 1'b1 expected 1, got %b", result); pass = 1'b0; end result = $onehot0(2'b01); if (result != 1) begin $display("FAILED: for 2'b01 expected 1, got %b", result); pass = 1'b0; end result = $onehot0(4'b0x11); if (result != 0) begin $display("FAILED: for 4'b0x11 expected 0, got %b", result); pass = 1'b0; end expr = 4'b1100; result = $onehot0(expr); if (result != 0) begin $display("FAILED: for 4'b1100 expected 0, got %b", result); pass = 1'b0; end result = $onehot0(34'b1100000000000000000000000000000001); if (result != 0) begin $display("FAILED: for 34'1100000000000000000000000000000001 expected 0, got %b", result); pass = 1'b0; end result = $onehot0(34'b1000000000000000000000000000000000); if (result != 1) begin $display("FAILED: for 34'1000000000000000000000000000000000 expected 1, got %b", result); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sf_onehot0_fail.v000066400000000000000000000002421435245347300217660ustar00rootroot00000000000000module top; reg result; initial begin result = $onehot0(top); result = $onehot0("a string"); result = $onehot0(4'b001, 1'b0); end endmodule iverilog-12_0/ivtest/ivltests/sf_onehot_fail.v000066400000000000000000000002371435245347300217120ustar00rootroot00000000000000module top; reg result; initial begin result = $onehot(top); result = $onehot("a string"); result = $onehot(4'b001, 1'b0); end endmodule iverilog-12_0/ivtest/ivltests/sformatf.v000066400000000000000000000041251435245347300205540ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for $sformatf system function. module ivl_sformatf_test; wire test_net; assign (pull1, strong0) test_net = 1'b1; struct packed { logic [15:0] high; logic [15:0] low; } word; initial begin string f; word = 32'b0101_0101_0101_0101_0101_0101_0101_0101; // Test constant values // Integers f = $sformatf("sformatf test 1: %b %d %o %x", 8'd120, -12, 331, 120, 97); if(f != "sformatf test 1: 01111000 -12 00000000513 00000078 97") begin $display(f); $display("FAILED 1"); $finish(); end // Floats f = $sformatf("sformatf test 2: %e %f %g", 123.45, 100e12, 100e12); if(f != "sformatf test 2: 1.234500e+02 100000000000000.000000 1e+14") begin $display(f); $display("FAILED 2"); $finish(); end // Strings f = $sformatf("sformatf test 3: %s %c", "'string test'", 97); if(f != "sformatf test 3: 'string test' a") begin $display(f); $display("FAILED 3"); $finish(); end // Other stuff f = $sformatf("sformatf test 4: %t %v %u %z", 120s, test_net, word, word); if(f != "sformatf test 4: 120 Pu1 UUUU UUUU") begin $display(f); $display("FAILED 4"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/shellho1.v000066400000000000000000000060631435245347300204550ustar00rootroot00000000000000/* * Copyright (c) 2000 Mark Schellhorn * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /**************************************************************************** The following code illustrates an apparent bug in the VCS v5.2 simulator. The check for whether or not the memory[0] array element was set correctly fails; yet the $display statement immediately after the check shows the memory[0] element actually has been set correctly. I've noted that if the $display and the check are reversed, the $display is incorrect but the check passes. This appears to be a problem with the simulator's internal scheduler. ***************************************************************************/ module bug_test; reg [1:0] temp; initial begin /********** First test. */ $display("Running first test.\n"); // Try setting memory array in other module using hierarchical // references & concatenation. temp = 2'h3; top.memory.memory[0] = {2'h0,temp}; top.memory.memory[0] = {top.memory.memory[0],temp}; // Check that setting was made correctly if (top.memory.memory[0] != {2{temp}}) begin $display("ERROR! top.memory.memory[0] failed to get"); $display("set correctly!"); end else begin $display("PASS! top.memory.memory[0] set correctly."); end // Display the value that was checked $display("top.memory.memory[0] = %h",top.memory.memory[0]); /********** Second test. */ $display("\nRunning second test.\n"); // Try setting memory array in other module using hierarchical // references & concatenation. temp = 2'h3; top.memory.memory[1] = {2'h0,temp}; top.memory.memory[1] = {top.memory.memory[1],temp}; // Display the value that will be checked $display("top.memory.memory[1] = %h",top.memory.memory[1]); // Check that setting was made correctly if (top.memory.memory[1] != {2{temp}}) begin $display("ERROR! top.memory.memory[1] failed to get"); $display("set correctly!"); end else begin $display("PASS! top.memory.memory[1] set correctly."); end // Display the value that was checked $display("top.memory.memory[1] = %h",top.memory.memory[1]); $finish(0); end endmodule // Module containing a memory array module memory; reg [3:0] memory [0:1]; endmodule // Module to instantiate test and memory modules module top; bug_test bug_test(); memory memory(); endmodule iverilog-12_0/ivtest/ivltests/shift1.v000066400000000000000000000023021435245347300201240ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Rowland * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module dummy; reg [7:0] decode_vec; wire [7:0] data1; wire [7:0] data2; // icarus cant handle this statement assign data1 = (decode_vec[8'h02>>1] ) ? 8'h55 : 8'h00; assign data2 = (decode_vec[8'h01 ] ) ? 8'h55 : 8'h00; initial begin #0; $monitor("%h %h %h", decode_vec, data1, data2); decode_vec = 8'h02; #10; decode_vec = 8'h80; #10; decode_vec = 8'h02; #10; $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/shift2.v000066400000000000000000000007201435245347300201270ustar00rootroot00000000000000module main; reg [7:0] xu; reg signed [7:0] xs; initial begin xu = 8'b1100_0000; xs = 8'b1100_0000; xu = xu >>> 3; xs = xs >>> 3; if (xu !== 8'b0001_1000) begin $display("FAILED -- Unsigned >>> failed. xu=%b", xu); $finish; end if (xs !== 8'b1111_1000) begin $display("FAILED -- Signed >>> failed. xs=%b", xs); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/shift3.v000066400000000000000000000012101435245347300201230ustar00rootroot00000000000000module main; reg [7:0] xu; reg signed [7:0] xs; initial begin xu = 8'b1100_0000; xs = 8'b1100_0000; xu = xs >>> 3; xs = xu >>> 3; // IEEE1364-2005 Secion 5.5.1 Rules for Expression Types // "Expression type depends only on the operands. It does not depend // on the left-hand side (if any)." if (xu !== 8'b1111_1000) begin $display("FAILED -- xu = xs >>> 3 failed. xu=%b", xu); $finish; end if (xs !== 8'b0001_1111) begin $display("FAILED -- xs = xu >>> 3 failed. xs=%b", xs); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/shift4.v000066400000000000000000000022531435245347300201340ustar00rootroot00000000000000module main; reg signed [7:0] a; reg [7:0] b; initial begin // Make sure the arithmetic right shift sign extends $display("simple arithmetic right shift"); a = 8'b11001001; $display("before: a = %b", a); a = a>>>1; $display("after: a = %b", a); if (a !== 8'b11100100) begin $display("FAILED"); $finish; end // The concatenation operator is always unsigned, so // it must turn off sign extension. $display("concatenated arithmetic right shift"); a = 8'b11001001; b = 0; $display("before: a = %b", a); {a,b} = {a,b}>>>1; $display("after: a = %b", a); if (a !== 8'b01100100) begin $display("FAILED"); $finish; end // The concatenation operator is always unsigned, but // we can turn on signed behavior with $signed. $display("concatenated arithmetic right shift with $signed"); a = 8'b11001001; b = 0; $display("before: a = %b", a); {a,b} = $signed({a,b})>>>1; $display("after: a = %b", a); if (a !== 8'b11100100) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/shift5.v000066400000000000000000000016551435245347300201420ustar00rootroot00000000000000/* * This example pulled from comp.lang.verilog. It was written * by Russell Fredrickson to test * arithmetic shift for other compilers, and caught mine. */ module ArithmeticShiftTest; reg signed [31:0] in; reg [5:0] shift; reg signed [31:0] out; //calculate arithmetic barrel shift right always@(*) out = in >>> shift; initial begin //set up inputs for always block in = 32'sh80000000;//set to highest value negative number(-2147483648) shift = 6'd32; //shift the entire width of the word #1; //allow time for inputs to propagate //check output if(out === (32'sh80000000 >>> 6'd32)) begin $display("PASS: 32'sh80000000 >>> 6'd32 = 0x%h", out); end else begin $display("FAIL: 32'sh80000000 >>> 6'd32 != 0x%h,", (32'sh80000000 >>> 6'd32), " actual = 0x%h.", out); end end // initial begin endmodule // ArithmeticShiftTest iverilog-12_0/ivtest/ivltests/shift_pad.v000066400000000000000000000023221435245347300206710ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [1:0] out; reg in; initial begin in = 1; out = in << 1; if (out !== 2'b10) begin $display("FAILED (1) -- out == %b", out); $finish; end out <= in << 1; #1 if (out !== 2'b10) begin $display("FAILED (2) -- out == %b", out); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/shiftl.v000066400000000000000000000027501435245347300202260ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This tests the primitive synthesis of a simple left shift. */ module test (clk,c,a,b); input clk; input a, b; output [1:0] c; reg [1:0] c; (* ivl_synthesis_on *) always @(posedge clk) c <= (a << 1) | b; endmodule module main; reg a, b, clk; wire [1:0] c; test dut (.clk(clk), .c(c), .a(a), .b(b)); integer x; (* ivl_synthesis_off *) initial begin clk = 0; for (x = 0 ; x < 4 ; x = x+1) begin a = x[1]; b = x[0]; #1 clk = 1; #1 clk = 0; if (c !== x[1:0]) begin $display("FAILED == x=%0d (ab=%b%b), c=%b", x, a, b, c); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/signal_init_assign.vhd000066400000000000000000000010571435245347300231140ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; -- This is a simple test of the initialization assignment for -- signals. We also let a generic into the test. entity test is generic (PARM : std_logic := '0'); port (clk : in std_logic; src : in std_logic; dst : out std_logic); end test; architecture operation of test is signal tmp : std_logic := PARM; begin step: process (clk) begin -- process step if clk'event and clk = '1' then -- rising clock edge dst <= tmp xor src; end if; end process step; end operation; iverilog-12_0/ivtest/ivltests/signed1.v000066400000000000000000000033041435245347300202630ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests that signed registers are compared using signed * arithmetic. */ module main; reg signed [7:0] vala; reg signed [7:0] valb; reg [7:0] valc; initial begin vala = -1; valb = +1; valc = -1; if (vala >= valb) begin $display("FAILED -- vala(%b) is >= valb(%b)", vala, valb); $finish; end if (vala > valb) begin $display("FAILED -- vala(%b) is > valb(%b)", vala, valb); $finish; end if (valb <= vala) begin $display("FAILED -- valb(%b) is <= vala(%b)", valb, vala); $finish; end if (valb < vala) begin $display("FAILED -- valb(%b) is < vala(%b)", valb, vala); $finish; end if (valc <= valb) begin $display("FAILED -- valc(%b) is not > valb(%b)", valc, valb); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/signed10.v000066400000000000000000000020561435245347300203460ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module displaysigned(); reg signed [7:0] foo; reg [7:0] bar; initial begin foo = -8'sd2; bar = foo; $display("foo=%0d bar=%0d $signed(bar)=%0d", foo, bar, $signed(bar)); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/signed11.v000066400000000000000000000023641435245347300203510ustar00rootroot00000000000000/* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program catches some glitches in the MUXZ that Icarus Verilog * uses to implement the ?: in structural cases. */ module main; parameter FOO = 0; initial begin if ((FOO < -255) || (FOO > 255)) begin $display("FAILED -- foo=%d does not fall in the range?", FOO); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/signed12.v000066400000000000000000000003171435245347300203460ustar00rootroot00000000000000module top; // Does this have to be signed? wire signed [7:0] out; // Either of these will not expand correctly. // assign out = 'sh1f; assign out = 5'sh1f; initial #1 $displayb(out); endmodule iverilog-12_0/ivtest/ivltests/signed13.v000066400000000000000000000007601435245347300203510ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg pass; reg [3:0] var; integer lp; initial begin pass = 1'b1; for (lp = 0; lp < 16; lp = lp + 1) begin var = lp; // This should bit extend var as unsigned and then // convert it into a signed value. if (lp !== $signed(var+5'b0)) begin $display("FAILED: expected %2d, got %2d", lp, $signed(var+5'b0)); pass = 1'b0; end end if (pass) $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/signed2.v000066400000000000000000000026511435245347300202700ustar00rootroot00000000000000/* * Copyright (c) 2000 Steve Wilson (stevew@home.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Verify signed constant assignment to an integer. */ module test; integer I0,I1; reg [15:0] R0,R1; reg [3:0] error; initial begin error = 0; I0 = -4'd12; I1 = -32'd12; if(I0 !== 32'hfffffff4) begin $display("FAILED - negative decimal assignment failed. I0 s/b fffffff4, is %h", I0); error =1; end if(I1 !== 32'hfffffff4) begin $display("FAILED - negative decimal assignment failed. I1 s/b fffffff4, is %h", I1); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed3.v000066400000000000000000000026321435245347300202700ustar00rootroot00000000000000/* * Copyright (c) 2000 Steve Wilson (stevew@home.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Verify signed constant assignment to an reg. */ module test; integer I0,I1; reg [15:0] R0,R1; reg [3:0] error; initial begin R0 = -4'd12; R1 = -16'd12; error = 0; if(R0 !== 16'hfff4) begin $display("FAILED - negative decimal assignment failed. R0 s/b fff4, is %h", R0); error = 1; end if(R1 !== 16'hfff4) begin $display("FAILED - negative decimal assignment failed. R1 s/b fff4, is %h", R1); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed4.v000066400000000000000000000022201435245347300202620ustar00rootroot00000000000000/* * Copyright (c) 2001 Steve Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* Check that display prints the right signed value. */ module signed1(); reg [7:0] x; reg signed [7:0] y; initial begin x = 8'b0000_0011; y = 8'b1111_1101; $display("x = %0d (should be 3)",x); $display("y = %0d (should be -3)",y); x = y; $display("x = %0d (should be 253)",x); end endmodule iverilog-12_0/ivtest/ivltests/signed5.v000066400000000000000000000027061435245347300202740ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests the magic $signed system function. */ module main; reg [3:0] a; initial begin a = 4'd12; // The expression should not change the bit pattern in any way if ($signed(a) !== 4'b1100) begin $display("FAILED -- $signed(%b) === %b", a, $signed(a)); $finish; end if ($signed(a) == 4) begin $display("FAILED -- $signed(%b) == 4", a); $finish; end // The >= should do a signed comparison here. if ($signed(a) >= 0) begin $display("FAILED -- $signed(%b) > 0", a); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/signed6.v000066400000000000000000000030731435245347300202730ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * test the signedness of wires. */ module main; reg signed [7:0] val_rs = -5; wire [7:0] val_w = val_rs + 1; wire signed [7:0] val_ws = val_rs + 1; initial begin #1 /* Let assignments settle. */ $display("val_w=%d, val_ws=%d", val_w, val_ws); if (val_w !== 8'd252) begin $display("FAILED -- val_w is wrong: %b", val_w); $finish; end if (val_ws !== -8'sd4) begin $display("FAILED == val_ws is wrong: %b", val_ws); $finish; end if (val_ws > 0) begin $display("FAILED -- signed test of val_ws failed"); $finish; end if (val_w < 0) begin $display("FAILED -- signed test of val_w failed"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/signed7.v000066400000000000000000000033721435245347300202760ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * test the signedness of wires. */ module main; reg signed [7:0] val_rs = -5; wire [7:0] val_w = val_rs + 1; wire signed [7:0] val_ws = val_rs + 1; sub dut(val_w, val_ws); endmodule // main module sub(val_w, val_ws); input [7:0] val_w; input signed [7:0] val_ws; wire [7:0] val_w; wire signed [7:0] val_ws; initial begin #1 /* Let assignments settle. */ $display("val_w=%d, val_ws=%d", val_w, val_ws); if (val_w !== 8'd252) begin $display("FAILED -- val_w is wrong: %b", val_w); $finish; end if (val_ws !== -8'sd4) begin $display("FAILED == val_ws is wrong: %b", val_ws); $finish; end if (val_ws > 0) begin $display("FAILED -- signed test of val_ws failed"); $finish; end if (val_w < 0) begin $display("FAILED -- signed test of val_w failed"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/signed8.v000066400000000000000000000027201435245347300202730ustar00rootroot00000000000000/* * Copyright (c) 2003 The ASIC Group (www.asicgroup.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module mult58s(input [4:0] a, input signed [7:0] b, output signed [15:0] p); wire signed [12:0] pt; wire signed [5:0] ta; assign ta = a; assign pt = b * ta; assign p=pt; endmodule module test_mult; integer a,b, prod; wire [15:0] p; mult58s dut(a[4:0], b[7:0], p); initial begin for(a = 0; a < (1<<5); a=a+1 ) for(b=-127; b<128; b=b+1) begin prod = a * b; #1 if(p !== prod[15:0]) begin $display("Error Miscompare with a=%h, b=%h expect = %0d (%h) acutal = %h", a[4:0], b[7:0], prod, prod[15:0], p); $finish; end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed9.v000066400000000000000000000023231435245347300202730ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module assignsigned(); parameter foo = 10; reg signed [15:0] bar = -1; wire baz; assign baz = (bar < $signed(foo)); initial begin #1 $display("bar=%h(%0d), foo=%0d, baz = %b", bar, bar, foo, baz); if (baz !== 1'b1) begin $display("FAILED -- Compare returns %b instead of 1.", baz); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed_a.v000066400000000000000000000013211435245347300204770ustar00rootroot00000000000000module top; reg pass; reg [3:0] array [1:8]; reg signed [2:0] a; reg signed [127:0] b; reg [4*8:1] res; initial begin array [7] = 4'b1001; pass = 1'b1; /* If this fails it is likely because the index width is less * than an integer width. */ a = -1; $sformat(res, "%b", array[a]); if (res !== "xxxx") begin $display("Failed: &A<> negative, expected 4'bxxxx, got %s.", res); pass = 1'b0; end b = 7; b[120] = 1'b1; // This should be stripped! $sformat(res, "%b", array[b]); if (res !== "1001") begin $display("Failed: &A<> large, expected 4'b1001, got %s.", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed_equality.v000066400000000000000000000020361435245347300221200ustar00rootroot00000000000000module top; parameter seeq1 = 6'sb111000 === 4'sb1000; parameter seeqx = 6'sbxxx000 === 4'sbx000; parameter seeqz = 6'sbzzz000 === 4'sbz000; parameter seq1 = 6'sb111000 == 4'sb1000; parameter seqx = 6'sbxxx000 == 4'sbx000; parameter seqz = 6'sbzzz000 == 4'sbz000; reg pass; initial begin pass = 1'b1; if (seeq1 !== 1'b1) begin $display("FAILED: signed === (1), got %b", seeq1); pass = 1'b0; end if (seeqx !== 1'b1) begin $display("FAILED: signed === (x), got %b", seeqx); pass = 1'b0; end if (seeqz !== 1'b1) begin $display("FAILED: signed === (z), got %b", seeqz); pass = 1'b0; end if (seq1 !== 1'b1) begin $display("FAILED: signed == (1), got %b", seq1); pass = 1'b0; end if (seqx !== 1'bx) begin $display("FAILED: signed == (x), got %b", seqx); pass = 1'b0; end if (seqz !== 1'bx) begin $display("FAILED: signed == (z), got %b", seqz); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed_net_display.v000066400000000000000000000013271435245347300226000ustar00rootroot00000000000000`begin_keywords "1364-2005" module signed_net_display; wire signed [3:0] value[-7:7]; genvar i; for (i = 7; i >= -7; i = i - 1) begin:genloop assign value[i] = i; end reg [2*8-1:0] result; reg [2*8-1:0] expect; integer j; reg fail = 0; initial begin #0; for (j = -7; j <= 7; j = j + 1) begin $swrite(result, "%d", value[j]); if (j < 0) begin expect[1*8 +: 8] = "-"; expect[0*8 +: 8] = "0" - j; end else begin expect[1*8 +: 8] = " "; expect[0*8 +: 8] = "0" + j; end $display("%s : %s", expect, result); if (result !== expect) fail = 1; end if (fail) $display("FAILED"); else $display("PASSED"); end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/signed_part.v000066400000000000000000000007461435245347300212370ustar00rootroot00000000000000module top; reg pass = 1'b1; reg [14:-1] big = 16'h0123; reg signed [15:0] a; wire [3:0] w_big = big[a+:4]; initial begin #1; // Wait for the assigns above to happen. /* If this fails it is likely because the index width is less * than an int width. */ a = -2; #1; if (w_big !== 4'b011x) begin $display("Failed: .part/v check, expected 4'b011x, got %b.", w_big); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/signed_pv.v000066400000000000000000000025571435245347300207200ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; parameter pval = -2; reg pass = 1'b1; reg [14:-1] big = 16'h0123; reg [15:0] big_0 = 16'h0123; reg signed [15:0] idxs [0:1]; reg signed [15:0] a; reg [4*8:1] res; initial begin /* If this fails it is likely because the index width is less * than an integer width. */ a = -2; $sformat(res, "%b", big[a+:4]); if (res !== "011x") begin $display("Failed: &PV<> check 1, expected 4'b011x, got %s.", res); pass = 1'b0; end a = 0; idxs[0] = -1; $sformat(res, "%b", big_0[idxs[a]+:4]); if (res !== "011x") begin $display("Failed: &PV<> check 2, expected 4'b011x, got %s.", res); pass = 1'b0; end /* This should work since it is a constant value. */ `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST $sformat(res, "%b", big[pval+:4]); `else $sformat(res, "%bx", big[(pval+1)+:3]); `endif if (res !== "011x") begin $display("Failed: &PV<> check 3, expected 4'b011x, got %s.", res); pass = 1'b0; end /* This should always work since it uses the index directly. */ a = -1; $sformat(res, "%b", big_0[a+:4]); if (res !== "011x") begin $display("Failed: &PV<> check 4, expected 4'b011x, got %s.", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/simparam.v000066400000000000000000000102461435245347300205450ustar00rootroot00000000000000`timescale 1ns/1ps module top; lower dut(); endmodule module lower; parameter bad_name = "this_is_a_bad_name"; reg [15:0] def = "OK"; reg pass = 1'b1; reg [1023:0] result; real rl_res; initial begin #1; /* Display the version and other information. */ $display("Testing with Icarus Verilog version: %g, subversion: %g", $simparam("simulatorVersion"), $simparam("simulatorSubversion")); $display("Using a CPU word size of %g bits.", $simparam("CPUWordSize")); $display("Running in directory: %0s\n", $simparam$str("cwd")); /* * Check the time units and precision. * * Since this is double math check that the result is within a * factor of 1e-10 of the correct value. */ rl_res = $simparam("timeUnit") - 1e-9; rl_res = (rl_res < 0) ? -rl_res : rl_res; if (rl_res > 1e-9*1e-10) begin $display("$simparam(\"timeUnit\") failed, got %g.", rl_res); pass = 1'b0; end rl_res = $simparam("timePrecision") - 1e-12; rl_res = (rl_res < 0) ? -rl_res : rl_res; if (rl_res >= 1e-12*1e-10) begin $display("$simparam(\"timePrecision\") failed, got %g.", rl_res); pass = 1'b0; end /* Check the string routines, see below for why this is a task. */ check_string; /* Check that a bad parameter name with a default works. */ if ($simparam(bad_name, 1.0) != 1.0) begin $display("$simparam with a bad name and a default value failed."); pass = 1'b0; end result = $simparam$str(bad_name, def); if (result[15:0] != "OK") begin $display("$simparam$str with a bad name and a default value failed."); pass = 1'b0; end /* These should also print an error message. */ if ($simparam(bad_name) != 0.0) begin $display("$simparam with a bad name failed."); pass = 1'b0; end result = $simparam$str(bad_name); if (result[55:0] != "") begin $display("$simparam$str with a bad name failed."); pass = 1'b0; end /* All these are currently unimplemented and just return 0.0 or N/A. */ if ($simparam("gdev") != 0.0) begin $display("$simparam(\"gdev\") failed."); pass = 1'b0; end if ($simparam("gmin") != 0.0) begin $display("$simparam(\"gmin\") failed."); pass = 1'b0; end if ($simparam("imax") != 0.0) begin $display("$simparam(\"imax\") failed."); pass = 1'b0; end if ($simparam("imelt") != 0.0) begin $display("$simparam(\"imelt\") failed."); pass = 1'b0; end if ($simparam("iteration") != 0.0) begin $display("$simparam(\"iteration\") failed."); pass = 1'b0; end if ($simparam("scale") != 0.0) begin $display("$simparam(\"scale\") failed."); pass = 1'b0; end if ($simparam("shrink") != 0.0) begin $display("$simparam(\"shrink\") failed."); pass = 1'b0; end if ($simparam("sourceScaleFactor") != 0.0) begin $display("$simparam(\"sourceScaleFactor\") failed."); pass = 1'b0; end if ($simparam("tnom") != 0.0) begin $display("$simparam(\"tnom\") failed."); pass = 1'b0; end result = $simparam$str("analysis_name"); if (result[23:0] != "N/A") begin $display("$simparam$str(\"analysis_name\") failed."); pass = 1'b0; end result = $simparam$str("analysis_type"); if (result[23:0] != "N/A") begin $display("$simparam$str(\"analysis_type\") failed."); pass = 1'b0; end if (pass) $display("\nPASSED"); end /* We need this to make instance and path different. */ task check_string; begin result = $simparam$str("module"); if (result[39:0] != "lower") begin $display("$simparam$str(\"module\") failed, got %0s.", result); pass = 1'b0; end result = $simparam$str("instance"); if (result[55:0] != "top.dut") begin $display("$simparam$str(\"instance\") failed, got %0s.", result); pass = 1'b0; end result = $simparam$str("path"); if (result[159:0] != "top.dut.check_string") begin $display("$simparam$str(\"instance\") failed, got %0s.", result); pass = 1'b0; end end endtask endmodule iverilog-12_0/ivtest/ivltests/simple_byte.v000066400000000000000000000011401435245347300212410ustar00rootroot00000000000000module main; byte foo, bar = 10; byte wire_res; byte var_res; assign wire_res = foo*bar; initial begin foo = 9; var_res = foo * bar; $display("%0d * %0d = %0d %0d", foo, bar, foo * bar, var_res); if ((foo * bar) !== 90) begin $display("FAILED"); $finish; end if (var_res !== 90) begin $display("FAILED"); $finish; end #0; // allow CA to propagate $display("%0d * %0d = %0d", foo, bar, wire_res); if (wire_res !== 90) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/simple_int.v000066400000000000000000000011351435245347300210740ustar00rootroot00000000000000module main; int foo, bar = 10; int wire_res; int var_res; assign wire_res = foo*bar; initial begin foo = 9; var_res = foo * bar; $display("%0d * %0d = %0d %0d", foo, bar, foo * bar, var_res); if ((foo * bar) !== 90) begin $display("FAILED"); $finish; end if (var_res !== 90) begin $display("FAILED"); $finish; end #0; // allow CA to propagate $display("%0d * %0d = %0d", foo, bar, wire_res); if (wire_res !== 90) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/simple_longint.v000066400000000000000000000011511435245347300217520ustar00rootroot00000000000000module main; longint foo, bar = 10; longint wire_res; longint var_res; assign wire_res = foo*bar; initial begin foo = 9; var_res = foo * bar; $display("%0d * %0d = %0d %0d", foo, bar, foo * bar, var_res); if ((foo * bar) !== 90) begin $display("FAILED"); $finish; end if (var_res !== 90) begin $display("FAILED"); $finish; end #0; // allow CA to propagate $display("%0d * %0d = %0d", foo, bar, wire_res); if (wire_res !== 90) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/simple_shortint.v000066400000000000000000000011541435245347300221550ustar00rootroot00000000000000module main; shortint foo, bar = 10; shortint wire_res; shortint var_res; assign wire_res = foo*bar; initial begin foo = 9; var_res = foo * bar; $display("%0d * %0d = %0d %0d", foo, bar, foo * bar, var_res); if ((foo * bar) !== 90) begin $display("FAILED"); $finish; end if (var_res !== 90) begin $display("FAILED"); $finish; end #0; // allow CA to propagate $display("%0d * %0d = %0d", foo, bar, wire_res); if (wire_res !== 90) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sint_test.v000066400000000000000000000267041435245347300207560ustar00rootroot00000000000000// Eleven basic tests in here: // 1. int must be initialised before any initial or always block // 2. assignments to (signed) int with random numbers // 3. assignments to (signed) int with random values including X and Z // 4. converting unsigned integers to signed int // 5. converting signed integers to signed int // 6. converting integers including X and Z states to signed int // 7. trying signed sums (procedural, function, task and module) // 8. trying signed mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to signed int (signed extension) // 11. trying some concatenations from bytes, shortints to ints module ms_add (input int signed a, b, output int signed sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter UMAX = 'h7fff_ffff; parameter MAX8 = 'h7f; parameter MAX16 = 'h7fff; parameter LEN = 32; // variables used as golden references reg signed [LEN-1:0] ar; // holds numbers reg signed [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg signed [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // type assumed tested before byte signed pt1, pt2; shortint signed ps1, ps2; // types to be tested int signed bu; // holds numbers int signed bu_xz; // 'x and 'z are attempted on this int signed bresult; // hold results from sums and mults int signed mcaresult; // wired to a module instance int signed mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // int 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation ms_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 32'b0 || bu_xz !== 32'b0 || bresult !== 32'b0 || mcaresult !== 32'b0 || mabresult !== 32'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving int type with signed random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to int: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type signed int // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = $random; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to int (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to signed int // maintaining bit representation is expected for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random}; #1; force bu = ui; #1; if (bu !== ui) begin $display ("FAILED - incorrect truncation from unsigned integer to int: %b", bu); $finish; end end release bu; // converting signed integers to signed ints // bit representation should be maintained for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random; #1; force bu = si; #1; if (bu !== si) begin $display ("FAILED - incorrect assignment from signed integer to int: %b mismatchs %b", bu, si); $finish; end end release bu; // converting integers having 'x 'z values into type signed int // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si); si = ar_xz; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to int: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying signed sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random; ar_xz = $random; #1; bresult = bu + bu_xz; #1; if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed ints: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // invoking shortint sum function if ( fs_sum (bu, bu_xz) !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed int in function"); $finish; end // invoking byte sum task ts_sum (bu, bu_xz, bresult); if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed int in task: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // checking byte sum from module if ( mcaresult !== s_sum(ar, ar_xz) || mabresult !== s_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of signed int from module"); $finish; end end // trying signed mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ($random % UMAX) << (LEN/2); ar_xz = ($random % UMAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; // truncated multiplication #1; if ( bresult !== sh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of signed ints (truncated)"); $finish; end #1; ps1 = $random % 'h7fff; ps2 = $random % 'h7fff; #1; bresult = ps1 * ps2; // int = shorint x shortint #1; if ( bresult !== s_mul(ps1, ps2) ) begin $display ("FAILED - incorrect multiplication of signed shortints"); $finish; end // invoking int mult function (shortint*shortint) if ( fs_mul (ps1, ps2) !== s_mul(ps1, ps2) ) begin $display ("FAILED - incorrect product of signed shortint for a function returning signed int"); $finish; end // invoking int mult task (shortint*shortint) ts_mul (ps1, ps2, bresult); if ( bresult !== s_mul(ps1, ps2) ) begin $display ("FAILED - incorrect product of signed shortint in task returning signed int"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random; ar_xz = $random; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on signed ints"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on signed ints"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on signed ints"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on signed ints"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on signed ints"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on signed ints"); $finish; end end # 1; // signed small number to signed int for (i = 0; i < (1< // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests size casting of complex expressions. module resize(output wire logic [4:0] result); logic [6:0] a; assign result = (5'(a + 2)); initial begin a = 7'd39; end endmodule module resize_test(); logic [4:0] result; resize dut(result); initial begin #1; if(result !== 5'd9) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/size_cast3.v000066400000000000000000000030151435245347300207770ustar00rootroot00000000000000module test(); localparam size1 = 4; localparam size2 = 6; localparam size3 = 8; localparam [5:0] value1 = 6'h3f; localparam signed [5:0] value2 = 6'h3f; reg [31:0] result; reg failed = 0; initial begin result = size1'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value2) + 'd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; result = size2'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value2) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; result = size3'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size3'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size3'(value2) + 'd0; $display("%h", result); if (result !== 32'h000000ff) failed = 1; result = size3'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/size_cast4.v000066400000000000000000000027771435245347300210160ustar00rootroot00000000000000module test(); localparam size1 = 4; localparam size2 = 6; localparam size3 = 8; reg [5:0] value1 = 6'h3f; reg signed [5:0] value2 = 6'h3f; reg [31:0] result; reg failed = 0; initial begin result = size1'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value2) + 'd0; $display("%h", result); if (result !== 32'h0000000f) failed = 1; result = size1'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; result = size2'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value2) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size2'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; result = size3'(value1) + 'd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size3'(value1) + 'sd0; $display("%h", result); if (result !== 32'h0000003f) failed = 1; result = size3'(value2) + 'd0; $display("%h", result); if (result !== 32'h000000ff) failed = 1; result = size3'(value2) + 'sd0; $display("%h", result); if (result !== 32'hffffffff) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/size_cast5.v000066400000000000000000000051731435245347300210100ustar00rootroot00000000000000module test(); function [31:0] cast_4uu(input [5:0] value); cast_4uu = 4'(value) + 'd0; endfunction function [31:0] cast_4us(input [5:0] value); cast_4us = 4'(value) + 'sd0; endfunction function [31:0] cast_4su(input signed [5:0] value); cast_4su = 4'(value) + 'd0; endfunction function [31:0] cast_4ss(input signed [5:0] value); cast_4ss= 4'(value) + 'sd0; endfunction function [31:0] cast_6uu(input [5:0] value); cast_6uu = 6'(value) + 'd0; endfunction function [31:0] cast_6us(input [5:0] value); cast_6us = 6'(value) + 'sd0; endfunction function [31:0] cast_6su(input signed [5:0] value); cast_6su = 6'(value) + 'd0; endfunction function [31:0] cast_6ss(input signed [5:0] value); cast_6ss= 6'(value) + 'sd0; endfunction function [31:0] cast_8uu(input [5:0] value); cast_8uu = 8'(value) + 'd0; endfunction function [31:0] cast_8us(input [5:0] value); cast_8us = 8'(value) + 'sd0; endfunction function [31:0] cast_8su(input signed [5:0] value); cast_8su = 8'(value) + 'd0; endfunction function [31:0] cast_8ss(input signed [5:0] value); cast_8ss= 8'(value) + 'sd0; endfunction localparam [31:0] result1a = cast_4uu(6'h3f); localparam [31:0] result1b = cast_4us(6'h3f); localparam [31:0] result1c = cast_4su(6'h3f); localparam [31:0] result1d = cast_4ss(6'h3f); localparam [31:0] result2a = cast_6uu(6'h3f); localparam [31:0] result2b = cast_6us(6'h3f); localparam [31:0] result2c = cast_6su(6'h3f); localparam [31:0] result2d = cast_6ss(6'h3f); localparam [31:0] result3a = cast_8uu(6'h3f); localparam [31:0] result3b = cast_8us(6'h3f); localparam [31:0] result3c = cast_8su(6'h3f); localparam [31:0] result3d = cast_8ss(6'h3f); reg failed = 0; initial begin $display("%h", result1a); if (result1a !== 32'h0000000f) failed = 1; $display("%h", result1b); if (result1b !== 32'h0000000f) failed = 1; $display("%h", result1c); if (result1c !== 32'h0000000f) failed = 1; $display("%h", result1d); if (result1d !== 32'hffffffff) failed = 1; $display("%h", result2a); if (result2a !== 32'h0000003f) failed = 1; $display("%h", result2b); if (result2b !== 32'h0000003f) failed = 1; $display("%h", result2c); if (result2c !== 32'h0000003f) failed = 1; $display("%h", result2d); if (result2d !== 32'hffffffff) failed = 1; $display("%h", result3a); if (result3a !== 32'h0000003f) failed = 1; $display("%h", result3b); if (result3b !== 32'h0000003f) failed = 1; $display("%h", result3c); if (result3c !== 32'h000000ff) failed = 1; $display("%h", result3d); if (result3d !== 32'hffffffff) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/slongint_test.v000066400000000000000000000306711435245347300216340ustar00rootroot00000000000000// Eleven basic tests in here: // 1. longint must be initialised before any initial or always block // 2. assignments to (signed) longint with random numbers // 3. assignments to (signed) longint with random values including X and Z // 4. converting unsigned 64-bit integer time to signed longint // 5. converting signed integers to signed longint // 6. converting 64-bit integers including X and Z states to unsigned longint // 7. trying unsigned sums (procedural, function, task and module) // 8. trying unsigned mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to unsigned longint (signed extension) // 11. trying some concatenations from bytes, shortints, ints to longints module ms_add (input longint signed a, b, output longint signed sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter MAX8 = 'h7f; parameter MAX16 = 'h7fff; parameter LEN = 64; // variables used as golden references reg signed [LEN-1:0] ar; // holds numbers reg signed [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg signed [LEN-1:0] ar_expected; reg unsigned [LEN-1:0] ui; // unsigned 64-bit integer reg signed [LEN-1:0] si; // signed 64-bit integer reg signed [LEN/2-1:0] slice; // type assumed to be tested before hand byte signed pt1, pt2; shortint signed ps1, ps2; int signed pv1, pv2; // types to be tested longint signed bu; // holds numbers longint signed bu_xz; // 'x and 'z are attempted on this longint signed bresult; // hold results from sums and mults longint signed mcaresult; // wired to a module instance longint signed mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // longint 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation ms_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 64'b0 || bu_xz != 64'b0 || bresult !== 64'b0 || mcaresult !== 64'b0 || mabresult !== 64'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving longint type with signed random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { $random, $random }; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to int: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned longint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = { $random, $random }; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to longint (when 'x 'z): %b", bu); $finish; end end // converting unsigned 64-bit integers (time) to unsigned longint // this should pass trivially for (i = 0; i< N_REPS; i = i+1) begin #1; ui = { {$random}, {$random} }; #1; force bu = ui; #1; if (bu !== ui) begin $display ("FAILED - incorrect assignment from 64-bit integer to longint: %b", bu); $finish; end end release bu; // converting signed 64-bit integers to unsigned longints // keeping the same bit representation is expected for (i = 0; i< N_REPS; i = i+1) begin #1; si = { {$random}, {$random} }; #1; force bu = si; #1; if (bu !== si) begin $display ("FAILED - incorrect assignment from 64-bit signed integer to longint: %d mismatchs %d", bu, -ui); $finish; end end release bu; // converting integers having 'x 'z values into type unsigned longint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; ui = { {$random}, {$random} }; ar_xz = xz_inject (ui); ui = ar_xz; ar_expected = xz_expected (ar_xz); #1; force bu_xz = ui; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from 64-bit integer (with 'x 'z) to longint: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying signed sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { $random, $random }; ar_xz = { $random, $random }; #1; bresult = bu + bu_xz; #1; if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed longints: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // invoking longint sum function if ( fs_sum (bu, bu_xz) !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned longint in function"); $finish; end // invoking longint sum task ts_sum (bu, bu_xz, bresult); if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned longint in task: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // checking longint sum from module if ( mcaresult !== s_sum(ar, ar_xz) || mabresult !== s_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of signed longtint from module"); $finish; end end // trying signed mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { $random % 32'd32768, $random % 32'd16384 }; ar_xz = { $random % 32'd16384, $random % 32'd32768 }; #1; bresult = bu * bu_xz; // truncated mult #1; if ( bresult !== sh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of signed longints: %0d mismatchs %0d", bresult, sh_mul(ar, ar_xz)); $finish; end #1; pv1 = $random; pv2 = $random; #1; bresult = pv1 * pv2; // longint = int x int #1; if ( bresult !== s_mul(pv1, pv2) ) begin $display ("FAILED - incorrect multiplication of signed longints for int inputs"); $finish; end // invoking longint mult function (int*int) if ( fs_mul (pv1, pv2) !== s_mul(pv1, pv2) ) begin $display ("FAILED - incorrect product of signed ints for a function returning signed longint"); $finish; end // invoking longint mult task (int*int) ts_mul (pv1, pv2, bresult); if ( bresult !== s_mul(pv1, pv2) ) begin $display ("FAILED - incorrect product of signed int in task returning signed longint"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { $random, $random }; ar_xz = { $random, $random }; #1; if ( (bu < bu_xz ) != (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on signed longints"); $finish; end if ( (bu <= bu_xz ) != (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on signed longints"); $finish; end if ( (bu > bu_xz ) != (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on signed longints"); $finish; end if ( (bu >= bu_xz ) != (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on signed longints"); $finish; end if ( (bu == bu_xz ) != (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on signed longints"); $finish; end if ( (bu != bu_xz ) != (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on signed ints"); $finish; end end # 1; // signed small number to unsigned shorint for (i = 0; i < N_REPS; i = i+1) begin #1; slice = $random % 'h7fff_ffff; force bu = slice; ar = slice; #1; if (bu !== ar) begin $display ("FAILED - incorrect signed extend to signed longint"); $finish; end end release bu; // trying concatenations (and replication) for (i = 0; i< N_REPS; i = i+1) begin #1; pt1 = $random % MAX8; pt2 = $random % MAX8; #1; bresult = { {4{pt1}}, {4{pt2}} }; #1; if ( bresult[63:56] !== pt1 || bresult[55:48] !== pt1 || bresult[47:40] !== pt1 || bresult[39:32] !== pt1 || bresult[31:24] !== pt2 || bresult[23:16] !== pt2 || bresult[15:8] !== pt2 || bresult[7:0] !== pt2) begin $display ("FAILED - incorrect concatenation and replication of bytes into signed longints"); $finish; end #1; ps1 = $random % MAX16; ps2 = $random % MAX16; #1; bresult = { {2{ps1}}, {2{ps2}} }; #1; if ( bresult[63:48] !== ps1 || bresult[47:32] !== ps1 || bresult[31:16] !== ps2 || bresult[15:0] !== ps2) begin $display ("FAILED - incorrect concatenation and replication of shortint into signed long ints"); $finish; end #1; pv1 = $random; pv2 = $random; #1; bresult = { pv1, pv2 }; #1; if ( bresult[63:32] !== pv1 || bresult[31:0] !== pv2) begin $display ("FAILED - incorrect concatenation and replication of int into signed longints"); $finish; end end #1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [LEN-1:0] xz_inject (input signed [LEN-1:0] value); integer i, k; time temp; begin temp = {$random, $random}; for (i=0; i P) = (td, td, th, 0, th, 0); endspecify endmodule `endcelldefine iverilog-12_0/ivtest/ivltests/specify2.v000066400000000000000000000016411435245347300204570ustar00rootroot00000000000000module main; wire dst; reg src; spec_buf dut(dst, src); initial begin src = 0; #10 if (dst !== 0) begin $display("FAILED -- setup failed: src=%b, dst=%b", src, dst); $finish; end src = 1; #5 if (dst !== 0) begin $display("FAILED -- dst changed too fast. src=%b, dst=%b", src, dst); $finish; end #5 if (dst !== 1) begin $display("FAILED -- dst failed to change. src=%b, dst=%b", src, dst); $finish; end src = 0; #5 if (dst !== 1) begin $display("FAILED -- dst changed too fast. src=%b, dst=%b", src, dst); $finish; end #5 if (dst !== 0) begin $display("FAILED -- dst failed to change. src=%b, dst=%b", src, dst); $finish; end $display("PASSED"); end endmodule // main module spec_buf(output wire O, input wire I); buf (O, I); specify (I => O) = (7); endspecify endmodule // sec_buf iverilog-12_0/ivtest/ivltests/specify3.v000066400000000000000000000012461435245347300204610ustar00rootroot00000000000000// specify3.v module top; reg a, b, fast; wire q; initial begin a = 0; b = 0; fast = 0; #10 $monitor($time,,"a=%b, b=%b, fast=%b, q=%b", a, b, fast, q); #10 a = 1; #10 a = 0; #10 b = 1; #10 b = 0; #10 a = 1; #10 fast = 1; #10 b = 1; #10 b = 0; #10 a = 0; #10 a = 1; #10 $finish(0); end myxor g1 (q, a, b, fast); endmodule module myxor (q, a, b, fast); output q; input a, b, fast; xor g1 (q, a, b); specify if (fast) (b => q) = 1; if (fast) (a => q) = 1; if (~fast) (b => q) = 4; if (~fast) (a => q) = 4; endspecify endmodule iverilog-12_0/ivtest/ivltests/specify4.v000066400000000000000000000007401435245347300204600ustar00rootroot00000000000000// specify4.v module top; reg d, c; wire q; initial begin d = 0; c = 1; #10 $monitor($time,,"q=%b, d=%b, c=%b", q, d, c); #5 c = 0; #5 c = 1; #5 c = 0; d = 1; #5 c = 1; #5 c = 0; d = 0; #5 c = 1; #10 $finish(0); end mydff g1 (q, d, c); endmodule module mydff (output reg q, input d, input c); always @(posedge c) q <= d; specify (posedge c => (q +: d)) = (3, 2); endspecify endmodule iverilog-12_0/ivtest/ivltests/specify5.v000066400000000000000000000035041435245347300204620ustar00rootroot00000000000000`timescale 100 ps / 10 ps module test; reg cdn, cp, d; wire qr, qp; initial begin $timeformat(-9, 2, " ns", 9); $monitor("%t - cdn=%b, cp=%b, d=%b, qr=%b, qp=%b",$time,cdn,cp,d,qr,qp); // Reset the FF. cp = 0; d = 1; #100 cdn = 0; #100 cdn = 1; // Toggle in some data. #100 cp = 1; #100 cp = 0; d = 0; #100 cp = 1; #100 cp = 0; d = 1; #100 cp = 1; end dff_rtl dutr(qr, d, cp, cdn); // This one works fine. dff_prm dutp(qp, d, cp, cdn); // This one has no delay. endmodule // The RTL version appears to work fine. module dff_rtl (q, d, cp, cdn); output q; input d; input cp; input cdn; reg qi; always @(posedge cp or negedge cdn) begin if (~cdn) qi <= 1'b0; else qi <= d; end buf (q, qi); specify specparam tpd_cp_q_lh = 6; specparam tpd_cp_q_hl = 7; specparam tpd_cdn_q_lh = 0; specparam tpd_cdn_q_hl = 3; if (cdn) (posedge cp => (q +: d)) = (tpd_cp_q_lh, tpd_cp_q_hl); (negedge cdn => (q +: 1'b0)) = (tpd_cdn_q_lh, tpd_cdn_q_hl); endspecify endmodule // The primitive version has no delay. module dff_prm (q, d, cp, cdn); output q; input d, cp, cdn; UDP_DFF G3(q, d, cp, cdn); specify specparam tpd_cp_q_lh = 6; specparam tpd_cp_q_hl = 7; specparam tpd_cdn_q_lh = 0; specparam tpd_cdn_q_hl = 3; if (cdn) (posedge cp => (q +: d)) = (tpd_cp_q_lh, tpd_cp_q_hl); (negedge cdn => (q +: 1'b0)) = (tpd_cdn_q_lh, tpd_cdn_q_hl); endspecify endmodule // This is overly simplistic, but it works for this example. primitive UDP_DFF(q, d, cp, cdn); output q; reg q; input d, cp, cdn; table // d cp cdn q0 q * ? ? : ? : - ; ? n ? : ? : - ; 0 r 1 : ? : 0 ; 1 r 1 : ? : 1 ; ? ? 0 : ? : 0 ; ? ? p : ? : - ; endtable endprimitive iverilog-12_0/ivtest/ivltests/specify_01.v000066400000000000000000000015641435245347300207010ustar00rootroot00000000000000module dff (clk, d, q) ; input d,clk; output q; reg q_out; wire q; specify specparam tR_clk_q = 100, tF_clk_q = 150; (clk,d => q) = (tR_clk_q,tF_clk_q); endspecify always @(posedge clk) q_out <= d; buf u_buf (q,q_out); endmodule module test; reg clk, d; reg err; time pos_lvl,neg_lvl; dff u_dff (clk,d,q); initial begin // $dumpfile("test.vcd"); // $dumpvars(0,test); err = 0; d = 0; clk = 0; #200; clk = 1; #200; clk = 0; #200; clk = 1; #200; clk = 0; #200; clk = 1; $display("pos_lvl=%t neg_lvl=%t",pos_lvl,neg_lvl); if((pos_lvl != 700) && (neg_lvl != 350)) $display("FAILED"); else $display("PASSED"); end always @(posedge q) pos_lvl = $time; always @(negedge q) neg_lvl = $time; initial begin #250; d = 1; #450; d = 0; end endmodule iverilog-12_0/ivtest/ivltests/specparam1.v000066400000000000000000000013351435245347300207670ustar00rootroot00000000000000module test(); specparam sp1 = 2'd1; specparam [1:0] sp2 = 2; specparam sp3 = 3.5; specify specparam sp4 = sp1; specparam [1:0] sp5 = sp2 + 1; specparam sp6 = sp3 + 1.0; endspecify reg pass = 1; initial begin $display("%b", sp1); if (($bits(sp1) != 2) || (sp1 !== 2'd1)) pass = 0; $display("%b", sp2); if (($bits(sp2) != 2) || (sp2 !== 2'd2)) pass = 0; $display("%f", sp3); if (sp3 != 3.5) pass = 0; $display("%b", sp4); if (($bits(sp4) != 2) || (sp4 !== 2'd1)) pass = 0; $display("%b", sp5); if (($bits(sp5) != 2) || (sp5 !== 2'd3)) pass = 0; $display("%f", sp6); if (sp6 != 4.5) pass = 0; if (pass) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/specparam2.v000066400000000000000000000006671435245347300207770ustar00rootroot00000000000000module test(); specparam sp1 = 1; specparam sp2 = 2; specparam [3:0] sp3 = 4'b0101; localparam lp1 = {sp2{1'b1}}; localparam lp2 = sp3[sp1 +: sp2]; reg pass = 1; initial begin $display("%b", lp1); if (($bits(lp1) != 2) || (lp1 !== 2'b11)) pass = 0; $display("%b", lp2); if (($bits(lp2) != 2) || (lp2 !== 2'b10)) pass = 0; if (pass) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sqrt32.v000066400000000000000000000137271435245347300201010ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: sqrt32.v,v 1.2 2007/08/30 01:25:29 stevewilliams Exp $" */ /* * This module approximates the square root of an unsigned 32bit * number. The algorithm works by doing a bit-wise binary search. * Starting from the most significant bit, the accumulated value * tries to put a 1 in the bit position. If that makes the square * too big for the input, the bit is left zero, otherwise it is set * in the result. This continues for each bit, decreasing in * significance, until all the bits are calculated or all the * remaining bits are zero. * * Since the result is an integer, this function really calculates * value of the expression: * * x = floor(sqrt(y)) * * where sqrt(y) is the exact square root of y and floor(N) is the * largest integer <= N. * * For 32bit numbers, this will never run more then 16 iterations, * which amounts to 16 clocks. */ module sqrt (input clk, output wire rdy, input reset, input [31:0] x, output reg [15:0] acc); //32 parameter ss=5; localparam w=1<= ((z + 1)*(z + 1))) begin $display("test=%d x=%d, y=%d ERROR: y is too small", idx, A, Z); $display("FAILED"); $finish; end end else begin $display ("Could not verify above number"); end end $display ("Running tests Amax=%d random input numbers", Amax); for (idx = 0 ; idx < Amax; idx = 1+ idx) begin A = $random; // A = A - ((A / Amax) * Amax); //this is needed only if <32 bit //A = idx; //sequential -- comment out to get random tests if (A < 1<<(w-1)) begin reset_dut; run_dut; //$display("%d: x=%d, y=%d", idx, A, Z); a = A; z = Z; if (a < (z *z)) begin $display("test=%d x=%d, y=%d ERROR:y is too big", idx, A, Z); $display("FAILED"); $finish; end if (z<65535) // at this number y*y overflows, so cannot test this way begin if (a >= ((z + 1)*(z + 1))) begin $display("test=%d x=%d, y=%d ERROR: y is too small", idx, A, Z); $display("FAILED"); $finish; end end else begin $display ("Could not verify above number"); end //$display("%d: x=%d, y=%d", idx, A, Z); if (idx%1000 == 0) $display("Finished %d tests", idx); end // if (A < Amax) begin end $display ("PASSED"); $finish; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/sqrt32synth.v000066400000000000000000000137341435245347300211650ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: sqrt32synth.v,v 1.2 2007/08/30 01:25:29 stevewilliams Exp $" */ /* * This module approximates the square root of an unsigned 32bit * number. The algorithm works by doing a bit-wise binary search. * Starting from the most significant bit, the accumulated value * tries to put a 1 in the bit position. If that makes the square * too big for the input, the bit is left zero, otherwise it is set * in the result. This continues for each bit, decreasing in * significance, until all the bits are calculated or all the * remaining bits are zero. * * Since the result is an integer, this function really calculates * value of the expression: * * x = floor(sqrt(y)) * * where sqrt(y) is the exact square root of y and floor(N) is the * largest integer <= N. * * For 32bit numbers, this will never run more then 16 iterations, * which amounts to 16 clocks. */ module sqrt (input clk, output wire rdy, input reset, input [31:0] x, output reg [15:0] acc); //32 parameter ss=5; localparam w=1<= ((z + 1)*(z + 1))) begin $display("test=%d x=%d, y=%d ERROR: y is too small", idx, A, Z); $display("FAILED"); $finish; end end else begin $display ("Could not verify above number"); end end $display ("Running tests Amax=%d random input numbers", Amax); for (idx = 0 ; idx < Amax; idx = 1+ idx) begin A = $random; // A = A - ((A / Amax) * Amax); //this is needed only if <32 bit //A = idx; //sequential -- comment out to get random tests if (A < 1<<(w-1)) begin reset_dut; run_dut; //$display("%d: x=%d, y=%d", idx, A, Z); a = A; z = Z; if (a < (z *z)) begin $display("test=%d x=%d, y=%d ERROR:y is too big", idx, A, Z); $display("FAILED"); $finish; end if (z<65535) // at this number y*y overflows, so cannot test this way begin if (a >= ((z + 1)*(z + 1))) begin $display("test=%d x=%d, y=%d ERROR: y is too small", idx, A, Z); $display("FAILED"); $finish; end end else begin $display ("Could not verify above number"); end //$display("%d: x=%d, y=%d", idx, A, Z); if (idx%1000 == 0) $display("Finished %d tests", idx); end // if (A < Amax) begin end $display ("PASSED"); $finish; end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/sscanf_u.v000066400000000000000000000007521435245347300205360ustar00rootroot00000000000000module top; reg [63:0] str; reg [31:0] in, ck, out; integer res; initial begin // To avoid embedded NULL bytes each byte must have a 1. in = 32'b000x100z_001z000x_101xxxzz_100z111x; ck = 32'b00001000_00100000_10100000_10001110; $sformat(str, "%u", in); res = $sscanf(str, "%u", out); if (res !== 1) $display("FAILED: $sscanf() returned %d", res); else if (ck !== out) $display("FAILED: %b !== %b", in, out); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sscanf_z.v000066400000000000000000000007041435245347300205400ustar00rootroot00000000000000module top; reg [63:0] str; reg [31:0] in, out; integer res; initial begin // To avoid embedded NULL bytes each byte must have an x or a 1 and a z. in = 32'b000x100z_001z000x_101xxxzz_100z111x; $sformat(str, "%z", in); res = $sscanf(str, "%z", out); if (res !== 1) $display("FAILED: $sscanf() returned %d", res); else if (in !== out) $display("FAILED: %b !== %b", in, out); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ssetclr1.v000066400000000000000000000031221435245347300204670ustar00rootroot00000000000000/* * In this example, the set and clr are both synchronous. This checks * that this complex case is handled correctly. */ module main; reg Q, clk, rst, set, clr; (* ivl_synthesis_on *) always@(posedge clk or posedge rst) begin if (rst) Q <= 1'b0; else if (clr) Q <= 1'b0; else if (set) Q <= 1'b1; else Q <= Q; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 0; set = 0; clr = 0; #1 rst = 1; #1 rst = 0; if (Q !== 0) begin $display("FAILED -- rst"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clk"); $finish; end #1 set = 1; #1 ; if (Q !== 0) begin $display("FAILED -- 1 set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 set"); $finish; end #1 clr = 1; #1 ; if (Q !== 1) begin $display("FAILED -- 1 clr+set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clr+set"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 2 clr+set"); $finish; end #1 set = 1; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 set+clr"); $finish; end #1 clr = 0; #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 set-clr"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/ssetclr2.v000066400000000000000000000031221435245347300204700ustar00rootroot00000000000000/* * In this example, the set and clr are both synchronous. This checks * that this complex case is handled correctly. */ module main; reg Q, clk, rst, set, clr; (* ivl_synthesis_on *) always@(posedge clk or posedge rst) begin if (rst) Q <= 1'b0; else if (set) Q <= 1'b1; else if (clr) Q <= 1'b0; else Q <= Q; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 0; set = 0; clr = 0; #1 rst = 1; #1 rst = 0; if (Q !== 0) begin $display("FAILED -- rst"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clk"); $finish; end #1 set = 1; #1 ; if (Q !== 0) begin $display("FAILED -- 1 set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 set"); $finish; end #1 clr = 1; #1 ; if (Q !== 1) begin $display("FAILED -- 1 clr+set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 clr+set"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 2 clr+set"); $finish; end #1 set = 0; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clr-set"); $finish; end #1 clr = 0; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 set-clr"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/ssetclr3.v000066400000000000000000000031011435245347300204660ustar00rootroot00000000000000/* * In this example, the set and clr are both synchronous. This checks * that this complex case is handled correctly. */ module main; reg Q, clk, rst, set, clr; (* ivl_synthesis_on *) always@(posedge clk or posedge rst) begin if (rst) Q <= 1'b0; else if (set) Q <= 1'b1; else if (clr) Q <= 1'b0; end (* ivl_synthesis_off *) initial begin clk = 0; rst = 0; set = 0; clr = 0; #1 rst = 1; #1 rst = 0; if (Q !== 0) begin $display("FAILED -- rst"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clk"); $finish; end #1 set = 1; #1 ; if (Q !== 0) begin $display("FAILED -- 1 set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 set"); $finish; end #1 clr = 1; #1 ; if (Q !== 1) begin $display("FAILED -- 1 clr+set (no clk)"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 1 clr+set"); $finish; end #1 clk = 1; #1 clk = 0; if (Q !== 1) begin $display("FAILED -- 2 clr+set"); $finish; end #1 set = 0; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 clr-set"); $finish; end #1 clr = 0; #1 clk = 1; #1 clk = 0; if (Q !== 0) begin $display("FAILED -- 1 set-clr"); $finish; end $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/sshortint_test.v000066400000000000000000000264501435245347300220340ustar00rootroot00000000000000// Eleven basic tests in here: // 1. shortint must be initialised before any initial or always block // 2. assignments to (signed) shortint with random numbers // 3. assignments to (signed) shortint with random values including X and Z // 4. converting unsigned integers to signed shortint // 5. converting signed integers to signed shortint // 6. converting integers including X and Z states to signed shortint // 7. trying signed sums (procedural, function, task and module) // 8. trying signed mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to signed shortint (signed extension) // 11. trying some concatenations from bytes to shortints module ms_add (input shortint signed a, b, output shortint signed sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter UMAX = 'h7fff; parameter MAX8 = 256; parameter LEN = 16; // variables used as golden references reg signed [LEN-1:0] ar; // holds numbers reg signed [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg signed [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // type assumed to be tested before hand byte signed pt1, pt2; // types to be tested shortint signed bu; // holds numbers shortint signed bu_xz; // 'x and 'z are attempted on this shortint signed bresult; // hold results from sums and mults shortint signed mcaresult; // wired to a module instance shortint signed mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // shortint 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation ms_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 16'b0 || bu_xz != 16'b0 || mcaresult !== 16'b0 || mabresult !== 16'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving shortint type with signed random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % UMAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to shortint: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type signed shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = $random % UMAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to shortint (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to signed shortint // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random} % 2*(UMAX+1); // full range as unsigned #1; force bu = ui; #1; if (bu !== ui[LEN-1:0]) begin $display ("FAILED - incorrect truncation from unsigned integer to shortint: %b", bu); $finish; end end release bu; // converting signed integers to signed shortints // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random % UMAX; #1; force bu = si; #1; if (bu !== si[LEN-1:0]) begin $display ("FAILED - incorrect truncation from signed integer to shortint: %b mismatchs %b", bu, si[LEN-1:0]); $finish; end end release bu; // converting signed integers having 'x 'z values into type signed shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si[LEN-1:0]); si = {si[31:LEN], ar_xz}; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to shortint: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying signed sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % UMAX; ar_xz = $random % UMAX; #1; bresult = bu + bu_xz; #1; if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed shortints: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // invoking shortint sum function if ( fs_sum (bu, bu_xz) !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed shortint in function"); $finish; end // invoking shortint sum task ts_sum (bu, bu_xz, bresult); if ( bresult !== s_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of signed shortint in task: %0d mismatchs %0d", bresult, s_sum(ar, ar_xz)); $finish; end // checking shortint sum from module if ( mcaresult !== s_sum(ar, ar_xz) || mabresult !== s_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of signed shortint from module"); $finish; end end // trying signed mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ($random % UMAX) << LEN/2; ar_xz = ($random % UMAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; // truncated multiplication #1; if ( bresult !== sh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of signed shortints (truncated)"); $finish; end #1; pt1 = $random; pt2 = $random; #1; bresult = pt1 * pt2; // shortint = byte x byte #1; if ( bresult !== s_mul(pt1, pt2) ) begin $display ("FAILED - incorrect multiplication of signed shortints for input bytes"); $finish; end // invoking shortint mult function (byte*byte) if ( fs_mul (pt1, pt2) !== s_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of signed bytes for a function returning signed shortint"); $finish; end // invoking shortint mult task (byte*byte) ts_mul (pt1, pt2, bresult); if ( bresult !== s_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of signed bytes in task returning signed shortint"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = $random % UMAX; ar_xz = $random % UMAX; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on signed shortints"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on signed shortints"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on signed shortints"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on signed shortints"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on signed shortints"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on signed shortints"); $finish; end end # 1; // signed small number to signed shorint for (i = 0; i < (1<|This is a test|"); $display("*|%s|", "This is a test"); $display("*|", "This is a test", "|"); $display(">| 65|"); $display("*|%d|", "A"); $display(">|16706|"); $display("*|%d|", "AB"); $display(">| 4276803|"); $display("*|%d|", "ABC"); $display(">|1094861636|"); $display("*|%d|", "ABCD"); $display(">|01000001|"); $display("*|%b|", "A"); $display(">|01000001010000100100001101000100|"); $display("*|%b|", "ABCD"); $display(">|01000001010000100100001101000100010010000100100101001010010010110100110001001101010011100100111101010000010100010101001001010011|"); $display("*|%b|", "ABCDHIJKLMNOPQRS"); $display(">|41|"); $display("*|%h|", "A"); $display(">|41424344|"); $display("*|%h|", "ABCD"); $display(">|4142434448494a4b4c4d4e4f50515253|"); $display("*|%h|", "ABCDHIJKLMNOPQRS"); end endmodule iverilog-12_0/ivtest/ivltests/string11.v000066400000000000000000000002431435245347300204000ustar00rootroot00000000000000module main; reg [31:0] bytes; initial begin bytes = "\101\102\103\n"; $write("bytes=%h\n", bytes); $finish(0); end endmodule // main iverilog-12_0/ivtest/ivltests/string12.v000066400000000000000000000002131435245347300203760ustar00rootroot00000000000000module top; initial begin if ("this matches" == "this\ matches") $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/string2.v000066400000000000000000000020051435245347300203160ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* This tests the printing of a string stored in a reg. */ module main; reg [8*6:1] foo; initial begin foo = "PASSED"; $display("%s", foo); end endmodule // main iverilog-12_0/ivtest/ivltests/string3.v000066400000000000000000000022441435245347300203240ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* This tests the printing of a string stored in a reg, with leading blanks. */ module main; reg [8*7:1] foo; reg [7:0] tmp; initial begin foo = "PASSED"; tmp = foo[8*7:8*6+1]; if (tmp !== 8'h00) begin $display("FAILED -- high bits are %b", tmp); $finish; end $display("%s", foo); end endmodule // main iverilog-12_0/ivtest/ivltests/string4.v000066400000000000000000000027661435245347300203360ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - assign a string in a function // // This test was contributed via forwarding on the geda netlist. I don't // know who actually wrote it - that isn't obvious from the copy of email // I eventually received - SDW // module test(); wire [31:0] A; reg [31:0] B; function [31:0] message; input [1:0] reg_num; begin message = (reg_num == 2'b00) ? "Mes0": (reg_num == 2'b01) ? "Mes1": (reg_num == 2'b10) ? "Mes2": "Mes3"; end endfunction assign A = "hi"; initial begin B = "ho"; #1; $display ("%s", A); $display ("%s", message(1)); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/string5.v000066400000000000000000000017361435245347300203330ustar00rootroot00000000000000/* * Copyright (c) 2001 Philip Blundell * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module m; task t; input [255:0] s; begin $display("%s", s); end endtask initial begin t("Hello world of Verilog"); end endmodule iverilog-12_0/ivtest/ivltests/string7.v000066400000000000000000000040551435245347300203320ustar00rootroot00000000000000/* * Copyright (c) 2002 Tom Verbeure * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; integer myInt; reg [39:0] myReg40; reg [0:39] myReg40r; reg [0:38] myReg39r; reg [13:0] myReg14; reg [7:0] myReg8; initial begin $display("============================ myReg8 = 65"); myReg8 = 65; $display(">|A|"); $display("*|%s|", myReg8); $display("============================ myReg40 = \"12345\""); myReg40 = "12345"; $display(">|12345|"); $display("*|%s|", myReg40); $display(">|5|"); $display("*|%s|", myReg40[7:0]); $display("============================ myReg40r = \"12345\""); myReg40r = "12345"; $display(">|12345|"); $display("*|%s|", myReg40r); $display(">|1|"); $display("*|%s|", myReg40r[0:7]); $display("============================ myReg39r = \"12345\""); myReg39r = "12345"; $display(">|12345|"); $display("*|%s|", myReg39r); $display(">|b|"); $display("*|%s|", myReg39r[0:7]); $display("============================ myReg14 = 65"); myReg14 = 65; $display(">| A|"); $display("*|%s|", myReg14); $display("============================ myReg14 = 33*356+65"); myReg14 = 33*256 + 65; $display(">|!A|"); $display("*|%s|", myReg14); $display("============================ myInt = 65"); myInt = 65; $display(">| A|"); $display("*|%s|", myInt); end endmodule iverilog-12_0/ivtest/ivltests/string8.v000066400000000000000000000023471435245347300203350ustar00rootroot00000000000000/* * Copyright (c) 2002 Tom Verbeure * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [13:0] myReg14; reg [15:0] myReg16; initial begin $display("============================ myReg14 = 33*256+65"); myReg14 = 33*256 + 65; $display(">|!A|"); $display("*|%s|", myReg14); $display(">|!|"); $display("*|%s|", myReg14[13:8]); $display("============================ myReg16 = 33*512+65*2"); myReg16 = 33*512 + 65*2; $display(">|!A|"); $display("*|%s|", myReg16[14:1]); end endmodule iverilog-12_0/ivtest/ivltests/string9.v000066400000000000000000000037511435245347300203360ustar00rootroot00000000000000/* * Copyright (c) 2002 Tom Verbeure * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; integer myInt; reg [39:0] myReg40; reg [0:39] myReg40r; reg [0:38] myReg39r; reg [13:0] myReg14; reg [7:0] myReg8; initial begin $display("============================ myReg8 = 65"); myReg8 = 65; $display(">|A|"); $display("*|%c|", myReg8); $display("============================ myReg40 = \"12345\""); myReg40 = "12345"; $display(">|5|"); $display("*|%c|", myReg40); $display(">|5|"); $display("*|%s|", myReg40[7:0]); $display("============================ myReg40r = \"12345\""); myReg40r = "12345"; $display(">|5|"); $display("*|%c|", myReg40r); $display(">|1|"); $display("*|%c|", myReg40r[0:7]); $display("============================ myReg39r = \"12345\""); myReg39r = "12345"; $display(">|5|"); $display("*|%c|", myReg39r); $display(">|b|"); $display("*|%c|", myReg39r[0:7]); $display("============================ myReg14 = 33*256+65"); myReg14 = 33*256 + 65; $display(">|A|"); $display("*|%c|", myReg14); $display(">|!|"); $display("*|%c|", myReg14[13:8]); $display("============================ myInt = 66*256 + 65"); myInt = 66*256 + 65; $display(">|A|"); $display("*|%c|", myInt); end endmodule iverilog-12_0/ivtest/ivltests/string_events.v000066400000000000000000000012511435245347300216220ustar00rootroot00000000000000module test(); string str; always @(str) begin $display("str = %s", str); end task automatic test_task(input integer delay, input string str1, input string str2); string str; fork begin @(str) $display("str%0d = %s", delay, str); @(str) $display("str%0d = %s", delay, str); end begin #delay; #2 str = str1; #2 str = str1; #2 str = str2; end join endtask initial begin #1 str = "hello"; #1 str = "hello"; #1 str = "world"; fork test_task(1, "hello1", "world1"); test_task(2, "hello2", "world2"); join fork test_task(1, "world1", "hello1"); test_task(2, "world2", "hello2"); join #1 $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/string_index.v000066400000000000000000000022771435245347300214360ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests accessing individual characters in a string module string_index(); initial begin int i; string str = "that is a test string"; for(i = 0; i < $size(str); ++i) begin if(str[i] == "t") str[i] = "w"; end if(str != "whaw is a wesw swring") begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/struct1.v000066400000000000000000000011071435245347300203350ustar00rootroot00000000000000module main; struct packed { logic [7:0] high; logic [7:0] low; } word1, word2; initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end word2 = word1; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct10.v000066400000000000000000000014621435245347300204210ustar00rootroot00000000000000module main; struct packed { bit [7:0][7:0] a; bit [15:0] b; } foo; struct packed { bit [0:7] [7:0] a; bit [0:15] b; } bar; initial begin foo = '0; foo.a[2:1] = 16'h1234; foo.a[5] = 8'h42; foo.a[7] = '1; foo.a[7][1:0] = '0; foo.b = '1; foo.b[1:0] = '0; $display("foo = %h", foo); bar = '0; bar.a[5:6] = 16'h1234; bar.a[2] = 8'h42; bar.a[0] = '1; bar.a[0][1:0] = '0; bar.b = '1; bar.b[14:15] = '0; $display("bar = %h", bar); if (foo !== 80'hFC00_4200_0012_3400_FFFC) begin $display("FAILED -- foo=%h", foo); $finish; end if (foo !== bar) begin $display("FAILED -- bar != foo"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct2.v000066400000000000000000000014131435245347300203360ustar00rootroot00000000000000module main; // Declare word1 as a VARIABLE struct packed { logic [7:0] high; logic [7:0] low; } word1; // Declare word2 as a NET wire struct packed { logic [7:0] high; logic [7:0] low; } word2; assign word2 = word1; initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end #1 /* Make sure word2 assign propagates */; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct3.v000066400000000000000000000014671435245347300203500ustar00rootroot00000000000000module main; // Declare word1 as a VARIABLE struct packed { logic [7:0] high; logic [7:0] low; } word1; // Declare word2 as a NET wire struct packed { logic [7:0] high; logic [7:0] low; } word2; assign word2.high = word1.high; assign word2.low = word1.low; initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end #1 /* Make sure word2 assign propagates */; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct3b.v000066400000000000000000000021471435245347300205060ustar00rootroot00000000000000module main; // Declare word1 as a VARIABLE struct packed { logic [7:0] high; logic [7:0] low; } word1; // Declare word2, word3 as a NET wire struct packed { logic [7:0] high; logic [7:0] low; } word2, word3; assign word2.high = word1.high; assign word2.low = word1.low; assign {word3.high, word3.low} = {word1.low, word1.high}; initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end #1 /* Make sure word2 assign propagates */; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end /* and also for word3 */ if (word3.low !== 8'haa || word3.high !== 8'h55) begin $display("FAILED: word3 = %h, word3.high = %h, word3.low = %h (should be reverse)", word1, word3.high, word3.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct4.v000066400000000000000000000015171435245347300203450ustar00rootroot00000000000000module main; // Declare word1 as a VARIABLE struct packed { logic [7:0] high; logic [7:0] low; } word1; // Declare word2 as a VARIABLE struct packed { logic [7:0] high; logic [7:0] low; } word2; always @(word1) begin word2.high = word1.high; word2.low = word1.low; end initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end #1 /* Make sure word2 assign propagates */; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct5.v000066400000000000000000000014551435245347300203470ustar00rootroot00000000000000module main; typedef struct packed { logic [7:0] high; logic [7:0] low; } word_t; // Declare word1 as a VARIABLE word_t word1; // Declare word2 as a VARIABLE word_t word2; always @(word1) begin word2.high = word1.high; word2.low = word1.low; end initial begin word1 = 16'haa_55; if (word1.high !== 8'haa || word1.low !== 8'h55) begin $display("FAILED: word1 = %h, word1.high = %h, word1.low = %h", word1, word1.high, word1.low); $finish; end #1 /* Make sure word2 assign propagates */; if (word2.high !== 8'haa || word2.low !== 8'h55) begin $display("FAILED: word2 = %h, word2.high = %h, word2.low = %h", word1, word2.high, word2.low); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct6.v000066400000000000000000000007431435245347300203470ustar00rootroot00000000000000// This tests that the individual bits of a uwire are checked for // double-driving individually. The code below uses a packed struct // to represent individual bits. module test; struct packed { logic [15:0] hig; logic [15:0] low; } foo; assign foo.low = 'haaaa; assign foo.hig = 'h5555; initial begin #1 if (foo !== 'h5555aaaa) begin $display("FAILED -- foo=%h", foo); $finish; end $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/struct7.v000066400000000000000000000017411435245347300203470ustar00rootroot00000000000000module main; struct packed { logic [1:0][7:0] p; } val; logic [1:0][7:0] arr; initial begin arr[0] = 'haa; arr[1] = 'h55; $display("arr = %h", arr); if (arr !== 'h55_aa) begin $display("FAILED"); $finish; end if (arr[0] !== 'haa) begin $display("FAILED -- arr[0]=%h", arr[0]); $finish; end if (arr[1] !== 'h55) begin $display("FAILED -- arr[1]=%h", arr[1]); $finish; end val.p[0] = 'haa; val.p[1] = 'h55; $display("val.p = %h", val.p); $display("val = %h", val); if (val !== 'h55_aa) begin $display("FAILED"); $finish; end if (val.p !== 'h55_aa) begin $display("FAILED"); $finish; end if (val.p[0] !== 'haa) begin $display("FAILED -- val.p[0]=%h", val.p[0]); $finish; end if (val.p[1] !== 'h55) begin $display("FAILED -- val.p[1]=%h", val.p[1]); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct8.v000066400000000000000000000010721435245347300203450ustar00rootroot00000000000000module main; wire struct packed { logic m1; logic [7:0] m8; } foo; assign foo = {1'b1, 8'ha5}; struct packed { logic [3:0] m4; logic [7:0] m8; } bar; initial begin #1 /* wait for logic to settle. */; bar.m8 <= foo.m8[7:0]; bar.m4 <= foo.m8[7:4]; #1 $display("bar8=%h, bar4=%h", bar.m8, bar.m4); if (bar.m8 !== 8'ha5) begin $display("FAILED"); $finish; end if (bar.m4 !== 4'ha) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct9.v000066400000000000000000000007221435245347300203470ustar00rootroot00000000000000 module main; wire [4:0] foo; struct packed { logic [3:0] bar4; logic [3:0] bar0; } bar; assign foo = bar.bar0; initial begin bar = 'h5a; #1 if (bar.bar0 !== 4'ha || bar.bar4 != 4'h5) begin $display("FAILED -- bar.bar0=%b, bar.bar4=%b", bar.bar0, bar.bar4); $finish; end if (foo !== 5'h0a) begin $display("FAILED -- foo=%b", foo); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct_invalid_member.v000066400000000000000000000004711435245347300233140ustar00rootroot00000000000000// Check that structs with invalid member declarations are deteceted, report an // error and do not cause a crash module test; struct packed { logic x; // OK logic y, z; // OK logic bit; // Invalid logic a b c; // Invalid logc d; // Invalid e; // Invalid } s; endmodule iverilog-12_0/ivtest/ivltests/struct_line_info.v000066400000000000000000000006311435245347300222770ustar00rootroot00000000000000// Checks that the line and file information is correctly attached to a struct // data type and will be used when printing an error message about the struct. module test; // Direct struct packed { real r; } s1; // Used in a struct typedef struct packed { real r; } struct1_type; // Used as a signal type typedef struct packed { struct1_type s; real r; } struct2_type; struct2_type s2; endmodule iverilog-12_0/ivtest/ivltests/struct_member_signed.v000066400000000000000000000013151435245347300231350ustar00rootroot00000000000000// Tests that the signedness for struct members is handled correctly module test; struct packed { logic [15:0] x; logic signed [15:0] y; } s; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED: ", `"x`"); \ failed = 1'b1; \ end initial begin s.x = -1; s.y = -1; `check(!$is_signed(s.x)); `check($is_signed(s.y)); // These evaluate as signed `check($signed(s.x) < 0); `check(s.y < 0); // These all evaluate as unsigned `check(s.x > 0); `check(s.y[15:0] > 0) `check({s.y} > 0) `check($unsigned(s.y) > 0) `check(s.y > 16'h0) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/struct_packed_array.v000066400000000000000000000033441435245347300227660ustar00rootroot00000000000000module main; typedef struct packed { logic [3:0] high; logic [3:0] low; } word; typedef word [1:0] dword; dword foo; int idx; initial begin foo[0].low = 1; foo[0].high = 2; foo[1].low = 3; foo[1].high = 4; $display("foo = %h", foo); if (foo !== 16'h4321) begin $display("FAILED -- foo=%h", foo); $finish; end $display("foo[0] = %h", foo[0]); if (foo[0] !== 8'h21) begin $display("FAILED -- foo[0]=%h", foo[0]); $finish; end $display("foo[1] = %h", foo[1]); if (foo[1] !== 8'h43) begin $display("FAILED -- foo[1]=%h", foo[1]); $finish; end $display("foo[0].low = %h", foo[0].low); if (foo[0].low !== 4'h1) begin $display("FAILED -- foo[0].low=%h", foo[0].low); $finish; end $display("foo[0].high = %h", foo[0].high); if (foo[0].high !== 4'h2) begin $display("FAILED -- foo[0].high=%h", foo[0].high); $finish; end $display("foo[1].low = %h", foo[1].low); if (foo[1].low !== 4'h3) begin $display("FAILED -- foo[1].low=%h", foo[1].low); $finish; end $display("foo[1].high = %h", foo[1].high); if (foo[1].high !== 4'h4) begin $display("FAILED -- foo[1].high=%h", foo[1].high); $finish; end idx = 0; $display("foo[idx=0].low = %h", foo[idx].low); if (foo[idx].low !== 4'h1) begin $display("FAILED -- foo[0].low=%h", foo[idx].low); $finish; end idx = 1; $display("foo[idx=1].high = %h", foo[idx].high); if (foo[idx].high !== 8'h4) begin $display("FAILED -- foo[1].high=%h", foo[idx].high); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct_packed_array2.v000066400000000000000000000034021435245347300230430ustar00rootroot00000000000000module main; typedef struct packed { logic [3:0] high; logic [3:0] low; } word; typedef word [1:0] dword; wire dword foo; int idx; assign foo[0].low = 1; assign foo[0].high = 2; assign foo[1].low = 3; assign foo[1].high = 4; initial begin #1 $display("foo = %h", foo); if (foo !== 16'h4321) begin $display("FAILED -- foo=%h", foo); $finish; end $display("foo[0] = %h", foo[0]); if (foo[0] !== 8'h21) begin $display("FAILED -- foo[0]=%h", foo[0]); $finish; end $display("foo[1] = %h", foo[1]); if (foo[1] !== 8'h43) begin $display("FAILED -- foo[1]=%h", foo[1]); $finish; end $display("foo[0].low = %h", foo[0].low); if (foo[0].low !== 4'h1) begin $display("FAILED -- foo[0].low=%h", foo[0].low); $finish; end $display("foo[0].high = %h", foo[0].high); if (foo[0].high !== 4'h2) begin $display("FAILED -- foo[0].high=%h", foo[0].high); $finish; end $display("foo[1].low = %h", foo[1].low); if (foo[1].low !== 4'h3) begin $display("FAILED -- foo[1].low=%h", foo[1].low); $finish; end $display("foo[1].high = %h", foo[1].high); if (foo[1].high !== 4'h4) begin $display("FAILED -- foo[1].high=%h", foo[1].high); $finish; end idx = 0; $display("foo[idx=0].low = %h", foo[idx].low); if (foo[idx].low !== 4'h1) begin $display("FAILED -- foo[0].low=%h", foo[idx].low); $finish; end idx = 1; $display("foo[idx=1].high = %h", foo[idx].high); if (foo[idx].high !== 8'h4) begin $display("FAILED -- foo[1].high=%h", foo[idx].high); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/struct_packed_darray_fail.v000066400000000000000000000003071435245347300241210ustar00rootroot00000000000000// Check that declaring a dynamic array typed member in a packed struct is an // error. module test; struct packed { int x[]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/struct_packed_queue_fail.v000066400000000000000000000002751435245347300237670ustar00rootroot00000000000000// Check that declaring a queue typed member in a packed struct is an error. module test; struct packed { int x[$]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/struct_packed_sysfunct.v000066400000000000000000000014371435245347300235270ustar00rootroot00000000000000// This tests system functions available for packed structures // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test; typedef struct packed { logic [7:0] high; logic [7:0] low; } word_t; // Declare word0 as a VARIABLE word_t word0; // error counter bit err = 0; initial begin if ($bits(word0 ) !== 16) begin $display("FAILED -- $bits(word0 ) = %d", $bits(word0 )); err=1; end if ($bits(word0.high) !== 8) begin $display("FAILED -- $bits(word0.high) = %d", $bits(word0.high)); err=1; end if ($bits(word0.low ) !== 8) begin $display("FAILED -- $bits(word0.low ) = %d", $bits(word0.low )); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/struct_packed_sysfunct2.v000066400000000000000000000013231435245347300236030ustar00rootroot00000000000000// Check that the signedness of a struct member is handled correctly when passed // to a system function module test; bit failed = 1'b0; struct packed { int s; int unsigned u; } x; int s; int unsigned u; logic [16*8-1:0] s1; logic [16*8-1:0] s2; initial begin u = -10; s = -20; x.u = u; x.s = s; $swrite(s1, s); $swrite(s2, x.s); if (s1 != s2) begin failed = 1'b1; $display("FAILED. Expected %s, got %s.", s1, s2); end $swrite(s1, u); $swrite(s2, x.u); if (s1 != s2) begin failed = 1'b1; $display("FAILED. Expected %s, got %s.", s1, s2); end if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/struct_packed_uarray_fail.v000066400000000000000000000003121435245347300241360ustar00rootroot00000000000000// Check that declaring an unpacked array typed member in a packed struct is an // error. module test; struct packed { int x[2]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/struct_packed_value_list.v000066400000000000000000000025571435245347300240240ustar00rootroot00000000000000// This tests assigning value lists to packed structures // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test; typedef struct packed { logic [7:0] high; logic [7:0] low; } word_t; // Declare word* as a VARIABLE word_t word0, word1, word2, word3, word4, word5; // error counter bit err = 0; // access to structure elements assign word0 = '{2, 3}; assign word1 = '{high:5, low:6}; assign word2 = '{low:7, high:8}; assign word3 = '{default:13}; assign word4 = '{high:8'haa, default:1}; assign word5 = '{high:9'h000, low:9'h1ff}; initial begin #1; // check for correctness if (word0 !== 16'b00000010_00000011) begin $display("FAILED -- word0 = 'b%b", word0); err=1; end if (word1 !== 16'b00000101_00000110) begin $display("FAILED -- word1 = 'b%b", word1); err=1; end if (word2 !== 16'b00001000_00000111) begin $display("FAILED -- word2 = 'b%b", word2); err=1; end if (word3 !== 16'b00001101_00001101) begin $display("FAILED -- word3 = 'b%b", word3); err=1; end if (word4 !== 16'b10101010_00000001) begin $display("FAILED -- word4 = 'b%b", word4); err=1; end if (word5 !== 16'b00000000_11111111) begin $display("FAILED -- word5 = 'b%b", word5); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/struct_packed_write_read.v000066400000000000000000000123251435245347300237740ustar00rootroot00000000000000// This tests unalligned write/read access to packed structures // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test; typedef struct packed { logic [7:0] high; logic [7:0] low; } word_t; // Declare word* as a VARIABLE word_t word_se0, word_se1, word_se2, word_se3; word_t word_sw0, word_sw1, word_sw2, word_sw3; word_t word_sp0, word_sp1, word_sp2, word_sp3; word_t word_ep0, word_ep1, word_ep2, word_ep3; // error counter bit err = 0; // access to structure elements assign word_se1.high = {8+0{1'b1}}; assign word_se1.low = {8+0{1'b0}}; assign word_se2.high = {8+1{1'b1}}; assign word_se2.low = {8+1{1'b0}}; assign word_se3.high = {8-1{1'b1}}; assign word_se3.low = {8-1{1'b0}}; // access to whole structure assign word_sw1 = {16+0{1'b1}}; assign word_sw2 = {16+1{1'b1}}; assign word_sw3 = {16-1{1'b1}}; // access to parts of structure elements assign word_ep1.high [3:0] = {4+0{1'b1}}; assign word_ep1.low [3:0] = {4+0{1'b0}}; assign word_ep2.high [3:0] = {4+1{1'b1}}; assign word_ep2.low [3:0] = {4+1{1'b0}}; assign word_ep3.high [3:0] = {4-1{1'b1}}; assign word_ep3.low [3:0] = {4-1{1'b0}}; // access to parts of the whole structure assign word_sp1 [11:4] = {8+0{1'b1}}; assign word_sp2 [11:4] = {8+1{1'b1}}; assign word_sp3 [11:4] = {8-1{1'b1}}; initial begin #1; // access to structure elements if (word_se0 !== 16'bxxxxxxxx_xxxxxxxx) begin $display("FAILED -- word_se0 = 'b%b", word_se0 ); err=1; end if (word_se1 !== 16'b11111111_00000000) begin $display("FAILED -- word_se1 = 'b%b", word_se1 ); err=1; end if (word_se1.high !== 8'b11111111 ) begin $display("FAILED -- word_se1.high = 'b%b", word_se1.high); err=1; end if (word_se1.low !== 8'b00000000 ) begin $display("FAILED -- word_se1.low = 'b%b", word_se1.low ); err=1; end if (word_se2 !== 16'b11111111_00000000) begin $display("FAILED -- word_se2 = 'b%b", word_se2 ); err=1; end if (word_se2.high !== 8'b11111111 ) begin $display("FAILED -- word_se2.high = 'b%b", word_se2.high); err=1; end if (word_se2.low !== 8'b00000000 ) begin $display("FAILED -- word_se2.low = 'b%b", word_se2.low ); err=1; end if (word_se3 !== 16'b01111111_00000000) begin $display("FAILED -- word_se3 = 'b%b", word_se3 ); err=1; end if (word_se3.high !== 8'b01111111 ) begin $display("FAILED -- word_se3.high = 'b%b", word_se3.high); err=1; end if (word_se3.low !== 8'b00000000 ) begin $display("FAILED -- word_se3.low = 'b%b", word_se3.low ); err=1; end // access to whole structure if (word_sw0 !== 16'bxxxxxxxx_xxxxxxxx) begin $display("FAILED -- word_sw0 = 'b%b", word_sw0 ); err=1; end if (word_sw1 !== 16'b11111111_11111111) begin $display("FAILED -- word_sw1 = 'b%b", word_sw1 ); err=1; end if (word_sw2 !== 16'b11111111_11111111) begin $display("FAILED -- word_sw2 = 'b%b", word_sw2 ); err=1; end if (word_sw3 !== 16'b01111111_11111111) begin $display("FAILED -- word_sw3 = 'b%b", word_sw3 ); err=1; end // access to parts of structure elements if (word_ep0 !== 16'bxxxxxxxx_xxxxxxxx) begin $display("FAILED -- word_ep0 = 'b%b", word_ep0 ); err=1; end if (word_ep1 !== 16'bxxxx1111_xxxx0000) begin $display("FAILED -- word_ep1 = 'b%b", word_ep1 ); err=1; end if (word_ep1.high !== 8'bxxxx1111 ) begin $display("FAILED -- word_ep1.high = 'b%b", word_ep1.high); err=1; end if (word_ep1.low !== 8'bxxxx0000 ) begin $display("FAILED -- word_ep1.low = 'b%b", word_ep1.low ); err=1; end if (word_ep2 !== 16'bxxxx1111_xxxx0000) begin $display("FAILED -- word_ep2 = 'b%b", word_ep2 ); err=1; end if (word_ep2.high !== 8'bxxxx1111 ) begin $display("FAILED -- word_ep2.high = 'b%b", word_ep2.high); err=1; end if (word_ep2.low !== 8'bxxxx0000 ) begin $display("FAILED -- word_ep2.low = 'b%b", word_ep2.low ); err=1; end if (word_ep3 !== 16'bxxxx0111_xxxx0000) begin $display("FAILED -- word_ep3 = 'b%b", word_ep3 ); err=1; end if (word_ep3.high !== 8'bxxxx0111 ) begin $display("FAILED -- word_ep3.high = 'b%b", word_ep3.high); err=1; end if (word_ep3.low !== 8'bxxxx0000 ) begin $display("FAILED -- word_ep3.low = 'b%b", word_ep3.low ); err=1; end // access to parts of the whole structure if (word_sp0 !== 16'bxxxxxxxx_xxxxxxxx) begin $display("FAILED -- word_sp0 = 'b%b", word_sp0 ); err=1; end if (word_sp1 !== 16'bxxxx1111_1111xxxx) begin $display("FAILED -- word_sp1 = 'b%b", word_sp1 ); err=1; end if (word_sp2 !== 16'bxxxx1111_1111xxxx) begin $display("FAILED -- word_sp2 = 'b%b", word_sp2 ); err=1; end if (word_sp3 !== 16'bxxxx0111_1111xxxx) begin $display("FAILED -- word_sp3 = 'b%b", word_sp3 ); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/struct_packed_write_read2.v000066400000000000000000000123511435245347300240550ustar00rootroot00000000000000// This tests unalligned write/read access to packed structures // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test; typedef struct packed { logic [7:0] high; logic [7:0] low; } word_t; // Declare word* as a VARIABLE wire word_t word_se0, word_se1, word_se2, word_se3; wire word_t word_sw0, word_sw1, word_sw2, word_sw3; wire word_t word_sp0, word_sp1, word_sp2, word_sp3; wire word_t word_ep0, word_ep1, word_ep2, word_ep3; // error counter bit err = 0; // access to structure elements assign word_se1.high = {8+0{1'b1}}; assign word_se1.low = {8+0{1'b0}}; assign word_se2.high = {8+1{1'b1}}; assign word_se2.low = {8+1{1'b0}}; assign word_se3.high = {8-1{1'b1}}; assign word_se3.low = {8-1{1'b0}}; // access to whole structure assign word_sw1 = {16+0{1'b1}}; assign word_sw2 = {16+1{1'b1}}; assign word_sw3 = {16-1{1'b1}}; // access to parts of structure elements assign word_ep1.high [3:0] = {4+0{1'b1}}; assign word_ep1.low [3:0] = {4+0{1'b0}}; assign word_ep2.high [3:0] = {4+1{1'b1}}; assign word_ep2.low [3:0] = {4+1{1'b0}}; assign word_ep3.high [3:0] = {4-1{1'b1}}; assign word_ep3.low [3:0] = {4-1{1'b0}}; // access to parts of the whole structure assign word_sp1 [11:4] = {8+0{1'b1}}; assign word_sp2 [11:4] = {8+1{1'b1}}; assign word_sp3 [11:4] = {8-1{1'b1}}; initial begin #1; // access to structure elements if (word_se0 !== 16'bzzzzzzzz_zzzzzzzz) begin $display("FAILED -- word_se0 = 'b%b", word_se0 ); err=1; end if (word_se1 !== 16'b11111111_00000000) begin $display("FAILED -- word_se1 = 'b%b", word_se1 ); err=1; end if (word_se1.high !== 8'b11111111 ) begin $display("FAILED -- word_se1.high = 'b%b", word_se1.high); err=1; end if (word_se1.low !== 8'b00000000 ) begin $display("FAILED -- word_se1.low = 'b%b", word_se1.low ); err=1; end if (word_se2 !== 16'b11111111_00000000) begin $display("FAILED -- word_se2 = 'b%b", word_se2 ); err=1; end if (word_se2.high !== 8'b11111111 ) begin $display("FAILED -- word_se2.high = 'b%b", word_se2.high); err=1; end if (word_se2.low !== 8'b00000000 ) begin $display("FAILED -- word_se2.low = 'b%b", word_se2.low ); err=1; end if (word_se3 !== 16'b01111111_00000000) begin $display("FAILED -- word_se3 = 'b%b", word_se3 ); err=1; end if (word_se3.high !== 8'b01111111 ) begin $display("FAILED -- word_se3.high = 'b%b", word_se3.high); err=1; end if (word_se3.low !== 8'b00000000 ) begin $display("FAILED -- word_se3.low = 'b%b", word_se3.low ); err=1; end // access to whole structure if (word_sw0 !== 16'bzzzzzzzz_zzzzzzzz) begin $display("FAILED -- word_sw0 = 'b%b", word_sw0 ); err=1; end if (word_sw1 !== 16'b11111111_11111111) begin $display("FAILED -- word_sw1 = 'b%b", word_sw1 ); err=1; end if (word_sw2 !== 16'b11111111_11111111) begin $display("FAILED -- word_sw2 = 'b%b", word_sw2 ); err=1; end if (word_sw3 !== 16'b01111111_11111111) begin $display("FAILED -- word_sw3 = 'b%b", word_sw3 ); err=1; end // access to parts of structure elements if (word_ep0 !== 16'bzzzzzzzz_zzzzzzzz) begin $display("FAILED -- word_ep0 = 'b%b", word_ep0 ); err=1; end if (word_ep1 !== 16'bzzzz1111_zzzz0000) begin $display("FAILED -- word_ep1 = 'b%b", word_ep1 ); err=1; end if (word_ep1.high !== 8'bzzzz1111 ) begin $display("FAILED -- word_ep1.high = 'b%b", word_ep1.high); err=1; end if (word_ep1.low !== 8'bzzzz0000 ) begin $display("FAILED -- word_ep1.low = 'b%b", word_ep1.low ); err=1; end if (word_ep2 !== 16'bzzzz1111_zzzz0000) begin $display("FAILED -- word_ep2 = 'b%b", word_ep2 ); err=1; end if (word_ep2.high !== 8'bzzzz1111 ) begin $display("FAILED -- word_ep2.high = 'b%b", word_ep2.high); err=1; end if (word_ep2.low !== 8'bzzzz0000 ) begin $display("FAILED -- word_ep2.low = 'b%b", word_ep2.low ); err=1; end if (word_ep3 !== 16'bzzzz0111_zzzz0000) begin $display("FAILED -- word_ep3 = 'b%b", word_ep3 ); err=1; end if (word_ep3.high !== 8'bzzzz0111 ) begin $display("FAILED -- word_ep3.high = 'b%b", word_ep3.high); err=1; end if (word_ep3.low !== 8'bzzzz0000 ) begin $display("FAILED -- word_ep3.low = 'b%b", word_ep3.low ); err=1; end // access to parts of the whole structure if (word_sp0 !== 16'bzzzzzzzz_zzzzzzzz) begin $display("FAILED -- word_sp0 = 'b%b", word_sp0 ); err=1; end if (word_sp1 !== 16'bzzzz1111_1111zzzz) begin $display("FAILED -- word_sp1 = 'b%b", word_sp1 ); err=1; end if (word_sp2 !== 16'bzzzz1111_1111zzzz) begin $display("FAILED -- word_sp2 = 'b%b", word_sp2 ); err=1; end if (word_sp3 !== 16'bzzzz0111_1111zzzz) begin $display("FAILED -- word_sp3 = 'b%b", word_sp3 ); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/struct_signed.v000066400000000000000000000020251435245347300216050ustar00rootroot00000000000000// Tests that packed structs can have signed/unsigned modifier and that signed // packed structs when used as a primary behave correctly. module test; // Unsigned by default struct packed { logic [15:0] x; } s1; // Explicitly unsigned struct packed unsigned { logic [15:0] x; } s2; // Explicitly signed struct packed signed { logic [15:0] x; } s3; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED: ", `"x`"); \ failed = 1'b1; \ end initial begin s1 = -1; s2 = -1; s3 = -1; `check(!$is_signed(s1)); `check(!$is_signed(s2)); `check($is_signed(s3)); // These evaluate as signed `check($signed(s1) < 0); `check($signed(s2) < 0); `check(s3 < 0); // These all evaluate as unsigned `check(s1 > 0); `check(s2 > 0); `check(s3.x > 0) `check(s3[15:0] > 0) `check({s3} > 0) `check($unsigned(s3) > 0) `check(s3 > 16'h0) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/supply1.v000066400000000000000000000023301435245347300203440ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This sample tests that the supply0 and supply1 nets take on * the proper initial value. */ module test; supply0 gnd; supply1 vdd; initial begin #1; if (gnd !== 0) begin $display("FAILED -- gnd == %b", gnd); $finish; end if (vdd !== 1) begin $display("FAILED -- vdd == %b", vdd); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/supply2.v000066400000000000000000000026131435245347300203510ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This sample tests that the supply0 and supply1 nets take on * the proper initial value. This adds to the supply1 test some * constant drivers that could tickle constant propagation bugs. */ module test; supply0 gnd; supply1 vdd; // These should drop away as meaningless. assign gnd = 1; assign vdd = 0; initial begin #1 if (gnd !== 0) begin $display("FAILED -- gnd == %b", gnd); $finish; end if (vdd !== 1) begin $display("FAILED -- vdd == %b", vdd); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv-2val-nets.v000066400000000000000000000023361435245347300211760ustar00rootroot00000000000000// This tests part selects of 2-value logic vectors through // module ports. This is not supported in SystemVerilog, but // we expect it to work as an Icarus Verilog extension, as // long as all the bits of the 2-value are singly driven. module main; bit [5:0] a, b; wire bit [6:0] sum; wire bit c2, c4; sub b10 (.c_i(1'b0), .a(a[1:0]), .b(b[1:0]), .out(sum[1:0]), .c_o(c2)); sub b32 (.c_i(c2), .a(a[3:2]), .b(b[3:2]), .out(sum[3:2]), .c_o(c4)); sub b54 (.c_i(c4), .a(a[5:4]), .b(b[5:4]), .out(sum[5:4]), .c_o(sum[6])); bit [6:0] idxa, idxb; initial begin for (idxa = 0 ; idxa < 'b1_000000 ; idxa = idxa+1) begin for (idxb = 0 ; idxb < 'b1_000000 ; idxb = idxb+1) begin a = idxa; b = idxb; #1 /* wait for devices to settle */; if (idxa + idxb != sum) begin $display("FAILED: %0d + %0d --> %0d", a, b, sum); $stop; end end end // for (idxa = 0 ; idxa < 'b1_000000 ; idxa = idxa+1) $display("PASSED"); $finish; end // initial begin endmodule // main module sub (input wire bit c_i, input wire bit[1:0] a, b, output wire bit [1:0] out, output wire bit c_o); assign {c_o, out} = {1'b0, a} + {1'b0, b} + {2'b00, c_i}; endmodule // sub iverilog-12_0/ivtest/ivltests/sv-constants.v000066400000000000000000000030721435245347300213750ustar00rootroot00000000000000module tb; parameter P = '1; parameter W = 82; wire [W-1:0] one = '1; wire [W-1:0] zero = '0; wire [W-1:0] x = 'x; wire [W-1:0] z = 'z; wire [15:0] expr_add = 16'h0 + '1; wire [15:0] expr_xor = 16'haaaa ^ '1; wire [3:0] bitsel = 4'h2; wire [3:0] bitsel_lv; wire [3:0] param = P; assign bitsel_lv['1] = 1'b1; initial begin #5; if (4'hf !== '1) begin $display("FAILED, 4'hf !== '1"); $finish; end if (one !== '1) begin $display("FAILED, one !== '1"); $finish; end if (one !== {W{1'b1}}) begin $display("FAILED, one = %b", one); $finish; end if (zero !== {W{1'b0}}) begin $display("FAILED, zero = %b", zero); $finish; end if (x !== {W{1'bx}}) begin $display("FAILED, x = %b", x); $finish; end if (z !== {W{1'bz}}) begin $display("FAILED, z = %b", z); $finish; end if (expr_add !== 16'hffff) begin $display("FAILED, expr_add = %b", expr_add); $finish; end if (expr_xor !== 16'h5555) begin $display("FAILED, expr_xor = %b", expr_xor); $finish; end if (bitsel_lv[1] !== 1'b1) begin $display("FAILED, bitsel_lv[1] = %b", bitsel_lv[1]); $finish; end if (bitsel['1] !== 1'b1) begin $display("FAILED, bitsel['1] = %b", bitsel['1]); $finish; end if (bitsel['1:'0] !== 2'b10) begin $display("FAILED, bitsel['1:'0] = %b", bitsel['1:'0]); $finish; end if (param !== 4'h1) begin $display("FAILED, param = %b, %b", param, P); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_assign_pattern2.v000066400000000000000000000014431435245347300237440ustar00rootroot00000000000000 program main; function int sum_array(bit[7:0] array[]); int idx; sum_array = 0; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array += array[idx]; endfunction // sum_array bit [7:0] obj[]; int foo; initial begin foo = sum_array('{}); if (foo !== 0) begin $display("FAILED -- sum of empty array returns %0d", foo); $finish; end obj = new[3]; obj = '{1,2,3}; foo = sum_array(obj); if (foo !== 6) begin $display("FAILED -- sum of '{1,2,3} is %0d", foo); $finish; end obj = new[3] ('{4,5,6}); foo = sum_array(obj); if (foo !== 15) begin $display("FAILED -- sum of '{4,5,6} is %0d", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_array_cassign1.v000066400000000000000000000003161435245347300223470ustar00rootroot00000000000000// Check that continuous assignment of two compatible arrays is supported module test; wire [1:0] x[1:0]; wire [1:0] y[1:0]; assign x = y; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign2.v000066400000000000000000000004721435245347300223530ustar00rootroot00000000000000// Check that continuous assignment of two compatible arrays is supported, even // if the upper and lower bounds of the arrays are not identical, as long as the // size is the same. module test; wire [1:0] x[1:0]; wire [1:0] y[2:1]; assign x = y; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign3.v000066400000000000000000000004241435245347300223510ustar00rootroot00000000000000// Check that continuous assignment of two compatible arrays is supported, even // if the element types are not identical, but just equivalent. module test; wire [1:0] x[1:0]; wire [2:1] y[1:0]; assign x = y; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign4.v000066400000000000000000000005211435245347300223500ustar00rootroot00000000000000// Check that continuous assignment of two compatible arrays is supported, even // if the element types are not identical and one is a built-in integer and the // other a equivalent packed type. module test; wire signed [31:0] x[1:0]; wire integer y[1:0]; assign x = y; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign5.v000066400000000000000000000004711435245347300223550ustar00rootroot00000000000000// Check that continuous assignment of two compatible arrays is supported, even // if the element types have different number of dimensions, but have the same // packed width. module test; wire [3:0] x[1:0]; wire [1:0][1:0] y[1:0]; assign x = y; initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail1.v000066400000000000000000000003511435245347300233410ustar00rootroot00000000000000// Check that it is an error if the element type is not the same in a // continuous array assignment. module test; wire [3:0] x[1:0]; reg [1:0] y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail10.v000066400000000000000000000006021435245347300234200ustar00rootroot00000000000000// Check that it is an error trying to continuously assign an unpacked array // with an enum element type to another unpacked array with an element type that // is not the same enum type, even if the two element types are the same size. module test; wire integer x[1:0]; enum integer { A } y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail11.v000066400000000000000000000005571435245347300234320ustar00rootroot00000000000000// Check that it is an error to continuously assign an unpacked array with an // enum element type if the other unpacked array element type is not the same // enum type, even if the two element types are the same size. module test; wire enum integer { A } x[1:0]; integer y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail2.v000066400000000000000000000003601435245347300233420ustar00rootroot00000000000000// Check that it is an error if the array size is not the same in a continuous // unpacked array assignment. module test; wire [1:0] x[2:0]; reg [1:0] y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail3.v000066400000000000000000000004651435245347300233510ustar00rootroot00000000000000// Check that it is an error if the number of unpacked dimensions do not match // in an continuous array assignment, even if the canonical size of the array is // the same. module test; wire [1:0] x[1:0][1:0]; reg [1:0] y[3:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail4.v000066400000000000000000000004401435245347300233430ustar00rootroot00000000000000// Check that it is an error if the element type is not the same in a // continuous array assignment, even if the difference is just 2-state vs. // 4-state. module test; wire [1:0] x[1:0]; bit [1:0] y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail5.v000066400000000000000000000004651435245347300233530ustar00rootroot00000000000000// Check that it is an error if the element type is not the same in a // continuous array assignment, even if one of the types is a packed type and // the other is a real type. module test; wire [1:0] x[1:0]; real [1:0] y[1:0]; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail6.v000066400000000000000000000003401435245347300233440ustar00rootroot00000000000000// Check that it is an error trying to continuously assign a scalar expression // to a unpacked array. module test; wire [1:0] x[1:0]; assign x = 1'b1 + 1'b1; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail7.v000066400000000000000000000003441435245347300233510ustar00rootroot00000000000000// Check that it is an error trying to continuously assign a scalar variable to // an unpacked array. module test; wire [1:0] x[1:0]; reg [1:0] y; assign x = y; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail8.v000066400000000000000000000003241435245347300233500ustar00rootroot00000000000000// Check that it is an error trying to continuously assign a scalar net to an // unpacked array. module test; wire a[1:0]; wire x; assign a = x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_cassign_fail9.v000066400000000000000000000003771435245347300233610ustar00rootroot00000000000000// Check that it is an error trying to continuously assign an element of an // unpacked array to another unpacked array as a whole. module test; wire a[1:0]; wire x[1:0]; assign a = x[0]; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_array_query.v000066400000000000000000000011471435245347300220070ustar00rootroot00000000000000// Check that array query functions return the correct value for C style arrays module test; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end bit [1:0] a[10]; initial begin `check($left(a), 0) `check($right(a), 9) `check($low(a), 0) `check($high(a), 9) `check($size(a), 10) `check($increment(a), -1) `check($dimensions(a), 2) `check($unpacked_dimensions(a), 1) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_cast.v000066400000000000000000000020101435245347300234650ustar00rootroot00000000000000// Check that implicit cast works for expressions in assignment patterns. The // result should be the same as assigning the expression to a variable with the // same type as the base type of the assignment pattern target. module test; int dv[]; real dr[]; int tmpv; real tmpr; bit failed = 1'b0; `define check_v(expr) \ dv = '{expr}; \ tmpv = expr; \ if (dv[0] !== tmpv) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", dv[0], tmpv); \ failed = 1'b1; \ end `define check_r(expr) \ dr = '{expr}; \ tmpr = expr; \ if (dr[0] != tmpr) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", dr[0], tmpr); \ failed = 1'b1; \ end real r; int i; initial begin r = 4.56; i = -11; // Implicit cast from real to vector `check_v(1.234e16) `check_v(r) // Implicit cast from vector to real `check_r(32'hfffffff0) `check_r(i) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_concat.v000066400000000000000000000012271435245347300240130ustar00rootroot00000000000000// Check that concatenations are evaluated correctly in assignment patterns. // The result should be the same as assigning the expression to a variable with // the same type as the base type of the assignment pattern target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end shortint x; byte y; initial begin x = -1; y = 10; `check({x,y}) `check({3{y}}) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_const.v000066400000000000000000000013341435245347300236710ustar00rootroot00000000000000// Check that named constants can be accessed in assignment patterns. The // result should be the same as assigning the expression to a variable with the // same type as the base type of the assignment pattern target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end parameter A = -1; localparam B = 10; typedef enum { X = -1, Y = 0, Z = 1 } T; initial begin `check(A) `check(B) `check(X) `check(Y) `check(Z) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_expand.v000066400000000000000000000016361435245347300240270ustar00rootroot00000000000000// Check that the width of the element type of the target of an assignment // pattern is considered when evaluating the expression. The result should be // the same as assigning the expression to a variable with the same type as the // base type of the assignment pattern target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end shortint x; bit [7:0] y; initial begin x = -11; y = 8'h80; // Sign extension `check(x) `check(16'sh8000) // No sign extension `check(8'hff) `check(y) // Gets evaluated in a 32 bit context, the result is 2/-2 not 0 `check(1'b1 + 1'b1) `check(1'sb1 + 1'sb1) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_func.v000066400000000000000000000013221435245347300234730ustar00rootroot00000000000000// Check that function calls within an assignment pattern are evaluated // correctly. The result should be the same as assigning the expression to a // variable with the same type as the base type of the assignment pattern // target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end int x, y; function int fn(int x); return x*2; endfunction initial begin x = -3; y = 10; `check(fn(x)) `check($clog2(y)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_op.v000066400000000000000000000023631435245347300231640ustar00rootroot00000000000000// Check that operators in an assignment pattern are evaluated correctly. The // result should be the same as assigning the expression to a variable with the // same type as the base type of the assignment pattern target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end int x, y; initial begin x = -2; y = 5; `check(+x); `check(-x); `check(!x); `check(~x); `check(&x); `check(~&x); `check(|x); `check(~|x); `check(^x); `check(~^x); `check(x + y) `check(x - y) `check(x * y) `check(x / y) `check(x % y) `check(x ** y) `check(x & y) `check(x | y) `check(x ^ y) `check(x ^~ y) `check(x >> y); `check(x << y); `check(x >>> y); `check(x <<< y); `check(x == y); `check(x != y); `check(x === y); `check(x !== y); `check(x < y); `check(x <= y); `check(x > y); `check(x >= y); `check(x && y); `check(x || y); `check(x ? x : y); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_assign_pattern_part.v000066400000000000000000000013551435245347300235140ustar00rootroot00000000000000// Check that part selects are evaluated correctly within assignment patterns. // The result should be the same as assigning the expression to a variable with // the same type as the base type of the assignment pattern target. module test; int d[]; int tmp; bit failed = 1'b0; `define check(expr) \ d = '{expr}; \ tmp = expr; \ if (d[0] !== tmp) begin \ $display("FAILED: `%s`, got %0d, expected %0d", `"expr`", d[0], tmp); \ failed = 1'b1; \ end logic [23:0] x; int i = 13; initial begin x = 24'ha5a5a5; `check(x[0]) `check(x[7:0]) `check(x[3+:8]) `check(x[23-:5]) `check(x[i+:8]) `check(x[i-:5]) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_cast_darray-v10.v000066400000000000000000000041211435245347300223370ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for casting a dynamic array to vector type // using Icarus specific VPI functions module sv_cast_string(); bit [7:0] darr []; bit [63:0] darr_64 []; bit [7*8 - 1:0] arr; bit [127:0] arr_128; initial begin darr_64 = new[2]; darr_64[0] = "ABCDEFGH"; darr_64[1] = "IJKLMNOP"; darr = new[7]; // Set darr to '{"a","b","c","d","e","f","g"} foreach(darr[i]) darr[i] = "a" + i; // Casting dynamic array to vector $ivl_darray_method$to_vec(darr, arr); if(arr !== "abcdefg") begin $display("FAILED 1"); $finish(); end $ivl_darray_method$to_vec(darr_64, arr_128); if(arr_128 !== "ABCDEFGHIJKLMNOP") begin $display("FAILED 2"); $finish(); end // Reset the stored data to perform reverse casting test arr = "0123456"; arr_128 = "cafedeadbeefc0de"; // Casting vector to dynamic array $ivl_darray_method$from_vec(darr, arr); foreach(darr[i]) begin if(darr[i] != "0" + i) begin $display("FAILED 3"); $finish(); end end $ivl_darray_method$from_vec(darr_64, arr_128); if(darr_64[0] !== "cafedead" || darr_64[1] !== "beefc0de") begin $display("FAILED 4"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_cast_darray.v000066400000000000000000000034561435245347300217450ustar00rootroot00000000000000module test(); typedef bit [63:0] bit64; typedef logic [63:0] vec64; byte byte_array []; bit [15:0] bit_array []; logic [31:0] vec_array []; real real_array []; bit64 bit_result; vec64 vec_result; reg failed = 0; initial begin byte_array = new [8]; foreach (byte_array[i]) byte_array[i] = i*16 + i; bit_result = bit64'(byte_array); $display("%h", bit_result); if (bit_result !== 64'h0011223344556677) failed = 1; vec_result = vec64'(byte_array); $display("%h", vec_result); if (vec_result !== 64'h0011223344556677) failed = 1; bit_array = new [4]; foreach (bit_array[i]) bit_array[i] = i*4096 + i*256 + i*16 + i; bit_result = bit64'(bit_array); $display("%h", bit_result); if (bit_result !== 64'h0000111122223333) failed = 1; vec_result = vec64'(bit_array); $display("%h", vec_result); if (vec_result !== 64'h0000111122223333) failed = 1; vec_array = new [2]; vec_array[0] = 32'b01xz_0001_0010_0011_0100_0101_0110_0111; vec_array[1] = 32'b1000_1001_1010_1011_1100_1101_1110_1111; bit_result = bit64'(vec_array); $display("%h", bit_result); if (bit_result !== 64'b0100_0001_0010_0011_0100_0101_0110_0111_1000_1001_1010_1011_1100_1101_1110_1111) failed = 1; vec_result = vec64'(vec_array); $display("%h", vec_result); if (vec_result !== 64'b01xz_0001_0010_0011_0100_0101_0110_0111_1000_1001_1010_1011_1100_1101_1110_1111) failed = 1; real_array = new [1]; real_array[0] = 1.2345678; bit_result = bit64'(real_array); $display("%h", bit_result); if (bit_result !== $realtobits(1.2345678)) failed = 1; vec_result = vec64'(real_array); $display("%h", vec_result); if (vec_result !== $realtobits(1.2345678)) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_cast_integer.v000066400000000000000000000041321435245347300221100ustar00rootroot00000000000000// This tests SystemVerilog casting support // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. // Extended by Maciej Suminski // Extended by Martin Whitaker module test(); // variables used in casting byte var_08; shortint var_16; int var_32; longint var_64; real var_real; // error counter bit err = 0; initial begin var_08 = byte'(4'sh5); if (var_08 !== 8'sh05) begin $display("FAILED -- var_08 = 'h%0h != 8'h05", var_08); err=1; end var_16 = shortint'(var_08); if (var_16 !== 16'sh05) begin $display("FAILED -- var_16 = 'h%0h != 16'h05", var_16); err=1; end var_32 = int'(var_16); if (var_32 !== 32'sh05) begin $display("FAILED -- var_32 = 'h%0h != 32'h05", var_32); err=1; end var_64 = longint'(var_32); if (var_64 !== 64'sh05) begin $display("FAILED -- var_64 = 'h%0h != 64'h05", var_64); err=1; end var_real = 13.4; var_08 = byte'(var_real); if (var_08 !== 13) begin $display("FAILED -- var_08 = %d != 13", var_08); err=1; end var_real = 14.5; var_16 = shortint'(var_real); if (var_16 !== 15) begin $display("FAILED -- var_16 = %d != 15", var_16); err=1; end var_real = 15.6; var_32 = int'(var_real); if (var_32 !== 16) begin $display("FAILED -- var_32 = %d != 16", var_32); err=1; end var_real = -15.6; var_64 = longint'(var_real); if (var_64 !== -16) begin $display("FAILED -- var_64 = %d != -16", var_64); err=1; end var_08 = byte'(4'hf); if (var_08 !== 8'sh0f) begin $display("FAILED -- var_08 = 'h%0h != 8'h0f", var_08); err=1; end var_08 = byte'(4'shf); if (var_08 !== 8'shff) begin $display("FAILED -- var_08 = 'h%0h != 8'hff", var_08); err=1; end var_16 = byte'(16'h0f0f); if (var_16 !== 16'sh0f) begin $display("FAILED -- var_16 = 'h%0h != 16'h0f", var_16); err=1; end var_16 = byte'(4'shf) + 'd0; if (var_16 !== 16'shff) begin $display("FAILED -- var_16 = 'h%0h != 16'hff", var_16); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_cast_integer2.v000066400000000000000000000043561435245347300222020ustar00rootroot00000000000000// This tests SystemVerilog casting support // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. // Extended by Maciej Suminski // Copied and modified by Martin Whitaker module test(); typedef logic signed [7:0] reg08; typedef logic signed [15:0] reg16; typedef logic signed [31:0] reg32; typedef logic signed [63:0] reg64; // variables used in casting reg08 var_08; reg16 var_16; reg32 var_32; reg64 var_64; real var_real; // error counter bit err = 0; initial begin var_08 = reg08'(4'sh5); if (var_08 !== 8'sh05) begin $display("FAILED -- var_08 = 'h%0h != 8'h05", var_08); err=1; end var_16 = reg16'(var_08); if (var_16 !== 16'sh05) begin $display("FAILED -- var_16 = 'h%0h != 16'h05", var_16); err=1; end var_32 = reg32'(var_16); if (var_32 !== 32'sh05) begin $display("FAILED -- var_32 = 'h%0h != 32'h05", var_32); err=1; end var_64 = reg64'(var_32); if (var_64 !== 64'sh05) begin $display("FAILED -- var_64 = 'h%0h != 64'h05", var_64); err=1; end var_real = 13.4; var_08 = reg08'(var_real); if (var_08 !== 13) begin $display("FAILED -- var_08 = %d != 13", var_08); err=1; end var_real = 14.5; var_16 = reg16'(var_real); if (var_16 !== 15) begin $display("FAILED -- var_16 = %d != 15", var_16); err=1; end var_real = 15.6; var_32 = reg32'(var_real); if (var_32 !== 16) begin $display("FAILED -- var_32 = %d != 16", var_32); err=1; end var_real = -15.6; var_64 = reg64'(var_real); if (var_64 !== -16) begin $display("FAILED -- var_64 = %d != -16", var_64); err=1; end var_08 = reg08'(4'hf); if (var_08 !== 8'sh0f) begin $display("FAILED -- var_08 = 'h%0h != 8'h0f", var_08); err=1; end var_08 = reg08'(4'shf); if (var_08 !== 8'shff) begin $display("FAILED -- var_08 = 'h%0h != 8'hff", var_08); err=1; end var_16 = reg08'(16'h0f0f); if (var_16 !== 16'sh0f) begin $display("FAILED -- var_16 = 'h%0h != 16'h0f", var_16); err=1; end var_16 = reg08'(4'shf) + 'd0; if (var_16 !== 16'shff) begin $display("FAILED -- var_16 = 'h%0h != 16'hff", var_16); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_cast_packed_array.v000066400000000000000000000037271435245347300231110ustar00rootroot00000000000000// This tests SystemVerilog casting support // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. // Extended by Maciej Suminski // Copied and modified by Martin Whitaker // Copied and modified again by Lars-Peter Clausen module test(); typedef logic [7:0] pa08; typedef pa08 [1:0] pa16; typedef pa16 [1:0] pa32; typedef pa32 [1:0] pa64; // variables used in casting pa08 var_08; pa16 var_16; pa32 var_32; pa64 var_64; real var_real; // error counter bit err = 0; initial begin var_08 = pa08'(4'h5); if (var_08 !== 8'h05) begin $display("FAILED -- var_08 = 'h%0h != 8'h05", var_08); err=1; end var_16 = pa16'(var_08); if (var_16 !== 16'h05) begin $display("FAILED -- var_16 = 'h%0h != 16'h05", var_16); err=1; end var_32 = pa32'(var_16); if (var_32 !== 32'h05) begin $display("FAILED -- var_32 = 'h%0h != 32'h05", var_32); err=1; end var_64 = pa64'(var_32); if (var_64 !== 64'h05) begin $display("FAILED -- var_64 = 'h%0h != 64'h05", var_64); err=1; end var_real = 13.4; var_08 = pa08'(var_real); if (var_08 !== 13) begin $display("FAILED -- var_08 = %d != 13", var_08); err=1; end var_real = 14.5; var_16 = pa16'(var_real); if (var_16 !== 15) begin $display("FAILED -- var_16 = %d != 15", var_16); err=1; end var_real = 15.6; var_32 = pa32'(var_real); if (var_32 !== 16) begin $display("FAILED -- var_32 = %d != 16", var_32); err=1; end var_real = -15.6; var_64 = pa64'(var_real); if (var_64 !== -16) begin $display("FAILED -- var_64 = %d != -16", var_64); err=1; end var_08 = pa08'(4'hf); if (var_08 !== 8'h0f) begin $display("FAILED -- var_08 = 'h%0h != 8'h0f", var_08); err=1; end var_16 = pa08'(16'h0f0f); if (var_16 !== 16'h0f) begin $display("FAILED -- var_16 = 'h%0h != 16'h0f", var_16); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_cast_packed_struct.v000066400000000000000000000045331435245347300233130ustar00rootroot00000000000000// This tests SystemVerilog casting support // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. // Extended by Maciej Suminski // Copied and modified by Martin Whitaker // Copied and modified again by Lars-Peter Clausen module test(); typedef struct packed signed { logic [7:0] x; } s08; typedef struct packed signed { logic [15:0] x; } s16; typedef struct packed signed { int x; } s32; typedef struct packed signed { int x; shortint y; byte z; logic [7:0] w; } s64; // variables used in casting s08 var_08; s16 var_16; s32 var_32; s64 var_64; real var_real; // error counter bit err = 0; initial begin var_08 = s08'(4'sh5); if (var_08 !== 8'sh05) begin $display("FAILED -- var_08 = 'h%0h != 8'h05", var_08); err=1; end var_16 = s16'(var_08); if (var_16 !== 16'sh05) begin $display("FAILED -- var_16 = 'h%0h != 16'h05", var_16); err=1; end var_32 = s32'(var_16); if (var_32 !== 32'sh05) begin $display("FAILED -- var_32 = 'h%0h != 32'h05", var_32); err=1; end var_64 = s64'(var_32); if (var_64 !== 64'sh05) begin $display("FAILED -- var_64 = 'h%0h != 64'h05", var_64); err=1; end var_real = 13.4; var_08 = s08'(var_real); if (var_08 !== 13) begin $display("FAILED -- var_08 = %d != 13", var_08); err=1; end var_real = 14.5; var_16 = s16'(var_real); if (var_16 !== 15) begin $display("FAILED -- var_16 = %d != 15", var_16); err=1; end var_real = 15.6; var_32 = s32'(var_real); if (var_32 !== 16) begin $display("FAILED -- var_32 = %d != 16", var_32); err=1; end var_real = -15.6; var_64 = s64'(var_real); if (var_64 !== -16) begin $display("FAILED -- var_64 = %d != -16", var_64); err=1; end var_08 = s08'(4'hf); if (var_08 !== 8'sh0f) begin $display("FAILED -- var_08 = 'h%0h != 8'h0f", var_08); err=1; end var_08 = s08'(4'shf); if (var_08 !== 8'shff) begin $display("FAILED -- var_08 = 'h%0h != 8'hff", var_08); err=1; end var_16 = s08'(16'h0f0f); if (var_16 !== 16'sh0f) begin $display("FAILED -- var_16 = 'h%0h != 16'h0f", var_16); err=1; end var_16 = s08'(4'shf) + 'd0; if (var_16 !== 16'shff) begin $display("FAILED -- var_16 = 'h%0h != 16'hff", var_16); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_cast_string.v000066400000000000000000000030071435245347300217610ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for casting a string to a vector type. module sv_cast_string(); string str; typedef logic [55:0] strbits; strbits chars; initial begin int i; str = "0123456"; chars = strbits'(str); if(chars != 56'h30313233343536) begin $display("FAILED 1 chars = %x", chars); $finish(); end str = "6543210"; chars = strbits'(str); if(chars != "6543210") begin $display("FAILED 2 chars = %x", chars); $finish(); end str = "wrong string"; // Vector to string casting str = string'(chars); if(str != "6543210") begin $display("FAILED 3 str = %s", str); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_cast_typedef.v000066400000000000000000000011631435245347300221140ustar00rootroot00000000000000// Check that type cast works as expected when using type identifiers. module test; typedef string T_S; typedef real T_R; typedef logic [15:0] T_V; string s; real r; logic [15:0] v; bit failed; `define check(expr, val) \ if (expr != val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin v = "Hi"; s = T_S'(v); `check(s, "Hi") v = 123; r = T_R'(v); `check(r, 123) r = 1.23; v = T_V'(r); `check(v, 16'd1) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class1.v000066400000000000000000000033311435245347300206270ustar00rootroot00000000000000 /* * This tests a trivial class. In SystemVerilong, classes are garbage * collected dynamic objects, so this tests the creation of class objects, * some simple manipulations, copying (by reference) and cleanup. */ program main; // Trivial example of a class class foo_t ; int a; int b; endclass : foo_t // foo_t foo_t obj, copy; initial begin if (obj != null) begin $display("FAILED -- objects must start out null."); $finish; end obj = new; if (obj == null) begin $display("FAILED -- After allocation, object is NOT null."); $finish; end // This is the most trivial assignment of class properties. obj.a = 10; obj.b = 11; if (obj.a != 10 || obj.b != 11) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // This actually makes a shared link to the same object. This // will make a link to the object. copy = obj; if (copy.a != 10 || copy.b != 11) begin $display("FAILED -- copy object: copy.a=%0d, copy.b=%0d", copy.a, copy.b); $finish; end copy.a = 7; copy.b = 8; if (obj.a != 7 || obj.b != 8) begin $display("FAILED -- check shared-ness: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // Clear the copy pointer. obj still exists, though. copy = null; if (obj.a != 7 || obj.b != 8) begin $display("FAILED -- clear copy preserved link: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // This is the last reference to the class, so it should cause // the object to be destroyed. How to test that? obj = null; $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class10.v000066400000000000000000000015151435245347300207110ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; class bar_t; int a; int b; endclass // bar_t // Trivial example of a class class foo_t ; byte a; bar_t b; endclass : foo_t // foo_t foo_t obj; bar_t tmp; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hf_ff; obj.b = new; tmp = obj.b; tmp.a = 0; tmp.b = 1; if (obj.a != -1) begin $display("FAILED -- assign to object: obj.a=%0d", obj.a); $finish; end if (tmp.a != 0 || tmp.b != 1) begin $display("FAILED -- obj.b.a=%0d, obj.b.b=%0d", tmp.a, tmp.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class11.v000066400000000000000000000027321435245347300207140ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple user defined * methods work. */ program main; // Trivial example of a class class foo_t ; int value_; task clear(); value_ = 0; endtask // clear task add(int x); this.value_ = this.value_ + x; endtask // add function int peek(); peek = value_; endfunction // peek function int is_multiple(int x); if (value_ % x == 0) is_multiple = 1; else is_multiple = 0; endfunction // is_multiple endclass : foo_t // foo_t foo_t obj; initial begin obj = new; obj.clear(); if (obj.peek() != 0) begin $display("FAILED -- obj.value_=%0d after clear.", obj.value_); $finish; end obj.add(5); if (obj.peek() != 5) begin $display("FAILED -- obj.value_=%0d after add(5).", obj.value_); $finish; end if (obj.is_multiple(2) != 0) begin $display("FAILED -- obj.is_multipe(2) incorrect result. (5/2)"); $finish; end obj.add(3); if (obj.peek() != 8) begin $display("FAILED -- obj.value_=%0d after add(3).", obj.value_); $finish; end if (obj.is_multiple(2) == 0) begin $display("FAILED -- obj.is_multipe(2) incorrect result. (8/2)"); $finish; end obj.clear(); if (obj.peek() != 0) begin $display("FAILED -- obj.value_=%0d after second clear.", obj.value_); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class12.v000066400000000000000000000014731435245347300207160ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple user defined * constructors work. */ program main; // Trivial examples of classes. class foo_t ; int value; function new(); value = 42; endfunction // new endclass : foo_t // foo_t class bar_t ; int value; function new (int init); value = init; endfunction // new endclass : bar_t // foo_t foo_t obj1; bar_t obj2; initial begin obj1 = new; if (obj1.value !== 42) begin $display("FAILED -- Default constructor left value=%0d.", obj1.value); $finish; end obj2 = new(53); if (obj2.value !== 53) begin $display("FAILED -- new(53) constructure left value=%0d.", obj2.value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class13.v000066400000000000000000000023111435245347300207070ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple user defined * constructors work, and also tests shallow copoy "new". */ program main; // Trivial examples of classes. class foo_t ; int value; function new(); value = 42; endfunction // new endclass : foo_t // foo_t class bar_t ; int value; function new (int init); value = init; endfunction // new endclass : bar_t // foo_t foo_t obj1; bar_t obj2; foo_t obj1b; initial begin obj1 = new; if (obj1.value !== 42) begin $display("FAILED -- Default constructor left value=%0d.", obj1.value); $finish; end obj2 = new(53); if (obj2.value !== 53) begin $display("FAILED -- new(53) constructure left value=%0d.", obj2.value); $finish; end // Shallow object copy obj1b = new obj1; if (obj1b.value !== 42) begin $display("FAILED -- Shallow copy constructor left value=%0d.", obj1b.value); $finish; end obj1.value = 85; if (obj1b.value !== 42) begin $display("FAILED -- Shallow copied value changed to %0d.", obj1b.value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class14.v000066400000000000000000000034341435245347300207170ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple user defined * constructors work, and also tests shallow copoy "new". */ program main; class share_t; int value; endclass // share_t // Trivial examples of classes. class foo_t ; int value; string text; share_t common; endclass : foo_t // foo_t foo_t obj1; foo_t obj2; share_t tmp; initial begin obj1 = new; obj1.common = new; obj1.value = 42; obj1.text = "text"; tmp = obj1.common; tmp.value = 54; if (obj1.value !== 42) begin $display("FAILED -- obj1.value=%0d.", obj1.value); $finish; end if (obj1.text != "text") begin $display("FAILED -- obj1.text=%s", obj1.text); $finish; end tmp = obj1.common; if (tmp.value !== 54) begin $display("FAILED -- obj1.common.value=%0d.", tmp.value); $finish; end obj2 = new obj1; obj1.value = 43; obj1.text = "new text"; tmp = obj1.common; tmp.value = 53; if (obj1.value !== 43) begin $display("FAILED -- obj1.value=%0d.", obj1.value); $finish; end if (obj2.value !== 42) begin $display("FAILED -- obj2.value=%0d.", obj2.value); $finish; end if (obj1.text != "new text") begin $display("FAILED -- obj1.text=%s", obj1.text); $finish; end if (obj2.text != "text") begin $display("FAILED -- obj2.text=%s", obj2.text); $finish; end tmp = obj1.common; if (tmp.value !== 53) begin $display("FAILED -- obj1.common.value=%0d.", tmp.value); $finish; end tmp = obj2.common; if (tmp.value !== 53) begin $display("FAILED -- obj2.common.value=%0d.", tmp.value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class15.v000066400000000000000000000020441435245347300207140ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple property * initializers work, but are overridden by an constructor. */ program main; // Trivial examples of classes. class foo_t ; int int_value = 42; bit [3:0] bit_value = 5; string txt_value = "text"; function new(); // The declaration assignments happen before the constructor // is called, so we can refer to them. int_value = int_value + 1; // s.b. 43 bit_value = bit_value * 2; // s.b. 10 txt_value = "fluf"; endfunction endclass : foo_t // foo_t foo_t obj1; initial begin obj1 = new; if (obj1.int_value !== 43) begin $display("FAILED -- obj1.int_value=%0d.", obj1.int_value); $finish; end if (obj1.bit_value !== 4'd10) begin $display("FAILED -- obj1.bit_value=%0b.", obj1.bit_value); $finish; end if (obj1.txt_value != "fluf") begin $display("FAILED -- obj1.txt_value=%s", obj1.txt_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class16.v000066400000000000000000000020441435245347300207150ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple property * initializers work, but are overridden by an constructor. */ program main; // Trivial examples of classes. class foo_t ; int int_value = 42; bit [3:0] bit_value = 5; string txt_value = "text"; function new(); // The declaration assignments happen before the constructor // is called, so we can refer to them. int_value = int_value + 1; // s.b. 43 bit_value = bit_value * 2; // s.b. 10 txt_value = "fluf"; endfunction endclass : foo_t // foo_t foo_t obj1; initial begin obj1 = new; if (obj1.int_value !== 43) begin $display("FAILED -- obj1.int_value=%0d.", obj1.int_value); $finish; end if (obj1.bit_value !== 4'd10) begin $display("FAILED -- obj1.bit_value=%0b.", obj1.bit_value); $finish; end if (obj1.txt_value != "fluf") begin $display("FAILED -- obj1.txt_value=%s", obj1.txt_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class17.v000066400000000000000000000021051435245347300207140ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple property * initializers work. */ program main; // Trivial examples of classes. class foo_t ; int int_value = 42; bit [3:0] bit_value = 5; string txt_value = "text"; endclass : foo_t // foo_t foo_t obj1; foo_t obj2; initial begin obj1 = new; // The shallow copy constructor bypasses (or at least overrides) // property declaration assignments, so obj2 should hold the // updated values and not the constructed values. obj1.int_value = 43; obj1.bit_value = 10; obj1.txt_value = "fluf"; obj2 = new obj1; if (obj2.int_value !== 43) begin $display("FAILED -- obj2.int_value=%0d.", obj2.int_value); $finish; end if (obj2.bit_value !== 4'd10) begin $display("FAILED -- obj2.bit_value=%0b.", obj2.bit_value); $finish; end if (obj2.txt_value != "fluf") begin $display("FAILED -- obj2.txt_value=%s", obj2.txt_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class18.v000066400000000000000000000023231435245347300207170ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple property * initializers work, but are overridden by an constructor. It * also tests the global const property. */ program main; // Trivial examples of classes. class foo_t ; const int int_incr = 1; int int_value = 42; function new(); // The declaration assignments happen before the constructor // is called, so we can refer to them. int_value = int_value + int_incr; // s.b. 43 endfunction endclass : foo_t // foo_t foo_t obj1; foo_t obj2; initial begin obj1 = new; if (obj1.int_incr !== 1) begin $display("FAILED == obj1.int_incr=%0d.", obj1.int_incr); $finish; end if (obj1.int_value !== 43) begin $display("FAILED -- obj1.int_value=%0d.", obj1.int_value); $finish; end // Try a shallow copy to see that the const propery is handled. obj2 = new obj1; if (obj2.int_incr !== 1) begin $display("FAILED == obj2.int_incr=%0d.", obj2.int_incr); $finish; end if (obj2.int_value !== 43) begin $display("FAILED -- obj2.int_value=%0d.", obj2.int_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class19.v000066400000000000000000000027431435245347300207260ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that simple property * initializers work, but are overridden by an constructor. It * also tests the global const property. */ program main; // Trivial examples of classes. class foo_t ; static int int_incr = 1; int int_value = 42; function new(); // The declaration assignments happen before the constructor // is called, so we can refer to them. int_value = int_value + int_incr; // s.b. 43 endfunction endclass : foo_t // foo_t foo_t obj1; foo_t obj2; initial begin // Static properties do not actually look at the instance, so // we do not need to create an instance to access them. if (obj1.int_incr !== 1) begin $display("FAILED == obj1.int_incr=%0d.", obj1.int_incr); $finish; end obj1 = new; if (obj1.int_value !== 43) begin $display("FAILED -- obj1.int_value=%0d.", obj1.int_value); $finish; end // Try a shallow copy to see that the const propery is handled. obj2 = new obj1; if (obj2.int_value !== 43) begin $display("FAILED -- obj2.int_value=%0d.", obj2.int_value); $finish; end obj1.int_incr = 2; if (obj1.int_incr !== 2) begin $display("FAILED == obj1.int_incr=%0d", obj1.int_incr); $finish; end if (obj2.int_incr !== 2) begin $display("FAILED == obj2.int_incr=%0d", obj2.int_incr); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class2.v000066400000000000000000000014771435245347300206410ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; byte signed a; byte unsigned b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hfff; obj.b = 'hfff; if (obj.a != -1 || obj.b != 255) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end obj.a = obj.a + 1; obj.b = obj.b + 1; if (obj.a != 0 || obj.b != 0) begin $display("FAILED -- increment properties: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class20.v000066400000000000000000000012061435245347300207070ustar00rootroot00000000000000 program main; class base_t ; int int_value; function new(); int_value = 42; endfunction // new endclass : base_t class foo_t extends base_t ; string str_value; function new(); str_value = "42"; endfunction endclass : foo_t foo_t obj1; initial begin obj1 = new; if (obj1.int_value !== 42) begin $display("FAILED -- obj1.int_value = %0d", obj1.int_value); $finish; end if (obj1.str_value != "42") begin $display("FAILED -- obj1.str_value = %0s", obj1.str_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class21.v000066400000000000000000000012371435245347300207140ustar00rootroot00000000000000 program main; class base_t ; int int_value; function new(int val); int_value = val; endfunction // new endclass : base_t class foo_t extends base_t ; string str_value; function new(); super.new(42); str_value = "42"; endfunction endclass : foo_t foo_t obj1; initial begin obj1 = new; if (obj1.int_value !== 42) begin $display("FAILED -- obj1.int_value = %0d", obj1.int_value); $finish; end if (obj1.str_value != "42") begin $display("FAILED -- obj1.str_value = %0s", obj1.str_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class22.v000066400000000000000000000012221435245347300207070ustar00rootroot00000000000000 program main; class base_t ; int int_value; function new(int val); int_value = val; endfunction // new endclass : base_t class foo_t extends base_t(42) ; string str_value; function new(); str_value = "42"; endfunction endclass : foo_t foo_t obj1; initial begin obj1 = new; if (obj1.int_value !== 42) begin $display("FAILED -- obj1.int_value = %0d", obj1.int_value); $finish; end if (obj1.str_value != "42") begin $display("FAILED -- obj1.str_value = %0s", obj1.str_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class23.v000066400000000000000000000012561435245347300207170ustar00rootroot00000000000000 program main; class base_t ; int int_value; function new(int val); int_value = val; endfunction // new endclass : base_t class foo_t extends base_t ; string str_value; function new(int eval); super.new(eval); str_value = "42"; endfunction endclass : foo_t foo_t obj1; initial begin obj1 = new (42); if (obj1.int_value !== 42) begin $display("FAILED -- obj1.int_value = %0d", obj1.int_value); $finish; end if (obj1.str_value != "42") begin $display("FAILED -- obj1.str_value = %0s", obj1.str_value); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class24.v000066400000000000000000000033621435245347300207200ustar00rootroot00000000000000 /* * This tests a trivial class. In SystemVerilong, classes are garbage * collected dynamic objects, so this tests the creation of class objects, * some simple manipulations, copying (by reference) and cleanup. */ // Trivial example of a class program main; class base_t; int x; int y; endclass : base_t class foo_t; int a; int b; base_t base = new ( ); endclass : foo_t foo_t obj, copy; initial begin obj = new; if (obj == null) begin $display("FAILED -- After allocation, object is NOT null."); $finish; end // This is the most trivial assignment of class properties. obj.a = 10; obj.b = 11; obj.base.x = 12; obj.base.y = 13; if (obj.a != 10 || obj.b != 11) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // This actually makes a shared link to the same object. This // will make a link to the object. copy = obj; if (copy.a != 10 || copy.b != 11) begin $display("FAILED -- copy object: copy.a=%0d, copy.b=%0d", copy.a, copy.b); $finish; end copy.a = 7; copy.b = 8; if (obj.a != 7 || obj.b != 8) begin $display("FAILED -- check shared-ness: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // Clear the copy pointer. obj still exists, though. copy = null; if (obj.a != 7 || obj.b != 8) begin $display("FAILED -- clear copy preserved link: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end // This is the last reference to the class, so it should cause // the object to be destroyed. How to test that? obj = null; $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class3.v000066400000000000000000000015171435245347300206350ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; shortint signed a; shortint unsigned b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hf_ffff; obj.b = 'hf_ffff; if (obj.a != -1 || obj.b != 65535) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end obj.a = obj.a + 1; obj.b = obj.b + 1; if (obj.a != 0 || obj.b != 0) begin $display("FAILED -- increment properties: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class4.v000066400000000000000000000015271435245347300206370ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; int signed a; int unsigned b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hf_ffffffff; obj.b = 'hf_ffffffff; if (obj.a != -1 || obj.b != 'd4_294_967_295) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end obj.a = obj.a + 1; obj.b = obj.b + 1; if (obj.a != 0 || obj.b != 0) begin $display("FAILED -- increment properties: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class5.v000066400000000000000000000015731435245347300206410ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; longint signed a; longint unsigned b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 68'hf_ffffffff_ffffffff; obj.b = 68'hf_ffffffff_ffffffff; if (obj.a != -1 || obj.b != 64'hffffffff_ffffffff) begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end obj.a = obj.a + 1; obj.b = obj.b + 1; if (obj.a != 0 || obj.b != 0) begin $display("FAILED -- increment properties: obj.a=%0d, obj.b=%0d", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class6.v000066400000000000000000000014621435245347300206370ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; real a; real b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 0.5; obj.b = -1.5; if (obj.a != 0.5 || obj.b != -1.5) begin $display("FAILED -- assign to object: obj.a=%f, obj.b=%f", obj.a, obj.b); $finish; end obj.a = obj.a - 0.5; obj.b = obj.b + 1.5; if (obj.a != 0.0 || obj.b != 0.0) begin $display("FAILED -- increment properties: obj.a=%f, obj.b=%f", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class7.v000066400000000000000000000015611435245347300206400ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; string a; string b; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // Absent any other constructor, strings get initialized as nil. if (obj.a != "" || obj.b != "") begin $display("FAILED -- String property not initialized."); $finish; end // This is the most trivial assignment of class properties. obj.a = "Hello"; obj.b = "World"; $display("obj = {%0s, %0s}", obj.a, obj.b); if (obj.a != "Hello" || obj.b != "World") begin $display("FAILED -- assign to object: obj.a=%0s, obj.b=%0s", obj.a, obj.b); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class8.v000066400000000000000000000017751435245347300206500ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; byte a; int b; real c; string d; endclass : foo_t // foo_t foo_t obj; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hf_ff; obj.b = 'hf_ffffffff; obj.c = -1.5; obj.d = "-1"; if (obj.a != -1 || obj.b != -1 || obj.c != -1.5 || obj.d != "-1") begin $display("FAILED -- assign to object: obj.a=%0d, obj.b=%0d, obj.c=%f, obj.d=%0s", obj.a, obj.b, obj.c, obj.d); $finish; end obj.a = obj.a + 1; obj.b = obj.b + 1; obj.c = obj.c + 1.5; if (obj.a != 0 || obj.b != 0 || obj.c != 0.0) begin $display("FAILED -- increment properties: obj.a=%0d, obj.b=%0d, obj.c=%f", obj.a, obj.b, obj.c); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class9.v000066400000000000000000000016331435245347300206420ustar00rootroot00000000000000 /* * This tests a trivial class. This tests that properties can be * given types, and that the types behave properly. */ program main; // Trivial example of a class class foo_t ; byte a; int b[]; endclass : foo_t // foo_t foo_t obj; int tmp[]; initial begin obj = new; // This is the most trivial assignment of class properties. obj.a = 'hf_ff; obj.b = new[2]; tmp = obj.b; tmp[0] = 0; tmp[1] = 1; if (obj.a != -1) begin $display("FAILED -- assign to object: obj.a=%0d", obj.a); $finish; end tmp = obj.b; if (tmp.size() != 2) begin $display("FAILED -- obj.b.size() = %0d", tmp.size()); $finish; end if (tmp[0] != 0 || tmp[1] != 1) begin $display("FAILED -- obj.b[0]=%0d, obj.b[1]=%0d", tmp[0], tmp[1]); $finish; end $display("PASSED"); $finish; end endprogram // main iverilog-12_0/ivtest/ivltests/sv_class_compat1.v000066400000000000000000000005421435245347300221730ustar00rootroot00000000000000// Check that an object can be assigned to a variable of its base class type module test; class B; int x; task t; $display("PASSED"); endtask endclass class C extends B; int y; task t; $display("FAILED"); endtask endclass B b; C c; initial begin c = new; b = c; b.t; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_compat2.v000066400000000000000000000007401435245347300221740ustar00rootroot00000000000000// Check that an object can be assigned to a variable of base class across more // than one hierarchy level module test; class B; int x; task t; $display("PASSED"); endtask endclass class C extends B; int y; task t; $display("FAILED"); endtask endclass class D extends C; int z; task t; $display("FAILED"); endtask endclass B b; D d; initial begin d = new; b = d; b.t; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_compat_fail1.v000066400000000000000000000004701435245347300231660ustar00rootroot00000000000000// Check that an error is reported when trying to assign an object to variable // of an unrelated class type module test; class B; int x; endclass class C; int y; endclass B b; C c; initial begin c = new; b = c; // This should fail, both classes are unrelated end endmodule iverilog-12_0/ivtest/ivltests/sv_class_compat_fail2.v000066400000000000000000000005271435245347300231720ustar00rootroot00000000000000// Check that an error is reported when trying when trying to assign an object // of a base class to a variable of a inherited class. module test; class B; int x; endclass class C extends B; int y; endclass B b; C c; initial begin b = new; c = b; // This should fail, B is a base class of C end endmodule iverilog-12_0/ivtest/ivltests/sv_class_compat_fail3.v000066400000000000000000000007071435245347300231730ustar00rootroot00000000000000// Check that an error is reported when trying to assign an object to a variable // that shares a common base class but is not directly related. module test; class B; int x; endclass class C extends B; int y; endclass class D extends B; int z; endclass C c; D d; initial begin c = new; d = c; // This should fail, both C and D inherit from B, but there is no // direct relationship. end endmodule iverilog-12_0/ivtest/ivltests/sv_class_constructor1.v000066400000000000000000000003351435245347300232750ustar00rootroot00000000000000// Check that a class constructor declaration without parenthesis after the // `new` is supported. module test; class C; function new; $display("PASSED"); endfunction endclass C c = new; endmodule iverilog-12_0/ivtest/ivltests/sv_class_constructor_fail.v000066400000000000000000000003551435245347300242110ustar00rootroot00000000000000// Check that a class constructor with non-ANSI port results in an error. module test; class C; function new; input x; // This is a syntax error $display("FAILED"); endfunction endclass C c = new; endmodule iverilog-12_0/ivtest/ivltests/sv_class_empty_item.v000066400000000000000000000003471435245347300230060ustar00rootroot00000000000000// Check that empty item declarations are supported for classes module test; class C; ; int x;; task test; $display("PASSED"); endtask; ; endclass C c; initial begin c = new; c.test; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_extends_scoped.v000066400000000000000000000005531435245347300236400ustar00rootroot00000000000000// Check that base class defined in a package is handled correctly package P; class B; task check; $display("PASSED"); endtask endclass endpackage module test; class B; task check; $display("FAILED"); endtask endclass class C extends P::B; endclass C c; initial begin c = new; c.check(); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_in_module_decl.v000066400000000000000000000010241435245347300235650ustar00rootroot00000000000000// Check that it is possible to have multiple instances of a module that defines // a class and that the actual class types can have different implementations // based on module parameters. module M #( parameter X = 0 ); class C; function int f; return X; endfunction endclass C c = new; endmodule module test; M #(10) m1(); M #(20) m2(); initial begin if (m1.c.f() == 10 && m2.c.f() == 20) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_localparam.v000066400000000000000000000010031435245347300227330ustar00rootroot00000000000000// Check that it is possible to declare parameters and localparams inside a // class. Both declared parameters that can not be overridden. module test; class C; // `parameter` is also declaring a local parameter inside a class parameter A = 1; localparam B = 2; function bit test(); return A == 1 && B == 2; endfunction endclass initial begin C c; c = new; if (c.test() && c.A == 1 && c.B == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_call_void.v000066400000000000000000000013001435245347300241140ustar00rootroot00000000000000// Check that it is possible to call void function from within a class method. // Check this for functions defined outside the class as well as functions that // are methods of the class or base class. integer sum = 0; function void f1(integer x); sum += x; endfunction class B; function void f2(integer x); sum += x; endfunction endclass class C extends B; function void f3(integer x); sum += x; endfunction task t; f1(10); f2(20); f3(30); endtask endclass module test; C c = new; initial begin c.t; c.f2(40); c.f3(50); if (sum === 150) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_default1.v000066400000000000000000000015431435245347300236760ustar00rootroot00000000000000// Check that default values on function methods are supported and it is // possible to omit any of the arguments. class C; function integer f(integer x = 1, integer y = 2, integer z = 3); return x + y + z; endfunction endclass module test; C c = new; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED. %s, expected %d, got %d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check(c.f(), 6); `check(c.f(4), 9); `check(c.f(4, ), 9); `check(c.f(4, , ), 9); `check(c.f(4, 6), 13); `check(c.f(4, 6, ), 13); `check(c.f(4, , 8), 14); `check(c.f(4, 6, 8), 18); `check(c.f(, 6), 10); `check(c.f(, 6, ), 10); `check(c.f(, 6 ,8), 15); `check(c.f(, , 8), 11); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_default2.v000066400000000000000000000017061435245347300237000ustar00rootroot00000000000000// Check that default values on task methods are supported and it is possible to // omit any of the arguments. class C; integer r; task t(integer x = 1, integer y = 2, integer z = 3); r = x + y + z; endtask endclass module test; C c = new; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED. %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin c.t(); `check(c.r, 6); c.t(4); `check(c.r, 9); c.t(4, ); `check(c.r, 9); c.t(4, ,); `check(c.r, 9); c.t(4, 6); `check(c.r, 13); c.t(4, 6, ); `check(c.r, 13); c.t(4, , 8); `check(c.r, 14); c.t(4, 6, 8); `check(c.r, 18); c.t(, 6); `check(c.r, 10); c.t(, 6, ); `check(c.r, 10); c.t(, 6, 8); `check(c.r, 15); c.t(, , 8); `check(c.r, 11); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_lt_static1.v000066400000000000000000000004761435245347300242440ustar00rootroot00000000000000// Check that specifing static lifetime for a class method taks results in an // error. module test; class C; // This should fail, all class methods have automatic lifetime task static t(int x); int y; y = 2 * x; endtask endclass initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_lt_static2.v000066400000000000000000000005361435245347300242420ustar00rootroot00000000000000// Check that specifing static lifetime for a class method function results in // an error. module test; class C; // This should fail, all class methods have automatic lifetime function static int t(int x); int y; y = 2 * x; return y; endfunction endclass initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_signed1.v000066400000000000000000000024611435245347300235230ustar00rootroot00000000000000// Check that the signedness of methods on user defined classes is handled // correctly. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end class C; function shortint s; return -1; endfunction function bit [15:0] u; return -1; endfunction endclass C c; int unsigned x = 10; int y = 10; int z; initial begin c = new; // These all evaluate as signed `check($signed(c.u()) < 0) `check(c.s() < 0) // These all evaluate as unsigned `check(c.u() > 0) `check({c.s()} > 0) `check($unsigned(c.s()) > 0) `check(c.s() > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = c.u() + x; `check(z === 65545) z = c.u() + y; `check(z === 65545) z = c.s() + x; `check(z === 65545) z = c.s() + y; `check(z === 9) // For ternary operators if one operand is unsigned the result is unsigend z = x ? c.u() : x; `check(z === 65535) z = x ? c.u() : y; `check(z === 65535) z = x ? c.s() : x; `check(z === 65535) z = x ? c.s() : y; `check(z === -1) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_signed2.v000066400000000000000000000010101435245347300235110ustar00rootroot00000000000000// Check that the signedness of methods on user defined classes is handled // correctly when passing the result to a system function. module test; class C; function shortint s; return -1; endfunction function bit [15:0] u; return -1; endfunction endclass C c; string s; initial begin c = new; s = $sformatf("%0d %0d", c.s(), c.u()); if (s == "-1 65535") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_method_var_init.v000066400000000000000000000007671435245347300240130ustar00rootroot00000000000000// Check that variable initialization as part of the declaration works as // expected in class methods. module test; class C; task t(bit check); int x = 10; // The initialization should happen on each invocation if (check) begin if (x === 10) begin $display("PASSED"); end else begin $display("FAILED"); end end x = 20; endtask endclass initial begin C c; c = new; c.t(1'b0); c.t(1'b1); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_fail1.v000066400000000000000000000002721435245347300224740ustar00rootroot00000000000000// Check that using the class new operator on a non-class variable results in an // error. module test; int i; initial begin i = new; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_fail2.v000066400000000000000000000003001435245347300224650ustar00rootroot00000000000000// Check that using the class new operator on a dynamic array variable results // in an error. module test; int i[]; initial begin i = new; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_init.v000066400000000000000000000005571435245347300224510ustar00rootroot00000000000000// Check that the class new initializer can be used for all sorts for variable // declarations package P; class C; endclass C c = new; endpackage module test; class C; task check; $display("PASSED"); endtask endclass class D; C c = new; endclass C c = new; initial begin static C c = new; c.check(); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed1.v000066400000000000000000000003211435245347300227010ustar00rootroot00000000000000// Check that typed constructor calls are supported. module test; class C; function new; $display("PASSED"); endfunction endclass initial begin C c; c = C::new; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed2.v000066400000000000000000000007061435245347300227110ustar00rootroot00000000000000// Check that typed constructor calls are supported when assigning to an // variable of a base class type. module test; class B; int x = 0; task check; if (x === 10) begin $display("PASSED"); end else begin $display("FAILED"); end endtask endclass class C extends B; function new; x = 10; endfunction endclass initial begin B b; b = C::new; b.check; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed3.v000066400000000000000000000004171435245347300227110ustar00rootroot00000000000000// Check that typed constructor calls are supported when the type is a typedef // of a class type. module test; class C; function new; $display("PASSED"); endfunction endclass typedef C T; initial begin T c; c = T::new; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed_fail1.v000066400000000000000000000004701435245347300237010ustar00rootroot00000000000000// Check that an error is reported when using a typed constructor call to assign // to a class that is not a base class. module test; class B; endclass class C; endclass initial begin B b; b = C::new; // This should fail, B is not a base class of C $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed_fail2.v000066400000000000000000000005641435245347300237060ustar00rootroot00000000000000// Check that an error is reported when using a typed constructor call to assign // to a class that is an inherited class. module test; class B; endclass class C extends B; endclass initial begin C c; c = B::new; // This should fail, B is a base class of C, but C is not a // base class of B. $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed_fail3.v000066400000000000000000000006661435245347300237120ustar00rootroot00000000000000// Check that an error is reported when using a typed constructor call to assign // to a class that has a common base class, but is not directly related. module test; class B; endclass class C extends B; endclass class D extends B; endclass initial begin D d; d = C::new; // This should fail, C and D share a common base class, but are // not compatible $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_new_typed_fail4.v000066400000000000000000000004431435245347300237040ustar00rootroot00000000000000// Check that an error is reported when trying to use a typed constructor call // with a type that is not a class. module test; class C; endclass typedef int T; initial begin C c; c = T::new; // This should fail, T is not a class $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_property_signed1.v000066400000000000000000000023521435245347300241260ustar00rootroot00000000000000// Check that the signedness of class properties are handled correctly when // accessing the property on a class object. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end class C; shortint s = -1; bit [15:0] u = -1; endclass C c; int unsigned x = 10; int y = 10; int z; initial begin c = new; // These all evaluate as signed `check(c.s < 0) `check($signed(c.u) < 0) // These all evaluate as unsigned `check(c.u > 0) `check({c.s} > 0) `check($unsigned(c.s) > 0) `check(c.s > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = c.u + x; `check(z === 65545) z = c.u + y; `check(z === 65545) z = c.s + x; `check(z === 65545) z = c.s + y; `check(z === 9) // For ternary operators if one operand is unsigned the result is unsigend z = x ? c.u : x; `check(z === 65535) z = x ? c.u : y; `check(z === 65535) z = x ? c.s : x; `check(z === 65535) z = x ? c.s : y; `check(z === -1) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_property_signed2.v000066400000000000000000000007201435245347300241240ustar00rootroot00000000000000// Check that the signedness of class properties are handled correctly when // accessing the property on a class object and passing it to a system function. module test; class C; shortint s = -1; bit [15:0] u = -1; endclass C c; string s; initial begin c = new; s = $sformatf("%0d %0d", c.s, c.u); if (s == "-1 65535") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_property_signed3.v000066400000000000000000000024601435245347300241300ustar00rootroot00000000000000// Check that the signedness of class properties are handled correctly when // accessing the property in a class method. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED: ", `"x`", `__LINE__); \ failed = 1'b1; \ end int unsigned x = 10; int y = 10; int z; class C; shortint s = -1; bit [15:0] u = -1; task test; // These all evaluate as signed `check(s < 0) `check($signed(u) < 0) // These all evaluate as unsigned `check(u > 0) `check({s} > 0) `check($unsigned(s) > 0) `check(s > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = u + x; `check(z === 65545) z = u + y; `check(z === 65545) z = s + x; `check(z === 65545) z = s + y; `check(z === 9) // For ternary operators if one operand is unsigned the result is unsigend z = x ? u : x; `check(z === 65535) z = x ? u : y; `check(z === 65535) z = x ? s : x; `check(z === 65535) z = x ? s : y; `check(z === -1) if (!failed) begin $display("PASSED"); end endtask endclass C c; initial begin c = new; c.test(); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_property_signed4.v000066400000000000000000000010151435245347300241240ustar00rootroot00000000000000// Check that the signedness of class properties are handled correctly when // accessing the property in a class method and passing it to a system function. module test; class C; shortint s = -1; bit [15:0] u = -1; task test; string str; str = $sformatf("%0d %0d", s, u); if (str == "-1 65535") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end endtask endclass C c; initial begin c = new; c.test(); end endmodule iverilog-12_0/ivtest/ivltests/sv_class_return.v000066400000000000000000000006111435245347300221430ustar00rootroot00000000000000// Check that functions returning a class object are supported module test; class C; int i; task t; if (i == 10) begin $display("PASSED"); end else begin $display("FAILED"); end endtask endclass function C f; C c; c = new; c.i = 10; return c; endfunction initial begin C c; c = f(); c.t; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_static_prop1.v000066400000000000000000000010141435245347300232320ustar00rootroot00000000000000// Check that static class properties can be accessed for read and write in // class tasks. Check the property is shared across all instances and has the // same value for all instances. class C; static int i; task t; int x; x = i; i = x + 1; endtask endclass module test; C c1 = new; C c2 = new; C c3 = new; initial begin c1.t(); c2.t(); if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_static_prop2.v000066400000000000000000000010431435245347300232350ustar00rootroot00000000000000// Check that static class properties can be accessed for read and write in // class tasks using `this`. Check the property is shared across all instances // and has the same value for all instances. class C; static int i; task t; int x; x = this.i; this.i = x + 1; endtask endclass module test; C c1 = new; C c2 = new; C c3 = new; initial begin c1.t(); c2.t(); if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_static_prop3.v000066400000000000000000000010271435245347300232400ustar00rootroot00000000000000// Check that static class properties can be accessed for read and write on a // class object. Check the property is shared across all instances and has the // same value for all instances. class C; static int i; endclass module test; C c1 = new; C c2 = new; C c3 = new; task t(C c); int x; x = c.i; c.i = x + 1; endtask initial begin t(c1); t(c2); if (c1.i == 2 && c2.i == 2 && c3.i == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_super1.v000066400000000000000000000006261435245347300220510ustar00rootroot00000000000000// Check that it is possible to explicitly call the base class constructor, even // if it does not take any parameters. Check that it is possible to call it with // parenthesis after the `new`. module test; class B; function new(); $display("PASSED"); endfunction endclass class C extends B; function new(); super.new(); endfunction endclass C c = new; endmodule iverilog-12_0/ivtest/ivltests/sv_class_super2.v000066400000000000000000000006271435245347300220530ustar00rootroot00000000000000// Check that it is possible to explicitly call the base class constructor, even // if it does not take any parameters. Check that it is possible to call it // without parenthesis after the `new`. module test; class B; function new(); $display("PASSED"); endfunction endclass class C extends B; function new(); super.new; endfunction endclass C c = new; endmodule iverilog-12_0/ivtest/ivltests/sv_class_super3.v000066400000000000000000000011021435245347300220410ustar00rootroot00000000000000// Check that `super` keyword can be used to access members of the base class class B; int x, y; task set_y; y = 2000; endtask function bit check_x; return x === 1000; endfunction endclass class C extends B; byte x, y; task set_x; super.x = 1000; endtask function bit check_y; return super.y === 2000; endfunction endclass module test; C c; initial begin c = new; c.set_x; c.set_y; if (c.check_x() && c.check_y()) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_super4.v000066400000000000000000000005101435245347300220440ustar00rootroot00000000000000// Check that `super` keyword can be used to call tasks of the base class class B; task t; $display("PASSED"); endtask endclass class C extends B; task t; $display("FAILED"); endtask task check; super.t; endtask endclass module test; C c; initial begin c = new; c.check; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_super5.v000066400000000000000000000006611435245347300220540ustar00rootroot00000000000000// Check that `super` keyword can be used to call functions of the base class class B; function int f; return 1; endfunction endclass class C extends B; function int f; return 2; endfunction task check; if (super.f() === 1) begin $display("PASSED"); end else begin $display("FAILED"); end endtask endclass module test; C c; initial begin c = new; c.check; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_super6.v000066400000000000000000000010461435245347300220530ustar00rootroot00000000000000// Check that `this.super` is supported class B; int x, y; task set_y; y = 2000; endtask function bit check_x; return x === 1000; endfunction endclass class C extends B; byte x, y; task set_x; this.super.x = 1000; endtask function bit check_y; return this.super.y === 2000; endfunction endclass module test; C c; initial begin c = new; c.set_x; c.set_y; if (c.check_x() && c.check_y()) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_class_task1.v000066400000000000000000000005011435245347300216450ustar00rootroot00000000000000// Check that it is possible to call a class task without parenthesis after the // task name when using the implicit `this` class handle. module test; class C; task a; $display("PASSED"); endtask task b; this.a; endtask endclass C c = new; initial begin c.b; end endmodule iverilog-12_0/ivtest/ivltests/sv_class_virt_new_fail.v000066400000000000000000000003221435245347300234530ustar00rootroot00000000000000// Check that an error is reported when trying to create an object of a virtual // class. module test; virtual class C; endclass C c; initial begin c = new; // This should fail end endmodule iverilog-12_0/ivtest/ivltests/sv_darray1.v000066400000000000000000000021501435245347300210020ustar00rootroot00000000000000/* * This demonstrates a basic dynamic array */ module main; int foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray2.v000066400000000000000000000021521435245347300210050ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; byte foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray3.v000066400000000000000000000021561435245347300210120ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; shortint foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray4.v000066400000000000000000000021551435245347300210120ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; longint foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray5.v000066400000000000000000000021521435245347300210100ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; real foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray5b.v000066400000000000000000000021571435245347300211570ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; shortreal foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray6.v000066400000000000000000000023171435245347300210140ustar00rootroot00000000000000 /* * This demonstrates a basic dynamic array */ module main; string foo[]; int idx; string tmp; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end tmp = "fooa"; for (idx = 0 ; idx < foo.size() ; idx += 1) begin tmp[3] = 'h41 + idx; foo[idx] = tmp; end $display("foo[7] = %0s", foo[7]); if (foo[7] != "fooH") begin $display("FAILED -- foo[7] = %0s (s.b. fooH)", foo[7]); $finish; end $display("foo[9] = %0s", foo[9]); if (foo[9] != "fooJ") begin $display("FAILED -- foo[9] = %0s (s.b. fooJ)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin tmp[3] = 'h41 + (idx%10); if (foo[idx%10] != tmp) begin $display("FAILED -- foo[%0d%%10] = %0s", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray7.v000066400000000000000000000022471435245347300210170ustar00rootroot00000000000000// Check that dynamic arrays of packed array types are supported module main; typedef reg [3:0] T1; typedef T1 [7:0] T2; T2 foo[]; int idx; initial begin if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d, s.b. 0", foo.size()); $finish; end foo = new[10]; if (foo.size() != 10) begin $display("FAILED -- foo.size()=%0d, s.b. 10", foo.size()); $finish; end for (idx = 0 ; idx < foo.size() ; idx += 1) begin foo[idx] = idx; end $display("foo[7] = %d", foo[7]); if (foo[7] != 7) begin $display("FAILED -- foo[7] = %0d (s.b. 7)", foo[7]); $finish; end $display("foo[9] = %d", foo[9]); if (foo[9] != 9) begin $display("FAILED -- foo[9] = %0d (s.b. 9)", foo[9]); $finish; end for (idx = 0 ; idx < 2*foo.size() ; idx += 1) begin if (foo[idx%10] != (idx%10)) begin $display("FAILED -- foo[%0d%%10] = %0d", idx, foo[idx%10]); $finish; end end foo.delete(); if (foo.size() != 0) begin $display("FAILED -- foo.size()=%0d (after delete: s.b. 0)", foo.size()); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray_args1.v000066400000000000000000000012411435245347300220160ustar00rootroot00000000000000 program main; function int sum_array(bit[7:0] array[]); int idx; sum_array = 0; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array += array[idx]; endfunction // sum_array bit [7:0] obj[]; int foo; initial begin foo = sum_array('{}); if (foo !== 0) begin $display("FAILED -- sum of empty array returns %0d", foo); $finish; end obj = new[3]; obj[0] = 1; obj[1] = 2; obj[2] = 3; foo = sum_array(obj); if (foo !== 6) begin $display("FAILED -- sum of '{1,2,3} is %0d", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_darray_args2.v000066400000000000000000000015161435245347300220240ustar00rootroot00000000000000 program main; function real sum_array(real array[]); int idx; sum_array = 0.0; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array = sum_array + array[idx]; endfunction // sum_array real obj[]; real foo; initial begin foo = sum_array('{}); if (foo != 0.0) begin $display("FAILED -- sum of empty array returns %0d", foo); $finish; end obj = new[3]; obj = '{1.0,2.0,3.0}; foo = sum_array(obj); if (foo != 6.0) begin $display("FAILED -- sum of '{%f,%f,%f} is %0d", obj[0], obj[1], obj[2], foo); $finish; end obj = new[3] ('{4.0,5.0,6.0}); foo = sum_array(obj); if (foo != 15.0) begin $display("FAILED -- sum of '{4,5,6} is %0d", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_darray_args2b.v000066400000000000000000000015021435245347300221610ustar00rootroot00000000000000 program main; function real sum_array(real array[]); int idx; sum_array = 0.0; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array = sum_array + array[idx]; endfunction // sum_array real obj[]; real foo; initial begin foo = sum_array('{}); if (foo != 0.0) begin $display("FAILED -- sum of empty array returns %0d", foo); $finish; end obj = new[3]; obj = '{1,2,3}; foo = sum_array(obj); if (foo != 6.0) begin $display("FAILED -- sum of '{%f,%f,%f} is %0d", obj[0], obj[1], obj[2], foo); $finish; end obj = new[3] ('{4,5,6}); foo = sum_array(obj); if (foo != 15.0) begin $display("FAILED -- sum of '{4,5,6} is %0d", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_darray_args3.v000066400000000000000000000011641435245347300220240ustar00rootroot00000000000000 program main; function real sum_array(real array[]); int idx; sum_array = 0.0; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array = sum_array + array[idx]; endfunction // sum_array real obj[]; real foo; initial begin foo = sum_array('{}); if (foo != 0.0) begin $display("FAILED -- sum of empty array returns %0d", foo); $finish; end obj = new[3] (3.0); foo = sum_array(obj); if (foo != 9.0) begin $display("FAILED -- sum of '{3.3.3} is %0d", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_darray_args4.v000066400000000000000000000017671435245347300220360ustar00rootroot00000000000000 program main; function string sum_array(string array[]); int idx; sum_array = ""; for (idx = 0 ; idx < array.size() ; idx = idx+1) sum_array = {sum_array, array[idx]}; endfunction // sum_array string obj[]; string foo; initial begin foo = sum_array('{}); if (foo != "") begin $display("FAILED -- sum of empty array returns %0s", foo); $finish; end obj = new[3]; obj = '{"1", "2", "3"}; foo = sum_array(obj); if (foo != "123") begin $display("FAILED -- sum of '{\"1\",\"2\",\"3\"} is %0s", foo); $finish; end obj = new[3] ('{"A", "B", "C"}); foo = sum_array(obj); if (foo != "ABC") begin $display("FAILED -- sum of '{\"A\",\"B\",\"C\"} is %0s", foo); $finish; end obj = new[3] ("A"); foo = sum_array(obj); if (foo != "AAA") begin $display("FAILED -- sum of \"AAA\" is %0s", foo); $finish; end $display("PASSED"); end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_darray_assign1.v000066400000000000000000000011151435245347300223460ustar00rootroot00000000000000// Check that dynamic arrays with compatible packed base types can be assigned // to each other. Even if the element types are not identical. module test; typedef bit [31:0] T1; typedef bit [31:0] T2[]; // For two packed types to be compatible they need to have the same packed // width, both be 2-state or 4-state and both be either signed or unsigned. bit [32:1] d1[]; bit [7:0][3:0] d2[]; int unsigned d3[]; T1 d4[]; T2 d5; initial begin d1 = new[1]; d2 = d1; d3 = d2; d4 = d3; d5 = d4; d1 = d5; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign2.v000066400000000000000000000014131435245347300223500ustar00rootroot00000000000000// Check that dynamic arrays with compatible packed base types can be passed as // task arguments. Even it the element types are not identical. module test; typedef logic [31:0] T[]; task t1(logic [31:0] d[]); d[0] = 1; endtask task t2(logic [7:0][3:0] d[]); d[0] = 1; endtask task t3([31:0] d[]); d[0] = 1; endtask task t4(T d); d[0] = 1; endtask // For two packed types to be compatible they need to have the same packed // width, both be 2-state or 4-state and both be either signed or unsigned. logic [31:0] d1[]; logic [7:0][3:0] d2[]; initial begin d1 = new[1]; d2 = new[1]; t1(d1); t1(d2); t2(d1); t2(d2); t3(d1); t3(d2); t4(d1); t4(d2); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail1.v000066400000000000000000000004571435245347300233510ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with a 2-state // element type to a dynamic array with 4-state element type. Even if they are // otherwise identical. module test; logic [31:0] d1[]; bit [31:0] d2[]; initial begin d1 = d2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail2.v000066400000000000000000000004721435245347300233470ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with a signed element // type to a dynamic array with a unsigned element type. Even if they are // otherwise identical. module test; logic [31:0] d1[]; logic signed [31:0] d2[]; initial begin d1 = d2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail3.v000066400000000000000000000003241435245347300233440ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with different // element type width. module test; int d1[]; shortint d2[]; initial begin d1 = d2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail4.v000066400000000000000000000005161435245347300233500ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with an enum // element type to a dynamic array with a packed type. Even if the enum base // type is the same as the packed type. module test; enum logic [31:0] { A } d1[]; logic [31:0] d2[]; initial begin d1 = d2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail5.v000066400000000000000000000003631435245347300233510ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with a real // element type to a dynamic array with an int element type. module test; int d1[]; real d2[]; initial begin d1 = d2; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_assign_fail6.v000066400000000000000000000003631435245347300233520ustar00rootroot00000000000000// Check that it is not possible to assign a dynamic array with an int // element type to a dynamic array with a real element type. module test; real d1[]; int d2[]; initial begin d1 = d2; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_copy_empty1.v000066400000000000000000000004521435245347300232550ustar00rootroot00000000000000// Check that it is possible to copy an empty dynamic array. module test; initial begin int d1[]; int d2[]; d1 = '{1, 2, 3}; d1 = d2; if (d1.size() == 0 && d2.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_copy_empty2.v000066400000000000000000000004601435245347300232550ustar00rootroot00000000000000// Check that it is possible to copy an empty queue to an dynamic array. module test; initial begin int d[]; int q[$]; d = '{1, 2, 3}; d = q; if (d.size() == 0 && q.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_copy_empty3.v000066400000000000000000000005321435245347300232560ustar00rootroot00000000000000// Check that it is possible to copy an empty dynamic array using a dynamic // array new operation. module test; initial begin int d1[]; int d2[]; d1 = '{1, 2, 3}; d1 = new [2](d2); if (d1.size() == 2 && d2.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_copy_empty4.v000066400000000000000000000005371435245347300232640ustar00rootroot00000000000000// Check that it is possible to copy an empty queue to a dynamic array using a // dynamic array new operation. module test; initial begin int d[]; int q[$]; d = '{1, 2, 3}; d = new [2](q); if (d.size() == 2 && q.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_decl_assign.v000066400000000000000000000014711435245347300232610ustar00rootroot00000000000000package mypackage; logic [1:0] array1[] = new[4]; logic [1:0] array2[] = new[4]('{0,1,2,3}); endpackage module test(); import mypackage::*; logic [1:0] array3[] = new[4]; logic [1:0] array4[] = new[4]('{0,1,2,3}); reg failed = 0; initial begin foreach (array1[i]) begin array1[i] = i; end foreach (array1[i]) begin $display(array1[i]); if (array1[i] !== i) failed = 1; end foreach (array2[i]) begin $display(array2[i]); if (array2[i] !== i) failed = 1; end foreach (array3[i]) begin array3[i] = i; end foreach (array3[i]) begin $display(array3[i]); if (array3[i] !== i) failed = 1; end foreach (array4[i]) begin $display(array4[i]); if (array4[i] !== i) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_function.v000066400000000000000000000034511435245347300226330ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for dynamic arrays used as the function parameters and return type. module sv_darray_function(); typedef logic[7:0] byte_array []; typedef logic[3*8-1:0] byte_vector; function byte_array inc_array(byte_array inp); byte_array tmp; tmp = new[$size(inp)]; for(int i = 0; i < $size(inp); ++i) begin tmp[i] = inp[i] + 1; end return tmp; endfunction initial begin byte_array a, b; byte_vector c; a = new[3]; a[0] = 10; a[1] = 11; a[2] = 12; b = inc_array(a); if($size(a) != 3 || a[0] !== 10 || a[1] !== 11 || a[2] !== 12) begin $display("FAILED 1"); $finish(); end if($size(b) != 3 || b[0] !== 11 || b[1] !== 12 || b[2] !== 13) begin $display("FAILED 2"); $finish(); end // Cast dynamic array returned by function to logic vector c = byte_vector'(inc_array(b)); if(c !== 24'h0c0d0e) begin $display("FAILED 3"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_nest1.v000066400000000000000000000002141435245347300220320ustar00rootroot00000000000000// Check that declarations for dynamic arrays of queues are supported. module test; // Dynamic array of queues int q[$][]; endmodule iverilog-12_0/ivtest/ivltests/sv_darray_nest2.v000066400000000000000000000002331435245347300220340ustar00rootroot00000000000000// Check that declarations for dynamic arrays of dynamic arrays are supported. module test; // Dynamic array of dynamic arrays int q[][]; endmodule iverilog-12_0/ivtest/ivltests/sv_darray_nest3.v000066400000000000000000000002371435245347300220410ustar00rootroot00000000000000// Check that declarations for dynamic arrays of unpacked arrays are supported. module test; // Dynamic array of unpacked arrays int q[10][]; endmodule iverilog-12_0/ivtest/ivltests/sv_darray_nest4.v000066400000000000000000000002371435245347300220420ustar00rootroot00000000000000// Check that declarations for unpacked arrays of dynamic arrays are supported. module test; // Unpacked array of dynamic arrays int q[][10]; endmodule iverilog-12_0/ivtest/ivltests/sv_darray_oob_real.v000066400000000000000000000004761435245347300225740ustar00rootroot00000000000000// Check that out-of-bounds access on a real typed dynamic array works and // returns the correct value. module test; real d[]; real x; initial begin x = d[1]; if (x == 0.0) begin $display("PASSED"); end else begin $display("FAILED. Expected 0.0, got %f", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_oob_string.v000066400000000000000000000005021435245347300231450ustar00rootroot00000000000000// Check that out-of-bounds access on a string typed dynamic array works and // returns the right value. module test; string d[]; string x; initial begin x = d[1]; if (x == "") begin $display("PASSED"); end else begin $display("FAILED. Expected '', got '%s'", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_oob_vec2.v000066400000000000000000000005251435245347300225030ustar00rootroot00000000000000// Check that out-of-bounds access on a 2-state vector dynamic array works and // returns the correct value. module test; bit [7:0] d[]; logic [7:0] x; initial begin x = d[1]; if (x === 8'h00) begin $display("PASSED"); end else begin $display("FAILED. Expected 00000000, got %b",x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_oob_vec4.v000066400000000000000000000005301435245347300225010ustar00rootroot00000000000000// Check that out-of-bounds access on a 4-state vector dynamic array works and // returns the correct value. module test; logic [7:0] d[]; logic [7:0] x; initial begin x = d[1]; if (x === 8'hxx) begin $display("PASSED"); end else begin $display("FAILED. Expected xxxxxxxx, got %b", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_darray_signed.v000066400000000000000000000011241435245347300222520ustar00rootroot00000000000000module main; bit pass; bit signed [7:0] s8[]; bit [7:0] u8[]; string res, fmt; initial begin pass = 1'b1; s8 = new[2]; u8 = new[2]; s8[0] = -1; u8[0] = -1; fmt = "%0d"; $display(fmt, s8[0]); $sformat(res, fmt, s8[0]); if (res != "-1") begin $display("Failed: expected '-1', got '%s'", res); pass = 1'b0; end $display(fmt, u8[0]); $swrite(res, u8[0]); if (res != "255") begin $display("Failed: expected '255', got '%s'", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_darray_word_size.v000066400000000000000000000034161435245347300230140ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests if dynamic array words are of appropriate size. module sv_cast_string(); bit [6:1] darr []; bit [63:0] darr_64 []; logic [4:10] darr_rev []; initial begin darr = new[4]; darr_64 = new[8]; darr_rev = new[3]; if($size(darr[0]) != 6 || $size(darr_64[2]) != 64 || $size(darr_rev[1]) != 7 || $size(darr) != 4 || $size(darr_64) != 8 || $size(darr_rev) != 3) begin $display("FAILED"); $finish(); end darr[0] = 6'b110011; darr[1] = 6'b000011; darr[2] = darr[0] + darr[1]; darr_64[0] = 64'hcafe0000dead0000; darr_64[1] = 64'h0000bad00000d00d; darr_64[2] = darr_64[0] + darr_64[1]; darr_rev[0] = 7'b1111000; darr_rev[1] = 7'b0000011; darr_rev[2] = darr_rev[0] + darr_rev[1]; if(darr[2] !== 6'b110110 || darr_64[2] !== 64'hcafebad0deadd00d || darr_rev[2] !== 7'b1111011) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_default_port_value1.v000066400000000000000000000003741435245347300234120ustar00rootroot00000000000000module dut(input wire [7:0] i = 8'd10, output wire [7:0] o); assign o = i; endmodule module tb(); wire [7:0] result; dut dut(,result); initial begin #1; if (result === 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_default_port_value2.v000066400000000000000000000003771435245347300234160ustar00rootroot00000000000000module dut(input wire [7:0] i = 8'd10, output wire [7:0] o); assign o = i; endmodule module tb(); wire [7:0] result; dut dut(.o(result)); initial begin #1; if (result === 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_default_port_value3.v000066400000000000000000000004061435245347300234100ustar00rootroot00000000000000reg [7:0] v; module dut(input wire [7:0] i = v, output wire [7:0] o); assign o = i; endmodule module tb(); wire [7:0] result; dut dut(,result); initial begin #1; if (result === 10) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_deferred_assert1.v000066400000000000000000000014061435245347300226640ustar00rootroot00000000000000// This just tests the compiler accepts the syntax. It needs to be improved // when deferred assertions are supported. module test(); integer i = 1; initial begin assert #0 (i == 1); assert #0 (i == 0); assert #0 (i == 1) else $display("Check 3 : this shouldn't be displayed"); assert #0 (i == 0) else $display("Check 4 : this should be displayed"); assert #0 (i == 1) $display("Check 5 : this should be displayed"); assert #0 (i == 0) $display("Check 6 : this shouldn't be displayed"); assert #0 (i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assert #0 (i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_deferred_assert2.v000066400000000000000000000014361435245347300226700ustar00rootroot00000000000000// This just tests the compiler accepts the syntax. It needs to be improved // when deferred assertions are supported. module test(); integer i = 1; initial begin assert final (i == 1); assert final (i == 0); assert final (i == 1) else $display("Check 3 : this shouldn't be displayed"); assert final (i == 0) else $display("Check 4 : this should be displayed"); assert final (i == 1) $display("Check 5 : this should be displayed"); assert final (i == 0) $display("Check 6 : this shouldn't be displayed"); assert final (i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assert final (i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_deferred_assume1.v000066400000000000000000000014061435245347300226600ustar00rootroot00000000000000// This just tests the compiler accepts the syntax. It needs to be improved // when deferred assumeions are supported. module test(); integer i = 1; initial begin assume #0 (i == 1); assume #0 (i == 0); assume #0 (i == 1) else $display("Check 3 : this shouldn't be displayed"); assume #0 (i == 0) else $display("Check 4 : this should be displayed"); assume #0 (i == 1) $display("Check 5 : this should be displayed"); assume #0 (i == 0) $display("Check 6 : this shouldn't be displayed"); assume #0 (i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assume #0 (i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_deferred_assume2.v000066400000000000000000000014361435245347300226640ustar00rootroot00000000000000// This just tests the compiler accepts the syntax. It needs to be improved // when deferred assumeions are supported. module test(); integer i = 1; initial begin assume final (i == 1); assume final (i == 0); assume final (i == 1) else $display("Check 3 : this shouldn't be displayed"); assume final (i == 0) else $display("Check 4 : this should be displayed"); assume final (i == 1) $display("Check 5 : this should be displayed"); assume final (i == 0) $display("Check 6 : this shouldn't be displayed"); assume final (i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assume final (i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_end_label.v000066400000000000000000000016111435245347300213450ustar00rootroot00000000000000module top; initial begin: b_label $display("PASSED"); end: b_label initial fork:fj_label join:fj_label initial fork:fja_label join_any:fja_label initial fork:fjn_label join_none:fjn_label task t_label; endtask: t_label task twa_label(input arg); endtask: twa_label function fn_label; input arg; endfunction: fn_label function fa_label(input in); endfunction: fa_label endmodule:top macromodule extra; parameter add_inv = 1; reg a; wire y, yb; pbuf dut(y, a); if (add_inv) begin: g_label pinv dut2(yb, y); end: g_label endmodule: extra package pkg; endpackage: pkg program pgm; class foo; endclass: foo endprogram: pgm primitive pbuf (out, in); output out; input in; table 0 : 0; 1 : 1; endtable endprimitive: pbuf primitive pinv (output out, input in); table 0 : 1; 1 : 0; endtable endprimitive: pinv iverilog-12_0/ivtest/ivltests/sv_end_label_fail.v000066400000000000000000000016471435245347300223510ustar00rootroot00000000000000module top; initial begin: b_label $display("FAILED"); end: b_label_f initial fork:fj_label join:fj_label_f initial fork:fja_label join_any:fja_label_f initial fork:fjn_label join_none:fjn_label_f task t_label; endtask: t_label_f task twa_label(input arg); endtask: twa_label_f function fn_label; input arg; endfunction: fn_label_f function fa_label(input in); endfunction: fa_label_f endmodule:top_f macromodule extra; parameter add_inv = 1; reg a; wire y, yb; pbuf dut(y, a); if (add_inv) begin: g_label pinv dut2(yb, y); end: g_label_f endmodule: extra_f package pkg; endpackage: pkg_f program pgm; class foo; endclass: foo_f endprogram: pgm_f primitive pbuf (out, in); output out; input in; table 0 : 0; 1 : 1; endtable endprimitive: pbuf primitive pinv (output out, input in); table 0 : 1; 1 : 0; endtable endprimitive: pinv_f iverilog-12_0/ivtest/ivltests/sv_end_labels.v000066400000000000000000000005111435245347300215260ustar00rootroot00000000000000// This tests end labes (test should pass compilation) // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // error counter bit err = 0; initial begin : dummy_label if (!err) $display("PASSED"); end : dummy_label endmodule : test iverilog-12_0/ivtest/ivltests/sv_end_labels_bad.v000066400000000000000000000005141435245347300223370ustar00rootroot00000000000000// This tests end labes (should fail compilation) // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // error counter bit err = 0; initial begin : dummy_label if (!err) $display("PASSED"); end : dummy_label_bad endmodule : test_bad iverilog-12_0/ivtest/ivltests/sv_end_labels_unnamed.v000066400000000000000000000003171435245347300232410ustar00rootroot00000000000000// Check that end labels on unnamed blocks generate an error module test; generate if (1) begin end : label endgenerate initial begin end : label initial fork join : label endmodule iverilog-12_0/ivtest/ivltests/sv_enum1.v000066400000000000000000000014051435245347300204660ustar00rootroot00000000000000 module foo_mod(output reg pass_flag, input wire go_flag); typedef enum logic [1:0] { W0, W1, W2 } foo_t; foo_t foo; always @(posedge go_flag) begin pass_flag = 0; if ($bits(foo) !== 2) begin $display("FAILED -- $bits(foo)=%0d", $bits(foo)); $finish; end if ($bits(foo_t) !== 2) begin $display("FAILED -- $bits(foo_t)=%0d", $bits(foo_t)); $finish; end pass_flag = 1; end endmodule module main; logic go_flag = 0; wire [1:0] pass_flag; foo_mod dut[1:0] (.pass_flag(pass_flag), .go_flag(go_flag)); initial begin #1 go_flag = 1; #1 if (pass_flag !== 2'b11) begin $display("FAILED -- pass_flag=%b", pass_flag); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_for_variable.v000066400000000000000000000007071435245347300221000ustar00rootroot00000000000000 program main; int sum; logic idx; // Use this to test scope; initial begin sum = 0; idx = 1'bx; for (int idx = 0 ; idx < 8 ; idx += 1) begin sum += idx; end if (sum != 28) begin $display("FAILED -- sum=%0d", sum); $finish; end if (idx !== 1'bx) begin $display("FAILED -- idx in upper scope became %b", idx); $finish; end $display("PASSED"); end // initial begin endprogram iverilog-12_0/ivtest/ivltests/sv_foreach1.v000066400000000000000000000033301435245347300211300ustar00rootroot00000000000000/* * Copyright (c) 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. */ `default_nettype none module main; reg [4:0] foo [0:3][0:7]; bit [3:0] idx1, idx2; initial begin for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) foo[idx1][idx2] = {idx1[1:0], idx2[2:0]}; end foreach (foo[ia,ib]) begin if (ia > 3 || ib > 7) begin $display("FAILED -- index out of range: ia=%0d, ib=%0d", ia, ib); $finish; end if (foo[ia][ib] !== {ia[1:0], ib[2:0]}) begin $display("FAILED -- foo[%0d][%0d] == %b", ia, ib, foo[ia][ib]); $finish; end foo[ia][ib] = 5'bzzzz; end for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) if (foo[idx1][idx2] !== 5'bzzzz) begin $display("FAILED -- foreach failed to visit foo[%0d][%0d]", idx1,idx2); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_foreach2.v000066400000000000000000000036351435245347300211410ustar00rootroot00000000000000/* * Copyright (c) 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. */ `default_nettype none module main; class test_t; reg [1:0] a; reg [2:0] b; function new (int ax, int bx); begin a = ax; b = bx; end endfunction // new endclass // test_t test_t foo [0:3][0:7], tmp; bit [3:0] idx1, idx2; initial begin for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) foo[idx1][idx2] = new(idx1,idx2); end foreach (foo[ia,ib]) begin if (ia > 3 || ib > 7) begin $display("FAILED -- index out of range: ia=%0d, ib=%0d", ia, ib); $finish; end tmp = foo[ia][ib]; if (tmp.a !== ia[1:0] || tmp.b !== ib[2:0]) begin $display("FAILED -- foo[%0d][%0d] == %b", ia, ib, {tmp.a, tmp.b}); $finish; end foo[ia][ib] = null; end for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) if (foo[idx1][idx2] != null) begin $display("FAILED -- foreach failed to visit foo[%0d][%0d]", idx1,idx2); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_foreach3.v000066400000000000000000000042151435245347300211350ustar00rootroot00000000000000/* * Copyright (c) 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. */ `default_nettype none module main; class test_t; reg [1:0] a; reg [2:0] b; function new (int ax, int bx); begin a = ax; b = bx; end endfunction // new endclass // test_t class container_t; test_t foo [0:3][0:7]; function new(); bit [3:0] idx1, idx2; begin for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) foo[idx1][idx2] = new(idx1,idx2); end end endfunction // new task run(); bit [3:0] idx1, idx2; test_t tmp; foreach (foo[ia,ib]) begin if (ia > 3 || ib > 7) begin $display("FAILED -- index out of range: ia=%0d, ib=%0d", ia, ib); $finish; end tmp = foo[ia][ib]; if (tmp.a !== ia[1:0] || tmp.b !== ib[2:0]) begin $display("FAILED -- foo[%0d][%0d] == %b", ia, ib, {tmp.a, tmp.b}); $finish; end foo[ia][ib] = null; end for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) if (foo[idx1][idx2] != null) begin $display("FAILED -- foreach failed to visit foo[%0d][%0d]", idx1,idx2); $finish; end end endtask // run endclass container_t dut; initial begin dut = new; dut.run; $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_foreach4.v000066400000000000000000000041751435245347300211430ustar00rootroot00000000000000/* * Copyright (c) 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. */ `default_nettype none class test_t; reg [1:0] a; reg [2:0] b; function new (int ax, int bx); begin a = ax; b = bx; end endfunction // new endclass // test_t module main; class container_t; test_t foo [0:3][0:7]; function new(); bit [3:0] idx1, idx2; begin for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) foo[idx1][idx2] = new(idx1,idx2); end end endfunction // new task run(); bit [3:0] idx1, idx2; test_t tmp; foreach (foo[ia,ib]) begin if (ia > 3 || ib > 7) begin $display("FAILED -- index out of range: ia=%0d, ib=%0d", ia, ib); $finish; end tmp = foo[ia][ib]; if (tmp.a !== ia[1:0] || tmp.b !== ib[2:0]) begin $display("FAILED -- foo[%0d][%0d] == %b", ia, ib, {tmp.a, tmp.b}); $finish; end foo[ia][ib] = null; end for (idx1 = 0 ; idx1 < 4 ; idx1 = idx1+1) begin for (idx2 = 0 ; idx2 <= 7 ; idx2 = idx2+1) if (foo[idx1][idx2] != null) begin $display("FAILED -- foreach failed to visit foo[%0d][%0d]", idx1,idx2); $finish; end end endtask // run endclass container_t dut; initial begin dut = new; dut.run; $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_foreach5.v000066400000000000000000000014641435245347300211420ustar00rootroot00000000000000module test(); reg [3:0] array[0:1][0:2]; reg [3:0] expected; reg failed = 0; initial begin for (int i = 0; i < 2; i++) begin for (int j = 0; j < 3; j++) begin array[i][j] = i * 4 + j; end end foreach (array[i,j,k]) begin expected = i * 4 + j; $display("Value of array[%0d][%0d][%0d]=%b", i, j, k, array[i][j][k]); if (array[i][j][k] !== expected[k]) failed = 1; end foreach (array[i,j]) begin expected = i * 4 + j; $display("Value of array[%0d][%0d]=%h", i, j, array[i][j]); if (array[i][j] !== expected) failed = 1; end foreach (array[i]) begin expected = i * 4; $display("Value of array[%0d][0]=%h", i, array[i][0]); if (array[i][0] !== expected) failed = 1; end if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_foreach6.v000066400000000000000000000005331435245347300211370ustar00rootroot00000000000000// Check that foreach loops without an index list work as expected. This is not // particularly useful, but it is legal code. module test; logic a[10]; int i = 0; initial begin foreach(a[]) begin i++; end if (i == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_foreach7.v000066400000000000000000000005451435245347300211430ustar00rootroot00000000000000// Check that foreach loops with only empty indices works as expected. This is // not particularly useful, but it is legal code. module test; logic a[2][3][4]; int i = 0; initial begin foreach(a[,,]) begin i++; end if (i == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_foreach8.v000066400000000000000000000005731435245347300211450ustar00rootroot00000000000000// Check that it is possible to omit a dimensions in a foreach loop by not // specifying a loop identifiers for the dimension. module test; logic a[2][3][4]; int k = 0; initial begin foreach(a[i,,j]) begin $display(i, j); k++; end if (k == 8) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_foreach_fail1.v000066400000000000000000000003721435245347300221260ustar00rootroot00000000000000// Check that an error is reported if the number of loop indices exceeds the // number of array dimensions in a foreach loop. module test; logic a[10]; initial begin foreach(a[i,j]) begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_immediate_assert.v000066400000000000000000000011571435245347300227640ustar00rootroot00000000000000module test(); integer i = 1; initial begin assert(i == 1); assert(i == 0); assert(i == 1) else $display("Check 3 : this shouldn't be displayed"); assert(i == 0) else $display("Check 4 : this should be displayed"); assert(i == 1) $display("Check 5 : this should be displayed"); assert(i == 0) $display("Check 6 : this shouldn't be displayed"); assert(i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assert(i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_immediate_assume.v000066400000000000000000000011571435245347300227600ustar00rootroot00000000000000module test(); integer i = 1; initial begin assume(i == 1); assume(i == 0); assume(i == 1) else $display("Check 3 : this shouldn't be displayed"); assume(i == 0) else $display("Check 4 : this should be displayed"); assume(i == 1) $display("Check 5 : this should be displayed"); assume(i == 0) $display("Check 6 : this shouldn't be displayed"); assume(i == 1) $display("Check 7 : this should be displayed"); else $display("Check 7 : this shouldn't be displayed"); assume(i == 0) $display("Check 8 : this shouldn't be displayed"); else $display("Check 8 : this should be displayed"); end endmodule iverilog-12_0/ivtest/ivltests/sv_interface.v000066400000000000000000000061331435245347300214040ustar00rootroot00000000000000// This tests SystemVerilog interfaces // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // error counter bit err = 0; logic clk = 1'b1; logic rst = 1'b1; // reset integer rst_cnt = 0; // clock generator always #5 clk = ~clk; // reset is removed after a delay always @ (posedge clk) begin rst_cnt <= rst_cnt + 1; rst <= rst_cnt <= 3; end // counters int cnt; int cnt_src; int cnt_drn; // add all counters assign cnt = cnt_src + cnt_drn + inf.cnt; // finish report initial begin wait (cnt == 3*16); if (!err) $display("PASSED"); $finish; end // interface instance handshake inf ( .clk (clk), .rst (rst) ); // source instance source #( .RW (8), .RP (8'b11100001) ) source ( .clk (clk), .rst (rst), .inf (inf), .cnt (cnt_src) ); // drain instance drain #( .RW (8), .RP (8'b11010100) ) drain ( .clk (clk), .rst (rst), .inf (inf), .cnt (cnt_drn) ); endmodule // interface definition interface handshake #( parameter int unsigned WC = 32 )( input logic clk, input logic rst ); // modport signals logic req; // request logic grt; // grant logic inc; // increment // local signals integer cnt; // counter // source modport src ( output req, input grt ); // drain modport drn ( input req, output grt ); // incremet condition assign inc = req & grt; // local logic (counter) always @ (posedge clk, posedge rst) if (rst) cnt <= '0; else cnt <= cnt + inc; endinterface // source module module source #( // random generator parameters parameter int unsigned RW=1, // LFSR width parameter bit [RW-1:0] RP='0, // LFSR polinom parameter bit [RW-1:0] RR='1 // LFSR reset state )( input logic clk, input logic rst, handshake.src inf, output integer cnt ); // LFSR logic [RW-1:0] rnd; // LFSR in Galois form always @ (posedge clk, posedge rst) if (rst) rnd <= RR; else rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP); // counter always @ (posedge clk, posedge rst) if (rst) cnt <= 32'd0; else cnt <= cnt + (inf.req & inf.grt); // request signal assign inf.req = rnd[0]; endmodule // drain module module drain #( // random generator parameters parameter int unsigned RW=1, // LFSR width parameter bit [RW-1:0] RP='0, // LFSR polinom parameter bit [RW-1:0] RR='1 // LFSR reset state )( input logic clk, input logic rst, handshake.drn inf, output integer cnt ); // LFSR logic [RW-1:0] rnd; // LFSR in Galois form always @ (posedge clk, posedge rst) if (rst) rnd <= RR; else rnd <= {rnd[0], rnd[RW-1:1]} ^ ({RW{rnd[0]}} & RP); // counter always @ (posedge clk, posedge rst) if (rst) cnt <= 32'd0; else cnt <= cnt + (inf.req & inf.grt); // grant signal assign inf.grt = rnd[0]; endmodule iverilog-12_0/ivtest/ivltests/sv_literals.v000066400000000000000000000577671435245347300213060ustar00rootroot00000000000000// This tests literal values, from verilog 2001 and SystemVerilog // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // logic vector logic unsigned [15:0] luv; // logic unsigned vector logic signed [15:0] lsv; // logic signed vector // error counter bit err = 0; initial begin // unsized literals without base luv = '0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != '0", luv); err=1; end luv = '1; if (luv !== 16'b1111_1111_1111_1111) begin $display("FAILED -- luv = 'b%b != '1", luv); err=1; end luv = 'x; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'x", luv); err=1; end luv = 'z; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'z", luv); err=1; end // unsized binary literals single character luv = 'b0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'b0", luv); err=1; end luv = 'b1; if (luv !== 16'b0000_0000_0000_0001) begin $display("FAILED -- luv = 'b%b != 'b1", luv); err=1; end luv = 'bx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'bx", luv); err=1; end luv = 'bz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'bz", luv); err=1; end // unsized binary literals two characters luv = 'b00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'b00", luv); err=1; end luv = 'b11; if (luv !== 16'b0000_0000_0000_0011) begin $display("FAILED -- luv = 'b%b != 'b11", luv); err=1; end luv = 'bxx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'bxx", luv); err=1; end luv = 'bzz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'bzz", luv); err=1; end luv = 'b1x; if (luv !== 16'b0000_0000_0000_001x) begin $display("FAILED -- luv = 'b%b != 'b1x", luv); err=1; end luv = 'b1z; if (luv !== 16'b0000_0000_0000_001z) begin $display("FAILED -- luv = 'b%b != 'b1z", luv); err=1; end luv = 'bx1; if (luv !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- luv = 'b%b != 'bx1", luv); err=1; end luv = 'bz1; if (luv !== 16'bzzzz_zzzz_zzzz_zzz1) begin $display("FAILED -- luv = 'b%b != 'bz1", luv); err=1; end // unsized binary literals single character luv = 'o0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'o0", luv); err=1; end luv = 'o5; if (luv !== 16'b0000_0000_0000_0101) begin $display("FAILED -- luv = 'b%b != 'o5", luv); err=1; end luv = 'ox; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'ox", luv); err=1; end luv = 'oz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'oz", luv); err=1; end // unsized binary literals two characters luv = 'o00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'o00", luv); err=1; end luv = 'o55; if (luv !== 16'b0000_0000_0010_1101) begin $display("FAILED -- luv = 'b%b != 'o55", luv); err=1; end luv = 'oxx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'oxx", luv); err=1; end luv = 'ozz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'ozz", luv); err=1; end luv = 'o5x; if (luv !== 16'b0000_0000_0010_1xxx) begin $display("FAILED -- luv = 'b%b != 'o5x", luv); err=1; end luv = 'o5z; if (luv !== 16'b0000_0000_0010_1zzz) begin $display("FAILED -- luv = 'b%b != 'o5z", luv); err=1; end luv = 'ox5; if (luv !== 16'bxxxx_xxxx_xxxx_x101) begin $display("FAILED -- luv = 'b%b != 'ox5", luv); err=1; end luv = 'oz5; if (luv !== 16'bzzzz_zzzz_zzzz_z101) begin $display("FAILED -- luv = 'b%b != 'oz5", luv); err=1; end // unsized binary literals single character luv = 'h0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'h0", luv); err=1; end luv = 'h9; if (luv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- luv = 'b%b != 'h9", luv); err=1; end luv = 'hx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'hx", luv); err=1; end luv = 'hz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'hz", luv); err=1; end // unsized binary literals two characters luv = 'h00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'h00", luv); err=1; end luv = 'h99; if (luv !== 16'b0000_0000_1001_1001) begin $display("FAILED -- luv = 'b%b != 'h99", luv); err=1; end luv = 'hxx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'hxx", luv); err=1; end luv = 'hzz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'hzz", luv); err=1; end luv = 'h9x; if (luv !== 16'b0000_0000_1001_xxxx) begin $display("FAILED -- luv = 'b%b != 'h9x", luv); err=1; end luv = 'h9z; if (luv !== 16'b0000_0000_1001_zzzz) begin $display("FAILED -- luv = 'b%b != 'h9z", luv); err=1; end luv = 'hx9; if (luv !== 16'bxxxx_xxxx_xxxx_1001) begin $display("FAILED -- luv = 'b%b != 'hx9", luv); err=1; end luv = 'hz9; if (luv !== 16'bzzzz_zzzz_zzzz_1001) begin $display("FAILED -- luv = 'b%b != 'hz9", luv); err=1; end // unsized binary literals single character luv = 'd0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'd0", luv); err=1; end luv = 'd9; if (luv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- luv = 'b%b != 'd9", luv); err=1; end luv = 'dx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'dx", luv); err=1; end luv = 'dz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'dz", luv); err=1; end // unsized binary literals two characters luv = 'd00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 'd00", luv); err=1; end luv = 'd99; if (luv !== 16'b0000_0000_0110_0011) begin $display("FAILED -- luv = 'b%b != 'd99", luv); err=1; end // luv = 'dxx; if (luv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 'dxx", luv); err=1; end // luv = 'dzz; if (luv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 'dzz", luv); err=1; end // unsized binary literals single character luv = 15'b0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'b0", luv); err=1; end luv = 15'b1; if (luv !== 16'b0000_0000_0000_0001) begin $display("FAILED -- luv = 'b%b != 15'b1", luv); err=1; end luv = 15'bx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'bx", luv); err=1; end luv = 15'bz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'bz", luv); err=1; end // unsized binary literals two characters luv = 15'b00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'b00", luv); err=1; end luv = 15'b11; if (luv !== 16'b0000_0000_0000_0011) begin $display("FAILED -- luv = 'b%b != 15'b11", luv); err=1; end luv = 15'bxx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'bxx", luv); err=1; end luv = 15'bzz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'bzz", luv); err=1; end luv = 15'b1x; if (luv !== 16'b0000_0000_0000_001x) begin $display("FAILED -- luv = 'b%b != 15'b1x", luv); err=1; end luv = 15'b1z; if (luv !== 16'b0000_0000_0000_001z) begin $display("FAILED -- luv = 'b%b != 15'b1z", luv); err=1; end luv = 15'bx1; if (luv !== 16'b0xxx_xxxx_xxxx_xxx1) begin $display("FAILED -- luv = 'b%b != 15'bx1", luv); err=1; end luv = 15'bz1; if (luv !== 16'b0zzz_zzzz_zzzz_zzz1) begin $display("FAILED -- luv = 'b%b != 15'bz1", luv); err=1; end // unsized binary literals single character luv = 15'o0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'o0", luv); err=1; end luv = 15'o5; if (luv !== 16'b0000_0000_0000_0101) begin $display("FAILED -- luv = 'b%b != 15'o5", luv); err=1; end luv = 15'ox; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'ox", luv); err=1; end luv = 15'oz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'oz", luv); err=1; end // unsized binary literals two characters luv = 15'o00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'o00", luv); err=1; end luv = 15'o55; if (luv !== 16'b0000_0000_0010_1101) begin $display("FAILED -- luv = 'b%b != 15'o55", luv); err=1; end luv = 15'oxx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'oxx", luv); err=1; end luv = 15'ozz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'ozz", luv); err=1; end luv = 15'o5x; if (luv !== 16'b0000_0000_0010_1xxx) begin $display("FAILED -- luv = 'b%b != 15'o5x", luv); err=1; end luv = 15'o5z; if (luv !== 16'b0000_0000_0010_1zzz) begin $display("FAILED -- luv = 'b%b != 15'o5z", luv); err=1; end luv = 15'ox5; if (luv !== 16'b0xxx_xxxx_xxxx_x101) begin $display("FAILED -- luv = 'b%b != 15'ox5", luv); err=1; end luv = 15'oz5; if (luv !== 16'b0zzz_zzzz_zzzz_z101) begin $display("FAILED -- luv = 'b%b != 15'oz5", luv); err=1; end // unsized binary literals single character luv = 15'h0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'h0", luv); err=1; end luv = 15'h9; if (luv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- luv = 'b%b != 15'h9", luv); err=1; end luv = 15'hx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'hx", luv); err=1; end luv = 15'hz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'hz", luv); err=1; end // unsized binary literals two characters luv = 15'h00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'h00", luv); err=1; end luv = 15'h99; if (luv !== 16'b0000_0000_1001_1001) begin $display("FAILED -- luv = 'b%b != 15'h99", luv); err=1; end luv = 15'hxx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'hxx", luv); err=1; end luv = 15'hzz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'hzz", luv); err=1; end luv = 15'h9x; if (luv !== 16'b0000_0000_1001_xxxx) begin $display("FAILED -- luv = 'b%b != 15'h9x", luv); err=1; end luv = 15'h9z; if (luv !== 16'b0000_0000_1001_zzzz) begin $display("FAILED -- luv = 'b%b != 15'h9z", luv); err=1; end luv = 15'hx9; if (luv !== 16'b0xxx_xxxx_xxxx_1001) begin $display("FAILED -- luv = 'b%b != 15'hx9", luv); err=1; end luv = 15'hz9; if (luv !== 16'b0zzz_zzzz_zzzz_1001) begin $display("FAILED -- luv = 'b%b != 15'hz9", luv); err=1; end // unsized binary literals single character luv = 15'd0; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'd0", luv); err=1; end luv = 15'd9; if (luv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- luv = 'b%b != 15'd9", luv); err=1; end luv = 15'dx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'dx", luv); err=1; end luv = 15'dz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'dz", luv); err=1; end // unsized binary literals two characters luv = 15'd00; if (luv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- luv = 'b%b != 15'd00", luv); err=1; end luv = 15'd99; if (luv !== 16'b0000_0000_0110_0011) begin $display("FAILED -- luv = 'b%b != 15'd99", luv); err=1; end // luv = 15'dxx; if (luv !== 16'b0xxx_xxxx_xxxx_xxxx) begin $display("FAILED -- luv = 'b%b != 15'dxx", luv); err=1; end // luv = 15'dzz; if (luv !== 16'b0zzz_zzzz_zzzz_zzzz) begin $display("FAILED -- luv = 'b%b != 15'dzz", luv); err=1; end // unsized binary literals single character lsv = 'sb0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sb0", lsv); err=1; end lsv = 'sb1; if (lsv !== 16'b0000_0000_0000_0001) begin $display("FAILED -- lsv = 'b%b != 'sb1", lsv); err=1; end lsv = 'sbx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sbx", lsv); err=1; end lsv = 'sbz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sbz", lsv); err=1; end // unsized binary literals two characters lsv = 'sb00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sb00", lsv); err=1; end lsv = 'sb11; if (lsv !== 16'b0000_0000_0000_0011) begin $display("FAILED -- lsv = 'b%b != 'sb11", lsv); err=1; end lsv = 'sbxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sbxx", lsv); err=1; end lsv = 'sbzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sbzz", lsv); err=1; end lsv = 'sb1x; if (lsv !== 16'b0000_0000_0000_001x) begin $display("FAILED -- lsv = 'b%b != 'sb1x", lsv); err=1; end lsv = 'sb1z; if (lsv !== 16'b0000_0000_0000_001z) begin $display("FAILED -- lsv = 'b%b != 'sb1z", lsv); err=1; end lsv = 'sbx1; if (lsv !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- lsv = 'b%b != 'sbx1", lsv); err=1; end lsv = 'sbz1; if (lsv !== 16'bzzzz_zzzz_zzzz_zzz1) begin $display("FAILED -- lsv = 'b%b != 'sbz1", lsv); err=1; end // unsized binary literals single character lsv = 'so0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'so0", lsv); err=1; end lsv = 'so5; if (lsv !== 16'b0000_0000_0000_0101) begin $display("FAILED -- lsv = 'b%b != 'so5", lsv); err=1; end lsv = 'sox; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sox", lsv); err=1; end lsv = 'soz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'soz", lsv); err=1; end // unsized binary literals two characters lsv = 'so00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'so00", lsv); err=1; end lsv = 'so55; if (lsv !== 16'b0000_0000_0010_1101) begin $display("FAILED -- lsv = 'b%b != 'so55", lsv); err=1; end lsv = 'soxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'soxx", lsv); err=1; end lsv = 'sozz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sozz", lsv); err=1; end lsv = 'so5x; if (lsv !== 16'b0000_0000_0010_1xxx) begin $display("FAILED -- lsv = 'b%b != 'so5x", lsv); err=1; end lsv = 'so5z; if (lsv !== 16'b0000_0000_0010_1zzz) begin $display("FAILED -- lsv = 'b%b != 'so5z", lsv); err=1; end lsv = 'sox5; if (lsv !== 16'bxxxx_xxxx_xxxx_x101) begin $display("FAILED -- lsv = 'b%b != 'sox5", lsv); err=1; end lsv = 'soz5; if (lsv !== 16'bzzzz_zzzz_zzzz_z101) begin $display("FAILED -- lsv = 'b%b != 'soz5", lsv); err=1; end // unsized binary literals single character lsv = 'sh0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sh0", lsv); err=1; end lsv = 'sh9; if (lsv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- lsv = 'b%b != 'sh9", lsv); err=1; end lsv = 'shx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'shx", lsv); err=1; end lsv = 'shz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'shz", lsv); err=1; end // unsized binary literals two characters lsv = 'sh00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sh00", lsv); err=1; end lsv = 'sh99; if (lsv !== 16'b0000_0000_1001_1001) begin $display("FAILED -- lsv = 'b%b != 'sh99", lsv); err=1; end lsv = 'shxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'shxx", lsv); err=1; end lsv = 'shzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'shzz", lsv); err=1; end lsv = 'sh9x; if (lsv !== 16'b0000_0000_1001_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sh9x", lsv); err=1; end lsv = 'sh9z; if (lsv !== 16'b0000_0000_1001_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sh9z", lsv); err=1; end lsv = 'shx9; if (lsv !== 16'bxxxx_xxxx_xxxx_1001) begin $display("FAILED -- lsv = 'b%b != 'shx9", lsv); err=1; end lsv = 'shz9; if (lsv !== 16'bzzzz_zzzz_zzzz_1001) begin $display("FAILED -- lsv = 'b%b != 'shz9", lsv); err=1; end // unsized binary literals single character lsv = 'sd0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sd0", lsv); err=1; end lsv = 'sd9; if (lsv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- lsv = 'b%b != 'sd9", lsv); err=1; end lsv = 'sdx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sdx", lsv); err=1; end lsv = 'sdz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sdz", lsv); err=1; end // unsized binary literals two characters lsv = 'sd00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 'sd00", lsv); err=1; end lsv = 'sd99; if (lsv !== 16'b0000_0000_0110_0011) begin $display("FAILED -- lsv = 'b%b != 'sd99", lsv); err=1; end // lsv = 'sdxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 'sdxx", lsv); err=1; end // lsv = 'sdzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 'sdzz", lsv); err=1; end // unsized binary literals single character lsv = 15'sb0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sb0", lsv); err=1; end lsv = 15'sb1; if (lsv !== 16'b0000_0000_0000_0001) begin $display("FAILED -- lsv = 'b%b != 15'sb1", lsv); err=1; end lsv = 15'sbx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sbx", lsv); err=1; end lsv = 15'sbz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sbz", lsv); err=1; end // unsized binary literals two characters lsv = 15'sb00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sb00", lsv); err=1; end lsv = 15'sb11; if (lsv !== 16'b0000_0000_0000_0011) begin $display("FAILED -- lsv = 'b%b != 15'sb11", lsv); err=1; end lsv = 15'sbxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sbxx", lsv); err=1; end lsv = 15'sbzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sbzz", lsv); err=1; end lsv = 15'sb1x; if (lsv !== 16'b0000_0000_0000_001x) begin $display("FAILED -- lsv = 'b%b != 15'sb1x", lsv); err=1; end lsv = 15'sb1z; if (lsv !== 16'b0000_0000_0000_001z) begin $display("FAILED -- lsv = 'b%b != 15'sb1z", lsv); err=1; end lsv = 15'sbx1; if (lsv !== 16'bxxxx_xxxx_xxxx_xxx1) begin $display("FAILED -- lsv = 'b%b != 15'sbx1", lsv); err=1; end lsv = 15'sbz1; if (lsv !== 16'bzzzz_zzzz_zzzz_zzz1) begin $display("FAILED -- lsv = 'b%b != 15'sbz1", lsv); err=1; end // unsized binary literals single character lsv = 15'so0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'so0", lsv); err=1; end lsv = 15'so5; if (lsv !== 16'b0000_0000_0000_0101) begin $display("FAILED -- lsv = 'b%b != 15'so5", lsv); err=1; end lsv = 15'sox; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sox", lsv); err=1; end lsv = 15'soz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'soz", lsv); err=1; end // unsized binary literals two characters lsv = 15'so00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'so00", lsv); err=1; end lsv = 15'so55; if (lsv !== 16'b0000_0000_0010_1101) begin $display("FAILED -- lsv = 'b%b != 15'so55", lsv); err=1; end lsv = 15'soxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'soxx", lsv); err=1; end lsv = 15'sozz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sozz", lsv); err=1; end lsv = 15'so5x; if (lsv !== 16'b0000_0000_0010_1xxx) begin $display("FAILED -- lsv = 'b%b != 15'so5x", lsv); err=1; end lsv = 15'so5z; if (lsv !== 16'b0000_0000_0010_1zzz) begin $display("FAILED -- lsv = 'b%b != 15'so5z", lsv); err=1; end lsv = 15'sox5; if (lsv !== 16'bxxxx_xxxx_xxxx_x101) begin $display("FAILED -- lsv = 'b%b != 15'sox5", lsv); err=1; end lsv = 15'soz5; if (lsv !== 16'bzzzz_zzzz_zzzz_z101) begin $display("FAILED -- lsv = 'b%b != 15'soz5", lsv); err=1; end // unsized binary literals single character lsv = 15'sh0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sh0", lsv); err=1; end lsv = 15'sh9; if (lsv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- lsv = 'b%b != 15'sh9", lsv); err=1; end lsv = 15'shx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'shx", lsv); err=1; end lsv = 15'shz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'shz", lsv); err=1; end // unsized binary literals two characters lsv = 15'sh00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sh00", lsv); err=1; end lsv = 15'sh99; if (lsv !== 16'b0000_0000_1001_1001) begin $display("FAILED -- lsv = 'b%b != 15'sh99", lsv); err=1; end lsv = 15'shxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'shxx", lsv); err=1; end lsv = 15'shzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'shzz", lsv); err=1; end lsv = 15'sh9x; if (lsv !== 16'b0000_0000_1001_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sh9x", lsv); err=1; end lsv = 15'sh9z; if (lsv !== 16'b0000_0000_1001_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sh9z", lsv); err=1; end lsv = 15'shx9; if (lsv !== 16'bxxxx_xxxx_xxxx_1001) begin $display("FAILED -- lsv = 'b%b != 15'shx9", lsv); err=1; end lsv = 15'shz9; if (lsv !== 16'bzzzz_zzzz_zzzz_1001) begin $display("FAILED -- lsv = 'b%b != 15'shz9", lsv); err=1; end // unsized binary literals single character lsv = 15'sd0; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sd0", lsv); err=1; end lsv = 15'sd9; if (lsv !== 16'b0000_0000_0000_1001) begin $display("FAILED -- lsv = 'b%b != 15'sd9", lsv); err=1; end lsv = 15'sdx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sdx", lsv); err=1; end lsv = 15'sdz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sdz", lsv); err=1; end // unsized binary literals two characters lsv = 15'sd00; if (lsv !== 16'b0000_0000_0000_0000) begin $display("FAILED -- lsv = 'b%b != 15'sd00", lsv); err=1; end lsv = 15'sd99; if (lsv !== 16'b0000_0000_0110_0011) begin $display("FAILED -- lsv = 'b%b != 15'sd99", lsv); err=1; end // lsv = 15'sdxx; if (lsv !== 16'bxxxx_xxxx_xxxx_xxxx) begin $display("FAILED -- lsv = 'b%b != 15'sdxx", lsv); err=1; end // lsv = 15'sdzz; if (lsv !== 16'bzzzz_zzzz_zzzz_zzzz) begin $display("FAILED -- lsv = 'b%b != 15'sdzz", lsv); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_macro.v000066400000000000000000000012331435245347300205410ustar00rootroot00000000000000 `define FOO(val=42, text="42") do_foo(val, text) module main; int ref_val; string ref_text; task do_foo(int val, string text); if (val!=ref_val || text!=ref_text) begin $display("FAILED -- val=%d (expect %d), text=%0s, (expect %0s)", val, ref_val, text, ref_text); $finish; end endtask // do_foo initial begin ref_val = 42; ref_text = "42"; `FOO(,); ref_val = 42; ref_text = "41"; `FOO(,"41"); ref_val = 41; ref_text = "42"; `FOO(41,); ref_val = 41; ref_text = "41"; `FOO(41,"41"); $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_macro2.v000066400000000000000000000001701435245347300206220ustar00rootroot00000000000000`define msg(x,y) `"x: `\`"y`\`"`" module test(); initial begin $display(`msg(left side,right side)); end endmodule iverilog-12_0/ivtest/ivltests/sv_macro3a.v000066400000000000000000000005021435245347300207630ustar00rootroot00000000000000`define PREFIX my_prefix `define SUFFIX my_suffix `define BACKTICK "`" `define name1 `PREFIX``_```SUFFIX `define name2(p,s) p``_``s `define stringify(text) `"text`" module test(); initial begin $display(`BACKTICK); $display(`stringify(`name1)); $display(`stringify(`name2(`PREFIX, `SUFFIX))); end endmodule iverilog-12_0/ivtest/ivltests/sv_macro3b.v000066400000000000000000000005041435245347300207660ustar00rootroot00000000000000`define PREFIX_ my_prefix_ `define SUFFIX my_suffix `define BACKTICK "`" `define name1 `PREFIX``_```SUFFIX `define name2(p,s) p``_``s `define stringify(text) `"text`" module test(); initial begin $display(`BACKTICK); $display(`stringify(`name1)); $display(`stringify(`name2(`PREFIX, `SUFFIX))); end endmodule iverilog-12_0/ivtest/ivltests/sv_new_array_error.v000066400000000000000000000000671435245347300226440ustar00rootroot00000000000000module test(); logic [1:0] array = new[4]; endmodule iverilog-12_0/ivtest/ivltests/sv_package.v000066400000000000000000000051541435245347300210410ustar00rootroot00000000000000// This tests SystemVerilog packages // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. package p1; localparam int p1_prmt = 100+10+1; typedef bit [10+1-1:0] p1_type; function int p1_func (int x); p1_func = x+10+1; endfunction endpackage package p2; localparam int p1_prmt = 100+20+1; typedef bit [20+1-1:0] p1_type; function int p1_func (int x); p1_func = x+20+1; endfunction localparam int p2_prmt = 100+20+2; typedef bit [20+2-1:0] p2_type; function int p2_func (int x); p2_func = x+20+2; endfunction endpackage package p3; localparam int p1_prmt = 100+30+1; typedef bit [30+1-1:0] p1_type; function int p1_func (int x); p1_func = x+30+1; endfunction localparam int p2_prmt = 100+30+2; typedef bit [30+2-1:0] p2_type; function int p2_func (int x); p2_func = x+30+2; endfunction localparam int p3_prmt = 100+30+3; typedef bit [30+3-1:0] p3_type; function int p3_func (int x); p3_func = x+30+3; endfunction endpackage module test (); // import all from p1 import p1::*; // import only p2_* from p2 import p2::p2_prmt; import p2::p2_type; import p2::p2_func; // import nothing from p3 // declare a set of variables p1_type p1_var; p2_type p2_var; p3::p3_type p3_var; // error counter bit err = 0; initial begin // test parameters if ( p1_prmt !== 100+10+1) begin $display("FAILED -- p1_prmt = %d != 100+10+1", p1_prmt); err=1; end if ( p2_prmt !== 100+20+2) begin $display("FAILED -- p2_prmt = %d != 100+20+2", p2_prmt); err=1; end if (p3::p3_prmt !== 100+30+3) begin $display("FAILED -- p3::p3_prmt = %d != 100+30+3", p3::p3_prmt); err=1; end // test variable bit sizes if ($bits(p1_var) !== 10+1) begin $display("FAILED -- lv = %d != 10+1", $bits(p1_var)); err=1; end if ($bits(p2_var) !== 20+2) begin $display("FAILED -- lv = %d != 20+2", $bits(p2_var)); err=1; end if ($bits(p3_var) !== 30+3) begin $display("FAILED -- lv = %d != 30+3", $bits(p3_var)); err=1; end // test functions if ( p1_func(1000) !== 1000+10+1) begin $display("FAILED -- p1_func(1000) = %d != 1000+10+1", p1_func(1000)); err=1; end if ( p2_func(1000) !== 1000+20+2) begin $display("FAILED -- p2_func(1000) = %d != 1000+20+2", p2_func(1000)); err=1; end if (p3::p3_func(1000) !== 1000+30+3) begin $display("FAILED -- p3::p3_func(1000) = %d != 1000+30+3", p3::p3_func(1000)); err=1; end if (!err) $display("PASSED"); end endmodule // test iverilog-12_0/ivtest/ivltests/sv_package2.v000066400000000000000000000017521435245347300211230ustar00rootroot00000000000000 // This tests SystemVerilog packages. Make sure that names that // are the same is different packages can be references properly // in the various packages. package p1; localparam step = 1; function int next_step(int x); next_step = x + step; endfunction // next_step endpackage // p1 package p2; localparam step = 2; function int next_step(int x); next_step = x + step; endfunction // next_step endpackage // p2 program main; int x; initial begin if (p1::step != 1) begin $display("FAILED -- p1::step == %0d", p1::step); $finish; end if (p2::step != 2) begin $display("FAILED -- p2::step == %0d", p1::step); $finish; end x = p1::next_step(0); if (x != 1) begin $display("FAILED -- p1::next_step(0) --> %0d", x); $finish; end x = p2::next_step(0); if (x != 2) begin $display("FAILED -- p2::next_step(0) --> %0d", x); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_package3.v000066400000000000000000000011251435245347300211160ustar00rootroot00000000000000 // This tests SystemVerilog packages. Make sure that typedef // names work. package p1; typedef struct packed { bit [7:0] high; bit [7:0] low; } word_t; endpackage program main; import p1::word_t; word_t word; initial begin if ($bits(word) != 16) begin $display("FAILED -- $bits(word) == %0d", $bits(word)); $finish; end word.low = 'h55; word.high = 'haa; if (word != 'haa55) begin $display("FAILED -- word = %h", word); $finish; end $display("PASSED"); $finish; end // initial begin endprogram // main iverilog-12_0/ivtest/ivltests/sv_package4.v000066400000000000000000000013531435245347300211220ustar00rootroot00000000000000 // This tests SystemVerilog packages. Make sure that typedef // names work. package p1; typedef struct packed { bit [7:0] high; bit [7:0] low; } word_t; word_t word; endpackage module main; import p1::word; initial begin if ($bits(word) != 16) begin $display("FAILED -- $bits(p1::word) == %0d", $bits(p1::word)); $finish; end word = 'haa55; if (word != 'haa55) begin $display("FAILED -- p1::word = %h", word); $finish; end word.low = 'h66; word.high = 'hbb; if (word != 'hbb66 || word.low != 8'h66) begin $display("FAILED -- p1::word = %h", word); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_package5.v000066400000000000000000000007311435245347300211220ustar00rootroot00000000000000 // This tests SystemVerilog packages. Make sure that typedef // names work. package p1; localparam step = 5; task foo(output int y, input int x); y = x + step; endtask // foo endpackage module main; import p1::foo; int y, x; initial begin x = 5; foo(y, x); if (y != 10) begin $display("FAILED -- x=%0d, y=%0d", x, y); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_package_implicit_var1.v000066400000000000000000000002551435245347300236610ustar00rootroot00000000000000// Check that it is not possible to declare a variable in a package without an explicit data // type for the variable. pacakge P; x; // This is a syntax error endpackage iverilog-12_0/ivtest/ivltests/sv_package_implicit_var2.v000066400000000000000000000002631435245347300236610ustar00rootroot00000000000000// Check that it is not possible to declare a variable in a package without an explicit data // type for the variable. pacakge P; [3:0] x; // This is a syntax error endpackage iverilog-12_0/ivtest/ivltests/sv_packed_port1.v000066400000000000000000000012131435245347300220120ustar00rootroot00000000000000 module main; typedef struct packed { logic [3:0] adr; logic [3:0] val; } foo_s; foo_s [1:0][3:0] ival; foo_s [1:0][3:0] oval; genvar g; for (g = 0 ; g < 4 ; g = g+1) begin:loop TEST dut(.in(ival[0][g]), .out(oval[0][g])); end initial begin ival = 'hx3x2x1x0; #1 $display("ival = %h, oval = %h", ival, oval); if (oval !== 64'hzzzzzzzzxcxdxexf) begin $display("FAILED -- oval=%h", oval); $finish; end $display("PASSED"); $finish; end endmodule // main module TEST (input wire [7:0] in, output wire [7:0] out); assign out = ~in; endmodule // TEST iverilog-12_0/ivtest/ivltests/sv_packed_port2.v000066400000000000000000000012131435245347300220130ustar00rootroot00000000000000 module main; typedef struct packed { logic [3:0] adr; logic [3:0] val; } foo_s; foo_s [3:0][1:0] ival; foo_s [3:0][1:0] oval; genvar g; for (g = 0 ; g < 4 ; g = g+1) begin:loop TEST dut(.in(ival[g][0]), .out(oval[g][0])); end initial begin ival = 'hx3x2x1x0; #1 $display("ival = %h, oval = %h", ival, oval); if (oval !== 64'hzzxxzzxxzzxdzzxf) begin $display("FAILED -- oval=%h", oval); $finish; end $display("PASSED"); $finish; end endmodule // main module TEST (input wire [7:0] in, output wire [7:0] out); assign out = ~in; endmodule // TEST iverilog-12_0/ivtest/ivltests/sv_param_port_list.v000066400000000000000000000010531435245347300226370ustar00rootroot00000000000000module mod #( parameter A = 1, localparam B = A + 1, parameter C = B - 1 ) ( input [A-1:0] a, input [B-1:0] b, input [C-1:0] c ); endmodule module top(); reg [3:0] a = 'ha; reg [4:0] b = 'hb; reg [5:0] c = 'hc; mod #(4, 6) m(a, b, c); initial begin $display("%0d %0d %0d", m.A, m.B, m.C); $display("%0d %0d %0d", $bits(m.a), $bits(m.b), $bits(m.c)); if (m.A === 4 && $bits(m.a) === 4 && m.B === 5 && $bits(m.b) === 5 && m.C === 6 && $bits(m.c) === 6) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_parameter_type.v000066400000000000000000000036731435245347300224730ustar00rootroot00000000000000// SystemVerilog parameter type test module // // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2012 by Iztok Jeras. module test (); // logic vector logic [15:0] lv; // error counter bit err = 0; // system clock (does not have any real function in the test) logic clk = 1; always #5 clk = ~clk; // counters int cnt; int cnt_bit ; int cnt_byte; int cnt_int ; int cnt_ar1d; int cnt_ar2d; // sizes int siz_bit ; int siz_byte; int siz_int ; int siz_ar1d; int siz_ar2d; // add all counters assign cnt = cnt_bit + cnt_byte + cnt_int + cnt_ar1d + cnt_ar2d; // finish report initial begin // some unnecessary delay wait (cnt); // check if variable sizes are correct if (siz_bit != 1) begin $display("FAILED -- siz_bit = %0d", siz_bit ); err=1; end if (siz_byte != 8) begin $display("FAILED -- siz_byte = %0d", siz_byte); err=1; end if (siz_int != 32) begin $display("FAILED -- siz_int = %0d", siz_int ); err=1; end if (siz_ar1d != 24) begin $display("FAILED -- siz_ar1d = %0d", siz_ar1d); err=1; end if (siz_ar2d != 16) begin $display("FAILED -- siz_ar2d = %0d", siz_ar2d); err=1; end if (!err) $display("PASSED"); $finish(); end // instances with various types mod_typ #(.TYP (bit )) mod_bit (clk, cnt_bit [ 1-1:0], siz_bit ); mod_typ #(.TYP (byte )) mod_byte (clk, cnt_byte[ 8-1:0], siz_byte); mod_typ #(.TYP (int )) mod_int (clk, cnt_int [32-1:0], siz_int ); mod_typ #(.TYP (bit [23:0] )) mod_ar1d (clk, cnt_ar1d[24-1:0], siz_ar1d); mod_typ #(.TYP (bit [3:0][3:0])) mod_ar2d (clk, cnt_ar2d[16-1:0], siz_ar2d); endmodule // test module mod_typ #( parameter type TYP = byte )( input logic clk, output TYP cnt = 0, output int siz ); always @ (posedge clk) cnt <= cnt + 1; assign siz = $bits (cnt); endmodule iverilog-12_0/ivtest/ivltests/sv_pkg_class.v000066400000000000000000000007561435245347300214170ustar00rootroot00000000000000package p_defs; class a_class; int id_; function new(int id); id_ = id; endfunction task display(); $display("This is class %0d.", id_); endtask endclass endpackage // This should print the following: // This is class 2. // This is class 1. module top; import p_defs::a_class; a_class ac1; a_class ac2; initial begin ac1 = new(1); ac2 = new(2); ac2.display(); ac1.display(); end endmodule iverilog-12_0/ivtest/ivltests/sv_port_default1.v000066400000000000000000000016201435245347300222110ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; string text_val; function new (int int_init, string text_init = "default text"); int_val = int_init; text_val = text_init; endfunction : new endclass : foo_t foo_t obj1; initial begin obj1 = new (5, "new text"); if (obj1.int_val != 5 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end obj1 = new (7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default10.v000066400000000000000000000013631435245347300222750ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; function int increment(int val, int step = 1, int flag = 1); increment = val + step*flag; endfunction // increment initial begin if (increment(5) !== 6) begin $display("FAILED -- increment(5) --> %0d", increment(5)); $finish; end if (increment(5,2) !== 7) begin $display("FAILED -- increment(5,2) --> %0d", increment(5,2)); $finish; end if (increment(5,,3) !== 8) begin $display("FAILED -- increment(5,,3) --> %0d", increment(5,,3)); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default11.v000066400000000000000000000014341435245347300222750ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; task increment(output int res, input int val, input int step = 1, input int flag = 1); res = val + step*flag; endtask // increment int res; initial begin increment(res,5); if (res !== 6) begin $display("FAILED -- increment(5) --> %0d", res); $finish; end increment(res,5,2); if (res !== 7) begin $display("FAILED -- increment(5,2) --> %0d", res); $finish; end increment(res,5,,3); if (res !== 8) begin $display("FAILED -- increment(5,,3) --> %0d", res); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default12.v000066400000000000000000000011561435245347300222770ustar00rootroot00000000000000// Test non-constant port default value. module test(); integer a; integer b; function integer k(integer i, integer j = a+b); k = i + j; endfunction wire [31:0] x = k(1); wire [31:0] y = k(2); integer result; reg fail = 0; initial begin a = 1; b = 2; #0; result = x; $display(result); if (result !== 4) fail = 1; result = y; $display(result); if (result !== 5) fail = 1; result = k(3); $display(result); if (result !== 6) fail = 1; result = k(3,4); $display(result); if (result !== 7) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_port_default13.v000066400000000000000000000003541435245347300222770ustar00rootroot00000000000000// Check non-constant port default value is rejected // in constant context. module test(); integer a; integer b; function integer k(integer i, integer j = a+b); k = i + j; endfunction localparam integer result = k(3); endmodule iverilog-12_0/ivtest/ivltests/sv_port_default14.v000066400000000000000000000012251435245347300222760ustar00rootroot00000000000000// Test default value for output port // This should work, but isn't supported yet module test(); integer a; integer b; integer c; task k(input integer i = a, output integer j = b); j = i; endtask integer result; reg fail = 0; initial begin a = 1; b = 2; k(3,c); $display(a,,b,,c); if (a !== 1 || b !== 2 || c !== 3) fail = 1; k(,c); $display(a,,b,,c); if (a !== 1 || b !== 2 || c !== 1) fail = 1; k(4,); $display(a,,b,,c); if (a !== 1 || b !== 4 || c !== 1) fail = 1; k(); $display(a,,b,,c); if (a !== 1 || b !== 1 || c !== 1) fail = 1; if (fail) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_port_default2.v000066400000000000000000000016431435245347300222170ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; string text_val; task init (int int_init, string text_init = "default text"); int_val = int_init; text_val = text_init; endtask endclass : foo_t foo_t obj1; initial begin obj1 = new; obj1.init(5, "new text"); if (obj1.int_val != 5 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end obj1 = new; obj1.init(7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default3.v000066400000000000000000000015731435245347300222220ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0]log_val; function new (int int_init, logic[3:0] log_init = 4'bzzzz); int_val = int_init; log_val = log_init; endfunction : new endclass : foo_t foo_t obj1; initial begin obj1 = new (5, 4'b1010); if (obj1.int_val != 5 || obj1.log_val !== 4'b1010) begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%0s", obj1.int_val, obj1.log_val); $finish; end obj1 = new (7); if (obj1.int_val != 7 || obj1.log_val !== 4'bzzzz) begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%0s", obj1.int_val, obj1.log_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default4.v000066400000000000000000000016171435245347300222220ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic [3:0] log_val; task init (int int_init, logic[3:0] log_init = 4'bzzzz); int_val = int_init; log_val = log_init; endtask endclass : foo_t foo_t obj1; initial begin obj1 = new; obj1.init(5, 4'b1111); if (obj1.int_val != 5 || obj1.log_val !== 4'b1111) begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b", obj1.int_val, obj1.log_val); $finish; end obj1 = new; obj1.init(7); if (obj1.int_val != 7 || obj1.log_val !== 4'bzzzz) begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%0s", obj1.int_val, obj1.log_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default5.v000066400000000000000000000031001435245347300222100ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0] log_val; string text_val; function new (int int_init, logic[3:0]log_init = 4'bzzzz, string text_init = "default text"); int_val = int_init; log_val = log_init; text_val = text_init; endfunction : new endclass : foo_t foo_t obj1; initial begin obj1 = new (4, 4'b0101, "new text"); if (obj1.int_val != 4 || obj1.log_val !== 4'b0101 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new (5, , "new text"); if (obj1.int_val != 5 || obj1.log_val !== 4'bzzzz || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new (6, 4'b1010); if (obj1.int_val != 6 || obj1.log_val !== 4'b1010 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new (7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default6.v000066400000000000000000000031721435245347300222220ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0] log_val; string text_val; task init (int int_init, logic[3:0]log_init = 4'bzzzz, string text_init = "default text"); int_val = int_init; log_val = log_init; text_val = text_init; endtask : init endclass : foo_t foo_t obj1; initial begin obj1 = new; obj1.init(4, 4'b0101, "new text"); if (obj1.int_val != 4 || obj1.log_val !== 4'b0101 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(5, , "new text"); if (obj1.int_val != 5 || obj1.log_val !== 4'bzzzz || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(6, 4'b1010); if (obj1.int_val != 6 || obj1.log_val !== 4'b1010 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default7.v000066400000000000000000000034051435245347300222220ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0] log_val; string text_val; task init (int int_init, logic[3:0]log_init = 4'bzzzz, string text_init = "default text"); this.init2(int_init, log_init, text_init); endtask : init task init2 (int int_init, logic[3:0]log_init, string text_init); int_val = int_init; log_val = log_init; text_val = text_init; endtask : init2 endclass : foo_t foo_t obj1; initial begin obj1 = new; obj1.init(4, 4'b0101, "new text"); if (obj1.int_val != 4 || obj1.log_val !== 4'b0101 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(5, , "new text"); if (obj1.int_val != 5 || obj1.log_val !== 4'bzzzz || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(6, 4'b1010); if (obj1.int_val != 6 || obj1.log_val !== 4'b1010 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default8.v000066400000000000000000000034221435245347300222220ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0] log_val; string text_val; task init (int int_init, logic[3:0]log_init = 4'bzzzz, string text_init = "default text"); this.init2(int_init, log_init, text_init); endtask : init function void init2 (int int_init, logic[3:0]log_init, string text_init); int_val = int_init; log_val = log_init; text_val = text_init; endfunction : init2 endclass : foo_t foo_t obj1; initial begin obj1 = new; obj1.init(4, 4'b0101, "new text"); if (obj1.int_val != 4 || obj1.log_val !== 4'b0101 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(5, , "new text"); if (obj1.int_val != 5 || obj1.log_val !== 4'bzzzz || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(6, 4'b1010); if (obj1.int_val != 6 || obj1.log_val !== 4'b1010 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new; obj1.init(7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_port_default9.v000066400000000000000000000033241435245347300222240ustar00rootroot00000000000000 // This tests the basic support for default arguments to task/function // ports. The default port syntax gives SystemVerilog a limited form // of variable argument lists. program main; class foo_t; int int_val; logic[3:0] log_val; string text_val; function new (int int_init, logic[3:0]log_init = 4'bzzzz, string text_init = "default text"); this.init2(int_init, log_init, text_init); endfunction : new function void init2 (int int_init, logic[3:0]log_init, string text_init); int_val = int_init; log_val = log_init; text_val = text_init; endfunction : init2 endclass : foo_t foo_t obj1; initial begin obj1 = new(4, 4'b0101, "new text"); if (obj1.int_val != 4 || obj1.log_val !== 4'b0101 || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new(5, , "new text"); if (obj1.int_val != 5 || obj1.log_val !== 4'bzzzz || obj1.text_val != "new text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new(6, 4'b1010); if (obj1.int_val != 6 || obj1.log_val !== 4'b1010 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.log_val=%b obj1.text_val=%0s", obj1.int_val, obj1.log_val, obj1.text_val); $finish; end obj1 = new(7); if (obj1.int_val != 7 || obj1.text_val != "default text") begin $display("FAILED -- obj1.int_val=%0d, obj1.text_val=%0s", obj1.int_val, obj1.text_val); $finish; end $display("PASSED"); end endprogram // main iverilog-12_0/ivtest/ivltests/sv_ps_function1.v000066400000000000000000000005621435245347300220540ustar00rootroot00000000000000// Check that it is possible to call a package scoped function. package P; function integer T(integer x, integer y); return x + y; endfunction endpackage module test; initial begin integer x; x = P::T(1, 2); if (x === 3) begin $display("PASSED"); end else begin $display("FAILED. x = %d, expected 3", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_function2.v000066400000000000000000000005531435245347300220550ustar00rootroot00000000000000// Check that it is possible to call a package scoped function with no // arguments. package P; function integer T(); return 1; endfunction endpackage module test; initial begin integer x; x = P::T(); if (x === 1) begin $display("PASSED"); end else begin $display("FAILED: x = %d, expected 1", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_function3.v000066400000000000000000000006341435245347300220560ustar00rootroot00000000000000// Check that it is possible to call a package scoped function with empty // positional arguments. package P; function integer T(integer x = 1, integer y = 2); return x + y; endfunction endpackage module test; initial begin integer x; x = P::T(, 4); if (x === 5) begin $display("PASSED"); end else begin $display("FAILED. x = %d, expected 5", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_function4.v000066400000000000000000000011141435245347300220510ustar00rootroot00000000000000// Check that it is possible to reference a package scoped function, even if // there is a type identifier of the same name in the current scope. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; function integer T(integer x); return x + 1; endfunction endpackage module test; typedef integer T; initial begin integer x; x = P::T(10); `check(x, 11) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type1.v000066400000000000000000000010161435245347300212030ustar00rootroot00000000000000// Check that it is possible to reference a package scoped type identifier, even if // there is a identifier of the same name in the current scope. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; typedef logic [31:0] T; endpackage module test; logic T; initial begin P::T x; `check($bits(x), 32) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_cast1.v000066400000000000000000000007661435245347300222300ustar00rootroot00000000000000// Check that it is possible to reference a package scoped type identifier as // the type in a type cast expression. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; typedef integer T; endpackage module test; integer x; initial begin x = P::T'(-1024.123); `check(x, -1024) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_cast2.v000066400000000000000000000011171435245347300222200ustar00rootroot00000000000000// Check that it is possible to reference a package scoped type identifier as // the type in a type cast expression, even if there is a identifier of the same // name in the local scope. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; typedef integer T; endpackage module test; localparam T = 2; integer x; initial begin x = P::T'(-1024.123); `check(x, -1024) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_class1.v000066400000000000000000000011101435245347300223630ustar00rootroot00000000000000// Check that class types declared in a package can be referenced using a scoped // type identifier. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; localparam A = 8; class C; logic [A-1:0] x; task t; `check($bits(x), 8) if (!failed) begin $display("PASSED"); end endtask endclass endpackage module test; localparam A = 4; P::C c; initial begin c = new; c.t(); end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_class_prop.v000066400000000000000000000006331435245347300233530ustar00rootroot00000000000000// Check that it is possible to use a package scope type identifier for the type // of a property of class defined in the root scope package P; typedef integer T; endpackage class C; P::T x; endclass module test; C c; initial begin c = new; c.x = 32'h55aa55aa; if (c.x === 32'h55aa55aa) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_enum1.v000066400000000000000000000011251435245347300222300ustar00rootroot00000000000000// Check that enum types declared in a package can be referenced using a scoped // type identifier. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; localparam X = 8; typedef enum logic [X-1:0] { A, B = X } T; endpackage module test; localparam X = 4; typedef int T; P::T x = P::B; initial begin `check(x, P::B) `check(x, 8) `check($bits(x), 8); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_expr1.v000066400000000000000000000007151435245347300222460ustar00rootroot00000000000000// Check that it is possible to reference a package scoped type identifier in an // expression. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; typedef integer T; endpackage module test; initial begin `check($bits(P::T), $bits(integer)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_expr2.v000066400000000000000000000010531435245347300222430ustar00rootroot00000000000000// Check that it is possible to reference a package scoped type identifier in an // expression, even if there is a non type identifier of the same name in the // current scope. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; typedef integer T; endpackage module test; integer T; initial begin `check($bits(P::T), $bits(integer)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_type_struct1.v000066400000000000000000000011411435245347300226060ustar00rootroot00000000000000// Check that struct types declared in a package can be referenced using a // scoped type identifier. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; localparam A = 8; typedef struct packed { logic [A-1:0] x; } T; endpackage typedef int T; module test; localparam A = 4; typedef int T; P::T x; initial begin x = 8'hff; `check(x, 8'hff) `check($bits(x), 8) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_ps_var1.v000066400000000000000000000010301435245347300210060ustar00rootroot00000000000000// Check that it is possible to reference a package scoped identifier, even if // there is a type identifier of the same name in the current scope. bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end package P; integer T = 10; endpackage module test; typedef integer T; integer x; initial begin x = P::T; `check(x, 10) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue1.v000066400000000000000000000040101435245347300206410ustar00rootroot00000000000000 module main; string words [$], tmp_word; int nums [$], tmp_num; initial begin words.push_back("Hello"); words.push_back("World"); if (words.size != 2) begin $display("FAILED -- words.size=%0d", words.size); $finish; end if (words[0] != "Hello") begin $display("FAILED -- words[0] = %s", words[0]); $finish; end if (words[$] != "World") begin $display("FAILED -- words[$] = %s", words[$]); $finish; end tmp_word = words.pop_front(); if (tmp_word != "Hello") begin $display("FAILED -- words.pop_front()=%s", tmp_word); $finish; end if (words[0] != words[$]) begin $display("FAILED -- words[0](=%s) !== words[$](=%s)", words[0], words[$]); $finish; end nums.push_back(2); nums.push_back(3); nums.push_front(1); if (nums.size != 3) begin $display("FAILED -- nums.size=%0d", nums.size); $finish; end if (nums[0] !== 1) begin $display("FAILED -- nums[0] = %0d", nums[0]); $finish; end if (nums[$] !== 3) begin $display("FAILED -- nums[$] = %0d", nums[$]); $finish; end tmp_num = nums.pop_back(); if (tmp_num !== 3) begin $display("FAILED -- tmp_num=%0d (from back)", tmp_num); $finish; end if (nums.size !== 2) begin $display("FAILED -- nums.size after pop_back = %0d", nums.size); $finish; end if (nums[0] !== 1) begin $display("FAILED -- nums[0] = %0d", nums[0]); $finish; end if (nums[1] !== 2) begin $display("FAILED -- nums[1] = %0d", nums[1]); $finish; end tmp_num = nums.pop_front(); if (tmp_num !== 1) begin $display("FAILED == tmp_num=%0d (fron front)", tmp_num); $finish; end if (nums.size !== 1) begin $display("FAILED -- nums.size after pop_front = %0d", nums.size); $finish; end if (nums[0] !== 2) begin $display("FAILED -- nums[0] = %0d after pop_front", nums[0]); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_queue2.v000066400000000000000000000015221435245347300206470ustar00rootroot00000000000000 module main; string words [$]; int nums [$]; initial begin words.push_back("Hello"); words.push_back("World"); nums.push_back(1); nums.push_back(2); nums.push_front(0); foreach (words[widx]) begin case (widx) 0: if (words[widx] != "Hello") begin $display("FAILED -- words[%0d] == %s", widx, words[widx]); $finish; end 1: if (words[widx] != "World") begin $display("FAILED -- words[%0d] == %s", widx, words[widx]); $finish; end default: begin $display("FAILED -- widx = %0d", widx); $finish; end endcase end foreach (nums[nidx]) begin if (nidx !== nums[nidx]) begin $display("FAILED -- nums[%0d] == %0d", nidx, nums[nidx]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_queue3.v000066400000000000000000000024661435245347300206600ustar00rootroot00000000000000/* * Copyright (c) 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. */ `default_nettype none module main; string words [$]; int nums[$]; initial begin words.push_back("Hello, World!"); nums.push_back(42); words = {}; if (words.size != 0) begin $display("FAILED -- words.size=%0d after clear", words.size); $finish; end nums = {}; if (nums.size != 0) begin $display("FAILED -- nums.size=%0d after clear", nums.size); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_queue_assign1.v000066400000000000000000000010711435245347300222110ustar00rootroot00000000000000// Check that queues with compatible packed base types can be assigned to each // other. Even if the element types are not identical. module test; typedef bit [31:0] T1; typedef bit [31:0] T2[$]; // For two packed types to be compatible they need to have the same packed // width, both be 2-state or 4-state and both be either signed or unsigned. bit [32:1] q1[$]; bit [7:0][3:0] q2[$]; int unsigned q3[$]; T1 q4[$]; T2 q5; initial begin q2 = q1; q3 = q2; q4 = q3; q5 = q4; q1 = q5; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign2.v000066400000000000000000000014221435245347300222120ustar00rootroot00000000000000// Check that queues with compatible packed base types can be passed as task // arguments. Even it the element types are not identical. module test; typedef logic [31:0] T[$]; task t1(logic [31:0] q[$]); q[0] = 1; endtask task t2(logic [7:0][3:0] q[$]); q[0] = 1; endtask task t3([31:0] q[$]); q[0] = 1; endtask task t4(T q); q[0] = 1; endtask // For two packed types to be compatible they need to have the same packed // width, both be 2-state or 4-state and both be either signed or unsigned. logic [31:0] q1[$]; logic [7:0][3:0] q2[$]; initial begin q1.push_back(1); q2.push_back(2); t1(q1); t1(q2); t2(q1); t2(q2); t3(q1); t3(q2); t4(q1); t4(q2); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail1.v000066400000000000000000000004361435245347300232100ustar00rootroot00000000000000// Check that it is not possible to assign a queue with a 2-state element type // to a queue with 4-state element type. Even if they are otherwise identical. module test; logic [31:0] q1[$]; bit [31:0] q2[$]; initial begin q1 = q2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail2.v000066400000000000000000000004511435245347300232060ustar00rootroot00000000000000// Check that it is not possible to assign a queue with a signed element type to // a queue with a unsigned element type. Even if they are otherwise identical. module test; logic [31:0] q1[$]; logic signed [31:0] q2[$]; initial begin q1 = q2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail3.v000066400000000000000000000003341435245347300232070ustar00rootroot00000000000000// Check that it is not possible to assign a queue to another queue with a // different element width. module test; int q1[$]; shortint q2[$]; initial begin q1 = q2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail4.v000066400000000000000000000005001435245347300232030ustar00rootroot00000000000000// Check that it is not possible to assign a queue with an enum element type to // a queue with a packed type. Even if the enum base type is the same as the // packed type. module test; enum logic [31:0] { A } q1[$]; logic [31:0] q2[$]; initial begin q1 = q2; $dispaly("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail5.v000066400000000000000000000003451435245347300232130ustar00rootroot00000000000000// Check that it is not possible to assign a queue with a real element type to a // queue with an int element type. module test; int q1[$]; real q2[$]; initial begin q1 = q2; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_assign_fail6.v000066400000000000000000000003451435245347300232140ustar00rootroot00000000000000// Check that it is not possible to assign a queue with an int element type to a // queue with a real element type. module test; real q1[$]; int q2[$]; initial begin q1 = q2; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_copy_empty1.v000066400000000000000000000004571435245347300231240ustar00rootroot00000000000000// Check that it is possible to copy an empty queue. module test; typedef int T[$]; initial begin T q1; T q2; q1 = '{1, 2, 3}; q1 = q2; if (q1.size() == 0 && q2.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_copy_empty2.v000066400000000000000000000004571435245347300231250ustar00rootroot00000000000000// Check that it is possible to copy an empty dynamic array to a queue. module test; initial begin int q[$]; int d[]; q = '{1, 2, 3}; q = d; if (q.size() == 0 && d.size() == 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_function1.v000066400000000000000000000017201435245347300225530ustar00rootroot00000000000000// Check that a queue return type is supported for functions module test; typedef int Q[$]; // Since this is not an automatic function calling this repeatetly will // append to the same queue. function Q f1(int x); f1.push_back(1 + x); f1.push_back(2 + x); endfunction // Since this function is automatic a new queue will be created each time it // is called. function automatic Q f2(int x); f2.push_back(1 + x); f2.push_back(2 + x); endfunction initial begin Q a, b, c, d; a = f1(0); // `a` should be a copy and not affected by the second call b = f1(2); c = f2(0); d = f2(2); if (a.size() == 2 && a[0] == 1 && a[1] == 2 && b.size() == 4 && b[0] == 1 && b[1] == 2 && b[2] == 3 && b[3] == 4 && c.size() == 2 && c[0] == 1 && c[1] == 2 && d.size() == 2 && d[0] == 3 && d[1] == 4) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_function2.v000066400000000000000000000006351435245347300225600ustar00rootroot00000000000000// Check that bounded queues are supported as function return types. module test; typedef int Q[$:1]; function automatic Q f(); // The last element should be discarded return '{1, 2, 3}; endfunction initial begin int q[$]; q = f(); if (q.size() == 2 && q[0] == 1 && q[1] == 2) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_method_signed1.v000066400000000000000000000043331435245347300235420ustar00rootroot00000000000000// Check that the signedness of the element type of a queue is correctly handled // whenn calling one of the pop methods with parenthesis. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end int unsigned x = 10; int y = 10; int z; longint w; shortint qs[$]; bit [15:0] qu[$]; initial begin for (int i = 0; i < 16; i++) begin qu.push_back(-1); qs.push_back(-1); end // These all evaluate as signed `check($signed(qu.pop_back()) < 0) `check(qs.pop_back() < 0) `check($signed(qu.pop_front()) < 0) `check(qs.pop_front() < 0) // These all evaluate as unsigned `check(qu.pop_back() > 0) `check({qs.pop_back()} > 0) `check($unsigned(qs.pop_back()) > 0) `check(qs.pop_back() > 16'h0) `check(qu.pop_front() > 0) `check({qs.pop_front()} > 0) `check($unsigned(qs.pop_front()) > 0) `check(qs.pop_front() > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = qu.pop_back() + x; `check(z === 65545) z = qu.pop_back() + y; `check(z === 65545) z = qu.pop_front() + x; `check(z === 65545) z = qu.pop_front() + y; `check(z === 65545) z = qs.pop_back() + x; `check(z === 65545) z = qs.pop_back() + y; `check(z === 9) z = qs.pop_front() + x; `check(z === 65545) z = qs.pop_front() + y; `check(z === 9) // For ternary operators if one operand is unsigned the result is unsigend z = x ? qu.pop_back() : x; `check(z === 65535) z = x ? qu.pop_back() : y; `check(z === 65535) z = x ? qu.pop_front() : x; `check(z === 65535) z = x ? qu.pop_front() : y; `check(z === 65535) z = x ? qs.pop_back() : x; `check(z === 65535) z = x ? qs.pop_back() : y; `check(z === -1) z = x ? qs.pop_front() : x; `check(z === 65535) z = x ? qs.pop_front() : y; `check(z === -1) // Size return value is always positive, but check that it gets padded // properly w = x ? qu.size() : 64'h123; `check(w === 64'h4) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_method_signed2.v000066400000000000000000000013501435245347300235370ustar00rootroot00000000000000// Check that the signedness of the element type of a queue is correctly handled // when passing the result of one of the pop methods as an argument to a system // function. module test; shortint qs[$]; bit [15:0] qu[$]; string s; initial begin qs.push_back(-1); qs.push_back(-2); qu.push_back(-1); qu.push_back(-2); // Values popped from qs should be treated as signed, values popped from qu // should be treated as unsigned s = $sformatf("%0d %0d %0d %0d", qs.pop_front(), qs.pop_back(), qu.pop_front(), qu.pop_back()); if (s == "-1 -2 65535 65534") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_method_signed3.v000066400000000000000000000042411435245347300235420ustar00rootroot00000000000000// Check that the signedness of the element type of a queue is correctly handled // whenn calling one of the pop methods with parenthesis. module test; bit failed = 1'b0; `define check(x) \ if (!(x)) begin \ $display("FAILED(%0d): ", `__LINE__, `"x`"); \ failed = 1'b1; \ end int unsigned x = 10; int y = 10; int z; longint w; shortint qs[$]; bit [15:0] qu[$]; initial begin for (int i = 0; i < 16; i++) begin qu.push_back(-1); qs.push_back(-1); end // These all evaluate as signed `check($signed(qu.pop_back) < 0) `check(qs.pop_back < 0) `check($signed(qu.pop_front) < 0) `check(qs.pop_front < 0) // These all evaluate as unsigned `check(qu.pop_back > 0) `check({qs.pop_back} > 0) `check($unsigned(qs.pop_back) > 0) `check(qs.pop_back > 16'h0) `check(qu.pop_front > 0) `check({qs.pop_front} > 0) `check($unsigned(qs.pop_front) > 0) `check(qs.pop_front > 16'h0) // In arithmetic expressions if one operand is unsigned all operands are // considered unsigned z = qu.pop_back + x; `check(z === 65545) z = qu.pop_back + y; `check(z === 65545) z = qu.pop_front + x; `check(z === 65545) z = qu.pop_front + y; `check(z === 65545) z = qs.pop_back + x; `check(z === 65545) z = qs.pop_back + y; `check(z === 9) z = qs.pop_front + x; `check(z === 65545) z = qs.pop_front + y; `check(z === 9) // For ternary operators if one operand is unsigned the result is unsigend z = x ? qu.pop_back : x; `check(z === 65535) z = x ? qu.pop_back : y; `check(z === 65535) z = x ? qu.pop_front : x; `check(z === 65535) z = x ? qu.pop_front : y; `check(z === 65535) z = x ? qs.pop_back : x; `check(z === 65535) z = x ? qs.pop_back : y; `check(z === -1) z = x ? qs.pop_front : x; `check(z === 65535) z = x ? qs.pop_front : y; `check(z === -1) // Size return value is always positive, but check that it gets padded // properly w = x ? qu.size : 64'h123; `check(w === 64'h4) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_method_signed4.v000066400000000000000000000013401435245347300235400ustar00rootroot00000000000000// Check that the signedness of the element type of a queue is correctly handled // when passing the result of one of the pop methods as an argument to a system // function. module test; shortint qs[$]; bit [15:0] qu[$]; string s; initial begin qs.push_back(-1); qs.push_back(-2); qu.push_back(-1); qu.push_back(-2); // Values popped from qs should be treated as signed, values popped from qu // should be treated as unsigned s = $sformatf("%0d %0d %0d %0d", qs.pop_front, qs.pop_back, qu.pop_front, qu.pop_back); if (s == "-1 -2 65535 65534") begin $display("PASSED"); end else begin $display("FAILED s=%s", s); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_nest1.v000066400000000000000000000001751435245347300217020ustar00rootroot00000000000000// Check that declarations for queues of queues are supported. module test; // Queue of queues int q[$][$]; endmodule iverilog-12_0/ivtest/ivltests/sv_queue_nest2.v000066400000000000000000000002141435245347300216750ustar00rootroot00000000000000// Check that declarations for queues of dynamic arrays are supported. module test; // Queue of dynamic arrays int q[][$]; endmodule iverilog-12_0/ivtest/ivltests/sv_queue_nest3.v000066400000000000000000000002201435245347300216730ustar00rootroot00000000000000// Check that declarations for queues of unpacked arrays are supported. module test; // Queue of unpacked arrays int q[10][$]; endmodule iverilog-12_0/ivtest/ivltests/sv_queue_nest4.v000066400000000000000000000002201435245347300216740ustar00rootroot00000000000000// Check that declarations for unpacked arrays of queues are supported. module test; // Unpacked array of queues int q[$][10]; endmodule iverilog-12_0/ivtest/ivltests/sv_queue_oob_real.v000066400000000000000000000004671435245347300224360ustar00rootroot00000000000000// Check that out-of-bounds access on a real typed queue works and returns the // correct value. module test; real q[$]; real x; initial begin x = q[1]; if (x == 0.0) begin $display("PASSED"); end else begin $display("FAILED. Expected 0.0, got %f", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_oob_string.v000066400000000000000000000004731435245347300230160ustar00rootroot00000000000000// Check that out-of-bounds access on a string typed queue works and returns the // right value. module test; string q[$]; string x; initial begin x = q[1]; if (x == "") begin $display("PASSED"); end else begin $display("FAILED. Expected '', got '%s'", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_oob_vec2.v000066400000000000000000000005161435245347300223450ustar00rootroot00000000000000// Check that out-of-bounds access on a 2-state vector queue works and returns // the correct value. module test; bit [7:0] q[$]; logic [7:0] x; initial begin x = q[1]; if (x === 8'h00) begin $display("PASSED"); end else begin $display("FAILED. Expected 00000000, got %b",x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_oob_vec4.v000066400000000000000000000005211435245347300223430ustar00rootroot00000000000000// Check that out-of-bounds access on a 4-state vector queue works and returns // the correct value. module test; logic [7:0] q[$]; logic [7:0] x; initial begin x = q[1]; if (x === 8'hxx) begin $display("PASSED"); end else begin $display("FAILED. Expected xxxxxxxx, got %b", x); end end endmodule iverilog-12_0/ivtest/ivltests/sv_queue_parray.v000066400000000000000000000126551435245347300221540ustar00rootroot00000000000000module top; typedef reg [4:0] T1; typedef T1 [7:0] T2; T2 q_tst [$]; T2 q_tmp [$]; T2 elem; integer idx; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, T2 expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; q_tst.delete(0); // Warning: skip delete on an empty queue check_size(0, `__FILE__, `__LINE__); check_idx_value(0, 0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); // Warning: cannot pop_front() an empty queue if (elem !== 'X) begin $display("Failed: pop_front() != 'X (%0d)", elem); passed = 1'b0; end elem = q_tst.pop_back(); // Warning: cannot pop_back() an empty queue if (elem !== 'X) begin $display("Failed: pop_back() != 'X (%0d)", elem); passed = 1'b0; end q_tst.push_back(2); q_tst.push_front(1); q_tst.push_back(3); q_tst.push_back(100); q_tst.delete(3); // Should $ work here? q_tst.delete(3); // Warning: skip an out of range delete() q_tst.delete(-1); // Warning: skip delete with negative index q_tst.delete('X); // Warning: skip delete with undefined index check_size(3, `__FILE__, `__LINE__); if (q_tst[0] !== 1) begin $display("Failed: element [0] != 1 (%0d)", q_tst[0]); passed = 1'b0; end if (q_tst[1] !== 2) begin $display("Failed: element [1] != 2 (%0d)", q_tst[1]); passed = 1'b0; end if (q_tst[2] !== 3) begin $display("Failed: element [2] != 3 (%0d)", q_tst[2]); passed = 1'b0; end if (q_tst[3] !== 'X) begin $display("Failed: element [3] != 'X (%0d)", q_tst[3]); passed = 1'b0; end if (q_tst[-1] !== 'X) begin $display("Failed: element [-1] != 'X (%0d)", q_tst[-1]); passed = 1'b0; end if (q_tst['X] !== 'X) begin $display("Failed: element ['X] != 'X (%0d)", q_tst['X]); passed = 1'b0; end check_idx_value(-1, 0.0, `__FILE__, `__LINE__); check_idx_value('X, 0.0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); if (elem !== 1) begin $display("Failed: element pop_front() != 1 (%0d)", elem); passed = 1'b0; end elem = q_tst.pop_back(); if (elem !== 3) begin $display("Failed: element pop_back() != 3 (%0d)", elem); passed = 1'b0; end check_size(1, `__FILE__, `__LINE__); if ((q_tst[0] !== q_tst[$]) || (q_tst[0] !== 2)) begin $display("Failed: q_tst[0](%0d) != q_tst[$](%0d) != 2", q_tst[0], q_tst[$]); passed = 1'b0; end q_tst.delete(); check_size(0, `__FILE__, `__LINE__); q_tst.push_front(5); q_tst.push_front(100); q_tst.push_back(100); elem = q_tst.pop_back; elem = q_tst.pop_front; check_size(1, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); q_tst[0] = 1; q_tst[1] = 3; q_tst[1] = 2; q_tst[2] = 3; q_tst[-1] = 10; // Warning: will not be added (negative index) q_tst['X] = 10; // Warning: will not be added (undefined index) q_tst[4] = 10; // Warning: will not be added (out of range index) idx = -1; q_tst[idx] = 10; // Warning: will not be added (negative index) idx = 3'b0x1; q_tst[idx] = 10; // Warning: will not be added (undefined index) idx = 4; q_tst[idx] = 10; // Warning: will not be added (out of range index) check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst.delete(); q_tst[0] = 2; q_tst.insert(1, 4); q_tst.insert(0, 1); q_tst.insert(2, 3); q_tst.insert(-1, 10); // Warning: will not be added (negative index) q_tst.insert('X, 10); // Warning: will not be added (undefined index) q_tst.insert(5, 10); // Warning: will not be added (out of range index) check_size(4, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); check_idx_value(3, 4, `__FILE__, `__LINE__); q_tst = '{3, 2, 1}; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 3, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 1, `__FILE__, `__LINE__); q_tmp = '{1, 2}; q_tst = q_tmp; q_tmp[0] = 3; q_tmp[2] = 1; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); q_tst[2] = 3; check_size(3, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst = {1, 2}; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); q_tst = '{}; check_size(0, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_parray_bounded.v000066400000000000000000000045171435245347300236520ustar00rootroot00000000000000module top; typedef reg [4:0] T1; typedef T1 [7:0] T2; T2 q_tst [$:2]; T2 q_tmp [$]; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, T2 expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; check_size(0, `__FILE__, `__LINE__); q_tst.push_back(2); q_tst.push_front(1); q_tst.push_back(3); q_tst.push_back(100); // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst.push_front(5); // Warning: back item removed. q_tst[3] = 3; // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); check_idx_value(1, 1, `__FILE__, `__LINE__); check_idx_value(2, 2, `__FILE__, `__LINE__); q_tst.insert(3, 10); // Warning: item not added. q_tst.insert(1, 2); // Warning: back item removed. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 1, `__FILE__, `__LINE__); q_tst = '{1, 2, 3, 4}; // Warning: items not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tmp = '{4, 3, 2, 1}; q_tst = q_tmp; // Warning not all items copied q_tmp[0] = 5; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 4, `__FILE__, `__LINE__); check_idx_value(1, 3, `__FILE__, `__LINE__); check_idx_value(2, 2, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_parray_fail.v000066400000000000000000000005621435245347300231410ustar00rootroot00000000000000module top; typedef reg [4:0] T1; typedef T1 [7:0] T2; int bound = 2; T2 q_vec [$]; T2 q_vec1 [$:-1]; T2 q_vec2 [$:'X]; T2 q_vec3 [$:bound]; initial begin $display(q_vec.size(1)); $display(q_vec.pop_front(1)); $display(q_vec.pop_back(1)); q_vec.push_front(1, 2); q_vec.push_back(1, 2); $display("FAILED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_real.v000066400000000000000000000130131435245347300215660ustar00rootroot00000000000000module top; real q_tst [$]; real q_tmp [$]; real elem; integer idx; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, real expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %.1f (%.1f)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; q_tst.delete(0); // Warning: skip delete on an empty queue check_size(0, `__FILE__, `__LINE__); check_idx_value(0, 0.0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); // Warning: cannot pop_front() an empty queue if (elem != 0.0) begin $display("Failed: pop_front() != 0.0 (%.1f)", elem); passed = 1'b0; end elem = q_tst.pop_back(); // Warning: cannot pop_back() an empty queue if (elem != 0.0) begin $display("Failed: pop_back() != 0.0 (%.1f)", elem); passed = 1'b0; end q_tst.push_back(2.0); q_tst.push_front(1.0); q_tst.push_back(3.0); q_tst.push_back(100.0); q_tst.delete(3); // Should $ work here? q_tst.delete(3); // Warning: skip an out of range delete() q_tst.delete(-1); // Warning: skip delete with negative index q_tst.delete('X); // Warning: skip delete with undefined index check_size(3, `__FILE__, `__LINE__); if (q_tst[0] != 1.0) begin $display("Failed: element [0] != 1.0 (%.1f)", q_tst[0]); passed = 1'b0; end if (q_tst[1] != 2.0) begin $display("Failed: element [1] != 2.0 (%.1f)", q_tst[1]); passed = 1'b0; end if (q_tst[2] != 3.0) begin $display("Failed: element [2] != 3.0 (%.1f)", q_tst[2]); passed = 1'b0; end if (q_tst[3] != 0.0) begin $display("Failed: element [3] != 0.0 (%.1f)", q_tst[3]); passed = 1'b0; end if (q_tst[-1] != 0.0) begin $display("Failed: element [-1] != 0.0 (%.1f)", q_tst[-1]); passed = 1'b0; end if (q_tst['X] != 0.0) begin $display("Failed: element ['X] != 0.0 (%.1f)", q_tst['X]); passed = 1'b0; end check_idx_value(-1, 0.0, `__FILE__, `__LINE__); check_idx_value('X, 0.0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); if (elem != 1.0) begin $display("Failed: element pop_front() != 1.0 (%.1f)", elem); passed = 1'b0; end elem = q_tst.pop_back(); if (elem != 3.0) begin $display("Failed: element pop_back() != 3.0 (%.1f)", elem); passed = 1'b0; end check_size(1, `__FILE__, `__LINE__); if ((q_tst[0] != q_tst[$]) || (q_tst[0] != 2.0)) begin $display("Failed: q_tst[0](%.1f) != q_tst[$](%.1f) != 2.0", q_tst[0], q_tst[$]); passed = 1'b0; end q_tst.delete(); check_size(0, `__FILE__, `__LINE__); q_tst.push_front(5.0); q_tst.push_front(100.0); q_tst.push_back(100.0); elem = q_tst.pop_back; elem = q_tst.pop_front; check_size(1, `__FILE__, `__LINE__); check_idx_value(0, 5.0, `__FILE__, `__LINE__); q_tst[0] = 1.0; q_tst[1] = 2.5; q_tst[1] = 2.0; q_tst[2] = 3.0; q_tst[-1] = 10.0; // Warning: will not be added (negative index) q_tst['X] = 10.0; // Warning: will not be added (undefined index) q_tst[4] = 10.0; // Warning: will not be added (out of range index) idx = -1; q_tst[idx] = 10.0; // Warning: will not be added (negative index) idx = 3'b0x1; q_tst[idx] = 10.0; // Warning: will not be added (undefined index) idx = 4; q_tst[idx] = 10.0; // Warning: will not be added (out of range index) check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 3.0, `__FILE__, `__LINE__); q_tst.delete(); q_tst[0] = 2.0; q_tst.insert(1, 4.0); q_tst.insert(0, 1.0); q_tst.insert(2, 3.0); q_tst.insert(-1, 10.0); // Warning: will not be added (negative index) q_tst.insert('X, 10.0); // Warning: will not be added (undefined index) q_tst.insert(5, 10.0); // Warning: will not be added (out of range index) check_size(4, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 3.0, `__FILE__, `__LINE__); check_idx_value(3, 4.0, `__FILE__, `__LINE__); q_tst = '{3.0, 2.0, 1.0}; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 3.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 1.0, `__FILE__, `__LINE__); q_tmp = '{1.0, 2.0}; q_tst = q_tmp; q_tmp[0] = 3.0; q_tmp[2] = 1.0; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); q_tst[2] = 3.0; check_size(3, `__FILE__, `__LINE__); check_idx_value(2, 3.0, `__FILE__, `__LINE__); q_tst = {1.0, 2.0}; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); q_tst = '{}; check_size(0, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_real_bounded.v000066400000000000000000000045471435245347300233020ustar00rootroot00000000000000module top; real q_tst [$:2]; real q_tmp [$]; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, real expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %.1f (%.1f)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; check_size(0, `__FILE__, `__LINE__); q_tst.push_back(2.0); q_tst.push_front(1.0); q_tst.push_back(3.0); q_tst.push_back(100.0); // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 3.0, `__FILE__, `__LINE__); q_tst.push_front(0.5); // Warning: back item removed. q_tst[3] = 3.0; // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 0.5, `__FILE__, `__LINE__); check_idx_value(1, 1.0, `__FILE__, `__LINE__); check_idx_value(2, 2.0, `__FILE__, `__LINE__); q_tst.insert(3, 10.0); // Warning: item not added. q_tst.insert(1, 2.0); // Warning: back item removed. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 0.5, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 1.0, `__FILE__, `__LINE__); q_tst = '{1.0, 2.0, 3.0, 4.0}; // Warning: items not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); check_idx_value(2, 3.0, `__FILE__, `__LINE__); q_tmp = '{4.0, 3.0, 2.0, 1.0}; q_tst = q_tmp; // Warning not all items copied q_tmp[0] = 5.0; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 4.0, `__FILE__, `__LINE__); check_idx_value(1, 3.0, `__FILE__, `__LINE__); check_idx_value(2, 2.0, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_real_fail.v000066400000000000000000000005411435245347300225630ustar00rootroot00000000000000module top; int bound = 2; real q_real [$]; real q_real1 [$:-1]; real q_real2 [$:'X]; real q_real3 [$:bound]; initial begin $display(q_real.size(1.0)); $display(q_real.pop_front(1.0)); $display(q_real.pop_back(1.0)); q_real.push_front(1.0, 2.0); q_real.push_back(1.0, 2.0); $display("FAILED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_string.v000066400000000000000000000135301435245347300221550ustar00rootroot00000000000000module top; string q_tst [$]; string q_tmp [$]; string elem; integer idx; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue initial size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, string expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != '%s' ('%s')", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; q_tst.delete(0); // Warning: skip delete on an empty queue check_size(0, `__FILE__, `__LINE__); check_idx_value(0, "", `__FILE__, `__LINE__); elem = q_tst.pop_front(); // Warning: cannot pop_front() an empty queue if (elem != "") begin $display("Failed: pop_front() != '' ('%s')", elem); passed = 1'b0; end elem = q_tst.pop_back(); // Warning: cannot pop_back() an empty queue if (elem != "") begin $display("Failed: pop_back() != '' ('%s')", elem); passed = 1'b0; end q_tst.push_back("World"); q_tst.push_front("Hello"); q_tst.push_back("!"); q_tst.push_back("This should get deleted"); q_tst.delete(3); q_tst.delete(3); // Warning: skip an out of range delete() q_tst.delete(-1); // Warning: skip delete with negative index q_tst.delete('X); // Warning: skip delete with undefined index check_size(3, `__FILE__, `__LINE__); if (q_tst[0] != "Hello") begin $display("Failed: element [0] != 'Hello' ('%s')", q_tst[0]); passed = 1'b0; end if (q_tst[1] != "World") begin $display("Failed: element [1] != 'World' ('%s')", q_tst[1]); passed = 1'b0; end if (q_tst[2] != "!") begin $display("Failed: element [2] != '!' ('%s')", q_tst[2]); passed = 1'b0; end if (q_tst[3] != "") begin $display("Failed: element [3] != '' ('%s')", q_tst[3]); passed = 1'b0; end if (q_tst[-1] != "") begin $display("Failed: element [-1] != '' ('%s')", q_tst[-1]); passed = 1'b0; end if (q_tst['X] != "") begin $display("Failed: element ['X] != '' ('%s')", q_tst['X]); passed = 1'b0; end check_idx_value(-1, "", `__FILE__, `__LINE__); check_idx_value('X, "", `__FILE__, `__LINE__); elem = q_tst.pop_front(); if (elem != "Hello") begin $display("Failed: element pop_front() != 'Hello' ('%s')", elem); passed = 1'b0; end elem = q_tst.pop_back(); if (elem != "!") begin $display("Failed: element pop_back() != '!' ('%s')", elem); passed = 1'b0; end check_size(1, `__FILE__, `__LINE__); if ((q_tst[0] != q_tst[$]) || (q_tst[0] != "World")) begin $display("Failed: q_tst[0]('%s') != q_tst[$]('%s') != 'World'", q_tst[0], q_tst[$]); passed = 1'b0; end q_tst.delete(); check_size(0, `__FILE__, `__LINE__); q_tst.push_front("hello"); q_tst.push_front("Will be removed"); q_tst.push_back("Will also be removed"); elem = q_tst.pop_back; elem = q_tst.pop_front; check_size(1, `__FILE__, `__LINE__); check_idx_value(0, "hello", `__FILE__, `__LINE__); q_tst[0] = "Hello"; q_tst[1] = "world"; q_tst[1] = "World"; q_tst[2] = "!"; q_tst[-1] = "Will not write"; // Warning: will not be added (negative index) q_tst['X] = "Will not write"; // Warning: will not be added (undefined index) q_tst[4] = "Will not write"; // Warning: will not be added (out of range index) idx = -1; q_tst[idx] = "Will not write"; // Warning: will not be added (negative index) idx = 3'b0x1; q_tst[idx] = "Will not write"; // Warning: will not be added (undefined index) idx = 4; q_tst[idx] = "Will not write"; // Warning: will not be added (out of range index) check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); check_idx_value(2, "!", `__FILE__, `__LINE__); q_tst.delete(); q_tst[0] = "World"; q_tst.insert(1, "Again"); q_tst.insert(0, "Hello"); q_tst.insert(2, "!"); q_tst.insert(-1, "Will not be added"); // Warning: will not be added (negative index) q_tst.insert('X, "Will not be added"); // Warning: will not be added (undefined index) q_tst.insert(5, "Will not be added"); // Warning: will not be added (out of range index) check_size(4, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); check_idx_value(2, "!", `__FILE__, `__LINE__); check_idx_value(3, "Again", `__FILE__, `__LINE__); q_tst = '{"!", "World", "Hello"}; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "!", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); check_idx_value(2, "Hello", `__FILE__, `__LINE__); q_tmp = '{"Hello", "World"}; q_tst = q_tmp; q_tmp[0] = "Goodbye"; q_tmp[2] = "Not seen"; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); q_tst[2] = "Added, but removed"; check_size(3, `__FILE__, `__LINE__); check_idx_value(2, "Added, but removed", `__FILE__, `__LINE__); q_tst = {"Hello", "World"}; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); q_tst = '{}; check_size(0, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_string_bounded.v000066400000000000000000000050611435245347300236550ustar00rootroot00000000000000module top; string q_tst [$:2]; string q_tmp [$]; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size() !== size) begin $display("%s:%0d: Failed: queue initial size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, string expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != '%s' ('%s')", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; check_size(0, `__FILE__, `__LINE__); q_tst.push_back("World"); q_tst.push_front("Hello"); q_tst.push_back("!"); q_tst.push_back("This will not be added"); // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); check_idx_value(2, "!", `__FILE__, `__LINE__); q_tst.push_front("I say,"); // Warning: sback item removed. q_tst[3] = "Will not be added"; // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "I say,", `__FILE__, `__LINE__); check_idx_value(1, "Hello", `__FILE__, `__LINE__); check_idx_value(2, "World", `__FILE__, `__LINE__); q_tst.insert(3, "Will not be added"); // Warning: item not added. q_tst.insert(1, "to you"); // Warning: back item removed. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "I say,", `__FILE__, `__LINE__); check_idx_value(1, "to you", `__FILE__, `__LINE__); check_idx_value(2, "Hello", `__FILE__, `__LINE__); q_tst = '{"Hello", "World", "!", "Will not be added"}; // Warning: items not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "Hello", `__FILE__, `__LINE__); check_idx_value(1, "World", `__FILE__, `__LINE__); check_idx_value(2, "!", `__FILE__, `__LINE__); q_tmp = '{"Again,", "Hello", "World", "!"}; q_tst = q_tmp; // Warning not all items copied q_tmp[0] = "Will not change anything"; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, "Again,", `__FILE__, `__LINE__); check_idx_value(1, "Hello", `__FILE__, `__LINE__); check_idx_value(2, "World", `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_string_fail.v000066400000000000000000000005401435245347300231450ustar00rootroot00000000000000module top; int bound = 2; string q_str [$]; string q_str1 [$:-1]; string q_str2 [$:'X]; string q_str3 [$:bound]; initial begin $display(q_str.size("a")); $display(q_str.pop_front("a")); $display(q_str.pop_back("a")); q_str.push_front("a", "b"); q_str.push_back("a", "b"); $display("FAILED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_vec.v000066400000000000000000000126011435245347300214220ustar00rootroot00000000000000module top; int q_tst [$]; int q_tmp [$]; int elem; integer idx; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, int expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; q_tst.delete(0); // Warning: skip delete on an empty queue check_size(0, `__FILE__, `__LINE__); check_idx_value(0, 0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); // Warning: cannot pop_front() an empty queue if (elem !== 'X) begin $display("Failed: pop_front() != 'X (%0d)", elem); passed = 1'b0; end elem = q_tst.pop_back(); // Warning: cannot pop_back() an empty queue if (elem !== 'X) begin $display("Failed: pop_back() != 'X (%0d)", elem); passed = 1'b0; end q_tst.push_back(2); q_tst.push_front(1); q_tst.push_back(3); q_tst.push_back(100); q_tst.delete(3); // Should $ work here? q_tst.delete(3); // Warning: skip an out of range delete() q_tst.delete(-1); // Warning: skip delete with negative index q_tst.delete('X); // Warning: skip delete with undefined index check_size(3, `__FILE__, `__LINE__); if (q_tst[0] !== 1) begin $display("Failed: element [0] != 1 (%0d)", q_tst[0]); passed = 1'b0; end if (q_tst[1] !== 2) begin $display("Failed: element [1] != 2 (%0d)", q_tst[1]); passed = 1'b0; end if (q_tst[2] !== 3) begin $display("Failed: element [2] != 3 (%0d)", q_tst[2]); passed = 1'b0; end if (q_tst[3] !== 'X) begin $display("Failed: element [3] != 'X (%0d)", q_tst[3]); passed = 1'b0; end if (q_tst[-1] !== 'X) begin $display("Failed: element [-1] != 'X (%0d)", q_tst[-1]); passed = 1'b0; end if (q_tst['X] !== 'X) begin $display("Failed: element ['X] != 'X (%0d)", q_tst['X]); passed = 1'b0; end check_idx_value(-1, 0.0, `__FILE__, `__LINE__); check_idx_value('X, 0.0, `__FILE__, `__LINE__); elem = q_tst.pop_front(); if (elem !== 1) begin $display("Failed: element pop_front() != 1 (%0d)", elem); passed = 1'b0; end elem = q_tst.pop_back(); if (elem !== 3) begin $display("Failed: element pop_back() != 3 (%0d)", elem); passed = 1'b0; end check_size(1, `__FILE__, `__LINE__); if ((q_tst[0] !== q_tst[$]) || (q_tst[0] !== 2)) begin $display("Failed: q_tst[0](%0d) != q_tst[$](%0d) != 2", q_tst[0], q_tst[$]); passed = 1'b0; end q_tst.delete(); check_size(0, `__FILE__, `__LINE__); q_tst.push_front(5); q_tst.push_front(100); q_tst.push_back(100); elem = q_tst.pop_back; elem = q_tst.pop_front; check_size(1, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); q_tst[0] = 1; q_tst[1] = 3; q_tst[1] = 2; q_tst[2] = 3; q_tst[-1] = 10; // Warning: will not be added (negative index) q_tst['X] = 10; // Warning: will not be added (undefined index) q_tst[4] = 10; // Warning: will not be added (out of range index) idx = -1; q_tst[idx] = 10; // Warning: will not be added (negative index) idx = 3'b0x1; q_tst[idx] = 10; // Warning: will not be added (undefined index) idx = 4; q_tst[idx] = 10; // Warning: will not be added (out of range index) check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst.delete(); q_tst[0] = 2; q_tst.insert(1, 4); q_tst.insert(0, 1); q_tst.insert(2, 3); q_tst.insert(-1, 10); // Warning: will not be added (negative index) q_tst.insert('X, 10); // Warning: will not be added (undefined index) q_tst.insert(5, 10); // Warning: will not be added (out of range index) check_size(4, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); check_idx_value(3, 4, `__FILE__, `__LINE__); q_tst = '{3, 2, 1}; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 3, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 1, `__FILE__, `__LINE__); q_tmp = '{1, 2}; q_tst = q_tmp; q_tmp[0] = 3; q_tmp[2] = 1; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1.0, `__FILE__, `__LINE__); check_idx_value(1, 2.0, `__FILE__, `__LINE__); q_tst[2] = 3; check_size(3, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst = {1, 2}; check_size(2, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); q_tst = '{}; check_size(0, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_vec_bounded.v000066400000000000000000000044421435245347300231260ustar00rootroot00000000000000module top; int q_tst [$:2]; int q_tmp [$]; bit passed; task automatic check_size(integer size, string fname, integer lineno); if (q_tst.size !== size) begin $display("%s:%0d: Failed: queue size != %0d (%0d)", fname, lineno, size, q_tst.size); passed = 1'b0; end endtask task automatic check_idx_value(integer idx, int expected, string fname, integer lineno); if (q_tst[idx] != expected) begin $display("%s:%0d: Failed: element [%0d] != %0d (%0d)", fname, lineno, idx, expected, q_tst[idx]); passed = 1'b0; end endtask initial begin passed = 1'b1; check_size(0, `__FILE__, `__LINE__); q_tst.push_back(2); q_tst.push_front(1); q_tst.push_back(3); q_tst.push_back(100); // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tst.push_front(5); // Warning: back item removed. q_tst[3] = 3; // Warning: item not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); check_idx_value(1, 1, `__FILE__, `__LINE__); check_idx_value(2, 2, `__FILE__, `__LINE__); q_tst.insert(3, 10); // Warning: item not added. q_tst.insert(1, 2); // Warning: back item removed. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 5, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 1, `__FILE__, `__LINE__); q_tst = '{1, 2, 3, 4}; // Warning: items not added. check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 1, `__FILE__, `__LINE__); check_idx_value(1, 2, `__FILE__, `__LINE__); check_idx_value(2, 3, `__FILE__, `__LINE__); q_tmp = '{4, 3, 2, 1}; q_tst = q_tmp; // Warning not all items copied q_tmp[0] = 5; check_size(3, `__FILE__, `__LINE__); check_idx_value(0, 4, `__FILE__, `__LINE__); check_idx_value(1, 3, `__FILE__, `__LINE__); check_idx_value(2, 2, `__FILE__, `__LINE__); if (passed) $display("PASSED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_queue_vec_fail.v000066400000000000000000000005061435245347300224160ustar00rootroot00000000000000module top; int bound = 2; int q_vec [$]; int q_vec1 [$:-1]; int q_vec2 [$:'X]; int q_vec3 [$:bound]; initial begin $display(q_vec.size(1)); $display(q_vec.pop_front(1)); $display(q_vec.pop_back(1)); q_vec.push_front(1, 2); q_vec.push_back(1, 2); $display("FAILED"); end endmodule : top iverilog-12_0/ivtest/ivltests/sv_root_class.v000066400000000000000000000006331435245347300216130ustar00rootroot00000000000000class a_class; int id_; function new(int id); id_ = id; endfunction task display(); $display("This is class %0d.", id_); endtask endclass // This should print the following: // This is class 2. // This is class 1. module top; a_class ac1; a_class ac2; initial begin ac1 = new(1); ac2 = new(2); ac2.display(); ac1.display(); end endmodule iverilog-12_0/ivtest/ivltests/sv_root_func.v000066400000000000000000000004371435245347300214430ustar00rootroot00000000000000function int a_func (input int id); a_func = id; endfunction // This should print the following: // This is func 2. // This is func 1. module top; initial begin $display("this is func %0d.", a_func(2)); $display("this is func %0d.", a_func(1)); end endmodule iverilog-12_0/ivtest/ivltests/sv_root_task.v000066400000000000000000000003531435245347300214470ustar00rootroot00000000000000task a_task (input int id); $display("This is task %0d.", id); endtask // This should print the following: // This is task 2. // This is task 1. module top; initial begin a_task(2); a_task(1); end endmodule iverilog-12_0/ivtest/ivltests/sv_sign_cast1.v000066400000000000000000000012001435245347300214650ustar00rootroot00000000000000// Check that sign casts have the expected results when the value gets width // extended. module test; bit failed = 1'b0; reg [7:0] val; reg signed [7:0] sval; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \ failed = 1'b1; \ end initial begin // An unsized number has an implicit width of integer width. val = unsigned'(-4); `check(val, 8'hfc); val = unsigned'(-4'sd4); `check(val, 8'h0c); sval = signed'(4'hc); `check(sval, -4); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_sign_cast2.v000066400000000000000000000036151435245347300215020ustar00rootroot00000000000000// Check that unsigned arguments to a sign cast are evaluated as self-determined. module test; reg [3:0] op1; reg [2:0] op2; reg [7:0] result; bit failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \ failed = 1'b1; \ end initial begin // Addition tests op1 = 4'b1111; op2 = 3'b111; result = 8'sd0 + signed'(op1 + op2); `check(result, 8'b00000110); result = 8'sd0 + unsigned'(op1 + op2); `check(result, 8'b00000110); op1 = 4'b1000; op2 = 3'b011; result = 8'sd0 + signed'(op1 + op2); `check(result, 8'b11111011); result = 8'sd0 + unsigned'(op1 + op2); `check(result, 8'b00001011); // Multiply tests op1 = 4'b0101; op2 = 3'b100; result = 8'sd0 + signed'(op1 * op2); `check(result, 8'b00000100); result = 8'sd0 + unsigned'(op1 * op2); `check(result, 8'b00000100); op1 = 4'b0010; op2 = 3'b100; result = 8'sd0 + signed'(op1 * op2); `check(result, 8'b11111000); result = 8'sd0 + unsigned'(op1 * op2); `check(result, 8'b00001000); // Left ASR tests op1 = 4'b1010; result = 8'sd0 + signed'(op1 <<< 1); `check(result, 8'b00000100); result = 8'sd0 + unsigned'(op1 <<< 1); `check(result, 8'b00000100); op1 = 4'b0101; result = 8'sd0 + signed'(op1 <<< 1); `check(result, 8'b11111010); result = 8'sd0 + unsigned'(op1 <<< 1); `check(result, 8'b00001010); // Right ASR tests op1 = 4'b1010; result = 8'sd0 + signed'(op1 >>> 1); `check(result, 8'b00000101); result = 8'sd0 + unsigned'(op1 >>> 1); `check(result, 8'b00000101); op1 = 4'b1010; result = 8'sd0 + signed'(op1 >>> 0); `check(result, 8'b11111010); result = 8'sd0 + unsigned'(op1 >>> 0); `check(result, 8'b00001010); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_sign_cast3.v000066400000000000000000000036321435245347300215020ustar00rootroot00000000000000// Check that signed arguments to a sign cast are evaluated as self-determined. module test; reg signed [3:0] op1; reg signed [2:0] op2; reg [7:0] result; bit failed = 1'b0; `define check(val, exp) \ if (exp !== val) begin \ $display("FAILED(%0d). Got %b, expected %b.", `__LINE__, val, exp); \ failed = 1'b1; \ end initial begin // Addition tests op1 = 4'b1111; op2 = 3'b111; result = 8'sd0 + signed'(op1 + op2); `check(result, 8'b11111110); result = 8'sd0 + unsigned'(op1 + op2); `check(result, 8'b00001110); op1 = 4'b1000; op2 = 3'b011; result = 8'sd0 + signed'(op1 + op2); `check(result, 8'b11111011); result = 8'sd0 + unsigned'(op1 + op2); `check(result, 8'b00001011); // Multiply tests op1 = 4'b0101; op2 = 3'b100; result = 8'sd0 + signed'(op1 * op2); `check(result, 8'b11111100); result = 8'sd0 + unsigned'(op1 * op2); `check(result, 8'b00001100); op1 = 4'b0010; op2 = 3'b100; result = 8'sd0 + signed'(op1 * op2); `check(result, 8'b11111000); result = 8'sd0 + unsigned'(op1 * op2); `check(result, 8'b00001000); // Left ASR tests op1 = 4'b1010; result = 8'sd0 + signed'(op1 <<< 1); `check(result, 8'b00000100); result = 8'sd0 + unsigned'(op1 <<< 1); `check(result, 8'b00000100); op1 = 4'b0101; result = 8'sd0 + signed'(op1 <<< 1); `check(result, 8'b11111010); result = 8'sd0 + unsigned'(op1 <<< 1); `check(result, 8'b00001010); // Right ASR tests op1 = 4'b0101; result = 8'sd0 + signed'(op1 >>> 1); `check(result, 8'b00000010); result = 8'sd0 + unsigned'(op1 >>> 1); `check(result, 8'b00000010); op1 = 4'b1010; result = 8'sd0 + signed'(op1 >>> 1); `check(result, 8'b11111101); result = 8'sd0 + unsigned'(op1 >>> 1); `check(result, 8'b00001101); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_string1.v000066400000000000000000000002621435245347300210300ustar00rootroot00000000000000/* * This is the most basic test of string variables. */ module main; string foo = "PASSED"; initial begin $display(foo); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string2.v000066400000000000000000000031641435245347300210350ustar00rootroot00000000000000/* * This is the most basic test of string variables. */ module main; string foo; string bar; initial begin foo = "foo"; bar = "bar"; if (foo != "foo") begin $display("FAILED -- foo=%0s (1)", foo); $finish; end if (bar != "bar") begin $display("FAILED -- bar=%0s (2)", bar); $finish; end if (foo == bar) begin $display("FAILED -- %0s == %0s (3)", foo, bar); $finish; end if (! (foo != bar)) begin $display("FAILED -- ! (%0s != %0s) (4)", foo, bar); $finish; end if (bar > foo) begin $display("FAILED -- %s > %s (5)", bar, foo); $finish; end if (bar >= foo) begin $display("FAILED -- %s >= %s (6)", bar, foo); $finish; end if (foo < bar) begin $display("FAILED -- %s < %s (7)", foo, bar); $finish; end if (foo <= bar) begin $display("FAILED -- %s <= %s (8)", foo, bar); $finish; end bar = foo; if (foo != bar) begin $display("FAILED -- %0s != %0s (9)", foo, bar); $finish; end if (foo > bar) begin $display("FAILED -- %0s > %0s (10)", foo, bar); $finish; end if (foo < bar) begin $display("FAILED -- %0s < %0s (11)", foo, bar); $finish; end if (! (foo == bar)) begin $display("FAILED -- ! (%0s == %0s) (12)", foo, bar); $finish; end if (! (foo <= bar)) begin $display("FAILED -- ! (%0s <= %0s) (13)", foo, bar); $finish; end if (! (foo >= bar)) begin $display("FAILED -- ! (%0s >= %0s) (14)", foo, bar); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string3.v000066400000000000000000000004141435245347300210310ustar00rootroot00000000000000/* * This demonstrates that strings can be used as * constructed formats in $display et al. */ module main; string foo; string bar; initial begin foo = "%0s"; bar = "PASSED"; $display(foo, bar); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string4.v000066400000000000000000000006101435245347300210300ustar00rootroot00000000000000/* * This demonstrates that strings can be used as * constructed formats in $display et al. */ module main; string foo; string bar; initial begin bar = "PAS"; foo = {bar, "SED"}; if (foo != "PASSED") begin $display("FAILED (1)"); $finish; end foo = "PAS"; bar = "SED"; $display({foo,bar}); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string5.v000066400000000000000000000017301435245347300210350ustar00rootroot00000000000000/* * This demonstrates that strings can be used as * constructed formats in $display et al. */ module main; string foo; initial begin foo = "PAXXED"; $display("foo.len()=%0d (s.b. 6)", foo.len()); if (foo.len() != 6) begin $display("FAILED -- foo.len() = %0d", foo.len()); $finish; end $display("foo[-1]=%b (s.b. 00000000)", foo[-1]); if (foo[-1] != 'h00) begin $display("FAILED -- foo[-1]=%h", foo[-1]); $finish; end $display("foo[7]=%b (s.b. 00000000)", foo[7]); if (foo[7] != 'h00) begin $display("FAILED -- foo[7]=%h", foo[7]); $finish; end $display("foo[4]=%b (s.b. 01000101)", foo[4]); if (foo[4] != 'h45) begin $display("FAILED -- foo[4]=%h", foo[4]); $finish; end foo[2] = 'h00; if (foo != "PAXXED") begin $display("FAILED -- foo=%0s (1)", foo); $finish; end foo[2]='h53; foo[3]='h53; $display(foo); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string6.v000066400000000000000000000020631435245347300210360ustar00rootroot00000000000000// Test the various string.Xtoa() methods module testbench; string str; int val; real valr; task test_string_value(string str, string reference); if (str != reference) begin $display("FAILED -- str=%0s, should be %s", str, reference); $finish; end endtask // test_string_value initial begin val = 11; valr = 11.1; str.itoa(val); test_string_value(str, "11"); str.hextoa(val); test_string_value(str, "b"); str.octtoa(val); test_string_value(str, "13"); str.bintoa(val); test_string_value(str, "1011"); str.realtoa(valr); test_string_value(str, "11.1"); val = -11; valr = -11.1; str.itoa(val); test_string_value(str, "-11"); str.hextoa(val); test_string_value(str, "-b"); str.octtoa(val); test_string_value(str, "-13"); str.bintoa(val); test_string_value(str, "-1011"); str.realtoa(valr); test_string_value(str, "-11.1"); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_string7.v000066400000000000000000000024711435245347300210420ustar00rootroot00000000000000 module main; string foo; int error_count; task check_char(input int idx, input [7:0] val); if (foo[idx] !== val) begin $display("FAILED: foo[%0d]==%02h, expecting %02h", idx, foo[idx], val); error_count = error_count+1; end endtask // check_char initial begin // These are the special charasters in strings as defined by // IEEE Std 1800-2017: 5.9.1 Special characters in strings. // The string assignment is governed by: // IEEE Std 1800-2017: 6.16 String data type foo = "abc\n\t\\\"\v\f\a\001\002\x03\x04"; error_count = 0; check_char(0, 8'h61); // 'a' check_char(1, 8'h62); // 'b' check_char(2, 8'h63); // 'c' check_char(3, 8'h0a); // '\n' check_char(4, 8'h09); // '\t' check_char(5, 8'h5c); // '\\' check_char(6, 8'h22); // '\"' check_char(7, 8'h0b); // '\v' check_char(8, 8'h0c); // '\f' check_char(9, 8'h07); // '\a' check_char(10, 8'h01); // '\001' check_char(11, 8'h02); // '\002' check_char(12, 8'h03); // '\x03' check_char(13, 8'h04); // '\x04' if (foo.len() !== 14) begin $display("FAILED: foo.len() == %0d, should be 14", foo.len()); error_count = error_count+1; end if (error_count == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_string7b.v000066400000000000000000000025201435245347300211770ustar00rootroot00000000000000 module main; string foo; int error_count; task check_char(input int idx, input [7:0] val); if (foo[idx] !== val) begin $display("FAILED: foo[%0d]==%02h, expecting %02h", idx, foo[idx], val); error_count = error_count+1; end endtask // check_char initial begin // These are the special charasters in strings as defined by // IEEE Std 1800-2017: 5.9.1 Special characters in strings. // The string assignment is governed by: // IEEE Std 1800-2017: 6.16 String data type foo = "abc"; foo = {foo, "\n\t\\\"\v\f\a\001\002\x03\x04"}; error_count = 0; check_char(0, 8'h61); // 'a' check_char(1, 8'h62); // 'b' check_char(2, 8'h63); // 'c' check_char(3, 8'h0a); // '\n' check_char(4, 8'h09); // '\t' check_char(5, 8'h5c); // '\\' check_char(6, 8'h22); // '\"' check_char(7, 8'h0b); // '\v' check_char(8, 8'h0c); // '\f' check_char(9, 8'h07); // '\a' check_char(10, 8'h01); // '\001' check_char(11, 8'h02); // '\002' check_char(12, 8'h03); // '\x03' check_char(13, 8'h04); // '\x04' if (foo.len() !== 14) begin $display("FAILED: foo.len() == %0d, should be 14", foo.len()); error_count = error_count+1; end if (error_count == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_timeunit_prec1.v000066400000000000000000000057301435245347300223760ustar00rootroot00000000000000timeunit 10us; timeprecision 10us; module fast_g (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 10us end endmodule // fast_g `timescale 100us / 1us // These will be ignored since a `timescale was already given. timeunit 10us; timeprecision 10us; module slow (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 100us end endmodule // slow module fast (out); timeunit 10us; timeprecision 1us; output out; reg out; initial begin #0 out = 0; #1 out = 1; // 10us end endmodule // fast module saf(out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 100us end endmodule // saf `timescale 1us / 1us module main; reg pass; wire slow, fast, fast_g, saf; slow m1 (slow); fast_g m2 (fast_g); fast m3 (fast); saf m4 (saf); initial begin pass = 1'b1; #9; if (slow !== 1'b0) begin $display("FAILED: slow at 9us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 9us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b0) begin $display("FAILED: fast at 9us, expected 1'b0, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b0) begin $display("FAILED: fast_g at 9us, expected 1'b0, got %b.", fast_g); pass = 1'b0; end #2 // 11us if (slow !== 1'b0) begin $display("FAILED: slow at 11us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 11us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 11us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 11us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end #88 // 99 us if (slow !== 1'b0) begin $display("FAILED: slow at 99us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 99us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 99us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 99us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end #2 // 101 us if (slow !== 1'b1) begin $display("FAILED: slow at 101us, expected 1'b1, got %b.", slow); pass = 1'b0; end if (saf !== 1'b1) begin $display("FAILED: saf at 101us, expected 1'b1, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 101us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 101us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end if (pass) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_timeunit_prec2.v000066400000000000000000000056521435245347300224020ustar00rootroot00000000000000timeunit 10us / 10us; module fast_g (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 10us end endmodule // fast_g `timescale 100us / 1us // These will be ignored since a `timescale was already given. timeunit 10us/10us; module slow (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 100us end endmodule // slow module fast (out); timeunit 10us/1us; output out; reg out; initial begin #0 out = 0; #1 out = 1; // 10us end endmodule // fast module saf(out); output out; reg out; initial begin #0 out = 0; #1 out = 1; // 100us end endmodule // saf `timescale 1us / 1us module main; reg pass; wire slow, fast, fast_g, saf; slow m1 (slow); fast_g m2 (fast_g); fast m3 (fast); saf m4 (saf); initial begin pass = 1'b1; #9; if (slow !== 1'b0) begin $display("FAILED: slow at 9us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 9us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b0) begin $display("FAILED: fast at 9us, expected 1'b0, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b0) begin $display("FAILED: fast_g at 9us, expected 1'b0, got %b.", fast_g); pass = 1'b0; end #2 // 11us if (slow !== 1'b0) begin $display("FAILED: slow at 11us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 11us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 11us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 11us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end #88 // 99 us if (slow !== 1'b0) begin $display("FAILED: slow at 99us, expected 1'b0, got %b.", slow); pass = 1'b0; end if (saf !== 1'b0) begin $display("FAILED: saf at 99us, expected 1'b0, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 99us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 99us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end #2 // 101 us if (slow !== 1'b1) begin $display("FAILED: slow at 101us, expected 1'b1, got %b.", slow); pass = 1'b0; end if (saf !== 1'b1) begin $display("FAILED: saf at 101us, expected 1'b1, got %b.", saf); pass = 1'b0; end if (fast !== 1'b1) begin $display("FAILED: fast at 101us, expected 1'b1, got %b.", fast); pass = 1'b0; end if (fast_g !== 1'b1) begin $display("FAILED: fast_g at 101us, expected 1'b1, got %b.", fast_g); pass = 1'b0; end if (pass) $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_timeunit_prec3a.v000066400000000000000000000066141435245347300225430ustar00rootroot00000000000000/* * Check the basic parsing. */ // A global timeunit and timeprecision are OK timeunit 100us; timeprecision 1us; /* * Check the various timeunit/precision combinations (this is valid SV syntax). */ // A local time unit is OK. module check_tu; timeunit 10us; endmodule // A local time precision is OK. module check_tp; timeprecision 10us; endmodule // Both a local time unit and precision are OK. module check_tup; timeunit 10us; timeprecision 10us; endmodule // Both a local time unit and precision are OK (check both orders). module check_tpu; timeprecision 10us; timeunit 10us; endmodule /* * Now do the same with repeat declarations (this is valid SV syntax). */ // A global timeunit and timeprecision are OK timeunit 100us; timeprecision 1us; // A local time unit is OK. module check_tu_d; timeunit 10us; timeunit 10us; endmodule // A local time precision is OK. module check_tp_d; timeprecision 10us; timeprecision 10us; endmodule // Both a local time unit and precision are OK. module check_tup_d; timeunit 10us; timeprecision 10us; timeunit 10us; timeprecision 10us; endmodule // Both a local time unit and precision are OK (check both orders). module check_tpu_d; timeprecision 10us; timeunit 10us; timeprecision 10us; timeunit 10us; endmodule /* * Now check all the valid timeunit and time precision values. */ module check_100s; timeunit 100s; timeprecision 100s; endmodule module check_10s; timeunit 10s; timeprecision 10s; endmodule module check_1s; timeunit 1s; timeprecision 1s; endmodule module check_100ms; timeunit 100ms; timeprecision 100ms; endmodule module check_10ms; timeunit 10ms; timeprecision 10ms; endmodule module check_1ms; timeunit 1ms; timeprecision 1ms; endmodule module check_100us; timeunit 100us; timeprecision 100us; endmodule module check_10us; timeunit 10us; timeprecision 10us; endmodule module check_1us; timeunit 1us; timeprecision 1us; endmodule module check_100ns; timeunit 100ns; timeprecision 100ns; endmodule module check_10ns; timeunit 10ns; timeprecision 10ns; endmodule module check_1ns; timeunit 1ns; timeprecision 1ns; endmodule module check_100ps; timeunit 100ps; timeprecision 100ps; endmodule module check_10ps; timeunit 10ps; timeprecision 10ps; endmodule module check_1ps; timeunit 1ps; timeprecision 1ps; endmodule module check_100fs; timeunit 100fs; timeprecision 100fs; endmodule module check_10fs; timeunit 10fs; timeprecision 10fs; endmodule module check_1fs; timeunit 1fs; timeprecision 1fs; endmodule module check1; initial begin $printtimescale(check_100s); $printtimescale(check_10s); $printtimescale(check_1s); $printtimescale(check_100ms); $printtimescale(check_10ms); $printtimescale(check_1ms); $printtimescale(check_100us); $printtimescale(check_10us); $printtimescale(check_1us); $printtimescale(check_100ns); $printtimescale(check_10ns); $printtimescale(check_1ns); $printtimescale(check_100ps); $printtimescale(check_10ps); $printtimescale(check_1ps); $printtimescale(check_100fs); $printtimescale(check_10fs); $printtimescale(check_1fs); $display(""); $printtimescale(check_tu); $printtimescale(check_tp); $printtimescale(check_tup); $printtimescale(check_tpu); $display(""); $printtimescale(check_tu_d); $printtimescale(check_tp_d); $printtimescale(check_tup_d); $printtimescale(check_tpu_d); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec3b.v000066400000000000000000000025601435245347300225400ustar00rootroot00000000000000/* * Check declarations and repeat declarations in nested modules. */ timeunit 100us; timeprecision 1us; // A local time unit is OK. module check_tu_nest; timeunit 10us; module nested; timeunit 100us; timeunit 100us; endmodule timeunit 10us; endmodule // A local time precision is OK. module check_tp_nest; timeprecision 10us; module nested; timeprecision 1us; timeprecision 1us; endmodule timeprecision 10us; endmodule // Both a local time unit and precision are OK. module check_tup_nest; timeunit 10us; timeprecision 10us; module nested; timeunit 100us; timeprecision 1us; timeunit 100us; timeprecision 1us; endmodule timeunit 10us; timeprecision 10us; endmodule // Both a local time unit and precision are OK (check both orders). module check_tpu_nest; timeprecision 10us; timeunit 10us; module nested; timeprecision 1us; timeunit 100us; timeprecision 1us; timeunit 100us; endmodule timeprecision 10us; timeunit 10us; endmodule module check2; initial begin $printtimescale(check_tu_nest); $printtimescale(check_tp_nest); $printtimescale(check_tup_nest); $printtimescale(check_tpu_nest); $display(""); $printtimescale(check_tu_nest.nested); $printtimescale(check_tp_nest.nested); $printtimescale(check_tup_nest.nested); $printtimescale(check_tpu_nest.nested); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec3c.v000066400000000000000000000004261435245347300225400ustar00rootroot00000000000000// A global timeprecision and local time units. timeprecision 10ps; module gtp_ltu1; timeunit 1ns; endmodule module gtp_ltu2; timeunit 1us; endmodule `timescale 1s/1s module check3; initial begin $printtimescale(gtp_ltu1); $printtimescale(gtp_ltu2); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec3d.v000066400000000000000000000004321435245347300225360ustar00rootroot00000000000000// A global timeunit and local time precision. timeunit 10s; module gtu_ltp1; timeprecision 10ps; endmodule module gtu_ltp2; timeprecision 1ns; endmodule `timescale 1s/1s module check4; initial begin $printtimescale(gtu_ltp1); $printtimescale(gtu_ltp2); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec4a.v000066400000000000000000000043621435245347300225420ustar00rootroot00000000000000/* * Check the basic parsing. */ /* * Check the various timeunit/precision combinations (this is valid SV syntax). */ // A global timeunit and timeprecision are OK timeunit 100us/1us; // Both a local time unit and precision are OK. module check_tup; timeunit 10us/10us; endmodule /* * Now do the same with repeat declarations (this is valid SV syntax). */ // A global timeunit and timeprecision are OK timeunit 100us/1us; // Both a local time unit and precision are OK. module check_tup_d; timeunit 10us/10us; timeunit 10us/10us; timeunit 10us; timeprecision 10us; endmodule /* * Now check all the valid timeunit and time precision values. */ module check_100s; timeunit 100s / 100s; endmodule module check_10s; timeunit 10s / 10s; endmodule module check_1s; timeunit 1s / 1s; endmodule module check_100ms; timeunit 100ms / 100ms; endmodule module check_10ms; timeunit 10ms / 10ms; endmodule module check_1ms; timeunit 1ms / 1ms; endmodule module check_100us; timeunit 100us / 100us; endmodule module check_10us; timeunit 10us / 10us; endmodule module check_1us; timeunit 1us / 1us; endmodule module check_100ns; timeunit 100ns / 100ns; endmodule module check_10ns; timeunit 10ns / 10ns; endmodule module check_1ns; timeunit 1ns / 1ns; endmodule module check_100ps; timeunit 100ps / 100ps; endmodule module check_10ps; timeunit 10ps / 10ps; endmodule module check_1ps; timeunit 1ps / 1ps; endmodule module check_100fs; timeunit 100fs / 100fs; endmodule module check_10fs; timeunit 10fs / 10fs; endmodule module check_1fs; timeunit 1fs / 1fs; endmodule module check1; initial begin $printtimescale(check_100s); $printtimescale(check_10s); $printtimescale(check_1s); $printtimescale(check_100ms); $printtimescale(check_10ms); $printtimescale(check_1ms); $printtimescale(check_100us); $printtimescale(check_10us); $printtimescale(check_1us); $printtimescale(check_100ns); $printtimescale(check_10ns); $printtimescale(check_1ns); $printtimescale(check_100ps); $printtimescale(check_10ps); $printtimescale(check_1ps); $printtimescale(check_100fs); $printtimescale(check_10fs); $printtimescale(check_1fs); $display(""); $printtimescale(check_tup); $printtimescale(check_tup_d); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec4b.v000066400000000000000000000006541435245347300225430ustar00rootroot00000000000000/* * Check declarations and repeat declarations in nested modules. */ timeunit 100us/1us; // Both a local time unit and precision are OK. module check_tup_nest; timeunit 10us / 10us; module nested; timeunit 100us / 1us; timeunit 100us / 1us; endmodule timeunit 10us / 10us; endmodule module check2(); initial begin $printtimescale(check_tup_nest); $printtimescale(check_tup_nest.nested); end endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1.v000066400000000000000000000000261435245347300233620ustar00rootroot00000000000000// deliberately empty iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1a.v000066400000000000000000000026361435245347300235340ustar00rootroot00000000000000/* * Check that errors are caught. */ timeunit 100us; timeprecision 1us; // Repeated declarations must match the initial declarations. timeunit 1ms; timeprecision 1ns; // A local time unit is OK, but a repeat must match. module check_tu_d_e; timeunit 10us; timeunit 1us; endmodule // A local time precision is OK, but a repeat must match. module check_tp_d_e; timeprecision 10us; timeprecision 1us; endmodule // A repeat time unit is only allowed if an initial one is given. module check_tu_m_e; integer foo; timeunit 10us; endmodule // A repeat time precision is only allowed if an initial one is given. module check_tp_m_e; integer foo; timeprecision 10us; endmodule // A local time unit is OK and a repeat is OK, but this is not a prec decl. module check_tup_d_e; timeunit 10us; timeunit 10us; timeprecision 1us; endmodule // A local time prec is OK and a repeat is OK, but this is not a unit decl. module check_tpu_d_e; timeprecision 1us; timeprecision 1us; timeunit 10us; endmodule /* Check some invalid values */ // Only a power of 10 is allowed. timeunit 200s; timeprecision 200s; // Too many zeros (only allow 0 - 2). timeunit 1000s; timeprecision 1000s; // This actually trips as an invalid scale of '2s'. timeunit 12s; timeprecision 12s; // This needs to be checked. The base time_literal supports this, but // for now timeunit/precision code does not. timeunit 1_0s; timeprecision 1_0s; iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1b.v000066400000000000000000000001331435245347300235230ustar00rootroot00000000000000// Check a missing global time precision. `resetall timeunit 1ns; module no_gtp; endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1c.v000066400000000000000000000001731435245347300235300ustar00rootroot00000000000000// Check a global timeprecision that is too large. `resetall timeunit 1ns; timeprecision 10ns; module gtp_large; endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1d.v000066400000000000000000000001351435245347300235270ustar00rootroot00000000000000// Check a missing local time precision. `resetall module no_ltp; timeunit 1ns; endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail1e.v000066400000000000000000000001771435245347300235360ustar00rootroot00000000000000// Check a local timeprecision that is too large. `resetall module ltp_large; timeunit 1ns; timeprecision 10ns; endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail2.v000066400000000000000000000000261435245347300233630ustar00rootroot00000000000000// deliberately empty iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail2a.v000066400000000000000000000021301435245347300235220ustar00rootroot00000000000000/* * Check that errors are caught. */ timeunit 100us/1us; // Repeated declarations must match the initial declarations. timeunit 1ms/1ns; // A local time unit/precision is OK, but a repeat must match. module check_tup_d_e; timeunit 10us/10us; timeunit 1us/1us; timeunit 1us; timeprecision 1us; endmodule // A repeat time unit/precision is only allowed if an initial one is given. module check_tup_m_e; integer foo; timeunit 10us/10us; endmodule // A local time unit is OK and a repeat is OK, but this is not a prec decl. module check_tu_d_e; timeunit 10us; timeunit 10us/1us; endmodule // A local time prec is OK and a repeat is OK, but this is not a unit decl. module check_tp_d_e; timeprecision 1us; timeunit 10us/1us; endmodule /* Check some invalid values */ // Only a power of 10 is allowed. timeunit 200s/200s; // Too many zeros (only allow 0 - 2). timeunit 1000s/1000s; // This actually trips as an invalid scale of '2s'. timeunit 12s/12s; // This needs to be checked. The base time_literal supports this, but // for now timeunit/precision code does not. timeunit 1_0s/1_0s; iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail2b.v000066400000000000000000000001551435245347300235300ustar00rootroot00000000000000// Check a global timeprecision that is too large. `resetall timeunit 1ns/10ns; module gtp_large; endmodule iverilog-12_0/ivtest/ivltests/sv_timeunit_prec_fail2c.v000066400000000000000000000001551435245347300235310ustar00rootroot00000000000000// Check a local timeprecision that is too large. `resetall module ltp_large; timeunit 1ns/10ns; endmodule iverilog-12_0/ivtest/ivltests/sv_type_param1.v000066400000000000000000000007071435245347300216670ustar00rootroot00000000000000// Check that basic type parameter syntax is supported bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test #( parameter type T1 = integer ); T1 x; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param2.v000066400000000000000000000010501435245347300216600ustar00rootroot00000000000000// Check that it is possible to declare multiple type parameters as a list with // a single type keyword. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test #( parameter type T1 = integer, T2 = real ); T1 x; T2 y = 1.23; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) `check(y, 1.23) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param3.v000066400000000000000000000007461435245347300216740ustar00rootroot00000000000000// Check that it is possible to declare type parameters when omitting the // parameter keyword. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test #( type T1 = integer ); T1 x; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param4.v000066400000000000000000000007701435245347300216720ustar00rootroot00000000000000// Check that it is possible to reference other parameters in the default value // of a type parameter. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test #( parameter A = 10, parameter type T1 = logic [A-1:0] ); T1 x; initial begin `check($bits(x), A) `check($bits(T1), A) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param5.v000066400000000000000000000007161435245347300216730ustar00rootroot00000000000000// Check that it is possible to declare local type parameters. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test; parameter A = 10; localparam type T1 = logic [A-1:0]; T1 x; initial begin `check($bits(x), A) `check($bits(T1), A) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param6.v000066400000000000000000000023471435245347300216760ustar00rootroot00000000000000// Check that various syntax variations for type parameters without a default // value are supported. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module M1 #( parameter type T1 ); T1 x; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) end endmodule module M2 #( type T1 ); T1 x; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) end endmodule module M3 #( parameter type T1, T2 ); T1 x; T2 y = 1.23; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) `check(y, 1.23) end endmodule module M4 #( type T1, T2 ); T1 x; T2 y = 1.23; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) `check(y, 1.23) end endmodule module test; M1 #( .T1 (integer) ) i_m1 (); M2 #( .T1 (integer) ) i_m2 (); M3 #( .T1 (integer), .T2 (real) ) i_m3(); M4 #( .T1 (integer), .T2 (real) ) i_m4 (); initial begin #1 if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param7.v000066400000000000000000000017501435245347300216740ustar00rootroot00000000000000// Check that it is possible to overwrite type parameters and that the provided // type is evaluated in the scope instantiating the module. bit failed = 1'b0; `define check(expr, val) \ if (expr != val) begin \ $display("failed: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module M #( parameter type T1 = integer, parameter WIDTH = 0 ); typedef logic [1:0] T2; localparam A = 2; T1 x; initial begin `check($bits(x), WIDTH) `check($bits(T1), WIDTH) end endmodule module test; localparam A = 4; typedef logic [A-1:0] T2; M #( .WIDTH ($bits(integer)) ) i_m1 (); M #( .T1 (logic [15:0]), .WIDTH (16) ) i_m2 (); // `A` must be evauluated in this context M #( .T1 (logic [A-1:0]), .WIDTH (4) ) i_m3 (); // `T2` must be evauluated in this context M #( .T1 (T2), .WIDTH (4) ) i_m4 (); initial begin #1 if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_type_param_fail1.v000066400000000000000000000003771435245347300226650ustar00rootroot00000000000000// Check that overrideing a type parameter with an expression that is not a type // generates an error. module M #( type T = int ); T x; initial begin $display("FAILED"); end endmodule module test; M #( .T(10) ) m(); endmodule iverilog-12_0/ivtest/ivltests/sv_type_param_fail2.v000066400000000000000000000004311435245347300226550ustar00rootroot00000000000000// Check that trying to override a type parameter using a defparam statement // generates an error. module M #( type T = int ); T x; initial begin $display("FAILED"); end endmodule module test; M m(); defparam m.T = real; // Error, this is illegal endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_array_base1.v000066400000000000000000000005551435245347300233570ustar00rootroot00000000000000// Check that a vector base typeof an array type is evaluated in the scope where // the array type is declared. localparam A = 8; typedef logic [A-1:0] T[1:0]; module test; localparam A = 4; T x; initial begin x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_array_base2.v000066400000000000000000000006261435245347300233570ustar00rootroot00000000000000// Check that a complex base type (like a struct) of an array type is evaluated // in the scope where the array type is declared. localparam A = 8; typedef struct packed { logic [A-1:0] x; } T[1:0]; module test; localparam A = 4; T x; initial begin x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_array_base3.v000066400000000000000000000006601435245347300233560ustar00rootroot00000000000000// Check that a vector base type of an array type gets evaluated in the right // scope if the base type is defined in a different scope than the array type. localparam A = 8; typedef logic [A-1:0] Base; module test; localparam A = 4; typedef Base T[1:0]; T x; initial begin x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_array_base4.v000066400000000000000000000007331435245347300233600ustar00rootroot00000000000000// Check that a complex base type (like a struct) of an array type gets // evaluated in the right scope if the base type is defined in a different scope // than the array type. localparam A = 8; typedef struct packed { logic [A-1:0] x; } Base; module test; localparam A = 4; typedef Base T[1:0]; T x; initial begin x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_chained.v000066400000000000000000000015141435245347300225550ustar00rootroot00000000000000// Check that chained type definitions declared in different scopes work // correctly. package P1; localparam A = 8; typedef logic [A-1:0] T; endpackage package P2; localparam A = 4; typedef P1::T T; endpackage bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end module test; localparam A = 2; typedef P2::T T; T x; P1::T y; P2::T z; initial begin x = 8'hff; y = 8'hff; z = 8'hff; `check(x, 8'hff); `check($bits(T), 8); `check($bits(x), 8); `check(y, 8'hff); `check($bits(y), 8); `check($bits(P1::T), 8); `check(z, 8'hff); `check($bits(z), 8); `check($bits(P2::T), 8); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_circular1.v000066400000000000000000000003201435245347300230410ustar00rootroot00000000000000// Check that circular type definitions are detected and an error is reported. module test; typedef T1; typedef T1 T2; typedef T2 T1; T2 x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_circular2.v000066400000000000000000000003361435245347300230510ustar00rootroot00000000000000// Check that longer chains of circular type definitions are detected as an // error. module test; typedef T1; typedef struct packed { T1 x; } T2; typedef T2 [1:0] T3; typedef T3 T1; T1 x; endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_darray_base1.v000066400000000000000000000006021435245347300235140ustar00rootroot00000000000000// Check that a vector base typeof a dynamic array type is evaluated in the // scope where the array type is declared. localparam A = 8; typedef logic [A-1:0] T[]; module test; localparam A = 4; T x; initial begin x = new [1]; x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_darray_base2.v000066400000000000000000000007411435245347300235210ustar00rootroot00000000000000// Check that a complex base type (like a packed array) of a dynamic array type // is evaluated in the scope where the array type is declared. localparam A = 8; // Use type identifier for the base to force packed array typedef logic l; typedef l [A-1:0] T[]; module test; localparam A = 4; T x; initial begin x = new [1]; x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_darray_base3.v000066400000000000000000000007101435245347300235160ustar00rootroot00000000000000// Check that a vector base type of a dynamic array type gets evaluated in the // right scope if the base type is defined in a different scope than the array // type. localparam A = 8; typedef logic [A-1:0] Base; module test; localparam A = 4; typedef Base T[]; T x; initial begin x = new [1]; x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_darray_base4.v000066400000000000000000000010371435245347300235220ustar00rootroot00000000000000// Check that a complex base type (like a struct) of a dynamic array type gets // evaluated in the right scope if the base type is defined in a different scope // than the array type. localparam A = 8; // Use type identifier for the base to force packed array typedef logic l; typedef l [A-1:0] Base; module test; localparam A = 4; typedef Base T[]; T x; initial begin x = new [1]; x[0] = 8'hff; if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_base.v000066400000000000000000000017041435245347300227350ustar00rootroot00000000000000// Check that forward typedefs of basic types are supported `define check(val, exp) \ if (val != exp) begin \ $display("FAILED(%0d). '%s' expected ", `__LINE__, `"val`", exp, " got ", val, ); \ failed = 1'b1; \ end bit failed = 1'b0; module test; typedef T1; typedef T1; // Check forward typedef twice for the same type typedef T2; typedef T3; typedef T4; T1 x = -1; T2 y = 1.23; T3 z = "Hello"; T4 w; typedef integer T1; // There can be as many forward typedefs as we like, even after the type // itself has already been declared. typedef T1; typedef T1; typedef real T2; typedef string T3; typedef logic [1:0] T4[3:0]; initial begin `check($bits(x), $bits(integer)) `check($bits(T1), $bits(integer)) `check(x, -1) `check(y, 1.23) `check(z, "Hello") `check($unpacked_dimensions(w), 1) `check($size(w), 4) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_class.v000066400000000000000000000014461435245347300231330ustar00rootroot00000000000000// Check that forward typedefs of classes are supported module test; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %d, got %d", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end bit failed = 1'b0; typedef class C; typedef C; C x; class C; int x; endclass C y; // There can be as many forward typedefs as we like, even after the type // itself has already been declared. typedef C; typedef class C; C z; initial begin // Check they are all the same type and can be assigned to each other x = y; y = z; z = x; `check($bits(x.x), $bits(int)); `check($bits(y.x), $bits(int)); `check($bits(z.x), $bits(int)); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_class2.v000066400000000000000000000004311435245347300232060ustar00rootroot00000000000000// Check that it is possible to use a forward declared class type as the type of // a property in another class. module test; typedef class B; class C; B b; endclass class B; endclass C c; initial begin c = new; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_enum1.v000066400000000000000000000012761435245347300230540ustar00rootroot00000000000000// Check that forward enum typedefs are supported module test; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end bit failed = 1'b0; typedef T; typedef enum T; T x; typedef enum integer { A, B } T; T y; typedef enum T; typedef T; T z; initial begin // Check that they are all the same type and can be assigned to each other x = y; y = z; z = x; `check($bits(x), $bits(integer)) `check($bits(y), $bits(integer)) `check($bits(z), $bits(integer)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_enum2.v000066400000000000000000000004671435245347300230560ustar00rootroot00000000000000// Check that the base type of an enum can be a forward typedef module test; typedef T1; typedef enum T1 { A, B } T2; typedef logic [31:0] T1; T2 z; initial begin if ($bits(z) == 32) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_enum3.v000066400000000000000000000005221435245347300230470ustar00rootroot00000000000000// Check that a forwarded enum typedef can be referenced in a class module test; typedef T; class C; T x; endclass typedef enum integer { X, Y } T; initial begin C c; c = new; if ($bits(c.x) == 32) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_enum_fail.v000066400000000000000000000002511435245347300237560ustar00rootroot00000000000000// Check that a enum can't be its own base type module test; typedef T; typedef enum T { A, B } T; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_struct.v000066400000000000000000000011121435245347300233400ustar00rootroot00000000000000// Check that forward struct typedefs are supported module test; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end bit failed = 1'b0; typedef T; typedef struct T; T x; typedef struct packed { int x; } T; T y; typedef struct T; typedef T; T z; initial begin `check($bits(x), $bits(int)) `check($bits(y), $bits(int)) `check($bits(z), $bits(int)) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_struct_fail.v000066400000000000000000000003711435245347300243410ustar00rootroot00000000000000// Check that it is an error to use a forwarded struct type as the type for the // member in the struct itself. module test; typedef T; typedef struct packed { T x; } T; T x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_union.v000066400000000000000000000013241435245347300231510ustar00rootroot00000000000000// Check that forward typdes of unions are supported module test; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \ failed = 1'b1; \ end bit failed = 1'b0; typedef union T; typedef T; T x; typedef union packed { int x; logic [3:0][7:0] y; } T; T y; // There can be as many forward typedefs as we like, even after the type // itself has already been declared. typedef T; typedef union T; T z; initial begin `check($bits(x), $bits(int)); `check($bits(y), $bits(int)); `check($bits(z), $bits(int)); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_fwd_union_fail.v000066400000000000000000000003671435245347300241520ustar00rootroot00000000000000// Check that it is an error to use a forwarded union type as the type for the // members in the union itself. module test; typedef T; typedef union packed { T x; } T; T x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_nested_array.v000066400000000000000000000014721435245347300236450ustar00rootroot00000000000000// Check that nested unpacked array types are supported. module test; localparam A = 3; localparam B = 5; localparam C = 2; localparam D = 7; typedef logic [31:0] T1[A]; typedef T1 T2[B][C]; T2 x[D]; T2 y; bit failed = 1'b0; `define check(expr, val) \ if (expr !== val) begin \ $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ failed = 1'b1; \ end initial begin `check($unpacked_dimensions(x), 4) `check($size(x, 1), A) `check($size(x, 2), B) `check($size(x, 3), C) `check($size(x, 4), D) `check($unpacked_dimensions(y), 3) `check($size(y, 1), A) `check($size(y, 2), B) `check($size(y, 3), C) `check($bits(T2), $bits(integer) * A * B * C) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_queue_base1.v000066400000000000000000000005601435245347300233610ustar00rootroot00000000000000// Check that a vector base typeof a queue type is evaluated in the scope where // the array type is declared. localparam A = 8; typedef logic [A-1:0] T[$]; module test; localparam A = 4; T x; initial begin x.push_back(8'hff); if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_queue_base2.v000066400000000000000000000007171435245347300233660ustar00rootroot00000000000000// Check that a complex base type (like a packed array) of a queue type is // evaluated in the scope where the array type is declared. localparam A = 8; // Use type identifier for the base to force packed array typedef logic l; typedef l [A-1:0] T[$]; module test; localparam A = 4; T x; initial begin x.push_back(8'hff); if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_queue_base3.v000066400000000000000000000006631435245347300233670ustar00rootroot00000000000000// Check that a vector base type of a queue type gets evaluated in the right // scope if the base type is defined in a different scope than the array type. localparam A = 8; typedef logic [A-1:0] Base; module test; localparam A = 4; typedef Base T[$]; T x; initial begin x.push_back(8'hff); if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_queue_base4.v000066400000000000000000000010241435245347300233600ustar00rootroot00000000000000// Check that a complex base type (like a packed array) of a queue type gets // evaluated in the right scope if the base type is defined in a different scope // than the array type. localparam A = 8; // Use type identifier for the base to force packed array typedef logic l; typedef l [A-1:0] Base; module test; localparam A = 4; typedef Base T[$]; T x; initial begin x.push_back(8'hff); if (x[0] === 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_scope1.v000066400000000000000000000015141435245347300223540ustar00rootroot00000000000000 typedef struct packed { logic [1:0] hig; logic [1:0] low; } foo_t; module main; // This typedef should work, and should shadow the foo_t definition // in the $root scope. typedef struct packed { logic [2:0] hig_x; logic [2:0] low_x; } foo_t; foo_t foo; initial begin foo = 6'b111000; if ($bits(foo_t) != 6) begin $display("FAILED -- Got wrong foo_t definition?"); $finish; end if ($bits(foo) != 6) begin $display("FAILED -- $bits(foo)==%0d", $bits(foo)); $finish; end if (foo.hig_x !== 3'b111) begin $display("FAILED -- foo=%b, foo.hig_x=%b", foo, foo.hig_x); $finish; end if (foo.low_x !== 3'b000) begin $display("FAILED -- foo=%b, foo.low_x=%b", foo, foo.low_x); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_typedef_scope2.v000066400000000000000000000007521435245347300223600ustar00rootroot00000000000000// Check that it is possible to overwrite a type identifier declared in a higher // level scope. Check that this works if the new type is an array type. typedef logic [3:0] T; T x; module test; typedef logic [7:0] T[1:0]; T y; initial begin y[0] = 8'hff; y[1] = 8'hfe; if ($bits(T) == 16 && $size(x) == 4 && $size(y) == 2 && y[0] == 8'hff && y[1] == 8'hfe) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_typedef_scope3.v000066400000000000000000000010101435245347300223450ustar00rootroot00000000000000// Check that it is possible to overwrite a type identifier declared in a higher // level scope. Check that this works when the new type is declared in a class. typedef logic [3:0] T; T x; module test; class C; typedef logic [7:0] T; T y; task t; y = 8'hff; if ($bits(x) == 4 && $bits(y) == 8 && y == 8'hff) begin $display("PASSED"); end else begin $display("FAILED"); end endtask endclass C c; initial begin c = new; c.t(); end endmodule iverilog-12_0/ivtest/ivltests/sv_union1.v000066400000000000000000000014011435245347300206460ustar00rootroot00000000000000 module main; typedef union packed { logic [3:0] bits; struct packed { logic [1:0] hig; logic [1:0] low; } words; } bits_t; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits !== 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words !== 'b1001) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end //foo.words.low = 'b00; //foo.words.hig = 'b11; foo.words = 'b1100; if (foo.words !== 'b1100) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits !== 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union1b.v000066400000000000000000000013721435245347300210170ustar00rootroot00000000000000 typedef union packed { logic [3:0] bits; struct packed { logic [1:0] hig; logic [1:0] low; } words; } bits_t; module main; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits !== 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words !== 'b1001) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end //foo.words.low = 'b00; //foo.words.hig = 'b11; foo.words = 'b1100; if (foo.words !== 'b1100) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits !== 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union2.v000066400000000000000000000014701435245347300206550ustar00rootroot00000000000000 module main; typedef struct packed { logic [1:0] hig; logic [1:0] low; } word_as_nibbles; typedef union packed { logic [3:0] bits; word_as_nibbles words; } bits_t; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits != 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words != 'b1001) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end //foo.words.low = 'b00; //foo.words.hig = 'b11; foo.words = 'b1100; if (foo.words != 'b1100) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits != 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union2b.v000066400000000000000000000014411435245347300210150ustar00rootroot00000000000000 typedef struct packed { logic [1:0] hig; logic [1:0] low; } word_as_nibbles; typedef union packed { logic [3:0] bits; word_as_nibbles words; } bits_t; module main; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits != 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words != 'b1001) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end //foo.words.low = 'b00; //foo.words.hig = 'b11; foo.words = 'b1100; if (foo.words != 'b1100) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits != 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union3.v000066400000000000000000000013471435245347300206610ustar00rootroot00000000000000 module main; typedef enum logic [3:0] { WORD0, WORD1, WORD9='b1001, WORDC='b1100 } word_t; typedef union packed { logic [3:0] bits; word_t words; } bits_t; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits !== 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words !== WORD9) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end foo.words = WORDC; if (foo.words !== WORDC) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits !== 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union3b.v000066400000000000000000000013311435245347300210140ustar00rootroot00000000000000 typedef enum logic [3:0] { WORD0, WORD1, WORD9='b1001, WORDC='b1100 } word_t; typedef union packed { logic [3:0] bits; word_t words; } bits_t; module main; bits_t foo; initial begin foo.bits = 'b1001; if (foo.bits !== 'b1001) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end if (foo.words !== WORD9) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end foo.words = WORDC; if (foo.words !== WORDC) begin $display("FAILED -- foo.words=%b", foo.words); $finish; end if (foo.bits !== 'b1100) begin $display("FAILED -- foo.bits=%b", foo.bits); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_union4b.v000066400000000000000000000007001435245347300210140ustar00rootroot00000000000000 typedef union packed { logic [3:0] bits; struct packed { logic [1:0] hig; logic [1:0] low; } words; } bits_t; module main; bits_t foo; initial begin if ($bits(foo) !== 4) begin $display("FAILED -- $bits(foo)=%0d", $bits(foo)); $finish; end if ($bits(bits_t) !== 4) begin $display("FAILED -- $bits(bits_t)=%0d", $bits(bits_t)); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_unit1a.v000066400000000000000000000004551435245347300206460ustar00rootroot00000000000000`define MACRO2 12 `define MACRO3 13 `default_nettype tri1 module test1(); buf(a,b); initial #1 begin $display("test1 macro1 = %0d", `MACRO1 ); $display("test1 macro2 = %0d", `MACRO2 ); $display("test1 macro3 = %0d", `MACRO3 ); $display("test1 wire = %b", a); end endmodule `undef MACRO1 iverilog-12_0/ivtest/ivltests/sv_unit1b.v000066400000000000000000000005421435245347300206440ustar00rootroot00000000000000`ifndef MACRO1 `define MACRO1 21 `endif `ifndef MACRO2 `define MACRO2 22 `endif `ifndef MACRO3 `define MACRO3 23 `endif module test2(input w); buf(a,b); initial #2 begin $display("test2 macro1 = %0d", `MACRO1 ); $display("test2 macro2 = %0d", `MACRO2 ); $display("test2 macro3 = %0d", `MACRO3 ); $display("test2 wire = %b", a); end endmodule iverilog-12_0/ivtest/ivltests/sv_unit1c.v000066400000000000000000000005421435245347300206450ustar00rootroot00000000000000`ifndef MACRO1 `define MACRO1 21 `endif `ifndef MACRO2 `define MACRO2 22 `endif `ifndef MACRO3 `define MACRO3 23 `endif module test2(input w); buf(a,b); initial #2 begin $display("test2 macro1 = %0d", `MACRO1 ); $display("test2 macro2 = %0d", `MACRO2 ); $display("test2 macro3 = %0d", `MACRO3 ); $display("test2 wire = %b", a); end endmodule iverilog-12_0/ivtest/ivltests/sv_unit2a.v000066400000000000000000000020321435245347300206400ustar00rootroot00000000000000function int hello(int a); begin $display("hello from unit 1"); hello = a; end endfunction task hello1; begin $display("hello1 from unit 1"); end endtask task hello2; begin $display("hello2 from unit 1"); end endtask task hello3; begin $display("hello3 from unit 1"); end endtask class c1; task hello2; begin hello1; $display("hello2 from c1"); end endtask endclass module m1(); int i; c1 obj; initial begin #1; i = $unit::hello(1); obj = new; obj.hello2; hello1; hello2; hello3; hello4; end task hello2; begin $display("hello2 from m1"); end endtask endmodule module m2(); m1 m1inst(); task hello1; begin $display("hello1 from m2"); end endtask task hello2; begin $display("hello2 from m2"); end endtask task hello3; begin $display("hello3 from m2"); end endtask task hello4; begin $display("hello4 from m2"); end endtask endmodule iverilog-12_0/ivtest/ivltests/sv_unit2b.v000066400000000000000000000014441435245347300206470ustar00rootroot00000000000000task hello1; begin $display("hello1 from unit 2"); end endtask task hello2; begin $display("hello2 from unit 2"); end endtask task hello3; begin $display("hello3 from unit 2"); end endtask module m3(); initial begin #2; // allow m1 to go first m2.m1inst.obj.hello2; hello1; hello2; hello3; hello4; end task hello2; begin $display("hello2 from m3"); end endtask endmodule module m4(); m3 m3inst(); task hello1; begin $display("hello1 from m4"); end endtask task hello2; begin $display("hello2 from m4"); end endtask task hello3; begin $display("hello3 from m4"); end endtask task hello4; begin $display("hello4 from m4"); end endtask endmodule iverilog-12_0/ivtest/ivltests/sv_unit3a.v000066400000000000000000000017001435245347300206420ustar00rootroot00000000000000int num1 = 101; string str1 = "unit1"; int num2 = 102; string str2 = "unit1"; int num3 = 103; string str3 = "unit1"; class c1; int num2 = 100; string str2 = "c1"; task display; begin $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); end endtask endclass module m1(); int num2 = 112; string str2 = "m1"; c1 obj; initial begin #1; obj = new; obj.display; $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); $display("%d from %s", num3, str3); $display("%d from %s", m2.num4, m2.str4); end /* This should not change the result, but Icarus ignores the order in which variables are declared and used. int num3 = 113; string str3 = "m1"; */ endmodule module m2(); int num1 = 121; string str1 = "m2"; int num2 = 122; string str2 = "m2"; int num3 = 123; string str3 = "m2"; int num4 = 124; string str4 = "m2"; m1 m1inst(); endmodule iverilog-12_0/ivtest/ivltests/sv_unit3b.v000066400000000000000000000014121435245347300206430ustar00rootroot00000000000000int num1 = 201; string str1 = "unit2"; int num2 = 202; string str2 = "unit2"; int num3 = 203; string str3 = "unit2"; module m3(); int num2 = 232; string str2 = "m3"; initial begin #2; // allow m1 to go first m2.m1inst.obj.display; $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); $display("%d from %s", num3, str3); $display("%d from %s", m4.num4, m4.str4); end /* This should not change the result, but Icarus ignores the order in which variables are declared and used. int num3 = 113; string str3 = "m3"; */ endmodule module m4(); int num1 = 241; string str1 = "m4"; int num2 = 242; string str2 = "m4"; int num3 = 243; string str3 = "m4"; int num4 = 244; string str4 = "m4"; m3 m3inst(); endmodule iverilog-12_0/ivtest/ivltests/sv_unit4a.v000066400000000000000000000017141435245347300206500ustar00rootroot00000000000000localparam num1 = 101, str1 = "unit1"; localparam num2 = 102, str2 = "unit1"; localparam num3 = 103, str3 = "unit1"; class c1; const int num2 = 100; const string str2 = "c1"; task display; begin $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); end endtask endclass module m1(); localparam num2 = 112, str2 = "m1"; c1 obj; initial begin #1; obj = new; obj.display; $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); $display("%d from %s", num3, str3); $display("%d from %s", m2.num4, m2.str4); end /* This should not change the result, but Icarus ignores the order in which variables are declared and used. localparam num3 = 113, str3 = "m1"; */ endmodule module m2(); localparam num1 = 121, str1 = "m2"; localparam num2 = 122, str2 = "m2"; localparam num3 = 123, str3 = "m2"; localparam num4 = 124, str4 = "m2"; m1 m1inst(); endmodule iverilog-12_0/ivtest/ivltests/sv_unit4b.v000066400000000000000000000014001435245347300206410ustar00rootroot00000000000000parameter num1 = 201, str1 = "unit2"; parameter num2 = 202, str2 = "unit2"; parameter num3 = 203, str3 = "unit2"; module m3(); parameter num2 = 232, str2 = "m3"; initial begin #2; // allow m1 to go first m2.m1inst.obj.display; $display("%d from %s", num1, str1); $display("%d from %s", num2, str2); $display("%d from %s", num3, str3); $display("%d from %s", m4.num4, m4.str4); end /* This should not change the result, but Icarus ignores the order in which variables are declared and used. parameter num = 113, str3 = "m3"; */ endmodule module m4(); parameter num1 = 241, str1 = "m4"; parameter num2 = 242, str2 = "m4"; parameter num3 = 243, str3 = "m4"; parameter num4 = 244, str4 = "m4"; m3 m3inst(); endmodule iverilog-12_0/ivtest/ivltests/sv_unpacked_port.v000066400000000000000000000015721435245347300223040ustar00rootroot00000000000000 module test #(parameter width = 8) (input wire clk, input wire [1:0] addr, input wire [width-1:0] data[0:3], output reg [width-1:0] Q /* */); always @(posedge clk) Q <= data[addr]; endmodule // test module main; localparam width = 8; reg clk; reg [1:0] addr; logic [width-1:0] data [0:3]; wire [width-1:0] Q; test #(.width(width)) DUT (.clk(clk), .addr(addr), .data(data), .Q(Q)); reg [2:0] idx; initial begin clk = 0; data[0] = 0; data[1] = 1; data[2] = 2; data[3] = 3; addr = 0; for (idx = 0 ; idx < 4 ; idx += 1) begin clk = 0; #1 addr = idx[1:0]; #1 clk = 1; #1 if (Q !== data[addr]) begin $display("FAILED -- data[%0d]==%h, Q==%h", addr, data[addr], Q); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_unpacked_port2.v000066400000000000000000000014461435245347300223660ustar00rootroot00000000000000 module test (input clk, input wire [7:0] D, input wire [1:0] S, output reg [7:0] Q [0:3] /* */); always @(posedge clk) Q[S] <= D; endmodule // test module main; reg clk; reg [1:0] S; reg [7:0] D; wire [7:0] Q [0:3]; test dut(.clk(clk), .D(D), .S(S), .Q(Q)); initial begin clk = 0; S = 0; D = 0; #1 clk = 1; #1 clk = 0; S = 1; D = 1; #1 clk = 1; #1 clk = 0; S = 2; D = 2; #1 clk = 1; #1 clk = 0; S = 3; D = 3; #1 clk = 1; #1 clk = 0; for (int idx = 0 ; idx < 4 ; idx = idx+1) begin if (Q[idx] != idx) begin $display("FAILED -- Q[%0d] = %0d", idx, Q[idx]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_unpacked_wire.v000066400000000000000000000014731435245347300222660ustar00rootroot00000000000000 module main; localparam width = 8; reg clk; reg [1:0] addr; logic [width-1:0] data [0:3]; reg [width-1:0] Q; // Does SystemVerilog support continuous assignment // of unpacked arrays? I think it does, but the LRM // is really not clear on this. wire [width-1:0] data_x[0:3]; assign data_x = data; always @(posedge clk) Q <= data_x[addr]; reg [2:0] idx; initial begin clk = 0; data[0] = 0; data[1] = 1; data[2] = 2; data[3] = 3; addr = 0; for (idx = 0 ; idx < 4 ; idx += 1) begin clk = 0; #1 addr = idx[1:0]; #1 clk = 1; #1 if (Q !== data[addr]) begin $display("FAILED -- data[%0d]==%h, Q==%h", addr, data[addr], Q); $finish; end end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_unpacked_wire2.v000066400000000000000000000011231435245347300223400ustar00rootroot00000000000000 module TEST #(parameter ME = 0) (input OE, output wire [3:0] Q /* */); assign Q = OE? ME : 4'd0; endmodule // TEST module main; logic OE; logic [3:0] Q [0:3]; genvar gidx; for (gidx = 0 ; gidx < 4 ; gidx = gidx+1) begin : DRV TEST #(.ME(gidx)) dut (.OE(OE), .Q(Q[gidx])); end int idx; initial begin OE = 1; #1 ; for (idx = 0 ; idx < 4 ; idx = idx+1) begin if (Q[idx] !== idx[3:0]) begin $display("FAILED -- Q[%0d] === %b", idx, Q[idx]); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_uwire1.v000066400000000000000000000012321435245347300206530ustar00rootroot00000000000000 // This simple program tests that a variable can be assigned // party by continuous assignment, and partly by behavioral // assignment. As long as the parts don't overlap, this is // legal (in SystemVerilog) module main; logic [3:0] foo; // Part of the vector is assigned by continuous assignment logic [1:0] bar; assign foo[2:1] = bar; initial begin // Part of the vector is assigned behaviorally. foo[0] = 1'b1; foo[3] = 1'b1; bar = 2'b00; #1 if (foo !== 4'b1001) begin $display("FAILED -- foo=%b", foo); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_uwire2.v000066400000000000000000000012361435245347300206600ustar00rootroot00000000000000 // This simple program tests that a variable can be assigned // party by continuous assignment, and partly by behavioral // assignment. As long as the parts don't overlap, this is // legal (in SystemVerilog) module main; logic [3:0] foo; // Part of the vector is assigned by continuous assignment logic [1:0] bar; assign foo[2:1] = bar; initial begin // Part of the vector is assigned behaviorally. foo[0:0] = 1'b1; foo[3:3] = 1'b1; bar = 2'b00; #1 if (foo !== 4'b1001) begin $display("FAILED -- foo=%b", foo); $finish; end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/sv_uwire3.v000066400000000000000000000014011435245347300206530ustar00rootroot00000000000000 // output ports may be uwire, or even a variable, if wire-ness // or variable-ness are not explicitly stated. typedef struct packed { logic [1:0] a; logic [1:0] b; } sample_t; module main; sample_t dst; logic [1:0] src_a, src_b; DUT dut(.out(dst), .x(src_a), .y(src_b)); initial begin src_a = 1; src_b = 2; #1 /* wait for dst */; if (dst.a !== 1) begin $display("FAILED -- dst.a=%b (dst=%b)", dst.a, dst); $finish; end if (dst.b !== 2) begin $display("FAILED -- dst.b=%b (dst=%b)", dst.b, dst); $finish; end $display("PASSED"); end endmodule // main module DUT(output sample_t out, input logic [1:0] x, y); always @* begin out.a = x; out.b = y; end endmodule iverilog-12_0/ivtest/ivltests/sv_uwire4.v000066400000000000000000000014011435245347300206540ustar00rootroot00000000000000 // output ports may be uwire, or even a variable, if wire-ness // or variable-ness are not explicitly stated. typedef struct packed { logic [1:0] a; logic [1:0] b; } sample_t; module main; sample_t dst; logic [1:0] src_a, src_b; DUT dut(.out(dst), .a(src_a), .b(src_b)); initial begin src_a = 1; src_b = 2; #1 /* wait for dst */; if (dst.a !== 1) begin $display("FAILED -- dst.a=%b (dst=%b)", dst.a, dst); $finish; end if (dst.b !== 2) begin $display("FAILED -- dst.b=%b (dst=%b)", dst.b, dst); $finish; end $display("PASSED"); end endmodule // main module DUT(output sample_t out, input logic [1:0] a, b); always @* begin out.a = a; out.b = b; end endmodule iverilog-12_0/ivtest/ivltests/sv_var_block.v000066400000000000000000000015611435245347300214060ustar00rootroot00000000000000// Check that the var keyword is supported for variable declarations in blocks `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module test; bit failed = 1'b0; initial begin var x; var [7:0] y; var signed [8:0] z; var logic [9:0] w; x = 1'b1; y = 8'd10; z = -8'sd1; w = 8'd20; `check(x, 1'b1) `check(y, 10) `check(z, -1) `check(w, 20) // var should default to logic and allow x state x = 1'bx; y = 8'hxx; z = 8'hxx; w = 8'hxx; `check(x, 1'bx) `check(y, 8'hxx) `check(z, 8'hxx) `check(w, 8'hxx) `check($bits(x), 1) `check($bits(y), 8) `check($bits(z), 9) `check($bits(w), 10) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_for.v000066400000000000000000000004511435245347300210770ustar00rootroot00000000000000// Check that var keyword is supported in for loop variable declarations module test; initial begin int j; for (var int i = 0; i < 10; i++) begin j = i; end if (j == 9) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_for_fail.v000066400000000000000000000004441435245347300220740ustar00rootroot00000000000000// Check that it is an error to not declare the data type in for loops, even // when using var module test; initial begin // The data type is not optional in a for loop, even when using var for (var [7:0] i = 0; i < 10; i++) begin end $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_var_function.v000066400000000000000000000013271435245347300221410ustar00rootroot00000000000000// Check that the var keyword is supported for function ports `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ return 1'b1; \ end \ return 1'b0; module test; function bit f1 (var int x); `check(x, 10) endfunction function bit f2 (input var int x); `check(x, 20) endfunction function bit f3 (var [7:0] x); `check(x, 30) endfunction function bit f4 (input var [7:0] x); `check(x, 40) endfunction initial begin bit failed; failed = f1(10); failed |= f2(20); failed |= f3(30); failed |= f4(40); if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_init1.v000066400000000000000000000003341435245347300213350ustar00rootroot00000000000000module top(); integer i = 1; integer j = 0; always @(i) j = i; initial begin #0 $display("%0d %0d", i, j); if ((i === 1) && (j === 0)) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_var_init2.v000066400000000000000000000003751435245347300213430ustar00rootroot00000000000000module top(); always @(sub.i) sub.j = sub.i; initial begin:sub static integer i = 1; static integer j = 0; #0 $display("%0d %0d", i, j); if ((i === 1) && (j === 0)) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sv_var_module.v000066400000000000000000000015521435245347300216010ustar00rootroot00000000000000// Check that the var keyword is supported for variable declarations in modules `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module test; var x; var [7:0] y; var signed [8:0] z; var logic [9:0] w; bit failed = 1'b0; initial begin x = 1'b1; y = 8'd10; z = -8'sd1; w = 8'd20; `check(x, 1'b1) `check(y, 10) `check(z, -1) `check(w, 20) // var should default to logic and allow x state x = 1'bx; y = 8'hxx; z = 8'hxx; w = 8'hxx; `check(x, 1'bx) `check(y, 8'hxx) `check(z, 8'hxx) `check(w, 8'hxx) `check($bits(x), 1) `check($bits(y), 8) `check($bits(z), 9) `check($bits(w), 10) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_inout1.v000066400000000000000000000002571435245347300231010ustar00rootroot00000000000000// Check that using the var keyword for module ANSI inout ports results in an error module test #( inout var x ); initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_inout2.v000066400000000000000000000002571435245347300231020ustar00rootroot00000000000000// Check that using the var keyword for module non-ANSI inout ports results in an error module test; inout var x; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_input1.v000066400000000000000000000017571435245347300231100ustar00rootroot00000000000000// Check that the var keyword is supported for module ANSI input ports bit failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module M #( parameter VAL_X = 0, parameter VAL_Y = 0, parameter VAL_Z = 0, parameter VAL_W = 0 ) ( input var x, input var [7:0] y, input var signed [7:0] z, input var logic [7:0] w ); initial begin `check(x, VAL_X) `check(y, VAL_Y) `check(z, VAL_Z) `check(w, VAL_W) end endmodule module test; M #( .VAL_X (1'b1), .VAL_Y (8'd10), .VAL_Z (-8'sd1), .VAL_W (8'd20) ) i_m1 ( .x (1'b1), .y (8'd10), .z (-8'sd1), .w (8'd20) ); // When unconnected it should default to x, rather z M #( .VAL_X (1'bx), .VAL_Y (8'hx), .VAL_Z (8'hx), .VAL_W (8'hx) ) i_m2 (); initial begin #1 if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_input2.v000066400000000000000000000017711435245347300231050ustar00rootroot00000000000000// Check that the var keyword is supported for module non-ANSI input ports bit failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module M(x, y, z, w); parameter VAL_X = 0; parameter VAL_Y = 0; parameter VAL_Z = 0; parameter VAL_W = 0; input var x; input var [7:0] y; input var signed [7:0] z; input var logic [7:0] w; initial begin `check(x, VAL_X) `check(y, VAL_Y) `check(z, VAL_Z) `check(w, VAL_W) end endmodule module test; M #( .VAL_X (1'b1), .VAL_Y (8'd10), .VAL_Z (-8'sd1), .VAL_W (8'd20) ) i_m1 ( .x (1'b1), .y (8'd10), .z (-8'sd1), .w (8'd20) ); // When unconnected it should default to x, rather z M #( .VAL_X (1'bx), .VAL_Y (8'hx), .VAL_Z (8'hx), .VAL_W (8'hx) ) i_m2 (); initial begin #1 if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_output1.v000066400000000000000000000025051435245347300233010ustar00rootroot00000000000000// Check that the var keyword is supported for module ANSI output ports bit failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module M #( parameter VAL_X = 0, parameter VAL_Y = 0, parameter VAL_Z = 0, parameter VAL_W = 0 ) ( output var x, output var [7:0] y, output var signed [7:0] z, output var logic [7:0] w ); assign x = VAL_X; assign y = VAL_Y; assign z = VAL_Z; assign w = VAL_W; endmodule module test; logic x1; logic x2; logic [7:0] y1; logic [7:0] y2; logic signed [7:0] z1; logic signed [7:0] z2; logic [7:0] w1; logic [7:0] w2; M #( .VAL_X (1'b1), .VAL_Y (10), .VAL_Z (-1), .VAL_W (20) ) i_m1 ( .x (x1), .y (y1), .z (z1), .w (w1) ); // The type for var should default to logic, check that the value can be X M #( .VAL_X (1'bx), .VAL_Y (8'hxx), .VAL_Z (8'hxx), .VAL_W (8'hxx) ) i_m2 ( .x (x2), .y (y2), .z (z2), .w (w2) ); initial begin `check(x1, 1'b1) `check(y1, 10) `check(z1, -1) `check(w1, 20) `check(x2, 1'bx) `check(y2, 8'hxx) `check(z2, 8'hxx) `check(w2, 8'hxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_module_output2.v000066400000000000000000000025171435245347300233050ustar00rootroot00000000000000// Check that the var keyword is supported for module non-ANSI output ports bit failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module M(x, y, z, w); parameter VAL_X = 0; parameter VAL_Y = 0; parameter VAL_Z = 0; parameter VAL_W = 0; output var x; output var [7:0] y; output var signed [7:0] z; output var logic [7:0] w; assign x = VAL_X; assign y = VAL_Y; assign z = VAL_Z; assign w = VAL_W; endmodule module test; logic x1; logic x2; logic [7:0] y1; logic [7:0] y2; logic signed [7:0] z1; logic signed [7:0] z2; logic [7:0] w1; logic [7:0] w2; M #( .VAL_X (1'b1), .VAL_Y (10), .VAL_Z (-1), .VAL_W (20) ) i_m1 ( .x (x1), .y (y1), .z (z1), .w (w1) ); // The type for var should default to logic, check that the value can be X M #( .VAL_X (1'bx), .VAL_Y (8'hxx), .VAL_Z (8'hxx), .VAL_W (8'hxx) ) i_m2 ( .x (x2), .y (y2), .z (z2), .w (w2) ); initial begin `check(x1, 1'b1) `check(y1, 10) `check(z1, -1) `check(w1, 20) `check(x2, 1'bx) `check(y2, 8'hxx) `check(z2, 8'hxx) `check(w2, 8'hxx) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_package.v000066400000000000000000000016201435245347300217030ustar00rootroot00000000000000// Check that the var keyword is supported for variable declarations in packages `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end package P; var x; var [7:0] y; var signed [8:0] z; var logic [9:0] w; endpackage module test; import P::*; bit failed = 1'b0; initial begin x = 1'b1; y = 8'd10; z = -8'sd1; w = 8'd20; `check(x, 1'b1) `check(y, 10) `check(z, -1) `check(w, 20) // var should default to logic and allow x state x = 1'bx; y = 8'hxx; z = 8'hxx; w = 8'hxx; `check(x, 1'bx) `check(y, 8'hxx) `check(z, 8'hxx) `check(w, 8'hxx) `check($bits(x), 1) `check($bits(y), 8) `check($bits(z), 9) `check($bits(w), 10) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_var_task.v000066400000000000000000000013741435245347300212600ustar00rootroot00000000000000// Check that the var keyword is supported for task ports bit failed = 1'b0; `define check(val, exp) \ if (val !== exp) begin \ $display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, `"val`", val, exp); \ failed = 1'b1; \ end module test; task t1 (var int x); `check(x, 10) endtask task t2 (input var int x, output var int y); `check(x, 20) y = x; endtask task t3 (var [7:0] x); `check(x, 30) endtask task t4 (input var [7:0] x, output var [7:0] y); `check(x, 40) y = x; endtask initial begin int o1; logic [7:0] o2; t1(10); t2(20, o1); t3(30); t4(40, o2); `check(o1, 20) `check(o2, 40) if (!failed) begin $display("PASSED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast1.v000066400000000000000000000010031435245347300214670ustar00rootroot00000000000000// Check that void casts are supported module test; int a; real b; string c; function int f1(int x); a = x; return x; endfunction function real f2(real x); b = x; return x; endfunction function string f3(string x); c = x; return x; endfunction initial begin void'(f1(10)); void'(f2(1.0)); void'(f3("10")); if (a === 10 && b == 1.0 && c == "10") begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast2.v000066400000000000000000000011341435245347300214750ustar00rootroot00000000000000// Check that void casts on class methods are supported module test; int a; real b; string c; class C; function int f1(int x); a = x; return x; endfunction function real f2(real x); b = x; return x; endfunction function string f3(string x); c = x; return x; endfunction endclass C d; initial begin d = new; void'(d.f1(10)); void'(d.f2(1.0)); void'(d.f3("10")); if (a === 10 && b == 1.0 && c == "10") begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast3.v000066400000000000000000000004331435245347300214770ustar00rootroot00000000000000// Check that void casts on methods of built-in types is supported module test; int q[$]; initial begin q.push_back(1); void'(q.pop_back()); if (q.size() === 0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast4.v000066400000000000000000000002311435245347300214740ustar00rootroot00000000000000// Check that void casts on SystemFunctions is supported module test; initial begin void'($clog2(10)); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast_fail1.v000066400000000000000000000002521435245347300224670ustar00rootroot00000000000000// Check that void casting a void function results in an error module test; function void f(int x); endfunction initial begin void'(f(10)); end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast_fail2.v000066400000000000000000000002241435245347300224670ustar00rootroot00000000000000// Check that void casting a task results in an error module test; task t(int x); endtask initial begin void'(t(10)); end endmodule iverilog-12_0/ivtest/ivltests/sv_void_cast_fail3.v000066400000000000000000000001751435245347300224750ustar00rootroot00000000000000// Check that void casting an expression results in an error module test; initial begin void'(1+2); end endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import1.v000066400000000000000000000007731435245347300227140ustar00rootroot00000000000000package my_package; parameter p1 = 1; localparam p2 = p1 + 2; typedef logic [15:0] word; typedef struct packed { word v; } st; st s; event e; function word f(word g); f = g + 1; endfunction task h(word i); s.v = s.v + i; $display(s.v); endtask endpackage module test(); import my_package::*; word my_v; initial begin my_v = p1; #1 ->e; end initial begin @e s.v = my_v; h(f(1)); if (p2 === 3 && s.v === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import2.v000066400000000000000000000013651435245347300227130ustar00rootroot00000000000000package my_package; parameter p1 = 1; localparam p2 = p1 + 'bx; typedef logic [1:0] word; word v = 2'bx; event e; function word f(word g); f = g + 2'bx; endfunction task h(word i); v = v + i + 2'bx; $display(v); endtask endpackage module test(); import my_package::*; parameter p1 = 3; localparam p2 = p1 + 2; typedef logic [7:0] word; word v = 0; event e; word my_v = 0; initial begin #1 ->my_package::e; end initial begin @(my_package::e); my_v = p1; #1 ->e; end initial begin @e v = my_v; h(f(1)); if (p2 === 5 && $bits(v) === 8 && v === 5) $display("PASSED"); else $display("FAILED"); end function word f(word g); f = g + 1; endfunction task h(word i); v = v + i; $display(v); endtask endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import3.v000066400000000000000000000015561435245347300227160ustar00rootroot00000000000000package my_package; parameter p1 = 1; localparam p2 = 2; typedef logic [3:0] word; word v = 0; event e; function word f(word g); f = g + 1; endfunction task h(word i); v = v + i; $display(v); endtask endpackage module test(); parameter p1 = 'bx; localparam p2 = 'bx; typedef logic [7:0] word; word v = 8'bx; event e; word my_v = 1; initial begin #1 ->my_package::e; end initial begin @(my_package::e); #1 my_v = 8'bx; #1 ->e; end initial begin:my_block import my_package::*; // Because this is a new scope, we should use the // imported versions of p1, p2, e, v, f, and h. @e v = my_v; h(f(1)); if (p1 === 1 && p2 === 2 && $bits(v) === 4 && v === 3) $display("PASSED"); else $display("FAILED"); end function word f(word g); f = g + 8'bx; endfunction task h(word i); v = v + i + 8'bx; $display(v); endtask endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import4.v000066400000000000000000000004571435245347300227160ustar00rootroot00000000000000package my_package; parameter p1 = 1; localparam p2 = 2; typedef logic [1:0] word; word v; event e; endpackage module test(); import my_package::*; word my_v; initial begin @(e) v = p1 + p2; end parameter p1 = 3; localparam p2 = 4; typedef logic [7:0] word; word v; event e; endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import5.v000066400000000000000000000011051435245347300227060ustar00rootroot00000000000000package my_package1; parameter p1 = 1; localparam p2 = 2; typedef logic [1:0] word; word v; event e; function word f(word g); f = g + 1; endfunction task h(word i); v = v + i; $display(v); endtask endpackage package my_package2; parameter p1 = 1; localparam p2 = 2; typedef logic [1:0] word; word v; event e; function word f(word g); f = g + 1; endfunction task h(word i); v = v + i; $display(v); endtask endpackage module test(); import my_package1::*; import my_package2::*; word my_v; initial begin @(e) v = p1 + p2; h(f(1)); end endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import6.v000066400000000000000000000011161435245347300227110ustar00rootroot00000000000000package my_package1; parameter p1 = 1; localparam p2 = p1 + 2; typedef logic [15:0] word; typedef struct packed { word v; } st; endpackage package my_package2; import my_package1::*; st s; event e; function word f(word g); f = g + 1; endfunction task h(word i); s.v = s.v + i; $display(s.v); endtask endpackage module test(); import my_package1::*; import my_package2::*; word my_v; initial begin my_v = p1; #1 ->e; end initial begin @e s.v = my_v; h(f(1)); if (p2 === 3 && s.v === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/sv_wildcard_import7.v000066400000000000000000000010221435245347300227060ustar00rootroot00000000000000package my_package; parameter p1 = 1; localparam p2 = p1 + 2; typedef logic [15:0] word; typedef struct packed { word v; } st; endpackage import my_package::*; st s; event e; function word f(word g); f = g + 1; endfunction task h(word i); s.v = s.v + i; $display(s.v); endtask module test(); import my_package::*; word my_v; initial begin my_v = p1; #1 ->e; end initial begin @e s.v = my_v; h(f(1)); if (p2 === 3 && s.v === 3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/switch_primitives.v000066400000000000000000000017451435245347300225140ustar00rootroot00000000000000module switch_primitives(); wire a; wire b0; wire b1; wire m0; wire m1; wire t0; wire t1; reg in; reg en; bufif0(b0, a, en); bufif1(b1, a, en); pmos(m0, a, en); nmos(m1, a, en); tranif0(t0, a, en); tranif1(a, t1, en); assign a = in; initial begin $monitor("%b %b %b %b %b %b %b %b %v %v %v %v %v %v", en, a, b0, b1, m0, m1, t0, t1, b0, b1, m0, m1, t0, t1); #1 $display("------------------"); #1 en = 1'b0; in = 1'b0; #1 en = 1'b0; in = 1'b1; #1 en = 1'b0; in = 1'bx; #1 en = 1'b0; in = 1'bz; #1 $display("------------------"); #1 en = 1'b1; in = 1'b0; #1 en = 1'b1; in = 1'b1; #1 en = 1'b1; in = 1'bx; #1 en = 1'b1; in = 1'bz; #1 $display("------------------"); #1 en = 1'bx; in = 1'b0; #1 en = 1'bx; in = 1'b1; #1 en = 1'bx; in = 1'bx; #1 en = 1'bx; in = 1'bz; #1 $display("------------------"); #1 en = 1'bz; in = 1'b0; #1 en = 1'bz; in = 1'b1; #1 en = 1'bz; in = 1'bx; #1 en = 1'bz; in = 1'bz; end endmodule iverilog-12_0/ivtest/ivltests/swrite.v000066400000000000000000000307221435245347300202520ustar00rootroot00000000000000`timescale 1ns/1ps //`define DEBUG module top; parameter length = 34; parameter str = "%s"; reg [length*8-1:0] result, fmt; integer val = 1000; reg [31:0] eval, uval, zval; reg [63:0] hval, sval; real rval = 1234.567; wire net; time tm = 234567; realtime rtm = 2345.678; reg failed; `ifdef DEBUG integer lp; `endif assign (pull1, strong0) net = 1'b1; task check_result; input [length*8-1:0] result, value; input [80*8-1:0] message; if (result != value) begin $display("%0s", message); $display("Got :%s:", result); $display("Wanted :%s:", value); `ifdef DEBUG for (lp=0; lp", "%l in $swrite failed!"); $swrite(result, "%L"); check_result(result, "<%L>", "%L in $swrite failed!"); // %m $swrite(result, "%m"); check_result(result, "top", "%m in $swrite failed!"); $swrite(result, "%M"); check_result(result, "top", "%M in $swrite failed!"); $swrite(result, "%8m"); check_result(result, " top", "%m in $swrite failed!"); $swrite(result, "%-8m"); check_result(result, "top ", "%m in $swrite failed!"); // %s $swrite(result, "%s", "Hello"); check_result(result, "Hello", "%s in $swrite failed!"); $swrite(result, "%S", "Hello"); check_result(result, "Hello", "%S in $swrite failed!"); $swrite(result, str, "Hello"); check_result(result, "Hello", "%s in $swrite failed!"); $swrite(result, "%14s", "Hello"); check_result(result, " Hello", "%14s in $swrite failed!"); $swrite(result, "%-14s", "Hello"); check_result(result, "Hello ", "%-14s in $swrite failed!"); // %t $swrite(result, "%t", 0); check_result(result, " 0.0000 ps", "%t in $swrite failed!"); $swrite(result, "%t", 1); check_result(result, " 1000.0000 ps", "%t in $swrite failed!"); $swrite(result, "%T", 1); check_result(result, " 1000.0000 ps", "%T in $swrite failed!"); $swrite(result, "%t", 10_000); check_result(result, " 10000000.0000 ps", "%t in $swrite failed!"); $swrite(result, "%t", $time); check_result(result, " 1000.0000 ps", "%t $time in $swrite failed!"); // $swrite(result, "%t", $simtime); // check_result(result, " 1000.0000 ps", // "%t $simtime in $swrite failed!"); $swrite(result, "%-t", 1); check_result(result, "1000.0000 ps ", "%-t in $swrite failed!"); $swrite(result, "%15t", 1); check_result(result, " 1000.0000 ps", "%15t in $swrite failed!"); $swrite(result, "%-15t", 1); check_result(result, "1000.0000 ps ", "%-15t in $swrite failed!"); $swrite(result, "%15.1t", 1); check_result(result, " 1000.0 ps", "%15.1t in $swrite failed!"); // Real values. $swrite(result, "%t", 1.1); check_result(result, " 1100.0000 ps", "%t in $swrite failed!"); $swrite(result, "%t", $realtime); check_result(result, " 1000.0000 ps", "%t $realtime in $swrite failed!"); $swrite(result, "%-t", 1.1); check_result(result, "1100.0000 ps ", "%-t in $swrite failed!"); $swrite(result, "%15t", 1.1); check_result(result, " 1100.0000 ps", "%15t in $swrite failed!"); $swrite(result, "%-15t", 1.1); check_result(result, "1100.0000 ps ", "%-15t in $swrite failed!"); $swrite(result, "%15.1t", 1.1); check_result(result, " 1100.0 ps", "%15.1t in $swrite failed!"); // %u $swrite(result, "%u", eval); check_result(result, "\"", "%u in $swrite failed!"); $swrite(result, "%U", eval); check_result(result, "\"", "%U in $swrite failed!"); $swrite(result, "%u", sval); check_result(result, "Help me!", "%u in $swrite failed!"); // "Help me!" $swrite(result, "%u", hval); check_result(result, "Help me!", "%u in $swrite failed!"); // "Help" with check for correct x and z functionality. $swrite(result, "%u", uval); check_result(result, "Help", "%u in $swrite failed!"); // %v $swrite(result, "%v", net); check_result(result, "Pu1", "%v in $swrite failed!"); $swrite(result, "%V", net); check_result(result, "Pu1", "%V in $swrite failed!"); $swrite(result, "%14v", net); check_result(result, " Pu1", "%14v in $swrite failed!"); $swrite(result, "%-14v", net); check_result(result, "Pu1 ", "%-14v in $swrite failed!"); // %z $swrite(result, "%z", eval); check_result(result, "\"", "%z in $swrite failed!"); $swrite(result, "%Z", eval); check_result(result, "\"", "%Z in $swrite failed!"); // "Help me!", but because of NULLs we only get "Help" $swrite(result, "%z", hval); check_result(result, "Help", "%z in $swrite failed!"); // "Help me!" encoded using all the states! $swrite(result, "%z", zval); check_result(result, "Help me!", "%z in $swrite failed!"); // $sformat() $sformat(result, "%s", "Hello world"); check_result(result, "Hello world", "String in $sformat failed!"); $sformat(result, str, "Hello world"); check_result(result, "Hello world", "Parameter in $sformat failed!"); $sformat(result, fmt, "Hello world"); check_result(result, "Hello world", "Register in $sformat failed!"); $sformat(result, "%s"); check_result(result, "<%s>", "$sformat missing argument failed!"); $sformat(result, "%s", "Hello world", 2); check_result(result, "Hello world", "$sformat extra argument failed!"); if (!failed) $display("All tests passed."); end endmodule iverilog-12_0/ivtest/ivltests/synth_if_no_else.v000066400000000000000000000012201435245347300222530ustar00rootroot00000000000000 module test(output reg Q, input wire D, input wire OE); always @* begin Q = 0; if (OE) Q = D; end endmodule // test module main; reg D, OE; wire Q; test dut(Q, D, OE); (* ivl_synthesis_off *) initial begin OE = 0; D = 0; #1 if (Q !== 0) begin $display("FAILED -- Q=%b, D=%b, OE=%b", Q, D, OE); $finish; end D = 1; #1 if (Q !== 0) begin $display("FAILED -- Q=%b, D=%b, OE=%b", Q, D, OE); $finish; end OE = 1; #1 if (Q !== 1) begin $display("FAILED -- Q=%b, D=%b, OE=%b", Q, D, OE); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/sys_func_as_task.v000066400000000000000000000003341435245347300222670ustar00rootroot00000000000000module top; reg [79:0] str; integer val; initial begin str = "5"; $sscanf(str, "%d", val); if (val == 5) $display("PASSED"); else $display("Failed to convert string, got %d", val); end endmodule iverilog-12_0/ivtest/ivltests/sys_func_task_error.v000066400000000000000000000006031435245347300230140ustar00rootroot00000000000000module top; reg [79:0] str; integer val; initial begin // This should be a not defined in any module message. $this_icarus_call_should_not_exist; str = "5"; // This should be a system function is being called as a task error. $sscanf(str, "%d", val); // This should be a system task is being called as a function error. val = $display; end endmodule iverilog-12_0/ivtest/ivltests/sysargs.v000066400000000000000000000003341435245347300204240ustar00rootroot00000000000000module main; wire a; device U1(a); task work; begin $deposit(U1.r, 1); $display("PASSED"); $finish; end endtask initial work; endmodule module device(r); output r; reg r; endmodule iverilog-12_0/ivtest/ivltests/system.vhd000066400000000000000000000073161435245347300206000ustar00rootroot00000000000000-- This system does nothing useful -- It takes input X and this is registered internally -- It computes x+1 and x+const independently -- The output is computed as (x+const)-(x+1)=const-1 -- so the higher level modifies C and then C-1 is returned library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity Const_system is generic (C: in integer := 500); port (clk, reset: in std_logic; x: in std_logic_vector (7 downto 0); y: out std_logic_vector (10 downto 0) ); end Const_system; library ieee; use ieee.std_logic_1164.all; entity Add is generic (n: integer := 8); port (a, b: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0); cin: in std_logic ); end Add; library ieee; use ieee.std_logic_1164.all; entity Inc is generic (n: integer := 8); port (a: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0) ); end Inc; library ieee; use ieee.std_logic_1164.all; entity Reg_N is generic (n: integer := 4); port (clk, reset: in std_logic; a: in std_logic_vector (n-1 downto 0); a_reg: out std_logic_vector (n-1 downto 0) ); end Reg_N; architecture System_rtl of Const_system is -- Register component component Reg_N is generic (n: integer := 4); port (clk, reset: in std_logic; a: in std_logic_vector (n-1 downto 0); a_reg: out std_logic_vector (n-1 downto 0) ); end component; -- incrementer component component Inc is generic (n: integer := 8); port (a: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0) ); end component; -- adder component component Add is generic (n: integer := 8); port (a, b: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0); cin: in std_logic ); end component; signal x_int: std_logic_vector (7 downto 0); signal x_inc: std_logic_vector (7 downto 0); signal x_sum: std_logic_vector (10 downto 0); signal x_ext: std_logic_vector (10 downto 0); signal x_inv: std_logic_vector (10 downto 0); signal x_dif: std_logic_vector (10 downto 0); signal zero, one: std_logic; signal const: std_logic_vector (10 downto 0); begin const <= conv_std_logic_vector (C, 11); -- connstant bit 0, 1 zero <= '0'; one <= '1'; -- registering input X RegX: Reg_N generic map (n => 8) port map ( clk => clk, reset => reset, a => x, a_reg => x_int); -- Incrementing input x_int incrementer: Inc generic map (n => 8) port map (a => x_int, sum => x_inc); -- x + 1 -- forming 1's complement of x+1 x_inv <= "111" & not x_inc; x_ext <= "000" & x_int; -- adding constant to x_int addition: Add generic map (n => 11) port map (a => x_ext, b => const, cin => zero, sum => x_sum); -- x + 1000 -- this should get x+1000-(x+1) = 1000-1 = 999 subtraction: Add generic map (n => 11) port map (a => x_sum, b => x_inv, cin => one, sum => x_dif); -- registering output X RegY: Reg_N generic map (n => 11) port map ( clk => clk, reset => reset, a => x_dif, a_reg => y); end System_rtl; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; architecture Add_rtl of Add is signal cx: std_logic_vector (n downto 0); begin cx <= ('0' & a) + ('0' & b) + cin; sum <= cx (n-1 downto 0); end Add_rtl; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; architecture Inc_rtl of Inc is signal cx: std_logic_vector (n downto 0); begin cx <= ('0' & a) + '1'; sum <= cx (n-1 downto 0); end Inc_rtl; library ieee; use ieee.std_logic_1164.all; architecture Reg_rtl of Reg_N is begin My_register: process (clk, reset) begin if (reset = '1') then a_reg <= (others => '0'); elsif (clk'event and clk = '1') then a_reg <= a; end if; end process; end Reg_rtl; iverilog-12_0/ivtest/ivltests/talu.v000066400000000000000000000061101435245347300176740ustar00rootroot00000000000000/* talu - a verilog test, * illustrating problems I had in fragments of an ALU from an 8-bit micro */ module talu; reg error; reg [7:0] a; reg [7:0] b; reg cin; reg [1:0] op; wire cout; wire [7:0] aluout; alu alu_m(a, b, cin, op, aluout, cout); initial begin error = 0; // add op='b00; cin='b0; a='h0; b='h0; #2 if({cout, aluout} != 9'h000) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end // add1 op='b01; cin='b0; a='h01; b='h01; #2 if({cout, aluout} != 9'h103) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end // and op='b10; cin='b0; a='h16; b='h0F; #2 if({cout, aluout} != 9'h006) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end op='b10; cin='b0; a='h28; b='hF7; #2 if({cout, aluout} != 9'h020) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end // genbit op='b11; cin='b0; a='h00; b='h03; #2 if({cout, aluout} != 9'h008) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end op='b11; cin='b0; a='h00; b='h00; #2 if({cout, aluout} != 9'h001) begin $display($time, " FAILED %b %b %h %h %b %h", op, cin, a, b, cout, aluout); error = 1; end /* tests are incomplete - doesn't compile yet on ivl */ if(error == 0) $display("PASSED"); $finish; end endmodule /* * fragments of an ALU from an 8-bit micro */ module alu(Aval, Bval, cin, op, ALUout, cout); input [7:0] Aval; input [7:0] Bval; input cin; input [1:0] op; output cout; output [7:0] ALUout; reg cout; reg [7:0] ALUout; always @(Aval or Bval or cin or op) begin case(op) 2'b00 : {cout, ALUout} = Aval + Bval; 2'b10 : {cout, ALUout} = {1'b0, Aval & Bval}; // C++ compilation troubles with both of these: 2'b01 : {cout, ALUout} = 9'h100 ^ (Aval + Bval + 9'h001); 2'b11 : {cout, ALUout} = {1'b0, 8'b1 << Bval}; // 2'b01 : {cout, ALUout} = 9'h000; // 2'b11 : {cout, ALUout} = 9'h000; endcase end // always @ (Aval or Bval or cin or op) endmodule /* Copyright (C) 1999 Stephen G. Tell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ iverilog-12_0/ivtest/ivltests/task-scope.v000066400000000000000000000026631435245347300210110ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephan I. Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // compile time test for nested task scope elaboration `define TEST module nest(r); output [7:0] r; reg [7:0] r; task incr; input [7:0] a; begin r <= r+a; #1 $display("R=%b",r); end endtask endmodule module test; wire [7:0] acc; nest n(acc); initial n.r <= 0; `ifdef TEST task increment; begin n.incr(1); end endtask `endif initial begin `ifdef TEST #10 increment; #10 increment; #10 increment; `else #10 n.incr(3); `endif #10; if (acc==3) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/task3.14A.v000066400000000000000000000022171435245347300203040ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task w/ no I/O or internal state module main; reg globvar; task my_task ; globvar = 1'b1; endtask initial begin globvar = 1'b0; my_task; if(globvar) $display("PASSED"); else $display("FAILED - task 3.14A task didn't correctly affect global var"); end endmodule // main iverilog-12_0/ivtest/ivltests/task3.14B.v000066400000000000000000000022261435245347300203050ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task w/ simple input. module main; reg globvar; task my_task ; input in1; globvar = in1; endtask initial begin globvar = 1'b0; my_task(1'b1); if(globvar) $display("PASSED"); else $display("FAILED - task 3.14B task didn't correctly affect global var"); end endmodule // main iverilog-12_0/ivtest/ivltests/task3.14C.v000066400000000000000000000026671435245347300203170ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task w/ simple input and output module main; reg globvar; reg in1; reg error; task my_task ; input in1; output out1; out1 = in1; endtask initial begin error = 0; my_task(1'b1,globvar); if(~globvar) begin $display("FAILED - task 3.14C task didn't correctly affect global var(1)"); error = 1; end in1 = 0; my_task(!in1,globvar); if(~globvar) begin $display("FAILED - task 3.14C task didn't correctly affect global var(2)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task3.14D.v000066400000000000000000000032721435245347300203110ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task w/ multiple inputs, single output module main; reg var1,var2; reg in1; reg error; task my_task ; input in1,in2; output out1,out2; begin out1 = in1 ; out2 = in2 ; end endtask initial begin error = 0; my_task(1'b1,1'b0,var1,var2); if(~(var1 & ~var2)) begin $display("FAILED - task 3.14D task didn't return correct value (1)"); error = 1; end in1 = 0; my_task(~in1,~in1,var1,var2); if(~(var1 & var2)) begin $display("FAILED - task 3.14D task didn't return correct value(2)"); error = 1; end in1 = 0; my_task(in1,in1,var1,var2); if(~(~var1 & ~var2)) begin $display("FAILED - task 3.14D task didn't return correct value(2)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task3.14E.v000066400000000000000000000033301435245347300203050ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task calling a function module main; reg var1,var2; reg in1; reg error; function foo ; input in1 ; foo = in1 ; endfunction task my_task ; input in1,in2; output out1,out2; begin out1 = foo(~foo(in1)) ; out2 = foo(in2) ; end endtask initial begin error = 0; my_task(1'b1,1'b0,var1,var2); if(~(~var1 & ~var2)) begin $display("FAILED - task 3.14E task calling a function (1)"); error = 1; end in1 = 0; my_task(~in1,~in1,var1,var2); if(~(~var1 & var2)) begin $display("FAILED - task 3.14E task calling a function(2)"); error = 1; end in1 = 0; my_task(in1,in1,var1,var2); if(~(var1 & ~var2)) begin $display("FAILED - task 3.14E task calling a function(3)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task3.14F.v000066400000000000000000000030211435245347300203030ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate task with internal delay module main; reg var1,var2; reg in1; reg error; task my_task ; input in1; output out1; out1 = #10 in1; endtask initial begin var1 = 0; error = 0; fork my_task(1'b1,var1); begin if(var1 != 1'b0) begin $display("FAILED - task3.14F Task with internal delay(1)"); error = 1; end #20; if(var1 != 1'b1) begin $display("FAILED - task3.14F Task with internal delay(2)"); error = 1; end end join if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task_bypath.v000066400000000000000000000017601435245347300212460ustar00rootroot00000000000000/* * Copyright (c) 2001 Peter Bain * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; task foo; begin $display("PASSED"); end endtask task bar; begin test.foo; end endtask initial begin test.bar; end endmodule iverilog-12_0/ivtest/ivltests/task_in_expr_fail.v000066400000000000000000000003711435245347300224130ustar00rootroot00000000000000// Check that an error is reported when a task is used in an expression module test; task t; endtask initial begin int x; x = t() + 1; // This should fail, task can not be used in expression $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/task_init_assign.v000066400000000000000000000006541435245347300222670ustar00rootroot00000000000000module main; // The declaration assignment within a task it not allowed // in Verilog, but it is allowed in SystemVerilog. task foo (input integer x, output integer y); integer step = 3; y = x + step; endtask // foo integer a, b; initial begin a = 3; foo(a, b); if (b !== 6) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task_init_var1.v000066400000000000000000000013421435245347300216470ustar00rootroot00000000000000module test(); task accumulate1(input integer value, output integer result); static int acc = 1; acc = acc + value; result = acc; endtask task automatic accumulate2(input integer value, output integer result); int acc = 1; acc = acc + value; result = acc; endtask integer value; reg failed = 0; initial begin accumulate1(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate1(3, value); $display("%d", value); if (value !== 6) failed = 1; accumulate2(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate2(3, value); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_init_var2.v000066400000000000000000000014161435245347300216520ustar00rootroot00000000000000module static test(); task accumulate1(input integer value, output integer result); begin:blk static int acc = 1; acc = acc + value; result = acc; end endtask task automatic accumulate2(input integer value, output integer result); begin:blk int acc = 1; acc = acc + value; result = acc; end endtask integer value; initial begin static reg failed = 0; accumulate1(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate1(3, value); $display("%d", value); if (value !== 6) failed = 1; accumulate2(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate2(3, value); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_init_var3.v000066400000000000000000000013511435245347300216510ustar00rootroot00000000000000module automatic test(); task static accumulate1(input integer value, output integer result); static int acc = 1; acc = acc + value; result = acc; endtask task accumulate2(input integer value, output integer result); int acc = 1; acc = acc + value; result = acc; endtask integer value; reg failed = 0; initial begin accumulate1(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate1(3, value); $display("%d", value); if (value !== 6) failed = 1; accumulate2(2, value); $display("%d", value); if (value !== 3) failed = 1; accumulate2(3, value); $display("%d", value); if (value !== 4) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_inpad.v000066400000000000000000000025151435245347300210510ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * The assignment to the input of a task port should pad with * zeros. It seems that certain Verilog bugs can cause this test to * fail. */ module test; task writeInto; input [31:0] x; begin $display("x=%h", x); if (x[31:10] !== 22'd0) begin $display("FAILED -- x is %b", x); $finish; end end endtask reg [7:0] y; reg [31:0] y1; initial begin y1 = 512; y = 4; writeInto(y1); writeInto(y); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_iotypes.v000066400000000000000000000030051435245347300214450ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program, based on PR#150, need only compile. It is testing * the syntax of giving types to task ports. I'm careful to *not* * invoke this task because there are potential optimization gotchas * that have been known to trip up the compiler. Specifically, ports * that are unused in a task that is not called can cause crashes in * some Icarus Verilog versions */ module gen_errors; task A; input B; integer B; output C; integer C; output D; reg D; inout [31:0] E; reg [31:0] E; input [15:0] F; reg [15:0] F; begin C = B; end endtask initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_iotypes2.v000066400000000000000000000011441435245347300215310ustar00rootroot00000000000000module main; task take_args; input integer iarg; input real rarg; output integer iout; output real rout; begin iout = iarg + 1; rout = rarg + 1.0; end endtask // take_args integer ii, io; real ri, ro; initial begin ii = 4; ri = 6.0; io = 0; ro = 0.0; take_args(ii,ri,io,ro); if (io !== 5) begin $display("FAILED -- ii=%d, io=%d", ii, io); $finish; end if (ro != 7.0) begin $display("FAILED -- ri=%f, ro=%f", ri, ro); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/task_mem.v000066400000000000000000000025661435245347300205420ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests the use of memories within tasks. */ module test; parameter addrsiz = 14; parameter ramsiz = 1 << addrsiz; task loadram; integer i, j; reg [15:0] memword; reg [15:0] tempram[0:(2*ramsiz)-1]; begin for (i = 0; i < 16; i = i + 2) tempram[i] = i; for (i = 0; i < 16; i = i + 2) if (tempram[i] !== i) begin $display("FAILED -- %m.tempram[%d] = %b", i, tempram[i]); $finish; end $display("PASSED"); end endtask // loadram initial loadram; endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_atom2_fail.v000066400000000000000000000005561435245347300235230ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as an atom2 typed variable. Even // if the size of the packed dimensions matches that of the size of the atom2 // type. module test; task t; input [15:0] x; shortint x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_enum1.v000066400000000000000000000006241435245347300225270ustar00rootroot00000000000000// Check that it is possible to declare the data type for an enum type task port // separately from the direction for non-ANSI style port declarations. module test; typedef enum integer { A, B } T; task t; input x; T x; if (x == B && $bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(B); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_enum2.v000066400000000000000000000006131435245347300225260ustar00rootroot00000000000000// Check that it is possible to declare the data type for an enum type task port // before the direction for non-ANSI style port declarations. module test; typedef enum integer { A, B } T; task t; T x; input x; if (x == B && $bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(B); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_enum_fail.v000066400000000000000000000006051435245347300234400ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a enum typed variable. Even if // the size of the packed dimensions matches that of the size of the enum type. typedef enum integer { A, B } T; module test; task t; input [31:0] x; T x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail1.v000066400000000000000000000003761435245347300225020ustar00rootroot00000000000000// Check that declaring multiple task non-ANSI ports with the same name is an // error. Even if they both have an implicit type. module test; task t; input x; input x; $display("FAILED"); endtask reg y; initial t(y, y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail10.v000066400000000000000000000004661435245347300225620ustar00rootroot00000000000000// Check that declaring two non-ANSI task ports with an implicit type and the // same name is an error. Even if the signal was previously declared as an // variable. module test; task t; integer x; input x; input x; $display("FAILED"); endtask integer y; initial t(y, y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail11.v000066400000000000000000000004161435245347300225560ustar00rootroot00000000000000// Check that declaring two non-ANSI output task ports with an explicit type is // an error. Even if the types are the same. module test; task t; input integer x; input integer x; $display("FAILED"); endtask integer y; initial t(y, y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail2.v000066400000000000000000000004151435245347300224750ustar00rootroot00000000000000// Check that declaring a variable multiple times for a signal that was // previously declared as a non-ANSI task input port is an error. module test; task t; input x; reg x; reg x; $display("FAILED"); endtask reg y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail3.v000066400000000000000000000004171435245347300225000ustar00rootroot00000000000000// Check that declaring a variable multiple times for a signal that was // previously declared as a non-ANSI task output port is an error. module test; task t; output x; reg x; reg x; $display("FAILED"); endtask reg y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail4.v000066400000000000000000000005031435245347300224750ustar00rootroot00000000000000// Check that declaring an integer typed non-ANSI task port for signal that was // previously declared as a variable is an error. Even if the types for both // declarations are the same. module test; task t; integer x; input integer x; $display("FAILED"); endtask integer y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail5.v000066400000000000000000000004661435245347300225060ustar00rootroot00000000000000// Check that declaring an integer typed variabe for a signal that was // previously declared as a non-ANSI task port is an error. Even if the types // for both declarations are the same. module test; task t; input integer x; integer x; $display("FAILED"); endtask initial t(); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail6.v000066400000000000000000000004711435245347300225030ustar00rootroot00000000000000// Check that declaring a real typed variable for a signal that was previously // declared as a non-ANSI task port is an error. Even if the types for both // declarations are the same. module test; task t; output real x; real x; $display("FAILED"); endtask real y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail7.v000066400000000000000000000004671435245347300225110ustar00rootroot00000000000000// Check that declaring a real typed non-ANSI task port for signal that was // previously declared as a variable is an error. Even if the types for both // declarations are the same. module test; task t; real x; output real x; $display("FAILED"); endtask real y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail8.v000066400000000000000000000004071435245347300225040ustar00rootroot00000000000000// Check that declaring an integer typed variable for a signal that was previously // declared as a real typed non-ANSI task port is an error. module test; task t; output real x; integer x; $display("FAILED"); endtask initial t(); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_fail9.v000066400000000000000000000004161435245347300225050ustar00rootroot00000000000000// Check that declaring a non-ANSI task port with an explicit type for a signal // that was previously declared real variable is an error. module test; task t; real x; output integer x; $display("FAILED"); endtask real y; initial t(y); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_int1.v000066400000000000000000000005611435245347300223550ustar00rootroot00000000000000// Check that it is possible to declare the data type for an atom2 type task // port separately from the direction for non-ANSI style port declarations. module test; task t; input x; int x; if (x == 10 && $bits(x) == $bits(int)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_int2.v000066400000000000000000000005501435245347300223540ustar00rootroot00000000000000// Check that it is possible to declare the data type for an atom2 type task // port before the direction for non-ANSI style port declarations. module test; task t; int x; input x; if (x == 10 && $bits(x) == $bits(int)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_integer1.v000066400000000000000000000005731435245347300232230ustar00rootroot00000000000000// Check that it is possible to declare the data type for an integer type task // port separately from the direction for non-ANSI style port declarations. module test; task t; input x; integer x; if (x == 10 && $bits(x) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_integer2.v000066400000000000000000000005621435245347300232220ustar00rootroot00000000000000// Check that it is possible to declare the data type for an integer type task // port before the direction for non-ANSI style port declarations. module test; task t; integer x; input x; if (x == 10 && $bits(x) == $bits(integer)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_integer_fail.v000066400000000000000000000005611435245347300241320ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as an integer typed variable. // Even if the size of the packed dimensions matches that of the size of the // integer type. module test; task t; input [31:0] x; integer x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_parray1.v000066400000000000000000000011101435245347300230500ustar00rootroot00000000000000// Check that it is possible to declare the data type for a packed array type // task port separately from the direction for non-ANSI style port declarations. module test; typedef logic [7:0] T1; typedef T1 [3:0] T2; task t; input x; T2 x; if (x[0] == 1 && x[1] == 2 && x[2] == 3 && x[3] == 4 && $bits(x) == $bits(T2)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial begin static T2 val; val[0] = 8'h1; val[1] = 8'h2; val[2] = 8'h3; val[3] = 8'h4; t(val); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_parray2.v000066400000000000000000000010771435245347300230650ustar00rootroot00000000000000// Check that it is possible to declare the data type for a packed array type // task port before the direction for non-ANSI style port declarations. module test; typedef logic [7:0] T1; typedef T1 [3:0] T2; task t; T2 x; input x; if (x[0] == 1 && x[1] == 2 && x[2] == 3 && x[3] == 4 && $bits(x) == $bits(T2)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial begin static T2 val; val[0] = 8'h1; val[1] = 8'h2; val[2] = 8'h3; val[3] = 8'h4; t(val); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_parray_fail.v000066400000000000000000000006341435245347300237740ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a packed array typed variable. // Even if the size of the packed dimensions matches that of the size of the // packed array. typedef reg [7:0] T1; typedef T1 [3:0] T2; module test; task t; input [31:0] x; T2 x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_real1.v000066400000000000000000000005321435245347300225040ustar00rootroot00000000000000// Check that it is possible to declare the data type for a real type task port // separately from the direction for non-ANSI style port declarations. module test; task t; input x; real x; if (x == 1.23) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(1.23); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_real2.v000066400000000000000000000005211435245347300225030ustar00rootroot00000000000000// Check that it is possible to declare the data type for a real type task port // before the direction for non-ANSI style port declarations. module test; task t; real x; input x; if (x == 1.23) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(1.23); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_real_fail.v000066400000000000000000000004131435245347300234140ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a real typed variable. module test; task t; input [3:0] x; real x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_string1.v000066400000000000000000000005421435245347300230700ustar00rootroot00000000000000// Check that it is possible to declare the data type for a string type task // port separately from the direction for non-ANSI style port declarations. module test; task t; input x; string x; if (x == "TEST") begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t("TEST"); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_string2.v000066400000000000000000000005311435245347300230670ustar00rootroot00000000000000// Check that it is possible to declare the data type for a string type task // port before the direction for non-ANSI style port declarations. module test; task t; string x; input x; if (x == "TEST") begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t("TEST"); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_struct1.v000066400000000000000000000010041435245347300231000ustar00rootroot00000000000000// Check that it is possible to declare the data type for a struct type task // port separately from the direction for non-ANSI style port declarations. module test; typedef struct packed { reg [31:0] x; reg [7:0] y; } T; task t; input x; T x; if (x.x == 10 && x.y == 20 && $bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial begin static T val; val.x = 10; val.y = 20; t(val); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_struct2.v000066400000000000000000000007731435245347300231150ustar00rootroot00000000000000// Check that it is possible to declare the data type for a struct type task // port before the direction for non-ANSI style port declarations. module test; typedef struct packed { reg [31:0] x; reg [7:0] y; } T; task t; input x; T x; if (x.x == 10 && x.y == 20 && $bits(x) == $bits(T)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial begin static T val; val.x = 10; val.y = 20; t(val); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_struct_fail.v000066400000000000000000000006471435245347300240260ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a packed struct typed // variable. Even if the size of the packed dimensions matches that of the size // of the struct. typedef struct packed { reg [31:0] x; reg [7:0] y; } T; module test; task t; input [47:0] x; T x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_time1.v000066400000000000000000000005611435245347300225210ustar00rootroot00000000000000// Check that it is possible to declare the data type for a time type task port // separately from the direction for non-ANSI style port declarations. module test; task t; input x; time x; if (x == 10 && $bits(x) == $bits(time)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_time2.v000066400000000000000000000005501435245347300225200ustar00rootroot00000000000000// Check that it is possible to declare the data type for a time type task port // before the direction for non-ANSI style port declarations. module test; task t; time x; input x; if (x == 10 && $bits(x) == $bits(time)) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_time_fail.v000066400000000000000000000005441435245347300234340ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a time typed variable. Even if // the size of the packed dimensions matches that of the size of the time type. module test; task t; input [63:0] x; time x; $display("FAILED"); endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_vec1.v000066400000000000000000000005641435245347300223430ustar00rootroot00000000000000// Check that it is possible to declare the data type for a vector type task // port separately from the direction for non-ANSI style port declarations. module test; task t; input [7:0] x; reg [7:0] x; if (x == 10 && $bits(x) == 8) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_vec2.v000066400000000000000000000005531435245347300223420ustar00rootroot00000000000000// Check that it is possible to declare the data type for a vector type task // port before the direction for non-ANSI style port declarations. module test; task t; reg [7:0] x; input [7:0] x; if (x == 10 && $bits(x) == 8) begin $display("PASSED"); end else begin $display("FAILED"); end endtask initial t(10); endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_vec_fail1.v000066400000000000000000000005301435245347300233270ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a vector typed variable and // the size of the packed dimensions do not match. module test; task t; input [7:0] x; reg [3:0] x; $display("FAILED"); endtask initial begin t(10); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_vec_fail2.v000066400000000000000000000005061435245347300233330ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port without implicit // packed dimensions if it is later redeclared as a vector typed variable and // the vector type is not a scalar. module test; task t; input [7:0] x; reg x; $display("FAILED"); endtask initial begin t(10); end endmodule iverilog-12_0/ivtest/ivltests/task_nonansi_vec_fail3.v000066400000000000000000000004771435245347300233430ustar00rootroot00000000000000// Check that it is an error to declare a non-ANSI task port with implicit // packed dimensions if it is later redeclared as a vector typed variable and // the vector type is a scalar. module test; task t; input x; reg [3:0] x; $display("FAILED"); endtask initial begin t(10); end endmodule iverilog-12_0/ivtest/ivltests/task_noop.v000066400000000000000000000021321435245347300207240ustar00rootroot00000000000000/* * Copyright (c) 2000 Chris Lattner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test catches the definition of a null task. The statement is * empty, so the compiler can do some optimizations. */ module test; task mod; input [31:0] a; begin end endtask initial begin mod(5'd0); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_noop2.v000066400000000000000000000016341435245347300210140ustar00rootroot00000000000000/* * Copyright (c) 2000 Philips Semiconductors Stefan.Thiede@philips.com * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test(a); input a; task otto; ; endtask endmodule iverilog-12_0/ivtest/ivltests/task_omemw.v000066400000000000000000000023511435245347300211000ustar00rootroot00000000000000// Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // This tests tasks being able to write to output parameters that // are memory words. This is legal as val[0] is a valid l-value. module test; reg [31:0] val[1:0], tmp; task testT; output [31:0] val2; begin val2 = 1234; end endtask initial begin testT(val[0]); if (val[0] === 1234) $display("PASSED"); else $display("FAILED -- val[0] == %b"); end endmodule iverilog-12_0/ivtest/ivltests/task_omemw2.v000066400000000000000000000025321435245347300211630ustar00rootroot00000000000000// Copyright (c) 2000 Stephen Williams (steve@icarus.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // This tests tasks being able to write to output parameters that // are memory words. This is legal as val[0] is a valid l-value. // In addition, it catches binding issues. Note the common name // of the val parameter and the val memory. module test; reg [31:0] val[1:0], tmp; task testT; output [31:0] val; begin val = 1234; end endtask initial begin testT(val[0]); if (val[0] === 1234) $display("PASSED"); else $display("FAILED -- val[0] == %b",val[0]); end endmodule iverilog-12_0/ivtest/ivltests/task_omemw3.v000066400000000000000000000022071435245347300211630ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; reg [31:0] arr[1:0]; task writeInto; output [31:0] into; begin into = 1; end endtask initial begin writeInto(arr[1]); if (arr[1] !== 32'd0) begin $display("FAILED -- arr[1] = %h", arr[1]); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_port_range_mismatch.v000066400000000000000000000005101435245347300237740ustar00rootroot00000000000000// Check that range mismatches between port direction and data type are detected // for task ports. An error should be reported and no crash should occur. module test; task t; input [1:0] x; reg [3:0] x; reg [3:0] y; y = x; $display("FAILED"); endtask initial begin t(4'b1001); end endmodule iverilog-12_0/ivtest/ivltests/task_port_size.v000066400000000000000000000021571435245347300217760ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: task_port_size.v,v 1.1 2001/07/24 04:13:49 sib4 Exp $ // PR#205 module main; function f; input a; begin f = a; end endfunction reg r; initial begin r <= f(32'b 101); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/task_port_types1.v000066400000000000000000000014011435245347300222400ustar00rootroot00000000000000// Check that it is possible to use SV data types for ANSI style task ports module test; typedef logic [7:0] T1; typedef struct packed { int i; } T2; typedef enum { A } T3; task t(input reg a, input logic b, input bit c, input logic [3:0] d, input bit [3:0][3:0] e, input byte f, input int g, input T1 h, input T2 i, input T3 j, input real k, input shortreal l, input string m, input int n[], input int o[$], input x, input [3:0] y, input signed z ); $display("PASSED"); endtask initial begin t('0, '0, '0, '0, '0, '0, '0, '0, '0, A, 0.0, 0.0, "", '{0}, '{0}, '0, '0, '0); end endmodule iverilog-12_0/ivtest/ivltests/task_port_types2.v000066400000000000000000000012151435245347300222440ustar00rootroot00000000000000// Check that it is possible to use SV data types for non-ANSI style task ports module test; typedef logic [7:0] T1; typedef struct packed { int i; } T2; typedef enum { A } T3; task t; input reg a; input logic b; input bit c; input logic [3:0] d; input bit [3:0][3:0] e; input byte f; input int g; input T1 h; input T2 i; input T3 j; input real k; input shortreal l; input string m; input int n[]; input int o[$]; input x; input [3:0] y; input signed z; $display("PASSED"); endtask initial begin t('0, '0, '0, '0, '0, '0, '0, '0, '0, A, 0.0, 0.0, "", '{0}, '{0}, '0, '0, '0); end endmodule iverilog-12_0/ivtest/ivltests/task_scope.v000066400000000000000000000026651435245347300210750ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: task_scope.v,v 1.1 2001/06/19 13:52:13 ka6s Exp $ // $Log: task_scope.v,v $ // Revision 1.1 2001/06/19 13:52:13 ka6s // Added 4 tests from Stephan Boettcher // // Test for task scope lookup in VVP module test; wire w; jobs j(w); task ini; begin j.set(1'bz); end endtask initial begin ini; #1; j.set(1'b1); #1; if (w===1) $display("PASSED"); else $display("FAILED"); end endmodule // test module jobs (out); output out; reg out; task set; input val; begin #1 out = val; end endtask endmodule // jobs iverilog-12_0/ivtest/ivltests/task_scope2.v000066400000000000000000000031201435245347300211420ustar00rootroot00000000000000/* * Modified to add "endtask : " syntax. This modification tests * the SystemVerilog extension to the syntax. -- Stephen Williams */ /* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: task_scope.v,v 1.1 2001/06/19 13:52:13 ka6s Exp $ // $Log: task_scope.v,v $ // Revision 1.1 2001/06/19 13:52:13 ka6s // Added 4 tests from Stephan Boettcher // // Test for task scope lookup in VVP module test; wire w; jobs j(w); task ini; begin j.set(1'bz); end endtask : ini initial begin ini; #1; j.set(1'b1); #1; if (w===1) $display("PASSED"); else $display("FAILED"); end endmodule // test module jobs (out); output out; reg out; task set; input val; begin #1 out = val; end endtask : set endmodule // jobs iverilog-12_0/ivtest/ivltests/tern1.v000066400000000000000000000025611435245347300177660ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test catches the case where the operands of the ?: operator * have different sizes. */ module main; reg [3:0] r; reg [3:0] a; reg [4:0] b; reg f; initial begin a = 4'b1010; b = 5'b10101; f = 1; r = f? a : b; if (r !== 4'b1010) begin $display("FAILED: r === %b", r); $finish; end f = 0; r = f? a : b; if (r !== 4'b0101) begin $display("FAILED: r === %b", r); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/tern10.v000066400000000000000000000007621435245347300200470ustar00rootroot00000000000000module main; reg flag; reg [3:0] a, b; wire [4:0] Q = flag? a : b; initial begin flag = 1; a = 4'b1010; b = 4'b0101; #1 $display("%b = %b? %b : %b", Q, flag, a, b); if (Q !== 5'b01010) begin $display("FAILED -- Q=%b, flag=%b, a=%b", Q, flag, a); $finish; end flag = 0; #1 if (Q !== 5'b00101) begin $display("FAILED -- Q=%b, flag=%b, b=%b", Q, flag, b); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/tern2.v000066400000000000000000000006411435245347300177640ustar00rootroot00000000000000/* * This program doesn't do anything, and shouldn't be run. This is * only to check that the null target can see the ternary operator. */ module main2( ); reg sel; reg [13:0] out; reg [13:0] a, b; // This assign works OK // assign out[13:0] = ( sel ? a[13:0] : b[13:0] ); always @( sel or a or b ) begin out[13:0] = ( sel ? a[13:0] : b[13:0] ); end endmodule iverilog-12_0/ivtest/ivltests/tern3.v000066400000000000000000000013451435245347300177670ustar00rootroot00000000000000module test; reg [0:0] stat; initial begin stat = 1'b0; // This should display (Start). $display("(%s)", stat[0] ? "Stop" : "Start"); // This should also display (Start). It's been known // to display (tart) by getting the expression width // from the true clause. $display("(%s)", !stat[0] ? "Start" : "Stop"); $display("$bits == %0d", $bits(stat[0] ? "Stop" : "Start")); if ($bits(stat[0] ? "Stop" : "Start") !== 40) begin $display("FAILED"); $finish; end $display("$bits == %0d", $bits(stat[0] ? "Start" : "Stop")); if ($bits(stat[0] ? "Start" : "Stop") !== 40) begin $display("FAILED"); $finish; end end endmodule iverilog-12_0/ivtest/ivltests/tern4.v000066400000000000000000000005461435245347300177720ustar00rootroot00000000000000module main; reg out, c, a, b; initial begin c = 0; a = 0; b = 1; out = c ? (a & b) : b; $display("%b = %b ? (%b & %b) : %b;", out, c, a, b, b); if (out !== 1) begin $display("FAILED -- out=%b result is incorrect!", out); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/tern5.v000066400000000000000000000020571435245347300177720ustar00rootroot00000000000000/* */ module main(); reg [8:0] foo; reg [1:0] bar; initial begin foo = 2'b00 ? 9'b000111xxx : 9'b01x01x01x; $display("00: foo = %b", foo); foo = 2'b01 ? 9'b000111xxx : 9'b01x01x01x; $display("01: foo = %b", foo); foo = 2'b0x ? 9'b000111xxx : 9'b01x01x01x; $display("0x: foo = %b", foo); foo = 2'b11 ? 9'b000111xxx : 9'b01x01x01x; $display("11: foo = %b", foo); foo = 2'b1x ? 9'b000111xxx : 9'b01x01x01x; $display("1x: foo = %b", foo); bar = 2'b00; foo = bar? 9'b000111xxx : 9'b01x01x01x; $display("%b: foo = %b", bar, foo); bar = 2'b01; foo = bar? 9'b000111xxx : 9'b01x01x01x; $display("%b: foo = %b", bar, foo); bar = 2'b0x; foo = bar? 9'b000111xxx : 9'b01x01x01x; $display("%b: foo = %b", bar, foo); bar = 2'b11; foo = bar? 9'b000111xxx : 9'b01x01x01x; $display("%b: foo = %b", bar, foo); bar = 2'b1x; foo = bar? 9'b000111xxx : 9'b01x01x01x; $display("%b: foo = %b", bar, foo); end endmodule iverilog-12_0/ivtest/ivltests/tern6.v000066400000000000000000000027171435245347300177760ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program catches some glitches in the MUXZ that Icarus Verilog * uses to implement the ?: in structural cases. */ module main; reg [6:0] a, b; reg sel; wire [6:0] test = sel? a : b; wire [7:0] test2 = test; initial begin sel = 0; // At this point, test2 should be x. #1 $display("sel=%b, test2=%b", sel, test2); b = 0; #1 $display("sel=b, test2=%b", sel, test2); if (test2 !== 8'b0_0000000) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/tern7.v000066400000000000000000000032571435245347300177770ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* tern7.v * This tests types. */ module main; reg b, c, d, e; wire a = b ? c : (d&e); reg [4:0] tmp; reg ref; initial begin // Do an exaustive scan of the possible values. for (tmp = 0 ; tmp < 16 ; tmp = tmp + 1) begin b <= tmp[0]; c <= tmp[1]; d <= tmp[2]; e <= tmp[3]; ref = tmp[0] ? tmp[1] : (tmp[2]&tmp[3]); #1 if (ref !== a) begin $display("FAILED -- a=%b, b=%b, c=%b, d=%b, e=%b", a, b, c, d, e); $finish; end end // for (tmp = 0 ; tmp < 16 ; tmp = tmp + 1) b <= 0; c <= 1; d <= 1; e <= 0; #1 if (a !== 1'b0) begin $display("FAILED (1)"); $finish; end e <= 1; #1 if (a !== 1'b1) begin $display("FAILED (2)"); $finish; end $display("PASSED"); end endmodule // main `end_keywords iverilog-12_0/ivtest/ivltests/tern8.v000066400000000000000000000023201435245347300177660ustar00rootroot00000000000000/* * Copyright (c) 2005 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* tern8.v * This tests types. */ module main; reg b; real c, d; wire real a = b ? c : d; initial begin b <= 0; c <= 1.0; d <= 2.0; #1 if (a != 2.0) begin $display("FAILED (1)"); $finish; end b <= 1; #1 if (a != 1.0) begin $display("FAILED (2)"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/tern9.v000066400000000000000000000036751435245347300200050ustar00rootroot00000000000000/* tern9.v */ module main; reg flag; reg val; wire test1 = flag? val : 1'bx; wire test2 = flag? 1'b0 : 1'bx; wire test3 = flag? 1'bx : val; initial begin flag = 1; val = 0; #1 if (test1 !== 1'b0) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end if (test2 !== 1'b0) begin $display("FAILED -- flag=%b, test2=%b", flag, test2); $finish; end if (test3 !== 1'bx) begin $display("FAILED -- flag=%b, test3=%b", flag, test3); $finish; end val = 1; #1 if (test1 !== 1'b1) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end val = 1'bx; #1 if (test1 !== 1'bx) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end val = 1'bz; #1 if (test1 !== 1'bz) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end flag = 0; val = 0; #1 if (test1 !== 1'bx) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end if (test2 !== 1'bx) begin $display("FAILED -- flag=%b, test2=%b", flag, test2); $finish; end if (test3 !== 1'b0) begin $display("FAILED -- flag=%b, test3=%b", flag, test3); $finish; end val = 1; #1 if (test1 !== 1'bx) begin $display("FAILED -- flag=%b, val=%b, test1=%b", flag, val, test1); $finish; end if (test3 !== 1'b1) begin $display("FAILED -- flag=%b, test3=%b", flag, test3); $finish; end val = 1'bx; #1 if (test3 !== 1'bx) begin $display("FAILED -- flag=%b, val=%b, test3=%b", flag, val, test3); $finish; end val = 1'bz; #1 if (test3 !== 1'bz) begin $display("FAILED -- flag=%b, val=%b, test3=%b", flag, val, test3); $finish; end $display("PASSED"); $finish; end // initial begin endmodule iverilog-12_0/ivtest/ivltests/test_bufif0.v000066400000000000000000000074031435245347300211470ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_bufif0 (); wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; reg gnd, vdd, x, z; reg failed; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; bufif0 n0 ( t0, gnd, gnd); bufif0 n1 ( t1, gnd, vdd); bufif0 n2 ( t2, gnd, x); bufif0 n3 ( t3, gnd, z); bufif0 n4 ( t4, vdd, gnd); bufif0 n5 ( t5, vdd, vdd); bufif0 n6 ( t6, vdd, x); bufif0 n7 ( t7, vdd, z); bufif0 n8 ( t8, x, gnd); bufif0 n9 ( t9, x, vdd); bufif0 na ( ta, x, x); bufif0 nb ( tb, x, z); bufif0 nc ( tc, z, gnd); bufif0 nd ( td, z, vdd); bufif0 ne ( te, z, x); bufif0 nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== gnd) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:0", gnd, gnd, t0 ); end if (t1 !== z) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:z", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:StL", gnd, x, t3 ); end if (t4 !== 1'b1) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:1", vdd, gnd, t4 ); end if (t5 !== z) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:z", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:StH", vdd, x, t7 ); end if (t8 !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", x, gnd, t8 ); end if (t9 !== 1'bz) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:z", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:z", z, vdd, td ); end if (te !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", z, x, te ); end if (tf !== 1'bx) begin failed = 1; $display ("FAILED: bufif0 s:%d g:%d d:%d expected:x", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_bufif1.v000066400000000000000000000073311435245347300211500ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_bufif1 ( ); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; reg failed; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; bufif1 b0 ( t0, gnd, gnd); bufif1 b1 ( t1, gnd, vdd); bufif1 b2 ( t2, gnd, x); bufif1 b3 ( t3, gnd, z); bufif1 b4 ( t4, vdd, gnd); bufif1 b5 ( t5, vdd, vdd); bufif1 b6 ( t6, vdd, x); bufif1 b7 ( t7, vdd, z); bufif1 b8 ( t8, x, gnd); bufif1 b9 ( t9, x, vdd); bufif1 ba ( ta, x, x); bufif1 bb ( tb, x, z); bufif1 bc ( tc, z, gnd); bufif1 bd ( td, z, vdd); bufif1 be ( te, z, x); bufif1 bf ( tf, z, z); initial begin // // work around initial state assignment bug failed = 0; assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; if (t0 !== z) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:z", gnd, gnd, t0 ); end if (t1 !== 0) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:0", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:StL", gnd, z, t3 ); end if (t4 !== 1'bz) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:z", gnd, z, t4 ); end if (t5 !== 1) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:1", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:StH", vdd, z, t7 ); end if (t8 !== 1'bz) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:z", x, gnd, t8 ); end if (t9 !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:z", z, gnd, tc ); end if (td !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", z, vdd, td ); end if (te !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", z, x, te ); end if (tf !== 1'bx) begin failed = 1; $display ("FAILED: bufif1 s:%d g:%d d:%d expected:x", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_dec2to4.v000066400000000000000000000036631435245347300212440ustar00rootroot00000000000000// This module generate enable and two-bit selector for verifying a 2-to-4 decoder module stimulus #(parameter M = 8, T = 10) ( output reg [1:0] sel, output reg en ); bit [2:0] i; initial begin sel = 0; en = 1'bx; #T; sel = 1; #T; sel = 2; #T; sel = 3; #T; sel = 2'bxx; #T; en = 0; #T; en = 1; #T; en = 1'bx; #T; for (i = 0; i < M; i=i+1) begin #T; {sel, en} = i; end end endmodule // This module always checks that y complies with a decoding operation module check (input [1:0] sel, input en, input [0:3] y); always @(sel, en, y) begin if (en == 0) begin #1; if (y !== 4'b0000) begin $display("ERROR"); $finish; end else if (en == 1) begin #1; case (sel) 0: if (y !== 4'b1000) begin $display("ERROR"); $finish; end 1: if (y !== 4'b0100) begin $display("ERROR"); $finish; end 2: if (y !== 4'b0010) begin $display("ERROR"); $finish; end 3: if (y !== 4'b0001) begin $display("ERROR"); $finish; end default: if (y !== 4'b0000) begin $display("ERROR"); $finish; end endcase end // else else begin if (y !== 4'b0000) begin $display("ERROR"); $finish; end end end // if end endmodule module test; parameter M = 8; parameter T = 10; parameter S = 4*M*T + 40; wire [1:0] sel; wire en; wire [0:3] y; stimulus #(M, T) stim (.sel(sel), .en(en) ); dec2to4 duv (.sel(sel), .en(en), .y(y) ); check check (.sel(sel), .en(en), .y(y) ); initial begin #S; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_disphob.v000066400000000000000000000030711435245347300214210ustar00rootroot00000000000000// Released under GPL2.0 // (c) 2002 Tom Verbeure module main; integer myInt; reg [13:0] myReg14; reg [7:0] myReg8; reg [31:0] myReg32; initial begin $display("============================ myReg14 = 65"); myReg14 = 65; $display(">| 65|"); $display("*|",myReg14,"|"); $write("*|",myReg14,"|\n"); $display(">|0041|"); $displayh("*|",myReg14,"|"); $writeh("*|",myReg14,"|\n"); $display(">|00101|"); $displayo("*|",myReg14,"|"); $writeo("*|",myReg14,"|\n"); $display(">|00000001000001|"); $displayb("*|",myReg14,"|"); $writeb("*|",myReg14,"|\n"); $display("============================ myInt = -10"); myInt = -10; $display(">| -10|"); $display("*|",myInt,"|"); $display(">|fffffff6|"); $displayh("*|",myInt,"|"); $display(">|37777777766|"); $displayo("*|",myInt,"|"); $display(">|11111111111111111111111111110110|"); $displayb("*|",myInt,"|"); $display("============================ myReg32 = -10"); myReg32 = -10; $display(">|4294967286|"); $display("*|",myReg32,"|"); $display(">|fffffff6|"); $displayh("*|",myReg32,"|"); $display(">|37777777766|"); $displayo("*|",myReg32,"|"); $display(">|11111111111111111111111111110110|"); $displayb("*|",myReg32,"|"); $display("============================ myInt = 65"); myInt = 65; $display(">| 65|"); $display("*|",myInt,"|"); $display(">|00000041|"); $displayh("*|",myInt,"|"); $display(">|00000000101|"); $displayo("*|",myInt,"|"); $display(">|00000000000000000000000001000001|"); $displayb("*|",myInt,"|"); end endmodule iverilog-12_0/ivtest/ivltests/test_dispwided.v000066400000000000000000000023001435245347300217370ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test the display of very wide vectors in decimal. */ module test; reg signed [127:0] value; initial begin value = 1; while (value != 0) begin $display("value=%d", value); value = value << 1; end value = -1; while (value != 0) begin $display("value=%d", value); value = value << 1; end end endmodule // test iverilog-12_0/ivtest/ivltests/test_enumsystem.v000066400000000000000000000045421435245347300222060ustar00rootroot00000000000000/*************************************************************** ** Author: Oswaldo Cadenas (oswaldo.cadenas@gmail.com) ** Date: September 27 2011 ** ** Test: Intended to test the vhd code in enumsystem.vhd ** ** A stimulus modules generates a count 0,1,.., 7, 1 and an enable signal ** A scoreboard forces a check according to the operation found in enumsystem.vhd ** ** The test runs for sometime making sure relevant input conditions are met throughout **************************************************************************************/ module stim (input clk, reset, output reg [2:0] count, output reg en); always @(posedge clk) begin if (reset) count <= 3'b0; else count <= count + 1; end initial begin en = 1; repeat (100) @(posedge clk); en = 0; end endmodule module scoreboard (input [2:0] count, input reset, en, input [0:3] y); initial begin @(posedge reset); @(negedge reset); // waiting for reset to become inactive mycheck(); end task mycheck; forever begin #1; if (en == 0) begin if (y !== 4'b0000) begin $display ("ERROR"); $finish; end end else begin #2; case (count) 0: if (y !== 4'b1000) begin $display("ERROR"); $finish; end 1: if (y !== 4'b0100) begin $display("ERROR"); $finish; end 2: if (y !== 4'b0010) begin $display("ERROR"); $finish; end 3: if (y !== 4'b0001) begin $display("ERROR"); $finish; end default: if (y !== 4'b1111 && en == 1) begin $display("ERROR here, en = %d", en); $finish; end endcase end // else end // always endtask endmodule module test; parameter T = 10; parameter S = 2*10*150; bit clk = 0, reset = 0; wire en; wire [2:0] count; wire [0:3] y; initial forever #(T) clk = !clk; initial begin @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end stim stim (.clk(clk), .reset(reset), .en(en), .count(count) ); enumsystem duv (.clk(clk), .reset(reset), .en(en), .y(y) ); scoreboard check (.en(en), .reset(reset), .count(count), .y(y) ); initial begin #S; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_extended.v000066400000000000000000000051441435245347300215740ustar00rootroot00000000000000// Released under GPL2.0 // (c) 2002 Tom Verbeure module main; integer myInt; reg [39:0] myReg40; reg [0:39] myReg40r; reg [0:38] myReg39r; reg [13:0] myReg14; reg [7:0] myReg8; reg [31:0] myReg32; initial begin $display("============================ myReg8 = 65"); myReg8 = 65; $display(">| 65|"); $display("*|%d|", myReg8); $display("*|",myReg8,"|"); $display("============================ myReg14 = -10"); myReg14 = -10; $display(">|16374|"); $display("*|%d|", myReg14); $display("*|",myReg14,"|"); $display("============================ myReg14 = 65"); myReg14 = 65; $display(">1| 65|"); $display("*1|%d|", myReg14); $display(">2|65|"); $display("*2|%0d|", myReg14); $display(">3| 65|"); $display("*3|%10d|", myReg14); $display(">4| 65|"); $display("*4|%08d|", myReg14); $display("*4|%8d|", myReg14); $display(">5| 65|"); $display("*5|%03d|", myReg14); $display("*5|%3d|", myReg14); $display("============================ myReg14 = 1000"); myReg14 = 1000; $display(">|1000|"); $display("*|%03d|", myReg14); $finish(0); $display("*|",myReg14,"|"); $display(">|0041|"); $display("*|%h|", myReg14); $display(">|00000001000001|"); $display("*|%b|", myReg14); $display(">|41|"); $display("*|%0h|", myReg14); $display(">|1000001|"); $display("*|%0b|", myReg14); $display(">| A|"); $display("*|%s|", myReg14); $display(">|A|"); $display("*|%0s|", myReg14); $display("============================ myInt = -10"); myInt = -10; $display(">| -10|"); $display("*|%d|", myInt); $display("*|",myInt,"|"); $display(">|fffffff6|"); $display("*|%h|", myInt); $display("============================ myReg32 = -10"); myReg32 = -10; $display(">|4294967286|"); $display("*|%d|", myReg32); $display("*|",myReg32,"|"); $display(">|fffffff6|"); $display("*|%h|", myReg32); $display("============================ myInt = 65"); myInt = 65; $display(">| 65|"); $display("*|%d|", myInt); $display("*|",myInt,"|"); $display("*| A|"); $display(">|%s|", myInt); $display("*|A|"); $display(">|%0s|", myInt); $display("============================ myReg32 = 65"); myReg32 = 65; $display(">| 65|"); $display("*|%d|", myReg32); $display("*|",myReg32,"|"); $display("*| A|"); $display(">|%s|", myReg32); $display("*|A|"); $display(">|%0s|", myReg32); $display("*| A|"); $display(">|%s|", " A"); $display("*| A|"); $display(">|%0s|", " A"); $display("*|0|"); $display(">|%0t|", $time); $display("*| 0|"); $display(">|%t|", $time); end endmodule iverilog-12_0/ivtest/ivltests/test_forgen.v000066400000000000000000000012121435245347300212440ustar00rootroot00000000000000module main; parameter WIDTH = 8; parameter ITERATIONS = 1000; reg [WIDTH-1:0] src0, src1, ref_dst; reg clk; wire [WIDTH-1:0] dst; test #(.width(WIDTH)) test0 (.dst(dst), .src0(src0), .src1(src1), .clk(clk)); integer idx; initial begin clk = 0; for (idx = 0 ; idx < ITERATIONS ; idx = idx+1) begin src0 = $random; src1 = $random; ref_dst = src0 ^ src1; #1 clk = 1; #1 if (dst !== ref_dst) begin $display("FAILED: src0=%b, src1=%b dst=%b, ref=%b", src0, src1, dst, ref_dst); $finish; end clk = 0; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/test_gxor.v000066400000000000000000000020241435245347300207450ustar00rootroot00000000000000// This module generate M single 2*HW-1 bit vector each T time steps module stimulus #(parameter HW = 4, T = 10, M = 200) ( output reg [2*HW-1:0] a ); int i; int MAX; initial begin MAX = 1 << 2*HW; for (i = 0; i < M; i=i+1) begin a = $random % MAX ; #T; end end endmodule // This module always checks that y complies with an XOR reduction operation on 2*HW-1 bits input as x module check #(parameter HW = 4) (input [2*HW-1:0] x, input y); wire yi = ^x; always @(y, yi) begin #1; if (y !== yi) begin $display("ERROR"); $finish; end end endmodule module test; parameter M = 200; // number of test vectors parameter T = 10; // time step unit parameter HW = 4; // bit width of input vecotrs parameter S = M*T + 40; wire [2*HW-1:0] a; wire y; stimulus #(HW, T, M) stim (.a(a)); gxor_reduce #(HW) duv (.a(a), .ar(y)); check check (.x(a), .y(y) ); initial begin #S; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_inc_dec.v000066400000000000000000000176111435245347300213620ustar00rootroot00000000000000/* * Author: Oswaldo Cadenas */ module test; parameter S = 9; parameter K = 3; parameter L = 2**(S-K); parameter N = 2**(S-1); reg signed [S-1:0] a_reg; bit signed [S-1:0] a_bit; byte signed a_byte; shortint signed a_short; int signed a_int; longint signed a_long; byte signed amount; byte unsigned pos; int temp; int i; initial begin // test for style "a += some" statement on type reg for (i = 0; i < N; i = i+1) begin a_reg = $random % L; amount = $random % K; #1; temp = a_reg + amount; a_reg += amount; #1; //$display ("a = %0d, amount = %0d, temp = %0d", a, amount, temp); if (temp !== a_reg) begin $display("FAILED"); $finish; end #1; temp = a_reg - amount; a_reg -= amount; #1; if (temp !== a_reg) begin $display("FAILED"); $finish; end end // test for style "a += some" statement on type bit for (i = 0; i < N; i = i+1) begin a_bit = $random % L; amount = $random % K; #1; temp = a_bit + amount; a_bit += amount; #1; if (temp !== a_bit) begin $display("FAILED"); $finish; end #1; temp = a_bit - amount; a_bit -= amount; #1; if (temp !== a_bit) begin $display("FAILED"); $finish; end end // for // test for style "a += some" statement on type byte for (i = 0; i < N; i = i+1) begin a_byte = $random % L; amount = $random % K; #1; temp = a_byte + amount; a_byte += amount; #1; if (temp !== a_byte) begin $display("FAILED"); $finish; end #1; temp = a_byte - amount; a_byte -= amount; #1; if (temp !== a_byte) begin $display("FAILED"); $finish; end end // for // test for style "a += some" statement on type shortint for (i = 0; i < N; i = i+1) begin a_short = 2*($random % L); amount = 2*($random % K); #1; temp = a_short + amount; a_short += amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short - amount; a_short -= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short * amount; a_short *= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short / amount; a_short /= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short % amount; a_short %= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short & amount; a_short &= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short | amount; a_short |= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short ^ amount; a_short ^= amount; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; pos = 2*({$random} % K); temp = a_short << pos; a_short <<= pos; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short >> pos; a_short >>= pos; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short <<< pos; a_short <<<= pos; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end #1; temp = a_short >>> pos; a_short >>>= pos; #1; if (temp !== a_short) begin $display("FAILED"); $finish; end end // for // test for style "a += some" statement on type int for (i = 0; i < N; i = i+1) begin a_int = 4*($random % L); amount = 4*($random % K); #1; temp = a_int + amount; a_int += amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int - amount; a_int -= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int * amount; a_int *= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int / amount; a_int /= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int % amount; a_int %= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int & amount; a_int &= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int | amount; a_int |= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int ^ amount; a_int ^= amount; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; pos = 4*({$random} % K); temp = a_int << pos; a_int <<= pos; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int >> pos; a_int >>= pos; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int <<< pos; a_int <<<= pos; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end #1; temp = a_int >>> pos; a_int >>= pos; #1; if (temp !== a_int) begin $display("FAILED"); $finish; end end // for // test for style "a += some" statement on type longint for (i = 0; i < N; i = i+1) begin a_long = 8*($random % L); amount = 8*($random % K); #1; temp = a_long + amount; a_long += amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long - amount; a_long -= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long * amount; a_long *= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long / amount; a_long /= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long % amount; a_long %= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long & amount; a_long &= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long | amount; a_long |= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long ^ amount; a_long ^= amount; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; pos = 8*({$random} % K); temp = a_long << pos; a_long <<= pos; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long >> pos; a_long >>= pos; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long <<< pos; a_long <<<= pos; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end #1; temp = a_long >>> pos; a_long >>= pos; #1; if (temp !== a_long) begin $display("FAILED"); $finish; end end // for $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_mos_strength_reduction.v000066400000000000000000000074401435245347300245650ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module rpull ( i, o); input i; output o; wire gnd; wire vdd; wire pu0; wire pu1; reg failed; assign gnd = 1'b0; assign vdd = 1'b1; assign (pull0,pull1) pu0 = 1'b0; assign (pull0,pull1) pu1 = 1'b1; rnmos n0 ( o, gnd, i); rpmos p0 ( o, vdd, i); initial begin #1; failed = 0; if (i === vdd) if (o !== pu0) begin $display ("FAILED: test_mos_strength_reduction: case pull i:%d o:%d pu0:%d", i, o, pu0); failed = 1; end else if (i === gnd) if (o !== pu1) begin $display ("FAILED: test_mos_strength_reduction: case pull i:%d o:%d pu0:%d", i, o, pu0); failed = 1; end else begin $display ("FAILED: test_mos_strength_reduction: case pull i:%d o:%d pu0:%d", i, o, pu0); failed = 1; end if ( ! failed ) $display ("PASSED"); end endmodule module rweak (i, o); input i; output o; wire gnd; wire vdd; wire we0; wire we1; reg failed; assign gnd = 1'b0; assign vdd = 1'b1; assign (weak0,weak1) we0 = 1'b0; assign (weak0,weak1) we1 = 1'b1; rnmos rn0 ( n0, gnd, i); rnmos rn1 ( o, n0, i); rpmos rp1 ( o, p0, i); rpmos rp0 ( p0, vdd, i); initial begin #1; failed = 0; if (i === vdd) if (o !== we0) begin $display ("FAILED: test_mos_strength_reduction: case weak i:%d o:%d pu0:%d", i, o, we0); failed = 1; end else if (i === gnd) if (o !== we1) begin $display ("FAILED: test_mos_strength_reduction: case weak i:%d o:%d pu0:%d", i, o, we0); failed = 1; end else begin $display ("FAILED: test_mos_strength_reduction: case weak i:%d o:%d pu0:%d", i, o, we0); failed = 1; end if ( ! failed ) $display ("PASSED: test_mos_strength_reduction: case rweak"); end endmodule module test_mos_strength_reduction; /* beginning of _testbench */ reg vdd; reg gnd; reg c0,c1; reg failed; wire n0,p0; wire n1,p1; wire n2,p2; wire n3,p3; wire n4,p4; wire st1st0; wire pu1pu0; wire we1pu0; wire me1pu0; wire sm1pu0; wire o0; wire o1; assign (strong1, strong0) st1st0 = 1'b1; assign (strong1, strong0) st1st0 = 1'b0; assign (pull1, pull0) pu1pu0 = 1'b1; assign (pull1, pull0) pu1pu0 = 1'b0; assign (weak1, weak0) we1pu0 = 1'b1; assign (pull1, pull0) we1pu0 = 1'b0; rpull pu0 (vdd,o0); rweak we0 (vdd,o1); rnmos rn_0 (n1,gnd,c0); rnmos rn_1 (n2,n1,c0); rnmos rn_2 (n3,n2,c0); rnmos rn_3 (n4,n3,c0); rnmos rn_4 ( o,n4,c0); rpmos rp_0 (p0,vdd,c1); rpmos rp_1 (p1,p0,c1); rpmos rp_2 (p2,p1,c1); rpmos rp_3 (p3,p2,c1); rpmos rp_4 ( o,p3,c1); initial begin failed = 0; vdd = 1'b1; gnd = 1'b0; #1; c0 = 1'b1; c1 = 1'b1; #1; if (o !== gnd ) begin $display ("FAILED: test_mos_strength_reduction: case 0"); failed = 1; end #1; c0 = 1'b0; c1 = 1'b0; #1; if (o !== vdd ) begin $display ("FAILED: test_mos_strength_reduction: case 1"); failed = 1; end #1; c0 = 1'b1; c1 = 1'b0; #1; if (o !== 1'bx ) begin $display ("FAILED: test_mos_strength_reduction: case x"); failed = 1; end if (! failed ) $display ("PASSED: test_mos_strength_reduction"); #1; end endmodule iverilog-12_0/ivtest/ivltests/test_mux2to1.v000066400000000000000000000017501435245347300213120ustar00rootroot00000000000000// This module generate all 8 inputs for three boolean variables module stimulus #(parameter M = 8, T = 10) ( output reg i0, i1, output reg s ); bit [2:0] i; initial begin for (i = 0; i < M; i=i+1) begin #T; {i0, i1, s} = i; end #T; end endmodule // This module always checks the internal generated muxed output complies with the received one module check (input i0, i1, s, y); logic y_check; always @(i0, i1, s) y_check = s ? i1 : i0; always @(y, y_check) begin #1 if (y != y_check) begin $display("ERROR"); $finish; end end endmodule module test; parameter M = 8; parameter T = 10; parameter S = (M+1)*T + 40; wire i0, i1, s, y; stimulus #(M, T) stim (.i0(i0), .i1(i1), .s(s) ); mux2to1 duv (.i0(i0), .i1(i1), .s(s), .y(y) ); check check (.i0(i0), .i1(i1), .s(s), .y(y) ); initial begin #S; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_nmos.v000066400000000000000000000073011435245347300207450ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_nmos (); wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; reg gnd, vdd, x, z; reg failed; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; nmos n0 ( t0, gnd, gnd); nmos n1 ( t1, gnd, vdd); nmos n2 ( t2, gnd, x); nmos n3 ( t3, gnd, z); nmos n4 ( t4, vdd, gnd); nmos n5 ( t5, vdd, vdd); nmos n6 ( t6, vdd, x); nmos n7 ( t7, vdd, z); nmos n8 ( t8, x, gnd); nmos n9 ( t9, x, vdd); nmos na ( ta, x, x); nmos nb ( tb, x, z); nmos nc ( tc, z, gnd); nmos nd ( td, z, vdd); nmos ne ( te, z, x); nmos nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== z) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", gnd, gnd, t0 ); end if (t1 !== 0) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:0", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:StL", gnd, z, t3 ); end if (t4 !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", vdd, gnd, t4 ); end if (t5 !== 1) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:0", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:StH", vdd, z, t7 ); end if (t8 !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", x, gnd, t8 ); end if (t9 !== 1'bx) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:x", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", z, vdd, td ); end if (te !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", z, x, te ); end if (tf !== 1'bz) begin failed = 1; $display ("FAILED: nmos s:%d g:%d d:%v expected:z", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_notif0.v000066400000000000000000000074031435245347300211730ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_notif0 (); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; reg failed; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; notif0 n0 ( t0, gnd, gnd); notif0 n1 ( t1, gnd, vdd); notif0 n2 ( t2, gnd, x); notif0 n3 ( t3, gnd, z); notif0 n4 ( t4, vdd, gnd); notif0 n5 ( t5, vdd, vdd); notif0 n6 ( t6, vdd, x); notif0 n7 ( t7, vdd, z); notif0 n8 ( t8, x, gnd); notif0 n9 ( t9, x, vdd); notif0 na ( ta, x, x); notif0 nb ( tb, x, z); notif0 nc ( tc, z, gnd); notif0 nd ( td, z, vdd); notif0 ne ( te, z, x); notif0 nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== vdd) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:1", gnd, gnd, t0 ); end if (t1 !== z) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:z", gnd, vdd, t1 ); end if (t2 !== StH) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:StH", gnd, x, t2 ); end if (t3 !== StH) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:StH", gnd, z, t3 ); end if (t4 !== 1'b0) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:0", vdd, gnd, t4 ); end if (t5 !== z) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:z", vdd, vdd, t5 ); end if (t6 !== StL) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:Stl", vdd, x, t6 ); end if (t7 !== StL) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:Stl", vdd, z, t7 ); end if (t8 !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", x, gnd, t8 ); end if (t9 !== 1'bz) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:z", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:z", z, vdd, td ); end if (te !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", z, x, te ); end if (tf !== 1'bx) begin failed = 1; $display ("FAILED: notif0 s:%d g:%d d:%d expected:x", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_notif1.v000066400000000000000000000073341435245347300211770ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_notif1 ( ); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; reg failed; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; notif1 b0 ( t0, gnd, gnd); notif1 b1 ( t1, gnd, vdd); notif1 b2 ( t2, gnd, x); notif1 b3 ( t3, gnd, z); notif1 b4 ( t4, vdd, gnd); notif1 b5 ( t5, vdd, vdd); notif1 b6 ( t6, vdd, x); notif1 b7 ( t7, vdd, z); notif1 b8 ( t8, x, gnd); notif1 b9 ( t9, x, vdd); notif1 ba ( ta, x, x); notif1 bb ( tb, x, z); notif1 bc ( tc, z, gnd); notif1 bd ( td, z, vdd); notif1 be ( te, z, x); notif1 bf ( tf, z, z); initial begin // // work around initial state assignment bug failed = 0; assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; if (t0 !== z) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:z", gnd, gnd, t0 ); end if (t1 !== 1) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:1", gnd, vdd, t1 ); end if (t2 !== StH) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:StH", gnd, x, t2 ); end if (t3 !== StH) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:StH", gnd, z, t3 ); end if (t4 !== 1'bz) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:z", vdd, gnd, t4 ); end if (t5 !== 0) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:0", vdd, vdd, t5 ); end if (t6 !== StL) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:StL", vdd, x, t6 ); end if (t7 !== StL) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:StL", vdd, z, t7 ); end if (t8 !== 1'bz) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:z", x, gnd, t8 ); end if (t9 !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:z", z, gnd, tc ); end if (td !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", z, vdd, td ); end if (te !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", z, x, te ); end if (tf !== 1'bx) begin failed = 1; $display ("FAILED: notif1 s:%d g:%d d:%d expected:x", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_pmos.v000066400000000000000000000073011435245347300207470ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_pmos (); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; reg failed; pmos n0 ( t0, gnd, gnd); pmos n1 ( t1, gnd, vdd); pmos n2 ( t2, gnd, x); pmos n3 ( t3, gnd, z); pmos n4 ( t4, vdd, gnd); pmos n5 ( t5, vdd, vdd); pmos n6 ( t6, vdd, x); pmos n7 ( t7, vdd, z); pmos n8 ( t8, x, gnd); pmos n9 ( t9, x, vdd); pmos na ( ta, x, x); pmos nb ( tb, x, z); pmos nc ( tc, z, gnd); pmos nd ( td, z, vdd); pmos ne ( te, z, x); pmos nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== gnd) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:0", gnd, gnd, t0 ); end if (t1 !== z) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:StL", gnd, z, t3 ); end if (t4 !== 1'b1) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:1", vdd, gnd, t4 ); end if (t5 !== z) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:StH", vdd, z, t7 ); end if (t8 !== 1'bx) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:x", x, gnd, t8 ); end if (t9 !== 1'bz) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", z, vdd, td ); end if (te !== 1'bz) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", z, x, te ); end if (tf !== 1'bz) begin failed = 1; $display ("FAILED: pmos s:%d g:%d d:%d expected:z", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_rnmos.v000066400000000000000000000073401435245347300211320ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_rnmos (); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; reg failed; rnmos n0 ( t0, gnd, gnd); rnmos n1 ( t1, gnd, vdd); rnmos n2 ( t2, gnd, x); rnmos n3 ( t3, gnd, z); rnmos n4 ( t4, vdd, gnd); rnmos n5 ( t5, vdd, vdd); rnmos n6 ( t6, vdd, x); rnmos n7 ( t7, vdd, z); rnmos n8 ( t8, x, gnd); rnmos n9 ( t9, x, vdd); rnmos na ( ta, x, x); rnmos nb ( tb, x, z); rnmos nc ( tc, z, gnd); rnmos nd ( td, z, vdd); rnmos ne ( te, z, x); rnmos nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== z) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", gnd, gnd, t0 ); end if (t1 !== 0) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:0", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:StL", gnd, z, t3 ); end if (t4 !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", vdd, gnd, t4 ); end if (t5 !== 1) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:0", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:StH", vdd, z, t7 ); end if (t8 !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", x, gnd, t8 ); end if (t9 !== 1'bx) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:x", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", z, vdd, td ); end if (te !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", z, x, te ); end if (tf !== 1'bz) begin failed = 1; $display ("FAILED: rnmos s:%d g:%d d:%d expected:z", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_rpmos.v000066400000000000000000000073421435245347300211360ustar00rootroot00000000000000/* * Copyright (c) 2000 Intrinsity, Inc. * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test_rpmos (); reg gnd, vdd, x, z; wire t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, ta, tb, tc, td, te, tf; wire StH, StL; assign (strong1, highz0) StH = 1'bx; assign (highz1, strong0) StL = 1'bx; reg failed; rpmos n0 ( t0, gnd, gnd); rpmos n1 ( t1, gnd, vdd); rpmos n2 ( t2, gnd, x); rpmos n3 ( t3, gnd, z); rpmos n4 ( t4, vdd, gnd); rpmos n5 ( t5, vdd, vdd); rpmos n6 ( t6, vdd, x); rpmos n7 ( t7, vdd, z); rpmos n8 ( t8, x, gnd); rpmos n9 ( t9, x, vdd); rpmos na ( ta, x, x); rpmos nb ( tb, x, z); rpmos nc ( tc, z, gnd); rpmos nd ( td, z, vdd); rpmos ne ( te, z, x); rpmos nf ( tf, z, z); initial begin assign gnd = 1'b1; assign vdd = 1'b0; assign x = 1'b0; assign z = 1'b0; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'b1; assign z = 1'b1; #10; assign gnd = 1'b0; assign vdd = 1'b1; assign x = 1'bx; assign z = 1'bz; #10; failed = 0; if (t0 !== gnd) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:0", gnd, gnd, t0 ); end if (t1 !== z) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", gnd, vdd, t1 ); end if (t2 !== StL) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:StL", gnd, x, t2 ); end if (t3 !== StL) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:StL", gnd, z, t3 ); end if (t4 !== 1'b1) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:1", vdd, gnd, t4 ); end if (t5 !== z) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", vdd, vdd, t5 ); end if (t6 !== StH) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:StH", vdd, x, t6 ); end if (t7 !== StH) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:StH", vdd, z, t7 ); end if (t8 !== 1'bx) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:x", x, gnd, t8 ); end if (t9 !== 1'bz) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", x, vdd, t9 ); end if (ta !== 1'bx) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:x", x, x, ta ); end if (tb !== 1'bx) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:x", x, z, tb ); end if (tc !== 1'bz) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", z, gnd, tc ); end if (td !== 1'bz) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", z, vdd, td ); end if (te !== 1'bz) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", z, x, te ); end if (tf !== 1'bz) begin failed = 1; $display ("FAILED: rpmos s:%d g:%d d:%d expected:z", z, z, tf ); end if (failed == 0) $display ("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/test_signal_init_assign.v000066400000000000000000000023351435245347300236370ustar00rootroot00000000000000module main; reg src; reg clk; wire dst0, dst1; test #(.parm(0)) test0 (.dst(dst0), .src(src), .clk(clk)); test #(.parm(1)) test1 (.dst(dst1), .src(src), .clk(clk)); //Note: For Modelsim compatibility do instantiation as: //test #(.parm(2'b10)) test0 (.dst(dst0), .src(src), .clk(clk)); //test #(.parm(2'b11)) test1 (.dst(dst1), .src(src), .clk(clk)); //The reason is that Modelsim handles single-bit std_logic as an //enumeration, and enumeration values 2 and 3 correspond to the //stdlogic '0' and '1' values. The integer to std_logic values //in modelsim are: // 0 - 'U' // 1 - 'X' // 2 - '0' // 3 - '1' // 4 - 'Z' // 5 - 'W' // 6 - 'L' // 7 - 'H' // 8 - '-' //Maybe in the future we'll have to do something similar? initial begin clk = 0; src = 0; #1 clk = 1; #1 if (dst0 !== 1'b0 || dst1 !== 1'b1) begin $display("FAILED: src=%b, dst0=%b dst1=%b", src, dst0, dst1); $finish; end clk = 0; src = 1; #1 clk = 1; #1 if (dst0 !== 1'b1 || dst1 !== 1'b0) begin $display("FAILED: src=%b, dst0=%b dst1=%b", src, dst0, dst1); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/test_system.v000066400000000000000000000023361435245347300213200ustar00rootroot00000000000000/*************************************************************** ** Author: Oswaldo Cadenas (oswaldo.cadenas@gmail.com) ** Date: September 26 2011 ** ** Test: Intended to test a system composed of some parametric system ** that has an adder, a register and an incrementer ** Each module has parameter: N for data length ** ** A system is given parameter P and should return P-1, this is run for M test vectors **************************************************************************************/ module test; parameter integer T = 25; // for the clock period parameter integer P = 1000; // a constant passed to the system under test parameter integer M = 200; // number of test vectors int i; bit clk = 0, reset = 0; byte unsigned x; wire [10:0] y; initial forever #(T) clk = !clk; initial begin @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end initial begin @(posedge reset); @(negedge reset); for (i = 0; i < M; i=i+1) begin x = {$random} % 255; @(negedge clk); if (y !== P-1) begin $display ("ERROR"); $finish; end end #100; $display ("PASSED"); $finish; end const_system #(P) duv (.clk(clk), .reset(reset), .x(x), .y(y) ); endmodule iverilog-12_0/ivtest/ivltests/test_timebase.v000066400000000000000000000051301435245347300215600ustar00rootroot00000000000000/*************************************************************** ** Author: Oswaldo Cadenas (oswaldo.cadenas@gmail.com) ** Date: September 26 2011 ** ** Test: Intended to test parametric counter in timebase.vhd ** the counter has parameters: N for counter length and VALUE to flag when the count reaches this value ** ** Four counter instances are created here: ** duv1 with counter default parameters for N and VALUE ** duv2 with N1, V1 for parameter N, VALUE respectively ** duv3 with N2, V2 for parameters N, VALUE respectively ** duv4 with N2 replacing N and VALUE left as default ** ** The test for a long time making sure each of the four counter flags TICK become one **************************************************************************************/ module test; parameter integer T = 25; parameter integer N1 = 8; parameter integer N2 = 17; parameter integer V1 = 200; parameter integer V2 = 17'h16C8A; bit clk = 0, reset = 0; wire [11:0] count1; wire [N1-1:0] count2; wire [N2-1:0] count3; wire [N2-1:0] count4; wire tick1, tick2, tick3, tick4; reg tick1_reg, tick2_reg, tick3_reg, tick4_reg; initial forever #(T) clk = !clk; initial begin @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end // duv1 switch always @(posedge clk, posedge reset) if (reset) tick1_reg <= 1'b0; else if (tick1) tick1_reg <= 1'b1; // duv2 switch always @(posedge clk, posedge reset) if (reset) tick2_reg <= 1'b0; else if (tick2) tick2_reg <= 1'b1; // duv3 switch always @(posedge clk, posedge reset) if (reset) tick3_reg <= 1'b0; else if (tick3) tick3_reg <= 1'b1; // duv4 switch always @(posedge clk, posedge reset) if (reset) tick4_reg <= 1'b0; else if (tick4) tick4_reg <= 1'b1; initial begin #(V2*2*T + 1000); if (tick1_reg != 1 || tick2_reg != 1 || tick3_reg != 1 || tick4_reg != 1) begin $display ("Counting FAILED"); $finish; end else begin $display ("PASSED"); #20; $finish; end end timebase duv1 (.clock(clk), .reset(reset), .enable(1'b1), .tick(tick1), .count_value(count1) ); // default parameters timebase #(.n(N1), .value(V1)) duv2 (.clock(clk), .reset(reset), .enable(1'b1), .tick(tick2), .count_value(count2) ); // N1, V1 parameters timebase #(N2, V2) duv3 (.clock(clk), .reset(reset), .enable(1'b1), .tick(tick3), .count_value(count3) ); // N2, V2 parameters timebase #(.n(N2)) duv4 (.clock(clk), .reset(reset), .enable(1'b1), .tick(tick4), .count_value(count4) ); // only one parameter modified endmodule iverilog-12_0/ivtest/ivltests/test_tliteral.v000066400000000000000000000034151435245347300216130ustar00rootroot00000000000000timeunit 1ns; timeprecision 10ps; module test; parameter factor = 1e-9/10e-12; longint tmanual, tnow, tdiff; longint incr; initial begin tmanual = 0; if ($realtime != 0) begin $display ("FAILED"); $finish; end #33.1ns; incr = 33.1e-9/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #78.1ps; incr = 78.1e-12/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #123.08ns; incr = 123.08e-9/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #9.006ns; incr = 9.006e-9/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #17.003ns; incr = 17.003e-9/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #578.23us; incr = 578.23e-6/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #0.0356ms; incr = 0.0356e-3/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end #1.011s; incr = 1.011e0/10e-12; tmanual = tmanual + incr; tnow = $realtime*factor; tdiff = tnow-tmanual; if (tdiff != 0) begin $display ("FAILED"); $finish; end $display("PASSED"); //$display ("Time now is: %t, manual = %0d, tnow = %0d, diff = %0d ", $realtime, tmanual, tnow, tdiff); $finish; end endmodule iverilog-12_0/ivtest/ivltests/test_va_math.v000066400000000000000000000566401435245347300214220ustar00rootroot00000000000000/* * Verilog-A math library test code for Icarus Verilog. * http://www.icarus.com/eda/verilog/ * * Copyright (C) 2007-2009 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. */ /* * As of Dec. 2009 some systems have started returning the sign of * a NaN, because of this we can for some conditions get -nan. This * will cause mismatches with the gold file. Alan M. Feldstein * suggested on the iverilog-devel mailing list that we use fabs * ($abs()) since C99 speifies that it will remove the sign of the * NaN. This appears to work, so I wrapped all functions that we * expect to return NaN with a call to $abs(). */ // Get the Verilog-A constants. `include "constants.vams" module top; real zero, mzero, inf, minf, nan; initial begin // Define a few constants. zero = 0.0; mzero = -1.0 * zero; inf = 1/0.0; minf = $ln(0); nan = $abs($sqrt(-1.0)); $display("Using +0 = %f, -0 = %f, nan = %f, inf = %f and -inf = %f.\n", zero, mzero, nan, inf, minf); // Check that the comparisons used to detection a NaN work correctly. if (nan != nan) $display("NaN != comparison works correctly."); else $display("NaN != comparison failed."); if (nan == nan) $display("NaN == comparison failed.\n"); else $display("NaN == comparison works correctly.\n"); check_sqrt; $display(""); check_ln; $display(""); check_log; $display(""); check_exp; $display(""); check_abs; $display(""); check_ceil; $display(""); check_floor; $display(""); check_sin; $display(""); check_cos; $display(""); check_tan; $display(""); check_asin; $display(""); check_acos; $display(""); check_atan; $display(""); check_sinh; $display(""); check_cosh; $display(""); check_tanh; $display(""); check_asinh; $display(""); check_acosh; $display(""); check_atanh; $display(""); check_min; $display(""); check_max; $display(""); check_pow; $display(""); check_atan2; $display(""); check_hypot; $display(""); check_constants; end // Task to check the square root function. task check_sqrt; begin $display("--- Checking the $sqrt function ---"); $display("The square root of 2.0 is %f.", $sqrt(2.0)); $display("The square root of 1.0 is %f.", $sqrt(1.0)); $display("The square root of 0.0 is %f.", $sqrt(zero)); $display("The square root of -0.0 is %f.", $sqrt(mzero)); $display("The square root of -1.0 is %f.", $abs($sqrt(-1.0))); $display("The square root of inf is %f.", $sqrt(inf)); $display("The square root of -inf is %f.", $abs($sqrt(minf))); $display("The square root of nan is %f.", $abs($sqrt(nan))); end endtask // Task to check the natural log function. task check_ln; begin $display("--- Checking the $ln function ---"); $display("The natural log of 10.0 is %f.", $ln(10.0)); $display("The natural log of 1.0 is %f.", $ln(1.0)); $display("The natural log of 0.5 is %f.", $ln(0.5)); $display("The natural log of 0.0 is %f.", $ln(zero)); $display("The natural log of -0.0 is %f.", $ln(mzero)); $display("The natural log of -1.0 is %f.", $abs($ln(-1.0))); $display("The natural log of inf is %f.", $ln(inf)); $display("The natural log of -inf is %f.", $abs($ln(minf))); $display("The natural log of nan is %f.", $abs($ln(nan))); end endtask // Task to check the log base 10 function. // This was originally $log, but that was deprecated in VAMS-2.3. task check_log; begin $display("--- Checking the $log10 function ---"); $display("The log base 10 of 10.0 is %f.", $log10(10.0)); $display("The log base 10 of 1.0 is %f.", $log10(1.0)); $display("The log base 10 of 0.5 is %f.", $log10(0.5)); $display("The log base 10 of 0.0 is %f.", $log10(zero)); $display("The log base 10 of -0.0 is %f.", $log10(mzero)); $display("The log base 10 of -1.0 is %f.", $abs($log10(-1.0))); $display("The log base 10 of inf is %f.", $log10(inf)); $display("The log base 10 of -inf is %f.", $abs($log10(minf))); $display("The log base 10 of nan is %f.", $abs($log10(nan))); end endtask // Task to check the exponential function. task check_exp; begin $display("--- Checking the $exp function ---"); $display("The exponential of 1.0 is %f.", $exp(1.0)); $display("The exponential of 0.0 is %f.", $exp(zero)); $display("The exponential of -0.0 is %f.", $exp(mzero)); $display("The exponential of -1.0 is %f.", $exp(-1.0)); $display("The exponential of inf is %f.", $exp(inf)); $display("The exponential of -inf is %f.", $exp(minf)); $display("The exponential of nan is %f.", $abs($exp(nan))); end endtask // Task to check the absolute value function. task check_abs; begin $display("--- Checking the $abs function ---"); $display("The absolute value of 1.0 is %f.", $abs(1.0)); $display("The absolute value of 0.0 is %f.", $abs(zero)); $display("The absolute value of -0.0 is %f.", $abs(mzero)); $display("The absolute value of -1.0 is %f.", $abs(-1.0)); $display("The absolute value of inf is %f.", $abs(inf)); $display("The absolute value of -inf is %f.", $abs(minf)); $display("The absolute value of nan is %f.", $abs(nan)); end endtask // Task to check the ceiling function. task check_ceil; begin $display("--- Checking the $ceil function ---"); $display("The ceiling of 2.1 is %f.", $ceil(2.1)); $display("The ceiling of 0.5 is %f.", $ceil(0.5)); // Some C math libraries return -0.0 and some return 0.0. // Both appear to be correct since the standard does not // specify exactly what should be done so convert to 0.0. $display("The ceiling of -0.5 is %f.", $ceil(-0.5)+0.0); $display("The ceiling of -1.1 is %f.", $ceil(-1.1)); $display("The ceiling of inf is %f.", $ceil(inf)); $display("The ceiling of -inf is %f.", $ceil(minf)); $display("The ceiling of nan is %f.", $abs($ceil(nan))); end endtask // Task to check the floor function. task check_floor; begin $display("--- Checking the $floor function ---"); $display("The floor of 2.1 is %f.", $floor(2.1)); $display("The floor of 0.5 is %f.", $floor(0.5)); $display("The floor of -0.5 is %f.", $floor(-0.5)); $display("The floor of -1.1 is %f.", $floor(-1.1)); $display("The floor of inf is %f.", $floor(inf)); $display("The floor of -inf is %f.", $floor(minf)); $display("The floor of nan is %f.", $abs($floor(nan))); end endtask // Task to check the sin function. task check_sin; begin $display("--- Checking the $sin function ---"); $display("The sin of 4.0 is %f.", $sin(4.0)); $display("The sin of 1.0 is %f.", $sin(1.0)); $display("The sin of 0.0 is %f.", $sin(zero)); $display("The sin of -0.0 is %f.", $sin(mzero)); $display("The sin of -1.0 is %f.", $sin(-1.0)); $display("The sin of -4.0 is %f.", $sin(-4.0)); $display("The sin of inf is %f.", $abs($sin(inf))); $display("The sin of -inf is %f.", $abs($sin(minf))); $display("The sin of nan is %f.", $abs($sin(nan))); end endtask // Task to check the cos function. task check_cos; begin $display("--- Checking the $cos function ---"); $display("The cos of 4.0 is %f.", $cos(4.0)); $display("The cos of 1.0 is %f.", $cos(1.0)); $display("The cos of 0.0 is %f.", $cos(zero)); $display("The cos of -0.0 is %f.", $cos(mzero)); $display("The cos of -1.0 is %f.", $cos(-1.0)); $display("The cos of -4.0 is %f.", $cos(-4.0)); $display("The cos of inf is %f.", $abs($cos(inf))); $display("The cos of -inf is %f.", $abs($cos(minf))); $display("The cos of nan is %f.", $abs($cos(nan))); end endtask // Task to check the tan function. task check_tan; begin $display("--- Checking the $tan function ---"); $display("The tan of 4.0 is %f.", $tan(4.0)); $display("The tan of 1.0 is %f.", $tan(1.0)); $display("The tan of 0.0 is %f.", $tan(zero)); $display("The tan of -0.0 is %f.", $tan(mzero)); $display("The tan of -1.0 is %f.", $tan(-1.0)); $display("The tan of -4.0 is %f.", $tan(-4.0)); // The underlying C math libraries can give different results for // this corner case, so we can only use four significant digits // for these two tests. $display("The tan of pi/2 is %.4g.", $tan($asin(1.0))); $display("The tan of -pi/2 is %.4g.", $tan($asin(-1.0))); $display("The tan of inf is %f.", $abs($tan(inf))); $display("The tan of -inf is %f.", $abs($tan(minf))); $display("The tan of nan is %f.", $abs($tan(nan))); end endtask // Task to check the asin function. task check_asin; begin $display("--- Checking the $asin function ---"); $display("The asin of 1.1 is %f.", $abs($asin(1.1))); $display("The asin of 1.0 is %f.", $asin(1.0)); $display("The asin of 0.5 is %f.", $asin(0.5)); $display("The asin of 0.0 is %f.", $asin(zero)); $display("The asin of -0.0 is %f.", $asin(mzero)); $display("The asin of -0.5 is %f.", $asin(-0.5)); $display("The asin of -1.0 is %f.", $asin(-1.0)); $display("The asin of -1.1 is %f.", $abs($asin(-1.1))); $display("The asin of inf is %f.", $abs($asin(inf))); $display("The asin of -inf is %f.", $abs($asin(minf))); $display("The asin of nan is %f.", $abs($asin(nan))); end endtask // Task to check the acos function. task check_acos; begin $display("--- Checking the $acos function ---"); $display("The acos of 1.1 is %f.", $abs($acos(1.1))); $display("The acos of 1.0 is %f.", $acos(1.0)); $display("The acos of 0.5 is %f.", $acos(0.5)); $display("The acos of 0.0 is %f.", $acos(zero)); $display("The acos of -0.0 is %f.", $acos(mzero)); $display("The acos of -0.5 is %f.", $acos(-0.5)); $display("The acos of -1.0 is %f.", $acos(-1.0)); $display("The acos of -1.1 is %f.", $abs($acos(-1.1))); $display("The acos of inf is %f.", $abs($acos(inf))); $display("The acos of -inf is %f.", $abs($acos(minf))); $display("The acos of nan is %f.", $abs($acos(nan))); end endtask // Task to check the atan function. task check_atan; begin $display("--- Checking the $atan function ---"); $display("The atan of 2.0 is %f.", $atan(2.0)); $display("The atan of 0.5 is %f.", $atan(0.5)); $display("The atan of 0.0 is %f.", $atan(zero)); $display("The atan of -0.0 is %f.", $atan(mzero)); $display("The atan of -0.5 is %f.", $atan(-0.5)); $display("The atan of -2.0 is %f.", $atan(-2.0)); $display("The atan of inf is %f.", $atan(inf)); $display("The atan of -inf is %f.", $atan(minf)); $display("The atan of nan is %f.", $abs($atan(nan))); end endtask // Task to check the sinh function. task check_sinh; begin $display("--- Checking the $sinh function ---"); $display("The sinh of 2.0 is %f.", $sinh(2.0)); $display("The sinh of 1.0 is %f.", $sinh(1.0)); $display("The sinh of 0.5 is %f.", $sinh(0.5)); $display("The sinh of 0.0 is %f.", $sinh(zero)); $display("The sinh of -0.0 is %f.", $sinh(mzero)); $display("The sinh of -0.5 is %f.", $sinh(-0.5)); $display("The sinh of -1.0 is %f.", $sinh(-1.0)); $display("The sinh of -2.0 is %f.", $sinh(-2.0)); $display("The sinh of inf is %f.", $sinh(inf)); $display("The sinh of -inf is %f.", $sinh(minf)); $display("The sinh of nan is %f.", $abs($sinh(nan))); end endtask // Task to check the cosh function. task check_cosh; begin $display("--- Checking the $cosh function ---"); $display("The cosh of 2.0 is %f.", $cosh(2.0)); $display("The cosh of 1.0 is %f.", $cosh(1.0)); $display("The cosh of 0.5 is %f.", $cosh(0.5)); $display("The cosh of 0.0 is %f.", $cosh(zero)); $display("The cosh of -0.0 is %f.", $cosh(mzero)); $display("The cosh of -0.5 is %f.", $cosh(-0.5)); $display("The cosh of -1.0 is %f.", $cosh(-1.0)); $display("The cosh of -2.0 is %f.", $cosh(-2.0)); $display("The cosh of inf is %f.", $cosh(inf)); $display("The cosh of -inf is %f.", $cosh(minf)); $display("The cosh of nan is %f.", $abs($cosh(nan))); end endtask // Task to check the tanh function. task check_tanh; begin $display("--- Checking the $tanh function ---"); $display("The tanh of 2.0 is %f.", $tanh(2.0)); $display("The tanh of 1.0 is %f.", $tanh(1.0)); $display("The tanh of 0.5 is %f.", $tanh(0.5)); $display("The tanh of 0.0 is %f.", $tanh(zero)); $display("The tanh of -0.0 is %f.", $tanh(mzero)); $display("The tanh of -0.5 is %f.", $tanh(-0.5)); $display("The tanh of -1.0 is %f.", $tanh(-1.0)); $display("The tanh of -2.0 is %f.", $tanh(-2.0)); $display("The tanh of inf is %f.", $tanh(inf)); $display("The tanh of -inf is %f.", $tanh(minf)); $display("The tanh of nan is %f.", $abs($tanh(nan))); end endtask // Task to check the asinh function. task check_asinh; begin $display("--- Checking the $asinh function ---"); $display("The asinh of 2.0 is %f.", $asinh(2.0)); $display("The asinh of 1.0 is %f.", $asinh(1.0)); $display("The asinh of 0.5 is %f.", $asinh(0.5)); $display("The asinh of 0.0 is %f.", $asinh(zero)); $display("The asinh of -0.0 is %f.", $asinh(mzero)); $display("The asinh of -0.5 is %f.", $asinh(-0.5)); $display("The asinh of -1.0 is %f.", $asinh(-1.0)); $display("The asinh of -2.0 is %f.", $asinh(-2.0)); $display("The asinh of inf is %f.", $asinh(inf)); $display("The asinh of -inf is %f.", $asinh(minf)); $display("The asinh of nan is %f.", $abs($asinh(nan))); end endtask // Task to check the acosh function. task check_acosh; begin $display("--- Checking the $acosh function ---"); $display("The acosh of 2.0 is %f.", $acosh(2.0)); $display("The acosh of 1.0 is %f.", $acosh(1.0)); $display("The acosh of 0.5 is %f.", $abs($acosh(0.5))); $display("The acosh of 0 is %f.", $abs($acosh(zero))); $display("The acosh of -0 is %f.", $abs($acosh(mzero))); $display("The acosh of -0.5 is %f.", $abs($acosh(-0.5))); $display("The acosh of -1.0 is %f.", $abs($acosh(-1.0))); $display("The acosh of -2.0 is %f.", $abs($acosh(-2.0))); $display("The acosh of inf is %f.", $acosh(inf)); $display("The acosh of -inf is %f.", $abs($acosh(minf))); $display("The acosh of nan is %f.", $abs($acosh(nan))); end endtask // Task to check the atanh function. task check_atanh; begin $display("--- Checking the $atanh function ---"); $display("The atanh of 2.0 is %f.", $abs($atanh(2.0))); $display("The atanh of 1.0 is %f.", $atanh(1.0)); $display("The atanh of 0.5 is %f.", $atanh(0.5)); $display("The atanh of 0.0 is %f.", $atanh(zero)); $display("The atanh of -0.0 is %f.", $atanh(mzero)); $display("The atanh of -0.5 is %f.", $atanh(-0.5)); $display("The atanh of -1.0 is %f.", $atanh(-1.0)); $display("The atanh of -2.0 is %f.", $abs($atanh(-2.0))); $display("The atanh of inf is %f.", $abs($atanh(inf))); $display("The atanh of -inf is %f.", $abs($atanh(minf))); $display("The atanh of nan is %f.", $abs($atanh(nan))); end endtask // Task to check the min function. task check_min; begin $display("--- Checking the $min function ---"); $display("The minimum of 1.0 and 2.0 is %f.", $min(1.0, 2.0)); $display("The minimum of 2.0 and 1.0 is %f.", $min(2.0, 1.0)); $display("The minimum of 1.0 and -1.0 is %f.", $min(1.0, -1.0)); $display("The minimum of -1.0 and -2.0 is %f.", $min(-1.0, -2.0)); $display("The minimum of 2.0 and inf is %f.", $min(2.0, inf)); $display("The minimum of inf and 2.0 is %f.", $min(inf, 2.0)); $display("The minimum of 2.0 and -inf is %f.", $min(2.0, minf)); $display("The minimum of -inf and 2.0 is %f.", $min(minf, 2.0)); $display("The minimum of 2.0 and nan is %f.", $min(2.0, nan)); $display("The minimum of nan and 2.0 is %f.", $min(nan, 2.0)); end endtask // Task to check the max function. task check_max; begin $display("--- Checking the $max function ---"); $display("The maximum of 1.0 and 2.0 is %f.", $max(1.0, 2.0)); $display("The maximum of 2.0 and 1.0 is %f.", $max(2.0, 1.0)); $display("The maximum of 1.0 and -1.0 is %f.", $max(1.0, -1.0)); $display("The maximum of -1.0 and -2.0 is %f.", $max(-1.0, -2.0)); $display("The maximum of 2.0 and inf is %f.", $max(2.0, inf)); $display("The maximum of inf and 2.0 is %f.", $max(inf, 2.0)); $display("The maximum of 2.0 and -inf is %f.", $max(2.0, minf)); $display("The maximum of -inf and 2.0 is %f.", $max(minf, 2.0)); $display("The maximum of 2.0 and nan is %f.", $max(2.0, nan)); $display("The maximum of nan and 2.0 is %f.", $max(nan, 2.0)); end endtask // Task to check the power function. task check_pow; begin $display("--- Checking the $pow function ---"); $display(" 0.0 to the power of 0.0 is %f.", $pow(zero, zero)); $display(" 1.0 to the power of 0.0 is %f.", $pow(1.0, zero)); $display("-1.0 to the power of 0.0 is %f.", $pow(-1.0, zero)); $display(" 0.0 to the power of 1.0 is %f.", $pow(zero, 1.0)); $display(" 1.0 to the power of 1.0 is %f.", $pow(1.0, 1.0)); $display("-1.0 to the power of 1.0 is %f.", $pow(-1.0, 1.0)); $display(" 8.0 to the power of 1/3 is %f.", $pow(8.0, 1.0/3.0)); $display(" 8.0 to the power of -1/3 is %f.", $pow(8.0, -1.0/3.0)); $display(" 2.0 to the power of 3.0 is %f.", $pow(2.0, 3.0)); $display(" 2.0 to the power of 5000 is %f.", $pow(2.0, 5000)); $display("-2.0 to the power of 5001 is %f.", $pow(-2.0, 5001)); $display(" 2.0 to the power of -5000 is %f.", $pow(2.0, -5000)); $display(" inf to the power of 0.0 is %f.", $pow(inf, zero)); $display("-inf to the power of 0.0 is %f.", $pow(minf, zero)); $display(" inf to the power of 1.0 is %f.", $pow(inf, 1.0)); $display("-inf to the power of 1.0 is %f.", $pow(minf, 1.0)); $display(" inf to the power of 2.0 is %f.", $pow(inf, 2.0)); $display("-inf to the power of 2.0 is %f.", $pow(minf, 2.0)); $display(" 1.0 to the power of inf is %f.", $pow(1.0, inf)); $display("-1.0 to the power of inf is %f.", $pow(-1.0, inf)); $display(" 0.5 to the power of inf is %f.", $pow(0.5, inf)); $display(" 2.0 to the power of inf is %f.", $pow(2.0, inf)); $display(" 1.0 to the power of -inf is %f.", $pow(1.0, minf)); $display("-1.0 to the power of -inf is %f.", $pow(-1.0, minf)); $display(" 0.5 to the power of -inf is %f.", $pow(0.5, minf)); $display(" 2.0 to the power of -inf is %f.", $pow(2.0, minf)); $display("-1.0 to the power of -1/3 is %f.", $abs($pow(-1.0, -1.0/3.0))); $display(" 1.0 to the power of nan is %f.", $pow(1.0, nan)); $display(" nan to the power of 1.0 is %f.", $abs($pow(nan, 1.0))); $display(" nan to the power of 0.0 is %f.", $pow(nan, zero)); $display(" nan to the power of nan is %f.", $abs($pow(nan, nan))); end endtask // Task to check the atan of x/y function. task check_atan2; begin $display("--- Checking the $atan2 function ---"); $display("The atan of 0.0/ 0.0 is %f.", $atan2(zero, zero)); $display("The atan of -0.0/ 0.0 is %f.", $atan2(mzero, zero)); $display("The atan of 0.0/-0.0 is %f.", $atan2(zero, mzero)); $display("The atan of -0.0/-0.0 is %f.", $atan2(mzero, mzero)); $display("The atan of 0.0/ 1.0 is %f.", $atan2(zero, 1.0)); $display("The atan of 1.0/ 0.0 is %f.", $atan2(1.0, zero)); $display("The atan of 1.0/ 1.0 is %f.", $atan2(1.0, 1.0)); $display("The atan of 0.0/-1.0 is %f.", $atan2(zero, -1.0)); $display("The atan of -1.0/ 0.0 is %f.", $atan2(-1.0, zero)); $display("The atan of -1.0/-1.0 is %f.", $atan2(-1.0, -1.0)); $display("The atan of inf/ 0.0 is %f.", $atan2(inf, zero)); $display("The atan of 0.0/ inf is %f.", $atan2(zero, inf)); $display("The atan of inf/ inf is %f.", $atan2(inf, inf)); $display("The atan of -inf/ 0.0 is %f.", $atan2(minf, zero)); $display("The atan of 0.0/-inf is %f.", $atan2(zero, minf)); $display("The atan of -inf/-inf is %f.", $atan2(minf, minf)); $display("The atan of nan/ 0.0 is %f.", $abs($atan2(nan, zero))); $display("The atan of nan/ 1.0 is %f.", $abs($atan2(nan, 1.0))); $display("The atan of 1.0/ nan is %f.", $abs($atan2(1.0, nan))); end endtask // Task to check the distance from origin function. task check_hypot; begin $display("--- Checking the $hypot function ---"); $display("The distance to ( 0.0, 0.0) is %f.", $hypot(zero, zero)); $display("The distance to ( 2.0, 0.0) is %f.", $hypot(2.0, zero)); $display("The distance to ( -2.0, 0.0) is %f.", $hypot(-2.0, zero)); $display("The distance to ( 0.0, 2.0) is %f.", $hypot(zero, 2.0)); $display("The distance to ( 0.0, -2.0) is %f.", $hypot(zero, -2.0)); $display("The distance to ( inf, 0.0) is %f.", $hypot(inf, zero)); $display("The distance to ( 0.0, inf) is %f.", $hypot(zero, inf)); $display("The distance to ( -inf, 0.0) is %f.", $hypot(minf, zero)); $display("The distance to ( nan, 0.0) is %f.", $abs($hypot(nan, zero))); $display("The distance to ( 0.0, nan) is %f.", $abs($hypot(zero, nan))); end endtask // Task to check the mathematical constants. task check_constants; begin $display("--- Checking the mathematical constants ---"); $display(" Pi is %.16f.", `M_PI); $display(" 2*Pi is %.16f.", `M_TWO_PI); $display(" Pi/2 is %.16f.", `M_PI_2); $display(" Pi/4 is %.16f.", `M_PI_4); $display(" 1/Pi is %.16f.", `M_1_PI); $display(" 2/Pi is %.16f.", `M_2_PI); $display("2/sqrt(Pi) is %.16f.", `M_2_SQRTPI); $display(" e is %.16f.", `M_E); $display(" log2(e) is %.16f.", `M_LOG2E); $display(" log10(e) is %.16f.", `M_LOG10E); $display(" loge(2) is %.16f.", `M_LN2); $display(" loge(10) is %.16f.", `M_LN10); $display(" sqrt(2) is %.16f.", `M_SQRT2); $display(" 1/sqrt(2) is %.16f.", `M_SQRT1_2); end endtask endmodule iverilog-12_0/ivtest/ivltests/test_vams_math.v000066400000000000000000000555241435245347300217620ustar00rootroot00000000000000/* * Verilog-A math library test code for Icarus Verilog. * http://www.icarus.com/eda/verilog/ * * Copyright (C) 2007-2009 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. */ /* * As of Dec. 2009 some systems have started returning the sign of * a NaN, because of this we can for some conditions get -nan. This * will cause mismatches with the gold file. Alan M. Feldstein * suggested on the iverilog-devel mailing list that we use fabs * (abs()) since C99 speifies that it will remove the sign of the * NaN. This appears to work, so I wrapped all functions that we * expect to return NaN with a call to abs(). */ // Get the Verilog-A constants. `include "constants.vams" module top; real zero, mzero, pinf, minf, nan; initial begin // Define a few constants. zero = 0.0; mzero = -1.0 * zero; pinf = 1/0.0; minf = ln(0); nan = abs(sqrt(-1.0)); $display("Using +0 = %f, -0 = %f, nan = %f, inf = %f and -inf = %f.\n", zero, mzero, nan, pinf, minf); // Check that the comparisons used to detection a NaN work correctly. if (nan != nan) $display("NaN != comparison works correctly."); else $display("NaN != comparison failed."); if (nan == nan) $display("NaN == comparison failed.\n"); else $display("NaN == comparison works correctly.\n"); check_sqrt; $display(""); check_ln; $display(""); check_log; $display(""); check_exp; $display(""); check_abs; $display(""); check_ceil; $display(""); check_floor; $display(""); check_sin; $display(""); check_cos; $display(""); check_tan; $display(""); check_asin; $display(""); check_acos; $display(""); check_atan; $display(""); check_sinh; $display(""); check_cosh; $display(""); check_tanh; $display(""); check_asinh; $display(""); check_acosh; $display(""); check_atanh; $display(""); check_min; $display(""); check_max; $display(""); check_pow; $display(""); check_atan2; $display(""); check_hypot; $display(""); check_constants; end // Task to check the square root function. task check_sqrt; begin $display("--- Checking the sqrt function ---"); $display("The square root of 2.0 is %f.", sqrt(2.0)); $display("The square root of 1.0 is %f.", sqrt(1.0)); $display("The square root of 0.0 is %f.", sqrt(zero)); $display("The square root of -0.0 is %f.", sqrt(mzero)); $display("The square root of -1.0 is %f.", abs(sqrt(-1.0))); $display("The square root of inf is %f.", sqrt(pinf)); $display("The square root of -inf is %f.", abs(sqrt(minf))); $display("The square root of nan is %f.", abs(sqrt(nan))); end endtask // Task to check the natural log function. task check_ln; begin $display("--- Checking the ln function ---"); $display("The natural log of 10.0 is %f.", ln(10.0)); $display("The natural log of 1.0 is %f.", ln(1.0)); $display("The natural log of 0.5 is %f.", ln(0.5)); $display("The natural log of 0.0 is %f.", ln(zero)); $display("The natural log of -0.0 is %f.", ln(mzero)); $display("The natural log of -1.0 is %f.", abs(ln(-1.0))); $display("The natural log of inf is %f.", ln(pinf)); $display("The natural log of -inf is %f.", abs(ln(minf))); $display("The natural log of nan is %f.", abs(ln(nan))); end endtask // Task to check the log base 10 function. task check_log; begin $display("--- Checking the log function ---"); $display("The log base 10 of 10.0 is %f.", log(10.0)); $display("The log base 10 of 1.0 is %f.", log(1.0)); $display("The log base 10 of 0.5 is %f.", log(0.5)); $display("The log base 10 of 0.0 is %f.", log(zero)); $display("The log base 10 of -0.0 is %f.", log(mzero)); $display("The log base 10 of -1.0 is %f.", abs(log(-1.0))); $display("The log base 10 of inf is %f.", log(pinf)); $display("The log base 10 of -inf is %f.", abs(log(minf))); $display("The log base 10 of nan is %f.", abs(log(nan))); end endtask // Task to check the exponential function. task check_exp; begin $display("--- Checking the exp function ---"); $display("The exponential of 1.0 is %f.", exp(1.0)); $display("The exponential of 0.0 is %f.", exp(zero)); $display("The exponential of -0.0 is %f.", exp(mzero)); $display("The exponential of -1.0 is %f.", exp(-1.0)); $display("The exponential of inf is %f.", exp(pinf)); $display("The exponential of -inf is %f.", exp(minf)); $display("The exponential of nan is %f.", abs(exp(nan))); end endtask // Task to check the absolute value function. task check_abs; begin $display("--- Checking the abs function ---"); $display("The absolute value of 1.0 is %f.", abs(1.0)); $display("The absolute value of 0.0 is %f.", abs(zero)); $display("The absolute value of -0.0 is %f.", abs(mzero)); $display("The absolute value of -1.0 is %f.", abs(-1.0)); $display("The absolute value of inf is %f.", abs(pinf)); $display("The absolute value of -inf is %f.", abs(minf)); $display("The absolute value of nan is %f.", abs(nan)); end endtask // Task to check the ceiling function. task check_ceil; begin $display("--- Checking the ceil function ---"); $display("The ceiling of 2.1 is %f.", ceil(2.1)); $display("The ceiling of 0.5 is %f.", ceil(0.5)); $display("The ceiling of -0.5 is %f.", ceil(-0.5) + 0.0); $display("The ceiling of -1.1 is %f.", ceil(-1.1)); $display("The ceiling of inf is %f.", ceil(pinf)); $display("The ceiling of -inf is %f.", ceil(minf)); $display("The ceiling of nan is %f.", abs(ceil(nan))); end endtask // Task to check the floor function. task check_floor; begin $display("--- Checking the floor function ---"); $display("The floor of 2.1 is %f.", floor(2.1)); $display("The floor of 0.5 is %f.", floor(0.5)); $display("The floor of -0.5 is %f.", floor(-0.5)); $display("The floor of -1.1 is %f.", floor(-1.1)); $display("The floor of inf is %f.", floor(pinf)); $display("The floor of -inf is %f.", floor(minf)); $display("The floor of nan is %f.", abs(floor(nan))); end endtask // Task to check the sin function. task check_sin; begin $display("--- Checking the sin function ---"); $display("The sin of 4.0 is %f.", sin(4.0)); $display("The sin of 1.0 is %f.", sin(1.0)); $display("The sin of 0.0 is %f.", sin(zero)); $display("The sin of -0.0 is %f.", sin(mzero)); $display("The sin of -1.0 is %f.", sin(-1.0)); $display("The sin of -4.0 is %f.", sin(-4.0)); $display("The sin of inf is %f.", abs(sin(pinf))); $display("The sin of -inf is %f.", abs(sin(minf))); $display("The sin of nan is %f.", abs(sin(nan))); end endtask // Task to check the cos function. task check_cos; begin $display("--- Checking the cos function ---"); $display("The cos of 4.0 is %f.", cos(4.0)); $display("The cos of 1.0 is %f.", cos(1.0)); $display("The cos of 0.0 is %f.", cos(zero)); $display("The cos of -0.0 is %f.", cos(mzero)); $display("The cos of -1.0 is %f.", cos(-1.0)); $display("The cos of -4.0 is %f.", cos(-4.0)); $display("The cos of inf is %f.", abs(cos(pinf))); $display("The cos of -inf is %f.", abs(cos(minf))); $display("The cos of nan is %f.", abs(cos(nan))); end endtask // Task to check the tan function. task check_tan; begin $display("--- Checking the tan function ---"); $display("The tan of 4.0 is %f.", tan(4.0)); $display("The tan of 1.0 is %f.", tan(1.0)); $display("The tan of 0.0 is %f.", tan(zero)); $display("The tan of -0.0 is %f.", tan(mzero)); $display("The tan of -1.0 is %f.", tan(-1.0)); $display("The tan of -4.0 is %f.", tan(-4.0)); // The underlying math libraries can give different results for // this corner case, so we can only use four significant digits // for these two tests. $display("The tan of pi/2 is %.4g.", tan(asin(1.0))); $display("The tan of -pi/2 is %.4g.", tan(asin(-1.0))); $display("The tan of inf is %f.", abs(tan(pinf))); $display("The tan of -inf is %f.", abs(tan(minf))); $display("The tan of nan is %f.", abs(tan(nan))); end endtask // Task to check the asin function. task check_asin; begin $display("--- Checking the asin function ---"); $display("The asin of 1.1 is %f.", abs(asin(1.1))); $display("The asin of 1.0 is %f.", asin(1.0)); $display("The asin of 0.5 is %f.", asin(0.5)); $display("The asin of 0.0 is %f.", asin(zero)); $display("The asin of -0.0 is %f.", asin(mzero)); $display("The asin of -0.5 is %f.", asin(-0.5)); $display("The asin of -1.0 is %f.", asin(-1.0)); $display("The asin of -1.1 is %f.", abs(asin(-1.1))); $display("The asin of inf is %f.", abs(asin(pinf))); $display("The asin of -inf is %f.", abs(asin(minf))); $display("The asin of nan is %f.", abs(asin(nan))); end endtask // Task to check the acos function. task check_acos; begin $display("--- Checking the acos function ---"); $display("The acos of 1.1 is %f.", abs(acos(1.1))); $display("The acos of 1.0 is %f.", acos(1.0)); $display("The acos of 0.5 is %f.", acos(0.5)); $display("The acos of 0.0 is %f.", acos(zero)); $display("The acos of -0.0 is %f.", acos(mzero)); $display("The acos of -0.5 is %f.", acos(-0.5)); $display("The acos of -1.0 is %f.", acos(-1.0)); $display("The acos of -1.1 is %f.", abs(acos(-1.1))); $display("The acos of inf is %f.", abs(acos(pinf))); $display("The acos of -inf is %f.", abs(acos(minf))); $display("The acos of nan is %f.", abs(acos(nan))); end endtask // Task to check the atan function. task check_atan; begin $display("--- Checking the atan function ---"); $display("The atan of 2.0 is %f.", atan(2.0)); $display("The atan of 0.5 is %f.", atan(0.5)); $display("The atan of 0.0 is %f.", atan(zero)); $display("The atan of -0.0 is %f.", atan(mzero)); $display("The atan of -0.5 is %f.", atan(-0.5)); $display("The atan of -2.0 is %f.", atan(-2.0)); $display("The atan of inf is %f.", atan(pinf)); $display("The atan of -inf is %f.", atan(minf)); $display("The atan of nan is %f.", abs(atan(nan))); end endtask // Task to check the sinh function. task check_sinh; begin $display("--- Checking the sinh function ---"); $display("The sinh of 2.0 is %f.", sinh(2.0)); $display("The sinh of 1.0 is %f.", sinh(1.0)); $display("The sinh of 0.5 is %f.", sinh(0.5)); $display("The sinh of 0.0 is %f.", sinh(zero)); $display("The sinh of -0.0 is %f.", sinh(mzero)); $display("The sinh of -0.5 is %f.", sinh(-0.5)); $display("The sinh of -1.0 is %f.", sinh(-1.0)); $display("The sinh of -2.0 is %f.", sinh(-2.0)); $display("The sinh of inf is %f.", sinh(pinf)); $display("The sinh of -inf is %f.", sinh(minf)); $display("The sinh of nan is %f.", abs(sinh(nan))); end endtask // Task to check the cosh function. task check_cosh; begin $display("--- Checking the cosh function ---"); $display("The cosh of 2.0 is %f.", cosh(2.0)); $display("The cosh of 1.0 is %f.", cosh(1.0)); $display("The cosh of 0.5 is %f.", cosh(0.5)); $display("The cosh of 0.0 is %f.", cosh(zero)); $display("The cosh of -0.0 is %f.", cosh(mzero)); $display("The cosh of -0.5 is %f.", cosh(-0.5)); $display("The cosh of -1.0 is %f.", cosh(-1.0)); $display("The cosh of -2.0 is %f.", cosh(-2.0)); $display("The cosh of inf is %f.", cosh(pinf)); $display("The cosh of -inf is %f.", cosh(minf)); $display("The cosh of nan is %f.", abs(cosh(nan))); end endtask // Task to check the tanh function. task check_tanh; begin $display("--- Checking the tanh function ---"); $display("The tanh of 2.0 is %f.", tanh(2.0)); $display("The tanh of 1.0 is %f.", tanh(1.0)); $display("The tanh of 0.5 is %f.", tanh(0.5)); $display("The tanh of 0.0 is %f.", tanh(zero)); $display("The tanh of -0.0 is %f.", tanh(mzero)); $display("The tanh of -0.5 is %f.", tanh(-0.5)); $display("The tanh of -1.0 is %f.", tanh(-1.0)); $display("The tanh of -2.0 is %f.", tanh(-2.0)); $display("The tanh of inf is %f.", tanh(pinf)); $display("The tanh of -inf is %f.", tanh(minf)); $display("The tanh of nan is %f.", abs(tanh(nan))); end endtask // Task to check the asinh function. task check_asinh; begin $display("--- Checking the asinh function ---"); $display("The asinh of 2.0 is %f.", asinh(2.0)); $display("The asinh of 1.0 is %f.", asinh(1.0)); $display("The asinh of 0.5 is %f.", asinh(0.5)); $display("The asinh of 0.0 is %f.", asinh(zero)); $display("The asinh of -0.0 is %f.", asinh(mzero)); $display("The asinh of -0.5 is %f.", asinh(-0.5)); $display("The asinh of -1.0 is %f.", asinh(-1.0)); $display("The asinh of -2.0 is %f.", asinh(-2.0)); $display("The asinh of inf is %f.", asinh(pinf)); $display("The asinh of -inf is %f.", asinh(minf)); $display("The asinh of nan is %f.", abs(asinh(nan))); end endtask // Task to check the acosh function. task check_acosh; begin $display("--- Checking the acosh function ---"); $display("The acosh of 2.0 is %f.", acosh(2.0)); $display("The acosh of 1.0 is %f.", acosh(1.0)); $display("The acosh of 0.5 is %f.", abs(acosh(0.5))); $display("The acosh of 0 is %f.", abs(acosh(zero))); $display("The acosh of -0 is %f.", abs(acosh(mzero))); $display("The acosh of -0.5 is %f.", abs(acosh(-0.5))); $display("The acosh of -1.0 is %f.", abs(acosh(-1.0))); $display("The acosh of -2.0 is %f.", abs(acosh(-2.0))); $display("The acosh of inf is %f.", acosh(pinf)); $display("The acosh of -inf is %f.", abs(acosh(minf))); $display("The acosh of nan is %f.", abs(acosh(nan))); end endtask // Task to check the atanh function. task check_atanh; begin $display("--- Checking the atanh function ---"); $display("The atanh of 2.0 is %f.", abs(atanh(2.0))); $display("The atanh of 1.0 is %f.", atanh(1.0)); $display("The atanh of 0.5 is %f.", atanh(0.5)); $display("The atanh of 0.0 is %f.", atanh(zero)); $display("The atanh of -0.0 is %f.", atanh(mzero)); $display("The atanh of -0.5 is %f.", atanh(-0.5)); $display("The atanh of -1.0 is %f.", atanh(-1.0)); $display("The atanh of -2.0 is %f.", abs(atanh(-2.0))); $display("The atanh of inf is %f.", abs(atanh(pinf))); $display("The atanh of -inf is %f.", abs(atanh(minf))); $display("The atanh of nan is %f.", abs(atanh(nan))); end endtask // Task to check the min function. task check_min; begin $display("--- Checking the min function ---"); $display("The minimum of 1.0 and 2.0 is %f.", min(1.0, 2.0)); $display("The minimum of 2.0 and 1.0 is %f.", min(2.0, 1.0)); $display("The minimum of 1.0 and -1.0 is %f.", min(1.0, -1.0)); $display("The minimum of -1.0 and -2.0 is %f.", min(-1.0, -2.0)); $display("The minimum of 2.0 and inf is %f.", min(2.0, pinf)); $display("The minimum of inf and 2.0 is %f.", min(pinf, 2.0)); $display("The minimum of 2.0 and -inf is %f.", min(2.0, minf)); $display("The minimum of -inf and 2.0 is %f.", min(minf, 2.0)); $display("The minimum of 2.0 and nan is %f.", min(2.0, nan)); $display("The minimum of nan and 2.0 is %f.", min(nan, 2.0)); end endtask // Task to check the max function. task check_max; begin $display("--- Checking the max function ---"); $display("The maximum of 1.0 and 2.0 is %f.", max(1.0, 2.0)); $display("The maximum of 2.0 and 1.0 is %f.", max(2.0, 1.0)); $display("The maximum of 1.0 and -1.0 is %f.", max(1.0, -1.0)); $display("The maximum of -1.0 and -2.0 is %f.", max(-1.0, -2.0)); $display("The maximum of 2.0 and inf is %f.", max(2.0, pinf)); $display("The maximum of inf and 2.0 is %f.", max(pinf, 2.0)); $display("The maximum of 2.0 and -inf is %f.", max(2.0, minf)); $display("The maximum of -inf and 2.0 is %f.", max(minf, 2.0)); $display("The maximum of 2.0 and nan is %f.", max(2.0, nan)); $display("The maximum of nan and 2.0 is %f.", max(nan, 2.0)); end endtask // Task to check the power function. task check_pow; begin $display("--- Checking the pow function ---"); $display(" 0.0 to the power of 0.0 is %f.", pow(zero, zero)); $display(" 1.0 to the power of 0.0 is %f.", pow(1.0, zero)); $display("-1.0 to the power of 0.0 is %f.", pow(-1.0, zero)); $display(" 0.0 to the power of 1.0 is %f.", pow(zero, 1.0)); $display(" 1.0 to the power of 1.0 is %f.", pow(1.0, 1.0)); $display("-1.0 to the power of 1.0 is %f.", pow(-1.0, 1.0)); $display(" 8.0 to the power of 1/3 is %f.", pow(8.0, 1.0/3.0)); $display(" 8.0 to the power of -1/3 is %f.", pow(8.0, -1.0/3.0)); $display(" 2.0 to the power of 3.0 is %f.", pow(2.0, 3.0)); $display(" 2.0 to the power of 5000 is %f.", pow(2.0, 5000)); $display("-2.0 to the power of 5001 is %f.", pow(-2.0, 5001)); $display(" 2.0 to the power of -5000 is %f.", pow(2.0, -5000)); $display(" inf to the power of 0.0 is %f.", pow(pinf, zero)); $display("-inf to the power of 0.0 is %f.", pow(minf, zero)); $display(" inf to the power of 1.0 is %f.", pow(pinf, 1.0)); $display("-inf to the power of 1.0 is %f.", pow(minf, 1.0)); $display(" inf to the power of 2.0 is %f.", pow(pinf, 2.0)); $display("-inf to the power of 2.0 is %f.", pow(minf, 2.0)); $display(" 1.0 to the power of inf is %f.", pow(1.0, pinf)); $display("-1.0 to the power of inf is %f.", pow(-1.0, pinf)); $display(" 0.5 to the power of inf is %f.", pow(0.5, pinf)); $display(" 2.0 to the power of inf is %f.", pow(2.0, pinf)); $display(" 1.0 to the power of -inf is %f.", pow(1.0, minf)); $display("-1.0 to the power of -inf is %f.", pow(-1.0, minf)); $display(" 0.5 to the power of -inf is %f.", pow(0.5, minf)); $display(" 2.0 to the power of -inf is %f.", pow(2.0, minf)); $display("-1.0 to the power of -1/3 is %f.", abs(pow(-1.0, -1.0/3.0))); $display(" 1.0 to the power of nan is %f.", pow(1.0, nan)); $display(" nan to the power of 1.0 is %f.", abs(pow(nan, 1.0))); $display(" nan to the power of 0.0 is %f.", pow(nan, zero)); $display(" nan to the power of nan is %f.", abs(pow(nan, nan))); end endtask // Task to check the atan of x/y function. task check_atan2; begin $display("--- Checking the atan2 function ---"); $display("The atan of 0.0/ 0.0 is %f.", atan2(zero, zero)); $display("The atan of -0.0/ 0.0 is %f.", atan2(mzero, zero)); $display("The atan of 0.0/-0.0 is %f.", atan2(zero, mzero)); $display("The atan of -0.0/-0.0 is %f.", atan2(mzero, mzero)); $display("The atan of 0.0/ 1.0 is %f.", atan2(zero, 1.0)); $display("The atan of 1.0/ 0.0 is %f.", atan2(1.0, zero)); $display("The atan of 1.0/ 1.0 is %f.", atan2(1.0, 1.0)); $display("The atan of 0.0/-1.0 is %f.", atan2(zero, -1.0)); $display("The atan of -1.0/ 0.0 is %f.", atan2(-1.0, zero)); $display("The atan of -1.0/-1.0 is %f.", atan2(-1.0, -1.0)); $display("The atan of inf/ 0.0 is %f.", atan2(pinf, zero)); $display("The atan of 0.0/ inf is %f.", atan2(zero, pinf)); $display("The atan of inf/ inf is %f.", atan2(pinf, pinf)); $display("The atan of -inf/ 0.0 is %f.", atan2(minf, zero)); $display("The atan of 0.0/-inf is %f.", atan2(zero, minf)); $display("The atan of -inf/-inf is %f.", atan2(minf, minf)); $display("The atan of nan/ 0.0 is %f.", abs(atan2(nan, zero))); $display("The atan of nan/ 1.0 is %f.", abs(atan2(nan, 1.0))); $display("The atan of 1.0/ nan is %f.", abs(atan2(1.0, nan))); end endtask // Task to check the distance from origin function. task check_hypot; begin $display("--- Checking the hypot function ---"); $display("The distance to ( 0.0, 0.0) is %f.", hypot(zero, zero)); $display("The distance to ( 2.0, 0.0) is %f.", hypot(2.0, zero)); $display("The distance to ( -2.0, 0.0) is %f.", hypot(-2.0, zero)); $display("The distance to ( 0.0, 2.0) is %f.", hypot(zero, 2.0)); $display("The distance to ( 0.0, -2.0) is %f.", hypot(zero, -2.0)); $display("The distance to ( inf, 0.0) is %f.", hypot(pinf, zero)); $display("The distance to ( 0.0, inf) is %f.", hypot(zero, pinf)); $display("The distance to ( -inf, 0.0) is %f.", hypot(minf, zero)); $display("The distance to ( nan, 0.0) is %f.", abs(hypot(nan, zero))); $display("The distance to ( 0.0, nan) is %f.", abs(hypot(zero, nan))); end endtask // Task to check the mathematical constants. task check_constants; begin $display("--- Checking the mathematical constants ---"); $display(" Pi is %.16f.", `M_PI); $display(" 2*Pi is %.16f.", `M_TWO_PI); $display(" Pi/2 is %.16f.", `M_PI_2); $display(" Pi/4 is %.16f.", `M_PI_4); $display(" 1/Pi is %.16f.", `M_1_PI); $display(" 2/Pi is %.16f.", `M_2_PI); $display("2/sqrt(Pi) is %.16f.", `M_2_SQRTPI); $display(" e is %.16f.", `M_E); $display(" log2(e) is %.16f.", `M_LOG2E); $display(" log10(e) is %.16f.", `M_LOG10E); $display(" loge(2) is %.16f.", `M_LN2); $display(" loge(10) is %.16f.", `M_LN10); $display(" sqrt(2) is %.16f.", `M_SQRT2); $display(" 1/sqrt(2) is %.16f.", `M_SQRT1_2); end endtask endmodule iverilog-12_0/ivtest/ivltests/test_varray1.v000066400000000000000000000037331435245347300213630ustar00rootroot00000000000000// This module generate M single 2*HW-1 bit vector each T time steps module stimulus #(parameter W = 8, M = 200, MAX = 256) ( input bit clk, reset, output reg [W-1:0] x ); int i; initial begin @(negedge reset); for (i = 0; i < M; i=i+1) begin @(negedge clk); x = {$random} % MAX; end end endmodule module test; parameter M = 200; // number of test vectors parameter W = 8; // bit width of input vecotrs parameter T = 10; // for timing parameter D = 8; // depth of pipeline, MAX of 8 parameter K = 10; // distance between boundaries of pipeline parameter S = 2*M*T + 12*D; parameter MAX = D*K; bit clk =0, reset = 0; wire [W-1:0] xin; wire [W-1:0] din = K; wire [W-1:0] dout, bout, xout; wire [2:0] lin = 3'b111; // -1 in fact wire [2:0] lout; int x_gold; // for computing expected result initial forever #T clk = ~clk; stimulus #(W, M, MAX) stim (.clk(clk), .reset(reset), .x(xin)); diq_array #(W, D) duv (.clk(clk), .reset(reset), .din(din), .bin(8'd0), .xin(xin), .lin(lin), .dout(dout), .bout(bout), .xout(xout), .lout(lout) ); initial begin: checking @(negedge reset); @(posedge clk); repeat (D) @(negedge clk); forever begin @(posedge clk); #1; // checking dout if (dout !== din) begin $display("ERROR"); $finish; end // checking bout if (bout !== MAX) begin $display("ERROR"); $finish; end // checking lout x_gold = xout-1; // dirty fix, for example xin = 30 muste be reported as 2 if (lout !== x_gold/K) begin $display("ERROR"); $finish; end end end initial begin doreset(); #S; $display("PASSED"); $finish; end task doreset; begin @(negedge clk); reset = 1; repeat (5) @(negedge clk); reset = 0; end endtask endmodule iverilog-12_0/ivtest/ivltests/test_when_else.v000066400000000000000000000013641435245347300217450ustar00rootroot00000000000000module main; reg [1:0] src; wire [3:0] dst, dst2, dst3; foo_entity dut (.data_o(dst), .data_o2(dst2), .data_o3(dst3), .data_i(src)); initial begin src = 2'b00; #1 if (dst != 4'b0001 || dst2 != 4'bxxxx || dst3 != 4'bxxx) begin $display("FAILED"); $finish; end src = 2'b01; #1 if (dst != 4'b0010 || dst2 != 4'b0101 || dst3 != 4'b0011) begin $display("FAILED"); $finish; end src = 2'b10; #1 if (dst != 4'b0100 || dst2 != 4'b0101 || dst3 != 4'b1100) begin $display("FAILED"); $finish; end src = 2'b11; #1 if (dst != 4'b1000 || dst2 != 4'b0101 || dst3 != 4'b1100) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/test_width.v000066400000000000000000000055501435245347300211140ustar00rootroot00000000000000// Released under GPL2.0 // (c) 2002 Tom Verbeure module main; integer myInt; reg [39:0] myReg40; reg [0:39] myReg40r; reg [0:38] myReg39r; reg [13:0] myReg14; reg [7:0] myReg8; reg [31:0] myReg32; initial begin $display("============================ myReg14 = -10"); myReg14 = -10; $display(">|16374|"); $display("*|%d|", myReg14); $display("*|%0d|", myReg14); $display("*|",myReg14,"|"); $display("============================ myReg14 = 65"); myReg14 = 65; $display(">| 65|"); $display("*|%d|", myReg14); $display("*|",myReg14,"|"); $display(">|65|"); $display("*|%0d|", myReg14); $display(">|0041|"); $display("*|%h|", myReg14); $display(">|41|"); $display("*|%0h|", myReg14); $display(">|00101|"); $display("*|%o|", myReg14); $display(">|101|"); $display("*|%0o|", myReg14); $display(">|00000001000001|"); $display("*|%b|", myReg14); $display(">|1000001|"); $display("*|%0b|", myReg14); $display(">| A|"); $display("*|%s|", myReg14); $display(">|A|"); $display("*|%0s|", myReg14); $display("============================ myInt = -10"); myInt = -10; $display(">| -10|"); $display("*|%d|", myInt); $display("*|",myInt,"|"); $display(">|-10|"); $display("*|%0d|", myInt); $display(">|fffffff6|"); $display("*|%h|", myInt); $display("*|%0h|", myInt); $display(">|37777777766|"); $display("*|%o|", myInt); $display("*|%0o|", myInt); $display(">|11111111111111111111111111110110|"); $display("*|%b|", myInt); $display("*|%0b|", myInt); $display("============================ myReg32 = -10"); myReg32 = -10; $display(">|4294967286|"); $display("*|%d|", myReg32); $display("*|%0d|", myReg32); $display("*|",myReg32,"|"); $display(">|fffffff6|"); $display("*|%h|", myReg32); $display("*|%0h|", myReg32); $display(">|37777777766|"); $display("*|%o|", myReg32); $display("*|%0o|", myReg32); $display("============================ myInt = 65"); myInt = 65; $display(">| 65|"); $display("*|%d|", myInt); $display("*|",myInt,"|"); $display(">|65|"); $display("*|%0d|", myInt); $display(">|00000041|"); $display("*|%h|", myInt); $display(">|41|"); $display("*|%0h|", myInt); $display(">|00000000101|"); $display("*|%o|", myInt); $display(">|101|"); $display("*|%0o|", myInt); $display(">|00000000000000000000000001000001|"); $display("*|%b|", myInt); $display(">|1000001|"); $display("*|%0b|", myInt); $display("*| A|"); $display(">|%s|", myInt); $display("*|A|"); $display(">|%0s|", myInt); $display("============================ Print \" A\""); $display("*| A|"); $display(">|%s|", " A"); $display(">|%0s|", " A"); $display("============================ Print $time"); $display("*| 0|"); $display(">|%t|", $time); $display("*|0|"); $display(">|%0t|", $time); end endmodule iverilog-12_0/ivtest/ivltests/test_work14.v000066400000000000000000000011561435245347300211220ustar00rootroot00000000000000module test14; import work14_pkg::*; bit clk = 0; parameter longint maxvalue = 2**29 + 17; logic [29:0] mvalue; logic [29:0] lvalue; initial begin : clkgen forever #10 clk = ~clk; end assign lvalue = maxvalue; work14_comp #(.max_out_val(maxvalue)) duv (.clk_i(clk), .val(mvalue)); initial begin @(posedge clk); #1; if (lvalue !== mvalue) $display ("ERROR due to mismatch between lvalue=%d and mvalue=%d", lvalue, mvalue); @(posedge clk); #1; if (lvalue !== mvalue) $display ("ERROR due to mismatch between lvalue=%d and mvalue=%d", lvalue, mvalue); #5; $display ("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/time1.v000066400000000000000000000024661435245347300177600ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - Verify glitch doesn't propagate. // // D: module main (); reg a; reg error; wire c; reg d; assign c = a; always @(c) #5 d = c; always @(posedge d) error <= 1'b1; initial begin /* $dumpfile("/root/testsuite/dump.vcd"); $dumpvars(0,main); $dumpon; */ a =1'b0; error = 1'b0; #10; a = 1'b1; # 3; a = 1'b0; # 10; if(error) $display("FAILED"); else $display("PASSED"); #5; $finish ; end endmodule iverilog-12_0/ivtest/ivltests/time2.v000066400000000000000000000026751435245347300177630ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Check posedge vector - should use bit 0 only. Doesn't work with XL module time2 (); reg [3:0] clock; reg [3:0] b; reg [3:0] count; initial begin b = 4'b1111; count = 0; for (clock = 0; clock<=10; clock = clock + 1) begin $display("time = %t, clock = %h",$time,clock); #10; end end always @(posedge clock & b) begin count = count+1; $display(" edge ! time = %t, count = %h",$time,count); end initial begin #1000; if(count != 6) $display("FAILED - vect[0] clock detect count=%d",count); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/time3.v000066400000000000000000000025211435245347300177520ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // SDW - time3.v - Verify glitch doesn't propagate with non-blocking // // D: module main (); reg a; reg error; wire c; reg d; assign c = a; always @(c) #5 d <= c; always @(posedge d) error <= 1'b1; initial begin /* $dumpfile("/root/testsuite/dump.vcd"); $dumpvars(0,main); $dumpon; */ a =1'b0; error = 1'b0; #10; a = 1'b1; # 3; a = 1'b0; # 10; if(error) $display("FAILED"); else $display("PASSED"); #5; $finish; end endmodule iverilog-12_0/ivtest/ivltests/time4.v000066400000000000000000000022731435245347300177570ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module tests time variables */ module main; time t; initial begin if (t !== 64'bx) begin $display("FAILED -- t == %b", t); $finish; end #35 t = $time; #5 if (t !== 35) begin $display("FAILED -- t == %b (should be 35)", t); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/time5.v000066400000000000000000000036111435245347300177550ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests that a non-integer delay, in the absence of any * timescale values, will round properly. A 2.4 delay rounds to 2, and * a 2.6 delay rounds to 3. */ module main; reg clk; reg out1, out2; time time1; time time2; always @(posedge clk) #2.4 begin $display($time,, "set out1 == 1"); time1 = $time; out1 = 1; end always @(posedge clk) #2.6 begin $display($time,, "set out2 == 1"); time2 = $time; out2 = 1; end initial begin clk = 0; out1 = 0; out2 = 0; time1 = 0; time2 = 0; #1 if (out1 !== 0) begin $display("FAILED -- out1 is not 0: %b", out1); $finish; end clk = 1; #3 if (out1 !== 1) begin $display("FAILED -- out is not 1 at time 3: %b", out1); $finish; end if (time1 != 3) begin $display("FAILED -- time1 = %d", time1); $finish; end #1 if (time2 != 4) begin $display("FAILED -- time2 = %d", time2); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/time6.v000066400000000000000000000040611435245347300177560ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests that a non-integer delay gets its extra * precision accounted for if the timescale supports it. In this * example, set the units to 1ms, but set the precision so that the * numbers can be given accurate to .1ms. This should cause a delay * of 2.4 and 2.6 to really be different. */ `timescale 1ms / 100us module main; reg clk; reg out1, out2; time time1; time time2; always @(posedge clk) #2.4 begin $display($time,, "set out1 == 1"); time1 = $simtime; out1 = 1; end always @(posedge clk) #2.6 begin $display($time,, "set out2 == 1"); time2 = $simtime; out2 = 1; end initial begin clk = 0; out1 = 0; out2 = 0; time1 = 0; time2 = 0; #1 if (out1 !== 0) begin $display("FAILED -- out1 is not 0: %b", out1); $finish; end clk = 1; #3 if (out1 !== 1) begin $display("FAILED -- out is not 1 at time 3: %b", out1); $finish; end if (time1 != 34) begin $display("FAILED -- time1 = %d", time1); $finish; end #1 if (time2 != 36) begin $display("FAILED -- time2 = %d", time2); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/time6b.v000066400000000000000000000046201435245347300201210ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests that a non-integer delay gets its extra * precision accounted for if the timescale supports it. In this * example, set the units to 1ms, but set the precision so that the * numbers can be given accurate to .1ms. This should cause a delay * of 2.4 and 2.6 to really be different. */ `timescale 1ms / 100us module main; reg err; reg clk; reg out1, out2; realtime time1; realtime time2; real eps; always @(posedge clk) #2.4 begin $display($time,,$realtime, " set out1 == 1"); time1 = $realtime; out1 = 1; end always @(posedge clk) #2.6 begin $display($time,,$realtime, " set out2 == 1"); time2 = $realtime; out2 = 1; end initial begin clk = 0; out1 = 0; out2 = 0; time1 = 0; time2 = 0; err = 0; $timeformat(-3,1,"ms",5); #1 if (out1 !== 0) begin $display("Error -- out1 s/b 0 at time $time but is=%x", out1); err =1 ; end clk = 1; #3 if (out1 !== 1) begin $display("Error -- out1 s/b 1 at time $time but is=%x", out1); err =1 ; end eps = time1 - 3.4; if (eps < 0.0) eps = 0.0 - eps; if (eps > 0.0001) begin $display("Error -- time1 s/b 3.4 but is=%t", time1); err =1 ; end #1 eps = time2 - 3.6; if (eps < 0.0) eps = 0.0 - eps; if (eps > 0.0001) begin $display("Error -- time2 s/b 3.6 but is=%t, ", time2); err =1 ; end if(err == 0) $display("PASSED"); else $display("FAILED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/time6c.v000066400000000000000000000045441435245347300201270ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests that a non-integer delay gets its extra * precision accounted for if the timescale supports it. In this * example, set the units to 1ms, but set the precision so that the * numbers can be given accurate to .1ms. This should cause a delay * of 2.4 and 2.6 to really be different. */ `timescale 1ms / 100us module main; reg err; reg clk; reg out1, out2; realtime time1; realtime time2; real eps; always @(posedge clk) #2.4 begin $display($time,,$realtime, " set out1 == 1"); time1 = $realtime; out1 = 1; end always @(posedge clk) #2.6 begin $display($time,,$realtime, " set out2 == 1"); time2 = $realtime; out2 = 1; end initial begin clk = 0; out1 = 0; out2 = 0; time1 = 0; time2 = 0; err = 0; $timeformat(-3,1,"ms",5); #1 if (out1 !== 0) begin $display("Error -- out1 s/b 0 at time $time but is=%x", out1); err =1 ; end clk = 1; #3 if (out1 !== 1) begin $display("Error -- out1 s/b 1 at time $time but is=%x", out1); err =1 ; end eps = time1 - 3.4; if (eps < 0.0) eps = 0.0 - eps; if (eps > 0.0001) begin $display("Error -- time1 s/b 3.4 but is=%t", time1); err =1 ; end #1 eps = time2 - 3.6; if (eps < 0.0) eps = 0.0 - eps; if (eps > 0.0001) begin $display("Error -- time2 s/b 3.6 but is=%t, ", time2); err =1 ; end // Use a gold file to check this version. end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/time7.v000066400000000000000000000050041435245347300177550ustar00rootroot00000000000000/* * Copyright (c) 2000 Nadim Shaikli * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* This is made up from PR#63 */ module main; reg one, clk; reg [1:0] a, b, c, passed; reg [7:0] count; always #1 one = ~one; // generate a clock always #10 clk = ~clk; initial begin $display ("\n<< BEGIN >>"); one = 1'b1; clk = 1'b0; passed = 2'b00; count = 0; #15 a[1:0] = 2'b01; #10 a[1:0] = 2'b10; #20 $display ("\n<< END >>"); if (passed == 2) $display ("PASSED"); else $display ("FAILED"); $finish; end always @(clk) begin // Problematic lines below -- comment them out to see timing skew b[1:0] <= #2.5 a[1:0]; c[1:0] <= #7.8 a[1:0]; end always @(one) count[7:0] <= count + 1; always @(count) begin case ( count ) 'd25: if (b[1:0] == 2'b01) begin $display ("@ %0t - Got ONE", $time); passed = passed + 1; end else $display ("@ %0t - failure", $time); 'd29: if (b[1:0] == 2'b01) begin $display ("@ %0t - Got ONE", $time); passed = passed + 1; end else $display ("@ %0t - failure", $time); default: $display ("@ %0t - no count", $time); endcase end // Waves definition // initial // begin // $recordvars("primitives", "drivers"); // $dumpfile("out.dump"); // $dumpvars(5, main); // Line below ought to work // $dumpvars; // end endmodule // main iverilog-12_0/ivtest/ivltests/time8.v000066400000000000000000000026611435245347300177640ustar00rootroot00000000000000/* * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [1:0] out; initial begin out = 2'b0; if (out !== 2'b0) begin $display("FAILED to initialize: out == %b", out); $finish; end out <= #5 2'b1; if (out !== 2'b0) begin $display("FAILED -- changed immediately: out == %b", out); $finish; end #4 if (out !== 2'b0) begin $display("FAILED -- changed too soon: out == %b", out); $finish; end #2 if (out !== 2'b1) begin $display("FAILED to change after delay: out == %b", out); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/timebase.vhd000066400000000000000000000025301435245347300210360ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- The operation is: -- 1) An internal counter is initilaised to zero after a reset is received. -- 2) An enable allows an internal running counter to count clock pulses -- 3) A tick signal output is generated when a the number of pulses accumulated -- are equal to a specified parameter entity TimeBase is generic (N: in Natural := 12; VALUE: Natural := 1999); port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (N-1 downto 0) ); end TimeBase; architecture TimeBase_rtl of TimeBase is signal RunningCounter : std_logic_vector(N-1 downto 0); -- this is the N bit free running counter to allow a big count begin RunningCounterProcess : process (CLOCK) begin if ( CLOCK'event and CLOCK = '1') then if (RESET = '1') then RunningCounter <= (others => '0'); elsif ( ENABLE = '1') then RunningCounter <= RunningCounter + 1; end if; else RunningCounter <= RunningCounter; end if; end process; TICK <= '1' when (RunningCounter = VALUE) else '0'; COUNT_VALUE <= RunningCounter; end TimeBase_rtl; iverilog-12_0/ivtest/ivltests/timeform1.v000066400000000000000000000021721435245347300206360ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* */ `timescale 1ns / 1ns module main; initial begin #3 $display("$time = %t (unformatted)", $time); $timeformat(-6, 6, "ns", 12); $display("$time = %t (-6,6)", $time); $timeformat(-6, 1, "ns", 12); $display("$time = %t (-6,1)", $time); end endmodule // main iverilog-12_0/ivtest/ivltests/timeform2.v000066400000000000000000000020621435245347300206350ustar00rootroot00000000000000// // Copyright (c) 2003 Steve Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // `timescale 1ns / 1ps module main; task test; $display("time within task: %t", $time); endtask // test initial begin $timeformat(-9, 3, "ns", 6); #1 $display("time within module: %t", $time); test; end endmodule iverilog-12_0/ivtest/ivltests/timeliteral.v000066400000000000000000000054671435245347300212600ustar00rootroot00000000000000/* * From IEEE 1800-2012 * * 5.8 Time literals * * Time is written in integer or fixed-point format, followed without a space by a * time unit ( fs ps ns us ms s ). * For example: * 2.1ns * 40ps * The time literal is interpreted as a realtime value scaled to the current time * unit and rounded to the current time precision. */ module same; timeunit 1ps; timeprecision 1ps; function logic check_time; realtime result; check_time = 1'b1; result = 1ns; if (result != 1000.0) begin $display("Failed-same: Expected 1ns to be rounded to 1000.0, got %f", result); check_time = 1'b0; end result = 1ps; if (result != 1.0) begin $display("Failed-same: Expected 1ps to be rounded to 1.0, got %f", result); check_time = 1'b0; end result = 0.5ps; if (result != 1.0) begin $display("Failed-same: Expected 0.5ps to be rounded to 1.0, got %f", result); check_time = 1'b0; end result = 0.499ps; if (result != 0.0) begin $display("Failed-same: Expected 0.49ps to be rounded to 0.0, got %f", result); check_time = 1'b0; end endfunction endmodule module max; timeunit 100s; timeprecision 1fs; function logic check_time; realtime result; check_time = 1'b1; result = 1s; if (result != 1e-2) begin $display("Failed-max: Expected 1s to be rounded to 1.0e-2, got %f", result); check_time = 1'b0; end result = 0.5fs; if (result != 1e-17) begin $display("Failed-max: Expected 0.5fs to be rounded to 1.0e-17, got %f", result); check_time = 1'b0; end result = 0.499fs; if (result != 0.0) begin $display("Failed-max: Expected 0.49fs to be rounded to 0.0, got %f", result); check_time = 1'b0; end endfunction endmodule module top; timeunit 1ns; timeprecision 1ps; realtime result; logic passed; initial begin passed = 1'b1; result = 1ns; if (result != 1.0) begin $display("Failed: Expected 1ns to be rounded to 1.0, got %f", result); passed = 1'b0; end result = 1ps; if (result != 0.001) begin $display("Failed: Expected 1ps to be rounded to 0.001, got %f", result); passed = 1'b0; end result = 1.23456789ps; if (result != 0.001) begin $display("Failed: Expected 1.23456789ps to be rounded to 0.001, got %f", result); passed = 1'b0; end result = 0.5ps; if (result != 0.001) begin $display("Failed: Expected 0.5ps to be rounded to 0.001, got %f", result); passed = 1'b0; end result = 0.499ps; if (result != 0.0) begin $display("Failed: Expected 0.49ps to be rounded to 0.0, got %f", result); passed = 1'b0; end passed &= same.check_time(); passed &= max.check_time(); if (passed) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/timescale1.v000066400000000000000000000040101435245347300207530ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test checks that times within modules are scaled up to the * precision of the simulation. */ `timescale 100us / 1us module slow (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; end endmodule // slow `timescale 10us / 1us module fast (out); output out; reg out; initial begin #0 out = 0; #1 out = 1; end endmodule // fast `timescale 1us / 1us module main; wire slow, fast; slow m1 (slow); fast m2 (fast); initial begin #5 if (slow !== 1'b0) begin $display("FAILED"); $finish; end if (fast !== 1'b0) begin $display("FAILED"); $finish; end #10 if (slow !== 1'b0) begin $display("FAILED"); $finish; end if (fast !== 1'b1) begin $display("FAILED"); $finish; end #80 if (slow !== 1'b0) begin $display("FAILED"); $finish; end if (fast !== 1'b1) begin $display("FAILED"); $finish; end #10 if (slow !== 1'b1) begin $display("FAILED"); $finish; end if (fast !== 1'b1) begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/timescale2.v000066400000000000000000000005701435245347300207630ustar00rootroot00000000000000`timescale 1ns/1ns module main; submodule test(); endmodule // main `timescale 10ns/1ns module submodule; reg [63:0] val; initial begin #1 $display("$time = %0d", $time); val = $time; if (val !== 64'd1) begin $display("FAILED -- value is %0d (should be 1)", val); $finish; end $display("PASSED"); end endmodule // submodule iverilog-12_0/ivtest/ivltests/timescale3.v000066400000000000000000000001301435245347300207540ustar00rootroot00000000000000// This is an error since the timeunit is less than the precision. `timescale 1ns/10ns iverilog-12_0/ivtest/ivltests/tran-keeper.v000066400000000000000000000023111435245347300211430ustar00rootroot00000000000000module main; // Model a pin with a weak keeper circuit. The way this works: // If the pin value is 1, then attach a weak1 pullup, but // if the pin value is 0, attach a weak0 pulldown. wire pin; pullup (weak1) (keep1); pulldown (weak0) (keep0); tranif1 (pin, keep1, pin); tranif0 (pin, keep0, pin); // Logic to drive a value onto a pin. reg value, enable; bufif1 (pin, value, enable); initial begin value = 0; enable = 1; #1 if (pin !== 0) begin $display("FAILED -- value=%b, enable=%b, pin=%b", value, enable, pin); $finish; end // pin should hold its value after the drive is removed. enable = 0; #1 if (pin !== 0) begin $display("FAILED -- value=%b, enable=%b, pin=%b", value, enable, pin); $finish; end value = 1; enable = 1; #1 if (pin !== 1) begin $display("FAILED -- value=%b, enable=%b, pin=%b", value, enable, pin); $finish; end // pin should hold its value after the drive is removed. enable = 0; #1 if (pin !== 1) begin $display("FAILED -- value=%b, enable=%b, pin=%b", value, enable, pin); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/tran.v000066400000000000000000000065561435245347300177110ustar00rootroot00000000000000module test(); reg a, b; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; tran t1(a1, a2); tran t2(a2, a3); tran t3(a3, a4); tran t4(a4, a5); tran t5(a5, a6); tran t6(a6, a7); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; tran t11(a11, b11); tran t12(a12, b12); tran t13(a13, b13); tran t14(a14, b14); tran t15(a15, b15); tran t21(a21, b21); tran t22(a22, b22); tran t23(a23, b23); tran t24(a24, b24); tran t25(a25, b25); tran t31(a31, b31); tran t32(a32, b32); tran t33(a33, b33); tran t34(a34, b34); tran t35(a35, b35); tran t41(a41, b41); tran t42(a42, b42); tran t43(a43, b43); tran t44(a44, b44); tran t45(a45, b45); tran t51(a51, b51); tran t52(a52, b52); tran t53(a53, b53); tran t54(a54, b54); tran t55(a55, b55); task display_strengths; input ta, tb; begin a = ta; b = tb; #1; $display("a = %b b = %b", a, b); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz); display_strengths(1'bx, 1'bz); display_strengths(1'b0, 1'bz); display_strengths(1'b1, 1'bz); display_strengths(1'bz, 1'bx); display_strengths(1'bx, 1'bx); display_strengths(1'b0, 1'bx); display_strengths(1'b1, 1'bx); display_strengths(1'bz, 1'b0); display_strengths(1'bx, 1'b0); display_strengths(1'b0, 1'b0); display_strengths(1'b1, 1'b0); display_strengths(1'bz, 1'b1); display_strengths(1'bx, 1'b1); display_strengths(1'b0, 1'b1); display_strengths(1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/tranif0.v000066400000000000000000000130461435245347300203000ustar00rootroot00000000000000module test(); reg a, b, en; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; tranif0 t1(a1, a2, en); tranif0 t2(a2, a3, en); tranif0 t3(a3, a4, en); tranif0 t4(a4, a5, en); tranif0 t5(a5, a6, en); tranif0 t6(a6, a7, en); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; tranif0 t11(a11, b11, en); tranif0 t12(a12, b12, en); tranif0 t13(a13, b13, en); tranif0 t14(a14, b14, en); tranif0 t15(a15, b15, en); tranif0 t21(a21, b21, en); tranif0 t22(a22, b22, en); tranif0 t23(a23, b23, en); tranif0 t24(a24, b24, en); tranif0 t25(a25, b25, en); tranif0 t31(a31, b31, en); tranif0 t32(a32, b32, en); tranif0 t33(a33, b33, en); tranif0 t34(a34, b34, en); tranif0 t35(a35, b35, en); tranif0 t41(a41, b41, en); tranif0 t42(a42, b42, en); tranif0 t43(a43, b43, en); tranif0 t44(a44, b44, en); tranif0 t45(a45, b45, en); tranif0 t51(a51, b51, en); tranif0 t52(a52, b52, en); tranif0 t53(a53, b53, en); tranif0 t54(a54, b54, en); tranif0 t55(a55, b55, en); task display_strengths; input ta, tb, ten; begin a = ta; b = tb; en = ten; #1; $display("a = %b b = %b en = %b", a, b, en); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz, 1'bz); display_strengths(1'bz, 1'bz, 1'bx); display_strengths(1'bz, 1'bz, 1'b0); display_strengths(1'bz, 1'bz, 1'b1); display_strengths(1'bx, 1'bz, 1'bz); display_strengths(1'bx, 1'bz, 1'bx); display_strengths(1'bx, 1'bz, 1'b0); display_strengths(1'bx, 1'bz, 1'b1); display_strengths(1'b0, 1'bz, 1'bz); display_strengths(1'b0, 1'bz, 1'bx); display_strengths(1'b0, 1'bz, 1'b0); display_strengths(1'b0, 1'bz, 1'b1); display_strengths(1'b1, 1'bz, 1'bz); display_strengths(1'b1, 1'bz, 1'bx); display_strengths(1'b1, 1'bz, 1'b0); display_strengths(1'b1, 1'bz, 1'b1); display_strengths(1'bz, 1'bx, 1'bz); display_strengths(1'bz, 1'bx, 1'bx); display_strengths(1'bz, 1'bx, 1'b0); display_strengths(1'bz, 1'bx, 1'b1); display_strengths(1'bx, 1'bx, 1'bz); display_strengths(1'bx, 1'bx, 1'bx); display_strengths(1'bx, 1'bx, 1'b0); display_strengths(1'bx, 1'bx, 1'b1); display_strengths(1'b0, 1'bx, 1'bz); display_strengths(1'b0, 1'bx, 1'bx); display_strengths(1'b0, 1'bx, 1'b0); display_strengths(1'b0, 1'bx, 1'b1); display_strengths(1'b1, 1'bx, 1'bz); display_strengths(1'b1, 1'bx, 1'bx); display_strengths(1'b1, 1'bx, 1'b0); display_strengths(1'b1, 1'bx, 1'b1); display_strengths(1'bz, 1'b0, 1'bz); display_strengths(1'bz, 1'b0, 1'bx); display_strengths(1'bz, 1'b0, 1'b0); display_strengths(1'bz, 1'b0, 1'b1); display_strengths(1'bx, 1'b0, 1'bz); display_strengths(1'bx, 1'b0, 1'bx); display_strengths(1'bx, 1'b0, 1'b0); display_strengths(1'bx, 1'b0, 1'b1); display_strengths(1'b0, 1'b0, 1'bz); display_strengths(1'b0, 1'b0, 1'bx); display_strengths(1'b0, 1'b0, 1'b0); display_strengths(1'b0, 1'b0, 1'b1); display_strengths(1'b1, 1'b0, 1'bz); display_strengths(1'b1, 1'b0, 1'bx); display_strengths(1'b1, 1'b0, 1'b0); display_strengths(1'b1, 1'b0, 1'b1); display_strengths(1'bz, 1'b1, 1'bz); display_strengths(1'bz, 1'b1, 1'bx); display_strengths(1'bz, 1'b1, 1'b0); display_strengths(1'bz, 1'b1, 1'b1); display_strengths(1'bx, 1'b1, 1'bz); display_strengths(1'bx, 1'b1, 1'bx); display_strengths(1'bx, 1'b1, 1'b0); display_strengths(1'bx, 1'b1, 1'b1); display_strengths(1'b0, 1'b1, 1'bz); display_strengths(1'b0, 1'b1, 1'bx); display_strengths(1'b0, 1'b1, 1'b0); display_strengths(1'b0, 1'b1, 1'b1); display_strengths(1'b1, 1'b1, 1'bz); display_strengths(1'b1, 1'b1, 1'bx); display_strengths(1'b1, 1'b1, 1'b0); display_strengths(1'b1, 1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/tranif1.v000066400000000000000000000130461435245347300203010ustar00rootroot00000000000000module test(); reg a, b, en; wire a1, a2, a3, a4, a5, a6, a7; assign (supply1, supply0) a1 = a; tranif1 t1(a1, a2, en); tranif1 t2(a2, a3, en); tranif1 t3(a3, a4, en); tranif1 t4(a4, a5, en); tranif1 t5(a5, a6, en); tranif1 t6(a6, a7, en); wire a11, a12, a13, a14, a15, b11, b12, b13, b14, b15; wire a21, a22, a23, a24, a25, b21, b22, b23, b24, b25; wire a31, a32, a33, a34, a35, b31, b32, b33, b34, b35; wire a41, a42, a43, a44, a45, b41, b42, b43, b44, b45; wire a51, a52, a53, a54, a55, b51, b52, b53, b54, b55; assign (supply1, supply0) a11 = a, b11 = b; assign (supply1, strong0) a12 = a, b12 = b; assign (supply1, pull0) a13 = a, b13 = b; assign (supply1, weak0) a14 = a, b14 = b; assign (supply1, highz0) a15 = a, b15 = b; assign (strong1, supply0) a21 = a, b21 = b; assign (strong1, strong0) a22 = a, b22 = b; assign (strong1, pull0) a23 = a, b23 = b; assign (strong1, weak0) a24 = a, b24 = b; assign (strong1, highz0) a25 = a, b25 = b; assign ( pull1, supply0) a31 = a, b31 = b; assign ( pull1, strong0) a32 = a, b32 = b; assign ( pull1, pull0) a33 = a, b33 = b; assign ( pull1, weak0) a34 = a, b34 = b; assign ( pull1, highz0) a35 = a, b35 = b; assign ( weak1, supply0) a41 = a, b41 = b; assign ( weak1, strong0) a42 = a, b42 = b; assign ( weak1, pull0) a43 = a, b43 = b; assign ( weak1, weak0) a44 = a, b44 = b; assign ( weak1, highz0) a45 = a, b45 = b; assign ( highz1, supply0) a51 = a, b51 = b; assign ( highz1, strong0) a52 = a, b52 = b; assign ( highz1, pull0) a53 = a, b53 = b; assign ( highz1, weak0) a54 = a, b54 = b; tranif1 t11(a11, b11, en); tranif1 t12(a12, b12, en); tranif1 t13(a13, b13, en); tranif1 t14(a14, b14, en); tranif1 t15(a15, b15, en); tranif1 t21(a21, b21, en); tranif1 t22(a22, b22, en); tranif1 t23(a23, b23, en); tranif1 t24(a24, b24, en); tranif1 t25(a25, b25, en); tranif1 t31(a31, b31, en); tranif1 t32(a32, b32, en); tranif1 t33(a33, b33, en); tranif1 t34(a34, b34, en); tranif1 t35(a35, b35, en); tranif1 t41(a41, b41, en); tranif1 t42(a42, b42, en); tranif1 t43(a43, b43, en); tranif1 t44(a44, b44, en); tranif1 t45(a45, b45, en); tranif1 t51(a51, b51, en); tranif1 t52(a52, b52, en); tranif1 t53(a53, b53, en); tranif1 t54(a54, b54, en); tranif1 t55(a55, b55, en); task display_strengths; input ta, tb, ten; begin a = ta; b = tb; en = ten; #1; $display("a = %b b = %b en = %b", a, b, en); $display("a1(%v) a2(%v) a3(%v) a4(%v) a5(%v) a6(%v) a7(%v)", a1, a2, a3, a4, a5, a6, a7); $display("t11(%v %v) t12(%v %v) t13(%v %v) t14(%v %v) t15(%v %v)", a11, b11, a12, b12, a13, b13, a14, b14, a15, b15); $display("t21(%v %v) t22(%v %v) t23(%v %v) t24(%v %v) t25(%v %v)", a21, b21, a22, b22, a23, b23, a24, b24, a25, b25); $display("t31(%v %v) t32(%v %v) t33(%v %v) t34(%v %v) t35(%v %v)", a31, b31, a32, b32, a33, b33, a34, b34, a35, b35); $display("t41(%v %v) t42(%v %v) t43(%v %v) t44(%v %v) t45(%v %v)", a41, b41, a42, b42, a43, b43, a44, b44, a45, b45); $display("t51(%v %v) t52(%v %v) t53(%v %v) t54(%v %v) t55(%v %v)", a51, b51, a52, b52, a53, b53, a54, b54, a55, b55); end endtask initial begin display_strengths(1'bz, 1'bz, 1'bz); display_strengths(1'bz, 1'bz, 1'bx); display_strengths(1'bz, 1'bz, 1'b0); display_strengths(1'bz, 1'bz, 1'b1); display_strengths(1'bx, 1'bz, 1'bz); display_strengths(1'bx, 1'bz, 1'bx); display_strengths(1'bx, 1'bz, 1'b0); display_strengths(1'bx, 1'bz, 1'b1); display_strengths(1'b0, 1'bz, 1'bz); display_strengths(1'b0, 1'bz, 1'bx); display_strengths(1'b0, 1'bz, 1'b0); display_strengths(1'b0, 1'bz, 1'b1); display_strengths(1'b1, 1'bz, 1'bz); display_strengths(1'b1, 1'bz, 1'bx); display_strengths(1'b1, 1'bz, 1'b0); display_strengths(1'b1, 1'bz, 1'b1); display_strengths(1'bz, 1'bx, 1'bz); display_strengths(1'bz, 1'bx, 1'bx); display_strengths(1'bz, 1'bx, 1'b0); display_strengths(1'bz, 1'bx, 1'b1); display_strengths(1'bx, 1'bx, 1'bz); display_strengths(1'bx, 1'bx, 1'bx); display_strengths(1'bx, 1'bx, 1'b0); display_strengths(1'bx, 1'bx, 1'b1); display_strengths(1'b0, 1'bx, 1'bz); display_strengths(1'b0, 1'bx, 1'bx); display_strengths(1'b0, 1'bx, 1'b0); display_strengths(1'b0, 1'bx, 1'b1); display_strengths(1'b1, 1'bx, 1'bz); display_strengths(1'b1, 1'bx, 1'bx); display_strengths(1'b1, 1'bx, 1'b0); display_strengths(1'b1, 1'bx, 1'b1); display_strengths(1'bz, 1'b0, 1'bz); display_strengths(1'bz, 1'b0, 1'bx); display_strengths(1'bz, 1'b0, 1'b0); display_strengths(1'bz, 1'b0, 1'b1); display_strengths(1'bx, 1'b0, 1'bz); display_strengths(1'bx, 1'b0, 1'bx); display_strengths(1'bx, 1'b0, 1'b0); display_strengths(1'bx, 1'b0, 1'b1); display_strengths(1'b0, 1'b0, 1'bz); display_strengths(1'b0, 1'b0, 1'bx); display_strengths(1'b0, 1'b0, 1'b0); display_strengths(1'b0, 1'b0, 1'b1); display_strengths(1'b1, 1'b0, 1'bz); display_strengths(1'b1, 1'b0, 1'bx); display_strengths(1'b1, 1'b0, 1'b0); display_strengths(1'b1, 1'b0, 1'b1); display_strengths(1'bz, 1'b1, 1'bz); display_strengths(1'bz, 1'b1, 1'bx); display_strengths(1'bz, 1'b1, 1'b0); display_strengths(1'bz, 1'b1, 1'b1); display_strengths(1'bx, 1'b1, 1'bz); display_strengths(1'bx, 1'b1, 1'bx); display_strengths(1'bx, 1'b1, 1'b0); display_strengths(1'bx, 1'b1, 1'b1); display_strengths(1'b0, 1'b1, 1'bz); display_strengths(1'b0, 1'b1, 1'bx); display_strengths(1'b0, 1'b1, 1'b0); display_strengths(1'b0, 1'b1, 1'b1); display_strengths(1'b1, 1'b1, 1'bz); display_strengths(1'b1, 1'b1, 1'bx); display_strengths(1'b1, 1'b1, 1'b0); display_strengths(1'b1, 1'b1, 1'b1); end endmodule iverilog-12_0/ivtest/ivltests/tri0.v000066400000000000000000000030761435245347300176150ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module tests the basic behavior of a tri0 register. We use a ?: * to turn on/off the driver to the tri0 net and watch its value. * A tri0 net should pull to 0 when undriven, and follow the driver * otherwise. */ module main; reg enable, val; tri0 t0 = enable ? val : 1'bz; initial begin enable = 0; val = 0; #1 if (t0 !== 1'b0) begin $display("FAILED -- undriven t0 == %b", t0); $finish; end enable = 1; #1 if (t0 !== 1'b0) begin $display("FAILED -- driven-0 t0 == %b", t0); $finish; end val = 1; #1 if (t0 !== 1'b1) begin $display("FAILED -- driven-1 t0 == %b", t0); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/tri0b.v000066400000000000000000000031011435245347300177440ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module tests the basic behavior of a tri0 register. We use a ?: * to turn on/off the driver to the tri0 net and watch its value. * A tri0 net should pull to 0 when undriven, and follow the driver * otherwise. */ module main; reg enable, val; tri0 t0 = (~enable) ? 1'bz : val; initial begin enable = 0; val = 0; #1 if (t0 !== 1'b0) begin $display("FAILED -- undriven t0 == %b", t0); $finish; end enable = 1; #1 if (t0 !== 1'b0) begin $display("FAILED -- driven-0 t0 == %b", t0); $finish; end val = 1; #1 if (t0 !== 1'b1) begin $display("FAILED -- driven-1 t0 == %b", t0); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/tri1.v000066400000000000000000000030761435245347300176160ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This module tests the basic behavior of a tri1 register. We use a ?: * to turn on/off the driver to the tri1 net and watch its value. * A tri1 net should pull to 1 when undriven, and follow the driver * otherwise. */ module main; reg enable, val; tri1 t1 = enable ? val : 1'bz; initial begin enable = 0; val = 0; #1 if (t1 !== 1'b1) begin $display("FAILED -- undriven t1 == %b", t1); $finish; end enable = 1; #1 if (t1 !== 1'b0) begin $display("FAILED -- driven-0 t1 == %b", t1); $finish; end val = 1; #1 if (t1 !== 1'b1) begin $display("FAILED -- driven-1 t1 == %b", t1); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/tri2.v000066400000000000000000000013111435245347300176050ustar00rootroot00000000000000`timescale 1 ns / 1 ns module short(inout [7:0] p, input en); assign p = en ? 8'h55 : 8'hzz; endmodule module long(inout [15:0] p, input en); assign p = en ? 16'haaaa : 16'hzzzz; endmodule module main; wire [15:0] bus; reg l_en, s_en; integer fails=0; long l(.p(bus), .en(l_en)); short s(.p(bus[7:0]), .en(s_en)); initial begin // $dumpfile("tri.vcd"); // $dumpvars(3,main); l_en = 0; s_en = 0; #10; l_en = 1; #10; $display("s.p = %4x", s.p); if (s.p !== 8'haa) fails=1; #10; l_en = 0; s_en = 1; #10; $display("l.p = %4x", l.p); if (l.p !== 16'hzz55) fails=2; #10; s_en = 0; #10; if (fails == 0) $display("PASSED"); else $display("FAILED ",fails); end endmodule iverilog-12_0/ivtest/ivltests/tri3.v000066400000000000000000000005401435245347300176110ustar00rootroot00000000000000module test(); tri1 a; tri0 b; assign (pull1,pull0) a = 1'b0; assign (pull1,pull0) b = 1'b1; reg failed; initial begin failed = 0; #1; $display("a = %b, expect x", a); if (a !== 1'bx) failed = 1; $display("b = %b, expect x", b); if (b !== 1'bx) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/triand.v000066400000000000000000000030201435245347300202050ustar00rootroot00000000000000module main; reg a, b; triand net; assign net = a; assign net = b; initial begin a = 'b0; b = 'b0; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'b1; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'bx; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'bz; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'b1; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'bx; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'bz; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bx; b = 'bx; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bx; b = 'bz; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bz; b = 'bz; #1 if (net !== 1'bz) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/trior.v000066400000000000000000000030171435245347300200710ustar00rootroot00000000000000module main; reg a, b; trior net; assign net = a; assign net = b; initial begin a = 'b0; b = 'b0; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'b1; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'bx; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b0; b = 'bz; #1 if (net !== 1'b0) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'b1; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'bx; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'b1; b = 'bz; #1 if (net !== 1'b1) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bx; b = 'bx; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bx; b = 'bz; #1 if (net !== 1'bx) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end a = 'bz; b = 'bz; #1 if (net !== 1'bz) begin $display("FAILED -- a=%b, b=%b, net=%b", a, b, net); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/two_state_display.v000066400000000000000000000015021435245347300224650ustar00rootroot00000000000000module top; bit [2:-1] vec = 4'b1001; bit btvar = 0; byte bvar = 0; shortint svar = 0; int ivar = 0; longint lvar = 0; initial begin if ((vec[-1] != 1) && (vec[0] != 0) && (vec[1] != 0) && (vec[2] != 1)) begin $display("Failed to select vector bits correctly"); $finish; end $display("Vec: ", vec); $display("Bit: ", btvar); $display("Byte: ", bvar); $display("Short: ", svar); $display("Int: ", ivar); $display("Long: ", lvar); $display("Monitor results:"); $monitor("Time: ", $stime, "\n Bit: ", btvar, "\n Byte: ", bvar, "\n Short: ", svar, "\n Int: ", ivar, "\n Long: ", lvar); #1 btvar = 1; #1 bvar = 1; #1 svar = 1; #1 ivar = 1; #1 lvar = 1; end endmodule iverilog-12_0/ivtest/ivltests/types1.v000066400000000000000000000014041435245347300201550ustar00rootroot00000000000000/* * This is a simplified version of the test program for issue 1323691 * from the iverilog bugs database. */ `timescale 1ns/1ns module main; parameter early_empty=1; reg re; reg rc_isEmpty, rc_willBeEmpty; wire empty; assign empty = (early_empty!=0) ? rc_willBeEmpty && re || rc_isEmpty : rc_isEmpty; initial begin rc_isEmpty <= 1'bx; rc_willBeEmpty <= 1'b1; re <= 1'b0; rc_isEmpty <= 1'b0; #1 if (empty !== 1'b0) begin $display("FAILED -- empty == %b (s.b. 0)", empty); $finish; end rc_isEmpty <= 1; #1 if (empty !== 1'b1) begin $display("FAILED -- empty == %b (s.b. 1)", empty); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/ubyte_test.v000066400000000000000000000242611435245347300211250ustar00rootroot00000000000000// Ten basic tests in here: // 1. byte must be initialised before any initial or always block // 2. assignments to (unsigned) bytes with random numbers // 3. assignments to (unsigned) bytes with random values including X and Z // 4. converting unsigned integers to unsigned bytes // 5. converting signed integers to unsigned bytes // 6. converting integers including X and Z states to unsigned bytes // 7. trying unsigned sums (procedural, function, task and module) // 8. trying unsigned (truncated) mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed number to unsigned bytes (sign extension) module mu_add (input byte unsigned a, b, output byte unsigned sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter MAX = 256; parameter LEN = 8; // variables used as golden references reg unsigned [LEN-1:0] ar; // holds numbers reg unsigned [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg unsigned [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // types to be tested byte unsigned bu; // holds numbers byte unsigned bu_xz; // 'x and 'z are attempted on this byte unsigned bresult; // hold results from sums and mults byte unsigned mcaresult; // this is permanently wired to a module byte unsigned mabresult; // this is permanently wired to a module integer i; // continuous assigments // type LHS type RHS // --------- --------- // byte 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation mu_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if ( bu !== 8'b0 || bu_xz !== 8'b0 || bresult !== 8'b0 || mcaresult !== 8'b0 || mabresult !== 8'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving byte type with unsigned random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % MAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to byte: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned bytes // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to byte (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to unsigned bytes // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random}; #1; force bu = ui; #1; if (bu !== ui[LEN-1:0]) begin $display ("FAILED - incorrect truncation from unsigned integer to byte: %b", bu); $finish; end end release bu; // converting signed integers to unsigned bytes // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random % MAX/2; #1; force bu = si; #1; if (bu !== si[LEN-1:0]) begin $display ("FAILED - incorrect truncation from signed integer to byte: %b mismatchs %b", bu, si[7:0]); $finish; end end release bu; // converting signed integers having 'x 'z values into type unsigned bytes // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si[LEN-1:0]); si = {si[31:LEN], ar_xz}; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to byte: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying unsigned sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = {$random} % MAX; #1; bresult = bu + bu_xz; #1; if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned bytes: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // invoking byte sum function if ( fu_sum (bu, bu_xz) !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned bytes in function"); $finish; end // invoking byte sum task tu_sum (bu, bu_xz, bresult); if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned bytes in task: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // checking byte sum from module if ( mcaresult !== u_sum(ar, ar_xz) || mabresult !== u_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of unsigned bytes from module"); $finish; end end // trying unsigned mults: trucation is forced for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ({$random} % MAX) << LEN/2; ar_xz = ({$random} % MAX) << (LEN/2 -1); #1; bresult = bu * bu_xz; #1; if ( bresult !== u_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned bytes: %0d mismatchs %0d", bresult, u_mul(ar, ar_xz)); $finish; end // invoking byte mult function if ( fu_mul (bu, bu_xz) !== u_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect product of unsigned bytes in function"); $finish; end // invoking byte mult task tu_mul (bu, bu_xz, bresult); if ( bresult !== u_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect product of unsigned bytes in task: %0d mismatchs %0d", bresult, u_mul(ar, ar_xz)); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % MAX; ar_xz = {$random} % MAX; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on unsigned bytes"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on unsigned bytes"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on unsigned bytes"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on unsigned bytes"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on unsigned bytes"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on unsigned bytes"); $finish; end end # 1; // signed small number to unsigned byte for (i = 0; i < (1< * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: udp_jkff.v,v 1.2 2007/08/29 00:01:22 stevewilliams Exp $ module test_jkff; reg cp; reg j, k; reg s, r; reg qq; integer errors; initial errors = 0; initial begin cp <= 0; #10 {s,r, qq} <= 3'b 10_1; #10 {s,r, qq} <= 3'b 00_1; #10 {s,r, qq} <= 3'b x0_1; #10 {s,r, qq} <= 3'b 00_1; #10 {s,r, qq} <= 3'b 01_0; #10 {s,r, qq} <= 3'b 00_0; #10 {s,r, qq} <= 3'b x0_x; #10 {s,r, qq} <= 3'b 00_x; #10 {s,r, qq} <= 3'b 10_1; #10 {s,r, qq} <= 3'b 11_x; #10 {s,r, qq} <= 3'b 01_0; #10 {s,r, qq} <= 3'b 00_0; #10 {s,r, qq} <= 3'b 01_0; #10 {s,r, qq} <= 3'b 11_x; #10 {s,r, qq} <= 3'b 01_0; #10 {s,r, qq} <= 3'b 00_0; #10 {cp, j,k, qq} <= 4'b 0_00_0; #10 {cp, j,k, qq} <= 4'b 1_00_0; #10 {cp, j,k, qq} <= 4'b 0_01_0; #10 {cp, j,k, qq} <= 4'b 1_01_0; #10 {cp, j,k, qq} <= 4'b 0_11_0; #10 {cp, j,k, qq} <= 4'b 1_11_1; #10 {cp, j,k, qq} <= 4'b 0_11_1; #10 {cp, j,k, qq} <= 4'b 1_11_0; #10 {cp, j,k, qq} <= 4'b 0_00_0; #10 {cp, j,k, qq} <= 4'b x_00_0; #10 {cp, j,k, qq} <= 4'b 0_10_0; #10 {cp, j,k, qq} <= 4'b 1_10_1; #10 {cp, j,k, qq} <= 4'b x_10_1; #10 {cp, j,k, qq} <= 4'b 1_10_1; #10 {cp, j,k, qq} <= 4'b 0_10_1; #10 {cp, j,k, qq} <= 4'b x_10_1; #10 {cp, j,k, qq} <= 4'b 0_01_1; #10 {cp, j,k, qq} <= 4'b x_01_x; #10 {cp, j,k, qq} <= 4'b 1_01_x; #10 {cp, j,k, qq} <= 4'b 0_11_x; #10 {cp, j,k, qq} <= 4'b 1_11_x; #10 {cp, j,k, qq} <= 4'b 0_01_x; #10 {cp, j,k, qq} <= 4'b 1_01_0; #10 {cp, j,k, qq} <= 4'b x_11_0; #10 {cp, j,k, qq} <= 4'b 1_11_x; #10 {cp, j,k, qq} <= 4'b 0_10_x; #10 {cp, j,k, qq} <= 4'b 1_10_1; #10 {cp, j,k, qq} <= 4'b 0_00_1; #10; if (errors > 0) $display("FAILED"); else $display("PASSED"); #10 $finish; end wire q; `ifdef FAKE_UDP // to get a vvp template, from which to build a UDP test vvp and ff (q, j, k, s, r); `else jkff ff (q, cp, j, k, s, r); `endif always @(cp or j or k or s or r) begin #2; $display("cp=%b j=%b k=%b s=%b r=%b q=%b", cp, j, k, s, r, q); if (q !== qq && $time > 2) begin $display("FAILED: expect q=%b (time=%t)", qq, $time); errors = errors + 1; end end endmodule `ifdef FAKE_UDP `else primitive jkff(q, cp, j, k, s, r); output q; input cp, j, k, s, r; reg q; table // (cp) jk s r : q : q ; ? ?? (?0) 0 : ? : - ; ? ?? 0 (?0) : ? : - ; ? *? 0 0 : ? : - ; ? ?* 0 0 : ? : - ; ? ?? 1 0 : ? : 1 ; ? ?? 0 1 : ? : 0 ; ? ?? x 0 : 1 : 1 ; ? ?? 0 x : 0 : 0 ; (?0) ?? 0 0 : ? : - ; (1x) ?? 0 0 : ? : - ; (?1) 0? 0 0 : 0 : 0 ; (?1) ?0 0 0 : 1 : 1 ; (0x) 0? 0 0 : 0 : 0 ; (0x) ?0 0 0 : 1 : 1 ; (01) 1? 0 0 : 0 : 1 ; (01) ?1 0 0 : 1 : 0 ; (01) 10 0 0 : x : 1 ; (01) 01 0 0 : x : 0 ; endtable endprimitive `endif iverilog-12_0/ivtest/ivltests/udp_lfsr.v000066400000000000000000000067301435245347300205550ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephan Boettcher * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // $Id: udp_lfsr.v,v 1.1 2001/10/27 23:38:29 sib4 Exp $ module test_lfsr; reg cp; reg in; wire out; reg reset; lfsr sr(cp, reset, in, out); reg errors; initial errors = 0; integer i; initial begin in = 0; cp = 0; #2 reset = 1; #2 reset = 0; #1; for (i=0; i<512; i=i+1) #5 cp = ~cp; in = 0; cp = 0; #2 reset = 1; #2 reset = 0; #1; for (i=0; i<512; i=i+1) #5 cp <= ~cp; #5; if (errors == 0) $display("PASSED"); #10 $finish; end reg [7:0] here; reg [7:0] next; reg [7:0] old; reg [7:0] new; always @(reset) if (reset) begin here = 1; #1; old = {out, sr.s}; if (old === here) begin $display("%b RESET", old); end else begin $display("%b RESET FAILED: expect %b", old, here); errors = 1; end end always begin @(posedge cp) old = {out, sr.s}; next = {here[6:0], ^(here & sr.P) ^ in}; @(negedge cp) new = {out, sr.s}; if (old != here || new !== next) begin $display("%b->%b FAILED: expect %b->%b", old, new, here, next); errors = 1; end else begin $display("%b->%b", old, new); end here = next; end endmodule module lfsr (clk, reset, in, out); parameter P = 8'b 1101_1001; input clk; input reset; input in; output out; wire [6:0] s; wire i = ^{P & {out,s}} ^ in; jkff ff1 (s[0], clk, i, ~i, reset, 0); jkff ff2 (s[1], clk, s[0], ~s[0], 0, reset); jkff ff3 (s[2], clk, s[1], ~s[1], 0, reset); jkff ff4 (s[3], clk, s[2], ~s[2], 0, reset); jkff ff8 (out, clk, s[6], ~s[6], 0, reset); jkff ff7 (s[6], clk, s[5], ~s[5], 0, reset); jkff ff6 (s[5], clk, s[4], ~s[4], 0, reset); jkff ff5 (s[4], clk, s[3], ~s[3], 0, reset); endmodule primitive jkff(q, cp, j, k, s, r); output q; input cp, j, k, s, r; reg q; table // (cp) j k s r : q : q ; ? ? ? (?0) 0 : ? : - ; ? ? ? 0 (?0) : ? : - ; ? * ? 0 0 : ? : - ; ? ? * 0 0 : ? : - ; ? ? ? 1 0 : ? : 1 ; ? ? ? 0 1 : ? : 0 ; ? ? ? x 0 : 1 : 1 ; ? ? ? 0 x : 0 : 0 ; (?0) ? ? 0 0 : ? : - ; (1x) ? ? 0 0 : ? : - ; (?1) 0 ? 0 0 : 0 : 0 ; (?1) ? 0 0 0 : 1 : 1 ; (0x) 0 ? 0 0 : 0 : 0 ; (0x) ? 0 0 0 : 1 : 1 ; (01) 1 ? 0 0 : 0 : 1 ; (01) ? 1 0 0 : 1 : 0 ; (01) 1 0 0 0 : x : 1 ; (01) 0 1 0 0 : x : 0 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/udp_output_reg.v000066400000000000000000000010201435245347300217670ustar00rootroot00000000000000// Check that it is possible to have a `output reg` in a UDP defintion module test; reg clk = 1'b0; reg d = 1'b0; wire q; dff ff(q, clk, d); initial begin #1 clk = 1'b1; #1 clk = 1'b0; d = 1'b1; if (q === 1'b0) begin $display("PASSED"); end else begin $display("FAILED"); end end endmodule primitive dff(q, c, d); output reg q; input c, d; table //c d : q : q+ p 0 : ? : 0 ; p 1 : ? : 1 ; n ? : ? : - ; ? * : ? : - ; endtable endprimitive iverilog-12_0/ivtest/ivltests/udp_prop.v000066400000000000000000000014661435245347300205700ustar00rootroot00000000000000module test; reg cp; reg d; wire q; dff ff(q, cp, d); always begin #5 cp=0; #5 cp=1; end always begin @(negedge cp) d <= ~d; @(posedge cp) if (q !== 'bx && d === q) begin $display("FAILED, d=%b, q=%b", d, q); #1 $finish; end end initial begin #1 d <= 1; #22; $display("PASSED"); $finish; end initial $monitor($time,,cp,,d,,q); endmodule primitive dff(q, cp, d); output q; input cp, d; reg q; table // (cp) d : q : q ; ? * : ? : - ; (?0) ? : ? : - ; (1x) ? : ? : - ; (x1) 0 : 0 : 0 ; (x1) 1 : 1 : 1 ; (0x) 0 : 0 : 0 ; (0x) 1 : 1 : 1 ; (01) 0 : ? : 0 ; (01) 1 : ? : 1 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/udp_real_delay.v000066400000000000000000000014721435245347300217060ustar00rootroot00000000000000`timescale 1ns/100ps primitive udp_and( output y, input a, input b ); table //a b : y 0 0 : 0 ; 0 1 : 0 ; 1 0 : 0 ; 1 1 : 1 ; x 0 : 0 ; 0 x : 0 ; endtable endprimitive module test(); reg a; reg b; wire y; udp_and #0.5 gate(y, a, b); reg failed = 0; initial begin $monitor($realtime,,a,,b,,y); a = 0; b = 0; #0.6 if (y !== 1'b0) failed = 1; a = 1; b = 1; #0.4 if (y !== 1'b0) failed = 1; #0.2 if (y !== 1'b1) failed = 1; a = 0; b = 1; #0.4 if (y !== 1'b1) failed = 1; #0.2 if (y !== 1'b0) failed = 1; a = 1; b = 1; #0.4 if (y !== 1'b0) failed = 1; #0.2 if (y !== 1'b1) failed = 1; a = 1; b = 0; #0.4 if (y !== 1'b1) failed = 1; #0.2 if (y !== 1'b0) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/udp_sched.v000066400000000000000000000022051435245347300206660ustar00rootroot00000000000000/* * This test tries to assure that all synchronous UDP outputs are * scheduled before any non-blocking assignment event. The reason * is that primitive outputs are scheduled in the active event * queue, which is supposed to empty before any non-blocking * assignments take effect. * * This is based on an example by Steve Sharp */ primitive u_dff(q,d,c); output q; reg q; input d,c; table //d c : q : q+ 0 p : ? : 0 ; 1 p : ? : 1 ; ? n : ? : - ; * ? : ? : - ; endtable endprimitive module top; reg rclk, dclk; wire clk = rclk; wire q0,q1,q2,q3,q4; u_dff ff0(q0, 1'b1, clk), ff1(q1, 1'b1, q0), ff2(q2, 1'b1, q1), ff3(q3, 1'b1, q2), ff4(q4, 1'b1, q3); initial begin #1 // Blocking assign makes an active event that // starts the u_dff devices rippling rclk = 1; // Non-blocking assign and the following @(dclk) pause // the thread until the non-blocking event queue is // processed. dclk <= 1; @(dclk) if (q4 !== 1'b1) begin $display("FAILED -- q4 did not propagate in time (q4=%b)", q4); $finish; end $display("q4=%b", q4); $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/udp_x.v000066400000000000000000000040531435245347300200520ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program checks that conbinational UDPs with x outputs are * properly executed. */ module main; wire Y; reg A, B, S; muxx1 MUX2 ( Y, S, A, B ) ; initial begin S = 0; A = 0; B = 0; #1 if (Y !== 1'b0) begin $display("FAILED -- Y is %b", Y); $finish; end B = 1; #1 if (Y !== 1'b0) begin $display("FAILED -- Y is %b", Y); $finish; end S = 1; #1 if (Y !== 1'b1) begin $display("FAILED -- Y is %b", Y); $finish; end B = 1'bx; #1 if (Y !== 1'bx) begin $display("FAILED -- Y is %b", Y); $finish; end B = 1; S = 1'bx; #1 if (Y !== 1'bx) begin $display("FAILED -- Y is %b", Y); $finish; end B = 0; #1 if (Y !== 1'b0) begin $display("FAILED -- Y is %b", Y); $finish; end $display("PASSED"); end // initial begin endmodule primitive muxx1(Q, S, A, B); output Q; input S, A, B; table // S A B Q 0 0 ? : 0 ; 0 1 ? : 1 ; 0 x ? : x ; // problem line 1 ? 0 : 0 ; 1 ? 1 : 1 ; 1 ? x : x ; // problem line x 0 0 : 0 ; x 1 1 : 1 ; endtable endprimitive iverilog-12_0/ivtest/ivltests/ufuncsynth1.v000066400000000000000000000012631435245347300212220ustar00rootroot00000000000000module main; function [15:0] sum; input [15:0] a; input [15:0] b; sum = a + b; endfunction // sum reg clk; reg [15:0] d, e, out; (* ivl_synthesis_on *) always @(posedge clk) out <= sum(d, e); initial begin clk = 0; d = 0; e = 0; #1 clk = 1; #1 clk = 0; if (out !== 16'd0) begin $display("FAILED -- sum(%0d,%d) --> %0d", d, e, out); $finish; end d = 5; e = 13; #1 clk = 1; #1 clk = 0; if (out !== 16'd18) begin $display("FAILED -- sum(%0d,%d) --> %0d", d, e, out); $finish; end $display("PASSED"); $finish; end endmodule // main iverilog-12_0/ivtest/ivltests/uint_test.v000066400000000000000000000272321435245347300207550ustar00rootroot00000000000000// Eleven basic tests in here: // 1. int must be initialised before any initial or always block // 2. assignments to (unsigned) int with random numbers // 3. assignments to (unsigned) int with random values including X and Z // 4. converting unsigned integers to unsigned int // 5. converting signed integers to unsigned int // 6. converting integers including X and Z states to unsigned int // 7. trying unsigned sums (procedural, function, task and module) // 8. trying unsigned mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to unsigned int (signed extension) // 11. trying some concatenations from bytes, shortints to ints module mu_add (input int unsigned a, b, output int unsigned sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter UMAX = 'hffff_ffff; parameter MAX8 = 256; parameter MAX16 = 65536; parameter LEN = 32; // variables used as golden references reg unsigned [LEN-1:0] ar; // holds numbers reg unsigned [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg unsigned [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // type assumed tested before byte unsigned pt1, pt2; shortint unsigned ps1, ps2; // types to be tested int unsigned bu; // holds numbers int unsigned bu_xz; // 'x and 'z are attempted on this int unsigned bresult; // hold results from sums and mults int unsigned mcaresult; // wired to a module instance int unsigned mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // int 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation mu_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 32'b0 || bu_xz !== 32'b0 || bresult !== 32'b0 || mcaresult !== 32'b0 || mabresult !== 32'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving int type with unsigned random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random}; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to int: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned int // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = {$random}; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to int (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to unsigned int // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random}; #1; force bu = ui; #1; if (bu !== ui) begin $display ("FAILED - incorrect truncation from unsigned integer to int: %b", bu); $finish; end end release bu; // converting signed integers to unsigned ints // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random; #1; force bu = si; #1; if (bu !== si) begin $display ("FAILED - incorrect truncation from signed integer to int: %b mismatchs %b", bu, si); $finish; end end release bu; // converting integers having 'x 'z values into type unsigned int // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si); si = ar_xz; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to int: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying unsigned sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random}; ar_xz = {$random}; #1; bresult = bu + bu_xz; #1; if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned ints: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // invoking shortint sum function if ( fu_sum (bu, bu_xz) !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned int in function"); $finish; end // invoking byte sum task tu_sum (bu, bu_xz, bresult); if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned int in task: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // checking byte sum from module if ( mcaresult !== u_sum(ar, ar_xz) || mabresult !== u_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of unsigned int from module"); $finish; end end // trying unsigned mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ({$random} % UMAX) << (LEN/2); ar_xz = ({$random} % UMAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; // truncated multiplication #1; if ( bresult !== uh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of unsigned ints (truncated)"); $finish; end #1; ps1 = {$random} % 'hffff; ps2 = {$random} % 'hffff; #1; bresult = ps1 * ps2; // int = shortint x shortint #1; if ( bresult !== u_mul(ps1, ps2) ) begin $display ("FAILED - incorrect multiplication of unsigned input shorints"); $finish; end // invoking shortint mult function (byte*byte) if ( fu_mul (ps1, ps2) !== u_mul(ps1, ps2) ) begin $display ("FAILED - incorrect product of unsigned shortint for a function returning unsigned int"); $finish; end // invoking shortint mult task (byte*byte) tu_mul (ps1, ps2, bresult); if ( bresult !== u_mul(ps1, ps2) ) begin $display ("FAILED - incorrect product of unsigned shortint in task returning unsigned int"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random}; ar_xz = {$random}; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on unsigned ints"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on unsigned ints"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on unsigned ints"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on unsigned ints"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on unsigned ints"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on unsigned ints"); $finish; end end # 1; // signed small numbers to unsigned int for (i = 0; i < (1< '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to longint (when 'x 'z): %b", bu); $finish; end end // converting unsigned 64-bit integers (time) to unsigned longint // this should pass trivially for (i = 0; i< N_REPS; i = i+1) begin #1; ui = { {$random}, {$random} }; #1; force bu = ui; #1; if (bu !== ui) begin $display ("FAILED - incorrect assignment from 64-bit integer to longint: %b", bu); $finish; end end release bu; // converting signed integers to unsigned ints // keeping the same bit representation is expected for (i = 0; i< N_REPS; i = i+1) begin #1; ui = { {$random}, {$random} }; #1; force bu = -ui; #1; if (-bu !== ui) begin $display ("FAILED - incorrect assignment from 64-bit signed integer to longint: %d mismatchs %d", bu, -ui); $finish; end end release bu; // converting integers having 'x 'z values into type unsigned longint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; ui = { {$random}, {$random} }; ar_xz = xz_inject (ui); ui = ar_xz; ar_expected = xz_expected (ar_xz); #1; force bu_xz = ui; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from 64-bit integer (with 'x 'z) to longint: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying unsigned sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { {$random}, {$random} }; ar_xz = { {$random}, {$random} }; #1; bresult = bu + bu_xz; #1; if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned longints: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // invoking longint sum function if ( fu_sum (bu, bu_xz) !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned longint in function"); $finish; end // invoking longint sum task tu_sum (bu, bu_xz, bresult); if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned longint in task: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // checking longint sum from module if ( mcaresult !== u_sum(ar, ar_xz) || mabresult !== u_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of unsigned longtint from module"); $finish; end end // trying unsigned mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { {$random} % 32'd65536, {$random} % 32'd32768 }; ar_xz = { {$random} % 32'd32768, {$random} % 32'd65536 }; #1; bresult = bu * bu_xz; // truncated mult #1; if ( bresult !== uh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of unsigned longints: %0d mismatchs %0d", bresult, uh_mul(ar, ar_xz)); $finish; end #1; pv1 = {$random}; pv2 = {$random}; #1; bresult = pv1 * pv2; // longint = int x int #1; if ( bresult !== u_mul(pv1, pv2) ) begin $display ("FAILED - incorrect multiplication of unsigned longints for int inputs"); $finish; end // invoking longint mult function (int*int) if ( fu_mul (pv1, pv2) !== u_mul(pv1, pv2) ) begin $display ("FAILED - incorrect product of unsigned ints for a function returning unsigned longint"); $finish; end // invoking longint mult task (int*int) tu_mul (pv1, pv2, bresult); if ( bresult !== u_mul(pv1, pv2) ) begin $display ("FAILED - incorrect product of unsigned int in task returning unsigned longint"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = { {$random}, {$random} }; ar_xz = { {$random}, {$random} }; #1; if ( (bu < bu_xz ) != (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on unsigned longints"); $finish; end if ( (bu <= bu_xz ) != (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on unsigned longints"); $finish; end if ( (bu > bu_xz ) != (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on unsigned longints"); $finish; end if ( (bu >= bu_xz ) != (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on unsigned longints"); $finish; end if ( (bu == bu_xz ) != (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on unsigned longints"); $finish; end if ( (bu != bu_xz ) != (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on unsigned ints"); $finish; end end # 1; // signed small number to unsigned shorint for (i = 0; i < N_REPS; i = i+1) begin #1; slice = $random % 'h7fff_ffff; force bu = slice; ar = slice; #1; if (bu !== ar) begin $display ("FAILED - incorrect signed extend to unsigned longint"); $finish; end end release bu; // trying concatenations (and replication) for (i = 0; i< N_REPS; i = i+1) begin #1; pt1 = {$random} % MAX8; pt2 = {$random} % MAX8; #1; bresult = { {4{pt1}}, {4{pt2}} }; #1; if ( bresult[63:56] !== pt1 || bresult[55:48] !== pt1 || bresult[47:40] !== pt1 || bresult[39:32] !== pt1 || bresult[31:24] !== pt2 || bresult[23:16] !== pt2 || bresult[15:8] !== pt2 || bresult[7:0] !== pt2) begin $display ("FAILED - incorrect concatenation and replication of bytes into unsigned longints"); $finish; end #1; ps1 = {$random} % MAX16; ps2 = {$random} % MAX16; #1; bresult = { {2{ps1}}, {2{ps2}} }; #1; if ( bresult[63:48] !== ps1 || bresult[47:32] !== ps1 || bresult[31:16] !== ps2 || bresult[15:0] !== ps2) begin $display ("FAILED - incorrect concatenation and replication of shortint into unsigned long ints"); $finish; end #1; pv1 = {$random}; pv2 = {$random}; #1; bresult = { pv1, pv2 }; #1; if ( bresult[63:32] !== pv1 || bresult[31:0] !== pv2) begin $display ("FAILED - incorrect concatenation and replication of int into unsigned longints"); $finish; end end #1; $display("PASSED"); end // this returns X and Z states into bit random positions for a value function [LEN-1:0] xz_inject (input unsigned [LEN-1:0] value); integer i, k; time temp; begin temp = {$random, $random}; for (i=0; i %b", val, y); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unary_lnot2.v000066400000000000000000000020401435245347300212010ustar00rootroot00000000000000/* * Copyright (c) 2000 Chris Lattner * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; reg [3:0] val, y; initial begin val = 2; y = !{!val}; if (y !== 4'b0001) begin $display("FAILED -- !!4'b%b --> 4'b%b", val, y); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unary_lnot3.v000066400000000000000000000032561435245347300212140ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This checks that ! of x works properly. */ module main; reg x; reg [1:0] xx; initial begin if (1'bx !== 1'bx) begin $display("FAILED -- simple constant x does't compare."); $finish; end if (1'bx !== !1'bx) begin $display("FAILED -- !1'bx comes out wrong."); $finish; end x = 1'bx; if (x !== 1'bx) begin $display("FAILED -- variable x comes out wrong."); $finish; end x = !x; if (x !== 1'bx) begin $display("FAILED -- ! of variable x comes out wrong."); $finish; end xx = 2'bx0; if (xx !== 2'bx0) begin $display("FAILED -- variable x comes out wrong."); $finish; end x = !xx; if (x !== 1'bx) begin $display("FAILED -- ! of variable xx comes out wrong."); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_minus.v000066400000000000000000000023661435245347300213110ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [7:0] x, y; initial begin x = -4; if (x !== 8'hfc) begin $display("FAILED -- x = -4 --> %b", x); $finish; end x = 4; if (x !== 8'h04) begin $display("FAILED"); $finish; end y = -x; if (y !== 8'hfc) begin $display("FAILED -- y = -%b --> %b", x, y); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/unary_minus1.v000066400000000000000000000030271435245347300213650ustar00rootroot00000000000000// // Copyright (c) 2001 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - From PR 272 reported by Lennart Augustsson module test; reg clk; reg [31:0] x; reg [31:0] y; reg error; always@(posedge clk) x <= -y; always #2 clk = ~clk; initial begin clk = 0; error = 0; y = 0; #10; if( x !== 32'h0) begin error = 1; $display("FAILED - X should still be 0, and it's not"); end #10; y = 32'h11111111; #10; if(x !== 32'heeee_eeef) begin error = 1; $display("FAILED - X should still be EEEE_EEEF, rather x=%h",x); end #10; if(error == 0) $display("PASSED"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/unary_minus2.v000066400000000000000000000026241435245347300213700ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ `timescale 1ns / 1ns module U1 (OUT); parameter VALUE = -384; output [9:0] OUT; assign OUT = VALUE; endmodule module U2 (OUT); parameter VALUE = 96; output [9:0] OUT; assign OUT = VALUE; endmodule module main; wire [9:0] out1, out2; U1 u1 (out1); U2 u2 (out2); initial #1 begin if (out1 !== 10'h280) begin $display("FAILED -- out1 = %b", out1); $finish; end if (out2 !== 10'h060) begin $display("FAILED -- out2 = %b", out2); $finish; end $display("PASSED"); end // initial #1 endmodule // main iverilog-12_0/ivtest/ivltests/unary_minus3.v000066400000000000000000000022071435245347300213660ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test(); reg [7:0] test; wire [7:0] neg_test = -test; initial begin for (test = 0 ; test < 255 ; test = test + 1) begin #1 if (neg_test !== (-test)) begin $display("FAILED -- %b !== -%b", neg_test, test); $finish; end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unary_minus4.v000066400000000000000000000007331435245347300213710ustar00rootroot00000000000000module bug(); reg [15 : 0] in; reg sel; wire [31 : 0] result = { 16'd0, sel ? -in : in }; initial begin in = 100; sel = 0; #1 if (result !== 32'h0000_0064) begin $display("FAILED -- result=%h, sel=%b, in=%h", result, sel, in); $finish; end sel = 1; #1 if (result !== 32'h0000_ff9c) begin $display("FAILED == result=%h, sel=%b, in=%h, -in=%h", result, sel, in, -in); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unary_nand.v000066400000000000000000000026431435245347300210740ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary nand ~&(value) // module main; reg [3:0] vect; reg error; wire result; assign result = ~&(vect); initial begin error = 0; for(vect=4'b000;vect<4'b1111;vect = vect + 1) begin #1; if(result !== 1'b1) begin $display("FAILED - Unary nand ~&(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b1111; #1; if(result !== 1'b0) begin $display("FAILED - Unary nand ~&(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_nand2.v000066400000000000000000000027461435245347300211620ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary nand ~&(value) // // SJW - Make a version that uses behavioral code to implement ~& module main; reg [3:0] vect; reg error; reg result; initial begin error = 0; for(vect=4'b000;vect<4'b1111;vect = vect + 1) begin result = ~& vect; if(result !== 1'b1) begin $display("FAILED - Unary nand ~&(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b1111; result = ~& vect; if(result !== 1'b0) begin $display("FAILED - Unary nand ~&(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_nor.v000066400000000000000000000026411435245347300207500ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary nor ~|(value) // module main; reg [3:0] vect; reg error; wire result; assign result = ~|(vect); initial begin error = 0; for(vect=4'b0001;vect<4'b1111;vect = vect + 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary nor ~|(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; #1; if(result !== 1'b1) begin $display("FAILED - Unary nor |~(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_nor2.v000066400000000000000000000027151435245347300210340ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary nor ~|(value) // SJW - ~| in behavioral assignment to reg. module main; reg [3:0] vect; reg error; reg result; initial begin error = 0; for(vect=4'b0001;vect<4'b1111;vect = vect + 1) begin result = ~| vect; if(result !== 1'b0) begin $display("FAILED - Unary nor ~|(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; result = ~| vect; if(result !== 1'b1) begin $display("FAILED - Unary nor |~(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_not.v000066400000000000000000000024711435245347300207530ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [7:0] tmp; initial begin tmp = 8'b0; #1 if (tmp !== 8'b00000000) begin $display("FAILED to set tmp: %b", tmp); $finish; end tmp <= ~ 8'b0; #1 if (tmp !== 8'b11111111) begin $display("FAILED to set ~0: %b", tmp); $finish; end tmp <= ~tmp; #1 if (tmp !== 8'b00000000) begin $display("FAILED to invert tmp: %b", tmp); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/unary_or.v000066400000000000000000000026321435245347300205720ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary or |(value) // module main; reg [3:0] vect; reg error; wire result; assign result = |(vect); initial begin error = 0; for(vect=4'b0001;vect<4'b1111;vect = vect + 1) begin #1; if(result !== 1'b1) begin $display("FAILED - Unary or |(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; #1; if(result !== 1'b0) begin $display("FAILED - Unary or |(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_xnor1.v000066400000000000000000000032111435245347300212130ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary or ~^(value) // module main; reg [3:0] vect; reg error; wire result; assign result = ~^(vect); initial begin error = 0; for(vect=4'b0001;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary xnor ~^(%b)=%b",vect,result); error = 1'b1; end end #1; for(vect=4'b0011;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary xnor ~^(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; #1; if(result !== 1'b1) begin $display("FAILED - Unary xnor ~^(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_xnor2.v000066400000000000000000000032111435245347300212140ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary or ^~(value) // module main; reg [3:0] vect; reg error; wire result; assign result = ^~(vect); initial begin error = 0; for(vect=4'b0001;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary xnor ^~(%b)=%b",vect,result); error = 1'b1; end end #1; for(vect=4'b0011;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary xnor ^~(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; #1; if(result !== 1'b1) begin $display("FAILED - Unary xnor ^~(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/unary_xor.v000066400000000000000000000032011435245347300207530ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate unary or |(value) // module main; reg [3:0] vect; reg error; wire result; assign result = ^(vect); initial begin error = 0; for(vect=4'b0001;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b1) begin $display("FAILED - Unary xor ^(%b)=%b",vect,result); error = 1'b1; end end #1; for(vect=4'b0011;vect<4'b0000;vect = vect << 1) begin #1; if(result !== 1'b0) begin $display("FAILED - Unary xor ^(%b)=%b",vect,result); error = 1'b1; end end #1; vect = 4'b0000; #1; if(result !== 1'b0) begin $display("FAILED - Unary xor ^(%b)=%b",vect,result); error = 1'b1; end if(error === 0 ) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/uncon_drive.v000066400000000000000000000014021435245347300212410ustar00rootroot00000000000000module top; reg pass; highz dutz(); pulllow dut0(); pullhigh dut1(); initial begin pass = 1'b1; #10; if (pass) $display("PASSED"); end endmodule module highz(in); input in; initial #1 if (in !== 1'bz) begin $display("FAILED: high-Z of floating input port (%b)", in); top.pass = 1'b0; end endmodule `unconnected_drive pull0 module pulllow(in); input in; initial #1 if (in !== 1'b0) begin $display("FAILED: pull0 of floating input port (%b)", in); top.pass = 1'b0; end endmodule `nounconnected_drive `unconnected_drive pull1 module pullhigh(in); input in; initial #1 if (in !== 1'b1) begin $display("FAILED: pull1 of floating input port (%b)", in); top.pass = 1'b0; end endmodule `nounconnected_drive iverilog-12_0/ivtest/ivltests/undef.v000066400000000000000000000007131435245347300200330ustar00rootroot00000000000000/* * 1364-2001 19.3.2 "An undefined text macro has no value, just as if it had * never been defined." */ `define a 1 `ifdef a `define b 1 `else `define b 0 `endif `undef a `ifdef a `define c 1 `else `define c 0 `endif module test; initial begin if(`a+1 !== 1) begin $display("FAIL"); $finish; end if(`b+1 === 1) begin $display("FAIL"); $finish; end if(`c+1 !== 1) begin $display("FAIL"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select.v000066400000000000000000000054661435245347300224220ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [2:-1] vec; integer idx; initial begin pass = 1'b1; idx = 'bx; vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx] = 1'b1; `endif if (vec !== 4'bxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx] = 1'b1; if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx:0] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:0], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[0:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[0:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx+:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx+:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx-:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx-:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx+:1] = 1'b1; if (vec !== 4'bxxxx) begin $display("Failed vec[idx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx+:2] = 2'b01; if (vec !== 4'bxxxx) begin $display("Failed vec[idx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx-:1] = 1'b1; if (vec !== 4'bxxxx) begin $display("Failed vec[idx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx-:2] = 2'b01; if (vec !== 4'bxxxx) begin $display("Failed vec[idx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select2.v000066400000000000000000000055521435245347300225000ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [2:-1] vec; integer idx; initial begin pass = 1'b1; idx = 'bx; vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx] <= 1'b1; `endif #1 if (vec !== 4'bxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx] <= 1'b1; #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx:0] <= 1'b1; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:0], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[0:1'bx] <= 1'b1; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[0:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx:1'bx] <= 1'b1; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx+:1] <= 1'b1; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx+:2] <= 2'b01; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx-:1] <= 1'b1; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx-:2] <= 2'b01; `endif #1 if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx+:1] <= 1'b1; #1 if (vec !== 4'bxxxx) begin $display("Failed vec[idx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx+:2] <= 2'b01; #1 if (vec !== 4'bxxxx) begin $display("Failed vec[idx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx-:1] <= 1'b1; #1 if (vec !== 4'bxxxx) begin $display("Failed vec[idx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end vec = 4'bxxxx; vec[idx-:2] <= 2'b01; #1 if (vec !== 4'bxxxx) begin $display("Failed vec[idx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select3a.v000066400000000000000000000051501435245347300226340ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [2:-1] vec; initial begin pass = 1'b1; vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx] = 1'b1; `endif if (vec !== 4'bxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx:0] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:0], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx:0]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[0:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[0:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[0:1'bx]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx:1'bx]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx+:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx+:1]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx+:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx+:2]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx-:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx-:1]; `endif vec = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec[1'bx-:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST deassign vec[1'bx-:2]; `endif if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select3b.v000066400000000000000000000002201435245347300226260ustar00rootroot00000000000000module top; reg [2:-1] vec; integer idx; initial begin idx = 'bx; assign vec[idx] = 1'b1; deassign vec[idx]; end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select3c.v000066400000000000000000000002261435245347300226350ustar00rootroot00000000000000module top; reg [2:-1] vec; integer idx; initial begin idx = 'bx; assign vec[idx+:1] = 1'b1; deassign vec[idx+:1]; end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select4a.v000066400000000000000000000047321435245347300226420ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; wire [2:-1] vec; assign vec = 4'bxxxx; initial begin pass = 1'b1; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx] = 1'b1; `endif if (vec !== 4'bxxx) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx:0] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:0], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx:0]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[0:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[0:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[0:1'bx]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx:1'bx] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx:1'bx], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx:1'bx]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx+:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx+:1]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx+:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx+:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx+:2]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx-:1] = 1'b1; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:1], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx-:1]; `endif `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST force vec[1'bx-:2] = 2'b01; `endif if (vec !== 4'bxxxx) begin $display("Failed vec[1'bx-:2], expected 4'bxxxx, got %b", vec); pass = 1'b0; end `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST release vec[1'bx-:2]; `endif if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select4b.v000066400000000000000000000002171435245347300226350ustar00rootroot00000000000000module top; wire [2:-1] vec; integer idx; initial begin idx = 'bx; force vec[idx] = 1'b1; release vec[idx]; end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select4c.v000066400000000000000000000002251435245347300226350ustar00rootroot00000000000000module top; wire [2:-1] vec; integer idx; initial begin idx = 'bx; force vec[idx+:1] = 1'b1; release vec[idx+:1]; end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select5.v000066400000000000000000000026171435245347300225020ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; wire [2:-1] vec1; wire [2:-1] vec2; wire [2:-1] vec3; wire [2:-1] vec4; wire [2:-1] vec5; wire [2:-1] vec6; assign vec1 = 4'bxxxx; assign vec2 = 4'bxxxx; assign vec3 = 4'bxxxx; assign vec4 = 4'bxxxx; assign vec5 = 4'bxxxx; assign vec6 = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST assign vec1[1'bx] = 1'b1; assign vec2[1'bx:0] = 1'b1; assign vec3[0:1'bx] = 1'b1; assign vec4[1'bx:1'bx] = 1'b1; assign vec5[1'bx+:1] = 1'b1; assign vec6[1'bx-:1] = 1'b1; `endif initial begin pass = 1'b1; if (vec1 !== 4'bxxx) begin $display("Failed vec1, expected 4'bxxxx, got %b", vec1); pass = 1'b0; end if (vec2 !== 4'bxxx) begin $display("Failed vec2, expected 4'bxxxx, got %b", vec2); pass = 1'b0; end if (vec3 !== 4'bxxx) begin $display("Failed vec3, expected 4'bxxxx, got %b", vec3); pass = 1'b0; end if (vec4 !== 4'bxxx) begin $display("Failed vec4, expected 4'bxxxx, got %b", vec4); pass = 1'b0; end if (vec5 !== 4'bxxx) begin $display("Failed vec5, expected 4'bxxxx, got %b", vec5); pass = 1'b0; end if (vec6 !== 4'bxxx) begin $display("Failed vec6, expected 4'bxxxx, got %b", vec6); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undef_lval_select_SV.v000066400000000000000000000011011435245347300230100ustar00rootroot00000000000000`ifdef __ICARUS__ `define SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST `endif module top; reg pass; reg [1:-1][3:0] vec; initial begin pass = 1'b1; vec[1] = 4'bxxxx; vec[0] = 4'bxxxx; vec[-1] = 4'bxxxx; `ifdef SUPPORT_CONST_OUT_OF_RANGE_IN_IVTEST vec[1'bx] = 4'b1001; `endif if ((vec[1] !== 4'bxxx) && (vec[0] !== 4'bxxxx) && (vec[-1] !== 4'bxxxx)) begin $display("Failed vec[1'bx], expected 4'bxxxx, got %b, %b,%b", vec[1], vec[0], vec[-1]); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/undefined_shift.v000066400000000000000000000100231435245347300220630ustar00rootroot00000000000000// Check that when the right hand operand of a shift operation // contains 'x' or 'z' bits, the result is undefined. module test; reg pass; reg signed [3:0] lhs; reg [3:0] rhs; reg [3:0] res; wire [3:0] res1 = lhs << rhs; wire [3:0] res2 = lhs >> rhs; wire [3:0] res3 = lhs >>> rhs; wire [3:0] res4 = lhs << 4'b000x; wire [3:0] res5 = lhs >> 4'b00x0; wire [3:0] res6 = lhs >>> 4'b0z00; wire [3:0] res7 = 4'd1 << 4'b000x; wire [3:0] res8 = 4'd1 >> 4'b00x0; wire [3:0] res9 = 4'd1 >>> 4'b0z00; wire [3:0] res10 = 4'd0 << rhs; wire [3:0] res11 = 4'd0 >> rhs; wire [3:0] res12 = 4'd0 >>> rhs; initial begin pass = 1'b1; lhs = 4'd1; if (res1 !== 4'bxxxx) begin $display("FAILED test 1, expected 4'bxxxx, got 4'b%b", res1); pass = 1'b0; end if (res2 !== 4'bxxxx) begin $display("FAILED test 2, expected 4'bxxxx, got 4'b%b", res2); pass = 1'b0; end if (res3 !== 4'bxxxx) begin $display("FAILED test 3, expected 4'bxxxx, got 4'b%b", res3); pass = 1'b0; end if (res4 !== 4'bxxxx) begin $display("FAILED test 4, expected 4'bxxxx, got 4'b%b", res4); pass = 1'b0; end if (res5 !== 4'bxxxx) begin $display("FAILED test 5, expected 4'bxxxx, got 4'b%b", res5); pass = 1'b0; end if (res6 !== 4'bxxxx) begin $display("FAILED test 6, expected 4'bxxxx, got 4'b%b", res6); pass = 1'b0; end if (res7 !== 4'bxxxx) begin $display("FAILED test 7, expected 4'bxxxx, got 4'b%b", res7); pass = 1'b0; end if (res8 !== 4'bxxxx) begin $display("FAILED test 8, expected 4'bxxxx, got 4'b%b", res8); pass = 1'b0; end if (res9 !== 4'bxxxx) begin $display("FAILED test 9, expected 4'bxxxx, got 4'b%b", res9); pass = 1'b0; end if (res10 !== 4'bxxxx) begin $display("FAILED test 10, expected 4'bxxxx, got 4'b%b", res10); pass = 1'b0; end if (res11 !== 4'bxxxx) begin $display("FAILED test 11, expected 4'bxxxx, got 4'b%b", res11); pass = 1'b0; end if (res12 !== 4'bxxxx) begin $display("FAILED test 12, expected 4'bxxxx, got 4'b%b", res12); pass = 1'b0; end res = lhs << rhs; if (res !== 4'bxxxx) begin $display("FAILED test 13, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = lhs >> rhs; if (res !== 4'bxxxx) begin $display("FAILED test 14, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = lhs >>> rhs; if (res !== 4'bxxxx) begin $display("FAILED test 15, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = lhs << 4'b000x; if (res !== 4'bxxxx) begin $display("FAILED test 16, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = lhs >> 4'b00x0; if (res !== 4'bxxxx) begin $display("FAILED test 17, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = lhs >>> 4'b0z00; if (res !== 4'bxxxx) begin $display("FAILED test 18, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd1 << 4'b000x; if (res !== 4'bxxxx) begin $display("FAILED test 19, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd1 >> 4'b00x0; if (res !== 4'bxxxx) begin $display("FAILED test 20, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd1 >>> 4'b0z00; if (res !== 4'bxxxx) begin $display("FAILED test 21, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd0 << rhs; if (res !== 4'bxxxx) begin $display("FAILED test 22, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd0 >> rhs; if (res !== 4'bxxxx) begin $display("FAILED test 23, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end res = 4'd0 >>> rhs; if (res !== 4'bxxxx) begin $display("FAILED test 24, expected 4'bxxxx, got 4'b%b", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/union_packed_darray_fail.v000066400000000000000000000003051435245347300237230ustar00rootroot00000000000000// Check that declaring a dynamic array typed member in a packed union is an // error. module test; union packed { int x[]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/union_packed_queue_fail.v000066400000000000000000000002761435245347300235740ustar00rootroot00000000000000// Check that declaring a queue typed member in a packed union is an // error. module test; union packed { int x[$]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/union_packed_uarray_fail.v000066400000000000000000000003311435245347300237430ustar00rootroot00000000000000// Check that declaring an unpacked array typed member in a packed union is an // error. module test; struct packed { int x; shortint y[2]; } s; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/unnamed_block_var_decl.v000066400000000000000000000005651435245347300233770ustar00rootroot00000000000000// Check variable declarations in unnamed blocks // All of these should pass in SystemVerilog and all but the last should fail in // Verilog module test; initial begin integer x; end initial begin integer x; integer y; end initial begin integer x, y; end initial begin integer x; integer y; x = y; end initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unnamed_fork_var_decl.v000066400000000000000000000005441435245347300232430ustar00rootroot00000000000000// Check variable declarations in unnamed forks // All of these should pass in SystemVerilog and all should fail in Verilog module test; initial fork integer x; join initial fork integer x; integer y; join initial fork integer x, y; join initial fork integer x; integer y; x = y; join initial begin $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/unnamed_generate_block.v000066400000000000000000000020161435245347300234030ustar00rootroot00000000000000// Copyright 2007, Martin Whitaker. // This code may be freely copied for any purpose. module unnamed_generate_block(); localparam up = 1; wire [2:0] count1; wire [2:0] count2; wire [2:0] count3; generate if (up) count_up counter(count1); else count_down counter(count1); endgenerate generate if (up) begin:genblk1 count_up counter(count2); end else begin:genblk1 count_down counter(count2); end endgenerate count_down genblk01(count3); initial begin:genblk001 reg [2:0] count; #1 count = 4; #1 count = 5; #1 count = 6; #1 count = 7; end always @(genblk0001.counter.count) begin $display(genblk0001.counter.count); end //initial begin // $dumpfile("dump.vcd"); // $dumpvars; //end endmodule module count_up(output reg [2:0] count); initial begin #1 count = 0; #1 count = 1; #1 count = 2; #1 count = 3; end endmodule module count_down(output reg [2:0] count); initial begin #1 count = 3; #1 count = 2; #1 count = 1; #1 count = 0; end endmodule iverilog-12_0/ivtest/ivltests/unp_array_typedef.v000066400000000000000000000116531435245347300224570ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for typedefs using unpacked arrays (including dynamic arrays). module unp_array_typedef(); typedef logic [7:0] bit_darray []; typedef logic [15:0] bit_unparray [4]; typedef string string_darray []; typedef string string_unparray [2]; typedef real real_darray []; typedef real real_unparray [5]; typedef int int_darray []; typedef int int_unparray [3]; typedef struct packed { logic [7:0] high; logic [7:0] low; } word; typedef word word_darray []; typedef word word_unparray [2]; bit_darray bit_darr; bit_unparray bit_unparr; string_darray string_darr; string_unparray string_unparr; real_darray real_darr; real_unparray real_unparr; int_darray int_darr; int_unparray int_unparr; // TODO at the moment dynamic arrays of struct are not supported // word_darray word_darr; word_unparray word_unparr; initial begin // Bit type bit_darr = new[3]; bit_darr[0] = "a"; bit_darr[1] = "b"; bit_darr[2] = "c"; if(bit_darr[0] !== "a" || bit_darr[1] !== "b" || bit_darr[2] !== "c") begin $display("FAILED 1"); $finish(); end bit_unparr[0] = 16'h1234; bit_unparr[1] = 16'h5678; bit_unparr[2] = 16'h9abc; if(bit_unparr[0] !== 16'h1234 || bit_unparr[1] !== 16'h5678 || bit_unparr[2] !== 16'h9abc) begin $display("FAILED 2"); $finish(); end // String type string_darr = new[3]; string_darr[0] = "icarus"; string_darr[1] = "verilog"; string_darr[2] = "test"; if(string_darr[0] != "icarus" || string_darr[1] != "verilog" || string_darr[2] != "test") begin $display("FAILED 3"); $finish(); end string_unparr[0] = "test_string"; string_unparr[1] = "another test"; if(string_unparr[0] != "test_string" || string_unparr[1] != "another test") begin $display("FAILED 4"); $finish(); end // Real type real_darr = new[3]; real_darr[0] = -1.20; real_darr[1] = 2.43; real_darr[2] = 7.4; if(real_darr[0] != -1.20 || real_darr[1] != 2.43 || real_darr[2] != 7.4) begin $display("FAILED 5"); $finish(); end real_unparr[0] = 1.0; real_unparr[1] = 2.5; real_unparr[2] = 3.0; real_unparr[3] = 4.5; real_unparr[4] = 5.0; if(real_unparr[0] != 1.0 || real_unparr[1] != 2.5 || real_unparr[2] != 3.0 || real_unparr[3] != 4.5 || real_unparr[4] != 5.0) begin $display("FAILED 6"); $finish(); end // Integer type int_darr = new[3]; int_darr[0] = -3; int_darr[1] = 3; int_darr[2] = 72; if(int_darr[0] !== -3 || int_darr[1] != 3 || int_darr[2] != 72) begin $display("FAILED 7"); $finish(); end int_unparr[0] = 22; int_unparr[1] = 18; int_unparr[2] = 9; if(int_unparr[0] !== 22 || int_unparr[1] != 18 || int_unparr[2] != 9) begin $display("FAILED 8"); $finish(); end // Struct // TODO at the moment dynamic arrays of struct are not supported /* word_darr = new[3]; word_darr[0].high = 8'h11; word_darr[0].low = 8'h22; word_darr[1].high = 8'h33; word_darr[1].low = 8'h44; word_darr[2].high = 8'h55; word_darr[2].low = 8'h66; if(word_darr[0].low !== 8'h22 || word_darr[0].high !== 8'h11 || word_darr[1].low !== 8'h44 || word_darr[1].high !== 8'h33) begin word_darr[2].low !== 8'h66 || word_darr[2].high !== 8'h55) begin $display("FAILED 9"); $finish(); end*/ // TODO not available at the moment //word_unparr[0].high = 8'haa; //word_unparr[0].low = 8'h55; //word_unparr[1].high = 8'h02; //word_unparr[1].low = 8'h01; //if(word_unparr[0].low !== 8'h55 || word_unparr[0].high !== 8'haa || //word_unparr[1].low !== 8'h01 || word_unparr[1].high !== 8'h02) begin //$display("FAILED 10"); //$finish(); //end word_unparr[0] = 16'haa55; word_unparr[1] = 16'h0102; if(word_unparr[0] !== 16'haa55 || word_unparr[1] !== 16'h0102) begin $display("FAILED 10"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/urand.v000066400000000000000000000004561435245347300200470ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [31:0] var; integer ivar; wire [31:0] out = ivar + 2147483648; initial begin $monitor(var,, out); var = 0; ivar = -2147483648; repeat (60) begin #1 var = $urandom; ivar = $random; end end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/urand_r.v000066400000000000000000000004451435245347300203660ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [31:0] var; initial begin $monitor(var); var = 0; repeat (60) begin #1 var = $urandom_range(16,0); // #1 var = $urandom_range(4294967295,0); // #1 var = $urandom_range(-1,0); end end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/urand_r2.v000066400000000000000000000003151435245347300204440ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [31:0] var; initial begin $monitor(var); var = 0; repeat (60) begin #1 var = $urandom_range(0,16); end end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/urand_r3.v000066400000000000000000000003131435245347300204430ustar00rootroot00000000000000`begin_keywords "1364-2005" module top; reg [31:0] var; initial begin $monitor(var); var = 0; repeat (60) begin #1 var = $urandom_range(16); end end endmodule `end_keywords iverilog-12_0/ivtest/ivltests/ushortint_test.v000066400000000000000000000266701435245347300220420ustar00rootroot00000000000000// Eleven basic tests in here: // 1. shortint must be initialised before any initial or always block // 2. assignments to (unsigned) shortint with random numbers // 3. assignments to (unsigned) shortint with random values including X and Z // 4. converting unsigned integers to unsigned shortint // 5. converting signed integers to unsigned shortint // 6. converting integers including X and Z states to unsigned shortint // 7. trying unsigned sums (procedural, function, task and module) // 8. trying unsigned mults (procedural, function and task) // 9. trying relational operators // 10. smaller signed numbers to unsigned shortint (signed extension) // 11. trying some concatenations from bytes to shortints module mu_add (input shortint unsigned a, b, output shortint unsigned sc, ss); assign sc = a + b; always @(a, b) ss = a + b; endmodule module main; parameter N_REPS = 500; // repetition with random numbers parameter XZ_REPS = 500; // repetition with 'x 'z values parameter UMAX = 65536; parameter MAX8 = 256; parameter LEN = 16; // variables used as golden references reg unsigned [LEN-1:0] ar; // holds numbers reg unsigned [LEN-1:0] ar_xz; // holds 'x and/or 'z in random positions reg unsigned [LEN-1:0] ar_expected; integer unsigned ui; integer signed si; reg signed [LEN/2-1:0] slice; // type assumed tested before byte unsigned pt1, pt2; // types to be tested shortint unsigned bu; // holds numbers shortint unsigned bu_xz; // 'x and 'z are attempted on this shortint unsigned bresult; // hold results from sums and mults shortint unsigned mcaresult; // wired to a module instance shortint unsigned mabresult; // also wired to a module instance integer i; // continuous assigments // type LHS type RHS // --------- --------- // shortint 4-value logic assign bu = ar; assign bu_xz = ar_xz; // module instantiation mu_add duv (.a(bu), .b(bu_xz), .sc(mcaresult), .ss(mabresult) ); // all test initial begin // time 0 checkings (Section 6.4 of IEEE 1850 LRM) if (bu !== 16'b0 || bu_xz !== 16'b0 || bresult !== 16'b0 || mcaresult !== 16'b0 || mabresult !== 16'b0) begin $display ("FAILED - time zero initialisation incorrect: %b %b", bu, bu_xz); $finish; end // driving shortint type with unsigned random numbers from a variable for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; #1; if (bu !== ar) begin $display ("FAILED - incorrect assigment to shortint: %b", bu); $finish; end end # 1; // attempting to drive variables having 'x 'z values into type unsigned shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< XZ_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = xz_inject (ar); ar_expected = xz_expected (ar_xz); #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect assigment to shortint (when 'x 'z): %b", bu); $finish; end end // converting unsigned integers to unsigned shortint // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; ui = {$random} % UMAX; #1; force bu = ui; #1; if (bu !== ui[LEN-1:0]) begin $display ("FAILED - incorrect truncation from unsigned integer to shortint: %b", bu); $finish; end end release bu; // converting signed integers to unsigned shortints // truncation expected (Section 4.3.2 of IEEE 1850 LRM) for (i = 0; i< N_REPS; i = i+1) begin #1; si = $random % UMAX/2-1; #1; force bu = si; #1; if (bu !== si[LEN-1:0]) begin $display ("FAILED - incorrect truncation from signed integer to shortint: %b mismatchs %b", bu, si[LEN-1:0]); $finish; end end release bu; // converting integers having 'x 'z values into type unsigned shortint // 'x 'z injections (Section 4.3.2 of IEEE 1850 LRM) // truncation and coercion to zero expected for (i = 0; i< XZ_REPS; i = i+1) begin #1; si = $random; ar_xz = xz_inject (si[LEN-1:0]); si = {si[31:LEN], ar_xz}; ar_expected = xz_expected (ar_xz); #1; force bu_xz = si; #1; if (bu_xz !== ar_expected) // 'x -> '0, 'z -> '0 begin $display ("FAILED - incorrect conversion from integer (with 'x 'z) to shortint: %b mismatchs %b", bu_xz, ar_expected); $finish; end end release bu_xz; // trying unsigned sums for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = {$random} % UMAX; #1; bresult = bu + bu_xz; #1; if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortints: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // invoking shortint sum function if ( fu_sum (bu, bu_xz) !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortint in function"); $finish; end // invoking byte sum task tu_sum (bu, bu_xz, bresult); if ( bresult !== u_sum(ar, ar_xz) ) begin $display ("FAILED - incorrect addition of unsigned shortint in task: %0d mismatchs %0d", bresult, u_sum(ar, ar_xz)); $finish; end // checking shortint sum from module if ( mcaresult !== u_sum(ar, ar_xz) || mabresult !== u_sum(ar, ar_xz)) begin $display ("FAILED - incorrect addition of unsigned shortint from module"); $finish; end end // trying unsigned mults for (i = 0; i< N_REPS; i = i+1) begin #1; ar = ({$random} % UMAX) << LEN/2; ar_xz = ({$random} % UMAX) << (LEN/2 - 1); #1; bresult = bu * bu_xz; // truncated multiplication #1; if ( bresult !== uh_mul(ar, ar_xz) ) begin $display ("FAILED - incorrect multiplication of unsigned shortints (truncated)"); $finish; end #1; pt1 = {$random}; pt2 = {$random}; #1; bresult = pt1 * pt2; // shortint = byte x byte #1; if ( bresult !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect multiplication of unsigned shortints for bytes inputs"); $finish; end // invoking shortint mult function (byte*byte) if ( fu_mul (pt1, pt2) !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of unsigned bytes for a function returning unsigned shortint"); $finish; end // invoking shortint mult task (byte*byte) tu_mul (pt1, pt2, bresult); if ( bresult !== u_mul(pt1, pt2) ) begin $display ("FAILED - incorrect product of unsigned bytes in task returning unsigned shortint"); $finish; end end // trying relational operators for (i = 0; i< N_REPS; i = i+1) begin #1; ar = {$random} % UMAX; ar_xz = {$random} % UMAX; #1; if ( (bu < bu_xz ) !== (ar < ar_xz) ) begin $display ("FAILED - incorrect 'less than' on unsigned shortints"); $finish; end if ( (bu <= bu_xz ) !== (ar <= ar_xz) ) begin $display ("FAILED - incorrect 'less than or equal' on unsigned shortints"); $finish; end if ( (bu > bu_xz ) !== (ar > ar_xz) ) begin $display ("FAILED - incorrect 'greater than' on unsigned shortints"); $finish; end if ( (bu >= bu_xz ) !== (ar >= ar_xz) ) begin $display ("FAILED - incorrect 'greater than or equal' than on unsigned shortints"); $finish; end if ( (bu == bu_xz ) !== (ar == ar_xz) ) begin $display ("FAILED - incorrect 'equal to' on unsigned shortints"); $finish; end if ( (bu != bu_xz ) !== (ar != ar_xz) ) begin $display ("FAILED - incorrect 'not equal to' on unsigned shortints"); $finish; end end # 1; // signed small number to unsigned shorint for (i = 0; i < (1< width) port map (clk => clk, din => d_path(i), bin => b_path(i), reset => reset, xin => x_path(i), lin => l_int(i), dout => d_path(i+1), bout => b_path(i+1), xout => x_path(i+1), lout => l_int(i+1) ); end generate; d_path(0) <= din; b_path(0) <= bin; x_path(0) <= xin; l_int(0) <= lin; dout <= d_path(size); bout <= b_path(size); xout <= x_path(size); lout <= l_int(size); end systolic; library ieee; use ieee.std_logic_1164.all; use work.diq_pkg.all; entity diq is generic (n: integer := 8); port (clk, reset: in std_logic; din,bin,xin: in std_logic_vector (n-1 downto 0); lin: in std_logic_vector (2 downto 0); dout,bout,xout: out std_logic_vector (n-1 downto 0); lout: out std_logic_vector (2 downto 0) ); end diq; architecture diq_wordlevel of diq is signal b_int, d_int, x_int, x_inv: std_logic_vector (n-1 downto 0); signal l_int, l_inc: std_logic_vector (2 downto 0); signal sel: std_logic; signal zero,uno: std_logic; begin d_reg: process(clk,reset) begin if reset = '1' then d_int <= (others => '0'); elsif (clk'event and clk = '1') then d_int <= din; end if; end process; l_reg: process(clk,reset) begin if reset = '1' then l_int <= (others => '0'); elsif (clk'event and clk = '1') then l_int <= lin; end if; end process; b_reg: process(clk,reset) begin if reset = '1' then b_int <= (others => '0'); elsif (clk'event and clk = '1') then b_int <= bin; end if; end process; x_reg: process(clk,reset) begin if reset = '1' then x_int <= (others => '0'); elsif (clk'event and clk = '1') then x_int <= xin; end if; end process; zero <= '0'; uno <= '1'; addition: Add_Synth generic map (n => n) port map (a => b_int, b => d_int, cin => zero, comp => open, sum => bout); x_inv <= not x_int; comparison: Add_Synth generic map (n => n) port map (a => b_int, b => x_inv, cin => uno, comp => sel, sum => open); incrementer: Inc_Synth generic map (n => 3) port map (a => l_int, sum => l_inc); -- outputs lout <= l_inc when (sel = '1') else l_int; dout <= d_int; xout <= x_int; end diq_wordlevel; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Inc_Synth is generic (n: integer := 8); port (a: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0) ); end Inc_Synth; architecture compact_inc of Inc_Synth is signal cx: std_logic_vector (n downto 0); begin cx <= ('0' & a) + '1'; sum <= cx (n-1 downto 0); end compact_inc; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Add_Synth is generic (n: integer := 8); port (a, b: in std_logic_vector (n-1 downto 0); sum: out std_logic_vector (n-1 downto 0); cin: in std_logic; comp: out std_logic ); end Add_Synth; architecture compact of Add_Synth is signal cx: std_logic_vector (n downto 0); begin cx <= ('0' & a) + ('0' & b) + cin; sum <= cx (n-1 downto 0); comp <= cx(n-1); end compact; iverilog-12_0/ivtest/ivltests/varrshft.v000066400000000000000000000052331435245347300205730ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate variable right shift in assign module main; reg globvar; reg [7:0] var1,var2,var3; reg error; wire [7:0] value; assign value = var1 >> var2; initial begin error = 0; #1 ; var1 = 8'h80; var2 = 8'h7; #1; if(value !== 8'h1) begin error = 1; $display ("FAILED - 80 >> 7 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h6; #1; if(value !== 8'h2) begin error = 1; $display ("FAILED - 80 >> 6 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h5; #1; if(value !== 8'h4) begin error = 1; $display ("FAILED - 80 >> 5 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h4; #1; if(value !== 8'h8) begin error = 1; $display ("FAILED - 80 >> 4 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h3; #1; if(value !== 8'h10) begin error = 1; $display ("FAILED - 80 >> 3 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h2; #1; if(value !== 8'h20) begin error = 1; $display ("FAILED - 80 >> 2 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h1; #1; if(value !== 8'h40) begin error = 1; $display ("FAILED - 80 >> 1 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h0; #1; if(value !== 8'h80) begin error = 1; $display ("FAILED - 80 >> 0 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h7; #1; if(value !== 8'h01) begin error = 1; $display ("FAILED - a5 >> 7 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h1; #1; if(value !== 8'h52) begin error = 1; $display ("FAILED - aa >> 1 is %h",value); end if(error === 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/varrshft1.v000066400000000000000000000052561435245347300206610ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate variable right shift in always module main; reg globvar; reg [7:0] var1,var2,var3; reg error; reg [7:0] value; always @(var1 or var2) value = var1 >> var2; initial begin error = 0; #1 ; var1 = 8'h80; var2 = 8'h7; #1; if(value !== 8'h1) begin error = 1; $display ("FAILED - 80 >> 7 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h6; #1; if(value !== 8'h2) begin error = 1; $display ("FAILED - 80 >> 6 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h5; #1; if(value !== 8'h4) begin error = 1; $display ("FAILED - 80 >> 5 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h4; #1; if(value !== 8'h8) begin error = 1; $display ("FAILED - 80 >> 4 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h3; #1; if(value !== 8'h10) begin error = 1; $display ("FAILED - 80 >> 3 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h2; #1; if(value !== 8'h20) begin error = 1; $display ("FAILED - 80 >> 2 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h1; #1; if(value !== 8'h40) begin error = 1; $display ("FAILED - 80 >> 1 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h0; #1; if(value !== 8'h80) begin error = 1; $display ("FAILED - 80 >> 0 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h7; #1; if(value !== 8'h01) begin error = 1; $display ("FAILED - a5 >> 7 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h1; #1; if(value !== 8'h52) begin error = 1; $display ("FAILED - aa >> 1 is %h",value); end if(error === 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/varrshft2.v000066400000000000000000000060101435245347300206470ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate variable right shift in function module main; reg globvar; reg [7:0] var1,var2,var3; reg error; reg [7:0] value; function [7:0] rshft; input [7:0] var1,var2; begin rshft = var1 >> var2; end endfunction initial begin error = 0; #1 ; var1 = 8'h80; var2 = 8'h7; value = rshft(var1,var2); #1; if(value !== 8'h1) begin error = 1; $display ("FAILED - 80 >> 7 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h6; value = rshft(var1,var2); #1; if(value !== 8'h2) begin error = 1; $display ("FAILED - 80 >> 6 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h5; value = rshft(var1,var2); #1; if(value !== 8'h4) begin error = 1; $display ("FAILED - 80 >> 5 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h4; value = rshft(var1,var2); #1; if(value !== 8'h8) begin error = 1; $display ("FAILED - 80 >> 4 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h3; value = rshft(var1,var2); #1; if(value !== 8'h10) begin error = 1; $display ("FAILED - 80 >> 3 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h2; value = rshft(var1,var2); #1; if(value !== 8'h20) begin error = 1; $display ("FAILED - 80 >> 2 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h1; value = rshft(var1,var2); #1; if(value !== 8'h40) begin error = 1; $display ("FAILED - 80 >> 1 is %h",value); end #1 ; var1 = 8'h80; var2 = 8'h0; value = rshft(var1,var2); #1; if(value !== 8'h80) begin error = 1; $display ("FAILED - 80 >> 0 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h7; value = rshft(var1,var2); #1; if(value !== 8'h01) begin error = 1; $display ("FAILED - a5 >> 7 is %h",value); end #1 ; var1 = 8'ha5; var2 = 8'h1; value = rshft(var1,var2); #1; if(value !== 8'h52) begin error = 1; $display ("FAILED - aa >> 1 is %h",value); end if(error === 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/vcd-dup.v000066400000000000000000000022561435245347300203000ustar00rootroot00000000000000module test; reg a, b1, b2; submod m1 (a, b1, c1); submod m2 (a, b2, c2); task set; input [2:0] bits; reg t1; begin t1 <= a; #1 {a,b1,b2} <= bits; end endtask initial begin $dumpfile("work/vcd-dup.vcd"); $dumpvars(2, test); // test, test.m1, test.m2 $dumpvars(3, m2.c1, m1.mm1.c1); // duplicate signals #0; // does not trip $enddefinitions a = 0; // does not trip $enddefinitions $dumpvars(0, m1); // (test.m1), test.m1.mm1, test.m1.mm2 #1; // $enddefinitions called $dumpvars(0, m2); // ignored end initial begin #1 set(3'd 0); #1; #1 set(3'd 1); #1; #1 set(3'd 2); #1 $dumpoff; #1 set(3'd 3); #1; #1 set(3'd 4); #1 $dumpon; #1 set(3'd 5); #1; #1 set(3'd 6); #1; #1 set(3'd 7); #1; #1 set(3'd 0); #1 $dumpall; #1 $finish; end endmodule module submod (a, b, c); input a, b; output c; subsub mm1 (a&b, c1); subsub mm2 (a|b, c2); assign c = c1 ^ c2; endmodule module subsub (a, c); input a; output c; wire c1 = ~a; assign c = c1; endmodule iverilog-12_0/ivtest/ivltests/vcd1.v000066400000000000000000000033161435245347300175710ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate declared wire and implicit wires displayed. // // This circuit has 3 i/os and 3 implicit wires. Both should be // present in vcd file?? module xorckt (out,in0,in1); input in0; input in1; wire junk; nand #1 na1 (na1_out,in0,in1); nand #1 na2 (na2_out,in0,na1_out); nand #1 na3 (na3_out,in1,na1_out); nand #1 na4 (out,na2_out,na3_out); assign junk = in0; endmodule module main; wire xout; reg i1,i2; xorckt myckt (.out(xout),.in0(i1),.in1(i2)); initial begin $dumpfile("work/test.vcd"); $dumpvars(0,main.myckt); i1 = 1'b0; i2 = 1'b0; #5; $display("%b xor %b = %b",i1,i2,xout); i1 = 1'b1; i2 = 1'b0; #5; $display("%b xor %b = %b",i1,i2,xout); i1 = 1'b1; i2 = 1'b1; #5; $display("%b xor %b = %b",i1,i2,xout); i1 = 1'b0; i2 = 1'b1; #5 ; $display("%b xor %b = %b",i1,i2,xout); end endmodule // main iverilog-12_0/ivtest/ivltests/vector.v000066400000000000000000000031751435245347300202410ustar00rootroot00000000000000/* * Copyright (c) 2001 Brendan J Simon * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // test case to show vector ordering bugs. module test; reg [4:0] foo40; // works great. reg [0:4] foo04; // only works for time=0; //reg [4:0] foo04; reg [5:1] foo51; // never works. //reg [4:0] foo51; reg [1:5] foo15; // never works. //reg [4:0] foo15; initial begin #102; $finish(0); end initial #1 begin foo40 = 0; foo04 = 0; foo51 = 0; foo15 = 0; end always #10 begin foo40 <= foo40 + 1; foo04 <= foo04 + 1; foo51 <= foo51 + 1; foo15 <= foo15 + 1; end always @(foo40) begin $write("foo40=%8d\n", foo40); end always @(foo04) begin $write(" foo04=%8d\n", foo04); end always @(foo51) begin $write(" foo51=%8d\n", foo51); end always @(foo15) begin $write(" foo15=%8d\n", foo15); end endmodule iverilog-12_0/ivtest/ivltests/verify_two_var_delays.v000066400000000000000000000051471435245347300233460ustar00rootroot00000000000000`timescale 1ns/10ps module top; reg pass; real rise, fall, delay, base, diff; reg in, ctl; wire out, outif0; buf #(rise, fall) dut(out, in); bufif0 #(rise, fall) dutif0(outif0, in, ctl); // Check that the buffer output has the correct value and changed at the // correct time. always @(out) begin if ((in === 1'bz && out !== 1'bx) || (in !== 1'bz && out !== in)) begin $display("in (%b) !== out (%b) at %.1f", in, out, $realtime); pass = 1'b0; end diff = $realtime - (base + delay); if (diff < 0.0) diff = -diff; if (diff >= 0.01) begin $display("Incorrect buf delay at %.1f, got %.1f, expected %.1f", base, $realtime-base, delay); pass = 1'b0; end end // Check that the bufif0 output has the correct value and changed at the // correct time. always @(outif0) begin if (ctl) begin if (outif0 !== 1'bz) begin $display("outif0 (%b) !== 1'bz at %.1f", out, $realtime); pass = 1'b0; end end else if ((in === 1'bz && outif0 !== 1'bx) || (in !== 1'bz && outif0 !== in)) begin $display("in (%b) !== outif0 (%b) at %.1f", in, outif0, $realtime); pass = 1'b0; end diff = $realtime - (base + delay); if (diff < 0.0) diff = -diff; if (diff >= 0.01) begin $display("Incorrect bufif0 delay at %.1f, got %.1f, expected %.1f", base, $realtime-base, delay); pass = 1'b0; end end function real min(input real a, input real b); if (a < b) min = a; else min = b; endfunction initial begin // $monitor($realtime,,out,outif0,, in,, ctl); pass = 1'b1; rise = 1.1; fall = 1.2; ctl = 1'b0; // x -> 0 (fall) in = 1'b0; delay = fall; base = $realtime; #2; // 0 -> 1 (rise) in = 1'b1; delay = rise; base = $realtime; #2; // 1 -> x (min(rise, fall)) delay = min(rise, fall); in = 1'bz; base = $realtime; #2; // x -> 1 (rise) in = 1'b1; delay = rise; base = $realtime; #2; // 1 -> 0 (fall) in = 1'b0; delay = fall; base = $realtime; #2; fall = 1.0; // 0 -> x (min(rise, fall)) in = 1'bx; delay = min(rise, fall); base = $realtime; #2; // x -> z (min(rise, fall)) ctl = 1'b1; delay = min(rise, fall); base = $realtime; #2; // z -> x (min(rise, fall)) ctl = 1'b0; delay = min(rise, fall); base = $realtime; #2; fall = 1.2; // x -> z (min(rise, fall)) ctl = 1'b1; delay = min(rise, fall); base = $realtime; #2; if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_and104_stdlogic.v000066400000000000000000000034711435245347300226320ustar00rootroot00000000000000module check (input unsigned [103:0] a, b, c); wire [103:0] int_AB; assign int_AB = a & b; always @(a, b, int_AB, c) begin #1; if (int_AB !== c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [103:0] A, B); parameter S = 2000; int unsigned i; initial begin A = 0; B= 0; // values with 0, 1 for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test case for handling an array of arrays module vhdl_array_of_array_test; vhdl_array_of_array dut(); initial begin if(dut.sig[0] !== 8'haa) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_array_of_array.vhd000066400000000000000000000023741435245347300232700ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test case for handling an array of arrays library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_array_of_array is end entity vhdl_array_of_array; architecture test of vhdl_array_of_array is type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0); signal sig : t_byte_array(2 downto 0); begin sig <= (0 => x"aa", 1 => x"bb", 2 => x"cc"); end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_boolean.v000066400000000000000000000037321435245347300213720ustar00rootroot00000000000000// Copyright (c) 2015 CERN // @author Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // boolean values test. module vhdl_boolean_test; vhdl_boolean dut(); initial begin if(dut.true_val != \true ) begin $display("FAILED true 1"); $finish(); end if(!dut.true_val) begin $display("FAILED true 2"); $finish(); end if(dut.false_val != \false ) begin $display("FAILED false 1"); $finish(); end if(dut.false_val) begin $display("FAILED false 2"); $finish(); end if(!dut.and1) begin $display("FAILED and1"); $finish(); end if(dut.and2) begin $display("FAILED and2"); $finish(); end if(dut.and3) begin $display("FAILED and3"); $finish(); end if(!dut.or1) begin $display("FAILED or1"); $finish(); end if(!dut.or2) begin $display("FAILED or2"); $finish(); end if(dut.or3) begin $display("FAILED or3"); $finish(); end if(!dut.not1) begin $display("FAILED not1"); $finish(); end if(dut.not2) begin $display("FAILED not2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_boolean.vhd000066400000000000000000000024441435245347300217050ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- @author Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- boolean values test. library ieee; entity vhdl_boolean is end vhdl_boolean; architecture test of vhdl_boolean is signal true_val, false_val, and1, and2, and3, or1, or2, or3, not1, not2 : boolean; begin true_val <= true; false_val <= false; and1 <= true and true; and2 <= true and false; and3 <= false and false; or1 <= true or true; or2 <= true or false; or3 <= false or false; not1 <= not false; not2 <= not true; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_case_multi.v000066400000000000000000000024301435245347300220720ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for multiple choices in case alternative statements. module vhdl_case_multi_test; reg [2:0] test_vec; reg parity; vhdl_case_multi dut(test_vec, parity); initial begin // Execute both paths test_vec = 'b101; #1; if(parity !== 1'b0) begin $display("FAILED 1"); $finish(); end test_vec = 'b001; #1; if(parity !== 1'b1) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_case_multi.vhd000066400000000000000000000025121435245347300224070ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for multiple choices in case alternative statements. library ieee; use ieee.std_logic_1164.all; entity vhdl_case_multi is port ( inp: in std_logic_vector (0 to 2); parity: out std_logic ); end vhdl_case_multi; architecture vhdl_case_multi_rtl of vhdl_case_multi is begin process (inp) begin case inp is when "000"|"011"|"101"|"110" => parity <= "0"; when "001"|"010"|"100"|"111" => parity <= "1"; when others => parity <= "Z"; end case; end process; end vhdl_case_multi_rtl; iverilog-12_0/ivtest/ivltests/vhdl_concat.v000066400000000000000000000023451435245347300212210ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for expression concatenation in VHDL. module concat_test; concat dut(); initial begin #1; // wait for signal assignments if(dut.concat1 !== 2'b10) begin $display("FAILED: concat1 should be 10 but is %b", dut.concat1); $finish(); end if(dut.concat2 !== 5'b11010) begin $display("FAILED: concat2 should be 11010 but is %b", dut.concat2); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_concat.vhd000066400000000000000000000021621435245347300215320ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for expression concatenation in VHDL. library ieee; use ieee.std_logic_1164.all; entity concat is end concat; architecture test of concat is signal concat1 : std_logic_vector(1 downto 0); signal concat2 : std_logic_vector(0 to 4); begin concat1 <= '1' & '0'; concat2 <= '1' & "10" & concat1; end test; iverilog-12_0/ivtest/ivltests/vhdl_concat_func.v000066400000000000000000000022351435245347300222320ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place / Suite 330, Boston, MA 02111/1307, USA // Test for concatenation of function call results. module test_concat_func(); logic [7:0] in_word, out_word; concat_func dut(in_word, out_word); initial begin in_word = 8'b11101010; #1; if(out_word !== 8'b11010010) begin $display("FAILED out_word = %b", out_word); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_concat_func.vhd000066400000000000000000000026351435245347300225520ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for concatenation of function call results. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity concat_func is port(in_word : in std_logic_vector(7 downto 0); out_word : out std_logic_vector(7 downto 0)); end entity concat_func; architecture test of concat_func is begin process(in_word) variable tmp : unsigned(7 downto 0); variable int : integer; begin tmp := unsigned(in_word); int := to_integer(tmp); out_word <= in_word(7 downto 6) & std_logic_vector(to_unsigned(int, 3)) & std_logic_vector(resize(tmp, 3)); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_concurrent_assert.v000066400000000000000000000017201435245347300235110ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for concurrent assertion statements. module vhdl_concurrent_assert_test; vhdl_concurrent_assert dut(); // we do not need anything else here endmodule iverilog-12_0/ivtest/ivltests/vhdl_concurrent_assert.vhd000066400000000000000000000023401435245347300240240ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for concurrent assertion statements. library ieee; use ieee.std_logic_1164.all; entity vhdl_concurrent_assert is end vhdl_concurrent_assert; architecture test of vhdl_concurrent_assert is signal bool_false: boolean := false; signal bool_true: boolean := true; begin assert (bool_false) report "this assert should be fired"; assert (bool_true) report "this assert should not be fired"; end test; iverilog-12_0/ivtest/ivltests/vhdl_const_array.v000066400000000000000000000030361435245347300222740ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for constant arrays access module constant_array_test(); reg [7:0] out_word; reg [2:0] index; constant_array dut(index, out_word); initial begin index = 2; #1; // wait for signal assignments if(out_word !== 16) begin $display("FAILED 1"); $finish(); end index = 4; #1; if(out_word !== 64) begin $display("FAILED 2"); $finish(); end if(dut.test_a !== 32) begin $display("FAILED 3"); $finish(); end if(dut.test_b !== 4) begin $display("FAILED 4"); $finish(); end if(dut.test_c !== 3'b100) begin $display("FAILED 5"); $finish(); end if(dut.test_d !== 1'b1) begin $display("FAILED 6"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_const_array.vhd000066400000000000000000000036321435245347300226120ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for constant arrays access library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.constant_array_pkg.all; entity constant_array is port (index : in std_logic_vector(2 downto 0); output : out std_logic_vector(7 downto 0)); end entity constant_array; architecture test of constant_array is type logic_array is array (integer range <>) of std_logic_vector(0 to 3); constant test_array : logic_array(0 to 5) := (0 => "0010", 1 => "1000", 2 => "0100", 3 => "0110", 4 => "0101", 5 => "1100"); -- Check if constant vectors are not broken with the changes constant vector : std_logic_vector(5 downto 0) := "110011"; signal test_a : unsigned(7 downto 0); signal test_b : std_logic_vector(3 downto 0); signal test_c : std_logic_vector(2 downto 0); signal test_d : std_logic; begin test_a <= const_array(3); test_b <= test_array(2); test_c <= vector(4 downto 2); test_d <= vector(5); process (index) begin output <= const_array(to_integer(unsigned(index))); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_const_array_pkg.vhd000066400000000000000000000024351435245347300234530ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for constant arrays access library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package constant_array_pkg is type t_unsigned_array is array (natural range <>) of unsigned(7 downto 0); constant const_array : t_unsigned_array(7 downto 0) := (0 => "00000010", 1 => "00001000", 2 => "00010000", 3 => "00100000", 4 => "01000000", 5 => "01111100", others => "00000010"); end package constant_array_pkg; iverilog-12_0/ivtest/ivltests/vhdl_const_package.v000066400000000000000000000024041435245347300225470ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests if constants in packages can be initialized with expressions // that normally require elaboration to be properly emitted. module const_package_test; const_package dut(); initial begin if(dut.c_bitstring != 'b1001) begin $display("FAILED 1"); $finish; end #1; // wait for signal assignment if(dut.c_aggregate != 'b10001000) begin $display("FAILED 2"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_const_package.vhd000066400000000000000000000023711435245347300230660ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests if constants in packages can be initialized with expressions -- that normally require elaboration to be properly emitted. library IEEE; use IEEE.STD_LOGIC_1164.all; use work.const_package_pkg.all; entity const_package is end const_package; architecture test of const_package is signal bitstring : std_logic_vector(3 downto 0) := c_bitstring; signal aggregate : std_logic_vector(7 downto 0); begin aggregate <= c_aggregate; end test; iverilog-12_0/ivtest/ivltests/vhdl_const_package_pkg.vhd000066400000000000000000000023621435245347300237270ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests if constants in packages can be initialized with expressions -- that normally require elaboration to be properly emitted. library IEEE; use IEEE.STD_LOGIC_1164.all; package const_package_pkg is constant c_bitstring : std_logic_vector(3 downto 0) := "1001"; constant c_aggregate : std_logic_vector(7 downto 0) := (7 => '1', 3 => '1', others => '0'); end const_package_pkg; package body const_package_pkg is end const_package_pkg; iverilog-12_0/ivtest/ivltests/vhdl_const_record.v000066400000000000000000000032001435245347300224250ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for accessing constant records & arrays of records in VHDL. module vhdl_const_record_test; int sel; logic [7:0] hex; logic [7:0] aval; vhdl_const_record dut(sel, hex, aval); initial begin if(dut.sig !== 8'h66) begin $display("FAILED 1"); $finish(); end sel = 0; #1; if(hex !== 8'h14 || aval !== 8'haa || dut.sig2 !== 8'h00) begin $display("FAILED 2"); $finish(); end sel = 1; #1; if(hex !== 8'h24 || aval !== 8'hbb || dut.sig2 !== 8'h11) begin $display("FAILED 3"); $finish(); end sel = 2; #1; if(hex !== 8'h34 || aval !== 8'hcc || dut.sig2 !== 8'h22) begin $display("FAILED 4"); $finish(); end sel = 3; #1; if(hex !== 8'h56 || aval !== 8'hdd || dut.sig2 !== 8'h33) begin $display("FAILED 5"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_const_record.vhd000066400000000000000000000054671435245347300227620ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for accessing constant records & arrays of records in VHDL. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_const_record is port(sel : in integer range 0 to 3; hex : out std_logic_vector(7 downto 0); aval : out std_logic_vector(7 downto 0)); end entity vhdl_const_record; architecture test of vhdl_const_record is type t_var is (var_presence, var_identif, var_1, var_2, var_3, var_rst, var_4, var_5, var_whatever); type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0); type t_var_record is record var : t_var; -- 32 bits a : t_byte_array (3 downto 0); -- 4*8 bits hexvalue : std_logic_vector (7 downto 0); -- 8 bits end record; -- total 72 bits type t_var_array is array (natural range <>) of t_var_record; constant c_vars_array : t_var_array(0 to 3) := ( 0 => (var => var_presence, hexvalue => x"14", a => (0 => x"aa", 1 => x"ab", 2 => x"ac", 3 => x"ad")), 1 => (var => var_identif, hexvalue => x"24", a => (0 => x"ba", 1 => x"bb", 2 => x"bc", 3 => x"bd")), 2 => (var => var_1, hexvalue => x"34", a => (0 => x"ca", 1 => x"cb", 2 => x"cc", 3 => x"cd")), 3 => (var => var_2, hexvalue => x"56", a => (0 => x"da", 1 => x"db", 2 => x"dc", 3 => x"dd")) ); constant c_record : t_var_record := ( var => var_4, hexvalue => x"66", a => (0 => x"00", 1 => x"11", 2 => x"22", 3 => x"33") ); signal sig : std_logic_vector(7 downto 0); signal sig2 : std_logic_vector(7 downto 0); begin sig <= c_record.hexvalue; process(sel) begin sig2 <= c_record.a(sel); hex <= c_vars_array(sel).hexvalue; aval <= c_vars_array(sel).a(sel); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_delay_assign.v000066400000000000000000000026171435245347300224160ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for delayed assignment statements. module vhdl_delay_assign_test; logic a, b, c; int passed = 0; vhdl_delay_assign dut(a, b, c); always @(b) begin if($time == 10) begin passed = passed + 1; end else begin $display("FAILED 1"); $finish(); end end always @(c) begin if($time == 10) begin passed = passed + 1; end else begin $display("FAILED 2"); $finish(); end end initial begin a = 1; #11; if(passed !== 2) begin $display("FAILED 3"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_delay_assign.vhd000066400000000000000000000022211435245347300227210ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for delayed assignment statements. library ieee; use ieee.std_logic_1164.all; entity vhdl_delay_assign is port(a : in std_logic; b, c : out std_logic); end vhdl_delay_assign; architecture test of vhdl_delay_assign is begin b <= a after 10 ns; process(a) begin c <= a after 10 ns; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_elab_range.v000066400000000000000000000022711435245347300220270ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Bug report test (could not elaborate a function used to specify a range). module vhdl_elab_range_test; integer left, right; vhdl_elab_range dut(left, right); initial begin #1; if(left !== 2) begin $display("FAILED 1"); $finish(); end if(right !== 0) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_elab_range.vhd000066400000000000000000000026401435245347300223430ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Bug report test (could not elaborate a function used to specify a range). library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_elab_range is port(sig_left, sig_right : out integer); end entity vhdl_elab_range; architecture test of vhdl_elab_range is function inc_by_two(a : in integer) return integer is begin return a + 2; end function inc_by_two; signal test_sig : unsigned(inc_by_two(0) downto 0) := (others => '0'); begin process begin sig_left <= test_sig'left; sig_right <= test_sig'right; wait; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_eval_cond.v000066400000000000000000000020601435245347300216760ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place / Suite 330, Boston, MA 02111/1307, USA // Test initial conditional assignment evaluation module vhdl_eval_cond_test; logic in, out; vhdl_eval_cond dut(in, out); assign in = 1; initial begin if(out === 1'b0) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_eval_cond.vhd000066400000000000000000000021601435245347300222130ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and-or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test initial conditional assignment evaluation library ieee; use ieee.std_logic_1164.all; entity vhdl_eval_cond is port( input : in std_logic; output : out std_logic ); end vhdl_eval_cond; architecture rtl of vhdl_eval_cond is begin output <= '1' when input = '0' else '0'; end rtl; iverilog-12_0/ivtest/ivltests/vhdl_expr1.v000066400000000000000000000007271435245347300210130ustar00rootroot00000000000000module main; wire [3:0] a, b; wire [3:0] out; subtract dut (.a(a), .b(b), .out_sig(out)); reg [8:0] test_vector; assign {a, b} = test_vector; initial begin for (test_vector=0 ; test_vector[8]==0 ; test_vector=test_vector+1) begin #1 if (out != a-b) begin $display("FAILED -- out=%b, expecting %b-%b=%b", out, a, b, a-b); $finish; end end $display("PASSED"); $finish; end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_expr1.vhd000066400000000000000000000006651435245347300213300ustar00rootroot00000000000000-- This VHDL was converted from Verilog using the -- Icarus Verilog VHDL Code Generator 0.10.0 (devel) (s20090923-519-g6ce96cc) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity subtract is port ( a : in unsigned(3 downto 0); b : in unsigned(3 downto 0); out_sig : out unsigned(3 downto 0) ); end entity; architecture test of subtract is begin out_sig <= (a + not b) + 1; end architecture; iverilog-12_0/ivtest/ivltests/vhdl_fa4_test1.v000066400000000000000000000007471435245347300215500ustar00rootroot00000000000000/* * This module instantiates the fa4 entity, which in turn * instantiates other entities. This demonstrates hierarchical * constructs in VHDL. */ module test; reg [3:0] a, b; reg cin; wire [3:0] s; wire cout; initial begin cin = 0; a = 4'h2; b = 4'h3; end initial begin #1; if (s !== 4'h5) begin $display("Error in trivial sum"); $finish; end $display ("PASSED"); end fa4 duv (.c_i(cin), .va_i(a), .vb_i(b), .vs_o(s), .c_o(cout) ); endmodule // test iverilog-12_0/ivtest/ivltests/vhdl_fa4_test1.vhd000066400000000000000000000035051435245347300220570ustar00rootroot00000000000000library ieee; use ieee.numeric_bit.all; -- Declare a 1-bit full-adder. entity fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl; -- Declare and implement a 4-bit full-adder that uses the -- 1-bit full-adder described above. entity fa4 is port (va_i, vb_i: in bit_vector (3 downto 0); c_i: in bit; vs_o: out bit_vector (3 downto 0); c_o: out bit ); end entity fa4; architecture fa4_rtl of fa4 is -- full 1-bit adder component fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit); end component fa1; -- internal carry signals propagation signal c_int4, c_int3, c_int2, c_int1, c_int0: bit; begin -- carry in c_int0 <= c_i; -- slice 0 s0: fa1 port map (c_i => c_int0, a_i => va_i(0), b_i => vb_i(0), s_o => vs_o(0), c_o => c_int1 ); -- slice 1 s1: fa1 port map (c_i => c_int1, a_i => va_i(1), b_i => vb_i(1), s_o => vs_o(1), c_o => c_int2 ); -- slice 2 s2: fa1 port map (c_i => c_int2, a_i => va_i(2), b_i => vb_i(2), s_o => vs_o(2), c_o => c_int3 ); -- slice 3 s3: fa1 port map (c_i => c_int3, a_i => va_i(3), b_i => vb_i(3), s_o => vs_o(3), c_o => c_int4 ); -- carry out c_o <= c_int4; end architecture fa4_rtl; iverilog-12_0/ivtest/ivltests/vhdl_fa4_test2.v000066400000000000000000000007471435245347300215510ustar00rootroot00000000000000/* * This module instantiates the fa4 entity, which in turn * instantiates other entities. This demonstrates hierarchical * constructs in VHDL. */ module test; reg [3:0] a, b; reg cin; wire [3:0] s; wire cout; initial begin cin = 0; a = 4'h2; b = 4'h3; end initial begin #1; if (s !== 4'h5) begin $display("Error in trivial sum"); $finish; end $display ("PASSED"); end fa4 duv (.c_i(cin), .va_i(a), .vb_i(b), .vs_o(s), .c_o(cout) ); endmodule // test iverilog-12_0/ivtest/ivltests/vhdl_fa4_test2.vhd000066400000000000000000000035141435245347300220600ustar00rootroot00000000000000library ieee; use ieee.numeric_bit.all; -- Declare a 1-bit full-adder. entity fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl; -- Declare and implement a 4-bit full-adder that uses the -- 1-bit full-adder described above. entity fa4 is port (va_i, vb_i: in bit_vector (3 downto 0); c_i: in bit; vs_o: out bit_vector (3 downto 0); c_o: out bit ); end entity fa4; architecture fa4_rtl of fa4 is -- full 1-bit adder component fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit); end component fa1; -- internal carry signals propagation signal c_int: bit_vector (4 downto 0); begin -- carry in c_int(0) <= c_i; -- slice 0 s0: fa1 port map (c_i => c_int(0), a_i => va_i(0), b_i => vb_i(0), s_o => vs_o(0), c_o => c_int(1) ); -- slice 1 s1: fa1 port map (c_i => c_int(1), a_i => va_i(1), b_i => vb_i(1), s_o => vs_o(1), c_o => c_int(2) ); -- slice 2 s2: fa1 port map (c_i => c_int(2), a_i => va_i(2), b_i => vb_i(2), s_o => vs_o(2), c_o => c_int(3) ); -- slice 3 s3: fa1 port map (c_i => c_int(3), a_i => va_i(3), b_i => vb_i(3), s_o => vs_o(3), c_o => c_int(4) ); -- carry out c_o <= c_int(4); end architecture fa4_rtl; iverilog-12_0/ivtest/ivltests/vhdl_fa4_test3.v000066400000000000000000000007471435245347300215520ustar00rootroot00000000000000/* * This module instantiates the fa4 entity, which in turn * instantiates other entities. This demonstrates hierarchical * constructs in VHDL. */ module test; reg [3:0] a, b; reg cin; wire [3:0] s; wire cout; initial begin cin = 0; a = 4'h2; b = 4'h3; end initial begin #1; if (s !== 4'h5) begin $display("Error in trivial sum"); $finish; end $display ("PASSED"); end fa4 duv (.c_i(cin), .va_i(a), .vb_i(b), .vs_o(s), .c_o(cout) ); endmodule // test iverilog-12_0/ivtest/ivltests/vhdl_fa4_test3.vhd000066400000000000000000000040111435245347300220520ustar00rootroot00000000000000-- In this test, we declare a component in the "gates" package -- and show that it can be referenced within the package namespace. library ieee; use ieee.numeric_bit.all; package gates is -- full 1-bit adder component fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit); end component fa1; end package gates; -- Declare and implement a 4-bit full-adder that uses the -- 1-bit full-adder described above. entity fa4 is port (va_i, vb_i: in bit_vector (3 downto 0); c_i: in bit; vs_o: out bit_vector (3 downto 0); c_o: out bit ); end entity fa4; architecture fa4_rtl of fa4 is use work.gates.fa1; -- internal carry signals propagation signal c_int: bit_vector (4 downto 0); begin -- carry in c_int(0) <= c_i; -- slice 0 s0: fa1 port map (c_i => c_int(0), a_i => va_i(0), b_i => vb_i(0), s_o => vs_o(0), c_o => c_int(1) ); -- slice 1 s1: fa1 port map (c_i => c_int(1), a_i => va_i(1), b_i => vb_i(1), s_o => vs_o(1), c_o => c_int(2) ); -- slice 2 s2: fa1 port map (c_i => c_int(2), a_i => va_i(2), b_i => vb_i(2), s_o => vs_o(2), c_o => c_int(3) ); -- slice 3 s3: fa1 port map (c_i => c_int(3), a_i => va_i(3), b_i => vb_i(3), s_o => vs_o(3), c_o => c_int(4) ); -- carry out c_o <= c_int(4); end architecture fa4_rtl; -- Declare a 1-bit full-adder. entity fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl; iverilog-12_0/ivtest/ivltests/vhdl_fa4_test4.v000066400000000000000000000007471435245347300215530ustar00rootroot00000000000000/* * This module instantiates the fa4 entity, which in turn * instantiates other entities. This demonstrates hierarchical * constructs in VHDL. */ module test; reg [3:0] a, b; reg cin; wire [3:0] s; wire cout; initial begin cin = 0; a = 4'h2; b = 4'h3; end initial begin #1; if (s !== 4'h5) begin $display("Error in trivial sum"); $finish; end $display ("PASSED"); end fa4 duv (.c_i(cin), .va_i(a), .vb_i(b), .vs_o(s), .c_o(cout) ); endmodule // test iverilog-12_0/ivtest/ivltests/vhdl_fa4_test4.vhd000066400000000000000000000050271435245347300220630ustar00rootroot00000000000000-- In this test, we declare a component in the "mypackage" package -- and show that it can be referenced within the package namespace. -- it also shows the usage of subtypes, constants and signals -- expressed in terms of defined subtypes library ieee; use ieee.numeric_bit.all; package mypackage is -- trivial sub type subtype Myrange_t is integer range 0 to 4; -- some constants constant ZERO: Myrange_t := 0; constant ONE: Myrange_t := 1; constant TWO: Myrange_t := 2; constant THREE: Myrange_t := 3; constant FOUR: Myrange_t := 4; -- another subtype subtype AdderWidth_t is bit_vector (THREE downto ZERO); subtype CarryWidth_t is bit_vector (THREE+1 downto ZERO); -- full 1-bit adder component fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit); end component fa1; end package mypackage; -- Declare and implement a 4-bit full-adder that uses the -- 1-bit full-adder described above. use work.mypackage.all; entity fa4 is port (va_i, vb_i: in AdderWidth_t; c_i: in bit; vs_o: out AdderWidth_t; c_o: out bit ); end entity fa4; architecture fa4_rtl of fa4 is -- auxiliary signal for carry signal c_int: CarryWidth_t; begin -- carry in c_int(ZERO) <= c_i; -- slice 0 s0: fa1 port map (c_i => c_int(ZERO), a_i => va_i(ZERO), b_i => vb_i(ZERO), s_o => vs_o(ZERO), c_o => c_int(ONE) ); -- slice 1 s1: fa1 port map (c_i => c_int(ONE), a_i => va_i(ONE), b_i => vb_i(ONE), s_o => vs_o(ONE), c_o => c_int(TWO) ); -- slice 2 s2: fa1 port map (c_i => c_int(TWO), a_i => va_i(TWO), b_i => vb_i(TWO), s_o => vs_o(TWO), c_o => c_int(THREE) ); -- slice 3 s3: fa1 port map (c_i => c_int(THREE), a_i => va_i(THREE), b_i => vb_i(THREE), s_o => vs_o(THREE), c_o => c_int(FOUR) ); -- carry out c_o <= c_int(FOUR); end architecture fa4_rtl; -- Declare a 1-bit full-adder. entity fa1 is port (a_i, b_i, c_i: in bit; s_o, c_o: out bit ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl; iverilog-12_0/ivtest/ivltests/vhdl_file_open.v000066400000000000000000000020701435245347300217050ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test file_open() function. module file_open_test; logic active, ok; vhdl_file_open dut(active, ok); initial begin active = 1; #1; if(ok !== 1'b1) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_file_open.vhd000066400000000000000000000031651435245347300222270ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test file_open() function. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; entity vhdl_file_open is port(active : in std_logic; ok : out std_logic); end vhdl_file_open; architecture test of vhdl_file_open is begin process(active) file ok_file, bad_file : text; variable ok_status, bad_status : FILE_OPEN_STATUS; begin if rising_edge(active) then file_open(ok_status, ok_file, "ivltests/vhdl_file_open.vhd", read_mode); file_open(bad_status, bad_file, "not_existing_file", read_mode); if ok_status = OPEN_OK and bad_status = NAME_ERROR then ok := '1'; else ok := '0'; end if; file_close(ok_file); end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_generic_default.v000066400000000000000000000020761435245347300230730ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for generics without a default value. module vhdl_generic_default_test; logic a; vhdl_generic_default #(.\value (1'b1))dut(a); initial begin if(a !== 1'b1) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_generic_default.vhd000066400000000000000000000021201435245347300233750ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for generics without a default value. library ieee; use ieee.std_logic_1164.all; entity vhdl_generic_default is generic(value : std_logic); port(a : out std_logic); end vhdl_generic_default; architecture test of vhdl_generic_default is begin a <= value; end test; iverilog-12_0/ivtest/ivltests/vhdl_generic_eval.v000066400000000000000000000022301435245347300223660ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for generics evaluation. module generic_eval(); reg [7:0] data; reg out_bit_def, out_bit_ovr; test_eval_generic dut(data, out_bit_def, out_bit_ovr); initial begin data = 8'b11010010; #1; if(out_bit_def !== 1'b0 || out_bit_ovr !== 1'b1) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_generic_eval.vhd000066400000000000000000000042201435245347300227030ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for generics evaluation. library ieee; use ieee.std_logic_1164.all; entity eval_generic is generic( msb : integer range 1 to 7 := 7; bit_select : integer range 0 to 7 := 3 ); port( in_word : in std_logic_vector(msb downto 0); out_bit : out std_logic ); end entity eval_generic; architecture test of eval_generic is begin out_bit <= in_word(bit_select); end architecture test; library ieee; use ieee.std_logic_1164.all; entity test_eval_generic is port( in_word : in std_logic_vector(7 downto 0); out_bit_def, out_bit_ovr : out std_logic ); end entity test_eval_generic; architecture test of test_eval_generic is constant const_int : integer := 7; component eval_generic is generic( msb : integer range 1 to 7; bit_select : integer range 0 to 7 ); port( in_word : in std_logic_vector(msb downto 0); out_bit : out std_logic ); end component eval_generic; begin override_test_unit: eval_generic generic map(bit_select => 2, msb => const_int) port map( in_word => (others => '1'), out_bit => out_bit_ovr ); default_test_unit: eval_generic port map( in_word => in_word, out_bit => out_bit_def ); end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_image_attr.v000066400000000000000000000017631435245347300220710ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for 'image attribute in VHDL. module image_attr_test; logic start_test; image_attr_entity dut(start_test); initial begin start_test = 1'b0; #1 start_test = 1'b1; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_image_attr.vhd000066400000000000000000000030661435245347300224030ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for 'image attribute in VHDL. library ieee; use ieee.std_logic_1164.all; entity image_attr_entity is port (start_test : in std_logic); end image_attr_entity; architecture test of image_attr_entity is begin process(start_test) variable var_int : integer := 10; variable var_real : real := 12.34; variable var_char : character := 'o'; variable var_time : time := 10 ns; begin if(start_test = '1') then report "integer'image test: " & integer'image(var_int); report "real'image test: " & real'image(var_real); report "character'image test: " & character'image(var_char); report "time'image test: " & time'image(var_time); end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_init.v000066400000000000000000000025201435245347300207100ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests signal initializers. module vhdl_init_testbench; vhdl_init dut(); initial begin // Simply check if the assigned values are correct if (dut.a !== 'b11101001) begin $display("FAILED #1: expected 11101001, got %b", dut.a); $finish; end if (dut.b !== 'b1010) begin $display("FAILED #2: expected 1010, got %b", dut.b); $finish; end if (dut.c !== 'b1000) begin $display("FAILED #3: expected 1000, got %b", dut.c); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_init.vhd000066400000000000000000000027121435245347300212270ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests signal initializers. library ieee; use ieee.std_logic_1164.all; entity vhdl_init is end; architecture test of vhdl_init is -- Convert string to bitstring in initalizer signal a : std_logic_vector(7 downto 0) := "11101001"; -- Initialize with aggregate expression signal b : std_logic_vector(3 downto 0) := (0 => '0', 3 => '1', 1 => '1', 2 => '0'); -- Initialize with aggregate expression, inverted range signal c : std_logic_vector(0 to 3) := (3 => '1', others => '0'); begin -- Architecture statement part cannot be empty -- Assign the previous value, otherwise you will get unknown value a <= "11101001"; end test; iverilog-12_0/ivtest/ivltests/vhdl_inout.v000066400000000000000000000022741435245347300211110ustar00rootroot00000000000000// Copyright (c) 2015 CERN // @author Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for port inout mode. module vhdl_inout_test; logic a, b, c; vhdl_inout dut(a, b, c); initial begin b <= 1'b0; #1; if(a !== 1'b1 || c !== 1'b0) begin $display("FAILED 1"); $finish(); end b <= 1'b1; #1; if(a !== 1'b0 || c !== 1'b1) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_inout.vhd000066400000000000000000000023761435245347300214300ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- @author Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for port inout mode. library ieee; use ieee.std_logic_1164.all; entity vhdl_inout is port(a : inout std_logic; b : in std_logic; c : out std_logic); end vhdl_inout; architecture test of vhdl_inout is begin a <= not b; process(a) begin -- c indirectly follows b if(a = '1') then c <= '0'; else c <= '1'; end if; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_labeled_assign.v000066400000000000000000000022201435245347300226760ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for labeled assignment statements module labeled_assign_test; reg [7:0] in, out; labeled_assign dut(in, out); initial begin in = 8'hdd; #1; if(out !== 8'h11) begin $display("FAILED 1"); $finish(); end if(dut.test_rx !== 8'haa) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_labeled_assign.vhd000066400000000000000000000025441435245347300232230ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for labeled assignment statements library ieee; use ieee.std_logic_1164.all; entity labeled_assign is port (input : in std_logic_vector(7 downto 0); output : out std_Logic_vector(7 downto 0)); end entity; architecture test of labeled_assign is signal test_rx : std_logic_vector (7 downto 0); begin first_label: test_rx <= x"aa"; process(input) variable tmp : std_logic_vector(7 downto 0); begin second_label: tmp := input; third_label: output <= tmp xor x"cc"; end process; end architecture; iverilog-12_0/ivtest/ivltests/vhdl_lfcr.v000066400000000000000000000016561435245347300207040ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test special character enums (LF, CR). module vhdl_lfcr_test; vhdl_lfcr dut(); // we do not need anything more endmodule iverilog-12_0/ivtest/ivltests/vhdl_lfcr.vhd000066400000000000000000000021241435245347300212070ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test special character enums (LF, CR). library ieee; use ieee.std_logic_1164.all; entity vhdl_lfcr is end vhdl_lfcr; architecture test of vhdl_lfcr is begin process begin report "first line" & LF & "after LF" & CR & "after CR"; wait; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_logic.v000066400000000000000000000031061435245347300210430ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // std_logic values test. module vhdl_logic_test; logic low, high, hiz, dontcare, uninitialized, unknown; vhdl_logic dut(low, high, hiz, dontcare, uninitialized, unknown); initial begin if(low !== 1'b0) begin $display("FAILED low"); $finish(); end if(high !== 1'b1) begin $display("FAILED high"); $finish(); end if(hiz !== 1'bz) begin $display("FAILED hiz"); $finish(); end if(dontcare !== 1'bx) begin $display("FAILED dontcare"); $finish(); end if(uninitialized !== 1'bx) begin $display("FAILED uninitialized"); $finish(); end if(unknown !== 1'bx) begin $display("FAILED unknown"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_logic.vhd000066400000000000000000000022371435245347300213630ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- std_logic values test. library ieee; use ieee.std_logic_1164.all; entity vhdl_logic is port (low, high, hiz, dontcare, uninitialized, unknown : out std_logic); end vhdl_logic; architecture test of vhdl_logic is begin low <= '0'; high <= '1'; hiz <= 'Z'; dontcare <= '-'; uninitialized <= 'U'; unknown <= 'X'; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_loop.v000066400000000000000000000022061435245347300207170ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for basic loops in VHDL. module vhdl_loop_test; logic start; int counter; vhdl_loop dut(start, counter); initial begin for(int i = 0; i < 5; ++i) begin if(counter !== i) begin $display("FAILED"); $finish(); end #10; end $display("PASSED"); $finish(); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_loop.vhd000066400000000000000000000023321435245347300212330ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for basic loops in VHDL. library ieee; use ieee.std_logic_1164.all; entity vhdl_loop is port(start : in std_logic; counter : out integer); end vhdl_loop; architecture test of vhdl_loop is begin process(start) variable cnt : integer := 0; begin loop cnt := cnt + 1; counter <= cnt; wait for 10 s; end loop; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_multidim_array.v000066400000000000000000000025761435245347300230020ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test multidimensional arrays. module vhdl_multidim_array_test; vhdl_multidim_array dut(); initial begin int i, j; for(i = 0; i <= 1; i = i + 1) begin for(j = dut.array_size - 1; j >= 0; j = j - 1) begin $display("%d", dut.arr[i][j]); //$display("%d, %d = %d", i, j, arr[i][j]); //if(dut.arr[i][j] !== i * 10 + j) begin //$display("FAILED: arr[%d][%d] == %d, instead of %d", i, j, dut.arr[i][j], i * 10 + j); //$finish(); //end end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_multidim_array.vhd000066400000000000000000000026651435245347300233150ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test multidimensional arrays. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity vhdl_multidim_array is end vhdl_multidim_array; architecture archi of vhdl_multidim_array is constant array_size : integer := 16; subtype one_dim is unsigned(array_size - 1 downto 0); type multi_dim is array (0 to 1) of one_dim; begin process variable arr : multi_dim; begin -- fill the array with test data for i in array_size - 1 downto 0 loop arr(0)(i) := 2 ** i; arr(1)(i) := not arr(0)(i); end loop; wait; end process; end archi; iverilog-12_0/ivtest/ivltests/vhdl_nand104_stdlogic.v000066400000000000000000000034651435245347300230130ustar00rootroot00000000000000module check (input unsigned [103:0] a, b, c); wire [103:0] int_AB; assign int_AB = ~(a & b); always @(a, b, int_AB, c) begin #1; if (int_AB !== c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [103:0] A, B); parameter S = 2000; int unsigned i; initial begin A = 0; B= 0; // values with 0, 1 for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for NOW() system function. module now_test; logic gen_report; now_entity dut(gen_report); initial begin gen_report = 0; #5; gen_report = 1; #5; gen_report = 0; #5; gen_report = 1; #5; gen_report = 0; #5; gen_report = 1; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_now.vhd000066400000000000000000000022741435245347300210720ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for NOW() system function. library ieee; use ieee.std_logic_1164.all; entity now_entity is port (report_time : in std_logic); end now_entity; architecture test of now_entity is begin process(report_time) begin if(rising_edge(report_time)) then report "reporting sim time: " & integer'image(now); end if; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_or104_stdlogic.v000066400000000000000000000035011435245347300225020ustar00rootroot00000000000000module check (input unsigned [103:0] a, b, c); wire [103:0] int_AB; assign int_AB = a | b; always @(a, b, int_AB, c) begin #1; if (int_AB !== c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [103:0] A, B); parameter S = 2000; int unsigned i; initial begin A = 0; B= 0; // values with 0, 1 for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Power and division remainder operators test module vhdl_pow_rem_test; integer a, b, pow_res, rem_res; vhdl_pow_rem dut(a, b, pow_res, rem_res); initial begin a = 5; b = 2; if(pow_res != 25 || rem_res != 1) begin $display("FAILED 1"); $finish(); end a = -5; b = 3; if(rem_res != -2 || pow_res != -125) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_pow_rem.vhd000066400000000000000000000021651435245347300217360ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- @author Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Power and division remainder operators test library ieee; use ieee.std_logic_1164.all; entity vhdl_pow_rem is port( a, b : in integer; pow_res, rem_res : out integer ); end vhdl_pow_rem; architecture rtl of vhdl_pow_rem is begin pow_res <= a ** b; rem_res <= a rem b; end rtl; iverilog-12_0/ivtest/ivltests/vhdl_prefix_array.v000066400000000000000000000022641435245347300224450ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place / Suite 330, Boston, MA 02111/1307, USA // Example to test prefix for VTypeArray (and using function as index). module test_prefix_aray(); logic [1:0] sel_word; logic [31:0] out_word; prefix_array dut(sel_word, out_word); initial begin sel_word = 2; #1; if(out_word !== 32'd5) begin $display("FAILED out_word = %d", out_word); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_prefix_array.vhd000066400000000000000000000032311435245347300227540ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Example to test prefix for VTypeArray (and using function as index). library ieee; use ieee.std_logic_1164.all; entity prefix_array is port(sel_word : in std_logic_vector(1 downto 0); out_word : out integer); end entity prefix_array; architecture test of prefix_array is type t_timeouts is record a : integer; b : integer; end record; type t_timeouts_table is array (natural range <>) of t_timeouts; constant c_TIMEOUTS_TABLE : t_timeouts_table(3 downto 0) := (0 => (a => 1, b => 2), 1 => (a => 3, b => 4), 2 => (a => 5, b => 6), 3 => (a => 7, b => 8)); begin process(sel_word) begin out_word <= to_unsigned((c_TIMEOUTS_TABLE(to_integer(unsigned(sel_word))).a), 32); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_procedure.v000066400000000000000000000017151435245347300217420ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for VHDL procedure calls module vhdl_procedure_test; logic run; vhdl_procedure dut(run); initial begin run = 0; #1 run = 1; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_procedure.vhd000066400000000000000000000024331435245347300222540ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for VHDL procedure calls. library ieee; use ieee.std_logic_1164.all; entity vhdl_procedure is port(run : in std_logic); end entity vhdl_procedure; architecture test of vhdl_procedure is procedure proc(word_i : std_logic_vector(3 downto 0)) is begin report "Procedure executed"; end procedure; begin process(run) begin report "before rising_edge"; if rising_edge(run) then proc("0000"); end if; report "after rising_edge"; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_process_scope.v000066400000000000000000000020621435245347300226150ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test a case when two variables with the same name are used in two // different processes. module vhdl_process_scope_test; vhdl_process_scope dut(); initial begin #0; // the test takes place in the dut processes $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_process_scope.vhd000066400000000000000000000024361435245347300231360ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test a case when two variables with the same name are used in two -- different processes. library ieee; use ieee.std_logic_1164.all; entity vhdl_process_scope is end vhdl_process_scope; architecture test of vhdl_process_scope is begin process variable var : integer := 1; begin assert var = 1; wait; end process; process variable var : integer := 2; begin assert var = 2; wait; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_rand23_bit.v000066400000000000000000000014471435245347300217030ustar00rootroot00000000000000module check (input unsigned [0:22] a, b, c); wire [0:22] int_AB; assign int_AB = a & b; always @(a, b, int_AB, c) begin #1; if (int_AB != c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [0:22] A, B); parameter MAX = 1 << 23; parameter S = 10000; int unsigned i; initial begin A = 0; B= 0; for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for 'range, 'reverse_range, 'left and 'right attributes in VHDL. module range_test; range_entity dut(); initial begin int i; #1; // wait for signal assignments if(dut.left_asc !== 2) begin $display("FAILED: left_asc should be %2d but is %2d", 2, dut.left_asc); $finish(); end if(dut.right_asc !== 4) begin $display("FAILED: right_asc should be %2d but is %2d", 2, dut.right_asc); $finish(); end if(dut.left_dsc !== 9) begin $display("FAILED: left_dsc should be %2d but is %2d", 2, dut.left_dsc); $finish(); end if(dut.right_dsc !== 3) begin $display("FAILED: right_dsc should be %2d but is %2d", 2, dut.right_dsc); $finish(); end if(dut.pow_left !== 16) begin $display("FAILED: pow_left should be %2d but is %2d", 16, dut.pow_left); $finish(); end if(dut.rem_left !== 2) begin $display("FAILED: rem_left should be %2d but is %2d", 2, dut.rem_left); $finish(); end for(i = $left(dut.ascending); i <= $right(dut.ascending); i++) begin if(2*i !== dut.ascending[i]) begin $display("FAILED: ascending[%2d] should be %2d but is %2d", i, 2*i, dut.ascending[i]); $finish(); end end for(i = $right(dut.descending); i <= $left(dut.descending); i++) begin if(3*i !== dut.descending[i]) begin $display("FAILED: descending[%2d] should be %2d but is %2d", i, 3*i, dut.descending[i]); $finish(); end end for(i = $left(dut.ascending_rev); i <= $right(dut.ascending_rev); i++) begin if(4*i !== dut.ascending_rev[i]) begin $display("FAILED: ascending_rev[%2d] should be %2d but is %2d", i, 4*i, dut.ascending_rev[i]); $finish(); end end for(i = $right(dut.descending_rev); i <= $left(dut.descending_rev); i++) begin if(5*i !== dut.descending_rev[i]) begin $display("FAILED: descending_rev[%2d] should be %2d but is %2d", i, 5*i, dut.descending_rev[i]); $finish(); end end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_range.vhd000066400000000000000000000044001435245347300213540ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for 'range, 'reverse_range, 'left and 'right attributes in VHDL. library ieee; use ieee.std_logic_1164.all; use work.vhdl_range_pkg.all; entity range_entity is port (gen_vals: in std_logic); end range_entity; architecture test of range_entity is type int_array is array (integer range <>) of integer; signal ascending : int_array(2 to 4); signal descending : int_array(9 downto 3); signal ascending_rev : int_array(8 to 13); signal descending_rev : int_array(15 downto 10); signal range_pow : int_array(2**4 downto 0); signal range_rem : int_array(8 rem 3 downto 0); signal left_asc, right_asc, left_dsc, right_dsc, pow_left, rem_left : integer; -- There is no limited ranged integer in SystemVerilog, so just see if it compiles signal int_asc : integer_asc; signal int_desc : integer_desc; begin process(gen_vals) begin left_asc <= ascending'left; right_asc <= ascending'right; left_dsc <= descending'left; right_dsc <= descending'right; pow_left <= range_pow'left; rem_left <= range_rem'left; -- 'range test for i in ascending'range loop ascending(i) <= i * 2; end loop; for i in descending'range loop descending(i) <= i * 3; end loop; -- 'reverse_range test for i in ascending_rev'reverse_range loop ascending_rev(i) <= i * 4; end loop; for i in descending_rev'reverse_range loop descending_rev(i) <= i * 5; end loop; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_range_func.v000066400000000000000000000022101435245347300220500ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for 'range, 'left and 'right attributes in VHDL subprograms. module range_func_test; range_func dut(); initial begin #1; if(dut.neg_out !== 4'b0011) begin $display("FAILED 1"); $finish(); end if(dut.rev_out !== 4'b0001) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_range_func.vhd000066400000000000000000000026721435245347300224000ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for 'range, 'left and 'right attributes in VHDL subprograms. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.range_func_pkg.all; entity range_func is end range_func; architecture test of range_func is signal neg_inp : std_logic_vector(3 downto 0); signal neg_out : std_logic_vector(3 downto 0); signal rev_inp : std_logic_vector(3 downto 0); signal rev_out : std_logic_vector(3 downto 0); begin neg_inp <= "1100"; rev_inp <= "1000"; process(neg_inp) begin neg_out <= negator(neg_inp); end process; process(rev_inp) begin rev_out <= reverse(rev_inp); end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_range_func_pkg.vhd000066400000000000000000000033431435245347300232350ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for 'range, 'left and 'right attributes in VHDL subprograms. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package range_func_pkg is function negator (word_i : std_logic_vector(3 downto 0)) return std_logic_vector; function reverse (word_i : std_logic_vector(3 downto 0)) return std_logic_vector; end range_func_pkg; package body range_func_pkg is function negator (word_i : std_logic_vector(3 downto 0)) return std_logic_vector is variable neg : std_logic_vector(word_i'left downto word_i'right); begin for I in word_i'range loop neg (I) := not word_i(I); end loop; return neg; end function; function reverse (word_i : std_logic_vector(3 downto 0)) return std_logic_vector is variable rev : std_logic_vector(3 downto 0); begin for I in word_i'right to word_i'left loop rev (rev'left - I) := word_i(I); end loop; return rev; end function; end range_func_pkg; iverilog-12_0/ivtest/ivltests/vhdl_range_pkg.vhd000066400000000000000000000020771435245347300222250ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; package vhdl_range_pkg is subtype integer_asc is integer range 0 to 7; subtype integer_desc is integer range 8 downto 1; end vhdl_range_pkg; package body vhdl_range_pkg is end vhdl_range_pkg; iverilog-12_0/ivtest/ivltests/vhdl_real.v000066400000000000000000000030641435245347300206740ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Basic test for 'real' floating-type support in VHDL. module vhdl_real_testbench; vhdl_real dut(); initial begin // simply check if the assigned values are correct if (dut.c != 1111.222) begin $display("FAILED"); $finish; end if (dut.e != 1135.022) begin $display("FAILED"); $finish; end if (dut.a != 1.2) begin $display("FAILED"); $finish; end if (dut.b != 32.12323) begin $display("FAILED"); $finish; end if (dut.exp != 2.334e+2) begin $display("FAILED"); $finish; end #10; // wait for the no_init signal assignment if (dut.no_init != 33.32323) begin $display("FAILED"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_real.vhd000066400000000000000000000023651435245347300212130ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Basic test for 'real' floating-type support in VHDL. library ieee; entity vhdl_real is end; architecture test of vhdl_real is constant c : real := 1111.222; constant d : real := 23.8; constant e : real := c + d; signal a : real := 1.2; signal b : real := 32.123_23; signal pi : real := 3.14159265; signal exp : real := 2.334E+2; signal no_init : real; begin no_init <= a + b; end test; iverilog-12_0/ivtest/ivltests/vhdl_record_elab.v000066400000000000000000000032261435245347300222120ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests initialization of records with aggregate expressions. // (based on the vhdl_struct_array test) module vhdl_record_elab_test; reg [15:0] in; wire [15:0] out; vhdl_record_elab dut( .o_high1(out[15:12]), .o_low1(out[11:8]), .o_high0(out[7:4]), .o_low0(out[3:0]), .i_high1(in[15:12]), .i_low1(in[11:8]), .i_high0(in[7:4]), .i_low0(in[3:0])); initial begin for (in = 0 ; in < 256 ; in = in+1) begin #1 if (in !== out[15:0]) begin $display("FAILED -- out=%h, in=%h", out, in); $finish; end end if (dut.dword_a[0].low !== 4'b0110 || dut.dword_a[0].high !== 4'b1001 || dut.dword_a[1].low !== 4'b0011 || dut.dword_a[1].high !== 4'b1100) begin $display("FAILED 2"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_record_elab.vhd000066400000000000000000000040251435245347300225240ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests initialization of records with aggregate expressions. -- (based on the vhdl_struct_array test) library ieee; use ieee.std_logic_1164.all; entity vhdl_record_elab is port ( i_low0: in std_logic_vector (3 downto 0); i_high0: in std_logic_vector (3 downto 0); i_low1: in std_logic_vector (3 downto 0); i_high1: in std_logic_vector (3 downto 0); o_low0: out std_logic_vector (3 downto 0); o_high0: out std_logic_vector (3 downto 0); o_low1: out std_logic_vector (3 downto 0); o_high1: out std_logic_vector (3 downto 0) ); end vhdl_record_elab; architecture test of vhdl_record_elab is type word is record high: std_logic_vector (3 downto 0); low: std_logic_vector (3 downto 0); end record; type dword is array (1 downto 0) of word; signal my_dword : dword; signal dword_a : dword; begin -- inputs my_dword(0) <= (low => i_low0, high => i_high0); -- test if you can assign values in any order my_dword(1) <= (high => i_high1, low => i_low1); dword_a <= (0 => (low => "0110", high => "1001"), 1 => (high => "1100", low => "0011")); -- outputs o_low0 <= my_dword(0).low; o_high0 <= my_dword(0).high; o_low1 <= my_dword(1).low; o_high1 <= my_dword(1).high; end test; iverilog-12_0/ivtest/ivltests/vhdl_reduce.v000066400000000000000000000040061435245347300212150ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for or_reduce/and_reduce functions. module vhdl_reduce_test; logic [4:0] inp; logic and_reduced, or_reduced; vhdl_reduce test(inp, and_reduced, or_reduced); initial begin inp = 5'b00000; #1 if(and_reduced !== 1'b0 || or_reduced !== 1'b0) begin $display("FAILED 1"); $finish(); end inp = 5'b00010; #1 if(and_reduced !== 1'b0 || or_reduced !== 1'b1) begin $display("FAILED 2"); $finish(); end inp = 5'b11111; #1 if(and_reduced !== 1'b1 || or_reduced !== 1'b1) begin $display("FAILED 3"); $finish(); end inp = 5'bzz1xx; #1 if(and_reduced !== 1'bx || or_reduced !== 1'b1) begin $display(and_reduced); $display(or_reduced); $display("FAILED 4"); $finish(); end inp = 5'bzz0xx; #1 if(and_reduced !== 1'b0 || or_reduced !== 1'bx) begin $display(and_reduced); $display(or_reduced); $display("FAILED 5"); $finish(); end inp = 5'bzzzxx; #1 if(and_reduced !== 1'bx || or_reduced !== 1'bx) begin $display(and_reduced); $display(or_reduced); $display("FAILED 6"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_reduce.vhd000066400000000000000000000023711435245347300215340ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for or_reduce/and_reduce functions. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_misc.all; entity vhdl_reduce is port(inp : in std_logic_vector(4 downto 0); and_reduced : out std_logic; or_reduced : out std_logic); end vhdl_reduce; architecture test of vhdl_reduce is begin process(inp) begin or_reduced <= or_reduce(inp); and_reduced <= and_reduce(inp); end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_report.v000066400000000000000000000021371435245347300212640ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Report & assert tests. module vhdl_report_test; logic start_test; vhdl_report dut(start_test); int a; initial begin // as of the moment of writing vhdlpp does not handle procedure calls a = vhdl_report_pkg::test_asserts(0); start_test = 1'b0; #1 start_test = 1'b1; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_report.vhd000066400000000000000000000041261435245347300216000ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Report & assert tests. library ieee; use ieee.std_logic_1164.all; use work.vhdl_report_pkg.all; entity vhdl_report is port (start_test : in std_logic); end vhdl_report; architecture test of vhdl_report is begin process(start_test) begin if(start_test = '1') then -- Report without severity specified, by default it is NOTE report "normal report"; -- Report with severity specified -- should continue execution when severity != FAILURE report "report with severity" severity ERROR; -- Assert, no report, no severity specified, by default it is ERROR assert false; -- Assert with report, no severity specified, by default it is ERROR assert 1 = 0 report "assert with report"; -- Assert without report, severity specified -- should continue execution when severity != FAILURE assert 1 = 2 severity NOTE; -- Assert with report and severity specified assert false report "assert with report & severity" severity FAILURE; -- FAILURE causes program to stop report "this should never be shown"; end if; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_report_pkg.vhd000066400000000000000000000026661435245347300224500ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Report & assert tests. library ieee; use ieee.std_logic_1164.all; package vhdl_report_pkg is -- as of the moment of writing vhdlpp does not support procedures function test_asserts(a : integer) return integer; end vhdl_report_pkg; package body vhdl_report_pkg is -- Test functions used to output package files function test_asserts(a : integer) return integer is begin report "procedure 1" severity ERROR; assert false; assert 1 = 0 report "procedure 2"; assert 1 = 2 severity NOTE; assert false report "procedure 3" severity WARNING; return 0; end function; end vhdl_report_pkg; iverilog-12_0/ivtest/ivltests/vhdl_resize.v000066400000000000000000000023271435245347300212530ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Resize function test module vhdl_resize_test; logic signed [7:0] in; logic signed [15:0] out; vhdl_resize dut(in, out); initial begin in = -120; #0; if(out !== -115) begin $display("FAILED 1: out = %d", out); $finish(); end in = 120; #0; if(out !== 125) begin $display("FAILED 2: out = %d", out); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_resize.vhd000066400000000000000000000021731435245347300215660ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and-or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Resize function test library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_resize is port( input : in signed(7 downto 0); output : out signed(15 downto 0) ); end vhdl_resize; architecture rtl of vhdl_resize is begin output <= resize(input + 5, output'length); end rtl; iverilog-12_0/ivtest/ivltests/vhdl_rtoi.v000066400000000000000000000024601435245347300207250ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test real to integer conversion module vhdl_rtoi_testbench; vhdl_rtoi dut(); initial begin #1; // wait for the no_init signal assignment if (dut.a !== 2) begin $display("FAILED 1"); $finish; end if (dut.b !== 4) begin $display("FAILED 2"); $finish; end if (dut.c !== 5) begin $display("FAILED 3"); $finish; end if (dut.d !== 17) begin $display("FAILED 4"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_rtoi.vhd000066400000000000000000000022351435245347300212410ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test real to integer conversion library ieee; use ieee.numeric_std.all; entity vhdl_rtoi is end; architecture test of vhdl_rtoi is signal a, b, c, d : integer; begin -- test rounding a <= integer(2.3); -- should be 2 b <= integer(3.7); -- should be 4 c <= integer(4.5); -- should be 5 d <= integer(8.1 * 2.1); -- ==17.01, should be 17 end test; iverilog-12_0/ivtest/ivltests/vhdl_sa1_test1.v000066400000000000000000000042701435245347300215550ustar00rootroot00000000000000// This module generates M pairs of N-1 bits unsigned numbers A, B // and also serialises them starting from LSB bits between // activation of active-high reset signal module stimulus #(parameter N = 4, M = 10) (input clk, output reg reset, output reg sa, sb, output reg unsigned [N-1:0] A, B ); parameter D = 5; int unsigned i; reg unsigned [N-1:0] r1, r2; initial begin repeat(M) begin r1 = {$random} % N; r2 = {$random} % N; do_items(r1, r2); end end task do_items (input unsigned [N-1:0] v1, v2); begin A = 0; B = 0; reset = 0; do_reset(); A = v1; B = v2; for (i=0; i| |------>|D Q|---> s_o -- b_i -->| FA1 | | | -- | |--- | | -- ---> |_______| | |_____| --rst __|_______________________| -- | | | -- | | | -- | | | ______ -- | | ---->|D Q|--- -- | | | | | -- | | | | | -- | | |_____| | -- | |____________| | -- |________________________________| -- library ieee; use ieee.std_logic_1164.all; use work.work6.all; entity sa1 is port (clk, reset: in std_logic; a_i, b_i: in std_logic; s_o: out std_logic ); end entity sa1; architecture sa1_rtl of sa1 is signal sum, carry, carry_reg: std_logic; begin a1: fa1 port map (c_i => carry_reg, a_i => a_i, b_i => b_i, s_o => sum, c_o => carry ); f1: fdc port map (clk => clk, reset => reset, d => sum, q => s_o); f2: fdc port map (clk => clk, reset => reset, d => carry, q => carry_reg); end architecture sa1_rtl; -- a one bit full adder written according to -- textbook's boolean equations library ieee; use ieee.std_logic_1164.all; entity fa1 is port (a_i, b_i, c_i: in std_logic; s_o, c_o: out std_logic ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl;-- a D-type flip-flop with synchronous reset library ieee; use ieee.std_logic_1164.all; entity fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic ); end fdc; architecture fdc_rtl of fdc is begin i_finish: process (clk) begin if (clk'event and clk = '1') then if (reset = '1') then q <= '0'; else q <= d; end if; end if; end process; end fdc_rtl; iverilog-12_0/ivtest/ivltests/vhdl_sa1_test2.v000066400000000000000000000042701435245347300215560ustar00rootroot00000000000000// This module generates M pairs of N-1 bits unsigned numbers A, B // and also serialises them starting from LSB bits between // activation of active-high reset signal module stimulus #(parameter N = 4, M = 10) (input clk, output reg reset, output reg sa, sb, output reg unsigned [N-1:0] A, B ); parameter D = 5; int unsigned i; reg unsigned [N-1:0] r1, r2; initial begin repeat(M) begin r1 = {$random} % N; r2 = {$random} % N; do_items(r1, r2); end end task do_items (input unsigned [N-1:0] v1, v2); begin A = 0; B = 0; reset = 0; do_reset(); A = v1; B = v2; for (i=0; i| |------>|D Q|---> s_o -- b_i -->| FA1 | | | -- | |--- | | -- ---> |_______| | |_____| --rst __|_______________________| -- | | | -- | | | -- | | | ______ -- | | ---->|D Q|--- -- | | | | | -- | | | | | -- | | |_____| | -- | |____________| | -- |________________________________| -- library ieee; use ieee.std_logic_1164.all; use work.work6.all; entity sa1 is port (clk, reset: in std_logic; a_i, b_i: in std_logic; s_o: out std_logic ); end entity sa1; architecture sa1_rtl of sa1 is signal sum, carry, carry_reg: std_logic; begin a1: fa1 port map (c_i => carry_reg, a_i => a_i, b_i => b_i, s_o => sum, c_o => carry ); f1: fdc port map (clk => clk, reset => reset, d => sum, q => s_o); f2: fdc port map (clk => clk, reset => reset, d => carry, q => carry_reg); end architecture sa1_rtl; -- a one bit full adder written according to -- textbook's boolean equations library ieee; use ieee.std_logic_1164.all; entity fa1 is port (a_i, b_i, c_i: in std_logic; s_o, c_o: out std_logic ); end entity fa1; architecture fa1_rtl of fa1 is begin s_o <= a_i xor b_i xor c_i; c_o <= (a_i and b_i) or (c_i and (a_i xor b_i)); end architecture fa1_rtl;-- a D-type flip-flop with synchronous reset library ieee; use ieee.std_logic_1164.all; entity fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic ); end fdc; architecture fdc_rtl of fdc is begin i_finish: process (clk) begin if (clk'event and clk = '1') then if (reset = '1') then q <= '0'; else q <= d; end if; end if; end process; end fdc_rtl; iverilog-12_0/ivtest/ivltests/vhdl_sa1_test3.v000066400000000000000000000010131435245347300215470ustar00rootroot00000000000000module test; reg clk, reset; wire [24:0] count; initial begin clk = 1'b0; forever #25 clk = ~clk; end initial begin reset = 1'b0; @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end initial begin #200000; #500; if (count != 2000) begin $display ("Counting FAILED"); $finish; end else begin $display ("PASSED"); #20; $finish; end end bigcount duv (.clk(clk), .reset(reset), .count(count) ); endmodule iverilog-12_0/ivtest/ivltests/vhdl_sa1_test3.vhd000066400000000000000000000057241435245347300221000ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; package work6 is -- D-type flip flop component fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic); end component; component TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end component; end package work6; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- The operation is: -- 1) An internal counter (of 25 bits) is initilaised to zero after a reset is received. -- 2) An enable allows an internal running counter to count clock pulses -- 3) A tick signal output is generated when a count of 20000000 pulses has been accumulated entity TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end TimeBase; architecture TimeBase_rtl of TimeBase is constant DIVIDER_VALUE : std_logic_vector := x"7cf"; -- 20000000 count value, 1 second signal RunningCounter : std_logic_vector(24 downto 0); -- this is the 25 bit free running counter to allow a big count begin RunningCounterProcess : process (CLOCK) begin if ( CLOCK'event and CLOCK = '1') then if (RESET = '1') then RunningCounter <= '0' & x"000000"; elsif ( ENABLE = '1') then RunningCounter <= RunningCounter + 1; end if; else RunningCounter <= RunningCounter; end if; end process; TICK <= '1' when (RunningCounter = DIVIDER_VALUE) else '0'; COUNT_VALUE <= RunningCounter; end TimeBase_rtl; library ieee; use ieee.std_logic_1164.all; use work.work6.all; entity bigcount is port (clk, reset: in std_logic; count: out std_logic_vector (24 downto 0) ); end entity bigcount; architecture bigcount_rtl of bigcount is signal d, t, q, myreset: std_logic; begin d <= t xor q; myreset <= reset or t; f1: fdc port map (clk => clk, reset => reset, d => d, q => q); tb: timebase port map (CLOCK => clk, RESET => myreset, ENABLE => '1', TICK => t, COUNT_VALUE => open ); counting: timebase port map (CLOCK => clk, RESET => reset, ENABLE => q, TICK => open, COUNT_VALUE => count ); end bigcount_rtl;-- a D-type flip-flop with synchronous reset library ieee; use ieee.std_logic_1164.all; entity fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic ); end fdc; architecture fdc_rtl of fdc is begin i_finish: process (clk) begin if (clk'event and clk = '1') then if (reset = '1') then q <= '0'; else q <= d; end if; end if; end process; end fdc_rtl; iverilog-12_0/ivtest/ivltests/vhdl_sadd23_bit.v000066400000000000000000000016251435245347300216700ustar00rootroot00000000000000module check (input signed [22:0] a, b, c); wire signed [22:0] int_AB; assign int_AB = a + b; always @(a, b, int_AB, c) begin #1; if (int_AB != c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg signed [22:0] A, B); parameter MAX = 1 << 23; parameter S = 10000; int unsigned i; initial begin A = 0; B= 0; for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for selected assignments. module vhdl_selected_test; logic [1:0] sel; logic [3:0] in; logic out; vhdl_selected dut(sel, in, out); initial begin in = 4'b1010; sel = 1'b00; #1; if(out !== 1'b0) begin $display("FAILED 1"); $finish(); end sel = 1'b01; #1; if(out !== 1'b1) begin $display("FAILED 2"); $finish(); end sel = 1'b10; #1; if(out !== 1'b0) begin $display("FAILED 3"); $finish(); end sel = 1'b11; #1; if(out !== 1'b1) begin $display("FAILED 4"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_selected.vhd000066400000000000000000000024721435245347300220570ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for selected assignments. library ieee; use ieee.std_logic_1164.all; entity vhdl_selected is port(sel : in std_logic_vector(1 downto 0); inputs : in std_logic_vector(3 downto 0); output : out std_logic); end vhdl_selected; architecture test of vhdl_selected is begin with sel select output <= inputs(0) when "00", inputs(1) when "01", inputs(2) when "10", inputs(3) when "11", 'Z' when others; end test; iverilog-12_0/ivtest/ivltests/vhdl_shift.v000066400000000000000000000035621435245347300210710ustar00rootroot00000000000000// Copyr (c) 2015-2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for shift operators (logical and arithmetic) module shifter_test; reg signed [7:0] inp, out_srl, out_sll, out_sra, out_sla, out_shl_u, out_shr_u, out_shl_s, out_shr_s; shifter dut(inp, out_srl, out_sll, out_sra, out_sla, out_shl_u, out_shr_u, out_shl_s, out_shr_s); initial begin inp = 8'b11101100; #1; // wait for signal assignments if(out_srl !== 8'b01110110) begin $display("FAILED 1"); $finish(); end if(out_sll !== 8'b11011000) begin $display("FAILED 2"); $finish(); end if(out_sra !== 8'b11110110) begin $display("FAILED 3"); $finish(); end if(out_sla !== 8'b11011000) begin $display("FAILED 4"); $finish(); end if(out_shl_u !== 8'b10110000) begin $display("FAILED 5"); $finish(); end if(out_shr_u !== 8'b00111011) begin $display("FAILED 6"); $finish(); end if(out_shl_s !== 8'b10110000) begin $display("FAILED 7"); $finish(); end if(out_shr_s !== 8'b11111011) begin $display("FAILED 8"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_shift.vhd000066400000000000000000000034101435245347300213750ustar00rootroot00000000000000-- Copyright (c) 2015-2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for shift operators (logical and arithmetic) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_bit.all; entity shifter is port(input : in signed(7 downto 0); out_srl, out_sll, out_sra, out_sla : out signed(7 downto 0); out_shl_u, out_shr_u : out unsigned(7 downto 0); out_shl_s, out_shr_s : out signed(7 downto 0) ); end entity shifter; architecture test of shifter is begin process(input) -- test the unsigned variant of shift_left/right() functions variable unsigned_input : unsigned(7 downto 0); begin unsigned_input := input; out_srl <= input srl 1; out_sll <= input sll 1; out_sra <= input sra 1; out_sla <= input sla 1; out_shl_s <= shift_left(input, 2); out_shr_s <= shift_right(input, 2); out_shl_u <= shift_left(unsigned_input, 2); out_shr_u <= shift_right(unsigned_input, 2); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_signals.v000066400000000000000000000005051435245347300214060ustar00rootroot00000000000000module main; reg [4:0] src; wire dst; test dut(.i(src[3:0]), .o(dst)); initial begin for (src = 0 ; src < 16 ; src = src+1) begin #1 if (dst !== & src[3:0]) begin $display("FAILED: src=%b, dst=%b", src, dst); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_signals.vhd000066400000000000000000000017341435245347300217270ustar00rootroot00000000000000-- This VHDL was converted from Verilog using the -- Icarus Verilog VHDL Code Generator 0.10.0 (devel) (s20090923-656-gce5c263) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- Generated from Verilog module test (foo.v:3) entity test is port ( i : in unsigned(3 downto 0); o : out std_logic ); end entity; -- Generated from Verilog module test (foo.v:3) architecture from_verilog of test is signal tmp_s1 : std_logic; -- Temporary created at foo.v:6 signal tmp_s11 : std_logic; -- Temporary created at foo.v:6 signal tmp_s3 : std_logic; -- Temporary created at foo.v:6 signal tmp_s4 : std_logic; -- Temporary created at foo.v:6 signal tmp_s7 : std_logic; -- Temporary created at foo.v:6 signal tmp_s8 : std_logic; -- Temporary created at foo.v:6 begin tmp_s4 <= tmp_s1 and tmp_s3; tmp_s8 <= tmp_s4 and tmp_s7; o <= tmp_s8 and tmp_s11; tmp_s1 <= i(3); tmp_s3 <= i(2); tmp_s7 <= i(1); tmp_s11 <= i(0); end architecture; iverilog-12_0/ivtest/ivltests/vhdl_smul23_bit.v000066400000000000000000000016521435245347300217350ustar00rootroot00000000000000module check (input signed [22:0] a, b, input signed [45:0] c); wire signed [45:0] int_AB; assign int_AB = a * b; always @(a, b, int_AB, c) begin #1; if (int_AB != c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg signed [22:0] A, B); parameter MAX = 1 << 23; parameter S = 10000; int unsigned i; initial begin A = 0; B= 0; for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test string escaping in VHDL. module vhdl_string_test; logic start; vhdl_string dut(start); // nothing else is needed here endmodule iverilog-12_0/ivtest/ivltests/vhdl_string.vhd000066400000000000000000000024541435245347300215750ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test string escaping in VHDL. library ieee; use ieee.std_logic_1164.all; entity vhdl_string is port (start : in std_logic); end entity vhdl_string; architecture test of vhdl_string is begin process (start) variable test_str : string(1 to 4) := "VHDL"; begin report ""; report """"; report "test"; report test_str; report ("brackets test"); report ((("multiple brackets test"))); report """quotation "" marks "" test"""; end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_string_lim.v000066400000000000000000000020731435245347300221170ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test limited length strings in VHDL. module vhdl_string_lim_test; logic start, res; vhdl_string_lim dut(start, res); initial begin #1; if(res !== 1'b1) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_string_lim.vhd000066400000000000000000000024771435245347300224430ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test limited length strings in VHDL. library ieee; use ieee.std_logic_1164.all; entity vhdl_string_lim is port (start : in std_logic; res : out std_logic); end entity vhdl_string_lim; architecture test of vhdl_string_lim is begin process (start) variable a : string; variable b : string(1 to 1); variable c : string(1 to 5); begin a := "test string"; b := "a"; c := "abcde"; res <= (a = "test string") and (b = "a") and (c = "abcde"); end process; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_struct_array.v000066400000000000000000000007431435245347300224740ustar00rootroot00000000000000module main; reg [16:0] in; wire [15:0] out; foo_entity dut (.o_high1(out[15:12]), .o_low1(out[11:8]), .o_high0(out[7:4]), .o_low0(out[3:0]), .i_high1(in[15:12]), .i_low1(in[11:8]), .i_high0(in[7:4]), .i_low0(in[3:0])); initial begin for (in = 0 ; in < 256 ; in = in+1) begin #1 if (in !== out[15:0]) begin $display("FAILED -- out=%h, in=%h", out, in); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_struct_array.vhd000066400000000000000000000017061435245347300230100ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity foo_entity is port ( i_low0: in std_logic_vector (3 downto 0); i_high0: in std_logic_vector (3 downto 0); i_low1: in std_logic_vector (3 downto 0); i_high1: in std_logic_vector (3 downto 0); o_low0: out std_logic_vector (3 downto 0); o_high0: out std_logic_vector (3 downto 0); o_low1: out std_logic_vector (3 downto 0); o_high1: out std_logic_vector (3 downto 0) ); end foo_entity; architecture beh of foo_entity is type word is record high: std_logic_vector (3 downto 0); low: std_logic_vector (3 downto 0); end record; type dword is array (1 downto 0) of word; signal my_dword: dword; begin -- inputs my_dword(0).low <= i_low0; my_dword(0).high <= i_high0; my_dword(1).low <= i_low1; my_dword(1).high <= i_high1; -- outputs o_low0 <= my_dword(0).low; o_high0 <= my_dword(0).high; o_low1 <= my_dword(1).low; o_high1 <= my_dword(1).high; end beh; iverilog-12_0/ivtest/ivltests/vhdl_subprogram.v000066400000000000000000000023211435245347300221250ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Tests for various subprogram features (see the responding VHDL file for // details). module subprogram_test; subprogram dut(); initial begin #1; // wait for signal assignment if(dut.negated !== 'b00111000) begin $display("FAILED 1"); $finish; end if(dut.reversed != 'b11100001) begin $display("FAILED 2"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_subprogram.vhd000066400000000000000000000034411435245347300224450ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests for various subprogram features. library ieee; use ieee.std_logic_1164.all; -- tests subprograms imported from an external library use work.subprogram_pkg.all; entity subprogram is end; architecture behaviour of subprogram is function negate(input_word : std_logic_vector(7 downto 0)) -- tests using undefined size std_logic_vector as a return type return std_logic_vector is -- tests variable declaration in subprograoms variable output_word : std_logic_vector(7 downto 0); begin for i in 7 downto 0 loop -- tests distuingishing between vector and function call basing on the -- function parameter output_word(i) := not input_word(i); end loop; return output_word; end function; signal negated : std_logic_vector(7 downto 0); signal reversed : std_logic_vector(7 downto 0); begin -- parameter type is determined by checking the parameter type in function declaration negated <= negate("11000111"); reversed <= reverse("10000111"); end; iverilog-12_0/ivtest/ivltests/vhdl_subprogram_pkg.vhd000066400000000000000000000026041435245347300233060ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Tests for various subprogram features. library ieee; use ieee.std_logic_1164.all; -- tests functions defined in packages package subprogram_pkg is function reverse(input_word : std_logic_vector(7 downto 0)) return std_logic_vector; end subprogram_pkg; package body subprogram_pkg is function reverse(input_word : std_logic_vector(7 downto 0)) return std_logic_vector is variable output_word : std_logic_vector(7 downto 0); begin for i in 7 downto 0 loop output_word(i) := input_word(7 - i); end loop; return output_word; end function; end subprogram_pkg; iverilog-12_0/ivtest/ivltests/vhdl_subtypes.v000066400000000000000000000025621435245347300216310ustar00rootroot00000000000000// Copyright (c) 2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for subtype definitions. module vhdl_subtypes_test; int a, b, c; time d; int e; vhdl_subtypes dut(a, b, c, d, e); initial begin #1; if(a !== 1) begin $display("FAILED"); $finish(); end if(b !== 2) begin $display("FAILED"); $finish(); end if(c !== 3) begin $display("FAILED"); $finish(); end if(d !== 4) begin $display("FAILED"); $finish(); end if(e !== 5) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_subtypes.vhd000066400000000000000000000025121435245347300221400ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for subtype definitions. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_bit.all; use work.vhdl_subtypes_pkg.all; entity vhdl_subtypes is port( a : out int_type_const; b : out int_type; c : out int_type_downto; d : out time_type; e : out uns_type_const ); end vhdl_subtypes; architecture test of vhdl_subtypes is begin process begin a <= 1; b <= 2; c <= 3; d <= 4 s; e <= 5; wait; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_subtypes_pkg.vhd000066400000000000000000000024411435245347300230020ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for subtype definitions. library ieee; use ieee.numeric_bit.all; package vhdl_subtypes_pkg is constant type_range : integer := 10; subtype int_type_const is integer range 0 to type_range-1; subtype int_type is integer range 0 to 7; subtype int_type_downto is integer range 8 downto 1; subtype time_type is time range 0 fs to 1 ms; subtype uns_type_const is unsigned(7 downto 0); end vhdl_subtypes_pkg; package body vhdl_subtypes_pkg is end vhdl_subtypes_pkg; iverilog-12_0/ivtest/ivltests/vhdl_test1.v000066400000000000000000000006001435245347300210020ustar00rootroot00000000000000module main; wire [15:0] out; reg [16:0] in; mask dut (.\output (out), .\input (in[15:0])); wire [15:0] out_ref = in[15:0] & 16'haaaa; initial begin for (in = 0 ; in[16] == 0 ; in = in+1) #1 if (out !== out_ref) begin $display("FAILED: in=%b, out=%b, out_ref=%b", in, out, out_ref); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_test1.vhd000066400000000000000000000010761435245347300213260ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 28.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mask is port (input : in std_logic_vector(15 downto 0); output : out std_logic_vector(15 downto 0) ); end; architecture behaviour of mask is begin L: process(input) variable tmp : std_logic_vector(15 downto 0); begin output <= tmp; --this shouln't really change anything tmp := input; tmp := tmp and "1010101010101010"; output <= tmp; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_test2.v000066400000000000000000000007231435245347300210110ustar00rootroot00000000000000module main; wire [15:0] out; reg [16:0] in; reg [15:0] mask; mask dut (.\output (out), .\input (in[15:0]), .mask(mask)); wire [15:0] out_ref = in[15:0] & mask; initial begin for (in = 0 ; in[16] == 0 ; in = in+1) begin mask = $random; #1 if (out !== out_ref) begin $display("FAILED: in=%b, out=%b, mask=%b, out_ref=%b", in, out, mask, out_ref); $finish; end end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_test2.vhd000066400000000000000000000010461435245347300213240ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 28.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mask is port (input : in std_logic_vector(15 downto 0); mask : in std_logic_vector(15 downto 0); output : out std_logic_vector(15 downto 0) ); end; architecture behaviour of mask is begin L: process(input) variable tmp : std_logic_vector(15 downto 0); begin tmp := input; tmp := tmp and mask; output <= tmp; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_test3.v000066400000000000000000000005011435245347300210040ustar00rootroot00000000000000module main; reg clk; reg [4:0] in; wire [15:0] out; dummy dut (.clk(clk), .\input (in[3:0]), .\output (out)); initial begin clk = 0; for (in = 0 ; in <= 16 ; in = in+1) begin #1 clk = 1; #1 clk = 0; $display("input = %b, output=%b", in[3:0], out); end end endmodule // main iverilog-12_0/ivtest/ivltests/vhdl_test3.vhd000066400000000000000000000021261435245347300213250ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 28.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dummy is port (clk : in std_logic; input : in std_logic_vector(3 downto 0); output : out std_logic_vector(15 downto 0) ); end; architecture behaviour of dummy is begin L: process(clk) variable one : integer; -- mix integers and unsigned variable a : unsigned (6 downto 0); -- variable b,c,d : unsigned(6 downto 0); begin if(clk'event and clk = '1') then --do some mess around.. a(3 downto 0) := unsigned(input); a(6 downto 4) := "000"; one := 1; b := a + one; --unsigned plus integer b := a + 1; --variable plus constant integer c := a + a; -- c := c - b; --two assignments in a row to the same variable d := c + 2; output(6 downto 0) <= std_logic_vector(d); --signal assignment output(15 downto 7) <= (others => '0'); end if; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_test4.v000066400000000000000000000006561435245347300210200ustar00rootroot00000000000000module test; wire [7:0] o1, o2, o3; dummy foo(.o1(o1), .o2(o2), .o3(o3)); initial begin #1 if (o1 !== 8'h00) begin $display("FAILED -- o1 = %b", o1); $finish; end if (o2 !== 8'h08) begin $display("FAILED -- o2 = %b", o2); $finish; end if (o3 !== 8'h80) begin $display("FAILED == o3 = %b", o3); $finish; end $display("PASSED"); end // initial begin endmodule iverilog-12_0/ivtest/ivltests/vhdl_test4.vhd000066400000000000000000000007541435245347300213330ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 27.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dummy is port (o1: out std_logic_vector(7 downto 0); o2: out std_logic_vector(7 downto 0); o3: out std_logic_vector(7 downto 0) ); end; architecture behaviour of dummy is begin o1 <= (others => '0'); o2 <= (3 => '1', others => '0'); o3 <= (7=>'1', 6|5|4|3|2|1|0 => '0', others => '1'); --tricky end; iverilog-12_0/ivtest/ivltests/vhdl_test5.v000066400000000000000000000024651435245347300210210ustar00rootroot00000000000000// // Author: Pawel Szostek (pawel.szostek@cern.ch) // Date: 01.08.2011 `timescale 1ns/1ps module stimulus (output reg [7:0] a); parameter S = 20000; int unsigned j,i; initial begin for(i=0; i= 10) ret = 1'b1; else if(temp >= 4) ret = 1'b0; else if(temp >= 2) ret = 1'bx; else ret = 1'b0; inject = ret; end endfunction endmodule module main; wire [7:0] i, o; wire [0:7] o_vl; dummy dummy_vhdl(o, i); stimulus stim(i); assign o_vl = i; always @(i) begin #1; if(o !== o_vl) begin $display("OUTPUT: ", o); $display("INPUT: ", i); $display("CORRECT: ", o_vl); end end initial begin #120000; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_test5.vhd000066400000000000000000000005531435245347300213310ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 27.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dummy is port (o1: out std_logic_vector(7 downto 0); -- intentionally messed indices i1: in std_logic_vector(0 to 7) -- ); end; architecture behaviour of dummy is begin o1 <= i1; end; iverilog-12_0/ivtest/ivltests/vhdl_test6.v000066400000000000000000000024701435245347300210160ustar00rootroot00000000000000// // Author: Pawel Szostek (pawel.szostek@cern.ch) // Date: 01.08.2011 `timescale 1ns/1ps module stimulus (output reg [7:0] a); parameter S = 20000; int unsigned j,i; initial begin for(i=0; i= 10) ret = 1'b1; else if(temp >= 4) ret = 1'b0; else if(temp >= 2) ret = 1'bx; else ret = 1'b0; inject = ret; end endfunction endmodule module main; wire [7:0] i, o; wire [0:7] o_vl; dummy dummy_vhdl(o, i); stimulus stim(i); assign o_vl = i; always @(i) begin #1 if(o !== o_vl) begin $display("OUTPUT: ", o); $display("INPUT: ", i); $display("CORRECT: ", o_vl); end end initial begin #120000; $display("PASSED"); $finish; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_test6.vhd000066400000000000000000000005531435245347300213320ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 27.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dummy is port (o1: out std_logic_vector(8 downto 1); -- intentionally messed indices i1: in std_logic_vector(0 to 7) -- ); end; architecture behaviour of dummy is begin o1 <= i1; end; iverilog-12_0/ivtest/ivltests/vhdl_test7.v000066400000000000000000000027561435245347300210260ustar00rootroot00000000000000// // Author: Pawel Szostek (pawel.szostek@cern.ch) // Date: 01.08.2011 `timescale 1ns/1ps module dummy_v( input [7:0] in, output reg [7:0] out); assign out = {in[7], 7'b1111111}; //there is no equivalent to vhdl's `others' endmodule module stimulus (output reg [7:0] a); parameter S = 20000; int unsigned j,i; initial begin for(i=0; i= 10) ret = 1'b1; else if(temp >= 4) ret = 1'b0; else if(temp >= 2) ret = 1'bx; else ret = 1'b0; inject = ret; end endfunction endmodule module main; wire [7:0] i,o; wire [7:0] veri; dummy dummy_vhdl(i,o); dummy_v dummy_verilog(i, veri); stimulus stim(i); always @(i) begin #1; if(o != veri) begin $display("ERROR!"); $display("VERILOG: ", veri); $display("VHDL: ", o); $stop; end end initial begin #12000; #10; $display("PASSED"); //stop; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_test7.vhd000066400000000000000000000011651435245347300213330ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 28.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity dummy is port ( input : in std_logic_vector(7 downto 0); output : out std_logic_vector(7 downto 0) ); end; architecture behaviour of dummy is begin L: process(input) variable tmp : std_logic_vector(7 downto 0); begin tmp := input; -- use multiple assignments to the same variable tmp := (7 => input(7), others => '1'); -- inluding slices in a process output <= tmp; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_test8.v000066400000000000000000000030201435245347300210100ustar00rootroot00000000000000// // Author: Pawel Szostek (pawel.szostek@cern.ch) // Date: 01.08.2011 `timescale 1ns/1ps module match_bits_v(input [7:0] a,b, output reg [7:0] match); integer i; wire ab_xor; always @(a or b) begin for (i=7; i>=0; i=i-1) begin match[i] = ~(a[i]^b[i]); end end endmodule module check(input [7:0] a,b,o_vhdl, o_verilog); always @(a or b) begin #1 if (o_vhdl !== o_verilog) begin $display("ERROR!"); $display("VERILOG: ", o_verilog); $display("VHDL: ", o_vhdl); $finish; end end endmodule module stimulus (output reg [7:0] a,b); parameter S = 20000; int unsigned i,j,k,l; initial begin //stimulate data for (i=0; i= 10) inject = 1'b1; else inject = 1'b0; end endfunction endmodule module main; wire [7:0] a,b,o_vhdl, o_verilog; match_bits match_vhdl(a,b,o_vhdl); match_bits_v match_verilog(a,b,o_verilog); stimulus stim(a,b); check c(a,b,o_vhdl, o_verilog); endmodule iverilog-12_0/ivtest/ivltests/vhdl_test8.vhd000066400000000000000000000007261435245347300213360ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 27.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity match_bits is port (a,b: in std_logic_vector(7 downto 0); matches : out std_logic_vector(7 downto 0) ); end; architecture behaviour of match_bits is begin process(a, b) begin for i in 7 downto 0 loop matches(i) <= not (a(i) xor b(i)); end loop; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_test9.v000066400000000000000000000030571435245347300210230ustar00rootroot00000000000000// // Author: Pawel Szostek (pawel.szostek@cern.ch) // Date: 01.08.2011 `timescale 1ns/1ps module count_ones_v(input [15:0] vec, output reg [4:0] count); integer i; integer result; always @(vec) begin result = 0; for (i=15; i>=0; i=i-1) begin if(vec[i] == 1'b1) begin result = result + 1; end end count = result; end endmodule module check(input [15:0] a, input [4:0] o_vhdl, input [4:0] o_verilog); reg ena; initial begin ena = 0; #10; ena = 1; end always @(a)begin #1 if (ena == 0) begin end else if (o_vhdl !== o_verilog) begin $display("ERROR!"); $display("VERILOG: ", o_verilog); $display("VHDL: ", o_vhdl); end end endmodule module stimulus (output reg [15:0] a); parameter S = 20000; int unsigned i,j,k,l; initial begin //stimulate data for (i=0; i= 10) inject = 1'b1; else inject = 1'b0; end endfunction endmodule module main; wire [15:0] a; wire [4:0] o_vhdl, o_verilog; count_ones_v c_vhdl(a,o_vhdl); count_ones c_verilog(a,o_verilog); stimulus stim(a); check c(a,o_vhdl, o_verilog); initial begin #120000; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_test9.vhd000066400000000000000000000011661435245347300213360ustar00rootroot00000000000000-- -- Author: Pawel Szostek (pawel.szostek@cern.ch) -- Date: 27.07.2011 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity count_ones is port ( vec: in std_logic_vector(15 downto 0); count : out unsigned(4 downto 0)); end; architecture behaviour of count_ones is begin process(vec) variable result : unsigned(4 downto 0); begin result := to_unsigned(0, result'length); for i in 15 downto 0 loop if vec(i) = '1' then result := result +1; end if; end loop; count <= result; end process; end; iverilog-12_0/ivtest/ivltests/vhdl_textio_read.v000066400000000000000000000024521435245347300222600ustar00rootroot00000000000000// Copyright (c) 2015-2016 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test reading files using std.textio library. module vhdl_textio_read_test; reg clk, active, ok; int line_counter; vhdl_textio_read dut(clk, active, line_counter, ok); always #1 clk = ~clk; initial begin clk = 0; active = 1; // wait until the input file is read #14 active = 0; if(ok !== 1'b1) begin $display("FAILED"); $finish(); end $display("PASSED"); #0; // Need to wait for the file to close before we finish! $finish(); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_textio_read.vhd000066400000000000000000000055731435245347300226030ustar00rootroot00000000000000-- Copyright (c) 2015-2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test reading files using std.textio library. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; entity vhdl_textio_read is port( clk, active : in std_logic; line_counter : out integer; ok : out std_logic ); end vhdl_textio_read; architecture test of vhdl_textio_read is begin read_data: process(clk, active) file data_file : text; variable data_line : line; variable data_string : string(6 downto 1); variable data_int, data_hex : integer; variable data_bool : boolean; variable data_real : real; variable data_time : time; variable data_logic : std_logic_vector(5 downto 0); begin if rising_edge(active) then file_open(data_file, "vhdl_textio.tmp", read_mode); line_counter := 0; elsif falling_edge(active) then file_close(data_file); end if; if rising_edge(clk) and active = '1' then readline(data_file, data_line); line_counter := line_counter + 1; case line_counter is -- Test reading different variable types when 1 => read(data_line, data_int); when 2 => read(data_line, data_bool); when 3 => read(data_line, data_time); when 4 => hread(data_line, data_hex); when 5 => read(data_line, data_real); when 6 => read(data_line, data_string); when 7 => read(data_line, data_logic); -- Verify the read data if data_int = 123 and data_bool = true and data_time = 100 s and data_hex = x"f3" and data_real = 12.21 and data_string = "string" and data_logic = "1100XZ" then ok <= '1'; end if; end case; end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_textio_write.v000066400000000000000000000020261435245347300224740ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test writing files using std.textio library. module vhdl_textio_write_test; reg write; vhdl_textio_write dut(write); initial begin // this test is later verified by vhdl_read_textio $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_textio_write.vhd000066400000000000000000000044451435245347300230170ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test writing files using std.textio library. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; entity vhdl_textio_write is port( wr : in std_logic ); end vhdl_textio_write; architecture test of vhdl_textio_write is begin write_data: process(wr) file data_file : text open write_mode is "vhdl_textio.tmp"; variable data_line : line; variable data_string : string(6 downto 1); variable data_int, data_hex : integer; variable data_bool : boolean; variable data_real : real; variable data_time : time; variable data_vector : std_logic_vector(5 downto 0); begin data_string := "string"; data_int := 123; data_hex := X"F3"; data_bool := true; data_real := 12.21; data_time := 100 s; data_vector := "1100XZ"; -- Test writing different variable types write(data_line, data_int); writeline(data_file, data_line); write(data_line, data_bool); writeline(data_file, data_line); write(data_line, data_time); writeline(data_file, data_line); hwrite(data_line, data_hex); writeline(data_file, data_line); write(data_line, data_real); writeline(data_file, data_line); write(data_line, data_string); writeline(data_file, data_line); write(data_line, data_vector); writeline(data_file, data_line); end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_time.v000066400000000000000000000021441435245347300207050ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for time related expressions. module vhdl_time_test; logic a, b; time tout, tin; vhdl_time dut(a, b, tout, tin); always @(a) begin $display("a changed at %t", $realtime); end initial begin tin = 100ns; // Start the test b = 1'b0; b = 1'b1; $display(tout); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_time.vhd000066400000000000000000000037661435245347300212340ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for time related expressions. library ieee; use ieee.std_logic_1164.all; use work.time_pkg.all; entity vhdl_time is port(a : out std_logic; b : in std_logic; tout : out time; tin : in time); end vhdl_time; architecture test of vhdl_time is signal time_sig : time_subtype := 100 ns; begin tout <= 140 ns; process(b) variable time_var : time; begin if(rising_edge(b)) then time_var := 100 ns; time_sig := 500 ns; a := '0'; wait for 50 ns; a := '1'; wait for time_sig; -- signal a := '0'; wait for time_const; -- constant a := '1'; wait for time_var; -- variable a := '0'; wait for (time_sig + time_const + time_var); a := '1'; -- Modify variable & signal values time_var := 10 ns; wait for time_var; a := '0'; time_sig := 20 ns; wait for time_sig; a := '1'; -- Test time read from port wait for tin; a := '0'; end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_time_pkg.vhd000066400000000000000000000020771435245347300220670ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for time related expressions. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package time_pkg is constant time_const : time := 200 ns; subtype time_subtype is time range 0 fs to 1 ms; end time_pkg; package body time_pkg is end time_pkg; iverilog-12_0/ivtest/ivltests/vhdl_timescale_1ns.cfg000066400000000000000000000000231435245347300227620ustar00rootroot00000000000000+timescale+1ns/1ns iverilog-12_0/ivtest/ivltests/vhdl_to_integer.v000066400000000000000000000023131435245347300221040ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for to_integer() function. module to_int_test; logic unsigned [7:0] unsign; logic signed [7:0] sign; to_int dut(unsign, sign); initial begin unsign = 8'b11001100; sign = 8'b11001100; #1; if(dut.s_natural !== 204) begin $display("FAILED 1"); $finish(); end if(dut.s_integer !== -52) begin $display("FAILED 2"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_to_integer.vhd000066400000000000000000000024021435245347300224170ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for to_integer() function. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity to_int is port ( unsign : in unsigned(7 downto 0); sign : in signed(7 downto 0) ); end to_int; architecture test of to_int is signal s_natural : natural; signal s_integer : integer; begin process (unsign) begin s_natural <= (unsign); end process; process (sign) begin s_integer <= (sign); end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_uadd23_bit.v000066400000000000000000000016061435245347300216710ustar00rootroot00000000000000module check (input unsigned [22:0] a, b, c); wire unsigned [22:0] int_AB; assign int_AB = a + b; always @(a, b, int_AB, c) begin #1; if (int_AB != c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [22:0] A, B); parameter MAX = 1 << 23; parameter S = 10000; int unsigned i; initial begin A = 0; B= 0; for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Unary minus operator test module vhdl_unary_minus_test; logic signed [7:0] data_in; logic signed [7:0] data_out; logic clk = 1'b0; vhdl_unary_minus dut(data_in, clk, data_out); always #10 clk = ~clk; initial begin #5; data_in = -12; #20; if(data_out !== 12) begin $display("FAILED 1"); $finish(); end data_in = 33; #20; if(data_out !== -33) begin $display("FAILED 2"); $finish(); end $display("PASSED"); $finish(); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_unary_minus.vhd000066400000000000000000000023461435245347300226400ustar00rootroot00000000000000-- Copyright (c) 2016 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and-or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Unary minus operator test library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_unary_minus is port(data_in : in signed(7 downto 0); clk : in std_logic; data_out : out signed(7 downto 0) ); end vhdl_unary_minus; architecture test of vhdl_unary_minus is begin process(clk) begin if rising_edge(clk) then data_out <= -data_in; end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_unbounded.v000066400000000000000000000024251435245347300217340ustar00rootroot00000000000000// Copyright (c) 2014 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Basic test for the unbounded arrays in VHDL. module vhdl_unbounded_array_test; vhdl_unbounded_array dut(); initial begin #1; // wait for signal assignment if(dut.sig_logic != 'b01010101) begin $display("FAILED 1"); $finish; end if(dut.sig_integer[2] != 1) begin $display("FAILED 2"); $finish; end if(dut.sig_real[1] != 2.5) begin $display("FAILED 3"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_unbounded.vhd000066400000000000000000000027561435245347300222570ustar00rootroot00000000000000-- Copyright (c) 2014 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Basic test for the unbounded arrays in VHDL. library ieee; use ieee.std_logic_1164.all; entity vhdl_unbounded_array is end vhdl_unbounded_array; architecture test of vhdl_unbounded_array is -- This can be translated as an unpacked array in SystemVerilog type unb_logic is array (integer range <>) of std_logic; -- These have to be packed arrays type unb_integer is array (natural range <>) of integer; type unb_real is array (integer range <>) of real; signal sig_logic : unb_logic(7 downto 0); signal sig_integer : unb_integer(3 downto 0); signal sig_real : unb_real(0 to 3); begin sig_logic <= "01010101"; sig_integer(2) <= 1; sig_real(1) <= 2.5; end architecture test; iverilog-12_0/ivtest/ivltests/vhdl_unbounded_func.v000066400000000000000000000026701435245347300227510ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Basic test for functions that work with unbounded vectors as return // and param types. module vhdl_unbounded_func_test(); vhdl_unbounded_func dut(); initial begin #1; // wait for signal assignment if(dut.test_out1 != 'b1010100110) begin $display("FAILED 1"); $finish; end if(dut.test_out2 != 'b010110) begin $display("FAILED 2"); $finish; end if(dut.neg_test_out1 != ~dut.test_out1) begin $display("FAILED 3"); $finish; end if(dut.neg_test_out2 != ~dut.test_out2) begin $display("FAILED 4"); $finish; end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_unbounded_func.vhd000066400000000000000000000036411435245347300232640ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Basic test for functions that work with unbounded vectors as return -- and param types. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.vhdl_unbounded_func_pkg.all; package included_pkg is function negator(word_i : std_logic_vector) return std_logic_vector; end included_pkg; package body included_pkg is function negator(word_i : std_logic_vector) return std_logic_vector is variable word_o : std_logic_vector (word_i'left downto word_i'right); begin for I in word_i'range loop word_o (I) := not word_i(I); end loop; return word_o; end function; end included_pkg; entity vhdl_unbounded_func is end vhdl_unbounded_func; architecture test of vhdl_unbounded_func is signal test_out1 : std_logic_vector(9 downto 0); signal test_out2 : std_logic_vector(5 downto 0); signal neg_test_out1 : std_logic_vector(9 downto 0); signal neg_test_out2 : std_logic_vector(5 downto 0); begin test_out1 <= f_manch_encoder(B"11101"); test_out2 <= f_manch_encoder(B"001"); neg_test_out1 <= negator(test_out1); neg_test_out2 <= negator(test_out2); end test; iverilog-12_0/ivtest/ivltests/vhdl_unbounded_func_pkg.vhd000066400000000000000000000027771435245347300241360ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Basic test for functions that work with unbounded vectors as return -- and param types. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package vhdl_unbounded_func_pkg is function f_manch_encoder (word_i :std_logic_vector) return std_logic_vector; end vhdl_unbounded_func_pkg; package body vhdl_unbounded_func_pkg is function f_manch_encoder (word_i : std_logic_vector) return std_logic_vector is variable word_manch_o : std_logic_vector((2*word_i'length) - 1 downto 0); begin for I in word_i'range loop word_manch_o (I*2) := not word_i(I); word_manch_o (I*2+1) := word_i(I); end loop; return word_manch_o; end function; end vhdl_unbounded_func_pkg; iverilog-12_0/ivtest/ivltests/vhdl_usub23_bit.v000066400000000000000000000016611435245347300217330ustar00rootroot00000000000000module check (input unsigned [22:0] a, b, c); wire unsigned [22:0] int_AB; assign int_AB = a - b; always @(a, b, int_AB, c) begin #1; if (int_AB != c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [22:0] A, B); parameter MAX = 1 << 23; parameter S = 10000; int unsigned i; initial begin A = 0; B= 0; for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for variable initialization. module vhdl_var_init_test; logic init; logic [7:0] slv; bit b; int i; vhdl_var_init dut(init, slv, b, i); initial begin init = 0; #1 init = 1; #1; if(slv !== 8'b01000010) begin $display("FAILED 1"); $finish(); end if(b !== false) begin $display("FAILED 2"); $finish(); end if(i !== 42) begin $display("FAILED 3"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_var_init.vhd000066400000000000000000000026701435245347300221020ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- @author Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test for variable initialization. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vhdl_var_init is port(init : in std_logic; slv : out std_logic_vector(7 downto 0); bool : out boolean; i : out integer ); end vhdl_var_init; architecture test of vhdl_var_init is begin process(init) variable var_slv : std_logic_vector(7 downto 0) := "01000010"; variable var_bool : boolean := false; variable var_int : integer := 42; begin if rising_edge(init) then slv <= var_slv; bool <= var_bool; i <= var_int; end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_wait.v000066400000000000000000000022271435245347300207150ustar00rootroot00000000000000// Copyright (c) 2015 CERN // @author Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // 'wait on' & 'wait until' test module vhdl_wait_test; logic [1:0] a, b; vhdl_wait dut(a, b); always @(posedge b[0]) begin $display("wait 1 acknowledged"); // complete "wait 2" a[1] = 1'b0; end always @(posedge b[1]) begin $display("wait 2 acknowledged"); end initial begin // complete "wait 1" a = 2'b00; end endmodule iverilog-12_0/ivtest/ivltests/vhdl_wait.vhd000066400000000000000000000027101435245347300212260ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- @author Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- 'wait on' & 'wait until' test library ieee; use ieee.std_logic_1164.all; entity vhdl_wait is port(a : in std_logic_vector(1 downto 0); b : out std_logic_vector(1 downto 0)); end vhdl_wait; architecture test of vhdl_wait is begin process begin report "final wait test"; wait; end process; process begin wait on a(0); report "wait 1 completed"; -- acknowledge wait 1 b(0) <= '1'; end process; process begin wait until(a(1) = '1' and a(1)'event); report "wait 2 completed"; -- acknowledge wait 2 b(1) <= '1'; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_while.v000066400000000000000000000020701435245347300210550ustar00rootroot00000000000000// Copyright (c) 2015 CERN // Maciej Suminski // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test while loops in VHDL. module vhdl_while_test; logic start; int out; vhdl_while dut(start, out); initial begin start = 1; #1; if(out !== 10) begin $display("FAILED"); $finish(); end $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/vhdl_while.vhd000066400000000000000000000024461435245347300214000ustar00rootroot00000000000000-- Copyright (c) 2015 CERN -- Maciej Suminski -- -- This source code is free software; you can redistribute it -- and/or modify it in source code form under the terms of the GNU -- General Public License as published by the Free Software -- Foundation; either version 2 of the License, or (at your option) -- any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA -- Test while loops in VHDL. library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity vhdl_while is port( start: in std_logic; output: out integer ); end vhdl_while; architecture test of vhdl_while is begin process(start) variable a : integer := 0; begin if(rising_edge(start)) then while (a < 10) loop a := a + 1; end loop; output <= a; end if; end process; end test; iverilog-12_0/ivtest/ivltests/vhdl_xnor104_stdlogic.v000066400000000000000000000035041435245347300230530ustar00rootroot00000000000000module check (input unsigned [103:0] a, b, c); wire [103:0] int_AB; assign int_AB = ~(a ^ b); always @(a, b, int_AB, c) begin #1; if (int_AB !== c) begin $display("ERROR"); $finish; end end endmodule module stimulus (output reg unsigned [103:0] A, B); parameter S = 2000; int unsigned i; initial begin A = 0; B= 0; // values with 0, 1 for (i=0; i // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // Test for vvp_net_fun_t::recv_vec4_pv() implementation (vvp). module vvp_recv_vec4_pv (input wire logic clk, input wire logic inp, output wire logic[16:0] arr_out); logic[16:0] arr; always begin arr[15:0] <= arr[16:1]; @(clk); wait(clk == 1'b1); end assign arr[16] = inp; assign arr_out = arr; endmodule module vvp_recv_vec4_pv_test; logic clk, inp; logic [16:0] arr, src; vvp_recv_vec4_pv dut(clk, inp, arr); always #5 clk <= ~clk; initial begin int i; src <= 17'b01101110010011011; clk <= 1'b1; #5; for(i = 0; i < 17; i = i + 1) begin #10 inp = src[i]; end #5; // wait for the last assignment occuring in the for loop above if(arr !== src) begin $display("FAILED"); end else begin $display("PASSED"); end $finish(); end endmodule iverilog-12_0/ivtest/ivltests/vvp_scalar_value.v000066400000000000000000000015561435245347300222740ustar00rootroot00000000000000module vvp_scalar_value(); reg [2:0] v1; reg [2:0] v2; wire [2:0] w1; wire [2:0] w2; wire [2:0] w3; assign ( highz1, strong0) w1 = v1; assign (strong1, highz0) w2 = v1; assign ( highz1, strong0) w3 = v1; assign (strong1, highz0) w3 = v2; reg failed; initial begin failed = 0; v1 = 3'bz10; #1; $display("%b %v %v %v", w1, w1[2], w1[1], w1[0]); if (w1 !== 3'bzz0) failed = 1; $display("%b %v %v %v", w2, w2[2], w2[1], w2[0]); if (w2 !== 3'bz1z) failed = 1; v2 = 3'b000; #1; $display("%b %v %v %v", w3, w3[2], w3[1], w3[0]); if (w3 !== 3'bzz0) failed = 1; v2 = 3'b111; #1; $display("%b %v %v %v", w3, w3[2], w3[1], w3[0]); if (w3 !== 3'b11x) failed = 1; v2 = 3'bzzz; #1; $display("%b %v %v %v", w3, w3[2], w3[1], w3[0]); if (w3 !== 3'bzz0) failed = 1; if (failed) $display("FAILED"); else $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wait1.v000066400000000000000000000025311435245347300177570ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg foo = 0; initial #10 foo = 1; initial #1 begin if (foo !== 1'b0) begin $display("FAILED -- foo before wait is %b", foo); $finish; end // This wait without a statement has caused a few bugs. wait (foo) ; if (foo !== 1'b1) begin $display("FAILED -- foo after wait is %b", foo); $finish; end if ($time != 10) begin $display("FAILED -- $time after wait is %t", $time); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wait2.v000066400000000000000000000025341435245347300177630ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg foo = 1'bx; initial #10 foo = 1; initial #1 begin if (foo !== 1'bx) begin $display("FAILED -- foo before wait is %b", foo); $finish; end // This wait without a statement has caused a few bugs. wait (foo) ; if (foo !== 1'b1) begin $display("FAILED -- foo after wait is %b", foo); $finish; end if ($time != 10) begin $display("FAILED -- $time after wait is %t", $time); $finish; end $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wait3.v000066400000000000000000000014371435245347300177650ustar00rootroot00000000000000/* * this test attempts to show a problem with the waits. This skip * and skip2 modules should have identical behavior. */ module skip(r,a); input r; output a; wire r; reg a; initial a=0; always begin wait(r); #1 a=1; wait(!r); #1 a=0; end endmodule module skip2(r,a); input r; output a; wire r; reg a; initial a=0; always @ (r or a) begin case ({r,a}) 00: ; // idle 10: #1 a=1; 11: ; // idle 01: #1 a=0; endcase end endmodule module test; reg r1; wire a1; reg clk; // skip2 skip1(r1,a1); // simulates as expected skip skip1(r1,a1); // simulation hangs always #50 clk= !clk; initial begin $monitor($time," ",r1,a1); $display("starting"); #100 r1=0; #100 r1=1; wait(a1); #100 r1=0; #1000 $display("timeout"); $finish(0); end endmodule iverilog-12_0/ivtest/ivltests/wait_fork.v000066400000000000000000000010511435245347300207130ustar00rootroot00000000000000module top; reg [4:1] res; reg pass; initial begin pass = 1'b1; res = 4'b0000; fork #3 res[3] = 1'b1; #4 res[4] = 1'b1; join_none fork #1 res[1] = 1'b1; #2 res[2] = 1'b1; join_any if (res != 4'b0001) begin $display("Error: Only first process should have run: %b", res); pass = 1'b0; end wait fork; if (res != 4'b1111) begin $display("Error: All processes should have run: %b", res); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/warn_opt_sys_tf.v000066400000000000000000000006441435245347300221550ustar00rootroot00000000000000// This will not generate a RE if these are calling the correct warning. module top; integer res; initial begin // $countdrivers is now implemented res = $getpattern; $input; $key; $nokey; $list; $log; $nolog; $save; $restart; $incsave; res = $scale; $scope; $showscopes; $showvars; $sreadmemb; $sreadmemh; $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/when_else.vhd000066400000000000000000000011441435245347300212160ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; entity foo_entity is port( data_i : in std_logic_vector(1 downto 0); data_o, data_o2, data_o3 : out std_logic_vector(3 downto 0) ); end foo_entity; architecture behaviour of foo_entity is begin data_o <= "0001" when ( data_i="00" ) else "0010" when ( data_i="01" ) else "0100" when ( data_i="10" ) else "1000"; -- test cases without the final 'else' statement data_o2 <= "0101" when ( data_i="01" ); data_o3 <= "1100" when ( data_i="10" ) else "0011" when ( data_i="01" ); end behaviour; iverilog-12_0/ivtest/ivltests/width.v000066400000000000000000000024411435245347300200510ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [7:0] a; reg [6:-1] b; initial begin a = 1; b = 2; if (a !== 8'h01) begin $display("FAILED -- to initialize a: %b", a); $finish; end if (b !== 8'h02) begin $display("FAILED -- to initialize b: %b", b); $finish; end b = a; if (b !== 8'h01) begin $display("FAILED -- to copy a to b: %b", b); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/wild_cmp_const.v000066400000000000000000000125351435245347300217430ustar00rootroot00000000000000module top; parameter weq1 = 2'b01 ==? 2'b01; parameter weq2 = 2'b01 ==? 2'b00; parameter weq3 = 2'b0x ==? 2'b00; parameter weq4 = 2'b00 ==? 2'b0x; parameter weq5 = 2'b01 ==? 2'b0x; parameter weq6 = 2'b0z ==? 2'b0x; parameter weq7 = 2'b0x ==? 2'b0x; parameter weq8 = 2'b00 ==? 2'b0z; parameter weq9 = 2'b01 ==? 2'b0z; parameter weqa = 2'b0z ==? 2'b0z; parameter weqb = 2'b0x ==? 2'b0z; parameter weqc = 2'bx0 ==? 2'b00; parameter weqd = 2'bx1 ==? 2'b00; parameter weqe = 2'b1x ==? 2'b00; parameter weqf = 3'b100 ==? 2'b00; parameter wneq1 = 2'b01 !=? 2'b01; parameter wneq2 = 2'b01 !=? 2'b00; parameter wneq3 = 2'b0x !=? 2'b00; parameter wneq4 = 2'b00 !=? 2'b0x; parameter wneq5 = 2'b01 !=? 2'b0x; parameter wneq6 = 2'b0z !=? 2'b0x; parameter wneq7 = 2'b0x !=? 2'b0x; parameter wneq8 = 2'b00 !=? 2'b0z; parameter wneq9 = 2'b01 !=? 2'b0z; parameter wneqa = 2'b0z !=? 2'b0z; parameter wneqb = 2'b0x !=? 2'b0z; parameter wneqc = 2'bx0 !=? 2'b00; parameter wneqd = 2'bx1 !=? 2'b00; parameter wneqe = 2'b1x !=? 2'b00; parameter wneqf = 3'b100 !=? 2'b00; reg pass; initial begin pass = 1'b1; if (weq1 !== 1'b1) begin $display("Failed: parameter 2'b01 ==? 2'b01 returned 1'b%b not 1'b1", weq1); pass = 1'b0; end if (weq2 !== 1'b0) begin $display("Failed: parameter 2'b01 ==? 2'b00 returned 1'b%b not 1'b0", weq2); pass = 1'b0; end if (weq3 !== 1'bx) begin $display("Failed: parameter 2'b0x ==? 2'b00 returned 1'b%b not 1'bx", weq3); pass = 1'b0; end if (weq4 !== 1'b1) begin $display("Failed: parameter 2'b00 ==? 2'b0x returned 1'b%b not 1'b1", weq4); pass = 1'b0; end if (weq5 !== 1'b1) begin $display("Failed: parameter 2'b01 ==? 2'b0x returned 1'b%b not 1'b1", weq5); pass = 1'b0; end if (weq6 !== 1'b1) begin $display("Failed: parameter 2'b0x ==? 2'b0x returned 1'b%b not 1'b1", weq6); pass = 1'b0; end if (weq7 !== 1'b1) begin $display("Failed: parameter 2'b0z ==? 2'b0x returned 1'b%b not 1'b1", weq7); pass = 1'b0; end if (weq8 !== 1'b1) begin $display("Failed: parameter 2'b00 ==? 2'b0z returned 1'b%b not 1'b1", weq8); pass = 1'b0; end if (weq9 !== 1'b1) begin $display("Failed: parameter 2'b01 ==? 2'b0z returned 1'b%b not 1'b1", weq9); pass = 1'b0; end if (weqa !== 1'b1) begin $display("Failed: parameter 2'b0x ==? 2'b0z returned 1'b%b not 1'b1", weqa); pass = 1'b0; end if (weqb !== 1'b1) begin $display("Failed: parameter 2'b0z ==? 2'b0z returned 1'b%b not 1'b1", weqb); pass = 1'b0; end if (weqc !== 1'bx) begin $display("Failed: parameter 2'bx0 ==? 2'b00 returned 1'b%b not 1'bx", weqc); pass = 1'b0; end if (weqd !== 1'b0) begin $display("Failed: parameter 2'bx1 ==? 2'b00 returned 1'b%b not 1'b0", weqd); pass = 1'b0; end if (weqe !== 1'b0) begin $display("Failed: parameter 2'b1x ==? 2'b00 returned 1'b%b not 1'b0", weqe); pass = 1'b0; end if (weqf !== 1'b0) begin $display("Failed: parameter 3'b100 ==? 2'b00 returned 1'b%b not 1'b0", weqf); pass = 1'b0; end if (wneq1 !== 1'b0) begin $display("Failed: parameter 2'b01 !=? 2'b01 returned 1'b%b not 1'b0", wneq1); pass = 1'b0; end if (wneq2 !== 1'b1) begin $display("Failed: parameter 2'b01 !=? 2'b00 returned 1'b%b not 1'b1", wneq2); pass = 1'b0; end if (wneq3 !== 1'bx) begin $display("Failed: parameter 2'b0x !=? 2'b00 returned 1'b%b not 1'bx", wneq3); pass = 1'b0; end if (wneq4 !== 1'b0) begin $display("Failed: parameter 2'b00 !=? 2'b0x returned 1'b%b not 1'b0", wneq4); pass = 1'b0; end if (wneq5 !== 1'b0) begin $display("Failed: parameter 2'b01 !=? 2'b0x returned 1'b%b not 1'b0", wneq5); pass = 1'b0; end if (wneq6 !== 1'b0) begin $display("Failed: parameter 2'b0x !=? 2'b0x returned 1'b%b not 1'b0", wneq6); pass = 1'b0; end if (wneq7 !== 1'b0) begin $display("Failed: parameter 2'b0z !=? 2'b0x returned 1'b%b not 1'b0", wneq7); pass = 1'b0; end if (wneq8 !== 1'b0) begin $display("Failed: parameter 2'b00 !=? 2'b0z returned 1'b%b not 1'b0", wneq8); pass = 1'b0; end if (wneq9 !== 1'b0) begin $display("Failed: parameter 2'b01 !=? 2'b0z returned 1'b%b not 1'b0", wneq9); pass = 1'b0; end if (wneqa !== 1'b0) begin $display("Failed: parameter 2'b0x !=? 2'b0z returned 1'b%b not 1'b0", wneqa); pass = 1'b0; end if (wneqb !== 1'b0) begin $display("Failed: parameter 2'b0z !=? 2'b0z returned 1'b%b not 1'b0", wneqb); pass = 1'b0; end if (wneqc !== 1'bx) begin $display("Failed: parameter 2'bx0 !=? 2'b00 returned 1'b%b not 1'bx", wneqc); pass = 1'b0; end if (wneqd !== 1'b1) begin $display("Failed: parameter 2'bx1 !=? 2'b00 returned 1'b%b not 1'b1", wneqd); pass = 1'b0; end if (wneqe !== 1'b1) begin $display("Failed: parameter 2'b1x !=? 2'b00 returned 1'b%b not 1'b1", wneqe); pass = 1'b0; end if (wneqf !== 1'b1) begin $display("Failed: parameter 3'b100 !=? 2'b00 returned 1'b%b not 1'b1", wneqf); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wild_cmp_err.v000066400000000000000000000003171435245347300214000ustar00rootroot00000000000000module top; parameter weq1 = 2'b01 ==? 0.0; parameter weq2 = 0.0 ==? 2'b01; parameter wneq1 = 2'b01 !=? 0.0; parameter wneq2 = 0.0 !=? 2'b01; initial begin $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/wild_cmp_err2.v000066400000000000000000000010351435245347300214600ustar00rootroot00000000000000module top; reg [1:0] lv, rv; real rl; reg res; string st; wire r1, r2, r3, r4, r5, r6, r7, r8; assign r1 = rl ==? rv; assign r2 = lv ==? rl; assign r3 = rl !=? rv; assign r4 = lv !=? rl; assign r1 = st ==? rv; assign r2 = lv ==? st; assign r3 = st !=? rv; assign r4 = lv !=? st; initial begin res = rl ==? rv; res = lv ==? rl; res = rl !=? rv; res = lv !=? rl; res = st ==? rv; res = lv ==? st; res = st !=? rv; res = lv !=? st; $display("FAILED"); end endmodule iverilog-12_0/ivtest/ivltests/wild_cmp_net.v000066400000000000000000000056411435245347300214030ustar00rootroot00000000000000module top; reg [1:0] lv, rv; reg pass; wire res, resb; assign res = lv ==? rv; assign resb = lv !=? rv; initial begin pass = 1'b1; lv = 2'b00; rv = 2'b00; #1; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (resb !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b00; rv = 2'b01; #1; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end if (resb !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b10; rv = 2'b00; #1; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end if (resb !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b1x; rv = 2'b00; #1; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end if (resb !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b0x; rv = 2'b00; #1; if (res !== 1'bx) begin $display("Failed: %b ==? %b returned 1'b%b not 1'bx", lv, rv, res); pass = 1'b0; end if (resb !== 1'bx) begin $display("Failed: %b !=? %b returned 1'b%b not 1'bx", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b00; rv = 2'b0x; #1; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (resb !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b01; rv = 2'b0x; #1; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (resb !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b0z; rv = 2'b0x; #1; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (resb !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, resb); pass = 1'b0; end #1; lv = 2'b0x; rv = 2'b0x; #1; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (resb !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, resb); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wild_cmp_var.v000066400000000000000000000076301435245347300214050ustar00rootroot00000000000000module top; reg [1:0] lv, rv; reg res, pass; initial begin pass = 1'b1; lv = 2'b00; rv = 2'b00; res = lv ==? rv; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b00; rv = 2'b01; res = lv ==? rv; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b10; rv = 2'b00; res = lv ==? rv; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b1x; rv = 2'b00; res = lv ==? rv; if (res !== 1'b0) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b0x; rv = 2'b00; res = lv ==? rv; if (res !== 1'bx) begin $display("Failed: %b ==? %b returned 1'b%b not 1'bx", lv, rv, res); pass = 1'b0; end lv = 2'b00; rv = 2'b0x; res = lv ==? rv; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b01; rv = 2'b0x; res = lv ==? rv; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b0z; rv = 2'b0x; res = lv ==? rv; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b0x; rv = 2'b0x; res = lv ==? rv; if (res !== 1'b1) begin $display("Failed: %b ==? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b00; rv = 2'b00; res = lv !=? rv; if (res !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b00; rv = 2'b01; res = lv !=? rv; if (res !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b10; rv = 2'b00; res = lv !=? rv; if (res !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b1x; rv = 2'b00; res = lv !=? rv; if (res !== 1'b1) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b0x; rv = 2'b00; res = lv !=? rv; if (res !== 1'bx) begin $display("Failed: %b !=? %b returned 1'b%b not 1'bx", lv, rv, res); pass = 1'b0; end lv = 2'b00; rv = 2'b0x; res = lv !=? rv; if (res !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b01; rv = 2'b0x; res = lv !=? rv; if (res !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b0z; rv = 2'b0x; res = lv !=? rv; if (res !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end lv = 2'b0x; rv = 2'b0x; res = lv !=? rv; if (res !== 1'b0) begin $display("Failed: %b !=? %b returned 1'b%b not 1'b0", lv, rv, res); pass = 1'b0; end // Check in a few other contexts. lv = 2'b01; rv = 2'b0x; res = (lv ==? rv) ? 1'b1 : 1'b0; if (res !== 1'b1) begin $display("Failed: %b ==? %b (ternary) returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end if (lv !=? rv) begin $display("Failed: %b ==? %b (if) returned 1'b%b not 1'b1", lv, rv, res); pass = 1'b0; end lv = 2'b00; while (lv ==? rv) lv += 2'b01; if (lv !== 2'b10) begin $display("Failed: %b ==? %b (while) expected lv to be 2'b10", lv, rv); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wildsense.v000066400000000000000000000030631435245347300207300ustar00rootroot00000000000000// Copyright (c) 2000 Steve Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Try the always @ * construct from Verilog 2000 LRM spec module test; // // Define a procedural assignment based mux. // reg [1:0] sel; reg [1:0] out, a,b,c,d; reg error; always @ * case (sel) 2'b00: out = a; 2'b01: out = b; 2'b10: out = c; 2'b11: out = d; endcase initial begin error = 0; #1 ; sel = 0; a = 0; #1; if(out !== 2'b00) begin $display("FAILED - Wildcard sensitivy list a != 0(1)"); error =1; end #1; a = 1; #1; if(out !== 2'b01) begin $display("FAILED - Wildcard sensitivity list a != 1 (2)"); error =1; end if(error == 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wildsense2.v000066400000000000000000000020171435245347300210100ustar00rootroot00000000000000module main; reg [2:0] ADDR; wire [1:0] data0 = 0, data1 = 1, data2 = 2, data3 = 3; reg [1:0] data; always @* case (ADDR[2:0]) 3'b000: data = data0; 3'b001: data = data1; 3'b010: data = data2; 3'b011: data = data3; default: data = 0; endcase // case(ADDR[2:0]) initial begin ADDR = 0; #1 $display("data=%b", data); if (data !== ADDR) begin $display("FAILED"); $finish; end ADDR = 1; #1 $display("data=%b", data); if (data !== ADDR) begin $display("FAILED"); $finish; end ADDR = 2; #1 $display("data=%b", data); if (data !== ADDR) begin $display("FAILED"); $finish; end ADDR = 3; #1 $display("data=%b", data); if (data !== ADDR) begin $display("FAILED"); $finish; end ADDR = 4; #1 $display("data=%b", data); if (data !== 0)begin $display("FAILED"); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/ivltests/wireadd1.v000066400000000000000000000027261435245347300204400ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous adds in assignment..dependent on always + working // // $Log: wireadd1.v,v $ // Revision 1.2 2001/05/03 05:45:37 ka6s // Lets try this again // // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 + var2; always @( var1 or var2) var3 = var1 + var2 ; initial begin error = 0; for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin #1 ; if(var3 !== var3a) error = 1; #1; end if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wireeq.v000066400000000000000000000027751435245347300202400ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous <= in assignment. // module main; reg globvar; reg [3:0] var1; reg error; wire var2 = (var1 == 4'h02); initial begin error = 0; var1 = 4'h0 ; #1 ; if(var2 != 1'b0) begin $display("FAILED continuous <= logical op (1)"); error = 1; end #1 ; var1 = 4'h2; #1 ; if(var2 != 1'b1) begin $display("FAILED continuos <= logical op (2)"); error = 1; end #1 ; var1 = 4'h4; #1 ; if(var2 != 1'b0) begin $display("FAILED continuos <= logical op (3)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wirege.v000066400000000000000000000030001435245347300202040ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous <= in assignment. // module main; reg globvar; reg [3:0] var1; reg error; wire var2 = (4'h02 >= var1); initial begin error = 0; var1 = 4'h0 ; #1 ; if(var2 !== 1'b1) begin $display("FAILED continuous >= logical op (1)"); error = 1; end #1 ; var1 = 4'h2; #1 ; if(var2 !== 1'b1) begin $display("FAILED continuos <= logical op (2)"); error = 1; end #1 ; var1 = 4'h4; #1 ; if(var2 !== 1'b0) begin $display("FAILED continuos <= logical op (3)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wireland.v000066400000000000000000000026001435245347300205340ustar00rootroot00000000000000/* * Copyright (c) 2000 Peter monta (pmonta@pacbell.net) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // Reworked slightly to be self checking. module main; wire y; reg a,b; reg error; assign y = a && (b ? 0 : 1); initial begin error = 0; #1 ; // get passed the time 0 race problems ;-) b = 1; a = 1; #1 ; if(y !== 0) begin $display("FAILED"); error = 1; end #1 ; b = 0; #1 ; if(y !== 1) begin $display("FAILED"); error = 1; end if(error === 0) $display("PASSED"); end endmodule iverilog-12_0/ivtest/ivltests/wirele.v000066400000000000000000000030001435245347300202110ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous <= in assignment. // module main; reg globvar; reg [3:0] var1; reg error; wire var2 = (var1 <= 4'h02); initial begin error = 0; var1 = 4'h0 ; #1 ; if(var2 !== 1'b1) begin $display("FAILED continuous <= logical op (1)"); error = 1; end #1 ; var1 = 4'h2; #1 ; if(var2 !== 1'b1) begin $display("FAILED continuos <= logical op (2)"); error = 1; end #1 ; var1 = 4'h4; #1 ; if(var2 !== 1'b0) begin $display("FAILED continuos <= logical op (3)"); error = 1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wiremod1.v000066400000000000000000000027441435245347300204670ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous % in assignment..dependent on always % working // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 % var2; always @( var1 or var2) var3 = var1 % var2 ; initial begin for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin error = 0; #1 ; if(var3 != var3a) begin $display("FAILED continuous 1=%h,2=%h,3=%h,3a=%h", var1,var2,var3,var3a); error = 1; end #1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wiresl.v000066400000000000000000000027351435245347300202450ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous << in assignment..dependent on always << working // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 << var2; always @( var1 or var2) var3 = var1 << var2 ; initial begin error = 0; for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin #1 ; if(var3 != var3a) begin $display("FAILED continous << 1=%h,2=%h,3=%h,3a=%h", var1,var2,var3,var3a); error = 1; end #1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wiresl2.v000066400000000000000000000017031435245347300203210ustar00rootroot00000000000000`begin_keywords "1364-2005" /* * This test is from PR#193 */ /* test:tshl Compilation fails with vvp from icarus verilog-20010616 snapshot $ iverilog -t vvp tshl.v ivl: eval_expr.c:418: draw_binary_expr_ls: Assertion `0' failed. In vvm, runtime has trouble with $display $ iverilog tshl.v $ ./a.out out=01 (looks like the correct output "out=01" followed by some random memory garbage.) */ module tshl; reg [2:0] bit; wire [7:0] shbit; integer i; shl shl_0(shbit, bit); initial begin for(i = 0; i < 8; i = i + 1) begin bit <= i[2:0]; #1 $display("out=%h", shbit); end // for (i = 0; i < 8; i = i + 1) $finish(0); end // initial begin endmodule module shl(out, bit); output [7:0] out; input [2:0] bit; reg [7:0] out_reg; always @(bit) begin out_reg <= 8'h01 << bit; end // always @ (bit) assign out = out_reg; endmodule // shl `end_keywords iverilog-12_0/ivtest/ivltests/wiresr.v000066400000000000000000000027361435245347300202540ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous >> in assignment..dependent on always >> working // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 >> var2; always @( var1 or var2) var3 = var1 >> var2 ; initial begin error =0; for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin #1 ; if(var3 != var3a) begin $display("FAILED continuous >> 1=%h,2=%h,3=%h,3a=%h", var1,var2,var3,var3a); error = 1; end #1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wiresub1.v000066400000000000000000000026361435245347300205010ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous sub in assignment..dependent on always - working // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 - var2; always @( var1 or var2) var3 = var1 - var2 ; initial begin error = 0; for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin #1 ; if(var3 !== var3a) begin #1 ; error = 1; end #1; end if(error == 0) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/ivltests/wirexor1.v000066400000000000000000000027361435245347300205210ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW - Validate continuous xor in assignment..dependent on always ^ working // module main; reg globvar; reg [3:0] var1,var2,var3; wire [3:0] var3a; reg error; assign var3a = var1 ^ var2; always @( var1 or var2) var3 = var1 ^ var2 ; initial begin error = 0; for ( var1 = 4'b0; var1 != 4'hf; var1 = var1 + 1) for ( var2 = 4'b0; var2 != 4'hf; var2 = var2 + 1) begin #1 ; if(var3 != var3a) begin $display("FAILED continuous xor 1=%h,2=%h,3=%h,3a=%h", var1,var2,var3,var3a); error = 1; end #1; end if(error == 0) $display("PASSED"); end endmodule // main iverilog-12_0/ivtest/ivltests/work14.vhd000066400000000000000000000010551435245347300203750ustar00rootroot00000000000000 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.work14_pkg.all; entity work14_comp is generic ( max_out_val : natural := 3; sample_parm : string := "test"); port ( clk_i : in std_logic; val : out std_logic_vector(f_log2_size(max_out_val)-1 downto 0)); end work14_comp; architecture rtl of work14_comp is begin -- rtl foo : process(clk_i) begin if rising_edge(clk_i) then val <= std_logic_vector(to_unsigned(max_out_val, val'length)); end if; end process; end rtl; iverilog-12_0/ivtest/ivltests/work14_pkg.vhd000066400000000000000000000012331435245347300212340ustar00rootroot00000000000000 library ieee; use ieee.std_logic_1164.all; package work14_pkg is function f_log2_size ( A : natural) return natural; component work14_comp generic ( max_out_val : natural; sample_parm : string); port ( clk_i : in std_logic; val : out std_logic_vector(f_log2_size(max_out_val)-1 downto 0)); end component; end work14_pkg; package body work14_pkg is function f_log2_size (A : natural) return natural is begin for I in 1 to 64 loop -- Works for up to 64 bits if (2**I >= A) then return(I); end if; end loop; return(63); end function f_log2_size; end work14_pkg; iverilog-12_0/ivtest/ivltests/work7.cfg000066400000000000000000000001541435245347300202740ustar00rootroot00000000000000ivltests/work7/work7-pkg.vhd ivltests/work7/timebase.vhd ivltests/work7/bigcount.vhd ivltests/work7/fdc.vhd iverilog-12_0/ivtest/ivltests/work7.v000066400000000000000000000010131435245347300177750ustar00rootroot00000000000000module test; reg clk, reset; wire [24:0] count; initial begin clk = 1'b0; forever #25 clk = ~clk; end initial begin reset = 1'b0; @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end initial begin #200000; #500; if (count != 2000) begin $display ("Counting FAILED"); $finish; end else begin $display ("PASSED"); #20; $finish; end end bigcount duv (.clk(clk), .reset(reset), .count(count) ); endmodule iverilog-12_0/ivtest/ivltests/work7/000077500000000000000000000000001435245347300176135ustar00rootroot00000000000000iverilog-12_0/ivtest/ivltests/work7/bigcount.vhd000066400000000000000000000011571435245347300221340ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; use work.work7.all; entity bigcount is port (clk, reset: in std_logic; count: out std_logic_vector (24 downto 0) ); end entity bigcount; architecture bigcount_rtl of bigcount is signal d, t, q, myreset: std_logic; begin d <= t xor q; myreset <= reset or t; f1: fdc port map (clk => clk, reset => reset, d => d, q => q); tb: timebase port map (CLOCK => clk, RESET => myreset, ENABLE => '1', TICK => t, COUNT_VALUE => open ); counting: timebase port map (CLOCK => clk, RESET => reset, ENABLE => q, TICK => open, COUNT_VALUE => count ); end bigcount_rtl; iverilog-12_0/ivtest/ivltests/work7/fdc.vhd000066400000000000000000000006601435245347300210540ustar00rootroot00000000000000-- a D-type flip-flop with synchronous reset library ieee; use ieee.std_logic_1164.all; entity fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic ); end fdc; architecture fdc_rtl of fdc is begin i_finish: process (clk) begin if (clk'event and clk = '1') then if (reset = '1') then q <= '0'; else q <= d; end if; end if; end process; end fdc_rtl; iverilog-12_0/ivtest/ivltests/work7/timebase.vhd000066400000000000000000000025611435245347300221130ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- The operation is: -- 1) An internal counter (of 25 bits) is initilaised to zero after a reset is received. -- 2) An enable allows an internal running counter to count clock pulses -- 3) A tick signal output is generated when a count of 20000000 pulses has been accumulated entity TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end TimeBase; architecture TimeBase_rtl of TimeBase is constant DIVIDER_VALUE : std_logic_vector := x"7cf"; -- 20000000 count value, 1 second signal RunningCounter : std_logic_vector(24 downto 0); -- this is the 25 bit free running counter to allow a big count begin RunningCounterProcess : process (CLOCK) begin if ( CLOCK'event and CLOCK = '1') then if (RESET = '1') then RunningCounter <= '0' & x"000000"; elsif ( ENABLE = '1') then RunningCounter <= RunningCounter + 1; end if; else RunningCounter <= RunningCounter; end if; end process; TICK <= '1' when (RunningCounter = DIVIDER_VALUE) else '0'; COUNT_VALUE <= RunningCounter; end TimeBase_rtl; iverilog-12_0/ivtest/ivltests/work7/work7-pkg.vhd000066400000000000000000000011031435245347300221410ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; package work7 is -- D-type flip flop component fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic); end component; component TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end component; end package work7; iverilog-12_0/ivtest/ivltests/work7b.cfg000066400000000000000000000001601435245347300204330ustar00rootroot00000000000000+vhdl-libdir+ivltests/work7b ivltests/work7b/timebase.vhd ivltests/work7b/bigcount.vhd ivltests/work7b/fdc.vhd iverilog-12_0/ivtest/ivltests/work7b.v000066400000000000000000000010131435245347300201370ustar00rootroot00000000000000module test; reg clk, reset; wire [24:0] count; initial begin clk = 1'b0; forever #25 clk = ~clk; end initial begin reset = 1'b0; @(negedge clk); reset = 1'b1; repeat(6) @(negedge clk); reset = 1'b0; end initial begin #200000; #500; if (count != 2000) begin $display ("Counting FAILED"); $finish; end else begin $display ("PASSED"); #20; $finish; end end bigcount duv (.clk(clk), .reset(reset), .count(count) ); endmodule iverilog-12_0/ivtest/ivltests/work7b/000077500000000000000000000000001435245347300177555ustar00rootroot00000000000000iverilog-12_0/ivtest/ivltests/work7b/bigcount.vhd000066400000000000000000000012011435245347300222640ustar00rootroot00000000000000library ieee; library uselib; use ieee.std_logic_1164.all; use uselib.work7.all; entity bigcount is port (clk, reset: in std_logic; count: out std_logic_vector (24 downto 0) ); end entity bigcount; architecture bigcount_rtl of bigcount is signal d, t, q, myreset: std_logic; begin d <= t xor q; myreset <= reset or t; f1: fdc port map (clk => clk, reset => reset, d => d, q => q); tb: timebase port map (CLOCK => clk, RESET => myreset, ENABLE => '1', TICK => t, COUNT_VALUE => open ); counting: timebase port map (CLOCK => clk, RESET => reset, ENABLE => q, TICK => open, COUNT_VALUE => count ); end bigcount_rtl; iverilog-12_0/ivtest/ivltests/work7b/fdc.vhd000066400000000000000000000006601435245347300212160ustar00rootroot00000000000000-- a D-type flip-flop with synchronous reset library ieee; use ieee.std_logic_1164.all; entity fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic ); end fdc; architecture fdc_rtl of fdc is begin i_finish: process (clk) begin if (clk'event and clk = '1') then if (reset = '1') then q <= '0'; else q <= d; end if; end if; end process; end fdc_rtl; iverilog-12_0/ivtest/ivltests/work7b/timebase.vhd000066400000000000000000000025611435245347300222550ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- The operation is: -- 1) An internal counter (of 25 bits) is initilaised to zero after a reset is received. -- 2) An enable allows an internal running counter to count clock pulses -- 3) A tick signal output is generated when a count of 20000000 pulses has been accumulated entity TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end TimeBase; architecture TimeBase_rtl of TimeBase is constant DIVIDER_VALUE : std_logic_vector := x"7cf"; -- 20000000 count value, 1 second signal RunningCounter : std_logic_vector(24 downto 0); -- this is the 25 bit free running counter to allow a big count begin RunningCounterProcess : process (CLOCK) begin if ( CLOCK'event and CLOCK = '1') then if (RESET = '1') then RunningCounter <= '0' & x"000000"; elsif ( ENABLE = '1') then RunningCounter <= RunningCounter + 1; end if; else RunningCounter <= RunningCounter; end if; end process; TICK <= '1' when (RunningCounter = DIVIDER_VALUE) else '0'; COUNT_VALUE <= RunningCounter; end TimeBase_rtl; iverilog-12_0/ivtest/ivltests/work7b/uselib/000077500000000000000000000000001435245347300212405ustar00rootroot00000000000000iverilog-12_0/ivtest/ivltests/work7b/uselib/work7.pkg000066400000000000000000000011031435245347300230070ustar00rootroot00000000000000library ieee; use ieee.std_logic_1164.all; package work7 is -- D-type flip flop component fdc is port (clk: in std_logic; reset: in std_logic; d: in std_logic; q: out std_logic); end component; component TimeBase is port( CLOCK : in std_logic; -- input clock of 20MHz TICK : out std_logic; -- out 1 sec timebase signal RESET : in std_logic; -- master reset signal (active high) ENABLE : in std_logic; COUNT_VALUE: out std_logic_vector (24 downto 0) ); end component; end package work7; iverilog-12_0/ivtest/ivltests/wreal.v000066400000000000000000000021711435245347300200440ustar00rootroot00000000000000module top; reg pass; real in; wreal out1, out2, outa; wreal ca1 = 2.25; wreal ca2; assign ca2 = 4.5; sub1 dut1(out1, in); sub2 dut2(out2, in); suba duta(outa, in); initial begin pass = 1'b1; in = 1.0; #1; if (out1 != 1.0) begin $display("FAILED: expected out1 to be 1.0, got %f", out1); pass = 1'b0; end if (out2 != 1.0) begin $display("FAILED: expected out2 to be 1.0, got %f", out2); pass = 1'b0; end if (outa != 1.0) begin $display("FAILED: expected outa to be 1.0, got %f", outa); pass = 1'b0; end if (ca1 != 2.25) begin $display("FAILED: expected ca1 to be 2.25, got %f", ca1); pass = 1'b0; end if (ca2 != 4.5) begin $display("FAILED: expected ca1 to be 4.5, got %f", ca2); pass = 1'b0; end if (pass) $display("PASSED"); end endmodule module sub1(out, in); output out; input in; wreal out, in; assign out = in; endmodule module sub2(out, in); output wreal out; input wreal in; assign out = in; endmodule module suba(output wreal out, input wreal in); assign out = in; endmodule iverilog-12_0/ivtest/ivltests/writemem-error.v000066400000000000000000000167301435245347300217200ustar00rootroot00000000000000module top; reg [20*8-1:0] str; real rval; reg [7:0] array [0:7]; reg [7:0] array2 [8:15]; reg [7:0] check [0:7]; integer idx, istr; initial begin for (idx = 0; idx < 8; idx = idx + 1) array[idx] = idx + 1; for (idx = 8; idx < 16; idx = idx + 1) array2[idx] = 0; // An invalid string. $writememb(str, array); $writememb(istr, array); // Check a valid string. str = "work/writemem.txt"; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb(str, array); $readmemb(str, check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 1, expected %0d, got %0d", idx, idx+1, check[idx]); end end // Check a string with a non-printing character. str[7:0] = 'd2; $writememb(str, array); // This should write, but will print a warning about the real. rval = 0.0; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", array, rval); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 2, expected %0d, got %0d", idx, idx+1, check[idx]); end end // This should write, but will print a warning about the real. rval = 7.0; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", array, 0, rval); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 3, expected %0d, got %0d", idx, idx+1, check[idx]); end end // These should not write the array. for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", check, -1, 7); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 4, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", array2, 7, 15); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 5, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", check, 0, 8); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 6, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", array2, 8, 16); $readmemb("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 7, expected %0d, got %0d", idx, idx+1, check[idx]); end end // Check that we can write part of an array. for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememb("work/writemem.txt", array, 0, 6); $readmemb("work/writemem.txt", check, 0, 6); for (idx = 0; idx < 7; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememb 8, expected %0d, got %0d", idx, idx+1, check[idx]); end end if (check[7] !== 0) begin $display("Failed: for index 7 of writememb 8, expected 0, got %0d", check[7]); end // An invalid string. str = 'bx; $writememh(str, array); $writememh(istr, array); // Check a valid string. str = "work/writemem.txt"; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh(str, array); $readmemh(str, check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 1, expected %0d, got %0d", idx, idx+1, check[idx]); end end // Check a string with a non-printing character. str[7:0] = 'd2; $writememh(str, array); // This should write, but will print a warning about the real. rval = 0.0; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", array, rval); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 2, expected %0d, got %0d", idx, idx+1, check[idx]); end end // This should write, but will print a warning about the real. rval = 7.0; for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", array, 0, rval); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 3, expected %0d, got %0d", idx, idx+1, check[idx]); end end // These should not write the array. for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", check, -1, 7); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 4, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", array2, 7, 15); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 5, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", check, 0, 8); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 6, expected %0d, got %0d", idx, idx+1, check[idx]); end end for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", array2, 8, 16); $readmemh("work/writemem.txt", check); for (idx = 0; idx < 8; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 7, expected %0d, got %0d", idx, idx+1, check[idx]); end end // Check that we can write part of an array. for (idx = 0; idx < 8; idx = idx + 1) check[idx] = 0; $writememh("work/writemem.txt", array, 0, 6); $readmemh("work/writemem.txt", check, 0, 6); for (idx = 0; idx < 7; idx = idx + 1) begin if (check[idx] !== idx + 1) begin $display("Failed: for index %0d of writememh 8, expected %0d, got %0d", idx, idx+1, check[idx]); end end if (check[7] !== 0) begin $display("Failed: for index 7 of writememh 8, expected 0, got %0d", check[7]); end end endmodule iverilog-12_0/ivtest/ivltests/writemem-invalid.v000066400000000000000000000010711435245347300222050ustar00rootroot00000000000000module top; reg [7:0] array [7:0]; initial begin $writememb(); $writememb(top); $writememb("writemem.txt"); $writememb("writemem.txt", top); $writememb("writemem.txt", array, top); $writememb("writemem.txt", array, 0, top); $writememb("writemem.txt", array, 0, 7, top); $writememh(); $writememh(top); $writememh("writemem.txt"); $writememh("writemem.txt", top); $writememh("writemem.txt", array, top); $writememh("writemem.txt", array, 0, top); $writememh("writemem.txt", array, 0, 7, top); end endmodule iverilog-12_0/ivtest/ivltests/writememb1.v000066400000000000000000000035441435245347300210130ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin for(count = 0; count <= 7; count = count + 1) begin array[count] = 1 << count; end array[2] = 8'bx0z0x0z0; $writememb("work/writememb1.dat", array, 6, 1); for(count = 0; count <= 7; count = count + 1) begin array[count] = 'bx; end error = 0; $readmemb("work/writememb1.dat", array); for(count = 0; count <= 3; count = count + 1) begin if(array[count] !== (1<<(6-count))) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count], 1 << count); end end if (array[4] != 8'bx0z0x0z0) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[4], 8'bx0z0x0z0); end if (array[5] != 8'b00000010) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[5], 1 << 5); end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/writememb2.v000066400000000000000000000030331435245347300210050ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // // module main (); reg [7:0] array [7:0]; reg error ; reg [3:0] count; initial begin for(count = 0; count <= 7; count = count + 1) begin array[count] = 1 << count; end $writememb("work/writememb2.dat", array, 6, 1); for(count = 0; count <= 7; count = count + 1) begin array[count] = 'bx; end error = 0; $readmemb("work/writememb2.dat", array); for(count = 0; count <= 5; count = count + 1) begin if(array[count] !== (1<<(6-count))) begin error = 1; $display("FAILED - array[count] == %h, s/b %h", array[count], 1 << count); end end if(error == 0) $display("PASSED\n"); $finish ; end endmodule iverilog-12_0/ivtest/ivltests/writememh1.v000066400000000000000000000031221435245347300210110ustar00rootroot00000000000000// // Copyright (c) 1999 Steven Wilson (stevew@home.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // // SDW: Initial readmemh function - length of data = array size. // // module main (); reg [7:0] array [0:7]; reg error ; reg [3:0] count; initial begin for(count = 0; count <= 7; count = count + 1) begin array[count] = 1 << count; end $writememh("work/writememh1.dat", array); for(count = 0; count <= 7; count = count + 1) begin array[count] = 'bx; end error = 0; $readmemh("work/writememh1.dat", array); for(count = 0; count <= 7; count = count + 1) begin if(array[count] !== (1<& syntax?) Fixed always3.1.9A.v, Fixed always3.1.9B.v. Added tests always3.1.9C,D.v Fixed wiremod1.v, syntax error in ptest006-008 in $display. Howcome IVL likes these? Removed sdw_template.v. Added "PASSED" printout to z1,z2. This should make them compatible with XL. Fixed assign3.2D.v syntax error, moved syntax error into assign3.2E.v to test for it! Fixed contrib8.4.v so that it prints PASSED. 12/11/99 Added contrib directory and fifo.v in same donated by Tom Coonan. He's GPL this and other work for inclusion within the test suite! THANKS TOM!!!!! Note that two tests always3.1.11B and udp_bufg are commented out because they hang the testsuite currently. 12/1/99 Added qmark6.v contributed by Dan Nelsen. Muxtest.v validates X on sel, when inputs are both 1 or 0. 11/12/99 Added several ga_* tests that use a primitive gate vector. The ga_nand.v test of this sequence fails. Went thru the ptestxxx.v series and replaced all != or == constructs with !==/===. 11/8/99 Fixed stuff added on 11/6 - it now says PASSED! Added wirele.v, wirege.v, wireeq.v tests. These with the CVS 11/7/99 cut that I used to test. 11/6/99 Added tests wireadd1.v wiremod1.v wiresl.v wiresr.v wiresub1.v wirexor1.v Several of the tests in regress.list had the .v extension so they weren't running correctly. That's fixed. 10/14/99 This is mainly a debug release. See below. lh_varindx added (tests left hand variable index of a vector.) Rewrote always3.1.6A-C COMPLETELY. Changed time1.v to use always block and #5 d = a; Added time3.v that looks at same structure for non-blocking (#5 d <= a). Added an always3.1.6D.v ( a case test from Steve Williams.) There was a race condition in the always3.1.6A-C that was due in part to the nature of always case (x) ...default #1; whoops! Removed qmark2.v - it became redundant(besides it was broken sematically) 10/5/99 Changed location of #0 to first item in the initial block for always3.1.6A-C.v This also counts as a test for proper operation of the semantics for #0 which is used to defeat what would otherwise be a race condition. Researched the operation of #0 in Moorby 4th edition. This seems to be kosher (though not GOOD programming practice.) Added several contributed tests by many folks. Note that the regression_report.txt is the results of running with the 9/28 IVL release. 9/27/99 Added a #0 to take care of a race in always3.1.6A-C. Added the ability to put an optional main module name as a 4th arguement within the regress.list line. 9/20/99 This release collects the tests together along with a regression script(sregress.pl) which is a modified version of a script contributed by Guy Hutchison. (Thanks Guy!!!) To run the testsuite - ensure that you have the appropriate IVL environment variables set - the script doesn't check for THAT yet - maybe next time;-) You need the appropriate stuff in your search path for IVL and set VPI_MODULE_PATH and LD_LIBRARY_PATH as necessary. See the IVL docs for info. Now - simply move into the testsuite directory and type: ./sregress.pl This will run the regression script, and create a series of log files in the log directory. The test runs are summarized in regression_report.txt. The tests run are obtained from regress.list. 9/9/99 Completed thru 3.14F(tasks). So Added from Section 3.11-3.14. Updated ivl_test.html file. Also have included some of the "contributed" tests. Haven't worked them all into the test document yet. 9/6/99 Completed all of the always block tests. Added tests for sections 3.2-3.10. Reworked the 3.1.5 tests that had bugs. Updated the ivl_tests.html file to reflect work to date. Note that runsh doesn't use the "verilog" script yet. 8/18/99 New tests added 3.1.5C - 3.1.7B 8/12/99 Initial release to Steve Williams. iverilog-12_0/ivtest/obsolete/elist000066400000000000000000000052171435245347300175510ustar00rootroot00000000000000# $Log: elist,v $ # Revision 1.19 2004/01/21 04:52:30 stevewilliams # Add pr904 # # Revision 1.18 2002/11/21 21:16:51 stevewilliams # Add array5 as an error test. # # Revision 1.17 2002/11/13 03:26:33 stevewilliams # Add tests pr564, pr581 and pr585. # # Revision 1.16 2002/11/02 01:11:16 stevewilliams # Add pr567 to elist # # Revision 1.15 2002/11/02 01:02:32 stevewilliams # memory names in messages no longer have scope. # # Revision 1.14 2002/04/22 00:50:54 stevewilliams # Add the implicit1 test to the elist. # # Revision 1.13 2002/04/13 02:39:57 stevewilliams # Add the memidx2 test of mem index errors. # # Revision 1.12 2002/04/12 02:56:57 stevewilliams # Fix typos in elist file. # # Revision 1.11 2002/04/12 02:51:52 stevewilliams # Add range3 to error test. # # Revision 1.10 2002/01/23 05:57:41 stevewilliams # Fix scope2.v implicit wire error. # # Revision 1.9 2001/05/25 02:17:54 stevewilliams # add port-test3 test. # # Revision 1.8 2001/02/13 03:35:31 stevewilliams # Add cond_wide test (PR#143) # # Revision 1.7 2001/02/09 03:01:20 stevewilliams # Add test for PR#133. # # Revision 1.6 2000/12/07 02:24:54 stevewilliams # Get add32 error message right. # # Revision 1.5 2000/12/07 01:41:13 ka6s # Add the $log feature to the comments here to allow automatic update logging. # # readmemh5 ivltests main ./ivltests/readmemh5.v:35: error: part select of a memory: array function3.11E ivltests test ./ivltests/function3.11E.v:30: parse error add32 contrib main ./contrib/add32.v:14: error: sum is not a reg in this context. range1 ivltests main ./ivltests/range1.v:44: error: bit/part select thing[9:9] is out of range. range2 ivltests bug ./ivltests/range2.v:9: error: bit/part select [3:2] out of range for din range3 ivltests simple ./ivltests/range3.v:26: error: Signal ``b'' declared both as a vector and a scalar. port-test3 ivltests BENCH ./ivltests/port-test3.v:16: error: data in module CPU declared as inout and as a reg type. scope2b ivltests main ./ivltests/scope2b.v:30: error: Net q is not defined in this context. memidx2 ivltests main ./ivltests/memidx2.v:14: error: memory mem needs an index in this context. implicit1 ivltests Counter56 ./ivltests/implicit1.v:25: error: Counter56.CounterReset not defined in this scope. pr567 ivltests test ./ivltests/pr567.v:3: error: Assign to memory "blah" requires a word select index. pr581 ivltests main ./ivltests/pr581.v:14: error: memories (data) cannot be l-values in continuous assignments. array5 ivltests test ./ivltests/array5.v:14: error: Part select expressions must be constant. pr904 ivltests err ./ivltests/pr904.v:26: error: Missing expression 3 of concatenation list. iverilog-12_0/ivtest/obsolete/eregress.pl000066400000000000000000000142041435245347300206560ustar00rootroot00000000000000#!/usr/bin/env perl -s # # Copyright (c) 1999 Guy Hutchison (stevew@home.com) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA $total_count = 0; $num_opts = $#ARGV ; if($num_opts ne -1) { # Got here cuz there is a command line option $regress_fn = $ARGV[0]; if(!( -e "$regress_fn")) { print("Error - Command line option file $num_opts doesn't exist.\n"); exit(1); } } else { $regress_fn = "./elist"; } $logdir = "errlog"; $bindir = "bin"; # not currently used $report_fn = "./err_regress.txt"; $comp_name = "IVL" ; # Change the name of the compiler in use here. # this may change to a command line option after # I get things debugged! # Debug variables $dbg1 = 0; $dbg2 = 0; # Main script print ("Reading/parsing test list\n"); &read_regression_list; &execute_regression; print ("Checking logfiles\n"); &check_results; print("Testing $testname ********"); # # parses the regression list file # # First line # splits the data into a list of names (@testlist), and a # number of hashes, indexed by name of test. Hashes are # (from left-to-right in regression file): # # %testtype type of test. compile = compile only # normal = compile & run, expect standard # PASSED/FAILED message at EOT. # %testpath path to test, from root of test directory. No # trailing slash on test path. # # %testmod = main module declaration (optional) # # Second line # # The error you expect to find. sub read_regression_list { open (REGRESS_LIST, "<$regress_fn"); local ($found, $testname); while () { # read first line chop; if (!/^#/) { # strip out any comments later in the file s/#.*//g; @found = split; $compare_line = ; # Read 2nd line chop($compare_line); # Now spread things out a bit $testname = $found[0]; $testpath{$testname} = $found[1]; $testmod{$testname} = $found[2]; $compare{$testname} = $compare_line; push (@testlist, $testname); if($dbg1 == 1) { print $testname,"-",$testpath{$testname},"-", $testmod{$testname},"=",$compare{$testname},"\n"; } } } close (REGRESS_LIST); } # # execute_regression sequentially compiles and executes each test in # the regression. Regression is done as a two-pass run (execute, check # results) so that at some point the execution part can be parallelized. # sub execute_regression { local ($testname, $rv); local ($bpath, $lpath, $vpath); foreach $testname (@testlist) { # # First lets clean up the "last" test run. # if(-e "core") { system("rm -f core"); } if(-e "simv") { system("rm -f simv"); } if(-e "simv.exe") { system("rm -f simv.exe"); # And we support DOS too!! } # # This is REALLY only an IVL switch... # # vermod is used to declare the "main module" # $vermod = "-s ".$testmod{$testname} ; $vername = "iverilog "; $verout = "-o simv"; $redir = "&>"; print "Test $testname:"; if ($testpath{$testname} eq "") { $vpath = "./$testname.v"; } else { $vpath = "./$testpath{$testname}/$testname.v"; } $lpath = "./$logdir/$testname.log"; system("rm -rf $lpath"); system("rm -rf *.out"); # # if we have a logfile - remove it first # if(-e "$lpath") { system("rm $lpath"); } # # Now build the command up # $cmd = "$vername $versw $verout $vermod $vpath $redir $lpath "; print "$cmd\n"; system("$cmd"); # and execute it. } } sub check_results { local ($testname, $rv); local ($bpath, $lpath, $vpath); local ($pass_count, $fail_count, $crash_count); local ($result); $pass_count = 0; $no_sorry = 0; $no_parse_err =0; $no_run = 0; $crash_count = 0; $comperr_cnt = 0; $comp_err = 0; open (REPORT, ">$report_fn"); print REPORT "Test Results:\n"; $num_tests = 0; foreach $testname (@testlist) { $lpath = "$logdir/$testname.log"; $num_tests++; # count tests # Read in the logfile into infile. open(FILE_D,$lpath); @infile = ; close(FILE_D); $num_lines = $#infile ; for($indx=0; $indx <= $num_lines; $indx++) { chop($infile[$indx]); } if($dbg1 == 1) { print "Number lines = ",$num_lines,"\n"; } #Now scan the log file for the error $error_found = 0; for($indx=0; $indx <= $num_lines; $indx++) { if($dbg2 == 1) { print "Comparing:\n"; print "read:",$infile[$indx],"\n"; print "cmpr:",$compare{$testname},"\n"; } if($infile[$indx] eq $compare{$testname}) { $error_found = 1; } } if($error_found == 1) { $pass_count++ ; print REPORT "$testname\t\tPASSED\n"; print "$testname\t\tPASSED\n"; } else { print REPORT "$testname\t\tFAILED\n"; print "$testname\t\tFAILED\n"; } } $total = $pass_count + $no_compile + $no_run + $crash_count; print REPORT "Tests passed: $pass_count of $num_tests total\n"; print "Tests passed: $pass_count of $num_tests total\n"; close (REPORT); } iverilog-12_0/ivtest/obsolete/sregress.pl000066400000000000000000000377771435245347300207200ustar00rootroot00000000000000#!/usr/bin/env perl -s ##!/utilities/perl/bin/perl -s # # Copyright (c) 1999 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # 9/17/99 - SDW - Modified to handle multiple compilers. This is needed # to allow verification of the sweet in other environments. # Right now it works with Verilog-XL. Need to debug w/ ivl # # Modified the check_results analysis to handle different # compilers. Works with Veriog-XL. Need to debug w/ ivl # # 9/23/99 - SDW - Added command line option to change the source of the # regress.list - If a command line option is present, then # it is used as the name of a file for the regress.list. # # 9/27/99 - SDW - Added optional "main module" arguement to the regress.list # format. # # 10/5/99 - SDW - Added a "CN" Switch for IVL to pass -t null to the # compiler. Per Steve Williams' request. # # 12/27/99- SDW - added $redir to cmd generation and validated against # XL again. Using &> it was going into backround on solaris. # Changed $redir to -l which is the switch for XL to gen a # log file. This got me a serial run. # # 12/31/99 - SDW - Last change of the century! Steve Williams asked for # qualifying Compiler errors. So far I'm now counting # sorry messages and "parse error" messages. Steve will # perhaps be suprised that there are other types appearing # like "failed to elaborate.." Anyway - seems to work. # # 01/01/00 - SDW - Added a grep for "Unable" which should pick up the # elaboration errors. # # 03/13/00 - SDW - Fixed REPORT print error for Compiler Error Count # # 05/08/00 - SDW - Added gold=filename as 4th option instead of # module name (some time I'll have to make it 4th or # 5th to handle place where we need module names too!) # Also rm'd any pre-existing log files # 06/11/00 - SDW - Added CRASH detection for CE class tests # # 10/04/00 - SDW - Added suggested change from Steve Williams # to remove simv.exe for the software to run # on windows. # Global setup and paths $total_count = 0; $num_opts = $#ARGV ; if($num_opts ne -1) { # Got here cuz there is a command line option $regress_fn = $ARGV[0]; if(!( -e "$regress_fn")) { print("Error - Command line option file $num_opts doesn't exist.\n"); exit(1); } } else { $regress_fn = "./regress.list"; } $logdir = "log"; $bindir = "bin"; # not currently used $report_fn = "./regression_report.txt"; $comp_name = "IVL" ; # Change the name of the compiler in use here. # this may change to a command line option after # I get things debugged! if($comp_name eq "XL") { $vername = "vlogcmd"; # XL's command name $versw = ""; # switches $verout = ""; $redir = " -l "; } else { $vername = "iverilog"; # IVL's shell $versw = ""; # switches $verout = "-o simv"; # output (for IVL ) $redir = "&>"; # $redir = "2>&1 > "; } # Main script print ("Reading/parsing test list\n"); &read_regression_list; &execute_regression; print ("Checking logfiles\n"); &check_results; print("Testing $testname ********"); # # parses the regression list file # # splits the data into a list of names (@testlist), and a # number of hashes, indexed by name of test. Hashes are # (from left-to-right in regression file): # # %testtype type of test. compile = compile only # normal = compile & run, expect standard # PASSED/FAILED message at EOT. # %testpath path to test, from root of test directory. No # trailing slash on test path. # # %testmod = main module declaration (optional) sub read_regression_list { open (REGRESS_LIST, "<$regress_fn"); local ($found, $testname); while () { chop; if (!/^#/) { # strip out any comments later in the file s/#.*//g; $found = split; if ($found > 2) { $total_count++; $testname = $_[0]; $testtype{$testname} = $_[1]; $testpath{$testname} = $_[2]; if($#_ eq 3) { # Check for 4 fields if(!($_ =~ /gold=/) && !($_ =~ /diff=/ )) { $testmod{$testname} = $_[3]; # Module name, not gold $opt{$testname} = ""; # or diff } elsif ($_ =~ /gold=/) { $testmod{$testname} = "" ; # It's a gold file $opt{$testname} = $_[3] ; } elsif ($_ =~ /diff=/) { # It's a diff file $testmod{$testname} = ""; $opt{$testname} = $_[3]; } } elsif ($#_ eq 4) { # Check for 5 fields $testmod{$testname} = $_[3]; # Module name - always in this case if ($_ =~ /gold=/) { $opt{$testname} = $_[4]; } elsif ($_ =~ /diff=/) { $opt{$testname} = $_[4]; } } push (@testlist, $testname); } } } close (REGRESS_LIST); } # # execute_regression sequentially compiles and executes each test in # the regression. Regression is done as a two-pass run (execute, check # results) so that at some point the execution part can be parallelized. # sub execute_regression { local ($testname, $rv); local ($bpath, $lpath, $vpath); foreach $testname (@testlist) { # # First lets clean up if its' IVL. We need to know if # these are generated on the current pass. # if($comp_name eq "IVL") { if(-e "core") { system("rm -f core"); } if(-e "simv") { system("rm -f simv"); } if(-e "simv.exe") { system("rm -f simv.exe"); } } # # This is REALLY only an IVL switch... # # vermod is used to declare the "main module" # if( $testmod{$testname} ne "") { $vermod = "-s ".$testmod{$testname} ; } else { $vermod = " "; } if($comp_name eq "XL") { # Just over-ride for XL $vermod = " "; } print "Test $testname:"; if ($testpath{$testname} eq "") { $vpath = "./$testname.v"; } else { $vpath = "./$testpath{$testname}/$testname.v"; } $lpath = "./$logdir/$testname.log"; system("rm -rf $lpath"); system("rm -rf *.out"); # Check here for "compile only" situation and set # the switch appropriately. # # While we're in CO mode - take a snapshot of it. Note # this puts a contraint on the order -never can have a CO # as the FIRST test in the list for this to work. # if($testtype{$testname} ne "CO") { # Capture ONLY $versw = $old_versw ; # the non-compile only } # command here. if(($testtype{$testname} eq "CO") || ($testtype{$testname} eq "CN")) { if($comp_name eq "XL") { $versw = "-c" ; } else { if($testtype{$testname} eq "CN") { $versw = "-t null"; } else { $versw = ""; } } } else { $versw = $old_versw ; # Restore non-compile only state } # # if we have a logfile - remove it first # if(-e "$lpath") { system("rm $lpath"); } # # Now build the command up # # $cmd = "$vername $versw $vermod $verout $vpath &> $lpath "; $cmd = "$vername $versw $vermod $verout $vpath $redir $lpath "; print "$cmd\n"; system("$cmd"); # Note that with IVL we have to execute the code now # that it's compiled - there is GOING to be switch in # the verilog switch that will make this unnecessary. if($comp_name eq "IVL") { if( -e "simv") { if(!($testtype{$testname} eq "CO" ) && !($testtype{$testname} eq "CN" ) && !($testtype{$testname} eq "CE" )) { system ("./simv >> $lpath"); } else { system ("echo PASSED >> $lpath" ); } } elsif ( -e "core") { system ("echo CRASHED >> $lpath" ); } elsif ($testtype{$testname} eq "CN" ) { system ("echo PASSED >> $lpath" ); } else { system ("echo COMPERR >> $lpath" ); } } } } sub check_results { local ($testname, $rv); local ($bpath, $lpath, $vpath); local ($pass_count, $fail_count, $crash_count); local ($result); $pass_count = 0; $no_sorry = 0; $no_parse_err =0; $no_run = 0; $crash_count = 0; $comperr_cnt = 0; $comp_err = 0; open (REPORT, ">$report_fn"); print REPORT "Test Results:\n"; foreach $testname (@testlist) { $lpath = "$logdir/$testname.log"; # # This section is used to compare against GOLD FILES # We compare the log file against a known GOOD result # # This section runs if gold=name is the 4th option # $gold_file = ""; $gold_file = ""; $diff_file = ""; $optname = $opt{$testname} ; if(($opt{$testname} ne "") && ($optname =~ /gold=/)){ $gold_file = $opt{$testname}; $gold_file =~ s/gold=//; # remove gold= operator system("rm -rf ./dfile"); system("diff $lpath ./gold/$gold_file > ./dfile "); if( -z "dfile" ) { system ("echo PASSED >> $lpath" ); } else { system ("echo FAILED >> $lpath"); } } $gold_file = ""; $diff_file = ""; # # Now look for difference file requirements - use this for # vcd's initially I guess. # if(($opt{$testname} ne "") && ($optname =~ /diff=/)){ $diff_file = $optname ; $diff_file =~ s/diff=//; system("rm -rf ./dfile"); ($out_file,$gold_file) = split(/:/,$diff_file); system("diff $out_file $gold_file > ./dfile"); if( -z "dfile" ) { system ("echo PASSED >> $lpath" ); } else { system ("echo FAILED >> $lpath"); } } # uncompress the log file, if a compressed log file exists if (-f "$lpath.gz") { system "gunzip $lpath.gz"; } # check the log file for the test status if (-f $lpath) { print ("Checking test $lpath\n"); $result = `tail -150 $lpath`; # First do analysis for all tests that SHOULD run if(($testtype{$testname} ne "CO") && ($testtype{$testname} ne "CE") && ($testtype{$testname} ne "CN")) { # # This section is true for all tests that execute - # no matter the compiler. # if ($result =~ /PASSED/) { printf REPORT "%30s passed\n", $testname; $pass_count++; } elsif (($result =~ /FAILED/)) { printf REPORT "%30s execution failed\n", $testname; $no_run++; } # Need to check for syntax errors in tests that # are expected to pass. if($comp_name eq "XL") { if($result =~ /Error/) { printf REPORT "%30s compile errors\n", $testname; $no_compile++ ; } } else {# IVL compile error check goes here if ($result =~ /PASSED/) { } elsif ($result =~ /COMPERR/) { $comp_err = 0; printf REPORT "%30s ",$testname; if($result =~ /parse error/) { printf REPORT "had parse errors:"; $no_parse_err++; $no_compile++ ; $comp_err++; } if(($result =~ /Unable/) || ($result =~ /unhandled/)) { printf REPORT "had elaboration errors:"; $no_compile++ ; $comp_err++; } if($result =~ /sorry/) { printf REPORT "had unsupported features"; $no_sorry++ ; $no_compile++ ; $comp_err++; } if($comp_err eq 0) { printf REPORT "has C Compiler problem"; $no_compile++ ; $comperr_cnt++; } if($result =~ /CRASHED/ ) { printf REPORT "%30s compile crashed\n", $testname; printf "%30s compile crashed(2)\n", $testname; $crash_count++; } printf REPORT "\n"; } elsif (($result =~ /CRASHED/)) { printf REPORT "%30s compile crashed\n", $testname; printf "%30s compile crashed (1)\n", $testname; $crash_count++; } } } # Now look at Compile only situation - going to be # different results for each compiler. # Test for CE case first if($testtype{$testname} eq "CE") { if($comp_name eq "XL") { # Deal with XL frist if($result =~ /Error/) { $pass_count++; } } else { # Deal with IVL here... if (($result =~ /CRASHED/)) { printf REPORT "%30s compile crashed\n", $testname; printf "%30s compile crashed (1)\n", $testname; $crash_count++; } } } if(($testtype{$testname} eq "CO") || ($testtype{$testname} eq "CN")) { if($comp_name eq "XL") { if($result =~ /Error/) { printf REPORT "%30s compile failed\n", $testname; print "%30s compile failed\n", $testname; $no_compile++ ; } else { printf REPORT "%30s passed\n", $testname; $pass_count++ ; } } else { # IVL stuff goes here. if ($result =~ /PASSED/) { printf REPORT "%30s passed\n", $testname; $pass_count++; } elsif ($result =~ /COMPERR/) { $comp_err = 0; printf REPORT "%30s ",$testname; if($result =~ /parse error/) { printf REPORT "had parse errors:"; $no_parse_err++; $comp_err++; } if(($result =~ /Unable/) || ($result =~ /unhandled/)) { printf REPORT "had elaboration errors:"; $comp_err++; } if($result =~ /sorry/) { printf REPORT "had unsupported features"; $no_sorry++ ; $comp_err++; } if($comp_err eq 0) { printf REPORT "has C Compiler problem"; $comperr_cnt++; } if(!(comp_err eq 0)) { $no_compile++; } printf REPORT "\n"; } elsif ($result =~ /CRASHED/ ) { printf REPORT "%30s compile crashed\n", $testname; $crash_count++ ; } } } } else { printf REPORT "%30s No log file\n", $testname; $crash_count++; } } $total = $pass_count + $no_compile + $no_run + $crash_count; print REPORT "Tests passed: $pass_count, Parse Errors: $no_parse_err, Unsupported: $no_sorry, failed execution, $no_run, crashed: $crash_count, C Compiler errors: $comperr_cnt total: $total_count\n"; print "Tests passed: $pass_count, Parse Errors: $no_parse_err, Unsupported: $no_sorry, failed execution, $no_run, crashed: $crash_count, C compiler err: $comperr_cnt total: $total_count\n"; close (REPORT); } iverilog-12_0/ivtest/obsolete/vvptests/000077500000000000000000000000001435245347300203775ustar00rootroot00000000000000iverilog-12_0/ivtest/obsolete/vvptests/COPYING000066400000000000000000000431061435245347300214360ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: 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) 19yy 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. iverilog-12_0/ivtest/obsolete/vvptests/README000066400000000000000000000003441435245347300212600ustar00rootroot00000000000000This series of tests is used to validate the vvp portion of the iverilog runtimesystem. To use the tests just run: ./vvp.pl This will execute the regression list in regress.list and generate a report in regression_report.txt iverilog-12_0/ivtest/obsolete/vvptests/regress.list000066400000000000000000000033351435245347300227520ustar00rootroot00000000000000# # Copyright (c) 1999 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # Note that no extension is required for the testname, and that the # sregress.pl logic requires that the FIRST test in the list not be a # CO class test. # # Testtype can be one of # # normal: Normal results expected, i.e it should compile an execute # to a PASSED # CO: Compile only - Examine the logfile for any errors - shouldn't # be any. # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # The third arguement is the directory, and forth optional is one of # modulename - Defines the top level module # gold=filename - Compare a gold file against the generated log file. # diff=filename1:filename2 - Compare the two files for equality. # assignx0 normal vvpsources hello normal vvpsources resolvz normal vvpsources force normal vvpsources force0 normal vvpsources force_pca normal vvpsources iverilog-12_0/ivtest/obsolete/vvptests/vvp.pl000066400000000000000000000270341435245347300215550ustar00rootroot00000000000000#!/usr/bin/env perl -s ##!/utilities/perl/bin/perl -s # # Script vvp.pl modified to handle vvp for Steve Williams # # Copyright (c) 1999 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # 3/25/2001 SDW Modified sregress.pl script to run vvp. # 4/13/2001 SDW Added CORE DUMP detection # 5/5/2001 SDW Modified from vvp_reg.pl to run JUST vvp, no iverilog. # # $Log: vvp.pl,v $ # Revision 1.1 2001/05/07 05:13:21 stevewilliams # Add the initial suite to CVS. # # Revision 1.5 2001/04/14 03:44:03 ka6s # Added what I THINK is working redirection. The Parse Err is showing up now! # # Revision 1.4 2001/04/14 03:33:02 ka6s # Fixed detection of Core dumps. Made sure I remove core before we run vvp. # # Global setup and paths $| = 1; # This turns off buffered I/O $total_count = 0; $debug = 1; $num_opts = $#ARGV ; if($num_opts ne -1) { # Got here cuz there is a command line option $regress_fn = $ARGV[0]; if(!( -e "$regress_fn")) { print("Error - Command line option file $num_opts doesn't exist.\n"); exit(1); } } else { $regress_fn = "./regress.list"; } $logdir = "log"; $bindir = "bin"; # not currently used $report_fn = "./regression_report.txt"; $comp_name = "IVL" ; # Change the name of the compiler in use here. # this may change to a command line option after # I get things debugged! $vername = "/usr/bin/env vvp"; # IVL's shell $versw = ""; # switches $verout = "-o simv -tvvp"; # vvp source output (for IVL ) #$redir = "&>"; $redir = "> "; # Main script print ("Reading/parsing test list\n"); &read_regression_list; &rmv_logs ; &execute_regression; print ("Checking logfiles\n"); &check_results; # # Remove log files # sub rmv_logs { foreach (@testlist) { $cmd = "rm -rf log/$_.log"; system("$cmd"); } } # # parses the regression list file # # splits the data into a list of names (@testlist), and a # number of hashes, indexed by name of test. Hashes are # (from left-to-right in regression file): # # %testtype type of test. compile = compile only # normal = compile & run, expect standard # PASSED/FAILED message at EOT. # %testpath path to test, from root of test directory. No # trailing slash on test path. # # %testmod = main module declaration (optional) sub read_regression_list { open (REGRESS_LIST, "<$regress_fn"); local ($found, $testname); while () { chop; if (!/^#/) { # strip out any comments later in the file s/#.*//g; $found = split; if ($found > 2) { $total_count++; $testname = $_[0]; $testtype{$testname} = $_[1]; $testpath{$testname} = $_[2]; if($#_ eq 3) { # Check for 4 fields if(!($_ =~ /gold=/) && !($_ =~ /diff=/ )) { $testmod{$testname} = $_[3]; # Module name, not gold $opt{$testname} = ""; # or diff } elsif ($_ =~ /gold=/) { $testmod{$testname} = "" ; # It's a gold file $opt{$testname} = $_[3] ; } elsif ($_ =~ /diff=/) { # It's a diff file $testmod{$testname} = ""; $opt{$testname} = $_[3]; } } elsif ($#_ eq 4) { # Check for 5 fields $testmod{$testname} = $_[3]; # Module name - always in this case if ($_ =~ /gold=/) { $opt{$testname} = $_[4]; } elsif ($_ =~ /diff=/) { $opt{$testname} = $_[4]; } } push (@testlist, $testname); } } } close (REGRESS_LIST); } # # execute_regression sequentially compiles and executes each test in # the regression. Regression is done as a two-pass run (execute, check # results) so that at some point the execution part can be parallelized. # sub execute_regression { local ($testname, $rv); local ($bpath, $lpath, $vpath); foreach $testname (@testlist) { # # First lets clean up if its' IVL. We need to know if # these are generated on the current pass. # # # This is REALLY only an IVL switch... # # vermod is used to declare the "main module" # if( $testmod{$testname} ne "") { $vermod = "-s ".$testmod{$testname} ; } else { $vermod = " "; } print "Test $testname:"; if ($testpath{$testname} eq "") { $vpath = "./$testname.vp"; } else { $vpath = "./$testpath{$testname}/$testname.vp"; } $lpath = "./$logdir/$testname.log"; system("rm -rf $lpath"); system("rm -rf *.out"); # Check here for "compile only" situation and set # the switch appropriately. # # While we're in CO mode - take a snapshot of it. Note # this puts a contraint on the order -never can have a CO # as the FIRST test in the list for this to work. # if($testtype{$testname} ne "CO") { # Capture ONLY $versw = $old_versw ; # the non-compile only } # command here. if(($testtype{$testname} eq "CO") || ($testtype{$testname} eq "CN")) { if($testtype{$testname} eq "CN") { $versw = "-t null"; } else { $versw = ""; } } else { $versw = $old_versw ; # Restore non-compile only state } # # if we have a logfile - remove it first # if(-e "$lpath") { system("rm $lpath"); } # # Now build the command up # # $cmd = "$vername $versw $vermod $verout $vpath &> $lpath "; $cmd = "$vername $vpath $redir $lpath 2>&1 "; print "$cmd\n"; $rc = system("$cmd"); # Note that with IVL we have to execute the code now # that it's compiled - there is GOING to be switch in # the verilog switch that will make this unnecessary. #if(($rc == 0) && ($comp_name eq "IVL")) { # if( -e "simv") { # if(!($testtype{$testname} eq "CO" ) && # !($testtype{$testname} eq "CN" ) && # !($testtype{$testname} eq "CE" )) { # system ("rm -rf core"); # system ("/usr/bin/env vvp simv >> $lpath 2>&1 "); # } else { # # } # if( -e "core") { # system ("echo CRASHED > $lpath" ); # } # } elsif ( -e "core") { # system ("echo CRASHED >> $lpath" ); # # } elsif ($testtype{$testname} eq "CN" ) { # # system ("echo PASSED >> $lpath" ); # } else { # system ("echo COMPERR >> $lpath" ); # } #} } } sub check_results { local ($testname, $rv); local ($bpath, $lpath, $vpath); local ($pass_count, $fail_count, $crash_count); local ($result); $pass_count = 0; $no_sorry = 0; $parse =0; $no_run = 0; $crash_count = 0; $comperr_cnt = 0; $comp_err = 0; $unhandled = 0; $unable = 0; $assertion = 0; $passed = 0; $failed = 0; open (REPORT, ">$report_fn"); print REPORT "Test Results:\n"; foreach $testname (@testlist) { $lpath = "$logdir/$testname.log"; # # This section is used to compare against GOLD FILES # We compare the log file against a known GOOD result # # This section runs if gold=name is the 4th option # $gold_file = ""; $gold_file = ""; $diff_file = ""; $optname = $opt{$testname} ; if(($opt{$testname} ne "") && ($optname =~ /gold=/)){ $gold_file = $opt{$testname}; $gold_file =~ s/gold=//; # remove gold= operator system("rm -rf ./dfile"); system("diff $lpath ./gold/$gold_file > ./dfile "); if( -z "dfile" ) { system ("echo PASSED >> $lpath" ); } else { system ("echo FAILED >> $lpath"); } } $gold_file = ""; $diff_file = ""; # # Now look for difference file requirements - use this for # vcd's initially I guess. # if(($opt{$testname} ne "") && ($optname =~ /diff=/)){ $diff_file = $optname ; $diff_file =~ s/diff=//; system("rm -rf ./dfile"); ($out_file,$gold_file) = split(/:/,$diff_file); print("diff $out_file $gold_file > ./dfile"); system("diff $out_file $gold_file > ./dfile"); if( -z "dfile" ) { system ("echo PASSED >> $lpath" ); } else { system ("echo FAILED >> $lpath"); } } # uncompress the log file, if a compressed log file exists if (-f "$lpath.gz") { system "gunzip $lpath.gz"; } # check the log file for the test status if (-f $lpath) { print ("Checking test $lpath\n"); $result = `tail -150 $lpath`; $err_flag = 0; # First do analysis for all tests that SHOULD run printf REPORT "%30s ",$testname; if( ($testtype{$testname} ne "CE") && ($testtype{$testname} ne "CN")) { # # This section is true for all tests that execute - # no matter the compiler. # if ($result =~ "Unhandled") { $err_flag = 1; printf REPORT "Unhandled-"; $unhandled++; } if ($result =~ "sorry") { $err_flag = 1; printf REPORT "Sorry-"; $unhandled++; } if ($result =~ "parse") { $err_flag = 1; printf REPORT "Parse Err-"; $parse++; } if ($result =~ "Unable" ) { $err_flag = 1; printf REPORT "Unable-"; $unable++; } if ($result =~ "Assertion" ) { $err_flag = 1; printf REPORT "Assertion-"; $assertion++; } if ($result =~ "CRASHED" ) { $err_flag = 1; printf REPORT "Ran-CORE DUMP-"; $failed++; } if($testtype{$testname} ne "CO") { if ($result =~ "PASSED" ) { printf REPORT "Ran-PASSED-"; $passed++; } if ($result =~ "FAILED" ) { printf REPORT "Ran-FAILED-"; $failed++; } } else { if(-z $lpath) { printf REPORT "CO-PASSED-"; $passed++; } else { printf REPORT "CO-FAILED-"; $failed++; } } printf REPORT "\n"; } else { printf REPORT "\n"; } } } $total = $pass_count + $no_compile + $no_run + $crash_count; print REPORT "Tests passed: $passed, failed: $failed, Unhandled: $unhandled Unable: $unable, Assert: $assertion, Parse Errs: $parse"; print "Tests passed: $passed, failed: $failed, Unhandled: $unhandled Unable: $unable, Assert: $assertion Parse Errs: $parse\n"; close (REPORT); } iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/000077500000000000000000000000001435245347300226165ustar00rootroot00000000000000iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/assignx0.vp000066400000000000000000000026761435245347300247340ustar00rootroot00000000000000:vpi_time_precision + 0; :vpi_module "system"; ; Copyright (c) 2001 Stephen Williams (steve@icarus.com) ; ; This source code is free software; you can redistribute it ; and/or modify it in source code form under the terms of the GNU ; General Public License as published by the Free Software ; Foundation; either version 2 of the License, or (at your option) ; any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ; ; This program tests the indexed %assign statement. ; S_main .scope module, "main"; V_test .var "test", 3, 0; start %set V_test[0], 0; %set V_test[1], 0; %set V_test[2], 0; %set V_test[3], 0; %ix/load 0, 3; %assign/x0 V_test, 1, 1; %delay 2; %load 8, V_test[0]; %load 9, V_test[1]; %load 10, V_test[2]; %load 11, V_test[3]; %mov 12, 0, 1; %mov 13, 0, 1; %mov 14, 0, 1; %mov 15, 1, 1; %cmp/u 8, 12, 4; %jmp/1 passed, 6; %vpi_call "$display", "FAILED"; %vpi_call "$finish"; %end; passed %vpi_call "$display", "PASSED"; %vpi_call "$finish"; %end; .thread start; iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/force.vp000066400000000000000000000036101435245347300242630ustar00rootroot00000000000000#! /usr/bin/env vvp -v :vpi_time_precision + 0; :vpi_module "system"; S_test .scope module, "test"; V_test.val1 .var "val1", 3, 0; V_test.val2 .var "val2", 3, 0; V_test._L0 .net "_L0", 1, 0, C<0>, C<1>; V_test._L3 .net "_L3", 0, 0, C<0>; V_test._L4 .net "_L4", 0, 0, L_test._L5; L_test._L5/L0C0 .functor XNOR, V_test.val1[0], C<0>, C<0>, C<0>; L_test._L5/L0C1 .functor XNOR, V_test.val1[1], C<1>, C<0>, C<0>; L_test._L5/L0C2 .functor XNOR, V_test.val1[2], C<0>, C<0>, C<0>; L_test._L5/L0C3 .functor XNOR, V_test.val1[3], C<0>, C<0>, C<0>; L_test._L5 .functor AND, L_test._L5/L0C0, L_test._L5/L0C1, L_test._L5/L0C2, L_test._L5/L0C3; fofu .force V_test.val2, L_test._L5, C<0>, C<0>, C<0>; .scope S_test; T_0 ; %set V_test.val2[0], 0; %set V_test.val2[1], 0; %set V_test.val2[2], 0; %set V_test.val2[3], 0; %set V_test.val1[0], 0; %set V_test.val1[1], 1; %set V_test.val1[2], 0; %set V_test.val1[3], 0; %delay 50; %load 8, V_test.val2[0]; %load 9, V_test.val2[1]; %load 10, V_test.val2[2]; %load 11, V_test.val2[3]; %mov 12, 1, 1; %mov 13, 0, 3; %cmp/u 8, 12, 4; %inv 6, 1; %mov 8, 6, 1; %jmp/0xz T_0.0, 8; %vpi_call "$display", "force FAILED"; %jmp T_0.1; T_0.0 ; %vpi_call "$display", "force PASSED"; T_0.1 ; %delay 50; %load 8, V_test.val2[0]; %load 9, V_test.val2[1]; %load 10, V_test.val2[2]; %load 11, V_test.val2[3]; %mov 12, 1, 1; %mov 13, 0, 3; %cmp/u 8, 12, 4; %inv 6, 1; %mov 8, 6, 1; %jmp/0xz T_0.2, 8; %vpi_call "$display", "release PASSED"; %jmp T_0.3; T_0.2 ; %vpi_call "$display", "release FAILED"; T_0.3 ; %end; .thread T_0; .scope S_test; T_1 ; %delay 20; %force fofu[0], 4; %delay 40; %release V_test.val2[0]; %release V_test.val2[1]; %release V_test.val2[2]; %release V_test.val2[3]; %end; .thread T_1; iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/force0.vp000066400000000000000000000011551435245347300243450ustar00rootroot00000000000000#! /home/drjury/stephan/icarus/lib/ivl/../../bin/vvp :vpi_time_precision + 0; :vpi_module "system"; S_ftest .scope module, "ftest"; V_ftest.a .net "a", 0, 0, C<0>; V_ftest.b .net "b", 0, 0, C<0>; V_ftest._L4 .net "_L4", 0, 0, C<1>; fofu .force V_ftest.a, C<1> ; .scope S_ftest; T_0 ; %force fofu, 1 ; %delay 1; %load 8, V_ftest.b[0]; %cmp/u 8, 0, 1; %inv 6, 1; %mov 8, 6, 1; %jmp/0xz T_0.0, 8; %vpi_call "$display", "FAILED: %b %b", V_ftest.a, V_ftest.b; %jmp T_0.1; T_0.0 ; %vpi_call "$display", "PASSED: %b %b", V_ftest.a, V_ftest.b; T_0.1 ; %end; .thread T_0; iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/force_pca.vp000066400000000000000000000104671435245347300251160ustar00rootroot00000000000000#! /home/drjury/stephan/icarus/lib/ivl/../../bin/vvp :vpi_time_precision + 0; :vpi_module "system"; S .scope module, "test"; V.force_expr .var "force_expr", 1, 0; V.pca_expr .var "pca_expr", 1, 0; V.tgt .var "tgt", 1, 0; S.test .scope task, "test.test", S; V.test.errors .var "errors", 0, 0; V.test.expect .var "expect", 1, 0; fofu .force V.tgt, V.force_expr[0], V.force_expr[1]; TD.test ; %delay 1; %load 8, V.tgt[0]; %load 9, V.tgt[1]; %load 10, V.test.expect[0]; %load 11, V.test.expect[1]; %cmp/u 8, 10, 2; %inv 6, 1; %mov 8, 6, 1; %jmp/0xz T_0.0, 8; %vpi_call "$display", "%b FAILED: expect %b", V.tgt, V.test.expect; %set V.test.errors[0], 1; %jmp T_0.1; T_0.0 ; %vpi_call "$display", "%b", V.tgt; T_0.1 ; %end; .scope S; T_1 ; %set V.test.errors[0], 0; %end; .thread T_1; .scope S; T_2 ; %vpi_call "$dumpvars"; %set V.tgt[0], 0; %set V.tgt[1], 0; %set V.pca_expr[0], 1; %set V.pca_expr[1], 0; %set V.force_expr[0], 0; %set V.force_expr[1], 0; %set V.test.expect[0], 0; %set V.test.expect[1], 0; %fork TD.test, S.test; %join; %cassign V.tgt[0], V.pca_expr[0]; %cassign V.tgt[1], V.pca_expr[1]; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %set V.pca_expr[0], 1; %set V.pca_expr[1], 1; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %force fofu, 2; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %set V.force_expr[0], 0; %set V.force_expr[1], 1; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %release V.tgt[0]; %release V.tgt[1]; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %deassign V.tgt[0], 2; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %set V.pca_expr[0], 1; %set V.pca_expr[1], 0; %set V.test.expect[0], 1; %set V.test.expect[1], 1; %fork TD.test, S.test; %join; %cassign V.tgt[0], V.pca_expr[0]; %cassign V.tgt[1], V.pca_expr[1]; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %force fofu, 2; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %deassign V.tgt[0], 2; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %release V.tgt[0]; %release V.tgt[1]; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %set V.force_expr[0], 1; %set V.force_expr[1], 1; %force fofu, 2; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %cassign V.tgt[0], V.pca_expr[0]; %cassign V.tgt[1], V.pca_expr[1]; %load 8, V.force_expr[0]; %load 9, V.force_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %release V.tgt[0]; %release V.tgt[1]; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %deassign V.tgt[0], 2; %load 8, V.pca_expr[0]; %load 9, V.pca_expr[1]; %set V.test.expect[0], 8; %set V.test.expect[1], 9; %fork TD.test, S.test; %join; %load 8, V.test.errors[0]; %mov 4, 8, 1; %mov 8, 1, 1; %jmp/0xz T_2.0, 4; %mov 8, 0, 1; T_2.0 ; %jmp/0xz T_2.1, 8; %vpi_call "$display", "PASSED"; T_2.1 ; %vpi_call "$finish"; %end; .thread T_2; iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/hello.vp000066400000000000000000000002401435245347300242640ustar00rootroot00000000000000#! /usr/bin/env vvp :vpi_module "system"; S_main .scope module, "main"; .scope S_main; T_0 ; %vpi_call "$display", "PASSED"; %end; .thread T_0; iverilog-12_0/ivtest/obsolete/vvptests/vvpsources/resolvz.vp000066400000000000000000000041461435245347300246760ustar00rootroot00000000000000:vpi_module "system"; ; Copyright (c) 2001 Stephen Williams (steve@icarus.com) ; ; This source code is free software; you can redistribute it ; and/or modify it in source code form under the terms of the GNU ; General Public License as published by the Free Software ; Foundation; either version 2 of the License, or (at your option) ; any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ; This program tests the .resolv functor. It works by sending a few ; variables into the .resolv object and watching what it does. main .scope module, "main" ; main.a .var "a", 0, 0; main.b .var "b", 0, 0; main.x .resolv tri, main.a, main.b, C, C; main.out .net "out", 0, 0, main.x; code ; %set main.a, 3; a = 1'bz %set main.b, 3; b = 1'bz %delay 1; %load 8, main.x; %cmp/u 8, 3, 1; if (x !== 1'bz) ... %jmp/1 is_a_z, 6; %vpi_call "$display", "FAILED (z) -- main.x = %b", main.out; %vpi_call "$finish"; %end; is_a_z ; ... endif %set main.a, 1; a = 1'b1; %delay 1; %load 8, main.x; %cmp/u 8, 1, 1; if (x !== 1'b1) ... %jmp/1 is_a_1, 6; %vpi_call "$display", "FAILED (1) -- main.x = %b", main.out; %vpi_call "$finish"; %end; is_a_1 ; %set main.b, 0; b = 1'b0; %delay 1; %load 8, main.x; %cmp/u 8, 2, 1; if (x !== 1'bx) ... %jmp/1 is_a_x, 6; %vpi_call "$display", "FAILED (x) -- main.x = %b", main.out; %vpi_call "$finish"; %end; is_a_x ; %set main.a, 0; a = 1'bz; %delay 1; %load 8, main.x; %cmp/u 8, 0, 1; if (x !== 1'b0) ... %jmp/1 is_a_0, 6; %vpi_call "$display", "FAILED (0) -- main.x = %b", main.out; %vpi_call "$finish"; %end; is_a_0 ; ; Done. If I get here, it passed all the tests. %vpi_call "$display", "PASSED"; %end; .thread code; iverilog-12_0/ivtest/perl-lib/000077500000000000000000000000001435245347300163735ustar00rootroot00000000000000iverilog-12_0/ivtest/perl-lib/Diff.pm000066400000000000000000000074641435245347300176140ustar00rootroot00000000000000# # Module for comparing expected and actual output of tests. # It knows how to skip valgrind output ^==\d+== or ^**\d+** # package Diff; use strict; use warnings; our $VERSION = '1.00'; use base 'Exporter'; our @EXPORT = qw(diff); # # We only need a simple diff, but we need to strip \r at the end of line # and we need to ignore the valgrind output. # sub diff { my ($gold, $log, $skip, $unordered) = @_; my ($diff, $gline, $lline); $diff = 0; # # If we do not have a gold file then we just look for a log file line # with just PASSED on it to indicate that the test worked correctly. # if ($gold eq "") { open (LOG, "<$log") or do { warn "Error: unable to open $log for reading.\n"; return 1; }; $diff = 1; # Loop on the log file lines looking for a "passed" by it self. # For VHDL tests we need to ignore time, filename, severity, etc. # that GHDL prints for report statments foreach $lline () { if ($lline =~ /^\s*passed\s*$/i) { $diff = 0; } elsif ($lline =~ /@\d+\w+:\(report note\): passed\s*$/i) { $diff = 0; } } close (LOG); } else { open (GOLD, "<$gold") or do { warn "Error: unable to open $gold for reading.\n"; return 1; }; open (LOG, "<$log") or do { warn "Error: unable to open $log for reading.\n"; return 1; }; if ($unordered) { my @glines = sort map { s/\r\n$/\n/; $_ } ; my @llines = sort map { s/\r\n$/\n/; $_ } ; my $gindex = 0; my $lindex = 0; while ($gindex < @glines) { # Skip lines from valgrind ^==\d+== or ^**\d+** while ($lindex < @llines && $llines[$lindex] =~ m/^(==|\*\*)\d+(==|\*\*)/) { $lindex++ } if ($lindex == @llines) { $diff = 1; last; } # Skip initial lines if needed. if ($skip > 0) { $lindex++; $skip--; next; } if ($glines[$gindex] ne $llines[$lindex]) { $diff = 1; last; } $gindex++; $lindex++; } # Check to see if the log file has extra lines. while ($lindex < @llines && $llines[$lindex] =~ m/^(==|\*\*)\d+(==|\*\*)/) { $lindex++ } $diff = 1 if $lindex < @llines; } else { # Loop on the gold file lines. foreach $gline () { if (eof LOG) { $diff = 1; last; } $lline = ; # Skip lines from valgrind ^==\d+== or ^**\d+** while ($lline =~ m/^(==|\*\*)\d+(==|\*\*)/) { $lline = ; } # Skip initial lines if needed. if ($skip > 0) { $skip--; next; } $gline =~ s/\r\n$/\n/; # Strip at the end of line. $lline =~ s/\r\n$/\n/; # Strip at the end of line. if ($gline ne $lline) { $diff = 1; last; } } # Check to see if the log file has extra lines. while (!eof LOG and !$diff) { $lline = ; $diff = 1 if ($lline !~ m/^(==|\*\*)\d+(==|\*\*)/); } } close (LOG); close (GOLD); } return $diff; } 1; # Module loaded OK iverilog-12_0/ivtest/perl-lib/Environment.pm000066400000000000000000000060031435245347300212340ustar00rootroot00000000000000# # Module for processing command line arguments, etc. # package Environment; use strict; use warnings; our $VERSION = '1.03'; use base 'Exporter'; our @EXPORT = qw(get_args get_regress_fn get_ivl_version); use constant DEF_REGRESS_FN => './regress.list'; # Default regression list. use constant DEF_SUFFIX => ''; # Default suffix. use constant DEF_STRICT => 0; # Default strict option. use constant DEF_WITH_VALG => 0; # Default valgrind usage (keep this off). use constant DEF_FORCE_SV => 0; # Default is use the generation supplied. use Getopt::Long; # # Get the executable/etc. suffix. # sub get_args { my $suffix = DEF_SUFFIX; my $strict = DEF_STRICT; my $with_valg = DEF_WITH_VALG; my $force_sv = DEF_FORCE_SV; if (!GetOptions("suffix=s" => \$suffix, "strict" => \$strict, "with-valgrind" => \$with_valg, "force-sv" => \$force_sv, "help" => \&usage)) { die "Error: Invalid argument(s).\n"; } return ($suffix, $strict, $with_valg, $force_sv); } sub usage { my $def_sfx = DEF_SUFFIX; my $def_opt = DEF_STRICT ? "yes" : "no"; my $def_reg_fn = DEF_REGRESS_FN; my $def_with_valg = DEF_WITH_VALG ? "on" : "off"; my $def_force_sv = DEF_FORCE_SV ? "yes" : "no"; warn "$0 usage:\n\n" . " --suffix= # The Icarus executable suffix, " . "default \"$def_sfx\".\n" . " --strict # Force strict standard compliance, " . "default \"$def_opt\".\n" . " --with-valgrind # Run the test suite with valgrind, " . "default \"$def_with_valg\".\n" . " --force-sv # Force tests to be run as SystemVerilog, " . "default \"$def_force_sv\".\n" . " # The regression file, " . "default \"$def_reg_fn\".\n\n"; exit; } # # Get the name of the regression list file. Either the default # or the file specified in the command line arguments. # sub get_regress_fn { my $regress_fn = DEF_REGRESS_FN; # Is there a command line argument (alternate regression list)? if ($#ARGV != -1) { $regress_fn = $ARGV[0]; -e "$regress_fn" or die "Error: command line regression file $regress_fn doesn't exist.\n"; -f "$regress_fn" or die "Error: command line regression file $regress_fn is not a file.\n"; -r "$regress_fn" or die "Error: command line regression file $regress_fn is not ". "readable.\n"; if ($#ARGV > 0) { warn "Warning: only using first file argument to script.\n"; } } return $regress_fn; } # # Get the current version from iverilog. # sub get_ivl_version { my $sfx = shift(@_); if (`iverilog$sfx -V` =~ /^Icarus Verilog version (\d+)\.(\d+)/) { if ($1 == 0) { return $1.".".$2; } else { return $1; } } else { die "Failed to get version from iverilog$sfx -V output"; } } 1; # Module loaded OK iverilog-12_0/ivtest/perl-lib/RegressionList.pm000066400000000000000000000153151435245347300217120ustar00rootroot00000000000000# # Module for parsing and loading regression test lists. # package RegressionList; use strict; use warnings; our $VERSION = '1.01'; use base 'Exporter'; our @EXPORT = qw(read_regression_list @testlist %srcpath %testtype %args %plargs %diff %gold %unordered %testmod %offset); # Properties of each test. # It may be nicer to have read_regression_list return an array # of hashes with these as keys. our (@testlist, %srcpath, %testtype, %args, %plargs, %diff, %gold, %unordered, %testmod, %offset) = (); # # Parses the regression list file # # Parameters: # $regress_fn = file name to read tests from. # $ver = iverilog version. # # (from left-to-right in regression file): # # test_name type,opt_ivl_args test_dir opt_module_name log/gold_file # # type can be: # normal # CO = compile only. # CE = compile error. # CN = compile null. # RE = runtime error. # EF = expected fail. # NI = not implemented. # sub read_regression_list { my $regress_fn = shift or die "No regression list file name specified"; my $ver = shift or die "No iverilog version specified"; my $force_sv = shift; my $opt = shift; my ($line, @fields, $tname, $tver, %nameidx, $options); open (REGRESS_LIST, "<$regress_fn") or die "Error: unable to open $regress_fn for reading.\n"; while ($line = ) { # can't use chomp here - in MSYS2 it only consumes the LF, not the CR $line =~ s/\r?\n?$//; # recognise a trailing '\' as a line continuation if ($line =~ s/\\$//) { my $next_line = ; $next_line =~ s/^\s+//; $line .= $next_line; redo unless eof(REGRESS_LIST); } next if ($line =~ /^\s*#/); # Skip comments. next if ($line =~ /^\s*$/); # Skip blank lines. $line =~ s/#.*$//; # Strip in line comments. $line =~ s/\s+$//; # Strip trailing white space. @fields = split(' ', $line); if (@fields < 2) { die "Error: $fields[0] must have at least 3 fields.\n"; } $tname = $fields[0]; if ($tname =~ /:/) { ($tver, $tname) = split(":", $tname); # Skip if this is not our version or option. next if (($tver ne "v$ver") && ($tver ne $opt)); } else { next if (exists($testtype{$tname})); # Skip if already defined. } # Get the test type and the iverilog argument(s). Separate the # arguments with a space. if ($fields[1] =~ ',') { ($testtype{$tname},$args{$tname}) = split(',', $fields[1], 2); if ($args{$tname} =~ ',') { my @args = split(',', $args{$tname}); $plargs{$tname} = join(' ', grep(/^\+/, @args)); $args{$tname} = join(' ', grep(!/^\+/, @args)); } elsif ($args{$tname} =~ /^\+/) { $plargs{$tname} = $args{$tname}; $args{$tname} = ""; } else { $plargs{$tname} = ""; } } else { $testtype{$tname} = $fields[1]; $plargs{$tname} = ""; $args{$tname} = ""; } if ($opt ne "std") { $args{$tname} = $opt . $args{$tname}; } $srcpath{$tname} = $fields[2]; $srcpath{$tname} = "" if (!defined($srcpath{$tname})); # The four field case. if (@fields == 4) { if ($fields[3] =~ s/^diff=//) { $testmod{$tname} = "" ; ($diff{$tname}, $gold{$tname}, $offset{$tname}) = split(':', $fields[3]); # Make sure this is numeric if it is not given. if (!$offset{$tname}) { $offset{$tname} = 0; } } elsif ($fields[3] =~ s/^gold=//) { $testmod{$tname} = "" ; $diff{$tname} = ""; $gold{$tname} = "gold/$fields[3]"; $offset{$tname} = 0; } elsif ($fields[3] =~ s/^unordered=//) { $testmod{$tname} = "" ; $diff{$tname} = ""; $gold{$tname} = "gold/$fields[3]"; $unordered{$tname} = 1; $offset{$tname} = 0; } else { $testmod{$tname} = $fields[3]; $diff{$tname} = ""; $gold{$tname} = ""; $offset{$tname} = 0; } # The five field case. } elsif (@fields == 5) { if ($fields[4] =~ s/^diff=//) { $testmod{$tname} = "" ; ($diff{$tname}, $gold{$tname}, $offset{$tname}) = split(':', $fields[4]); # Make sure this is numeric if it is not given. if (!$offset{$tname}) { $offset{$tname} = 0; } } elsif ($fields[4] =~ s/^gold=//) { $testmod{$tname} = "" ; $diff{$tname} = ""; $gold{$tname} = "gold/$fields[4]"; $offset{$tname} = 0; } elsif ($fields[4] =~ s/^unordered=//) { $testmod{$tname} = "" ; $diff{$tname} = ""; $gold{$tname} = "gold/$fields[4]"; $unordered{$tname} = 1; $offset{$tname} = 0; } } else { $testmod{$tname} = ""; $diff{$tname} = ""; $gold{$tname} = ""; $offset{$tname} = 0; } # If the name exists this is a replacement so skip the original one. if (exists($nameidx{$tname})) { splice(@testlist, $nameidx{$tname}, 1, ""); } push (@testlist, $tname); $nameidx{$tname} = @testlist - 1; # The generation to use is passed if it does not match # the default. To make sure the tests are protable we # use the force SV flag to force all tests to be run # as the latest SystemVerilog generation. This assumes # the correct `begin_keywords has been added to the # various files. if ($force_sv) { my $fsv_flags = "-g2012"; $args{$tname} =~ s/-g2012//; $args{$tname} =~ s/-g2009//; $args{$tname} =~ s/-g2005-sv//; $args{$tname} =~ s/-g2005//; $args{$tname} =~ s/-g2001-noconfig//; $args{$tname} =~ s/-g2001//; $args{$tname} =~ s/-g1995//; $args{$tname} =~ s/-g2x/-gicarus-misc/; # Deprecated for 2001 $args{$tname} =~ s/-g2//; # Deprecated for 2001 $args{$tname} =~ s/-g1//; # Deprecated for 1995 if ($args{$tname}) { $args{$tname} = "$fsv_flags $args{$tname}"; } else { $args{$tname} = "$fsv_flags"; } } } close (REGRESS_LIST); } 1; # Module loaded OK iverilog-12_0/ivtest/perl-lib/Reporting.pm000066400000000000000000000015151435245347300207040ustar00rootroot00000000000000# # Module for writing to the regression report file. # package Reporting; use strict; use warnings; our $VERSION = '1.00'; use base 'Exporter'; our @EXPORT = qw(open_report_file print_rpt close_report_file); use constant DEF_REPORT_FN => './regression_report.txt'; $| = 1; # This turns off buffered I/O # # Open the report file for writing. # If no argument is given, DEF_REPORT_FN is the filename. # sub open_report_file { my $report_fn = shift || DEF_REPORT_FN; open (REGRESS_RPT, ">$report_fn") or die "Error: unable to open $report_fn for writing.\n"; } # # Print the argument to both the normal output and the report file. # sub print_rpt { print @_; print REGRESS_RPT @_; } # # Close the report file once we're done with it. # sub close_report_file { close (REGRESS_RPT); } 1; # Module loaded OK iverilog-12_0/ivtest/regress000077500000000000000000000000551435245347300162650ustar00rootroot00000000000000#!/bin/csh limit coredumpsize 0 ./vvp_reg.pl iverilog-12_0/ivtest/regress-fsv.list000066400000000000000000000124441435245347300200350ustar00rootroot00000000000000# This test list contains tests that should work using any simulator that # supports SystemVerilog (1800-2012). # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # Some constructs/usage are not errors in SystemVerilog br1015a normal ivltests br1027a normal ivltests gold=br1027a-fsv.gold br1027c normal ivltests gold=br1027c-fsv.gold br1027e normal ivltests gold=br1027e-fsv.gold br_gh25a normal ivltests br_gh25b normal ivltests br_gh567 normal ivltests check_constant_3 normal ivltests function4 normal ivltests module_inout_port_type normal ivltests module_input_port_list_def normal,-g2005-sv ivltests module_input_port_type normal ivltests parameter_in_generate1 normal ivltests parameter_no_default normal ivltests parameter_omit1 normal ivltests parameter_omit2 normal ivltests parameter_omit3 normal ivltests pr1963962 normal ivltests gold=pr1963962-fsv.gold pr3015421 CE ivltests gold=pr3015421-fsv.gold resetall normal,-Wtimescale ivltests gold=resetall-fsv.gold scope2b normal ivltests sys_func_task_error RE ivltests gold=sys_func_task_error-fsv.gold unnamed_block_var_decl normal ivltests unnamed_fork_var_decl normal ivltests # We do not run synthesis when forcing SystemVerilog so these pass br995 normal ivltests br_gh306a normal ivltests br_gh306b normal ivltests case5-syn-fail normal ivltests casesynth7 normal ivltests casesynth8 normal ivltests dffsynth normal ivltests dffsynth8 normal ivltests memsynth1 normal ivltests memsynth2 normal ivltests memsynth3 normal ivltests memsynth5 normal ivltests memsynth6 normal ivltests memsynth7 normal ivltests memsynth9 normal ivltests mix_reset normal ivltests # These use $abstime() and will actually run correctly with -g2012 (different # results), but since this file is loaded in sv-tests mark them as NI instead # of creating the correct gold file pr2590274a NI ivltests pr2590274b NI ivltests pr2590274c NI ivltests # These are not supported in Icarus, but are valid SystemVerilog array_lval_select3a normal ivltests br605a normal ivltests br605b normal ivltests br971 normal ivltests br1005 normal ivltests br1015b normal ivltests br_ml20150315b normal ivltests sv_darray_nest1 normal ivltests sv_darray_nest2 normal ivltests sv_darray_nest3 normal ivltests sv_darray_nest4 normal ivltests sv_darray_oob_vec2 normal ivltests sv_deferred_assert1 normal ivltests sv_deferred_assert2 normal ivltests sv_deferred_assume1 normal ivltests sv_deferred_assume2 normal ivltests sv_queue_nest1 normal ivltests sv_queue_nest2 normal ivltests sv_queue_nest3 normal ivltests sv_queue_nest4 normal ivltests sv_queue_oob_vec2 normal ivltests iverilog-12_0/ivtest/regress-ivl1.list000066400000000000000000000264051435245347300201140ustar00rootroot00000000000000# This test list contains tests that use Icarus specific language extensions # and tests for known Icarus limitations and deviations. # NOTE: This isn't a complete list - some tests adapt themselves if the # __ICARUS__ macro is defined. # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # #------------------------------------------------------------------------------ # Icarus pre-processor extensions #------------------------------------------------------------------------------ # Escaped defines `` macro_str_esc normal ivltests gold=macro_str_esc.gold macro_with_args normal ivltests gold=macro_with_args.gold mcl1 normal ivltests gold=mcl1.gold pr622 normal ivltests gold=pr622.gold pr639 normal ivltests gold=pr639.gold pr1741212 normal ivltests gold=pr1741212.gold pr1912112 normal ivltests gold=pr1912112.gold pr1925360 normal ivltests repeat1 normal ivltests # This just checks whether the pre-processor runs successfully pr2002443 CO,-E ivltests #------------------------------------------------------------------------------ # Icarus language extensions #------------------------------------------------------------------------------ # $abs, $min and $max to match VAMS abs, min and max constfunc6_ams normal ivltests non-polymorphic-abs normal ivltests pr3270320_ams CE ivltests test_va_math normal,-mva_math ivltests gold=test_va_math.gold va_math normal ivltests # $abstime from VAMS abstime normal ivltests pr2590274a normal ivltests gold=pr2590274.gold pr2590274b normal ivltests gold=pr2590274.gold pr2590274c normal,-gspecify ivltests gold=pr2590274.gold # $bits bitsel normal ivltests gold=bitsel.gold bitsel10 normal ivltests bitsel2 normal ivltests bitsel3 normal ivltests bitsel4 normal ivltests bitsel5 normal ivltests bitsel6 normal ivltests bitsel7 normal ivltests bitsel8 normal ivltests # pr615 bitsel9 normal ivltests # pr617 bitwidth3 normal ivltests clog2 normal ivltests clog2-signal normal ivltests param_vec normal ivltests param_vec2 normal ivltests pr498a normal ivltests pr721 normal ivltests pr809 normal ivltests pr809b normal ivltests pr979 normal ivltests gold=pr979.gold pr1000 normal ivltests pr1609611 normal ivltests pr1750870 normal ivltests pr1765789 normal ivltests pr1771903 normal ivltests gold=pr1771903.gold pr1793749 normal ivltests gold=pr1793749.gold pr1793749b normal ivltests gold=pr1793749b.gold pr1861212b normal ivltests gold=pr1861212.gold pr1864110c normal ivltests gold=pr1864110c.gold pr1864115 normal ivltests gold=pr1864115.gold pr2806449 normal ivltests pr2877555 normal ivltests real4 normal ivltests realtobits normal ivltests specparam1 normal ivltests specparam2 normal ivltests tern3 normal ivltests gold=tern3.gold v2005_math normal ivltests # $deposit deposit normal ivltests deposit_wire normal ivltests sysargs normal ivltests # $fatal fatal_et_al normal ivltests gold=fatal_et_al.gold fatal_et_al2 RE ivltests gold=fatal_et_al2.gold # $finish_and_return plus_arg_string normal,-g2009,\ +img=test_image.file ivltests # $fopena, $fopenr and $fopenw fileio normal ivltests gold=fileio.gold # $is_signed pr1494799 normal ivltests gold=pr1494799.gold pr2428890c normal ivltests # $ivl_darray_method$to_vec & $ivl_darray_method$from_vec sv_cast_darray normal,-g2005-sv ivltests # $ivl_to_unsigned br978 normal ivltests br_ml20150424 normal ivltests # $readmempath pr2509349a normal ivltests gold=pr2509349a.gold pr2509349b normal ivltests gold=pr2509349b.gold # $simparam simparam normal ivltests # $simtime blocking_repeat_ec normal ivltests ca_time_smtm normal ivltests gold=ca_time_smtm.gold nb_array_pv normal ivltests nb_ec_array normal ivltests nb_ec_array_pv normal ivltests nb_ec_array_pv2 normal ivltests nb_ec_pv normal ivltests nb_ec_pv2 normal ivltests nb_ec_real normal ivltests nb_ec_vector normal ivltests pr2486350 normal ivltests gold=pr2486350.gold pr534 normal ivltests gold=pr534.gold stime normal ivltests gold=stime.gold swrite normal ivltests gold=swrite.gold time6 normal ivltests time6b normal ivltests # Rewrote time6 to pass with XL time6c normal ivltests gold=time6c.gold # $sizeof concat1 normal ivltests # PR#327,372 concat2 normal ivltests # PR#282 constconcat1 normal ivltests constconcat2 normal ivltests rptconcat2 normal ivltests # Repeat concatenation operation. sdw_lvalconcat2 normal ivltests # bool type bool1 normal ivltests compare_bool_reg normal ivltests constfunc8 normal ivltests # Binary ~& and ~| operators binary_nand normal ivltests binary_nor normal ivltests # real modulus pr1528093 normal ivltests # wire real br_gh456 normal,-g2012 ivltests ca_64delay normal ivltests gold=ca_64delay.gold ca_time_real normal ivltests gold=ca_time_real.gold ca_var_delay normal ivltests cast_real_signed normal ivltests cast_real_unsigned normal ivltests delayed_sfunc normal,-gspecify ivltests gold=delayed_sfunc.gold module_port_shortreal normal,-g2005-sv ivltests # shortreal pr1861212c normal ivltests gold=pr1861212.gold pr1864110a normal ivltests gold=pr1864110a.gold pr1864110b normal ivltests gold=pr1864110b.gold pr1873372 normal ivltests gold=pr1873372.gold pr1880003 normal ivltests pr1898293 normal ivltests pr2123158 normal ivltests pr2453002b normal ivltests pr2456943 normal ivltests pr2715748 normal ivltests gold=pr2715748.gold pr2806474 normal ivltests pr2976242 normal ivltests pr2976242b normal ivltests pr2976242c CE ivltests gold=pr2976242c.gold real8 normal ivltests real_array normal ivltests real_array_nb normal ivltests real_concat_invalid1 CE ivltests real_mod_in_ca normal ivltests real_op_fail CE ivltests real_pulse_clean normal ivltests real_pwr_in_ca normal ivltests real_select_invalid CE ivltests real_wire_array normal ivltests real_wire_force_rel normal ivltests tern8 normal ivltests # Two-state wires br_gh99e normal,-g2009 ivltests pull371 normal,-g2012 ivltests sv-2val-nets normal,-g2009 ivltests # Left aligned formats pr2476430 normal ivltests # A % at the end of the format string is displayed a a % eofmt_percent normal ivltests gold=eofmt_percent.gold # Command line parameters br_gh377 normal,-Ptest.name= ivltests gold=br_gh377.gold cmdline_parm1 normal,-Pmain.foo=2 ivltests # Dumping array words array_dump normal ivltests diff=work/array_dump.vcd:gold/array_dump.vcd.gold:2 pr2859628 normal ivltests diff=work/pr2859628.vcd:gold/pr2859628.vcd.gold:2 # Icarus supports integer values larger than 32-bits big_int normal ivltests # PR#405 ca_pow_signed normal ivltests urand normal ivltests gold=urand.gold # Avoiding time-0 races race normal ivltests #------------------------------------------------------------------------------ # Icarus limitations #------------------------------------------------------------------------------ # Limited support for event expressions in automatic scopes automatic_error4 CE ivltests # These are not currently supported in Icarus # Also update the regress-fsv.list since it has these marked as normal array_lval_select3a CE ivltests br605a EF ivltests br605b EF ivltests br971 EF ivltests br1005 CE,-g2009 ivltests br1015b CE,-g2009 ivltests br_ml20150315b CE,-g2009 ivltests sv_deferred_assert1 CE,-g2009 ivltests gold=sv_deferred_assert1.gold sv_deferred_assert2 CE,-g2009 ivltests gold=sv_deferred_assert2.gold sv_deferred_assume1 CE,-g2009 ivltests gold=sv_deferred_assume1.gold sv_deferred_assume2 CE,-g2009 ivltests gold=sv_deferred_assume2.gold #------------------------------------------------------------------------------ # Icarus deviations #------------------------------------------------------------------------------ # Icarus still allows (implicit) declaration after use in some circumstances. pr1909940 normal ivltests pr1909940b normal ivltests # Icarus allows hierarchical references to unnamed generate blocks. # We should add a warning about this, as it's not strictly allowed. unnamed_generate_block normal ivltests gold=unnamed_generate_block.gold #------------------------------------------------------------------------------ # Implementation defined behaviour #------------------------------------------------------------------------------ # From IEEE 1364-2005 section 5.2.1: # NOTE 2 -- Bit-select or part-select indices that are outside of the declared # range may be flagged as a compile time error. br_gh497b CE ivltests gold=br_gh497b.gold br_gh497d CE ivltests gold=br_gh497d.gold br_gh497f CE ivltests gold=br_gh497f.gold iverilog-12_0/ivtest/regress-ivl2.list000066400000000000000000000102411435245347300201040ustar00rootroot00000000000000# This test list contains tests that give different results when iverilog # is run without the -gstrict-expr-width option or vvp is run without the # -compatible option. # # Copyright (c) 1999-2014 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # #------------------------------------------------------------------------------ # Differences when iverilog is run without -gstrict-expr-width #------------------------------------------------------------------------------ # The standard requires oversized unsized constant numbers to be truncated. # These tests are specifically testing that such numbers aren't truncated. pr903 normal ivltests pr1388974 normal ivltests # The standard doesn't support lossless expressions. br_gh13a normal ivltests gold=br_gh13a.gold param-width normal ivltests gold=param-width-ivl.gold #------------------------------------------------------------------------------ # Differences when vvp is run without -compatible #------------------------------------------------------------------------------ # Different output when real numbers are displayed without a format specifier. br_gh383d normal,-g2012 ivltests gold=br_gh383d-ivl.gold ca_time_real normal ivltests gold=ca_time_real-ivl.gold delayed_sfunc normal,-gspecify ivltests gold=delayed_sfunc-ivl.gold localparam_type normal ivltests gold=parameter_type-ivl.gold parameter_type normal ivltests gold=parameter_type-ivl.gold pr1701890 normal ivltests gold=pr1701890-ivl.gold pr1864110a normal ivltests gold=pr1864110a-ivl.gold pr1864110b normal ivltests gold=pr1864110b-ivl.gold pr1864115 normal ivltests gold=pr1864115-ivl.gold iverilog-12_0/ivtest/regress-msys2.list000077500000000000000000000054701435245347300203200ustar00rootroot00000000000000# This test list is used to override other test lists when running # on Windows using MSYS2. # # Copyright (c) 1999-2015 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # Warning about non-existent /tmp directory pr2509349a normal ivltests gold=pr2509349a-msys2.gold iverilog-12_0/ivtest/regress-sv.list000066400000000000000000001154411435245347300176700ustar00rootroot00000000000000# This test list contains tests that should work using any simulator that # supports SystemVerilog (1800-2012). # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # always4A CE,-g2005-sv ivltests always4B CE,-g2005-sv ivltests always_comb normal,-g2005-sv ivltests always_comb_fail CE,-g2005-sv ivltests always_comb_fail3 CE,-g2005-sv ivltests always_comb_fail4 CE,-g2005-sv ivltests always_comb_no_sens nornal,-g2005-sv ivltests gold=always_comb_no_sens.gold always_comb_rfunc nornal,-g2005-sv ivltests always_comb_trig normal,-g2005-sv ivltests always_comb_warn normal,-g2005-sv ivltests gold=always_comb_warn.gold always_ff normal,-g2005-sv ivltests always_ff_fail CE,-g2005-sv ivltests always_ff_fail2 CE,-g2005-sv ivltests always_ff_fail3 CE,-g2005-sv ivltests always_ff_fail4 CE,-g2005-sv ivltests always_ff_no_sens CE,-g2005-sv ivltests always_ff_warn normal,-g2005-sv ivltests gold=always_ff_warn.gold always_ff_warn_sens normal,-g2005-sv ivltests gold=always_ff_warn_sens.gold always_latch normal,-g2005-sv ivltests always_latch_fail CE,-g2005-sv ivltests always_latch_fail3 CE,-g2005-sv ivltests always_latch_fail4 CE,-g2005-sv ivltests always_latch_no_sens CE,-g2005-sv ivltests always_latch_trig normal,-g2005-sv ivltests always_latch_warn normal,-g2005-sv ivltests gold=always_latch_warn.gold array_size normal,-g2005-sv ivltests # test [size] arrays array_string normal,-g2009 ivltests array_unpacked_sysfunct normal,-g2005-sv ivltests array_packed normal,-g2005-sv ivltests assign_op_after_cmp1 normal,-g2009 ivltests assign_op_after_cmp2 normal,-g2009 ivltests assign_op_after_cmp3 normal,-g2009 ivltests assign_op_concat normal,-g2009 ivltests assign_op_oob normal,-g2009 ivltests assign_op_real_array normal,-g2009 ivltests assign_op_real_array_oob normal,-g2009 ivltests assign_op_type normal,-g2009 ivltests automatic_error14 CE,-g2005-sv ivltests automatic_error15 CE,-g2005-sv ivltests automatic_error16 CE,-g2005-sv ivltests automatic_error17 CE,-g2005-sv ivltests automatic_error18 CE,-g2005-sv ivltests bitp1 normal,-g2005-sv ivltests bits normal,-g2005-sv ivltests bits2 normal,-g2005-sv ivltests bits3 normal,-g2005-sv ivltests br884 normal,-g2009 ivltests br917a normal,-g2009 ivltests br917b normal,-g2009 ivltests br917c normal,-g2009 ivltests br917d normal,-g2009 ivltests br921 normal,-g2009 ivltests gold=br921.gold br932a normal,-g2009 ivltests br932b normal,-g2009 ivltests br936 normal,-g2009 ivltests br956 normal,-g2009 ivltests br959 normal,-g2009 ivltests br962 normal,-g2009 ivltests br963 normal,-g2009 ivltests br973 normal,-g2009 ivltests br974a normal,-g2009 ivltests br974b normal,-g2009 ivltests br974c normal,-g2009 ivltests br975 CE,-g2009 ivltests gold=br975.gold br979 normal,-g2009 ivltests br991b CE,-g2009 ivltests gold=br991b.gold br1003a normal,-g2009 ivltests gold=br1003a.gold br1003b normal,-g2009 ivltests gold=br1003b.gold br1003c normal,-g2009 ivltests gold=br1003c.gold br1003d normal,-g2009 ivltests gold=br1003d.gold br1004 normal,-g2009 ivltests br1005 normal,-g2009 ivltests gold=br1005.gold br1015b normal,-g2009 ivltests br1025 normal,-g2009 ivltests br1027b normal,-g2009 ivltests gold=br1027b.gold br1027d normal,-g2009 ivltests gold=br1027d.gold br1027f normal,-g2009 ivltests gold=br1027f.gold br_gh4 normal,-g2009 ivltests br_gh4a normal,-g2009 ivltests br_gh72a normal,-g2009 ivltests gold=br_gh72a.gold br_gh72b normal,-g2009 ivltests gold=br_gh72b.gold br_gh72b_fail CE,-g2009 ivltests gold=br_gh72b_fail.gold br_gh104a normal,-g2009 ivltests br_gh104b normal,-g2009 ivltests br_gh105a normal,-g2009 ivltests gold=br_gh105a.gold br_gh105b normal,-g2009 ivltests gold=br_gh105b.gold br_gh112a normal,-g2009 ivltests br_gh112b normal,-g2009 ivltests br_gh112c normal,-g2009 ivltests br_gh112d normal,-g2009 ivltests br_gh112e normal,-g2009 ivltests br_gh112f normal,-g2009 ivltests br_gh129 normal,-g2009 ivltests br_gh130a CE,-g2009 ivltests br_gh130b normal,-g2009 ivltests br_gh165 normal,-g2009 ivltests gold=br_gh165.gold br_gh164a normal,-g2009 ivltests br_gh164b normal,-g2009 ivltests br_gh164c normal,-g2009 ivltests br_gh164d normal,-g2009 ivltests br_gh164e normal,-g2009 ivltests br_gh167a normal,-g2009 ivltests br_gh167b normal,-g2009 ivltests br_gh177a normal,-g2009 ivltests br_gh177b normal,-g2009 ivltests br_gh194 normal,-g2009 ivltests br_gh219 normal,-g2009 ivltests br_gh220 normal,-g2009 ivltests br_gh224 normal,-g2009 ivltests br_gh226 normal,-g2009 ivltests br_gh231 normal,-g2009 ivltests br_gh243 normal,-g2009 ivltests br_gh265 CE,-g2009 ivltests gold=br_gh265.gold br_gh277b normal,-g2009 ivltests br_gh280 normal,-g2009 ivltests br_gh281 normal,-g2012 ivltests br_gh281b normal,-g2012 ivltests br_gh289a normal,-g2009 ivltests br_gh289b normal,-g2009 ivltests br_gh289c normal,-g2009 ivltests br_gh289d normal,-g2009 ivltests gold=br_gh289d.gold br_gh337 normal,-g2009 ivltests br_gh361 normal,-g2009 ivltests br_gh365 normal,-g2009 ivltests gold=br_gh365.gold br_gh366 normal,-g2009 ivltests gold=br_gh366.gold br_gh368 normal,-g2009 ivltests gold=br_gh368.gold br_gh374 normal,-g2009 ivltests gold=br_gh374.gold br_gh386a normal,-g2009 ivltests br_gh386b normal,-g2009 ivltests br_gh386c CE,-g2009 ivltests br_gh386d normal,-g2009 ivltests br_gh388 normal,-g2009 ivltests gold=br_gh388.gold br_gh391 normal,-g2009 ivltests gold=br_gh391.gold br_gh411 normal,-g2009 ivltests br_gh418 normal,-g2009 ivltests br_gh433 normal,-g2009 ivltests gold=br_gh433.gold br_gh437 normal,-g2009 ivltests br_gh440 CE,-g2009 ivltests gold=br_gh440.gold br_gh443 normal,-g2009 ivltests br_gh445 normal,-g2009 ivltests br_gh461 normal,-g2009 ivltests br_gh477 normal,-g2009 ivltests br_gh478 normal,-g2009 ivltests br_gh498 normal,-g2009 ivltests br_gh508a normal,-g2009 ivltests br_gh527 normal,-g2009 ivltests br_gh530 CO,-g2009 ivltests br_gh540 normal,-g2009 ivltests br_gh553 normal,-g2009 ivltests br_gh556 normal,-g2009 ivltests br_gh568 normal,-g2009 ivltests br_gh661a normal,-g2009 ivltests br_gh661b normal,-g2009 ivltests br_gh672 normal,-g2009 ivltests br_gh699 CE,-g2009 ivltests br_gh756 normal,-g2009 ivltests br_gh782a normal,-g2009 ivltests gold=br_gh782a.gold br_gh782b normal,-g2009 ivltests gold=br_gh782b.gold br_gh801 normal,-g2009 ivltests br_gh801b normal,-g2009 ivltests br_ml20171017 normal,-g2009 ivltests br_ml20180227 CE,-g2009 ivltests br_ml20180309a normal,-g2009 ivltests br_ml20180309b normal,-g2009 ivltests br_ml20181012a CE,-g2009 ivltests br_ml20181012b CE,-g2009 ivltests br_ml20181012c CE,-g2009 ivltests br_ml20181012d CE,-g2009 ivltests br_ml20191221 normal,-g2009 ivltests br_mw20200501 normal,-g2009 ivltests case_priority normal,-g2005-sv ivltests gold=case_priority.gold case_unique normal,-g2005-sv ivltests gold=case_unique.gold cast_real normal,-g2005-sv ivltests cfunc_assign_op_mixed normal,-g2009 ivltests cfunc_assign_op_pv normal,-g2009 ivltests cfunc_assign_op_real normal,-g2009 ivltests cfunc_assign_op_vec normal,-g2009 ivltests clkgen_bit normal,-g2009 ivltests clkgen_logic normal,-g2009 ivltests clkgen_net normal,-g2009 ivltests clkgen_reg normal,-g2009 ivltests disable_fork_cmd normal,-g2009 ivltests display_bug normal,-g2009 ivltests gold=display_bug.gold edge normal,-g2009 ivltests enum_base_atom2 normal,-g2005-sv ivltests enum_base_fail_array CE,-g2005-sv ivltests enum_base_fail_darray CE,-g2005-sv ivltests enum_base_fail_darray CE,-g2005-sv ivltests enum_base_fail_enum CE,-g2005-sv ivltests enum_base_fail_queue CE,-g2005-sv ivltests enum_base_fail_range1 CE,-g2005-sv ivltests enum_base_fail_range2 CE,-g2005-sv ivltests enum_base_fail_range3 CE,-g2005-sv ivltests enum_base_fail_real1 CE,-g2005-sv ivltests enum_base_fail_real2 CE,-g2005-sv ivltests enum_base_fail_string1 CE,-g2005-sv ivltests enum_base_fail_string2 CE,-g2005-sv ivltests enum_base_fail_struct CE,-g2005-sv ivltests enum_base_integer normal,-g2005-sv ivltests enum_base_none normal,-g2005-sv ivltests enum_base_range normal,-g2005-sv ivltests enum_base_scalar normal,-g2005-sv ivltests enum_base_time normal,-g2005-sv ivltests enum_base_typename1 normal,-g2005-sv ivltests enum_base_typename2 normal,-g2005-sv ivltests enum_compatibility1 normal,-g2005-sv ivltests enum_compatibility2 normal,-g2005-sv ivltests enum_compatibility3 normal,-g2005-sv ivltests enum_compatibility_fail CE,-g2005-sv ivltests enum_elem_ranges normal,-g2005-sv ivltests enum_dims_invalid CE,-g2005-sv ivltests enum_in_struct normal,-g2005-sv ivltests enum_in_class normal,-g2005-sv ivltests enum_in_class_name_coll CE,-g2005-sv ivltests enum_line_info CE,-g2005-sv ivltests gold=enum_line_info.gold enum_method_signed1 normal,-g2005-sv ivltests enum_method_signed2 normal,-g2005-sv ivltests enum_method_signed3 normal,-g2005-sv ivltests enum_method_signed4 normal,-g2005-sv ivltests enum_next normal,-g2005-sv ivltests enum_order normal,-g2005-sv ivltests enum_ports normal,-g2005-sv ivltests enum_test1 normal,-g2005-sv ivltests enum_test2 normal,-g2005-sv ivltests enum_test3 CE,-g2005-sv ivltests enum_test4 normal,-g2005-sv ivltests enum_test5 CE,-g2005-sv ivltests enum_test6 CE,-g2005-sv ivltests enum_test7 CE,-g2005-sv ivltests enum_test8 normal,-g2005-sv ivltests enum_value_expr normal,-g2005-sv ivltests enum_values normal,-g2005-sv ivltests escaped_macro_name normal,-g2009 ivltests gold=escaped_macro_name.gold extra_semicolon normal,-g2005-sv ivltests fileline normal,-g2009 ivltests gold=fileline.gold fileline2 normal,-g2009 ivltests gold=fileline2.gold final normal,-g2005-sv ivltests gold=final.gold final2 normal,-g2005-sv ivltests gold=final2.gold first_last_num normal,-g2005-sv ivltests fork_join_any normal,-g2009 ivltests fork_join_dis normal,-g2009 ivltests fork_join_none normal,-g2009 ivltests fr49 normal,-g2009 ivltests func_init_var1 normal,-g2009 ivltests func_init_var2 normal,-g2009 ivltests func_init_var3 normal,-g2009 ivltests func_void_in_expr_fail CE,-g2005-sv ivltests function10 CO,-g2005-sv ivltests function11 CE,-g2005-sv ivltests function12 normal,-g2005-sv ivltests gold=function12.gold genvar_inc_dec normal,-g2009 ivltests genvar_compressed normal,-g2009 ivltests generate_module CE,-g2005-sv ivltests generate_timeunit CE,-g2005-sv ivltests ibit_test normal,-g2005-sv ivltests ibyte_test normal,-g2005-sv ivltests iint_test normal,-g2005-sv ivltests ilongint_test normal,-g2005-sv ivltests implicit_cast1 normal,-g2009 ivltests implicit_cast2 normal,-g2009 ivltests implicit_cast3 normal,-g2009 ivltests implicit_cast4 normal,-g2009 ivltests implicit_cast5 normal,-g2009 ivltests implicit_cast6 normal,-g2009 ivltests implicit_cast7 normal,-g2009 ivltests implicit_cast8 normal,-g2009 ivltests implicit_cast9 normal,-g2009 ivltests implicit_cast10 normal,-g2009 ivltests implicit_cast11 normal,-g2009 ivltests implicit_cast12 normal,-g2009 ivltests implicit_cast13 normal,-g2009 ivltests implicit-port1 normal,-g2005-sv ivltests # SystemVerilog implicit port connections implicit-port2 CE,-g2005-sv ivltests implicit-port3 CE,-g2005-sv ivltests implicit-port4 normal,-g2005-sv ivltests implicit-port5 normal,-g2005-sv ivltests implicit-port6 CE,-g2005-sv ivltests implicit-port7 normal,-g2005-sv ivltests inc_dec_stmt normal,-g2009 ivltests int_param normal,-g2009 ivltests ishortint_test normal,-g2005-sv ivltests iuint1 normal,-g2005-sv ivltests l_impl normal,-g2005-sv ivltests l_equiv normal,-g2005-sv ivltests l_equiv_ca normal,-g2005-sv ivltests l_equiv_const normal,-g2005-sv ivltests line_directive normal,-g2009,-I./ivltests ivltests gold=line_directive.gold localparam_implicit normal,-g2005-sv ivltests localparam_implicit2 CE,-g2005-sv ivltests localparam_implicit3 CE,-g2005-sv ivltests localparam_query normal,-g2005-sv ivltests localparam_type2 normal,-g2009 ivltests logical_short_circuit normal,-g2012 ivltests logp2 normal,-g2005-sv ivltests mod_inst_pkg normal,-g2009 ivltests module_nonansi_atom2_fail CE,-g2005-sv ivltests module_nonansi_enum1 normal,-g2005-sv ivltests module_nonansi_enum2 normal,-g2005-sv ivltests module_nonansi_enum_fail CE,-g2005-sv ivltests module_nonansi_int1 normal,-g2005-sv ivltests module_nonansi_int2 normal,-g2005-sv ivltests module_nonansi_parray1 normal,-g2005-sv ivltests module_nonansi_parray2 normal,-g2005-sv ivltests module_nonansi_parray_fail CE,-g2005-sv ivltests module_nonansi_real1 normal,-g2005-sv ivltests module_nonansi_real2 normal,-g2005-sv ivltests module_nonansi_real_fail CE,-g2005-sv ivltests module_nonansi_struct1 normal,-g2005-sv ivltests module_nonansi_struct2 normal,-g2005-sv ivltests module_nonansi_struct_fail CE,-g2005-sv ivltests module_output_port_sv_var1 normal,-g2005-sv ivltests module_output_port_sv_var2 normal,-g2005-sv ivltests module_port_typedef_array1 normal,-g2005-sv ivltests module_port_typedef_vector normal,-g2005-sv ivltests named_begin normal,-g2009 ivltests named_begin_fail CE,-g2009 ivltests named_fork normal,-g2009 ivltests named_fork_fail CE,-g2009 ivltests net_class_fail CE,-g2005-sv ivltests net_darray_fail CE,-g2005-sv ivltests net_queue_fail CE,-g2005-sv ivltests net_string_fail CE,-g2005-sv ivltests package_vec_part_select normal,-g2005-sv ivltests packeda normal,-g2009 ivltests packeda2 normal,-g2009 ivltests parameter_in_generate2 CE,-g2005-sv ivltests parameter_no_default CE,-g2005-sv ivltests parameter_no_default_fail1 CE ivltests parameter_no_default_fail2 CE ivltests parameter_no_default_toplvl normal,-g2005-sv ivltests parameter_override_invalid7 CE,-g2005-sv ivltests parameter_override_invalid8 CE,-g2005-sv ivltests parameter_scalar normal,-g2005-sv ivltests parameter_type2 normal,-g2009 ivltests parpkg_test normal,-g2009 ivltests parpkg_test2 normal,-g2009 ivltests parpkg_test3 normal,-g2009 ivltests part_sel_port normal,-g2005-sv ivltests plus_5 normal,-g2009 ivltests pr3366114 normal,-g2009 ivltests pr3366217a CE,-g2005-sv ivltests gold=pr3366217a.gold pr3366217b CE,-g2005-sv ivltests gold=pr3366217b.gold pr3366217c CE,-g2005-sv ivltests gold=pr3366217c.gold pr3366217d CE,-g2005-sv ivltests gold=pr3366217d.gold pr3366217e normal,-g2005-sv ivltests pr3366217f normal,-g2005-sv ivltests gold=pr3366217f.gold pr3366217g CE,-g2005-sv ivltests unordered=pr3366217g.gold pr3366217h normal,-g2005-sv ivltests pr3366217i normal,-g2005-sv ivltests pr3390385 normal,-g2009 ivltests pr3390385b normal,-g2009 ivltests pr3390385c normal,-g2009 ivltests pr3390385d normal,-g2009 ivltests pr3462145 normal,-g2009 ivltests pr3515542 CE,-g2005-sv ivltests gold=pr3515542.gold pr3534333 normal,-g2005-sv ivltests pr3576165 normal,-g2009 ivltests program2 normal,-g2009 ivltests program2b normal,-g2009 ivltests program3 normal,-g2009 ivltests program3a normal,-g2009 ivltests program3b CE,-g2009 ivltests program4 normal,-g2009 ivltests program5a CE,-g2009 ivltests program5b CE,-g2009 ivltests program_hello normal,-g2009 ivltests program_hello2 CE,-g2009 ivltests pv_wr_vec2 normal,-g2005-sv ivltests pv_wr_vec2_nb normal,-g2005-sv ivltests pv_wr_vec2_nb_ec normal,-g2005-sv ivltests pv_wr_vec2a normal,-g2005-sv ivltests pv_wr_vec2a_nb normal,-g2005-sv ivltests pv_wr_vec2a_nb_ec normal,-g2005-sv ivltests recursive_func2 normal,-g2005-sv ivltests gold=recursive_func.gold recursive_func_const2 normal,-g2005-sv ivltests gold=recursive_func_const.gold sbyte_test normal,-g2005-sv ivltests scalar_vector normal,-g2005-sv ivltests sf_countbits normal,-g2012 ivltests sf_countbits_fail RE,-g2012 ivltests gold=sf_countbits_fail.gold sf_countones normal,-g2009 ivltests sf_countones_fail RE,-g2009 ivltests gold=sf_countones_fail.gold sf_isunknown normal,-g2005-sv ivltests sf_isunknown_fail RE,-g2005-sv ivltests gold=sf_isunknown_fail.gold sf_onehot normal,-g2005-sv ivltests sf_onehot_fail RE,-g2005-sv ivltests gold=sf_onehot_fail.gold sf_onehot0 normal,-g2005-sv ivltests sf_onehot0_fail RE,-g2005-sv ivltests gold=sf_onehot0_fail.gold sformatf normal,-g2009 ivltests simple_byte normal,-g2005-sv ivltests simple_int normal,-g2005-sv ivltests simple_longint normal,-g2005-sv ivltests simple_shortint normal,-g2005-sv ivltests sint_test normal,-g2005-sv ivltests size_cast normal,-g2009 ivltests size_cast2 normal,-g2005-sv ivltests size_cast3 normal,-g2009 ivltests size_cast4 normal,-g2009 ivltests size_cast5 normal,-g2009 ivltests slongint_test normal,-g2005-sv ivltests sshortint_test normal,-g2005-sv ivltests string_events normal,-g2009 ivltests gold=string_events.gold string_index normal,-g2005-sv ivltests struct1 normal,-g2009 ivltests struct2 normal,-g2009 ivltests struct3 normal,-g2009 ivltests struct3b normal,-g2009 ivltests struct4 normal,-g2009 ivltests struct5 normal,-g2009 ivltests struct6 normal,-g2009 ivltests struct7 normal,-g2009 ivltests struct8 normal,-g2009 ivltests struct9 normal,-g2009 ivltests struct10 normal,-g2009 ivltests struct_line_info CE,-g2009 ivltests gold=struct_line_info.gold struct_member_signed normal,-g2009 ivltests struct_packed_array normal,-g2009 ivltests struct_packed_array2 normal,-g2009 ivltests struct_packed_darray_fail CE,-g2009 ivltests struct_packed_queue_fail CE,-g2009 ivltests struct_packed_sysfunct normal,-g2009 ivltests struct_packed_sysfunct2 normal,-g2009 ivltests struct_packed_uarray_fail CE,-g2009 ivltests struct_packed_write_read2 normal,-g2009 ivltests struct_invalid_member CE,-g2009 ivltests gold=struct_invalid_member.gold struct_signed normal,-g2009 ivltests sv-constants normal,-g2005-sv ivltests sv_assign_pattern_cast normal,-g2005-sv ivltests sv_assign_pattern_const normal,-g2005-sv ivltests sv_assign_pattern_concat normal,-g2005-sv ivltests sv_assign_pattern_expand normal,-g2005-sv ivltests sv_assign_pattern_func normal,-g2005-sv ivltests sv_assign_pattern_op normal,-g2005-sv ivltests sv_assign_pattern_part normal,-g2005-sv ivltests sv_array_assign_pattern2 normal,-g2009 ivltests sv_array_cassign1 normal,-g2005-sv ivltests sv_array_cassign2 normal,-g2005-sv ivltests sv_array_cassign3 normal,-g2005-sv ivltests sv_array_cassign4 normal,-g2005-sv ivltests sv_array_cassign5 normal,-g2005-sv ivltests sv_array_cassign_fail1 CE,-g2005-sv ivltests sv_array_cassign_fail2 CE,-g2005-sv ivltests sv_array_cassign_fail3 CE,-g2005-sv ivltests sv_array_cassign_fail4 CE,-g2005-sv ivltests sv_array_cassign_fail5 CE,-g2005-sv ivltests sv_array_cassign_fail6 CE,-g2005-sv ivltests sv_array_cassign_fail7 CE,-g2005-sv ivltests sv_array_cassign_fail8 CE,-g2005-sv ivltests sv_array_cassign_fail9 CE,-g2005-sv ivltests sv_array_cassign_fail10 CE,-g2005-sv ivltests sv_array_cassign_fail11 CE,-g2005-sv ivltests sv_array_query normal,-g2005-sv ivltests sv_cast_integer normal,-g2005-sv ivltests sv_cast_integer2 normal,-g2005-sv ivltests sv_cast_packed_array normal,-g2005-sv ivltests sv_cast_packed_struct normal,-g2005-sv ivltests sv_cast_string normal,-g2005-sv ivltests sv_cast_typedef normal,-g2005-sv ivltests sv_class1 normal,-g2009 ivltests sv_class2 normal,-g2009 ivltests sv_class3 normal,-g2009 ivltests sv_class4 normal,-g2009 ivltests sv_class5 normal,-g2009 ivltests sv_class6 normal,-g2009 ivltests sv_class7 normal,-g2009 ivltests sv_class8 normal,-g2009 ivltests sv_class9 normal,-g2009 ivltests sv_class10 normal,-g2009 ivltests sv_class11 normal,-g2009 ivltests sv_class12 normal,-g2009 ivltests sv_class13 normal,-g2009 ivltests sv_class14 normal,-g2009 ivltests sv_class15 normal,-g2009 ivltests sv_class16 normal,-g2009 ivltests sv_class17 normal,-g2009 ivltests sv_class18 normal,-g2009 ivltests sv_class19 normal,-g2009 ivltests sv_class20 normal,-g2009 ivltests sv_class21 normal,-g2009 ivltests sv_class22 normal,-g2009 ivltests sv_class23 normal,-g2009 ivltests sv_class24 normal,-g2009 ivltests sv_class_compat1 normal,-g2009 ivltests sv_class_compat2 normal,-g2009 ivltests sv_class_compat_fail1 CE,-g2009 ivltests sv_class_compat_fail2 CE,-g2009 ivltests sv_class_compat_fail3 CE,-g2009 ivltests sv_class_constructor1 normal,-g2009 ivltests sv_class_constructor_fail CE,-g2009 ivltests sv_class_empty_item normal,-g2009 ivltests sv_class_extends_scoped normal,-g2009 ivltests sv_class_localparam normal,-g2009 ivltests sv_class_new_fail1 CE,-g2009 ivltests sv_class_new_fail2 CE,-g2009 ivltests sv_class_new_init normal,-g2009 ivltests sv_class_new_typed1 normal,-g2009 ivltests sv_class_new_typed2 normal,-g2009 ivltests sv_class_new_typed3 normal,-g2009 ivltests sv_class_new_typed_fail1 CE,-g2009 ivltests sv_class_new_typed_fail2 CE,-g2009 ivltests sv_class_new_typed_fail3 CE,-g2009 ivltests sv_class_new_typed_fail4 CE,-g2009 ivltests sv_class_in_module_decl normal,-g2009 ivltests sv_class_method_call_void normal,-g2009 ivltests sv_class_method_default1 normal,-g2009 ivltests sv_class_method_default2 normal,-g2009 ivltests sv_class_method_lt_static1 CE,-g2009 ivltests sv_class_method_lt_static2 CE,-g2009 ivltests sv_class_method_signed1 normal,-g2009 ivltests sv_class_method_signed2 normal,-g2009 ivltests sv_class_method_var_init normal,-g2009 ivltests sv_class_property_signed1 normal,-g2009 ivltests sv_class_property_signed2 normal,-g2009 ivltests sv_class_property_signed3 normal,-g2009 ivltests sv_class_property_signed4 normal,-g2009 ivltests sv_class_return normal,-g2009 ivltests sv_class_static_prop1 normal,-g2009 ivltests sv_class_static_prop2 normal,-g2009 ivltests sv_class_static_prop3 normal,-g2009 ivltests sv_class_super1 normal,-g2009 ivltests sv_class_super2 normal,-g2009 ivltests sv_class_super3 normal,-g2009 ivltests sv_class_super4 normal,-g2009 ivltests sv_class_super5 normal,-g2009 ivltests sv_class_super6 normal,-g2009 ivltests sv_class_task1 normal,-g2009 ivltests sv_class_virt_new_fail CE,-g2009 ivltests sv_darray1 normal,-g2009 ivltests sv_darray2 normal,-g2009 ivltests sv_darray3 normal,-g2009 ivltests sv_darray4 normal,-g2009 ivltests sv_darray5 normal,-g2009 ivltests sv_darray5b normal,-g2009 ivltests sv_darray6 normal,-g2009 ivltests sv_darray7 normal,-g2009 ivltests sv_darray_args1 normal,-g2009 ivltests sv_darray_args2 normal,-g2009 ivltests sv_darray_args2b normal,-g2009 ivltests sv_darray_args3 normal,-g2009 ivltests sv_darray_args4 normal,-g2009 ivltests sv_darray_assign1 normal,-g2009 ivltests sv_darray_assign2 normal,-g2009 ivltests sv_darray_assign_fail1 CE,-g2009 ivltests sv_darray_assign_fail2 CE,-g2009 ivltests sv_darray_assign_fail3 CE,-g2009 ivltests sv_darray_assign_fail4 CE,-g2009 ivltests sv_darray_assign_fail5 CE,-g2009 ivltests sv_darray_assign_fail6 CE,-g2009 ivltests sv_darray_copy_empty1 normal,-g2009 ivltests sv_darray_copy_empty2 normal,-g2009 ivltests sv_darray_copy_empty3 normal,-g2009 ivltests sv_darray_copy_empty4 normal,-g2009 ivltests sv_darray_decl_assign normal,-g2009 ivltests sv_darray_function normal,-g2009 ivltests sv_darray_oob_real normal,-g2009 ivltests sv_darray_oob_string normal,-g2009 ivltests sv_darray_oob_vec4 normal,-g2009 ivltests sv_darray_signed normal,-g2009 ivltests sv_darray_word_size normal,-g2005-sv ivltests sv_default_port_value1 normal,-g2009 ivltests sv_default_port_value2 normal,-g2009 ivltests sv_default_port_value3 CE,-g2009 ivltests gold=sv_default_port_value3.gold sv_deferred_assert1 normal,-g2009 ivltests gold=sv_deferred_assert1.gold sv_deferred_assert2 normal,-g2009 ivltests gold=sv_deferred_assert2.gold sv_deferred_assume1 normal,-g2009 ivltests gold=sv_deferred_assume1.gold sv_deferred_assume2 normal,-g2009 ivltests gold=sv_deferred_assume2.gold sv_end_label normal,-g2005-sv ivltests sv_end_label_fail CE,-g2009 ivltests gold=sv_end_label_fail.gold sv_end_labels normal,-g2009 ivltests sv_end_labels_bad CE,-g2009 ivltests gold=sv_end_labels_bad.gold sv_end_labels_unnamed CE,-g2009 ivltests gold=sv_end_labels_unnamed.gold sv_enum1 normal,-g2009 ivltests sv_for_variable normal,-g2009 ivltests sv_foreach1 normal,-g2009 ivltests sv_foreach2 normal,-g2009 ivltests sv_foreach3 normal,-g2009 ivltests sv_foreach4 normal,-g2009 ivltests sv_foreach5 normal,-g2009 ivltests sv_foreach6 normal,-g2009 ivltests sv_foreach7 normal,-g2009 ivltests sv_foreach8 normal,-g2009 ivltests gold=sv_foreach8.gold sv_foreach_fail1 CE,-g2009 ivltests sv_immediate_assert normal,-g2009 ivltests gold=sv_immediate_assert.gold sv_immediate_assume normal,-g2009 ivltests gold=sv_immediate_assume.gold sv_macro normal,-g2009 ivltests sv_macro2 normal,-g2009 ivltests gold=sv_macro2.gold sv_macro3a normal,-g2009 ivltests gold=sv_macro3.gold sv_macro3b normal,-g2009 ivltests gold=sv_macro3.gold sv_new_array_error CE,-g2009 ivltests gold=sv_new_array_error.gold sv_package normal,-g2009 ivltests sv_package2 normal,-g2009 ivltests sv_package3 normal,-g2009 ivltests sv_package4 normal,-g2009 ivltests sv_package5 normal,-g2009 ivltests sv_package_implicit_var1 CE,-g2009 ivltests sv_package_implicit_var2 CE,-g2009 ivltests sv_packed_port1 normal,-g2009 ivltests sv_packed_port2 normal,-g2009 ivltests sv_param_port_list normal,-g2009 ivltests sv_pkg_class normal,-g2009 ivltests gold=sv_pkg_class.gold sv_port_default1 normal,-g2009 ivltests sv_port_default2 normal,-g2009 ivltests sv_port_default3 normal,-g2009 ivltests sv_port_default4 normal,-g2009 ivltests sv_port_default5 normal,-g2009 ivltests sv_port_default6 normal,-g2009 ivltests sv_port_default7 normal,-g2009 ivltests sv_port_default8 normal,-g2009 ivltests sv_port_default9 normal,-g2009 ivltests sv_port_default10 normal,-g2009 ivltests sv_port_default11 normal,-g2009 ivltests sv_port_default12 normal,-g2009 ivltests sv_port_default13 CE,-g2009 ivltests sv_port_default14 CE,-g2009 ivltests sv_ps_function1 normal,-g2009 ivltests sv_ps_function2 normal,-g2009 ivltests sv_ps_function3 normal,-g2009 ivltests sv_ps_function4 normal,-g2009 ivltests sv_ps_type1 normal,-g2009 ivltests sv_ps_type_cast1 normal,-g2009 ivltests sv_ps_type_cast2 normal,-g2009 ivltests sv_ps_type_class1 normal,-g2009 ivltests sv_ps_type_class_prop normal,-g2009 ivltests sv_ps_type_enum1 normal,-g2009 ivltests sv_ps_type_expr1 normal,-g2009 ivltests sv_ps_type_expr2 normal,-g2009 ivltests sv_ps_type_struct1 normal,-g2009 ivltests sv_ps_var1 normal,-g2009 ivltests sv_queue1 normal,-g2009 ivltests sv_queue2 normal,-g2009 ivltests sv_queue3 normal,-g2009 ivltests sv_queue_assign1 normal,-g2009 ivltests sv_queue_assign2 normal,-g2009 ivltests sv_queue_assign_fail1 CE,-g2009 ivltests sv_queue_assign_fail2 CE,-g2009 ivltests sv_queue_assign_fail3 CE,-g2009 ivltests sv_queue_assign_fail4 CE,-g2009 ivltests sv_queue_assign_fail5 CE,-g2009 ivltests sv_queue_assign_fail6 CE,-g2009 ivltests sv_queue_copy_empty1 normal,-g2009 ivltests sv_queue_copy_empty2 normal,-g2009 ivltests sv_queue_function1 normal,-g2009 ivltests sv_queue_function2 normal,-g2009 ivltests sv_queue_oob_real normal,-g2009 ivltests sv_queue_oob_string normal,-g2009 ivltests sv_queue_oob_vec4 normal,-g2009 ivltests sv_queue_parray normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray.gold sv_queue_parray_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_parray_bounded.gold sv_queue_parray_fail CE,-g2009 ivltests gold=sv_queue_parray_fail.gold sv_queue_real normal,-g2009,-pfileline=1 ivltests gold=sv_queue_real.gold sv_queue_real_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_real_bounded.gold sv_queue_real_fail CE,-g2009 ivltests gold=sv_queue_real_fail.gold sv_queue_method_signed1 normal,-g2009 ivltests sv_queue_method_signed2 normal,-g2009 ivltests sv_queue_method_signed3 normal,-g2009 ivltests sv_queue_method_signed4 normal,-g2009 ivltests sv_queue_string normal,-g2009,-pfileline=1 ivltests gold=sv_queue_string.gold sv_queue_string_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_string_bounded.gold sv_queue_string_fail CE,-g2009 ivltests gold=sv_queue_string_fail.gold sv_queue_vec normal,-g2009,-pfileline=1 ivltests gold=sv_queue_vec.gold sv_queue_vec_bounded normal,-g2009,-pfileline=1 ivltests gold=sv_queue_vec_bounded.gold sv_queue_vec_fail CE,-g2009 ivltests gold=sv_queue_vec_fail.gold sv_root_class normal,-g2009 ivltests gold=sv_root_class.gold sv_root_func normal,-g2009 ivltests gold=sv_root_func.gold sv_root_task normal,-g2009 ivltests gold=sv_root_task.gold sv_sign_cast1 normal,-g2005-sv ivltests sv_sign_cast2 normal,-g2005-sv ivltests sv_sign_cast3 normal,-g2005-sv ivltests sv_string1 normal,-g2009 ivltests sv_string2 normal,-g2009 ivltests sv_string3 normal,-g2009 ivltests sv_string4 normal,-g2009 ivltests sv_string5 normal,-g2009 ivltests sv_string6 normal,-g2009 ivltests sv_string7 normal,-g2009 ivltests sv_string7b normal,-g2009 ivltests sv_timeunit_prec1 normal,-g2005-sv ivltests sv_timeunit_prec2 normal,-g2009 ivltests sv_timeunit_prec3a normal,-g2005-sv ivltests gold=sv_timeunit_prec3a.gold sv_timeunit_prec3b normal,-g2005-sv ivltests gold=sv_timeunit_prec3b.gold sv_timeunit_prec3c normal,-g2005-sv ivltests gold=sv_timeunit_prec3c.gold sv_timeunit_prec3d normal,-g2005-sv ivltests gold=sv_timeunit_prec3d.gold sv_timeunit_prec4a normal,-g2009 ivltests gold=sv_timeunit_prec4a.gold sv_timeunit_prec4b normal,-g2009 ivltests gold=sv_timeunit_prec4b.gold sv_timeunit_prec_fail1 CE,-g2005-sv,-u,\ ./ivltests/sv_timeunit_prec_fail1a.v,\ ./ivltests/sv_timeunit_prec_fail1b.v,\ ./ivltests/sv_timeunit_prec_fail1c.v,\ ./ivltests/sv_timeunit_prec_fail1d.v,\ ./ivltests/sv_timeunit_prec_fail1e.v, ivltests gold=sv_timeunit_prec_fail1.gold sv_timeunit_prec_fail2 CE,-g2009,-u,\ ./ivltests/sv_timeunit_prec_fail2a.v,\ ./ivltests/sv_timeunit_prec_fail2b.v,\ ./ivltests/sv_timeunit_prec_fail2c.v, ivltests gold=sv_timeunit_prec_fail2.gold sv_type_param1 normal,-g2005-sv ivltests sv_type_param2 normal,-g2005-sv ivltests sv_type_param3 normal,-g2005-sv ivltests sv_type_param4 normal,-g2005-sv ivltests sv_type_param5 normal,-g2005-sv ivltests sv_type_param6 normal,-g2005-sv ivltests sv_type_param7 normal,-g2005-sv ivltests sv_type_param_fail1 CE,-g2005-sv ivltests sv_type_param_fail2 CE,-g2005-sv ivltests sv_typedef_array_base1 normal,-g2009 ivltests sv_typedef_array_base2 normal,-g2009 ivltests sv_typedef_array_base3 normal,-g2009 ivltests sv_typedef_array_base4 normal,-g2009 ivltests sv_typedef_chained normal,-g2009 ivltests sv_typedef_circular1 CE,-g2009 ivltests sv_typedef_circular2 CE,-g2009 ivltests sv_typedef_darray_base1 normal,-g2009 ivltests sv_typedef_darray_base2 normal,-g2009 ivltests sv_typedef_darray_base3 normal,-g2009 ivltests sv_typedef_darray_base4 normal,-g2009 ivltests sv_typedef_fwd_base normal,-g2009 ivltests sv_typedef_fwd_class normal,-g2009 ivltests sv_typedef_fwd_class2 normal,-g2009 ivltests sv_typedef_fwd_union normal,-g2009 ivltests sv_typedef_fwd_union_fail CE,-g2009 ivltests sv_typedef_fwd_enum1 normal,-g2009 ivltests sv_typedef_fwd_enum2 normal,-g2009 ivltests sv_typedef_fwd_enum3 normal,-g2009 ivltests sv_typedef_fwd_enum_fail CE,-g2009 ivltests sv_typedef_fwd_struct normal,-g2009 ivltests sv_typedef_fwd_struct_fail CE,-g2009 ivltests sv_typedef_nested_array normal,-g2009 ivltests sv_typedef_queue_base1 normal,-g2009 ivltests sv_typedef_queue_base2 normal,-g2009 ivltests sv_typedef_queue_base3 normal,-g2009 ivltests sv_typedef_queue_base4 normal,-g2009 ivltests sv_typedef_scope1 normal,-g2009 ivltests sv_typedef_scope2 normal,-g2009 ivltests sv_typedef_scope3 normal,-g2009 ivltests sv_union1 normal,-g2009 ivltests sv_union1b normal,-g2009 ivltests sv_union2 normal,-g2009 ivltests sv_union2b normal,-g2009 ivltests sv_union3 normal,-g2009 ivltests sv_union3b normal,-g2009 ivltests sv_union4b normal,-g2009 ivltests sv_unit1b normal,-g2009,-DMACRO1=1,-DMACRO2=2,\ ./ivltests/sv_unit1a.v ivltests gold=sv_unit1b.gold sv_unit1c normal,-g2009,-DMACRO1=1,-DMACRO2=2,-u,\ ./ivltests/sv_unit1a.v ivltests gold=sv_unit1c.gold sv_unit2b normal,-g2009,-u,\ ./ivltests/sv_unit2a.v ivltests gold=sv_unit2b.gold sv_unit3b normal,-g2009,-u,\ ./ivltests/sv_unit3a.v ivltests gold=sv_unit3b.gold sv_unit4b normal,-g2009,-u,\ ./ivltests/sv_unit4a.v ivltests gold=sv_unit3b.gold sv_unpacked_port normal,-g2009 ivltests sv_unpacked_port2 normal,-g2009 ivltests sv_unpacked_wire normal,-g2009 ivltests sv_unpacked_wire2 normal,-g2009 ivltests sv_uwire1 normal,-g2009 ivltests sv_uwire2 normal,-g2009 ivltests sv_uwire3 normal,-g2009 ivltests sv_uwire4 normal,-g2009 ivltests sv_var_block normal,-g2005-sv ivltests sv_var_for normal,-g2005-sv ivltests sv_var_for_fail CE,-g2005-sv ivltests sv_var_function normal,-g2005-sv ivltests sv_var_init1 normal,-g2009 ivltests sv_var_init2 normal,-g2009 ivltests sv_var_module normal,-g2005-sv ivltests sv_var_module_inout1 CE,-g2005-sv ivltests sv_var_module_inout2 CE,-g2005-sv ivltests sv_var_module_input1 normal,-g2005-sv ivltests sv_var_module_input2 normal,-g2005-sv ivltests sv_var_module_output1 normal,-g2005-sv ivltests sv_var_module_output2 normal,-g2005-sv ivltests sv_var_package normal,-g2005-sv ivltests sv_var_task normal,-g2005-sv ivltests sv_void_cast1 normal,-g2005-sv ivltests sv_void_cast2 normal,-g2005-sv ivltests sv_void_cast3 normal,-g2005-sv ivltests sv_void_cast4 normal,-g2005-sv ivltests sv_void_cast_fail1 CE,-g2005-sv ivltests sv_void_cast_fail2 CE,-g2005-sv ivltests sv_void_cast_fail3 CE,-g2005-sv ivltests sv_wildcard_import1 normal,-g2009 ivltests sv_wildcard_import2 normal,-g2009 ivltests sv_wildcard_import3 normal,-g2009 ivltests sv_wildcard_import4 CE,-g2009 ivltests gold=sv_wildcard_import4.gold sv_wildcard_import5 CE,-g2009 ivltests unordered=sv_wildcard_import5.gold sv_wildcard_import6 normal,-g2009 ivltests sv_wildcard_import7 normal,-g2009 ivltests sys_func_as_task normal,-g2005-sv ivltests gold=sys_func_as_task.gold task_init_assign normal,-g2009 ivltests task_init_var1 normal,-g2009 ivltests task_init_var2 normal,-g2009 ivltests task_init_var3 normal,-g2009 ivltests task_nonansi_atom2_fail CE,-g2005-sv ivltests task_nonansi_enum1 normal,-g2005-sv ivltests task_nonansi_enum2 normal,-g2005-sv ivltests task_nonansi_enum_fail CE,-g2005-sv ivltests task_nonansi_int1 normal,-g2005-sv ivltests task_nonansi_int2 normal,-g2005-sv ivltests task_nonansi_parray1 normal,-g2005-sv ivltests task_nonansi_parray2 normal,-g2005-sv ivltests task_nonansi_parray_fail CE,-g2005-sv ivltests task_nonansi_struct1 normal,-g2005-sv ivltests task_nonansi_struct2 normal,-g2005-sv ivltests task_nonansi_struct_fail CE,-g2005-sv ivltests task_port_types1 normal,-g2009 ivltests task_port_types2 normal,-g2009 ivltests task_scope2 normal,-g2009 ivltests test_inc_dec normal,-g2009 ivltests test_tliteral normal,-g2009 ivltests timeliteral normal,-g2009 ivltests two_state_display normal,-g2005-sv ivltests gold=two_state_display.gold ubyte_test normal,-g2005-sv ivltests uint_test normal,-g2005-sv ivltests ulongint_test normal,-g2005-sv ivltests undef_lval_select_SV normal,-g2009 ivltests union_packed_darray_fail CE,-g2009 ivltests union_packed_queue_fail CE,-g2009 ivltests union_packed_uarray_fail CE,-g2009 ivltests unp_array_typedef normal,-g2005-sv ivltests packed_dims_invalid_class CE,-g2005-sv ivltests packed_dims_invalid_module CE,-g2005-sv ivltests ushortint_test normal,-g2005-sv ivltests vvp_recv_vec4_pv normal,-g2005-sv ivltests wait_fork normal,-g2009 ivltests sf1289 normal,-g2012 ivltests wild_cmp_const normal,-g2009 ivltests wild_cmp_net normal,-g2009 ivltests wild_cmp_var normal,-g2009 ivltests wild_cmp_err CE,-g2009 ivltests gold=wild_cmp_err.gold wild_cmp_err2 CE,-g2009 ivltests gold=wild_cmp_err2.gold gh161a normal,-g2012 ivltests gh161b normal,-g2012 ivltests pull371b normal,-g2012 ivltests br_gh175 normal,-g2012 ivltests br_gh307 normal,-g2012 ivltests br_gh383a normal,-g2012 ivltests gold=br_gh383a.gold br_gh383b normal,-g2012 ivltests gold=br_gh383b.gold br_gh383c normal,-g2012 ivltests gold=br_gh383c.gold br_gh383d normal,-g2012 ivltests gold=br_gh383d.gold br_gh390a CE,-g2012 ivltests br_gh390b normal,-g2012 ivltests gold=br_gh390b.gold br_gh412 normal,-g2012 ivltests br_gh414 normal,-g2012 ivltests br_gh436 normal,-g2012 ivltests gold=br_gh436.gold br_gh451 normal,-g2012,-Ptest.foo=4 ivltests gold=br_gh451.gold br_gh453 normal,-g2012 ivltests br_gh460 normal,-g2012 ivltests issue576 normal,-g2012 ivltests iverilog-12_0/ivtest/regress-synth.list000066400000000000000000000130421435245347300203770ustar00rootroot00000000000000# This test list contains tests that exercise the Icarus synthesis # functionality. The test framework automatically adds the -S option # for compiler versions that support synthesis. # # Copyright (c) 1999-2014 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # We no longer support the ivl_full_case attribute. This is a dangerous # thing to use, as it results in synthesis vs. simulation mismatches. #full_case normal ivltests #full_case2 normal ivltests basicexpr normal ivltests basicexpr2 normal ivltests basicexpr3 normal ivltests basicexpr4 normal ivltests basiclatch normal ivltests basicreg normal ivltests basicstate normal ivltests basicstate2 normal ivltests blocksynth1 normal ivltests blocksynth2 normal ivltests blocksynth3 normal ivltests br993a normal ivltests br993b normal ivltests br994 normal ivltests br995 CE ivltests br_gh99v normal ivltests br_gh99w normal ivltests br_gh99x normal ivltests br_gh115 normal ivltests br_gh306a CE ivltests br_gh306b CE ivltests case1 normal ivltests case2 normal ivltests case3 normal ivltests case4 normal ivltests case5 normal ivltests case5-syn-fail CE ivltests case6 normal ivltests case7 normal ivltests case_wo_default normal ivltests casesynth1 normal ivltests casesynth2 normal ivltests casesynth3 normal ivltests casesynth4 normal ivltests casesynth5 normal ivltests casesynth6 normal ivltests casesynth7 normal ivltests gold=casesynth7.gold casesynth8 CE ivltests casesynth9 normal ivltests casex_synth normal ivltests condit1 normal ivltests conditsynth1 normal ivltests conditsynth2 normal ivltests conditsynth3 normal ivltests dffsynth normal ivltests dffsynth2 normal ivltests dffsynth3 normal ivltests dffsynth4 normal ivltests dffsynth5 normal ivltests dffsynth6 normal ivltests dffsynth7 normal ivltests dffsynth8 CE ivltests dffsynth9 normal ivltests dffsynth10 normal ivltests dffsynth11 normal ivltests ff_dual_enable normal ivltests for_loop_synth normal ivltests for_loop_synth2 normal ivltests if_part_no_else normal ivltests if_part_no_else2 normal ivltests inside_synth normal ivltests inside_synth2 normal ivltests inside_synth3 normal ivltests land5 normal ivltests lcatsynth normal ivltests memsynth1 normal ivltests memsynth2 normal ivltests memsynth3 normal ivltests memsynth4 normal ivltests memsynth5 normal ivltests memsynth6 normal ivltests memsynth7 normal ivltests memsynth8 normal ivltests memsynth9 normal ivltests mix_reset normal ivltests multireg normal ivltests not_a_latch1 normal ivltests not_a_latch2 normal ivltests partselsynth normal ivltests pr519 normal ivltests pr685 normal ivltests shiftl normal ivltests sqrt32synth normal ivltests ssetclr1 normal ivltests ssetclr2 normal ivltests ssetclr3 normal ivltests synth_if_no_else normal ivltests ufuncsynth1 normal ivltests iverilog-12_0/ivtest/regress-v10.list000066400000000000000000000234001435245347300176370ustar00rootroot00000000000000# This test list is used to override other test lists when using # Icarus Verilog v10. # # Copyright (c) 1999-2015 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # Different error messages. br975 CE,-g2009 ivltests gold=br975-v10.gold pr1704726a CE ivltests gold=pr1704726a-v10.gold pr1704726c CE ivltests gold=pr1704726c-v10.gold pr1704726d CE ivltests gold=pr1704726d-v10.gold # The fix to give a sensible error message has not been backported. br_gh265 CE,-g2009 ivltests # The enhanced error message has not been backported. pr1698820 normal ivltests gold=pr1698820-v10.gold # Different warning messages. fdisplay_fail_fd normal ivltests gold=fdisplay_fail_fd-v10.gold fdisplay_fail_mcd normal ivltests gold=fdisplay_fail_mcd-v10.gold # The fix for type elaboration in the correct scope hasn't been backported. br_gh289a NI br_gh289b EF,-g2009 ivltests br_gh289c EF,-g2009 ivltests # The fix for class access to enclosing scopes hasn't been backported. br1003a normal,-g2009 ivltests gold=br1003a-v10.gold br_ml20191221 CE,-g2009 ivltests # The fix for void functions hasn't been backported. br_gh281 NI br_gh281b NI function10 NI function11 NI function12 NI # The fix for nested structs on the LHS of an assignment hasn't been backported. gh161a NI # The VVP runtime doesn't support return statements in automatic functions. # It's possible this could be fixed, but for now mark this as not implemented. # We can't mark it as EF, because it causes a runtime assertion failure. func_init_var2 NI # The fix for the assertion failure on an illegal SV cast causes enum_test1 to fail. # It's possible this could be fixed, but for now mark this as not implemented. # We can't mark it as CE, because it causes a compiler assertion failure. br_ml20180227 NI # The timescale parsing rework hasn't been backported to v10. # sv_timeunit_prec3b and sv_timeunit_prec4b fail at the compilation stage, # so are marked as NI to distinguish them from expected errors. resetall normal,-Wtimescale ivltests gold=resetall-v10.gold br1003b normal,-g2009 ivltests gold=br1003b-v10.gold br1003c normal,-g2009 ivltests gold=br1003c-v10.gold sv_timeunit_prec3b NI sv_timeunit_prec4b NI sv_timeunit_prec_fail1 CE,-g2005-sv,\ ./ivltests/sv_timeunit_prec_fail1a.v,\ ./ivltests/sv_timeunit_prec_fail1b.v,\ ./ivltests/sv_timeunit_prec_fail1c.v,\ ./ivltests/sv_timeunit_prec_fail1d.v,\ ./ivltests/sv_timeunit_prec_fail1e.v, ivltests gold=sv_timeunit_prec_fail1-v10.gold sv_timeunit_prec_fail2 CE,-g2009,\ ./ivltests/sv_timeunit_prec_fail2a.v,\ ./ivltests/sv_timeunit_prec_fail2b.v,\ ./ivltests/sv_timeunit_prec_fail2c.v, ivltests gold=sv_timeunit_prec_fail2-v10.gold # nor has the support for separate compilation units. sv_unit1c NI sv_unit2b NI sv_unit3b NI sv_unit4b NI # The macro redefinition warnings haven't been backported to v10 macro_redefinition NI macro_replacement NI # The fix for casting strings to vectors uses new VVP instructions, # so can't be backported. br_ml20180309a NI br_ml20180309b NI # The fix for uninitialised 2-state function return values uses new # VVP syntax, so can't be backported. br_gh337 NI # The fix for string values in event expressions hasn't been backported. br_gh365 NI string_events NI # The enhanced support for `` and `" hasn't been backported. br_gh366 EF ivltests gold=br_gh366.gold sv_macro3 EF ivltests gold=sv_macro3.gold # The fix for join_any inside a task hasn't been backported. br_gh368 NI # V10 does not support analog functionality analog1 NI analog2 NI # V10 does not support this VHDL functionality ivlh_textio NI test_when_else NI vhdl_concurrent_assert NI vhdl_delay_assign NI vhdl_elab_range NI vhdl_eval_cond NI vhdl_file_open NI vhdl_image_attr NI vhdl_lfcr NI vhdl_loop NI vhdl_multidim_array NI vhdl_now NI vhdl_pow_rem NI vhdl_process_scope NI vhdl_range NI vhdl_resize NI vhdl_shift NI vhdl_string NI vhdl_string_lim NI vhdl_subtypes NI vhdl_textio_write NI vhdl_textio_read NI vhdl_unary_minus NI vhdl_wait NI vhdl_while NI # V10 does not support this SystemVerilog functionality always_comb NI always_comb_fail NI always_comb_fail3 NI always_comb_fail4 NI always_comb_no_sens NI always_comb_rfunc NI always_comb_trig NI always_comb_warn NI always_ff NI always_ff_fail NI always_ff_fail2 NI always_ff_fail3 NI always_ff_fail4 NI always_ff_no_sens NI always_ff_warn NI always_ff_warn_sens NI always_latch NI always_latch_fail NI always_latch_fail3 NI always_latch_fail4 NI always_latch_no_sens NI always_latch_trig NI always_latch_warn NI br1004 NI br_gh226 CE,-g2009 ivltests br_gh177a NI br_gh177b NI br_gh277b NI case_priority NI case_unique NI genvar_inc_dec NI gh161b NI l_equiv NI l_equiv_ca NI l_equiv_const NI sf_countbits NI sf_countbits_fail NI sf_countones NI sf_countones_fail NI sf_isunknown NI sf_isunknown_fail NI sf_onehot NI sf_onehot_fail NI sf_onehot0 NI sf_onehot0_fail NI sformatf NI sv_darray_decl_assign NI sv_deferred_assert1 NI sv_deferred_assert2 NI sv_deferred_assume1 NI sv_deferred_assume2 NI sv_immediate_assert NI sv_immediate_assume NI sv_new_array_error NI sv_param_port_list NI sv_queue_real NI sv_queue_real_bounded NI sv_queue_real_fail NI sv_queue_string NI sv_queue_string_bounded NI sv_queue_string_fail NI sv_queue_vec NI sv_queue_vec_bounded NI sv_queue_vec_fail NI sv_wildcard_import1 NI sv_wildcard_import2 NI sv_wildcard_import3 NI sv_wildcard_import4 NI sv_wildcard_import5 NI sv_wildcard_import6 NI sv_wildcard_import7 NI vvp_recv_vec4_pv CE,-g2009 ivltests wild_cmp_const NI wild_cmp_err NI wild_cmp_err2 NI wild_cmp_net NI wild_cmp_var NI # and has non-standard support for this sv_cast_darray NI sv_cast_darray-v10 normal,-g2009 ivltests # V10 doesn't support rtran switches rtran NI rtranif0 NI rtranif1 NI # V10 doesn't support this by default br1000 normal,-gshared-loop-index ivltests # V10 does not support these SDF elements br_ml20190814 EF,-gspecify ivltests # V10 has incomplete synthesis support br993a CE,-S ivltests br993b CE,-S ivltests br_gh115 CE,-S ivltests basiclatch normal ivltests blocksynth2 normal ivltests blocksynth3 normal ivltests case1 normal ivltests case2 normal ivltests case4 normal ivltests case5 normal ivltests case5-syn-fail normal ivltests case6 normal ivltests casesynth1 normal ivltests casesynth2 normal ivltests casesynth3 normal ivltests casesynth7 NI casex_synth normal ivltests condit1 normal ivltests conditsynth1 normal ivltests conditsynth2 normal ivltests conditsynth3 normal ivltests dffsynth normal ivltests dffsynth3 normal ivltests dffsynth4 normal ivltests dffsynth9 normal ivltests dffsynth10 normal ivltests dffsynth11 normal ivltests inside_synth normal ivltests inside_synth3 normal ivltests memsynth1 normal ivltests memsynth2 normal ivltests memsynth3 normal ivltests memsynth5 normal ivltests memsynth6 normal ivltests memsynth7 normal ivltests memsynth9 normal ivltests mix_reset normal ivltests multireg normal ivltests sqrt32synth normal ivltests ssetclr3 normal ivltests iverilog-12_0/ivtest/regress-v11.list000066400000000000000000000131751435245347300176500ustar00rootroot00000000000000# This test list is used to override other test lists when using # Icarus Verilog v11. # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # v11 does not print a warning for too many parameter overrides param_test3 normal ivltests eofmt_percent normal ivltests gold=eofmt_percent-v11.gold # v11 does not fail during elaboration for these tests pr1916261a normal ivltests comment1 normal ivltests # v11 has not been updated to support this. line_directive EF,-I./ivltests ivltests gold=line_directive.gold program2b CE,-g2009 ivltests program3a CE,-g2009 ivltests sv_default_port_value1 CE,-g2009 ivltests sv_default_port_value2 CE,-g2009 ivltests sv_default_port_value3 CE,-g2009 ivltests # v11 does not check for as many issues as devel. br_gh440 CE,-g2009 ivltests gold=br_gh440-v11.gold # v11 has incomplete synthesis support dffsynth CE,-S ivltests memsynth1 CE,-S ivltests memsynth2 CE,-S ivltests memsynth3 CE,-S ivltests memsynth5 CE,-S ivltests memsynth6 CE,-S ivltests memsynth7 CE,-S ivltests memsynth9 CE,-S ivltests mix_reset CE,-S ivltests # These tests pass, but synthesis is creating unnecessary latches. case1 normal ivltests case2 normal ivltests casex_synth normal ivltests # For V11 vvp does not fail for these tests automatic_error11 normal ivltests gold=automatic_error11.gold automatic_error12 normal ivltests gold=automatic_error12.gold automatic_error13 normal ivltests gold=automatic_error13.gold br_gh230 normal ivltests gold=br_gh230.gold fdisplay3 normal ivltests gold=fdisplay3.gold fread-error normal ivltests gold=fread-error.gold pr2800985b normal ivltests gold=pr2800985b.gold queue_fail normal ivltests gold=queue_fail.gold readmem-invalid normal ivltests gold=readmem-invalid.gold scan-invalid normal ivltests gold=scan-invalid.gold warn_opt_sys_tf normal ivltests gold=warn_opt_sys_tf.gold writemem-invalid normal ivltests gold=writemem-invalid.gold sf_countbits_fail normal,-g2012 ivltests gold=sf_countbits_fail.gold sf_countones_fail normal,-g2009 ivltests gold=sf_countones_fail.gold sf_isunknown_fail normal,-g2009 ivltests gold=sf_isunknown_fail.gold sf_onehot_fail normal,-g2009 ivltests gold=sf_onehot_fail.gold sf_onehot0_fail normal,-g2009 ivltests gold=sf_onehot0_fail.gold # These tests are not implemented for v11 analog1 NI ivltests analog2 NI ivltests br605a NI ivltests br605b NI ivltests br971 NI ivltests br_gh72b_fail NI ivltests br_gh175 NI ivltests br_gh307 NI ivltests br_gh383a NI ivltests br_gh383b NI ivltests br_gh383c NI ivltests br_gh383d NI ivltests br_gh390a NI ivltests br_gh390b NI ivltests br_gh412 NI ivltests br_gh414 NI ivltests br_gh436 NI ivltests br_gh453 NI ivltests br_gh460 NI ivltests br_gh478 NI ivltests br_gh527 NI ivltests edge NI ivltests fileline2 NI ivltests ifdef_fail NI ivltests scalar_vector NI ivltests string12 NI ivltests sv_deferred_assert1 NI ivltests sv_deferred_assert2 NI ivltests sv_deferred_assume1 NI ivltests sv_deferred_assume2 NI ivltests timeliteral NI ivltests vhdl_multidim_array NI ivltests iverilog-12_0/ivtest/regress-v12.list000066400000000000000000000062061435245347300176460ustar00rootroot00000000000000# This test list is used to override other test lists when using # Icarus Verilog v12. # # Copyright (c) 1999-2015 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # v11 has incomplete synthesis support dffsynth CE,-S ivltests memsynth1 CE,-S ivltests memsynth2 CE,-S ivltests memsynth3 CE,-S ivltests memsynth5 CE,-S ivltests memsynth6 CE,-S ivltests memsynth7 CE,-S ivltests memsynth9 CE,-S ivltests mix_reset CE,-S ivltests # These tests pass, but synthesis is creating unnecessary latches. case1 normal ivltests case2 normal ivltests casex_synth normal ivltests iverilog-12_0/ivtest/regress-vams.list000066400000000000000000000071351435245347300202060ustar00rootroot00000000000000# This test list contains tests that should work using any simulator that # supports Verilog-AMS. # # Copyright (c) 1999-2014 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # #analog1 normal,-gverilog-ams ivltests #analog2 normal,-gverilog-ams ivltests analog1 NI ivltests analog2 NI ivltests br_gh99c normal,-gverilog-ams ivltests cast_int_ams normal,-gverilog-ams ivltests constfunc4_ams normal,-gverilog-ams ivltests scaled_real normal,-gverilog-ams ivltests test_vams_math normal,-gverilog-ams ivltests gold=test_vams_math.gold value_range1 normal,-gverilog-ams ivltests value_range2 normal,-gverilog-ams ivltests value_range3 CE,-gverilog-ams ivltests vams_abs1 normal,-gverilog-ams ivltests vams_abs2 normal,-gverilog-ams ivltests vams_abs3 normal,-gverilog-ams ivltests wreal normal,-gverilog-ams ivltests # Verilog functions added in a VAMS simulator constfunc6_ams normal ivltests non-polymorphic-abs normal ivltests pr3270320_ams CE ivltests test_va_math normal,-mva_math ivltests gold=test_va_math.gold va_math normal ivltests iverilog-12_0/ivtest/regress-vhdl.list000066400000000000000000000320641435245347300201740ustar00rootroot00000000000000# This test list contains tests that should work using any simulator that # supports standard VHDL. # # Copyright (c) 1999-2014 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # br942 normal,-g2005-sv,ivltests/br942.vhd ivltests br943_944 normal,-g2005-sv,ivltests/br943_944.vhd ivltests br985 normal,-g2005-sv,ivltests/br985.vhd ivltests br986 normal,-g2005-sv,ivltests/br986.vhd ivltests br987 normal,-g2005-sv,ivltests/br987.vhd ivltests ivlh_event normal,-mvhdl_sys ivltests gold=ivlh_event.gold ivlh_rising_falling normal,-mvhdl_sys ivltests gold=ivlh_rising_falling.gold ivlh_textio normal,-mvhdl_textio,-g2005-sv ivltests test_dec2to4 normal,-g2005-sv,ivltests/dec2to4.vhd ivltests test_enumsystem normal,-g2005-sv,ivltests/enumsystem.vhd ivltests test_forgen normal,-g2005-sv,ivltests/forgen.vhd ivltests test_gxor normal,-g2005-sv,ivltests/gxor.vhd ivltests test_mux2to1 normal,-g2005-sv,ivltests/mux2to1.vhd ivltests test_signal_init_assign normal,-g2005-sv,ivltests/signal_init_assign.vhd ivltests test_system normal,-g2005-sv,ivltests/system.vhd ivltests test_timebase normal,-g2005-sv,ivltests/timebase.vhd ivltests test_varray1 normal,-g2005-sv,ivltests/varray1.vhd ivltests test_when_else normal,-g2005-sv,ivltests/when_else.vhd ivltests test_work14 normal,-g2005-sv,ivltests/work14_pkg.vhd,ivltests/work14.vhd ivltests vhdl_and104_stdlogic normal,-g2005-sv,ivltests/vhdl_and104_stdlogic.vhd ivltests vhdl_and23_bit normal,-g2005-sv,ivltests/vhdl_and23_bit.vhd ivltests vhdl_and_gate normal,-g2005-sv,ivltests/vhdl_and_gate.vhd ivltests vhdl_andg_bit normal,-g2005-sv,ivltests/vhdl_andg_bit.vhd ivltests vhdl_andg_stdlogic normal,-g2005-sv,ivltests/vhdl_andg_stdlogic.vhd ivltests vhdl_array_of_array normal,-g2005-sv,ivltests/vhdl_array_of_array.vhd ivltests vhdl_case_multi normal,-g2005-sv,ivltests/vhdl_case_multi.vhd ivltests vhdl_boolean normal,-g2005-sv,ivltests/vhdl_boolean.vhd ivltests vhdl_concat normal,-g2005-sv,ivltests/vhdl_concat.vhd ivltests vhdl_concat_func normal,-g2005-sv,ivltests/vhdl_concat_func.vhd ivltests vhdl_concurrent_assert normal,-g2005-sv,ivltests/vhdl_concurrent_assert.vhd ivltests gold=vhdl_concurrent_assert.gold vhdl_const_package normal,-g2005-sv,ivltests/vhdl_const_package_pkg.vhd,ivltests/vhdl_const_package.vhd ivltests vhdl_const_record normal,-g2005-sv,ivltests/vhdl_const_record.vhd ivltests vhdl_const_array normal,-g2005-sv,ivltests/vhdl_const_array_pkg.vhd,ivltests/vhdl_const_array.vhd ivltests vhdl_delay_assign normal,-g2005-sv,-fivltests/vhdl_timescale_1ns.cfg,ivltests/vhdl_delay_assign.vhd ivltests vhdl_elab_range normal,-g2005-sv,ivltests/vhdl_elab_range.vhd ivltests vhdl_eval_cond normal,-g2005-sv,ivltests/vhdl_eval_cond.vhd ivltests vhdl_expr1 normal,-g2005-sv,ivltests/vhdl_expr1.vhd ivltests vhdl_generic_eval normal,-g2005-sv,ivltests/vhdl_generic_eval.vhd ivltests vhdl_fa4_test1 normal,-g2005-sv,ivltests/vhdl_fa4_test1.vhd ivltests vhdl_fa4_test2 normal,-g2005-sv,ivltests/vhdl_fa4_test2.vhd ivltests vhdl_fa4_test3 normal,-g2005-sv,ivltests/vhdl_fa4_test3.vhd ivltests vhdl_fa4_test4 normal,-g2005-sv,ivltests/vhdl_fa4_test4.vhd ivltests vhdl_file_open normal,-g2005-sv,ivltests/vhdl_file_open.vhd ivltests vhdl_generic_default normal,-g2005-sv,ivltests/vhdl_generic_default.vhd ivltests vhdl_init normal,-g2005-sv,ivltests/vhdl_init.vhd ivltests vhdl_image_attr normal,-g2005-sv,-fivltests/vhdl_timescale_1ns.cfg,ivltests/vhdl_image_attr.vhd ivltests gold=vhdl_image_attr.gold vhdl_inout normal,-g2005-sv,ivltests/vhdl_inout.vhd ivltests vhdl_labeled_assign normal,-g2005-sv,ivltests/vhdl_labeled_assign.vhd ivltests vhdl_lfcr normal,-g2005-sv,ivltests/vhdl_lfcr.vhd ivltests gold=vhdl_lfcr.gold vhdl_logic normal,-g2005-sv,ivltests/vhdl_logic.vhd ivltests vhdl_loop normal,-g2005-sv,ivltests/vhdl_loop.vhd ivltests #vhdl_multidim_array normal,-g2005-sv,ivltests/vhdl_multidim_array.vhd ivltests vhdl_multidim_array NI ivltests vhdl_nand104_stdlogic normal,-g2005-sv,ivltests/vhdl_nand104_stdlogic.vhd ivltests vhdl_nand23_bit normal,-g2005-sv,ivltests/vhdl_nand23_bit.vhd ivltests vhdl_nandg_bit normal,-g2005-sv,ivltests/vhdl_nandg_bit.vhd ivltests vhdl_nandg_stdlogic normal,-g2005-sv,ivltests/vhdl_nandg_stdlogic.vhd ivltests vhdl_nor104_stdlogic normal,-g2005-sv,ivltests/vhdl_nor104_stdlogic.vhd ivltests vhdl_nor23_bit normal,-g2005-sv,ivltests/vhdl_nor23_bit.vhd ivltests vhdl_norg_bit normal,-g2005-sv,ivltests/vhdl_norg_bit.vhd ivltests vhdl_norg_stdlogic normal,-g2005-sv,ivltests/vhdl_norg_stdlogic.vhd ivltests vhdl_not104_stdlogic normal,-g2005-sv,ivltests/vhdl_not104_stdlogic.vhd ivltests vhdl_not23_bit normal,-g2005-sv,ivltests/vhdl_not23_bit.vhd ivltests vhdl_notfunc_stdlogic normal,-g2005-sv,ivltests/vhdl_notfunc_stdlogic.vhd ivltests vhdl_notg_bit normal,-g2005-sv,ivltests/vhdl_notg_bit.vhd ivltests vhdl_notg_stdlogic normal,-g2005-sv,ivltests/vhdl_notg_stdlogic.vhd ivltests vhdl_now normal,-g2005-sv,ivltests/vhdl_now.vhd ivltests gold=vhdl_now.gold vhdl_or104_stdlogic normal,-g2005-sv,ivltests/vhdl_or104_stdlogic.vhd ivltests vhdl_or23_bit normal,-g2005-sv,ivltests/vhdl_or23_bit.vhd ivltests vhdl_org_bit normal,-g2005-sv,ivltests/vhdl_org_bit.vhd ivltests vhdl_org_stdlogic normal,-g2005-sv,ivltests/vhdl_org_stdlogic.vhd ivltests vhdl_pow_rem normal,-g2005-sv,ivltests/vhdl_pow_rem.vhd ivltests vhdl_prefix_array normal,-g2005-sv,ivltests/vhdl_prefix_array.vhd ivltests vhdl_procedure normal,-g2005-sv,ivltests/vhdl_procedure.vhd ivltests gold=vhdl_procedure.gold vhdl_process_scope normal,-g2005-sv,ivltests/vhdl_process_scope.vhd ivltests vhdl_rand23_bit normal,-g2005-sv,ivltests/vhdl_rand23_bit.vhd ivltests vhdl_range normal,-g2005-sv,ivltests/vhdl_range_pkg.vhd,ivltests/vhdl_range.vhd ivltests vhdl_range_func normal,-g2005-sv,ivltests/vhdl_range_func_pkg.vhd,ivltests/vhdl_range_func.vhd, ivltests vhdl_real normal,-g2005-sv,ivltests/vhdl_real.vhd ivltests vhdl_record_elab normal,-g2005-sv,ivltests/vhdl_record_elab_pkg.vhd,ivltests/vhdl_record_elab.vhd ivltests vhdl_reduce normal,-g2005-sv,ivltests/vhdl_reduce.vhd ivltests vhdl_report normal,-g2005-sv,ivltests/vhdl_report_pkg.vhd,ivltests/vhdl_report.vhd ivltests gold=vhdl_report.gold vhdl_resize normal,-g2005-sv,ivltests/vhdl_resize.vhd ivltests vhdl_rtoi normal,-g2005-sv,ivltests/vhdl_rtoi.vhd ivltests vhdl_sa1_test1 normal,-g2005-sv,ivltests/vhdl_sa1_test1.vhd ivltests vhdl_sa1_test2 normal,-g2005-sv,ivltests/vhdl_sa1_test2.vhd ivltests vhdl_sa1_test3 normal,-g2005-sv,-mvhdl_sys,ivltests/vhdl_sa1_test3.vhd ivltests vhdl_sadd23_bit normal,-g2005-sv,ivltests/vhdl_sadd23_bit.vhd ivltests vhdl_sadd23_stdlogic normal,-g2005-sv,ivltests/vhdl_sadd23_stdlogic.vhd ivltests vhdl_sdiv23_bit normal,-g2005-sv,ivltests/vhdl_sdiv23_bit.vhd ivltests vhdl_sdiv23_stdlogic normal,-g2005-sv,ivltests/vhdl_sdiv23_stdlogic.vhd ivltests vhdl_selected normal,-g2005-sv,ivltests/vhdl_selected.vhd ivltests vhdl_shift normal,-g2005-sv,ivltests/vhdl_shift.vhd ivltests vhdl_signals normal,-g2005-sv,ivltests/vhdl_signals.vhd ivltests vhdl_smul23_bit normal,-g2005-sv,ivltests/vhdl_smul23_bit.vhd ivltests vhdl_smul23_stdlogic normal,-g2005-sv,ivltests/vhdl_smul23_stdlogic.vhd ivltests vhdl_ssub23_bit normal,-g2005-sv,ivltests/vhdl_ssub23_bit.vhd ivltests vhdl_ssub23_stdlogic normal,-g2005-sv,ivltests/vhdl_ssub23_stdlogic.vhd ivltests vhdl_struct_array normal,-g2005-sv,ivltests/vhdl_struct_array.vhd ivltests vhdl_subtypes normal,-g2005-sv,ivltests/vhdl_subtypes_pkg.vhd,ivltests/vhdl_subtypes.vhd ivltests vhdl_subprogram normal,-g2005-sv,ivltests/vhdl_subprogram_pkg.vhd,ivltests/vhdl_subprogram.vhd ivltests vhdl_string normal,-g2005-sv,ivltests/vhdl_string.vhd ivltests gold=vhdl_string.gold vhdl_string_lim normal,-g2005-sv,ivltests/vhdl_string_lim.vhd ivltests vhdl_test1 normal,-g2005-sv,ivltests/vhdl_test1.vhd ivltests vhdl_test2 normal,-g2005-sv,ivltests/vhdl_test2.vhd ivltests vhdl_test3 normal,-g2005-sv,ivltests/vhdl_test3.vhd ivltests gold=vhdl_test3.gold vhdl_test4 normal,-g2005-sv,ivltests/vhdl_test4.vhd ivltests vhdl_test5 normal,-g2005-sv,ivltests/vhdl_test5.vhd ivltests vhdl_test6 normal,-g2005-sv,ivltests/vhdl_test6.vhd ivltests vhdl_test7 normal,-g2005-sv,ivltests/vhdl_test7.vhd ivltests vhdl_test8 normal,-g2005-sv,ivltests/vhdl_test8.vhd ivltests vhdl_test9 normal,-g2005-sv,ivltests/vhdl_test9.vhd ivltests # vhdl_textio_write creates the test data for vhdl_textio_read, so it has to be run first vhdl_textio_write normal,-g2005-sv,ivltests/vhdl_textio_write.vhd ivltests vhdl_textio_read normal,-g2005-sv,ivltests/vhdl_textio_read.vhd ivltests vhdl_time normal,-g2005-sv,-fivltests/vhdl_timescale_1ns.cfg,ivltests/vhdl_time_pkg.vhd,ivltests/vhdl_time.vhd ivltests gold=vhdl_time.gold vhdl_to_integer normal,-g2005-sv,ivltests/vhdl_to_integer.vhd ivltests vhdl_uadd23_bit normal,-g2005-sv,ivltests/vhdl_uadd23_bit.vhd ivltests vhdl_uadd23_stdlogic normal,-g2005-sv,ivltests/vhdl_uadd23_stdlogic.vhd ivltests vhdl_udiv23_bit normal,-g2005-sv,ivltests/vhdl_udiv23_bit.vhd ivltests vhdl_udiv23_stdlogic normal,-g2005-sv,ivltests/vhdl_udiv23_stdlogic.vhd ivltests vhdl_umul23_bit normal,-g2005-sv,ivltests/vhdl_umul23_bit.vhd ivltests vhdl_umul23_stdlogic normal,-g2005-sv,ivltests/vhdl_umul23_stdlogic.vhd ivltests vhdl_unary_minus normal,-g2005-sv,ivltests/vhdl_unary_minus.vhd ivltests vhdl_unbounded normal,-g2005-sv,ivltests/vhdl_unbounded.vhd ivltests vhdl_unbounded_func normal,-g2005-sv,ivltests/vhdl_unbounded_func_pkg.vhd,ivltests/vhdl_unbounded_func.vhd ivltests vhdl_usub23_bit normal,-g2005-sv,ivltests/vhdl_usub23_bit.vhd ivltests vhdl_usub23_stdlogic normal,-g2005-sv,ivltests/vhdl_usub23_stdlogic.vhd ivltests vhdl_var_init normal,-g2005-sv,ivltests/vhdl_var_init.vhd ivltests vhdl_wait normal,-g2005-sv,ivltests/vhdl_wait.vhd ivltests gold=vhdl_wait.gold vhdl_while normal,-g2005-sv,ivltests/vhdl_while.vhd ivltests vhdl_xnor104_stdlogic normal,-g2005-sv,ivltests/vhdl_xnor104_stdlogic.vhd ivltests vhdl_xnor104_stdlogic normal,-g2005-sv,ivltests/vhdl_xnor104_stdlogic.vhd ivltests vhdl_xnor23_bit normal,-g2005-sv,ivltests/vhdl_xnor23_bit.vhd ivltests vhdl_xnorg_bit normal,-g2005-sv,ivltests/vhdl_xnorg_bit.vhd ivltests vhdl_xnorg_stdlogic normal,-g2005-sv,ivltests/vhdl_xnorg_stdlogic.vhd ivltests vhdl_xor23_bit normal,-g2005-sv,ivltests/vhdl_xor23_bit.vhd ivltests vhdl_xorg_bit normal,-g2005-sv,ivltests/vhdl_xorg_bit.vhd ivltests vhdl_xorg_stdlogic normal,-g2005-sv,ivltests/vhdl_xorg_stdlogic.vhd ivltests work7 normal,-g2009,-fivltests/work7.cfg ivltests work7b normal,-g2009,-fivltests/work7b.cfg ivltests iverilog-12_0/ivtest/regress-vlg.list000066400000000000000000002074161435245347300200340ustar00rootroot00000000000000# This test list contains tests that should work using any simulator that # supports standard Verilog (1364-2005). # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # addsr normal ivltests # Finds problems with >> using different sizes addwide normal ivltests always3.1.1A CE ivltests always3.1.1B CE ivltests always3.1.1C normal ivltests always3.1.1D normal ivltests always3.1.1E normal ivltests always3.1.1F normal ivltests always3.1.1G normal ivltests always3.1.1H normal ivltests always3.1.1I normal ivltests always3.1.1J normal ivltests always3.1.1K normal ivltests always3.1.2A CE ivltests always3.1.2B CE ivltests always3.1.2C CE ivltests always3.1.2D CE ivltests always3.1.2E CE,-Ttyp ivltests always3.1.2F CE,-Ttyp ivltests always3.1.2G CE ivltests always3.1.2H CE ivltests always3.1.2I CE ivltests always3.1.3A CE ivltests always3.1.3B CE ivltests always3.1.3B2 normal ivltests always3.1.3C CE ivltests always3.1.3D CE ivltests always3.1.3D2 normal ivltests always3.1.3E CE ivltests always3.1.3E2 normal ivltests always3.1.3F CE ivltests always3.1.3F2 normal ivltests always3.1.3G CE ivltests always3.1.3H CE ivltests always3.1.3J CE ivltests always3.1.4A normal ivltests always3.1.4B normal ivltests always3.1.4C normal ivltests always3.1.4D normal ivltests always3.1.4E normal ivltests always3.1.4F normal ivltests always3.1.4G normal ivltests always3.1.4H normal ivltests always3.1.4I normal ivltests always3.1.5A normal ivltests always3.1.5B normal ivltests always3.1.5C normal ivltests always3.1.5D normal ivltests always3.1.5E normal ivltests always3.1.5F normal ivltests always3.1.6A normal ivltests always3.1.6B normal ivltests always3.1.6C normal ivltests always3.1.6D normal ivltests always3.1.7A normal ivltests always3.1.7B normal ivltests always3.1.7C normal ivltests always3.1.7D normal ivltests always3.1.8A normal ivltests always3.1.9A CE ivltests always3.1.9B CE ivltests always3.1.9C normal ivltests # always #1 disable taskname always3.1.9D normal ivltests # always #1 disable blockid always3.1.10A CE ivltests always3.1.11A normal ivltests always3.1.11B normal ivltests always3.1.12A normal ivltests # always fork join always3.1.12B normal ivltests # always fork: block_id join always3.1.12C normal ivltests always_star_array_lval normal ivltests gold=always_star_array_lval.gold andnot1 normal ivltests arith-unknown normal ivltests array4 normal ivltests array5 CE ivltests array6 normal ivltests array7 normal ivltests array_lval_select1 normal ivltests array_lval_select2 normal ivltests array_lval_select3b CE ivltests array_lval_select3c normal ivltests array_lval_select4a normal ivltests array_lval_select4b CE ivltests array_lval_select5 normal ivltests array_lval_select6 normal ivltests array_packed_2d normal ivltests gold=array_packed_2d.gold array_select normal ivltests array_select_a normal ivltests array_word_check normal ivltests gold=array_word_check.gold array_word_width normal ivltests gold=array_word_width.gold array_word_width2 normal ivltests assign3.2A normal ivltests assign3.2B normal ivltests assign3.2C normal ivltests assign3.2D normal ivltests assign3.2E normal ivltests assign_add normal ivltests assign_deassign_pv normal ivltests assign_delay normal ivltests # continuous assign with a delay assign_deq normal ivltests # continuous assign with == assign_ge normal ivltests # continuous assign with >= assign_le normal ivltests # continuous assign with <= assign_mem1 normal ivltests assign_mem2 normal ivltests # Const prop/dead signal elimination assign_nb1 normal ivltests # Assign a constant to a single bit array (pmonta) assign_nb2 normal ivltests # Assign a constant to a single bit array (pmonta) assign_neq normal ivltests # continuous assign with != attrib normal ivltests attrib01_module normal ivltests attrib02_port_decl normal ivltests attrib03_parameter normal ivltests attrib04_net_var normal ivltests attrib05_port_conn normal ivltests attrib06_operator_suffix normal ivltests attrib07_func_call normal ivltests attrib08_mod_inst normal ivltests attrib09_case normal ivltests attrib_expr normal ivltests automatic_error1 CE ivltests automatic_error2 CE ivltests automatic_error3 CE ivltests automatic_error5 CE ivltests automatic_error6 CE ivltests automatic_error7 CE ivltests automatic_error8 CE ivltests automatic_error9 CE ivltests automatic_error10 CE ivltests automatic_error11 RE ivltests gold=automatic_error11.gold automatic_error12 RE ivltests gold=automatic_error12.gold automatic_error13 RE ivltests gold=automatic_error13.gold automatic_events normal ivltests gold=automatic_events.gold automatic_events2 normal ivltests gold=automatic_events.gold automatic_events3 normal ivltests gold=automatic_events3.gold automatic_task normal ivltests gold=automatic_task.gold automatic_task2 normal ivltests gold=automatic_task2.gold automatic_task3 normal ivltests gold=automatic_task3.gold bitwidth normal ivltests bitwidth2 normal ivltests blankport normal ivltests main # PR 204 Stephan Boettcher - block_only_with_var_def normal ivltests bnot normal ivltests # test triggered an overzealous assert in vvm br605a normal ivltests br605b normal ivltests br916a normal ivltests gold=br916a.gold br916b normal ivltests gold=br916b.gold br918a normal ivltests br918b normal ivltests br918c normal ivltests br918d normal ivltests br919 normal ivltests br924 CE ivltests br930 CO ivltests br931 normal ivltests br935 normal ivltests br937 normal,+string=0123456789 ivltests br946 normal ivltests br947 normal ivltests gold=br947.gold br948 normal ivltests br955 normal ivltests br960a normal,-gspecify ivltests gold=br960a.gold br960b normal,-gspecify ivltests gold=br960b.gold br960c normal,-gspecify ivltests gold=br960c.gold br960d normal,-gspecify ivltests gold=br960d.gold br961 normal ivltests br961a CE ivltests br965 normal ivltests br967 normal ivltests br968 normal ivltests br971 normal ivltests br972 normal ivltests br977 normal ivltests br982 CE ivltests br982a CE ivltests br982b CE ivltests br988 normal ivltests br990 normal ivltests br991a normal ivltests br999 normal ivltests br1000 normal ivltests br1001 normal ivltests br1006 normal,-gspecify ivltests br1007 normal,-Wselect-range ivltests gold=br1007.gold br1008 normal ivltests gold=br1008.gold br1015a CE ivltests br1019 normal ivltests br1027 normal ivltests br1027a CE ivltests gold=br1027a.gold br1027c CE ivltests gold=br1027c.gold br1027e CE ivltests gold=br1027e.gold br1029a normal ivltests gold=br1029a.gold br1029b normal ivltests gold=br1029a.gold br1029c CE ivltests gold=br1029c.gold br_gh6 normal ivltests br_gh7 normal ivltests br_gh8 normal ivltests br_gh9 normal ivltests br_gh11 CO ivltests br_gh12 normal ivltests br_gh13 normal ivltests br_gh14 normal ivltests br_gh15 normal ivltests br_gh18 normal ivltests br_gh19 normal ivltests br_gh19a normal ivltests br_gh19b normal ivltests br_gh22 normal ivltests br_gh25a CE ivltests br_gh25b CE ivltests br_gh26 CE ivltests br_gh28 normal ivltests br_gh30 normal ivltests br_gh33 normal ivltests gold=br_gh33.gold br_gh37 normal ivltests br_gh60a CE ivltests br_gh62 CE ivltests gold=br_gh62.gold br_gh79 CE ivltests gold=br_gh79.gold br_gh99a normal ivltests br_gh99b normal ivltests br_gh99d normal ivltests br_gh99f normal ivltests br_gh99g normal ivltests br_gh99h normal ivltests br_gh99i normal ivltests br_gh99j normal ivltests br_gh99k normal ivltests br_gh99l normal ivltests br_gh99m normal ivltests br_gh99o normal ivltests br_gh99p normal ivltests br_gh99q normal ivltests br_gh99r normal ivltests br_gh99s normal ivltests br_gh99t normal ivltests br_gh99u normal ivltests br_gh103 normal ivltests br_gh127a normal ivltests gold=br_gh127a.gold br_gh127b normal ivltests gold=br_gh127b.gold br_gh127c normal ivltests gold=br_gh127c.gold br_gh127d normal ivltests gold=br_gh127d.gold br_gh127e normal ivltests gold=br_gh127e.gold br_gh127f normal ivltests gold=br_gh127f.gold br_gh142 CE ivltests br_gh152 CE ivltests br_gh156 normal ivltests diff=work/br_gh156.vcd:gold/br_gh156.vcd.gold:2 br_gh157 CE ivltests gold=br_gh157.gold br_gh162 normal ivltests br_gh163 CE ivltests br_gh198 normal ivltests gold=br_gh198.gold br_gh199a normal ivltests br_gh199b normal ivltests br_gh209 normal ivltests diff=work/br_gh209.dat:gold/br_gh209.dat br_gh230 RE ivltests gold=br_gh230.gold br_gh244a normal ivltests br_gh244b normal ivltests br_gh277a normal ivltests br_gh283a normal ivltests br_gh283b normal ivltests br_gh283c normal ivltests br_gh309 normal ivltests br_gh315 normal,-gspecify ivltests br_gh316a normal,-gspecify ivltests br_gh316b normal,-gspecify ivltests br_gh316c normal,-gspecify ivltests br_gh330 normal ivltests br_gh345 normal ivltests br_gh356a normal,-gspecify ivltests br_gh356b normal,-gspecify ivltests br_gh435 normal ivltests br_gh484 normal ivltests br_gh497a normal ivltests br_gh497c normal ivltests br_gh497e normal ivltests br_gh508b normal ivltests br_gh515 normal ivltests br_gh531 normal ivltests gold=br_gh531.gold br_gh533 CE ivltests br_gh567 normal,-g2001 ivltests gold=br_gh567.gold br_gh621 normal ivltests br_gh632 normal ivltests br_gh632b normal,-S ivltests br_gh632c normal ivltests br_gh674 normal ivltests br_gh732 normal ivltests gold=br_gh732.gold br_gh782c normal ivltests br_gh782d normal ivltests br_gh782e normal ivltests br_gh782f normal ivltests br_gh788 normal,-gno-io-range-error,-Wno-anachronisms ivltests gold=br_gh788.gold br_gh793 normal ivltests br_ml20150315 normal ivltests gold=br_ml_20150315.gold br_ml20150321 CE ivltests br_mw20171108 normal ivltests br_ml20190806a normal ivltests br_ml20190806b normal ivltests br_ml20190814 normal,-gspecify ivltests gold=br_ml20190814.gold bufif normal ivltests # Validate bufif0, bufif1 busbug normal ivltests gold=busbug.gold ca_force normal ivltests ca_func normal,-gstrict-ca-eval ivltests ca_mult normal ivltests gold=ca_mult.gold ca_pow_synth normal ivltests ca_pow_unsigned normal ivltests ca_real_logical normal ivltests ca_time normal ivltests gold=ca_time.gold case3.8A normal ivltests case3.8B normal ivltests case3.8C normal ivltests case3.8D normal ivltests # test case for x and z exact match in labels. casex3.9A normal ivltests casex3.9B normal ivltests casex3.9C normal ivltests casex3.9D normal ivltests casex3.9E normal ivltests casez3.10A normal ivltests casez3.10B normal ivltests casez3.10C normal ivltests casez3.10D normal ivltests casez3.10E normal ivltests # Use ? and z in label cast_int normal ivltests check_constant_1 CE ivltests check_constant_2 CE ivltests check_constant_3 CE,-g1995 ivltests check_constant_4 CE ivltests check_constant_5 CE ivltests check_constant_6 CE ivltests check_constant_7 CE ivltests check_constant_8 CE ivltests check_constant_9 CE ivltests check_constant_10 CE ivltests check_constant_11 CE ivltests check_constant_12 CE ivltests check_constant_13 CE ivltests check_constant_14 CE ivltests check_constant_15 CE ivltests check_constant_16 CE ivltests check_constant_17 CE ivltests check_constant_18 CE ivltests check_constant_19 CE ivltests check_constant_20 CE ivltests cmos normal ivltests gold=cmos.gold comment1 CE ivltests # PR410/411 comp1000 normal ivltests gold=comp1000.gold comp1001 normal ivltests gold=comp1001.gold comp1001_fail3 normal ivltests comp1001_fail4 normal ivltests comp1001_fail5 normal ivltests complex_lidx normal ivltests con_tri normal ivltests # Contrib by S Williams concat3 normal ivltests concat4 normal ivltests concat_zero_wid_fail CE ivltests concat_zero_wid_fail2 normal ivltests cond_band normal ivltests # Bitwise and in if condition cond_wide normal ivltests # condition is a wide value cond_wide2 normal ivltests # condition is a wide value const normal ivltests # PR 122 - Steve Tell - const without length spec. const2 normal ivltests # Some cases that the DCM module trips. const3 normal ivltests const4 normal ivltests constadd normal ivltests constadd2 normal ivltests constadd3 normal ivltests constfunc1 normal ivltests constfunc2 normal ivltests constfunc3 normal ivltests constfunc4 normal ivltests constfunc5 normal ivltests constfunc6 normal ivltests constfunc7 normal ivltests constfunc9 normal ivltests constfunc10 normal ivltests constfunc11 normal ivltests constfunc12 normal ivltests constfunc13 normal ivltests constfunc14 normal ivltests constfunc15 normal ivltests constmult normal ivltests consttern normal ivltests contrib8.1 normal ivltests contrib8.2 normal ivltests test # Add the 4th optional argument -s test contrib8.3 CE ivltests contrib8.4 normal ivltests contrib8.5 normal ivltests # Add the 4th optional argument -s test countdrivers1 normal ivltests countdrivers2 normal ivltests countdrivers3 normal ivltests countdrivers4 normal ivltests countdrivers5 normal ivltests cprop normal ivltests credence20041209 normal ivltests dangling_port normal ivltests # PR#209: dangling port optimization (VVP) dcomp1 normal ivltests gold=dcomp1.gold deassign3.4A normal ivltests decl_assign1 normal ivltests def_nettype normal ivltests def_nettype_none CE ivltests gold=def_nettype_none.gold define1 normal ivltests # Use defined value for reg def and reg assign defparam normal ivltests main # defparams with list defparam2 normal ivltests gold=defparam2.gold defparam3 normal ivltests gold=defparam3.gold defparam3.5 normal ivltests # defparam(single) defparam4 normal ivltests gold=defparam4.gold delay normal ivltests gold=delay.gold delay2 normal ivltests delay3 normal ivltests delay4 normal ivltests delay5 normal ivltests delay_assign_nb normal ivltests delay_assign_nb2 normal ivltests delay_var normal ivltests gold=delay_var.gold delayed_comp_reduct normal ivltests dff1 normal ivltests # Contrib by S Williams disable3.6A normal ivltests disable3.6B normal ivltests disable_cleanup normal ivltests disable_fork normal ivltests disblock normal ivltests # PR280 disblock2 normal ivltests gold=disblock2.gold disp_dec normal ivltests gold=disp_dec.gold disp_dec2 normal ivltests gold=disp_dec2.gold disp_leading_z normal ivltests gold=disp_leading_z.gold disp_parm normal ivltests gold=disp_parm.gold disp_part normal ivltests gold=disp_part.gold div16 normal contrib test_div16 # Uses $random and divide operator (Tom Coonan) dotinid normal ivltests # escaped names with . dots drive_strength normal ivltests # Contributed test drive_strength1 normal ivltests drive_strength2 normal ivltests gold=drive_strength2.gold drive_strength3 normal ivltests dummy7 normal ivltests gold=dummy7.gold dump_memword normal ivltests diff=work/test.vcd:gold/dump_memword.vcd:2 dumpvars normal ivltests # PR#174: dumpvars non-hierarchical arguments eeq normal ivltests # === and !== in structural context else1 normal ivltests # ifdef with else else2 normal ivltests # compound ifdef with else else3 normal ivltests # compound ifdef compound else elsif_test normal ivltests eq normal ivltests escape1 normal ivltests # \$modulename in defparam and if() escape2a CO ivltests escape2b CO ivltests escape2c CO ivltests escape3 normal ivltests escape4 normal ivltests escape4b normal ivltests event2 normal ivltests event3 normal ivltests gold=event3.gold event3.15 normal ivltests # Validate event lists, and -> operator. event_array CE ivltests event_list normal ivltests # Contrib by S Williams event_list2 normal ivltests # Contrib by S Williams event_list3 normal ivltests gold=event_list3.gold extend normal ivltests fdisplay1 normal ivltests gold=fdisplay1.gold fdisplay2 normal ivltests diff=work/fdisplay2.out:gold/fdisplay2.out fdisplay3 RE ivltests gold=fdisplay3.gold fdisplay_fail_fd normal ivltests gold=fdisplay_fail_fd.gold fdisplay_fail_mcd normal ivltests gold=fdisplay_fail_mcd.gold fifo normal contrib fopen1 normal ivltests # Test basic fopen operation fopen2 normal ivltests # Test basic fopen operation for3.16A normal ivltests force1 normal ivltests force2 normal ivltests force3.17A normal ivltests force3.17B normal ivltests force3.17C normal ivltests force_lval_part normal ivltests force_release_reg_pv normal ivltests force_release_wire8_pv normal ivltests force_release_wire_pv normal ivltests fork1 normal ivltests # Validate 3 way fork with simple assignments. fork3.19A normal ivltests fork3.19B normal ivltests format normal ivltests gold=format.gold fr47 normal ivltests fread normal ivltests fread-error RE ivltests gold=fread-error.gold fscanf_u normal ivltests fscanf_u_warn normal ivltests gold=fscanf_u_warn.gold fscanf_z normal ivltests fscanf_z_warn normal ivltests gold=fscanf_z_warn.gold function1 normal ivltests gold=function1.gold function2 normal ivltests function3 normal ivltests function3.11B normal ivltests function3.11C normal ivltests function3.11D normal ivltests function3.11F normal ivltests function4 CE ivltests # Functions must have at least one argument function5 CO ivltests # PR 184 function6 normal ivltests function7 normal ivltests function8 normal ivltests function9 normal ivltests function_exp normal ivltests # Contrib by S Williams ga_and normal ivltests ga_mod normal ivltests main ga_mod1 normal ivltests main ga_mod2 normal ivltests main ga_nand normal ivltests ga_nor normal ivltests ga_or normal ivltests ga_xnor normal ivltests ga_xor normal ivltests galan normal ivltests # Ternary test with varying size lhs vs rhs gate_connect1 normal ivltests gate_connect2 CE ivltests gold=gate_connect2.gold gen_case_opt1 normal ivltests gen_case_opt2 normal ivltests gen_case_opt3 normal ivltests gencrc normal contrib # 32/16 bit crc generate_case normal ivltests generate_case2 normal ivltests generate_case3 normal ivltests generate_multi_loop normal ivltests gold=generate_multi_loop.gold generate_specify CE,-g2005-sv ivltests generate_specparam CE,-g2005-sv ivltests genloop normal ivltests genvar_scopes normal ivltests hello1 normal ivltests hier_ref_error CE ivltests hierspace normal ivltests # whitespace.around .dots. in. hierarchical .names idiv1 normal ivltests # Contrib by S Williams idiv2 normal ivltests # Int div within an expression idiv3 normal ivltests gold=idiv3.gold ifdef1 normal ivltests # ifdef with no define ifdef2 normal ivltests # ifdef with define ifdef3 normal ivltests # compound ifdef with 1 define ifdef4 normal ivltests # compound ifdef with 2 defines ifdef_fail CE ivltests include1 normal ivltests # include file 1 level deep include2 normal ivltests # include file 2 levels deep include3 normal ivltests # include file 3 levels deep indef_width_concat CE ivltests gold=indef_width_concat.gold initmod normal ivltests gold=initmod.gold initmod2 normal ivltests gold=initmod2.gold inout normal ivltests # modname(a,a); inout a; inout2 normal ivltests inout3 normal ivltests inout4 normal ivltests int_not_signext normal ivltests gold=int_not_signext.gold integer1lt normal ivltests integer2le normal ivltests integer3gt normal ivltests integer4ge normal ivltests integer5 normal ivltests itor_rtoi normal ivltests gold=itor_rtoi.gold land2 normal ivltests land3 normal ivltests land4 normal ivltests gold=land4.gold landor1 normal ivltests ldelay1 normal ivltests ldelay2 normal ivltests ldelay3 normal ivltests ldelay4 normal ivltests ldelay5 normal ivltests lh_catadd normal ivltests lh_memcat normal ivltests gold=lh_memcat.gold lh_memcat2 normal ivltests lh_memcat3 normal ivltests lh_varindx normal ivltests lh_varindx2 normal ivltests lh_varindx4 normal ivltests lh_varindx5 normal ivltests localparam_type normal ivltests gold=parameter_type.gold long_div normal ivltests gold=long_div.gold macro2 normal ivltests macro_args CO,-yivltests ivltests macro_redefinition normal,-Wmacro-redefinition ivltests gold=macro_redefinition.gold macro_replacement normal,-Wmacro-replacement ivltests gold=macro_replacement.gold macsub normal ivltests mangle normal ivltests mangle_1 normal ivltests many_drivers normal ivltests # net with many drivers mcl2 normal ivltests gold=mcl2.gold mem1 normal ivltests gold=mem1.gold mem2port normal ivltests # memory ports with constant address memassign normal ivltests # PR 126 - daavid Leask - assign bus part fm memory item memidx normal ivltests # PR 221 memidxrng normal ivltests # PR 271 memory address range checks meminit normal ivltests meminit2 normal ivltests memport_bs normal ivltests # PR#303 memref normal ivltests mhead_task normal ivltests # Verify hierarchical task name in another mod. mixed_type_div_mod normal ivltests mixed_width_case normal ivltests modparam normal ivltests top # Override parameter via passed down value module3.12A normal ivltests main module3.12B normal ivltests module_inout_port_list_def CE ivltests # inout ports do not support default values module_inout_port_type CE ivltests module_input_port_list_def CE ivltests # input ports only support default values in SV module_input_port_type CE ivltests module_nonansi_fail1 CE ivltests module_nonansi_fail2 CE ivltests module_nonansi_fail3 CE ivltests module_nonansi_fail4 CE ivltests module_nonansi_fail5 CE ivltests module_nonansi_fail6 CE ivltests module_nonansi_fail7 CE ivltests module_nonansi_fail8 CE ivltests module_nonansi_fail9 CE ivltests module_nonansi_fail10 CE ivltests module_nonansi_fail11 CE ivltests module_nonansi_fail12 CE ivltests module_nonansi_fail13 CE ivltests module_nonansi_integer1 normal ivltests module_nonansi_integer2 normal ivltests module_nonansi_integer_fail CE ivltests module_nonansi_time1 normal ivltests module_nonansi_time2 normal ivltests module_nonansi_time_fail CE ivltests module_nonansi_vec1 normal ivltests module_nonansi_vec2 normal ivltests module_nonansi_vec_fail1 CE ivltests module_nonansi_vec_fail2 CE ivltests module_nonansi_vec_fail3 CE ivltests module_output_port_list_def normal ivltests module_output_port_var1 normal ivltests module_output_port_var2 normal ivltests module_port_range_mismatch CE ivltests modulus normal ivltests # wire % and reg % operators modulus2 normal ivltests # reg % operators monitor normal ivltests gold=monitor.gold monitor2 normal ivltests gold=monitor2.gold monitor3 normal ivltests gold=monitor3.gold mult1 normal ivltests # wire * and reg * operators mult16 normal contrib mul16 # Contributed by Tom Coonan - has $random mult2 normal ivltests # wire * and reg * operators multi_bit_strength normal ivltests gold=multi_bit_strength.gold multi_driver_delay normal ivltests multiply_large normal ivltests # Takes care of PR222 muxtest normal ivltests # Validates that X sel and inputs same, output not X named_event_no_edges CE ivltests nb_assign normal ivltests nb_delay normal ivltests nb_ec_concat normal ivltests nb_ec_multi_ev normal ivltests nblkorder normal ivltests # Validates Non-blocking order determinism negative_genvar normal ivltests negvalue normal ivltests gold=negvalue.gold neq1 normal ivltests gold=neq1.gold nested_func normal ivltests gold=nested_func.gold nested_impl_event1 normal ivltests gold=nested_impl_event1.gold nested_impl_event2 normal ivltests gold=nested_impl_event2.gold no_if_statement CE ivltests no_timescale_in_module CE ivltests npmos normal ivltests npmos2 normal ivltests onehot normal contrib # one hot design p_monta normal ivltests par_mismatch CE,-gspecify ivltests param-extend normal ivltests param-width normal ivltests gold=param-width.gold param_add normal ivltests # Addition in param declar param_and normal ivltests # bitwise & param_and2 normal ivltests # logical && in param declar param_band normal ivltests # Bitwise and in param declar param_binv normal ivltests # Bit vector inv in param declar param_bor normal ivltests # Bitwise OR in param declar param_concat normal ivltests # param has concat value (pmonta) param_eq3 normal ivltests # Bit equiv in param declar param_expr normal ivltests # & in param declar param_mod normal ivltests # Modulus in param declar param_select normal ivltests # bit and part select of parameters. param_select2 normal ivltests # bit and part select of parameters. param_select3 normal ivltests # bit and part select of parameters. param_string normal ivltests # parameter storing a string. param_tern normal ivltests param_tern2 normal ivltests param_test1 normal ivltests gold=param_test1.gold param_test2 normal ivltests gold=param_test2.gold param_test3 normal ivltests gold=param_test3.gold # PR#293 param_test4 normal ivltests param_times normal ivltests # param has multiplication. parameter_1bit normal ivltests parameter_type normal ivltests gold=parameter_type.gold parameter_in_generate1 CE ivltests parameter_no_default CE ivltests parameter_omit1 CE ivltests parameter_omit2 CE ivltests parameter_omit3 CE ivltests parameter_omit_invalid1 CE ivltests parameter_omit_invalid2 CE ivltests parameter_omit_invalid3 CE ivltests parameter_override_invalid1 CE ivltests parameter_override_invalid2 CE ivltests parameter_override_invalid3 CE ivltests parameter_override_invalid4 CE ivltests parameter_override_invalid5 CE ivltests parameter_override_invalid6 CE ivltests patch1268 normal ivltests pca1 normal ivltests # Procedural Continuous Assignment in a mux pic normal contrib pictest gold=pic.gold port-test2 normal ivltests # Port declaration syntax checks port-test3 CE ivltests # Port declaration syntax checks port-test4a CE ivltests # Port declaration input duplication checks (PR394) port-test4b CE ivltests # Port declaration output duplication checks (PR394) port-test5 normal ivltests # demonstrates 2001 module port syntax port-test6 normal ivltests # demonstrates 2001 module port syntax port-test7 normal ivltests # demonstrates 2001 module port syntax posedge normal ivltests # Contrib by S Williams pow-ca normal ivltests pow-const normal ivltests pow-proc normal ivltests pow_ca_signed normal ivltests pow_ca_unsigned normal ivltests pow_reg_signed normal ivltests pow_reg_unsigned normal ivltests pow_signed normal ivltests pow_unsigned normal ivltests pr136 normal ivltests # PR136 param foo_size 8 * 4 pr142 normal ivltests # Test for PR142 pr183 CO,-gno-specify ivltests pr224 normal ivltests # reg [3:0] ack; ... @(posedge ack) pr224a normal ivltests # reg [3:0] ack; ... @(posedge ack[p]) pr243 normal ivltests gold=pr243.gold pr245 normal ivltests gold=pr245.gold pr245_std normal ivltests gold=pr245.gold pr273 normal ivltests # Non-constant bit select in ordered list. pr298 normal ivltests gold=pr298.gold pr304 normal ivltests # test for PR304 pr307 normal ivltests # wide adds pr307a normal ivltests # wide adds pr312 normal ivltests pr338 CO ivltests # pr 338 - constant zz see also constadd2.v pr355 normal ivltests pr377 normal ivltests gold=pr377.gold pr434 normal ivltests gold=pr434.gold pr445 normal ivltests pr478 normal ivltests pr487 normal ivltests gold=pr487.gold pr492 normal ivltests gold=pr492.gold pr498b CE ivltests gold=pr498b.gold pr508 normal ivltests pr509 normal ivltests pr509b normal ivltests pr511 normal ivltests pr513 normal ivltests pr522 normal ivltests gold=pr522.gold pr524 normal ivltests gold=pr524.gold pr527 normal ivltests gold=pr527.gold pr528 normal ivltests gold=pr528.gold pr528b normal ivltests gold=pr528b.gold pr529 normal ivltests pr530a normal ivltests gold=pr530.gold pr530b normal ivltests gold=pr530.gold pr530c normal ivltests gold=pr530.gold pr531a normal ivltests gold=pr531a.gold pr531b normal ivltests gold=pr531a.gold pr532 normal ivltests gold=pr532.gold pr532b normal ivltests gold=pr532.gold pr533 normal ivltests gold=pr533.gold pr538 normal ivltests gold=pr538.gold pr540 normal ivltests gold=pr540.gold pr540b normal ivltests gold=pr540b.gold pr540c normal ivltests gold=pr540c.gold pr541 normal ivltests gold=pr541.gold pr542 normal ivltests gold=pr542.gold pr544 normal ivltests gold=pr544.gold pr547 normal ivltests gold=pr547.gold pr556 normal ivltests gold=pr556.gold pr564 normal ivltests pr569 normal ivltests gold=pr569.gold pr572 normal ivltests gold=pr572.gold pr572b normal ivltests gold=pr572.gold pr578 normal ivltests pr584 normal ivltests gold=pr584.gold pr585 normal ivltests pr587 normal ivltests pr590 normal ivltests gold=pr590.gold pr594 normal ivltests gold=pr594.gold pr596 normal ivltests gold=pr596.gold pr602 normal ivltests pr617 normal ivltests pr632 normal ivltests gold=pr632.gold pr673 normal ivltests gold=pr673.gold pr675 normal ivltests pr678 normal ivltests pr690 normal ivltests pr693 normal ivltests gold=pr693.gold pr699 normal ivltests pr699b normal ivltests pr704 normal ivltests # Uses ivltests/pr704.hex pr707 normal ivltests pr708 normal ivltests pr710 normal ivltests pr718 normal ivltests pr722 normal ivltests pr729 normal ivltests gold=pr729.gold pr734 normal ivltests pr735 normal ivltests pr748 normal ivltests pr751 normal,-Wsensitivity-entire-vector ivltests gold=pr751.gold pr757 normal ivltests pr772 normal ivltests pr810 normal ivltests pr812 normal ivltests gold=pr812.gold pr820 normal ivltests gold=pr820.gold pr823 normal ivltests pr841 normal ivltests pr842 normal ivltests pr848 normal ivltests pr856 normal ivltests pr859 normal ivltests pr860 normal ivltests pr872 normal ivltests pr902 normal ivltests gold=pr902.gold pr905 normal ivltests gold=pr905.gold pr910 normal ivltests gold=pr910.gold pr913 normal ivltests pr923 normal ivltests gold=pr923.gold pr938 normal ivltests gold=pr938.gold pr938b normal ivltests gold=pr938.gold pr938b_std normal ivltests gold=pr938.gold pr941 normal ivltests pr973 normal ivltests pr978 normal ivltests pr985 normal ivltests gold=pr985.gold pr987 normal ivltests gold=pr987.gold pr990 normal ivltests pr991 normal ivltests gold=pr991.gold pr993 normal ivltests gold=pr993.gold pr995 normal ivltests gold=pr995.gold pr1002 normal ivltests gold=pr1002.gold pr1002a normal ivltests gold=pr1002a.gold pr1007 normal ivltests pr1008 normal ivltests gold=pr1008.gold pr1022 normal ivltests pr1024 normal ivltests pr1026 normal ivltests gold=pr1026.gold pr1029 normal ivltests pr1032 normal ivltests pr1033 normal ivltests gold=pr1033.gold pr1065 normal ivltests gold=pr1065.gold pr1072 normal ivltests pr1077 normal,-g2 ivltests gold=pr1077.gold pr1087 normal ivltests pr1101 normal ivltests pr1115 normal ivltests pr1353345 normal ivltests pr1353345b normal ivltests pr1367855 normal ivltests pr1380261 normal ivltests pr1403406 normal ivltests gold=pr1403406.gold pr1403406a normal,-fivltests/pr1403406-1.cf ivltests gold=pr1403406a.gold pr1403406b normal,-fivltests/pr1403406-1.cf,-fivltests/pr1403406-2.cf ivltests gold=pr1403406b.gold pr1421777 normal ivltests pr1444055 normal ivltests pr1449749a normal ivltests pr1455873 normal ivltests pr1465769 normal ivltests pr1467825 CO,-gno-specify ivltests pr1474283 normal ivltests pr1474316 normal ivltests pr1474318 normal ivltests pr1476440 normal ivltests gold=pr1476440.gold pr1477190 normal ivltests pr1478121 normal ivltests pr1478988 normal ivltests pr1489568 normal ivltests pr1489570 normal ivltests pr1491355 normal ivltests pr1492075 normal ivltests gold=pr1492075.gold pr1508882 normal ivltests pr1510724 normal ivltests pr1515168 normal ivltests pr1520314 CO ivltests pr1522570 normal ivltests pr1530426 normal ivltests pr1561597 normal ivltests pr1565544 normal ivltests pr1565699b normal ivltests pr1570451 normal ivltests pr1570451b normal ivltests pr1570635 normal ivltests pr1570635b normal ivltests pr1574175 normal ivltests gold=pr1574175.gold pr1581580 normal ivltests pr1587634 CO,-Ttyp ivltests pr1587669 normal,-gspecify ivltests gold=pr1587669.gold pr1589497 normal ivltests gold=pr1589497.gold pr1598445 normal ivltests pr1601896 normal ivltests pr1601898 normal ivltests pr1603313 normal ivltests pr1603918 normal ivltests pr1612693 normal ivltests pr1623097 normal ivltests gold=pr1623097.gold pr1625912 normal ivltests pr1628288 normal ivltests gold=pr1628288.gold pr1628300 normal ivltests gold=pr1628300.gold pr1629683 normal ivltests gold=pr1629683.gold pr1632861 normal ivltests gold=pr1632861.gold pr1634526 normal ivltests gold=pr1634526.gold pr1636409 normal ivltests gold=pr1636409.gold pr1637208 normal ivltests pr1638985 normal ivltests gold=pr1638985.gold pr1639060 normal ivltests gold=pr1639060.gold pr1639064 normal ivltests gold=pr1639064.gold pr1639064b normal ivltests gold=pr1639064b.gold pr1639968 normal ivltests gold=pr1639968.gold pr1639971 normal ivltests gold=pr1639971.gold pr1645277 normal ivltests gold=pr1645277.gold pr1645518 normal ivltests gold=pr1645518.gold pr1648365 normal ivltests gold=pr1648365.gold pr1650842 normal ivltests pr1657307 normal ivltests pr1661640 normal ivltests gold=pr1661640.gold pr1662508 normal ivltests pr1664684 normal ivltests gold=pr1664684.gold pr1675789 normal ivltests pr1675789b normal ivltests pr1676071 normal ivltests pr1676836 normal ivltests pr1682887 normal ivltests pr1687193 normal ivltests gold=pr1687193.gold pr1688717 normal ivltests gold=pr1688717.gold pr1690058 normal ivltests pr1691599b normal ivltests pr1691709 normal ivltests pr1693890 normal ivltests pr1693921 normal ivltests pr1694413 normal ivltests pr1694427 normal ivltests pr1695257 CO ivltests pr1695309 normal ivltests pr1695322 normal ivltests pr1695334 normal ivltests pr1696137 normal ivltests pr1697250 normal ivltests pr1697732 normal ivltests pr1698499 normal ivltests gold=pr1698499.gold pr1698658 normal ivltests gold=pr1698658.gold pr1698659 normal ivltests gold=pr1698659.gold pr1698820 normal ivltests gold=pr1698820.gold pr1699444 normal ivltests gold=pr1699444.gold pr1699519 normal ivltests gold=pr1699519.gold pr1701855 normal ivltests gold=pr1701855.gold pr1701855b normal ivltests gold=pr1701855b.gold pr1701889 normal ivltests gold=pr1701889.gold pr1701890 normal ivltests gold=pr1701890.gold pr1701921 normal ivltests pr1702593 normal ivltests gold=pr1702593.gold pr1703120 normal ivltests gold=pr1703120.gold pr1703346 normal ivltests pr1703959 normal ivltests pr1704013 CE ivltests pr1704726a CE ivltests gold=pr1704726a.gold pr1704726b normal ivltests pr1704726c CE ivltests gold=pr1704726c.gold pr1704726d CE ivltests gold=pr1704726d.gold pr1705027 CO ivltests pr1716276 normal ivltests pr1717361 normal ivltests pr1719055 normal ivltests gold=pr1719055.gold pr1723367 normal,-gno-io-range-error ivltests gold=pr1723367.gold pr1735724 CE ivltests pr1735822 normal ivltests pr1735836 normal ivltests gold=pr1735836.gold pr1740476b normal ivltests pr1742910 normal ivltests pr1745005 normal ivltests pr1746401 normal ivltests pr1746848 normal ivltests gold=pr1746848.gold pr1752353 normal ivltests pr1752823a normal ivltests gold=pr1752823a.gold pr1752823b normal ivltests gold=pr1752823b.gold pr1755593 normal ivltests pr1755629 normal ivltests pr1758122 normal,-g2001-noconfig ivltests gold=pr1758122.gold pr1758135 normal ivltests gold=pr1758135.gold pr1763333 CE ivltests pr1770199 normal ivltests gold=pr1770199.gold pr1776485 normal ivltests pr1777103 normal ivltests pr1780480 normal ivltests gold=pr1780480.gold pr1784984 normal ivltests pr1787394a normal ivltests gold=pr1787394a.gold pr1787394b normal ivltests gold=pr1787394a.gold pr1787423 normal ivltests gold=pr1787423.gold pr1787423b normal ivltests pr1787423c normal ivltests pr1792108 normal ivltests gold=pr1792108.gold pr1792152 normal ivltests gold=pr1792152.gold pr1792734 normal ivltests gold=pr1792734.gold pr1793157 normal ivltests gold=pr1793157.gold pr1794362 normal ivltests pr1795005a normal ivltests gold=pr1795005a.gold pr1795005b normal ivltests gold=pr1795005b.gold pr1799904 normal ivltests gold=pr1799904.gold pr1804877 normal ivltests gold=pr1804877.gold pr1805837 normal ivltests gold=pr1805837.gold pr1812297 normal ivltests pr1819452 normal ivltests gold=pr1819452.gold pr1820472 normal ivltests gold=pr1820472.gold pr1822658 normal ivltests pr1823732 normal ivltests gold=pr1823732.gold pr1828642 normal ivltests gold=pr1828642.gold pr1830834 normal ivltests gold=pr1830834.gold pr1831724 normal ivltests gold=pr1831724.gold pr1832097a normal ivltests pr1832097b normal ivltests pr1833024 CE ivltests gold=pr1833024.gold pr1833754 CE ivltests pr1841300 normal,-gno-io-range-error ivltests gold=pr1841300.gold pr1845683 normal ivltests gold=pr1845683.gold pr1851310 normal ivltests gold=pr1851310.gold pr1855504 normal ivltests gold=pr1855504.gold pr1861212a normal ivltests gold=pr1861212.gold pr1862744a normal,-Winfloop ivltests pr1862744b CE,-Winfloop ivltests gold=pr1862744b.gold pr1866215 normal ivltests gold=pr1866215.gold pr1866215b normal ivltests gold=pr1866215b.gold pr1867161a normal ivltests gold=pr1867161a.gold pr1867161b normal ivltests gold=pr1867161b.gold pr1867332 CO ivltests pr1868792 normal ivltests pr1868991a normal ivltests pr1868991b CO ivltests pr1869769 normal ivltests pr1869772 normal ivltests pr1869781 normal ivltests pr1873146 normal ivltests pr1875866 normal ivltests pr1875866b normal ivltests pr1876798 normal ivltests gold=pr1876798.gold pr1877740 normal ivltests pr1877743 normal,-gspecify ivltests pr1878909 normal ivltests pr1879226 normal ivltests pr1883052 normal ivltests pr1883052b normal ivltests pr1885847 normal ivltests gold=pr1885847.gold pr1887168 normal ivltests gold=pr1887168.gold pr1892959 normal ivltests pr1892959b normal ivltests pr1898983 normal ivltests gold=pr1898983.gold pr1901125 normal ivltests pr1903157 CO ivltests pr1903324 normal ivltests pr1903343 normal ivltests gold=pr1903343.gold pr1903520 normal ivltests pr1907192 normal ivltests pr1912843 normal ivltests pr1913918a normal ivltests pr1913918b normal ivltests pr1913918c normal ivltests pr1913937 normal ivltests pr1916261 normal ivltests pr1916261a CE ivltests pr1921332 CO ivltests pr1924845 normal ivltests pr1925356 normal ivltests pr1925363a CE ivltests pr1925363b CE ivltests pr1932444 normal ivltests pr1934744 normal ivltests pr1936363 normal ivltests gold=pr1936363.gold pr1938138 CE ivltests pr1939165 normal ivltests pr1946411 normal ivltests pr1948110 normal ivltests pr1948342 normal ivltests pr1949025 normal ivltests gold=pr1949025.gold pr1950282 normal ivltests pr1956211 normal ivltests pr1958801 normal ivltests pr1960545 normal ivltests gold=pr1960545.gold pr1960548 normal ivltests gold=pr1960548.gold pr1960558 normal ivltests gold=pr1960558.gold pr1960575 normal ivltests gold=pr1960575.gold pr1960596 normal ivltests gold=pr1960596.gold pr1960619 normal,-gno-io-range-error ivltests gold=pr1960619.gold pr1960625 normal ivltests pr1960633 normal ivltests pr1963240 normal ivltests gold=pr1963240.gold pr1963960 normal ivltests pr1963962 normal ivltests gold=pr1963962.gold pr1971662a CE ivltests pr1971662b CE ivltests pr1978358 normal ivltests pr1978358b normal ivltests pr1978358c normal ivltests pr1978358d normal ivltests pr1983762 normal ivltests pr1985582 normal ivltests gold=pr1985582.gold pr1988302 normal ivltests pr1988302b CE ivltests pr1988310 normal ivltests pr1990029 normal ivltests pr1990164 normal ivltests pr1990269 normal ivltests pr1992244 normal ivltests pr1992729 normal ivltests pr1993479 normal ivltests gold=pr1993479.gold pr2001162 normal,-gno-io-range-error ivltests gold=pr2001162.gold pr2011429 normal ivltests pr2013758 normal ivltests pr2014673 normal ivltests pr2015466 normal ivltests pr2018235a normal ivltests pr2018235b normal ivltests pr2018305 normal ivltests pr2019553 normal ivltests pr2029336 normal ivltests diff=work/pr2029336.out:gold/pr2029336.gold pr2030767 normal ivltests pr2036953 normal ivltests pr2038048 normal ivltests pr2039632 CE ivltests pr2039694 normal ivltests gold=pr2039694.gold pr2043324 normal ivltests pr2043585 normal,-Wsensitivity-entire-array ivltests gold=pr2043585.gold pr2051694 CE ivltests pr2051975 CE ivltests pr2053944 normal ivltests gold=pr2053944.gold pr2076363 normal ivltests pr2076391 normal ivltests gold=pr2076391.gold pr2076425 normal ivltests pr2085984 normal ivltests pr2091455 normal ivltests gold=pr2091455.gold pr2109179 normal ivltests pr2117473 normal ivltests pr2117488 normal ivltests pr2119622 normal ivltests gold=pr2119622.gold pr2121536 normal ivltests pr2121536b normal ivltests pr2123190 normal ivltests pr2132552 normal ivltests gold=pr2132552.gold pr2136787 normal ivltests gold=pr2136787.gold pr2138682 normal ivltests gold=pr2138682.gold pr2138979 normal ivltests pr2138979b normal ivltests gold=pr2138979b.gold pr2138979c normal ivltests gold=pr2138979c.gold pr2138979d normal ivltests gold=pr2138979d.gold pr2139593 normal ivltests pr2146620 normal ivltests gold=pr2146620.gold pr2146620b normal ivltests gold=pr2146620b.gold pr2146620c normal ivltests pr2146824 normal ivltests gold=pr2146824.gold pr2148401 normal ivltests pr2152011 normal ivltests gold=pr2152011.gold pr2159630 normal ivltests gold=pr2159630.gold pr2166188 normal ivltests pr2166311 normal ivltests pr2169870 normal ivltests gold=pr2169870.gold pr2172606 normal ivltests pr2172606b normal ivltests pr2181249 normal ivltests pr2190323 normal ivltests pr2201909 normal ivltests pr2201909b normal ivltests pr2202706 normal,+option=0123456789abcdef ivltests pr2202706b normal,+option ivltests pr2202706c normal,+hex=123456789abcdef_x_z,+oct=1234567_x_z,+bin=101_x_z,+dec=123456789_,+dec_x=x,+dec_z=z_,+neg=-1_00,+real=12.3456789,+neg_real=-23.456e+3,+real_inf=Inf,+bad_num=not_a_num,+warn_real=9.825units ivltests pr2202846a normal ivltests pr2202846b normal ivltests pr2202846c normal ivltests pr2208681 normal ivltests pr2215342 normal,-grelative-include ivltests pr2219441 normal ivltests pr2219441b normal ivltests pr2224845 normal ivltests pr2224949 normal ivltests pr2233180 normal ivltests pr2233180b normal ivltests pr2233180c normal ivltests pr2233192 normal ivltests pr2233192b normal ivltests pr2233192c normal ivltests pr2248925 normal ivltests gold=pr2248925.gold pr2251119 normal ivltests gold=pr2251119.gold pr2257003 normal ivltests pr2257003b normal ivltests pr2270035 normal ivltests pr2276163 normal ivltests pr2281479 normal ivltests pr2305307 normal ivltests pr2305307b normal ivltests pr2305307c normal ivltests pr2306259 normal ivltests pr2350934 normal ivltests pr2350934b normal ivltests pr2350988 normal ivltests pr2352834 normal ivltests pr2355304 normal ivltests pr2355304b normal ivltests pr2358264 normal ivltests pr2358848 normal ivltests pr2395378a CE ivltests pr2395378b CE ivltests pr2395378c CE ivltests pr2395835 normal ivltests pr2425055a normal ivltests pr2425055b normal ivltests pr2425055c normal ivltests pr2428890 normal ivltests pr2428890b normal ivltests pr2434688 normal ivltests pr2434688b normal ivltests pr2450244 normal ivltests pr2453002 normal ivltests pr2459681 normal ivltests pr2470181a normal ivltests pr2470181b normal ivltests pr2503208 normal ivltests pr2528915 CE ivltests pr2533175 normal ivltests pr2579479 normal ivltests pr2580730 normal ivltests gold=pr2580730.gold pr2593733 normal ivltests pr2597278 normal ivltests pr2597278b CE ivltests pr2605006 normal ivltests pr2673846 normal ivltests pr2688910 normal ivltests pr2709097 normal ivltests pr2715547 normal ivltests pr2715558 normal ivltests gold=pr2715558.gold pr2715558b normal ivltests gold=pr2715558b.gold pr2721213 normal ivltests pr2722330a normal ivltests pr2722330b normal ivltests pr2722339a normal ivltests pr2722339b normal ivltests pr2723712 normal ivltests pr2725700a normal ivltests pr2725700b normal ivltests pr2725700c normal ivltests pr2728032 normal ivltests pr2728547 normal ivltests pr2728812a normal ivltests pr2728812b CE,-pRECURSIVE_MOD_LIMIT=5 ivltests pr2728812c CE ivltests pr2745281 normal ivltests pr2781595 normal ivltests pr2785294 normal ivltests gold=pr2785294.gold pr2788686 normal ivltests pr2790236 normal ivltests pr2792883 CE ivltests pr2792897 normal ivltests pr2792897 normal ivltests pr2794144 CE ivltests gold=pr2794144.gold pr2800985a normal ivltests pr2800985b RE ivltests gold=pr2800985b.gold pr2801134 normal ivltests pr2801662 normal ivltests pr2809288 CE ivltests gold=pr2809288.gold pr2815398a normal ivltests gold=pr2815398a.gold pr2815398a_std normal ivltests pr2815398b normal ivltests gold=pr2815398b.gold pr2818823 normal ivltests pr2823414 CE ivltests gold=pr2823414.gold pr2823711 normal ivltests pr2824189 normal ivltests pr2829776 normal ivltests pr2829776b normal,-gspecify ivltests pr2832234 normal ivltests pr2834340 normal ivltests pr2834340b normal ivltests pr2835632a normal ivltests pr2835632b normal ivltests pr2837451 normal ivltests pr2842185 normal ivltests pr2842621 normal ivltests gold=pr2842621.gold pr2842621_std normal ivltests pr2848986 CE ivltests gold=pr2848986.gold pr2849783 normal ivltests pr2849783 normal ivltests pr2865563 normal ivltests pr2877564 CE ivltests gold=pr2877564.gold pr2883958 normal ivltests pr2885048 normal ivltests pr2890322 normal ivltests pr2901556 normal ivltests pr2909386a normal ivltests pr2909386b normal ivltests pr2909414 normal ivltests pr2909555 normal ivltests pr2913404 normal ivltests pr2913416 normal ivltests pr2913438a normal ivltests pr2913438b normal ivltests pr2913927 normal ivltests pr2918095 normal ivltests pr2922063 normal ivltests pr2922063a normal ivltests pr2922063b normal ivltests pr2924354 normal ivltests gold=pr2924354.gold pr2929913 normal ivltests pr2930506 normal ivltests pr2937417 normal ivltests pr2937417b normal ivltests pr2937417c normal ivltests pr2941939 normal ivltests pr2943394 normal ivltests pr2951657 normal ivltests pr2969724 normal ivltests pr2971207 normal ivltests pr2972866 normal,-Tmax,-gspecify ivltests gold=pr2972866.gold pr2973532 normal ivltests pr2974051 normal ivltests pr2974216 normal ivltests pr2974216b normal ivltests pr2974294 normal ivltests pr2985542 normal ivltests pr2986497 CO ivltests pr2986528 normal ivltests pr2991457 normal ivltests pr2991457b normal ivltests pr2994193 normal ivltests pr2998515 normal ivltests pr3011327 normal ivltests pr3012758 normal ivltests pr3015421 CE ivltests gold=pr3015421.gold pr3022502 normal ivltests pr3024131 normal ivltests pr3039548 normal ivltests gold=pr3039548.gold pr3044843 normal ivltests pr3054101a normal ivltests gold=pr3054101a.gold pr3054101b normal ivltests gold=pr3054101a.gold pr3054101c normal ivltests gold=pr3054101c.gold pr3054101d normal ivltests gold=pr3054101c.gold pr3054101e normal ivltests gold=pr3054101e.gold pr3054101f normal ivltests gold=pr3054101e.gold pr3054101g normal ivltests gold=pr3054101g.gold pr3054101h normal ivltests gold=pr3054101g.gold pr3061015a CE ivltests pr3061015b CE ivltests pr3061015c CE ivltests pr3064375 normal ivltests gold=pr3064375.gold pr3064511 normal ivltests pr3077640 normal ivltests pr3078759 CO,-gspecify ivltests pr3098439 normal ivltests pr3098439a normal ivltests pr3098439b normal ivltests pr3103880 normal ivltests pr3104254 normal ivltests pr3112073a CE ivltests pr3149494 normal ivltests gold=pr3149494.gold pr3190941 CE ivltests gold=pr3190941.gold pr3190948 normal ivltests pr3194155 normal ivltests gold=pr3194155.gold pr3197861 normal ivltests pr3197917 normal ivltests pr3270320 CE ivltests pr3284821 normal ivltests pr3292735 normal ivltests pr3296466a normal ivltests pr3296466b normal ivltests pr3296466c normal ivltests pr3296466d normal ivltests pr3306516 normal,-gspecify ivltests pr3309391 normal ivltests pr3368642 normal ivltests pr3409749 normal ivltests pr3437290a normal ivltests pr3437290b normal ivltests pr3437290c normal ivltests pr3441576 normal ivltests gold=pr3441576.gold pr3445452 normal ivltests pr3452808 normal ivltests pr3465541 normal ivltests pr3477107 normal ivltests pr3499807 normal ivltests gold=pr3499807.gold pr3522653 normal ivltests gold=pr3522653.gold pr3527022 normal ivltests pr3527694 normal ivltests gold=pr3527694.gold pr3534422 normal ivltests pr3539372 normal ivltests pr3549328 CE ivltests pr3557493 normal ivltests pr3561350 normal ivltests pr3563412 normal ivltests pr3571573 normal ivltests gold=pr3571573.gold pr3582052 normal ivltests pr3587570 normal ivltests pr3592746 normal ivltests prng normal ivltests ptest001 normal ivltests ptest002 normal ivltests ptest003 normal ivltests ptest004 normal ivltests ptest005 normal ivltests ptest006 normal ivltests ptest007 normal ivltests ptest008 normal ivltests ptest009 normal ivltests ptest010 normal ivltests ptest011 normal ivltests pullupdown normal ivltests # Contributed test pullupdown2 normal ivltests # Contributed test pullupdown3 normal ivltests # Contributed test pv_undef_sig_sel normal ivltests pv_wr_vec4 normal ivltests pv_wr_vec4_nb normal ivltests pv_wr_vec4_nb_ec normal ivltests pv_wr_vec4a normal ivltests pv_wr_vec4a_nb normal ivltests pv_wr_vec4a_nb_ec normal ivltests qmark normal ivltests qmark1 normal ivltests qmark3 normal ivltests qmark5 normal ivltests qmark6 normal ivltests queue normal ivltests queue_fail RE ivltests gold=queue_fail.gold queue_stat normal ivltests gold=queue_stat.gold ram16x1 normal ivltests # Sitting here for a long time? random normal ivltests gold=random.gold readmem-error normal ivltests gold=readmem-error.gold readmem-invalid RE ivltests gold=readmem-invalid.gold readmemb1 normal ivltests # basic $readmemb - uses readmemh1.dat readmemb2 normal ivltests # $readmemb w/ short data file - readmemh2.dat readmemb3 normal ivltests # $readmemb 0-3 with long dfile - readmemh1.dat readmemh1 normal ivltests # basic $readmemh - uses readmemh1.dat readmemh1a normal ivltests # basic $readmemh with @addr - uses readmemh1a.dat readmemh2 normal ivltests # $readmemh w/ short data file - readmemh2.dat readmemh3 normal ivltests # $readmemh 0-3 with long dfile - readmemh1.dat readmemh4 normal ivltests # $readmemh - comments in data file readmemh5 CE ivltests # Should be error for readmemh(romimg,rom[0:7]) real normal ivltests real2 normal ivltests real3 normal ivltests real5 normal ivltests gold=real5.gold real6 normal ivltests real7 normal ivltests real9 normal ivltests real10 normal ivltests real11 normal ivltests real_array_multi_dim normal ivltests real_array_store_after_cmp normal ivltests real_assign_deassign normal ivltests real_concat_invalid2 CE ivltests real_delay normal,-gspecify ivltests gold=real_delay.gold real_events normal ivltests gold=real_events.gold real_force_rel normal ivltests real_invalid_ops CE ivltests gold=real_invalid_ops.gold real_logical normal ivltests real_reg_force_rel normal ivltests recursive_func1 normal ivltests gold=recursive_func.gold recursive_func_const1 normal ivltests gold=recursive_func_const.gold recursive_task normal ivltests gold=recursive_task.gold redef_net_error CE ivltests redef_reg_error CE ivltests repeat2 normal ivltests repeat_expr_probe normal ivltests repl_zero_wid_fail CE ivltests repl_zero_wid_pass normal ivltests resetall normal,-Wtimescale ivltests gold=resetall.gold resetall2 normal,-Wtimescale ivltests gold=resetall2.gold resolv1 normal ivltests # PR#300 rise_fall_decay1 normal ivltests rise_fall_decay2 normal ivltests rise_fall_delay1 normal ivltests rise_fall_delay2 normal ivltests rise_fall_delay3 normal ivltests rl_pow normal ivltests rnpmos normal ivltests rnpmos2 normal ivltests rop normal ivltests rptconcat normal ivltests # Repeat concatenation operation. rtran normal ivltests gold=rtran.gold rtranif0 normal ivltests gold=rtranif0.gold rtranif1 normal ivltests gold=rtranif1.gold scan-invalid RE ivltests gold=scan-invalid.gold scanf normal ivltests scanf2 normal ivltests scanf3 normal ivltests scanf4 normal ivltests sched1 normal ivltests sched2 normal ivltests schedule normal ivltests scope1 normal ivltests # scope of var into a task scope2 normal ivltests # scope of var stops at module boundaries scope2b CE,-g1 ivltests # broken version of scope2 scope4 normal ivltests scope5 normal ivltests scoped_events normal ivltests gold=scoped_events.gold sdf1 normal,-gspecify ivltests gold=sdf1.gold sdf2 normal,-gspecify ivltests gold=sdf1.gold sdf3 normal,-gspecify ivltests gold=sdf1.gold sdf4 normal,-gspecify ivltests gold=sdf1.gold sdf5 normal,-gspecify ivltests gold=sdf5.gold sdf6 normal,-gspecify ivltests gold=sdf6.gold sdf7 normal,-gspecify ivltests gold=sdf7.gold sdf8 normal,-gspecify ivltests gold=sdf8.gold sdf_del_max normal,-gspecify,-Tmax ivltests sdf_del_min normal,-gspecify,-Tmin ivltests sdf_del_typ normal,-gspecify,-Ttyp ivltests sdf_esc_id normal,-gspecify ivltests gold=sdf1.gold sdw_always1 normal ivltests sdw_always2 normal ivltests sdw_always3 normal ivltests sdw_array normal ivltests sdw_assign normal ivltests sdw_dsbl normal ivltests sdw_force normal ivltests sdw_function1 normal ivltests sdw_function2 normal ivltests sdw_function3 normal ivltests sdw_function4 normal ivltests # function with if from George Gallant bug rpt sdw_function5 normal ivltests # function with if from George Gallant bug rpt sdw_instmod1 normal ivltests sdw_instmod2 normal ivltests sdw_int normal ivltests sdw_lvalconcat normal ivltests sdw_param1 normal ivltests sdw_param2 normal ivltests sdw_release normal ivltests sdw_stmt002 normal ivltests sdw_task1 normal ivltests sdw_task2 normal ivltests sel_rval_bit_ob normal,-Wselect-range ivltests gold=sel_rval_bit_ob.gold sel_rval_part_ob normal,-Wselect-range ivltests gold=sel_rval_part_ob.gold select normal ivltests # structural word select select2 normal ivltests # structural bit select select3 normal ivltests gold=select3.gold select4 normal ivltests # structural bit select select5 normal ivltests # structural bit select select6 normal ivltests select7 normal ivltests select8 normal ivltests select_padding normal ivltests shellho1 normal ivltests top gold=shellho1.gold shift1 normal ivltests gold=shift1.gold shift2 normal ivltests shift3 normal ivltests shift4 normal ivltests shift5 normal ivltests gold=shift5.gold shift_pad normal ivltests signed1 normal ivltests signed2 normal ivltests signed3 normal ivltests signed4 normal ivltests gold=signed4.gold signed5 normal ivltests signed6 normal ivltests signed7 normal ivltests signed8 normal ivltests signed9 normal ivltests signed10 normal ivltests gold=signed10.gold signed11 normal ivltests signed12 normal ivltests gold=signed12.gold signed13 normal ivltests signed_a normal ivltests signed_equality normal ivltests signed_net_display normal ivltests signed_part normal ivltests signed_pv normal ivltests sp2 normal ivltests diff=work/sp2.inv:gold/sp2.inv specify1 CO ivltests specify2 normal,-gspecify ivltests specify3 normal,-gspecify ivltests gold=specify3.gold specify4 normal,-gspecify ivltests gold=specify4.gold specify5 normal,-gspecify ivltests gold=specify5.gold specify_01 normal,-gspecify ivltests test # Yet another version of specify sqrt32 normal ivltests sscanf_u normal ivltests sscanf_z normal ivltests stask_parm1 normal ivltests stask_parm2 normal ivltests gold=stask_parm2.gold stask_sens_null_arg normal ivltests string1 normal ivltests string2 normal ivltests string3 normal ivltests string4 normal ivltests gold=string4.gold string5 normal ivltests gold=string5.gold string7 normal ivltests gold=string7.gold string8 normal ivltests gold=string8.gold string9 normal ivltests gold=string9.gold string10 normal ivltests gold=string10.gold string11 normal ivltests gold=string11.gold string12 normal ivltests supply1 normal ivltests supply2 normal ivltests switch_primitives normal ivltests gold=switch_primitives.gold sys_func_task_error RE ivltests gold=sys_func_task_error.gold talu normal ivltests task-scope normal ivltests task3.14A normal ivltests task3.14B normal ivltests task3.14C normal ivltests task3.14D normal ivltests task3.14E normal ivltests task3.14F normal ivltests task_bypath normal ivltests # task enabled by complete path name. task_in_expr_fail CE ivltests task_inpad normal ivltests # Validates input of task should pad w/ 0 task_iotypes normal ivltests # task ports with types. task_iotypes2 normal ivltests # task ports with types. task_mem normal ivltests task_nonansi_fail1 CE ivltests task_nonansi_fail2 CE ivltests task_nonansi_fail3 CE ivltests task_nonansi_fail4 CE ivltests task_nonansi_fail5 CE ivltests task_nonansi_fail6 CE ivltests task_nonansi_fail7 CE ivltests task_nonansi_fail8 CE ivltests task_nonansi_fail9 CE ivltests task_nonansi_fail10 CE ivltests task_nonansi_fail11 CE ivltests task_nonansi_integer1 normal ivltests task_nonansi_integer2 normal ivltests task_nonansi_integer_fail CE ivltests task_nonansi_real1 normal ivltests task_nonansi_real2 normal ivltests task_nonansi_real_fail CE ivltests task_nonansi_time1 normal ivltests task_nonansi_time2 normal ivltests task_nonansi_time_fail CE ivltests task_nonansi_vec1 normal ivltests task_nonansi_vec2 normal ivltests task_nonansi_vec_fail1 CE ivltests task_nonansi_vec_fail2 CE ivltests task_nonansi_vec_fail3 CE ivltests task_noop normal ivltests # Task with no contents. task_noop2 CO ivltests # Task *really* with no contents. task_omemw2 normal ivltests task_omemw3 CO ivltests # Pass bit selected from vector to task task_port_range_mismatch CE ivltests task_port_size normal ivltests # truncate task port connections task_scope normal ivltests tern1 normal ivltests # Finds problems with ?: using different sizes tern2 CO ivltests # make sure ?: is recognized by -tnull tern4 normal ivltests tern5 normal ivltests gold=tern5.gold tern6 normal ivltests tern7 normal ivltests tern9 normal ivltests tern10 normal ivltests test_bufif0 normal ivltests test_bufif1 normal ivltests test_disphob normal ivltests gold=test_disphob.gold test_dispwided normal ivltests gold=test_dispwided.gold test_extended normal ivltests gold=test_extended.gold test_mos_strength_reduction normal ivltests test_nmos normal ivltests test_notif0 normal ivltests test_notif1 normal ivltests test_pmos normal ivltests test_rnmos normal ivltests test_rpmos normal ivltests test_width normal ivltests gold=test_width.gold time1 normal ivltests time2 normal ivltests # Tests posedge vector uses vector[0] time3 normal ivltests time4 normal ivltests time5 normal ivltests time7 normal ivltests # gold=time7.gold time8 normal ivltests timeform1 normal ivltests gold=timeform1.gold timeform2 normal ivltests gold=timeform2.gold timescale1 normal ivltests timescale2 normal ivltests timescale3 CE ivltests tran normal ivltests gold=tran.gold tranif0 normal ivltests gold=tranif0.gold tranif1 normal ivltests gold=tranif1.gold tran-keeper normal ivltests tri0 normal ivltests tri0b normal ivltests tri1 normal ivltests tri2 normal ivltests tri3 normal ivltests triand normal ivltests trior normal ivltests types1 normal ivltests udp_bufg normal ivltests udp_bufg2 normal ivltests udp_bx normal ivltests gold=udp_bx.gold udp_delay_fail CE ivltests udp_dff normal ivltests udp_dff_std normal ivltests udp_eval_arg normal ivltests udp_jkff normal ivltests udp_output_reg normal ivltests udp_real_delay normal ivltests udp_sched normal ivltests udp_x normal ivltests unary_and normal ivltests # Unary And &(vect) unary_lnot1 normal ivltests unary_lnot2 normal ivltests unary_lnot3 normal ivltests unary_minus normal ivltests # Unary minus -(vect) unary_minus1 normal ivltests # From 272 directly. unary_minus2 normal ivltests unary_minus3 normal ivltests unary_minus4 normal ivltests unary_nand normal ivltests # Unary nand ~&(vect) unary_nand2 normal ivltests # Unary nand ~&(vect) unary_nor normal ivltests # Unary nor ~|(vect) unary_nor2 normal ivltests # Unary nor ~|(vect) unary_not normal ivltests # Unary not ~ unary_or normal ivltests # Unary or |(vect) unary_xnor1 normal ivltests # Unary xnor ~^(vect) unary_xnor2 normal ivltests # Unary xnor ^~(vect) unary_xor normal ivltests # Unary or ^(vect) uncon_drive normal ivltests undef normal ivltests gold=undef.gold undef_lval_select normal ivltests undef_lval_select2 normal ivltests undef_lval_select3a normal ivltests undef_lval_select3b CE ivltests undef_lval_select3c CE ivltests undef_lval_select4a normal ivltests undef_lval_select4b CE ivltests undef_lval_select4c CE ivltests undef_lval_select5 normal ivltests undefined_shift normal ivltests unnamed_block_var_decl CE ivltests unnamed_fork_var_decl CE ivltests urand_r normal ivltests gold=urand_r.gold urand_r2 normal ivltests gold=urand_r.gold urand_r3 normal ivltests gold=urand_r.gold uwire normal ivltests uwire2 normal ivltests uwire_fail CE ivltests gold=uwire_fail.gold vardly normal ivltests varlsfht normal ivltests # variable << in wire varlsfht1 normal ivltests # variable << in always varlsfht2 normal ivltests # variable << in function varrshft normal ivltests # variable >> in wire varrshft1 normal ivltests # variable >> in always varrshft2 normal ivltests # variable >> in function vcd-dup normal ivltests diff=work/vcd-dup.vcd:gold/vcd-dup.vcd.gold:2 vector normal ivltests gold=vector.gold verify_two_var_delays normal ivltests vvp_scalar_value normal ivltests wait1 normal ivltests wait2 normal ivltests wait3 normal ivltests gold=wait3.gold warn_opt_sys_tf RE ivltests gold=warn_opt_sys_tf.gold wildsense normal ivltests # Wildcard sensitivity list. wildsense2 normal ivltests # Wildcard sensitivity list. wireadd1 normal ivltests wireeq normal ivltests wirege normal ivltests wireland normal ivltests # assign a && (b ? 0 : 1) (pmonta) wirele normal ivltests wiremod1 normal ivltests wiresl normal ivltests wiresl2 normal ivltests gold=wiresl2.gold wiresr normal ivltests wiresub1 normal ivltests wirexor1 normal ivltests writemem-error normal ivltests gold=writemem-error.gold writemem-invalid RE ivltests gold=writemem-invalid.gold writememb1 normal ivltests # pr#400 writememb2 normal ivltests # pr#400 writememh1 normal ivltests # pr#334 writememh2 normal ivltests # pr#400 xnor_test normal ivltests # ~^ in an IF() z1 normal ivltests foo z2 normal ivltests foo zero_repl normal ivltests zero_repl_fail CE ivltests cmpi normal ivltests iverilog-12_0/ivtest/regress-vlog95.list000066400000000000000000001420021435245347300203560ustar00rootroot00000000000000# This test list is used to override other test lists when using # the Icarus Verilog vlog95 target. # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected Fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # TE: Translation Error - We EXPECT the translated code to fail - # only supported in the vlog95 checker. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the # generated log file. # unordered=filename - Compare a gold file against the # generated log file, allowing for lines # to appear in any order # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # # Verilog 95 does not support automatic tasks or functions. always_comb_rfunc CE ivltests automatic_error11 CE ivltests automatic_error12 CE ivltests automatic_error13 CE ivltests automatic_events CE ivltests automatic_events2 CE ivltests automatic_events3 CE ivltests automatic_task CE ivltests automatic_task2 CE ivltests automatic_task3 CE ivltests br942 CE ivltests br_gh531 CE ivltests def_nettype CE ivltests func_init_var1 CE,-pallowsigned=1 ivltests func_init_var2 CE,-pallowsigned=1 ivltests func_init_var3 CE,-pallowsigned=1 ivltests nested_func CE ivltests pr2169870 CE ivltests pr2172606b CE ivltests pr2276163 CE ivltests pr2929913 CE ivltests real_events CE ivltests recursive_func1 CE ivltests recursive_func2 CE ivltests recursive_func_const1 CE ivltests recursive_func_const2 CE ivltests recursive_task CE ivltests task_init_var1 CE,-pallowsigned=1 ivltests task_init_var2 CE,-pallowsigned=1 ivltests task_init_var3 CE,-pallowsigned=1 ivltests task_nonansi_int1 normal,-g2005-sv,-pallowsigned=1 ivltests task_nonansi_int2 normal,-g2005-sv,-pallowsigned=1 ivltests task_port_types1 CE,-pallowsigned=1 ivltests task_port_types2 CE,-pallowsigned=1 ivltests test_work14 CE ivltests vhdl_elab_range CE ivltests vhdl_notfunc_stdlogic CE ivltests vhdl_procedure CE ivltests vhdl_range_func CE ivltests vhdl_report CE ivltests vhdl_subprogram CE ivltests vhdl_unbounded_func CE ivltests # Verilog 95 does not support real nets. array_lval_select4a CE ivltests # Also net arrays array_lval_select4b CE ivltests # Also net arrays array_lval_select5 CE ivltests # Also net arrays array_lval_select6 CE ivltests # Also net arrays br_gh456 CE,-g2009,-pallowsigned=1 ivltests ca_64delay CE ivltests # Also net arrays ca_time_real CE ivltests ca_var_delay CE ivltests cast_real CE,-pallowsigned=1 ivltests cast_real_signed CE,-pallowsigned=1 ivltests cast_real_unsigned CE ivltests sv_cast_integer normal,-g2005-sv,-pallowsigned=1 ivltests sv_cast_integer2 normal,-g2005-sv,-pallowsigned=1 ivltests sv_cast_packed_struct normal,-g2005-sv,-pallowsigned=1 ivltests sv_cast_string CE ivltests clog2 CE ivltests # Also big int delayed_sfunc CE ivltests implicit_cast4 CE,-g2009,-pallowsigned=1 ivltests implicit_cast5 CE,-g2009,-pallowsigned=1 ivltests implicit_cast6 CE,-g2009,-pallowsigned=1 ivltests implicit_cast12 CE,-g2009,-pallowsigned=1 ivltests implicit_cast13 CE,-g2009,-pallowsigned=1 ivltests module_port_shortreal CE,-g2005-sv ivltests pr1861212c CE ivltests pr1864110a CE ivltests pr1864110b CE ivltests pr1864110c CE ivltests pr1864115 CE ivltests pr1873372 CE ivltests pr1880003 CE ivltests pr1898293 CE ivltests pr2123158 CE ivltests pr2123190 CE ivltests pr2453002b CE ivltests pr2456943 CE ivltests pr2806474 CE ivltests pr2976242 CE ivltests pr2976242b CE ivltests real8 CE ivltests real_mod_in_ca CE ivltests real_pulse_clean CE ivltests real_pwr_in_ca CE ivltests # Also power operator real_wire_array CE ivltests real_wire_force_rel CE ivltests tern8 CE ivltests v2005_math CE ivltests vams_abs2 CE,-gverilog-ams,-pallowsigned=1 ivltests vams_abs3 CE,-gverilog-ams,-pallowsigned=1 ivltests vhdl_real CE,-g2009,ivltests/vhdl_real.vhd ivltests vhdl_unbounded CE,-g2009,ivltests/vhdl_unbounded.vhd ivltests wreal CE ivltests # Real modulus is an Icarus extension. pr1528093 CE ivltests # IEEE 1364-1995 does not support the general power operator. br_gh9 CE ivltests br_gh244a CE ivltests br_gh244b CE ivltests ca_pow_signed CE,-pallowsigned=1 ivltests br_mw20171108 CE,-pallowsigned=1 ivltests ca_pow_synth CE ivltests ca_pow_unsigned CE ivltests constfunc3 CE ivltests pow_ca_signed CE ivltests pow_ca_unsigned CE ivltests pow_reg_signed CE ivltests pow_reg_unsigned CE ivltests pow_signed CE ivltests pow_unsigned CE ivltests pow-ca CE,-pallowsigned=1 ivltests pow-proc CE,-pallowsigned=1 ivltests pr2352834 CE,-pallowsigned=1 ivltests pr2823711 CE ivltests pr2909386b CE,-pallowsigned=1 ivltests rl_pow CE ivltests vhdl_pow_rem CE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_pow_rem.vhd ivltests # IEEE 1364-1995 does not support these SV functions sf_countbits RE,-g2012 ivltests sf_countbits_fail RE,-g2012 ivltests sf_countones RE,-g2009 ivltests sf_countones_fail RE,-g2009 ivltests sf_isunknown RE,-g2005-sv ivltests sf_isunknown_fail RE,-g2005-sv ivltests sf_onehot RE,-g2005-sv ivltests sf_onehot_fail RE,-g2005-sv ivltests sf_onehot0 RE,-g2005-sv ivltests sf_onehot0_fail RE,-g2005-sv ivltests # IEEE 1364-1995 only supports register arrays. array_lval_select1 normal,-DVLOG95 ivltests array_lval_select2 normal,-DVLOG95 ivltests array_lval_select3a TE,-DVLOG95 ivltests array_lval_select3b CE,-DVLOG95 ivltests array_lval_select3c normal,-DVLOG95 ivltests array_select CE,-pallowsigned=1 ivltests array_select_a CE ivltests array_unpacked_sysfunct CE,-g2005-sv ivltests array_word_width2 CE ivltests assign_op_after_cmp3 CE,-g2009 ivltests assign_op_real_array CE,-g2009 ivltests assign_op_real_array_oob CE,-g2009 ivltests br1008 CE ivltests br1019 CE ivltests br_gh556 CE,-g2009 ivltests br_gh632c CE ivltests br_gh661a CE ivltests br_gh661b CE ivltests br_ml20171017 CE ivltests genvar_scopes CE ivltests meminit2 CE ivltests memsynth4 CE,-S ivltests # Synthesized net array module_port_typedef_array1 CE,-g2005-sv ivltests # Module port array negative_genvar CE ivltests pr1565544 CE ivltests pr1657307 CE ivltests pr1695322 CE ivltests pr1701855b CE ivltests pr1703346 CE ivltests pr1740476b CE ivltests pr1758122 CE,-g2001-noconfig ivltests pr1799904 CE ivltests pr1820472 CE ivltests pr1868792 CE ivltests pr1876798 CE ivltests pr1903324 CE ivltests pr2011429 CE ivltests pr2076391 CE,-pallowsigned=1 ivltests pr2201909 CE ivltests pr2201909b CE ivltests pr2166311 CE ivltests pr2715748 CE ivltests # Also real net pr2815398b CE ivltests pr3054101g CE ivltests pr3054101h CE ivltests pr3592746 CE ivltests real_array CE ivltests real_array_nb CE,-pallowsigned=1 ivltests real_array_multi_dim CE,-pallowsigned=1 ivltests real_array_store_after_cmp CE ivltests scan-invalid CE ivltests sel_rval_bit_ob CE ivltests sel_rval_part_ob CE ivltests signed_net_display CE,-pallowsigned=1 ivltests sv_array_cassign1 CE,-g2005-sv ivltests sv_array_cassign2 CE,-g2005-sv ivltests sv_array_cassign3 CE,-g2005-sv ivltests sv_array_cassign4 CE,-g2005-sv ivltests sv_array_cassign5 CE,-g2005-sv ivltests sv_unpacked_port CE,-g2009 ivltests sv_unpacked_port2 CE,-g2009,-pallowsigned=1 ivltests sv_unpacked_wire CE,-g2009 ivltests sv_unpacked_wire2 CE,-g2009,-pallowsigned=1 ivltests # A zero replication in a CA is not supported. concat4 EF ivltests # SystemVerilog final blocks are not supported. br_gh443 CE,-g2009 ivltests final CE,-g2009 ivltests final2 CE,-g2009 ivltests program_hello CE,-g2009 ivltests program2 CE,-g2009,-pallowsigned=1 ivltests program2b CE,-g2009,-pallowsigned=1 ivltests program3 CE,-g2009 ivltests program3a CE,-g2009 ivltests program4 CE,-g2009 ivltests # No support for the SystemVerilog string data type. array_string CE,-g2009,-pallowsigned=1 ivltests br932a CE,-g2009 ivltests br932b CE,-g2009 ivltests br_gh4 CE,-g2009 ivltests br_gh175 CE,-g2009,-pallowsigned=1 ivltests br_gh194 CE,-g2009 ivltests br_gh365 CE,-g2009 ivltests br_gh453 CE,-g2009,-pallowsigned=1 ivltests br_ml20180309a CE,-g2009 ivltests br_ml20180309b CE,-g2009 ivltests ivlh_textio CE,-g2005-sv ivltests plus_arg_string CE,-g2009 ivltests sformatf CE,-g2009 ivltests string_events CE,-g2009 ivltests string_index CE,-g2005-sv ivltests sv_cast_typedef CE,-g2005-sv ivltests sv_macro CE,-g2009,-pallowsigned=1 ivltests sv_string1 CE,-g2009 ivltests sv_string2 CE,-g2009 ivltests sv_string3 CE,-g2009 ivltests sv_string4 CE,-g2009 ivltests sv_string5 CE,-g2009 ivltests sv_string6 CE,-g2009,-pallowsigned=1 ivltests sv_string7 CE,-g2009,-pallowsigned=1 ivltests sv_string7b CE,-g2009,-pallowsigned=1 ivltests sv_typedef_fwd_base CE,-g2009 ivltests vhdl_string_lim CE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_string_lim.vhd ivltests vhdl_textio_write CE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_textio_write.vhd ivltests vhdl_textio_read CE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_textio_read.vhd ivltests # SystemVerilog dynamic arrays and new operator. always_comb_warn CE,-g2009,-pallowsigned=1 ivltests always_ff_warn CE,-g2009,-pallowsigned=1 ivltests always_latch_warn CE,-g2009,-pallowsigned=1 ivltests br962 CE,-g2009 ivltests br963 CE,-g2009 ivltests br_gh164a CE,-g2009,-pallowsigned=1 ivltests br_gh164b CE,-g2009,-pallowsigned=1 ivltests br_gh164c CE,-g2009,-pallowsigned=1 ivltests br_gh164d CE,-g2009,-pallowsigned=1 ivltests br_gh164e CE,-g2009,-pallowsigned=1 ivltests br_gh383a CE,-g2012, ivltests br_gh383b CE,-g2012, ivltests br_gh383c CE,-g2012,-pallowsigned=1 ivltests br_gh383d CE,-g2012,-pallowsigned=1 ivltests br_gh460 CE,-g2012 ivltests br_ml20191221 CE,-g2009,-pallowsigned=1 ivltests sv_assign_pattern_cast CE,-g2005-sv,-pallowsigned=1 ivltests sv_assign_pattern_const CE,-g2005-sv,-pallowsigned=1 ivltests sv_assign_pattern_concat CE,-g2005-sv,-pallowsigned=1 ivltests sv_assign_pattern_expand CE,-g2005,-sv-pallowsigned=1 ivltests sv_assign_pattern_func CE,-g2005-sv,-pallowsigned=1 ivltests sv_assign_pattern_op CE,-g2005-sv,-pallowsigned=1 ivltests sv_assign_pattern_part CE,-g2005-sv,-pallowsigned=1 ivltests sv_array_assign_pattern2 CE,-g2009,-pallowsigned=1 ivltests sv_cast_darray CE,-g2005-sv,-pallowsigned=1 ivltests sv_darray1 CE,-g2009,-pallowsigned=1 ivltests sv_darray2 CE,-g2009,-pallowsigned=1 ivltests sv_darray3 CE,-g2009,-pallowsigned=1 ivltests sv_darray4 CE,-g2009,-pallowsigned=1 ivltests sv_darray5 CE,-g2009,-pallowsigned=1 ivltests sv_darray5b CE,-g2009,-pallowsigned=1 ivltests sv_darray6 CE,-g2009,-pallowsigned=1 ivltests # Also string sv_darray7 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args1 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args2 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args2b CE,-g2009,-pallowsigned=1 ivltests sv_darray_args3 CE,-g2009,-pallowsigned=1 ivltests sv_darray_args4 CE,-g2009,-pallowsigned=1 ivltests # Also string sv_darray_assign1 CE,-g2009 ivltests sv_darray_assign2 CE,-g2009 ivltests sv_darray_copy_empty1 CE,-g2009 ivltests sv_darray_copy_empty2 CE,-g2009 ivltests sv_darray_copy_empty3 CE,-g2009 ivltests sv_darray_copy_empty4 CE,-g2009 ivltests sv_darray_decl_assign CE,-g2009,-pallowsigned=1 ivltests sv_darray_function CE,-g2009,-pallowsigned=1 ivltests sv_darray_oob_real CE,-g2009 ivltests sv_darray_oob_string CE,-g2009 ivltests # Also string sv_darray_oob_vec2 CE,-g2009 ivltests # Also 2-state sv_darray_oob_vec4 CE,-g2009 ivltests sv_darray_signed CE,-g2009,-pallowsigned=1 ivltests # Also string sv_darray_word_size CE,-g2009 ivltests sv_new_array_error CE,-g2009, ivltests unp_array_typedef CE,-g2009,-pallowsigned=1 ivltests # Also string # SystemVerilog classes, new and null operators. br959 CE,-g2009 ivltests br1003a CE,-g2009 ivltests br1004 CE,-g2009 ivltests br_gh104a CE,-g2009 ivltests br_gh167a CE,-g2009 ivltests br_gh167b CE,-g2009 ivltests br_gh177a CE,-g2009 ivltests br_gh177b CE,-g2009 ivltests br_gh388 CE,-g2009 ivltests br_gh390b CE,-g2009 ivltests br_gh391 CE,-g2009 ivltests br_gh437 CE,-g2009 ivltests br_gh445 CE,-g2009 ivltests br_gh461 CE,-g2009 ivltests enum_in_class CE,-g2005-sv ivltests enum_in_class_name_coll CE,-g2005-sv ivltests sv_class1 CE,-g2009 ivltests sv_class2 CE,-g2009 ivltests sv_class3 CE,-g2009 ivltests sv_class4 CE,-g2009 ivltests sv_class5 CE,-g2009 ivltests sv_class6 CE,-g2009 ivltests sv_class7 CE,-g2009 ivltests sv_class8 CE,-g2009 ivltests sv_class9 CE,-g2009 ivltests # Also dynamic array sv_class10 CE,-g2009 ivltests sv_class11 CE,-g2009 ivltests sv_class12 CE,-g2009 ivltests sv_class13 CE,-g2009 ivltests sv_class14 CE,-g2009 ivltests sv_class15 CE,-g2009 ivltests sv_class16 CE,-g2009 ivltests sv_class17 CE,-g2009 ivltests sv_class18 CE,-g2009 ivltests sv_class19 CE,-g2009 ivltests sv_class20 CE,-g2009 ivltests sv_class21 CE,-g2009 ivltests sv_class22 CE,-g2009 ivltests sv_class23 CE,-g2009 ivltests sv_class24 CE,-g2009 ivltests sv_class_compat1 CE,-g2009 ivltests sv_class_compat2 CE,-g2009 ivltests sv_class_constructor1 CE,-g2009 ivltests sv_class_empty_item CE,-g2009 ivltests sv_class_extends_scoped CE,-g2009 ivltests sv_class_localparam CE,-g2009 ivltests sv_class_new_init CE,-g2009 ivltests sv_class_new_typed1 CE,-g2009 ivltests sv_class_new_typed2 CE,-g2009 ivltests sv_class_new_typed3 CE,-g2009 ivltests sv_class_in_module_decl CE,-g2009 ivltests sv_class_method_call_void CE,-g2009 ivltests sv_class_method_default1 CE,-g2009 ivltests sv_class_method_default2 CE,-g2009 ivltests sv_class_method_signed1 CE,-g2009,-pallowsigned=1 ivltests sv_class_method_signed2 CE,-g2009,-pallowsigned=1 ivltests sv_class_method_var_init CE,-g2009,-pallowsigned=1 ivltests sv_class_property_signed1 CE,-g2009,-pallowsigned=1 ivltests sv_class_property_signed2 CE,-g2009,-pallowsigned=1 ivltests sv_class_property_signed3 CE,-g2009,-pallowsigned=1 ivltests sv_class_property_signed4 CE,-g2009,-pallowsigned=1 ivltests sv_class_static_prop1 CE,-g2009 ivltests sv_class_static_prop2 CE,-g2009 ivltests sv_class_static_prop3 CE,-g2009 ivltests sv_class_super1 CE,-g2009 ivltests sv_class_super2 CE,-g2009 ivltests sv_class_super3 CE,-g2009 ivltests sv_class_super4 CE,-g2009 ivltests sv_class_super5 CE,-g2009 ivltests sv_class_super6 CE,-g2009 ivltests sv_class_task1 CE,-g2009 ivltests sv_end_label CE,-g2009 ivltests # Also generate sv_foreach2 CE,-g2009,-pallowsigned=1 ivltests sv_foreach3 CE,-g2009 ivltests sv_foreach4 CE,-g2009 ivltests sv_pkg_class CE,-g2009 ivltests sv_port_default1 CE,-g2009 ivltests sv_port_default2 CE,-g2009,-pallowsigned=1 ivltests sv_port_default3 CE,-g2009 ivltests sv_port_default4 CE,-g2009,-pallowsigned=1 ivltests sv_port_default5 CE,-g2009 ivltests sv_port_default6 CE,-g2009,-pallowsigned=1 ivltests sv_port_default7 CE,-g2009,-pallowsigned=1 ivltests sv_port_default8 CE,-g2009,-pallowsigned=1 ivltests sv_port_default9 CE,-g2009 ivltests sv_ps_type_class1 CE,-g2009 ivltests sv_ps_type_class_prop CE,-g2009 ivltests sv_root_class CE,-g2009 ivltests sv_typedef_fwd_class CE,-g2009 ivltests sv_typedef_fwd_class2 CE,-g2009 ivltests sv_typedef_fwd_enum3 CE,-g2009 ivltests sv_typedef_scope3 CE,-g2009 ivltests sv_unit2b CE,-g2009 ivltests sv_unit3b CE,-g2009 ivltests sv_unit4b CE,-g2009 ivltests # These variable assignments are converted to wire definitions that are # assigned from both a continuous assignment and a procedural assignment. # This is not supported in 1364-1995 so the translated code will fail. sv_uwire1 TE,-g2009 ivltests sv_uwire2 TE,-g2009 ivltests vvp_recv_vec4_pv TE,-g2009,-pallowsigned=1 ivltests # SystemVerilog requires that variable initialization that is part of a # declaration is performed before the start of simulation. When standard # Verilog is selected, Icarus ensures that combinatorial always blocks # are started before initial blocks, so these tests will fail. sv_var_init1 EF,-g2009 ivltests # This test should fail the same way, but there is an unresolved bug in # translation. sv_var_init2 TE,-g2009 ivltests # No support for these SystemVerilog features always4A CE,-g2009 ivltests # join_any always4B CE,-g2009 ivltests # join_none br936 CE,-g2009,-pallowsigned=1 ivltests # join_any br_gh165 CE,-g2009 ivltests # join_* br_gh368 CE,-g2009 ivltests # join_* br_gh412 CE,-g2009 ivltests # queues br_gh414 CE,-g2009,-pallowsigned=1 ivltests # strings br_gh436 CE,-g2012,-pallowsigned=1 ivltests # queues/strings br_gh672 CE,-g2009 ivltests # join_none br_mw20200501 CE,-g2009 ivltests # queues disable_fork_cmd CE,-g2009 ivltests # disable fork and join_* enum_method_signed1 CE,-g2009,-pallowsigned=1 ivltests enum_method_signed2 CE,-g2009,-pallowsigned=1 ivltests enum_method_signed3 CE,-g2009,-pallowsigned=1 ivltests enum_method_signed4 CE,-g2009,-pallowsigned=1 ivltests enum_next CE,-g2009,-pallowsigned=1 ivltests # enum enum_test1 CE,-g2009 ivltests # enum fork_join_any CE,-g2009,-pallowsigned=1 ivltests # join_any fork_join_dis CE,-g2009,-pallowsigned=1 ivltests # join_any fork_join_none CE,-g2009,-pallowsigned=1 ivltests # join_none logical_short_circuit CE,-g2012 ivltests # ++ plus_5 CE,-g2009,-pallowsigned=1 ivltests # ++/-- pr3366217f CE,-g2009,-pallowsigned=1 ivltests # enum pr3366217h CE,-g2009,-pallowsigned=1 ivltests # enum pr3366217i CE,-g2009 ivltests # enum pr3390385 CE,-g2009 ivltests # ++ pr3390385b CE,-g2009 ivltests # ++ pr3390385c CE,-g2009 ivltests # ++ pr3390385d CE,-g2009 ivltests # ++ pr3462145 CE,-g2009 ivltests # ++ sv_queue_assign1 CE,-g2009 ivltests # queue sv_queue_assign2 CE,-g2009 ivltests # queue sv_queue_copy_empty1 CE,-g2009 ivltests # queue sv_queue_copy_empty2 CE,-g2009 ivltests # queue sv_queue_function1 CE,-g2009,-pallowsigned=1 ivltests # queue sv_queue_function2 CE,-g2009,-pallowsigned=1 ivltests # queue sv_queue_oob_real CE,-g2009 ivltests # queue sv_queue_oob_string CE,-g2009 ivltests # queue, string sv_queue_oob_vec2 CE,-g2009 ivltests # queue, 2-state sv_queue_oob_vec4 CE,-g2009 ivltests # queue sv_typedef_darray_base1 CE,-g2009 ivltests # Dyanmic array sv_typedef_darray_base2 CE,-g2009 ivltests # Dyanmic array sv_typedef_darray_base3 CE,-g2009 ivltests # Dyanmic array sv_typedef_darray_base4 CE,-g2009 ivltests # Dyanmic array sv_typedef_queue_base1 CE,-g2009 ivltests # queue sv_typedef_queue_base2 CE,-g2009 ivltests # queue sv_typedef_queue_base3 CE,-g2009 ivltests # queue sv_typedef_queue_base4 CE,-g2009 ivltests # queue sv_void_cast1 CE,-g2009,-pallowsigned=1 ivltests # string sv_void_cast2 CE,-g2009,-pallowsigned=1 ivltests # string, class sv_void_cast3 CE,-g2009,-pallowsigned=1 ivltests # queue wait_fork CE,-g2009 ivltests # wait fork and join_* wild_cmp_err CE,-g2009 ivltests # ==?/!=? wild_cmp_err2 CE,-g2009 ivltests # ==?/!=? wild_cmp_net CE,-g2009 ivltests # ==?/!=? wild_cmp_var CE,-g2009 ivltests # ==?/!=? # No support for the SystemVerilog two state types (initial value problems). br_gh337 EF,-g2009,-pallowsigned=1 ivltests ibit_test EF,-g2009 ivltests ibyte_test EF,-g2009 ivltests iint_test EF,-g2009 ivltests ilongint_test EF,-g2009 ivltests ishortint_test EF,-g2009 ivltests sbyte_test EF,-g2009,-pallowsigned=1 ivltests sint_test EF,-g2009,-pallowsigned=1 ivltests slongint_test EF,-g2009,-pallowsigned=1 ivltests sshortint_test EF,-g2009,-pallowsigned=1 ivltests ubyte_test EF,-g2009,-pallowsigned=1 ivltests uint_test EF,-g2009,-pallowsigned=1 ivltests ulongint_test EF,-g2009,-pallowsigned=1 ivltests ushortint_test EF,-g2009,-pallowsigned=1 ivltests # These have four state to two state cast problems br_gh99e EF,-g2009 ivltests implicit_cast1 EF,-g2009,-pallowsigned=1 ivltests implicit_cast2 EF,-g2009,-pallowsigned=1 ivltests implicit_cast3 EF,-g2009,-pallowsigned=1 ivltests implicit_cast8 EF,-g2009,-pallowsigned=1 ivltests implicit_cast10 EF,-g2009,-pallowsigned=1 ivltests implicit_cast11 EF,-g2009,-pallowsigned=1 ivltests # These tests have unresolved failures that still need to be looked at. # The following two have problem getting the correct net/expression # information from the nexus. pr1723367 is the real torture test. partselsynth TE,-S ivltests pr1723367 TE,-gno-io-range-error ivltests gold=pr1723367.gold # There is a separate driver for each bit of byte_value. generate_multi_loop NI ivltests # Assert # There are multiple drivers on the nexus. A local pulldown and the actual # input driver. pr3194155 NI ivltests # Asserts # This is caused because the two port are cross coupled. This creates a # recursive call that never ends and blows over the stack limit. pr3452808 NI ivltests # Seg. faults # Translating selects of a non-zero based vector/array cast the base select # expression to $signed(). The normalization is already removed, but the code # cannot currently determine if the $signed() is from the normalization or # from the original code. bitsel5 CE ivltests # Translating selects with the LSB > MSB are also normalized and the code # cannot determine if the $signed() should be removed or not. pr751 CE,-Wsensitivity-entire-vector ivltests # gold=pr751.gold # This has a port connect issue and a failure because the actual port is cast # from 4-state to 2-state and the port information is removed on the 4-state # side (the actual port). I'm not sure why the enum is not a bit or other # 2-state variable, but when that is done there is a compile error. vhdl_var_init CE,-g2009,vhdl_var_init.vhd ivltests # This refers to a signal in a parent scope that is driven by a constant, # which hits the unhandled out_of_scope_drive clause in emit_nexus_as_ca. vhdl_range_func TE,-g2005-sv,-pallowsigned=1,ivltests/vhdl_range_func_pkg.vhd,ivltests/vhdl_range_func.vhd, ivltests # This casts a signed value to a larger size (requiring sign extension, then uses # the cast value in an unsigned expression with an even larger width (requiring # zero padding. I can't think how to do this in standard Verilog without using # an intermediate variable. size_cast4 EF,-g2009,-pallowsigned=1 ivltests # Similarly, this needs an intermediate variable assignment to produce the # correct result. br_gh219 EF,-g2009,-pallowsigned=1 ivltests # This has a gate output connected to a VP part select. The translator # creates a CA for the part select, but has nothing to connect it to. # It leaves the gate output unconnected. rise_fall_decay2 CE ivltests # The code generator is generating unnecessary calls to $unsigned. array_packed_2d normal,-g2009,-pallowsigned=1 ivltests gold=array_packed_2d.gold br_gh112c normal,-g2009,-pallowsigned=1 ivltests br_gh112d normal,-g2009,-pallowsigned=1 ivltests # This generates a very larg (65536 bit) constant, and the parser can't cope. br_gh162 TE ivltests # New tests that need to be looked at go here. vhdl_concat_func EF,-g2005-sv,-pallowsigned=1,ivltests/vhdl_concat_func.vhd ivltests vhdl_resize EF,-g2005-sv,-pallowsigned=1,ivltests/vhdl_resize.vhd ivltests # Size (spacing) difference since -4 is used for the second value. # Should this be $signed() if it is not an integer? pr2159630 EF,-pallowsigned=1 ivltests gold=pr2159630.gold # No support for most Verilog-A constructs analog1 CE,-gverilog-ams ivltests analog2 CE,-gverilog-ams ivltests # These tests have generate scopes that are not currently supported. br955 CE ivltests br988 CE ivltests br_gh345 CE ivltests br_gh567 CE,-g2001,-pallowsigned=1 ivltests br_gh568 CE,-g2009,-pallowsigned=1 ivltests br_gh621 CE ivltests # Also automatic tasks complex_lidx CE ivltests defparam3 CE ivltests defparam4 CE ivltests gen_case_opt1 CE ivltests gen_case_opt2 CE ivltests gen_case_opt3 CE ivltests genloop CE ivltests generate_case CE ivltests generate_case2 CE ivltests generate_case3 CE ivltests genvar_inc_dec CE,-g2009 ivltests # also integer arrays genvar_compressed CE,-g2009 ivltests # also integer arrays packeda2 CE,-g2009,-pallowsigned=1 ivltests pr1565699b CE ivltests pr1623097 CE ivltests pr1676071 CE ivltests pr1691599b CE ivltests pr1695309 CE ivltests pr1704726b CE ivltests pr1755629 CE ivltests pr1828642 CE ivltests pr1956211 CE ivltests pr1960625 CE ivltests pr1988302 CE ivltests pr1988310 CE ivltests pr2018235a CE ivltests pr2091455 CE ivltests pr2109179 CE ivltests pr2138682 CE ivltests pr2257003 CE ivltests pr2257003b CE ivltests pr2306259 CE ivltests pr2350934 CE ivltests pr2350934b CE ivltests pr2350988 CE ivltests pr2355304 CE ivltests pr2728812a CE ivltests pr2815398a CE ivltests pr2815398a_std CE ivltests pr2909414 CE ivltests pr2924354 CE ivltests pr3011327 CE ivltests pr3409749 CE ivltests pr3437290b CE ivltests pr3527694 CE ivltests pr3534422 CE ivltests pr3557493 CE ivltests scoped_events CE ivltests sv_packed_port1 CE,-g2009 ivltests sv_packed_port2 CE,-g2009 ivltests br_gh433 CE,-g2009,-pallowsigned=1 ivltests sv_queue1 CE,-g2009,-pallowsigned=1 ivltests sv_queue2 CE,-g2009,-pallowsigned=1 ivltests sv_queue3 CE,-g2009 ivltests sv_queue_method_signed1 CE,-g2009,-pallowsigned=1 ivltests sv_queue_method_signed2 CE,-g2009,-pallowsigned=1 ivltests sv_queue_method_signed3 CE,-g2009,-pallowsigned=1 ivltests sv_queue_method_signed4 CE,-g2009,-pallowsigned=1 ivltests sv_queue_real CE,-g2009 ivltests sv_queue_real_bounded CE,-g2009 ivltests sv_queue_real_fail CE,-g2009 ivltests sv_queue_string CE,-g2009 ivltests sv_queue_string_bounded CE,-g2009 ivltests sv_queue_string_fail CE,-g2009 ivltests sv_queue_vec CE,-g2009,-pallowsigned=1 ivltests sv_queue_vec_bounded CE,-g2009,-pallowsigned=1 ivltests sv_queue_vec_fail CE,-g2009,-pallowsigned=1 ivltests sv_queue_parray CE,-g2009, ivltests sv_queue_parray_bounded CE,-g2009, ivltests sv_queue_parray_fail CE,-g2009, ivltests test_forgen CE,-g2009,ivltests/forgen.vhd ivltests test_gxor CE,-g2009,-pallowsigned=1,ivltests/gxor.vhd ivltests test_varray1 CE,-g2009,-pallowsigned=1,ivltests/varray1.vhd ivltests unnamed_generate_block CE ivltests # Currently part selects in a CA with a non-zero base are not supported. always_ff_warn_sens CE,-g2009 ivltests bitsel6 CE ivltests bitsel7 CE ivltests pr3054101a CE ivltests pr3054101b CE ivltests # Currently variable indexed part selects in a CA with a non-zero base are not supported. pr2835632b CE ivltests # Also scale expr. problems pr3054101c CE ivltests pr3054101d CE,-pallowsigned=1 ivltests pr3054101e CE ivltests # Also scale expr. problems pr3054101f CE ivltests # Also scale expr. problems signed_part CE,-pallowsigned=1 ivltests # Currently no support for tran_VP (inout ports and tranif gates). bitsel10 CE ivltests # Also uses a logic bufif0 br918c CE ivltests # Also uses a logic pullup br965 CE ivltests br_gh127b CE ivltests br_gh127c CE ivltests br_gh127e CE ivltests br_gh127f CE ivltests br_gh315 CE,-gspecify ivltests br_gh316c CE,-gspecify ivltests br_gh356a CE,-gspecify ivltests br_gh356b CE,-gspecify ivltests countdrivers3 CE ivltests # also uses a logic bufif1 inout TE ivltests # Duplicate names inout2 CE ivltests inout3 CE ivltests inout4 CE ivltests pr1444055 CE ivltests pr1478121 CE ivltests pr2219441 CE ivltests pr3296466a CE ivltests pr3296466b CE ivltests # Also some nexus problems. pr3296466d CE ivltests rise_fall_delay3 CE ivltests # Uses tranif1 gates tri2 CE ivltests # The Icarus compiler does not support arrayed UDP instance. These are # created in the synthesis process. basicexpr TE,-S ivltests basicstate TE,-S ivltests basicstate2 TE,-S ivltests br993a TE,-S ivltests br993b TE,-S ivltests br994 TE,-S ivltests br_gh99v TE,-S ivltests br_gh99w TE,-S ivltests br_gh99x TE,-S ivltests casesynth1 TE,-S ivltests casesynth2 TE,-S ivltests casesynth3 TE,-S ivltests casesynth7 TE,-S ivltests conditsynth1 TE,-S ivltests conditsynth2 TE,-S ivltests conditsynth3 TE,-S ivltests dffsynth6 TE,-S ivltests dffsynth9 TE,-S ivltests dffsynth10 TE,-S ivltests inside_synth2 TE,-S ivltests multireg TE,-S ivltests shiftl TE,-S ivltests ufuncsynth1 TE,-S ivltests pr685 TE,-S ivltests # The translator doesn't currently support multi-bit asynchronous set values. # These are created in the synthesis process. dffsynth7 CE,-S ivltests dffsynth11 CE,-S ivltests sqrt32synth CE,-S ivltests # The converter generates a complex expression for $strobe and Icarus does not # currently support this. The translation is correct. pr1830834 EF ivltests # This test relies on variable initialisation occurring before any other # process runs. Check that it at least compiles cleanly. vhdl_loop CO,-g2005-sv,-pallowsigned=1,ivltests/vhdl_loop.vhd ivltests # These tests have different output because of file name/line, etc. differences. br916a normal ivltests gold=br916a-vlog95.gold br916b normal ivltests gold=br916b-vlog95.gold br1003b normal,-g2009 ivltests gold=br1003b-vlog95.gold br1003c normal,-g2009 ivltests gold=br1003c-vlog95.gold br1003d normal,-g2009 ivltests gold=br1003d-vlog95.gold br1007 normal,-Wselect-range ivltests gold=br1007-vlog95.gold br_gh230 RE ivltests gold=br_gh230-vlog95.gold eofmt_percent normal ivltests gold=eofmt_percent-vlog95.gold fatal_et_al normal ivltests gold=fatal_et_al-vlog95.gold fdisplay3 RE ivltests gold=fdisplay3-vlog95.gold fdisplay_fail_fd normal ivltests gold=fdisplay_fail_fd-vlog95.gold fdisplay_fail_mcd normal ivltests gold=fdisplay_fail_mcd-vlog95.gold format RE ivltests gold=format-vlog95.gold fread-error RE ivltests gold=fread-error-vlog95.gold fscanf_u_warn normal ivltests gold=fscanf_u_warn-vlog95.gold fscanf_z_warn normal ivltests gold=fscanf_z_warn-vlog95.gold localparam_type normal ivltests gold=parameter_type-vlog95.gold parameter_type normal ivltests gold=parameter_type-vlog95.gold mem1 normal ivltests gold=mem1-vlog95.gold pic normal contrib gold=pic-vlog95.gold pr910 normal ivltests gold=pr910-vlog95.gold pr1698820 normal ivltests gold=pr1698820-vlog95.gold pr1819452 normal ivltests gold=pr1819452-vlog95.gold pr2509349a normal ivltests gold=pr2509349a-vlog95.gold pr2509349b normal ivltests gold=pr2509349b-vlog95.gold pr2800985b RE ivltests gold=pr2800985b-vlog95.gold queue_fail RE ivltests gold=queue_fail-vlog95.gold readmem-invalid RE ivltests gold=readmem-invalid-vlog95.gold # Because the lower module has a parameter it is given a unique name that # does not match what the code is looking for. If we can verify that there # is only a single instance or that the instance has the original or at # least all the instances have the same value we may be able to use the # original name. simparam EF ivltests sv_immediate_assert normal,-g2009 ivltests gold=sv_immediate_assert-vlog95.gold sv_immediate_assume normal,-g2009 ivltests gold=sv_immediate_assume-vlog95.gold swrite normal ivltests gold=swrite-vlog95.gold sys_func_task_error RE ivltests gold=sys_func_task_error-vlog95.gold # In Verilog 95 a system function cannot be called as a task. sys_func_as_task RE,-g2009 ivltests warn_opt_sys_tf RE ivltests gold=warn_opt_sys_tf-vlog95.gold writemem-error normal ivltests gold=writemem-error-vlog95.gold writemem-invalid RE ivltests gold=writemem-invalid-vlog95.gold # For Verilog 95 signed is supported as an option (-pallowsigned=1). array6 normal,-pallowsigned=1 ivltests assign_op_oob normal,-g2009,-pallowsigned=1 ivltests assign_op_type normal,-g2009,-pallowsigned=1 ivltests bitp1 normal,-g2009,-pallowsigned=1 ivltests bits normal,-g2009,-pallowsigned=1 ivltests bits2 normal,-g2009,-pallowsigned=1 ivltests br884 normal,-g2009,-pallowsigned=1 ivltests br917a normal,-g2009,-pallowsigned=1 ivltests br917b normal,-g2009,-pallowsigned=1 ivltests br917c normal,-g2009,-pallowsigned=1 ivltests br917d normal,-g2009,-pallowsigned=1 ivltests br943_944 normal,-g2009,-pallowsigned=1,ivltests/br943_944.vhd ivltests br985 normal,-g2009,-pallowsigned=1,ivltests/br985.vhd ivltests br1025 normal,-g2009,-pallowsigned=1 ivltests br_gh8 normal,-pallowsigned=1 ivltests br_gh99c normal,-gverilog-ams,-pallowsigned=1 ivltests br_gh99r normal,-pallowsigned=1 ivltests br_gh112e normal,-g2009,-pallowsigned=1 ivltests br_gh112f normal,-g2009,-pallowsigned=1 ivltests br_gh129 normal,-g2009,-pallowsigned=1 ivltests br_gh130b normal,-g2009,-pallowsigned=1 ivltests br_gh198 normal,-pallowsigned=1 ivltests gold=br_gh198.gold br_gh199a normal,-pallowsigned=1 ivltests br_gh199b normal,-pallowsigned=1 ivltests br_gh231 normal,-g2009,-pallowsigned=1 ivltests br_gh281 normal,-g2009,-pallowsigned=1 ivltests br_gh281b normal,-g2009,-pallowsigned=1 ivltests br_gh283a normal,-pallowsigned=1 ivltests br_gh283b normal,-pallowsigned=1 ivltests br_gh283c normal,-pallowsigned=1 ivltests br_gh289b normal,-g2009,-pallowsigned=1 ivltests br_gh386d normal,-g2009,-pallowsigned=1 ivltests br_gh477 normal,-g2009,-pallowsigned=1 ivltests br_gh540 normal,-g2009,-pallowsigned=1 ivltests ca_mult normal,-pallowsigned=1 ivltests gold=ca_mult.gold cast_int normal,-pallowsigned=1 ivltests cast_int_ams normal,-gverilog-ams,-pallowsigned=1 ivltests cfunc_assign_op_vec normal,-g2009,-pallowsigned=1 ivltests constfunc4 normal,-pallowsigned=1 ivltests constfunc4_ams normal,-gverilog-ams,-pallowsigned=1 ivltests constfunc6 normal,-pallowsigned=1 ivltests constfunc6_ams normal,-pallowsigned=1 ivltests constfunc7 normal,-pallowsigned=1 ivltests constfunc13 normal,-pallowsigned=1 ivltests constfunc14 normal,-pallowsigned=1 ivltests enum_base_atom2 normal,-g2005-sv,-pallowsigned=1 ivltests enum_base_none normal,-g2005-sv,-pallowsigned=1 ivltests enum_elem_ranges normal,-g2009,-pallowsigned=1 ivltests enum_value_expr normal,-g2009,-pallowsigned=1 ivltests enum_values normal,-g2009,-pallowsigned=1 ivltests enum_ports normal,-g2005-sv,-pallowsigned=1 ivltests extend normal,-pallowsigned=1 ivltests first_last_num normal,-g2009,-pallowsigned=1 ivltests fr49 normal,-g2009,-pallowsigned=1 ivltests function12 normal,-g2005-sv,-pallowsigned=1 ivltests gold=function12.gold implicit_cast7 normal,-g2009,-pallowsigned=1 ivltests implicit_cast9 normal,-g2009,-pallowsigned=1 ivltests inc_dec_stmt normal,-g2009,-pallowsigned=1 ivltests int_param normal,-g2009,-pallowsigned=1 ivltests iuint1 normal,-g2009,-pallowsigned=1 ivltests logp2 normal,-g2009,-pallowsigned=1 ivltests mixed_width_case normal,-pallowsigned=1 ivltests mod_inst_pkg normal,-g2009,-pallowsigned=1 ivltests module_nonansi_int1 normal,-g2005-sv,-pallowsigned=1 ivltests module_nonansi_int2 normal,-g2005-sv,-pallowsigned=1 ivltests module_output_port_sv_var1 normal,-g2005-sv,-pallowsigned=1 ivltests module_output_port_sv_var2 normal,-g2005-sv,-pallowsigned=1 ivltests module_output_port_var1 normal,-pallowsigned=1 ivltests module_output_port_var2 normal,-pallowsigned=1 ivltests packeda normal,-g2009,-pallowsigned=1 ivltests pr1033 normal,-pallowsigned=1 ivltests gold=pr1033.gold pr1380261 normal,-pallowsigned=1 ivltests pr1494799 normal,-pallowsigned=1 ivltests gold=pr1494799.gold pr1589497 normal,-pallowsigned=1 ivltests gold=pr1589497.gold pr1603313 normal,-pallowsigned=1 ivltests pr1717361 normal,-pallowsigned=1 ivltests pr1719055 normal,-pallowsigned=1 ivltests gold=pr1719055.gold pr1793749 normal,-pallowsigned=1 ivltests gold=pr1793749.gold pr1879226 normal,-pallowsigned=1 ivltests pr1883052 normal,-pallowsigned=1 ivltests pr1883052b normal,-pallowsigned=1 ivltests pr1950282 normal,-pallowsigned=1 ivltests pr1958801 normal,-pallowsigned=1 ivltests pr1993479 normal,-pallowsigned=1 ivltests gold=pr1993479.gold pr2030767 normal,-pallowsigned=1 ivltests pr2117473 normal,-pallowsigned=1 ivltests pr2121536 normal,-pallowsigned=1 ivltests pr2121536b normal,-pallowsigned=1 ivltests pr2152011 normal,-pallowsigned=1 ivltests gold=pr2152011.gold pr2233180 normal,-pallowsigned=1 ivltests pr2233180b normal,-pallowsigned=1 ivltests pr2233180c normal,-pallowsigned=1 ivltests pr2233192 normal,-pallowsigned=1 ivltests pr2233192b normal,-pallowsigned=1 ivltests pr2233192c normal,-pallowsigned=1 ivltests pr2425055b normal,-pallowsigned=1 ivltests pr2425055c normal,-pallowsigned=1 ivltests pr2722330a normal,-pallowsigned=1 ivltests pr2722330b normal,-pallowsigned=1 ivltests pr2909555 normal,-pallowsigned=1 ivltests pr2913416 normal,-pallowsigned=1 ivltests pr2913438b normal,-pallowsigned=1 ivltests pr2922063 normal,-pallowsigned=1 ivltests pr2922063a normal,-pallowsigned=1 ivltests pr2922063b normal,-pallowsigned=1 ivltests pr2986528 normal,-pallowsigned=1 ivltests pr2998515 normal,-pallowsigned=1 ivltests pr3104254 normal,-pallowsigned=1 ivltests pr3284821 normal,-pallowsigned=1 ivltests pr3292735 normal,-pallowsigned=1 ivltests pr3366217e normal,-g2009,-pallowsigned=1 ivltests pr748 normal,-pallowsigned=1 ivltests pull371 normal,-g2009,-pallowsigned=1 ivltests pull371b normal,-g2009,-pallowsigned=1 ivltests sf1289 normal,-g2009,-pallowsigned=1 ivltests shift2 normal,-pallowsigned=1 ivltests shift3 normal,-pallowsigned=1 ivltests shift5 normal,-pallowsigned=1 ivltests gold=shift5.gold signed1 normal,-pallowsigned=1 ivltests signed4 normal,-pallowsigned=1 ivltests gold=signed4.gold signed6 normal,-pallowsigned=1 ivltests signed7 normal,-pallowsigned=1 ivltests signed8 normal,-pallowsigned=1 ivltests signed9 normal,-pallowsigned=1 ivltests signed12 normal,-pallowsigned=1 ivltests gold=signed12.gold signed_a normal,-pallowsigned=1 ivltests signed_pv normal,-pallowsigned=1 ivltests simple_byte normal,-g2009,-pallowsigned=1 ivltests simple_int normal,-g2009,-pallowsigned=1 ivltests simple_longint normal,-g2009,-pallowsigned=1 ivltests simple_shortint normal,-g2009,-pallowsigned=1 ivltests size_cast3 normal,-g2009,-pallowsigned=1 ivltests size_cast5 normal,-g2009,-pallowsigned=1 ivltests struct_member_signed normal,-g2009,-pallowsigned=1 ivltests struct_packed_array normal,-g2009,-pallowsigned=1 ivltests struct_packed_array2 normal,-g2009,-pallowsigned=1 ivltests struct_packed_sysfunct2 normal,-g2009,-pallowsigned=1 ivltests struct_signed normal,-g2009,-pallowsigned=1 ivltests sv_for_variable normal,-g2009,-pallowsigned=1 ivltests sv_foreach1 normal,-g2009,-pallowsigned=1 ivltests sv_foreach5 normal,-g2009,-pallowsigned=1 ivltests sv_foreach6 normal,-g2009,-pallowsigned=1 ivltests sv_foreach7 normal,-g2009,-pallowsigned=1 ivltests sv_foreach8 normal,-g2009,-pallowsigned=1 ivltests sv_package normal,-g2009,-pallowsigned=1 ivltests sv_package2 normal,-g2009,-pallowsigned=1 ivltests sv_package5 normal,-g2009,-pallowsigned=1 ivltests sv_port_default10 normal,-g2009,-pallowsigned=1 ivltests sv_port_default11 normal,-g2009,-pallowsigned=1 ivltests sv_root_func normal,-g2009,-pallowsigned=1 ivltests gold=sv_root_func.gold sv_root_task normal,-g2009,-pallowsigned=1 ivltests gold=sv_root_task.gold sv_var_block normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_for normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_function normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_module normal,-g2005-sv,-pallowsigned=1 ivltests # Inputs can not be reg in Verilog 95, so the translated code will fail sv_var_module_input1 TE,-g2005-sv,-pallowsigned=1 ivltests sv_var_module_input2 TE,-g2005-sv,-pallowsigned=1 ivltests sv_var_module_output1 normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_module_output2 normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_package normal,-g2005-sv,-pallowsigned=1 ivltests sv_var_task normal,-g2005-sv,-pallowsigned=1 ivltests sv_void_cast4 normal,-g2009,-pallowsigned=1 ivltests test_dispwided normal,-pallowsigned=1 ivltests gold=test_dispwided.gold test_inc_dec normal,-g2009,-pallowsigned=1 ivltests test_enumsystem normal,-g2009,-pallowsigned=1,ivltests/enumsystem.vhd ivltests vhdl_boolean normal,-g2009,-pallowsigned=1,ivltests/vhdl_boolean.vhd ivltests vhdl_file_open normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_file_open.vhd ivltests vhdl_prefix_array normal,-g2009,-pallowsigned=1,ivltests/vhdl_prefix_array.vhd ivltests vhdl_range normal,-g2009,-pallowsigned=1,ivltests/vhdl_range_pkg.vhd,ivltests/vhdl_range.vhd ivltests vhdl_range_func normal,-g2009,-pallowsigned=1,ivltests/vhdl_range_func_pkg.vhd,ivltests/vhdl_range_func.vhd ivltests vhdl_rtoi normal,-g2009,-pallowsigned=1,ivltests/vhdl_rtoi.vhd ivltests vhdl_shift normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_shift.vhd ivltests vhdl_to_integer normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_to_integer.vhd ivltests test_system normal,-g2009,-pallowsigned=1,ivltests/system.vhd ivltests test_tliteral normal,-g2009,-pallowsigned=1 ivltests vhdl_test8 normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_test8.vhd ivltests vhdl_test9 normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_test9.vhd ivltests two_state_display normal,-g2009,-pallowsigned=1 ivltests gold=two_state_display.gold undefined_shift normal,-pallowsigned=1 ivltests vams_abs1 normal,-gverilog-ams,-pallowsigned=1 ivltests vhdl_concurrent_assert normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_concurrent_assert.vhd ivltests gold=vhdl_concurrent_assert.gold vhdl_const_record normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_const_record.vhd ivltests vhdl_delay_assign normal,-g2005-sv,-pallowsigned=1,-fivltests/vhdl_timescale_1ns.cfg,ivltests/vhdl_delay_assign.vhd ivltests vhdl_elab_range normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_elab_range.vhd ivltests vhdl_image_attr normal,-g2005-sv,-pallowsigned=1,-fivltests/vhdl_timescale_1ns.cfg,ivltests/vhdl_image_attr.vhd ivltests gold=vhdl_image_attr.gold vhdl_process_scope normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_process_scope.vhd ivltests vhdl_sadd23_bit normal,-g2009,-pallowsigned=1,ivltests/vhdl_sadd23_bit.vhd ivltests vhdl_sdiv23_bit normal,-g2009,-pallowsigned=1,ivltests/vhdl_sdiv23_bit.vhd ivltests vhdl_ssub23_bit normal,-g2009,-pallowsigned=1,ivltests/vhdl_ssub23_bit.vhd ivltests vhdl_smul23_bit normal,-g2009,-pallowsigned=1,ivltests/vhdl_smul23_bit.vhd ivltests vhdl_sadd23_stdlogic normal,-g2009,-pallowsigned=1,ivltests/vhdl_sadd23_stdlogic.vhd ivltests vhdl_sdiv23_stdlogic normal,-g2009,-pallowsigned=1,ivltests/vhdl_sdiv23_stdlogic.vhd ivltests vhdl_ssub23_stdlogic normal,-g2009,-pallowsigned=1,ivltests/vhdl_ssub23_stdlogic.vhd ivltests vhdl_smul23_stdlogic normal,-g2009,-pallowsigned=1,ivltests/vhdl_smul23_stdlogic.vhd ivltests vhdl_test3 normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_test3.vhd ivltests gold=vhdl_test3.gold vhdl_report normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_report_pkg.vhd,ivltests/vhdl_report.vhd ivltests gold=vhdl_report.gold vhdl_subprogram normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_subprogram_pkg.vhd,ivltests/vhdl_subprogram.vhd ivltests vhdl_subtypes normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_subtypes_pkg.vhd,ivltests/vhdl_subtypes.vhd ivltests vhdl_unary_minus normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_unary_minus.vhd ivltests vhdl_unbounded_func normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_unbounded_func_pkg.vhd,ivltests/vhdl_unbounded_func.vhd ivltests vhdl_var_init normal,-g2009,-pallowsigned=1,ivltests/vhdl_var_init.vhd ivltests vhdl_while normal,-g2005-sv,-pallowsigned=1,ivltests/vhdl_while.vhd ivltests # $signed() and $unsigned() in the compiler are always supported and they # are supported in general if the -pallowsigned=1 flag is provided. br919 normal,-pallowsigned=1 ivltests br968 normal,-pallowsigned=1 ivltests concat3 normal,-pallowsigned=1 ivltests l_equiv normal,-g2005-sv,-pallowsigned=1 ivltests l_equiv_ca normal,-g2005-sv,-pallowsigned=1 ivltests mult2 normal,-pallowsigned=1 ivltests pr757 normal,-pallowsigned=1 ivltests pr1002 normal,-pallowsigned=1 ivltests gold=pr1002.gold pr1002a normal,-pallowsigned=1 ivltests gold=pr1002a.gold pr1522570 normal,-pallowsigned=1 ivltests pr1698499 normal,-pallowsigned=1 ivltests gold=pr1698499.gold pr1793749b normal,-pallowsigned=1 ivltests gold=pr1793749b.gold pr1795005a normal,-pallowsigned=1 ivltests gold=pr1795005a.gold pr1795005b normal,-pallowsigned=1 ivltests gold=pr1795005b.gold pr1823732 normal,-pallowsigned=1 ivltests gold=pr1823732.gold pr1841300 normal,-pallowsigned=1,-gno-io-range-error ivltests gold=pr1841300.gold pr1845683 normal,-pallowsigned=1 ivltests gold=pr1845683.gold pr1960558 normal,-pallowsigned=1 ivltests gold=pr1960558.gold pr1960619 normal,-pallowsigned=1,-gno-io-range-error ivltests gold=pr1960619.gold pr1963240 normal,-pallowsigned=1 ivltests gold=pr1963240.gold pr1990164 normal,-pallowsigned=1 ivltests pr2136787 normal,-pallowsigned=1 ivltests gold=pr2136787.gold pr2138979 normal,-pallowsigned=1 ivltests pr2138979b normal,-pallowsigned=1 ivltests gold=pr2138979b.gold pr2138979c normal,-pallowsigned=1 ivltests gold=pr2138979c.gold # This one still has CA $signed() problems. The $signed() is not added when # the value is not sign extended. pr2138979d EF,-pallowsigned=1 ivltests gold=pr2138979d.gold pr2722339a normal,-pallowsigned=1 ivltests pr2722339b normal,-pallowsigned=1 ivltests pr2901556 normal,-pallowsigned=1 ivltests pr2913404 normal,-pallowsigned=1 ivltests pr3077640 normal,-pallowsigned=1 ivltests select_padding normal,-pallowsigned=1 ivltests shift4 normal,-pallowsigned=1 ivltests signed5 normal,-pallowsigned=1 ivltests signed10 normal,-pallowsigned=1 ivltests gold=signed10.gold signed13 normal,-pallowsigned=1 ivltests sv_sign_cast1 normal,-g2005-sv,-pallowsigned=1 ivltests sv_sign_cast2 normal,-g2005-sv,-pallowsigned=1 ivltests sv_sign_cast3 normal,-g2005-sv,-pallowsigned=1 ivltests # Also tests have different output because of file name/line, etc. differences. readmem-error normal,-pallowsigned=1 ivltests gold=readmem-error-vlog95.gold # Translating a down index part select require -pallowsigned=1 to get the # index calculation to be 100% correct when the select expression is not # already signed. param_select3 normal,-pallowsigned=1 ivltests select5 normal,-pallowsigned=1 ivltests # Translating a parameter with the LSB > MSB requires -pallowsigned=1 to get # the index calculation correct. pr487 normal,-pallowsigned=1 ivltests gold=pr487.gold # Support for greater than 32 bit integer constants is an Icarus extension. # If the -pallowsigned=1 flag is given then they can be converted correctly. big_int normal,-pallowsigned=1 ivltests pr2673846 normal,-pallowsigned=1 ivltests pr2029336 normal,-pallowsigned=1 ivltests diff=work/pr2029336.out:gold/pr2029336.gold urand normal,-pallowsigned=1 ivltests gold=urand.gold # The synthesized caseZ compare is not supported. casesynth6 normal ivltests # Tests that require 4-state dynamic arrays #unp_array_typedef CE,-g2005-sv ivltests #sv_darray_word_size CE,-g2005-sv,-pallowsigned=1 ivltests #sv_darray_function CE,-g2005-sv,-pallowsigned=1 ivltests # Priority and unique case statements are converted to ordinary case # statements, so no warnings are generated. case_priority normal,-g2009 ivltests gold=case_priority-vlog95.gold case_unique normal,-g2009 ivltests gold=case_unique-vlog95.gold # An error is reported for both compiler passes br_gh377 normal,-Ptest.name= ivltests gold=br_gh377-vlog95.gold iverilog-12_0/ivtest/src/000077500000000000000000000000001435245347300154545ustar00rootroot00000000000000iverilog-12_0/ivtest/src/alloca.h000066400000000000000000000013761435245347300170670ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #ifndef VCD_ALLOCA_H #define VCD_ALLOCA_H #include /* * if your system really doesn't have alloca() at all, * you can force functionality by using malloc * instead. but note that you're going to have some * memory leaks because of it. you have been warned. */ #ifdef _MSC_VER #define alloca _alloca #endif #ifndef __sun__ #ifndef alloca #define alloca __alloca #endif #else #include #endif #define wave_alloca alloca #endif iverilog-12_0/ivtest/src/analyzer.h000066400000000000000000000034501435245347300174540ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #ifndef VCD_ANALYZER_H #define VCD_ANALYZER_H #include #include #include "alloca.h" #include "debug.h" typedef struct Node *nptr; typedef struct HistEnt *hptr; typedef struct Bits *bptr; typedef struct VectorEnt *vptr; typedef struct BitVector *bvptr; typedef unsigned long Ulong; typedef unsigned int Uint; typedef struct HistEnt { hptr next; /* next transition in history */ TimeType time; /* time of transition */ unsigned char flags; /* so far only set on glitch/real condition */ union { unsigned char val; /* value: "0XZ1"[val] */ char *vector; /* pointer to a whole vector */ } v; } HistEnt; enum HistEntFlagBits { HIST_GLITCH_B, HIST_REAL_B, HIST_STRING_B }; #define HIST_GLITCH (1<time; if((obj<=key)&&(obj>max_compare_time)) { max_compare_time=obj; max_compare_pos=cpos; max_compare_index=(hptr *)s2; } delta=key-obj; if(delta<0) rv=-1; else if(delta>0) rv=1; else rv=0; return(rv); } hptr bsearch_node(nptr n, TimeType key) { max_compare_time=-2; max_compare_pos=NULL; max_compare_index=NULL; bsearch(&key, n->harray, n->numhist, sizeof(hptr), compar_histent); if((!max_compare_pos)||(max_compare_time<0)) { max_compare_pos=n->harray[1]; /* aix bsearch fix */ max_compare_index=&(n->harray[1]); } return(max_compare_pos); } /*****************************************************************************************/ static int compar_facs(const void *key, const void *v2) { struct symbol *s2; int rc; s2=*((struct symbol **)v2); rc=sigcmp((char *)key,s2->name); return(rc); } struct symbol *bsearch_facs(struct globals *obj, char *ascii) { struct symbol **rc; if ((!ascii)||(!strlen(ascii))) return(NULL); rc=(struct symbol **)bsearch(ascii, obj->facs, obj->numfacs, sizeof(struct symbol *), compar_facs); if(rc) return(*rc); else return(NULL); } iverilog-12_0/ivtest/src/bsearch.h000066400000000000000000000011301435245347300172270ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #ifndef VCD_BSEARCH_NODES_VECTORS_H #define VCD_BSEARCH_NODES_VECTORS_H #include "globals.h" hptr bsearch_node(nptr n, TimeType key); vptr bsearch_vector(bvptr b, TimeType key); char *bsearch_trunc(char *ascii, int maxlen); struct symbol *bsearch_facs(struct globals *obj, char *ascii); #endif iverilog-12_0/ivtest/src/debug.c000066400000000000000000000064151435245347300167140ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ /* * debug.c 01feb99ajb * malloc debugs added on 13jul99ajb */ #include "debug.h" #define DEB_FAIL 333 #undef free_2 #ifdef DEBUG_MALLOC /* normally this should be undefined..this is *only* for finding stray allocations/frees */ static struct memchunk *mem=NULL; static size_t mem_total=0; static int mem_chunks=0; static void mem_addnode(void *ptr, size_t size) { struct memchunk *m; m=(struct memchunk *)malloc(sizeof(struct memchunk)); m->ptr=ptr; m->size=size; m->next=mem; mem=m; mem_total+=size; mem_chunks++; fprintf(stderr,"mem_addnode: TC:%05d TOT:%010d PNT:%010p LEN:+%d\n",mem_chunks,mem_total,ptr,size); } static void mem_freenode(void *ptr) { struct memchunk *m, *mprev=NULL; m=mem; while(m) { if(m->ptr==ptr) { if(mprev) { mprev->next=m->next; } else { mem=m->next; } mem_total=mem_total-m->size; mem_chunks--; fprintf(stderr,"mem_freenode: TC:%05d TOT:%010d PNT:%010p LEN:-%d\n",mem_chunks,mem_total,ptr,m->size); free(m); return; } mprev=m; m=m->next; } fprintf(stderr,"mem_freenode: PNT:%010p *INVALID*\n",ptr); sleep(1); } #endif /* * wrapped malloc family... */ void *malloc_2(size_t size) { void *ret; ret=malloc(size); if(ret) { DEBUG_M(mem_addnode(ret,size)); return(ret); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(DEB_FAIL); } } void *realloc_2(void *ptr, size_t size) { void *ret; ret=realloc(ptr, size); if(ret) { DEBUG_M(mem_freenode(ptr)); DEBUG_M(mem_addnode(ret,size)); return(ret); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(DEB_FAIL); } } void *calloc_2(size_t nmemb, size_t size) { void *ret; ret=calloc(nmemb, size); if(ret) { DEBUG_M(mem_addnode(ret, nmemb*size)); return(ret); } else { fprintf(stderr, "FATAL ERROR: Out of memory, sorry.\n"); exit(DEB_FAIL); } } #ifdef DEBUG_MALLOC_LINES void free_2(void *ptr, char *filename, int lineno) { if(ptr) { DEBUG_M(mem_freenode(ptr)); free(ptr); } else { fprintf(stderr, "WARNING: Attempt to free NULL pointer caught: \"%s\", line %d.\n", filename, lineno); } } #else void free_2(void *ptr) { if(ptr) { DEBUG_M(mem_freenode(ptr)); free(ptr); } else { fprintf(stderr, "WARNING: Attempt to free NULL pointer caught.\n"); } } #endif /* * atoi 64-bit version.. * y/on default to '1' * n/nonnum default to '0' */ char *atoi_cont_ptr=NULL; TimeType atoi_64(char *str) { TimeType val=0; unsigned char ch, nflag=0; atoi_cont_ptr=NULL; switch(*str) { case 'y': case 'Y': return(LLDescriptor(1)); case 'o': case 'O': str++; ch=*str; if((ch=='n')||(ch=='N')) return(LLDescriptor(1)); else return(LLDescriptor(0)); case 'n': case 'N': return(LLDescriptor(0)); break; default: break; } while((ch=*(str++))) { if((ch>='0')&&(ch<='9')) { val=(val*10+(ch&15)); } else if((ch=='-')&&(val==0)&&(!nflag)) { nflag=1; } else if(val) { atoi_cont_ptr=str-1; break; } } return(nflag?(-val):val); } iverilog-12_0/ivtest/src/debug.h000066400000000000000000000041241435245347300167140ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000 * * 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. */ #ifndef VCD_DEBUG_H #define VCD_DEBUG_H #include #include #include struct memchunk { struct memchunk *next; void *ptr; size_t size; }; /* * If you have problems viewing traces (mangled timevalues), * make sure that you use longs rather than the glib 64-bit * types... */ #ifdef G_HAVE_GINT64 typedef gint64 TimeType; typedef guint64 UTimeType; #ifndef _MSC_VER #define LLDescriptor(x) x##LL #define ULLDescriptor(x) x##ULL #define TTFormat "%lld" #define UTTFormat "%llu" #else #define LLDescriptor(x) x##i64 #define ULLDescriptor(x) x##i64 #define TTFormat "%I64d" #define UTTFormat "%I64u" #endif #define WAVE_MINZOOM (LLDescriptor(-4000000000)) #else typedef long TimeType; typedef unsigned long UTimeType; #define TTFormat "%d" #define UTTFormat "%u" #define LLDescriptor(x) x #define ULLDescriptor(x) x #define WAVE_MINZOOM (LLDescriptor(-20000000)) #endif #ifdef DEBUG_PRINTF #define DEBUG(x) x #else #define DEBUG(x) #endif #ifdef DEBUG_MALLOC #define DEBUG_M(x) x #else #define DEBUG_M(x) #endif #ifdef DEBUG_MALLOC_LINES void free_2(void *ptr, char *filename, int lineno); #define free_2(x) free_2((x),__FILE__,__LINE__) #else void free_2(void *ptr); #endif void *malloc_2(size_t size); void *realloc_2(void *ptr, size_t size); void *calloc_2(size_t nmemb, size_t size); TimeType atoi_64(char *str); extern char *atoi_cont_ptr; /* for unformat_time()'s parse continue for the time unit */ #undef WAVE_USE_SIGCMP_INFINITE_PRECISION /* define this for slow sigcmp with infinite digit accuracy */ #define WAVE_OPT_SKIP 1 /* make larger for more accel on traces */ #endif iverilog-12_0/ivtest/src/globals.c000066400000000000000000000030121435245347300172370ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #include "globals.h" #include "misc.h" struct globals *make_vcd_class(void) { struct globals *g; g=(struct globals *)calloc_2(1, sizeof(struct globals)); g->sym=NULL; g->facs=NULL; g->facs_are_sorted=0; g->numfacs=0; g->regions=0; g->longestname=0; g->firstnode=NULL; g->curnode=NULL; g->hier_delimeter='.'; g->autocoalesce=1; g->vcd_explicit_zero_subscripts=-1; g->convert_to_reals=0; g->atomic_vectors=1; g->vcd_handle=NULL; g->vcd_is_compressed=0; g->vcdbyteno=0; g->header_over=0; g->dumping_off=0; g->start_time=-1; g->end_time=-1; g->current_time=-1; g->time_scale=1; g->count_glitches=0; g->num_glitches=0; g->num_glitch_regions=0; g->vcd_hier_delimeter[0]=0; g->vcd_hier_delimeter[1]=0; g->pv=NULL; g->rootv=NULL; g->slistroot=NULL; g->slistcurr=NULL; g->slisthier=NULL; g->slisthier_len=0; g->T_MAX_STR=1024; g->yytext=NULL; g->yylen=0; g->yylen_cache=0; g->vcdsymroot=NULL; g->vcdsymcurr=NULL; g->sorted=NULL; g->numsyms=0; g->he_curr=NULL; g->he_fini=NULL; g->vcdbuf=NULL; g->vst=NULL; g->vend=NULL; g->varsplit=NULL; g->vsplitcurr=NULL; g->var_prevch=0; g->currenttime=0; g->max_time=0; g->min_time=-1; g->time_dimension='n'; g->sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); return(g); } iverilog-12_0/ivtest/src/globals.h000066400000000000000000000035011435245347300172470ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #ifndef WAVE_GLOBALS_H #define WAVE_GLOBALS_H #include #include #include #include #include "alloca.h" #include "debug.h" struct globals { struct symbol **sym; struct symbol **facs; char facs_are_sorted; int numfacs; int regions; int longestname; struct symbol *firstnode; /* 1st sym in aet */ struct symbol *curnode; /* current loaded sym in aet loader */ char hier_delimeter; char autocoalesce; int vcd_explicit_zero_subscripts; /* 0=yes, -1=no */ char convert_to_reals; char atomic_vectors; FILE *vcd_handle; char vcd_is_compressed; int vcdbyteno; /* really should be size_t, but this is only used for debugging mangled traces */ int header_over; int dumping_off; TimeType start_time; TimeType end_time; TimeType current_time; TimeType time_scale; /* multiplier is 1, 10, 100 */ int count_glitches; /* set to 1 if we want to enable glitch code */ int num_glitches; int num_glitch_regions; char vcd_hier_delimeter[2]; /* fill in after rc reading code */ struct vcdsymbol *pv, *rootv; struct slist *slistroot, *slistcurr; char *slisthier; int slisthier_len; int T_MAX_STR; /* was originally a const..now it reallocs */ char *yytext; int yylen, yylen_cache; struct vcdsymbol *vcdsymroot, *vcdsymcurr; struct vcdsymbol **sorted; int numsyms; struct HistEnt *he_curr, *he_fini; char *vcdbuf, *vst, *vend; char *varsplit, *vsplitcurr; int var_prevch; TimeType currenttime, max_time, min_time; char time_dimension; }; struct globals *make_vcd_class(void); #endif iverilog-12_0/ivtest/src/main.c000066400000000000000000000074521435245347300165540ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000 * * 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. */ /* * vcdiff.c 12apr00 ajb */ #include #include "misc.h" #include "globals.h" #include "vcd.h" int compare_symbols(TimeType max0, TimeType max1, struct symbol *s0, struct symbol *s1) { hptr h0, h1; TimeType t0, t1; int rc=0; h0=&(s0->n->head); h1=&(s1->n->head); if(!s0->n->ext) { /* bit case */ while((h0)&&(h1)) { t0=h0->time; t1=h1->time; if((t0>max0)||(t1>max0)||(t0>max1)||(t1>max1)) break; if (h0->v.val!=h1->v.val) { fprintf(stdout, "*** '%s' value mismatch: "TTFormat"='%c' vs "TTFormat"='%c'\n", s0->name, h0->time, "0xz1"[h0->v.val], h1->time, "0xz1"[h1->v.val]); rc+=1; } if((h0->next)&&(h1->next)) { if(t0==t1) { h0=h0->next; h1=h1->next; } else if(t0next; } else { h1=h1->next; } continue; } else { return(rc); } } } else { /* vec case */ while((h0)&&(h1)) { t0=h0->time; t1=h1->time; if((t0>max0)||(t1>max0)||(t0>max1)||(t1>max1)) break; if ((h0->time>=0)&&(h1->time>=0)) if ((h0->flags&(HIST_REAL|HIST_STRING))==(h1->flags&(HIST_REAL|HIST_STRING))) { if((h0->flags&HIST_REAL)&&(!(h0->flags&HIST_STRING))) { if(*((double *)h0->v.vector)!=*((double *)h1->v.vector)) { fprintf(stdout, "*** '%s' value mismatch: "TTFormat"='%f' vs "TTFormat"='%f'\n", s0->name, h0->time, *((double *)h0->v.vector), h1->time, *((double *)h1->v.vector)); rc+=1; } } else { if((h0->v.vector)&&(h1->v.vector)) { if(strcmp(h0->v.vector, h1->v.vector)) { fprintf(stdout, "*** '%s' value mismatch: "TTFormat"='%s' vs "TTFormat"='%s'\n", s0->name, h0->time, h0->v.vector, h1->time, h1->v.vector); rc+=1; } } } } if((h0->next)&&(h1->next)) { if(t0==t1) { h0=h0->next; h1=h1->next; } else if(t0next; } else { h1=h1->next; } continue; } else { return(rc); } } } return(rc); } /* * the meat and potatoes... */ int main(int argc, char **argv) { int i, j; struct globals *v[2]; int warnings=0; if(argc<3) { fprintf(stderr, "Usage\n-----\n"); fprintf(stderr, "%s file1 file2\n\n",argv[0]); fprintf(stderr,"Using -vcd as a filename accepts input from stdin.\n"); exit(VCD_FAIL); } if((!strcmp("-vcd",argv[1]))&&(!strcmp("-vcd",argv[2]))) { fprintf(stderr, "Can only accept stdin input for one file, exiting\n"); exit(VCD_FAIL); } for(i=0;i<2;i++) { v[i]=make_vcd_class(); vcd_main(v[i],argv[i+1]); fprintf(stdout,"\n"); } if((v[0]->numfacs)!=(v[1]->numfacs)) { fprintf(stdout, "*** Number of symbols differ: %d vs %d.\n\n",v[0]->numfacs, v[1]->numfacs); warnings++; } for(i=0;i<2;i++) { for(j=0;jnumfacs;j++) { struct symbol *as; as=symfind(v[1-i],v[i]->facs[j]->name); if(!as) { fprintf(stdout, "*** '%s' not found in '%s'\n",v[i]->facs[j]->name, argv[2-i]); warnings++; } else { struct ExtNode *en0, *en1; en0=v[i]->facs[j]->n->ext; en1=as->n->ext; if( ((!en0)&&(!en1)) || ( ((en0)&&(en1)) && (en0->msi==en1->msi) && (en0->lsi==en1->lsi) ) ) { v[i]->facs[j]->altsym=as; } else { fprintf(stdout, "*** '%s' size/direction mismatch\n", v[i]->facs[j]->name); warnings++; } } } } for(j=0;jnumfacs;j++) { struct symbol *s, *as; s=v[0]->facs[j]; as=s->altsym; if(as) { warnings+=compare_symbols(v[0]->max_time, v[1]->max_time, s, as); } } printf("\nEncountered %d warnings, exiting.\n",warnings); exit(warnings?VCD_FAIL:0); } iverilog-12_0/ivtest/src/misc.c000066400000000000000000000100751435245347300165560ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #include "misc.h" #include "bsearch.h" /* * Generic hash function for symbol names... */ int hash(char *s) { char *p; unsigned int h=0, g; for(p=s;*p;p++) { h=(h<<4)+(*p); if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } return(h%SYMPRIME); } /* * add symbol to table. no duplicate checking * is necessary as aet's are "correct." */ struct symbol *symadd(struct globals *obj, char *name, int hv) { struct symbol *s; s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); strcpy(s->name=(char *)malloc_2(strlen(name)+1),name); s->next=obj->sym[hv]; obj->sym[hv]=s; return(s); } /* * find a slot already in the table... */ struct symbol *symfind(struct globals *obj, char *s) { int hv; struct symbol *temp; if(!obj->facs_are_sorted) { hv=hash(s); if(!(temp=obj->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } else /* no sense hashing if the facs table is built */ { DEBUG(printf("BSEARCH: %s\n",s)); return(bsearch_facs(obj, s)); } } /* * compares two facilities a la strcmp but preserves * numbers for comparisons * * there are two flavors..the slow and accurate to any * arbitrary number of digits version (first) and the * fast one good to 2**31-1. we default to the faster * version since there's probably no real need to * process ints larger than two billion anyway... */ #ifdef WAVE_USE_SIGCMP_INFINITE_PRECISION int sigcmp(char *s1, char *s2) { char *n1, *n2; unsigned char c1, c2; int len1, len2; for(;;) { c1=(unsigned char)*s1; c2=(unsigned char)*s2; if((c1==0)&&(c2==0)) return(0); if((c1>='0')&&(c1<='9')&&(c2>='0')&&(c2<='9')) { n1=s1; n2=s2; len1=len2=0; do { len1++; c1=(unsigned char)*(n1++); } while((c1>='0')&&(c1<='9')); if(!c1) n1--; do { len2++; c2=(unsigned char)*(n2++); } while((c2>='0')&&(c2<='9')); if(!c2) n2--; do { if(len1==len2) { c1=(unsigned char)*(s1++); len1--; c2=(unsigned char)*(s2++); len2--; } else if(len1='0')&&(c1>='0')) { u1=(int)(c1&15); u2=(int)(c2&15); while(((c2=(unsigned char)*s2)>='0')&&(c2<='9')) { u2*=10; u2+=(unsigned int)(c2&15); s2++; } while(((c2=(unsigned char)*s1)>='0')&&(c2<='9')) { u1*=10; u1+=(unsigned int)(c2&15); s1++; } if(u1==u2) continue; else return((int)u1-(int)u2); } else { if(c1!=c2) return((int)c1-(int)c2); } } } #endif /* * Quicksort algorithm from p154 of * "Introduction to Algorithms" by Cormen, Leiserson, and Rivest. * 05-jul-97bsi */ int partition(struct symbol **a, int p, int r) { struct symbol *x, *t; int i,j; x=a[p]; i=p-1; j=r+1; while(1) { do { j--; } while(sigcmp(a[j]->name,x->name)>0); do { i++; } while(sigcmp(a[i]->name,x->name)<0); if(i #include #include #include #include "alloca.h" #include "analyzer.h" #include "debug.h" #include "globals.h" #define SYMPRIME 4093 #define WAVE_DECOMPRESSOR "gzip -cd " /* zcat alone doesn't cut it for AIX */ struct symbol { struct symbol *altsym; /* points to sym in alt vcd file */ struct symbol *nextinaet;/* for aet node chaining */ struct HistEnt *h; /* points to previous one */ struct symbol *vec_root, *vec_chain; struct symbol *next; /* for hash chain */ char *name; struct Node *n; }; struct symbol *symfind(struct globals *, char *); struct symbol *symadd(struct globals *, char *, int); int hash(char *s); int sigcmp(char *, char *); void quicksort(struct symbol **, int, int); extern struct symbol **sym, **facs; extern char facs_are_sorted; extern int numfacs; extern int regions; extern struct symbol *firstnode; extern struct symbol *curnode; extern int longestname; extern char hier_delimeter; #endif iverilog-12_0/ivtest/src/vcd.c000066400000000000000000001215131435245347300163770ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * more profiler optimizations 25jan00ajb * finsim parameter fix 26jan00ajb * vector rechaining code 03apr00ajb * multiple var section code 06apr00ajb * stripped from gtkwave 09apr00ajb */ #include "vcd.h" #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ /******************************************************************/ static void add_histent(struct globals *obj, TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(struct globals *obj); static void vcd_build_symbols(struct globals *obj); static void vcd_cleanup(struct globals *obj); static void evcd_strcpy(char *dst, char *src); /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_EOF, T_STRING, T_UNKNOWN_KEY }; char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "", "", "" }; #define NUM_TOKENS 18 #define T_GET(x) tok=get_token(x);if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ enum VarTypes { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_END, V_LB, V_COLON, V_RB, V_STRING }; char *vartypes[]={ "event", "parameter", "integer", "real", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "$end", "", "", "", ""}; #define NUM_VTOKENS 19 /******************************************************************/ /* * histent structs are NEVER freed so this is OK.. */ #define VCD_HISTENT_GRANULARITY 100 static struct HistEnt *histent_calloc(struct globals *obj) { if(obj->he_curr==obj->he_fini) { obj->he_curr=(struct HistEnt *)calloc_2(VCD_HISTENT_GRANULARITY, sizeof(struct HistEnt)); obj->he_fini=obj->he_curr+VCD_HISTENT_GRANULARITY; } return(obj->he_curr++); } /******************************************************************/ static struct queuedevent *queuedevents=NULL; /******************************************************************/ /* * bsearch compare */ static int vcdsymbsearchcompare(const void *s1, const void *s2) { char *v1; struct vcdsymbol *v2; v1=(char *)s1; v2=*((struct vcdsymbol **)s2); return(strcmp(v1, v2->id)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(struct globals *obj, char *key) { struct vcdsymbol **v; struct vcdsymbol *t; v=(struct vcdsymbol **)bsearch(key, obj->sorted, obj->numsyms, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==obj->sorted)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * create sorted (by id) table */ static void create_sorted_table(struct globals *obj) { struct vcdsymbol *v; struct vcdsymbol **pnt; if(obj->sorted) { free_2(obj->sorted); /* this means we saw a 2nd enddefinition chunk! */ } if(obj->numsyms) { pnt=obj->sorted=(struct vcdsymbol **)calloc_2(obj->numsyms, sizeof(struct vcdsymbol *)); v=obj->vcdsymroot; while(v) { *(pnt++)=v; v=v->next; } qsort(obj->sorted, obj->numsyms, sizeof(struct vcdsymbol *), vcdsymcompare); } } /******************************************************************/ /* * single char get inlined/optimized */ static void getch_alloc(struct globals *obj) { obj->vend=obj->vst=obj->vcdbuf=(char *)calloc_2(1,VCD_BSIZ); } static void getch_free(struct globals *obj) { free_2(obj->vcdbuf); obj->vcdbuf=obj->vst=obj->vend=NULL; } static int getch_fetch(struct globals *obj) { size_t rd; if(feof(obj->vcd_handle)||errno) return(-1); obj->vcdbyteno+=(obj->vend-obj->vcdbuf); rd=fread(obj->vcdbuf, sizeof(char), VCD_BSIZ, obj->vcd_handle); obj->vend=(obj->vst=obj->vcdbuf)+rd; if(!rd) return(-1); return((int)(*(obj->vst++))); } #define getch(x) ((x->vst!=x->vend)?((int)(*(x->vst++))):(getch_fetch(x))) static int getch_patched(struct globals *obj) { char ch; ch=*obj->vsplitcurr; if(!ch) { return(-1); } else { obj->vsplitcurr++; return((int)ch); } } /* * simple tokenizer */ static int get_token(struct globals *obj) { int ch; int i, len=0; int is_string=0; for(;;) { ch=getch(obj); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { obj->yytext[len++]=ch; for(;;) { ch=getch(obj); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(obj->yytext[len++]=ch;;obj->yytext[len++]=ch) { if(len==obj->T_MAX_STR) { obj->yytext=(char *)realloc_2(obj->yytext, (obj->T_MAX_STR=obj->T_MAX_STR*2)+1); } ch=getch(obj); if(ch<=' ') break; } obj->yytext[len]=0; /* terminator */ if(is_string) { obj->yylen=len; return(T_STRING); } for(i=0;iyytext+1,tokens[i])) { return(i); } } return(T_UNKNOWN_KEY); } static int get_vartoken_patched(struct globals *obj) { int ch; int i, len=0; if(!obj->var_prevch) { for(;;) { ch=getch_patched(obj); if(ch<0) { free_2(obj->varsplit); obj->varsplit=NULL; return(V_END); } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=obj->var_prevch; obj->var_prevch=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); for(obj->yytext[len++]=ch;;obj->yytext[len++]=ch) { if(len==obj->T_MAX_STR) { obj->yytext=(char *)realloc_2(obj->yytext, (obj->T_MAX_STR=obj->T_MAX_STR*2)+1); } ch=getch_patched(obj); if(ch<0) break; if((ch==':')||(ch==']')) { obj->var_prevch=ch; break; } } obj->yytext[len]=0; /* terminator */ for(i=0;iyytext,vartypes[i])) { if(ch<0) { free_2(obj->varsplit); obj->varsplit=NULL; } return(i); } } obj->yylen=len; if(ch<0) { free_2(obj->varsplit); obj->varsplit=NULL; } return(V_STRING); } static int get_vartoken(struct globals *obj) { int ch; int i, len=0; if(obj->varsplit) { int rc=get_vartoken_patched(obj); if(rc!=V_END) return(rc); obj->var_prevch=0; } if(!obj->var_prevch) { for(;;) { ch=getch(obj); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=obj->var_prevch; obj->var_prevch=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); for(obj->yytext[len++]=ch;;obj->yytext[len++]=ch) { if(len==obj->T_MAX_STR) { obj->yytext=(char *)realloc_2(obj->yytext, (obj->T_MAX_STR=obj->T_MAX_STR*2)+1); } ch=getch(obj); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(obj->yytext[0]!='\\')) { obj->varsplit=obj->yytext+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!obj->varsplit)&&(obj->yytext[0]!='\\')) { obj->var_prevch=ch; break; } } obj->yytext[len]=0; /* absolute terminator */ if((obj->varsplit)&&(obj->yytext[len-1]==']')) { char *vst; vst=malloc_2(strlen(obj->varsplit)+1); strcpy(vst, obj->varsplit); *obj->varsplit=0x00; /* zero out var name at the left bracket */ len=obj->varsplit-obj->yytext; obj->varsplit=obj->vsplitcurr=vst; obj->var_prevch=0; } else { obj->varsplit=NULL; } for(i=0;iyytext,vartypes[i])) { return(i); } } obj->yylen=len; return(V_STRING); } static int get_strtoken(struct globals *obj) { int ch; int len=0; if(!obj->var_prevch) { for(;;) { ch=getch(obj); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=obj->var_prevch; obj->var_prevch=0; } for(obj->yytext[len++]=ch;;obj->yytext[len++]=ch) { if(len==obj->T_MAX_STR) { obj->yytext=(char *)realloc_2(obj->yytext, (obj->T_MAX_STR=obj->T_MAX_STR*2)+1); } ch=getch(obj); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; } obj->yytext[len]=0; /* terminator */ obj->yylen=len; return(V_STRING); } static void sync_end(struct globals *obj, char *hdr) { int tok; if(hdr) DEBUG(fprintf(stderr,"%s",hdr)); for(;;) { tok=get_token(obj); if((tok==T_END)||(tok==T_EOF)) break; if(hdr)DEBUG(fprintf(stderr," %s",yytext)); } if(hdr) DEBUG(fprintf(stderr,"\n")); } static char *build_slisthier(struct globals *obj) { struct slist *s; int len=0; if(!obj->slistroot) { if(obj->slisthier) { free_2(obj->slisthier); } obj->slisthier_len=0; obj->slisthier=(char *)malloc_2(1); *obj->slisthier=0; return(obj->slisthier); } s=obj->slistroot; len=0; while(s) { len+=s->len+(s->next?1:0); s=s->next; } obj->slisthier=(char *)malloc_2((obj->slisthier_len=len)+1); s=obj->slistroot; len=0; while(s) { strcpy(obj->slisthier+len,s->str); len+=s->len; if(s->next) { strcpy(obj->slisthier+len,obj->vcd_hier_delimeter); len++; } s=s->next; } return(obj->slisthier); } void append_vcd_slisthier(struct globals *obj, char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(obj->slistcurr) { obj->slistcurr->next=s; obj->slistcurr=s; } else { obj->slistcurr=obj->slistroot=s; } build_slisthier(obj); DEBUG(fprintf(stderr, "SCOPE: %s\n",obj->slisthier)); } static void parse_valuechange(struct globals *obj) { struct vcdsymbol *v; char *vector; int vlen; switch(obj->yytext[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': if(obj->yylen>1) { v=bsearch_vcd(obj, obj->yytext+1); if(!v) { fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf),obj->yytext+1); } else { if(v->vartype!=V_EVENT) { v->value[0]=obj->yytext[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); add_histent(obj, obj->current_time,v->narray[0],v->value[0],1, NULL); } else { v->value[0]=(obj->dumping_off)?'x':'1'; /* only '1' is relevant */ if(obj->current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(obj, v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } DEBUG(fprintf(stderr,"%s = '%c' (event)\n",v->name,v->value[0])); add_histent(obj, obj->current_time,v->narray[0],v->value[0],1, NULL); v->ev->last_event_time=obj->current_time; } } } else { fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", obj->vcdbyteno+(obj->vst-obj->vcdbuf)); } break; case 'b': case 'B': { /* extract binary number then.. */ vector=malloc_2(obj->yylen_cache=obj->yylen); strcpy(vector,obj->yytext+1); vlen=obj->yylen-1; get_strtoken(obj); v=bsearch_vcd(obj, obj->yytext); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(vector); } else { if((obj->convert_to_reals)&&(v->vartype==V_REAL)) { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(d); } else { add_histent(obj, obj->current_time, v->narray[0],'g',1,(char *)d); } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!obj->atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(obj, obj->current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(obj->yylen_cache!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(obj, obj->current_time, v->narray[0],0,1,vector); } } break; } case 'p': /* extract port dump value.. */ vector=malloc_2(obj->yylen_cache=obj->yylen); strcpy(vector,obj->yytext+1); vlen=obj->yylen-1; get_strtoken(obj); /* throw away 0_strength_component */ get_strtoken(obj); /* throw away 0_strength_component */ get_strtoken(obj); /* this is the id */ v=bsearch_vcd(obj, obj->yytext); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(vector); } else { if((obj->convert_to_reals)&&(v->vartype==V_REAL)) /* should never happen, but just in case.. */ { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(d); } else { add_histent(obj, obj->current_time, v->narray[0],'g',1,(char *)d); } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!obj->atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(obj, obj->current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(obj->yylen_cachesize) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(obj, obj->current_time, v->narray[0],0,1,vector); } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); sscanf(obj->yytext+1,"%lg",d); get_strtoken(obj); v=bsearch_vcd(obj, obj->yytext); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(d); } else { add_histent(obj, obj->current_time, v->narray[0],'g',1,(char *)d); } break; } #ifndef STRICT_VCD_ONLY case 's': case 'S': { char *d; d=(char *)malloc_2(obj->yylen); strcpy(d, obj->yytext+1); get_strtoken(obj); v=bsearch_vcd(obj, obj->yytext); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf), obj->yytext); free_2(d); } else { add_histent(obj, obj->current_time, v->narray[0],'s',1,(char *)d); } break; } #endif } } static void evcd_strcpy(char *dst, char *src) { static char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static char *vcd="01xz0101xz0101xzxxxxxxx"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(struct globals *obj) { int tok; for(;;) { switch(tok=get_token(obj)) { case T_COMMENT: sync_end(obj, "COMMENT:"); break; case T_DATE: sync_end(obj, "DATE:"); break; case T_VERSION: sync_end(obj, "VERSION:"); break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; vtok=get_token(obj); if((vtok==T_END)||(vtok==T_EOF)) break; obj->time_scale=atoi_64(obj->yytext); if(!obj->time_scale) obj->time_scale=1; for(i=0;iyylen;i++) { if((obj->yytext[i]<'0')||(obj->yytext[i]>'9')) { prefix=obj->yytext[i]; break; } } if(prefix==' ') { vtok=get_token(obj); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=obj->yytext[0]; } switch(prefix) { case ' ': case 'm': case 'u': case 'n': case 'p': case 'f': obj->time_dimension=prefix; break; case 's': obj->time_dimension=' '; break; default: /* unknown */ obj->time_dimension='n'; break; } DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",obj->time_scale, obj->time_dimension)); sync_end(obj, NULL); } break; case T_SCOPE: T_GET(obj); T_GET(obj); if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=obj->yylen; s->str=(char *)malloc_2(obj->yylen+1); strcpy(s->str,obj->yytext); if(obj->slistcurr) { obj->slistcurr->next=s; obj->slistcurr=s; } else { obj->slistcurr=obj->slistroot=s; } build_slisthier(obj); DEBUG(fprintf(stderr, "SCOPE: %s\n",obj->slisthier)); } sync_end(obj, NULL); break; case T_UPSCOPE: if(obj->slistroot) { struct slist *s; s=obj->slistroot; if(!s->next) { free_2(s->str); free_2(s); obj->slistroot=obj->slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; obj->slistcurr=s; break; } s=s->next; } build_slisthier(obj); DEBUG(fprintf(stderr, "SCOPE: %s\n",obj->slisthier)); } sync_end(obj, NULL); break; case T_VAR: if((obj->header_over)&&(0)) { fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n",obj->vcdbyteno+(obj->vst-obj->vcdbuf)); exit(VCD_FAIL); } else { int vtok; struct vcdsymbol *v=NULL; obj->var_prevch=0; obj->varsplit=NULL; vtok=get_vartoken(obj); if(vtok>V_PORT) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=obj->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(obj); if(vtok==V_STRING) { v->size=atoi_64(obj->yytext); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(obj); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(obj->yytext); vtok=get_vartoken(obj); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(obj); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(obj->yytext); vtok=get_vartoken(obj); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(obj); if(vtok==V_END) goto err; v->id=(char *)malloc_2(obj->yylen+1); strcpy(v->id, obj->yytext); vtok=get_vartoken(obj); if(vtok!=V_STRING) goto err; if(obj->slisthier_len) { v->name=(char *)malloc_2(obj->slisthier_len+1+obj->yylen+1); strcpy(v->name,obj->slisthier); strcpy(v->name+obj->slisthier_len,obj->vcd_hier_delimeter); strcpy(v->name+obj->slisthier_len+1,obj->yytext); } else { v->name=(char *)malloc_2(obj->yylen+1); strcpy(v->name,obj->yytext); } if(obj->pv) { if(!strcmp(obj->pv->name,v->name)) { obj->pv->chain=v; v->root=obj->rootv; if(obj->pv==obj->rootv) obj->pv->root=obj->rootv; } else { obj->rootv=v; } } else { obj->rootv=v; } obj->pv=v; } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(obj); if(vtok==V_END) goto err; v->size=atoi_64(obj->yytext); if(!v->size) v->size=1; vtok=get_strtoken(obj); if(vtok==V_END) goto err; v->id=(char *)malloc_2(obj->yylen+1); strcpy(v->id, obj->yytext); vtok=get_vartoken(obj); if(vtok!=V_STRING) goto err; if(obj->slisthier_len) { v->name=(char *)malloc_2(obj->slisthier_len+1+obj->yylen+1); strcpy(v->name,obj->slisthier); strcpy(v->name+obj->slisthier_len,obj->vcd_hier_delimeter); strcpy(v->name+obj->slisthier_len+1,obj->yytext); } else { v->name=(char *)malloc_2(obj->yylen+1); strcpy(v->name,obj->yytext); } if(obj->pv) { if(!strcmp(obj->pv->name,v->name)) { obj->pv->chain=v; v->root=obj->rootv; if(obj->pv==obj->rootv) obj->pv->root=obj->rootv; } else { obj->rootv=v; } } else { obj->rootv=v; } obj->pv=v; vtok=get_vartoken(obj); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(obj); if(vtok!=V_STRING) goto err; v->msi=atoi_64(obj->yytext); vtok=get_vartoken(obj); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(obj); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(obj->yytext); vtok=get_vartoken(obj); if(vtok!=V_RB) goto err; } dumpv: if((v->vartype==V_REAL)||((obj->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { v->vartype=V_REAL; v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) goto err; v->size=v->msi-v->lsi+1; } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) goto err; v->size=v->msi-v->lsi+1; } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; if(obj->atomic_vectors) { for(i=0;isize;i++) { v->value[i]='x'; } v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[0]->head.time=-1; v->narray[0]->head.v.val=1; } else { for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.val=1; } } } if(v->vartype==V_EVENT) { struct queuedevent *q; v->ev=q=(struct queuedevent *)calloc_2(1,sizeof(struct queuedevent)); q->sym=v; q->last_event_time=-1; q->next=queuedevents; queuedevents=q; } if(!obj->vcdsymroot) { obj->vcdsymroot=obj->vcdsymcurr=v; } else { obj->vcdsymcurr->next=v; obj->vcdsymcurr=v; } obj->numsyms++; DEBUG(fprintf(stderr,"VAR %s %d %s %s[%d:%d]\n", vartypes[v->vartype], v->size, v->id, v->name, v->msi, v->lsi)); goto bail; err: if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); } bail: if(vtok!=V_END) sync_end(obj, NULL); break; } case T_ENDDEFINITIONS: obj->header_over=1; /* do symbol table management here */ create_sorted_table(obj); if(!obj->sorted) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(VCD_FAIL); } break; case T_STRING: if(obj->header_over) { /* catchall for events when header over */ if(obj->yytext[0]=='#') { TimeType time; time=atoi_64(obj->yytext+1); if(obj->start_time<0) { obj->start_time=time; } obj->current_time=time; if(obj->end_timeend_time=time; /* in case of malformed vcd files */ DEBUG(fprintf(stderr,"#"TTFormat"\n",time)); } else { parse_valuechange(obj); } } break; case T_DUMPALL: /* dump commands modify vals anyway so */ case T_DUMPPORTSALL: break; /* just loop through.. */ case T_DUMPOFF: case T_DUMPPORTSOFF: obj->dumping_off=1; break; case T_DUMPON: case T_DUMPPORTSON: obj->dumping_off=0; break; case T_DUMPVARS: case T_DUMPPORTS: break; case T_VCDCLOSE: break; /* next token will be '#' time related followed by $end */ case T_END: /* either closure for dump commands or */ break; /* it's spurious */ case T_UNKNOWN_KEY: sync_end(obj, NULL); /* skip over unknown keywords */ break; case T_EOF: return; default: DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n")); } } } /*******************************************************************************/ void add_histent(struct globals *obj, TimeType time, struct Node *n, char ch, int regadd, char *vector) { struct HistEnt *he; char heval; if(!vector) { if(!n->curr) { he=histent_calloc(obj); he->time=-1; he->v.val=1; n->curr=he; n->head.next=he; add_histent(obj, time,n,ch,regadd, vector); } else { if(regadd) { time*=(obj->time_scale); } if(ch=='0') heval=0; else if(ch=='1') heval=3; else if((ch=='x')||(ch=='X')) heval=1; else heval=2; if((n->curr->v.val!=heval)||(time==obj->start_time)) /* same region == go skip */ { if((n->curr->time==time)&&(obj->count_glitches)) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", time, n, "0XZ1"[n->curr->v.val], ch)); n->curr->v.val=heval; /* we have a glitch! */ obj->num_glitches++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ obj->num_glitch_regions++; } } else { he=histent_calloc(obj); he->time=time; he->v.val=heval; n->curr->next=he; n->curr=he; obj->regions+=regadd; } } } } else { switch(ch) { case 's': /* string */ { if(!n->curr) { he=histent_calloc(obj); he->flags=(HIST_STRING|HIST_REAL); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(obj, time,n,ch,regadd, vector); } else { if(regadd) { time*=(obj->time_scale); } if((n->curr->time==time)&&(obj->count_glitches)) { DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n", time, n)); if(n->curr->v.vector) free_2(n->curr->v.vector); n->curr->v.vector=vector; /* we have a glitch! */ obj->num_glitches++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ obj->num_glitch_regions++; } } else { he=histent_calloc(obj); he->flags=(HIST_STRING|HIST_REAL); he->time=time; he->v.vector=vector; n->curr->next=he; n->curr=he; obj->regions+=regadd; } } break; } case 'g': /* real number */ { if(!n->curr) { he=histent_calloc(obj); he->flags=HIST_REAL; he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(obj, time,n,ch,regadd, vector); } else { if(regadd) { time*=(obj->time_scale); } if( (n->curr->v.vector&&vector&&(*(double *)n->curr->v.vector!=*(double *)vector)) ||(time==obj->start_time) ||(!n->curr->v.vector) ) /* same region == go skip */ { if((n->curr->time==time)&&(obj->count_glitches)) { DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n", time, n)); if(n->curr->v.vector) free_2(n->curr->v.vector); n->curr->v.vector=vector; /* we have a glitch! */ obj->num_glitches++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ obj->num_glitch_regions++; } } else { he=histent_calloc(obj); he->flags=HIST_REAL; he->time=time; he->v.vector=vector; n->curr->next=he; n->curr=he; obj->regions+=regadd; } } else { free_2(vector); } } break; } default: { if(!n->curr) { he=histent_calloc(obj); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(obj, time,n,ch,regadd, vector); } else { if(regadd) { time*=(obj->time_scale); } if( (n->curr->v.vector&&vector&&(strcmp(n->curr->v.vector,vector))) ||(time==obj->start_time) ||(!n->curr->v.vector) ) /* same region == go skip */ { if((n->curr->time==time)&&(obj->count_glitches)) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", time, n, "0XZ1"[n->curr->v.val], ch)); if(n->curr->v.vector) free_2(n->curr->v.vector); n->curr->v.vector=vector; /* we have a glitch! */ obj->num_glitches++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ obj->num_glitch_regions++; } } else { he=histent_calloc(obj); he->time=time; he->v.vector=vector; n->curr->next=he; n->curr=he; obj->regions+=regadd; } } else { free_2(vector); } } break; } } } } static void add_tail_histents(struct globals *obj) { int i,j; /* dump out any pending events 1st */ struct queuedevent *q; q=queuedevents; while(q) { struct vcdsymbol *v; v=q->sym; if(obj->current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(obj, v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } q=q->next; } /* then do 'x' trailers */ for(i=0;inumsyms;i++) { struct vcdsymbol *v; v=obj->sorted[i]; if(v->vartype==V_REAL) { double *d; d=malloc_2(sizeof(double)); *d=1.0; add_histent(obj, MAX_HISTENT_TIME-1, v->narray[0], 'g', 0, (char *)d); } else if((v->size==1)||(!obj->atomic_vectors)) for(j=0;jsize;j++) { add_histent(obj, MAX_HISTENT_TIME-1, v->narray[j], 'x', 0, NULL); } else { add_histent(obj, MAX_HISTENT_TIME-1, v->narray[0], 'x', 0, (char *)calloc_2(1,sizeof(char))); } } for(i=0;inumsyms;i++) { struct vcdsymbol *v; v=obj->sorted[i]; if(v->vartype==V_REAL) { double *d; d=malloc_2(sizeof(double)); *d=0.0; add_histent(obj, MAX_HISTENT_TIME, v->narray[0], 'g', 0, (char *)d); } else if((v->size==1)||(!obj->atomic_vectors)) for(j=0;jsize;j++) { add_histent(obj, MAX_HISTENT_TIME, v->narray[j], 'z', 0, NULL); } else { add_histent(obj, MAX_HISTENT_TIME, v->narray[0], 'z', 0, (char *)calloc_2(1,sizeof(char))); } } } /*******************************************************************************/ static void vcd_build_symbols(struct globals *obj) { int i,j; int max_slen=-1; struct sym_chain *sym_chain=NULL, *sym_curr=NULL; for(i=0;inumsyms;i++) { struct vcdsymbol *v, *vprime; int msi; int delta; { char *str; int slen; int substnode; v=obj->sorted[i]; msi=v->msi; delta=((v->lsi-v->msi)<0)?-1:1; substnode=0; slen=strlen(v->name); str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */ strcpy(str,v->name); if(v->msi>=0) { strcpy(str+slen,obj->vcd_hier_delimeter); slen++; } if((vprime=bsearch_vcd(obj, v->id))!=v) /* hash mish means dup net */ { if(v->size!=vprime->size) { fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name); } else { substnode=1; } } if(((v->size==1)||(!obj->atomic_vectors))&&(v->vartype!=V_REAL)) { struct symbol *s; for(j=0;jsize;j++) { if(v->msi>=0) { if(!obj->vcd_explicit_zero_subscripts) sprintf(str+slen,"%d",msi); else sprintf(str+slen-1,"[%d]",msi); } if(!symfind(obj, str)) { s=symadd(obj, str,hash(str)); s->n=v->narray[j]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[j]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; } s->n->nname=s->name; s->h=s->n->curr; if(!obj->firstnode) { obj->firstnode=obj->curnode=s; } else { obj->curnode->nextinaet=s; obj->curnode=s; } obj->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } else { fprintf(stderr,"Warning: %s is a duplicate net name.\n",str); } msi+=delta; } if((j==1)&&(v->root)) { s->vec_root=(struct symbol *)v->root; /* these will get patched over */ s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */ v->sym_chain=s; if(!sym_chain) { sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_chain=sym_curr; } else { sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_curr=sym_curr->next; } sym_curr->val=s; } } else /* atomic vector */ { if(v->vartype!=V_REAL) { sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi); } else { *(str+slen-1)=0; } if(!symfind(obj, str)) { struct symbol *s; s=symadd(obj, str,hash(str)); s->n=v->narray[0]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[0]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; n->ext=n2->ext; } else { struct ExtNode *en; en=(struct ExtNode *)malloc_2(sizeof(struct ExtNode)); en->msi=v->msi; en->lsi=v->lsi; s->n->ext=en; } s->n->nname=s->name; s->h=s->n->curr; if(!obj->firstnode) { obj->firstnode=obj->curnode=s; } else { obj->curnode->nextinaet=s; obj->curnode=s; } obj->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } else { fprintf(stderr,"Warning: %s is a duplicate net name.\n",str); } } } } if(sym_chain) { sym_curr=sym_chain; while(sym_curr) { sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain; if ((struct vcdsymbol *)sym_curr->val->vec_chain) sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain; DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)")); sym_chain=sym_curr; sym_curr=sym_curr->next; free_2(sym_chain); } } } /*******************************************************************************/ void vcd_sortfacs(struct globals *obj) { int i; obj->facs=(struct symbol **)malloc_2(obj->numfacs*sizeof(struct symbol *)); obj->curnode=obj->firstnode; for(i=0;inumfacs;i++) { char *subst, ch; int len; obj->facs[i]=obj->curnode; if((len=strlen(subst=obj->curnode->name))>obj->longestname) obj->longestname=len; obj->curnode=obj->curnode->nextinaet; while((ch=(*subst))) { if(ch==obj->hier_delimeter) { *subst=0x01; } /* forces sort at hier boundaries */ subst++; } } quicksort(obj->facs,0,obj->numfacs-1); for(i=0;inumfacs;i++) { char *subst, ch; subst=obj->facs[i]->name; while((ch=(*subst))) { if(ch==0x01) { *subst=obj->hier_delimeter; } /* restore back to normal */ subst++; } #ifdef DEBUG_FACILITIES printf("%-4d %s\n",i,obj->facs[i]->name); #endif } obj->facs_are_sorted=1; } /*******************************************************************************/ static void vcd_cleanup(struct globals *obj) { int i; struct slist *s, *s2; if(obj->sorted) { for(i=0;inumsyms;i++) { struct vcdsymbol *v; v=obj->sorted[i]; if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); if(v->ev) free_2(v->ev); if(v->narray) free_2(v->narray); free_2(v); } } free_2(obj->sorted); obj->sorted=NULL; } if(obj->slisthier) { free_2(obj->slisthier); obj->slisthier=NULL; } s=obj->slistroot; while(s) { s2=s->next; if(s->str)free_2(s->str); free_2(s); s=s2; } obj->slistroot=obj->slistcurr=NULL; obj->slisthier_len=0; queuedevents=NULL; /* deallocated in the symbol stuff */ if(obj->vcd_is_compressed) { pclose(obj->vcd_handle); } else { fclose(obj->vcd_handle); } if(obj->yytext) { free_2(obj->yytext); obj->yytext=NULL; } } /*******************************************************************************/ TimeType vcd_main(struct globals *obj, char *fname) { int flen; obj->pv=obj->rootv=NULL; obj->vcd_hier_delimeter[0]=obj->hier_delimeter; errno=0; /* reset in case it's set for some reason */ printf("Processing '%s'\n",fname); obj->yytext=(char *)malloc_2(obj->T_MAX_STR+1); flen=strlen(fname); if (((flen>2)&&(!strcmp(fname+flen-3,".gz")))|| ((flen>3)&&(!strcmp(fname+flen-4,".zip")))) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); obj->vcd_handle=popen(str,"r"); obj->vcd_is_compressed=~0; } else { if(strcmp("-vcd",fname)) { obj->vcd_handle=fopen(fname,"rb"); } else { obj->vcd_handle=stdin; } obj->vcd_is_compressed=0; } if(!obj->vcd_handle) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", obj->vcd_is_compressed?"compressed":"", fname); exit(VCD_FAIL); } getch_alloc(obj); /* alloc membuff for vcd getch buffer */ build_slisthier(obj); vcd_parse(obj); add_tail_histents(obj); vcd_build_symbols(obj); vcd_sortfacs(obj); vcd_cleanup(obj); printf("Found %d symbols.\n", obj->numfacs); printf("["TTFormat"] start time.\n["TTFormat"] end time.\n", obj->start_time, obj->end_time); if(obj->num_glitches) printf("Warning: encountered %d glitch%s across %d glitch region%s.\n", obj->num_glitches, (obj->num_glitches!=1)?"es":"", obj->num_glitch_regions, (obj->num_glitch_regions!=1)?"s":""); getch_free(obj); /* free membuff for vcd getch buffer */ obj->min_time=obj->start_time*obj->time_scale; obj->max_time=obj->end_time*obj->time_scale; if(obj->min_time==obj->max_time) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); exit(VCD_FAIL); } return(obj->max_time); } /*******************************************************************************/ iverilog-12_0/ivtest/src/vcd.h000066400000000000000000000031571435245347300164070ustar00rootroot00000000000000/* * Copyright (c) Tony Bybell 1999-2000. * * 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. */ #ifndef VCD_VCD_H #define VCD_VCD_H #include #include #ifndef _MSC_VER #include #endif #include #include #include #include #include "misc.h" #include "alloca.h" #include "debug.h" #include "globals.h" #define VCD_BSIZ 32768 /* size of getch() emulation buffer--this val should be ok */ #define VCD_FAIL 666 TimeType vcd_main(struct globals *obj, char *fname); void append_vcd_slisthier(struct globals *obj, char *str); struct sym_chain { struct sym_chain *next; struct symbol *val; }; struct slist { struct slist *next; char *str; int len; }; struct vcdsymbol { struct vcdsymbol *root, *chain; struct symbol *sym_chain; struct vcdsymbol *next; char *name; char *id; unsigned char vartype; int msi, lsi; int size; char *value; struct queuedevent *ev; /* only if vartype==V_EVENT */ struct Node **narray; }; struct queuedevent { struct queuedevent *next; struct vcdsymbol *sym; TimeType last_event_time; /* make +1 == 0 if there's not an event there too */ }; extern char autocoalesce; extern int vcd_explicit_zero_subscripts; /* 0=yes, -1=no */ extern char convert_to_reals; extern char atomic_vectors; extern char hier_delimeter; extern TimeType currenttime; extern TimeType max_time; extern TimeType min_time; extern char time_dimension; #endif iverilog-12_0/ivtest/sv_regress.list000066400000000000000000000053561435245347300177550ustar00rootroot00000000000000# # Copyright (c) 1999 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # Format of the file # # testname testtype directory # # The is the verilog file name minus an extension. It may contain # an optional version prefix separated from the name with a ":". The test # suite will use a version specific test instead of the default case. # # The can be one of the following: # # normal: Normal results expected, i.e it should compile and execute # producing at least a single line with PASSED. # # CO: Compile Only - Compile the file to the default output type. # # CN: Compile Null - Compile with the null target. Similar to CO. # # CE: Compile with Errors - We EXPECT errors - we're checking # illegal syntax # # RE: Runtime with Errors - We EXPECT errors - we're checking # illegal syntax # # EF: Expected fail - We EXPECT this test to fail - only use # with older versions of Icarus. # # NI: Not implemented. Only use for version specific tests. # # is where the .v file is located. # # An optional fourth and fifth argument can be supplied. # # The fourth argument may be one of the following. # # modulename - Defines the top level module # gold=filename - Compare a gold file against the generated log file. # diff=filename1:filename2:skip_ln - Compare the two files for equality. # Skip the first lines or none. # # If a is given you can supply a fifth argument for the # gold or diff commands. # struct_packed_write_read normal,-g2009 ivltests struct_packed_value_list normal,-g2009 ivltests array_packed_write_read normal,-g2009 ivltests array_packed_value_list normal,-g2009 ivltests array_packed_sysfunct normal,-g2009 ivltests sv_literals normal,-g2009 ivltests sv_parameter_type normal,-g2009 ivltests sv_interface normal,-g2009 ivltests iverilog-12_0/ivtest/vhdl_gold/000077500000000000000000000000001435245347300166275ustar00rootroot00000000000000iverilog-12_0/ivtest/vhdl_gold/bitsel.gold000066400000000000000000000005001435245347300207530ustar00rootroot00000000000000bitsel.vhd:24:7:@0ms:(report note): '1' bitsel.vhd:24:7:@0ms:(report note): '0' bitsel.vhd:24:7:@0ms:(report note): '0' bitsel.vhd:24:7:@0ms:(report note): '1' bitsel.vhd:24:7:@0ms:(report note): '0' bitsel.vhd:24:7:@0ms:(report note): '1' bitsel.vhd:24:7:@0ms:(report note): '1' bitsel.vhd:24:7:@0ms:(report note): '0' iverilog-12_0/ivtest/vhdl_gold/function1.gold000066400000000000000000000001431435245347300214020ustar00rootroot00000000000000function1.vhd:37:5:@0ms:(report note): 8 = sum(3, 5) function1.vhd:38:5:@0ms:(report note): PASSED iverilog-12_0/ivtest/vhdl_gold/mux2.gold000066400000000000000000000002301435245347300203640ustar00rootroot00000000000000mux2.vhd:52:5:@0ms:(report note): 'U' mux2.vhd:52:5:@0ms:(report note): '1' mux2.vhd:52:5:@1ms:(report note): '0' mux2.vhd:52:5:@2ms:(report note): '1' iverilog-12_0/ivtest/vhdl_gold/signed4.gold000066400000000000000000000002611435245347300210320ustar00rootroot00000000000000signed4.vhd:22:5:@0ms:(report note): x = 3 (should be 3) signed4.vhd:24:5:@0ms:(report note): y = -3 (should be -3) signed4.vhd:28:5:@0ms:(report note): x = 253 (should be 253) iverilog-12_0/ivtest/vhdl_gold/simple_gen.gold000066400000000000000000000003221435245347300216150ustar00rootroot00000000000000simple_gen.vhd:71:5:@1ms:(report note): 1 simple_gen.vhd:72:5:@1ms:(report note): 2 simple_gen.vhd:73:5:@1ms:(report note): 3 simple_gen.vhd:74:5:@1ms:(report note): 4 simple_gen.vhd:75:5:@1ms:(report note): 5 iverilog-12_0/ivtest/vhdl_reg.pl000077500000000000000000000175051435245347300170270ustar00rootroot00000000000000#!/usr/bin/env perl # # Regression script for VHDL output. Based on vvp_reg.pl. # # This script is based on code with the following Copyright. # # Copyright (c) 1999-2020 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA use lib './perl-lib'; use RegressionList; use Diff; use Reporting; use Environment; # # Main script # &open_report_file('vhdl_regression_report.txt'); my ($suffix, $strict, $with_valg, $force_sv) = &get_args; my $ver = &get_ivl_version($suffix); my $msg = $with_valg ? " (with valgrind)" : ""; &print_rpt("Running VHDL tests for Icarus Verilog version: $ver$msg.\n"); &print_rpt("-" x 70 . "\n"); if ($#ARGV != -1) { my $regress_fn = &get_regress_fn; &read_regression_list($regress_fn, $ver, $force_sv, ""); } else { &read_regression_list("vhdl_regress.list", $ver, $force_sv, ""); } &execute_regression($suffix, $with_valg); &close_report_file; # # execute_regression sequentially compiles and executes each test in # the regression. It then checks that the output matches the gold file. # sub execute_regression { my $sfx = shift(@_); my $with_valg = shift(@_); my ($tname, $total, $passed, $failed, $expected_fail, $not_impl, $len, $cmd, $diff_file, $outfile, $unit); $total = 0; $passed = 0; $failed = 0; $expected_fail = 0; $not_impl = 0; $len = 0; # Check for the VHDL output directory mkdir 'vhdl' unless (-d 'vhdl'); foreach $tname (@testlist) { $len = length($tname) if (length($tname) > $len); } foreach $tname (@testlist) { next if ($tname eq ""); # Skip test that have been replaced. $total++; &print_rpt(sprintf("%${len}s: ", $tname)); if ($diff{$tname} ne "" and -e $diff{$tname}) { unlink $diff{$tname} or die "Error: unable to remove old diff file $diff{$tname}.\n"; } if (-e "log/$tname.log") { unlink "log/$tname.log" or die "Error: unable to remove old log file log/$tname.log.\n"; } if ($testtype{$tname} eq "NI") { &print_rpt("Not Implemented.\n"); $not_impl++; next; } # Store all the output in the vhdl subdirectory for debugging $outfile = "vhdl/$tname.vhd"; # # Build up the iverilog command line and run it. # $cmd = $with_valg ? "valgrind --trace-children=yes " : ""; $cmd .= "iverilog$sfx -t vhdl -o $outfile $args{$tname}"; $cmd .= " -s $testmod{$tname}" if ($testmod{$tname} ne ""); $cmd .= " ./$srcpath{$tname}/$tname.v > log/$tname.log 2>&1"; #print "$cmd\n"; if (system("$cmd")) { if ($testtype{$tname} eq "CE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - CE (core dump).\n"); $failed++; } else { &print_rpt("Passed - CE.\n"); $passed++; } next; } # Check the log file for an un-translatable construct error # We report this separately so we can distinguish between # expected and unexpected failures $cmd = "grep -q -i -E '(no vhdl translation|cannot be translated)' log/$tname.log"; if (system($cmd) == 0) { &print_rpt("==> Failed - No VHDL translation.\n"); $not_impl++; next; } else { &print_rpt("==> Failed - running iverilog.\n"); $failed++; next; } } # # Compile the output with GHDL # $cmd = "(cd vhdl ; ghdl -a $tname.vhd) >> log/$tname.log 2>&1"; #print "$cmd\n"; if (system("$cmd")) { if ($testtype{$tname} eq "CE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - CE (core dump).\n"); $failed++; } else { &print_rpt("Passed - CE.\n"); $passed++; } next; } &print_rpt("==> Failed - running ghdl.\n"); $failed++; next; } # The CO test type now includes compilation of the VHDL if ($testtype{$tname} eq "CO") { &print_rpt("Passed - CO.\n"); $passed++; next; } # Try to guess the name of the primary VHDL unit # ghdl -f lists all the units in a file: take the first one ($unit) = `ghdl -f $outfile` =~ /^entity (\w+)/; unless ($unit) { &print_rpt("==> Failed -- cannot determine primary VHDL unit.\n"); $failed++; next; } #print "primary unit is $unit\n"; # Elaborate the primary unit to produce and executable # Could elaborate and run in a single step, but this should # provide better error detection. $cmd = "(cd vhdl ; ghdl -e $unit) >> log/$tname.log 2>&1"; #print "$cmd\n"; if (system($cmd)) { &print_rpt("==> Failed - running ghdl elaboration step.\n"); $failed++; next; } # Finally, run the exectutable $cmd = "(cd vhdl ; ghdl -r $unit --stop-delta=10000) >> log/$tname.log 2>&1"; #print "$cmd\n"; if (system($cmd)) { if ($testtype{$tname} eq "RE") { &print_rpt("Passed - RE.\n"); $passed++; next; } else { # If the log contains `SIMULATION FINISHED' then # this is OK $cmd = "grep -q 'SIMULATION FINISHED' log/$tname.log"; if (system($cmd)) { &print_rpt("==> Failed - simulating VHDL.\n"); $failed++; next; } } } if ($diff{$tname} ne "") { $diff_file = $diff{$tname} } else { $diff_file = "log/$tname.log"; } # print "diff $gold{$tname}, $diff_file, $offset{$tname}\n"; if (diff($gold{$tname}, $diff_file, $offset{$tname})) { if ($testtype{$tname} eq "EF") { &print_rpt("Passed - expected fail.\n"); $expected_fail++; next; } &print_rpt("==> Failed - output does not match gold file.\n"); $failed++; next; } &print_rpt("Passed.\n"); $passed++; } continue { if ($tname ne "") { # Remove GHDL temporary files my $tmpfiles = './vhdl/*.o ./vhdl/work-obj93.cf'; $tmpfiles .= " ./vhdl/$unit" if $unit; system("rm -f $tmpfiles") and die "Error: failed to remove temporary files.\n"; } } &print_rpt("=" x 70 . "\n"); &print_rpt("Test results:\n Total=$total, Passed=$passed, Failed=$failed,". " Not Implemented=$not_impl, Expected Fail=$expected_fail\n"); } iverilog-12_0/ivtest/vhdl_regress.list000066400000000000000000000224201435245347300202510ustar00rootroot00000000000000hello1 normal ivltests mux2 normal vhdl_tests diff=log/mux2.log:vhdl_gold/mux2.gold dff normal vhdl_tests counter normal vhdl_tests assign normal vhdl_tests blocking normal vhdl_tests constassign normal vhdl_tests readout normal vhdl_tests autof normal vhdl_tests generics normal vhdl_tests partpv CO vhdl_tests case1 normal ivltests case2 normal ivltests case3 normal ivltests case4 normal ivltests case5 normal ivltests case6 normal ivltests case7 normal ivltests case3.8A normal ivltests case3.8B normal ivltests case3.8C normal ivltests case3.8D normal ivltests blocksynth1 normal ivltests casesynth1 normal ivltests casesynth2 normal ivltests casesynth3 normal ivltests casex_synth normal ivltests dffsynth normal ivltests dffsynth2 normal ivltests dffsynth4 normal ivltests inside_synth3 normal ivltests memsynth1 normal ivltests memsynth2 normal ivltests memsynth3 normal ivltests memsynth4 normal ivltests memsynth5 normal ivltests memsynth7 normal ivltests memsynth8 normal ivltests memsynth9 normal ivltests multireg normal ivltests condit1 normal ivltests conditsynth1 normal ivltests conditsynth2 normal ivltests conditsynth3 normal ivltests basiclatch normal ivltests basicstate normal ivltests basicstate2 normal ivltests ssetclr1 normal ivltests ssetclr2 normal ivltests ssetclr3 normal ivltests always3.1.11A normal ivltests always3.1.11B normal ivltests always3.1.1C normal ivltests always3.1.1D normal ivltests always3.1.1E normal ivltests always3.1.1F normal ivltests always3.1.4A normal ivltests always3.1.4D normal ivltests always3.1.4E normal ivltests always3.1.4G normal ivltests always3.1.5A normal ivltests always3.1.5B normal ivltests always3.1.5C normal ivltests always3.1.5D normal ivltests always3.1.5E normal ivltests always3.1.5F normal ivltests always3.1.6D normal ivltests always3.1.7A normal ivltests always3.1.7B normal ivltests always3.1.7C normal ivltests always3.1.7D normal ivltests always3.1.8A normal ivltests function3.11B normal ivltests function3.11C normal ivltests function3.11D normal ivltests function3.11F normal ivltests module3.12A normal ivltests module3.12B normal ivltests muxtest normal ivltests ptest001 normal ivltests ptest002 normal ivltests ptest003 normal ivltests ptest004 normal ivltests ptest005 normal ivltests ptest006 normal ivltests ptest007 normal ivltests ptest008 normal ivltests ptest009 normal ivltests ptest010 normal ivltests qmark normal ivltests qmark1 normal ivltests qmark3 normal ivltests qmark5 normal ivltests qmark6 normal ivltests sdw_always1 normal ivltests sdw_always2 normal ivltests sdw_always3 normal ivltests sdw_assign normal ivltests sdw_function1 normal ivltests sdw_function2 noraml ivltests sdw_function3 normal ivltests sdw_function4 normal ivltests sdw_function5 normal ivltests sdw_task1 normal ivltests sdw_task2 normal ivltests sdw_int normal ivltests sdw_lvalconcat2 normal ivltests sdw_param1 normal ivltests sdw_param2 normal ivltests sdw_stmt002 normal ivltests sdw_array normal ivltests sdw_instmod1 normal ivltests sdw_instmod2 normal ivltests sdw_lvalconcat normal ivltests task3.14A normal ivltests task3.14B normal ivltests task3.14C normal ivltests task3.14D normal ivltests task3.14E normal ivltests z1 normal ivltests z2 normal ivltests landor1 normal ivltests land2 normal ivltests land3 normal ivltests contrib8.1 normal ivltests contrib8.2 normal ivltests contrib8.4 normal ivltests dff1 normal ivltests fifo normal contrib gencrc normal contrib idiv2 normal ivltests event_list2 normal ivltests timescale1 normal ivltests integer1lt normal ivltests integer2le normal ivltests integer3gt normal ivltests integer4ge normal ivltests time1 normal ivltests time3 normal ivltests time8 normal ivltests wireadd1 normal ivltests wiresl normal ivltests wiresr normal ivltests wiresub1 normal ivltests wirexor1 normal ivltests wirele normal ivltests wirege normal ivltests wireeq normal ivltests andnot1 normal ivltests constmult normal ivltests constadd normal ivltests constadd2 normal ivltests constadd3 normal ivltests consttern normal ivltests talu normal ivltests udp_bufg normal ivltests udp_bufg2 normal ivltests unary_not normal ivltests unary_and normal ivltests unary_nand normal ivltests unary_nand2 normal ivltests unary_or normal ivltests unary_nor normal ivltests unary_nor2 normal ivltests unary_xor normal ivltests unary_xnor1 normal ivltests unary_xnor2 normal ivltests unary_minus normal ivltests unary_minus2 normal ivltests unary_minus3 normal ivltests unary_minus4 normal ivltests pr2224949 normal ivltests pr2281479 normal ivltests pr2281519 CO vhdl_tests pr2147135a CO vhdl_tests pr2147135b CO vhdl_tests pr2391405 CO vhdl_tests pr2362426 normal vhdl_tests ga_and normal ivltests ga_or normal ivltests ga_xor normal ivltests ga_nand normal ivltests ga_nor normal ivltests ga_xnor normal ivltests binary_nand normal ivltests binary_nor normal ivltests rptconcat normal ivltests rptconcat2 normal ivltests inout normal ivltests modparam normal ivltests port-test2 normal ivltests scope2 normal ivltests scope2b normal ivltests tri0 normal ivltests tri0b normal ivltests tri1 normal ivltests posedge normal ivltests nblkorder normal ivltests task_inpad normal ivltests cond_band normal ivltests cond_wide normal ivltests cond_wide2 normal ivltests wildsense normal ivltests wildsense2 normal ivltests assign_mem1 normal ivltests meminit normal ivltests meminit2 normal ivltests task_noop normal ivltests task_bypath normal ivltests task_iotypes normal ivltests assign_nb1 normal ivltests assign_nb2 normal ivltests assign_delay normal ivltests define1 normal ivltests delay2 normal ivltests delay3 normal ivltests delay4 normal ivltests delay5 normal ivltests delay_assign_nb normal ivltests delay_assign_nb2 normal ivltests ldelay1 normal ivltests ldelay2 normal ivltests ldelay3 normal ivltests ldelay5 normal ivltests wireland normal ivltests param_concat normal ivltests param_select normal ivltests param_select2 normal ivltests param_select3 normal ivltests param_times normal ivltests function1 normal ivltests diff=log/function1.log:vhdl_gold/function1.gold function_exp normal ivltests addsr normal ivltests tern1 normal ivltests tern4 normal ivltests tern6 normal ivltests tern7 normal ivltests tern9 normal ivltests tern10 normal ivltests bnot normal ivltests stask_parm1 normal ivltests task_omemw2 normal ivltests lh_varindx2 normal ivltests lh_varindx4 normal ivltests lh_varindx5 normal ivltests lh_catadd normal ivltests signed1 normal ivltests signed2 normal ivltests signed3 normal ivltests signed4 noraml ivltests diff=log/signed4.log:vhdl_gold/signed4.gold signed5 normal ivltests signed6 normal ivltests signed7 normal ivltests signed9 normal ivltests signed11 normal ivltests repeat2 normal ivltests decl_assign1 normal ivltests shift2 normal ivltests # Out of order from here pr1903520 normal ivltests pr142 normal ivltests bitsel normal ivltests diff=log/bitsel.log:vhdl_gold/bitsel.gold bitsel2 normal ivltests bitsel3 normal ivltests bitsel4 normal ivltests bitsel5 normal ivltests select normal ivltests uwire normal ivltests xnor_test normal ivltests pr2202846a normal ivltests pr2202846b normal ivltests pr2202846c normal ivltests pr2489116 normal vhdl_tests pr2489237 CO vhdl_tests pr2516774 normal vhdl_tests pr2516774b CO vhdl_tests pr2527366 CO vhdl_tests pr2529315 CO vhdl_tests pr2529315b CO vhdl_tests pr2531370 CO vhdl_tests pr2526768 normal vhdl_tests pr2536040 CO vhdl_tests pr2541625 normal vhdl_tests pr2534491 normal vhdl_tests pr2554173 CO vhdl_tests pr2555813 CO vhdl_tests pr2555813b CO vhdl_tests pr2554029 CO vhdl_tests pr2554124 CO vhdl_tests simple_gen normal vhdl_tests diff=log/simple_gen.log:vhdl_gold/simple_gen.gold pr2911213 normal vhdl_tests reserved normal vhdl_tests pr2555831 normal vhdl_tests pr2661101 normal vhdl_tests pr3397689 normal vhdl_tests iverilog-12_0/ivtest/vhdl_tests/000077500000000000000000000000001435245347300170445ustar00rootroot00000000000000iverilog-12_0/ivtest/vhdl_tests/assign.v000066400000000000000000000011571435245347300205230ustar00rootroot00000000000000/* * Basics tests of continuous assignment. */ module testbench(); reg [3:0] a, b; integer c, d; wire [3:0] x, y, z; assign x = a + b + b; assign y = b - a; assign z = a + (a * b); initial begin a <= 4'h2; b <= 4'h3; #1; if (x !== 4'h8) begin $display("FAILED -- 2 + 3 + 3 !== 8"); $finish; end if (y !== 4'h1) begin $display("FAILED -- 3 - 2 !== 1"); $finish; end if (z !== 4'h8) begin $display("FAILED -- 2 + (2 * 3) !== 8"); $finish; end $display("PASSED"); end endmodule // testbench iverilog-12_0/ivtest/vhdl_tests/autof.v000066400000000000000000000006321435245347300203520ustar00rootroot00000000000000// This is a simple test of automatic functions module autof(); reg [7:0] result; function automatic [7:0] fact; input [7:0] n; if (n == 0) fact = 1; else fact = n * fact(n-1); endfunction // fact initial begin result = fact(4); if (result == 24) $display("PASSED"); else $display("FAILED -- Expected 24 but got %d", result); end endmodule // autof iverilog-12_0/ivtest/vhdl_tests/blocking.v000066400000000000000000000011571435245347300210270ustar00rootroot00000000000000module testbench(); reg [3:0] a, b; initial begin a = 1; b = 2; #1; a = a + b; b = a + b; if (a !== 3) begin $display("FAILED -- a !== 3"); $finish; end if (b !== 5) begin $display("FAILED -- b !== 5"); $finish; end #2; $display("PASSED"); end // initial begin initial begin #2; if (a !== 3) begin $display("FAILED -- a (signal) !== 3"); $finish; end if (b !== 5) begin $display("FAILED -- b (signal) !== 5"); $finish; end end endmodule // testbench iverilog-12_0/ivtest/vhdl_tests/constassign.v000066400000000000000000000003571435245347300215730ustar00rootroot00000000000000// A very simple test to check continuous assignment // of a constant module main(); wire p; assign p = 1; initial begin #1; if (p == 1) $display("PASSED"); else $display("FAILED"); end endmodule // main iverilog-12_0/ivtest/vhdl_tests/counter.v000066400000000000000000000011421435245347300207100ustar00rootroot00000000000000module testbench(); wire [3:0] q; reg clr, clk, enable; counter uut(q, clr, clk); always @(clk) if (enable) #1 clk <= !clk; initial begin enable <= 1; clk <= 0; clr <= 1; #2; clr <= 0; #7; enable <= 0; if (q == 4'b0011) $display("PASSED"); else $display("FAILED -- counter not correct (%d)", q); end endmodule // testbench module counter(q, clr, clk); output [3:0] q; input clr, clk; reg [3:0] q; always @(posedge clk or posedge clr) if (clr) q <= 4'b0000; else q <= q + 1'b1; endmodule // counter iverilog-12_0/ivtest/vhdl_tests/dff.v000066400000000000000000000020101435245347300177630ustar00rootroot00000000000000/* * A D-type flip-flop to check synchronous logic works * correctly. */ module testbench; reg d, clk, rst, enable; wire q, q_bar; dff uut(q, q_bar, d, clk, rst); initial clk <= 0; always @(clk) if (enable) #1 clk <= !clk; initial begin enable <= 1; rst <= 1; d <= 1'bx; #2; if (q !== 0) begin $display("FAILED -- Not reset"); $finish; end rst <= 0; d <= 1'b1; #2; if (q !== 1) begin $display("FAILED -- q not 1 as expected"); $finish; end d <= 1'b0; #2; if (q !== 0) begin $display("FAILED -- q not 0 as expected"); $finish; end rst <= 1; #2; enable <= 0; // Alternative to using $finish $display("PASSED"); end endmodule // testbench module dff(q, q_bar, d, clk, rst); output q, q_bar; input d, clk, rst; reg q; always @(posedge clk or posedge rst) if (rst) q <= 1'b0; else q <= d; not(q_bar, q); endmodule // dff iverilog-12_0/ivtest/vhdl_tests/generics.v000066400000000000000000000022241435245347300210320ustar00rootroot00000000000000// A few simple tests of translating parameters to generics module top(); wire [7:0] v1, v2, v3; wire [7:0] w1, w2, w3; child c1(v1, w1); child c2(v2, w2); child c3(v3, w3); defparam c1.MY_VALUE = 6; defparam c2.MY_VALUE = 44; initial begin #2; $display("c1 reg value: %d", v1); $display("c2 reg value: %d", v2); $display("c3 reg value: %d", v3); $display("c1 wire value: %d", w1); $display("c2 wire value: %d", w2); $display("c3 wire value: %d", w3); if (v1 !== 6) $display("FAILED - v1 !== 6"); else if (v2 !== 44) $display("FAILED - v2 !== 44"); else if (v3 !== 12) $display("FAILED - v3 !== 12"); else if (w1 !== 7) $display("FAILED - v1 !== 7"); else if (w2 !== 45) $display("FAILED - v2 !== 45"); else if (w3 !== 13) $display("FAILED - v3 !== 13"); else $display("PASSED"); end endmodule // top module child(value, value_w); output [7:0] value, value_w; reg [7:0] value; parameter MY_VALUE = 12; assign value_w = MY_VALUE + 1; // Make a non-trivial process initial begin #1; value <= MY_VALUE; end endmodule // child iverilog-12_0/ivtest/vhdl_tests/mux2.v000066400000000000000000000010071435245347300201240ustar00rootroot00000000000000/* * A simple test of some of the structural elements. */ module testbench; wire o; reg i0, i1, sel; mux2 uut(o, i0, i1, sel); initial begin i0 <= 1; i1 <= 0; sel <= 0; #1; sel <= 1; #1; i1 <= 1; #1; end always @(o) $display(o); endmodule // testbench module mux2(c, a, b, s); input a, b, s; output c; wire s_bar, a_and_s_bar, b_and_s; not(s_bar, s); and(a_and_s_bar, a, s_bar); and(b_and_s, b, s); or(c, a_and_s_bar, b_and_s); endmodule // mux2 iverilog-12_0/ivtest/vhdl_tests/partpv.v000066400000000000000000000003111435245347300205420ustar00rootroot00000000000000// This test is intended to generate a IVL_LPM_SELECT_PV // in the `b' port map module top; wire [7:0] foo; bot b( .q(foo[3:0]) ); endmodule // top module bot(q); output [3:0] q; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2147135a.v000066400000000000000000000001651435245347300205660ustar00rootroot00000000000000module test(); wire d; wire [5:0] f; b u1 (.c({d, f})); endmodule module b (c); output [6:0] c; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2147135b.v000066400000000000000000000003231435245347300205630ustar00rootroot00000000000000module test( clk, a, b ); input clk; output [0:0] a; output b; reg [0:0] a; reg b; integer i = 5; always @(posedge clk) begin a[i] <= 1'b0; b <= 1'b0; end endmodule iverilog-12_0/ivtest/vhdl_tests/pr2281519.v000066400000000000000000000002621435245347300204300ustar00rootroot00000000000000module test(); wire clk; reg [8:0] lowp2_tmp; reg [8:0] lowp2_out; always @(posedge clk) begin lowp2_out <= ( {lowp2_tmp[8], lowp2_tmp} ) >> 1; end endmodule iverilog-12_0/ivtest/vhdl_tests/pr2362426.v000066400000000000000000000007011435245347300204230ustar00rootroot00000000000000module test(); reg c; a #(1) ua( .c(c), .b(h)); initial begin c = 0; #1 c = 1; #1 c = 0; $display("PASSED"); end endmodule module a( c, b, ); parameter e = 2; input c; output [e-1:0] b; reg [e-1:0] f; reg [e-1:0] g; reg [e-1:0] b; integer d; always @(posedge c) begin for(d=0; d 0; n = n - 1) begin fact = fact * n; end endfunction // for initial begin r = fact(5); $display("fact(5) = %d", r); if (r == 120) $display("PASSED"); else $display("FAILED"); end endmodule // top iverilog-12_0/ivtest/vhdl_tests/pr2516774b.v000066400000000000000000000026371435245347300206060ustar00rootroot00000000000000// This slightly convoluted module used to cause an argument-size // mismatch in the call to the function extend_data module test (c); parameter MAX_SIZE = 32; input c; reg [MAX_SIZE-1:0] d, e, f; reg [7:0] g; wire h; always @(posedge h or negedge c) if (~c) f <= #2 {MAX_SIZE{1'b0}}; else case (g) 8'h18 : f <= #2 hw(d, e); default : f <= #2 {MAX_SIZE{1'b0}}; endcase parameter FALSE_RESULT = {MAX_SIZE{1'b0}}, TRUE_RESULT = FALSE_RESULT | 1'b1; function integer sign_of; input [2*MAX_SIZE-1:0] data; input size; reg [2*MAX_SIZE-1:0] data; integer size; if (data[size-1]===1'b1) sign_of = -1; else sign_of = 1; endfunction function [2*MAX_SIZE-1:0] extend_data; input [2*MAX_SIZE-1:0] data; input size; input new_size; input extend; reg [2*MAX_SIZE-1:0] data; integer size, new_size; reg extend; for (extend_data = data ; new_size-size>0 ; new_size=new_size-1) extend_data[new_size-1] = extend & data[size-1]; endfunction function [MAX_SIZE-1:0] hw; input [MAX_SIZE-1:0] a; input [MAX_SIZE-1:0] b; reg [MAX_SIZE-1:0] a, b; reg [MAX_SIZE:0] diff; begin diff = extend_data(b, MAX_SIZE, MAX_SIZE+1, 1'b1) - extend_data(a, MAX_SIZE, MAX_SIZE+1, 1'b1); if (sign_of(diff, MAX_SIZE+1)==-1) hw = TRUE_RESULT; else hw = FALSE_RESULT; end endfunction endmodule iverilog-12_0/ivtest/vhdl_tests/pr2526768.v000066400000000000000000000016631435245347300204460ustar00rootroot00000000000000module top(); wire [7:0] Z, CO; reg [7:0] A, B, CI; reg ok; test test(Z, CO, A, B, CI); task check; input [7:0] want_z, want_co; begin $display("A = %d, B = %d, CI = %d", A, B, CI); $display("==> Z = %d, CO = %d", Z, CO); $display("??? Z = %d, CO = %d", want_z, want_co); if (want_co !== CO || want_z !== Z) begin $display("FAILED"); ok = 0; end $display; end endtask // check initial begin ok = 1; A = 0; B = 0; CI = 0; #1 check(0, 0); A = 4; #1 check(4, 0); B = 251; #1 check(255, 0); if (ok) $display("PASSED"); end endmodule // top module test (Z, CO, A, B, CI); parameter width=8; input [width-1:0] A, B, CI; output [width-1:0] Z, CO; reg [width-1:0] Z, CO; integer i; always @(A or B or CI) begin for(i=0; i < width; i=i+1) {CO[i],Z[i]} = A[i] + B[i] + CI[i]; end endmodule iverilog-12_0/ivtest/vhdl_tests/pr2527366.v000066400000000000000000000001771435245347300204400ustar00rootroot00000000000000module test(input b); a ua(.BISTEA(b), .BISTEB(b)); endmodule // test module a (input BISTEA, input BISTEB); endmodule // a iverilog-12_0/ivtest/vhdl_tests/pr2529315.v000066400000000000000000000003431435245347300204270ustar00rootroot00000000000000module test ( input clk_dma, input rst_dma_n, input wr_valid, input wr_trans, input wr_flush, output wr_ready); wire buf_wr_wstrb; assign buf_wr_wstrb = wr_ready && wr_valid; assign wr_ready = wr_flush ; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2529315b.v000066400000000000000000000015201435245347300205670ustar00rootroot00000000000000module test ( Z, CO32, A, B, CI); input[63:0] A; input[63:0] B; input CI; output[63:0] Z; output CO32; wire[31:0] Z1; wire[31:0] Z2; adder32 add0( .Z(Z[31:0]), .A(A[31:0]), .B(B[31:0]), .CI(CI)); carry32 car0( .CO (CO32), .A (A[31:0]), .B (B[31:0]), .CI (CI)); adder32 add1( .Z (Z1), .A (A[63:32]), .B (B[63:32]), .CI (1'b0)); adder32 add2( .Z (Z2), .A (A[63:32]), .B (B[63:32]), .CI (1'b1)); assign Z[63:32] = CO32 ? Z2 : Z1; endmodule module adder32 ( Z, A, B, CI); input[31:0] A; input[31:0] B; input CI; output [31:0] Z; assign Z = A + B + CI; endmodule module carry32 ( CO, A, B, CI); input[31:0] A; input[31:0] B; input CI; output CO; wire[31:0] unused; assign {CO, unused} = A + B + CI; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2531370.v000066400000000000000000000000751435245347300204230ustar00rootroot00000000000000module test(); initial $display("Error: %m"); endmodule iverilog-12_0/ivtest/vhdl_tests/pr2534491.v000066400000000000000000000004161435245347300204310ustar00rootroot00000000000000module test (); initial begin : local_vars integer i, sum; sum = 0; for (i = 1; i <= 10; i = i + 1) sum = sum + i; $display("sum(1..10) = %d", sum); if (sum == 55) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/vhdl_tests/pr2536040.v000066400000000000000000000001471435245347300204220ustar00rootroot00000000000000module test ( input a, input _b_, output A, output b__); assign A = a; assign b__ = _b_; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2541625.v000066400000000000000000000006171435245347300204310ustar00rootroot00000000000000module top(); wire out1, out2; child c1(1, 0, out1); child c2(1, 1, out2); initial begin #1; if (out1 !== 0) $display("FAILED -- out1 !== 0"); else if (out2 !== 1) $display("FAILED -- out2 !== 1"); else $display("PASSED"); end endmodule // top module child(in1, in2, out); input in1, in2; output out; assign out = in1 & in2; endmodule // child iverilog-12_0/ivtest/vhdl_tests/pr2554029.v000066400000000000000000000002271435245347300204300ustar00rootroot00000000000000module test(); a a (.pi(pi)); endmodule // test module a(input pi); assign Pi = pi; b b(.Pi(Pi)); endmodule // a module b(input Pi); endmodule iverilog-12_0/ivtest/vhdl_tests/pr2554124.v000066400000000000000000000002261435245347300204230ustar00rootroot00000000000000module test(); wire b; a a( .b_buf(b), .b (b)); endmodule // test module a(output b_buf, input b); assign b_buf = 1'b0; endmodule // a iverilog-12_0/ivtest/vhdl_tests/pr2554173.v000066400000000000000000000002121435245347300204220ustar00rootroot00000000000000module test(); a a_( .b_buf(b), .b (b) ); endmodule // test module a(b, b_buf); input b, b_buf; endmodule // a_ iverilog-12_0/ivtest/vhdl_tests/pr2555813.v000066400000000000000000000002351435245347300204310ustar00rootroot00000000000000module test(); wire a, b; a__a a_( .b_buf(b), .b (a) ); endmodule module a__a(b_buf, b); output b_buf; input b; endmodule iverilog-12_0/ivtest/vhdl_tests/pr2555813b.v000066400000000000000000000002051435245347300205700ustar00rootroot00000000000000module test(); wire x, y; a__a a_( .b_buf(y), .b (x) ); endmodule module a__a(b_buf, b); output b_buf; input b; endmodule // a__a iverilog-12_0/ivtest/vhdl_tests/pr2555831.v000066400000000000000000000011211435245347300204240ustar00rootroot00000000000000module top (); reg [31:0] din; wire [31:0] dout; test t(din, dout); initial begin din = 5; #1; $display("dout=%d", dout); if (dout == 5) $display("PASSED"); else $display("FAILED"); end endmodule // top module test ( din, dout); input [31:0] din; output [31:0] dout; buff #(1) d0_1 ( .in(din[0:0]), .out(dout[0:0])); buff #(32) d0_32 ( .in(din[31:0]), .out(dout[31:0])); endmodule // test module buff (out, in); parameter SIZE=1; output [SIZE-1:0] out; input [SIZE-1:0] in; assign out[SIZE-1:0] = in[SIZE-1:0]; endmodule // buff iverilog-12_0/ivtest/vhdl_tests/pr2661101.v000066400000000000000000000004041435245347300204130ustar00rootroot00000000000000module top(); reg [7:0] a, a_a, a__a; initial begin a = 1; #1; a_a = 2; #1; a__a = 3; #1; if (a == 1 && a_a == 2 && a__a == 3) $display("PASSED"); else $display("FAILED"); $finish; end endmodule // top iverilog-12_0/ivtest/vhdl_tests/pr2911213.v000066400000000000000000000013341435245347300204200ustar00rootroot00000000000000module top(); reg [3:0] a; reg [4:0] b; wire [8:0] y; functest uut(a, b, y); initial begin a = 3'b101; b = 4'b0101; #1; if (y == 8'b10100101) $display("PASSED"); else $display("FAILED y = %b", y); end endmodule // top module functest ( operand_a, operand_b, result_y ); input [3:0] operand_a; input [4:0] operand_b; output [8:0] result_y; function [8:0] concat_this; input [3:0] op_s; input [4:0] op_l; concat_this = {op_s, op_l}; endfunction reg [8:0] result_y_wire; always @ (operand_a or operand_b) begin result_y_wire = concat_this(operand_a, operand_b); end assign result_y = result_y_wire; endmodule iverilog-12_0/ivtest/vhdl_tests/pr3397689.v000066400000000000000000000020731435245347300204530ustar00rootroot00000000000000module top(); reg p_clk, rst_in, reg_req_t; wire out; weird_ff uut(p_clk, rst_in, reg_req_t, out); initial begin p_clk = 0; rst_in = 1; reg_req_t = 0; #1; rst_in = 0; #1; p_clk = 1; #2; p_clk = 0; $display("%d", out); if (out != 1'bx) begin $display("FAILED 1 - ff was reset"); $finish; end #1; rst_in = 1; #1; p_clk = 1; #1; p_clk = 0; $display("%d", out); if (out != 1'b0) begin $display("FAILED 2 - ff was not reset"); $finish; end $display("PASSED"); end endmodule // top module weird_ff(p_clk, rst_in, reg_req_t, out); input p_clk; input rst_in; input reg_req_t; output out; reg [1:0] wr_req_pipe; parameter G_ASYNC_RESET = 0; wire a_rst = (G_ASYNC_RESET != 0) ? rst_in : 1'b0; wire s_rst = (G_ASYNC_RESET == 0) ? rst_in : 1'b0; always @(posedge p_clk or posedge a_rst) if (a_rst | s_rst) wr_req_pipe <= 'b0; else wr_req_pipe <= {wr_req_pipe, reg_req_t}; assign out = wr_req_pipe[1]; endmodule // weird_ff iverilog-12_0/ivtest/vhdl_tests/readout.v000066400000000000000000000007411435245347300207000ustar00rootroot00000000000000// This causes GHDL to fail with 'port "p" cannot be read' // since the code generator does not yet identify p as an // internal signal as well as a port. module top; wire ign; a inst(ign); endmodule // top module a(p); output p; b inst(p); initial begin #1; if (p !== 1) $display("FAILED -- p !== 1"); else $display("PASSED"); $finish; end endmodule // a module b(q); output q; assign q = 1; endmodule // b iverilog-12_0/ivtest/vhdl_tests/reserved.v000066400000000000000000000002731435245347300210540ustar00rootroot00000000000000module top(); register loop(); process signal(); endmodule // top module register(); endmodule // register module process(); initial $display("PASSED"); endmodule // process iverilog-12_0/ivtest/vhdl_tests/simple_gen.v000066400000000000000000000010671435245347300213610ustar00rootroot00000000000000// A simple generate example for VHDL conversion module main(); wire [39:0] data; integer j; generate genvar i; for (i = 0; i < 4; i = i + 1) begin inc u(data[(i+1)*8 - 1:i*8], data[(i+2)*8 - 1:(i+1)*8]); end endgenerate assign data[7:0] = 1; initial begin #1; $display(data[7:0]); $display(data[15:8]); $display(data[23:16]); $display(data[31:24]); $display(data[39:32]); end endmodule // simple_gen module inc(in, out); input [7:0] in; output [7:0] out; assign out = in + 1; endmodule // inc iverilog-12_0/ivtest/vlog95_reg.pl000077500000000000000000000234651435245347300172210ustar00rootroot00000000000000#!/usr/bin/env perl # # Script to handle regression for normal Verilog files. # # This script is based on code with the following Copyright. # # Copyright (c) 1999-2020 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA use lib './perl-lib'; use RegressionList; use Diff; use Reporting; use Environment; # # Main script # &open_report_file; my ($suffix, $strict, $with_valg, $force_sv) = &get_args; my $ver = &get_ivl_version($suffix); my $opt = $force_sv ? " (force SV)" : ""; my $msg = $with_valg ? " (with valgrind)" : ""; &print_rpt("Running vlog95 compiler/VVP tests for Icarus Verilog " . "version: $ver$opt$msg.\n"); &print_rpt("-" x 76 . "\n"); if ($#ARGV != -1) { my $regress_fn = &get_regress_fn; &read_regression_list($regress_fn, $ver, $force_sv, ""); } else { if ($force_sv) { &read_regression_list("regress-fsv.list", $ver, $force_sv, ""); } &read_regression_list("regress-vlog95.list", $ver, $force_sv, ""); &read_regression_list("regress-v$ver.list", $ver, $force_sv, ""); &read_regression_list("regress-ivl2.list", $ver, $force_sv, ""); &read_regression_list("regress-ivl1.list", $ver, $force_sv, ""); &read_regression_list("regress-vlg.list", $ver, $force_sv, ""); &read_regression_list("regress-vams.list", $ver, $force_sv, ""); if ($ver >= 10) { &read_regression_list("regress-sv.list", $ver, $force_sv, ""); &read_regression_list("regress-vhdl.list", $ver, $force_sv, ""); } if ($ver == 0.9) { &read_regression_list("regress-synth.list", $ver, $force_sv, ""); } else { &read_regression_list("regress-synth.list", $ver, $force_sv, "-S"); } } &execute_regression($suffix, $with_valg); &close_report_file; # # execute_regression sequentially compiles and executes each test in # the regression. It then checks that the output matches the gold file. # sub execute_regression { my $sfx = shift(@_); my $with_valg = shift(@_); my ($tname, $total, $passed, $failed, $expected_fail, $not_impl, $len, $cmd, $diff_file); $total = 0; $passed = 0; $failed = 0; $expected_fail = 0; $not_impl = 0; $len = 0; foreach $tname (@testlist) { $len = length($tname) if (length($tname) > $len); } # Make sure we have a log and work directory. if (! -d 'log') { mkdir 'log' or die "Error: unable to create log directory.\n"; } if (! -d 'work') { mkdir 'work' or die "Error: unable to create work directory.\n"; } foreach $tname (@testlist) { my $pass_type; next if ($tname eq ""); # Skip test that have been replaced. $total++; &print_rpt(sprintf("%${len}s: ", $tname)); if ($diff{$tname} ne "" and -e $diff{$tname}) { unlink $diff{$tname} or die "Error: unable to remove old diff file $diff{$tname}.\n"; } if (-e "log/$tname.log") { unlink "log/$tname.log" or die "Error: unable to remove old log file log/$tname.log.\n"; } if ($testtype{$tname} eq "NI") { &print_rpt("Not Implemented.\n"); $not_impl++; next; } if (! -e "./$srcpath{$tname}/$tname.v") { &print_rpt("Failed - missing source file.\n"); $failed++; next; } # # Build up the iverilog command line and run it. # $pass_type = 0; $cmd = $with_valg ? "valgrind --trace-children=yes " : ""; $cmd .= "iverilog$sfx -o vlog95.v"; $cmd .= " -s $testmod{$tname}" if ($testmod{$tname} ne ""); $cmd .= $testtype{$tname} eq "CN" ? " -t null" : " -t vlog95"; $cmd .= " -pfileline=1 -pspacing=4" if ($testtype{$tname} ne "CN"); $cmd .= " -D__ICARUS_UNSIZED__ $args{$tname}"; $cmd .= " ./$srcpath{$tname}/$tname.v > log/$tname.log 2>&1"; # print "$cmd\n"; if (system("$cmd")) { if ($testtype{$tname} eq "CE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - CE (core dump).\n"); $failed++; next; } else { $pass_type = 1; } } else { &print_rpt("==> Failed - running iverilog.\n"); $failed++; next; } } else { if ($testtype{$tname} eq "CE") { &print_rpt("==> Failed - CE (no error reported).\n"); $failed++; next; } } if ($testtype{$tname} eq "CO") { &print_rpt("Passed - CO.\n"); $passed++; next; } if ($testtype{$tname} eq "CN") { &print_rpt("Passed - CN.\n"); $passed++; next; } # Run the translated Verilog code. All compile errors should # already be handled. Remove the -S flag if it exists along # with any included source file(s) and any -f arguments. The # -pallowsigned flag and the various generation flags should # also be removed. If we had -pallowsigned=1 then use the # -g2001-noconfig to get signed/unsigned otherwise use -g1995. my $gen_flag; if($args{$tname} =~ m/-pallowsigned=1/) { $gen_flag = "-g2001-noconfig"; } else { $gen_flag = "-g1995"; } $args{$tname} =~ s/-S//; $args{$tname} =~ s/\S+\.vhd//g; $args{$tname} =~ s/\S+\.v//g; $args{$tname} =~ s/-f\S+//g; $args{$tname} =~ s/-pallowsigned=1//g; $args{$tname} =~ s/-g2001(-noconfig)?//g; $args{$tname} =~ s/-g2005(-sv)?//g; $args{$tname} =~ s/-g2009//g; $args{$tname} =~ s/-g2012//g; $args{$tname} =~ s/-gverilog-ams//g; $cmd = "iverilog$sfx -o vsim $gen_flag $args{$tname}"; $cmd .= " -s $testmod{$tname}" if ($testmod{$tname} ne ""); $cmd .= " vlog95.v >> log/$tname.log 2>&1"; # print "$cmd\n"; if ($pass_type == 0 and system("$cmd")) { if ($testtype{$tname} eq "TE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - TE (core dump).\n"); $failed++; next; } else { $pass_type = 3; } } else { &print_rpt("==> Failed - running iverilog (translated).\n"); $failed++; next; } } $cmd = "vvp$sfx vsim $plargs{$tname} >> log/$tname.log 2>&1"; # print "$cmd\n"; if ($pass_type == 0 and system("$cmd")) { if ($testtype{$tname} eq "RE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - RE (core dump).\n"); $failed++; next; } else { $pass_type = 2; } } else { &print_rpt("==> Failed - running vvp.\n"); $failed++; next; } } if ($diff{$tname} ne "") { $diff_file = $diff{$tname} } else { if ($pass_type == 1) { &print_rpt("Passed - CE.\n"); $passed++; next; } elsif ($pass_type == 2) { &print_rpt("Passed - RE.\n"); $passed++; next; } elsif ($pass_type == 3) { &print_rpt("Passed - TE.\n"); $passed++; next; } $diff_file = "log/$tname.log"; } # print "diff $gold{$tname}, $diff_file, $offset{$tname}, $unordered{$tname}\n"; if (diff($gold{$tname}, $diff_file, $offset{$tname}, $unordered{$tname})) { if ($testtype{$tname} eq "EF") { &print_rpt("Passed - expected fail.\n"); $expected_fail++; next; } &print_rpt("==> Failed -"); if ($pass_type == 1) { &print_rpt(" CE -"); } elsif ($pass_type == 2) { &print_rpt(" RE -"); } elsif ($pass_type == 3) { &print_rpt(" TE -"); } &print_rpt(" output does not match gold file.\n"); $failed++; next; } if ($pass_type == 1) { &print_rpt("Passed - CE.\n"); } elsif ($pass_type == 2) { &print_rpt("Passed - RE.\n"); } elsif ($pass_type == 3) { &print_rpt("Passed - TE.\n"); } else { &print_rpt("Passed.\n"); } $passed++; } continue { if ($tname ne "") { system("rm -f ./vlog95.v ./vsim") and die "Error: failed to remove temporary file.\n"; } } &print_rpt("=" x 76 . "\n"); &print_rpt("Test results:\n Total=$total, Passed=$passed, Failed=$failed,". " Not Implemented=$not_impl, Expected Fail=$expected_fail\n"); } iverilog-12_0/ivtest/vpi/000077500000000000000000000000001435245347300154635ustar00rootroot00000000000000iverilog-12_0/ivtest/vpi/br_gh117.c000066400000000000000000000034571435245347300171520ustar00rootroot00000000000000#include PLI_INT32 readWriteSynch(p_cb_data cb_data) { vpi_printf("Read write - current time %d\n", cb_data->time->low); return 0; } PLI_INT32 readOnlySynch(p_cb_data cb_data) { vpi_printf("Read only - current time %d\n", cb_data->time->low); return 0; } PLI_INT32 afterDelay(p_cb_data cb_data) { s_cb_data cb_data_s; s_vpi_time time_s; PLI_INT32 time = cb_data != NULL ? cb_data->time->low : 0; PLI_INT32 period = 10; if (time < 50) { vpi_printf("After delay - current time %d\n", time); // set null pointers cb_data_s.obj = NULL; cb_data_s.value = NULL; cb_data_s.user_data = NULL; // time cb_data_s.time = &time_s; time_s.type = vpiSimTime; time_s.high = 0; // register read_write_synch time_s.low = 1; cb_data_s.reason = cbReadWriteSynch; cb_data_s.cb_rtn = readWriteSynch; vpi_free_object(vpi_register_cb(&cb_data_s)); // register read_only_synch time_s.low = period-1; cb_data_s.reason = cbReadOnlySynch; cb_data_s.cb_rtn = readOnlySynch; vpi_free_object(vpi_register_cb(&cb_data_s)); // register next time step time_s.low = period; cb_data_s.reason = cbAfterDelay; cb_data_s.cb_rtn = afterDelay; vpi_free_object(vpi_register_cb(&cb_data_s)); } else { vpi_printf("Finish sim - current time %d\n", time); // finish simulation vpi_control(vpiFinish, 0); } return 0; } void registerCallbacks(void) { vpi_printf("Register callbacks\n"); afterDelay(NULL); } void (*vlog_startup_routines[])(void) = { registerCallbacks, 0 }; iverilog-12_0/ivtest/vpi/br_gh117.v000066400000000000000000000000601435245347300171600ustar00rootroot00000000000000module cb(); always begin #1; end endmodule iverilog-12_0/ivtest/vpi/br_gh141.c000066400000000000000000000020231435245347300171330ustar00rootroot00000000000000#include #include "veriuser.h" #include "acc_user.h" static int calltf(int ud, int reason) { (void)ud; (void)reason; tf_asynchon(); return 0; } static int misctf(int ud, int reason, int paramvc) { handle hdl1; handle hdl2; s_setval_value val; s_setval_delay dly; (void)ud; (void)paramvc; io_printf("misctf called for reason %d\n", reason); hdl1 = acc_handle_tfarg(1); assert(hdl1); hdl2 = acc_handle_tfarg(2); assert(hdl2); if (reason == reason_paramvc && paramvc == 1) { val.format = accIntVal; (void)acc_fetch_value(hdl1, "%%", &val); dly.model = accNoDelay; (void)acc_set_value(hdl2, &val, &dly); } return 0; } s_tfcell veriusertfs[2] = { {usertask, 0, 0, 0, calltf, misctf, "$background_copy", 1, 0, 0, {0} }, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } }; static void veriusertfs_register(void) { veriusertfs_register_table(veriusertfs); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/br_gh141.v000066400000000000000000000003631435245347300171630ustar00rootroot00000000000000module test; reg [15:0] x; reg [15:0] y; initial begin x = 0; y = 0; $monitor(x,,y); $background_copy(x, y); #1 $display("started background copy"); #1 x = 1; #1 x = 2; #1 $display("finished background copy"); end endmodule iverilog-12_0/ivtest/vpi/br_gh169.c000066400000000000000000000032111435245347300171450ustar00rootroot00000000000000# include # include # include # include static void list_vars(vpiHandle scope) { vpiHandle iter; vpiHandle item; iter = vpi_iterate(vpiNet, scope); if (iter) { while ( (item = vpi_scan(iter)) ) { vpi_printf(" wire %s\n", vpi_get_str(vpiFullName, item)); } } iter = vpi_iterate(vpiReg, scope); if (iter) { while ( (item = vpi_scan(iter)) ) { vpi_printf(" reg %s\n", vpi_get_str(vpiFullName, item)); } } iter = vpi_iterate(vpiRealVar, scope); if (iter) { while ( (item = vpi_scan(iter)) ) { vpi_printf(" real %s\n", vpi_get_str(vpiFullName, item)); } } iter = vpi_iterate(vpiInternalScope, scope); if (iter) { while ( (item = vpi_scan(iter)) ) { vpi_printf("scope %s\n", vpi_get_str(vpiFullName, item)); list_vars(item); } } } static PLI_INT32 list_vars_calltf(PLI_BYTE8*xx) { vpiHandle iter = vpi_iterate(vpiModule, NULL); vpiHandle item; (void)xx; /* Parameter is not used. */ while ( (item = vpi_scan(iter)) ) { vpi_printf("scope %s\n", vpi_get_str(vpiName, item)); list_vars(item); } return 0; } static void list_vars_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$list_vars"; tf_data.calltf = list_vars_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.user_data = "$list_vars"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { list_vars_register, 0 }; iverilog-12_0/ivtest/vpi/br_gh169a.v000066400000000000000000000004031435245347300173310ustar00rootroot00000000000000module dut1(input wire i1, output reg o1); always @* o1 = i1; endmodule module dut2(input wire i2, output reg o2); always @* o2 = i2; endmodule module test(); wire a, b, c; dut2 dut2(a, b); dut1 dut1(b, c); initial begin $list_vars; end endmodule iverilog-12_0/ivtest/vpi/br_gh169b.v000066400000000000000000000003771435245347300173440ustar00rootroot00000000000000module dut1(input real i1, output real o1); assign o1 = i1; endmodule module dut2(input real i2, output real o2); assign o2 = i2; endmodule module test(); real a, b, c; dut2 dut2(a, b); dut1 dut1(b, c); initial begin $list_vars; end endmodule iverilog-12_0/ivtest/vpi/br_gh184.v000066400000000000000000000017341435245347300171750ustar00rootroot00000000000000// When registering a simulation time callback, some simulators interpret // the specified time value as relative to the current simulation time. To // support this case, define the macro CB_TIME_IS_RELATIVE when compiling // this module. module main; integer val1, val2; initial begin val1 = 0; val2 = 1; #1; $poke_at_simtime(val1, 1, 10); $poke_at_simtime(val2, 2, 10); `ifdef CB_TIME_IS_RELATIVE #1; `endif #8; if (val1 !== 0) begin $display("FAILED -- val1==%0d before delayed poke", val1); $finish; end if (val2 !== 1) begin $display("FAILED -- val2==%0d before delayed poke", val2); $finish; end #1; if (val1 !== 1) begin $display("FAILED -- val1==%0d: poke didn't happen", val1); $finish; end if (val2 !== 2) begin $display("FAILED -- val2==%0d: poke didn't happen", val2); $finish; end $display("PASSED"); $finish(0); end endmodule // main iverilog-12_0/ivtest/vpi/br_gh235.c000066400000000000000000000014641435245347300171470ustar00rootroot00000000000000#include #include "vpi_user.h" static PLI_INT32 atEndOfCompile(s_cb_data *data) { vpiHandle handle; s_vpi_time time = { vpiSimTime, 0, 0, 0 }; s_vpi_value value; (void)data; /* Parameter is not used. */ handle = vpi_handle_by_name("test.flag", 0); assert(handle); value.format = vpiIntVal; value.value.integer = 1; vpi_put_value(handle, &value, &time, vpiPureTransportDelay); return 0; } static void vpiRegister(void) { s_cb_data cb_data; s_vpi_time time = { vpiSuppressTime, 0, 0, 0 }; cb_data.time = &time; cb_data.value = 0; cb_data.user_data = 0; cb_data.obj = 0; cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = atEndOfCompile; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[]) (void) = { vpiRegister, 0}; iverilog-12_0/ivtest/vpi/br_gh235.v000066400000000000000000000003321435245347300171630ustar00rootroot00000000000000module test; typedef enum reg { FALSE = 1'b0, TRUE = 1'b1 } boolean; boolean flag; initial begin #1 $display("%b", flag); if (flag === TRUE) $display("PASSED"); else $display("FAILED"); end endmodule iverilog-12_0/ivtest/vpi/br_gh308.c000066400000000000000000000020661435245347300171470ustar00rootroot00000000000000# include # include static int test_calltf(char*user_data) { s_vpi_value value; (void)user_data; /* Parameter is not used. */ vpiHandle vec_handle = vpi_handle_by_name("test.vec", 0); vpiHandle msb_handle = vpi_handle(vpiLeftRange, vec_handle); vpiHandle lsb_handle = vpi_handle(vpiRightRange, vec_handle); assert(msb_handle); assert(lsb_handle); value.format = vpiBinStrVal; vpi_get_value(msb_handle, &value); vpi_printf("msb = 'b_%s\n", value.value.str); value.format = vpiBinStrVal; vpi_get_value(lsb_handle, &value); vpi_printf("lsb = 'b_%s\n", value.value.str); return 0; } static void vpi_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.calltf = test_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.tfname = "$test"; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { vpi_register, 0 }; iverilog-12_0/ivtest/vpi/br_gh308.v000066400000000000000000000001601435245347300171630ustar00rootroot00000000000000module test; reg [31:0] vec; initial begin vec = 0; // make sure vec is not pruned $test; end endmodule iverilog-12_0/ivtest/vpi/br_gh317.c000066400000000000000000000025751435245347300171540ustar00rootroot00000000000000#include "vpi_user.h" static void get_type(char *obj, vpiHandle scope) { vpiHandle hand; vpi_printf("Looking for \"%s\": ", obj); hand = vpi_handle_by_name(obj, scope); if (hand) vpi_printf("found \"%s\"\n", vpi_get_str(vpiName, hand)); else vpi_printf("Not found\n"); } static PLI_INT32 CompileTF(PLI_BYTE8 *x) { (void)x; /* Parameter is not used. */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle scope = vpi_handle(vpiScope, callh); get_type("\\esc.port", scope); get_type("\\esc.port ", scope); get_type("\\esc.mod .\\esc.inm .\\esc.port", NULL); get_type("\\esc.mod .\\esc.inm .\\esc.port ", NULL); get_type("\\esc.val", scope); get_type("\\esc.val ", scope); get_type("\\esc.mod .\\esc.inm .\\esc.val", NULL); get_type("\\esc.mod .\\esc.inm .\\esc.val ", NULL); get_type("\\esc.mod .\\esc.inm .normal", NULL); get_type("\\esc.mod .inst.\\esc.id", NULL); get_type("\\esc.mod .inst.\\esc.id ", NULL); get_type("\\esc.mod .inst.normal", NULL); return 0; } static void my_Register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$print_if_found"; tf_data.calltf = 0; tf_data.compiletf = CompileTF; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { my_Register, 0}; iverilog-12_0/ivtest/vpi/br_gh317.v000066400000000000000000000005401435245347300171650ustar00rootroot00000000000000module \esc.mod ; \esc.sub \esc.inm (1'b1); sub inst(); endmodule module \esc.sub (input wire \esc.port ); reg \esc.val ; reg normal; initial begin $print_if_found(); normal = 1'b0; \esc.val = 1'b1; end endmodule module sub; reg \esc.id ; reg normal; initial begin normal = 1'b1; \esc.id = 1'b0; end endmodule iverilog-12_0/ivtest/vpi/br_gh496.c000066400000000000000000000024651435245347300171620ustar00rootroot00000000000000# include # include # include # include static PLI_INT32 list_packages_calltf(PLI_BYTE8*xx) { vpiHandle iter = vpi_iterate(vpiPackage, NULL); vpiHandle item; (void)xx; /* Parameter is not used. */ while ( (item = vpi_scan(iter)) ) { vpi_printf("package %s\n", vpi_get_str(vpiName, item)); } return 0; } static PLI_INT32 list_modules_calltf(PLI_BYTE8*xx) { vpiHandle iter = vpi_iterate(vpiModule, NULL); vpiHandle item; (void)xx; /* Parameter is not used. */ while ( (item = vpi_scan(iter)) ) { vpi_printf("module %s\n", vpi_get_str(vpiName, item)); } return 0; } static void list_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$list_packages"; tf_data.calltf = list_packages_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.user_data = "$list_packages"; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$list_modules"; tf_data.calltf = list_modules_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.user_data = "$list_modules"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { list_register, 0 }; iverilog-12_0/ivtest/vpi/br_gh496.v000066400000000000000000000002561435245347300172010ustar00rootroot00000000000000package p1; endpackage module m1; endmodule package p2; endpackage module m2; endmodule module test; initial begin $list_packages; $list_modules; end endmodule iverilog-12_0/ivtest/vpi/br_gh59.c000066400000000000000000000035001435245347300170640ustar00rootroot00000000000000#include #include "vpi_user.h" static PLI_INT32 EndOfCompile(s_cb_data *data) { s_vpi_time timerec = { vpiSimTime, 0, 0, 0 }; s_vpi_value val; vpiHandle b0_handle; vpiHandle wr_handle; vpiHandle in_handle; (void)data; /* Parameter is not used. */ b0_handle = vpi_handle_by_name("test.B0", 0); assert(b0_handle); wr_handle = vpi_handle_by_name("test.WR", 0); assert(wr_handle); in_handle = vpi_handle_by_name("test.IN", 0); assert(in_handle); timerec.low = 500; val.value.str = "01"; val.format = vpiBinStrVal; vpi_put_value(in_handle, &val, &timerec, vpiInertialDelay); val.value.str = "zz"; val.format = vpiBinStrVal; vpi_put_value(b0_handle, &val, &timerec, vpiInertialDelay); val.format = vpiIntVal; val.value.integer = 0; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); timerec.low = 500; val.value.integer = 0; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); val.value.integer = 1; timerec.low = 1000; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); timerec.low = 1500; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); timerec.low = 2000; val.value.integer = 0; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); timerec.low = 3000; val.value.integer = 0; vpi_put_value(wr_handle, &val, &timerec, vpiInertialDelay); return 0; } static void VPIRegister(void) { s_cb_data cb_data; s_vpi_time timerec = { vpiSuppressTime, 0, 0, 0 }; cb_data.time = &timerec; cb_data.value = 0; cb_data.user_data = 0; cb_data.obj = 0; cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = EndOfCompile; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[])(void) = { VPIRegister, 0 }; iverilog-12_0/ivtest/vpi/br_gh59.v000066400000000000000000000003121435245347300171050ustar00rootroot00000000000000`timescale 1 ns / 1 ns module test( inout wire [1:0] B0, input wire WR, input wire [1:0] IN ); assign B0 = WR ? 2'bz : IN; initial $monitor("%b %b %b %0t", IN, WR, B0, $time); endmodule iverilog-12_0/ivtest/vpi/br_gh73a.v000066400000000000000000000013151435245347300172460ustar00rootroot00000000000000module partsel(inout wire [1:0] part); assign part = 2'bz; endmodule module test(); wire [3:0] full; partsel sel(full[1:0]); initial begin #1 $peek(full); #0 $display("display : %b %b", full, sel.part); #1 $force(full); #1 $peek(full); #0 $display("display : %b %b", full, sel.part); #1 $release(full); #0 $display("display : %b %b", full, sel.part); #1 $force(full); #1 $peek(full); #0 $display("display : %b %b", full, sel.part); #1 $poke(full); #1 $peek(full); #0 $display("display : %b %b", full, sel.part); #1 $release(full); #0 $display("display : %b %b", full, sel.part); #1 $poke(full); #1 $peek(full); #0 $display("display : %b %b", full, sel.part); end endmodule iverilog-12_0/ivtest/vpi/br_gh73b.v000066400000000000000000000014041435245347300172460ustar00rootroot00000000000000module partsel(inout wire [1:0] part); assign part = 2'bz; endmodule module test(); wire [3:0] full; partsel sel(full[2:1]); initial begin #1 $peek(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $force(full[2:1]); #1 $peek(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $release(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $force(full[2:1]); #1 $peek(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $poke(full[2:1]); #1 $peek(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $release(full[2:1]); #0 $display("display : %b %b", sel.part, full); #1 $poke(full[2:1]); #1 $peek(full[2:1]); #0 $display("display : %b %b", sel.part, full); end endmodule iverilog-12_0/ivtest/vpi/br_ml20191013.c000066400000000000000000000157031435245347300175510ustar00rootroot00000000000000/********************************************************************** * $pow example -- PLI application using VPI routines * * C source to calculate the result of a number to the power of an * exponent. The result is returned as a 32-bit integer. * * Usage: result = $pow(,); * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ #define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ #include /* ANSI C standard library */ #include /* ANSI C standard input/output library */ #include /* ANSI C standard arguments library */ #include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */ #if VPI_1995 #include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */ #endif /* prototypes of PLI application routine names */ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowSizetf(char *user_data); static PLI_INT32 PLIbook_PowCalltf(char *user_data); static PLI_INT32 PLIbook_PowCompiletf(char *user_data); #else static PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data); static PLI_INT32 PLIbook_PowCalltf(PLI_BYTE8 *user_data); static PLI_INT32 PLIbook_PowCompiletf(PLI_BYTE8 *user_data); #endif static PLI_INT32 PLIbook_PowStartOfSim(s_cb_data *callback_data); /********************************************************************** * $pow Registration Data * (add this function name to the vlog_startup_routines array) *********************************************************************/ void PLIbook_pow_register(void) { s_vpi_systf_data tf_data; s_cb_data cb_data_s; vpiHandle callback_handle; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncSized; tf_data.tfname = "$pow"; tf_data.calltf = PLIbook_PowCalltf; tf_data.compiletf = PLIbook_PowCompiletf; tf_data.sizetf = PLIbook_PowSizetf; tf_data.user_data = NULL; vpi_register_systf(&tf_data); cb_data_s.reason = cbStartOfSimulation; cb_data_s.cb_rtn = PLIbook_PowStartOfSim; cb_data_s.obj = NULL; cb_data_s.time = NULL; cb_data_s.value = NULL; cb_data_s.user_data = NULL; callback_handle = vpi_register_cb(&cb_data_s); vpi_free_object(callback_handle); /* don't need callback handle */ } /********************************************************************** * Sizetf application *********************************************************************/ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowSizetf(char *user_data) #else static PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data) #endif { (void)user_data; /* Parameter is not used. */ //vpi_printf("\n$pow PLI sizetf function.\n\n"); return(32); /* $pow returns 32-bit values */ } /********************************************************************** * compiletf application to verify valid systf args. *********************************************************************/ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowCompiletf(char *user_data) #else static PLI_INT32 PLIbook_PowCompiletf(PLI_BYTE8 *user_data) #endif { vpiHandle systf_handle, arg_itr, arg_handle; PLI_INT32 tfarg_type; int err_flag = 0; (void)user_data; /* Parameter is not used. */ vpi_printf("\n$pow PLI compiletf function.\n\n"); do { /* group all tests, so can break out of group on error */ systf_handle = vpi_handle(vpiSysTfCall, NULL); arg_itr = vpi_iterate(vpiArgument, systf_handle); if (arg_itr == NULL) { vpi_printf("ERROR: $pow requires 2 arguments; has none\n"); err_flag = 1; break; } arg_handle = vpi_scan(arg_itr); tfarg_type = vpi_get(vpiType, arg_handle); if ( (tfarg_type != vpiReg) && (tfarg_type != vpiIntegerVar) && (tfarg_type != vpiConstant) ) { vpi_printf("ERROR: $pow arg1 must be number, variable or net\n"); err_flag = 1; break; } arg_handle = vpi_scan(arg_itr); if (arg_handle == NULL) { vpi_printf("ERROR: $pow requires 2nd argument\n"); err_flag = 1; break; } tfarg_type = vpi_get(vpiType, arg_handle); if ( (tfarg_type != vpiReg) && (tfarg_type != vpiIntegerVar) && (tfarg_type != vpiConstant) ) { vpi_printf("ERROR: $pow arg2 must be number, variable or net\n"); err_flag = 1; break; } if (vpi_scan(arg_itr) != NULL) { vpi_printf("ERROR: $pow requires 2 arguments; has too many\n"); vpi_free_object(arg_itr); err_flag = 1; break; } } while (0 == 1); /* end of test group; only executed once */ if (err_flag) { vpi_control(vpiFinish, 1); /* abort simulation */ } return(0); } /********************************************************************** * calltf to calculate base to power of exponent and return result. *********************************************************************/ #include #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowCalltf(char *user_data) #else static PLI_INT32 PLIbook_PowCalltf(PLI_BYTE8 *user_data) #endif { s_vpi_value value_s; vpiHandle systf_handle, arg_itr, arg_handle; PLI_INT32 base, expo; double result; (void)user_data; /* Parameter is not used. */ vpi_printf("\n$pow PLI calltf function.\n\n"); systf_handle = vpi_handle(vpiSysTfCall, NULL); arg_itr = vpi_iterate(vpiArgument, systf_handle); if (arg_itr == NULL) { vpi_printf("ERROR: $pow failed to obtain systf arg handles\n"); return(0); } /* read base from systf arg 1 (compiletf has already verified) */ arg_handle = vpi_scan(arg_itr); value_s.format = vpiIntVal; vpi_get_value(arg_handle, &value_s); base = value_s.value.integer; /* read exponent from systf arg 2 (compiletf has already verified) */ arg_handle = vpi_scan(arg_itr); vpi_free_object(arg_itr); /* not calling scan until returns null */ vpi_get_value(arg_handle, &value_s); expo = value_s.value.integer; /* calculate result of base to power of exponent */ result = pow( (double)base, (double)expo ); /* write result to simulation as return value $pow */ value_s.value.integer = (PLI_INT32)result; vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay); return(0); } /********************************************************************** * Start-of-simulation application *********************************************************************/ static PLI_INT32 PLIbook_PowStartOfSim(s_cb_data *callback_data) { (void)callback_data; /* Parameter is not used. */ vpi_printf("\n$pow StartOfSim callback.\n\n"); return(0); } /*********************************************************************/ void (*vlog_startup_routines[])(void) = { /*** add user entries here ***/ PLIbook_pow_register, //PLIbook_test_user_data_register, 0 /*** final entry must be 0 ***/ }; iverilog-12_0/ivtest/vpi/br_ml20191013.v000066400000000000000000000017431435245347300175730ustar00rootroot00000000000000/********************************************************************** * $pow example -- Verilog HDL test bench. * * Verilog test bench to test the $pow PLI application. * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ `timescale 1ns / 1ns module test; reg [31:0] result; reg a, b; initial begin $display("Start simulation pow_test.v"); a = 1; b = 0; /* Test $pow with valid values */ #1 $display("$pow(2,3) returns %d", $pow(2,3)); #1 result = $pow(a,b); #1 $display("$pow(a,b) returns %d (a=%d b=%d)", result, a, b); #1 $finish(0); end endmodule /*********************************************************************/ iverilog-12_0/ivtest/vpi/by_index.c000066400000000000000000000052671435245347300174420ustar00rootroot00000000000000#include #include "vpi_user.h" static PLI_INT32 check_val_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void) name; /* Not used */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item, index, value; s_vpi_value val; assert(argv); item = vpi_scan(argv); assert(item); index = vpi_scan(argv); assert(index); value = vpi_scan(argv); assert(value); vpi_free_object(argv); PLI_INT32 i_idx; val.format = vpiIntVal; vpi_get_value(index, &val); i_idx = val.value.integer; vpiHandle sel; sel = vpi_handle_by_index(item, i_idx); assert(sel); vpi_printf("The index is %d\n", vpi_get(vpiIndex, sel)); vpi_printf("The type is %s\n", vpi_get_str(vpiType, sel)); vpi_printf("%s ", vpi_get_str(vpiName, sel)); val.format = vpiObjTypeVal; vpi_get_value(value, &val); if (val.format == vpiRealVal) { vpi_printf("=> %.2f == ", val.value.real); val.format = vpiRealVal; vpi_get_value(sel, &val); vpi_printf("%.2f\n", val.value.real); } else { val.format = vpiDecStrVal; vpi_get_value(value, &val); vpi_printf("=> %s == ", val.value.str); val.format = vpiDecStrVal; vpi_get_value(sel, &val); vpi_printf("%s\n", val.value.str); } return 0; } static PLI_INT32 put_val_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void) name; /* Not used */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item, index, value; s_vpi_value val; assert(argv); item = vpi_scan(argv); assert(item); index = vpi_scan(argv); assert(index); value = vpi_scan(argv); assert(value); vpi_free_object(argv); PLI_INT32 i_idx; val.format = vpiIntVal; vpi_get_value(index, &val); i_idx = val.value.integer; vpiHandle sel; sel = vpi_handle_by_index(item, i_idx); assert(sel); val.format = vpiObjTypeVal; vpi_get_value(value, &val); assert (val.format != vpiRealVal); val.format = vpiIntVal; vpi_get_value(value, &val); vpi_put_value(sel, &val, NULL, vpiNoDelay); return 0; } static void check_val_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$check_val"; tf_data.calltf = check_val_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$put_val"; tf_data.calltf = put_val_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { check_val_register, 0 }; iverilog-12_0/ivtest/vpi/by_index.v000066400000000000000000000015361435245347300174600ustar00rootroot00000000000000module top; reg [8:1] val; wire [1:4] wval; reg [3:0] wdrv; real r_arr [1:8]; integer i_arr [8:1]; integer lp; assign wval = wdrv; initial begin wdrv = 4'b1010; for (lp=1; lp<=8; lp=lp+1) begin val[lp] = lp % 2; r_arr[lp] = lp + 0.25; i_arr[lp] = lp - 1; end #1; $check_val(val, 3, 1); $check_val(wval, 4, 0); $check_val(r_arr, 5, 5.25); $check_val(i_arr, 2, 1); $display("Original value is %b", val); $put_val(val, 2, 1); $put_val(val, 1, 0); $display(" New value is %b", val); $display("Original net value is %b", wval); $put_val(wval, 2, 1); $put_val(wval, 1, 0); $display(" New net value is %b", wval); #1; // Verify that an update overrides the put value wdrv = 4'b1001; $display(" net value is now %b", wval); end endmodule iverilog-12_0/ivtest/vpi/by_name.c000066400000000000000000000042111435245347300172370ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies some functionality of vpi_handle_by_name() */ #include #include #include "vpi_user.h" static void FindHandleByName(void) { int i; vpiHandle hand; char *s[] = { "top0", "top0.t_my", "top0.f_my", "top0.r", "top0.t", "top0.e", "top0.i", "top0.init", "top0.lvl1_0", "top0.lvl1_1", "top0.lvl1_0.lvl2.t_my", "top0.lvl1_0.lvl2.f_my", "top0.lvl1_0.lvl2.r", "top0.lvl1_0.lvl2.t", "top0.lvl1_0.lvl2.e", "top0.lvl1_0.lvl2.i", "top0.lvl1_0.lvl2.init", "top1", "noexsist", "top1.noexsist", "top1.lvl1.noexsist", 0 }; for (i=0; s[i]; i++) { vpi_printf("Looking up %s: ", s[i]); hand = vpi_handle_by_name(s[i], NULL); if (hand) vpi_printf("Found name = %s, type = %d\n", vpi_get_str(vpiName, hand), (int)vpi_get(vpiType, hand)); else vpi_printf("*** Not found ***\n"); } } #ifdef IVERILOG_V0_8 static PLI_INT32 CompileTF(char *x) #else static PLI_INT32 CompileTF(PLI_BYTE8 *x) #endif { (void)x; /* Parameter is not used. */ FindHandleByName(); return 0; } static void my_Register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test"; tf_data.calltf = 0; tf_data.compiletf = CompileTF; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { my_Register, 0}; iverilog-12_0/ivtest/vpi/by_name.v000066400000000000000000000030071435245347300172640ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module lvl2; reg r; time t; event e; integer i; task t_my; r = 1'b0; endtask function f_my; input in; begin f_my = !in; end endfunction initial begin: init t_my; r = f_my(r); r = f_my(i); r = f_my(t); ->e; end endmodule module lvl1; lvl2 lvl2(); endmodule module top0; reg r; time t; event e; integer i; task t_my; r = 1'b0; endtask function f_my; input in; begin f_my = !in; end endfunction initial begin: init t_my; r = f_my(r); r = f_my(i); r = f_my(t); ->e; end lvl1 lvl1_0(); lvl1 lvl1_1(); endmodule module top1; initial begin: init $test; end endmodule iverilog-12_0/ivtest/vpi/callback1.c000066400000000000000000000045231435245347300174500ustar00rootroot00000000000000/* * Copyright (c) 2002 Mike Runyan, Michael Ruff * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include "vpi_user.h" static PLI_INT32 my_EndOfCompile(p_cb_data cb_data) { vpi_printf ("EndOfCompile %s\n", cb_data->user_data); return 0; } static PLI_INT32 my_StartOfSimulation(p_cb_data cb_data) { vpi_printf ("StartOfSimulation %s\n", cb_data->user_data); return 0; } static PLI_INT32 my_EndOfSimulation(p_cb_data cb_data) { vpi_printf ("EndOfSimulation %s\n", cb_data->user_data); return 0; } static void my_Register(void) { s_cb_data cb_data; cb_data.time = NULL; vpi_printf("Registering Callbacks\n"); // first register cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = my_EndOfCompile; cb_data.user_data = "EOC"; vpi_register_cb(&cb_data); cb_data.reason = cbStartOfSimulation; cb_data.cb_rtn = my_StartOfSimulation; cb_data.user_data = "SOS"; vpi_register_cb(&cb_data); cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = my_EndOfSimulation; cb_data.user_data = "EOS"; vpi_register_cb(&cb_data); // second register cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = my_EndOfCompile; cb_data.user_data = "EOC"; vpi_register_cb(&cb_data); cb_data.reason = cbStartOfSimulation; cb_data.cb_rtn = my_StartOfSimulation; cb_data.user_data = "SOS"; vpi_register_cb(&cb_data); cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = my_EndOfSimulation; cb_data.user_data = "EOS"; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[])(void) = { my_Register, 0 }; iverilog-12_0/ivtest/vpi/callback1.v000066400000000000000000000015721435245347300174740ustar00rootroot00000000000000/* * Copyright (c) 2002 Mike Runyan, Michael Ruff * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module test; initial $display("Hello World"); endmodule iverilog-12_0/ivtest/vpi/celldefine.c000066400000000000000000000013751435245347300177270ustar00rootroot00000000000000#include "vpi_user.h" static PLI_INT32 calltf(PLI_BYTE8 *data) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle mod = vpi_scan(argv); (void)data; /* Parameter is not used. */ vpi_free_object(argv); vpi_printf("Module instance %s is%s a cell.\n", vpi_get_str(vpiFullName, mod), vpi_get(vpiCellInstance, mod) ? "" : " not"); return 0; } static void vpi_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$is_cell"; tf_data.calltf = calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = {vpi_register, 0}; iverilog-12_0/ivtest/vpi/celldefine.v000066400000000000000000000014431435245347300177460ustar00rootroot00000000000000module top; reg pass; reg in; wire out, outb; lower_cell dutb(outb, in); lower_no_cell dut(out, in); always @(outb) begin if (outb !== ~in) begin $display("FAILED outb at time %t, expected %b, got %b", $time, ~in, outb); pass = 1'b0; end end always @(out) begin if (out !== in) begin $display("FAILED out at time %t, expected %b, got %b", $time, in, out); pass = 1'b0; end end initial begin pass = 1'b1; #1 in = 1'b0; #1 in = 1'b1; #1 in = 1'b0; #1 if (pass) $display("Verilog checking was OK."); $is_cell(dut); $is_cell(dutb); end endmodule `celldefine module lower_cell(output out, input in); not(out, in); endmodule `endcelldefine module lower_no_cell(output out, input in); buf(out, in); endmodule iverilog-12_0/ivtest/vpi/check_version.c000066400000000000000000000061471435245347300204610ustar00rootroot00000000000000/* * This test verifies the the vpi_get_vlog_info() call returns the * version information correctly. This does not currently work in * V0.8 so it is marked NI. */ #include "vpi_user.h" #include #include static PLI_INT32 compiletf(PLI_BYTE8 *name) { vpiHandle callh, argv, arg; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); /* Check that there is an argument. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() requires a single vector argument!", name); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (arg == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() requires a single vector argument!", name); vpi_control(vpiFinish, 1); return 0; } /* Check that the argument is a register with at least 640 bits. */ if (vpi_get(vpiType, arg) != vpiReg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() requires a vector argument!", name); vpi_free_object(argv); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiSize, arg) < 640) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() vector is too small need 640 bits!", name); vpi_free_object(argv); vpi_control(vpiFinish, 1); return 0; } /* We only take one argument. */ arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() only takes one argument!", name); vpi_free_object(argv); vpi_control(vpiFinish, 1); return 0; } return 0; } static PLI_INT32 calltf(PLI_BYTE8 *name) { vpiHandle callh, argv, reg; s_vpi_vlog_info info; s_vpi_value val; PLI_INT32 ret; char *str, *cp; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); reg = vpi_scan(argv); vpi_free_object(argv); /* Get the Verilog version information. */ ret = vpi_get_vlog_info(&info); if (ret == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() failed to get verilog information!", name); vpi_control(vpiFinish, 1); } /* For Icarus we can just return everything before the space to * get the version and subversion. */ str = strdup(info.version); cp = strchr(str, ' '); if (cp) *cp = '\0'; val.format = vpiStringVal; val.value.str = str; vpi_put_value(reg, &val, 0, vpiNoDelay); free(str); return 0; } static void my_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$get_version"; tf_data.calltf = calltf; tf_data.compiletf = compiletf; tf_data.sizetf = 0; tf_data.user_data = "$get_version"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { my_register, 0}; iverilog-12_0/ivtest/vpi/check_version.v000066400000000000000000000013051435245347300204730ustar00rootroot00000000000000module top; reg [80*8:1] simp_str, info_str; real ver, subver; initial begin ver = $simparam("simulatorVersion"); subver = $simparam("simulatorSubversion"); // For 0.9 only use one digit after the decimal point. if (ver < 1.0) $swrite(simp_str, "%0.1f.%0.0f", ver, subver); // For the rest, 10 and above, use no digits after the decimal point. else $swrite(simp_str, "%0.0f.%0.0f", ver, subver); $get_version(info_str); if (simp_str !== info_str) begin $display("FAILED"); $display("$simparam version: '%0s'", simp_str); $display("vpi_get_vlog_info version: '%0s'", info_str); end else $display("The two versions matched!"); end endmodule iverilog-12_0/ivtest/vpi/display_array.c000066400000000000000000000162041435245347300204750ustar00rootroot00000000000000/* * Copyright (c) 2014-2021 CERN * @author Maciej Suminski * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include # include # include static PLI_INT32 display_array_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, array, cell, l_range, r_range; s_vpi_value val; /* Fetch arguments */ argv = vpi_iterate(vpiArgument, callh); assert(argv); array = vpi_scan(argv); assert(array); vpi_free_object(argv); int array_size = vpi_get(vpiSize, array); if(array_size < 0) { vpi_printf("ERROR: Arrays cannot have negative size"); vpi_control(vpiFinish, 0); return 0; } /* Test range handles */ l_range = vpi_handle(vpiLeftRange, array); r_range = vpi_handle(vpiRightRange, array); val.format = vpiIntVal; vpi_get_value(l_range, &val); int left = val.value.integer; vpi_get_value(r_range, &val); int right = val.value.integer; assert(right - left + 1 == array_size); /*vpi_printf("array range: %d to %d\n", left, right);*/ /* Test accessing cells by index */ vpi_printf("{ "); int i; for(i = 0; i < array_size; ++i) { cell = vpi_handle_by_index(array, i); val.format = vpiObjTypeVal; vpi_get_value(cell, &val); if(val.format == vpiRealVal) vpi_printf("%f", val.value.real); else if(val.format == vpiStringVal) vpi_printf("%s", val.value.str); else { // convenient way to handle all other formats val.format = vpiDecStrVal; vpi_get_value(cell, &val); // sorry for another vpi call vpi_printf("%s", val.value.str); } if(i != array_size - 1) vpi_printf(", "); } vpi_printf(" }\n"); return 0; } static PLI_INT32 increase_array_vals_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, array, array_iterator, cell; PLI_INT32 iter_type; s_vpi_value val; /* Fetch arguments */ argv = vpi_iterate(vpiArgument, callh); assert(argv); array = vpi_scan(argv); assert(array); vpi_free_object(argv); switch(vpi_get(vpiType, array)) { case vpiArrayType: case vpiRegArray: iter_type = vpiReg; break; case vpiMemory: iter_type = vpiMemoryWord; break; default: vpi_printf("sorry: increase_array_vals: missing iterator for " "the given array type\n"); return 0; } /* Test accessing cells with iterators */ array_iterator = vpi_iterate(iter_type, array); while((cell = vpi_scan(array_iterator))) { /* Test format recognition */ val.format = vpiObjTypeVal; vpi_get_value(cell, &val); /* Increase the read value */ switch(val.format) { case vpiIntVal: ++val.value.integer; break; case vpiVectorVal: /* Only support a single aval */ assert((uint32_t)val.value.vector->aval < UINT_MAX); assert(val.value.vector->bval == 0); ++val.value.vector->aval; break; case vpiRealVal: ++val.value.real; break; case vpiStringVal: { char*s = val.value.str; while(*s) ++*s++; // oh yeah, I love C } break; default: vpi_printf("sorry: increase_array_vals: format not implemented\n"); return 0; } /* Test data write */ vpi_put_value(cell, &val, 0, vpiNoDelay); } return 0; } static PLI_INT32 one_arg_array_compiletf(ICARUS_VPI_CONST PLI_BYTE8*user_data) { (void) user_data; /* Parameter is not used. */ vpiHandle systf_handle, arg_iterator, arg_handle; PLI_INT32 arg_type; /* obtain a handle to the system task instance */ systf_handle = vpi_handle(vpiSysTfCall, NULL); if (systf_handle == NULL) { vpi_printf("ERROR: $display_array failed to obtain systf handle\n"); vpi_control(vpiFinish,0); /* abort simulation */ return 0; } /* obtain handles to system task arguments */ arg_iterator = vpi_iterate(vpiArgument, systf_handle); if (arg_iterator == NULL) { vpi_printf("ERROR: $display_array requires exactly 1 argument\n"); vpi_control(vpiFinish, 0); return 0; } /* check the type of object in system task arguments */ arg_handle = vpi_scan(arg_iterator); if (vpi_scan(arg_iterator) != NULL) { /* are there more arguments? */ vpi_printf("ERROR: $display_array takes only 1 argument\n"); vpi_free_object(arg_iterator); vpi_control(vpiFinish, 0); return 0; } arg_type = vpi_get(vpiType, arg_handle); if (arg_type != vpiArrayType && arg_type != vpiRegArray && arg_type != vpiMemory) { vpi_printf("%d", arg_type); // TODO remove vpi_printf("ERROR: $display_array works only with arrays\n"); vpi_free_object(arg_iterator); vpi_control(vpiFinish, 0); return 0; } return 0; } static void test_array_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$display_array"; tf_data.calltf = display_array_calltf; tf_data.compiletf = one_arg_array_compiletf; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$increase_array_vals"; tf_data.calltf = increase_array_vals_calltf; tf_data.compiletf = one_arg_array_compiletf; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { test_array_register, 0 }; iverilog-12_0/ivtest/vpi/display_array.v000066400000000000000000000033071435245347300205200ustar00rootroot00000000000000/* * Copyright (c) 2014 CERN * @author Maciej Suminski * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ // Test for VPI functions handling dynamic arrays module main(); initial begin int int_darray[]; real real_darray[]; bit [63:0] bit_darray[]; string string_darray[]; int_darray = new[4]; int_darray = '{1, 2, 3, 4}; $display_array(int_darray); $increase_array_vals(int_darray); $display_array(int_darray); real_darray = new[2]; real_darray = '{2.2, 2.3}; $increase_array_vals(real_darray); $display_array(real_darray); bit_darray = new[4]; bit_darray = '{64'hdeadbeefcafebabe, 64'h0badc0dec0dec0de, 64'h0123456789abcdef, 64'hfedcba9876543210}; $increase_array_vals(bit_darray); $display_array(bit_darray); string_darray = new[4]; string_darray = '{"test string", "another one", "yet one more", "the last one"}; $increase_array_vals(string_darray); $display_array(string_darray); end endmodule iverilog-12_0/ivtest/vpi/event1.c000066400000000000000000000036021435245347300170320ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test that named events are passed properly to system tasks. */ #include #include #include "vpi_user.h" static int num; #ifdef IVERILOG_V0_8 static PLI_INT32 CompileTF(char *x) #else static PLI_INT32 CompileTF(PLI_BYTE8 *x) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; int first = 1; (void)x; /* Parameter is not used. */ vpi_printf("%s (", vpi_get_str(vpiName, sys)); while ((arg = vpi_scan(argv))) { if (!first) vpi_printf(", "); else first = 0; vpi_printf("%s [type = %d]", vpi_get_str(vpiFullName, arg), (int)vpi_get(vpiType, arg)); if (vpi_get(vpiType, arg) == vpiNamedEvent) num++; } vpi_printf(")\n"); if (num == 2) vpi_printf("PASSED\n"); return 0; } static void Register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test"; tf_data.calltf = 0; tf_data.compiletf = CompileTF; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { Register, 0}; iverilog-12_0/ivtest/vpi/event1.v000066400000000000000000000020001435245347300170440ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Test that named events are passed properly to system tasks. */ module test(); event evt, evt2; initial begin //->evt; $test(evt, evt2, test); end endmodule iverilog-12_0/ivtest/vpi/event2.c000066400000000000000000000043031435245347300170320ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies deletion of event callbacks */ #include #include "vpi_user.h" static vpiHandle Handle; static PLI_INT32 Callback(s_cb_data *data) { s_vpi_time t; static int count = 0; (void)data; /* Parameter is not used. */ t.type = vpiScaledRealTime; vpi_get_time(0, &t); vpi_printf("Callback @ %.1f\n", t.real); if (count>1) { vpi_printf("vpi_remove_cb returned %d @ %.1f\n", (int)vpi_remove_cb(Handle), t.real); } count++; return 0; } static PLI_INT32 CallbackRegister(s_cb_data *data) { vpiHandle hand; s_cb_data cb_data; s_vpi_time timerec = { vpiSimTime, 0, 0, 0 }; (void)data; /* Parameter is not used. */ hand = vpi_handle_by_name("test.e", 0); assert(hand); cb_data.time = &timerec; cb_data.value = 0; cb_data.user_data = (char *)hand; cb_data.obj = hand; cb_data.reason = cbValueChange; cb_data.cb_rtn = Callback; Handle = vpi_register_cb(&cb_data); return (0); } static void VPIRegister(void) { s_cb_data cb_data; s_vpi_time timerec = { vpiSuppressTime, 0, 0, 0 }; cb_data.time = &timerec; cb_data.value = 0; cb_data.user_data = 0; cb_data.obj = 0; cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = CallbackRegister; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[]) (void) = { VPIRegister, 0}; iverilog-12_0/ivtest/vpi/event2.v000066400000000000000000000001511435245347300170520ustar00rootroot00000000000000module test; event e; initial begin repeat (5) begin #10; ->e; end end endmodule iverilog-12_0/ivtest/vpi/final.c000066400000000000000000000012231435245347300167160ustar00rootroot00000000000000#include #include static PLI_INT32 end_of_sim_cb(struct t_cb_data *x) { (void)x; /* Parameter is not used. */ vpi_printf("In VPI cbEndOfSimulation callback.\n"); return 0; } static void cb_register(void) { s_cb_data cb_data; memset(&cb_data, 0, sizeof(s_cb_data)); cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = end_of_sim_cb; vpi_register_cb(&cb_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { cb_register, 0 }; iverilog-12_0/ivtest/vpi/final.v000066400000000000000000000001201435245347300167340ustar00rootroot00000000000000module tb; initial $finish(0); final $display("In final statement."); endmodule iverilog-12_0/ivtest/vpi/find_sig.c000066400000000000000000000013311435245347300174070ustar00rootroot00000000000000 /* */ # include # include static int sn_calltf(char*user_data) { vpiHandle obj = vpi_handle_by_name("xor_try.unused", 0); (void)user_data; /* Parameter is not used. */ if (obj==0) { vpi_printf("FAILED -- no xor_try.unused\n"); return 0; } vpi_printf("PASSED\n"); return 0; } static void vpi_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.calltf = sn_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.tfname = "$sn"; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { vpi_register, 0 }; iverilog-12_0/ivtest/vpi/find_sig.v000066400000000000000000000003631435245347300174360ustar00rootroot00000000000000//--------------------------------------------------------------------------- // //--------------------------------------------------------------------------- module xor_try; (* ivl_do_not_elide *) reg unused; initial $sn; endmodule iverilog-12_0/ivtest/vpi/force.c000066400000000000000000000063151435245347300167320ustar00rootroot00000000000000# include # include static PLI_INT32 peek_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.str = ""; val.format = vpiBinStrVal; vpi_get_value(arg, &val); vpi_printf("peek : %s\n", val.value.str); return 0; } static int count = 0; static PLI_INT32 poke_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.integer = count++; val.format = vpiIntVal; vpi_put_value(arg, &val, 0, vpiNoDelay); vpi_printf("poke : %d\n", val.value.integer); return 0; } static PLI_INT32 force_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.str = "10"; val.format = vpiBinStrVal; vpi_put_value(arg, &val, 0, vpiForceFlag); vpi_printf("force : %s\n", val.value.str); return 0; } static PLI_INT32 release_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.format = vpiBinStrVal; vpi_put_value(arg, &val, 0, vpiReleaseFlag); vpi_printf("release : %s\n", val.value.str); return 0; } void peekpoke_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$peek"; tf_data.calltf = peek_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$poke"; tf_data.calltf = poke_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$force"; tf_data.calltf = force_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$release"; tf_data.calltf = release_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { peekpoke_register, 0 }; iverilog-12_0/ivtest/vpi/force_real.c000066400000000000000000000063251435245347300177360ustar00rootroot00000000000000# include # include static PLI_INT32 peek_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.real = 0.0; val.format = vpiRealVal; vpi_get_value(arg, &val); vpi_printf("peek : %f\n", val.value.real); return 0; } static int count = 1.0; static PLI_INT32 poke_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.real = count; count += 1.0; val.format = vpiRealVal; vpi_put_value(arg, &val, 0, vpiNoDelay); vpi_printf("poke : %f\n", val.value.real); return 0; } static PLI_INT32 force_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.value.real = 3.0; val.format = vpiRealVal; vpi_put_value(arg, &val, 0, vpiForceFlag); vpi_printf("force : %f\n", val.value.real); return 0; } static PLI_INT32 release_calltf(PLI_BYTE8 *xx) { s_vpi_value val; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)xx; arg = vpi_scan(argv); vpi_free_object(argv); /* Free iterator since we did not scan to NULL. */ assert(arg != 0); val.format = vpiRealVal; vpi_put_value(arg, &val, 0, vpiReleaseFlag); vpi_printf("release : %f\n", val.value.real); return 0; } void peekpoke_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$peek"; tf_data.calltf = peek_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$poke"; tf_data.calltf = poke_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$force"; tf_data.calltf = force_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$release"; tf_data.calltf = release_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { peekpoke_register, 0 }; iverilog-12_0/ivtest/vpi/force_reg.v000066400000000000000000000010231435245347300176010ustar00rootroot00000000000000module test(); reg [1:0] IN; wire [1:0] OUT; assign OUT = IN; initial begin #1 $peek(IN); #0 $display("display : %b", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $release(IN); #0 $display("display : %b", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $release(IN); #0 $display("display : %b", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %b", OUT); end endmodule iverilog-12_0/ivtest/vpi/force_reg_pv.v000066400000000000000000000011031435245347300203050ustar00rootroot00000000000000module test(); reg [3:0] IN; wire [3:0] OUT; assign OUT = IN; initial begin #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $force(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $release(IN[2:1]); #0 $display("display :%b", OUT); #1 $force(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $poke(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $release(IN[2:1]); #0 $display("display :%b", OUT); #1 $poke(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); end endmodule iverilog-12_0/ivtest/vpi/force_reg_real.v000066400000000000000000000010211435245347300206020ustar00rootroot00000000000000module test(); real IN; wire real OUT; assign OUT = IN; initial begin #1 $peek(IN); #0 $display("display : %f", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $release(IN); #0 $display("display : %f", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $release(IN); #0 $display("display : %f", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %f", OUT); end endmodule iverilog-12_0/ivtest/vpi/force_wire.v000066400000000000000000000010231435245347300177720ustar00rootroot00000000000000module test(); wire [1:0] IN; wire [1:0] OUT; assign OUT = IN; initial begin #1 $peek(IN); #0 $display("display : %b", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $release(IN); #0 $display("display : %b", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %b", OUT); #1 $release(IN); #0 $display("display : %b", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %b", OUT); end endmodule iverilog-12_0/ivtest/vpi/force_wire_pv.v000066400000000000000000000011031435245347300204760ustar00rootroot00000000000000module test(); wire [3:0] IN; wire [3:0] OUT; assign OUT = IN; initial begin #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $force(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $release(IN[2:1]); #0 $display("display :%b", OUT); #1 $force(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $poke(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); #1 $release(IN[2:1]); #0 $display("display :%b", OUT); #1 $poke(IN[2:1]); #1 $peek(IN[2:1]); #0 $display("display :%b", OUT); end endmodule iverilog-12_0/ivtest/vpi/force_wire_real.v000066400000000000000000000010211435245347300207730ustar00rootroot00000000000000module test(); wire real IN; wire real OUT; assign OUT = IN; initial begin #1 $peek(IN); #0 $display("display : %f", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $release(IN); #0 $display("display : %f", OUT); #1 $force(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %f", OUT); #1 $release(IN); #0 $display("display : %f", OUT); #1 $poke(IN); #1 $peek(IN); #0 $display("display : %f", OUT); end endmodule iverilog-12_0/ivtest/vpi/genblk_direct.v000066400000000000000000000052621435245347300204530ustar00rootroot00000000000000module test; // test name collisions parameter genblk1 = 0; localparam genblk2 = 0; typedef reg genblk3; reg genblk4; wire genblk5; event genblk6; class genblk7; endclass function genblk8(); endfunction; task genblk9; endtask parameter TRUE = 1; genvar i; genvar j; for (i = 0; i < 2; i = i + 1) reg r1 = 1; for (i = 0; i < 2; i = i + 1) for (j = 0; j < 2; j = j + 1) reg r2 = 1; for (i = 0; i < 2; i = i + 1) case (TRUE) 0: reg r3a = 1; 1: reg r3b = 1; endcase for (i = 0; i < 2; i = i + 1) if (TRUE) reg r4a = 1; else reg r4b = 1; for (i = 0; i < 2; i = i + 1) if (!TRUE) reg r5a = 1; else if (TRUE) reg r5b = 1; else reg r5c = 1; for (i = 0; i < 2; i = i + 1) if (!TRUE) reg r6a = 1; else if (!TRUE) reg r6b = 1; else reg r6c = 1; case (TRUE) 0: reg r7a = 1; 1: reg r7b = 1; endcase case (TRUE) 0: case (TRUE) 0: reg r8a = 1; 1: reg r8b = 1; endcase 1: case (TRUE) 0: reg r8c = 1; 1: reg r8d = 1; endcase endcase case (TRUE) 0: if (TRUE) reg r9a = 1; else reg r9b = 1; 1: if (TRUE) reg r9c = 1; else reg r9d = 1; endcase case (TRUE) 0: if (!TRUE) reg r10a = 1; else if (TRUE) reg r10b = 1; else reg r10c = 1; 1: if (!TRUE) reg r10d = 1; else if (TRUE) reg r10e = 1; else reg r10f = 1; endcase case (TRUE) 0: if (!TRUE) reg r11a = 1; else if (!TRUE) reg r11b = 1; else reg r11c = 1; 1: if (!TRUE) reg r11d = 1; else if (!TRUE) reg r11e = 1; else reg r11f = 1; endcase if (TRUE) reg r12a = 1; else reg r12b = 1; if (!TRUE) reg r13a = 1; else if (TRUE) reg r13b = 1; else reg r13c = 1; if (!TRUE) reg r14a = 1; else if (!TRUE) reg r14b = 1; else reg r14c = 1; if (TRUE) if (TRUE) reg r15a = 1; else reg r15b = 1; else reg r15c = 1; if (TRUE) if (!TRUE) reg r16a = 1; else reg r16b = 1; else reg r16c = 1; if (TRUE) case (TRUE) 0: reg r17a = 1; 1: reg r17b = 1; endcase else case (TRUE) 0: reg r17c = 1; 1: reg r17d = 1; endcase if (!TRUE) case (TRUE) 0: reg r18a = 1; 1: reg r18b = 1; endcase else if (TRUE) case (TRUE) 0: reg r18c = 1; 1: reg r18d = 1; endcase else case (TRUE) 0: reg r18e = 1; 1: reg r18f = 1; endcase if (!TRUE) case (TRUE) 0: reg r19a = 1; 1: reg r19b = 1; endcase else if (!TRUE) case (TRUE) 0: reg r19c = 1; 1: reg r19d = 1; endcase else case (TRUE) 0: reg r19e = 1; 1: reg r19f = 1; endcase initial begin $list_regs; end endmodule iverilog-12_0/ivtest/vpi/genblk_named.v000066400000000000000000000154351435245347300202700ustar00rootroot00000000000000module test; parameter TRUE = 1; genvar i; genvar j; for (i = 0; i < 2; i = i + 1) begin : l1 reg r1 = 1; end for (i = 0; i < 2; i = i + 1) begin : l2 for (j = 0; j < 2; j = j + 1) begin : l1 reg r2 = 1; end end for (i = 0; i < 2; i = i + 1) begin : l3 case (TRUE) 0: begin : c1 reg r3a = 1; end 1: begin : c1 reg r3b = 1; end endcase end for (i = 0; i < 2; i = i + 1) begin : l4 if (TRUE) begin : i1 reg r4a = 1; end else begin : i1 reg r4b = 1; end end for (i = 0; i < 2; i = i + 1) begin : l5 if (!TRUE) begin : i1 reg r5a = 1; end else begin : i1 if (TRUE) begin : i1 reg r5b = 1; end else begin : i1 reg r5c = 1; end end end for (i = 0; i < 2; i = i + 1) begin : l6 if (!TRUE) begin : i1 reg r6a = 1; end else begin : i1 if (!TRUE) begin : i1 reg r6b = 1; end else begin : i1 reg r6c = 1; end end end case (TRUE) 0: begin : c1 reg r7a = 1; end 1: begin : c1 reg r7b = 1; end endcase case (TRUE) 0: begin : c2 case (TRUE) 0: begin : c1 reg r8a = 1; end 1: begin : c1 reg r8b = 1; end endcase end 1: begin : c2 case (TRUE) 0: begin : c1 reg r8c = 1; end 1: begin : c1 reg r8d = 1; end endcase end endcase case (TRUE) 0: begin : c3 if (TRUE) begin : i1 reg r9a = 1; end else begin : i1 reg r9b = 1; end end 1: begin : c3 if (TRUE) begin : i1 reg r9c = 1; end else begin : i1 reg r9d = 1; end end endcase case (TRUE) 0: begin : c4 if (!TRUE) begin : i1 reg r10a = 1; end else begin : i1 if (TRUE) begin : i1 reg r10b = 1; end else begin : i1 reg r10c = 1; end end end 1: begin : c4 if (!TRUE) begin : i1 reg r10d = 1; end else begin : i1 if (TRUE) begin : i1 reg r10e = 1; end else begin : i1 reg r10f = 1; end end end endcase case (TRUE) 0: begin : c5 if (!TRUE) begin : i1 reg r11a = 1; end else begin : i1 if (!TRUE) begin : i1 reg r11b = 1; end else begin : i1 reg r11c = 1; end end end 1: begin : c5 if (!TRUE) begin : i1 reg r11d = 1; end else begin : i1 if (!TRUE) begin : i1 reg r11e = 1; end else begin : i1 reg r11f = 1; end end end endcase case (TRUE) 0: begin : c6 if (!TRUE) begin : i1 reg r12a = 1; end else if (TRUE) begin : i1 reg r12b = 1; end else begin : i1 reg r12c = 1; end end 1: begin : c6 if (!TRUE) begin : i1 reg r12d = 1; end else if (TRUE) begin : i1 reg r12e = 1; end else begin : i1 reg r12f = 1; end end endcase case (TRUE) 0: begin : c7 if (!TRUE) begin : i1 reg r13a = 1; end else if (!TRUE) begin : i1 reg r13b = 1; end else begin : i1 reg r13c = 1; end end 1: begin : c7 if (!TRUE) begin : i1 reg r13d = 1; end else if (!TRUE) begin : i1 reg r13e = 1; end else begin : i1 reg r13f = 1; end end endcase if (TRUE) begin : i01 reg r14a = 1; end else begin : i01 reg r14b = 1; end if (!TRUE) begin : i02 reg r15a = 1; end else begin : i02 if (TRUE) begin : i1 reg r15b = 1; end else begin : i1 reg r15c = 1; end end if (!TRUE) begin : i03 reg r16a = 1; end else begin : i03 if (!TRUE) begin : i1 reg r16b = 1; end else begin : i1 reg r16c = 1; end end if (!TRUE) begin : i04 reg r17a = 1; end else if (TRUE) begin : i04 reg r17b = 1; end else begin : i04 reg r17c = 1; end if (!TRUE) begin : i05 reg r18a = 1; end else if (!TRUE) begin : i05 reg r18b = 1; end else begin : i05 reg r18c = 1; end if (TRUE) begin : i06 if (TRUE) begin : i1 reg r19a = 1; end else begin : i1 reg r19b = 1; end end else begin : i06 reg r19c = 1; end if (TRUE) begin : i07 if (!TRUE) begin : i1 reg r20a = 1; end else begin : i1 reg r20b = 1; end end else begin : i07 reg r20c = 1; end if (TRUE) begin : i08 case (TRUE) 0: begin : c1 reg r21a = 1; end 1: begin : c1 reg r21b = 1; end endcase end else begin : i08 case (TRUE) 0: begin : c1 reg r21c = 1; end 1: begin : c1 reg r21d = 1; end endcase end if (!TRUE) begin : i09 case (TRUE) 0: begin : c1 reg r22a = 1; end 1: begin : c1 reg r22b = 1; end endcase end else if (TRUE) begin : i09 case (TRUE) 0: begin : c1 reg r22c = 1; end 1: begin : c1 reg r22d = 1; end endcase end else begin : i09 case (TRUE) 0: begin : c1 reg r22e = 1; end 1: begin : c1 reg r22f = 1; end endcase end if (!TRUE) begin : i10 case (TRUE) 0: begin : c1 reg r23a = 1; end 1: begin : c1 reg r23b = 1; end endcase end else if (!TRUE) begin : i10 case (TRUE) 0: begin : c1 reg r23c = 1; end 1: begin : c1 reg r23d = 1; end endcase end else begin : i10 case (TRUE) 0: begin : c1 reg r23e = 1; end 1: begin : c1 reg r23f = 1; end endcase end initial begin $list_regs; end endmodule iverilog-12_0/ivtest/vpi/genblk_names.c000066400000000000000000000021101435245347300202460ustar00rootroot00000000000000#include #include #include "vpi_user.h" static void display_scope(vpiHandle scope) { vpiHandle iter; vpiHandle item; iter = vpi_iterate(vpiReg, scope); if (iter) { while ( (item = vpi_scan(iter)) ) { vpi_printf("reg %s\n", vpi_get_str(vpiFullName, item)); } } if (scope) { iter = vpi_iterate(vpiInternalScope, scope); } else { iter = vpi_iterate(vpiModule, NULL); } if (iter) { while ( (item = vpi_scan(iter)) ) { display_scope(item); } } } static PLI_INT32 list_regs_calltf(PLI_BYTE8*xx) { (void)xx; /* Parameter is not used. */ display_scope(NULL); return 0; } static void list_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$list_regs"; tf_data.calltf = list_regs_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.user_data = "$list_regs"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { list_register, 0 }; iverilog-12_0/ivtest/vpi/genblk_unnamed.v000066400000000000000000000147111435245347300206270ustar00rootroot00000000000000module test; // force leading zero on outer scope genblk numbers localparam genblk1 = 0; localparam genblk2 = 0; localparam genblk3 = 0; localparam genblk4 = 0; localparam genblk5 = 0; localparam genblk6 = 0; localparam genblk7 = 0; localparam genblk8 = 0; localparam genblk9 = 0; parameter TRUE = 1; genvar i; genvar j; for (i = 0; i < 2; i = i + 1) begin reg r1 = 1; end for (i = 0; i < 2; i = i + 1) begin for (j = 0; j < 2; j = j + 1) begin reg r2 = 1; end end for (i = 0; i < 2; i = i + 1) begin case (TRUE) 0: begin reg r3a = 1; end 1: begin reg r3b = 1; end endcase end for (i = 0; i < 2; i = i + 1) begin if (TRUE) begin reg r4a = 1; end else begin reg r4b = 1; end end for (i = 0; i < 2; i = i + 1) begin if (!TRUE) begin reg r5a = 1; end else begin if (TRUE) begin reg r5b = 1; end else begin reg r5c = 1; end end end for (i = 0; i < 2; i = i + 1) begin if (!TRUE) begin reg r6a = 1; end else begin if (!TRUE) begin reg r6b = 1; end else begin reg r6c = 1; end end end case (TRUE) 0: begin reg r7a = 1; end 1: begin reg r7b = 1; end endcase case (TRUE) 0: begin case (TRUE) 0: begin reg r8a = 1; end 1: begin reg r8b = 1; end endcase end 1: begin case (TRUE) 0: begin reg r8c = 1; end 1: begin reg r8d = 1; end endcase end endcase case (TRUE) 0: begin if (TRUE) begin reg r9a = 1; end else begin reg r9b = 1; end end 1: begin if (TRUE) begin reg r9c = 1; end else begin reg r9d = 1; end end endcase case (TRUE) 0: begin if (!TRUE) begin reg r10a = 1; end else begin if (TRUE) begin reg r10b = 1; end else begin reg r10c = 1; end end end 1: begin if (!TRUE) begin reg r10d = 1; end else begin if (TRUE) begin reg r10e = 1; end else begin reg r10f = 1; end end end endcase case (TRUE) 0: begin if (!TRUE) begin reg r11a = 1; end else begin if (!TRUE) begin reg r11b = 1; end else begin reg r11c = 1; end end end 1: begin if (!TRUE) begin reg r11d = 1; end else begin if (!TRUE) begin reg r11e = 1; end else begin reg r11f = 1; end end end endcase case (TRUE) 0: begin if (!TRUE) begin reg r12a = 1; end else if (TRUE) begin reg r12b = 1; end else begin reg r12c = 1; end end 1: begin if (!TRUE) begin reg r12d = 1; end else if (TRUE) begin reg r12e = 1; end else begin reg r12f = 1; end end endcase case (TRUE) 0: begin if (!TRUE) begin reg r13a = 1; end else if (!TRUE) begin reg r13b = 1; end else begin reg r13c = 1; end end 1: begin if (!TRUE) begin reg r13d = 1; end else if (!TRUE) begin reg r13e = 1; end else begin reg r13f = 1; end end endcase if (TRUE) begin reg r14a = 1; end else begin reg r14b = 1; end if (!TRUE) begin reg r15a = 1; end else begin if (TRUE) begin reg r15b = 1; end else begin reg r15c = 1; end end if (!TRUE) begin reg r16a = 1; end else begin if (!TRUE) begin reg r16b = 1; end else begin reg r16c = 1; end end if (!TRUE) begin reg r17a = 1; end else if (TRUE) begin reg r17b = 1; end else begin reg r17c = 1; end if (!TRUE) begin reg r18a = 1; end else if (!TRUE) begin reg r18b = 1; end else begin reg r18c = 1; end if (TRUE) begin if (TRUE) begin reg r19a = 1; end else begin reg r19b = 1; end end else begin reg r19c = 1; end if (TRUE) begin if (!TRUE) begin reg r20a = 1; end else begin reg r20b = 1; end end else begin reg r20c = 1; end if (TRUE) begin case (TRUE) 0: begin reg r21a = 1; end 1: begin reg r21b = 1; end endcase end else begin case (TRUE) 0: begin reg r21c = 1; end 1: begin reg r21d = 1; end endcase end if (!TRUE) begin case (TRUE) 0: begin reg r22a = 1; end 1: begin reg r22b = 1; end endcase end else if (TRUE) begin case (TRUE) 0: begin reg r22c = 1; end 1: begin reg r22d = 1; end endcase end else begin case (TRUE) 0: begin reg r22e = 1; end 1: begin reg r22f = 1; end endcase end if (!TRUE) begin case (TRUE) 0: begin reg r23a = 1; end 1: begin reg r23b = 1; end endcase end else if (!TRUE) begin case (TRUE) 0: begin reg r23c = 1; end 1: begin reg r23d = 1; end endcase end else begin case (TRUE) 0: begin reg r23e = 1; end 1: begin reg r23f = 1; end endcase end initial begin $list_regs; end endmodule iverilog-12_0/ivtest/vpi/getp.c000066400000000000000000000017141435245347300165710ustar00rootroot00000000000000#include "veriuser.h" static int calltf(int ud, int reason) { int i; PLI_BYTE8 *inst = tf_getinstance(); (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ for (i = 1; i < 5; i++) { io_printf("tf_getp(%d)\t\t-> %d\n", i, (int)tf_getp(i)); io_printf("tf_igetp(%d,inst)\t-> %d\n", i, (int)tf_igetp(i,inst)); io_printf("tf_getrealp(%d)\t\t-> %f\n", i, tf_getrealp(i)); io_printf("tf_igetrealp(%d,inst)\t-> %f\n", i, tf_igetrealp(i,inst)); } return 0; } static int sizetf(int ud, int reason) { (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ return 32; } s_tfcell veriusertfs[2] = { {usertask, 0, 0, sizetf, calltf, 0, "$mytest", 1, 0, 0, {0} }, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } }; static void veriusertfs_register(void) { veriusertfs_register_table(veriusertfs); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/getp.v000066400000000000000000000001041435245347300166040ustar00rootroot00000000000000module test; initial begin $mytest(1,9.6,3); end endmodule iverilog-12_0/ivtest/vpi/hello_poke.c000066400000000000000000000043231435245347300177520ustar00rootroot00000000000000/* * Copyright (c) 2001 Picture Elements, Inc. * Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include # include #ifdef IVERILOG_V0_8 static PLI_INT32 my_hello_calltf(char *xx) #else static PLI_INT32 my_hello_calltf(PLI_BYTE8 *xx) #endif { s_vpi_value value; (void)xx; /* Parameter is not used. */ vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; if (argv == 0) { vpi_printf("ERROR: $hello_poke requires one argument\n"); vpi_sim_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); assert(arg != 0); value.format = vpiStringVal; value.value.str = "Hello"; vpi_put_value(arg, &value, 0, vpiNoDelay); arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: too many arguments to $hello_poke\n"); vpi_sim_control(vpiFinish, 1); } return 0; } static void my_hello_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$hello_poke"; tf_data.calltf = my_hello_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { my_hello_register, 0 }; iverilog-12_0/ivtest/vpi/hello_poke.v000066400000000000000000000005661435245347300200020ustar00rootroot00000000000000module main; reg [5*8-1 : 0] hello; initial begin hello = "XXXXX"; if (hello !== "XXXXX") begin $display("FAILED -- X = %h", hello); $finish; end $hello_poke(hello); if (hello !== "Hello") begin $display("FAILED -- Hello = %h", hello); $finish; end $display("PASSED"); end // initial begin endmodule // main iverilog-12_0/ivtest/vpi/hello_tf.c000066400000000000000000000031531435245347300174250ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include # include #ifdef IVERILOG_V0_8 static PLI_INT32 my_hello_calltf(char *xx) #else static PLI_INT32 my_hello_calltf(PLI_BYTE8 *xx) #endif { (void)xx; /* Parameter is not used. */ io_printf("Hello World, from VPI.\n"); return 0; } static void my_hello_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$my_hello"; tf_data.calltf = my_hello_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { my_hello_register, 0 }; iverilog-12_0/ivtest/vpi/hello_tf.v000066400000000000000000000032051435245347300174460ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Here we have the canonical "Hello, World" program written in Verilog, * with VPI. It uses the hello_vpi.vpi module that is compiled from * the hello_vpi.c program also in this directory. See the * hello_vpi.c for instructions on how to compile it. * * Compile this program with the command: * * iverilog -ohello_vpi hello_vpi.vl * * After churning for a little while, the program will create the output * file "hello" which is compiled, linked and ready to run. Run this * program like so: * * vvp -M. -mhello_vpi hello_vpi * * and the program will print the message to its output. Easy! For * more on how to make the iverilog command work, see the iverilog * manual page. */ module main(); initial begin $my_hello; $finish(0); end endmodule iverilog-12_0/ivtest/vpi/hello_vpi.c000066400000000000000000000036321435245347300176140ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This file contains an example VPI module to demonstrate the tools * to create vpi modules. To compile this module, use the iverilog-vpi * command like so: * * iverilog-vpi hello_vpi.c * * The result is the hello_vpi.vpi module. See the hello_vpi.vl * program for example Verilog code to call this module. */ # include #ifdef IVERILOG_V0_8 static PLI_INT32 my_hello_calltf(char *xx) #else static PLI_INT32 my_hello_calltf(PLI_BYTE8 *xx) #endif { (void)xx; /* Parameter is not used. */ vpi_printf("Hello World, from VPI.\n"); return 0; } static void my_hello_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$my_hello"; tf_data.calltf = my_hello_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { my_hello_register, 0 }; iverilog-12_0/ivtest/vpi/hello_vpi.v000066400000000000000000000032051435245347300176330ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Here we have the canonical "Hello, World" program written in Verilog, * with VPI. It uses the hello_vpi.vpi module that is compiled from * the hello_vpi.c program also in this directory. See the * hello_vpi.c for instructions on how to compile it. * * Compile this program with the command: * * iverilog -ohello_vpi hello_vpi.vl * * After churning for a little while, the program will create the output * file "hello" which is compiled, linked and ready to run. Run this * program like so: * * vvp -M. -mhello_vpi hello_vpi * * and the program will print the message to its output. Easy! For * more on how to make the iverilog command work, see the iverilog * manual page. */ module main(); initial begin $my_hello; $finish(0); end endmodule iverilog-12_0/ivtest/vpi/hello_vpi1.c000066400000000000000000000017771435245347300177050ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include PLI_INT32 my_hello_calltf(PLI_BYTE8 *xx) { (void)xx; /* Parameter is not used. */ vpi_printf("Hello World, from VPI.\n"); return 0; } iverilog-12_0/ivtest/vpi/hello_vpi2.c000066400000000000000000000026301435245347300176730ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include extern PLI_INT32 my_hello_calltf(PLI_BYTE8 *xx); static void my_hello_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$my_hello"; tf_data.calltf = my_hello_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } /* * This is a table of register functions. This table is the external * symbol that the simulator looks for when loading this .vpi module. */ void (*vlog_startup_routines[])(void) = { my_hello_register, 0 }; iverilog-12_0/ivtest/vpi/hello_vpi2.v000066400000000000000000000032051435245347300177150ustar00rootroot00000000000000/* * Copyright (c) 2002 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Here we have the canonical "Hello, World" program written in Verilog, * with VPI. It uses the hello_vpi.vpi module that is compiled from * the hello_vpi.c program also in this directory. See the * hello_vpi.c for instructions on how to compile it. * * Compile this program with the command: * * iverilog -ohello_vpi hello_vpi.vl * * After churning for a little while, the program will create the output * file "hello" which is compiled, linked and ready to run. Run this * program like so: * * vvp -M. -mhello_vpi hello_vpi * * and the program will print the message to its output. Easy! For * more on how to make the iverilog command work, see the iverilog * manual page. */ module main(); initial begin $my_hello; $finish(0); end endmodule iverilog-12_0/ivtest/vpi/listparams.c000066400000000000000000000037401435245347300200120ustar00rootroot00000000000000# include # include # include # include #ifdef IVERILOG_V0_8 static PLI_INT32 listparams_compiletf(char*name) #else static PLI_INT32 listparams_compiletf(PLI_BYTE8*name) #endif { (void)name; /* Parameter is not used. */ return 0; } static void param_by_name(vpiHandle scope, const char*key) { vpiHandle iter = vpi_iterate(vpiParameter, scope); vpiHandle item; while ( (item = vpi_scan(iter)) ) { s_vpi_value value; if (strcmp(key, vpi_get_str(vpiName,item)) != 0) continue; vpi_printf("%8s: ", vpi_get_str(vpiName, item)); switch (vpi_get(vpiConstType, item)) { case vpiStringConst: value.format = vpiStringVal; vpi_get_value(item, &value); vpi_printf("%s", value.value.str); break; case vpiBinaryConst: value.format = vpiBinStrVal; vpi_get_value(item, &value); vpi_printf("%s", value.value.str); break; default: break; } vpi_printf("\n"); } } #ifdef IVERILOG_V0_8 static PLI_INT32 listparams_calltf(char*name) #else static PLI_INT32 listparams_calltf(PLI_BYTE8*name) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall,0); vpiHandle scope= vpi_handle(vpiScope, sys); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item; (void)name; /* Parameter is not used. */ while ( (item = vpi_scan(argv)) ) { s_vpi_value value; value.format = vpiStringVal; vpi_get_value(item, &value); param_by_name(scope, value.value.str); } return 0; } static void listparams_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$listparams"; tf_data.calltf = listparams_calltf; tf_data.compiletf = listparams_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$listparams"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { listparams_register, 0 }; iverilog-12_0/ivtest/vpi/listparams.v000066400000000000000000000017171435245347300200370ustar00rootroot00000000000000// Copyright (c) 2006 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; parameter foo = 4'b0101; parameter str = "String Text"; initial begin $listparams("foo", "str"); end endmodule // main iverilog-12_0/ivtest/vpi/memmon.c000066400000000000000000000042621435245347300171230ustar00rootroot00000000000000# include # include #ifdef IVERILOG_V0_8 static PLI_INT32 memmonitor_compiletf(char*name) #else static PLI_INT32 memmonitor_compiletf(PLI_BYTE8*name) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall,0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; if (argv == 0) { vpi_printf("ERROR: %s expects at least 1 argument.\n", name); vpi_control(vpiFinish, 1); return 0; } while ( (arg = vpi_scan(argv)) ) { if (vpi_get(vpiType, arg) != vpiMemory) { vpi_printf("ERROR: %s expects only memory arguments\n", name); vpi_control(vpiFinish, 1); return 0; } } return 0; } static PLI_INT32 callback(struct t_cb_data*cb) { vpi_printf("ValueChange: index=%d, value=%s\n", (int)cb->index, cb->value->value.str); return 0; } static PLI_INT32 cleanup(struct t_cb_data*cb) { free(cb->value); return 0; } #ifdef IVERILOG_V0_8 static PLI_INT32 memmonitor_calltf(char*name) #else static PLI_INT32 memmonitor_calltf(PLI_BYTE8*name) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall,0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; (void)name; /* Parameter is not used. */ while ( (arg = vpi_scan(argv)) ) { s_cb_data cb_data; cb_data.reason = cbValueChange; cb_data.cb_rtn = callback; cb_data.obj = arg; cb_data.time = 0; cb_data.value = malloc(sizeof(struct t_vpi_value)); cb_data.index = 0; cb_data.user_data = 0; cb_data.value->format = vpiBinStrVal; cb_data.value->value.str = 0; vpi_register_cb(&cb_data); cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = cleanup; vpi_register_cb(&cb_data); } return 0; } static void memmonitor_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$memmonitor"; tf_data.calltf = memmonitor_calltf; tf_data.compiletf = memmonitor_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$memmonitor"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { memmonitor_register, 0 }; iverilog-12_0/ivtest/vpi/memmon.v000066400000000000000000000020041435245347300171360ustar00rootroot00000000000000// Copyright (c) 2006 Stephen Williams // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module main; reg [7:0] mem [0:1]; initial begin mem[0] = 0; mem[1] = 1; $memmonitor(mem); #1 mem[0] = 4; #1 mem[1] = 5; #1 $finish(0); end endmodule // main iverilog-12_0/ivtest/vpi/memwide.cc000066400000000000000000000114621435245347300174250ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies named events can be peeked and poked. */ #include #include #include #include "vpi_user.h" static s_vpi_time suppress_time = { vpiSuppressTime, 0, 0, 0 }; static vpiHandle findReg(const char *name_); static vpiHandle findMem(const char *name_); extern "C" PLI_INT32 CallbackPeek(s_cb_data * /*data*/) { vpiHandle handle; vpi_printf("!!!C++: callback\n"); // Find big_reg if((handle=findReg("big_reg"))) { unsigned size=vpi_get(vpiSize,handle); vpi_printf("!!!C++: %s size is %d\n",vpi_get_str(vpiName,handle),size); s_vpi_value value; value.format=vpiVectorVal; value.value.vector=NULL; vpi_get_value(handle,&value); for(unsigned i=0;(i*32) %s\n", tf_mipname()); io_printf("tf_imipname(inst)\t-> %s\n", tf_imipname(inst)); return 0; } static int sizetf(int ud, int reason) { (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ return 32; } s_tfcell veriusertfs[2] = { {usertask, 0, 0, sizetf, calltf, 0, "$mytest", 1, 0, 0, {0} }, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } }; static void veriusertfs_register(void) { veriusertfs_register_table(veriusertfs); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/mipname.v000066400000000000000000000002611435245347300172770ustar00rootroot00000000000000module test3; initial #1 $mytest; endmodule module test2; initial #2 $mytest; test3 t3(); endmodule module test; initial #3 $mytest; test2 t2(); endmodule iverilog-12_0/ivtest/vpi/myscope.c000066400000000000000000000013021435245347300173020ustar00rootroot00000000000000 /* */ # include # include static int sn_calltf(char*user_data) { vpiHandle scope = vpi_handle(vpiScope, 0); (void)user_data; /* Parameter is not used. */ assert(scope); vpi_printf("My scope name: %s (s.b. xor_try)\n", vpi_get_str(vpiFullName, scope)); return 0; } static void vpi_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.calltf = sn_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.tfname = "$sn"; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { vpi_register, 0 }; iverilog-12_0/ivtest/vpi/myscope.v000066400000000000000000000010311435245347300173240ustar00rootroot00000000000000//--------------------------------------------------------------------------- // //--------------------------------------------------------------------------- module xor_try; reg [1:0] inp_xor; // The two-bit inputs to the XOR reg out_xor; // The XOR output reg clk; initial begin clk = 1'b1; #10 $sn; #160 $finish(0); end always #50 clk = ~clk; // The clock always @(posedge clk) out_xor = #1 (inp_xor[0] ^ inp_xor[1]); // The actual operation endmodule iverilog-12_0/ivtest/vpi/myscope2.c000066400000000000000000000023321435245347300173700ustar00rootroot00000000000000 /* */ # include # include static char * instance = 0; static int sn_calltf(int user_data, int reason) { int high_time, low_time; (void)user_data; /* Parameter is not used. */ io_printf("... sn_calltf(reason=%d)\n", reason); low_time = tf_igetlongtime(&high_time,instance); io_printf("high_time=%d, low_time=%d\n", high_time, low_time); return 0; } int ise_vls_misc(int data, int reason, int paramvc) { (void)paramvc; /* Parameter is not used. */ io_printf("... ise_vls_misc(reason=%d)\n", reason); if (reason != reason_endofcompile) return sn_calltf(data, reason); else return 0; } int ise_startup(int data, int reason) { (void)data; /* Parameter is not used. */ instance = tf_getinstance(); io_printf("... ise_startup(reason=%d)\n", reason); tf_isynchronize(instance); return 1; } static s_tfcell sn[2] = { {usertask, 0, ise_startup, 0, sn_calltf, ise_vls_misc, "$sn", 1, 0, 0, {0} }, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } }; static void veriusertfs_register(void) { veriusertfs_register_table(sn); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/myscope2.v000066400000000000000000000010311435245347300174060ustar00rootroot00000000000000//--------------------------------------------------------------------------- // //--------------------------------------------------------------------------- module xor_try; reg [1:0] inp_xor; // The two-bit inputs to the XOR reg out_xor; // The XOR output reg clk; initial begin clk = 1'b1; #10 $sn; #160 $finish(0); end always #50 clk = ~clk; // The clock always @(posedge clk) out_xor = #1 (inp_xor[0] ^ inp_xor[1]); // The actual operation endmodule iverilog-12_0/ivtest/vpi/nulls1.c000066400000000000000000000042661435245347300170550ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include "vpi_user.h" #include PLI_INT32 ValueChange(p_cb_data cb_data) { static s_vpi_time get_time = { vpiSimTime, 0, 0, 0 }; (void)cb_data; /* Parameter is not used. */ vpi_get_time(NULL,&get_time); vpi_printf("%6d: Value Change\n", (int)get_time.low); return(0); } #ifdef IVERILOG_V0_8 PLI_INT32 CompileTF(char *user_data) #else PLI_INT32 CompileTF(PLI_BYTE8 *user_data) #endif { s_cb_data cb_data; vpiHandle call_h=vpi_handle(vpiSysTfCall,NULL); vpiHandle arg_i,arg_h; (void)user_data; /* Parameter is not used. */ // Get First Argument and Setup Value Change Callback arg_i=vpi_iterate(vpiArgument,call_h); arg_h=vpi_scan(arg_i); vpi_free_object(arg_i); cb_data.reason = cbValueChange; cb_data.cb_rtn = ValueChange; cb_data.value = NULL; cb_data.time = NULL; cb_data.user_data = NULL; cb_data.obj = arg_h; vpi_register_cb(&cb_data); return(0); } static void my_Register(void) { s_vpi_systf_data tf_data; vpi_printf("Registering Callbacks\n"); // Register the $Verbench call tf_data.type = vpiSysTask; tf_data.user_data = 0; tf_data.sizetf = NULL; tf_data.tfname = "$vpi_call"; tf_data.calltf = NULL; tf_data.compiletf = CompileTF; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { my_Register, 0}; iverilog-12_0/ivtest/vpi/nulls1.v000066400000000000000000000020471435245347300170730ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // Michael Runyan (mrunyan at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg foo; initial begin #0 foo=0; forever #10 foo=~foo; end initial begin #101 $finish(0); end initial #1 $vpi_call(foo); endmodule iverilog-12_0/ivtest/vpi/pokereg.cc000066400000000000000000000116071435245347300174330ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include "vpi_user.h" static struct str_s { int format; const char *str; } words[4] = { {vpiBinStrVal, "x001x001"}, {vpiOctStrVal, "0x2"}, {vpiDecStrVal, "3"}, {vpiHexStrVal, "x4"} }; #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 RegPeek(char *) #else extern "C" PLI_INT32 RegPeek(PLI_BYTE8 *) #endif { vpiHandle mod_h, iterate, handle; vpiHandle reg_h[5]; s_vpi_value value; int index; vpi_printf("RegPeek Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get register iterate = vpi_iterate(vpiReg, mod_h); if (iterate == NULL) return -1; for (index = 0; index < 5; index++) reg_h[index] = NULL; while ((handle = vpi_scan(iterate))) { if (!strcmp("r_peek_1", vpi_get_str(vpiName, handle))) { reg_h[0] = handle; } else if (!strcmp("r_peek_2", vpi_get_str(vpiName, handle))) { reg_h[1] = handle; } else if (!strcmp("r_peek_3", vpi_get_str(vpiName, handle))) { reg_h[2] = handle; } else if (!strcmp("r_peek_4", vpi_get_str(vpiName, handle))) { reg_h[3] = handle; } else if (!strcmp("r_peek_5", vpi_get_str(vpiName, handle))) { reg_h[4] = handle; } } // Get value for (index = 0; index < 5; index++) { // Print out info value.format=vpiBinStrVal; vpi_get_value(reg_h[index], &value); vpi_printf("%3d: 'b_%s,", index, value.value.str); value.format=vpiOctStrVal; vpi_get_value(reg_h[index], &value); vpi_printf(" 'o_%s,", value.value.str); value.format=vpiDecStrVal; vpi_get_value(reg_h[index], &value); vpi_printf(" 'd_%s,", value.value.str); value.format=vpiHexStrVal; vpi_get_value(reg_h[index], &value); vpi_printf(" 'h_%s\n", value.value.str); } return 0; } #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 RegPoke(char *) #else extern "C" PLI_INT32 RegPoke(PLI_BYTE8 *) #endif { vpiHandle mod_h, iterate, handle; vpiHandle reg_h[5]; s_vpi_value value; int index; vpi_printf("RegPoke Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get register iterate = vpi_iterate(vpiReg, mod_h); if (iterate == NULL) return -1; for (index = 0; index < 5; index++) reg_h[index] = NULL; while ((handle = vpi_scan(iterate))) { if (!strcmp("r_poke_1", vpi_get_str(vpiName, handle))) { reg_h[0] = handle; } else if (!strcmp("r_poke_2", vpi_get_str(vpiName, handle))) { reg_h[1] = handle; } else if (!strcmp("r_poke_3", vpi_get_str(vpiName, handle))) { reg_h[2] = handle; } else if (!strcmp("r_poke_4", vpi_get_str(vpiName, handle))) { reg_h[3] = handle; } else if (!strcmp("r_poke_5", vpi_get_str(vpiName, handle))) { reg_h[4] = handle; } } // Poke register using integer and strings for (index = 0; index < 5; index++) { if (index < 4) { value.format=words[index].format; value.value.str=strdup(words[index].str); vpi_printf("%3d: %s\n", index, value.value.str); } else { value.format=vpiIntVal; value.value.integer = 69; vpi_printf("%3d: %d\n", index, (int)value.value.integer); } vpi_put_value(reg_h[index], &value, NULL, vpiNoDelay); if (index < 4) free(value.value.str); } return 0; } extern "C" void RegisterCallbacks(void) { s_vpi_systf_data tf_data; vpi_printf("Registering Callbacks\n"); tf_data.type = vpiSysTask; tf_data.tfname = "$regpoke"; tf_data.calltf = RegPoke; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.tfname = "$regpeek"; tf_data.calltf = RegPeek; vpi_register_systf(&tf_data); } #ifdef __SUNPRO_CC extern "C" #endif void (*vlog_startup_routines[])() = { RegisterCallbacks, 0 }; iverilog-12_0/ivtest/vpi/pokereg.v000066400000000000000000000035761435245347300173210ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // Michael Runyan (mrunyan at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg [7:0] r_poke_1, r_poke_2, r_poke_3, r_poke_4, r_poke_5; reg [7:0] r_peek_1, r_peek_2, r_peek_3, r_peek_4, r_peek_5; task f_copy; begin // twizzle copy r_peek_1 = r_poke_2; r_peek_2 = r_poke_3; r_peek_3 = r_poke_4; r_peek_4 = r_poke_5; r_peek_5 = r_poke_1; end endtask task f_dump; integer i; begin $display("Verilog compare r_poke <=> r_peek"); $display (" 'b_%b <=> 'b_%b%s", r_poke_1, r_peek_5, r_poke_1 !== r_peek_5 ? " - ERROR" : ""); $display (" 'b_%b <=> 'b_%b%s", r_poke_2, r_peek_1, r_poke_2 !== r_peek_1 ? " - ERROR" : ""); $display (" 'b_%b <=> 'b_%b%s", r_poke_3, r_peek_2, r_poke_3 !== r_peek_2 ? " - ERROR" : ""); $display (" 'b_%b <=> 'b_%b%s", r_poke_4, r_peek_3, r_poke_4 !== r_peek_3 ? " - ERROR" : ""); $display (" 'b_%b <=> 'b_%b%s", r_poke_5, r_peek_4, r_poke_5 !== r_peek_4 ? " - ERROR" : ""); end endtask initial begin #0; $regpoke; #10; f_copy; #10; $regpeek; #10; f_dump; end endmodule iverilog-12_0/ivtest/vpi/pokevent.cc000066400000000000000000000064531435245347300176350ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies named events can be peeked and poked. */ #include #include #include #include "vpi_user.h" extern "C" PLI_INT32 CallbackPeek(s_cb_data *data) { static s_vpi_time zero_delay = { vpiNoDelay, 0, 0, 0 }; vpi_printf(" callback\n"); // Toggle poke event vpiHandle poke_e = *(vpiHandle *)data->user_data; vpi_put_value(poke_e, NULL, &zero_delay, vpiInertialDelay); return 0; } static vpiHandle FindPoke(const char *name) { vpiHandle module, iterate, handle; // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return NULL; module = vpi_scan(iterate); vpi_free_object(iterate); // find named event handle = NULL; iterate = vpi_iterate(vpiNamedEvent, module); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp(name, vpi_get_str(vpiName, handle))) { vpi_free_object(iterate); break; } } } return handle; } static void RegisterPeek(const char *name, vpiHandle poke) { vpiHandle module, iterate, handle; s_cb_data vc_cb_data; static vpiHandle user_data = poke; // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return; module = vpi_scan(iterate); vpi_free_object(iterate); // find named event handle = NULL; iterate = vpi_iterate(vpiNamedEvent, module); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp(name, vpi_get_str(vpiName, handle))) { vpi_free_object(iterate); break; } } } // Register callback vc_cb_data.time = NULL; vc_cb_data.value = NULL; vc_cb_data.user_data = (char *)&user_data; vc_cb_data.obj = handle; vc_cb_data.reason = cbValueChange; vc_cb_data.cb_rtn = CallbackPeek; vpi_register_cb(&vc_cb_data); } extern "C" PLI_INT32 EndofCompile(s_cb_data * /*cb_data*/) { RegisterPeek("e_Peek", FindPoke("e_Poke")); return 0; } extern "C" void my_Register(void) { s_cb_data cb_data; vpi_printf("!!!C++: Registering Callbacks\n"); cb_data.time = NULL; cb_data.value = NULL; cb_data.user_data = (char *) NULL; cb_data.obj = NULL; cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = EndofCompile; vpi_register_cb(&cb_data); } #ifdef __SUNPRO_CC extern "C" #endif void (*vlog_startup_routines[]) () = { my_Register, 0 }; iverilog-12_0/ivtest/vpi/pokevent.v000066400000000000000000000004231435245347300175040ustar00rootroot00000000000000module test; event e_Peek; event e_Poke; initial begin // $dumpvars; #0; ->e_Poke; #51 $finish(0); end always @(e_Poke) begin $display("e_Poke received @ %0t", $time); #10; $display("e_Peek asserted @ %0t", $time); ->e_Peek; end endmodule iverilog-12_0/ivtest/vpi/ports_params.c000066400000000000000000000072341435245347300203470ustar00rootroot00000000000000/* * Copyright (c) 2012 Andrew Stevens wackston@googlemail.com * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include "vpi_user.h" static void checkParams(void) { vpiHandle mod_i = vpi_iterate(vpiModule, NULL) ; assert( mod_i != NULL ); vpiHandle module = vpi_scan(mod_i); assert( module != NULL ); vpi_free_object(mod_i); vpiHandle param_i = vpi_iterate(vpiParameter, module) ; assert( param_i != NULL ); vpiHandle parameter; while ( (parameter=vpi_scan(param_i))!=NULL) { char *name =vpi_get_str(vpiName, parameter) ; int type = vpi_get(vpiConstType, parameter) ; printf( "PARAM NAME=%s type=%d ", name, type ); s_vpi_value val ; switch(type) { case vpiDecConst: case vpiBinaryConst: case vpiOctConst: case vpiHexConst: val.format = vpiIntVal ; vpi_get_value(parameter, &val) ; printf( "value=(INT)%d ", val.value.integer ); break ; case vpiRealConst: val.format = vpiRealVal ; vpi_get_value(parameter, &val) ; printf( "value=(REAL)%g ", val.value.real ); break ; case vpiStringConst: val.format = vpiStringVal ; vpi_get_value(parameter, &val) ; printf( "value=(STR)\"%s\" ", val.value.str ); break; default: printf( "value= " ); break ; } int local =vpi_get(vpiLocalParam, parameter)!=0 ; printf( "local=%s\n", local ? "yes" : "no" ); } } static void checkPorts(void) { vpiHandle mod_i = vpi_iterate(vpiModule, NULL) ; assert( mod_i != 0 ); vpiHandle module = vpi_scan(mod_i); assert( module != 0 ); vpi_free_object(mod_i) ; vpiHandle port_i = vpi_iterate(vpiPort, module) ; vpiHandle port ; while ( (port=vpi_scan(port_i))!=NULL) { char *portName = vpi_get_str(vpiName, port) ; int portIndex = vpi_get(vpiPortIndex, port) ; PLI_INT32 dir = vpi_get(vpiDirection, port) ; PLI_INT32 size = vpi_get(vpiSize, port) ; printf( "PORT name=%s index=%d dir=%d size=%d\n", portName, portIndex, dir, size ); } } static PLI_INT32 checkPortsParams(struct t_cb_data*cb) { (void)cb; /* Parameter is not used. */ checkParams(); checkPorts(); return 0; } static void setCallback(void) { s_cb_data cb ; /* setup a callback for start of simulation */ cb.reason = cbStartOfSimulation ; cb.cb_rtn = checkPortsParams; cb.user_data = "checkPortsParams" ; cb.obj = NULL ; cb.time = NULL ; cb.value = NULL ; vpi_register_cb(&cb) ; } void (*vlog_startup_routines[]) (void) = { setCallback, 0}; iverilog-12_0/ivtest/vpi/ports_params.v000066400000000000000000000030511435245347300203630ustar00rootroot00000000000000`timescale 1ns/1ns `define DAC_MSB 7 `define ADC_MSB 15 `define NSEC 1 `define USEC (`NSEC*1000) `define MSEC (`USEC*1000) // TOPLEVEL TO STIMULATE module toy_toplevel( input wire [`ADC_MSB:0] V_load_adc, input wire V_load_valid, output reg pwm, output reg [`DAC_MSB:0] V_src ) ; parameter time STARTUP_DELAY = 2 * `MSEC; parameter real ADC_RANGE = 32.0; parameter real ADC_OFFSET = -ADC_RANGE/2.0; parameter real DAC_RANGE = 16.0; parameter real DAC_OFFSET = -DAC_RANGE/2.0; parameter real UPDATE_FREQ_MHZ = 1.0; parameter time CLOCK_INTERVAL = `USEC / UPDATE_FREQ_MHZ; reg clk = 0; reg ls_only = 0; real V_load = 0.0; function real decode_value( input real base, input real range, input integer msb, input integer value ); begin decode_value = base + range * value / $itor(1<< (msb+1)); end endfunction function integer encode_value( input real base, input real range, input integer msb, input real value ); begin encode_value = (value -base) * $itor(1<< (msb+1)) / range; end endfunction always @( posedge(V_load_valid) ) begin V_load = decode_value( ADC_OFFSET, ADC_RANGE, `ADC_MSB, V_load_adc ); end initial begin clk = 0; ls_only = 0; #( `USEC * 1 ); # ( CLOCK_INTERVAL/4 ); $finish(0); // Stop things for VPI unit test... forever begin # ( CLOCK_INTERVAL/2 ); clk <= ! clk; end end always @clk begin ls_only= (V_load >2.5); pwm <= clk | ls_only; end initial begin V_src = encode_value( DAC_OFFSET, DAC_RANGE, `DAC_MSB, 7.2 ); end endmodule iverilog-12_0/ivtest/vpi/pr1693971.c000066400000000000000000000157651435245347300170520ustar00rootroot00000000000000/********************************************************************** * $my_pow example -- PLI application using VPI routines * * C source to calculate the result of a number to the power of an * exponent. The result is returned as a 32-bit integer. * * Usage: result = $my_pow(,); * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ #define VPI_1995 0 /* set to non-zero for Verilog-1995 compatibility */ #include /* ANSI C standard library */ #include /* ANSI C standard input/output library */ #include /* ANSI C standard arguments library */ #include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */ #if VPI_1995 #include "../vpi_1995_compat.h" /* kludge new Verilog-2001 routines */ #endif /* prototypes of PLI application routine names */ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowSizetf(char *user_data); static PLI_INT32 PLIbook_PowCalltf(char *user_data); static PLI_INT32 PLIbook_PowCompiletf(char *user_data); #else static PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data); static PLI_INT32 PLIbook_PowCalltf(PLI_BYTE8 *user_data); static PLI_INT32 PLIbook_PowCompiletf(PLI_BYTE8 *user_data); #endif static PLI_INT32 PLIbook_PowStartOfSim(s_cb_data *callback_data); /********************************************************************** * $my_pow Registration Data * (add this function name to the vlog_startup_routines array) *********************************************************************/ void PLIbook_pow_register(void) { s_vpi_systf_data tf_data; s_cb_data cb_data_s; vpiHandle callback_handle; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncSized; tf_data.tfname = "$my_pow"; tf_data.calltf = PLIbook_PowCalltf; tf_data.compiletf = PLIbook_PowCompiletf; tf_data.sizetf = PLIbook_PowSizetf; tf_data.user_data = NULL; vpi_register_systf(&tf_data); cb_data_s.reason = cbStartOfSimulation; cb_data_s.cb_rtn = PLIbook_PowStartOfSim; cb_data_s.obj = NULL; cb_data_s.time = NULL; cb_data_s.value = NULL; cb_data_s.user_data = NULL; callback_handle = vpi_register_cb(&cb_data_s); vpi_free_object(callback_handle); /* don't need callback handle */ } /********************************************************************** * Sizetf application *********************************************************************/ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowSizetf(char *user_data) #else static PLI_INT32 PLIbook_PowSizetf(PLI_BYTE8 *user_data) #endif { (void)user_data; /* Parameter is not used. */ //vpi_printf("\n$my_pow PLI sizetf function.\n\n"); return(32); /* $my_pow returns 32-bit values */ } /********************************************************************** * compiletf application to verify valid systf args. *********************************************************************/ #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowCompiletf(char *user_data) #else static PLI_INT32 PLIbook_PowCompiletf(PLI_BYTE8 *user_data) #endif { vpiHandle systf_handle, arg_itr, arg_handle; PLI_INT32 tfarg_type; int err_flag = 0; (void)user_data; /* Parameter is not used. */ vpi_printf("\n$my_pow PLI compiletf function.\n\n"); do { /* group all tests, so can break out of group on error */ systf_handle = vpi_handle(vpiSysTfCall, NULL); arg_itr = vpi_iterate(vpiArgument, systf_handle); if (arg_itr == NULL) { vpi_printf("ERROR: $my_pow requires 2 arguments; has none\n"); err_flag = 1; break; } arg_handle = vpi_scan(arg_itr); tfarg_type = vpi_get(vpiType, arg_handle); if ( (tfarg_type != vpiReg) && (tfarg_type != vpiIntegerVar) && (tfarg_type != vpiConstant) ) { vpi_printf("ERROR: $my_pow arg1 must be number, variable or net\n"); err_flag = 1; break; } arg_handle = vpi_scan(arg_itr); if (arg_handle == NULL) { vpi_printf("ERROR: $my_pow requires 2nd argument\n"); err_flag = 1; break; } tfarg_type = vpi_get(vpiType, arg_handle); if ( (tfarg_type != vpiReg) && (tfarg_type != vpiIntegerVar) && (tfarg_type != vpiConstant) ) { vpi_printf("ERROR: $my_pow arg2 must be number, variable or net\n"); err_flag = 1; break; } if (vpi_scan(arg_itr) != NULL) { vpi_printf("ERROR: $my_pow requires 2 arguments; has too many\n"); vpi_free_object(arg_itr); err_flag = 1; break; } } while (0 == 1); /* end of test group; only executed once */ if (err_flag) { vpi_control(vpiFinish, 1); /* abort simulation */ } return(0); } /********************************************************************** * calltf to calculate base to power of exponent and return result. *********************************************************************/ #include #ifdef IVERILOG_V0_8 static PLI_INT32 PLIbook_PowCalltf(char *user_data) #else static PLI_INT32 PLIbook_PowCalltf(PLI_BYTE8 *user_data) #endif { s_vpi_value value_s; vpiHandle systf_handle, arg_itr, arg_handle; PLI_INT32 base, expo; double result; (void)user_data; /* Parameter is not used. */ //vpi_printf("\n$my_pow PLI calltf function.\n\n"); systf_handle = vpi_handle(vpiSysTfCall, NULL); arg_itr = vpi_iterate(vpiArgument, systf_handle); if (arg_itr == NULL) { vpi_printf("ERROR: $my_pow failed to obtain systf arg handles\n"); return(0); } /* read base from systf arg 1 (compiletf has already verified) */ arg_handle = vpi_scan(arg_itr); value_s.format = vpiIntVal; vpi_get_value(arg_handle, &value_s); base = value_s.value.integer; /* read exponent from systf arg 2 (compiletf has already verified) */ arg_handle = vpi_scan(arg_itr); vpi_free_object(arg_itr); /* not calling scan until returns null */ vpi_get_value(arg_handle, &value_s); expo = value_s.value.integer; /* calculate result of base to power of exponent */ result = pow( (double)base, (double)expo ); /* write result to simulation as return value $my_pow */ value_s.value.integer = (PLI_INT32)result; vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay); return(0); } /********************************************************************** * Start-of-simulation application *********************************************************************/ static PLI_INT32 PLIbook_PowStartOfSim(s_cb_data *callback_data) { (void)callback_data; /* Parameter is not used. */ vpi_printf("\n$my_pow StartOfSim callback.\n\n"); return(0); } /*********************************************************************/ void (*vlog_startup_routines[])(void) = { /*** add user entries here ***/ PLIbook_pow_register, //PLIbook_test_user_data_register, 0 /*** final entry must be 0 ***/ }; iverilog-12_0/ivtest/vpi/pr1693971.v000066400000000000000000000025461435245347300170660ustar00rootroot00000000000000/********************************************************************** * $my_pow example -- Verilog HDL test bench. * * Verilog test bench to test the $my_pow PLI application. * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ `timescale 1ns / 1ns module test; reg [32:0] result; reg a, b; buf i1 (c,a); initial begin $display("Start simulation pow_test.v"); a = 1; b = 0; /* Test $my_pow with invalid arguments */ /* These invalid calls will need to be commented out to use */ /* the valid calls to $my_pow in simulation */ // #1 result = $my_pow; // #1 result = $my_pow(); // #1 result = $my_pow(1); // #1 result = $my_pow(2,i1); // #1 result = $my_pow(1,2,3); /* Test $my_pow with valid values */ #1 $display("$my_pow(2,3) returns %d", $my_pow(2,3)); #1 result = $my_pow(a,b); #1 $display("$my_pow(a,b) returns %d (a=%d b=%d)", result, a, b); // #1 $stop; #1 $finish(0); end endmodule /*********************************************************************/ iverilog-12_0/ivtest/vpi/pr2048463.c000066400000000000000000000146271435245347300170350ustar00rootroot00000000000000/********************************************************************** * $my_monitor example -- PLI application using VPI routines * * C source to place value change callbacks on all nets in a module * instance, and print the simulation time and new value whenever * any net changes value. * * Usage: $my_monitor(); * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ #include /* ANSI C standard library */ #include /* ANSI C standard input/output library */ #include /* ANSI C standard arguments library */ #include #include /* IEEE 1364 PLI VPI routine library */ /* prototypes of routines in this PLI application */ PLI_INT32 PLIbook_MyMonitor_calltf(PLI_BYTE8 *user_data); PLI_INT32 PLIbook_MyMonitor_compiletf(PLI_BYTE8 *user_data); PLI_INT32 PLIbook_MyMonitor_callback(p_cb_data cb_data_p); /* To make this memory clean we need to keep a list of the allocated * names so we can free them at EOS. */ static char** name_list = 0; static unsigned name_count = 0; static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) { unsigned idx; (void)cb_data; /* Parameter is not used. */ for (idx = 0; idx < name_count; idx += 1) { free(name_list[idx]); } free(name_list); name_list = 0; name_count = 0; return 0; } /********************************************************************** * VPI Registration Data *********************************************************************/ void PLIbook_MyMonitor_register(void) { s_vpi_systf_data tf_data; s_cb_data cb_data; tf_data.type = vpiSysTask; tf_data.sysfunctype = 0; tf_data.tfname = "$my_monitor"; tf_data.calltf = PLIbook_MyMonitor_calltf; tf_data.compiletf = PLIbook_MyMonitor_compiletf; tf_data.sizetf = NULL; tf_data.user_data = NULL; vpi_register_systf(&tf_data); cb_data.reason = cbEndOfSimulation; cb_data.time = 0; cb_data.cb_rtn = sys_end_of_simulation; cb_data.user_data = "system"; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[])(void) = { PLIbook_MyMonitor_register, 0 }; /* dummy +loadvpi= boostrap routine - mimics old style exec all routines */ /* in standard PLI vlog_startup_routines table */ void vpi_compat_bootstrap(void) { int i; for (i = 0;; i++) { if (vlog_startup_routines[i] == NULL) break; vlog_startup_routines[i](); } } /********************************************************************** * compiletf application *********************************************************************/ PLI_INT32 PLIbook_MyMonitor_compiletf(PLI_BYTE8 *user_data) { vpiHandle systf_handle, arg_iterator, arg_handle; PLI_INT32 tfarg_type; (void)user_data; /* Parameter is not used. */ /* obtain a handle to the system task instance */ systf_handle = vpi_handle(vpiSysTfCall, NULL); /* obtain handles to system task arguments */ arg_iterator = vpi_iterate(vpiArgument, systf_handle); if (arg_iterator == NULL) { vpi_printf("ERROR: $my_monitor requires 1 argument\n"); vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } /* check the type of object in system task arguments */ arg_handle = vpi_scan(arg_iterator); tfarg_type = vpi_get(vpiType, arg_handle); if (tfarg_type != vpiModule) { vpi_printf("ERROR: $my_monitor arg1 must be module instance\n"); vpi_free_object(arg_iterator); /* free iterator memory */ vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } /* check that there is only 1 system task argument */ arg_handle = vpi_scan(arg_iterator); if (arg_handle != NULL) { vpi_printf("ERROR: $my_monitor can only have 1 argument\n"); vpi_free_object(arg_iterator); /* free iterator memory */ vpi_control(vpiFinish, 1); /* abort simulation */ return(0); } return(0); /* no syntax errors detected */ } /********************************************************************** * calltf routine *********************************************************************/ PLI_INT32 PLIbook_MyMonitor_calltf(PLI_BYTE8 *user_data) { vpiHandle systf_h, arg_itr, mod_h, net_itr, net_h, cb_h; s_vpi_time time_s; s_vpi_value value_s; s_cb_data cb_data_s; PLI_BYTE8 *net_name_temp, *net_name_keep; (void)user_data; /* Parameter is not used. */ /* setup value change callback options */ time_s.type = vpiScaledRealTime; value_s.format = vpiBinStrVal; cb_data_s.reason = cbValueChange; cb_data_s.cb_rtn = PLIbook_MyMonitor_callback; cb_data_s.time = &time_s; cb_data_s.value = &value_s; /* obtain a handle to the system task instance */ systf_h = vpi_handle(vpiSysTfCall, NULL); /* obtain handle to system task argument */ /* compiletf has already verified only 1 arg with correct type */ arg_itr = vpi_iterate(vpiArgument, systf_h); mod_h = vpi_scan(arg_itr); vpi_free_object(arg_itr); /* free iterator--did not scan to null */ /* add value change callback for each net in module named in tfarg */ vpi_printf("\nAdding monitors to all nets in module %s:\n\n", vpi_get_str(vpiDefName, mod_h)); net_itr = vpi_iterate(vpiNet, mod_h); while ((net_h = vpi_scan(net_itr)) != NULL) { net_name_temp = vpi_get_str(vpiFullName, net_h); net_name_keep = malloc(strlen((char *)net_name_temp)+1); strcpy((char *)net_name_keep, (char *)net_name_temp); cb_data_s.obj = net_h; cb_data_s.user_data = net_name_keep; name_count += 1; name_list = (char **)realloc(name_list, name_count*sizeof(char **)); name_list[name_count-1] = net_name_keep; cb_h = vpi_register_cb(&cb_data_s); vpi_free_object(cb_h); /* don't need callback handle */ } return(0); } /********************************************************************** * Value change callback application *********************************************************************/ PLI_INT32 PLIbook_MyMonitor_callback(p_cb_data cb_data_p) { vpi_printf("At time %0.2f", cb_data_p->time->real); vpi_printf(":\t %s", cb_data_p->user_data); vpi_printf(" = %s\n", cb_data_p->value->value.str); return(0); } /*********************************************************************/ iverilog-12_0/ivtest/vpi/pr2048463.v000066400000000000000000000026521435245347300170530ustar00rootroot00000000000000/********************************************************************** * $my_monitor example -- Verilog HDL test bench. * * Verilog test bench to test the $my_monitor PLI application. * * For the book, "The Verilog PLI Handbook" by Stuart Sutherland * Copyright 1999 & 2001, Kluwer Academic Publishers, Norwell, MA, USA * Contact: www.wkap.il * Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA * Contact: www.sutherland-hdl.com *********************************************************************/ `timescale 1ns / 1ns module test; reg a, b, ci, clk; wire sum, co; addbit i1 (a, b, ci, sum, co); initial $my_monitor(i1); initial begin #0 a = 0; #0 b = 0; #0 ci = 0; #10 a = 1; #10 a = 0; #10 b = 1; #10 a = 1; #10 $finish(0); end endmodule /*** A gate level 1 bit adder model ***/ `timescale 1ns / 1ns module addbit (a, b, ci, sum, co); input a, b, ci; output sum, co; wire a, b, ci, sum, co, n1, n2, n3; /* assign n1 = a ^ b; assign sum = n1 ^ ci; assign n2 = a & b; assign n3 = n1 & ci; assign co = n2 | n3; */ // Gate delays are used to ensure the signal changes occur in a // defined order. xor #1 (n1, a, b); and #2 (n2, a, b); and #3 (n3, n1, ci); xor #4 (sum, n1, ci); or #4 (co, n2, n3); endmodule /*********************************************************************/ iverilog-12_0/ivtest/vpi/pr2314742.c000066400000000000000000000070311435245347300170200ustar00rootroot00000000000000#include #include #include #include /* * This file exercises an error */ static int chkvpierr(void) { s_vpi_error_info info; int level; if ((level = vpi_chk_error(&info)) != 0) { fprintf(stderr, "+++ VPI ERROR +++ level %d\n", level); fprintf(stderr, "+++ MESS: %s\n", info.message); fprintf(stderr, "+++ PROD: %s\n", info.product); fprintf(stderr, "+++ CODE: %s\n", info.code); fprintf(stderr, "+++ FILE: %s\n", info.file); fprintf(stderr, "+++\n"); } return level; } #ifdef IVERILOG_V0_8 static PLI_INT32 xxx_compiletf(char *user_data) #else static PLI_INT32 xxx_compiletf(PLI_BYTE8 *user_data) #endif { (void)user_data; /* Parameter is not used. */ return 0; } char charbuf[100]; #ifdef IVERILOG_V0_8 static PLI_INT32 xxx_calltf(char *user_data) #else static PLI_INT32 xxx_calltf(PLI_BYTE8 *user_data) #endif { vpiHandle systf_h; s_vpi_value vpival; /* get/set register values */ s_vpi_time t; vpiHandle arg_iterator; int i; vpiHandle argi[100]; (void)user_data; /* Parameter is not used. */ /* Get handle to this instance, look up our workarea */ systf_h = vpi_handle(vpiSysTfCall, NULL); chkvpierr(); arg_iterator = vpi_iterate(vpiArgument, systf_h); chkvpierr(); i = 0; if (arg_iterator == NULL) { fprintf(stderr, "ERROR: missing argument list to $example(...)"); } /* Copy args pointers into argi array */ while ((argi[i] = vpi_scan(arg_iterator)) != NULL) { chkvpierr(); i++; } /* iterator is exhausted, no need to free */ /* Fill in the time struct */ t.type = vpiScaledRealTime; t.high = 0; t.low = 0; t.real = 10.0; /* Fill in the value struct */ vpival.format = vpiBinStrVal; vpival.value.str = charbuf; /* * This is where the real work happens. We are called in an intial * block and we schedule three "set-values" at times 10, 20 and 30 * to args 0, 1 and 2. The charbuf gets shared among the three * calls, even though it shouldn't and the values are not distinct. */ /* Write this value to argi[0] at time 10.0 */ strcpy(charbuf, "01010101"); vpi_put_value(argi[0], &vpival, &t, vpiTransportDelay); /* Write this value to argi[1] at time 20.0 */ strcpy(charbuf, "x1x1x1x1"); t.real = 20.0; vpi_put_value(argi[1], &vpival, &t, vpiTransportDelay); /* Write this value to argi[2] at time 30.0 */ strcpy(charbuf, "0xz101xz"); t.real = 30.0; vpi_put_value(argi[2], &vpival, &t, vpiTransportDelay); return 0; } static void xxx_register(void) { s_vpi_systf_data tfdata; vpi_printf("+++ in XXX_REGISTER\n"); tfdata.type = vpiSysFunc; /* * TOM: sysfunctype field seems to be problematic for different simulators! * some simulators simply don't register callback if subtype missing. * * Icarus - doesn't implement vpiSizedFunc, so use vpiIntFunct. * CVER - use vpiIntFunc * MTI - use vpiSizedFunc or vpiIntFunc. * XL/NC - doesn't matter * VCS - doesn't matter * */ tfdata.sysfunctype = vpiIntFunc; /* tfdata.sysfunctype = vpiSizedFunc; */ tfdata.tfname = "$example"; tfdata.calltf = xxx_calltf; tfdata.compiletf = xxx_compiletf; /* tfdata.sizetf = xxx_sizetf; */ tfdata.sizetf = 0; tfdata.user_data = 0; vpi_register_systf(&tfdata); chkvpierr(); } static void xxx_startup(void) { vpi_printf("*** Registering XXX PLI functions.\n"); xxx_register(); } /** * * **/ void (*vlog_startup_routines[])(void) = { xxx_startup, 0 }; iverilog-12_0/ivtest/vpi/pr2314742.v000066400000000000000000000007411435245347300170440ustar00rootroot00000000000000module top; reg [7:0] a; reg [7:0] b; reg [7:0] c; integer retcode; initial begin #0; // avoid T0 race a = 0; b = 0; c = 0; /* Use VPI to set values on these registers */ retcode = $example(a, b, c); end always @(a) $display("%t The value of A is: %b", $time, a); always @(b) $display("%t The value of B is: %b", $time, b); always @(c) $display("%t The value of C is: %b", $time, c); endmodule // top iverilog-12_0/ivtest/vpi/pr2966059.c000066400000000000000000000025231435245347300170370ustar00rootroot00000000000000#include "vpi_user.h" #ifdef IVERILOG_V0_8 static PLI_INT32 number_compiletf(char *x) #else static PLI_INT32 number_compiletf(PLI_BYTE8 *x) #endif { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; char *name; s_vpi_value var; (void)x; /* Parameter is not used. */ if (argv == 0) { vpi_printf("ERROR: missing required numeric argument.\n"), vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); /* Check to see what vpi_get_value does during compiletf. */ name = vpi_get_str(vpiName, arg); vpi_printf("vpi_get_value (%s):\n", name ? name : ""); var.format = vpiObjTypeVal; vpi_get_value(arg, &var); vpi_printf(" format = %d\n", (int) var.format); var.format = vpiDecStrVal; vpi_get_value(arg, &var); vpi_printf(" value = %s\n", var.value.str); vpi_free_object(argv); return 0; } static void local_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$check_number"; tf_data.calltf = 0; tf_data.compiletf = number_compiletf; tf_data.sizetf = 0; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { local_register, 0}; iverilog-12_0/ivtest/vpi/pr2966059.v000066400000000000000000000011221435245347300170540ustar00rootroot00000000000000module top; parameter ip = 1; parameter rp = 2.0; parameter sp = "\003"; real rlval; wire real wreal; reg [3:0] rval; wire [3:0] wval; assign wval = 2; initial begin rval = 4'b1001; rlval = 2.0; $check_number(1); $check_number(ip); $check_number(2.0); $check_number(rp); $check_number("\003"); $check_number(sp); $check_number(rlval); $check_number(rlval+1); $check_number(wreal); $check_number(wreal+1); $check_number(rval); $check_number(rval+1); $check_number(wval); $check_number(wval+1); end endmodule iverilog-12_0/ivtest/vpi/pr2971220.c000066400000000000000000000163641435245347300170310ustar00rootroot00000000000000#include "string.h" #include "vpi_user.h" /* * Not all systems support passing a system task/function call handle * to vpi_get_systf_info(). All should support vpiUserSystf. You can * only get the vpiUserSystf handle when vpiUserDefn is 1 (true). */ /* * Set the following when compiling if the call handle is not supported: * SYSTF_INFO_CALLH_NOT_SUPPORTED */ static vpiHandle registered_task_as; static vpiHandle registered_func_as; /* These tasks/functions do not take any arguments. */ static PLI_INT32 sys_compiletf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); if (argv) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s does not take any arguments.\n", name); vpi_free_object(argv); vpi_control(vpiFinish, 1); } return 0; } /* Helper function to print the function type as a string value. */ static const char *func_type(PLI_INT32 type) { char *res = 0; switch (type) { case vpiIntFunc: res = "vpiIntFunc"; break; case vpiRealFunc: res = "vpiRealFunc"; break; case vpiTimeFunc: res = "vpiTimeFunc"; break; case vpiSizedFunc: res = "vpiSizedFunc"; break; case vpiSizedSignedFunc: res = "vpiSizedSignedFunc"; break; default: res = ""; break; } return res; } /* The calltf routine for the task check. */ static PLI_INT32 sys_check_sys_task_calltf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); PLI_INT32 res; s_vpi_systf_data tf_data; vpiHandle iter; /* Check the stashed handle. */ vpi_get_systf_info(registered_task_as, &tf_data); vpi_printf("registered as: %s - %s\n", vpi_get_str(vpiType, registered_task_as), tf_data.tfname); /* Check to see if vpiUserDefn is set correctly. */ res = vpi_get(vpiUserDefn, callh); vpi_printf(" vpiUserDefn: is "); if (res != 1) { vpi_printf("undefined (%d)!\n", (int)res); } else { vpi_printf("defined.\n"); /* Check vpi_get_systf_info (just check the name). */ vpi_get_systf_info(vpi_handle(vpiUserSystf, callh), &tf_data); vpi_printf(" vpi_get_systf_info: "); if (strcmp(tf_data.tfname, name)) { vpi_printf("failed.\n"); } else { vpi_printf("passed.\n"); } #ifdef SYSTF_INFO_CALLH_NOT_SUPPORTED vpi_printf(" vpi_get_systf_info (callh): not supported.\n"); #else /* This is not supported by all simulators. */ vpi_get_systf_info(callh, &tf_data); vpi_printf(" vpi_get_systf_info (callh): "); if (strcmp(tf_data.tfname, name)) { vpi_printf("failed.\n"); } else { vpi_printf("passed.\n"); } #endif } /* Look for all the user defined system tasks/functions. */ vpi_printf("Looking for all user defined system tasks/functions:\n"); iter = vpi_iterate(vpiUserSystf, 0); if (iter) { vpiHandle val; while ((val = vpi_scan(iter))) { vpi_get_systf_info(val, &tf_data); vpi_printf(" Found "); if (tf_data.type == vpiSysTask) vpi_printf("task"); else vpi_printf("function (%s)", func_type(tf_data.sysfunctype)); vpi_printf(" %s - %s", vpi_get_str(vpiType, val), tf_data.tfname); if (vpi_compare_objects(val, registered_task_as)) { vpi_printf(" *****> caller"); } vpi_printf(".\n"); } vpi_printf("Done.\n"); } else { vpi_printf(" No user defined system tasks/functions found!\n"); } return 0; } /* The calltf routine for the function check. */ static PLI_INT32 sys_check_sys_func_calltf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); PLI_INT32 res; s_vpi_systf_data tf_data; /* Check the stashed handle. */ vpi_get_systf_info(registered_func_as, &tf_data); vpi_printf("registered as: %s - %s\n", vpi_get_str(vpiType, registered_func_as), tf_data.tfname); /* Check to see if vpiUserDefn is set correctly. */ res = vpi_get(vpiUserDefn, callh); vpi_printf(" vpiUserDefn: "); if (res != 1) { vpi_printf("is undefined (%d)!\n", (int)res); } else { vpi_printf("is defined.\n"); /* Check vpi_get_systf_info (just check the name). */ vpi_get_systf_info(vpi_handle(vpiUserSystf, callh), &tf_data); vpi_printf(" vpi_get_systf_info: "); if (strcmp(tf_data.tfname, name)) { vpi_printf("failed.\n"); } else { vpi_printf("passed.\n"); } #ifdef SYSTF_INFO_CALLH_NOT_SUPPORTED vpi_printf(" vpi_get_systf_info (callh): not supported.\n"); #else /* This is not supported by all simulators. */ vpi_get_systf_info(callh, &tf_data); vpi_printf(" vpi_get_systf_info (callh): "); if (strcmp(tf_data.tfname, name)) { vpi_printf("failed.\n"); } else { vpi_printf("passed.\n"); } #endif } /* We would normally put a value for a function, but since we're * not testing that with this code we'll just use the default * value (0). */ return 0; } /* A simple task to add a few more definitions to the vpiUserSystf list. */ static PLI_INT32 sys_hello_calltf(PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpi_printf("Hello from %s at %s:%d.\n", name, vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); return 0; } static void register_check_systf(void) { vpiHandle res; s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.calltf = sys_check_sys_task_calltf; tf_data.compiletf = sys_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$check_sys_task"; tf_data.user_data = "$check_sys_task";; registered_task_as = vpi_register_systf(&tf_data); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.calltf = sys_check_sys_func_calltf; tf_data.compiletf = sys_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$check_sys_func"; tf_data.user_data = "$check_sys_func";; registered_func_as = vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.calltf = sys_hello_calltf; tf_data.compiletf = sys_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$hello"; tf_data.user_data = "$hello";; res = vpi_register_systf(&tf_data); /* Icarus does not need this, but it should not be an error either. */ vpi_free_object(res); // Does this work on all simulators? I would expect vpi_printf() to be OK, // but vpi_get_systf_info() could be suspect. vpi_get_systf_info(registered_task_as, &tf_data); vpi_printf("--> registered task as: %s.\n", tf_data.tfname); vpi_get_systf_info(registered_func_as, &tf_data); vpi_printf("--> registered func as: %s.\n", tf_data.tfname); } void (*vlog_startup_routines[])(void) = { register_check_systf, 0 }; /* This is needed by other simulators. */ void vpi_bootstrap(void) { int i; for (i = 0; vlog_startup_routines[i]; i += 1) { vlog_startup_routines[i](); } } iverilog-12_0/ivtest/vpi/pr2971220.v000066400000000000000000000002031435245347300170350ustar00rootroot00000000000000module top; integer res; initial begin $hello; $check_sys_task; res = $check_sys_func; $hello; end endmodule iverilog-12_0/ivtest/vpi/pr521.c000066400000000000000000000015321435245347300165010ustar00rootroot00000000000000#include #include char *veriuser_version_str = "Test PLI v0.1 "; static int pli_test(int ud, int reason) { int a; (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ a = tf_getp(1); printf ("PLI Parameter received 0x%x\n",a); return 0; } static int return_32(int ud, int reason) { (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ return (32); } s_tfcell veriusertfs[] = { {userfunction, 0, 0, return_32, pli_test, 0, "$pli_test", 1, 0, 0, {0} }, /* all entry must be entered before this line */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } /* this must be the last entry */ }; static void veriusertfs_register(void) { veriusertfs_register_table(veriusertfs); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/pr521.v000066400000000000000000000005401435245347300165220ustar00rootroot00000000000000module pli_test; wire [15:0] a = 16'h4321; wire [ 7:0] b = a[15:8]; integer rc; initial begin #1 /* Allow the continuous assignments above to settle. */ ; $display("Passing parameter to PLI routine: 0x%x",a[15:8]); rc = $pli_test(a[15:8]); $display("Passing parameter to PLI routine: 0x%x",b); rc = $pli_test(b); end endmodule iverilog-12_0/ivtest/vpi/pr686.c000066400000000000000000000047541435245347300165260ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include "vpi_user.h" # include static PLI_INT32 next_sim_time_callback(struct t_cb_data*cb) { vpiHandle obj = (vpiHandle)cb->user_data; s_vpi_value val; s_vpi_time tim; val.format = vpiIntVal; vpi_get_value(obj, &val); tim.type = vpiSimTime; vpi_get_time(obj, &tim); vpi_printf("Callback time=%d %s=%d\n", (int)tim.low, vpi_get_str(vpiName, obj), (int)val.value.integer); return 0; } #ifdef IVERILOG_V0_8 static PLI_INT32 test_next_compiletf(char *name) #else static PLI_INT32 test_next_compiletf(PLI_BYTE8 *name) #endif { (void)name; /* Parameter is not used. */ return 0; } #ifdef IVERILOG_V0_8 static PLI_INT32 test_next_calltf(char *name) #else static PLI_INT32 test_next_calltf(PLI_BYTE8 *name) #endif { vpiHandle sys, argv, value; (void)name; /* Parameter is not used. */ sys = vpi_handle(vpiSysTfCall, 0); assert(sys); argv = vpi_iterate(vpiArgument, sys); assert(argv); for (value = vpi_scan(argv) ; value ; value = vpi_scan(argv)) { s_cb_data cb; cb.reason = cbNextSimTime; cb.cb_rtn = next_sim_time_callback; cb.user_data = (char*)value; vpi_register_cb(&cb); } return 0; } static void register_functions(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test_next_sim_time"; tf_data.calltf = test_next_calltf; tf_data.compiletf = test_next_compiletf; tf_data.sizetf = 0; tf_data.user_data = ""; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { register_functions, 0 }; iverilog-12_0/ivtest/vpi/pr686.v000066400000000000000000000022701435245347300165400ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ module main; reg [3:0] foo; initial begin foo = 0; foo <= 1; // This will display 1 at time=1 $test_next_sim_time(foo); $strobe("foo should be 0: %d", foo); #1 foo <= #4 2; $strobe("foo should be 1: %d", foo); $test_next_sim_time(foo); #5 $display("foo is finally %d", foo); end endmodule // main iverilog-12_0/ivtest/vpi/pr723.c000066400000000000000000000014671435245347300165140ustar00rootroot00000000000000#include #include "vpi_user.h" #ifdef IVERILOG_V0_8 static PLI_INT32 calltf(char *data) #else static PLI_INT32 calltf(PLI_BYTE8 *data) #endif { int i; (void)data; /* Parameter is not used. */ for (i = 0; i < 31; i++) { if (vpi_mcd_name(1U< #include "vpi_user.h" static PLI_INT32 EndOfCompile(s_cb_data *data) { vpiHandle hand; s_vpi_time timerec = { vpiSimTime, 0, 0, 0 }; s_vpi_value val; int i; (void)data; /* Parameter is not used. */ hand = vpi_handle_by_name("test.r", 0); assert(hand); // Get current state val.format = vpiIntVal; vpi_get_value(hand, &val); // Add a few transitions for (i = 0; i < 6; i++) { if (i < 3) { // delay 10+i time units timerec.low = 1000 * (i + 1); } else { timerec.type = vpiScaledRealTime; timerec.low = 0; timerec.real = 10000.0 * (i+1); } // Toggle state val.value.integer ^= 1; // Put new state vpi_put_value(hand, &val, &timerec, vpiPureTransportDelay); } return 0; } static void VPIRegister(void) { s_cb_data cb_data; s_vpi_time timerec = { vpiSuppressTime, 0, 0, 0 }; cb_data.time = &timerec; cb_data.value = 0; cb_data.user_data = 0; cb_data.obj = 0; cb_data.reason = cbEndOfCompile; cb_data.cb_rtn = EndOfCompile; vpi_register_cb(&cb_data); } void (*vlog_startup_routines[]) (void) = { VPIRegister, 0}; iverilog-12_0/ivtest/vpi/putvalue.v000066400000000000000000000004311435245347300175150ustar00rootroot00000000000000/* * This test verifies vpiPureTransportDelay functionality */ `timescale 1 ns / 1 ps module test; reg r; initial begin $monitor(" r = ", r); #0.1 r = 1'b0; #100000 $finish(0); end always @(r) $display(" r = %b @ %0t", r, $time); endmodule iverilog-12_0/ivtest/vpi/range1.c000066400000000000000000000025521435245347300170100ustar00rootroot00000000000000 /* */ # include # include static int sn_calltf(char*user_data) { s_vpi_value value; int left_value; int right_value; (void)user_data; /* Parameter is not used. */ /* Get the handle of an object that we know to be present. */ vpiHandle xor_hand = vpi_handle_by_name("xor_try.inp_xor",0); /* The object is a vector, get the expressions for the left and right range values. */ vpiHandle left_hand = vpi_handle(vpiLeftRange, xor_hand); vpiHandle right_hand = vpi_handle(vpiRightRange, xor_hand); assert(left_hand); assert(right_hand); /* Extract the values from the expressions. */ value.format = vpiIntVal; vpi_get_value(left_hand, &value); left_value = value.value.integer; value.format = vpiIntVal; vpi_get_value(right_hand, &value); right_value = value.value.integer; vpi_printf("Dimensions of xor_try.inp_xor: [%d:%d]\n", left_value, right_value); return 0; } static void vpi_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.calltf = sn_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; tf_data.tfname = "$sn"; tf_data.user_data = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { vpi_register, 0 }; iverilog-12_0/ivtest/vpi/range1.v000066400000000000000000000010251435245347300170250ustar00rootroot00000000000000//--------------------------------------------------------------------------- // //--------------------------------------------------------------------------- module xor_try; reg [1:0] inp_xor; // The two-bit inputs to the XOR reg out_xor; // The XOR output reg clk; initial begin clk = 1'b1; $sn; #160 $finish(0); end always #50 clk = ~clk; // The clock always @(posedge clk) out_xor = #1 (inp_xor[0] ^ inp_xor[1]); // The actual operation endmodule iverilog-12_0/ivtest/vpi/realcb.c000066400000000000000000000046171435245347300170670ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program tests change callbacks on real variables. */ # include # include static PLI_INT32 watchreal_cb(p_cb_data cb) { s_vpi_value value; vpiHandle arg = (vpiHandle) (cb->user_data); value.format = vpiRealVal; vpi_get_value(arg, &value); assert(value.format == vpiRealVal); vpi_printf("watchreal: %s = %f\n", vpi_get_str(vpiName, arg), value.value.real); return 0; } #ifdef IVERILOG_V0_8 static PLI_INT32 my_watchreal_calltf(char *xx) #else static PLI_INT32 my_watchreal_calltf(PLI_BYTE8 *xx) #endif { struct t_cb_data cb; struct t_vpi_time timerec; (void)xx; /* Parameter is not used. */ vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; timerec.type = vpiSimTime; timerec.low = 0; timerec.high = 0; while (0 != (arg = vpi_scan(argv))) { assert(vpi_get(vpiType, arg) == vpiRealVar); cb.reason = cbValueChange; cb.cb_rtn = watchreal_cb; cb.time = &timerec; cb.obj = arg; cb.value = 0; cb.user_data = (char*)arg; vpi_register_cb(&cb); } return 0; } static void my_watchreal_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$my_watchreal"; tf_data.calltf = my_watchreal_calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { my_watchreal_register, 0 }; iverilog-12_0/ivtest/vpi/realcb.v000066400000000000000000000020731435245347300171040ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * $Id: realcb.v,v 1.1 2003/02/10 05:14:13 stevewilliams Exp $ */ module main; real x, y; initial begin $my_watchreal(x, y); #1 x = 1.0; #1 y = 2.0; #1 x = 1.5; #1 y = 5.1; end endmodule // main iverilog-12_0/ivtest/vpi/realtime.c000066400000000000000000000034671435245347300174430ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies vpiScaledRealTime */ #include #include "vpi_user.h" s_vpi_time get_time = { vpiScaledRealTime, 0, 0, 0 }; #ifdef IVERILOG_V0_8 static PLI_INT32 calltf(char *data) #else static PLI_INT32 calltf(PLI_BYTE8 *data) #endif { vpiHandle hand, iter; (void)data; /* Parameter is not used. */ hand = vpi_handle(vpiSysTfCall, 0); iter = vpi_iterate(vpiArgument, hand); hand = vpi_scan(iter); vpi_free_object(iter); vpi_printf("calltf from %s", vpi_get_str(vpiName, hand)); vpi_get_time(0, &get_time); vpi_printf(" %f,", get_time.real); vpi_get_time(hand, &get_time); vpi_printf(" %f\n", get_time.real); return 0; } static void VPIRegister(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test"; tf_data.calltf = calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { VPIRegister, 0}; iverilog-12_0/ivtest/vpi/realtime.v000066400000000000000000000006241435245347300174560ustar00rootroot00000000000000`timescale 1 ms / 1 ps module test; initial begin #12345.6789; $display("time = %0f", $realtime); $test(test); #2345.67891; $display("time = %0f", $realtime); $test(test); end endmodule `timescale 1 ps / 1 ps module test2; initial begin #12345.6789; $display("time = %0f", $realtime); $test(test2); #2345.67891; $display("time = %0f", $realtime); $test(test2); end endmodule iverilog-12_0/ivtest/vpi/realtime2.c000066400000000000000000000034671435245347300175250ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This test verifies vpiScaledRealTime */ #include #include "vpi_user.h" s_vpi_time get_time = { vpiScaledRealTime, 0, 0, 0 }; #ifdef IVERILOG_V0_8 static PLI_INT32 calltf(char *data) #else static PLI_INT32 calltf(PLI_BYTE8 *data) #endif { vpiHandle hand, iter; (void)data; /* Parameter is not used. */ hand = vpi_handle(vpiSysTfCall, 0); iter = vpi_iterate(vpiArgument, hand); hand = vpi_scan(iter); vpi_free_object(iter); vpi_printf("calltf from %s", vpi_get_str(vpiName, hand)); vpi_get_time(0, &get_time); vpi_printf(" %f,", get_time.real); vpi_get_time(hand, &get_time); vpi_printf(" %f\n", get_time.real); return 0; } static void VPIRegister(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test"; tf_data.calltf = calltf; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { VPIRegister, 0}; iverilog-12_0/ivtest/vpi/realtime2.v000066400000000000000000000005741435245347300175440ustar00rootroot00000000000000`timescale 1 ns / 1 ps module test; initial begin #12.3456; $display("$time = %0t", $time); $test(test); #34.5678; $display("$time = %0t", $time); $test(test); end endmodule `timescale 1 ps / 1 ps module test2; initial begin #56.7890; $display("$time = %0t", $time); $test(test2); #78.9012; $display("$time = %0t", $time); $test(test2); end endmodule iverilog-12_0/ivtest/vpi/ro_synch.c000066400000000000000000000046061435245347300174610ustar00rootroot00000000000000# include # include # include struct poke_details { vpiHandle dst; int val; int dly; }; static PLI_INT32 delayed_poke(p_cb_data cb_data) { s_vpi_value value; s_vpi_time time; struct poke_details*poke = (struct poke_details*)cb_data->user_data; value.format = vpiIntVal; value.value.integer = poke->val; if (poke->dly < 0) { vpi_put_value(poke->dst, &value, 0, vpiNoDelay); } else { time.type = vpiSimTime; time.high = 0; time.low = poke->dly; time.real = 0.0; vpi_put_value(poke->dst, &value, &time, vpiTransportDelay); } fflush(stderr); // for Windows free(poke); return 0; } static PLI_INT32 poke_compiletf(char*xx) { (void)xx; /* Parameter is not used. */ return 0; } static PLI_INT32 poke_calltf(char*xx) { s_vpi_value value; s_vpi_time poke_time; s_cb_data cb_data; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle dst, val, dly, tmp; struct poke_details*poke; (void)xx; /* Parameter is not used. */ assert(argv); dst = vpi_scan(argv); assert(dst); val = vpi_scan(argv); assert(val); dly = vpi_scan(argv); assert(dly); tmp = vpi_scan(argv); assert(tmp == 0); poke = calloc(1, sizeof (struct poke_details)); assert(poke); poke->dst = dst; value.format = vpiIntVal; vpi_get_value(val, &value); poke->val = value.value.integer; value.format = vpiIntVal; vpi_get_value(dly, &value); poke->dly = value.value.integer; poke_time.low = 0; poke_time.high = 0; poke_time.type = vpiSimTime; cb_data.reason = cbReadOnlySynch; cb_data.cb_rtn = delayed_poke; cb_data.user_data = (char*)poke; cb_data.time = &poke_time; vpi_register_cb(&cb_data); return 0; } static void poke_after_delay_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$delayed_poke"; tf_data.calltf = poke_calltf; tf_data.compiletf = poke_compiletf; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { poke_after_delay_register, 0 }; iverilog-12_0/ivtest/vpi/ro_synch.v000066400000000000000000000007111435245347300174750ustar00rootroot00000000000000module main; integer val; initial begin val = 0; $delayed_poke(val, 1, -1); $delayed_poke(val, 2, 0); $delayed_poke(val, 3, 1); #1 if (val !== 0) begin $display("FAILED -- val==%0d before legal poke", val); $finish; end #1 if (val !== 3) begin $display("FAILED -- val==%0d: legal poke didn't happen", val); $finish; end $display("PASSED"); $finish(0); end endmodule // main iverilog-12_0/ivtest/vpi/scanmem.cc000066400000000000000000000104721435245347300174210ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include "vpi_user.h" #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPeek(char *) #else extern "C" PLI_INT32 MemPeek(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; s_vpi_value value; vpi_printf("MemPeek Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_peek", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Invert read memory iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { // Get current value value.format=vpiIntVal; vpi_get_value(handle, &value); // Store inverted value.value.integer ^= 0xffffffff; if (vpi_get(vpiSize, handle) < 32) { value.value.integer &= ~((1 << vpi_get(vpiSize, handle)) - 1); } vpi_put_value(handle, &value, NULL, vpiNoDelay); } return 0; } #define REP4(x) \ (((x) & 0xff) << 24 | ((x) & 0xff) << 16 | ((x) & 0xff) << 8 | ((x) & 0xff)) #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPoke(char *) #else extern "C" PLI_INT32 MemPoke(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; s_vpi_value value; vpi_printf("MemPoke Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_poke", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Poke memory using integers iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { value.format = vpiIntVal; vpi_get_value(vpi_handle(vpiIndex, handle), &value); value.value.integer = REP4(1 + value.value.integer); if (vpi_get(vpiSize, handle) < 32) { value.value.integer &= ~((1 << vpi_get(vpiSize, handle)) - 1); } vpi_put_value(handle, &value, NULL, vpiNoDelay); } return 0; } extern "C" void RegisterCallbacks(void) { s_vpi_systf_data tf_data; vpi_printf("Registering Callbacks\n"); tf_data.type = vpiSysTask; tf_data.tfname = "$mempoke"; tf_data.calltf = MemPoke; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.tfname = "$mempeek"; tf_data.calltf = MemPeek; vpi_register_systf(&tf_data); } #ifdef __SUNPRO_CC extern "C" #endif void (*vlog_startup_routines[]) () = { RegisterCallbacks, 0 }; iverilog-12_0/ivtest/vpi/scanmem.v000066400000000000000000000030771435245347300173040ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // Michael Runyan (mrunyan at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg [5:0] addr; reg [31:0] m_poke[4:0]; reg [31:0] m_peek[4:0]; task f_init; integer i; begin for (i = 0; i < 5; i = i + 1) begin m_poke[i] = $random; end end endtask task f_copy; integer i; begin for (i = 0; i < 5; i = i + 1) begin m_peek[i] = m_poke[i]; end end endtask task f_dump; integer i; begin for (i = 0; i < 5; i = i + 1) begin $display ("m_poke[%0d] <=> m_peek[%0d] 0x%x 0x%x%s", i, i, m_poke[i], m_peek[i], m_poke[i] !== ~m_peek[i] ? " - ERROR" : ""); end end endtask initial begin // f_init; #0; $mempoke; #10; f_copy; #10; $mempeek; #10; f_dump; end endmodule iverilog-12_0/ivtest/vpi/scanmem2.cc000066400000000000000000000115541435245347300175050ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include "vpi_user.h" // A 76 bit value const char *str[4] = { "f00cafababedeabbeef", "70850123451113459662575", "17001453725653733652737357", "1111000000001100101011111010101110101011111011011110101010111011111011101111" }; #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPeek(char *) #else extern "C" PLI_INT32 MemPeek(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; s_vpi_value value; int cnt = 0; const char *orig; vpi_printf("MemPeek Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_peek", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Get value orig = ""; iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { switch (cnt % 4) { case 0: value.format=vpiBinStrVal; orig = str[3]; break; case 1: value.format=vpiOctStrVal; orig = str[2]; break; case 2: value.format=vpiDecStrVal; orig = str[1]; break; case 3: value.format=vpiHexStrVal; orig = str[0]; break; } // Get current value vpi_get_value(handle, &value); vpi_printf("%0d: %s%s\n", cnt, value.value.str, strcmp(orig, value.value.str) ? " ERROR" : ""); cnt++; } return 0; } #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPoke(char *) #else extern "C" PLI_INT32 MemPoke(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; s_vpi_value value; int cnt = 0; vpi_printf("MemPoke Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_poke", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Poke memory using strings iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { switch (cnt % 4) { case 0: value.format=vpiHexStrVal; value.value.str = strdup(str[0]); break; case 1: value.format=vpiDecStrVal; value.value.str = strdup(str[1]); break; case 2: value.format=vpiOctStrVal; value.value.str = strdup(str[2]); break; case 3: value.format=vpiBinStrVal; value.value.str = strdup(str[3]); break; } vpi_printf("%0d: %s\n", cnt, value.value.str); vpi_put_value(handle, &value, NULL, vpiNoDelay); free(value.value.str); cnt++; } return 0; } extern "C" void RegisterCallbacks(void) { s_vpi_systf_data tf_data; vpi_printf("Registering Callbacks\n"); tf_data.type = vpiSysTask; tf_data.tfname = "$mempoke"; tf_data.calltf = MemPoke; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.tfname = "$mempeek"; tf_data.calltf = MemPeek; vpi_register_systf(&tf_data); } #ifdef __SUNPRO_CC extern "C" #endif void (*vlog_startup_routines[])() = { RegisterCallbacks, 0 }; iverilog-12_0/ivtest/vpi/scanmem2.v000066400000000000000000000032031435245347300173550ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // Michael Runyan (mrunyan at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg [5:0] addr; reg [75:0] m_poke[4:0]; reg [75:0] m_peek[4:0]; task f_copy_for_buggy_eda_vendor; integer i; reg [75:0] tmp; begin for (i = 0; i < 5; i = i + 1) begin tmp = m_poke[i]; m_peek[i] = tmp; end end endtask task f_copy; integer i; begin for (i = 0; i < 5; i = i + 1) begin m_peek[i] = m_poke[i]; end end endtask task f_dump; integer i; begin for (i = 0; i < 5; i = i + 1) begin $display ("%0d: m_poke <=> m_peek, 0x%x <=> 0x%x%s", i, m_poke[i], m_peek[i], m_poke[i] !== m_peek[i] ? " - ERROR" : ""); end end endtask initial begin #0; $mempoke; #10; f_copy; //f_copy_buggy_eda_vendor; #10; $mempeek; #10; f_dump; end endmodule iverilog-12_0/ivtest/vpi/scanmem3.cc000066400000000000000000000121731435245347300175040ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include "vpi_user.h" static struct str_s { int format; const char *str; } words[8] = { {vpiBinStrVal, "x001x001"}, {vpiOctStrVal, "0x2"}, {vpiDecStrVal, "3"}, {vpiHexStrVal, "x4"}, {vpiBinStrVal, "x101x101"}, {vpiOctStrVal, "0x6"}, {vpiDecStrVal, "7"}, {vpiHexStrVal, "x8"} }; #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPeek(char *) #else extern "C" PLI_INT32 MemPeek(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; vpiHandle word_h[8]; s_vpi_value value; int index; vpi_printf("MemPeek Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_peek", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Get value iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { // Get word index value.format=vpiIntVal; vpi_get_value(vpi_handle(vpiIndex, handle), &value); index = value.value.integer; // squirrel away handles word_h[index] = handle; } for (index = 0; index < 8; index++) { // Print out info value.format=vpiBinStrVal; vpi_get_value(word_h[index], &value); vpi_printf("%3d: 'b_%s,", index, value.value.str); value.format=vpiOctStrVal; vpi_get_value(word_h[index], &value); vpi_printf(" 'o_%s,", value.value.str); value.format=vpiDecStrVal; vpi_get_value(word_h[index], &value); vpi_printf(" 'd_%s,", value.value.str); value.format=vpiHexStrVal; vpi_get_value(word_h[index], &value); vpi_printf(" 'h_%s\n", value.value.str); } return 0; } #ifdef IVERILOG_V0_8 extern "C" PLI_INT32 MemPoke(char *) #else extern "C" PLI_INT32 MemPoke(PLI_BYTE8 *) #endif { vpiHandle mod_h, mem_h, iterate, handle; vpiHandle word_h[8]; s_vpi_value value; int index; vpi_printf("MemPoke Callback\n"); // get top module handle iterate = vpi_iterate(vpiModule, NULL); if (iterate == NULL) return -1; mod_h = vpi_scan(iterate); vpi_free_object(iterate); // Get memory mem_h = NULL; iterate = vpi_iterate(vpiMemory, mod_h); if (iterate != NULL) { while ((handle = vpi_scan(iterate))) { if (!strcmp("m_poke", vpi_get_str(vpiName, handle))) { vpiHandle memw_iter = vpi_iterate(vpiMemoryWord, handle); vpi_printf(" Found %s (%d deep x %d bits)\n", vpi_get_str(vpiName, handle), (int)vpi_get(vpiSize, handle), (int)vpi_get(vpiSize, vpi_scan(memw_iter))); vpi_free_object(memw_iter); mem_h = handle; vpi_free_object(iterate); break; } } } // Poke memory using strings iterate = vpi_iterate(vpiMemoryWord, mem_h); while ((handle = vpi_scan(iterate))) { // Get word index value.format=vpiIntVal; vpi_get_value(vpi_handle(vpiIndex, handle), &value); index = value.value.integer; // squirrel away handles word_h[index] = handle; } for (index = 0; index < 8; index++) { value.format=words[index].format; value.value.str=strdup(words[index].str); vpi_printf("%3d: %s\n", index, value.value.str); vpi_put_value(word_h[index], &value, NULL, vpiNoDelay); free(value.value.str); } return 0; } extern "C" void RegisterCallbacks(void) { s_vpi_systf_data tf_data; vpi_printf("Registering Callbacks\n"); tf_data.type = vpiSysTask; tf_data.tfname = "$mempoke"; tf_data.calltf = MemPoke; tf_data.compiletf = 0; tf_data.sizetf = 0; vpi_register_systf(&tf_data); tf_data.tfname = "$mempeek"; tf_data.calltf = MemPeek; vpi_register_systf(&tf_data); } #ifdef __SUNPRO_CC extern "C" #endif void (*vlog_startup_routines[])() = { RegisterCallbacks, 0 }; iverilog-12_0/ivtest/vpi/scanmem3.v000066400000000000000000000027001435245347300173570ustar00rootroot00000000000000// Copyright (c) 2002 Michael Ruff (mruff at chiaro.com) // Michael Runyan (mrunyan at chiaro.com) // // This source code is free software; you can redistribute it // and/or modify it in source code form under the terms of the GNU // General Public License as published by the Free Software // Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA // module test; reg [2:0] addr; reg [7:0] m_poke[7:0]; reg [7:0] m_peek[7:0]; task f_copy; integer i; begin for (i = 0; i < 8; i = i + 1) begin m_peek[i] = m_poke[i]; end end endtask task f_dump; integer i; begin $display("Verilog compare m_poke <=> m_peek"); for (i = 0; i < 8; i = i + 1) begin $display (" %0d: 'b_%b <=> 'b_%b%s", i, m_poke[i], m_peek[i], m_poke[i] !== m_peek[i] ? " - ERROR" : ""); end end endtask initial begin #0; $mempoke; #10; f_copy; #10; $mempeek; #10; f_dump; end endmodule iverilog-12_0/ivtest/vpi/scopes.c000066400000000000000000000025311435245347300171240ustar00rootroot00000000000000#include #include #include "vpi_user.h" static void spaces(int num) { while (num > 0) { vpi_printf(" "); num--; } } static void RecurseScope(vpiHandle handle, int depth) { vpiHandle iter, hand; iter = !handle ? vpi_iterate(vpiModule, NULL) : vpi_iterate(vpiInternalScope, handle); while (iter && (hand = vpi_scan(iter))) { spaces(depth); vpi_printf("%s is type ", vpi_get_str(vpiName, hand)); switch (vpi_get(vpiType,hand)) { case vpiModule: vpi_printf("vpiModule\n"); break; case vpiTask: vpi_printf("vpiTask\n"); break; case vpiFunction: vpi_printf("vpiFunction\n"); break; case vpiNamedBegin: vpi_printf("vpiNamedBegin\n"); break; case vpiNamedFork: vpi_printf("vpiNamedFork\n"); break; default: vpi_printf("unknown (%d)\n", (int)vpi_get(vpiType,hand)); break; } RecurseScope(hand, depth + 2); } } #ifdef IVERILOG_V0_8 static PLI_INT32 CompileTF(char *x) #else static PLI_INT32 CompileTF(PLI_BYTE8 *x) #endif { (void)x; /* Parameter is not used. */ RecurseScope(NULL, 0); return 0; } static void my_Register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$test"; tf_data.calltf = 0; tf_data.compiletf = CompileTF; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[]) (void) = { my_Register, 0}; iverilog-12_0/ivtest/vpi/scopes.v000066400000000000000000000015471435245347300171550ustar00rootroot00000000000000module lvl3; reg [1:0] m[1:0]; initial begin fork: my_fork repeat (1) begin m[0] = 2'b0; end repeat (1) begin m[1] = 2'b1; end join end endmodule module lvl2_0; reg r; initial r = $random; lvl3 lvl3(); endmodule module lvl1_0; reg r; function f_foo; input bar; begin f_foo = bar; end endfunction initial r = f_foo(r); lvl2_0 lvl2(); endmodule module top0; reg r; task t_bar; r = 1'b0; endtask initial begin: my_init r = $random; t_bar; end lvl1_0 lvl1(); endmodule module lvl2_1; integer i; initial i = $random; lvl3 lvl3(); endmodule module lvl1_1; integer i; initial i = $random; lvl2_1 lvl2(); endmodule module top1; integer i; initial i = $random; lvl1_1 lvl1(); endmodule module top2; initial $test; endmodule iverilog-12_0/ivtest/vpi/spec_delays.c000066400000000000000000000123501435245347300201230ustar00rootroot00000000000000# include # include # include # include #ifdef IVERILOG_V0_8 static PLI_INT32 dump_specify_compiletf(char*name) #else static PLI_INT32 dump_specify_compiletf(PLI_BYTE8*name) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item; item = vpi_scan(argv); if (argv == 0) { vpi_printf("%s: scope name argument missing.\n", name); vpi_control(vpiFinish, 1); return -1; } if (vpi_get(vpiType, item) != vpiModule) { vpi_printf("%s: Argument is not a vpiModule\n", name); vpi_control(vpiFinish, 1); return -1; } item = vpi_scan(argv); if (item != 0) { vpi_printf("%s: Too many arguments.\n", name); vpi_control(vpiFinish, 1); return -1; } return 0; } #ifdef IVERILOG_V0_8 static PLI_INT32 dump_specify_calltf(char*name) #else static PLI_INT32 dump_specify_calltf(PLI_BYTE8*name) #endif { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item = vpi_scan(argv); (void)name; /* Parameter is not used. */ assert(item); vpi_free_object(argv); vpi_printf("** Look for vpiModPath objects in %s.\n", vpi_get_str(vpiName, item)); argv = vpi_iterate(vpiModPath, item); if (argv == 0) { vpi_printf("** NO modpath items?\n"); } else { struct t_vpi_time delay_times[12]; struct t_vpi_delay delays; for (item = vpi_scan(argv); item; item = vpi_scan(argv)) { vpiHandle in_argv = vpi_iterate(vpiModPathIn, item); vpiHandle in_term = in_argv ? vpi_scan(in_argv) : 0; vpiHandle in_expr = in_term ? vpi_handle(vpiExpr, in_term) : 0; if (in_argv) vpi_free_object(in_argv); vpiHandle out_argv = vpi_iterate(vpiModPathOut, item); vpiHandle out_term = out_argv ? vpi_scan(out_argv) : 0; vpiHandle out_expr = out_term ? vpi_handle(vpiExpr, out_term) : 0; if (out_argv) vpi_free_object(out_argv); vpi_printf("** got path: %s ", in_expr ? vpi_get_str(vpiName, in_expr) : "?"); vpi_printf("--> %s\n", out_expr ? vpi_get_str(vpiName, out_expr) : "?"); delays.da = delay_times; delays.no_of_delays = 12; delays.time_type = vpiSimTime; delays.mtm_flag = 0; delays.append_flag = 0; #ifdef IVERILOG_V10 delays.plusere_flag = 0; #else delays.pulsere_flag = 0; #endif vpi_get_delays(item, &delays); vpi_printf("** (%d,%d,%d, %d,%d,%d, %d,%d,%d, %d,%d,%d)\n", (int)delay_times[0].low, (int)delay_times[1].low, (int)delay_times[2].low, (int)delay_times[3].low, (int)delay_times[4].low, (int)delay_times[5].low, (int)delay_times[6].low, (int)delay_times[7].low, (int)delay_times[8].low, (int)delay_times[9].low, (int)delay_times[10].low, (int)delay_times[11].low); delays.da = delay_times; delays.no_of_delays = 12; delays.time_type = vpiScaledRealTime; delays.mtm_flag = 0; delays.append_flag = 0; #ifdef IVERILOG_V10 delays.plusere_flag = 0; #else delays.pulsere_flag = 0; #endif vpi_get_delays(item, &delays); vpi_printf("** (%f,%f,%f, %f,%f,%f, %f,%f,%f, %f,%f,%f)\n", delay_times[0].real, delay_times[1].real, delay_times[2].real, delay_times[3].real, delay_times[4].real, delay_times[5].real, delay_times[6].real, delay_times[7].real, delay_times[8].real, delay_times[9].real, delay_times[10].real, delay_times[11].real); delays.time_type = vpiScaledRealTime; delay_times[0].real = 3.0; delay_times[1].real = 3.0; delay_times[2].real = 3.0; delay_times[3].real = 3.0; delay_times[4].real = 3.0; delay_times[5].real = 3.0; delay_times[6].real = 3.0; delay_times[7].real = 3.0; delay_times[8].real = 3.0; delay_times[9].real = 3.0; delay_times[10].real = 3.0; delay_times[11].real = 3.0; vpi_put_delays(item, &delays); delays.da = delay_times; delays.no_of_delays = 12; delays.time_type = vpiScaledRealTime; delays.mtm_flag = 0; delays.append_flag = 0; #ifdef IVERILOG_V10 delays.plusere_flag = 0; #else delays.pulsere_flag = 0; #endif vpi_get_delays(item, &delays); vpi_printf("** (%f,%f,%f, %f,%f,%f, %f,%f,%f, %f,%f,%f)\n", delay_times[0].real, delay_times[1].real, delay_times[2].real, delay_times[3].real, delay_times[4].real, delay_times[5].real, delay_times[6].real, delay_times[7].real, delay_times[8].real, delay_times[9].real, delay_times[10].real, delay_times[11].real); } } vpi_printf("** done\n"); return 0; } static void sys_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$dump_specify"; tf_data.calltf = dump_specify_calltf; tf_data.compiletf = dump_specify_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dump_specify"; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { sys_register, 0 }; iverilog-12_0/ivtest/vpi/spec_delays.v000066400000000000000000000007741435245347300201550ustar00rootroot00000000000000`celldefine //`timescale 1ns / 1ps // Description : 2 input XOR module XOR20 (input A, input B, output Q); xor (Q,B,A); specify (A => Q) = (1,1); (B => Q) = (1,1); endspecify endmodule `endcelldefine module tb; reg a, b; wire q; XOR20 dut(.A(a), .B(b), .Q(q)); initial begin $monitor($time,, "A=%b, B=%b, Q=%b", a, b, q); $dump_specify(dut); #10 ; a = 1; b = 1; #10 ; b = 0; #10 $finish(0); end endmodule // tb iverilog-12_0/ivtest/vpi/start_of_simtime1.c000066400000000000000000000040551435245347300212640ustar00rootroot00000000000000# include # include # include struct poke_details { vpiHandle dst; int val; }; static PLI_INT32 delayed_poke(p_cb_data cb_data) { s_vpi_value value; struct poke_details*poke = (struct poke_details*)cb_data->user_data; value.format = vpiIntVal; value.value.integer = poke->val; vpi_put_value(poke->dst, &value, 0, vpiNoDelay); free(poke); return 0; } static PLI_INT32 poke_compiletf(char*xx) { (void)xx; /* Parameter is not used. */ return 0; } static PLI_INT32 poke_calltf(char*xx) { s_vpi_value value; s_vpi_time poke_time; s_cb_data cb_data; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle dst, val, del, tmp; struct poke_details*poke; (void)xx; /* Parameter is not used. */ assert(argv); dst = vpi_scan(argv); assert(dst); val = vpi_scan(argv); assert(val); del = vpi_scan(argv); assert(del); tmp = vpi_scan(argv); assert(tmp == 0); poke = calloc(1, sizeof (struct poke_details)); assert(poke); poke->dst = dst; value.format = vpiIntVal; vpi_get_value(val, &value); poke->val = value.value.integer; value.format = vpiIntVal; vpi_get_value(del, &value); poke_time.low = value.value.integer; poke_time.high = 0; poke_time.type = vpiSimTime; cb_data.reason = cbAtStartOfSimTime; cb_data.cb_rtn = delayed_poke; cb_data.user_data = (char*)poke; cb_data.time = &poke_time; vpi_register_cb(&cb_data); return 0; } static void poke_after_delay_register(void) { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$poke_at_simtime"; tf_data.calltf = poke_calltf; tf_data.compiletf = poke_compiletf; tf_data.sizetf = 0; vpi_register_systf(&tf_data); } void (*vlog_startup_routines[])(void) = { poke_after_delay_register, 0 }; iverilog-12_0/ivtest/vpi/start_of_simtime1.v000066400000000000000000000012471435245347300213070ustar00rootroot00000000000000// When registering a simulation time callback, some simulators interpret // the specified time value as relative to the current simulation time. To // support this case, define the macro CB_TIME_IS_RELATIVE when compiling // this module. module main; integer val; initial begin val = 0; #1 $poke_at_simtime(val, 1, 10); `ifdef CB_TIME_IS_RELATIVE #1; `endif #8 if (val !== 0) begin $display("FAILED -- val==%0d before delayed poke", val); $finish; end #1 if (val !== 1) begin $display("FAILED -- val==%0d: poke didn't happen", val); $finish; end $display("PASSED"); $finish(0); end endmodule // main iverilog-12_0/ivtest/vpi/timescale.c000066400000000000000000000035511435245347300176010ustar00rootroot00000000000000#include "veriuser.h" extern PLI_INT32 tf_getlongsimtime(PLI_INT32 *high); static int mytest(int ud, int reason) { PLI_INT32 ht, lt; PLI_BYTE8 *cp; PLI_BYTE8 *inst = tf_getinstance(); PLI_BYTE8 *name = tf_spname(); (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ io_printf("Module %s\n", name); lt = tf_gettime(); io_printf("\ttf_gettime()\t\t\t-> %d\n", (int)lt); cp = tf_strgettime(); io_printf("\ttf_strgettime()\t\t\t-> %s\n", cp); lt = tf_getlongtime(&ht); io_printf("\ttf_getlongtime()\t\t-> %d/%d\n", (int)ht, (int)lt); lt = tf_igetlongtime(&ht, inst); io_printf("\ttf_igetlongtime(inst)\t\t-> %d/%d\n", (int)ht, (int)lt); lt = tf_getlongsimtime(&ht); io_printf("\ttf_getlongsimtime()\t\t-> %d/%d\n", (int)ht, (int)lt); lt = tf_gettimeprecision(); io_printf("\ttf_gettimeprecision()\t\t-> %d\n", (int)lt); lt = tf_igettimeprecision(inst); io_printf("\ttf_igettimeprecision(inst)\t-> %d\n", (int)lt); lt = tf_gettimeunit(); io_printf("\ttf_gettimeunit()\t\t-> %d\n", (int)lt); lt = tf_igettimeunit(inst); io_printf("\ttf_gettimeunit(inst)\t\t-> %d\n", (int)lt); lt = tf_igettimeunit(0); io_printf("\ttf_gettimeunit(0)\t\t-> %d\n", (int)lt); return 0; } static int return_32(int ud, int reason) { (void)ud; /* Parameter is not used. */ (void)reason; /* Parameter is not used. */ return 32; } s_tfcell veriusertfs[2] = { { usertask, 0, 0, return_32, mytest, 0, "$mytest", 1, 0, 0, {0} }, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0} } }; // Icarus registration p_tfcell icarus_veriusertfs(void) { return veriusertfs; } // Icarus Verilog compatibility static void veriusertfs_register(void) { veriusertfs_register_table(veriusertfs); } void (*vlog_startup_routines[])(void) = { &veriusertfs_register, 0 }; iverilog-12_0/ivtest/vpi/timescale.v000066400000000000000000000002611435245347300176170ustar00rootroot00000000000000`timescale 1us / 1ns module usns; initial begin #123; $mytest; end endmodule `timescale 1ns / 1ns module nsns; initial begin #456; $mytest; end endmodule iverilog-12_0/ivtest/vpi_gold/000077500000000000000000000000001435245347300164705ustar00rootroot00000000000000iverilog-12_0/ivtest/vpi_gold/br_gh117.gold000066400000000000000000000010641435245347300206520ustar00rootroot00000000000000Compiling vpi/br_gh117.c... Making br_gh117.vpi from br_gh117.o... Register callbacks After delay - current time 0 Read write - current time 1 Read only - current time 9 After delay - current time 10 Read write - current time 11 Read only - current time 19 After delay - current time 20 Read write - current time 21 Read only - current time 29 After delay - current time 30 Read write - current time 31 Read only - current time 39 After delay - current time 40 Read write - current time 41 Read only - current time 49 Finish sim - current time 50 iverilog-12_0/ivtest/vpi_gold/br_gh141.gold000066400000000000000000000004741435245347300206530ustar00rootroot00000000000000Compiling vpi/br_gh141.c... Making br_gh141.vpi from br_gh141.o... misctf called for reason 16 0 0 started background copy misctf called for reason 7 misctf called for reason 7 1 1 misctf called for reason 7 misctf called for reason 7 2 2 finished background copy misctf called for reason 9 iverilog-12_0/ivtest/vpi_gold/br_gh169a.gold000066400000000000000000000003521435245347300210210ustar00rootroot00000000000000Compiling vpi/br_gh169.c... Making br_gh169a.vpi from br_gh169.o... scope test wire test.a wire test.c wire test.b scope test.dut1 wire test.dut1.i1 reg test.dut1.o1 scope test.dut2 wire test.dut2.i2 reg test.dut2.o2 iverilog-12_0/ivtest/vpi_gold/br_gh169b.gold000066400000000000000000000003611435245347300210220ustar00rootroot00000000000000Compiling vpi/br_gh169.c... Making br_gh169b.vpi from br_gh169.o... scope test real test.a real test.c real test.b scope test.dut1 real test.dut1.o1 real test.dut1.i1 scope test.dut2 real test.dut2.i2 real test.dut2.o2 iverilog-12_0/ivtest/vpi_gold/br_gh184.gold000066400000000000000000000001351435245347300206540ustar00rootroot00000000000000Compiling vpi/start_of_simtime1.c... Making br_gh184.vpi from start_of_simtime1.o... PASSED iverilog-12_0/ivtest/vpi_gold/br_gh235.gold000066400000000000000000000001151435245347300206470ustar00rootroot00000000000000Compiling vpi/br_gh235.c... Making br_gh235.vpi from br_gh235.o... 1 PASSED iverilog-12_0/ivtest/vpi_gold/br_gh308.gold000066400000000000000000000002301435245347300206460ustar00rootroot00000000000000Compiling vpi/br_gh308.c... Making br_gh308.vpi from br_gh308.o... msb = 'b_00000000000000000000000000011111 lsb = 'b_00000000000000000000000000000000 iverilog-12_0/ivtest/vpi_gold/br_gh317.gold000066400000000000000000000012701435245347300206530ustar00rootroot00000000000000Compiling vpi/br_gh317.c... Making br_gh317.vpi from br_gh317.o... Looking for "\esc.port": found "esc.port" Looking for "\esc.port ": found "esc.port" Looking for "\esc.mod .\esc.inm .\esc.port": found "esc.port" Looking for "\esc.mod .\esc.inm .\esc.port ": found "esc.port" Looking for "\esc.val": found "esc.val" Looking for "\esc.val ": found "esc.val" Looking for "\esc.mod .\esc.inm .\esc.val": found "esc.val" Looking for "\esc.mod .\esc.inm .\esc.val ": found "esc.val" Looking for "\esc.mod .\esc.inm .normal": found "normal" Looking for "\esc.mod .inst.\esc.id": found "esc.id" Looking for "\esc.mod .inst.\esc.id ": found "esc.id" Looking for "\esc.mod .inst.normal": found "normal" iverilog-12_0/ivtest/vpi_gold/br_gh496.gold000066400000000000000000000002101435245347300206540ustar00rootroot00000000000000Compiling vpi/br_gh496.c... Making br_gh496.vpi from br_gh496.o... package $unit package p1 package p2 module m1 module m2 module test iverilog-12_0/ivtest/vpi_gold/br_gh59.gold000066400000000000000000000001611435245347300205740ustar00rootroot00000000000000Compiling vpi/br_gh59.c... Making br_gh59.vpi from br_gh59.o... zz z zz 0 01 0 01 500 01 1 zz 1000 01 0 01 2000 iverilog-12_0/ivtest/vpi_gold/br_gh73a.gold000066400000000000000000000005271435245347300207370ustar00rootroot00000000000000Compiling vpi/force.c... Making br_gh73a.vpi from force.o... peek : zzzz display : zzzz zz force : 10 peek : 0010 display : 0010 10 release : zzzz display : zzzz zz force : 10 peek : 0010 display : 0010 10 poke : 0 peek : 0010 display : 0010 10 release : 0000 display : 0000 00 poke : 1 peek : 0001 display : 0001 01 iverilog-12_0/ivtest/vpi_gold/br_gh73b.gold000066400000000000000000000005111435245347300207310ustar00rootroot00000000000000Compiling vpi/force.c... Making br_gh73b.vpi from force.o... peek : zz display : zz zzzz force : 10 peek : 10 display : 10 z10z release : zz display : zz zzzz force : 10 peek : 10 display : 10 z10z poke : 0 peek : 10 display : 10 z10z release : 00 display : 00 z00z poke : 1 peek : 01 display : 01 z01z iverilog-12_0/ivtest/vpi_gold/br_ml20191013.gold000066400000000000000000000005051435245347300212530ustar00rootroot00000000000000Compiling vpi/br_ml20191013.c... Making br_ml20191013.vpi from br_ml20191013.o... $pow PLI compiletf function. $pow PLI compiletf function. $pow StartOfSim callback. Start simulation pow_test.v $pow PLI calltf function. $pow(2,3) returns 8 $pow PLI calltf function. $pow(a,b) returns 1 (a=1 b=0) iverilog-12_0/ivtest/vpi_gold/by_index.gold000066400000000000000000000006661435245347300211500ustar00rootroot00000000000000Compiling vpi/by_index.c... Making by_index.vpi from by_index.o... The index is 3 The type is vpiRegBit val[3] => 1 == 1 The index is 4 The type is vpiNetBit wval[4] => 0 == 0 The index is 5 The type is vpiMemoryWord r_arr[5] => 5.25 == 5.25 The index is 2 The type is vpiMemoryWord i_arr[2] => 1 == 1 Original value is 01010101 New value is 01010110 Original net value is 1010 New net value is 0110 net value is now 1001 iverilog-12_0/ivtest/vpi_gold/by_name-std.log000066400000000000000000000021751435245347300214020ustar00rootroot00000000000000Compiling vpi/by_name.c... Making by_name.vpi from by_name.o... Looking up top0: Found name = top0, type = 32 Looking up top0.t_my: Found name = t_my, type = 59 Looking up top0.f_my: Found name = f_my, type = 20 Looking up top0.r: Found name = r, type = 48 Looking up top0.t: Found name = t, type = 63 Looking up top0.e: Found name = e, type = 34 Looking up top0.i: Found name = i, type = 25 Looking up top0.init: Found name = init, type = 33 Looking up top0.lvl1_0: Found name = lvl1_0, type = 32 Looking up top0.lvl1_1: Found name = lvl1_1, type = 32 Looking up top0.lvl1_0.lvl2.t_my: Found name = t_my, type = 59 Looking up top0.lvl1_0.lvl2.f_my: Found name = f_my, type = 20 Looking up top0.lvl1_0.lvl2.r: Found name = r, type = 48 Looking up top0.lvl1_0.lvl2.t: Found name = t, type = 63 Looking up top0.lvl1_0.lvl2.e: Found name = e, type = 34 Looking up top0.lvl1_0.lvl2.i: Found name = i, type = 25 Looking up top0.lvl1_0.lvl2.init: Found name = init, type = 33 Looking up top1: Found name = top1, type = 32 Looking up noexsist: *** Not found *** Looking up top1.noexsist: *** Not found *** Looking up top1.lvl1.noexsist: *** Not found *** iverilog-12_0/ivtest/vpi_gold/by_name.log000066400000000000000000000021751435245347300206120ustar00rootroot00000000000000Compiling vpi/by_name.c... Making by_name.vpi from by_name.o... Looking up top0: Found name = top0, type = 32 Looking up top0.t_my: Found name = t_my, type = 59 Looking up top0.f_my: Found name = f_my, type = 20 Looking up top0.r: Found name = r, type = 48 Looking up top0.t: Found name = t, type = 48 Looking up top0.e: Found name = e, type = 34 Looking up top0.i: Found name = i, type = 25 Looking up top0.init: Found name = init, type = 33 Looking up top0.lvl1_0: Found name = lvl1_0, type = 32 Looking up top0.lvl1_1: Found name = lvl1_1, type = 32 Looking up top0.lvl1_0.lvl2.t_my: Found name = t_my, type = 59 Looking up top0.lvl1_0.lvl2.f_my: Found name = f_my, type = 20 Looking up top0.lvl1_0.lvl2.r: Found name = r, type = 48 Looking up top0.lvl1_0.lvl2.t: Found name = t, type = 48 Looking up top0.lvl1_0.lvl2.e: Found name = e, type = 34 Looking up top0.lvl1_0.lvl2.i: Found name = i, type = 25 Looking up top0.lvl1_0.lvl2.init: Found name = init, type = 33 Looking up top1: Found name = top1, type = 32 Looking up noexsist: *** Not found *** Looking up top1.noexsist: *** Not found *** Looking up top1.lvl1.noexsist: *** Not found *** iverilog-12_0/ivtest/vpi_gold/callback1.log000066400000000000000000000003371435245347300210130ustar00rootroot00000000000000Compiling vpi/callback1.c... Making callback1.vpi from callback1.o... Registering Callbacks EndOfCompile EOC EndOfCompile EOC StartOfSimulation SOS StartOfSimulation SOS Hello World EndOfSimulation EOS EndOfSimulation EOS iverilog-12_0/ivtest/vpi_gold/celldefine.gold000066400000000000000000000002561435245347300214340ustar00rootroot00000000000000Compiling vpi/celldefine.c... Making celldefine.vpi from celldefine.o... Verilog checking was OK. Module instance top.dut is not a cell. Module instance top.dutb is a cell. iverilog-12_0/ivtest/vpi_gold/check_version.gold000066400000000000000000000001551435245347300221620ustar00rootroot00000000000000Compiling vpi/check_version.c... Making check_version.vpi from check_version.o... The two versions matched! iverilog-12_0/ivtest/vpi_gold/display_array.gold000066400000000000000000000004271435245347300222050ustar00rootroot00000000000000Compiling vpi/display_array.c... Making display_array.vpi from display_array.o... { 1, 2, 3, 4 } { 2, 3, 4, 5 } { 3.200000, 3.300000 } { 16045690984503098047, 841540768339247327, 81985529216486896, 18364758544493064721 } { uftu!tusjoh, bopuifs!pof, zfu!pof!npsf, uif!mbtu!pof } iverilog-12_0/ivtest/vpi_gold/event1.log000066400000000000000000000002131435245347300203710ustar00rootroot00000000000000Compiling vpi/event1.c... Making event1.vpi from event1.o... $test (test.evt [type = 34], test.evt2 [type = 34], test [type = 32]) PASSED iverilog-12_0/ivtest/vpi_gold/event2.log000066400000000000000000000002161435245347300203750ustar00rootroot00000000000000Compiling vpi/event2.c... Making event2.vpi from event2.o... Callback @ 10.0 Callback @ 20.0 Callback @ 30.0 vpi_remove_cb returned 1 @ 30.0 iverilog-12_0/ivtest/vpi_gold/final.gold000066400000000000000000000001621435245347300204270ustar00rootroot00000000000000Compiling vpi/final.c... Making final.vpi from final.o... In final statement. In VPI cbEndOfSimulation callback. iverilog-12_0/ivtest/vpi_gold/find_sig.gold000066400000000000000000000001131435245347300211140ustar00rootroot00000000000000Compiling vpi/find_sig.c... Making find_sig.vpi from find_sig.o... PASSED iverilog-12_0/ivtest/vpi_gold/force_reg.gold000066400000000000000000000004471435245347300212770ustar00rootroot00000000000000Compiling vpi/force.c... Making force_reg.vpi from force.o... peek : xx display : xx force : 10 peek : 10 display : 10 release : 10 display : 10 force : 10 peek : 10 display : 10 poke : 0 peek : 10 display : 10 release : 10 display : 10 poke : 1 peek : 01 display : 01 iverilog-12_0/ivtest/vpi_gold/force_reg_pv.gold000066400000000000000000000004611435245347300220000ustar00rootroot00000000000000Compiling vpi/force.c... Making force_reg_pv.vpi from force.o... peek : xx display :xxxx force : 10 peek : 10 display :x10x release : 10 display :x10x force : 10 peek : 10 display :x10x poke : 0 peek : 10 display :x10x release : 10 display :x10x poke : 1 peek : 01 display :x01x iverilog-12_0/ivtest/vpi_gold/force_reg_real.gold000066400000000000000000000006441435245347300223010ustar00rootroot00000000000000Compiling vpi/force_real.c... Making force_reg_real.vpi from force_real.o... peek : 0.000000 display : 0.000000 force : 3.000000 peek : 3.000000 display : 3.000000 release : 3.000000 display : 3.000000 force : 3.000000 peek : 3.000000 display : 3.000000 poke : 1.000000 peek : 3.000000 display : 3.000000 release : 3.000000 display : 3.000000 poke : 2.000000 peek : 2.000000 display : 2.000000 iverilog-12_0/ivtest/vpi_gold/force_wire.gold000066400000000000000000000004501435245347300214620ustar00rootroot00000000000000Compiling vpi/force.c... Making force_wire.vpi from force.o... peek : zz display : zz force : 10 peek : 10 display : 10 release : zz display : zz force : 10 peek : 10 display : 10 poke : 0 peek : 10 display : 10 release : 00 display : 00 poke : 1 peek : 01 display : 01 iverilog-12_0/ivtest/vpi_gold/force_wire_pv.gold000066400000000000000000000004621435245347300221720ustar00rootroot00000000000000Compiling vpi/force.c... Making force_wire_pv.vpi from force.o... peek : zz display :zzzz force : 10 peek : 10 display :z10z release : zz display :zzzz force : 10 peek : 10 display :z10z poke : 0 peek : 10 display :z10z release : 00 display :z00z poke : 1 peek : 01 display :z01z iverilog-12_0/ivtest/vpi_gold/force_wire_real.gold000066400000000000000000000006451435245347300224730ustar00rootroot00000000000000Compiling vpi/force_real.c... Making force_wire_real.vpi from force_real.o... peek : 0.000000 display : 0.000000 force : 3.000000 peek : 3.000000 display : 3.000000 release : 0.000000 display : 0.000000 force : 3.000000 peek : 3.000000 display : 3.000000 poke : 1.000000 peek : 3.000000 display : 3.000000 release : 1.000000 display : 1.000000 poke : 2.000000 peek : 2.000000 display : 2.000000 iverilog-12_0/ivtest/vpi_gold/genblk_direct.gold000066400000000000000000000014751435245347300221420ustar00rootroot00000000000000Compiling vpi/genblk_names.c... Making genblk_direct.vpi from genblk_names.o... reg test.genblk01[0].r1 reg test.genblk01[1].r1 reg test.genblk02[0].genblk1[0].r2 reg test.genblk02[0].genblk1[1].r2 reg test.genblk02[1].genblk1[0].r2 reg test.genblk02[1].genblk1[1].r2 reg test.genblk03[0].genblk1.r3b reg test.genblk03[1].genblk1.r3b reg test.genblk04[0].genblk1.r4a reg test.genblk04[1].genblk1.r4a reg test.genblk05[0].genblk1.r5b reg test.genblk05[1].genblk1.r5b reg test.genblk06[0].genblk1.r6c reg test.genblk06[1].genblk1.r6c reg test.genblk07.r7b reg test.genblk08.r8d reg test.genblk09.r9c reg test.genblk10.r10e reg test.genblk11.r11f reg test.genblk12.r12a reg test.genblk13.r13b reg test.genblk14.r14c reg test.genblk15.r15a reg test.genblk16.r16b reg test.genblk17.r17b reg test.genblk18.r18d reg test.genblk19.r19f iverilog-12_0/ivtest/vpi_gold/genblk_named.gold000066400000000000000000000013451435245347300217500ustar00rootroot00000000000000Compiling vpi/genblk_names.c... Making genblk_named.vpi from genblk_names.o... reg test.c1.r7b reg test.c2.c1.r8d reg test.c3.i1.r9c reg test.c4.i1.i1.r10e reg test.c5.i1.i1.r11f reg test.c6.i1.r12e reg test.c7.i1.r13f reg test.i01.r14a reg test.i02.i1.r15b reg test.i03.i1.r16c reg test.i04.r17b reg test.i05.r18c reg test.i06.i1.r19a reg test.i07.i1.r20b reg test.i08.c1.r21b reg test.i09.c1.r22d reg test.i10.c1.r23f reg test.l1[0].r1 reg test.l1[1].r1 reg test.l2[0].l1[0].r2 reg test.l2[0].l1[1].r2 reg test.l2[1].l1[0].r2 reg test.l2[1].l1[1].r2 reg test.l3[0].c1.r3b reg test.l3[1].c1.r3b reg test.l4[0].i1.r4a reg test.l4[1].i1.r4a reg test.l5[0].i1.i1.r5b reg test.l5[1].i1.i1.r5b reg test.l6[0].i1.i1.r6c reg test.l6[1].i1.i1.r6c iverilog-12_0/ivtest/vpi_gold/genblk_unnamed.gold000066400000000000000000000020621435245347300223100ustar00rootroot00000000000000Compiling vpi/genblk_names.c... Making genblk_unnamed.vpi from genblk_names.o... reg test.genblk01[0].r1 reg test.genblk01[1].r1 reg test.genblk02[0].genblk1[0].r2 reg test.genblk02[0].genblk1[1].r2 reg test.genblk02[1].genblk1[0].r2 reg test.genblk02[1].genblk1[1].r2 reg test.genblk03[0].genblk1.r3b reg test.genblk03[1].genblk1.r3b reg test.genblk04[0].genblk1.r4a reg test.genblk04[1].genblk1.r4a reg test.genblk05[0].genblk1.genblk1.r5b reg test.genblk05[1].genblk1.genblk1.r5b reg test.genblk06[0].genblk1.genblk1.r6c reg test.genblk06[1].genblk1.genblk1.r6c reg test.genblk07.r7b reg test.genblk08.genblk1.r8d reg test.genblk09.genblk1.r9c reg test.genblk10.genblk1.genblk1.r10e reg test.genblk11.genblk1.genblk1.r11f reg test.genblk12.genblk1.r12e reg test.genblk13.genblk1.r13f reg test.genblk14.r14a reg test.genblk15.genblk1.r15b reg test.genblk16.genblk1.r16c reg test.genblk17.r17b reg test.genblk18.r18c reg test.genblk19.genblk1.r19a reg test.genblk20.genblk1.r20b reg test.genblk21.genblk1.r21b reg test.genblk22.genblk1.r22d reg test.genblk23.genblk1.r23f iverilog-12_0/ivtest/vpi_gold/getp.log000066400000000000000000000007121435245347300201320ustar00rootroot00000000000000Compiling vpi/getp.c... Making getp.vpi from getp.o... tf_getp(1) -> 1 tf_igetp(1,inst) -> 1 tf_getrealp(1) -> 1.000000 tf_igetrealp(1,inst) -> 1.000000 tf_getp(2) -> 10 tf_igetp(2,inst) -> 10 tf_getrealp(2) -> 9.600000 tf_igetrealp(2,inst) -> 9.600000 tf_getp(3) -> 3 tf_igetp(3,inst) -> 3 tf_getrealp(3) -> 3.000000 tf_igetrealp(3,inst) -> 3.000000 tf_getp(4) -> 0 tf_igetp(4,inst) -> 0 tf_getrealp(4) -> 0.000000 tf_igetrealp(4,inst) -> 0.000000 iverilog-12_0/ivtest/vpi_gold/hello.log000066400000000000000000000001361435245347300202760ustar00rootroot00000000000000Compiling vpi/hello_vpi.c... Making hello_vpi.vpi from hello_vpi.o... Hello World, from VPI. iverilog-12_0/ivtest/vpi_gold/hello2.log000066400000000000000000000002141435245347300203550ustar00rootroot00000000000000Compiling vpi/hello_vpi1.c... Compiling vpi/hello_vpi2.c... Making hello_vpi2.vpi from hello_vpi1.o hello_vpi2.o... Hello World, from VPI. iverilog-12_0/ivtest/vpi_gold/hello_poke.log000066400000000000000000000001211435245347300213060ustar00rootroot00000000000000Compiling vpi/hello_poke.c... Making hello_poke.vpi from hello_poke.o... PASSED iverilog-12_0/ivtest/vpi_gold/hello_tf.log000066400000000000000000000001331435245347300207640ustar00rootroot00000000000000Compiling vpi/hello_tf.c... Making hello_tf.vpi from hello_tf.o... Hello World, from VPI. iverilog-12_0/ivtest/vpi_gold/listparams.log000066400000000000000000000001571435245347300213550ustar00rootroot00000000000000Compiling vpi/listparams.c... Making listparams.vpi from listparams.o... foo: 0101 str: String Text iverilog-12_0/ivtest/vpi_gold/memmon.log000066400000000000000000000002101435245347300204540ustar00rootroot00000000000000Compiling vpi/memmon.c... Making memmon.vpi from memmon.o... ValueChange: index=0, value=00000100 ValueChange: index=1, value=00000101 iverilog-12_0/ivtest/vpi_gold/memwide-std.log000066400000000000000000000016751435245347300214230ustar00rootroot00000000000000Compiling vpi/memwide.cc... Making memwide.vpi from memwide.o... !!!C++: Registering Callbacks !!!C++: event_trigger fullname is test.event_trigger !!!C++: Registered Value Change Callback for event_trigger !!!VERILOG: big_reg=xxxxxxxxx my_mem[1]=xxxxxxxxx !!!C++: callback !!!C++: big_reg fullname is test.big_reg !!!C++: big_reg size is 33 Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!C++: my_mem fullname is test.my_mem !!!C++: my_mem[1] size is 33 !!!C++: fullname is test.my_mem[1] Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!VERILOG: big_reg=123456789 my_mem[1]=154329876 !!!C++: callback !!!C++: big_reg fullname is test.big_reg !!!C++: big_reg size is 33 Vec 0) 23456789 00000000 Vec 1) 00000001 00000000 !!!C++: my_mem fullname is test.my_mem !!!C++: my_mem[1] size is 33 !!!C++: fullname is test.my_mem[1] Vec 0) 54329876 00000000 Vec 1) 00000001 00000000 iverilog-12_0/ivtest/vpi_gold/memwide.log000066400000000000000000000023601435245347300206230ustar00rootroot00000000000000Compiling vpi/memwide.cc... Making memwide.vpi from memwide.o... !!!C++: Registering Callbacks !!!C++: event_trigger fullname is test.event_trigger !!!C++: Registered Value Change Callback for event_trigger !!!C++: callback !!!C++: big_reg fullname is test.big_reg !!!C++: big_reg size is 33 Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!C++: my_mem fullname is test.my_mem !!!C++: my_mem[1] size is 33 !!!C++: fullname is test.my_mem[1] Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!VERILOG: big_reg=xxxxxxxxx my_mem[1]=xxxxxxxxx !!!C++: callback !!!C++: big_reg fullname is test.big_reg !!!C++: big_reg size is 33 Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!C++: my_mem fullname is test.my_mem !!!C++: my_mem[1] size is 33 !!!C++: fullname is test.my_mem[1] Vec 0) ffffffff ffffffff Vec 1) 00000001 00000001 !!!VERILOG: big_reg=123456789 my_mem[1]=154329876 !!!C++: callback !!!C++: big_reg fullname is test.big_reg !!!C++: big_reg size is 33 Vec 0) 23456789 00000000 Vec 1) 00000001 00000000 !!!C++: my_mem fullname is test.my_mem !!!C++: my_mem[1] size is 33 !!!C++: fullname is test.my_mem[1] Vec 0) 54329876 00000000 Vec 1) 00000001 00000000 iverilog-12_0/ivtest/vpi_gold/mipname.log000066400000000000000000000003431435245347300206210ustar00rootroot00000000000000Compiling vpi/mipname.c... Making mipname.vpi from mipname.o... tf_mipname() -> test.t2.t3 tf_imipname(inst) -> test.t2.t3 tf_mipname() -> test.t2 tf_imipname(inst) -> test.t2 tf_mipname() -> test tf_imipname(inst) -> test iverilog-12_0/ivtest/vpi_gold/myscope.gold000066400000000000000000000001471435245347300210200ustar00rootroot00000000000000Compiling vpi/myscope.c... Making myscope.vpi from myscope.o... My scope name: xor_try (s.b. xor_try) iverilog-12_0/ivtest/vpi_gold/myscope2.gold000066400000000000000000000005031435245347300210760ustar00rootroot00000000000000Compiling vpi/myscope2.c... Making myscope2.vpi from myscope2.o... ... ise_startup(reason=1) ... ise_vls_misc(reason=16) ... ise_vls_misc(reason=8) ... sn_calltf(reason=8) high_time=0, low_time=0 ... sn_calltf(reason=3) high_time=0, low_time=10 ... ise_vls_misc(reason=9) ... sn_calltf(reason=9) high_time=0, low_time=170 iverilog-12_0/ivtest/vpi_gold/nulls1-std.log000066400000000000000000000004731435245347300212050ustar00rootroot00000000000000Compiling vpi/nulls1.c... Making nulls1.vpi from nulls1.o... Registering Callbacks 0: Value Change 10: Value Change 20: Value Change 30: Value Change 40: Value Change 50: Value Change 60: Value Change 70: Value Change 80: Value Change 90: Value Change 100: Value Change iverilog-12_0/ivtest/vpi_gold/nulls1.log000066400000000000000000000005201435245347300204060ustar00rootroot00000000000000Compiling vpi/nulls1.c... Making nulls1.vpi from nulls1.o... Registering Callbacks 0: Value Change 0: Value Change 10: Value Change 20: Value Change 30: Value Change 40: Value Change 50: Value Change 60: Value Change 70: Value Change 80: Value Change 90: Value Change 100: Value Change iverilog-12_0/ivtest/vpi_gold/pokereg.log000066400000000000000000000011071435245347300206260ustar00rootroot00000000000000Compiling vpi/pokereg.cc... Making pokereg.vpi from pokereg.o... Registering Callbacks RegPoke Callback 0: x001x001 1: 0x2 2: 3 3: x4 4: 69 RegPeek Callback 0: 'b_00xxx010, 'o_0x2, 'd_X, 'h_XX 1: 'b_00000011, 'o_003, 'd_3, 'h_03 2: 'b_xxxx0100, 'o_xX4, 'd_X, 'h_x4 3: 'b_01000101, 'o_105, 'd_69, 'h_45 4: 'b_x001x001, 'o_XX1, 'd_X, 'h_XX Verilog compare r_poke <=> r_peek 'b_x001x001 <=> 'b_x001x001 'b_00xxx010 <=> 'b_00xxx010 'b_00000011 <=> 'b_00000011 'b_xxxx0100 <=> 'b_xxxx0100 'b_01000101 <=> 'b_01000101 iverilog-12_0/ivtest/vpi_gold/pokevent.log000066400000000000000000000005771435245347300210370ustar00rootroot00000000000000Compiling vpi/pokevent.cc... Making pokevent.vpi from pokevent.o... !!!C++: Registering Callbacks e_Poke received @ 0 e_Peek asserted @ 10 callback e_Poke received @ 10 e_Peek asserted @ 20 callback e_Poke received @ 20 e_Peek asserted @ 30 callback e_Poke received @ 30 e_Peek asserted @ 40 callback e_Poke received @ 40 e_Peek asserted @ 50 callback e_Poke received @ 50 iverilog-12_0/ivtest/vpi_gold/ports_params.gold000066400000000000000000000011611435245347300220500ustar00rootroot00000000000000Compiling vpi/ports_params.c... Making ports_params.vpi from ports_params.o... PARAM NAME=ADC_OFFSET type=2 value=(REAL)-16 local=no PARAM NAME=ADC_RANGE type=2 value=(REAL)32 local=no PARAM NAME=CLOCK_INTERVAL type=3 value=(INT)1000 local=no PARAM NAME=DAC_OFFSET type=2 value=(REAL)-8 local=no PARAM NAME=DAC_RANGE type=2 value=(REAL)16 local=no PARAM NAME=STARTUP_DELAY type=3 value=(INT)2000000 local=no PARAM NAME=UPDATE_FREQ_MHZ type=2 value=(REAL)1 local=no PORT name=V_load_adc index=0 dir=1 size=16 PORT name=V_load_valid index=1 dir=1 size=1 PORT name=pwm index=2 dir=2 size=1 PORT name=V_src index=3 dir=2 size=8 iverilog-12_0/ivtest/vpi_gold/pr1693971.log000066400000000000000000000004201435245347300203740ustar00rootroot00000000000000Compiling vpi/pr1693971.c... Making pr1693971.vpi from pr1693971.o... $my_pow PLI compiletf function. $my_pow PLI compiletf function. $my_pow StartOfSim callback. Start simulation pow_test.v $my_pow(2,3) returns 8 $my_pow(a,b) returns 1 (a=1 b=0) iverilog-12_0/ivtest/vpi_gold/pr2048463.log000066400000000000000000000014301435245347300203650ustar00rootroot00000000000000Compiling vpi/pr2048463.c... Making pr2048463.vpi from pr2048463.o... Adding monitors to all nets in module addbit: At time 0.00: test.i1.a = 0 At time 0.00: test.i1.b = 0 At time 0.00: test.i1.ci = 0 At time 1.00: test.i1.n1 = 0 At time 2.00: test.i1.n2 = 0 At time 3.00: test.i1.n3 = 0 At time 5.00: test.i1.sum = 0 At time 7.00: test.i1.co = 0 At time 10.00: test.i1.a = 1 At time 11.00: test.i1.n1 = 1 At time 15.00: test.i1.sum = 1 At time 20.00: test.i1.a = 0 At time 21.00: test.i1.n1 = 0 At time 25.00: test.i1.sum = 0 At time 30.00: test.i1.b = 1 At time 31.00: test.i1.n1 = 1 At time 35.00: test.i1.sum = 1 At time 40.00: test.i1.a = 1 At time 41.00: test.i1.n1 = 0 At time 42.00: test.i1.n2 = 1 At time 45.00: test.i1.sum = 0 At time 46.00: test.i1.co = 1 iverilog-12_0/ivtest/vpi_gold/pr2314742.gold000066400000000000000000000006441435245347300205330ustar00rootroot00000000000000Compiling vpi/pr2314742.c... Making pr2314742.vpi from pr2314742.o... *** Registering XXX PLI functions. +++ in XXX_REGISTER 0 The value of A is: 00000000 0 The value of B is: 00000000 0 The value of C is: 00000000 10 The value of A is: 01010101 20 The value of B is: x1x1x1x1 30 The value of C is: 0xz101xz iverilog-12_0/ivtest/vpi_gold/pr2966059.gold000066400000000000000000000013521435245347300205460ustar00rootroot00000000000000Compiling vpi/pr2966059.c... Making pr2966059.vpi from pr2966059.o... vpi_get_value (): format = 9 value = 1 vpi_get_value (ip): format = 9 value = 1 vpi_get_value (): format = 7 value = 0 vpi_get_value (rp): format = 7 value = 2 vpi_get_value (): format = 8 value = 3 vpi_get_value (sp): format = 8 value = 3 vpi_get_value (rlval): format = 7 value = 0 vpi_get_value (): format = 7 value = 0 vpi_get_value (wreal): format = 7 value = 0 vpi_get_value (): format = 7 value = 0 vpi_get_value (rval): format = 9 value = x vpi_get_value (): format = 9 value = x vpi_get_value (wval): format = 9 value = z vpi_get_value (): format = 9 value = x iverilog-12_0/ivtest/vpi_gold/pr2971220.gold000066400000000000000000000013331435245347300205270ustar00rootroot00000000000000Compiling vpi/pr2971220.c... Making pr2971220.vpi from pr2971220.o... --> registered task as: $check_sys_task. --> registered func as: $check_sys_func. Hello from $hello at vpi/pr2971220.v:4. registered as: vpiUserSystf - $check_sys_task vpiUserDefn: is defined. vpi_get_systf_info: passed. vpi_get_systf_info (callh): passed. Looking for all user defined system tasks/functions: Found task vpiUserSystf - $check_sys_task *****> caller. Found function (vpiIntFunc) vpiUserSystf - $check_sys_func. Found task vpiUserSystf - $hello. Done. registered as: vpiUserSystf - $check_sys_func vpiUserDefn: is defined. vpi_get_systf_info: passed. vpi_get_systf_info (callh): passed. Hello from $hello at vpi/pr2971220.v:7. iverilog-12_0/ivtest/vpi_gold/pr521.log000066400000000000000000000003011435245347300200360ustar00rootroot00000000000000Compiling vpi/pr521.c... Making pr521.vpi from pr521.o... Passing parameter to PLI routine: 0x43 PLI Parameter received 0x43 Passing parameter to PLI routine: 0x43 PLI Parameter received 0x43 iverilog-12_0/ivtest/vpi_gold/pr686.log000066400000000000000000000002411435245347300200550ustar00rootroot00000000000000Compiling vpi/pr686.c... Making pr686.vpi from pr686.o... foo should be 0: 1 Callback time=1 foo=1 foo should be 1: 1 Callback time=5 foo=1 foo is finally 2 iverilog-12_0/ivtest/vpi_gold/pr723-std.log000066400000000000000000000013611435245347300206410ustar00rootroot00000000000000Compiling vpi/pr723.c... Making pr723.vpi from pr723.o... Open some files open MCD returned 00000002 open MCD returned 00000004 open MCD returned 00000008 open MCD returned 00000010 open FD ('r') returned 80000003 open FD ('r') returned 80000004 open FD ('w') returned 80000005 open FD ('w') returned 80000006 open FD ('a') returned 80000007 open FD ('a') returned 80000008 MCD 01: stdout MCD 02: /dev/null MCD 03: /dev/null MCD 04: /dev/null MCD 05: /dev/null FP 00: stdin FP 01: stdout FP 02: stderr FP 03: /dev/null FP 04: /dev/null FP 05: /dev/null FP 06: /dev/null FP 07: /dev/null FP 08: /dev/null write to MCD 1 write to FD 2 write to FD 1 Close some files MCD 01: stdout FP 00: stdin FP 01: stdout FP 02: stderr iverilog-12_0/ivtest/vpi_gold/pr723-v10.log000066400000000000000000000023461435245347300204610ustar00rootroot00000000000000Compiling vpi/pr723.c... Making pr723.vpi from pr723.o... Open some files open MCD returned 00000002 open MCD returned 00000004 open MCD returned 00000008 open MCD returned 00000010 open FD ('r') returned 80000003 open FD ('r') returned 80000004 open FD ('w') returned 80000005 open FD ('w') returned 80000006 open FD ('a') returned 80000007 open FD ('a') returned 80000008 MCD 01: stdout MCD 02: /dev/null MCD 03: /dev/null MCD 04: /dev/null MCD 05: /dev/null FP 00: stdin FP 01: stdout FP 02: stderr FP 03: /dev/null FP 04: /dev/null FP 05: /dev/null FP 06: /dev/null FP 07: /dev/null FP 08: /dev/null write to MCD 1 write to FD 2 write to FD 1 Close some files WARNING: vpi/pr723.v:48: invalid file descriptor/MCD (0x2) given to $fclose. WARNING: vpi/pr723.v:49: invalid file descriptor/MCD (0x40000000) given to $fclose. WARNING: vpi/pr723.v:54: invalid file descriptor/MCD (0x80000003) given to $fclose. WARNING: vpi/pr723.v:57: invalid file descriptor/MCD (0x81ca1ca0) given to $fclose. MCD 01: stdout FP 00: stdin FP 01: stdout FP 02: stderr WARNING: vpi/pr723.v:63: invalid file descriptor/MCD (0x40000000) given to $fdisplay. WARNING: vpi/pr723.v:64: invalid file descriptor/MCD (0x8000000f) given to $fdisplay. iverilog-12_0/ivtest/vpi_gold/pr723.log000066400000000000000000000030161435245347300200500ustar00rootroot00000000000000Compiling vpi/pr723.c... Making pr723.vpi from pr723.o... Open some files open MCD returned 00000002 open MCD returned 00000004 open MCD returned 00000008 open MCD returned 00000010 open FD ('r') returned 80000003 open FD ('r') returned 80000004 open FD ('w') returned 80000005 open FD ('w') returned 80000006 open FD ('a') returned 80000007 open FD ('a') returned 80000008 MCD 01: stdout MCD 02: /dev/null MCD 03: /dev/null MCD 04: /dev/null MCD 05: /dev/null FP 00: stdin FP 01: stdout FP 02: stderr FP 03: /dev/null FP 04: /dev/null FP 05: /dev/null FP 06: /dev/null FP 07: /dev/null FP 08: /dev/null write to MCD 1 write to FD 2 write to FD 1 Close some files WARNING: vpi/pr723.v:47: could not close MCD STDOUT (0x1) in $fclose(). WARNING: vpi/pr723.v:48: invalid MCD (0x2) given to $fclose(). WARNING: vpi/pr723.v:49: invalid MCD (0x40000000) given to $fclose(). WARNING: vpi/pr723.v:51: could not close file descriptor STDIN (0x80000000) in $fclose(). WARNING: vpi/pr723.v:52: could not close file descriptor STDOUT (0x80000001) in $fclose(). WARNING: vpi/pr723.v:53: could not close file descriptor STDERR (0x80000002) in $fclose(). WARNING: vpi/pr723.v:54: invalid file descriptor (0x80000003) given to $fclose(). WARNING: vpi/pr723.v:57: invalid file descriptor (0x81ca1ca0) given to $fclose(). MCD 01: stdout FP 00: stdin FP 01: stdout FP 02: stderr WARNING: vpi/pr723.v:63: invalid MCD (0x40000000) given to $fdisplay(). WARNING: vpi/pr723.v:64: invalid file descriptor (0x8000000f) given to $fdisplay(). iverilog-12_0/ivtest/vpi_gold/putp.log000066400000000000000000000000771435245347300201670ustar00rootroot00000000000000Compiling vpi/putp.c... Making putp.vpi from putp.o... PASSED iverilog-12_0/ivtest/vpi_gold/putp2.log000066400000000000000000000001021435245347300202360ustar00rootroot00000000000000Compiling vpi/putp2.c... Making putp2.vpi from putp2.o... PASSED iverilog-12_0/ivtest/vpi_gold/putvalue.log000066400000000000000000000005561435245347300210460ustar00rootroot00000000000000Compiling vpi/putvalue.c... Making putvalue.vpi from putvalue.o... r = x r = 0 @ 0 r = 0 r = 1 @ 1000 r = 1 r = 0 @ 2000 r = 0 r = 1 @ 3000 r = 1 r = 0 @ 40000000 r = 0 r = 1 @ 50000000 r = 1 r = 0 @ 60000000 r = 0 iverilog-12_0/ivtest/vpi_gold/range1.gold000066400000000000000000000001431435245347300205120ustar00rootroot00000000000000Compiling vpi/range1.c... Making range1.vpi from range1.o... Dimensions of xor_try.inp_xor: [1:0] iverilog-12_0/ivtest/vpi_gold/realcb.log000066400000000000000000000002361435245347300204240ustar00rootroot00000000000000Compiling vpi/realcb.c... Making realcb.vpi from realcb.o... watchreal: x = 1.000000 watchreal: y = 2.000000 watchreal: x = 1.500000 watchreal: y = 5.100000 iverilog-12_0/ivtest/vpi_gold/realtime.log000066400000000000000000000005301435245347300207730ustar00rootroot00000000000000Compiling vpi/realtime.c... Making realtime.vpi from realtime.o... time = 12346.000000 calltf from test2 12346.000000, 12346.000000 time = 14692.000000 calltf from test2 14692.000000, 14692.000000 time = 12345.678900 calltf from test 12345678900000.000000, 12345.678900 time = 14691.357810 calltf from test 14691357810000.000000, 14691.357810 iverilog-12_0/ivtest/vpi_gold/realtime2.log000066400000000000000000000004341435245347300210600ustar00rootroot00000000000000Compiling vpi/realtime2.c... Making realtime2.vpi from realtime2.o... $time = 57 calltf from test2 57.000000, 57.000000 $time = 136 calltf from test2 136.000000, 136.000000 $time = 12000 calltf from test 12346.000000, 12.346000 $time = 47000 calltf from test 46914.000000, 46.914000 iverilog-12_0/ivtest/vpi_gold/ro_synch.gold000066400000000000000000000003751435245347300211700ustar00rootroot00000000000000Compiling vpi/ro_synch.c... Making ro_synch.vpi from ro_synch.o... VPI error: attempted to put a value to variable 'val' during a read-only synch callback. VPI error: attempted to put a value to variable 'val' during a read-only synch callback. PASSED iverilog-12_0/ivtest/vpi_gold/scanmem.log000066400000000000000000000007141435245347300206200ustar00rootroot00000000000000Compiling vpi/scanmem.cc... Making scanmem.vpi from scanmem.o... Registering Callbacks MemPoke Callback Found m_poke (5 deep x 32 bits) MemPeek Callback Found m_peek (5 deep x 32 bits) m_poke[0] <=> m_peek[0] 0x01010101 0xfefefefe m_poke[1] <=> m_peek[1] 0x02020202 0xfdfdfdfd m_poke[2] <=> m_peek[2] 0x03030303 0xfcfcfcfc m_poke[3] <=> m_peek[3] 0x04040404 0xfbfbfbfb m_poke[4] <=> m_peek[4] 0x05050505 0xfafafafa iverilog-12_0/ivtest/vpi_gold/scanmem2.log000066400000000000000000000017561435245347300207110ustar00rootroot00000000000000Compiling vpi/scanmem2.cc... Making scanmem2.vpi from scanmem2.o... Registering Callbacks MemPoke Callback Found m_poke (5 deep x 76 bits) 0: f00cafababedeabbeef 1: 70850123451113459662575 2: 17001453725653733652737357 3: 1111000000001100101011111010101110101011111011011110101010111011111011101111 4: f00cafababedeabbeef MemPeek Callback Found m_peek (5 deep x 76 bits) 0: 1111000000001100101011111010101110101011111011011110101010111011111011101111 1: 17001453725653733652737357 2: 70850123451113459662575 3: f00cafababedeabbeef 4: 1111000000001100101011111010101110101011111011011110101010111011111011101111 0: m_poke <=> m_peek, 0xf00cafababedeabbeef <=> 0xf00cafababedeabbeef 1: m_poke <=> m_peek, 0xf00cafababedeabbeef <=> 0xf00cafababedeabbeef 2: m_poke <=> m_peek, 0xf00cafababedeabbeef <=> 0xf00cafababedeabbeef 3: m_poke <=> m_peek, 0xf00cafababedeabbeef <=> 0xf00cafababedeabbeef 4: m_poke <=> m_peek, 0xf00cafababedeabbeef <=> 0xf00cafababedeabbeef iverilog-12_0/ivtest/vpi_gold/scanmem3.log000066400000000000000000000016451435245347300207070ustar00rootroot00000000000000Compiling vpi/scanmem3.cc... Making scanmem3.vpi from scanmem3.o... Registering Callbacks MemPoke Callback Found m_poke (8 deep x 8 bits) 0: x001x001 1: 0x2 2: 3 3: x4 4: x101x101 5: 0x6 6: 7 7: x8 MemPeek Callback Found m_peek (8 deep x 8 bits) 0: 'b_x001x001, 'o_XX1, 'd_X, 'h_XX 1: 'b_00xxx010, 'o_0x2, 'd_X, 'h_XX 2: 'b_00000011, 'o_003, 'd_3, 'h_03 3: 'b_xxxx0100, 'o_xX4, 'd_X, 'h_x4 4: 'b_x101x101, 'o_XX5, 'd_X, 'h_XX 5: 'b_00xxx110, 'o_0x6, 'd_X, 'h_XX 6: 'b_00000111, 'o_007, 'd_7, 'h_07 7: 'b_xxxx1000, 'o_xX0, 'd_X, 'h_x8 Verilog compare m_poke <=> m_peek 0: 'b_x001x001 <=> 'b_x001x001 1: 'b_00xxx010 <=> 'b_00xxx010 2: 'b_00000011 <=> 'b_00000011 3: 'b_xxxx0100 <=> 'b_xxxx0100 4: 'b_x101x101 <=> 'b_x101x101 5: 'b_00xxx110 <=> 'b_00xxx110 6: 'b_00000111 <=> 'b_00000111 7: 'b_xxxx1000 <=> 'b_xxxx1000 iverilog-12_0/ivtest/vpi_gold/scopes-std.log000066400000000000000000000007051435245347300212610ustar00rootroot00000000000000Compiling vpi/scopes.c... Making scopes.vpi from scopes.o... top0 is type vpiModule t_bar is type vpiTask my_init is type vpiNamedBegin lvl1 is type vpiModule f_foo is type vpiFunction lvl2 is type vpiModule lvl3 is type vpiModule my_fork is type vpiNamedFork top1 is type vpiModule lvl1 is type vpiModule lvl2 is type vpiModule lvl3 is type vpiModule my_fork is type vpiNamedFork top2 is type vpiModule iverilog-12_0/ivtest/vpi_gold/scopes.log000066400000000000000000000007051435245347300204710ustar00rootroot00000000000000Compiling vpi/scopes.c... Making scopes.vpi from scopes.o... top0 is type vpiModule lvl1 is type vpiModule f_foo is type vpiFunction lvl2 is type vpiModule lvl3 is type vpiModule my_fork is type vpiNamedFork my_init is type vpiNamedBegin t_bar is type vpiTask top1 is type vpiModule lvl1 is type vpiModule lvl2 is type vpiModule lvl3 is type vpiModule my_fork is type vpiNamedFork top2 is type vpiModule iverilog-12_0/ivtest/vpi_gold/spec_delays.log000066400000000000000000000016251435245347300214720ustar00rootroot00000000000000Compiling vpi/spec_delays.c... Making spec_delays.vpi from spec_delays.o... ** Look for vpiModPath objects in dut. ** got path: A --> Q ** (1,1,1, 1,1,1, 1,1,1, 1,1,1) ** (1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000) ** (3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000) ** got path: B --> Q ** (1,1,1, 1,1,1, 1,1,1, 1,1,1) ** (1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000, 1.000000,1.000000,1.000000) ** (3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000, 3.000000,3.000000,3.000000) ** done 0 A=x, B=x, Q=x 10 A=1, B=1, Q=x 13 A=1, B=1, Q=0 20 A=1, B=0, Q=0 23 A=1, B=0, Q=1 iverilog-12_0/ivtest/vpi_gold/start_of_simtime1.log000066400000000000000000000001461435245347300226250ustar00rootroot00000000000000Compiling vpi/start_of_simtime1.c... Making start_of_simtime1.vpi from start_of_simtime1.o... PASSED iverilog-12_0/ivtest/vpi_gold/timescale.log000066400000000000000000000012371435245347300211440ustar00rootroot00000000000000Compiling vpi/timescale.c... Making timescale.vpi from timescale.o... Module nsns tf_gettime() -> 456 tf_strgettime() -> 456 tf_getlongtime() -> 0/456 tf_igetlongtime(inst) -> 0/456 tf_getlongsimtime() -> 0/456 tf_gettimeprecision() -> -9 tf_igettimeprecision(inst) -> -9 tf_gettimeunit() -> -9 tf_gettimeunit(inst) -> -9 tf_gettimeunit(0) -> -9 Module usns tf_gettime() -> 123 tf_strgettime() -> 123000 tf_getlongtime() -> 0/123 tf_igetlongtime(inst) -> 0/123 tf_getlongsimtime() -> 0/123000 tf_gettimeprecision() -> -9 tf_igettimeprecision(inst) -> -9 tf_gettimeunit() -> -6 tf_gettimeunit(inst) -> -6 tf_gettimeunit(0) -> -9 iverilog-12_0/ivtest/vpi_reg.pl000077500000000000000000000224201435245347300166600ustar00rootroot00000000000000#!/usr/bin/env perl # # Script to handle regression for VPI routines # use lib './perl-lib'; use Environment; $| = 1; # This turns off buffered I/O # We support a --suffix= and --with-valgrind flags. use Getopt::Long; $sfx = ""; # Default suffix. $with_valg = 0; # Default valgrind usage (keep this off). if (!GetOptions("suffix=s" => \$sfx, "with-valgrind" => \$with_valg, "help" => \&usage)) { die "Error: Invalid argument(s).\n"; } sub usage { warn "$0 usage:\n\n" . " --suffix= # The Icarus executables suffix, " . "default \"\".\n" . " --with-valgrind # Run the test suite with valgrind, " . "default \"off\".\n" . " # The regression file, " . "default \"./vpi_regress.list\".\n\n"; exit; } $regress_fn = "./vpi_regress.list"; # Default regression list. # Is there a command line argument (alternate regression list)? if ($#ARGV != -1) { $regress_fn = $ARGV[0]; -e $regress_fn or die "Error: command line regression file $regress_fn doesn't exist.\n"; -f $regress_fn or die "Error: command line regression file $regress_fn is not a file.\n"; -r $regress_fn or die "Error: command line regression file $regress_fn is not ". "readable.\n"; if ($#ARGV > 0) { warn "Warning: only using first file argument to script.\n"; } } # # Main script # my $sys = $ENV{MSYSTEM} ? 'msys2' : 'other'; my $ver = &get_ivl_version($sfx); my $msg = $with_valg ? " (with valgrind)" : ""; print ("Running VPI tests for Icarus Verilog version: $ver$msg.\n"); print "-" x 76 . "\n"; &read_regression_list; &execute_regression; # # parses the regression list file # # (from left-to-right in regression file): # # test_name type c/c++_code gold_file opt_c/c++_defines # sub read_regression_list { my ($line, @fields, $tname, $tver, %nameidx); open (REGRESS_LIST, "<$regress_fn") or die "Error: unable to open $regress_fn for reading.\n"; while ($line = ) { chomp $line; next if ($line =~ /^\s*#/); # Skip comments. next if ($line =~ /^\s*$/); # Skip blank lines. $line =~ s/#.*$//; # Strip in line comments. $line =~ s/\s+$//; # Strip trailing white space. # You must specify at least the first four fields, cargs is optional # and gets the rest of the fields if present. @fields = split(' ', $line, 5); if (@fields < 3) { die "Error: $fields[0] must have at least 4 fields.\n"; } $tname = $fields[0]; # Check for a version or system specific line. if ($tname =~ /:/) { ($tver, $tname) = split(':', $tname); next if (exists($ccode{$tname})); # Skip if already defined. next if ($tver ne "v$ver" && $tver ne $sys); # Skip if this is not our version or system. # Get the test type and any iverilog arguments. if ($fields[1] =~ ',') { ($testtype, $args{$tname}) = split(',', $fields[1], 2); # For now we just support args to iverilog. if ($args{$tname} =~ ',') { $args{$tname} = join(' ', split(',', $args{$tname})); } } else { $testtype = $fields[1]; $args{$tname} = ""; } # This version of the program does not implement something # required to run this test. if ($testtype eq "NI") { $args{$tname} = ""; $ccode{$tname} = ""; $goldfile{$tname} = ""; $cargs{$tname} = ""; } else { $ccode{$tname} = $fields[2]; $goldfile{$tname} = $fields[3]; $cargs{$tname} = $fields[4]; } # print "Read $tver:$tname=$ccode{$tname}, $goldfile{$tname}, ". # "$args{$tname}, $cargs{$tname}\n"; } else { next if (exists($ccode{$tname})); # Skip if already defined. # Get the test type and any iverilog arguments. if ($fields[1] =~ ',') { ($testtype, $args{$tname}) = split(',', $fields[1], 2); # For now we just support args to iverilog. if ($args{$tname} =~ ',') { $args{$tname} = join(' ', split(',', $args{$tname})); } } else { $args{$tname} = ""; } $ccode{$tname} = $fields[2]; $goldfile{$tname} = $fields[3]; $cargs{$tname} = $fields[4]; # print "Read $tname=$ccode{$tname}, $goldfile{$tname}, ". # "$args{$tname}, $cargs{$tname}\n"; } # If there wasn't a cargs field make it a null string. $cargs{$tname} = "" if (!defined($cargs{$tname})); # If the name exists this is a replacement so skip the original one. if (exists($nameidx{$tname})) { splice(@testlist, $nameidx{$tname}, 1, ""); } push (@testlist,$tname); $nameidx{$tname} = @testlist - 1; } close (REGRESS_LIST); } # # execute_regression sequentially compiles and executes each test in # the regression. It then checks that the output matched the gold file. # sub execute_regression { my ($tname, $total, $passed, $failed, $not_impl, $len, $cmd); $total = 0; $passed = 0; $failed = 0; $not_impl = 0; $len = 0; foreach $tname (@testlist) { $len = length($tname) if (length($tname) > $len); } # Make sure we have a log directory. if (! -d 'vpi_log') { mkdir 'vpi_log' or die "Error: unable to create vpi_log directory.\n"; } foreach $tname (@testlist) { next if ($tname eq ""); # Skip test that have been replaced. $total++; printf "%${len}s: ", $tname; if (-e "vpi_log/$tname.log") { unlink "vpi_log/$tname.log" or die "Error: unable to remove old log file ". "vpi_log/$tname.log.\n"; } if ($ccode{$tname} eq "") { print "Not Implemented.\n"; $not_impl++; next; } $cmd = "iverilog-vpi$sfx --name=$tname $cargs{$tname} " . "vpi/$ccode{$tname} > vpi_log/$tname.log 2>&1"; if (system("$cmd")) { print "==> Failed - running iverilog-vpi.\n"; $failed++; next; } $cmd = $with_valg ? "valgrind --trace-children=yes " : ""; if ($ver < 11) { $cmd .= "iverilog$sfx $args{$tname} -o vsim vpi/$tname.v >> " . "vpi_log/$tname.log 2>&1"; } else { $cmd .= "iverilog$sfx $args{$tname} -L . -m $tname -o vsim vpi/$tname.v >> " . "vpi_log/$tname.log 2>&1"; } if (system("$cmd")) { print "==> Failed - running iverilog.\n"; $failed++; next; } $cmd = $with_valg ? "valgrind --leak-check=full " . "--show-reachable=yes " : ""; if ($ver < 11) { $cmd .= "vvp$sfx -M . -m $tname vsim >> vpi_log/$tname.log 2>&1"; } else { $cmd .= "vvp$sfx vsim >> vpi_log/$tname.log 2>&1"; } if (system("$cmd")) { print "==> Failed - running vvp.\n"; $failed++; next; } if (diff("vpi_gold/$goldfile{$tname}", "vpi_log/$tname.log")) { print "==> Failed - output does not match gold file.\n"; $failed++; next; } print "Passed.\n"; $passed++; } continue { # We have to use system and not unlink here since these files # were created by this process and it doesn't seem to know they # are not being used. if ($tname ne "" and $ccode{$tname} ne "") { my $doto = $ccode{$tname}; $doto =~ s/\.(c|cc|cpp)$/.o/; system("rm -f $doto $tname.vpi vsim") and die "Error: failed to remove temporary files.\n"; } } print "=" x 76 . "\n"; print "Test results: Total=$total, Passed=$passed, Failed=$failed,". " Not Implemented=$not_impl\n"; exit $failed; } # # We only need a simple diff, but we need to strip \r at the end of line. # sub diff { my ($gold, $log) = @_; my ($diff, $gline, $lline); $diff = 0; open (GOLD, "<$gold") or die "Error: unable to open $gold for reading.\n"; open (LOG, "<$log") or die "Error: unable to open $log for reading.\n"; # Loop on the gold file lines. foreach $gline () { if (eof LOG) { $diff = 1; last; } $lline = ; # Skip lines from valgrind ^==\d+== or ^**\d+** while ($lline =~ m/^(==|\*\*)\d+(==|\*\*)/) { $lline = ; } $gline =~ s/\r\n$/\n/; # Strip at the end of line. $lline =~ s/\r\n$/\n/; # Strip at the end of line. if ($gline ne $lline) { $diff = 1; last; } } # Check to see if the log file has extra lines. while (!eof LOG and !$diff) { $lline = ; $diff = 1 if ($lline !~ m/^(==|\*\*)\d+(==|\*\*)/); } close (LOG); close (GOLD); return $diff } iverilog-12_0/ivtest/vpi_regress.list000066400000000000000000000133351435245347300201170ustar00rootroot00000000000000#========== # This file controls how the individual VPI tests are run. The verilog # file must be named .v. The output log file is named # .log. The verilog and C/C++ files are located in the # "vpi" directory and the gold files are located in the "vpi_gold" # directory. The NI (Not Implemented) type is only available for # version specific tests. It is ignored by the default case! # # The basic steps for each test are: # iverilog-vpi --name # iverilog -o sim_file .v # vvp -M . -m sim_file # diff # remove temporary files. # # The following are the recognized fields: # #ver:test name type C/C++ file gold log file compiler options # # The compiler option field is optional and when present will contain # all subsequent fields. #========== #========== # For testing with other simulators #========== # Icarus returns vpiReg instead of vpiTimeVar. vstd:by_name normal by_name.c by_name-std.log # This test uses an Icarus language extension ($simparam). vstd:check_version NI check_version.c check_version.gold # Icarus generates spurious value change callback triggers at T=0. vstd:memwide normal memwide.cc memwide-std.log vstd:nulls1 normal nulls1.c nulls1-std.log # Icarus outputs warning messages. vstd:pr723 normal pr723.c pr723-std.log # This test uses an Icarus language extension (wire real). vstd:pr2966059 NI pr2966059.c pr2966059.gold # This test has a non-deterministic output order. The gold file needs # to be adjusted to match the simulator being used. vstd:scopes normal scopes.c scopes-std.log #========== # MSYS2 exceptions #========== # This still needs investigating. msys2:pr723 NI pr723.c pr723.log #========== # V10 exceptions #========== # V10 exceptions v10:br_gh117 NI br_gh117.c br_gh117.gold v10:br_ml20191013 NI br_ml20191013.c br_ml20191013.gold v10:by_index NI by_index.c by_index.gold v10:pr723 normal pr723.c pr723-v10.log v10:spec_delays normal,-gspecify spec_delays.c spec_delays.log -DIVERILOG_V10 #========== # V11 exceptions #========== #========== # The default case. #========== br_gh59 normal br_gh59.c br_gh59.gold br_gh73a normal force.c br_gh73a.gold br_gh73b normal force.c br_gh73b.gold br_gh117 normal br_gh117.c br_gh117.gold br_gh141 normal br_gh141.c br_gh141.gold br_gh169a normal br_gh169.c br_gh169a.gold br_gh169b normal,-g2009 br_gh169.c br_gh169b.gold br_gh184 normal start_of_simtime1.c br_gh184.gold br_gh235 normal,-g2009 br_gh235.c br_gh235.gold br_gh308 normal br_gh308.c br_gh308.gold br_gh317 normal br_gh317.c br_gh317.gold br_gh496 normal,-g2009 br_gh496.c br_gh496.gold br_ml20191013 normal br_ml20191013.c br_ml20191013.gold by_index normal by_index.c by_index.gold by_name normal by_name.c by_name.log callback1 normal callback1.c callback1.log celldefine normal celldefine.c celldefine.gold check_version normal check_version.c check_version.gold display_array normal,-g2009 display_array.c display_array.gold event1 normal event1.c event1.log event2 normal event2.c event2.log final normal,-g2009 final.c final.gold find_sig normal find_sig.c find_sig.gold force_reg normal force.c force_reg.gold force_reg_pv normal force.c force_reg_pv.gold force_reg_real normal force_real.c force_reg_real.gold force_wire normal force.c force_wire.gold force_wire_pv normal force.c force_wire_pv.gold force_wire_real normal force_real.c force_wire_real.gold genblk_named normal genblk_names.c genblk_named.gold genblk_unnamed normal genblk_names.c genblk_unnamed.gold genblk_direct normal,-g2009 genblk_names.c genblk_direct.gold getp normal getp.c getp.log hello_poke normal hello_poke.c hello_poke.log hello_tf normal hello_tf.c hello_tf.log hello_vpi normal hello_vpi.c hello.log hello_vpi2 normal hello_vpi2.c hello2.log vpi/hello_vpi1.c listparams normal listparams.c listparams.log memmon normal,-g1995 memmon.c memmon.log memwide normal memwide.cc memwide.log mipname normal mipname.c mipname.log myscope normal myscope.c myscope.gold myscope2 normal myscope2.c myscope2.gold nulls1 normal nulls1.c nulls1.log pokevent normal pokevent.cc pokevent.log pokereg normal pokereg.cc pokereg.log ports_params normal ports_params.c ports_params.gold pr521 normal pr521.c pr521.log pr686 normal pr686.c pr686.log pr723 normal pr723.c pr723.log pr1693971 normal pr1693971.c pr1693971.log pr2048463 normal pr2048463.c pr2048463.log pr2314742 normal pr2314742.c pr2314742.gold pr2966059 normal,-gno-xtypes pr2966059.c pr2966059.gold pr2971220 normal pr2971220.c pr2971220.gold putp normal putp.c putp.log putp2 normal putp2.c putp2.log putvalue normal putvalue.c putvalue.log range1 normal range1.c range1.gold realcb normal realcb.c realcb.log realtime normal realtime.c realtime.log realtime2 normal realtime2.c realtime2.log ro_synch normal ro_synch.c ro_synch.gold scanmem normal scanmem.cc scanmem.log scanmem2 normal scanmem2.cc scanmem2.log scanmem3 normal scanmem3.cc scanmem3.log scopes normal scopes.c scopes.log spec_delays normal,-gspecify spec_delays.c spec_delays.log start_of_simtime1 normal start_of_simtime1.c start_of_simtime1.log timescale normal timescale.c timescale.log # Add new tests in alphabetic/numeric order. If the test needs # a compile option or a different log file to run with an older # version or if it uses something not implemented (NI) by other # versions of the program it will also need a version specific # line above. iverilog-12_0/ivtest/vvp_reg.pl000077500000000000000000000212001435245347300166700ustar00rootroot00000000000000#!/usr/bin/env perl # # Script to handle regression for Icarus Verilog using the vvp target. # # This script is based on code with the following Copyright. # # Copyright (c) 1999-2021 Guy Hutchison (ghutchis@pacbell.net) # # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA use lib './perl-lib'; use RegressionList; use Diff; use Reporting; use Environment; # # Main script # &open_report_file; my ($suffix, $strict, $with_valg, $force_sv) = &get_args; my $ver = &get_ivl_version($suffix); my $opt = $strict ? ($force_sv ? " (strict, force SV)" : " (strict)") : ($force_sv ? " (force SV)" : ""); my $msg = $with_valg ? " (with valgrind)" : ""; &print_rpt("Running compiler/VVP tests for Icarus Verilog " . "version: $ver$opt$msg.\n"); &print_rpt("-" x 76 . "\n"); if ($#ARGV != -1) { my $regress_fn = &get_regress_fn; &read_regression_list($regress_fn, $ver, $force_sv, ""); } else { if ($ENV{MSYSTEM}) { &read_regression_list("regress-msys2.list", $ver, $force_sv, ""); } if ($force_sv) { &read_regression_list("regress-fsv.list", $ver, $force_sv, ""); } &read_regression_list("regress-v$ver.list", $ver, $force_sv, ""); if ($strict == 0) { &read_regression_list("regress-ivl2.list", $ver, $force_sv, ""); } &read_regression_list("regress-ivl1.list", $ver, $force_sv, ""); &read_regression_list("regress-vlg.list", $ver, $force_sv, ""); &read_regression_list("regress-vams.list", $ver, $force_sv, ""); if ($ver >= 10) { &read_regression_list("regress-sv.list", $ver, $force_sv, ""); &read_regression_list("regress-vhdl.list", $ver, $force_sv, ""); } if ($ver == 0.9 or $force_sv) { &read_regression_list("regress-synth.list", $ver, $force_sv, ""); } else { &read_regression_list("regress-synth.list", $ver, $force_sv, "-S"); } } $failed = &execute_regression($suffix, $strict, $with_valg); &close_report_file; exit $failed; # # execute_regression sequentially compiles and executes each test in # the regression. It then checks that the output matches the gold file. # sub execute_regression { my $sfx = shift(@_); my $strict = shift(@_); my $with_valg = shift(@_); my ($tname, $total, $passed, $failed, $expected_fail, $not_impl, $len, $cmd, $ivl_args, $vvp_args, $diff_file); $total = 0; $passed = 0; $failed = 0; $expected_fail = 0; $not_impl = 0; $len = 0; foreach $tname (@testlist) { $len = length($tname) if (length($tname) > $len); } # Make sure we have a log and work directory. if (! -d 'log') { mkdir 'log' or die "Error: unable to create log directory.\n"; } if (! -d 'work') { mkdir 'work' or die "Error: unable to create work directory.\n"; } if ($strict) { $ivl_args = "-gstrict-expr-width"; $vvp_args = "-compatible"; } else { $ivl_args = "-D__ICARUS_UNSIZED__"; $vvp_args = ""; } foreach $tname (@testlist) { my ($pass_type); next if ($tname eq ""); # Skip test that have been replaced. $total++; &print_rpt(sprintf("%${len}s: ", $tname)); if ($diff{$tname} ne "" and -e $diff{$tname}) { unlink $diff{$tname} or die "Error: unable to remove old diff file $diff{$tname}.\n"; } if (-e "log/$tname.log") { unlink "log/$tname.log" or die "Error: unable to remove old log file log/$tname.log.\n"; } if ($testtype{$tname} eq "NI") { &print_rpt("Not Implemented.\n"); $not_impl++; next; } if (! -e "./$srcpath{$tname}/$tname.v") { &print_rpt("Failed - missing source file.\n"); $failed++; next; } # # Build up the iverilog command line and run it. # $pass_type = 0; $cmd = $with_valg ? "valgrind --trace-children=yes " : ""; $cmd .= "iverilog$sfx -o vsim $ivl_args $args{$tname}"; $cmd .= " -s $testmod{$tname}" if ($testmod{$tname} ne ""); $cmd .= " -t null" if ($testtype{$tname} eq "CN"); $cmd .= " ./$srcpath{$tname}/$tname.v > log/$tname.log 2>&1"; # print "$cmd\n"; if (system("$cmd")) { if ($testtype{$tname} eq "CE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - CE (core dump).\n"); $failed++; next; } else { $pass_type = 1; } } else { &print_rpt("==> Failed - running iverilog.\n"); $failed++; next; } } else { if ($testtype{$tname} eq "CE") { &print_rpt("==> Failed - CE (no error reported).\n"); $failed++; next; } } if ($testtype{$tname} eq "CO") { &print_rpt("Passed - CO.\n"); $passed++; next; } if ($testtype{$tname} eq "CN") { &print_rpt("Passed - CN.\n"); $passed++; next; } $cmd = $with_valg ? "valgrind --leak-check=full " . "--show-reachable=yes " : ""; $cmd .= "vvp$sfx vsim $vvp_args $plargs{$tname} >> log/$tname.log 2>&1"; # print "$cmd\n"; if ($pass_type == 0 and system("$cmd")) { if ($testtype{$tname} eq "RE") { # Check if the system command core dumped! if ($? >> 8 & 128) { &print_rpt("==> Failed - RE (core dump).\n"); $failed++; next; } else { $pass_type = 2; } } else { &print_rpt("==> Failed - running vvp.\n"); $failed++; next; } } elsif ($testtype{$tname} eq "RE") { &print_rpt("==> Failed - RE (no error reported).\n"); $failed++; next; } if ($diff{$tname} ne "") { $diff_file = $diff{$tname} } elsif ($gold{$tname} ne "") { $diff_file = "log/$tname.log"; } else { if ($pass_type == 1) { &print_rpt("Passed - CE.\n"); $passed++; next; } elsif ($pass_type == 2) { &print_rpt("Passed - RE.\n"); $passed++; next; } $diff_file = "log/$tname.log"; } # print "diff $gold{$tname}, $diff_file, $offset{$tname}, $unordered{$tname}\n"; if (diff($gold{$tname}, $diff_file, $offset{$tname}, $unordered{$tname})) { if ($testtype{$tname} eq "EF") { &print_rpt("Passed - expected fail.\n"); $expected_fail++; next; } &print_rpt("==> Failed -"); if ($pass_type == 1) { &print_rpt(" CE -"); } elsif ($pass_type == 2) { &print_rpt(" RE -"); } &print_rpt(" output does not match gold file.\n"); $failed++; next; } if ($pass_type == 1) { &print_rpt("Passed - CE.\n"); } elsif ($pass_type == 2) { &print_rpt("Passed - RE.\n"); } else { &print_rpt("Passed.\n"); } $passed++; } continue { if ($tname ne "") { system("rm -f ./vsim && rm -rf ivl_vhdl_work") and die "Error: failed to remove temporary file.\n"; } } &print_rpt("=" x 76 . "\n"); &print_rpt("Test results:\n Total=$total, Passed=$passed, Failed=$failed,". " Not Implemented=$not_impl, Expected Fail=$expected_fail\n"); # Remove remaining temporary files system("rm -f *.tmp ivltests/*.tmp"); return($failed) } iverilog-12_0/lexor.lex000066400000000000000000001337621435245347300152260ustar00rootroot00000000000000%option prefix="VL" %option never-interactive %option nounput %{ /* * Copyright (c) 1998-2022 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" //# define YYSTYPE lexval # include # include # include "compiler.h" # include "parse_misc.h" # include "parse_api.h" # include "parse.h" # include # include # include "lexor_keyword.h" # include "discipline.h" # include using namespace std; # define YY_USER_INIT reset_lexor(); # define yylval VLlval # define YY_NO_INPUT /* * Lexical location information is passed in the yylloc variable to th * parser. The file names, strings, are kept in a list so that I can * re-use them. The set_file_name function will return a pointer to * the name as it exists in the list (and delete the passed string.) * If the name is new, it will be added to the list. */ extern YYLTYPE yylloc; char* yytext_string_filter(const char*str, size_t str_len) { if (str == 0) return 0; char*buf = new char[str_len+1]; size_t didx = 0; for (size_t sidx = 0 ; sidx < str_len ; sidx += 1, didx += 1) { if (str[sidx] == 0) { VLerror(yylloc, "error: Found nil (\\000) in string literal, replacing with space (\\015) character."); buf[didx] = ' '; } else if (str[sidx] == '\\') { /* Skip \\\n */ if ((sidx+1 < str_len) && (str[sidx+1] == '\n')) { sidx += 1; didx -= 1; } else { buf[didx] = str[sidx]; } } else { buf[didx] = str[sidx]; } } buf[didx] = 0; return buf; } char* strdupnew(char const *str) { return str ? strcpy(new char [strlen(str)+1], str) : 0; } static const char* set_file_name(char*text) { perm_string path = filename_strings.make(text); delete[]text; /* Check this file name with the list of library file names. If there is a match, then turn on the pform_library_flag. This is how the parser knows that modules declared in this file are library modules. */ pform_library_flag = library_file_map[path]; return path; } void reset_lexor(); static void line_directive(); static void line_directive2(); static void reset_all(); verinum*make_unsized_binary(const char*txt); verinum*make_undef_highz_dec(const char*txt); verinum*make_unsized_dec(const char*txt); verinum*make_unsized_octal(const char*txt); verinum*make_unsized_hex(const char*txt); static int dec_buf_div2(char *buf); static int get_timescale_scale(const char*cp); static int get_timescale_const(int scale, const char*units); static void process_ucdrive(const char*txt); static list keyword_mask_stack; static int comment_enter; static bool in_module = false; static bool in_UDP = false; bool in_celldefine = false; UCDriveType uc_drive = UCD_NONE; static int ts_state = 0; static int ts_scale = 0; static int ts_unit = 0; static int ts_prec = 0; /* * The parser sometimes needs to indicate to the lexor that the next * identifier needs to be understood in the context of a package. The * parser feeds back that left context with calls to the * lex_in_package_scope. */ static PPackage* in_package_scope = 0; void lex_in_package_scope(PPackage*pkg) { in_package_scope = pkg; } %} %x CCOMMENT %x PCOMMENT %x LCOMMENT %x CSTRING %s UDPTABLE %x PPTIMESCALE_SCALE %x PPTIMESCALE_UNITS %x PPTIMESCALE_SLASH %x PPTIMESCALE_ERROR %x PPUCDRIVE %x PPUCDRIVE_ERROR %x PPDEFAULT_NETTYPE %x PPDEFAULT_NETTYPE_ERROR %x PPBEGIN_KEYWORDS %x PPBEGIN_KEYWORDS_ERROR %s EDGES %x REAL_SCALE W [ \t\b\f\r]+ S [afpnumkKMGT] TU [munpf] %% /* Recognize the various line directives. */ ^"#line"[ \t]+.+ { line_directive(); } ^[ \t]?"`line"[ \t]+.+ { line_directive2(); } [ \t\b\f\r] { ; } \n { yylloc.first_line += 1; } /* C++ style comments start with / / and run to the end of the current line. These are very easy to handle. The meta-comments format is a little more tricky to handle, but do what we can. */ /* The lexor detects "// synthesis translate_on/off" meta-comments, we handle them here by turning on/off a flag. The pform uses that flag to attach implicit attributes to "initial" and "always" statements. */ "// Icarus preprocessor had ("[0-9]+") errors."\n { pre_process_failed(yytext); } "//"{W}*"synthesis"{W}+"translate_on"{W}*\n { pform_mc_translate_on(true); } "//"{W}*"synthesis"{W}+"translate_off"{W}*\n { pform_mc_translate_on(false); } "//" { comment_enter = YY_START; BEGIN(LCOMMENT); } . { yymore(); } \n { yylloc.first_line += 1; BEGIN(comment_enter); } /* The contents of C-style comments are ignored, like white space. */ "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); } . { ; } /* Check for a possible nested comment. */ "/*" { VLerror(yylloc, "error: Possible nested comment."); } \n { yylloc.first_line += 1; } "*/" { BEGIN(comment_enter); } "(*" { return K_PSTAR; } "*)" { return K_STARP; } ".*" { return K_DOTSTAR; } "<<" { return K_LS; } "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */} ">>" { return K_RS; } ">>>" { return K_RSS; } "**" { return K_POW; } "<=" { return K_LE; } ">=" { return K_GE; } "=>" { return K_EG; } "+=>"|"-=>" { /* * Resolve the ambiguity between the += assignment * operator and +=> polarity edge path operator * * +=> should be treated as two separate tokens '+' and * '=>' (K_EG), therefore we only consume the first * character of the matched pattern i.e. either + or - * and push back the rest of the matches text (=>) in * the input stream. */ yyless(1); return yytext[0]; } "*>" { return K_SG; } "==" { return K_EQ; } "!=" { return K_NE; } "===" { return K_CEQ; } "!==" { return K_CNE; } "==?" { return K_WEQ; } "!=?" { return K_WNE; } "||" { return K_LOR; } "&&" { return K_LAND; } "<->" { return K_LEQUIV; } "&&&" { return K_TAND; } "~|" { return K_NOR; } "~^" { return K_NXOR; } "^~" { return K_NXOR; } "~&" { return K_NAND; } "->" { return K_TRIGGER; } "->>" { return K_NB_TRIGGER; } "+:" { return K_PO_POS; } "-:" { return K_PO_NEG; } "<+" { return K_CONTRIBUTE; } "+=" { return K_PLUS_EQ; } "-=" { return K_MINUS_EQ; } "*=" { return K_MUL_EQ; } "/=" { return K_DIV_EQ; } "%=" { return K_MOD_EQ; } "&=" { return K_AND_EQ; } "|=" { return K_OR_EQ; } "^=" { return K_XOR_EQ; } "<<=" { return K_LS_EQ; } ">>=" { return K_RS_EQ; } "<<<=" { return K_LS_EQ; } ">>>=" { return K_RSS_EQ; } "++" { return K_INCR; } "--" {return K_DECR; } "'{" { return K_LP; } "::" { return K_SCOPE_RES; } /* This is horrible. The Verilog systax uses "->" in a lot of places. The trickiest is in constraints, where it is not an operator at all but a constraint implication. This only turns up as a problem when the "->" is followed by a constraint_expression_list. If that shows up, then there will be a "{" to the right of the "->". In that case, turn the "->" into a K_CONSTRAINT_IMPL so that the parser can be written without the shift/reduce conflict. Ugh! */ "->"/{W}*"{" { return gn_system_verilog()? K_CONSTRAINT_IMPL : K_TRIGGER; } /* Watch out for the tricky case of (*). Cannot parse this as "(*" and ")", but since I know that this is really ( * ), replace it with "*" and return that. */ "("{W}*"*"{W}*")" { return '*'; } "]" { BEGIN(0); return yytext[0]; } [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; } \" { BEGIN(CSTRING); } \\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ } \\\" { yymore(); /* Catch \", which is an escaped quote */ } \\\n { yymore(); /* Catch \\n, which will be filtered out */ yylloc.first_line += 1; } \n { BEGIN(0); yylval.text = yytext_string_filter(yytext, yyleng); VLerror(yylloc, "error: Missing closing quote for string."); yylloc.first_line += 1; return STRING; } \" { BEGIN(0); yylval.text = yytext_string_filter(yytext, yyleng); yylval.text[strlen(yylval.text)-1] = 0; return STRING; } . { yymore(); } /* The UDP Table is a unique lexical environment. These are most tokens that we can expect in a table. */ \(\?0\) { return '_'; } \(\?1\) { return '+'; } \(\?[xX]\) { return '%'; } \(\?\?\) { return '*'; } \(01\) { return 'r'; } \(0[xX]\) { return 'Q'; } \(b[xX]\) { return 'q'; } \(b0\) { return 'f'; /* b0 is 10|00, but only 10 is meaningful */} \(b1\) { return 'r'; /* b1 is 11|01, but only 01 is meaningful */} \(0\?\) { return 'P'; } \(10\) { return 'f'; } \(1[xX]\) { return 'M'; } \(1\?\) { return 'N'; } \([xX]0\) { return 'F'; } \([xX]1\) { return 'R'; } \([xX]\?\) { return 'B'; } [bB] { return 'b'; } [lL] { return 'l'; /* IVL extension */ } [hH] { return 'h'; /* IVL extension */ } [fF] { return 'f'; } [rR] { return 'r'; } [xX] { return 'x'; } [nN] { return 'n'; } [pP] { return 'p'; } [01\?\*\-:;] { return yytext[0]; } "01" { return K_edge_descriptor; } "0x" { return K_edge_descriptor; } "0z" { return K_edge_descriptor; } "10" { return K_edge_descriptor; } "1x" { return K_edge_descriptor; } "1z" { return K_edge_descriptor; } "x0" { return K_edge_descriptor; } "x1" { return K_edge_descriptor; } "z0" { return K_edge_descriptor; } "z1" { return K_edge_descriptor; } [a-zA-Z_][a-zA-Z0-9$_]* { int rc = lexor_keyword_code(yytext, yyleng); switch (rc) { case IDENTIFIER: yylval.text = strdupnew(yytext); if (strncmp(yylval.text,"PATHPULSE$", 10) == 0) rc = PATHPULSE_IDENTIFIER; break; case K_edge: BEGIN(EDGES); break; case K_module: case K_macromodule: in_module = true; break; case K_endmodule: in_module = false; break; case K_primitive: in_UDP = true; break; case K_endprimitive: in_UDP = false; break; case K_table: BEGIN(UDPTABLE); break; default: yylval.text = 0; break; } /* Special case: If this is part of a scoped name, then check the package for identifier details. For example, if the source file is foo::bar, the parse.y will note the PACKAGE_IDENTIFIER and "::" token and mark the "in_package_scope" variable. Then this lexor will see the identifier here and interpret it in the package scope. */ if (in_package_scope) { if (rc == IDENTIFIER) { if (typedef_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) { yylval.type_identifier.text = yylval.text; yylval.type_identifier.type = type; rc = TYPE_IDENTIFIER; } } in_package_scope = 0; return rc; } /* If this identifier names a discipline, then return this as a DISCIPLINE_IDENTIFIER and return the discipline as the value instead. */ if (rc == IDENTIFIER && gn_verilog_ams_flag) { perm_string tmp = lex_strings.make(yylval.text); map::iterator cur = disciplines.find(tmp); if (cur != disciplines.end()) { delete[]yylval.text; yylval.discipline = (*cur).second; rc = DISCIPLINE_IDENTIFIER; } } /* If this identifier names a previously declared package, then return this as a PACKAGE_IDENTIFIER instead. */ if (rc == IDENTIFIER && gn_system_verilog()) { if (PPackage*pkg = pform_test_package_identifier(yylval.text)) { delete[]yylval.text; yylval.package = pkg; rc = PACKAGE_IDENTIFIER; } } /* If this identifier names a previously declared type, then return this as a TYPE_IDENTIFIER instead. */ if (rc == IDENTIFIER && gn_system_verilog()) { if (typedef_t*type = pform_test_type_identifier(yylloc, yylval.text)) { yylval.type_identifier.text = yylval.text; yylval.type_identifier.type = type; rc = TYPE_IDENTIFIER; } } return rc; } \\[^ \t\b\f\r\n]+ { yylval.text = strdupnew(yytext+1); if (gn_system_verilog()) { if (PPackage*pkg = pform_test_package_identifier(yylval.text)) { delete[]yylval.text; yylval.package = pkg; return PACKAGE_IDENTIFIER; } } if (gn_system_verilog()) { if (typedef_t*type = pform_test_type_identifier(yylloc, yylval.text)) { yylval.type_identifier.text = yylval.text; yylval.type_identifier.type = type; return TYPE_IDENTIFIER; } } return IDENTIFIER; } \$([a-zA-Z0-9$_]+) { /* The 1364-1995 timing checks. */ if (strcmp(yytext,"$hold") == 0) return K_Shold; if (strcmp(yytext,"$nochange") == 0) return K_Snochange; if (strcmp(yytext,"$period") == 0) return K_Speriod; if (strcmp(yytext,"$recovery") == 0) return K_Srecovery; if (strcmp(yytext,"$setup") == 0) return K_Ssetup; if (strcmp(yytext,"$setuphold") == 0) return K_Ssetuphold; if (strcmp(yytext,"$skew") == 0) return K_Sskew; if (strcmp(yytext,"$width") == 0) return K_Swidth; /* The new 1364-2001 timing checks. */ if (strcmp(yytext,"$fullskew") == 0) return K_Sfullskew; if (strcmp(yytext,"$recrem") == 0) return K_Srecrem; if (strcmp(yytext,"$removal") == 0) return K_Sremoval; if (strcmp(yytext,"$timeskew") == 0) return K_Stimeskew; if (strcmp(yytext,"$attribute") == 0) return KK_attribute; if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) { yylval.package = pform_units.back(); return PACKAGE_IDENTIFIER; } yylval.text = strdupnew(yytext); return SYSTEM_IDENTIFIER; } \'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext); return BASED_NUMBER; } \'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext); return BASED_NUMBER; } \'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]* { yylval.number = make_unsized_binary(yytext); return BASED_NUMBER; } \'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]* { yylval.number = make_unsized_octal(yytext); return BASED_NUMBER; } \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]* { yylval.number = make_unsized_hex(yytext); return BASED_NUMBER; } \'[01xzXZ] { if (!gn_system_verilog()) { VLwarn(yylloc, "warning: Using SystemVerilog 'N bit vector. " "Use at least -g2005-sv to remove this warning."); } generation_t generation_save = generation_flag; generation_flag = GN_VER2005_SV; yylval.number = make_unsized_binary(yytext); generation_flag = generation_save; return UNBASED_NUMBER; } /* Decimal numbers are the usual. But watch out for the UDPTABLE mode, where there are no decimal numbers. Reject the match if we are in the UDPTABLE state. */ [0-9][0-9_]* { if (YY_START==UDPTABLE) { REJECT; } else { yylval.number = make_unsized_dec(yytext); based_size = yylval.number->as_ulong(); return DEC_NUMBER; } } /* This rule handles scaled time values for SystemVerilog. */ [0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s { if (gn_system_verilog()) { yylval.text = strdupnew(yytext); return TIME_LITERAL; } else REJECT; } /* These rules handle the scaled real literals from Verilog-AMS. The value is a number with a single letter scale factor. If verilog-ams is not enabled, then reject this rule. If it is enabled, then collect the scale and use it to scale the value. */ [0-9][0-9_]*\.[0-9][0-9_]*/{S} { if (!gn_verilog_ams_flag) REJECT; BEGIN(REAL_SCALE); yymore(); } [0-9][0-9_]*/{S} { if (!gn_verilog_ams_flag) REJECT; BEGIN(REAL_SCALE); yymore(); } {S} { size_t token_len = strlen(yytext); char*tmp = new char[token_len + 5]; int scale = 0; strcpy(tmp, yytext); switch (tmp[token_len-1]) { case 'a': scale = -18; break; /* atto- */ case 'f': scale = -15; break; /* femto- */ case 'p': scale = -12; break; /* pico- */ case 'n': scale = -9; break; /* nano- */ case 'u': scale = -6; break; /* micro- */ case 'm': scale = -3; break; /* milli- */ case 'k': scale = 3; break; /* kilo- */ case 'K': scale = 3; break; /* kilo- */ case 'M': scale = 6; break; /* mega- */ case 'G': scale = 9; break; /* giga- */ case 'T': scale = 12; break; /* tera- */ default: assert(0); break; } snprintf(tmp+token_len-1, 5, "e%d", scale); yylval.realtime = new verireal(tmp); delete[]tmp; BEGIN(0); return REALTIME; } [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? { yylval.realtime = new verireal(yytext); return REALTIME; } [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* { yylval.realtime = new verireal(yytext); return REALTIME; } /* Notice and handle the `timescale directive. */ `timescale { ts_state = 0; BEGIN(PPTIMESCALE_SCALE); } 10?0? { ts_scale = get_timescale_scale(yytext); BEGIN(PPTIMESCALE_UNITS); } "//" { comment_enter = PPTIMESCALE_SCALE; BEGIN(LCOMMENT); } "/*" { comment_enter = PPTIMESCALE_SCALE; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPTIMESCALE_ERROR); } [munpf]?s { if (++ts_state == 1) { ts_unit = get_timescale_const(ts_scale, yytext); BEGIN(PPTIMESCALE_SLASH); } else { ts_prec = get_timescale_const(ts_scale, yytext); if (in_module) { VLerror(yylloc, "error: timescale directive cannot be inside " "a module definition."); } if (ts_unit < ts_prec) { VLerror(yylloc, "error: timescale unit must not be less than " "the precision."); } else { pform_set_timescale(ts_unit, ts_prec, yylloc.text, yylloc.first_line); } BEGIN(0); } } "//" { comment_enter = PPTIMESCALE_UNITS; BEGIN(LCOMMENT); } "/*" { comment_enter = PPTIMESCALE_UNITS; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPTIMESCALE_ERROR); } "/" { BEGIN(PPTIMESCALE_SCALE); } "//" { comment_enter = PPTIMESCALE_SLASH; BEGIN(LCOMMENT); } "/*" { comment_enter = PPTIMESCALE_SLASH; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPTIMESCALE_ERROR); } /* On error, try to recover by skipping to the end of the line. */ [^\n]+ { VLerror(yylloc, "error: Invalid `timescale directive."); BEGIN(0); } /* Notice and handle the `celldefine and `endcelldefine directives. */ `celldefine { in_celldefine = true; } `endcelldefine { in_celldefine = false; } /* Notice and handle the `resetall directive. */ `resetall { if (in_module) { VLerror(yylloc, "error: `resetall directive cannot be inside a " "module definition."); } else if (in_UDP) { VLerror(yylloc, "error: `resetall directive cannot be inside a " "UDP definition."); } else { reset_all(); } } /* Notice and handle the `unconnected_drive directive. */ `unconnected_drive { BEGIN(PPUCDRIVE); } [a-zA-Z0-9_]+ { process_ucdrive(yytext); if (in_module) { VLerror(yylloc, "error: `unconnected_drive directive cannot be " "inside a module definition."); } BEGIN(0); } "//" { comment_enter = PPUCDRIVE; BEGIN(LCOMMENT); } "/*" { comment_enter = PPUCDRIVE; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPUCDRIVE_ERROR); } /* On error, try to recover by skipping to the end of the line. */ [^\n]+ { VLerror(yylloc, "error: Invalid `unconnected_drive directive."); BEGIN(0); } /* Notice and handle the `nounconnected_drive directive. */ `nounconnected_drive { if (in_module) { VLerror(yylloc, "error: `nounconnected_drive directive cannot be " "inside a module definition."); } uc_drive = UCD_NONE; } /* These are directives that I do not yet support. I think that IVL should handle these, not an external preprocessor. */ /* From 1364-2005 Chapter 19. */ ^{W}?`pragma{W}?.* { } /* From 1364-2005 Annex D. */ ^{W}?`default_decay_time{W}?.* { } ^{W}?`default_trireg_strength{W}?.* { } ^{W}?`delay_mode_distributed{W}?.* { } ^{W}?`delay_mode_path{W}?.* { } ^{W}?`delay_mode_unit{W}?.* { } ^{W}?`delay_mode_zero{W}?.* { } /* From other places. */ ^{W}?`disable_portfaults{W}?.* { } ^{W}?`enable_portfaults{W}?.* { } `endprotect { } ^{W}?`nosuppress_faults{W}?.* { } `protect { } ^{W}?`suppress_faults{W}?.* { } ^{W}?`uselib{W}?.* { } /* Notice and handle the `begin_keywords directive. */ `begin_keywords { BEGIN(PPBEGIN_KEYWORDS); } \"[a-zA-Z0-9 -\.]*\" { keyword_mask_stack.push_front(lexor_keyword_mask); char*word = yytext+1; char*tail = strchr(word, '"'); tail[0] = 0; if (strcmp(word,"1364-1995") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995; } else if (strcmp(word,"1364-2001") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG; } else if (strcmp(word,"1364-2001-noconfig") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001; } else if (strcmp(word,"1364-2005") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG |GN_KEYWORDS_1364_2005; } else if (strcmp(word,"1800-2005") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG |GN_KEYWORDS_1364_2005 |GN_KEYWORDS_1800_2005; } else if (strcmp(word,"1800-2009") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG |GN_KEYWORDS_1364_2005 |GN_KEYWORDS_1800_2005 |GN_KEYWORDS_1800_2009; } else if (strcmp(word,"1800-2012") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG |GN_KEYWORDS_1364_2005 |GN_KEYWORDS_1800_2005 |GN_KEYWORDS_1800_2009 |GN_KEYWORDS_1800_2012; } else if (strcmp(word,"VAMS-2.3") == 0) { lexor_keyword_mask = GN_KEYWORDS_1364_1995 |GN_KEYWORDS_1364_2001 |GN_KEYWORDS_1364_2001_CONFIG |GN_KEYWORDS_1364_2005 |GN_KEYWORDS_VAMS_2_3; } else { fprintf(stderr, "%s:%d: Ignoring unknown keywords string: %s\n", yylloc.text, yylloc.first_line, word); } BEGIN(0); } "//" { comment_enter = PPBEGIN_KEYWORDS; BEGIN(LCOMMENT); } "/*" { comment_enter = PPBEGIN_KEYWORDS; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPBEGIN_KEYWORDS_ERROR); } /* On error, try to recover by skipping to the end of the line. */ [^\n]+ { VLerror(yylloc, "error: Invalid `begin_keywords directive."); BEGIN(0); } /* Notice and handle the `end_keywords directive. */ `end_keywords { if (!keyword_mask_stack.empty()) { lexor_keyword_mask = keyword_mask_stack.front(); keyword_mask_stack.pop_front(); } else { VLwarn(yylloc, "warning: Mismatched `end_keywords directive"); } } /* Notice and handle the `default_nettype directive. */ `default_nettype { BEGIN(PPDEFAULT_NETTYPE); } [a-zA-Z0-9_]+ { NetNet::Type net_type; /* Add support for other wire types and better error detection. */ if (strcmp(yytext,"wire") == 0) { net_type = NetNet::WIRE; } else if (strcmp(yytext,"tri") == 0) { net_type = NetNet::TRI; } else if (strcmp(yytext,"tri0") == 0) { net_type = NetNet::TRI0; } else if (strcmp(yytext,"tri1") == 0) { net_type = NetNet::TRI1; } else if (strcmp(yytext,"wand") == 0) { net_type = NetNet::WAND; } else if (strcmp(yytext,"triand") == 0) { net_type = NetNet::TRIAND; } else if (strcmp(yytext,"wor") == 0) { net_type = NetNet::WOR; } else if (strcmp(yytext,"trior") == 0) { net_type = NetNet::TRIOR; } else if (strcmp(yytext,"none") == 0) { net_type = NetNet::NONE; } else { VLerror(yylloc, "error: Net type '%s' is not a valid (or supported) " "default net type.", yytext); net_type = NetNet::WIRE; error_count += 1; } pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line); BEGIN(0); } "//" { comment_enter = PPDEFAULT_NETTYPE; BEGIN(LCOMMENT); } "/*" { comment_enter = PPDEFAULT_NETTYPE; BEGIN(CCOMMENT); } "\n" { yylloc.first_line += 1; } {W} { ; } . { BEGIN(PPDEFAULT_NETTYPE_ERROR); } /* On error, try to recover by skipping to the end of the line. */ [^\n]+ { VLerror(yylloc, "error: Invalid `default_nettype directive."); BEGIN(0); } /* These are directives that are not supported by me and should have been handled by an external preprocessor such as ivlpp. */ ^{W}?`define{W}?.* { VLwarn(yylloc, "warning: `define not supported. Use an external preprocessor."); } ^{W}?`else{W}?.* { VLwarn(yylloc, "warning: `else not supported. Use an external preprocessor."); } ^{W}?`elsif{W}?.* { VLwarn(yylloc, "warning: `elsif not supported. Use an external preprocessor."); } ^{W}?`endif{W}?.* { VLwarn(yylloc, "warning: `endif not supported. Use an external preprocessor."); } ^{W}?`ifdef{W}?.* { VLwarn(yylloc, "warning: `ifdef not supported. Use an external preprocessor."); } ^{W}?`ifndef{W}?.* { VLwarn(yylloc, "warning: `ifndef not supported. Use an external preprocessor."); } ^`include{W}?.* { VLwarn(yylloc, "warning: `include not supported. Use an external preprocessor."); } ^`undef{W}?.* { VLwarn(yylloc, "warning: `undef not supported. Use an external preprocessor."); } `[a-zA-Z_]+ { VLwarn(yylloc, "warning: Macro replacement not supported. " "Use an external preprocessor."); } `{W} { VLerror(yylloc, "error: Stray tic (`) here. Perhaps you put white " "space between the tic and preprocessor directive?"); } . { return yytext[0]; } /* Final catchall. something got lost or mishandled. */ /* XXX Should we tell the user something about the lexical state? */ <*>.|\n { if (isprint(yytext[0])) VLerror(yylloc, "error: Unmatched character (%c).", yytext[0]); else VLerror(yylloc, "error: Unmatched character (0x%x).", (unsigned char) yytext[0]); } %% /* * The UDP state table needs some slightly different treatment by the * lexor. The level characters are normally accepted as other things, * so the parser needs to switch my mode when it believes in needs to. */ void lex_end_table() { BEGIN(INITIAL); } static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size) { if (size <= integer_width) return size; verinum::V pad = bits[size-1]; if (pad == verinum::V1) pad = verinum::V0; for (unsigned idx = integer_width; idx < size; idx += 1) { if (bits[idx] != pad) { VLwarn(yylloc, "warning: Unsized numeric constant truncated " "to integer width."); break; } } return integer_width; } verinum*make_unsized_binary(const char*txt) { bool sign_flag = false; bool single_flag = false; const char*ptr = txt; assert(*ptr == '\''); ptr += 1; if (tolower(*ptr) == 's') { sign_flag = true; ptr += 1; } assert((tolower(*ptr) == 'b') || gn_system_verilog()); if (tolower(*ptr) == 'b') { ptr += 1; } else { assert(sign_flag == false); single_flag = true; } while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; unsigned size = 0; for (const char*idx = ptr ; *idx ; idx += 1) if (*idx != '_') size += 1; if (size == 0) { VLerror(yylloc, "error: Numeric literal has no digits in it."); verinum*out = new verinum(); out->has_sign(sign_flag); out->is_single(single_flag); return out; } if ((based_size > 0) && (size > based_size)) VLwarn(yylloc, "warning: Extra digits given for sized binary constant."); verinum::V*bits = new verinum::V[size]; unsigned idx = size; while (*ptr) { switch (ptr[0]) { case '0': bits[--idx] = verinum::V0; break; case '1': bits[--idx] = verinum::V1; break; case 'z': case 'Z': case '?': bits[--idx] = verinum::Vz; break; case 'x': case 'X': bits[--idx] = verinum::Vx; break; case '_': break; default: fprintf(stderr, "%c\n", ptr[0]); assert(0); } ptr += 1; } if (gn_strict_expr_width_flag && (based_size == 0)) size = truncate_to_integer_width(bits, size); verinum*out = new verinum(bits, size, false); out->has_sign(sign_flag); out->is_single(single_flag); delete[]bits; return out; } verinum*make_unsized_octal(const char*txt) { bool sign_flag = false; const char*ptr = txt; assert(*ptr == '\''); ptr += 1; if (tolower(*ptr) == 's') { sign_flag = true; ptr += 1; } assert(tolower(*ptr) == 'o'); ptr += 1; while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; unsigned size = 0; for (const char*idx = ptr ; *idx ; idx += 1) if (*idx != '_') size += 3; if (based_size > 0) { int rem = based_size % 3; if (rem != 0) based_size += 3 - rem; if (size > based_size) VLwarn(yylloc, "warning: Extra digits given for sized octal constant."); } verinum::V*bits = new verinum::V[size]; unsigned idx = size; while (*ptr) { unsigned val; switch (ptr[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val = *ptr - '0'; bits[--idx] = (val&4) ? verinum::V1 : verinum::V0; bits[--idx] = (val&2) ? verinum::V1 : verinum::V0; bits[--idx] = (val&1) ? verinum::V1 : verinum::V0; break; case 'x': case 'X': bits[--idx] = verinum::Vx; bits[--idx] = verinum::Vx; bits[--idx] = verinum::Vx; break; case 'z': case 'Z': case '?': bits[--idx] = verinum::Vz; bits[--idx] = verinum::Vz; bits[--idx] = verinum::Vz; break; case '_': break; default: assert(0); } ptr += 1; } if (gn_strict_expr_width_flag && (based_size == 0)) size = truncate_to_integer_width(bits, size); verinum*out = new verinum(bits, size, false); out->has_sign(sign_flag); delete[]bits; return out; } verinum*make_unsized_hex(const char*txt) { bool sign_flag = false; const char*ptr = txt; assert(*ptr == '\''); ptr += 1; if (tolower(*ptr) == 's') { sign_flag = true; ptr += 1; } assert(tolower(*ptr) == 'h'); ptr += 1; while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; unsigned size = 0; for (const char*idx = ptr ; *idx ; idx += 1) if (*idx != '_') size += 4; if (based_size > 0) { int rem = based_size % 4; if (rem != 0) based_size += 4 - rem; if (size > based_size) VLwarn(yylloc, "warning: Extra digits given for sized hex constant."); } verinum::V*bits = new verinum::V[size]; unsigned idx = size; while (*ptr) { unsigned val; switch (ptr[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val = *ptr - '0'; bits[--idx] = (val&8) ? verinum::V1 : verinum::V0; bits[--idx] = (val&4) ? verinum::V1 : verinum::V0; bits[--idx] = (val&2) ? verinum::V1 : verinum::V0; bits[--idx] = (val&1) ? verinum::V1 : verinum::V0; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': val = tolower(*ptr) - 'a' + 10; bits[--idx] = (val&8) ? verinum::V1 : verinum::V0; bits[--idx] = (val&4) ? verinum::V1 : verinum::V0; bits[--idx] = (val&2) ? verinum::V1 : verinum::V0; bits[--idx] = (val&1) ? verinum::V1 : verinum::V0; break; case 'x': case 'X': bits[--idx] = verinum::Vx; bits[--idx] = verinum::Vx; bits[--idx] = verinum::Vx; bits[--idx] = verinum::Vx; break; case 'z': case 'Z': case '?': bits[--idx] = verinum::Vz; bits[--idx] = verinum::Vz; bits[--idx] = verinum::Vz; bits[--idx] = verinum::Vz; break; case '_': break; default: assert(0); } ptr += 1; } if (gn_strict_expr_width_flag && (based_size == 0)) size = truncate_to_integer_width(bits, size); verinum*out = new verinum(bits, size, false); out->has_sign(sign_flag); delete[]bits; return out; } /* Divide the integer given by the string by 2. Return the remainder bit. */ static int dec_buf_div2(char *buf) { int partial; int len = strlen(buf); char *dst_ptr; int pos; partial = 0; pos = 0; /* dst_ptr overwrites buf, but all characters that are overwritten were already used by the reader. */ dst_ptr = buf; while(buf[pos] == '0') ++pos; for(; pos= 2){ *dst_ptr = partial/2 + '0'; partial = partial & 1; ++dst_ptr; } else{ *dst_ptr = '0'; ++dst_ptr; } } // If result of division was zero string, it should remain that way. // Don't eat the last zero... if (dst_ptr == buf){ *dst_ptr = '0'; ++dst_ptr; } *dst_ptr = 0; return partial; } /* Support a single x, z or ? as a decimal constant (from 1364-2005). */ verinum* make_undef_highz_dec(const char* ptr) { bool signed_flag = false; assert(*ptr == '\''); /* The number may have decorations of the form 'sd, possibly with space between the d and the . Also, the 's' is optional, and marks the number as signed. */ ptr += 1; if (tolower(*ptr) == 's') { signed_flag = true; ptr += 1; } assert(tolower(*ptr) == 'd'); ptr += 1; while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; /* Process the code. */ verinum::V* bits = new verinum::V[1]; switch (*ptr) { case 'x': case 'X': bits[0] = verinum::Vx; break; case 'z': case 'Z': case '?': bits[0] = verinum::Vz; break; default: assert(0); } ptr += 1; while (*ptr == '_') ptr += 1; assert(*ptr == 0); verinum*out = new verinum(bits, 1, false); out->has_sign(signed_flag); delete[]bits; return out; } /* * Making a decimal number is much easier than the other base numbers * because there are no z or x values to worry about. It is much * harder than other base numbers because the width needed in bits is * hard to calculate. */ verinum*make_unsized_dec(const char*ptr) { char buf[4096]; bool signed_flag = false; unsigned idx; if (ptr[0] == '\'') { /* The number has decorations of the form 'sd, possibly with space between the d and the . Also, the 's' is optional, and marks the number as signed. */ ptr += 1; if (tolower(*ptr) == 's') { signed_flag = true; ptr += 1; } assert(tolower(*ptr) == 'd'); ptr += 1; while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr += 1; } else { /* ... or an undecorated decimal number is passed it. These numbers are treated as signed decimal. */ assert(isdigit(*ptr)); signed_flag = true; } /* Copy the digits into a buffer that I can use to do in-place decimal divides. */ idx = 0; while ((idx < sizeof buf) && (*ptr != 0)) { if (*ptr == '_') { ptr += 1; continue; } buf[idx++] = *ptr++; } if (idx == sizeof buf) { fprintf(stderr, "Ridiculously long" " decimal constant will be truncated!\n"); idx -= 1; } buf[idx] = 0; unsigned tmp_size = idx * 4 + 1; verinum::V *bits = new verinum::V[tmp_size]; idx = 0; while (idx < tmp_size) { int rem = dec_buf_div2(buf); bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0; } assert(strcmp(buf, "0") == 0); /* Now calculate the minimum number of bits needed to represent this unsigned number. */ unsigned size = tmp_size; while ((size > 1) && (bits[size-1] == verinum::V0)) size -= 1; /* Now account for the signedness. Don't leave a 1 in the high bit if this is a signed number. */ if (signed_flag && (bits[size-1] == verinum::V1)) { size += 1; assert(size <= tmp_size); } /* Since we never have the real number of bits that a decimal number represents we do not check for extra bits. */ // if (based_size > 0) { } if (gn_strict_expr_width_flag && (based_size == 0)) size = truncate_to_integer_width(bits, size); verinum*res = new verinum(bits, size, false); res->has_sign(signed_flag); delete[]bits; return res; } /* * Convert a string to a scale value ("1" -> 0, "10" -> 1, "100" -> 2). * We have already checked the string is valid. */ static int get_timescale_scale(const char *cp) { /* Skip the 1 digit. */ assert(*cp == '1'); cp += 1; /* Check the number of zeros after the 1. */ int scale = strspn(cp, "0"); assert(scale < 3); cp += scale; assert(*cp == '\0'); return scale; } /* * Convert a scale and a units string to a time unit or precision. * We have already checked the string is valid. */ static int get_timescale_const(int scale, const char *units) { if (strncmp("s", units, 1) == 0) { return scale; } else if (strncmp("ms", units, 2) == 0) { return scale - 3; } else if (strncmp("us", units, 2) == 0) { return scale - 6; } else if (strncmp("ns", units, 2) == 0) { return scale - 9; } else if (strncmp("ps", units, 2) == 0) { return scale - 12; } else if (strncmp("fs", units, 2) == 0) { return scale - 15; } assert(0); return 0; } /* * Process either a pull0 or a pull1. */ static void process_ucdrive(const char*txt) { UCDriveType ucd = UCD_NONE; const char*cp = txt; if (strncmp("pull", cp, 4) != 0) { VLerror(yylloc, "error: pull required for `unconnected_drive " "directive."); return; } cp += 4; if (*cp == '0') ucd = UCD_PULL0; else if (*cp == '1') ucd = UCD_PULL1; else { VLerror(yylloc, "error: `unconnected_drive does not support " "'pull%c'.", *cp); return; } cp += 1; if (*cp != '\0') { VLerror(yylloc, "error: Invalid `unconnected_drive directive " "(extra garbage after pull direction)."); return; } uc_drive = ucd; } int yywrap() { return 1; } /* * The line directive matches lines of the form #line "foo" N and * calls this function. Here I parse out the file name and line * number, and change the yylloc to suite. */ static void line_directive() { char *cpr; /* Skip any leading space. */ char *cp = strchr(yytext, '#'); /* Skip the #line directive. */ assert(strncmp(cp, "#line", 5) == 0); cp += 5; /* Skip the space after the #line directive. */ cp += strspn(cp, " \t"); /* Find the starting " and skip it. */ char*fn_start = strchr(cp, '"'); if (cp != fn_start) { VLerror(yylloc, "error: Invalid #line directive (file name start)."); return; } fn_start += 1; /* Find the last ". */ char*fn_end = strrchr(fn_start, '"'); if (!fn_end) { VLerror(yylloc, "error: Invalid #line directive (file name end)."); return; } /* Copy the file name and assign it to yylloc. */ char*buf = new char[fn_end-fn_start+1]; strncpy(buf, fn_start, fn_end-fn_start); buf[fn_end-fn_start] = 0; /* Skip the space after the file name. */ cp = fn_end; cp += 1; cpr = cp; cpr += strspn(cp, " \t"); if (cp == cpr) { VLerror(yylloc, "error: Invalid #line directive (missing space " "after file name)."); delete[] buf; return; } cp = cpr; /* Get the line number and verify that it is correct. */ unsigned long lineno = strtoul(cp, &cpr, 10); if (cp == cpr) { VLerror(yylloc, "error: Invalid line number for #line directive."); delete[] buf; return; } cp = cpr; /* Verify that only space is left. */ cpr += strspn(cp, " \t"); if ((size_t)(cpr-yytext) != strlen(yytext)) { VLerror(yylloc, "error: Invalid #line directive (extra garbage " "after line number)."); delete[] buf; return; } /* Now we can assign the new values to yyloc. */ yylloc.text = set_file_name(buf); yylloc.first_line = lineno; } /* * The line directive matches lines of the form `line N "foo" M and * calls this function. Here I parse out the file name and line * number, and change the yylloc to suite. M is ignored. */ static void line_directive2() { char *cpr; /* Skip any leading space. */ char *cp = strchr(yytext, '`'); /* Skip the `line directive. */ assert(strncmp(cp, "`line", 5) == 0); cp += 5; /* strtoul skips leading space. */ unsigned long lineno = strtoul(cp, &cpr, 10); if (cp == cpr) { VLerror(yylloc, "error: Invalid line number for `line directive."); return; } lineno -= 1; cp = cpr; /* Skip the space between the line number and the file name. */ cpr += strspn(cp, " \t"); if (cp == cpr) { VLerror(yylloc, "error: Invalid `line directive (missing space " "after line number)."); return; } cp = cpr; /* Find the starting " and skip it. */ char*fn_start = strchr(cp, '"'); if (cp != fn_start) { VLerror(yylloc, "error: Invalid `line directive (file name start)."); return; } fn_start += 1; /* Find the last ". */ char*fn_end = strrchr(fn_start, '"'); if (!fn_end) { VLerror(yylloc, "error: Invalid `line directive (file name end)."); return; } /* Skip the space after the file name. */ cp = fn_end + 1; cpr = cp; cpr += strspn(cp, " \t"); if (cp == cpr) { VLerror(yylloc, "error: Invalid `line directive (missing space " "after file name)."); return; } cp = cpr; /* Check that the level is correct, we do not need the level. */ if (strspn(cp, "012") != 1) { VLerror(yylloc, "error: Invalid level for `line directive."); return; } cp += 1; /* Verify that only space and/or a single line comment is left. */ cp += strspn(cp, " \t"); if (strncmp(cp, "//", 2) != 0 && (size_t)(cp-yytext) != strlen(yytext)) { VLerror(yylloc, "error: Invalid `line directive (extra garbage " "after level)."); return; } /* Copy the file name and assign it and the line number to yylloc. */ char*buf = new char[fn_end-fn_start+1]; strncpy(buf, fn_start, fn_end-fn_start); buf[fn_end-fn_start] = 0; yylloc.text = set_file_name(buf); yylloc.first_line = lineno; } /* * Reset all compiler directives. This will be called when a `resetall * directive is encountered or when a new compilation unit is started. */ static void reset_all() { pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line); in_celldefine = false; uc_drive = UCD_NONE; pform_set_timescale(def_ts_units, def_ts_prec, 0, 0); } extern FILE*vl_input; void reset_lexor() { yyrestart(vl_input); yylloc.first_line = 1; /* Announce the first file name. */ yylloc.text = set_file_name(strdupnew(vl_file.c_str())); if (separate_compilation) { reset_all(); if (!keyword_mask_stack.empty()) { lexor_keyword_mask = keyword_mask_stack.back(); keyword_mask_stack.clear(); } } } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_lexor() { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } iverilog-12_0/lexor_keyword.gperf000066400000000000000000000371131435245347300172760ustar00rootroot00000000000000/* * We need this to prevent -Wextra (-W) from complaining that the mask and * tokenType values are not initialized for the empty table entries. */ %define initializer-suffix ,0,0 %language=C++ %define class-name Lkwd %{ /* Command-line: gperf -o -i 7 -C -k '1-4,6,9,$' -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf */ #include #include "config.h" #include "parse_misc.h" #include "parse.h" #include #include "lexor_keyword.h" #include "compiler.h" %} struct lexor_keyword { const char*name; int mask; int tokenType; }; %% above, GN_KEYWORDS_VAMS_2_3, K_above abs, GN_KEYWORDS_VAMS_2_3, K_abs absdelay, GN_KEYWORDS_VAMS_2_3, K_absdelay abstol, GN_KEYWORDS_VAMS_2_3, K_abstol accept_on, GN_KEYWORDS_1800_2009, K_accept_on access, GN_KEYWORDS_VAMS_2_3, K_access acos, GN_KEYWORDS_VAMS_2_3, K_acos acosh, GN_KEYWORDS_VAMS_2_3, K_acosh ac_stim, GN_KEYWORDS_VAMS_2_3, K_ac_stim alias, GN_KEYWORDS_1800_2005, K_alias aliasparam, GN_KEYWORDS_VAMS_2_3, K_aliasparam always, GN_KEYWORDS_1364_1995, K_always always_comb, GN_KEYWORDS_1800_2005, K_always_comb always_ff, GN_KEYWORDS_1800_2005, K_always_ff always_latch, GN_KEYWORDS_1800_2005, K_always_latch analog, GN_KEYWORDS_VAMS_2_3, K_analog analysis, GN_KEYWORDS_VAMS_2_3, K_analysis and, GN_KEYWORDS_1364_1995, K_and asin, GN_KEYWORDS_VAMS_2_3, K_asin asinh, GN_KEYWORDS_VAMS_2_3, K_asinh # This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3 assert, GN_KEYWORDS_1800_2005|GN_KEYWORDS_VAMS_2_3, K_assert assign, GN_KEYWORDS_1364_1995, K_assign assume, GN_KEYWORDS_1800_2005, K_assume atan, GN_KEYWORDS_VAMS_2_3, K_atan atan2, GN_KEYWORDS_VAMS_2_3, K_atan2 atanh, GN_KEYWORDS_VAMS_2_3, K_atanh automatic, GN_KEYWORDS_1364_2001, K_automatic before, GN_KEYWORDS_1800_2005, K_before begin, GN_KEYWORDS_1364_1995, K_begin bind, GN_KEYWORDS_1800_2005, K_bind bins, GN_KEYWORDS_1800_2005, K_bins binsof, GN_KEYWORDS_1800_2005, K_binsof bit, GN_KEYWORDS_1800_2005, K_bit branch, GN_KEYWORDS_VAMS_2_3, K_branch break, GN_KEYWORDS_1800_2005, K_break bool, GN_KEYWORDS_ICARUS, K_bool buf, GN_KEYWORDS_1364_1995, K_buf bufif0, GN_KEYWORDS_1364_1995, K_bufif0 bufif1, GN_KEYWORDS_1364_1995, K_bufif1 byte, GN_KEYWORDS_1800_2005, K_byte case, GN_KEYWORDS_1364_1995, K_case casex, GN_KEYWORDS_1364_1995, K_casex casez, GN_KEYWORDS_1364_1995, K_casez ceil, GN_KEYWORDS_VAMS_2_3, K_ceil cell, GN_KEYWORDS_1364_2001_CONFIG, K_cell chandle, GN_KEYWORDS_1800_2005, K_chandle checker, GN_KEYWORDS_1800_2009, K_checker class, GN_KEYWORDS_1800_2005, K_class clocking, GN_KEYWORDS_1800_2005, K_clocking cmos, GN_KEYWORDS_1364_1995, K_cmos config, GN_KEYWORDS_1364_2001_CONFIG, K_config connect, GN_KEYWORDS_VAMS_2_3, K_connect connectmodule, GN_KEYWORDS_VAMS_2_3, K_connectmodule connectrules, GN_KEYWORDS_VAMS_2_3, K_connectrules const, GN_KEYWORDS_1800_2005, K_const constraint, GN_KEYWORDS_1800_2005, K_constraint context, GN_KEYWORDS_1800_2005, K_context continue, GN_KEYWORDS_1800_2005, K_continue continuous, GN_KEYWORDS_VAMS_2_3, K_continuous cos, GN_KEYWORDS_VAMS_2_3, K_cos cosh, GN_KEYWORDS_VAMS_2_3, K_cosh cover, GN_KEYWORDS_1800_2005, K_cover covergroup, GN_KEYWORDS_1800_2005, K_covergroup coverpoint, GN_KEYWORDS_1800_2005, K_coverpoint cross, GN_KEYWORDS_1800_2005, K_cross ddt, GN_KEYWORDS_VAMS_2_3, K_ddt ddt_nature, GN_KEYWORDS_VAMS_2_3, K_ddt_nature ddx, GN_KEYWORDS_VAMS_2_3, K_ddx deassign, GN_KEYWORDS_1364_1995, K_deassign default, GN_KEYWORDS_1364_1995, K_default defparam, GN_KEYWORDS_1364_1995, K_defparam design, GN_KEYWORDS_1364_2001_CONFIG, K_design disable, GN_KEYWORDS_1364_1995, K_disable discipline, GN_KEYWORDS_VAMS_2_3, K_discipline discrete, GN_KEYWORDS_VAMS_2_3, K_discrete dist, GN_KEYWORDS_1800_2005, K_dist do, GN_KEYWORDS_1800_2005, K_do domain, GN_KEYWORDS_VAMS_2_3, K_domain driver_update, GN_KEYWORDS_VAMS_2_3, K_driver_update edge, GN_KEYWORDS_1364_1995, K_edge else, GN_KEYWORDS_1364_1995, K_else end, GN_KEYWORDS_1364_1995, K_end endcase, GN_KEYWORDS_1364_1995, K_endcase endchecker, GN_KEYWORDS_1800_2009, K_endchecker endconfig, GN_KEYWORDS_1364_2001_CONFIG, K_endconfig endclass, GN_KEYWORDS_1800_2005, K_endclass endclocking, GN_KEYWORDS_1800_2005, K_endclocking endconnectrules, GN_KEYWORDS_VAMS_2_3, K_endconnectrules enddiscipline, GN_KEYWORDS_VAMS_2_3, K_enddiscipline endfunction, GN_KEYWORDS_1364_1995, K_endfunction endgenerate, GN_KEYWORDS_1364_2001, K_endgenerate endgroup, GN_KEYWORDS_1800_2005, K_endgroup endinterface, GN_KEYWORDS_1800_2005, K_endinterface endmodule, GN_KEYWORDS_1364_1995, K_endmodule endnature, GN_KEYWORDS_VAMS_2_3, K_endnature endpackage, GN_KEYWORDS_1800_2005, K_endpackage endparamset, GN_KEYWORDS_VAMS_2_3, K_endparamset endprimitive, GN_KEYWORDS_1364_1995, K_endprimitive endprogram, GN_KEYWORDS_1800_2005, K_endprogram endproperty, GN_KEYWORDS_1800_2005, K_endproperty endspecify, GN_KEYWORDS_1364_1995, K_endspecify endsequence, GN_KEYWORDS_1800_2005, K_endsequence endtable, GN_KEYWORDS_1364_1995, K_endtable endtask, GN_KEYWORDS_1364_1995, K_endtask enum, GN_KEYWORDS_1800_2005, K_enum event, GN_KEYWORDS_1364_1995, K_event eventually, GN_KEYWORDS_1800_2009, K_eventually exclude, GN_KEYWORDS_VAMS_2_3, K_exclude exp, GN_KEYWORDS_VAMS_2_3, K_exp expect, GN_KEYWORDS_1800_2005, K_expect export, GN_KEYWORDS_1800_2005, K_export extends, GN_KEYWORDS_1800_2005, K_extends extern, GN_KEYWORDS_1800_2005, K_extern final, GN_KEYWORDS_1800_2005, K_final final_step, GN_KEYWORDS_VAMS_2_3, K_final_step first_match, GN_KEYWORDS_1800_2005, K_first_match flicker_noise, GN_KEYWORDS_VAMS_2_3, K_flicker_noise floor, GN_KEYWORDS_VAMS_2_3, K_floor flow, GN_KEYWORDS_VAMS_2_3, K_flow for, GN_KEYWORDS_1364_1995, K_for foreach, GN_KEYWORDS_1800_2005, K_foreach force, GN_KEYWORDS_1364_1995, K_force forever, GN_KEYWORDS_1364_1995, K_forever fork, GN_KEYWORDS_1364_1995, K_fork forkjoin, GN_KEYWORDS_1800_2005, K_forkjoin from, GN_KEYWORDS_VAMS_2_3, K_from function, GN_KEYWORDS_1364_1995, K_function generate, GN_KEYWORDS_1364_2001, K_generate genvar, GN_KEYWORDS_1364_2001, K_genvar global, GN_KEYWORDS_1800_2009, K_global ground, GN_KEYWORDS_VAMS_2_3, K_ground highz0, GN_KEYWORDS_1364_1995, K_highz0 highz1, GN_KEYWORDS_1364_1995, K_highz1 hypot, GN_KEYWORDS_VAMS_2_3, K_hypot idt, GN_KEYWORDS_VAMS_2_3, K_idt idtmod, GN_KEYWORDS_VAMS_2_3, K_idtmod idt_nature, GN_KEYWORDS_VAMS_2_3, K_idt_nature if, GN_KEYWORDS_1364_1995, K_if iff, GN_KEYWORDS_1800_2005, K_iff ifnone, GN_KEYWORDS_1364_1995, K_ifnone ignore_bins, GN_KEYWORDS_1800_2005, K_ignore_bins illegal_bins, GN_KEYWORDS_1800_2005, K_illegal_bins implies, GN_KEYWORDS_1800_2009, K_implies implements, GN_KEYWORDS_1800_2012, K_implements import, GN_KEYWORDS_1800_2005, K_import incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir include, GN_KEYWORDS_1364_2001_CONFIG, K_include inf, GN_KEYWORDS_VAMS_2_3, K_inf initial, GN_KEYWORDS_1364_1995, K_initial initial_step, GN_KEYWORDS_VAMS_2_3, K_initial_step inout, GN_KEYWORDS_1364_1995, K_inout input, GN_KEYWORDS_1364_1995, K_input inside, GN_KEYWORDS_1800_2005, K_inside instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance int, GN_KEYWORDS_1800_2005, K_int integer, GN_KEYWORDS_1364_1995, K_integer interconnect, GN_KEYWORDS_1800_2012, K_interconnect interface, GN_KEYWORDS_1800_2005, K_interface intersect, GN_KEYWORDS_1800_2005, K_intersect join, GN_KEYWORDS_1364_1995, K_join join_any, GN_KEYWORDS_1800_2005, K_join_any join_none, GN_KEYWORDS_1800_2005, K_join_none laplace_nd, GN_KEYWORDS_VAMS_2_3, K_laplace_nd laplace_np, GN_KEYWORDS_VAMS_2_3, K_laplace_np laplace_zd, GN_KEYWORDS_VAMS_2_3, K_laplace_zd laplace_zp, GN_KEYWORDS_VAMS_2_3, K_laplace_zp large, GN_KEYWORDS_1364_1995, K_large last_crossing, GN_KEYWORDS_VAMS_2_3, K_last_crossing let, GN_KEYWORDS_1800_2009, K_let liblist, GN_KEYWORDS_1364_2001_CONFIG, K_liblist library, GN_KEYWORDS_1364_2001_CONFIG, K_library limexp, GN_KEYWORDS_VAMS_2_3, K_limexp ln, GN_KEYWORDS_VAMS_2_3, K_ln local, GN_KEYWORDS_1800_2005, K_local localparam, GN_KEYWORDS_1364_2001, K_localparam log, GN_KEYWORDS_VAMS_2_3, K_log # This is defined by SystemVerilog 1800-2005 and as an Icarus extension. logic, GN_KEYWORDS_1800_2005|GN_KEYWORDS_ICARUS, K_logic longint, GN_KEYWORDS_1800_2005, K_longint macromodule, GN_KEYWORDS_1364_1995, K_macromodule matches, GN_KEYWORDS_1800_2005, K_matches max, GN_KEYWORDS_VAMS_2_3, K_max medium, GN_KEYWORDS_1364_1995, K_medium merged, GN_KEYWORDS_VAMS_2_3, K_merged min, GN_KEYWORDS_VAMS_2_3, K_min modport, GN_KEYWORDS_1800_2005, K_modport module, GN_KEYWORDS_1364_1995, K_module nand, GN_KEYWORDS_1364_1995, K_nand nature, GN_KEYWORDS_VAMS_2_3, K_nature negedge, GN_KEYWORDS_1364_1995, K_negedge net_resolution, GN_KEYWORDS_VAMS_2_3, K_net_resolution nettype, GN_KEYWORDS_1800_2012, K_nettype new, GN_KEYWORDS_1800_2005, K_new nexttime, GN_KEYWORDS_1800_2009, K_nexttime nmos, GN_KEYWORDS_1364_1995, K_nmos noise_table, GN_KEYWORDS_VAMS_2_3, K_noise_table nor, GN_KEYWORDS_1364_1995, K_nor noshowcancelled, GN_KEYWORDS_1364_2001, K_noshowcancelled not, GN_KEYWORDS_1364_1995, K_not notif0, GN_KEYWORDS_1364_1995, K_notif0 notif1, GN_KEYWORDS_1364_1995, K_notif1 null, GN_KEYWORDS_1800_2005, K_null or, GN_KEYWORDS_1364_1995, K_or output, GN_KEYWORDS_1364_1995, K_output package, GN_KEYWORDS_1800_2005, K_package packed, GN_KEYWORDS_1800_2005, K_packed parameter, GN_KEYWORDS_1364_1995, K_parameter paramset, GN_KEYWORDS_VAMS_2_3, K_paramset pmos, GN_KEYWORDS_1364_1995, K_pmos posedge, GN_KEYWORDS_1364_1995, K_posedge potential, GN_KEYWORDS_VAMS_2_3, K_potential pow, GN_KEYWORDS_VAMS_2_3, K_pow primitive, GN_KEYWORDS_1364_1995, K_primitive priority, GN_KEYWORDS_1800_2005, K_priority program, GN_KEYWORDS_1800_2005, K_program property, GN_KEYWORDS_1800_2005, K_property protected, GN_KEYWORDS_1800_2005, K_protected pull0, GN_KEYWORDS_1364_1995, K_pull0 pull1, GN_KEYWORDS_1364_1995, K_pull1 pulldown, GN_KEYWORDS_1364_1995, K_pulldown pullup, GN_KEYWORDS_1364_1995, K_pullup pulsestyle_onevent, GN_KEYWORDS_1364_2001, K_pulsestyle_onevent pulsestyle_ondetect, GN_KEYWORDS_1364_2001, K_pulsestyle_ondetect pure, GN_KEYWORDS_1800_2005, K_pure rand, GN_KEYWORDS_1800_2005, K_rand randc, GN_KEYWORDS_1800_2005, K_randc randcase, GN_KEYWORDS_1800_2005, K_randcase randsequence, GN_KEYWORDS_1800_2005, K_randsequence rcmos, GN_KEYWORDS_1364_1995, K_rcmos real, GN_KEYWORDS_1364_1995, K_real realtime, GN_KEYWORDS_1364_1995, K_realtime ref, GN_KEYWORDS_1800_2005, K_ref reg, GN_KEYWORDS_1364_1995, K_reg reject_on, GN_KEYWORDS_1800_2009, K_reject_on release, GN_KEYWORDS_1364_1995, K_release repeat, GN_KEYWORDS_1364_1995, K_repeat resolveto, GN_KEYWORDS_VAMS_2_3, K_resolveto restrict, GN_KEYWORDS_1800_2009, K_restrict return, GN_KEYWORDS_1800_2005, K_return rnmos, GN_KEYWORDS_1364_1995, K_rnmos rpmos, GN_KEYWORDS_1364_1995, K_rpmos rtran, GN_KEYWORDS_1364_1995, K_rtran rtranif0, GN_KEYWORDS_1364_1995, K_rtranif0 rtranif1, GN_KEYWORDS_1364_1995, K_rtranif1 s_always, GN_KEYWORDS_1800_2009, K_s_always s_eventually, GN_KEYWORDS_1800_2009, K_s_eventually s_nexttime, GN_KEYWORDS_1800_2009, K_s_nexttime s_until, GN_KEYWORDS_1800_2009, K_s_until s_until_with, GN_KEYWORDS_1800_2009, K_s_until_with scalared, GN_KEYWORDS_1364_1995, K_scalared sequence, GN_KEYWORDS_1800_2005, K_sequence shortint, GN_KEYWORDS_1800_2005, K_shortint shortreal, GN_KEYWORDS_1800_2005, K_shortreal showcancelled, GN_KEYWORDS_1364_2001, K_showcancelled signed, GN_KEYWORDS_1364_2001, K_signed sin, GN_KEYWORDS_VAMS_2_3, K_sin sinh, GN_KEYWORDS_VAMS_2_3, K_sinh slew, GN_KEYWORDS_VAMS_2_3, K_slew small, GN_KEYWORDS_1364_1995, K_small soft, GN_KEYWORDS_1800_2012, K_soft solve, GN_KEYWORDS_1800_2005, K_solve specify, GN_KEYWORDS_1364_1995, K_specify specparam, GN_KEYWORDS_1364_1995, K_specparam split, GN_KEYWORDS_VAMS_2_3, K_split sqrt, GN_KEYWORDS_VAMS_2_3, K_sqrt static, GN_KEYWORDS_1800_2005, K_static # This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3 string, GN_KEYWORDS_1800_2005|GN_KEYWORDS_VAMS_2_3, K_string strong, GN_KEYWORDS_1800_2009, K_strong strong0, GN_KEYWORDS_1364_1995, K_strong0 strong1, GN_KEYWORDS_1364_1995, K_strong1 struct, GN_KEYWORDS_1800_2005, K_struct super, GN_KEYWORDS_1800_2005, K_super supply0, GN_KEYWORDS_1364_1995, K_supply0 supply1, GN_KEYWORDS_1364_1995, K_supply1 sync_accept_on, GN_KEYWORDS_1800_2009, K_sync_accept_on sync_reject_on, GN_KEYWORDS_1800_2009, K_sync_reject_on table, GN_KEYWORDS_1364_1995, K_table tagged, GN_KEYWORDS_1800_2005, K_tagged tan, GN_KEYWORDS_VAMS_2_3, K_tan tanh, GN_KEYWORDS_VAMS_2_3, K_tanh task, GN_KEYWORDS_1364_1995, K_task this, GN_KEYWORDS_1800_2005, K_this throughout, GN_KEYWORDS_1800_2005, K_throughout time, GN_KEYWORDS_1364_1995, K_time timeprecision, GN_KEYWORDS_1800_2005, K_timeprecision timer, GN_KEYWORDS_VAMS_2_3, K_timer timeunit, GN_KEYWORDS_1800_2005, K_timeunit tran, GN_KEYWORDS_1364_1995, K_tran tranif0, GN_KEYWORDS_1364_1995, K_tranif0 tranif1, GN_KEYWORDS_1364_1995, K_tranif1 transition, GN_KEYWORDS_VAMS_2_3, K_transition tri, GN_KEYWORDS_1364_1995, K_tri tri0, GN_KEYWORDS_1364_1995, K_tri0 tri1, GN_KEYWORDS_1364_1995, K_tri1 triand, GN_KEYWORDS_1364_1995, K_triand trior, GN_KEYWORDS_1364_1995, K_trior trireg, GN_KEYWORDS_1364_1995, K_trireg type, GN_KEYWORDS_1800_2005, K_type typedef, GN_KEYWORDS_1800_2005, K_typedef union, GN_KEYWORDS_1800_2005, K_union unique, GN_KEYWORDS_1800_2005, K_unique unique0, GN_KEYWORDS_1800_2009, K_unique0 units, GN_KEYWORDS_VAMS_2_3, K_units # Reserved for future use! unsigned, GN_KEYWORDS_1364_2001, K_unsigned until, GN_KEYWORDS_1800_2009, K_until until_with, GN_KEYWORDS_1800_2009, K_until_with untyped, GN_KEYWORDS_1800_2009, K_untyped use, GN_KEYWORDS_1364_2001_CONFIG, K_use uwire, GN_KEYWORDS_1364_2005, K_uwire var, GN_KEYWORDS_1800_2005, K_var vectored, GN_KEYWORDS_1364_1995, K_vectored virtual, GN_KEYWORDS_1800_2005, K_virtual void, GN_KEYWORDS_1800_2005, K_void wait, GN_KEYWORDS_1364_1995, K_wait wait_order, GN_KEYWORDS_1800_2005, K_wait_order wand, GN_KEYWORDS_1364_1995, K_wand weak, GN_KEYWORDS_1800_2009, K_weak weak0, GN_KEYWORDS_1364_1995, K_weak0 weak1, GN_KEYWORDS_1364_1995, K_weak1 while, GN_KEYWORDS_1364_1995, K_while white_noise, GN_KEYWORDS_VAMS_2_3, K_white_noise wildcard, GN_KEYWORDS_1800_2005, K_wildcard wire, GN_KEYWORDS_1364_1995, K_wire with, GN_KEYWORDS_1800_2005, K_with within, GN_KEYWORDS_1800_2005, K_within # This is the name originally proposed for uwire and is deprecated! wone, GN_KEYWORDS_1364_2005, K_wone wor, GN_KEYWORDS_1364_1995, K_wor # This is defined by Verilog-AMS 2.3 and as an Icarus extension. wreal, GN_KEYWORDS_VAMS_2_3|GN_KEYWORDS_ICARUS, K_wreal xnor, GN_KEYWORDS_1364_1995, K_xnor xor, GN_KEYWORDS_1364_1995, K_xor zi_nd, GN_KEYWORDS_VAMS_2_3, K_zi_nd zi_np, GN_KEYWORDS_VAMS_2_3, K_zi_np zi_zd, GN_KEYWORDS_VAMS_2_3, K_zi_zd zi_zp, GN_KEYWORDS_VAMS_2_3, K_zi_zp %% int lexor_keyword_mask = 0; int lexor_keyword_code(const char*str, unsigned nstr) { const struct lexor_keyword*rc = Lkwd::check_identifier(str, nstr); if (rc == 0) return IDENTIFIER; else if ((rc->mask & lexor_keyword_mask) == 0) return IDENTIFIER; else return rc->tokenType; } iverilog-12_0/lexor_keyword.h000066400000000000000000000017571435245347300164270ustar00rootroot00000000000000#ifndef IVL_lexor_keyword_H #define IVL_lexor_keyword_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. */ extern int lexor_keyword_code (const char*str, unsigned len); #endif /* IVL_lexor_keyword_H */ iverilog-12_0/libmisc/000077500000000000000000000000001435245347300147715ustar00rootroot00000000000000iverilog-12_0/libmisc/LineInfo.cc000066400000000000000000000025611435245347300170070ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "LineInfo.h" # include using namespace std; LineInfo::LineInfo() : lineno_(0) { } LineInfo::~LineInfo() { } string LineInfo::get_fileline() const { ostringstream buf; buf << (file_.str()? file_.str() : "") << ":" << lineno_; string res = buf.str(); return res; } void LineInfo::set_line(const LineInfo&that) { file_ = that.file_; lineno_ = that.lineno_; } void LineInfo::set_file(perm_string f) { file_ = f; } void LineInfo::set_lineno(unsigned n) { lineno_ = n; } iverilog-12_0/libmisc/LineInfo.h000066400000000000000000000034561435245347300166550ustar00rootroot00000000000000#ifndef IVL_LineInfo_H #define IVL_LineInfo_H /* * Copyright (c) 1999-2021 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 /* * This class holds line information for an internal object. * * Note that the file names are C-style strings that are allocated by * the lexor (which parses the line directives) and are never * deallocated. We can therefore safely store the pointer and never * delete the string, even if LineInfo objects are destroyed. */ class LineInfo { public: LineInfo(); virtual ~LineInfo(); // Get a fully formatted file/lineno std::string get_fileline() const; // Set the file/line from another LineInfo object. void set_line(const LineInfo&that); // Access parts of LineInfo data void set_file(perm_string f); void set_lineno(unsigned n); perm_string get_file() const { return file_; } unsigned get_lineno() const { return lineno_; } private: perm_string file_; unsigned lineno_; }; #endif /* IVL_LineInfo_H */ iverilog-12_0/libmisc/StringHeap.cc000066400000000000000000000131301435245347300173420ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 # include # include # include #ifdef CHECK_WITH_VALGRIND # include "ivl_alloc.h" static char **string_pool = NULL; static unsigned string_pool_count = 0; #endif using namespace std; static const unsigned DEFAULT_CELL_SIZE = 0x10000; StringHeap::StringHeap() { cell_base_ = 0; cell_ptr_ = 0; } StringHeap::~StringHeap() { // This is a planned memory leak. The string heap is intended // to hold permanently-allocated strings. } const char* StringHeap::add(const char*text) { unsigned len = strlen(text); unsigned rem = cell_base_==0? 0 : (DEFAULT_CELL_SIZE - cell_ptr_); // Special case: huge items get their own allocation. if ( (len+1) >= DEFAULT_CELL_SIZE ) { char*buf = strdup(text); #ifdef CHECK_WITH_VALGRIND string_pool_count += 1; string_pool = (char**)realloc(string_pool, string_pool_count*sizeof(char**)); string_pool[string_pool_count-1] = buf; #endif return buf; } // If the current cell that I'm working through cannot hold // the current string, then set it aside and get another cell // to put the string into. if (rem < (len+1)) { // release any unused memory. This assumes that a // realloc shrink of the memory region will return the // same pointer. if (rem > 0) { char*old = cell_base_; cell_base_ = (char*)realloc(cell_base_, cell_ptr_); assert(cell_base_ != 0); assert(cell_base_ == old); } // start new cell cell_base_ = (char*)malloc(DEFAULT_CELL_SIZE); cell_ptr_ = 0; rem = DEFAULT_CELL_SIZE; assert(cell_base_ != 0); #ifdef CHECK_WITH_VALGRIND string_pool_count += 1; string_pool = (char **) realloc(string_pool, string_pool_count*sizeof(char **)); string_pool[string_pool_count-1] = cell_base_; #endif } assert( (len+1) <= rem ); char*res = cell_base_ + cell_ptr_; memcpy(res, text, len); cell_ptr_ += len; cell_base_[cell_ptr_++] = 0; assert(cell_ptr_ <= DEFAULT_CELL_SIZE); return res; } perm_string StringHeap::make(const char*text) { return perm_string(add(text)); } StringHeapLex::StringHeapLex() { hit_count_ = 0; add_count_ = 0; for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) hash_table_[idx] = 0; } StringHeapLex::~StringHeapLex() { } void StringHeapLex::cleanup() { #ifdef CHECK_WITH_VALGRIND for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) { free(string_pool[idx]); } free(string_pool); string_pool = NULL; string_pool_count = 0; for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) { hash_table_[idx] = 0; } #endif } unsigned StringHeapLex::add_hit_count() const { return hit_count_; } unsigned StringHeapLex::add_count() const { return add_count_; } static unsigned hash_string(const char*text) { unsigned h = 0; while (*text) { h = (h << 4) ^ (h >> 28) ^ *text; text += 1; } return h; } const char* StringHeapLex::add(const char*text) { unsigned hash_value = hash_string(text) % HASH_SIZE; /* If we easily find the string in the hash table, then return that and be done. */ if (hash_table_[hash_value] && (strcmp(hash_table_[hash_value], text) == 0)) { hit_count_ += 1; return hash_table_[hash_value]; } /* The existing hash entry is not a match. Replace it with the newly allocated value, and return the new pointer as the result to the add. */ const char*res = StringHeap::add(text); hash_table_[hash_value] = res; add_count_ += 1; return res; } perm_string StringHeapLex::make(const char*text) { return perm_string(add(text)); } perm_string StringHeapLex::make(const string&text) { return perm_string(add(text.c_str())); } bool operator == (perm_string a, const char*b) { if (a.str() == b) return true; if (! (a.str() && b)) return false; if (strcmp(a.str(), b) == 0) return true; return false; } bool operator == (perm_string a, perm_string b) { return a == b.str(); } bool operator != (perm_string a, const char*b) { return ! (a == b); } bool operator != (perm_string a, perm_string b) { return ! (a == b); } bool operator < (perm_string a, perm_string b) { if (b.str() && !a.str()) return true; if (b.str() == a.str()) return false; if (strcmp(a.str(), b.str()) < 0) return true; return false; } ostream& operator << (ostream&out, perm_string that) { if (that.nil()) out << ""; else out << that.str(); return out; } const perm_string empty_perm_string = perm_string::literal(""); iverilog-12_0/libmisc/StringHeap.h000066400000000000000000000072661435245347300172210ustar00rootroot00000000000000#ifndef IVL_StringHeap_H #define IVL_StringHeap_H /* * Copyright (c) 2002-2021 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 class perm_string { public: perm_string() : text_(0) { } perm_string(const perm_string&that) : text_(that.text_) { } ~perm_string() { } inline bool nil() const { return text_ == 0; } perm_string& operator = (const perm_string&that) { text_ = that.text_; return *this; } const char*str() const { return text_; } operator const char* () const { return str(); } // This is an escape for making perm_string objects out of // literals. For example, perm_string::literal("Label"); Please // do *not* cheat and pass arbitrary const char* items here. static perm_string literal(const char*t) { return perm_string(t); } private: friend class StringHeap; friend class StringHeapLex; explicit perm_string(const char*t) : text_(t) { }; private: const char*text_; }; extern const perm_string empty_perm_string; extern bool operator == (perm_string a, perm_string b); extern bool operator == (perm_string a, const char* b); extern bool operator != (perm_string a, perm_string b); extern bool operator != (perm_string a, const char* b); extern bool operator > (perm_string a, perm_string b); extern bool operator < (perm_string a, perm_string b); extern bool operator >= (perm_string a, perm_string b); extern bool operator <= (perm_string a, perm_string b); extern std::ostream& operator << (std::ostream&out, perm_string that); /* * The string heap is a way to permanently allocate strings * efficiently. They only take up the space of the string characters * and the terminating nul, there is no malloc overhead. */ class StringHeap { public: StringHeap(); ~StringHeap(); const char*add(const char*); perm_string make(const char*); private: char*cell_base_; unsigned cell_ptr_; private: // not implemented StringHeap(const StringHeap&); StringHeap& operator= (const StringHeap&); }; /* * A lexical string heap is a string heap that makes an effort to * return the same pointer for identical strings. This saves further * space by not allocating duplicate strings, so in a system with lots * of identifiers, this can theoretically save more space. */ class StringHeapLex : private StringHeap { public: StringHeapLex(); ~StringHeapLex(); const char*add(const char*); perm_string make(const char*); perm_string make(const std::string&); unsigned add_count() const; unsigned add_hit_count() const; void cleanup(); private: enum { HASH_SIZE = 4096 }; const char*hash_table_[HASH_SIZE]; unsigned add_count_; unsigned hit_count_; private: // not implemented StringHeapLex(const StringHeapLex&); StringHeapLex& operator= (const StringHeapLex&); }; #endif /* IVL_StringHeap_H */ iverilog-12_0/libveriuser/000077500000000000000000000000001435245347300157025ustar00rootroot00000000000000iverilog-12_0/libveriuser/Makefile.in000066400000000000000000000065261435245347300177600ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ RANLIB = @RANLIB@ AR = @AR@ LD = @LD@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif LDRELOCFLAGS = @LDRELOCFLAGS@ LDTARGETFLAGS = @LDTARGETFLAGS@ CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \ a_fetch_argv.o a_fetch_dir.o a_fetch_fullname.o a_fetch_location.o \ a_fetch_param.o a_fetch_range.o a_fetch_tfarg.o a_fetch_time.o \ a_fetch_type.o a_fetch_type_str.o a_fetch_value.o a_handle_by_name.o \ a_handle_hiconn.o a_handle_object.o a_handle_parent.o \ a_handle_simulated_net.o a_handle_tfarg.o a_initialize.o a_next.o \ a_next_bit.o a_next_port.o a_next_topmod.o a_object_of_type.o \ a_product_version.o a_set_value.o a_vcl.o a_version.o O = asynch.o delay.o exprinfo.o finish.o getcstringp.o getinstance.o \ getlongp.o getp.o getsimtime.o io_print.o math.o mc_scan_plusargs.o \ nodeinfo.o nump.o putlongp.o putp.o spname.o typep.o workarea.o \ veriusertfs.o priv.o $A all: dep libveriuser.a $(ALL32) check: all clean: rm -rf *.o dep libveriuser.a libveriuser.o distclean: clean rm -f Makefile config.log rm -f config.h stamp-config-h cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in cd ..; ./config.status --file=libveriuser/$@ dep: mkdir dep stamp-config-h: $(srcdir)/config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=libveriuser/config.h config.h: stamp-config-h libveriuser.o: $O $(LD) $(LDTARGETFLAGS) -r -o $@ $O libveriuser.a: libveriuser.o rm -f $@ $(AR) cvq $@ libveriuser.o $(RANLIB) $@ %.o: %.c config.h $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep install:: all installdirs installfiles F = ./libveriuser.a installfiles: $(F) | installdirs $(INSTALL_DATA) ./libveriuser.a "$(DESTDIR)$(libdir)/libveriuser$(suffix).a" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)" uninstall:: rm -f "$(DESTDIR)$(libdir)/libveriuser$(suffix).a" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/libveriuser/a_close.c000066400000000000000000000017401435245347300174550ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 "priv.h" void acc_close(void) { if (pli_trace) { fprintf(pli_trace, "acc_close()\n"); } } iverilog-12_0/libveriuser/a_compare_handles.c000066400000000000000000000017451435245347300215010ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.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 PLI_INT32 acc_compare_handles(handle handle1, handle handle2) { return handle1 == handle2; } iverilog-12_0/libveriuser/a_configure.c000066400000000000000000000043411435245347300203310ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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 #include "priv.h" #include int acc_configure(PLI_INT32 config_param, const char*value) { int rc; switch (config_param) { case accDevelopmentVersion: vpi_printf("Request PLI Development Version %s\n", value); rc = 1; if (pli_trace) { fprintf(pli_trace, "acc_configure(accDevelopmentVersion, %s)\n", value); } break; case accEnableArgs: if (pli_trace) { fprintf(pli_trace, "acc_configure(accEnableArgs, %s)\n", value); } rc = 0; if (strcmp(value,"acc_set_scope") == 0) { vpi_printf("XXXX acc_configure argument: Sorry: " "(accEnableArgs, %s\n", value); } else if (strcmp(value,"no_acc_set_scope") == 0) { vpi_printf("XXXX acc_configure argument: Sorry: " "(accEnableArgs, %s\n", value); } else { vpi_printf("XXXX acc_configure argument error. " "(accEnableArgs, %s(invalid)\n", value); } break; default: if (pli_trace) { fprintf(pli_trace, "acc_configure(config=%d, %s)\n", (int)config_param, value); } #if 0 vpi_printf("XXXX acc_configure(%d, %s)\n", (int)config_param, value); #else /* Parameter is not necessarily a string. */ vpi_printf("XXXX acc_configure(%d, ...)\n", (int)config_param); #endif rc = 0; break; } return rc; } iverilog-12_0/libveriuser/a_fetch_argc.c000066400000000000000000000022601435245347300204330ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 # include /* * acc_fetch_argc implemented using VPI interface */ int acc_fetch_argc(void) { s_vpi_vlog_info vpi_vlog_info; /* get command line info */ if (! vpi_get_vlog_info(&vpi_vlog_info)) return 0; /* return argc */ return vpi_vlog_info.argc; } iverilog-12_0/libveriuser/a_fetch_argv.c000066400000000000000000000022741435245347300204630ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 # include /* * acc_fetch_argv implemented using VPI interface */ char **acc_fetch_argv(void) { s_vpi_vlog_info vpi_vlog_info; /* get command line info */ if (! vpi_get_vlog_info(&vpi_vlog_info)) return (char **)0; /* return argc */ return vpi_vlog_info.argv; } iverilog-12_0/libveriuser/a_fetch_dir.c000066400000000000000000000025561435245347300203050ustar00rootroot00000000000000/* * Copyright (c) 2003-2014 Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include # include # include "priv.h" PLI_INT32 acc_fetch_direction(handle obj) { (void)obj; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "acc_fetch_direction: enter.\n"); fflush(pli_trace); } fprintf(stderr, "acc_fetch_direction: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "acc_fetch_direction: return.\n"); fflush(pli_trace); } return accInout; } iverilog-12_0/libveriuser/a_fetch_fullname.c000066400000000000000000000024141435245347300213230ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 #include "priv.h" /* * acc_fetch_fullname implemented using VPI interface */ char *acc_fetch_fullname(handle object) { return __acc_newstring(vpi_get_str(vpiFullName, object)); } char* acc_fetch_name(handle object) { return __acc_newstring(vpi_get_str(vpiName, object)); } char* acc_fetch_defname(handle object) { return __acc_newstring(vpi_get_str(vpiDefName, object)); } iverilog-12_0/libveriuser/a_fetch_location.c000066400000000000000000000020671435245347300213340ustar00rootroot00000000000000/* * Copyright (c) 2003-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 #include int acc_fetch_location(p_location loc, handle obj) { (void)obj; /* Parameter is not used. */ loc->line_no = 0; loc->filename = ""; return 1; } iverilog-12_0/libveriuser/a_fetch_param.c000066400000000000000000000027131435245347300206220ustar00rootroot00000000000000/* * Copyright (c) 2003-2009 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 #include #include "priv.h" double acc_fetch_paramval(handle object) { s_vpi_value val; val.format = vpiObjTypeVal; vpi_get_value(object, &val); switch (val.format) { case vpiStringVal: if (pli_trace) { fprintf(pli_trace, "acc_fetch_paramval(%s) --> \"%s\"\n", vpi_get_str(vpiName, object), val.value.str); } return (double) (intptr_t)val.value.str; default: vpi_printf("XXXX: parameter %s has type %d\n", vpi_get_str(vpiName, object), (int)val.format); assert(0); return 0.0; } } iverilog-12_0/libveriuser/a_fetch_range.c000066400000000000000000000021441435245347300206140ustar00rootroot00000000000000/* * Copyright (c) 2003 Michael Ruff (mruff at chiaro.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 /* * acc_fetch_range implemented using VPI interface */ PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb) { *msb = vpi_get(vpiLeftRange, object); *lsb = vpi_get(vpiRightRange, object); return 0; } iverilog-12_0/libveriuser/a_fetch_tfarg.c000066400000000000000000000062401435245347300206240ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include "priv.h" /* * acc_fetch_tfarg and friends implemented using VPI interface */ double acc_fetch_itfarg(PLI_INT32 n, handle obj) { vpiHandle iter, hand = 0; s_vpi_value value; int idx = n; double rtn; iter = vpi_iterate(vpiArgument, obj); /* scan to nth argument */ while (idx > 0 && (hand = vpi_scan(iter))) idx--; if (hand) { value.format=vpiRealVal; vpi_get_value(hand, &value); rtn = value.value.real; vpi_free_object(iter); } else { rtn = 0.0; } if (pli_trace) { fprintf(pli_trace, "%s: acc_fetch_itfarg(%d, %p) --> %f\n", vpi_get_str(vpiName, obj), (int)n, obj, rtn); } return rtn; } double acc_fetch_tfarg(PLI_INT32 n) { return acc_fetch_itfarg_int(n, cur_instance); } PLI_INT32 acc_fetch_itfarg_int(PLI_INT32 n, handle obj) { vpiHandle iter, hand = 0; s_vpi_value value; int idx = n; int rtn; iter = vpi_iterate(vpiArgument, obj); /* scan to nth argument */ while (idx > 0 && (hand = vpi_scan(iter))) idx--; if (hand) { value.format=vpiIntVal; vpi_get_value(hand, &value); rtn = value.value.integer; vpi_free_object(iter); } else { rtn = 0; } if (pli_trace) { fprintf(pli_trace, "%s: acc_fetch_itfarg_int(%d, %p) --> %d\n", vpi_get_str(vpiName, obj), (int)n, obj, rtn); } return rtn; } PLI_INT32 acc_fetch_tfarg_int(PLI_INT32 n) { return acc_fetch_itfarg_int(n, cur_instance); } char *acc_fetch_itfarg_str(PLI_INT32 n, handle obj) { vpiHandle iter, hand = 0; s_vpi_value value; int idx = n; char *rtn; iter = vpi_iterate(vpiArgument, obj); /* scan to nth argument */ while (idx > 0 && (hand = vpi_scan(iter))) idx -= 1; if (hand) { value.format=vpiStringVal; vpi_get_value(hand, &value); rtn = __acc_newstring(value.value.str); vpi_free_object(iter); } else { rtn = (char *) 0; } if (pli_trace) { fprintf(pli_trace, "%s: acc_fetch_itfarg_str(%d, %p) --> \"%s\"\n", vpi_get_str(vpiName, obj), (int)n, obj, rtn? rtn : ""); } return rtn; } char *acc_fetch_tfarg_str(PLI_INT32 n) { return acc_fetch_itfarg_str(n, cur_instance); } iverilog-12_0/libveriuser/a_fetch_time.c000066400000000000000000000020751435245347300204610ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "priv.h" void acc_fetch_timescale_info(handle obj, p_timescale_info info) { info->precision = vpi_get(vpiTimePrecision, 0); info->unit = vpi_get(vpiTimeUnit, obj); } iverilog-12_0/libveriuser/a_fetch_type.c000066400000000000000000000054461435245347300205110ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include PLI_INT32 acc_fetch_size(handle obj) { return vpi_get(vpiSize, obj); } PLI_INT32 acc_fetch_type(handle obj) { switch (vpi_get(vpiType, obj)) { case vpiConstant: /*XXXX SWIFT PLI tasks seem to assume that string constants show up an accParameter, instead of accConstant. */ if (vpi_get(vpiConstType, obj) == vpiStringConst) return accParameter; else return accConstant; case vpiNamedEvent: return accNamedEvent; case vpiNet: return accNet; case vpiParameter: return accParameter; case vpiReg: return accReg; case vpiIntegerVar: return accIntegerVar; case vpiModule: return accModule; } vpi_printf("acc_fetch_type: vpiType %d is what accType?\n", (int)vpi_get(vpiType, obj)); return accUnknown; } PLI_INT32 acc_fetch_fulltype(handle obj) { int type = vpi_get(vpiType, obj); switch (type) { case vpiNet: { type = vpi_get(vpiNetType, obj); switch(type) { case vpiWire: return accWire; default: vpi_printf("acc_fetch_fulltype: vpiNetType %d unknown?\n", type); return accUnknown; } } case vpiConstant: /* see acc_fetch_type */ if (vpi_get(vpiConstType, obj) == vpiStringConst) return accStringParam; else return accConstant; case vpiIntegerVar: return accIntegerVar; case vpiModule: if (!vpi_handle(vpiScope, obj)) return accTopModule; else return accModuleInstance; /* FIXME accCellInstance */ case vpiNamedEvent: return accNamedEvent; case vpiParameter: switch(vpi_get(vpiConstType, obj)) { case vpiRealConst: return accRealParam; case vpiStringConst: return accStringParam; default: return accIntegerParam; } case vpiReg: return accReg; default: vpi_printf("acc_fetch_fulltype: vpiType %d unknown?\n", type); return accUnknown; } } iverilog-12_0/libveriuser/a_fetch_type_str.c000066400000000000000000000027231435245347300213740ustar00rootroot00000000000000/* * Copyright (c) 2003-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 #include #include const char* acc_fetch_type_str(PLI_INT32 type) { switch (type) { case accNet: return "accNet"; case accReg: return "accReg"; case accParameter: return "accParameter"; case accConstant: return "accConstant"; } vpi_printf("acc_fetch_type_str: type %d is what accType?\n", (int)type); return "acc_fetch_type_str(unknown)"; } /* * FIXME: What does this do? How should it be declared in acc_user.h? */ PLI_INT32 acc_fetch_paramtype(handle obj) { (void)obj; /* Parameter is not used. */ return 0; } iverilog-12_0/libveriuser/a_fetch_value.c000066400000000000000000000062471435245347300206440ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include "priv.h" # include # include static char* fetch_struct_value(handle obj, s_acc_value*value) { struct t_vpi_value val; switch (value->format) { case accScalarVal: val.format = vpiScalarVal; vpi_get_value(obj, &val); switch (val.value.scalar) { case vpi0: value->value.scalar = acc0; break; case vpi1: value->value.scalar = acc1; break; case vpiX: value->value.scalar = accX; break; case vpiZ: value->value.scalar = accZ; break; default: assert(0); } if (pli_trace) { fprintf(pli_trace, "acc_fetch_value(<%s>, " "accScalarVal) --> %d\n", vpi_get_str(vpiFullName,obj), value->value.scalar); } break; case accIntVal: val.format = vpiIntVal; vpi_get_value(obj, &val); value->value.integer = val.value.integer; if (pli_trace) { fprintf(pli_trace, "acc_fetch_value(<%s>, " "accIntVal) --> %d\n", vpi_get_str(vpiFullName,obj), value->value.integer); } break; case accRealVal: val.format = vpiRealVal; vpi_get_value(obj, &val); value->value.real = val.value.real; if (pli_trace) { fprintf(pli_trace, "acc_fetch_value(<%s>, " "accRealVal) --> %g\n", vpi_get_str(vpiFullName,obj), value->value.real); } break; default: vpi_printf("XXXX acc_fetch_value(..., \"%%%%\", <%d>);\n", value->format); value->value.str = ""; break; } return 0; } static char* fetch_strength_value(handle obj) { struct t_vpi_value val; char str[4]; val.format = vpiStrengthVal; vpi_get_value(obj, &val); /* Should this iterate over the bits? It now matches the old code. */ vpip_format_strength(str, &val, 0); if (pli_trace) { fprintf(pli_trace, "acc_fetch_value(<%s>, \"%%v\") --> %s\n", vpi_get_str(vpiFullName,obj), str); } return __acc_newstring(str); } char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value) { if (strcmp(fmt, "%%") == 0) return fetch_struct_value(obj, value); if (strcmp(fmt, "%v") == 0) return fetch_strength_value(obj); vpi_printf("XXXX acc_fetch_value(..., \"%s\", ...)\n", fmt); return ""; } iverilog-12_0/libveriuser/a_handle_by_name.c000066400000000000000000000027111435245347300212740ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 Michael Ruff (mruff at chiaro.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 # include "priv.h" # include # include /* * acc_handle_by_name implemented using VPI interface */ handle acc_handle_by_name(const char*obj_name, handle scope) { vpiHandle res; /* if no scope provided, use tasks scope */ if (!scope) { scope = vpi_handle(vpiScope, cur_instance); } res = vpi_handle_by_name(obj_name, scope); if (pli_trace) { fprintf(pli_trace, "acc_handle_by_name(\"%s\", scope=%s) " " --> %p\n", obj_name, vpi_get_str(vpiFullName, scope), res); } return res; } iverilog-12_0/libveriuser/a_handle_hiconn.c000066400000000000000000000025341435245347300211430ustar00rootroot00000000000000/* * Copyright (c) 2003-2014 Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include # include # include "priv.h" handle acc_handle_hiconn(handle obj) { (void)obj; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "acc_handle_hiconn: enter.\n"); fflush(pli_trace); } fprintf(stderr, "acc_handle_hiconn: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "acc_handle_hiconn: return.\n"); fflush(pli_trace); } return 0; } iverilog-12_0/libveriuser/a_handle_object.c000066400000000000000000000030431435245347300211270ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 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 #include "priv.h" static vpiHandle search_scope = 0; handle acc_handle_object(const char*name) { vpiHandle scope = search_scope? search_scope : vpi_handle(vpiScope, cur_instance); vpiHandle res = vpi_handle_by_name(name, scope); if (pli_trace) { fprintf(pli_trace, "acc_handle_object(%s ) --> .\n", name, acc_fetch_fullname(scope)); } return res; } char* acc_set_scope(handle ref, ...) { char*name; search_scope = ref; name = acc_fetch_fullname(search_scope); if (pli_trace) { fprintf(pli_trace, "acc_set_scope()\n", name); } return acc_fetch_fullname(ref); } iverilog-12_0/libveriuser/a_handle_parent.c000066400000000000000000000022771435245347300211620ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "priv.h" handle acc_handle_parent(handle obj) { vpiHandle scope = vpi_handle(vpiScope, obj); while (scope && (vpi_get(vpiType, scope) != vpiModule)) scope = vpi_handle(vpiScope, scope); return scope; } handle acc_handle_scope(handle obj) { return vpi_handle(vpiScope, obj); } iverilog-12_0/libveriuser/a_handle_simulated_net.c000066400000000000000000000022071435245347300225170ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include # include # include "priv.h" handle acc_handle_simulated_net(handle obj) { if (pli_trace) { fprintf(pli_trace, "acc_handle_simulated_set: returns argument\n"); fflush(pli_trace); } return obj; } iverilog-12_0/libveriuser/a_handle_tfarg.c000066400000000000000000000026331435245347300207700ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include "priv.h" /* * acc_handle_tfarg implemented using VPI interface */ handle acc_handle_tfarg(int n) { vpiHandle rtn_h = 0; if (n > 0) { vpiHandle sys_i; sys_i = vpi_iterate(vpiArgument, cur_instance); /* find nth arg */ while (n > 0) { rtn_h = vpi_scan(sys_i); if (rtn_h == 0) break; n--; } if (rtn_h) vpi_free_object(sys_i); } else { rtn_h = (vpiHandle) 0; } return rtn_h; } handle acc_handle_tfinst(void) { return cur_instance; } iverilog-12_0/libveriuser/a_initialize.c000066400000000000000000000017031435245347300205100ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 int acc_error_flag; int acc_initialize() { acc_error_flag = 0; return 1; } iverilog-12_0/libveriuser/a_next.c000066400000000000000000000050041435245347300173230ustar00rootroot00000000000000/* * Copyright (c) 2003-2009 Michael Ruff (mruff at chiaro.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 #include #include "priv.h" /* * acc_next and friends implemented using VPI */ handle acc_next(PLI_INT32 *type, handle scope, handle prev) { vpiHandle iter, hand = 0; /* trace */ if (pli_trace) { PLI_INT32 *ip; fprintf(pli_trace, "acc_next(%p <", type); for (ip = type; *ip; ip++) { fprintf(pli_trace, "%s%d", ip != type ? "," : "", (int)*ip); } fprintf(pli_trace, ">, %p", scope); if (scope) fprintf(pli_trace, " \"%s\"", vpi_get_str(vpiName, scope)); fprintf(pli_trace, ", %p", prev); if (prev) fprintf(pli_trace, " \"%s\"", vpi_get_str(vpiName, prev)); else fprintf(pli_trace, ")"); fflush(pli_trace); } /* * The acc_next_* functions need to be reentrant, so we need to * rescan all the items up to the previous one, then return * the next one. */ iter = vpi_iterate(vpiScope, scope); /* ICARUS extension */ if (prev) { while ((hand = vpi_scan(iter))) { if (hand == prev) break; } } /* scan for next */ if (!prev || hand) { while ((hand = vpi_scan(iter))) { if (acc_object_in_typelist(hand, type)) break; } } /* don't leak iterators */ if (hand) vpi_free_object(iter); /* trace */ if (pli_trace) { fprintf(pli_trace, " --> %p", hand); if (hand) fprintf(pli_trace, " \"%s\"\n", vpi_get_str(vpiName, hand)); else fprintf(pli_trace, "\n"); } return hand; } handle acc_next_scope(handle scope, handle prev) { PLI_INT32 type[2] = {accScope, 0}; return acc_next(type, scope, prev); } iverilog-12_0/libveriuser/a_next_bit.c000066400000000000000000000026021435245347300201620ustar00rootroot00000000000000/* * Copyright (c) 2003-2014 Stephen Williams (steve@picturel.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include # include # include "priv.h" handle acc_next_bit(handle ref, handle bit) { (void)ref; /* Parameter is not used. */ (void)bit; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "acc_next_bit: enter.\n"); fflush(pli_trace); } fprintf(stderr, "acc_next_bit: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "acc_next_bit: return.\n"); fflush(pli_trace); } return 0; } iverilog-12_0/libveriuser/a_next_port.c000066400000000000000000000026041435245347300203720ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include # include # include "priv.h" handle acc_next_port(handle ref, handle bit) { (void)ref; /* Parameter is not used. */ (void)bit; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "acc_next_port: enter.\n"); fflush(pli_trace); } fprintf(stderr, "acc_next_port: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "acc_next_port: return.\n"); fflush(pli_trace); } return 0; } iverilog-12_0/libveriuser/a_next_topmod.c000066400000000000000000000025151435245347300207110ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 #include #undef NULL #define NULL 0 /* * acc_next_topmod implemented using VPI interface */ handle acc_next_topmod(handle prev_topmod) { static vpiHandle last = NULL; static vpiHandle mod_i = NULL; if (!prev_topmod) { /* start over */ mod_i = vpi_iterate(vpiModule, NULL); } else { /* subsequent time through */ assert(prev_topmod == last); } last = vpi_scan(mod_i); return last; } iverilog-12_0/libveriuser/a_object_of_type.c000066400000000000000000000053641435245347300213510ustar00rootroot00000000000000/* * Copyright (c) 2002-2013 Michael Ruff (mruff at chiaro.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 #include #include "priv.h" /* * acc_object_of_type implemented using VPI interface */ int acc_object_of_type(handle object, PLI_INT32 type) { int vtype; int rtn = 0; /* false */ if (pli_trace) { fprintf(pli_trace, "acc_object_of_type(%p \"%s\", %d)", object, vpi_get_str(vpiName, object), (int)type); fflush(pli_trace); } /* get VPI type of object */ vtype = vpi_get(vpiType, object); switch (type) { case accModule: rtn = vtype == vpiModule; break; case accScope: if (vtype == vpiModule || vtype == vpiNamedBegin || vtype == vpiNamedFork || vtype == vpiTask || vtype == vpiFunction || vtype == vpiGenScope) rtn = 1; break; case accNet: rtn = vtype == vpiNet; break; case accReg: rtn = vtype == vpiReg; break; case accRealParam: if (vtype == vpiNamedEvent && vpi_get(vpiConstType, object) == vpiRealConst) rtn = 1; break; case accParameter: rtn = vtype == vpiParameter; break; case accNamedEvent: rtn = vtype == vpiNamedEvent; break; case accIntegerVar: rtn = vtype == vpiIntegerVar; break; case accRealVar: rtn = vtype == vpiRealVar; break; case accTimeVar: rtn = vtype == vpiTimeVar; break; case accScalar: if (vtype == vpiReg || vtype == vpiNet) rtn = vpi_get(vpiSize, object) == 1; break; case accVector: if (vtype == vpiReg || vtype == vpiNet) rtn = vpi_get(vpiSize, object) > 1; break; default: vpi_printf("acc_object_of_type: Unknown type %d\n", (int)type); rtn = 0; } if (pli_trace) fprintf(pli_trace, " --> %d\n", rtn); return rtn; } int acc_object_in_typelist(handle object, PLI_INT32*typelist) { while (typelist[0] != 0) { int rtn = acc_object_of_type(object, typelist[0]); if (rtn) return rtn; typelist += 1; } return 0; } iverilog-12_0/libveriuser/a_product_version.c000066400000000000000000000020271435245347300215740ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 char *acc_product_version(void) { s_vpi_vlog_info info; if (! vpi_get_vlog_info(&info)) return (char *)0; return info.version; } iverilog-12_0/libveriuser/a_set_value.c000066400000000000000000000065041435245347300203420ustar00rootroot00000000000000/* * Copyright (c) 2002-2009 Michael Ruff (mruff at chiaro.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 #include /* * acc_set_value implemented using VPI interface */ int acc_set_value(handle object, p_setval_value value, p_setval_delay delay) { s_vpi_time when, *whenp; s_vpi_value val; int flags; assert(delay); assert(value); assert(object); /* map setval_delay.model to flags */ switch (delay->model) { case accNoDelay: flags = vpiNoDelay; break; case accInertialDelay: flags = vpiInertialDelay; break; case accTransportDelay: flags = vpiTransportDelay; break; case accPureTransportDelay: flags = vpiPureTransportDelay; break; case accForceFlag: flags = vpiForceFlag; break; case accReleaseFlag: flags = vpiReleaseFlag; break; default: flags = -1; assert(0); break; } /* map acc_time to vpi_time */ if (delay->model != accNoDelay) { switch (delay->time.type) { case accSimTime: when.type = vpiSimTime; break; case accRealTime: when.type = vpiScaledRealTime; break; default: assert(0); break; } when.high = delay->time.high; when.low = delay->time.low; when.real = delay->time.real; whenp = &when; } else whenp = 0; /* map setval_value to vpi_value and flags */ switch (value->format) { case accBinStrVal: val.format = vpiBinStrVal; val.value.str = value->value.str; break; case accOctStrVal: val.format = vpiOctStrVal; val.value.str = value->value.str; break; case accDecStrVal: val.format = vpiDecStrVal; val.value.str = value->value.str; break; case accHexStrVal: val.format = vpiHexStrVal; val.value.str = value->value.str; break; case accScalarVal: val.format = vpiScalarVal; val.value.scalar = value->value.scalar; break; case accIntVal: val.format = vpiIntVal; val.value.integer = value->value.integer; break; case accRealVal: val.format = vpiRealVal; val.value.real = value->value.real; break; case accStringVal: val.format = vpiStringVal; val.value.str = value->value.str; break; case accVectorVal: val.format = vpiVectorVal; val.value.vector = (p_vpi_vecval)value->value.vector; break; default: vpi_printf("XXXX acc_set_value(value->format=%d)\n", value->format); assert(0); break; } /* put value */ vpi_put_value(object, &val, whenp, flags); return 1; } iverilog-12_0/libveriuser/a_vcl.c000066400000000000000000000133761435245347300171440ustar00rootroot00000000000000/* * Copyright (c) 2003-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 #include #include #include "priv.h" #include #include "ivl_alloc.h" /* * This is the structure of a record that I use locally to hold the * information about a VCL. This record includes a pointer to the vpi * callback that is actually watching the value, and that callback has * a pointer to this record in its user_data so that I can get to it * when the value changes. * * Keep all these records in a vcl_list so that I can get access to * them for the vcl_delete. */ struct vcl_record { /* Object who's value I'm watching. */ vpiHandle obj; /* User's callback routine. */ PLI_INT32(*consumer)(p_vc_record); void*user_data; PLI_INT32 vcl_flag; vpiHandle callback; struct vcl_record*next; }; static struct vcl_record*vcl_list = 0; static int vpi_strength_to_vcl(int vs) { switch (vs) { case vpiSupplyDrive: return vclSupply; case vpiStrongDrive: return vclStrong; case vpiPullDrive: return vclPull; case vpiLargeCharge: return vclLarge; case vpiWeakDrive: return vclWeak; case vpiMediumCharge: return vclMedium; case vpiSmallCharge: return vclSmall; case vpiHiZ: return vclHighZ; default: return -1; } } /* * This is a VPI callback that notices the value change. This function * further dispatches the information about the callback to the * consumer function. */ static PLI_INT32 vcl_value_callback(struct t_cb_data*cb) { s_vpi_time sim_time; s_vpi_value obj_value; struct t_vc_record vcr; struct vcl_record*cur = (struct vcl_record*)cb->user_data; sim_time.type = vpiSimTime; vpi_get_time(cur->obj, &sim_time); switch (cur->vcl_flag) { case VCL_VERILOG_LOGIC: vpi_printf("XXXX vcl_value_callback(%s=%d);\n", vpi_get_str(vpiName, cur->obj), -1); vcr.vc_reason = logic_value_change; break; case VCL_VERILOG_STRENGTH: vcr.vc_reason = strength_value_change; obj_value.format = vpiStrengthVal; vpi_get_value(cur->obj, &obj_value); assert(obj_value.format == vpiStrengthVal); switch (obj_value.value.strength[0].logic) { case vpi0: vcr.out_value.strengths_s.logic_value = acc0; vcr.out_value.strengths_s.strength1 = vpi_strength_to_vcl(obj_value.value.strength[0].s0); vcr.out_value.strengths_s.strength2 = vpi_strength_to_vcl(obj_value.value.strength[0].s0); break; case vpi1: vcr.out_value.strengths_s.logic_value = acc1; vcr.out_value.strengths_s.strength1 = vpi_strength_to_vcl(obj_value.value.strength[0].s1); vcr.out_value.strengths_s.strength2 = vpi_strength_to_vcl(obj_value.value.strength[0].s1); break; case vpiX: vcr.out_value.strengths_s.logic_value = accX; vcr.out_value.strengths_s.strength1 = vpi_strength_to_vcl(obj_value.value.strength[0].s1); vcr.out_value.strengths_s.strength2 = vpi_strength_to_vcl(obj_value.value.strength[0].s0); break; case vpiZ: vcr.out_value.strengths_s.logic_value = accZ; vcr.out_value.strengths_s.strength1 = vclHighZ; vcr.out_value.strengths_s.strength2 = vclHighZ; break; default: assert(0); } if (pli_trace) { fprintf(pli_trace, "Call vcl_value_callback(%s=%d )\n", vpi_get_str(vpiFullName, cur->obj), vcr.out_value.strengths_s.logic_value, vcr.out_value.strengths_s.strength1, vcr.out_value.strengths_s.strength2); } break; default: assert(0); } vcr.vc_hightime = sim_time.high; vcr.vc_lowtime = sim_time.low; vcr.user_data = cur->user_data; (cur->consumer) (&vcr); return 0; } void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record), void*data, PLI_INT32 vcl_flag) { struct vcl_record*cur; struct t_cb_data cb; switch (vpi_get(vpiType, obj)) { case vpiNet: case vpiReg: cur = malloc(sizeof (struct vcl_record)); cur->obj = obj; cur->consumer = consumer; cur->user_data = data; cur->vcl_flag = vcl_flag; cur->next = vcl_list; vcl_list = cur; cb.reason = cbValueChange; cb.cb_rtn = vcl_value_callback; cb.obj = obj; cb.time = 0; cb.value = 0; cb.user_data = (void*)cur; cur->callback = vpi_register_cb(&cb); if (pli_trace) { fprintf(pli_trace, "acc_vcl_add(<%s>, ..., %p, %d)\n", vpi_get_str(vpiFullName, obj), data, (int)vcl_flag); } break; default: vpi_printf("XXXX acc_vcl_add(, ..., %d);\n", (int)vpi_get(vpiType, obj), (int)vcl_flag); break; } } void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record), void*data, PLI_INT32 vcl_flag) { (void)obj; /* Parameter is not used. */ (void)consumer; /* Parameter is not used. */ (void)data; /* Parameter is not used. */ (void)vcl_flag; /* Parameter is not used. */ vpi_printf("XXXX acc_vcl_delete(...)\n"); } iverilog-12_0/libveriuser/a_version.c000066400000000000000000000020171435245347300200330ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 char *acc_version(void) { s_vpi_vlog_info info; if (! vpi_get_vlog_info(&info)) return (char *)0; return info.version; } iverilog-12_0/libveriuser/asynch.c000066400000000000000000000021511435245347300173320ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 /* Enables async misctf callbacks */ int async_misctf_enable = 0; /* * Implement misctf async enable */ int tf_asynchon(void) { async_misctf_enable = 1; return 0; } int tf_asynchoff(void) { async_misctf_enable = 0; return 0; } iverilog-12_0/libveriuser/config.h.in000066400000000000000000000024351435245347300177310ustar00rootroot00000000000000#ifndef IVL_config_H #define IVL_config_H /* * Copyright (c) 2003-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. */ # define SIZEOF_UNSIGNED_LONG_LONG 0 # define SIZEOF_UNSIGNED_LONG 0 # define SIZEOF_UNSIGNED 0 #if SIZEOF_UNSIGNED >= 8 typedef unsigned ivl_u64_t; #else # if SIZEOF_UNSIGNED_LONG >= 8 typedef unsigned long ivl_u64_t; # else # if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG typedef unsigned long long ivl_u64_t; # else typedef unsigned long ivl_u64_t; # endif # endif #endif #endif /* IVL_config_H */ iverilog-12_0/libveriuser/cppcheck.sup000066400000000000000000000105621435245347300202170ustar00rootroot00000000000000// These are the functions that the runtime exports. // The ACC functions. // acc_close() unusedFunction:a_close.c:23 // acc_compare_handles() unusedFunction:a_compare_handles.c:23 // acc_configure() unusedFunction:a_configure.c:25 // acc_fetch_argc() unusedFunction:a_fetch_argc.c:27 // acc_fetch_argv() unusedFunction:a_fetch_argv.c:27 // acc_fetch_defname() unusedFunction:a_fetch_fullname.c:37 // acc_fetch_direction() unusedFunction:a_fetch_dir.c:26 // acc_fetch_fulltype() unusedFunction:a_fetch_type.c:66 // acc_fetch_itfarg() unusedFunction:a_fetch_tfarg.c:27 // acc_fetch_location() unusedFunction:a_fetch_location.c:23 // acc_fetch_name() unusedFunction:a_fetch_fullname.c:32 // acc_fetch_paramtype() unusedFunction:a_fetch_type_str.c:47 // acc_fetch_paramval() unusedFunction:a_fetch_param.c:25 // acc_fetch_range() unusedFunction:a_fetch_range.c:26 // acc_fetch_size() unusedFunction:a_fetch_type.c:24 // acc_fetch_tfarg() unusedFunction:a_fetch_tfarg.c:56 // acc_fetch_tfarg_int() unusedFunction:a_fetch_tfarg.c:91 // acc_fetch_timescale_info() unusedFunction:a_fetch_time.c:24 // acc_fetch_type() unusedFunction:a_fetch_type.c:29 // acc_fetch_type_str() unusedFunction:a_fetch_type_str.c:24 // acc_fetch_value() unusedFunction:a_fetch_value.c:115 // acc_handle_by_name() unusedFunction:a_handle_by_name.c:29 // acc_handle_hiconn() unusedFunction:a_handle_hiconn.c:26 // acc_handle_object() unusedFunction:a_handle_object.c:26 // acc_handle_parent() unusedFunction:a_handle_parent.c:24 // acc_handle_scope() unusedFunction:a_handle_parent.c:34 // acc_handle_simulated_net() unusedFunction:a_handle_simulated_net.c:26 // acc_handle_tfarg() unusedFunction:a_handle_tfarg.c:27 // acc_handle_tfinst() unusedFunction:a_handle_tfarg.c:53 // acc_initialize() unusedFunction:a_initialize.c:24 // acc_next_bit() unusedFunction:a_next_bit.c:26 // acc_next_port() unusedFunction:a_next_port.c:26 // acc_next_scope() unusedFunction:a_next.c:86 // acc_next_topmod() unusedFunction:a_next_topmod.c:30 // acc_product_version() unusedFunction:a_product_version.c:23 // acc_set_scope() unusedFunction:a_handle_object.c:39 // acc_set_value() unusedFunction:a_set_value.c:27 // acc_vcl_add() unusedFunction:a_vcl.c:157 // acc_vcl_delete() unusedFunction:a_vcl.c:196 // acc_version() unusedFunction:a_version.c:23 // These are the TF routines. // io_printf() unusedFunction:io_print.c:26 // mc_scan_plusargs() unusedFunction:mc_scan_plusargs.c:27 // tf_asynchoff() unusedFunction:asynch.c:34 // tf_asynchon() unusedFunction:asynch.c:28 // tf_dofinish() unusedFunction:finish.c:26 // tf_dostop() unusedFunction:finish.c:32 // tf_error() unusedFunction:io_print.c:45 // tf_exprinfo() unusedFunction:exprinfo.c:26 // tf_getcstringp() unusedFunction:getcstringp.c:26 // tf_getlongp() unusedFunction:getlongp.c:30 // tf_getlongtime() unusedFunction:getsimtime.c:112 // tf_getp() unusedFunction:getp.c:73 // tf_getrealp() unusedFunction:getp.c:120 // tf_gettime() unusedFunction:getsimtime.c:77 // tf_getworkarea() unusedFunction:workarea.c:61 // tf_igettimeprecision() unusedFunction:getsimtime.c:196 // tf_igettimeunit() unusedFunction:getsimtime.c:226 // tf_long_to_real() unusedFunction:math.c:47 // tf_message() unusedFunction:io_print.c:56 // tf_mipname() unusedFunction:spname.c:46 // tf_multiply_long() unusedFunction:math.c:27 // tf_nodeinfo() unusedFunction:nodeinfo.c:27 // tf_nump() unusedFunction:nump.c:43 // tf_putlongp() unusedFunction:putlongp.c:29 // tf_putp() unusedFunction:putp.c:88 // tf_putrealp() unusedFunction:putp.c:137 // tf_real_to_long() unusedFunction:math.c:40 // tf_rosynchronize() unusedFunction:veriusertfs.c:433 // tf_scale_longdelay() unusedFunction:getsimtime.c:136 // tf_scale_realdelay() unusedFunction:getsimtime.c:161 // tf_setdelay() unusedFunction:delay.c:75 // tf_setrealdelay() unusedFunction:veriusertfs.c:468 // tf_setworkarea() unusedFunction:workarea.c:37 // tf_spname() unusedFunction:spname.c:25 // tf_strgetp() unusedFunction:getp.c:177 // tf_strgettime() unusedFunction:getsimtime.c:85 // tf_synchronize() unusedFunction:veriusertfs.c:406 // tf_typep() unusedFunction:typep.c:25 // tf_unscale_longdelay() unusedFunction:getsimtime.c:144 // tf_unscale_realdelay() unusedFunction:getsimtime.c:171 // tf_warning() unusedFunction:io_print.c:34 // Non-standard TF routines the Icarus provides. // tf_getlongsimtime() unusedFunction:getsimtime.c:126 // veriusertfs_register_table() unusedFunction:veriusertfs.c:93 iverilog-12_0/libveriuser/delay.c000066400000000000000000000042241435245347300171460ustar00rootroot00000000000000/* * Copyright (c) 2003-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 #include #include "priv.h" #include static PLI_INT32 delay_callback(struct t_cb_data*cb) { (void)cb; /* Parameter is not used. */ vpi_printf("XXXX delay_callback called.\n"); return 0; } int tf_isetdelay(PLI_INT32 delay, void*ss) { vpiHandle sys = (vpiHandle)ss; int unit = vpi_get(vpiTimeUnit, sys); int prec = vpi_get(vpiTimePrecision, 0); struct t_cb_data cb; struct t_vpi_time ct; if (pli_trace) { fprintf(pli_trace, "%s: tf_isetdelay(%d, ...)" " ;\n", vpi_get_str(vpiName, sys), (int)delay, unit, prec); } /* Convert the delay from the UNITS of the specified task/function to the precision of the simulation. */ assert(unit >= prec); while (unit > prec) { PLI_INT32 tmp = delay * 10; assert(tmp > delay); delay = tmp; unit -= 1; } /* Create a VPI callback to schedule the delay. */ ct.type = vpiSimTime; ct.high = 0; ct.low = delay; cb.reason = cbAfterDelay; cb.cb_rtn = delay_callback; cb.obj = 0; cb.time = &ct; cb.value = 0; cb.user_data = 0; vpi_register_cb(&cb); return 0; } int tf_setdelay(PLI_INT32 delay) { return tf_isetdelay(delay, tf_getinstance()); } iverilog-12_0/libveriuser/exprinfo.c000066400000000000000000000026231435245347300177030ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include # include # include "priv.h" struct t_tfexprinfo* tf_exprinfo(PLI_INT32 a, struct t_tfexprinfo*ip) { (void)a; /* Parameter is not used. */ (void)ip; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "tf_exprinfo: enter.\n"); fflush(pli_trace); } fprintf(stderr, "tf_exprinfo: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "tf_exprinfo: return.\n"); fflush(pli_trace); } return 0; } iverilog-12_0/libveriuser/finish.c000066400000000000000000000021311435245347300173230ustar00rootroot00000000000000/* * Copyright (c) 2002 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 /* * Implement tf_dofinish and tf_dostop using vpi functions. */ int tf_dofinish(void) { vpi_control(vpiFinish, 0); return 0; } int tf_dostop(void) { vpi_control(vpiStop, 0); return 0; } iverilog-12_0/libveriuser/getcstringp.c000066400000000000000000000020361435245347300204000ustar00rootroot00000000000000/* * Copyright (c) 2002 Michael Ruff (mruff at chiaro.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 /* * tf_getinstance implemented using equivalent acc_ routing */ char *tf_getcstringp(int n) { char*res = acc_fetch_tfarg_str(n); return res; } iverilog-12_0/libveriuser/getinstance.c000066400000000000000000000020351435245347300203520ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include "priv.h" /* * tf_getinstance implemented using VPI interface */ PLI_BYTE8* tf_getinstance(void) { return (PLI_BYTE8 *)cur_instance; } iverilog-12_0/libveriuser/getlongp.c000066400000000000000000000036451435245347300176750ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include #include #include #include "priv.h" /* * tf_getlongp implemented using VPI interface */ int tf_getlongp(int *highvalue, int n) { vpiHandle sys_i, arg_h = 0; s_vpi_value value; int len, rtn; assert(highvalue); assert(n > 0); /* get task/func handle */ sys_i = vpi_iterate(vpiArgument, cur_instance); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) assert(0); n--; } /* get the value */ value.format = vpiHexStrVal; vpi_get_value(arg_h, &value); /* convert string to int(s) */ len = strlen(value.value.str); if (len > 8) { char *str; /* low word */ str = value.value.str + (len - 8); rtn = (int) strtoul(str, 0, 16); /* high word */ *str = '\0'; *highvalue = (int) strtoul(value.value.str, 0, 16); } else { *highvalue = 0; rtn = (int) strtoul(value.value.str, 0, 16); } vpi_free_object(sys_i); return rtn; } iverilog-12_0/libveriuser/getp.c000066400000000000000000000105571435245347300170150ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 # include # include # include "priv.h" /* * tf_getp and friends, implemented using VPI interface */ PLI_INT32 tf_igetp(PLI_INT32 n, void *obj) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value value; int rtn = 0; assert(n > 0); /* get task/func handle */ sys_h = (vpiHandle)obj; sys_i = vpi_iterate(vpiArgument, sys_h); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) { goto out; } n--; } /* If it is a constant string, return a pointer to it else int value */ if (vpi_get(vpiType, arg_h) == vpiConstant && vpi_get(vpiConstType, arg_h) == vpiStringConst) { value.format = vpiStringVal; vpi_get_value(arg_h, &value); /* The following may generate a compilation warning, but this * functionality is required by some versions of the standard. */ rtn = (int) value.value.str; /* Oh my */ } else { value.format = vpiIntVal; vpi_get_value(arg_h, &value); rtn = value.value.integer; } vpi_free_object(sys_i); out: if (pli_trace) { fprintf(pli_trace, "tf_igetp(n=%d, obj=%p) --> %d\n", (int)n, obj, rtn); } return rtn; } PLI_INT32 tf_getp(PLI_INT32 n) { int rtn = tf_igetp(n, cur_instance); return rtn; } double tf_igetrealp(PLI_INT32 n, void *obj) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value value; double rtn = 0.0; assert(n > 0); /* get task/func handle */ sys_h = (vpiHandle)obj; sys_i = vpi_iterate(vpiArgument, sys_h); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) { goto out; } n--; } if (vpi_get(vpiType, arg_h) == vpiConstant && vpi_get(vpiConstType, arg_h) == vpiStringConst) { rtn = 0.0; } else { value.format = vpiRealVal; vpi_get_value(arg_h, &value); rtn = value.value.real; } vpi_free_object(sys_i); out: if (pli_trace) { fprintf(pli_trace, "tf_igetrealp(n=%d, obj=%p) --> %f\n", (int)n, obj, rtn); } return rtn; } double tf_getrealp(PLI_INT32 n) { double rtn = tf_igetrealp(n, cur_instance); return rtn; } char *tf_istrgetp(PLI_INT32 n, PLI_INT32 fmt, void *obj) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value value; char *rtn = 0; assert(n > 0); /* get task/func handle */ sys_h = (vpiHandle)obj; sys_i = vpi_iterate(vpiArgument, sys_h); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) { goto out; } n--; } if (vpi_get(vpiType, arg_h) == vpiConstant && vpi_get(vpiConstType, arg_h) == vpiStringConst) { value.format = vpiStringVal; vpi_get_value(arg_h, &value); rtn = value.value.str; } else { value.format = -1; switch (tolower(fmt)) { case 'b': value.format = vpiBinStrVal; break; case 'o': value.format = vpiOctStrVal; break; case 'd': value.format = vpiDecStrVal; break; case 'h': value.format = vpiHexStrVal; break; } if (value.format > 0) { vpi_get_value(arg_h, &value); rtn = value.value.str; } } vpi_free_object(sys_i); out: if (pli_trace) { fprintf(pli_trace, "tf_istrgetp(n=%d, fmt=%c, obj=%p) --> \"%s\"\n", (int)n, (int)fmt, obj, rtn); } return rtn; } char *tf_strgetp(PLI_INT32 n, PLI_INT32 fmt) { char *rtn = tf_istrgetp(n, fmt, cur_instance); return rtn; } iverilog-12_0/libveriuser/getsimtime.c000066400000000000000000000140241435245347300202160ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include #include #include "config.h" #include "priv.h" #include /* * some TF time routines implemented using VPI interface */ // On some platforms (e.g. MinGW), pow() may not always generate an // exact integer result when supplied with integer operands. Converting // the result to an integer before we use it seems to be enough to work // round this issue. static ivl_u64_t pow10u(PLI_INT32 val) { return (ivl_u64_t)pow(10, val); } static ivl_u64_t scale(int high, int low, void*obj) { ivl_u64_t scaled; vpiHandle use_obj = obj; if (use_obj == 0) { /* If object is not passed in, then use current scope. */ vpiHandle hand = vpi_handle(vpiScope, cur_instance); use_obj = hand; } else { /* If object IS passed in, make sure it is a scope. If it is not, then get the scope of the object. We need a scope handle to go on. */ switch (vpi_get(vpiType,use_obj)) { case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: break; default: use_obj = vpi_handle(vpiScope, use_obj); break; } } scaled = high; scaled = (scaled << 32) | low; scaled /= pow10u(vpi_get(vpiTimeUnit, use_obj) - vpi_get(vpiTimePrecision,0)); return scaled; } PLI_INT32 tf_gettime(void) { s_vpi_time timerec; timerec.type = vpiSimTime; vpi_get_time (0, &timerec); return scale(timerec.high, timerec.low, 0) & 0xffffffff; } char *tf_strgettime(void) { static char buf[32]; s_vpi_time timerec; timerec.type = vpiSimTime; vpi_get_time (0, &timerec); if (timerec.high) snprintf(buf, sizeof(buf)-1, "%u%08u", (unsigned int)timerec.high, (unsigned int)timerec.low); else snprintf(buf, sizeof(buf)-1, "%u", (unsigned int)timerec.low); return buf; } PLI_INT32 tf_igetlongtime(PLI_INT32 *high, void*obj) { s_vpi_time timerec; ivl_u64_t scaled; timerec.type = vpiSimTime; vpi_get_time ((vpiHandle)obj, &timerec); scaled = scale(timerec.high, timerec.low, obj); *high = (scaled >> 32) & 0xffffffff; return scaled & 0xffffffff; } PLI_INT32 tf_getlongtime(PLI_INT32 *high) { return tf_igetlongtime(high, 0); } /* * This function is not defined in the IEEE standard, but is provided for * compatibility with other simulators. On platforms that support this, * make it a weak symbol just in case the user has defined their own * function for this. */ #if !defined(__CYGWIN__) && !defined(__MINGW32__) PLI_INT32 tf_getlongsimtime(PLI_INT32 *high) __attribute__ ((weak)); #endif PLI_INT32 tf_getlongsimtime(PLI_INT32 *high) { s_vpi_time timerec; timerec.type = vpiSimTime; vpi_get_time (0, &timerec); *high = timerec.high; return timerec.low; } void tf_scale_longdelay(void*obj, PLI_INT32 low, PLI_INT32 high, PLI_INT32 *alow, PLI_INT32 *ahigh) { ivl_u64_t scaled = scale(high, low, obj); *ahigh = (scaled >> 32) & 0xffffffff; *alow = scaled & 0xffffffff; } void tf_unscale_longdelay(void*obj, PLI_INT32 low, PLI_INT32 high, PLI_INT32 *alow, PLI_INT32 *ahigh) { ivl_u64_t unscaled; vpiHandle hand = vpi_handle(vpiScope, cur_instance); (void)obj; /* Parameter is not used. */ unscaled = high; unscaled = (unscaled << 32) | low; unscaled *= pow(10, vpi_get(vpiTimeUnit, hand) - vpi_get(vpiTimePrecision, 0)); *ahigh = (unscaled >> 32) & 0xffffffff; *alow = unscaled & 0xffffffff; } void tf_scale_realdelay(void*obj, double real, double *areal) { vpiHandle hand = vpi_handle(vpiScope, cur_instance); (void)obj; /* Parameter is not used. */ *areal = real / pow(10, vpi_get(vpiTimeUnit, hand) - vpi_get(vpiTimePrecision, 0)); } void tf_unscale_realdelay(void*obj, double real, double *areal) { vpiHandle hand = vpi_handle(vpiScope, cur_instance); (void)obj; /* Parameter is not used. */ *areal = real * pow(10, vpi_get(vpiTimeUnit, hand) - vpi_get(vpiTimePrecision, 0)); } PLI_INT32 tf_gettimeprecision(void) { PLI_INT32 rc; vpiHandle hand; hand = vpi_handle(vpiScope, cur_instance); rc = vpi_get(vpiTimePrecision, hand); if (pli_trace) fprintf(pli_trace, "tf_gettimeprecision(<%s>) --> %d\n", vpi_get_str(vpiName, cur_instance), (int)rc); return rc; } PLI_INT32 tf_igettimeprecision(void*obj) { PLI_INT32 rc; if (obj == 0) { /* If the obj pointer is null, then get the simulation time precision. */ rc = vpi_get(vpiTimePrecision, 0); } else { vpiHandle scope = vpi_handle(vpiScope, (vpiHandle)obj); assert(scope); rc = vpi_get(vpiTimePrecision, scope); } if (pli_trace) fprintf(pli_trace, "tf_igettimeprecision(<%s>) --> %d\n", obj? vpi_get_str(vpiName, obj) : ".", (int)rc); return rc; } PLI_INT32 tf_gettimeunit() { vpiHandle hand = vpi_handle(vpiScope, cur_instance); return vpi_get(vpiTimeUnit, hand); } PLI_INT32 tf_igettimeunit(void*obj) { return vpi_get(!obj ? vpiTimePrecision : vpiTimeUnit, (vpiHandle)obj); } iverilog-12_0/libveriuser/io_print.c000066400000000000000000000033041435245347300176710ustar00rootroot00000000000000/* * Copyright (c) 2002-2014 Michael Ruff (mruff at chiaro.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 /* * io_printf implemented using VPI interface */ void io_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vpi_vprintf(fmt, ap); va_end(ap); } void tf_warning(const char *fmt, ...) { va_list ap; vpi_printf("warning! "); va_start(ap, fmt); vpi_vprintf(fmt, ap); va_end(ap); } void tf_error(const char *fmt, ...) { va_list ap; vpi_printf("error! "); va_start(ap, fmt); vpi_vprintf(fmt, ap); va_end(ap); } PLI_INT32 tf_message(PLI_INT32 level, char*facility, char*messno, char*fmt, ...) { va_list ap; (void)level; /* Parameter is not used. */ vpi_printf("%s[%s] ", facility, messno); va_start(ap, fmt); vpi_vprintf(fmt, ap); va_end(ap); vpi_printf("\n"); return 0; } iverilog-12_0/libveriuser/math.c000066400000000000000000000031701435245347300170000ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include # include # include # include "config.h" # include "vpi_user.h" # include "veriuser.h" void tf_multiply_long(PLI_INT32*aof_low1, PLI_INT32*aof_high1, PLI_INT32 aof_low2, PLI_INT32 aof_high2) { ivl_u64_t a, b; a = *aof_high1; a = (a << 32) | *aof_low1; b = aof_high2; b = (b << 32) | aof_low2; a *= b; *aof_high1 = (a >> 32) & 0xffffffff; *aof_low1 = a & 0xffffffff; } void tf_real_to_long(double real, PLI_INT32*low, PLI_INT32*high) { ivl_u64_t rtn = (ivl_u64_t)real; *high = (rtn >> 32) & 0xffffffff; *low = rtn & 0xffffffff; } void tf_long_to_real(PLI_INT32 low, PLI_INT32 high, double *real) { ivl_u64_t a; a = high; a = (a << 32) | low; *real = (double)a; } iverilog-12_0/libveriuser/mc_scan_plusargs.c000066400000000000000000000032741435245347300213770ustar00rootroot00000000000000/* * Copyright (c) 2002-2013 Michael Ruff (mruff at chiaro.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 # include /* * mc_scan_plusargs implemented using VPI interface */ char *mc_scan_plusargs(char *plusarg) { int argc, diff; char **argv; s_vpi_vlog_info vpi_vlog_info; /* get command line */ if (! vpi_get_vlog_info(&vpi_vlog_info)) return (char *)0; /* for each argument */ argv = vpi_vlog_info.argv; for (argc = 0; argc < vpi_vlog_info.argc; argc++, argv++) { char *a, *p; a = *argv; p = plusarg; /* only plusargs */ if (*a != '+') continue; a += 1; /* impossible matches */ if (strlen(a) < strlen(p)) continue; diff = 0; while (*p) { if (*a != *p) { diff = 1; break; } a++; p++; } if (!diff) return a; } /* didn't find it yet */ return (char *)0; } iverilog-12_0/libveriuser/nodeinfo.c000066400000000000000000000026741435245347300176600ustar00rootroot00000000000000/* * Copyright (c) 2003-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 # include # include # include # include "priv.h" /* XXX Not declared or used anywhere? */ struct t_tfnodeinfo* tf_nodeinfo(PLI_INT32 a, struct t_tfnodeinfo*ip) { (void)a; /* Parameter is not used. */ (void)ip; /* Parameter is not used. */ if (pli_trace) { fprintf(pli_trace, "tf_nodeinfo: enter.\n"); fflush(pli_trace); } fprintf(stderr, "tf_nodeinfo: XXXX not implemented. XXXX\n"); if (pli_trace) { fprintf(pli_trace, "tf_nodeinfo: return.\n"); fflush(pli_trace); } return 0; } iverilog-12_0/libveriuser/nump.c000066400000000000000000000024361435245347300170320ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include "veriuser.h" #include "priv.h" /* * tf_nump implemented using VPI interface */ int tf_inump(void *obj) { vpiHandle sys_h, sys_i; int cnt; sys_h = (vpiHandle)obj; sys_i = vpi_iterate(vpiArgument, sys_h); /* count number of args */ for (cnt = 0; sys_i && vpi_scan(sys_i); cnt++); return cnt; } int tf_nump(void) { return tf_inump(cur_instance); } iverilog-12_0/libveriuser/priv.c000066400000000000000000000027341435245347300170340ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 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 "priv.h" # include # include vpiHandle cur_instance = 0; FILE* pli_trace = 0; static char string_buffer[8192]; static unsigned string_fill = 0; static void buffer_reset(void) { string_fill = 0; } char* __acc_newstring(const char*txt) { char*res; unsigned len; if (txt == 0) return 0; len = strlen(txt); assert(len < sizeof string_buffer); if ((string_fill + len + 1) >= sizeof string_buffer) buffer_reset(); res = string_buffer + string_fill; strcpy(string_buffer + string_fill, txt); string_fill += len + 1; return res; } iverilog-12_0/libveriuser/priv.h000066400000000000000000000027521435245347300170410ustar00rootroot00000000000000#ifndef IVL_priv_H #define IVL_priv_H /* * Copyright (c) 2003-2020 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 "vpi_user.h" /* * The VPI handle for the current task/function instance. This is the * handle returned by vpi_handle(vpiSysTfCall, 0) when the task/function * is compiled or called, but we also need it when executing a callback. */ extern vpiHandle cur_instance; /* * This function implements the acc_ string buffer, by adding the * input string to the buffer, and returning a pointer to the first * character of the new string. */ extern char* __acc_newstring(const char*txt); /* * Trace file for logging ACC and TF calls. */ extern FILE* pli_trace; #endif /* IVL_priv_H */ iverilog-12_0/libveriuser/putlongp.c000066400000000000000000000033631435245347300177230ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 #include #include #include "priv.h" /* * tf_putlongp implemented using VPI interface */ void tf_putlongp(int n, int lowvalue, int highvalue) { vpiHandle sys_i, arg_h = 0; s_vpi_value val; int type; char str[20]; assert(n >= 0); /* get task/func handle */ sys_i = vpi_iterate(vpiArgument, cur_instance); type = vpi_get(vpiType, cur_instance); /* verify function */ assert(!(n == 0 && type != vpiSysFuncCall)); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) assert(0); n--; } if (!arg_h) arg_h = cur_instance; /* fill in vpi_value */ sprintf(str, "%x%08x", highvalue, lowvalue); val.format = vpiHexStrVal; val.value.str = str; vpi_put_value(arg_h, &val, 0, vpiNoDelay); vpi_free_object(sys_i); } iverilog-12_0/libveriuser/putp.c000066400000000000000000000070141435245347300170400ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.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 # include # include "priv.h" /* * tf_putp and friends implemented using VPI interface */ PLI_INT32 tf_iputp(PLI_INT32 n, PLI_INT32 value, void *obj) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value val; int rtn = 0, type; assert(n >= 0); /* get task/func handle */ sys_h = (vpiHandle)obj; type = vpi_get(vpiType, sys_h); /* Special case, we are putting the return value. */ if ((type == vpiSysFuncCall) && (n == 0)) { val.format = vpiIntVal; val.value.integer = value; vpi_put_value(sys_h, &val, 0, vpiNoDelay); if (pli_trace) { fprintf(pli_trace, "tf_iputp(, value=%d, func=%s) " "--> %d\n", (int)value, vpi_get_str(vpiName, obj), 0); } return 0; } if ((n == 0) && (type != vpiSysFuncCall)) { if (pli_trace) { fprintf(pli_trace, "tf_iputp(, value=%d, func=%s) " "--> %d\n", (int)value, vpi_get_str(vpiName, obj), 1); } return 1; } sys_i = vpi_iterate(vpiArgument, sys_h); /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) { rtn = 1; goto out; } n--; } /* fill in vpi_value */ val.format = vpiIntVal; val.value.integer = value; vpi_put_value(arg_h, &val, 0, vpiNoDelay); if (arg_h) vpi_free_object(sys_i); out: if (pli_trace) { fprintf(pli_trace, "tf_iputp(n=%d, value=%d, obj=%p) --> %d\n", (int)n, (int)value, obj, rtn); } return rtn; } PLI_INT32 tf_putp(PLI_INT32 n, PLI_INT32 value) { int rtn = tf_iputp(n, value, cur_instance); return rtn; } PLI_INT32 tf_iputrealp(PLI_INT32 n, double value, void *obj) { vpiHandle sys_h, sys_i, arg_h = 0; s_vpi_value val; int rtn = 0, type; assert(n >= 0); /* get task/func handle */ sys_h = (vpiHandle)obj; sys_i = vpi_iterate(vpiArgument, sys_h); type = vpi_get(vpiType, sys_h); /* verify function */ if (n == 0 && type != vpiSysFuncCall) { rtn = 1; goto free; } /* find nth arg */ while (n > 0) { if (!(arg_h = vpi_scan(sys_i))) { rtn = 1; goto out; } n--; } if (!arg_h) arg_h = sys_h; /* fill in vpi_value */ val.format = vpiRealVal; val.value.real = value; vpi_put_value(arg_h, &val, 0, vpiNoDelay); free: vpi_free_object(sys_i); out: if (pli_trace) { fprintf(pli_trace, "tf_iputrealp(n=%d, value=%f, obj=%p) --> %d\n", (int)n, value, obj, rtn); } return rtn; } PLI_INT32 tf_putrealp(PLI_INT32 n, double value) { int rtn = tf_iputrealp(n, value, cur_instance); return rtn; } iverilog-12_0/libveriuser/spname.c000066400000000000000000000026361435245347300173400ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 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 #include #include "priv.h" char* tf_spname(void) { char*rtn; vpiHandle scope = vpi_handle(vpiScope, cur_instance); rtn = __acc_newstring(vpi_get_str(vpiFullName, scope)); if (pli_trace) { fprintf(pli_trace, "%s: tf_spname() --> %s\n", vpi_get_str(vpiName, cur_instance), rtn); } return rtn; } char *tf_imipname(void *obj) { return vpi_get_str(vpiFullName, vpi_handle(vpiScope, (vpiHandle)obj)); } char *tf_mipname(void) { return tf_imipname(cur_instance); } iverilog-12_0/libveriuser/typep.c000066400000000000000000000035401435245347300172110ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 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 #include #include "priv.h" PLI_INT32 tf_typep(PLI_INT32 narg) { vpiHandle argv, arg_h = 0; int rtn; assert(narg > 0); /* get task/func handle */ argv = vpi_iterate(vpiArgument, cur_instance); /* find nth arg */ while (narg > 0) { /* Watch that the argument is not out of range. */ if (!(arg_h = vpi_scan(argv))) return TF_NULLPARAM; narg -= 1; } switch (vpi_get(vpiType, arg_h)) { case vpiConstant: switch (vpi_get(vpiConstType, arg_h)) { case vpiStringConst: rtn = TF_STRING; break; case vpiRealConst: rtn = TF_READONLYREAL; break; default: rtn = TF_READONLY; break; } break; case vpiIntegerVar: case vpiReg: case vpiMemoryWord: rtn = TF_READWRITE; break; case vpiRealVar: rtn = TF_READWRITEREAL; break; default: rtn = TF_READONLY; break; } vpi_free_object(argv); return rtn; } iverilog-12_0/libveriuser/veriusertfs.c000066400000000000000000000273151435245347300204370ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 Michael Ruff (mruff at chiaro.com) * Michael Runyan (mrunyan at chiaro.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. */ /* * Contains the routines required to implement veriusertfs routines * via VPI. This is extremely ugly, so don't look after eating dinner. */ # include # include # include # include # include "config.h" # include "priv.h" # include "vpi_user.h" # include "veriuser.h" # include "ivl_alloc.h" /* * Data to be passed to the callback function via the VPI callback * user data pointer. */ typedef struct t_pli_data { p_tfcell tf; /* pointer to veriusertfs cell */ vpiHandle call_handle; /* handle returned by vpiSysTfCall */ int paramvc; /* parameter number for misctf */ } s_pli_data, *p_pli_data; static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8 *); static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8 *); static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8 *); static PLI_INT32 callback(p_cb_data); /* * Keep a pointer to the user data so that it can be freed when the * simulation is finished. */ static p_pli_data* udata_store = 0; static unsigned udata_count = 0; static p_pli_data new_pli_data(p_tfcell tf, vpiHandle call_handle, int paramvc) { p_pli_data data = calloc(1, sizeof(s_pli_data)); data->tf = tf; data->call_handle = call_handle; data->paramvc = paramvc; udata_count += 1; udata_store = (p_pli_data*)realloc(udata_store, udata_count*sizeof(p_pli_data*)); udata_store[udata_count-1] = data; return data; } static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) { unsigned idx; (void)cb_data; /* Parameter is not used. */ for (idx = 0; idx < udata_count; idx += 1) { free(udata_store[idx]); } free(udata_store); udata_store = 0; udata_count = 0; return 0; } /* * Register veriusertfs routines/wrappers. Iterate over the tfcell * array, registering each function. */ void veriusertfs_register_table(p_tfcell vtable) { static int need_EOS_cb = 1; const char*path; p_tfcell tf; s_vpi_systf_data tf_data; if (!pli_trace && (path = getenv("PLI_TRACE"))) { static char trace_buf[1024]; if (strcmp(path,"-") == 0) pli_trace = stdout; else { pli_trace = fopen(path, "w"); if (!pli_trace) { perror(path); exit(1); } } setvbuf(pli_trace, trace_buf, _IOLBF, sizeof(trace_buf)); } for (tf = vtable; tf; tf++) { /* last element */ if (tf->type == 0) break; /* force forwref true */ if (!tf->forwref) { vpi_printf("veriusertfs: %s, forcing forwref = true\n", tf->tfname); } if (need_EOS_cb) { s_cb_data cb_data; cb_data.reason = cbEndOfSimulation; cb_data.time = 0; cb_data.cb_rtn = sys_end_of_simulation; cb_data.user_data = "system"; vpi_register_cb(&cb_data); need_EOS_cb = 0; } /* Build a VPI system task/function structure, and point it to the pli_data that represents this function. Supply wrapper functions for the system task actions. */ memset(&tf_data, 0, sizeof(s_vpi_systf_data)); switch (tf->type) { case usertask: tf_data.type = vpiSysTask; break; case userfunction: tf_data.sysfunctype = vpiIntFunc; tf_data.type = vpiSysFunc; break; case userrealfunction: tf_data.sysfunctype = vpiRealFunc; tf_data.type = vpiSysFunc; break; default: vpi_printf("veriusertfs: %s, unsupported type %d\n", tf->tfname, tf->type); continue; } tf_data.tfname = tf->tfname; tf_data.compiletf = compiletf; tf_data.calltf = calltf; tf_data.sizetf = sizetf; tf_data.user_data = (PLI_BYTE8*)tf; if (pli_trace) { fprintf(pli_trace, "Registering system %s:\n", tf->type == usertask ? "task" : "function"); fprintf(pli_trace, " tfname : %s\n", tf->tfname); if (tf->data) fprintf(pli_trace, " data : %d\n", tf->data); if (tf->checktf) fprintf(pli_trace, " checktf: %p\n", tf->checktf); if (tf->sizetf) fprintf(pli_trace, " sizetf : %p\n", tf->sizetf); if (tf->calltf) fprintf(pli_trace, " calltf : %p\n", tf->calltf); if (tf->misctf) fprintf(pli_trace, " misctf : %p\n", tf->misctf); } /* register */ vpi_register_systf(&tf_data); } return; } /* * This function calls the veriusertfs checktf and sets up all the * callbacks misctf requires. */ static PLI_INT32 compiletf(ICARUS_VPI_CONST PLI_BYTE8*data) { p_tfcell tf; p_pli_data pli; s_cb_data cb_data; vpiHandle arg_i, arg_h; int rtn = 0; /* cast back from opaque */ tf = (p_tfcell)data; /* get call handle */ cur_instance = vpi_handle(vpiSysTfCall, NULL); /* build callback user data for this instance */ pli = new_pli_data(tf, cur_instance, 0); /* Attach the pli_data structure to the VPI handle of the system task. This is how I manage the map from vpiHandle to PLI1 user data. We do it here (instead of during register) because this is the first that I have both the vpiHandle and the user data. */ vpi_put_userdata(cur_instance, pli); /* default cb_data */ memset(&cb_data, 0, sizeof(s_cb_data)); cb_data.cb_rtn = callback; cb_data.user_data = (PLI_BYTE8*)pli; /* register EOS misctf callback */ cb_data.reason = cbEndOfSimulation; vpi_register_cb(&cb_data); /* If there is a misctf function, then create a value change callback for all the arguments. In the tf_* API, misctf functions get value change callbacks, controlled by the tf_asyncon and tf_asyncoff functions. */ if (tf->misctf && ((arg_i = vpi_iterate(vpiArgument, cur_instance)) != NULL)) { int paramvc = 1; cb_data.reason = cbValueChange; while ((arg_h = vpi_scan(arg_i)) != NULL) { /* replicate user_data for each instance */ p_pli_data dp = new_pli_data(tf, cur_instance, paramvc++); cb_data.user_data = (PLI_BYTE8*)dp; cb_data.obj = arg_h; vpi_register_cb(&cb_data); } } /* * Since we are in compiletf, checktf and misctf need to * be executed. Check runs first to match other simulators. */ if (tf->checktf) { if (pli_trace) { fprintf(pli_trace, "Call %s->checktf(reason_checktf)\n", tf->tfname); } rtn = tf->checktf(tf->data, reason_checktf); } if (tf->misctf) { if (pli_trace) { fprintf(pli_trace, "Call %s->misctf" "(user_data=%d, reason=%d, paramvc=%d)\n", tf->tfname, tf->data, reason_endofcompile, 0); } tf->misctf(tf->data, reason_endofcompile, 0); } cur_instance = 0; return rtn; } /* * This function is the wrapper for the veriusertfs calltf routine. */ static PLI_INT32 calltf(ICARUS_VPI_CONST PLI_BYTE8*data) { int rc = 0; p_tfcell tf; /* cast back from opaque */ tf = (p_tfcell)data; /* get call handle */ cur_instance = vpi_handle(vpiSysTfCall, NULL); /* execute calltf */ if (tf->calltf) { if (pli_trace) { fprintf(pli_trace, "Call %s->calltf(%d, %d)\n", tf->tfname, tf->data, reason_calltf); } rc = tf->calltf(tf->data, reason_calltf); } cur_instance = 0; return rc; } /* * This function is the wrapper for the veriusertfs sizetf routine. */ static PLI_INT32 sizetf(ICARUS_VPI_CONST PLI_BYTE8*data) { int rc = 32; p_tfcell tf; /* cast back from opaque */ tf = (p_tfcell)data; /* get call handle */ cur_instance = vpi_handle(vpiSysTfCall, NULL); /* execute sizetf */ if (tf->sizetf) { if (pli_trace) { fprintf(pli_trace, "Call %s->sizetf(%d, %d)\n", tf->tfname, tf->data, reason_sizetf); } rc = tf->sizetf(tf->data, reason_sizetf); } cur_instance = 0; return rc; } /* * This function is the wrapper for all the misctf callbacks */ extern int async_misctf_enable; static PLI_INT32 callback(p_cb_data data) { p_pli_data pli; p_tfcell tf; int reason; int paramvc = 0; PLI_INT32 rc; /* not enabled */ if (data->reason == cbValueChange && !async_misctf_enable) return 0; /* cast back from opaque */ pli = (p_pli_data)data->user_data; tf = pli->tf; cur_instance = pli->call_handle; switch (data->reason) { case cbValueChange: reason = reason_paramvc; paramvc = pli->paramvc; break; case cbEndOfSimulation: reason = reason_finish; break; case cbReadWriteSynch: reason = reason_synch; break; case cbReadOnlySynch: reason = reason_rosynch; break; case cbAfterDelay: reason = reason_reactivate; break; default: reason = -1; assert(0); } if (pli_trace) { fprintf(pli_trace, "Call %s->misctf" "(user_data=%d, reason=%d, paramvc=%d)\n", tf->tfname, tf->data, reason, paramvc); } /* execute misctf */ rc = (tf->misctf) ? tf->misctf(tf->data, reason, paramvc) : 0; cur_instance = 0; return rc; } PLI_INT32 tf_isynchronize(void*obj) { vpiHandle sys = (vpiHandle)obj; p_pli_data pli = vpi_get_userdata(sys); s_cb_data cb; s_vpi_time ti; ti.type = vpiSuppressTime; cb.reason = cbReadWriteSynch; cb.cb_rtn = callback; cb.obj = sys; cb.time = &ti; cb.user_data = (PLI_BYTE8*)pli; vpi_register_cb(&cb); if (pli_trace) fprintf(pli_trace, "tf_isynchronize(%p) --> %d\n", obj, 0); return 0; } PLI_INT32 tf_synchronize(void) { return tf_isynchronize(tf_getinstance()); } PLI_INT32 tf_irosynchronize(void*obj) { vpiHandle sys = (vpiHandle)obj; p_pli_data pli = vpi_get_userdata(sys); s_cb_data cb; s_vpi_time ti = {vpiSuppressTime, 0, 0, 0.0}; cb.reason = cbReadOnlySynch; cb.cb_rtn = callback; cb.obj = sys; cb.time = &ti; cb.user_data = (PLI_BYTE8*)pli; vpi_register_cb(&cb); if (pli_trace) fprintf(pli_trace, "tf_irosynchronize(%p) --> %d\n", obj, 0); return 0; } PLI_INT32 tf_rosynchronize(void) { return tf_irosynchronize(tf_getinstance()); } PLI_INT32 tf_isetrealdelay(double dly, void*obj) { vpiHandle sys = (vpiHandle)obj; p_pli_data pli = vpi_get_userdata(sys); s_cb_data cb; s_vpi_time ti = {vpiSimTime, 0, 0, 0.0}; /* Scale delay to SimTime */ ivl_u64_t delay = ((dly / pow(10, tf_gettimeunit() - tf_gettimeprecision())) + 0.5); ti.high = delay >> 32 & 0xffffffff; ti.low = delay & 0xffffffff; cb.reason = cbAfterDelay; cb.cb_rtn = callback; cb.obj = sys; cb.time = &ti; cb.user_data = (PLI_BYTE8*)pli; vpi_register_cb(&cb); if (pli_trace) fprintf(pli_trace, "tf_isetrealdelay(%f, %p) --> %d\n", dly, obj, 0); return 0; } PLI_INT32 tf_setrealdelay(double dly) { return tf_isetrealdelay(dly, tf_getinstance()); } iverilog-12_0/libveriuser/workarea.c000066400000000000000000000034331435245347300176640ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 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 # include # include "ivl_alloc.h" #include "priv.h" /* * Keep a list of sys handle to work area bindings. */ struct workarea_cell { vpiHandle sys; void* area; struct workarea_cell*next; }; static struct workarea_cell*area_list = 0; PLI_INT32 tf_setworkarea(void*workarea) { struct workarea_cell*cur; cur = area_list; while (cur) { if (cur->sys == cur_instance) { cur->area = workarea; return 0; } cur = cur->next; } cur = calloc(1, sizeof (struct workarea_cell)); cur->next = area_list; cur->sys = cur_instance; cur->area = workarea; area_list = cur; return 0; } PLI_BYTE8* tf_getworkarea(void) { struct workarea_cell*cur; cur = area_list; while (cur) { if (cur->sys == cur_instance) { return cur->area; } cur = cur->next; } return 0; } iverilog-12_0/link_const.cc000066400000000000000000000214251435245347300160250ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 "netlist.h" # include "netmisc.h" # include "ivl_assert.h" using namespace std; /* * Scan the link for drivers. If there are only constant drivers, then * the nexus has a known constant value. */ bool Nexus::drivers_constant() const { if (driven_ == VAR) return false; if (driven_ != NO_GUESS) return true; unsigned constant_drivers = 0; for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { /* A target of a procedural assign or force statement can't be treated as constant. */ const NetNet*sig = dynamic_cast(cur->get_obj()); if (sig && (sig->peek_lref() > 0)) { driven_ = VAR; return false; } /* If we are connected to a tran, there may be a driver on the other side of the tran. We could try checking for this, but for now, be pessimistic. */ if (dynamic_cast(cur->get_obj())) { driven_ = VAR; return false; } Link::DIR cur_dir = cur->get_dir(); if (cur_dir == Link::INPUT) continue; /* If this is an input or inout port of a root module, then this is probably not a constant value. I certainly don't know what the value is, anyhow. This can happen in cases like this: module main(sig); input sig; endmodule If main is a root module (it has no parent) then sig is not constant because it connects to an unspecified outside world. */ if (cur_dir == Link::PASSIVE) { if (sig == 0 || sig->scope()->parent() != 0) continue; if (sig->port_type() == NetNet::NOT_A_PORT) continue; if (sig->port_type() == NetNet::POUTPUT) continue; driven_ = VAR; return false; } /* If there is an implicit pullup/pulldown on a net, count it as a constant driver. */ if (sig) switch (sig->type()) { case NetNet::SUPPLY0: case NetNet::TRI0: constant_drivers += 1; driven_ = V0; continue; case NetNet::SUPPLY1: case NetNet::TRI1: constant_drivers += 1; driven_ = V1; continue; default: break; } const NetSubstitute*ps = dynamic_cast(cur->get_obj()); if (ps) { if (ps->pin(1).nexus()->drivers_constant() && ps->pin(2).nexus()->drivers_constant() ) { constant_drivers += 1; continue; } driven_ = VAR; return false; } if (! dynamic_cast(cur->get_obj())) { driven_ = VAR; return false; } constant_drivers += 1; } /* If there is more than one constant driver for this nexus, we would need to resolve the constant value, taking into account the drive strengths. This is a lot of work for something that will rarely occur, so for now leave the resolution to be done at run time. */ if (constant_drivers > 1) { driven_ = VAR; return false; } return true; } verinum::V Nexus::driven_value() const { switch (driven_) { case V0: return verinum::V0; case V1: return verinum::V1; case Vx: return verinum::Vx; case Vz: return verinum::Vz; case VAR: assert(0); break; case NO_GUESS: break; } const Link*cur = list_; verinum::V val = verinum::Vz; for (cur = first_nlink() ; cur ; cur = cur->next_nlink()) { const NetConst*obj; const NetNet*sig; if ((obj = dynamic_cast(cur->get_obj()))) { // Multiple drivers are not currently supported. ivl_assert(*obj, val == verinum::Vz); val = obj->value(cur->get_pin()); } else if ((sig = dynamic_cast(cur->get_obj()))) { // If we find an implicit pullup or pulldown on a // net, this is a good guess for the driven value, // but keep looking for other drivers. if ((sig->type() == NetNet::SUPPLY0) || (sig->type() == NetNet::TRI0)) { // Multiple drivers are not currently supported. ivl_assert(*sig, val == verinum::Vz); val = verinum::V0; } if ((sig->type() == NetNet::SUPPLY1) || (sig->type() == NetNet::TRI1)) { // Multiple drivers are not currently supported. ivl_assert(*sig, val == verinum::Vz); val = verinum::V1; } } } /* Cache the result. */ switch (val) { case verinum::V0: driven_ = V0; break; case verinum::V1: driven_ = V1; break; case verinum::Vx: driven_ = Vx; break; case verinum::Vz: driven_ = Vz; break; } return val; } verinum Nexus::driven_vector() const { const Link*cur = list_; verinum val; verinum pval; unsigned width = 0; for (cur = first_nlink() ; cur ; cur = cur->next_nlink()) { const NetSubstitute*ps; const NetConst*obj; const NetNet*sig; if ((obj = dynamic_cast(cur->get_obj()))) { // Multiple drivers are not currently supported. ivl_assert(*obj, val.len() == 0); ivl_assert(*obj, cur->get_pin() == 0); val = obj->value(); width = val.len(); } else if ((ps = dynamic_cast(cur->get_obj()))) { if (cur->get_pin() != 0) continue; // Multiple drivers are not currently supported. ivl_assert(*ps, val.len() == 0); val = ps->pin(1).nexus()->driven_vector(); pval = ps->pin(2).nexus()->driven_vector(); for (unsigned idx = 0; idx < pval.len(); idx += 1) val.set(ps->base() + idx, pval.get(idx)); width = val.len(); } else if ((sig = dynamic_cast(cur->get_obj()))) { width = sig->vector_width(); // If we find an implicit pullup or pulldown on a // net, this is a good guess for the driven value, // but keep looking for other drivers. if ((sig->type() == NetNet::SUPPLY0) || (sig->type() == NetNet::TRI0)) { // Multiple drivers are not currently supported. ivl_assert(*sig, val.len() == 0); val = verinum(verinum::V0, width); } if ((sig->type() == NetNet::SUPPLY1) || (sig->type() == NetNet::TRI1)) { // Multiple drivers are not currently supported. ivl_assert(*sig, val.len() == 0); val = verinum(verinum::V1, width); } } } // If we have a width but not a value, this must be an undriven net. if (val.len() != width) val = verinum(verinum::Vz, width); return val; } /* * Calculate a vector that represent all the bits of the vector, with * each driven bit set to true, otherwise false. */ vector Nexus::driven_mask(void) const { vector mask (vector_width()); for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { Link::DIR link_dir = cur->get_dir(); if (link_dir==Link::PASSIVE) continue; if (link_dir==Link::INPUT) continue; const NetPins*obj = cur->get_obj(); // If the link is to a variable (REG or INTEGER) then // the variable is driving all the bits. We have our // complete answer, mark all the bits as driven and // finish. Otherwise, we are not going to get new // information from this node, move on. if (const NetNet*sig = dynamic_cast (obj)) { NetNet::Type sig_type = sig->type(); if (sig_type==NetNet::REG) { for (size_t idx = 0 ; idx < mask.size() ; idx += 1) mask[idx] = true; return mask; } continue; } const NetPartSelect*obj_ps = dynamic_cast(obj); if(obj_ps) { if (obj_ps->dir()==NetPartSelect::VP) { if(cur->get_pin() != 0) continue; for (size_t idx = 0 ; idx < mask.size() ; idx += 1) mask[idx] = true; return mask; } else { if (cur->get_pin() != 1) continue; } for (unsigned idx = 0 ; idx < obj_ps->width() ; idx += 1) { size_t bit = idx + obj_ps->base(); ivl_assert(*obj, bit < mask.size()); mask[bit] = true; } continue; } for (size_t idx = 0 ; idx < mask.size() ; idx += 1) mask[idx] = true; return mask; } return mask; } iverilog-12_0/load_module.cc000066400000000000000000000113771435245347300161530ustar00rootroot00000000000000/* * Copyright (c) 2001-2021 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 "util.h" # include "parse_api.h" # include "compiler.h" # include # include # include # include # include # include # include # include # include # include "ivl_alloc.h" using namespace std; /* * The module library items are maps of key names to file name within * the directory. */ struct module_library { char*dir; bool key_case_sensitive; mapname_map; struct module_library*next; }; static struct module_library*library_list = 0; static struct module_library*library_last = 0; const char dir_character = '/'; extern char depfile_mode; extern FILE *depend_file; /* * Use the type name as a key, and search the module library for a * file name that has that key. */ bool load_module(const char*type, int&parser_errors) { char path[4096]; char*ltype = strdup(type); parser_errors = 0; for (char*tmp = ltype ; *tmp ; tmp += 1) *tmp = tolower(*tmp); for (struct module_library*lcur = library_list ; lcur != 0 ; lcur = lcur->next) { const char*key = lcur->key_case_sensitive? type : ltype; map::const_iterator cur; cur = lcur->name_map.find(key); if (cur == lcur->name_map.end()) continue; snprintf(path, sizeof(path), "%s%c%s", lcur->dir, dir_character, (*cur).second); if(depend_file) { if (depfile_mode == 'p') { fprintf(depend_file, "M %s\n", path); } else if (depfile_mode != 'i') { fprintf(depend_file, "%s\n", path); } fflush(depend_file); } if (verbose_flag) cerr << "Loading library file " << path << "." << endl; parser_errors = pform_parse(path); if (verbose_flag) cerr << "... Load module complete." << endl << flush; return parser_errors == 0; } return false; } /* * This function takes the name of a library directory that the caller * passed, and builds a name index for it. */ int build_library_index(const char*path, bool key_case_sensitive) { DIR*dir = opendir(path); if (dir == 0) return -1; if (verbose_flag) { cerr << "Indexing library: " << path << endl; } struct module_library*mlp = new struct module_library; mlp->dir = strdup(path); mlp->key_case_sensitive = key_case_sensitive; /* Scan the director for files. check each file name to see if it has one of the configured suffixes. If it does, then use the root of the name as the key and index the file name. */ while (struct dirent*de = readdir(dir)) { unsigned namsiz = strlen(de->d_name); char*key = 0; for (list::iterator suf = library_suff.begin() ; suf != library_suff.end() ; ++ suf ) { const char*sufptr = *suf; unsigned sufsiz = strlen(sufptr); if (sufsiz >= namsiz) continue; /* If the directory is case insensitive, then so is the suffix. */ if (key_case_sensitive) { if (strcmp(de->d_name + (namsiz-sufsiz), sufptr) != 0) continue; } else { if (strcasecmp(de->d_name + (namsiz-sufsiz), sufptr) != 0) continue; } key = new char[namsiz-sufsiz+1]; strncpy(key, de->d_name, namsiz-sufsiz); key[namsiz-sufsiz] = 0; break; } if (key == 0) continue; /* If the key is not to be case sensitive, then change it to lowercase. */ if (! key_case_sensitive) for (char*tmp = key ; *tmp ; tmp += 1) *tmp = tolower(*tmp); mlp->name_map[key] = strdup(de->d_name); delete[]key; } closedir(dir); if (library_last) { assert(library_list); library_last->next = mlp; mlp->next = 0; library_last = mlp; } else { library_list = mlp; library_last = mlp; mlp->next = 0; } return 0; } iverilog-12_0/lpm.txt000066400000000000000000000022221435245347300146760ustar00rootroot00000000000000 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-12_0/main.cc000066400000000000000000001114641435245347300146110ustar00rootroot00000000000000const char COPYRIGHT[] = "Copyright (c) 1998-2021 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 "version_base.h" # include "version_tag.h" const char NOTICE[] = " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; # include # include # include # include # include # include # include # include # include #if defined(HAVE_TIMES) # include #endif #if defined(HAVE_GETOPT_H) # include #endif # include "pform.h" # include "parse_api.h" # include "PGenerate.h" # include "netlist.h" # include "target.h" # include "compiler.h" # include "discipline.h" # include "t-dll.h" using namespace std; #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H) extern "C" int getopt(int argc, char*argv[], const char*fmt); extern "C" int optind; extern "C" const char*optarg; #endif #if defined(__CYGWIN__) && !defined(HAVE_GETOPT_H) extern "C" int getopt(int argc, char*argv[], const char*fmt); extern "C" int optind; extern "C" const char*optarg; #endif #if defined(TRAP_SIGINT_FOR_DEBUG) /* * This is a debugging aid. Do not compile it in general, but leave it * here for those days when I need the ability to cleanly exit on a * signal interrupt. */ # include static void signals_handler(int sig) { fprintf(stderr, "Exit on signal %d\n", sig); exit(1); } #endif # include "ivl_alloc.h" /* Count errors detected in flag processing. */ unsigned flag_errors = 0; static unsigned long pre_process_fail_count = 0; const char*basedir = strdup("."); /* * These are the language support control flags. These support which * language features (the generation) to support. The generation_flag * is a major mode, and the gn_* flags control specific sub-features. */ generation_t generation_flag = GN_DEFAULT; bool gn_icarus_misc_flag = true; bool gn_cadence_types_flag = true; bool gn_specify_blocks_flag = true; bool gn_supported_assertions_flag = true; bool gn_unsupported_assertions_flag = true; bool gn_io_range_error_flag = true; bool gn_strict_ca_eval_flag = false; bool gn_strict_expr_width_flag = false; bool gn_shared_loop_index_flag = true; bool gn_verilog_ams_flag = false; /* * For some generations we allow a system function to be called * as a task and only print a warning message. The default for * this is that it is a run time error. */ ivl_sfunc_as_task_t def_sfunc_as_task = IVL_SFUNC_AS_TASK_ERROR; map flags; char*vpi_module_list = 0; void add_vpi_module(const char*name) { if (vpi_module_list == 0) { vpi_module_list = strdup(name); } else { char*tmp = (char*)realloc(vpi_module_list, strlen(vpi_module_list) + strlen(name) + 2); strcat(tmp, ","); strcat(tmp, name); vpi_module_list = tmp; } flags["VPI_MODULE_LIST"] = vpi_module_list; load_vpi_module(name); } map missing_modules; map library_file_map; vector source_files; list library_suff; list roots; char*ivlpp_string = 0; char depfile_mode = 'a'; char* depfile_name = NULL; FILE *depend_file = NULL; /* * These are the warning enable flags. */ bool warn_implicit = false; bool warn_implicit_dimensions = false; bool warn_timescale = false; bool warn_portbinding = false; bool warn_inf_loop = false; bool warn_ob_select = false; bool warn_sens_entire_vec = false; bool warn_sens_entire_arr = false; bool warn_anachronisms = false; bool warn_floating_nets = false; /* * Ignore errors about missing modules */ bool ignore_missing_modules = false; /* * Debug message class flags. */ bool debug_scopes = false; bool debug_eval_tree = false; bool debug_elaborate = false; bool debug_emit = false; bool debug_synth2 = false; bool debug_optimizer = false; /* * Compilation control flags. */ bool separate_compilation = false; /* * Optimization control flags. */ unsigned opt_const_func = 0; /* * Miscellaneous flags. */ bool disable_virtual_pins = false; unsigned long array_size_limit = 16777216; // Minimum required by IEEE-1364? unsigned recursive_mod_limit = 10; bool disable_concatz_generation = false; /* * Verbose messages enabled. */ bool verbose_flag = false; unsigned integer_width = 32; /* * Width limit for unsized expressions. */ unsigned width_cap = 65536; int def_ts_units = 0; int def_ts_prec = 0; /* * Keep a heap of identifier strings that I encounter. This is a more * efficient way to allocate those strings. */ StringHeapLex lex_strings; StringHeapLex filename_strings; StringHeapLex bits_strings; /* * In library searches, Windows file names are never case sensitive. */ #if defined(__MINGW32__) const bool CASE_SENSITIVE = false; #else const bool CASE_SENSITIVE = true; #endif /* * Are we doing synthesis? */ bool synthesis = false; extern void cprop(Design*des); extern void exposenodes(Design*des); extern void synth(Design*des); extern void synth2(Design*des); extern void syn_rules(Design*des); extern void nodangle(Design*des); typedef void (*net_func)(Design*); static struct net_func_map { const char*name; void (*func)(Design*); } func_table[] = { { "cprop", &cprop }, { "exposenodes", &exposenodes }, { "nodangle", &nodangle }, { "synth", &synth }, { "synth2", &synth2 }, { "syn-rules", &syn_rules }, { 0, 0 } }; queue net_func_queue; net_func name_to_net_func(const string&name) { for (unsigned idx = 0 ; func_table[idx].name ; idx += 1) if (name == func_table[idx].name) return func_table[idx].func; return 0; } const char *net_func_to_name(const net_func func) { for (unsigned idx = 0 ; func_table[idx].name ; idx += 1) if (func == func_table[idx].func) return func_table[idx].name; return "This cannot happen"; } static void process_generation_flag(const char*gen) { if (strcmp(gen,"1") == 0) { // FIXME: Deprecated for 1995 generation_flag = GN_VER1995; } else if (strcmp(gen,"2") == 0) { // FIXME: Deprecated for 2001 generation_flag = GN_VER2001; } else if (strcmp(gen,"2x") == 0) { // FIXME: Deprecated for 2001 generation_flag = GN_VER2001; gn_icarus_misc_flag = true; } else if (strcmp(gen,"1995") == 0) { generation_flag = GN_VER1995; } else if (strcmp(gen,"2001") == 0) { generation_flag = GN_VER2001; } else if (strcmp(gen,"2001-noconfig") == 0) { generation_flag = GN_VER2001_NOCONFIG; } else if (strcmp(gen,"2005") == 0) { generation_flag = GN_VER2005; } else if (strcmp(gen,"2005-sv") == 0) { generation_flag = GN_VER2005_SV; } else if (strcmp(gen,"2009") == 0) { generation_flag = GN_VER2009; } else if (strcmp(gen,"2012") == 0) { generation_flag = GN_VER2012; } else if (strcmp(gen,"icarus-misc") == 0) { gn_icarus_misc_flag = true; } else if (strcmp(gen,"no-icarus-misc") == 0) { gn_icarus_misc_flag = false; } else if (strcmp(gen,"xtypes") == 0) { gn_cadence_types_flag = true; } else if (strcmp(gen,"no-xtypes") == 0) { gn_cadence_types_flag = false; } else if (strcmp(gen,"specify") == 0) { gn_specify_blocks_flag = true; } else if (strcmp(gen,"no-specify") == 0) { gn_specify_blocks_flag = false; } else if (strcmp(gen,"assertions") == 0) { gn_supported_assertions_flag = true; gn_unsupported_assertions_flag = true; } else if (strcmp(gen,"supported-assertions") == 0) { gn_supported_assertions_flag = true; gn_unsupported_assertions_flag = false; } else if (strcmp(gen,"no-assertions") == 0) { gn_supported_assertions_flag = false; gn_unsupported_assertions_flag = false; } else if (strcmp(gen,"verilog-ams") == 0) { gn_verilog_ams_flag = true; } else if (strcmp(gen,"no-verilog-ams") == 0) { gn_verilog_ams_flag = false; } else if (strcmp(gen,"io-range-error") == 0) { gn_io_range_error_flag = true; } else if (strcmp(gen,"no-io-range-error") == 0) { gn_io_range_error_flag = false; } else if (strcmp(gen,"strict-ca-eval") == 0) { gn_strict_ca_eval_flag = true; } else if (strcmp(gen,"no-strict-ca-eval") == 0) { gn_strict_ca_eval_flag = false; } else if (strcmp(gen,"strict-expr-width") == 0) { gn_strict_expr_width_flag = true; } else if (strcmp(gen,"no-strict-expr-width") == 0) { gn_strict_expr_width_flag = false; } else if (strcmp(gen,"shared-loop-index") == 0) { gn_shared_loop_index_flag = true; } else if (strcmp(gen,"no-shared-loop-index") == 0) { gn_shared_loop_index_flag = false; } else { } } static void parm_to_flagmap(const string&flag) { string key; const char*value; unsigned off = flag.find('='); if (off > flag.size()) { key = flag; value = strdup(""); } else { key = flag.substr(0, off); value = strdup(flag.substr(off+1).c_str()); } flags[key] = value; } static void find_module_mention(map&check_map, Module*m); static void find_module_mention(map&check_map, PGenerate*s); /* * Convert a string to a time unit or precision. * * Returns true on failure. */ static bool get_ts_const(const char*&cp, int&res, bool is_units) { /* Check for the 1 digit. */ if (*cp != '1') { if (is_units) { cerr << "Error: Invalid +timescale units constant " "(1st digit)." << endl; } else { cerr << "Error: Invalid +timescale precision constant " "(1st digit)." << endl; } return true; } cp += 1; /* Check the number of zeros after the 1. */ res = strspn(cp, "0"); if (res > 2) { if (is_units) { cerr << "Error: Invalid +timescale units constant " "(number of zeros)." << endl; } else { cerr << "Error: Invalid +timescale precision constant " "(number of zeros)." << endl; } return true; } cp += res; /* Now process the scaling string. */ if (strncmp("s", cp, 1) == 0) { res -= 0; cp += 1; return false; } else if (strncmp("ms", cp, 2) == 0) { res -= 3; cp += 2; return false; } else if (strncmp("us", cp, 2) == 0) { res -= 6; cp += 2; return false; } else if (strncmp("ns", cp, 2) == 0) { res -= 9; cp += 2; return false; } else if (strncmp("ps", cp, 2) == 0) { res -= 12; cp += 2; return false; } else if (strncmp("fs", cp, 2) == 0) { res -= 15; cp += 2; return false; } if (is_units) { cerr << "Error: Invalid +timescale units scale." << endl; } else { cerr << "Error: Invalid +timescale precision scale." << endl; } return true; } /* * Process a string with the following form (no space allowed): * * num = < '1' | '10' | '100' > * scale = < 's' | 'ms' | 'us' | 'ns' | 'ps' | 'fs' > * * " '/' * * and set the default time units and precision if successful. * * Return true if we have an error processing the timescale string. */ static bool set_default_timescale(const char*ts_string) { /* Because this came from a command file we can not have embedded * space in this string. */ const char*cp = ts_string; int units = 0; int prec = 0; /* Get the time units. */ if (get_ts_const(cp, units, true)) return true; /* Skip the '/'. */ if (*cp != '/') { cerr << "Error: +timescale separator '/' is missing." << endl; return true; } cp += 1; /* Get the time precision. */ if (get_ts_const(cp, prec, false)) return true; /* The time unit must be greater than or equal to the precision. */ if (units < prec) { cerr << "Error: +timescale unit must not be less than the " "precision." << endl; return true; } /* We have valid units and precision so set the global defaults. */ def_ts_units = units; def_ts_prec = prec; return false; } /* * Read the contents of a config file. This file is a temporary * configuration file made by the compiler driver to carry the bulky * flags generated from the user. This reduces the size of the command * line needed to invoke ivl. * * Each line of the iconfig file has the format: * * : * * The is all the text after the ':' and up to but not * including the end of the line. Thus, white spaces and ':' * characters may appear here. * * The valid keys are: * * -y: * -yl: * -Y: * * -T: * Select which expression to use. * * -t: (obsolete) * Usually, "-t:dll" * * basedir: * Location to look for installed sub-components * * debug: * Activate a class of debug messages. * * depfile: * Give the path to an output dependency file. * * flag:= * Generic compiler flag strings. * * functor: * Append a named functor to the processing path. * * generation:<1|2|2x|xtypes|no-xtypes|specify|no-specify> * This is the generation flag * * ivlpp: * This specifies the ivlpp command line used to process * library modules as I read them in. * * iwidth: * This specifies the width of integer variables. (that is, * variables declared using the "integer" keyword.) * * library_file: * This marks that a source file with the given path is a * library. Any modules in that file are marked as library * modules. * * module: * Load a VPI module. * * out: * Path to the output file. * * sys_func: * Path to a system functions descriptor table * * root: * Specify a root module. There may be multiple of this. * * warnings: * Warning flag letters. * * ignore_missing_modules: * true to ignore errors about missing modules */ bool had_timescale = false; static void read_iconfig_file(const char*ipath) { char buf[8*1024]; vector > to_build_library_index; FILE*ifile = fopen(ipath, "r"); if (ifile == 0) { cerr << "ERROR: Unable to read config file: " << ipath << endl; return; } while (fgets(buf, sizeof buf, ifile) != 0) { assert(strlen(buf) < sizeof buf); if ((strlen(buf) == ((sizeof buf) - 1)) && buf[sizeof buf -2] != '\n') { cerr << "WARNING: Line buffer overflow reading iconfig file: " << ipath << "." << endl; assert(0); } if (buf[0] == '#') continue; char*cp = strchr(buf, ':'); if (cp == 0) continue; *cp++ = 0; char*ep = cp + strlen(cp); while (ep > cp) { ep -= 1; switch (*ep) { case '\r': case '\n': case ' ': case '\t': *ep = 0; break; default: ep = cp; } } if (strcmp(buf, "basedir") == 0) { free((void *)basedir); basedir = strdup(cp); } else if (strcmp(buf, "debug") == 0) { if (strcmp(cp, "scopes") == 0) { debug_scopes = true; cerr << "debug: Enable scopes debug" << endl; } else if (strcmp(cp,"eval_tree") == 0) { debug_eval_tree = true; cerr << "debug: Enable eval_tree debug" << endl; } else if (strcmp(cp,"elaborate") == 0) { debug_elaborate = true; cerr << "debug: Enable elaborate debug" << endl; } else if (strcmp(cp,"emit") == 0) { debug_emit = true; cerr << "debug: Enable emit debug" << endl; } else if (strcmp(cp,"synth2") == 0) { debug_synth2 = true; cerr << "debug: Enable synth2 debug" << endl; } else if (strcmp(cp,"optimizer") == 0) { debug_optimizer = true; cerr << "debug: Enable optimizer debug" << endl; } else { } } else if (strcmp(buf, "depmode") == 0) { depfile_mode = *cp; } else if (strcmp(buf, "depfile") == 0) { depfile_name = strdup(cp); } else if (strcmp(buf, "flag") == 0) { string parm = cp; parm_to_flagmap(parm); } else if (strcmp(buf,"functor") == 0) { if (strncmp(cp, "synth", 5) == 0) { synthesis = true; // We are doing synthesis. } net_func tmp = name_to_net_func(cp); if (tmp == 0) { cerr << "No such design transform function ``" << cp << "''." << endl; flag_errors += 1; break; } net_func_queue.push(tmp); } else if (strcmp(buf, "generation") == 0) { process_generation_flag(cp); } else if (strcmp(buf, "ivlpp") == 0) { ivlpp_string = strdup(cp); } else if (strcmp(buf, "iwidth") == 0) { integer_width = strtoul(cp,0,10); } else if (strcmp(buf, "widthcap") == 0) { width_cap = strtoul(cp,0,10); } else if (strcmp(buf, "library_file") == 0) { perm_string path = filename_strings.make(cp); library_file_map[path] = true; } else if (strcmp(buf,"module") == 0) { add_vpi_module(cp); } else if (strcmp(buf, "out") == 0) { free((void *)flags["-o"]); flags["-o"] = strdup(cp); } else if (strcmp(buf, "sys_func") == 0) { load_sys_func_table(cp); } else if (strcmp(buf, "root") == 0) { roots.push_back(lex_strings.make(cp)); } else if (strcmp(buf,"warnings") == 0) { /* Scan the warnings enable string for warning flags. */ for ( ; *cp ; cp += 1) switch (*cp) { case 'f': warn_floating_nets = true; break; case 'i': warn_implicit = true; break; case 'd': warn_implicit_dimensions = true; break; case 'l': warn_inf_loop = true; break; case 's': warn_ob_select = true; break; case 'p': warn_portbinding = true; break; case 't': warn_timescale = true; break; case 'v': warn_sens_entire_vec = true; break; case 'a': warn_sens_entire_arr = true; break; case 'n': warn_anachronisms = true; break; default: break; } } else if (strcmp(buf, "ignore_missing_modules") == 0) { if (strcmp(cp, "true") == 0) ignore_missing_modules = true; } else if (strcmp(buf, "-y") == 0) { to_build_library_index.push_back(make_pair(strdup(cp), CASE_SENSITIVE)); } else if (strcmp(buf, "-yl") == 0) { to_build_library_index.push_back(make_pair(strdup(cp), false)); } else if (strcmp(buf, "-Y") == 0) { library_suff.push_back(strdup(cp)); } else if (strcmp(buf,"-t") == 0) { // NO LONGER USED } else if (strcmp(buf,"-T") == 0) { if (strcmp(cp,"min") == 0) { min_typ_max_flag = MIN; min_typ_max_warn = 0; } else if (strcmp(cp,"typ") == 0) { min_typ_max_flag = TYP; min_typ_max_warn = 0; } else if (strcmp(cp,"max") == 0) { min_typ_max_flag = MAX; min_typ_max_warn = 0; } else { cerr << "Invalid argument (" << optarg << ") to -T flag." << endl; flag_errors += 1; } } else if (strcmp(buf,"defparam") == 0) { parm_to_defparam_list(cp); } else if (strcmp(buf,"timescale") == 0) { if (had_timescale) { cerr << "Command File: Warning: default timescale " "is being set multiple times." << endl; cerr << " : using the last valid " "+timescale found." << endl; } if (set_default_timescale(cp)) { cerr << " : with +timescale+" << cp << "+" << endl; flag_errors += 1; } else had_timescale = true; } } fclose(ifile); for (vector >::iterator it = to_build_library_index.begin() ; it != to_build_library_index.end() ; ++ it ) { build_library_index(it->first, it->second); free(it->first); } } /* * This function reads a list of source file names. Each name starts * with the first non-space character, and ends with the last non-space * character. Spaces in the middle are OK. */ static void read_sources_file(const char*path) { char line_buf[2048]; FILE*fd = fopen(path, "r"); if (fd == 0) { cerr << "ERROR: Unable to read source file list: " << path << endl; return; } while (fgets(line_buf, sizeof line_buf, fd) != 0) { // assertion test that we are not overflowing the line // buffer. Really should make this more robust, but // better to assert then go weird. assert(strlen(line_buf) < sizeof line_buf); if ((strlen(line_buf) == ((sizeof line_buf) - 1)) && line_buf[sizeof line_buf -2] != '\n') { cerr << "WARNING: Line buffer overflow reading sources file: " << path << "." << endl; assert(0); } char*cp = line_buf + strspn(line_buf, " \t\r\b\f"); char*tail = cp + strlen(cp); while (tail > cp) { if (! isspace((int)tail[-1])) break; tail -= 1; tail[0] = 0; } if (cp < tail) source_files.push_back(filename_strings.make(cp)); } fclose(fd); } extern Design* elaborate(list root); #if defined(HAVE_TIMES) static double cycles_diff(struct tms *a, struct tms *b) { clock_t aa = a->tms_utime + a->tms_stime + a->tms_cutime + a->tms_cstime; clock_t bb = b->tms_utime + b->tms_stime + b->tms_cutime + b->tms_cstime; return (aa-bb)/(double)sysconf(_SC_CLK_TCK); } #else // ! defined(HAVE_TIMES) // Provide dummies struct tms { int x; }; inline static void times(struct tms *) { } inline static double cycles_diff(struct tms *, struct tms *) { return 0; } #endif // ! defined(HAVE_TIMES) static void EOC_cleanup(void) { cleanup_sys_func_table(); for (list::iterator suf = library_suff.begin() ; suf != library_suff.end() ; ++ suf ) { free((void *)*suf); } library_suff.clear(); free((void *) basedir); free(ivlpp_string); free(depfile_name); for (map::iterator flg = flags.begin() ; flg != flags.end() ; ++ flg ) { free((void *)flg->second); } flags.clear(); lex_strings.cleanup(); bits_strings.cleanup(); filename_strings.cleanup(); } int main(int argc, char*argv[]) { bool help_flag = false; bool times_flag = false; bool version_flag = false; const char* net_path = 0; const char* pf_path = 0; int opt; struct tms cycles[5]; #if defined(TRAP_SIGINT_FOR_DEBUG) signal(SIGINT, &signals_handler); #endif if( ::getenv("IVL_WAIT_FOR_DEBUGGER") != 0 ) { fprintf( stderr, "Waiting for debugger...\n"); bool debugger_release = false; while( !debugger_release ) { #if defined(__MINGW32__) Sleep(1000); #else sleep(1); #endif } } library_suff.push_back(strdup(".v")); flags["-o"] = strdup("a.out"); min_typ_max_flag = TYP; min_typ_max_warn = 10; while ((opt = getopt(argc, argv, "C:F:f:hN:P:p:Vv")) != EOF) switch (opt) { case 'C': read_iconfig_file(optarg); break; case 'F': read_sources_file(optarg); break; case 'f': parm_to_flagmap(optarg); break; case 'h': help_flag = true; break; case 'N': net_path = optarg; break; case 'P': pf_path = optarg; break; case 'p': parm_to_flagmap(optarg); break; case 'v': verbose_flag = true; # if defined(HAVE_TIMES) times_flag = true; # endif flags["VVP_EXTRA_ARGS"] = strdup(" -v"); break; case 'V': version_flag = true; break; default: flag_errors += 1; break; } if (flag_errors) return flag_errors; if (version_flag) { cout << "\nIcarus Verilog Parser/Elaborator version " << VERSION << " (" << VERSION_TAG << ")" << endl << endl; cout << COPYRIGHT << endl << endl; cout << NOTICE << endl; cout << " FLAGS DLL " << flags["DLL"] << endl; dll_target_obj.test_version(flags["DLL"]); return 0; } if (help_flag) { cout << "Icarus Verilog Parser/Elaborator version " << VERSION << " (" << VERSION_TAG << ")" << endl << "usage: ivl \n" "options:\n" "\t-C Config file from driver.\n" "\t-F List of source files from driver.\n" "\t-h Print usage information, and exit.\n" "\t-N Dump the elaborated netlist to .\n" "\t-P Write the parsed input to .\n" "\t-p Set a parameter value.\n" "\t-v Print progress indications" #if defined(HAVE_TIMES) " and execution times" #endif ".\n" "\t-V Print version and copyright information, and exit.\n" ; return 0; } int arg = optind; while (arg < argc) { perm_string path = filename_strings.make(argv[arg++]); source_files.push_back(path); } if (source_files.empty()) { cerr << "No input files." << endl; return 1; } separate_compilation = source_files.size() > 1; if( depfile_name ) { depend_file = fopen(depfile_name, "a"); if(! depend_file) { perror(depfile_name); } } lexor_keyword_mask = 0; switch (generation_flag) { case GN_VER2012: lexor_keyword_mask |= GN_KEYWORDS_1800_2012; // fallthrough case GN_VER2009: lexor_keyword_mask |= GN_KEYWORDS_1800_2009; // fallthrough case GN_VER2005_SV: lexor_keyword_mask |= GN_KEYWORDS_1800_2005; // fallthrough case GN_VER2005: lexor_keyword_mask |= GN_KEYWORDS_1364_2005; // fallthrough case GN_VER2001: lexor_keyword_mask |= GN_KEYWORDS_1364_2001_CONFIG; // fallthrough case GN_VER2001_NOCONFIG: lexor_keyword_mask |= GN_KEYWORDS_1364_2001; // fallthrough case GN_VER1995: lexor_keyword_mask |= GN_KEYWORDS_1364_1995; } if (gn_cadence_types_flag) lexor_keyword_mask |= GN_KEYWORDS_ICARUS; if (gn_verilog_ams_flag) lexor_keyword_mask |= GN_KEYWORDS_VAMS_2_3; if (verbose_flag) { if (times_flag) times(cycles+0); cout << "Using language generation: "; switch (generation_flag) { case GN_VER1995: cout << "IEEE1364-1995"; break; case GN_VER2001_NOCONFIG: cout << "IEEE1364-2001-noconfig"; break; case GN_VER2001: cout << "IEEE1364-2001"; break; case GN_VER2005: cout << "IEEE1364-2005"; break; case GN_VER2005_SV: cout << "IEEE1800-2005"; break; case GN_VER2009: cout << "IEEE1800-2009"; break; case GN_VER2012: cout << "IEEE1800-2012"; break; } if (gn_verilog_ams_flag) cout << ",verilog-ams"; if (gn_specify_blocks_flag) cout << ",specify"; else cout << ",no-specify"; if (gn_cadence_types_flag) cout << ",xtypes"; else cout << ",no-xtypes"; if (gn_icarus_misc_flag) cout << ",icarus-misc"; else cout << ",no-icarus-misc"; cout << endl << "PARSING INPUT" << endl; } const char *flag_tmp = flags["DISABLE_VIRTUAL_PINS"]; if (flag_tmp) disable_virtual_pins = strcmp(flag_tmp,"true")==0; flag_tmp = flags["ARRAY_SIZE_LIMIT"]; if (flag_tmp) array_size_limit = strtoul(flag_tmp,NULL,0); flag_tmp = flags["RECURSIVE_MOD_LIMIT"]; if (flag_tmp) recursive_mod_limit = strtoul(flag_tmp,NULL,0); flag_tmp = flags["DISABLE_CONCATZ_GENERATION"]; if (flag_tmp) disable_concatz_generation = strcmp(flag_tmp,"true")==0; /* Parse the input. Make the pform. */ int rc = 0; for (unsigned idx = 0; idx < source_files.size(); idx += 1) { rc += pform_parse(source_files[idx]); } if (pf_path) { ofstream out (pf_path); out << "PFORM DUMP NATURES:" << endl; for (map::iterator cur = natures.begin() ; cur != natures.end() ; ++ cur ) { pform_dump(out, (*cur).second); } out << "PFORM DUMP DISCIPLINES:" << endl; for (map::iterator cur = disciplines.begin() ; cur != disciplines.end() ; ++ cur ) { pform_dump(out, (*cur).second); } out << "PFORM DUMP COMPILATION UNITS:" << endl; for (vector::iterator pac = pform_units.begin() ; pac != pform_units.end() ; ++ pac) { pform_dump(out, *pac); } out << "PFORM DUMP PACKAGES:" << endl; for (vector::iterator pac = pform_packages.begin() ; pac != pform_packages.end() ; ++ pac) { pform_dump(out, *pac); } out << "PFORM DUMP MODULES:" << endl; for (map::iterator mod = pform_modules.begin() ; mod != pform_modules.end() ; ++ mod ) { pform_dump(out, (*mod).second); } out << "PFORM DUMP PRIMITIVES:" << endl; for (map::iterator idx = pform_primitives.begin() ; idx != pform_primitives.end() ; ++ idx ) { (*idx).second->dump(out); } } if (rc) { return rc; } if (pre_process_fail_count) { cerr << "Preprocessor failed with " << pre_process_fail_count << " errors." << endl; return pre_process_fail_count; } /* If the user did not give specific module(s) to start with, then look for modules that are not instantiated anywhere. */ if (roots.empty()) { map mentioned_p; map::iterator mod; if (verbose_flag) cout << "LOCATING TOP-LEVEL MODULES" << endl << " "; for (mod = pform_modules.begin() ; mod != pform_modules.end() ; ++ mod ) { find_module_mention(mentioned_p, mod->second); } for (mod = pform_modules.begin() ; mod != pform_modules.end() ; ++ mod ) { if (!(*mod).second->can_be_toplevel()) continue; /* Don't choose modules instantiated in other modules. */ if (mentioned_p[(*mod).second->mod_name()]) continue; /* What's left might as well be chosen as a root. */ if (verbose_flag) cout << " " << (*mod).second->mod_name(); roots.push_back((*mod).second->mod_name()); } if (verbose_flag) cout << endl; } /* If there is *still* no guess for the root module, then give up completely, and complain. */ if (roots.empty()) { cerr << "No top level modules, and no -s option." << endl; return ignore_missing_modules ? 0 : 1; } if (verbose_flag) { if (times_flag) { times(cycles+1); cerr<<" ... done, " <errors > 0)) { if (des != 0) { cerr << des->errors << " error(s) during elaboration." << endl; if (net_path) { ofstream out (net_path); des->dump(out); } } else { cerr << "Elaboration failed" << endl; } goto errors_summary; } des->set_flags(flags); switch(min_typ_max_flag) { case MIN: des->set_delay_sel(Design::MIN); break; case TYP: des->set_delay_sel(Design::TYP); break; case MAX: des->set_delay_sel(Design::MAX); break; default: assert(0); } /* Done with all the pform data. Delete the modules. */ for (map::iterator idx = pform_modules.begin() ; idx != pform_modules.end() ; ++ idx ) { delete (*idx).second; (*idx).second = 0; } if (verbose_flag) { if (times_flag) { times(cycles+2); cerr<<" ... done, " <join_islands(); if (net_path) { if (verbose_flag) cerr<<" dumping netlist to " <dump(out); } if (des->errors) { cerr << des->errors << " error(s) in post-elaboration processing." << endl; return des->errors; } if (verbose_flag) { if (times_flag) { times(cycles+3); cerr<<" ... done, " <emit(&dll_target_obj)) { if (emit_rc > 0) { cerr << "error: Code generation had " << emit_rc << " error(s)." << endl; delete des; EOC_cleanup(); return 1; } if (emit_rc < 0) { cerr << "error: Code generator failure: " << emit_rc << endl; delete des; EOC_cleanup(); return -1; } assert(emit_rc); } if (verbose_flag) { if (times_flag) { times(cycles+4); cerr<<" ... done, " <::const_iterator idx; for (idx = missing_modules.begin() ; idx != missing_modules.end() ; ++ idx ) cerr << " " << (*idx).first << " referenced " << (*idx).second << " times."<< endl; cerr << "***" << endl; } int rtn = des? des->errors : 1; delete des; EOC_cleanup(); return rtn; } static void find_module_mention(map&check_map, Module*mod) { list gates = mod->get_gates(); list::const_iterator gate; for (gate = gates.begin(); gate != gates.end(); ++ gate ) { PGModule*tmp = dynamic_cast(*gate); if (tmp) { // Note that this module has been instantiated check_map[tmp->get_type()] = true; } } list::const_iterator cur; for (cur = mod->generate_schemes.begin() ; cur != mod->generate_schemes.end() ; ++ cur ) { find_module_mention(check_map, *cur); } } static void find_module_mention(map&check_map, PGenerate*schm) { list::const_iterator gate; for (gate = schm->gates.begin(); gate != schm->gates.end(); ++ gate ) { PGModule*tmp = dynamic_cast(*gate); if (tmp) { // Note that this module has been instantiated check_map[tmp->get_type()] = true; } } list::const_iterator cur; for (cur = schm->generate_schemes.begin() ; cur != schm->generate_schemes.end() ; ++ cur ) { find_module_mention(check_map, *cur); } } void pre_process_failed(const char*text) { const char*num_start = strchr(text, '(') + 1; unsigned long res; char*rem; res = strtoul(num_start, &rem, 10); assert(res > 0); assert(rem[0] == ')'); pre_process_fail_count += res; } iverilog-12_0/mingw-cross.txt000066400000000000000000000016731435245347300163670ustar00rootroot00000000000000 These are instructions for building Icarus Verilog binaries for Windows using mingw cross compiler tools on Linux. To start with, you need the mingw64-cross-* packages for your linux distribution, which gives you the x86_64-w64-mingw32-* commands installed on your system. Installing the cross environment is outside the scope of this writeup. First, configure with this command: $ ./configure --host=x86_64-w64-mingw32 This generates the Makefiles needed to cross compile everything with the mingw32 compiler. The configure script will generate the command name paths, so long as commands line x86_64-w64-mingw32-gcc et. al. are in your path. Next, compile with the command: $ make The configure generated the cross compiler flags, but there are a few bits that need to be compiled with the native compiler. (version.exe for example is used by the build process but is not installed.) The configure script should have gotten all that right. iverilog-12_0/mingw.txt000066400000000000000000000004411435245347300152300ustar00rootroot00000000000000Please see the following references for instruction on building and installing Icarus Verilog as a native Windows application using the MinGW tools: * README.md in subdir 'msys2' * Icarus Verilog Wiki: http://iverilog.wikia.com/wiki/Installation_Guide#Compiling_on_MS_Windows_.28MinGW.29 iverilog-12_0/mkinstalldirs000077500000000000000000000066471435245347300161720ustar00rootroot00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2006-05-11.19 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' IFS=" "" $nl" errstatus=0 dirmode= usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit $? ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit $? ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because `.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do case $file in /*) pathcomp=/ ;; *) pathcomp= ;; esac oIFS=$IFS IFS=/ set fnord $file shift IFS=$oIFS for d do test "x$d" = x && continue pathcomp=$pathcomp$d case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr= chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp=$pathcomp/ done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: iverilog-12_0/msys2/000077500000000000000000000000001435245347300144245ustar00rootroot00000000000000iverilog-12_0/msys2/PKGBUILD000066400000000000000000000016671435245347300155620ustar00rootroot00000000000000_realname=iverilog pkgbase=mingw-w64-${_realname} pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}" pkgver=ci pkgrel=1 pkgdesc="Icarus Verilog, a Verilog simulation and synthesis tool (mingw-w64)" arch=('any') url="http://iverilog.icarus.com/" license=('GPLv2+') depends=("${MINGW_PACKAGE_PREFIX}-readline" "${MINGW_PACKAGE_PREFIX}-gcc-libs") makedepends=("autoconf" "man-db" "${MINGW_PACKAGE_PREFIX}-gcc" "${MINGW_PACKAGE_PREFIX}-ghostscript") source=() sha256sums=() build() { cd "${srcdir}"/../.. sh autoconf.sh ./configure \ --prefix="${MINGW_PREFIX}" \ --host="$CARCH"-w64-mingw32 mingw32-make } check() { cd "${srcdir}"/../.. mingw32-make check } package() { cd "${srcdir}"/../.. mingw32-make DESTDIR="${pkgdir}" install mkdir -p "${pkgdir}${MINGW_PREFIX}/share/doc/${_realname}" mv "${pkgdir}${MINGW_PREFIX}"/*.pdf "${pkgdir}${MINGW_PREFIX}/share/doc/${_realname}" } iverilog-12_0/msys2/README.md000066400000000000000000000051731435245347300157110ustar00rootroot00000000000000# MSYS2 build recipe This subdir contains a [PKGBUILD](https://wiki.archlinux.org/index.php/PKGBUILD) recipe for building iverilog on [MSYS2](https://www.msys2.org/). MSYS2 is a collection of tools and libraries for Windows, which is closely based on the packaging approach in [Arch Linux](https://www.archlinux.org/). Precisely, the package manager in MSYS2 is a port of [pacman](https://wiki.archlinux.org/index.php/pacman). Therefore, the structure of PKGBUILD recipes in MSYS2 is very similar to packages in Arch Linux and the build script (`makepkg-mingw`) is a port of [makepkg](https://wiki.archlinux.org/index.php/makepkg). Other than that, PKGBUILD files are shell scripts containing some specific functions (build, package, check, etc.) and metadata (variables). The build system takes care of dependencies, creating temporary directories, generating a tarball, etc. Therefore, the recommended approach for building iverilog on Windows is the following: ```sh # Install the toolchain pacman -S mingw-w64-x86_64-toolchain # and/or mingw-w64-i686-toolchain # Retrieve iverilog sources. Optionally, retrieve a tarball, or an specific branch/version. git clone https://github.com/steveicarus/iverilog cd iverilog # Call makepkg-mingw from subdir 'msys2'. It will build, check and package iverilog. cd msys2 MINGW_INSTALLS=mingw64 makepkg-mingw --noconfirm --noprogressbar -sCLf # or, set the envvar to 'mingw32', or unset it for building both packages at the same time # Optionally, install the tarball(s)/package(s). Or just distribute it/them. pacman -U --noconfirm *.zst ``` NOTE: the continuous integration workflow in [github.com/steveicarus](https://github.com/steveicarus) uses the procedure above for building iverilog on MINGW32 and MINGW64 each time a commit is pushed or a Pull Request is updated. The two generated packages are uploaded as artifacts. Hence, users willing to test *nightly* builds or specific features, can download and install the tarballs from the corresponding CI run. Nevertheless, the content of functions `build` and `check` in the PKGBUILD file should be familiar for any user willing to build iverilog *manually*. Those can be executed in a shell (ignoring makepkg), as long as the few envvars are properly defined. HINT: this document explains the most straightforward and automatec solution for building iverilog on Windows. However, intermediate and advanced users might want to check [iverilog.fandom.com/wiki/Installation_using_MSYS2](https://iverilog.fandom.com/wiki/Installation_using_MSYS2) for some specific tweaks, such as using a custom prefix for iverilog executables, or using MSYS2 packages/tarballs outside of MSYS2. iverilog-12_0/named.h000066400000000000000000000021631435245347300146060ustar00rootroot00000000000000#ifndef IVL_named_H #define IVL_named_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" /* * There are lots of places where names are attached to objects. This * simple template expresses the lot. */ template struct named { perm_string name; T parm; }; #endif /* IVL_named_H */ iverilog-12_0/net_analog.cc000066400000000000000000000024241435245347300157670ustar00rootroot00000000000000/* * 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 # include # include # include "compiler.h" # include "netlist.h" # include "netmisc.h" # include "ivl_assert.h" NetContribution::NetContribution(NetEAccess*l, NetExpr*r) : lval_(l), rval_(r) { } NetContribution::~NetContribution() { } const NetEAccess* NetContribution::lval() const { return lval_; } const NetExpr* NetContribution::rval() const { return rval_; } iverilog-12_0/net_assign.cc000066400000000000000000000200701435245347300160070ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 "netlist.h" # include "netclass.h" # include "netdarray.h" # include "netenum.h" # include "ivl_assert.h" using namespace std; /* * NetAssign */ unsigned count_lval_width(const NetAssign_*idx) { unsigned wid = 0; while (idx) { wid += idx->lwidth(); idx = idx->more; } return wid; } NetAssign_::NetAssign_(NetAssign_*n) : nest_(n), sig_(0), word_(0), base_(0), sel_type_(IVL_SEL_OTHER) { lwid_ = 0; more = 0; signed_ = false; turn_sig_to_wire_on_release_ = false; } NetAssign_::NetAssign_(NetNet*s) : nest_(0), sig_(s), word_(0), base_(0), sel_type_(IVL_SEL_OTHER) { lwid_ = sig_->vector_width(); sig_->incr_lref(); more = 0; signed_ = false; turn_sig_to_wire_on_release_ = false; } NetAssign_::~NetAssign_() { if (sig_) { sig_->decr_lref(); if (turn_sig_to_wire_on_release_ && sig_->peek_lref() == 0) sig_->type(NetNet::WIRE); } assert( more == 0 ); delete word_; } string NetAssign_::get_fileline() const { if (sig_) return sig_->get_fileline(); else return nest_->get_fileline(); } NetScope*NetAssign_::scope() const { if (sig_) return sig_->scope(); else return nest_->scope(); } void NetAssign_::set_word(NetExpr*r) { assert(word_ == 0); word_ = r; } NetExpr* NetAssign_::word() { return word_; } const NetExpr* NetAssign_::word() const { return word_; } const NetExpr* NetAssign_::get_base() const { return base_; } ivl_select_type_t NetAssign_::select_type() const { return sel_type_; } unsigned NetAssign_::lwidth() const { // This gets me the type of the l-value expression, down to // the type of the member. If this returns nil, then resort to // the lwid_ value. ivl_type_t ntype = net_type(); if (ntype == 0) return lwid_; // If the type is a darray, and there is a word index, then we // actually want the width of the elements. if (const netdarray_t*darray = dynamic_cast (ntype)) { if (word_ == 0) return 1; else return darray->element_width(); } return ntype->packed_width(); } ivl_variable_type_t NetAssign_::expr_type() const { ivl_type_t ntype = net_type(); if (const netdarray_t*darray = dynamic_cast(ntype)) { if (word_ == 0) return IVL_VT_DARRAY; else return darray->element_base_type(); } if (sig_ && sig_->data_type()==IVL_VT_STRING && base_!=0) return IVL_VT_BOOL; if (ntype) return ntype->base_type(); ivl_assert(*this, sig_); return sig_->data_type(); } const ivl_type_s* NetAssign_::net_type() const { if (nest_) { const ivl_type_s*ntype = nest_->net_type(); if (member_.nil()) return ntype; if (const netclass_t*class_type = dynamic_cast(ntype)) { return class_type->get_prop_type(member_idx_); } if (const netdarray_t*darray = dynamic_cast (ntype)) { if (word_ == 0) return ntype; else return darray->element_type(); } return 0; } if (const netclass_t*class_type = sig_->class_type()) { if (member_.nil()) return sig_->net_type(); return class_type->get_prop_type(member_idx_); } if (const netdarray_t*darray = dynamic_cast (sig_->net_type())) { if (word_ == 0) return sig_->net_type(); else return darray->element_type(); } return 0; } const netenum_t*NetAssign_::enumeration() const { const netenum_t*tmp = 0; ivl_type_t ntype = net_type(); if (ntype == 0) { ivl_assert(*this, sig_); // If the base signal is not an enumeration, return nil. if ( (tmp = sig_->enumeration()) == 0 ) return 0; } else { tmp = dynamic_cast(ntype); if (tmp == 0) return 0; } // Part select of an enumeration is not an enumeration. if (base_ != 0) return 0; // Concatenation of enumerations is not an enumeration. if (more != 0) return 0; return tmp; } perm_string NetAssign_::name() const { if (sig_) { return sig_->name(); } else { return perm_string::literal(""); } } NetNet* NetAssign_::sig() const { assert(sig_? nest_==0 : nest_!=0); return sig_; } void NetAssign_::set_part(NetExpr*base, unsigned wid, ivl_select_type_t sel_type) { base_ = base; lwid_ = wid; sel_type_ = sel_type; } void NetAssign_::set_property(const perm_string&mname, unsigned idx) { member_ = mname; member_idx_ = idx; } /* */ void NetAssign_::turn_sig_to_wire_on_release() { turn_sig_to_wire_on_release_ = true; } NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv) : lval_(lv), rval_(rv), delay_(0) { } NetAssignBase::~NetAssignBase() { delete rval_; while (lval_) { NetAssign_*tmp = lval_; lval_ = tmp->more; tmp->more = 0; delete tmp; } } NetExpr* NetAssignBase::rval() { return rval_; } const NetExpr* NetAssignBase::rval() const { return rval_; } void NetAssignBase::set_rval(NetExpr*r) { delete rval_; rval_ = r; } NetAssign_* NetAssignBase::l_val(unsigned idx) { NetAssign_*cur = lval_; while (idx > 0) { if (cur == 0) return cur; cur = cur->more; idx -= 1; } assert(idx == 0); return cur; } const NetAssign_* NetAssignBase::l_val(unsigned idx) const { const NetAssign_*cur = lval_; while (idx > 0) { if (cur == 0) return cur; cur = cur->more; idx -= 1; } assert(idx == 0); return cur; } unsigned NetAssignBase::l_val_count() const { const NetAssign_*cur = lval_; unsigned cnt = 0; while (cur) { cnt += 1; cur = cur->more; } return cnt; } unsigned NetAssignBase::lwidth() const { unsigned sum = 0; for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) sum += cur->lwidth(); return sum; } void NetAssignBase::set_delay(NetExpr*expr) { delay_ = expr; } const NetExpr* NetAssignBase::get_delay() const { return delay_; } NetAssign::NetAssign(NetAssign_*lv, NetExpr*rv) : NetAssignBase(lv, rv), op_(0) { } NetAssign::NetAssign(NetAssign_*lv, char op, NetExpr*rv) : NetAssignBase(lv, rv), op_(op) { } NetAssign::~NetAssign() { } NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv, NetEvWait*ev, NetExpr*cnt) : NetAssignBase(lv, rv) { event_ = ev; count_ = cnt; } NetAssignNB::~NetAssignNB() { } unsigned NetAssignNB::nevents() const { if (event_) return event_->nevents(); return 0; } const NetEvent*NetAssignNB::event(unsigned idx) const { if (event_) return event_->event(idx); return 0; } const NetExpr*NetAssignNB::get_count() const { return count_; } NetCAssign::NetCAssign(NetAssign_*lv, NetExpr*rv) : NetAssignBase(lv, rv) { } NetCAssign::~NetCAssign() { } NetDeassign::NetDeassign(NetAssign_*l) : NetAssignBase(l, 0) { } NetDeassign::~NetDeassign() { } NetForce::NetForce(NetAssign_*lv, NetExpr*rv) : NetAssignBase(lv, rv) { } NetForce::~NetForce() { } NetRelease::NetRelease(NetAssign_*l) : NetAssignBase(l, 0) { } NetRelease::~NetRelease() { } iverilog-12_0/net_design.cc000066400000000000000000001006361435245347300160030ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 # include # include /* * This source file contains all the implementations of the Design * class declared in netlist.h. */ # include "netlist.h" # include "netscalar.h" # include "netvector.h" # include "util.h" # include "compiler.h" # include "netmisc.h" # include "PExpr.h" # include "PTask.h" # include # include "ivl_assert.h" using namespace std; Design:: Design() : errors(0), nodes_(0), procs_(0), aprocs_(0) { branches_ = 0; procs_idx_ = 0; des_precision_ = 0; nodes_functor_cur_ = 0; nodes_functor_nxt_ = 0; des_delay_sel_ = Design::TYP; } Design::~Design() { } void Design::set_precision(int val) { if (val < des_precision_) des_precision_ = val; } int Design::get_precision() const { return des_precision_; } void Design::set_delay_sel(delay_sel_t sel) { des_delay_sel_ = sel; } const char* Design::get_delay_sel() const { switch (des_delay_sel_) { case Design::MIN: return "MINIMUM"; break; case Design::TYP: return "TYPICAL"; break; case Design::MAX: return "MAXIMUM"; break; default: assert(0); return "TYPICAL"; } } uint64_t Design::scale_to_precision(uint64_t val, const NetScope*scope) const { int units = scope->time_unit(); assert( units >= des_precision_ ); while (units > des_precision_) { units -= 1; val *= 10; } return val; } NetScope* Design::make_root_scope(perm_string root, NetScope*unit_scope, bool program_block, bool is_interface) { NetScope *root_scope_; root_scope_ = new NetScope(0, hname_t(root), NetScope::MODULE, unit_scope, false, program_block, is_interface); /* This relies on the fact that the basename return value is permallocated. */ root_scope_->set_module_name(root_scope_->basename()); root_scopes_.push_back(root_scope_); return root_scope_; } NetScope* Design::find_root_scope() { assert(root_scopes_.front()); return root_scopes_.front(); } list Design::find_root_scopes() const { return root_scopes_; } NetScope* Design::make_package_scope(perm_string name, NetScope*unit_scope, bool is_unit) { NetScope*scope; scope = new NetScope(0, hname_t(name), NetScope::PACKAGE, unit_scope, false, false, false, is_unit); scope->set_module_name(scope->basename()); packages_[name] = scope; return scope; } NetScope* Design::find_package(perm_string name) const { map::const_iterator cur = packages_.find(name); if (cur == packages_.end()) return 0; return cur->second; } list Design::find_package_scopes() const { listres; for (map::const_iterator cur = packages_.begin() ; cur != packages_.end() ; ++cur) { res.push_back (cur->second); } return res; } /* * This method locates a scope in the design, given its rooted * hierarchical name. Each component of the key is used to scan one * more step down the tree until the name runs out or the search * fails. */ NetScope* Design::find_scope(const std::list&path) const { if (path.empty()) return 0; for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end(); ++ scope ) { NetScope*cur = *scope; if (path.front() != cur->fullname()) continue; std::list tmp = path; tmp.pop_front(); while (cur) { if (tmp.empty()) return cur; cur = cur->child( tmp.front() ); tmp.pop_front(); } } return 0; } /* * This method locates a scope in the design, given its rooted * hierarchical name. Each component of the key is used to scan one * more step down the tree until the name runs out or the search * fails. */ NetScope* Design::find_scope(const hname_t&path) const { for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end(); ++ scope ) { NetScope*cur = *scope; if (path.peek_name() == cur->basename()) return cur; } return 0; } static bool is_design_unit(NetScope*scope) { return (scope->type() == NetScope::MODULE && !scope->nested_module()) || (scope->type() == NetScope::PACKAGE); } static bool is_subroutine(NetScope::TYPE type) { return type == NetScope::TASK || type == NetScope::FUNC; } /* * This method locates a scope within another scope, given its relative * hierarchical name. Each component of the key is used to scan one * more step down the tree until the name runs out or the search * fails. */ NetScope* Design::find_scope_(NetScope*scope, const std::list&path, NetScope::TYPE type) const { std::list tmp = path; do { hname_t key = tmp.front(); /* If we are looking for a module or we are not * looking at the last path component check for * a name match (second line). */ if (scope->type() == NetScope::MODULE && (type == NetScope::MODULE || tmp.size() > 1) && scope->module_name()==key.peek_name()) { /* Up references may match module name */ } else { NetScope*found_scope = scope->child(key); if (found_scope == 0) { found_scope = scope->find_import(this, key.peek_name()); if (found_scope) found_scope = found_scope->child(key); } scope = found_scope; if (scope == 0) break; } tmp.pop_front(); } while (! tmp.empty()); return scope; } /* * This is a relative lookup of a scope by name. The starting point is * the scope parameter within which I start looking for the scope. If * I do not find the scope within the passed scope, start looking in * parent scopes until I find it, or I run out of parent scopes. */ NetScope* Design::find_scope(NetScope*scope, const std::list&path, NetScope::TYPE type) const { assert(scope); if (path.empty()) return scope; // Record the compilation unit scope for use later. NetScope*unit_scope = scope->unit(); // First search upwards through the hierarchy. while (scope) { NetScope*found_scope = find_scope_(scope, path, type); if (found_scope) return found_scope; // Avoid searching the unit scope twice. if (scope == unit_scope) unit_scope = 0; // Special case - see IEEE 1800-2012 section 23.8.1. if (unit_scope && is_design_unit(scope) && is_subroutine(type)) { found_scope = find_scope_(unit_scope, path, type); if (found_scope) return found_scope; unit_scope = 0; } scope = scope->parent(); } // If we haven't already done so, search the compilation unit scope. if (unit_scope) { NetScope*found_scope = find_scope_(unit_scope, path, type); if (found_scope) return found_scope; } // Last chance. Look for the name starting at the root. return find_scope(path); } /* * This method locates a scope within another scope, given its relative * hierarchical name. Each component of the key is used to scan one * more step down the tree until the name runs out or the search * fails. */ NetScope* Design::find_scope_(NetScope*scope, const hname_t&path, NetScope::TYPE type) const { /* If we are looking for a module or we are not * looking at the last path component check for * a name match (second line). */ if ((scope->type() == NetScope::MODULE) && (type == NetScope::MODULE) && (scope->module_name() == path.peek_name())) { /* Up references may match module name */ return scope; } NetScope*found_scope = scope->child(path); if (found_scope == 0) { found_scope = scope->find_import(this, path.peek_name()); if (found_scope) found_scope = found_scope->child(path); } return found_scope; } /* * This is a relative lookup of a scope by name. The starting point is * the scope parameter within which I start looking for the scope. If * I do not find the scope within the passed scope, start looking in * parent scopes until I find it, or I run out of parent scopes. */ NetScope* Design::find_scope(NetScope*scope, const hname_t&path, NetScope::TYPE type) const { assert(scope); // Record the compilation unit scope for use later. NetScope*unit_scope = scope->unit(); // First search upwards through the hierarchy. while (scope) { NetScope*found_scope = find_scope_(scope, path, type); if (found_scope) return found_scope; // Avoid searching the unit scope twice. if (scope == unit_scope) unit_scope = 0; // Special case - see IEEE 1800-2012 section 23.8.1. if (unit_scope && is_design_unit(scope) && is_subroutine(type)) { found_scope = find_scope_(unit_scope, path, type); if (found_scope) return found_scope; unit_scope = 0; } scope = scope->parent(); } // If we haven't already done so, search the compilation unit scope. if (unit_scope) { NetScope*found_scope = find_scope_(unit_scope, path, type); if (found_scope) return found_scope; } // Last chance. Look for the name starting at the root. listpath_list; path_list.push_back(path); return find_scope(path_list); } /* * This method runs through the scope, noticing the defparam * statements that were collected during the elaborate_scope pass and * applying them to the target parameters. The implementation actually * works by using a specialized method from the NetScope class that * does all the work for me. */ void Design::run_defparams() { for (list::const_iterator scope = root_scopes_.begin(); scope != root_scopes_.end(); ++ scope ) (*scope)->run_defparams(this); } void NetScope::run_defparams(Design*des) { for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->run_defparams(des); while (! defparams.empty()) { pair pp = defparams.front(); defparams.pop_front(); pform_name_t path = pp.first; PExpr*val = pp.second; perm_string perm_name = peek_tail_name(path); path.pop_back(); list eval_path = eval_scope_path(des, this, path); /* If there is no path on the name, then the targ_scope is the current scope. */ NetScope*targ_scope = des->find_scope(this, eval_path); if (targ_scope == 0) { // Push the defparam onto a list for retry // later. It is possible for the scope lookup to // fail if the scope being defparam'd into is // generated by an index array for generate. eval_path.push_back(hname_t(perm_name)); defparams_later.push_back(make_pair(eval_path,val)); continue; } targ_scope->replace_parameter(des, perm_name, val, this, true); } // If some of the defparams didn't find a scope in the name, // then try again later. It may be that the target scope is // created later by generate scheme or instance array. if (! defparams_later.empty()) des->defparams_later.insert(this); } void NetScope::run_defparams_later(Design*des) { set target_scopes; list,PExpr*> > defparams_even_later; while (! defparams_later.empty()) { pair,PExpr*> cur = defparams_later.front(); defparams_later.pop_front(); listeval_path = cur.first; perm_string name = eval_path.back().peek_name(); eval_path.pop_back(); PExpr*val = cur.second; NetScope*targ_scope = des->find_scope(this, eval_path); if (targ_scope == 0) { // If a scope in the target path is not found, // then push this defparam for handling even // later. Maybe a later generate scheme or // instance array will create the scope. defparams_even_later.push_back(cur); continue; } targ_scope->replace_parameter(des, name, val, this, true); // We'll need to re-evaluate parameters in this scope target_scopes.insert(targ_scope); } // The scopes that this defparam set touched will be // re-evaluated later it a top_defparams work item. So do not // do the evaluation now. // If there are some scopes that still have missing scopes, // then save them back into the defparams_later list for a // later pass. defparams_later = defparams_even_later; if (! defparams_later.empty()) des->defparams_later.insert(this); } void Design::evaluate_parameters() { for (map::const_iterator cur = packages_.begin() ; cur != packages_.end() ; ++ cur) { cur->second->evaluate_parameters(this); } for (list::const_iterator scope = root_scopes_.begin() ; scope != root_scopes_.end() ; ++ scope ) { (*scope)->evaluate_parameters(this); } } void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur) { /* Evaluate the parameter expression. */ PExpr*val_expr = (*cur).second.val_expr; NetScope*val_scope = (*cur).second.val_scope; // The param_type may be nil if the parameter has no declared type. In // this case, we'll try to take our type from the r-value. ivl_type_t param_type = cur->second.ivl_type; // Most parameter declarations are packed vectors, of the form: // parameter [H:L] foo == bar; // so get the netvector_t. Note that this may also be the special // case of a netvector_t with no dimensions, that exists only to carry // signed-ness, e.g.: // parameter signed foo = bar; // These will be marked as scalar, but also have the implict flag set. const netvector_t* param_vect = dynamic_cast (param_type); if (debug_elaborate) { cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "parameter=" << cur->first << endl; if (param_type) cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "param_type=" << *param_type << endl; else cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "param_type=(nil)" << endl; cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "val_expr=" << *val_expr << endl; } ivl_variable_type_t use_type; int lv_width = -2; if (param_type) { use_type = param_type->base_type(); // Is this an implicit netvector_t with no dimenions? if (param_vect && param_vect->get_implicit() && param_vect->get_scalar()) lv_width = -2; else if (param_type->packed()) lv_width = param_type->packed_width(); } else { use_type = val_expr->expr_type(); } if (debug_elaborate) { cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "use_type = " << use_type << endl; } NetExpr*expr = elab_and_eval(des, val_scope, val_expr, lv_width, true, cur->second.is_annotatable, use_type); if (! expr) return; // Make sure to carry the signed-ness from a vector type. if (param_vect) expr->cast_signed(param_vect->get_signed()); if (debug_elaborate) { cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "expr = " << *expr << endl; cerr << val_expr->get_fileline() << ": " << __func__ << ": " << "expr type = " << expr->expr_type() << endl; } switch (expr->expr_type()) { case IVL_VT_REAL: if (! dynamic_cast(expr)) { cerr << expr->get_fileline() << ": error: Unable to evaluate real parameter " << (*cur).first << " value: " << *expr << endl; des->errors += 1; return; } // If the parameter has no type, then infer its type from the // r-value expression. if (param_type==0) { param_type = &netreal_t::type_real; cur->second.ivl_type = param_type; } break; case IVL_VT_LOGIC: case IVL_VT_BOOL: if (! dynamic_cast(expr)) { cerr << expr->get_fileline() << ": error: Unable to evaluate parameter " << (*cur).first << " value: " << *expr << endl; des->errors += 1; return; } // If the parameter has no type, then infer its type from the // r-value expression. if (param_type==0) { param_type = new netvector_t(expr->expr_type(), expr->expr_width()-1, 0, expr->has_sign()); cur->second.ivl_type = param_type; } if (param_type->base_type() != IVL_VT_NO_TYPE) expr->cast_signed(param_type->get_signed()); if (!expr->has_width()) { expr = pad_to_width(expr, integer_width, *expr); } else if (param_type->slice_dimensions().size()==0 && !expr->has_width()) { expr = pad_to_width(expr, integer_width, *expr); } break; default: cerr << expr->get_fileline() << ": internal error: " << "Unhandled expression type " << expr->expr_type() << "?" << endl; cerr << expr->get_fileline() << ": : " << "param_type: " << *param_type << endl; des->errors += 1; return; } // By the time we're done with the above, we should certainly know the // type of the parameter. ivl_assert(*expr, cur->second.ivl_type); cur->second.val = expr; // If there are no value ranges to test the value against, // then we are done. if ((*cur).second.range == 0) return; NetEConst*val = dynamic_cast((*cur).second.val); ivl_assert(*expr, val); verinum value = val->value(); bool from_flag = (*cur).second.range == 0? true : false; for (range_t*value_range = (*cur).second.range ; value_range ; value_range = value_range->next) { // If we already know that the value is // within a "from" range, then do not test // any more of the from ranges. if (from_flag && value_range->exclude_flag==false) continue; if (value_range->low_expr) { NetEConst*tmp = dynamic_cast(value_range->low_expr); ivl_assert(*value_range->low_expr, tmp); if (value_range->low_open_flag && value <= tmp->value()) continue; else if (value < tmp->value()) continue; } if (value_range->high_expr) { NetEConst*tmp = dynamic_cast(value_range->high_expr); ivl_assert(*value_range->high_expr, tmp); if (value_range->high_open_flag && value >= tmp->value()) continue; else if (value > tmp->value()) continue; } // Within the range. If this is a "from" // range, then set the from_flag and continue. if (value_range->exclude_flag == false) { from_flag = true; continue; } // OH NO! In an excluded range. signal an error. from_flag = false; break; } // If we found no from range that contains the // value, then report an error. if (! from_flag) { cerr << val->get_fileline() << ": error: " << "Parameter value " << value << " is out of range for parameter " << (*cur).first << "." << endl; des->errors += 1; } } void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur) { PExpr*val_expr = (*cur).second.val_expr; NetScope*val_scope = (*cur).second.val_scope; ivl_type_t param_type = cur->second.ivl_type; ivl_assert(*val_expr, param_type); NetExpr*expr = elab_and_eval(des, val_scope, val_expr, -1, true, cur->second.is_annotatable, param_type->base_type()); if (! expr) return; NetECReal*res = 0; switch (expr->expr_type()) { case IVL_VT_REAL: if (NetECReal*tmp = dynamic_cast(expr)) { res = tmp; } else { cerr << expr->get_fileline() << ": error: " << "Unable to evaluate real parameter " << (*cur).first << " value: " << *expr << endl; des->errors += 1; return; } break; default: cerr << expr->get_fileline() << ": internal error: " << "Failed to cast expression?" << endl; des->errors += 1; return; break; } (*cur).second.val = res; double value = res->value().as_double(); bool from_flag = (*cur).second.range == 0? true : false; for (range_t*value_range = (*cur).second.range ; value_range ; value_range = value_range->next) { if (from_flag && value_range->exclude_flag==false) continue; if (value_range->low_expr) { double tmp; bool flag = eval_as_double(tmp, value_range->low_expr); ivl_assert(*value_range->low_expr, flag); if (value_range->low_open_flag && value <= tmp) continue; else if (value < tmp) continue; } if (value_range->high_expr) { double tmp; bool flag = eval_as_double(tmp, value_range->high_expr); ivl_assert(*value_range->high_expr, flag); if (value_range->high_open_flag && value >= tmp) continue; else if (value > tmp) continue; } if (value_range->exclude_flag == false) { from_flag = true; continue; } // All the above tests failed, so we must have tripped // an exclude rule. from_flag = false; break; } if (! from_flag) { cerr << res->get_fileline() << ": error: " << "Parameter value " << value << " is out of range for real parameter " << (*cur).first << "." << endl; des->errors += 1; } } /* * Evaluate a parameter that is forced to type string. This comes to pass when * the input is something like this: * * parameter string foo = ; * * The param_type should be netstring_t, the val_expr is the pform of the * input , and we try to elaborate/evaluate down to a IVL_VT_STRING * expression. */ void NetScope::evaluate_parameter_string_(Design*des, param_ref_t cur) { PExpr*val_expr = (*cur).second.val_expr; NetScope*val_scope = (*cur).second.val_scope; ivl_type_t param_type = cur->second.ivl_type; ivl_assert(cur->second, val_expr); ivl_assert(cur->second, param_type); NetExpr*expr = elab_and_eval(des, val_scope, val_expr, param_type, true); if (! expr) return; cur->second.val = expr; if (debug_elaborate) { cerr << cur->second.get_fileline() << ": " << __func__ << ": " << "Parameter type: " << *param_type << endl; cerr << cur->second.get_fileline() << ": " << __func__ << ": " << "Parameter value: " << *val_expr << endl; cerr << cur->second.get_fileline() << ": " << __func__ << ": " << "Elaborated value: " << *expr << endl; } } void NetScope::evaluate_type_parameter_(Design *des, param_ref_t cur) { const PETypename *type_expr = dynamic_cast(cur->second.val_expr); if (!type_expr) { cerr << this->get_fileline() << ": error: " << "Type parameter `" << cur->first << "` value `" << *cur->second.val_expr << "` is not a type." << endl; des->errors++; // Recover cur->second.ivl_type = netvector_t::integer_type(); return; } data_type_t *type = type_expr->get_type(); NetScope *type_scope = cur->second.val_scope; cur->second.ivl_type = type->elaborate_type(des, type_scope); } void NetScope::evaluate_parameter_(Design*des, param_ref_t cur) { // If the parameter has already been evaluated, quietly return. if (cur->second.val || cur->second.ivl_type) return; if (cur->second.val_expr == 0) { cerr << this->get_fileline() << ": error: " << "Missing value for parameter `" << cur->first << "`." << endl; des->errors += 1; cur->second.val = new NetEConst(verinum(verinum::Vx)); return; } if (cur->second.type_flag) { evaluate_type_parameter_(des, cur); return; } ivl_type_t param_type = cur->second.ivl_type; // If the parameter type is present, then elaborate it now. Elaborate // the type in the current scope, and not the scope of the expression. if (cur->second.val_type) { param_type = cur->second.val_type->elaborate_type(des, this); cur->second.ivl_type = param_type; cur->second.val_type = 0; } // Guess the varaiable type of the parameter. If the parameter has no // given type, then guess the type from the expression and use that to // evaluate (this is currently handled in evaluate_parameter_logic_()). ivl_variable_type_t use_type; if (param_type) use_type = param_type->base_type(); else use_type = IVL_VT_NO_TYPE; if (cur->second.solving) { cerr << cur->second.get_fileline() << ": error: " << "Recursive parameter reference found involving " << cur->first << "." << endl; des->errors += 1; } else { cur->second.solving = true; switch (use_type) { case IVL_VT_NO_TYPE: case IVL_VT_BOOL: case IVL_VT_LOGIC: evaluate_parameter_logic_(des, cur); break; case IVL_VT_REAL: evaluate_parameter_real_(des, cur); break; case IVL_VT_STRING: evaluate_parameter_string_(des, cur); break; default: cerr << cur->second.get_fileline() << ": internal error: " << "Unexpected parameter type " << use_type << "." << endl; cerr << cur->second.get_fileline() << ": : " << "Parameter name: " << cur->first << endl; if (param_type) cerr << cur->second.get_fileline() << ": : " << "Parameter ivl_type: " << *param_type << endl; cerr << cur->second.get_fileline() << ": : " << "Expression is: " << *cur->second.val_expr << endl; ivl_assert(cur->second, 0); break; } cur->second.solving = false; } // If we have failed to evaluate the expression, create a dummy // value. This prevents spurious error messages being output. if (cur->second.val == 0) { verinum val(verinum::Vx); cur->second.val = new NetEConst(val); } // Flag that the expression has been evaluated. cur->second.val_expr = 0; } void NetScope::evaluate_parameters(Design*des) { for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->evaluate_parameters(des); if (debug_scopes) cerr << "debug: " << "Evaluating parameters in " << scope_path(this) << endl; for (param_ref_t cur = parameters.begin() ; cur != parameters.end() ; ++ cur) { evaluate_parameter_(des, cur); } } void Design::residual_defparams() { for (list::const_iterator scope = root_scopes_.begin(); scope != root_scopes_.end(); ++ scope ) (*scope)->residual_defparams(this); } void NetScope::residual_defparams(Design*des) { // Clean out the list of defparams that never managed to match // a scope. Print a warning for each. while (! defparams_later.empty()) { pair,PExpr*> cur = defparams_later.front(); defparams_later.pop_front(); cerr << cur.second->get_fileline() << ": warning: " << "Scope of " << cur.first << " not found." << endl; } for (map::const_iterator cur = children_.begin() ; cur != children_.end() ; ++ cur ) cur->second->residual_defparams(des); } const char* Design::get_flag(const string&key) const { map::const_iterator tmp = flags_.find(key); if (tmp == flags_.end()) return ""; else return (*tmp).second; } /* * This method looks for a signal (reg, wire, whatever) starting at * the specified scope. If the name is hierarchical, it is split into * scope and name and the scope used to find the proper starting point * for the real search. * * It is the job of this function to properly implement Verilog scope * rules as signals are concerned. */ NetNet* Design::find_signal(NetScope*scope, pform_name_t path) { assert(scope); perm_string key = peek_tail_name(path); path.pop_back(); if (! path.empty()) { list eval_path = eval_scope_path(this, scope, path); scope = find_scope(scope, eval_path); } while (scope) { if (NetNet*net = scope->find_signal(key)) return net; if (NetScope*import_scope = scope->find_import(this, key)) { scope = import_scope; continue; } if (scope->type() == NetScope::MODULE) break; scope = scope->parent(); } return 0; } NetFuncDef* Design::find_function(NetScope*scope, const pform_name_t&name) { assert(scope); std::list eval_path = eval_scope_path(this, scope, name); NetScope*func = find_scope(scope, eval_path, NetScope::FUNC); if (func && (func->type() == NetScope::FUNC)) { // If a function is used in a parameter definition or in // a signal declaration, it is possible to get here before // the function's signals have been elaborated. If this is // the case, elaborate them now. if (func->elab_stage() < 2) { func->need_const_func(true); const PFunction*pfunc = func->func_pform(); assert(pfunc); pfunc->elaborate_sig(this, func); } return func->func_def(); } return 0; } NetScope* Design::find_task(NetScope*scope, const pform_name_t&name) { std::list eval_path = eval_scope_path(this, scope, name); NetScope*task = find_scope(scope, eval_path, NetScope::TASK); if (task && (task->type() == NetScope::TASK)) return task; return 0; } void Design::add_node(NetNode*net) { assert(net->design_ == 0); if (nodes_ == 0) { net->node_next_ = net; net->node_prev_ = net; } else { net->node_next_ = nodes_->node_next_; net->node_prev_ = nodes_; net->node_next_->node_prev_ = net; net->node_prev_->node_next_ = net; } nodes_ = net; net->design_ = this; } void Design::del_node(NetNode*net) { assert(net != 0); assert(net->design_ == this); /* Interact with the Design::functor method by manipulating the cur and nxt pointers that it is using. */ if (net == nodes_functor_nxt_) nodes_functor_nxt_ = nodes_functor_nxt_->node_next_; if (net == nodes_functor_nxt_) nodes_functor_nxt_ = 0; if (net == nodes_functor_cur_) nodes_functor_cur_ = 0; /* Now perform the actual delete. */ if (nodes_ == net) nodes_ = net->node_prev_; if (nodes_ == net) { nodes_ = 0; } else { net->node_next_->node_prev_ = net->node_prev_; net->node_prev_->node_next_ = net->node_next_; } net->design_ = 0; } void Design::add_branch(NetBranch*bra) { bra->next_ = branches_; branches_ = bra; } void Design::add_process(NetProcTop*pro) { pro->next_ = procs_; procs_ = pro; } void Design::add_process(NetAnalogTop*pro) { pro->next_ = aprocs_; aprocs_ = pro; } void Design::delete_process(NetProcTop*top) { assert(top); if (procs_ == top) { procs_ = top->next_; } else { NetProcTop*cur = procs_; while (cur->next_ != top) { assert(cur->next_); cur = cur->next_; } cur->next_ = top->next_; } if (procs_idx_ == top) procs_idx_ = top->next_; delete top; } void Design::join_islands(void) { if (nodes_ == 0) return; NetNode*cur = nodes_->node_next_; do { join_island(cur); cur = cur->node_next_; } while (cur != nodes_->node_next_); } iverilog-12_0/net_event.cc000066400000000000000000000251411435245347300156500ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 "compiler.h" # include "netlist.h" # include "ivl_assert.h" using namespace std; /* * NOTE: The name_ is perm-allocated by the caller. */ NetEvent::NetEvent(perm_string n) : name_(n) { local_flag_ = false; scope_ = 0; snext_ = 0; probes_ = 0; trig_ = 0; waitref_ = 0; exprref_ = 0; wlist_ = 0; } NetEvent::~NetEvent() { assert(waitref_ == 0); if (scope_) scope_->rem_event(this); while (probes_) { NetEvProbe*tmp = probes_->enext_; delete probes_; probes_ = tmp; } /* name_ is lex_strings. */ } perm_string NetEvent::name() const { return name_; } NetScope* NetEvent::scope() { assert(scope_); return scope_; } const NetScope* NetEvent::scope() const { assert(scope_); return scope_; } unsigned NetEvent::nprobe() const { unsigned cnt = 0; NetEvProbe*cur = probes_; while (cur) { cnt += 1; cur = cur->enext_; } return cnt; } NetEvProbe* NetEvent::probe(unsigned idx) { NetEvProbe*cur = probes_; while (cur && idx) { cur = cur->enext_; idx -= 1; } return cur; } const NetEvProbe* NetEvent::probe(unsigned idx) const { NetEvProbe*cur = probes_; while (cur && idx) { cur = cur->enext_; idx -= 1; } return cur; } unsigned NetEvent::ntrig() const { unsigned cnt = 0; NetEvTrig*cur = trig_; while (cur) { cnt += 1; cur = cur->enext_; } return cnt; } unsigned NetEvent::nwait() const { return waitref_; } unsigned NetEvent::nexpr() const { return exprref_; } /* * A "similar" event is one that has an identical non-nil set of * probes. */ void NetEvent::find_similar_event(list&event_list) { if (probes_ == 0) return; set candidate_events; /* First, get a list of all the NetEvProbes that are connected to my first probe. Then use that to create a set of candidate events. These candidate events are a superset of the similar events, so I will be culling this list later. */ listfirst_probes; probes_->find_similar_probes(first_probes); for (list::iterator idx = first_probes.begin() ; idx != first_probes.end() ; ++ idx ) { candidate_events.insert( (*idx)->event() ); } if (candidate_events.empty()) return; /* Now scan the remaining probes, in each case checking that the probe event is a candidate event. After each iteration, events that don't have a similar probe will be removed from the candidate_events set. If the candidate_events set becomes empty, then give up. */ unsigned probe_count = 1; for (NetEvProbe*cur = probes_->enext_ ; cur; cur = cur->enext_) { listsimilar_probes; cur->find_similar_probes(similar_probes); set candidate_tmp; for (list::iterator idx = similar_probes.begin() ; idx != similar_probes.end() ; ++ idx ) { NetEvent*tmp = (*idx)->event(); if (candidate_events.find(tmp) != candidate_events.end()) candidate_tmp .insert(tmp); } // None of the candidate events match this probe? Give up! if (candidate_tmp.empty()) return; candidate_events = candidate_tmp; probe_count += 1; } /* Scan the surviving candidate events. We know that they all have probes that match the current event's probes. Check for remaining compatibility details and save the survivors in the event_list that the caller passed. */ for (set::iterator idx = candidate_events.begin() ; idx != candidate_events.end() ; ++ idx ) { NetEvent*tmp = *idx; // This shouldn't be possible? if (tmp == this) continue; /* For automatic tasks, the VVP runtime holds state for events in the automatically allocated context. This means we can't merge similar events in different automatic tasks. */ if (scope()->is_auto() && (tmp->scope() != scope())) continue; unsigned tcnt = 0; for (NetEvProbe*cur = tmp->probes_ ; cur ; cur = cur->enext_) tcnt += 1; if (tcnt == probe_count) event_list .push_back(tmp); } } void NetEvent::replace_event(NetEvent*that) { while (wlist_) { wlist_->obj->replace_event(this, that); } } NexusSet* NetEvent::nex_async_() { /* If there are behavioral trigger statements attached to me, then this is not an asynchronous event. */ if (trig_ != 0) return 0; NexusSet*tmp = new NexusSet; for (NetEvProbe*cur = probes_ ; cur != 0 ; cur = cur->enext_) { if (cur->edge() != NetEvProbe::ANYEDGE) { delete tmp; return 0; } for (unsigned idx = 0 ; idx < cur->pin_count() ; idx += 1) { Nexus*nex = cur->pin(idx).nexus(); tmp->add(nex, 0, nex->vector_width()); } } return tmp; } NetEvTrig::NetEvTrig(NetEvent*ev) : event_(ev) { enext_ = event_->trig_; event_->trig_ = this; } NetEvTrig::~NetEvTrig() { if (event_->trig_ == this) { event_->trig_ = enext_; } else { NetEvTrig*cur = event_->trig_; while (cur->enext_ != this) { assert(cur->enext_); cur = cur->enext_; } cur->enext_ = this->enext_; } } const NetEvent* NetEvTrig::event() const { return event_; } NetEvNBTrig::NetEvNBTrig(NetEvent*ev, NetExpr*dly) : event_(ev), dly_(dly) { enext_ = event_->nb_trig_; event_->nb_trig_ = this; } NetEvNBTrig::~NetEvNBTrig() { if (event_->nb_trig_ == this) { event_->nb_trig_ = enext_; } else { NetEvNBTrig*cur = event_->nb_trig_; while (cur->enext_ != this) { assert(cur->enext_); cur = cur->enext_; } cur->enext_ = this->enext_; } } const NetExpr* NetEvNBTrig::delay() const { return dly_; } const NetEvent* NetEvNBTrig::event() const { return event_; } NetEvProbe::NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt, edge_t t, unsigned p) : NetNode(s, n, p), event_(tgt), edge_(t) { for (unsigned idx = 0 ; idx < p ; idx += 1) { pin(idx).set_dir(Link::INPUT); } enext_ = event_->probes_; event_->probes_ = this; } NetEvProbe::~NetEvProbe() { if (event_->probes_ == this) { event_->probes_ = enext_; } else { NetEvProbe*cur = event_->probes_; while (cur->enext_ != this) { assert(cur->enext_); cur = cur->enext_; } cur->enext_ = this->enext_; } } NetEvProbe::edge_t NetEvProbe::edge() const { return edge_; } NetEvent* NetEvProbe::event() { return event_; } const NetEvent* NetEvProbe::event() const { return event_; } /* * A similar NetEvProbe is one that is connected to all the same nexa * that this probe is connected to, and also is the same edge * type. Don't count myself as a similar probe. */ void NetEvProbe::find_similar_probes(list&plist) { Nexus*nex = pin(0).nexus(); for (Link*lcur = nex->first_nlink(); lcur; lcur = lcur->next_nlink()) { NetPins*obj = lcur->get_obj(); // Skip NexusSet objects if (obj == 0) continue; if (obj->pin_count() != pin_count()) continue; NetEvProbe*tmp = dynamic_cast(obj); if (tmp == 0) continue; if (tmp == this) continue; if (edge() != tmp->edge()) continue; bool ok_flag = true; for (unsigned idx = 1 ; ok_flag && idx < pin_count() ; idx += 1) if (! pin(idx).is_linked(tmp->pin(idx))) ok_flag = false; if (ok_flag == true) plist .push_back(tmp); } } NetEvWait::NetEvWait(NetProc*pr) : statement_(pr), has_t0_trigger_(false) { } NetEvWait::~NetEvWait() { if (! events_.empty()) { for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { NetEvent*tgt = events_[idx]; tgt->waitref_ -= 1; struct NetEvent::wcell_*tmp = tgt->wlist_; if (tmp->obj == this) { tgt->wlist_ = tmp->next; delete tmp; } else { assert(tmp->next); while (tmp->next->obj != this) { tmp = tmp->next; assert(tmp->next); } tmp->next = tmp->next->next; delete tmp; } delete tgt; } events_.clear(); } delete statement_; } void NetEvWait::add_event(NetEvent*tgt) { /* A wait fork is an empty event. */ if (! tgt) { assert(events_.empty()); events_.push_back(0); return; } events_.push_back(tgt); // Remember to tell the NetEvent that there is someone // pointing to it. tgt->waitref_ += 1; struct NetEvent::wcell_*tmp = new NetEvent::wcell_; tmp->obj = this; tmp->next = tgt->wlist_; tgt->wlist_ = tmp; } void NetEvWait::replace_event(NetEvent*src, NetEvent*repl) { unsigned idx; for (idx = 0 ; idx < events_.size() ; idx += 1) { if (events_[idx] == src) break; } assert(idx < events_.size()); // First, remove me from the list held by the src NetEvent. assert(src->waitref_ > 0); src->waitref_ -= 1; struct NetEvent::wcell_*tmp = src->wlist_; if (tmp->obj == this) { src->wlist_ = tmp->next; delete tmp; } else { assert(tmp->next); while (tmp->next->obj != this) { tmp = tmp->next; assert(tmp->next); } tmp->next = tmp->next->next; delete tmp; } // Replace the src pointer with the repl pointer. events_[idx] = repl; // Remember to tell the replacement NetEvent that there is // someone pointing to it. repl->waitref_ += 1; tmp = new NetEvent::wcell_; tmp->obj = this; tmp->next = repl->wlist_; repl->wlist_ = tmp; } NetProc* NetEvWait::statement() { return statement_; } const NetProc* NetEvWait::statement() const { return statement_; } iverilog-12_0/net_expr.cc000066400000000000000000000252521435245347300155100ustar00rootroot00000000000000/* * Copyright (c) 2002-2020 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 "netlist.h" # include "netenum.h" # include "netclass.h" # include "netdarray.h" # include "netscalar.h" # include "compiler.h" # include "netmisc.h" # include # include "ivl_assert.h" using namespace std; NetExpr::NetExpr(unsigned w) : net_type_(0), width_(w), signed_flag_(false) { } NetExpr::NetExpr(ivl_type_t t) : net_type_(t), width_(0), signed_flag_(false) { } NetExpr::~NetExpr() { } ivl_type_t NetExpr::net_type() const { return net_type_; } void NetExpr::cast_signed(bool flag) { cast_signed_base_(flag); } bool NetExpr::has_width() const { return true; } /* * the grand default data type is a logic vector. */ ivl_variable_type_t NetExpr::expr_type() const { if (net_type_) return net_type_->base_type(); else return IVL_VT_LOGIC; } const netenum_t*NetExpr::enumeration() const { return 0; } NetEArrayPattern::NetEArrayPattern(ivl_type_t lv_type, vector&items) : NetExpr(lv_type), items_(items) { } NetEArrayPattern::~NetEArrayPattern() { for (size_t idx = 0 ; idx < items_.size() ; idx += 1) delete items_[idx]; } /* * Create an add/sub node from the two operands. */ NetEBAdd::NetEBAdd(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBAdd::~NetEBAdd() { } ivl_variable_type_t NetEBAdd::expr_type() const { if (left_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; if (right_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; return IVL_VT_LOGIC; } /* * Create a comparison operator with two sub-expressions. */ NetEBComp::NetEBComp(char op__, NetExpr*l, NetExpr*r) : NetEBinary(op__, l, r, 1, false) { } NetEBComp::~NetEBComp() { } bool NetEBComp::has_width() const { return true; } ivl_variable_type_t NetEBComp::expr_type() const { // Case compare always returns BOOL if (op() == 'E' || op() == 'N') return IVL_VT_BOOL; if (left()->expr_type() == IVL_VT_LOGIC) return IVL_VT_LOGIC; if (right()->expr_type() == IVL_VT_LOGIC) return IVL_VT_LOGIC; return IVL_VT_BOOL; } NetEBDiv::NetEBDiv(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBDiv::~NetEBDiv() { } ivl_variable_type_t NetEBDiv::expr_type() const { if (left_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; if (right_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; return IVL_VT_LOGIC; } NetEBMinMax::NetEBMinMax(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBMinMax::~NetEBMinMax() { } ivl_variable_type_t NetEBMinMax::expr_type() const { if (left_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; if (right_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; return IVL_VT_LOGIC; } NetEBMult::NetEBMult(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBMult::~NetEBMult() { } ivl_variable_type_t NetEBMult::expr_type() const { if (left_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; if (right_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; return IVL_VT_LOGIC; } NetEBPow::NetEBPow(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBPow::~NetEBPow() { } ivl_variable_type_t NetEBPow::expr_type() const { if (right_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; if (left_->expr_type() == IVL_VT_REAL) return IVL_VT_REAL; return IVL_VT_LOGIC; } NetEBShift::NetEBShift(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBShift::~NetEBShift() { } bool NetEBShift::has_width() const { return left_->has_width(); } NetEConcat::NetEConcat(unsigned cnt, unsigned r, ivl_variable_type_t vt) : parms_(cnt), repeat_(r), expr_type_(vt) { expr_width(0); } NetEConcat::~NetEConcat() { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) delete parms_[idx]; } ivl_variable_type_t NetEConcat::expr_type() const { return expr_type_; } void NetEConcat::set(unsigned idx, NetExpr*e) { assert(idx < parms_.size()); assert(parms_[idx] == 0); parms_[idx] = e; expr_width( expr_width() + repeat_ * e->expr_width() ); } NetEConstEnum::NetEConstEnum(perm_string n, const netenum_t*eset, const verinum&v) : NetEConst(v), enum_set_(eset), name_(n) { assert(has_width()); } NetEConstEnum::~NetEConstEnum() { } const netenum_t*NetEConstEnum::enumeration() const { return enum_set_; } NetECReal::NetECReal(const verireal&val) : value_(val) { expr_width(1); cast_signed_base_(true); } NetECReal::~NetECReal() { } const verireal& NetECReal::value() const { return value_; } ivl_variable_type_t NetECReal::expr_type() const { return IVL_VT_REAL; } NetECRealParam::NetECRealParam(const NetScope*s, perm_string n, const verireal&v) : NetECReal(v), scope_(s), name_(n) { } NetECRealParam::~NetECRealParam() { } perm_string NetECRealParam::name() const { return name_; } const NetScope* NetECRealParam::scope() const { return scope_; } NetECString::NetECString(const std::string& val) : NetEConst(verinum(val)) { } NetECString::~NetECString() { } ivl_variable_type_t NetECString::expr_type() const { return IVL_VT_STRING; } NetELast::NetELast(NetNet*s) : sig_(s) { } NetELast::~NetELast() { } ivl_variable_type_t NetELast::expr_type() const { return IVL_VT_BOOL; } NetENetenum::NetENetenum(const netenum_t*s) : netenum_(s) { } NetENetenum::~NetENetenum() { } const netenum_t* NetENetenum::netenum() const { return netenum_; } NetENew::NetENew(ivl_type_t t) : obj_type_(t), size_(0), init_val_(0) { } NetENew::NetENew(ivl_type_t t, NetExpr*size, NetExpr*init_val) : obj_type_(t), size_(size), init_val_(init_val) { } NetENew::~NetENew() { } ivl_variable_type_t NetENew::expr_type() const { return size_ ? IVL_VT_DARRAY : IVL_VT_CLASS; } NetENull::NetENull() { } NetENull::~NetENull() { } NetEProperty::NetEProperty(NetNet*net, size_t pidx, NetExpr*idx) : net_(net), pidx_(pidx), index_(idx) { const netclass_t*use_type = dynamic_cast(net->net_type()); assert(use_type); ivl_type_t prop_type = use_type->get_prop_type(pidx_); expr_width(prop_type->packed_width()); cast_signed(prop_type->get_signed()); } NetEProperty::~NetEProperty() { } ivl_variable_type_t NetEProperty::expr_type() const { const netclass_t*use_type = dynamic_cast(net_->net_type()); assert(use_type); ivl_type_t prop_type = use_type->get_prop_type(pidx_); return prop_type->base_type(); } NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid, ivl_select_type_t sel_type) : expr_(exp), base_(base), use_type_(0), sel_type_(sel_type) { expr_width(wid); } NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid, ivl_type_t use_type) : expr_(exp), base_(base), use_type_(use_type), sel_type_(IVL_SEL_OTHER) { expr_width(wid); } NetESelect::~NetESelect() { delete expr_; delete base_; } const NetExpr*NetESelect::sub_expr() const { return expr_; } const NetExpr*NetESelect::select() const { return base_; } ivl_select_type_t NetESelect::select_type() const { return sel_type_; } ivl_variable_type_t NetESelect::expr_type() const { if (use_type_) return use_type_->base_type(); ivl_variable_type_t type = expr_->expr_type(); // Special case: If the sub-expression is an IVL_VT_STRING, // then this node is representing a character select. The // width is the width of a byte, and the data type is BOOL. if (type == IVL_VT_STRING && expr_width()==8) return IVL_VT_BOOL; return type; } const netenum_t* NetESelect::enumeration() const { return dynamic_cast (use_type_); } NetESFunc::NetESFunc(const char*n, ivl_variable_type_t t, unsigned width, unsigned np, bool is_overridden) : name_(0), type_(t), enum_type_(0), parms_(np), is_overridden_(is_overridden) { name_ = lex_strings.add(n); expr_width(width); } NetESFunc::NetESFunc(const char*n, ivl_type_t rtype, unsigned np) : NetExpr(rtype), name_(0), type_(rtype->base_type()), enum_type_(dynamic_cast(rtype)), parms_(np), is_overridden_(false) { name_ = lex_strings.add(n); expr_width(rtype->packed_width()); cast_signed_base_(rtype->get_signed()); } NetESFunc::~NetESFunc() { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) if (parms_[idx]) delete parms_[idx]; /* name_ string ls lex_strings allocated. */ } const char* NetESFunc::name() const { return name_; } unsigned NetESFunc::nparms() const { return parms_.size(); } void NetESFunc::parm(unsigned idx, NetExpr*v) { assert(idx < parms_.size()); if (parms_[idx]) delete parms_[idx]; parms_[idx] = v; } const NetExpr* NetESFunc::parm(unsigned idx) const { assert(idx < parms_.size()); return parms_[idx]; } NetExpr* NetESFunc::parm(unsigned idx) { assert(idx < parms_.size()); return parms_[idx]; } ivl_variable_type_t NetESFunc::expr_type() const { return type_; } const netenum_t* NetESFunc::enumeration() const { return enum_type_; } NetEShallowCopy::NetEShallowCopy(NetExpr*arg1, NetExpr*arg2) : arg1_(arg1), arg2_(arg2) { } NetEShallowCopy::~NetEShallowCopy() { } ivl_variable_type_t NetEShallowCopy::expr_type() const { return arg1_->expr_type(); } NetEAccess::NetEAccess(NetBranch*br, ivl_nature_t nat) : branch_(br), nature_(nat) { cast_signed_base_(true); } NetEAccess::~NetEAccess() { } ivl_variable_type_t NetEAccess::expr_type() const { return IVL_VT_REAL; } iverilog-12_0/net_func.cc000066400000000000000000000072431435245347300154650ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 "netlist.h" # include "compiler.h" # include "PExpr.h" # include using namespace std; /* * To make a NetUserFunc device, make as many pins as there are ports * in the function. Get the port count from the function definition, * which accounts for all the inputs, plus one for the phantom output * that is the result. */ NetUserFunc::NetUserFunc(NetScope*s, perm_string n, NetScope*d, NetEvWait*trigger__) : NetNode(s, n, d->func_def()->port_count()+1), def_(d), trigger_(trigger__) { pin(0).set_dir(Link::OUTPUT); for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) { pin(idx).set_dir(Link::INPUT); pin(idx).drive0(IVL_DR_HiZ); pin(idx).drive1(IVL_DR_HiZ); } } NetUserFunc::~NetUserFunc() { } unsigned NetUserFunc::port_width(unsigned port) const { NetFuncDef*fdef = def_->func_def(); /* Port 0 is the return port. */ if (port == 0) { const NetNet*sig = fdef->return_sig(); assert(sig); return sig->vector_width(); } port -= 1; assert(port < fdef->port_count()); const NetNet*port_sig = fdef->port(port); return port_sig->vector_width(); } const NetScope* NetUserFunc::def() const { return def_; } /* * This method of the PECallFunction class checks that the parameters * of the PECallFunction match the function definition. This is used * during elaboration to validate the parameters before using them. */ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope) const { assert(dscope); /* How many parameters have I got? Normally the size of the list is correct, but there is the special case of a list of 1 nil pointer. This is how the parser tells me of no parameter. In other words, ``func()'' is 1 nil parameter. */ unsigned parms_count = parms_.size(); if ((parms_count == 1) && (parms_[0] == 0)) parms_count = 0; if (dscope->type() != NetScope::FUNC) { cerr << get_fileline() << ": error: Attempt to call scope " << scope_path(dscope) << " as a function." << endl; des->errors += 1; return false; } return true; } NetSysFunc::NetSysFunc(NetScope*s, perm_string n, const struct sfunc_return_type*def, unsigned ports, NetEvWait*trigger__) : NetNode(s, n, ports), def_(def), trigger_(trigger__) { pin(0).set_dir(Link::OUTPUT); // Q for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) { pin(idx).set_dir(Link::INPUT); pin(idx).drive0(IVL_DR_HiZ); pin(idx).drive1(IVL_DR_HiZ); } } NetSysFunc::~NetSysFunc() { } const char*NetSysFunc::func_name() const { return def_->name; } ivl_variable_type_t NetSysFunc::data_type() const { return def_->type; } unsigned NetSysFunc::vector_width() const { return def_->wid; } iverilog-12_0/net_func_eval.cc000066400000000000000000000757461435245347300165110ustar00rootroot00000000000000/* * Copyright (c) 2012-2022 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 "netlist.h" # include "netmisc.h" # include "compiler.h" # include # include "ivl_assert.h" using namespace std; /* * We only evaluate one function at a time, so to support the disable * statement, we just need to record the target block and then early * terminate each enclosing block or loop statement until we get back * to the target block. */ static const NetScope*disable = 0; static NetExpr* fix_assign_value(const NetNet*lhs, NetExpr*rhs) { NetEConst*ce = dynamic_cast(rhs); if (ce == 0) return rhs; unsigned lhs_width = lhs->vector_width(); unsigned rhs_width = rhs->expr_width(); if (rhs_width < lhs_width) { rhs = pad_to_width(rhs, lhs_width, *rhs); } else if (rhs_width > lhs_width) { verinum value(ce->value(), lhs_width); ce = new NetEConst(value); ce->set_line(*rhs); delete rhs; rhs = ce; } rhs->cast_signed(lhs->get_signed()); return rhs; } NetExpr* NetFuncDef::evaluate_function(const LineInfo&loc, const std::vector&args) const { // Make the context map. map::iterator ptr; mapcontext_map; if (debug_eval_tree) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "Evaluate function " << scope()->basename() << endl; } // Put the return value into the map... LocalVar&return_var = context_map[scope()->basename()]; return_var.nwords = 0; return_var.value = 0; // Load the input ports into the map... ivl_assert(loc, port_count() == args.size()); for (size_t idx = 0 ; idx < port_count() ; idx += 1) { const NetNet*pnet = port(idx); perm_string aname = pnet->name(); LocalVar&input_var = context_map[aname]; input_var.nwords = 0; input_var.value = fix_assign_value(pnet, args[idx]); if (debug_eval_tree) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << " input " << aname << " = " << *args[idx] << endl; } } // Ask the scope to collect definitions for local values. This // fills in the context_map with local variables held by the scope. scope()->evaluate_function_find_locals(loc, context_map); // Execute any variable initialization statements. if (const NetProc*init_proc = scope()->var_init()) init_proc->evaluate_function(loc, context_map); if (debug_eval_tree && proc_==0) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "Function " << scope_path(scope()) << " has no statement?" << endl; } // Perform the evaluation. Note that if there were errors // when compiling the function definition, we may not have // a valid statement. bool flag = proc_ && proc_->evaluate_function(loc, context_map); if (debug_eval_tree && !flag) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "Cannot evaluate " << scope_path(scope()) << "." << endl; } // Extract the result... ptr = context_map.find(scope()->basename()); NetExpr*res = ptr->second.value; context_map.erase(ptr); // Cleanup the rest of the context. for (ptr = context_map.begin() ; ptr != context_map.end() ; ++ptr) { unsigned nwords = ptr->second.nwords; if (nwords > 0) { NetExpr**array = ptr->second.array; for (unsigned idx = 0 ; idx < nwords ; idx += 1) { delete array[idx]; } delete [] ptr->second.array; } else { delete ptr->second.value; } } if (disable) { if (debug_eval_tree) cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "disable of " << scope_path(disable) << " trapped in function " << scope_path(scope()) << "." << endl; ivl_assert(loc, disable==scope()); disable = 0; } // Done. if (flag) { if (debug_eval_tree) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "Evaluated to "; if (res) cerr << *res; else cerr << ""; cerr << endl; } return res; } if (debug_eval_tree) { cerr << loc.get_fileline() << ": NetFuncDef::evaluate_function: " << "Evaluation failed." << endl; } delete res; return 0; } void NetScope::evaluate_function_find_locals(const LineInfo&loc, map&context_map) const { for (map::const_iterator cur = signals_map_.begin() ; cur != signals_map_.end() ; ++cur) { const NetNet*tmp = cur->second; // Skip ports, which are handled elsewhere. if (tmp->port_type() != NetNet::NOT_A_PORT) continue; unsigned nwords = 0; if (tmp->unpacked_dimensions() > 0) nwords = tmp->unpacked_count(); LocalVar&local_var = context_map[tmp->name()]; local_var.nwords = nwords; if (nwords > 0) { NetExpr**array = new NetExpr*[nwords]; for (unsigned idx = 0 ; idx < nwords ; idx += 1) { array[idx] = 0; } local_var.array = array; } else { local_var.value = 0; } if (debug_eval_tree) { cerr << loc.get_fileline() << ": debug: " << " (local) " << tmp->name() << (nwords > 0 ? "[]" : "") << endl; } } } NetExpr* NetExpr::evaluate_function(const LineInfo&, map&) const { cerr << get_fileline() << ": sorry: I don't know how to evaluate this expression at compile time." << endl; cerr << get_fileline() << ": : Expression type:" << typeid(*this).name() << endl; return 0; } bool NetProc::evaluate_function(const LineInfo&, map&) const { cerr << get_fileline() << ": sorry: I don't know how to evaluate this statement at compile time." << endl; cerr << get_fileline() << ": : Statement type:" << typeid(*this).name() << endl; return false; } void NetAssign::eval_func_lval_op_real_(const LineInfo&loc, verireal&lv, const verireal&rv) const { switch (op_) { case '+': lv = lv + rv; break; case '-': lv = lv - rv; break; case '*': lv = lv * rv; break; case '/': lv = lv / rv; break; case '%': lv = lv % rv; break; default: cerr << "Illegal assignment operator: " << human_readable_op(op_) << endl; ivl_assert(loc, 0); } } void NetAssign::eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const { unsigned lv_width = lv.len(); bool lv_sign = lv.has_sign(); switch (op_) { case 'l': case 'R': // The left operand is self-determined. break; case 'r': // The left operand is self-determined, but we need to // cast it to unsigned to get a logical shift. lv.has_sign(false); break; default: // The left operand must be cast to the expression type/size lv.has_sign(rv.has_sign()); lv = cast_to_width(lv, rv.len()); } switch (op_) { case '+': lv = lv + rv; break; case '-': lv = lv - rv; break; case '*': lv = lv * rv; break; case '/': lv = lv / rv; break; case '%': lv = lv % rv; break; case '&': for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) lv.set(idx, lv[idx] & rv[idx]); break; case '|': for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) lv.set(idx, lv[idx] | rv[idx]); break; case '^': for (unsigned idx = 0 ; idx < lv.len() ; idx += 1) lv.set(idx, lv[idx] ^ rv[idx]); break; case 'l': lv = lv << rv.as_unsigned(); break; case 'r': lv = lv >> rv.as_unsigned(); break; case 'R': lv = lv >> rv.as_unsigned(); break; default: cerr << "Illegal assignment operator: " << human_readable_op(op_) << endl; ivl_assert(loc, 0); } lv = cast_to_width(lv, lv_width); lv.has_sign(lv_sign); } bool NetAssign::eval_func_lval_(const LineInfo&loc, map&context_map, const NetAssign_*lval, NetExpr*rval_result) const { map::iterator ptr = context_map.find(lval->name()); ivl_assert(*this, ptr != context_map.end()); LocalVar*var = & ptr->second; while (var->nwords == -1) { assert(var->ref); var = var->ref; } NetExpr*old_lval; int word = 0; if (var->nwords > 0) { NetExpr*word_result = lval->word()->evaluate_function(loc, context_map); if (word_result == 0) { delete rval_result; return false; } NetEConst*word_const = dynamic_cast(word_result); ivl_assert(loc, word_const); if (!word_const->value().is_defined()) return true; word = word_const->value().as_long(); if (word < 0 || word >= var->nwords) return true; old_lval = var->array[word]; } else { assert(var->nwords == 0); old_lval = var->value; } if (const NetExpr*base_expr = lval->get_base()) { NetExpr*base_result = base_expr->evaluate_function(loc, context_map); if (base_result == 0) { delete rval_result; return false; } NetEConst*base_const = dynamic_cast(base_result); ivl_assert(loc, base_const); long base = base_const->value().as_long(); if (old_lval == 0) old_lval = make_const_x(lval->sig()->vector_width()); NetEConst*lval_const = dynamic_cast(old_lval); ivl_assert(loc, lval_const); verinum lval_v = lval_const->value(); NetEConst*rval_const = dynamic_cast(rval_result); ivl_assert(loc, rval_const); verinum rval_v = rval_const->value(); verinum lpart(verinum::Vx, lval->lwidth()); if (op_) { for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1) { long ldx = base + idx; if (ldx >= 0 && ldx < lval_v.len()) lpart.set(idx, lval_v[ldx]); } eval_func_lval_op_(loc, lpart, rval_v); } else { lpart = cast_to_width(rval_v, lval->lwidth()); } for (unsigned idx = 0 ; idx < lpart.len() ; idx += 1) { long ldx = base + idx; if (ldx >= 0 && ldx < lval_v.len()) lval_v.set(idx+base, lpart[idx]); } delete base_result; delete rval_result; rval_result = new NetEConst(lval_v); } else { if (op_ == 0) { rval_result = fix_assign_value(lval->sig(), rval_result); } else if (dynamic_cast(rval_result)) { NetECReal*lval_const = dynamic_cast(old_lval); ivl_assert(loc, lval_const); verireal lval_r = lval_const->value(); NetECReal*rval_const = dynamic_cast(rval_result); ivl_assert(loc, rval_const); verireal rval_r = rval_const->value(); eval_func_lval_op_real_(loc, lval_r, rval_r); delete rval_result; rval_result = new NetECReal(lval_r); } else { NetEConst*lval_const = dynamic_cast(old_lval); ivl_assert(loc, lval_const); verinum lval_v = lval_const->value(); NetEConst*rval_const = dynamic_cast(rval_result); ivl_assert(loc, rval_const); verinum rval_v = rval_const->value(); eval_func_lval_op_(loc, lval_v, rval_v); delete rval_result; rval_result = new NetEConst(lval_v); } } if (old_lval) delete old_lval; if (debug_eval_tree) { cerr << get_fileline() << ": NetAssign::evaluate_function: " << lval->name() << " = " << *rval_result << endl; } if (var->nwords > 0) { var->array[word] = rval_result; } else { assert(var->nwords == 0); var->value = rval_result; } return true; } bool NetAssign::evaluate_function(const LineInfo&loc, map&context_map) const { // Evaluate the r-value expression. const NetExpr*use_rval = rval(); if (use_rval == 0) return false; NetExpr*rval_result = use_rval->evaluate_function(loc, context_map); if (rval_result == 0) return false; // Handle the easy case of a single variable on the LHS. if (l_val_count() == 1) return eval_func_lval_(loc, context_map, l_val(0), rval_result); // If we get here, the LHS must be a concatenation, so we // expect the RHS to be a vector value. NetEConst*rval_const = dynamic_cast(rval_result); ivl_assert(*this, rval_const); if (op_) { cerr << get_fileline() << ": sorry: Assignment operators " "inside a constant function are not currently " "supported if the LHS is a concatenation." << endl; return false; } verinum rval_full = rval_const->value(); delete rval_result; unsigned base = 0; for (unsigned ldx = 0 ; ldx < l_val_count() ; ldx += 1) { const NetAssign_*lval = l_val(ldx); verinum rval_part(verinum::Vx, lval->lwidth()); for (unsigned idx = 0 ; idx < rval_part.len() ; idx += 1) rval_part.set(idx, rval_full[base+idx]); bool flag = eval_func_lval_(loc, context_map, lval, new NetEConst(rval_part)); if (!flag) return false; base += lval->lwidth(); } return true; } /* * Evaluating a NetBlock in a function is a simple matter of * evaluating the statements in order. */ bool NetBlock::evaluate_function(const LineInfo&loc, map&context_map) const { if (last_ == 0) return true; // If we need to make a local scope, then this context map // will be filled in and used for statements within this block. maplocal_context_map; bool use_local_context_map = false; if (subscope_!=0) { // First, copy the containing scope symbols into the new // scope as references. for (map::iterator cur = context_map.begin() ; cur != context_map.end() ; ++cur) { LocalVar&cur_var = local_context_map[cur->first]; cur_var.nwords = -1; if (cur->second.nwords == -1) cur_var.ref = cur->second.ref; else cur_var.ref = &cur->second; } // Now collect the new locals. subscope_->evaluate_function_find_locals(loc, local_context_map); use_local_context_map = true; // Execute any variable initialization statements. if (const NetProc*init_proc = subscope_->var_init()) init_proc->evaluate_function(loc, local_context_map); } // Now use the local context map if there is any local // context, or the containing context map. map&use_context_map = use_local_context_map? local_context_map : context_map; bool flag = true; NetProc*cur = last_; do { cur = cur->next_; if (debug_eval_tree) { cerr << get_fileline() << ": NetBlock::evaluate_function: " << "Execute statement (" << typeid(*cur).name() << ") at " << cur->get_fileline() << "." << endl; } bool cur_flag = cur->evaluate_function(loc, use_context_map); flag = flag && cur_flag; } while (cur != last_ && !disable); if (debug_eval_tree) { cerr << get_fileline() << ": NetBlock::evaluate_function: " << "subscope_=" << subscope_ << ", disable=" << disable << ", flag=" << (flag?"true":"false") << endl; } if (disable == subscope_) disable = 0; return flag; } bool NetCase::evaluate_function_vect_(const LineInfo&loc, map&context_map) const { NetExpr*case_expr = expr_->evaluate_function(loc, context_map); if (case_expr == 0) return false; NetEConst*case_const = dynamic_cast (case_expr); ivl_assert(loc, case_const); verinum case_val = case_const->value(); delete case_expr; NetProc*default_statement = 0; for (unsigned cnt = 0 ; cnt < items_.size() ; cnt += 1) { const Item*item = &items_[cnt]; if (item->guard == 0) { default_statement = item->statement; continue; } NetExpr*item_expr = item->guard->evaluate_function(loc, context_map); if (item_expr == 0) return false; NetEConst*item_const = dynamic_cast (item_expr); ivl_assert(loc, item_const); verinum item_val = item_const->value(); delete item_expr; ivl_assert(loc, item_val.len() == case_val.len()); bool match = true; for (unsigned idx = 0 ; idx < item_val.len() ; idx += 1) { verinum::V bit_a = case_val.get(idx); verinum::V bit_b = item_val.get(idx); if (bit_a == verinum::Vx && type_ == EQX) continue; if (bit_b == verinum::Vx && type_ == EQX) continue; if (bit_a == verinum::Vz && type_ != EQ) continue; if (bit_b == verinum::Vz && type_ != EQ) continue; if (bit_a != bit_b) { match = false; break; } } if (!match) continue; return item->statement->evaluate_function(loc, context_map); } if (default_statement) return default_statement->evaluate_function(loc, context_map); return true; } bool NetCase::evaluate_function_real_(const LineInfo&loc, map&context_map) const { NetExpr*case_expr = expr_->evaluate_function(loc, context_map); if (case_expr == 0) return false; NetECReal*case_const = dynamic_cast (case_expr); ivl_assert(loc, case_const); double case_val = case_const->value().as_double(); delete case_expr; NetProc*default_statement = 0; for (unsigned cnt = 0 ; cnt < items_.size() ; cnt += 1) { const Item*item = &items_[cnt]; if (item->guard == 0) { default_statement = item->statement; continue; } NetExpr*item_expr = item->guard->evaluate_function(loc, context_map); if (item_expr == 0) return false; NetECReal*item_const = dynamic_cast (item_expr); ivl_assert(loc, item_const); double item_val = item_const->value().as_double(); delete item_expr; if (item_val != case_val) continue; return item->statement->evaluate_function(loc, context_map); } if (default_statement) return default_statement->evaluate_function(loc, context_map); return true; } bool NetCase::evaluate_function(const LineInfo&loc, map&context_map) const { if (expr_->expr_type() == IVL_VT_REAL) return evaluate_function_real_(loc, context_map); else return evaluate_function_vect_(loc, context_map); } bool NetCondit::evaluate_function(const LineInfo&loc, map&context_map) const { NetExpr*cond = expr_->evaluate_function(loc, context_map); if (cond == 0) { if (debug_eval_tree) { cerr << get_fileline() << ": NetCondit::evaluate_function: " << "Unable to evaluate condition (" << *expr_ <<")" << endl; } return false; } NetEConst*cond_const = dynamic_cast (cond); ivl_assert(loc, cond_const); long val = cond_const->value().as_long(); delete cond; bool flag; if (val) // The condition is true, so evaluate the if clause flag = (if_ == 0) || if_->evaluate_function(loc, context_map); else // The condition is false, so evaluate the else clause flag = (else_ == 0) || else_->evaluate_function(loc, context_map); if (debug_eval_tree) { cerr << get_fileline() << ": NetCondit::evaluate_function: " << "Finished, flag=" << (flag?"true":"false") << endl; } return flag; } bool NetDisable::evaluate_function(const LineInfo&, map&) const { disable = target_; if (debug_eval_tree) { cerr << get_fileline() << ": NetDisable::evaluate_function: " << "disable " << scope_path(disable) << endl; } return true; } bool NetDoWhile::evaluate_function(const LineInfo&loc, map&context_map) const { bool flag = true; if (debug_eval_tree) { cerr << get_fileline() << ": NetDoWhile::evaluate_function: " << "Start loop" << endl; } while (!disable) { // Evaluate the statement. flag = proc_->evaluate_function(loc, context_map); if (! flag) break; // Evaluate the condition expression to try and get the // condition for the loop. NetExpr*cond = cond_->evaluate_function(loc, context_map); if (cond == 0) { flag = false; break; } NetEConst*cond_const = dynamic_cast (cond); ivl_assert(loc, cond_const); long val = cond_const->value().as_long(); delete cond; // If the condition is false, then the loop is done. if (val == 0) break; } if (debug_eval_tree) { cerr << get_fileline() << ": NetDoWhile::evaluate_function: " << "Done loop, flag=" << (flag?"true":"false") << endl; } return flag; } bool NetForever::evaluate_function(const LineInfo&loc, map&context_map) const { bool flag = true; if (debug_eval_tree) { cerr << get_fileline() << ": debug: NetForever::evaluate_function: " << "Start loop" << endl; } while (flag && !disable) { flag = flag && statement_->evaluate_function(loc, context_map); } if (debug_eval_tree) { cerr << get_fileline() << ": debug: NetForever::evaluate_function: " << "Done loop" << endl; } return flag; } /* * For now, resort to the block form of the statement until we learn * to do this directly. */ bool NetForLoop::evaluate_function(const LineInfo&loc, map&context_map) const { return as_block_->evaluate_function(loc, context_map); } bool NetRepeat::evaluate_function(const LineInfo&loc, map&context_map) const { bool flag = true; // Evaluate the condition expression to try and get the // condition for the loop. NetExpr*count_expr = expr_->evaluate_function(loc, context_map); if (count_expr == 0) return false; NetEConst*count_const = dynamic_cast (count_expr); ivl_assert(loc, count_const); long count = count_const->value().as_long(); delete count_expr; if (debug_eval_tree) { cerr << get_fileline() << ": debug: NetRepeat::evaluate_function: " << "Repeating " << count << " times." << endl; } while ((count > 0) && flag && !disable) { flag = flag && statement_->evaluate_function(loc, context_map); count -= 1; } if (debug_eval_tree) { cerr << get_fileline() << ": debug: NetRepeat::evaluate_function: " << "Finished loop" << endl; } return flag; } bool NetSTask::evaluate_function(const LineInfo&, map&) const { // system tasks within a constant function are ignored return true; } bool NetWhile::evaluate_function(const LineInfo&loc, map&context_map) const { bool flag = true; if (debug_eval_tree) { cerr << get_fileline() << ": NetWhile::evaluate_function: " << "Start loop" << endl; } while (flag && !disable) { // Evaluate the condition expression to try and get the // condition for the loop. NetExpr*cond = cond_->evaluate_function(loc, context_map); if (cond == 0) { flag = false; break; } NetEConst*cond_const = dynamic_cast (cond); ivl_assert(loc, cond_const); long val = cond_const->value().as_long(); delete cond; // If the condition is false, then break. if (val == 0) break; // The condition is true, so evaluate the statement // another time. bool tmp_flag = proc_->evaluate_function(loc, context_map); if (! tmp_flag) flag = false; } if (debug_eval_tree) { cerr << get_fileline() << ": NetWhile::evaluate_function: " << "Done loop, flag=" << (flag?"true":"false") << endl; } return flag; } NetExpr* NetEBinary::evaluate_function(const LineInfo&loc, map&context_map) const { NetExpr*lval = left_->evaluate_function(loc, context_map); NetExpr*rval = right_->evaluate_function(loc, context_map); if (lval == 0 || rval == 0) { delete lval; delete rval; return 0; } NetExpr*res = eval_arguments_(lval, rval); delete lval; delete rval; return res; } NetExpr* NetEConcat::evaluate_function(const LineInfo&loc, map&context_map) const { vectorvals(parms_.size()); unsigned gap = 0; unsigned valid_vals = 0; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { ivl_assert(*this, parms_[idx]); vals[idx] = parms_[idx]->evaluate_function(loc, context_map); if (vals[idx] == 0) continue; gap += vals[idx]->expr_width(); valid_vals += 1; } NetExpr*res = 0; if (valid_vals == parms_.size()) { res = eval_arguments_(vals, gap); } for (unsigned idx = 0 ; idx < vals.size() ; idx += 1) { delete vals[idx]; } return res; } NetExpr* NetEConst::evaluate_function(const LineInfo&, map&) const { NetEConst*res = new NetEConst(value_); res->set_line(*this); return res; } NetExpr* NetECReal::evaluate_function(const LineInfo&, map&) const { NetECReal*res = new NetECReal(value_); res->set_line(*this); return res; } NetExpr* NetESelect::evaluate_function(const LineInfo&loc, map&context_map) const { NetExpr*sub_exp = expr_->evaluate_function(loc, context_map); ivl_assert(loc, sub_exp); NetEConst*sub_const = dynamic_cast (sub_exp); ivl_assert(loc, sub_exp); verinum sub = sub_const->value(); delete sub_exp; long base = 0; if (base_) { NetExpr*base_val = base_->evaluate_function(loc, context_map); ivl_assert(loc, base_val); NetEConst*base_const = dynamic_cast(base_val); ivl_assert(loc, base_const); base = base_const->value().as_long(); delete base_val; } else { sub.has_sign(has_sign()); sub = pad_to_width(sub, expr_width()); } verinum res (verinum::Vx, expr_width()); for (unsigned idx = 0 ; idx < res.len() ; idx += 1) { long sdx = base + idx; if (sdx >= 0 && sdx < sub.len()) res.set(idx, sub[sdx]); } NetEConst*res_const = new NetEConst(res); return res_const; } NetExpr* NetESignal::evaluate_function(const LineInfo&loc, map&context_map) const { map::iterator ptr = context_map.find(name()); if (ptr == context_map.end()) { cerr << get_fileline() << ": error: Cannot evaluate " << name() << " in this context." << endl; return 0; } // Follow indirect references to the actual variable. LocalVar*var = & ptr->second; while (var->nwords == -1) { assert(var->ref); var = var->ref; } NetExpr*value = 0; if (var->nwords > 0) { ivl_assert(loc, word_); NetExpr*word_result = word_->evaluate_function(loc, context_map); if (word_result == 0) return 0; NetEConst*word_const = dynamic_cast(word_result); ivl_assert(loc, word_const); int word = word_const->value().as_long(); if (word_const->value().is_defined() && (word >= 0) && (word < var->nwords)) value = var->array[word]; } else { value = var->value; } if (value == 0) { switch (expr_type()) { case IVL_VT_REAL: return new NetECReal( verireal(0.0) ); case IVL_VT_BOOL: return make_const_0(expr_width()); case IVL_VT_LOGIC: return make_const_x(expr_width()); default: cerr << get_fileline() << ": sorry: I don't know how to initialize " << *this << endl; return 0; } } return value->dup_expr(); } NetExpr* NetETernary::evaluate_function(const LineInfo&loc, map&context_map) const { unique_ptr cval (cond_->evaluate_function(loc, context_map)); switch (const_logical(cval.get())) { case C_0: return false_val_->evaluate_function(loc, context_map); case C_1: return true_val_->evaluate_function(loc, context_map); case C_X: break; default: cerr << get_fileline() << ": error: Condition expression is not constant here." << endl; return 0; } NetExpr*tval = true_val_->evaluate_function(loc, context_map); NetExpr*fval = false_val_->evaluate_function(loc, context_map); NetExpr*res = blended_arguments_(tval, fval); delete tval; delete fval; return res; } NetExpr* NetEUnary::evaluate_function(const LineInfo&loc, map&context_map) const { NetExpr*val = expr_->evaluate_function(loc, context_map); if (val == 0) return 0; NetExpr*res = eval_arguments_(val); delete val; return res; } NetExpr* NetESFunc::evaluate_function(const LineInfo&loc, map&context_map) const { ID id = built_in_id_(); ivl_assert(*this, id != NOT_BUILT_IN); NetExpr*val0 = 0; NetExpr*val1 = 0; NetExpr*res = 0; switch (parms_.size()) { case 1: val0 = parms_[0]->evaluate_function(loc, context_map); if (val0 == 0) break; res = evaluate_one_arg_(id, val0); break; case 2: val0 = parms_[0]->evaluate_function(loc, context_map); val1 = parms_[1]->evaluate_function(loc, context_map); if (val0 == 0 || val1 == 0) break; res = evaluate_two_arg_(id, val0, val1); break; default: ivl_assert(*this, 0); break; } delete val0; delete val1; return res; } NetExpr* NetEUFunc::evaluate_function(const LineInfo&loc, map&context_map) const { NetFuncDef*def = func_->func_def(); ivl_assert(*this, def); vectorargs(parms_.size()); for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) args[idx] = parms_[idx]->evaluate_function(loc, context_map); NetExpr*res = def->evaluate_function(*this, args); return res; } iverilog-12_0/net_link.cc000066400000000000000000000357401435245347300154720ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 # include "netlist.h" # include # include # include # include # include # include "ivl_alloc.h" using namespace std; void Nexus::connect(Link&r) { Nexus*r_nexus = r.next_? r.find_nexus_() : 0; if (this == r_nexus) return; delete[] name_; name_ = 0; // Special case: This nexus is empty. Simply copy all the // links of the other nexus to this one, and delete the old // nexus. if (list_ == 0) { if (r.next_ == 0) { list_ = &r; r.next_ = &r; r.nexus_ = this; driven_ = NO_GUESS; } else { driven_ = r_nexus->driven_; list_ = r_nexus->list_; list_->nexus_ = this; r_nexus->list_ = 0; delete r_nexus; } return; } // Special case: The Link is unconnected. Put it at the end of // the current list and move the list_ pointer and nexus_ back // pointer to suit. if (r.next_ == 0) { if (r.get_dir() != Link::INPUT) driven_ = NO_GUESS; r.nexus_ = this; r.next_ = list_->next_; list_->next_ = &r; list_->nexus_ = 0; list_ = &r; return; } if (r_nexus->driven_ != Vz) driven_ = NO_GUESS; // Splice the list of links from the "tmp" nexus to the end of // this nexus. Adjust the nexus pointers as needed. Link*save_first = list_->next_; list_->next_ = r_nexus->list_->next_; r_nexus->list_->next_ = save_first; list_->nexus_ = 0; list_ = r_nexus->list_; list_->nexus_ = this; r_nexus->list_ = 0; delete r_nexus; } void connect(Link&l, Link&r) { Nexus*tmp; assert(&l != &r); // If either the l or r link already are part of a Nexus, then // re-use that nexus. Go through some effort so that we are // not gratuitously creating Nexus object. if (l.next_ && (tmp=l.find_nexus_())) { connect(tmp, r); } else if (r.next_ && (tmp=r.find_nexus_())) { connect(tmp, l); } else { // No existing Nexus (both links are so far unconnected) // so start one. tmp = new Nexus(l); tmp->connect(r); } } Link::Link() : dir_(PASSIVE), drive0_(IVL_DR_STRONG), drive1_(IVL_DR_STRONG), next_(0), nexus_(0) { node_ = 0; pin_zero_ = true; } Link::~Link() { if (next_) { Nexus*tmp = nexus(); tmp->unlink(this); if (tmp->list_ == 0) delete tmp; } } Nexus* Link::find_nexus_() const { assert(next_); if (nexus_) return nexus_; for (Link*cur = next_ ; cur != this ; cur = cur->next_) { if (cur->nexus_) return cur->nexus_; } return 0; } Nexus* Link::nexus() { if (next_ == 0) { assert(nexus_ == 0); Nexus*tmp = new Nexus(*this); return tmp; } return find_nexus_(); } const Nexus* Link::nexus() const { if (next_ == 0) return 0; return find_nexus_(); } void Link::set_dir(DIR d) { dir_ = d; } Link::DIR Link::get_dir() const { return dir_; } void Link::drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay) { find_nexus_()->drivers_delays(rise, fall, decay); } void Link::drivers_drive(ivl_drive_t drive0__, ivl_drive_t drive1__) { find_nexus_()->drivers_drive(drive0__, drive1__); } void Link::drive0(ivl_drive_t str) { drive0_ = str; } void Link::drive1(ivl_drive_t str) { drive1_ = str; } ivl_drive_t Link::drive0() const { return drive0_; } ivl_drive_t Link::drive1() const { return drive1_; } void Link::cur_link(NetPins*&net, unsigned &pin) { net = get_obj(); pin = get_pin(); } void Link::cur_link(const NetPins*&net, unsigned &pin) const { net = get_obj(); pin = get_pin(); } void Link::unlink() { if (! is_linked()) return; find_nexus_()->unlink(this); } bool Link::is_equal(const Link&that) const { return (get_obj() == that.get_obj()) && (get_pin() == that.get_pin()); } bool Link::is_linked() const { if (next_ == 0) return false; if (next_ == this) return false; return true; } bool Link::is_linked(const Link&that) const { // If this or that link is linked to nothing, then they cannot // be linked to each other. if (! this->is_linked()) return false; if (! that.is_linked()) return false; const Link*cur = next_; while (cur != this) { if (cur == &that) return true; cur = cur->next_; } return false; } Nexus::Nexus(Link&that) { name_ = 0; driven_ = NO_GUESS; t_cookie_ = 0; if (that.next_ == 0) { list_ = &that; that.next_ = &that; that.nexus_ = this; driven_ = NO_GUESS; } else { Nexus*tmp = that.find_nexus_(); list_ = tmp->list_; list_->nexus_ = this; driven_ = tmp->driven_; name_ = tmp->name_; tmp->list_ = 0; tmp->name_ = 0; delete tmp; } } Nexus::~Nexus() { assert(list_ == 0); delete[] name_; } bool Nexus::assign_lval() const { for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { const NetPins*obj; unsigned pin; cur->cur_link(obj, pin); const NetNet*net = dynamic_cast (obj); if (net == 0) continue; if (net->peek_lref() > 0) return true; } return false; } void Nexus::count_io(unsigned&inp, unsigned&out) const { for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { switch (cur->get_dir()) { case Link::INPUT: inp += 1; break; case Link::OUTPUT: out += 1; break; default: break; } } } bool Nexus::has_floating_input() const { bool found_input = false; for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur->get_dir() == Link::OUTPUT) return false; if (cur->get_dir() == Link::INPUT) found_input = true; } return found_input; } bool Nexus::drivers_present() const { for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur->get_dir() == Link::OUTPUT) return true; if (cur->get_dir() == Link::INPUT) continue; // Must be PASSIVE, so if it is some kind of net, see if // it is the sort that might drive the nexus. Note that // supply0/1 and tri0/1 nets are classified as OUTPUT. const NetPins*obj; unsigned pin; cur->cur_link(obj, pin); if (const NetNet*net = dynamic_cast(obj)) switch (net->type()) { case NetNet::WAND: case NetNet::WOR: case NetNet::TRIAND: case NetNet::TRIOR: case NetNet::REG: return true; default: break; } } return false; } void Nexus::drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay) { for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur->get_dir() != Link::OUTPUT) continue; NetObj*obj = dynamic_cast(cur->get_obj()); if (obj == 0) continue; obj->rise_time(rise); obj->fall_time(fall); obj->decay_time(decay); } } void Nexus::drivers_drive(ivl_drive_t drive0, ivl_drive_t drive1) { for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur->get_dir() != Link::OUTPUT) continue; cur->drive0(drive0); cur->drive1(drive1); } } void Nexus::unlink(Link*that) { delete[] name_; name_ = 0; assert(that); // Special case: the Link is the only link in the nexus. In // this case, the unlink is trivial. Also clear the Nexus // pointers. if (that->next_ == that) { assert(that->nexus_ == this); assert(list_ == that); list_ = 0; driven_ = NO_GUESS; that->nexus_ = 0; that->next_ = 0; return; } // If the link I'm removing was a driver for this nexus, then // cancel my guess of the driven value. if (that->get_dir() != Link::INPUT) driven_ = NO_GUESS; // Look for the Link that points to "that". We know that there // will be one because the list is a circle. When we find the // prev pointer, then remove that from the list. Link*prev = list_; while (prev->next_ != that) prev = prev->next_; prev->next_ = that->next_; // If "that" was the last item in the list, then change the // list_ pointer to point to the new end of the list. if (list_ == that) { assert(that->nexus_ == this); list_ = prev; list_->nexus_ = this; } that->nexus_ = 0; that->next_ = 0; } Link* Nexus::first_nlink() { if (list_) return list_->next_; else return 0; } const Link* Nexus::first_nlink() const { if (list_) return list_->next_; else return 0; } /* * The t_cookie can be set exactly once. This attaches an ivl_nexus_t * object to the Nexus, and causes the Link list to be marked up for * efficient use by the code generator. The change is to give all the * links a valid nexus_ pointer. This breaks most of the other * methods, but they are not used during code generation. */ void Nexus::t_cookie(ivl_nexus_t val) const { assert(val && !t_cookie_); t_cookie_ = val; for (Link*cur = list_->next_ ; cur->nexus_ == 0 ; cur = cur->next_) cur->nexus_ = const_cast (this); } unsigned Nexus::vector_width() const { for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { const NetNet*sig = dynamic_cast(cur->get_obj()); if (sig == 0) continue; return sig->vector_width(); } return 0; } NetNet* Nexus::pick_any_net() { for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { NetNet*sig = dynamic_cast(cur->get_obj()); if (sig != 0) return sig; } return 0; } NetNode* Nexus::pick_any_node() { for (Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { NetNode*node = dynamic_cast(cur->get_obj()); if (node != 0) return node; } return 0; } const char* Nexus::name() const { if (name_) return name_; const NetNet*sig = 0; unsigned pin = 0; for (const Link*cur = first_nlink() ; cur ; cur = cur->next_nlink()) { const NetNet*cursig = dynamic_cast(cur->get_obj()); if (cursig == 0) continue; if (sig == 0) { sig = cursig; pin = cur->get_pin(); continue; } if ((cursig->pin_count() == 1) && (sig->pin_count() > 1)) continue; if ((cursig->pin_count() > 1) && (sig->pin_count() == 1)) { sig = cursig; pin = cur->get_pin(); continue; } if (cursig->local_flag() && !sig->local_flag()) continue; if (cursig->name() < sig->name()) continue; sig = cursig; pin = cur->get_pin(); } if (sig == 0) { const Link*lnk = first_nlink(); const NetObj*obj = dynamic_cast(lnk->get_obj()); pin = lnk->get_pin(); cerr << "internal error: No signal for nexus of " << obj->name() << " pin " << pin << " type=" << typeid(*obj).name() << "?" << endl; ostringstream tmp; tmp << "nex=" << this << ends; const string tmps = tmp.str(); name_ = new char[strlen(tmps.c_str()) + 1]; strcpy(name_, tmps.c_str()); } else { assert(sig); ostringstream tmp; tmp << scope_path(sig->scope()) << "." << sig->name(); if (sig->pin_count() > 1) tmp << "<" << pin << ">"; tmp << ends; const string tmps = tmp.str(); name_ = new char[strlen(tmps.c_str()) + 1]; strcpy(name_, tmps.c_str()); } return name_; } NexusSet::NexusSet() { } NexusSet::~NexusSet() { for (size_t idx = 0 ; idx < items_.size() ; idx += 1) delete items_[idx]; } size_t NexusSet::size() const { return items_.size(); } void NexusSet::add(Nexus*that, unsigned base, unsigned wid) { assert(that); elem_t*cur = new elem_t(that, base, wid); if (items_.size() == 0) { items_.resize(1); items_[0] = cur; return; } unsigned ptr = bsearch_(*cur); if (ptr < items_.size()) { delete cur; return; } assert(ptr == items_.size()); items_.push_back(cur); } void NexusSet::add(NexusSet&that) { for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) add(that.items_[idx]->lnk.nexus(), that.items_[idx]->base, that.items_[idx]->wid); } void NexusSet::rem_(const NexusSet::elem_t*that) { if (items_.empty()) return; unsigned ptr = bsearch_(*that); if (ptr >= items_.size()) return; if (items_.size() == 1) { delete items_[0]; items_.clear(); return; } delete items_[ptr]; for (unsigned idx = ptr ; idx < (items_.size()-1) ; idx += 1) items_[idx] = items_[idx+1]; items_.pop_back(); } void NexusSet::rem(const NexusSet&that) { for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) rem_(that.items_[idx]); } unsigned NexusSet::find_nexus(const NexusSet::elem_t&that) const { return bsearch_(that); } NexusSet::elem_t& NexusSet::at (unsigned idx) { assert(idx < items_.size()); return *items_[idx]; } size_t NexusSet::bsearch_(const NexusSet::elem_t&that) const { for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) { if (*items_[idx] == that) return idx; } return items_.size(); } bool NexusSet::elem_t::contains(const struct elem_t&that) const { if (! lnk.is_linked(that.lnk)) return false; if (that.base < base) return false; if ((that.base+that.wid) > (base+wid)) return false; return true; } bool NexusSet::contains_(const NexusSet::elem_t&that) const { for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) { if (items_[idx]->contains(that)) return true; } return false; } bool NexusSet::contains(const NexusSet&that) const { for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) { if (! contains_(*that.items_[idx])) return false; } return true; } bool NexusSet::intersect(const NexusSet&that) const { for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) { size_t where = bsearch_(*that.items_[idx]); if (where == items_.size()) continue; return true; } return false; } iverilog-12_0/net_modulo.cc000066400000000000000000000041041435245347300160220ustar00rootroot00000000000000/* * 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 # include # include # include # include "netlist.h" # include "compiler.h" /* * 0 -- Result * 1 -- DataA * 2 -- DataB */ NetModulo::NetModulo(NetScope*s, perm_string n, unsigned wr, unsigned wa, unsigned wb) : NetNode(s, n, 3), width_r_(wr), width_a_(wa), width_b_(wb) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // DataA pin(2).set_dir(Link::INPUT); // DataB signed_flag_ = false; } NetModulo::~NetModulo() { } unsigned NetModulo::width_r() const { return width_r_; } unsigned NetModulo::width_a() const { return width_a_; } unsigned NetModulo::width_b() const { return width_b_; } Link& NetModulo::pin_Result() { return pin(0); } void NetModulo::set_signed(bool flag) { signed_flag_ = flag; } bool NetModulo::get_signed() const { return signed_flag_; } const Link& NetModulo::pin_Result() const { return pin(0); } Link& NetModulo::pin_DataA() { return pin(1); } const Link& NetModulo::pin_DataA() const { return pin(1); } Link& NetModulo::pin_DataB() { return pin(2); } const Link& NetModulo::pin_DataB() const { return pin(2); } iverilog-12_0/net_nex_input.cc000066400000000000000000000424241435245347300165430ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 # include # include # include # include "compiler.h" # include "netlist.h" # include "netmisc.h" using namespace std; NexusSet* NetExpr::nex_input(bool, bool, bool) const { cerr << get_fileline() << ": internal error: nex_input not implemented: " << *this << endl; return new NexusSet; } NexusSet* NetProc::nex_input(bool, bool, bool) const { cerr << get_fileline() << ": internal error: NetProc::nex_input not implemented" << endl; return new NexusSet; } NexusSet* NetEArrayPattern::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; for (size_t idx = 0 ; idx < items_.size() ; idx += 1) { if (items_[idx]==0) continue; NexusSet*tmp = items_[idx]->nex_input(rem_out, always_sens, nested_func); if (tmp == 0) continue; result->add(*tmp); delete tmp; } return result; } NexusSet* NetEBinary::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = left_->nex_input(rem_out, always_sens, nested_func); NexusSet*tmp = right_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; return result; } NexusSet* NetEConcat::nex_input(bool rem_out, bool always_sens, bool nested_func) const { if (parms_[0] == NULL) return new NexusSet; NexusSet*result = parms_[0]->nex_input(rem_out, always_sens, nested_func); for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { if (parms_[idx] == NULL) { delete result; return new NexusSet; } NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetEAccess::nex_input(bool, bool, bool) const { return new NexusSet; } /* * A constant has not inputs, so always return an empty set. */ NexusSet* NetEConst::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetECReal::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetEEvent::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetELast::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetENetenum::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetENew::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetENull::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetEProperty::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetEScope::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetESelect::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = base_? base_->nex_input(rem_out, always_sens, nested_func) : new NexusSet(); NexusSet*tmp = expr_->nex_input(rem_out, always_sens, nested_func); bool const_select = result->size() == 0; if (always_sens && const_select) { if (NetEConst *val = dynamic_cast (base_)) { assert(select_type() == IVL_SEL_OTHER); if (NetESignal *sig = dynamic_cast (expr_)) { delete tmp; tmp = sig->nex_input_base(rem_out, always_sens, nested_func, val->value().as_unsigned(), expr_width()); } else { cerr << get_fileline() << ": Sorry, cannot determine the sensitivity " << "for the select of " << *expr_ << ", using all bits." << endl; } } } result->add(*tmp); delete tmp; /* See the comment for NetESignal below. */ if (base_ && ! always_sens && warn_sens_entire_vec) { cerr << get_fileline() << ": warning: @* is sensitive to all " "bits in '" << *expr_ << "'." << endl; } return result; } /* * The $fread, etc. system functions can have NULL arguments. */ NexusSet* NetESFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (parms_.empty()) return result; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]) { NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } } return result; } NexusSet* NetEShallowCopy::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetESignal::nex_input(bool rem_out, bool always_sens, bool nested_func) const { return nex_input_base(rem_out, always_sens, nested_func, 0, 0); } NexusSet* NetESignal::nex_input_base(bool rem_out, bool always_sens, bool nested_func, unsigned base, unsigned width) const { /* * This is not what I would expect for the various selects (bit, * part, index, array). This code adds all the bits/array words * instead of building the appropriate select and then using it * as the trigger. Other simulators also add everything. */ bool const_select = false; unsigned const_word = 0; NexusSet*result = new NexusSet; /* Local signals are not added to the sensitivity list. */ if (net_->local_flag()) return result; /* If we have an array index add it to the sensitivity list. */ if (word_) { NexusSet*tmp; tmp = word_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; if (!always_sens && warn_sens_entire_arr) { cerr << get_fileline() << ": warning: @* is sensitive to all " << net_->unpacked_count() << " words in array '" << name() << "'." << endl; } if (always_sens) if (NetEConst *val = dynamic_cast (word_)) { const_select = true; const_word = val->value().as_unsigned(); } } if ((base == 0) && (width == 0)) width = net_->vector_width(); if (const_select) { result->add(net_->pin(const_word).nexus(), base, width); } else { for (unsigned idx = 0 ; idx < net_->pin_count() ; idx += 1) result->add(net_->pin(idx).nexus(), base, width); } return result; } NexusSet* NetETernary::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*tmp; NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func); tmp = true_val_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; tmp = false_val_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; return result; } NexusSet* NetEUFunc::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (always_sens) { NetFuncDef*func = func_->func_def(); // Avoid recursive function calls. static set func_set; if (!nested_func) func_set.clear(); if (!func_set.insert(func).second) return result; NexusSet*tmp = func->proc()->nex_input(rem_out, always_sens, true); // Remove the function inputs NexusSet*in = new NexusSet; for (unsigned idx = 0 ; idx < func->port_count() ; idx += 1) { NetNet*net = func->port(idx); assert(net->pin_count() == 1); in->add(net->pin(0).nexus(), 0, net->vector_width()); } tmp->rem(*in); delete in; result->add(*tmp); delete tmp; } return result; } NexusSet* NetEUnary::nex_input(bool rem_out, bool always_sens, bool nested_func) const { return expr_->nex_input(rem_out, always_sens, nested_func); } NexusSet* NetAlloc::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetAssign_::nex_input(bool rem_out, bool always_sens, bool nested_func) const { assert(! nest_); NexusSet*result = new NexusSet; if (word_) { NexusSet*tmp = word_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (base_) { NexusSet*tmp = base_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetAssignBase::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; // For the deassign and release statements there is no R-value. if (rval_) { NexusSet*tmp = rval_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } /* It is possible that the lval_ can have nex_input values. In particular, index expressions are statement inputs as well, so should be addressed here. */ for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) { NexusSet*tmp = cur->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } /* * The nex_input of a begin/end block is the NexusSet of bits that the * block reads from outside the block. That means it is the union of * the nex_input for all the substatements. * * The input set for a sequential set is not exactly the union of the * input sets because there is the possibility of intermediate values, * that don't deserve to be in the input set. To wit: * * begin * t = a + b; * c = ~t; * end * * In this example, "t" should not be in the input set because it is * used by the sequence as a temporary value. */ NexusSet* NetBlock::nex_input(bool rem_out, bool always_sens, bool nested_func) const { if (last_ == 0) return new NexusSet; if (! always_sens && (type_ != SEQU)) { cerr << get_fileline() << ": internal error: Sorry, " << "I don't know how to synthesize fork/join blocks." << endl; return new NexusSet; } NetProc*cur = last_->next_; /* This is the accumulated input set. */ NexusSet*result = new NexusSet; /* This is an accumulated output set. */ NexusSet*prev = new NexusSet; do { /* Get the inputs for the current statement. */ NexusSet*tmp = cur->nex_input(rem_out, always_sens, nested_func); /* Add the current input set to the accumulated input set. */ result->add(*tmp); delete tmp; /* Add the current outputs to the accumulated output set if * they are going to be removed from the input set below. */ if (rem_out) cur->nex_output(*prev); cur = cur->next_; } while (cur != last_->next_); /* Remove from the input set those bits that are outputs from other statements. They aren't really inputs to the block, just internal intermediate values. */ if (rem_out) result->rem(*prev); delete prev; return result; } /* * The inputs to a case statement are the inputs to the expression, * the inputs to all the guards, and the inputs to all the guarded * statements. */ NexusSet* NetCase::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func); for (size_t idx = 0 ; idx < items_.size() ; idx += 1) { /* Skip cases that have empty statements. */ if (items_[idx].statement == 0) continue; NexusSet*tmp = items_[idx].statement->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; /* Usually, this is the guard expression. The default case is special and is identified by a null guard. The default guard obviously has no input. */ if (items_[idx].guard) { tmp = items_[idx].guard->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } } return result; } NexusSet* NetCondit::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func); if (if_ != 0) { NexusSet*tmp = if_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (else_ != 0) { NexusSet*tmp = else_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetDisable::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetDoWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func); if (proc_) { NexusSet*tmp = proc_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetEvTrig::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetEvNBTrig::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetEvWait::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (statement_) { NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetForever::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (statement_) { NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetForLoop::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (init_expr_) { NexusSet*tmp = init_expr_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (condition_) { NexusSet*tmp = condition_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (step_statement_) { NexusSet*tmp = step_statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (statement_) { NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } if (gn_shared_loop_index_flag) { NexusSet*tmp = new NexusSet(); for (unsigned idx = 0 ; idx < index_->pin_count() ; idx += 1) tmp->add(index_->pin(idx).nexus(), 0, index_->vector_width()); result->rem(*tmp); delete tmp; } return result; } NexusSet* NetFree::nex_input(bool, bool, bool) const { return new NexusSet; } /* * The NetPDelay statement is a statement of the form * * # * * The nex_input set is the input set of the . Do *not* * include the input set of the because it does not affect the * result. The statement can be omitted. */ NexusSet* NetPDelay::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (statement_) { NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } NexusSet* NetRepeat::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = expr_->nex_input(rem_out, always_sens, nested_func); if (statement_) { NexusSet*tmp = statement_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } /* * The $display, etc. system tasks can have NULL arguments. */ NexusSet* NetSTask::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = new NexusSet; if (parms_.empty()) return result; for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]) { NexusSet*tmp = parms_[idx]->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } } return result; } /* * The NetUTask represents a call to a user defined task. There are no * parameters to consider, because the compiler already removed them * and converted them to blocking assignments. */ NexusSet* NetUTask::nex_input(bool, bool, bool) const { return new NexusSet; } NexusSet* NetWhile::nex_input(bool rem_out, bool always_sens, bool nested_func) const { NexusSet*result = cond_->nex_input(rem_out, always_sens, nested_func); if (proc_) { NexusSet*tmp = proc_->nex_input(rem_out, always_sens, nested_func); result->add(*tmp); delete tmp; } return result; } iverilog-12_0/net_nex_output.cc000066400000000000000000000111521435245347300167360ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 # include # include # include "netlist.h" # include "netmisc.h" using namespace std; void NetProc::nex_output(NexusSet&) { cerr << get_fileline() << ": internal error: NetProc::nex_output not implemented" << endl; cerr << get_fileline() << ": : on object type " << typeid(*this).name() << endl; } void NetAlloc::nex_output(NexusSet&) { } void NetAssign_::nex_output(NexusSet&out) { assert(! nest_); assert(sig_); unsigned use_word = 0; unsigned use_base = 0; unsigned use_wid = lwidth(); if (word_) { long tmp = 0; if (eval_as_long(tmp, word_)) { // A constant word select, so add the selected word. use_word = tmp; } else { // A variable word select. The obvious thing to do // is to add the whole array, but this could cause // NetBlock::nex_input() to overprune the input set. // As array access is not yet handled in synthesis, // I'll leave this as TBD - the output set is not // otherwise used when elaborating an always @* // block. return; } } Nexus*nex = sig_->pin(use_word).nexus(); if (base_) { // Unable to evaluate the bit/part select of // the l-value, so this is a mux. Pretty // sure I don't know how to handle this yet // in synthesis, so punt for now. // Even with constant bit/part select, we want to // return the entire signal as an output. The // context will need to sort out which bits are // actually assigned. use_base = 0; use_wid = nex->vector_width(); } out.add(nex, use_base, use_wid); } /* * Assignments have as output all the bits of the concatenated signals * of the l-value. */ void NetAssignBase::nex_output(NexusSet&out) { for (NetAssign_*cur = lval_ ; cur ; cur = cur->more) { cur->nex_output(out); } } void NetBlock::nex_output(NexusSet&out) { if (last_ == 0) return; NetProc*cur = last_; do { cur = cur->next_; cur->nex_output(out); } while (cur != last_); } void NetCase::nex_output(NexusSet&out) { for (size_t idx = 0 ; idx < items_.size() ; idx += 1) { // Empty statements clearly have no output. if (items_[idx].statement == 0) continue; items_[idx].statement->nex_output(out); } } void NetCondit::nex_output(NexusSet&out) { if (if_) if_->nex_output(out); if (else_) else_->nex_output(out); } void NetDisable::nex_output(NexusSet&) { } void NetDoWhile::nex_output(NexusSet&out) { if (proc_) proc_->nex_output(out); } void NetEvTrig::nex_output(NexusSet&) { } void NetEvNBTrig::nex_output(NexusSet&) { } void NetEvWait::nex_output(NexusSet&out) { if (statement_) statement_->nex_output(out); } void NetForever::nex_output(NexusSet&out) { if (statement_) statement_->nex_output(out); } void NetForLoop::nex_output(NexusSet&out) { if (statement_) statement_->nex_output(out); } void NetFree::nex_output(NexusSet&) { } void NetPDelay::nex_output(NexusSet&out) { if (statement_) statement_->nex_output(out); } void NetRepeat::nex_output(NexusSet&out) { if (statement_) statement_->nex_output(out); } /* * For the purposes of synthesis, system task calls have no output at * all. This is OK because most system tasks are not synthesizable in * the first place. */ void NetSTask::nex_output(NexusSet&) { } /* * Consider a task call to not have any outputs. This is not quite * right, we should be listing as outputs all the output ports, but for * the purposes that this method is used, this will do for now. */ void NetUTask::nex_output(NexusSet&) { } void NetWhile::nex_output(NexusSet&out) { if (proc_) proc_->nex_output(out); } iverilog-12_0/net_proc.cc000066400000000000000000000155001435245347300154700ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 "compiler.h" # include "netlist.h" # include "netmisc.h" # include "ivl_assert.h" using namespace std; NetBlock::NetBlock(Type t, NetScope*ss) : type_(t), subscope_(ss), last_(0) { } NetBlock::~NetBlock() { while (last_ != 0) { if (last_->next_ == last_) { delete last_; last_ = 0; } else { NetProc*cur = last_->next_; last_->next_ = cur->next_; cur->next_ = cur; delete cur; } } } void NetBlock::append(NetProc*cur) { if (last_ == 0) { last_ = cur; cur->next_ = cur; } else { cur->next_ = last_->next_; last_->next_ = cur; last_ = cur; } } void NetBlock::prepend(NetProc*cur) { if (last_ == 0) { last_ = cur; cur->next_ = cur; } else { cur->next_ = last_->next_; last_->next_ = cur; } } const NetProc* NetBlock::proc_first() const { if (last_ == 0) return 0; return last_->next_; } const NetProc* NetBlock::proc_next(const NetProc*cur) const { if (cur == last_) return 0; return cur->next_; } NetCase::NetCase(ivl_case_quality_t q, NetCase::TYPE c, NetExpr*ex, unsigned cnt) : quality_(q), type_(c), expr_(ex), items_(cnt) { ivl_assert(*this, expr_); } NetCase::~NetCase() { delete expr_; for (size_t idx = 0 ; idx < items_.size() ; idx += 1) { delete items_[idx].guard; if (items_[idx].statement) delete items_[idx].statement; } } NetCase::TYPE NetCase::type() const { return type_; } void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p) { ivl_assert(*this, idx < items_.size()); items_[idx].guard = e; items_[idx].statement = p; } void NetCase::prune() { // Test whether the case expression has been padded out NetESelect*padded_expr = dynamic_cast(expr_); if ((padded_expr == 0) || (padded_expr->select() != 0)) return; // If so, run through the case item expressions to find // the minimum number of bits needed to unambiguously // select the correct case item. const NetExpr*unpadded_expr = padded_expr->sub_expr(); unsigned padded_width = padded_expr->expr_width(); unsigned prune_width = unpadded_expr->expr_width(); for (unsigned idx = 0; idx < items_.size(); idx += 1) { // If there is no guard expression, this is the default // case, so skip it. if (items_[idx].guard == 0) continue; // If the guard expression is not constant, assume // all bits are needed, so no pruning can be done. NetEConst*gc = dynamic_cast(items_[idx].guard); if (gc == 0) return; unsigned sig_bits = gc->value().significant_bits(); if (sig_bits > prune_width) prune_width = sig_bits; // If all the padding bits are needed, no pruning // can be done. if (prune_width >= padded_width) return; } ivl_assert(*this, prune_width < padded_width); if (debug_elaborate) { cerr << get_fileline() << ": debug: pruning case expressions to " << prune_width << " bits." << endl; } // Prune the case expression expr_ = pad_to_width(unpadded_expr->dup_expr(), prune_width, *expr_); delete padded_expr; // Prune the case item expressions for (unsigned idx = 0; idx < items_.size(); idx += 1) { if (items_[idx].guard == 0) continue; NetEConst*gc = dynamic_cast(items_[idx].guard); ivl_assert(*this, gc); verinum value(gc->value(), prune_width); NetEConst*tmp = new NetEConst(value); tmp->set_line(*gc); delete gc; items_[idx].guard = tmp; } } NetDisable::NetDisable(NetScope*tgt, bool flow_control) : target_(tgt), flow_control_(flow_control) { } NetDisable::~NetDisable() { } const NetScope* NetDisable::target() const { return target_; } NetForever::NetForever(NetProc*p) : statement_(p) { } NetForever::~NetForever() { delete statement_; } NetForLoop::NetForLoop(NetNet*ind, NetExpr*iexpr, NetExpr*cond, NetProc*sub, NetProc*step) : index_(ind), init_expr_(iexpr), condition_(cond), statement_(sub), step_statement_(step) { as_block_ = NULL; } void NetForLoop::wrap_up() { NetBlock*top = new NetBlock(NetBlock::SEQU, 0); // Handle the case that we are missing the initialization // statement. This can happen for example with statments like this: // for ( ; ; ) ; // If the index_ and init_expr_ are present, then generate the // inital assignment and push it into the sequential block. if (index_ || init_expr_) { top->set_line(*this); NetAssign_*lv = new NetAssign_(index_); NetAssign*set_stmt = new NetAssign(lv, init_expr_); set_stmt->set_line(*init_expr_); top->append(set_stmt); } NetBlock*internal_block = new NetBlock(NetBlock::SEQU, 0); internal_block->set_line(*this); if (statement_) internal_block->append(statement_); // The step statement is optional. If missing, it is assumed that // the programmer has added it to the regular statement. Hopefully. if (step_statement_) internal_block->append(step_statement_); NetWhile*wloop = new NetWhile(condition_, internal_block); wloop->set_line(*this); top->append(wloop); as_block_ = top; } NetForLoop::~NetForLoop() { delete init_expr_; delete condition_; delete statement_; delete step_statement_; } NetPDelay::NetPDelay(uint64_t d, NetProc*st) : delay_(d), expr_(0), statement_(st) { } NetPDelay::NetPDelay(NetExpr*d, NetProc*st) : delay_(0), expr_(d), statement_(st) { } NetPDelay::~NetPDelay() { delete expr_; } uint64_t NetPDelay::delay() const { ivl_assert(*this, expr_ == 0); return delay_; } const NetExpr* NetPDelay::expr() const { return expr_; } NetRepeat::NetRepeat(NetExpr*e, NetProc*p) : expr_(e), statement_(p) { } NetRepeat::~NetRepeat() { delete expr_; delete statement_; } const NetExpr* NetRepeat::expr() const { return expr_; } iverilog-12_0/net_scope.cc000066400000000000000000000522001435245347300156340ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch) * * 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 "compiler.h" # include "netlist.h" # include "netclass.h" # include "netenum.h" # include "netvector.h" # include "PExpr.h" # include "PPackage.h" # include # include # include # include "ivl_assert.h" using namespace std; class PExpr; Definitions::Definitions() { } Definitions::~Definitions() { } void Definitions::add_enumeration_set(const enum_type_t*key, netenum_t*enum_set) { netenum_t*&tmp = enum_sets_[key]; assert(tmp == 0); tmp = enum_set; } bool Definitions::add_enumeration_name(netenum_t*enum_set, perm_string name) { netenum_t::iterator enum_val = enum_set->find_name(name); assert(enum_val != enum_set->end_name()); NetEConstEnum*val = new NetEConstEnum(name, enum_set, enum_val->second); pair::iterator, bool> cur; cur = enum_names_.insert(make_pair(name,val)); // Return TRUE if the name is added (i.e. is NOT a duplicate.) return cur.second; } netenum_t* Definitions::enumeration_for_key(const enum_type_t*key) const { map::const_iterator cur; cur = enum_sets_.find(key); if (cur != enum_sets_.end()) return cur->second; else return 0; } /* * This locates the VALUE for the given enumeration literal. */ const NetExpr* Definitions::enumeration_expr(perm_string key) { map::const_iterator eidx; eidx = enum_names_.find(key); if (eidx != enum_names_.end()) { return eidx->second; } else { return 0; } } void Definitions::add_class(netclass_t*net_class) { classes_[net_class->get_name()] = net_class; } /* * The NetScope class keeps a scope tree organized. Each node of the * scope tree points to its parent, its right sibling and its leftmost * child. The root node has no parent or siblings. The node stores the * name of the scope. The complete hierarchical name of the scope is * formed by appending the path of scopes from the root to the scope * in question. */ NetScope::NetScope(NetScope*up, const hname_t&n, NetScope::TYPE t, NetScope*in_unit, bool nest, bool program, bool interface, bool compilation_unit) : type_(t), name_(n), nested_module_(nest), program_block_(program), is_interface_(interface), is_unit_(compilation_unit), unit_(in_unit), up_(up) { imports_ = 0; events_ = 0; lcounter_ = 0; is_auto_ = false; is_cell_ = false; calls_stask_ = false; in_final_ = false; if (compilation_unit) unit_ = this; if (up) { need_const_func_ = up->need_const_func_; is_const_func_ = up->is_const_func_; time_unit_ = up->time_unit(); time_prec_ = up->time_precision(); time_from_timescale_ = up->time_from_timescale(); // Need to check for duplicate names? up_->children_[name_] = this; if (unit_ == 0) unit_ = up_->unit_; } else { need_const_func_ = false; is_const_func_ = false; time_unit_ = 0; time_prec_ = 0; time_from_timescale_ = false; } var_init_ = 0; switch (t) { case NetScope::TASK: task_ = 0; break; case NetScope::FUNC: func_ = 0; break; case NetScope::MODULE: case NetScope::PACKAGE: module_name_ = perm_string(); break; case NetScope::CLASS: class_def_ = 0; break; default: /* BEGIN_END and FORK_JOIN, do nothing */ break; } func_pform_ = 0; elab_stage_ = 1; lineno_ = 0; def_lineno_ = 0; genvar_tmp_val = 0; tie_hi_ = 0; tie_lo_ = 0; } NetScope::~NetScope() { lcounter_ = 0; /* name_ and module_name_ are perm-allocated. */ } void NetScope::set_line(const LineInfo*info) { file_ = info->get_file(); def_file_ = file_; lineno_ = info->get_lineno(); def_lineno_ = lineno_; } void NetScope::set_line(perm_string file, unsigned lineno) { file_ = file; def_file_ = file; lineno_ = lineno; def_lineno_ = lineno; } string NetScope::get_fileline() const { ostringstream buf; buf << (file_? file_ : "") << ":" << lineno_; string res = buf.str(); return res; } string NetScope::get_def_fileline() const { ostringstream buf; buf << (def_file_? def_file_ : "") << ":" << def_lineno_; string res = buf.str(); return res; } void NetScope::set_line(perm_string file, perm_string def_file, unsigned lineno, unsigned def_lineno) { file_ = file; def_file_ = def_file; lineno_ = lineno; def_lineno_ = def_lineno; } void NetScope::add_imports(const map*imports) { if (!imports->empty()) imports_ = imports; } NetScope*NetScope::find_import(const Design*des, perm_string name) { if (imports_ == 0) return 0; map::const_iterator cur = imports_->find(name); if (cur != imports_->end()) { return des->find_package(cur->second->pscope_name()); } else return 0; } void NetScope::add_typedefs(const map*typedefs) { if (!typedefs->empty()) typedefs_ = *typedefs; } NetScope*NetScope::find_typedef_scope(const Design*des, const typedef_t*type) { assert(type); NetScope *cur_scope = this; while (cur_scope) { auto it = cur_scope->typedefs_.find(type->name); if (it != cur_scope->typedefs_.end() && it->second == type) return cur_scope; NetScope*import_scope = cur_scope->find_import(des, type->name); if (import_scope) cur_scope = import_scope; else if (cur_scope == unit_) return 0; else cur_scope = cur_scope->parent(); if (cur_scope == 0) cur_scope = unit_; } return 0; } /* * Attach to the a parameter name in the scope a value and a type. The value * (val_expr) is the PExpr form that is not yet elaborated. Later, when * elaboration happens, the val_expr is elaborated and written to the val * member. */ void NetScope::set_parameter(perm_string key, bool is_annotatable, const LexicalScope::param_expr_t ¶m, NetScope::range_t *range_list) { param_expr_t&ref = parameters[key]; ref.is_annotatable = is_annotatable; ref.val_expr = param.expr; ref.val_type = param.data_type; ref.val_scope = this; ref.local_flag = param.local_flag; ref.overridable = param.overridable; ref.type_flag = param.type_flag; ivl_assert(param, !ref.range); ref.range = range_list; ref.val = 0; ref.ivl_type = 0; ref.set_line(param); } /* * This is a simplified version of set_parameter, for use when the * parameter value is already known. It is currently only used to * add a genvar to the parameter list. */ void NetScope::set_parameter(perm_string key, NetExpr*val, const LineInfo&file_line) { param_expr_t&ref = parameters[key]; ref.is_annotatable = false; ref.val_expr = 0; ref.val_type = 0; ref.val_scope = this; ref.ivl_type = netvector_t::integer_type(); ivl_assert(file_line, ref.ivl_type); ref.val = val; ref.set_line(file_line); } bool NetScope::auto_name(const char*prefix, char pad, const char* suffix) { // Find the current reference to myself in the parent scope. map::iterator self = up_->children_.find(name_); assert(self != up_->children_.end()); assert(self->second == this); // This is to keep the pad attempts from being stuck in some // sort of infinite loop. This should not be a practical // limit, but an extreme one. const size_t max_pad_attempts = 32 + strlen(prefix); string use_prefix = prefix; // Try a variety of potential new names. Make sure the new // name is not in the parent scope. Keep looking until we are // sure we have a unique name, or we run out of names to try. while (use_prefix.size() <= max_pad_attempts) { // Try this name... string tmp = use_prefix + suffix; perm_string base_name = lex_strings.make(tmp.c_str()); hname_t new_name(base_name, name_.peek_numbers()); if (!up_->child(new_name) && !up_->symbol_exists(base_name)) { // Ah, this name is unique. Rename myself, and // change my name in the parent scope. name_ = new_name; up_->children_.erase(self); up_->children_[name_] = this; return true; } // Name collides, so try a different name. use_prefix = use_prefix + pad; } return false; } /* * Return false if the parameter does not already exist. * A parameter is not automatically created. */ void NetScope::replace_parameter(Design *des, perm_string key, PExpr*val, NetScope*scope, bool defparam) { if (parameters.find(key) == parameters.end()) { cerr << val->get_fileline() << ": error: parameter `" << key << "` not found in `" << scope_path(this) << "`." << endl; des->errors++; return; } param_expr_t&ref = parameters[key]; if (ref.local_flag) { cerr << val->get_fileline() << ": error: " << "Cannot override localparam `" << key << "` in `" << scope_path(this) << "`." << endl; des->errors++; return; } if (!ref.overridable) { cerr << val->get_fileline() << ": error: " << "Cannot override parameter `" << key << "` in `" << scope_path(this) << "`. Parameter cannot be overriden " << "in the scope it has been declared in." << endl; des->errors++; return; } if (ref.type_flag && defparam) { cerr << val->get_fileline() << ": error: " << "Cannot override type parameter `" << key << "` in `" << scope_path(this) << "`. It is not allowed to override type" << " parameters using a defparam statement." << endl; des->errors++; return; } ref.val_expr = val; ref.val_scope = scope; } bool NetScope::make_parameter_unannotatable(perm_string key) { bool flag = false; if (parameters.find(key) != parameters.end()) { param_expr_t&ref = parameters[key]; flag = ref.is_annotatable; ref.is_annotatable = false; } return flag; } /* * NOTE: This method takes a const char* as a key to lookup a * parameter, because we don't save that pointer. However, due to the * way the map<> template works, we need to *cheat* and use the * perm_string::literal method to fake the compiler into doing the * compare without actually creating a perm_string. */ const NetExpr* NetScope::get_parameter(Design*des, const char* key, ivl_type_t&ivl_type) { return get_parameter(des, perm_string::literal(key), ivl_type); } const NetExpr* NetScope::get_parameter(Design*des, perm_string key, ivl_type_t&ivl_type) { map::iterator idx; idx = parameters.find(key); if (idx != parameters.end()) { if (idx->second.val_expr) evaluate_parameter_(des, idx); ivl_type = idx->second.ivl_type; return idx->second.val; } ivl_type = 0; const NetExpr*tmp = enumeration_expr(key); return tmp; } LineInfo NetScope::get_parameter_line_info(perm_string key) const { map::const_iterator idx; idx = parameters.find(key); if (idx != parameters.end()) return idx->second; // To get here the parameter must already exist, so we should // never get here. assert(0); // But return something to avoid a compiler warning. return LineInfo(); } void NetScope::print_type(ostream&stream) const { switch (type_) { case BEGIN_END: stream << "sequential block"; break; case FORK_JOIN: stream << "parallel block"; break; case FUNC: stream << "function"; break; case MODULE: stream << "module <" << module_name_ << "> instance"; break; case TASK: stream << "task"; break; case GENBLOCK: stream << "generate block"; break; case PACKAGE: stream << "package " << module_name_; break; case CLASS: stream << "class"; break; } } void NetScope::set_task_def(NetTaskDef*def) { assert( type_ == TASK ); assert( task_ == 0 ); task_ = def; } NetTaskDef* NetScope::task_def() { assert( type_ == TASK ); return task_; } const NetTaskDef* NetScope::task_def() const { assert( type_ == TASK ); return task_; } void NetScope::set_func_def(NetFuncDef*def) { assert( type_ == FUNC ); assert( func_ == 0 ); func_ = def; } NetFuncDef* NetScope::func_def() { assert( type_ == FUNC ); return func_; } bool NetScope::in_func() const { return (type_ == FUNC) ? true : false; } const NetFuncDef* NetScope::func_def() const { assert( type_ == FUNC ); return func_; } void NetScope::set_class_def(netclass_t*def) { assert( type_ == CLASS ); assert( class_def_==0 ); class_def_ = def; } const netclass_t* NetScope::class_def(void) const { if (type_==CLASS) return class_def_; else return 0; } void NetScope::set_module_name(perm_string n) { assert(type_==MODULE || type_==PACKAGE); module_name_ = n; } perm_string NetScope::module_name() const { assert(type_==MODULE || type_==PACKAGE); return module_name_; } void NetScope::set_num_ports(unsigned int num_ports) { assert(type_ == MODULE); assert(ports_.empty()); ports_.resize( num_ports ); } void NetScope::add_module_port_net(NetNet*subport) { assert(type_ == MODULE); port_nets.push_back(subport); } void NetScope::add_module_port_info( unsigned idx, perm_string name, PortType::Enum ptype, unsigned long width ) { assert(type_ == MODULE); assert(ports_.size() > idx); PortInfo &info = ports_[idx]; info.name = name; info.type = ptype; info.width = width; } unsigned NetScope::module_port_nets() const { assert(type_ == MODULE); return port_nets.size(); } const std::vector & NetScope::module_port_info() const { assert(type_ == MODULE); return ports_; } NetNet* NetScope::module_port_net(unsigned idx) const { assert(type_ == MODULE); assert(idx < port_nets.size()); return port_nets[idx]; } void NetScope::time_unit(int val) { time_unit_ = val; } void NetScope::time_precision(int val) { time_prec_ = val; } void NetScope::time_from_timescale(bool val) { time_from_timescale_ = val; } int NetScope::time_unit() const { return time_unit_; } int NetScope::time_precision() const { return time_prec_; } bool NetScope::time_from_timescale() const { return time_from_timescale_; } perm_string NetScope::basename() const { return name_.peek_name(); } void NetScope::add_event(NetEvent*ev) { assert(ev->scope_ == 0); ev->scope_ = this; ev->snext_ = events_; events_ = ev; } void NetScope::rem_event(NetEvent*ev) { assert(ev->scope_ == this); ev->scope_ = 0; if (events_ == ev) { events_ = ev->snext_; } else { NetEvent*cur = events_; while (cur->snext_ != ev) { assert(cur->snext_); cur = cur->snext_; } cur->snext_ = ev->snext_; } ev->snext_ = 0; } NetEvent* NetScope::find_event(perm_string name) { for (NetEvent*cur = events_; cur ; cur = cur->snext_) if (cur->name() == name) return cur; return 0; } void NetScope::add_genvar(perm_string name, LineInfo *li) { assert((type_ == MODULE) || (type_ == GENBLOCK)); genvars_[name] = li; } LineInfo* NetScope::find_genvar(perm_string name) { if (genvars_.find(name) != genvars_.end()) return genvars_[name]; else return 0; } void NetScope::add_signal(NetNet*net) { signals_map_[net->name()]=net; } void NetScope::rem_signal(NetNet*net) { assert(net->scope() == this); signals_map_.erase(net->name()); } /* * This method looks for a signal within the current scope. The name * is assumed to be the base name of the signal, so no sub-scopes are * searched. */ NetNet* NetScope::find_signal(perm_string key) { if (signals_map_.find(key)!=signals_map_.end()) return signals_map_[key]; else return 0; } netclass_t*NetScope::find_class(const Design*des, perm_string name) { // Special case: The scope itself is the class that we are // looking for. This may happen for example when elaborating // methods within the class. if (type_==CLASS && name_==hname_t(name)) return class_def_; // Look for the class directly within this scope. map::const_iterator cur = classes_.find(name); if (cur != classes_.end()) return cur->second; // Try the imports. NetScope*import_scope = find_import(des, name); if (import_scope) return import_scope->find_class(des, name); if (up_==0 && type_==CLASS) { assert(class_def_); NetScope*def_parent = class_def_->definition_scope(); return def_parent->find_class(des, name); } // Try looking up for the class. if (up_!=0 && type_!=MODULE) return up_->find_class(des, name); // Try the compilation unit. if (unit_ != 0 && this != unit_) return unit_->find_class(des, name); // Nowhere left to try... return 0; } /* * This method locates a child scope by name. The name is the simple * name of the child, no hierarchy is searched. */ NetScope* NetScope::child(const hname_t&name) { map::iterator cur = children_.find(name); if (cur == children_.end()) return 0; else return cur->second; } const NetScope* NetScope::child(const hname_t&name) const { map::const_iterator cur = children_.find(name); if (cur == children_.end()) return 0; else return cur->second; } /* Helper function to see if the given scope is defined in a class and if * so return the class scope. */ const NetScope* NetScope::get_class_scope() const { const NetScope*scope = this; while (scope) { switch(scope->type()) { case NetScope::CLASS: return scope; case NetScope::TASK: case NetScope::FUNC: case NetScope::BEGIN_END: case NetScope::FORK_JOIN: break; case NetScope::MODULE: case NetScope::GENBLOCK: case NetScope::PACKAGE: return 0; default: assert(0); } scope = scope->parent(); } return scope; } const NetScope* NetScope::child_byname(perm_string name) const { hname_t hname (name); map::const_iterator cur = children_.lower_bound(hname); if (cur == children_.end()) return 0; if (cur->first.peek_name() == name) return cur->second; return 0; } bool NetScope::symbol_exists(perm_string sym) { if (signals_map_.find(sym) != signals_map_.end()) return true; if (parameters.find(sym) != parameters.end()) return true; if (genvars_.find(sym) != genvars_.end()) return true; if (classes_.find(sym) != classes_.end()) return true; if (typedefs_.find(sym) != typedefs_.end()) return true; if (find_event(sym)) return true; return false; } perm_string NetScope::local_symbol() { perm_string sym; do { ostringstream res; res << "_ivl_" << (lcounter_++); perm_string sym_tmp = lex_strings.make(res.str()); // If the name already exists, try again. if (symbol_exists(sym_tmp)) continue; // No collisions, this is the one. sym = sym_tmp; } while (sym.nil()); return sym; } void NetScope::add_tie_hi(Design*des) { if (tie_hi_ == 0) { NetNet*sig = new NetNet(this, lex_strings.make("_LOGIC1"), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); tie_hi_ = new NetLogic(this, local_symbol(), 1, NetLogic::PULLUP, 1); des->add_node(tie_hi_); connect(sig->pin(0), tie_hi_->pin(0)); } } void NetScope::add_tie_lo(Design*des) { if (tie_lo_ == 0) { NetNet*sig = new NetNet(this, lex_strings.make("_LOGIC0"), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); tie_lo_ = new NetLogic(this, local_symbol(), 1, NetLogic::PULLDOWN, 1); des->add_node(tie_lo_); connect(sig->pin(0), tie_lo_->pin(0)); } } iverilog-12_0/net_tran.cc000066400000000000000000000114751435245347300155000ustar00rootroot00000000000000/* * Copyright (c) 2008-2021 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 # include # include # include "compiler.h" # include "netlist.h" # include "netmisc.h" # include "ivl_target_priv.h" # include "ivl_assert.h" using namespace std; static bool has_enable(ivl_switch_type_t tt) { switch (tt) { case IVL_SW_TRANIF0: case IVL_SW_TRANIF1: case IVL_SW_RTRANIF0: case IVL_SW_RTRANIF1: return true; default: return false; } } NetTran::NetTran(NetScope*scope__, perm_string n, ivl_switch_type_t tt, unsigned width) : NetNode(scope__, n, has_enable(tt)? 3 : 2), type_(tt), wid_(width) { pin(0).set_dir(Link::PASSIVE); pin(1).set_dir(Link::PASSIVE); if (pin_count() == 3) { pin(2).set_dir(Link::INPUT); // Enable } part_ = 0; off_ = 0; } NetTran::NetTran(NetScope*scope__, perm_string n, unsigned wid, unsigned part, unsigned off) : NetNode(scope__, n, 2), type_(IVL_SW_TRAN_VP), wid_(wid), part_(part), off_(off) { pin(0).set_dir(Link::PASSIVE); pin(1).set_dir(Link::PASSIVE); } NetTran::~NetTran() { } unsigned NetTran::vector_width() const { return wid_; } unsigned NetTran::part_width() const { return part_; } unsigned NetTran::part_offset() const { return off_; } void join_island(NetPins*obj) { IslandBranch*branch = dynamic_cast (obj); // If this is not even a branch, then stop now. if (branch == 0) return; // If this is a branch, but already given to an island, then // stop. if (branch->island_) return; list uncommitted_neighbors; // Look for neighboring objects that might already be in // islands. If we find something, then join that island. for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) { Nexus*nex = obj->pin(idx).nexus(); for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { unsigned pin; NetPins*tmp_pins; cur->cur_link(tmp_pins, pin); NetObj*tmp = dynamic_cast (tmp_pins); if (tmp == 0) continue; // Skip self. if (tmp == obj) continue; // If tmp is not a branch, then skip it. IslandBranch*tmp_branch = dynamic_cast (tmp); if (tmp_branch == 0) continue; // If tmp is an uncommitted branch, then save // it. When I finally choose an island for self, // these branches will be scanned so that they join // this island as well. if (tmp_branch->island_ == 0) { uncommitted_neighbors.push_back(tmp); continue; } ivl_assert(*obj, branch->island_==0 || branch->island_==tmp_branch->island_); // We found an existing island to join. Join it // now. Keep scanning in order to find more neighbors. if (branch->island_ == 0) { if (debug_elaborate) cerr << obj->get_fileline() << ": debug: " << "Join branch to existing island." << endl; branch->island_ = tmp_branch->island_; ivl_assert(*obj, branch->island_->discipline == tmp_branch->island_->discipline); } else if (branch->island_ != tmp_branch->island_) { cerr << obj->get_fileline() << ": internal error: " << "Oops, Found 2 neighboring islands." << endl; ivl_assert(*obj, 0); } } } // If after all that we did not find an island to join, then // start the island not and join it. if (branch->island_ == 0) { branch->island_ = new ivl_island_s; branch->island_->discipline = branch->discipline_; if (debug_elaborate) cerr << obj->get_fileline() << ": debug: " << "Create new island for this branch" << endl; } // Now scan all the uncommitted neighbors I found. Calling // join_island() on them will cause them to notice me in the // process, and thus they will join my island. This process // will recurse until all the connected branches join this island. for (list::iterator cur = uncommitted_neighbors.begin() ; cur != uncommitted_neighbors.end() ; ++ cur ) { join_island(*cur); } } iverilog-12_0/net_udp.cc000066400000000000000000000046331435245347300153220ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2001 Stephan Boettcher * * 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 "compiler.h" # include "netlist.h" using namespace std; NetUDP::NetUDP(NetScope*s, perm_string n, unsigned pins, PUdp *u) : NetNode(s, n, pins), udp(u) { pin(0).set_dir(Link::OUTPUT); for (unsigned idx = 1 ; idx < pins ; idx += 1) { pin(idx).set_dir(Link::INPUT); } table_idx = udp->tinput.size() - 1; } bool NetUDP::first(string&inp, char&out) const { table_idx = (unsigned) -1; return next(inp, out); } bool NetUDP::next(string&inp, char&out) const { table_idx++; if (table_idx >= udp->tinput.size()) return false; if (is_sequential()) { inp = string("") + udp->tcurrent[table_idx] + udp->tinput[table_idx]; assert(inp.length() == pin_count()); } else { inp = udp->tinput[table_idx]; assert(inp.length() == (pin_count()-1)); } out = udp->toutput[table_idx]; assert((out == '0') || (out == '1') || (out == 'x') || (is_sequential() && (out == '-'))); return true; } char NetUDP::get_initial() const { assert (is_sequential()); switch (udp->initial) { case verinum::V0: return '0'; case verinum::V1: return '1'; case verinum::Vx: case verinum::Vz: return 'x'; } assert(0); return 'x'; } unsigned NetUDP::port_count() const { return udp->ports.size(); } string NetUDP::port_name(unsigned idx) const { assert(idx < udp->ports.size()); return udp->ports[idx]; } iverilog-12_0/netclass.cc000066400000000000000000000127071435245347300155010ustar00rootroot00000000000000/* * Copyright (c) 2012-2017 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 "netclass.h" # include "netlist.h" # include using namespace std; netclass_t::netclass_t(perm_string name, const netclass_t*super) : name_(name), super_(super), class_scope_(0), definition_scope_(0) { } netclass_t::~netclass_t() { } bool netclass_t::set_property(perm_string pname, property_qualifier_t qual, ivl_type_t ptype) { map::const_iterator cur; cur = properties_.find(pname); if (cur != properties_.end()) return false; prop_t tmp; tmp.name = pname; tmp.qual = qual; tmp.type = ptype; tmp.initialized_flag = false; property_table_.push_back(tmp); properties_[pname] = property_table_.size()-1; return true; } void netclass_t::set_class_scope(NetScope*class_scope__) { assert(class_scope_ == 0); class_scope_ = class_scope__; } void netclass_t::set_definition_scope(NetScope*use_definition_scope) { assert(definition_scope_ == 0); definition_scope_ = use_definition_scope; } ivl_variable_type_t netclass_t::base_type() const { return IVL_VT_CLASS; } size_t netclass_t::get_properties(void) const { size_t res = properties_.size(); if (super_) res += super_->get_properties(); return res; } int netclass_t::property_idx_from_name(perm_string pname) const { map::const_iterator cur; cur = properties_.find(pname); if (cur == properties_.end()) { if (super_) return super_->property_idx_from_name(pname); else return -1; } int pidx = cur->second; if (super_) pidx += super_->get_properties(); return pidx; } const char*netclass_t::get_prop_name(size_t idx) const { size_t super_size = 0; if (super_) super_size = super_->get_properties(); assert(idx < (super_size + property_table_.size())); if (idx < super_size) return super_->get_prop_name(idx); else return property_table_[idx-super_size].name; } property_qualifier_t netclass_t::get_prop_qual(size_t idx) const { size_t super_size = 0; if (super_) super_size = super_->get_properties(); assert(idx < (super_size+property_table_.size())); if (idx < super_size) return super_->get_prop_qual(idx); else return property_table_[idx-super_size].qual; } ivl_type_t netclass_t::get_prop_type(size_t idx) const { size_t super_size = 0; if (super_) super_size = super_->get_properties(); assert(idx < (super_size+property_table_.size())); if (idx < super_size) return super_->get_prop_type(idx); else return property_table_[idx-super_size].type; } bool netclass_t::get_prop_initialized(size_t idx) const { size_t super_size = 0; if (super_) super_size = super_->get_properties(); assert(idx < (super_size+property_table_.size())); if (idx < super_size) return super_->get_prop_initialized(idx); else return property_table_[idx].initialized_flag; } void netclass_t::set_prop_initialized(size_t idx) const { size_t super_size = 0; if (super_) super_size = super_->get_properties(); assert(idx >= super_size && idx < (super_size+property_table_.size())); idx -= super_size; assert(! property_table_[idx].initialized_flag); property_table_[idx].initialized_flag = true; } bool netclass_t::test_for_missing_initializers() const { for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) { if (property_table_[idx].initialized_flag) continue; if (property_table_[idx].qual.test_const()) return true; } return false; } NetScope*netclass_t::method_from_name(perm_string name) const { NetScope*task = class_scope_->child( hname_t(name) ); if ((task == 0) && super_) task = super_->method_from_name(name); return task; } NetNet* netclass_t::find_static_property(perm_string name) const { NetNet*tmp = class_scope_->find_signal(name); return tmp; } bool netclass_t::test_scope_is_method(const NetScope*scope) const { while (scope && scope != class_scope_) { scope = scope->parent(); } if (scope == 0) return false; else return true; } const NetExpr* netclass_t::get_parameter(Design *des, perm_string name, ivl_type_t &par_type) const { return class_scope_->get_parameter(des, name, par_type); } bool netclass_t::test_compatibility(ivl_type_t that) const { for (const netclass_t *class_type = dynamic_cast(that); class_type; class_type = class_type->get_super()) { if (class_type == this) return true; } return false; } iverilog-12_0/netclass.h000066400000000000000000000123711435245347300153400ustar00rootroot00000000000000#ifndef IVL_netclass_H #define IVL_netclass_H /* * Copyright (c) 2012-2021 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 "LineInfo.h" # include "ivl_target.h" # include "nettypes.h" # include "property_qual.h" # include # include class Design; class NetExpr; class NetNet; class NetScope; class PClass; class PExpr; class netclass_t : public ivl_type_s { public: netclass_t(perm_string class_name, const netclass_t*super); ~netclass_t(); // Set the property of the class during elaboration. Set the // name and type, and return true. If the name is already // present, then return false. bool set_property(perm_string pname, property_qualifier_t qual, ivl_type_t ptype); // Set the scope for the class. The scope has no parents and // is used for the elaboration of methods // (tasks/functions). In other words, this is the class itself. void set_class_scope(NetScope*cscope); inline const NetScope* class_scope(void) const { return class_scope_; } // Set the scope for the class definition. This is the scope // where the class definition was encountered, and may be used // to locate symbols that the class definition may inherit // from its context. This can be nil, or a package or module // where a class is defined. void set_definition_scope(NetScope*dscope); NetScope*definition_scope(void); // As an ivl_type_s object, the netclass is always an // ivl_VT_CLASS object. ivl_variable_type_t base_type() const; // This is the name of the class type inline perm_string get_name() const { return name_; } // If this is derived from another class, then this method // returns a pointer to the super-class. inline const netclass_t* get_super() const { return super_; } // Get the number of properties in this class. Include // properties in the parent class. size_t get_properties(void) const; // Get information about each property. const char*get_prop_name(size_t idx) const; property_qualifier_t get_prop_qual(size_t idx) const; ivl_type_t get_prop_type(size_t idx) const; // These methods are used by the elaborator to note the // initializer for constant properties. Properties start out // as not initialized, and when elaboration detects an // assignment to the property, it is marked initialized. bool get_prop_initialized(size_t idx) const; void set_prop_initialized(size_t idx) const; bool test_for_missing_initializers(void) const; // Map the name of a property to its index. Return <0 if the // name is not a property in the class. int property_idx_from_name(perm_string pname) const; // The task method scopes from the method name. NetScope*method_from_name(perm_string mname) const; // Find the elaborated signal (NetNet) for a static // property. Search by name. The signal is created by the // elaborate_sig pass. NetNet*find_static_property(perm_string name) const; // Test if this scope is a method within the class. This is // used to check scope for handling data protection keywords // "local" and "protected". bool test_scope_is_method(const NetScope*scope) const; void elaborate_sig(Design*des, PClass*pclass); void elaborate(Design*des, PClass*pclass); void emit_scope(struct target_t*tgt) const; bool emit_defs(struct target_t*tgt) const; std::ostream& debug_dump(std::ostream&fd) const; void dump_scope(std::ostream&fd) const; const NetExpr* get_parameter(Design *des, perm_string name, ivl_type_t &par_type) const; void set_virtual(bool virtual_class) { virtual_class_ = virtual_class; } bool is_virtual() const { return virtual_class_; } protected: bool test_compatibility(ivl_type_t that) const; private: perm_string name_; // If this is derived from another base class, point to it // here. const netclass_t*super_; // Map property names to property table index. std::map properties_; // Vector of properties. struct prop_t { perm_string name; property_qualifier_t qual; ivl_type_t type; mutable bool initialized_flag; }; std::vector property_table_; // This holds task/function definitions for methods. NetScope*class_scope_; // This holds the context for the class type definition. NetScope*definition_scope_; bool virtual_class_; }; inline NetScope*netclass_t::definition_scope(void) { return definition_scope_; } #endif /* IVL_netclass_H */ iverilog-12_0/netdarray.cc000066400000000000000000000033261435245347300156530ustar00rootroot00000000000000/* * Copyright (c) 2012-2020 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 "netdarray.h" # include "netqueue.h" # include using namespace std; netdarray_t::netdarray_t(ivl_type_t vec) : netarray_t(vec) { } netdarray_t::~netdarray_t() { } ivl_variable_type_t netdarray_t::base_type(void) const { return IVL_VT_DARRAY; } bool netdarray_t::test_equivalence(ivl_type_t that) const { // Queues and dynamic arrays are not equivalent, so check for the base // type to make sure both are either dynamic array or queue. if (base_type() != that->base_type()) return false; return test_compatibility(that); } bool netdarray_t::test_compatibility(ivl_type_t that) const { // This will match both queues and dynamic arrays const netdarray_t *that_da = dynamic_cast(that); if (!that_da) return false; return element_type()->type_equivalent(that_da->element_type()); } iverilog-12_0/netdarray.h000066400000000000000000000040711435245347300155130ustar00rootroot00000000000000#ifndef IVL_netdarray_H #define IVL_netdarray_H /* * Copyright (c) 2012-2015 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 "nettypes.h" # include "ivl_target.h" class netdarray_t : public netarray_t { public: explicit netdarray_t(ivl_type_t vec); ~netdarray_t(); // This is the "base_type()" virtual method of the // nettype_base_t. The ivl_target api expects this to return // IVL_VT_DARRAY for dynamic arrays? ivl_variable_type_t base_type() const; // A dynamic array may have a type that is signed. inline bool get_signed() const { return element_type()->get_signed(); } // This is the base_type() of the element of the array. We // need this in some cases in order to get the base type of // the element, and not the IVL_VT_DARRAY of the array itself. inline ivl_variable_type_t element_base_type() const { return element_type()->base_type(); } // This is a convenience function for getting the width of an // element. Strictly speaking it's not necessary. inline unsigned long element_width(void) const { return element_type()->packed_width(); } std::ostream& debug_dump(std::ostream&) const; private: bool test_compatibility(ivl_type_t that) const; bool test_equivalence(ivl_type_t that) const; }; #endif /* IVL_netdarray_H */ iverilog-12_0/netenum.cc000066400000000000000000000074251435245347300153410ustar00rootroot00000000000000/* * Copyright (c) 2010-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 "netenum.h" # include "compiler.h" # include using namespace std; netenum_t::netenum_t(ivl_type_t btype, size_t name_count, bool integer_flag) : base_type_(btype), integer_flag_(integer_flag), names_(name_count), bits_(name_count) { } netenum_t::~netenum_t() { } bool netenum_t::get_signed() const { return base_type_->get_signed(); } bool netenum_t::get_isint() const { return integer_flag_; } /* * Enumerations are by definition always packed. */ bool netenum_t::packed() const { return true; } long netenum_t::packed_width() const { return base_type_->packed_width(); } vector netenum_t::slice_dimensions() const { return base_type_->slice_dimensions(); } bool netenum_t::insert_name(size_t name_idx, perm_string name, const verinum&val) { std::pair::iterator, bool> res; assert(val.has_len() && val.len() == packed_width()); // Insert a map of the name to the value. This also gets a // flag that returns true if the name is unique, or false // otherwise. res = names_map_.insert( make_pair(name,val) ); assert(name_idx < names_.size() && names_[name_idx] == 0); names_[name_idx] = name; return res.second; } void netenum_t::insert_name_close(void) { for (size_t idx = 0 ; idx < names_.size() ; idx += 1) { // If we failed to elaborate the name then skip this step. if (names_[idx].nil()) continue; netenum_t::iterator cur = names_map_.find(names_[idx]); vectorstr (cur->second.len() + 1); for (unsigned bit = 0 ; bit < cur->second.len() ; bit += 1) { switch (cur->second.get(bit)) { case verinum::V0: str[bit] = '0'; break; case verinum::V1: str[bit] = '1'; break; case verinum::Vx: str[bit] = 'x'; break; case verinum::Vz: str[bit] = 'z'; break; } } bits_[idx] = bits_strings.make(&str[0]); } } netenum_t::iterator netenum_t::find_name(perm_string name) const { return names_map_.find(name); } /* * Check to see if the given value is already in the enumeration mapping. */ perm_string netenum_t::find_value(const verinum&val) const { perm_string res; for(netenum_t::iterator cur = names_map_.begin(); cur != names_map_.end(); ++ cur) { if (cur->second == val) { res = cur->first; break; } } return res; } netenum_t::iterator netenum_t::end_name() const { return names_map_.end(); } netenum_t::iterator netenum_t::first_name() const { return names_map_.find(names_.front()); } netenum_t::iterator netenum_t::last_name() const { return names_map_.find(names_.back()); } perm_string netenum_t::name_at(size_t idx) const { assert(idx < names_.size()); return names_[idx]; } perm_string netenum_t::bits_at(size_t idx) const { return bits_[idx]; } bool netenum_t::matches(const netenum_t*other) const { return this == other; } iverilog-12_0/netenum.h000066400000000000000000000054031435245347300151750ustar00rootroot00000000000000#ifndef IVL_netenum_H #define IVL_netenum_H /* * Copyright (c) 2010-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 "ivl_target.h" # include "nettypes.h" # include "verinum.h" # include "StringHeap.h" # include "LineInfo.h" # include # include class NetScope; class netenum_t : public LineInfo, public ivl_type_s { public: explicit netenum_t(ivl_type_t base_type, size_t name_count, bool integer_flag); ~netenum_t(); virtual ivl_variable_type_t base_type() const; virtual bool packed() const; virtual long packed_width() const; std::vector slice_dimensions() const; bool get_signed() const; bool get_isint() const; // The size() is the number of enumeration literals. size_t size() const; // Insert the name (and value) at the specific place in the // enumeration. This must be done exactly once for each // enumeration value. bool insert_name(size_t idx, perm_string name, const verinum&val); // Indicate that there will be no more names to insert. void insert_name_close(void); typedef std::map::const_iterator iterator; iterator find_name(perm_string name) const; iterator end_name() const; perm_string find_value(const verinum&val) const; // These methods roughly match the .first() and .last() methods. iterator first_name() const; iterator last_name() const; perm_string name_at(size_t idx) const; perm_string bits_at(size_t idx) const; // Check if two enumerations have the same definition. bool matches(const netenum_t*other) const; private: ivl_type_t base_type_; bool integer_flag_; std::map names_map_; std::vector names_; std::vector bits_; }; inline ivl_variable_type_t netenum_t::base_type() const { return base_type_->base_type(); } inline size_t netenum_t::size() const { return names_.size(); } #endif /* IVL_netenum_H */ iverilog-12_0/netlist.cc000066400000000000000000002305661435245347300153540ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 # include # include # include # include # include "compiler.h" # include "netlist.h" # include "netmisc.h" # include "netclass.h" # include "netdarray.h" # include "netenum.h" # include "netparray.h" # include "netscalar.h" # include "netqueue.h" # include "netstruct.h" # include "netvector.h" # include "ivl_assert.h" using namespace std; ostream& operator<< (ostream&o, NetNet::Type t) { switch (t) { case NetNet::NONE: o << "net_none"; break; case NetNet::IMPLICIT: o << "wire /*implicit*/"; break; case NetNet::IMPLICIT_REG: o << "reg /*implicit*/"; break; case NetNet::REG: o << "reg"; break; case NetNet::SUPPLY0: o << "supply0"; break; case NetNet::SUPPLY1: o << "supply1"; break; case NetNet::TRI: o << "tri"; break; case NetNet::TRI0: o << "tri0"; break; case NetNet::TRI1: o << "tri1"; break; case NetNet::TRIAND: o << "triand"; break; case NetNet::TRIOR: o << "trior"; break; case NetNet::WAND: o << "wand"; break; case NetNet::WOR: o << "wor"; break; case NetNet::WIRE: o << "wire"; break; case NetNet::UNRESOLVED_WIRE: o << "uwire"; } return o; } unsigned count_signals(const Link&pin) { unsigned count = 0; const Nexus*nex = pin.nexus(); for (const Link*clnk = nex->first_nlink() ; clnk ; clnk = clnk->next_nlink()) { const NetPins*cur; unsigned cpin; clnk->cur_link(cur, cpin); if (dynamic_cast(cur)) count += 1; } return count; } const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx) { const Nexus*nex = net->pin(pin).nexus(); for (const Link*clnk = nex->first_nlink() ; clnk ; clnk = clnk->next_nlink()) { const NetPins*cur; unsigned cpin; clnk->cur_link(cur, cpin); const NetNet*sig = dynamic_cast(cur); if (sig) { bidx = cpin; return sig; } } return 0; } Link* find_next_output(Link*lnk) { Link*cur = lnk->next_nlink(); while (cur != lnk) { if (cur->get_dir() == Link::OUTPUT) return cur; cur = cur->next_nlink(); if (cur == 0) cur = lnk->nexus()->first_nlink(); } return 0; } void NetPins::devirtualize_pins(void) { if (pins_) return; if (npins_ > array_size_limit) { cerr << get_fileline() << ": error: pin count " << npins_ << " exceeds " << array_size_limit << " (set by -pARRAY_SIZE_LIMIT)" << endl; assert(0); } if (debug_optimizer && npins_ > 1000) cerr << "debug: devirtualizing " << npins_ << " pins." << endl; pins_ = new Link[npins_]; pins_[0].pin_zero_ = true; pins_[0].node_ = this; pins_[0].dir_ = default_dir_; for (unsigned idx = 1 ; idx < npins_ ; idx += 1) { pins_[idx].pin_zero_ = false; pins_[idx].pin_ = idx; pins_[idx].dir_ = default_dir_; } } bool NetPins::pins_are_virtual(void) const { return pins_ == NULL; } NetPins::NetPins(unsigned npins) : npins_(npins) { default_dir_ = Link::PASSIVE; pins_ = NULL; // Wait until someone asks. if (disable_virtual_pins) devirtualize_pins(); // Ask. Bummer. } NetPins::~NetPins() { if (pins_) { assert(pins_[0].node_ == this); assert(pins_[0].pin_zero_); delete[] pins_; } } Link& NetPins::pin(unsigned idx) { if (!pins_) devirtualize_pins(); if (idx >= npins_) { cerr << get_fileline() << ": internal error: pin("< 0); * because it would happen before we get to print a useful * message in the NetNet constructor */ } NetObj::~NetObj() { } NetScope* NetObj::scope() { return scope_; } const NetScope* NetObj::scope() const { return scope_; } NetNode::NetNode(NetScope*s, perm_string n, unsigned npins) : NetObj(s, n, npins), node_next_(0), node_prev_(0), design_(0) { } NetNode::~NetNode() { if (design_) design_->del_node(this); } NetBranch::NetBranch(ivl_discipline_t dis) : NetPins(2), IslandBranch(dis) { pin(0).set_dir(Link::PASSIVE); pin(1).set_dir(Link::PASSIVE); } NetBranch::~NetBranch() { } NetBus::NetBus(NetScope*s, unsigned pin_count__) : NetObj(s, perm_string::literal(""), pin_count__) { for (unsigned idx = 0 ; idx &unpacked) { unsigned long sum = 1; for (list::const_iterator cur = unpacked.begin() ; cur != unpacked.end() ; ++cur) { // Special case: If there are any undefined dimensions, // then give up on trying to create pins for the net. if (! cur->defined()) return 0; sum *= cur->width(); } if (sum >= UINT_MAX) return 0; return sum; } template static unsigned calculate_count(T*type) { long wid = type->packed_width(); if (wid >= 0) return wid; else return 1; } void NetNet::calculate_slice_widths_from_packed_dims_(void) { ivl_assert(*this, net_type_); if (!net_type_->packed()) return; slice_dims_ = net_type_->slice_dimensions(); // Special case: There are no actual packed dimensions, so // build up a fake dimension of "1". if (slice_dims_.empty()) { slice_wids_.resize(1); slice_wids_[0] = net_type_->packed_width(); return; } slice_wids_.resize(slice_dims_.size()); ivl_assert(*this, ! slice_wids_.empty()); slice_wids_[0] = netrange_width(slice_dims_); vector::const_iterator cur = slice_dims_.begin(); for (size_t idx = 1 ; idx < slice_wids_.size() ; idx += 1, ++cur) { slice_wids_[idx] = slice_wids_[idx-1] / cur->width(); } } const list NetNet::not_an_array; NetNet::NetNet(NetScope*s, perm_string n, Type t, const list&unpacked, ivl_type_t use_net_type) : NetObj(s, n, calculate_count(unpacked)), type_(t), port_type_(NOT_A_PORT), local_flag_(false), net_type_(use_net_type), discipline_(0), unpacked_dims_(unpacked.size()), eref_count_(0), lref_count_(0) { calculate_slice_widths_from_packed_dims_(); size_t idx = 0; for (list::const_iterator cur = unpacked.begin() ; cur != unpacked.end() ; ++cur, idx += 1) { unpacked_dims_[idx] = *cur; } assert(idx == unpacked_dims_.size()); ivl_assert(*this, s); if (pin_count() == 0) { cerr << "Invalid array dimensions: " << unpacked << endl; ivl_assert(*this, 0); } initialize_dir_(); s->add_signal(this); } NetNet::NetNet(NetScope*s, perm_string n, Type t, ivl_type_t type) : NetObj(s, n, 1), type_(t), port_type_(NOT_A_PORT), local_flag_(false), net_type_(type), discipline_(0), eref_count_(0), lref_count_(0) { calculate_slice_widths_from_packed_dims_(); initialize_dir_(); s->add_signal(this); } NetNet::~NetNet() { if (eref_count_ > 0) { cerr << get_fileline() << ": internal error: attempt to delete " << "signal ``" << name() << "'' which has " << "expression references." << endl; dump_net(cerr, 4); } assert(eref_count_ == 0); if (lref_count_ > 0) { cerr << get_fileline() << ": internal error: attempt to delete " << "signal ``" << name() << "'' which has " << "assign references." << endl; dump_net(cerr, 4); } assert(lref_count_ == 0); if (scope()) scope()->rem_signal(this); } NetNet::Type NetNet::type() const { return type_; } void NetNet::type(NetNet::Type t) { if (type_ == t) return; type_ = t; initialize_dir_(); } NetNet::PortType NetNet::port_type() const { return port_type_; } void NetNet::port_type(NetNet::PortType t) { port_type_ = t; } int NetNet::get_module_port_index() const { return port_index_; } void NetNet::set_module_port_index(unsigned idx) { port_index_ = idx; assert( port_index_ >= 0 ); } ivl_variable_type_t NetNet::data_type() const { ivl_assert(*this, net_type_); return net_type_->base_type(); } bool NetNet::get_signed() const { ivl_assert(*this, net_type_); return net_type_->get_signed(); } bool NetNet::get_scalar() const { ivl_assert(*this, net_type_); return net_type_->get_scalar(); } const netenum_t*NetNet::enumeration(void) const { return dynamic_cast (net_type_); } const netstruct_t*NetNet::struct_type(void) const { ivl_type_t cur_type = net_type_; while (cur_type) { if (const netdarray_t*da = dynamic_cast (cur_type)) { cur_type = da->element_type(); continue; } if (const netparray_t*da = dynamic_cast (cur_type)) { cur_type = da->element_type(); continue; } if (const netstruct_t*st = dynamic_cast (cur_type)) return st; else return 0; } assert(0); return 0; } const netdarray_t* NetNet::darray_type(void) const { return dynamic_cast (net_type_); } const netqueue_t* NetNet::queue_type(void) const { return dynamic_cast (net_type_); } const netclass_t* NetNet::class_type(void) const { return dynamic_cast (net_type_); } /* * "depth" is the number of index expressions that the user is using * to index this identifier. So consider if Net was declared like so: * * reg [5:0][3:0] foo; * * In this case, slice_width(2) == 1 (slice_width(N) where N is the * number of dimensions will always be 1.) and represents * $bits(foo[a][b]). Then, slice_width(1)==4 ($bits(foo[a]) and slice_width(0)==24. * * NOTE: The caller should already have accounted for unpacked * dimensions. The "depth" is only for the packed dimensions. */ unsigned long NetNet::slice_width(size_t depth) const { if (depth > slice_wids_.size()) return 0; if (depth == slice_wids_.size()) return 1; return slice_wids_[depth]; } ivl_discipline_t NetNet::get_discipline() const { return discipline_; } void NetNet::set_discipline(ivl_discipline_t dis) { ivl_assert(*this, discipline_ == 0); discipline_ = dis; } bool NetNet::sb_is_valid(const list&indices, long sb) const { ivl_assert(*this, indices.size()+1 == packed_dims().size()); assert(packed_dims().size() == 1); const netrange_t&rng = packed_dims().back(); if (rng.get_msb() >= rng.get_lsb()) return (sb <= rng.get_msb()) && (sb >= rng.get_lsb()); else return (sb <= rng.get_lsb()) && (sb >= rng.get_msb()); } long NetNet::sb_to_idx(const list&indices, long sb) const { ivl_assert(*this, indices.size()+1 == packed_dims().size()); vector::const_iterator pcur = packed_dims().end(); -- pcur; long acc_off; long acc_wid = pcur->width(); if (pcur->get_msb() >= pcur->get_lsb()) acc_off = sb - pcur->get_lsb(); else acc_off = pcur->get_lsb() - sb; // The acc_off is the position within the innermost // dimension. If this is a multi-dimension packed array then // we need to add in the canonical address of the current slice. if (! indices.empty()) { list::const_iterator icur = indices.end(); do { -- icur; -- pcur; long tmp_off; if (pcur->get_msb() >= pcur->get_lsb()) tmp_off = *icur - pcur->get_lsb(); else tmp_off = pcur->get_lsb() - *icur; acc_off += tmp_off * acc_wid; acc_wid *= pcur->width(); } while (icur != indices.begin()); } return acc_off; } bool NetNet::sb_to_slice(const list&indices, long sb, long&loff, unsigned long&lwid) const { ivl_assert(*this, indices.size() < packed_dims().size()); return prefix_to_slice(packed_dims(), indices, sb, loff, lwid); } unsigned NetNet::unpacked_count() const { unsigned c = 1; for (size_t idx = 0 ; idx < unpacked_dims_.size() ; idx += 1) { c *= unpacked_dims_[idx].width(); } return c; } void NetNet::incr_eref() { eref_count_ += 1; } void NetNet::decr_eref() { assert(eref_count_ > 0); eref_count_ -= 1; } unsigned NetNet::peek_eref() const { return eref_count_; } /* * Test each of the bits in the range, and set them. If any bits are * already set then return true. */ bool NetNet::test_and_set_part_driver(unsigned pmsb, unsigned plsb, int widx) { if (lref_mask_.empty()) lref_mask_.resize(vector_width() * pin_count()); // If indexing a word that doesn't exist, then pretend this is // never driven. if (widx < 0) return false; if (widx >= (int)pin_count()) return false; bool rc = false; unsigned word_base = vector_width() * widx; for (unsigned idx = plsb ; idx <= pmsb ; idx += 1) { if (lref_mask_[idx+word_base]) rc = true; else lref_mask_[idx+word_base] = true; } return rc; } void NetNet::incr_lref() { lref_count_ += 1; } void NetNet::decr_lref() { assert(lref_count_ > 0); lref_count_ -= 1; } unsigned NetNet::get_refs() const { return lref_count_ + eref_count_; } void NetNet::add_delay_path(NetDelaySrc*path) { delay_paths_.push_back(path); } unsigned NetNet::delay_paths(void)const { return delay_paths_.size(); } const NetDelaySrc* NetNet::delay_path(unsigned idx) const { assert(idx < delay_paths_.size()); return delay_paths_[idx]; } NetPartSelect::NetPartSelect(NetNet*sig, unsigned off, unsigned wid, NetPartSelect::dir_t dir__, bool signed_flag__) : NetNode(sig->scope(), sig->scope()->local_symbol(), 2), off_(off), wid_(wid), dir_(dir__), signed_flag_(signed_flag__) { set_line(*sig); switch (dir_) { case NetPartSelect::VP: pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); break; case NetPartSelect::PV: pin(0).set_dir(Link::INPUT); pin(1).set_dir(Link::OUTPUT); break; } connect(pin(1), sig->pin(0)); } NetPartSelect::NetPartSelect(NetNet*sig, NetNet*sel, unsigned wid, bool signed_flag__) : NetNode(sig->scope(), sig->scope()->local_symbol(), 3), off_(0), wid_(wid), dir_(VP), signed_flag_(signed_flag__) { switch (dir_) { case NetPartSelect::VP: pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); break; case NetPartSelect::PV: /* Only a vector to part can be a variable select. */ assert(0); } pin(2).set_dir(Link::INPUT); connect(pin(1), sig->pin(0)); connect(pin(2), sel->pin(0)); } NetPartSelect::~NetPartSelect() { } unsigned NetPartSelect::width() const { return wid_; } unsigned NetPartSelect::base() const { return off_; } NetSubstitute::NetSubstitute(NetNet*sig, NetNet*sub, unsigned wid, unsigned off) : NetNode(sig->scope(), sig->scope()->local_symbol(), 3), wid_(wid), off_(off) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); pin(2).set_dir(Link::INPUT); connect(pin(1), sig->pin(0)); connect(pin(2), sub->pin(0)); } NetSubstitute::~NetSubstitute() { } NetProc::NetProc() : next_(0) { } NetProc::~NetProc() { } NetProcTop::NetProcTop(NetScope*s, ivl_process_type_t t, NetProc*st) : type_(t), statement_(st), scope_(s) { synthesized_design_ = 0; } NetProcTop::~NetProcTop() { if (!synthesized_design_) { delete statement_; return; } NexusSet nex_set; statement_->nex_output(nex_set); delete statement_; bool flag = false; for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) { NetNet*net = nex_set[idx].lnk.nexus()->pick_any_net(); if (net->peek_lref() > 0) { cerr << get_fileline() << ": warning: '" << net->name() << "' is driven by more than one process." << endl; flag = true; } } if (flag) { cerr << get_fileline() << ": sorry: Cannot synthesize signals " "that are driven by more than one process." << endl; synthesized_design_->errors += 1; } } NetProc* NetProcTop::statement() { return statement_; } const NetProc* NetProcTop::statement() const { return statement_; } NetScope* NetProcTop::scope() { return scope_; } const NetScope* NetProcTop::scope() const { return scope_; } NetAnalogTop::NetAnalogTop(NetScope*scope__, ivl_process_type_t t, NetProc*st) : type_(t), statement_(st), scope_(scope__) { next_ = 0; } NetAnalogTop::~NetAnalogTop() { } NetProc* NetAnalogTop::statement() { return statement_; } const NetProc* NetAnalogTop::statement() const { return statement_; } NetScope* NetAnalogTop::scope() { return scope_; } const NetScope* NetAnalogTop::scope() const { return scope_; } NetCastInt2::NetCastInt2(NetScope*scope__, perm_string n, unsigned width__) : NetNode(scope__, n, 2), width_(width__) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetCastInt4::NetCastInt4(NetScope*scope__, perm_string n, unsigned width__) : NetNode(scope__, n, 2), width_(width__) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetCastReal::NetCastReal(NetScope*scope__, perm_string n, bool signed_flag__) : NetNode(scope__, n, 2), signed_flag_(signed_flag__) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetConcat::NetConcat(NetScope*scope__, perm_string n, unsigned wid, unsigned cnt, bool trans_flag) : NetNode(scope__, n, cnt+1), width_(wid), transparent_(trans_flag) { pin(0).set_dir(Link::OUTPUT); for (unsigned idx = 1 ; idx < cnt+1 ; idx += 1) { pin(idx).set_dir(Link::INPUT); } } NetConcat::~NetConcat() { } unsigned NetConcat::width() const { return width_; } NetReplicate::NetReplicate(NetScope*scope__, perm_string n, unsigned wid, unsigned rpt) : NetNode(scope__, n, 2), width_(wid), repeat_(rpt) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetReplicate::~NetReplicate() { } unsigned NetReplicate::width() const { return width_; } unsigned NetReplicate::repeat() const { return repeat_; } /* * The NetFF class represents an LPM_FF device. The pinout is assigned * like so: * 0 -- Clock * 1 -- Enable * 2 -- Aset * 3 -- Aclr * 4 -- Sset * 5 -- Sclr * 6 -- Data * 7 -- Q * ... */ NetFF::NetFF(NetScope*s, perm_string n, bool negedge__, unsigned width__) : NetNode(s, n, 8), negedge_(negedge__), width_(width__) { pin_Clock().set_dir(Link::INPUT); pin_Enable().set_dir(Link::INPUT); pin_Aset().set_dir(Link::INPUT); pin_Aclr().set_dir(Link::INPUT); pin_Sset().set_dir(Link::INPUT); pin_Sclr().set_dir(Link::INPUT); pin_Data().set_dir(Link::INPUT); pin_Q().set_dir(Link::OUTPUT); } NetFF::~NetFF() { } bool NetFF::is_negedge() const { return negedge_; } unsigned NetFF::width() const { return width_; } Link& NetFF::pin_Clock() { return pin(0); } const Link& NetFF::pin_Clock() const { return pin(0); } Link& NetFF::pin_Enable() { return pin(1); } const Link& NetFF::pin_Enable() const { return pin(1); } Link& NetFF::pin_Aset() { return pin(2); } const Link& NetFF::pin_Aset() const { return pin(2); } Link& NetFF::pin_Aclr() { return pin(3); } const Link& NetFF::pin_Aclr() const { return pin(3); } Link& NetFF::pin_Sset() { return pin(4); } const Link& NetFF::pin_Sset() const { return pin(4); } Link& NetFF::pin_Sclr() { return pin(5); } const Link& NetFF::pin_Sclr() const { return pin(5); } Link& NetFF::pin_Data() { return pin(6); } const Link& NetFF::pin_Data() const { return pin(6); } Link& NetFF::pin_Q() { return pin(7); } const Link& NetFF::pin_Q() const { return pin(7); } void NetFF::aset_value(const verinum&val) { aset_value_ = val; } const verinum& NetFF::aset_value() const { return aset_value_; } void NetFF::sset_value(const verinum&val) { sset_value_ = val; } const verinum& NetFF::sset_value() const { return sset_value_; } /* * The NetLatch class represents an LPM_LATCH device. The pinout is assigned * like so: * 0 -- Enable * 1 -- Data * 2 -- Q */ NetLatch::NetLatch(NetScope*s, perm_string n, unsigned width__) : NetNode(s, n, 3), width_(width__) { pin_Enable().set_dir(Link::INPUT); pin_Data().set_dir(Link::INPUT); pin_Q().set_dir(Link::OUTPUT); } NetLatch::~NetLatch() { } unsigned NetLatch::width() const { return width_; } Link& NetLatch::pin_Enable() { return pin(0); } const Link& NetLatch::pin_Enable() const { return pin(0); } Link& NetLatch::pin_Data() { return pin(1); } const Link& NetLatch::pin_Data() const { return pin(1); } Link& NetLatch::pin_Q() { return pin(2); } const Link& NetLatch::pin_Q() const { return pin(2); } NetAbs::NetAbs(NetScope*s, perm_string n, unsigned w) : NetNode(s, n, 2), width_(w) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetAbs::~NetAbs() { } unsigned NetAbs::width() const { return width_; } /* * The NetAddSub class represents an LPM_ADD_SUB device. The pinout is * assigned like so: * 0 -- Cout * 1 -- DataA (normally a vector) * 2 -- DataB (normally a vector) * 3 -- Result (normally a vector) */ NetAddSub::NetAddSub(NetScope*s, perm_string n, unsigned w) : NetNode(s, n, 4), width_(w) { pin(0).set_dir(Link::OUTPUT); // Cout pin(1).set_dir(Link::INPUT); // DataA pin(2).set_dir(Link::INPUT); // DataB pin(3).set_dir(Link::OUTPUT); // Result } NetAddSub::~NetAddSub() { } unsigned NetAddSub::width()const { return width_; } Link& NetAddSub::pin_Cout() { return pin(0); } const Link& NetAddSub::pin_Cout() const { return pin(0); } Link& NetAddSub::pin_DataA() { return pin(1); } const Link& NetAddSub::pin_DataA() const { return pin(1); } Link& NetAddSub::pin_DataB() { return pin(2); } const Link& NetAddSub::pin_DataB() const { return pin(2); } Link& NetAddSub::pin_Result() { return pin(3); } const Link& NetAddSub::pin_Result() const { return pin(3); } NetArrayDq::NetArrayDq(NetScope*s, perm_string n, NetNet*mem__, unsigned awid) : NetNode(s, n, 2), mem_(mem__), awidth_(awid) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // Address // Increment the expression reference count for the target // memory so that it is not deleted underneath me. mem_->incr_eref(); } NetArrayDq::~NetArrayDq() { } unsigned NetArrayDq::width() const { return mem_->vector_width(); } unsigned NetArrayDq::awidth() const { return awidth_; } const NetNet* NetArrayDq::mem() const { return mem_; } Link& NetArrayDq::pin_Result() { return pin(0); } Link& NetArrayDq::pin_Address() { return pin(1); } const Link& NetArrayDq::pin_Result() const { return pin(0); } const Link& NetArrayDq::pin_Address() const { return pin(1); } /* * The pinout for the NetCLShift is: * 0 -- Result * 1 -- Data * 2 -- Distance */ NetCLShift::NetCLShift(NetScope*s, perm_string n, unsigned width__, unsigned width_dist__, bool right_flag__, bool signed_flag__) : NetNode(s, n, 3), width_(width__), width_dist_(width_dist__), right_flag_(right_flag__), signed_flag_(signed_flag__) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // Data pin(2).set_dir(Link::INPUT); // Distance } NetCLShift::~NetCLShift() { } unsigned NetCLShift::width() const { return width_; } unsigned NetCLShift::width_dist() const { return width_dist_; } bool NetCLShift::right_flag() const { return right_flag_; } bool NetCLShift::signed_flag() const { return signed_flag_; } Link& NetCLShift::pin_Data() { return pin(1); } const Link& NetCLShift::pin_Data() const { return pin(1); } Link& NetCLShift::pin_Result() { return pin(0); } const Link& NetCLShift::pin_Result() const { return pin(0); } Link& NetCLShift::pin_Distance() { return pin(2); } const Link& NetCLShift::pin_Distance() const { return pin(2); } NetCompare::NetCompare(NetScope*s, perm_string n, unsigned wi) : NetNode(s, n, 8), width_(wi) { signed_flag_ = false; pin(0).set_dir(Link::OUTPUT); // AGB pin(1).set_dir(Link::OUTPUT); // AGEB pin(2).set_dir(Link::OUTPUT); // AEB pin(3).set_dir(Link::OUTPUT); // ANEB pin(4).set_dir(Link::OUTPUT); // ALB pin(5).set_dir(Link::OUTPUT); // ALEB pin(6).set_dir(Link::INPUT); // DataA pin(7).set_dir(Link::INPUT); // DataB } NetCompare::~NetCompare() { } unsigned NetCompare::width() const { return width_; } bool NetCompare::get_signed() const { return signed_flag_; } void NetCompare::set_signed(bool flag) { signed_flag_ = flag; } Link& NetCompare::pin_AGB() { return pin(0); } const Link& NetCompare::pin_AGB() const { return pin(0); } Link& NetCompare::pin_AGEB() { return pin(1); } const Link& NetCompare::pin_AGEB() const { return pin(1); } Link& NetCompare::pin_AEB() { return pin(2); } const Link& NetCompare::pin_AEB() const { return pin(2); } Link& NetCompare::pin_ANEB() { return pin(3); } const Link& NetCompare::pin_ANEB() const { return pin(3); } Link& NetCompare::pin_ALB() { return pin(4); } const Link& NetCompare::pin_ALB() const { return pin(4); } Link& NetCompare::pin_ALEB() { return pin(5); } const Link& NetCompare::pin_ALEB() const { return pin(5); } Link& NetCompare::pin_DataA() { return pin(6); } const Link& NetCompare::pin_DataA() const { return pin(6); } Link& NetCompare::pin_DataB() { return pin(7); } const Link& NetCompare::pin_DataB() const { return pin(7); } NetDivide::NetDivide(NetScope*sc, perm_string n, unsigned wr, unsigned wa, unsigned wb) : NetNode(sc, n, 3), width_r_(wr), width_a_(wa), width_b_(wb), signed_flag_(false) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // DataA pin(2).set_dir(Link::INPUT); // DataB } NetDivide::~NetDivide() { } unsigned NetDivide::width_r() const { return width_r_; } unsigned NetDivide::width_a() const { return width_a_; } unsigned NetDivide::width_b() const { return width_b_; } void NetDivide::set_signed(bool flag) { signed_flag_ = flag; } bool NetDivide::get_signed() const { return signed_flag_; } Link& NetDivide::pin_Result() { return pin(0); } const Link& NetDivide::pin_Result() const { return pin(0); } Link& NetDivide::pin_DataA() { return pin(1); } const Link& NetDivide::pin_DataA() const { return pin(1); } Link& NetDivide::pin_DataB() { return pin(2); } const Link& NetDivide::pin_DataB() const { return pin(2); } NetLiteral::NetLiteral(NetScope*sc, perm_string n, const verireal&val) : NetNode(sc, n, 1), real_(val) { pin(0).set_dir(Link::OUTPUT); } NetLiteral::~NetLiteral() { } ivl_variable_type_t NetLiteral::data_type() const { return IVL_VT_REAL; } const verireal& NetLiteral::value_real() const { return real_; } NetMult::NetMult(NetScope*sc, perm_string n, unsigned wr, unsigned wa, unsigned wb) : NetNode(sc, n, 3), signed_(false), width_r_(wr), width_a_(wa), width_b_(wb) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // DataA pin(2).set_dir(Link::INPUT); // DataB } NetMult::~NetMult() { } void NetMult::set_signed(bool flag) { signed_ = flag; } bool NetMult::get_signed() const { return signed_; } unsigned NetMult::width_r() const { return width_r_; } unsigned NetMult::width_a() const { return width_a_; } unsigned NetMult::width_b() const { return width_b_; } Link& NetMult::pin_Result() { return pin(0); } const Link& NetMult::pin_Result() const { return pin(0); } Link& NetMult::pin_DataA() { return pin(1); } const Link& NetMult::pin_DataA() const { return pin(1); } Link& NetMult::pin_DataB() { return pin(2); } const Link& NetMult::pin_DataB() const { return pin(2); } NetPow::NetPow(NetScope*sc, perm_string n, unsigned wr, unsigned wa, unsigned wb) : NetNode(sc, n, 3), signed_(false), width_r_(wr), width_a_(wa), width_b_(wb) { pin(0).set_dir(Link::OUTPUT); // Result pin(1).set_dir(Link::INPUT); // DataA pin(2).set_dir(Link::INPUT); // DataB } NetPow::~NetPow() { } void NetPow::set_signed(bool flag) { signed_ = flag; } bool NetPow::get_signed() const { return signed_; } unsigned NetPow::width_r() const { return width_r_; } unsigned NetPow::width_a() const { return width_a_; } unsigned NetPow::width_b() const { return width_b_; } Link& NetPow::pin_Result() { return pin(0); } const Link& NetPow::pin_Result() const { return pin(0); } Link& NetPow::pin_DataA() { return pin(1); } const Link& NetPow::pin_DataA() const { return pin(1); } Link& NetPow::pin_DataB() { return pin(2); } const Link& NetPow::pin_DataB() const { return pin(2); } /* * The NetMux class represents an LPM_MUX device. The pinout is assigned * like so: * 0 -- Result * 1 -- Sel * 2+N -- Data[N] (N is the size of the mux) */ NetMux::NetMux(NetScope*s, perm_string n, unsigned wi, unsigned si, unsigned sw) : NetNode(s, n, 2+si), width_(wi), size_(si), swidth_(sw) { pin(0).set_dir(Link::OUTPUT); // Q pin(1).set_dir(Link::INPUT); // Sel for (unsigned idx = 0 ; idx < size_ ; idx += 1) { pin_Data(idx).set_dir(Link::INPUT); // Data[idx] } } NetMux::~NetMux() { } unsigned NetMux::width()const { return width_; } unsigned NetMux::size() const { return size_; } unsigned NetMux::sel_width() const { return swidth_; } Link& NetMux::pin_Result() { return pin(0); } const Link& NetMux::pin_Result() const { return pin(0); } Link& NetMux::pin_Sel() { return pin(1); } const Link& NetMux::pin_Sel() const { return pin(1); } Link& NetMux::pin_Data(unsigned s) { assert(s < size_); return pin(2+s); } const Link& NetMux::pin_Data(unsigned s) const { assert(s < size_); return pin(2+s); } NetSignExtend::NetSignExtend(NetScope*s, perm_string n, unsigned w) : NetNode(s, n, 2), width_(w) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetSignExtend::~NetSignExtend() { } unsigned NetSignExtend::width() const { return width_; } NetBUFZ::NetBUFZ(NetScope*s, perm_string n, unsigned w, bool trans) : NetNode(s, n, 2), width_(w), transparent_(trans) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetBUFZ::~NetBUFZ() { } unsigned NetBUFZ::width() const { return width_; } NetCaseCmp::NetCaseCmp(NetScope*s, perm_string n, unsigned wid, kind_t k) : NetNode(s, n, 3), width_(wid), kind_(k) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); pin(2).set_dir(Link::INPUT); } NetCaseCmp::~NetCaseCmp() { } unsigned NetCaseCmp::width() const { return width_; } NetCondit::NetCondit(NetExpr*ex, NetProc*i, NetProc*e) : expr_(ex), if_(i), else_(e) { } NetCondit::~NetCondit() { delete expr_; delete if_; delete else_; } const NetExpr* NetCondit::expr() const { return expr_; } NetExpr* NetCondit::expr() { return expr_; } void NetCondit::set_expr(NetExpr*ex) { delete expr_; expr_ = ex; } NetProc* NetCondit::if_clause() { return if_; } NetProc* NetCondit::else_clause() { return else_; } NetConst::NetConst(NetScope*s, perm_string n, verinum::V v) : NetNode(s, n, 1), value_(v, 1) { pin(0).set_dir(Link::OUTPUT); } NetConst::NetConst(NetScope*s, perm_string n, const verinum&val) : NetNode(s, n, 1), value_(val) { pin(0).set_dir(Link::OUTPUT); } NetConst::~NetConst() { } verinum::V NetConst::value(unsigned idx) const { assert(idx < width()); return value_[idx]; } NetBaseDef::NetBaseDef(NetScope*s, const vector&po, const std::vector&pd) : scope_(s), ports_(po), pdefaults_(pd) { proc_ = 0; } NetBaseDef::~NetBaseDef() { } const NetScope* NetBaseDef::scope() const { return scope_; } NetScope*NetBaseDef::scope() { return scope_; } unsigned NetBaseDef::port_count() const { return ports_.size(); } NetNet* NetBaseDef::port(unsigned idx) const { assert(idx < ports_.size()); return ports_[idx]; } NetExpr* NetBaseDef::port_defe(unsigned idx) const { assert(idx < pdefaults_.size()); return pdefaults_[idx]; } void NetBaseDef::set_proc(NetProc*st) { assert(proc_ == 0); assert(st != 0); proc_ = st; } const NetProc* NetBaseDef::proc() const { return proc_; } NetFuncDef::NetFuncDef(NetScope*s, NetNet*result, const vector&po, const vector&pd) : NetBaseDef(s, po, pd), result_sig_(result) { } NetFuncDef::~NetFuncDef() { } const NetNet* NetFuncDef::return_sig() const { return result_sig_; } NetSTask::NetSTask(const char*na, ivl_sfunc_as_task_t sfat, const vector&pa) : name_(0), sfunc_as_task_(sfat), parms_(pa) { name_ = lex_strings.add(na); assert(name_[0] == '$'); } NetSTask::~NetSTask() { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) delete parms_[idx]; /* The name_ string is perm-allocated in lex_strings. */ } const char*NetSTask::name() const { return name_; } ivl_sfunc_as_task_t NetSTask::sfunc_as_task() const { return sfunc_as_task_; } unsigned NetSTask::nparms() const { return parms_.size(); } const NetExpr* NetSTask::parm(unsigned idx) const { return parms_[idx]; } NetEUFunc::NetEUFunc(NetScope*scope, NetScope*def, NetESignal*res, vector&p, bool nc) : scope_(scope), func_(def), result_sig_(res), parms_(p), need_const_(nc) { expr_width(result_sig_->expr_width()); cast_signed_base_(result_sig_->has_sign()); } NetEUFunc::~NetEUFunc() { for (unsigned idx = 0 ; idx < parms_.size() ; idx += 1) delete parms_[idx]; } #if 0 const string NetEUFunc::name() const { return func_->name(); } #endif const NetESignal*NetEUFunc::result_sig() const { return result_sig_; } unsigned NetEUFunc::parm_count() const { return parms_.size(); } const NetExpr* NetEUFunc::parm(unsigned idx) const { assert(idx < parms_.size()); return parms_[idx]; } const NetScope* NetEUFunc::func() const { return func_; } ivl_variable_type_t NetEUFunc::expr_type() const { if (result_sig_) return result_sig_->expr_type(); return IVL_VT_VOID; } const netenum_t* NetEUFunc::enumeration() const { if (result_sig_) return result_sig_->enumeration(); return 0; } NetUTask::NetUTask(NetScope*def) : task_(def) { } NetUTask::~NetUTask() { } const NetScope* NetUTask::task() const { return task_; } NetAlloc::NetAlloc(NetScope*scope__) : scope_(scope__) { } NetAlloc::~NetAlloc() { } #if 0 const string NetAlloc::name() const { return scope_->name(); } #endif const NetScope* NetAlloc::scope() const { return scope_; } NetFree::NetFree(NetScope*scope__) : scope_(scope__) { } NetFree::~NetFree() { } #if 0 const string NetFree::name() const { return scope_->name(); } #endif const NetScope* NetFree::scope() const { return scope_; } /* * Create a bitwise operator node from the opcode and the left and * right expressions. */ NetEBBits::NetEBBits(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : NetEBinary(op__, l, r, wid, signed_flag) { } NetEBBits::~NetEBBits() { } NetEBinary::NetEBinary(char op__, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag) : op_(op__), left_(l), right_(r) { expr_width(wid); cast_signed_base_(signed_flag); } NetEBinary::~NetEBinary() { delete left_; delete right_; } bool NetEBinary::has_width() const { return left_->has_width() && right_->has_width(); } NetEBLogic::NetEBLogic(char op__, NetExpr*l, NetExpr*r) : NetEBinary(op__, l, r, 1, false) { } NetEBLogic::~NetEBLogic() { } NetEConst::NetEConst(const verinum&val) : NetExpr(val.len()), value_(val) { cast_signed_base_(value_.has_sign()); } NetEConst::~NetEConst() { } void NetEConst::cast_signed(bool flag) { cast_signed_base_(flag); value_.has_sign(flag); } const verinum& NetEConst::value() const { return value_; } bool NetEConst::has_width() const { return value_.has_len(); } ivl_variable_type_t NetEConst::expr_type() const { if (value_.len() == 0) return IVL_VT_LOGIC; if (value_.is_string()) return IVL_VT_BOOL; if (value_.is_defined()) return IVL_VT_BOOL; return IVL_VT_LOGIC; } void NetEConst::trim() { if (value_.is_string()) return; value_.has_len(false); value_ = trim_vnum(value_); expr_width(value_.len()); } NetEConstParam::NetEConstParam(const NetScope*s, perm_string n, const verinum&v) : NetEConst(v), scope_(s), name_(n) { cast_signed_base_(v.has_sign()); } NetEConstParam::~NetEConstParam() { } perm_string NetEConstParam::name() const { return name_; } const NetScope* NetEConstParam::scope() const { return scope_; } NetEEvent::NetEEvent(NetEvent*e) : event_(e) { e->exprref_ += 1; } NetEEvent::~NetEEvent() { } const NetEvent* NetEEvent::event() const { return event_; } NetEScope::NetEScope(NetScope*s) : scope_(s) { } NetEScope::~NetEScope() { } const NetScope* NetEScope::scope() const { return scope_; } NetESignal::NetESignal(NetNet*n) : NetExpr(n->vector_width()), net_(n), enum_type_(n->enumeration()), word_(0) { net_->incr_eref(); set_line(*n); cast_signed_base_(net_->get_signed()); } NetESignal::NetESignal(NetNet*n, NetExpr*w) : NetExpr(n->vector_width()), net_(n), word_(w) { net_->incr_eref(); set_line(*n); cast_signed_base_(net_->get_signed()); } NetESignal::~NetESignal() { net_->decr_eref(); } perm_string NetESignal::name() const { return net_->name(); } const netenum_t* NetESignal::enumeration() const { return enum_type_; } const NetExpr* NetESignal::word_index() const { return word_; } unsigned NetESignal::vector_width() const { return net_->vector_width(); } const NetNet* NetESignal::sig() const { return net_; } NetNet* NetESignal::sig() { return net_; } /* * The lsi() and msi() methods should be removed from the NetESignal * class, to be replaced with packed dimensions aware methods of * getting at dimensions. */ long NetESignal::lsi() const { const vector&packed = net_->packed_dims(); ivl_assert(*this, packed.size() == 1); return packed.back().get_lsb(); } long NetESignal::msi() const { const vector&packed = net_->packed_dims(); ivl_assert(*this, packed.size() == 1); return packed.back().get_msb(); } ivl_variable_type_t NetESignal::expr_type() const { if (net_->darray_type()) return IVL_VT_DARRAY; else return net_->data_type(); } /* * Make a ternary operator from all the sub-expressions. The condition * expression is self-determined, but the true and false expressions * should have the same width. NOTE: This matching of the widths really * has to be done in elaboration. */ NetETernary::NetETernary(NetExpr*c, NetExpr*t, NetExpr*f, unsigned wid, bool signed_flag) : cond_(c), true_val_(t), false_val_(f) { expr_width(wid); cast_signed_base_(signed_flag); } NetETernary::~NetETernary() { delete cond_; delete true_val_; delete false_val_; } const netenum_t* NetETernary::enumeration() const { // If the condition can evaluate to an ambiguous value, // the result may be blended, and so is not guaranteed // to be a valid enumeration value. if (cond_->expr_type() != IVL_VT_BOOL) return 0; if (true_val_->enumeration() != false_val_->enumeration()) return 0; return true_val_->enumeration(); } const NetExpr* NetETernary::cond_expr() const { return cond_; } const NetExpr* NetETernary::true_expr() const { return true_val_; } const NetExpr* NetETernary::false_expr() const { return false_val_; } ivl_variable_type_t NetETernary::expr_type() const { ivl_assert(*this, true_val_); ivl_assert(*this, false_val_); ivl_variable_type_t tru = true_val_->expr_type(); ivl_variable_type_t fal = false_val_->expr_type(); ivl_variable_type_t sel = cond_->expr_type(); if (tru == IVL_VT_LOGIC && fal == IVL_VT_BOOL) return IVL_VT_LOGIC; if (tru == IVL_VT_BOOL && fal == IVL_VT_LOGIC) return IVL_VT_LOGIC; if (sel == IVL_VT_LOGIC && (tru == IVL_VT_LOGIC || tru == IVL_VT_BOOL) && (fal == IVL_VT_LOGIC || fal == IVL_VT_BOOL)) return IVL_VT_LOGIC; if (tru == IVL_VT_REAL && (fal == IVL_VT_LOGIC || fal == IVL_VT_BOOL)) return IVL_VT_REAL; if (fal == IVL_VT_REAL && (tru == IVL_VT_LOGIC || tru == IVL_VT_BOOL)) return IVL_VT_REAL; if (tru != fal) { cerr << get_fileline() << ": internal error:" << " Unexpected ?: type clash:" << " tru=" << tru << ", fal=" << fal << endl; } ivl_assert(*this, tru == fal); return tru; } NetEUnary::NetEUnary(char op__, NetExpr*ex, unsigned wid, bool signed_flag) : NetExpr(wid), op_(op__), expr_(ex) { cast_signed_base_(signed_flag); } NetEUnary::~NetEUnary() { delete expr_; } ivl_variable_type_t NetEUnary::expr_type() const { return expr_->expr_type(); } NetEUBits::NetEUBits(char op__, NetExpr*ex, unsigned wid, bool signed_flag) : NetEUnary(op__, ex, wid, signed_flag) { } NetEUBits::~NetEUBits() { } ivl_variable_type_t NetEUBits::expr_type() const { return expr_->expr_type(); } NetEUReduce::NetEUReduce(char op__, NetExpr*ex) : NetEUnary(op__, ex, 1, false) { } NetEUReduce::~NetEUReduce() { } ivl_variable_type_t NetEUReduce::expr_type() const { return expr_->expr_type(); } NetECast::NetECast(char op__, NetExpr*ex, unsigned wid, bool signed_flag) : NetEUnary(op__, ex, wid, signed_flag) { } NetECast::~NetECast() { } ivl_variable_type_t NetECast::expr_type() const { ivl_variable_type_t ret = IVL_VT_NO_TYPE; switch (op_) { case 'v': ret = IVL_VT_LOGIC; break; case 'r': ret = IVL_VT_REAL; break; case '2': ret = IVL_VT_BOOL; break; default: assert(0); } return ret; } NetLogic::NetLogic(NetScope*s, perm_string n, unsigned pins, TYPE t, unsigned wid, bool is_cassign__) : NetNode(s, n, pins), type_(t), width_(wid), is_cassign_(is_cassign__) { pin(0).set_dir(Link::OUTPUT); for (unsigned idx = 1 ; idx < pins ; idx += 1) { pin(idx).set_dir(Link::INPUT); } } NetLogic::TYPE NetLogic::type() const { return type_; } unsigned NetLogic::width() const { return width_; } bool NetLogic::is_cassign() const { return is_cassign_; } NetUReduce::NetUReduce(NetScope*scope__, perm_string n, NetUReduce::TYPE t, unsigned wid) : NetNode(scope__, n, 2), type_(t), width_(wid) { pin(0).set_dir(Link::OUTPUT); pin(1).set_dir(Link::INPUT); } NetUReduce::TYPE NetUReduce::type() const { return type_; } unsigned NetUReduce::width() const { return width_; } NetTaskDef::NetTaskDef(NetScope*n, const vector&po, const vector&pd) : NetBaseDef(n, po, pd) { } NetTaskDef::~NetTaskDef() { delete proc_; } /* * These are the delay_type() functions. They are used to determine * the type of delay for the given object. */ /* * This function implements the following table: * * in_A in_B out * NO NO NO * NO ZERO ZERO * NO POS POS * NO DEF POS * ZERO NO ZERO * ZERO ZERO ZERO * ZERO POS POS * ZERO DEF POS * POS NO POS * POS ZERO POS * POS POS POS * POS DEF POS * DEF NO POS * DEF ZERO POS * DEF POS POS * DEF DEF DEF * * It is used to combine two delay values. */ static DelayType combine_delays(const DelayType a, const DelayType b) { /* The default is POSSIBLE_DELAY. */ DelayType result = POSSIBLE_DELAY; /* If both are no or zero delay then we return ZERO_DELAY. */ if ((a == NO_DELAY || a == ZERO_DELAY) && (b == NO_DELAY || b == ZERO_DELAY)) { result = ZERO_DELAY; } /* Except if both are no delay then we return NO_DELAY. */ if (a == NO_DELAY && b == NO_DELAY) { result = NO_DELAY; } /* If both are definite delay then we return DEFINITE_DELAY. */ if (a == DEFINITE_DELAY && b == DEFINITE_DELAY) { result = DEFINITE_DELAY; } return result; } /* * This is used to see what we can find out about the delay when it * is given as an expression. We also use this for loop expressions. */ static DelayType delay_type_from_expr(const NetExpr*expr) { DelayType result = POSSIBLE_DELAY; if (const NetEConst*e = dynamic_cast(expr)) { if (e->value().is_zero()) result = ZERO_DELAY; else result = DEFINITE_DELAY; } if (const NetECReal*e = dynamic_cast(expr)) { if (e->value().as_double() == 0.0) result = ZERO_DELAY; else result = DEFINITE_DELAY; } return result; } /* * The looping structures can use the same basic code so put it here * instead of duplicating it for each one (repeat and while). */ static DelayType get_loop_delay_type(const NetExpr*expr, const NetProc*proc, bool print_delay) { DelayType result; switch (delay_type_from_expr(expr)) { /* We have a constant false expression so the body never runs. */ case ZERO_DELAY: result = NO_DELAY; break; /* We have a constant true expression so the body always runs. */ case DEFINITE_DELAY: if (proc) { result = proc->delay_type(print_delay); } else { result = NO_DELAY; } break; /* We don't know if the body will run so reduce a DEFINITE_DELAY * to a POSSIBLE_DELAY. All other stay the same. */ case POSSIBLE_DELAY: if (proc) { result = combine_delays(NO_DELAY, proc->delay_type(print_delay)); } else { result = NO_DELAY; } break; /* This should never happen since delay_type_from_expr() only * returns three different values. */ default: result = NO_DELAY; assert(0); } return result; } /* The default object does not have any delay. */ DelayType NetProc::delay_type(bool /* print_delay */ ) const { return NO_DELAY; } DelayType NetBlock::delay_type(bool print_delay) const { // A join_none has no delay. if (type() == PARA_JOIN_NONE) return NO_DELAY; DelayType result; // A join_any has the minimum delay. if (type() == PARA_JOIN_ANY) { result = DEFINITE_DELAY; for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) { DelayType dt = cur->delay_type(print_delay); if (dt < result) result = dt; if ((dt == NO_DELAY) && !print_delay) break; } // A begin or join has the maximum delay. } else { result = NO_DELAY; for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) { DelayType dt = cur->delay_type(print_delay); if (dt > result) result = dt; if ((dt == DEFINITE_DELAY) && !print_delay) break; } } return result; } DelayType NetCase::delay_type(bool print_delay) const { DelayType result = NO_DELAY; bool def_stmt = false; unsigned nstmts = nitems(); for (unsigned idx = 0; idx < nstmts; idx += 1) { if (!expr(idx)) def_stmt = true; DelayType dt = stat(idx) ? stat(idx)->delay_type(print_delay) : NO_DELAY; if (idx == 0) { result = dt; } else { result = combine_delays(result, dt); } } // FIXME: If all the cases are covered (e.g. an enum) then this is not true. /* If we don't have a default statement we don't know for sure * that we have a delay. */ if (!def_stmt) result = combine_delays(NO_DELAY, result); return result; } DelayType NetCondit::delay_type(bool print_delay) const { DelayType if_type = if_ ? if_->delay_type(print_delay) : NO_DELAY; DelayType el_type = else_? else_->delay_type(print_delay) : NO_DELAY; return combine_delays(if_type, el_type); } /* * A do/while will execute the body at least once. */ DelayType NetDoWhile::delay_type(bool print_delay) const { if (proc_) return proc_->delay_type(print_delay); return ZERO_DELAY; } DelayType NetEvWait::delay_type(bool print_delay) const { if (print_delay) { cerr << get_fileline() << ": error: an event control is not allowed " "in an always_comb, always_ff or always_latch process." << endl; } return DEFINITE_DELAY; } DelayType NetForever::delay_type(bool print_delay) const { if (statement_) return statement_->delay_type(print_delay); return ZERO_DELAY; } DelayType NetForLoop::delay_type(bool print_delay) const { return get_loop_delay_type(condition_, statement_, print_delay); } DelayType NetPDelay::delay_type(bool print_delay) const { if (print_delay) { cerr << get_fileline() << ": error: a blocking delay is not allowed " "in an always_comb, always_ff or always_latch process." << endl; } if (expr_) { if (statement_) { return combine_delays(delay_type_from_expr(expr_), statement_->delay_type(print_delay)); } else { return delay_type_from_expr(expr_); } } if (delay() > 0) return DEFINITE_DELAY; if (statement_) { return combine_delays(ZERO_DELAY, statement_->delay_type(print_delay)); } else { return ZERO_DELAY; } } DelayType NetRepeat::delay_type(bool print_delay) const { return get_loop_delay_type(expr_, statement_, print_delay); } DelayType NetTaskDef::delay_type(bool print_delay) const { if (proc_) { return proc_->delay_type(print_delay); } else { return NO_DELAY; } } DelayType NetUTask::delay_type(bool print_delay) const { // Is this a void function call in a final block? if (task()->type() == NetScope::FUNC) { return NO_DELAY; } else { return task()->task_def()->delay_type(print_delay); } } static bool do_expr_event_match(const NetExpr*expr, const NetEvWait*evwt) { // The event wait should only have a single event. if (evwt->nevents() != 1) return false; // The event should have a single probe. const NetEvent *evt = evwt->event(0); if (evt->nprobe() != 1) return false; // The probe should be for any edge. const NetEvProbe *prb = evt->probe(0); if (prb->edge() != NetEvProbe::ANYEDGE) return false; // Create a NexusSet from the event probe signals. NexusSet *ns_evwt = new NexusSet; for (unsigned idx =0; idx < prb->pin_count(); idx += 1) { if (! prb->pin(idx).is_linked()) { delete ns_evwt; return false; } // Casting away const is safe since this nexus set is only being read. ns_evwt->add(const_cast (prb->pin(idx).nexus()), 0, prb->pin(idx).nexus()->vector_width()); } // Get the NexusSet for the expression. NexusSet *ns_expr = expr->nex_input(); // Make sure the event and expression NexusSets match exactly. if (ns_evwt->size() != ns_expr->size()) { delete ns_evwt; delete ns_expr; return false; } ns_expr->rem(*ns_evwt); delete ns_evwt; if (ns_expr->size() != 0) { delete ns_expr; return false; } delete ns_expr; return true; } static bool while_is_wait(const NetExpr*expr, const NetProc*stmt) { if (const NetEvWait*evwt = dynamic_cast(stmt)) { if (evwt->statement()) return false; const NetEBComp*cond = dynamic_cast(expr); if (! cond) return false; if (cond->op() != 'N') return false; const NetEConst*cval = dynamic_cast(cond->right()); if (! cval) return false; const verinum val = cval->value(); if (val.len() != 1) return false; if (val.get(0) != verinum::V1) return false; if (! do_expr_event_match(cond->left(), evwt)) return false; if (evwt->get_lineno() != cond->get_lineno()) return false; if (evwt->get_file() != cond->get_file()) return false; return true; } return false; } DelayType NetWhile::delay_type(bool print_delay) const { // If the wait was a constant value the compiler already removed it // so we know we can only have a possible delay. if (while_is_wait(cond_, proc_)) { if (print_delay) { cerr << get_fileline() << ": error: a wait statement is " "not allowed in an " "always_comb, always_ff or always_latch process." << endl; } return POSSIBLE_DELAY; } return get_loop_delay_type(cond_, proc_, print_delay); } /* * These are the check_synth() functions. They are used to print * a warning if the item is not synthesizable. */ static const char * get_process_type_as_string(ivl_process_type_t pr_type) { switch (pr_type) { case IVL_PR_ALWAYS_COMB: return "in an always_comb process."; break; case IVL_PR_ALWAYS_FF: return "in an always_ff process."; break; case IVL_PR_ALWAYS_LATCH: return "in an always_latch process."; break; default: assert(0); return 0; } } static void print_synth_warning(const NetProc *net_proc, const char *name, ivl_process_type_t pr_type) { cerr << net_proc->get_fileline() << ": warning: " << name << " statement cannot be synthesized " << get_process_type_as_string(pr_type) << endl; } static void check_if_logic_l_value(const NetAssignBase *base, ivl_process_type_t pr_type) { if (base->l_val_count() != 1) return; const NetAssign_*lval = base->l_val(0); if (! lval) return; NetNet*sig = lval->sig(); if (! sig) return; if ((sig->data_type() != IVL_VT_BOOL) && (sig->data_type() != IVL_VT_LOGIC)) { cerr << base->get_fileline() << ": warning: Assinging to a " "non-integral variable ("<< sig->name() << ") cannot be synthesized " << get_process_type_as_string(pr_type) << endl; } } /* By default elements can be synthesized or ignored. */ bool NetProc::check_synth(ivl_process_type_t /* pr_type */, const NetScope* /* scope */ ) const { return false; } // FIXME: User function calls still need to be checked (NetEUFunc). // : Non-constant system functions need a warning (NetESFunc). // : Constant functions should already be elaborated. /* By default assign elements can be synthesized. */ bool NetAssignBase::check_synth(ivl_process_type_t /* pr_type */, const NetScope* /* scope */ ) const { return false; } bool NetAssign::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { check_if_logic_l_value(this, pr_type); // FIXME: Check that ff/latch only use this for internal signals. return false; } bool NetAssignNB::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { bool result = false; if (pr_type == IVL_PR_ALWAYS_COMB) { cerr << get_fileline() << ": warning: A non-blocking assignment " "should not be used in an always_comb process." << endl; } if (event_) { cerr << get_fileline() << ": error: A non-blocking assignment " "cannot be synthesized with an event control " << get_process_type_as_string(pr_type) << endl; result = true; } check_if_logic_l_value(this, pr_type); return result; } bool NetBlock::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; // Only a begin/end can be synthesized. if (type() != SEQU) { cerr << get_fileline() << ": error: A fork/"; switch (type()) { case PARA: cerr << "join"; break; case PARA_JOIN_ANY: cerr << "join_any"; break; case PARA_JOIN_NONE: cerr << "join_none"; break; default: assert(0); } cerr << " statement cannot be synthesized " << get_process_type_as_string(pr_type) << endl; result = true; } const NetScope*save_scope = scope; if (subscope()) scope = subscope(); if (scope != save_scope) { result |= scope->check_synth(pr_type, scope); } for (const NetProc*cur = proc_first(); cur; cur = proc_next(cur)) { result |= cur->check_synth(pr_type, scope); } return result; } bool NetCase::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; for (unsigned idx = 0; idx < nitems(); idx += 1) { if (stat(idx)) result |= stat(idx)->check_synth(pr_type, scope); } // FIXME: Check for ff/latch/comb structures. return result; } bool NetCAssign::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "A procedural assign", pr_type); return false; } bool NetCondit::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; if (if_) result |= if_->check_synth(pr_type, scope); if (else_) result |= else_->check_synth(pr_type, scope); // FIXME: Check for ff/latch/comb structures. return result; } bool NetDeassign::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "A procedural deassign", pr_type); return false; } bool NetDisable::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { while (scope) { if (scope != target_) scope = scope->parent(); else break; } if (! scope) { cerr << get_fileline() << ": warning: A disable statement can " "only be synthesized when disabling an enclosing block " << get_process_type_as_string(pr_type) << endl; } return false; } bool NetDoWhile::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; print_synth_warning(this, "A do/while", pr_type); if (proc_) result |= proc_->check_synth(pr_type, scope); return result; } bool NetEvTrig::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "An event trigger", pr_type); return false; } bool NetEvNBTrig::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "A non-blocking event trigger", pr_type); return false; } // The delay check above has already marked this as an error. bool NetEvWait::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; if (statement_) result |= statement_->check_synth(pr_type, scope); return result; } bool NetForce::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "A force", pr_type); return false; } bool NetForever::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; print_synth_warning(this, "A forever", pr_type); if (statement_) result |= statement_->check_synth(pr_type, scope); return result; } /* * A bunch of private routines to verify that a for loop has the correct * structure for synthesis. */ static void print_for_idx_warning(const NetProc*proc, const char*check, ivl_process_type_t pr_type, NetNet*idx) { cerr << proc->get_fileline() << ": warning: A for statement must use " "the index (" << idx->name() << ") in the " << check << " expression to be synthesized " << get_process_type_as_string(pr_type) << endl; } static void check_for_const_synth(const NetExpr*expr, const NetProc*proc, const char*str, ivl_process_type_t pr_type) { if (! dynamic_cast(expr)) { cerr << proc-> get_fileline() << ": warning: A for " "statement must " << str << " value to be synthesized " << get_process_type_as_string(pr_type) << endl; } } static void check_for_bin_synth(const NetExpr*left,const NetExpr*right, const char*str, const char*check, const NetProc*proc, ivl_process_type_t pr_type, NetNet*index) { const NetESignal*lsig = dynamic_cast(left); const NetESignal*rsig = dynamic_cast(right); if (lsig && (lsig->sig() == index)) { check_for_const_synth(right, proc, str, pr_type); } else if (rsig && (rsig->sig() == index)) { check_for_const_synth(left, proc, str, pr_type); } else { print_for_idx_warning(proc, check, pr_type, index); } } static void print_for_step_warning(const NetProc*proc, ivl_process_type_t pr_type) { cerr << proc->get_fileline() << ": warning: A for statement step must " "be a simple assignment statement to be synthesized " << get_process_type_as_string(pr_type) << endl; } static void print_for_step_warning(const NetProc*proc, ivl_process_type_t pr_type, NetNet*idx) { cerr << proc->get_fileline() << ": warning: A for statement step must " "be an assignment to the index variable (" << idx->name() << ") to be synthesized " << get_process_type_as_string(pr_type) << endl; } static void check_for_bstep_synth(const NetExpr*expr, const NetProc*proc, ivl_process_type_t pr_type, NetNet*index) { if (const NetECast*tmp = dynamic_cast(expr)) { expr = tmp->expr(); } if (const NetEBAdd*tmp = dynamic_cast(expr)) { check_for_bin_synth(tmp->left(), tmp->right(), "change by a constant", "step", proc, pr_type, index); } else { cerr << proc->get_fileline() << ": warning: A for statement " "step must be a simple binary +/- " "to be synthesized " << get_process_type_as_string(pr_type) << endl; } } static void check_for_step_synth(const NetAssign*assign, const NetProc*proc, ivl_process_type_t pr_type, NetNet*index) { if (assign->l_val_count() != 1) { print_for_step_warning(proc, pr_type); } else if (assign->l_val(0)->sig() != index) { print_for_step_warning(proc, pr_type, index); } else { switch (assign->assign_operator()) { case '+': case '-': check_for_const_synth(assign->rval(), proc, "have a constant step", pr_type); break; case 0: check_for_bstep_synth(assign->rval(), proc, pr_type, index); break; default: cerr << proc->get_fileline() << ": warning: A for statement " "step does not support operator '" << assign->assign_operator() << "' it must be +/- to be synthesized " << get_process_type_as_string(pr_type) << endl; break; } } } bool NetForLoop::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; // FIXME: What about an enum (NetEConstEnum)? if (! dynamic_cast(init_expr_)) { cerr << get_fileline() << ": warning: A for statement must " "have a constant initial value to be synthesized " << get_process_type_as_string(pr_type) << endl; } // FIXME: Do the following also need to be supported in the condition? // It would seem like they are hard to use to find the bounds. // From NetEBinary // What about NetEBits sig & constant, etc. // From NetEUnary // What about NetEUBits ! sig or ! (sig == constat) // What about NetEUReduce &signal if (const NetESignal*tmp = dynamic_cast(condition_)) { if (tmp->sig() != index_) { print_for_idx_warning(this, "condition", pr_type, index_); } } else if (const NetEBComp*cmp = dynamic_cast(condition_)) { check_for_bin_synth(cmp->left(), cmp->right(), "compare against a constant", "condition", this, pr_type, index_); } else { print_for_idx_warning(this, "condition", pr_type, index_); } if (const NetAssign*tmp = dynamic_cast(step_statement_)) { check_for_step_synth(tmp, this, pr_type, index_); } else { print_for_step_warning(this, pr_type); } if (statement_) result |= statement_->check_synth(pr_type, scope); return result; } // The delay check above has already marked this as an error. bool NetPDelay::check_synth(ivl_process_type_t /* pr_type */, const NetScope* /* scope */ ) const { return false; } bool NetRelease::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */ ) const { print_synth_warning(this, "A release", pr_type); return false; } bool NetRepeat::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; print_synth_warning(this, "A repeat", pr_type); if (statement_) result |= statement_->check_synth(pr_type, scope); return result; } bool NetScope::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */) const { bool result = false; // Skip local events/signals for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) { if (cur->local_flag()) continue; cerr << cur->get_fileline() << ": warning: An event (" << cur->name() << ") cannot be synthesized " << get_process_type_as_string(pr_type) << endl; } for (signals_map_iter_t cur = signals_map_.begin(); cur != signals_map_.end() ; ++ cur) { const NetNet*sig = cur->second; if ((sig->data_type() != IVL_VT_BOOL) && (sig->data_type() != IVL_VT_LOGIC)) { cerr << sig->get_fileline() << ": warning: A non-integral " "variable (" << sig->name() << ") cannot be " "synthesized " << get_process_type_as_string(pr_type) << endl; } } return result; } bool NetSTask::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */) const { if (strcmp(name(), "$ivl_darray_method$delete") == 0) { cerr << get_fileline() << ": warning: Dynamic array " "delete method cannot be synthesized " << get_process_type_as_string(pr_type) << endl; } else { cerr << get_fileline() << ": warning: System task (" << name() << ") cannot be synthesized " << get_process_type_as_string(pr_type) << endl; } return false; } /* * This function is called to make sure the task/function can be used * in a context where it must be synthesizable, such as in an always_comb * or always_ff. * * If this is a function, then the function must be void. */ bool NetBaseDef::check_synth(ivl_process_type_t pr_type, const NetScope* /* scope */) const { bool result = false; const NetScope *tscope = this->scope(); result |= tscope->check_synth(pr_type, tscope); if (! tscope->is_auto()) { cerr << tscope->get_def_file() << ":" << tscope->get_def_lineno() << ": warning: user task (" << tscope->basename() << ") must be automatic to be synthesized " << get_process_type_as_string(pr_type) << endl; } if (proc_) result |= proc_->check_synth(pr_type, tscope); return result; } bool NetUTask::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { const NetScope* task_scope = task(); if (task_scope->type() == NetScope::FUNC) { // This can happen if this a void function. return task_scope->func_def()->check_synth(pr_type, scope); } else { return task_scope->task_def()->check_synth(pr_type, scope); } } bool NetWhile::check_synth(ivl_process_type_t pr_type, const NetScope* scope) const { bool result = false; // A wait is already maked as an error in the delay check above. if (! while_is_wait(cond_, proc_)) { print_synth_warning(this, "A while", pr_type); if (proc_) result |= proc_->check_synth(pr_type, scope); } return result; } iverilog-12_0/netlist.h000066400000000000000000005156471435245347300152240ustar00rootroot00000000000000#ifndef IVL_netlist_H #define IVL_netlist_H /* * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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. */ /* * The netlist types, as described in this header file, are intended * to be the output from elaboration of the source design. The design * can be passed around in this form to the various stages and design * processors. */ # include # include # include # include # include # include # include # include "ivl_target.h" # include "ivl_target_priv.h" # include "pform_types.h" # include "config.h" # include "nettypes.h" # include "verinum.h" # include "verireal.h" # include "StringHeap.h" # include "HName.h" # include "LineInfo.h" # include "Attrib.h" # include "PScope.h" # include "PUdp.h" #ifdef HAVE_IOSFWD # include #else # include #endif class Design; class Link; class Nexus; class NetEvent; class NetNet; class NetNode; class NetObj; class NetPins; class NetProc; class NetProcTop; class NetRelease; class NetScope; class NetEvProbe; class NetExpr; class NetEAccess; class NetEConstEnum; class NetESignal; class NetFuncDef; class NetRamDq; class NetTaskDef; class NetEvTrig; class NetEvNBTrig; class NetEvWait; class PClass; class PExpr; class PFunction; class PPackage; class PTaskFunc; class data_type_t; struct enum_type_t; class netclass_t; class netdarray_t; class netparray_t; class netqueue_t; class netenum_t; class netstruct_t; class netvector_t; struct target; struct functor_t; #if defined(__cplusplus) && defined(_MSC_VER) # define ENUM_UNSIGNED_INT : unsigned int #else # define ENUM_UNSIGNED_INT #endif std::ostream& operator << (std::ostream&o, ivl_variable_type_t val); extern void join_island(NetPins*obj); class Link { friend void connect(Link&, Link&); friend class NetPins; friend class Nexus; friend class NexusSet; public: enum DIR ENUM_UNSIGNED_INT { PASSIVE, INPUT, OUTPUT }; private: // Only NetPins can create/delete Link objects Link(); ~Link(); public: // Manipulate the link direction. void set_dir(DIR d); DIR get_dir() const; // Set the delay for all the drivers to this nexus. void drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay); // A link has a drive strength for 0 and 1 values. The drive0 // strength is for when the link has the value 0, and drive1 // strength is for when the link has a value 1. void drive0(ivl_drive_t); void drive1(ivl_drive_t); // This sets the drives for all drivers of this link, and not // just the current link. void drivers_drive(ivl_drive_t d0, ivl_drive_t d1); ivl_drive_t drive0() const; ivl_drive_t drive1() const; void cur_link(NetPins*&net, unsigned &pin); void cur_link(const NetPins*&net, unsigned &pin) const; // Get a pointer to the nexus that represents all the links // connected to me. Nexus* nexus(); const Nexus* nexus()const; // Return a pointer to the next link in the nexus. Link* next_nlink(); const Link* next_nlink() const; // Remove this link from the set of connected pins. The // destructor will automatically do this if needed. void unlink(); // Return true if this link is connected to anything else. bool is_linked() const; // Return true if these pins are connected. bool is_linked(const Link&that) const; // Return true if this is the same pin of the same object of // that link. bool is_equal(const Link&that) const; // Return information about the object that this link is // a part of. Note that the get_obj() method can return NIL if // this Link is part of a NexusSet. That should be OK, because // they are collection variables, and not functional parts of // a design. const NetPins*get_obj() const; NetPins*get_obj(); unsigned get_pin() const; void dump_link(std::ostream&fd, unsigned ind) const; private: // The NetNode manages these. They point back to the // NetNode so that following the links can get me here. union { NetPins *node_; unsigned pin_; }; bool pin_zero_ : 1; DIR dir_ : 2; ivl_drive_t drive0_ : 3; ivl_drive_t drive1_ : 3; private: Nexus* find_nexus_() const; private: // The Nexus uses these to maintain its list of Link // objects. If this link is not connected to anything, // then these pointers are both nil. Link *next_; Nexus*nexus_; private: // not implemented Link(const Link&); Link& operator= (const Link&); }; class NetPins : public LineInfo { public: explicit NetPins(unsigned npins); virtual ~NetPins(); unsigned pin_count() const { return npins_; } Link&pin(unsigned idx); const Link&pin(unsigned idx) const; void dump_node_pins(std::ostream&, unsigned, const char**pin_names =0) const; void set_default_dir(Link::DIR d); bool is_linked() const; bool pins_are_virtual(void) const; void devirtualize_pins(void); // This is for showing a brief description of the object to // the stream. It is used for debug and diagnostics. virtual void show_type(std::ostream&fd) const; private: Link*pins_; const unsigned npins_; Link::DIR default_dir_; }; /* ========= * A NetObj is anything that has any kind of behavior in the * netlist. Nodes can be gates, registers, etc. and are linked * together to form a design web. * * The web of nodes that makes up a circuit is held together by the * Link class. There is a link for each pin. All mutually connected * pins form a ring of links. * * A link can be INPUT, OUTPUT or PASSIVE. An input never drives the * signal, and PASSIVE never receives the value of the signal. Wires * are PASSIVE, for example. * * A NetObj also has delays specified as rise_time, fall_time and * decay_time. The rise and fall time are the times to transition to 1 * or 0 values. The decay_time is the time needed to decay to a 'bz * value, or to decay of the net is a trireg. The exact and precise * interpretation of the rise/fall/decay times is typically left to * the target to properly interpret. */ class NetObj : public NetPins, public Attrib { public: // The name of the object must be a permallocated string. A // lex_strings string, for example. explicit NetObj(NetScope*s, perm_string n, unsigned npins); virtual ~NetObj(); NetScope* scope(); const NetScope* scope() const; perm_string name() const { return name_; } void rename(perm_string n) { name_ = n; } const NetExpr* rise_time() const { return delay1_; } const NetExpr* fall_time() const { return delay2_; } const NetExpr* decay_time() const { return delay3_; } void rise_time(const NetExpr* d) { delay1_ = d; } void fall_time(const NetExpr* d) { delay2_ = d; } void decay_time(const NetExpr* d) { delay3_ = d; } void dump_obj_attr(std::ostream&, unsigned) const; virtual void show_type(std::ostream&fd) const; private: NetScope*scope_; perm_string name_; const NetExpr* delay1_; const NetExpr* delay2_; const NetExpr* delay3_; }; /* * Objects that can be island branches are derived from this. (It is * possible for an object to be a NetObj and an IslandBranch.) This is * used to collect island information about the node. */ class IslandBranch { public: explicit IslandBranch(ivl_discipline_t dis =0) : island_(0), discipline_(dis) { } ivl_island_t get_island() const { return island_; } friend void join_island(NetPins*); private: ivl_island_t island_; ivl_discipline_t discipline_; }; /* * A NetBranch is a construct of Verilog-A that is a branch between * two nodes. The branch has exactly 2 pins and a discipline. * * pin(0) is the source of flow through a branch and the plus side of * potential. Pin(1) is the sink of flow and the minus (or ground) of * potential. */ class NetBranch : public NetPins, public IslandBranch { public: explicit NetBranch(ivl_discipline_t dis); explicit NetBranch(ivl_discipline_t dis, perm_string name); ~NetBranch(); // If the branch is named, this returns the name. perm_string name() const { return name_; } ivl_branch_s* target_obj() const { return &target_obj_; } void dump(std::ostream&, unsigned) const; private: perm_string name_; mutable ivl_branch_s target_obj_; // The design class uses this member to list the branches. friend class Design; NetBranch*next_; }; /* * The Nexus represents a collection of links that are joined * together. Each link has its own properties, this class holds the * properties of the group. * * The links in a nexus are grouped into a circularly linked list, * with the nexus pointing to the last Link. Each link in turn points * to the next link in the nexus, with the last link pointing back to * the first. The last link also has a non-nil nexus_ pointer back to * this nexus. * * The t_cookie() is an ivl_nexus_t that the code generator uses to * store data in the nexus. When a Nexus is created, this cookie is * set to nil. The code generator may set the cookie once. This locks * the nexus, and rewrites the Link list to be optimal for the code * generator. In the process, *all* of the other methods are no longer * functional. */ class Nexus { friend void connect(Link&, Link&); friend class Link; private: // Only Link objects can create (or delete) Nexus objects explicit Nexus(Link&r); ~Nexus(); public: void connect(Link&r); const char* name() const; void drivers_delays(NetExpr*rise, NetExpr*fall, NetExpr*decay); void drivers_drive(ivl_drive_t d0, ivl_drive_t d1); Link*first_nlink(); const Link* first_nlink()const; /* Get the width of the Nexus, or 0 if there are no vectors (in the form of NetNet objects) linked. */ unsigned vector_width() const; NetNet* pick_any_net(); NetNode* pick_any_node(); /* This method counts the number of input and output links for this nexus, and assigns the results to the output arguments. */ void count_io(unsigned&inp, unsigned&out) const; /* This method returns true if there are any assignments that use this nexus as an l-value. This can be true if the nexus is a variable, but also if this is a net with a force. */ bool assign_lval() const; /* This method returns true if there are any inputs attached to this nexus but no drivers. */ bool has_floating_input() const; /* This method returns true if there are any drivers (including variables) attached to this nexus. */ bool drivers_present() const; /* This method returns true if all the possible drivers of this nexus are constant. It will also return true if there are no drivers at all. */ bool drivers_constant() const; /* Given the nexus has constant drivers, this method returns the value that has been driven. */ verinum::V driven_value() const; verinum driven_vector() const; /* Return a mask of the bits of this vector that are driven. This is usually all false or all true, but in special cases it may be a blend. */ std::vector driven_mask(void)const; /* The code generator sets an ivl_nexus_t to attach code generation details to the nexus. */ ivl_nexus_t t_cookie() const { return t_cookie_; } void t_cookie(ivl_nexus_t) const; private: Link*list_; void unlink(Link*); mutable char* name_; /* Cache the calculated name for the Nexus. */ mutable ivl_nexus_t t_cookie_; enum VALUE { NO_GUESS, V0, V1, Vx, Vz, VAR }; mutable VALUE driven_; private: // not implemented Nexus(const Nexus&); Nexus& operator= (const Nexus&); }; inline void connect(Nexus*l, Link&r) { l->connect(r); } class NexusSet { public: struct elem_t { inline elem_t(Nexus*n, unsigned b, unsigned w) : base(b), wid(w) { lnk.set_dir(Link::PASSIVE); n->connect(lnk); } inline elem_t() : base(0), wid(0) { } inline bool operator == (const struct elem_t&that) const { return lnk.is_linked(that.lnk) && base==that.base && wid==that.wid; } bool contains(const struct elem_t&that) const; Link lnk; unsigned base; unsigned wid; private: elem_t(const elem_t&); elem_t& operator= (elem_t&); }; public: ~NexusSet(); NexusSet(); size_t size() const; // Add the nexus/part to the set, if it is not already present. void add(Nexus*that, unsigned base, unsigned wid); void add(NexusSet&that); // Remove the nexus from the set, if it is present. void rem(const NexusSet&that); unsigned find_nexus(const elem_t&that) const; elem_t& at(unsigned idx); inline elem_t& operator[] (unsigned idx) { return at(idx); } // Return true if this set contains every nexus/part in that // set. That means that every bit of that set is accounted for // this set. bool contains(const NexusSet&that) const; // Return true if this set contains any nexus in that set. bool intersect(const NexusSet&that) const; private: // NexSet items are canonical part selects of vectors. std::vector items_; size_t bsearch_(const struct elem_t&that) const; void rem_(const struct elem_t*that); bool contains_(const elem_t&that) const; private: // not implemented NexusSet(const NexusSet&); NexusSet& operator= (const NexusSet&); }; /* * A NetBus is a transparent device that is merely a bunch of pins * used to tie some pins to. It is a convenient way to collect a * bundle of pins and pass that bundle around. */ class NetBus : public NetObj { public: NetBus(NetScope*scope, unsigned pin_count); ~NetBus(); unsigned find_link(const Link&that) const; private: // not implemented NetBus(const NetBus&); NetBus& operator= (const NetBus&); }; /* * A NetNode is a device of some sort, where each pin has a different * meaning. (i.e., pin(0) is the output to an and gate.) NetNode * objects are listed in the nodes_ of the Design object. */ class NetNode : public NetObj { public: // The name parameter must be a permallocated string. explicit NetNode(NetScope*s, perm_string n, unsigned npins); virtual ~NetNode(); virtual bool emit_node(struct target_t*) const; virtual void dump_node(std::ostream&, unsigned) const; // This is used to scan a modifiable netlist, one node at a time. virtual void functor_node(Design*, functor_t*); private: friend class Design; NetNode*node_next_, *node_prev_; Design*design_; }; /* * A NetDelaySrc is an input-only device that calculates a path delay * based on the time that the inputs change. This class is used by the * NetNet class, and NetDelaySrc objects cannot exist outside of its * association with NetNet objects. */ class NetDelaySrc : public NetObj { public: explicit NetDelaySrc(NetScope*s, perm_string n, unsigned nsrc, bool condit_src, bool conditional, bool parallel); ~NetDelaySrc(); // These functions set the delays from the values in the // source. These set_delays functions implement the various // rules wrt collections of transitions. // One transition specified. void set_delays(uint64_t del); // Two transitions: rise and fall void set_delays(uint64_t rise, uint64_t fall); // Three transitions void set_delays(uint64_t rise, uint64_t fall, uint64_t tz); void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z, uint64_t tz1, uint64_t t1z, uint64_t tz0); void set_delays(uint64_t t01, uint64_t t10, uint64_t t0z, uint64_t tz1, uint64_t t1z, uint64_t tz0, uint64_t t0x, uint64_t tx1, uint64_t t1x, uint64_t tx0, uint64_t txz, uint64_t tzx); uint64_t get_delay(unsigned pe) const; void set_posedge(); void set_negedge(); bool is_posedge() const; bool is_negedge() const; unsigned src_count() const; Link&src_pin(unsigned); const Link&src_pin(unsigned) const; bool is_condit() const; bool has_condit() const; Link&condit_pin(); const Link&condit_pin() const; bool is_parallel() const; void dump(std::ostream&, unsigned ind) const; private: uint64_t transition_delays_[12]; bool condit_flag_; bool conditional_; bool parallel_; bool posedge_; bool negedge_; private: // Not implemented NetDelaySrc(const NetDelaySrc&); NetDelaySrc& operator= (const NetDelaySrc&); }; /* * NetNet is a special kind of NetObj that doesn't really do anything, * but carries the properties of the wire/reg/trireg, including its * name. Scalars and vectors are all the same thing here, a NetNet * with a single pin. The difference between a scalar and vector is * the width of the atomic vector datum it carries. * * NetNet objects can also appear as side effects of synthesis or * other abstractions. * * Note that INTEGER types are an alias for a ``reg signed [31:0]''. * * NetNet objects have a name and exist within a scope, so the * constructor takes a pointer to the containing scope. The object * automatically adds itself to the scope. * * NetNet objects are located by searching NetScope objects. * * The pins of a NetNet object are usually PASSIVE: they do not drive * anything and they are not a data sink, per se. The pins follow the * values on the nexus. The exceptions are reg, trireg, tri0, tri1, * supply0, and supply1 objects, whose pins are classed as OUTPUT. */ class PortType { public: enum Enum ENUM_UNSIGNED_INT { NOT_A_PORT, PIMPLICIT, PINPUT, POUTPUT, PINOUT, PREF }; /* * Merge Port types (used to construct a sane combined port-type * for module ports with complex defining expressions). * */ static Enum merged( Enum lhs, Enum rhs ); }; extern std::ostream& operator << (std::ostream&, PortType::Enum); /* * Information on actual ports (rather than port-connected signals) of * module. * N.b. must be POD as passed through a "C" interface in the t-dll-api. */ struct PortInfo { PortType::Enum type; unsigned long width; perm_string name; }; class NetNet : public NetObj, public PortType { public: enum Type ENUM_UNSIGNED_INT { NONE, IMPLICIT, IMPLICIT_REG, WIRE, TRI, TRI1, SUPPLY0, SUPPLY1, WAND, TRIAND, TRI0, WOR, TRIOR, REG, UNRESOLVED_WIRE }; typedef PortType::Enum PortType; static const std::listnot_an_array; public: // This form is the more generic form of the constructor. For // now, the unpacked type is not buried into an ivl_type_s object. explicit NetNet(NetScope*s, perm_string n, Type t, const std::list&unpacked, ivl_type_t type); explicit NetNet(NetScope*s, perm_string n, Type t, ivl_type_t type); virtual ~NetNet(); Type type() const; void type(Type t); PortType port_type() const; void port_type(PortType t); // If this net net is a port (i.e. a *sub*port net of a module port) // its port index is number of the module it connects through int get_module_port_index() const; // -1 Not connected to port... void set_module_port_index(unsigned idx); ivl_variable_type_t data_type() const; /* If a NetNet is signed, then its value is to be treated as signed. Otherwise, it is unsigned. */ bool get_signed() const; bool get_scalar() const; inline const ivl_type_s* net_type(void) const { return net_type_; } const netenum_t*enumeration(void) const; const netstruct_t*struct_type(void) const; const netdarray_t*darray_type(void) const; const netqueue_t*queue_type(void) const; const netclass_t*class_type(void) const; /* Attach a discipline to the net. */ ivl_discipline_t get_discipline() const; void set_discipline(ivl_discipline_t dis); /* This method returns a reference to the packed dimensions for the vector. These are arranged as a list where the first range in the list (front) is the left-most range in the Verilog declaration. These packed dims are compressed to represent the dimensions of all the subtypes. */ const std::vector& packed_dims() const { return slice_dims_; } const std::vector& unpacked_dims() const { return unpacked_dims_; } /* The vector_width returns the bit width of the packed array, vector or scalar that is this NetNet object. */ inline unsigned long vector_width() const { return slice_width(0); } /* Given a prefix of indices, figure out how wide the resulting slice would be. This is a generalization of the vector_width(), where the depth would be 0. */ unsigned long slice_width(size_t depth) const; /* This method converts a signed index (the type that might be found in the Verilog source) to canonical. It accounts for variation in the definition of the reg/wire/whatever. Note that a canonical index of a multi-dimensioned packed array is a single dimension. For example, "reg [4:1][3:0]..." has the canonical dimension [15:0] and the sb_to_idx() method will convert [2][2] to the canonical index [6]. */ long sb_to_idx(const std::list&prefix, long sb) const; /* This method converts a partial packed indices list and a tail index, and generates a canonical slice offset and width. */ bool sb_to_slice(const std::list&prefix, long sb, long&off, unsigned long&wid) const; /* This method checks that the signed index is valid for this signal. If it is, the above sb_to_idx can be used to get the pin# from the index. */ bool sb_is_valid(const std::list&prefix, long sb) const; /* This method returns 0 for scalars and vectors, and greater for arrays. The value is the number of array indices. (Currently only one array index is supported.) */ inline unsigned unpacked_dimensions() const { return unpacked_dims_.size(); } /* This method returns 0 for scalars, but vectors and other PACKED arrays have packed dimensions. */ inline size_t packed_dimensions() const { return slice_dims_.size(); } // This is the number of array elements. unsigned unpacked_count() const; bool local_flag() const { return local_flag_; } void local_flag(bool f) { local_flag_ = f; } // NetESignal objects may reference this object. Keep a // reference count so that I keep track of them. void incr_eref(); void decr_eref(); unsigned peek_eref() const; // Assignment statements count their lrefs here. And by // assignment statements, we mean BEHAVIORAL assignments. void incr_lref(); void decr_lref(); unsigned peek_lref() const { return lref_count_; } // Treating this node as a uwire, this function tests whether // any bits in the canonical part are already driven. This is // only useful for UNRESOLVED_WIRE objects. The msb and lsb // are the part select of the signal, and the widx is the word // index if this is an unpacked array. bool test_and_set_part_driver(unsigned msb, unsigned lsb, int widx =0); unsigned get_refs() const; /* Manage path delays */ void add_delay_path(class NetDelaySrc*path); unsigned delay_paths(void) const; const class NetDelaySrc*delay_path(unsigned idx) const; virtual void dump_net(std::ostream&, unsigned) const; private: void initialize_dir_(); private: Type type_ : 5; PortType port_type_ : 3; bool local_flag_: 1; ivl_type_t net_type_; ivl_discipline_t discipline_; std::vector unpacked_dims_; // These are the widths of the various slice depths. There is // one entry in this vector for each packed dimension. The // value at N is the slice width if N indices are provided. // // For example: slice_wids_[0] is vector_width(). void calculate_slice_widths_from_packed_dims_(void); std::vector slice_dims_; std::vector slice_wids_; unsigned eref_count_; unsigned lref_count_; // When the signal is an unresolved wire, we need more detail // which bits are assigned. This mask is true for each bit // that is known to be driven. std::vector lref_mask_; std::vector delay_paths_; int port_index_; }; /* * This object type is used for holding local variable values when * evaluating constant user functions. */ struct LocalVar { int nwords; // zero for a simple variable, -1 for reference union { NetExpr* value; // a simple variable NetExpr** array; // an array variable LocalVar* ref; // A reference to a previous scope }; }; class NetBaseDef { public: NetBaseDef(NetScope*n, const std::vector&po, const std::vector&pd); virtual ~NetBaseDef(); const NetScope*scope() const; NetScope*scope(); unsigned port_count() const; NetNet*port(unsigned idx) const; NetExpr*port_defe(unsigned idx) const; void set_proc(NetProc*p); //const string& name() const; const NetProc*proc() const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetScope*scope_; std::vectorports_; std::vectorpdefaults_; protected: NetProc*proc_; }; /* * Some definitions (and methods to manipulate them) are common to a * couple of types. Keep them here. */ class Definitions { public: Definitions(); ~Definitions(); // Add the enumeration to the set of enumerations in this // scope. Include a key that the elaboration can use to look // up this enumeration based on the pform type. void add_enumeration_set(const enum_type_t*key, netenum_t*enum_set); bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name); // Look up the enumeration set that was added with the given // key. This is used by enum_type_t::elaborate_type to locate // a previously elaborated enumeration. netenum_t* enumeration_for_key(const enum_type_t*key) const; // Look up an enumeration literal in this scope. If the // literal is present, return the expression that defines its // value. const NetExpr* enumeration_expr(perm_string key); // Definitions scopes can also hold classes, by name. void add_class(netclass_t*class_type); protected: // Enumerations. The enum_sets_ is a list of all the // enumerations present in this scope. The enum_names_ is a // map of all the enumeration names back to the sets that // contain them. std::map enum_sets_; std::map enum_names_; // This is a map of all the classes (by name) in this scope. std::map classes_; }; /* * This object type is used to contain a logical scope within a * design. The scope doesn't represent any executable hardware, but is * just a handle that netlist processors can use to grab at the design. */ class NetScope : public Definitions, public Attrib { public: enum TYPE { MODULE, CLASS, TASK, FUNC, BEGIN_END, FORK_JOIN, GENBLOCK, PACKAGE }; /* Create a new scope associated with a given compilation unit, and attach it to the given parent. If no compilation unit is specified, the parent's compilation unit is used. The name is expected to have been permallocated. */ NetScope(NetScope*up, const hname_t&name, TYPE t, NetScope*in_unit=0, bool nest=false, bool program=false, bool interface=false, bool compilation_unit=false); ~NetScope(); /* Rename the scope using the name generated by inserting as many pad characters as required between prefix and suffix to make the name unique in the parent scope. Return false if a unique name couldn't be generated. */ bool auto_name(const char* prefix, char pad, const char* suffix); void add_imports(const std::map*imports); NetScope*find_import(const Design*des, perm_string name); void add_typedefs(const std::map*typedefs); /* Search the scope hierarchy for the scope where 'type' was defined. */ NetScope*find_typedef_scope(const Design*des, const typedef_t*type); /* Parameters exist within a scope, and these methods allow one to manipulate the set. In these cases, the name is the *simple* name of the parameter, the hierarchy is implicit in the scope. */ struct range_t; void set_parameter(perm_string name, bool is_annotatable, const LexicalScope::param_expr_t ¶m, NetScope::range_t *range_list); void set_parameter(perm_string name, NetExpr*val, const LineInfo&file_line); const NetExpr*get_parameter(Design*des, const char* name, ivl_type_t&ivl_type); const NetExpr*get_parameter(Design*des, perm_string name, ivl_type_t&ivl_type); /* These are used by defparam elaboration to replace the expression with a new expression, without affecting the range or signed_flag. Return false if the name does not exist. */ void replace_parameter(Design *des, perm_string name, PExpr*val, NetScope*scope, bool defparam = false); /* This is used to ensure the value of a parameter cannot be changed at run-time. This is required if a specparam is used in an expression that must be evaluated at compile-time. Returns true if the named parameter is a specparam and has not already been set to be unannotatable. */ bool make_parameter_unannotatable(perm_string name); /* These methods set or access events that live in this scope. */ void add_event(NetEvent*); void rem_event(NetEvent*); NetEvent*find_event(perm_string name); /* These methods add or find a genvar that lives in this scope. */ void add_genvar(perm_string name, LineInfo *li); LineInfo* find_genvar(perm_string name); /* These methods manage signals. The add_ and rem_signal methods are used by the NetNet objects to make themselves available to the scope, and the find_signal method can be used to locate signals within a scope. */ void add_signal(NetNet*); void rem_signal(NetNet*); NetNet* find_signal(perm_string name); netclass_t* find_class(const Design*des, perm_string name); /* The unit(), parent(), and child() methods allow users of NetScope objects to locate nearby scopes. */ NetScope* unit() { return unit_; } NetScope* parent() { return up_; } NetScope* child(const hname_t&name); const NetScope* unit() const { return unit_; } const NetScope* parent() const { return up_; } const NetScope* child(const hname_t&name) const; /* A helper function to find the enclosing class scope. */ const NetScope* get_class_scope() const; // Look for a child scope by name. This ignores the number // part of the child scope name, so there may be multiple // matches. Only return one. This function is only really // useful for some elaboration error checking. const NetScope* child_byname(perm_string name) const; // Nested modules have slightly different scope search rules. inline bool nested_module() const { return nested_module_; } // Program blocks and interfaces have elaboration constraints. inline bool program_block() const { return program_block_; } inline bool is_interface() const { return is_interface_; } inline bool is_unit() const { return is_unit_; } inline TYPE type() const { return type_; } void print_type(std::ostream&) const; // This provides a link to the variable initialisation process // for use when evaluating a constant function. Note this is // only used for static functions - the variable initialization // for automatic functions is included in the function definition. void set_var_init(const NetProc*proc) { var_init_ = proc; } const NetProc* var_init() const { return var_init_; } void set_task_def(NetTaskDef*); void set_func_def(NetFuncDef*); void set_class_def(netclass_t*); void set_module_name(perm_string); NetTaskDef* task_def(); NetFuncDef* func_def(); // This is used by the evaluate_function setup to collect // local variables from the scope. void evaluate_function_find_locals(const LineInfo&loc, std::map&ctx) const; void set_line(perm_string file, perm_string def_file, unsigned lineno, unsigned def_lineno); void set_line(perm_string file, unsigned lineno); void set_line(const LineInfo *info); perm_string get_file() const { return file_; }; perm_string get_def_file() const { return def_file_; }; unsigned get_lineno() const { return lineno_; }; unsigned get_def_lineno() const { return def_lineno_; }; std::string get_fileline() const; std::string get_def_fileline() const; bool in_func() const; /* Provide a link back to the pform to allow early elaboration of constant functions. */ void set_func_pform(const PFunction*pfunc) { func_pform_ = pfunc; }; const PFunction*func_pform() const { return func_pform_; }; /* Allow tracking of elaboration stages. The three stages are: 1 - scope elaboration 2 - signal elaboration 3 - statement elaboration This is only used for functions, to support early elaboration. */ void set_elab_stage(unsigned stage) { elab_stage_ = stage; }; unsigned elab_stage() const { return elab_stage_; }; /* Is this a function called in a constant expression. */ void need_const_func(bool need_const) { need_const_func_ = need_const; }; bool need_const_func() const { return need_const_func_; }; /* Is this a constant function. */ void is_const_func(bool is_const) { is_const_func_ = is_const; }; bool is_const_func() const { return is_const_func_; }; /* Is the task or function automatic. */ void is_auto(bool is_auto__) { is_auto_ = is_auto__; }; bool is_auto() const { return is_auto_; }; /* Is the module a cell (is in a `celldefine) */ void is_cell(bool is_cell__) { is_cell_ = is_cell__; }; bool is_cell() const { return is_cell_; }; /* Is there a call to a system task in this scope. */ void calls_sys_task(bool calls_stask__) { calls_stask_ = calls_stask__; }; bool calls_sys_task() const { return calls_stask_; }; /* Is this scope elaborating a final procedure? */ void in_final(bool in_final__) { in_final_ = in_final__; }; bool in_final() const { return in_final_; }; const NetTaskDef* task_def() const; const NetFuncDef* func_def() const; const netclass_t* class_def() const; /* If the scope represents a module instance, the module_name is the name of the module itself. */ perm_string module_name() const; /* If the scope is a module then it may have ports that we need * to keep track of. */ void set_num_ports(unsigned int num_ports); void add_module_port_net(NetNet*port); unsigned module_port_nets() const; NetNet*module_port_net(unsigned idx) const; void add_module_port_info( unsigned idx, perm_string name, // May be "" for undeclared port PortType::Enum type, unsigned long width ); const std::vector &module_port_info() const; /* Scopes have their own time units and time precision. The unit and precision are given as power of 10, i.e., -3 is units of milliseconds. If a NetScope is created with a parent scope, the new scope will initially inherit the unit and precision of the parent scope. */ void time_unit(int); void time_precision(int); void time_from_timescale(bool); int time_unit() const; int time_precision() const; bool time_from_timescale() const; /* The fullname of the scope is the hierarchical name component (which includes the name and array index) whereas the basename is just my name. */ perm_string basename() const; const hname_t& fullname() const { return name_; } void run_defparams(class Design*); void run_defparams_later(class Design*); void evaluate_parameters(class Design*); // Look for defparams that never matched, and print warnings. void residual_defparams(class Design*); bool symbol_exists(perm_string sym); /* This method generates a non-hierarchical name that is guaranteed to be unique within this scope. */ perm_string local_symbol(); void dump(std::ostream&) const; // Check to see if the scope has items that are not allowed // in an always_comb/ff/latch process. virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; void emit_scope(struct target_t*tgt) const; bool emit_defs(struct target_t*tgt) const; /* This method runs the functor on me. Recurse through the children of this node as well. */ void run_functor(Design*des, functor_t*fun); /* These are used in synthesis. They provide shared pullup and pulldown nodes for this scope. */ void add_tie_hi(Design*des); void add_tie_lo(Design*des); Link&tie_hi() const { return tie_hi_->pin(0); }; Link&tie_lo() const { return tie_lo_->pin(0); }; /* This member is used during elaboration to pass defparam assignments from the scope pass to the parameter evaluation step. After that, it is not used. */ std::list > defparams; std::list,PExpr*> > defparams_later; public: struct range_t { bool exclude_flag; // Lower bound bool low_open_flag; NetExpr*low_expr; // Upper bound bool high_open_flag; NetExpr*high_expr; // Link to the next range specification struct range_t*next; }; /* After everything is all set up, the code generators like access to these things to make up the parameter lists. */ struct param_expr_t : public LineInfo { param_expr_t() : val_expr(0), val_type(0), val_scope(0), solving(false), is_annotatable(false), local_flag(false), range(0), val(0), ivl_type(0) { } // Source expression and data type (before elaboration) PExpr*val_expr; data_type_t*val_type; // Scope information NetScope*val_scope; // Evaluation status bool solving; // specparam status bool is_annotatable; // Is this a localparam? bool local_flag; // Can it be overriden? bool overridable = false; // Is it a type parameter bool type_flag = false; // range constraints struct range_t*range; // Expression value. Elaborated version of val_expr. // For type parameters this will always be 0. NetExpr*val; // For non-type parameter this contains the elaborate type of the // parameter itself. For type parameters this contains the // elaborated assigned type value. ivl_type_t ivl_type; }; std::mapparameters; typedef std::map::iterator param_ref_t; LineInfo get_parameter_line_info(perm_string name) const; /* Module instance arrays are collected here for access during the multiple elaboration passes. */ typedef std::vector scope_vec_t; std::mapinstance_arrays; /* Loop generate uses this as scratch space during elaboration. Expression evaluation can use this to match names. */ perm_string genvar_tmp; long genvar_tmp_val; std::map loop_index_tmp; private: void evaluate_type_parameter_(Design*des, param_ref_t cur); void evaluate_parameter_logic_(Design*des, param_ref_t cur); void evaluate_parameter_real_(Design*des, param_ref_t cur); void evaluate_parameter_string_(Design*des, param_ref_t cur); void evaluate_parameter_(Design*des, param_ref_t cur); private: TYPE type_; hname_t name_; // True if the scope is a nested module/program block bool nested_module_; // True if the scope is a program block bool program_block_; // True if the scope is an interface bool is_interface_; // True if the scope is a compilation unit bool is_unit_; perm_string file_; perm_string def_file_; unsigned lineno_; unsigned def_lineno_; signed char time_unit_, time_prec_; bool time_from_timescale_; const std::map*imports_; std::maptypedefs_; NetEvent *events_; std::map genvars_; typedef std::map::const_iterator signals_map_iter_t; std::map signals_map_; perm_string module_name_; std::vector port_nets; std::vector ports_; const NetProc*var_init_; union { NetTaskDef*task_; NetFuncDef*func_; netclass_t*class_def_; }; const PFunction*func_pform_; unsigned elab_stage_; NetScope*unit_; NetScope*up_; std::map children_; unsigned lcounter_; bool need_const_func_, is_const_func_, is_auto_, is_cell_, calls_stask_; /* Final procedures sets this to notify statements that they are part of a final procedure. */ bool in_final_; NetNode*tie_hi_; NetNode*tie_lo_; }; /* * This class implements the LPM_ABS component. The node has a single * input, a signed expression, that it converts to the absolute * value. The gate is simple: pin(0) is the output and pin(1) is the input. */ class NetAbs : public NetNode { public: NetAbs(NetScope*s, perm_string n, unsigned width); ~NetAbs(); unsigned width() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_; }; /* * This class implements the LPM_ADD_SUB component as described in the * EDIF LPM Version 2 1 0 standard. It is used as a structural * implementation of the + and - operators. */ class NetAddSub : public NetNode { public: NetAddSub(NetScope*s, perm_string n, unsigned width); ~NetAddSub(); // Get the width of the device (that is, the width of the // operands and results). unsigned width() const; Link& pin_Cout(); Link& pin_DataA(); Link& pin_DataB(); Link& pin_Result(); const Link& pin_Cout() const; const Link& pin_DataA() const; const Link& pin_DataB() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_; }; /* * The NetArrayDq node represents an array dereference. The NetNet * that this object refers to is an array, and the Address pin selects * which word of the array to place on the Result. */ class NetArrayDq : public NetNode { public: NetArrayDq(NetScope*s, perm_string name, NetNet*mem, unsigned awid); ~NetArrayDq(); unsigned width() const; unsigned awidth() const; unsigned size() const; const NetNet*mem() const; Link& pin_Address(); Link& pin_Result(); const Link& pin_Address() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: NetNet*mem_; unsigned awidth_; }; /* * Convert an IVL_VT_REAL input to a logical value with the * given width. The input is pin(1) and the output is pin(0). */ class NetCastInt4 : public NetNode { public: NetCastInt4(NetScope*s, perm_string n, unsigned width); unsigned width() const { return width_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; }; class NetCastInt2 : public NetNode { public: NetCastInt2(NetScope*s, perm_string n, unsigned width); unsigned width() const { return width_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; }; /* * Convert an input to IVL_VT_REAL. The input is pin(1), which can be * any vector type (VT_BOOL or VT_LOGIC) and the output is pin(0), * which is IVL_VT_REAL. The conversion interprets the input as an * unsigned value unless the signed_flag is true. */ class NetCastReal : public NetNode { public: NetCastReal(NetScope*s, perm_string n, bool signed_flag); bool signed_flag() const { return signed_flag_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: bool signed_flag_; }; /* * This type represents the LPM_CLSHIFT device. */ class NetCLShift : public NetNode { public: NetCLShift(NetScope*s, perm_string n, unsigned width, unsigned width_dist, bool right_flag, bool signed_flag); ~NetCLShift(); unsigned width() const; unsigned width_dist() const; bool right_flag() const; bool signed_flag() const; Link& pin_Data(); Link& pin_Result(); Link& pin_Distance(); const Link& pin_Data() const; const Link& pin_Result() const; const Link& pin_Distance() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; unsigned width_dist_; bool right_flag_; bool signed_flag_; }; /* * This class supports the LPM_COMPARE device. * * The width of the device is the width of the inputs. If one of the * inputs is narrower than the other, it is up to the generator to * make sure all the data pins are properly driven. * * The signed() property is true if the comparison is to be done to * signed arguments. The result is always UNsigned. * * NOTE: This is not the same as the device used to support case * compare. Case comparisons handle Vx and Vz values, whereas this * device need not. */ class NetCompare : public NetNode { public: NetCompare(NetScope*scope, perm_string n, unsigned width); ~NetCompare(); unsigned width() const; bool get_signed() const; void set_signed(bool); Link& pin_AGB(); Link& pin_AGEB(); Link& pin_AEB(); Link& pin_ANEB(); Link& pin_ALB(); Link& pin_ALEB(); Link& pin_DataA(); Link& pin_DataB(); const Link& pin_AGB() const; const Link& pin_AGEB() const; const Link& pin_AEB() const; const Link& pin_ANEB() const; const Link& pin_ALB() const; const Link& pin_ALEB() const; const Link& pin_DataA() const; const Link& pin_DataB() const; virtual void functor_node(Design*, functor_t*); virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; bool signed_flag_; }; /* * This node is a means to connect net inputs together to form a wider * vector. The output (pin 0) is a concatenation of the input vectors, * with pin-1 at the LSB, pin-2 next, and so on. This node is most * like the NetLogic node, as it has one output at pin 0 and the * remaining pins are the input that are combined to make the * output. It is separated out because it it generally a special case * for the code generators. * * When constructing the node, the width is the vector_width of the * output, and the cnt is the number of pins. (the number of input * vectors.) */ class NetConcat : public NetNode { public: NetConcat(NetScope*scope, perm_string n, unsigned wid, unsigned cnt, bool transparent_flag = false); ~NetConcat(); unsigned width() const; // This is true if the concatenation is a transparent // concatenation, meaning strengths are passed through as // is. In this case, the output strengths of this node will be // ignored. bool transparent() const { return transparent_; } void dump_node(std::ostream&, unsigned ind) const; bool emit_node(struct target_t*) const; void functor_node(Design*des, functor_t*fun); private: unsigned width_; bool transparent_; }; /* * This class represents a theoretical (though not necessarily * practical) integer divider gate. This is not to represent any real * hardware, but to support the / operator in Verilog, when it shows * up in structural contexts. * * The operands of the operation are the DataA and DataB inputs, * and the Result output reflects the value DataA/DataB. */ class NetDivide : public NetNode { public: NetDivide(NetScope*scope, perm_string n, unsigned width, unsigned wa, unsigned wb); ~NetDivide(); unsigned width_r() const; unsigned width_a() const; unsigned width_b() const; void set_signed(bool); bool get_signed() const; Link& pin_DataA(); Link& pin_DataB(); Link& pin_Result(); const Link& pin_DataA() const; const Link& pin_DataB() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_r_; unsigned width_a_; unsigned width_b_; bool signed_flag_; }; /* * This class represents a theoretical (though not necessarily * practical) integer modulo gate. This is not to represent any real * hardware, but to support the % operator in Verilog, when it shows * up in structural contexts. * * The operands of the operation are the DataA and DataB inputs, * and the Result output reflects the value DataA%DataB. */ class NetModulo : public NetNode { public: NetModulo(NetScope*s, perm_string n, unsigned width, unsigned wa, unsigned wb); ~NetModulo(); unsigned width_r() const; unsigned width_a() const; unsigned width_b() const; void set_signed(bool); bool get_signed() const; Link& pin_DataA(); Link& pin_DataB(); Link& pin_Result(); const Link& pin_DataA() const; const Link& pin_DataB() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_r_; unsigned width_a_; unsigned width_b_; bool signed_flag_; }; /* * This class represents an LPM_FF device. There is no literal gate * type in Verilog that maps, but gates of this type can be inferred. */ class NetFF : public NetNode { public: NetFF(NetScope*s, perm_string n, bool negedge, unsigned vector_width); ~NetFF(); bool is_negedge() const; unsigned width() const; Link& pin_Clock(); Link& pin_Enable(); Link& pin_Aset(); Link& pin_Aclr(); Link& pin_Sset(); Link& pin_Sclr(); Link& pin_Data(); Link& pin_Q(); const Link& pin_Clock() const; const Link& pin_Enable() const; const Link& pin_Aset() const; const Link& pin_Aclr() const; const Link& pin_Sset() const; const Link& pin_Sclr() const; const Link& pin_Data() const; const Link& pin_Q() const; void aset_value(const verinum&val); const verinum& aset_value() const; void sset_value(const verinum&val); const verinum& sset_value() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: bool negedge_; unsigned width_; verinum aset_value_; verinum sset_value_; }; /* * This class represents an LPM_LATCH device. There is no literal gate * type in Verilog that maps, but gates of this type can be inferred. */ class NetLatch : public NetNode { public: NetLatch(NetScope*s, perm_string n, unsigned vector_width); ~NetLatch(); unsigned width() const; Link& pin_Enable(); Link& pin_Data(); Link& pin_Q(); const Link& pin_Enable() const; const Link& pin_Data() const; const Link& pin_Q() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_; }; /* * This class implements a basic LPM_MULT combinational multiplier. It * is used as a structural representation of the * operator. The * device has inputs A and B and output Result all with independent * widths. * * NOTE: Check this width thing. I think that the independence of the * widths is not necessary or even useful. */ class NetMult : public NetNode { public: NetMult(NetScope*sc, perm_string n, unsigned width, unsigned wa, unsigned wb); ~NetMult(); bool get_signed() const; void set_signed(bool); // Get the width of the device bussed inputs. There are these // parameterized widths: unsigned width_r() const; // Result unsigned width_a() const; // DataA unsigned width_b() const; // DataB Link& pin_DataA(); Link& pin_DataB(); Link& pin_Result(); const Link& pin_DataA() const; const Link& pin_DataB() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: bool signed_; unsigned width_r_; unsigned width_a_; unsigned width_b_; }; /* * This class represents an LPM_MUX device. This device has some * number of Result points (the width of the device) and some number * of input choices. There is also a selector of some width. The * parameters are: * * width -- Width of the result and each possible Data input * size -- Number of Data input (each of width) * selw -- Width in bits of the select input * * All the data inputs must have the same type, and are the type of * the result. The actual type does not matter, as the mux does not * process data, just selects alternatives. * * The select input must be an integral type of some sort. Not real. */ class NetMux : public NetNode { public: NetMux(NetScope*scope, perm_string n, unsigned width, unsigned size, unsigned selw); ~NetMux(); unsigned width() const; unsigned size() const; unsigned sel_width() const; Link& pin_Result(); Link& pin_Data(unsigned si); Link& pin_Sel(); const Link& pin_Result() const; const Link& pin_Data(unsigned) const; const Link& pin_Sel() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned width_; unsigned size_; unsigned swidth_; }; /* * This class implements a basic LPM_POW combinational power. It * is used as a structural representation of the ** operator. The * device has inputs A and B and output Result all with independent * widths. * * NOTE: Check this width thing. I think that the independence of the * widths is not necessary or even useful. */ class NetPow : public NetNode { public: NetPow(NetScope*sc, perm_string n, unsigned width, unsigned wa, unsigned wb); ~NetPow(); bool get_signed() const; void set_signed(bool); // Get the width of the device bussed inputs. There are these // parameterized widths: unsigned width_r() const; // Result unsigned width_a() const; // DataA unsigned width_b() const; // DataB Link& pin_DataA(); Link& pin_DataB(); Link& pin_Result(); const Link& pin_DataA() const; const Link& pin_DataB() const; const Link& pin_Result() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*des, functor_t*fun); private: bool signed_; unsigned width_r_; unsigned width_a_; unsigned width_b_; }; /* * The NetReplicate node takes a vector input and makes it into a larger * vector by repeating the input vector some number of times. The * repeat count is a fixed value. This is just like the repeat * concatenation of Verilog: {{}}. * * When constructing this node, the wid is the vector width of the * output, and the rpt is the repeat count. The wid must be an even * multiple of the cnt, and wid/cnt is the expected input width. * * The device has exactly 2 pins: pin(0) is the output and pin(1) the * input. */ class NetReplicate : public NetNode { public: NetReplicate(NetScope*scope, perm_string n, unsigned wid, unsigned rpt); ~NetReplicate(); unsigned width() const; unsigned repeat() const; void dump_node(std::ostream&, unsigned ind) const; bool emit_node(struct target_t*) const; private: unsigned width_; unsigned repeat_; }; /* * This node represents the call of a user defined function in a * structural context. The pin count is the same as the port count, * with pin0 the return value. */ class NetUserFunc : public NetNode { public: NetUserFunc(NetScope*s, perm_string n, NetScope*def, NetEvWait*trigger__); ~NetUserFunc(); unsigned port_width(unsigned port) const; const NetScope* def() const; const NetEvWait* trigger() const { return trigger_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: NetScope*def_; NetEvWait*trigger_; }; /* * The number of ports includes the return value, so will always be at * least 1. */ class NetSysFunc : public NetNode { public: NetSysFunc(NetScope*s, perm_string n, const struct sfunc_return_type*def, unsigned ports, NetEvWait*trigger__); ~NetSysFunc(); ivl_variable_type_t data_type() const; unsigned vector_width() const; const char* func_name() const; const NetEvWait* trigger() const { return trigger_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: const struct sfunc_return_type*def_; NetEvWait*trigger_; }; class NetTran : public NetNode, public IslandBranch { public: // Tran devices other than TRAN_VP NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type, unsigned wid); // Create a TRAN_VP NetTran(NetScope*scope, perm_string n, unsigned wid, unsigned part, unsigned off); ~NetTran(); ivl_switch_type_t type() const { return type_; } // These are only used for IVL_SW_TRAN_PV unsigned vector_width() const; unsigned part_width() const; unsigned part_offset() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: ivl_switch_type_t type_; unsigned wid_; unsigned part_; unsigned off_; }; /* ========= * There are cases where expressions need to be represented. The * NetExpr class is the root of a hierarchy that serves that purpose. * * The expr_width() is the width of the expression, which is calculated * before the expression is elaborated. */ class NetExpr : public LineInfo { public: explicit NetExpr(unsigned w =0); explicit NetExpr(ivl_type_t t); virtual ~NetExpr() =0; virtual void expr_scan(struct expr_scan_t*) const =0; virtual void dump(std::ostream&) const; // This is the advanced description of the type. I think I // want to replace the other type description members with // this single method. The default for this method returns // nil. ivl_type_t net_type() const; // Expressions have type. virtual ivl_variable_type_t expr_type() const; // How wide am I? unsigned expr_width() const { return width_; } // This method returns true if the expression is // signed. Unsigned expressions return false. bool has_sign() const { return signed_flag_; } virtual void cast_signed(bool flag); // This returns true if the expression has a definite // width. This is generally true, but in some cases the // expression is amorphous and desires a width from its // environment. For example, 'd5 has indefinite width, but // 5'd5 has a definite width. // This method is only really used within concatenation // expressions to check validity. virtual bool has_width() const; // Return the enumeration set that defines this expressions // enumeration type, or return nil if the expression is not // part of the enumeration. virtual const netenum_t*enumeration() const; // This method evaluates the expression and returns an // equivalent expression that is reduced as far as compile // time knows how. Essentially, this is designed to fold // constants. virtual NetExpr*eval_tree(); // Make a duplicate of myself, and subexpressions if I have // any. This is a deep copy operation. virtual NetExpr*dup_expr() const =0; // Evaluate the expression at compile time, a la within a // constant function. This is used by the constant function // evaluation function code, and the return value is an // allocated constant, or nil if the expression cannot be // evaluated for any reason. virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; // Get the Nexus that are the input to this // expression. Normally this descends down to the reference to // a signal that reads from its input. virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const =0; // Return a version of myself that is structural. This is used // for converting expressions to gates. The arguments are: // // des, scope: The context where this work is done // // root: The root expression of which this expression is a part. // // rise/fall/decay: Attach these delays to the driver for the // expression output. // // drive0/drive1: Attach these strengths to the driver for // the expression output. virtual NetNet*synthesize(Design*des, NetScope*scope, NetExpr*root); protected: void expr_width(unsigned wid) { width_ = wid; } void cast_signed_base_(bool flag) { signed_flag_ = flag; } private: ivl_type_t net_type_; unsigned width_; bool signed_flag_; private: // not implemented NetExpr(const NetExpr&); NetExpr& operator=(const NetExpr&); }; class NetEArrayPattern : public NetExpr { public: NetEArrayPattern(ivl_type_t lv_type, std::vector&items); ~NetEArrayPattern(); inline size_t item_size() const { return items_.size(); } const NetExpr* item(size_t idx) const { return items_[idx]; } void expr_scan(struct expr_scan_t*) const; void dump(std::ostream&) const; NetEArrayPattern* dup_expr() const; NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; private: std::vector items_; }; /* * The expression constant is slightly special, and is sometimes * returned from other classes that can be evaluated at compile * time. This class represents constant values in expressions. */ class NetEConst : public NetExpr { public: explicit NetEConst(const verinum&val); ~NetEConst(); const verinum&value() const; virtual void cast_signed(bool flag); virtual bool has_width() const; virtual ivl_variable_type_t expr_type() const; /* This method allows the constant value to be converted to an unsized value. This is used after evaluating a unsized constant expression. */ void trim(); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetEConst* dup_expr() const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*); virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; private: verinum value_; }; class NetEConstEnum : public NetEConst { public: explicit NetEConstEnum(perm_string name, const netenum_t*enum_set, const verinum&val); ~NetEConstEnum(); perm_string name() const; const netenum_t*enumeration() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetEConstEnum* dup_expr() const; private: const netenum_t*enum_set_; perm_string name_; }; class NetEConstParam : public NetEConst { public: explicit NetEConstParam(const NetScope*scope, perm_string name, const verinum&val); ~NetEConstParam(); perm_string name() const; const NetScope*scope() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetEConstParam* dup_expr() const; private: const NetScope*scope_; perm_string name_; }; /* * This class represents a constant real value. */ class NetECReal : public NetExpr { public: explicit NetECReal(const verireal&val); ~NetECReal(); const verireal&value() const; // The type of this expression is ET_REAL ivl_variable_type_t expr_type() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetECReal* dup_expr() const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*); virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; private: verireal value_; }; class NetECString : public NetEConst { public: explicit NetECString(const std::string& val); ~NetECString(); // The type of a string is IVL_VT_STRING ivl_variable_type_t expr_type() const; }; class NetECRealParam : public NetECReal { public: explicit NetECRealParam(const NetScope*scope, perm_string name, const verireal&val); ~NetECRealParam(); perm_string name() const; const NetScope*scope() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetECRealParam* dup_expr() const; private: const NetScope*scope_; perm_string name_; }; /* * The NetPartSelect device represents a netlist part select of a * signal vector. Pin 0 is a vector that is a part select of pin 1, * which connected to the NetNet of the signal being selected from. * * The part to be selected is the canonical (0-based) offset and the * specified number of bits (wid). * * If the offset is non-constant, then pin(2) is the input vector for * the selector. If this pin is present, then use the non-constant * selector as the input. * * The NetPartSelect can be output from the signal (i.e. reading a * part) or input into the signal. The DIR method gives the type of * the node. * * VP (Vector-to-Part) * Output pin 0 is the part select, and input pin 1 is connected to * the NetNet object. * * PV (Part-to-Vector) * Output pin 1 is connected to the NetNet, and input pin 0 is the * part select. In this case, the node is driving the NetNet. * * Note that whatever the direction that data is intended to flow, * pin-0 is the part select and pin-1 is connected to the NetNet. */ class NetPartSelect : public NetNode { public: // enum for the device direction enum dir_t { VP, PV}; explicit NetPartSelect(NetNet*sig, unsigned off, unsigned wid, dir_t dir, bool signed_flag__ = false); explicit NetPartSelect(NetNet*sig, NetNet*sel, unsigned wid, bool signed_flag__ = false); ~NetPartSelect(); unsigned base() const; unsigned width() const; inline dir_t dir() const { return dir_; } /* Is the select signal signed? */ inline bool signed_flag() const { return signed_flag_; } virtual void dump_node(std::ostream&, unsigned ind) const; bool emit_node(struct target_t*tgt) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned off_; unsigned wid_; dir_t dir_; bool signed_flag_; }; /* * This device supports simple substitution of a part within a wider * vector. For example, this: * * wire [7:0] foo = NetSubstitute(bar, bat, off); * * means that bar is a vector the same width as foo, bat is a narrower * vector. The off is a constant offset into the bar vector. This * looks something like this: * * foo = bar; * foo[off +: ] = bat; * * There is no direct way in Verilog to express this (as a single * device), it instead turns up in certain synthesis situation, * i.e. the example above. */ class NetSubstitute : public NetNode { public: NetSubstitute(NetNet*sig, NetNet*sub, unsigned wid, unsigned off); ~NetSubstitute(); inline unsigned width() const { return wid_; } inline unsigned base() const { return off_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*tgt) const; virtual void functor_node(Design*des, functor_t*fun); private: unsigned wid_; unsigned off_; }; /* * The NetBUFZ is a magic device that represents the continuous * assign, with the output being the target register and the input * the logic that feeds it. The netlist preserves the directional * nature of that assignment with the BUFZ. The target may elide it if * that makes sense for the technology. * * A NetBUFZ is transparent if strengths are passed through it without * change. A NetBUFZ is non-transparent if values other than HiZ are * converted to the strength of the output. */ class NetBUFZ : public NetNode { public: explicit NetBUFZ(NetScope*s, perm_string n, unsigned wid, bool transp); ~NetBUFZ(); unsigned width() const; bool transparent() const { return transparent_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; bool transparent_; }; /* * This node is used to represent case equality in combinational * logic. Although this is not normally synthesizable, it makes sense * to support an abstract gate that can compare x and z. This node * always generates a single bit result, no matter the width of the * input. The elaboration, btw, needs to make sure the input widths * match. * * The case compare can be generated to handle ===/!==, or also * to test guards in the case/casez/casex statements. * * This pins are assigned as: * * 0 -- Output (always returns 0 or 1) * 1 -- Input * 2 -- Input (wildcard input for EQX and EQZ variants) */ class NetCaseCmp : public NetNode { public: enum kind_t { EEQ, // === NEQ, // !== WEQ, // ==? WNE, // !=? XEQ, // casex guard tests ZEQ // casez guard tests }; public: explicit NetCaseCmp(NetScope*s, perm_string n, unsigned wid, kind_t eeq); ~NetCaseCmp(); unsigned width() const; // What kind of case compare? inline kind_t kind() const { return kind_; } virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; private: unsigned width_; const kind_t kind_; }; extern std::ostream& operator << (std::ostream&fd, NetCaseCmp::kind_t that); /* NOTE: This class should be replaced with the NetLiteral class * below, that is more general in that it supports different types of * values. * * This class represents instances of the LPM_CONSTANT device. The * node has only outputs and a constant value. The width is available * by getting the pin_count(), and the value bits are available one at * a time. There is no meaning to the aggregation of bits to form a * wide NetConst object, although some targets may have an easier time * detecting interesting constructs if they are combined. */ class NetConst : public NetNode { public: explicit NetConst(NetScope*s, perm_string n, verinum::V v); explicit NetConst(NetScope*s, perm_string n, const verinum&val); ~NetConst(); inline const verinum&value(void) const { return value_; } verinum::V value(unsigned idx) const; inline unsigned width() const { return value_.len(); } inline bool is_string() const { return value_.is_string(); } virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*, functor_t*); virtual void dump_node(std::ostream&, unsigned ind) const; private: verinum value_; }; /* * This class represents instances of the LPM_CONSTANT device. The * node has only outputs and a constant value. The width is available * by getting the pin_count(), and the value bits are available one at * a time. There is no meaning to the aggregation of bits to form a * wide NetConst object, although some targets may have an easier time * detecting interesting constructs if they are combined. */ class NetLiteral : public NetNode { public: // A read-valued literal. explicit NetLiteral(NetScope*s, perm_string n, const verireal&val); ~NetLiteral(); ivl_variable_type_t data_type() const; const verireal& value_real() const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*, functor_t*); virtual void dump_node(std::ostream&, unsigned ind) const; private: verireal real_; }; /* * This class represents all manner of logic gates. Pin 0 is OUTPUT and * all the remaining pins are INPUT. The BUFIF[01] gates have the * more specific pinout as follows: * * bufif * 0 -- output * 1 -- input data * 2 -- enable * * The pullup and pulldown gates have no inputs at all, and pin0 is * the output 1 or 0, depending on the gate type. It is the strength * of that value that is important. * * All these devices process vectors bitwise, so each bit can be * logically separated. The exception is the CONCAT gate, which is * really an abstract gate that takes the inputs and turns it into a * vector of bits. */ class NetLogic : public NetNode { public: enum TYPE { AND, BUF, BUFIF0, BUFIF1, CMOS, EQUIV, IMPL, NAND, NMOS, NOR, NOT, NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RCMOS, RNMOS, RPMOS, PMOS, XNOR, XOR }; explicit NetLogic(NetScope*s, perm_string n, unsigned pins, TYPE t, unsigned wid, bool is_cassign__=false); TYPE type() const; unsigned width() const; bool is_cassign() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*, functor_t*); private: TYPE type_; unsigned width_; bool is_cassign_; }; /* * This class represents a structural sign extension. The pin-0 is a * vector of the input pin-1 sign-extended. The input is taken to be * signed. This generally matches a hardware implementation of * replicating the top bit enough times to create the desired output * width. */ class NetSignExtend : public NetNode { public: explicit NetSignExtend(NetScope*s, perm_string n, unsigned wid); ~NetSignExtend(); unsigned width() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*, functor_t*); private: unsigned width_; }; /* * This class represents *reduction* logic operators. Certain boolean * logic operators have reduction forms which take in a vector and * return a single bit that is calculated by applying the logic * operation through the width of the input vector. These correspond * to reduction unary operators in Verilog. */ class NetUReduce : public NetNode { public: enum TYPE {NONE, AND, OR, XOR, NAND, NOR, XNOR}; NetUReduce(NetScope*s, perm_string n, TYPE t, unsigned wid); TYPE type() const; unsigned width() const; virtual void dump_node(std::ostream&, unsigned ind) const; virtual bool emit_node(struct target_t*) const; virtual void functor_node(Design*, functor_t*); private: TYPE type_; unsigned width_; }; /* * The UDP is a User Defined Primitive from the Verilog source. Do not * expand it out any further than this in the netlist, as this can be * used to represent target device primitives. * * The UDP can be combinational or sequential. The sequential UDP * includes the current output in the truth table, and supports edges, * whereas the combinational does not and is entirely level sensitive. * In any case, pin 0 is an output, and all the remaining pins are * inputs. * * Set_table takes as input a string with one letter per pin. The * parser translates the written sequences to one of these. The * valid characters are: * * 0, 1, x -- The levels * r -- (01) * R -- (x1) * f -- (10) * F -- (x0) * P -- (0x) * N -- (1x) * * It also takes one of the following glob letters to represent more * than one item. * * p -- 01, 0x or x1 // check this with the lexer * n -- 10, 1x or x0 // check this with the lexer * ? -- 0, 1, or x * * -- any edge * + -- 01 or x1 * _ -- 10 or x0 (Note that this is not the output '-'.) * % -- 0x or 1x * * SEQUENTIAL * These objects have a single bit of memory. The logic table includes * an entry for the current value, and allows edges on the inputs. In * canonical form, only the entries that generate 0, 1 or - (no change) * are listed. * * COMBINATIONAL * The logic table is a map between the input levels and the * output. Each input pin can have the value 0, 1 or x and the output * can have the values 0 or 1. If the input matches nothing, the * output is x. In canonical form, only the entries that generate 0 or * 1 are listed. * */ class NetUDP : public NetNode { public: explicit NetUDP(NetScope*s, perm_string n, unsigned pins, PUdp*u); virtual bool emit_node(struct target_t*) const; virtual void dump_node(std::ostream&, unsigned ind) const; /* Use these methods to scan the truth table of the device. "first" returns the first item in the table, and "next" returns the next item in the table. The method will return false when the scan is done. */ bool first(std::string&inp, char&out) const; bool next(std::string&inp, char&out) const; unsigned rows() const { return udp->tinput.size(); } unsigned nin() const { return pin_count()-1; } bool is_sequential() const { return udp->sequential; } perm_string udp_name() const { return udp->name_; } perm_string udp_file() const { return udp->get_file(); } unsigned udp_lineno() const { return udp->get_lineno(); } char get_initial() const; unsigned port_count() const; std::string port_name(unsigned idx) const; private: mutable unsigned table_idx; PUdp *udp; }; enum DelayType { NO_DELAY, ZERO_DELAY, POSSIBLE_DELAY, DEFINITE_DELAY }; /* ========= * A process is a behavioral-model description. A process is a * statement that may be compound. The various statement types may * refer to places in a netlist (by pointing to nodes) but is not * linked into the netlist. However, elaborating a process may cause * special nodes to be created to handle things like events. */ class NetProc : public virtual LineInfo { public: explicit NetProc(); virtual ~NetProc(); // Find the nexa that are input by the statement. This is used // for example by @* to find the inputs to the process for the // sensitivity list. virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; // Find the nexa that are set by the statement. Add the output // values to the set passed as a parameter. virtual void nex_output(NexusSet&); // This method is called to emit the statement to the // target. The target returns true if OK, false for errors. virtual bool emit_proc(struct target_t*) const; // This method is used by the NetFuncDef object to evaluate a // constant function at compile time. The loc is the location // of the function call, and is used for error messages. The // ctx is a map of name to expression. This is for mapping // identifiers to values. The function returns true if the // processing succeeds, or false otherwise. virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; // This method is called by functors that want to scan a // process in search of matchable patterns. virtual int match_proc(struct proc_match_t*); // Return true if this represents the root of a combinational // process. Most process types are not. virtual bool is_asynchronous(); // Return true if this represents the root of a synchronous // process. Most process types are not. virtual bool is_synchronous(); // Synthesize as asynchronous logic, and return true on success. // // nex_map holds the set of nexuses that are driven by this // process, nex_out holds the accumulated outputs from this and // preceding sequential processes (i.e statements in the same // block), enables holds the accumulated clock/gate enables, // and bitmasks holds the accumulated masks that flag which bits // are unconditionally driven (i.e. driven by every clause in // every statement). On output, the values passed in to nex_out, // enables, and bitmasks may either be merged with or replaced // by the values originating from this process, depending on the // type of statement this process represents. // // The clock/gate enables generated by synthesis operate at a // vector level (i.e. they are asserted if any bit(s) in the // vector are driven). typedef std::vector mask_t; virtual bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); // Synthesize as synchronous logic, and return true on success. // That means binding the outputs to the data port of a FF, and // the event inputs to a FF clock. Only some key NetProc sub-types // that have specific meaning in synchronous statements. The // remainder reduce to a call to synth_async that connects the // output to the Data input of the FF. // // The nex_map, nex_out, ff_ce, and bitmasks arguments serve // the same purpose as in the synth_async method (where ff_ce // is equivalent to enables). The events argument is filled // in by the NetEvWait implementation of this method with the // probes that it does not itself pick off as a clock. These // events should be picked off by e.g. condit statements as // asynchronous set/reset inputs to the flipflop being generated. virtual bool synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clock, NetBus&ff_ce, NetBus&ff_aclr, NetBus&ff_aset, std::vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, std::vector&bitmasks, const std::vector&events); virtual void dump(std::ostream&, unsigned ind) const; // Recursively checks to see if there is delay in this element. virtual DelayType delay_type(bool print_delay=false) const; // Check to see if the item is synthesizable. virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; protected: bool synth_async_block_substatement_(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks, NetProc*substmt); private: friend class NetBlock; NetProc*next_; private: // not implemented NetProc(const NetProc&); NetProc& operator= (const NetProc&); }; class NetAlloc : public NetProc { public: explicit NetAlloc(NetScope*); ~NetAlloc(); const std::string name() const; const NetScope* scope() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; private: NetScope*scope_; }; /* * Procedural assignment is broken into a suite of classes. These * classes represent the various aspects of the assignment statement * in behavioral code. (The continuous assignment is *not* * represented here.) * * The NetAssignBase carries the common aspects of an assignment, * including the r-value. This class has no cares of blocking vs * non-blocking, however it carries nearly all the other properties * of the assignment statement. It is abstract because it does not * differentiate the virtual behaviors. * * The NetAssign and NetAssignNB classes are the concrete classes that * give the assignment its final, precise meaning. These classes fill * in the NetProc behaviors. * * The l-value of the assignment is a collection of NetAssign_ * objects that are connected to the structural netlist where the * assignment has its effect. The NetAssign_ class is not to be * derived from. * * The collection is arranged from lsb up to msb, and represents the * concatenation of l-values. The elaborator may collapse some * concatenations into a single NetAssign_. The "more" member of the * NetAssign_ object points to the next most significant bits of l-value. * * NOTE: The elaborator will make an effort to match the width of the * r-value to the width of the l-value, but targets and functions * should know that this is not a guarantee. */ class NetAssign_ { public: explicit NetAssign_(NetAssign_*nest); explicit NetAssign_(NetNet*sig); ~NetAssign_(); // This is so NetAssign_ objects can be passed to ivl_assert // and other macros that call this method. std::string get_fileline() const; // If this expression exists, then it is used to select a word // from an array/memory. NetExpr*word(); const NetExpr*word() const; NetScope*scope()const; // Get the base index of the part select, or 0 if there is no // part select. const NetExpr* get_base() const; ivl_select_type_t select_type() const; void set_word(NetExpr*); // Set a part select expression for the l-value vector. Note // that the expression calculates a CANONICAL bit address. void set_part(NetExpr* loff, unsigned wid, ivl_select_type_t = IVL_SEL_OTHER); // Set the member or property name if the signal type is a // class. void set_property(const perm_string&name, unsigned int idx); inline int get_property_idx(void) const { return member_idx_; } // Determine if the assigned object is signed or unsigned. // This is used when determining the expression type for // a compressed assignment statement. bool get_signed() const { return signed_; } void set_signed(bool flag) { signed_ = flag; } // Get the width of the r-value that this node expects. This // method accounts for the presence of the mux, so it is not // necessarily the same as the pin_count(). unsigned lwidth() const; ivl_variable_type_t expr_type() const; // Get the expression type of the l-value. This may be // different from the type of the contained signal if for // example a darray is indexed. const ivl_type_s* net_type() const; // Return the enumeration type of this l-value, or nil if it's // not an enumeration. const netenum_t*enumeration() const; // Get the name of the underlying object. perm_string name() const; NetNet* sig() const; inline const NetAssign_* nest() const { return nest_; } // Mark that the synthesizer has worked with this l-value, so // when it is released, the l-value signal should be turned // into a wire. void turn_sig_to_wire_on_release(); // It is possible that l-values can have *inputs*, as well as // being outputs. For example foo[idx] = ... is the l-value // (NetAssign_ object) with a foo l-value and the input // expression idx. NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; // Figuring out nex_output to process ultimately comes down to // this method. void nex_output(NexusSet&); // This pointer is for keeping simple lists. NetAssign_* more; void dump_lval(std::ostream&o) const; private: // Nested l-value. If this is set, sig_ must NOT be set! NetAssign_*nest_; NetNet *sig_; // Memory word index NetExpr*word_; // member/property if signal is a class. perm_string member_; int member_idx_ = -1; bool signed_; bool turn_sig_to_wire_on_release_; // indexed part select base NetExpr*base_; unsigned lwid_; ivl_select_type_t sel_type_; }; class NetAssignBase : public NetProc { public: NetAssignBase(NetAssign_*lv, NetExpr*rv); virtual ~NetAssignBase() =0; // This is the (procedural) value that is to be assigned when // the assignment is executed. NetExpr*rval(); const NetExpr*rval() const; void set_rval(NetExpr*); NetAssign_* l_val(unsigned); const NetAssign_* l_val(unsigned) const; unsigned l_val_count() const; void set_delay(NetExpr*); const NetExpr* get_delay() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&o); // This returns the total width of the accumulated l-value. It // accounts for any grouping of NetAssign_ objects that might happen. unsigned lwidth() const; bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); // This dumps all the lval structures. void dump_lval(std::ostream&) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetAssign_*lval_; NetExpr *rval_; NetExpr *delay_; }; class NetAssign : public NetAssignBase { public: explicit NetAssign(NetAssign_*lv, NetExpr*rv); explicit NetAssign(NetAssign_*lv, char op, NetExpr*rv); ~NetAssign(); bool is_asynchronous(); inline char assign_operator(void) const { return op_; } virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: void eval_func_lval_op_real_(const LineInfo&loc, verireal&lv, const verireal&rv) const; void eval_func_lval_op_(const LineInfo&loc, verinum&lv, verinum&rv) const; bool eval_func_lval_(const LineInfo&loc, std::map&ctx, const NetAssign_*lval, NetExpr*rval_result) const; char op_; }; class NetAssignNB : public NetAssignBase { public: explicit NetAssignNB(NetAssign_*lv, NetExpr*rv, NetEvWait*ev, NetExpr*cnt); ~NetAssignNB(); virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; unsigned nevents() const; const NetEvent*event(unsigned) const; const NetExpr* get_count() const; private: NetEvWait*event_; NetExpr*count_; }; /* * A block is stuff like begin-end blocks, that contain an ordered * list of NetProc statements. * * NOTE: The emit method calls the target->proc_block function but * does not recurse. It is up to the target-supplied proc_block * function to call emit_recurse. */ class NetBlock : public NetProc { public: enum Type { SEQU, PARA, PARA_JOIN_ANY, PARA_JOIN_NONE }; NetBlock(Type t, NetScope*subscope); ~NetBlock(); Type type() const { return type_; } NetScope* subscope() const { return subscope_; } void append(NetProc*); void prepend(NetProc*); const NetProc*proc_first() const; const NetProc*proc_next(const NetProc*cur) const; bool evaluate_function(const LineInfo&loc, std::map&ctx) const; // synthesize as asynchronous logic, and return true. bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); bool synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, std::vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, std::vector&bitmasks, const std::vector&events); // This version of emit_recurse scans all the statements of // the begin-end block sequentially. It is typically of use // for sequential blocks. void emit_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: const Type type_; NetScope*subscope_; NetProc*last_; }; /* * A CASE statement in the Verilog source leads, eventually, to one of * these. This is different from a simple conditional because of the * way the comparisons are performed. Also, it is likely that the * target may be able to optimize differently. * * Case statements can have unique, unique0, or priority attached to * them. If not otherwise adorned, it is QBASIC. * * Case can be one of three types: * EQ -- All bits must exactly match * EQZ -- z bits are don't care * EQX -- x and z bits are don't care. */ class NetCase : public NetProc { public: enum TYPE { EQ, EQX, EQZ }; NetCase(ivl_case_quality_t q, TYPE c, NetExpr*ex, unsigned cnt); ~NetCase(); void set_case(unsigned idx, NetExpr*ex, NetProc*st); void prune(); inline ivl_case_quality_t case_quality() const { return quality_; } TYPE type() const; const NetExpr*expr() const { return expr_; } inline unsigned nitems() const { return items_.size(); } inline const NetExpr*expr(unsigned idx) const { return items_[idx].guard;} inline const NetProc*stat(unsigned idx) const { return items_[idx].statement; } virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&out); bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: bool evaluate_function_vect_(const LineInfo&loc, std::map&ctx) const; bool evaluate_function_real_(const LineInfo&loc, std::map&ctx) const; bool synth_async_casez_(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); ivl_case_quality_t quality_; TYPE type_; struct Item { inline Item() : guard(0), statement(0) { } NetExpr*guard; NetProc*statement; }; NetExpr* expr_; std::vectoritems_; }; /* * The cassign statement causes the r-val net to be forced onto the * l-val reg when it is executed. The code generator is expected to * know what that means. */ class NetCAssign : public NetAssignBase { public: explicit NetCAssign(NetAssign_*lv, NetExpr*rv); ~NetCAssign(); virtual void dump(std::ostream&, unsigned ind) const; virtual bool emit_proc(struct target_t*) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: // not implemented NetCAssign(const NetCAssign&); NetCAssign& operator= (const NetCAssign&); }; /* * A condit represents a conditional. It has an expression to test, * and a pair of statements to select from. If the original statement * has empty clauses, then the NetProc for it will be a null pointer. */ class NetCondit : public NetProc { public: explicit NetCondit(NetExpr*ex, NetProc*i, NetProc*e); ~NetCondit(); const NetExpr*expr() const; NetExpr*expr(); NetProc* if_clause(); NetProc* else_clause(); // Replace the condition expression. void set_expr(NetExpr*ex); bool emit_recurse_if(struct target_t*) const; bool emit_recurse_else(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&o); bool is_asynchronous(); bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); bool synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, std::vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, std::vector&bitmasks, const std::vector&events); virtual bool emit_proc(struct target_t*) const; virtual int match_proc(struct proc_match_t*); virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetExpr* expr_; NetProc*if_; NetProc*else_; }; /* * This represents the analog contribution statement. The l-val is a * branch expression, and the r-value is an arbitrary expression that * may include branches and real values. */ class NetContribution : public NetProc { public: explicit NetContribution(NetEAccess*lval, NetExpr*rval); ~NetContribution(); const NetEAccess* lval() const; const NetExpr* rval() const; virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; private: NetEAccess*lval_; NetExpr*rval_; }; /* * The procedural deassign statement (the opposite of assign) releases * any assign expressions attached to the bits of the reg. The * lval is the expression of the "deassign ;" statement with the * expr elaborated to a net. */ class NetDeassign : public NetAssignBase { public: explicit NetDeassign(NetAssign_*l); ~NetDeassign(); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: // not implemented NetDeassign(const NetDeassign&); NetDeassign& operator= (const NetDeassign&); }; /* * This node represents the behavioral disable statement. The Verilog * source that produces it looks like: * * disable ; * * Where the scope is a named block or a task. It cannot be a module * instance scope because module instances cannot be disabled. */ class NetDisable : public NetProc { public: explicit NetDisable(NetScope*tgt, bool flow_control = false); ~NetDisable(); const NetScope*target() const; bool flow_control() const { return flow_control_; } virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetScope*target_; // If false all threads in the target_ scope are disabled. If true only // the closest thread in thread hierachy of the target_ scope is // disabled. The latter is used to implement flow control statements like // `return`. bool flow_control_; private: // not implemented NetDisable(const NetDisable&); NetDisable& operator= (const NetDisable&); }; /* * The do/while statement is a condition that is tested at the end of * each iteration, and a statement (a NetProc) that is executed once and * then again as long as the condition is true. */ class NetDoWhile : public NetProc { public: NetDoWhile(NetExpr*c, NetProc*p) : cond_(c), proc_(p) { } const NetExpr*expr() const { return cond_; } void emit_proc_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetExpr* cond_; NetProc*proc_; }; /* * A NetEvent is an object that represents an event object, that is * objects declared like so in Verilog: * * event foo; * * Once an object of this type exists, behavioral code can wait on the * event or trigger the event. Event waits refer to this object, as do * the event trigger statements. The NetEvent class may have a name and * a scope. The name is a simple name (no hierarchy) and the scope is * the NetScope that contains the object. The scope member is written * by the NetScope object when the NetEvent is stored. * * The NetEvWait class represents a thread wait for an event. When * this statement is executed, it starts waiting on the * event. Conceptually, it puts itself on the event list for the * referenced event. When the event is triggered, the wait ends its * block and starts the associated statement. * * The NetEvTrig class represents trigger statements. Executing this * statement causes the referenced event to be triggered, which in * turn awakens the waiting threads. Each NetEvTrig object references * exactly one event object. * * The NetEvNBTrig class represents non-blocking trigger statements. * Executing this statement causes the referenced event to be triggered * at some time in the future, which in turn awakens the waiting threads. * Each NetEvNBTrig object references exactly one event object. * * The NetEvProbe class is the structural equivalent of the NetEvTrig, * in that it is a node and watches bit values that it receives. It * checks for edges then if appropriate triggers the associated * NetEvent. Each NetEvProbe references exactly one event object, and * the NetEvent objects have a list of NetEvProbe objects that * reference it. */ class NetEvent : public LineInfo { friend class NetScope; friend class NetEvProbe; friend class NetEvTrig; friend class NetEvNBTrig; friend class NetEvWait; friend class NetEEvent; public: // The name of the event is the basename, and should not // include the scope. Also, the name passed here should be // perm-allocated. explicit NetEvent (perm_string n); ~NetEvent(); perm_string name() const; bool local_flag() const { return local_flag_; } void local_flag(bool f) { local_flag_ = f; } // Get information about probes connected to me. unsigned nprobe() const; NetEvProbe* probe(unsigned); const NetEvProbe* probe(unsigned) const; // Return the number of NetEvWait nodes that reference me. unsigned nwait() const; unsigned ntrig() const; unsigned nexpr() const; NetScope* scope(); const NetScope* scope() const; void nex_output(NexusSet&); // Locate the first event that matches my behavior and // monitors the same signals. void find_similar_event(std::list&); // This method replaces pointers to me with pointers to // that. It is typically used to replace similar events // located by the find_similar_event method. void replace_event(NetEvent*that); private: // This returns a nexus set if it represents possibly // asynchronous inputs, otherwise 0. NexusSet*nex_async_(); private: perm_string name_; bool local_flag_; // The NetScope class uses these to list the events. NetScope*scope_; NetEvent*snext_; // Use these methods to list the probes attached to me. NetEvProbe*probes_; // Use these methods to list the triggers attached to me. NetEvTrig* trig_; // Use these methods to list the non-blocking triggers attached to me. NetEvNBTrig* nb_trig_; // Use This member to count references by NetEvWait objects. unsigned waitref_; struct wcell_ { NetEvWait*obj; struct wcell_*next; }; struct wcell_ *wlist_; // expression references, ala. task/funcs unsigned exprref_; private: // not implemented NetEvent(const NetEvent&); NetEvent& operator= (const NetEvent&); }; class NetEvTrig : public NetProc { friend class NetEvent; public: explicit NetEvTrig(NetEvent*tgt); ~NetEvTrig(); const NetEvent*event() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetEvent*event_; // This is used to place me in the NetEvents lists of triggers. NetEvTrig*enext_; }; class NetEvNBTrig : public NetProc { friend class NetEvent; public: explicit NetEvNBTrig(NetEvent*tgt, NetExpr*dly); ~NetEvNBTrig(); const NetExpr*delay() const; const NetEvent*event() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetEvent*event_; NetExpr*dly_; // This is used to place me in the NetEvents lists of triggers. NetEvNBTrig*enext_; }; class NetEvWait : public NetProc { public: explicit NetEvWait(NetProc*st); ~NetEvWait(); void add_event(NetEvent*tgt); void replace_event(NetEvent*orig, NetEvent*repl); inline void set_t0_trigger() { has_t0_trigger_ = true; }; inline unsigned nevents() const { return events_.size(); } inline const NetEvent*event(unsigned idx) const { return events_[idx]; } inline NetEvent*event(unsigned idx) { return events_[idx]; } inline bool has_t0_trigger() const { return has_t0_trigger_; }; NetProc*statement(); const NetProc*statement() const; virtual bool emit_proc(struct target_t*) const; bool emit_recurse(struct target_t*) const; virtual int match_proc(struct proc_match_t*); // It is possible that this is the root of a combinational // process. This method checks. virtual bool is_asynchronous(); // It is possible that this is the root of a synchronous // process? This method checks. virtual bool is_synchronous(); virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&out); virtual bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); virtual bool synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, std::vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, std::vector&bitmasks, const std::vector&events); virtual void dump(std::ostream&, unsigned ind) const; // This will ignore any statement. virtual void dump_inline(std::ostream&) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetProc*statement_; // Events that I might wait for. std::vectorevents_; bool has_t0_trigger_; }; std::ostream& operator << (std::ostream&out, const NetEvWait&obj); class NetEvProbe : public NetNode { friend class NetEvent; public: enum edge_t { ANYEDGE, POSEDGE, NEGEDGE, EDGE }; explicit NetEvProbe(NetScope*s, perm_string n, NetEvent*tgt, edge_t t, unsigned p); ~NetEvProbe(); edge_t edge() const; NetEvent* event(); const NetEvent* event() const; void find_similar_probes(std::list&); virtual bool emit_node(struct target_t*) const; virtual void dump_node(std::ostream&, unsigned ind) const; private: NetEvent*event_; edge_t edge_; // The NetEvent class uses this to list me. NetEvProbe*enext_; }; /* * The force statement causes the r-val net to be forced onto the * l-val net when it is executed. The code generator is expected to * know what that means. */ class NetForce : public NetAssignBase { public: explicit NetForce(NetAssign_*l, NetExpr*r); ~NetForce(); virtual void dump(std::ostream&, unsigned ind) const; virtual bool emit_proc(struct target_t*) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; }; /* * A forever statement is executed over and over again forever. Or * until its block is disabled. */ class NetForever : public NetProc { public: explicit NetForever(NetProc*s); ~NetForever(); void emit_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetProc*statement_; }; class NetForLoop : public NetProc { public: explicit NetForLoop(NetNet*index, NetExpr*initial_expr, NetExpr*cond, NetProc*sub, NetProc*step); ~NetForLoop(); void wrap_up(); void emit_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; // synthesize as asynchronous logic, and return true. bool synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, std::vector&bitmasks); private: NetNet*index_; NetExpr*init_expr_; NetExpr*condition_; NetProc*statement_; NetProc*step_statement_; // The code generator needs to see this rewritten as a while // loop with synthetic statements. This is a hack that I // should probably take out later as the ivl_target learns // about for loops. NetBlock*as_block_; }; class NetFree : public NetProc { public: explicit NetFree(NetScope*); ~NetFree(); const std::string name() const; const NetScope* scope() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; private: NetScope*scope_; }; /* * A function definition is elaborated just like a task, though by now * it is certain that the first parameter (a phantom parameter) is the * output and all the remaining parameters are the inputs. This makes * for easy code generation in targets that support behavioral * descriptions. * * The NetNet array that is passed in as a parameter is the set of * signals that make up its parameter list. These are all internal to * the scope of the function. */ class NetFuncDef : public NetBaseDef { public: NetFuncDef(NetScope*, NetNet*result, const std::vector&po, const std::vector&pd); ~NetFuncDef(); // Return true if the function returns "void". We still treat // it as a function since we need to check that the contents // meet the requirements of a function, but we need to know // that it is void because it can be evaluated differently. inline bool is_void() const { return result_sig_ == 0; } // Non-void functions have a return value as a signal. const NetNet*return_sig() const; // When we want to evaluate the function during compile time, // use this method to pass in the argument and get out a // result. The result should be a constant. If the function // cannot evaluate to a constant, this returns nil. NetExpr* evaluate_function(const LineInfo&loc, const std::vector&args) const; void dump(std::ostream&, unsigned ind) const; private: NetNet*result_sig_; }; /* * This class represents delay statements of the form: * * # * * Where the statement may be null. The delay is evaluated at * elaboration time to make a constant unsigned long that is the delay * in simulation ticks. * * If the delay expression is non-constant, construct the NetPDelay * object with a NetExpr* instead of the d value, and use the expr() * method to get the expression. If expr() returns 0, use the delay() * method to get the constant delay. */ class NetPDelay : public NetProc { public: NetPDelay(uint64_t d, NetProc*st); NetPDelay(NetExpr* d, NetProc*st); ~NetPDelay(); uint64_t delay() const; const NetExpr*expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; bool emit_proc_recurse(struct target_t*) const; private: uint64_t delay_; NetExpr*expr_; NetProc*statement_; }; /* * A repeat statement is executed some fixed number of times. */ class NetRepeat : public NetProc { public: explicit NetRepeat(NetExpr*e, NetProc*s); ~NetRepeat(); const NetExpr*expr() const; void emit_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetExpr*expr_; NetProc*statement_; }; /* * The procedural release statement (the opposite of force) releases * any force expressions attached to the bits of the wire or reg. The * lval is the expression of the "release ;" statement with the * expr elaborated to a net. */ class NetRelease : public NetAssignBase { public: explicit NetRelease(NetAssign_*l); ~NetRelease(); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: }; /* * The NetSTask class is a call to a system task. These kinds of tasks * are generally handled very simply in the target. They certainly are * handled differently from user defined tasks because ivl knows all * about the user defined tasks. */ class NetSTask : public NetProc { public: NetSTask(const char*na, ivl_sfunc_as_task_t sfat, const std::vector&); ~NetSTask(); const char* name() const; ivl_sfunc_as_task_t sfunc_as_task() const; unsigned nparms() const; const NetExpr* parm(unsigned idx) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: const char* name_; ivl_sfunc_as_task_t sfunc_as_task_; std::vectorparms_; }; /* * This class represents an elaborated class definition. NetUTask * classes may refer to objects of this type to get the meaning of the * defined task. * * The task also introduces a scope, and the parameters are actually * reg objects in the new scope. The task is called by the calling * thread assigning (blocking assignment) to the in and inout * parameters, then invoking the thread, and finally assigning out the * output and inout variables. The variables accessible as ports are * also elaborated and accessible as ordinary reg objects. */ class NetTaskDef : public NetBaseDef { public: NetTaskDef(NetScope*n, const std::vector&po, const std::vector&pd); ~NetTaskDef(); void dump(std::ostream&, unsigned) const; DelayType delay_type(bool print_delay=false) const; private: // not implemented NetTaskDef(const NetTaskDef&); NetTaskDef& operator= (const NetTaskDef&); }; /* * The NetELast expression node takes as an argument a net, that is * intended to be a queue or dynamic array object. The return value is * the index of the last item in the node. This is intended to * implement the '$' is the expression "foo[$]". */ class NetELast : public NetExpr { public: explicit NetELast(NetNet*sig); ~NetELast(); inline const NetNet*sig() const { return sig_; } virtual ivl_variable_type_t expr_type() const; virtual void dump(std::ostream&) const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetELast*dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; private: NetNet*sig_; }; /* * This node represents a function call in an expression. The object * contains a pointer to the function definition, which is used to * locate the value register and input expressions. */ class NetEUFunc : public NetExpr { public: NetEUFunc(NetScope*, NetScope*, NetESignal*, std::vector&, bool); ~NetEUFunc(); const NetESignal*result_sig() const; unsigned parm_count() const; const NetExpr* parm(unsigned idx) const; const NetScope* func() const; virtual ivl_variable_type_t expr_type() const; virtual const netenum_t* enumeration() const; virtual void dump(std::ostream&) const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEUFunc*dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual NetExpr* eval_tree(); virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root); private: NetScope*scope_; NetScope*func_; NetESignal*result_sig_; std::vector parms_; bool need_const_; private: // not implemented NetEUFunc(const NetEUFunc&); NetEUFunc& operator= (const NetEUFunc&); }; /* * A call to a nature access function for a branch. */ class NetEAccess : public NetExpr { public: explicit NetEAccess(NetBranch*br, ivl_nature_t nat); ~NetEAccess(); ivl_nature_t get_nature() const { return nature_; } NetBranch* get_branch() const { return branch_; } virtual ivl_variable_type_t expr_type() const; virtual void dump(std::ostream&) const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEAccess*dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; private: NetBranch*branch_; ivl_nature_t nature_; }; /* * A call to a user defined task is elaborated into this object. This * contains a pointer to the elaborated task definition, but is a * NetProc object so that it can be linked into statements. */ class NetUTask : public NetProc { public: explicit NetUTask(NetScope*); ~NetUTask(); const std::string name() const; const NetScope* task() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; private: NetScope*task_; }; /* * The while statement is a condition that is tested in the front of * each iteration, and a statement (a NetProc) that is executed as * long as the condition is true. */ class NetWhile : public NetProc { public: NetWhile(NetExpr*c, NetProc*p) : cond_(c), proc_(p) { } const NetExpr*expr() const { return cond_; } void emit_proc_recurse(struct target_t*) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void nex_output(NexusSet&); virtual bool emit_proc(struct target_t*) const; virtual void dump(std::ostream&, unsigned ind) const; virtual DelayType delay_type(bool print_delay=false) const; virtual bool check_synth(ivl_process_type_t pr_type, const NetScope*scope) const; virtual bool evaluate_function(const LineInfo&loc, std::map&ctx) const; private: NetExpr*cond_; NetProc*proc_; }; /* * The is the top of any process. It carries the type (initial or * always) and a pointer to the statement, probably a block, that * makes up the process. */ class NetProcTop : public LineInfo, public Attrib { public: NetProcTop(NetScope*s, ivl_process_type_t t, class NetProc*st); ~NetProcTop(); ivl_process_type_t type() const { return type_; } NetProc*statement(); const NetProc*statement() const; NetScope*scope(); const NetScope*scope() const; /* Return true if this process represents combinational logic. */ bool is_asynchronous() const; /* Create asynchronous logic from this thread and return true, or return false if that cannot be done. */ bool synth_async(Design*des); /* Return true if this process represents synchronous logic. */ bool is_synchronous(); /* Create synchronous logic from this thread and return true, or return false if that cannot be done. */ bool synth_sync(Design*des); void dump(std::ostream&, unsigned ind) const; bool emit(struct target_t*tgt) const; private: bool tie_off_floating_inputs_(Design*des, NexusSet&nex_map, NetBus&nex_in, std::vector&bitmasks, bool is_ff_input); const ivl_process_type_t type_; NetProc*const statement_; Design*synthesized_design_; NetScope*scope_; friend class Design; NetProcTop*next_; }; class NetAnalogTop : public LineInfo, public Attrib { public: NetAnalogTop(NetScope*scope, ivl_process_type_t t, NetProc*st); ~NetAnalogTop(); ivl_process_type_t type() const { return type_; } NetProc*statement(); const NetProc*statement() const; NetScope*scope(); const NetScope*scope() const; void dump(std::ostream&, unsigned ind) const; bool emit(struct target_t*tgt) const; private: const ivl_process_type_t type_; NetProc* statement_; NetScope*scope_; friend class Design; NetAnalogTop*next_; }; /* * This class represents a binary operator, with the left and right * operands and a single character for the operator. The operator * values are: * * ^ -- Bit-wise exclusive OR * + -- Arithmetic add * - -- Arithmetic minus * * -- Arithmetic multiply * / -- Arithmetic divide * % -- Arithmetic modulus * p -- Arithmetic power (**) * & -- Bit-wise AND * | -- Bit-wise OR * < -- Less than * > -- Greater than * e -- Logical equality (==) * E -- Case equality (===) * L -- Less or equal * G -- Greater or equal * n -- Logical inequality (!=) * N -- Case inequality (!==) * a -- Logical AND (&&) * A -- Bitwise NAND (~&) * o -- Logical OR (||) * O -- Bit-wise NOR (~|) * l -- Left shift (<<) * r -- Right shift (>>) * R -- signed right shift (>>>) * X -- Bitwise exclusive NOR (~^) * m -- min(a,b) * M -- max(a,b) */ class NetEBinary : public NetExpr { public: NetEBinary(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBinary(); const NetExpr*left() const { return left_; } const NetExpr*right() const { return right_; } char op() const { return op_; } // A binary expression node only has a definite // self-determinable width if the operands both have definite // widths. virtual bool has_width() const; virtual NetEBinary* dup_expr() const; virtual NetExpr* eval_tree(); virtual NetExpr* evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; protected: char op_; NetExpr* left_; NetExpr* right_; virtual NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const; }; /* * The addition operators have slightly more complex width * calculations because there is the optional carry bit that can be * used. The operators covered by this class are: * + -- Arithmetic add * - -- Arithmetic minus */ class NetEBAdd : public NetEBinary { public: NetEBAdd(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBAdd(); virtual ivl_variable_type_t expr_type() const; virtual NetEBAdd* dup_expr() const; virtual NetExpr* eval_tree(); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetExpr * eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetECReal* eval_tree_real_(const NetExpr*l, const NetExpr*r) const; }; /* * This class represents the integer division operators. * / -- Divide * % -- Modulus */ class NetEBDiv : public NetEBinary { public: NetEBDiv(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBDiv(); virtual ivl_variable_type_t expr_type() const; virtual NetEBDiv* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const; }; /* * The bitwise binary operators are represented by this class. This is * a specialization of the binary operator, so is derived from * NetEBinary. The particular constraints on these operators are that * operand and result widths match exactly, and each bit slice of the * operation can be represented by a simple gate. The operators * covered by this class are: * * ^ -- Bit-wise exclusive OR * & -- Bit-wise AND * | -- Bit-wise OR * O -- Bit-wise NOR * X -- Bit-wise XNOR (~^) */ class NetEBBits : public NetEBinary { public: NetEBBits(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBBits(); virtual NetEBBits* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const; }; /* * The binary comparison operators are handled by this class. This * this case the bit width of the expression is 1 bit, and the * operands take their natural widths. The supported operators are: * * < -- Less than * > -- Greater than * e -- Logical equality (==) * E -- Case equality (===) * L -- Less or equal (<=) * G -- Greater or equal (>=) * n -- Logical inequality (!=) * N -- Case inequality (!==) */ class NetEBComp : public NetEBinary { public: NetEBComp(char op, NetExpr*l, NetExpr*r); ~NetEBComp(); /* A compare expression has a definite width. */ virtual bool has_width() const; virtual ivl_variable_type_t expr_type() const; virtual NetEBComp* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetEConst* must_be_leeq_(const NetExpr*le, const verinum&rv, bool eq_flag) const; NetEConst*eval_arguments_(const NetExpr*le, const NetExpr*re) const; NetEConst*eval_eqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const; NetEConst*eval_eqeq_real_(bool ne_flag, const NetExpr*le, const NetExpr*re) const; NetEConst*eval_less_(const NetExpr*le, const NetExpr*re) const; NetEConst*eval_leeq_(const NetExpr*le, const NetExpr*re) const; NetEConst*eval_leeq_real_(const NetExpr*le, const NetExpr*ri, bool eq_flag) const; NetEConst*eval_gt_(const NetExpr*le, const NetExpr*re) const; NetEConst*eval_gteq_(const NetExpr*le, const NetExpr*re) const; NetEConst*eval_eqeqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const; NetEConst*eval_weqeq_(bool ne_flag, const NetExpr*le, const NetExpr*re) const; }; /* * The binary logical operators are those that return boolean * results. The supported operators are: * * a -- Logical AND (&&) * o -- Logical OR (||) */ class NetEBLogic : public NetEBinary { public: NetEBLogic(char op, NetExpr*l, NetExpr*r); ~NetEBLogic(); virtual NetEBLogic* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const; }; /* * Support the binary min(l,r) and max(l,r) operators. The opcodes * supported are: * * m -- min * M -- max */ class NetEBMinMax : public NetEBinary { public: NetEBMinMax(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBMinMax(); virtual ivl_variable_type_t expr_type() const; private: NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const; }; /* * Support the binary multiplication (*) operator. */ class NetEBMult : public NetEBinary { public: NetEBMult(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBMult(); virtual ivl_variable_type_t expr_type() const; virtual NetEBMult* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const; }; /* * Support the binary power (**) operator. */ class NetEBPow : public NetEBinary { public: NetEBPow(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBPow(); virtual ivl_variable_type_t expr_type() const; virtual NetEBPow* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetExpr* eval_arguments_(const NetExpr*l, const NetExpr*r) const; NetExpr* eval_tree_real_(const NetExpr*l, const NetExpr*r) const; }; /* * Support the binary shift operators. The supported operators are: * * l -- left shift (<<) * r -- right shift (>>) * R -- right shift arithmetic (>>>) */ class NetEBShift : public NetEBinary { public: NetEBShift(char op, NetExpr*l, NetExpr*r, unsigned wid, bool signed_flag); ~NetEBShift(); // A shift expression only needs the left expression to have a // definite width to give the expression a definite width. virtual bool has_width() const; virtual NetEBShift* dup_expr() const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); private: NetEConst* eval_arguments_(const NetExpr*l, const NetExpr*r) const; }; /* * This expression node supports the concat expression. This is an * operator that just glues the results of many expressions into a * single value. * * Note that the class stores the parameter expressions in source code * order. That is, the parm(0) is placed in the most significant * position of the result. */ class NetEConcat : public NetExpr { public: NetEConcat(unsigned cnt, unsigned repeat, ivl_variable_type_t vt); ~NetEConcat(); // Manipulate the parameters. void set(unsigned idx, NetExpr*e); unsigned repeat() const { return repeat_; } unsigned nparms() const { return parms_.size() ; } NetExpr* parm(unsigned idx) const { return parms_[idx]; } virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual NetEConcat* dup_expr() const; virtual NetEConst* eval_tree(); virtual NetExpr* evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root); virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; private: std::vectorparms_; unsigned repeat_; ivl_variable_type_t expr_type_; NetEConst* eval_arguments_(const std::vector&vals, unsigned gap) const; }; /* * This expression node supports bit/part selects from general * expressions. The sub-expression is self-sized, and has bits * selected from it. The base is the expression that identifies the * lsb of the expression, and the wid is the width of the part select, * or 1 for a bit select. No matter what the subexpression is, the * base is translated in canonical bits. It is up to the elaborator * to figure this out and adjust the expression if the subexpression * has a non-canonical base or direction. * * If the base expression is null, then this expression node can be * used to express width expansion, signed or unsigned depending on * the has_sign() flag. * * An alternative form of this expression node is used for dynamic * array word selects and for packed struct member selects. In this * case use_type indicates the type of the selected element/member. */ class NetESelect : public NetExpr { public: NetESelect(NetExpr*exp, NetExpr*base, unsigned wid, ivl_select_type_t sel_type = IVL_SEL_OTHER); NetESelect(NetExpr*exp, NetExpr*base, unsigned wid, ivl_type_t use_type); ~NetESelect(); const NetExpr*sub_expr() const; const NetExpr*select() const; ivl_select_type_t select_type() const; // The type of a bit/part select is the base type of the // sub-expression. The type of an array/member select is // the base type of the element/member. virtual ivl_variable_type_t expr_type() const; virtual const netenum_t* enumeration() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEConst* eval_tree(); virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual NetESelect* dup_expr() const; virtual NetNet*synthesize(Design*des, NetScope*scope, NetExpr*root); virtual void dump(std::ostream&) const; private: NetExpr*expr_; NetExpr*base_; ivl_type_t use_type_; ivl_select_type_t sel_type_; }; /* * This node is for representation of named events. */ class NetEEvent : public NetExpr { public: explicit NetEEvent(NetEvent*); ~NetEEvent(); const NetEvent* event() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEEvent* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; private: NetEvent*event_; }; /* * This class is a special (and magical) expression node type that * represents enumeration types. These can only be found as parameters * to NetSTask objects. */ class NetENetenum : public NetExpr { public: explicit NetENetenum(const netenum_t*); ~NetENetenum(); const netenum_t* netenum() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetENetenum* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; private: const netenum_t*netenum_; }; class NetENew : public NetExpr { public: // Make class object explicit NetENew(ivl_type_t); // dynamic array of objects. explicit NetENew(ivl_type_t, NetExpr*size, NetExpr* init_val=0); ~NetENew(); inline ivl_type_t get_type() const { return obj_type_; } inline const NetExpr*size_expr() const { return size_; } inline const NetExpr*init_expr() const { return init_val_; } virtual ivl_variable_type_t expr_type() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetENew* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; private: ivl_type_t obj_type_; NetExpr*size_; NetExpr*init_val_; }; /* * The NetENull node represents the SystemVerilog (null) * expression. This is always a null class handle. */ class NetENull : public NetExpr { public: NetENull(); ~NetENull(); virtual void expr_scan(struct expr_scan_t*) const; virtual NetENull* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; }; /* * The NetEProperty represents a SystemVerilog property select of a * class object. In SV, the expression would look like "a.b", where * the "a" is the signal (the NetNet) and "b" is the property name. * * The canon_index is an optional expression to address an element for * parameters that are arrays. */ class NetEProperty : public NetExpr { public: NetEProperty(NetNet*n, size_t pidx_, NetExpr*canon_index =0); ~NetEProperty(); inline const NetNet* get_sig() const { return net_; } inline size_t property_idx() const { return pidx_; } inline const NetExpr*get_index() const { return index_; } public: // Overridden methods ivl_variable_type_t expr_type() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEProperty* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; private: NetNet*net_; size_t pidx_; NetExpr*index_; }; /* * This class is a special (and magical) expression node type that * represents scope names. These can only be found as parameters to * NetSTask objects. */ class NetEScope : public NetExpr { public: explicit NetEScope(NetScope*); ~NetEScope(); const NetScope* scope() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEScope* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; private: NetScope*scope_; }; /* * This node represents a system function call in an expression. The * object contains the name of the system function, which the backend * uses to do VPI matching. */ class NetESFunc : public NetExpr { public: NetESFunc(const char*name, ivl_variable_type_t t, unsigned width, unsigned nprms, bool is_overridden =false); NetESFunc(const char*name, ivl_type_t rtype, unsigned nprms); ~NetESFunc(); const char* name() const; unsigned nparms() const; void parm(unsigned idx, NetExpr*expr); NetExpr* parm(unsigned idx); const NetExpr* parm(unsigned idx) const; virtual NetExpr* eval_tree(); virtual NetExpr* evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual const netenum_t* enumeration() const; virtual void dump(std::ostream&) const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetESFunc*dup_expr() const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root); private: /* Use the 32 bit ID as follows: * The lower sixteen bits are used to identify the individual * functions. * * The top sixteen bits are used to indicate the number of * arguments the function can take by bit position. If more * than one bit is set the argument can take a different number * of arguments. This varies from 0 to 14 with the MSB indicating * fifteen or more (an unbounded value). For example all bit set * except for the LSB indicate 1 or more arguments are allowed. */ enum ID { NOT_BUILT_IN = 0x0, /* Available in all version of Verilog/SystemVerilog. */ ITOR = 0x00020001, /* $itor takes one argument. */ RTOI = 0x00020002, /* $rtoi takes one argument. */ /* Available in Verilog 2005 and later. */ ACOS = 0x00020003, /* $acos takes one argument. */ ACOSH = 0x00020004, /* $acosh takes one argument. */ ASIN = 0x00020005, /* $asin takes one argument. */ ASINH = 0x00020006, /* $asinh takes one argument. */ ATAN = 0x00020007, /* $atan takes one argument. */ ATANH = 0x00020008, /* $atanh takes one argument. */ ATAN2 = 0x00040009, /* $atan2 takes two argument. */ CEIL = 0x0002000a, /* $ceil takes one argument. */ CLOG2 = 0x0002000b, /* $clog2 takes one argument. */ COS = 0x0002000c, /* $cos takes one argument. */ COSH = 0x0002000d, /* $cosh takes one argument. */ EXP = 0x0002000e, /* $exp takes one argument. */ FLOOR = 0x0002000f, /* $floor takes one argument. */ HYPOT = 0x00040010, /* $hypot takes two argument. */ LN = 0x00020011, /* $ln takes one argument. */ LOG10 = 0x00020012, /* $log10 takes one argument. */ POW = 0x00040013, /* $pow takes two argument. */ SIN = 0x00020014, /* $sin takes one argument. */ SINH = 0x00020015, /* $sinh takes one argument. */ SQRT = 0x00020016, /* $sqrt takes one argument. */ TAN = 0x00020017, /* $tan takes one argument. */ TANH = 0x00020018, /* $tanh takes one argument. */ /* Added in SystemVerilog 2005 and later. */ DIMS = 0x00020019, /* $dimensions takes one argument. */ HIGH = 0x0006001a, /* $high takes one or two arguments. */ INCR = 0x0006001b, /* $increment takes one or two arguments. */ LEFT = 0x0006001c, /* $left takes one or two arguments. */ LOW = 0x0006001d, /* $low takes one or two arguments. */ RIGHT = 0x0006001e, /* $right takes one or two arguments. */ SIZE = 0x0006001f, /* $size takes one or two arguments. */ UPDIMS = 0x00020020, /* $unpacked_dimensions takes one argument. */ ISUNKN = 0x00020021, /* $isunknown takes one argument. */ ONEHT = 0x00020022, /* $onehot takes one argument. */ ONEHT0 = 0x00020023, /* $onehot0 takes one argument. */ /* Added in SystemVerilog 2009 and later. */ CTONES = 0x00020024, /* $countones takes one argument. */ /* Added in SystemVerilog 2012 and later. */ CTBITS = 0xfffc0025, /* $countbits takes two or more arguments. */ /* Added as Icarus extensions to Verilog-A. */ ABS = 0x00020026, /* $abs takes one argument. */ MAX = 0x00040027, /* $max takes two argument. */ MIN = 0x00040028, /* $min takes two argument. */ /* A dummy value to properly close the enum. */ DUMMY = 0xffffffff }; bool takes_nargs_(ID func, unsigned nargs) { if (nargs > 15) nargs = 15; return func & (1U << (nargs + 16)); } const char* name_; ivl_variable_type_t type_; const netenum_t*enum_type_; std::vectorparms_; bool is_overridden_; ID built_in_id_() const; NetExpr* evaluate_one_arg_(ID id, const NetExpr*arg) const; NetExpr* evaluate_two_arg_(ID id, const NetExpr*arg0, const NetExpr*arg1) const; NetEConst* evaluate_rtoi_(const NetExpr*arg) const; NetECReal* evaluate_itor_(const NetExpr*arg) const; NetEConst* evaluate_clog2_(const NetExpr*arg) const; NetECReal* evaluate_math_one_arg_(ID id, const NetExpr*arg) const; NetECReal* evaluate_math_two_arg_(ID id, const NetExpr*arg0, const NetExpr*arg1) const; NetExpr* evaluate_abs_(const NetExpr*arg) const; NetExpr* evaluate_min_max_(ID id, const NetExpr*arg0, const NetExpr*arg1) const; /* Constant SystemVerilog functions. */ NetEConst* evaluate_countones_(const NetExpr*arg) const; NetEConst* evaluate_dimensions_(const NetExpr*arg) const; NetEConst* evaluate_isunknown_(const NetExpr*arg) const; NetEConst* evaluate_onehot_(const NetExpr*arg) const; NetEConst* evaluate_onehot0_(const NetExpr*arg) const; NetEConst* evaluate_unpacked_dimensions_(const NetExpr*arg) const; /* This value is used as a default when the array functions are * called with a single argument. */ static const NetEConst*const_one_; NetEConst* evaluate_array_funcs_(ID id, const NetExpr*arg0, const NetExpr*arg1) const; NetEConst* evaluate_countbits_(void) const; public: bool is_built_in() const { return built_in_id_() != NOT_BUILT_IN; }; private: // not implemented NetESFunc(const NetESFunc&); NetESFunc& operator= (const NetESFunc&); }; class NetEShallowCopy : public NetExpr { public: // Make a shallow copy from arg2 into arg1. explicit NetEShallowCopy(NetExpr*arg1, NetExpr*arg2); ~NetEShallowCopy(); virtual ivl_variable_type_t expr_type() const; virtual void expr_scan(struct expr_scan_t*) const; virtual NetEShallowCopy* dup_expr() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void dump(std::ostream&os) const; void expr_scan_oper1(struct expr_scan_t*) const; void expr_scan_oper2(struct expr_scan_t*) const; private: NetExpr*arg1_; NetExpr*arg2_; }; /* * This class represents the ternary (?:) operator. It has 3 * expressions, one of which is a condition used to select which of * the other two expressions is the result. */ class NetETernary : public NetExpr { public: NetETernary(NetExpr*c, NetExpr*t, NetExpr*f, unsigned wid, bool signed_flag); ~NetETernary(); const netenum_t* enumeration() const; const NetExpr*cond_expr() const; const NetExpr*true_expr() const; const NetExpr*false_expr() const; virtual NetETernary* dup_expr() const; virtual NetExpr* eval_tree(); virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; virtual NetNet*synthesize(Design*, NetScope*scope, NetExpr*root); public: static bool test_operand_compat(ivl_variable_type_t tru, ivl_variable_type_t fal); private: NetExpr* blended_arguments_(const NetExpr*t, const NetExpr*f) const; NetExpr*cond_; NetExpr*true_val_; NetExpr*false_val_; }; /* * This class represents a unary operator, with the single operand * and a single character for the operator. The operator values are: * * ~ -- Bit-wise negation * ! -- Logical negation * & -- Reduction AND * | -- Reduction OR * ^ -- Reduction XOR * + -- * - -- * A -- Reduction NAND (~&) * N -- Reduction NOR (~|) * X -- Reduction NXOR (~^ or ^~) * m -- abs(x) (i.e. "magnitude") * v -- Cast from real to integer (vector) * 2 -- Cast from real or logic (vector) to bool (vector) * r -- Cast from integer (vector) to real * i -- post-increment * I -- pre-increment * d -- post-decrement * D -- pre-decrement */ class NetEUnary : public NetExpr { public: NetEUnary(char op, NetExpr*ex, unsigned wid, bool signed_flag); ~NetEUnary(); char op() const { return op_; } const NetExpr* expr() const { return expr_; } virtual NetEUnary* dup_expr() const; virtual NetExpr* eval_tree(); virtual NetExpr* evaluate_function(const LineInfo&loc, std::map&ctx) const; virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual ivl_variable_type_t expr_type() const; virtual NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; protected: char op_; NetExpr* expr_; private: virtual NetExpr* eval_arguments_(const NetExpr*ex) const; virtual NetExpr* eval_tree_real_(const NetExpr*ex) const; }; class NetEUBits : public NetEUnary { public: NetEUBits(char op, NetExpr*ex, unsigned wid, bool signed_flag); ~NetEUBits(); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetEUBits* dup_expr() const; virtual ivl_variable_type_t expr_type() const; }; class NetEUReduce : public NetEUnary { public: NetEUReduce(char op, NetExpr*ex); ~NetEUReduce(); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetEUReduce* dup_expr() const; virtual ivl_variable_type_t expr_type() const; private: virtual NetEConst* eval_arguments_(const NetExpr*ex) const; virtual NetEConst* eval_tree_real_(const NetExpr*ex) const; }; class NetECast : public NetEUnary { public: NetECast(char op, NetExpr*ex, unsigned wid, bool signed_flag); ~NetECast(); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetECast* dup_expr() const; virtual ivl_variable_type_t expr_type() const; virtual void dump(std::ostream&) const; private: virtual NetExpr* eval_arguments_(const NetExpr*ex) const; }; /* * When a signal shows up in an expression, this type represents * it. From this the expression can get any kind of access to the * structural signal, including arrays. * * The NetESignal may refer to an array, if the word_index is * included. This expression calculates the index of the word in the * array. It may only be nil if the expression refers to the whole * array, and that is legal only in limited situation. */ class NetESignal : public NetExpr { public: explicit NetESignal(NetNet*n); NetESignal(NetNet*n, NetExpr*word_index); ~NetESignal(); perm_string name() const; virtual NetESignal* dup_expr() const; NetNet* synthesize(Design*des, NetScope*scope, NetExpr*root); NexusSet* nex_input(bool rem_out = true, bool always_sens = false, bool nested_func = false) const; NexusSet* nex_input_base(bool rem_out, bool always_sens, bool nested_func, unsigned base, unsigned width) const; const netenum_t*enumeration() const; virtual NetExpr*evaluate_function(const LineInfo&loc, std::map&ctx) const; // This is the expression for selecting an array word, if this // signal refers to an array. const NetExpr* word_index() const; // This is the width of the vector that this signal refers to. unsigned vector_width() const; // Point back to the signal that this expression node references. const NetNet* sig() const; NetNet* sig(); // Declared vector dimensions for the signal. long msi() const; long lsi() const; virtual ivl_variable_type_t expr_type() const; virtual void expr_scan(struct expr_scan_t*) const; virtual void dump(std::ostream&) const; private: NetNet*net_; const netenum_t*enum_type_; // Expression to select a word from the net. NetExpr*word_; }; /* * The Design object keeps a list of work items for processing * elaboration. This is the type of those work items. */ struct elaborator_work_item_t { explicit elaborator_work_item_t(Design*d) : des(d) { } virtual ~elaborator_work_item_t() { } virtual void elaborate_runrun() =0; protected: Design*des; }; /* * This class contains an entire design. It includes processes and a * netlist, and can be passed around from function to function. */ class Design { public: Design(); ~Design(); /* We need to pass the tool delay selection for $sdf_annotate. */ enum delay_sel_t { MIN, TYP, MAX }; void set_delay_sel(delay_sel_t sel); const char* get_delay_sel() const; /* The flags are a generic way of accepting command line parameters/flags and passing them to the processing steps that deal with the design. The compilation driver sets the entire flags map after elaboration is done. Subsequent steps can then use the get_flag() function to get the value of an interesting key. */ void set_flags(const std::map&f) { flags_ = f; } const char* get_flag(const std::string&key) const; NetScope* make_root_scope(perm_string name, NetScope*unit_scope, bool program_block, bool is_interface); NetScope* find_root_scope(); std::list find_root_scopes() const; NetScope* make_package_scope(perm_string name, NetScope*unit_scope, bool is_unit); std::list find_package_scopes() const; /* Attempt to set the precision to the specified value. If the precision is already more precise, the keep the precise setting. This is intended to hold the simulation precision for use throughout the entire design. */ void set_precision(int val); int get_precision() const; /* This function takes a delay value and a scope, and returns the delay value scaled to the precision of the design. */ uint64_t scale_to_precision(uint64_t, const NetScope*)const; /* Look up a scope. If no starting scope is passed, then the path is taken as an absolute scope name. Otherwise, the scope is located starting at the passed scope and working up if needed. */ NetScope* find_scope(const hname_t&path) const; NetScope* find_scope(NetScope*, const hname_t&name, NetScope::TYPE type = NetScope::MODULE) const; NetScope* find_package(perm_string name) const; // Note: Try to remove these versions of find_scope. Avoid // using these in new code, use the above forms (or // symbol_search) instead. NetScope* find_scope(const std::list&path) const; NetScope* find_scope(NetScope*, const std::list&path, NetScope::TYPE type = NetScope::MODULE) const; /* These members help manage elaboration of scopes. When we get to a point in scope elaboration where we want to put off a scope elaboration, an object of scope_elaboration_t is pushed onto the scope_elaborations list. The scope elaborator will go through this list elaborating scopes until the list is empty. */ std::listelaboration_work_list; void run_elaboration_work(void); std::set defparams_later; // PARAMETERS void run_defparams(); void evaluate_parameters(); // Look for defparams that never matched, and print warnings. void residual_defparams(); /* This method locates a signal, starting at a given scope. The name parameter may be partially hierarchical, so this method, unlike the NetScope::find_signal method, handles global name binding. */ NetNet*find_signal(NetScope*scope, pform_name_t path); // Functions NetFuncDef* find_function(NetScope*scope, const pform_name_t&key); // Tasks NetScope* find_task(NetScope*scope, const pform_name_t&name); // NODES void add_node(NetNode*); void del_node(NetNode*); // BRANCHES void add_branch(NetBranch*); // PROCESSES void add_process(NetProcTop*); void add_process(NetAnalogTop*); void delete_process(NetProcTop*); bool check_proc_delay() const; bool check_proc_synth() const; NetNet* find_discipline_reference(ivl_discipline_t dis, NetScope*scope); // Iterate over the design... void dump(std::ostream&) const; void functor(struct functor_t*); void join_islands(void); int emit(struct target_t*) const; // This is incremented by elaboration when an error is // detected. It prevents code being emitted. unsigned errors; private: NetScope* find_scope_(NetScope*, const hname_t&name, NetScope::TYPE type = NetScope::MODULE) const; NetScope* find_scope_(NetScope*, const std::list&path, NetScope::TYPE type = NetScope::MODULE) const; // Keep a tree of scopes. The NetScope class handles the wide // tree and per-hop searches for me. std::listroot_scopes_; // Keep a map of all the elaborated packages. Note that // packages do not nest. std::mappackages_; // List the nodes in the design. NetNode*nodes_; // These are in support of the node functor iterator. NetNode*nodes_functor_cur_; NetNode*nodes_functor_nxt_; // List the branches in the design. NetBranch*branches_; // List the processes in the design. NetProcTop*procs_; NetProcTop*procs_idx_; // List the ANALOG processes in the design. NetAnalogTop*aprocs_; // Map of discipline take to NetNet for the reference node. std::mapdiscipline_references_; // Map the design arguments to values. std::map flags_; int des_precision_; delay_sel_t des_delay_sel_; private: // not implemented Design(const Design&); Design& operator= (const Design&); }; /* ======= */ inline bool operator == (const Link&l, const Link&r) { return l.is_equal(r); } inline bool operator != (const Link&l, const Link&r) { return ! l.is_equal(r); } /* Connect the pins of two nodes together. Either may already be connected to other things, connect is transitive. */ extern void connect(Link&, Link&); /* Return true if l and r are connected. */ inline bool connected(const Link&l, const Link&r) { return l.is_linked(r); } /* Return the number of signals in the nexus. */ extern unsigned count_signals(const Link&pin); /* Find the next link that is an output into the nexus. */ extern Link* find_next_output(Link*lnk); /* Find the signal connected to the given node pin. There should always be exactly one signal. The bidx parameter gets filled with the signal index of the Net, in case it is a vector. */ const NetNet* find_link_signal(const NetObj*net, unsigned pin, unsigned&bidx); inline std::ostream& operator << (std::ostream&o, const NetExpr&exp) { exp.dump(o); return o; } extern std::ostream& operator << (std::ostream&, NetNet::Type); /* * Manipulator to dump a scope complete path to the output. The * manipulator is "scope_path" and works like this: * * out << .... << scope_path(sc) << ... ; */ struct __ScopePathManip { const NetScope*scope; }; inline __ScopePathManip scope_path(const NetScope*scope) { __ScopePathManip tmp; tmp.scope = scope; return tmp; } extern std::ostream& operator << (std::ostream&o, __ScopePathManip); struct __ObjectPathManip { const NetObj*obj; }; inline __ObjectPathManip scope_path(const NetObj*obj) { __ObjectPathManip tmp; tmp.obj = obj; return tmp; } extern std::ostream& operator << (std::ostream&o, __ObjectPathManip); /* * If this link has a nexus_ pointer, then it is the last Link in the * list. next_nlink() returns 0 for the last Link. */ inline Link* Link::next_nlink() { if (nexus_) return 0; else return next_; } inline const Link* Link::next_nlink() const { if (nexus_) return 0; else return next_; } inline NetPins*Link::get_obj() { if (pin_zero_) return node_; Link*tmp = this - pin_; assert(tmp->pin_zero_); return tmp->node_; } inline const NetPins*Link::get_obj() const { if (pin_zero_) return node_; const Link*tmp = this - pin_; assert(tmp->pin_zero_); return tmp->node_; } inline unsigned Link::get_pin() const { if (pin_zero_) return 0; else return pin_; } #undef ENUM_UNSIGNED_INT #endif /* IVL_netlist_H */ iverilog-12_0/netlist.txt000066400000000000000000000325261435245347300156020ustar00rootroot00000000000000/* * Copyright (c) 1998-1999 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. */ Note that the netlist.h header contains detailed descriptions of how things work. This is just an overview. 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. XXXX I do not yet properly deal with cases where elaboration knows for XXXX certain that the bit width does not matter. In this case, I XXXX really should tell the expression node about it so that it can XXXX 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-12_0/netmisc.cc000066400000000000000000001613411435245347300153260ustar00rootroot00000000000000/* * Copyright (c) 2001-2021 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 # include # include "netlist.h" # include "netparray.h" # include "netvector.h" # include "netmisc.h" # include "PExpr.h" # include "pform_types.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; NetNet* sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig) { netvector_t*zero_vec = new netvector_t(sig->data_type(), sig->vector_width()-1, 0); NetNet*zero_net = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, zero_vec); zero_net->set_line(*sig); zero_net->local_flag(true); if (sig->data_type() == IVL_VT_REAL) { verireal zero (val); NetLiteral*zero_obj = new NetLiteral(scope, scope->local_symbol(), zero); zero_obj->set_line(*sig); des->add_node(zero_obj); connect(zero_net->pin(0), zero_obj->pin(0)); } else { verinum zero ((int64_t)val); zero = cast_to_width(zero, sig->vector_width()); zero.has_sign(sig->get_signed()); NetConst*zero_obj = new NetConst(scope, scope->local_symbol(), zero); zero_obj->set_line(*sig); des->add_node(zero_obj); connect(zero_net->pin(0), zero_obj->pin(0)); } NetAddSub*adder = new NetAddSub(scope, scope->local_symbol(), sig->vector_width()); adder->set_line(*sig); des->add_node(adder); adder->attribute(perm_string::literal("LPM_Direction"), verinum("SUB")); connect(zero_net->pin(0), adder->pin_DataA()); connect(adder->pin_DataB(), sig->pin(0)); netvector_t*tmp_vec = new netvector_t(sig->data_type(), sig->vector_width()-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*sig); tmp->local_flag(true); connect(adder->pin_Result(), tmp->pin(0)); return tmp; } NetNet* cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid) { if (src->data_type() == IVL_VT_BOOL) return src; netvector_t*tmp_vec = new netvector_t(IVL_VT_BOOL, wid-1, 0, src->get_signed()); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); tmp->local_flag(true); NetCastInt2*cast = new NetCastInt2(scope, scope->local_symbol(), wid); cast->set_line(*src); des->add_node(cast); connect(cast->pin(0), tmp->pin(0)); connect(cast->pin(1), src->pin(0)); return tmp; } NetNet* cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid) { if (src->data_type() != IVL_VT_REAL) return src; netvector_t*tmp_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); tmp->local_flag(true); NetCastInt4*cast = new NetCastInt4(scope, scope->local_symbol(), wid); cast->set_line(*src); des->add_node(cast); connect(cast->pin(0), tmp->pin(0)); connect(cast->pin(1), src->pin(0)); return tmp; } NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src) { if (src->data_type() == IVL_VT_REAL) return src; netvector_t*tmp_vec = new netvector_t(IVL_VT_REAL); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*src); tmp->local_flag(true); NetCastReal*cast = new NetCastReal(scope, scope->local_symbol(), src->get_signed()); cast->set_line(*src); des->add_node(cast); connect(cast->pin(0), tmp->pin(0)); connect(cast->pin(1), src->pin(0)); return tmp; } NetExpr* cast_to_int2(NetExpr*expr, unsigned width) { // Special case: The expression is already BOOL if (expr->expr_type() == IVL_VT_BOOL) return expr; if (debug_elaborate) cerr << expr->get_fileline() << ": debug: " << "Cast expression to int2, width=" << width << "." << endl; NetECast*cast = new NetECast('2', expr, width, expr->has_sign()); cast->set_line(*expr); return cast; } NetExpr* cast_to_int4(NetExpr*expr, unsigned width) { // Special case: The expression is already LOGIC or BOOL if (expr->expr_type() == IVL_VT_LOGIC || expr->expr_type() == IVL_VT_BOOL) return expr; if (debug_elaborate) cerr << expr->get_fileline() << ": debug: " << "Cast expression to int4, width=" << width << "." << endl; NetECast*cast = new NetECast('v', expr, width, expr->has_sign()); cast->set_line(*expr); return cast; } NetExpr* cast_to_real(NetExpr*expr) { if (expr->expr_type() == IVL_VT_REAL) return expr; if (debug_elaborate) cerr << expr->get_fileline() << ": debug: " << "Cast expression to real." << endl; NetECast*cast = new NetECast('r', expr, 1, true); cast->set_line(*expr); return cast; } /* * Add a signed constant to an existing expression. Generate a new * NetEBAdd node that has the input expression and an expression made * from the constant value. */ static NetExpr* make_add_expr(NetExpr*expr, long val) { if (val == 0) return expr; // If the value to be added is <0, then instead generate a // SUBTRACT node and turn the value positive. char add_op = '+'; if (val < 0) { add_op = '-'; val = -val; } verinum val_v (val, expr->expr_width()); val_v.has_sign(expr->has_sign()); NetEConst*val_c = new NetEConst(val_v); val_c->set_line(*expr); NetEBAdd*res = new NetEBAdd(add_op, expr, val_c, expr->expr_width(), expr->has_sign()); res->set_line(*expr); return res; } static NetExpr* make_add_expr(const LineInfo*loc, NetExpr*expr1, NetExpr*expr2) { bool use_signed = expr1->has_sign() && expr2->has_sign(); unsigned use_wid = expr1->expr_width(); if (expr2->expr_width() > use_wid) use_wid = expr2->expr_width(); expr1 = pad_to_width(expr1, use_wid, *loc); expr2 = pad_to_width(expr2, use_wid, *loc); NetEBAdd*tmp = new NetEBAdd('+', expr1, expr2, use_wid, use_signed); return tmp; } /* * Subtract an existing expression from a signed constant. */ static NetExpr* make_sub_expr(long val, NetExpr*expr) { verinum val_v (val, expr->expr_width()); val_v.has_sign(expr->has_sign()); NetEConst*val_c = new NetEConst(val_v); val_c->set_line(*expr); NetEBAdd*res = new NetEBAdd('-', val_c, expr, expr->expr_width(), expr->has_sign()); res->set_line(*expr); return res; } /* * Subtract a signed constant from an existing expression. */ static NetExpr* make_sub_expr(NetExpr*expr, long val) { verinum val_v (val, expr->expr_width()); val_v.has_sign(expr->has_sign()); NetEConst*val_c = new NetEConst(val_v); val_c->set_line(*expr); NetEBAdd*res = new NetEBAdd('-', expr, val_c, expr->expr_width(), expr->has_sign()); res->set_line(*expr); return res; } /* * Multiply an existing expression by a signed positive number. * This does a lossless multiply, so the arguments will need to be * sized to match the output size. */ static NetExpr* make_mult_expr(NetExpr*expr, unsigned long val) { const unsigned val_wid = ceil(log2((double)val)) ; unsigned use_wid = expr->expr_width() + val_wid; verinum val_v (val, use_wid); val_v.has_sign(expr->has_sign()); NetEConst*val_c = new NetEConst(val_v); val_c->set_line(*expr); // We know by definitions that the expr argument needs to be // padded to be the right argument width for this lossless multiply. expr = pad_to_width(expr, use_wid, *expr); NetEBMult*res = new NetEBMult('*', expr, val_c, use_wid, expr->has_sign()); res->set_line(*expr); return res; } /* * This routine is used to calculate the number of bits needed to * contain the given number. */ static unsigned num_bits(long arg) { unsigned res = 0; /* For a negative value we have room for one extra value, but * we have a signed result so we need an extra bit for this. */ if (arg < 0) { arg = -arg - 1; res += 1; } /* Calculate the number of bits needed here. */ while (arg) { res += 1; arg >>= 1; } return res; } /* * This routine generates the normalization expression needed for a variable * bit select or a variable base expression for an indexed part * select. This function doesn't actually look at the variable * dimensions, it just does the final calculation using msb/lsb of the * last slice, and the off of the slice in the variable. */ NetExpr *normalize_variable_base(NetExpr *base, long msb, long lsb, unsigned long wid, bool is_up, long soff) { long offset = lsb; if (msb < lsb) { /* Correct the offset if needed. */ if (is_up) offset -= wid - 1; /* Calculate the space needed for the offset. */ unsigned min_wid = num_bits(offset); if (num_bits(soff) > min_wid) min_wid = num_bits(soff); /* We need enough space for the larger of the offset or the * base expression. */ if (min_wid < base->expr_width()) min_wid = base->expr_width(); /* Now that we have the minimum needed width increase it by * one to make room for the normalization calculation. */ min_wid += 2; /* Pad the base expression to the correct width. */ base = pad_to_width(base, min_wid, *base); /* If the base expression is unsigned and either the lsb * is negative or it does not fill the width of the base * expression then we could generate negative normalized * values so cast the expression to signed to get the * math correct. */ if ((lsb < 0 || num_bits(lsb+1) <= base->expr_width()) && ! base->has_sign()) { /* We need this extra select to hide the signed * property from the padding above. It will be * removed automatically during code generation. */ NetESelect *tmp = new NetESelect(base, 0 , min_wid); tmp->set_line(*base); tmp->cast_signed(true); base = tmp; } /* Normalize the expression. */ base = make_sub_expr(offset+soff, base); } else { /* Correct the offset if needed. */ if (!is_up) offset += wid - 1; /* If the offset is zero then just return the base (index) * expression. */ if ((soff-offset) == 0) return base; /* Calculate the space needed for the offset. */ unsigned min_wid = num_bits(-offset); if (num_bits(soff) > min_wid) min_wid = num_bits(soff); /* We need enough space for the larger of the offset or the * base expression. */ if (min_wid < base->expr_width()) min_wid = base->expr_width(); /* Now that we have the minimum needed width increase it by * one to make room for the normalization calculation. */ min_wid += 2; /* Pad the base expression to the correct width. */ base = pad_to_width(base, min_wid, *base); /* If the offset is greater than zero then we need to do * signed math to get the location value correct. */ if (offset > 0 && ! base->has_sign()) { /* We need this extra select to hide the signed * property from the padding above. It will be * removed automatically during code generation. */ NetESelect *tmp = new NetESelect(base, 0 , min_wid); tmp->set_line(*base); tmp->cast_signed(true); base = tmp; } /* Normalize the expression. */ base = make_add_expr(base, soff-offset); } return base; } /* * This method is how indices should work except that the base should * be a vector of expressions that matches the size of the dims list, * so that we can generate an expression based on the entire packed * vector. For now, we assert that there is only one set of dimensions. */ NetExpr *normalize_variable_base(NetExpr *base, const list&dims, unsigned long wid, bool is_up) { ivl_assert(*base, dims.size() == 1); const netrange_t&rng = dims.back(); return normalize_variable_base(base, rng.get_msb(), rng.get_lsb(), wid, is_up); } NetExpr *normalize_variable_bit_base(const list&indices, NetExpr*base, const NetNet*reg) { const vector&packed_dims = reg->packed_dims(); ivl_assert(*base, indices.size()+1 == packed_dims.size()); // Get the canonical offset of the slice within which we are // addressing. We need that address as a slice offset to // calculate the proper complete address const netrange_t&rng = packed_dims.back(); long slice_off = reg->sb_to_idx(indices, rng.get_lsb()); return normalize_variable_base(base, rng.get_msb(), rng.get_lsb(), 1, true, slice_off); } NetExpr *normalize_variable_part_base(const list&indices, NetExpr*base, const NetNet*reg, unsigned long wid, bool is_up) { const vector&packed_dims = reg->packed_dims(); ivl_assert(*base, indices.size()+1 == packed_dims.size()); // Get the canonical offset of the slice within which we are // addressing. We need that address as a slice offset to // calculate the proper complete address const netrange_t&rng = packed_dims.back(); long slice_off = reg->sb_to_idx(indices, rng.get_lsb()); return normalize_variable_base(base, rng.get_msb(), rng.get_lsb(), wid, is_up, slice_off); } NetExpr *normalize_variable_slice_base(const list&indices, NetExpr*base, const NetNet*reg, unsigned long&lwid) { const vector&packed_dims = reg->packed_dims(); ivl_assert(*base, indices.size() < packed_dims.size()); vector::const_iterator pcur = packed_dims.end(); for (size_t idx = indices.size() ; idx < packed_dims.size(); idx += 1) { -- pcur; } long sb = min(pcur->get_lsb(), pcur->get_msb()); long loff; reg->sb_to_slice(indices, sb, loff, lwid); unsigned min_wid = base->expr_width(); if ((sb < 0) && !base->has_sign()) min_wid += 1; if (min_wid < num_bits(pcur->get_lsb())) min_wid = pcur->get_lsb(); if (min_wid < num_bits(pcur->get_msb())) min_wid = pcur->get_msb(); base = pad_to_width(base, min_wid, *base); if ((sb < 0) && !base->has_sign()) { NetESelect *tmp = new NetESelect(base, 0 , min_wid); tmp->set_line(*base); tmp->cast_signed(true); base = tmp; } if (pcur->get_msb() >= pcur->get_lsb()) { if (pcur->get_lsb() != 0) base = make_sub_expr(base, pcur->get_lsb()); base = make_mult_expr(base, lwid); min_wid = base->expr_width(); if (min_wid < num_bits(loff)) min_wid = num_bits(loff); if (loff != 0) min_wid += 1; base = pad_to_width(base, min_wid, *base); base = make_add_expr(base, loff); } else { if (pcur->get_msb() != 0) base = make_sub_expr(base, pcur->get_msb()); base = make_mult_expr(base, lwid); min_wid = base->expr_width(); if (min_wid < num_bits(loff)) min_wid = num_bits(loff); if (loff != 0) min_wid += 1; base = pad_to_width(base, min_wid, *base); base = make_sub_expr(loff, base); } return base; } ostream& operator << (ostream&o, __IndicesManip val) { for (list::const_iterator cur = val.val.begin() ; cur != val.val.end() ; ++cur) { o << "[" << *cur << "]"; } return o; } ostream& operator << (ostream&o, __IndicesManip val) { for (list::const_iterator cur = val.val.begin() ; cur != val.val.end() ; ++cur) { o << "[" << *(*cur) << "]"; } return o; } /* * The src is the input index expression list from the expression, and * the count is the number that are to be elaborated into the indices * list. At the same time, create a indices_const list that contains * the evaluated values for the expression, if they can be evaluated. */ void indices_to_expressions(Design*des, NetScope*scope, // loc is for error messages. const LineInfo*loc, // src is the index list, and count is // the number of items in the list to use. const list&src, unsigned count, // True if the expression MUST be constant. bool need_const, // These are the outputs. indices_flags&flags, list&indices, list&indices_const) { ivl_assert(*loc, count <= src.size()); flags.invalid = false; flags.variable = false; flags.undefined = false; for (list::const_iterator cur = src.begin() ; count > 0 ; ++cur, --count) { ivl_assert(*loc, cur->sel != index_component_t::SEL_NONE); if (cur->sel != index_component_t::SEL_BIT) { cerr << loc->get_fileline() << ": error: " << "Array cannot be indexed by a range." << endl; des->errors += 1; } ivl_assert(*loc, cur->msb); NetExpr*word_index = elab_and_eval(des, scope, cur->msb, -1, need_const); if (word_index == 0) flags.invalid = true; // Track if we detect any non-constant expressions // here. This may allow for a special case. NetEConst*word_const = dynamic_cast (word_index); if (word_const == 0) flags.variable = true; else if (!word_const->value().is_defined()) flags.undefined = true; else if (!flags.variable && !flags.undefined) indices_const.push_back(word_const->value().as_long()); indices.push_back(word_index); } } static void make_strides(const vector&dims, vector&stride) { stride[dims.size()-1] = 1; for (size_t idx = stride.size()-1 ; idx > 0 ; --idx) { long tmp = dims[idx].width(); if (idx < stride.size()) tmp *= stride[idx]; stride[idx-1] = tmp; } } /* * Take in a vector of constant indices and convert them to a single * number that is the canonical address (zero based, 1-d) of the * word. If any of the indices are out of bounds, return nil instead * of an expression. */ static NetExpr* normalize_variable_unpacked(const vector&dims, list&indices) { // Make strides for each index. The stride is the distance (in // words) to the next element in the canonical array. vector stride (dims.size()); make_strides(dims, stride); int64_t canonical_addr = 0; int idx = 0; for (list::const_iterator cur = indices.begin() ; cur != indices.end() ; ++cur, ++idx) { long tmp = *cur; if (dims[idx].get_lsb() <= dims[idx].get_msb()) tmp -= dims[idx].get_lsb(); else tmp -= dims[idx].get_msb(); // Notice of this index is out of range. if (tmp < 0 || tmp >= (long)dims[idx].width()) { return 0; } canonical_addr += tmp * stride[idx]; } NetEConst*canonical_expr = new NetEConst(verinum(canonical_addr)); return canonical_expr; } NetExpr* normalize_variable_unpacked(const NetNet*net, list&indices) { const vector&dims = net->unpacked_dims(); return normalize_variable_unpacked(dims, indices); } NetExpr* normalize_variable_unpacked(const netsarray_t*stype, list&indices) { const vector&dims = stype->static_dimensions(); return normalize_variable_unpacked(dims, indices); } NetExpr* normalize_variable_unpacked(const LineInfo&loc, const vector&dims, list&indices) { // Make strides for each index. The stride is the distance (in // words) to the next element in the canonical array. vector stride (dims.size()); make_strides(dims, stride); NetExpr*canonical_expr = 0; int idx = 0; for (list::const_iterator cur = indices.begin() ; cur != indices.end() ; ++cur, ++idx) { NetExpr*tmp = *cur; // If the expression elaboration generated errors, then // give up. Presumably, the error during expression // elaboration already generated the error message. if (tmp == 0) return 0; int64_t use_base; if (! dims[idx].defined()) use_base = 0; else if (dims[idx].get_lsb() <= dims[idx].get_msb()) use_base = dims[idx].get_lsb(); else use_base = dims[idx].get_msb(); int64_t use_stride = stride[idx]; // Account for that we are doing arithmetic and should // have a proper width to make sure there are no // losses. So calculate a min_wid width. unsigned tmp_wid; unsigned min_wid = tmp->expr_width(); if (use_base != 0 && ((tmp_wid = num_bits(use_base)) >= min_wid)) min_wid = tmp_wid + 1; if ((tmp_wid = num_bits(dims[idx].width()+1)) >= min_wid) min_wid = tmp_wid + 1; if (use_stride != 1) min_wid += num_bits(use_stride); tmp = pad_to_width(tmp, min_wid, loc); // Now generate the math to calculate the canonical address. NetExpr*tmp_scaled = 0; if (NetEConst*tmp_const = dynamic_cast (tmp)) { // Special case: the index is constant, so this // iteration can be replaced with a constant // expression. int64_t val = tmp_const->value().as_long(); val -= use_base; val *= use_stride; // Very special case: the index is zero, so we can // skip this iteration if (val == 0) continue; tmp_scaled = new NetEConst(verinum(val)); } else { tmp_scaled = tmp; if (use_base != 0) tmp_scaled = make_add_expr(tmp_scaled, -use_base); if (use_stride != 1) tmp_scaled = make_mult_expr(tmp_scaled, use_stride); } if (canonical_expr == 0) { canonical_expr = tmp_scaled; } else { bool expr_has_sign = canonical_expr->has_sign() && tmp_scaled->has_sign(); canonical_expr = new NetEBAdd('+', canonical_expr, tmp_scaled, canonical_expr->expr_width()+1, expr_has_sign); } } // If we don't have an expression at this point, all the indices were // constant zero. But this variant of normalize_variable_unpacked() // is only used when at least one index is not a constant. ivl_assert(loc, canonical_expr); return canonical_expr; } NetExpr* normalize_variable_unpacked(const NetNet*net, list&indices) { const vector&dims = net->unpacked_dims(); return normalize_variable_unpacked(*net, dims, indices); } NetExpr* normalize_variable_unpacked(const LineInfo&loc, const netsarray_t*stype, list&indices) { const vector&dims = stype->static_dimensions(); return normalize_variable_unpacked(loc, dims, indices); } NetExpr* make_canonical_index(Design*des, NetScope*scope, const LineInfo*loc, const std::list&src, const netsarray_t*stype, bool need_const) { NetExpr*canon_index = 0; list indices_const; list indices_expr; indices_flags flags; indices_to_expressions(des, scope, loc, src, src.size(), need_const, flags, indices_expr, indices_const); if (flags.undefined) { cerr << loc->get_fileline() << ": warning: " << "ignoring undefined value array access." << endl; } else if (flags.variable) { canon_index = normalize_variable_unpacked(*loc, stype, indices_expr); } else { canon_index = normalize_variable_unpacked(stype, indices_const); } return canon_index; } NetEConst* make_const_x(unsigned long wid) { verinum xxx (verinum::Vx, wid); NetEConst*resx = new NetEConst(xxx); return resx; } NetEConst* make_const_0(unsigned long wid) { verinum xxx (verinum::V0, wid); NetEConst*resx = new NetEConst(xxx); return resx; } NetEConst* make_const_val(unsigned long value) { verinum tmp (value, integer_width); NetEConst*res = new NetEConst(tmp); return res; } NetEConst* make_const_val_s(long value) { verinum tmp (value, integer_width); tmp.has_sign(true); NetEConst*res = new NetEConst(tmp); return res; } NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid) { verinum xxx (verinum::Vx, wid); NetConst*res = new NetConst(scope, scope->local_symbol(), xxx); des->add_node(res); netvector_t*sig_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sig_vec); sig->local_flag(true); connect(sig->pin(0), res->pin(0)); return sig; } NetNet* make_const_z(Design*des, NetScope*scope, unsigned long wid) { verinum xxx (verinum::Vz, wid); NetConst*res = new NetConst(scope, scope->local_symbol(), xxx); des->add_node(res); netvector_t*sig_vec = new netvector_t(IVL_VT_LOGIC, wid-1, 0); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, sig_vec); sig->local_flag(true); connect(sig->pin(0), res->pin(0)); return sig; } NetExpr* condition_reduce(NetExpr*expr) { if (expr->expr_type() == IVL_VT_REAL) { if (NetECReal *tmp = dynamic_cast(expr)) { verinum::V res; if (tmp->value().as_double() == 0.0) res = verinum::V0; else res = verinum::V1; verinum vres (res, 1, true); NetExpr *rtn = new NetEConst(vres); rtn->set_line(*expr); delete expr; return rtn; } NetExpr *rtn = new NetEBComp('n', expr, new NetECReal(verireal(0.0))); rtn->set_line(*expr); return rtn; } if (expr->expr_width() == 1) return expr; verinum zero (verinum::V0, expr->expr_width()); zero.has_sign(expr->has_sign()); NetEConst*ezero = new NetEConst(zero); ezero->set_line(*expr); NetEBComp*cmp = new NetEBComp('n', expr, ezero); cmp->set_line(*expr); cmp->cast_signed(false); return cmp; } NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, int context_width, bool need_const, bool annotatable, ivl_variable_type_t cast_type, bool force_unsigned) { PExpr::width_mode_t mode = PExpr::SIZED; if ((context_width == -2) && !gn_strict_expr_width_flag) mode = PExpr::EXPAND; pe->test_width(des, scope, mode); if (pe->expr_type() == IVL_VT_CLASS) { cerr << pe->get_fileline() << ": Error: " << "Class/null r-value not allowed in this context." << endl; des->errors += 1; return 0; } // Get the final expression width. If the expression is unsized, // this may be different from the value returned by test_width(). unsigned expr_width = pe->expr_width(); // If context_width is positive, this is the RHS of an assignment, // so the LHS width must also be included in the width calculation. unsigned pos_context_width = context_width > 0 ? context_width : 0; if ((pe->expr_type() != IVL_VT_REAL) && (expr_width < pos_context_width)) expr_width = pos_context_width; // If this is the RHS of a compressed assignment, the LHS also // affects the expression type (signed/unsigned). if (force_unsigned) pe->cast_signed(false); if (debug_elaborate) { cerr << pe->get_fileline() << ": elab_and_eval: test_width of " << *pe << endl; cerr << pe->get_fileline() << ": : " << "returns type=" << pe->expr_type() << ", context_width=" << context_width << ", signed=" << pe->has_sign() << ", expr_width=" << expr_width << ", mode=" << PExpr::width_mode_name(mode) << endl; cerr << pe->get_fileline() << ": : " << "cast_type=" << cast_type << endl; } // If we can get the same result using a smaller expression // width, do so. unsigned min_width = pe->min_width(); if ((min_width != UINT_MAX) && (pe->expr_type() != IVL_VT_REAL) && (pos_context_width > 0) && (expr_width > pos_context_width)) { expr_width = max(min_width, pos_context_width); if (debug_elaborate) { cerr << pe->get_fileline() << ": : " << "pruned to width=" << expr_width << endl; } } if ((mode >= PExpr::LOSSLESS) && (expr_width > width_cap) && (expr_width > pos_context_width)) { cerr << pe->get_fileline() << ": warning: excessive unsized " << "expression width detected." << endl; cerr << pe->get_fileline() << ": : The expression width " << "is capped at " << width_cap << " bits." << endl; expr_width = width_cap; } unsigned flags = PExpr::NO_FLAGS; if (need_const) flags |= PExpr::NEED_CONST; if (annotatable) flags |= PExpr::ANNOTATABLE; if (debug_elaborate) { cerr << pe->get_fileline() << ": elab_and_eval: " << "Calculated width is " << expr_width << "." << endl; } NetExpr*tmp = pe->elaborate_expr(des, scope, expr_width, flags); if (tmp == 0) return 0; if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != tmp->expr_type())) { switch (tmp->expr_type()) { case IVL_VT_BOOL: case IVL_VT_LOGIC: case IVL_VT_REAL: break; default: cerr << tmp->get_fileline() << ": error: " "The expression '" << *pe << "' cannot be implicitly " "cast to the target type." << endl; des->errors += 1; delete tmp; return 0; } switch (cast_type) { case IVL_VT_REAL: tmp = cast_to_real(tmp); break; case IVL_VT_BOOL: tmp = cast_to_int2(tmp, pos_context_width); break; case IVL_VT_LOGIC: tmp = cast_to_int4(tmp, pos_context_width); break; default: break; } } eval_expr(tmp, context_width); if (NetEConst*ce = dynamic_cast(tmp)) { if ((mode >= PExpr::LOSSLESS) && (context_width < 0)) ce->trim(); } return tmp; } NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, ivl_type_t lv_net_type, bool need_const) { if (debug_elaborate) { cerr << pe->get_fileline() << ": " << __func__ << ": " << "pe=" << *pe << ", lv_net_type=" << *lv_net_type << endl; } // Elaborate the expression using the more general // elaborate_expr method. unsigned flags = PExpr::NO_FLAGS; if (need_const) flags |= PExpr::NEED_CONST; NetExpr*tmp = pe->elaborate_expr(des, scope, lv_net_type, flags); if (tmp == 0) return 0; ivl_variable_type_t cast_type = ivl_type_base(lv_net_type); ivl_variable_type_t expr_type = tmp->expr_type(); if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != expr_type)) { // Catch some special cases. switch (cast_type) { case IVL_VT_DARRAY: case IVL_VT_QUEUE: if ((expr_type == IVL_VT_DARRAY) || (expr_type == IVL_VT_QUEUE)) return tmp; // This is needed to handle the special case of `'{}` which // gets elaborated to NetENull. if (dynamic_cast(pe)) return tmp; // fall through case IVL_VT_STRING: if (dynamic_cast(pe)) return tmp; break; case IVL_VT_CLASS: if (dynamic_cast(pe)) return tmp; break; default: break; } cerr << tmp->get_fileline() << ": error: " "The expression '" << *pe << "' cannot be implicitly " "cast to the target type." << endl; des->errors += 1; delete tmp; return 0; } return tmp; } NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name, unsigned arg_idx, PExpr*pe, bool need_const) { PExpr::width_mode_t mode = PExpr::SIZED; pe->test_width(des, scope, mode); if (debug_elaborate) { cerr << pe->get_fileline() << ": " << __func__ << ": " << "test_width of " << name << " argument " << (arg_idx+1) << " " << *pe << endl; cerr << pe->get_fileline() << ": " << "returns type=" << pe->expr_type() << ", width=" << pe->expr_width() << ", signed=" << pe->has_sign() << ", mode=" << PExpr::width_mode_name(mode) << endl; } unsigned flags = PExpr::SYS_TASK_ARG; if (need_const) flags |= PExpr::NEED_CONST; NetExpr*tmp = pe->elaborate_expr(des, scope, pe->expr_width(), flags); if (tmp == 0) return 0; eval_expr(tmp, -1); if (NetEConst*ce = dynamic_cast(tmp)) { // For lossless/unsized constant expressions, we can now // determine the exact width required to hold the result. // But leave literal numbers exactly as the user supplied // them. if ((mode >= PExpr::LOSSLESS) && !dynamic_cast(pe) && tmp->expr_width()>32) ce->trim(); } return tmp; } bool evaluate_range(Design*des, NetScope*scope, const LineInfo*li, const pform_range_t&range, long&index_l, long&index_r) { bool dimension_ok = true; // Unsized and queue dimensions should be handled before calling // this function. If we find them here, we are in a context where // they are not allowed. if (range.first == 0) { cerr << li->get_fileline() << ": error: " "An unsized dimension is not allowed here." << endl; dimension_ok = false; des->errors += 1; } else if (dynamic_cast(range.first)) { cerr << li->get_fileline() << ": error: " "A queue dimension is not allowed here." << endl; dimension_ok = false; des->errors += 1; } else { NetExpr*texpr = elab_and_eval(des, scope, range.first, -1, true); if (! eval_as_long(index_l, texpr)) { cerr << range.first->get_fileline() << ": error: " "Dimensions must be constant." << endl; cerr << range.first->get_fileline() << " : " << (range.second ? "This MSB" : "This size") << " expression violates the rule: " << *range.first << endl; dimension_ok = false; des->errors += 1; } delete texpr; if (range.second == 0) { // This is a SystemVerilog [size] dimension. The IEEE // standard does not allow this in a packed dimension, // but we do. At least one commercial simulator does too. if (!dimension_ok) { // bail out } else if (index_l > 0) { index_r = index_l - 1; index_l = 0; } else { cerr << range.first->get_fileline() << ": error: " "Dimension size must be greater than zero." << endl; cerr << range.first->get_fileline() << " : " "This size expression violates the rule: " << *range.first << endl; dimension_ok = false; des->errors += 1; } } else { texpr = elab_and_eval(des, scope, range.second, -1, true); if (! eval_as_long(index_r, texpr)) { cerr << range.second->get_fileline() << ": error: " "Dimensions must be constant." << endl; cerr << range.second->get_fileline() << " : " "This LSB expression violates the rule: " << *range.second << endl; dimension_ok = false; des->errors += 1; } delete texpr; } } /* Error recovery */ if (!dimension_ok) { index_l = 0; index_r = 0; } return dimension_ok; } bool evaluate_ranges(Design*des, NetScope*scope, const LineInfo*li, vector&llist, const list&rlist) { bool dimensions_ok = true; for (list::const_iterator cur = rlist.begin() ; cur != rlist.end() ; ++cur) { long index_l, index_r; dimensions_ok &= evaluate_range(des, scope, li, *cur, index_l, index_r); llist.push_back(netrange_t(index_l, index_r)); } return dimensions_ok; } void eval_expr(NetExpr*&expr, int context_width) { assert(expr); if (dynamic_cast(expr)) return; NetExpr*tmp = expr->eval_tree(); if (tmp != 0) { tmp->set_line(*expr); delete expr; expr = tmp; } if (context_width <= 0) return; NetEConst *ce = dynamic_cast(expr); if (ce == 0) return; // The expression is a constant, so resize it if needed. if (ce->expr_width() < (unsigned)context_width) { expr = pad_to_width(expr, context_width, *expr); } else if (ce->expr_width() > (unsigned)context_width) { verinum value(ce->value(), context_width); ce = new NetEConst(value); ce->set_line(*expr); delete expr; expr = ce; } } bool eval_as_long(long&value, const NetExpr*expr) { if (const NetEConst*tmp = dynamic_cast(expr) ) { value = tmp->value().as_long(); return true; } if (const NetECReal*rtmp = dynamic_cast(expr)) { value = rtmp->value().as_long(); return true; } return false; } bool eval_as_double(double&value, NetExpr*expr) { if (NetEConst*tmp = dynamic_cast(expr) ) { value = tmp->value().as_double(); return true; } if (NetECReal*rtmp = dynamic_cast(expr)) { value = rtmp->value().as_double(); return true; } return false; } /* * At the parser level, a name component is a name with a collection * of expressions. For example foo[N] is the name "foo" and the index * expression "N". This function takes as input the name component and * returns the path component name. It will evaluate the index * expression if it is present. */ hname_t eval_path_component(Design*des, NetScope*scope, const name_component_t&comp, bool&error_flag) { // No index expression, so the path component is an undecorated // name, for example "foo". if (comp.index.empty()) return hname_t(comp.name); vector index_values; for (list::const_iterator cur = comp.index.begin() ; cur != comp.index.end() ; ++cur) { const index_component_t&index = *cur; if (index.sel != index_component_t::SEL_BIT) { cerr << index.msb->get_fileline() << ": error: " << "Part select is not valid for this kind of object." << endl; des->errors += 1; return hname_t(comp.name, 0); } // The parser will assure that path components will have only // bit select index expressions. For example, "foo[n]" is OK, // but "foo[n:m]" is not. assert(index.sel == index_component_t::SEL_BIT); // Evaluate the bit select to get a number. NetExpr*tmp = elab_and_eval(des, scope, index.msb, -1); ivl_assert(*index.msb, tmp); if (NetEConst*ctmp = dynamic_cast(tmp)) { index_values.push_back(ctmp->value().as_long()); delete ctmp; continue; } #if 1 // Darn, the expression doesn't evaluate to a constant. That's // an error to be reported. And make up a fake index value to // return to the caller. cerr << index.msb->get_fileline() << ": error: " << "Scope index expression is not constant: " << *index.msb << endl; des->errors += 1; #endif error_flag = true; delete tmp; } return hname_t(comp.name, index_values); } std::list eval_scope_path(Design*des, NetScope*scope, const pform_name_t&path) { bool path_error_flag = false; list res; typedef pform_name_t::const_iterator pform_path_it; for (pform_path_it cur = path.begin() ; cur != path.end(); ++ cur ) { const name_component_t&comp = *cur; res.push_back( eval_path_component(des,scope,comp,path_error_flag) ); } #if 0 if (path_error_flag) { cerr << "XXXXX: Errors evaluating path " << path << endl; } #endif return res; } /* * Human readable version of op. Used in elaboration error messages. */ const char *human_readable_op(const char op, bool unary) { const char *type; switch (op) { case '~': type = "~"; break; // Negation case '+': type = "+"; break; case '-': type = "-"; break; case '*': type = "*"; break; case '/': type = "/"; break; case '%': type = "%"; break; case '<': type = "<"; break; case '>': type = ">"; break; case 'L': type = "<="; break; case 'G': type = ">="; break; case '^': type = "^"; break; // XOR case 'X': type = "~^"; break; // XNOR case '&': type = "&"; break; // Bitwise AND case 'A': type = "~&"; break; // NAND (~&) case '|': type = "|"; break; // Bitwise OR case 'O': type = "~|"; break; // NOR case '!': type = "!"; break; // Logical NOT case 'a': type = "&&"; break; // Logical AND case 'o': type = "||"; break; // Logical OR case 'q': type = "->"; break; // Logical implication case 'Q': type = "<->"; break; // Logical equivalence case 'e': type = "=="; break; case 'n': type = "!="; break; case 'E': type = "==="; break; // Case equality case 'N': if (unary) type = "~|"; // NOR else type = "!=="; // Case inequality break; case 'w': type = "==?"; break; // Wild equality case 'W': type = "!=?"; break; // Wild inequality case 'l': type = "<<(<)"; break; // Left shifts case 'r': type = ">>"; break; // Logical right shift case 'R': type = ">>>"; break; // Arithmetic right shift case 'p': type = "**"; break; // Power case 'i': case 'I': type = "++"; break; /* increment */ case 'd': case 'D': type = "--"; break; /* decrement */ default: type = "???"; assert(0); } return type; } const_bool const_logical(const NetExpr*expr) { switch (expr->expr_type()) { case IVL_VT_REAL: { const NetECReal*val = dynamic_cast (expr); if (val == 0) return C_NON; if (val->value().as_double() == 0.0) return C_0; else return C_1; } case IVL_VT_BOOL: case IVL_VT_LOGIC: { const NetEConst*val = dynamic_cast (expr); if (val == 0) return C_NON; verinum cval = val->value(); const_bool res = C_0; for (unsigned idx = 0; idx < cval.len(); idx += 1) { switch (cval.get(idx)) { case verinum::V1: return C_1; break; case verinum::V0: break; default: if (res == C_0) res = C_X; break; } } return res; } default: break; } return C_NON; } uint64_t get_scaled_time_from_real(Design*des, NetScope*scope, NetECReal*val) { verireal fn = val->value(); int shift = scope->time_unit() - scope->time_precision(); assert(shift >= 0); int64_t delay = fn.as_long64(shift); shift = scope->time_precision() - des->get_precision(); assert(shift >= 0); for (int lp = 0; lp < shift; lp += 1) delay *= 10; return delay; } /* * This function looks at the NetNet signal to see if there are any * NetPartSelect::PV nodes driving this signal. If so, See if they can * be collapsed into a single concatenation. */ void collapse_partselect_pv_to_concat(Design*des, NetNet*sig) { NetScope*scope = sig->scope(); vector ps_map (sig->vector_width()); Nexus*nex = sig->pin(0).nexus(); for (Link*cur = nex->first_nlink(); cur ; cur = cur->next_nlink()) { NetPins*obj; unsigned obj_pin; cur->cur_link(obj, obj_pin); // Look for NetPartSelect devices, where this signal is // connected to pin 1 of a NetPartSelect::PV. NetPartSelect*ps_obj = dynamic_cast (obj); if (ps_obj == 0) continue; if (ps_obj->dir() != NetPartSelect::PV) continue; if (obj_pin != 1) continue; // Don't support overrun selects here. if (ps_obj->base()+ps_obj->width() > ps_map.size()) continue; ivl_assert(*ps_obj, ps_obj->base() < ps_map.size()); ps_map[ps_obj->base()] = ps_obj; } // Check the collected NetPartSelect::PV objects to see if // they cover the vector. unsigned idx = 0; unsigned device_count = 0; while (idx < ps_map.size()) { NetPartSelect*ps_obj = ps_map[idx]; if (ps_obj == 0) return; idx += ps_obj->width(); device_count += 1; } ivl_assert(*sig, idx == ps_map.size()); /* The vlog95 and possibly other code generators do not want * to have a group of part selects turned into a transparent * concatenation. */ if (disable_concatz_generation) { // HERE: If the part selects have matching strengths then we can use // a normal concat with a buf-Z after if the strengths are not // both strong. We would ideally delete any buf-Z driving the // concat, but that is not required for the vlog95 generator. return; } // Ah HAH! The NetPartSelect::PV objects exactly cover the // target signal. We can replace all of them with a single // concatenation. if (debug_elaborate) { cerr << sig->get_fileline() << ": debug: " << "Collapse " << device_count << " NetPartSelect::PV devices into a concatenation." << endl; } NetConcat*cat = new NetConcat(scope, scope->local_symbol(), ps_map.size(), device_count, true); des->add_node(cat); cat->set_line(*sig); connect(cat->pin(0), sig->pin(0)); idx = 0; unsigned concat_position = 1; while (idx < ps_map.size()) { assert(ps_map[idx]); NetPartSelect*ps_obj = ps_map[idx]; connect(cat->pin(concat_position), ps_obj->pin(0)); concat_position += 1; idx += ps_obj->width(); delete ps_obj; } } /* * Evaluate the prefix indices. All but the final index in a * chain of indices must be a single value and must evaluate * to constants at compile time. For example: * [x] - OK * [1][2][x] - OK * [1][x:y] - OK * [2:0][x] - BAD * [y][x] - BAD * Leave the last index for special handling. */ bool evaluate_index_prefix(Design*des, NetScope*scope, list&prefix_indices, const list&indices) { list::const_iterator icur = indices.begin(); for (size_t idx = 0 ; (idx+1) < indices.size() ; idx += 1, ++icur) { assert(icur != indices.end()); if (icur->sel != index_component_t::SEL_BIT) { cerr << icur->msb->get_fileline() << ": error: " "All but the final index in a chain of indices must be " "a single value, not a range." << endl; des->errors += 1; return false; } NetExpr*texpr = elab_and_eval(des, scope, icur->msb, -1, true); long tmp; if (texpr == 0 || !eval_as_long(tmp, texpr)) { cerr << icur->msb->get_fileline() << ": error: " "Array index expressions must be constant here." << endl; des->errors += 1; return false; } prefix_indices.push_back(tmp); delete texpr; } return true; } /* * Evaluate the indices. The chain of indices are applied to the * packed indices of a NetNet to generate a canonical expression to * replace the exprs. */ NetExpr*collapse_array_exprs(Design*des, NetScope*scope, const LineInfo*loc, NetNet*net, const list&indices) { // First elaborate all the expressions as far as possible. list exprs; list exprs_const; indices_flags flags; indices_to_expressions(des, scope, loc, indices, net->packed_dimensions(), false, flags, exprs, exprs_const); ivl_assert(*loc, exprs.size() == net->packed_dimensions()); // Special Case: there is only 1 packed dimension, so the // single expression should already be naturally canonical. if (net->slice_width(1) == 1) { return *exprs.begin(); } const std::vector&pdims = net->packed_dims(); std::vector::const_iterator pcur = pdims.begin(); list::iterator ecur = exprs.begin(); NetExpr* base = 0; for (size_t idx = 0 ; idx < net->packed_dimensions() ; idx += 1, ++pcur, ++ecur) { unsigned cur_slice_width = net->slice_width(idx+1); long lsb = pcur->get_lsb(); long msb = pcur->get_msb(); // This normalizes the expression of this index based on // the msb/lsb values. NetExpr*tmp = normalize_variable_base(*ecur, msb, lsb, cur_slice_width, msb > lsb); // If this slice has width, then scale it. if (net->slice_width(idx+1) != 1) { unsigned min_wid = tmp->expr_width(); if (num_bits(cur_slice_width) >= min_wid) { min_wid = num_bits(cur_slice_width)+1; tmp = pad_to_width(tmp, min_wid, *loc); } tmp = make_mult_expr(tmp, cur_slice_width); } // Now add it to the position we've accumulated so far. if (base) { base = make_add_expr(loc, base, tmp); } else { base = tmp; } } return base; } /* * Given a list of indices, treat them as packed indices and convert * them to an expression that normalizes the list to a single index * expression over a canonical equivalent 1-dimensional array. */ NetExpr*collapse_array_indices(Design*des, NetScope*scope, NetNet*net, const list&indices) { listprefix_indices; bool rc = evaluate_index_prefix(des, scope, prefix_indices, indices); assert(rc); const index_component_t&back_index = indices.back(); assert(back_index.sel == index_component_t::SEL_BIT); assert(back_index.msb && !back_index.lsb); NetExpr*base = elab_and_eval(des, scope, back_index.msb, -1, true); NetExpr*res = normalize_variable_bit_base(prefix_indices, base, net); eval_expr(res, -1); return res; } void assign_unpacked_with_bufz(Design*des, NetScope*scope, const LineInfo*loc, NetNet*lval, NetNet*rval) { ivl_assert(*loc, lval->pin_count()==rval->pin_count()); for (unsigned idx = 0 ; idx < lval->pin_count() ; idx += 1) { NetBUFZ*driver = new NetBUFZ(scope, scope->local_symbol(), lval->vector_width(), false); driver->set_line(*loc); des->add_node(driver); connect(lval->pin(idx), driver->pin(0)); connect(driver->pin(1), rval->pin(idx)); } } /* * synthesis sometimes needs to unpack assignment to a part * select. That looks like this: * * foo[N] <= ; * * The NetAssignBase::synth_async() method will turn that into a * netlist like this: * * NetAssignBase(PV) --> base()== * (0) (1) * | | * v v * foo * * This search will return a pointer to the NetAssignBase(PV) object, * but only if it matches this pattern. */ NetPartSelect* detect_partselect_lval(Link&pin) { NetPartSelect*found_ps = 0; Nexus*nex = pin.nexus(); for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { NetPins*obj; unsigned obj_pin; cur->cur_link(obj, obj_pin); // Skip NexusSet objects. if (obj == 0) continue; // NetNet pins have no effect on this search. if (dynamic_cast (obj)) continue; if (NetPartSelect*ps = dynamic_cast (obj)) { // If this is the input side of a NetPartSelect, skip. if (ps->pin(obj_pin).get_dir()==Link::INPUT) continue; // Oops, driven by the wrong size of a // NetPartSelect, so this is not going to work out. if (ps->dir()==NetPartSelect::VP) return 0; // So now we know this is a NetPartSelect::PV. It // is a candidate for our part-select assign. If // we already have a candidate, then give up. if (found_ps) return 0; // This is our candidate. Carry on. found_ps = ps; continue; } // If this is a driver to the Nexus that is not a // NetPartSelect device. This cannot happen to // part selected lval nets, so quit now. if (obj->pin(obj_pin).get_dir() == Link::OUTPUT) return 0; } return found_ps; } const netclass_t* find_class_containing_scope(const LineInfo&loc, const NetScope*scope) { while (scope && scope->type() != NetScope::CLASS) scope = scope->parent(); if (scope == 0) return 0; const netclass_t*found_in = scope->class_def(); ivl_assert(loc, found_in); return found_in; } /* * Find the scope that contains this scope, that is the method for a * class scope. Look for the scope whose PARENT is the scope for a * class. This is going to be a method. */ NetScope* find_method_containing_scope(const LineInfo&, NetScope*scope) { NetScope*up = scope->parent(); while (up && up->type() != NetScope::CLASS) { scope = up; up = up->parent(); } if (up == 0) return 0; // Should I check if this scope is a TASK or FUNC? return scope; } /* * Print a warning if we find a mixture of default and explicit timescale * based delays in the design, since this is likely an error. */ void check_for_inconsistent_delays(NetScope*scope) { static bool used_implicit_timescale = false; static bool used_explicit_timescale = false; static bool display_ts_dly_warning = true; if (scope->time_from_timescale()) used_explicit_timescale = true; else used_implicit_timescale = true; if (display_ts_dly_warning && used_explicit_timescale && used_implicit_timescale) { if (gn_system_verilog()) { cerr << "warning: Found both default and explicit " "timescale based delays. Use" << endl; cerr << " : -Wtimescale to find the design " "element(s) with no explicit" << endl; cerr << " : timescale." << endl; } else { cerr << "warning: Found both default and " "`timescale based delays. Use" << endl; cerr << " : -Wtimescale to find the " "module(s) with no `timescale." << endl; } display_ts_dly_warning = false; } } /* * Calculate the bit vector range for a parameter, from the type of the * parameter. This is expecting that the type is a vector type. The parameter * is presumably declared something like this: * * parameter [4:1] foo = ; * * In this case, the par_type is a netvector with a single dimension. The * par_msv gets 4, and par_lsv get 1. The caller uses these values to * interpret things like bit selects. */ bool calculate_param_range(const LineInfo&line, ivl_type_t par_type, long&par_msv, long&par_lsv, long length) { const netvector_t*vector_type = dynamic_cast (par_type); if (vector_type == 0) { // If the parameter doesn't have an explicit range, then // just return range values of [length-1:0]. par_msv = length-1; par_lsv = 0; return true; } ivl_assert(line, vector_type->packed()); const std::vector& packed_dims = vector_type->packed_dims(); // This is a netvector_t with 0 dimensions, then the parameter was // declared with a statement like this: // // parameter signed foo = ; // // The netvector_t is just here to carry the signed-ness, which we don't // even need here. So act like the type is defined by the r-value // length. if (packed_dims.size() == 0) { par_msv = length-1; par_lsv = 0; return true; } ivl_assert(line, packed_dims.size() == 1); netrange_t use_range = packed_dims[0]; par_msv = use_range.get_msb(); par_lsv = use_range.get_lsb(); return true; } iverilog-12_0/netmisc.h000066400000000000000000000463251435245347300151740ustar00rootroot00000000000000#ifndef IVL_netmisc_H #define IVL_netmisc_H /* * Copyright (c) 1999-2021 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 "netlist.h" class netsarray_t; /* * Search for a hierarchical name. The input path is one or more name * components (name_component_t) which describe a path to the object. The * simplest case is the path is a single name_component_t. This is the most * usual case. More complex cases might include a string of name components * that end in an item or scope, like this: * * a.b[1].c * * In this case, the "path input would include a.b.c, with index expressions * on name_component_t for "b". In this case, usually "c" is the found item * and "a" and "b" are scopes that lead up to the item. * * The search will stop when it finds a component in the path that is an * object of some sort (other then a scope. So for example, if a.b is an * array, then the search for a.b[1].c will stop at a.b, leave a.b[1] in * path_head, and "c" in path_tail. It is up to the caller to then note that * "c" must be a method of some sort. */ struct symbol_search_results { inline symbol_search_results() { scope = 0; net = 0; cls_val = 0; par_val = 0; type = 0; eve = 0; } inline bool is_scope() const { if (net) return false; if (eve) return false; if (cls_val) return false; if (par_val) return false; if (scope) return true; return false; } inline bool is_found() const { if (net) return true; if (eve) return true; if (cls_val) return true; if (par_val) return true; if (scope) return true; return false; } // Scope where symbol was located. This is set in all cases, // assuming the search succeeded. NetScope*scope; // If this was a net, the signal itself. NetNet*net; // For a class property we only have type information. ivl_type_t cls_val; // If this was a parameter, the value expression and the // optional value dimensions. const NetExpr*par_val; ivl_type_t type; // If this is a named event, ... NetEvent*eve; // Store bread crumbs of the search here. The path_tail is the parts // of the original path that were not found, or are after an object // (and so are probably members or methods). pform_name_t path_tail; // The path_head is the parts of the original path that were found. // The last item in path_head is the final name (possibly before the // path_tail items) that identifies the object. This name may contain // index expressions. If the search result is a scope, then this name // is also the name of the scope identified. pform_name_t path_head; }; /* * Test the search results and return true if this represents a function * return value. That will be the case if the object is a net, the scope * containing the object is a FUNCtion, and the containing scope and the * object have the same name. */ static inline bool test_function_return_value(const symbol_search_results&search_results) { if (!search_results.net) return false; if (search_results.scope->type()!=NetScope::FUNC) return false; if (search_results.net->name() != search_results.scope->basename()) return false; return true; } extern bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, pform_name_t path, struct symbol_search_results*res, NetScope*start_scope = 0); /* * Search for a symbol using the "start" scope as the starting * point. If the path includes a scope part, then locate the * scope first. * * The return value is the scope where the symbol was found. * If the symbol was not found, return 0. The output arguments * get 0 except for the pointer to the object that represents * the located symbol. * * The ex1 and ex2 output arguments are extended results. If the * symbol is a parameter (par!=0) then ex1 is the msb expression and * ex2 is the lsb expression for the range. If there is no range, then * these values are set to 0. */ extern NetScope* symbol_search(const LineInfo*li, Design*des, NetScope*start, const pform_name_t&path, NetNet*&net, /* net/reg */ const NetExpr*&par,/* parameter/expr */ NetEvent*&eve, /* named event */ ivl_type_t&par_type, ivl_type_t&cls_val); inline NetScope* symbol_search(const LineInfo*li, Design*des, NetScope*start, const pform_name_t&path, NetNet*&net, /* net/reg */ const NetExpr*&par,/* parameter/expr */ NetEvent*&eve /* named event */) { ivl_type_t par_type; ivl_type_t cls_val; return symbol_search(li, des, start, path, net, par, eve, par_type, cls_val); } /* * This function transforms an expression by either zero or sign extending * the high bits until the expression has the desired width. This may mean * not transforming the expression at all, if it is already wide enough. * The extension method and the returned expression type is determined by * signed_flag. */ extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag, const LineInfo&info, ivl_type_t use_type = 0); /* * This version determines the extension method from the base expression type. */ inline NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info, ivl_type_t use_type = 0) { return pad_to_width(expr, wid, expr->has_sign(), info, use_type); } /* * This function transforms an expression by either zero or sign extending * or discarding the high bits until the expression has the desired width. * This may mean not transforming the expression at all, if it is already * the correct width. The extension method (if needed) and the returned * expression type is determined by signed_flag. */ extern NetExpr*cast_to_width(NetExpr*expr, unsigned wid, bool signed_flag, const LineInfo&info); extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w, const LineInfo&info); extern NetNet*pad_to_width_signed(Design*des, NetNet*n, unsigned w, const LineInfo&info); /* * Generate the nodes necessary to cast an expression (a net) to a * real value. */ extern NetNet*cast_to_int4(Design*des, NetScope*scope, NetNet*src, unsigned wid); extern NetNet*cast_to_int2(Design*des, NetScope*scope, NetNet*src, unsigned wid); extern NetNet*cast_to_real(Design*des, NetScope*scope, NetNet*src); extern NetExpr*cast_to_int4(NetExpr*expr, unsigned width); extern NetExpr*cast_to_int2(NetExpr*expr, unsigned width); extern NetExpr*cast_to_real(NetExpr*expr); /* * Take the input expression and return a variation that assures that * the expression is 1-bit wide and logical. This reflects the needs * of conditions i.e. for "if" statements or logical operators. */ extern NetExpr*condition_reduce(NetExpr*expr); /* * This function transforms an expression by cropping the high bits * off with a part select. The result has the width w passed in. This * function does not pad, use pad_to_width if padding is desired. */ extern NetNet*crop_to_width(Design*des, NetNet*n, unsigned w); extern bool calculate_part(const LineInfo*li, Design*des, NetScope*scope, const index_component_t&index, long&off, unsigned long&wid); /* * These functions generate an equation to normalize an expression using * the provided vector/array information. */ extern NetExpr*normalize_variable_base(NetExpr *base, long msb, long lsb, unsigned long wid, bool is_up, long slice_off =0); extern NetExpr*normalize_variable_base(NetExpr *base, const std::list&dims, unsigned long wid, bool is_up); /* * Calculate a canonicalizing expression for a bit select, when the * base expression is the last index of an otherwise complete bit * select. For example: * reg [3:0][7:0] foo; * ... foo[1][x] ... * base is (x) and the generated expression will be (x+8). */ extern NetExpr*normalize_variable_bit_base(const std::list&indices, NetExpr *base, const NetNet*reg); /* * This is similar to normalize_variable_bit_base, but the tail index * it a base and width, instead of a bit. This is used for handling * indexed part selects: * reg [3:0][7:0] foo; * ... foo[1][x +: 2] * base is (x), wid input is (2), and is_up is (true). The output * expression is (x+8). */ extern NetExpr *normalize_variable_part_base(const std::list&indices, NetExpr*base, const NetNet*reg, unsigned long wid, bool is_up); /* * Calculate a canonicalizing expression for a slice select. The * indices array is less than needed to fully address a bit, so the * result is a slice of the packed array. The return value is an * expression that gets to the base of the slice, and (lwid) becomes * the width of the slice, in bits. For example: * reg [4:1][7:0] foo * ...foo[x]... * base is (x) and the generated expression will be (x*8 - 8), with * lwid set to (8). */ extern NetExpr*normalize_variable_slice_base(const std::list&indices, NetExpr *base, const NetNet*reg, unsigned long&lwid); /* * The as_indices() manipulator is a convenient way to emit a list of * index values in the form [<>][<>].... */ template struct __IndicesManip { explicit inline __IndicesManip(const std::list&v) : val(v) { } const std::list&val; }; template inline __IndicesManip as_indices(const std::list&indices) { return __IndicesManip(indices); } extern std::ostream& operator << (std::ostream&o, __IndicesManip); extern std::ostream& operator << (std::ostream&o, __IndicesManip); /* * Given a list of index expressions, generate elaborated expressions * and constant values, if possible. */ struct indices_flags { bool invalid; // at least one index failed elaboration bool variable; // at least one index is a dynamic value bool undefined; // at least one index is an undefined value }; extern void indices_to_expressions(Design*des, NetScope*scope, // loc is for error messages. const LineInfo*loc, // src is the index list, and count is // the number of items in the list to use. const std::list&src, unsigned count, // True if the expression MUST be constant. bool need_const, // These are the outputs. indices_flags&flags, std::list&indices,std::list&indices_const); extern NetExpr*normalize_variable_unpacked(const NetNet*net, std::list&indices); extern NetExpr*normalize_variable_unpacked(const netsarray_t*net, std::list&indices); extern NetExpr*normalize_variable_unpacked(const NetNet*net, std::list&indices); extern NetExpr*normalize_variable_unpacked(const LineInfo&loc, const netsarray_t*net, std::list&indices); extern NetExpr*make_canonical_index(Design*des, NetScope*scope, // loc for error messages const LineInfo*loc, // src is the index list const std::list&src, // This is the reference type const netsarray_t*stype, // True if the expression MUST be constant. bool need_const); /* * This function takes as input a NetNet signal and adds a constant * value to it. If the val is 0, then simply return sig. Otherwise, * return a new NetNet value that is the output of an addition. * * Not currently used. */ #if 0 extern NetNet*add_to_net(Design*des, NetNet*sig, long val); #endif extern NetNet*sub_net_from(Design*des, NetScope*scope, long val, NetNet*sig); /* * Make a NetEConst object that contains only X bits. */ extern NetEConst*make_const_x(unsigned long wid); extern NetEConst*make_const_0(unsigned long wid); extern NetEConst*make_const_val(unsigned long val); extern NetEConst*make_const_val_s(long val); /* * Make A const net */ extern NetNet* make_const_x(Design*des, NetScope*scope, unsigned long wid); extern NetNet* make_const_z(Design*des, NetScope*scope, unsigned long wid); /* * In some cases the lval is accessible as a pointer to the head of * a list of NetAssign_ objects. This function returns the width of * the l-value represented by this list. */ extern unsigned count_lval_width(const class NetAssign_*first); /* * This function elaborates an expression, and tries to evaluate it * right away. If the expression can be evaluated, this returns a * constant expression. If it cannot be evaluated, it returns whatever * it can. If the expression cannot be elaborated, return 0. * * The context_width is the width of the context where the expression is * being elaborated, or -1 if the expression is self-determined, or -2 * if the expression is lossless self-determined (this last option is * treated as standard self-determined if the gn_strict_expr_width flag * is set). * * cast_type allows the expression to be cast to a different type * (before it is evaluated). If cast to a vector type, the vector * width will be set to the context_width. The default value of * IVL_VT_NO_TYPE causes the expression to retain its self-determined * type. */ class PExpr; extern NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, int context_width, bool need_const =false, bool annotatable =false, ivl_variable_type_t cast_type =IVL_VT_NO_TYPE, bool force_unsigned =false); /* * This form of elab_and_eval uses the ivl_type_t to carry type * information instead of the piecemeal form. We should transition to * this form as we reasonably can. */ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*expr, ivl_type_t lv_net_type, bool need_const); /* * This function is a variant of elab_and_eval that elaborates and * evaluates the arguments of a system task. */ extern NetExpr* elab_sys_task_arg(Design*des, NetScope*scope, perm_string name, unsigned arg_idx, PExpr*pe, bool need_const =false); /* * This function elaborates an expression as if it is for the r-value * of an assignment, The lv_type and lv_width are the type and width * of the l-value, and the expr is the expression to elaborate. The * result is the NetExpr elaborated and evaluated. (See elab_expr.cc) * * I would rather that all calls to elaborate_rval_expr use the * lv_net_type argument to express the l-value type, but, for now, * that it not possible. Those cases will be indicated by the * lv_net_type being set to nil. */ extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type, ivl_variable_type_t lv_type, unsigned lv_width, PExpr*expr, bool need_const =false, bool force_unsigned =false); /* * Same as above, but lv_width and lv_type are derived from the lv_net_type. */ extern NetExpr* elaborate_rval_expr(Design *des, NetScope *scope, ivl_type_t lv_net_type, PExpr *expr, bool need_const = false, bool force_unsigned = false); extern bool evaluate_range(Design*des, NetScope*scope, const LineInfo*li, const pform_range_t&range, long&index_l, long&index_r); extern bool evaluate_ranges(Design*des, NetScope*scope, const LineInfo*li, std::vector&llist, const std::list&rlist); /* * This procedure evaluates an expression and if the evaluation is * successful the original expression is replaced with the new one. */ void eval_expr(NetExpr*&expr, int context_width =-1); /* * Get the long integer value for the passed in expression, if * possible. If it is not possible (the expression is not evaluated * down to a constant) then return false and leave value unchanged. */ bool eval_as_long(long&value, const NetExpr*expr); bool eval_as_double(double&value, NetExpr*expr); /* * Evaluate an entire scope path in the context of the given scope. */ extern std::list eval_scope_path(Design*des, NetScope*scope, const pform_name_t&path); extern hname_t eval_path_component(Design*des, NetScope*scope, const name_component_t&comp, bool&error_flag); /* * If this scope is contained within a class scope (i.e. a method of a * class) then return the class definition that contains it. */ extern const netclass_t*find_class_containing_scope(const LineInfo&loc,const NetScope*scope); extern NetScope* find_method_containing_scope(const LineInfo&log, NetScope*scope); /* * Return true if the data type is a type that is normally available * in vector for. IVL_VT_BOOL and IVL_VT_LOGIC are vectorable, * IVL_VT_REAL is not. */ extern bool type_is_vectorable(ivl_variable_type_t type); /* * Return a human readable version of the operator. */ const char *human_readable_op(const char op, bool unary = false); /* * Is the expression a constant value and if so what is its logical * value. * * C_NON - the expression is not a constant value. * C_0 - the expression is constant and it has a false value. * C_1 - the expression is constant and it has a true value. * C_X - the expression is constant and it has an 'bX value. */ enum const_bool { C_NON, C_0, C_1, C_X }; const_bool const_logical(const NetExpr*expr); /* * When scaling a real value to a time we need to do some standard * processing. */ extern uint64_t get_scaled_time_from_real(Design*des, NetScope*scope, NetECReal*val); extern void collapse_partselect_pv_to_concat(Design*des, NetNet*sig); extern bool evaluate_index_prefix(Design*des, NetScope*scope, std::list&prefix_indices, const std::list&indices); extern NetExpr*collapse_array_indices(Design*des, NetScope*scope, NetNet*net, const std::list&indices); extern NetExpr*collapse_array_exprs(Design*des, NetScope*scope, const LineInfo*loc, NetNet*net, const std::list&indices); extern void assign_unpacked_with_bufz(Design*des, NetScope*scope, const LineInfo*loc, NetNet*lval, NetNet*rval); extern NetPartSelect* detect_partselect_lval(Link&pin); /* * Print a warning if we find a mixture of default and explicit timescale * based delays in the design, since this is likely an error. */ extern void check_for_inconsistent_delays(NetScope*scope); #endif /* IVL_netmisc_H */ iverilog-12_0/netparray.cc000066400000000000000000000051771435245347300156750ustar00rootroot00000000000000/* * Copyright (c) 2012 Picture Elements, Inc. * 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 "netparray.h" using namespace std; netsarray_t::~netsarray_t() { } netparray_t::~netparray_t() { } /* * The packed width of a packed array is the packed width of the * element times the dimension width of the array itself. */ bool netparray_t::packed(void) const { return true; } long netparray_t::packed_width(void) const { long cur_width = element_type()->packed_width(); for (vector::const_iterator cur = static_dimensions().begin() ; cur != static_dimensions().end() ; ++cur) { cur_width *= cur->width(); } return cur_width; } vector netparray_t::slice_dimensions() const { const vector&packed_dims = static_dimensions(); vector elem_dims = element_type()->slice_dimensions(); vector res (packed_dims.size() + elem_dims.size()); for (size_t idx = 0 ; idx < packed_dims.size() ; idx += 1) res[idx] = packed_dims[idx]; for (size_t idx = 0 ; idx < elem_dims.size() ; idx += 1) res[idx+packed_dims.size()] = elem_dims[idx]; return res; } bool netparray_t::test_compatibility(ivl_type_t that) const { return packed_type_compatible(that); } bool netparray_t::test_equivalence(ivl_type_t that) const { return packed_types_equivalent(this, that); } netuarray_t::~netuarray_t() { } vector netuarray_t::slice_dimensions() const { return static_dimensions(); } bool netuarray_t::test_equivalence(ivl_type_t that) const { const netuarray_t *that_a = dynamic_cast(that); if (!that_a) return false; if (!netrange_equivalent(static_dimensions(), that_a->static_dimensions())) return false; return element_type()->type_equivalent(that_a->element_type()); } iverilog-12_0/netparray.h000066400000000000000000000053521435245347300155320ustar00rootroot00000000000000#ifndef IVL_netarray_H #define IVL_netarray_H /* * Copyright (c) 2012-2014 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include "nettypes.h" # include /* * Arrays with static dimensions (packed and unpacked) share this * common base type. */ class netsarray_t : public netarray_t { public: explicit netsarray_t(const std::vector&packed, ivl_type_t etype); ~netsarray_t(); public: // Virtual methods from the ivl_type_s type... public: inline const std::vector& static_dimensions() const { return dims_; } private: std::vector dims_; }; inline netsarray_t::netsarray_t(const std::vector&pd, ivl_type_t etype) : netarray_t(etype), dims_(pd) { } /* * Packed arrays. */ class netparray_t : public netsarray_t { public: explicit netparray_t(const std::vector&packed, ivl_type_t etype); ~netparray_t(); public: // Virtual methods from the ivl_type_s type... bool packed(void) const; long packed_width(void) const; std::vector slice_dimensions() const; private: bool test_compatibility(ivl_type_t that) const; bool test_equivalence(ivl_type_t that) const; }; inline netparray_t::netparray_t(const std::vector&pd, ivl_type_t etype) : netsarray_t(pd, etype) { } /* * Unpacked arrays are very similar, but lack packed slices. */ class netuarray_t : public netsarray_t { public: explicit netuarray_t(const std::vector&packed, ivl_type_t etype); ~netuarray_t(); public: // Virtual methods from the ivl_type_s type... std::vector slice_dimensions() const; private: bool test_equivalence(ivl_type_t that) const; }; inline netuarray_t::netuarray_t(const std::vector&pd, ivl_type_t etype) : netsarray_t(pd, etype) { } #endif /* IVL_netarray_H */ iverilog-12_0/netqueue.cc000066400000000000000000000021541435245347300155130ustar00rootroot00000000000000/* * Copyright (c) 2014-2020 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 "netqueue.h" # include using namespace std; netqueue_t::netqueue_t(ivl_type_t vec, long max_idx) : netdarray_t(vec), max_idx_(max_idx) { } netqueue_t::~netqueue_t() { } ivl_variable_type_t netqueue_t::base_type() const { return IVL_VT_QUEUE; } iverilog-12_0/netqueue.h000066400000000000000000000031431435245347300153540ustar00rootroot00000000000000#ifndef IVL__netqueue_H #define IVL__netqueue_H /* * Copyright (c) 2014-2020 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 "netdarray.h" # include "ivl_target.h" /* * A queue type is actually a dynamic array with a few extra * methods. This will probably result in a different implementation at * run-time, but for the most part this applies during elaboration. */ class netqueue_t : public netdarray_t { public: explicit netqueue_t(ivl_type_t vec, long max_idx); ~netqueue_t(); // This is the "base_type()" virtual method of the // nettype_base_t. The ivl_target api expects this to return // IVL_VT_QUEUE for queues. ivl_variable_type_t base_type() const; long max_idx(void) const { return max_idx_; } std::ostream& debug_dump(std::ostream&) const; private: long max_idx_; }; #endif iverilog-12_0/netscalar.cc000066400000000000000000000023171435245347300156350ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "netscalar.h" using namespace std; netreal_t netreal_t::type_real; netreal_t netreal_t::type_shortreal; netstring_t netstring_t::type_string; netreal_t::~netreal_t() { } ivl_variable_type_t netreal_t::base_type() const { return IVL_VT_REAL; } netstring_t::~netstring_t() { } ivl_variable_type_t netstring_t::base_type() const { return IVL_VT_STRING; } iverilog-12_0/netscalar.h000066400000000000000000000031241435245347300154740ustar00rootroot00000000000000#ifndef IVL_netscalar_H #define IVL_netscalar_H /* * Copyright (c) 2013-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 "nettypes.h" class netreal_t : public ivl_type_s { public: inline explicit netreal_t() { } ~netreal_t(); ivl_variable_type_t base_type() const; bool get_signed() const { return true; } bool get_scalar() const { return true; } std::ostream& debug_dump(std::ostream&) const; public: static netreal_t type_real; static netreal_t type_shortreal; }; class netstring_t : public ivl_type_s { public: inline explicit netstring_t() { } ~netstring_t(); ivl_variable_type_t base_type() const; std::ostream& debug_dump(std::ostream&) const; public: static netstring_t type_string; }; #endif /* IVL_netscalar_H */ iverilog-12_0/netstruct.cc000066400000000000000000000100751435245347300157140ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "netlist.h" # include "netstruct.h" # include "netvector.h" # include # include "ivl_assert.h" using namespace std; netstruct_t::netstruct_t() : union_(false), packed_(false) { } netstruct_t::~netstruct_t() { } void netstruct_t::union_flag(bool flag) { // This MUST be called before any members are pushed into the // definition. This is because the append relies on this flag // being accurate. ivl_assert(*this, members_.empty()); union_ = flag; } void netstruct_t::packed(bool flag) { ivl_assert(*this, members_.empty()); packed_ = flag; } void netstruct_t::append_member(Design*des, const netstruct_t::member_t&val) { ivl_assert(*this, val.net_type); members_.push_back(val); if (packed_) { if (! members_.back().net_type->packed()) { cerr << get_fileline() << ": error: " << "Member " << members_.back().name << " of packed struct/union" << " must be packed." << endl; des->errors += 1; } } if (union_ && packed_ && members_.size() > 1) { unsigned long expect_wid = members_.front().net_type->packed_width(); unsigned long got_wid = members_.back().net_type->packed_width(); if (expect_wid != got_wid) { cerr << get_fileline() << ": error: " << "Member " << val.name << " of packed union" << " is " << got_wid << " bits, expecting " << expect_wid << " bits." << endl; des->errors += 1; } } } const netstruct_t::member_t* netstruct_t::packed_member(perm_string name, unsigned long&off) const { unsigned long count_off = 0; for (size_t idx = members_.size() ; idx > 0 ; idx -= 1) { if (members_[idx-1].name == name) { off = count_off; return &members_[idx-1]; } // If this is not a union, then the members are lined up // from LSB to MSB. If this is a union, then all // members are at offset 0. if (!union_) count_off += members_[idx-1].net_type->packed_width(); } return 0; } long netstruct_t::packed_width(void) const { if (! packed_) return -1; // If this is a packed union, then all the members are the // same width, so it is sufficient to return the width of any // single member. if (union_) return members_.front().net_type->packed_width(); // The width of a packed struct is the sum of member widths. long res = 0; for (size_t idx = 0 ; idx < members_.size() ; idx += 1) res += members_[idx].net_type->packed_width(); return res; } vector netstruct_t::slice_dimensions() const { vector tmp; tmp .push_back(netrange_t(packed_width()-1, 0)); return tmp; } ivl_variable_type_t netstruct_t::base_type() const { if (! packed_) return IVL_VT_NO_TYPE; for (size_t idx = 0 ; idx < members_.size() ; idx += 1) { if (members_[idx].data_type() != IVL_VT_BOOL) return members_[idx].data_type(); } return IVL_VT_BOOL; } bool netstruct_t::test_compatibility(ivl_type_t that) const { return packed_type_compatible(that); } bool netstruct_t::test_equivalence(ivl_type_t that) const { if (!packed_) return this == that; return packed_types_equivalent(this, that); } iverilog-12_0/netstruct.h000066400000000000000000000060351435245347300155570ustar00rootroot00000000000000#ifndef IVL_netstruct_H #define IVL_netstruct_H /* * Copyright (c) 2011-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 "LineInfo.h" # include # include "ivl_target.h" # include "nettypes.h" class Design; class netstruct_t : public LineInfo, public ivl_type_s { public: struct member_t { perm_string name; ivl_type_t net_type; inline ivl_variable_type_t data_type() const { return net_type->base_type(); }; bool get_signed() const { return net_type->get_signed(); } }; public: netstruct_t(); ~netstruct_t(); // If this is a union (instead of struct) then this flag is // set. We handle union and struct together because they are // so similar. void union_flag(bool); bool union_flag(void) const; void packed(bool flag); bool packed(void) const; // When the struct is accessed as a primary it can be signed or unsigned void set_signed(bool flag) { signed_ = flag; } bool get_signed(void) const { return signed_; } // Append a new member to the struct/union. This must be done // after the union_flag and packed settings are set. This // function does error checking, and the "des" argument is // only present so that it can set error flags. void append_member(Design*des, const member_t&); // Given the name of a member, return a pointer to the member // description, and set the off value to be the offset into // the packed value where the member begins. const struct member_t* packed_member(perm_string name, unsigned long&off) const; // Return the width (in bits) of the packed record, or -1 if // the record is not packed. long packed_width() const; std::vector slice_dimensions() const; // Return the base type of the packed record, or // IVL_VT_NO_TYPE if the record is not packed. ivl_variable_type_t base_type() const; private: bool test_compatibility(ivl_type_t that) const; bool test_equivalence(ivl_type_t that) const; private: bool union_; bool packed_; bool signed_; std::vectormembers_; }; inline bool netstruct_t::union_flag(void) const { return union_; } inline bool netstruct_t::packed(void) const { return packed_; } #endif /* IVL_netstruct_H */ iverilog-12_0/nettypes.cc000066400000000000000000000131411435245347300155310ustar00rootroot00000000000000/* * Copyright (c) 2012-2016 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 "nettypes.h" # include "netenum.h" # include # include using namespace std; ivl_type_s::~ivl_type_s() { } /* * The derived class may override this to provide a more accurate * response. */ bool ivl_type_s::packed(void) const { return false; } long ivl_type_s::packed_width(void) const { return 1; } vector ivl_type_s::slice_dimensions() const { return vector(); } ivl_variable_type_t ivl_type_s::base_type() const { return IVL_VT_NO_TYPE; } bool ivl_type_s::get_signed() const { return false; } bool ivl_type_s::get_scalar() const { return false; } bool ivl_type_s::type_compatible(ivl_type_t that) const { if (this == that) return true; return test_compatibility(that); } bool ivl_type_s::test_compatibility(ivl_type_t that) const { return test_equivalence(that); } bool ivl_type_s::type_equivalent(ivl_type_t that) const { if (this == that) return true; return test_equivalence(that); } bool ivl_type_s::test_equivalence(ivl_type_t) const { return false; } netarray_t::~netarray_t() { } ivl_variable_type_t netarray_t::base_type() const { return element_type_->base_type(); } unsigned long netrange_width(const vector&packed) { unsigned wid = 1; for (vector::const_iterator cur = packed.begin() ; cur != packed.end() ; ++cur) { unsigned use_wid = cur->width(); wid *= use_wid; } return wid; } bool netrange_equivalent(const std::vector &a, const std::vector &b) { if (a.size() != b.size()) return false; for (size_t i = 0; i < a.size(); i++) { if (!a[i].equivalent(b[i])) return false; } return true; } /* * Given a netrange_t list (which represent packed dimensions) and a * prefix of calculated index values, calculate the canonical offset * and width of the resulting slice. In this case, the "sb" argument * is an extra index of the prefix. */ bool prefix_to_slice(const std::vector&dims, const std::list&prefix, long sb, long&loff, unsigned long&lwid) { assert(prefix.size() < dims.size()); // Figure out the width of the slice, given the number of // prefix numbers there are. We don't need to look at the // actual values yet, but we do need to know how many there // are compared to the actual dimensions of the target. So do // this by multiplying the widths of the dims that are NOT // accounted for by the prefix or sb indices. size_t acc_wid = 1; vector::const_iterator pcur = dims.end(); for (size_t idx = prefix.size()+1 ; idx < dims.size() ; idx += 1) { -- pcur; acc_wid *= pcur->width(); } lwid = acc_wid; // lwid is now the final slice width. // pcur is pointing to the dimension AFTER the dimension that // we have an index for, so step back one, then this will be // used with the sb index. Start accumulating in the acc_off // the offset into the n-dimensional vector. -- pcur; if (sb < pcur->get_msb() && sb < pcur->get_lsb()) return false; if (sb > pcur->get_msb() && sb > pcur->get_lsb()) return false; long acc_off = 0; if (pcur->get_msb() >= pcur->get_lsb()) acc_off += (sb - pcur->get_lsb()) * acc_wid; else acc_off += (pcur->get_lsb() - sb) * acc_wid; // If there are no more prefix items, we are done. if (prefix.empty()) { loff = acc_off; return true; } // Now similarly go through the prefix numbers, working // through the dimensions until we run out. Accumulate a // growing slice width (acc_wid) that is used to calculate the // growing offset (acc_off). list::const_iterator icur = prefix.end(); do { -- icur; acc_wid *= pcur->width(); -- pcur; if (pcur->get_msb() >= pcur->get_lsb()) acc_off += (*icur - pcur->get_lsb()) * acc_wid; else acc_off += (pcur->get_lsb() - *icur) * acc_wid; } while (icur != prefix.begin()); // Got our final offset. loff = acc_off; return true; } bool packed_types_equivalent(ivl_type_t a, ivl_type_t b) { if (!a->packed() || !b->packed()) return false; if (a->base_type() != b->base_type()) return false; if (a->packed_width() != b->packed_width()) return false; if (a->get_signed() != b->get_signed()) return false; // Special case, even though enums are packed they are not equivalent, // they are only assignment compatible to other packed types if (dynamic_cast(b)) return false; return true; } bool packed_type_compatible(ivl_type_t type) { if (type->packed()) return true; if (type->base_type() == IVL_VT_REAL) return true; return false; } iverilog-12_0/nettypes.h000066400000000000000000000131511435245347300153740ustar00rootroot00000000000000#ifndef IVL_nettypes_H #define IVL_nettypes_H /* * Copyright (c) 2012-2021 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 "ivl_target.h" # include # include # include # include # include class netrange_t; class LineInfo; /* * This is a fully abstract type that is a type that can be attached * to a NetNet object. */ class ivl_type_s { public: virtual ~ivl_type_s() =0; virtual bool packed(void) const; virtual long packed_width(void) const; virtual std::vector slice_dimensions() const; // Some types have a base variable type. This is the bit type // for packed data types, or IVL_VT_DARRAY or IVL_VT_CLASS for // those specific types. virtual ivl_variable_type_t base_type() const; virtual bool get_signed() const; virtual bool get_scalar() const; // Return true if "that" type is assignment compatible with this // type. bool type_compatible(ivl_type_t that) const; // Return true if "that" type is equivalent with this type as defined by // the standard bool type_equivalent(ivl_type_t that) const; virtual std::ostream& debug_dump(std::ostream&) const; private: // The "type_compatible" and "type_equivalent" methods uses this virtual // method to invoke type-specific tests of compatibility. virtual bool test_compatibility(ivl_type_t that) const; virtual bool test_equivalence(ivl_type_t that) const; }; /* * Convenience functions for making ivl_type_t objects from various inputs. */ extern ivl_type_t make_ivl_type(ivl_variable_type_t vt, const std::vector&packed_dimensions, bool signed_flag =false, bool isint_flag =false); /* * There are a couple types of array types. This class represents the * common bits of array types. */ class netarray_t : public ivl_type_s { public: inline explicit netarray_t(ivl_type_t etype) : element_type_(etype) { } ~netarray_t(); public: // Some virtual methods have a common implementation for arrays. // The base_type() for arrays is the base_Typeof the element. ivl_variable_type_t base_type() const; public: inline ivl_type_t element_type() const { return element_type_; } private: ivl_type_t element_type_; }; inline static std::ostream& operator << (std::ostream&out, const ivl_type_s&obj) { return obj.debug_dump(out); } class netrange_t { public: // Create an undefined range. An undefined range is a range // used to declare dynamic arrays, etc. inline netrange_t() : msb_(LONG_MAX), lsb_(LONG_MAX) { } // Create a properly defined netrange inline netrange_t(long m, long l) : msb_(m), lsb_(l) { } // Copy constructor. inline netrange_t(const netrange_t&that) : msb_(that.msb_), lsb_(that.lsb_) { } inline netrange_t& operator = (const netrange_t&that) { msb_ = that.msb_; lsb_ = that.lsb_; return *this; } inline bool defined() const { return msb_!=LONG_MAX || lsb_!= LONG_MAX; } inline unsigned long width()const { if (!defined()) return 0; else if (msb_ >= lsb_) return msb_-lsb_+1; else return lsb_-msb_+1; } inline long get_msb() const { assert(defined()); return msb_; } inline long get_lsb() const { assert(defined()); return lsb_; } inline bool operator == (const netrange_t&that) const { if (msb_ != that.msb_) return false; if (lsb_ != that.lsb_) return false; return true; } inline bool operator != (const netrange_t&that) const { if (msb_ != that.msb_) return true; if (lsb_ != that.lsb_) return true; return false; } bool equivalent(const netrange_t &that) const { return width() == that.width(); } private: long msb_; long lsb_; }; extern std::ostream&operator << (std::ostream&out, const std::list&rlist); extern std::ostream&operator << (std::ostream&out, const std::vector&rlist); extern unsigned long netrange_width(const std::vector&dims); extern bool netrange_equivalent(const std::vector &a, const std::vector &b); /* * There are a few cases where we need to know about the single-level * dimensions of a parameter declaration, for example: * * parameter [msv:lsv] foo ...; */ extern bool calculate_param_range(const LineInfo&line, ivl_type_t par_type, long&par_msv, long&par_lsv, long length); /* * Take as input a list of packed dimensions and a list of prefix * indices, and calculate the offset/width of the resulting slice into * the packed array. */ extern bool prefix_to_slice(const std::vector&dims, const std::list&prefix, long sb, long&loff, unsigned long&lwid); extern bool packed_types_equivalent(ivl_type_t a, ivl_type_t b); extern bool packed_type_compatible(ivl_type_t type); #endif /* IVL_nettypes_H */ iverilog-12_0/netvector.cc000066400000000000000000000057101435245347300156720ustar00rootroot00000000000000/* * Copyright (c) 2012-2013 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 "netvector.h" # include "compiler.h" # include using namespace std; netvector_t netvector_t::atom2s64 (IVL_VT_BOOL, 63, 0, true); netvector_t netvector_t::atom2u64 (IVL_VT_BOOL, 63, 0, false); netvector_t netvector_t::atom2s32 (IVL_VT_BOOL, 31, 0, true); netvector_t netvector_t::atom2u32 (IVL_VT_BOOL, 31, 0, false); netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true); netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 15, 0, false); netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 7, 0, true); netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 7, 0, false); netvector_t netvector_t::time_signed (IVL_VT_LOGIC, 63, 0, true); netvector_t netvector_t::time_unsigned (IVL_VT_LOGIC, 63, 0, false); static netvector_t* save_integer_type[2]; const netvector_t* netvector_t::integer_type(bool is_signed) { if (save_integer_type[is_signed]) return save_integer_type[is_signed]; save_integer_type[is_signed] = new netvector_t(IVL_VT_LOGIC, integer_width-1, 0, is_signed); save_integer_type[is_signed]->set_isint(true); return save_integer_type[is_signed]; } //netvector_t netvector_t::scalar_bool (IVL_VT_BOOL); netvector_t netvector_t::scalar_logic (IVL_VT_LOGIC); netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb, bool flag) : type_(type), signed_(flag), isint_(false), implicit_(false) { packed_dims_.push_back(netrange_t(msb,lsb)); } netvector_t::netvector_t(ivl_variable_type_t type) : type_(type), signed_(false), isint_(false), implicit_(false) { } netvector_t::~netvector_t() { } ivl_variable_type_t netvector_t::base_type() const { return type_; } /* * vectors are by definition packed. */ bool netvector_t::packed(void) const { return true; } long netvector_t::packed_width() const { return netrange_width(packed_dims_); } vector netvector_t::slice_dimensions() const { return packed_dims_; } bool netvector_t::test_compatibility(ivl_type_t that) const { return packed_type_compatible(that); } bool netvector_t::test_equivalence(const ivl_type_t that) const { return packed_types_equivalent(this, that); } iverilog-12_0/netvector.h000066400000000000000000000074601435245347300155400ustar00rootroot00000000000000#ifndef IVL_netvector_H #define IVL_netvector_H /* * Copyright (c) 2012-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 "nettypes.h" # include "ivl_target.h" # include class netvector_t : public ivl_type_s { public: explicit netvector_t(const std::vector&packed, ivl_variable_type_t type); // This is a variant of the vector form. Some code processes // the list of packed ranges as a list, but we will store them // as a vector in this constructor. explicit netvector_t(const std::list&packed, ivl_variable_type_t type); // special case: there is a single packed dimension and we // know it in the form [:]. This step saves me // creating a netrange_t for this single item. explicit netvector_t(ivl_variable_type_t type, long msb, long lsb, bool signed_flag =false); // Special case: scalar object--no packed dimensions at all. explicit netvector_t(ivl_variable_type_t type); ~netvector_t(); // Vectors can be interpreted as signed or unsigned when // handled as vectors. inline void set_signed(bool flag) { signed_ = flag; } inline bool get_signed(void) const { return signed_; } inline void set_isint(bool flag) { isint_ = flag; } inline bool get_isint(void) const { return isint_; } inline bool get_scalar(void) const { return packed_dims_.empty(); } void set_implicit(bool implicit) { implicit_ = implicit; } bool get_implicit() const { return implicit_; } ivl_variable_type_t base_type() const; const std::vector&packed_dims() const; bool packed(void) const; long packed_width() const; std::vector slice_dimensions() const; std::ostream& debug_dump(std::ostream&) const; public: // Some commonly used predefined types static netvector_t atom2s64; static netvector_t atom2u64; static netvector_t atom2s32; static netvector_t atom2u32; static netvector_t atom2s16; static netvector_t atom2u16; static netvector_t atom2s8; static netvector_t atom2u8; static netvector_t time_signed; static netvector_t time_unsigned; static netvector_t scalar_bool; static netvector_t scalar_logic; static const netvector_t*integer_type(bool is_signed = true); private: bool test_compatibility(ivl_type_t that) const; bool test_equivalence(ivl_type_t that) const; private: std::vector packed_dims_; ivl_variable_type_t type_; bool signed_ : 1; bool isint_ : 1; // original type of integer bool implicit_ : 1; }; inline netvector_t::netvector_t(const std::vector&pd, ivl_variable_type_t type) : packed_dims_(pd), type_(type), signed_(false), isint_(false) { } inline const std::vector& netvector_t::packed_dims() const { return packed_dims_; } inline static std::ostream& operator << (std::ostream&out, const netvector_t&obj) { return obj.debug_dump(out); } #endif /* IVL_netvector_H */ iverilog-12_0/nodangle.cc000066400000000000000000000221611435245347300154470ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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" /* * This functor scans the design looking for dangling objects and * excess local signals. These deletions are not necessarily required * for proper functioning of anything, but they can clean up the * appearance of design files that are generated. */ # include "functor.h" # include "netlist.h" # include "compiler.h" using namespace std; class nodangle_f : public functor_t { public: void event(Design*des, NetEvent*ev); void signal(Design*des, NetNet*sig); unsigned iteration; unsigned stotal, etotal; bool scontinue, econtinue; bool scomplete, ecomplete; }; void nodangle_f::event(Design*, NetEvent*ev) { if (ecomplete) return; /* If there are no references to this event, then go right ahead and delete it. There is no use looking further at it. */ if ((ev->nwait() + ev->ntrig() + ev->nexpr()) == 0) { delete ev; etotal += 1; return; } if (iteration == 0) { /* Try to remove duplicate probes from the event. This is done as a separate initial pass to ensure similar events are detected as soon as possible in subsequent iterations. */ for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { unsigned jdx = idx + 1; while (jdx < ev->nprobe()) { NetEvProbe*ip = ev->probe(idx); NetEvProbe*jp = ev->probe(jdx); if (ip->edge() != jp->edge()) { jdx += 1; continue; } bool fully_connected = true; for (unsigned jpin = 0; jpin < jp->pin_count(); jpin += 1) { unsigned ipin = 0; bool connected_flag = false; for (ipin = 0 ; ipin < ip->pin_count(); ipin += 1) if (connected(ip->pin(ipin), jp->pin(jpin))) { connected_flag = true; break; } if (!connected_flag) { fully_connected = false; break; } } if (fully_connected) { delete jp; } else { jdx += 1; } } } econtinue = true; } else { /* Postpone examining events in an automatic scope until the third (optional) pass. This will mean similar events are biased towards being stored in static scopes. */ if (ev->scope()->is_auto()) { if (iteration == 1) { econtinue = true; return; } } else { if (iteration == 2) { return; } } /* Try to find all the events that are similar to me, and replace their references with references to me. */ list match; ev->find_similar_event(match); for (list::iterator idx = match.begin() ; idx != match.end() ; ++ idx ) { NetEvent*tmp = *idx; assert(tmp != ev); tmp ->replace_event(ev); } } } static bool floating_net_tested(NetNet*sig) { static set tested_set; pair< set::iterator, bool > cur = tested_set.insert(sig); return !cur.second; } static void check_is_floating(NetNet*sig) { // Some signal types are implicitly driven if nothing else. if (sig->type() == NetNet::SUPPLY0) return; if (sig->type() == NetNet::SUPPLY1) return; if (sig->type() == NetNet::TRI0) return; if (sig->type() == NetNet::TRI1) return; if (sig->type() == NetNet::IMPLICIT_REG) return; if (sig->type() == NetNet::REG) return ; // Assignments drive a signal. if (sig->peek_lref() > 0) return; for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) { if (sig->pin(idx).get_dir() == Link::OUTPUT) continue; if (sig->pin(idx).nexus()->drivers_present()) continue; if (sig->port_type() == PortType::NOT_A_PORT && sig->pin_count()==1) { cerr << sig->get_fileline() << ": warning: " << "Signal " << scope_path(sig->scope()) << "." << sig->name() << " has no drivers." << endl; } else if (sig->port_type()==PortType::NOT_A_PORT) { cerr << sig->get_fileline() << ": warning: " << "Signal " << scope_path(sig->scope()) << "." << sig->name() << "[" << idx << "]" << " has no drivers." << endl; } else { cerr << sig->get_fileline() << ": warning: " << "Port " << sig->name() << " of " << scope_path(sig->scope()) << " has no drivers." << endl; } } } void nodangle_f::signal(Design*, NetNet*sig) { if (scomplete) return; if (warn_floating_nets && !sig->local_flag() && !floating_net_tested(sig)) { check_is_floating(sig); } /* Cannot delete signals referenced in an expression or an l-value. */ if (sig->get_refs() > 0) return; /* Cannot delete the ports of tasks, functions or modules. There are too many places where they are referenced. */ if ((sig->port_type() != NetNet::NOT_A_PORT) && ((sig->scope()->type() == NetScope::TASK) || (sig->scope()->type() == NetScope::FUNC) || (sig->scope()->type() == NetScope::MODULE))) return; /* Can't delete ports of cells. */ if ((sig->port_type() != NetNet::NOT_A_PORT) && (sig->scope()->attribute(perm_string::literal("ivl_synthesis_cell")) != verinum())) return; /* Don't delete signals that are marked with the ivl_do_not_elide property. */ if (!sig->local_flag() && (sig->attribute(perm_string::literal("ivl_do_not_elide")) != verinum())) return; /* Check to see if the signal is completely unconnected. If all the bits are unlinked, then delete it. */ if (! sig->is_linked()) { delete sig; stotal += 1; return; } /* The remaining things can only be done to synthesized signals, not ones that appear in the original Verilog. */ if (! sig->local_flag()) return; /* Check to see if there is some significant signal connected to every pin of this signal. */ unsigned significant_flags = 0; for (unsigned idx = 0 ; idx < sig->pin_count() ; idx += 1) { Nexus*nex = sig->pin(idx).nexus(); for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { if (cur == &sig->pin(idx)) continue; NetNet*cursig = dynamic_cast(cur->get_obj()); if (cursig == 0) continue; if (cursig->local_flag()) continue; significant_flags += 1; break; } if (significant_flags <= idx) break; } /* If every pin is connected to another significant signal, then I can delete this one. */ if (significant_flags == sig->pin_count()) { delete sig; stotal += 1; } } void nodangle(Design*des) { nodangle_f fun; fun.iteration = 0; fun.stotal = 0; fun.etotal = 0; fun.scomplete = false; fun.ecomplete = false; do { if (verbose_flag) { cout << " ... scan for dangling signal and event nodes. " << "(scomplete=" << (fun.scomplete? "T" : "F") << ", ecomplete=" << (fun.ecomplete? "T" : "F") << ")" << endl << flush; } fun.scontinue = false; fun.econtinue = false; des->functor(&fun); fun.iteration += 1; fun.scomplete = !fun.scontinue; fun.ecomplete = !fun.econtinue; if (verbose_flag) { cout << " ... " << fun.iteration << " iterations" << " deleted " << fun.stotal << " dangling signals" << " and " << fun.etotal << " events." << endl << flush; } } while (fun.scontinue || fun.econtinue); if (verbose_flag) { cout << " ... done" << endl << flush; } } iverilog-12_0/pad_to_width.cc000066400000000000000000000126541435245347300163330ustar00rootroot00000000000000/* * Copyright (c) 1999-2016 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 "netenum.h" # include "netlist.h" # include "netvector.h" # include "netmisc.h" NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag, const LineInfo&info, ivl_type_t use_type) { if (wid <= expr->expr_width() && !use_type) { expr->cast_signed(signed_flag); return expr; } /* If the expression is a const, then replace it with a wider const. This is a more efficient result. */ if (NetEConst*tmp = dynamic_cast(expr)) { verinum oval = tmp->value(); oval.has_sign(signed_flag); oval = pad_to_width(oval, wid); if (const netenum_t *enum_type = dynamic_cast(use_type)) { // The name of the enum is set to here, but the name is // only used in debugging output, so this is ok tmp = new NetEConstEnum(perm_string(), enum_type, oval); } else { tmp = new NetEConst(oval); } tmp->set_line(info); delete expr; return tmp; } NetESelect*tmp = new NetESelect(expr, 0, wid, use_type); tmp->cast_signed(signed_flag); tmp->set_line(info); return tmp; } NetExpr*cast_to_width(NetExpr*expr, unsigned wid, bool signed_flag, const LineInfo&info) { /* If the expression is a const, then replace it with a new const. This is a more efficient result. */ if (NetEConst*tmp = dynamic_cast(expr)) { tmp->cast_signed(signed_flag); if (wid != tmp->expr_width()) { tmp = new NetEConst(verinum(tmp->value(), wid)); tmp->set_line(info); delete expr; } return tmp; } NetESelect*tmp = new NetESelect(expr, 0, wid); tmp->cast_signed(signed_flag); tmp->set_line(info); return tmp; } /* * Pad a NetNet to the desired vector width by concatenating a * NetConst of constant zeros. Use a NetConcat node to do the * concatenation. */ NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid, const LineInfo&info) { NetScope*scope = net->scope(); if (net->vector_width() >= wid) return net; // Make the NetConcat and connect the input net to the lsb input. NetConcat*cc = new NetConcat(scope, scope->local_symbol(), wid, 2); cc->set_line(info); des->add_node(cc); connect(cc->pin(1), net->pin(0)); // Make a NetConst of the desired width and connect in to the // lsb input of the NetConcat. verinum pad(verinum::V0, wid - net->vector_width()); NetConst*con = new NetConst(scope, scope->local_symbol(), pad); con->set_line(info); des->add_node(con); connect(cc->pin(2), con->pin(0)); // Make a NetNet for the NetConst to NetConcat link. netvector_t*tmp_vec = new netvector_t(net->data_type(), wid - net->vector_width() - 1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(info); tmp->local_flag(true); connect(cc->pin(2), tmp->pin(0)); // Create a NetNet of the output width and connect it to the // NetConcat node output pin. tmp_vec = new netvector_t(net->data_type(), wid-1, 0); tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(info); tmp->local_flag(true); connect(cc->pin(0), tmp->pin(0)); return tmp; } NetNet*pad_to_width_signed(Design*des, NetNet*net, unsigned wid, const LineInfo&info) { NetScope*scope = net->scope(); if (net->vector_width() >= wid) return net; NetSignExtend*se = new NetSignExtend(scope, scope->local_symbol(), wid); se->set_line(info); des->add_node(se); netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0); tmp_vec->set_signed(true); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(info); tmp->local_flag(true); connect(tmp->pin(0), se->pin(0)); connect(se->pin(1), net->pin(0)); return tmp; } NetNet*crop_to_width(Design*des, NetNet*net, unsigned wid) { NetScope*scope = net->scope(); if (net->vector_width() <= wid) return net; NetPartSelect*ps = new NetPartSelect(net, 0, wid, NetPartSelect::VP); ps->set_line(*net); des->add_node(ps); netvector_t*tmp_vec = new netvector_t(net->data_type(), wid-1, 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->set_line(*net); tmp->local_flag(true); connect(ps->pin(0), tmp->pin(0)); return tmp; } iverilog-12_0/parse.y000066400000000000000000006034621435245347300146660ustar00rootroot00000000000000 %{ /* * Copyright (c) 1998-2022 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2013 / 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 # include "parse_misc.h" # include "compiler.h" # include "pform.h" # include "Statement.h" # include "PSpec.h" # include "PPackage.h" # include # include # include using namespace std; class PSpecPath; extern void lex_end_table(); static data_type_t* param_data_type = 0; static bool param_is_local = false; static bool param_is_type = false; static std::list* specparam_active_range = 0; /* Port declaration lists use this structure for context. */ static struct { NetNet::Type port_net_type; NetNet::PortType port_type; data_type_t* data_type; } port_declaration_context = {NetNet::NONE, NetNet::NOT_A_PORT, 0}; /* Modport port declaration lists use this structure for context. */ enum modport_port_type_t { MP_NONE, MP_SIMPLE, MP_TF, MP_CLOCKING }; static struct { modport_port_type_t type; union { NetNet::PortType direction; bool is_import; }; } last_modport_port = { MP_NONE, {NetNet::NOT_A_PORT}}; /* The task and function rules need to briefly hold the pointer to the task/function that is currently in progress. */ static PTask* current_task = 0; static PFunction* current_function = 0; static stack current_block_stack; /* The variable declaration rules need to know if a lifetime has been specified. */ static LexicalScope::lifetime_t var_lifetime; static pform_name_t* pform_create_this(void) { name_component_t name (perm_string::literal(THIS_TOKEN)); pform_name_t*res = new pform_name_t; res->push_back(name); return res; } static pform_name_t* pform_create_super(void) { name_component_t name (perm_string::literal(SUPER_TOKEN)); pform_name_t*res = new pform_name_t; res->push_back(name); return res; } /* This is used to keep track of the extra arguments after the notifier * in the $setuphold and $recrem timing checks. This allows us to print * a warning message that the delayed signals will not be created. We * need to do this since not driving these signals creates real * simulation issues. */ static unsigned args_after_notifier; /* The rules sometimes push attributes into a global context where sub-rules may grab them. This makes parser rules a little easier to write in some cases. */ static std::list*attributes_in_context = 0; /* Later version of bison (including 1.35) will not compile in stack extension if the output is compiled with C++ and either the YYSTYPE or YYLTYPE are provided by the source code. However, I can get the old behavior back by defining these symbols. */ # define YYSTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1 /* Recent version of bison expect that the user supply a YYLLOC_DEFAULT macro that makes up a yylloc value from existing values. I need to supply an explicit version to account for the text field, that otherwise won't be copied. The YYLLOC_DEFAULT blends the file range for the tokens of Rhs rule, which has N tokens. */ # define YYLLOC_DEFAULT(Current, Rhs, N) do { \ if (N) { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ (Current).text = YYRHSLOC (Rhs, 1).text; \ } else { \ (Current).first_line = YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = YYRHSLOC (Rhs, 0).last_column; \ (Current).last_line = YYRHSLOC (Rhs, 0).last_line; \ (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \ (Current).text = YYRHSLOC (Rhs, 0).text; \ } \ } while (0) /* * These are some common strength pairs that are used as defaults when * the user is not otherwise specific. */ static const struct str_pair_t pull_strength = { IVL_DR_PULL, IVL_DR_PULL }; static const struct str_pair_t str_strength = { IVL_DR_STRONG, IVL_DR_STRONG }; static std::list* make_port_list(char*id, std::list*udims, PExpr*expr) { std::list*tmp = new std::list; tmp->push_back(pform_port_t(lex_strings.make(id), udims, expr)); delete[]id; return tmp; } static std::list* make_port_list(list*tmp, char*id, std::list*udims, PExpr*expr) { tmp->push_back(pform_port_t(lex_strings.make(id), udims, expr)); delete[]id; return tmp; } static std::list* list_from_identifier(char*id) { std::list*tmp = new std::list; tmp->push_back(lex_strings.make(id)); delete[]id; return tmp; } static std::list* list_from_identifier(list*tmp, char*id) { tmp->push_back(lex_strings.make(id)); delete[]id; return tmp; } template void append(vector&out, const std::vector&in) { for (size_t idx = 0 ; idx < in.size() ; idx += 1) out.push_back(in[idx]); } /* * Look at the list and pull null pointers off the end. */ static void strip_tail_items(list*lst) { while (! lst->empty()) { if (lst->back() != 0) return; lst->pop_back(); } } /* * This is a shorthand for making a PECallFunction that takes a single * arg. This is used by some of the code that detects built-ins. */ static PECallFunction*make_call_function(perm_string tn, PExpr*arg) { std::vector parms(1); parms[0] = arg; PECallFunction*tmp = new PECallFunction(tn, parms); return tmp; } static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) { std::vector parms(2); parms[0] = arg1; parms[1] = arg2; PECallFunction*tmp = new PECallFunction(tn, parms); return tmp; } static std::list* make_named_numbers(perm_string name, long first, long last, PExpr*val =0) { std::list*lst = new std::list; named_pexpr_t tmp; // We are counting up. if (first <= last) { for (long idx = first ; idx <= last ; idx += 1) { ostringstream buf; buf << name.str() << idx << ends; tmp.name = lex_strings.make(buf.str()); tmp.parm = val; val = 0; lst->push_back(tmp); } // We are counting down. } else { for (long idx = first ; idx >= last ; idx -= 1) { ostringstream buf; buf << name.str() << idx << ends; tmp.name = lex_strings.make(buf.str()); tmp.parm = val; val = 0; lst->push_back(tmp); } } return lst; } static std::list* make_named_number(perm_string name, PExpr*val =0) { std::list*lst = new std::list; named_pexpr_t tmp; tmp.name = name; tmp.parm = val; lst->push_back(tmp); return lst; } static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok) { long value = 1; // We can never have an undefined value in an enumeration name // declaration sequence. if (! arg->is_defined()) { yyerror(loc, "error: Undefined value used in enum name sequence."); // We can never have a negative value in an enumeration name // declaration sequence. } else if (arg->is_negative()) { yyerror(loc, "error: Negative value used in enum name sequence."); } else { value = arg->as_ulong(); // We cannot have a zero enumeration name declaration count. if (! zero_ok && (value == 0)) { yyerror(loc, "error: Zero count used in enum name sequence."); value = 1; } } return value; } static void check_end_label(const struct vlltype&loc, const char *type, const char *begin, const char *end) { if (!end) return; if (!begin) yyerror(loc, "error: Unnamed %s must not have end label.", type); else if (strcmp(begin, end) != 0) yyerror(loc, "error: %s end label `%s` doesn't match %s name" " `%s`.", type, end, type, begin); if (!gn_system_verilog()) yyerror(loc, "error: %s end label requires SystemVerilog.", type); delete[] end; } static void current_task_set_statement(const YYLTYPE&loc, std::vector*s) { if (s == 0) { /* if the statement list is null, then the parser detected the case that there are no statements in the task. If this is SystemVerilog, handle it as an an empty block. */ pform_requires_sv(loc, "Task body with no statements"); PBlock*tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, loc); current_task->set_statement(tmp); return; } assert(s); /* An empty vector represents one or more null statements. Handle this as a simple null statement. */ if (s->empty()) return; /* A vector of 1 is handled as a simple statement. */ if (s->size() == 1) { current_task->set_statement((*s)[0]); return; } pform_requires_sv(loc, "Task body with multiple statements"); PBlock*tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, loc); tmp->set_statement(*s); current_task->set_statement(tmp); } static void current_function_set_statement(const YYLTYPE&loc, std::vector*s) { if (s == 0) { /* if the statement list is null, then the parser detected the case that there are no statements in the task. If this is SystemVerilog, handle it as an an empty block. */ pform_requires_sv(loc, "Function body with no statements"); PBlock*tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, loc); current_function->set_statement(tmp); return; } assert(s); /* An empty vector represents one or more null statements. Handle this as a simple null statement. */ if (s->empty()) return; /* A vector of 1 is handled as a simple statement. */ if (s->size() == 1) { current_function->set_statement((*s)[0]); return; } pform_requires_sv(loc, "Function body with multiple statements"); PBlock*tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, loc); tmp->set_statement(*s); current_function->set_statement(tmp); } %} %union { bool flag; char letter; int int_val; enum atom_type_t::type_code atom_type; /* text items are C strings allocated by the lexor using strdup. They can be put into lists with the texts type. */ char*text; std::list*perm_strings; std::list*port_list; std::vector* tf_ports; pform_name_t*pform_name; ivl_discipline_t discipline; hname_t*hier; std::list*strings; struct str_pair_t drive; PCase::Item*citem; std::vector*citems; lgate*gate; std::vector*gates; Module::port_t *mport; LexicalScope::range_t* value_range; std::vector*mports; std::list*let_port_lst; PLet::let_port_t*let_port_itm; named_number_t* named_number; std::list* named_numbers; named_pexpr_t*named_pexpr; std::list*named_pexprs; struct parmvalue_t*parmvalue; std::list*ranges; PExpr*expr; std::list*exprs; PEEvent*event_expr; std::vector*event_exprs; ivl_case_quality_t case_quality; NetNet::Type nettype; PGBuiltin::Type gatetype; NetNet::PortType porttype; ivl_variable_type_t vartype; PBlock::BL_TYPE join_keyword; PWire*wire; std::vector*wires; PCallTask *subroutine_call; PEventStatement*event_statement; Statement*statement; std::vector*statement_list; decl_assignment_t*decl_assignment; std::list*decl_assignments; struct_member_t*struct_member; std::list*struct_members; struct_type_t*struct_type; data_type_t*data_type; class_type_t*class_type; real_type_t::type_t real_type; property_qualifier_t property_qualifier; PPackage*package; struct { char*text; typedef_t*type; } type_identifier; struct { data_type_t*type; std::list*exprs; } class_declaration_extends; struct { char*text; PExpr*expr; } genvar_iter; struct { bool packed_flag; bool signed_flag; } packed_signing; verinum* number; verireal* realtime; PSpecPath* specpath; std::list *dimensions; LexicalScope::lifetime_t lifetime; enum typedef_t::basic_type typedef_basic_type; }; %token IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL %token TYPE_IDENTIFIER %token PACKAGE_IDENTIFIER %token DISCIPLINE_IDENTIFIER %token PATHPULSE_IDENTIFIER %token BASED_NUMBER DEC_NUMBER UNBASED_NUMBER %token REALTIME %token K_PLUS_EQ K_MINUS_EQ K_INCR K_DECR %token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_WEQ K_WNE K_LP K_LS K_RS K_RSS K_SG /* K_CONTRIBUTE is <+, the contribution assign. */ %token K_CONTRIBUTE %token K_PO_POS K_PO_NEG K_POW %token K_PSTAR K_STARP K_DOTSTAR %token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER K_NB_TRIGGER K_LEQUIV %token K_SCOPE_RES %token K_edge_descriptor %token K_CONSTRAINT_IMPL /* The base tokens from 1364-1995. */ %token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case %token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable %token K_edge K_else K_end K_endcase K_endfunction K_endmodule %token K_endprimitive K_endspecify K_endtable K_endtask K_event K_for %token K_force K_forever K_fork K_function K_highz0 K_highz1 K_if %token K_ifnone K_initial K_inout K_input K_integer K_join K_large %token K_macromodule K_medium K_module K_nand K_negedge K_nmos K_nor %token K_not K_notif0 K_notif1 K_or K_output K_parameter K_pmos K_posedge %token K_primitive K_pull0 K_pull1 K_pulldown K_pullup K_rcmos K_real %token K_realtime K_reg K_release K_repeat K_rnmos K_rpmos K_rtran %token K_rtranif0 K_rtranif1 K_scalared K_small K_specify K_specparam %token K_strong0 K_strong1 K_supply0 K_supply1 K_table K_task K_time %token K_tran K_tranif0 K_tranif1 K_tri K_tri0 K_tri1 K_triand K_trior %token K_trireg K_vectored K_wait K_wand K_weak0 K_weak1 K_while K_wire %token K_wor K_xnor K_xor %token K_Shold K_Snochange K_Speriod K_Srecovery K_Ssetup K_Ssetuphold %token K_Sskew K_Swidth /* Icarus specific tokens. */ %token KK_attribute K_bool K_logic /* The new tokens from 1364-2001. */ %token K_automatic K_endgenerate K_generate K_genvar K_localparam %token K_noshowcancelled K_pulsestyle_onevent K_pulsestyle_ondetect %token K_showcancelled K_signed K_unsigned %token K_Sfullskew K_Srecrem K_Sremoval K_Stimeskew /* The 1364-2001 configuration tokens. */ %token K_cell K_config K_design K_endconfig K_incdir K_include K_instance %token K_liblist K_library K_use /* The new tokens from 1364-2005. */ %token K_wone K_uwire /* The new tokens from 1800-2005. */ %token K_alias K_always_comb K_always_ff K_always_latch K_assert %token K_assume K_before K_bind K_bins K_binsof K_bit K_break K_byte %token K_chandle K_class K_clocking K_const K_constraint K_context %token K_continue K_cover K_covergroup K_coverpoint K_cross K_dist K_do %token K_endclass K_endclocking K_endgroup K_endinterface K_endpackage %token K_endprogram K_endproperty K_endsequence K_enum K_expect K_export %token K_extends K_extern K_final K_first_match K_foreach K_forkjoin %token K_iff K_ignore_bins K_illegal_bins K_import K_inside K_int /* Icarus already has defined "logic" above! */ %token K_interface K_intersect K_join_any K_join_none K_local %token K_longint K_matches K_modport K_new K_null K_package K_packed %token K_priority K_program K_property K_protected K_pure K_rand K_randc %token K_randcase K_randsequence K_ref K_return K_sequence K_shortint %token K_shortreal K_solve K_static K_string K_struct K_super %token K_tagged K_this K_throughout K_timeprecision K_timeunit K_type %token K_typedef K_union K_unique K_var K_virtual K_void K_wait_order %token K_wildcard K_with K_within /* The new tokens from 1800-2009. */ %token K_accept_on K_checker K_endchecker K_eventually K_global K_implies %token K_let K_nexttime K_reject_on K_restrict K_s_always K_s_eventually %token K_s_nexttime K_s_until K_s_until_with K_strong K_sync_accept_on %token K_sync_reject_on K_unique0 K_until K_until_with K_untyped K_weak /* The new tokens from 1800-2012. */ %token K_implements K_interconnect K_nettype K_soft /* The new tokens for Verilog-AMS 2.3. */ %token K_above K_abs K_absdelay K_abstol K_access K_acos K_acosh /* 1800-2005 has defined "assert" above! */ %token K_ac_stim K_aliasparam K_analog K_analysis K_asin K_asinh %token K_atan K_atan2 K_atanh K_branch K_ceil K_connect K_connectmodule %token K_connectrules K_continuous K_cos K_cosh K_ddt K_ddt_nature K_ddx %token K_discipline K_discrete K_domain K_driver_update K_endconnectrules %token K_enddiscipline K_endnature K_endparamset K_exclude K_exp %token K_final_step K_flicker_noise K_floor K_flow K_from K_ground %token K_hypot K_idt K_idtmod K_idt_nature K_inf K_initial_step %token K_laplace_nd K_laplace_np K_laplace_zd K_laplace_zp %token K_last_crossing K_limexp K_ln K_log K_max K_merged K_min K_nature %token K_net_resolution K_noise_table K_paramset K_potential K_pow /* 1800-2005 has defined "string" above! */ %token K_resolveto K_sin K_sinh K_slew K_split K_sqrt K_tan K_tanh %token K_timer K_transition K_units K_white_noise K_wreal %token K_zi_nd K_zi_np K_zi_zd K_zi_zp %type from_exclude block_item_decls_opt %type number pos_neg_number %type signing unsigned_signed_opt signed_unsigned_opt %type import_export %type K_genvar_opt K_static_opt K_virtual_opt %type udp_reg_opt edge_operator %type drive_strength drive_strength_opt dr_strength0 dr_strength1 %type udp_input_sym udp_output_sym %type udp_input_list udp_sequ_entry udp_comb_entry %type udp_input_declaration_list %type udp_entry_list udp_comb_entry_list udp_sequ_entry_list %type udp_body %type udp_port_list %type udp_port_decl udp_port_decls %type udp_initial udp_init_opt %type net_variable %type net_variable_list %type event_variable label_opt class_declaration_endlabel_opt %type block_identifier_opt %type identifier_name %type event_variable_list %type list_of_identifiers loop_variables %type list_of_port_identifiers list_of_variable_port_identifiers %type net_decl_assigns %type net_decl_assign %type port port_opt port_reference port_reference_list %type port_declaration %type list_of_ports module_port_list_opt list_of_port_declarations module_attribute_foreign %type parameter_value_range parameter_value_ranges %type parameter_value_ranges_opt %type value_range_expression %type enum_name_list enum_name %type enum_data_type enum_base_type %type tf_item_declaration tf_item_list tf_item_list_opt %type tf_port_declaration tf_port_item tf_port_item_list %type tf_port_list tf_port_list_opt tf_port_list_parens_opt %type modport_simple_port port_name parameter_value_byname %type port_name_list parameter_value_byname_list %type port_conn_expression_list_with_nuls %type attribute %type attribute_list attribute_instance_list attribute_list_opt %type case_item %type case_items %type gate_instance %type gate_instance_list %type let_port_list_opt let_port_list %type let_port_item %type hierarchy_identifier implicit_class_handle class_hierarchy_identifier %type assignment_pattern expression expr_mintypmax %type expr_primary_or_typename expr_primary %type class_new dynamic_array_new %type var_decl_initializer_opt initializer_opt %type inc_or_dec_expression inside_expression lpvalue %type branch_probe_expression streaming_concatenation %type delay_value delay_value_simple %type delay1 delay3 delay3_opt delay_value_list %type expression_list_with_nuls expression_list_proper %type argument_list_parens_opt %type cont_assign cont_assign_list %type variable_decl_assignment %type list_of_variable_decl_assignments %type data_type data_type_opt data_type_or_implicit data_type_or_implicit_or_void %type simple_type_or_string let_formal_type %type packed_array_data_type %type ps_type_identifier %type simple_packed_type %type class_scope %type struct_union_member %type struct_union_member_list %type struct_data_type %type packed_signing %type class_declaration_extends_opt %type class_item_qualifier property_qualifier %type class_item_qualifier_list property_qualifier_list %type class_item_qualifier_opt property_qualifier_opt %type random_qualifier %type variable_dimension %type dimensions_opt dimensions %type net_type net_type_opt net_type_or_var net_type_or_var_opt %type gatetype switchtype %type port_direction port_direction_opt %type integer_vector_type %type parameter_value_opt %type event_expression_list %type event_expression %type event_control %type statement statement_item statement_or_null %type compressed_statement %type loop_statement for_step for_step_opt jump_statement %type concurrent_assertion_statement %type deferred_immediate_assertion_statement %type simple_immediate_assertion_statement %type procedural_assertion_statement %type statement_or_null_list statement_or_null_list_opt %type analog_statement %type subroutine_call %type join_keyword %type spec_polarity %type specify_path_identifiers %type specify_simple_path specify_simple_path_decl %type specify_edge_path specify_edge_path_decl %type non_integer_type %type assert_or_assume %type deferred_mode %type atom_type %type module_start module_end %type lifetime lifetime_opt %type unique_priority %type genvar_iteration %type package_scope %type compressed_operator %type typedef_basic_type %token K_TAND %nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ %nonassoc K_XOR_EQ K_LS_EQ K_RS_EQ K_RSS_EQ K_NB_TRIGGER %right K_TRIGGER K_LEQUIV %right '?' ':' K_inside %left K_LOR %left K_LAND %left '|' %left '^' K_NXOR K_NOR %left '&' K_NAND %left K_EQ K_NE K_CEQ K_CNE K_WEQ K_WNE %left K_GE K_LE '<' '>' %left K_LS K_RS K_RSS %left '+' '-' %left '*' '/' '%' %left K_POW %left UNARY_PREC /* to resolve dangling else ambiguity. */ %nonassoc less_than_K_else %nonassoc K_else /* to resolve exclude (... ambiguity */ %nonassoc '(' %nonassoc K_exclude /* to resolve timeunits declaration/redeclaration ambiguity */ %nonassoc no_timeunits_declaration %nonassoc one_timeunits_declaration %nonassoc K_timeunit K_timeprecision %% /* IEEE1800-2005: A.1.2 */ /* source_text ::= [ timeunits_declaration ] { description } */ source_text : timeunits_declaration_opt { pform_set_scope_timescale(yyloc); } description_list | /* empty */ ; assert_or_assume : K_assert { $$ = 1; } /* IEEE1800-2012: Table 20-7 */ | K_assume { $$ = 4; } /* IEEE1800-2012: Table 20-7 */ ; assertion_item /* IEEE1800-2012: A.6.10 */ : concurrent_assertion_item | deferred_immediate_assertion_item ; assignment_pattern /* IEEE1800-2005: A.6.7.1 */ : K_LP expression_list_proper '}' { PEAssignPattern*tmp = new PEAssignPattern(*$2); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } | K_LP '}' { PEAssignPattern*tmp = new PEAssignPattern; FILE_NAME(tmp, @1); $$ = tmp; } ; /* Some rules have a ... [ block_identifier ':' ] ... part. This implements it in a LALR way. */ block_identifier_opt /* */ : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; } ; class_declaration /* IEEE1800-2005: A.1.2 */ : K_virtual_opt K_class lifetime_opt identifier_name class_declaration_extends_opt ';' { /* Up to 1800-2017 the grammar in the LRM allowed an optional lifetime * qualifier for class declarations. But the LRM never specified what * this qualifier should do. Starting with 1800-2023 the qualifier has * been removed from the grammar. Allow it for backwards compatibility, * but print a warning. */ if ($3 != LexicalScope::INHERITED) { cerr << @1 << ": warning: Class lifetime qualifier is deprecated " "and has no effect." << endl; warn_count += 1; } perm_string name = lex_strings.make($4); class_type_t *class_type= new class_type_t(name); FILE_NAME(class_type, @4); pform_set_typedef(@4, name, class_type, nullptr); pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $1); } class_items_opt K_endclass { // Process a class. pform_end_class_declaration(@9); } class_declaration_endlabel_opt { // Wrap up the class. check_end_label(@11, "class", $4, $11); delete[] $4; } ; class_constraint /* IEEE1800-2005: A.1.8 */ : constraint_prototype | constraint_declaration ; // This is used in places where a new type can be declared or an existig type // is referenced. E.g. typedefs. identifier_name : IDENTIFIER { $$ = $1; } | TYPE_IDENTIFIER { $$ = $1.text; } ; /* The endlabel after a class declaration is a little tricky because the class name is detected by the lexor as a TYPE_IDENTIFIER if it does indeed match a name. */ class_declaration_endlabel_opt : ':' identifier_name { $$ = $2; } | { $$ = 0; } ; /* This rule implements [ extends class_type ] in the class_declaration. It is not a rule of its own in the LRM. Note that for this to be correct, the identifier after the extends keyword must be a class name. Therefore, match TYPE_IDENTIFIER instead of IDENTIFIER, and this rule will return a data_type. */ class_declaration_extends_opt /* IEEE1800-2005: A.1.2 */ : K_extends ps_type_identifier argument_list_parens_opt { $$.type = $2; $$.exprs = $3; } | { $$.type = 0; $$.exprs = 0; } ; /* The class_items_opt and class_items rules together implement the rule snippet { class_item } (zero or more class_item) of the class_declaration. */ class_items_opt /* IEEE1800-2005: A.1.2 */ : class_items | ; class_items /* IEEE1800-2005: A.1.2 */ : class_items class_item | class_item ; class_item /* IEEE1800-2005: A.1.8 */ /* IEEE1800 A.1.8: class_constructor_declaration */ : method_qualifier_opt K_function K_new { assert(current_function==0); current_function = pform_push_constructor_scope(@3); } tf_port_list_parens_opt ';' block_item_decls_opt statement_or_null_list_opt K_endfunction endnew_opt { current_function->set_ports($5); pform_set_constructor_return(current_function); pform_set_this_class(@3, current_function); current_function_set_statement(@3, $8); pform_pop_scope(); current_function = 0; } /* IEEE1800-2017: A.1.9 Class items: Class properties... */ | property_qualifier_opt data_type list_of_variable_decl_assignments ';' { pform_class_property(@2, $1, $2, $3); } | K_const class_item_qualifier_opt data_type list_of_variable_decl_assignments ';' { pform_class_property(@1, $2 | property_qualifier_t::make_const(), $3, $4); } /* IEEEE1800-2017: A.1.9 Class items: class_item ::= { property_qualifier} data_declaration */ /* TODO: Restrict the access based on the property qualifier. */ | property_qualifier_opt type_declaration /* IEEE1800-1017: A.1.9 Class items: Class methods... */ | method_qualifier_opt task_declaration { /* The task_declaration rule puts this into the class */ } | method_qualifier_opt function_declaration { /* The function_declaration rule puts this into the class */ } /* External class method definitions... */ | K_extern method_qualifier_opt K_function K_new tf_port_list_parens_opt ';' { yyerror(@1, "sorry: External constructors are not yet supported."); } | K_extern method_qualifier_opt K_function data_type_or_implicit_or_void IDENTIFIER tf_port_list_parens_opt ';' { yyerror(@1, "sorry: External methods are not yet supported."); delete[] $5; } | K_extern method_qualifier_opt K_task IDENTIFIER tf_port_list_parens_opt ';' { yyerror(@1, "sorry: External methods are not yet supported."); delete[] $4; } /* Class constraints... */ | class_constraint /* Here are some error matching rules to help recover from various syntax errors within a class declaration. */ | property_qualifier_opt data_type error ';' { yyerror(@3, "error: Errors in variable names after data type."); yyerrok; } | property_qualifier_opt IDENTIFIER error ';' { yyerror(@3, "error: %s doesn't name a type.", $2); yyerrok; } | method_qualifier_opt K_function K_new error K_endfunction endnew_opt { yyerror(@1, "error: I give up on this class constructor declaration."); yyerrok; } | parameter_declaration /* Empty class item */ | ';' | error ';' { yyerror(@2, "error: Invalid class item."); yyerrok; } ; class_item_qualifier /* IEEE1800-2005 A.1.8 */ : K_static { $$ = property_qualifier_t::make_static(); } | K_protected { $$ = property_qualifier_t::make_protected(); } | K_local { $$ = property_qualifier_t::make_local(); } ; class_item_qualifier_list : class_item_qualifier_list class_item_qualifier { $$ = $1 | $2; } | class_item_qualifier { $$ = $1; } ; class_item_qualifier_opt : class_item_qualifier_list { $$ = $1; } | { $$ = property_qualifier_t::make_none(); } ; class_scope : ps_type_identifier K_SCOPE_RES { $$ = $1; } class_new /* IEEE1800-2005 A.2.4 */ : K_new argument_list_parens_opt { std::list*expr_list = $2; strip_tail_items(expr_list); PENewClass*tmp = new PENewClass(*expr_list); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } // This can't be a class_scope_opt because it will lead to shift/reduce // conflicts with array_new | class_scope K_new argument_list_parens_opt { std::list*expr_list = $3; strip_tail_items(expr_list); PENewClass *new_expr = new PENewClass(*expr_list, $1); FILE_NAME(new_expr, @2); delete $3; $$ = new_expr; } | K_new hierarchy_identifier { PEIdent*tmpi = new PEIdent(*$2); FILE_NAME(tmpi, @2); PENewCopy*tmp = new PENewCopy(tmpi); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } ; /* The concurrent_assertion_item pulls together the concurrent_assertion_statement and checker_instantiation rules. */ concurrent_assertion_item /* IEEE1800-2012 A.2.10 */ : block_identifier_opt concurrent_assertion_statement { delete $1; delete $2; } ; concurrent_assertion_statement /* IEEE1800-2012 A.2.10 */ : assert_or_assume K_property '(' property_spec ')' statement_or_null %prec less_than_K_else { /* */ if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } | assert_or_assume K_property '(' property_spec ')' K_else statement_or_null { /* */ if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } | assert_or_assume K_property '(' property_spec ')' statement_or_null K_else statement_or_null { /* */ if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } | K_cover K_property '(' property_spec ')' statement_or_null { /* */ if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } /* For now, cheat, and use property_spec for the sequence specification. They are syntactically identical. */ | K_cover K_sequence '(' property_spec ')' statement_or_null { /* */ if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } | K_restrict K_property '(' property_spec ')' ';' { /* */ if (gn_unsupported_assertions_flag) { yyerror(@2, "sorry: concurrent_assertion_item not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } $$ = 0; } | assert_or_assume K_property '(' error ')' statement_or_null %prec less_than_K_else { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } | assert_or_assume K_property '(' error ')' K_else statement_or_null { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } | assert_or_assume K_property '(' error ')' statement_or_null K_else statement_or_null { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } | K_cover K_property '(' error ')' statement_or_null { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } | K_cover K_sequence '(' error ')' statement_or_null { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } | K_restrict K_property '(' error ')' ';' { yyerrok; yyerror(@2, "error: Error in property_spec of concurrent assertion item."); $$ = 0; } ; constraint_block_item /* IEEE1800-2005 A.1.9 */ : constraint_expression ; constraint_block_item_list : constraint_block_item_list constraint_block_item | constraint_block_item ; constraint_block_item_list_opt : | constraint_block_item_list ; constraint_declaration /* IEEE1800-2005: A.1.9 */ : K_static_opt K_constraint IDENTIFIER '{' constraint_block_item_list_opt '}' { yyerror(@2, "sorry: Constraint declarations not supported."); } /* Error handling rules... */ | K_static_opt K_constraint IDENTIFIER '{' error '}' { yyerror(@4, "error: Errors in the constraint block item list."); } ; constraint_expression /* IEEE1800-2005 A.1.9 */ : expression ';' | expression K_dist '{' '}' ';' | expression constraint_trigger | K_if '(' expression ')' constraint_set %prec less_than_K_else | K_if '(' expression ')' constraint_set K_else constraint_set | K_foreach '(' IDENTIFIER '[' loop_variables ']' ')' constraint_set ; constraint_trigger : K_CONSTRAINT_IMPL '{' constraint_expression_list '}' ; constraint_expression_list /* */ : constraint_expression_list constraint_expression | constraint_expression ; constraint_prototype /* IEEE1800-2005: A.1.9 */ : K_static_opt K_constraint IDENTIFIER ';' { yyerror(@2, "sorry: Constraint prototypes not supported."); } ; constraint_set /* IEEE1800-2005 A.1.9 */ : constraint_expression | '{' constraint_expression_list '}' ; data_declaration /* IEEE1800-2005: A.2.1.3 */ : attribute_list_opt data_type list_of_variable_decl_assignments ';' { data_type_t*data_type = $2; if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @2); } pform_makewire(@2, 0, str_strength, $3, NetNet::IMPLICIT_REG, data_type, $1); } | attribute_list_opt K_var data_type_or_implicit list_of_variable_decl_assignments ';' { data_type_t*data_type = $3; if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @2); } pform_make_var(@2, $4, data_type, $1); } | attribute_list_opt K_event event_variable_list ';' { if ($3) pform_make_events(@2, $3); } | attribute_list_opt package_import_declaration ; package_scope : PACKAGE_IDENTIFIER K_SCOPE_RES { lex_in_package_scope($1); $$ = $1; } ; ps_type_identifier /* IEEE1800-2017: A.9.3 */ : TYPE_IDENTIFIER { pform_set_type_referenced(@1, $1.text); delete[]$1.text; $$ = new typeref_t($1.type); FILE_NAME($$, @1); } | package_scope TYPE_IDENTIFIER { lex_in_package_scope(0); $$ = new typeref_t($2.type, $1); FILE_NAME($$, @2); delete[] $2.text; } ; /* Data types that can have packed dimensions directly attached to it */ packed_array_data_type /* IEEE1800-2005: A.2.2.1 */ : enum_data_type { $$ = $1; } | struct_data_type { if (!$1->packed_flag) { yyerror(@1, "sorry: Unpacked structs not supported."); } $$ = $1; } | ps_type_identifier ; simple_packed_type /* Integer and vector types */ : integer_vector_type unsigned_signed_opt dimensions_opt { vector_type_t*tmp = new vector_type_t($1, $2, $3); FILE_NAME(tmp, @1); $$ = tmp; } | atom_type signed_unsigned_opt { atom_type_t*tmp = new atom_type_t($1, $2); FILE_NAME(tmp, @1); $$ = tmp; } | K_time unsigned_signed_opt { atom_type_t*tmp = new atom_type_t(atom_type_t::TIME, $2); FILE_NAME(tmp, @1); $$ = tmp; } ; data_type /* IEEE1800-2005: A.2.2.1 */ : simple_packed_type { $$ = $1; } | non_integer_type { real_type_t*tmp = new real_type_t($1); FILE_NAME(tmp, @1); $$ = tmp; } | packed_array_data_type dimensions_opt { if ($2) { parray_type_t*tmp = new parray_type_t($1, $2); FILE_NAME(tmp, @1); $$ = tmp; } else { $$ = $1; } } | K_string { string_type_t*tmp = new string_type_t; FILE_NAME(tmp, @1); $$ = tmp; } ; /* Data type or nothing, but not implicit */ data_type_opt : data_type { $$ = $1; } | { $$ = 0; } /* The data_type_or_implicit rule is a little more complex then the rule documented in the IEEE format syntax in order to allow for signaling the special case that the data_type is completely absent. The context may need that information to decide to resort to left context. */ scalar_vector_opt /*IEEE1800-2005: optional support for packed array */ : K_vectored { /* Ignore */ } | K_scalared { /* Ignore */ } | { /* Ignore */ } ; data_type_or_implicit /* IEEE1800-2005: A.2.2.1 */ : data_type_opt { $$ = $1; } | signing dimensions_opt { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2); tmp->implicit_flag = true; FILE_NAME(tmp, @1); $$ = tmp; } | scalar_vector_opt dimensions { vector_type_t*tmp = new vector_type_t(IVL_VT_LOGIC, false, $2); tmp->implicit_flag = true; FILE_NAME(tmp, @2); $$ = tmp; } ; data_type_or_implicit_or_void : data_type_or_implicit { $$ = $1; } | K_void { void_type_t*tmp = new void_type_t; FILE_NAME(tmp, @1); $$ = tmp; } ; deferred_immediate_assertion_item /* IEEE1800-2012: A.6.10 */ : block_identifier_opt deferred_immediate_assertion_statement { delete $1; delete $2; } ; deferred_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */ : assert_or_assume deferred_mode '(' expression ')' statement_or_null %prec less_than_K_else { if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: Deferred assertions are not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } delete $4; delete $6; $$ = 0; } | assert_or_assume deferred_mode '(' expression ')' K_else statement_or_null { if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: Deferred assertions are not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } delete $4; delete $7; $$ = 0; } | assert_or_assume deferred_mode '(' expression ')' statement_or_null K_else statement_or_null { if (gn_unsupported_assertions_flag) { yyerror(@1, "sorry: Deferred assertions are not supported." " Try -gno-assertions or -gsupported-assertions" " to turn this message off."); } delete $4; delete $6; delete $8; $$ = 0; } | K_cover deferred_mode '(' expression ')' statement_or_null { /* Coverage collection is not currently supported. */ delete $4; delete $6; $$ = 0; } | assert_or_assume deferred_mode '(' error ')' statement_or_null %prec less_than_K_else { yyerror(@1, "error: Malformed conditional expression."); $$ = $6; } | assert_or_assume deferred_mode '(' error ')' K_else statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $7; } | assert_or_assume deferred_mode '(' error ')' statement_or_null K_else statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $6; } | K_cover deferred_mode '(' error ')' statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $6; } ; deferred_mode : '#' DEC_NUMBER { if (!$2->is_zero()) { yyerror(@2, "error: Delay value must be zero for deferred assertion."); } delete $2; $$ = 0; } | K_final { $$ = 1; } ; /* NOTE: The "module" rule of the description combines the module_declaration, program_declaration, and interface_declaration rules from the standard description. */ description /* IEEE1800-2005: A.1.2 */ : module | udp_primitive | config_declaration | nature_declaration | package_declaration | discipline_declaration | package_item | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' { perm_string tmp3 = lex_strings.make($3); pform_set_type_attrib(tmp3, $5, $7); delete[] $3; delete[] $5; } | ';' { } ; description_list : description | description_list description ; /* This implements the [ : IDENTIFIER ] part of the constructor rule documented in IEEE1800-2005: A.1.8 */ endnew_opt : ':' K_new | ; /* The dynamic_array_new rule is kinda like an expression, but it is treated differently by rules that use this "expression". Watch out! */ dynamic_array_new /* IEEE1800-2005: A.2.4 */ : K_new '[' expression ']' { $$ = new PENewArray($3, 0); FILE_NAME($$, @1); } | K_new '[' expression ']' '(' expression ')' { $$ = new PENewArray($3, $6); FILE_NAME($$, @1); } ; for_step /* IEEE1800-2005: A.6.8 */ : lpvalue '=' expression { PAssign*tmp = new PAssign($1,$3); FILE_NAME(tmp, @1); $$ = tmp; } | inc_or_dec_expression { $$ = pform_compressed_assign_from_inc_dec(@1, $1); } | compressed_statement { $$ = $1; } ; for_step_opt : for_step { $$ = $1; } | { $$ = nullptr; } ; /* The function declaration rule matches the function declaration header, then pushes the function scope. This causes the definitions in the func_body to take on the scope of the function instead of the module. */ function_declaration /* IEEE1800-2005: A.2.6 */ : K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER ';' { assert(current_function == 0); current_function = pform_push_function_scope(@1, $4, $2); } tf_item_list_opt statement_or_null_list_opt K_endfunction { current_function->set_ports($7); current_function->set_return($3); current_function_set_statement($8? @8 : @4, $8); pform_set_this_class(@4, current_function); pform_pop_scope(); current_function = 0; } label_opt { // Last step: check any closing name. check_end_label(@11, "function", $4, $11); delete[]$4; } | K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER { assert(current_function == 0); current_function = pform_push_function_scope(@1, $4, $2); } '(' tf_port_list_opt ')' ';' block_item_decls_opt statement_or_null_list_opt K_endfunction { current_function->set_ports($7); current_function->set_return($3); current_function_set_statement($11? @11 : @4, $11); pform_set_this_class(@4, current_function); pform_pop_scope(); current_function = 0; if ($7 == 0) { pform_requires_sv(@4, "Empty parenthesis syntax"); } } label_opt { // Last step: check any closing name. check_end_label(@14, "function", $4, $14); delete[]$4; } /* Detect and recover from some errors. */ | K_function lifetime_opt data_type_or_implicit_or_void IDENTIFIER error K_endfunction { /* */ if (current_function) { pform_pop_scope(); current_function = 0; } assert(current_function == 0); yyerror(@1, "error: Syntax error defining function."); yyerrok; } label_opt { // Last step: check any closing name. check_end_label(@8, "function", $4, $8); delete[]$4; } ; genvar_iteration /* IEEE1800-2012: A.4.2 */ : IDENTIFIER '=' expression { $$.text = $1; $$.expr = $3; } | IDENTIFIER compressed_operator expression { $$.text = $1; $$.expr = pform_genvar_compressed(@1, $1, $2, $3);; } | IDENTIFIER K_INCR { $$.text = $1; $$.expr = pform_genvar_inc_dec(@1, $1, true); } | IDENTIFIER K_DECR { $$.text = $1; $$.expr = pform_genvar_inc_dec(@1, $1, false); } | K_INCR IDENTIFIER { $$.text = $2; $$.expr = pform_genvar_inc_dec(@1, $2, true); } | K_DECR IDENTIFIER { $$.text = $2; $$.expr = pform_genvar_inc_dec(@1, $2, false); } ; import_export /* IEEE1800-2012: A.2.9 */ : K_import { $$ = true; } | K_export { $$ = false; } ; implicit_class_handle /* IEEE1800-2005: A.8.4 */ : K_this '.' { $$ = pform_create_this(); } | K_super '.' { $$ = pform_create_super(); } | K_this '.' K_super '.' { $$ = pform_create_super(); } ; /* `this` or `super` followed by an identifier */ class_hierarchy_identifier : implicit_class_handle hierarchy_identifier { $1->splice($1->end(), *$2); delete $2; $$ = $1; } ; /* SystemVerilog adds support for the increment/decrement expressions, which look like a++, --a, etc. These are primaries but are in their own rules because they can also be statements. Note that the operator can only take l-value expressions. */ inc_or_dec_expression /* IEEE1800-2005: A.4.3 */ : K_INCR lpvalue %prec UNARY_PREC { PEUnary*tmp = new PEUnary('I', $2); FILE_NAME(tmp, @2); $$ = tmp; } | lpvalue K_INCR %prec UNARY_PREC { PEUnary*tmp = new PEUnary('i', $1); FILE_NAME(tmp, @1); $$ = tmp; } | K_DECR lpvalue %prec UNARY_PREC { PEUnary*tmp = new PEUnary('D', $2); FILE_NAME(tmp, @2); $$ = tmp; } | lpvalue K_DECR %prec UNARY_PREC { PEUnary*tmp = new PEUnary('d', $1); FILE_NAME(tmp, @1); $$ = tmp; } ; inside_expression /* IEEE1800-2005 A.8.3 */ : expression K_inside '{' open_range_list '}' { yyerror(@2, "sorry: \"inside\" expressions not supported yet."); $$ = 0; } ; integer_vector_type /* IEEE1800-2005: A.2.2.1 */ : K_reg { $$ = IVL_VT_LOGIC; } /* A synonym for logic. */ | K_bit { $$ = IVL_VT_BOOL; } | K_logic { $$ = IVL_VT_LOGIC; } | K_bool { $$ = IVL_VT_BOOL; } /* Icarus Verilog xtypes extension */ ; join_keyword /* IEEE1800-2005: A.6.3 */ : K_join { $$ = PBlock::BL_PAR; } | K_join_none { $$ = PBlock::BL_JOIN_NONE; } | K_join_any { $$ = PBlock::BL_JOIN_ANY; } ; jump_statement /* IEEE1800-2005: A.6.5 */ : K_break ';' { yyerror(@1, "sorry: break statements not supported."); $$ = 0; } | K_return ';' { PReturn*tmp = new PReturn(0); FILE_NAME(tmp, @1); $$ = tmp; } | K_return expression ';' { PReturn*tmp = new PReturn($2); FILE_NAME(tmp, @1); $$ = tmp; } ; lifetime /* IEEE1800-2005: A.2.1.3 */ : K_automatic { $$ = LexicalScope::AUTOMATIC; } | K_static { $$ = LexicalScope::STATIC; } ; lifetime_opt /* IEEE1800-2005: A.2.1.3 */ : lifetime { $$ = $1; } | { $$ = LexicalScope::INHERITED; } ; /* Loop statements are kinds of statements. */ loop_statement /* IEEE1800-2005: A.6.8 */ : K_for '(' lpvalue '=' expression ';' expression ';' for_step_opt ')' statement_or_null { PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11); FILE_NAME(tmp, @1); $$ = tmp; } // The initialization statement is optional. | K_for '(' ';' expression ';' for_step_opt ')' statement_or_null { PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8); FILE_NAME(tmp, @1); $$ = tmp; } // Handle for_variable_declaration syntax by wrapping the for(...) // statement in a synthetic named block. We can name the block // after the variable that we are creating, that identifier is // safe in the controlling scope. | K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression ';' for_step_opt ')' { static unsigned for_counter = 0; char for_block_name [64]; snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter); for_counter += 1; PBlock*tmp = pform_push_block_scope(@1, for_block_name, PBlock::BL_SEQ); current_block_stack.push(tmp); listassign_list; decl_assignment_t*tmp_assign = new decl_assignment_t; tmp_assign->name = lex_strings.make($5); assign_list.push_back(tmp_assign); pform_make_var(@5, &assign_list, $4); } statement_or_null { pform_name_t tmp_hident; tmp_hident.push_back(name_component_t(lex_strings.make($5))); PEIdent*tmp_ident = pform_new_ident(@5, tmp_hident); FILE_NAME(tmp_ident, @5); PForStatement*tmp_for = new PForStatement(tmp_ident, $7, $9, $11, $14); FILE_NAME(tmp_for, @1); pform_pop_scope(); vectortmp_for_list (1); tmp_for_list[0] = tmp_for; PBlock*tmp_blk = current_block_stack.top(); current_block_stack.pop(); tmp_blk->set_statement(tmp_for_list); $$ = tmp_blk; delete[]$5; } | K_forever statement_or_null { PForever*tmp = new PForever($2); FILE_NAME(tmp, @1); $$ = tmp; } | K_repeat '(' expression ')' statement_or_null { PRepeat*tmp = new PRepeat($3, $5); FILE_NAME(tmp, @1); $$ = tmp; } | K_while '(' expression ')' statement_or_null { PWhile*tmp = new PWhile($3, $5); FILE_NAME(tmp, @1); $$ = tmp; } | K_do statement_or_null K_while '(' expression ')' ';' { PDoWhile*tmp = new PDoWhile($5, $2); FILE_NAME(tmp, @1); $$ = tmp; } // When matching a foreach loop, implicitly create a named block // to hold the definitions for the index variables. | K_foreach '(' IDENTIFIER '[' loop_variables ']' ')' { static unsigned foreach_counter = 0; char for_block_name[64]; snprintf(for_block_name, sizeof for_block_name, "$ivl_foreach%u", foreach_counter); foreach_counter += 1; PBlock*tmp = pform_push_block_scope(@1, for_block_name, PBlock::BL_SEQ); current_block_stack.push(tmp); pform_make_foreach_declarations(@1, $5); } statement_or_null { PForeach*tmp_for = pform_make_foreach(@1, $3, $5, $9); pform_pop_scope(); vectortmp_for_list(1); tmp_for_list[0] = tmp_for; PBlock*tmp_blk = current_block_stack.top(); current_block_stack.pop(); tmp_blk->set_statement(tmp_for_list); $$ = tmp_blk; } /* Error forms for loop statements. */ | K_for '(' lpvalue '=' expression ';' expression ';' error ')' statement_or_null { $$ = 0; yyerror(@1, "error: Error in for loop step assignment."); } | K_for '(' lpvalue '=' expression ';' error ';' for_step_opt ')' statement_or_null { $$ = 0; yyerror(@1, "error: Error in for loop condition expression."); } | K_for '(' error ')' statement_or_null { $$ = 0; yyerror(@1, "error: Incomprehensible for loop."); } | K_while '(' error ')' statement_or_null { $$ = 0; yyerror(@1, "error: Error in while loop condition."); } | K_do statement_or_null K_while '(' error ')' ';' { $$ = 0; yyerror(@1, "error: Error in do/while loop condition."); } | K_foreach '(' IDENTIFIER '[' error ']' ')' statement_or_null { $$ = 0; yyerror(@4, "error: Errors in foreach loop variables list."); } ; list_of_variable_decl_assignments /* IEEE1800-2005 A.2.3 */ : variable_decl_assignment { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } | list_of_variable_decl_assignments ',' variable_decl_assignment { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } ; initializer_opt : '=' expression { $$ = $2; } | { $$ = nullptr; } ; var_decl_initializer_opt : initializer_opt | '=' class_new { $$ = $2; } | '=' dynamic_array_new { $$ = $2; } ; variable_decl_assignment /* IEEE1800-2005 A.2.3 */ : IDENTIFIER dimensions_opt var_decl_initializer_opt { if ($3 && pform_peek_scope()->var_init_needs_explicit_lifetime() && (var_lifetime == LexicalScope::INHERITED)) { cerr << @1 << ": warning: Static variable initialization requires " "explicit lifetime in this context." << endl; warn_count += 1; } decl_assignment_t*tmp = new decl_assignment_t; tmp->name = lex_strings.make($1); if ($2) { tmp->index = *$2; delete $2; } tmp->expr.reset($3); delete[]$1; $$ = tmp; } ; loop_variables /* IEEE1800-2005: A.6.8 */ : loop_variables ',' IDENTIFIER { std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); delete[]$3; $$ = tmp; } | loop_variables ',' { std::list*tmp = $1; tmp->push_back(perm_string()); $$ = tmp; } | IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } | { std::list*tmp = new std::list; tmp->push_back(perm_string()); $$ = tmp; } ; method_qualifier /* IEEE1800-2005: A.1.8 */ : K_virtual | class_item_qualifier ; method_qualifier_opt : method_qualifier | ; modport_declaration /* IEEE1800-2012: A.2.9 */ : K_modport { if (!pform_in_interface()) yyerror(@1, "error: modport declarations are only allowed " "in interfaces."); } modport_item_list ';' modport_item_list : modport_item | modport_item_list ',' modport_item ; modport_item : IDENTIFIER { pform_start_modport_item(@1, $1); } '(' modport_ports_list ')' { pform_end_modport_item(@1); } ; /* The modport_ports_list is a LALR(2) grammar. When the parser sees a ',' it needs to look ahead to the next token to decide whether it is a continuation of the preceding modport_ports_declaration, or the start of a new modport_ports_declaration. bison only supports LALR(1), so we have to handcraft a mini parser for this part of the syntax. last_modport_port holds the state for this mini parser.*/ modport_ports_list : modport_ports_declaration | modport_ports_list ',' modport_ports_declaration | modport_ports_list ',' modport_simple_port { if (last_modport_port.type == MP_SIMPLE) { pform_add_modport_port(@3, last_modport_port.direction, $3->name, $3->parm); } else { yyerror(@3, "error: modport expression not allowed here."); } delete $3; } | modport_ports_list ',' modport_tf_port { if (last_modport_port.type != MP_TF) yyerror(@3, "error: task/function declaration not allowed here."); } | modport_ports_list ',' IDENTIFIER { if (last_modport_port.type == MP_SIMPLE) { pform_add_modport_port(@3, last_modport_port.direction, lex_strings.make($3), 0); } else if (last_modport_port.type != MP_TF) { yyerror(@3, "error: List of identifiers not allowed here."); } delete[] $3; } | modport_ports_list ',' { yyerror(@2, "error: Superfluous comma in port declaration list."); } ; modport_ports_declaration : attribute_list_opt port_direction IDENTIFIER { last_modport_port.type = MP_SIMPLE; last_modport_port.direction = $2; pform_add_modport_port(@3, $2, lex_strings.make($3), 0); delete[] $3; delete $1; } | attribute_list_opt port_direction modport_simple_port { last_modport_port.type = MP_SIMPLE; last_modport_port.direction = $2; pform_add_modport_port(@3, $2, $3->name, $3->parm); delete $3; delete $1; } | attribute_list_opt import_export IDENTIFIER { last_modport_port.type = MP_TF; last_modport_port.is_import = $2; yyerror(@3, "sorry: modport task/function ports are not yet supported."); delete[] $3; delete $1; } | attribute_list_opt import_export modport_tf_port { last_modport_port.type = MP_TF; last_modport_port.is_import = $2; yyerror(@3, "sorry: modport task/function ports are not yet supported."); delete $1; } | attribute_list_opt K_clocking IDENTIFIER { last_modport_port.type = MP_CLOCKING; last_modport_port.direction = NetNet::NOT_A_PORT; yyerror(@3, "sorry: modport clocking declaration is not yet supported."); delete[] $3; delete $1; } ; modport_simple_port : '.' IDENTIFIER '(' expression ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($2); tmp->parm = $4; delete[]$2; $$ = tmp; } ; modport_tf_port : K_task IDENTIFIER tf_port_list_parens_opt | K_function data_type_or_implicit_or_void IDENTIFIER tf_port_list_parens_opt ; non_integer_type /* IEEE1800-2005: A.2.2.1 */ : K_real { $$ = real_type_t::REAL; } | K_realtime { $$ = real_type_t::REAL; } | K_shortreal { $$ = real_type_t::SHORTREAL; } ; number : BASED_NUMBER { $$ = $1; based_size = 0;} | DEC_NUMBER { $$ = $1; based_size = 0;} | DEC_NUMBER BASED_NUMBER { $$ = pform_verinum_with_size($1,$2, @2.text, @2.first_line); based_size = 0; } | UNBASED_NUMBER { $$ = $1; based_size = 0;} | DEC_NUMBER UNBASED_NUMBER { yyerror(@1, "error: Unbased SystemVerilog literal cannot have a size."); $$ = $1; based_size = 0;} ; open_range_list /* IEEE1800-2005 A.2.11 */ : open_range_list ',' value_range | value_range ; package_declaration /* IEEE1800-2005 A.1.2 */ : K_package lifetime_opt IDENTIFIER ';' { pform_start_package_declaration(@1, $3, $2); } timeunits_declaration_opt { pform_set_scope_timescale(@1); } package_item_list_opt K_endpackage label_opt { pform_end_package_declaration(@1); check_end_label(@10, "package", $3, $10); delete[]$3; } ; module_package_import_list_opt : | package_import_list ; package_import_list : package_import_declaration | package_import_list package_import_declaration ; package_import_declaration /* IEEE1800-2005 A.2.1.3 */ : K_import package_import_item_list ';' { } ; package_import_item : package_scope IDENTIFIER { lex_in_package_scope(0); pform_package_import(@1, $1, $2); delete[]$2; } | package_scope TYPE_IDENTIFIER { lex_in_package_scope(0); pform_package_import(@1, $1, $2.text); delete[]$2.text; } | package_scope '*' { lex_in_package_scope(0); pform_package_import(@1, $1, 0); } ; package_import_item_list : package_import_item_list',' package_import_item | package_import_item ; package_item /* IEEE1800-2005 A.1.10 */ : timeunits_declaration | parameter_declaration | type_declaration | function_declaration | task_declaration | data_declaration | class_declaration ; package_item_list : package_item_list package_item | package_item ; package_item_list_opt : package_item_list | ; port_direction /* IEEE1800-2005 A.1.3 */ : K_input { $$ = NetNet::PINPUT; } | K_output { $$ = NetNet::POUTPUT; } | K_inout { $$ = NetNet::PINOUT; } | K_ref { $$ = NetNet::PREF; if (!pform_requires_sv(@1, "Reference port (ref)")) { $$ = NetNet::PINPUT; } } ; /* port_direction_opt is used in places where the port direction is optional. The default direction is selected by the context, which needs to notice the PIMPLICIT direction. */ port_direction_opt : port_direction { $$ = $1; } | { $$ = NetNet::PIMPLICIT; } ; procedural_assertion_statement /* IEEE1800-2012 A.6.10 */ : concurrent_assertion_statement { $$ = $1; } | simple_immediate_assertion_statement { $$ = $1; } | deferred_immediate_assertion_statement { $$ = $1; } ; property_expr /* IEEE1800-2012 A.2.10 */ : expression ; /* The property_qualifier rule is as literally described in the LRM, but the use is usually as { property_qualifier }, which is implemented by the property_qualifier_opt rule below. */ property_qualifier /* IEEE1800-2005 A.1.8 */ : class_item_qualifier | random_qualifier ; property_qualifier_opt /* IEEE1800-2005 A.1.8: ... { property_qualifier } */ : property_qualifier_list { $$ = $1; } | { $$ = property_qualifier_t::make_none(); } ; property_qualifier_list /* IEEE1800-2005 A.1.8 */ : property_qualifier_list property_qualifier { $$ = $1 | $2; } | property_qualifier { $$ = $1; } ; /* The property_spec rule uses some helper rules to implement this rule from the LRM: [ clocking_event ] [ disable iff ( expression_or_dist ) ] property_expr This does it is a YACC friendly way. */ property_spec /* IEEE1800-2012 A.2.10 */ : clocking_event_opt property_spec_disable_iff_opt property_expr ; property_spec_disable_iff_opt /* */ : K_disable K_iff '(' expression ')' | ; random_qualifier /* IEEE1800-2005 A.1.8 */ : K_rand { $$ = property_qualifier_t::make_rand(); } | K_randc { $$ = property_qualifier_t::make_randc(); } ; signing /* IEEE1800-2005: A.2.2.1 */ : K_signed { $$ = true; } | K_unsigned { $$ = false; } ; simple_immediate_assertion_statement /* IEEE1800-2012 A.6.10 */ : assert_or_assume '(' expression ')' statement_or_null %prec less_than_K_else { if (gn_supported_assertions_flag) { std::listarg_list; PCallTask*tmp1 = new PCallTask(lex_strings.make("$error"), arg_list); FILE_NAME(tmp1, @1); PCondit*tmp2 = new PCondit($3, $5, tmp1); FILE_NAME(tmp2, @1); $$ = tmp2; } else { delete $3; delete $5; $$ = 0; } } | assert_or_assume '(' expression ')' K_else statement_or_null { if (gn_supported_assertions_flag) { PCondit*tmp = new PCondit($3, 0, $6); FILE_NAME(tmp, @1); $$ = tmp; } else { delete $3; delete $6; $$ = 0; } } | assert_or_assume '(' expression ')' statement_or_null K_else statement_or_null { if (gn_supported_assertions_flag) { PCondit*tmp = new PCondit($3, $5, $7); FILE_NAME(tmp, @1); $$ = tmp; } else { delete $3; delete $5; delete $7; $$ = 0; } } | K_cover '(' expression ')' statement_or_null { /* Coverage collection is not currently supported. */ delete $3; delete $5; $$ = 0; } | assert_or_assume '(' error ')' statement_or_null %prec less_than_K_else { yyerror(@1, "error: Malformed conditional expression."); $$ = $5; } | assert_or_assume '(' error ')' K_else statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $6; } | assert_or_assume '(' error ')' statement_or_null K_else statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $5; } | K_cover '(' error ')' statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $5; } ; simple_type_or_string /* IEEE1800-2005: A.2.2.1 */ : integer_vector_type { vector_type_t*tmp = new vector_type_t($1, false, 0); FILE_NAME(tmp, @1); $$ = tmp; } | non_integer_type { real_type_t*tmp = new real_type_t($1); FILE_NAME(tmp, @1); $$ = tmp; } | atom_type { atom_type_t*tmp = new atom_type_t($1, true); FILE_NAME(tmp, @1); $$ = tmp; } | K_time { atom_type_t*tmp = new atom_type_t(atom_type_t::TIME, false); FILE_NAME(tmp, @1); $$ = tmp; } | K_string { string_type_t*tmp = new string_type_t; FILE_NAME(tmp, @1); $$ = tmp; } | ps_type_identifier ; statement /* IEEE1800-2005: A.6.4 */ : attribute_list_opt statement_item { pform_bind_attributes($2->attributes, $1); $$ = $2; } ; /* Many places where statements are allowed can actually take a statement or a null statement marked with a naked semi-colon. */ statement_or_null /* IEEE1800-2005: A.6.4 */ : statement { $$ = $1; } | attribute_list_opt ';' { $$ = 0; } ; stream_expression : expression ; stream_expression_list : stream_expression_list ',' stream_expression | stream_expression ; stream_operator : K_LS | K_RS ; streaming_concatenation /* IEEE1800-2005: A.8.1 */ : '{' stream_operator '{' stream_expression_list '}' '}' { /* streaming concatenation is a SystemVerilog thing. */ if (pform_requires_sv(@2, "Streaming concatenation")) { yyerror(@2, "sorry: Streaming concatenation not supported."); $$ = 0; } else { $$ = 0; } } ; /* The task declaration rule matches the task declaration header, then pushes the function scope. This causes the definitions in the task_body to take on the scope of the task instead of the module. */ task_declaration /* IEEE1800-2005: A.2.7 */ : K_task lifetime_opt IDENTIFIER ';' { assert(current_task == 0); current_task = pform_push_task_scope(@1, $3, $2); } tf_item_list_opt statement_or_null_list_opt K_endtask { current_task->set_ports($6); current_task_set_statement(@3, $7); pform_set_this_class(@3, current_task); pform_pop_scope(); current_task = 0; if ($7 && $7->size() > 1) { pform_requires_sv(@7, "Task body with multiple statements"); } delete $7; } label_opt { // Last step: check any closing name. This is done late so // that the parser can look ahead to detect the present // label_opt but still have the pform_endmodule() called // early enough that the lexor can know we are outside the // module. check_end_label(@10, "task", $3, $10); delete[]$3; } | K_task lifetime_opt IDENTIFIER '(' { assert(current_task == 0); current_task = pform_push_task_scope(@1, $3, $2); } tf_port_list_opt ')' ';' block_item_decls_opt statement_or_null_list_opt K_endtask { current_task->set_ports($6); current_task_set_statement(@3, $10); pform_set_this_class(@3, current_task); pform_pop_scope(); if (generation_flag < GN_VER2005 && $6 == 0) { cerr << @3 << ": warning: task definition for \"" << $3 << "\" has an empty port declaration list!" << endl; } current_task = 0; if ($10) delete $10; } label_opt { // Last step: check any closing name. This is done late so // that the parser can look ahead to detect the present // label_opt but still have the pform_endmodule() called // early enough that the lexor can know we are outside the // module. check_end_label(@13, "task", $3, $13); delete[]$3; } | K_task lifetime_opt IDENTIFIER error K_endtask { if (current_task) { pform_pop_scope(); current_task = 0; } } label_opt { // Last step: check any closing name. This is done late so // that the parser can look ahead to detect the present // label_opt but still have the pform_endmodule() called // early enough that the lexor can know we are outside the // module. check_end_label(@7, "task", $3, $7); delete[]$3; } ; tf_port_declaration /* IEEE1800-2005: A.2.7 */ : port_direction K_var_opt data_type_or_implicit list_of_port_identifiers ';' { $$ = pform_make_task_ports(@1, $1, $3, $4, true); } ; /* These rules for tf_port_item are slightly expanded from the strict rules in the LRM to help with LALR parsing. NOTE: Some of these rules should be folded into the "data_type" variant which uses the data_type rule to match data type declarations. That some rules do not use the data_type production is a consequence of legacy. */ tf_port_item /* IEEE1800-2005: A.2.7 */ : port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER dimensions_opt initializer_opt { std::vector*tmp; NetNet::PortType use_port_type = $1; if ((use_port_type == NetNet::PIMPLICIT) && (gn_system_verilog() || ($3 == 0))) use_port_type = port_declaration_context.port_type; list* port_list = make_port_list($4, $5, 0); if (use_port_type == NetNet::PIMPLICIT) { yyerror(@1, "error: Missing task/function port direction."); use_port_type = NetNet::PINPUT; // for error recovery } if (($3 == 0) && ($1==NetNet::PIMPLICIT)) { // Detect special case this is an undecorated // identifier and we need to get the declaration from // left context. if ($5 != 0) { yyerror(@5, "internal error: How can there be an unpacked range here?\n"); } tmp = pform_make_task_ports(@4, use_port_type, port_declaration_context.data_type, port_list); } else { // Otherwise, the decorations for this identifier // indicate the type. Save the type for any right // context that may come later. port_declaration_context.port_type = use_port_type; if ($3 == 0) { $3 = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME($3, @4); } port_declaration_context.data_type = $3; tmp = pform_make_task_ports(@3, use_port_type, $3, port_list); } $$ = tmp; if ($6) { pform_requires_sv(@6, "Task/function default argument"); assert(tmp->size()==1); tmp->front().defe = $6; } } /* Rules to match error cases... */ | port_direction_opt K_var_opt data_type_or_implicit IDENTIFIER error { yyerror(@3, "error: Error in task/function port item after port name %s.", $4); yyerrok; $$ = 0; } ; tf_port_list /* IEEE1800-2005: A.2.7 */ : { port_declaration_context.port_type = gn_system_verilog() ? NetNet::PINPUT : NetNet::PIMPLICIT; port_declaration_context.data_type = 0; } tf_port_item_list { $$ = $2; } ; tf_port_item_list : tf_port_item_list ',' tf_port_item { std::vector*tmp; if ($1 && $3) { size_t s1 = $1->size(); tmp = $1; tmp->resize(tmp->size()+$3->size()); for (size_t idx = 0 ; idx < $3->size() ; idx += 1) tmp->at(s1+idx) = $3->at(idx); delete $3; } else if ($1) { tmp = $1; } else { tmp = $3; } $$ = tmp; } | tf_port_item { $$ = $1; } /* Rules to handle some errors in tf_port_list items. */ | error ',' tf_port_item { yyerror(@2, "error: Syntax error in task/function port declaration."); $$ = $3; } | tf_port_item_list ',' { yyerror(@2, "error: Superfluous comma in port declaration list."); $$ = $1; } | tf_port_item_list ';' { yyerror(@2, "error: ';' is an invalid port declaration separator."); $$ = $1; } ; timeunits_declaration /* IEEE1800-2005: A.1.2 */ : K_timeunit TIME_LITERAL ';' { pform_set_timeunit($2, allow_timeunit_decl); } | K_timeunit TIME_LITERAL '/' TIME_LITERAL ';' { bool initial_decl = allow_timeunit_decl && allow_timeprec_decl; pform_set_timeunit($2, initial_decl); pform_set_timeprec($4, initial_decl); } | K_timeprecision TIME_LITERAL ';' { pform_set_timeprec($2, allow_timeprec_decl); } ; /* Allow zero, one, or two declarations. The second declaration might be a repeat declaration, but the pform functions take care of that. */ timeunits_declaration_opt : /* empty */ %prec no_timeunits_declaration | timeunits_declaration %prec one_timeunits_declaration | timeunits_declaration timeunits_declaration ; value_range /* IEEE1800-2005: A.8.3 */ : expression { } | '[' expression ':' expression ']' { } ; variable_dimension /* IEEE1800-2005: A.2.5 */ : '[' expression ':' expression ']' { std::list *tmp = new std::list; pform_range_t index ($2,$4); tmp->push_back(index); $$ = tmp; } | '[' expression ']' { // SystemVerilog canonical range if (!gn_system_verilog()) { warn_count += 1; cerr << @2 << ": warning: Use of SystemVerilog [size] dimension. " << "Use at least -g2005-sv to remove this warning." << endl; } list *tmp = new std::list; pform_range_t index ($2,0); tmp->push_back(index); $$ = tmp; } | '[' ']' { std::list *tmp = new std::list; pform_range_t index (0,0); pform_requires_sv(@$, "Dynamic array declaration"); tmp->push_back(index); $$ = tmp; } | '[' '$' ']' { // SystemVerilog queue list *tmp = new std::list; pform_range_t index (new PENull,0); pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; } | '[' '$' ':' expression ']' { // SystemVerilog queue with a max size list *tmp = new std::list; pform_range_t index (new PENull,$4); pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; } ; variable_lifetime_opt : lifetime { if (pform_requires_sv(@1, "Overriding default variable lifetime") && $1 != pform_peek_scope()->default_lifetime) { yyerror(@1, "sorry: Overriding the default variable lifetime " "is not yet supported."); } var_lifetime = $1; } | ; /* Verilog-2001 supports attribute lists, which can be attached to a variety of different objects. The syntax inside the (* *) is a comma separated list of names or names with assigned values. */ attribute_list_opt : attribute_instance_list { $$ = $1; } | { $$ = 0; } ; attribute_instance_list : K_PSTAR K_STARP { $$ = 0; } | K_PSTAR attribute_list K_STARP { $$ = $2; } | attribute_instance_list K_PSTAR K_STARP { $$ = $1; } | attribute_instance_list K_PSTAR attribute_list K_STARP { std::list*tmp = $1; if (tmp) { tmp->splice(tmp->end(), *$3); delete $3; $$ = tmp; } else $$ = $3; } ; attribute_list : attribute_list ',' attribute { std::list*tmp = $1; tmp->push_back(*$3); delete $3; $$ = tmp; } | attribute { std::list*tmp = new std::list; tmp->push_back(*$1); delete $1; $$ = tmp; } ; attribute : IDENTIFIER initializer_opt { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($1); tmp->parm = $2; delete[]$1; $$ = tmp; } ; /* The block_item_decl is used in function definitions, task definitions, module definitions and named blocks. Wherever a new scope is entered, the source may declare new registers and integers. This rule matches those declarations. The containing rule has presumably set up the scope. */ block_item_decl /* variable declarations. Note that data_type can be 0 if we are recovering from an error. */ : K_var variable_lifetime_opt data_type_or_implicit list_of_variable_decl_assignments ';' { data_type_t*data_type = $3; if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @1); } pform_make_var(@1, $4, data_type, attributes_in_context); var_lifetime = LexicalScope::INHERITED; } | variable_lifetime_opt data_type list_of_variable_decl_assignments ';' { if ($2) pform_make_var(@2, $3, $2, attributes_in_context); var_lifetime = LexicalScope::INHERITED; } /* The extra `reg` is not valid (System)Verilog, this is a iverilog extension. */ | variable_lifetime_opt K_reg data_type list_of_variable_decl_assignments ';' { if ($3) pform_make_var(@3, $4, $3, attributes_in_context); var_lifetime = LexicalScope::INHERITED; } | K_event event_variable_list ';' { if ($2) pform_make_events(@1, $2); } | parameter_declaration /* Blocks can have type declarations. */ | type_declaration /* Blocks can have imports. */ | package_import_declaration /* Recover from errors that happen within variable lists. Use the trailing semi-colon to resync the parser. */ | K_var variable_lifetime_opt data_type_or_implicit error ';' { yyerror(@1, "error: Syntax error in variable list."); yyerrok; } | variable_lifetime_opt data_type error ';' { yyerror(@1, "error: Syntax error in variable list."); yyerrok; } | K_event error ';' { yyerror(@1, "error: Syntax error in event variable list."); yyerrok; } | parameter error ';' { yyerror(@1, "error: Syntax error in parameter list."); yyerrok; } | localparam error ';' { yyerror(@1, "error: Syntax error localparam list."); yyerrok; } ; block_item_decls : block_item_decl | block_item_decls block_item_decl ; block_item_decls_opt : block_item_decls { $$ = true; } | { $$ = false; } ; /* We need to handle K_enum separately because * `typedef enum ` can either be the start of a enum forward * declaration or a enum type declaration with a type identifier as its base * type. And this abmiguity can not be resolved if we reduce the K_enum to * typedef_basic_type. */ typedef_basic_type : K_struct { $$ = typedef_t::STRUCT; } | K_union { $$ = typedef_t::UNION; } | K_class { $$ = typedef_t::CLASS; } ; /* Type declarations are parsed here. The rule actions call pform functions that add the declaration to the current lexical scope. */ type_declaration : K_typedef data_type identifier_name dimensions_opt ';' { perm_string name = lex_strings.make($3); pform_set_typedef(@3, name, $2, $4); delete[]$3; } /* These are forward declarations... */ | K_typedef identifier_name ';' { perm_string name = lex_strings.make($2); pform_forward_typedef(@2, name, typedef_t::ANY); delete[]$2; } | K_typedef typedef_basic_type identifier_name ';' { perm_string name = lex_strings.make($3); pform_forward_typedef(@3, name, $2); delete[]$3; } | K_typedef K_enum identifier_name ';' { perm_string name = lex_strings.make($3); pform_forward_typedef(@3, name, typedef_t::ENUM); delete[]$3; } | K_typedef error ';' { yyerror(@2, "error: Syntax error in typedef clause."); yyerrok; } ; /* The structure for an enumeration data type is the keyword "enum", followed by the enumeration values in curly braces. Also allow for an optional base type. The default base type is "int", but it can be any of the integral or vector types. */ enum_base_type /* IEEE 1800-2012 A.2.2.1 */ : simple_packed_type { $$ = $1; } | ps_type_identifier dimensions_opt { if ($2) { $$ = new parray_type_t($1, $2); FILE_NAME($$, @1); } else { $$ = $1; } } | { $$ = new atom_type_t(atom_type_t::INT, true); FILE_NAME($$, @0); } ; enum_data_type /* IEEE 1800-2012 A.2.2.1 */ : K_enum enum_base_type '{' enum_name_list '}' { enum_type_t*enum_type = new enum_type_t($2); FILE_NAME(enum_type, @1); enum_type->names.reset($4); pform_put_enum_type_in_scope(enum_type); $$ = enum_type; } ; enum_name_list : enum_name { $$ = $1; } | enum_name_list ',' enum_name { std::list*lst = $1; lst->splice(lst->end(), *$3); delete $3; $$ = lst; } ; pos_neg_number : number { $$ = $1; } | '-' number { verinum tmp = -(*($2)); *($2) = tmp; $$ = $2; } ; enum_name : IDENTIFIER initializer_opt { perm_string name = lex_strings.make($1); delete[]$1; $$ = make_named_number(name, $2); } | IDENTIFIER '[' pos_neg_number ']' initializer_opt { perm_string name = lex_strings.make($1); long count = check_enum_seq_value(@1, $3, false); $$ = make_named_numbers(name, 0, count-1, $5); delete[]$1; delete $3; } | IDENTIFIER '[' pos_neg_number ':' pos_neg_number ']' initializer_opt { perm_string name = lex_strings.make($1); $$ = make_named_numbers(name, check_enum_seq_value(@1, $3, true), check_enum_seq_value(@1, $5, true), $7); delete[]$1; delete $3; delete $5; } ; /* `signed` and `unsigned` are only valid if preceded by `packed` */ packed_signing /* IEEE 1800-2012 A.2.2.1 */ : K_packed unsigned_signed_opt { $$.packed_flag = true; $$.signed_flag = $2; } | { $$.packed_flag = false; $$.signed_flag = false; } ; struct_data_type /* IEEE 1800-2012 A.2.2.1 */ : K_struct packed_signing '{' struct_union_member_list '}' { struct_type_t*tmp = new struct_type_t; FILE_NAME(tmp, @1); tmp->packed_flag = $2.packed_flag; tmp->signed_flag = $2.signed_flag; tmp->union_flag = false; tmp->members .reset($4); $$ = tmp; } | K_union packed_signing '{' struct_union_member_list '}' { struct_type_t*tmp = new struct_type_t; FILE_NAME(tmp, @1); tmp->packed_flag = $2.packed_flag; tmp->signed_flag = $2.signed_flag; tmp->union_flag = true; tmp->members .reset($4); $$ = tmp; } | K_struct packed_signing '{' error '}' { yyerror(@3, "error: Errors in struct member list."); yyerrok; struct_type_t*tmp = new struct_type_t; FILE_NAME(tmp, @1); tmp->packed_flag = $2.packed_flag; tmp->signed_flag = $2.signed_flag; tmp->union_flag = false; $$ = tmp; } | K_union packed_signing '{' error '}' { yyerror(@3, "error: Errors in union member list."); yyerrok; struct_type_t*tmp = new struct_type_t; FILE_NAME(tmp, @1); tmp->packed_flag = $2.packed_flag; tmp->signed_flag = $2.signed_flag; tmp->union_flag = true; $$ = tmp; } ; /* This is an implementation of the rule snippet: struct_union_member { struct_union_member } that is used in the rule matching struct and union types in IEEE 1800-2012 A.2.2.1. */ struct_union_member_list : struct_union_member_list struct_union_member { std::list*tmp = $1; if ($2) tmp->push_back($2); $$ = tmp; } | struct_union_member { std::list*tmp = new std::list; if ($1) tmp->push_back($1); $$ = tmp; } ; struct_union_member /* IEEE 1800-2012 A.2.2.1 */ : attribute_list_opt data_type list_of_variable_decl_assignments ';' { struct_member_t*tmp = new struct_member_t; FILE_NAME(tmp, @2); tmp->type .reset($2); tmp->names .reset($3); $$ = tmp; } | error ';' { yyerror(@2, "error: Error in struct/union member."); yyerrok; $$ = 0; } ; case_item : expression_list_proper ':' statement_or_null { PCase::Item*tmp = new PCase::Item; tmp->expr = *$1; tmp->stat = $3; delete $1; $$ = tmp; } | K_default ':' statement_or_null { PCase::Item*tmp = new PCase::Item; tmp->stat = $3; $$ = tmp; } | K_default statement_or_null { PCase::Item*tmp = new PCase::Item; tmp->stat = $2; $$ = tmp; } | error ':' statement_or_null { yyerror(@2, "error: Incomprehensible case expression."); yyerrok; } ; case_items : case_items case_item { $1->push_back($2); $$ = $1; } | case_item { $$ = new std::vector(1, $1); } ; charge_strength : '(' K_small ')' | '(' K_medium ')' | '(' K_large ')' ; charge_strength_opt : charge_strength | ; defparam_assign : hierarchy_identifier '=' expression { pform_set_defparam(*$1, $3); delete $1; } ; defparam_assign_list : defparam_assign | dimensions defparam_assign { yyerror(@1, "error: defparam may not include a range."); delete $1; } | defparam_assign_list ',' defparam_assign ; delay1 : '#' delay_value_simple { std::list*tmp = new std::list; tmp->push_back($2); $$ = tmp; } | '#' '(' delay_value ')' { std::list*tmp = new std::list; tmp->push_back($3); $$ = tmp; } ; delay3 : '#' delay_value_simple { std::list*tmp = new std::list; tmp->push_back($2); $$ = tmp; } | '#' '(' delay_value ')' { std::list*tmp = new std::list; tmp->push_back($3); $$ = tmp; } | '#' '(' delay_value ',' delay_value ')' { std::list*tmp = new std::list; tmp->push_back($3); tmp->push_back($5); $$ = tmp; } | '#' '(' delay_value ',' delay_value ',' delay_value ')' { std::list*tmp = new std::list; tmp->push_back($3); tmp->push_back($5); tmp->push_back($7); $$ = tmp; } ; delay3_opt : delay3 { $$ = $1; } | { $$ = 0; } ; delay_value_list : delay_value { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } | delay_value_list ',' delay_value { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } ; delay_value : expression { PExpr*tmp = $1; $$ = tmp; } | expression ':' expression ':' expression { $$ = pform_select_mtm_expr($1, $3, $5); } ; delay_value_simple : DEC_NUMBER { verinum*tmp = $1; if (tmp == 0) { yyerror(@1, "internal error: decimal delay."); $$ = 0; } else { $$ = new PENumber(tmp); FILE_NAME($$, @1); } based_size = 0; } | REALTIME { verireal*tmp = $1; if (tmp == 0) { yyerror(@1, "internal error: real time delay."); $$ = 0; } else { $$ = new PEFNumber(tmp); FILE_NAME($$, @1); } } | IDENTIFIER { PEIdent*tmp = new PEIdent(lex_strings.make($1)); FILE_NAME(tmp, @1); $$ = tmp; delete[]$1; } | TIME_LITERAL { int unit; based_size = 0; $$ = 0; if ($1 == 0 || !get_time_unit($1, unit)) yyerror(@1, "internal error: time literal delay."); else { double p = pow(10.0, (double)(unit - pform_get_timeunit())); double time = atof($1) * p; verireal *v = new verireal(time); $$ = new PEFNumber(v); FILE_NAME($$, @1); } } ; /* The discipline and nature declarations used to take no ';' after the identifier. The 2.3 LRM adds the ';', but since there are programs written to the 2.1 and 2.2 standard that don't, we choose to make the ';' optional in this context. */ optional_semicolon : ';' | ; discipline_declaration : K_discipline IDENTIFIER optional_semicolon { pform_start_discipline($2); } discipline_items K_enddiscipline { pform_end_discipline(@1); delete[] $2; } ; discipline_items : discipline_items discipline_item | discipline_item ; discipline_item : K_domain K_discrete ';' { pform_discipline_domain(@1, IVL_DIS_DISCRETE); } | K_domain K_continuous ';' { pform_discipline_domain(@1, IVL_DIS_CONTINUOUS); } | K_potential IDENTIFIER ';' { pform_discipline_potential(@1, $2); delete[] $2; } | K_flow IDENTIFIER ';' { pform_discipline_flow(@1, $2); delete[] $2; } ; nature_declaration : K_nature IDENTIFIER optional_semicolon { pform_start_nature($2); } nature_items K_endnature { pform_end_nature(@1); delete[] $2; } ; nature_items : nature_items nature_item | nature_item ; nature_item : K_units '=' STRING ';' { delete[] $3; } | K_abstol '=' expression ';' | K_access '=' IDENTIFIER ';' { pform_nature_access(@1, $3); delete[] $3; } | K_idt_nature '=' IDENTIFIER ';' { delete[] $3; } | K_ddt_nature '=' IDENTIFIER ';' { delete[] $3; } ; config_declaration : K_config IDENTIFIER ';' K_design lib_cell_identifiers ';' list_of_config_rule_statements K_endconfig { cerr << @1 << ": sorry: config declarations are not supported and " "will be skipped." << endl; delete[] $2; } ; lib_cell_identifiers : /* The BNF implies this can be blank, but I'm not sure exactly what * this means. */ | lib_cell_identifiers lib_cell_id ; list_of_config_rule_statements : /* config rules are optional. */ | list_of_config_rule_statements config_rule_statement ; config_rule_statement : K_default K_liblist list_of_libraries ';' | K_instance hierarchy_identifier K_liblist list_of_libraries ';' { delete $2; } | K_instance hierarchy_identifier K_use lib_cell_id opt_config ';' { delete $2; } | K_cell lib_cell_id K_liblist list_of_libraries ';' | K_cell lib_cell_id K_use lib_cell_id opt_config ';' ; opt_config : /* The use clause takes an optional :config. */ | ':' K_config ; lib_cell_id : IDENTIFIER { delete[] $1; } | IDENTIFIER '.' IDENTIFIER { delete[] $1; delete[] $3; } ; list_of_libraries : /* A NULL library means use the parents cell library. */ | list_of_libraries IDENTIFIER { delete[] $2; } ; drive_strength : '(' dr_strength0 ',' dr_strength1 ')' { $$.str0 = $2.str0; $$.str1 = $4.str1; } | '(' dr_strength1 ',' dr_strength0 ')' { $$.str0 = $4.str0; $$.str1 = $2.str1; } | '(' dr_strength0 ',' K_highz1 ')' { $$.str0 = $2.str0; $$.str1 = IVL_DR_HiZ; } | '(' dr_strength1 ',' K_highz0 ')' { $$.str0 = IVL_DR_HiZ; $$.str1 = $2.str1; } | '(' K_highz1 ',' dr_strength0 ')' { $$.str0 = $4.str0; $$.str1 = IVL_DR_HiZ; } | '(' K_highz0 ',' dr_strength1 ')' { $$.str0 = IVL_DR_HiZ; $$.str1 = $4.str1; } ; drive_strength_opt : drive_strength { $$ = $1; } | { $$.str0 = IVL_DR_STRONG; $$.str1 = IVL_DR_STRONG; } ; dr_strength0 : K_supply0 { $$.str0 = IVL_DR_SUPPLY; } | K_strong0 { $$.str0 = IVL_DR_STRONG; } | K_pull0 { $$.str0 = IVL_DR_PULL; } | K_weak0 { $$.str0 = IVL_DR_WEAK; } ; dr_strength1 : K_supply1 { $$.str1 = IVL_DR_SUPPLY; } | K_strong1 { $$.str1 = IVL_DR_STRONG; } | K_pull1 { $$.str1 = IVL_DR_PULL; } | K_weak1 { $$.str1 = IVL_DR_WEAK; } ; clocking_event_opt /* */ : event_control | ; event_control /* A.K.A. clocking_event */ : '@' hierarchy_identifier { PEIdent*tmpi = pform_new_ident(@2, *$2); FILE_NAME(tmpi, @2); PEEvent*tmpe = new PEEvent(PEEvent::ANYEDGE, tmpi); PEventStatement*tmps = new PEventStatement(tmpe); FILE_NAME(tmps, @1); $$ = tmps; delete $2; } | '@' '(' event_expression_list ')' { PEventStatement*tmp = new PEventStatement(*$3); FILE_NAME(tmp, @1); delete $3; $$ = tmp; } | '@' '(' error ')' { yyerror(@1, "error: Malformed event control expression."); $$ = 0; } ; event_expression_list : event_expression { $$ = new std::vector(1, $1); } | event_expression_list K_or event_expression { $1->push_back($3); $$ = $1; } | event_expression_list ',' event_expression { $1->push_back($3); $$ = $1; } ; event_expression : K_posedge expression { PEEvent*tmp = new PEEvent(PEEvent::POSEDGE, $2); FILE_NAME(tmp, @1); $$ = tmp; } | K_negedge expression { PEEvent*tmp = new PEEvent(PEEvent::NEGEDGE, $2); FILE_NAME(tmp, @1); $$ = tmp; } | K_edge expression { PEEvent*tmp = new PEEvent(PEEvent::EDGE, $2); FILE_NAME(tmp, @1); $$ = tmp; pform_requires_sv(@1, "Edge event"); } | expression { PEEvent*tmp = new PEEvent(PEEvent::ANYEDGE, $1); FILE_NAME(tmp, @1); $$ = tmp; } ; /* A branch probe expression applies a probe function (potential or flow) to a branch. The branch may be implicit as a pair of nets or explicit as a named branch. Elaboration will check that the function name really is a nature attribute identifier. */ branch_probe_expression : IDENTIFIER '(' IDENTIFIER ',' IDENTIFIER ')' { $$ = pform_make_branch_probe_expression(@1, $1, $3, $5); } | IDENTIFIER '(' IDENTIFIER ')' { $$ = pform_make_branch_probe_expression(@1, $1, $3); } ; expression : expr_primary_or_typename { $$ = $1; } | inc_or_dec_expression { $$ = $1; } | inside_expression { $$ = $1; } | '+' attribute_list_opt expr_primary %prec UNARY_PREC { $$ = $3; } | '-' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('-', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '~' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('~', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '&' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('&', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '!' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('!', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '|' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('|', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '^' attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('^', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '~' '&' attribute_list_opt expr_primary %prec UNARY_PREC { yyerror(@1, "error: '~' '&' is not a valid expression. " "Please use operator '~&' instead."); $$ = 0; } | '~' '|' attribute_list_opt expr_primary %prec UNARY_PREC { yyerror(@1, "error: '~' '|' is not a valid expression. " "Please use operator '~|' instead."); $$ = 0; } | '~' '^' attribute_list_opt expr_primary %prec UNARY_PREC { yyerror(@1, "error: '~' '^' is not a valid expression. " "Please use operator '~^' instead."); $$ = 0; } | K_NAND attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('A', $3); FILE_NAME(tmp, @3); $$ = tmp; } | K_NOR attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('N', $3); FILE_NAME(tmp, @3); $$ = tmp; } | K_NXOR attribute_list_opt expr_primary %prec UNARY_PREC { PEUnary*tmp = new PEUnary('X', $3); FILE_NAME(tmp, @3); $$ = tmp; } | '!' error %prec UNARY_PREC { yyerror(@1, "error: Operand of unary ! " "is not a primary expression."); $$ = 0; } | '^' error %prec UNARY_PREC { yyerror(@1, "error: Operand of reduction ^ " "is not a primary expression."); $$ = 0; } | expression '^' attribute_list_opt expression { PEBinary*tmp = new PEBinary('^', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_POW attribute_list_opt expression { PEBinary*tmp = new PEBPower('p', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '*' attribute_list_opt expression { PEBinary*tmp = new PEBinary('*', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '/' attribute_list_opt expression { PEBinary*tmp = new PEBinary('/', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '%' attribute_list_opt expression { PEBinary*tmp = new PEBinary('%', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '+' attribute_list_opt expression { PEBinary*tmp = new PEBinary('+', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '-' attribute_list_opt expression { PEBinary*tmp = new PEBinary('-', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '&' attribute_list_opt expression { PEBinary*tmp = new PEBinary('&', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '|' attribute_list_opt expression { PEBinary*tmp = new PEBinary('|', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_NAND attribute_list_opt expression { PEBinary*tmp = new PEBinary('A', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_NOR attribute_list_opt expression { PEBinary*tmp = new PEBinary('O', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_NXOR attribute_list_opt expression { PEBinary*tmp = new PEBinary('X', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '<' attribute_list_opt expression { PEBinary*tmp = new PEBComp('<', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '>' attribute_list_opt expression { PEBinary*tmp = new PEBComp('>', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_LS attribute_list_opt expression { PEBinary*tmp = new PEBShift('l', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_RS attribute_list_opt expression { PEBinary*tmp = new PEBShift('r', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_RSS attribute_list_opt expression { PEBinary*tmp = new PEBShift('R', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_EQ attribute_list_opt expression { PEBinary*tmp = new PEBComp('e', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_CEQ attribute_list_opt expression { PEBinary*tmp = new PEBComp('E', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_WEQ attribute_list_opt expression { PEBinary*tmp = new PEBComp('w', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_LE attribute_list_opt expression { PEBinary*tmp = new PEBComp('L', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_GE attribute_list_opt expression { PEBinary*tmp = new PEBComp('G', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_NE attribute_list_opt expression { PEBinary*tmp = new PEBComp('n', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_CNE attribute_list_opt expression { PEBinary*tmp = new PEBComp('N', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_WNE attribute_list_opt expression { PEBinary*tmp = new PEBComp('W', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_LOR attribute_list_opt expression { PEBinary*tmp = new PEBLogic('o', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_LAND attribute_list_opt expression { PEBinary*tmp = new PEBLogic('a', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_TRIGGER attribute_list_opt expression { PEBinary*tmp = new PEBLogic('q', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression K_LEQUIV attribute_list_opt expression { PEBinary*tmp = new PEBLogic('Q', $1, $4); FILE_NAME(tmp, @2); $$ = tmp; } | expression '?' attribute_list_opt expression ':' expression { PETernary*tmp = new PETernary($1, $4, $6); FILE_NAME(tmp, @2); $$ = tmp; } ; expr_mintypmax : expression { $$ = $1; } | expression ':' expression ':' expression { switch (min_typ_max_flag) { case MIN: $$ = $1; delete $3; delete $5; break; case TYP: delete $1; $$ = $3; delete $5; break; case MAX: delete $1; delete $3; $$ = $5; break; } if (min_typ_max_warn > 0) { cerr << $$->get_fileline() << ": warning: Choosing "; switch (min_typ_max_flag) { case MIN: cerr << "min"; break; case TYP: cerr << "typ"; break; case MAX: cerr << "max"; break; } cerr << " expression." << endl; min_typ_max_warn -= 1; } } ; /* Many contexts take a comma separated list of expressions. Null expressions can happen anywhere in the list, so there are two extra rules in expression_list_with_nuls for parsing and installing those nulls. The expression_list_proper rules do not allow null items in the expression list, so can be used where nul expressions are not allowed. */ expression_list_with_nuls : expression_list_with_nuls ',' expression { std::list*tmp = $1; if (tmp->empty()) tmp->push_back(0); tmp->push_back($3); $$ = tmp; } | expression { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } | { std::list*tmp = new std::list; $$ = tmp; } | expression_list_with_nuls ',' { std::list*tmp = $1; if (tmp->empty()) tmp->push_back(0); tmp->push_back(0); $$ = tmp; } ; /* A task or function can be invoked with the task/function name followed by * an argument list in parenthesis or with just the task/function name by * itself. When an argument list is used it might be empty. */ argument_list_parens_opt : '(' expression_list_with_nuls ')' { $$ = $2; } | { $$ = new std::list; } expression_list_proper : expression_list_proper ',' expression { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | expression { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; expr_primary_or_typename : expr_primary /* There are a few special cases (notably $bits argument) where the expression may be a type name. Let the elaborator sort this out. */ | data_type { PETypename*tmp = new PETypename($1); FILE_NAME(tmp, @1); $$ = tmp; } ; expr_primary : number { assert($1); PENumber*tmp = new PENumber($1); FILE_NAME(tmp, @1); $$ = tmp; } | REALTIME { PEFNumber*tmp = new PEFNumber($1); FILE_NAME(tmp, @1); $$ = tmp; } | STRING { PEString*tmp = new PEString($1); FILE_NAME(tmp, @1); $$ = tmp; } | TIME_LITERAL { int unit; based_size = 0; $$ = 0; if ($1 == 0 || !get_time_unit($1, unit)) yyerror(@1, "internal error: time literal."); else { double p = pow(10.0, (double)(unit - pform_get_timeunit())); double time = atof($1) * p; // The time value needs to be rounded at the correct digit // since this is a normal real value and not a delay that // will be rounded later. This style of rounding is not safe // for all real values! int rdigit = pform_get_timeunit() - pform_get_timeprec(); assert(rdigit >= 0); double scale = pow(10.0, (double)rdigit); time = round(time*scale)/scale; verireal *v = new verireal(time); $$ = new PEFNumber(v); FILE_NAME($$, @1); } } | SYSTEM_IDENTIFIER { perm_string tn = lex_strings.make($1); PECallFunction*tmp = new PECallFunction(tn); FILE_NAME(tmp, @1); $$ = tmp; delete[]$1; } /* The hierarchy_identifier rule matches simple identifiers as well as indexed arrays and part selects */ | hierarchy_identifier { PEIdent*tmp = pform_new_ident(@1, *$1); FILE_NAME(tmp, @1); $$ = tmp; delete $1; } /* These are array methods that cannot be matched with the above rule */ | hierarchy_identifier '.' K_and { pform_name_t * nm = $1; nm->push_back(name_component_t(lex_strings.make("and"))); PEIdent*tmp = pform_new_ident(@1, *nm); FILE_NAME(tmp, @1); $$ = tmp; delete nm; } | hierarchy_identifier '.' K_or { pform_name_t * nm = $1; nm->push_back(name_component_t(lex_strings.make("or"))); PEIdent*tmp = pform_new_ident(@1, *nm); FILE_NAME(tmp, @1); $$ = tmp; delete nm; } | hierarchy_identifier '.' K_unique { pform_name_t * nm = $1; nm->push_back(name_component_t(lex_strings.make("unique"))); PEIdent*tmp = pform_new_ident(@1, *nm); FILE_NAME(tmp, @1); $$ = tmp; delete nm; } | hierarchy_identifier '.' K_xor { pform_name_t * nm = $1; nm->push_back(name_component_t(lex_strings.make("xor"))); PEIdent*tmp = pform_new_ident(@1, *nm); FILE_NAME(tmp, @1); $$ = tmp; delete nm; } | package_scope hierarchy_identifier { lex_in_package_scope(0); $$ = pform_package_ident(@2, $1, $2); delete $2; } /* An identifier followed by an expression list in parentheses is a function call. If a system identifier, then a system function call. It can also be a call to a class method (function). */ | hierarchy_identifier attribute_list_opt '(' expression_list_with_nuls ')' { std::list*expr_list = $4; strip_tail_items(expr_list); PECallFunction*tmp = pform_make_call_function(@1, *$1, *expr_list); delete $1; delete $2; delete expr_list; $$ = tmp; } | class_hierarchy_identifier '(' expression_list_with_nuls ')' { list*expr_list = $3; strip_tail_items(expr_list); PECallFunction*tmp = pform_make_call_function(@1, *$1, *expr_list); delete $1; delete expr_list; $$ = tmp; } | SYSTEM_IDENTIFIER '(' expression_list_proper ')' { perm_string tn = lex_strings.make($1); PECallFunction*tmp = new PECallFunction(tn, *$3); FILE_NAME(tmp, @1); delete[]$1; delete $3; $$ = tmp; } | package_scope IDENTIFIER { lex_in_package_scope(0); } '(' expression_list_with_nuls ')' { perm_string use_name = lex_strings.make($2); PECallFunction*tmp = new PECallFunction($1, use_name, *$5); FILE_NAME(tmp, @2); delete[]$2; delete $5; $$ = tmp; } | SYSTEM_IDENTIFIER '(' ')' { perm_string tn = lex_strings.make($1); const std::vectorempty; PECallFunction*tmp = new PECallFunction(tn, empty); FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; pform_requires_sv(@1, "Empty function argument list"); } | K_this { PEIdent*tmp = new PEIdent(perm_string::literal(THIS_TOKEN)); FILE_NAME(tmp,@1); $$ = tmp; } | class_hierarchy_identifier { PEIdent*tmp = new PEIdent(*$1); FILE_NAME(tmp, @1); delete $1; $$ = tmp; } /* Many of the VAMS built-in functions are available as builtin functions with $system_function equivalents. */ | K_acos '(' expression ')' { perm_string tn = perm_string::literal("$acos"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_acosh '(' expression ')' { perm_string tn = perm_string::literal("$acosh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_asin '(' expression ')' { perm_string tn = perm_string::literal("$asin"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_asinh '(' expression ')' { perm_string tn = perm_string::literal("$asinh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_atan '(' expression ')' { perm_string tn = perm_string::literal("$atan"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_atanh '(' expression ')' { perm_string tn = perm_string::literal("$atanh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_atan2 '(' expression ',' expression ')' { perm_string tn = perm_string::literal("$atan2"); PECallFunction*tmp = make_call_function(tn, $3, $5); FILE_NAME(tmp,@1); $$ = tmp; } | K_ceil '(' expression ')' { perm_string tn = perm_string::literal("$ceil"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_cos '(' expression ')' { perm_string tn = perm_string::literal("$cos"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_cosh '(' expression ')' { perm_string tn = perm_string::literal("$cosh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_exp '(' expression ')' { perm_string tn = perm_string::literal("$exp"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_floor '(' expression ')' { perm_string tn = perm_string::literal("$floor"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_hypot '(' expression ',' expression ')' { perm_string tn = perm_string::literal("$hypot"); PECallFunction*tmp = make_call_function(tn, $3, $5); FILE_NAME(tmp,@1); $$ = tmp; } | K_ln '(' expression ')' { perm_string tn = perm_string::literal("$ln"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_log '(' expression ')' { perm_string tn = perm_string::literal("$log10"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_pow '(' expression ',' expression ')' { perm_string tn = perm_string::literal("$pow"); PECallFunction*tmp = make_call_function(tn, $3, $5); FILE_NAME(tmp,@1); $$ = tmp; } | K_sin '(' expression ')' { perm_string tn = perm_string::literal("$sin"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_sinh '(' expression ')' { perm_string tn = perm_string::literal("$sinh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_sqrt '(' expression ')' { perm_string tn = perm_string::literal("$sqrt"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_tan '(' expression ')' { perm_string tn = perm_string::literal("$tan"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_tanh '(' expression ')' { perm_string tn = perm_string::literal("$tanh"); PECallFunction*tmp = make_call_function(tn, $3); FILE_NAME(tmp,@1); $$ = tmp; } /* These mathematical functions are conveniently expressed as unary and binary expressions. They behave much like unary/binary operators, even though they are parsed as functions. */ | K_abs '(' expression ')' { PEUnary*tmp = new PEUnary('m', $3); FILE_NAME(tmp,@1); $$ = tmp; } | K_max '(' expression ',' expression ')' { PEBinary*tmp = new PEBinary('M', $3, $5); FILE_NAME(tmp,@1); $$ = tmp; } | K_min '(' expression ',' expression ')' { PEBinary*tmp = new PEBinary('m', $3, $5); FILE_NAME(tmp,@1); $$ = tmp; } /* Parenthesized expressions are primaries. */ | '(' expr_mintypmax ')' { $$ = $2; } /* Various kinds of concatenation expressions. */ | '{' expression_list_proper '}' { PEConcat*tmp = new PEConcat(*$2); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } | '{' expression '{' expression_list_proper '}' '}' { PExpr*rep = $2; PEConcat*tmp = new PEConcat(*$4, rep); FILE_NAME(tmp, @1); delete $4; $$ = tmp; } | '{' expression '{' expression_list_proper '}' error '}' { PExpr*rep = $2; PEConcat*tmp = new PEConcat(*$4, rep); FILE_NAME(tmp, @1); delete $4; $$ = tmp; yyerror(@5, "error: Syntax error between internal '}' " "and closing '}' of repeat concatenation."); yyerrok; } | '{' '}' { // This is the empty queue syntax. if (gn_system_verilog()) { std::list empty_list; PEConcat*tmp = new PEConcat(empty_list); FILE_NAME(tmp, @1); $$ = tmp; } else { yyerror(@1, "error: Concatenations are not allowed to be empty."); $$ = 0; } } /* Cast expressions are primaries */ | expr_primary '\'' '(' expression ')' { PExpr*base = $4; if (pform_requires_sv(@1, "Size cast")) { PECastSize*tmp = new PECastSize($1, base); FILE_NAME(tmp, @1); $$ = tmp; } else { $$ = base; } } | simple_type_or_string '\'' '(' expression ')' { PExpr*base = $4; if (pform_requires_sv(@1, "Type cast")) { PECastType*tmp = new PECastType($1, base); FILE_NAME(tmp, @1); $$ = tmp; } else { $$ = base; } } | signing '\'' '(' expression ')' { PExpr*base = $4; if (pform_requires_sv(@1, "Signing cast")) { PECastSign*tmp = new PECastSign($1, base); FILE_NAME(tmp, @1); $$ = tmp; } else { $$ = base; } } /* Aggregate literals are primaries. */ | assignment_pattern { $$ = $1; } /* SystemVerilog supports streaming concatenation */ | streaming_concatenation { $$ = $1; } | K_null { PENull*tmp = new PENull; FILE_NAME(tmp, @1); $$ = tmp; } ; /* A tf_item_list is shared between functions and tasks to match declarations of ports. We check later to make sure there are no output or inout ports actually used for functions. */ tf_item_list_opt /* IEEE1800-2017: A.2.7 */ : tf_item_list { $$ = $1; } | { $$ = 0; } ; tf_item_list /* IEEE1800-2017: A.2.7 */ : tf_item_declaration { $$ = $1; } | tf_item_list tf_item_declaration { if ($1 && $2) { std::vector*tmp = $1; size_t s1 = tmp->size(); tmp->resize(s1 + $2->size()); for (size_t idx = 0 ; idx < $2->size() ; idx += 1) tmp->at(s1+idx) = $2->at(idx); delete $2; $$ = tmp; } else if ($1) { $$ = $1; } else { $$ = $2; } } ; tf_item_declaration /* IEEE1800-2017: A.2.7 */ : tf_port_declaration { $$ = $1; } | block_item_decl { $$ = 0; } ; /* A gate_instance is a module instantiation or a built in part type. In any case, the gate has a set of connections to ports. */ gate_instance : IDENTIFIER '(' port_conn_expression_list_with_nuls ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = $3; FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | IDENTIFIER dimensions '(' port_conn_expression_list_with_nuls ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = $4; tmp->ranges = $2; FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | '(' port_conn_expression_list_with_nuls ')' { lgate*tmp = new lgate; tmp->name = ""; tmp->parms = $2; FILE_NAME(tmp, @1); $$ = tmp; } /* Degenerate modules can have no ports. */ | IDENTIFIER dimensions { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = 0; tmp->parms_by_name = 0; tmp->ranges = $2; FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } /* Modules can also take ports by port-name expressions. */ | IDENTIFIER '(' port_name_list ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = 0; tmp->parms_by_name = $3; FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | IDENTIFIER dimensions '(' port_name_list ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = 0; tmp->parms_by_name = $4; tmp->ranges = $2; FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | IDENTIFIER '(' error ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = 0; tmp->parms_by_name = 0; FILE_NAME(tmp, @1); yyerror(@2, "error: Syntax error in instance port " "expression(s)."); delete[]$1; $$ = tmp; } | IDENTIFIER dimensions '(' error ')' { lgate*tmp = new lgate; tmp->name = $1; tmp->parms = 0; tmp->parms_by_name = 0; tmp->ranges = $2; FILE_NAME(tmp, @1); yyerror(@3, "error: Syntax error in instance port " "expression(s)."); delete[]$1; $$ = tmp; } ; gate_instance_list : gate_instance_list ',' gate_instance { $1->push_back(*$3); delete $3; $$ = $1; } | gate_instance { $$ = new std::vector(1, *$1); delete $1; } ; gatetype : K_and { $$ = PGBuiltin::AND; } | K_nand { $$ = PGBuiltin::NAND; } | K_or { $$ = PGBuiltin::OR; } | K_nor { $$ = PGBuiltin::NOR; } | K_xor { $$ = PGBuiltin::XOR; } | K_xnor { $$ = PGBuiltin::XNOR; } | K_buf { $$ = PGBuiltin::BUF; } | K_bufif0 { $$ = PGBuiltin::BUFIF0; } | K_bufif1 { $$ = PGBuiltin::BUFIF1; } | K_not { $$ = PGBuiltin::NOT; } | K_notif0 { $$ = PGBuiltin::NOTIF0; } | K_notif1 { $$ = PGBuiltin::NOTIF1; } ; switchtype : K_nmos { $$ = PGBuiltin::NMOS; } | K_rnmos { $$ = PGBuiltin::RNMOS; } | K_pmos { $$ = PGBuiltin::PMOS; } | K_rpmos { $$ = PGBuiltin::RPMOS; } | K_cmos { $$ = PGBuiltin::CMOS; } | K_rcmos { $$ = PGBuiltin::RCMOS; } | K_tran { $$ = PGBuiltin::TRAN; } | K_rtran { $$ = PGBuiltin::RTRAN; } | K_tranif0 { $$ = PGBuiltin::TRANIF0; } | K_tranif1 { $$ = PGBuiltin::TRANIF1; } | K_rtranif0 { $$ = PGBuiltin::RTRANIF0; } | K_rtranif1 { $$ = PGBuiltin::RTRANIF1; } ; /* A general identifier is a hierarchical name, with the right most name the base of the identifier. This rule builds up a hierarchical name from the left to the right, forming a list of names. */ hierarchy_identifier : IDENTIFIER { $$ = new pform_name_t; $$->push_back(name_component_t(lex_strings.make($1))); delete[]$1; } | hierarchy_identifier '.' IDENTIFIER { pform_name_t * tmp = $1; tmp->push_back(name_component_t(lex_strings.make($3))); delete[]$3; $$ = tmp; } | hierarchy_identifier '[' expression ']' { pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); index_component_t itmp; itmp.sel = index_component_t::SEL_BIT; itmp.msb = $3; tail.index.push_back(itmp); $$ = tmp; } | hierarchy_identifier '[' '$' ']' { pform_requires_sv(@3, "Last element expression ($)"); pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); index_component_t itmp; itmp.sel = index_component_t::SEL_BIT_LAST; itmp.msb = 0; itmp.lsb = 0; tail.index.push_back(itmp); $$ = tmp; } | hierarchy_identifier '[' expression ':' expression ']' { pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); index_component_t itmp; itmp.sel = index_component_t::SEL_PART; itmp.msb = $3; itmp.lsb = $5; tail.index.push_back(itmp); $$ = tmp; } | hierarchy_identifier '[' expression K_PO_POS expression ']' { pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); index_component_t itmp; itmp.sel = index_component_t::SEL_IDX_UP; itmp.msb = $3; itmp.lsb = $5; tail.index.push_back(itmp); $$ = tmp; } | hierarchy_identifier '[' expression K_PO_NEG expression ']' { pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); index_component_t itmp; itmp.sel = index_component_t::SEL_IDX_DO; itmp.msb = $3; itmp.lsb = $5; tail.index.push_back(itmp); $$ = tmp; } ; /* This is a list of identifiers. The result is a list of strings, each one of the identifiers in the list. These are simple, non-hierarchical names separated by ',' characters. */ list_of_identifiers : IDENTIFIER { $$ = list_from_identifier($1); } | list_of_identifiers ',' IDENTIFIER { $$ = list_from_identifier($1, $3); } ; list_of_port_identifiers : IDENTIFIER dimensions_opt { $$ = make_port_list($1, $2, 0); } | list_of_port_identifiers ',' IDENTIFIER dimensions_opt { $$ = make_port_list($1, $3, $4, 0); } ; list_of_variable_port_identifiers : IDENTIFIER dimensions_opt initializer_opt { $$ = make_port_list($1, $2, $3); } | list_of_variable_port_identifiers ',' IDENTIFIER dimensions_opt initializer_opt { $$ = make_port_list($1, $3, $4, $5); } ; /* The list_of_ports and list_of_port_declarations rules are the port list formats for module ports. The list_of_ports_opt rule is only used by the module start rule. The first, the list_of_ports, is the 1364-1995 format, a list of port names, including .name() syntax. The list_of_port_declarations the 1364-2001 format, an in-line declaration of the ports. In both cases, the list_of_ports and list_of_port_declarations returns an array of Module::port_t* items that include the name of the port internally and externally. The actual creation of the nets/variables is done in the declaration, whether internal to the port list or in amongst the module items. */ list_of_ports : port_opt { std::vector*tmp = new std::vector(1); (*tmp)[0] = $1; $$ = tmp; } | list_of_ports ',' port_opt { std::vector*tmp = $1; tmp->push_back($3); $$ = tmp; } ; list_of_port_declarations : port_declaration { std::vector*tmp = new std::vector(1); (*tmp)[0] = $1; $$ = tmp; } | list_of_port_declarations ',' port_declaration { std::vector*tmp = $1; tmp->push_back($3); $$ = tmp; } | list_of_port_declarations ',' IDENTIFIER initializer_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($3); ptmp = pform_module_port_reference(@3, name); std::vector*tmp = $1; tmp->push_back(ptmp); if ($4) { switch (port_declaration_context.port_type) { case NetNet::PINOUT: yyerror(@4, "error: Default port value not allowed for inout ports."); break; case NetNet::PINPUT: pform_requires_sv(@4, "Default port value"); ptmp->default_value = $4; break; case NetNet::POUTPUT: pform_make_var_init(@3, name, $4); break; default: break; } } /* Get the port declaration details, the port type and what not, from context data stored by the last port_declaration rule. */ pform_module_define_port(@3, name, port_declaration_context.port_type, port_declaration_context.port_net_type, port_declaration_context.data_type, nullptr, nullptr); delete[]$3; $$ = tmp; } | list_of_port_declarations ',' { yyerror(@2, "error: Superfluous comma in port declaration list."); } | list_of_port_declarations ';' { yyerror(@2, "error: ';' is an invalid port declaration separator."); } ; port_declaration : attribute_list_opt K_input net_type_or_var_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); ptmp = pform_module_port_reference(@2, name); pform_module_define_port(@2, name, NetNet::PINPUT, $3, $4, $6, nullptr, $1); port_declaration_context.port_type = NetNet::PINPUT; port_declaration_context.port_net_type = $3; port_declaration_context.data_type = $4; delete[]$5; $$ = ptmp; } | attribute_list_opt K_input K_wreal IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($4); ptmp = pform_module_port_reference(@2, name); real_type_t*real_type = new real_type_t(real_type_t::REAL); FILE_NAME(real_type, @3); pform_module_define_port(@2, name, NetNet::PINPUT, NetNet::WIRE, real_type, nullptr, $1); port_declaration_context.port_type = NetNet::PINPUT; port_declaration_context.port_net_type = NetNet::WIRE; port_declaration_context.data_type = real_type; delete[]$4; $$ = ptmp; } | attribute_list_opt K_input net_type_or_var_opt data_type_or_implicit IDENTIFIER '=' expression { pform_requires_sv(@6, "Default port value"); Module::port_t*ptmp; perm_string name = lex_strings.make($5); data_type_t*use_type = $4; ptmp = pform_module_port_reference(@2, name); ptmp->default_value = $7; pform_module_define_port(@2, name, NetNet::PINPUT, $3, use_type, nullptr, $1); port_declaration_context.port_type = NetNet::PINPUT; port_declaration_context.port_net_type = $3; port_declaration_context.data_type = $4; delete[]$5; $$ = ptmp; } | attribute_list_opt K_inout net_type_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); ptmp = pform_module_port_reference(@2, name); pform_module_define_port(@2, name, NetNet::PINOUT, $3, $4, nullptr, $1); port_declaration_context.port_type = NetNet::PINOUT; port_declaration_context.port_net_type = $3; port_declaration_context.data_type = $4; delete[]$5; if ($6) { yyerror(@6, "sorry: Inout ports with unpacked dimensions not supported."); delete $6; } $$ = ptmp; } | attribute_list_opt K_inout K_wreal IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($4); ptmp = pform_module_port_reference(@2, name); real_type_t*real_type = new real_type_t(real_type_t::REAL); FILE_NAME(real_type, @3); pform_module_define_port(@2, name, NetNet::PINOUT, NetNet::WIRE, real_type, nullptr, $1); port_declaration_context.port_type = NetNet::PINOUT; port_declaration_context.port_net_type = NetNet::WIRE; port_declaration_context.data_type = real_type; delete[]$4; $$ = ptmp; } | attribute_list_opt K_output net_type_or_var_opt data_type_or_implicit IDENTIFIER dimensions_opt { Module::port_t*ptmp; perm_string name = lex_strings.make($5); NetNet::Type use_type = $3; if (use_type == NetNet::IMPLICIT) { if (vector_type_t*dtype = dynamic_cast ($4)) { if (dtype->implicit_flag) use_type = NetNet::IMPLICIT; else use_type = NetNet::IMPLICIT_REG; // The SystemVerilog types that can show up as // output ports are implicitly (on the inside) // variables because "reg" is not valid syntax // here. } else if ($4) { use_type = NetNet::IMPLICIT_REG; } } ptmp = pform_module_port_reference(@2, name); pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, $4, $6, $1); port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = use_type; port_declaration_context.data_type = $4; delete[]$5; $$ = ptmp; } | attribute_list_opt K_output K_wreal IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($4); ptmp = pform_module_port_reference(@2, name); real_type_t*real_type = new real_type_t(real_type_t::REAL); FILE_NAME(real_type, @3); pform_module_define_port(@2, name, NetNet::POUTPUT, NetNet::WIRE, real_type, nullptr, $1); port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = NetNet::WIRE; port_declaration_context.data_type = real_type; delete[]$4; $$ = ptmp; } | attribute_list_opt K_output net_type_or_var_opt data_type_or_implicit IDENTIFIER '=' expression { Module::port_t*ptmp; perm_string name = lex_strings.make($5); NetNet::Type use_type = $3; if (use_type == NetNet::IMPLICIT) { use_type = NetNet::IMPLICIT_REG; } ptmp = pform_module_port_reference(@2, name); pform_module_define_port(@2, name, NetNet::POUTPUT, use_type, $4, nullptr, $1); port_declaration_context.port_type = NetNet::POUTPUT; port_declaration_context.port_net_type = use_type; port_declaration_context.data_type = $4; pform_make_var_init(@5, name, $7); delete[]$5; $$ = ptmp; } ; /* * The signed_opt rule will return "true" if K_signed is present, * for "false" otherwise. This rule corresponds to the declaration * defaults for reg/bit/logic. * * The signed_unsigned_opt rule with match K_signed or K_unsigned * and return true or false as appropriate. The default is * "true". This corresponds to the declaration defaults for * byte/shortint/int/longint. */ unsigned_signed_opt : K_signed { $$ = true; } | K_unsigned { $$ = false; } | { $$ = false; } ; signed_unsigned_opt : K_signed { $$ = true; } | K_unsigned { $$ = false; } | { $$ = true; } ; /* * In some places we can take any of the 4 2-value atom-type * names. All the context needs to know if that type is its width. */ atom_type : K_byte { $$ = atom_type_t::BYTE; } | K_shortint { $$ = atom_type_t::SHORTINT; } | K_int { $$ = atom_type_t::INT; } | K_longint { $$ = atom_type_t::LONGINT; } | K_integer { $$ = atom_type_t::INTEGER; } ; /* An lpvalue is the expression that can go on the left side of a procedural assignment. This rule handles only procedural assignments. It is more limited than the general expr_primary rule to reflect the rules for assignment l-values. */ lpvalue : hierarchy_identifier { PEIdent*tmp = pform_new_ident(@1, *$1); FILE_NAME(tmp, @1); $$ = tmp; delete $1; } | class_hierarchy_identifier { PEIdent*tmp = new PEIdent(*$1); FILE_NAME(tmp, @1); $$ = tmp; delete $1; } | '{' expression_list_proper '}' { PEConcat*tmp = new PEConcat(*$2); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } | streaming_concatenation { yyerror(@1, "sorry: Streaming concatenation not supported in l-values."); $$ = 0; } ; /* Continuous assignments have a list of individual assignments. */ cont_assign : lpvalue '=' expression { std::list*tmp = new std::list; tmp->push_back($1); tmp->push_back($3); $$ = tmp; } ; cont_assign_list : cont_assign_list ',' cont_assign { std::list*tmp = $1; tmp->splice(tmp->end(), *$3); delete $3; $$ = tmp; } | cont_assign { $$ = $1; } ; /* This is the global structure of a module. A module is a start section, with optional ports, then an optional list of module items, and finally an end marker. */ module : attribute_list_opt module_start lifetime_opt IDENTIFIER { pform_startmodule(@2, $4, $2==K_program, $2==K_interface, $3, $1); } module_package_import_list_opt module_parameter_port_list_opt module_port_list_opt module_attribute_foreign ';' { pform_module_set_ports($8); } timeunits_declaration_opt { pform_set_scope_timescale(@2); } module_item_list_opt module_end { Module::UCDriveType ucd; // The lexor detected `unconnected_drive directives and // marked what it found in the uc_drive variable. Use that // to generate a UCD flag for the module. switch (uc_drive) { case UCD_NONE: default: ucd = Module::UCD_NONE; break; case UCD_PULL0: ucd = Module::UCD_PULL0; break; case UCD_PULL1: ucd = Module::UCD_PULL1; break; } // Check that program/endprogram and module/endmodule // keywords match. if ($2 != $15) { switch ($2) { case K_module: yyerror(@15, "error: module not closed by endmodule."); break; case K_program: yyerror(@15, "error: program not closed by endprogram."); break; case K_interface: yyerror(@15, "error: interface not closed by endinterface."); break; default: break; } } pform_endmodule($4, in_celldefine, ucd); } label_opt { // Last step: check any closing name. This is done late so // that the parser can look ahead to detect the present // label_opt but still have the pform_endmodule() called // early enough that the lexor can know we are outside the // module. switch ($2) { case K_module: check_end_label(@17, "module", $4, $17); break; case K_program: check_end_label(@17, "program", $4, $17); break; case K_interface: check_end_label(@17, "interface", $4, $17); break; default: break; } delete[]$4; } ; /* Modules start with a module/macromodule, program, or interface keyword, and end with a endmodule, endprogram, or endinterface keyword. The syntax for modules programs, and interfaces is almost identical, so let semantics sort out the differences. */ module_start : K_module { pform_error_in_generate(@1, "module declaration"); $$ = K_module; } | K_macromodule { pform_error_in_generate(@1, "module declaration"); $$ = K_module; } | K_program { pform_error_in_generate(@1, "program declaration"); $$ = K_program; } | K_interface { pform_error_in_generate(@1, "interface declaration"); $$ = K_interface; } ; module_end : K_endmodule { $$ = K_module; } | K_endprogram { $$ = K_program; } | K_endinterface { $$ = K_interface; } ; label_opt : ':' IDENTIFIER { $$ = $2; } | { $$ = 0; } ; module_attribute_foreign : K_PSTAR IDENTIFIER K_integer IDENTIFIER '=' STRING ';' K_STARP { $$ = 0; } | { $$ = 0; } ; module_port_list_opt : '(' list_of_ports ')' { $$ = $2; } | '(' list_of_port_declarations ')' { $$ = $2; } | { $$ = 0; } | '(' error ')' { yyerror(@2, "Errors in port declarations."); yyerrok; $$ = 0; } ; /* Module declarations include optional ANSI style module parameter ports. These are simply advance ways to declare parameters, so that the port declarations may use them. */ module_parameter_port_list_opt : | '#' '(' { pform_start_parameter_port_list(); } module_parameter_port_list { pform_end_parameter_port_list(); } ')' ; type_param : K_type { param_is_type = true; } ; module_parameter : parameter param_type parameter_assign | localparam param_type parameter_assign { pform_requires_sv(@1, "Local parameter in module parameter port list"); } ; module_parameter_port_list : module_parameter | data_type_opt { param_data_type = $1; param_is_local = false; param_is_type = false; } parameter_assign { pform_requires_sv(@3, "Omitting initial `parameter` in parameter port " "list"); } | type_param { param_is_local = false; } parameter_assign | module_parameter_port_list ',' module_parameter | module_parameter_port_list ',' data_type_opt { if ($3) { pform_requires_sv(@3, "Omitting `parameter`/`localparam` before " "data type in parameter port list"); param_data_type = $3; param_is_type = false; } } parameter_assign | module_parameter_port_list ',' type_param parameter_assign ; module_item /* Modules can contain further sub-module definitions. */ : module | attribute_list_opt net_type data_type_or_implicit delay3_opt net_variable_list ';' { data_type_t*data_type = $3; pform_check_net_data_type(@2, $2, $3); if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @2); } pform_set_data_type(@2, data_type, $5, $2, $1); if ($4 != 0) { yyerror(@2, "sorry: Net delays not supported."); delete $4; } delete $1; } | attribute_list_opt K_wreal delay3 net_variable_list ';' { real_type_t*tmpt = new real_type_t(real_type_t::REAL); pform_set_data_type(@2, tmpt, $4, NetNet::WIRE, $1); if ($3 != 0) { yyerror(@3, "sorry: Net delays not supported."); delete $3; } delete $1; } | attribute_list_opt K_wreal net_variable_list ';' { real_type_t*tmpt = new real_type_t(real_type_t::REAL); pform_set_data_type(@2, tmpt, $3, NetNet::WIRE, $1); delete $1; } /* Very similar to the rule above, but this takes a list of net_decl_assigns, which are = assignment declarations. */ | attribute_list_opt net_type data_type_or_implicit delay3_opt net_decl_assigns ';' { data_type_t*data_type = $3; pform_check_net_data_type(@2, $2, $3); if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @2); } pform_makewire(@2, $4, str_strength, $5, $2, data_type, $1); delete $1; } /* This form doesn't have the range, but does have strengths. This gives strength to the assignment drivers. */ | attribute_list_opt net_type data_type_or_implicit drive_strength net_decl_assigns ';' { data_type_t*data_type = $3; pform_check_net_data_type(@2, $2, $3); if (data_type == 0) { data_type = new vector_type_t(IVL_VT_LOGIC, false, 0); FILE_NAME(data_type, @2); } pform_makewire(@2, 0, $4, $5, $2, data_type, $1); delete $1; } | attribute_list_opt K_wreal net_decl_assigns ';' { real_type_t*data_type = new real_type_t(real_type_t::REAL); pform_makewire(@2, 0, str_strength, $3, NetNet::WIRE, data_type, $1); delete $1; } | K_trireg charge_strength_opt dimensions_opt delay3_opt list_of_identifiers ';' { yyerror(@1, "sorry: trireg nets not supported."); delete $3; delete $4; } /* The next two rules handle port declarations that include a net type, e.g. input wire signed [h:l] ; This creates the wire and sets the port type all at once. */ | attribute_list_opt port_direction net_type_or_var data_type_or_implicit list_of_port_identifiers ';' { pform_module_define_port(@2, $5, $2, $3, $4, $1); } | attribute_list_opt port_direction K_wreal list_of_port_identifiers ';' { real_type_t*real_type = new real_type_t(real_type_t::REAL); pform_module_define_port(@2, $4, $2, NetNet::WIRE, real_type, $1); } /* The next three rules handle port declarations that include a variable type, e.g. output reg signed [h:l] ; and also handle incomplete port declarations, e.g. input signed [h:l] ; */ | attribute_list_opt K_inout data_type_or_implicit list_of_port_identifiers ';' { NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE; if (vector_type_t*dtype = dynamic_cast ($3)) { if (dtype->implicit_flag) use_type = NetNet::NONE; } if (use_type == NetNet::NONE) pform_set_port_type(@2, $4, NetNet::PINOUT, $3, $1); else pform_module_define_port(@2, $4, NetNet::PINOUT, use_type, $3, $1); } | attribute_list_opt K_input data_type_or_implicit list_of_port_identifiers ';' { NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE; if (vector_type_t*dtype = dynamic_cast ($3)) { if (dtype->implicit_flag) use_type = NetNet::NONE; } if (use_type == NetNet::NONE) pform_set_port_type(@2, $4, NetNet::PINPUT, $3, $1); else pform_module_define_port(@2, $4, NetNet::PINPUT, use_type, $3, $1); } | attribute_list_opt K_output data_type_or_implicit list_of_variable_port_identifiers ';' { NetNet::Type use_type = $3 ? NetNet::IMPLICIT : NetNet::NONE; if (vector_type_t*dtype = dynamic_cast ($3)) { if (dtype->implicit_flag) use_type = NetNet::NONE; else use_type = NetNet::IMPLICIT_REG; // The SystemVerilog types that can show up as // output ports are implicitly (on the inside) // variables because "reg" is not valid syntax // here. } else if ($3) { use_type = NetNet::IMPLICIT_REG; } if (use_type == NetNet::NONE) pform_set_port_type(@2, $4, NetNet::POUTPUT, $3, $1); else pform_module_define_port(@2, $4, NetNet::POUTPUT, use_type, $3, $1); } | attribute_list_opt port_direction net_type_or_var data_type_or_implicit error ';' { yyerror(@2, "error: Invalid variable list in port declaration."); if ($1) delete $1; if ($4) delete $4; yyerrok; } | attribute_list_opt K_inout data_type_or_implicit error ';' { yyerror(@2, "error: Invalid variable list in port declaration."); if ($1) delete $1; if ($3) delete $3; yyerrok; } | attribute_list_opt K_input data_type_or_implicit error ';' { yyerror(@2, "error: Invalid variable list in port declaration."); if ($1) delete $1; if ($3) delete $3; yyerrok; } | attribute_list_opt K_output data_type_or_implicit error ';' { yyerror(@2, "error: Invalid variable list in port declaration."); if ($1) delete $1; if ($3) delete $3; yyerrok; } | K_let IDENTIFIER let_port_list_opt '=' expression ';' { perm_string tmp2 = lex_strings.make($2); pform_make_let(@1, tmp2, $3, $5); } /* Maybe this is a discipline declaration? If so, then the lexor will see the discipline name as an identifier. We match it to the discipline or type name semantically. */ | DISCIPLINE_IDENTIFIER list_of_identifiers ';' { pform_attach_discipline(@1, $1, $2); } /* block_item_decl rule is shared with task blocks and named begin/end. Careful to pass attributes to the block_item_decl. */ | attribute_list_opt { attributes_in_context = $1; } block_item_decl { delete attributes_in_context; attributes_in_context = 0; } /* */ | K_defparam { if (pform_in_interface()) yyerror(@1, "error: Parameter overrides are not allowed " "in interfaces."); } defparam_assign_list ';' /* Most gate types have an optional drive strength and optional two/three-value delay. These rules handle the different cases. We check that the actual number of delays is correct later. */ | attribute_list_opt gatetype gate_instance_list ';' { pform_makegates(@2, $2, str_strength, 0, $3, $1); } | attribute_list_opt gatetype delay3 gate_instance_list ';' { pform_makegates(@2, $2, str_strength, $3, $4, $1); } | attribute_list_opt gatetype drive_strength gate_instance_list ';' { pform_makegates(@2, $2, $3, 0, $4, $1); } | attribute_list_opt gatetype drive_strength delay3 gate_instance_list ';' { pform_makegates(@2, $2, $3, $4, $5, $1); } /* The switch type gates do not support a strength. */ | attribute_list_opt switchtype gate_instance_list ';' { pform_makegates(@2, $2, str_strength, 0, $3, $1); } | attribute_list_opt switchtype delay3 gate_instance_list ';' { pform_makegates(@2, $2, str_strength, $3, $4, $1); } /* Pullup and pulldown devices cannot have delays, and their strengths are limited. */ | K_pullup gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLUP, pull_strength, 0, $2, 0); } | K_pulldown gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLDOWN, pull_strength, 0, $2, 0); } | K_pullup '(' dr_strength1 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $5, 0); } | K_pullup '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLUP, $3, 0, $7, 0); } | K_pullup '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLUP, $5, 0, $7, 0); } | K_pulldown '(' dr_strength0 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $5, 0); } | K_pulldown '(' dr_strength1 ',' dr_strength0 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLDOWN, $5, 0, $7, 0); } | K_pulldown '(' dr_strength0 ',' dr_strength1 ')' gate_instance_list ';' { pform_makegates(@1, PGBuiltin::PULLDOWN, $3, 0, $7, 0); } /* This rule handles instantiations of modules and user defined primitives. These devices to not have delay lists or strengths, but then can have parameter lists. */ | attribute_list_opt IDENTIFIER parameter_value_opt gate_instance_list ';' { perm_string tmp1 = lex_strings.make($2); pform_make_modgates(@2, tmp1, $3, $4, $1); delete[]$2; } | attribute_list_opt IDENTIFIER parameter_value_opt error ';' { yyerror(@2, "error: Invalid module instantiation"); delete[]$2; if ($1) delete $1; } /* Continuous assignment can have an optional drive strength, then an optional delay3 that applies to all the assignments in the cont_assign_list. */ | K_assign drive_strength_opt delay3_opt cont_assign_list ';' { pform_make_pgassign_list(@1, $4, $3, $2); } /* Always and initial items are behavioral processes. */ | attribute_list_opt K_always statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_always_comb statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_COMB, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_always_ff statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_FF, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_always_latch statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS_LATCH, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_initial statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_INITIAL, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_final statement_item { PProcess*tmp = pform_make_behavior(IVL_PR_FINAL, $3, $1); FILE_NAME(tmp, @2); } | attribute_list_opt K_analog analog_statement { pform_make_analog_behavior(@2, IVL_PR_ALWAYS, $3); } | attribute_list_opt assertion_item | timeunits_declaration { pform_error_in_generate(@1, "timeunit declaration"); } | class_declaration | task_declaration | function_declaration /* A generate region can contain further module items. Actually, it is supposed to be limited to certain kinds of module items, but the semantic tests will check that for us. Do check that the generate/endgenerate regions do not nest. Generate schemes nest, but generate regions do not. */ | K_generate generate_item_list_opt K_endgenerate { // Test for bad nesting. I understand it, but it is illegal. if (pform_parent_generate()) { cerr << @1 << ": error: Generate/endgenerate regions cannot nest." << endl; cerr << @1 << ": : Try removing optional generate/endgenerate keywords," << endl; cerr << @1 << ": : or move them to surround the parent generate scheme." << endl; error_count += 1; } } | K_genvar list_of_identifiers ';' { pform_genvars(@1, $2); } | K_for '(' K_genvar_opt IDENTIFIER '=' expression ';' expression ';' genvar_iteration ')' { pform_start_generate_for(@2, $3, $4, $6, $8, $10.text, $10.expr); } generate_block { pform_endgenerate(false); } | generate_if generate_block K_else { pform_start_generate_else(@1); } generate_block { pform_endgenerate(true); } | generate_if generate_block %prec less_than_K_else { pform_endgenerate(true); } | K_case '(' expression ')' { pform_start_generate_case(@1, $3); } generate_case_items K_endcase { pform_endgenerate(true); } /* Elaboration system tasks. */ | SYSTEM_IDENTIFIER argument_list_parens_opt ';' { pform_make_elab_task(@1, lex_strings.make($1), *$2); delete[]$1; delete $2; } | modport_declaration /* 1364-2001 and later allow specparam declarations outside specify blocks. */ | attribute_list_opt K_specparam { if (pform_in_interface()) yyerror(@2, "error: specparam declarations are not allowed " "in interfaces."); pform_error_in_generate(@2, "specparam declaration"); } specparam_decl ';' /* specify blocks are parsed but ignored. */ | K_specify { if (pform_in_interface()) yyerror(@1, "error: specify blocks are not allowed " "in interfaces."); pform_error_in_generate(@1, "specify block"); } specify_item_list_opt K_endspecify | K_specify error K_endspecify { yyerror(@1, "error: Syntax error in specify block"); yyerrok; } /* These rules match various errors that the user can type into module items. These rules try to catch them at a point where a reasonable error message can be produced. */ | error ';' { yyerror(@2, "error: Invalid module item."); yyerrok; } | K_assign error '=' expression ';' { yyerror(@1, "error: Syntax error in left side of " "continuous assignment."); yyerrok; } | K_assign error ';' { yyerror(@1, "error: Syntax error in continuous assignment"); yyerrok; } | K_function error K_endfunction label_opt { yyerror(@1, "error: I give up on this function definition."); if ($4) { pform_requires_sv(@4, "Function end label"); delete[]$4; } yyerrok; } /* These rules are for the Icarus Verilog specific $attribute extensions. Then catch the parameters of the $attribute keyword. */ | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' ';' { perm_string tmp3 = lex_strings.make($3); perm_string tmp5 = lex_strings.make($5); pform_set_attrib(tmp3, tmp5, $7); delete[] $3; delete[] $5; } | KK_attribute '(' error ')' ';' { yyerror(@1, "error: Malformed $attribute parameter list."); } | ';' { } ; let_port_list_opt : '(' let_port_list ')' { $$ = $2; } | '(' ')' { $$ = 0; } | { $$ = 0; } ; let_port_list : let_port_item { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } | let_port_list ',' let_port_item { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } ; // FIXME: What about the attributes? let_port_item : attribute_list_opt let_formal_type IDENTIFIER dimensions_opt initializer_opt { perm_string tmp3 = lex_strings.make($3); $$ = pform_make_let_port($2, tmp3, $4, $5); } ; let_formal_type : data_type_or_implicit { $$ = $1; } | K_untyped { $$ = 0; } ; module_item_list : module_item_list module_item | module_item ; module_item_list_opt : module_item_list | ; generate_if : K_if '(' expression ')' { pform_start_generate_if(@1, $3); } ; generate_case_items : generate_case_items generate_case_item | generate_case_item ; generate_case_item : expression_list_proper ':' { pform_generate_case_item(@1, $1); } generate_block { pform_endgenerate(false); } | K_default ':' { pform_generate_case_item(@1, 0); } generate_block { pform_endgenerate(false); } ; generate_item : module_item /* Handle some anachronistic syntax cases. */ | K_begin generate_item_list_opt K_end { /* Detect and warn about anachronistic begin/end use */ if (generation_flag > GN_VER2001 && warn_anachronisms) { warn_count += 1; cerr << @1 << ": warning: Anachronistic use of begin/end to surround generate schemes." << endl; } } | K_begin ':' IDENTIFIER { pform_start_generate_nblock(@1, $3); } generate_item_list_opt K_end { /* Detect and warn about anachronistic named begin/end use */ if (generation_flag > GN_VER2001 && warn_anachronisms) { warn_count += 1; cerr << @1 << ": warning: Anachronistic use of named begin/end to surround generate schemes." << endl; } pform_endgenerate(false); } ; generate_item_list : generate_item_list generate_item | generate_item ; generate_item_list_opt : { pform_generate_single_item = false; } generate_item_list | ; /* A generate block is the thing within a generate scheme. It may be a single module item, an anonymous block of module items, or a named module item. In all cases, the meat is in the module items inside, and the processing is done by the module_item rules. We only need to take note here of the scope name, if any. */ generate_block : { pform_generate_single_item = true; } module_item { pform_generate_single_item = false; } | K_begin label_opt generate_item_list_opt K_end label_opt { if ($2) pform_generate_block_name($2); check_end_label(@5, "block", $2, $5); delete[]$2; } ; /* A net declaration assignment allows the programmer to combine the net declaration and the continuous assignment into a single statement. Note that the continuous assignment statement is generated as a side effect, and all I pass up is the name of the l-value. */ net_decl_assign : IDENTIFIER '=' expression { decl_assignment_t*tmp = new decl_assignment_t; tmp->name = lex_strings.make($1); tmp->expr.reset($3); delete[]$1; $$ = tmp; } ; net_decl_assigns : net_decl_assigns ',' net_decl_assign { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | net_decl_assign { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; net_type : K_wire { $$ = NetNet::WIRE; } | K_tri { $$ = NetNet::TRI; } | K_tri1 { $$ = NetNet::TRI1; } | K_supply0 { $$ = NetNet::SUPPLY0; } | K_wand { $$ = NetNet::WAND; } | K_triand { $$ = NetNet::TRIAND; } | K_tri0 { $$ = NetNet::TRI0; } | K_supply1 { $$ = NetNet::SUPPLY1; } | K_wor { $$ = NetNet::WOR; } | K_trior { $$ = NetNet::TRIOR; } | K_wone { $$ = NetNet::UNRESOLVED_WIRE; cerr << @1.text << ":" << @1.first_line << ": warning: " "'wone' is deprecated, please use 'uwire' " "instead." << endl; } | K_uwire { $$ = NetNet::UNRESOLVED_WIRE; } ; net_type_opt : net_type { $$ = $1; } | { $$ = NetNet::IMPLICIT; } ; net_type_or_var : net_type { $$ = $1; } | K_var { $$ = NetNet::REG; } net_type_or_var_opt : net_type_opt { $$ = $1; } | K_var { $$ = NetNet::REG; } ; /* The param_type rule is just the data_type_or_implicit rule wrapped with an assignment to para_data_type with the figured data type. This is used by parameter_assign, which is found to the right of the param_type in various rules. */ param_type : data_type_or_implicit { param_is_type = false; param_data_type = $1; } | type_param parameter : K_parameter { param_is_local = false; } ; localparam : K_localparam { param_is_local = true; } ; parameter_declaration : parameter_or_localparam param_type parameter_assign_list ';' parameter_or_localparam : parameter | localparam ; /* parameter and localparam assignment lists are broken into separate BNF so that I can call slightly different parameter handling code. localparams parse the same as parameters, they just behave differently when someone tries to override them. */ parameter_assign_list : parameter_assign | parameter_assign_list ',' parameter_assign ; parameter_assign : IDENTIFIER initializer_opt parameter_value_ranges_opt { pform_set_parameter(@1, lex_strings.make($1), param_is_local, param_is_type, param_data_type, $2, $3); delete[]$1; } ; parameter_value_ranges_opt : parameter_value_ranges { $$ = $1; } | { $$ = 0; } ; parameter_value_ranges : parameter_value_ranges parameter_value_range { $$ = $2; $$->next = $1; } | parameter_value_range { $$ = $1; $$->next = 0; } ; parameter_value_range : from_exclude '[' value_range_expression ':' value_range_expression ']' { $$ = pform_parameter_value_range($1, false, $3, false, $5); } | from_exclude '[' value_range_expression ':' value_range_expression ')' { $$ = pform_parameter_value_range($1, false, $3, true, $5); } | from_exclude '(' value_range_expression ':' value_range_expression ']' { $$ = pform_parameter_value_range($1, true, $3, false, $5); } | from_exclude '(' value_range_expression ':' value_range_expression ')' { $$ = pform_parameter_value_range($1, true, $3, true, $5); } | K_exclude expression { $$ = pform_parameter_value_range(true, false, $2, false, $2); } ; value_range_expression : expression { $$ = $1; } | K_inf { $$ = 0; } | '+' K_inf { $$ = 0; } | '-' K_inf { $$ = 0; } ; from_exclude : K_from { $$ = false; } | K_exclude { $$ = true; } ; /* The parameters of a module instance can be overridden by writing a list of expressions in a syntax much like a delay list. (The difference being the list can have any length.) The pform that attaches the expression list to the module checks that the expressions are constant. Although the BNF in IEEE1364-1995 implies that parameter value lists must be in parentheses, in practice most compilers will accept simple expressions outside of parentheses if there is only one value, so I'll accept simple numbers here. This also catches the case of a UDP with a single delay value, so we need to accept real values as well as decimal ones. The parameter value by name syntax is OVI enhancement BTF-B06 as approved by WG1364 on 6/28/1998. */ parameter_value_opt : '#' '(' expression_list_with_nuls ')' { struct parmvalue_t*tmp = new struct parmvalue_t; tmp->by_order = $3; tmp->by_name = 0; $$ = tmp; } | '#' '(' parameter_value_byname_list ')' { struct parmvalue_t*tmp = new struct parmvalue_t; tmp->by_order = 0; tmp->by_name = $3; $$ = tmp; } | '#' DEC_NUMBER { assert($2); PENumber*tmp = new PENumber($2); FILE_NAME(tmp, @1); struct parmvalue_t*lst = new struct parmvalue_t; lst->by_order = new std::list; lst->by_order->push_back(tmp); lst->by_name = 0; $$ = lst; based_size = 0; } | '#' REALTIME { assert($2); PEFNumber*tmp = new PEFNumber($2); FILE_NAME(tmp, @1); struct parmvalue_t*lst = new struct parmvalue_t; lst->by_order = new std::list; lst->by_order->push_back(tmp); lst->by_name = 0; $$ = lst; } | '#' error { yyerror(@1, "error: Syntax error in parameter value assignment list."); $$ = 0; } | { $$ = 0; } ; parameter_value_byname : '.' IDENTIFIER '(' expression ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($2); tmp->parm = $4; delete[]$2; $$ = tmp; } | '.' IDENTIFIER '(' ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($2); tmp->parm = 0; delete[]$2; $$ = tmp; } ; parameter_value_byname_list : parameter_value_byname { std::list*tmp = new std::list; tmp->push_back(*$1); delete $1; $$ = tmp; } | parameter_value_byname_list ',' parameter_value_byname { std::list*tmp = $1; tmp->push_back(*$3); delete $3; $$ = tmp; } ; /* The port (of a module) is a fairly complex item. Each port is handled as a Module::port_t object. A simple port reference has a name and a PExpr object, but more complex constructs are possible where the name can be attached to a list of PWire objects. The port_reference returns a Module::port_t, and so does the port_reference_list. The port_reference_list may have built up a list of PWires in the port_t object, but it is still a single Module::port_t object. The port rule below takes the built up Module::port_t object and tweaks its name as needed. */ port : port_reference { $$ = $1; } /* This syntax attaches an external name to the port reference so that the caller can bind by name to non-trivial port references. The port_t object gets its PWire from the port_reference, but its name from the IDENTIFIER. */ | '.' IDENTIFIER '(' port_reference ')' { Module::port_t*tmp = $4; tmp->name = lex_strings.make($2); delete[]$2; $$ = tmp; } /* A port can also be a concatenation of port references. In this case the port does not have a name available to the outside, only positional parameter passing is possible here. */ | '{' port_reference_list '}' { Module::port_t*tmp = $2; tmp->name = perm_string(); $$ = tmp; } /* This attaches a name to a port reference concatenation list so that parameter passing be name is possible. */ | '.' IDENTIFIER '(' '{' port_reference_list '}' ')' { Module::port_t*tmp = $5; tmp->name = lex_strings.make($2); delete[]$2; $$ = tmp; } ; port_opt : port { $$ = $1; } | { $$ = 0; } ; /* The port_name rule is used with a module is being *instantiated*, and not when it is being declared. See the port rule if you are looking for the ports of a module declaration. */ port_name : attribute_list_opt '.' IDENTIFIER '(' expression ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($3); tmp->parm = $5; delete[]$3; delete $1; $$ = tmp; } | attribute_list_opt '.' IDENTIFIER '(' error ')' { yyerror(@3, "error: Invalid port connection expression."); named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($3); tmp->parm = 0; delete[]$3; delete $1; $$ = tmp; } | attribute_list_opt '.' IDENTIFIER '(' ')' { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($3); tmp->parm = 0; delete[]$3; delete $1; $$ = tmp; } | attribute_list_opt '.' IDENTIFIER { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make($3); tmp->parm = new PEIdent(lex_strings.make($3), true); FILE_NAME(tmp->parm, @1); delete[]$3; delete $1; $$ = tmp; } | K_DOTSTAR { named_pexpr_t*tmp = new named_pexpr_t; tmp->name = lex_strings.make("*"); tmp->parm = 0; $$ = tmp; } ; port_name_list : port_name_list ',' port_name { std::list*tmp = $1; tmp->push_back(*$3); delete $3; $$ = tmp; } | port_name { std::list*tmp = new std::list; tmp->push_back(*$1); delete $1; $$ = tmp; } ; port_conn_expression_list_with_nuls : port_conn_expression_list_with_nuls ',' attribute_list_opt expression { std::list*tmp = $1; tmp->push_back($4); delete $3; $$ = tmp; } | attribute_list_opt expression { std::list*tmp = new std::list; tmp->push_back($2); delete $1; $$ = tmp; } | { std::list*tmp = new std::list; tmp->push_back(0); $$ = tmp; } | port_conn_expression_list_with_nuls ',' { std::list*tmp = $1; tmp->push_back(0); $$ = tmp; } ; /* A port reference is an internal (to the module) name of the port, possibly with a part of bit select to attach it to specific bits of a signal fully declared inside the module. The parser creates a PEIdent for every port reference, even if the signal is bound to different ports. The elaboration figures out the mess that this creates. The port_reference (and the port_reference_list below) puts the port reference PEIdent into the port_t object to pass it up to the module declaration code. */ port_reference : IDENTIFIER { Module::port_t*ptmp; perm_string name = lex_strings.make($1); ptmp = pform_module_port_reference(@1, name); delete[]$1; $$ = ptmp; } | IDENTIFIER '[' expression ':' expression ']' { index_component_t itmp; itmp.sel = index_component_t::SEL_PART; itmp.msb = $3; itmp.lsb = $5; name_component_t ntmp (lex_strings.make($1)); ntmp.index.push_back(itmp); pform_name_t pname; pname.push_back(ntmp); PEIdent*wtmp = new PEIdent(pname); FILE_NAME(wtmp, @1); Module::port_t*ptmp = new Module::port_t; ptmp->name = perm_string(); ptmp->expr.push_back(wtmp); ptmp->default_value = 0; delete[]$1; $$ = ptmp; } | IDENTIFIER '[' expression ']' { index_component_t itmp; itmp.sel = index_component_t::SEL_BIT; itmp.msb = $3; itmp.lsb = 0; name_component_t ntmp (lex_strings.make($1)); ntmp.index.push_back(itmp); pform_name_t pname; pname.push_back(ntmp); PEIdent*tmp = new PEIdent(pname); FILE_NAME(tmp, @1); Module::port_t*ptmp = new Module::port_t; ptmp->name = perm_string(); ptmp->expr.push_back(tmp); ptmp->default_value = 0; delete[]$1; $$ = ptmp; } | IDENTIFIER '[' error ']' { yyerror(@1, "error: Invalid port bit select"); Module::port_t*ptmp = new Module::port_t; PEIdent*wtmp = new PEIdent(lex_strings.make($1)); FILE_NAME(wtmp, @1); ptmp->name = lex_strings.make($1); ptmp->expr.push_back(wtmp); ptmp->default_value = 0; delete[]$1; $$ = ptmp; } ; port_reference_list : port_reference { $$ = $1; } | port_reference_list ',' port_reference { Module::port_t*tmp = $1; append(tmp->expr, $3->expr); delete $3; $$ = tmp; } ; /* The range is a list of variable dimensions. */ dimensions_opt : { $$ = 0; } | dimensions { $$ = $1; } ; dimensions : variable_dimension { $$ = $1; } | dimensions variable_dimension { std::list *tmp = $1; if ($2) { tmp->splice(tmp->end(), *$2); delete $2; } $$ = tmp; } ; net_variable : IDENTIFIER dimensions_opt { perm_string name = lex_strings.make($1); $$ = pform_makewire(@1, name, NetNet::IMPLICIT, $2); delete [] $1; } ; net_variable_list : net_variable { std::vector *tmp = new std::vector; tmp->push_back($1); $$ = tmp; } | net_variable_list ',' net_variable { $1->push_back($3); $$ = $1; } ; event_variable : IDENTIFIER dimensions_opt { if ($2) { yyerror(@2, "sorry: event arrays are not supported."); delete $2; } $$ = $1; } ; event_variable_list : event_variable { $$ = list_from_identifier($1); } | event_variable_list ',' event_variable { $$ = list_from_identifier($1, $3); } ; specify_item : K_specparam specparam_decl ';' | specify_simple_path_decl ';' { pform_module_specify_path($1); } | specify_edge_path_decl ';' { pform_module_specify_path($1); } | K_if '(' expression ')' specify_simple_path_decl ';' { PSpecPath*tmp = $5; if (tmp) { tmp->conditional = true; tmp->condition = $3; } pform_module_specify_path(tmp); } | K_if '(' expression ')' specify_edge_path_decl ';' { PSpecPath*tmp = $5; if (tmp) { tmp->conditional = true; tmp->condition = $3; } pform_module_specify_path(tmp); } | K_ifnone specify_simple_path_decl ';' { PSpecPath*tmp = $2; if (tmp) { tmp->conditional = true; tmp->condition = 0; } pform_module_specify_path(tmp); } | K_ifnone specify_edge_path_decl ';' { yywarn(@1, "sorry: ifnone with an edge-sensitive path is not supported."); yyerrok; } | K_Sfullskew '(' spec_reference_event ',' spec_reference_event ',' delay_value ',' delay_value spec_notifier_opt ')' ';' { delete $7; delete $9; } | K_Shold '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Snochange '(' spec_reference_event ',' spec_reference_event ',' delay_value ',' delay_value spec_notifier_opt ')' ';' { delete $7; delete $9; } | K_Speriod '(' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $5; } | K_Srecovery '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Srecrem '(' spec_reference_event ',' spec_reference_event ',' delay_value ',' delay_value spec_notifier_opt ')' ';' { delete $7; delete $9; } | K_Sremoval '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Ssetup '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Ssetuphold '(' spec_reference_event ',' spec_reference_event ',' delay_value ',' delay_value spec_notifier_opt ')' ';' { delete $7; delete $9; } | K_Sskew '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Stimeskew '(' spec_reference_event ',' spec_reference_event ',' delay_value spec_notifier_opt ')' ';' { delete $7; } | K_Swidth '(' spec_reference_event ',' delay_value ',' expression spec_notifier_opt ')' ';' { delete $5; delete $7; } | K_Swidth '(' spec_reference_event ',' delay_value ')' ';' { delete $5; } | K_pulsestyle_onevent specify_path_identifiers ';' { delete $2; } | K_pulsestyle_ondetect specify_path_identifiers ';' { delete $2; } | K_showcancelled specify_path_identifiers ';' { delete $2; } | K_noshowcancelled specify_path_identifiers ';' { delete $2; } ; specify_item_list : specify_item | specify_item_list specify_item ; specify_item_list_opt : /* empty */ { } | specify_item_list { } specify_edge_path_decl : specify_edge_path '=' '(' delay_value_list ')' { $$ = pform_assign_path_delay($1, $4); } | specify_edge_path '=' delay_value_simple { std::list*tmp = new std::list; tmp->push_back($3); $$ = pform_assign_path_delay($1, tmp); } ; edge_operator : K_posedge { $$ = true; } | K_negedge { $$ = false; } ; specify_edge_path : '(' specify_path_identifiers spec_polarity K_EG '(' specify_path_identifiers polarity_operator expression ')' ')' { int edge_flag = 0; $$ = pform_make_specify_edge_path(@1, edge_flag, $2, $3, false, $6, $8); } | '(' edge_operator specify_path_identifiers spec_polarity K_EG '(' specify_path_identifiers polarity_operator expression ')' ')' { int edge_flag = $2? 1 : -1; $$ = pform_make_specify_edge_path(@1, edge_flag, $3, $4, false, $7, $9); } | '(' specify_path_identifiers spec_polarity K_SG '(' specify_path_identifiers polarity_operator expression ')' ')' { int edge_flag = 0; $$ = pform_make_specify_edge_path(@1, edge_flag, $2, $3, true, $6, $8); } | '(' edge_operator specify_path_identifiers spec_polarity K_SG '(' specify_path_identifiers polarity_operator expression ')' ')' { int edge_flag = $2? 1 : -1; $$ = pform_make_specify_edge_path(@1, edge_flag, $3, $4, true, $7, $9); } ; polarity_operator : K_PO_POS | K_PO_NEG | ':' ; specify_simple_path_decl : specify_simple_path '=' '(' delay_value_list ')' { $$ = pform_assign_path_delay($1, $4); } | specify_simple_path '=' delay_value_simple { std::list*tmp = new std::list; tmp->push_back($3); $$ = pform_assign_path_delay($1, tmp); } | specify_simple_path '=' '(' error ')' { yyerror(@3, "Syntax error in delay value list."); yyerrok; $$ = 0; } ; specify_simple_path : '(' specify_path_identifiers spec_polarity K_EG specify_path_identifiers ')' { $$ = pform_make_specify_path(@1, $2, $3, false, $5); } | '(' specify_path_identifiers spec_polarity K_SG specify_path_identifiers ')' { $$ = pform_make_specify_path(@1, $2, $3, true, $5); } | '(' error ')' { yyerror(@1, "Invalid simple path"); yyerrok; } ; specify_path_identifiers : IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); $$ = tmp; delete[]$1; } | IDENTIFIER '[' expr_primary ']' { if (gn_specify_blocks_flag) { yywarn(@4, "warning: Bit selects are not currently supported " "in path declarations. The declaration " "will be applied to the whole vector."); } std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); $$ = tmp; delete[]$1; } | IDENTIFIER '[' expr_primary polarity_operator expr_primary ']' { if (gn_specify_blocks_flag) { yywarn(@4, "warning: Part selects are not currently supported " "in path declarations. The declaration " "will be applied to the whole vector."); } std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); $$ = tmp; delete[]$1; } | specify_path_identifiers ',' IDENTIFIER { std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); $$ = tmp; delete[]$3; } | specify_path_identifiers ',' IDENTIFIER '[' expr_primary ']' { if (gn_specify_blocks_flag) { yywarn(@4, "warning: Bit selects are not currently supported " "in path declarations. The declaration " "will be applied to the whole vector."); } std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); $$ = tmp; delete[]$3; } | specify_path_identifiers ',' IDENTIFIER '[' expr_primary polarity_operator expr_primary ']' { if (gn_specify_blocks_flag) { yywarn(@4, "warning: Part selects are not currently supported " "in path declarations. The declaration " "will be applied to the whole vector."); } std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); $$ = tmp; delete[]$3; } ; specparam : IDENTIFIER '=' expression { PExpr*tmp = $3; pform_set_specparam(@1, lex_strings.make($1), specparam_active_range, tmp); delete[]$1; } | IDENTIFIER '=' expression ':' expression ':' expression { PExpr*tmp = 0; switch (min_typ_max_flag) { case MIN: tmp = $3; delete $5; delete $7; break; case TYP: delete $3; tmp = $5; delete $7; break; case MAX: delete $3; delete $5; tmp = $7; break; } if (min_typ_max_warn > 0) { cerr << tmp->get_fileline() << ": warning: Choosing "; switch (min_typ_max_flag) { case MIN: cerr << "min"; break; case TYP: cerr << "typ"; break; case MAX: cerr << "max"; break; } cerr << " expression." << endl; min_typ_max_warn -= 1; } pform_set_specparam(@1, lex_strings.make($1), specparam_active_range, tmp); delete[]$1; } | PATHPULSE_IDENTIFIER '=' expression { delete[]$1; delete $3; } | PATHPULSE_IDENTIFIER '=' '(' expression ',' expression ')' { delete[]$1; delete $4; delete $6; } ; specparam_list : specparam | specparam_list ',' specparam ; specparam_decl : specparam_list | dimensions { specparam_active_range = $1; } specparam_list { specparam_active_range = 0; } ; spec_polarity : '+' { $$ = '+'; } | '-' { $$ = '-'; } | { $$ = 0; } ; spec_reference_event : K_posedge expression { delete $2; } | K_negedge expression { delete $2; } | K_posedge expr_primary K_TAND expression { delete $2; delete $4; } | K_negedge expr_primary K_TAND expression { delete $2; delete $4; } | K_edge '[' edge_descriptor_list ']' expr_primary { delete $5; } | K_edge '[' edge_descriptor_list ']' expr_primary K_TAND expression { delete $5; delete $7; } | expr_primary K_TAND expression { delete $1; delete $3; } | expr_primary { delete $1; } ; /* The edge_descriptor is detected by the lexor as the various 2-letter edge sequences that are supported here. For now, we don't care what they are, because we do not yet support specify edge events. */ edge_descriptor_list : edge_descriptor_list ',' K_edge_descriptor | K_edge_descriptor ; spec_notifier_opt : /* empty */ { } | spec_notifier { } ; spec_notifier : ',' { args_after_notifier = 0; } | ',' hierarchy_identifier { args_after_notifier = 0; delete $2; } | spec_notifier ',' { args_after_notifier += 1; } | spec_notifier ',' hierarchy_identifier { args_after_notifier += 1; if (args_after_notifier >= 3) { cerr << @3 << ": warning: Timing checks are not supported " "and delayed signal \"" << *$3 << "\" will not be driven." << endl; } delete $3; } /* How do we match this path? */ | IDENTIFIER { args_after_notifier = 0; delete[]$1; } ; subroutine_call : hierarchy_identifier argument_list_parens_opt { PCallTask*tmp = pform_make_call_task(@1, *$1, *$2); delete $1; delete $2; $$ = tmp; } | class_hierarchy_identifier argument_list_parens_opt { PCallTask*tmp = new PCallTask(*$1, *$2); FILE_NAME(tmp, @1); delete $1; delete $2; $$ = tmp; } | SYSTEM_IDENTIFIER argument_list_parens_opt { PCallTask*tmp = new PCallTask(lex_strings.make($1), *$2); FILE_NAME(tmp,@1); delete[]$1; delete $2; $$ = tmp; } | hierarchy_identifier '(' error ')' { yyerror(@3, "error: Syntax error in task arguments."); listpt; PCallTask*tmp = pform_make_call_task(@1, *$1, pt); delete $1; $$ = tmp; } ; statement_item /* This is roughly statement_item in the LRM */ /* assign and deassign statements are procedural code to do structural assignments, and to turn that structural assignment off. This is stronger than any other assign, but weaker than the force assignments. */ : K_assign lpvalue '=' expression ';' { PCAssign*tmp = new PCAssign($2, $4); FILE_NAME(tmp, @1); $$ = tmp; } | K_deassign lpvalue ';' { PDeassign*tmp = new PDeassign($2); FILE_NAME(tmp, @1); $$ = tmp; } /* Force and release statements are similar to assignments, syntactically, but they will be elaborated differently. */ | K_force lpvalue '=' expression ';' { PForce*tmp = new PForce($2, $4); FILE_NAME(tmp, @1); $$ = tmp; } | K_release lpvalue ';' { PRelease*tmp = new PRelease($2); FILE_NAME(tmp, @1); $$ = tmp; } /* begin-end blocks come in a variety of forms, including named and anonymous. The named blocks can also carry their own reg variables, which are placed in the scope created by the block name. These are handled by pushing the scope name, then matching the declarations. The scope is popped at the end of the block. */ /* In SystemVerilog an unnamed block can contain variable declarations. */ | K_begin label_opt { PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_SEQ); current_block_stack.push(tmp); } block_item_decls_opt { if (!$2) { if ($4) { pform_requires_sv(@4, "Variable declaration in unnamed block"); } else { /* If there are no declarations in the scope then just delete it. */ pform_pop_scope(); assert(! current_block_stack.empty()); PBlock*tmp = current_block_stack.top(); current_block_stack.pop(); delete tmp; } } } statement_or_null_list_opt K_end label_opt { PBlock*tmp; if ($2 || $4) { pform_pop_scope(); assert(! current_block_stack.empty()); tmp = current_block_stack.top(); current_block_stack.pop(); } else { tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, @1); } if ($6) tmp->set_statement(*$6); delete $6; check_end_label(@8, "block", $2, $8); delete[]$2; $$ = tmp; } /* fork-join blocks are very similar to begin-end blocks. In fact, from the parser's perspective there is no real difference. All we need to do is remember that this is a parallel block so that the code generator can do the right thing. */ /* In SystemVerilog an unnamed block can contain variable declarations. */ | K_fork label_opt { PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_PAR); current_block_stack.push(tmp); } block_item_decls_opt { if (!$2) { if ($4) { pform_requires_sv(@4, "Variable declaration in unnamed block"); } else { /* If there are no declarations in the scope then just delete it. */ pform_pop_scope(); assert(! current_block_stack.empty()); PBlock*tmp = current_block_stack.top(); current_block_stack.pop(); delete tmp; } } } statement_or_null_list_opt join_keyword label_opt { PBlock*tmp; if ($2 || $4) { pform_pop_scope(); assert(! current_block_stack.empty()); tmp = current_block_stack.top(); current_block_stack.pop(); tmp->set_join_type($7); } else { tmp = new PBlock($7); FILE_NAME(tmp, @1); } if ($6) tmp->set_statement(*$6); delete $6; check_end_label(@8, "fork", $2, $8); delete[]$2; $$ = tmp; } | K_disable hierarchy_identifier ';' { PDisable*tmp = new PDisable(*$2); FILE_NAME(tmp, @1); delete $2; $$ = tmp; } | K_disable K_fork ';' { pform_name_t tmp_name; PDisable*tmp = new PDisable(tmp_name); FILE_NAME(tmp, @1); $$ = tmp; } | K_TRIGGER hierarchy_identifier ';' { PTrigger*tmp = pform_new_trigger(@2, 0, *$2); delete $2; $$ = tmp; } | K_TRIGGER package_scope hierarchy_identifier { lex_in_package_scope(0); PTrigger*tmp = pform_new_trigger(@3, $2, *$3); delete $3; $$ = tmp; } /* FIXME: Does this need support for package resolution like above? */ | K_NB_TRIGGER hierarchy_identifier ';' { PNBTrigger*tmp = pform_new_nb_trigger(@2, 0, *$2); delete $2; $$ = tmp; } | K_NB_TRIGGER delay1 hierarchy_identifier ';' { PNBTrigger*tmp = pform_new_nb_trigger(@3, $2, *$3); delete $3; $$ = tmp; } | K_NB_TRIGGER event_control hierarchy_identifier ';' { PNBTrigger*tmp = pform_new_nb_trigger(@3, 0, *$3); delete $3; $$ = tmp; yywarn(@1, "sorry: ->> with event control is not currently supported."); } | K_NB_TRIGGER K_repeat '(' expression ')' event_control hierarchy_identifier ';' { PNBTrigger*tmp = pform_new_nb_trigger(@7, 0, *$7); delete $7; $$ = tmp; yywarn(@1, "sorry: ->> with repeat event control is not currently supported."); } | procedural_assertion_statement { $$ = $1; } | loop_statement { $$ = $1; } | jump_statement { $$ = $1; } | unique_priority K_case '(' expression ')' case_items K_endcase { PCase*tmp = new PCase($1, NetCase::EQ, $4, $6); FILE_NAME(tmp, @2); $$ = tmp; } | unique_priority K_casex '(' expression ')' case_items K_endcase { PCase*tmp = new PCase($1, NetCase::EQX, $4, $6); FILE_NAME(tmp, @2); $$ = tmp; } | unique_priority K_casez '(' expression ')' case_items K_endcase { PCase*tmp = new PCase($1, NetCase::EQZ, $4, $6); FILE_NAME(tmp, @1); $$ = tmp; } | unique_priority K_case '(' expression ')' error K_endcase { yyerrok; } | unique_priority K_casex '(' expression ')' error K_endcase { yyerrok; } | unique_priority K_casez '(' expression ')' error K_endcase { yyerrok; } | K_if '(' expression ')' statement_or_null %prec less_than_K_else { PCondit*tmp = new PCondit($3, $5, 0); FILE_NAME(tmp, @1); $$ = tmp; } | K_if '(' expression ')' statement_or_null K_else statement_or_null { PCondit*tmp = new PCondit($3, $5, $7); FILE_NAME(tmp, @1); $$ = tmp; } | K_if '(' error ')' statement_or_null %prec less_than_K_else { yyerror(@1, "error: Malformed conditional expression."); $$ = $5; } | K_if '(' error ')' statement_or_null K_else statement_or_null { yyerror(@1, "error: Malformed conditional expression."); $$ = $5; } /* SystemVerilog adds the compressed_statement */ | compressed_statement ';' { $$ = $1; } /* increment/decrement expressions can also be statements. When used as statements, we can rewrite a++ as a += 1, and so on. */ | inc_or_dec_expression ';' { $$ = pform_compressed_assign_from_inc_dec(@1, $1); } /* */ | delay1 statement_or_null { PExpr*del = $1->front(); assert($1->size() == 1); delete $1; PDelayStatement*tmp = new PDelayStatement(del, $2); FILE_NAME(tmp, @1); $$ = tmp; } | event_control statement_or_null { PEventStatement*tmp = $1; if (tmp == 0) { yyerror(@1, "error: Invalid event control."); $$ = 0; } else { tmp->set_statement($2); $$ = tmp; } } | '@' '*' statement_or_null { PEventStatement*tmp = new PEventStatement; FILE_NAME(tmp, @1); tmp->set_statement($3); $$ = tmp; } | '@' '(' '*' ')' statement_or_null { PEventStatement*tmp = new PEventStatement; FILE_NAME(tmp, @1); tmp->set_statement($5); $$ = tmp; } /* Various assignment statements */ | lpvalue '=' expression ';' { PAssign*tmp = new PAssign($1,$3); FILE_NAME(tmp, @1); $$ = tmp; } | error '=' expression ';' { yyerror(@2, "Syntax in assignment statement l-value."); yyerrok; $$ = new PNoop; } | lpvalue K_LE expression ';' { PAssignNB*tmp = new PAssignNB($1,$3); FILE_NAME(tmp, @1); $$ = tmp; } | error K_LE expression ';' { yyerror(@2, "Syntax in assignment statement l-value."); yyerrok; $$ = new PNoop; } | lpvalue '=' delay1 expression ';' { PExpr*del = $3->front(); $3->pop_front(); assert($3->empty()); PAssign*tmp = new PAssign($1,del,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue K_LE delay1 expression ';' { PExpr*del = $3->front(); $3->pop_front(); assert($3->empty()); PAssignNB*tmp = new PAssignNB($1,del,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue '=' event_control expression ';' { PAssign*tmp = new PAssign($1,0,$3,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue '=' K_repeat '(' expression ')' event_control expression ';' { PAssign*tmp = new PAssign($1,$5,$7,$8); FILE_NAME(tmp,@1); $$ = tmp; } | lpvalue K_LE event_control expression ';' { PAssignNB*tmp = new PAssignNB($1,0,$3,$4); FILE_NAME(tmp, @1); $$ = tmp; } | lpvalue K_LE K_repeat '(' expression ')' event_control expression ';' { PAssignNB*tmp = new PAssignNB($1,$5,$7,$8); FILE_NAME(tmp, @1); $$ = tmp; } /* The IEEE1800 standard defines dynamic_array_new assignment as a different rule from regular assignment. That implies that the dynamic_array_new is not an expression in general, which makes some sense. Elaboration should make sure the lpvalue is an array name. */ | lpvalue '=' dynamic_array_new ';' { PAssign*tmp = new PAssign($1,$3); FILE_NAME(tmp, @1); $$ = tmp; } /* The class new and dynamic array new expressions are special, so sit in rules of their own. */ | lpvalue '=' class_new ';' { PAssign*tmp = new PAssign($1,$3); FILE_NAME(tmp, @1); $$ = tmp; } | K_wait '(' expression ')' statement_or_null { PEventStatement*tmp; PEEvent*etmp = new PEEvent(PEEvent::POSITIVE, $3); tmp = new PEventStatement(etmp); FILE_NAME(tmp,@1); tmp->set_statement($5); $$ = tmp; } | K_wait K_fork ';' { PEventStatement*tmp = new PEventStatement((PEEvent*)0); FILE_NAME(tmp,@1); $$ = tmp; } | K_void '\'' '(' subroutine_call ')' ';' { $4->void_cast(); $$ = $4; } | subroutine_call ';' { $$ = $1; } | hierarchy_identifier K_with '{' constraint_block_item_list_opt '}' ';' { /* ....randomize with { } */ if ($1 && peek_tail_name(*$1) == "randomize") { if (pform_requires_sv(@2, "Randomize with constraint")) yyerror(@2, "sorry: Randomize with constraint not supported."); } else { yyerror(@2, "error: Constraint block can only be applied to randomize method."); } listpt; PCallTask*tmp = new PCallTask(*$1, pt); FILE_NAME(tmp, @1); delete $1; $$ = tmp; } /* IEEE1800 A.1.8: class_constructor_declaration with a call to parent constructor. Note that the implicit_class_handle must be K_super ("this.new" makes little sense) but that would cause a conflict. Anyhow, this statement must be in the beginning of a constructor, but let the elaborator figure that out. */ | implicit_class_handle K_new argument_list_parens_opt ';' { PChainConstructor*tmp = new PChainConstructor(*$3); FILE_NAME(tmp, @3); if (peek_head_name(*$1) == THIS_TOKEN) { yyerror(@1, "error: this.new is invalid syntax. Did you mean super.new?"); } delete $1; $$ = tmp; } | error ';' { yyerror(@2, "error: Malformed statement"); yyerrok; $$ = new PNoop; } ; compressed_operator : K_PLUS_EQ { $$ = '+'; } | K_MINUS_EQ { $$ = '-'; } | K_MUL_EQ { $$ = '*'; } | K_DIV_EQ { $$ = '/'; } | K_MOD_EQ { $$ = '%'; } | K_AND_EQ { $$ = '&'; } | K_OR_EQ { $$ = '|'; } | K_XOR_EQ { $$ = '^'; } | K_LS_EQ { $$ = 'l'; } | K_RS_EQ { $$ = 'r'; } | K_RSS_EQ { $$ = 'R'; } ; compressed_statement : lpvalue compressed_operator expression { PAssign*tmp = new PAssign($1, $2, $3); FILE_NAME(tmp, @1); $$ = tmp; } ; statement_or_null_list_opt : statement_or_null_list { $$ = $1; } | { $$ = 0; } ; statement_or_null_list : statement_or_null_list statement_or_null { std::vector*tmp = $1; if ($2) tmp->push_back($2); $$ = tmp; } | statement_or_null { std::vector*tmp = new std::vector(0); if ($1) tmp->push_back($1); $$ = tmp; } ; analog_statement : branch_probe_expression K_CONTRIBUTE expression ';' { $$ = pform_contribution_statement(@2, $1, $3); } ; tf_port_list_opt : tf_port_list { $$ = $1; } | { $$ = 0; } ; /* A task or function prototype can be declared with the task/function name * followed by a port list in parenthesis or or just the task/function name by * itself. When a port list is used it might be empty. */ tf_port_list_parens_opt : '(' tf_port_list_opt ')' { $$ = $2; } | { $$ = 0; } /* Note that the lexor notices the "table" keyword and starts the UDPTABLE state. It needs to happen there so that all the characters in the table are interpreted in that mode. It is still up to this rule to take us out of the UDPTABLE state. */ udp_body : K_table udp_entry_list K_endtable { lex_end_table(); $$ = $2; } | K_table K_endtable { lex_end_table(); yyerror(@1, "error: Empty UDP table."); $$ = 0; } | K_table error K_endtable { lex_end_table(); yyerror(@2, "Errors in UDP table"); yyerrok; $$ = 0; } ; udp_entry_list : udp_comb_entry_list | udp_sequ_entry_list ; udp_comb_entry : udp_input_list ':' udp_output_sym ';' { char*tmp = new char[strlen($1)+3]; strcpy(tmp, $1); char*tp = tmp+strlen(tmp); *tp++ = ':'; *tp++ = $3; *tp++ = 0; delete[]$1; $$ = tmp; } ; udp_comb_entry_list : udp_comb_entry { std::list*tmp = new std::list; tmp->push_back($1); delete[]$1; $$ = tmp; } | udp_comb_entry_list udp_comb_entry { std::list*tmp = $1; tmp->push_back($2); delete[]$2; $$ = tmp; } ; udp_sequ_entry_list : udp_sequ_entry { std::list*tmp = new std::list; tmp->push_back($1); delete[]$1; $$ = tmp; } | udp_sequ_entry_list udp_sequ_entry { std::list*tmp = $1; tmp->push_back($2); delete[]$2; $$ = tmp; } ; udp_sequ_entry : udp_input_list ':' udp_input_sym ':' udp_output_sym ';' { char*tmp = new char[strlen($1)+5]; strcpy(tmp, $1); char*tp = tmp+strlen(tmp); *tp++ = ':'; *tp++ = $3; *tp++ = ':'; *tp++ = $5; *tp++ = 0; $$ = tmp; } ; udp_initial : K_initial IDENTIFIER '=' number ';' { PExpr*etmp = new PENumber($4); PEIdent*itmp = new PEIdent(lex_strings.make($2)); PAssign*atmp = new PAssign(itmp, etmp); FILE_NAME(atmp, @2); delete[]$2; $$ = atmp; } ; udp_init_opt : udp_initial { $$ = $1; } | { $$ = 0; } ; udp_input_list : udp_input_sym { char*tmp = new char[2]; tmp[0] = $1; tmp[1] = 0; $$ = tmp; } | udp_input_list udp_input_sym { char*tmp = new char[strlen($1)+2]; strcpy(tmp, $1); char*tp = tmp+strlen(tmp); *tp++ = $2; *tp++ = 0; delete[]$1; $$ = tmp; } ; udp_input_sym : '0' { $$ = '0'; } | '1' { $$ = '1'; } | 'x' { $$ = 'x'; } | '?' { $$ = '?'; } | 'b' { $$ = 'b'; } | '*' { $$ = '*'; } | '%' { $$ = '%'; } | 'f' { $$ = 'f'; } | 'F' { $$ = 'F'; } | 'l' { $$ = 'l'; } | 'h' { $$ = 'h'; } | 'B' { $$ = 'B'; } | 'r' { $$ = 'r'; } | 'R' { $$ = 'R'; } | 'M' { $$ = 'M'; } | 'n' { $$ = 'n'; } | 'N' { $$ = 'N'; } | 'p' { $$ = 'p'; } | 'P' { $$ = 'P'; } | 'Q' { $$ = 'Q'; } | 'q' { $$ = 'q'; } | '_' { $$ = '_'; } | '+' { $$ = '+'; } | DEC_NUMBER { yyerror(@1, "internal error: Input digits parse as decimal number!"); $$ = '0'; } ; udp_output_sym : '0' { $$ = '0'; } | '1' { $$ = '1'; } | 'x' { $$ = 'x'; } | '-' { $$ = '-'; } | DEC_NUMBER { yyerror(@1, "internal error: Output digits parse as decimal number!"); $$ = '0'; } ; /* Port declarations create wires for the inputs and the output. The makes for these ports are scoped within the UDP, so there is no hierarchy involved. */ udp_port_decl : K_input list_of_identifiers ';' { $$ = pform_make_udp_input_ports($2); } | K_output IDENTIFIER ';' { perm_string pname = lex_strings.make($2); PWire*pp = new PWire(pname, NetNet::IMPLICIT, NetNet::POUTPUT); vector*tmp = new std::vector(1); (*tmp)[0] = pp; $$ = tmp; delete[]$2; } | K_reg IDENTIFIER ';' { perm_string pname = lex_strings.make($2); PWire*pp = new PWire(pname, NetNet::REG, NetNet::PIMPLICIT); vector*tmp = new std::vector(1); (*tmp)[0] = pp; $$ = tmp; delete[]$2; } | K_output K_reg IDENTIFIER ';' { perm_string pname = lex_strings.make($3); PWire*pp = new PWire(pname, NetNet::REG, NetNet::POUTPUT); vector*tmp = new std::vector(1); (*tmp)[0] = pp; $$ = tmp; delete[]$3; } ; udp_port_decls : udp_port_decl { $$ = $1; } | udp_port_decls udp_port_decl { std::vector*tmp = $1; size_t s1 = $1->size(); tmp->resize(s1+$2->size()); for (size_t idx = 0 ; idx < $2->size() ; idx += 1) tmp->at(s1+idx) = $2->at(idx); $$ = tmp; delete $2; } ; udp_port_list : IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } | udp_port_list ',' IDENTIFIER { std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); delete[]$3; $$ = tmp; } ; udp_reg_opt : K_reg { $$ = true; } | { $$ = false; }; udp_input_declaration_list : K_input IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($2)); $$ = tmp; delete[]$2; } | udp_input_declaration_list ',' K_input IDENTIFIER { std::list*tmp = $1; tmp->push_back(lex_strings.make($4)); $$ = tmp; delete[]$4; } ; udp_primitive /* This is the syntax for primitives that uses the IEEE1364-1995 format. The ports are simply names in the port list, and the declarations are in the body. */ : K_primitive IDENTIFIER '(' udp_port_list ')' ';' udp_port_decls udp_init_opt udp_body K_endprimitive label_opt { perm_string tmp2 = lex_strings.make($2); pform_make_udp(@2, tmp2, $4, $7, $9, $8); check_end_label(@11, "primitive", $2, $11); delete[]$2; } /* This is the syntax for IEEE1364-2001 format definitions. The port names and declarations are all in the parameter list. */ | K_primitive IDENTIFIER '(' K_output udp_reg_opt IDENTIFIER initializer_opt ',' udp_input_declaration_list ')' ';' udp_body K_endprimitive label_opt { perm_string tmp2 = lex_strings.make($2); perm_string tmp6 = lex_strings.make($6); pform_make_udp(@2, tmp2, $5, tmp6, $7, $9, $12); check_end_label(@14, "primitive", $2, $14); delete[]$2; delete[]$6; } ; unique_priority : { $$ = IVL_CASE_QUALITY_BASIC; } | K_unique { $$ = IVL_CASE_QUALITY_UNIQUE; } | K_unique0 { $$ = IVL_CASE_QUALITY_UNIQUE0; } | K_priority { $$ = IVL_CASE_QUALITY_PRIORITY; } ; /* Many keywords can be optional in the syntax, although their presence is significant. This is a fairly common pattern so collect those rules here. */ K_genvar_opt : K_genvar { $$ = true; } | { $$ = false; } ; K_static_opt : K_static { $$ = true; } | { $$ = false; } ; K_virtual_opt : K_virtual { $$ = true; } | { $$ = false; } ; K_var_opt : K_var | ; iverilog-12_0/parse_api.h000066400000000000000000000045161435245347300154710ustar00rootroot00000000000000#ifndef IVL_parse_api_H #define IVL_parse_api_H /* * Copyright (c) 2001-2021 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 "StringHeap.h" # include # include # include # include class Design; class Module; class PClass; class PPackage; class PTaskFunc; class PUdp; class data_type_t; struct enum_type_t; /* * These are maps of the modules and primitives parsed from the * Verilog source into pform for elaboration. The parser adds modules * to these maps as it compiles modules in the Verilog source. */ extern std::map pform_modules; extern std::map pform_primitives; extern std::vector pform_units; extern std::vector pform_packages; extern void pform_dump(std::ostream&out, const PClass*pac); extern void pform_dump(std::ostream&out, const PPackage*pac); extern void pform_dump(std::ostream&out, const PTaskFunc*tf); /* * This code actually invokes the parser to make modules. If the path * parameter is "-", the parser reads from stdin, otherwise it attempts * to open and read the specified file. When reading from a file, if * the ivlpp_string variable is not set to null, the file will be piped * through the command specified by ivlpp_string before being parsed. */ extern int pform_parse(const char*path); extern std::string vl_file; extern void pform_set_timescale(int units, int prec, const char*file, unsigned lineno); extern int def_ts_units; extern int def_ts_prec; #endif /* IVL_parse_api_H */ iverilog-12_0/parse_misc.cc000066400000000000000000000037771435245347300160210ustar00rootroot00000000000000/* * Copyright (c) 1998-2022 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 # include "parse_misc.h" # include # include using namespace std; extern const char*vl_file; unsigned error_count = 0; unsigned warn_count = 0; unsigned long based_size = 0; std::ostream& operator << (std::ostream&o, const YYLTYPE&loc) { if (loc.text) o << loc.text << ":"; else o << "<>:"; o << loc.first_line; return o; } void VLwarn(const char*msg) { warn_count += 1; cerr << yylloc.text << ":" << yylloc.first_line << ": " << msg << endl; } void VLerror(const char*msg) { error_count += 1; cerr << yylloc.text << ":" << yylloc.first_line << ": " << msg << endl; } void VLerror(const YYLTYPE&loc, const char*msg, ...) { va_list ap; va_start(ap, msg); fprintf(stderr, "%s:%d: ", loc.text, loc.first_line); vfprintf(stderr, msg, ap); va_end(ap); fprintf(stderr, "\n"); error_count += 1; based_size = 0; /* Clear the base information if we have an error. */ } void VLwarn(const YYLTYPE&loc, const char*msg) { warn_count += 1; cerr << loc << ": " << msg << endl; } int VLwrap() { return -1; } iverilog-12_0/parse_misc.h000066400000000000000000000072241435245347300156520ustar00rootroot00000000000000#ifndef IVL_parse_misc_H #define IVL_parse_misc_H /* * Copyright (c) 1998-2022 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 # include "compiler.h" # include "pform.h" /* * The vlltype supports the passing of detailed source file location * information between the lexical analyzer and the parser. Defining * YYLTYPE compels the lexor to use this type and not something other. */ struct vlltype { int first_line; int first_column; int last_line; int last_column; const char*text; std::string get_fileline() const; }; # define YYLTYPE struct vlltype class LineInfo; inline void FILE_NAME(LineInfo*tmp, const struct vlltype&where) { tmp->set_lineno(where.first_line); tmp->set_file(filename_strings.make(where.text)); } /* This for compatibility with new and older bison versions. */ #ifndef yylloc # define yylloc VLlloc #endif extern YYLTYPE yylloc; /* * Interface into the lexical analyzer. ... */ extern int VLlex(); extern void VLerror(const char*msg); extern void VLerror(const YYLTYPE&loc, const char*msg, ...) __attribute__((format(printf,2,3))); #define yywarn VLwarn extern void VLwarn(const char*msg); extern void VLwarn(const YYLTYPE&loc, const char*msg); extern void destroy_lexor(); extern std::ostream& operator << (std::ostream&, const YYLTYPE&loc); extern unsigned error_count, warn_count; extern unsigned long based_size; extern bool in_celldefine; enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 }; extern UCDriveType uc_drive; /* * The parser signals back to the lexor that the next identifier * should be in the package scope. For example, if the source is * :: * Then the parser calls this function to set the package context so * that the lexor can interpret in the package context. */ extern void lex_in_package_scope(PPackage*pkg); /* * Test if this identifier is a type identifier in the current * context. The pform code needs to help the lexor here because the * parser detects typedefs and marks the typedef'ed identifiers as * type names. */ extern typedef_t* pform_test_type_identifier(const YYLTYPE&loc, const char*txt); extern typedef_t* pform_test_type_identifier(PPackage*pkg, const char*txt); /* * Test if this identifier is a package name. The pform needs to help * the lexor here because the parser detects packages and saves them. */ extern PPackage* pform_test_package_identifier(const char*txt); /* * Export these functions because we have to generate PENumber class * in pform.cc for user defparam definition from command file. */ extern verinum*make_unsized_dec(const char*txt); extern verinum*make_undef_highz_dec(const char*txt); extern verinum*make_unsized_binary(const char*txt); extern verinum*make_unsized_octal(const char*txt); extern verinum*make_unsized_hex(const char*txt); extern char* strdupnew(char const *str); #endif /* IVL_parse_misc_H */ iverilog-12_0/pform.cc000066400000000000000000003057131435245347300150120ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 # include "compiler.h" # include "pform.h" # include "parse_misc.h" # include "parse_api.h" # include "PClass.h" # include "PEvent.h" # include "PPackage.h" # include "PUdp.h" # include "PGenerate.h" # include "PModport.h" # include "PSpec.h" # include "discipline.h" # include # include # include # include # include # include # include # include # include # include "ivl_assert.h" # include "ivl_alloc.h" using namespace std; /* * The "// synthesis translate_on/off" meta-comments cause this flag * to be turned off or on. The pform_make_behavior and similar * functions look at this flag and may choose to add implicit ivl * synthesis flags. */ static bool pform_mc_translate_flag = true; void pform_mc_translate_on(bool flag) { pform_mc_translate_flag = flag; } /* * The pform_modules is a map of the modules that have been defined in * the top level. This should not contain nested modules/programs. * pform_primitives is similar, but for UDP primitives. */ map pform_modules; map pform_primitives; /* * The pform_units is a list of the SystemVerilog compilation unit scopes. * The current compilation unit is the last element in the list. All items * declared or defined at the top level (outside any design element) are * added to the current compilation unit scope. */ vector pform_units; static bool is_compilation_unit(LexicalScope*scope) { // A compilation unit is the only scope that doesn't have a parent. assert(scope); return scope->parent_scope() == 0; } std::string vlltype::get_fileline() const { ostringstream buf; buf << (text? text : "") << ":" << first_line; string res = buf.str(); return res; } static bool is_hex_digit_str(const char *str) { while (*str) { if (!isxdigit(*str)) return false; str++; } return true; } static bool is_dec_digit_str(const char *str) { while (*str) { if (!isdigit(*str)) return false; str++; } return true; } static bool is_oct_digit_str(const char *str) { while (*str) { if (*str < '0' || *str > '7') return false; str++; } return true; } static bool is_bin_digit_str(const char *str) { while (*str) { if (*str != '0' && *str != '1') return false; str++; } return true; } /* * Parse configuration file with format =, where key * is the hierarchical name of a valid parameter name, and value * is the value user wants to assign to. The value should be constant. */ void parm_to_defparam_list(const string¶m) { char* key; char* value; unsigned off = param.find('='); if (off > param.size()) { key = strdup(param.c_str()); value = (char*)malloc(1); *value = '\0'; } else { key = strdup(param.substr(0, off).c_str()); value = strdup(param.substr(off+1).c_str()); } // Resolve hierarchical name for defparam. Remember // to deal with bit select for generate scopes. Bit // select expression should be constant integer. pform_name_t name; char *nkey = key; char *ptr = strchr(key, '.'); while (ptr != 0) { *ptr++ = '\0'; // Find if bit select is applied, this would be something // like - scope[2].param = 10 char *bit_l = strchr(nkey, '['); if (bit_l !=0) { *bit_l++ = '\0'; char *bit_r = strchr(bit_l, ']'); if (bit_r == 0) { cerr << ": error: missing ']' for defparam: " << nkey << endl; free(key); free(value); return; } *bit_r = '\0'; int i = 0; while (*(bit_l+i) != '\0') if (!isdigit(*(bit_l+i++))) { cerr << ": error: scope index expression is not constant: " << nkey << endl; free(key); free(value); return; } name_component_t tmp(lex_strings.make(nkey)); index_component_t index; index.sel = index_component_t::SEL_BIT; verinum *seln = new verinum(atoi(bit_l)); PENumber *sel = new PENumber(seln); index.msb = sel; index.lsb = sel; tmp.index.push_back(index); name.push_back(tmp); } else // no bit select name.push_back(name_component_t(lex_strings.make(nkey))); nkey = ptr; ptr = strchr(nkey, '.'); } name.push_back(name_component_t(lex_strings.make(nkey))); free(key); // Resolve value to PExpr class. Should support all kind of constant // format including based number, dec number, real number and string. // Is it a string? if (*value == '"') { char *buf = strdup (value); char *buf_ptr = buf+1; // Parse until another '"' or '\0' while (*buf_ptr != '"' && *buf_ptr != '\0') { buf_ptr++; // Check for escape, especially '\"', which does not mean the // end of string. if (*buf_ptr == '\\' && *(buf_ptr+1) != '\0') buf_ptr += 2; } if (*buf_ptr == '\0') // String end without '"' cerr << ": error: missing close quote of string for defparam: " << name << endl; else if (*(buf_ptr+1) != 0) { // '"' appears within string with no escape cerr << buf_ptr << endl; cerr << ": error: \'\"\' appears within string value for defparam: " << name << ". Ignore characters after \'\"\'" << endl; } *buf_ptr = '\0'; buf_ptr = buf+1; // Remember to use 'new' to allocate string for PEString // because 'delete' is used by its destructor. char *nchar = strcpy(new char [strlen(buf_ptr)+1], buf_ptr); PExpr* ndec = new PEString(nchar); Module::user_defparms.push_back( make_pair(name, ndec) ); free(buf); free(value); return; } // Is it a based number? char *num = strchr(value, '\''); if (num != 0) { verinum *val; const char *base = num + 1; if (*base == 's' || *base == 'S') base++; switch (*base) { case 'h': case 'H': if (is_hex_digit_str(base+1)) { val = make_unsized_hex(num); } else { cerr << ": error: invalid digit in hex value specified for defparam: " << name << endl; free(value); return; } break; case 'd': case 'D': if (is_dec_digit_str(base+1)) { val = make_unsized_dec(num); } else { cerr << ": error: invalid digit in decimal value specified for defparam: " << name << endl; free(value); return; } break; case 'o': case 'O': if (is_oct_digit_str(base+1)) { val = make_unsized_octal(num); } else { cerr << ": error: invalid digit in octal value specified for defparam: " << name << endl; free(value); return; } break; case 'b': case 'B': if (is_bin_digit_str(base+1)) { val = make_unsized_binary(num); } else { cerr << ": error: invalid digit in binary value specified for defparam: " << name << endl; free(value); return; } break; default: cerr << ": error: invalid numeric base specified for defparam: " << name << endl; free(value); return; } if (num != value) { // based number with size *num = 0; if (is_dec_digit_str(value)) { verinum *siz = make_unsized_dec(value); val = pform_verinum_with_size(siz, val, "", 0); } else { cerr << ": error: invalid size for value specified for defparam: " << name << endl; free(value); return; } } PExpr* ndec = new PENumber(val); Module::user_defparms.push_back( make_pair(name, ndec) ); free(value); return; } // Is it a decimal number? num = (value[0] == '-') ? value + 1 : value; if (num[0] != '\0' && is_dec_digit_str(num)) { verinum *val = make_unsized_dec(num); if (value[0] == '-') *val = -(*val); PExpr* ndec = new PENumber(val); Module::user_defparms.push_back( make_pair(name, ndec) ); free(value); return; } // Is it a real number? char *end = 0; double rval = strtod(value, &end); if (end != value && *end == 0) { verireal *val = new verireal(rval); PExpr* nreal = new PEFNumber(val); Module::user_defparms.push_back( make_pair(name, nreal) ); free(value); return; } // None of the above. cerr << ": error: invalid value specified for defparam: " << name << endl; free(value); } /* * The lexor accesses the vl_* variables. */ string vl_file = ""; extern int VLparse(); /* This tracks the current module being processed. There can only be exactly one module currently being parsed, since Verilog does not allow nested module definitions. */ static listpform_cur_module; bool pform_library_flag = false; /* * Give each unnamed block that has a variable declaration a unique name. */ static unsigned scope_unnamed_block_with_decl = 1; /* This tracks the current generate scheme being processed. This is always within a module. */ static PGenerate*pform_cur_generate = 0; /* This indicates whether a new generate construct can be directly nested in the current generate construct. */ bool pform_generate_single_item = false; /* Blocks within the same conditional generate construct may have the same name. Here we collect the set of names used in each construct, so they can be added to the local scope without conflicting with each other. Generate constructs may nest, so we need a stack. */ static list > conditional_block_names; /* This tracks the current modport list being processed. This is always within an interface. */ static PModport*pform_cur_modport = 0; static NetNet::Type pform_default_nettype = NetNet::WIRE; /* * These variables track the time scale set by the most recent `timescale * directive. Time scales set by SystemVerilog timeunit and timeprecision * declarations are stored directly in the current lexical scope. */ static int pform_time_unit; static int pform_time_prec; /* * These variables track where the most recent `timescale directive * occurred. This allows us to warn about time scales that are inherited * from another file. */ static char*pform_timescale_file = 0; static unsigned pform_timescale_line; /* * These variables track whether we can accept new timeunits declarations. */ bool allow_timeunit_decl = true; bool allow_timeprec_decl = true; // Track whether the current parameter declaration is in a parameter port list static bool pform_in_parameter_port_list = false; /* * The lexical_scope keeps track of the current lexical scope that is * being parsed. The lexical scope may stack, so the current scope may * have a parent, that is restored when the current scope ends. * * Items that have scoped names are put in the lexical_scope object. */ static LexicalScope* lexical_scope = 0; LexicalScope* pform_peek_scope(void) { assert(lexical_scope); return lexical_scope; } void pform_pop_scope() { LexicalScope*scope = lexical_scope; assert(scope); map::const_iterator cur; for (cur = scope->possible_imports.begin(); cur != scope->possible_imports.end(); ++cur) { if (scope->local_symbols.find(cur->first) == scope->local_symbols.end()) scope->explicit_imports[cur->first] = cur->second; } scope->possible_imports.clear(); lexical_scope = scope->parent_scope(); assert(lexical_scope); } static LexicalScope::lifetime_t find_lifetime(LexicalScope::lifetime_t lifetime) { if (lifetime != LexicalScope::INHERITED) return lifetime; return lexical_scope->default_lifetime; } static PScopeExtra* find_nearest_scopex(LexicalScope*scope) { PScopeExtra*scopex = dynamic_cast (scope); while (scope && !scopex) { scope = scope->parent_scope(); scopex = dynamic_cast (scope); } return scopex; } static void add_local_symbol(LexicalScope*scope, perm_string name, PNamedItem*item) { assert(scope); // Check for conflict with another local symbol. map::const_iterator cur_sym = scope->local_symbols.find(name); if (cur_sym != scope->local_symbols.end()) { cerr << item->get_fileline() << ": error: " "'" << name << "' has already been declared " "in this scope." << endl; cerr << cur_sym->second->get_fileline() << ": : " "It was declared here as " << cur_sym->second->symbol_type() << "." << endl; error_count += 1; return; } // Check for conflict with an explicit import. map::const_iterator cur_pkg = scope->explicit_imports.find(name); if (cur_pkg != scope->explicit_imports.end()) { cerr << item->get_fileline() << ": error: " "'" << name << "' has already been " "imported into this scope from package '" << cur_pkg->second->pscope_name() << "'." << endl; error_count += 1; return; } scope->local_symbols[name] = item; } static PPackage*find_potential_import(const struct vlltype&loc, LexicalScope*scope, perm_string name, bool tf_call, bool make_explicit) { assert(scope); PPackage*found_pkg = 0; for (list::const_iterator cur_pkg = scope->potential_imports.begin(); cur_pkg != scope->potential_imports.end(); ++cur_pkg) { PPackage*search_pkg = *cur_pkg; map::const_iterator cur_sym = search_pkg->local_symbols.find(name); if (cur_sym != search_pkg->local_symbols.end()) { if (found_pkg && make_explicit) { cerr << loc.get_fileline() << ": error: " "Ambiguous use of '" << name << "'. " "It is exported by both '" << found_pkg->pscope_name() << "' and by '" << search_pkg->pscope_name() << "'." << endl; error_count += 1; } else { found_pkg = search_pkg; if (make_explicit) { if (tf_call) scope->possible_imports[name] = found_pkg; else scope->explicit_imports[name] = found_pkg; } } } } return found_pkg; } static void check_potential_imports(const struct vlltype&loc, perm_string name, bool tf_call) { LexicalScope*scope = lexical_scope; while (scope) { if (scope->local_symbols.find(name) != scope->local_symbols.end()) return; if (scope->explicit_imports.find(name) != scope->explicit_imports.end()) return; if (find_potential_import(loc, scope, name, tf_call, true)) return; scope = scope->parent_scope(); } } /* * Set the local time unit/precision. This version is used for setting * the time scale for design elements (modules, packages, etc.) and is * called after any initial timeunit and timeprecision declarations * have been parsed. */ void pform_set_scope_timescale(const struct vlltype&loc) { PScopeExtra*scope = dynamic_cast(lexical_scope); assert(scope); PScopeExtra*parent = find_nearest_scopex(scope->parent_scope()); bool used_global_timescale = false; if (scope->time_unit_is_default) { if (is_compilation_unit(scope)) { scope->time_unit = def_ts_units; } else if (!is_compilation_unit(parent)) { scope->time_unit = parent->time_unit; scope->time_unit_is_default = parent->time_unit_is_default; } else if (pform_timescale_file != 0) { scope->time_unit = pform_time_unit; scope->time_unit_is_default = false; used_global_timescale = true; } else /* parent is compilation unit */ { scope->time_unit = parent->time_unit; scope->time_unit_is_default = parent->time_unit_is_default; } } if (scope->time_prec_is_default) { if (is_compilation_unit(scope)) { scope->time_precision = def_ts_prec; } else if (!is_compilation_unit(parent)) { scope->time_precision = parent->time_precision; scope->time_prec_is_default = parent->time_prec_is_default; } else if (pform_timescale_file != 0) { scope->time_precision = pform_time_prec; scope->time_prec_is_default = false; used_global_timescale = true; } else { scope->time_precision = parent->time_precision; scope->time_prec_is_default = parent->time_prec_is_default; } } if (gn_system_verilog() && (scope->time_unit < scope->time_precision)) { if (scope->time_unit_is_local || scope->time_prec_is_local) { VLerror("error: A timeprecision is missing or is too large!"); } } else { assert(scope->time_unit >= scope->time_precision); } if (warn_timescale && used_global_timescale && (strcmp(pform_timescale_file, loc.text) != 0)) { cerr << loc.get_fileline() << ": warning: " << "timescale for " << scope->pscope_name() << " inherited from another file." << endl; cerr << pform_timescale_file << ":" << pform_timescale_line << ": ...: The inherited timescale is here." << endl; } allow_timeunit_decl = false; allow_timeprec_decl = false; } /* * Set the local time unit/precision. This version is used for setting * the time scale for subsidiary items (classes, subroutines, etc.), * which simply inherit their time scale from their parent scope. */ static void pform_set_scope_timescale(PScope*scope, const PScope*parent) { scope->time_unit = parent->time_unit; scope->time_precision = parent->time_precision; scope->time_unit_is_default = parent->time_unit_is_default; scope->time_prec_is_default = parent->time_prec_is_default; } PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name) { PClass*class_scope = new PClass(name, lexical_scope); class_scope->default_lifetime = LexicalScope::AUTOMATIC; FILE_NAME(class_scope, loc); PScopeExtra*scopex = find_nearest_scopex(lexical_scope); assert(scopex); assert(!pform_cur_generate); pform_set_scope_timescale(class_scope, scopex); scopex->classes[name] = class_scope; scopex->classes_lexical .push_back(class_scope); lexical_scope = class_scope; return class_scope; } PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name, LexicalScope::lifetime_t lifetime) { PPackage*pkg_scope = new PPackage(name, lexical_scope); pkg_scope->default_lifetime = find_lifetime(lifetime); FILE_NAME(pkg_scope, loc); allow_timeunit_decl = true; allow_timeprec_decl = true; lexical_scope = pkg_scope; return pkg_scope; } PTask* pform_push_task_scope(const struct vlltype&loc, char*name, LexicalScope::lifetime_t lifetime) { perm_string task_name = lex_strings.make(name); LexicalScope::lifetime_t default_lifetime = find_lifetime(lifetime); bool is_auto = default_lifetime == LexicalScope::AUTOMATIC; PTask*task = new PTask(task_name, lexical_scope, is_auto); task->default_lifetime = default_lifetime; FILE_NAME(task, loc); PScopeExtra*scopex = find_nearest_scopex(lexical_scope); assert(scopex); if (is_compilation_unit(scopex) && !gn_system_verilog()) { cerr << task->get_fileline() << ": error: task declarations " "must be contained within a module." << endl; error_count += 1; } pform_set_scope_timescale(task, scopex); if (pform_cur_generate) { add_local_symbol(pform_cur_generate, task_name, task); pform_cur_generate->tasks[task_name] = task; } else { add_local_symbol(scopex, task_name, task); scopex->tasks[task_name] = task; } lexical_scope = task; return task; } PFunction* pform_push_function_scope(const struct vlltype&loc, const char*name, LexicalScope::lifetime_t lifetime) { perm_string func_name = lex_strings.make(name); LexicalScope::lifetime_t default_lifetime = find_lifetime(lifetime); bool is_auto = default_lifetime == LexicalScope::AUTOMATIC; PFunction*func = new PFunction(func_name, lexical_scope, is_auto); func->default_lifetime = default_lifetime; FILE_NAME(func, loc); PScopeExtra*scopex = find_nearest_scopex(lexical_scope); assert(scopex); if (is_compilation_unit(scopex) && !gn_system_verilog()) { cerr << func->get_fileline() << ": error: function declarations " "must be contained within a module." << endl; error_count += 1; } pform_set_scope_timescale(func, scopex); if (pform_cur_generate) { add_local_symbol(pform_cur_generate, func_name, func); pform_cur_generate->funcs[func_name] = func; } else { add_local_symbol(scopex, func_name, func); scopex->funcs[func_name] = func; } lexical_scope = func; return func; } PBlock* pform_push_block_scope(const struct vlltype&loc, char*name, PBlock::BL_TYPE bt) { perm_string block_name; if (name) block_name = lex_strings.make(name); else { // Create a unique name for this unnamed block. char tmp[32]; snprintf(tmp, sizeof tmp, "$unm_blk_%u", scope_unnamed_block_with_decl); block_name = lex_strings.make(tmp); scope_unnamed_block_with_decl += 1; } PBlock*block = new PBlock(block_name, lexical_scope, bt); FILE_NAME(block, loc); block->default_lifetime = find_lifetime(LexicalScope::INHERITED); if (name) add_local_symbol(lexical_scope, block_name, block); lexical_scope = block; return block; } /* * Create a new identifier. */ PEIdent* pform_new_ident(const struct vlltype&loc, const pform_name_t&name) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, false); return new PEIdent(name); } PTrigger* pform_new_trigger(const struct vlltype&loc, PPackage*pkg, const pform_name_t&name) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, false); PTrigger*tmp = new PTrigger(pkg, name); FILE_NAME(tmp, loc); return tmp; } PNBTrigger* pform_new_nb_trigger(const struct vlltype&loc, const list*dly, const pform_name_t&name) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, false); PExpr*tmp_dly = 0; if (dly) { assert(dly->size() == 1); tmp_dly = dly->front(); } PNBTrigger*tmp = new PNBTrigger(name, tmp_dly); FILE_NAME(tmp, loc); return tmp; } PGenerate* pform_parent_generate(void) { return pform_cur_generate; } bool pform_error_in_generate(const vlltype&loc, const char *type) { if (!pform_parent_generate()) return false; VLerror(loc, "error: %s is not allowed in generate block.", type); return true; } void pform_bind_attributes(map&attributes, list*attr, bool keep_attrs) { if (attr == 0) return; while (! attr->empty()) { named_pexpr_t tmp = attr->front(); attr->pop_front(); attributes[tmp.name] = tmp.parm; } if (!keep_attrs) delete attr; } bool pform_in_program_block() { if (pform_cur_module.empty()) return false; if (pform_cur_module.front()->program_block) return true; return false; } bool pform_in_interface() { if (pform_cur_module.empty()) return false; if (pform_cur_module.front()->is_interface) return true; return false; } static bool pform_at_module_level() { return (lexical_scope == pform_cur_module.front()) || (lexical_scope == pform_cur_generate); } PWire*pform_get_wire_in_scope(perm_string name) { return lexical_scope->wires_find(name); } static void pform_put_wire_in_scope(perm_string name, PWire*net) { add_local_symbol(lexical_scope, name, net); lexical_scope->wires[name] = net; } void pform_put_enum_type_in_scope(enum_type_t*enum_set) { if (std::find(lexical_scope->enum_sets.begin(), lexical_scope->enum_sets.end(), enum_set) != lexical_scope->enum_sets.end()) return; set enum_names; list::const_iterator cur; for (cur = enum_set->names->begin(); cur != enum_set->names->end(); ++cur) { if (enum_names.count(cur->name)) { cerr << enum_set->get_fileline() << ": error: " "Duplicate enumeration name '" << cur->name << "'." << endl; error_count += 1; } else { add_local_symbol(lexical_scope, cur->name, enum_set); enum_names.insert(cur->name); } } lexical_scope->enum_sets.push_back(enum_set); } static typedef_t *pform_get_typedef(const struct vlltype&loc, perm_string name) { typedef_t *&td = lexical_scope->typedefs[name]; if (!td) { td = new typedef_t(name); FILE_NAME(td, loc); add_local_symbol(lexical_scope, name, td); } return td; } void pform_forward_typedef(const struct vlltype&loc, perm_string name, enum typedef_t::basic_type basic_type) { typedef_t *td = pform_get_typedef(loc, name); if (!td->set_basic_type(basic_type)) { cout << loc << " error: Incompatible basic type `" << basic_type << "` for `" << name << "`. Previously declared in this scope as `" << td->get_basic_type() << "` at " << td->get_fileline() << "." << endl; error_count++; } } void pform_set_typedef(const struct vlltype&loc, perm_string name, data_type_t*data_type, std::list*unp_ranges) { typedef_t *td = pform_get_typedef(loc, name); if(unp_ranges) data_type = new uarray_type_t(data_type, unp_ranges); if (!td->set_data_type(data_type)) { cerr << loc << " error: Type identifier `" << name << "` has already been declared in this scope at " << td->get_data_type()->get_fileline() << "." << endl; error_count++; delete data_type; } } void pform_set_type_referenced(const struct vlltype&loc, const char*name) { perm_string lex_name = lex_strings.make(name); check_potential_imports(loc, lex_name, false); } typedef_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt) { perm_string name = lex_strings.make(txt); LexicalScope*cur_scope = lexical_scope; do { LexicalScope::typedef_map_t::iterator cur; // First look to see if this identifier is imported from // a package. If it is, see if it is a type in that // package. If it is, then great. If imported as // something other than a type, then give up now because // the name has at least shadowed any other possible // meaning for this name. map::iterator cur_pkg; cur_pkg = cur_scope->explicit_imports.find(name); if (cur_pkg != cur_scope->explicit_imports.end()) { PPackage*pkg = cur_pkg->second; cur = pkg->typedefs.find(name); if (cur != pkg->typedefs.end()) return cur->second; // Not a type. Give up. return 0; } cur = cur_scope->typedefs.find(name); if (cur != cur_scope->typedefs.end()) return cur->second; PPackage*pkg = find_potential_import(loc, cur_scope, name, false, false); if (pkg) { cur = pkg->typedefs.find(name); if (cur != pkg->typedefs.end()) return cur->second; // Not a type. Give up. return 0; } cur_scope = cur_scope->parent_scope(); } while (cur_scope); return 0; } PECallFunction* pform_make_call_function(const struct vlltype&loc, const pform_name_t&name, const list&parms) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, true); PECallFunction*tmp = new PECallFunction(name, parms); FILE_NAME(tmp, loc); return tmp; } PCallTask* pform_make_call_task(const struct vlltype&loc, const pform_name_t&name, const list&parms) { if (gn_system_verilog()) check_potential_imports(loc, name.front().name, true); PCallTask*tmp = new PCallTask(name, parms); FILE_NAME(tmp, loc); return tmp; } void pform_make_var(const struct vlltype&loc, std::list*assign_list, data_type_t*data_type, std::list*attr) { static const struct str_pair_t str = { IVL_DR_STRONG, IVL_DR_STRONG }; pform_makewire(loc, 0, str, assign_list, NetNet::REG, data_type, attr); } void pform_make_foreach_declarations(const struct vlltype&loc, std::list*loop_vars) { listassign_list; for (list::const_iterator cur = loop_vars->begin() ; cur != loop_vars->end() ; ++ cur) { if (cur->nil()) continue; decl_assignment_t*tmp_assign = new decl_assignment_t; tmp_assign->name = lex_strings.make(*cur); assign_list.push_back(tmp_assign); } pform_make_var(loc, &assign_list, &size_type); } PForeach* pform_make_foreach(const struct vlltype&loc, char*name, list*loop_vars, Statement*stmt) { perm_string use_name = lex_strings.make(name); delete[]name; if (loop_vars==0 || loop_vars->empty()) { cerr << loc.get_fileline() << ": error: " << "No loop variables at all in foreach index." << endl; error_count += 1; } ivl_assert(loc, loop_vars); PForeach*fe = new PForeach(use_name, *loop_vars, stmt); FILE_NAME(fe, loc); delete loop_vars; return fe; } static void pform_put_behavior_in_scope(PProcess*pp) { lexical_scope->behaviors.push_back(pp); } void pform_put_behavior_in_scope(AProcess*pp) { lexical_scope->analog_behaviors.push_back(pp); } void pform_set_default_nettype(NetNet::Type type, const char*file, unsigned lineno) { pform_default_nettype = type; if (! pform_cur_module.empty()) { cerr << file<<":"<mod_name() << " starts on line " << pform_cur_module.back()->get_fileline() << "." << endl; error_count += 1; } } static void pform_declare_implicit_nets(PExpr*expr) { /* If implicit net creation is turned off, then stop now. */ if (pform_default_nettype == NetNet::NONE) return; if (expr) expr->declare_implicit_nets(lexical_scope, pform_default_nettype); } /* * The lexor calls this function to set the active timescale when it * detects a `timescale directive. The function saves the directive * values (for use by subsequent design elements) and if warnings are * enabled checks to see if some design elements have no timescale. */ void pform_set_timescale(int unit, int prec, const char*file, unsigned lineno) { assert(unit >= prec); pform_time_unit = unit; pform_time_prec = prec; if (pform_timescale_file) { free(pform_timescale_file); } if (file) pform_timescale_file = strdup(file); else pform_timescale_file = 0; pform_timescale_line = lineno; } bool get_time_unit(const char*cp, int &unit) { const char *c; bool rc = true; if (strchr(cp, '_')) { VLerror(yylloc, "error: Invalid timeunit constant ('_' is not " "supported)."); return false; } c = strpbrk(cp, "munpfs"); if (!c) return false; if (*c == 's') unit = 0; else if (!strncmp(c, "ms", 2)) unit = -3; else if (!strncmp(c, "us", 2)) unit = -6; else if (!strncmp(c, "ns", 2)) unit = -9; else if (!strncmp(c, "ps", 2)) unit = -12; else if (!strncmp(c, "fs", 2)) unit = -15; else { rc = false; ostringstream msg; msg << "error: Invalid timeunit scale '" << cp << "'."; VLerror(msg.str().c_str()); } return rc; } /* * Get a timeunit or timeprecision value from a string. This is * similar to the code in lexor.lex for the `timescale directive. */ static bool get_time_unit_prec(const char*cp, int &res, bool is_unit) { /* We do not support a '_' in these time constants. */ if (strchr(cp, '_')) { if (is_unit) { VLerror(yylloc, "error: Invalid timeunit constant ('_' " "is not supported)."); } else { VLerror(yylloc, "error: Invalid timeprecision constant ('_' " "is not supported)."); } return true; } /* Check for the 1 digit. */ if (*cp != '1') { if (is_unit) { VLerror(yylloc, "error: Invalid timeunit constant " "(1st digit)."); } else { VLerror(yylloc, "error: Invalid timeprecision constant " "(1st digit)."); } return true; } cp += 1; /* Check the number of zeros after the 1. */ res = strspn(cp, "0"); if (res > 2) { if (is_unit) { VLerror(yylloc, "error: Invalid timeunit constant " "(number of zeros)."); } else { VLerror(yylloc, "error: Invalid timeprecision constant " "(number of zeros)."); } return true; } cp += res; /* Now process the scaling string. */ if (strncmp("s", cp, 1) == 0) { res -= 0; return false; } else if (strncmp("ms", cp, 2) == 0) { res -= 3; return false; } else if (strncmp("us", cp, 2) == 0) { res -= 6; return false; } else if (strncmp("ns", cp, 2) == 0) { res -= 9; return false; } else if (strncmp("ps", cp, 2) == 0) { res -= 12; return false; } else if (strncmp("fs", cp, 2) == 0) { res -= 15; return false; } ostringstream msg; msg << "error: Invalid "; if (is_unit) msg << "timeunit"; else msg << "timeprecision"; msg << " scale '" << cp << "'."; VLerror(msg.str().c_str()); return true; } void pform_set_timeunit(const char*txt, bool initial_decl) { int val; if (get_time_unit_prec(txt, val, true)) return; PScopeExtra*scope = dynamic_cast(lexical_scope); if (!scope) return; if (initial_decl) { scope->time_unit = val; scope->time_unit_is_local = true; scope->time_unit_is_default = false; allow_timeunit_decl = false; } else if (!scope->time_unit_is_local) { VLerror(yylloc, "error: Repeat timeunit found and the initial " "timeunit for this scope is missing."); } else if (scope->time_unit != val) { VLerror(yylloc, "error: Repeat timeunit does not match the " "initial timeunit for this scope."); } } int pform_get_timeunit() { PScopeExtra*scopex = find_nearest_scopex(lexical_scope); assert(scopex); return scopex->time_unit; } int pform_get_timeprec() { PScopeExtra*scopex = find_nearest_scopex(lexical_scope); assert(scopex); return scopex->time_precision; } void pform_set_timeprec(const char*txt, bool initial_decl) { int val; if (get_time_unit_prec(txt, val, false)) return; PScopeExtra*scope = dynamic_cast(lexical_scope); if (!scope) return; if (initial_decl) { scope->time_precision = val; scope->time_prec_is_local = true; scope->time_prec_is_default = false; allow_timeprec_decl = false; } else if (!scope->time_prec_is_local) { VLerror(yylloc, "error: Repeat timeprecision found and the initial " "timeprecision for this scope is missing."); } else if (scope->time_precision != val) { VLerror(yylloc, "error: Repeat timeprecision does not match the " "initial timeprecision for this scope."); } } verinum* pform_verinum_with_size(verinum*siz, verinum*val, const char*file, unsigned lineno) { assert(siz->is_defined()); unsigned long size = siz->as_ulong(); if (size == 0) { cerr << file << ":" << lineno << ": error: Sized numeric constant " "must have a size greater than zero." << endl; error_count += 1; } verinum::V pad; if (val->len() == 0) { pad = verinum::Vx; } else { switch (val->get(val->len()-1)) { case verinum::Vz: pad = verinum::Vz; break; case verinum::Vx: pad = verinum::Vx; break; default: pad = verinum::V0; break; } } verinum*res = new verinum(pad, size, true); unsigned copy = val->len(); if (res->len() < copy) copy = res->len(); for (unsigned idx = 0 ; idx < copy ; idx += 1) { res->set(idx, val->get(idx)); } res->has_sign(val->has_sign()); bool trunc_flag = false; for (unsigned idx = copy ; idx < val->len() ; idx += 1) { if (val->get(idx) != pad) { trunc_flag = true; break; } } if (trunc_flag) { cerr << file << ":" << lineno << ": warning: Numeric constant " << "truncated to " << copy << " bits." << endl; } delete siz; delete val; return res; } void pform_startmodule(const struct vlltype&loc, const char*name, bool program_block, bool is_interface, LexicalScope::lifetime_t lifetime, list*attr) { if (! pform_cur_module.empty() && !gn_system_verilog()) { cerr << loc << ": error: Module definition " << name << " cannot nest into module " << pform_cur_module.front()->mod_name() << "." << endl; error_count += 1; } if (lifetime != LexicalScope::INHERITED) { pform_requires_sv(loc, "Default subroutine lifetime"); } if (gn_system_verilog() && ! pform_cur_module.empty()) { if (pform_cur_module.front()->program_block) { cerr << loc << ": error: module, program, or interface " "declarations are not allowed in program " "blocks." << endl; error_count += 1; } if (pform_cur_module.front()->is_interface && !(program_block || is_interface)) { cerr << loc << ": error: module declarations are not " "allowed in interfaces." << endl; error_count += 1; } } perm_string lex_name = lex_strings.make(name); Module*cur_module = new Module(lexical_scope, lex_name); cur_module->program_block = program_block; cur_module->is_interface = is_interface; cur_module->default_lifetime = find_lifetime(lifetime); FILE_NAME(cur_module, loc); cur_module->library_flag = pform_library_flag; pform_cur_module.push_front(cur_module); allow_timeunit_decl = true; allow_timeprec_decl = true; pform_generate_single_item = false; add_local_symbol(lexical_scope, lex_name, cur_module); lexical_scope = cur_module; pform_bind_attributes(cur_module->attributes, attr); } void pform_start_parameter_port_list() { pform_in_parameter_port_list = true; pform_peek_scope()->has_parameter_port_list = true; } void pform_end_parameter_port_list() { pform_in_parameter_port_list = false; } /* * This function is called by the parser to make a simple port * reference. This is a name without a .X(...), so the internal name * should be generated to be the same as the X. */ Module::port_t* pform_module_port_reference(const struct vlltype&loc, perm_string name) { Module::port_t*ptmp = new Module::port_t; PEIdent*tmp = new PEIdent(name); FILE_NAME(tmp, loc); ptmp->name = name; ptmp->expr.push_back(tmp); ptmp->default_value = 0; return ptmp; } void pform_module_set_ports(vector*ports) { assert(! pform_cur_module.empty()); /* The parser parses ``module foo()'' as having one unconnected port, but it is really a module with no ports. Fix it up here. */ if (ports && (ports->size() == 1) && ((*ports)[0] == 0)) { delete ports; ports = 0; } if (ports != 0) { pform_cur_module.front()->ports = *ports; delete ports; } } void pform_endmodule(const char*name, bool inside_celldefine, Module::UCDriveType uc_drive_def) { // The parser will not call pform_endmodule() without first // calling pform_startmodule(). Thus, it is impossible for the // pform_cur_module stack to be empty at this point. assert(! pform_cur_module.empty()); Module*cur_module = pform_cur_module.front(); pform_cur_module.pop_front(); perm_string mod_name = cur_module->mod_name(); // Oops, there may be some sort of nesting problem. If // SystemVerilog is activated, it is possible for modules to // be nested. But if the nested module is broken, the parser // will recover and treat is as an invalid module item, // leaving the pform_cur_module stack in an inconsistent // state. For example, this: // module foo; // module bar blah blab blah error; // endmodule // may leave the pform_cur_module stack with the dregs of the // bar module. Try to find the foo module in the stack, and // print error messages as we go. if (strcmp(name, mod_name) != 0) { while (!pform_cur_module.empty()) { Module*tmp_module = pform_cur_module.front(); perm_string tmp_name = tmp_module->mod_name(); pform_cur_module.pop_front(); ostringstream msg; msg << "error: Module " << mod_name << " was nested within " << tmp_name << " but broken."; VLerror(msg.str().c_str()); ivl_assert(*cur_module, lexical_scope == cur_module); pform_pop_scope(); delete cur_module; cur_module = tmp_module; mod_name = tmp_name; if (strcmp(name, mod_name) == 0) break; } } assert(strcmp(name, mod_name) == 0); cur_module->is_cell = inside_celldefine; cur_module->uc_drive = uc_drive_def; // If this is a root module, then there is no parent module // and we try to put this newly defined module into the global // root list of modules. Otherwise, this is a nested module // and we put it into the parent module scope to be elaborated // if needed. map&use_module_map = (pform_cur_module.empty()) ? pform_modules : pform_cur_module.front()->nested_modules; map::const_iterator test = use_module_map.find(mod_name); if (test != use_module_map.end()) { ostringstream msg; msg << "error: Module " << name << " was already declared here: " << test->second->get_fileline() << endl; VLerror(msg.str().c_str()); } else { use_module_map[mod_name] = cur_module; } // The current lexical scope should be this module by now. ivl_assert(*cur_module, lexical_scope == cur_module); pform_pop_scope(); } void pform_genvars(const struct vlltype&li, list*names) { list::const_iterator cur; for (cur = names->begin(); cur != names->end() ; *cur++) { PGenvar*genvar = new PGenvar(); FILE_NAME(genvar, li); if (pform_cur_generate) { add_local_symbol(pform_cur_generate, *cur, genvar); pform_cur_generate->genvars[*cur] = genvar; } else { add_local_symbol(pform_cur_module.front(), *cur, genvar); pform_cur_module.front()->genvars[*cur] = genvar; } } delete names; } static unsigned detect_directly_nested_generate() { if (pform_cur_generate && pform_generate_single_item) switch (pform_cur_generate->scheme_type) { case PGenerate::GS_CASE_ITEM: // fallthrough case PGenerate::GS_CONDIT: // fallthrough case PGenerate::GS_ELSE: pform_cur_generate->directly_nested = true; return pform_cur_generate->id_number; default: break; } return ++lexical_scope->generate_counter; } void pform_start_generate_for(const struct vlltype&li, bool local_index, char*ident1, PExpr*init, PExpr*test, char*ident2, PExpr*next) { PGenerate*gen = new PGenerate(lexical_scope, ++lexical_scope->generate_counter); lexical_scope = gen; FILE_NAME(gen, li); pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_LOOP; pform_cur_generate->local_index = local_index; pform_cur_generate->loop_index = lex_strings.make(ident1); pform_cur_generate->loop_init = init; pform_cur_generate->loop_test = test; pform_cur_generate->loop_step = next; delete[]ident1; delete[]ident2; } void pform_start_generate_if(const struct vlltype&li, PExpr*test) { unsigned id_number = detect_directly_nested_generate(); PGenerate*gen = new PGenerate(lexical_scope, id_number); lexical_scope = gen; FILE_NAME(gen, li); pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CONDIT; pform_cur_generate->loop_init = 0; pform_cur_generate->loop_test = test; pform_cur_generate->loop_step = 0; conditional_block_names.push_front(set()); } void pform_start_generate_else(const struct vlltype&li) { assert(pform_cur_generate); assert(pform_cur_generate->scheme_type == PGenerate::GS_CONDIT); PGenerate*cur = pform_cur_generate; pform_endgenerate(false); PGenerate*gen = new PGenerate(lexical_scope, cur->id_number); lexical_scope = gen; FILE_NAME(gen, li); pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_ELSE; pform_cur_generate->loop_init = 0; pform_cur_generate->loop_test = cur->loop_test; pform_cur_generate->loop_step = 0; } /* * The GS_CASE version of the PGenerate contains only case items. The * items in turn contain the generated items themselves. */ void pform_start_generate_case(const struct vlltype&li, PExpr*expr) { unsigned id_number = detect_directly_nested_generate(); PGenerate*gen = new PGenerate(lexical_scope, id_number); lexical_scope = gen; FILE_NAME(gen, li); pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CASE; pform_cur_generate->loop_init = 0; pform_cur_generate->loop_test = expr; pform_cur_generate->loop_step = 0; conditional_block_names.push_front(set()); } /* * The named block generate case. */ void pform_start_generate_nblock(const struct vlltype&li, char*name) { PGenerate*gen = new PGenerate(lexical_scope, ++lexical_scope->generate_counter); lexical_scope = gen; FILE_NAME(gen, li); pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_NBLOCK; pform_cur_generate->loop_init = 0; pform_cur_generate->loop_test = 0; pform_cur_generate->loop_step = 0; pform_cur_generate->scope_name = lex_strings.make(name); delete[]name; add_local_symbol(pform_cur_generate->parent_scope(), pform_cur_generate->scope_name, pform_cur_generate); } /* * The generate case item is a special case schema that takes its id * from the case schema that it is a part of. The idea is that the * case schema can only instantiate exactly one item, so the items * need not have a unique number. */ void pform_generate_case_item(const struct vlltype&li, list*expr_list) { assert(pform_cur_generate); assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE); PGenerate*gen = new PGenerate(lexical_scope, pform_cur_generate->id_number); lexical_scope = gen; FILE_NAME(gen, li); gen->directly_nested = pform_cur_generate->directly_nested; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CASE_ITEM; pform_cur_generate->loop_init = 0; pform_cur_generate->loop_test = 0; pform_cur_generate->loop_step = 0; if (expr_list != 0) { list::iterator expr_cur = expr_list->begin(); pform_cur_generate->item_test.resize(expr_list->size()); for (unsigned idx = 0 ; idx < expr_list->size() ; idx += 1) { pform_cur_generate->item_test[idx] = *expr_cur; ++ expr_cur; } assert(expr_cur == expr_list->end()); } } void pform_generate_block_name(char*name) { assert(pform_cur_generate != 0); assert(pform_cur_generate->scope_name == 0); perm_string scope_name = lex_strings.make(name); pform_cur_generate->scope_name = scope_name; if (pform_cur_generate->scheme_type == PGenerate::GS_CONDIT || pform_cur_generate->scheme_type == PGenerate::GS_ELSE || pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM) { if (conditional_block_names.front().count(scope_name)) return; conditional_block_names.front().insert(scope_name); } LexicalScope*parent_scope = pform_cur_generate->parent_scope(); assert(parent_scope); if (pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM) // Skip over the PGenerate::GS_CASE container. parent_scope = parent_scope->parent_scope(); add_local_symbol(parent_scope, scope_name, pform_cur_generate); } void pform_endgenerate(bool end_conditional) { assert(pform_cur_generate != 0); assert(! pform_cur_module.empty()); if (end_conditional) conditional_block_names.pop_front(); // If there is no explicit block name then generate a temporary // name. This will be replaced by the correct name later, once // we know all the explicit names in the surrounding scope. If // the naming scheme used here is changed, PGenerate::elaborate // must be changed to match. if (pform_cur_generate->scope_name == 0) { char tmp[16]; snprintf(tmp, sizeof tmp, "$gen%u", pform_cur_generate->id_number); pform_cur_generate->scope_name = lex_strings.make(tmp); } // The current lexical scope should be this generate construct by now ivl_assert(*pform_cur_generate, lexical_scope == pform_cur_generate); pform_pop_scope(); PGenerate*parent_generate = dynamic_cast(lexical_scope); if (parent_generate) { assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM || parent_generate->scheme_type != PGenerate::GS_CASE); parent_generate->generate_schemes.push_back(pform_cur_generate); } else { assert(pform_cur_generate->scheme_type != PGenerate::GS_CASE_ITEM); pform_cur_module.front()->generate_schemes.push_back(pform_cur_generate); } pform_cur_generate = parent_generate; } void pform_make_elab_task(const struct vlltype&li, perm_string name, const list¶ms) { PCallTask*elab_task = new PCallTask(name, params); FILE_NAME(elab_task, li); lexical_scope->elab_tasks.push_back(elab_task); } MIN_TYP_MAX min_typ_max_flag = TYP; unsigned min_typ_max_warn = 10; PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max) { PExpr*res = 0; switch (min_typ_max_flag) { case MIN: res = min; delete typ; delete max; break; case TYP: res = typ; delete min; delete max; break; case MAX: res = max; delete min; delete typ; break; } if (min_typ_max_warn > 0) { cerr << res->get_fileline() << ": warning: Choosing "; switch (min_typ_max_flag) { case MIN: cerr << "min"; break; case TYP: cerr << "typ"; break; case MAX: cerr << "max"; break; } cerr << " expression." << endl; min_typ_max_warn -= 1; } return res; } static void process_udp_table(PUdp*udp, list*table, const struct vlltype&loc) { const bool synchronous_flag = udp->sequential; /* Interpret and check the table entry strings, to make sure they correspond to the inputs, output and output type. Make up vectors for the fully interpreted result that can be placed in the PUdp object. The table strings are made up by the parser to be two or three substrings separated by ';', i.e.: 0101:1:1 (synchronous device entry) 0101:0 (combinational device entry) The parser doesn't check that we got the right kind here, so this loop must watch out. */ std::vector &input = udp->tinput; std::vector ¤t = udp->tcurrent; std::vector &output = udp->toutput; input.resize(table->size()); current.resize(table->size()); output.resize(table->size()); { unsigned idx = 0; for (list::iterator cur = table->begin() ; cur != table->end() ; ++ cur , idx += 1) { string tmp = *cur; /* Pull the input values from the string. */ assert(tmp.find(':') == (udp->ports.size() - 1)); input[idx] = tmp.substr(0, udp->ports.size()-1); tmp = tmp.substr(udp->ports.size()-1); assert(tmp[0] == ':'); /* If this is a synchronous device, get the current output string. */ if (synchronous_flag) { if (tmp.size() != 4) { cerr << loc << ": error: " << "Invalid table format for" << " sequential primitive." << endl; error_count += 1; break; } assert(tmp.size() == 4); current[idx] = tmp[1]; tmp = tmp.substr(2); } else if (tmp.size() != 2) { cerr << loc << ": error: " << "Invalid table format for" << " combinational primitive." << endl; error_count += 1; break; } /* Finally, extract the desired output. */ assert(tmp.size() == 2); output[idx] = tmp[1]; } } } void pform_make_udp(const struct vlltype&loc, perm_string name, list*parms, vector*decl, list*table, Statement*init_expr) { unsigned local_errors = 0; assert(!parms->empty()); assert(decl); /* Put the declarations into a map, so that I can check them off with the parameters in the list. If the port is already in the map, merge the port type. I will rebuild a list of parameters for the PUdp object. */ map defs; for (unsigned idx = 0 ; idx < decl->size() ; idx += 1) { perm_string port_name = (*decl)[idx]->basename(); if (PWire*cur = defs[port_name]) { bool rc = true; assert((*decl)[idx]); if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) { rc = cur->set_port_type((*decl)[idx]->get_port_type()); assert(rc); } if ((*decl)[idx]->get_wire_type() != NetNet::IMPLICIT) { rc = cur->set_wire_type((*decl)[idx]->get_wire_type()); assert(rc); } } else { defs[port_name] = (*decl)[idx]; } } /* Put the parameters into a vector of wire descriptions. Look in the map for the definitions of the name. In this loop, the parms list in the list of ports in the port list of the UDP declaration, and the defs map maps that name to a PWire* created by an input or output declaration. */ std::vector pins(parms->size()); std::vector pin_names(parms->size()); { list::iterator cur; unsigned idx; for (cur = parms->begin(), idx = 0 ; cur != parms->end() ; ++ idx, ++ cur) { pins[idx] = defs[*cur]; pin_names[idx] = *cur; } } /* Check that the output is an output and the inputs are inputs. I can also make sure that only the single output is declared a register, if anything. The possible errors are: -- an input port (not the first) is missing an input declaration. -- An input port is declared output. */ assert(pins.size() > 0); do { if (pins[0] == 0) { cerr << loc << ": error: " << "Output port of primitive " << name << " missing output declaration." << endl; cerr << loc << ": : " << "Try: output " << pin_names[0] << ";" << endl; error_count += 1; local_errors += 1; break; } if (pins[0]->get_port_type() != NetNet::POUTPUT) { cerr << loc << ": error: " << "The first port of a primitive" << " must be an output." << endl; cerr << loc << ": : " << "Try: output " << pin_names[0] << ";" << endl; error_count += 1; local_errors += 1; break;; } } while (0); for (unsigned idx = 1 ; idx < pins.size() ; idx += 1) { if (pins[idx] == 0) { cerr << loc << ": error: " << "Port " << (idx+1) << " of primitive " << name << " missing" << " input declaration." << endl; cerr << loc << ": : " << "Try: input " << pin_names[idx] << ";" << endl; error_count += 1; local_errors += 1; continue; } if (pins[idx]->get_port_type() != NetNet::PINPUT) { cerr << loc << ": error: " << "Input port " << (idx+1) << " of primitive " << name << " has an output (or missing) declaration." << endl; cerr << loc << ": : " << "Note that only the first port can be an output." << endl; cerr << loc << ": : " << "Try \"input " << name << ";\"" << endl; error_count += 1; local_errors += 1; continue; } if (pins[idx]->get_wire_type() == NetNet::REG) { cerr << loc << ": error: " << "Port " << (idx+1) << " of primitive " << name << " is an input port" << " with a reg declaration." << endl; cerr << loc << ": : " << "primitive inputs cannot be reg." << endl; error_count += 1; local_errors += 1; continue; } } if (local_errors > 0) { delete parms; delete decl; delete table; delete init_expr; return; } /* Verify the "initial" statement, if present, to be sure that it only assigns to the output and the output is registered. Then save the initial value that I get. */ verinum::V init = verinum::Vx; if (init_expr) { // XXXX assert(pins[0]->get_wire_type() == NetNet::REG); PAssign*pa = dynamic_cast(init_expr); assert(pa); const PEIdent*id = dynamic_cast(pa->lval()); assert(id); // XXXX //assert(id->name() == pins[0]->name()); const PENumber*np = dynamic_cast(pa->rval()); assert(np); init = np->value()[0]; } // Put the primitive into the primitives table if (pform_primitives[name]) { VLwarn("warning: UDP primitive already exists."); } else { PUdp*udp = new PUdp(name, parms->size()); FILE_NAME(udp, loc); // Detect sequential udp. if (pins[0]->get_wire_type() == NetNet::REG) udp->sequential = true; // Make the port list for the UDP for (unsigned idx = 0 ; idx < pins.size() ; idx += 1) udp->ports[idx] = pins[idx]->basename(); process_udp_table(udp, table, loc); udp->initial = init; pform_primitives[name] = udp; } /* Delete the excess tables and lists from the parser. */ delete parms; delete decl; delete table; delete init_expr; } void pform_make_udp(const struct vlltype&loc, perm_string name, bool synchronous_flag, perm_string out_name, PExpr*init_expr, list*parms, list*table) { std::vector pins(parms->size() + 1); /* Make the PWire for the output port. */ pins[0] = new PWire(out_name, synchronous_flag? NetNet::REG : NetNet::WIRE, NetNet::POUTPUT); FILE_NAME(pins[0], loc); /* Make the PWire objects for the input ports. */ { list::iterator cur; unsigned idx; for (cur = parms->begin(), idx = 1 ; cur != parms->end() ; idx += 1, ++ cur) { assert(idx < pins.size()); pins[idx] = new PWire(*cur, NetNet::WIRE, NetNet::PINPUT); FILE_NAME(pins[idx], loc); } assert(idx == pins.size()); } /* Verify the initial expression, if present, to be sure that it only assigns to the output and the output is registered. Then save the initial value that I get. */ verinum::V init = verinum::Vx; if (init_expr) { // XXXX assert(pins[0]->get_wire_type() == NetNet::REG); PAssign*pa = dynamic_cast(init_expr); assert(pa); const PEIdent*id = dynamic_cast(pa->lval()); assert(id); // XXXX //assert(id->name() == pins[0]->name()); const PENumber*np = dynamic_cast(pa->rval()); assert(np); init = np->value()[0]; } // Put the primitive into the primitives table if (pform_primitives[name]) { VLerror("error: UDP primitive already exists."); } else { PUdp*udp = new PUdp(name, pins.size()); FILE_NAME(udp, loc); // Detect sequential udp. udp->sequential = synchronous_flag; // Make the port list for the UDP for (unsigned idx = 0 ; idx < pins.size() ; idx += 1) udp->ports[idx] = pins[idx]->basename(); assert(udp); assert(table); process_udp_table(udp, table, loc); udp->initial = init; pform_primitives[name] = udp; } delete parms; delete table; delete init_expr; } /* * This function attaches a range to a given name. The function is * only called by the parser within the scope of the net declaration, * and the name that I receive only has the tail component. */ static void pform_set_net_range(PWire *wire, const vector_type_t *vec_type, PWSRType rt = SR_NET, std::list*attr = 0) { pform_bind_attributes(wire->attributes, attr, true); if (!vec_type) return; list *range = vec_type->pdims.get(); if (range) wire->set_range(*range, rt); wire->set_signed(vec_type->signed_flag); } /* * This is invoked to make a named event. This is the declaration of * the event, and not necessarily the use of it. */ static void pform_make_event(const struct vlltype&loc, perm_string name) { PEvent*event = new PEvent(name); FILE_NAME(event, loc); add_local_symbol(lexical_scope, name, event); lexical_scope->events[name] = event; } void pform_make_events(const struct vlltype&loc, list*names) { list::iterator cur; for (cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; pform_make_event(loc, txt); } delete names; } /* * pform_makegates is called when a list of gates (with the same type) * are ready to be instantiated. The function runs through the list of * gates and calls the pform_makegate function to make the individual gate. */ static void pform_makegate(PGBuiltin::Type type, struct str_pair_t str, list* delay, const lgate&info, list*attr) { if (info.parms_by_name) { cerr << info.get_fileline() << ": error: Gates do not have port names." << endl; error_count += 1; return; } if (info.parms) { for (list::iterator cur = info.parms->begin() ; cur != info.parms->end() ; ++cur) { pform_declare_implicit_nets(*cur); } } perm_string dev_name = lex_strings.make(info.name); PGBuiltin*cur = new PGBuiltin(type, dev_name, info.parms, delay); cur->set_ranges(info.ranges); // The pform_makegates() that calls me will take care of // deleting the attr pointer, so tell the // pform_bind_attributes function to keep the attr object. pform_bind_attributes(cur->attributes, attr, true); cur->strength0(str.str0); cur->strength1(str.str1); cur->set_line(info); if (pform_cur_generate) { if (dev_name != "") add_local_symbol(pform_cur_generate, dev_name, cur); pform_cur_generate->add_gate(cur); } else { if (dev_name != "") add_local_symbol(pform_cur_module.front(), dev_name, cur); pform_cur_module.front()->add_gate(cur); } } void pform_makegates(const struct vlltype&loc, PGBuiltin::Type type, struct str_pair_t str, list*delay, std::vector*gates, list*attr) { assert(! pform_cur_module.empty()); if (pform_cur_module.front()->program_block) { cerr << loc << ": error: Gates and switches may not be instantiated in " << "program blocks." << endl; error_count += 1; } if (pform_cur_module.front()->is_interface) { cerr << loc << ": error: Gates and switches may not be instantiated in " << "interfaces." << endl; error_count += 1; } for (unsigned idx = 0 ; idx < gates->size() ; idx += 1) { pform_makegate(type, str, delay, (*gates)[idx], attr); } if (attr) delete attr; delete gates; } /* * A module is different from a gate in that there are different * constraints, and sometimes different syntax. The X_modgate * functions handle the instantiations of modules (and UDP objects) by * making PGModule objects. * * The first pform_make_modgate handles the case of a module * instantiated with ports passed by position. The "wires" is an * ordered array of port expressions. * * The second pform_make_modgate handles the case of a module * instantiated with ports passed by name. The "bind" argument is the * ports matched with names. */ static void pform_make_modgate(perm_string type, perm_string name, struct parmvalue_t*overrides, list*wires, list*ranges, const LineInfo&li, std::list*attr) { for (list::iterator idx = wires->begin() ; idx != wires->end() ; ++idx) { pform_declare_implicit_nets(*idx); } PGModule*cur = new PGModule(type, name, wires); cur->set_line(li); cur->set_ranges(ranges); if (overrides && overrides->by_name) { unsigned cnt = overrides->by_name->size(); named*byname = new named[cnt]; list::iterator by_name_cur = overrides->by_name->begin(); for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++ by_name_cur) { byname[idx].name = by_name_cur->name; byname[idx].parm = by_name_cur->parm; } cur->set_parameters(byname, cnt); } else if (overrides && overrides->by_order) { cur->set_parameters(overrides->by_order); } if (pform_cur_generate) { if (name != "") add_local_symbol(pform_cur_generate, name, cur); pform_cur_generate->add_gate(cur); } else { if (name != "") add_local_symbol(pform_cur_module.front(), name, cur); pform_cur_module.front()->add_gate(cur); } pform_bind_attributes(cur->attributes, attr); } static void pform_make_modgate(perm_string type, perm_string name, struct parmvalue_t*overrides, list*bind, list*ranges, const LineInfo&li, std::list*attr) { unsigned npins = bind->size(); named*pins = new named[npins]; list::iterator bind_cur = bind->begin(); for (unsigned idx = 0 ; idx < npins ; idx += 1, ++bind_cur) { pins[idx].name = bind_cur->name; pins[idx].parm = bind_cur->parm; pform_declare_implicit_nets(bind_cur->parm); } PGModule*cur = new PGModule(type, name, pins, npins); cur->set_line(li); cur->set_ranges(ranges); if (overrides && overrides->by_name) { unsigned cnt = overrides->by_name->size(); named*byname = new named[cnt]; list::iterator by_name_cur = overrides->by_name->begin(); for (unsigned idx = 0 ; idx < cnt ; idx += 1, ++by_name_cur) { byname[idx].name = by_name_cur->name; byname[idx].parm = by_name_cur->parm; } cur->set_parameters(byname, cnt); } else if (overrides && overrides->by_order) { cur->set_parameters(overrides->by_order); } if (pform_cur_generate) { add_local_symbol(pform_cur_generate, name, cur); pform_cur_generate->add_gate(cur); } else { add_local_symbol(pform_cur_module.front(), name, cur); pform_cur_module.front()->add_gate(cur); } pform_bind_attributes(cur->attributes, attr); } void pform_make_modgates(const struct vlltype&loc, perm_string type, struct parmvalue_t*overrides, std::vector*gates, std::list*attr) { // The grammer should not allow module gates to happen outside // an active module. But if really bad input errors combine in // an ugly way with error recovery, then catch this // implausible situation and return an error. if (pform_cur_module.empty()) { cerr << loc << ": internal error: " << "Module instantiations outside module scope are not possible." << endl; error_count += 1; delete gates; return; } assert(! pform_cur_module.empty()); // Detect some more realistic errors. if (pform_cur_module.front()->program_block) { cerr << loc << ": error: Module instantiations are not allowed in " << "program blocks." << endl; error_count += 1; } if (pform_cur_module.front()->is_interface) { cerr << loc << ": error: Module instantiations are not allowed in " << "interfaces." << endl; error_count += 1; } for (unsigned idx = 0 ; idx < gates->size() ; idx += 1) { lgate cur = (*gates)[idx]; perm_string cur_name = lex_strings.make(cur.name); if (cur.parms_by_name) { pform_make_modgate(type, cur_name, overrides, cur.parms_by_name, cur.ranges, cur, attr); } else if (cur.parms) { /* If there are no parameters, the parser will be tricked into thinking it is one empty parameter. This fixes that. */ if ((cur.parms->size() == 1) && (cur.parms->front() == 0)) { delete cur.parms; cur.parms = new list; } pform_make_modgate(type, cur_name, overrides, cur.parms, cur.ranges, cur, attr); } else { list*wires = new list; pform_make_modgate(type, cur_name, overrides, wires, cur.ranges, cur, attr); } } delete gates; } static PGAssign* pform_make_pgassign(PExpr*lval, PExpr*rval, list*del, struct str_pair_t str) { /* Implicit declaration of nets on the LHS of a continuous assignment was introduced in IEEE1364-2001. */ if (generation_flag != GN_VER1995) pform_declare_implicit_nets(lval); list*wires = new list; wires->push_back(lval); wires->push_back(rval); PGAssign*cur; if (del == 0) cur = new PGAssign(wires); else cur = new PGAssign(wires, del); cur->strength0(str.str0); cur->strength1(str.str1); if (pform_cur_generate) pform_cur_generate->add_gate(cur); else pform_cur_module.front()->add_gate(cur); return cur; } void pform_make_pgassign_list(const struct vlltype&loc, list*alist, list*del, struct str_pair_t str) { assert(alist->size() % 2 == 0); while (! alist->empty()) { PExpr*lval = alist->front(); alist->pop_front(); PExpr*rval = alist->front(); alist->pop_front(); PGAssign*tmp = pform_make_pgassign(lval, rval, del, str); FILE_NAME(tmp, loc); } } /* * This function makes the initial assignment to a variable as given * in the source. It handles the case where a variable is assigned * where it is declared, e.g. * * reg foo = ; * * In Verilog-2001 this is only supported at the module level, and is * equivalent to the combination of statements: * * reg foo; * initial foo = ; * * In SystemVerilog, variable initializations are allowed in any scope. * For static variables, initializations are performed before the start * of simulation. For automatic variables, initializations are performed * each time the enclosing block is entered. Here we store the variable * assignments in the current scope, and later elaboration creates an * initialization block that will be executed at the appropriate time. * * This syntax is not part of the IEEE1364-1995 standard, but is * approved by OVI as enhancement BTF-B14. */ void pform_make_var_init(const struct vlltype&li, perm_string name, PExpr*expr) { if (! pform_at_module_level() && !gn_system_verilog()) { VLerror(li, "error: Variable declaration assignments are only " "allowed at the module level."); delete expr; return; } PEIdent*lval = new PEIdent(name); FILE_NAME(lval, li); PAssign*ass = new PAssign(lval, expr, !gn_system_verilog()); FILE_NAME(ass, li); lexical_scope->var_inits.push_back(ass); } /* * This function makes a single signal (a wire, a reg, etc) as * requested by the parser. The name is unscoped, so I attach the * current scope to it (with the scoped_name function) and I try to * resolve it with an existing PWire in the scope. * * The wire might already exist because of an implicit declaration in * a module port, i.e.: * * module foo (bar... * * reg bar; * * The output (or other port direction indicator) may or may not have * been seen already, so I do not do any checking with it yet. But I * do check to see if the name has already been declared, as this * function is called for every declaration. */ static PWire* pform_get_or_make_wire(const struct vlltype&li, perm_string name, NetNet::Type type, NetNet::PortType ptype, PWSRType rt) { PWire *cur = 0; // If this is not a full declaration check if there is already a signal // with the same name that can be extended. if (rt != SR_BOTH) cur = pform_get_wire_in_scope(name); // If the wire already exists but isn't yet fully defined, // carry on adding details. if (rt == SR_NET && cur && !cur->is_net()) { // At the moment there can only be one location for the PWire, if // there is both a port and signal declaration use the location of // the signal. FILE_NAME(cur, li); cur->set_net(type); return cur; } if (rt == SR_PORT && cur && !cur->is_port()) { cur->set_port(ptype); return cur; } // If the wire already exists and is fully defined, this // must be a redeclaration. Start again with a new wire. // The error will be reported when we add the new wire // to the scope. Do not delete the old wire - it will // remain in the local symbol map. cur = new PWire(name, type, ptype, rt); FILE_NAME(cur, li); pform_put_wire_in_scope(name, cur); return cur; } /* * This function is used by the parser when I have port definition of * the form like this: * * input wire signed [7:0] nm; * * The port_type, type, signed_flag and range are known all at once, * so we can create the PWire object all at once instead of piecemeal * as is done for the old method. */ void pform_module_define_port(const struct vlltype&li, perm_string name, NetNet::PortType port_kind, NetNet::Type type, data_type_t*vtype, list*urange, list*attr, bool keep_attr) { pform_check_net_data_type(li, type, vtype); PWire *cur = pform_get_or_make_wire(li, name, type, port_kind, SR_BOTH); pform_set_net_range(cur, dynamic_cast (vtype), SR_BOTH); if (vtype) cur->set_data_type(vtype); if (urange) { cur->set_unpacked_idx(*urange); delete urange; } pform_bind_attributes(cur->attributes, attr, keep_attr); } void pform_module_define_port(const struct vlltype&li, list*ports, NetNet::PortType port_kind, NetNet::Type type, data_type_t*vtype, list*attr) { for (list::iterator cur = ports->begin() ; cur != ports->end() ; ++ cur ) { data_type_t*use_type = vtype; pform_module_define_port(li, cur->name, port_kind, type, use_type, cur->udims, attr, true); if (cur->expr) pform_make_var_init(li, cur->name, cur->expr); } delete ports; delete attr; } /* * this is the basic form of pform_makewire. This takes a single simple * name, port type, net type, data type, and attributes, and creates * the variable/net. Other forms of pform_makewire ultimately call * this one to create the wire and stash it. */ PWire *pform_makewire(const vlltype&li, perm_string name, NetNet::Type type, std::list *indices) { PWire*cur = pform_get_or_make_wire(li, name, type, NetNet::NOT_A_PORT, SR_NET); assert(cur); if (indices && !indices->empty()) cur->set_unpacked_idx(*indices); return cur; } void pform_makewire(const struct vlltype&li, std::list*delay, str_pair_t str, std::list*assign_list, NetNet::Type type, data_type_t*data_type, list*attr) { if (is_compilation_unit(lexical_scope) && !gn_system_verilog()) { VLerror(li, "error: Variable declarations must be contained within a module."); return; } std::vector *wires = new std::vector; for (list::iterator cur = assign_list->begin() ; cur != assign_list->end() ; ++ cur) { decl_assignment_t* curp = *cur; PWire *wire = pform_makewire(li, curp->name, type, &curp->index); wires->push_back(wire); } pform_set_data_type(li, data_type, wires, type, attr); while (! assign_list->empty()) { decl_assignment_t*first = assign_list->front(); assign_list->pop_front(); if (PExpr*expr = first->expr.release()) { if (type == NetNet::REG || type == NetNet::IMPLICIT_REG) { pform_make_var_init(li, first->name, expr); } else { PEIdent*lval = new PEIdent(first->name); FILE_NAME(lval, li); PGAssign*ass = pform_make_pgassign(lval, expr, delay, str); FILE_NAME(ass, li); } } delete first; } } /* * This function is called by the parser to create task ports. The * resulting wire (which should be a register) is put into a list to * be packed into the task parameter list. * * It is possible that the wire (er, register) was already created, * but we know that if the name matches it is a part of the current * task, so in that case I just assign direction to it. * * The following example demonstrates some of the issues: * * task foo; * input a; * reg a, b; * input b; * [...] * endtask * * This function is called when the parser matches the "input a" and * the "input b" statements. For ``a'', this function is called before * the wire is declared as a register, so I create the foo.a * wire. For ``b'', I will find that there is already a foo.b and I * just set the port direction. In either case, the ``reg a, b'' * statement is caught by the block_item non-terminal and processed * there. * * Ports are implicitly type reg, because it must be possible for the * port to act as an l-value in a procedural assignment. It is obvious * for output and inout ports that the type is reg, because the task * only contains behavior (no structure) to a procedural assignment is * the *only* way to affect the output. It is less obvious for input * ports, but in practice an input port receives its value as if by a * procedural assignment from the calling behavior. * * This function also handles the input ports of function * definitions. Input ports to function definitions have the same * constraints as those of tasks, so this works fine. Functions have * no output or inout ports. */ vector*pform_make_task_ports(const struct vlltype&loc, NetNet::PortType pt, data_type_t*vtype, list*ports, bool allow_implicit) { assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); assert(ports); vector*res = new vector(0); PWSRType rt = SR_BOTH; // If this is a non-ansi port declaration and the type is an implicit type // this is only a port declaration. vector_type_t*vec_type = dynamic_cast(vtype); if (allow_implicit && (!vtype || (vec_type && vec_type->implicit_flag))) rt = SR_PORT; for (list::iterator cur = ports->begin(); cur != ports->end(); ++cur) { perm_string &name = cur->name; PWire*curw = pform_get_or_make_wire(loc, name, NetNet::IMPLICIT_REG, pt, rt); if (rt == SR_BOTH) curw->set_data_type(vtype); pform_set_net_range(curw, vec_type, rt); if (cur->udims) { if (pform_requires_sv(loc, "Task/function port with unpacked dimensions")) curw->set_unpacked_idx(*cur->udims); } res->push_back(pform_tf_port_t(curw)); } delete ports; return res; } /* * The parser calls this in the rule that matches increment/decrement * statements. The rule that does the matching creates a PEUnary with * all the information we need, but here we convert that expression to * a compressed assignment statement. */ PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc, PExpr*exp) { PEUnary*expu = dynamic_cast (exp); ivl_assert(*exp, expu != 0); char use_op = 0; switch (expu->get_op()) { case 'i': case 'I': use_op = '+'; break; case 'd': case 'D': use_op = '-'; break; default: ivl_assert(*exp, 0); break; } PExpr*lval = expu->get_expr(); PExpr*rval = new PENumber(new verinum((uint64_t)1, 1)); FILE_NAME(rval, loc); PAssign*tmp = new PAssign(lval, use_op, rval); FILE_NAME(tmp, loc); delete exp; return tmp; } PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name, bool inc_flag) { pform_requires_sv(loc, "Increment/decrement operator"); PExpr*lval = new PEIdent(lex_strings.make(name)); PExpr*rval = new PENumber(new verinum(1)); FILE_NAME(lval, loc); FILE_NAME(rval, loc); PEBinary*tmp = new PEBinary(inc_flag ? '+' : '-', lval, rval); FILE_NAME(tmp, loc); return tmp; } PExpr* pform_genvar_compressed(const struct vlltype &loc, const char *name, char op, PExpr *rval) { pform_requires_sv(loc, "Compressed assignment operator"); PExpr *lval = new PEIdent(lex_strings.make(name)); FILE_NAME(lval, loc); PExpr *expr; switch (op) { case 'l': case 'r': case 'R': expr = new PEBShift(op, lval, rval); break; default: expr = new PEBinary(op, lval, rval); break; } FILE_NAME(expr, loc); return expr; } void pform_set_attrib(perm_string name, perm_string key, char*value) { if (PWire*cur = lexical_scope->wires_find(name)) { cur->attributes[key] = new PEString(value); } else if (PGate*curg = pform_cur_module.front()->get_gate(name)) { curg->attributes[key] = new PEString(value); } else { delete[] value; VLerror("error: Unable to match name for setting attribute."); } } /* * Set the attribute of a TYPE. This is different from an object in * that this applies to every instantiation of the given type. */ void pform_set_type_attrib(perm_string name, const string&key, char*value) { map::const_iterator udp = pform_primitives.find(name); if (udp == pform_primitives.end()) { VLerror("error: Type name is not (yet) defined."); delete[] value; return; } (*udp).second ->attributes[key] = new PEString(value); } LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag, bool low_open, PExpr*low_expr, bool hig_open, PExpr*hig_expr) { // Detect +-inf and make the the *_open flags false to force // the range interpretation as inf. if (low_expr == 0) low_open = false; if (hig_expr == 0) hig_open = false; LexicalScope::range_t*tmp = new LexicalScope::range_t; tmp->exclude_flag = exclude_flag; tmp->low_open_flag = low_open; tmp->low_expr = low_expr; tmp->high_open_flag = hig_open; tmp->high_expr = hig_expr; tmp->next = 0; return tmp; } static void pform_set_type_parameter(const struct vlltype&loc, perm_string name, LexicalScope::range_t*value_range) { pform_requires_sv(loc, "Type parameter"); if (value_range) VLerror(loc, "error: Type parameter must not have value range."); type_parameter_t *type = new type_parameter_t(name); pform_set_typedef(loc, name, type, 0); } void pform_set_parameter(const struct vlltype&loc, perm_string name, bool is_local, bool is_type, data_type_t*data_type, PExpr*expr, LexicalScope::range_t*value_range) { LexicalScope*scope = lexical_scope; if (is_compilation_unit(scope) && !gn_system_verilog()) { VLerror(loc, "error: %s declarations must be contained within a module.", is_local ? "localparam" : "parameter"); return; } if (expr == 0) { if (is_local) { VLerror(loc, "error: localparam must have a value."); } else if (!pform_in_parameter_port_list) { VLerror(loc, "error: parameter declared outside parameter " "port list must have a default value."); } else { pform_requires_sv(loc, "parameter without default value"); } } bool overridable = !is_local; if (scope == pform_cur_generate && !is_local) { if (!gn_system_verilog()) { VLerror(loc, "parameter declarations are not permitted in generate blocks"); return; } // SystemVerilog allows `parameter` in generate blocks, but it has // the same semantics as `localparam` in that scope. overridable = false; } bool in_module = dynamic_cast(scope) && scope == pform_cur_module.front(); if (!pform_in_parameter_port_list && in_module && scope->has_parameter_port_list) overridable = false; if (pform_in_class()) overridable = false; Module::param_expr_t*parm = new Module::param_expr_t(); FILE_NAME(parm, loc); if (is_type) pform_set_type_parameter(loc, name, value_range); else add_local_symbol(scope, name, parm); parm->expr = expr; parm->data_type = data_type; parm->range = value_range; parm->local_flag = is_local; parm->overridable = overridable; parm->type_flag = is_type; scope->parameters[name] = parm; // Only a module keeps the position of the parameter. if (overridable && in_module) pform_cur_module.front()->param_names.push_back(name); } void pform_set_specparam(const struct vlltype&loc, perm_string name, list*range, PExpr*expr) { assert(! pform_cur_module.empty()); Module*scope = pform_cur_module.front(); if (scope != lexical_scope) { delete range; delete expr; return; } assert(expr); Module::param_expr_t*parm = new Module::param_expr_t(); FILE_NAME(parm, loc); add_local_symbol(scope, name, parm); pform_cur_module.front()->specparams[name] = parm; parm->expr = expr; parm->range = 0; if (range) { assert(range->size() == 1); parm->data_type = new vector_type_t(IVL_VT_LOGIC, false, range); parm->range = 0; } } void pform_set_defparam(const pform_name_t&name, PExpr*expr) { assert(expr); if (pform_cur_generate) pform_cur_generate->defparms.push_back(make_pair(name,expr)); else pform_cur_module.front()->defparms.push_back(make_pair(name,expr)); } void pform_make_let(const struct vlltype&loc, perm_string name, list*ports, PExpr*expr) { LexicalScope*scope = pform_peek_scope(); cerr << loc.get_fileline() << ": sorry: let declarations (" << name << ") are not currently supported." << endl; error_count += 1; PLet*res = new PLet(name, scope, ports, expr); FILE_NAME(res, loc); /* cerr << "Found: "; res->dump(cerr, 0); */ delete res; delete ports; delete expr; } PLet::let_port_t* pform_make_let_port(data_type_t*data_type, perm_string name, list*range, PExpr*def) { PLet::let_port_t*res = new PLet::let_port_t; res->type_ = data_type; res->name_ = name; res->range_ = range; res->def_ = def; return res; } /* * Specify paths. */ extern PSpecPath* pform_make_specify_path(const struct vlltype&li, list*src, char pol, bool full_flag, list*dst) { PSpecPath*path = new PSpecPath(src->size(), dst->size(), pol, full_flag); FILE_NAME(path, li); unsigned idx; list::const_iterator cur; idx = 0; for (idx = 0, cur = src->begin() ; cur != src->end() ; ++ idx, ++ cur) { path->src[idx] = *cur; } assert(idx == path->src.size()); delete src; for (idx = 0, cur = dst->begin() ; cur != dst->end() ; ++ idx, ++ cur) { path->dst[idx] = *cur; } assert(idx == path->dst.size()); delete dst; return path; } extern PSpecPath*pform_make_specify_edge_path(const struct vlltype&li, int edge_flag, /*posedge==true */ list*src, char pol, bool full_flag, list*dst, PExpr*data_source_expression) { PSpecPath*tmp = pform_make_specify_path(li, src, pol, full_flag, dst); tmp->edge = edge_flag; tmp->data_source_expression = data_source_expression; return tmp; } extern PSpecPath* pform_assign_path_delay(PSpecPath*path, list*del) { if (path == 0) return 0; assert(path->delays.empty()); path->delays.resize(del->size()); for (unsigned idx = 0 ; idx < path->delays.size() ; idx += 1) { path->delays[idx] = del->front(); del->pop_front(); } delete del; return path; } extern void pform_module_specify_path(PSpecPath*obj) { if (obj == 0) return; pform_cur_module.front()->specify_paths.push_back(obj); } void pform_set_port_type(const struct vlltype&li, list*ports, NetNet::PortType pt, data_type_t*dt, list*attr) { assert(pt != NetNet::PIMPLICIT && pt != NetNet::NOT_A_PORT); vector_type_t *vt = dynamic_cast (dt); bool have_init_expr = false; for (list::iterator cur = ports->begin() ; cur != ports->end() ; ++ cur ) { PWire *wire = pform_get_or_make_wire(li, cur->name, NetNet::IMPLICIT, pt, SR_PORT); pform_set_net_range(wire, vt, SR_PORT, attr); if (cur->udims) { cerr << li << ": warning: " << "Array dimensions in incomplete port declarations " << "are currently ignored." << endl; cerr << li << ": : " << "The dimensions specified in the net or variable " << "declaration will be used." << endl; delete cur->udims; } if (cur->expr) { have_init_expr = true; delete cur->expr; } } if (have_init_expr) { cerr << li << ": error: " << "Incomplete port declarations cannot be initialized." << endl; error_count += 1; } delete ports; delete dt; delete attr; } /* * This function detects the derived class for the given type and * dispatches the type to the proper subtype function. */ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, std::vector *wires, NetNet::Type net_type, list*attr) { if (data_type == 0) { VLerror(li, "internal error: data_type==0."); assert(0); } vector_type_t*vec_type = dynamic_cast (data_type); for (std::vector::iterator it= wires->begin(); it != wires->end() ; ++it) { PWire *wire = *it; pform_set_net_range(wire, vec_type); // If these fail there is a bug somewhere else. pform_set_data_type() // is only ever called on a fresh wire that already exists. bool rc = wire->set_wire_type(net_type); ivl_assert(li, rc); wire->set_data_type(data_type); pform_bind_attributes(wire->attributes, attr, true); } delete wires; } vector* pform_make_udp_input_ports(list*names) { vector*out = new vector(names->size()); unsigned idx = 0; for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; PWire*pp = new PWire(txt, NetNet::IMPLICIT, NetNet::PINPUT); (*out)[idx] = pp; idx += 1; } delete names; return out; } PProcess* pform_make_behavior(ivl_process_type_t type, Statement*st, list*attr) { // Add an implicit @* around the statement for the always_comb and // always_latch statements. if ((type == IVL_PR_ALWAYS_COMB) || (type == IVL_PR_ALWAYS_LATCH)) { PEventStatement *tmp = new PEventStatement(true); tmp->set_line(*st); tmp->set_statement(st); st = tmp; } PProcess*pp = new PProcess(type, st); // If we are in a part of the code where the meta-comment // synthesis translate_off is in effect, then implicitly add // the ivl_synthesis_off attribute to any behavioral code that // we run into. if (pform_mc_translate_flag == false) { if (attr == 0) attr = new list; named_pexpr_t tmp; tmp.name = perm_string::literal("ivl_synthesis_off"); tmp.parm = 0; attr->push_back(tmp); } pform_bind_attributes(pp->attributes, attr); pform_put_behavior_in_scope(pp); ivl_assert(*st, ! pform_cur_module.empty()); if (pform_cur_module.front()->program_block && ((type == IVL_PR_ALWAYS) || (type == IVL_PR_ALWAYS_COMB) || (type == IVL_PR_ALWAYS_FF) || (type == IVL_PR_ALWAYS_LATCH))) { cerr << st->get_fileline() << ": error: Always statements are not allowed" << " in program blocks." << endl; error_count += 1; } return pp; } void pform_start_modport_item(const struct vlltype&loc, const char*name) { Module*scope = pform_cur_module.front(); ivl_assert(loc, scope && scope->is_interface); ivl_assert(loc, pform_cur_modport == 0); perm_string use_name = lex_strings.make(name); pform_cur_modport = new PModport(use_name); FILE_NAME(pform_cur_modport, loc); add_local_symbol(scope, use_name, pform_cur_modport); scope->modports[use_name] = pform_cur_modport; delete[] name; } void pform_end_modport_item(const struct vlltype&loc) { ivl_assert(loc, pform_cur_modport); pform_cur_modport = 0; } void pform_add_modport_port(const struct vlltype&loc, NetNet::PortType port_type, perm_string name, PExpr*expr) { ivl_assert(loc, pform_cur_modport); if (pform_cur_modport->simple_ports.find(name) != pform_cur_modport->simple_ports.end()) { cerr << loc << ": error: duplicate declaration of port '" << name << "' in modport list '" << pform_cur_modport->name() << "'." << endl; error_count += 1; } pform_cur_modport->simple_ports[name] = make_pair(port_type, expr); } bool pform_requires_sv(const struct vlltype&loc, const char *feature) { if (gn_system_verilog()) return true; VLerror(loc, "error: %s requires SystemVerilog.", feature); return false; } void pform_check_net_data_type(const struct vlltype&loc, NetNet::Type net_type, const data_type_t *data_type) { // For SystemVerilog the type is checked during elaboration since due to // forward typedefs and type parameters the actual type might not be known // yet. if (gn_system_verilog()) return; switch (net_type) { case NetNet::REG: case NetNet::IMPLICIT_REG: return; default: break; } if (!data_type) return; const vector_type_t*vec_type = dynamic_cast(data_type); if (vec_type && vec_type->implicit_flag) return; const real_type_t*rtype = dynamic_cast(data_type); if (rtype && rtype->type_code() == real_type_t::REAL) return; pform_requires_sv(loc, "Net data type"); } FILE*vl_input = 0; extern void reset_lexor(); int pform_parse(const char*path) { vl_file = path; if (strcmp(path, "-") == 0) { vl_input = stdin; } else if (ivlpp_string) { char*cmdline = (char*)malloc(strlen(ivlpp_string) + strlen(path) + 4); strcpy(cmdline, ivlpp_string); strcat(cmdline, " \""); strcat(cmdline, path); strcat(cmdline, "\""); if (verbose_flag) cerr << "Executing: " << cmdline << endl<< flush; vl_input = popen(cmdline, "r"); if (vl_input == 0) { cerr << "Unable to preprocess " << path << "." << endl; return 1; } if (verbose_flag) cerr << "...parsing output from preprocessor..." << endl << flush; free(cmdline); } else { vl_input = fopen(path, "r"); if (vl_input == 0) { cerr << "Unable to open " << path << "." << endl; return 1; } } if (pform_units.empty() || separate_compilation) { char unit_name[20]; static unsigned nunits = 0; if (separate_compilation) snprintf(unit_name, sizeof(unit_name)-1, "$unit#%u", ++nunits); else snprintf(unit_name, sizeof(unit_name)-1, "$unit"); PPackage*unit = new PPackage(lex_strings.make(unit_name), 0); unit->default_lifetime = LexicalScope::STATIC; unit->set_file(filename_strings.make(path)); unit->set_lineno(1); pform_units.push_back(unit); pform_cur_module.clear(); pform_cur_generate = 0; pform_cur_modport = 0; pform_set_timescale(def_ts_units, def_ts_prec, 0, 0); allow_timeunit_decl = true; allow_timeprec_decl = true; lexical_scope = unit; } reset_lexor(); error_count = 0; warn_count = 0; int rc = VLparse(); if (vl_input != stdin) { if (ivlpp_string) pclose(vl_input); else fclose(vl_input); } if (rc) { cerr << "I give up." << endl; error_count += 1; } destroy_lexor(); return error_count; } iverilog-12_0/pform.h000066400000000000000000000502421435245347300146460ustar00rootroot00000000000000#ifndef IVL_pform_H #define IVL_pform_H /* * Copyright (c) 1998-2021 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 "netlist.h" # include "HName.h" # include "named.h" # include "Module.h" # include "Statement.h" # include "AStatement.h" # include "PGate.h" # include "PExpr.h" # include "PTask.h" # include "PUdp.h" # include "PWire.h" # include "verinum.h" # include "discipline.h" # include # include # include # include # include /* * These classes implement the parsed form (P-form for short) of the * original Verilog source. the parser generates the pform for the * convenience of later processing steps. */ /* * Wire objects represent the named wires (of various flavor) declared * in the source. * * Gate objects are the functional modules that are connected together * by wires. * * Wires and gates, connected by joints, represent a netlist. The * netlist is therefore a representation of the desired circuit. */ class PGate; class PExpr; class PPackage; class PSpecPath; class PClass; class PPackage; struct vlltype; struct lgate; /* * The min:typ:max expression s selected at parse time using the * enumeration. When the compiler makes a choice, it also prints a * warning if min_typ_max_warn > 0. */ extern enum MIN_TYP_MAX { MIN, TYP, MAX } min_typ_max_flag; extern unsigned min_typ_max_warn; PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max); /* * This flag is true if the lexor thinks we are in a library source * file. */ extern bool pform_library_flag; /* * These type are lexical types -- that is, types that are used as * lexical values to decorate the parse tree during parsing. They are * not in any way preserved once parsing is done. */ /* This is information about port name information for named port connections. */ struct parmvalue_t { std::list*by_order; std::list*by_name; }; struct str_pair_t { ivl_drive_t str0, str1; }; /* Use this function to transform the parted form of the attribute list to the attribute map that is used later. */ extern void pform_bind_attributes(std::map&attributes, std::list*attr, bool keep_attr =false); /* The lexor calls this function to change the default nettype. */ extern void pform_set_default_nettype(NetNet::Type net, const char*file, unsigned lineno); /* Return true if currently processing a program block. This can be used to reject statements that cannot exist in program blocks. */ extern bool pform_in_program_block(void); /* Return true if currently processing an interface. This can be used to reject statements that cannot exist in interfaces. */ extern bool pform_in_interface(void); /* * Look for the given wire in the current lexical scope. If the wire * (including variables of any type) cannot be found in the current * scope, then return 0. */ extern PWire* pform_get_wire_in_scope(perm_string name); extern PWire* pform_get_make_wire_in_scope(const struct vlltype&li, perm_string name, NetNet::Type net_type, ivl_variable_type_t vt_type); /* * The parser uses startmodule and endmodule together to build up a * module as it parses it. The startmodule tells the pform code that a * module has been noticed in the source file and the following events * are to apply to the scope of that module. The endmodule causes the * pform to close up and finish the named module. * * The program_block flag indicates that the module is actually a program * block. The is_interface flag indicates that the module is actually * an interface. These flags have implications during parse and during * elaboration/code generation. */ extern void pform_startmodule(const struct vlltype&loc, const char*name, bool program_block, bool is_interface, LexicalScope::lifetime_t lifetime, std::list*attr); extern void pform_module_set_ports(std::vector*); extern void pform_set_scope_timescale(const struct vlltype&loc); /* These functions are used when we have a complete port definition, either in an ansi style or non-ansi style declaration. In this case, we have everything needed to define the port, all in one place. */ extern void pform_module_define_port(const struct vlltype&li, perm_string name, NetNet::PortType, NetNet::Type type, data_type_t*vtype, std::list*urange, std::list*attr, bool keep_attr =false); extern void pform_module_define_port(const struct vlltype&li, std::list*ports, NetNet::PortType, NetNet::Type type, data_type_t*vtype, std::list*attr); extern Module::port_t* pform_module_port_reference(const struct vlltype&loc, perm_string name); extern void pform_endmodule(const char*, bool inside_celldefine, Module::UCDriveType uc_drive_def); extern void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, std::list*base_exprs, bool virtual_class); extern void pform_class_property(const struct vlltype&loc, property_qualifier_t pq, data_type_t*data_type, std::list*decls); extern void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net); extern void pform_set_constructor_return(PFunction*net); extern void pform_end_class_declaration(const struct vlltype&loc); extern bool pform_in_class(); extern void pform_make_udp(const struct vlltype&loc, perm_string name, std::list*parms, std::vector*decl, std::list*table, Statement*init); extern void pform_make_udp(const struct vlltype&loc, perm_string name, bool sync_flag, perm_string out_name, PExpr*sync_init, std::list*parms, std::list*table); /* * Package related functions. */ extern void pform_start_package_declaration(const struct vlltype&loc, const char*type, LexicalScope::lifetime_t lifetime); extern void pform_end_package_declaration(const struct vlltype&loc); extern void pform_package_import(const struct vlltype&loc, PPackage*pkg, const char*ident); extern PExpr* pform_package_ident(const struct vlltype&loc, PPackage*pkg, pform_name_t*ident); /* * Interface related functions. */ extern void pform_start_modport_item(const struct vlltype&loc, const char*name); extern void pform_end_modport_item(const struct vlltype&loc); extern void pform_add_modport_port(const struct vlltype&loc, NetNet::PortType port_type, perm_string name, PExpr*expr); /* * This creates an identifier aware of names that may have been * imported from other packages. */ extern PEIdent* pform_new_ident(const struct vlltype&loc, const pform_name_t&name); extern PTrigger* pform_new_trigger(const struct vlltype&loc, PPackage*pkg, const pform_name_t&name); extern PNBTrigger* pform_new_nb_trigger(const struct vlltype&loc, const std::list*dly, const pform_name_t&name); /* * Enter/exit name scopes. The push_scope function pushes the scope * name string onto the scope hierarchy. The pop pulls it off and * deletes it. Thus, the string pushed must be allocated. */ extern void pform_pop_scope(); /* * Peek at the current (most recently active) scope. */ extern LexicalScope* pform_peek_scope(); extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name); extern PFunction*pform_push_constructor_scope(const struct vlltype&loc); extern PPackage* pform_push_package_scope(const struct vlltype&loc, perm_string name, LexicalScope::lifetime_t lifetime); extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name, LexicalScope::lifetime_t lifetime); extern PFunction*pform_push_function_scope(const struct vlltype&loc, const char*name, LexicalScope::lifetime_t lifetime); extern PBlock*pform_push_block_scope(const struct vlltype&loc, char*name, PBlock::BL_TYPE tt); extern void pform_put_behavior_in_scope(AProcess*proc); extern verinum* pform_verinum_with_size(verinum*s, verinum*val, const char*file, unsigned lineno); /* * This function takes the list of names as new genvars to declare in * the current module or generate scope. */ extern void pform_genvars(const struct vlltype&li, std::list*names); /* * This flag is set by the parser to indicate the current generate block * was not enclosed in a begin-end pair. This is a pre-requisite for * directly nesting generate constructs. */ extern bool pform_generate_single_item; extern void pform_start_generate_for(const struct vlltype&li, bool local_index, char*ident1, PExpr*init, PExpr*test, char*ident2, PExpr*next); extern void pform_start_generate_if(const struct vlltype&li, PExpr*test); extern void pform_start_generate_else(const struct vlltype&li); extern void pform_start_generate_case(const struct vlltype&lp, PExpr*test); extern void pform_start_generate_nblock(const struct vlltype&lp, char*name); extern void pform_generate_case_item(const struct vlltype&lp, std::list*test); extern void pform_generate_block_name(char*name); extern void pform_endgenerate(bool end_conditional); /* * This function returns the lexically containing generate scheme, if * there is one. The parser may use this to check if we are within a * generate scheme. */ extern PGenerate* pform_parent_generate(void); bool pform_error_in_generate(const vlltype&loc, const char *type); extern void pform_make_elab_task(const struct vlltype&li, perm_string name, const std::list¶ms); extern void pform_set_typedef(const struct vlltype&loc, perm_string name, data_type_t*data_type, std::list*unp_ranges = nullptr); extern void pform_forward_typedef(const struct vlltype&loc, perm_string name, enum typedef_t::basic_type basic_type); extern void pform_set_type_referenced(const struct vlltype&loc, const char*name); /* * This function makes a PECallFunction of the named function. */ extern PECallFunction* pform_make_call_function(const struct vlltype&loc, const pform_name_t&name, const std::list&parms); extern PCallTask* pform_make_call_task(const struct vlltype&loc, const pform_name_t&name, const std::list&parms); extern void pform_make_foreach_declarations(const struct vlltype&loc, std::list*loop_vars); extern PForeach* pform_make_foreach(const struct vlltype&loc, char*ident, std::list*loop_vars, Statement*stmt); /* * The makewire functions announce to the pform code new wires. These * go into a module that is currently opened. */ extern PWire *pform_makewire(const struct vlltype&li, perm_string name, NetNet::Type type, std::list *indices); /* This form handles assignment declarations. */ extern void pform_makewire(const struct vlltype&li, std::list*delay, str_pair_t str, std::list*assign_list, NetNet::Type type, data_type_t*data_type, std::list*attr = 0); extern void pform_make_var(const struct vlltype&loc, std::list*assign_list, data_type_t*data_type, std::list*attr = 0); extern void pform_make_var_init(const struct vlltype&li, perm_string name, PExpr*expr); /* This function is used when we have an incomplete port definition in a non-ansi style declaration. Look up the names of the wires, and set the port type, i.e. input, output or inout, and, if specified, the range and signedness. If the wire does not exist, create it. */ extern void pform_set_port_type(const struct vlltype&li, std::list*ports, NetNet::PortType, data_type_t*dt, std::list*attr); extern void pform_set_data_type(const struct vlltype&li, data_type_t *data_type, std::vector *wires, NetNet::Type net_type, std::list*attr); extern void pform_set_string_type(const struct vlltype&li, const string_type_t*string_type, std::list*names, NetNet::Type net_type, std::list*attr); extern void pform_set_class_type(const struct vlltype&li, class_type_t*class_type, std::list*names, NetNet::Type net_type, std::list*addr); /* pform_set_attrib and pform_set_type_attrib exist to support the $attribute syntax, which can only set string values to attributes. The functions keep the value strings that are passed in. */ extern void pform_set_attrib(perm_string name, perm_string key, char*value); extern void pform_set_type_attrib(perm_string name, const std::string&key, char*value); extern LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag, bool low_open, PExpr*low_expr, bool hig_open, PExpr*hig_expr); extern void pform_set_parameter(const struct vlltype&loc, perm_string name, bool is_local, bool is_type, data_type_t*data_type, PExpr*expr, LexicalScope::range_t*value_range); extern void pform_set_specparam(const struct vlltype&loc, perm_string name, std::list*range, PExpr*expr); extern void pform_set_defparam(const pform_name_t&name, PExpr*expr); extern void pform_make_let(const struct vlltype&loc, perm_string name, std::list*ports, PExpr*expr); extern PLet::let_port_t* pform_make_let_port(data_type_t*data_type, perm_string name, std::list*range, PExpr*def); /* * Functions related to specify blocks. */ extern PSpecPath*pform_make_specify_path(const struct vlltype&li, std::list*src, char pol, bool full_flag, std::list*dst); extern PSpecPath*pform_make_specify_edge_path(const struct vlltype&li, int edge_flag, /*posedge==true */ std::list*src, char pol, bool full_flag, std::list*dst, PExpr*data_source_expression); extern PSpecPath*pform_assign_path_delay(PSpecPath*obj, std::list*delays); extern void pform_module_specify_path(PSpecPath*obj); /* * pform_make_behavior creates processes that are declared with always * or initial items. */ extern PProcess* pform_make_behavior(ivl_process_type_t, Statement*, std::list*attr); extern void pform_mc_translate_on(bool flag); extern std::vector* pform_make_udp_input_ports(std::list*); extern void pform_make_events(const struct vlltype&loc, std::list*names); /* * The makegate function creates a new gate (which need not have a * name) and connects it to the specified wires. */ extern void pform_makegates(const struct vlltype&loc, PGBuiltin::Type type, struct str_pair_t str, std::list*delay, std::vector*gates, std::list*attr); extern void pform_make_modgates(const struct vlltype&loc, perm_string type, struct parmvalue_t*overrides, std::vector*gates, std::list*attr); /* Make a continuous assignment node, with optional bit- or part- select. */ extern void pform_make_pgassign_list(const struct vlltype&loc, std::list*alist, std::list*del, struct str_pair_t str); extern std::vector*pform_make_task_ports(const struct vlltype&loc, NetNet::PortType pt, data_type_t*vtype, std::list*ports, bool allow_implicit = false); /* * The parser uses this function to convert a unary * increment/decrement expression to the equivalent compressed * assignment statement. */ extern PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc, PExpr*exp); /* * The parser uses this function to convert a genvar increment/decrement * expression to the equivalent binary add/subtract expression. */ extern PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name, bool inc_flag); extern PExpr* pform_genvar_compressed(const struct vlltype &loc, const char *name, char op, PExpr *rval); /* * These are functions that the outside-the-parser code uses the do * interesting things to the Verilog. The parse function reads and * parses the source file and places all the modules it finds into the * mod list. The dump function dumps a module to the output stream. */ extern void pform_dump(std::ostream&out, Module*mod); /* ** pform_discipline.cc * Functions for handling the parse of natures and disciplines. These * functions are in pform_disciplines.cc */ extern void pform_start_nature(const char*name); extern void pform_end_nature(const struct vlltype&loc); extern void pform_nature_access(const struct vlltype&loc, const char*name); extern void pform_start_discipline(const char*name); extern void pform_end_discipline(const struct vlltype&loc); extern void pform_discipline_domain(const struct vlltype&loc, ivl_dis_domain_t use_domain); extern void pform_discipline_potential(const struct vlltype&loc, const char*name); extern void pform_discipline_flow(const struct vlltype&loc, const char*name); extern void pform_attach_discipline(const struct vlltype&loc, ivl_discipline_t discipline, std::list*names); extern void pform_dump(std::ostream&out, const ivl_nature_s*); extern void pform_dump(std::ostream&out, const ivl_discipline_s*); /* ** pform_analog.cc */ extern void pform_make_analog_behavior(const struct vlltype&loc, ivl_process_type_t type, Statement*st); extern AContrib*pform_contribution_statement(const struct vlltype&loc, PExpr*lval, PExpr*rval); extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*n1, char*n2); extern PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*branch); /* * Parse configuration file with format =, where key * is the hierarchical name of a valid parameter name and value * is the value user wants to assign to. The value should be constant. */ extern void parm_to_defparam_list(const std::string¶m); /* * Tasks to set the timeunit or timeprecision for SystemVerilog. */ extern bool get_time_unit(const char*cp, int &unit); extern int pform_get_timeunit(); extern int pform_get_timeprec(); extern void pform_set_timeunit(const char*txt, bool initial_decl); extern void pform_set_timeprec(const char*txt, bool initial_decl); /* * Flags to determine whether this is an initial declaration. */ extern bool allow_timeunit_decl; extern bool allow_timeprec_decl; void pform_put_enum_type_in_scope(enum_type_t*enum_set); bool pform_requires_sv(const struct vlltype&loc, const char *feature); void pform_start_parameter_port_list(); void pform_end_parameter_port_list(); void pform_check_net_data_type(const struct vlltype&loc, NetNet::Type net_type, const data_type_t *data_type); #endif /* IVL_pform_H */ iverilog-12_0/pform_analog.cc000066400000000000000000000042721435245347300163270ustar00rootroot00000000000000/* * Copyright (c) 2008-2021 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 "config.h" # include "compiler.h" # include "pform.h" # include "parse_misc.h" # include "AStatement.h" using namespace std; AContrib* pform_contribution_statement(const struct vlltype&loc, PExpr*lval, PExpr*rval) { AContrib*tmp = new AContrib(lval, rval); FILE_NAME(tmp, loc); return tmp; } void pform_make_analog_behavior(const struct vlltype&loc, ivl_process_type_t pt, Statement*statement) { AProcess*proc = new AProcess(pt, statement); FILE_NAME(proc, loc); pform_put_behavior_in_scope(proc); } PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*n1, char*n2) { vector parms (2); parms[0] = new PEIdent(lex_strings.make(n1)); FILE_NAME(parms[0], loc); parms[1] = new PEIdent(lex_strings.make(n2)); FILE_NAME(parms[1], loc); PECallFunction*res = new PECallFunction(lex_strings.make(name), parms); FILE_NAME(res, loc); return res; } PExpr* pform_make_branch_probe_expression(const struct vlltype&loc, char*name, char*branch_name) { vector parms (1); parms[0] = new PEIdent(lex_strings.make(branch_name)); FILE_NAME(parms[0], loc); PECallFunction*res = new PECallFunction(lex_strings.make(name), parms); FILE_NAME(res, loc); return res; } iverilog-12_0/pform_disciplines.cc000066400000000000000000000153101435245347300173670ustar00rootroot00000000000000/* * Copyright (c) 2008-2021 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 "config.h" # include "compiler.h" # include "pform.h" # include "parse_misc.h" # include "discipline.h" using namespace std; map natures; map disciplines; map access_function_nature; static perm_string nature_name = perm_string(); static perm_string nature_access = perm_string(); void pform_start_nature(const char*name) { nature_name = lex_strings.make(name); } void pform_nature_access(const struct vlltype&loc, const char*name) { if (nature_access) { cerr << loc.text << ":" << loc.first_line << ": error: " << "Too many access names for nature " << nature_name << "." << endl; error_count += 1; return; } nature_access = lex_strings.make(name); } void pform_end_nature(const struct vlltype&loc) { // The nature access function is required. If it is missing, // then signal an error. For a temporary expedient, we can set // the nature name as the access function, but don't expect it // to work. if (! nature_access) { cerr << loc.text << ":" << loc.first_line << ": error: " << "Missing access name for nature " << nature_name << "." << endl; error_count += 1; nature_access = nature_name; } ivl_nature_s*tmp = new ivl_nature_s(nature_name, nature_access); FILE_NAME(tmp, loc); natures[nature_name] = tmp; // Make sure the access function is not used by multiple // different natures. if (ivl_nature_t dup_access_nat = access_function_nature[nature_access]) { cerr << tmp->get_fileline() << ": error: " << "Access function name " << nature_access << " is already used by nature " << dup_access_nat->name() << " declared at " << dup_access_nat->get_fileline() << "." << endl; error_count += 1; } // Map the access function back to the nature so that // expressions that use the access function can find it. access_function_nature[nature_access] = tmp; nature_name = perm_string(); nature_access = perm_string(); } static perm_string discipline_name; static ivl_dis_domain_t discipline_domain = IVL_DIS_NONE; static ivl_nature_t discipline_potential = 0; static ivl_nature_t discipline_flow = 0; void pform_start_discipline(const char*name) { discipline_name = lex_strings.make(name); discipline_domain = IVL_DIS_NONE; } void pform_discipline_domain(const struct vlltype&loc, ivl_dis_domain_t use_domain) { assert(use_domain != IVL_DIS_NONE); if (discipline_domain != IVL_DIS_NONE) { cerr << loc.text << ":" << loc.first_line << ": error: " << "Too many domain attributes for discipline " << discipline_name << "." << endl; error_count += 1; return; } discipline_domain = use_domain; } void pform_discipline_potential(const struct vlltype&loc, const char*name) { if (discipline_potential) { cerr << loc.text << ":" << loc.first_line << ": error: " << "Too many potential natures for discipline " << discipline_name << "." << endl; error_count += 1; return; } perm_string key = lex_strings.make(name); discipline_potential = natures[key]; if (discipline_potential == 0) { cerr << loc.text << ":" << loc.first_line << ": error: " << "nature " << key << " is not declared." << endl; error_count += 1; return; } } void pform_discipline_flow(const struct vlltype&loc, const char*name) { if (discipline_flow) { cerr << loc.text << ":" << loc.first_line << ": error: " << "Too many flow natures for discipline " << discipline_name << "." << endl; error_count += 1; return; } perm_string key = lex_strings.make(name); discipline_flow = natures[key]; if (discipline_flow == 0) { cerr << loc.text << ":" << loc.first_line << ": error: " << "nature " << key << " is not declared." << endl; error_count += 1; return; } } void pform_end_discipline(const struct vlltype&loc) { // If the domain is not otherwise specified, then take it to // be continuous if potential or flow natures are given. if (discipline_domain == IVL_DIS_NONE && (discipline_potential||discipline_flow)) discipline_domain = IVL_DIS_CONTINUOUS; ivl_discipline_t tmp = new ivl_discipline_s(discipline_name, discipline_domain, discipline_potential, discipline_flow); disciplines[discipline_name] = tmp; FILE_NAME(tmp, loc); /* Clear the static variables for the next item. */ discipline_name = perm_string(); discipline_domain = IVL_DIS_NONE; discipline_potential = 0; discipline_flow = 0; } /* * The parser uses this function to attach a discipline to a wire. The * wire may be declared by now, or will be declared further later. If * it is already declared, we just attach the discipline. If it is not * declared yet, then this is the declaration and we create the signal * in the current lexical scope. */ void pform_attach_discipline(const struct vlltype&loc, ivl_discipline_t discipline, list*names) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { PWire* cur_net = pform_get_wire_in_scope(*cur); if (cur_net == 0) { /* Not declared yet, declare it now. */ cur_net = pform_makewire(loc, *cur, NetNet::WIRE, 0); assert(cur_net); } if (ivl_discipline_t tmp = cur_net->get_discipline()) { cerr << loc.text << ":" << loc.first_line << ": error: " << "discipline " << discipline->name() << " cannot override existing discipline " << tmp->name() << " on net " << cur_net->basename() << endl; error_count += 1; } else { data_type_t *type = new real_type_t(real_type_t::REAL); FILE_NAME(type, loc); cur_net->set_data_type(type); cur_net->set_discipline(discipline); } } } iverilog-12_0/pform_dump.cc000066400000000000000000001317331435245347300160360ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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" /* * This file provides the pform_dump function, that dumps the module * passed as a parameter. The dump is as much as possible in Verilog * syntax, so that a human can tell that it really does describe the * module in question. */ # include "pform.h" # include "PClass.h" # include "PEvent.h" # include "PGenerate.h" # include "PPackage.h" # include "PSpec.h" # include "PTask.h" # include "discipline.h" # include "ivl_target_priv.h" # include # include # include using namespace std; ostream& operator << (ostream&out, const PExpr&obj) { obj.dump(out); return out; } ostream& operator << (ostream&out, const PEventStatement&obj) { obj.dump_inline(out); return out; } ostream& operator << (ostream&o, const PDelays&d) { d.dump_delays(o); return o; } ostream& operator<< (ostream&out, const index_component_t&that) { out << "["; switch (that.sel) { case index_component_t::SEL_BIT: out << *that.msb; break; case index_component_t::SEL_BIT_LAST: out << "$"; break; case index_component_t::SEL_PART: out << *that.msb << ":" << *that.lsb; break; case index_component_t::SEL_IDX_UP: out << *that.msb << "+:" << *that.lsb; break; case index_component_t::SEL_IDX_DO: out << *that.msb << "-:" << *that.lsb; break; default: out << "???"; break; } out << "]"; return out; } ostream& operator<< (ostream&out, const name_component_t&that) { if (that.name == THIS_TOKEN) out << "this"; else if (that.name == SUPER_TOKEN) out << "super"; else out << that.name.str(); typedef std::list::const_iterator index_it_t; for (index_it_t idx = that.index.begin() ; idx != that.index.end() ; ++ idx ) { out << *idx; } return out; } ostream& operator<< (ostream&o, const pform_name_t&that) { pform_name_t::const_iterator cur; if (that.empty()) { o << ""; return o; } cur = that.begin(); o << *cur; ++ cur; while (cur != that.end()) { o << "." << *cur; ++ cur; } return o; } std::ostream& operator << (std::ostream&out, ivl_process_type_t pt) { switch (pt) { case IVL_PR_INITIAL: out << "initial"; break; case IVL_PR_ALWAYS: out << "always"; break; case IVL_PR_ALWAYS_COMB: out << "always_comb"; break; case IVL_PR_ALWAYS_FF: out << "always_ff"; break; case IVL_PR_ALWAYS_LATCH: out << "always_latch"; break; case IVL_PR_FINAL: out << "final"; break; } return out; } std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom) { switch (dom) { case IVL_DIS_NONE: out << "no-domain"; break; case IVL_DIS_DISCRETE: out << "discrete"; break; case IVL_DIS_CONTINUOUS: out << "continuous"; break; default: assert(0); break; } return out; } void data_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << typeid(*this).name() << endl; } ostream& data_type_t::debug_dump(ostream&out) const { out << typeid(*this).name(); return out; } std::ostream& typeref_t::debug_dump(ostream&out) const { if (scope) out << scope->pscope_name() << "::"; out << type->name; return out; } ostream& atom_type_t::debug_dump(ostream&out) const { if (signed_flag) out << "signed "; else out << "unsigned "; switch (type_code) { case INTEGER: out << "integer"; break; case TIME: out << "time"; break; case LONGINT: out << "longint"; break; case INT: out << "int"; break; case SHORTINT: out << "shortint"; break; case BYTE: out << "byte"; break; default: assert(0); break; } return out; } void void_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "void" << endl; } void parray_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "Packed array " << "[...]" << " of:" << endl; base_type->pform_dump(out, indent+4); } ostream& real_type_t::debug_dump(ostream&out) const { switch (type_code_) { case REAL: out << "real"; break; case SHORTREAL: out << "shortreal"; break; } return out; } void struct_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked") << " with " << (members.get()==0? 0 : members->size()) << " members" << endl; if (members.get()==0) return; for (list::iterator cur = members->begin() ; cur != members->end() ; ++ cur) { struct_member_t*curp = *cur; curp->pform_dump(out, indent+4); } } void uarray_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "Unpacked array " << "[...]" << " of:" << endl; base_type->pform_dump(out, indent+4); } void vector_type_t::pform_dump(ostream&fd, unsigned indent) const { fd << setw(indent) << "" << "vector of " << base_type; if (pdims.get()) { for (list::iterator cur = pdims->begin() ; cur != pdims->end() ; ++cur) { fd << "["; if (cur->first) fd << *(cur->first); if (cur->second) fd << ":" << *(cur->second); fd << "]"; } } fd << endl; } ostream& vector_type_t::debug_dump(ostream&fd) const { if (signed_flag) fd << "signed "; if (!pdims.get()) { fd << "/* vector_type_t nil */"; return fd; } for (list::iterator cur = pdims->begin() ; cur != pdims->end() ; ++cur) { fd << "["; if (cur->first) fd << *(cur->first); if (cur->second) fd << ":" << *(cur->second); fd << "]"; } return fd; } void class_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "class " << name; if (base_type) out << " extends "; if (! base_args.empty()) { out << " ("; for (list::const_iterator cur = base_args.begin() ; cur != base_args.end() ; ++cur) { const PExpr*curp = *cur; if (cur != base_args.begin()) out << ", "; curp->dump(out); } out << ")"; } out << " {"; for (map::const_iterator cur = properties.begin() ; cur != properties.end() ; ++cur) { out << " " << cur->first; } out << " }" << endl; if (base_type) base_type->pform_dump(out, indent+4); } void class_type_t::pform_dump_init(ostream&out, unsigned indent) const { for (vector::const_iterator cur = initialize.begin() ; cur != initialize.end() ; ++cur) { Statement*curp = *cur; curp->dump(out,indent+4); } } void struct_member_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << (type.get()? typeid(*type).name() : ""); for (list::iterator cur = names->begin() ; cur != names->end() ; ++cur) { decl_assignment_t*curp = *cur; out << " " << curp->name; } out << ";" << endl; } static void dump_attributes_map(ostream&out, const map&attributes, int ind) { for (map::const_iterator idx = attributes.begin() ; idx != attributes.end() ; ++ idx ) { out << setw(ind) << "" << "(* " << (*idx).first; if ((*idx).second) { out << " = " << *(*idx).second; } out << " *)" << endl; } } void PExpr::dump(ostream&out) const { out << typeid(*this).name(); } void PEAssignPattern::dump(ostream&out) const { out << "'{"; if (parms_.size() > 0) { parms_[0]->dump(out); for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { out << ", "; parms_[idx]->dump(out); } } out << "}"; } void PEConcat::dump(ostream&out) const { if (repeat_) out << "{" << *repeat_; if (parms_.empty()) { out << "{}"; return; } out << "{"; if (parms_[0]) out << *parms_[0]; for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { out << ", "; if (parms_[idx]) out << *parms_[idx]; } out << "}"; if (repeat_) out << "}"; } void PECallFunction::dump(ostream &out) const { if (package_) out << package_->pscope_name() << "::"; out << path_ << "("; if (! parms_.empty()) { if (parms_[0]) parms_[0]->dump(out); for (unsigned idx = 1; idx < parms_.size(); ++idx) { out << ", "; if (parms_[idx]) parms_[idx]->dump(out); } } out << ")"; } void PECastSize::dump(ostream &out) const { out << *size_ << "'("; base_->dump(out); out << ")"; } void PECastType::dump(ostream &out) const { target_->pform_dump(out, 0); out << "'("; base_->dump(out); out << ")"; } void PECastSign::dump(ostream &out) const { if (!signed_flag_) out << "un"; out << "signed'("; base_->dump(out); out << ")"; } void PEEvent::dump(ostream&out) const { switch (type_) { case PEEvent::ANYEDGE: break; case PEEvent::POSEDGE: out << "posedge "; break; case PEEvent::NEGEDGE: out << "negedge "; break; case PEEvent::EDGE: out << "edge "; break; case PEEvent::POSITIVE: out << "positive "; break; } out << *expr_; } void PEFNumber::dump(ostream &out) const { out << value(); } void PENewArray::dump(ostream&out) const { out << "new [" << *size_ << "]"; if (init_) out << "(" << *init_ << ")"; } void PENewClass::dump(ostream&out) const { out << "class_new("; if (parms_.size() > 0) { parms_[0]->dump(out); for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { out << ", "; if (parms_[idx]) parms_[idx]->dump(out); } } out << ")"; } void PENewCopy::dump(ostream&out) const { out << "copy_new("; src_->dump(out); out << ")"; } void PENull::dump(ostream&out) const { out << "null"; } void PENumber::dump(ostream&out) const { out << value(); } void PEIdent::dump(ostream&out) const { if (package_) out << package_->pscope_name() << "::"; out << path_; } void PEString::dump(ostream&out) const { out << "\"" << text_ << "\""; } void PETernary::dump(ostream&out) const { out << "(" << *expr_ << ")?(" << *tru_ << "):(" << *fal_ << ")"; } void PETypename::dump(ostream&fd) const { fd << ""; } void PEUnary::dump(ostream&out) const { switch (op_) { case 'm': out << "abs"; break; default: out << op_; break; } out << "(" << *expr_ << ")"; } void PEBinary::dump(ostream&out) const { /* Handle some special cases, where the operators are written in function notation. */ if (op_ == 'm') { out << "min(" << *left_ << "," << *right_ << ")"; return; } if (op_ == 'M') { out << "min(" << *left_ << "," << *right_ << ")"; return; } if (left_) out << "(" << *left_ << ")"; else out << "()"; switch (op_) { case 'a': out << "&&"; break; case 'e': out << "=="; break; case 'E': out << "==="; break; case 'l': out << "<<"; break; case 'L': out << "<="; break; case 'n': out << "!="; break; case 'N': out << "!=="; break; case 'p': out << "**"; break; case 'R': out << ">>>"; break; case 'r': out << ">>"; break; default: out << op_; break; } if (right_) out << "(" << *right_ << ")"; else out << "()"; } void PWire::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << type_; switch (port_type_) { case NetNet::PIMPLICIT: out << " implicit input"; break; case NetNet::PINPUT: out << " input"; break; case NetNet::POUTPUT: out << " output"; break; case NetNet::PINOUT: out << " inout"; break; case NetNet::PREF: out << " ref"; break; case NetNet::NOT_A_PORT: break; } if (signed_) { out << " signed"; } if (is_scalar_) { out << " scalar"; } if (set_data_type_) { out << " set_data_type_=" << *set_data_type_; } if (discipline_) { out << " discipline<" << discipline_->name() << ">"; } if (port_set_) { if (port_.empty()) { out << " port"; } else { out << " port"; for (list::const_iterator cur = port_.begin() ; cur != port_.end() ; ++cur) { out << "["; if (cur->first) out << *cur->first; if (cur->second) out << ":" << *cur->second; out << "]"; } } } if (net_set_) { if (net_.empty()) { out << " net"; } else { out << " net"; for (list::const_iterator cur = net_.begin() ; cur != net_.end() ; ++cur) { out << "["; if (cur->first) out << *cur->first; if (cur->second) out << ":" << *cur->second; out << "]"; } } } out << " " << name_; // If the wire has unpacked indices, dump them. for (list::const_iterator cur = unpacked_.begin() ; cur != unpacked_.end() ; ++cur) { out << "["; if (cur->first) out << *cur->first; if (cur->second) out << ":" << *cur->second; out << "]"; } out << ";" << endl; if (set_data_type_) { set_data_type_->pform_dump(out, 8); } dump_attributes_map(out, attributes, 8); } void PGate::dump_pins(ostream&out) const { if (pin_count()) { if (pin(0)) out << *pin(0); for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) { out << ", "; if (pin(idx)) out << *pin(idx); } } } void PDelays::dump_delays(ostream&out) const { if (delay_[0] && delay_[1] && delay_[2]) out << "#(" << *delay_[0] << "," << *delay_[1] << "," << *delay_[2] << ")"; else if (delay_[0] && delay_[1]) out << "#(" << *delay_[0] << "," << *delay_[1] << ")"; else if (delay_[0]) out << "#" << *delay_[0]; else out << "#0"; } void PGate::dump_delays(ostream&out) const { delay_.dump_delays(out); } void PGate::dump_ranges(ostream&out) const { for (list::iterator cur = ranges_->begin() ; cur != ranges_->end() ; ++cur) { out << "["; if (cur->first) out << *(cur->first); if (cur->second) out << ":" << *(cur->second); out << "]"; } } void PGate::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << typeid(*this).name() << " "; delay_.dump_delays(out); out << " " << get_name() << "("; dump_pins(out); out << ");" << endl; } void PGAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; out << "assign (" << strength0() << "0 " << strength1() << "1) "; dump_delays(out); out << " " << *pin(0) << " = " << *pin(1) << ";" << endl; } void PGBuiltin::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; switch (type()) { case PGBuiltin::BUFIF0: out << "bufif0 "; break; case PGBuiltin::BUFIF1: out << "bufif1 "; break; case PGBuiltin::NOTIF0: out << "notif0 "; break; case PGBuiltin::NOTIF1: out << "notif1 "; break; case PGBuiltin::NAND: out << "nand "; break; case PGBuiltin::NMOS: out << "nmos "; break; case PGBuiltin::RNMOS: out << "rnmos "; break; case PGBuiltin::RPMOS: out << "rpmos "; break; case PGBuiltin::PMOS: out << "pmos "; break; case PGBuiltin::RCMOS: out << "rcmos "; break; case PGBuiltin::CMOS: out << "cmos "; break; default: out << "builtin gate "; } out << "(" << strength0() << "0 " << strength1() << "1) "; dump_delays(out); out << " " << get_name(); dump_ranges(out); out << "("; dump_pins(out); out << ");" << endl; } void PGModule::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << type_ << " "; // If parameters are overridden by order, dump them. if (overrides_ && (! overrides_->empty())) { assert(parms_ == 0); out << "#("; list::const_iterator idx = overrides_->begin(); if (*idx == 0) out << ""; else out << *idx; for ( ; idx != overrides_->end() ; ++ idx) { out << "," << *idx; } out << ") "; } // If parameters are overridden by name, dump them. if (parms_) { assert(overrides_ == 0); out << "#("; for (unsigned idx = 0 ; idx < nparms_ ; idx += 1) { if (idx > 0) out << ", "; out << "." << parms_[idx].name << "("; if (parms_[idx].parm) out << *parms_[idx].parm; out << ")"; } out << ") "; } out << get_name(); dump_ranges(out); out << "("; if (pins_) { out << "." << pins_[0].name << "("; if (pins_[0].parm) out << *pins_[0].parm; out << ")"; for (unsigned idx = 1 ; idx < npins_ ; idx += 1) { out << ", ." << pins_[idx].name << "("; if (pins_[idx].parm) out << *pins_[idx].parm; out << ")"; } } else { dump_pins(out); } out << ");" << endl; dump_attributes_map(out, attributes, 8); } void Statement::dump(ostream&out, unsigned ind) const { /* I give up. I don't know what type this statement is, so just print the C++ typeid and let the user figure it out. */ out << setw(ind) << ""; out << "/* " << get_fileline() << ": " << typeid(*this).name() << " */ ;" << endl; dump_attributes_map(out, attributes, ind+2); } void AContrib::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; out << *lval_ << " <+ " << *rval_ << "; /* " << get_fileline() << " */" << endl; } void PAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; if (lval()) out << *lval(); else out << ""; out << " = "; if (delay_) out << "#" << *delay_ << " "; if (count_) out << "repeat(" << *count_ << ") "; if (event_) out << *event_ << " "; PExpr*rexpr = rval(); if (rexpr) out << *rval() << ";"; else out << ";"; out << " /* " << get_fileline() << " */" << endl; } void PAssignNB::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << *lval() << " <= "; if (delay_) out << "#" << *delay_ << " "; if (count_) out << "repeat(" << *count_ << ") "; if (event_) out << *event_ << " "; out << *rval() << ";" << " /* " << get_fileline() << " */" << endl; } void PBlock::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "begin"; if (pscope_name() != 0) out << " : " << pscope_name(); out << endl; if (pscope_name() != 0) { dump_parameters_(out, ind+2); dump_events_(out, ind+2); dump_wires_(out, ind+2); dump_var_inits_(out, ind+2); } for (unsigned idx = 0 ; idx < list_.size() ; idx += 1) { if (list_[idx]) list_[idx]->dump(out, ind+2); else out << setw(ind+2) << "" << "/* NOOP */ ;" << endl; } out << setw(ind) << "" << "end" << endl; } void PCallTask::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << path_; if (! parms_.empty()) { out << "("; if (parms_[0]) out << *parms_[0]; for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) { out << ", "; if (parms_[idx]) out << *parms_[idx]; } out << ")"; } out << "; /* " << get_fileline() << " */" << endl; } void PCase::dump(ostream&out, unsigned ind) const { out << setw(ind) << ""; switch (quality_) { case IVL_CASE_QUALITY_BASIC: break; case IVL_CASE_QUALITY_UNIQUE: out << "unique "; break; case IVL_CASE_QUALITY_UNIQUE0: out << "unique0 "; break; case IVL_CASE_QUALITY_PRIORITY: out << "priority "; break; } switch (type_) { case NetCase::EQ: out << "case"; break; case NetCase::EQX: out << "casex"; break; case NetCase::EQZ: out << "casez"; break; } out << " (" << *expr_ << ") /* " << get_fileline() << " */" << endl; dump_attributes_map(out, attributes, ind+2); for (unsigned idx = 0 ; idx < items_->size() ; idx += 1) { PCase::Item*cur = (*items_)[idx]; if (cur->expr.empty()) { out << setw(ind+2) << "" << "default:"; } else { list::iterator idx_exp = cur->expr.begin(); out << setw(ind+2) << ""; (*idx_exp)->dump(out); for (++idx_exp ; idx_exp != cur->expr.end() ; ++idx_exp) { out << ", "; (*idx_exp)->dump(out); } out << ":"; } if (cur->stat) { out << endl; cur->stat->dump(out, ind+6); } else { out << " ;" << endl; } } out << setw(ind) << "" << "endcase" << endl; } void PChainConstructor::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "super.new("; if (parms_.size() > 0) { if (parms_[0]) out << *parms_[0]; } for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) { out << ", "; if (parms_[idx]) out << *parms_[idx]; } out << ");" << endl; } void PCondit::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "if (" << *expr_ << ")" << endl; if (if_) if_->dump(out, ind+3); else out << setw(ind) << ";" << endl; if (else_) { out << setw(ind) << "" << "else" << endl; else_->dump(out, ind+3); } } void PCAssign::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "assign " << *lval_ << " = " << *expr_ << "; /* " << get_fileline() << " */" << endl; } void PDeassign::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "deassign " << *lval_ << "; /* " << get_fileline() << " */" << endl; } void PDelayStatement::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "#" << *delay_ << " /* " << get_fileline() << " */"; if (statement_) { out << endl; statement_->dump(out, ind+2); } else { out << " /* noop */;" << endl; } } void PDisable::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "disable "; if (scope_.empty()) out << scope_; else out << "fork"; out << "; /* " << get_fileline() << " */" << endl; } void PDoWhile::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "do" << endl; if (statement_) statement_->dump(out, ind+3); else out << setw(ind+3) << "" << "/* NOOP */" << endl; out << setw(ind) << "" << "while (" << *cond_ << ");" << endl; } void PEventStatement::dump(ostream&out, unsigned ind) const { if (expr_.size() == 0) { out << setw(ind) << "" << "@* "; } else if ((expr_.size() == 1) && (expr_[0] == 0)) { out << setw(ind) << "" << "wait fork "; } else { out << setw(ind) << "" << "@(" << *(expr_[0]); if (expr_.size() > 1) for (unsigned idx = 1 ; idx < expr_.size() ; idx += 1) out << " or " << *(expr_[idx]); out << ")"; } if (statement_) { out << endl; statement_->dump(out, ind+2); } else { out << " ;" << endl; } } void PEventStatement::dump_inline(ostream&out) const { assert(statement_ == 0); if (expr_.size() == 0) { out << "@* "; } else { out << "@(" << *(expr_[0]); if (expr_.size() > 1) for (unsigned idx = 1 ; idx < expr_.size() ; idx += 1) out << " or " << *(expr_[idx]); out << ")"; } } void PForce::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "force " << *lval_ << " = " << *expr_ << "; /* " << get_fileline() << " */" << endl; } void PForeach::dump(ostream&fd, unsigned ind) const { fd << setw(ind) << "" << "foreach " << "variable=" << array_var_ << ", indices=["; for (size_t idx = 0 ; idx < index_vars_.size() ; idx += 1) { if (idx > 0) fd << ","; fd << index_vars_[idx]; } fd << "] /* " << get_fileline() << " */" << endl; if (statement_) statement_->dump(fd, ind+3); else fd << setw(ind+3) << "" << "/* NOOP */" << endl; } void PForever::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "forever /* " << get_fileline() << " */" << endl; if (statement_) statement_->dump(out, ind+3); else out << setw(ind+3) << "" << "/* NOOP */" << endl; } void PForStatement::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "for ("; if (name1_) out << *name1_; else out << ""; out << " = "; if (expr1_) out << *expr1_; else out << ""; out << "; "; if (cond_) out << *cond_; else out << ""; out << "; )" << endl; if (step_) step_->dump(out, ind+6); else out << setw(ind+6) << "" << "" << endl; if (statement_) statement_->dump(out, ind+3); else out << setw(ind+3) << "" << "/* NOOP */" << endl; } void PFunction::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "function "; if (is_auto_) out << "automatic "; out << pscope_name() << ";" << endl; if (method_of()) out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl; if (return_type_) return_type_->pform_dump(out, ind+8); else out << setw(ind+8) << "" << "" << endl; dump_ports_(out, ind+2); dump_parameters_(out, ind+2); dump_events_(out, ind+2); dump_wires_(out, ind+2); dump_var_inits_(out, ind+2); if (statement_) statement_->dump(out, ind+2); else out << setw(ind+2) << "" << "/* NOOP */" << endl; } void PLet::let_port_t::dump(ostream&out, unsigned) const { if (type_) out << *type_ << " "; out << name_; // FIXME: This has not been tested and is likely wrong! if (range_) out << " " << range_; if (def_) out << "=" << *def_; } void PLet::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "let "; out << pscope_name(); if (ports_) { out << "("; typedef std::list::const_iterator port_itr_t; port_itr_t idx = ports_->begin(); (*idx)->dump(out, 0); for (++idx; idx != ports_->end(); ++idx ) { out << ", "; (*idx)->dump(out, 0); } out << ")"; } out << " = " << *expr_ << ";" << endl; } void PRelease::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "release " << *lval_ << "; /* " << get_fileline() << " */" << endl; } void PRepeat::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "repeat (" << *expr_ << ")" << endl; if (statement_) statement_->dump(out, ind+3); else out << setw(ind+3) << "" << "/* NOOP */" << endl; } void PReturn::dump(ostream&fd, unsigned ind) const { fd << setw(ind) << "" << "return ("; if (expr_) fd << *expr_; fd << ")" << endl; } void PTask::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "task "; if (is_auto_) out << "automatic "; out << pscope_name() << ";" << endl; if (method_of()) out << setw(ind) << "" << "method of " << method_of()->name << ";" << endl; dump_ports_(out, ind+2); dump_parameters_(out, ind+2); dump_events_(out, ind+2); dump_wires_(out, ind+2); dump_var_inits_(out, ind+2); if (statement_) statement_->dump(out, ind+2); else out << setw(ind+2) << "" << "/* NOOP */" << endl; } void PTaskFunc::dump_ports_(std::ostream&out, unsigned ind) const { if (ports_ == 0) return; for (unsigned idx = 0 ; idx < ports_->size() ; idx += 1) { if (ports_->at(idx).port == 0) { out << setw(ind) << "" << "ERROR PORT" << endl; continue; } out << setw(ind) << ""; switch (ports_->at(idx).port->get_port_type()) { case NetNet::PINPUT: out << "input "; break; case NetNet::POUTPUT: out << "output "; break; case NetNet::PINOUT: out << "inout "; break; case NetNet::PIMPLICIT: out << "PIMPLICIT"; break; case NetNet::NOT_A_PORT: out << "NOT_A_PORT"; break; default: assert(0); break; } out << ports_->at(idx).port->basename(); if (ports_->at(idx).defe) { out << " = " << *ports_->at(idx).defe; } out << ";" << endl; } } void PTrigger::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "-> " << event_ << ";" << endl; } void PNBTrigger::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "->> "; if (dly_) out << "#" << *dly_ << " "; out << event_ << ";" << endl; } void PWhile::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << "while (" << *cond_ << ")" << endl; if (statement_) statement_->dump(out, ind+3); else out << setw(ind+3) << "" << "/* NOOP */" << endl; } void PProcess::dump(ostream&out, unsigned ind) const { out << setw(ind) << "" << type_ << " /* " << get_fileline() << " */" << endl; dump_attributes_map(out, attributes, ind+2); if (statement_) statement_->dump(out, ind+2); else out << setw(ind+2) << "" << "/* NOOP */" << endl; } void AProcess::dump(ostream&out, unsigned ind) const { switch (type_) { case IVL_PR_INITIAL: out << setw(ind) << "" << "analog initial"; break; case IVL_PR_ALWAYS: out << setw(ind) << "" << "analog"; break; case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: assert(0); break; case IVL_PR_FINAL: out << setw(ind) << "" << "analog final"; break; } out << " /* " << get_fileline() << " */" << endl; dump_attributes_map(out, attributes, ind+2); if (statement_) statement_->dump(out, ind+2); else out << setw(ind+2) << "" << "/* NOOP */" << endl; } void PSpecPath::dump(std::ostream&out, unsigned ind) const { out << setw(ind) << "" << "specify path "; if (condition) out << "if (" << *condition << ") "; out << "("; if (edge) { if (edge > 0) out << "posedge "; else out << "negedge "; } for (unsigned idx = 0 ; idx < src.size() ; idx += 1) { if (idx > 0) out << ", "; assert(src[idx]); out << src[idx]; } out << " "; if (polarity_) out << polarity_; if (full_flag_) out << "*> "; else out << "=> "; if (data_source_expression) out << "("; for (unsigned idx = 0 ; idx < dst.size() ; idx += 1) { if (idx > 0) out << ", "; assert(dst[idx]); out << dst[idx]; } if (data_source_expression) out << " : " << *data_source_expression << ")"; out << ") = ("; for (unsigned idx = 0 ; idx < delays.size() ; idx += 1) { if (idx > 0) out << ", "; assert(delays[idx]); out << *delays[idx]; } out << ");" << endl; } void PGenerate::dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "generate(" << id_number << ")"; PGenerate*parent = dynamic_cast(parent_scope()); switch (scheme_type) { case GS_NONE: break; case GS_LOOP: out << " for (" << loop_index << "=" << *loop_init << "; " << *loop_test << "; " << loop_index << "=" << *loop_step << ")"; break; case GS_CONDIT: out << " if (" << *loop_test << ")"; break; case GS_ELSE: out << " else !(" << *loop_test << ")"; break; case GS_CASE: out << " case (" << *loop_test << ")"; break; case GS_CASE_ITEM: assert(parent); if (loop_test) out << " (" << *loop_test << ") == (" << *parent->loop_test << ")"; else out << " default:"; break; case GS_NBLOCK: out << " begin"; } if (scope_name) out << " : " << scope_name; out << endl; dump_parameters_(out, indent+2); typedef list::const_iterator parm_hiter_t; for (parm_hiter_t cur = defparms.begin() ; cur != defparms.end() ; ++ cur ) { out << setw(indent+2) << "" << "defparam " << (*cur).first << " = "; if ((*cur).second) out << *(*cur).second << ";" << endl; else out << "/* ERROR */;" << endl; } dump_events_(out, indent+2); dump_wires_(out, indent+2); for (list::const_iterator idx = gates.begin() ; idx != gates.end() ; ++ idx ) { (*idx)->dump(out, indent+2); } dump_var_inits_(out, indent+2); for (list::const_iterator idx = behaviors.begin() ; idx != behaviors.end() ; ++ idx ) { (*idx)->dump(out, indent+2); } for (list::const_iterator idx = analog_behaviors.begin() ; idx != analog_behaviors.end() ; ++ idx ) { (*idx)->dump(out, indent+2); } for (list::const_iterator idx = elab_tasks.begin() ; idx != elab_tasks.end() ; ++ idx ) { (*idx)->dump(out, indent+2); } typedef map::const_iterator genvar_iter_t; for (genvar_iter_t cur = genvars.begin() ; cur != genvars.end() ; ++ cur ) { out << setw(indent+2) << "" << "genvar " << ((*cur).first) << ";" << endl; } for (list::const_iterator idx = generate_schemes.begin() ; idx != generate_schemes.end() ; ++ idx ) { (*idx)->dump(out, indent+2); } if (scheme_type == GS_NBLOCK) { out << setw(indent) << "" << "end endgenerate" << endl; } else { out << setw(indent) << "" << "endgenerate" << endl; } } void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const { typedef typedef_map_t::const_iterator iter_t; for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) { out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl; cur->second->get_data_type()->pform_dump(out, indent+4); } } void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const { typedef map::const_iterator parm_iter_t; for (parm_iter_t cur = parameters.begin() ; cur != parameters.end() ; ++ cur ) { out << setw(indent) << ""; if (cur->second->local_flag) out << "localparam "; else out << "parameter "; if (cur->second->data_type) cur->second->data_type->debug_dump(out); else out << "(nil type)"; if ((*cur).second->expr) out << " " << (*cur).first << " = " << *(*cur).second->expr; for (LexicalScope::range_t*tmp = (*cur).second->range ; tmp ; tmp = tmp->next) { if (tmp->exclude_flag) out << " exclude "; else out << " from "; if (tmp->low_open_flag) out << "("; else out << "["; if (tmp->low_expr) out << *(tmp->low_expr); else if (tmp->low_open_flag==false) out << "-inf"; else out << ""; out << ":"; if (tmp->high_expr) out << *(tmp->high_expr); else if (tmp->high_open_flag==false) out << "inf"; else out << ""; if (tmp->high_open_flag) out << ")"; else out << "]"; } out << ";" << endl; } } void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const { for (vector::const_iterator cur = enum_sets.begin() ; cur != enum_sets.end() ; ++ cur) { out << setw(indent) << "" << "enum {" << endl; for (list::const_iterator idx = (*cur)->names->begin() ; idx != (*cur)->names->end() ; ++ idx) { out << setw(indent+4) << "" << idx->name << " = " << idx->parm << endl; } out << setw(indent) << "" << "}" << endl; } } void LexicalScope::dump_events_(ostream&out, unsigned indent) const { for (map::const_iterator cur = events.begin() ; cur != events.end() ; ++ cur ) { PEvent*ev = (*cur).second; out << setw(indent) << "" << "event " << ev->name() << "; // " << ev->get_fileline() << endl; } } void LexicalScope::dump_wires_(ostream&out, unsigned indent) const { // Iterate through and display all the wires. for (map::const_iterator wire = wires.begin() ; wire != wires.end() ; ++ wire ) { (*wire).second->dump(out, indent); } } void LexicalScope::dump_var_inits_(ostream&out, unsigned indent) const { // Iterate through and display all the register initializations. for (unsigned idx = 0; idx < var_inits.size(); idx += 1) { var_inits[idx]->dump(out, indent); } } void PScopeExtra::dump_classes_(ostream&out, unsigned indent) const { // Dump the task definitions. typedef map::const_iterator class_iter_t; for (class_iter_t cur = classes.begin() ; cur != classes.end() ; ++ cur ) { cur->second->dump(out, indent); } } void PScopeExtra::dump_tasks_(ostream&out, unsigned indent) const { // Dump the task definitions. typedef map::const_iterator task_iter_t; for (task_iter_t cur = tasks.begin() ; cur != tasks.end() ; ++ cur ) { out << setw(indent) << "" << "task " << (*cur).first << ";" << endl; (*cur).second->dump(out, indent+2); out << setw(indent) << "" << "endtask;" << endl; } } void PScopeExtra::dump_funcs_(ostream&out, unsigned indent) const { // Dump the task definitions. typedef map::const_iterator task_iter_t; for (task_iter_t cur = funcs.begin() ; cur != funcs.end() ; ++ cur ) { out << setw(indent) << "" << "function " << (*cur).first << ";" << endl; (*cur).second->dump(out, indent+2); out << setw(indent) << "" << "endfunction;" << endl; } } void PClass::dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "class " << type->name << ";" << endl; type->pform_dump(out, indent+2); type->pform_dump_init(out, indent+2); dump_tasks_(out, indent+2); dump_funcs_(out, indent+2); out << setw(indent) << "" << "endclass" << endl; } void Module::dump_specparams_(ostream&out, unsigned indent) const { typedef map::const_iterator parm_iter_t; for (parm_iter_t cur = specparams.begin() ; cur != specparams.end() ; ++ cur ) { out << setw(indent) << "" << "specparam "; if (cur->second->data_type) cur->second->data_type->debug_dump(out); else out << "(nil type)"; out << (*cur).first << " = "; if ((*cur).second->expr) out << *(*cur).second->expr << ";" << endl; else out << "/* ERROR */;" << endl; } } void Module::dump(ostream&out) const { if (attributes.begin() != attributes.end()) { out << "(* "; for (map::const_iterator idx = attributes.begin() ; idx != attributes.end() ; ++ idx ) { if (idx != attributes.begin()) { out << " , "; } out << (*idx).first; if ((*idx).second) { out << " = " << *(*idx).second; } } out << " *) "; } out << "module " << mod_name() << ";"; if (is_cell) out << " // Is in `celldefine."; out << endl; for (unsigned idx = 0 ; idx < ports.size() ; idx += 1) { port_t*cur = ports[idx]; if (cur == 0) { out << " unconnected" << endl; continue; } out << " ." << cur->name << "(" << *cur->expr[0]; for (unsigned wdx = 1 ; wdx < cur->expr.size() ; wdx += 1) { out << ", " << *cur->expr[wdx]; } out << ")" << endl; } for (map::const_iterator cur = nested_modules.begin() ; cur != nested_modules.end() ; ++cur) { out << setw(4) << "" << "Nested module " << cur->first << ";" << endl; } dump_typedefs_(out, 4); dump_parameters_(out, 4); dump_specparams_(out, 4); dump_enumerations_(out, 4); dump_classes_(out, 4); typedef map::const_iterator genvar_iter_t; for (genvar_iter_t cur = genvars.begin() ; cur != genvars.end() ; ++ cur ) { out << " genvar " << ((*cur).first) << ";" << endl; } typedef list::const_iterator genscheme_iter_t; for (genscheme_iter_t cur = generate_schemes.begin() ; cur != generate_schemes.end() ; ++ cur ) { (*cur)->dump(out, 4); } typedef list::const_iterator parm_hiter_t; for (parm_hiter_t cur = defparms.begin() ; cur != defparms.end() ; ++ cur ) { out << " defparam " << (*cur).first << " = "; if ((*cur).second) out << *(*cur).second << ";" << endl; else out << "/* ERROR */;" << endl; } dump_events_(out, 4); // Iterate through and display all the wires. dump_wires_(out, 4); // Dump the task definitions. dump_tasks_(out, 4); // Dump the function definitions. dump_funcs_(out, 4); // Iterate through and display all the gates for (list::const_iterator gate = gates_.begin() ; gate != gates_.end() ; ++ gate ) { (*gate)->dump(out); } dump_var_inits_(out, 4); for (list::const_iterator behav = behaviors.begin() ; behav != behaviors.end() ; ++ behav ) { (*behav)->dump(out, 4); } for (list::const_iterator idx = analog_behaviors.begin() ; idx != analog_behaviors.end() ; ++ idx) { (*idx)->dump(out, 4); } for (list::const_iterator idx = elab_tasks.begin() ; idx != elab_tasks.end() ; ++ idx ) { (*idx)->dump(out, 4); } for (list::const_iterator spec = specify_paths.begin() ; spec != specify_paths.end() ; ++ spec ) { (*spec)->dump(out, 4); } out << "endmodule" << endl; } void pform_dump(ostream&out, Module*mod) { mod->dump(out); } void PUdp::dump(ostream&out) const { out << "primitive " << name_ << "(" << ports[0]; for (unsigned idx = 1 ; idx < ports.size() ; idx += 1) out << ", " << ports[idx]; out << ");" << endl; if (sequential) out << " reg " << ports[0] << ";" << endl; out << " table" << endl; for (unsigned idx = 0 ; idx < tinput.size() ; idx += 1) { out << " "; for (unsigned chr = 0 ; chr < tinput[idx].length() ; chr += 1) out << " " << tinput[idx][chr]; if (sequential) out << " : " << tcurrent[idx]; out << " : " << toutput[idx] << " ;" << endl; } out << " endtable" << endl; if (sequential) out << " initial " << ports[0] << " = 1'b" << initial << ";" << endl; // Dump the attributes for the primitive as attribute // statements. for (map::const_iterator idx = attributes.begin() ; idx != attributes.end() ; ++ idx ) { out << " attribute " << (*idx).first; if ((*idx).second) out << " = " << *(*idx).second; out << endl; } out << "endprimitive" << endl; } void pform_dump(std::ostream&out, const ivl_nature_s*nat) { out << "nature " << nat->name() << endl; out << " access " << nat->access() << ";" << endl; out << "endnature" << endl; } void pform_dump(std::ostream&out, const ivl_discipline_s*dis) { out << "discipline " << dis->name() << endl; out << " domain " << dis->domain() << ";" << endl; if (const ivl_nature_s*tmp = dis->potential()) out << " potential " << tmp->name() << ";" << endl; if (const ivl_nature_s*tmp = dis->flow()) out << " flow " << tmp->name() << ";" << endl; out << "enddiscipline" << endl; } void pform_dump(std::ostream&fd, const PClass*cl) { cl->dump(fd, 0); } void pform_dump(std::ostream&out, const PPackage*pac) { pac->pform_dump(out); } void PPackage::pform_dump(std::ostream&out) const { out << "package " << pscope_name() << endl; dump_parameters_(out, 4); dump_typedefs_(out, 4); dump_enumerations_(out, 4); dump_wires_(out, 4); dump_tasks_(out, 4); dump_funcs_(out, 4); dump_var_inits_(out, 4); out << "endpackage" << endl; } void pform_dump(std::ostream&fd, const PTaskFunc*obj) { obj->dump(fd, 0); } iverilog-12_0/pform_package.cc000066400000000000000000000126711435245347300164630ustar00rootroot00000000000000/* * Copyright (c) 2012-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 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 "pform.h" # include "PPackage.h" # include "parse_misc.h" # include "parse_api.h" # include # include # include "ivl_assert.h" using namespace std; /* * This is a list of packages in the order that they were defined. */ vector pform_packages; /* * This allows us to easily check for name collisions. */ static map packages_by_name; static PPackage*pform_cur_package = 0; void pform_start_package_declaration(const struct vlltype&loc, const char*name, LexicalScope::lifetime_t lifetime) { ivl_assert(loc, pform_cur_package == 0); perm_string use_name = lex_strings.make(name); PPackage*pkg_scope = pform_push_package_scope(loc, use_name, lifetime); FILE_NAME(pkg_scope, loc); pform_cur_package = pkg_scope; } void pform_end_package_declaration(const struct vlltype&loc) { ivl_assert(loc, pform_cur_package); perm_string use_name = pform_cur_package->pscope_name(); map::const_iterator test = packages_by_name.find(use_name); if (test != packages_by_name.end()) { ostringstream msg; msg << "error: Package " << use_name << " was already declared here: " << test->second->get_fileline() << ends; VLerror(loc, msg.str().c_str()); } packages_by_name[use_name] = pform_cur_package; pform_packages.push_back(pform_cur_package); pform_cur_package = 0; pform_pop_scope(); } /* * Do the import early, during processing. This requires that the * package is declared in pform ahead of time (it is) and that we can * simply transfer definitions to the current scope (we can). */ void pform_package_import(const struct vlltype&loc, PPackage*pkg, const char*ident) { LexicalScope*scope = pform_peek_scope(); if (ident) { perm_string use_ident = lex_strings.make(ident); // Check that the requested symbol is available. map::const_iterator cur_sym = pkg->local_symbols.find(use_ident); if (cur_sym == pkg->local_symbols.end()) { cerr << loc.get_fileline() << ": error: " "'" << use_ident << "' is not exported by '" << pkg->pscope_name() << "'." << endl; error_count += 1; return; } // Check for conflict with local symbol. cur_sym = scope->local_symbols.find(use_ident); if (cur_sym != scope->local_symbols.end()) { cerr << loc.get_fileline() << ": error: " "'" << use_ident << "' has already been declared " "in this scope." << endl; cerr << cur_sym->second->get_fileline() << ": : " "It was declared here as " << cur_sym->second->symbol_type() << "." << endl; error_count += 1; return; } // Check for conflict with previous import. map::const_iterator cur_pkg = scope->explicit_imports.find(use_ident); if (cur_pkg != scope->explicit_imports.end()) { if (cur_pkg->second != pkg) { cerr << loc.get_fileline() << ": error: " "'" << use_ident << "' has already been " "imported into this scope from package '" << cur_pkg->second->pscope_name() << "'." << endl; error_count += 1; } return; } scope->explicit_imports[use_ident] = pkg; } else { list::const_iterator cur_pkg = find(scope->potential_imports.begin(), scope->potential_imports.end(), pkg); if (cur_pkg == scope->potential_imports.end()) scope->potential_imports.push_back(pkg); } } PExpr* pform_package_ident(const struct vlltype&loc, PPackage*pkg, pform_name_t*ident_name) { assert(ident_name); PEIdent*tmp = new PEIdent(pkg, *ident_name); FILE_NAME(tmp, loc); return tmp; } typedef_t* pform_test_type_identifier(PPackage*pkg, const char*txt) { perm_string use_name = lex_strings.make(txt); LexicalScope::typedef_map_t::const_iterator cur; cur = pkg->typedefs.find(use_name); if (cur != pkg->typedefs.end()) return cur->second; return 0; } /* * The lexor uses this function to know if the identifier names the * package. It will call this a PACKAGE_IDENTIFIER token in that case, * instead of a generic IDENTIFIER. */ PPackage* pform_test_package_identifier(const char*pkg_name) { perm_string use_name = lex_strings.make(pkg_name); map::const_iterator pcur = packages_by_name.find(use_name); if (pcur == packages_by_name.end()) return 0; assert(pcur->second); return pcur->second; } iverilog-12_0/pform_pclass.cc000066400000000000000000000123161435245347300163510ustar00rootroot00000000000000/* * Copyright (c) 2012-2021 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 "pform.h" # include "PClass.h" # include "parse_misc.h" using namespace std; /* * The functions here help the parser put together class type declarations. */ static PClass*pform_cur_class = 0; /* * The base_type is set to the base class if this declaration is * starting a derived class. For example, for the syntax: * * class foo extends bar (exprs) ... * * the base_type is the type of the class "bar", and the base_exprs, * if present, are the "exprs" that would be passed to a chained * constructor. */ void pform_start_class_declaration(const struct vlltype&loc, class_type_t*type, data_type_t*base_type, list*base_exprs, bool virtual_class) { PClass*class_scope = pform_push_class_scope(loc, type->name); class_scope->type = type; assert(pform_cur_class == 0); pform_cur_class = class_scope; assert(type->base_type == 0); type->base_type.reset(base_type); type->virtual_class = virtual_class; assert(type->base_args.empty()); if (base_exprs) { for (list::iterator cur = base_exprs->begin() ; cur != base_exprs->end() ; ++ cur) { type->base_args.push_back(*cur); } delete base_exprs; } } void pform_class_property(const struct vlltype&loc, property_qualifier_t property_qual, data_type_t*data_type, list*decls) { assert(pform_cur_class); // Add the non-static properties to the class type // object. Unwind the list of names to make a map of name to // type. for (list::iterator cur = decls->begin() ; cur != decls->end() ; ++cur) { decl_assignment_t*curp = *cur; data_type_t*use_type = data_type; if (! curp->index.empty()) { list*pd = new list (curp->index); use_type = new uarray_type_t(use_type, pd); FILE_NAME(use_type, loc); } pform_cur_class->type->properties[curp->name] = class_type_t::prop_info_t(property_qual,use_type); FILE_NAME(&pform_cur_class->type->properties[curp->name], loc); if (PExpr*rval = curp->expr.release()) { PExpr*lval = new PEIdent(curp->name); FILE_NAME(lval, loc); PAssign*tmp = new PAssign(lval, rval); FILE_NAME(tmp, loc); if (property_qual.test_static()) pform_cur_class->type->initialize_static.push_back(tmp); else pform_cur_class->type->initialize.push_back(tmp); } } } void pform_set_this_class(const struct vlltype&loc, PTaskFunc*net) { if (pform_cur_class == 0) return; list*this_name = new list; this_name->push_back(pform_port_t(perm_string::literal(THIS_TOKEN), 0, 0)); vector*this_port = pform_make_task_ports(loc, NetNet::PINPUT, pform_cur_class->type, this_name); // The pform_make_task_ports() function deletes the this_name // object. assert(this_port->at(0).defe == 0); PWire*this_wire = this_port->at(0).port; delete this_port; net->set_this(pform_cur_class->type, this_wire); } void pform_set_constructor_return(PFunction*net) { assert(pform_cur_class); net->set_return(pform_cur_class->type); } /* * A constructor is basically a function with special implications. */ PFunction*pform_push_constructor_scope(const struct vlltype&loc) { assert(pform_cur_class); PFunction*func = pform_push_function_scope(loc, "new", LexicalScope::AUTOMATIC); return func; } void pform_end_class_declaration(const struct vlltype&loc) { assert(pform_cur_class); // If there were initializer statements, then collect them // into an implicit constructor function. if (! pform_cur_class->type->initialize.empty()) { PFunction*func = pform_push_function_scope(loc, "new@", LexicalScope::AUTOMATIC); func->set_ports(0); pform_set_constructor_return(func); pform_set_this_class(loc, func); class_type_t*use_class = pform_cur_class->type; if (use_class->initialize.size() == 1) { func->set_statement(use_class->initialize.front()); } else { PBlock*tmp = new PBlock(PBlock::BL_SEQ); tmp->set_statement(use_class->initialize); func->set_statement(tmp); } pform_pop_scope(); } pform_cur_class = 0; pform_pop_scope(); } bool pform_in_class() { return pform_cur_class != 0; } iverilog-12_0/pform_types.cc000066400000000000000000000036461435245347300162360ustar00rootroot00000000000000/* * Copyright (c) 2007-2019 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 "pform_types.h" data_type_t::~data_type_t() { } PNamedItem::SymbolType data_type_t::symbol_type() const { return TYPE; } string_type_t::~string_type_t() { } atom_type_t size_type (atom_type_t::INT, true); PNamedItem::SymbolType enum_type_t::symbol_type() const { return ENUM; } PNamedItem::SymbolType class_type_t::symbol_type() const { return CLASS; } bool typedef_t::set_data_type(data_type_t *t) { if (data_type.get()) return false; data_type.reset(t); return true; } bool typedef_t::set_basic_type(enum basic_type bt) { if (bt == ANY) return true; if (basic_type != ANY && bt != basic_type) return false; basic_type = bt; return true; } std::ostream& operator<< (std::ostream&out, enum typedef_t::basic_type bt) { switch (bt) { case typedef_t::ANY: out << "any"; break; case typedef_t::ENUM: out << "enum"; break; case typedef_t::STRUCT: out << "struct"; break; case typedef_t::UNION: out << "union"; break; case typedef_t::CLASS: out << "class"; break; } return out; } iverilog-12_0/pform_types.h000066400000000000000000000343721435245347300161000ustar00rootroot00000000000000#ifndef IVL_pform_types_H #define IVL_pform_types_H /* * Copyright (c) 2007-2021 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. */ // This for the perm_string type. # include "StringHeap.h" # include "PNamedItem.h" # include "verinum.h" # include "named.h" # include "netstruct.h" # include "property_qual.h" # include "ivl_target.h" # include # include # include # include # include /* * parse-form types. */ class Design; class NetScope; class Definitions; class PExpr; class PScope; class PWire; class Statement; class netclass_t; class netenum_t; typedef named named_number_t; typedef named named_pexpr_t; /* * The pform_range_t holds variable dimensions for type * declarations. The two expressions are interpreted as the first and * last values of the range. For example: * * [ : ] -- Normal array range * first == * second = * * [] -- SystemVerilog canonical range * first = PENumber(0) * second = - 1; * * [ ] -- Dynamic array * first = 0 * second = 0 * * [ $ ] -- Queue type * first = PENull * second = 0 */ typedef std::pair pform_range_t; /* The lgate is gate instantiation information. */ struct lgate : public LineInfo { explicit lgate() : parms(0), parms_by_name(0), ranges(0) { } std::string name; std::list*parms; std::list*parms_by_name; std::list*ranges; }; /* * The pform_port_t holds the name and optional unpacked dimensions * and initialization expression for a single port in a list of port * declarations. */ struct pform_port_t { pform_port_t(perm_string n, std::list*ud, PExpr*e) : name(n), udims(ud), expr(e) { } ~pform_port_t() { } perm_string name; std::list*udims; PExpr*expr; }; /* * Semantic NOTES: * - The SEL_BIT is a single expression. This might me a bit select * of a vector, or a word select of an array. * * - The SEL_BIT_LAST index component is an array/queue [$] index, * that is the last item in the variable. */ struct index_component_t { enum ctype_t { SEL_NONE, SEL_BIT, SEL_BIT_LAST, SEL_PART, SEL_IDX_UP, SEL_IDX_DO }; index_component_t() : sel(SEL_NONE), msb(0), lsb(0) { }; ~index_component_t() { } ctype_t sel; class PExpr*msb; class PExpr*lsb; }; struct name_component_t { inline name_component_t() { } inline explicit name_component_t(perm_string n) : name(n) { } ~name_component_t() { } // Return true if this component is nil. inline bool empty() const { return name.nil(); } perm_string name; std::listindex; }; struct decl_assignment_t { perm_string name; std::listindex; std::unique_ptr expr; }; struct pform_tf_port_t { PWire*port; PExpr*defe; inline pform_tf_port_t() : port(0), defe(0) { } inline explicit pform_tf_port_t(PWire*p) : port(p), defe(0) { } }; /* * This is the base class for data types that are matched by the * "data_type" rule in the parse rule. We make the type virtual so * that dynamic types will work. */ class data_type_t : public PNamedItem { public: inline explicit data_type_t() { } virtual ~data_type_t() = 0; // This method is used by the pform dumper to diagnostic dump. The // pform_dump dumps type type in pform format, and the debug_dump // prints the output in a linear form. virtual void pform_dump(std::ostream&out, unsigned indent) const; virtual std::ostream& debug_dump(std::ostream&out) const; ivl_type_t elaborate_type(Design*des, NetScope*scope); virtual SymbolType symbol_type() const; private: // Elaborate the type to an ivl_type_s type. virtual ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; virtual NetScope *find_scope(Design* des, NetScope *scope) const; bool elaborating = false; // Keep per-scope elaboration results cached. std::map cache_type_elaborate_; }; struct typedef_t : public PNamedItem { explicit typedef_t(perm_string n) : basic_type(ANY), name(n) { }; ivl_type_t elaborate_type(Design*des, NetScope*scope); enum basic_type { ANY, ENUM, STRUCT, UNION, CLASS }; bool set_data_type(data_type_t *t); const data_type_t *get_data_type() const { return data_type.get(); } bool set_basic_type(basic_type bt); enum basic_type get_basic_type() const { return basic_type; } protected: enum basic_type basic_type; std::unique_ptr data_type; public: perm_string name; }; struct typeref_t : public data_type_t { explicit typeref_t(typedef_t *t, PScope *s = 0) : scope(s), type(t) {} ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; NetScope *find_scope(Design* des, NetScope *scope) const; std::ostream& debug_dump(std::ostream&out) const; private: PScope *scope; typedef_t *type; }; struct type_parameter_t : data_type_t { explicit type_parameter_t(perm_string n) : name(n) { } ivl_type_t elaborate_type_raw(Design *des, NetScope *scope) const; perm_string name; }; struct void_type_t : public data_type_t { virtual void pform_dump(std::ostream&out, unsigned indent) const; }; /* * The enum_type_t holds the parsed declaration to represent an * enumeration. Since this is in the pform, it represents the type * before elaboration so the range, for example, may not be complete * until it is elaborated in a scope. */ struct enum_type_t : public data_type_t { explicit enum_type_t(data_type_t *btype) : base_type(btype) { } // Return the elaborated version of the type. ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; SymbolType symbol_type() const; std::unique_ptr base_type; std::unique_ptr< std::list > names; }; struct struct_member_t : public LineInfo { std::unique_ptr type; std::unique_ptr< std::list > names; void pform_dump(std::ostream&out, unsigned indent) const; }; struct struct_type_t : public data_type_t { virtual void pform_dump(std::ostream&out, unsigned indent) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; bool packed_flag; bool union_flag; bool signed_flag; std::unique_ptr< std::list > members; }; struct atom_type_t : public data_type_t { enum type_code { INTEGER, TIME, BYTE, SHORTINT, INT, LONGINT }; explicit atom_type_t(enum type_code tc, bool flag) : type_code(tc), signed_flag(flag) { } enum type_code type_code; bool signed_flag; virtual std::ostream& debug_dump(std::ostream&out) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; }; extern atom_type_t size_type; /* * The vector_type_t class represents types in the old Verilog * way. Some typical examples: * * logic signed [7:0] foo * bit unsigned foo * reg foo * * There is one special case: * * If there are no reg/logic/bit/bool keywords, then Verilog will * assume the type is logic, but the context may need to know about * this case, so the implicit_flag member is set to true in that case. */ struct vector_type_t : public data_type_t { inline explicit vector_type_t(ivl_variable_type_t bt, bool sf, std::list*pd) : base_type(bt), signed_flag(sf), integer_flag(false), implicit_flag(false), pdims(pd) { } virtual void pform_dump(std::ostream&out, unsigned indent) const; virtual std::ostream& debug_dump(std::ostream&out) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; ivl_variable_type_t base_type; bool signed_flag; bool integer_flag; // True if "integer" was used bool implicit_flag; // True if this type is implicitly logic/reg std::unique_ptr< std::list > pdims; }; struct array_base_t : public data_type_t { public: inline explicit array_base_t(data_type_t*btype, std::list*pd) : base_type(btype), dims(pd) { } std::unique_ptr base_type; std::unique_ptr< std::list > dims; }; /* * The parray_type_t is a generalization of the vector_type_t in that * the base type is another general data type. Ultimately, the subtype * must also be packed (as this is a packed array) but that may be * worked out during elaboration. */ struct parray_type_t : public array_base_t { inline explicit parray_type_t(data_type_t*btype, std::list*pd) : array_base_t(btype, pd) { } virtual void pform_dump(std::ostream&out, unsigned indent) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; }; /* * The uarray_type_t represents unpacked array types. */ struct uarray_type_t : public array_base_t { inline explicit uarray_type_t(data_type_t*btype, std::list*pd) : array_base_t(btype, pd) { } public: virtual void pform_dump(std::ostream&out, unsigned indent) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; }; struct real_type_t : public data_type_t { public: enum type_t { REAL, SHORTREAL }; inline explicit real_type_t(type_t tc) : type_code_(tc) { } virtual std::ostream& debug_dump(std::ostream&out) const; ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; inline type_t type_code() const { return type_code_; } private: type_t type_code_; }; struct string_type_t : public data_type_t { inline explicit string_type_t() { } ~string_type_t(); ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const; }; struct class_type_t : public data_type_t { inline explicit class_type_t(perm_string n) : name(n) { } void pform_dump(std::ostream&out, unsigned indent) const; void pform_dump_init(std::ostream&out, unsigned indent) const; // This is the named type that is supposed to be the base // class that we are extending. This is nil if there is no // hierarchy. If there are arguments to the base class, then // put them in the base_args vector. std::unique_ptr base_type; std::listbase_args; bool virtual_class; // This is a map of the properties. Map the name to the type. struct prop_info_t : public LineInfo { inline prop_info_t() : qual(property_qualifier_t::make_none()) { } inline prop_info_t(property_qualifier_t q, data_type_t*t) : qual(q), type(t) { } prop_info_t(prop_info_t&&) = default; prop_info_t& operator=(prop_info_t&&) = default; property_qualifier_t qual; std::unique_ptr type; }; std::map properties; // This is an ordered list of property initializers. The name // is the name of the property to be assigned, and the val is // the expression that is assigned. std::vector initialize; // This is an ordered list of property initializers for static // properties. These are run in a synthetic "initial" block // without waiting for any constructor. std::vector initialize_static; ivl_type_t elaborate_type_raw(Design*, NetScope*) const; perm_string name; virtual SymbolType symbol_type() const; }; ivl_type_t elaborate_array_type(Design *des, NetScope *scope, const LineInfo &li, ivl_type_t base_type, const std::list &dims); /* * The pform_name_t is the general form for a hierarchical * identifier. It is an ordered list of name components. Each name * component is an identifier and an optional list of bit/part * selects. The simplest name component is a simple identifier: * * foo * * The bit/part selects come from the source and are made part of the * name component. A bit select is a single number that may be a bit * select of a vector or a word select of an array: * * foo[5] -- a bit select/word index * foo[6:4] -- a part select * * The index components of a name component are collected into an * ordered list, so there may be many, for example: * * foo[5][6:4] -- a part select of an array word * * The pform_name_t, then, is an ordered list of these name * components. The list of names comes from a hierarchical name in the * source, like this: * * foo[5].bar[6:4] -- a part select of a vector in sub-scope foo[5]. */ typedef std::list pform_name_t; inline perm_string peek_head_name(const pform_name_t&that) { return that.front().name; } inline perm_string peek_tail_name(const pform_name_t&that) { return that.back().name; } /* * In pform names, the "super" and "this" keywords are converted to * These tokens so that they don't interfere with the namespace and * are handled specially. */ # define SUPER_TOKEN "#" # define THIS_TOKEN "@" static inline std::ostream& operator<< (std::ostream&out, const data_type_t&that) { return that.debug_dump(out); } extern std::ostream& operator<< (std::ostream&out, const pform_name_t&); extern std::ostream& operator<< (std::ostream&out, const name_component_t&that); extern std::ostream& operator<< (std::ostream&out, const index_component_t&that); extern std::ostream& operator<< (std::ostream&out, enum typedef_t::basic_type bt); #endif /* IVL_pform_types_H */ iverilog-12_0/property_qual.h000066400000000000000000000045271435245347300164360ustar00rootroot00000000000000#ifndef IVL_property_qual_H #define IVL_property_qual_H /* * Copyright (c) 2013-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. */ class property_qualifier_t { public: static inline property_qualifier_t make_none() { property_qualifier_t res; res.mask_ = 0; return res; } static inline property_qualifier_t make_static() { property_qualifier_t res; res.mask_ = 1; return res; } static inline property_qualifier_t make_protected() { property_qualifier_t res; res.mask_ = 2; return res; } static inline property_qualifier_t make_local() { property_qualifier_t res; res.mask_ = 4; return res; } static inline property_qualifier_t make_rand() { property_qualifier_t res; res.mask_ = 8; return res; } static inline property_qualifier_t make_randc() { property_qualifier_t res; res.mask_ = 16; return res; } static inline property_qualifier_t make_const() { property_qualifier_t res; res.mask_ = 32; return res; } inline property_qualifier_t operator | (property_qualifier_t r) { property_qualifier_t res; res.mask_ = mask_ | r.mask_; return res; } public: inline bool test_static() const { return mask_ & 1; } inline bool test_protected() const { return mask_ & 2; } inline bool test_local() const { return mask_ & 4; } inline bool test_rand() const { return mask_ & 8; } inline bool test_randc() const { return mask_ & 16; } inline bool test_const() const { return mask_ & 32; } private: int mask_; }; #endif /* IVL_property_qual_H */ iverilog-12_0/scripts/000077500000000000000000000000001435245347300150365ustar00rootroot00000000000000iverilog-12_0/scripts/CREATE_VERSION.sh000066400000000000000000000006641435245347300175500ustar00rootroot00000000000000#!/bin/sh # This script manually creates a version.h file. # # It is used when creating a MinGW executable from a Cygwin # hosted git repository. It assumes that git is available. # # sh scripts/CREATE_VERSION.sh # echo "Building version_tag.h with git describe" tmp=`git describe | sed -e 's;\(.*\);#define VERSION_TAG "\1";'` echo "#ifndef VERSION_TAG" > version_tag.h echo "$tmp" >> version_tag.h echo "#endif" >> version_tag.h iverilog-12_0/scripts/MAKE_RELEASE.sh000066400000000000000000000036371435245347300172600ustar00rootroot00000000000000#!/bin/sh # This script makes a release from a git repository. The input is # the number for a snapshot and the path to a temporary directory. # for example: # # sh scripts/MAKE_RELEASE.sh 10.1 ~/tmp # # The above assumes that there is a tag "v0_9_1" at the point # to be released. (The tag has the "v", but the argument to this # script does not have the "v"). This script extracts based on the # tag, uses the temporary directory to stage intermediate results, # and finally creates a file called verilog-0.9.1.tar.gz that # contains the release ready to go. # # The complete steps to make a release x.y generally are: # # Edit version_base.h to suit. # # Edit verilog.spec to suit. # # git tag -a v10_1 # (Make the tag in the local git repository.) # # sh scripts/MAKE_RELEASE.sh 10.1 ~/tmp # (Make the snapshot bundle verilog-10.1.tar.gz) # # git push --tags # (Publish the tag to the repository.) # id=$1 destdir=$2 # The git tag to use. tag="v"`echo $id | tr '.' '_'` # The prefix is the directory that contains the extracted files # of the bundle. This is also the name of the bundle file itself. prefix="verilog-$id" if [ ! -d $destdir ]; then echo "ERROR: Directory $destdir does not exist." exit 1 fi if [ -e $destdir/$prefix ]; then echo "ERROR: $destdir/$prefix already exists." exit 1 fi echo "Exporting $tag to $destdir/$prefix..." git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - ) versionh="$destdir/$prefix/version_tag.h" echo "Create $versionh ..." echo "#ifndef VERSION_TAG" > $versionh echo "#define VERSION_TAG \"$tag\"" >> $versionh echo "#endif" >> $versionh echo "Running autoconf.sh..." ( cd $destdir/$prefix && sh autoconf.sh ) echo "Making bundle $prefix.tar.gz..." tar czf $prefix.tar.gz --exclude=autom4te.cache -C "$destdir" $prefix echo "Removing temporary $destdir/$prefix..." rm -rf "$destdir/$prefix" echo done iverilog-12_0/scripts/MAKE_SNAPSHOT.sh000066400000000000000000000037121435245347300174310ustar00rootroot00000000000000#!/bin/sh # This script makes snapshots from a git repository. The input is # the number for a snapshot and the path to a temporary directory. # for example: # # sh scripts/MAKE_SNAPSHOT.sh 20080428 ~/tmp # # The above assumes that there is a tag "s20080428" at the point # to be snapshot. (The tag has the "s", but the argument to this # script does not have the "s"). This script extracts based on the # tag, uses the temporary directory to stage intermediate results, # and finally creates a file called verilog-20080428.tar.gz that # contains the snapshot ready to go. # # The complete steps to make a snapshot YYYYMMDD generally are: # # edit the verilog.spec to set the rev_date to YYYYMMDD # # git tag -a sYYYYMMDD # (Make the tag in the local git repository.) # # sh scripts/MAKE_SNAPSHOT.sh YYYYMMDD ~/tmp # (Make the snapshot bundle verilog-YYYYMMDD.tar.gz) # # git push --tags # (Publish the tag to the repository.) # id=$1 destdir=$2 # The git tag to use is the snapshot id with a prepended "s". tag="s$id" # The prefix is the directory that contains the extracted files # of the bundle. This is also the name of the bundle file itself. prefix="verilog-$id" if [ ! -d $destdir ]; then echo "ERROR: Directory $destdir does not exist." exit 1 fi if [ -e $destdir/$prefix ]; then echo "ERROR: $destdir/$prefix already exists." exit 1 fi echo "Exporting $tag to $destdir/$prefix..." git archive --prefix="$prefix/" $tag | ( cd "$destdir" && tar xf - ) versionh="$destdir/$prefix/version_tag.h" echo "Create $versionh ..." echo "#ifndef VERSION_TAG" > $versionh echo "#define VERSION_TAG \"$tag\"" >> $versionh echo "#endif" >> $versionh echo "Running autoconf.sh..." ( cd $destdir/$prefix && sh autoconf.sh ) echo "Making bundle $prefix.tar.gz..." tar czf $prefix.tar.gz --exclude=autom4te.cache -C "$destdir" $prefix echo "Removing temporary $destdir/$prefix..." rm -rf "$destdir/$prefix" echo done iverilog-12_0/scripts/devel-stub.conf000066400000000000000000000013121435245347300177540ustar00rootroot00000000000000# # This is a debug conf file that the scripts/devel-stub.sh script uses # to control the ivl core. The contents of this file are normally written # to a temporary file by the driver program, but for devel purposes, where # the driver program is not used, this config substitutes. # # NOTE: DO NOT INSTALL THIS FILE! # generation:2009 generation:specify generation:assertions generation:xtypes generation:verilog-ams iwidth:32 sys_func:vpi/system.sft sys_func:vpi/v2005_math.sft sys_func:vpi/va_math.sft warnings:adfilnpstv debug:eval_tree debug:elaborate debug:emit debug:elab_pexpr debug:scopes debug:synth2 debug:optimizer out:a.out ivlpp:./ivlpp/ivlpp -D__ICARUS__ -L -Pfoo.pp sys_func:scripts/devel-stub.sft iverilog-12_0/scripts/devel-stub.sft000066400000000000000000000001451435245347300176260ustar00rootroot00000000000000 # This is an example function table. $realtime vpiSysFuncReal $verywide vpiSysFuncSized 128 signed iverilog-12_0/scripts/devel-stub.sh000066400000000000000000000011371435245347300174460ustar00rootroot00000000000000 # This is a little developer convenience script to run the ivl core program # in place with the stub target. It runs the ivl core verbose, with diagnostic # output files enable, and without the driver program or preprocessor. # It is useful only for development of the ivl core program. # # Run this script in the source directory for the ivl core program so that # the patch to the other components is correct. # # NOTE: DO NOT INSTALL THIS FILE. ./ivl -v -Ctgt-stub/stub.conf -C./scripts/devel-stub.conf -Pa.pf -Na.net -fDLL=tgt-stub/stub.tgt foo.vl | tee foo.log 2>&1 echo "*** ivl command completed" iverilog-12_0/solaris/000077500000000000000000000000001435245347300150235ustar00rootroot00000000000000iverilog-12_0/solaris/README-solaris_pkg.txt000066400000000000000000000024331435245347300210360ustar00rootroot00000000000000Notes about the solaris package. I. Installing a prebuilt solaris package ----------------------------------------- To install the solaris package do the following as root on your machine: 1) uncompress the package using: cp package_name.gz /tmp cd /tmp gunzip package_name.gz where "package_name.gz" is the compressed binary package. It will be named something like "verilog-0.3-SunOS-5.6-sparc.gz" 2) install the package using: cd /tmp pkgadd -d package_name this will install the package. The package will be registered under the name "IVLver" II. Uninstalling the solaris package ------------------------------------- To uninstall an installed solaris package do the following as root on your machine: pkgrm IVLver III. Notes on building a solaris package from sources ------------------------------------------------------ 1) build and install verilog. Be sure and pick where the package should install with the "--prefix=" argument to 'configure' 2) edit the 'pkginfo' file to update the version number and also set BASEDIR to the same as the argument to "--prefix=" 3) edit the 'prototype' file to add/removed files/directories from the list of installed components. 4) run the 'mksolpkg' script to create the solaris package iverilog-12_0/solaris/mksolpkg000077500000000000000000000020521435245347300165770ustar00rootroot00000000000000#!/bin/sh # # mksolpkg # a script to generate a native solaris package # if [ `whoami` != "root" ]; then echo "you must be root to run this script" exit 1 fi # an ugly hack to get various bits of info ver=`grep VERSION pkginfo | sed 's/"/ /g' | awk '{print $2}'` basedir=`grep BASEDIR pkginfo | sed 's/"/ /g' | awk '{print $2}'` name=`grep NAME pkginfo | sed 's/"/ /g' | awk '{print $2}'` pkg=`grep PKG pkginfo | sed 's/"/ /g' | awk '{print $2}'` arch=`grep ARCH pkginfo | sed 's/"/ /g' | awk '{print $2}'` march=`uname -p` if [ "$arch" != "$march" ]; then echo "Warning: you have listed \"$arch\" in the pkginfo file but this machine" echo " has a \"$march\" processor" exit 1 fi oslabel=`uname -s`-`uname -r`-$march fname=$name-$ver-$oslabel cp -f prototype $basedir cp -f pkginfo $basedir cd $basedir pkgmk -o -r `pwd` cd /var/spool/pkg pkgtrans -s `pwd` /tmp/$fname all cd /tmp gzip -f $fname echo "Your $oslabel package is left in /tmp/$fname.gz" # cleanup rm -f $basedir/prototype $basedir/pkginfo rm -fr /var/spool/pkg/$pkg iverilog-12_0/solaris/pkginfo000066400000000000000000000002711435245347300164030ustar00rootroot00000000000000PKG="IVLver" NAME="verilog" ARCH="sparc" VERSION="0.7" CATEGORY="application" VENDOR="Icarus.com" EMAIL="steve@icarus.com" PSTAMP="Stephen Williams" BASEDIR="/usr/local" CLASSES="none" iverilog-12_0/solaris/prototype000066400000000000000000000015601435245347300170150ustar00rootroot00000000000000i pkginfo=./pkginfo d none bin 0755 bin bin f none bin/iverilog 0755 bin bin f none bin/iverilog-vpi 0755 bin bin f none bin/vvp 0755 bin bin d none include 0755 bin bin f none include/acc_user.h 0644 bin bin f none include/ivl_target.h 0644 bin bin f none include/veriuser.h 0644 bin bin f none include/vpi_user.h 0644 bin bin d none lib 0755 bin bin d none lib/ivl 0755 bin bin f none lib/ivl/fpga.tgt 0644 bin bin f none lib/ivl/iverilog.conf 0644 bin bin f none lib/ivl/ivl 0755 bin bin f none lib/ivl/ivlpp 0755 bin bin f none lib/ivl/null.tgt 0644 bin bin f none lib/ivl/system.vpi 0644 bin bin f none lib/ivl/vvp.tgt 0644 bin bin f none lib/libveriuser.a 0644 bin bin f none lib/libvpi.a 0644 bin bin d none man 0755 bin bin d none man/man1 0755 bin bin f none man/man1/iverilog.1 0644 bin bin f none man/man1/iverilog-vpi.1 0644 bin bin f none man/man1/vvp.1 0644 bin bin iverilog-12_0/sv_vpi_user.h000066400000000000000000000050621435245347300160670ustar00rootroot00000000000000#ifndef SV_VPI_USER_H #define SV_VPI_USER_H /* * Copyright (c) 2010-2021 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 "vpi_user.h" #if defined(__MINGW32__) || defined (__CYGWIN__) # define DLLEXPORT __declspec(dllexport) #else # define DLLEXPORT #endif #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_END } #else # define EXTERN_C_START # define EXTERN_C_END #endif #ifndef __GNUC__ # undef __attribute__ # define __attribute__(x) #endif EXTERN_C_START /********* OBJECT TYPES ***********/ #define vpiPackage 600 #define vpiInterface 601 #define vpiProgram 602 #define vpiArrayType 606 #define vpiStaticArray 1 #define vpiDynamicArray 2 #define vpiAssocArray 3 #define vpiQueueArray 4 #define vpiLongIntVar 610 #define vpiShortIntVar 611 #define vpiIntVar 612 #define vpiByteVar 614 #define vpiLogicVar vpiReg #define vpiClassVar 615 #define vpiStringVar 616 #define vpiBitVar 620 #define vpiArrayVar vpiRegArray /********* TYPESPECS *************/ #define vpiClassTypespec 630 #define vpiEnumTypespec 633 #define vpiEnumConst 634 #define vpiClassDefn 652 /********* One-to-One ***********/ #define vpiBaseTypespec 703 /********* Many-to-One ***********/ #define vpiMember 742 /********* One-to-One and One-to-Many ***********/ #define vpiInstance 745 /********* generic object properties ***********/ #define vpiNullConst 11 /********* task/function properties **********/ #define vpiOtherFunc 6 /* Icarus-specific function type to use string as the return type */ #define vpiStringFunc 10 #define vpiSysFuncString vpiSysFuncString EXTERN_C_END #endif /* SV_VPI_USER_H */ iverilog-12_0/swift.txt000066400000000000000000000045311435245347300152470ustar00rootroot00000000000000 SWIFT MODEL SUPPORT FOR Icarus Verilog (PRELIMINARY) Copyright 2003 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-12_0/symbol_search.cc000066400000000000000000000272631435245347300165220ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2012 / 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 "netlist.h" # include "netclass.h" # include "netparray.h" # include "netmisc.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; /* * Search for the hierarchical name. The path may have multiple components. If * that's the case, then recursively pull the path apart until we find the * first item in the path, look that up, and work our way up. In most cases, * the path will be a string of scopes, with an object at the end. But if we * find an object before the end, then the tail will have to be figured out by * the initial caller. */ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, pform_name_t path, struct symbol_search_results*res, NetScope*start_scope) { assert(scope); bool prefix_scope = false; if (debug_elaborate) { cerr << li->get_fileline() << ": symbol_search: " << "scope: " << scope_path(scope) << endl; cerr << li->get_fileline() << ": symbol_search: " << "path: " << path << endl; if (start_scope) cerr << li->get_fileline() << ": symbol_search: " << "start_scope: " << scope_path(start_scope) << endl; } assert(li); ivl_assert(*li, ! path.empty()); name_component_t path_tail = path.back(); path.pop_back(); // If this is a recursive call, then we need to know that so // that we can enable the search for scopes. Set the // recurse_flag to true if this is a recurse. if (start_scope==0) start_scope = scope; // If there are components ahead of the tail, symbol_search // recursively. Ideally, the result is a scope that we search // for the tail key, but there are other special cases as well. if (! path.empty()) { bool flag = symbol_search(li, des, scope, path, res, start_scope); if (! flag) return false; // The prefix is found to be something besides a scope. Put the // tail into the path_tail of the result, and return success. The // caller needs to deal with that tail bit. Note that the // path_tail is a single item, but we might have been called // recursively, so the complete tail will be built up as we unwind. if (res->is_found() && !res->is_scope()) { if (!path_tail.empty()) res->path_tail.push_back(path_tail); return true; } // The prefix is found to be a scope, so switch to that // scope, set the hier_path to turn off upwards searches, // and continue our search for the tail. if (res->is_scope()) { scope = res->scope; prefix_scope = true; if (debug_scopes || debug_elaborate) { cerr << li->get_fileline() << ": symbol_search: " << "Prefix scope " << scope_path(scope) << endl; } if (scope->is_auto()) { cerr << li->get_fileline() << ": error: Hierarchical " "reference to automatically allocated item " "`" << path_tail.name << "' in path `" << path << "'" << endl; des->errors += 1; } } else { // Prefix is present, but is NOT a scope. Fail! Actually, this // should not happen, since this is the "not found" case, and we // should have returned already. assert(0); return false; } } bool passed_module_boundary = false; // At this point, we've stripped right-most components until the search // found the scope part of the path, or there is no scope part of the // path. For example, if the path in was s1.s2.x, we found the scope // s1.s2, res->is_scope() is true, and path_tail is x. We look for x // now. The preceeding code set prefix_scope=true to ease our test below. // // If the input was x (without prefixes) then we don't know if x is a // scope or item. In this case, res->is_found() is false and we may need // to scan upwards to find the scope or item. while (scope) { if (debug_scopes || debug_elaborate) { cerr << li->get_fileline() << ": symbol_search: " << "Looking for " << path_tail << " in scope " << scope_path(scope) << " prefix_scope=" << prefix_scope << endl; } if (scope->genvar_tmp.str() && path_tail.name == scope->genvar_tmp) return false; // These items cannot be seen outside the bounding module where // the search starts. But we continue searching up because scope // names can match. For example: // // module top; // int not_ok; // dut foo(...); // endmodule // module dut; // ... not_ok; // <-- Should NOT match. // ... top.not_ok; // Matches. // endmodule if (!passed_module_boundary) { // Special case `super` keyword. Return the `this` object, but // with the type of the base class. if (path_tail.name == "#") { if (NetNet *net = scope->find_signal(perm_string::literal(THIS_TOKEN))) { const netclass_t *class_type = dynamic_cast(net->net_type()); path.push_back(path_tail); res->scope = scope; res->net = net; res->type = class_type->get_super(); res->path_head = path; return true; } return false; } if (NetNet*net = scope->find_signal(path_tail.name)) { path.push_back(path_tail); res->scope = scope; res->net = net; res->type = net->net_type(); res->path_head = path; return true; } if (NetEvent*eve = scope->find_event(path_tail.name)) { path.push_back(path_tail); res->scope = scope; res->eve = eve; res->path_head = path; return true; } if (const NetExpr*par = scope->get_parameter(des, path_tail.name, res->type)) { path.push_back(path_tail); res->scope = scope; res->par_val = par; res->path_head = path; return true; } // Static items are just normal signals and are found above. if (scope->type() == NetScope::CLASS) { netclass_t*clsnet = scope->find_class(des, scope->basename()); int pidx = clsnet->property_idx_from_name(path_tail.name); if (pidx >= 0) { ivl_type_t prop_type = clsnet->get_prop_type(pidx); const netuarray_t*tmp_ua = dynamic_cast(prop_type); if (tmp_ua) prop_type = tmp_ua->element_type(); path.push_back(path_tail); res->scope = scope; res->cls_val = prop_type; res->path_head = path; return true; } } } if (NetScope*import_scope = scope->find_import(des, path_tail.name)) { scope = import_scope; continue; } // Could not find an object. Maybe this is a child scope name? If // so, evaluate the path components to find the exact scope this // refers to. This item might be: // .s // .s[n] // etc. The scope->child_byname tests if the name exists, and if // it does, the eval_path_component() evaluates any [n] // expressions to constants to generate an hname_t object for a // more complete scope name search. Note that the index // expressions for scope names must be constant. if (scope->child_byname(path_tail.name)) { bool flag = false; hname_t path_item = eval_path_component(des, start_scope, path_tail, flag); if (flag) { cerr << li->get_fileline() << ": XXXXX: Errors evaluating scope index" << endl; } else if (NetScope*chld = scope->child(path_item)) { path.push_back(path_tail); res->scope = chld; res->path_head = path; return true; } } // Don't scan up if we are searching within a prefixed scope. if (prefix_scope) break; // Special case: We can match the module name of a parent // module. That means if the current scope is a module of type // "mod", then "mod" matches the current scope. This is fairly // obscure, but looks like this: // // module foo; // reg x; // ... foo.x; // This matches x in myself. // endmodule // // This feature recurses, so code in subscopes of foo can refer to // foo by the name "foo" as well. In general, anything within // "foo" can use the name "foo" to reference it. if (scope->type()==NetScope::MODULE && scope->module_name()==path_tail.name) { path.push_back(path_tail); res->scope = scope; res->path_head = path; return true; } // If there is no prefix, then we are free to scan upwards looking // for a scope name. Note that only scopes can be searched for up // past module boundaries. To handle that, set a flag to indicate // that we passed a module boundary on the way up. if (scope->type()==NetScope::MODULE && !scope->nested_module()) passed_module_boundary = true; scope = scope->parent(); // Last chance - try the compilation unit. Note that modules may // reference nets/variables in the compilation unit, even if they // cannot reference variables in containing scope. // // int ok = 1; // module top; // int not_ok = 2; // dut foo(); // endmodule // // module dut; // ... = ok; // This reference is OK // ... = not_ok; // This reference is NOT OK. // endmodule if (scope == 0 && start_scope != 0) { scope = start_scope->unit(); start_scope = 0; passed_module_boundary = false; } } // Last chance: this is a single name, so it might be the name // of a root scope. Ask the design if this is a root // scope. This is only possible if there is no prefix. if (prefix_scope==false) { hname_t path_item (path_tail.name); scope = des->find_scope(path_item); if (scope) { path.push_back(path_tail); res->scope = scope; res->path_head = path; return true; } } return false; } /* * Compatibility version. Remove me! */ NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope, const pform_name_t&path, NetNet*&net, const NetExpr*&par, NetEvent*&eve, ivl_type_t&par_type, ivl_type_t&cls_val) { symbol_search_results recurse; bool flag = symbol_search(li, des, scope, path, &recurse); net = 0; cls_val = 0; par = 0; par_type = 0; eve = 0; // The compatible version doesn't know how to handle unmatched tail // components, so report them as errors. if (! recurse.path_tail.empty()) { if (debug_elaborate) { cerr << li->get_fileline() << ": symbol_search (compat): " << "path_tail items found: " << recurse.path_tail << endl; } return 0; } // Convert the extended results to the compatible results. net = recurse.net; cls_val = recurse.cls_val; par = recurse.par_val; par_type = recurse.type; eve = recurse.eve; if (! flag) { return 0; } return recurse.scope; } iverilog-12_0/syn-rules.y000066400000000000000000000230411435245347300155020ustar00rootroot00000000000000 %{ /* * Copyright (c) 2000-2021 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 /* * This file implements synthesis based on matching threads and * converting them to equivalent devices. The trick here is that the * proc_match_t functor can be used to scan a process and generate a * string of tokens. That string of tokens can then be matched by the * rules to determine what kind of device is to be made. */ # include "netlist.h" # include "netmisc.h" # include "functor.h" # include using namespace std; struct syn_token_t { int token; NetAssignBase*assign; NetProcTop*top; NetEvWait*evwait; NetEvent*event; NetExpr*expr; syn_token_t*next_; }; #define YYSTYPE syn_token_t* static int yylex(); static void yyerror(const char*); static Design*des_; static void make_DFF_CE(Design*des, NetProcTop*top, NetEvent*eclk, NetExpr*cexp, NetAssignBase*asn); %} %token S_ALWAYS S_ASSIGN S_ASSIGN_MEM S_ASSIGN_MUX S_ELSE S_EVENT %token S_EXPR S_IF S_INITIAL %% start /* These rules match simple DFF devices. Clocked assignments are simply implemented as DFF, and a CE is easily expressed with a conditional statement. The typical Verilog that get these are: always @(posedge CLK) Q = D always @(negedge CLK) Q = D always @(posedge CLK) if (CE) Q = D; always @(negedge CLK) if (CE) Q = D; The width of Q and D cause a wide register to be created. The code generators generally implement that as an array of flip-flops. */ : S_ALWAYS '@' '(' S_EVENT ')' S_ASSIGN ';' { make_DFF_CE(des_, $1->top, $4->event, 0, $6->assign); } | S_ALWAYS '@' '(' S_EVENT ')' S_IF S_EXPR S_ASSIGN ';' ';' { make_DFF_CE(des_, $1->top, $4->event, $7->expr, $8->assign); } /* Unconditional assignments in initial blocks should be made into initializers wherever possible. */ ; %% /* Various actions. */ static void hookup_DFF_CE(NetFF*ff, NetESignal*d, NetEvProbe*pclk, NetNet*ce, NetAssign_*a, unsigned rval_pinoffset) { if (rval_pinoffset != 0) { cerr << a->get_fileline() << ": sorry: " << "unable to hook up an R-value with offset " << rval_pinoffset << " to signal " << a->name() << "." << endl; return; } // a->sig() is a *NetNet, which doesn't have the loff_ and // lwid_ context. Add the correction for loff_ ourselves. // This extra calculation allows for assignments like: // lval[7:1] <= foo; // where lval is really a "reg [7:0]". In other words, part // selects in the l-value are handled by loff and the lwidth(). connect(ff->pin_Data(), d->sig()->pin(0)); connect(ff->pin_Q(), a->sig()->pin(0)); connect(ff->pin_Clock(), pclk->pin(0)); if (ce) connect(ff->pin_Enable(), ce->pin(0)); /* This lval_ represents a reg that is a WIRE in the synthesized results. This function signals the destructor to change the REG that this l-value refers to into a WIRE. It is done then, at the last minute, so that pending synthesis can continue to work with it as a WIRE. */ a->turn_sig_to_wire_on_release(); } static void make_DFF_CE(Design*des, NetProcTop*top, NetEvent*eclk, NetExpr*cexp, NetAssignBase*asn) { assert(asn); NetEvProbe*pclk = eclk->probe(0); NetESignal*d = dynamic_cast (asn->rval()); NetNet*ce = cexp? cexp->synthesize(des, top->scope(), cexp) : 0; if (d == 0) { cerr << asn->get_fileline() << ": internal error: " << " not a simple signal? " << *asn->rval() << endl; } assert(d); NetAssign_*a; unsigned rval_pinoffset=0; for (unsigned i=0; (a=asn->l_val(i)); i++) { // asn->l_val(i) are the set of *NetAssign_'s that form the list // of lval expressions. Treat each one independently, keeping // track of which bits of rval to use for each set of DFF inputs. // For example, given: // {carry,data} <= x + y + z; // run through this loop twice, where a and rval_pinoffset are // first data and 0, then carry and 1. // FIXME: ff gets its pin names wrong when loff_ is nonzero. if (a->sig()) { // cerr << "new NetFF named " << a->name() << endl; bool negedge = pclk->edge() == NetEvProbe::NEGEDGE; NetFF*ff = new NetFF(top->scope(), a->name(), negedge, a->sig()->vector_width()); hookup_DFF_CE(ff, d, pclk, ce, a, rval_pinoffset); des->add_node(ff); } rval_pinoffset += a->lwidth(); } des->delete_process(top); } static syn_token_t*first_ = 0; static syn_token_t*last_ = 0; static syn_token_t*ptr_ = 0; /* * The match class is used to take a process and turn it into a stream * of tokens. This stream is used by the yylex function to feed tokens * to the parser. */ struct tokenize : public proc_match_t { tokenize() { } ~tokenize() { } int assign(NetAssign*dev) { syn_token_t*cur; cur = new syn_token_t; // Bit Muxes can't be synthesized (yet), but it's too much // work to detect them now. // cur->token = dev->l_val(0)->bmux() ? S_ASSIGN_MUX : S_ASSIGN; cur->token = S_ASSIGN; cur->assign = dev; cur->next_ = 0; last_->next_ = cur; last_ = cur; return 0; } int assign_nb(NetAssignNB*dev) { syn_token_t*cur; cur = new syn_token_t; // Bit Muxes can't be synthesized (yet), but it's too much // work to detect them now. // cur->token = dev->l_val(0)->bmux() ? S_ASSIGN_MUX : S_ASSIGN; cur->token = S_ASSIGN; cur->assign = dev; cur->next_ = 0; last_->next_ = cur; last_ = cur; return 0; } int condit(NetCondit*dev) { syn_token_t*cur; cur = new syn_token_t; cur->token = S_IF; cur->next_ = 0; last_->next_ = cur; last_ = cur; cur = new syn_token_t; cur->token = S_EXPR; cur->expr = dev->expr(); cur->next_ = 0; last_->next_ = cur; last_ = cur; /* Because synthesis is broken this is needed to prevent * a seg. fault. */ if (!dev->if_clause()) return 0; dev -> if_clause() -> match_proc(this); if (dev->else_clause()) { cur = new syn_token_t; cur->token = S_ELSE; cur->next_ = 0; last_->next_ = cur; last_ = cur; dev -> else_clause() -> match_proc(this); } cur = new syn_token_t; cur->token = ';'; cur->next_ = 0; last_->next_ = cur; last_ = cur; return 0; } int event_wait(NetEvWait*dev) { syn_token_t*cur; cur = new syn_token_t; cur->token = '@'; cur->evwait = dev; cur->next_ = 0; last_->next_ = cur; last_ = cur; cur = new syn_token_t; cur->token = '('; cur->next_ = 0; last_->next_ = cur; last_ = cur; for (unsigned idx = 0; idx < dev->nevents(); idx += 1) { cur = new syn_token_t; cur->token = S_EVENT; cur->event = dev->event(idx); cur->next_ = 0; last_->next_ = cur; last_ = cur; } cur = new syn_token_t; cur->token = ')'; cur->next_ = 0; last_->next_ = cur; last_ = cur; dev -> statement() -> match_proc(this); cur = new syn_token_t; cur->token = ';'; cur->next_ = 0; last_->next_ = cur; last_ = cur; return 0; } }; static void syn_start_process(NetProcTop*t) { first_ = new syn_token_t; last_ = first_; ptr_ = first_; // Can the following be converted into S_ALWAYS? if ((t->type() == IVL_PR_ALWAYS_COMB) || (t->type() == IVL_PR_ALWAYS_FF) || (t->type() == IVL_PR_ALWAYS_LATCH)) { cerr << t->get_fileline() << ": internal error: " << " Need to check if this can be synthesized." << endl; assert(0); } first_->token = (t->type() == IVL_PR_ALWAYS)? S_ALWAYS : S_INITIAL; first_->top = t; first_->next_ = 0; tokenize go; t -> statement() -> match_proc(&go); } static void syn_done_process() { while (first_) { syn_token_t*cur = first_; first_ = cur->next_; delete cur; } } static int yylex() { if (ptr_ == 0) { yylval = 0; return 0; } yylval = ptr_; ptr_ = ptr_->next_; return yylval->token; } struct syn_rules_f : public functor_t { ~syn_rules_f() { } void process(class Design*, class NetProcTop*top) { /* If the scope that contains this process as a cell attribute attached to it, then skip synthesis. */ if (top->scope()->attribute(perm_string::literal("ivl_synthesis_cell")).len() > 0) return; syn_start_process(top); yyparse(); syn_done_process(); } }; void syn_rules(Design*d) { des_ = d; syn_rules_f obj; des_->functor(&obj); } static void yyerror(const char*) { } iverilog-12_0/sync.cc000066400000000000000000000033471435245347300146410ustar00rootroot00000000000000/* * Copyright (c) 2002-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 "functor.h" # include "netlist.h" # include /* * Most process statements are not roots of synchronous logic. */ bool NetProc::is_synchronous() { return false; } bool NetEvWait::is_synchronous() { for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) { NetEvent*ev = events_[idx]; if (ev->nprobe() == 0) return false; for (unsigned pdx = 0 ; pdx < ev->nprobe() ; pdx += 1) { NetEvProbe*pr = ev->probe(pdx); /* No level sensitive clocks. */ if (pr->edge() == NetEvProbe::ANYEDGE) return false; } } /* So we know that there is a clock source. Check that the input to the storage is asynchronous. */ return true; //statement_->is_asynchronous(); } bool NetProcTop::is_synchronous() { if (type_ == IVL_PR_INITIAL) return false; return statement_->is_synchronous(); } iverilog-12_0/synth.cc000066400000000000000000000101601435245347300150210ustar00rootroot00000000000000/* * Copyright (c) 1999-2017 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 "functor.h" # include "netlist.h" /* * This functor scans the behavioral code, looking for expressions to * synthesize. Although it uses the proc_match_t class, it doesn't * actually match anything, but transforms expressions into structural * netlists. The product of this should be a process where all the * expressions have been reduced to a signal ident, which references * the NetNet of the now synthesized expression. */ class do_expr : public proc_match_t { public: do_expr(Design*d, NetScope*s) : des_(d), scope_(s) { } private: Design*des_; NetScope*scope_; virtual int assign(NetAssign*); virtual int assign_nb(NetAssignNB*); virtual int event_wait(NetEvWait*); virtual int condit(NetCondit*); }; int do_expr::assign(NetAssign*stmt) { if (dynamic_cast(stmt->rval())) return 0; NetNet*tmp = stmt->rval()->synthesize(des_, scope_, stmt->rval()); if (tmp == 0) return 0; NetESignal*tmpe = new NetESignal(tmp); stmt->set_rval(tmpe); return 0; } int do_expr::assign_nb(NetAssignNB*stmt) { if (dynamic_cast(stmt->rval())) return 0; NetNet*tmp = stmt->rval()->synthesize(des_, scope_, stmt->rval()); if (tmp == 0) return 0; NetESignal*tmpe = new NetESignal(tmp); stmt->set_rval(tmpe); return 0; } int do_expr::condit(NetCondit*stmt) { /* synthesize the condition expression, if necessary. */ if (! dynamic_cast(stmt->expr())) { NetNet*tmp = stmt->expr()->synthesize(des_, scope_, stmt->expr()); if (tmp) { NetESignal*tmpe = new NetESignal(tmp); stmt->set_expr(tmpe); } } /* Now recurse through the if and else clauses. */ if (NetProc*tmp = stmt->if_clause()) tmp->match_proc(this); if (NetProc*tmp = stmt->else_clause()) tmp->match_proc(this); return 0; } int do_expr::event_wait(NetEvWait*stmt) { NetProc*tmp = stmt->statement(); if (tmp) return tmp->match_proc(this); else return 0; } class synth_f : public functor_t { public: synth_f() { top_ = NULL; } void process(Design*, NetProcTop*); private: void proc_always_(Design*); void proc_initial_(Design*); void proc_final_(Design*); NetProcTop*top_; }; /* * Look at a process, and divide the problem into always and initial * threads. */ void synth_f::process(Design*des, NetProcTop*top) { top_ = top; switch (top->type()) { case IVL_PR_ALWAYS: case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: proc_always_(des); break; case IVL_PR_INITIAL: proc_initial_(des); break; case IVL_PR_FINAL: proc_final_(des); break; } } void synth_f::proc_always_(Design*des) { do_expr expr_pat(des, top_->scope()); top_->statement()->match_proc(&expr_pat); } void synth_f::proc_initial_(Design*des) { do_expr expr_pat(des, top_->scope()); top_->statement()->match_proc(&expr_pat); } void synth_f::proc_final_(Design*des) { do_expr expr_pat(des, top_->scope()); top_->statement()->match_proc(&expr_pat); } void synth(Design*des) { synth_f synth_obj; des->functor(&synth_obj); } iverilog-12_0/synth2.cc000066400000000000000000002310331435245347300151070ustar00rootroot00000000000000/* * Copyright (c) 2002-2022 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 "functor.h" # include "netlist.h" # include "netvector.h" # include "netmisc.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; /* General notes on enables and bitmasks. * * When synthesising an asynchronous process that contains conditional * statements (if/case statements), we need to determine the conditions * that cause each nexus driven by that process to be updated. If a * nexus is not updated under all circumstances, we must infer a latch. * To this end, we generate an enable signal for each output nexus. As * we walk the statement tree for the process, for each substatement we * pass the enable signals generated so far into the synth_async method, * and on return from the synth_async method, the enable signals will be * updated to reflect any conditions introduced by that substatement. * Once we have synthesised all the statements for that process, if an * enable signal is not tied high, we must infer a latch for that nexus. * * When synthesising a synchronous process, we use the synth_async method * to synthesise the combinatorial inputs to the D pins of the flip-flops * we infer for that process. In this case the enable signal can be used * as a clock enable for the flip-flop. This saves us explicitly feeding * back the flip-flop output to undriven inputs of any synthesised muxes. * * The strategy described above is not sufficient when not all bits in * a nexus are treated identically (i.e. different conditional clauses * drive differing parts of the same vector). To handle this properly, * we would (potentially) need to generate a separate enable signal for * each bit in the vector. This would be a lot of work, particularly if * we wanted to eliminate duplicates. For now, the strategy employed is * to maintain a bitmask for each output nexus that identifies which bits * in the nexus are unconditionally driven (driven by every clause). When * we finish synthesising an asynchronous process, if the bitmask is not * all ones, we must infer a latch. This currently results in an error, * because to safely synthesise such a latch we would need the bit-level * gate enables. When we finish synthesising a synchronous process, if * the bitmask is not all ones, we explicitly feed the flip-flop outputs * back to undriven inputs of any synthesised muxes to ensure undriven * parts of the vector retain their previous state when the flip-flop is * clocked. * * The enable signals are passed as links to the current output nexus * for each signal. If an enable signal is not linked, this is treated * as if the signal was tied low. * * The bitmasks are passed as bool vectors. 'true' indicates a bit is * unconditionally driven. An empty vector (size = 0) indicates that * the current substatement doesn't drive any bits in the nexus. */ static void qualify_enable(Design*des, NetScope*scope, NetNet*qualifier, bool active_state, NetLogic::TYPE gate_type, Link&enable_i, Link&enable_o) { if (enable_i.is_linked(scope->tie_lo())) { connect(enable_o, scope->tie_lo()); return; } if (active_state == false) { NetLogic*gate = new NetLogic(scope, scope->local_symbol(), 2, NetLogic::NOT, 1); des->add_node(gate); connect(gate->pin(1), qualifier->pin(0)); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); connect(sig->pin(0), gate->pin(0)); qualifier = sig; } if (enable_i.is_linked(scope->tie_hi())) { connect(enable_o, qualifier->pin(0)); return; } NetLogic*gate = new NetLogic(scope, scope->local_symbol(), 3, gate_type, 1); des->add_node(gate); connect(gate->pin(1), qualifier->pin(0)); connect(gate->pin(2), enable_i); connect(enable_o, gate->pin(0)); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); connect(sig->pin(0), gate->pin(0)); } static void multiplex_enables(Design*des, NetScope*scope, NetNet*select, Link&enable_1, Link&enable_0, Link&enable_o) { if (!enable_1.is_linked() && !enable_0.is_linked() ) return; if ( enable_1.is_linked(scope->tie_hi()) && enable_0.is_linked(scope->tie_hi()) ) { connect(enable_o, scope->tie_hi()); return; } if (enable_1.is_linked(scope->tie_lo()) || !enable_1.is_linked()) { qualify_enable(des, scope, select, false, NetLogic::AND, enable_0, enable_o); return; } if (enable_0.is_linked(scope->tie_lo()) || !enable_0.is_linked()) { qualify_enable(des, scope, select, true, NetLogic::AND, enable_1, enable_o); return; } if (enable_1.is_linked(scope->tie_hi())) { qualify_enable(des, scope, select, true, NetLogic::OR, enable_0, enable_o); return; } if (enable_0.is_linked(scope->tie_hi())) { qualify_enable(des, scope, select, false, NetLogic::OR, enable_1, enable_o); return; } NetMux*mux = new NetMux(scope, scope->local_symbol(), 1, 2, 1); des->add_node(mux); connect(mux->pin_Sel(), select->pin(0)); connect(mux->pin_Data(1), enable_1); connect(mux->pin_Data(0), enable_0); connect(enable_o, mux->pin_Result()); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); connect(sig->pin(0), mux->pin_Result()); } static void merge_sequential_enables(Design*des, NetScope*scope, Link&top_enable, Link&sub_enable) { if (!sub_enable.is_linked()) return; if (top_enable.is_linked(scope->tie_hi())) return; if (sub_enable.is_linked(scope->tie_hi())) top_enable.unlink(); if (top_enable.is_linked()) { NetLogic*gate = new NetLogic(scope, scope->local_symbol(), 3, NetLogic::OR, 1); des->add_node(gate); connect(gate->pin(1), sub_enable); connect(gate->pin(2), top_enable); top_enable.unlink(); connect(top_enable, gate->pin(0)); NetNet*sig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, &netvector_t::scalar_logic); sig->local_flag(true); connect(sig->pin(0), gate->pin(0)); } else { connect(top_enable, sub_enable); } } static void merge_sequential_masks(NetProc::mask_t&top_mask, NetProc::mask_t&sub_mask) { if (sub_mask.size() == 0) return; if (top_mask.size() == 0) { top_mask = sub_mask; return; } assert(top_mask.size() == sub_mask.size()); for (unsigned idx = 0 ; idx < top_mask.size() ; idx += 1) { if (sub_mask[idx] == true) top_mask[idx] = true; } } static void merge_parallel_masks(NetProc::mask_t&top_mask, NetProc::mask_t&sub_mask) { if (sub_mask.size() == 0) return; if (top_mask.size() == 0) { top_mask = sub_mask; return; } assert(top_mask.size() == sub_mask.size()); for (unsigned idx = 0 ; idx < top_mask.size() ; idx += 1) { if (sub_mask[idx] == false) top_mask[idx] = false; } } static bool all_bits_driven(NetProc::mask_t&mask) { if (mask.size() == 0) return false; for (unsigned idx = 0 ; idx < mask.size() ; idx += 1) { if (mask[idx] == false) return false; } return true; } bool NetProcTop::tie_off_floating_inputs_(Design*des, NexusSet&nex_map, NetBus&nex_in, vector&bitmasks, bool is_ff_input) { bool flag = true; for (unsigned idx = 0 ; idx < nex_in.pin_count() ; idx += 1) { if (nex_in.pin(idx).nexus()->has_floating_input()) { if (all_bits_driven(bitmasks[idx])) { // If all bits are unconditionally driven, we can // use the enable signal to prevent the flip-flop/ // latch from updating when an undriven mux input // is selected, so we can just tie off the input. unsigned width = nex_map[idx].wid; NetLogic*gate = new NetLogic(scope(), scope()->local_symbol(), 1, NetLogic::PULLDOWN, width); des->add_node(gate); connect(nex_in.pin(idx), gate->pin(0)); if (nex_in.pin(idx).nexus()->pick_any_net()) continue; ivl_variable_type_t data_type = IVL_VT_LOGIC; netvector_t*tmp_vec = new netvector_t(data_type, width-1,0); NetNet*sig = new NetNet(scope(), scope()->local_symbol(), NetNet::WIRE, tmp_vec); sig->local_flag(true); connect(sig->pin(0), gate->pin(0)); } else if (is_ff_input) { // For a flip-flop, we can feed back the output // to ensure undriven bits hold their last value. connect(nex_in.pin(idx), nex_map[idx].lnk); } else { // This infers a latch, but without generating // gate enable signals at the bit-level, we // can't safely latch the undriven bits (we // shouldn't generate combinatorial loops). cerr << get_fileline() << ": warning: A latch " << "has been inferred for some bits of '" << nex_map[idx].lnk.nexus()->pick_any_net()->name() << "'." << endl; cerr << get_fileline() << ": sorry: Bit-level " "latch gate enables are not currently " "supported in synthesis." << endl; des->errors += 1; flag = false; } } } return flag; } bool NetProc::synth_async(Design*, NetScope*, NexusSet&, NetBus&, NetBus&, vector&) { return false; } /* * Async synthesis of assignments is done by synthesizing the rvalue * expression, then connecting the l-value directly to the output of * the r-value. * * The nex_map is the O-set for the statement, and lists the positions * of the outputs as the caller wants results linked up. The nex_out, * however, is the set of nexa that are to actually get linked to the * r-value. */ bool NetAssignBase::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { if (dynamic_cast(this) || dynamic_cast(this) || dynamic_cast(this) || dynamic_cast(this)) { cerr << get_fileline() << ": sorry: Procedural continuous " "assignment is not currently supported in synthesis." << endl; des->errors += 1; return false; } /* If the lval is a concatenation, synthesise each part separately. */ if (lval_->more ) { /* Temporarily set the lval_ and rval_ fields for each part in turn and recurse. Restore them when done. */ NetAssign_*full_lval = lval_; NetExpr*full_rval = rval_; unsigned offset = 0; bool flag = true; while (lval_) { unsigned width = lval_->lwidth(); NetEConst*base = new NetEConst(verinum(offset)); base->set_line(*this); rval_ = new NetESelect(full_rval->dup_expr(), base, width); rval_->set_line(*this); eval_expr(rval_, width); NetAssign_*more = lval_->more; lval_->more = 0; if (!synth_async(des, scope, nex_map, nex_out, enables, bitmasks)) flag = false; lval_ = lval_->more = more; offset += width; } lval_ = full_lval; rval_ = full_rval; return flag; } assert(rval_); NetNet*rsig = rval_->synthesize(des, scope, rval_); assert(rsig); if (lval_->word() && ! dynamic_cast(lval_->word())) { cerr << get_fileline() << ": sorry: Assignment to variable " "location in memory is not currently supported in " "synthesis." << endl; des->errors += 1; return false; } NetNet*lsig = lval_->sig(); if (!lsig) { cerr << get_fileline() << ": error: " "NetAssignBase::synth_async on unsupported lval "; dump_lval(cerr); cerr << endl; des->errors += 1; return false; } if (debug_synth2) { cerr << get_fileline() << ": NetAssignBase::synth_async: " << "l-value signal is " << lsig->vector_width() << " bits, " << "r-value signal is " << rsig->vector_width() << " bits." << endl; cerr << get_fileline() << ": NetAssignBase::synth_async: " << "lval_->lwidth()=" << lval_->lwidth() << endl; cerr << get_fileline() << ": NetAssignBase::synth_async: " << "lsig = " << scope_path(scope) << "." << lsig->name() << endl; if (const NetExpr*base = lval_->get_base()) { cerr << get_fileline() << ": NetAssignBase::synth_async: " << "base_=" << *base << endl; } cerr << get_fileline() << ": NetAssignBase::synth_async: " << "nex_map.size()==" << nex_map.size() << ", nex_out.pin_count()==" << nex_out.pin_count() << endl; } unsigned ptr = 0; if (nex_out.pin_count() > 1) { NexusSet tmp_set; nex_output(tmp_set); ivl_assert(*this, tmp_set.size() == 1); ptr = nex_map.find_nexus(tmp_set[0]); ivl_assert(*this, nex_out.pin_count() > ptr); ivl_assert(*this, enables.pin_count() > ptr); ivl_assert(*this, bitmasks.size() > ptr); } else { ivl_assert(*this, nex_out.pin_count() == 1); ivl_assert(*this, enables.pin_count() == 1); ivl_assert(*this, bitmasks.size() == 1); } unsigned lval_width = lval_->lwidth(); unsigned lsig_width = lsig->vector_width(); ivl_assert(*this, nex_map[ptr].wid == lsig_width); // Here we note if the l-value is actually a bit/part // select. If so, generate a NetPartSelect to perform the select. bool is_part_select = lval_width != lsig_width; long base_off = 0; if (is_part_select && !scope->loop_index_tmp.empty()) { // If we are within a NetForLoop, there may be an index // value. That is collected from the scope member // loop_index_tmp, and the evaluate_function method // knows how to apply it. ivl_assert(*this, !scope->loop_index_tmp.empty()); ivl_assert(*this, lval_width < lsig_width); // Evaluate the index expression to a constant. const NetExpr*base_expr_raw = lval_->get_base(); ivl_assert(*this, base_expr_raw); NetExpr*base_expr = base_expr_raw->evaluate_function(*this, scope->loop_index_tmp); if (! eval_as_long(base_off, base_expr)) { ivl_assert(*this, 0); } ivl_assert(*this, base_off >= 0); ivl_variable_type_t tmp_data_type = rsig->data_type(); netvector_t*tmp_type = new netvector_t(tmp_data_type, lsig_width-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); tmp->local_flag(true); tmp->set_line(*this); NetPartSelect*ps = new NetPartSelect(tmp, base_off, lval_width, NetPartSelect::PV); ps->set_line(*this); des->add_node(ps); connect(ps->pin(0), rsig->pin(0)); rsig = tmp; } else if (is_part_select) { // In this case, there is no loop_index_tmp, so we are // not within a NetForLoop. Generate a NetSubstitute // object to handle the bit/part-select in the l-value. ivl_assert(*this, scope->loop_index_tmp.empty()); ivl_assert(*this, lval_width < lsig_width); const NetExpr*base_expr_raw = lval_->get_base(); ivl_assert(*this, base_expr_raw); NetExpr*base_expr = base_expr_raw->evaluate_function(*this, scope->loop_index_tmp); if (! eval_as_long(base_off, base_expr)) { cerr << get_fileline() << ": sorry: assignment to variable " "bit location is not currently supported in " "synthesis." << endl; des->errors += 1; return false; } ivl_assert(*this, base_off >= 0); ivl_variable_type_t tmp_data_type = rsig->data_type(); netvector_t*tmp_type = new netvector_t(tmp_data_type, lsig_width-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); tmp->local_flag(true); tmp->set_line(*this); NetNet*isig = nex_out.pin(ptr).nexus()->pick_any_net(); if (isig) { if (debug_synth2) { cerr << get_fileline() << ": NetAssignBase::synth_async: " << " Found an isig:" << endl; nex_out.pin(ptr).dump_link(cerr, 8); } } else { if (debug_synth2) { cerr << get_fileline() << ": NetAssignBase::synth_async: " << " Found no isig, resorting to lsig." << endl; } isig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); isig->local_flag(true); isig->set_line(*this); connect(isig->pin(0), nex_out.pin(ptr)); } ivl_assert(*this, isig); NetSubstitute*ps = new NetSubstitute(isig, rsig, lsig_width, base_off); ps->set_line(*this); des->add_node(ps); connect(ps->pin(0), tmp->pin(0)); rsig = tmp; } rsig = crop_to_width(des, rsig, lsig_width); ivl_assert(*this, rsig->pin_count()==1); nex_out.pin(ptr).unlink(); enables.pin(ptr).unlink(); connect(nex_out.pin(ptr), rsig->pin(0)); connect(enables.pin(ptr), scope->tie_hi()); mask_t&bitmask = bitmasks[ptr]; if (is_part_select) { if (bitmask.size() == 0) { bitmask = mask_t (lsig_width, false); } ivl_assert(*this, bitmask.size() == lsig_width); for (unsigned idx = 0; idx < lval_width; idx += 1) { bitmask[base_off + idx] = true; } } else if (bitmask.size() > 0) { for (unsigned idx = 0; idx < bitmask.size(); idx += 1) { bitmask[idx] = true; } } else { bitmask = mask_t (lsig_width, true); } /* This lval_ represents a reg that is a WIRE in the synthesized results. This function signals the destructor to change the REG that this l-value refers to into a WIRE. It is done then, at the last minute, so that pending synthesis can continue to work with it as a REG. */ lval_->turn_sig_to_wire_on_release(); return true; } bool NetProc::synth_async_block_substatement_(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks, NetProc*substmt) { ivl_assert(*this, nex_map.size() == nex_out.pin_count()); ivl_assert(*this, nex_map.size() == enables.pin_count()); ivl_assert(*this, nex_map.size() == bitmasks.size()); // Create a temporary map of the output only from this statement. NexusSet tmp_map; substmt->nex_output(tmp_map); if (debug_synth2) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: " << "tmp_map.size()==" << tmp_map.size() << " for statement at " << substmt->get_fileline() << endl; for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: " << "incoming nex_out[" << idx << "] dump link" << endl; nex_out.pin(idx).dump_link(cerr, 8); } } // Create temporary variables to collect the output from the synthesis. NetBus tmp_out (scope, tmp_map.size()); NetBus tmp_ena (scope, tmp_map.size()); vector tmp_masks (tmp_map.size()); // Map (and move) the accumulated nex_out for this block // to the version that we can pass to the next statement. // We will move the result back later. for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) { unsigned ptr = nex_map.find_nexus(tmp_map[idx]); ivl_assert(*this, ptr < nex_out.pin_count()); connect(tmp_out.pin(idx), nex_out.pin(ptr)); nex_out.pin(ptr).unlink(); } if (debug_synth2) { for (unsigned idx = 0 ; idx < nex_map.size() ; idx += 1) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: nex_map[" << idx << "] dump link, base=" << nex_map[idx].base << ", wid=" << nex_map[idx].wid << endl; nex_map[idx].lnk.dump_link(cerr, 8); } for (unsigned idx = 0 ; idx < tmp_map.size() ; idx += 1) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: tmp_map[" << idx << "] dump link, base=" << tmp_map[idx].base << ", wid=" << tmp_map[idx].wid << endl; tmp_map[idx].lnk.dump_link(cerr, 8); } for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: tmp_out[" << idx << "] dump link" << endl; tmp_out.pin(idx).dump_link(cerr, 8); } } bool flag = substmt->synth_async(des, scope, tmp_map, tmp_out, tmp_ena, tmp_masks); if (debug_synth2) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: " "substmt->synch_async(...) --> " << (flag? "true" : "false") << " for statement at " << substmt->get_fileline() << "." << endl; } if (!flag) return false; // Now map the output from the substatement back to the // outputs for this block. for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) { unsigned ptr = nex_map.find_nexus(tmp_map[idx]); ivl_assert(*this, ptr < nex_out.pin_count()); if (debug_synth2) { cerr << get_fileline() << ": NetProc::synth_async_block_substatement_: " << "tmp_out.pin(" << idx << "):" << endl; tmp_out.pin(idx).dump_link(cerr, 8); } connect(nex_out.pin(ptr), tmp_out.pin(idx)); merge_sequential_enables(des, scope, enables.pin(ptr), tmp_ena.pin(idx)); merge_sequential_masks(bitmasks[ptr], tmp_masks[idx]); } return true; } /* * Sequential blocks are translated to asynchronous logic by * translating each statement of the block, in order, into gates. * The nex_out for the block is the union of the nex_out for all * the substatements. */ bool NetBlock::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { if (last_ == 0) { return true; } bool flag = true; NetProc*cur = last_; do { cur = cur->next_; bool sub_flag = synth_async_block_substatement_(des, scope, nex_map, nex_out, enables, bitmasks, cur); flag = flag && sub_flag; } while (cur != last_); return flag; } /* * This function is used to fix up a MUX selector to be no longer than * it needs to be. The general idea is that if the selector needs to * be only N bits, but is actually M bits, we translate it to this: * * osig = { |esig[M-1:N-1], esig[N-2:0] } * * This obviously implies that (N >= 2) and (M >= N). In the code * below, N is sel_need, and M is sel_got (= esig->vector_width()). */ static NetNet* mux_selector_reduce_width(Design*des, NetScope*scope, const LineInfo&loc, NetNet*esig, unsigned sel_need) { const unsigned sel_got = esig->vector_width(); ivl_assert(*esig, sel_got >= sel_need); // If the actual width matches the desired width (M==N) then // osig is esig itself. We're done. if (sel_got == sel_need) return esig; if (debug_synth2) { cerr << loc.get_fileline() << ": mux_selector_reduce_width: " << "Reduce selector width=" << sel_got << " to " << sel_need << " bits." << endl; } ivl_assert(*esig, sel_need >= 2); // This is the output signal, osig. ivl_variable_type_t osig_data_type = IVL_VT_LOGIC; netvector_t*osig_vec = new netvector_t(osig_data_type, sel_need-1, 0); NetNet*osig = new NetNet(scope, scope->local_symbol(), NetNet::TRI, osig_vec); osig->local_flag(true); osig->set_line(loc); // Create the concat: osig = {...,...} NetConcat*osig_cat = new NetConcat(scope, scope->local_symbol(), sel_need, 2, !disable_concatz_generation); osig_cat->set_line(loc); des->add_node(osig_cat); connect(osig_cat->pin(0), osig->pin(0)); // Create the part select esig[N-2:0]... NetPartSelect*ps0 = new NetPartSelect(esig, 0, sel_need-1, NetPartSelect::VP); ps0->set_line(loc); des->add_node(ps0); connect(ps0->pin(1), esig->pin(0)); netvector_t*ps0_vec = new netvector_t(osig_data_type, sel_need-2, 0); NetNet*ps0_sig = new NetNet(scope, scope->local_symbol(), NetNet::TRI, ps0_vec); ps0_sig->local_flag(true); ps0_sig->set_line(loc); connect(ps0_sig->pin(0), ps0->pin(0)); // osig = {..., esig[N-2:0]} connect(osig_cat->pin(1), ps0_sig->pin(0)); // Create the part select esig[M-1:N-1] NetPartSelect*ps1 = new NetPartSelect(esig, sel_need-1, sel_got-sel_need+1, NetPartSelect::VP); ps1->set_line(loc); des->add_node(ps1); connect(ps1->pin(1), esig->pin(0)); netvector_t*ps1_vec = new netvector_t(osig_data_type, sel_got-sel_need, 0); NetNet*ps1_sig = new NetNet(scope, scope->local_symbol(), NetNet::TRI, ps1_vec); ps1_sig->local_flag(true); ps1_sig->set_line(loc); connect(ps1_sig->pin(0), ps1->pin(0)); // Create the reduction OR: | esig[M-1:N-1] NetUReduce*ered = new NetUReduce(scope, scope->local_symbol(), NetUReduce::OR, sel_got-sel_need+1); ered->set_line(loc); des->add_node(ered); connect(ered->pin(1), ps1_sig->pin(0)); NetNet*ered_sig = new NetNet(scope, scope->local_symbol(), NetNet::TRI, &netvector_t::scalar_logic); ered_sig->local_flag(true); ered_sig->set_line(loc); connect(ered->pin(0), ered_sig->pin(0)); // osig = { |esig[M-1:N-1], esig[N-2:0] } connect(osig_cat->pin(2), ered_sig->pin(0)); return osig; } bool NetCase::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { if (type()==NetCase::EQZ || type()==NetCase::EQX) return synth_async_casez_(des, scope, nex_map, nex_out, enables, bitmasks); // Special case: If the case expression is constant, then this // is a pattern where the guards are non-constant and tested // against a constant case. Handle this as chained conditions // instead. if (dynamic_cast (expr_)) return synth_async_casez_(des, scope, nex_map, nex_out, enables, bitmasks); ivl_assert(*this, nex_map.size() == nex_out.pin_count()); ivl_assert(*this, nex_map.size() == enables.pin_count()); ivl_assert(*this, nex_map.size() == bitmasks.size()); if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "Selector expression: " << *expr_ << endl; } /* Synthesize the select expression. */ NetNet*esig = expr_->synthesize(des, scope, expr_); unsigned sel_width = esig->vector_width(); ivl_assert(*this, sel_width > 0); if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "selector width (sel_width) = " << sel_width << endl; } vector mux_width (nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { mux_width[idx] = nex_map[idx].wid; if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "idx=" << idx << ", mux_width[idx]=" << mux_width[idx] << endl; } } // The incoming nex_out is taken as the input for this // statement. Since there are collection of statements // that start at this same point, we save all these // inputs and reuse them for each statement. Unlink the // nex_out now, so we can hook up the mux outputs. NetBus statement_input (scope, nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { connect(statement_input.pin(idx), nex_out.pin(idx)); nex_out.pin(idx).unlink(); if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "statement_input.pin(" << idx << "):" << endl; statement_input.pin(idx).dump_link(cerr, 8); } } /* Collect all the statements into a map of index to statement. The guard expression it evaluated to be the index of the mux value, and the statement is bound to that index. */ unsigned long max_guard_value = 0; mapstatement_map; NetProc*default_statement = 0; for (size_t item = 0 ; item < items_.size() ; item += 1) { if (items_[item].guard == 0) { default_statement = items_[item].statement; continue; } NetEConst*ge = dynamic_cast(items_[item].guard); if (ge == 0) { cerr << items_[item].guard->get_fileline() << ": sorry: " << "variable case item expressions with a variable " << "case select expression are not supported in " << "synthesis. " << endl; des->errors += 1; return false; } ivl_assert(*this, ge); verinum gval = ge->value(); unsigned long sel_idx = gval.as_ulong(); if (statement_map[sel_idx]) { cerr << ge->get_fileline() << ": warning: duplicate case " << "value '" << sel_idx << "' detected. This case is " << "unreachable." << endl; delete items_[item].statement; items_[item].statement = 0; continue; } if (sel_idx > max_guard_value) max_guard_value = sel_idx; if (items_[item].statement) { statement_map[sel_idx] = items_[item].statement; continue; } // Handle the special case of an empty statement. statement_map[sel_idx] = this; } // The minimum selector width is the number of inputs that // are selected, rounded up to the nearest power of 2. unsigned sel_need = max(ceil(log2(max_guard_value + 1)), 1.0); // If the sel_width can select more than just the explicit // guard values, and there is a default statement, then adjust // the sel_need to allow for the implicit selections. if (default_statement && (sel_width > sel_need)) sel_need += 1; // The mux size is always an exact power of 2. if (sel_need >= 8*sizeof(unsigned)) { cerr << get_fileline() << ": sorry: mux select width of " << sel_need << " bits is too large for synthesis." << endl; des->errors += 1; return false; } unsigned mux_size = 1U << sel_need; if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "Adjusted mux_size is " << mux_size << " (max_guard_value=" << max_guard_value << ", sel_need=" << sel_need << ", sel_width=" << sel_width << ")." << endl; } if (sel_width > sel_need) { if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "Selector is " << sel_width << " bits, " << "need only " << sel_need << " bits." << endl; } esig = mux_selector_reduce_width(des, scope, *this, esig, sel_need); } /* If there is a default clause, synthesize it once and we'll link it in wherever it is needed. If there isn't, create a dummy default to pass on the accumulated nex_out from preceding statements. */ NetBus default_out (scope, nex_out.pin_count()); NetBus default_ena (scope, nex_out.pin_count()); vector default_masks (nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { connect(default_out.pin(idx), statement_input.pin(idx)); connect(default_ena.pin(idx), scope->tie_lo()); } if (default_statement) { bool flag = synth_async_block_substatement_(des, scope, nex_map, default_out, default_ena, default_masks, default_statement); if (!flag) return false; if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async: " << "synthesize default clause at " << default_statement->get_fileline() << " is done." << endl; } } vector out_mux (nex_out.pin_count()); vector ena_mux (nex_out.pin_count()); vector full_case (nex_out.pin_count()); for (size_t mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { out_mux[mdx] = new NetMux(scope, scope->local_symbol(), mux_width[mdx], mux_size, sel_need); des->add_node(out_mux[mdx]); // The select signal is already synthesized, and is // common for every mux of this case statement. Simply // hook it up. connect(out_mux[mdx]->pin_Sel(), esig->pin(0)); // The outputs are in the nex_out, and connected to the // mux Result pins. connect(out_mux[mdx]->pin_Result(), nex_out.pin(mdx)); // Make sure the output is now connected to a net. If // not, then create a fake one to carry the net-ness of // the pin. if (out_mux[mdx]->pin_Result().nexus()->pick_any_net() == 0) { ivl_variable_type_t mux_data_type = IVL_VT_LOGIC; netvector_t*tmp_vec = new netvector_t(mux_data_type, mux_width[mdx]-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->local_flag(true); ivl_assert(*this, tmp->vector_width() != 0); connect(out_mux[mdx]->pin_Result(), tmp->pin(0)); } // Create a mux for the enables, but don't hook it up // until we know we need it. ena_mux[mdx] = new NetMux(scope, scope->local_symbol(), 1, mux_size, sel_need); // Assume a full case to start with. We'll check this as // we synthesise each clause. full_case[mdx] = true; } for (unsigned idx = 0 ; idx < mux_size ; idx += 1) { NetProc*stmt = statement_map[idx]; if (stmt==0) { ivl_assert(*this, default_out.pin_count() == out_mux.size()); for (unsigned mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { connect(out_mux[mdx]->pin_Data(idx), default_out.pin(mdx)); connect(ena_mux[mdx]->pin_Data(idx), default_ena.pin(mdx)); merge_parallel_masks(bitmasks[mdx], default_masks[mdx]); if (!default_ena.pin(mdx).is_linked(scope->tie_hi())) full_case[mdx] = false; } continue; } ivl_assert(*this, stmt); if (stmt == this) { // Handle the special case of an empty statement. ivl_assert(*this, statement_input.pin_count() == out_mux.size()); for (unsigned mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { connect(out_mux[mdx]->pin_Data(idx), statement_input.pin(mdx)); connect(ena_mux[mdx]->pin_Data(idx), scope->tie_lo()); bitmasks[mdx] = mask_t (mux_width[mdx], false); full_case[mdx] = false; } continue; } NetBus tmp_out (scope, nex_out.pin_count()); NetBus tmp_ena (scope, nex_out.pin_count()); for (unsigned mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { connect(tmp_out.pin(mdx), statement_input.pin(mdx)); connect(tmp_ena.pin(mdx), scope->tie_lo()); } vector tmp_masks (nex_out.pin_count()); bool flag = synth_async_block_substatement_(des, scope, nex_map, tmp_out, tmp_ena, tmp_masks, stmt); if (!flag) return false; for (size_t mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { connect(out_mux[mdx]->pin_Data(idx), tmp_out.pin(mdx)); connect(ena_mux[mdx]->pin_Data(idx), tmp_ena.pin(mdx)); merge_parallel_masks(bitmasks[mdx], tmp_masks[mdx]); if (!tmp_ena.pin(mdx).is_linked(scope->tie_hi())) full_case[mdx] = false; } } for (unsigned mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { // Optimize away the enable mux if we have a full case, // otherwise hook it up. if (full_case[mdx]) { connect(enables.pin(mdx), scope->tie_hi()); delete ena_mux[mdx]; continue; } des->add_node(ena_mux[mdx]); connect(ena_mux[mdx]->pin_Sel(), esig->pin(0)); connect(enables.pin(mdx), ena_mux[mdx]->pin_Result()); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, &netvector_t::scalar_logic); tmp->local_flag(true); connect(ena_mux[mdx]->pin_Result(), tmp->pin(0)); } return true; } /* * casez statements are hard to implement as a single wide mux because * the test doesn't really map to a select input. Instead, implement * it as a chain of binary muxes. This gives the synthesizer more * flexibility, and is more typically what is desired from a casez anyhow. */ bool NetCase::synth_async_casez_(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { ivl_assert(*this, nex_map.size() == nex_out.pin_count()); ivl_assert(*this, nex_map.size() == enables.pin_count()); ivl_assert(*this, nex_map.size() == bitmasks.size()); /* Synthesize the select expression. */ NetNet*esig = expr_->synthesize(des, scope, expr_); unsigned sel_width = esig->vector_width(); ivl_assert(*this, sel_width > 0); vectormux_width (nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { mux_width[idx] = nex_map[idx].wid; if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async_casez_: " << "idx=" << idx << ", mux_width[idx]=" << mux_width[idx] << endl; } } // The incoming nex_out is taken as the input for this // statement. Since there are collection of statements // that start at this same point, we save all these // inputs and reuse them for each statement. Unlink the // nex_out now, so we can hook up the mux outputs. NetBus statement_input (scope, nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { connect(statement_input.pin(idx), nex_out.pin(idx)); nex_out.pin(idx).unlink(); if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async_casez_: " << "statement_input.pin(" << idx << "):" << endl; statement_input.pin(idx).dump_link(cerr, 8); } } // Look for a default statement. NetProc*default_statement = 0; for (size_t item = 0 ; item < items_.size() ; item += 1) { if (items_[item].guard != 0) continue; ivl_assert(*this, default_statement==0); default_statement = items_[item].statement; } /* If there is a default clause, synthesize it once and we'll link it in wherever it is needed. If there isn't, create a dummy default to pass on the accumulated nex_out from preceding statements. */ NetBus default_out (scope, nex_out.pin_count()); for (unsigned idx = 0 ; idx < default_out.pin_count() ; idx += 1) connect(default_out.pin(idx), statement_input.pin(idx)); if (default_statement) { bool flag = synth_async_block_substatement_(des, scope, nex_map, default_out, enables, bitmasks, default_statement); if (!flag) return false; if (debug_synth2) { cerr << get_fileline() << ": NetCase::synth_async_casez_: " << "synthesize default clause at " << default_statement->get_fileline() << " is done." << endl; } } netvector_t*condit_type = new netvector_t(IVL_VT_LOGIC, 0, 0); NetCaseCmp::kind_t case_kind = NetCaseCmp::EEQ; switch (type()) { case NetCase::EQ: case_kind = NetCaseCmp::EEQ; break; case NetCase::EQX: case_kind = NetCaseCmp::XEQ; break; case NetCase::EQZ: case_kind = NetCaseCmp::ZEQ; break; default: assert(0); } // Process the items from last to first. We generate a // true/false mux, with the select being the comparison of // the case select with the guard expression. The true input // (data1) is the current statement, and the false input is // the result of a later statement. vectorprev_mux (nex_out.pin_count()); for (size_t idx = 0 ; idx < items_.size() ; idx += 1) { size_t item = items_.size()-idx-1; if (items_[item].guard == 0) continue; NetProc*stmt = items_[item].statement; ivl_assert(*this, stmt); NetExpr*guard_expr = items_[item].guard; NetNet*guard = guard_expr->synthesize(des, scope, guard_expr); NetCaseCmp*condit_dev = new NetCaseCmp(scope, scope->local_symbol(), sel_width, case_kind); des->add_node(condit_dev); condit_dev->set_line(*this); // Note that the expression that may have wildcards must // go in the pin(2) input. This is the definition of the // NetCaseCmp statement. connect(condit_dev->pin(1), esig->pin(0)); connect(condit_dev->pin(2), guard->pin(0)); NetNet*condit = new NetNet(scope, scope->local_symbol(), NetNet::TRI, condit_type); condit->set_line(*this); condit->local_flag(true); connect(condit_dev->pin(0), condit->pin(0)); // Synthesize the guarded statement. NetBus tmp_out (scope, nex_out.pin_count()); NetBus tmp_ena (scope, nex_out.pin_count()); vector tmp_masks (nex_out.pin_count()); for (unsigned pdx = 0 ; pdx < nex_out.pin_count() ; pdx += 1) connect(tmp_out.pin(pdx), statement_input.pin(pdx)); synth_async_block_substatement_(des, scope, nex_map, tmp_out, tmp_ena, tmp_masks, stmt); NetBus prev_ena (scope, nex_out.pin_count()); for (unsigned mdx = 0 ; mdx < nex_out.pin_count() ; mdx += 1) { NetMux*mux = new NetMux(scope, scope->local_symbol(), mux_width[mdx], 2, 1); des->add_node(mux); mux->set_line(*this); connect(mux->pin_Sel(), condit->pin(0)); connect(mux->pin_Data(1), tmp_out.pin(mdx)); // If there is a previous mux, then use that as the // false clause input. Otherwise, use the default. if (prev_mux[mdx]) connect(mux->pin_Data(0), prev_mux[mdx]->pin_Result()); else connect(mux->pin_Data(0), default_out.pin(mdx)); // Make a NetNet for the result. ivl_variable_type_t mux_data_type = IVL_VT_LOGIC; netvector_t*tmp_vec = new netvector_t(mux_data_type, mux_width[mdx]-1,0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, tmp_vec); tmp->local_flag(true); tmp->set_line(*this); ivl_assert(*this, tmp->vector_width() != 0); connect(mux->pin_Result(), tmp->pin(0)); // This mux becomes the "false" input to the next mux. prev_mux[mdx] = mux; connect(prev_ena.pin(mdx), enables.pin(mdx)); enables.pin(mdx).unlink(); multiplex_enables(des, scope, condit, tmp_ena.pin(mdx), prev_ena.pin(mdx), enables.pin(mdx)); merge_parallel_masks(bitmasks[mdx], tmp_masks[mdx]); } } // Connect the last mux to the output. for (size_t mdx = 0 ; mdx < prev_mux.size() ; mdx += 1) connect(prev_mux[mdx]->pin_Result(), nex_out.pin(mdx)); return true; } /* * A condit statement (if (cond) ... else ... ;) infers an A-B mux, * with the cond expression acting as a select input. If the cond * expression is true, the if_ clause is selected, and if false, the * else_ clause is selected. */ bool NetCondit::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { // Handle the unlikely case that both clauses are empty. if ((if_ == 0) && (else_ == 0)) return true; ivl_assert(*this, nex_map.size() == nex_out.pin_count()); ivl_assert(*this, nex_map.size() == enables.pin_count()); ivl_assert(*this, nex_map.size() == bitmasks.size()); // Synthesize the condition. This will act as a select signal // for a binary mux. NetNet*ssig = expr_->synthesize(des, scope, expr_); ivl_assert(*this, ssig); // The incoming nex_out is taken as the input for this // statement. Since there are two statements that start // at this same point, we save all these inputs and reuse // them for both statements. Unlink the nex_out now, so // we can hook up the mux outputs. NetBus statement_input (scope, nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { connect(statement_input.pin(idx), nex_out.pin(idx)); nex_out.pin(idx).unlink(); if (debug_synth2) { cerr << get_fileline() << ": NetCondit::synth_async: " << "statement_input.pin(" << idx << "):" << endl; statement_input.pin(idx).dump_link(cerr, 8); } } NetBus a_out (scope, nex_out.pin_count()); NetBus a_ena (scope, nex_out.pin_count()); vector a_masks (nex_out.pin_count()); if (if_) { if (debug_synth2) { cerr << get_fileline() << ": NetCondit::synth_async: " << "Synthesize if clause at " << if_->get_fileline() << endl; } for (unsigned idx = 0 ; idx < a_out.pin_count() ; idx += 1) { connect(a_out.pin(idx), statement_input.pin(idx)); } bool flag = synth_async_block_substatement_(des, scope, nex_map, a_out, a_ena, a_masks, if_); if (!flag) return false; } else { for (unsigned idx = 0 ; idx < a_out.pin_count() ; idx += 1) { connect(a_out.pin(idx), statement_input.pin(idx)); connect(a_ena.pin(idx), scope->tie_lo()); } } NetBus b_out(scope, nex_out.pin_count()); NetBus b_ena(scope, nex_out.pin_count()); vector b_masks (nex_out.pin_count()); if (else_) { if (debug_synth2) { cerr << get_fileline() << ": NetCondit::synth_async: " << "Synthesize else clause at " << else_->get_fileline() << endl; } for (unsigned idx = 0 ; idx < b_out.pin_count() ; idx += 1) { connect(b_out.pin(idx), statement_input.pin(idx)); } bool flag = synth_async_block_substatement_(des, scope, nex_map, b_out, b_ena, b_masks, else_); if (!flag) return false; } else { for (unsigned idx = 0 ; idx < b_out.pin_count() ; idx += 1) { connect(b_out.pin(idx), statement_input.pin(idx)); connect(b_ena.pin(idx), scope->tie_lo()); } } /* The nex_out output, a_out input, and b_out input all have the same pin count (usually, but not always 1) because they are net arrays of the same dimension. The for loop below creates a NetMux for each pin of the output. (Note that pins may be, in fact usually are, vectors.) */ for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { bool a_driven = a_out.pin(idx).nexus()->pick_any_net(); bool b_driven = b_out.pin(idx).nexus()->pick_any_net(); if (!a_driven && !b_driven) { connect(nex_out.pin(idx), statement_input.pin(idx)); continue; } merge_parallel_masks(bitmasks[idx], a_masks[idx]); merge_parallel_masks(bitmasks[idx], b_masks[idx]); // If one clause is empty and the other clause unconditionally // drives all bits of the vector, we can rely on the enable // to prevent the flip-flop or latch updating when the empty // clause is selected, and hence don't need a mux. if (!a_driven && all_bits_driven(b_masks[idx])) { connect(nex_out.pin(idx), b_out.pin(idx)); continue; } if (!b_driven && all_bits_driven(a_masks[idx])) { connect(nex_out.pin(idx), a_out.pin(idx)); continue; } // Guess the mux type from the type of the output. ivl_variable_type_t mux_data_type = IVL_VT_LOGIC; if (NetNet*tmp = nex_out.pin(idx).nexus()->pick_any_net()) { mux_data_type = tmp->data_type(); } unsigned mux_off = 0; unsigned mux_width = nex_map[idx].wid; if (debug_synth2) { cerr << get_fileline() << ": NetCondit::synth_async: " << "Calculated mux_width=" << mux_width << endl; } NetPartSelect*apv = detect_partselect_lval(a_out.pin(idx)); if (debug_synth2 && apv) { cerr << get_fileline() << ": NetCondit::synth_async: " << "Assign-to-part apv base=" << apv->base() << ", width=" << apv->width() << endl; } NetPartSelect*bpv = detect_partselect_lval(b_out.pin(idx)); if (debug_synth2 && bpv) { cerr << get_fileline() << ": NetCondit::synth_async: " << "Assign-to-part bpv base=" << bpv->base() << ", width=" << bpv->width() << endl; } unsigned mux_lwidth = mux_width; ivl_assert(*this, mux_width != 0); if (apv && bpv && apv->width()==bpv->width() && apv->base()==bpv->base()) { // The a and b sides are both assigning to the // same bits of the output, so we can use that to // create a much narrower mux that only // manipulates the width of the part. mux_width = apv->width(); mux_off = apv->base(); a_out.pin(idx).unlink(); b_out.pin(idx).unlink(); connect(a_out.pin(idx), apv->pin(0)); connect(b_out.pin(idx), bpv->pin(0)); delete apv; delete bpv; } else { // The part selects are of no use. Forget them. apv = 0; bpv = 0; } NetMux*mux = new NetMux(scope, scope->local_symbol(), mux_width, 2, 1); mux->set_line(*this); des->add_node(mux); netvector_t*tmp_type = 0; if (mux_width==1) tmp_type = new netvector_t(mux_data_type); else tmp_type = new netvector_t(mux_data_type, mux_width-1,0); // Bind some temporary signals to carry pin type. NetNet*otmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); otmp->local_flag(true); otmp->set_line(*this); connect(mux->pin_Result(),otmp->pin(0)); connect(mux->pin_Sel(), ssig->pin(0)); connect(mux->pin_Data(1), a_out.pin(idx)); connect(mux->pin_Data(0), b_out.pin(idx)); // If we are only muxing a part of the output vector, make a // NetSubstitute to blend the mux output with the accumulated // output from previous statements. if (mux_width < mux_lwidth) { tmp_type = new netvector_t(mux_data_type, mux_lwidth-1,0); NetNet*itmp = statement_input.pin(idx).nexus()->pick_any_net(); if (itmp == 0) { itmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); itmp->local_flag(true); itmp->set_line(*this); connect(itmp->pin(0), statement_input.pin(idx)); } NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, NetNet::not_an_array, tmp_type); tmp->local_flag(true); tmp->set_line(*this); NetSubstitute*ps = new NetSubstitute(itmp, otmp, mux_lwidth, mux_off); des->add_node(ps); connect(ps->pin(0), tmp->pin(0)); otmp = tmp; } connect(nex_out.pin(idx), otmp->pin(0)); } for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { multiplex_enables(des, scope, ssig, a_ena.pin(idx), b_ena.pin(idx), enables.pin(idx)); } return true; } bool NetEvWait::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { bool flag = statement_->synth_async(des, scope, nex_map, nex_out, enables, bitmasks); return flag; } bool NetForLoop::synth_async(Design*des, NetScope*scope, NexusSet&nex_map, NetBus&nex_out, NetBus&enables, vector&bitmasks) { if (!index_) { cerr << get_fileline() << ": sorry: Unable to synthesize for-loop without explicit index variable." << endl; return false; } if (!step_statement_) { cerr << get_fileline() << ": sorry: Unable to synthesize for-loop without for_step statement." << endl; return false; } ivl_assert(*this, index_ && init_expr_); if (debug_synth2) { cerr << get_fileline() << ": NetForLoop::synth_async: " << "Index variable is " << index_->name() << endl; cerr << get_fileline() << ": NetForLoop::synth_async: " << "Initialization expression: " << *init_expr_ << endl; } // Get the step assignment statement and break it into the // l-value (should be the index) and the r-value, which is the // step expressions. NetAssign*step_assign = dynamic_cast (step_statement_); char assign_operator = step_assign->assign_operator(); ivl_assert(*this, step_assign); NetExpr*step_expr = step_assign->rval(); // Tell the scope that this index value is like a genvar. LocalVar index_var; index_var.nwords = 0; map index_args; // Calculate the initial value for the index. index_var.value = init_expr_->evaluate_function(*this, index_args); ivl_assert(*this, index_var.value); index_args[index_->name()] = index_var; for (;;) { // Evaluate the condition expression. If it is false, // then we are going to break out of this synthesis loop. NetExpr*tmp = condition_->evaluate_function(*this, index_args); ivl_assert(*this, tmp); long cond_value; bool rc = eval_as_long(cond_value, tmp); ivl_assert(*this, rc); delete tmp; if (!cond_value) break; scope->genvar_tmp = index_->name(); rc = eval_as_long(scope->genvar_tmp_val, index_var.value); ivl_assert(*this, rc); if (debug_synth2) { cerr << get_fileline() << ": NetForLoop::synth_async: " << "Synthesis iteration with " << index_->name() << "=" << *index_var.value << endl; } // Synthesize the iterated expression. Stash the loop // index value so that the substatements can see this // value and use it during its own synthesis. ivl_assert(*this, scope->loop_index_tmp.empty()); scope->loop_index_tmp = index_args; NetBus tmp_ena (scope, nex_out.pin_count()); vector tmp_masks (nex_out.pin_count()); rc = synth_async_block_substatement_(des, scope, nex_map, nex_out, tmp_ena, tmp_masks, statement_); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) { merge_sequential_enables(des, scope, enables.pin(idx), tmp_ena.pin(idx)); merge_sequential_masks(bitmasks[idx], tmp_masks[idx]); } scope->loop_index_tmp.clear(); // Evaluate the step_expr to generate the next index value. tmp = step_expr->evaluate_function(*this, index_args); ivl_assert(*this, tmp); // If there is an assign_operator, then replace the // index_var.value with (value tmp) and evaluate // that to get the next value. "value" is the existing // value, and "tmp" is the step value. We are replacing // (value += tmp) with (value = value + tmp) and // evaluating it. switch (assign_operator) { case 0: break; case '+': case '-': index_var.value = new NetEBAdd(assign_operator, tmp, index_var.value, 32, true); tmp = index_var.value->evaluate_function(*this, index_args); break; default: cerr << get_fileline() << ": internal error: " << "NetForLoop::synth_async: What to do with assign_operator=" << assign_operator << endl; ivl_assert(*this, 0); } delete index_var.value; index_var.value = tmp; index_args[index_->name()] = index_var; } delete index_var.value; return true; } /* * This method is called when the process is shown to be * asynchronous. Figure out the nexus set of outputs from this * process, and pass that to the synth_async method for the statement * of the process. The statement will connect its output to the * nex_out set, using the nex_map as a guide. Starting from the top, * the nex_map is the same as the nex_map. */ bool NetProcTop::synth_async(Design*des) { NexusSet nex_set; statement_->nex_output(nex_set); if (debug_synth2) { cerr << get_fileline() << ": NetProcTop::synth_async: " << "Process has " << nex_set.size() << " outputs." << endl; } NetBus nex_out (scope(), nex_set.size()); NetBus enables (scope(), nex_set.size()); vector bitmasks (nex_set.size()); // Save links to the initial nex_out. These will be used later // to detect floating part-substitute and mux inputs that need // to be tied off. NetBus nex_in (scope(), nex_out.pin_count()); for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) connect(nex_in.pin(idx), nex_out.pin(idx)); bool flag = statement_->synth_async(des, scope(), nex_set, nex_out, enables, bitmasks); if (!flag) return false; flag = tie_off_floating_inputs_(des, nex_set, nex_in, bitmasks, false); if (!flag) return false; for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) { if (enables.pin(idx).is_linked(scope()->tie_hi())) { connect(nex_set[idx].lnk, nex_out.pin(idx)); } else { cerr << get_fileline() << ": warning: " << "A latch has been inferred for '" << nex_set[idx].lnk.nexus()->pick_any_net()->name() << "'." << endl; if (enables.pin(idx).nexus()->pick_any_net()->local_flag()) { cerr << get_fileline() << ": warning: The latch " "enable is connected to a synthesized " "expression. The latch may be sensitive " "to glitches." << endl; } if (debug_synth2) { cerr << get_fileline() << ": debug: " << "Top level making a " << nex_set[idx].wid << "-wide " << "NetLatch device." << endl; } NetLatch*latch = new NetLatch(scope(), scope()->local_symbol(), nex_set[idx].wid); des->add_node(latch); latch->set_line(*this); NetNet*tmp = nex_out.pin(idx).nexus()->pick_any_net(); tmp->set_line(*this); assert(tmp); tmp = crop_to_width(des, tmp, latch->width()); connect(nex_set[idx].lnk, latch->pin_Q()); connect(tmp->pin(0), latch->pin_Data()); assert (enables.pin(idx).is_linked()); connect(enables.pin(idx), latch->pin_Enable()); } } synthesized_design_ = des; return true; } bool NetProc::synth_sync(Design*des, NetScope*scope, bool& /* ff_negedge */, NetNet* /* ff_clk */, NetBus&ff_ce, NetBus& /* ff_aclr*/, NetBus& /* ff_aset*/, vector& /*ff_aset_value*/, NexusSet&nex_map, NetBus&nex_out, vector&bitmasks, const vector&events) { if (events.size() > 0) { cerr << get_fileline() << ": error: Events are unaccounted" << " for in process synthesis." << endl; des->errors += 1; } if (debug_synth2) { cerr << get_fileline() << ": NetProc::synth_sync: " << "This statement is an async input to a sync process." << endl; } /* Synthesize the input to the DFF. */ return synth_async(des, scope, nex_map, nex_out, ff_ce, bitmasks); } /* * This method is called when a block is encountered near the surface * of a synchronous always statement. For example, this code will be * invoked for input like this: * * always @(posedge clk...) begin * * * ... * end * * This needs to be split into a DFF bank for each statement, because * the statements may each infer different reset and enables signals. */ bool NetBlock::synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, vector&bitmasks, const vector&events_in) { if (debug_synth2) { cerr << get_fileline() << ": NetBlock::synth_sync: " << "Examine this block for synchronous logic." << endl; } if (last_ == 0) { return true; } bool flag = true; NetProc*cur = last_; do { cur = cur->next_; // Create a temporary nex_map for the substatement. NexusSet tmp_map; cur->nex_output(tmp_map); // Create temporary variables to collect the output from the synthesis. NetBus tmp_out (scope, tmp_map.size()); NetBus tmp_ce (scope, tmp_map.size()); vector tmp_masks (tmp_map.size()); // Map (and move) the accumulated nex_out for this block // to the version that we can pass to the next statement. // We will move the result back later. for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) { unsigned ptr = nex_map.find_nexus(tmp_map[idx]); ivl_assert(*this, ptr < nex_out.pin_count()); connect(tmp_out.pin(idx), nex_out.pin(ptr)); nex_out.pin(ptr).unlink(); } /* Now go on with the synchronous synthesis for this subset of the statement. The tmp_map is the output nexa that we expect, and the tmp_out is where we want those outputs connected. */ bool ok_flag = cur->synth_sync(des, scope, ff_negedge, ff_clk, tmp_ce, ff_aclr, ff_aset, ff_aset_value, tmp_map, tmp_out, tmp_masks, events_in); flag = flag && ok_flag; if (ok_flag == false) continue; // Now map the output from the substatement back to the // outputs for this block. for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) { unsigned ptr = nex_map.find_nexus(tmp_map[idx]); ivl_assert(*this, ptr < nex_out.pin_count()); connect(nex_out.pin(ptr), tmp_out.pin(idx)); merge_sequential_enables(des, scope, ff_ce.pin(ptr), tmp_ce.pin(idx)); merge_sequential_masks(bitmasks[ptr], tmp_masks[idx]); } } while (cur != last_); if (debug_synth2) { cerr << get_fileline() << ": NetBlock::synth_sync: " << "Done Examining this block for synchronous logic." << endl; } return flag; } /* * This method handles the case where I find a conditional near the * surface of a synchronous thread. This conditional can be a CE or an * asynchronous set/reset, depending on whether the pin of the * expression is connected to an event, or not. */ bool NetCondit::synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, vector&bitmasks, const vector&events_in) { /* First try to turn the condition expression into an asynchronous set/reset. If the condition expression has inputs that are included in the sensitivity list, then it is likely intended as an asynchronous input. */ NexusSet*expr_input = expr_->nex_input(); assert(expr_input); for (unsigned idx = 0 ; idx < events_in.size() ; idx += 1) { NetEvProbe*ev = events_in[idx]; NexusSet pin_set; pin_set.add(ev->pin(0).nexus(), 0, 0); if (! expr_input->contains(pin_set)) continue; // Synthesize the set/reset input expression. NetNet*rst = expr_->synthesize(des, scope, expr_); ivl_assert(*this, rst->pin_count() == 1); // Check that the edge used on the set/reset input is correct. switch (ev->edge()) { case NetEvProbe::POSEDGE: if (ev->pin(0).nexus() != rst->pin(0).nexus()) { cerr << get_fileline() << ": error: " << "Condition for posedge asynchronous set/reset " << "must exactly match the event expression." << endl; des->errors += 1; return false; } break; case NetEvProbe::NEGEDGE: { bool is_inverter = false; NetNode*node = rst->pin(0).nexus()->pick_any_node(); if (NetLogic*gate = dynamic_cast(node)) { if (gate->type() == NetLogic::NOT) is_inverter = true; } if (NetUReduce*gate = dynamic_cast(node)) { if (gate->type() == NetUReduce::NOR) is_inverter = true; } if (!is_inverter || ev->pin(0).nexus() != node->pin(1).nexus()) { cerr << get_fileline() << ": error: " << "Condition for negedge asynchronous set/reset must be " << "a simple inversion of the event expression." << endl; des->errors += 1; return false; } break; } default: cerr << get_fileline() << ": error: " << "Asynchronous set/reset event must be " << "edge triggered." << endl; des->errors += 1; return false; } // Synthesize the true clause to figure out what kind of // set/reset we have. This should synthesize down to a // constant. If not, we have an asynchronous LOAD, a // very different beast. ivl_assert(*this, if_); NetBus tmp_out(scope, nex_out.pin_count()); NetBus tmp_ena(scope, nex_out.pin_count()); vector tmp_masks (nex_out.pin_count()); bool flag = if_->synth_async(des, scope, nex_map, tmp_out, tmp_ena, tmp_masks); if (!flag) return false; ivl_assert(*this, tmp_out.pin_count() == ff_aclr.pin_count()); ivl_assert(*this, tmp_out.pin_count() == ff_aset.pin_count()); for (unsigned pin = 0 ; pin < tmp_out.pin_count() ; pin += 1) { Nexus*rst_nex = tmp_out.pin(pin).nexus(); if (!all_bits_driven(tmp_masks[pin])) { cerr << get_fileline() << ": sorry: Not all bits of '" << nex_map[pin].lnk.nexus()->pick_any_net()->name() << "' are asynchronously set or reset. This is " << "not currently supported in synthesis." << endl; des->errors += 1; return false; } if (! rst_nex->drivers_constant() || ! tmp_ena.pin(pin).is_linked(scope->tie_hi()) ) { cerr << get_fileline() << ": sorry: Asynchronous load " << "is not currently supported in synthesis." << endl; des->errors += 1; return false; } if (ff_aclr.pin(pin).is_linked() || ff_aset.pin(pin).is_linked()) { cerr << get_fileline() << ": sorry: More than " "one asynchronous set/reset clause is " "not currently supported in synthesis." << endl; des->errors += 1; return false; } verinum rst_drv = rst_nex->driven_vector(); verinum zero (verinum::V0, rst_drv.len()); verinum ones (verinum::V1, rst_drv.len()); if (rst_drv==zero) { // Don't yet support multiple asynchronous reset inputs. ivl_assert(*this, ! ff_aclr.pin(pin).is_linked()); ivl_assert(*this, rst->pin_count()==1); connect(ff_aclr.pin(pin), rst->pin(0)); } else { // Don't yet support multiple asynchronous set inputs. ivl_assert(*this, ! ff_aset.pin(pin).is_linked()); ivl_assert(*this, rst->pin_count()==1); connect(ff_aset.pin(pin), rst->pin(0)); if (rst_drv!=ones) ff_aset_value[pin] = rst_drv; } } if (else_ == 0) return true; vector events; for (unsigned jdx = 0 ; jdx < events_in.size() ; jdx += 1) { if (jdx != idx) events.push_back(events_in[jdx]); } return else_->synth_sync(des, scope, ff_negedge, ff_clk, ff_ce, ff_aclr, ff_aset, ff_aset_value, nex_map, nex_out, bitmasks, events); } delete expr_input; #if 0 /* Detect the case that this is a *synchronous* set/reset. It is not asynchronous because we know the condition is not included in the sensitivity list, but if the if_ case is constant (has no inputs) then we can model this as a synchronous set/reset. This is only synchronous set/reset if there is a true and a false clause, and no inputs. The "no inputs" requirement is met if the assignments are of all constant values. */ assert(if_ != 0); NexusSet*a_set = if_->nex_input(); if ((a_set->count() == 0) && if_ && else_) { NetNet*rst = expr_->synthesize(des); assert(rst->pin_count() == 1); /* Synthesize the true clause to figure out what kind of set/reset we have. */ NetNet*asig = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, nex_map->pin_count()); asig->local_flag(true); bool flag = if_->synth_async(des, scope, nex_map, asig); if (!flag) { /* This path leads nowhere */ delete asig; } else { assert(asig->pin_count() == ff->width()); /* Collect the set/reset value into a verinum. If this turns out to be entirely 0 values, then use the Sclr input. Otherwise, use the Aset input and save the set value. */ verinum tmp (verinum::V0, ff->width()); for (unsigned bit = 0 ; bit < ff->width() ; bit += 1) { assert(asig->pin(bit).nexus()->drivers_constant()); tmp.set(bit, asig->pin(bit).nexus()->driven_value()); } assert(tmp.is_defined()); if (tmp.is_zero()) { connect(ff->pin_Sclr(), rst->pin(0)); } else { connect(ff->pin_Sset(), rst->pin(0)); ff->sset_value(tmp); } delete a_set; assert(else_ != 0); flag = else_->synth_sync(des, scope, ff, nex_map, nex_out, std::vector()) && flag; DEBUG_SYNTH2_EXIT("NetCondit",flag) return flag; } } delete a_set; #endif #if 0 /* This gives a false positive for strange coding styles, such as ivltests/conditsynth3.v. */ /* Failed to find an asynchronous set/reset, so any events input are probably in error. */ if (events_in.size() > 0) { cerr << get_fileline() << ": error: Events are unaccounted" << " for in process synthesis." << endl; des->errors += 1; } #endif return synth_async(des, scope, nex_map, nex_out, ff_ce, bitmasks); } bool NetEvWait::synth_sync(Design*des, NetScope*scope, bool&ff_negedge, NetNet*ff_clk, NetBus&ff_ce, NetBus&ff_aclr,NetBus&ff_aset, vector&ff_aset_value, NexusSet&nex_map, NetBus&nex_out, vector&bitmasks, const vector&events_in) { if (debug_synth2) { cerr << get_fileline() << ": NetEvWait::synth_sync: " << "Synchronous process an event statement." << endl; } if (events_in.size() > 0) { cerr << get_fileline() << ": error: Events are unaccounted" << " for in process synthesis." << endl; des->errors += 1; } assert(events_in.size() == 0); /* This can't be other than one unless there are named events, which I cannot synthesize. */ ivl_assert(*this, events_.size() == 1); NetEvent*ev = events_[0]; assert(ev->nprobe() >= 1); vectorevents (ev->nprobe() - 1); /* Get the input set from the substatement. This will be used to figure out which of the probes is the clock. */ NexusSet*statement_input = statement_ -> nex_input(); /* Search for a clock input. The clock input is the edge event that is not also an input to the substatement. */ NetEvProbe*pclk = 0; unsigned event_idx = 0; for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { NetEvProbe*tmp = ev->probe(idx); assert(tmp->pin_count() == 1); NexusSet tmp_nex; tmp_nex .add( tmp->pin(0).nexus(), 0, 0 ); if (! statement_input ->contains(tmp_nex)) { if (pclk != 0) { cerr << get_fileline() << ": error: Too many " << "clocks for synchronous logic." << endl; cerr << get_fileline() << ": : Perhaps an" << " asynchronous set/reset is misused?" << endl; des->errors += 1; } pclk = tmp; } else { events[event_idx++] = tmp; } } if (pclk == 0) { cerr << get_fileline() << ": error: None of the edges" << " are valid clock inputs." << endl; cerr << get_fileline() << ": : Perhaps the clock" << " is read by a statement or expression?" << endl; des->errors += 1; return false; } if (debug_synth2) { cerr << get_fileline() << ": NetEvWait::synth_sync: " << "Found and synthesized the FF clock." << endl; } connect(ff_clk->pin(0), pclk->pin(0)); if (pclk->edge() == NetEvProbe::NEGEDGE) { ff_negedge = true; if (debug_synth2) { cerr << get_fileline() << ": debug: " << "Detected a NEGEDGE clock for the synthesized ff." << endl; } } /* Synthesize the input to the DFF. */ return statement_->synth_sync(des, scope, ff_negedge, ff_clk, ff_ce, ff_aclr, ff_aset, ff_aset_value, nex_map, nex_out, bitmasks, events); } /* * This method is called for a process that is determined to be * synchronous. Create a NetFF device to hold the output from the * statement, and synthesize that statement in place. */ bool NetProcTop::synth_sync(Design*des) { if (debug_synth2) { cerr << get_fileline() << ": NetProcTop::synth_sync: " << "Process is apparently synchronous. Making NetFFs." << endl; } NexusSet nex_set; statement_->nex_output(nex_set); vector aset_value(nex_set.size()); /* Make a model FF that will connect to the first item in the set, and will also take the initial connection of clocks and resets. */ // Create a net to carry the clock for the synthesized FFs. NetNet*clock = new NetNet(scope(), scope()->local_symbol(), NetNet::TRI, &netvector_t::scalar_logic); clock->local_flag(true); clock->set_line(*this); NetBus ce (scope(), nex_set.size()); NetBus nex_d (scope(), nex_set.size()); NetBus nex_q (scope(), nex_set.size()); NetBus aclr (scope(), nex_set.size()); NetBus aset (scope(), nex_set.size()); vector bitmasks (nex_set.size()); // Save links to the initial nex_d. These will be used later // to detect floating part-substitute and mux inputs that need // to be tied off. NetBus nex_in (scope(), nex_d.pin_count()); for (unsigned idx = 0 ; idx < nex_in.pin_count() ; idx += 1) connect(nex_in.pin(idx), nex_d.pin(idx)); // The Q of the NetFF devices is connected to the output that // we are. The nex_q is a bundle of the outputs. for (unsigned idx = 0 ; idx < nex_q.pin_count() ; idx += 1) connect(nex_q.pin(idx), nex_set[idx].lnk); // Connect the D of the NetFF devices later. /* Synthesize the input to the DFF. */ bool negedge = false; bool flag = statement_->synth_sync(des, scope(), negedge, clock, ce, aclr, aset, aset_value, nex_set, nex_d, bitmasks, vector()); if (! flag) { delete clock; return false; } flag = tie_off_floating_inputs_(des, nex_set, nex_in, bitmasks, true); if (!flag) return false; for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) { //ivl_assert(*this, nex_set[idx].nex); if (debug_synth2) { cerr << get_fileline() << ": debug: " << "Top level making a " << nex_set[idx].wid << "-wide " << "NetFF device." << endl; } NetFF*ff2 = new NetFF(scope(), scope()->local_symbol(), negedge, nex_set[idx].wid); des->add_node(ff2); ff2->set_line(*this); ff2->aset_value(aset_value[idx]); NetNet*tmp = nex_d.pin(idx).nexus()->pick_any_net(); tmp->set_line(*this); assert(tmp); tmp = crop_to_width(des, tmp, ff2->width()); connect(nex_q.pin(idx), ff2->pin_Q()); connect(tmp->pin(0), ff2->pin_Data()); connect(clock->pin(0), ff2->pin_Clock()); if (ce.pin(idx).is_linked()) connect(ce.pin(idx), ff2->pin_Enable()); if (aclr.pin(idx).is_linked()) connect(aclr.pin(idx), ff2->pin_Aclr()); if (aset.pin(idx).is_linked()) connect(aset.pin(idx), ff2->pin_Aset()); #if 0 if (ff->pin_Sset().is_linked()) connect(ff->pin_Sset(), ff2->pin_Sset()); if (ff->pin_Sclr().is_linked()) connect(ff->pin_Sclr(), ff2->pin_Sclr()); #endif } // The "clock" net was just to carry the connection back // to the flip-flop. Delete it now. The connection will // persist. delete clock; synthesized_design_ = des; return true; } class synth2_f : public functor_t { public: void process(Design*, NetProcTop*); private: }; /* * Look at a process. If it is asynchronous, then synthesize it as an * asynchronous process and delete the process itself for its gates. */ void synth2_f::process(Design*des, NetProcTop*top) { if (top->attribute(perm_string::literal("ivl_synthesis_off")).as_ulong() != 0) return; /* If the scope that contains this process as a cell attribute attached to it, then skip synthesis. */ if (top->scope()->attribute(perm_string::literal("ivl_synthesis_cell")).len() > 0) return; /* Create shared pullup and pulldown nodes (if they don't already exist) for use when creating clock/gate enables. */ top->scope()->add_tie_hi(des); top->scope()->add_tie_lo(des); if (top->is_synchronous()) { bool flag = top->synth_sync(des); if (! flag) { cerr << top->get_fileline() << ": error: " << "Unable to synthesize synchronous process." << endl; des->errors += 1; return; } des->delete_process(top); return; } if (! top->is_asynchronous()) { bool synth_error_flag = false; if (top->attribute(perm_string::literal("ivl_combinational")).as_ulong() != 0) { cerr << top->get_fileline() << ": error: " << "Process is marked combinational," << " but isn't really." << endl; des->errors += 1; synth_error_flag = true; } if (top->attribute(perm_string::literal("ivl_synthesis_on")).as_ulong() != 0) { cerr << top->get_fileline() << ": error: " << "Process is marked for synthesis," << " but I can't do it." << endl; des->errors += 1; synth_error_flag = true; } if (! synth_error_flag) cerr << top->get_fileline() << ": warning: " << "Process not synthesized." << endl; return; } if (! top->synth_async(des)) { cerr << top->get_fileline() << ": error: " << "Unable to synthesize asynchronous process." << endl; des->errors += 1; return; } des->delete_process(top); } void synth2(Design*des) { synth2_f synth_obj; des->functor(&synth_obj); } iverilog-12_0/sys_funcs.cc000066400000000000000000000156401435245347300157000ustar00rootroot00000000000000/* * Copyright (c) 2004-2019 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 "compiler.h" # include # include # include /* * Manage the information about system functions. This information is * collected from the sources before elaboration and made available * via the lookup_sys_func function. */ static const struct sfunc_return_type default_return_type = { 0, IVL_VT_LOGIC, 32, false, false }; struct sfunc_return_type_cell : sfunc_return_type { struct sfunc_return_type_cell*next; }; static struct sfunc_return_type_cell*sfunc_list_head = 0; static struct sfunc_return_type_cell*sfunc_list_tail = 0; void append_to_list(struct sfunc_return_type_cell*cell) { if (sfunc_list_tail) { sfunc_list_tail->next = cell; sfunc_list_tail = cell; } else { sfunc_list_head = cell; sfunc_list_tail = cell; } cell->next = 0; } void cleanup_sys_func_table() { struct sfunc_return_type_cell *next, *cur = sfunc_list_head; while (cur) { next = cur->next; delete cur; cur = next; } } static struct sfunc_return_type* find_in_sys_func_list(const char*name) { struct sfunc_return_type_cell*cur = sfunc_list_head; while (cur) { if (strcmp(cur->name, name) == 0) return cur; cur = cur->next; } return 0; } const struct sfunc_return_type* lookup_sys_func(const char*name) { /* First, try to find the name in the function list. */ struct sfunc_return_type*def = find_in_sys_func_list(name); if (def) return def; /* No luck finding, so return the default description. */ return &default_return_type; } void add_sys_func(const struct sfunc_return_type&ret_type) { struct sfunc_return_type*def = find_in_sys_func_list(ret_type.name); if (def) { /* Keep the original definition, but flag that it overrides a later definition. */ def->override_flag = true; return; } struct sfunc_return_type_cell*cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(ret_type.name); cell->type = ret_type.type; cell->wid = ret_type.wid; cell->signed_flag = ret_type.signed_flag; cell->override_flag = ret_type.override_flag; append_to_list(cell); } /* * This function loads a system functions descriptor file with the * format: * * [] * * The driver passes us user-provided tables first, so we add new entries * to the end of the list. This allows user-defined functions to override * built-in functions. */ int load_sys_func_table(const char*path) { struct sfunc_return_type_cell*cell; FILE*fd = fopen(path, "r"); if (fd == 0) { if (verbose_flag) { fprintf(stderr, "%s: Unable to open System Function Table file.\n", path); } return -1; } if (verbose_flag) { fprintf(stderr, "%s: Processing System Function Table file.\n", path); } char buf[256]; while (fgets(buf, sizeof buf, fd)) { char*name = buf + strspn(buf, " \t\r\n"); /* Skip empty lines. */ if (name[0] == 0) continue; /* Skip comment lines. */ if (name[0] == '#') continue; char*cp = name + strcspn(name, " \t\r\n"); if (cp[0]) *cp++ = 0; cp += strspn(cp, " \t\r\n"); char*stype = cp; if (stype[0] == 0) { fprintf(stderr, "%s:%s: No function type?\n", path, name); continue; } cp = stype + strcspn(stype, " \t\r\n"); if (cp[0]) *cp++ = 0; struct sfunc_return_type*def = find_in_sys_func_list(name); if (def) { /* Keep the original definition, but flag that it overrides a later definition. */ def->override_flag = true; continue; } if (strcmp(stype,"vpiSysFuncReal") == 0) { cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_REAL; cell->wid = 1; cell->signed_flag = true; cell->override_flag = false; append_to_list(cell); continue; } if (strcmp(stype,"vpiSysFuncInt") == 0) { cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_LOGIC; cell->wid = 32; cell->signed_flag = true; cell->override_flag = false; append_to_list(cell); continue; } /* If this is a sized integer, then parse the additional arguments, the width (decimal) and the optional signed/unsigned flag. */ if (strcmp(stype,"vpiSysFuncSized") == 0) { cp += strspn(cp, " \t\r\n"); char*swidth = cp; unsigned width = 32; bool signed_flag = false; cp = swidth + strcspn(swidth, " \t\r\n"); if (cp[0]) *cp++ = 0; width = strtoul(swidth, 0, 10); cp += strspn(cp, " \t\r\n"); char*flag = cp; while (flag[0]) { cp = flag + strcspn(flag, " \t\r\n"); if (cp[0]) *cp++ = 0; if (strcmp(flag,"signed") == 0) { signed_flag = true; } else if (strcmp(flag,"unsigned") == 0) { signed_flag = false; } flag = cp + strspn(cp, " \t\r\n"); } cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_LOGIC; cell->wid = width; cell->signed_flag = signed_flag; cell->override_flag = false; append_to_list(cell); continue; } if (strcmp(stype,"vpiSysFuncVoid") == 0) { cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_VOID; cell->wid = 0; cell->signed_flag = false; cell->override_flag = false; append_to_list(cell); continue; } if (strcmp(stype,"vpiSysFuncString") == 0) { cell = new struct sfunc_return_type_cell; cell->name = lex_strings.add(name); cell->type = IVL_VT_STRING; cell->wid = 0; // string is a dynamic length type cell->signed_flag = false; cell->override_flag = false; append_to_list(cell); continue; } fprintf(stderr, "%s:%s: Unknown type: %s\n", path, name, stype); } fclose(fd); return 0; } iverilog-12_0/t-dll-analog.cc000066400000000000000000000045061435245347300161360ustar00rootroot00000000000000/* * Copyright (c) 2008-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.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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 # include # include "target.h" # include "ivl_target.h" # include "compiler.h" # include "t-dll.h" # include # include "ivl_alloc.h" bool dll_target::process(const NetAnalogTop*net) { bool rc_flag = true; ivl_process_t obj = (struct ivl_process_s*) calloc(1, sizeof(struct ivl_process_s)); obj->type_ = net->type(); obj->analog_flag = 1; FILE_NAME(obj, net); /* Save the scope of the process. */ obj->scope_ = lookup_scope_(net->scope()); obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); assert(stmt_cur_ == 0); stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_); rc_flag = net->statement()->emit_proc(this) && rc_flag; assert(stmt_cur_); obj->stmt_ = stmt_cur_; stmt_cur_ = 0; /* Save the process in the design. */ obj->next_ = des_.threads_; des_.threads_ = obj; return rc_flag; } bool dll_target::proc_contribution(const NetContribution*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_CONTRIB; assert(expr_ == 0); net->lval()->expr_scan(this); stmt_cur_->u_.contrib_.lval = expr_; expr_ = 0; net->rval()->expr_scan(this); stmt_cur_->u_.contrib_.rval = expr_; expr_ = 0; return true; } iverilog-12_0/t-dll-api.cc000066400000000000000000002061471435245347300154530ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch) * * 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 "StringHeap.h" # include "t-dll.h" # include "discipline.h" # include "netclass.h" # include "netdarray.h" # include "netenum.h" # include "netvector.h" # include # include # include # include "ivl_alloc.h" using namespace std; static StringHeap api_strings; /* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */ extern "C" ivl_island_t ivl_branch_island(ivl_branch_t net) { assert(net); return net->island; } extern "C" ivl_nexus_t ivl_branch_terminal(ivl_branch_t net, int idx) { assert(net); assert(idx >= 0); assert(idx < 2); return net->pins[idx]; } extern "C" const char*ivl_design_delay_sel(ivl_design_t des) { assert(des); assert(des->self); return des->self->get_delay_sel(); } extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key) { assert(des); assert(des->self); return des->self->get_flag(key); } extern "C" int ivl_design_process(ivl_design_t des, ivl_process_f func, void*cd) { assert(des); for (ivl_process_t idx = des->threads_; idx; idx = idx->next_) { int rc = (func)(idx, cd); if (rc != 0) return rc; } return 0; } extern "C" ivl_scope_t ivl_design_root(ivl_design_t des) { cerr << "ANACHRONISM: ivl_design_root called. " "Use ivl_design_roots instead." << endl; assert(des); assert (des->roots.size() > 0); return des->roots[0]; } extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes, unsigned int *nscopes) { assert(des); assert (nscopes && scopes); if (des->root_scope_list.size() == 0) { size_t fill = 0; des->root_scope_list.resize(des->packages.size() + des->roots.size()); for (size_t idx = 0 ; idx < des->packages.size() ; idx += 1) des->root_scope_list[fill++] = des->packages[idx]; for (size_t idx = 0 ; idx < des->roots.size() ; idx += 1) des->root_scope_list[fill++] = des->roots[idx]; } *scopes = &des->root_scope_list[0]; *nscopes = des->root_scope_list.size(); } extern "C" int ivl_design_time_precision(ivl_design_t des) { assert(des); return des->time_precision; } extern "C" unsigned ivl_design_consts(ivl_design_t des) { assert(des); return des->consts.size(); } extern "C" ivl_net_const_t ivl_design_const(ivl_design_t des, unsigned idx) { assert(des); assert(idx < des->consts.size()); return des->consts[idx]; } extern "C" unsigned ivl_design_disciplines(ivl_design_t des) { assert(des); return des->disciplines.size(); } extern "C" ivl_discipline_t ivl_design_discipline(ivl_design_t des, unsigned idx) { assert(des); assert(idx < des->disciplines.size()); return des->disciplines[idx]; } extern "C" ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net) { assert(net); return net->domain(); } extern "C" ivl_nature_t ivl_discipline_flow(ivl_discipline_t net) { assert(net); return net->flow(); } extern "C" const char* ivl_discipline_name(ivl_discipline_t net) { assert(net); return net->name(); } extern "C" ivl_nature_t ivl_discipline_potential(ivl_discipline_t net) { assert(net); return net->potential(); } extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net) { if (net == 0) return IVL_EX_NONE; return net->type_; } extern "C" const char*ivl_expr_file(ivl_expr_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_expr_lineno(ivl_expr_t net) { assert(net); return net->lineno; } extern "C" ivl_variable_type_t ivl_const_type(ivl_net_const_t net) { assert(net); return net->type; } extern "C" const char*ivl_const_bits(ivl_net_const_t net) { assert(net); switch (net->type) { case IVL_VT_BOOL: case IVL_VT_LOGIC: case IVL_VT_STRING: if (net->width_ <= sizeof(net->b.bit_)) return net->b.bit_; else return net->b.bits_; default: return 0; } } extern "C" ivl_expr_t ivl_const_delay(ivl_net_const_t net, unsigned transition) { assert(net); assert(transition < 3); return net->delay[transition]; } extern "C" const char*ivl_const_file(ivl_net_const_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_const_lineno(ivl_net_const_t net) { assert(net); return net->lineno; } extern "C" ivl_nexus_t ivl_const_nex(ivl_net_const_t net) { assert(net); return net->pin_; } extern "C" double ivl_const_real(ivl_net_const_t net) { assert(net); assert(net->type == IVL_VT_REAL); return net->b.real_value; } extern "C" ivl_scope_t ivl_const_scope(ivl_net_const_t net) { assert(net); return net->scope; } extern "C" int ivl_const_signed(ivl_net_const_t net) { assert(net); return net->signed_; } extern "C" unsigned ivl_const_width(ivl_net_const_t net) { assert(net); return net->width_; } extern "C" unsigned ivl_enum_names(ivl_enumtype_t net) { assert(net); return net->size(); } extern "C" const char* ivl_enum_name(ivl_enumtype_t net, unsigned idx) { assert(net); assert(idx < net->size()); return net->name_at(idx); } extern "C" const char* ivl_enum_bits(ivl_enumtype_t net, unsigned idx) { assert(net); assert(idx < net->size()); return net->bits_at(idx); } extern "C" ivl_variable_type_t ivl_enum_type(ivl_enumtype_t net) { assert(net); return net->base_type(); } extern "C" unsigned ivl_enum_width(ivl_enumtype_t net) { assert(net); return net->packed_width(); } extern "C" int ivl_enum_signed(ivl_enumtype_t net) { assert(net); return net->get_signed(); } extern "C" const char*ivl_enum_file(ivl_enumtype_t net) { assert(net); return net->get_file().str(); } extern "C" unsigned ivl_enum_lineno(ivl_enumtype_t net) { assert(net); return net->get_lineno(); } extern "C" const char* ivl_event_name(ivl_event_t net) { assert(net); static char*name_buffer = 0; static unsigned name_size = 0; ivl_scope_t scope = net->scope; const char*sn = ivl_scope_name(scope); unsigned need = strlen(sn) + 1 + strlen(net->name) + 1; if (need > name_size) { name_buffer = (char*)realloc(name_buffer, need); name_size = need; } strcpy(name_buffer, sn); char*tmp = name_buffer + strlen(sn); *tmp++ = '.'; strcpy(tmp, net->name); cerr << "ANACHRONISM: Call to anachronistic ivl_event_name." << endl; return name_buffer; } extern "C" const char* ivl_event_basename(ivl_event_t net) { assert(net); return net->name; } extern "C" const char*ivl_event_file(ivl_event_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_event_lineno(ivl_event_t net) { assert(net); return net->lineno; } extern "C" ivl_scope_t ivl_event_scope(ivl_event_t net) { assert(net); return net->scope; } extern "C" unsigned ivl_event_nany(ivl_event_t net) { assert(net); return net->nany; } extern "C" ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx) { assert(net); assert(idx < net->nany); return net->pins[idx]; } extern "C" unsigned ivl_event_nedg(ivl_event_t net) { assert(net); return net->nedg; } extern "C" ivl_nexus_t ivl_event_edg(ivl_event_t net, unsigned idx) { assert(net); assert(idx < net->nedg); return net->pins[net->nany + net->nneg + net->npos + idx]; } extern "C" unsigned ivl_event_nneg(ivl_event_t net) { assert(net); return net->nneg; } extern "C" ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx) { assert(net); assert(idx < net->nneg); return net->pins[net->nany + idx]; } extern "C" unsigned ivl_event_npos(ivl_event_t net) { assert(net); return net->npos; } extern "C" ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx) { assert(net); assert(idx < net->npos); return net->pins[net->nany + net->nneg + idx]; } extern "C" const char* ivl_expr_bits(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_NUMBER); return net->u_.number_.bits_; } extern "C" ivl_branch_t ivl_expr_branch(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_BACCESS); return net->u_.branch_.branch; } extern "C" ivl_scope_t ivl_expr_def(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_UFUNC: return net->u_.ufunc_.def; default: assert(0); } return 0; } extern "C" uint64_t ivl_expr_delay_val(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_DELAY); return net->u_.delay_.value; } extern "C" double ivl_expr_dvalue(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_REALNUM); return net->u_.real_.value; } extern "C" ivl_enumtype_t ivl_expr_enumtype(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_ENUMTYPE); return net->u_.enumtype_.type; } extern "C" ivl_type_t ivl_expr_net_type(ivl_expr_t net) { assert(net); return net->net_type; } extern "C" const char* ivl_expr_name(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_SFUNC: return net->u_.sfunc_.name_; case IVL_EX_SIGNAL: return net->u_.signal_.sig->name_; case IVL_EX_PROPERTY: { ivl_signal_t sig = ivl_expr_signal(net); ivl_type_t use_type = ivl_signal_net_type(sig); unsigned idx = ivl_expr_property_idx(net); return ivl_type_prop_name(use_type, idx); } default: assert(0); } return 0; } extern "C" ivl_nature_t ivl_expr_nature(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_BACCESS); return net->u_.branch_.nature; } extern "C" char ivl_expr_opcode(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_BINARY: return net->u_.binary_.op_; case IVL_EX_UNARY: return net->u_.unary_.op_; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_BINARY: return net->u_.binary_.lef_; case IVL_EX_PROPERTY: return net->u_.property_.index; case IVL_EX_SELECT: return net->u_.select_.expr_; case IVL_EX_UNARY: return net->u_.unary_.sub_; case IVL_EX_MEMORY: return net->u_.memory_.idx_; case IVL_EX_NEW: return net->u_.new_.size; case IVL_EX_SHALLOWCOPY: return net->u_.shallow_.dest; case IVL_EX_SIGNAL: return net->u_.signal_.word; case IVL_EX_TERNARY: return net->u_.ternary_.cond; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_BINARY: return net->u_.binary_.rig_; case IVL_EX_NEW: return net->u_.new_.init_val; case IVL_EX_SELECT: return net->u_.select_.base_; case IVL_EX_SHALLOWCOPY: return net->u_.shallow_.src; case IVL_EX_TERNARY: return net->u_.ternary_.true_e; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_expr_oper3(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_TERNARY: return net->u_.ternary_.false_e; default: assert(0); } return 0; } extern "C" ivl_parameter_t ivl_expr_parameter(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_NUMBER: return net->u_.number_.parameter; case IVL_EX_STRING: return net->u_.string_.parameter; case IVL_EX_REALNUM: return net->u_.real_.parameter; default: return 0; } } extern "C" ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_EX_ARRAY_PATTERN: assert(idx < net->u_.array_pattern_.parms); return net->u_.array_pattern_.parm[idx]; case IVL_EX_CONCAT: assert(idx < net->u_.concat_.parms); return net->u_.concat_.parm[idx]; case IVL_EX_SFUNC: assert(idx < net->u_.sfunc_.parms); return net->u_.sfunc_.parm[idx]; case IVL_EX_UFUNC: assert(idx < net->u_.ufunc_.parms); return net->u_.ufunc_.parm[idx]; default: assert(0); return 0; } } extern "C" unsigned ivl_expr_parms(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_ARRAY_PATTERN: return net->u_.array_pattern_.parms; case IVL_EX_CONCAT: return net->u_.concat_.parms; case IVL_EX_SFUNC: return net->u_.sfunc_.parms; case IVL_EX_UFUNC: return net->u_.ufunc_.parms; default: assert(0); return 0; } } extern "C" unsigned ivl_expr_repeat(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_CONCAT); return net->u_.concat_.rept; } extern "C" ivl_event_t ivl_expr_event(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_EVENT); return net->u_.event_.event; } extern "C" int ivl_expr_property_idx(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_PROPERTY); return net->u_.property_.prop_idx; } extern "C" ivl_scope_t ivl_expr_scope(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_SCOPE); return net->u_.scope_.scope; } extern "C" ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_SELECT); return net->u_.select_.sel_type_; } extern "C" ivl_signal_t ivl_expr_signal(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_SIGNAL: case IVL_EX_ARRAY: return net->u_.signal_.sig; case IVL_EX_PROPERTY: return net->u_.property_.sig; default: assert(0); return 0; } } extern "C" int ivl_expr_signed(ivl_expr_t net) { assert(net); return net->signed_; } extern "C" int ivl_expr_sized(ivl_expr_t net) { assert(net); return net->sized_; } extern "C" const char* ivl_expr_string(ivl_expr_t net) { assert(net); assert(net->type_ == IVL_EX_STRING); return net->u_.string_.value_; } extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net) { assert(net); switch (net->type_) { case IVL_EX_ULONG: return net->u_.ulong_.value; case IVL_EX_NUMBER: { unsigned long val = 0; for (unsigned long idx = 0 ; idx < net->width_ ; idx += 1) { if (net->u_.number_.bits_[idx] == '1') val |= 1UL << idx; } return val; } default: assert(0); } assert(0); return 0; } extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net) { assert(net); return net->value_; } extern "C" unsigned ivl_expr_width(ivl_expr_t net) { assert(net); return net->width_; } /* * ivl_file_table_index puts entries in the map as needed and returns * the appropriate index. * ivl_file_table_size returns the number of entries in the table. * ivl_file_table_item returns the file name for the given index. */ struct ltstr { bool operator()(const char*s1, const char*s2) const { return strcmp(s1, s2) < 0; } }; static map fn_map; static vector fn_vector; static void ivl_file_table_init() { /* The first two index entries do not depend on a real * file name and are always available. */ fn_vector.push_back("N/A"); fn_map["N/A"] = 0; fn_vector.push_back(""); fn_map[""] = 1; } extern "C" const char* ivl_file_table_item(unsigned idx) { if (fn_vector.empty()) { ivl_file_table_init(); } assert(idx < fn_vector.size()); return fn_vector[idx]; } extern "C" unsigned ivl_file_table_index(const char*name) { if (fn_vector.empty()) { ivl_file_table_init(); } if (name == NULL) return 0; /* The new index is the current map size. This is inserted only * if the file name is not currently in the map. */ pair::iterator, bool> result; result = fn_map.insert(make_pair(name, fn_vector.size())); if (result.second) { fn_vector.push_back(name); } return result.first->second; } extern "C" unsigned ivl_file_table_size() { if (fn_vector.empty()) { ivl_file_table_init(); } return fn_vector.size(); } extern "C" int ivl_island_flag_set(ivl_island_t net, unsigned flag, int value) { assert(net); if (flag >= net->flags.size()) { if (value == 0) return 0; else net->flags.resize(flag+1, false); } int old_flag = net->flags[flag]; net->flags[flag] = value != 0; return old_flag; } extern "C" int ivl_island_flag_test(ivl_island_t net, unsigned flag) { assert(net); if (flag >= net->flags.size()) return 0; else return net->flags[flag]; } extern "C" const char*ivl_logic_file(ivl_net_logic_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_logic_lineno(ivl_net_logic_t net) { assert(net); return net->lineno; } extern "C" unsigned ivl_logic_is_cassign(ivl_net_logic_t net) { assert(net); return net->is_cassign; } extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key) { assert(net); unsigned idx; for (idx = 0 ; idx < net->nattr ; idx += 1) { if (strcmp(net->attr[idx].key, key) == 0) return net->attr[idx].type == IVL_ATT_STR ? net->attr[idx].val.str : 0; } return 0; } extern "C" unsigned ivl_logic_attr_cnt(ivl_net_logic_t net) { assert(net); return net->nattr; } extern "C" ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx) { assert(net); assert(idx < net->nattr); return net->attr + idx; } extern "C" ivl_drive_t ivl_logic_drive0(ivl_net_logic_t net) { ivl_nexus_t nex = ivl_logic_pin(net, 0); for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx); if (ivl_nexus_ptr_log(cur) != net) continue; if (ivl_nexus_ptr_pin(cur) != 0) continue; return ivl_nexus_ptr_drive0(cur); } assert(0); return IVL_DR_STRONG; } extern "C" ivl_drive_t ivl_logic_drive1(ivl_net_logic_t net) { ivl_nexus_t nex = ivl_logic_pin(net, 0); for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx); if (ivl_nexus_ptr_log(cur) != net) continue; if (ivl_nexus_ptr_pin(cur) != 0) continue; return ivl_nexus_ptr_drive1(cur); } assert(0); return IVL_DR_STRONG; } extern "C" const char* ivl_logic_name(ivl_net_logic_t net) { assert(net); cerr << "ANACHRONISM: Call to anachronistic ivl_logic_name." << endl; return net->name_; } extern "C" const char* ivl_logic_basename(ivl_net_logic_t net) { assert(net); return net->name_; } extern "C" ivl_scope_t ivl_logic_scope(ivl_net_logic_t net) { assert(net); return net->scope_; } extern "C" ivl_logic_t ivl_logic_type(ivl_net_logic_t net) { assert(net); return net->type_; } extern "C" unsigned ivl_logic_pins(ivl_net_logic_t net) { assert(net); return net->npins_; } extern "C" ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin) { assert(net); assert(pin < net->npins_); return net->pins_[pin]; } extern "C" ivl_udp_t ivl_logic_udp(ivl_net_logic_t net) { assert(net); assert(net->type_ == IVL_LO_UDP); assert(net->udp); return net->udp; } extern "C" ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition) { assert(net); assert(transition < 3); return net->delay[transition]; } extern "C" unsigned ivl_logic_width(ivl_net_logic_t net) { assert(net); return net->width_; } extern "C" int ivl_udp_sequ(ivl_udp_t net) { assert(net); return net->sequ; } extern "C" unsigned ivl_udp_nin(ivl_udp_t net) { assert(net); return net->nin; } extern "C" char ivl_udp_init(ivl_udp_t net) { assert(net); return net->init; } extern "C" const char* ivl_udp_port(ivl_udp_t net, unsigned idx) { assert(net); assert(idx <= net->nin); assert(net->ports); assert(net->ports[idx].c_str()); return net->ports[idx].c_str(); } extern "C" const char* ivl_udp_row(ivl_udp_t net, unsigned idx) { assert(net); assert(idx < net->nrows); assert(net->table); assert(net->table[idx]); return net->table[idx]; } extern "C" unsigned ivl_udp_rows(ivl_udp_t net) { assert(net); return net->nrows; } extern "C" const char* ivl_udp_name(ivl_udp_t net) { assert(net); assert(net->name); return net->name; } extern "C" const char* ivl_udp_file(ivl_udp_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_udp_lineno(ivl_udp_t net) { assert(net); return net->lineno; } extern "C" const char* ivl_lpm_basename(ivl_lpm_t net) { assert(net); return net->name; } extern "C" ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net) { assert(net); switch(net->type) { case IVL_LPM_FF: return net->u_.ff.aclr; default: assert(0); return 0; } } extern "C" ivl_nexus_t ivl_lpm_sync_clr(ivl_lpm_t net) { assert(net); switch(net->type) { case IVL_LPM_FF: return net->u_.ff.sclr; default: assert(0); return 0; } } extern "C" ivl_expr_t ivl_lpm_delay(ivl_lpm_t net, unsigned transition) { assert(net); assert(transition < 3); return net->delay[transition]; } extern "C" ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net) { assert(net); switch(net->type) { case IVL_LPM_FF: return net->u_.ff.aset; default: assert(0); return 0; } } extern "C" ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net) { assert(net); switch(net->type) { case IVL_LPM_FF: return net->u_.ff.sset; default: assert(0); return 0; } } extern "C" ivl_signal_t ivl_lpm_array(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_ARRAY: return net->u_.array.sig; default: assert(0); return 0; } } extern "C" unsigned ivl_lpm_base(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: return net->u_.part.base; case IVL_LPM_SUBSTITUTE: return net->u_.substitute.base; default: assert(0); return 0; } } extern "C" unsigned ivl_lpm_negedge(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: return net->u_.ff.negedge_flag; default: assert(0); return 0; } } extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: return net->u_.ff.clk; default: assert(0); return 0; } } extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: return net->u_.ff.aset_value; default: assert(0); return 0; } } extern "C" ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: return net->u_.ff.sset_value; default: assert(0); return 0; } } extern "C" ivl_scope_t ivl_lpm_define(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_UFUNC: return net->u_.ufunc.def; default: assert(0); return 0; } } extern "C" ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: return net->u_.ff.we; case IVL_LPM_LATCH: return net->u_.latch.e; default: assert(0); return 0; } } extern "C" const char* ivl_lpm_file(ivl_lpm_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_lpm_lineno(ivl_lpm_t net) { assert(net); return net->lineno; } extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx) { assert(net); switch (net->type) { case IVL_LPM_ABS: case IVL_LPM_CAST_INT: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_REAL: assert(idx == 0); return net->u_.arith.a; case IVL_LPM_ADD: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_POW: case IVL_LPM_SUB: assert(idx <= 1); if (idx == 0) return net->u_.arith.a; else return net->u_.arith.b; case IVL_LPM_MUX: assert(idx < net->u_.mux.size); return net->u_.mux.d[idx]; case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: case IVL_LPM_SIGN_EXT: assert(idx == 0); return net->u_.reduce.a; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: assert(idx <= 1); if (idx == 0) return net->u_.shift.d; else return net->u_.shift.s; case IVL_LPM_FF: assert(idx == 0); return net->u_.ff.d.pin; case IVL_LPM_LATCH: assert(idx == 0); return net->u_.latch.d.pin; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: assert(idx < net->u_.concat.inputs); return net->u_.concat.pins[idx+1]; case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: assert(idx <= 1); if (idx == 0) return net->u_.part.a; else return net->u_.part.s; case IVL_LPM_REPEAT: assert(idx == 0); return net->u_.repeat.a; case IVL_LPM_SFUNC: // Skip the return port. assert(idx < (net->u_.sfunc.ports-1)); return net->u_.sfunc.pins[idx+1]; case IVL_LPM_SUBSTITUTE: assert(idx <= 1); if (idx == 0) return net->u_.substitute.a; else return net->u_.substitute.s; case IVL_LPM_UFUNC: // Skip the return port. assert(idx < (net->u_.ufunc.ports-1)); return net->u_.ufunc.pins[idx+1]; default: assert(0); return 0; } } extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx) { cerr << "ANACHRONISM: Call to anachronistic ivl_lpm_datab." << endl; assert(net); switch (net->type) { case IVL_LPM_ADD: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_POW: case IVL_LPM_SUB: assert(idx == 0); return net->u_.arith.b; default: assert(0); return 0; } } /* * This function returns the hierarchical name for the LPM device. The * name needs to be built up from the scope name and the lpm base * name. * * Anachronism: This function is provided for * compatibility. Eventually, it will be removed. */ extern "C" const char* ivl_lpm_name(ivl_lpm_t net) { assert(net); static char*name_buffer = 0; static unsigned name_size = 0; ivl_scope_t scope = ivl_lpm_scope(net); const char*sn = ivl_scope_name(scope); unsigned need = strlen(sn) + 1 + strlen(net->name) + 1; if (need > name_size) { name_buffer = (char*)realloc(name_buffer, need); name_size = need; } strcpy(name_buffer, sn); char*tmp = name_buffer + strlen(sn); *tmp++ = '.'; strcpy(tmp, net->name); return name_buffer; } extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_ABS: case IVL_LPM_ADD: case IVL_LPM_CAST_INT: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_REAL: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_POW: case IVL_LPM_SUB: return net->u_.arith.q; case IVL_LPM_FF: return net->u_.ff.q.pin; case IVL_LPM_LATCH: return net->u_.latch.q.pin; case IVL_LPM_MUX: return net->u_.mux.q; case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: case IVL_LPM_SIGN_EXT: return net->u_.reduce.q; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: return net->u_.shift.q; case IVL_LPM_SFUNC: return net->u_.sfunc.pins[0]; case IVL_LPM_UFUNC: return net->u_.ufunc.pins[0]; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: return net->u_.concat.pins[0]; case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: return net->u_.part.q; case IVL_LPM_REPEAT: return net->u_.repeat.q; case IVL_LPM_SUBSTITUTE: return net->u_.substitute.q; case IVL_LPM_ARRAY: return net->u_.array.q; default: assert(0); return 0; } } extern "C" ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net) { ivl_nexus_t nex = ivl_lpm_q(net); for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx); if (ivl_nexus_ptr_lpm(cur) != net) continue; if (ivl_nexus_ptr_pin(cur) != 0) continue; return ivl_nexus_ptr_drive0(cur); } assert(0); return IVL_DR_STRONG; } extern "C" ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net) { ivl_nexus_t nex = ivl_lpm_q(net); for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx); if (ivl_nexus_ptr_lpm(cur) != net) continue; if (ivl_nexus_ptr_pin(cur) != 0) continue; return ivl_nexus_ptr_drive1(cur); } assert(0); return IVL_DR_STRONG; } extern "C" ivl_scope_t ivl_lpm_scope(ivl_lpm_t net) { assert(net); return net->scope; } extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_MUX: return net->u_.mux.s; case IVL_LPM_ARRAY: return net->u_.array.a; default: assert(0); return 0; } } extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_MUX: return net->u_.mux.swid; case IVL_LPM_ARRAY: return net->u_.array.swid; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: cerr << "error: ivl_lpm_selects() is no longer supported for " "IVL_LPM_CONCAT, use ivl_lpm_size() instead." << endl; // fallthrough default: assert(0); return 0; } } extern "C" int ivl_lpm_signed(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_FF: case IVL_LPM_MUX: return 0; case IVL_LPM_ABS: case IVL_LPM_ADD: case IVL_LPM_CAST_REAL: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_POW: case IVL_LPM_SUB: case IVL_LPM_CAST_INT2: return net->u_.arith.signed_flag; case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: return 0; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: return net->u_.shift.signed_flag; case IVL_LPM_CAST_INT: case IVL_LPM_SIGN_EXT: // Sign extend is always signed. return 1; case IVL_LPM_SFUNC: return 0; case IVL_LPM_UFUNC: return 0; case IVL_LPM_CONCAT: // Concatenations are always unsigned case IVL_LPM_CONCATZ: // Concatenations are always unsigned return 0; case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: return net->u_.part.signed_flag; case IVL_LPM_REPEAT: case IVL_LPM_SUBSTITUTE: return 0; case IVL_LPM_ARRAY: // Array ports take the signedness of the array. return net->u_.array.sig->net_type->get_signed()? 1 : 0; default: assert(0); return 0; } } extern "C" unsigned ivl_lpm_size(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_MUX: return net->u_.mux.size; case IVL_LPM_SFUNC: return net->u_.sfunc.ports - 1; case IVL_LPM_UFUNC: return net->u_.ufunc.ports - 1; case IVL_LPM_REPEAT: return net->u_.repeat.count; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: return net->u_.concat.inputs; case IVL_LPM_ABS: case IVL_LPM_CAST_INT: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_REAL: case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: case IVL_LPM_SIGN_EXT: case IVL_LPM_FF: return 1; case IVL_LPM_ADD: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_POW: case IVL_LPM_SUB: case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: return 2; default: assert(0); return 0; } } extern "C" const char* ivl_lpm_string(ivl_lpm_t net) { assert(net); assert(net->type == IVL_LPM_SFUNC); return net->u_.sfunc.fun_name; } extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net) { assert(net); return net->type; } extern "C" unsigned ivl_lpm_width(ivl_lpm_t net) { assert(net); return net->width; } extern "C" ivl_event_t ivl_lpm_trigger(ivl_lpm_t net) { assert(net); switch (net->type) { case IVL_LPM_SFUNC: return net->u_.sfunc.trigger; case IVL_LPM_UFUNC: return net->u_.ufunc.trigger; default: assert(0); return 0; } } /* * Deprecated */ extern "C" ivl_expr_t ivl_lval_mux(ivl_lval_t) { return 0; } extern "C" ivl_expr_t ivl_lval_idx(ivl_lval_t net) { assert(net); if (net->type_ == IVL_LVAL_ARR) return net->idx; return 0x0; } extern "C" ivl_expr_t ivl_lval_part_off(ivl_lval_t net) { assert(net); return net->loff; } extern "C" ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net) { assert(net); return net->sel_type; } extern "C" unsigned ivl_lval_width(ivl_lval_t net) { assert(net); return net->width_; } extern "C" int ivl_lval_property_idx(ivl_lval_t net) { assert(net); return net->property_idx; } extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net) { assert(net); switch (net->type_) { case IVL_LVAL_REG: case IVL_LVAL_ARR: return net->n.sig; default: return 0; } } extern "C" ivl_lval_t ivl_lval_nest(ivl_lval_t net) { assert(net); if (net->type_ == IVL_LVAL_LVAL) return net->n.nest; return 0; } extern "C" const char* ivl_nature_name(ivl_nature_t net) { assert(net); return net->name(); } /* * The nexus name is rarely needed. (Shouldn't be needed at all!) This * function will calculate the name if it is not already calculated. */ extern "C" const char* ivl_nexus_name(ivl_nexus_t net) { assert(net); if (net->name_ == 0) { char tmp[2 * sizeof(net) + 5]; snprintf(tmp, sizeof tmp, "n%p", (void *)net); net->name_ = api_strings.add(tmp); } return net->name_; } extern "C" void* ivl_nexus_get_private(ivl_nexus_t net) { assert(net); return net->private_data; } extern "C" void ivl_nexus_set_private(ivl_nexus_t net, void*data) { assert(net); net->private_data = data; } extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net) { assert(net); return net->ptrs_.size(); } extern "C" ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx) { assert(net); assert(idx < net->ptrs_.size()); return & net->ptrs_[idx]; } extern "C" ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net) { assert(net); return (ivl_drive_t)(net->drive0); } extern "C" ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net) { assert(net); return (ivl_drive_t)(net->drive1); } extern "C" unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net) { assert(net); return net->pin_; } extern "C" ivl_branch_t ivl_nexus_ptr_branch(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_BRA) return 0; return net->l.bra; } extern "C" ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_CON) return 0; return net->l.con; } extern "C" ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_LOG) return 0; return net->l.log; } extern "C" ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_LPM) return 0; return net->l.lpm; } extern "C" ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_SIG) return 0; return net->l.sig; } extern "C" ivl_switch_t ivl_nexus_ptr_switch(ivl_nexus_ptr_t net) { if (net == 0) return 0; if (net->type_ != __NEXUS_PTR_SWI) return 0; return net->l.swi; } extern "C" const char* ivl_parameter_basename(ivl_parameter_t net) { assert(net); return net->basename; } extern "C" int ivl_parameter_local(ivl_parameter_t net) { assert(net); return net->local; } extern "C" int ivl_parameter_is_type(ivl_parameter_t net) { assert(net); return net->is_type; } extern "C" int ivl_parameter_signed(ivl_parameter_t net) { assert(net); return net->signed_flag; } extern "C" int ivl_parameter_msb(ivl_parameter_t net) { assert(net); return net->msb; } extern "C" int ivl_parameter_lsb(ivl_parameter_t net) { assert(net); return net->lsb; } /* * No need to waste space with storing the width of the parameter since * it can easily be computed when needed. */ extern "C" unsigned ivl_parameter_width(ivl_parameter_t net) { unsigned result = 1; assert(net); if (net->msb >= net->lsb) result += net->msb - net->lsb; else result += net->lsb - net->msb; return result; } extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net) { assert(net); return net->value; } extern "C" const char* ivl_parameter_file(ivl_parameter_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net) { assert(net); return net->lineno; } extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net) { assert(net); return net->scope; } extern "C" ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj) { assert(obj); return obj->condit; } extern "C" int ivl_path_is_condit(ivl_delaypath_t obj) { assert(obj); return obj->conditional ? 1 : 0; } extern "C" int ivl_path_is_parallel(ivl_delaypath_t obj) { assert(obj); return obj->parallel ? 1 : 0; } extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t edg) { assert(obj); return obj->delay[edg]; } extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj) { assert(obj); assert(obj->scope); return obj->scope; } extern ivl_nexus_t ivl_path_source(ivl_delaypath_t net) { assert(net); return net->src; } extern int ivl_path_source_posedge(ivl_delaypath_t net) { assert(net); return net->posedge ? 1 : 0; } extern int ivl_path_source_negedge(ivl_delaypath_t net) { assert(net); return net->negedge ? 1 : 0; } extern "C" const char*ivl_process_file(ivl_process_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_process_lineno(ivl_process_t net) { assert(net); return net->lineno; } extern "C" ivl_process_type_t ivl_process_type(ivl_process_t net) { assert(net); return net->type_; } extern "C" int ivl_process_analog(ivl_process_t net) { assert(net); return net->analog_flag != 0; } extern "C" ivl_scope_t ivl_process_scope(ivl_process_t net) { assert(net); return net->scope_; } extern "C" ivl_statement_t ivl_process_stmt(ivl_process_t net) { assert(net); return net->stmt_; } extern "C" unsigned ivl_process_attr_cnt(ivl_process_t net) { assert(net); return net->nattr; } extern "C" ivl_attribute_t ivl_process_attr_val(ivl_process_t net, unsigned idx) { assert(net); assert(idx < net->nattr); return net->attr + idx; } extern "C" unsigned ivl_scope_attr_cnt(ivl_scope_t net) { assert(net); return net->nattr; } extern "C" ivl_attribute_t ivl_scope_attr_val(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->nattr); return net->attr + idx; } extern "C" const char* ivl_scope_basename(ivl_scope_t net) { assert(net); return net->name_; } extern "C" int ivl_scope_children(ivl_scope_t net, ivl_scope_f func, void*cd) { for (map::iterator cur = net->children.begin() ; cur != net->children.end() ; ++ cur ) { int rc = func(cur->second, cd); if (rc != 0) return rc; } return 0; } extern "C" size_t ivl_scope_childs(ivl_scope_t net) { assert(net); assert(net->child.size() == net->children.size()); return net->child.size(); } extern "C" ivl_scope_t ivl_scope_child(ivl_scope_t net, size_t idx) { assert(net); assert(idx < net->child.size()); return net->child[idx]; } extern "C" ivl_type_t ivl_scope_class(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->classes.size()); return net->classes[idx]; } extern "C" unsigned ivl_scope_classes(ivl_scope_t net) { assert(net); return net->classes.size(); } extern "C" ivl_statement_t ivl_scope_def(ivl_scope_t net) { assert(net); return net->def; } extern "C" const char*ivl_scope_def_file(ivl_scope_t net) { assert(net); return net->def_file.str(); } extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net) { assert(net); return net->def_lineno; } extern "C" unsigned ivl_scope_enumerates(ivl_scope_t net) { assert(net); return net->enumerations_.size(); } extern "C" ivl_enumtype_t ivl_scope_enumerate(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->enumerations_.size()); return net->enumerations_[idx]; } extern "C" unsigned ivl_scope_events(ivl_scope_t net) { assert(net); return net->nevent_; } extern "C" ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->nevent_); return net->event_[idx]; } extern "C" const char*ivl_scope_file(ivl_scope_t net) { assert(net); return net->file.str(); } extern "C" ivl_variable_type_t ivl_scope_func_type(ivl_scope_t net) { assert(net); assert(net->type_ == IVL_SCT_FUNCTION); return net->func_type; } extern "C" int ivl_scope_func_signed(ivl_scope_t net) { assert(net); assert(net->type_==IVL_SCT_FUNCTION); assert(net->func_type==IVL_VT_LOGIC || net->func_type==IVL_VT_BOOL); return net->func_signed? 1 : 0; } extern "C" unsigned ivl_scope_func_width(ivl_scope_t net) { assert(net); assert(net->type_ == IVL_SCT_FUNCTION); assert(net->func_type==IVL_VT_LOGIC || net->func_type==IVL_VT_BOOL); return net->func_width; } extern "C" unsigned ivl_scope_is_auto(ivl_scope_t net) { assert(net); return net->is_auto; } extern "C" unsigned ivl_scope_is_cell(ivl_scope_t net) { assert(net); return net->is_cell; } extern "C" unsigned ivl_scope_lineno(ivl_scope_t net) { assert(net); return net->lineno; } extern "C" unsigned ivl_scope_logs(ivl_scope_t net) { assert(net); return net->nlog_; } extern "C" ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->nlog_); return net->log_[idx]; } extern "C" unsigned ivl_scope_lpms(ivl_scope_t net) { assert(net); return net->nlpm_; } extern "C" ivl_lpm_t ivl_scope_lpm(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->nlpm_); return net->lpm_[idx]; } static unsigned scope_name_len(ivl_scope_t net) { unsigned len = 0; for (ivl_scope_t cur = net ; cur ; cur = cur->parent) len += strlen(cur->name_) + 1; return len; } static void push_scope_basename(ivl_scope_t net, char*buf) { assert(net); if (net->parent == 0) { strcpy(buf, net->name_); return; } push_scope_basename(net->parent, buf); strcat(buf, "."); strcat(buf, net->name_); } extern "C" const char* ivl_scope_name(ivl_scope_t net) { assert(net); static char*name_buffer = 0; static unsigned name_size = 0; if (net->parent == 0) return net->name_; unsigned needlen = scope_name_len(net); if (name_size < needlen) { name_buffer = (char*)realloc(name_buffer, needlen); name_size = needlen; } push_scope_basename(net, name_buffer); return name_buffer; } extern "C" unsigned ivl_scope_params(ivl_scope_t net) { assert(net); return net->param.size(); } extern "C" ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->param.size()); return & (net->param[idx]); } extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net) { assert(net); return net->parent; } extern "C" unsigned ivl_scope_mod_module_ports(ivl_scope_t net) { assert(net); assert(net->type_ == IVL_SCT_MODULE ); return static_cast(net->module_ports_info.size()); } extern "C" const char *ivl_scope_mod_module_port_name(ivl_scope_t net, unsigned idx ) { assert(net); assert(net->type_ == IVL_SCT_MODULE ); assert(idx < net->module_ports_info.size()); return net->module_ports_info[idx].name; } extern "C" ivl_signal_port_t ivl_scope_mod_module_port_type(ivl_scope_t net, unsigned idx ) { assert(net); switch( net->module_ports_info[idx].type ) { case PortType::PINPUT : return IVL_SIP_INPUT; case PortType::POUTPUT : return IVL_SIP_OUTPUT; case PortType::PINOUT : return IVL_SIP_INOUT; default : return IVL_SIP_NONE; } } extern "C" unsigned ivl_scope_mod_module_port_width(ivl_scope_t net, unsigned idx ) { assert(net); return net->module_ports_info[idx].width; } extern "C" unsigned ivl_scope_ports(ivl_scope_t net) { assert(net); if (net->type_ == IVL_SCT_MODULE || net->type_ == IVL_SCT_FUNCTION || net->type_ == IVL_SCT_TASK) return net->ports; return 0; } extern "C" ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx) { assert(net); assert(net->type_ == IVL_SCT_FUNCTION || net->type_ == IVL_SCT_TASK); assert(idx < net->ports); return net->u_.port[idx]; } extern "C" ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx) { assert(net); assert(net->type_ == IVL_SCT_MODULE); assert(idx < net->ports); return net->u_.nex[idx]; } extern "C" unsigned ivl_scope_sigs(ivl_scope_t net) { assert(net); return net->sigs_.size(); } extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->sigs_.size()); return net->sigs_[idx]; } extern "C" unsigned ivl_scope_switches(ivl_scope_t net) { assert(net); return net->switches.size(); } extern "C" ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx) { assert(net); assert(idx < net->switches.size()); return net->switches[idx]; } extern "C" int ivl_scope_time_precision(ivl_scope_t net) { assert(net); return net->time_precision; } extern "C" int ivl_scope_time_units(ivl_scope_t net) { assert(net); return net->time_units; } extern "C" ivl_scope_type_t ivl_scope_type(ivl_scope_t net) { assert(net); return net->type_; } extern "C" const char* ivl_scope_tname(ivl_scope_t net) { assert(net); return net->tname_; } extern "C" int ivl_signal_array_base(ivl_signal_t net) { assert(net); return net->array_base; } extern "C" unsigned ivl_signal_array_count(ivl_signal_t net) { assert(net); return net->array_words; } extern "C" unsigned ivl_signal_array_addr_swapped(ivl_signal_t net) { assert(net); return net->array_addr_swapped; } extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net) { assert(net); return net->array_dimensions_; } extern "C" ivl_discipline_t ivl_signal_discipline(ivl_signal_t net) { assert(net); return net->discipline; } extern "C" const char* ivl_signal_attr(ivl_signal_t net, const char*key) { assert(net); if (net->nattr == 0) return 0; for (unsigned idx = 0 ; idx < net->nattr ; idx += 1) if (strcmp(key, net->attr[idx].key) == 0) return net->attr[idx].type == IVL_ATT_STR ? net->attr[idx].val.str : 0; return 0; } extern "C" unsigned ivl_signal_attr_cnt(ivl_signal_t net) { assert(net); return net->nattr; } extern "C" ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx) { assert(net); assert(idx < net->nattr); return net->attr + idx; } extern "C" const char* ivl_signal_basename(ivl_signal_t net) { assert(net); return net->name_; } extern "C" const char* ivl_signal_name(ivl_signal_t net) { assert(net); static char*name_buffer = 0; static unsigned name_size = 0; unsigned needlen = scope_name_len(net->scope_); needlen += strlen(net->name_) + 2; if (name_size < needlen) { name_buffer = (char*)realloc(name_buffer, needlen); name_size = needlen; } push_scope_basename(net->scope_, name_buffer); strcat(name_buffer, "."); strcat(name_buffer, net->name_); return name_buffer; } extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word) { assert(net); assert(word < net->array_words); if (net->array_words > 1) { if (net->pins) { return net->pins[word]; } else { // net->pins can be NULL for a virtualized reg array. assert(net->type_ == IVL_SIT_REG); return NULL; } } else { return net->pin; } } extern "C" unsigned ivl_signal_packed_dimensions(ivl_signal_t net) { assert(net); return net->packed_dims.size(); } extern "C" int ivl_signal_packed_msb(ivl_signal_t net, unsigned dim) { assert(net); assert(dim < net->packed_dims.size()); return net->packed_dims[dim].get_msb(); } extern "C" int ivl_signal_packed_lsb(ivl_signal_t net, unsigned dim) { assert(net); assert(dim < net->packed_dims.size()); return net->packed_dims[dim].get_lsb(); } extern "C" int ivl_signal_msb(ivl_signal_t net) { assert(net); if (net->packed_dims.empty()) return 0; assert(net->packed_dims.size() == 1); return net->packed_dims[0].get_msb(); } extern "C" int ivl_signal_lsb(ivl_signal_t net) { assert(net); if (net->packed_dims.empty()) return 0; assert(net->packed_dims.size() == 1); return net->packed_dims[0].get_lsb(); } extern "C" ivl_scope_t ivl_signal_scope(ivl_signal_t net) { assert(net); return net->scope_; } extern "C" unsigned ivl_signal_width(ivl_signal_t net) { assert(net); assert(net->net_type); return net->net_type->packed_width(); } extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net) { assert(net); return net->port_; } extern "C" int ivl_signal_module_port_index(ivl_signal_t net) { assert(net); return net->module_port_index_; } extern "C" int ivl_signal_local(ivl_signal_t net) { assert(net); return net->local_; } extern "C" int ivl_signal_signed(ivl_signal_t net) { assert(net); assert(net->net_type); return net->net_type->get_signed()? 1 : 0; } extern "C" unsigned ivl_signal_forced_net(ivl_signal_t net) { assert(net); return net->forced_net_; } extern "C" const char* ivl_signal_file(ivl_signal_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_signal_lineno(ivl_signal_t net) { assert(net); return net->lineno; } extern "C" int ivl_signal_integer(ivl_signal_t net) { assert(net); if (const netvector_t*vec = dynamic_cast (net->net_type)) return vec->get_isint()? 1 : 0; else if (const netenum_t*enm = dynamic_cast (net->net_type)) return enm->get_isint()? 1 : 0; else return 0; } extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net) { assert(net); assert(net->net_type); return net->net_type->base_type(); } extern "C" ivl_type_t ivl_signal_net_type(ivl_signal_t net) { assert(net); return net->net_type; } extern "C" unsigned ivl_signal_npath(ivl_signal_t net) { assert(net); return net->npath; } extern "C" ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx) { assert(net); assert(idx < net->npath); return net->path + idx; } extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net) { assert(net); return net->type_; } extern "C" ivl_statement_type_t ivl_statement_type(ivl_statement_t net) { assert(net); return net->type_; } extern "C" const char* ivl_stmt_file(ivl_statement_t net) { assert(net); return net->file.str(); } extern "C" unsigned ivl_stmt_lineno(ivl_statement_t net) { assert(net); return net->lineno; } extern "C" ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_BLOCK: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: return net->u_.block_.scope; default: assert(0); return 0; } } extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_BLOCK: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: return net->u_.block_.nstmt_; default: assert(0); return 0; } } extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i) { assert(net); switch (net->type_) { case IVL_ST_BLOCK: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: return net->u_.block_.stmt_ + i; default: assert(0); return 0; } } extern "C" ivl_scope_t ivl_stmt_call(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ALLOC: return net->u_.alloc_.scope; case IVL_ST_DISABLE: return net->u_.disable_.scope; case IVL_ST_FREE: return net->u_.free_.scope; case IVL_ST_UTASK: return net->u_.utask_.def; default: assert(0); return 0; } } extern "C" bool ivl_stmt_flow_control(ivl_statement_t net) { return net->u_.disable_.flow_control; } extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: return net->u_.case_.ncase; default: assert(0); return 0; } } extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: assert(idx < net->u_.case_.ncase); return net->u_.case_.case_ex[idx]; default: assert(0); return 0; } } extern "C" ivl_case_quality_t ivl_stmt_case_quality(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: return net->u_.case_.quality; default: assert(0); return IVL_CASE_QUALITY_BASIC; } } extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: assert(idx < net->u_.case_.ncase); return net->u_.case_.case_st + idx; default: assert(0); return 0; } } extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN_NB: return net->u_.assign_.count; case IVL_ST_CONDIT: return net->u_.condit_.cond_; case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: return net->u_.case_.cond; case IVL_ST_DO_WHILE: case IVL_ST_REPEAT: case IVL_ST_WHILE: return net->u_.while_.cond_; default: assert(0); return 0; } } extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net) { assert(net); assert(net->type_ == IVL_ST_CONDIT); if (net->u_.condit_.stmt_[1].type_ == IVL_ST_NONE) return 0; else return net->u_.condit_.stmt_ + 1; } extern "C" ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net) { assert(net); assert(net->type_ == IVL_ST_CONDIT); if (net->u_.condit_.stmt_[0].type_ == IVL_ST_NONE) return 0; else return net->u_.condit_.stmt_ + 0; } extern "C" ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN: case IVL_ST_ASSIGN_NB: return net->u_.assign_.delay; case IVL_ST_DELAYX: return net->u_.delayx_.expr; case IVL_ST_NB_TRIGGER: return net->u_.wait_.delay; default: assert(0); return 0; } } extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net) { assert(net); assert(net->type_ == IVL_ST_DELAY); return net->u_.delay_.value; } extern "C" unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net) { assert(net); if (net->type_ == IVL_ST_WAIT) { return net->u_.wait_.needs_t0_trigger; } else { return 0; } } extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN_NB: return net->u_.assign_.nevent; case IVL_ST_NB_TRIGGER: return 1; case IVL_ST_TRIGGER: return 1; case IVL_ST_WAIT: return net->u_.wait_.nevent; default: assert(0); } return 0; } extern "C" ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN_NB: assert(idx < net->u_.assign_.nevent); if (net->u_.assign_.nevent == 1) return net->u_.assign_.event; else return net->u_.assign_.events[idx]; case IVL_ST_NB_TRIGGER: assert(idx == 0); return net->u_.wait_.event; case IVL_ST_TRIGGER: assert(idx == 0); return net->u_.wait_.event; case IVL_ST_WAIT: assert(idx < net->u_.wait_.nevent); if (net->u_.wait_.nevent == 1) return net->u_.wait_.event; else return net->u_.wait_.events[idx]; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_stmt_lexp(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_CONTRIB: return net->u_.contrib_.lval; default: assert(0); } return 0; } extern "C" ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN: case IVL_ST_ASSIGN_NB: case IVL_ST_CASSIGN: case IVL_ST_DEASSIGN: case IVL_ST_FORCE: case IVL_ST_RELEASE: assert(idx < net->u_.assign_.lvals_); return net->u_.assign_.lval_ + idx; default: assert(0); } return 0; } extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN: case IVL_ST_ASSIGN_NB: case IVL_ST_CASSIGN: case IVL_ST_DEASSIGN: case IVL_ST_FORCE: case IVL_ST_RELEASE: return net->u_.assign_.lvals_; default: assert(0); } return 0; } extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net) { assert(net); assert((net->type_ == IVL_ST_ASSIGN) || (net->type_ == IVL_ST_ASSIGN_NB) || (net->type_ == IVL_ST_CASSIGN) || (net->type_ == IVL_ST_DEASSIGN) || (net->type_ == IVL_ST_FORCE) || (net->type_ == IVL_ST_RELEASE)); unsigned sum = 0; unsigned nlvals; struct ivl_lval_s*lvals; nlvals = net->u_.assign_.lvals_; lvals = net->u_.assign_.lval_; for (unsigned idx = 0 ; idx < nlvals ; idx += 1) { ivl_lval_t cur = lvals + idx; switch(cur->type_) { case IVL_LVAL_REG: case IVL_LVAL_ARR: case IVL_LVAL_LVAL: sum += ivl_lval_width(cur); break; default: assert(0); } } return sum; } extern "C" const char* ivl_stmt_name(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_STASK: return net->u_.stask_.name_; default: assert(0); } return 0; } extern "C" char ivl_stmt_opcode(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN: return net->u_.assign_.oper; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx) { assert(net); switch (net->type_) { case IVL_ST_STASK: assert(idx < net->u_.stask_.nparm_); return net->u_.stask_.parms_[idx]; default: assert(0); } return 0; } extern "C" unsigned ivl_stmt_parm_count(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_STASK: return net->u_.stask_.nparm_; default: assert(0); } return 0; } extern "C" ivl_expr_t ivl_stmt_rval(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_ASSIGN: case IVL_ST_ASSIGN_NB: case IVL_ST_CASSIGN: case IVL_ST_FORCE: return net->u_.assign_.rval_; case IVL_ST_CONTRIB: return net->u_.contrib_.rval; default: assert(0); } return 0; } extern "C" ivl_sfunc_as_task_t ivl_stmt_sfunc_as_task(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_STASK: return net->u_.stask_.sfunc_as_task_; default: assert(0); } return IVL_SFUNC_AS_TASK_ERROR; } extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net) { assert(net); switch (net->type_) { case IVL_ST_DELAY: return net->u_.delay_.stmt_; case IVL_ST_DELAYX: return net->u_.delayx_.stmt_; case IVL_ST_FOREVER: return net->u_.forever_.stmt_; case IVL_ST_WAIT: return net->u_.wait_.stmt_; case IVL_ST_DO_WHILE: case IVL_ST_REPEAT: case IVL_ST_WHILE: return net->u_.while_.stmt_; default: assert(0); } return 0; } extern "C" const char*ivl_switch_basename(ivl_switch_t net) { assert(net); return net->name; } extern "C" ivl_scope_t ivl_switch_scope(ivl_switch_t net) { assert(net); return net->scope; } extern "C" ivl_switch_type_t ivl_switch_type(ivl_switch_t net) { assert(net); return net->type; } extern "C" ivl_nexus_t ivl_switch_a(ivl_switch_t net) { assert(net); return net->pins[0]; } extern "C" ivl_nexus_t ivl_switch_b(ivl_switch_t net) { assert(net); return net->pins[1]; } extern "C" ivl_nexus_t ivl_switch_enable(ivl_switch_t net) { assert(net); return net->pins[2]; } extern "C" unsigned ivl_switch_width(ivl_switch_t net) { assert(net); return net->width; } extern "C" unsigned ivl_switch_part(ivl_switch_t net) { assert(net); return net->part; } extern "C" unsigned ivl_switch_offset(ivl_switch_t net) { assert(net); return net->offset; } extern "C" ivl_expr_t ivl_switch_delay(ivl_switch_t net, unsigned transition) { assert(net); assert(transition < 3); return net->delay[transition]; } extern "C" const char* ivl_switch_file(ivl_switch_t net) { assert(net); return net->file; } extern "C" ivl_island_t ivl_switch_island(ivl_switch_t net) { assert(net); return net->island; } extern "C" unsigned ivl_switch_lineno(ivl_switch_t net) { assert(net); return net->lineno; } extern "C" ivl_variable_type_t ivl_type_base(ivl_type_t net) { if (net == 0) return IVL_VT_NO_TYPE; else return net->base_type(); } extern "C" ivl_type_t ivl_type_element(ivl_type_t net) { if (const netarray_t*da = dynamic_cast (net)) return da->element_type(); assert(0); return 0; } extern "C" unsigned ivl_type_packed_width(ivl_type_t net) { return net->packed_width(); } extern "C" unsigned ivl_type_packed_dimensions(ivl_type_t net) { assert(net); vector slice = net->slice_dimensions(); return slice.size(); } extern "C" int ivl_type_packed_lsb(ivl_type_t net, unsigned dim) { assert(net); vector slice = net->slice_dimensions(); assert(dim < slice.size()); return slice[dim].get_lsb(); } extern "C" int ivl_type_packed_msb(ivl_type_t net, unsigned dim) { assert(net); vector slice = net->slice_dimensions(); assert(dim < slice.size()); return slice[dim].get_msb(); } extern "C" const char* ivl_type_name(ivl_type_t net) { if (const netclass_t*class_type = dynamic_cast(net)) return class_type->get_name(); return 0; } extern "C" int ivl_type_properties(ivl_type_t net) { const netclass_t*class_type = dynamic_cast(net); assert(class_type); return class_type->get_properties(); } extern "C" const char* ivl_type_prop_name(ivl_type_t net, int idx) { if (idx < 0) return 0; const netclass_t*class_type = dynamic_cast(net); assert(class_type); return class_type->get_prop_name(idx); } extern "C" ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx) { const netclass_t*class_type = dynamic_cast(net); assert(class_type); return class_type->get_prop_type(idx); } extern "C" int ivl_type_signed(ivl_type_t net) { assert(net); return net->get_signed()? 1 : 0; } iverilog-12_0/t-dll-expr.cc000066400000000000000000000470411435245347300156540ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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 # include # include "t-dll.h" # include "netlist.h" # include "netclass.h" # include # include # include "ivl_alloc.h" # include "ivl_assert.h" using namespace std; /* * This is a little convenience function for converting a NetExpr * expression type to the expression type used by ivl_expr_t objects. */ static ivl_variable_type_t get_expr_type(const NetExpr*net) { return net->expr_type(); } /* * These methods implement the expression scan that generates the * ivl_expr_t representing the expression. Each method leaves the * expr_ member filled with the ivl_expr_t that represents it. Each * method expects that the expr_ member empty (0) when it starts. */ /* * This function takes an expression in the expr_ member that is * already built up, and adds a subtraction of the given constant. */ void dll_target::sub_off_from_expr_(long off) { assert(expr_ != 0); char*bits; ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); tmpc->type_ = IVL_EX_NUMBER; tmpc->value_ = IVL_VT_VECTOR; tmpc->net_type= 0; tmpc->width_ = expr_->width_; tmpc->signed_ = expr_->signed_; tmpc->sized_ = 1; tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_); for (unsigned idx = 0 ; idx < tmpc->width_ ; idx += 1) { bits[idx] = (off & 1)? '1' : '0'; off >>= 1; } /* Now make the subtracter (x-4 in the above example) that has as input A the index expression and input B the constant to subtract. */ ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); tmps->type_ = IVL_EX_BINARY; tmps->value_ = IVL_VT_VECTOR; tmps->net_type= 0; tmps->width_ = tmpc->width_; tmps->signed_ = tmpc->signed_; tmps->sized_ = 1; tmps->u_.binary_.op_ = '-'; tmps->u_.binary_.lef_ = expr_; tmps->u_.binary_.rig_ = tmpc; /* Replace (x) with (x-off) */ expr_ = tmps; } void dll_target::mul_expr_by_const_(long val) { assert(expr_ != 0); char*bits; ivl_expr_t tmpc = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); tmpc->type_ = IVL_EX_NUMBER; tmpc->value_ = IVL_VT_VECTOR; tmpc->net_type= 0; tmpc->width_ = expr_->width_; tmpc->signed_ = expr_->signed_; tmpc->sized_ = 1; tmpc->u_.number_.bits_ = bits = (char*)malloc(tmpc->width_); for (unsigned idx = 0 ; idx < tmpc->width_ ; idx += 1) { bits[idx] = (val & 1)? '1' : '0'; val >>= 1; } /* Now make the subtracter (x-4 in the above example) that has as input A the index expression and input B the constant to subtract. */ ivl_expr_t tmps = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); tmps->type_ = IVL_EX_BINARY; tmps->value_ = IVL_VT_VECTOR; tmpc->net_type= 0; tmps->width_ = tmpc->width_; tmps->signed_ = tmpc->signed_; tmps->sized_ = 1; tmps->u_.binary_.op_ = '*'; tmps->u_.binary_.lef_ = expr_; tmps->u_.binary_.rig_ = tmpc; /* Replace (x) with (x*valf) */ expr_ = tmps; } ivl_expr_t dll_target::expr_from_value_(const verinum&val) { ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); unsigned idx; char*bits; expr->type_ = IVL_EX_NUMBER; expr->value_= IVL_VT_VECTOR; expr->net_type=0; expr->width_= val.len(); expr->signed_ = val.has_sign()? 1 : 0; expr->sized_= 1; expr->u_.number_.bits_ = bits = (char*)malloc(expr->width_ + 1); for (idx = 0 ; idx < expr->width_ ; idx += 1) switch (val.get(idx)) { case verinum::V0: bits[idx] = '0'; break; case verinum::V1: bits[idx] = '1'; break; case verinum::Vx: bits[idx] = 'x'; break; case verinum::Vz: bits[idx] = 'z'; break; default: assert(0); } bits[expr->width_] = 0; return expr; } void dll_target::expr_access_func(const NetEAccess*net) { assert(expr_ == 0); // Make a stub Branch Access Function expression node. expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_BACCESS; expr_->value_ = IVL_VT_REAL; expr_->net_type=0; expr_->width_ = 1; expr_->signed_= 1; expr_->sized_ = 1; FILE_NAME(expr_, net); expr_->u_.branch_.branch = net->get_branch()->target_obj(); expr_->u_.branch_.nature = net->get_nature(); } void dll_target::expr_array_pattern(const NetEArrayPattern*net) { assert(expr_ == 0); ivl_expr_t expr_tmp = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_tmp->type_ = IVL_EX_ARRAY_PATTERN; expr_tmp->value_= net->expr_type(); expr_tmp->net_type = net->net_type(); expr_tmp->width_ = 1; expr_tmp->signed_ = 0; expr_tmp->sized_ = 0; FILE_NAME(expr_tmp, net); expr_tmp->u_.array_pattern_.parms = net->item_size(); expr_tmp->u_.array_pattern_.parm = new ivl_expr_t [net->item_size()]; for (size_t idx = 0 ; idx < net->item_size() ; idx += 1) { const NetExpr*tmp = net->item(idx); tmp->expr_scan(this); expr_tmp->u_.array_pattern_.parm[idx] = expr_; expr_ = 0; } expr_ = expr_tmp; } void dll_target::expr_binary(const NetEBinary*net) { assert(expr_ == 0); net->left()->expr_scan(this); ivl_expr_t left = expr_; expr_ = 0; net->right()->expr_scan(this); ivl_expr_t rght = expr_; expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_BINARY; expr_->value_= get_expr_type(net); expr_->net_type=0; expr_->width_= net->expr_width(); expr_->signed_ = net->has_sign()? 1 : 0; expr_->sized_= 1; FILE_NAME(expr_, net); expr_->u_.binary_.op_ = net->op(); expr_->u_.binary_.lef_ = left; expr_->u_.binary_.rig_ = rght; } void dll_target::expr_concat(const NetEConcat*net) { assert(expr_ == 0); ivl_expr_t cur = new struct ivl_expr_s; assert(cur); cur->type_ = IVL_EX_CONCAT; cur->value_ = net->expr_type(); cur->net_type=0; cur->width_ = net->expr_width(); cur->signed_ = net->has_sign() ? 1 : 0; cur->sized_ = 1; FILE_NAME(cur, net); cur->u_.concat_.rept = net->repeat(); cur->u_.concat_.parms = net->nparms(); cur->u_.concat_.parm = new ivl_expr_t [net->nparms()]; for (unsigned idx = 0 ; idx < net->nparms() ; idx += 1) { expr_ = 0; net->parm(idx)->expr_scan(this); assert(expr_); cur->u_.concat_.parm[idx] = expr_; } expr_ = cur; } void dll_target::expr_const(const NetEConst*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->value_= net->expr_type(); expr_->net_type=0; FILE_NAME(expr_, net); if (net->value().is_string()) { expr_->type_ = IVL_EX_STRING; expr_->width_= net->expr_width(); expr_->u_.string_.value_ =strdup(net->value().as_string().c_str()); } else { verinum val = net->value(); unsigned idx; char*bits; expr_->type_ = IVL_EX_NUMBER; expr_->width_= net->expr_width(); expr_->signed_ = net->has_sign()? 1 : 0; expr_->sized_= net->has_width()? 1 : 0; expr_->u_.number_.bits_ = bits = (char*)malloc(expr_->width_); for (idx = 0 ; idx < expr_->width_ ; idx += 1) switch (val.get(idx)) { case verinum::V0: bits[idx] = '0'; break; case verinum::V1: bits[idx] = '1'; break; case verinum::Vx: bits[idx] = 'x'; break; case verinum::Vz: bits[idx] = 'z'; break; default: assert(0); } } } void dll_target::expr_param(const NetEConstParam*net) { ivl_scope_t scop = find_scope(des_, net->scope()); ivl_parameter_t par = scope_find_param(scop, net->name()); if (par == 0) { cerr << net->get_fileline() << ": internal error: " << "Parameter " << net->name() << " missing from " << ivl_scope_name(scop) << endl; } assert(par); expr_const(net); expr_->u_.string_.parameter = par; } void dll_target::expr_rparam(const NetECRealParam*net) { ivl_scope_t scop = find_scope(des_, net->scope()); ivl_parameter_t par = scope_find_param(scop, net->name()); if (par == 0) { cerr << net->get_fileline() << ": internal error: " << "Parameter " << net->name() << " missing from " << ivl_scope_name(scop) << endl; } assert(par); assert(par->value); expr_ = par->value; } void dll_target::expr_creal(const NetECReal*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->width_ = net->expr_width(); expr_->signed_ = 1; expr_->sized_ = 1; expr_->type_ = IVL_EX_REALNUM; FILE_NAME(expr_, net); expr_->value_= IVL_VT_REAL; expr_->net_type=0; expr_->u_.real_.value = net->value().as_double(); } void dll_target::expr_last(const NetELast*net) { assert(expr_ == 0); ivl_expr_t expr = new struct ivl_expr_s; expr->type_ = IVL_EX_SFUNC; expr->value_ = IVL_VT_LOGIC; expr->width_ = 32; expr->signed_ = 1; expr->sized_ = 1; expr->net_type = 0; FILE_NAME(expr, net); expr->u_.sfunc_.name_ = "$high"; ivl_signal_t sig = find_signal(des_, net->sig()); ivl_expr_t esig = new struct ivl_expr_s; esig->type_ = IVL_EX_SIGNAL; esig->value_ = IVL_VT_DARRAY; esig->net_type= sig->net_type; esig->width_ = 1; esig->signed_ = sig->net_type->get_signed()? 1 : 0; FILE_NAME(esig, net); esig->u_.signal_.word = 0; esig->u_.signal_.sig = sig; expr->u_.sfunc_.parms = 1; expr->u_.sfunc_.parm = new ivl_expr_t[1]; expr->u_.sfunc_.parm[0] = esig; expr_ = expr; } void dll_target::expr_new(const NetENew*net) { ivl_expr_t size = 0; ivl_expr_t init_val = 0; if (net->size_expr()) { net->size_expr()->expr_scan(this); size = expr_; expr_ = 0; } if (net->init_expr()) { net->init_expr()->expr_scan(this); init_val = expr_; expr_ = 0; } assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->width_ = net->expr_width(); expr_->signed_ = 0; expr_->sized_ = 1; expr_->type_ = IVL_EX_NEW; FILE_NAME(expr_, net); expr_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS expr_->net_type= net->get_type(); expr_->u_.new_.size = size; expr_->u_.new_.init_val = init_val; } void dll_target::expr_null(const NetENull*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->width_ = net->expr_width(); expr_->signed_ = 0; expr_->sized_ = 1; expr_->type_ = IVL_EX_NULL; FILE_NAME(expr_, net); expr_->value_ = IVL_VT_CLASS; expr_->net_type= 0; } void dll_target::expr_property(const NetEProperty*net) { ivl_expr_t index = 0; if (const NetExpr*index_expr = net->get_index()) { index_expr->expr_scan(this); index = expr_; expr_ = 0; } assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->width_ = net->expr_width(); expr_->signed_ = net->has_sign(); expr_->sized_ = 1; expr_->type_ = IVL_EX_PROPERTY; FILE_NAME(expr_, net); expr_->value_ = net->expr_type(); expr_->net_type= net->net_type(); expr_->u_.property_.sig = find_signal(des_, net->get_sig()); expr_->u_.property_.prop_idx = net->property_idx(); expr_->u_.property_.index = index; } void dll_target::expr_event(const NetEEvent*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_EVENT; FILE_NAME(expr_, net); expr_->value_= IVL_VT_VOID; expr_->net_type=0; /* Locate the event by name. Save the ivl_event_t in the expression so that the generator can find it easily. */ const NetEvent*ev = net->event(); ivl_scope_t ev_scope = lookup_scope_(ev->scope()); for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { expr_->u_.event_.event = ev_scope->event_[idx]; break; } } } void dll_target::expr_scope(const NetEScope*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_SCOPE; FILE_NAME(expr_, net); expr_->value_= IVL_VT_VOID; expr_->net_type=0; expr_->u_.scope_.scope = lookup_scope_(net->scope()); } void dll_target::expr_scopy(const NetEShallowCopy*net) { assert(expr_ == 0); net->expr_scan_oper1(this); ivl_expr_t expr1 = expr_; expr_ = 0; net->expr_scan_oper2(this); ivl_expr_t expr2 = expr_; expr_ = 0; expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_SHALLOWCOPY; FILE_NAME(expr_, net); expr_->value_ = net->expr_type(); expr_->net_type = net->net_type(); expr_->u_.shallow_.dest = expr1; expr_->u_.shallow_.src = expr2; } void dll_target::expr_netenum(const NetENetenum*net) { assert(expr_ == 0); expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_ENUMTYPE; FILE_NAME(expr_, net); expr_->value_= IVL_VT_VOID; expr_->net_type=0; expr_->u_.enumtype_.type = net->netenum(); } void dll_target::expr_select(const NetESelect*net) { assert(expr_ == 0); net->sub_expr()->expr_scan(this); ivl_expr_t expr = expr_; expr_ = 0; if (net->select()) net->select()->expr_scan(this); ivl_expr_t base = expr_; expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_SELECT; expr_->value_= net->expr_type(); expr_->net_type=0; expr_->width_= net->expr_width(); expr_->signed_ = net->has_sign()? 1 : 0; expr_->sized_= 1; FILE_NAME(expr_, net); expr_->u_.select_.sel_type_ = net->select_type(); expr_->u_.select_.expr_ = expr; expr_->u_.select_.base_ = base; } void dll_target::expr_sfunc(const NetESFunc*net) { assert(expr_ == 0); ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr->type_ = IVL_EX_SFUNC; expr->value_= net->expr_type(); expr->net_type=net->net_type(); expr->width_= net->expr_width(); expr->signed_ = net->has_sign()? 1 : 0; expr->sized_= 1; FILE_NAME(expr, net); /* system function names are lex_strings strings. */ expr->u_.sfunc_.name_ = net->name(); unsigned cnt = net->nparms(); expr->u_.sfunc_.parms = cnt; expr->u_.sfunc_.parm = new ivl_expr_t[cnt]; /* make up the parameter expressions. */ for (unsigned idx = 0 ; idx < cnt ; idx += 1) { net->parm(idx)->expr_scan(this); assert(expr_); expr->u_.sfunc_.parm[idx] = expr_; expr_ = 0; } expr_ = expr; } void dll_target::expr_ternary(const NetETernary*net) { assert(expr_ == 0); ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr->type_ = IVL_EX_TERNARY; expr->value_= net->expr_type(); expr->net_type=0; expr->width_ = net->expr_width(); expr->signed_ = net->has_sign()? 1 : 0; expr->sized_ = 1; FILE_NAME(expr, net); net->cond_expr()->expr_scan(this); assert(expr_); expr->u_.ternary_.cond = expr_; expr_ = 0; net->true_expr()->expr_scan(this); assert(expr_); expr->u_.ternary_.true_e = expr_; expr_ = 0; net->false_expr()->expr_scan(this); assert(expr_); expr->u_.ternary_.false_e = expr_; expr_ = expr; } void dll_target::expr_signal(const NetESignal*net) { ivl_signal_t sig = find_signal(des_, net->sig()); assert(expr_ == 0); /* If there is a word expression, generate it. */ ivl_expr_t word_expr = 0; if (const NetExpr*word = net->word_index()) { word->expr_scan(this); assert(expr_); word_expr = expr_; expr_ = 0; } expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_SIGNAL; expr_->value_= net->expr_type(); expr_->net_type=0; expr_->width_= net->expr_width(); expr_->signed_ = net->has_sign()? 1 : 0; expr_->sized_= 1; FILE_NAME(expr_, net); expr_->u_.signal_.word = word_expr; expr_->u_.signal_.sig = sig; /* Make account for the special case that this is a reference to an array as a whole. We detect this case by noting that this is an array (more than 0 array dimensions) and that there is no word select expression. For this case, we have an IVL_EX_ARRAY expression instead of a SIGNAL expression. */ if (sig->array_dimensions_ > 0 && word_expr == 0) { expr_->type_ = IVL_EX_ARRAY; expr_->width_ = 0; // Doesn't make much sense for arrays. } } void dll_target::expr_ufunc(const NetEUFunc*net) { assert(expr_ == 0); ivl_expr_t expr = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr->type_ = IVL_EX_UFUNC; expr->value_= net->expr_type(); expr->net_type=0; expr->width_= net->expr_width(); expr->signed_ = net->has_sign()? 1 : 0; expr->sized_= 1; FILE_NAME(expr, net); expr->u_.ufunc_.def = lookup_scope_(net->func()); if (expr->u_.ufunc_.def == 0) { cerr << net->get_fileline() << ": internal error: " << "dll_target::expr_ufunc: " << "Unable to match scope " << scope_path(net->func()) << endl; } ivl_assert(*net, expr->u_.ufunc_.def); ivl_assert(*net, expr->u_.ufunc_.def->type_ == IVL_SCT_FUNCTION); unsigned cnt = net->parm_count(); expr->u_.ufunc_.parms = cnt; expr->u_.ufunc_.parm = new ivl_expr_t[cnt]; /* make up the parameter expressions. */ for (unsigned idx = 0 ; idx < cnt ; idx += 1) { net->parm(idx)->expr_scan(this); assert(expr_); expr->u_.ufunc_.parm[idx] = expr_; expr_ = 0; } expr_ = expr; } void dll_target::expr_unary(const NetEUnary*net) { assert(expr_ == 0); net->expr()->expr_scan(this); assert(expr_); ivl_expr_t sub = expr_; expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s)); expr_->type_ = IVL_EX_UNARY; expr_->value_= net->expr_type(); expr_->net_type=0; expr_->width_ = net->expr_width(); expr_->signed_ = net->has_sign()? 1 : 0; expr_->sized_ = 1; FILE_NAME(expr_, net); expr_->u_.unary_.op_ = net->op(); expr_->u_.unary_.sub_ = sub; } iverilog-12_0/t-dll-proc.cc000066400000000000000000000656421435245347300156500ustar00rootroot00000000000000/* * Copyright (c) 2000-2022 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.will need a Picture Elements Binary Software * License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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 # include # include "target.h" # include "ivl_target.h" # include "compiler.h" # include "t-dll.h" # include "netclass.h" # include # include "ivl_alloc.h" # include "ivl_assert.h" bool dll_target::process(const NetProcTop*net) { bool rc_flag = true; ivl_process_t obj = (struct ivl_process_s*) calloc(1, sizeof(struct ivl_process_s)); obj->type_ = net->type(); obj->analog_flag = 0; FILE_NAME(obj, net); /* Save the scope of the process. */ obj->scope_ = lookup_scope_(net->scope()); obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); /* This little bit causes the process to be completely generated so that it can be passed to the DLL. The stmt_cur_ member is used to hold a pointer to the current statement in progress, and the emit_proc() method fills in that object. We know a few things about the current statement: we are not in the middle of one, and when we are done, we have our statement back. The asserts check these conditions. */ assert(stmt_cur_ == 0); stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_); rc_flag = net->statement()->emit_proc(this) && rc_flag; assert(stmt_cur_); obj->stmt_ = stmt_cur_; stmt_cur_ = 0; /* Save the process in the design. */ obj->next_ = des_.threads_; des_.threads_ = obj; return rc_flag; } void dll_target::task_def(const NetScope*net) { ivl_scope_t scop = lookup_scope_(net); const NetTaskDef*def = net->task_def(); assert(def); assert(def->proc()); assert(stmt_cur_ == 0); stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_); def->proc()->emit_proc(this); assert(stmt_cur_); scop->def = stmt_cur_; stmt_cur_ = 0; scop->ports = def->port_count(); if (scop->ports > 0) { scop->u_.port = new ivl_signal_t[scop->ports]; for (unsigned idx = 0 ; idx < scop->ports ; idx += 1) scop->u_.port[idx] = find_signal(des_, def->port(idx)); } } bool dll_target::func_def(const NetScope*net) { ivl_scope_t scop = lookup_scope_(net); const NetFuncDef*def = net->func_def(); assert(def); assert(def->proc()); assert(stmt_cur_ == 0); stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_); def->proc()->emit_proc(this); assert(stmt_cur_); scop->def = stmt_cur_; stmt_cur_ = 0; scop->ports = def->port_count() + 1; if (scop->ports > 0) { scop->u_.port = new ivl_signal_t[scop->ports]; for (unsigned idx = 1 ; idx < scop->ports ; idx += 1) scop->u_.port[idx] = find_signal(des_, def->port(idx-1)); } /* FIXME: the ivl_target API expects port-0 to be the output port. This assumes that the return value is a signal, which is *not* correct. Someday, I'm going to have to change this, but that will break code generators that use this result. */ if (const NetNet*ret_sig = def->return_sig()) scop->u_.port[0] = find_signal(des_, ret_sig); else scop->u_.port[0] = 0; /* If there is no return value, then this is a void function. */ return true; } /* * This private function makes the assignment lvals for the various * kinds of assignment statements. */ bool dll_target::make_assign_lvals_(const NetAssignBase*net) { bool flag = true; assert(stmt_cur_); unsigned cnt = net->l_val_count(); stmt_cur_->u_.assign_.lvals_ = cnt; stmt_cur_->u_.assign_.lval_ = new struct ivl_lval_s[cnt]; stmt_cur_->u_.assign_.delay = 0; for (unsigned idx = 0 ; idx < cnt ; idx += 1) { struct ivl_lval_s*cur = stmt_cur_->u_.assign_.lval_ + idx; const NetAssign_*asn = net->l_val(idx); flag &= make_single_lval_(net, cur, asn); } return flag; } bool dll_target::make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, const NetAssign_*asn) { bool flag = true; const NetExpr*loff = asn->get_base(); if (loff == 0) { cur->loff = 0; cur->sel_type = IVL_SEL_OTHER; } else { loff->expr_scan(this); cur->loff = expr_; cur->sel_type = asn->select_type(); expr_ = 0; } cur->width_ = asn->lwidth(); if (asn->sig()) { cur->type_ = IVL_LVAL_REG; cur->n.sig = find_signal(des_, asn->sig()); } else { const NetAssign_*asn_nest = asn->nest(); ivl_assert(*li, asn_nest); struct ivl_lval_s*cur_nest = new struct ivl_lval_s; make_single_lval_(li, cur_nest, asn_nest); cur->type_ = IVL_LVAL_LVAL; cur->n.nest = cur_nest; } cur->idx = 0; // If there is a word select expression, it is // really an array index. Note that the word index // expression is already converted to canonical // form by elaboration. if (asn->word()) { assert(expr_ == 0); asn->word()->expr_scan(this); cur->type_ = IVL_LVAL_ARR; cur->idx = expr_; expr_ = 0; } cur->property_idx = asn->get_property_idx(); return flag; } void dll_target::proc_alloc(const NetAlloc*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_ALLOC; stmt_cur_->u_.alloc_.scope = lookup_scope_(net->scope()); } /* */ bool dll_target::proc_assign(const NetAssign*net) { bool flag = true; assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); stmt_cur_->type_ = IVL_ST_ASSIGN; FILE_NAME(stmt_cur_, net); stmt_cur_->u_.assign_.delay = 0; /* Make the lval fields. */ flag &= make_assign_lvals_(net); stmt_cur_->u_.assign_.oper = net->assign_operator(); assert(expr_ == 0); net->rval()->expr_scan(this); stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; const NetExpr*del = net->get_delay(); if (del) { del->expr_scan(this); stmt_cur_->u_.assign_.delay = expr_; expr_ = 0; } return flag; } void dll_target::proc_assign_nb(const NetAssignNB*net) { const NetExpr* delay_exp = net->get_delay(); const NetExpr* cnt_exp = net->get_count(); assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); stmt_cur_->type_ = IVL_ST_ASSIGN_NB; FILE_NAME(stmt_cur_, net); stmt_cur_->u_.assign_.delay = 0; stmt_cur_->u_.assign_.count = 0; stmt_cur_->u_.assign_.nevent = 0; /* Make the lval fields. */ make_assign_lvals_(net); /* Make the rval field. */ assert(expr_ == 0); net->rval()->expr_scan(this); stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; /* Process a delay if it exists. */ if (const NetEConst*delay_num = dynamic_cast(delay_exp)) { verinum val = delay_num->value(); ivl_expr_t de = new struct ivl_expr_s; de->type_ = IVL_EX_DELAY; de->width_ = 8 * sizeof(uint64_t); de->signed_ = 0; de->u_.delay_.value = val.as_ulong64(); stmt_cur_->u_.assign_.delay = de; } else if (delay_exp != 0) { delay_exp->expr_scan(this); stmt_cur_->u_.assign_.delay = expr_; expr_ = 0; } /* Process a count if it exists. */ if (const NetEConst*cnt_num = dynamic_cast(cnt_exp)) { verinum val = cnt_num->value(); ivl_expr_t cnt = new struct ivl_expr_s; cnt->type_ = IVL_EX_ULONG; cnt->width_ = 8 * sizeof(unsigned long); cnt->signed_ = 0; cnt->u_.ulong_.value = val.as_ulong(); stmt_cur_->u_.assign_.count = cnt; } else if (cnt_exp != 0) { cnt_exp->expr_scan(this); stmt_cur_->u_.assign_.count = expr_; expr_ = 0; } /* Process the events if they exist. This is a copy of code * from NetEvWait below. */ if (net->nevents() > 0) { stmt_cur_->u_.assign_.nevent = net->nevents(); if (net->nevents() > 1) { stmt_cur_->u_.assign_.events = (ivl_event_t*) calloc(net->nevents(), sizeof(ivl_event_t*)); } for (unsigned edx = 0 ; edx < net->nevents() ; edx += 1) { /* Locate the event by name. Save the ivl_event_t in the statement so that the generator can find it easily. */ const NetEvent*ev = net->event(edx); ivl_scope_t ev_scope = lookup_scope_(ev->scope()); ivl_event_t ev_tmp=0; assert(ev_scope); assert(ev_scope->nevent_ > 0); for (unsigned idx = 0; idx < ev_scope->nevent_; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { ev_tmp = ev_scope->event_[idx]; break; } } // XXX should we assert(ev_tmp)? if (net->nevents() == 1) stmt_cur_->u_.assign_.event = ev_tmp; else stmt_cur_->u_.assign_.events[edx] = ev_tmp; /* If this is an event with a probe, then connect up the pins. This wasn't done during the ::event method because the signals weren't scanned yet. */ if (ev->nprobe() >= 1) { unsigned iany = 0; unsigned ineg = ev_tmp->nany; unsigned ipos = ineg + ev_tmp->nneg; unsigned iedg = ipos + ev_tmp->npos; for (unsigned idx = 0; idx < ev->nprobe(); idx += 1) { const NetEvProbe*pr = ev->probe(idx); unsigned base = 0; switch (pr->edge()) { case NetEvProbe::ANYEDGE: base = iany; iany += pr->pin_count(); break; case NetEvProbe::NEGEDGE: base = ineg; ineg += pr->pin_count(); break; case NetEvProbe::POSEDGE: base = ipos; ipos += pr->pin_count(); break; case NetEvProbe::EDGE: base = iedg; iedg += pr->pin_count(); break; } for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) { ivl_nexus_t nex = (ivl_nexus_t) pr->pin(bit).nexus()->t_cookie(); assert(nex); ev_tmp->pins[base+bit] = nex; } } } } } } bool dll_target::proc_block(const NetBlock*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); /* First, count the statements in the block. */ unsigned count = 0; for (const NetProc*cur = net->proc_first() ; cur ; cur = net->proc_next(cur)) count += 1; /* If the block has no statements, then turn it into a no-op */ if (count == 0) { stmt_cur_->type_ = IVL_ST_NOOP; return true; } /* If there is exactly one statement and the block is not a fork/join_none, there is no need for the block wrapper, generate the contained statement instead. */ if ((count == 1) && (net->subscope() == 0) && (net->type() != NetBlock::PARA_JOIN_NONE)) { return net->proc_first()->emit_proc(this); } /* Handle the general case. The block has some statements in it, so fill in the block fields of the existing statement, and generate the contents for the statement array. */ switch (net->type()) { case NetBlock::SEQU: stmt_cur_->type_ = IVL_ST_BLOCK; break; case NetBlock::PARA: stmt_cur_->type_ = IVL_ST_FORK; break; case NetBlock::PARA_JOIN_ANY: stmt_cur_->type_ = IVL_ST_FORK_JOIN_ANY; break; case NetBlock::PARA_JOIN_NONE: stmt_cur_->type_ = IVL_ST_FORK_JOIN_NONE; break; } stmt_cur_->u_.block_.nstmt_ = count; stmt_cur_->u_.block_.stmt_ = (struct ivl_statement_s*) calloc(count, sizeof(struct ivl_statement_s)); if (net->subscope()) stmt_cur_->u_.block_.scope = lookup_scope_(net->subscope()); else stmt_cur_->u_.block_.scope = 0; struct ivl_statement_s*save_cur_ = stmt_cur_; unsigned idx = 0; bool flag = true; for (const NetProc*cur = net->proc_first() ; cur ; cur = net->proc_next(cur), idx += 1) { assert(idx < count); stmt_cur_ = save_cur_->u_.block_.stmt_ + idx; bool rc = cur->emit_proc(this); flag = flag && rc; } assert(idx == count); stmt_cur_ = save_cur_; return flag; } /* * A case statement is in turn an array of statements with gate * expressions. This builds arrays of the right size and builds the * ivl_expr_t and ivl_statement_s arrays for the substatements. */ void dll_target::proc_case(const NetCase*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); switch (net->type()) { case NetCase::EQ: stmt_cur_->type_ = IVL_ST_CASE; break; case NetCase::EQX: stmt_cur_->type_ = IVL_ST_CASEX; break; case NetCase::EQZ: stmt_cur_->type_ = IVL_ST_CASEZ; break; } assert(stmt_cur_->type_ != IVL_ST_NONE); stmt_cur_->u_.case_.quality = net->case_quality(); assert(expr_ == 0); assert(net->expr()); net->expr()->expr_scan(this); stmt_cur_->u_.case_.cond = expr_; expr_ = 0; /* If the condition expression is a real valued expression, then change the case statement to a CASER statement. */ if (stmt_cur_->u_.case_.cond->value_ == IVL_VT_REAL) stmt_cur_->type_ = IVL_ST_CASER; unsigned ncase = net->nitems(); stmt_cur_->u_.case_.ncase = ncase; stmt_cur_->u_.case_.case_ex = new ivl_expr_t[ncase]; stmt_cur_->u_.case_.case_st = new struct ivl_statement_s[ncase]; ivl_statement_t save_cur = stmt_cur_; for (unsigned idx = 0 ; idx < ncase ; idx += 1) { const NetExpr*ex = net->expr(idx); if (ex) { ex->expr_scan(this); save_cur->u_.case_.case_ex[idx] = expr_; expr_ = 0; } else { save_cur->u_.case_.case_ex[idx] = 0; } stmt_cur_ = save_cur->u_.case_.case_st + idx; stmt_cur_->type_ = IVL_ST_NONE; if (net->stat(idx) == 0) { stmt_cur_->type_ = IVL_ST_NOOP; } else { net->stat(idx)->emit_proc(this); } } stmt_cur_ = save_cur; } bool dll_target::proc_cassign(const NetCAssign*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_CASSIGN; /* Make the l-value fields. */ make_assign_lvals_(net); assert(expr_ == 0); net->rval()->expr_scan(this); stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; return true; } bool dll_target::proc_condit(const NetCondit*net) { bool rc_flag = true; assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_CONDIT; stmt_cur_->u_.condit_.stmt_ = (struct ivl_statement_s*) calloc(2, sizeof(struct ivl_statement_s)); assert(expr_ == 0); net->expr()->expr_scan(this); stmt_cur_->u_.condit_.cond_ = expr_; if (expr_ == 0) rc_flag = false; expr_ = 0; ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = save_cur_->u_.condit_.stmt_+0; rc_flag = net->emit_recurse_if(this) && rc_flag; stmt_cur_ = save_cur_->u_.condit_.stmt_+1; rc_flag = net->emit_recurse_else(this) && rc_flag; stmt_cur_ = save_cur_; return rc_flag; } bool dll_target::proc_deassign(const NetDeassign*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_DEASSIGN; /* Make the l-value fields. */ make_assign_lvals_(net); return true; } bool dll_target::proc_delay(const NetPDelay*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); ivl_statement_t tmp = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); if (const NetExpr*expr = net->expr()) { stmt_cur_->type_ = IVL_ST_DELAYX; assert(expr_ == 0); expr->expr_scan(this); stmt_cur_->u_.delayx_.expr = expr_; expr_ = 0; stmt_cur_->u_.delayx_.stmt_ = tmp; } else { stmt_cur_->type_ = IVL_ST_DELAY; stmt_cur_->u_.delay_.stmt_ = tmp; stmt_cur_->u_.delay_.value = net->delay(); } ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = tmp; bool flag = net->emit_proc_recurse(this); /* If the recurse doesn't turn this new item into something, then either it failed or there is no statement there. Either way, draw a no-op into the statement. */ if (stmt_cur_->type_ == IVL_ST_NONE) { stmt_cur_->type_ = IVL_ST_NOOP; } stmt_cur_ = save_cur_; return flag; } bool dll_target::proc_disable(const NetDisable*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_DISABLE; stmt_cur_->u_.disable_.flow_control = net->flow_control(); const NetScope* dis_scope = net->target(); /* A normal disable. */ if (dis_scope) stmt_cur_->u_.disable_.scope = lookup_scope_(dis_scope); /* A SystemVerilog disable fork. */ else stmt_cur_->u_.disable_.scope = 0; return true; } void dll_target::proc_do_while(const NetDoWhile*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_DO_WHILE; stmt_cur_->u_.while_.stmt_ = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); assert(expr_ == 0); net->expr()->expr_scan(this); stmt_cur_->u_.while_.cond_ = expr_; expr_ = 0; /* Now generate the statement of the do/while loop. We know it is a single statement, and we know that the emit_proc_recurse() will call emit_proc() for it. */ ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = save_cur_->u_.while_.stmt_; net->emit_proc_recurse(this); stmt_cur_ = save_cur_; } bool dll_target::proc_force(const NetForce*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_FORCE; /* Make the l-value fields. */ make_assign_lvals_(net); assert(expr_ == 0); net->rval()->expr_scan(this); stmt_cur_->u_.assign_.rval_ = expr_; expr_ = 0; return true; } void dll_target::proc_forever(const NetForever*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_FOREVER; ivl_statement_t tmp = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = tmp; net->emit_recurse(this); save_cur_->u_.forever_.stmt_ = stmt_cur_; stmt_cur_ = save_cur_; } void dll_target::proc_free(const NetFree*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_FREE; stmt_cur_->u_.free_.scope = lookup_scope_(net->scope()); } bool dll_target::proc_release(const NetRelease*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_RELEASE; /* Make the l-value fields. */ make_assign_lvals_(net); return true; } void dll_target::proc_repeat(const NetRepeat*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_REPEAT; assert(expr_ == 0); net->expr()->expr_scan(this); stmt_cur_->u_.while_.cond_ = expr_; expr_ = 0; ivl_statement_t tmp = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = tmp; net->emit_recurse(this); save_cur_->u_.while_.stmt_ = stmt_cur_; stmt_cur_ = save_cur_; } void dll_target::proc_stask(const NetSTask*net) { unsigned nparms = net->nparms(); assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_STASK; /* System task names are lex_strings strings. */ stmt_cur_->u_.stask_.name_ = net->name(); stmt_cur_->u_.stask_.sfunc_as_task_ = net->sfunc_as_task(); stmt_cur_->u_.stask_.nparm_= nparms; stmt_cur_->u_.stask_.parms_= (ivl_expr_t*) calloc(nparms, sizeof(ivl_expr_t)); for (unsigned idx = 0 ; idx < nparms ; idx += 1) { if (net->parm(idx)) net->parm(idx)->expr_scan(this); stmt_cur_->u_.stask_.parms_[idx] = expr_; expr_ = 0; } } bool dll_target::proc_trigger(const NetEvTrig*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_TRIGGER; stmt_cur_->u_.wait_.nevent = 1; /* Locate the event by name. Save the ivl_event_t in the statement so that the generator can find it easily. */ const NetEvent*ev = net->event(); ivl_scope_t ev_scope = lookup_scope_(ev->scope()); for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { stmt_cur_->u_.wait_.event = ev_scope->event_[idx]; break; } } return true; } bool dll_target::proc_nb_trigger(const NetEvNBTrig*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_NB_TRIGGER; stmt_cur_->u_.wait_.nevent = 1; stmt_cur_->u_.wait_.delay = 0; if (const NetExpr*expr = net->delay()) { assert(expr_ == 0); expr->expr_scan(this); stmt_cur_->u_.wait_.delay = expr_; expr_ = 0; } /* Locate the event by name. Save the ivl_event_t in the statement so that the generator can find it easily. */ const NetEvent*ev = net->event(); ivl_scope_t ev_scope = lookup_scope_(ev->scope()); for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { stmt_cur_->u_.wait_.event = ev_scope->event_[idx]; break; } } return true; } void dll_target::proc_utask(const NetUTask*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_UTASK; stmt_cur_->u_.utask_.def = lookup_scope_(net->task()); } bool dll_target::proc_wait(const NetEvWait*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_WAIT; stmt_cur_->u_.wait_.stmt_ = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); stmt_cur_->u_.wait_.nevent = net->nevents(); /* This is a wait fork statement. */ if ((net->nevents() == 1) && (net->event(0) == 0)) { stmt_cur_->u_.wait_.needs_t0_trigger = 0; stmt_cur_->u_.wait_.event = 0; stmt_cur_->type_ = IVL_ST_WAIT; stmt_cur_->u_.wait_.stmt_->type_ = IVL_ST_NOOP; return true; } stmt_cur_->u_.wait_.needs_t0_trigger = net->has_t0_trigger(); // This event processing code is also in the NB assign above. if (net->nevents() > 1) { stmt_cur_->u_.wait_.events = (ivl_event_t*) calloc(net->nevents(), sizeof(ivl_event_t*)); } for (unsigned edx = 0 ; edx < net->nevents() ; edx += 1) { /* Locate the event by name. Save the ivl_event_t in the statement so that the generator can find it easily. */ const NetEvent*ev = net->event(edx); ivl_scope_t ev_scope = lookup_scope_(ev->scope()); ivl_event_t ev_tmp=0; assert(ev_scope); assert(ev_scope->nevent_ > 0); for (unsigned idx = 0 ; idx < ev_scope->nevent_ ; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { ev_tmp = ev_scope->event_[idx]; break; } } // XXX should we assert(ev_tmp)? if (net->nevents() == 1) stmt_cur_->u_.wait_.event = ev_tmp; else stmt_cur_->u_.wait_.events[edx] = ev_tmp; /* If this is an event with a probe, then connect up the pins. This wasn't done during the ::event method because the signals weren't scanned yet. */ if (ev->nprobe() >= 1) { unsigned iany = 0; unsigned ineg = ev_tmp->nany; unsigned ipos = ineg + ev_tmp->nneg; unsigned iedg = ipos + ev_tmp->npos; for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { const NetEvProbe*pr = ev->probe(idx); unsigned base = 0; switch (pr->edge()) { case NetEvProbe::ANYEDGE: base = iany; iany += pr->pin_count(); break; case NetEvProbe::NEGEDGE: base = ineg; ineg += pr->pin_count(); break; case NetEvProbe::POSEDGE: base = ipos; ipos += pr->pin_count(); break; case NetEvProbe::EDGE: base = iedg; iedg += pr->pin_count(); break; } for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) { ivl_nexus_t nex = (ivl_nexus_t) pr->pin(bit).nexus()->t_cookie(); ivl_assert(*ev, nex); ev_tmp->pins[base+bit] = nex; } } } } /* The ivl_statement_t for the wait statement is not complete until we calculate the sub-statement. */ ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = stmt_cur_->u_.wait_.stmt_; bool flag = net->emit_recurse(this); if (flag && (stmt_cur_->type_ == IVL_ST_NONE)) stmt_cur_->type_ = IVL_ST_NOOP; stmt_cur_ = save_cur_; return flag; } void dll_target::proc_while(const NetWhile*net) { assert(stmt_cur_); assert(stmt_cur_->type_ == IVL_ST_NONE); FILE_NAME(stmt_cur_, net); stmt_cur_->type_ = IVL_ST_WHILE; stmt_cur_->u_.while_.stmt_ = (struct ivl_statement_s*) calloc(1, sizeof(struct ivl_statement_s)); assert(expr_ == 0); net->expr()->expr_scan(this); stmt_cur_->u_.while_.cond_ = expr_; expr_ = 0; /* Now generate the statement of the while loop. We know it is a single statement, and we know that the emit_proc_recurse() will call emit_proc() for it. */ ivl_statement_t save_cur_ = stmt_cur_; stmt_cur_ = save_cur_->u_.while_.stmt_; net->emit_proc_recurse(this); stmt_cur_ = save_cur_; } iverilog-12_0/t-dll.cc000066400000000000000000002300371435245347300146770ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 # include # include // sprintf() # include "compiler.h" # include "t-dll.h" # include "netclass.h" # include "netqueue.h" # include "netmisc.h" # include "discipline.h" # include # include "ivl_assert.h" # include "ivl_alloc.h" using namespace std; struct dll_target dll_target_obj; #if defined(__WIN32__) inline ivl_dll_t ivl_dlopen(const char *name) { ivl_dll_t res = (ivl_dll_t) LoadLibrary(name); return res; } inline void * ivl_dlsym(ivl_dll_t dll, const char *nm) { return (void*)GetProcAddress((HMODULE)dll, nm); } inline void ivl_dlclose(ivl_dll_t dll) { FreeLibrary((HMODULE)dll); } const char *dlerror(void) { static char msg[256]; unsigned long err = GetLastError(); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &msg, sizeof(msg) - 1, NULL ); return msg; } #elif defined(HAVE_DLFCN_H) inline ivl_dll_t ivl_dlopen(const char*name) { return dlopen(name,RTLD_LAZY); } inline void* ivl_dlsym(ivl_dll_t dll, const char*nm) { void*sym = dlsym(dll, nm); /* Not found? try without the leading _ */ if (sym == 0 && nm[0] == '_') sym = dlsym(dll, nm+1); return sym; } inline void ivl_dlclose(ivl_dll_t dll) { dlclose(dll); } #elif defined(HAVE_DL_H) inline ivl_dll_t ivl_dlopen(const char*name) { return shl_load(name, BIND_IMMEDIATE, 0); } inline void* ivl_dlsym(ivl_dll_t dll, const char*nm) { void*sym; int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym); return (rc == 0) ? sym : 0; } inline void ivl_dlclose(ivl_dll_t dll) { shl_unload(dll); } inline const char*dlerror(void) { return strerror( errno ); } #endif ivl_scope_s::ivl_scope_s() : func_type(IVL_VT_NO_TYPE) { func_signed = false; func_width = 0; } /* * The custom new operator for the ivl_nexus_s type allows us to * allocate nexus objects in blocks. There are generally lots of them * permanently allocated, and allocating them in blocks reduces the * allocation overhead. */ template void* pool_permalloc(size_t s) { static TYPE * pool_ptr = 0; static int pool_remaining = 0; static const size_t POOL_SIZE = 4096; assert(s == sizeof(TYPE)); if (pool_remaining <= 0) { pool_ptr = new TYPE[POOL_SIZE]; pool_remaining = POOL_SIZE; } TYPE*tmp = pool_ptr; pool_ptr += 1; pool_remaining -= 1; return tmp; } void* ivl_nexus_s::operator new(size_t s) { return pool_permalloc(s); } void ivl_nexus_s::operator delete(void*, size_t) { assert(0); } void* ivl_net_const_s::operator new(size_t s) { return pool_permalloc(s); } void ivl_net_const_s::operator delete(void*, size_t) { assert(0); } static StringHeapLex net_const_strings; static perm_string make_scope_name(const hname_t&name) { if (! name.has_numbers()) return name.peek_name(); char buf[1024]; snprintf(buf, sizeof buf, "%s", name.peek_name().str()); char*cp = buf + strlen(buf); size_t ncp = sizeof buf - (cp-buf); for (size_t idx = 0 ; idx < name.has_numbers() ; idx += 1) { int len = snprintf(cp, ncp, "[%d]", name.peek_number(idx)); cp += len; ncp -= len; } return lex_strings.make(buf); } static void drive_from_link(const Link&lnk, ivl_drive_t&drv0, ivl_drive_t&drv1) { drv0 = lnk.drive0(); drv1 = lnk.drive1(); } ivl_attribute_s* dll_target::fill_in_attributes(const Attrib*net) { ivl_attribute_s*attr; unsigned nattr = net->attr_cnt(); if (nattr == 0) return 0; attr = new struct ivl_attribute_s[nattr]; for (unsigned idx = 0 ; idx < nattr ; idx += 1) { verinum tmp = net->attr_value(idx); attr[idx].key = net->attr_key(idx); if (tmp.is_string()) { attr[idx].type = IVL_ATT_STR; attr[idx].val.str = strings_.add(tmp.as_string().c_str()); } else if (tmp == verinum()) { attr[idx].type = IVL_ATT_VOID; } else { attr[idx].type = IVL_ATT_NUM; attr[idx].val.num = tmp.as_long(); } } return attr; } /* * This function locates an ivl_scope_t object that matches the * NetScope object. The search works by looking for the parent scope, * then scanning the parent scope for the NetScope object. */ static ivl_scope_t find_scope_from_root(ivl_scope_t root, const NetScope*cur) { if (const NetScope*par = cur->parent()) { ivl_scope_t parent = find_scope_from_root(root, par); if (parent == 0) { return 0; } map::iterator idx = parent->children.find(cur->fullname()); if (idx == parent->children.end()) return 0; else return idx->second; } else { perm_string cur_name = make_scope_name(cur->fullname()); if (strcmp(root->name_, cur_name) == 0) return root; } return 0; } ivl_scope_t dll_target::find_scope(ivl_design_s &des, const NetScope*cur) { assert(cur); // If the scope is a PACKAGE, then it is a special kind of // root scope and it in the packages array instead. if (cur->type() == NetScope::PACKAGE) { perm_string cur_name = cur->module_name(); for (size_t idx = 0 ; idx < des.packages.size() ; idx += 1) { if (des.packages[idx]->name_ == cur_name) return des.packages[idx]; } return 0; } for (unsigned idx = 0; idx < des.roots.size(); idx += 1) { assert(des.roots[idx]); ivl_scope_t scope = find_scope_from_root(des.roots[idx], cur); if (scope) return scope; } for (size_t idx = 0; idx < des.packages.size(); idx += 1) { assert(des.packages[idx]); ivl_scope_t scope = find_scope_from_root(des.packages[idx], cur); if (scope) return scope; } return 0; } ivl_scope_t dll_target::lookup_scope_(const NetScope*cur) { return find_scope(des_, cur); } /* * This is a convenience function to locate an ivl_signal_t object * given the NetESignal that has the signal name. */ ivl_signal_t dll_target::find_signal(ivl_design_s &des, const NetNet*net) { ivl_scope_t scope = find_scope(des, net->scope()); assert(scope); perm_string nname = net->name(); for (unsigned idx = 0 ; idx < scope->sigs_.size() ; idx += 1) { if (strcmp(scope->sigs_[idx]->name_, nname) == 0) return scope->sigs_[idx]; } assert(0); return 0; } static ivl_nexus_t nexus_sig_make(ivl_signal_t net, unsigned pin) { ivl_nexus_t tmp = new struct ivl_nexus_s; tmp->ptrs_.resize(1); tmp->ptrs_[0].pin_ = pin; tmp->ptrs_[0].type_ = __NEXUS_PTR_SIG; tmp->ptrs_[0].l.sig = net; ivl_drive_t drive = IVL_DR_HiZ; switch (ivl_signal_type(net)) { case IVL_SIT_REG: drive = IVL_DR_STRONG; break; default: break; } tmp->ptrs_[0].drive0 = drive; tmp->ptrs_[0].drive1 = drive; return tmp; } static void nexus_sig_add(ivl_nexus_t nex, ivl_signal_t net, unsigned pin) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); ivl_drive_t drive = IVL_DR_HiZ; switch (ivl_signal_type(net)) { case IVL_SIT_REG: drive = IVL_DR_STRONG; break; default: break; } nex->ptrs_[top].type_= __NEXUS_PTR_SIG; nex->ptrs_[top].drive0 = drive; nex->ptrs_[top].drive1 = drive; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.sig= net; } static void nexus_bra_add(ivl_nexus_t nex, ivl_branch_t net, unsigned pin) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); nex->ptrs_[top].type_= __NEXUS_PTR_BRA; nex->ptrs_[top].drive0 = 0; nex->ptrs_[top].drive1 = 0; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.bra= net; } /* * Add the pin of the logic object to the nexus, and return the nexus * pointer used for the pin. * * NOTE: This pointer is only valid until another pin is added to the * nexus. */ static ivl_nexus_ptr_t nexus_log_add(ivl_nexus_t nex, ivl_net_logic_t net, unsigned pin) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); nex->ptrs_[top].type_= __NEXUS_PTR_LOG; nex->ptrs_[top].drive0 = (pin == 0)? IVL_DR_STRONG : IVL_DR_HiZ; nex->ptrs_[top].drive1 = (pin == 0)? IVL_DR_STRONG : IVL_DR_HiZ; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.log= net; return & (nex->ptrs_[top]); } static void nexus_con_add(ivl_nexus_t nex, ivl_net_const_t net, unsigned pin, ivl_drive_t drive0, ivl_drive_t drive1) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); nex->ptrs_[top].type_= __NEXUS_PTR_CON; nex->ptrs_[top].drive0 = drive0; nex->ptrs_[top].drive1 = drive1; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.con= net; } static void nexus_lpm_add(ivl_nexus_t nex, ivl_lpm_t net, unsigned pin, ivl_drive_t drive0, ivl_drive_t drive1) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); nex->ptrs_[top].type_= __NEXUS_PTR_LPM; nex->ptrs_[top].drive0 = drive0; nex->ptrs_[top].drive1 = drive1; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.lpm= net; } static void nexus_switch_add(ivl_nexus_t nex, ivl_switch_t net, unsigned pin) { unsigned top = nex->ptrs_.size(); nex->ptrs_.resize(top+1); nex->ptrs_[top].type_= __NEXUS_PTR_SWI; nex->ptrs_[top].drive0 = IVL_DR_HiZ; nex->ptrs_[top].drive1 = IVL_DR_HiZ; nex->ptrs_[top].pin_ = pin; nex->ptrs_[top].l.swi= net; } void scope_add_logic(ivl_scope_t scope, ivl_net_logic_t net) { if (scope->nlog_ == 0) { scope->nlog_ = 1; scope->log_ = (ivl_net_logic_t*)malloc(sizeof(ivl_net_logic_t)); scope->log_[0] = net; } else { scope->nlog_ += 1; scope->log_ = (ivl_net_logic_t*) realloc(scope->log_, scope->nlog_*sizeof(ivl_net_logic_t)); scope->log_[scope->nlog_-1] = net; } } void scope_add_event(ivl_scope_t scope, ivl_event_t net) { if (scope->nevent_ == 0) { scope->nevent_ = 1; scope->event_ = (ivl_event_t*)malloc(sizeof(ivl_event_t)); scope->event_[0] = net; } else { scope->nevent_ += 1; scope->event_ = (ivl_event_t*) realloc(scope->event_, scope->nevent_*sizeof(ivl_event_t)); scope->event_[scope->nevent_-1] = net; } } static void scope_add_lpm(ivl_scope_t scope, ivl_lpm_t net) { if (scope->nlpm_ == 0) { assert(scope->lpm_ == 0); scope->nlpm_ = 1; scope->lpm_ = (ivl_lpm_t*)malloc(sizeof(ivl_lpm_t)); scope->lpm_[0] = net; } else { assert(scope->lpm_); scope->nlpm_ += 1; scope->lpm_ = (ivl_lpm_t*) realloc(scope->lpm_, scope->nlpm_*sizeof(ivl_lpm_t)); scope->lpm_[scope->nlpm_-1] = net; } } static void scope_add_switch(ivl_scope_t scope, ivl_switch_t net) { scope->switches.push_back(net); } ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope, const char*name) { unsigned idx = 0; while (idx < scope->param.size()) { if (strcmp(name, scope->param[idx].basename) == 0) return &scope->param[idx]; idx += 1; } return 0; } /* * This method scans the parameters of the scope, and makes * ivl_parameter_t objects. This involves saving the name and scanning * the expression value. */ void dll_target::make_scope_parameters(ivl_scope_t scop, const NetScope*net) { if (net->parameters.empty()) { scop->param.clear(); return; } scop->param.resize(net->parameters.size()); unsigned idx = 0; typedef map::const_iterator pit_t; for (pit_t cur_pit = net->parameters.begin() ; cur_pit != net->parameters.end() ; ++ cur_pit ) { assert(idx < scop->param.size()); ivl_parameter_t cur_par = &scop->param[idx]; cur_par->basename = cur_pit->first; cur_par->local = cur_pit->second.local_flag || !cur_pit->second.overridable; cur_par->is_type = cur_pit->second.type_flag; if (cur_pit->second.ivl_type == 0) { cerr << "?:?: internal error: " << "No type for parameter " << cur_pit->first << " in scope " << net->fullname() << "?" << endl; } assert(cur_pit->second.ivl_type); cur_par->signed_flag = cur_pit->second.ivl_type->get_signed(); cur_par->scope = scop; FILE_NAME(cur_par, &(cur_pit->second)); // Type parameters don't have a range or expression if (!cur_pit->second.type_flag) { calculate_param_range(cur_pit->second, cur_pit->second.ivl_type, cur_par->msb, cur_par->lsb, cur_pit->second.val->expr_width()); NetExpr*etmp = cur_pit->second.val; if (etmp == 0) { cerr << "?:?: internal error: What is the parameter " << "expression for " << cur_pit->first << " in " << net->fullname() << "?" << endl; } assert(etmp); make_scope_param_expr(cur_par, etmp); } idx += 1; } } void dll_target::make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp) { if (const NetEConst*e = dynamic_cast(etmp)) { expr_const(e); assert(expr_); switch (expr_->type_) { case IVL_EX_STRING: expr_->u_.string_.parameter = cur_par; break; case IVL_EX_NUMBER: expr_->u_.number_.parameter = cur_par; break; default: assert(0); } } else if (const NetECReal*er = dynamic_cast(etmp)) { expr_creal(er); assert(expr_); assert(expr_->type_ == IVL_EX_REALNUM); expr_->u_.real_.parameter = cur_par; } if (expr_ == 0) { cerr << etmp->get_fileline() << ": internal error: " << "Parameter expression not reduced to constant? " << *etmp << endl; } ivl_assert(*etmp, expr_); cur_par->value = expr_; expr_ = 0; } static void fill_in_scope_function(ivl_scope_t scope, const NetScope*net) { scope->type_ = IVL_SCT_FUNCTION; const NetFuncDef*def = net->func_def(); assert(def); if (def->is_void()) { // Special case: If there is no return signal, this is // apparently a VOID function. scope->func_type = IVL_VT_VOID; scope->func_signed = 0; scope->func_width = 0; } else { const NetNet*return_sig = def->return_sig(); scope->func_type = return_sig->data_type(); scope->func_signed = return_sig->get_signed(); scope->func_width = return_sig->vector_width(); } scope->tname_ = def->scope()->basename(); } void dll_target::add_root(const NetScope *s) { ivl_scope_t root_ = new struct ivl_scope_s; perm_string name = s->basename(); root_->name_ = name; FILE_NAME(root_, s); root_->parent = 0; root_->nlog_ = 0; root_->log_ = 0; root_->nevent_ = 0; root_->event_ = 0; root_->nlpm_ = 0; root_->lpm_ = 0; root_->def = 0; make_scope_parameters(root_, s); root_->tname_ = root_->name_; root_->time_precision = s->time_precision(); root_->time_units = s->time_unit(); root_->nattr = s->attr_cnt(); root_->attr = fill_in_attributes(s); root_->is_auto = 0; root_->is_cell = s->is_cell(); switch (s->type()) { case NetScope::PACKAGE: root_->type_ = IVL_SCT_PACKAGE; break; case NetScope::MODULE: root_->type_ = IVL_SCT_MODULE; break; case NetScope::CLASS: root_->type_ = IVL_SCT_CLASS; break; default: assert(0); } switch (s->type()) { case NetScope::MODULE: root_->ports = s->module_port_nets(); if (root_->ports > 0) { root_->u_.net = new NetNet*[root_->ports]; for (unsigned idx = 0; idx < root_->ports; idx += 1) { root_->u_.net[idx] = s->module_port_net(idx); } } root_->module_ports_info = s->module_port_info(); des_.roots.push_back(root_); break; case NetScope::PACKAGE: root_->ports = 0; des_.packages.push_back(root_); break; default: assert(0); break; } } bool dll_target::start_design(const Design*des) { const char*dll_path_ = des->get_flag("DLL"); dll_ = ivl_dlopen(dll_path_); if ((dll_ == 0) && (dll_path_[0] != '/')) { size_t len = strlen(basedir) + 1 + strlen(dll_path_) + 1; char*tmp = new char[len]; snprintf(tmp, len, "%s/%s", basedir, dll_path_); dll_ = ivl_dlopen(tmp); delete[]tmp; } if (dll_ == 0) { cerr << "error: " << dll_path_ << " failed to load." << endl; cerr << dll_path_ << ": " << dlerror() << endl; return false; } stmt_cur_ = 0; // Initialize the design object. des_.self = des; des_.time_precision = des->get_precision(); des_.disciplines.resize(disciplines.size()); unsigned idx = 0; for (map::const_iterator cur = disciplines.begin() ; cur != disciplines.end() ; ++ cur ) { des_.disciplines[idx] = cur->second; idx += 1; } assert(idx == des_.disciplines.size()); list scope_list; scope_list = des->find_package_scopes(); for (list::const_iterator cur = scope_list.begin() ; cur != scope_list.end(); ++ cur ) { add_root(*cur); } scope_list = des->find_root_scopes(); for (list::const_iterator cur = scope_list.begin() ; cur != scope_list.end(); ++ cur ) { add_root(*cur); } target_ = (target_design_f)ivl_dlsym(dll_, LU "target_design" TU); if (target_ == 0) { cerr << dll_path_ << ": error: target_design entry " "point is missing." << endl; return false; } return true; } /* * Here ivl is telling us that the design is scanned completely, and * here is where we call the API to process the constructed design. */ int dll_target::end_design(const Design*) { int rc; if (errors == 0) { if (verbose_flag) { cout << " ... invoking target_design" << endl; } rc = (target_)(&des_); } else { if (verbose_flag) { cout << " ... skipping target_design due to errors." << endl; } rc = errors; } ivl_dlclose(dll_); return rc; } void dll_target::switch_attributes(struct ivl_switch_s *obj, const NetNode*net) { obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); } void dll_target::logic_attributes(struct ivl_net_logic_s *obj, const NetNode*net) { obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); } void dll_target::make_delays_(ivl_expr_t*delay, const NetObj*net) { delay[0] = 0; delay[1] = 0; delay[2] = 0; /* Translate delay expressions to ivl_target form. Try to preserve pointer equality, not as a rule but to save on expression trees. */ if (net->rise_time()) { expr_ = 0; net->rise_time()->expr_scan(this); delay[0] = expr_; expr_ = 0; } if (net->fall_time()) { if (net->fall_time() == net->rise_time()) { delay[1] = delay[0]; } else { expr_ = 0; net->fall_time()->expr_scan(this); delay[1] = expr_; expr_ = 0; } } if (net->decay_time()) { if (net->decay_time() == net->rise_time()) { delay[2] = delay[0]; } else { expr_ = 0; net->decay_time()->expr_scan(this); delay[2] = expr_; expr_ = 0; } } } void dll_target::make_logic_delays_(struct ivl_net_logic_s*obj, const NetObj*net) { make_delays_(obj->delay, net); } void dll_target::make_switch_delays_(struct ivl_switch_s*obj, const NetObj*net) { make_delays_(obj->delay, net); } void dll_target::make_lpm_delays_(struct ivl_lpm_s*obj, const NetObj*net) { make_delays_(obj->delay, net); } void dll_target::make_const_delays_(struct ivl_net_const_s*obj, const NetObj*net) { make_delays_(obj->delay, net); } bool dll_target::branch(const NetBranch*net) { struct ivl_branch_s*obj = net->target_obj(); ivl_assert(*net, net->pin_count() == 2); assert(net->pin(0).nexus()->t_cookie()); obj->pins[0] = net->pin(0).nexus()->t_cookie(); nexus_bra_add(obj->pins[0], obj, 0); assert(net->pin(1).nexus()->t_cookie()); obj->pins[1] = net->pin(1).nexus()->t_cookie(); nexus_bra_add(obj->pins[1], obj, 1); obj->island = net->get_island(); return true; } /* * Add a bufz object to the scope that contains it. * * Note that in the ivl_target API a BUFZ device is a special kind of * ivl_net_logic_t device, so create an ivl_net_logic_t cookie to * handle it. */ bool dll_target::bufz(const NetBUFZ*net) { struct ivl_net_logic_s *obj = new struct ivl_net_logic_s; assert(net->pin_count() == 2); obj->type_ = net->transparent()? IVL_LO_BUFT : IVL_LO_BUFZ; obj->width_= net->width(); obj->is_cassign = 0; obj->npins_= 2; obj->pins_ = new ivl_nexus_t[2]; FILE_NAME(obj, net); /* Get the ivl_nexus_t objects connected to the two pins. (We know a priori that the ivl_nexus_t objects have been allocated, because the signals have been scanned before me. This saves me the trouble of allocating them.) */ assert(net->pin(0).nexus()->t_cookie()); obj->pins_[0] = net->pin(0).nexus()->t_cookie(); ivl_nexus_ptr_t out_ptr = nexus_log_add(obj->pins_[0], obj, 0); out_ptr->drive0 = net->pin(0).drive0(); out_ptr->drive1 = net->pin(0).drive1(); assert(net->pin(1).nexus()->t_cookie()); obj->pins_[1] = net->pin(1).nexus()->t_cookie(); nexus_log_add(obj->pins_[1], obj, 1); /* Attach the logic device to the scope that contains it. */ assert(net->scope()); ivl_scope_t scop = find_scope(des_, net->scope()); assert(scop); obj->scope_ = scop; obj->name_ = net->name(); logic_attributes(obj, net); make_logic_delays_(obj, net); scope_add_logic(scop, obj); return true; } bool dll_target::class_type(const NetScope*in_scope, netclass_t*net) { ivl_scope_t use_scope = find_scope(des_, in_scope); use_scope->classes.push_back(net); return true; } bool dll_target::enumeration(const NetScope*in_scope, netenum_t*net) { ivl_scope_t use_scope = find_scope(des_, in_scope); use_scope->enumerations_.push_back(net); return true; } void dll_target::event(const NetEvent*net) { struct ivl_event_s *obj = new struct ivl_event_s; FILE_NAME(obj, net); ivl_scope_t scop = find_scope(des_, net->scope()); obj->name = net->name(); obj->scope = scop; scope_add_event(scop, obj); obj->nany = 0; obj->nneg = 0; obj->npos = 0; obj->nedg = 0; if (net->nprobe() >= 1) { for (unsigned idx = 0 ; idx < net->nprobe() ; idx += 1) { const NetEvProbe*pr = net->probe(idx); switch (pr->edge()) { case NetEvProbe::ANYEDGE: obj->nany += pr->pin_count(); break; case NetEvProbe::NEGEDGE: obj->nneg += pr->pin_count(); break; case NetEvProbe::POSEDGE: obj->npos += pr->pin_count(); break; case NetEvProbe::EDGE: obj->nedg += pr->pin_count(); break; } } unsigned npins = obj->nany + obj->nneg + obj->npos + obj->nedg; obj->pins = (ivl_nexus_t*)calloc(npins, sizeof(ivl_nexus_t)); } else { obj->pins = 0; } } void dll_target::logic(const NetLogic*net) { struct ivl_net_logic_s *obj = new struct ivl_net_logic_s; obj->width_ = net->width(); FILE_NAME(obj, net); switch (net->type()) { case NetLogic::AND: obj->type_ = IVL_LO_AND; break; case NetLogic::BUF: obj->type_ = IVL_LO_BUF; break; case NetLogic::BUFIF0: obj->type_ = IVL_LO_BUFIF0; break; case NetLogic::BUFIF1: obj->type_ = IVL_LO_BUFIF1; break; case NetLogic::CMOS: obj->type_ = IVL_LO_CMOS; break; case NetLogic::EQUIV: obj->type_ = IVL_LO_EQUIV; break; case NetLogic::IMPL: obj->type_ = IVL_LO_IMPL; break; case NetLogic::NAND: obj->type_ = IVL_LO_NAND; break; case NetLogic::NMOS: obj->type_ = IVL_LO_NMOS; break; case NetLogic::NOR: obj->type_ = IVL_LO_NOR; break; case NetLogic::NOT: obj->type_ = IVL_LO_NOT; break; case NetLogic::NOTIF0: obj->type_ = IVL_LO_NOTIF0; break; case NetLogic::NOTIF1: obj->type_ = IVL_LO_NOTIF1; break; case NetLogic::OR: obj->type_ = IVL_LO_OR; break; case NetLogic::PULLDOWN: obj->type_ = IVL_LO_PULLDOWN; break; case NetLogic::PULLUP: obj->type_ = IVL_LO_PULLUP; break; case NetLogic::RCMOS: obj->type_ = IVL_LO_RCMOS; break; case NetLogic::RNMOS: obj->type_ = IVL_LO_RNMOS; break; case NetLogic::RPMOS: obj->type_ = IVL_LO_RPMOS; break; case NetLogic::PMOS: obj->type_ = IVL_LO_PMOS; break; case NetLogic::XNOR: obj->type_ = IVL_LO_XNOR; break; case NetLogic::XOR: obj->type_ = IVL_LO_XOR; break; default: assert(0); obj->type_ = IVL_LO_NONE; break; } /* Some of the logical gates are used to represent operators in a * continuous assignment, so set a flag if that is the case. */ obj->is_cassign = net->is_cassign(); /* Connect all the ivl_nexus_t objects to the pins of the device. */ obj->npins_ = net->pin_count(); obj->pins_ = new ivl_nexus_t[obj->npins_]; for (unsigned idx = 0 ; idx < obj->npins_ ; idx += 1) { const Nexus*nex = net->pin(idx).nexus(); assert(nex->t_cookie()); obj->pins_[idx] = nex->t_cookie(); ivl_nexus_ptr_t tmp = nexus_log_add(obj->pins_[idx], obj, idx); if (idx == 0) { tmp->drive0 = net->pin(0).drive0(); tmp->drive1 = net->pin(0).drive1(); } } assert(net->scope()); ivl_scope_t scop = find_scope(des_, net->scope()); assert(scop); obj->scope_= scop; obj->name_ = net->name(); logic_attributes(obj, net); make_logic_delays_(obj, net); scope_add_logic(scop, obj); } bool dll_target::tran(const NetTran*net) { struct ivl_switch_s*obj = new struct ivl_switch_s; obj->type = net->type(); obj->width = net->vector_width(); obj->part = 0; obj->offset = 0; obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); obj->island = net->get_island(); assert(obj->scope); assert(obj->island); FILE_NAME(obj, net); const Nexus*nex; nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->pins[0] = nex->t_cookie(); nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->pins[1] = nex->t_cookie(); nexus_switch_add(obj->pins[0], obj, 0); nexus_switch_add(obj->pins[1], obj, 1); if (net->pin_count() > 2) { nex = net->pin(2).nexus(); assert(nex->t_cookie()); obj->pins[2] = nex->t_cookie(); nexus_switch_add(obj->pins[2], obj, 2); } else { obj->pins[2] = 0; } if (obj->type == IVL_SW_TRAN_VP) { obj->part = net->part_width(); obj->offset= net->part_offset(); } switch_attributes(obj, net); make_switch_delays_(obj, net); scope_add_switch(obj->scope, obj); return true; } bool dll_target::substitute(const NetSubstitute*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_SUBSTITUTE; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.substitute.base = net->base(); obj->u_.substitute.q = net->pin(0).nexus()->t_cookie(); obj->u_.substitute.a = net->pin(1).nexus()->t_cookie(); obj->u_.substitute.s = net->pin(2).nexus()->t_cookie(); nexus_lpm_add(obj->u_.substitute.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nexus_lpm_add(obj->u_.substitute.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nexus_lpm_add(obj->u_.substitute.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } bool dll_target::sign_extend(const NetSignExtend*net) { struct ivl_lpm_s*obj = new struct ivl_lpm_s; obj->type = IVL_LPM_SIGN_EXT; obj->width = net->width(); obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); const Nexus*nex; nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.reduce.q = nex->t_cookie(); nexus_lpm_add(obj->u_.reduce.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.reduce.a = nex->t_cookie(); nexus_lpm_add(obj->u_.reduce.a, obj, 1, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } bool dll_target::ureduce(const NetUReduce*net) { struct ivl_lpm_s*obj = new struct ivl_lpm_s; switch (net->type()) { case NetUReduce::NONE: assert(0); delete obj; return false; case NetUReduce::AND: obj->type = IVL_LPM_RE_AND; break; case NetUReduce::OR: obj->type = IVL_LPM_RE_OR; break; case NetUReduce::XOR: obj->type = IVL_LPM_RE_XOR; break; case NetUReduce::NAND: obj->type = IVL_LPM_RE_NAND; break; case NetUReduce::NOR: obj->type = IVL_LPM_RE_NOR; break; case NetUReduce::XNOR: obj->type = IVL_LPM_RE_XNOR; break; } obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); const Nexus*nex; nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.reduce.q = nex->t_cookie(); nexus_lpm_add(obj->u_.reduce.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.reduce.a = nex->t_cookie(); nexus_lpm_add(obj->u_.reduce.a, obj, 1, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } void dll_target::net_case_cmp(const NetCaseCmp*net) { struct ivl_lpm_s*obj = new struct ivl_lpm_s; switch (net->kind()) { case NetCaseCmp::EEQ: obj->type = IVL_LPM_CMP_EEQ; break; case NetCaseCmp::NEQ: obj->type = IVL_LPM_CMP_NEE; break; case NetCaseCmp::WEQ: obj->type = IVL_LPM_CMP_WEQ; break; case NetCaseCmp::WNE: obj->type = IVL_LPM_CMP_WNE; break; case NetCaseCmp::XEQ: obj->type = IVL_LPM_CMP_EQX; break; case NetCaseCmp::ZEQ: obj->type = IVL_LPM_CMP_EQZ; break; } obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.arith.signed_flag = 0; const Nexus*nex; nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin(2).nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } ivl_event_t dll_target::make_lpm_trigger(const NetEvWait*net) { ivl_event_t trigger = 0; if (net) { const NetEvent*ev = net->event(0); /* Locate the event by name. */ ivl_scope_t ev_scope = lookup_scope_(ev->scope()); assert(ev_scope); assert(ev_scope->nevent_ > 0); for (unsigned idx = 0; idx < ev_scope->nevent_; idx += 1) { const char*ename = ivl_event_basename(ev_scope->event_[idx]); if (strcmp(ev->name(), ename) == 0) { trigger = ev_scope->event_[idx]; break; } } /* Connect up the probe pins. This wasn't done during the ::event method because the signals weren't scanned yet. */ assert(ev->nprobe() == 1); const NetEvProbe*pr = ev->probe(0); for (unsigned bit = 0; bit < pr->pin_count(); bit += 1) { ivl_nexus_t nex = (ivl_nexus_t) pr->pin(bit).nexus()->t_cookie(); assert(nex); trigger->pins[bit] = nex; } } return trigger; } bool dll_target::net_sysfunction(const NetSysFunc*net) { unsigned idx; const Nexus*nex; struct ivl_lpm_s*obj = new struct ivl_lpm_s; obj->type = IVL_LPM_SFUNC; obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->u_.sfunc.ports = net->pin_count(); assert(net->pin_count() >= 1); obj->width = net->vector_width(); obj->u_.sfunc.fun_name = net->func_name(); obj->u_.sfunc.pins = new ivl_nexus_t[net->pin_count()]; nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.sfunc.pins[0] = nex->t_cookie(); nexus_lpm_add(obj->u_.sfunc.pins[0], obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); for (idx = 1 ; idx < net->pin_count() ; idx += 1) { nex = net->pin(idx).nexus(); assert(nex->t_cookie()); obj->u_.sfunc.pins[idx] = nex->t_cookie(); nexus_lpm_add(obj->u_.sfunc.pins[idx], obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } /* Save information about the trigger event if it exists. */ obj->u_.sfunc.trigger = make_lpm_trigger(net->trigger()); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } /* * An IVL_LPM_UFUNC represents a node in a combinational expression * that calls a user defined function. I create an LPM object that has * the right connections, and refers to the ivl_scope_t of the * definition. */ bool dll_target::net_function(const NetUserFunc*net) { struct ivl_lpm_s*obj = new struct ivl_lpm_s; obj->type = IVL_LPM_UFUNC; obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); /* Get the definition of the function and save it. */ const NetScope*def = net->def(); assert(def); obj->u_.ufunc.def = lookup_scope_(def); /* Save information about the ports in the ivl_lpm_s structure. Note that port 0 is the return value. */ obj->u_.ufunc.ports = net->pin_count(); assert(net->pin_count() >= 1); obj->width = net->port_width(0); /* Now collect all the pins and connect them to the nexa of the net. The output pins have strong drive, and the remaining input pins are HiZ. */ obj->u_.ufunc.pins = new ivl_nexus_t[net->pin_count()]; for (unsigned idx = 0 ; idx < net->pin_count() ; idx += 1) { const Nexus*nex = net->pin(idx).nexus(); assert(nex->t_cookie()); ivl_nexus_t nn = nex->t_cookie(); assert(nn); obj->u_.ufunc.pins[idx] = nn; ivl_drive_t drive = idx == 0 ? IVL_DR_STRONG : IVL_DR_HiZ; nexus_lpm_add(obj->u_.ufunc.pins[idx], obj, idx, drive, drive); } /* Save information about the trigger event if it exists. */ obj->u_.ufunc.trigger = make_lpm_trigger(net->trigger()); make_lpm_delays_(obj, net); /* All done. Add this LPM to the scope. */ scope_add_lpm(obj->scope, obj); return true; } void dll_target::udp(const NetUDP*net) { struct ivl_net_logic_s *obj = new struct ivl_net_logic_s; obj->type_ = IVL_LO_UDP; FILE_NAME(obj, net); /* The NetUDP class hasn't learned about width yet, so we assume a width of 1. */ obj->width_ = 1; obj->is_cassign = 0; static map udps; ivl_udp_t u; if (udps.find(net->udp_name()) != udps.end()) { u = udps[net->udp_name()]; } else { u = new struct ivl_udp_s; u->nrows = net->rows(); u->table = (ivl_udp_s::ccharp_t*)malloc((u->nrows+1)*sizeof(char*)); u->table[u->nrows] = 0x0; u->nin = net->nin(); u->sequ = net->is_sequential(); u->file = net->udp_file(); u->lineno = net->udp_lineno(); if (u->sequ) u->init = net->get_initial(); else u->init = 'x'; u->name = net->udp_name(); string inp; char out; unsigned int i = 0; if (net->first(inp, out)) do { string tt = inp+out; u->table[i++] = strings_.add(tt.c_str()); } while (net->next(inp, out)); assert(i==u->nrows); assert((u->nin + 1) == net->port_count()); u->ports = new string [u->nin + 1]; for(unsigned idx = 0; idx <= u->nin; idx += 1) { u->ports[idx] = net->port_name(idx); } udps[net->udp_name()] = u; } obj->udp = u; // Some duplication of code here, see: dll_target::logic() /* Connect all the ivl_nexus_t objects to the pins of the device. */ obj->npins_ = net->pin_count(); obj->pins_ = new ivl_nexus_t[obj->npins_]; for (unsigned idx = 0 ; idx < obj->npins_ ; idx += 1) { /* Skip unconnected input pins. These will take on HiZ values by the code generators. */ if (! net->pin(idx).is_linked()) { obj->pins_[idx] = 0; continue; } const Nexus*nex = net->pin(idx).nexus(); ivl_assert(*net, nex && nex->t_cookie()); obj->pins_[idx] = nex->t_cookie(); nexus_log_add(obj->pins_[idx], obj, idx); } assert(net->scope()); ivl_scope_t scop = find_scope(des_, net->scope()); assert(scop); obj->scope_= scop; obj->name_ = net->name(); FILE_NAME(obj, net); make_logic_delays_(obj, net); obj->nattr = 0; obj->attr = 0; scope_add_logic(scop, obj); } void dll_target::lpm_abs(const NetAbs*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_ABS; obj->name = net->name(); // NetAddSub names are permallocated. assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->u_.arith.signed_flag = 0; obj->width = net->width(); const Nexus*nex; /* the output is pin(0) */ nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin(1).nexus(); assert(nex->t_cookie()); /* pin(1) is the input data. */ obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } void dll_target::lpm_add_sub(const NetAddSub*net) { ivl_lpm_t obj = new struct ivl_lpm_s; if (net->attribute(perm_string::literal("LPM_Direction")) == verinum("SUB")) obj->type = IVL_LPM_SUB; else obj->type = IVL_LPM_ADD; obj->name = net->name(); // NetAddSub names are permallocated. assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->u_.arith.signed_flag = 0; /* Choose the width of the adder. If the carry bit is connected, then widen the adder by one and plan on leaving the fake inputs unconnected. */ obj->width = net->width(); if (net->pin_Cout().is_linked()) { obj->width += 1; } const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); /* If the carry output is connected, then connect the extra Q pin to the carry nexus and zero the a and b inputs. */ if (net->pin_Cout().is_linked()) { cerr << "XXXX: t-dll.cc: Forgot how to connect cout." << endl; } make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } bool dll_target::lpm_array_dq(const NetArrayDq*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_ARRAY; obj->name = net->name(); obj->u_.array.sig = find_signal(des_, net->mem()); assert(obj->u_.array.sig); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.array.swid = net->awidth(); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); const Nexus*nex; nex = net->pin_Address().nexus(); assert(nex->t_cookie()); obj->u_.array.a = nex->t_cookie(); nexus_lpm_add(obj->u_.array.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.array.q = nex->t_cookie(); nexus_lpm_add(obj->u_.array.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); return true; } /* * The lpm_clshift device represents both left and right shifts, * depending on what is connected to the Direction pin. We convert * this device into SHIFTL or SHIFTR devices. */ void dll_target::lpm_clshift(const NetCLShift*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_SHIFTL; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); /* Look at the direction input of the device, and select the shift direction accordingly. */ if (net->right_flag()) obj->type = IVL_LPM_SHIFTR; if (net->signed_flag()) obj->u_.shift.signed_flag = 1; else obj->u_.shift.signed_flag = 0; obj->width = net->width(); obj->u_.shift.select = net->width_dist(); const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.shift.q = nex->t_cookie(); nexus_lpm_add(obj->u_.shift.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_Data().nexus(); assert(nex->t_cookie()); obj->u_.shift.d = nex->t_cookie(); nexus_lpm_add(obj->u_.shift.d, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_Distance().nexus(); assert(nex->t_cookie()); obj->u_.shift.s = nex->t_cookie(); nexus_lpm_add(obj->u_.shift.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } bool dll_target::lpm_arith1_(ivl_lpm_type_t lpm_type, unsigned width, bool signed_flag, const NetNode*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = lpm_type; obj->name = net->name(); // NetCastInt2 names are permallocated assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = width; obj->u_.arith.signed_flag = signed_flag? 1 : 0; const Nexus*nex; nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } bool dll_target::lpm_cast_int2(const NetCastInt2*net) { return lpm_arith1_(IVL_LPM_CAST_INT2, net->width(), true, net); } bool dll_target::lpm_cast_int4(const NetCastInt4*net) { return lpm_arith1_(IVL_LPM_CAST_INT, net->width(), true, net); } bool dll_target::lpm_cast_real(const NetCastReal*net) { return lpm_arith1_(IVL_LPM_CAST_REAL, 0, net->signed_flag(), net); } /* * Make out of the NetCompare object an ivl_lpm_s object. The * comparators in ivl_target do not support < or <=, but they can be * trivially converted to > and >= by swapping the operands. */ void dll_target::lpm_compare(const NetCompare*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->name = net->name(); // NetCompare names are permallocated assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); bool swap_operands = false; obj->width = net->width(); obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; const Nexus*nex; nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); if (net->pin_AGEB().is_linked()) { nex = net->pin_AGEB().nexus(); obj->type = IVL_LPM_CMP_GE; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); } else if (net->pin_AGB().is_linked()) { nex = net->pin_AGB().nexus(); obj->type = IVL_LPM_CMP_GT; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); } else if (net->pin_ALEB().is_linked()) { nex = net->pin_ALEB().nexus(); obj->type = IVL_LPM_CMP_GE; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); swap_operands = true; } else if (net->pin_ALB().is_linked()) { nex = net->pin_ALB().nexus(); obj->type = IVL_LPM_CMP_GT; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); swap_operands = true; } else if (net->pin_AEB().is_linked()) { nex = net->pin_AEB().nexus(); obj->type = IVL_LPM_CMP_EQ; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); } else if (net->pin_ANEB().is_linked()) { nex = net->pin_ANEB().nexus(); obj->type = IVL_LPM_CMP_NE; assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); } else { assert(0); } if (swap_operands) { ivl_nexus_t tmp = obj->u_.arith.a; obj->u_.arith.a = obj->u_.arith.b; obj->u_.arith.b = tmp; } nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } void dll_target::lpm_divide(const NetDivide*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_DIVIDE; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); unsigned wid = net->width_r(); obj->width = wid; obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } void dll_target::lpm_modulo(const NetModulo*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_MOD; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); unsigned wid = net->width_r(); obj->width = wid; obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } void dll_target::lpm_ff(const NetFF*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_FF; obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); scope_add_lpm(obj->scope, obj); const Nexus*nex; /* Set the clock polarity. */ obj->u_.ff.negedge_flag = net->is_negedge(); /* Set the clk signal to point to the nexus, and the nexus to point back to this device. */ nex = net->pin_Clock().nexus(); assert(nex->t_cookie()); obj->u_.ff.clk = nex->t_cookie(); assert(obj->u_.ff.clk); nexus_lpm_add(obj->u_.ff.clk, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); /* If there is a clock enable, then connect it up to the FF device. */ if (net->pin_Enable().is_linked()) { nex = net->pin_Enable().nexus(); assert(nex->t_cookie()); obj->u_.ff.we = nex->t_cookie(); assert(obj->u_.ff.we); nexus_lpm_add(obj->u_.ff.we, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } else { obj->u_.ff.we = 0; } if (net->pin_Aclr().is_linked()) { nex = net->pin_Aclr().nexus(); assert(nex->t_cookie()); obj->u_.ff.aclr = nex->t_cookie(); assert(obj->u_.ff.aclr); nexus_lpm_add(obj->u_.ff.aclr, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } else { obj->u_.ff.aclr = 0; } if (net->pin_Aset().is_linked()) { nex = net->pin_Aset().nexus(); assert(nex->t_cookie()); obj->u_.ff.aset = nex->t_cookie(); assert(obj->u_.ff.aset); nexus_lpm_add(obj->u_.ff.aset, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); verinum tmp = net->aset_value(); if (tmp.len() > 0) obj->u_.ff.aset_value = expr_from_value_(tmp); else obj->u_.ff.aset_value = 0; } else { obj->u_.ff.aset = 0; obj->u_.ff.aset_value = 0; } if (net->pin_Sclr().is_linked()) { nex = net->pin_Sclr().nexus(); assert(nex->t_cookie()); obj->u_.ff.sclr = nex->t_cookie(); assert(obj->u_.ff.sclr); nexus_lpm_add(obj->u_.ff.sclr, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } else { obj->u_.ff.sclr = 0; } if (net->pin_Sset().is_linked()) { nex = net->pin_Sset().nexus(); assert(nex->t_cookie()); obj->u_.ff.sset = nex->t_cookie(); assert(obj->u_.ff.sset); nexus_lpm_add(obj->u_.ff.sset, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); verinum tmp = net->sset_value(); if (tmp.len() > 0) obj->u_.ff.sset_value = expr_from_value_(tmp); else obj->u_.ff.sset_value = 0; } else { obj->u_.ff.sset = 0; obj->u_.ff.sset_value = 0; } nex = net->pin_Q().nexus(); assert(nex->t_cookie()); obj->u_.ff.q.pin = nex->t_cookie(); nexus_lpm_add(obj->u_.ff.q.pin, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_Data().nexus(); assert(nex->t_cookie()); obj->u_.ff.d.pin = nex->t_cookie(); nexus_lpm_add(obj->u_.ff.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } void dll_target::lpm_latch(const NetLatch*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_LATCH; obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); scope_add_lpm(obj->scope, obj); const Nexus*nex; nex = net->pin_Enable().nexus(); assert(nex->t_cookie()); obj->u_.latch.e = nex->t_cookie(); assert(obj->u_.latch.e); nexus_lpm_add(obj->u_.latch.e, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_Q().nexus(); assert(nex->t_cookie()); obj->u_.latch.q.pin = nex->t_cookie(); nexus_lpm_add(obj->u_.latch.q.pin, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_Data().nexus(); assert(nex->t_cookie()); obj->u_.latch.d.pin = nex->t_cookie(); nexus_lpm_add(obj->u_.latch.d.pin, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } /* * Make the NetMult object into an IVL_LPM_MULT node. */ void dll_target::lpm_mult(const NetMult*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_MULT; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); unsigned wid = net->width_r(); obj->width = wid; obj->u_.arith.signed_flag = 0; const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } /* * Hook up the mux devices so that the select expression selects the * correct sub-expression with the ivl_lpm_data2 function. */ void dll_target::lpm_mux(const NetMux*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_MUX; obj->name = net->name(); // The NetMux permallocates its name. obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.mux.size = net->size(); obj->u_.mux.swid = net->sel_width(); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); const Nexus*nex; /* Connect the output bits. */ nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.mux.q = nex->t_cookie(); nexus_lpm_add(obj->u_.mux.q, obj, 0, net->pin_Result().drive0(), net->pin_Result().drive1()); /* Connect the select bits. */ nex = net->pin_Sel().nexus(); assert(nex->t_cookie()); obj->u_.mux.s = nex->t_cookie(); nexus_lpm_add(obj->u_.mux.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); unsigned selects = obj->u_.mux.size; obj->u_.mux.d = new ivl_nexus_t [selects]; for (unsigned sdx = 0 ; sdx < selects ; sdx += 1) { nex = net->pin_Data(sdx).nexus(); ivl_nexus_t tmp = nex->t_cookie(); obj->u_.mux.d[sdx] = tmp; if (tmp == 0) { cerr << net->get_fileline() << ": internal error: " << "dll_target::lpm_mux: " << "Missing data port " << sdx << " of mux " << obj->name << "." << endl; } ivl_assert(*net, tmp); nexus_lpm_add(tmp, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); } } /* * Make the NetPow object into an IVL_LPM_POW node. */ void dll_target::lpm_pow(const NetPow*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_POW; FILE_NAME(obj, net); obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); unsigned wid = net->width_r(); obj->u_.arith.signed_flag = net->get_signed()? 1 : 0; obj->width = wid; const Nexus*nex; nex = net->pin_Result().nexus(); assert(nex->t_cookie()); obj->u_.arith.q = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nex = net->pin_DataA().nexus(); assert(nex->t_cookie()); obj->u_.arith.a = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); nex = net->pin_DataB().nexus(); assert(nex->t_cookie()); obj->u_.arith.b = nex->t_cookie(); nexus_lpm_add(obj->u_.arith.b, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); } bool dll_target::concat(const NetConcat*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = net->transparent()? IVL_LPM_CONCATZ : IVL_LPM_CONCAT; obj->name = net->name(); // NetConcat names are permallocated assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.concat.inputs = net->pin_count() - 1; obj->u_.concat.pins = new ivl_nexus_t[obj->u_.concat.inputs+1]; for (unsigned idx = 0 ; idx < obj->u_.concat.inputs+1 ; idx += 1) { ivl_drive_t dr = idx == 0? IVL_DR_STRONG : IVL_DR_HiZ; const Nexus*nex = net->pin(idx).nexus(); assert(nex->t_cookie()); obj->u_.concat.pins[idx] = nex->t_cookie(); nexus_lpm_add(obj->u_.concat.pins[idx], obj, 0, dr, dr); } make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } bool dll_target::part_select(const NetPartSelect*net) { ivl_lpm_t obj = new struct ivl_lpm_s; switch (net->dir()) { case NetPartSelect::VP: obj->type = IVL_LPM_PART_VP; break; case NetPartSelect::PV: obj->type = IVL_LPM_PART_PV; break; } obj->name = net->name(); // NetPartSelect names are permallocated. assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); /* Part selects are always unsigned, so we use this to indicate * if the part select base signal is signed or not. */ if (net->signed_flag()) obj->u_.part.signed_flag = 1; else obj->u_.part.signed_flag = 0; /* Choose the width of the part select. */ obj->width = net->width(); obj->u_.part.base = net->base(); obj->u_.part.s = 0; const Nexus*nex; switch (obj->type) { case IVL_LPM_PART_VP: /* NetPartSelect:pin(0) is the output pin. */ nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.part.q = nex->t_cookie(); /* NetPartSelect:pin(1) is the input pin. */ nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.part.a = nex->t_cookie(); /* If the part select has an additional pin, that pin is a variable select base. */ if (net->pin_count() >= 3) { nex = net->pin(2).nexus(); assert(nex->t_cookie()); obj->u_.part.s = nex->t_cookie(); } break; case IVL_LPM_PART_PV: /* NetPartSelect:pin(1) is the output pin. */ nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.part.q = nex->t_cookie(); /* NetPartSelect:pin(0) is the input pin. */ nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.part.a = nex->t_cookie(); break; default: assert(0); } nexus_lpm_add(obj->u_.part.q, obj, 0, IVL_DR_STRONG, IVL_DR_STRONG); nexus_lpm_add(obj->u_.part.a, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); /* The select input is optional. */ if (obj->u_.part.s) nexus_lpm_add(obj->u_.part.s, obj, 0, IVL_DR_HiZ, IVL_DR_HiZ); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } bool dll_target::replicate(const NetReplicate*net) { ivl_lpm_t obj = new struct ivl_lpm_s; obj->type = IVL_LPM_REPEAT; obj->name = net->name(); assert(net->scope()); obj->scope = find_scope(des_, net->scope()); assert(obj->scope); FILE_NAME(obj, net); obj->width = net->width(); obj->u_.repeat.count = net->repeat(); ivl_drive_t dr = IVL_DR_STRONG; const Nexus*nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->u_.repeat.q = nex->t_cookie(); nexus_lpm_add(obj->u_.repeat.q, obj, 0, dr, dr); dr = IVL_DR_HiZ; nex = net->pin(1).nexus(); assert(nex->t_cookie()); obj->u_.repeat.a = nex->t_cookie(); nexus_lpm_add(obj->u_.repeat.a, obj, 0, dr, dr); make_lpm_delays_(obj, net); scope_add_lpm(obj->scope, obj); return true; } /* * The assignment l-values are captured by the assignment statements * themselves in the process handling. */ void dll_target::net_assign(const NetAssign_*) const { } bool dll_target::net_const(const NetConst*net) { unsigned idx; char*bits; static char*bits_tmp = 0; static unsigned bits_cnt = 0; struct ivl_net_const_s *obj = new struct ivl_net_const_s; if (net->is_string()) { obj->type = IVL_VT_STRING; assert((net->width() % 8) == 0); } else obj->type = IVL_VT_BOOL; assert(net->scope()); obj->scope = find_scope(des_, net->scope()); FILE_NAME(obj, net); /* constants have a single vector output. */ assert(net->pin_count() == 1); obj->width_ = net->width(); obj->signed_ = net->value().has_sign(); if (obj->width_ <= sizeof(obj->b.bit_)) { bits = obj->b.bit_; } else { if (obj->width_ >= bits_cnt) { bits_tmp = (char*)realloc(bits_tmp, obj->width_+1); bits_cnt = obj->width_+1; } bits = bits_tmp; } for (idx = 0 ; idx < obj->width_ ; idx += 1) switch (net->value(idx)) { case verinum::V0: bits[idx] = '0'; break; case verinum::V1: bits[idx] = '1'; break; case verinum::Vx: if (obj->type == IVL_VT_BOOL) obj->type = IVL_VT_LOGIC; bits[idx] = 'x'; assert(! net->is_string()); break; case verinum::Vz: if (obj->type == IVL_VT_BOOL) obj->type = IVL_VT_LOGIC; bits[idx] = 'z'; assert(! net->is_string()); break; } if (obj->width_ > sizeof(obj->b.bit_)) { bits[obj->width_] = 0; obj->b.bits_ = net_const_strings.make(bits); } /* Connect to all the nexus objects. Note that the one-bit case can be handled more efficiently without allocating array space. */ ivl_drive_t drv0, drv1; drive_from_link(net->pin(0), drv0, drv1); const Nexus*nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->pin_ = nex->t_cookie(); nexus_con_add(obj->pin_, obj, 0, drv0, drv1); des_.consts.push_back(obj); make_const_delays_(obj, net); return true; } bool dll_target::net_literal(const NetLiteral*net) { struct ivl_net_const_s *obj = new struct ivl_net_const_s; obj->type = IVL_VT_REAL; assert(net->scope()); obj->scope = find_scope(des_, net->scope()); FILE_NAME(obj, net); obj->width_ = 1; obj->signed_ = 1; obj->b.real_value = net->value_real().as_double(); /* Connect to all the nexus objects. Note that the one-bit case can be handled more efficiently without allocating array space. */ ivl_drive_t drv0, drv1; drive_from_link(net->pin(0), drv0, drv1); const Nexus*nex = net->pin(0).nexus(); assert(nex->t_cookie()); obj->pin_ = nex->t_cookie(); nexus_con_add(obj->pin_, obj, 0, drv0, drv1); des_.consts.push_back(obj); make_const_delays_(obj, net); return true; } void dll_target::net_probe(const NetEvProbe*) { } void dll_target::scope(const NetScope*net) { if (net->parent() == 0) { // Root scopes are already created... } else { perm_string sname = make_scope_name(net->fullname()); ivl_scope_t scop = new struct ivl_scope_s; scop->name_ = sname; FILE_NAME(scop, net); scop->parent = find_scope(des_, net->parent()); assert(scop->parent); scop->parent->children[net->fullname()] = scop; scop->parent->child .push_back(scop); scop->nlog_ = 0; scop->log_ = 0; scop->nevent_ = 0; scop->event_ = 0; scop->nlpm_ = 0; scop->lpm_ = 0; scop->def = 0; make_scope_parameters(scop, net); scop->time_precision = net->time_precision(); scop->time_units = net->time_unit(); scop->nattr = net->attr_cnt(); scop->attr = fill_in_attributes(net); scop->is_auto = net->is_auto(); scop->is_cell = net->is_cell(); switch (net->type()) { case NetScope::PACKAGE: cerr << "?:?" << ": internal error: " << "Package scopes should not have parents." << endl; // fallthrough case NetScope::MODULE: scop->type_ = IVL_SCT_MODULE; scop->tname_ = net->module_name(); scop->ports = net->module_port_nets(); if (scop->ports > 0) { scop->u_.net = new NetNet*[scop->ports]; for (unsigned idx = 0; idx < scop->ports; idx += 1) { scop->u_.net[idx] = net->module_port_net(idx); } } scop->module_ports_info = net->module_port_info(); break; case NetScope::TASK: { const NetTaskDef*def = net->task_def(); if (def == 0) { cerr << "?:?" << ": internal error: " << "task " << scop->name_ << " has no definition." << endl; } assert(def); scop->type_ = IVL_SCT_TASK; scop->tname_ = def->scope()->basename(); break; } case NetScope::FUNC: fill_in_scope_function(scop, net); break; case NetScope::BEGIN_END: scop->type_ = IVL_SCT_BEGIN; scop->tname_ = scop->name_; break; case NetScope::FORK_JOIN: scop->type_ = IVL_SCT_FORK; scop->tname_ = scop->name_; break; case NetScope::GENBLOCK: scop->type_ = IVL_SCT_GENERATE; scop->tname_ = scop->name_; break; case NetScope::CLASS: scop->type_ = IVL_SCT_CLASS; scop->tname_ = scop->name_; break; } } } void dll_target::convert_module_ports(const NetScope*net) { ivl_scope_t scop = find_scope(des_, net); if (scop->ports > 0) { NetNet**nets = scop->u_.net; scop->u_.nex = new ivl_nexus_t[scop->ports]; for (unsigned idx = 0; idx < scop->ports; idx += 1) { ivl_signal_t sig = find_signal(des_, nets[idx]); scop->u_.nex[idx] = nexus_sig_make(sig, 0); } delete [] nets; } } void dll_target::signal(const NetNet*net) { ivl_signal_t obj = new struct ivl_signal_s; obj->name_ = net->name(); /* Attach the signal to the ivl_scope_t object that contains it. This involves growing the sigs_ array in the scope object, or creating the sigs_ array if this is the first signal. */ obj->scope_ = find_scope(des_, net->scope()); assert(obj->scope_); FILE_NAME(obj, net); obj->scope_->sigs_.push_back(obj); /* Save the primitive properties of the signal in the ivl_signal_t object. */ { size_t idx = 0; vector::const_iterator cur; obj->packed_dims.resize(net->packed_dims().size()); for (cur = net->packed_dims().begin(), idx = 0 ; cur != net->packed_dims().end() ; ++cur, idx += 1) { obj->packed_dims[idx] = *cur; } } obj->net_type = net->net_type(); obj->local_ = net->local_flag()? 1 : 0; obj->forced_net_ = (net->type() != NetNet::REG) && (net->peek_lref() > 0) ? 1 : 0; obj->discipline = net->get_discipline(); obj->array_dimensions_ = net->unpacked_dimensions(); switch (net->port_type()) { case NetNet::PINPUT: obj->port_ = IVL_SIP_INPUT; break; case NetNet::POUTPUT: obj->port_ = IVL_SIP_OUTPUT; break; case NetNet::PINOUT: obj->port_ = IVL_SIP_INOUT; break; default: obj->port_ = IVL_SIP_NONE; break; } obj->module_port_index_ = net->get_module_port_index(); switch (net->type()) { case NetNet::REG: obj->type_ = IVL_SIT_REG; break; /* The SUPPLY0/1 net types are replaced with pulldown/up by elaborate. They should not make it here. */ case NetNet::SUPPLY0: assert(0); break; case NetNet::SUPPLY1: assert(0); break; /* We will convert this to a TRI after we check that there is only one driver. */ case NetNet::UNRESOLVED_WIRE: obj->type_ = IVL_SIT_UWIRE; break; case NetNet::TRI: case NetNet::WIRE: case NetNet::IMPLICIT: obj->type_ = IVL_SIT_TRI; break; case NetNet::TRI0: obj->type_ = IVL_SIT_TRI0; break; case NetNet::TRI1: obj->type_ = IVL_SIT_TRI1; break; case NetNet::TRIAND: case NetNet::WAND: obj->type_ = IVL_SIT_TRIAND; break; case NetNet::TRIOR: case NetNet::WOR: obj->type_ = IVL_SIT_TRIOR; break; default: obj->type_ = IVL_SIT_NONE; break; } /* Initialize the path fields to be filled in later. */ obj->npath = 0; obj->path = 0; obj->nattr = net->attr_cnt(); obj->attr = fill_in_attributes(net); // Special case: IVL_VT_QUEUE objects don't normally show up in the // network, but can in certain special cases. In these cases, it is the // object itself and not the array elements that is in the network. of // course, only do this if there is at least one link to this signal. if (obj->net_type->base_type()==IVL_VT_QUEUE && net->is_linked()) { const Nexus*nex = net->pin(0).nexus(); ivl_nexus_t tmp = nexus_sig_make(obj, 0); tmp->nexus_ = nex; tmp->name_ = 0; nex->t_cookie(tmp); } /* Get the nexus objects for all the pins of the signal. If the signal has only one pin, then write the single ivl_nexus_t object into n.pin_. Otherwise, make an array of ivl_nexus_t cookies. When I create an ivl_nexus_t object, store it in the t_cookie of the Nexus object so that I find it again when I next encounter the nexus. */ if (obj->array_dimensions_ == 1) { const vector& dims = net->unpacked_dims(); if (dims[0].get_msb() < dims[0].get_lsb()) { obj->array_base = dims[0].get_msb(); obj->array_addr_swapped = false; } else { obj->array_base = dims[0].get_lsb(); obj->array_addr_swapped = true; } obj->array_words = net->unpacked_count(); } else { // The back-end API doesn't yet support multi-dimension // unpacked arrays, so just report the canonical dimensions. obj->array_base = 0; // For a queue we pass the maximum queue size as the array words. if (obj->net_type->base_type() == IVL_VT_QUEUE) { long max_size = net->queue_type()->max_idx()+1; ivl_assert(*net, max_size >= 0); obj->array_words = max_size; } else obj->array_words = net->unpacked_count(); obj->array_addr_swapped = 0; } ivl_assert(*net, (obj->array_words == net->pin_count()) || (obj->net_type->base_type() == IVL_VT_QUEUE)); if (debug_optimizer && obj->array_words > 1000) cerr << "debug: " "t-dll creating nexus array " << obj->array_words << " long" << endl; if (obj->array_words > 1 && net->pins_are_virtual()) { obj->pins = NULL; if (debug_optimizer && obj->array_words > 1000) cerr << "debug: " "t-dll used NULL for big nexus array" << endl; return; } if (obj->array_words > 1) obj->pins = new ivl_nexus_t[obj->array_words]; for (unsigned idx = 0 ; idx < obj->array_words ; idx += 1) { const Nexus*nex = net->pins_are_virtual() ? 0 : net->pin(idx).nexus(); if (nex == 0) { // Special case: This pin is connected to // nothing. This can happen, for example, if the // variable is only used in behavioral // code. Create a stub nexus. ivl_nexus_t tmp = nexus_sig_make(obj, idx); tmp->nexus_ = nex; tmp->name_ = 0; if (obj->array_words > 1) obj->pins[idx] = tmp; else obj->pin = tmp; } else if (nex->t_cookie()) { if (obj->array_words > 1) { obj->pins[idx] = nex->t_cookie(); nexus_sig_add(obj->pins[idx], obj, idx); } else { obj->pin = nex->t_cookie(); nexus_sig_add(obj->pin, obj, idx); } } else { ivl_nexus_t tmp = nexus_sig_make(obj, idx); tmp->nexus_ = nex; tmp->name_ = 0; nex->t_cookie(tmp); if (obj->array_words > 1) obj->pins[idx] = tmp; else obj->pin = tmp; } } if (debug_optimizer && obj->array_words > 1000) cerr << "debug: t-dll done with big nexus array" << endl; } bool dll_target::signal_paths(const NetNet*net) { /* Nothing to do if there are no paths for this signal. */ if (net->delay_paths() == 0) return true; ivl_signal_t obj = find_signal(des_, net); assert(obj); /* We cannot have already set up the paths for this signal. */ assert(obj->npath == 0); assert(obj->path == 0); /* Figure out how many paths there really are. */ for (unsigned idx = 0 ; idx < net->delay_paths() ; idx += 1) { const NetDelaySrc*src = net->delay_path(idx); obj->npath += src->src_count(); } obj->path = new struct ivl_delaypath_s[obj->npath]; unsigned ptr = 0; for (unsigned idx = 0 ; idx < net->delay_paths() ; idx += 1) { const NetDelaySrc*src = net->delay_path(idx); /* If this path has a condition, then hook it up. */ ivl_nexus_t path_condit = 0; if (src->has_condit()) { const Nexus*nt = src->condit_pin().nexus(); path_condit = nt->t_cookie(); } for (unsigned pin = 0; pin < src->src_count(); pin += 1) { const Nexus*nex = src->src_pin(pin).nexus(); if (! nex->t_cookie()) { cerr << src->get_fileline() << ": internal error: " << "No signal connected to pin " << pin << " of delay path to " << net->name() << "." << endl; } assert(nex->t_cookie()); obj->path[ptr].scope = lookup_scope_(src->scope()); obj->path[ptr].src = nex->t_cookie(); obj->path[ptr].condit = path_condit; obj->path[ptr].conditional = src->is_condit(); obj->path[ptr].parallel = src->is_parallel(); obj->path[ptr].posedge = src->is_posedge(); obj->path[ptr].negedge = src->is_negedge(); for (unsigned pe = 0 ; pe < 12 ; pe += 1) { obj->path[ptr].delay[pe] = src->get_delay(pe); } ptr += 1; } } return true; } void dll_target::test_version(const char*target_name) { dll_ = ivl_dlopen(target_name); if ((dll_ == 0) && (target_name[0] != '/')) { size_t len = strlen(basedir) + 1 + strlen(target_name) + 1; char*tmp = new char[len]; snprintf(tmp, len, "%s/%s", basedir, target_name); dll_ = ivl_dlopen(tmp); delete[]tmp; } if (dll_ == 0) { cout << "\n\nUnable to load " << target_name << " for version details." << endl; return; } target_query_f targ_query = (target_query_f)ivl_dlsym(dll_, LU "target_query" TU); if (targ_query == 0) { cerr << "Target " << target_name << " has no version hooks." << endl; return; } const char*version_string = (*targ_query) ("version"); if (version_string == 0) { cerr << "Target " << target_name << " has no version string" << endl; return; } cout << target_name << ": " << version_string << endl; } iverilog-12_0/t-dll.h000066400000000000000000000574111435245347300145440ustar00rootroot00000000000000#ifndef IVL_t_dll_H #define IVL_t_dll_H /* * Copyright (c) 2000-2021 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 "target.h" # include "ivl_target.h" # include "ivl_target_priv.h" # include "StringHeap.h" # include "netlist.h" # include # include #if defined(__MINGW32__) #include typedef void *ivl_dll_t; #elif defined(HAVE_DLFCN_H) # include typedef void* ivl_dll_t; #elif defined(HAVE_DL_H) # include typedef shl_t ivl_dll_t; #else # error No DLL stub support for this target. #endif /* * The DLL target type loads a named object file to handle the process * of scanning the netlist. When it is time to start the design, I * locate and link in the desired DLL, then start calling methods. The * DLL will call me back to get information out of the netlist in * particular. */ struct dll_target : public target_t, public expr_scan_t { // This is a special function for loading and testing the // version of a loadable target code generator. void test_version(const char*target_name); bool start_design(const Design*); int end_design(const Design*); bool bufz(const NetBUFZ*); bool branch(const NetBranch*); bool class_type(const NetScope*, netclass_t*); bool enumeration(const NetScope*, netenum_t*); void event(const NetEvent*); void logic(const NetLogic*); bool tran(const NetTran*); bool ureduce(const NetUReduce*); void net_case_cmp(const NetCaseCmp*); void udp(const NetUDP*); void lpm_abs(const NetAbs*); void lpm_add_sub(const NetAddSub*); bool lpm_array_dq(const NetArrayDq*); bool lpm_cast_int2(const NetCastInt2*); bool lpm_cast_int4(const NetCastInt4*); bool lpm_cast_real(const NetCastReal*); void lpm_clshift(const NetCLShift*); void lpm_compare(const NetCompare*); void lpm_divide(const NetDivide*); void lpm_ff(const NetFF*); void lpm_latch(const NetLatch*); void lpm_modulo(const NetModulo*); void lpm_mult(const NetMult*); void lpm_mux(const NetMux*); void lpm_pow(const NetPow*); bool concat(const NetConcat*); bool part_select(const NetPartSelect*); bool replicate(const NetReplicate*); void net_assign(const NetAssign_*) const; bool net_sysfunction(const NetSysFunc*); bool net_function(const NetUserFunc*); bool net_const(const NetConst*); bool net_literal(const NetLiteral*); void net_probe(const NetEvProbe*); bool sign_extend(const NetSignExtend*); bool substitute(const NetSubstitute*); bool process(const NetProcTop*); bool process(const NetAnalogTop*); void scope(const NetScope*); void convert_module_ports(const NetScope*); void signal(const NetNet*); bool signal_paths(const NetNet*); ivl_dll_t dll_; ivl_design_s des_; target_design_f target_; /* These methods and members are used for forming the statements of a thread. */ struct ivl_statement_s*stmt_cur_; void proc_alloc(const NetAlloc*); bool proc_assign(const NetAssign*); void proc_assign_nb(const NetAssignNB*); bool proc_block(const NetBlock*); void proc_case(const NetCase*); bool proc_cassign(const NetCAssign*); bool proc_condit(const NetCondit*); bool proc_contribution(const NetContribution*); bool proc_deassign(const NetDeassign*); bool proc_delay(const NetPDelay*); bool proc_disable(const NetDisable*); void proc_do_while(const NetDoWhile*); bool proc_force(const NetForce*); void proc_forever(const NetForever*); void proc_free(const NetFree*); bool proc_release(const NetRelease*); void proc_repeat(const NetRepeat*); void proc_stask(const NetSTask*); bool proc_trigger(const NetEvTrig*); bool proc_nb_trigger(const NetEvNBTrig*); void proc_utask(const NetUTask*); bool proc_wait(const NetEvWait*); void proc_while(const NetWhile*); bool func_def(const NetScope*); void task_def(const NetScope*); struct ivl_expr_s*expr_; void expr_access_func(const NetEAccess*); void expr_array_pattern(const NetEArrayPattern*); void expr_binary(const NetEBinary*); void expr_concat(const NetEConcat*); void expr_const(const NetEConst*); void expr_creal(const NetECReal*); void expr_last(const NetELast*); void expr_new(const NetENew*); void expr_null(const NetENull*); void expr_param(const NetEConstParam*); void expr_property(const NetEProperty*); void expr_rparam(const NetECRealParam*); void expr_event(const NetEEvent*); void expr_scope(const NetEScope*); void expr_scopy(const NetEShallowCopy*); void expr_netenum(const NetENetenum*); void expr_select(const NetESelect*); void expr_sfunc(const NetESFunc*); void expr_ternary(const NetETernary*); void expr_ufunc(const NetEUFunc*); void expr_unary(const NetEUnary*); void expr_signal(const NetESignal*); ivl_scope_t lookup_scope_(const NetScope*scope); ivl_attribute_s* fill_in_attributes(const Attrib*net); void switch_attributes(struct ivl_switch_s *obj, const NetNode*net); void logic_attributes(struct ivl_net_logic_s *obj, const NetNode*net); private: StringHeap strings_; static ivl_scope_t find_scope(ivl_design_s &des, const NetScope*cur); static ivl_signal_t find_signal(ivl_design_s &des, const NetNet*net); static ivl_parameter_t scope_find_param(ivl_scope_t scope, const char*name); void add_root(const NetScope *s); bool make_assign_lvals_(const NetAssignBase*net); bool make_single_lval_(const LineInfo*li, struct ivl_lval_s*cur, const NetAssign_*asn); void sub_off_from_expr_(long); void mul_expr_by_const_(long); void make_delays_(ivl_expr_t*delay, const NetObj*net); void make_logic_delays_(struct ivl_net_logic_s*obj, const NetObj*net); void make_switch_delays_(struct ivl_switch_s*obj, const NetObj*net); void make_lpm_delays_(struct ivl_lpm_s*obj, const NetObj*net); void make_const_delays_(struct ivl_net_const_s*obj, const NetObj*net); void make_scope_parameters(ivl_scope_t scope, const NetScope*net); void make_scope_param_expr(ivl_parameter_t cur_par, NetExpr*etmp); ivl_event_t make_lpm_trigger(const NetEvWait*ev); bool lpm_arith1_(ivl_lpm_type_t lpm_type, unsigned wid, bool signed_flag, const NetNode*net); static ivl_expr_t expr_from_value_(const verinum&that); }; extern struct dll_target dll_target_obj; /* * These are various private declarations used by the t-dll target. */ struct ivl_delaypath_s { ivl_scope_t scope; ivl_nexus_t src; ivl_nexus_t condit; bool conditional; bool parallel; bool posedge; bool negedge; uint64_t delay[12]; }; struct ivl_event_s { perm_string name; ivl_scope_t scope; perm_string file; unsigned lineno; unsigned nany, nneg, npos, nedg; ivl_nexus_t*pins; }; /* * The ivl_expr_t is an opaque reference to one of these * structures. This structure holds all the information we need about * an expression node, including its type, the expression width, and * type specific properties. */ struct ivl_expr_s { ivl_expr_type_t type_; ivl_variable_type_t value_; ivl_type_t net_type; perm_string file; unsigned lineno; unsigned width_; unsigned signed_ : 1; unsigned sized_ : 1; union { struct { char op_; ivl_expr_t lef_; ivl_expr_t rig_; } binary_; struct { size_t parms; ivl_expr_t*parm; } array_pattern_; struct { ivl_select_type_t sel_type_; ivl_expr_t expr_; ivl_expr_t base_; } select_; struct { ivl_expr_t dest; ivl_expr_t src; } shallow_; struct { ivl_branch_t branch; ivl_nature_t nature; } branch_; struct { unsigned rept; unsigned parms; ivl_expr_t*parm; } concat_; struct { char*bits_; ivl_parameter_t parameter; } number_; struct { ivl_event_t event; } event_; struct { ivl_scope_t scope; } scope_; struct { ivl_enumtype_t type; } enumtype_; struct { ivl_signal_t sig; ivl_expr_t word; } signal_; struct { const char *name_; ivl_expr_t *parm; unsigned parms; } sfunc_; struct { char*value_; ivl_parameter_t parameter; } string_; struct { ivl_expr_t cond; ivl_expr_t true_e; ivl_expr_t false_e; } ternary_; struct { ivl_memory_t mem_; ivl_expr_t idx_; } memory_; struct { ivl_scope_t def; ivl_expr_t *parm; unsigned parms; } ufunc_; struct { unsigned long value; } ulong_; struct { double value; ivl_parameter_t parameter; } real_; struct { char op_; ivl_expr_t sub_; } unary_; struct { uint64_t value; } delay_; struct { ivl_expr_t size; ivl_expr_t init_val; } new_; struct { ivl_signal_t sig; unsigned prop_idx; ivl_expr_t index; } property_; } u_; }; /* * LPM devices are handled by this suite of types. The ivl_lpm_s * structure holds the core, including a type code, the object name * and scope. The other properties of the device are held in the type * specific member of the union. */ struct ivl_lpm_s { ivl_lpm_type_t type; ivl_scope_t scope; perm_string name; perm_string file; unsigned lineno; // Value returned by ivl_lpm_width; unsigned width; ivl_expr_t delay[3]; union { struct ivl_lpm_ff_s { unsigned negedge_flag :1; ivl_nexus_t clk; ivl_nexus_t we; ivl_nexus_t aclr; ivl_nexus_t aset; ivl_nexus_t sclr; ivl_nexus_t sset; union { ivl_nexus_t*pins; ivl_nexus_t pin; } q; union { ivl_nexus_t*pins; ivl_nexus_t pin; } d; ivl_expr_t aset_value; ivl_expr_t sset_value; } ff; struct ivl_lpm_latch_s { ivl_nexus_t e; union { ivl_nexus_t*pins; ivl_nexus_t pin; } q; union { ivl_nexus_t*pins; ivl_nexus_t pin; } d; } latch; struct ivl_lpm_mux_s { unsigned size; unsigned swid; ivl_nexus_t*d; ivl_nexus_t q, s; } mux; struct ivl_lpm_shift_s { unsigned select; unsigned signed_flag :1; ivl_nexus_t q, d, s; } shift; struct ivl_lpm_arith_s { unsigned signed_flag :1; ivl_nexus_t q, a, b; } arith; struct ivl_lpm_array_s { ivl_signal_t sig; unsigned swid; ivl_nexus_t q, a; } array; struct ivl_concat_s { unsigned inputs; ivl_nexus_t*pins; } concat; struct ivl_part_s { unsigned base; unsigned signed_flag :1; ivl_nexus_t q, a, s; } part; // IVL_LPM_RE_* and IVL_LPM_SIGN_EXT use this. struct ivl_lpm_reduce_s { ivl_nexus_t q, a; } reduce; struct ivl_lpm_repeat_s { unsigned count; ivl_nexus_t q, a; } repeat; struct ivl_lpm_sfunc_s { const char* fun_name; unsigned ports; ivl_nexus_t*pins; ivl_event_t trigger; } sfunc; struct ivl_lpm_substitute { unsigned base; ivl_nexus_t q, a, s; } substitute; struct ivl_lpm_ufunc_s { ivl_scope_t def; unsigned ports; ivl_nexus_t*pins; ivl_event_t trigger; } ufunc; } u_; }; /* * This object represents l-values to assignments. The l-value can be * a register bit or part select, or a memory word select with a part * select. */ enum ivl_lval_type_t { IVL_LVAL_REG = 0, IVL_LVAL_ARR = 4, IVL_LVAL_LVAL= 5 // Nested l-value }; struct ivl_lval_s { ivl_expr_t loff; ivl_select_type_t sel_type :3; ivl_expr_t idx; unsigned width_; unsigned type_ : 8; /* values from ivl_lval_type_t */ int property_idx; union { ivl_signal_t sig; ivl_lval_t nest; // type_ == IVL_LVAL_LVAL } n; }; /* * This object represents a literal constant, possibly signed, in a * structural context. */ struct ivl_net_const_s { ivl_variable_type_t type : 4; unsigned width_ : 24; unsigned signed_ : 1; perm_string file; unsigned lineno; ivl_scope_t scope; union { double real_value; char bit_[sizeof(char*)]; const char* bits_; } b; ivl_nexus_t pin_; ivl_expr_t delay[3]; void* operator new (size_t s); void operator delete(void*obj, size_t s); // Not implemented }; /* * Logic gates (just about everything that has a single output) are * represented structurally by instances of this object. */ struct ivl_net_logic_s { ivl_logic_t type_; unsigned width_; unsigned is_cassign; ivl_udp_t udp; perm_string name_; ivl_scope_t scope_; perm_string file; unsigned lineno; unsigned npins_; ivl_nexus_t*pins_; struct ivl_attribute_s*attr; unsigned nattr; ivl_expr_t delay[3]; }; struct ivl_switch_s { ivl_switch_type_t type; unsigned width; unsigned part; unsigned offset; perm_string name; ivl_scope_t scope; ivl_island_t island; struct ivl_attribute_s*attr; unsigned nattr; ivl_expr_t delay[3]; ivl_nexus_t pins[3]; perm_string file; unsigned lineno; }; /* * UDP definition. */ struct ivl_udp_s { perm_string name; unsigned nin; int sequ; /* boolean */ char init; unsigned nrows; typedef const char*ccharp_t; ccharp_t*table; // zero terminated array of pointers perm_string file; unsigned lineno; std::string*ports; }; /* * The ivl_nexus_t is a single-bit link of some number of pins of * devices. the __nexus_ptr structure is a helper that actually does * the pointing. * * The type_ member specifies which of the object pointers in the * union are valid. * * The drive01 members gives the strength of the drive that the device * is applying to the nexus, with 0 HiZ and 3 supply. If the pin is an * input to the device, then the drives are both HiZ. */ struct ivl_nexus_ptr_s { unsigned pin_; unsigned type_ : 8; unsigned drive0 : 3; unsigned drive1 : 3; union { ivl_signal_t sig; /* type 0 */ ivl_net_logic_t log; /* type 1 */ ivl_net_const_t con; /* type 2 */ ivl_lpm_t lpm; /* type 3 */ ivl_switch_t swi; /* type 4 */ ivl_branch_t bra; /* type 5 */ } l; }; # define __NEXUS_PTR_SIG 0 # define __NEXUS_PTR_LOG 1 # define __NEXUS_PTR_CON 2 # define __NEXUS_PTR_LPM 3 # define __NEXUS_PTR_SWI 4 # define __NEXUS_PTR_BRA 5 /* * NOTE: ONLY allocate ivl_nexus_s objects with the included "new" operator. */ struct ivl_nexus_s { ivl_nexus_s() : ptrs_(1), nexus_(0), name_(0), private_data(0) { } std::vectorptrs_; const Nexus*nexus_; const char*name_; void*private_data; void* operator new (size_t s); void operator delete(void*obj, size_t s); // Not implemented }; /* * This is the implementation of a parameter. Each scope has a list of * these. */ struct ivl_parameter_s { perm_string basename; ivl_scope_t scope; ivl_expr_t value; long msb; long lsb; bool signed_flag; bool local; bool is_type; perm_string file; unsigned lineno; }; /* * All we know about a process is its type (initial or always) and the * single statement that is it. A process also has a scope, although * that generally only matters for VPI calls. */ struct ivl_process_s { ivl_process_type_t type_ : 3; unsigned int analog_flag : 1; ivl_scope_t scope_; ivl_statement_t stmt_; perm_string file; unsigned lineno; struct ivl_attribute_s*attr; unsigned nattr; ivl_process_t next_; }; /* * Scopes are kept in a tree. Each scope points to its first child, * and also to any siblings. Thus a parent can scan all its children * by following its child pointer, then following sibling pointers from * there. */ struct ivl_scope_s { ivl_scope_s(); ivl_scope_t parent; std::map children; // This is just like the children map above, but in vector // form for convenient access. std::vector child; perm_string name_; perm_string tname_; perm_string file; perm_string def_file; unsigned lineno; unsigned def_lineno; ivl_scope_type_t type_; std::vector classes; std::vector enumerations_; std::vector sigs_; unsigned nlog_; ivl_net_logic_t*log_; unsigned nevent_; ivl_event_t* event_; unsigned nlpm_; ivl_lpm_t* lpm_; std::vector param; /* Scopes that are tasks/functions have a definition. */ ivl_statement_t def; unsigned is_auto; ivl_variable_type_t func_type; bool func_signed; unsigned func_width; unsigned is_cell; // Ports of Module scope (just introspection data for VPI) - actual connections // are nets defined in u_.net (may be > 1 per module port) std::vector module_ports_info; unsigned ports; union { ivl_signal_t*port; ivl_nexus_t*nex; NetNet**net; } u_; std::vectorswitches; signed int time_precision :8; signed int time_units :8; struct ivl_attribute_s*attr; unsigned nattr; }; /* * A signal is a thing like a wire, a reg, or whatever. It has a type, * and if it is a port is also has a direction. Signals are collected * into scopes (which also point back to me) and have pins that * connect to the rest of the netlist. */ struct ivl_signal_s { ivl_signal_type_t type_; ivl_signal_port_t port_; int module_port_index_; ivl_discipline_t discipline; perm_string file; unsigned lineno; // This is the type for the signal ivl_type_t net_type; unsigned local_ : 1; unsigned forced_net_ : 1; /* For now, support only 0 or 1 array dimensions. */ unsigned array_dimensions_ : 8; unsigned array_addr_swapped : 1; /* These encode the declared packed dimensions for the signal, in case they are needed by the run-time */ std::vector packed_dims; perm_string name_; ivl_scope_t scope_; unsigned array_words; int array_base; union { ivl_nexus_t pin; ivl_nexus_t*pins; }; ivl_delaypath_s*path; unsigned npath; struct ivl_attribute_s*attr; unsigned nattr; }; /* * The ivl_statement_t represents any statement. The type of statement * is defined by the ivl_statement_type_t enumeration. Given the type, * certain information about the statement may be available. */ struct ivl_statement_s { enum ivl_statement_type_e type_; perm_string file; unsigned lineno; union { struct { /* IVL_ST_ALLOC */ ivl_scope_t scope; } alloc_; struct { /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN, IVL_ST_DEASSIGN */ unsigned lvals_; struct ivl_lval_s*lval_; char oper; // Operator if this is a compressed assignment. ivl_expr_t rval_; ivl_expr_t delay; // The following are only for NB event control. ivl_expr_t count; unsigned nevent; union { ivl_event_t event; ivl_event_t*events; }; } assign_; struct { /* IVL_ST_BLOCK, IVL_ST_FORK */ struct ivl_statement_s*stmt_; unsigned nstmt_; ivl_scope_t scope; } block_; struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */ ivl_case_quality_t quality; ivl_expr_t cond; unsigned ncase; ivl_expr_t*case_ex; struct ivl_statement_s*case_st; } case_; struct { /* IVL_ST_CONDIT */ /* This is the condition expression */ ivl_expr_t cond_; /* This is two statements, the true and false. */ struct ivl_statement_s*stmt_; } condit_; struct { /* IVL_ST_CONTRIB */ ivl_expr_t lval; ivl_expr_t rval; } contrib_; struct { /* IVL_ST_DELAY */ uint64_t value; ivl_statement_t stmt_; } delay_; struct { /* IVL_ST_DELAYX */ ivl_expr_t expr; /* XXXX */ ivl_statement_t stmt_; } delayx_; struct { /* IVL_ST_DISABLE */ ivl_scope_t scope; bool flow_control; } disable_; struct { /* IVL_ST_FOREVER */ ivl_statement_t stmt_; } forever_; struct { /* IVL_ST_FREE */ ivl_scope_t scope; } free_; struct { /* IVL_ST_STASK */ const char*name_; ivl_sfunc_as_task_t sfunc_as_task_; unsigned nparm_; ivl_expr_t*parms_; } stask_; struct { /* IVL_ST_UTASK */ ivl_scope_t def; } utask_; struct { /* IVL_ST_TRIGGER IVL_ST_NB_TRIGGER IVL_ST_WAIT */ unsigned needs_t0_trigger; unsigned nevent; union { ivl_event_t event; ivl_event_t*events; }; ivl_expr_t delay; ivl_statement_t stmt_; } wait_; struct { /* IVL_ST_WHILE IVL_ST_REPEAT */ ivl_expr_t cond_; ivl_statement_t stmt_; } while_; } u_; }; /* * The FILE_NAME function is a shorthand for attaching file/line * information to the statement object. */ static inline void FILE_NAME(ivl_expr_t expr, const LineInfo*info) { expr->file = info->get_file(); expr->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_event_t event, const LineInfo*info) { event->file = info->get_file(); event->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_lpm_t lpm, const LineInfo*info) { lpm->file = info->get_file(); lpm->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_net_const_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_net_logic_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_parameter_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_process_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_scope_t scope, const NetScope*info) { scope->file = info->get_file(); scope->def_file = info->get_def_file(); scope->lineno = info->get_lineno(); scope->def_lineno = info->get_def_lineno(); } static inline void FILE_NAME(ivl_statement_t stmt, const LineInfo*info) { stmt->file = info->get_file(); stmt->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_switch_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } static inline void FILE_NAME(ivl_signal_t net, const LineInfo*info) { net->file = info->get_file(); net->lineno = info->get_lineno(); } #endif /* IVL_t_dll_H */ iverilog-12_0/t-dll.txt000066400000000000000000000040631435245347300151270ustar00rootroot00000000000000 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-12_0/target.cc000066400000000000000000000355071435245347300151560ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 Stephen Williams * * 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 # include "target.h" # include using namespace std; target_t::~target_t() { } void target_t::scope(const NetScope*) { } void target_t::convert_module_ports(const NetScope*) { } bool target_t::branch(const NetBranch*obj) { cerr << obj->get_fileline() << ": error: target (" << typeid(*this).name() << "): Unhandled branch." << endl; return false; } bool target_t::class_type(const NetScope*, netclass_t*obj) { cerr << "<>:0" << ": error: target (" << typeid(*this).name() << "): Unhandled class_type <" << obj << ">." << endl; return false; } void target_t::event(const NetEvent*ev) { cerr << ev->get_fileline() << ": error: target (" << typeid(*this).name() << "): Unhandled event <" << ev->name() << ">." << endl; } bool target_t::enumeration(const NetScope*, netenum_t*obj) { cerr << "<>:0" << ": error: target (" << typeid(*this).name() << "): Unhandled enumeration <" << obj << ">." << endl; return false; } bool target_t::signal_paths(const NetNet*) { return true; } bool target_t::func_def(const NetScope*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled function definition." << endl; return false; } void target_t::task_def(const NetScope*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled task definition." << endl; } void target_t::logic(const NetLogic*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled logic gate" << endl; } bool target_t::tran(const NetTran*) { cerr << "target (" << typeid(*this).name() << "): " << "TRAN devices not supported." << endl; return false; } bool target_t::bufz(const NetBUFZ*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled continuous assign (BUFZ)." << endl; return false; } void target_t::udp(const NetUDP*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled UDP." << endl; } bool target_t::ureduce(const NetUReduce*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled unary reduction logic gate." << endl; return false; } void target_t::lpm_abs(const NetAbs*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetAbs." << endl; } void target_t::lpm_add_sub(const NetAddSub*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetAddSub." << endl; } bool target_t::lpm_array_dq(const NetArrayDq*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetArrayDq." << endl; return false; } bool target_t::lpm_cast_int2(const NetCastInt2*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetCastInt2." << endl; return false; } bool target_t::lpm_cast_int4(const NetCastInt4*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetCastInt4." << endl; return false; } bool target_t::lpm_cast_real(const NetCastReal*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetCastReal." << endl; return false; } void target_t::lpm_clshift(const NetCLShift*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetCLShift." << endl; } void target_t::lpm_compare(const NetCompare*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetCompare." << endl; } void target_t::lpm_divide(const NetDivide*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetDivide." << endl; } void target_t::lpm_modulo(const NetModulo*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetModulo." << endl; } void target_t::lpm_ff(const NetFF*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetFF." << endl; } void target_t::lpm_latch(const NetLatch*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetLatch." << endl; } void target_t::lpm_mult(const NetMult*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetMult." << endl; } void target_t::lpm_mux(const NetMux*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetMux." << endl; } void target_t::lpm_pow(const NetPow*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetPow." << endl; } bool target_t::concat(const NetConcat*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetConcat." << endl; return false; } bool target_t::part_select(const NetPartSelect*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetPartSelect." << endl; return false; } bool target_t::replicate(const NetReplicate*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetReplicate." << endl; return false; } void target_t::net_case_cmp(const NetCaseCmp*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled case compare node." << endl; } bool target_t::net_const(const NetConst*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled CONSTANT node." << endl; return false; } bool target_t::net_sysfunction(const NetSysFunc*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetSysFunc node." << endl; return false; } bool target_t::net_function(const NetUserFunc*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetUserFunc node." << endl; return false; } bool target_t::net_literal(const NetLiteral*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled LITERAL node." << endl; return false; } void target_t::net_probe(const NetEvProbe*net) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled probe trigger node" << endl; net->dump_node(cerr, 4); } bool target_t::sign_extend(const NetSignExtend*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetSignExtend node." << endl; return false; } bool target_t::substitute(const NetSubstitute*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled NetSubstitute node." << endl; return false; } bool target_t::process(const NetProcTop*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled process(NetProcTop)." << endl; return false; } bool target_t::process(const NetAnalogTop*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled process(NetAnalogTop)." << endl; return false; } void target_t::proc_alloc(const NetAlloc*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_alloc." << endl; } bool target_t::proc_assign(const NetAssign*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled procedural assignment." << endl; return false; } void target_t::proc_assign_nb(const NetAssignNB*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled non-blocking assignment." << endl; } bool target_t::proc_block(const NetBlock*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_block." << endl; return false; } void target_t::proc_case(const NetCase*cur) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled case:" << endl; cur->dump(cerr, 6); } bool target_t::proc_cassign(const NetCAssign*dev) { cerr << "target (" << typeid(*this).name() << "): "; cerr << dev->get_fileline(); cerr << ": Target does not support procedural continuous assignment." << endl; return false; } bool target_t::proc_condit(const NetCondit*condit) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled conditional:" << endl; condit->dump(cerr, 6); return false; } bool target_t::proc_contribution(const NetContribution*net) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled contribution:" << endl; net->dump(cerr, 6); return false; } bool target_t::proc_deassign(const NetDeassign*dev) { cerr << dev->get_fileline() << ": internal error: " << "target (" << typeid(*this).name() << "): " << "Unhandled proc_deassign." << endl; return false; } bool target_t::proc_delay(const NetPDelay*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_delay." << endl; return false; } bool target_t::proc_disable(const NetDisable*obj) { cerr << obj->get_fileline() << ": internal error: " << "target (" << typeid(*this).name() << "): " << "does not support disable statements." << endl; return false; } void target_t::proc_do_while(const NetDoWhile*net) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled do/while:" << endl; net->dump(cerr, 6); } bool target_t::proc_force(const NetForce*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_force." << endl; return false; } void target_t::proc_forever(const NetForever*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_forever." << endl; } void target_t::proc_free(const NetFree*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_free." << endl; } bool target_t::proc_release(const NetRelease*dev) { cerr << dev->get_fileline() << ": internal error: " << "target (" << typeid(*this).name() << "): " << "Unhandled proc_release." << endl; return false; } void target_t::proc_repeat(const NetRepeat*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_repeat." << endl; } bool target_t::proc_trigger(const NetEvTrig*tr) { cerr << tr->get_fileline() << ": error: target (" << typeid(*this).name() << "): Unhandled event trigger." << endl; return false; } bool target_t::proc_nb_trigger(const NetEvNBTrig*tr) { cerr << tr->get_fileline() << ": error: target (" << typeid(*this).name() << "): Unhandled non-blocking event trigger." << endl; return false; } void target_t::proc_stask(const NetSTask*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_stask." << endl; } void target_t::proc_utask(const NetUTask*) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled proc_utask." << endl; } bool target_t::proc_wait(const NetEvWait*tr) { cerr << tr->get_fileline() << ": error: target (" << typeid(*this).name() << "): Unhandled event wait." << endl; return false; } void target_t::proc_while(const NetWhile*net) { cerr << "target (" << typeid(*this).name() << "): " "Unhandled while:" << endl; net->dump(cerr, 6); } int target_t::end_design(const Design*) { return 0; } expr_scan_t::~expr_scan_t() { } void expr_scan_t::expr_access_func(const NetEAccess*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_access_func." << endl; } void expr_scan_t::expr_array_pattern(const NetEArrayPattern*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_array_pattern." << endl; } void expr_scan_t::expr_const(const NetEConst*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_const." << endl; } void expr_scan_t::expr_last(const NetELast*exp) { cerr << exp->get_fileline() << ": expr_scan_t(" << typeid(*this).name() << "): " << "unhandled expr_last." << endl; } void expr_scan_t::expr_new(const NetENew*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_new." << endl; } void expr_scan_t::expr_null(const NetENull*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_null." << endl; } void expr_scan_t::expr_param(const NetEConstParam*that) { expr_const(that); } void expr_scan_t::expr_property(const NetEProperty*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_property." << endl; } void expr_scan_t::expr_creal(const NetECReal*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_creal." << endl; } void expr_scan_t::expr_rparam(const NetECRealParam*that) { expr_creal(that); } void expr_scan_t::expr_concat(const NetEConcat*that) { cerr << that->get_fileline() << ": expr_scan_t (" << typeid(*this).name() << "): unhandled expr_concat." << endl; } void expr_scan_t::expr_event(const NetEEvent*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_event." << endl; } void expr_scan_t::expr_netenum(const NetENetenum*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_netenum." << endl; } void expr_scan_t::expr_scope(const NetEScope*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_scope." << endl; } void expr_scan_t::expr_scopy(const NetEShallowCopy*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_scopy." << endl; } void expr_scan_t::expr_select(const NetESelect*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_select." << endl; } void expr_scan_t::expr_sfunc(const NetESFunc*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_sfunc." << endl; } void expr_scan_t::expr_signal(const NetESignal*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_signal." << endl; } void expr_scan_t::expr_ternary(const NetETernary*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_ternary." << endl; } void expr_scan_t::expr_ufunc(const NetEUFunc*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled function call." << endl; } void expr_scan_t::expr_unary(const NetEUnary*) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_unary." << endl; } void expr_scan_t::expr_binary(const NetEBinary*ex) { cerr << "expr_scan_t (" << typeid(*this).name() << "): " "unhandled expr_binary: " <<*ex << endl; } iverilog-12_0/target.h000066400000000000000000000172661435245347300150220ustar00rootroot00000000000000#ifndef IVL_target_H #define IVL_target_H /* * Copyright (c) 1998-2021 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 "netlist.h" /* * This header file describes the types and constants used to describe * the possible target output types of the compiler. The backends * provide one of these in order to tell the previous steps what the * backend is able to do. */ /* * The backend driver is hooked into the compiler, and given a name, * by creating an instance of the target structure. The structure has * the name that the compiler will use to locate the driver, and a * pointer to a target_t object that is the actual driver. */ struct target { const char* name; struct target_t* meth; }; /* * The emit process uses a target_t driver to send the completed * design to a file. It is up to the driver object to follow along in * the iteration through the design, generating output as it can. */ struct target_t { inline target_t() : errors(0) { } virtual ~target_t(); /* Set this to count errors encountered during emit. */ int errors; /* Start the design. This sets the main output file stream that the target should use. */ virtual bool start_design(const Design*) =0; /* This is called once for each scope in the design, before anything else is called. */ virtual void scope(const NetScope*); virtual bool class_type(const NetScope*, netclass_t*); /* This is called to convert module ports from a NetNet* to an * ivl_signal_t object. */ virtual void convert_module_ports(const NetScope*); /* Output an event object. Called for each named event in the scope. */ virtual void event(const NetEvent*); /* Output an enumeration typespec. */ virtual bool enumeration(const NetScope*, netenum_t*); /* Output a signal (called for each signal) */ virtual void signal(const NetNet*) =0; virtual bool signal_paths(const NetNet*); /* Analog branches */ virtual bool branch(const NetBranch*); /* Output a defined task. */ virtual void task_def(const NetScope*); virtual bool func_def(const NetScope*); /* LPM style components are handled here. */ virtual void lpm_abs(const NetAbs*); virtual void lpm_add_sub(const NetAddSub*); virtual bool lpm_array_dq(const NetArrayDq*); virtual void lpm_clshift(const NetCLShift*); virtual bool lpm_cast_int2(const NetCastInt2*); virtual bool lpm_cast_int4(const NetCastInt4*); virtual bool lpm_cast_real(const NetCastReal*); virtual void lpm_compare(const NetCompare*); virtual void lpm_divide(const NetDivide*); virtual void lpm_modulo(const NetModulo*); virtual void lpm_ff(const NetFF*); virtual void lpm_latch(const NetLatch*); virtual void lpm_mult(const NetMult*); virtual void lpm_mux(const NetMux*); virtual void lpm_pow(const NetPow*); virtual bool concat(const NetConcat*); virtual bool part_select(const NetPartSelect*); virtual bool replicate(const NetReplicate*); /* Output a gate (called for each gate) */ virtual void logic(const NetLogic*); virtual bool tran(const NetTran*); virtual bool ureduce(const NetUReduce*); /* unary reduction operator */ virtual bool bufz(const NetBUFZ*); virtual void udp(const NetUDP*); virtual void net_case_cmp(const NetCaseCmp*); virtual bool net_const(const NetConst*); virtual bool net_sysfunction(const NetSysFunc*); virtual bool net_function(const NetUserFunc*); virtual bool net_literal(const NetLiteral*); virtual void net_probe(const NetEvProbe*); virtual bool sign_extend(const NetSignExtend*); virtual bool substitute(const NetSubstitute*); /* Output a process (called for each process). It is up to the target to recurse if desired. */ virtual bool process(const NetProcTop*); virtual bool process(const NetAnalogTop*); /* Various kinds of process nodes are dispatched through these. */ virtual void proc_alloc(const NetAlloc*); virtual bool proc_assign(const NetAssign*); virtual void proc_assign_nb(const NetAssignNB*); virtual bool proc_block(const NetBlock*); virtual void proc_case(const NetCase*); virtual bool proc_cassign(const NetCAssign*); virtual bool proc_condit(const NetCondit*); virtual bool proc_contribution(const NetContribution*); virtual bool proc_deassign(const NetDeassign*); virtual bool proc_delay(const NetPDelay*); virtual bool proc_disable(const NetDisable*); virtual void proc_do_while(const NetDoWhile*); virtual bool proc_force(const NetForce*); virtual void proc_forever(const NetForever*); virtual void proc_free(const NetFree*); virtual bool proc_release(const NetRelease*); virtual void proc_repeat(const NetRepeat*); virtual bool proc_trigger(const NetEvTrig*); virtual bool proc_nb_trigger(const NetEvNBTrig*); virtual void proc_stask(const NetSTask*); virtual void proc_utask(const NetUTask*); virtual bool proc_wait(const NetEvWait*); virtual void proc_while(const NetWhile*); /* Done with the design. The target returns !0 if there is some error in the code generation. */ virtual int end_design(const Design*); }; /* This class is used by the NetExpr class to help with the scanning of expressions. */ struct expr_scan_t { virtual ~expr_scan_t(); virtual void expr_access_func(const NetEAccess*); virtual void expr_array_pattern(const NetEArrayPattern*); virtual void expr_const(const NetEConst*); virtual void expr_last(const NetELast*); virtual void expr_new(const NetENew*); virtual void expr_null(const NetENull*); virtual void expr_param(const NetEConstParam*); virtual void expr_property(const NetEProperty*); virtual void expr_rparam(const NetECRealParam*); virtual void expr_creal(const NetECReal*); virtual void expr_concat(const NetEConcat*); virtual void expr_event(const NetEEvent*); virtual void expr_scope(const NetEScope*); virtual void expr_scopy(const NetEShallowCopy*); virtual void expr_select(const NetESelect*); virtual void expr_sfunc(const NetESFunc*); virtual void expr_signal(const NetESignal*); virtual void expr_ternary(const NetETernary*); virtual void expr_ufunc(const NetEUFunc*); virtual void expr_unary(const NetEUnary*); virtual void expr_binary(const NetEBinary*); virtual void expr_netenum(const NetENetenum*); }; /* This function takes a fully qualified Verilog name (which may have, for example, dots in it) and produces a mangled version that can be used by most any language. */ extern std::string mangle(const std::string&str); /* This function takes a string and produces an escaped version that can be used inside a string constant for a C++ compiler. */ extern std::string stresc(const std::string&str); #endif /* IVL_target_H */ iverilog-12_0/tgt-blif/000077500000000000000000000000001435245347300150575ustar00rootroot00000000000000iverilog-12_0/tgt-blif/Makefile.in000066400000000000000000000054701435245347300171320ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ CXX = @CXX@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ O = blif.o constants.o logic_gate.o lpm.o lpm_add.o lpm_cmp_eq.o lpm_cmp_gt.o \ lpm_ff.o lpm_mux.o lpm_part_vp.o lpm_re_logic.o lpm_shift.o lpm_sign_ext.o \ nex_data.o all: dep blif.tgt check: all clean: rm -rf *.o dep blif.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.cc) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-blif/$@ dep: mkdir dep %.o: %.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif blif.tgt: $O $(TGTDEPLIBS) $(CXX) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./blif.tgt \ $(srcdir)/blif.conf \ $(srcdir)/blif-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./blif.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/blif.tgt" $(INSTALL_DATA) $(srcdir)/blif.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/blif.conf" $(INSTALL_DATA) $(srcdir)/blif-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/blif-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/blif.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/blif.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/blif-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-blif/README-BLIF.txt000066400000000000000000000026221435245347300172710ustar00rootroot00000000000000 BLIF TARGET ----------- The BLIF code generator supports emitting the design to a blif format file as accepted by: ABC: A System for Sequential Synthesis and Verification This package contains tools sometimes used by ASIC designers. This blif target emits .blif file that the ABC system can read int via the "read_blif" command. USAGE ----- This code generator is intended to process structural Verilog source code. To convert a design to blif, use this command: iverilog -tblif -o.blif ... The source files can be Verilog, SystemVerilog, VHDL, whatever Icarus Verilog supports, so long as it elaborates down to the limited subset that the code generator supports. In other words, the files must be structural. The root module of the elaborated design becomes the model is generated. That module may instantiate sub-modules and so on down the design, completing the design. The output model is flattened, so it doesn't invoke any subcircuits. Bit vectors are exploded out at the model ports and internally. This is necessary since blif in particular and ABC in general processes bits, not vectors. LIMITATIONS ----------- Currently, only explicit logic gates and continuous assignments are supported. The design must contain only one root module. The name of that root module becomes the name of the blif model in the ".model" record. iverilog-12_0/tgt-blif/blif-s.conf000066400000000000000000000001401435245347300170750ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=blif.tgt iverilog-12_0/tgt-blif/blif.cc000066400000000000000000000155511435245347300163110ustar00rootroot00000000000000/* * Copyright (c) 2013-2020 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 "version_base.h" # include "version_tag.h" # include "priv.h" # include "ivl_target.h" # include "nex_data.h" # include # include # include # include using namespace std; /* * This is a BLIF target module. */ static const char*version_string = "Icarus Verilog BLIF Code Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (c) 2013-2020 Stephen Williams (steve@icarus.com)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; int blif_errors = 0; static void emit_blif(const char*blif_path, ivl_design_t des, ivl_scope_t model); static int process_scan_fun(ivl_process_t net, void* /*raw*/) { fprintf(stderr, "%s:%u: sorry: BLIF: Processes not supported yet.\n", ivl_process_file(net), ivl_process_lineno(net)); blif_errors += 1; return 0; } int target_design(ivl_design_t des) { const char*blif_path = ivl_design_flag(des, "-o"); vector root_modules; // Locate the root scope for the design. Note that the BLIF // format implies that there is a single root of the model. ivl_scope_t*roots; unsigned nroots; ivl_design_roots(des, &roots, &nroots); for (unsigned idx = 0 ; idx < nroots ; idx += 1) { if (ivl_scope_type(roots[idx]) == IVL_SCT_MODULE) { root_modules.push_back(roots[idx]); continue; } if (ivl_scope_type(roots[idx]) == IVL_SCT_PACKAGE) { fprintf(stderr, "Skipping package scope %s (%s:%u)\n", ivl_scope_name(roots[idx]), ivl_scope_file(roots[idx]), ivl_scope_lineno(roots[idx])); continue; } fprintf(stderr, "BLIF: Don't know how to handle root scope %s (%s:%u)\n", ivl_scope_name(roots[idx]), ivl_scope_file(roots[idx]), ivl_scope_lineno(roots[idx])); } if (root_modules.size() != 1) { fprintf(stderr, "BLIF: The BLIF code generator requires that there be only one root module scope. Found these root modules:\n"); for (size_t idx = 0 ; idx < root_modules.size() ; idx += 1) { fprintf(stderr, " %s (%s:%u)\n", ivl_scope_name(root_modules[idx]), ivl_scope_file(root_modules[idx]), ivl_scope_lineno(root_modules[idx])); } return 1; } // Detect processes and dispatch them. ivl_design_process(des, &process_scan_fun, 0); // Emit to the destination file. assert(blif_path); emit_blif(blif_path, des, root_modules[0]); return blif_errors; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } /* * Print all the bits of a signal. This is for the .input or .output * lines of a .model. All the bits need to be exploded, so print each * bit of a vector as its own name. */ static void print_signal_bits(FILE*fd, ivl_signal_t sig) { ivl_nexus_t nex = ivl_signal_nex(sig, 0); blif_nex_data_t* ned = blif_nex_data_t::get_nex_data(nex); ned->set_name(sig); for (unsigned idx = 0 ; idx < ned->get_width() ; idx += 1) { fprintf(fd, " %s%s", ned->get_name(), ned->get_name_index(idx)); } } static void emit_scope(FILE*fd, ivl_scope_t scope) { for (unsigned idx = 0 ; idx < ivl_scope_logs(scope) ; idx += 1) { ivl_net_logic_t net = ivl_scope_log(scope, idx); assert(net); blif_errors += print_logic_gate(fd, net); } for (unsigned idx = 0 ; idx < ivl_scope_lpms(scope) ; idx += 1) { ivl_lpm_t net = ivl_scope_lpm(scope, idx); blif_errors += print_lpm(fd, net); } for (size_t idx = 0 ; idx < ivl_scope_childs(scope) ; idx += 1) { ivl_scope_t child = ivl_scope_child(scope, idx); emit_scope(fd, child); } } static void emit_blif(const char*blif_path, ivl_design_t des, ivl_scope_t model) { FILE*fd = fopen(blif_path, "wt"); if (fd == 0) { perror(blif_path); blif_errors += 1; return; } fprintf(fd, ".model %s\n", ivl_scope_basename(model)); // The root scope vector ports_in; vector ports_out; for (unsigned idx = 0 ; idx < ivl_scope_sigs(model) ; idx += 1) { ivl_signal_t prt = ivl_scope_sig(model, idx); ivl_signal_port_t dir = ivl_signal_port(prt); switch (dir) { case IVL_SIP_NONE: break; case IVL_SIP_INPUT: ports_in.push_back(prt); break; case IVL_SIP_OUTPUT: ports_out.push_back(prt); break; case IVL_SIP_INOUT: fprintf(stderr, "BLIF: error: " "Model port %s is bi-directional.\n", ivl_signal_basename(prt)); blif_errors += 1; ports_in.push_back(prt); ports_out.push_back(prt); break; } } if (ports_in.size() > 0) { fprintf(fd, ".inputs"); for (size_t idx = 0 ; idx < ports_in.size() ; idx += 1) { ivl_signal_t prt = ports_in[idx]; print_signal_bits(fd, prt); } fprintf(fd, "\n"); } if (ports_out.size() > 0) { fprintf(fd, ".outputs"); for (size_t idx = 0 ; idx < ports_out.size() ; idx += 1) { ivl_signal_t prt = ports_out[idx]; print_signal_bits(fd, prt); } fprintf(fd, "\n"); } emit_scope(fd, model); emit_constants(fd, des, model); fprintf(fd, ".end\n"); fclose(fd); } bool scope_is_in_model(ivl_scope_t model, ivl_scope_t scope) { while (scope) { if (scope==model) return true; scope = ivl_scope_parent(scope); } return false; } iverilog-12_0/tgt-blif/blif.conf000066400000000000000000000001401435245347300166350ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=blif.tgt iverilog-12_0/tgt-blif/constants.cc000066400000000000000000000036171435245347300174110ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include static void print_constant(FILE*fd, ivl_net_const_t net) { unsigned wid = ivl_const_width(net); const char*val = ivl_const_bits(net); ivl_nexus_t nex = ivl_const_nex(net); blif_nex_data_t*ned = blif_nex_data_t::get_nex_data(nex); for (unsigned idx = 0 ; idx < wid ; idx += 1) { switch (val[idx]) { case '1': fprintf(fd, ".names %s%s # const 1\n1\n", ned->get_name(), ned->get_name_index(idx)); break; case '0': fprintf(fd, ".names %s%s # const 0\n", ned->get_name(), ned->get_name_index(idx)); break; default: fprintf(fd, ".names %s%s # const %c\n", ned->get_name(), ned->get_name_index(idx), val[idx]); break; } } } void emit_constants(FILE*fd, ivl_design_t des, ivl_scope_t model) { for (unsigned idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { ivl_net_const_t net = ivl_design_const(des, idx); if (! scope_is_in_model(model, ivl_const_scope(net))) continue; print_constant(fd, net); } } iverilog-12_0/tgt-blif/cppcheck.sup000066400000000000000000000002731435245347300173720ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:blif.cc:66 // target_query() unusedFunction:blif.cc:98 iverilog-12_0/tgt-blif/logic_gate.cc000066400000000000000000000064411435245347300174700ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include static int do_print_logic_gate(FILE*fd, ivl_net_logic_t net, unsigned bit); int print_logic_gate(FILE*fd, ivl_net_logic_t net) { int rc = 0; for (unsigned idx = 0 ; idx < ivl_logic_width(net) ; idx += 1) { rc += do_print_logic_gate(fd, net, idx); if (rc != 0) break; } return rc; } static int do_print_logic_gate(FILE*fd, ivl_net_logic_t net, unsigned bit) { int rc = 0; ivl_nexus_t nex_out = ivl_logic_pin(net,0); blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out); assert(ned_out->get_width() > bit); fprintf(fd, ".names"); for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { ivl_nexus_t nex = ivl_logic_pin(net,idx); blif_nex_data_t*ned = blif_nex_data_t::get_nex_data(nex); fprintf(fd, " %s%s", ned->get_name(), ned->get_name_index(bit)); } fprintf(fd, " %s%s", ned_out->get_name(), ned_out->get_name_index(bit)); fprintf(fd, "\n"); switch (ivl_logic_type(net)) { case IVL_LO_AND: for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) fprintf(fd, "1"); fprintf(fd, " 1\n"); break; case IVL_LO_OR: assert(ivl_logic_pins(net)==3); fprintf(fd, "1- 1\n"); fprintf(fd, "-1 1\n"); break; case IVL_LO_XOR: assert(ivl_logic_pins(net)==3); fprintf(fd, "10 1\n"); fprintf(fd, "01 1\n"); break; case IVL_LO_NAND: assert(ivl_logic_pins(net)==3); fprintf(fd, "0- 1\n"); fprintf(fd, "-0 1\n"); break; case IVL_LO_NOR: for (unsigned idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) fprintf(fd, "0"); fprintf(fd, " 1\n"); break; case IVL_LO_XNOR: assert(ivl_logic_pins(net)==3); fprintf(fd, "00 1\n"); fprintf(fd, "11 1\n"); break; case IVL_LO_BUF: assert(ivl_logic_pins(net)==2); fprintf(fd, "1 1\n"); break; case IVL_LO_NOT: assert(ivl_logic_pins(net)==2); fprintf(fd, "0 1\n"); break; case IVL_LO_PULLDOWN: assert(ivl_logic_pins(net)==1); fprintf(fd, "0\n"); break; case IVL_LO_PULLUP: assert(ivl_logic_pins(net)==1); fprintf(fd, "1\n"); break; case IVL_LO_BUFZ: assert(ivl_logic_pins(net)==2); fprintf(fd, "1 1\n"); break; default: fprintf(fd, "# ERROR: Logic type %d not handled\n", ivl_logic_type(net)); rc += 1; break; } return rc; } iverilog-12_0/tgt-blif/lpm.cc000066400000000000000000000071261435245347300161640ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include /* * Implement IVL_LPM_CONCAT devices by creating a .names buffer for * each bit of the output. Connect the output bit to the input bit. So * for example: * Q = {A, B, C} * becomes: * .names C Q[0] * 1 1 * .names B Q[1] * 1 1 * .names A Q[2] * 1 1 * (In this example, A, B, and C are 1 bit.) */ static int print_concat(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_CONCAT: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t nex_q = ivl_lpm_q(net); blif_nex_data_t*ned_q = blif_nex_data_t::get_nex_data(nex_q); ivl_nexus_t nex_d = ivl_lpm_data(net,0); blif_nex_data_t*ned_d = blif_nex_data_t::get_nex_data(nex_d); unsigned didx = 0; unsigned dpos = 0; for (unsigned wid = 0 ; wid < ivl_lpm_width(net) ; wid += 1) { if (dpos >= ned_d->get_width()) { didx += 1; dpos = 0; nex_d = ivl_lpm_data(net,didx); ned_d = blif_nex_data_t::get_nex_data(nex_d); } fprintf(fd, ".names %s%s %s%s\n1 1\n", ned_d->get_name(), ned_d->get_name_index(dpos), ned_q->get_name(), ned_q->get_name_index(wid)); dpos += 1; } return 0; } int print_lpm(FILE*fd, ivl_lpm_t net) { int rc = 0; ivl_lpm_type_t type = ivl_lpm_type(net); switch (type) { case IVL_LPM_ADD: rc += print_lpm_add(fd, net); break; case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EEQ: rc += print_lpm_cmp_eq(fd, net); break; case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: rc += print_lpm_cmp_gt(fd, net); break; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: rc += print_concat(fd, net); break; case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: rc += print_lpm_cmp_ne(fd, net); break; case IVL_LPM_FF: rc += print_lpm_ff(fd, net); break; case IVL_LPM_MUX: rc += print_lpm_mux(fd, net); break; case IVL_LPM_PART_VP: rc += print_lpm_part_vp(fd, net); break; case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: rc += print_lpm_re_logic(fd, net); break; case IVL_LPM_SUB: rc += print_lpm_sub(fd, net); break; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: rc += print_lpm_shift(fd, net, type == IVL_LPM_SHIFTL); break; case IVL_LPM_SIGN_EXT: rc += print_lpm_sign_ext(fd, net); break; default: fprintf(fd, "# XXXX ivl_lpm_type(net) --> %d\n", ivl_lpm_type(net)); fprintf(stderr, "%s:%u: sorry: ivl_lpm_type(net)==%d not implemented.\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_type(net)); rc += 1; break; } return rc; } iverilog-12_0/tgt-blif/lpm_add.cc000066400000000000000000000130741435245347300167730ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include /* * assign Q = A ^ B ^ Cin; * assign Cout = A&B | A&Cin | B&Cin; */ int print_lpm_add(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_ADD: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(ivl_lpm_width(net) == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); // Q[0] = A[0] ^ B[0] fprintf(fd, ".names %s%s %s%s %s%s\n" "10 1\n" "01 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); // Special case: If this is a 1-bit adder, then all we need is // the XOR above. We're done. if (ivl_lpm_width(net) == 1) return 0; // Cout[0] = A[0] & B[0] fprintf(fd, ".names %s%s %s%s %s%s/cout\n" "11 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); for (unsigned idx = 1 ; idx < ivl_lpm_width(net) ; idx += 1) { char cin[128]; snprintf(cin, sizeof cin, "%s%s/cout", q_ned->get_name(), q_ned->get_name_index(idx-1)); // Q[idx] = A[idx] ^ B[idx] ^ cin fprintf(fd, ".names %s%s %s%s %s %s%s\n" "001 1\n" "010 1\n" "100 1\n" "111 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), cin, q_ned->get_name(), q_ned->get_name_index(idx)); if ((idx+1) == ivl_lpm_width(net)) continue; // Cout[idx] = A[idx]&B[idx] | A[idx]&Cin | B[idx]&Cin fprintf(fd, ".names %s%s %s%s %s %s%s/cout\n" "011 1\n" "101 1\n" "11- 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), cin, q_ned->get_name(), q_ned->get_name_index(idx)); } return 0; } /* * Cin[0] = 1; * Cin[n: n!=0] = Cout[n-1] * assign Q[n] = A[n] ^ (~B[n]) ^ Cin[n]; * assign Cout[n] = A[n]&~B[n] | A[n]&Cin[n] | (~B[n])&Cin[n]; */ int print_lpm_sub(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_SUB: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(ivl_lpm_width(net) == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); // Q[0] = A[0] ^ ~B[0] ^ 1 fprintf(fd, ".names %s%s %s%s %s%s\n" "01 1\n" "10 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); if (ivl_lpm_width(net) == 1) return 0; // Cout[0] = A[0] & ~B[0] | A[0]&1 | ~B[0]&1 // = A[0] & ~B[0] | A[0] | ~B[0] // = A[0] | ~B[0] fprintf(fd, ".names %s%s %s%s %s%s/cout\n" "1- 1\n" "-0 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); for (unsigned idx = 1 ; idx < ivl_lpm_width(net) ; idx += 1) { char cin[128]; snprintf(cin, sizeof cin, "%s%s/cout", q_ned->get_name(), q_ned->get_name_index(idx-1)); // Q[idx] = A[idx] ^ ~B[idx] ^ cin fprintf(fd, ".names %s%s %s%s %s %s%s\n" "011 1\n" "000 1\n" "110 1\n" "101 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), cin, q_ned->get_name(), q_ned->get_name_index(idx)); if ((idx+1) == ivl_lpm_width(net)) continue; // Cout[idx] = A[idx]&~B[idx] | A[idx]&Cin | ~B[idx]&Cin fprintf(fd, ".names %s%s %s%s %s %s%s/cout\n" "001 1\n" "111 1\n" "10- 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), cin, q_ned->get_name(), q_ned->get_name_index(idx)); } return 0; } iverilog-12_0/tgt-blif/lpm_cmp_eq.cc000066400000000000000000000103371435245347300175060ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include /* * Implement IVL_LPM_CMP_EQ devices */ int print_lpm_cmp_eq(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_CMP_EQ: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(1 == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); if (ivl_lpm_width(net) == 1) { fprintf(fd, ".names %s%s %s%s %s%s\n" "11 1\n" "00 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); return 0; } for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s %s/%u\n" "11 1\n" "00 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), q_ned->get_name(), idx); } fprintf(fd, ".names"); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) fprintf(fd, " %s/%u", q_ned->get_name(), idx); fprintf(fd, " %s\n", q_ned->get_name()); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) fputc('1', fd); fprintf(fd, " 1\n"); return 0; } /* * Implement IVL_LPM_CMP_NE devices */ int print_lpm_cmp_ne(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_CMP_NE: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(1 == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); if (ivl_lpm_width(net) == 1) { fprintf(fd, ".names %s%s %s%s %s%s\n" "10 1\n" "01 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); return 0; } for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s %s/%u\n" "10 1\n" "01 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), q_ned->get_name(), idx); } fprintf(fd, ".names"); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) fprintf(fd, " %s/%u", q_ned->get_name(), idx); fprintf(fd, " %s\n", q_ned->get_name()); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { for (unsigned jdx = 0 ; jdx < ivl_lpm_width(net) ; jdx += 1) { if (idx==jdx) fputc('1', fd); else fputc('-', fd); } fprintf(fd, " 1\n"); } return 0; } iverilog-12_0/tgt-blif/lpm_cmp_gt.cc000066400000000000000000000125331435245347300175130ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include static int print_lpm_cmp_gt_s(FILE*fd, ivl_lpm_t net) { ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(1 == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); // This is true if the operator is GE instead of just GT. bool ge_flag = ivl_lpm_type(net)==IVL_LPM_CMP_GE; // Special case: if the input vector is a single bit, then the // operation is trivial. Note that since this is signed, the // "1" bit represents -1 and is <0. if (ivl_lpm_width(net) == 1) { fprintf(fd, ".names %s%s %s%s %s%s\n" "01 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); if (ge_flag) fprintf(fd, "00 1\n11 1\n"); return 0; } fprintf(stderr, "%s:%u: sorry: blif: Signed magnitude compare not implemented yet\n", ivl_lpm_file(net), ivl_lpm_lineno(net)); return 1; } static int print_lpm_cmp_gt_u(FILE*fd, ivl_lpm_t net) { ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t a_nex = ivl_lpm_data(net,0); ivl_nexus_t b_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*a_ned = blif_nex_data_t::get_nex_data(a_nex); blif_nex_data_t*b_ned = blif_nex_data_t::get_nex_data(b_nex); assert(1 == q_ned->get_width()); assert(ivl_lpm_width(net) == a_ned->get_width()); assert(ivl_lpm_width(net) == b_ned->get_width()); // This is true if the operator is GE instead of just GT. bool ge_flag = ivl_lpm_type(net)==IVL_LPM_CMP_GE; // Special case: if the input vector is a single bit, then the // operation is trivial. if (ivl_lpm_width(net) == 1) { fprintf(fd, ".names %s%s %s%s %s%s\n" "10 1\n", a_ned->get_name(), a_ned->get_name_index(0), b_ned->get_name(), b_ned->get_name_index(0), q_ned->get_name(), q_ned->get_name_index(0)); if (ge_flag) fprintf(fd, "00 1\n11 1\n"); return 0; } // Calculate GT and EQ for each bit. for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s %s%s/G%u\n" "10 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), q_ned->get_name(), q_ned->get_name_index(0), idx); } for (unsigned idx = ge_flag?0 : 1 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s %s%s/E%u\n" "11 1\n" "00 1\n", a_ned->get_name(), a_ned->get_name_index(idx), b_ned->get_name(), b_ned->get_name_index(idx), q_ned->get_name(), q_ned->get_name_index(0), idx); } // Generate a wide function to blend the per-bit comparisons. fprintf(fd, ".names"); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, " %s%s/G%u", q_ned->get_name(), q_ned->get_name_index(0), idx); } for (unsigned idx = ge_flag?0:1 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, " %s%s/E%u", q_ned->get_name(), q_ned->get_name_index(0), idx); } fprintf(fd, " %s%s\n", q_ned->get_name(), q_ned->get_name_index(0)); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { for (unsigned jdx = 0 ; jdx < ivl_lpm_width(net) ; jdx += 1) { if (jdx != idx) fprintf(fd, "-"); else fprintf(fd, "1"); } for (unsigned jdx = ge_flag?0:1 ; jdx < ivl_lpm_width(net) ; jdx += 1) { if (jdx <= idx) fprintf(fd, "-"); else fprintf(fd, "1"); } fprintf(fd, " 1\n"); } if (ge_flag) { for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) fputc('-', fd); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) fputc('1', fd); fprintf(fd, " 1\n"); } return 0; } int print_lpm_cmp_gt(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: LPM_LPM_CMP_GT: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); if (ivl_lpm_signed(net)) return print_lpm_cmp_gt_s(fd, net); else return print_lpm_cmp_gt_u(fd, net); } iverilog-12_0/tgt-blif/lpm_ff.cc000066400000000000000000000063301435245347300166330ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include using namespace std; int print_lpm_ff(FILE*fd, ivl_lpm_t net) { int errors = 0; ivl_nexus_t nex_q = ivl_lpm_q(net); blif_nex_data_t*ned_q = blif_nex_data_t::get_nex_data(nex_q); ivl_nexus_t nex_d = ivl_lpm_data(net,0); blif_nex_data_t*ned_d = blif_nex_data_t::get_nex_data(nex_d); ivl_nexus_t nex_c = ivl_lpm_clk(net); blif_nex_data_t*ned_c = blif_nex_data_t::get_nex_data(nex_c); ivl_nexus_t nex_ce = ivl_lpm_enable(net); blif_nex_data_t*ned_ce = nex_ce? blif_nex_data_t::get_nex_data(nex_ce) : 0; if (ivl_lpm_async_clr(net)) { errors += 1; fprintf(stderr, "%s:%u: sorry: blif: Asynchronous clear not implemented yet\n", ivl_lpm_file(net), ivl_lpm_lineno(net)); } if (ivl_lpm_async_set(net)) { errors += 1; fprintf(stderr, "%s:%u: sorry: blif: Asynchronous set not implemented yet\n", ivl_lpm_file(net), ivl_lpm_lineno(net)); } fprintf(fd, "# IVL_LPM_FF: width=%u, Q=%s, D=%s, C=%s, CE=%s\n", ivl_lpm_width(net), ned_q->get_name(), ned_d->get_name(), ned_c->get_name(), ned_ce? ned_ce->get_name() : "N/A"); if (ned_ce) { // If there is a clock-enable, rewrite this in a form // that blif can accept. Transform this: // // always @(posedge C) if (CE) Q <= D; // // to this: // // always @(posedge C) Q <= CE? D : Q; // // In ASIC-land, this is probably OK. for (unsigned wid = 0 ; wid < ivl_lpm_width(net) ; wid += 1) { fprintf(fd, ".names %s%s %s%s %s%s %s%s/EN\n" "0-1 1\n" "11- 1\n", ned_ce->get_name(), ned_ce->get_name_index(0), ned_d ->get_name(), ned_d ->get_name_index(wid), ned_q ->get_name(), ned_q ->get_name_index(wid), ned_d ->get_name(), ned_d ->get_name_index(wid)); fprintf(fd, ".latch %s%s/EN %s%s re %s%s 3\n", ned_d->get_name(), ned_d->get_name_index(wid), ned_q->get_name(), ned_q->get_name_index(wid), ned_c->get_name(), ned_c->get_name_index(0)); } } else { for (unsigned wid = 0 ; wid < ivl_lpm_width(net) ; wid += 1) { fprintf(fd, ".latch %s%s %s%s re %s%s 3\n", ned_d->get_name(), ned_d->get_name_index(wid), ned_q->get_name(), ned_q->get_name_index(wid), ned_c->get_name(), ned_c->get_name_index(0)); } } return errors; } iverilog-12_0/tgt-blif/lpm_mux.cc000066400000000000000000000104541435245347300170530ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "priv.h" # include "nex_data.h" # include # include using namespace std; /* * This handles the special case that the select port to the MUX is a * single bit. In other words, a binary mux. This may have an * arbitrary data width, but it selects from input A or input B. */ static int print_lpm_mux_s1(FILE*fd, ivl_lpm_t net) { ivl_nexus_t nex_out = ivl_lpm_q(net); blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out); ivl_nexus_t nex_sel = ivl_lpm_select(net); blif_nex_data_t*ned_sel = blif_nex_data_t::get_nex_data(nex_sel); ivl_nexus_t nex_d0 = ivl_lpm_data(net,0); blif_nex_data_t*ned_d0 = blif_nex_data_t::get_nex_data(nex_d0); ivl_nexus_t nex_d1 = ivl_lpm_data(net,1); blif_nex_data_t*ned_d1 = blif_nex_data_t::get_nex_data(nex_d1); fprintf(fd, "# IVL_LPM_MUX ivl_lpm_width(net)=%u, Q=%s, D0=%s, D1=%s\n", ivl_lpm_width(net), ned_out->get_name(), ned_d0->get_name(), ned_d1->get_name()); assert(ivl_lpm_width(net) == ned_out->get_width()); assert(ivl_lpm_width(net) == ned_d0->get_width()); assert(ivl_lpm_width(net) == ned_d1->get_width()); // Only support single-bit select assert(ned_sel->get_width() == 1); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s %s%s %s%s\n" "01- 1\n" "1-1 1\n", ned_sel->get_name(), ned_sel->get_name_index(0), ned_d0->get_name(), ned_d0->get_name_index(idx), ned_d1->get_name(), ned_d1->get_name_index(idx), ned_out->get_name(), ned_out->get_name_index(idx)); } return 0; } static int print_lpm_mux_sN(FILE*fd, ivl_lpm_t net) { ivl_nexus_t nex_out = ivl_lpm_q(net); blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out); ivl_nexus_t nex_sel = ivl_lpm_select(net); blif_nex_data_t*ned_sel = blif_nex_data_t::get_nex_data(nex_sel); vector ned_d (ivl_lpm_size(net)); for (size_t idx = 0 ; idx < ned_d.size() ; idx += 1) { ivl_nexus_t tmp = ivl_lpm_data(net,idx); ned_d[idx] = blif_nex_data_t::get_nex_data(tmp); } for (unsigned wid = 0 ; wid < ivl_lpm_width(net) ; wid += 1) { // First, print the names record with all the ports... fprintf(fd, ".names"); for (size_t idx = 0 ; idx < ned_sel->get_width() ; idx += 1) { fprintf(fd, " %s%s", ned_sel->get_name(), ned_sel->get_name_index(idx)); } for (size_t idx = 0 ; idx < ned_d.size() ; idx += 1) { fprintf(fd, " %s%s", ned_d[idx]->get_name(), ned_d[idx]->get_name_index(wid)); } fprintf(fd, " %s%s\n", ned_out->get_name(), ned_out->get_name_index(wid)); // Print the logic table. We need one line for each // select address. The select pins must exactly match // the select address. The output depends only on the // select D input. for (size_t didx = 0 ; didx < ned_d.size() ; didx += 1) { for (size_t idx = 0 ; idx < ned_sel->get_width() ; idx += 1) { if (didx & (1< static int print_part_vp_mux(FILE*fd, ivl_lpm_t net); /* * This implements the IVL_LPM_PART_VP, which is the vector-to-part * part select. Implement this as a .names buffer. */ int print_lpm_part_vp(FILE*fd, ivl_lpm_t net) { int rc = 0; // If this is a non-constant bit select, then handle it // elsewhere. if (ivl_lpm_data(net,1) != 0) return print_part_vp_mux(fd, net); ivl_nexus_t nex_out = ivl_lpm_q(net); blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out); assert(ivl_lpm_width(net) == ned_out->get_width()); // Only handle constant part select base. assert(ivl_lpm_data(net,1) == 0); unsigned bit_sel = ivl_lpm_base(net); ivl_nexus_t nex_in = ivl_lpm_data(net,0); blif_nex_data_t*ned_in = blif_nex_data_t::get_nex_data(nex_in); assert(bit_sel < ned_in->get_width()); for (unsigned idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { fprintf(fd, ".names %s%s %s%s # %s:%u\n1 1\n", ned_in->get_name(), ned_in->get_name_index(bit_sel+idx), ned_out->get_name(), ned_out->get_name_index(idx), ivl_lpm_file(net), ivl_lpm_lineno(net)); } return rc; } static int print_part_vp_mux(FILE*fd, ivl_lpm_t net) { // Only handle constant part select base. assert(ivl_lpm_data(net,1) != 0); ivl_nexus_t nex_out = ivl_lpm_q(net); blif_nex_data_t*ned_out = blif_nex_data_t::get_nex_data(nex_out); // Only handle bit selects. assert(ned_out->get_width() == 1); ivl_nexus_t nex_in = ivl_lpm_data(net,0); blif_nex_data_t*ned_in = blif_nex_data_t::get_nex_data(nex_in); ivl_nexus_t nex_sel = ivl_lpm_data(net,1); blif_nex_data_t*ned_sel = blif_nex_data_t::get_nex_data(nex_sel); unsigned sel_wid = ned_sel->get_width(); unsigned in_wid = ned_in->get_width(); assert((1U<get_name(), ned_sel->get_name_index(idx)); } for (unsigned idx = 0 ; idx < in_wid ; idx += 1) { fprintf(fd, " %s%s", ned_in->get_name(), ned_in->get_name_index(idx)); } fprintf(fd, " %s%s\n", ned_out->get_name(), ned_out->get_name_index(0)); for (unsigned idx = 0 ; idx < (1U< static bool re_xor(unsigned val) { bool flag = false; for (size_t idx = 0 ; idx < 8*sizeof(val) ; idx += 1) { if (val&1) flag ^= true; val >>= 1; } return flag; } int print_lpm_re_logic(FILE*fd, ivl_lpm_t net) { ivl_nexus_t nex_q = ivl_lpm_q(net); blif_nex_data_t*ned_q = blif_nex_data_t::get_nex_data(nex_q); ivl_nexus_t nex_d = ivl_lpm_data(net,0); blif_nex_data_t*ned_d = blif_nex_data_t::get_nex_data(nex_d); assert(ned_q->get_width() == 1); fprintf(fd, ".names"); for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) { fprintf(fd, " %s%s", ned_d->get_name(), ned_d->get_name_index(idx)); } fprintf(fd, " %s%s\n", ned_q->get_name(), ned_q->get_name_index(0)); switch (ivl_lpm_type(net)) { case IVL_LPM_RE_AND: for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) fputc('1', fd); fprintf(fd, " 1\n"); break; case IVL_LPM_RE_OR: for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) { for (size_t wid = 0 ; wid < ned_d->get_width() ; wid += 1) { if (wid==idx) fputc('1', fd); else fputc('-', fd); } fprintf(fd, " 1\n"); } break; case IVL_LPM_RE_XOR: assert(ned_d->get_width() < 8*sizeof(unsigned)); for (unsigned val = 0; val < (1U<get_width()); val += 1) { if (! re_xor(val)) continue; for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) { if (val & (1<get_width() ; idx += 1) { for (size_t wid = 0 ; wid < ned_d->get_width() ; wid += 1) { if (wid==idx) fputc('0', fd); else fputc('-', fd); } fprintf(fd, " 1\n"); } break; case IVL_LPM_RE_NOR: for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) fputc('0', fd); fprintf(fd, " 1\n"); break; case IVL_LPM_RE_XNOR: assert(ned_d->get_width() < 8*sizeof(unsigned)); for (unsigned val = 0; val < (1U<get_width()); val += 1) { if (re_xor(val)) continue; for (size_t idx = 0 ; idx < ned_d->get_width() ; idx += 1) { if (val & (1< /* * Implement IVL_LPM_SHIFT devices (via standard layered barrel shifter design) */ int print_lpm_shift(FILE*fd, ivl_lpm_t net, bool left) { fprintf(fd, "# %s:%u: IVL_LPM_SHIFT%c: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), left ? 'L' : 'R', ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t d_nex = ivl_lpm_data(net,0); ivl_nexus_t s_nex = ivl_lpm_data(net,1); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*d_ned = blif_nex_data_t::get_nex_data(d_nex); blif_nex_data_t*s_ned = blif_nex_data_t::get_nex_data(s_nex); unsigned dataw = ivl_lpm_width(net); size_t shiftw = s_ned->get_width(); bool signed_ = ivl_lpm_signed(net); assert(dataw == q_ned->get_width()); assert(dataw == d_ned->get_width()); // TODO: output width can be larger than data // TODO: optimizations: // * too large shift widths (more than data size) // * shift width of 1 // * data width of 1 for (size_t lvl = 0 ; lvl < shiftw ; lvl += 1) { for (unsigned idx = 0 ; idx < dataw ; idx += 1) { unsigned idx_2 = left ? idx - (1 << lvl) : idx + (1 << lvl); bool borrow = idx_2 >= dataw; bool signed_borrow = borrow && !left && signed_; // First arg (shift) fprintf(fd, ".names %s%s", s_ned->get_name(), s_ned->get_name_index(lvl)); // Multiplexed bits if (!borrow) { if (lvl == 0) { fprintf(fd, " %s%s %s%s", d_ned->get_name(), d_ned->get_name_index(idx), d_ned->get_name(), d_ned->get_name_index(idx_2)); } else { fprintf(fd, " %s/%zu/%u %s/%zu/%u", q_ned->get_name(), lvl - 1, idx, q_ned->get_name(), lvl - 1, idx_2); } } else if (signed_borrow) { if (lvl == 0) { fprintf(fd, " %s%s %s%s", d_ned->get_name(), d_ned->get_name_index(idx), d_ned->get_name(), d_ned->get_name_index(dataw - 1)); } else { fprintf(fd, " %s/%zu/%u %s%s", q_ned->get_name(), lvl - 1, idx, d_ned->get_name(), d_ned->get_name_index(dataw - 1)); } } else { if (lvl == 0) { fprintf(fd, " %s%s", d_ned->get_name(), d_ned->get_name_index(idx)); } else { fprintf(fd, " %s/%zu/%u", q_ned->get_name(), lvl - 1, idx); } } // Output if (lvl == shiftw - 1) { fprintf(fd, " %s%s\n", q_ned->get_name(), q_ned->get_name_index(idx)); } else { fprintf(fd, " %s/%zu/%u\n", q_ned->get_name(), lvl, idx); } if (!borrow || signed_borrow) fputs("1-1 1\n" "01- 1\n", fd); else fputs("01 1\n", fd); } } return 0; } iverilog-12_0/tgt-blif/lpm_sign_ext.cc000066400000000000000000000036531435245347300200650ustar00rootroot00000000000000/* * Copyright (c) 2016 Yury Gribov (tetra2005@gmail.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 "priv.h" # include "nex_data.h" # include /* * Implement IVL_LPM_SIGN_EXT devices */ int print_lpm_sign_ext(FILE*fd, ivl_lpm_t net) { fprintf(fd, "# %s:%u: IVL_LPM_SIGN_EXT: width=%u\n", ivl_lpm_file(net), ivl_lpm_lineno(net), ivl_lpm_width(net)); ivl_nexus_t q_nex = ivl_lpm_q(net); ivl_nexus_t d_nex = ivl_lpm_data(net,0); blif_nex_data_t*q_ned = blif_nex_data_t::get_nex_data(q_nex); blif_nex_data_t*d_ned = blif_nex_data_t::get_nex_data(d_nex); unsigned inw = d_ned->get_width(); unsigned outw = ivl_lpm_width(net); //printf("Shift: LPM width = %u, output width = %zd, input width = %u\n", outw, q_ned->get_width(), inw); assert(outw == q_ned->get_width()); assert(inw < outw); for (unsigned idx = 0 ; idx < outw ; idx += 1) { unsigned idx_in = idx < inw ? idx : inw - 1; fprintf(fd, ".names %s%s %s%s\n", d_ned->get_name(), d_ned->get_name_index(idx_in), q_ned->get_name(), q_ned->get_name_index(idx)); fprintf(fd, "1 1\n"); } return 0; } iverilog-12_0/tgt-blif/nex_data.cc000066400000000000000000000074161435245347300171610ustar00rootroot00000000000000/* * Copyright (c) 2013 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 "nex_data.h" # include # include # include # include # include using namespace std; inline blif_nex_data_t::blif_nex_data_t(ivl_nexus_t nex) : nex_(nex), name_(0) { } blif_nex_data_t::~blif_nex_data_t() { if (name_) free(name_); for (size_t idx = 0 ; idx < name_index_.size() ; idx += 1) if (name_index_[idx]) free(name_index_[idx]); } blif_nex_data_t* blif_nex_data_t::get_nex_data(ivl_nexus_t nex) { void*tmp = ivl_nexus_get_private(nex); if (tmp != 0) return reinterpret_cast (tmp); blif_nex_data_t*data = new blif_nex_data_t(nex); ivl_nexus_set_private(nex, data); return data; } void blif_nex_data_t::make_name_from_sig_(ivl_signal_t sig) { assert(name_ == 0); string tmp = ivl_signal_basename(sig); for (ivl_scope_t sscope = ivl_signal_scope(sig) ; ivl_scope_parent(sscope) ; sscope = ivl_scope_parent(sscope)) { tmp = ivl_scope_basename(sscope) + string("/") + tmp; } name_ = strdup(tmp.c_str()); assert(name_index_.size()==0); if (ivl_signal_width(sig) > 1) { name_index_.resize(ivl_signal_width(sig)); assert(ivl_signal_packed_dimensions(sig) == 1); int msb = ivl_signal_packed_msb(sig,0); int lsb = ivl_signal_packed_lsb(sig,0); int dir = (lsb <= msb)? 1 : -1; int val = lsb; for (unsigned idx = 0 ; idx < ivl_signal_width(sig) ; idx += 1) { char buf[64]; snprintf(buf, sizeof buf, "[%d]", val); name_index_[idx] = strdup(buf); val += dir; } } } /* * Given that there is not an explicit binding to a signal for naming, * search for a signal and use that signal to derive the name of this * nexus. */ void blif_nex_data_t::select_name_(void) { for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex_) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex_, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; make_name_from_sig_(sig); break; } assert(name_); } void blif_nex_data_t::set_name(ivl_signal_t sig) { assert(name_ == 0); assert(ivl_signal_nex(sig,0) == nex_); make_name_from_sig_(sig); } const char* blif_nex_data_t::get_name(void) { if (name_==0) select_name_(); return name_; } const char* blif_nex_data_t::get_name_index(unsigned bit) { if (name_==0) select_name_(); if (name_index_.size()==0) { assert(bit == 0); return ""; } assert(bit < name_index_.size()); assert(name_index_[bit]); return name_index_[bit]; } /* * Get the width from any signal that is attached to the nexus. */ size_t blif_nex_data_t::get_width(void) { if (name_==0) select_name_(); // Special case: If the nexus width is 1 bit, then there is no // need for index_name maps, so the name_index_ will be empty. if (name_index_.size()==0) return 1; return name_index_.size(); } iverilog-12_0/tgt-blif/nex_data.h000066400000000000000000000050731435245347300170200ustar00rootroot00000000000000#ifndef IVL_nex_data_H #define IVL_nex_data_H /* * Copyright (c) 2013-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 "ivl_target.h" # include # include /* * The ivl_target.h API allows for binding data to a nexus. This class * represents the data that we want to attach to a nexus. */ class blif_nex_data_t { private: // The constructors are private. Only the get_nex_data() // function can create these objects. explicit blif_nex_data_t(ivl_nexus_t nex); ~blif_nex_data_t(); public: // Return the blif_nex_data_t object that is associated with // the given nexus. If the nexus does not have a nex_data_t // object, then create it and bind it to the nexus. Thus, this // function will always return the same nex_data instance for // the same nexus. static blif_nex_data_t* get_nex_data(ivl_nexus_t nex); // In certain situations, we know a priori what we want the // nexus name to be. In those cases, the context can use this // method to set the name (by the signal from width the name // is derived). Note that this must be called before the name // is otherwise queried. void set_name(ivl_signal_t sig); // Get the symbolic name chosen for this nexus. const char*get_name(void); // Map a canonical bit index (0 : width-1) to the bit number // as understood by the signal. This is normally a null // mapping, but sometimes the signal name used for the mapping // has a non-canonical bit numbering. const char*get_name_index(unsigned bit); // Get the vector width for this nexus. size_t get_width(void); public: ivl_nexus_t nex_; char*name_; std::vector name_index_; private: void select_name_(void); void make_name_from_sig_(ivl_signal_t sig); }; #endif /* IVL_nex_data_H */ iverilog-12_0/tgt-blif/priv.h000066400000000000000000000044061435245347300162140ustar00rootroot00000000000000#ifndef IVL_priv_H #define IVL_priv_H /* * Copyright (c) 2013-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 "ivl_target.h" # include /* * Errors are counted here. When the blif processing is done, this * value is returned to ivl so that it can report error counts. */ extern int blif_errors; extern int print_logic_gate(FILE*fd, ivl_net_logic_t net); extern int print_lpm(FILE*fd, ivl_lpm_t net); extern int print_lpm_add(FILE*fd, ivl_lpm_t net); extern int print_lpm_ff(FILE*fd, ivl_lpm_t net); extern int print_lpm_sub(FILE*fd, ivl_lpm_t net); extern int print_lpm_cmp_eq(FILE*fd, ivl_lpm_t net); extern int print_lpm_cmp_gt(FILE*fd, ivl_lpm_t net); extern int print_lpm_cmp_ne(FILE*fd, ivl_lpm_t net); extern int print_lpm_mux(FILE*fd, ivl_lpm_t net); extern int print_lpm_part_vp(FILE*fd, ivl_lpm_t net); extern int print_lpm_re_logic(FILE*fd, ivl_lpm_t net); extern int print_lpm_shift(FILE*fd, ivl_lpm_t net, bool left); extern int print_lpm_sign_ext(FILE*fd, ivl_lpm_t net); /* * Emit all the constants for a model. This works by scanning the * design for all constants, testing that they are part of the model, * and writing them out as .names records. */ extern void emit_constants(FILE*fd, ivl_design_t des, ivl_scope_t model); /* * Return true if the passed scope is under the model scope, at any * depth. The scope may be an immediate child, or a child several * levels removed. */ extern bool scope_is_in_model(ivl_scope_t model, ivl_scope_t scope); #endif /* IVL_priv_H */ iverilog-12_0/tgt-fpga/000077500000000000000000000000001435245347300150605ustar00rootroot00000000000000iverilog-12_0/tgt-fpga/Makefile.in000066400000000000000000000072061435245347300171320ustar00rootroot00000000000000# # Copyright 2003 Stephen Williams (steve at 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 # Library 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 Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ mandir = @mandir@ datarootdir = @datarootdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ D = d-generic.o d-generic-edif.o d-lpm.o d-virtex.o d-virtex2.o O = edif.o fpga.o gates.o mangle.o tables.o generic.o xilinx.o $D all: dep fpga.tgt check: all clean: rm -rf *.o dep fpga.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-fpga/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif fpga.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) iverilog-fpga.ps: $(srcdir)/iverilog-fpga.man man -t $(srcdir)/iverilog-fpga.man > iverilog-fpga.ps iverilog-fpga.pdf: iverilog-fpga.ps ps2pdf iverilog-fpga.ps iverilog-fpga.pdf ifeq (@WIN32@,yes) INSTALL_DOC = installpdf installman INSTALL_DOCDIR = $(mandir)/man1 all: iverilog-fpga.pdf else INSTALL_DOC = installman INSTALL_DOCDIR = $(mandir)/man1 endif install: all installdirs installfiles F = ./fpga.tgt \ $(srcdir)/fpga.conf \ $(srcdir)/fpga-s.conf \ $(INSTALL_DOC) installman: $(srcdir)/iverilog-fpga.man installdirs $(INSTALL_DATA) $(srcdir)/iverilog-fpga.man "$(DESTDIR)$(mandir)/man1/iverilog-fpga$(suffix).1" installpdf: iverilog-fpga.pdf installdirs $(INSTALL_DATA) iverilog-fpga.pdf "$(DESTDIR)$(prefix)/iverilog-fpga$(suffix).pdf" installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./fpga.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga.tgt" $(INSTALL_DATA) $(srcdir)/fpga.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga.conf" $(INSTALL_DATA) $(srcdir)/fpga-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" "$(DESTDIR)$(INSTALL_DOCDIR)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga.tgt" rm -f "$(DESTDIR)$(prefix)/iverilog-fpga$(suffix).pdf" "$(DESTDIR)$(mandir)/man1/iverilog-fpga$(suffix).1" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga-s.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/fpga.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-fpga/cppcheck.sup000066400000000000000000000002161435245347300173700ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:fpga.c:104 iverilog-12_0/tgt-fpga/d-generic-edif.c000066400000000000000000000333241435245347300177730ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "device.h" # include "fpga_priv.h" # include # include # include # include "ivl_alloc.h" struct nexus_recall { struct nexus_recall*next; ivl_nexus_t nex; char* joined; }; static struct nexus_recall*net_list = 0; static unsigned edif_uref = 0; static void edif_set_nexus_joint(ivl_nexus_t nex, const char*joint) { size_t newlen; struct nexus_recall*rec; rec = (struct nexus_recall*)ivl_nexus_get_private(nex); if (rec == 0) { rec = malloc(sizeof(struct nexus_recall)); rec->nex = nex; rec->joined = malloc(8); rec->joined[0] = 0; rec->next = net_list; net_list = rec; ivl_nexus_set_private(nex, rec); } newlen = strlen(rec->joined) + strlen(joint) + 2; rec->joined = realloc(rec->joined, newlen); strcat(rec->joined, " "); strcat(rec->joined, joint); } static void show_root_ports_edif(ivl_scope_t root) { char jbuf[1024]; unsigned cnt = ivl_scope_sigs(root); unsigned idx; for (idx = 0 ; idx < cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); const char*use_name; const char*dir = 0; if (ivl_signal_attr(sig, "PAD") != 0) continue; switch (ivl_signal_port(sig)) { case IVL_SIP_NONE: continue; case IVL_SIP_INPUT: dir = "INPUT"; break; case IVL_SIP_OUTPUT: dir = "OUTPUT"; break; case IVL_SIP_INOUT: dir = "INOUT"; break; } use_name = ivl_signal_basename(sig); if (ivl_signal_pins(sig) == 1) { fprintf(xnf, " (port %s (direction %s))\n", use_name, dir); sprintf(jbuf, "(portRef %s)", use_name); edif_set_nexus_joint(ivl_signal_pin(sig, 0), jbuf); } else { unsigned pin; for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) { fprintf(xnf, " (port (rename %s_%u " "\"%s[%u]\") (direction %s))\n", use_name, pin, use_name, pin, dir); sprintf(jbuf, "(portRef %s_%u)", use_name, pin); edif_set_nexus_joint(ivl_signal_pin(sig, pin), jbuf); } } } } static void edif_show_header_generic(ivl_design_t des, const char*library) { ivl_scope_t root = ivl_design_root(des); /* write the primitive header */ fprintf(xnf, "(edif %s\n", ivl_scope_name(root)); fprintf(xnf, " (edifVersion 2 0 0)\n"); fprintf(xnf, " (edifLevel 0)\n"); fprintf(xnf, " (keywordMap (keywordLevel 0))\n"); fprintf(xnf, " (status\n"); fprintf(xnf, " (written\n"); fprintf(xnf, " (timeStamp 0 0 0 0 0 0)\n"); fprintf(xnf, " (author \"unknown\")\n"); fprintf(xnf, " (program \"Icarus Verilog/fpga.tgt\")))\n"); /* Write out the external references here? */ fputs(library, xnf); /* Write out the library header */ fprintf(xnf, " (library DESIGN\n"); fprintf(xnf, " (edifLevel 0)\n"); fprintf(xnf, " (technology (numberDefinition))\n"); /* The root module is a cell in the library. */ fprintf(xnf, " (cell %s\n", ivl_scope_name(root)); fprintf(xnf, " (cellType GENERIC)\n"); fprintf(xnf, " (view net\n"); fprintf(xnf, " (viewType NETLIST)\n"); fprintf(xnf, " (interface\n"); show_root_ports_edif(root); fprintf(xnf, " )\n"); /* end the (interface ) sexp */ fprintf(xnf, " (contents\n"); } static const char*external_library_text = " (external VIRTEX (edifLevel 0) (technology (numberDefinition))\n" " (cell AND2 (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port O (direction OUTPUT))\n" " (port I0 (direction INPUT))\n" " (port I1 (direction INPUT)))))\n" " (cell BUF (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port O (direction OUTPUT))\n" " (port I (direction INPUT)))))\n" " (cell FDCE (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port Q (direction OUTPUT))\n" " (port D (direction INPUT))\n" " (port C (direction INPUT))\n" " (port CE (direction INPUT))\n" " (port CLR (direction INPUT)))))\n" " (cell FDCPE (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port Q (direction OUTPUT))\n" " (port D (direction INPUT))\n" " (port C (direction INPUT))\n" " (port CE (direction INPUT))\n" " (port PRE (direction INPUT))\n" " (port CLR (direction INPUT)))))\n" " (cell GND (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface (port G (direction OUTPUT)))))\n" " (cell NOR2 (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port O (direction OUTPUT))\n" " (port I0 (direction INPUT))\n" " (port I1 (direction INPUT)))))\n" " (cell NOR3 (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface\n" " (port O (direction OUTPUT))\n" " (port I0 (direction INPUT))\n" " (port I1 (direction INPUT))\n" " (port I2 (direction INPUT)))))\n" " (cell VCC (cellType GENERIC)\n" " (view net\n" " (viewType NETLIST)\n" " (interface (port P (direction OUTPUT)))))\n" " )\n" ; static void edif_show_header(ivl_design_t des) { edif_show_header_generic(des, external_library_text); } static void edif_show_consts(ivl_design_t des) { unsigned idx; char jbuf[128]; for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { unsigned pin; ivl_net_const_t net = ivl_design_const(des, idx); const char*val = ivl_const_bits(net); for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) { ivl_nexus_t nex = ivl_const_pin(net, pin); const char*name; const char*port; edif_uref += 1; switch (val[pin]) { case '0': name = "GND"; port = "GROUND"; break; case '1': name = "VCC"; port = "VCC"; break; default: name = "???"; port = "?"; break; } fprintf(xnf, "(instance U%u " "(viewRef net" " (cellRef %s (libraryRef VIRTEX))))\n", edif_uref, name); sprintf(jbuf, "(portRef %s (instanceRef U%u))", port, edif_uref); edif_set_nexus_joint(nex, jbuf); } } } static void edif_show_footer(ivl_design_t des) { unsigned nref = 0; struct nexus_recall*cur; ivl_scope_t root = ivl_design_root(des); edif_show_consts(des); for (cur = net_list ; cur ; cur = cur->next) { fprintf(xnf, "(net (rename N%u \"%s\") (joined %s))\n", nref, ivl_nexus_name(cur->nex), cur->joined); nref += 1; } fprintf(xnf, " )\n"); /* end the (contents ) sexp */ fprintf(xnf, " )\n"); /* end the (view ) sexp */ fprintf(xnf, " )\n"); /* end the (cell ) sexp */ fprintf(xnf, " )\n"); /* end the (library ) sexp */ /* Make an instance of the defined object */ fprintf(xnf, " (design %s\n", ivl_scope_name(root)); fprintf(xnf, " (cellRef %s (libraryRef DESIGN))\n", ivl_scope_name(root)); if (part) fprintf(xnf, " (property PART (string \"%s\"))\n", part); fprintf(xnf, " )\n"); fprintf(xnf, ")\n"); /* end the (edif ) sexp */ } static void edif_show_logic(ivl_net_logic_t net) { char jbuf[1024]; unsigned idx; edif_uref += 1; switch (ivl_logic_type(net)) { case IVL_LO_AND: assert(ivl_logic_pins(net) <= 10); assert(ivl_logic_pins(net) >= 3); fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_logic_name(net)); fprintf(xnf, " (viewRef net" " (cellRef AND%u (libraryRef VIRTEX))))\n", ivl_logic_pins(net) - 1); sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { sprintf(jbuf, "(portRef I%u (instanceRef U%u))", idx-1, edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf); } break; case IVL_LO_BUF: assert(ivl_logic_pins(net) == 2); fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_logic_name(net)); fprintf(xnf, " (viewRef net" " (cellRef BUF (libraryRef VIRTEX))))\n"); sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf); break; case IVL_LO_BUFZ: { static int bufz_warned_once=0; if (!bufz_warned_once) { fprintf (stderr, "0:0: internal warning: BUFZ objects found " "in EDIF netlist.\n"); fprintf (stderr, "0:0: : I'll make BUFs for them.\n"); bufz_warned_once=1; } assert(ivl_logic_pins(net) == 2); fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_logic_name(net)); fprintf(xnf, " (viewRef net" " (cellRef BUF (libraryRef VIRTEX))))\n"); sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); sprintf(jbuf, "(portRef I (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 1), jbuf); } break; case IVL_LO_NOR: assert(ivl_logic_pins(net) <= 10); assert(ivl_logic_pins(net) >= 3); fprintf(xnf, "(instance (rename U%u \"%s\")", edif_uref, ivl_logic_name(net)); fprintf(xnf, " (viewRef net" " (cellRef NOR%u (libraryRef VIRTEX))))\n", ivl_logic_pins(net) - 1); sprintf(jbuf, "(portRef O (instanceRef U%u))", edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, 0), jbuf); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { sprintf(jbuf, "(portRef I%u (instanceRef U%u))", idx-1, edif_uref); edif_set_nexus_joint(ivl_logic_pin(net, idx), jbuf); } break; default: fprintf(stderr, "UNSUPPORT LOGIC TYPE: %d\n", ivl_logic_type(net)); } } static void edif_show_generic_dff(ivl_lpm_t net) { char jbuf[1024]; unsigned idx; ivl_nexus_t aclr = ivl_lpm_async_clr(net); ivl_nexus_t aset = ivl_lpm_async_set(net); const char*abits = 0; const char*fdcell = "FDCE"; if (aset != 0) { ivl_expr_t avalue = ivl_lpm_aset_value(net); fdcell = "FDCPE"; assert(avalue); abits = ivl_expr_bits(avalue); assert(abits); } for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { ivl_nexus_t nex; edif_uref += 1; fprintf(xnf, "(instance (rename U%u \"%s.%s[%u]\")", edif_uref, ivl_scope_name(ivl_lpm_scope(net)), ivl_lpm_basename(net), idx); fprintf(xnf, " (viewRef net" " (cellRef %s (libraryRef VIRTEX))))\n", fdcell); nex = ivl_lpm_q(net, idx); sprintf(jbuf, "(portRef Q (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); nex = ivl_lpm_data(net, idx); sprintf(jbuf, "(portRef D (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); nex = ivl_lpm_clk(net); sprintf(jbuf, "(portRef C (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); if ((nex = ivl_lpm_enable(net))) { sprintf(jbuf, "(portRef CE (instanceRef U%u))", edif_uref); edif_set_nexus_joint(nex, jbuf); } if (aclr) { sprintf(jbuf, "(portRef CLR (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aclr, jbuf); } if (aset) { if (abits[idx] == '1') { sprintf(jbuf, "(portRef PRE (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aset, jbuf); } else { assert(aclr == 0); sprintf(jbuf, "(portRef CLR (instanceRef U%u))", edif_uref); edif_set_nexus_joint(aset, jbuf); } } } } const struct device_s d_generic_edif = { edif_show_header, edif_show_footer, 0, /* show_cell_scope not implemented. */ 0, /* draw_pad not implemented */ edif_show_logic, edif_show_generic_dff, 0, /* show_cmp_eq */ 0, /* show_cmp_ne */ 0, /* show_cmp_ge */ 0, /* show_cmp_gt */ 0, 0, /* show_add */ 0, /* show_sub */ 0, /* show_shiftl */ 0 /* show_shiftr */ }; iverilog-12_0/tgt-fpga/d-generic.c000066400000000000000000000325301435245347300170640ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "device.h" # include "fpga_priv.h" # include /* * This is the device emitter for the most generic FPGA. It doesn't * know anything special about device types, so can't handle complex * logic. */ static void xnf_draw_pin(ivl_nexus_t nex, const char*nam, char dir) { const char*use_name = nam; const char*nex_name = xnf_mangle_nexus_name(nex); int invert = 0; if (use_name[0] == '~') { invert = 1; use_name += 1; } fprintf(xnf, " PIN, %s, %c, %s", use_name, dir, nex_name); if (invert) fprintf(xnf, ",,INV"); fprintf(xnf, "\n"); } static void show_root_ports_xnf(ivl_scope_t root) { unsigned cnt = ivl_scope_sigs(root); unsigned idx; for (idx = 0 ; idx < cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); const char*use_name; if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; use_name = ivl_signal_basename(sig); if (ivl_signal_pins(sig) == 1) { ivl_nexus_t nex = ivl_signal_pin(sig, 0); fprintf(xnf, "SIG, %s, PIN=%s\n", xnf_mangle_nexus_name(nex), use_name); } else { unsigned pin; for (pin = 0 ; pin < ivl_signal_pins(sig); pin += 1) { ivl_nexus_t nex = ivl_signal_pin(sig, pin); fprintf(xnf, "SIG, %s, PIN=%s%u\n", xnf_mangle_nexus_name(nex), use_name, pin); } } } } static void show_design_consts_xnf(ivl_design_t des) { unsigned idx; for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { unsigned pin; ivl_net_const_t net = ivl_design_const(des, idx); const char*val = ivl_const_bits(net); for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) { ivl_nexus_t nex = ivl_const_pin(net, pin); fprintf(xnf, "PWR,%c,%s\n", val[pin], xnf_mangle_nexus_name(nex)); } } } static void generic_show_header(ivl_design_t des) { ivl_scope_t root = ivl_design_root(des); fprintf(xnf, "LCANET,6\n"); fprintf(xnf, "PROG,iverilog,$Name: $,\"Icarus Verilog/fpga.tgt\"\n"); if (part && (part[0]!=0)) { fprintf(xnf, "PART,%s\n", part); } show_root_ports_xnf(root); } static void generic_show_footer(ivl_design_t des) { show_design_consts_xnf(des); fprintf(xnf, "EOF\n"); } static void generic_show_logic(ivl_net_logic_t net) { char name[1024]; ivl_nexus_t nex; unsigned idx; xnf_mangle_logic_name(net, name, sizeof name); switch (ivl_logic_type(net)) { case IVL_LO_AND: fprintf(xnf, "SYM, %s, AND, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_BUF: assert(ivl_logic_pins(net) == 2); fprintf(xnf, "SYM, %s, BUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); xnf_draw_pin(nex, "I", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_NAND: fprintf(xnf, "SYM, %s, NAND, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_NOR: fprintf(xnf, "SYM, %s, NOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_NOT: assert(ivl_logic_pins(net) == 2); fprintf(xnf, "SYM, %s, INV, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); xnf_draw_pin(nex, "I", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_OR: fprintf(xnf, "SYM, %s, OR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_XOR: fprintf(xnf, "SYM, %s, XOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_XNOR: fprintf(xnf, "SYM, %s, XNOR, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char ipin[32]; nex = ivl_logic_pin(net, idx); sprintf(ipin, "I%u", idx-1); xnf_draw_pin(nex, ipin, 'I'); } fprintf(xnf, "END\n"); break; case IVL_LO_BUFIF0: fprintf(xnf, "SYM, %s, TBUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); xnf_draw_pin(nex, "I", 'I'); nex = ivl_logic_pin(net, 2); xnf_draw_pin(nex, "~T", 'I'); fprintf(xnf, "END\n"); break; case IVL_LO_BUFIF1: fprintf(xnf, "SYM, %s, TBUF, LIBVER=2.0.0\n", name); nex = ivl_logic_pin(net, 0); xnf_draw_pin(nex, "O", 'O'); nex = ivl_logic_pin(net, 1); xnf_draw_pin(nex, "I", 'I'); nex = ivl_logic_pin(net, 2); xnf_draw_pin(nex, "T", 'I'); fprintf(xnf, "END\n"); break; default: fprintf(stderr, "fpga.tgt: unknown logic type %d\n", ivl_logic_type(net)); break; } } static void generic_show_dff(ivl_lpm_t net) { char name[1024]; ivl_nexus_t nex; xnf_mangle_lpm_name(net, name, sizeof name); fprintf(xnf, "SYM, %s, DFF, LIBVER=2.0.0\n", name); nex = ivl_lpm_q(net, 0); xnf_draw_pin(nex, "Q", 'O'); nex = ivl_lpm_data(net, 0); xnf_draw_pin(nex, "D", 'I'); nex = ivl_lpm_clk(net); xnf_draw_pin(nex, "C", 'I'); if ((nex = ivl_lpm_enable(net))) xnf_draw_pin(nex, "CE", 'I'); fprintf(xnf, "END\n"); } /* * The generic == comparator uses EQN records to generate 2-bit * comparators, that are then connected together by a wide AND gate. */ static void generic_show_cmp_eq(ivl_lpm_t net) { ivl_nexus_t nex; unsigned idx; char name[1024]; /* Make this many dual pair comparators, and */ unsigned deqn = ivl_lpm_width(net) / 2; /* Make this many single pair comparators. */ unsigned seqn = ivl_lpm_width(net) % 2; xnf_mangle_lpm_name(net, name, sizeof name); for (idx = 0 ; idx < deqn ; idx += 1) { fprintf(xnf, "SYM, %s/CD%u, EQN, " "EQN=(~((I0 @ I1) + (I2 @ I3)))\n", name, idx); fprintf(xnf, " PIN, O, O, %s/CDO%u\n", name, idx); nex = ivl_lpm_data(net, 2*idx); xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_datab(net, 2*idx); xnf_draw_pin(nex, "I1", 'I'); nex = ivl_lpm_data(net, 2*idx+1); xnf_draw_pin(nex, "I2", 'I'); nex = ivl_lpm_datab(net, 2*idx+1); xnf_draw_pin(nex, "I3", 'I'); fprintf(xnf, "END\n"); } if (seqn != 0) { fprintf(xnf, "SYM, %s/CT, XNOR, LIBVER=2.0.0\n", name); fprintf(xnf, " PIN, O, O, %s/CTO\n", name); nex = ivl_lpm_data(net, 2*deqn); xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_datab(net, 2*deqn); xnf_draw_pin(nex, "I1", 'I'); fprintf(xnf, "END\n"); } if (ivl_lpm_type(net) == IVL_LPM_CMP_EQ) fprintf(xnf, "SYM, %s/OUT, AND, LIBVER=2.0.0\n", name); else fprintf(xnf, "SYM, %s/OUT, NAND, LIBVER=2.0.0\n", name); nex = ivl_lpm_q(net, 0); xnf_draw_pin(nex, "O", 'O'); for (idx = 0 ; idx < deqn ; idx += 1) fprintf(xnf, " PIN, I%u, I, %s/CDO%u\n", idx, name, idx); for (idx = 0 ; idx < seqn ; idx += 1) fprintf(xnf, " PIN, I%u, I, %s/CTO\n", deqn+idx, name); fprintf(xnf, "END\n"); } /* * This function draws N-bit wide binary mux devices. These are so * very popular because they are the result of such expressions as: * * x = sel? a : b; * * This code only supports the case where sel is a single bit. It * works by drawing for each bit of the width an EQN device that takes * as inputs I0 and I1 the alternative inputs, and I2 the select. The * select bit is common with all the generated mux devices. */ static void generic_show_mux(ivl_lpm_t net) { char name[1024]; ivl_nexus_t sel; unsigned idx; xnf_mangle_lpm_name(net, name, sizeof name); /* Access the single select bit. This is common to the whole width of the mux. */ assert(ivl_lpm_selects(net) == 1); sel = ivl_lpm_select(net, 0); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { ivl_nexus_t nex; fprintf(xnf, "SYM, %s/M%u, EQN, " "EQN=((I0 * ~I2) + (I1 * I2))\n", name, idx); nex = ivl_lpm_q(net, idx); xnf_draw_pin(nex, "O", 'O'); nex = ivl_lpm_data2(net, 0, idx); xnf_draw_pin(nex, "I0", 'I'); nex = ivl_lpm_data2(net, 1, idx); xnf_draw_pin(nex, "I1", 'I'); xnf_draw_pin(sel, "I2", 'I'); fprintf(xnf, "END\n"); } } /* * This code cheats and just generates ADD4 devices enough to support * the add. Make no effort to optimize, because we have no idea what * kind of device we have. */ static void generic_show_add(ivl_lpm_t net) { char name[1024]; ivl_nexus_t nex; unsigned idx, nadd4, tail; xnf_mangle_lpm_name(net, name, sizeof name); /* Make this many ADD4 devices. */ nadd4 = ivl_lpm_width(net) / 4; tail = ivl_lpm_width(net) % 4; for (idx = 0 ; idx < nadd4 ; idx += 1) { fprintf(xnf, "SYM, %s/A%u, ADD4\n", name, idx); if (idx > 0) fprintf(xnf, " PIN, CI, I, %s/CO%u\n", name, idx-1); nex = ivl_lpm_q(net, idx*4+0); xnf_draw_pin(nex, "S0", 'O'); nex = ivl_lpm_q(net, idx*4+1); xnf_draw_pin(nex, "S1", 'O'); nex = ivl_lpm_q(net, idx*4+2); xnf_draw_pin(nex, "S2", 'O'); nex = ivl_lpm_q(net, idx*4+3); xnf_draw_pin(nex, "S3", 'O'); nex = ivl_lpm_data(net, idx*4+0); xnf_draw_pin(nex, "A0", 'I'); nex = ivl_lpm_data(net, idx*4+1); xnf_draw_pin(nex, "A1", 'I'); nex = ivl_lpm_data(net, idx*4+2); xnf_draw_pin(nex, "A2", 'I'); nex = ivl_lpm_data(net, idx*4+3); xnf_draw_pin(nex, "A3", 'I'); nex = ivl_lpm_datab(net, idx*4+0); xnf_draw_pin(nex, "B0", 'I'); nex = ivl_lpm_datab(net, idx*4+1); xnf_draw_pin(nex, "B1", 'I'); nex = ivl_lpm_datab(net, idx*4+2); xnf_draw_pin(nex, "B2", 'I'); nex = ivl_lpm_datab(net, idx*4+3); xnf_draw_pin(nex, "B3", 'I'); if ((idx*4+4) < ivl_lpm_width(net)) fprintf(xnf, " PIN, CO, O, %s/CO%u\n", name, idx); fprintf(xnf, "END\n"); } if (tail > 0) { fprintf(xnf, "SYM, %s/A%u, ADD4\n", name, nadd4); if (nadd4 > 0) fprintf(xnf, " PIN, CI, I, %s/CO%u\n", name, nadd4-1); switch (tail) { case 3: nex = ivl_lpm_data(net, nadd4*4+2); xnf_draw_pin(nex, "A2", 'I'); nex = ivl_lpm_datab(net, nadd4*4+2); xnf_draw_pin(nex, "B2", 'I'); nex = ivl_lpm_q(net, nadd4*4+2); xnf_draw_pin(nex, "S2", 'O'); case 2: nex = ivl_lpm_data(net, nadd4*4+1); xnf_draw_pin(nex, "A1", 'I'); nex = ivl_lpm_datab(net, nadd4*4+1); xnf_draw_pin(nex, "B1", 'I'); nex = ivl_lpm_q(net, nadd4*4+1); xnf_draw_pin(nex, "S1", 'O'); case 1: nex = ivl_lpm_data(net, nadd4*4+0); xnf_draw_pin(nex, "A0", 'I'); nex = ivl_lpm_datab(net, nadd4*4+0); xnf_draw_pin(nex, "B0", 'I'); nex = ivl_lpm_q(net, nadd4*4+0); xnf_draw_pin(nex, "S0", 'O'); } fprintf(xnf, "END\n"); } } const struct device_s d_generic = { generic_show_header, generic_show_footer, 0, /* show_scope */ 0, /* show_pad not implemented */ generic_show_logic, generic_show_dff, generic_show_cmp_eq, generic_show_cmp_eq, 0, /* ge not implemented */ 0, /* gt not implemented */ generic_show_mux, generic_show_add, 0, /* subtract not implemented */ 0, 0 }; iverilog-12_0/tgt-fpga/d-lpm.c000066400000000000000000000561051435245347300162440ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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. */ /* * This is the driver for a purely generic LPM module writer. This * uses LPM version 2 1 0 devices, without particularly considering * the target technology. * * The LPM standard is EIA-IS/103-A October 1996 * The output is EDIF 2 0 0 format. */ # include "device.h" # include "fpga_priv.h" # include "edif.h" # include "generic.h" # include # include static edif_cell_t lpm_cell_buf(void) { static edif_cell_t tmp = 0; if (tmp != 0) return tmp; tmp = edif_xcell_create(xlib, "BUF", 2); edif_cell_portconfig(tmp, 0, "Result", IVL_SIP_OUTPUT); edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); /* A buffer is an inverted inverter. */ edif_cell_port_pstring(tmp, 0, "LPM_Polarity", "INVERT"); edif_cell_pstring(tmp, "LPM_TYPE", "LPM_INV"); edif_cell_pinteger(tmp, "LPM_Width", 1); edif_cell_pinteger(tmp, "LPM_Size", 1); return tmp; } static edif_cell_t lpm_cell_inv(void) { static edif_cell_t tmp = 0; if (tmp != 0) return tmp; tmp = edif_xcell_create(xlib, "INV", 2); edif_cell_portconfig(tmp, 0, "Result", IVL_SIP_OUTPUT); edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); edif_cell_pstring(tmp, "LPM_TYPE", "LPM_INV"); edif_cell_pinteger(tmp, "LPM_Width", 1); edif_cell_pinteger(tmp, "LPM_Size", 1); return tmp; } static edif_cell_t lpm_cell_bufif0(void) { static edif_cell_t tmp = 0; if (tmp != 0) return tmp; tmp = edif_xcell_create(xlib, "BUFIF1", 3); edif_cell_portconfig(tmp, 0, "TriData", IVL_SIP_OUTPUT); edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); edif_cell_portconfig(tmp, 2, "EnableDT", IVL_SIP_INPUT); edif_cell_port_pstring(tmp, 2, "LPM_Polarity", "INVERT"); edif_cell_pstring(tmp, "LPM_TYPE", "LPM_BUSTRI"); edif_cell_pinteger(tmp, "LPM_Width", 1); return tmp; } static edif_cell_t lpm_cell_bufif1(void) { static edif_cell_t tmp = 0; if (tmp != 0) return tmp; tmp = edif_xcell_create(xlib, "BUFIF1", 3); edif_cell_portconfig(tmp, 0, "TriData", IVL_SIP_OUTPUT); edif_cell_portconfig(tmp, 1, "Data", IVL_SIP_INPUT); edif_cell_portconfig(tmp, 2, "EnableDT", IVL_SIP_INPUT); edif_cell_pstring(tmp, "LPM_TYPE", "LPM_BUSTRI"); edif_cell_pinteger(tmp, "LPM_Width", 1); return tmp; } static edif_cell_t lpm_cell_or(unsigned siz) { unsigned idx; edif_cell_t cell; char name[32]; sprintf(name, "or%u", siz); cell = edif_xlibrary_findcell(xlib, name); if (cell != 0) return cell; cell = edif_xcell_create(xlib, strdup(name), siz+1); edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); for (idx = 0 ; idx < siz ; idx += 1) { sprintf(name, "Data%ux0", idx); edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); } edif_cell_pstring(cell, "LPM_TYPE", "LPM_OR"); edif_cell_pinteger(cell, "LPM_Width", 1); edif_cell_pinteger(cell, "LPM_Size", siz); return cell; } static edif_cell_t lpm_cell_and(unsigned siz) { unsigned idx; edif_cell_t cell; char name[32]; sprintf(name, "and%u", siz); cell = edif_xlibrary_findcell(xlib, name); if (cell != 0) return cell; cell = edif_xcell_create(xlib, strdup(name), siz+1); edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); for (idx = 0 ; idx < siz ; idx += 1) { sprintf(name, "Data%ux0", idx); edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); } edif_cell_pstring(cell, "LPM_TYPE", "LPM_AND"); edif_cell_pinteger(cell, "LPM_Width", 1); edif_cell_pinteger(cell, "LPM_Size", siz); return cell; } static edif_cell_t lpm_cell_xor(unsigned siz) { unsigned idx; edif_cell_t cell; char name[32]; sprintf(name, "xor%u", siz); cell = edif_xlibrary_findcell(xlib, name); if (cell != 0) return cell; cell = edif_xcell_create(xlib, strdup(name), siz+1); edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); for (idx = 0 ; idx < siz ; idx += 1) { sprintf(name, "Data%ux0", idx); edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); } edif_cell_pstring(cell, "LPM_TYPE", "LPM_XOR"); edif_cell_pinteger(cell, "LPM_Width", 1); edif_cell_pinteger(cell, "LPM_Size", siz); return cell; } static edif_cell_t lpm_cell_nor(unsigned siz) { unsigned idx; edif_cell_t cell; char name[32]; sprintf(name, "nor%u", siz); cell = edif_xlibrary_findcell(xlib, name); if (cell != 0) return cell; cell = edif_xcell_create(xlib, strdup(name), siz+1); edif_cell_portconfig(cell, 0, "Result0", IVL_SIP_OUTPUT); edif_cell_port_pstring(cell, 0, "LPM_Polarity", "INVERT"); for (idx = 0 ; idx < siz ; idx += 1) { sprintf(name, "Data%ux0", idx); edif_cell_portconfig(cell, idx+1, strdup(name), IVL_SIP_INPUT); } edif_cell_pstring(cell, "LPM_TYPE", "LPM_OR"); edif_cell_pinteger(cell, "LPM_Width", 1); edif_cell_pinteger(cell, "LPM_Size", siz); return cell; } static void lpm_show_header(ivl_design_t des) { unsigned idx; ivl_scope_t root = ivl_design_root(des); unsigned sig_cnt = ivl_scope_sigs(root); unsigned nports = 0, pidx; /* Count the ports I'm going to use. */ for (idx = 0 ; idx < sig_cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; if (ivl_signal_attr(sig, "PAD") != 0) continue; nports += ivl_signal_pins(sig); } /* Create the base edf object. */ edf = edif_create(ivl_scope_basename(root), nports); pidx = 0; for (idx = 0 ; idx < sig_cnt ; idx += 1) { edif_joint_t jnt; ivl_signal_t sig = ivl_scope_sig(root, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; if (ivl_signal_attr(sig, "PAD") != 0) continue; if (ivl_signal_pins(sig) == 1) { edif_portconfig(edf, pidx, ivl_signal_basename(sig), ivl_signal_port(sig)); assert(ivl_signal_pins(sig) == 1); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0)); edif_port_to_joint(jnt, edf, pidx); } else { const char*name = ivl_signal_basename(sig); ivl_signal_port_t dir = ivl_signal_port(sig); char buf[128]; unsigned bit; for (bit = 0 ; bit < ivl_signal_pins(sig) ; bit += 1) { const char*tmp; sprintf(buf, "%s[%u]", name, bit); tmp = strdup(buf); edif_portconfig(edf, pidx+bit, tmp, dir); jnt = edif_joint_of_nexus(edf,ivl_signal_pin(sig,bit)); edif_port_to_joint(jnt, edf, pidx+bit); } } pidx += ivl_signal_pins(sig); } assert(pidx == nports); xlib = edif_xlibrary_create(edf, "LPM_LIBRARY"); } static void lpm_show_footer(ivl_design_t des) { edif_print(xnf, edf); } static void hookup_logic_gate(ivl_net_logic_t net, edif_cell_t cell) { unsigned pin, idx; edif_joint_t jnt; edif_cellref_t ref = edif_cellref_create(edf, cell); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); pin = edif_cell_port_byname(cell, "Result0"); edif_add_to_joint(jnt, ref, pin); for (idx = 1 ; idx < ivl_logic_pins(net) ; idx += 1) { char name[32]; jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx)); sprintf(name, "Data%ux0", idx-1); pin = edif_cell_port_byname(cell, name); edif_add_to_joint(jnt, ref, pin); } } static void lpm_logic(ivl_net_logic_t net) { edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; switch (ivl_logic_type(net)) { case IVL_LO_BUFZ: case IVL_LO_BUF: assert(ivl_logic_pins(net) == 2); cell = lpm_cell_buf(); ref = edif_cellref_create(edf, cell); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, ref, 0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, ref, 1); break; case IVL_LO_BUFIF0: assert(ivl_logic_pins(net) == 3); cell = lpm_cell_bufif0(); ref = edif_cellref_create(edf, cell); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, ref, 0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, ref, 1); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); edif_add_to_joint(jnt, ref, 2); break; case IVL_LO_BUFIF1: assert(ivl_logic_pins(net) == 3); cell = lpm_cell_bufif1(); ref = edif_cellref_create(edf, cell); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, ref, 0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, ref, 1); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); edif_add_to_joint(jnt, ref, 2); break; case IVL_LO_NOT: assert(ivl_logic_pins(net) == 2); cell = lpm_cell_inv(); ref = edif_cellref_create(edf, cell); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, ref, 0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, ref, 1); break; case IVL_LO_OR: cell = lpm_cell_or(ivl_logic_pins(net)-1); hookup_logic_gate(net, cell); break; case IVL_LO_NOR: cell = lpm_cell_nor(ivl_logic_pins(net)-1); hookup_logic_gate(net, cell); break; case IVL_LO_AND: cell = lpm_cell_and(ivl_logic_pins(net)-1); hookup_logic_gate( net, cell); break; case IVL_LO_XOR: cell = lpm_cell_xor(ivl_logic_pins(net)-1); hookup_logic_gate( net, cell); break; default: fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %d\n", ivl_logic_type(net)); break; } } static void lpm_show_dff(ivl_lpm_t net) { char name[64]; edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; unsigned idx; unsigned pin, wid = ivl_lpm_width(net); sprintf(name, "fd%s%s%s%s%s%u", ivl_lpm_enable(net)? "ce" : "", ivl_lpm_async_clr(net)? "cl" : "", ivl_lpm_sync_clr(net)? "sc" : "", ivl_lpm_async_set(net)? "se" : "", ivl_lpm_sync_set(net)? "ss" : "", wid); cell = edif_xlibrary_findcell(xlib, name); if (cell == 0) { unsigned nports = 2 * wid + 1; pin = 0; if (ivl_lpm_enable(net)) nports += 1; if (ivl_lpm_async_clr(net)) nports += 1; if (ivl_lpm_sync_clr(net)) nports += 1; if (ivl_lpm_async_set(net)) nports += 1; if (ivl_lpm_sync_set(net)) nports += 1; cell = edif_xcell_create(xlib, strdup(name), nports); edif_cell_pstring(cell, "LPM_Type", "LPM_FF"); edif_cell_pinteger(cell, "LPM_Width", wid); for (idx = 0 ; idx < wid ; idx += 1) { sprintf(name, "Q%u", idx); edif_cell_portconfig(cell, idx*2+0, strdup(name), IVL_SIP_OUTPUT); sprintf(name, "Data%u", idx); edif_cell_portconfig(cell, idx*2+1, strdup(name), IVL_SIP_INPUT); } pin = wid*2; if (ivl_lpm_enable(net)) { edif_cell_portconfig(cell, pin, "Enable", IVL_SIP_INPUT); pin += 1; } if (ivl_lpm_async_clr(net)) { edif_cell_portconfig(cell, pin, "Aclr", IVL_SIP_INPUT); pin += 1; } if (ivl_lpm_sync_clr(net)) { edif_cell_portconfig(cell, pin, "Sclr", IVL_SIP_INPUT); pin += 1; } if (ivl_lpm_async_set(net)) { edif_cell_portconfig(cell, pin, "Aset", IVL_SIP_INPUT); pin += 1; } if (ivl_lpm_sync_set(net)) { edif_cell_portconfig(cell, pin, "Sset", IVL_SIP_INPUT); pin += 1; } edif_cell_portconfig(cell, pin, "Clock", IVL_SIP_INPUT); pin += 1; assert(pin == nports); } ref = edif_cellref_create(edf, cell); pin = edif_cell_port_byname(cell, "Clock"); jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net)); edif_add_to_joint(jnt, ref, pin); if (ivl_lpm_enable(net)) { pin = edif_cell_port_byname(cell, "Enable"); jnt = edif_joint_of_nexus(edf, ivl_lpm_enable(net)); edif_add_to_joint(jnt, ref, pin); } if (ivl_lpm_async_clr(net)) { pin = edif_cell_port_byname(cell, "Aclr"); jnt = edif_joint_of_nexus(edf, ivl_lpm_async_clr(net)); edif_add_to_joint(jnt, ref, pin); } if (ivl_lpm_sync_clr(net)) { pin = edif_cell_port_byname(cell, "Sclr"); jnt = edif_joint_of_nexus(edf, ivl_lpm_sync_clr(net)); edif_add_to_joint(jnt, ref, pin); } if (ivl_lpm_async_set(net)) { pin = edif_cell_port_byname(cell, "Aset"); jnt = edif_joint_of_nexus(edf, ivl_lpm_async_set(net)); edif_add_to_joint(jnt, ref, pin); } if (ivl_lpm_sync_set(net)) { ivl_expr_t svalue = ivl_lpm_sset_value(net); pin = edif_cell_port_byname(cell, "Sset"); jnt = edif_joint_of_nexus(edf, ivl_lpm_sync_set(net)); edif_add_to_joint(jnt, ref, pin); edif_cellref_pinteger(ref, "LPM_Svalue", ivl_expr_uvalue(svalue)); } for (idx = 0 ; idx < wid ; idx += 1) { sprintf(name, "Q%u", idx); pin = edif_cell_port_byname(cell, name); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, ref, pin); sprintf(name, "Data%u", idx); pin = edif_cell_port_byname(cell, name); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, ref, pin); } } static void lpm_show_mux(ivl_lpm_t net) { edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; unsigned idx; char cellname[32]; unsigned wid_r = ivl_lpm_width(net); unsigned wid_s = ivl_lpm_selects(net); unsigned wid_z = ivl_lpm_size(net); sprintf(cellname, "mux%u_%u_%u", wid_r, wid_s, wid_z); cell = edif_xlibrary_findcell(xlib, cellname); if (cell == 0) { unsigned pins = wid_r + wid_s + wid_r*wid_z; cell = edif_xcell_create(xlib, strdup(cellname), pins); /* Make the output ports. */ for (idx = 0 ; idx < wid_r ; idx += 1) { sprintf(cellname, "Result%u", idx); edif_cell_portconfig(cell, idx, strdup(cellname), IVL_SIP_OUTPUT); } /* Make the select ports. */ for (idx = 0 ; idx < wid_s ; idx += 1) { sprintf(cellname, "Sel%u", idx); edif_cell_portconfig(cell, wid_r+idx, strdup(cellname), IVL_SIP_INPUT); } for (idx = 0 ; idx < wid_z ; idx += 1) { unsigned base = wid_r + wid_s + wid_r * idx; unsigned rdx; for (rdx = 0 ; rdx < wid_r ; rdx += 1) { sprintf(cellname, "Data%ux%u", idx, rdx); edif_cell_portconfig(cell, base+rdx, strdup(cellname), IVL_SIP_INPUT); } } edif_cell_pstring(cell, "LPM_Type", "LPM_MUX"); edif_cell_pinteger(cell, "LPM_Width", wid_r); edif_cell_pinteger(cell, "LPM_WidthS", wid_s); edif_cell_pinteger(cell, "LPM_Size", wid_z); } ref = edif_cellref_create(edf, cell); /* Connect the pins of the instance to the nexa. Access the cell pins by name. */ for (idx = 0 ; idx < wid_r ; idx += 1) { unsigned pin; sprintf(cellname, "Result%u", idx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, ref, pin); } for (idx = 0 ; idx < wid_s ; idx += 1) { unsigned pin; sprintf(cellname, "Sel%u", idx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, idx)); edif_add_to_joint(jnt, ref, pin); } for (idx = 0 ; idx < wid_z ; idx += 1) { unsigned rdx; for (rdx = 0 ; rdx < wid_r ; rdx += 1) { unsigned pin; sprintf(cellname, "Data%ux%u", idx, rdx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, idx, rdx)); edif_add_to_joint(jnt, ref, pin); } } } static void lpm_show_add(ivl_lpm_t net) { unsigned idx; unsigned cell_width; char cellname[32]; edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; const char*type = "ADD"; if (ivl_lpm_type(net) == IVL_LPM_SUB) type = "SUB"; /* Figure out the width of the cell. Normally, it is the LPM width known by IVL. But if the top data input bits are unconnected, then we really have a width one less, and we can use the cout to fill out the output width. */ cell_width = ivl_lpm_width(net); if ( (ivl_lpm_data(net,cell_width-1) == 0) && (ivl_lpm_datab(net,cell_width-1) == 0) ) cell_width -= 1; /* Find the correct ADD/SUB device in the library, search by name. If the device is not there, then create it and put it in the library. */ sprintf(cellname, "%s%u", type, cell_width); cell = edif_xlibrary_findcell(xlib, cellname); if (cell == 0) { unsigned pins = cell_width * 3 + 1; cell = edif_xcell_create(xlib, strdup(cellname), pins); for (idx = 0 ; idx < cell_width ; idx += 1) { sprintf(cellname, "Result%u", idx); edif_cell_portconfig(cell, idx*3+0, strdup(cellname), IVL_SIP_OUTPUT); sprintf(cellname, "DataA%u", idx); edif_cell_portconfig(cell, idx*3+1, strdup(cellname), IVL_SIP_INPUT); sprintf(cellname, "DataB%u", idx); edif_cell_portconfig(cell, idx*3+2, strdup(cellname), IVL_SIP_INPUT); } edif_cell_portconfig(cell, pins-1, "Cout", IVL_SIP_OUTPUT); edif_cell_pstring(cell, "LPM_Type", "LPM_ADD_SUB"); edif_cell_pstring(cell, "LPM_Direction", type); edif_cell_pinteger(cell, "LPM_Width", ivl_lpm_width(net)); } ref = edif_cellref_create(edf, cell); /* Connect the pins of the instance to the nexa. Access the cell pins by name. */ for (idx = 0 ; idx < cell_width ; idx += 1) { unsigned pin; sprintf(cellname, "Result%u", idx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, ref, pin); sprintf(cellname, "DataA%u", idx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, ref, pin); sprintf(cellname, "DataB%u", idx); pin = edif_cell_port_byname(cell, cellname); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx)); edif_add_to_joint(jnt, ref, pin); } if (cell_width < ivl_lpm_width(net)) { unsigned pin = edif_cell_port_byname(cell, "Cout"); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, cell_width)); edif_add_to_joint(jnt, ref, pin); } } static void lpm_show_mult(ivl_lpm_t net) { char name[64]; unsigned idx; edif_cell_t cell; edif_cellref_t ref; sprintf(name, "mult%u", ivl_lpm_width(net)); cell = edif_xlibrary_findcell(xlib, name); if (cell == 0) { cell = edif_xcell_create(xlib, strdup(name), 3 * ivl_lpm_width(net)); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { sprintf(name, "Result%u", idx); edif_cell_portconfig(cell, idx*3+0, strdup(name), IVL_SIP_OUTPUT); sprintf(name, "DataA%u", idx); edif_cell_portconfig(cell, idx*3+1, strdup(name), IVL_SIP_INPUT); sprintf(name, "DataB%u", idx); edif_cell_portconfig(cell, idx*3+2, strdup(name), IVL_SIP_INPUT); } edif_cell_pstring(cell, "LPM_Type", "LPM_MULT"); edif_cell_pinteger(cell, "LPM_WidthP", ivl_lpm_width(net)); edif_cell_pinteger(cell, "LPM_WidthA", ivl_lpm_width(net)); edif_cell_pinteger(cell, "LPM_WidthB", ivl_lpm_width(net)); } ref = edif_cellref_create(edf, cell); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { unsigned pin; ivl_nexus_t nex; edif_joint_t jnt; sprintf(name, "Result%u", idx); pin = edif_cell_port_byname(cell, name); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, ref, pin); if ( (nex = ivl_lpm_data(net, idx)) ) { sprintf(name, "DataA%u", idx); pin = edif_cell_port_byname(cell, name); jnt = edif_joint_of_nexus(edf, nex); edif_add_to_joint(jnt, ref, pin); } if ( (nex = ivl_lpm_datab(net, idx)) ) { sprintf(name, "DataB%u", idx); pin = edif_cell_port_byname(cell, name); jnt = edif_joint_of_nexus(edf, nex); edif_add_to_joint(jnt, ref, pin); } } } static void lpm_show_constant(ivl_net_const_t net) { edif_cell_t cell0 = edif_xlibrary_findcell(xlib, "cell0"); edif_cell_t cell1 = edif_xlibrary_findcell(xlib, "cell1"); edif_cellref_t ref0 = 0, ref1 = 0; const char*bits; unsigned idx; if (cell0 == 0) { cell0 = edif_xcell_create(xlib, "cell0", 1); edif_cell_portconfig(cell0, 0, "Result0", IVL_SIP_OUTPUT); edif_cell_pstring(cell0, "LPM_Type", "LPM_CONSTANT"); edif_cell_pinteger(cell0, "LPM_Width", 1); edif_cell_pinteger(cell0, "LPM_CValue", 0); } if (cell1 == 0) { cell1 = edif_xcell_create(xlib, "cell1", 1); edif_cell_portconfig(cell1, 0, "Result0", IVL_SIP_OUTPUT); edif_cell_pstring(cell1, "LPM_Type", "LPM_CONSTANT"); edif_cell_pinteger(cell1, "LPM_Width", 1); edif_cell_pinteger(cell1, "LPM_CValue", 1); } bits = ivl_const_bits(net); for (idx = 0 ; idx < ivl_const_pins(net) ; idx += 1) { if (bits[idx] == '1') { if (ref1 == 0) ref1 = edif_cellref_create(edf, cell1); } else { if (ref0 == 0) ref0 = edif_cellref_create(edf, cell0); } } for (idx = 0 ; idx < ivl_const_pins(net) ; idx += 1) { edif_joint_t jnt; jnt = edif_joint_of_nexus(edf, ivl_const_pin(net,idx)); if (bits[idx] == '1') edif_add_to_joint(jnt, ref1, 0); else edif_add_to_joint(jnt, ref0, 0); } } const struct device_s d_lpm_edif = { lpm_show_header, lpm_show_footer, 0, 0, lpm_logic, lpm_show_dff, /* show_dff */ 0, 0, 0, 0, /* show_cmp_gt */ lpm_show_mux, /* show_mux */ lpm_show_add, /* show_add */ lpm_show_add, /* show_sub */ 0, /* show_shiftl */ 0, /* show_shiftr */ lpm_show_mult, /* show_mult */ lpm_show_constant /* show_constant */ }; iverilog-12_0/tgt-fpga/d-virtex.c000066400000000000000000000613351435245347300167760ustar00rootroot00000000000000/* * Copyright (c) 2003-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 "device.h" # include "fpga_priv.h" # include "edif.h" # include "generic.h" # include "xilinx.h" # include # include # include /* * This is a table of cell types that are accessible via the cellref * attribute to a gate. */ const static struct edif_xlib_celltable virtex_celltable[] = { { "BUFG", xilinx_cell_bufg }, { "MULT_AND", xilinx_cell_mult_and }, { 0, 0} }; /* * The show_header function is called before any of the devices of the * netlist are scanned. * * In this function, we look at the ports of the root module to decide * if they are to be made into ports. Modules that have PAD attributes * are *not* to be used as ports, they will be connected to special * PAD devices instead. */ static void virtex_show_header(ivl_design_t des) { const char*part_str = 0; xilinx_common_header(des); xlib = edif_xlibrary_create(edf, "VIRTEX"); edif_xlibrary_set_celltable(xlib, virtex_celltable); if ( (part_str = ivl_design_flag(des, "part")) && (part_str[0] != 0) ) { edif_pstring(edf, "PART", part_str); } cell_0 = edif_xcell_create(xlib, "GND", 1); edif_cell_portconfig(cell_0, 0, "GROUND", IVL_SIP_OUTPUT); cell_1 = edif_xcell_create(xlib, "VCC", 1); edif_cell_portconfig(cell_1, 0, "VCC", IVL_SIP_OUTPUT); } static void virtex_or_wide(ivl_net_logic_t net) { edif_cell_t cell_muxcy_l = xilinx_cell_muxcy_l(xlib); edif_cell_t cell_muxcy = xilinx_cell_muxcy(xlib); edif_cell_t cell_lut4 = xilinx_cell_lut4(xlib); edif_cellref_t true_out, false_out; edif_cellref_t lut, muxcy, muxcy_down=NULL; edif_joint_t jnt; unsigned idx, inputs, lut4_cnt; if (ivl_logic_type(net) == IVL_LO_OR) { true_out = edif_cellref_create(edf, cell_1); false_out = edif_cellref_create(edf, cell_0); } else { true_out = edif_cellref_create(edf, cell_0); false_out = edif_cellref_create(edf, cell_1); } inputs = ivl_logic_pins(net) - 1; lut4_cnt = (inputs-1)/4; for (idx = 0 ; idx < lut4_cnt ; idx += 1) { muxcy = edif_cellref_create(edf, cell_muxcy_l); lut = edif_cellref_create(edf, cell_lut4); edif_cellref_pstring(lut, "INIT", "0001"); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, lut, LUT_O); edif_add_to_joint(jnt, muxcy, MUXCY_S); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, true_out, 0); edif_add_to_joint(jnt, muxcy, MUXCY_DI); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+1)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+2)); edif_add_to_joint(jnt, lut, LUT_I2); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx*4+1+3)); edif_add_to_joint(jnt, lut, LUT_I3); if (idx > 0) { jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxcy, MUXCY_CI); edif_add_to_joint(jnt, muxcy_down, MUXCY_O); } else { jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxcy, MUXCY_CI); edif_add_to_joint(jnt, false_out, 0); } muxcy_down = muxcy; } muxcy = edif_cellref_create(edf, cell_muxcy); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, true_out, 0); edif_add_to_joint(jnt, muxcy, MUXCY_DI); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxcy, MUXCY_CI); edif_add_to_joint(jnt, muxcy_down, MUXCY_O); switch (ivl_logic_pins(net) - 1 - lut4_cnt*4) { case 1: lut = edif_cellref_create(edf, xilinx_cell_inv(xlib)); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); edif_add_to_joint(jnt, lut, BUF_I); break; case 2: lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); edif_cellref_pstring(lut, "INIT", "1"); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); edif_add_to_joint(jnt, lut, LUT_I1); break; case 3: lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib)); edif_cellref_pstring(lut, "INIT", "01"); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2)); edif_add_to_joint(jnt, lut, LUT_I2); break; case 4: lut = edif_cellref_create(edf, cell_lut4); edif_cellref_pstring(lut, "INIT", "0001"); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+1)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+2)); edif_add_to_joint(jnt, lut, LUT_I2); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, lut4_cnt*4+1+3)); edif_add_to_joint(jnt, lut, LUT_I3); break; default: assert(0); } jnt = edif_joint_create(edf); edif_add_to_joint(jnt, lut, LUT_O); edif_add_to_joint(jnt, muxcy, MUXCY_S); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, muxcy, MUXCY_O); } /* * Pick off the cases where there is a Virtex specific implementation * that is better than the generic Xilinx implementation. Route the * remaining to the base xilinx_logic implementation. */ void virtex_logic(ivl_net_logic_t net) { /* Nothing I can do if the user expresses a specific opinion. The cellref attribute forces me to let the base xilinx_logic take care of it. */ if (ivl_logic_attr(net, "cellref")) { xilinx_logic(net); return; } switch (ivl_logic_type(net)) { case IVL_LO_OR: case IVL_LO_NOR: if (ivl_logic_pins(net) <= 5) { xilinx_logic(net); } else { virtex_or_wide(net); } break; default: xilinx_logic(net); break; } } void virtex_generic_dff(ivl_lpm_t net) { unsigned idx; ivl_nexus_t aclr = ivl_lpm_async_clr(net); ivl_nexus_t aset = ivl_lpm_async_set(net); ivl_nexus_t sclr = ivl_lpm_sync_clr(net); ivl_nexus_t sset = ivl_lpm_sync_set(net); const char*abits = 0; if (aset) { ivl_expr_t avalue = ivl_lpm_aset_value(net); assert(avalue); abits = ivl_expr_bits(avalue); assert(abits); } /* XXXX Can't handle both synchronous and asynchronous clear. */ assert( ! (aclr && sclr) ); /* XXXX Can't handle synchronous set at all. */ assert( ! sset ); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_cellref_t obj; ivl_nexus_t nex; edif_joint_t jnt; /* If there is a preset, then select an FDCPE instead of an FDCE device. */ if (aset && (abits[idx] == '1')) { obj = edif_cellref_create(edf, xilinx_cell_fdcpe(xlib)); } else if (aclr) { obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib)); } else if (sclr) { obj = edif_cellref_create(edf, xilinx_cell_fdre(xlib)); } else { obj = edif_cellref_create(edf, xilinx_cell_fdce(xlib)); } jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, obj, FDCE_Q); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, obj, FDCE_D); jnt = edif_joint_of_nexus(edf, ivl_lpm_clk(net)); edif_add_to_joint(jnt, obj, FDCE_C); if ( (nex = ivl_lpm_enable(net)) ) { jnt = edif_joint_of_nexus(edf, nex); edif_add_to_joint(jnt, obj, FDCE_CE); } if (aclr) { jnt = edif_joint_of_nexus(edf, aclr); edif_add_to_joint(jnt, obj, FDCE_CLR); } else if (sclr) { jnt = edif_joint_of_nexus(edf, sclr); edif_add_to_joint(jnt, obj, FDCE_CLR); } if (aset) { if (abits[idx] == '1') { jnt = edif_joint_of_nexus(edf, aset); edif_add_to_joint(jnt, obj, FDCE_PRE); } else { assert(aclr == 0); jnt = edif_joint_of_nexus(edf, aset); edif_add_to_joint(jnt, obj, FDCE_CLR); } } } } /* * This method handles both == and != operators, the identity * comparison operators. * * If the identity compare is applied to small enough input vectors, * it is shoved into a single LUT. Otherwise, it is strung out into a * row of LUT devices chained together by carry muxes. The output of * the comparison is the output of the last mux. * * When the compare is small, a LUT is generated with the appropriate * truth table to cause an == or != result. * * When the compare is too wide for a single LUT, then it is made into * a chain connected by a string of carry mux devices. Each LUT * implements == for up to two pairs of bits, even if the final output * is supposed to be !=. The LUT output is connected to an associated * MUX select input. The CO output of each muxcy is passed up to the * next higher order bits of the compare. * * For identity == compare, a != output from the LUT selects the DI * input of the muxcy, generating a 0 output that is passed up. Since * the next higher muxcy now gets a 0 input to both DI and CI, the * output of the next higher muxcy is guaranteed to be 0, and so on to * the final output of the carry chain. If the output from a LUT is ==, * then the CI input of the muxcy is selected and the truth of this * level depends on lower order bits. The least significant muxcy is * connected to GND and VCC so that its CO follows the least * significant LUT. * * Identity != is the same as == except that the output is * inverted. To get that effect without putting an inverter on the * output of the top muxcy pin CO (which would cost a LUT) the DI * inputs are all connected to VCC instead of GND, and the CI of the * least significant muxcy is connected to GND instead of VCC. The LUT * expressions for the chained compare are configured for ==, with the * changed CI/DI inputs performing the inversion. */ void virtex_eq(ivl_lpm_t net) { edif_cellref_t lut, mux, mux_prev; edif_joint_t jnt, jnt_di; unsigned idx; /* True if I'm implementing CMP_EQ instead of CMP_NE */ int eq = 1; assert(ivl_lpm_width(net) >= 1); if (ivl_lpm_type(net) == IVL_LPM_CMP_NE) eq = 0; switch (ivl_lpm_width(net)) { case 1: lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); edif_cellref_pstring(lut, "INIT", eq? "9" : "6"); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I1); return; case 2: lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib)); edif_cellref_pstring(lut, "INIT", eq? "9009" : "6FF6"); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1)); edif_add_to_joint(jnt, lut, LUT_I2); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1)); edif_add_to_joint(jnt, lut, LUT_I3); return; default: { edif_cellref_t di; di = edif_cellref_create(edf, eq? cell_0 : cell_1); jnt_di = edif_joint_create(edf); edif_add_to_joint(jnt_di, di, 0); } mux_prev = 0; for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 2) { int subwid = 2; if ((idx + 1) == ivl_lpm_width(net)) subwid = 1; mux = edif_cellref_create(edf, xilinx_cell_muxcy(xlib)); if (subwid == 2) { lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib)); edif_cellref_pstring(lut, "INIT", "9009"); } else { lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); edif_cellref_pstring(lut, "INIT", "9"); } jnt = edif_joint_create(edf); edif_add_to_joint(jnt, lut, LUT_O); edif_add_to_joint(jnt, mux, MUXCY_S); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx)); edif_add_to_joint(jnt, lut, LUT_I1); if (subwid > 1) { jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx+1)); edif_add_to_joint(jnt, lut, LUT_I2); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx+1)); edif_add_to_joint(jnt, lut, LUT_I3); } edif_add_to_joint(jnt_di, mux, MUXCY_DI); if (mux_prev) { jnt = edif_joint_create(edf); edif_add_to_joint(jnt, mux, MUXCY_CI); edif_add_to_joint(jnt, mux_prev, MUXCY_O); } else { edif_cellref_t ci; ci = edif_cellref_create(edf, eq? cell_1 : cell_0); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, ci, 0); edif_add_to_joint(jnt, mux, MUXCY_CI); } mux_prev = mux; } jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, mux_prev, MUXCY_O); return; } } /* * Implement hardware for the device (A >= B). We use LUT devices if * it can handle the slices, or carry chain logic if the slices must * span LUT devices. */ void virtex_ge(ivl_lpm_t net) { edif_cellref_t muxcy_prev; edif_cellref_t lut; edif_joint_t jnt; unsigned idx; if (ivl_lpm_width(net) == 1) { /* If the comparator is a single bit, then use a LUT2 with this truth table: Q A B --+---- 1 | 0 0 0 | 0 1 1 | 1 0 1 | 1 1 Connect the A value to I1 and the B value to I0. */ lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); edif_cellref_pstring(lut, "INIT", "D"); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I2); return; } /* Handle the case where the device is two slices wide. In this case, we can use a LUT4 to do all the calculation. Use this truth table: Q AA BB --+------ 1 | 00 00 0 | 00 01 0 | 00 10 0 | 00 11 1 | 01 00 1 | 01 01 0 | 01 10 0 | 01 11 1 | 10 00 1 | 10 01 1 | 10 10 0 | 10 11 1 | 11 xx The I3-I0 inputs are A1 A0 B1 B0 in that order. */ assert(ivl_lpm_width(net) >= 2); lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib)); edif_cellref_pstring(lut, "INIT", "F731"); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I2); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 1)); edif_add_to_joint(jnt, lut, LUT_I3); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 1)); edif_add_to_joint(jnt, lut, LUT_I1); /* There are only two slices, so this is all we need. */ if (ivl_lpm_width(net) == 2) { jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); return; } /* The general case requires that we make the >= comparator from slices. This is an iterative design. Each slice has the truth table: An Bn | A >= B ------+------- 0 0 | CI 0 1 | 0 1 0 | 1 1 1 | CI The CI for each slice is the output of the compare of the next less significant bits. We get this truth table by connecting a LUT2 to the S input of a MUXCY. When the S input is (1), it propagates its CI. This suggests that the init value for the LUT be "9" (XNOR). When the MUXCY S input is 0, it propagates a local input. We connect to that input An, and we get the desired and complete truth table for a slice. This iterative definition needs to terminate at the least significant bits. In fact, we have a non-iterative was to deal with the two least significant slices. We take the output of the LUT4 device for the least significant bits, and use that to generate the initial CI for the chain. */ muxcy_prev = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib)); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, lut, LUT_O); edif_add_to_joint(jnt, muxcy_prev, MUXCY_S); { edif_cellref_t p0 = edif_cellref_create(edf, cell_0); edif_cellref_t p1 = edif_cellref_create(edf, cell_1); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, p0, 0); edif_add_to_joint(jnt, muxcy_prev, MUXCY_DI); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, p1, 0); edif_add_to_joint(jnt, muxcy_prev, MUXCY_CI); } for (idx = 2 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_cellref_t muxcy; lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); muxcy = edif_cellref_create(edf, xilinx_cell_muxcy(xlib)); edif_cellref_pstring(lut, "INIT", "9"); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, lut, LUT_O); edif_add_to_joint(jnt, muxcy, MUXCY_S); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxcy, MUXCY_CI); edif_add_to_joint(jnt, muxcy_prev, MUXCY_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, lut, LUT_I0); edif_add_to_joint(jnt, muxcy, MUXCY_DI); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx)); edif_add_to_joint(jnt, lut, LUT_I1); muxcy_prev = muxcy; } jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, muxcy_prev, MUXCY_O); } /* * A 4-input N-wide mux can be made on Virtex devices using MUXF5 and * LUT devices. The MUXF5 selects a LUT device (and is connected to * S[1]) and the LUT devices, connected to S[0], select the input. */ static void virtex_mux4(ivl_lpm_t net) { unsigned idx; assert(ivl_lpm_selects(net) == 2); for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_joint_t jnt; edif_cellref_t lut01; edif_cellref_t lut23; edif_cellref_t muxf5; lut01 = edif_cellref_create(edf, xilinx_cell_lut3(xlib)); edif_cellref_pstring(lut01, "INIT", "CA"); lut23 = edif_cellref_create(edf, xilinx_cell_lut3(xlib)); edif_cellref_pstring(lut23, "INIT", "CA"); muxf5 = edif_cellref_create(edf, xilinx_cell_muxf5(xlib)); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 0, idx)); edif_add_to_joint(jnt, lut01, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 1, idx)); edif_add_to_joint(jnt, lut01, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 2, idx)); edif_add_to_joint(jnt, lut23, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 3, idx)); edif_add_to_joint(jnt, lut23, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 0)); edif_add_to_joint(jnt, lut01, LUT_I2); edif_add_to_joint(jnt, lut23, LUT_I2); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxf5, MUXF_I0); edif_add_to_joint(jnt, lut01, LUT_O); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxf5, MUXF_I1); edif_add_to_joint(jnt, lut23, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, muxf5, MUXF_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 1)); edif_add_to_joint(jnt, muxf5, MUXF_S); } } void virtex_mux(ivl_lpm_t net) { switch (ivl_lpm_selects(net)) { case 2: virtex_mux4(net); break; default: xilinx_mux(net); break; } } /* * This function generates ADD/SUB devices for Virtex devices, * based on the documented implementations of ADD8/ADD16, etc., from * the Libraries Guide. * * Each slice of the ADD/SUB device is made from a LUT2 device, an * XORCY device that mixes with the LUT2 to make a full adder, and a * MUXCY_L to propagate the carry. The most significant slice does not * have a carry to propagate, so has no MUXCY_L. * * If the device is a wide adder, then the LUT2 devices are configured * to implement an XOR function and a zero is pumped into the least * significant carry input. * * If the device is really an adder, then the input is turned into an * XNOR, which takes a 1-s complement of the B input. Pump a 1 into * the LSB carry input to finish converting the B input into the 2s * complement. */ void virtex_add(ivl_lpm_t net) { const char*ha_init = 0; edif_cellref_t lut, xorcy, muxcy, pad; edif_joint_t jnt; unsigned idx; if (ivl_lpm_width(net) < 2) { xilinx_add(net); return; } switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: ha_init = "6"; break; case IVL_LPM_SUB: ha_init = "9"; break; default: assert(0); } assert(ivl_lpm_width(net) > 1); lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib)); muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib)); edif_cellref_pstring(lut, "INIT", ha_init); /* The bottom carry-in takes a constant that primes the add or subtract. */ switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: pad = edif_cellref_create(edf, cell_0); break; case IVL_LPM_SUB: pad = edif_cellref_create(edf, cell_1); break; default: assert(0); } jnt = edif_joint_create(edf); edif_add_to_joint(jnt, pad, 0); edif_add_to_joint(jnt, muxcy, MUXCY_CI); edif_add_to_joint(jnt, xorcy, XORCY_CI); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, xorcy, XORCY_O); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, xorcy, XORCY_LI); edif_add_to_joint(jnt, muxcy, MUXCY_S); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I0); edif_add_to_joint(jnt, muxcy, MUXCY_DI); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I1); for (idx = 1 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_cellref_t muxcy0 = muxcy; lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); xorcy = edif_cellref_create(edf, xilinx_cell_xorcy(xlib)); edif_cellref_pstring(lut, "INIT", ha_init); /* If this is the last bit, then there is no further propagation in the carry chain, and I can skip the carry mux MUXCY. */ if ((idx+1) < ivl_lpm_width(net)) muxcy = edif_cellref_create(edf, xilinx_cell_muxcy_l(xlib)); else muxcy = 0; jnt = edif_joint_create(edf); edif_add_to_joint(jnt, muxcy0, MUXCY_O); edif_add_to_joint(jnt, xorcy, XORCY_CI); if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_CI); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, xorcy, XORCY_O); jnt = edif_joint_create(edf); edif_add_to_joint(jnt, xorcy, XORCY_LI); if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_S); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, idx)); edif_add_to_joint(jnt, lut, LUT_I0); if (muxcy) edif_add_to_joint(jnt, muxcy, MUXCY_DI); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, idx)); edif_add_to_joint(jnt, lut, LUT_I1); } } const struct device_s d_virtex_edif = { virtex_show_header, xilinx_show_footer, xilinx_show_scope, xilinx_pad, virtex_logic, virtex_generic_dff, virtex_eq, virtex_eq, virtex_ge, 0, /* show_cmp_gt */ virtex_mux, virtex_add, virtex_add, xilinx_shiftl, 0 /* show_shiftr */ }; iverilog-12_0/tgt-fpga/d-virtex2.c000066400000000000000000000050711435245347300170530ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "device.h" # include "fpga_priv.h" # include "edif.h" # include "generic.h" # include "xilinx.h" # include # include # include /* * This is a table of cell types that are accessible via the cellref * attribute to a gate. */ const static struct edif_xlib_celltable virtex2_celltable[] = { { "BUFG", xilinx_cell_bufg }, { "MULT_AND", xilinx_cell_mult_and }, { 0, 0} }; /* * The show_header function is called before any of the devices of the * netlist are scanned. * * In this function, we look at the ports of the root module to decide * if they are to be made into ports. Modules that have PAD attributes * are *not* to be used as ports, they will be connected to special * PAD devices instead. */ static void virtex2_show_header(ivl_design_t des) { const char*part_str = 0; xilinx_common_header(des); xlib = edif_xlibrary_create(edf, "VIRTEX2"); edif_xlibrary_set_celltable(xlib, virtex2_celltable); if ( (part_str = ivl_design_flag(des, "part")) && (part_str[0] != 0) ) { edif_pstring(edf, "PART", part_str); } cell_0 = edif_xcell_create(xlib, "GND", 1); edif_cell_portconfig(cell_0, 0, "GROUND", IVL_SIP_OUTPUT); cell_1 = edif_xcell_create(xlib, "VCC", 1); edif_cell_portconfig(cell_1, 0, "VCC", IVL_SIP_OUTPUT); } const struct device_s d_virtex2_edif = { virtex2_show_header, xilinx_show_footer, xilinx_show_scope, xilinx_pad, virtex_logic, virtex_generic_dff, virtex_eq, virtex_eq, virtex_ge, 0, /* show_cmp_gt */ virtex_mux, virtex_add, virtex_add, xilinx_shiftl, /* show_shiftl */ 0 /* show_shiftr */ }; iverilog-12_0/tgt-fpga/device.h000066400000000000000000000055271435245347300165010ustar00rootroot00000000000000#ifndef IVL_device_H #define IVL_device_H /* * Copyright (c) 2001-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 /* * This code generator supports a variety of device types. It does * this by keeping a device "driver" structure for each device * type. The device structure contains pointers to functions that emit * the proper XNF for a given type of device. * * If a device supports a method, the function pointer is filled in * with a pointer to the proper function. * * If a device does not support the method, then the pointer is null. */ typedef const struct device_s* device_t; struct device_s { /* These methods draw leading and trailing format text. */ void (*show_header)(ivl_design_t des); void (*show_footer)(ivl_design_t des); /* Draw scopes marked by ivl_synthesis_cell */ void (*show_cell_scope)(ivl_scope_t net); /* Draw pads connected to the specified signal. */ void (*show_pad)(ivl_signal_t sig, const char*str); /* Draw basic logic devices. */ void (*show_logic)(ivl_net_logic_t net); /* This method emits a D type Flip-Flop */ void (*show_dff)(ivl_lpm_t net); /* These methods show various comparators */ void (*show_cmp_eq)(ivl_lpm_t net); void (*show_cmp_ne)(ivl_lpm_t net); void (*show_cmp_ge)(ivl_lpm_t net); void (*show_cmp_gt)(ivl_lpm_t net); /* This method draws MUX devices */ void (*show_mux)(ivl_lpm_t net); /* This method draws ADD devices */ void (*show_add)(ivl_lpm_t net); void (*show_sub)(ivl_lpm_t net); /* These methods draw SHIFT devices */ void (*show_shiftl)(ivl_lpm_t net); void (*show_shiftr)(ivl_lpm_t net); /* Multipliers */ void (*show_mult)(ivl_lpm_t net); /* Constants */ void (*show_constant)(ivl_net_const_t net); }; /* * Return the device_t cookie given the name of the architecture. If * the device is not found, return 0. * * This function is used if the user specifies the architecture * explicitly, with the -parch=name flag. */ extern device_t device_from_arch(const char*arch); #endif /* IVL_device_H */ iverilog-12_0/tgt-fpga/edif.c000066400000000000000000000370161435245347300161420ustar00rootroot00000000000000/* * Copyright (c) 2003-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 "edif.h" # include # include # include # include "ivl_alloc.h" typedef enum property_e { PRP_NONE = 0, PRP_STRING, PRP_INTEGER } property_t; struct cellref_property_ { const char*name; property_t ptype; union { const char*str; long num; } value_; struct cellref_property_*next; }; struct edif_s { const char*name; /* List the ports of the design. */ unsigned nports; struct __cell_port*ports; /* All the external libraries attached to me. */ edif_xlibrary_t xlibs; /* list the cellref instances. */ edif_cellref_t celref; /* The root instance has cellref properties as well. */ struct cellref_property_*property; /* Keep a list of all the nexa */ struct edif_joint_s*nexa; }; struct edif_xlibrary_s { /* Name of this library. */ const char*name; /* The cells that are contained in this library. */ struct edif_cell_s*cells; /* point to the optional celltable. */ const struct edif_xlib_celltable*celltable; /* used to list libraries in an edif_t. */ struct edif_xlibrary_s*next; }; struct __cell_port { const char*name; const char*ename; struct cellref_property_*property; ivl_signal_port_t dir; }; struct edif_cell_s { const char*name; edif_xlibrary_t xlib; unsigned nports; struct __cell_port*ports; struct cellref_property_*property; struct edif_cell_s*next; }; struct edif_cellref_s { struct edif_cell_s* cell; unsigned u; struct cellref_property_*property; struct edif_cellref_s* next; }; struct joint_cell_ { struct edif_cellref_s*cell; unsigned port; struct joint_cell_*next; }; struct edif_joint_s { const char*name; struct joint_cell_*links; struct edif_joint_s*next; }; static int is_edif_name(const char*text) { static const char*edif_name_chars = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; return (strspn(text, edif_name_chars) == strlen(text)); } edif_t edif_create(const char*design_name, unsigned nports) { edif_t edf = malloc(sizeof(struct edif_s)); edf->name = design_name; edf->nports= nports; edf->ports = nports? calloc(nports, sizeof(struct __cell_port)) : 0; edf->celref= 0; edf->xlibs = 0; edf->property = 0; edf->nexa = 0; return edf; } void edif_portconfig(edif_t edf, unsigned idx, const char*name, ivl_signal_port_t dir) { assert(idx < edf->nports); edf->ports[idx].name = name; if (is_edif_name(name)) { edf->ports[idx].ename = 0; } else { char buf[16]; sprintf(buf, "PORT%u", idx); edf->ports[idx].ename = strdup(buf); } edf->ports[idx].dir = dir; } void edif_port_to_joint(edif_joint_t jnt, edif_t edf, unsigned port) { struct joint_cell_* jc = malloc(sizeof(struct joint_cell_)); jc->cell = 0; jc->port = port; jc->next = jnt->links; jnt->links = jc; } void edif_pstring(edif_t edf, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_STRING; prp->value_.str = value; prp->next = edf->property; edf->property = prp; } edif_xlibrary_t edif_xlibrary_create(edif_t edf, const char*name) { edif_xlibrary_t xlib = malloc(sizeof(struct edif_xlibrary_s)); xlib->name = name; xlib->cells = 0; xlib->celltable = 0; xlib->next = edf->xlibs; edf->xlibs = xlib; return xlib; } void edif_xlibrary_set_celltable(edif_xlibrary_t xlib, const struct edif_xlib_celltable*tab) { assert(xlib->celltable == 0); xlib->celltable = tab; } edif_cell_t edif_xlibrary_findcell(edif_xlibrary_t xlib, const char*cell_name) { const struct edif_xlib_celltable*tcur; edif_cell_t cur; for (cur = xlib->cells ; cur ; cur = cur->next) { if (strcmp(cell_name, cur->name) == 0) return cur; } if (xlib->celltable == 0) return 0; for (tcur = xlib->celltable ; tcur->cell_name ; tcur += 1) if (strcmp(cell_name, tcur->cell_name) == 0) { return (tcur->cell_func)(xlib); } return 0; } edif_cell_t edif_xlibrary_scope_cell(edif_xlibrary_t xlib, ivl_scope_t scope) { unsigned port_count, idx; edif_cell_t cur; /* Check to see if the cell is already somehow defined. */ cur = edif_xlibrary_findcell(xlib, ivl_scope_tname(scope)); if (cur) return cur; /* Count the ports of the scope. */ port_count = 0; for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; port_count += 1; } cur = edif_xcell_create(xlib, ivl_scope_tname(scope), port_count); port_count = 0; for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; edif_cell_portconfig(cur, port_count, ivl_signal_basename(sig), ivl_signal_port(sig)); port_count += 1; } return cur; } edif_cell_t edif_xcell_create(edif_xlibrary_t xlib, const char*name, unsigned nports) { unsigned idx; edif_cell_t cell = malloc(sizeof(struct edif_cell_s)); cell->name = name; cell->xlib = xlib; cell->nports = nports; cell->ports = calloc(nports, sizeof(struct __cell_port)); cell->property = 0; for (idx = 0 ; idx < nports ; idx += 1) { cell->ports[idx].name = "?"; cell->ports[idx].dir = IVL_SIP_NONE; cell->ports[idx].property = 0; } cell->next = xlib->cells; xlib->cells = cell; return cell; } void edif_cell_portconfig(edif_cell_t cell, unsigned idx, const char*name, ivl_signal_port_t dir) { assert(idx < cell->nports); cell->ports[idx].name = name; cell->ports[idx].dir = dir; } void edif_cell_port_pstring(edif_cell_t cell, unsigned idx, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_STRING; prp->value_.str = value; prp->next = cell->ports[idx].property; cell->ports[idx].property = prp; } unsigned edif_cell_port_byname(edif_cell_t cell, const char*name) { unsigned idx = 0; for (idx = 0 ; idx < cell->nports ; idx += 1) if (strcmp(name, cell->ports[idx].name) == 0) break; return idx; } void edif_cell_pstring(edif_cell_t cell, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_STRING; prp->value_.str = value; prp->next = cell->property; cell->property = prp; } void edif_cell_pinteger(edif_cell_t cell, const char*name, int value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_INTEGER; prp->value_.num = value; prp->next = cell->property; cell->property = prp; } edif_cellref_t edif_cellref_create(edif_t edf, edif_cell_t cell) { static unsigned u_number = 0; edif_cellref_t ref = malloc(sizeof(struct edif_cellref_s)); u_number += 1; assert(cell); assert(edf); ref->u = u_number; ref->cell = cell; ref->property = 0; ref->next = edf->celref; edf->celref = ref; return ref; } void edif_cellref_pstring(edif_cellref_t ref, const char*name, const char*value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_STRING; prp->value_.str = value; prp->next = ref->property; ref->property = prp; } void edif_cellref_pinteger(edif_cellref_t ref, const char*name, int value) { struct cellref_property_*prp = malloc(sizeof(struct cellref_property_)); prp->name = name; prp->ptype = PRP_INTEGER; prp->value_.num = value; prp->next = ref->property; ref->property = prp; } edif_joint_t edif_joint_create(edif_t edf) { edif_joint_t jnt = malloc(sizeof(struct edif_joint_s)); jnt->name = 0; jnt->links = 0; jnt->next = edf->nexa; edf->nexa = jnt; return jnt; } edif_joint_t edif_joint_of_nexus(edif_t edf, ivl_nexus_t nex) { void*tmp = ivl_nexus_get_private(nex); edif_joint_t jnt; if (tmp == 0) { jnt = edif_joint_create(edf); ivl_nexus_set_private(nex, jnt); return jnt; } jnt = (edif_joint_t) tmp; return jnt; } void edif_joint_rename(edif_joint_t jnt, const char*name) { assert(jnt->name == 0); jnt->name = name; } void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port) { struct joint_cell_* jc = malloc(sizeof(struct joint_cell_)); jc->cell = cell; jc->port = port; jc->next = jnt->links; jnt->links = jc; } static void fprint_property(FILE*fd, const struct cellref_property_*prp) { fprintf(fd, "(property %s ", prp->name); switch (prp->ptype) { case PRP_NONE: break; case PRP_STRING: fprintf(fd, "(string \"%s\")", prp->value_.str); break; case PRP_INTEGER: fprintf(fd, "(integer %ld)", prp->value_.num); break; } fprintf(fd, ")"); } /* * This function takes all the data structures that have been * assembled by the code generator, and writes them into an EDIF * formatted file. */ void edif_print(FILE*fd, edif_t edf) { edif_xlibrary_t xlib; edif_cell_t cell; edif_cellref_t ref; edif_joint_t jnt; struct cellref_property_*prp; unsigned idx; fprintf(fd, "(edif %s\n", edf->name); fprintf(fd, " (edifVersion 2 0 0)\n"); fprintf(fd, " (edifLevel 0)\n"); fprintf(fd, " (keywordMap (keywordLevel 0))\n"); fprintf(fd, " (status\n"); fprintf(fd, " (written\n"); fprintf(fd, " (timeStamp 0 0 0 0 0 0)\n"); fprintf(fd, " (author \"unknown\")\n"); fprintf(fd, " (program \"Icarus Verilog/fpga.tgt\")))\n"); fflush(fd); for (xlib = edf->xlibs ; xlib ; xlib = xlib->next) { fprintf(fd, " (external %s " "(edifLevel 0) " "(technology (numberDefinition))\n", xlib->name); for (cell = xlib->cells ; cell ; cell = cell->next) { fprintf(fd, " (cell %s (cellType GENERIC)\n", cell->name); fprintf(fd, " (view net\n" " (viewType NETLIST)\n" " (interface"); for (idx = 0 ; idx < cell->nports ; idx += 1) { struct __cell_port*pp = cell->ports + idx; fprintf(fd, "\n (port %s", pp->name); switch (pp->dir) { case IVL_SIP_INPUT: fprintf(fd, " (direction INPUT)"); break; case IVL_SIP_OUTPUT: fprintf(fd, " (direction OUTPUT)"); break; case IVL_SIP_INOUT: fprintf(fd, " (direction INOUT)"); break; default: break; } for (prp = pp->property ; prp ; prp=prp->next) { fprintf(fd, " "); fprint_property(fd, prp); } fprintf(fd, ")"); } for (prp = cell->property ; prp ; prp = prp->next) { fprintf(fd, "\n "); fprint_property(fd, prp); } fprintf(fd, ")))\n"); } fprintf(fd, " )\n"); /* terminate (external ...) sexp */ } fflush(fd); /* Write out the library header */ fprintf(fd, " (library DESIGN\n"); fprintf(fd, " (edifLevel 0)\n"); fprintf(fd, " (technology (numberDefinition))\n"); /* The root module is a cell in the library. */ fprintf(fd, " (cell %s\n", edf->name); fprintf(fd, " (cellType GENERIC)\n"); fprintf(fd, " (view net\n"); fprintf(fd, " (viewType NETLIST)\n"); fprintf(fd, " (interface\n"); for (idx = 0 ; idx < edf->nports ; idx += 1) { fprintf(fd, " (port "); if (edf->ports[idx].ename == 0) fprintf(fd, "%s ", edf->ports[idx].name); else fprintf(fd, "(rename %s \"%s\") ", edf->ports[idx].ename, edf->ports[idx].name); switch (edf->ports[idx].dir) { case IVL_SIP_INPUT: fprintf(fd, "(direction INPUT)"); break; case IVL_SIP_OUTPUT: fprintf(fd, "(direction OUTPUT)"); break; case IVL_SIP_INOUT: fprintf(fd, "(direction INOUT)"); break; default: break; } fprintf(fd, ")\n"); } fprintf(fd, " )\n"); /* end the (interface ) sexp */ fflush(fd); fprintf(fd, " (contents\n"); /* Display all the instances. */ for (ref = edf->celref ; ref ; ref = ref->next) { assert(ref->cell); fprintf(fd, "(instance U%u (viewRef net " "(cellRef %s (libraryRef %s)))", ref->u, ref->cell->name, ref->cell->xlib->name); for (prp = ref->property ; prp ; prp = prp->next) { fprintf(fd, " "); fprint_property(fd, prp); } fprintf(fd, ")\n"); } fflush(fd); /* Display all the joints. */ idx = 0; for (jnt = edf->nexa ; jnt ; jnt = jnt->next, idx += 1) { struct joint_cell_*jc; fprintf(fd, "(net "); if (jnt->name != 0) fprintf(fd, "(rename N%u \"%s\")", idx, jnt->name); else fprintf(fd, "N%u", idx); fprintf(fd, " (joined"); for (jc = jnt->links ; jc ; jc = jc->next) { if (jc->cell) { fprintf(fd, " (portRef %s (instanceRef U%u))", jc->cell->cell->ports[jc->port].name, jc->cell->u); } else { /* Reference to a port of the main cell. */ if (edf->ports[jc->port].ename) fprintf(fd, " (portRef %s)", edf->ports[jc->port].ename); else fprintf(fd, " (portRef %s)", edf->ports[jc->port].name); } } fprintf(fd, "))\n"); } fprintf(fd, " )\n"); /* end the (contents...) sexp */ fprintf(fd, " )\n"); /* end the (view ) sexp */ fprintf(fd, " )\n"); /* end the (cell ) sexp */ fprintf(fd, " )\n"); /* end the (library DESIGN) sexp */ /* Make an instance of the defined object */ fprintf(fd, " (design %s\n", edf->name); fprintf(fd, " (cellRef %s (libraryRef DESIGN))\n", edf->name); for (prp = edf->property ; prp ; prp = prp->next) { fprintf(fd, " "); fprint_property(fd, prp); fprintf(fd, "\n"); } fprintf(fd, " )\n"); fprintf(fd, ")\n"); fflush(fd); } iverilog-12_0/tgt-fpga/edif.h000066400000000000000000000224701435245347300161450ustar00rootroot00000000000000#ifndef IVL_edif_H #define IVL_edif_H /* * Copyright (c) 2003-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 # include /* * These types and functions support the task of generating and * writing out an EDIF 2 0 0 netlist. These functions work by * supporting the creation of an in-core netlist of the design, then * writing the netlist out all at once. The library manages cells with * ports, but does not otherwise interpret cells. They have no * contents. * * The general structure of netlist creation is as follows: * * Create a netlist with edif_create(); * This creates an edif object that represents the design. The * design is given a name, and that name becomes the name of the * single cell that this netlist handles. * * Add ports to the root with edif_portconfig * The design may, if it is a macro to be included in a larger * design, include ports. These are discovered by looking for port * signals in the root module. * * Declare external libraries with edif_xlibrary_create * Normally, this is the single technology library that contains * the primitive cells that the code generator intends to * use. The library is given a name, such as VIRTEX or whatever * the implementation tools expect. Cells are attached to the * library later. An edif netlist may include multiple external * references. * * Declare primitives with edif_xcell_create and edif_cell_portconfig. * These functions create CELL TYPES that are attached to an * external library. The libraries are created by * edif_xlibrary_create. * * Cells can be created at any time before their first use. It * therefore makes the most sense to not create the cell until it * is certain that they are needed by the design. * * Create instances and join them up * The edif_cellref_t objects represent instances of cells, and * are the devices of the generated netlist. These cellrefs are * connected together by the use of edif_joint_t joints. The * joints can be created from ivl_nexus_t objects, or from their * own ether. This instantiating of cells and joining them * together that is the most fun. It is the technology specific * stuff that the code generator does. * * Finally, print the result with edif_print(fd); * This function writes the netlist in memory to an EDIF file on * the stdio stream specified. * * This library is intended to be used once, to build up a netlist and * print it. All the names that are taken as const char* should be * somehow made permanent by the caller. Either they are constant * strings, or they are strduped as necessary to make them * permanent. The library will not duplicate them. */ /* TYPE DECLARATIONS */ /* This represents the entire EDIF design. You only need one of these to hold everything. */ typedef struct edif_s* edif_t; /* Each external library of the design gets one of these. */ typedef struct edif_xlibrary_s* edif_xlibrary_t; /* This represents a type of cell. */ typedef struct edif_cell_s* edif_cell_t; /* A cellref is an *instance* of a cell. */ typedef struct edif_cellref_s* edif_cellref_t; /* This represents a generic joint. Cell ports are connected by being associated with a joint. These can be bound to an ivl_nexus_t object, of stand along. */ typedef struct edif_joint_s* edif_joint_t; /* This structure defines a table that can be attached to an xlibrary to incorporate black-box cells to the library. The cell_name is the name that may be passed to the edif_xlibrary_findcell function, and the function pointer points to a function that creates the cell and defines ports for it. A real celltable is terminated by an entry with a null pointer for the cell_name. */ struct edif_xlib_celltable { const char*cell_name; edif_cell_t (*cell_func)(edif_xlibrary_t xlib); }; /* FUNCTIONS */ /* Start a new EDIF design. The design_name will be used as the name of the top-mode module of the design. */ extern edif_t edif_create(const char*design_name, unsigned nports); /* macro ports to the design are handled by this library similar to cells. The user creates ports with this function. This function configures the sole "port" of the cell with the name and dir passed in. The direction, in this case, is the *interface* direction. */ extern void edif_portconfig(edif_t edf, unsigned idx, const char*name, ivl_signal_port_t dir); /* This is like edif_add_to_joint, but works with the edif port. */ extern void edif_port_to_joint(edif_joint_t jnt, edif_t edf, unsigned port); /* The design may have properties attached to it. These properties will be attached to the instance declared in the footer of the EDIF file. */ extern void edif_pstring(edif_t edf, const char*name, const char*value); /* Create an external library and attach it to the edif design. This will lead to a (external ...) declaration of cells that can be used by the design. */ extern edif_xlibrary_t edif_xlibrary_create(edif_t edf, const char*name); extern void edif_xlibrary_set_celltable(edif_xlibrary_t lib, const struct edif_xlib_celltable*table); /* External libraries can be searched for existing cells, given a string name. This function searches for the cell by name, and returns it. */ extern edif_cell_t edif_xlibrary_findcell(edif_xlibrary_t lib, const char*cell_name); /* Similar to the above, but it gets the information it needs from the ivl_scope_t object. */ extern edif_cell_t edif_xlibrary_scope_cell(edif_xlibrary_t xlib, ivl_scope_t scope); /* Create a new cell, attached to the external library. Specify the number of ports that the cell has. The edif_cell_portconfig function is then used to assign name and direction to each of the ports. The cell has a number of pins that are referenced by their number from 0 to nports-1. You need to remember the pin numbers for the named ports for use when joining that pin to an edif_joint_t. Cellrefs get their port characteristics from the cell that they are created from. So the pinouts of cellrefs match the pinout of the associated cell. */ extern edif_cell_t edif_xcell_create(edif_xlibrary_t, const char*name, unsigned nports); extern void edif_cell_portconfig(edif_cell_t cell, unsigned idx, const char*name, ivl_signal_port_t dir); /* Attach a property to a cell port. */ extern void edif_cell_port_pstring(edif_cell_t cell, unsigned idx, const char*name, const char*value); /* Cells may have properties attached to them. These properties are included in the library declaration for the cell, instead of the cell instances. */ extern void edif_cell_pstring(edif_cell_t cell, const char*name, const char*value); extern void edif_cell_pinteger(edif_cell_t cell, const char*name, int value); /* Ports of cells are normally referenced by their port number. If you forget what that number is, this function can look it up by name. */ extern unsigned edif_cell_port_byname(edif_cell_t cell, const char*name); /* Create and instance from a cell. The instance refers to the cell, which is a type, and contains pips for pins. */ extern edif_cellref_t edif_cellref_create(edif_t edf, edif_cell_t cell); /* Instances can have properties attached to them. The name and value given here are turned into a (property (string "val")) expression attached to the instance. Examples of string properties commonly attached to cellref devices include such things as the INIT= to initialize LUT cells in FPGA devices. */ extern void edif_cellref_pstring(edif_cellref_t ref, const char*name, const char*value); extern void edif_cellref_pinteger(edif_cellref_t ref, const char*name, int value); /* This function gets the joint associated with a nexus. This will create a joint if necessary. */ extern edif_joint_t edif_joint_of_nexus(edif_t edf, ivl_nexus_t nex); /* For linking cells outside the ivl netlist, this function creates an anonymous joint. */ extern edif_joint_t edif_joint_create(edif_t edf); /* Renaming a joint causes it to take on a name when external tools view the EDIF file. */ extern void edif_joint_rename(edif_joint_t jnt, const char*name); /* Given a joint, this function adds the cell reference. */ extern void edif_add_to_joint(edif_joint_t jnt, edif_cellref_t cell, unsigned port); /* * Print the entire design. This should only be done after the design * is completely assembled. */ extern void edif_print(FILE*fd, edif_t design); #endif /* IVL_edif_H */ iverilog-12_0/tgt-fpga/fpga-s.conf000066400000000000000000000001471435245347300171060ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle -t:dll flag:DLL=fpga.tgt iverilog-12_0/tgt-fpga/fpga.c000066400000000000000000000075611435245347300161520ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "config.h" /* * This is the FPGA target module. */ # include # include # include "fpga_priv.h" # include /* This is the opened xnf file descriptor. It is the output that this code generator writes to. */ FILE*xnf = 0; const char*part = 0; const char*arch = 0; device_t device = 0; int scope_has_attribute(ivl_scope_t s, const char *name) { int i; for (i=0; ikey,name) == 0) return 1; } return 0; } static int show_process(ivl_process_t net, void*x) { ivl_scope_t scope = ivl_process_scope(net); /* Ignore processes that are within scopes that are cells. The cell_scope will generate a cell to represent the entire scope. */ if (scope_has_attribute(scope, "ivl_synthesis_cell")) return 0; fprintf(stderr, "fpga target: unsynthesized behavioral code\n"); return 0; } static void show_pads(ivl_scope_t scope) { unsigned idx; if (device->show_pad == 0) return; for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); const char*pad; if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; pad = ivl_signal_attr(sig, "PAD"); if (pad == 0) continue; assert(device->show_pad); device->show_pad(sig, pad); } } static void show_constants(ivl_design_t des) { unsigned idx; if (device->show_constant == 0) return; for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { ivl_net_const_t con = ivl_design_const(des, idx); device->show_constant(con); } } /* * This is the main entry point that ivl uses to invoke me, the code * generator. */ int target_design(ivl_design_t des) { ivl_scope_t root = ivl_design_root(des); const char*path = ivl_design_flag(des, "-o"); xnf = fopen(path, "w"); if (xnf == 0) { perror(path); return -1; } part = ivl_design_flag(des, "part"); if (part && (part[0] == 0)) part = 0; arch = ivl_design_flag(des, "arch"); if (arch && (arch[0] == 0)) arch = 0; if (arch == 0) arch = "lpm"; device = device_from_arch(arch); if (device == 0) { fprintf(stderr, "Unknown architecture arch=%s\n", arch); return -1; } /* Call the device driver to generate the netlist header. */ device->show_header(des); /* Catch any behavioral code that is left, and write warnings that it is not supported. */ ivl_design_process(des, show_process, 0); /* Get the pads from the design, and draw them to connect to the associated signals. */ show_pads(root); /* Scan the scopes, looking for gates to draw into the output netlist. */ show_scope_gates(root, 0); show_constants(des); /* Call the device driver to close out the file. */ device->show_footer(des); fclose(xnf); xnf = 0; return 0; } iverilog-12_0/tgt-fpga/fpga.conf000066400000000000000000000001471435245347300166460ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle -t:dll flag:DLL=fpga.tgt iverilog-12_0/tgt-fpga/fpga.txt000066400000000000000000000142531435245347300165430ustar00rootroot00000000000000 FPGA LOADABLE CODE GENERATOR FOR Icarus Verilog Copyright 2001 Stephen Williams The FPGA code generator supports a variety of FPGA devices, writing XNF or EDIF depending on the target. You can select the architecture of the device, and the detailed part name. The architecture is used to select library primitives, and the detailed part name is written into the generated file for the use of downstream tools. INVOKING THE FPGA TARGET The code generator is invoked with the -tfpga flag to iverilog. It understands the part= and the arch= parameters, which can be set with the -p flag of iverilog: iverilog -parch=virtex -ppart=v50-pq240-6 -tfpga foo.vl This example selects the Virtex architecture, and give the detailed part number as v50-pq240-6. The output is written into a.out unless a different output file is specified with the -o flag. The following is a list of architecture types that this code generator supports. * arch=lpm This is a device independent format, where the gates are device types as defined by the LPM 2 1 0 specification. Some backend tools may take this format, or users may write interface libraries to connect these netlists to the device in question. * arch=generic-edif (obsolete) This is generic EDIF code. It doesn't necessarily work because the external library is not available to the code generator. But, what it does is generate generic style gates that a portability library can map to target gates if desired. * arch=generic-xnf (obsolete) If this is selected, then the output is formatted as an XNF file, suitable for most any type of device. The devices that it emits are generic devices from the unified library. Some devices are macros, you may need to further resolve the generated XNF to get working code for your part. * arch=virtex If this is selected, then the output is formatted as an EDIF 200 file, suitable for Virtex class devices. This is supposed to know that you are targeting a Virtex part, so can generate primitives instead of using external macros. It includes the VIRTEX internal library, and should work properly for any Virtex part. * arch=virtex2 If this is selected, then the output is EDIF 2 0 0 suitable for Virtex-II and Virtex-II Pro devices. It uses the VIRTEX2 library, but is very similar to the Virtex target. XNF ROOT PORTS NOTE: As parts are moved over to EDIF format, XNF support will be phased out. Current Xilinx implementation tools will accept EDIF format files even for the older parts, and non-Xilinx implementation tools accept nothing else. When the output format is XNF, the code generator will generate "SIG" records for the signals that are ports of the root module. The name is declared as an external pin that this macro makes available. The name given to the macro pin is generated from the base name of the signal. If the signal is one bit wide, then the pin name is exactly the module port name. If the port is a vector, then the pin number is given as a vector. For example, the module: module main(out, in); output out; input [2:0] in; [...] endmodule leads to these SIG, records: SIG, main/out, PIN=out SIG, main/in<2>, PIN=in2 SIG, main/in<1>, PIN=in1 SIG, main/in<0>, PIN=in0 EDIF ROOT PORTS The EDIF format is more explicit about the interface into an EDIF file. The code generator uses that control to generate an explicit interface definition into the design. (This is *not* the same as the PADS of a part.) The generated EDIF interface section contains port definitions, including the proper direction marks. With the (rename ...) s-exp in EDIF, it is possible to assign arbitrary text to port names. The EDIF code generator therefore does not resort to the mangling that is needed for the XNF target. The base name of the signal that is an input or output is used as the name of the port, complete with the proper case. However, since the ports are single bit ports, the name of vectors includes the string "[0]" where the number is the bit number. For example, the module: module main(out, in); output out; input [2:0] in; [...] endmodule creates these ports: out OUTPUT in[0] INPUT in[1] INPUT in[2] INPUT Target tools, including Xilinx Foundation tools, understand the [] characters in the name and recollect the signals into a proper bus when presenting the vector to the user. PADS AND PIN ASSIGNMENT The ports of a root module may be assigned to specific pins, or to a generic pad. If a signal (that is a port) has a PAD attribute, then the value of that attribute is a list of locations, one for each bit of the signal, that specifies the pin for each bit of the signal. For example: module main( (* PAD = "P10" *) output out, (* PAD = "P20,P21,P22" *) input [2:0] in); [...] endmodule In this example, port ``out'' is assigned to pin 10, and port ``in'' is assigned to pins 20-22. If the architecture supports it, a pin number of 0 means let the back end tools choose a pin. The format of the pin number depends on the architecture family being targeted, so for example Xilinx family devices take the name that is associated with the "LOC" attribute. NOTE: If a module port is assigned to a pin (and therefore attached to a PAD) then it is *not* connected to a port of the EDIF file. This is because the PAD (and possibly IBUF or OBUF) would become an extra driver to the port. An error. SPECIAL DEVICES The code generator supports the "cellref" attribute attached to logic devices to cause specific device types be generated, instead of the usual device that the code generator might generate. For example, to get a clock buffer out of a Verilog buf: buf my_gbuf(out, in); $attribute(my_buf, "cellref", "GBUF:O,I"); The "cellref" attribute tells the code generator to use the given cell. The syntax of the value is: :,... The cell type is the name of the library part to use. The pin names are the names of the type in the library, in the order that the logic device pins are connected. COMPILING WITH XILINX FOUNDATION Compile a single-file design with command line tools like so: % iverilog -parch=virtex -o foo.edf foo.vl % edif2ngd foo.edf foo.ngo % ngdbuild -p v50-pq240 foo.ngo foo.ngd % map -o map.ncd foo.ngd % par -w map.ncd foo.ncd iverilog-12_0/tgt-fpga/fpga_priv.h000066400000000000000000000031451435245347300172110ustar00rootroot00000000000000#ifndef IVL_fpga_priv_H #define IVL_fpga_priv_H /* * Copyright (c) 2001-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 # include "device.h" /* This is the opened xnf file descriptor. It is the output that this code generator writes to, whether the format is XNF or EDIF. */ extern FILE*xnf; extern int show_scope_gates(ivl_scope_t net, void*x); extern device_t device; extern const char*part; extern const char*arch; /* * Attribute lookup, should this be provided in ivl_target.h? */ int scope_has_attribute(ivl_scope_t s, const char *name); /* * These are mangle functions. */ extern void xnf_mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf); extern void xnf_mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf); extern const char*xnf_mangle_nexus_name(ivl_nexus_t net); #endif /* IVL_fpga_priv_H */ iverilog-12_0/tgt-fpga/gates.c000066400000000000000000000104431435245347300163310ustar00rootroot00000000000000/* * Copyright (c) 2001-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 # include "fpga_priv.h" # include static void show_cell_scope(ivl_scope_t scope) { if (device->show_cell_scope == 0) { fprintf(stderr, "fpga.tgt: ivl_synthesis_cell(scope)" " not supported by this target.\n"); return; } device->show_cell_scope(scope); } static void show_gate_logic(ivl_net_logic_t net) { if (device->show_logic == 0) { fprintf(stderr, "fpga.tgt: IVL LOGIC not supported" " by this target.\n"); return; } assert(device->show_logic); device->show_logic(net); } static void show_gate_lpm(ivl_lpm_t net) { switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: if (device->show_add == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_ADD not supported" " by this target.\n"); return; } device->show_add(net); break; case IVL_LPM_SUB: if (device->show_sub == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_SUB not supported" " by this target.\n"); return; } device->show_sub(net); break; case IVL_LPM_CMP_EQ: if (device->show_cmp_eq == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_EQ not supported" " by this target.\n"); return; } device->show_cmp_eq(net); break; case IVL_LPM_CMP_NE: if (device->show_cmp_ne == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_NE not supported" " by this target.\n"); return; } device->show_cmp_ne(net); break; case IVL_LPM_CMP_GE: if (device->show_cmp_ge == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_GE not supported" " by this target.\n"); return; } device->show_cmp_ge(net); break; case IVL_LPM_CMP_GT: if (device->show_cmp_gt == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_CMP_GT not supported" " by this target.\n"); return; } device->show_cmp_gt(net); break; case IVL_LPM_FF: if (device->show_dff == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_FF not supported" " by this target.\n"); return; } device->show_dff(net); break; case IVL_LPM_MUX: if (device->show_mux == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_MUX not supported" " by this target.\n"); return; } device->show_mux(net); break; case IVL_LPM_MULT: if (device->show_mult == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_MULT not supported" " by this target.\n"); return; } device->show_mult(net); break; case IVL_LPM_SHIFTL: if (device->show_shiftl == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_SHIFTL not supported" " by this target.\n"); return; } device->show_shiftl(net); break; case IVL_LPM_SHIFTR: if (device->show_shiftr == 0) { fprintf(stderr, "fpga.tgt: IVL_LPM_SHIFTR not supported" " by this target.\n"); return; } device->show_shiftr(net); break; default: fprintf(stderr, "fpga.tgt: unknown LPM type %d\n", ivl_lpm_type(net)); break; } } int show_scope_gates(ivl_scope_t net, void*x) { unsigned idx; if (scope_has_attribute(net, "ivl_synthesis_cell")) { show_cell_scope(net); return 0; } for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1) show_gate_logic(ivl_scope_log(net, idx)); for (idx = 0 ; idx < ivl_scope_lpms(net) ; idx += 1) show_gate_lpm(ivl_scope_lpm(net, idx)); return ivl_scope_children(net, show_scope_gates, 0); } iverilog-12_0/tgt-fpga/generic.c000066400000000000000000000020301435245347300166330ustar00rootroot00000000000000/* * Copyright (c) 2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "generic.h" edif_t edf = 0; edif_xlibrary_t xlib = 0; edif_cell_t cell_0 = 0; edif_cell_t cell_1 = 0; edif_cell_t cell_ipad = 0; edif_cell_t cell_opad = 0; edif_cell_t cell_iopad = 0; iverilog-12_0/tgt-fpga/generic.h000066400000000000000000000026551435245347300166550ustar00rootroot00000000000000#ifndef IVL_generic_H #define IVL_generic_H /* * Copyright (c) 2003-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 "edif.h" extern edif_t edf; extern edif_xlibrary_t xlib; /* * The cell_* variables below are the various kinds of devices that * this family supports as primitives. If the cell type is used at * least once, then the edif_cell_t is non-zero and will also be * included in the library declaration. The constants underneath are * pin assignments for the cell. */ extern edif_cell_t cell_0; extern edif_cell_t cell_1; extern edif_cell_t cell_ipad; extern edif_cell_t cell_opad; extern edif_cell_t cell_iopad; #endif /* IVL_generic_H */ iverilog-12_0/tgt-fpga/iverilog-fpga.man000066400000000000000000000133641435245347300203170ustar00rootroot00000000000000.TH iverilog-fpga 1 "$Date: 2004/10/04 01:10:57 $" Version "$Date: 2004/10/04 01:10:57 $" .SH NAME iverilog-fpga - FPGA code generator for Icarus Verilog .SH SYNOPSIS .B iverilog -tfpga [iverilog-options] sourcefile .SH DESCRIPTION .PP The FPGA code generator supports a variety of FPGA devices, writing EDIF output depending on the target. You can select the architecture of the device, and the detailed part name. The architecture is used to select library primitives, and the detailed part name is written into the generated file for the use of downstream tools. The code generator is invoked with the \-tfpga flag to iverilog. It understands the part= and the arch= parameters, which can be set with the \-p flag of iverilog: iverilog \-parch=virtex \-ppart=v50\-pq240\-6 \-tfpga foo.vl This example selects the Virtex architecture, and give the detailed part number as v50\-pq240\-6. The output is written into a.out unless a different output file is specified with the \-o flag. .SH OPTIONS \fIiverilog \-tfpga\fP accepts the following options: .TP 8 .B -parch=\fIfamily\fP The \fIfamily\fP setting further specifies the target device family. See FPGA FAMILIES below. .TP 8 .B -ppart=\fIdevice\fP This specifies a specific device in the form of a detailed part number. The format of this number is defined by the part vendor. In most cases, the device string is taken literally and written as is to the EDIF output. .SH "FPGA FAMILIES" The following is a list of architecture types that this code generator supports. .TP 8 .B lpm This is a device independent format, where the gates are device types as defined by the LPM 2 1 0 specification. Some backend tools may take this format, or users may write interface libraries to connect these netlists to the device in question. The \fBlpm\fP family is the default if no other is specified. .TP 8 .B virtex If this is selected, then the output is formatted as an EDIF 2 0 0 file, suitable for Virtex class devices. This is supposed to know that you are targeting a Virtex part, so can generate primitives instead of using external macros. It includes the VIRTEX internal library, and should work properly for any Virtex part. .TP 8 .B virtex2 If this is selected, then the output is EDIF 2 0 0 suitable for Virtex\-II and Virtex\-II Pro devices. It uses the VIRTEX2 library, but is very similar to the Virtex target. .SH "EDIF ROOT PORTS" The EDIF format is explicit about the interface into an EDIF file. The code generator uses that control to generate an explicit interface definition into the design. (This is *not* the same as the PADS of a part.) The generated EDIF interface section contains port definitions, including the proper direction marks. With the (rename ...) s\-exp in EDIF, it is possible to assign arbitrary text to port names. The EDIF code generator therefore does not resort to the mangling that is needed for internal symbols. The base name of the signal that is an input or output is used as the name of the port, complete with the proper case. However, since the ports are single bit ports, the name of vectors includes the string "[0]" where the number is the bit number. For example, the module: .nf module main(out, in); output out; input [2:0] in; [...] endmodule .fi creates these ports: .nf out OUTPUT in[0] INPUT in[1] INPUT in[2] INPUT .fi Target tools, including Xilinx Foundation tools, understand the [] characters in the name and recollect the signals into a proper bus when presenting the vector to the user. .SH "PADS AND PIN ASSIGNMENT" The ports of a root module may be assigned to specific pins, or to a generic pad. If a signal (that is a port) has a PAD attribute, then the value of that attribute is a list of locations, one for each bit of the signal, that specifies the pin for each bit of the signal. For example: .nf module main( (* PAD = "P10" *) output out, (* PAD = "P20,P21,P22" *) input [2:0] in); [...] endmodule .fi In this example, port ``out'' is assigned to pin 10, and port ``in'' is assigned to pins 20\-22. If the architecture supports it, a pin number of 0 means let the back end tools choose a pin. The format of the pin number depends on the architecture family being targeted, so for example Xilinx family devices take the name that is associated with the "LOC" attribute. NOTE: If a module port is assigned to a pin (and therefore attached to a PAD) then it is *not* connected to a port of the EDIF file. This is because the PAD (and possibly IBUF or OBUF) would become an extra driver to the port. An error. .SH "SPECIAL DEVICES" The code generator supports the "cellref" attribute attached to logic devices to cause specific device types be generated, instead of the usual device that the code generator might generate. For example, to get a clock buffer out of a Verilog buf: .nf buf my_gbuf(out, in); $attribute(my_buf, "cellref", "GBUF:O,I"); .fi The "cellref" attribute tells the code generator to use the given cell. The syntax of the value is: .nf :,... .fi The cell type is the name of the library part to use. The pin names are the names of the type in the library, in the order that the logic device pins are connected. .SH EXAMPLES .TB 8 .I COMPILING WITH XILINX FOUNDATION/ISE Compile a single-file design with command line tools like so: .nf % iverilog \-parch=virtex \-o foo.edf foo.vl % edif2ngd foo.edf foo.ngo % ngdbuild \-p v50\-pq240 foo.ngo foo.ngd % map \-o map.ncd foo.ngd % par \-w map.ncd foo.ncd .fi .SH "AUTHOR" .nf Steve Williams (steve@icarus.com) .SH SEE ALSO iverilog(1), .BR "" .SH COPYRIGHT .nf Copyright \(co 2003 Stephen Williams This document can be freely redistributed according to the terms of the GNU General Public License version 2.0 iverilog-12_0/tgt-fpga/mangle.c000066400000000000000000000051751435245347300164770ustar00rootroot00000000000000/* * Copyright (c) 2001-2021 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 "fpga_priv.h" # include # include # include "ivl_alloc.h" static size_t xnf_mangle_scope_name(ivl_scope_t net, char*buf, size_t nbuf) { unsigned cnt = 0; ivl_scope_t parent = ivl_scope_parent(net); if (parent) { cnt = xnf_mangle_scope_name(parent, buf, nbuf); buf += cnt; *buf++ = '/'; cnt += 1; } strcpy(buf, ivl_scope_basename(net)); cnt += strlen(buf); return cnt; } void xnf_mangle_logic_name(ivl_net_logic_t net, char*buf, size_t nbuf) { size_t cnt = xnf_mangle_scope_name(ivl_logic_scope(net), buf, nbuf); buf[cnt++] = '/'; strcpy(buf+cnt, ivl_logic_basename(net)); } void xnf_mangle_lpm_name(ivl_lpm_t net, char*buf, size_t nbuf) { size_t cnt = xnf_mangle_scope_name(ivl_lpm_scope(net), buf, nbuf); buf[cnt++] = '/'; strcpy(buf+cnt, ivl_lpm_basename(net)); } /* * Nexus names are used in pin records to connect things together. It * almost doesn't matter what the nexus name is, but for readability * we choose a name that is close to the nexus name. This function * converts the existing name to a name that XNF can use. * * For speed, this function saves the calculated string into the real * nexus by using the private pointer. Every nexus is used at least * twice, so this cuts the mangling time in half at least. */ const char* xnf_mangle_nexus_name(ivl_nexus_t net) { char*name = ivl_nexus_get_private(net); char*cp; if (name != 0) { return name; } name = malloc(strlen(ivl_nexus_name(net)) + 1); strcpy(name, ivl_nexus_name(net)); for (cp = name ; *cp ; cp += 1) switch (*cp) { case '.': *cp = '/'; break; default: break; } ivl_nexus_set_private(net, name); return name; } iverilog-12_0/tgt-fpga/tables.c000066400000000000000000000032721435245347300165020ustar00rootroot00000000000000/* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "fpga_priv.h" # include # include extern const struct device_s d_generic; extern const struct device_s d_generic_edif; extern const struct device_s d_lpm_edif; extern const struct device_s d_virtex_edif; extern const struct device_s d_virtex2_edif; const struct device_table_s { const char*name; device_t driver; } device_table[] = { { "generic-edif", &d_generic_edif }, { "generic-xnf", &d_generic }, { "lpm", &d_lpm_edif }, { "virtex", &d_virtex_edif }, { "virtex2", &d_virtex2_edif }, { 0, 0 } }; device_t device_from_arch(const char*arch) { unsigned idx; assert(arch); for (idx = 0 ; device_table[idx].name ; idx += 1) { if (strcmp(arch, device_table[idx].name) == 0) return device_table[idx].driver; } return 0; } iverilog-12_0/tgt-fpga/xilinx.c000066400000000000000000000650101435245347300165410ustar00rootroot00000000000000/* * Copyright (c) 2003-2014 Stephen Williams (steve at 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 "edif.h" # include "generic.h" # include "xilinx.h" # include "fpga_priv.h" # include # include # include # include "ivl_alloc.h" edif_cell_t xilinx_cell_buf(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "BUF", 2); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_bufe(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "BUFE", 3); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); edif_cell_portconfig(cell, BUF_T, "E", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_bufg(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "BUFG", 2); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_buft(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "BUFT", 3); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); edif_cell_portconfig(cell, BUF_T, "T", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_ibuf(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "IBUF", 2); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_inv(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "INV", 2); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_muxf5(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "MUXF5", 4); edif_cell_portconfig(cell, MUXF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, MUXF_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXF_I1, "I1", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXF_S, "S", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_muxf6(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "MUXF6", 4); edif_cell_portconfig(cell, MUXF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, MUXF_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXF_I1, "I1", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXF_S, "S", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_obuf(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell) return cell; cell = edif_xcell_create(xlib, "OBUF", 2); edif_cell_portconfig(cell, BUF_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, BUF_I, "I", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_lut2(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "LUT2", 3); edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_lut3(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "LUT3", 4); edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I2, "I2", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_lut4(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "LUT4", 5); edif_cell_portconfig(cell, LUT_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, LUT_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I1, "I1", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I2, "I2", IVL_SIP_INPUT); edif_cell_portconfig(cell, LUT_I3, "I3", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_fdce(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "FDCE", 5); edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CLR,"CLR", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_fdcpe(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "FDCPE", 6); edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CLR,"CLR", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_PRE,"PRE", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_fdre(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "FDRE", 5); edif_cell_portconfig(cell, FDCE_Q, "Q", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, FDCE_D, "D", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_C, "C", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CE, "CE", IVL_SIP_INPUT); edif_cell_portconfig(cell, FDCE_CLR,"R", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_mult_and(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "MULT_AND", 3); edif_cell_portconfig(cell, MULT_AND_LO, "LO", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, MULT_AND_I0, "I0", IVL_SIP_INPUT); edif_cell_portconfig(cell, MULT_AND_I1, "I1", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_muxcy(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "MUXCY", 4); edif_cell_portconfig(cell, MUXCY_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, MUXCY_DI, "DI", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXCY_CI, "CI", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXCY_S, "S", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_muxcy_l(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "MUXCY_L", 4); edif_cell_portconfig(cell, MUXCY_O, "LO", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, MUXCY_DI, "DI", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXCY_CI, "CI", IVL_SIP_INPUT); edif_cell_portconfig(cell, MUXCY_S, "S", IVL_SIP_INPUT); return cell; } edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib) { static edif_cell_t cell = 0; if (cell != 0) return cell; cell = edif_xcell_create(xlib, "XORCY", 3); edif_cell_portconfig(cell, XORCY_O, "O", IVL_SIP_OUTPUT); edif_cell_portconfig(cell, XORCY_CI, "CI", IVL_SIP_INPUT); edif_cell_portconfig(cell, XORCY_LI, "LI", IVL_SIP_INPUT); return cell; } /* * This function does a lot of the stuff common to the header * functions of various Xilinx families. This includes creating the edf * object that holds the netlist. */ void xilinx_common_header(ivl_design_t des) { unsigned idx; ivl_scope_t root = ivl_design_root(des); unsigned sig_cnt = ivl_scope_sigs(root); unsigned nports = 0, pidx; /* Count the ports I'm going to use. */ for (idx = 0 ; idx < sig_cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; if (ivl_signal_attr(sig, "PAD") != 0) continue; nports += ivl_signal_pins(sig); } edf = edif_create(ivl_scope_basename(root), nports); pidx = 0; for (idx = 0 ; idx < sig_cnt ; idx += 1) { edif_joint_t jnt; ivl_signal_t sig = ivl_scope_sig(root, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; if (ivl_signal_attr(sig, "PAD") != 0) continue; if (ivl_signal_pins(sig) == 1) { edif_portconfig(edf, pidx, ivl_signal_basename(sig), ivl_signal_port(sig)); assert(ivl_signal_pins(sig) == 1); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0)); edif_port_to_joint(jnt, edf, pidx); } else { const char*name = ivl_signal_basename(sig); ivl_signal_port_t dir = ivl_signal_port(sig); char buf[128]; unsigned bit; for (bit = 0 ; bit < ivl_signal_pins(sig) ; bit += 1) { const char*tmp; sprintf(buf, "%s[%u]", name, bit); tmp = strdup(buf); edif_portconfig(edf, pidx+bit, tmp, dir); jnt = edif_joint_of_nexus(edf,ivl_signal_pin(sig,bit)); edif_port_to_joint(jnt, edf, pidx+bit); } } pidx += ivl_signal_pins(sig); } assert(pidx == nports); } void xilinx_show_footer(ivl_design_t des) { unsigned idx; for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { unsigned pin; ivl_net_const_t net = ivl_design_const(des, idx); const char*val = ivl_const_bits(net); for (pin = 0 ; pin < ivl_const_pins(net) ; pin += 1) { edif_joint_t jnt; edif_cellref_t pad; jnt = edif_joint_of_nexus(edf, ivl_const_pin(net, pin)); switch (val[pin]) { case '0': pad = edif_cellref_create(edf, cell_0); break; case '1': pad = edif_cellref_create(edf, cell_1); break; default: assert(0); break; } edif_add_to_joint(jnt, pad, 0); } } edif_print(xnf, edf); } /* * Make (or retrieve) a cell in the external library that reflects the * scope with its ports. */ void xilinx_show_scope(ivl_scope_t scope) { edif_cell_t cell; edif_cellref_t ref; unsigned port, idx; cell = edif_xlibrary_scope_cell(xlib, scope); ref = edif_cellref_create(edf, cell); for (idx = 0 ; idx < ivl_scope_sigs(scope) ; idx += 1) { edif_joint_t jnt; ivl_signal_t sig = ivl_scope_sig(scope, idx); if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; port = edif_cell_port_byname(cell, ivl_signal_basename(sig)); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, 0)); edif_add_to_joint(jnt, ref, port); } } void xilinx_pad(ivl_signal_t sig, const char*str) { unsigned idx; char**pins; if (cell_ipad == 0) { cell_ipad = edif_xcell_create(xlib, "IPAD", 1); edif_cell_portconfig(cell_ipad, 0, "IPAD", IVL_SIP_OUTPUT); } if (cell_opad == 0) { cell_opad = edif_xcell_create(xlib, "OPAD", 1); edif_cell_portconfig(cell_opad, 0, "OPAD", IVL_SIP_INPUT); } if (cell_iopad == 0) { cell_iopad = edif_xcell_create(xlib, "IOPAD", 1); edif_cell_portconfig(cell_iopad, 0, "IOPAD", IVL_SIP_INOUT); } /* Collect an array of pin assignments from the attribute string passed in as str. The format is a comma separated list of location names. */ pins = calloc(ivl_signal_pins(sig), sizeof(char*)); for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { const char*tmp = strchr(str, ','); if (tmp == 0) tmp = str+strlen(str); pins[idx] = malloc(tmp-str+1); strncpy(pins[idx], str, tmp-str); pins[idx][tmp-str] = 0; if (*tmp != 0) tmp += 1; str = tmp; } /* Now go through the pins of the signal, creating pads and bufs and joining them to the signal nexus. */ for (idx = 0 ; idx < ivl_signal_pins(sig) ; idx += 1) { edif_joint_t jnt; edif_cellref_t pad, buf; const char*name_str = ivl_signal_basename(sig); if (ivl_signal_pins(sig) > 1) { char name_buf[128]; sprintf(name_buf, "%s[%u]", name_str, idx); name_str = strdup(name_buf); } switch (ivl_signal_port(sig)) { case IVL_SIP_INPUT: pad = edif_cellref_create(edf, cell_ipad); buf = edif_cellref_create(edf, xilinx_cell_ibuf(xlib)); jnt = edif_joint_create(edf); edif_joint_rename(jnt, name_str); edif_add_to_joint(jnt, pad, 0); edif_add_to_joint(jnt, buf, BUF_I); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx)); edif_add_to_joint(jnt, buf, BUF_O); break; case IVL_SIP_OUTPUT: pad = edif_cellref_create(edf, cell_opad); buf = edif_cellref_create(edf, xilinx_cell_obuf(xlib)); jnt = edif_joint_create(edf); edif_joint_rename(jnt, name_str); edif_add_to_joint(jnt, pad, 0); edif_add_to_joint(jnt, buf, BUF_O); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx)); edif_add_to_joint(jnt, buf, BUF_I); break; case IVL_SIP_INOUT: pad = edif_cellref_create(edf, cell_iopad); jnt = edif_joint_of_nexus(edf, ivl_signal_pin(sig, idx)); edif_add_to_joint(jnt, pad, 0); break; default: assert(0); } if (pins[idx]) edif_cellref_pstring(pad, "LOC", pins[idx]); } /* Don't free the allocated pad name strings. The edif_cellref_pstring function attached the string to the LOC attribute, so the reference is permanent. */ free(pins); } /* * This function handles the case where the user specifies the cell to * use by attribute. */ static void edif_cellref_logic(ivl_net_logic_t net, const char*def) { char*str = strdup(def); char*pins; edif_cell_t cell; edif_cellref_t ref; unsigned idx; pins = strchr(str, ':'); assert(pins); *pins++ = 0; /* Locate the cell in the library, lookup by name. */ cell = edif_xlibrary_findcell(xlib, str); assert(cell); ref = edif_cellref_create(edf, cell); for (idx = 0 ; idx < ivl_logic_pins(net) ; idx += 1) { char*tmp; edif_joint_t jnt; unsigned port; assert(pins); tmp = strchr(pins,','); if (tmp != 0) *tmp++ = 0; else tmp = 0; port = edif_cell_port_byname(cell, pins); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, idx)); edif_add_to_joint(jnt, ref, port); pins = tmp; } free(str); } static void lut_logic(ivl_net_logic_t net, const char*init3, const char*init4, const char*init5) { edif_cellref_t lut = NULL; /* initialization shuts up gcc -Wall */ edif_joint_t jnt; const char* init = NULL; /* ditto */ assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); switch (ivl_logic_pins(net)) { case 3: lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); init = init3; break; case 4: lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib)); init = init4; break; case 5: lut = edif_cellref_create(edf, xilinx_cell_lut4(xlib)); init = init5; break; } edif_cellref_pstring(lut, "INIT", init); switch (ivl_logic_pins(net)) { case 5: jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 4)); edif_add_to_joint(jnt, lut, LUT_I3); case 4: jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 3)); edif_add_to_joint(jnt, lut, LUT_I2); case 3: jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); edif_add_to_joint(jnt, lut, LUT_I1); } jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); } void xilinx_logic(ivl_net_logic_t net) { edif_cellref_t obj; edif_joint_t jnt; { const char*cellref_attribute = ivl_logic_attr(net, "cellref"); if (cellref_attribute != 0) { edif_cellref_logic(net, cellref_attribute); return; } } switch (ivl_logic_type(net)) { case IVL_LO_BUF: case IVL_LO_BUFZ: assert(ivl_logic_pins(net) == 2); obj = edif_cellref_create(edf, xilinx_cell_buf(xlib)); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, obj, BUF_O); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, obj, BUF_I); break; case IVL_LO_BUFIF0: /* The Xilinx BUFT devices is a BUF that adds a T input. The output is tri-stated if the T input is 1. In other words, it acts just like bufif0. */ assert(ivl_logic_pins(net) == 3); obj = edif_cellref_create(edf, xilinx_cell_buft(xlib)); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, obj, BUF_O); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, obj, BUF_I); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); edif_add_to_joint(jnt, obj, BUF_T); break; case IVL_LO_BUFIF1: /* The Xilinx BUFE devices is a BUF that adds an enable input. The output is tri-stated if the E input is 0. In other words, it acts just like bufif1. */ assert(ivl_logic_pins(net) == 3); obj = edif_cellref_create(edf, xilinx_cell_bufe(xlib)); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, obj, BUF_O); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, obj, BUF_I); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 2)); edif_add_to_joint(jnt, obj, BUF_T); break; case IVL_LO_NOT: assert(ivl_logic_pins(net) == 2); obj = edif_cellref_create(edf, xilinx_cell_inv(xlib)); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 0)); edif_add_to_joint(jnt, obj, BUF_O); jnt = edif_joint_of_nexus(edf, ivl_logic_pin(net, 1)); edif_add_to_joint(jnt, obj, BUF_I); break; case IVL_LO_AND: assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); lut_logic(net, "8", "80", "8000"); break; case IVL_LO_NOR: assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); lut_logic(net, "1", "01", "0001"); break; case IVL_LO_OR: assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); lut_logic(net, "E", "FE", "FFFE"); break; case IVL_LO_XNOR: assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); lut_logic(net, "9", "69", "9669"); break; case IVL_LO_XOR: assert(ivl_logic_pins(net) <= 5); assert(ivl_logic_pins(net) >= 3); lut_logic(net, "6", "96", "6996"); break; default: fprintf(stderr, "UNSUPPORTED LOGIC TYPE: %d\n", ivl_logic_type(net)); break; } } /* * A fully generic Xilinx MUX is implemented entirely from LUT * devices. */ void xilinx_mux(ivl_lpm_t net) { unsigned idx; assert(ivl_lpm_selects(net) == 1); /* A/B Mux devices are made from LUT3 devices. I0 is connected to A, I1 to B, and I2 to the Select input. Create as many as are needed to implement the requested width. S B A | Q ------+-- 0 0 0 | 0 0 0 1 | 1 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 0 1 1 0 | 1 1 1 1 | 1 INIT = "CA" */ for (idx = 0 ; idx < ivl_lpm_width(net) ; idx += 1) { edif_cellref_t lut; edif_joint_t jnt; lut = edif_cellref_create(edf, xilinx_cell_lut3(xlib)); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, idx)); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 0, idx)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_data2(net, 1, idx)); edif_add_to_joint(jnt, lut, LUT_I1); jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net, 0)); edif_add_to_joint(jnt, lut, LUT_I2); edif_cellref_pstring(lut, "INIT", "CA"); } } /* * Any Xilinx device works with this adder. * Generic Xilinx add only works for single bit slices. */ void xilinx_add(ivl_lpm_t net) { const char*ha_init = 0; switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: ha_init = "6"; break; case IVL_LPM_SUB: ha_init = "9"; break; default: assert(0); } /* If this is a single bit wide, then generate only a half-adder. Normally this is an XOR, but if this is a SUB then it is an XNOR. */ if (ivl_lpm_width(net) == 1) { edif_cellref_t lut; edif_joint_t jnt; lut = edif_cellref_create(edf, xilinx_cell_lut2(xlib)); jnt = edif_joint_of_nexus(edf, ivl_lpm_q(net, 0)); edif_add_to_joint(jnt, lut, LUT_O); jnt = edif_joint_of_nexus(edf, ivl_lpm_data(net, 0)); edif_add_to_joint(jnt, lut, LUT_I0); jnt = edif_joint_of_nexus(edf, ivl_lpm_datab(net, 0)); edif_add_to_joint(jnt, lut, LUT_I1); edif_cellref_pstring(lut, "INIT", ha_init); return; } assert(0); } /* * The left shift is implemented as a matrix of MUX2_1 devices. The * matrix has as many rows as the device width, and a column for each * select. */ void xilinx_shiftl(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned nsel = 0; unsigned sdx, qdx; edif_cellref_t* cells; edif_cellref_t**table; edif_cellref_t pad0_cell; edif_joint_t pad0; /* First, find out how many select inputs we really need. We can only use the selects that are enough to shift out the entire width of the device. The excess can be used as an enable for the last column. When disabled, the last column emits zeros. */ while (nsel < ivl_lpm_selects(net)) { unsigned swid; nsel += 1; swid = 1 << nsel; if (swid >= width) break; } assert(nsel > 0); /* Allocate a matrix of edif_cellref_t variables. A devices will be addressed by the expression table[sdx][qdx]; This should make the algorithm code easier to read. */ cells = calloc(nsel * width, sizeof(edif_cellref_t)); table = calloc(nsel, sizeof(edif_cellref_t*)); for (sdx = 0 ; sdx < nsel ; sdx += 1) table[sdx] = cells + sdx*width; /* Make a 0 valued pad bit. I will use this for all the shift in values that are beyond the input. */ pad0_cell = edif_cellref_create(edf, cell_0); pad0 = edif_joint_create(edf); edif_add_to_joint(pad0, pad0_cell, 0); /* The LUT matrix is columns of devices, with the last column a LUT4 devices. The extra input of the LUT4s in the last column are used as an enable to collect all the excess select inputs. */ /* Allocate the LUT devices of the matrix, and connect the select inputs to I2 of all the devices of the column. */ for (sdx = 0 ; sdx < nsel ; sdx += 1) { const char*init_string = 0; ivl_nexus_t nex = ivl_lpm_select(net,sdx); edif_joint_t sdx_jnt = edif_joint_of_nexus(edf, nex); edif_cell_t lut; if (((sdx+1) == nsel) && (nsel < ivl_lpm_selects(net))) { lut = xilinx_cell_lut4(xlib); init_string = "00CA"; } else { lut = xilinx_cell_lut3(xlib); init_string = "CA"; } for (qdx = 0 ; qdx < width ; qdx += 1) { table[sdx][qdx] = edif_cellref_create(edf, lut); edif_add_to_joint(sdx_jnt, table[sdx][qdx], LUT_I2); edif_cellref_pstring(table[sdx][qdx], "INIT", init_string); } } /* Connect the inputs of the SHIFTL device to the column 0 LUT inputs. The slice on the low end shifts in a 0 for a select input. */ for (qdx = 0 ; qdx < width ; qdx += 1) { ivl_nexus_t nex0; edif_joint_t jnt0; edif_joint_t jnt1; nex0 = ivl_lpm_data(net,qdx); jnt0 = edif_joint_of_nexus(edf, nex0); if (qdx > 0) { ivl_nexus_t nex1; nex1 = ivl_lpm_data(net,qdx-1); jnt1 = edif_joint_of_nexus(edf, nex1); } else { jnt1 = pad0; } edif_add_to_joint(jnt0, table[0][qdx], LUT_I0); edif_add_to_joint(jnt1, table[0][qdx], LUT_I1); } /* Make the inner connections between LUT devices. Each column connects to the previous column, shifted by the power of the column value. If the shifted input falls off the end, then pad with zero. */ for (sdx = 1 ; sdx < nsel ; sdx += 1) { for (qdx = 0 ; qdx < width ; qdx += 1) { unsigned shift = 1 << sdx; edif_joint_t jnt0 = edif_joint_create(edf); edif_joint_t jnt1 = (qdx >= shift) ? edif_joint_create(edf) : pad0; edif_add_to_joint(jnt0, table[sdx][qdx], LUT_I0); edif_add_to_joint(jnt1, table[sdx][qdx], LUT_I1); edif_add_to_joint(jnt0, table[sdx-1][qdx], LUT_O); if (qdx >= shift) edif_add_to_joint(jnt1, table[sdx-1][qdx-shift], LUT_O); } } /* Connect the output of the last column to the output of the SHIFTL device. */ for (qdx = 0 ; qdx < width ; qdx += 1) { ivl_nexus_t nex = ivl_lpm_q(net,qdx); edif_joint_t jnt = edif_joint_of_nexus(edf, nex); edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_O); } /* Connect the excess select inputs to the enable inputs of the LUT4 devices in the last column. */ if (nsel < ivl_lpm_selects(net)) { edif_joint_t jnt; /* XXXX Only support 1 excess bit for now. */ assert((nsel + 1) == ivl_lpm_selects(net)); jnt = edif_joint_of_nexus(edf, ivl_lpm_select(net,nsel)); for (qdx = 0 ; qdx < width ; qdx += 1) edif_add_to_joint(jnt, table[nsel-1][qdx], LUT_I3); } free(cells); free(table); } iverilog-12_0/tgt-fpga/xilinx.h000066400000000000000000000104511435245347300165450ustar00rootroot00000000000000#ifndef IVL_xilinx_H #define IVL_xilinx_H /* * Copyright (c) 2003-2014 Stephen Williams (steve at 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. */ /* * This header file includes XILINX library support functions. They * manage the creation and reference of cells from the library. Use * the xilinx_cell_* functions to get an edif_cell_t from the * library. The function will create the cell in the library if * needed, or will return the existing cell if it was already called. */ # include "edif.h" /* === BUF Devices === */ /* Buffer types of devices have the BUF_O and BUF_I pin assignments. The BUF, INV, and certain specialized devices fit in this category. */ extern edif_cell_t xilinx_cell_buf (edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_bufe(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_bufg(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_buft(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_inv (edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_ibuf(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_obuf(edif_xlibrary_t xlib); #define BUF_O 0 #define BUF_I 1 /* Only bufe and buft buffers have this input. */ #define BUF_T 2 /* === LUT Devices === */ /* Most Xilinx devices have LUT2/3/4 devices that take, respectively, 2, 3 or 4 inputs. All forms have a single bit output. Also, the real behavior of the device will need to be specified by an INIT parameter string. */ extern edif_cell_t xilinx_cell_lut2(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_lut3(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_lut4(edif_xlibrary_t xlib); #define LUT_O 0 #define LUT_I0 1 #define LUT_I1 2 #define LUT_I2 3 #define LUT_I3 4 /* === Flip-Flop Devices === */ /* * These are flip-flops of various sort, but similar pinouts. */ extern edif_cell_t xilinx_cell_fdce(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_fdcpe(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_fdre(edif_xlibrary_t xlib); #define FDCE_Q 0 #define FDCE_C 1 #define FDCE_D 2 #define FDCE_CE 3 #define FDCE_CLR 4 #define FDCE_PRE 5 /* === Virtex/Virtex2 Carry Chain Logic === */ extern edif_cell_t xilinx_cell_mult_and(edif_xlibrary_t xlib); #define MULT_AND_LO 0 #define MULT_AND_I0 1 #define MULT_AND_I1 2 extern edif_cell_t xilinx_cell_muxcy(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_muxcy_l(edif_xlibrary_t xlib); #define MUXCY_O 0 #define MUXCY_DI 1 #define MUXCY_CI 2 #define MUXCY_S 3 extern edif_cell_t xilinx_cell_xorcy(edif_xlibrary_t xlib); #define XORCY_O 0 #define XORCY_CI 1 #define XORCY_LI 2 /* === Virtex/Virtex2 MUX devices */ extern edif_cell_t xilinx_cell_muxf5(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_muxf6(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_muxf7(edif_xlibrary_t xlib); extern edif_cell_t xilinx_cell_muxf8(edif_xlibrary_t xlib); #define MUXF_O 0 #define MUXF_I0 1 #define MUXF_I1 2 #define MUXF_S 3 /* === Inheritable Methods === */ extern void virtex_logic(ivl_net_logic_t net); extern void virtex_generic_dff(ivl_lpm_t net); extern void virtex_eq(ivl_lpm_t net); extern void virtex_ge(ivl_lpm_t net); extern void virtex_mux(ivl_lpm_t net); extern void virtex_add(ivl_lpm_t net); extern void xilinx_common_header(ivl_design_t des); extern void xilinx_show_footer(ivl_design_t des); extern void xilinx_show_scope(ivl_scope_t scope); extern void xilinx_pad(ivl_signal_t, const char*str); extern void xilinx_logic(ivl_net_logic_t net); extern void xilinx_mux(ivl_lpm_t net); extern void xilinx_add(ivl_lpm_t net); extern void xilinx_shiftl(ivl_lpm_t net); #endif /* IVL_xilinx_H */ iverilog-12_0/tgt-null/000077500000000000000000000000001435245347300151155ustar00rootroot00000000000000iverilog-12_0/tgt-null/Makefile.in000066400000000000000000000052061435245347300171650ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = null.o all: dep null.tgt check: all clean: rm -rf *.o dep null.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-null/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif null.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./null.tgt \ $(srcdir)/null.conf \ $(srcdir)/null-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./null.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/null.tgt" $(INSTALL_DATA) $(srcdir)/null.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/null.conf" $(INSTALL_DATA) $(srcdir)/null-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/null-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/null.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/null.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/null-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-null/cppcheck.sup000066400000000000000000000002711435245347300174260ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:null.c:50 // target_query() unusedFunction:null.c:57 iverilog-12_0/tgt-null/null-s.conf000066400000000000000000000001011435245347300171660ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules flag:DLL=null.tgt iverilog-12_0/tgt-null/null.c000066400000000000000000000042301435245347300162320ustar00rootroot00000000000000/* * Copyright (c) 2000-2020 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 "version_base.h" # include "version_tag.h" # include "config.h" # include /* * This is a null target module. It does nothing. */ # include "ivl_target.h" static const char*version_string = "Icarus Verilog NULL Code Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; int target_design(ivl_design_t des) { (void)des; /* Parameter is not used. */ return 0; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } iverilog-12_0/tgt-null/null.conf000066400000000000000000000000221435245347300167300ustar00rootroot00000000000000flag:DLL=null.tgt iverilog-12_0/tgt-pal/000077500000000000000000000000001435245347300147175ustar00rootroot00000000000000iverilog-12_0/tgt-pal/Makefile.in000066400000000000000000000045251435245347300167720ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = imain.o dump_final.o emit_jed.o enables.o fit_log.o fit_reg.o pads.o all: dep pal.tgt check: all clean: rm -rf *.o dep pal.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-pal/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@CYGWIN@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif pal.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) -lipal install: all installdirs installfiles F = ./pal.tgt installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./pal.tgt "$(DESTDIR)$(libdir)/ivl/pal.tgt" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)/$(libdir)/ivl" uninstall: rm -f "$DESTDIR)$(libdir)/ivl/pal.tgt" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-pal/cppcheck.sup000066400000000000000000000002161435245347300172270ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:imain.c:59 iverilog-12_0/tgt-pal/dump_final.c000066400000000000000000000032471435245347300172070ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "priv.h" # include void dump_final_design(FILE*out) { unsigned idx; for (idx = 0 ; idx < pins ; idx += 1) { struct pal_bind_s*pin = bind_pin + idx; if (bind_pin[idx].sop) { fprintf(out, "Output pin %u:\n", idx+1); fprintf(out, " pin nexus=%s\n", pin->nexus? ivl_nexus_name(pin->nexus) : ""); fprintf(out, " pin enable=%s\n", pin->enable ? ivl_logic_name(pin->enable) : "1"); if (pin->reg) fprintf(out, " pin ff=%s.%s.q%u\n", ivl_scope_name(ivl_lpm_scope(pin->reg)), ivl_lpm_basename(pin->reg), pin->reg_q); else fprintf(out, " pin ff=*.q%u\n", pin->reg_q); } else { fprintf(out, "Input pin %u:\n", idx+1); fprintf(out, " pin nexus=%s\n", pin->nexus? ivl_nexus_name(pin->nexus) : ""); } } } iverilog-12_0/tgt-pal/emit_jed.c000066400000000000000000000064521435245347300166520ustar00rootroot00000000000000/* * Copyright (c) 2001-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 "priv.h" # include # include # include # include "ivl_alloc.h" static void draw_macrocell_modes(FILE*jfd) { unsigned idx; unsigned cfuses; unsigned mode, mcnt; for (idx = 0 ; idx < pins ; idx += 1) { char*str; unsigned ffirst, flast, tmp; struct pal_bind_s*cur = bind_pin + idx; if (cur->sop == 0) continue; cfuses = pal_sop_cfuses(cur->sop); mcnt = 1 << pal_sop_cfuses(cur->sop); mode = 0; for (mode = 0 ; mode < mcnt ; mode += 1) { pal_sop_set_mode(cur->sop, mode); if (cur->reg && !pal_sop_is_register(cur->sop)) continue; if (!cur->reg && pal_sop_is_register(cur->sop)) continue; if (cur->sop_inv && !pal_sop_is_invert(cur->sop)) continue; if (!cur->sop_inv && pal_sop_is_invert(cur->sop)) continue; break; } assert(mode < mcnt); ffirst = pal_sop_cfuse(cur->sop, 0); flast = pal_sop_cfuse(cur->sop, 0); for (tmp = 1 ; tmp < cfuses ; tmp += 1) { unsigned f = pal_sop_cfuse(cur->sop, tmp); if (f < ffirst) ffirst = f; if (f > flast) flast = f; } assert(flast == (ffirst + cfuses - 1)); str = malloc(cfuses+1); str[cfuses] = 0; for (tmp = 0 ; tmp < cfuses ; tmp += 1) { if (mode & (1 << (cfuses-tmp-1))) str[pal_sop_cfuse(cur->sop, tmp)-ffirst] = '1'; else str[pal_sop_cfuse(cur->sop, tmp)-ffirst] = '0'; } fprintf(jfd, "L%05u %s* Note: ", ffirst, str); if (cur->nexus) fprintf(jfd, "%s ", ivl_nexus_name(cur->nexus)); { int pin = pal_sop_pin(cur->sop); if (pin > 0) fprintf(jfd, "pin %d: ", pin); } if (pal_sop_is_register(cur->sop)) fprintf(jfd, "sop)) fprintf(jfd, ", invert"); fprintf(jfd, "> *\n"); free(str); } } int emit_jedec(const char*path) { FILE*jfd; jfd = fopen(path, "w"); if (jfd == 0) { fprintf(stderr, "unable to open ``%s'' for output.\n", path); return -1; } fprintf(jfd, "\002This file created by Icarus Verilog/PAL\n"); fprintf(jfd, "*\n"); fprintf(jfd, "QF%u* Number of fuses*\n", pal_fuses(pal)); fprintf(jfd, "F0* Note: Default fuse set to 0*\n"); fprintf(jfd, "G0* Note: Security fuse NOT blown.*\n"); draw_macrocell_modes(jfd); fclose(jfd); return 0; } iverilog-12_0/tgt-pal/enables.c000066400000000000000000000036251435245347300165020ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "ivl_target.h" # include # include "priv.h" /* * Given a pin index, look at the nexus for a bufif device that is * driving it, if any. Save that device in the enable slot for the * cell. We'll try to fit it later. */ static void absorb_pad_enable(unsigned idx) { unsigned ndx; ivl_nexus_t nex = bind_pin[idx].nexus; for (ndx = 0 ; ndx < ivl_nexus_ptrs(nex) ; ndx += 1) { unsigned pin; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, ndx); ivl_net_logic_t log = ivl_nexus_ptr_log(ptr); if (log == 0) continue; pin = ivl_nexus_ptr_pin(ptr); assert(pin == 0); switch (ivl_logic_type(log)) { case IVL_LO_BUFIF0: case IVL_LO_BUFIF1: assert(bind_pin[idx].enable == 0); bind_pin[idx].enable = log; break; default: } } } void absorb_pad_enables(void) { unsigned idx; for (idx = 0 ; idx < pins ; idx += 1) { if (bind_pin[idx].sop == 0) continue; if (bind_pin[idx].nexus == 0) continue; absorb_pad_enable(idx); } } iverilog-12_0/tgt-pal/fit_log.c000066400000000000000000000070311435245347300165070ustar00rootroot00000000000000/* * 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 "ivl_target.h" # include # include # include # include "priv.h" # include "ivl_alloc.h" /* * By the time we get here, all the flip-flops have been placed in * macrocells, and enables attached to them. So all that's left is to * work backwards from each macrocell, making terms and sum-of-terms * from the asynchronous logic until we get to the table inputs. * * A product term is a null terminated array of ivl_nexus_t * objects. An expression is a null terminated array of terms. */ static void dump_expr(term_t**expr, const char*title) { unsigned idx; fprintf(stderr, "expression for %s:\n", title); for (idx = 0 ; expr[idx] ; idx += 1) { term_t*tp; fprintf(stderr, " term %u:\n", idx); for (tp = expr[idx] ; tp->nex ; tp += 1) fprintf(stderr, " %c%s\n", tp->inv? '~' : ' ', ivl_nexus_name(tp->nex)); } } static term_t** build_expr(ivl_nexus_t nex) { term_t* term = calloc(2, sizeof(term_t)); term_t**expr = calloc(2, sizeof(term_t*)); unsigned idx; assert(nex); expr[0] = term; term[0].inv = 0; term[0].nex = nex; /* First look to see if I'm connected to an input pin. If so, then this expression is done. */ for (idx = 0 ; idx < pins ; idx += 1) { struct pal_bind_s*pin = bind_pin + idx; if ((nex == pin->nexus) && (pin->sop == 0)) { return expr; } } fprintf(stderr, "sorry, I give up on nexus %s\n", ivl_nexus_name(nex)); return 0; } int fit_logic(void) { unsigned idx; for (idx = 0 ; idx < pins ; idx += 1) { ivl_nexus_t cell; struct pal_bind_s*pin = bind_pin + idx; if (pin->sop == 0) continue; cell = pin->nexus; if (cell == 0) continue; /* If there is an enable, then this is a bufifX or a notifX. Build the expression for the enable, and guess that the input to the cell is actually the input to the enable. */ if (pin->enable) { ivl_nexus_t en_nex = ivl_logic_pin(pin->enable, 2); assert(cell == ivl_logic_pin(pin->enable, 0)); cell = ivl_logic_pin(pin->enable, 1); assert(cell); pin->enable_ex = build_expr(en_nex); dump_expr(pin->enable_ex, ivl_nexus_name(en_nex)); } /* If there is a reg, then the input to the cell is really the D input to the ff. */ if (pin->reg) { assert(cell == ivl_lpm_q(pin->reg, pin->reg_q)); cell = ivl_lpm_data(pin->reg, pin->reg_q); } assert(cell); /* Here we are. Generate the sum-of-products for the input. */ pin->sop_ex = build_expr(cell); dump_expr(pin->sop_ex, ivl_nexus_name(cell)); } return 0; } iverilog-12_0/tgt-pal/fit_reg.c000066400000000000000000000065331435245347300165110ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "ivl_target.h" # include # include # include "priv.h" /* * The fit_registers function scans all the scopes for flip-flop * devices to be assigned to macrocells. First look to see if the * device is connected to a PAD directly or through a bufif device. If * not, then just pick a free macrocell and drop it there. */ static int scan_ff_q(ivl_lpm_t ff, unsigned q); int fit_registers(ivl_scope_t scope, void*x) { int rc; unsigned idx; unsigned lpms; /* Scan child scopes first... */ rc = ivl_scope_children(scope, fit_registers, 0); if (rc != 0) return rc; /* Scan the current scope for flip-flop devices. Pass the devices we find to the scan_ff_q function to assign to a macrocell. */ lpms = ivl_scope_lpms(scope); for (idx = 0 ; idx < lpms ; idx += 1) { ivl_lpm_t lpm = ivl_scope_lpm(scope, idx); unsigned wid, q; if (ivl_lpm_type(lpm) != IVL_LPM_FF) continue; wid = ivl_lpm_width(lpm); for (q = 0 ; q < wid ; q += 1) { rc = scan_ff_q(lpm, q); if (rc != 0) return rc; } } return 0; } /* * This is the part that actually assigns the single bit of a single * flip-flop to a single macrocell. */ int scan_ff_q(ivl_lpm_t ff, unsigned q) { unsigned idx; ivl_nexus_t nex; nex = ivl_lpm_q(ff, q); /* First, look to see if the Q is already connected to a pin or an enable. If I find such a connection, then immediately finish. */ for (idx = 0 ; idx < pins ; idx += 1) { struct pal_bind_s*pin = bind_pin + idx; if (pin->sop == 0) continue; if (pin->enable) { if (nex == ivl_logic_pin(pin->enable, 1)) { pin->reg = ff; pin->reg_q = q; return 0; } } else if (pin->nexus == nex) { pin->reg = ff; pin->reg_q = q; return 0; } } /* There is no pin connection, so try setting this to an unbound sop cell. We know that a sop is unbound if there are no enables, nexus or ff devices connected to it. */ for (idx = 0 ; idx < pins ; idx += 1) { struct pal_bind_s*pin = bind_pin + idx; if (pin->sop == 0) continue; if (pin->enable || pin->nexus || pin->reg) continue; /* Found one. Put the reg here. Leave the nexus empty so that the code generator knows to disable the pin. */ pin->reg = ff; pin->reg_q = q; return 0; } fprintf(stderr, "No room for this ff.\n"); error_count += 1; return 0; } iverilog-12_0/tgt-pal/imain.c000066400000000000000000000075121435245347300161650ustar00rootroot00000000000000/* * 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" /* * This module generates a PAL that implements the design. */ # include "priv.h" # include # include # include # include "ivl_alloc.h" extern void dump_final_design(FILE*out); /* * As processing proceeds, this variable is incremented as errors are * encountered. This allows the code generator to give up if it * detects errors deep within recursive functions. */ unsigned pal_errors = 0; /* * This is the pal device that the user asked for. */ pal_t pal = 0; /* * These variables are the global pin assignment array. Everything * operates to build this up. */ unsigned pins = 0; struct pal_bind_s* bind_pin = 0; /* * This is the main entry point that Icarus Verilog calls to generate * code for a pal. */ int target_design(ivl_design_t des) { unsigned idx; const char*part; ivl_scope_t root; /* Get the part type from the design, using the "part" key. Given the part type, try to open the pal description so that we can figure out the device. */ part = ivl_design_flag(des, "part"); if ((part == 0) || (*part == 0)) { fprintf(stderr, "error: part must be specified. Specify a\n"); fprintf(stderr, " : type with the -fpart= option.\n"); return -1; } pal = pal_alloc(part); if (pal == 0) { fprintf(stderr, "error: %s is not a valid part type.\n", part); return -1; } assert(pal); pins = pal_pins(pal); assert(pins > 0); /* Allocate the pin array, ready to start assigning resources. */ bind_pin = calloc(pins, sizeof (struct pal_bind_s)); /* Connect all the macrocells that drive pins to the pin that they drive. This doesn't yet look at the design, but is initializing the bind_pin array with part information. */ for (idx = 0 ; idx < pal_sops(pal) ; idx += 1) { pal_sop_t sop = pal_sop(pal, idx); int spin = pal_sop_pin(sop); if (spin == 0) continue; assert(spin > 0); bind_pin[spin-1].sop = sop; } /* Get pin assignments from the user. This is the first and most constrained step. Everything else must work around the results of these bindings. */ root = ivl_design_root(des); get_pad_bindings(root, 0); if (pal_errors) { fprintf(stderr, "PAD assignment failed.\n"); pal_free(pal); return -1; } /* Run through the assigned output pins and absorb the output enables that are connected to them. */ absorb_pad_enables(); /* Scan all the registers, and assign them to macro-cells. */ root = ivl_design_root(des); fit_registers(root, 0); if (pal_errors) { fprintf(stderr, "Register fitting failed.\n"); pal_free(pal); return -1; } fit_logic(); if (pal_errors) { fprintf(stderr, "Logic fitting failed.\n"); pal_free(pal); return -1; } dump_final_design(stdout); emit_jedec(ivl_design_flag(des, "-o")); pal_free(pal); return 0; } iverilog-12_0/tgt-pal/pads.c000066400000000000000000000040571435245347300160200ustar00rootroot00000000000000/* * Copyright (c) 2000 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "config.h" # include "priv.h" # include # include # include /* * This function scans the netlist for all the pin assignments that * are fixed by a PAD attribute. Search the scopes recursively, * looking for signals that may have PAD attributes. */ int get_pad_bindings(ivl_scope_t net, void*x) { unsigned idx; int rc = ivl_scope_children(net, get_pad_bindings, 0); if (rc) return rc; for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) { ivl_signal_t sig; const char*pad; int pin; sig = ivl_scope_sig(net, idx); pad = ivl_signal_attr(sig, "PAD"); if (pad == 0) continue; pin = strtol(pad+1, 0, 10); if ((pin == 0) || (pin > pins)) { printf("%s: Invalid PAD assignment: %s\n", ivl_signal_name(sig), pad); error_count += 1; continue; } assert(ivl_signal_pins(sig) == 1); if (bind_pin[pin-1].nexus) { if (bind_pin[pin-1].nexus != ivl_signal_pin(sig, 0)) { printf("%s: Unconnected signals share pin %d\n", ivl_signal_name(sig), pin); error_count += 1; } continue; } bind_pin[pin-1].nexus = ivl_signal_pin(sig, 0); } return 0; } iverilog-12_0/tgt-pal/priv.h000066400000000000000000000057751435245347300160660ustar00rootroot00000000000000#ifndef IVL_priv_H #define IVL_priv_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 # include extern pal_t pal; extern unsigned error_count; /* * A device has an array of pins, that are bound to the netlist either * by attribute or by random lookup. The bind_pin table keeps track of * pin allocations. * * Each cell also has attached to it an expression that calculates * results from an input. That expression is represented by a sum of * product terms. A product term is an array of term_t objects, * terminated by a term will a null nex pointers. A sum, then, is an * array of pointers to term_t arrays, terminated by a null pointer. */ typedef struct term_s { int inv; ivl_nexus_t nex; } term_t; /* * This structure describes a target device pin. If the pin is not * controlled by the pal (i.e. it is a power pin) then the sop field * is null. Otherwise, the sop in the macrocell that controls the pin. * * If the pin has an enable, then the sop for the enable function is * stored here as well. * * This structure for collecting the PAL design assumes that all the * macrocells are associated with pins, or are enables for other * pins. * * The bind_pin array is the complete description of the target as it * is accumulated. */ struct pal_bind_s { /* This is the netlist connection for the pin. */ ivl_nexus_t nexus; /* If the pin is an output, this is is sop that drives it. */ pal_sop_t sop; /* If the output has an enable, this is it, along with the single term that activates it. */ ivl_net_logic_t enable; term_t **enable_ex; /* If there is a register here, this is it. */ ivl_lpm_t reg; unsigned reg_q; /* The input to the cell is this expression. */ term_t **sop_ex; /* These are the SOP flags that I believe I need. */ unsigned sop_inv : 1; }; extern unsigned pins; extern struct pal_bind_s* bind_pin; /* * These are various steps in the fitting process. */ extern int get_pad_bindings(ivl_scope_t net, void*x); extern void absorb_pad_enables(void); extern int fit_registers(ivl_scope_t scope, void*x); extern int fit_logic(void); extern int emit_jedec(const char*path); #endif /* IVL_priv_H */ iverilog-12_0/tgt-pcb/000077500000000000000000000000001435245347300147075ustar00rootroot00000000000000iverilog-12_0/tgt-pcb/Makefile.in000066400000000000000000000065271435245347300167660ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ CC = @CC@ CXX = @CXX@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ YACC = @YACC@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ O = pcb.o scope.o show_netlist.o show_pcb.o footprint.o fp.o fp_lex.o all: dep pcb.tgt check: all clean: rm -f fp.cc fp.h fp.output fp_lex.cc rm -rf *.o dep pcb.tgt distclean: clean rm -f Makefile config.log rm -f stamp-pcb_config-h pcb_config.h cppcheck: $(O:.o=.cc) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ -UYY_USER_INIT \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYSTYPE -U__SIZE_TYPE__ -Ufree \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-pcb/$@ dep: mkdir dep stamp-pcb_config-h: $(srcdir)/pcb_config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=tgt-pcb/pcb_config.h pcb_config.h: stamp-pcb_config-h %.o: %.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep fp_lex.o: fp_lex.cc fp.h fp_lex.cc: $(srcdir)/fp.lex $(LEX) -s -ofp_lex.cc $(srcdir)/fp.lex fp%cc fp%h: $(srcdir)/fp%y $(YACC) --verbose -t -p fp --defines=fp.h -o fp.cc $< ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif pcb.tgt: $O $(TGTDEPLIBS) $(CXX) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./pcb.tgt \ $(srcdir)/pcb.conf \ $(srcdir)/pcb-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./pcb.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb.tgt" $(INSTALL_DATA) $(srcdir)/pcb.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb.conf" $(INSTALL_DATA) $(srcdir)/pcb-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/pcb-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-pcb/cppcheck.sup000066400000000000000000000002711435245347300172200ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:pcb.cc:52 // target_query() unusedFunction:pcb.cc:84 iverilog-12_0/tgt-pcb/footprint.cc000066400000000000000000000052251435245347300172460ustar00rootroot00000000000000/* * Copyright (c) 2011 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include "version_base.h" # include "version_tag.h" # include "pcb_config.h" # include "pcb_priv.h" # include "fp_api.h" # include # include using namespace std; map footprints; static int check_footprint(element_data_t*elem); /* * Scan the element list and collect footprints needed. */ int load_footprints(void) { for (map::const_iterator cur = element_list.begin() ; cur != element_list.end() ; ++ cur) { check_footprint(cur->second); } return 0; } /* * The fpparse function calls back the callback_fp_element function * for each Element that it parses. The check_footprint function * stores in the cur_footprint variable the name of the footprint that * we are trying to find in the file. The callback uses that name to * store the Element into the footprints map. */ static string cur_footprint = ""; void callback_fp_element(const struct fp_element_t&cur_elem) { assert(cur_footprint != ""); footprints[cur_footprint] = cur_elem; cur_footprint = ""; } static int check_footprint(element_data_t*elem) { if (elem->footprint == "") { cerr << "No footprint defined for \"" << elem->description << "\"." << endl; return -1; } map::iterator match = footprints.find(elem->footprint); if (match != footprints.end()) return 0; string fpname = elem->footprint + ".fp"; cur_footprint = elem->footprint; int rc = parse_fp_file(fpname); if (rc != 0) { cerr << "parse_fp_file(" << fpname << ") returns rc=" << rc << endl; return rc; } match = footprints.find(elem->footprint); if (match == footprints.end()) { cerr << "Unable to locate footprint " << elem->footprint << "." << endl; return -2; } return 0; } iverilog-12_0/tgt-pcb/fp.lex000066400000000000000000000041211435245347300160240ustar00rootroot00000000000000%option prefix="fp" %option never-interactive %option noinput %option nounput %option noyywrap %{ /* * Copyright (C) 2011-2017 Stephen Williams (steve@icarus.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. */ # include "fp_api.h" # include "fp.h" # define YY_DECL int yylex(YYSTYPE*yylvalp, YYLTYPE*yyllocp) %} SPACE [ \t\f\r] %% /* Skip comment lines */ "#".* { ; } /* Skip white space */ {SPACE} { ; } "\n" { yyllocp->first_line += 1; } "Element" { return K_ELEMENT; } "Pad" { return K_PAD; } "0x"[0-9a-fA-F]+ { yylvalp->integer = strtoul(yytext+2,0,10); return INTEGER; } "0"[0-7]* { yylvalp->integer = strtoul(yytext,0,8); return INTEGER; } [1-9][0-9]* { yylvalp->integer = strtoul(yytext,0,10); return INTEGER; } "\""[^\"]*"\"" { size_t len = strlen(yytext)-2; char*tmp = new char[len+1]; memcpy(tmp, yytext+1, len); tmp[len] = 0; yylvalp->text = tmp; return STRING; } /* Isolated characters are tokens */ . { return yytext[0]; } %% void init_fp_lexor(FILE*fd) { yyrestart(fd); } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_fp_lexor() { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } iverilog-12_0/tgt-pcb/fp.y000066400000000000000000000112531435245347300155100ustar00rootroot00000000000000 %define api.pure %parse-param {const char*file_path} %{ /* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include "fp_api.h" # include "pcb_priv.h" # include # include using namespace std; /* Recent version of bison expect that the user supply a YYLLOC_DEFAULT macro that makes up a yylloc value from existing values. I need to supply an explicit version to account for the text field, that otherwise won't be copied. */ # define YYLLOC_DEFAULT(Current, Rhs, N) do { \ (Current).first_line = (Rhs)[1].first_line; \ } while (0) static void yyerror(YYLTYPE*, const char*, const char*msg) { fprintf(stderr, "%s\n", msg); } extern void init_fp_lexor(FILE*fd); extern void destroy_fp_lexor(); extern int fplex(union YYSTYPE*yylvalp, YYLTYPE*yylloc); static fp_pad_t cur_pad; static fp_element_t cur_element; %} %union { long integer; char*text; }; %token STRING %token INTEGER %token K_ELEMENT %token K_PAD %type integer %% file_items : file_items file_item | file_item ; file_item : element ; element : K_ELEMENT element_header '(' element_items ')' { callback_fp_element(cur_element); } ; element_header : '[' INTEGER STRING STRING STRING integer integer integer integer integer integer STRING ']' { cur_element.nflags = $2; cur_element.description = $3; delete[]$3; cur_element.name = $4; delete[]$4; cur_element.value = $5; delete[]$5; cur_element.mx = $6; cur_element.my = $7; cur_element.tx = $8; cur_element.ty = $9; cur_element.tdir = $10; cur_element.tscale = $11; cur_element.tsflags = $12; delete[]$12; cur_element.pads.clear(); } | '[' error ']' { errormsg(@2, "Error in element header\n"); yyerrok; cur_element.nflags = 0; cur_element.description = ""; cur_element.name = ""; cur_element.value = ""; cur_element.mx = 0; cur_element.my = 0; cur_element.tx = 0; cur_element.ty = 0; cur_element.tdir = 0; cur_element.tscale = 0; cur_element.tsflags = ""; cur_element.pads.clear(); } ; element_items : element_items element_item | element_item ; element_item : pad { cur_element.pads[cur_pad.name] = cur_pad; } ; integer : INTEGER { $$ = $1; } | '-' INTEGER { $$ = -$2; } ; pad : K_PAD '[' integer integer integer integer integer integer integer STRING STRING STRING ']' { cur_pad.rx1 = $3; cur_pad.ry1 = $4; cur_pad.rx2 = $5; cur_pad.ry2 = $6; cur_pad.thickness = $7; cur_pad.clearance = $8; cur_pad.mask = $9; cur_pad.name = $10; delete[]$10; cur_pad.number = $11; delete[]$11; cur_pad.sflags = $12; delete[]$12; } | K_PAD '[' error ']' { errormsg(@3, "Error in pad header\n"); yyerrok; cur_pad.rx1 = 0; cur_pad.ry1 = 0; cur_pad.rx2 = 0; cur_pad.ry2 = 0; cur_pad.thickness = 0; cur_pad.clearance = 0; cur_pad.mask = 0; cur_pad.name = ""; cur_pad.number = ""; cur_pad.sflags = ""; } ; %% static string parse_file_path; int parse_fp_errors = 0; int parse_fp_sorrys = 0; void errormsg(const YYLTYPE&loc, const char*fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%u: error: ", parse_file_path.c_str(), loc.first_line); vfprintf(stderr, fmt, ap); va_end(ap); parse_fp_errors += 1; } void sorrymsg(const YYLTYPE&loc, const char*fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%u: sorry: ", parse_file_path.c_str(), loc.first_line); vfprintf(stderr, fmt, ap); va_end(ap); parse_fp_sorrys += 1; } int parse_fp_file(const string&file_path) { FILE*fd = fopen(file_path.c_str(), "r"); if (fd == 0) { perror(file_path.c_str()); return -1; } parse_file_path = file_path; parse_fp_errors = 0; parse_fp_sorrys = 0; init_fp_lexor(fd); int rc = yyparse(file_path.c_str()); fclose(fd); destroy_fp_lexor(); return rc; } iverilog-12_0/tgt-pcb/fp_api.h000066400000000000000000000044021435245347300163160ustar00rootroot00000000000000#ifndef IVL_fp_api_H #define IVL_fp_api_H /* * Copyright (c) 2011-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ # include /* * This is the interface function that the user invokes to parse a * footprint file. The argument is the path to the element. */ extern int parse_fp_file(const std::string&file_path); /* * The yyltype supports the passing of detailed source file location * information between the lexical analyzer and the parser. Defining * YYLTYPE compels the lexor to use this type and not something other. */ struct yyltype { unsigned first_line; yyltype() { first_line = 1; } }; # define YYLTYPE struct yyltype /* * Use this function during parse to generate error messages. The "loc" * is the location of the token that triggered the error, and the fmt * is printf-style format. */ extern void errormsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3))); extern void sorrymsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3))); extern void callback_fp_element(const struct fp_element_t&); /* * Set this to a non-zero value to enable parser debug output. */ //extern int yydebug; /* * The parser counts the errors that is handed in the parse_errors * variable. For a clean compile, this value should not change. (The * caller sets its initial value.) The sorrys are the count of * unsupported constructs that are encountered. */ //extern int parse_errors; extern int parse_fp_sorrys; #endif /* IVL_fp_api_H */ iverilog-12_0/tgt-pcb/pcb-s.conf000066400000000000000000000001371435245347300165630ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=pcb.tgt iverilog-12_0/tgt-pcb/pcb.cc000066400000000000000000000053711435245347300157700ustar00rootroot00000000000000/* * Copyright (c) 2011-2020 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. */ /* * This is a PCB target module. */ # include "version_base.h" # include "version_tag.h" # include "pcb_config.h" # include # include # include # include "pcb_priv.h" # include "ivl_target.h" static const char*version_string = "Icarus Verilog PCB Netlist Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (c) 2011-2020 Stephen Williams (steve@icarus.com)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; int target_design(ivl_design_t des) { ivl_scope_t*root_scopes; unsigned nroot; unsigned idx; int rc = 0; const char*pcb_path = ivl_design_flag(des, "-o"); ivl_design_roots(des, &root_scopes, &nroot); for (idx = 0 ; idx < nroot ; idx += 1) { int tmp = scan_scope(root_scopes[idx]); if (tmp != 0) { rc = tmp; break; } } load_footprints(); assert(pcb_path); show_pcb(pcb_path); const char*net_path = ivl_design_flag(des, "netlist"); if (net_path != 0) { printf("Send netlist to %s\n", net_path); show_netlist(net_path); } return rc; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } iverilog-12_0/tgt-pcb/pcb.conf000066400000000000000000000000601435245347300163160ustar00rootroot00000000000000functor:cprop functor:nodangle flag:DLL=pcb.tgt iverilog-12_0/tgt-pcb/pcb_config.h.in000066400000000000000000000020151435245347300175540ustar00rootroot00000000000000#ifndef IVL_pcb_config_H #define IVL_pcb_config_H /* * Copyright (c) 2011-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. */ # undef HAVE_STDINT_H # undef HAVE_INTTYPES_H # undef _LARGEFILE_SOURCE # undef _LARGEFILE64_SOURCE #endif /* IVL_pcb_config_H */ iverilog-12_0/tgt-pcb/pcb_priv.h000066400000000000000000000045501435245347300166700ustar00rootroot00000000000000#ifndef IVL_pcb_priv_H #define IVL_pcb_priv_H /* * Copyright (c) 2011-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 # include # include # include # include "ivl_target.h" extern int scan_scope(ivl_scope_t scope); /* * This nexus_list is a list of all the nets that the scan_scope * collects, wrapped up into a list. The show_netlist dumps that list * as a netlist. */ struct nexus_data { std::string name; std::set pins; }; extern std::list nexus_list; /* * The element_list is a collection of all the elements that were * located by the scope scan. The key is the refdes for the element, * and the value is the element_data_t structure that describes that * element. */ struct element_data_t { std::string description; std::string value; std::string footprint; }; extern std::map element_list; extern int load_footprints(void); struct fp_pad_t { long rx1, ry1; long rx2, ry2; int thickness; int clearance; int mask; std::string name; std::string number; std::string sflags; }; struct fp_element_t { long nflags; std::string description; std::string name; std::string value; long mx, my; long tx, ty; int tdir; int tscale; std::string tsflags; std::map pads; }; extern std::map footprints; extern void show_netlist(const char*net_path); extern void show_pcb(const char*pcb_path); #endif /* IVL_pcb_priv_H */ iverilog-12_0/tgt-pcb/scope.cc000066400000000000000000000152151435245347300163330ustar00rootroot00000000000000/* * Copyright (c) 2011-2013 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 "pcb_priv.h" # include # include # include # include using namespace std; list nexus_list; map element_list; struct attr_value { ivl_attribute_type_t type; string str; long num; }; static void sheet_box(ivl_scope_t scope, const map&attrs); static void black_box(ivl_scope_t scope, const map&attrs); static string wire_name(ivl_signal_t sig); int scan_scope(ivl_scope_t scope) { int black_box_flag = 0; map attrs; // Scan the attributes, looking in particular for the // black_box attribute. While we are at it, save the collected // attributes into a map that we can pass on to the processing // functions. for (unsigned idx = 0 ; idx < ivl_scope_attr_cnt(scope) ; idx += 1) { ivl_attribute_t attr = ivl_scope_attr_val(scope, idx); string attr_key = attr->key; if (attr_key == "ivl_black_box") { // Ah hah, this is a black box. black_box_flag = 1; } else { struct attr_value val; val.type = attr->type; switch (val.type) { case IVL_ATT_VOID: break; case IVL_ATT_STR: val.str = attr->val.str; break; case IVL_ATT_NUM: val.num = attr->val.num; break; } attrs[attr_key] = val; } } // If this scope is a black box, then process it // so. Otherwise, process it as a sheet, which will recurse. if (black_box_flag) { black_box(scope, attrs); } else { sheet_box(scope, attrs); } return 0; } extern "C" int child_scan_fun(ivl_scope_t scope, void*) { scan_scope(scope); return 0; } void sheet_box(ivl_scope_t scope, const map&) { printf("Sheet %s...\n", ivl_scope_name(scope)); unsigned sigs = ivl_scope_sigs(scope); for (unsigned idx = 0 ; idx < sigs ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); printf(" Wire %s\n", ivl_signal_basename(sig)); assert(ivl_signal_array_count(sig) == 1); ivl_nexus_t nex = ivl_signal_nex(sig, 0); struct nexus_data*nex_data = reinterpret_cast (ivl_nexus_get_private(nex)); if (nex_data == 0) { nex_data = new nexus_data; nex_data->name = wire_name(sig); nexus_list.push_back(nex_data); ivl_nexus_set_private(nex, nex_data); } } ivl_scope_children(scope, child_scan_fun, 0); } /* * A black box is a component. Do not process the contents, other than * to get at the ports that we'll attach to the netlist. */ static void black_box(ivl_scope_t scope, const map&attrs) { assert(ivl_scope_type(scope) == IVL_SCT_MODULE); printf(" Component %s is %s\n", ivl_scope_name(scope), ivl_scope_tname(scope)); // The refdes for the object is by default the name of // the instance. If the user attaches a refdes // attribute, then use that instead. string refdes = ivl_scope_basename(scope); map::const_iterator aptr = attrs.find("refdes"); if (aptr != attrs.end()) { assert(aptr->second.type == IVL_ATT_STR); refdes = aptr->second.str; } element_data_t*elem_data = new element_data_t; // Scan the parameters of the module for any values that may // be of interest to the PCB element. unsigned params = ivl_scope_params(scope); for (unsigned idx = 0 ; idx < params ; idx += 1) { ivl_parameter_t par = ivl_scope_param(scope, idx); string name = ivl_parameter_basename(par); if (name == "description") { ivl_expr_t exp = ivl_parameter_expr(par); switch (ivl_expr_type(exp)) { case IVL_EX_STRING: elem_data->description = ivl_expr_string(exp); break; default: assert(0); } } else if (name == "value") { ivl_expr_t exp = ivl_parameter_expr(par); switch (ivl_expr_type(exp)) { case IVL_EX_STRING: elem_data->value = ivl_expr_string(exp); break; default: assert(0); } } else if (name == "footprint") { ivl_expr_t exp = ivl_parameter_expr(par); switch (ivl_expr_type(exp)) { case IVL_EX_STRING: elem_data->footprint = ivl_expr_string(exp); break; default: assert(0); } } } // If there is a "description" attribute for the device, then // use that in place of the parameter. if ( (aptr = attrs.find("description")) != attrs.end() ) { assert(aptr->second.type == IVL_ATT_STR); elem_data->description = aptr->second.str; } // Get the "value" attribute for the device. if ( (aptr = attrs.find("value")) != attrs.end() ) { switch (aptr->second.type) { case IVL_ATT_VOID: break; case IVL_ATT_STR: elem_data->value = aptr->second.str; break; case IVL_ATT_NUM: assert(0); break; } } // Look for the ports of the black box and make sure they are // attached to signals. Attach the port as a pin wired to a net. unsigned sigs = ivl_scope_sigs(scope); for (unsigned idx = 0 ; idx < sigs ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); ivl_signal_port_t sip = ivl_signal_port(sig); // Skip signals that are not ports. if (sip == IVL_SIP_NONE) continue; assert(ivl_signal_array_count(sig) == 1); ivl_nexus_t nex = ivl_signal_nex(sig, 0); struct nexus_data*nex_data = reinterpret_cast(ivl_nexus_get_private(nex)); assert(nex_data); string pindes = ivl_signal_basename(sig); string pin = refdes + "-" + pindes; nex_data->pins.insert(pin); printf(" port %s\n", ivl_signal_basename(sig)); } element_data_t*&eptr = element_list[refdes]; assert(eptr == 0); eptr = elem_data; } static string wire_name(ivl_signal_t sig) { string res = ivl_signal_basename(sig); return res; } iverilog-12_0/tgt-pcb/show_netlist.cc000066400000000000000000000027361435245347300177500ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "pcb_priv.h" # include # include using namespace std; void show_netlist(const char*net_path) { assert(net_path); FILE*fnet = fopen(net_path, "w"); if (fnet == 0) { perror(net_path); return; } for (list::iterator cur = nexus_list.begin() ; cur != nexus_list.end() ; ++ cur) { nexus_data*curp = *cur; fprintf(fnet, "%s", curp->name.c_str()); for (set::const_iterator cp = curp->pins.begin() ; cp != curp->pins.end() ; ++ cp) { fprintf(fnet, " %s", cp->c_str()); } fprintf(fnet, "\n"); } fclose(fnet); } iverilog-12_0/tgt-pcb/show_pcb.cc000066400000000000000000000062261435245347300170300ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "pcb_config.h" # include "pcb_priv.h" # include # include using namespace std; static void show_pcb_header(FILE*fpcb) { fprintf(fpcb, "PCB[\"\" 400000 220000]\n"); fprintf(fpcb, "Grid[100.0 0 0 1]\n"); } static void show_pcb_element(FILE*fpcb, const string&refdes, element_data_t*elem); void show_pcb(const char*pcb_path) { assert(pcb_path); FILE*fpcb = fopen(pcb_path, "w"); if (fpcb == 0) { perror(pcb_path); return; } show_pcb_header(fpcb); // Draw the collected elements for (map::const_iterator cur = element_list.begin() ; cur != element_list.end() ; ++ cur) { show_pcb_element(fpcb, cur->first, cur->second); } fclose(fpcb); } static void show_pcb_element(FILE*fpcb, const string&refdes, element_data_t*elem) { string descr = elem->description; const string&value = elem->value; if (elem->footprint == "") { fprintf(fpcb, "Element[\"\" \"%s\" \"%s\" \"%s\"", descr.c_str(), refdes.c_str(), value.c_str()); // Mark-X Mark-Y fprintf(fpcb, " 0 0"); // Text-X Text-Y text-direction Text-scale Text-flags fprintf(fpcb, " 0 0 0 100 \"\""); fprintf(fpcb, "]\n"); // Fill in the contents of the element. Should get this // from a library. fprintf(fpcb, "(\n"); fprintf(fpcb, ")\n"); return; } fp_element_t&foot = footprints[elem->footprint]; if (descr == "") descr = foot.description; fprintf(fpcb, "Element[0x%lx \"%s\" \"%s\" \"%s\"", foot.nflags, descr.c_str(), refdes.c_str(), value.c_str()); fprintf(fpcb, " %ld %ld", foot.mx, foot.my); fprintf(fpcb, " %ld %ld %d %d \"%s\"", foot.tx, foot.ty, foot.tdir, foot.tscale, foot.tsflags.c_str()); fprintf(fpcb, "]\n(\n"); for (map::const_iterator cur = foot.pads.begin() ; cur != foot.pads.end() ; ++ cur) { fprintf(fpcb, "Pad[%ld %ld %ld %ld %d %d %d \"%s\" \"%s\" \"%s\"]\n", cur->second.rx1, cur->second.ry1, cur->second.rx2, cur->second.ry2, cur->second.thickness, cur->second.clearance, cur->second.mask, cur->second.name.c_str(), cur->second.number.c_str(), cur->second.sflags.c_str()); } fprintf(fpcb, ")\n"); } iverilog-12_0/tgt-sizer/000077500000000000000000000000001435245347300152775ustar00rootroot00000000000000iverilog-12_0/tgt-sizer/Makefile.in000066400000000000000000000052741435245347300173540ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ CXX = @CXX@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ O = sizer.o scan_lpms.o scan_logs.o all: dep sizer.tgt check: all clean: rm -rf *.o dep sizer.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.cc) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-sizer/$@ dep: mkdir dep %.o: %.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif sizer.tgt: $O $(TGTDEPLIBS) $(CXX) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./sizer.tgt \ $(srcdir)/sizer.conf \ $(srcdir)/sizer-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./sizer.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.tgt" $(INSTALL_DATA) $(srcdir)/sizer.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.conf" $(INSTALL_DATA) $(srcdir)/sizer-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/sizer-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-sizer/cppcheck.sup000066400000000000000000000002751435245347300176140ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:sizer.cc:76 // target_query() unusedFunction:sizer.cc:65 iverilog-12_0/tgt-sizer/scan_logs.cc000066400000000000000000000032141435245347300175560ustar00rootroot00000000000000/* * Copyright (c) 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 "sizer_priv.h" void scan_logs_gates(ivl_scope_t, ivl_net_logic_t log, struct sizer_statistics&stats) { unsigned wid = ivl_logic_width(log); stats.gate_count += wid; } void scan_logs(ivl_scope_t scope, struct sizer_statistics&stats) { for (unsigned idx = 0 ; idx < ivl_scope_logs(scope) ; idx += 1) { ivl_net_logic_t log = ivl_scope_log(scope, idx); switch (ivl_logic_type(log)) { // These logic gate types don't really exist in a // mapped design. case IVL_LO_BUFZ: break; case IVL_LO_AND: case IVL_LO_OR: case IVL_LO_XOR: case IVL_LO_NAND: case IVL_LO_NOR: case IVL_LO_XNOR: case IVL_LO_BUF: case IVL_LO_NOT: scan_logs_gates(scope, log, stats); break; default: stats.log_bytype[ivl_logic_type(log)] += 1; break; } } } iverilog-12_0/tgt-sizer/scan_lpms.cc000066400000000000000000000110121435245347300175600ustar00rootroot00000000000000/* * Copyright (c) 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 "sizer_priv.h" using namespace std; /* * Count each bit of flip-flops. It is clear and obvious how these * come out, so no need to make alternate counts as well. */ static void scan_lpms_ff(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { ivl_nexus_t out = ivl_lpm_q(lpm); unsigned wid = get_nexus_width(out); stats.flop_count += wid; } /* * Count adders as 2m gates. * Also keep a count of adders by width, just out of curiosity. */ static void scan_lpms_add(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { unsigned wid = ivl_lpm_width(lpm); stats.adder_count[wid] += 1; stats.gate_count += 2*wid; } /* * Count equality comparator as 2m gates. * Also keep a count of comparators by width, just out of curiosity. */ static void scan_lpms_equality(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { unsigned wid = ivl_lpm_width(lpm); stats.equality_count[wid] += 1; stats.gate_count += 2*wid; } static void scan_lpms_equality_wild(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { unsigned wid = ivl_lpm_width(lpm); stats.equality_wc_count[wid] += 1; stats.gate_count += 2*wid; } /* * Count magnitude comparators as 2m gates. * Also keep a count of comparators by width, just out of curiosity. */ static void scan_lpms_magnitude(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { unsigned wid = ivl_lpm_width(lpm); stats.magnitude_count[wid] += 1; stats.gate_count += 2*wid; } /* * Count mux devices as 2m gates. * Also count the mux slices of various select sizes. */ static void scan_lpms_mux(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { // For now, don't generate statistics for wide mux devices. if (ivl_lpm_size(lpm) > 2) { stats.lpm_bytype[ivl_lpm_type(lpm)] += 1; return; } // The "width" of a mux is the number of 1-bit slices. unsigned wid = ivl_lpm_width(lpm); // Count the slices of the various width of muxes. stats.mux_count[2] += wid; stats.gate_count += 2*wid; } /* * Count reduction gates (wide input gates) as 1m gates. */ static void scan_lpms_reduction(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats) { unsigned wid = ivl_lpm_width(lpm); stats.gate_count += wid; } void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats) { for (unsigned idx = 0 ; idx < ivl_scope_lpms(scope) ; idx += 1) { ivl_lpm_t lpm = ivl_scope_lpm(scope,idx); switch (ivl_lpm_type(lpm)) { // Part select nodes don't actually take up // hardware. These represent things like bundle // manipulations, which are done in routing. case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: case IVL_LPM_REPEAT: case IVL_LPM_SUBSTITUTE: break; case IVL_LPM_ADD: scan_lpms_add(scope, lpm, stats); break; case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_NEE: scan_lpms_equality(scope, lpm, stats); break; case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: scan_lpms_equality_wild(scope, lpm, stats); break; case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: scan_lpms_magnitude(scope, lpm, stats); break; // D-Type flip-flops. case IVL_LPM_FF: scan_lpms_ff(scope, lpm, stats); break; case IVL_LPM_MUX: scan_lpms_mux(scope, lpm, stats); break; case IVL_LPM_RE_AND: case IVL_LPM_RE_NAND: case IVL_LPM_RE_OR: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_XNOR: scan_lpms_reduction(scope, lpm, stats); break; default: stats.lpm_bytype[ivl_lpm_type(lpm)] += 1; break; } } } iverilog-12_0/tgt-sizer/sizer-s.conf000066400000000000000000000001411435245347300175360ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=sizer.tgt iverilog-12_0/tgt-sizer/sizer.cc000066400000000000000000000204431435245347300167450ustar00rootroot00000000000000/* * Copyright (c) 2014-2020 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 "version_base.h" # include "version_tag.h" # include "config.h" # include "sizer_priv.h" # include # include # include using namespace std; /* * This is a null target module. It does nothing. */ static const char*version_string = "Icarus Verilog SIZER Statistics Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (c) 2014-2020 Stephen Williams (steve@icarus.com)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; int sizer_errors = 0; FILE*sizer_out = 0; static int process_scan_fun(ivl_process_t net, void*raw); static void emit_sizer_scope(ivl_design_t des, ivl_scope_t model, struct sizer_statistics&stats); static void show_stats(struct sizer_statistics&stats); /* * This is called by the ivl core to get version information from the * loadable code generator. */ const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } /* * This is the main entry point from the IVL core. */ int target_design(ivl_design_t des) { const char*sizer_path = ivl_design_flag(des, "-o"); sizer_out = fopen(sizer_path, "wt"); assert(sizer_out); // Detect processes and dispatch them. ivl_design_process(des, &process_scan_fun, 0); // Locate the root scopes for the design. ivl_scope_t*roots; unsigned nroots; ivl_design_roots(des, &roots, &nroots); // Process all the root scopes. It is possible that there are // multiple root scopes, we will give isolated numbers for // each and keep then separate. for (unsigned idx = 0 ; idx < nroots ; idx += 1) { if (ivl_scope_type(roots[idx]) != IVL_SCT_MODULE) { fprintf(stderr, "SIZER: The root scope %s must be a module.\n", ivl_scope_basename(roots[idx])); sizer_errors += 1; continue; } struct sizer_statistics stats; emit_sizer_scope(des, roots[idx], stats); fprintf(sizer_out, "**** TOTALS\n"); show_stats(stats); } return sizer_errors; } /* * Processes are not collected into scopes, but we should not have any * left anyhow. Give error messages for all the processes that we find * to be remaining. */ static int process_scan_fun(ivl_process_t net, void* /*raw*/) { for (unsigned idx = 0 ; idx < ivl_process_attr_cnt(net) ; idx += 1) { ivl_attribute_t att = ivl_process_attr_val(net, idx); // If synthesis is explicitly turned off for this // process, then we just ignore it. if (strcmp(att->key, "ivl_synthesis_off") == 0) return 0; } fprintf(stderr, "%s:%u: SIZER: Processes not synthesized for statistics.\n", ivl_process_file(net), ivl_process_lineno(net)); sizer_errors += 1; return 0; } static void emit_sizer_scope(ivl_design_t des, ivl_scope_t scope, struct sizer_statistics&stats) { fprintf(sizer_out, "**** module/scope: %s\n", ivl_scope_name(scope)); scan_logs(scope, stats); scan_lpms(scope, stats); show_stats(stats); for (size_t idx = 0 ; idx < ivl_scope_childs(scope) ; idx += 1) { ivl_scope_t child = ivl_scope_child(scope,idx); struct sizer_statistics child_stats; emit_sizer_scope(des, child, child_stats); stats += child_stats; } } static void show_stats(struct sizer_statistics&stats) { fprintf(sizer_out, " Flip-Flops : %u\n", stats.flop_count); fprintf(sizer_out, " Logic Gates : %u\n", stats.gate_count); for (map::const_iterator cur = stats.adder_count.begin() ; cur != stats.adder_count.end() ; ++ cur) { fprintf(sizer_out, " ADDER[%u]: %u units\n", cur->first, cur->second); } for (map::const_iterator cur = stats.equality_count.begin() ; cur != stats.equality_count.end() ; ++ cur) { fprintf(sizer_out, " EQUALITY[%u]: %u units\n", cur->first, cur->second); } for (map::const_iterator cur = stats.equality_wc_count.begin() ; cur != stats.equality_wc_count.end() ; ++ cur) { fprintf(sizer_out, " EQUALITY_WC[%u]: %u units\n", cur->first, cur->second); } for (map::const_iterator cur = stats.magnitude_count.begin() ; cur != stats.magnitude_count.end() ; ++ cur) { fprintf(sizer_out, " MAGNITUDE[%u]: %u units\n", cur->first, cur->second); } for (map::const_iterator cur = stats.mux_count.begin() ; cur != stats.mux_count.end() ; ++ cur) { fprintf(sizer_out, " MUX[%u]: %u slices\n", cur->first, cur->second); } // These are diagnostic outputs for when more detail is needed. for (map::const_iterator cur = stats.lpm_bytype.begin() ; cur != stats.lpm_bytype.end() ; ++ cur) { fprintf(sizer_out, " LPM[%d]: %u unaccounted\n", cur->first, cur->second); } for (map::const_iterator cur = stats.log_bytype.begin() ; cur != stats.log_bytype.end() ; ++ cur) { fprintf(sizer_out, " LOG[%d]: %u unaccounted\n", cur->first, cur->second); } } unsigned get_nexus_width(ivl_nexus_t nex) { for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex,idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig) return ivl_signal_width(sig); } fprintf(stderr, "SIZER: Unable to find width of nexus?!\n"); sizer_errors += 1; return 0; } struct sizer_statistics& sizer_statistics::operator += (const sizer_statistics&that) { flop_count += that.flop_count; gate_count += that.gate_count; for (map::const_iterator cur = that.adder_count.begin() ; cur != that.adder_count.end() ; ++ cur) adder_count[cur->first] += cur->second; for (map::const_iterator cur = that.equality_count.begin() ; cur != that.equality_count.end() ; ++ cur) equality_count[cur->first] += cur->second; for (map::const_iterator cur = that.equality_wc_count.begin() ; cur != that.equality_wc_count.end() ; ++ cur) equality_wc_count[cur->first] += cur->second; for (map::const_iterator cur = that.magnitude_count.begin() ; cur != that.magnitude_count.end() ; ++ cur) magnitude_count[cur->first] += cur->second; for (map::const_iterator cur = that.mux_count.begin() ; cur != that.mux_count.end() ; ++ cur) mux_count[cur->first] += cur->second; for (map::const_iterator cur = that.lpm_bytype.begin() ; cur != that.lpm_bytype.end() ; ++ cur) lpm_bytype[cur->first] += cur->second; for (map::const_iterator cur = that.log_bytype.begin() ; cur != that.log_bytype.end() ; ++ cur) log_bytype[cur->first] += cur->second; return *this; } iverilog-12_0/tgt-sizer/sizer.conf000066400000000000000000000001411435245347300172760ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=sizer.tgt iverilog-12_0/tgt-sizer/sizer_priv.h000066400000000000000000000041651435245347300176520ustar00rootroot00000000000000#ifndef IVL_sizer_priv_H #define IVL_sizer_priv_H /* * Copyright (c) 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 "config.h" # include "ivl_target.h" # include # include struct sizer_statistics { // These are the accumulated global statistics unsigned flop_count; unsigned gate_count; // Count adders of various dimension std::map adder_count; // count equality comparators std::map equality_count; // count equality (with wildcard) comparators std::map equality_wc_count; // Count magnitude comparators std::map magnitude_count; // Count mux's of various dimension std::map mux_count; // Different kinds of nodes that we have not accounted for std::map lpm_bytype; std::map log_bytype; inline sizer_statistics() { flop_count = 0; gate_count = 0; } struct sizer_statistics& operator += (const struct sizer_statistics&that); }; extern int sizer_errors; extern FILE*sizer_out; extern void scan_logs(ivl_scope_t scope, struct sizer_statistics&stats); extern void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats); extern unsigned get_nexus_width(ivl_nexus_t nex); #endif /* IVL_sizer_priv_H */ iverilog-12_0/tgt-stub/000077500000000000000000000000001435245347300151205ustar00rootroot00000000000000iverilog-12_0/tgt-stub/Makefile.in000066400000000000000000000053341435245347300171720ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = stub.o classes.o constant.o enumerate.o expression.o statement.o switches.o types.o all: dep stub.tgt check: all clean: rm -rf *.o dep stub.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-stub/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif stub.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./stub.tgt \ $(srcdir)/stub.conf \ $(srcdir)/stub-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./stub.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/stub.tgt" $(INSTALL_DATA) $(srcdir)/stub.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/stub.conf" $(INSTALL_DATA) $(srcdir)/stub-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/stub-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/stub.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/stub.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/stub-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-stub/classes.c000066400000000000000000000023041435245347300167200ustar00rootroot00000000000000/* * Copyright (c) 2012 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 "priv.h" # include void show_class(ivl_type_t net) { fprintf(out, " class %s\n", ivl_type_name(net)); for (int idx = 0 ; idx < ivl_type_properties(net) ; idx += 1) { fprintf(out, " "); show_net_type(ivl_type_prop_type(net,idx)); fprintf(out, " %s\n", ivl_type_prop_name(net,idx)); } } iverilog-12_0/tgt-stub/constant.c000066400000000000000000000030431435245347300171150ustar00rootroot00000000000000/* * Copyright (c) 2013-2015 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 "priv.h" # include # include # include void show_constant(ivl_net_const_t net) { assert(net); fprintf(out, "constant "); switch (ivl_const_type(net)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: { const char*bits = ivl_const_bits(net); unsigned idx; assert(bits); for (idx = 0 ; idx < ivl_const_width(net) ; idx += 1) fprintf(out, "%c", bits[idx]); } break; case IVL_VT_REAL: fprintf(out, "%f", ivl_const_real(net)); break; default: fprintf(out, ""); break; } fprintf(out, " at %s:%u\n", ivl_const_file(net), ivl_const_lineno(net)); } iverilog-12_0/tgt-stub/cppcheck.sup000066400000000000000000000002751435245347300174350ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:stub.c:1837 // target_query() unusedFunction:stub.c:1907 iverilog-12_0/tgt-stub/enumerate.c000066400000000000000000000025621435245347300172560ustar00rootroot00000000000000/* * Copyright (c) 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 "priv.h" # include void show_enumerate(ivl_enumtype_t net) { unsigned idx; fprintf(out, " enumeration %p {\n", net); for (idx = 0 ; idx < ivl_enum_names(net) ; idx += 1) { fprintf(out, " %s = <", ivl_enum_name(net, idx)); const char*bits = ivl_enum_bits(net, idx); size_t bits_len = strlen(bits); size_t bit; for (bit = bits_len ; bit > 0 ; bit -= 1) fputc(bits[bit-1], out); fprintf(out, ">\n"); } fprintf(out, " }\n"); } iverilog-12_0/tgt-stub/expression.c000066400000000000000000000431101435245347300174620ustar00rootroot00000000000000/* * Copyright (c) 2007-2021 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 "priv.h" # include # include # include static const char*vt_type_string(ivl_expr_t net) { return data_type_string(ivl_expr_value(net)); } static void show_array_expression(ivl_expr_t net, unsigned ind) { ivl_signal_t sig = ivl_expr_signal(net); const char*name = ivl_signal_basename(sig); unsigned width = ivl_signal_width(sig); const char*vt = vt_type_string(net); fprintf(out, "%*sArray: %s, word_count=%u (%u dimensions), width=%u, type=%s\n", ind, "", name, ivl_signal_array_count(sig), ivl_signal_dimensions(sig), width, vt); } static void show_array_pattern_expression(ivl_expr_t net, unsigned ind) { size_t idx; fprintf(out, "%*sArrayPattern (%s): %u expressions\n", ind, "", vt_type_string(net), ivl_expr_parms(net)); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) { show_expression(ivl_expr_parm(net,idx), ind+4); } } static void show_branch_access_expression(ivl_expr_t net, unsigned ind) { ivl_branch_t bra = ivl_expr_branch(net); ivl_nature_t nature = ivl_expr_nature(net); fprintf(out, "%*s\n", ind, "", bra, ivl_nature_name(nature)); if (ivl_expr_value(net) != IVL_VT_REAL) { fprintf(out, "%*sERROR: Expecting type IVL_VT_REAL, got %s\n", ind, "", vt_type_string(net)); stub_errors += 1; } ivl_nexus_t ta = ivl_branch_terminal(bra, 0); ivl_nexus_t tb = ivl_branch_terminal(bra, 1); ivl_discipline_t ta_disc = discipline_of_nexus(ta); if (ta_disc == 0) { fprintf(out, "%*sERROR: Source terminal of branch has no discipline\n", ind, ""); stub_errors += 1; return; } ivl_discipline_t tb_disc = discipline_of_nexus(tb); if (tb_disc == 0) { fprintf(out, "%*sERROR: Reference terminal of branch has no discipline\n", ind, ""); stub_errors += 1; return; } if (ta_disc != tb_disc) { fprintf(out, "%*sERROR: Branch terminal disciplines mismatch: %s != %s\n", ind, "", ivl_discipline_name(ta_disc), ivl_discipline_name(tb_disc)); stub_errors += 1; } } static void show_binary_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); ivl_expr_t oper1 = ivl_expr_oper1(net); ivl_expr_t oper2 = ivl_expr_oper2(net); fprintf(out, "%*s<\"%c\" width=%u, %s, type=%s>\n", ind, "", ivl_expr_opcode(net), width, sign, vt); if (oper1) { show_expression(oper1, ind+3); } else { fprintf(out, "%*sERROR: Missing operand 1\n", ind+3, ""); stub_errors += 1; } if (oper2) { show_expression(oper2, ind+3); } else { fprintf(out, "%*sERROR: Missing operand 2\n", ind+3, ""); stub_errors += 1; } switch (ivl_expr_opcode(net)) { case '*': if (ivl_expr_value(net) == IVL_VT_REAL) { if (ivl_expr_width(net) != 1) { fprintf(out, "%*sERROR: Result width incorrect. Expecting 1, got %u\n", ind+3, "", ivl_expr_width(net)); stub_errors += 1; } } else { /* The width of a multiply may be any width. The implicit assumption is that the multiply returns a width that is the sum of the widths of the arguments, that is then truncated to the desired width, never padded. The compiler will automatically take care of sign extensions of arguments, so that the code generator need only generate an UNSIGNED multiply, and the result will come out right. */ unsigned max_width = ivl_expr_width(oper1) + ivl_expr_width(oper2); if (ivl_expr_width(net) > max_width) { fprintf(out, "%*sERROR: Result width to width. Expecting <= %u, got %u\n", ind+3, "", max_width, ivl_expr_width(net)); stub_errors += 1; } } break; default: break; } } static void show_enumtype_expression(ivl_expr_t net, unsigned ind) { fprintf(out, "%*s\n", ind, "", ivl_expr_enumtype(net)); } static void show_function_call(ivl_expr_t net, unsigned ind) { ivl_scope_t def = ivl_expr_def(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); unsigned idx; fprintf(out, "%*s<%s %s function %s with %u arguments (width=%u)>\n", ind, "", vt, sign, ivl_scope_name(def), ivl_expr_parms(net), ivl_expr_width(net)); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net,idx), ind+4); } static void show_memory_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); fprintf(out, "%*s\n", ind, "", width); } static void show_new_expression(ivl_expr_t net, unsigned ind) { switch (ivl_expr_value(net)) { case IVL_VT_CLASS: fprintf(out, "%*snew \n", ind, ""); if (ivl_expr_oper1(net)) { fprintf(out, "%*sERROR: class_new expression has a size!\n", ind+3, ""); show_expression(ivl_expr_oper1(net), ind+3); stub_errors += 1; } if (ivl_expr_oper2(net)){ fprintf(out, "%*sERROR: class_new with array element initializer!\n", ind+3, ""); show_expression(ivl_expr_oper2(net), ind+3); stub_errors += 1; } break; case IVL_VT_DARRAY: fprintf(out, "%*snew [] \n", ind, ""); if (ivl_expr_oper1(net)) { show_expression(ivl_expr_oper1(net), ind+3); } else { fprintf(out, "%*sERROR: darray_new missing size expression\n", ind+3, ""); stub_errors += 1; } /* The IVL_EX_NEW expression may include an element initializer. This may be an array pattern or simple expression. */ if (ivl_expr_oper2(net)) { show_expression(ivl_expr_oper2(net), ind+3); } break; default: fprintf(out, "%*snew ERROR: expression type: %s\n", ind+3, "", vt_type_string(net)); stub_errors += 1; break; } } static void show_null_expression(ivl_expr_t net, unsigned ind) { fprintf(out, "%*s\n", ind, ""); if (ivl_expr_value(net) != IVL_VT_CLASS) { fprintf(out, "%*sERROR: null expression must be IVL_VT_CLASS, got %s.\n", ind+3, "", vt_type_string(net)); stub_errors += 1; } } static void show_property_expression(ivl_expr_t net, unsigned ind) { ivl_signal_t sig = ivl_expr_signal(net); const char* pnam = ivl_expr_name(net); const char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned"; ivl_expr_t index; if (ivl_expr_value(net) == IVL_VT_REAL) { fprintf(out, "%*s\n", ind, "", ivl_signal_basename(sig), pnam); } else if (ivl_expr_value(net) == IVL_VT_STRING) { fprintf(out, "%*s\n", ind, "", ivl_signal_basename(sig), pnam); } else { fprintf(out, "%*s\n", ind, "", ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag); } if ( (index=ivl_expr_oper1(net)) ) { show_expression(index, ind+3); } if (ivl_signal_data_type(sig) != IVL_VT_CLASS) { fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n", ind+3, "", data_type_string(ivl_signal_data_type(sig))); } } static void show_select_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); ivl_expr_t oper1 = ivl_expr_oper1(net); ivl_expr_t oper2 = ivl_expr_oper2(net); if (ivl_expr_value(oper1) == IVL_VT_STRING) { /* If the sub-expression is a STRING, then this is a substring and the code generator will handle it differently. */ fprintf(out, "%*s\n", ind, "", width, width/8); if (width%8 != 0) { fprintf(out, "%*sERROR: Width should be a multiple of 8 bits.\n", ind, ""); stub_errors += 1; } assert(oper1); show_expression(oper1, ind+3); if (oper2) { show_expression(oper2, ind+3); } else { fprintf(out, "%*sERROR: oper2 missing! Pad makes no sense for IVL_VT_STRING expressions.\n", ind+3, ""); stub_errors += 1; } } else if (oper2) { /* If oper2 is present, then it is the base of a part select. The width of the expression defines the range of the part select. */ fprintf(out, "%*s\n", ind, "", width, sign, vt); show_expression(oper1, ind+3); show_expression(oper2, ind+3); } else { /* There is no base expression so this is a pad operation. The sub-expression is padded (signed or unsigned as appropriate) to the expression width. */ fprintf(out, "%*s\n", ind, "", width, sign); show_expression(oper1, ind+3); } } static void show_shallowcopy(ivl_expr_t net, unsigned ind) { ivl_expr_t oper1 = ivl_expr_oper1(net); ivl_expr_t oper2 = ivl_expr_oper2(net); fprintf(out, "%*s\n", ind, ""); show_expression(oper1, ind+3); show_expression(oper2, ind+3); if (ivl_expr_value(oper1) != ivl_expr_value(oper2)) { fprintf(out, "%*sERROR: Shallow copy operand types must match.\n", ind+3,""); stub_errors += 1; } if (ivl_expr_value(oper1)!=IVL_VT_CLASS && ivl_expr_value(oper1)!=IVL_VT_DARRAY) { fprintf(out, "%*sERROR: Operand 1 type is %s\n", ind+3, "", vt_type_string(oper1)); stub_errors += 1; } } static void show_signal_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); ivl_expr_t word = ivl_expr_oper1(net); ivl_signal_t sig = ivl_expr_signal(net); ivl_variable_type_t data_type = ivl_signal_data_type(sig); const char*vt_sig = data_type_string(data_type); unsigned dimensions = ivl_signal_dimensions(sig); unsigned word_count = ivl_signal_array_count(sig); if (data_type==IVL_VT_QUEUE) { if (dimensions != 0) { fprintf(out, "%*sERROR: Queue objects expect dimensions==0, got %u.\n", ind, "", dimensions); stub_errors += 1; } } else if (dimensions == 0 && word_count != 1) { fprintf(out, "%*sERROR: Word count = %u for non-array object\n", ind, "", word_count); stub_errors += 1; } fprintf(out, "%*s\n", ind, "", ivl_expr_name(net), word_count, width, sign, vt, vt_sig); /* If the expression refers to a signal array, then there must also be a word select expression, and if the signal is not an array, there must NOT be a word expression. */ if (dimensions == 0 && word != 0) { fprintf(out, "%*sERROR: Unexpected word expression\n", ind+2, ""); stub_errors += 1; } if (dimensions >= 1 && word == 0) { fprintf(out, "%*sERROR: Missing word expression\n", ind+2, ""); stub_errors += 1; } /* If this is not an array, then the expression with must match the signal width. We have IVL_EX_SELECT expressions for casting signal widths. */ if (dimensions == 0 && data_type!=IVL_VT_QUEUE && ivl_signal_width(sig) != width) { fprintf(out, "%*sERROR: Expression width (%u) doesn't match ivl_signal_width(sig)=%u\n", ind+2, "", width, ivl_signal_width(sig)); stub_errors += 1; } if (word != 0) { fprintf(out, "%*sAddress-0 word address:\n", ind+2, ""); show_expression(word, ind+2); } } static void show_ternary_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); fprintf(out, "%*s\n", ind, "", width, sign, vt); show_expression(ivl_expr_oper1(net), ind+4); show_expression(ivl_expr_oper2(net), ind+4); show_expression(ivl_expr_oper3(net), ind+4); if (ivl_expr_width(ivl_expr_oper2(net)) != width) { fprintf(out, "ERROR: Width of TRUE expressions is %u, not %u\n", ivl_expr_width(ivl_expr_oper2(net)), width); stub_errors += 1; } if (ivl_expr_width(ivl_expr_oper3(net)) != width) { fprintf(out, "ERROR: Width of FALSE expressions is %u, not %u\n", ivl_expr_width(ivl_expr_oper3(net)), width); stub_errors += 1; } } static void show_unary_expression(ivl_expr_t net, unsigned ind) { unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*vt = vt_type_string(net); char name[8]; switch (ivl_expr_opcode(net)) { default: snprintf(name, sizeof name, "%c", ivl_expr_opcode(net)); break; case 'm': snprintf(name, sizeof name, "abs()"); break; } if (ivl_expr_opcode(net) == '!' && ivl_expr_value(net) == IVL_VT_REAL) { fprintf(out, "%*sERROR: Real argument to unary ! !?\n", ind,""); stub_errors += 1; } fprintf(out, "%*s\n", ind, "", name, width, sign, vt); show_expression(ivl_expr_oper1(net), ind+4); } void show_expression(ivl_expr_t net, unsigned ind) { assert(net); unsigned idx; ivl_parameter_t par = ivl_expr_parameter(net); const ivl_expr_type_t code = ivl_expr_type(net); unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sized = ivl_expr_sized(net)? "sized" : "unsized"; const char*vt = vt_type_string(net); switch (code) { case IVL_EX_ARRAY: show_array_expression(net, ind); break; case IVL_EX_ARRAY_PATTERN: show_array_pattern_expression(net, ind); break; case IVL_EX_BACCESS: show_branch_access_expression(net, ind); break; case IVL_EX_BINARY: show_binary_expression(net, ind); break; case IVL_EX_CONCAT: fprintf(out, "%*s\n", ind, "", ivl_expr_repeat(net), width, sign, vt); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net, idx), ind+3); break; case IVL_EX_ENUMTYPE: show_enumtype_expression(net, ind); break; case IVL_EX_MEMORY: show_memory_expression(net, ind); break; case IVL_EX_NEW: show_new_expression(net, ind); break; case IVL_EX_NULL: show_null_expression(net, ind); break; case IVL_EX_PROPERTY: show_property_expression(net, ind); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); fprintf(out, "%*s 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); fprintf(out, ", %s %s %s", sign, sized, vt); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); break; } case IVL_EX_SELECT: show_select_expression(net, ind); break; case IVL_EX_STRING: fprintf(out, "%*s\n", vt); break; case IVL_EX_SFUNC: fprintf(out, "%*s\n", ind, "", ivl_expr_name(net), width, sign, vt, ivl_expr_file(net), ivl_expr_lineno(net)); { unsigned cnt = ivl_expr_parms(net); unsigned jdx; for (jdx = 0 ; jdx < cnt ; jdx += 1) show_expression(ivl_expr_parm(net, jdx), ind+3); } break; case IVL_EX_SIGNAL: show_signal_expression(net, ind); break; case IVL_EX_TERNARY: show_ternary_expression(net, ind); break; case IVL_EX_UNARY: show_unary_expression(net, ind); break; case IVL_EX_UFUNC: show_function_call(net, ind); break; case IVL_EX_REALNUM: { int jdx; union foo { double rv; unsigned char bv[sizeof(double)]; } tmp; tmp.rv = ivl_expr_dvalue(net); fprintf(out, "%*s 0 ; jdx -= 1) fprintf(out, "%02x", tmp.bv[jdx-1]); fprintf(out, ")"); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); } break; case IVL_EX_SHALLOWCOPY: show_shallowcopy(net, ind); break; default: fprintf(out, "%*s\n", ind, "", code); break; } } iverilog-12_0/tgt-stub/priv.h000066400000000000000000000045471435245347300162630ustar00rootroot00000000000000#ifndef IVL_priv_H #define IVL_priv_H /* * Copyright (c) 2004-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 # include /* * This is the output file where the generated result should be * written. */ extern FILE*out; /* * Keep a running count of errors that the stub detects. This will be * the error count returned to the ivl_target environment. */ extern int stub_errors; /* * This function finds the vector width of a signal. It relies on the * assumption that all the signal inputs to the nexus have the same * width. The ivl_target API should assert that condition. */ extern unsigned width_of_nexus(ivl_nexus_t nex); extern ivl_variable_type_t type_of_nexus(ivl_nexus_t nex); extern ivl_discipline_t discipline_of_nexus(ivl_nexus_t nex); extern unsigned width_of_type(ivl_type_t net); /* * Test that a given expression is a valid delay expression, and * print an error message if not. */ extern void test_expr_is_delay(ivl_expr_t expr); extern void show_class(ivl_type_t net); extern void show_enumerate(ivl_enumtype_t net); extern void show_constant(ivl_net_const_t net); /* * Show the details of the expression. */ extern void show_expression(ivl_expr_t net, unsigned ind); /* * Show the statement. */ extern void show_statement(ivl_statement_t net, unsigned ind); /* * Show the type of the signal, in one line. */ extern void show_type_of_signal(ivl_signal_t); extern void show_switch(ivl_switch_t net); /* */ extern const char*data_type_string(ivl_variable_type_t vtype); extern void show_net_type(ivl_type_t net_type); #endif /* IVL_priv_H */ iverilog-12_0/tgt-stub/statement.c000066400000000000000000000405411435245347300172740ustar00rootroot00000000000000/* * Copyright (c) 2004-2021 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 "priv.h" # include /* * If the l-value signal is a darray object, then the ivl_lval_idx() * gets you the array index expression. */ static unsigned show_assign_lval_darray(ivl_lval_t lval, unsigned ind) { ivl_signal_t sig = ivl_lval_sig(lval); assert(sig); fprintf(out, "%*s{name=%s darray width=%u l-value width=%u}\n", ind, "", ivl_signal_name(sig), ivl_signal_width(sig), ivl_lval_width(lval)); if (ivl_lval_idx(lval)) { fprintf(out, "%*sAddress-0 select of ", ind+4, ""); show_type_of_signal(sig); fprintf(out, ":\n"); show_expression(ivl_lval_idx(lval), ind+6); } if (ivl_lval_part_off(lval)) { fprintf(out, "%*sERROR: unexpected Part select expression:\n", ind+4, ""); stub_errors += 1; show_expression(ivl_lval_part_off(lval), ind+8); } return ivl_lval_width(lval); } static unsigned show_assign_lval_class(ivl_lval_t lval, unsigned ind) { ivl_signal_t sig = ivl_lval_sig(lval); int sig_prop = ivl_lval_property_idx(lval); assert(sig); /* If there is no property select, then this l-value is for the class handle itself. */ if (sig_prop < 0) { fprintf(out, "%*s{name=%s class object}\n", ind, "", ivl_signal_name(sig)); if (ivl_lval_width(lval) != 1) { fprintf(out, "%*sERROR: ivl_lval_width should be 1 for class objects\n", ind+4, ""); stub_errors += 1; } return ivl_lval_width(lval); } fprintf(out, "%*s{name=%s. l-value width=%u}\n", ind, "", ivl_signal_name(sig), sig_prop, ivl_lval_width(lval)); if (ivl_lval_idx(lval)) { ivl_expr_t mux = ivl_lval_idx(lval); fprintf(out, "%*sAddress-0 select expression:\n", ind+4, ""); show_expression(mux, ind+6); } return ivl_lval_width(lval); } unsigned width_of_type(ivl_type_t net) { switch (ivl_type_packed_dimensions(net)) { case 0: return 1; case 1: { int msb = ivl_type_packed_msb(net,0); int lsb = ivl_type_packed_lsb(net,0); if (msb > lsb) return msb-lsb+1; else return lsb-msb+1; } default: return 0; } } static ivl_type_t show_assign_lval_nest(ivl_lval_t lval, unsigned ind) { ivl_type_t sub_type; if (ivl_lval_nest(lval)) { fprintf(out, "%*s{nested lval property=%d}\n", ind, "", ivl_lval_property_idx(lval)); sub_type = show_assign_lval_nest(ivl_lval_nest(lval), ind+4); } else { assert(ivl_lval_sig(lval)); ivl_signal_t sig = ivl_lval_sig(lval); fprintf(out, "%*s{name=%s property=%d, signal width=%u l-value width=%u}\n", ind, "", ivl_signal_name(sig), ivl_lval_property_idx(lval), ivl_signal_width(sig), ivl_lval_width(lval)); sub_type = ivl_signal_net_type(sig); } assert(ivl_type_base(sub_type) == IVL_VT_CLASS); ivl_type_t lval_type = ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval)); return lval_type; } static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind) { ivl_lval_t lval_nest = ivl_lval_nest(lval); if (lval_nest) { ivl_type_t net_type = show_assign_lval_nest(lval, ind); return width_of_type(net_type); } ivl_signal_t sig = ivl_lval_sig(lval); assert(sig); /* Special case: target signal is a darray. */ if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) return show_assign_lval_darray(lval, ind); /* Special case: target signal is a class. */ if (ivl_signal_data_type(sig) == IVL_VT_CLASS) return show_assign_lval_class(lval, ind); fprintf(out, "%*s{name=%s signal width=%u l-value width=%u}\n", ind, "", ivl_signal_name(sig), ivl_signal_width(sig), ivl_lval_width(lval)); if (ivl_lval_idx(lval)) { fprintf(out, "%*sAddress-0 select expression:\n", ind+4, ""); show_expression(ivl_lval_idx(lval), ind+6); if (ivl_signal_dimensions(sig) < 1) { fprintf(out, "%*sERROR: Address on signal with " "array dimensions=%u\n", ind+4, "", ivl_signal_dimensions(sig)); stub_errors += 1; } } else if (ivl_signal_array_count(sig) > 1) { fprintf(out, "%*sERROR: Address missing on signal with " "word count=%u\n", ind+4, "", ivl_signal_array_count(sig)); stub_errors += 1; } if (ivl_lval_part_off(lval)) { fprintf(out, "%*sPart select base:\n", ind+4, ""); show_expression(ivl_lval_part_off(lval), ind+8); } return ivl_lval_width(lval); } static void show_stmt_cassign(ivl_statement_t net, unsigned ind) { unsigned idx; unsigned lwid = 0; fprintf(out, "%*sCONTINUOUS ASSIGN \n", ind, "", ivl_stmt_lwidth(net)); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) { lwid += show_assign_lval(ivl_stmt_lval(net, idx), ind+4); } fprintf(out, "%*sTotal expected l-value width: %u bits\n", ind+4, "", lwid); show_expression(ivl_stmt_rval(net), ind+4); } static void show_stmt_delayx(ivl_statement_t net, unsigned ind) { fprintf(out, "%*s#(X) /* calculated delay */\n", ind, ""); show_expression(ivl_stmt_delay_expr(net), ind+4); show_statement(ivl_stmt_sub_stmt(net), ind+2); } static void show_stmt_disable(ivl_statement_t net, unsigned ind) { ivl_scope_t scope = ivl_stmt_call(net); if (scope) { fprintf(out, "%*sdisable %s\n", ind, "", ivl_scope_basename(scope)); } else { fprintf(out, "%*sdisable fork\n", ind, ""); } } static void show_stmt_force(ivl_statement_t net, unsigned ind) { unsigned idx; unsigned lwid = 0; fprintf(out, "%*sforce \n", ind, "", ivl_stmt_lwidth(net)); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) { lwid += show_assign_lval(ivl_stmt_lval(net, idx), ind+4); } fprintf(out, "%*sTotal expected l-value width: %u bits\n", ind+4, "", lwid); show_expression(ivl_stmt_rval(net), ind+4); } static void show_stmt_release(ivl_statement_t net, unsigned ind) { unsigned idx; unsigned lwid = 0; fprintf(out, "%*srelease \n", ind, "", ivl_stmt_lwidth(net)); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) { lwid += show_assign_lval(ivl_stmt_lval(net, idx), ind+4); } fprintf(out, "%*sTotal l-value width: %u bits\n", ind+4, "", lwid); } /* * A trigger statement is the "-> name;" syntax in Verilog, where a * trigger signal is sent to a named event. The trigger statement is * actually a very simple object. */ static void show_stmt_trigger(ivl_statement_t net, unsigned ind) { unsigned cnt = ivl_stmt_nevent(net); unsigned idx; fprintf(out, "%*s->", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_event_t event = ivl_stmt_events(net, idx); fprintf(out, " %s", ivl_event_basename(event)); } /* The compiler should make exactly one target event, so if we find more or less, then print some error text. */ if (cnt != 1) { fprintf(out, " /* ERROR: Expect one target event, got %u */", cnt); } fprintf(out, ";\n"); } /* * A non-blocking trigger statement is the "->> name;" syntax in Verilog, * where a non-blocking trigger signal is sent to a named event. The trigger * statement is actually a very simple object. */ static void show_stmt_nb_trigger(ivl_statement_t net, unsigned ind) { unsigned cnt = ivl_stmt_nevent(net); unsigned idx; fprintf(out, "%*s->>", ind, ""); ivl_expr_t delay = ivl_stmt_delay_expr(net); if (delay) { fprintf(out, " #("); show_expression(ivl_stmt_delay_expr(net), ind+4); fprintf(out, ")"); } for (idx = 0 ; idx < cnt ; idx += 1) { ivl_event_t event = ivl_stmt_events(net, idx); fprintf(out, " %s", ivl_event_basename(event)); } /* The compiler should make exactly one target event, so if we find more or less, then print some error text. */ if (cnt != 1) { fprintf(out, " /* ERROR: Expect one target event, got %u */", cnt); } fprintf(out, ";\n"); } /* * The wait statement contains simply an array of events to wait on, * and a sub-statement to execute when an event triggers. */ static void show_stmt_wait(ivl_statement_t net, unsigned ind) { unsigned idx; const char*comma = ""; fprintf(out, "%*s", ind, ""); /* Emit a SystemVerilog wait fork. */ if ((ivl_stmt_nevent(net) == 1) && (ivl_stmt_events(net, 0) == 0)) { assert(ivl_statement_type(ivl_stmt_sub_stmt(net)) == IVL_ST_NOOP); fprintf(out, "wait fork;\n"); return; } fprintf(out, "@("); for (idx = 0 ; idx < ivl_stmt_nevent(net) ; idx += 1) { ivl_event_t evnt = ivl_stmt_events(net, idx); if (evnt == 0) fprintf(out, "%s/*ERROR*/", comma); else fprintf(out, "%s%s.%s", comma, ivl_scope_name(ivl_event_scope(evnt)), ivl_event_basename(evnt)); comma = ", "; } fprintf(out, ")\n"); show_statement(ivl_stmt_sub_stmt(net), ind+4); } void show_statement(ivl_statement_t net, unsigned ind) { unsigned idx; char opcode = 0; unsigned lwid = 0; const ivl_statement_type_t code = ivl_statement_type(net); switch (code) { case IVL_ST_ALLOC: fprintf(out, "%*sallocate automatic storage ...\n", ind, ""); break; case IVL_ST_ASSIGN: opcode = ivl_stmt_opcode(net); if (opcode == 0) opcode = ' '; fprintf(out, "%*sASSIGN opcode=%c\n", ind, "", ivl_stmt_lwidth(net), opcode); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) lwid += show_assign_lval(ivl_stmt_lval(net, idx), ind+4); if (ivl_stmt_delay_expr(net)) show_expression(ivl_stmt_delay_expr(net), idx+4); if (ivl_stmt_rval(net)) show_expression(ivl_stmt_rval(net), ind+4); fprintf(out, "%*sTotal l-value width is %u\n", ind+2, "", lwid); break; case IVL_ST_ASSIGN_NB: fprintf(out, "%*sASSIGN_NB \n", ind, "", ivl_stmt_lwidth(net)); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) show_assign_lval(ivl_stmt_lval(net, idx), ind+4); if (ivl_stmt_delay_expr(net)) { fprintf(out, "%*s\n", ind+4, ""); show_expression(ivl_stmt_delay_expr(net), ind+6); } if (ivl_stmt_rval(net)) show_expression(ivl_stmt_rval(net), ind+4); break; case IVL_ST_BLOCK: { unsigned cnt = ivl_stmt_block_count(net); ivl_scope_t sscope = ivl_stmt_block_scope(net); if (sscope) fprintf(out, "%*sbegin : %s\n", ind, "", ivl_scope_name(sscope)); else fprintf(out, "%*sbegin\n", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); show_statement(cur, ind+4); } fprintf(out, "%*send\n", ind, ""); break; } case IVL_ST_CASEX: case IVL_ST_CASEZ: case IVL_ST_CASER: case IVL_ST_CASE: { ivl_case_quality_t qual = ivl_stmt_case_quality(net); unsigned cnt = ivl_stmt_case_count(net); const char*qual_txt = ""; switch (qual) { case IVL_CASE_QUALITY_BASIC: qual_txt = "basic"; break; case IVL_CASE_QUALITY_UNIQUE: qual_txt = "unique"; break; case IVL_CASE_QUALITY_UNIQUE0: qual_txt = "unique0"; break; case IVL_CASE_QUALITY_PRIORITY: qual_txt = "priority"; break; } fprintf(out, "%*scase (...) <%u cases, %s>\n", ind, "", cnt, qual_txt); show_expression(ivl_stmt_cond_expr(net), ind+4); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_expr_t ex = ivl_stmt_case_expr(net, idx); ivl_statement_t st = ivl_stmt_case_stmt(net, idx); if (ex == 0) fprintf(out, "%*sdefault\n", ind+4, ""); else show_expression(ex, ind+4); show_statement(st, ind+4); } fprintf(out, "%*sendcase\n", ind, ""); break; } case IVL_ST_CASSIGN: show_stmt_cassign(net, ind); break; case IVL_ST_CONDIT: { ivl_expr_t ex = ivl_stmt_cond_expr(net); ivl_statement_t t = ivl_stmt_cond_true(net); ivl_statement_t f = ivl_stmt_cond_false(net); fprintf(out, "%*sif (...)\n", ind, ""); if (ex) { show_expression(ex, ind+4); } else { fprintf(out, "%*sERROR: Condition expression is NIL;\n", ind+4, ""); stub_errors += 1; } if (t) show_statement(t, ind+4); else fprintf(out, "%*s;\n", ind+4, ""); if (f) { fprintf(out, "%*selse\n", ind, ""); show_statement(f, ind+4); } break; } case IVL_ST_CONTRIB: fprintf(out, "%*sCONTRIBUTION ( <+ )\n", ind, ""); show_expression(ivl_stmt_lexp(net), ind+4); show_expression(ivl_stmt_rval(net), ind+4); break; case IVL_ST_DEASSIGN: fprintf(out, "%*sDEASSIGN \n", ind, "", ivl_stmt_lwidth(net)); for (idx = 0 ; idx < ivl_stmt_lvals(net) ; idx += 1) show_assign_lval(ivl_stmt_lval(net, idx), ind+4); break; case IVL_ST_DELAY: fprintf(out, "%*s#%" PRIu64 "\n", ind, "", ivl_stmt_delay_val(net)); show_statement(ivl_stmt_sub_stmt(net), ind+2); break; case IVL_ST_DELAYX: show_stmt_delayx(net, ind); break; case IVL_ST_DISABLE: show_stmt_disable(net, ind); break; case IVL_ST_DO_WHILE: fprintf(out, "%*sdo\n", ind, ""); show_statement(ivl_stmt_sub_stmt(net), ind+2); fprintf(out, "%*swhile\n", ind, ""); show_expression(ivl_stmt_cond_expr(net), ind+4); break; case IVL_ST_FORCE: show_stmt_force(net, ind); break; case IVL_ST_FORK: { unsigned cnt = ivl_stmt_block_count(net); fprintf(out, "%*sfork\n", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); show_statement(cur, ind+4); } fprintf(out, "%*sjoin\n", ind, ""); break; } case IVL_ST_FORK_JOIN_ANY: { unsigned cnt = ivl_stmt_block_count(net); fprintf(out, "%*sfork\n", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); show_statement(cur, ind+4); } fprintf(out, "%*sjoin_any\n", ind, ""); break; } case IVL_ST_FORK_JOIN_NONE: { unsigned cnt = ivl_stmt_block_count(net); fprintf(out, "%*sfork\n", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); show_statement(cur, ind+4); } fprintf(out, "%*sjoin_none\n", ind, ""); break; } case IVL_ST_FREE: fprintf(out, "%*sfree automatic storage ...\n", ind, ""); break; case IVL_ST_NOOP: fprintf(out, "%*s/* noop */;\n", ind, ""); break; case IVL_ST_RELEASE: show_stmt_release(net, ind); break; case IVL_ST_STASK: { fprintf(out, "%*sCall %s(%u parameters); /* %s:%u */\n", ind, "", ivl_stmt_name(net), ivl_stmt_parm_count(net), ivl_stmt_file(net), ivl_stmt_lineno(net)); for (idx = 0 ; idx < ivl_stmt_parm_count(net) ; idx += 1) if (ivl_stmt_parm(net, idx)) show_expression(ivl_stmt_parm(net, idx), ind+4); break; } case IVL_ST_TRIGGER: show_stmt_trigger(net, ind); break; case IVL_ST_NB_TRIGGER: show_stmt_nb_trigger(net, ind); break; case IVL_ST_UTASK: fprintf(out, "%*scall task ...\n", ind, ""); break; case IVL_ST_WAIT: show_stmt_wait(net, ind); break; case IVL_ST_WHILE: fprintf(out, "%*swhile\n", ind, ""); show_expression(ivl_stmt_cond_expr(net), ind+4); show_statement(ivl_stmt_sub_stmt(net), ind+2); break; default: fprintf(out, "%*sunknown statement type (%d)\n", ind, "", code); } } iverilog-12_0/tgt-stub/stub-s.conf000066400000000000000000000001401435245347300171770ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=stub.tgt iverilog-12_0/tgt-stub/stub.c000066400000000000000000001453741435245347300162570ustar00rootroot00000000000000/* * Copyright (c) 2000-2021 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. */ /* * This is a sample target module. All this does is write to the * output file some information about each object handle when each of * the various object functions is called. This can be used to * understand the behavior of the core as it uses a target module. */ # include "version_base.h" # include "version_tag.h" # include "config.h" # include "priv.h" # include # include # include # include # include "ivl_alloc.h" static const char*version_string = "Icarus Verilog STUB Code Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (c) 2000-2020 Stephen Williams (steve@icarus.com)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; FILE*out; int stub_errors = 0; static struct udp_define_cell { ivl_udp_t udp; unsigned ref; struct udp_define_cell*next; }*udp_define_list = 0; static void reference_udp_definition(ivl_udp_t udp) { struct udp_define_cell*cur; if (udp_define_list == 0) { udp_define_list = calloc(1, sizeof(struct udp_define_cell)); udp_define_list->udp = udp; udp_define_list->ref = 1; return; } cur = udp_define_list; while (cur->udp != udp) { if (cur->next == 0) { cur->next = calloc(1, sizeof(struct udp_define_cell)); cur->next->udp = udp; cur->next->ref = 1; return; } cur = cur->next; } cur->ref += 1; } /* * This function finds the vector width of a signal. It relies on the * assumption that all the signal inputs to the nexus have the same * width. The ivl_target API should assert that condition. */ unsigned width_of_nexus(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig != 0) { return ivl_signal_width(sig); } } /* ERROR: A nexus should have at least one signal to carry properties like width. */ return 0; } ivl_discipline_t discipline_of_nexus(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex); idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig != 0) { return ivl_signal_discipline(sig); } } /* ERROR: A nexus should have at least one signal to carry properties like the data type. */ return 0; } ivl_variable_type_t type_of_nexus(ivl_nexus_t net) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(net); idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(net, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig != 0) { return ivl_signal_data_type(sig); } } /* ERROR: A nexus should have at least one signal to carry properties like the data type. */ return IVL_VT_NO_TYPE; } const char*data_type_string(ivl_variable_type_t vtype) { const char*vt = "??"; switch (vtype) { case IVL_VT_NO_TYPE: vt = "NO_TYPE"; break; case IVL_VT_VOID: vt = "void"; break; case IVL_VT_BOOL: vt = "bool"; break; case IVL_VT_REAL: vt = "real"; break; case IVL_VT_LOGIC: vt = "logic"; break; case IVL_VT_STRING: vt = "string"; break; case IVL_VT_DARRAY: vt = "darray"; break; case IVL_VT_CLASS: vt = "class"; break; case IVL_VT_QUEUE: vt = "queue"; break; } return vt; } /* * The compiler will check the types of drivers to signals and will * only connect outputs to signals that are compatible. This function * shows the type compatibility that the compiler enforces at the * ivl_target.h level. */ static int check_signal_drive_type(ivl_variable_type_t sig_type, ivl_variable_type_t driver_type) { if (sig_type == IVL_VT_LOGIC && driver_type == IVL_VT_BOOL) return !0; if (sig_type == IVL_VT_LOGIC && driver_type == IVL_VT_LOGIC) return !0; if (sig_type == IVL_VT_BOOL && driver_type == IVL_VT_BOOL) return !0; if (sig_type == driver_type) return !0; return 0; } /* * The compare-like LPM nodes have input widths that match the * ivl_lpm_width() value, and an output width of 1. This function * checks that that is so, and indicates errors otherwise. */ static void check_cmp_widths(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); /* Check that the input widths are as expected. The inputs must be the width of the ivl_lpm_width() for this device, even though the output for this device is 1 bit. */ if (width != width_of_nexus(ivl_lpm_data(net,0))) { fprintf(out, " ERROR: Width of A is %u, not %u\n", width_of_nexus(ivl_lpm_data(net,0)), width); stub_errors += 1; } if (width != width_of_nexus(ivl_lpm_data(net,1))) { fprintf(out, " ERROR: Width of B is %u, not %u\n", width_of_nexus(ivl_lpm_data(net,1)), width); stub_errors += 1; } if (width_of_nexus(ivl_lpm_q(net)) != 1) { fprintf(out, " ERROR: Width of Q is %u, not 1\n", width_of_nexus(ivl_lpm_q(net))); stub_errors += 1; } } static void show_lpm_arithmetic_pins(ivl_lpm_t net) { ivl_nexus_t nex; nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); nex = ivl_lpm_data(net, 0); fprintf(out, " DataA: %p\n", nex); nex = ivl_lpm_data(net, 1); fprintf(out, " DataB: %p\n", nex); } static void show_lpm_abs(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t nex; fprintf(out, " LPM_ABS %s: \n", ivl_lpm_basename(net), width); nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); nex = ivl_lpm_data(net, 0); fprintf(out, " D: %p\n", nex); if (nex == 0) { fprintf(out, " ERROR: missing input\n"); stub_errors += 1; return; } if (width_of_nexus(nex) != width) { fprintf(out, " ERROR: D width (%u) is wrong\n", width_of_nexus(nex)); stub_errors += 1; } } static void show_lpm_add(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_ADD %s: \n", ivl_lpm_basename(net), width); show_lpm_arithmetic_pins(net); } static void show_lpm_array(ivl_lpm_t net) { ivl_nexus_t nex; unsigned width = ivl_lpm_width(net); ivl_signal_t array = ivl_lpm_array(net); fprintf(out, " LPM_ARRAY: \n", width, ivl_signal_basename(array)); nex = ivl_lpm_q(net); assert(nex); fprintf(out, " Q: %p\n", nex); nex = ivl_lpm_select(net); assert(nex); fprintf(out, " Address: %p (address width=%u)\n", nex, ivl_lpm_selects(net)); if (width_of_nexus(ivl_lpm_q(net)) != width) { fprintf(out, " ERROR: Data Q width doesn't match " "nexus width=%u\n", width_of_nexus(ivl_lpm_q(net))); stub_errors += 1; } if (ivl_signal_width(array) != width) { fprintf(out, " ERROR: Data width doesn't match " "word width=%u\n", ivl_signal_width(array)); stub_errors += 1; } } static void show_lpm_cast_int(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t q, a; fprintf(out, " LPM_CAST_INT %s: \n", ivl_lpm_basename(net), width); q = ivl_lpm_q(net); a = ivl_lpm_data(net,0); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); if (type_of_nexus(q) == IVL_VT_REAL) { fprintf(out, " ERROR: Data type of Q is %s, expecting !real\n", data_type_string(type_of_nexus(q))); stub_errors += 1; } if (type_of_nexus(a) != IVL_VT_REAL) { fprintf(out, " ERROR: Data type of A is %s, expecting real\n", data_type_string(type_of_nexus(a))); stub_errors += 1; } } static void show_lpm_cast_real(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t q, a; fprintf(out, " LPM_CAST_REAL %s: \n", ivl_lpm_basename(net), width); q = ivl_lpm_q(net); a = ivl_lpm_data(net,0); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); if (type_of_nexus(q) != IVL_VT_REAL) { fprintf(out, " ERROR: Data type of Q is %s, expecting real\n", data_type_string(type_of_nexus(q))); stub_errors += 1; } if (type_of_nexus(a) == IVL_VT_REAL) { fprintf(out, " ERROR: Data type of A is %s, expecting !real\n", data_type_string(type_of_nexus(a))); stub_errors += 1; } } static void show_lpm_divide(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_DIVIDE %s: \n", ivl_lpm_basename(net), width); show_lpm_arithmetic_pins(net); } /* IVL_LPM_CMP_EEQ/EQX/EQZ/NEE * This LPM node supports two-input compare. The output width is * actually always 1, the lpm_width is the expected width of the inputs. */ static void show_lpm_cmp_eeq(ivl_lpm_t net) { const char*str = 0; switch (ivl_lpm_type(net)) { case IVL_LPM_CMP_EEQ: str = "EEQ"; break; case IVL_LPM_CMP_EQX: str = "EQX"; break; case IVL_LPM_CMP_EQZ: str = "EQZ"; break; case IVL_LPM_CMP_NEE: str = "NEE"; break; case IVL_LPM_CMP_WEQ: str = "WEQ"; break; case IVL_LPM_CMP_WNE: str = "WNE"; break; default: assert(0); break; } unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_CMP_%s %s: \n", str, ivl_lpm_basename(net), width); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); fprintf(out, " B: %p\n", ivl_lpm_data(net,1)); check_cmp_widths(net); } /* IVL_LPM_CMP_GE * This LPM node supports two-input compare. */ static void show_lpm_cmp_ge(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_CMP_GE %s: \n", ivl_lpm_basename(net), width, ivl_lpm_signed(net)? "signed" : "unsigned"); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); fprintf(out, " B: %p\n", ivl_lpm_data(net,1)); check_cmp_widths(net); } /* IVL_LPM_CMP_GT * This LPM node supports two-input compare. */ static void show_lpm_cmp_gt(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_CMP_GT %s: \n", ivl_lpm_basename(net), width, ivl_lpm_signed(net)? "signed" : "unsigned"); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); fprintf(out, " B: %p\n", ivl_lpm_data(net,1)); check_cmp_widths(net); } /* IVL_LPM_CMP_NE * This LPM node supports two-input compare. The output width is * actually always 1, the lpm_width is the expected width of the inputs. */ static void show_lpm_cmp_ne(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_CMP_NE %s: \n", ivl_lpm_basename(net), width); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p\n", ivl_lpm_data(net,0)); fprintf(out, " B: %p\n", ivl_lpm_data(net,1)); check_cmp_widths(net); } /* IVL_LPM_CONCAT, IVL_LPM_CONCATZ * The concat device takes N inputs (N=ivl_lpm_size) and generates * a single output. The total output is known from the ivl_lpm_width * function. The widths of all the inputs are inferred from the widths * of the signals connected to the nexus of the inputs. The compiler * makes sure the input widths add up to the output width. */ static void show_lpm_concat(ivl_lpm_t net) { unsigned idx; unsigned width_sum = 0; unsigned width = ivl_lpm_width(net); const char*z = ivl_lpm_type(net)==IVL_LPM_CONCATZ? "Z" : ""; fprintf(out, " LPM_CONCAT%s %s: \n", z, ivl_lpm_basename(net), width, ivl_lpm_size(net)); fprintf(out, " O: %p\n", ivl_lpm_q(net)); for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 1) { ivl_nexus_t nex = ivl_lpm_data(net, idx); unsigned signal_width = width_of_nexus(nex); fprintf(out, " I%u: %p (width=%u)\n", idx, nex, signal_width); width_sum += signal_width; } if (width_sum != width) { fprintf(out, " ERROR! Got %u bits input, expecting %u!\n", width_sum, width); } } static void show_lpm_ff(ivl_lpm_t net) { ivl_nexus_t nex; char*edge = ivl_lpm_negedge(net) ? "negedge" : "posedge"; unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_FF %s: \n", ivl_lpm_basename(net), edge, width); nex = ivl_lpm_clk(net); fprintf(out, " clk: %p\n", nex); if (width_of_nexus(nex) != 1) { fprintf(out, " clk: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } if (ivl_lpm_enable(net)) { nex = ivl_lpm_enable(net); fprintf(out, " CE: %p\n", nex); if (width_of_nexus(nex) != 1) { fprintf(out, " CE: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } } if (ivl_lpm_async_clr(net)) { nex = ivl_lpm_async_clr(net); fprintf(out, " Aclr: %p\n", nex); if (width_of_nexus(nex) != 1) { fprintf(out, " Aclr: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } } if (ivl_lpm_async_set(net)) { nex = ivl_lpm_async_set(net); fprintf(out, " Aset: %p\n", nex); if (width_of_nexus(nex) != 1) { fprintf(out, " Aset: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } } nex = ivl_lpm_data(net,0); fprintf(out, " D: %p\n", nex); if (width_of_nexus(nex) != width) { fprintf(out, " D: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); if (width_of_nexus(nex) != width) { fprintf(out, " Q: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } } static void show_lpm_latch(ivl_lpm_t net) { ivl_nexus_t nex; unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_LATCH %s: \n", ivl_lpm_basename(net), width); nex = ivl_lpm_enable(net); fprintf(out, " E: %p\n", nex); if (width_of_nexus(nex) != 1) { fprintf(out, " E: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_data(net,0); fprintf(out, " D: %p\n", nex); if (width_of_nexus(nex) != width) { fprintf(out, " D: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); if (width_of_nexus(nex) != width) { fprintf(out, " Q: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } } static void show_lpm_mod(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_MOD %s: \n", ivl_lpm_basename(net), width); show_lpm_arithmetic_pins(net); } /* * The LPM_MULT node has a Q output and two data inputs. The width of * the Q output must be the width of the node itself. */ static void show_lpm_mult(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_MULT %s: \n", ivl_lpm_basename(net), width); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " A: %p \n", ivl_lpm_data(net,0), width_of_nexus(ivl_lpm_data(net,0))); fprintf(out, " B: %p \n", ivl_lpm_data(net,1), width_of_nexus(ivl_lpm_data(net,1))); if (width != width_of_nexus(ivl_lpm_q(net))) { fprintf(out, " ERROR: Width of Q is %u, not %u\n", width_of_nexus(ivl_lpm_q(net)), width); stub_errors += 1; } } /* * Show an IVL_LPM_MUX. * * The compiler is supposed to make sure that the Q output and data * inputs all have the width of the device. The ivl_lpm_select input * has its own width. */ static void show_lpm_mux(ivl_lpm_t net) { ivl_nexus_t nex; unsigned idx; unsigned width = ivl_lpm_width(net); unsigned size = ivl_lpm_size(net); ivl_drive_t drive0 = ivl_lpm_drive0(net); ivl_drive_t drive1 = ivl_lpm_drive1(net); fprintf(out, " LPM_MUX %s: \n", ivl_lpm_basename(net), width, size); nex = ivl_lpm_q(net); fprintf(out, " Q: %p \n", nex, drive0, drive1); if (width != width_of_nexus(nex)) { fprintf(out, " Q: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } /* The select input is a vector with the width from the ivl_lpm_selects function. */ nex = ivl_lpm_select(net); fprintf(out, " S: %p \n", nex, ivl_lpm_selects(net)); if (ivl_lpm_selects(net) != width_of_nexus(nex)) { fprintf(out, " S: ERROR: Nexus width is %u\n", width_of_nexus(nex)); stub_errors += 1; } /* The ivl_lpm_size() method give the number of inputs that can be selected from. */ for (idx = 0 ; idx < size ; idx += 1) { nex = ivl_lpm_data(net,idx); fprintf(out, " D%u: %p\n", idx, nex); if (width != width_of_nexus(nex)) { fprintf(out, " D%u: ERROR, Nexus width is %u\n", idx, width_of_nexus(nex)); stub_errors += 1; } } } static void show_lpm_part(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned base = ivl_lpm_base(net); ivl_nexus_t sel = ivl_lpm_data(net,1); const char*part_type_string = ""; switch (ivl_lpm_type(net)) { case IVL_LPM_PART_VP: part_type_string = "VP"; break; case IVL_LPM_PART_PV: part_type_string = "PV"; break; default: break; } fprintf(out, " LPM_PART_%s %s: \n", part_type_string, ivl_lpm_basename(net), width, base, ivl_lpm_signed(net)); fprintf(out, " O: %p\n", ivl_lpm_q(net)); fprintf(out, " I: %p\n", ivl_lpm_data(net,0)); if (sel != 0) { fprintf(out, " S: %p\n", sel); if (base != 0) { fprintf(out, " ERROR: Part select has base AND selector\n"); stub_errors += 1; } } /* The compiler must assure that the base plus the part select width fits within the input to the part select. */ switch (ivl_lpm_type(net)) { case IVL_LPM_PART_VP: if (width_of_nexus(ivl_lpm_data(net,0)) < (width+base)) { fprintf(out, " ERROR: Part select is out of range." " Data nexus width=%u, width+base=%u\n", width_of_nexus(ivl_lpm_data(net,0)), width+base); stub_errors += 1; } if (width_of_nexus(ivl_lpm_q(net)) != width) { fprintf(out, " ERROR: Part select input mismatch." " Nexus width=%u, expect width=%u\n", width_of_nexus(ivl_lpm_q(net)), width); stub_errors += 1; } break; case IVL_LPM_PART_PV: if (width_of_nexus(ivl_lpm_q(net)) < (width+base)) { fprintf(out, " ERROR: Part select is out of range." " Target nexus width=%u, width+base=%u\n", width_of_nexus(ivl_lpm_q(net)), width+base); stub_errors += 1; } if (width_of_nexus(ivl_lpm_data(net,0)) != width) { fprintf(out, " ERROR: Part select input mismatch." " Nexus width=%u, expect width=%u\n", width_of_nexus(ivl_lpm_data(net,0)), width); stub_errors += 1; } break; default: assert(0); } } /* * The reduction operators have similar characteristics and are * displayed here. */ static void show_lpm_re(ivl_lpm_t net) { ivl_nexus_t nex; const char*type = "?"; unsigned width = ivl_lpm_width(net); switch (ivl_lpm_type(net)) { case IVL_LPM_RE_AND: type = "AND"; break; case IVL_LPM_RE_NAND: type = "NAND"; break; case IVL_LPM_RE_OR: type = "OR"; break; case IVL_LPM_RE_NOR: type = "NOR"; break; case IVL_LPM_RE_XOR: type = "XOR"; break; case IVL_LPM_RE_XNOR: type = "XNOR"; default: break; } fprintf(out, " LPM_RE_%s: %s \n", type, ivl_lpm_name(net),width); nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); nex = ivl_lpm_data(net, 0); fprintf(out, " D: %p\n", nex); nex = ivl_lpm_q(net); if (1 != width_of_nexus(nex)) { fprintf(out, " ERROR: Width of Q is %u, expecting 1\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_data(net, 0); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Width of input is %u, expecting %u\n", width_of_nexus(nex), width); stub_errors += 1; } } static void show_lpm_repeat(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned count = ivl_lpm_size(net); ivl_nexus_t nex_q = ivl_lpm_q(net); ivl_nexus_t nex_a = ivl_lpm_data(net,0); fprintf(out, " LPM_REPEAT %s: \n", ivl_lpm_basename(net), width, count); fprintf(out, " Q: %p\n", nex_q); fprintf(out, " D: %p\n", nex_a); if (width != width_of_nexus(nex_q)) { fprintf(out, " ERROR: Width of Q is %u, expecting %u\n", width_of_nexus(nex_q), width); stub_errors += 1; } if (count == 0 || count > width || (width%count != 0)) { fprintf(out, " ERROR: Repeat count not reasonable\n"); stub_errors += 1; } else if (width/count != width_of_nexus(nex_a)) { fprintf(out, " ERROR: Width of D is %u, expecting %u\n", width_of_nexus(nex_a), width/count); stub_errors += 1; } } static void show_lpm_shift(ivl_lpm_t net, const char*shift_dir) { ivl_nexus_t nex; unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_SHIFT%s %s: \n", shift_dir, ivl_lpm_basename(net), width, ivl_lpm_signed(net)? "" : "un"); nex = ivl_lpm_q(net); fprintf(out, " Q: %p\n", nex); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Q output nexus width=%u " "does not match part width\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_data(net, 0); fprintf(out, " D: %p\n", nex); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Q output nexus width=%u " "does not match part width\n", width_of_nexus(nex)); stub_errors += 1; } nex = ivl_lpm_data(net, 1); fprintf(out, " S: %p \n", nex, width_of_nexus(nex)); } static void show_lpm_sign_ext(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t nex_q = ivl_lpm_q(net); ivl_nexus_t nex_a = ivl_lpm_data(net,0); fprintf(out, " LPM_SIGN_EXT %s: \n", ivl_lpm_basename(net), width); fprintf(out, " Q: %p\n", nex_q); fprintf(out, " D: %p \n", nex_a, width_of_nexus(nex_a)); if (width != width_of_nexus(nex_q)) { fprintf(out, " ERROR: Width of Q is %u, expecting %u\n", width_of_nexus(nex_q), width); stub_errors += 1; } } static void show_lpm_sub(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); fprintf(out, " LPM_SUB %s: \n", ivl_lpm_basename(net), width); show_lpm_arithmetic_pins(net); } static void show_lpm_substitute(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); ivl_nexus_t nex_q = ivl_lpm_q(net); ivl_nexus_t nex_a = ivl_lpm_data(net,0); ivl_nexus_t nex_s = ivl_lpm_data(net,1); unsigned sbase = ivl_lpm_base(net); unsigned swidth = width_of_nexus(nex_s); fprintf(out, " LPM_SUBSTITUTE %s: \n", ivl_lpm_basename(net), width, sbase, swidth); fprintf(out, " Q: %p\n", nex_q); if (width != width_of_nexus(nex_q)) { fprintf(out, " ERROR: Width of Q is %u, expecting %u\n", width_of_nexus(nex_q), width); stub_errors += 1; } fprintf(out, " A: %p\n", nex_a); if (width != width_of_nexus(nex_a)) { fprintf(out, " ERROR: Width of A is %u, expecting %u\n", width_of_nexus(nex_a), width); stub_errors += 1; } fprintf(out, " S: %p\n", nex_s); if (sbase + swidth > width) { fprintf(out, " ERROR: S part is out of bounds\n"); stub_errors += 1; } } static void show_lpm_sfunc(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned ports = ivl_lpm_size(net); ivl_variable_type_t data_type = type_of_nexus(ivl_lpm_q(net)); ivl_nexus_t nex; unsigned idx; fprintf(out, " LPM_SFUNC %s: \n", ivl_lpm_basename(net), ivl_lpm_string(net), width, data_type_string(data_type), ports); nex = ivl_lpm_q(net); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Q output nexus width=%u " " does not match part width\n", width_of_nexus(nex)); stub_errors += 1; } fprintf(out, " Q: %p\n", nex); for (idx = 0 ; idx < ports ; idx += 1) { nex = ivl_lpm_data(net, idx); fprintf(out, " D%u: %p \n", idx, nex, width_of_nexus(nex), data_type_string(type_of_nexus(nex))); } } static void show_lpm_delays(ivl_lpm_t net) { ivl_expr_t rise = ivl_lpm_delay(net, 0); ivl_expr_t fall = ivl_lpm_delay(net, 1); ivl_expr_t decay= ivl_lpm_delay(net, 2); if (rise==0 && fall==0 && decay==0) return; fprintf(out, " #DELAYS\n"); if (rise) show_expression(rise, 8); else fprintf(out, " ERROR: missing rise delay\n"); if (fall) show_expression(fall, 8); else fprintf(out, " ERROR: missing fall delay\n"); if (decay) show_expression(decay, 8); else fprintf(out, " ERROR: missing decay delay\n"); fprintf(out, " #END DELAYS\n"); } static void show_lpm_ufunc(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned ports = ivl_lpm_size(net); ivl_scope_t def = ivl_lpm_define(net); ivl_nexus_t nex; unsigned idx; fprintf(out, " LPM_UFUNC %s: \n", ivl_lpm_basename(net), ivl_scope_name(def), width, ports); show_lpm_delays(net); nex = ivl_lpm_q(net); if (width != width_of_nexus(nex)) { fprintf(out, " ERROR: Q output nexus width=%u " " does not match part width\n", width_of_nexus(nex)); stub_errors += 1; } fprintf(out, " Q: %p\n", nex); for (idx = 0 ; idx < ports ; idx += 1) { nex = ivl_lpm_data(net, idx); fprintf(out, " D%u: %p \n", idx, nex, width_of_nexus(nex)); } } static void show_lpm(ivl_lpm_t net) { switch (ivl_lpm_type(net)) { case IVL_LPM_ABS: show_lpm_abs(net); break; case IVL_LPM_ADD: show_lpm_add(net); break; case IVL_LPM_ARRAY: show_lpm_array(net); break; case IVL_LPM_CAST_INT: show_lpm_cast_int(net); break; case IVL_LPM_CAST_REAL: show_lpm_cast_real(net); break; case IVL_LPM_DIVIDE: show_lpm_divide(net); break; case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: show_lpm_cmp_eeq(net); break; case IVL_LPM_FF: show_lpm_ff(net); break; case IVL_LPM_LATCH: show_lpm_latch(net); break; case IVL_LPM_CMP_GE: show_lpm_cmp_ge(net); break; case IVL_LPM_CMP_GT: show_lpm_cmp_gt(net); break; case IVL_LPM_CMP_NE: show_lpm_cmp_ne(net); break; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: show_lpm_concat(net); break; case IVL_LPM_RE_AND: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_XNOR: show_lpm_re(net); break; case IVL_LPM_SHIFTL: show_lpm_shift(net, "L"); break; case IVL_LPM_SIGN_EXT: show_lpm_sign_ext(net); break; case IVL_LPM_SHIFTR: show_lpm_shift(net, "R"); break; case IVL_LPM_SUB: show_lpm_sub(net); break; case IVL_LPM_SUBSTITUTE: show_lpm_substitute(net); break; case IVL_LPM_MOD: show_lpm_mod(net); break; case IVL_LPM_MULT: show_lpm_mult(net); break; case IVL_LPM_MUX: show_lpm_mux(net); break; case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: show_lpm_part(net); break; case IVL_LPM_REPEAT: show_lpm_repeat(net); break; case IVL_LPM_SFUNC: show_lpm_sfunc(net); break; case IVL_LPM_UFUNC: show_lpm_ufunc(net); break; default: fprintf(out, " LPM(%d) %s: \n", ivl_lpm_type(net), ivl_lpm_basename(net), ivl_lpm_width(net), ivl_lpm_signed(net)); } } static int show_process(ivl_process_t net, void*x) { unsigned idx; (void)x; /* Parameter is not used. */ switch (ivl_process_type(net)) { case IVL_PR_INITIAL: if (ivl_process_analog(net)) fprintf(out, "analog initial\n"); else fprintf(out, "initial\n"); break; case IVL_PR_ALWAYS: if (ivl_process_analog(net)) fprintf(out, "analog\n"); else fprintf(out, "always\n"); break; case IVL_PR_ALWAYS_COMB: if (ivl_process_analog(net)) assert(0); else fprintf(out, "always_comb\n"); break; case IVL_PR_ALWAYS_FF: if (ivl_process_analog(net)) assert(0); else fprintf(out, "always_ff\n"); break; case IVL_PR_ALWAYS_LATCH: if (ivl_process_analog(net)) assert(0); else fprintf(out, "always_latch\n"); break; case IVL_PR_FINAL: if (ivl_process_analog(net)) fprintf(out, "analog final\n"); else fprintf(out, "final\n"); break; } for (idx = 0 ; idx < ivl_process_attr_cnt(net) ; idx += 1) { ivl_attribute_t attr = ivl_process_attr_val(net, idx); switch (attr->type) { case IVL_ATT_VOID: fprintf(out, " (* %s *)\n", attr->key); break; case IVL_ATT_STR: fprintf(out, " (* %s = \"%s\" *)\n", attr->key, attr->val.str); break; case IVL_ATT_NUM: fprintf(out, " (* %s = %ld *)\n", attr->key, attr->val.num); break; } } show_statement(ivl_process_stmt(net), 4); return 0; } static void show_parameter(ivl_parameter_t net) { const char*name = ivl_parameter_basename(net); fprintf(out, " parameter %s;\n", name); show_expression(ivl_parameter_expr(net), 7); } static void show_event(ivl_event_t net) { unsigned idx; fprintf(out, " event %s (%u pos, %u neg, %u any);\n", ivl_event_basename(net), ivl_event_npos(net), ivl_event_nneg(net), ivl_event_nany(net)); for (idx = 0 ; idx < ivl_event_nany(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_any(net, idx); fprintf(out, " ANYEDGE: %p\n", nex); } for (idx = 0 ; idx < ivl_event_nneg(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_neg(net, idx); fprintf(out, " NEGEDGE: %p\n", nex); } for (idx = 0 ; idx < ivl_event_npos(net) ; idx += 1) { ivl_nexus_t nex = ivl_event_pos(net, idx); fprintf(out, " POSEDGE: %p\n", nex); } } static const char* str_tab[8] = { "HiZ", "small", "medium", "weak", "large", "pull", "strong", "supply"}; /* * This function is used by the show_signal to dump a constant value * that is connected to the signal. While we are here, check that the * value is consistent with the signal itself. */ static void signal_nexus_const(ivl_signal_t sig, ivl_nexus_ptr_t ptr, ivl_net_const_t con) { const char*dr0 = str_tab[ivl_nexus_ptr_drive0(ptr)]; const char*dr1 = str_tab[ivl_nexus_ptr_drive1(ptr)]; const char*bits; unsigned idx, width = ivl_const_width(con); fprintf(out, " const-"); switch (ivl_const_type(con)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: bits = ivl_const_bits(con); assert(bits); for (idx = 0 ; idx < width ; idx += 1) { fprintf(out, "%c", bits[width-idx-1]); } break; case IVL_VT_REAL: fprintf(out, "%f", ivl_const_real(con)); break; default: fprintf(out, "????"); break; } fprintf(out, " (%s0, %s1, width=%u)\n", dr0, dr1, width); if (ivl_signal_width(sig) != width) { fprintf(out, "ERROR: Width of signal does not match " "width of connected constant vector.\n"); stub_errors += 1; } int drive_type_ok = check_signal_drive_type(ivl_signal_data_type(sig), ivl_const_type(con)); if (! drive_type_ok) { fprintf(out, "ERROR: Signal data type does not match" " literal type.\n"); stub_errors += 1; } } static void show_nexus_details(ivl_signal_t net, ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_net_const_t con; ivl_net_logic_t logic; ivl_lpm_t lpm; ivl_signal_t sig; ivl_switch_t swt; ivl_branch_t bra; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); const char*dr0 = str_tab[ivl_nexus_ptr_drive0(ptr)]; const char*dr1 = str_tab[ivl_nexus_ptr_drive1(ptr)]; if ((sig = ivl_nexus_ptr_sig(ptr))) { fprintf(out, " SIG %s word=%u (%s0, %s1)", ivl_signal_name(sig), ivl_nexus_ptr_pin(ptr), dr0, dr1); if (ivl_signal_width(sig) != ivl_signal_width(net)) { fprintf(out, " (ERROR: Width=%u)", ivl_signal_width(sig)); stub_errors += 1; } if (ivl_signal_data_type(sig) != ivl_signal_data_type(net)) { fprintf(out, " (ERROR: data type mismatch : %s vs. %s)", data_type_string(ivl_signal_data_type(sig)), data_type_string(ivl_signal_data_type(net))); stub_errors += 1; } fprintf(out, "\n"); } else if ((logic = ivl_nexus_ptr_log(ptr))) { fprintf(out, " LOG %s.%s[%u] (%s0, %s1)\n", ivl_scope_name(ivl_logic_scope(logic)), ivl_logic_basename(logic), ivl_nexus_ptr_pin(ptr), dr0, dr1); } else if ((lpm = ivl_nexus_ptr_lpm(ptr))) { fprintf(out, " LPM %s.%s (%s0, %s1)\n", ivl_scope_name(ivl_lpm_scope(lpm)), ivl_lpm_basename(lpm), dr0, dr1); } else if ((swt = ivl_nexus_ptr_switch(ptr))) { fprintf(out, " SWITCH %s.%s\n", ivl_scope_name(ivl_switch_scope(swt)), ivl_switch_basename(swt)); } else if ((con = ivl_nexus_ptr_con(ptr))) { signal_nexus_const(net, ptr, con); } else if ((bra = ivl_nexus_ptr_branch(ptr))) { fprintf(out, " BRANCH %p terminal %u\n", bra, ivl_nexus_ptr_pin(ptr)); } else { fprintf(out, " ?[%u] (%s0, %s1)\n", ivl_nexus_ptr_pin(ptr), dr0, dr1); } } } static void show_signal(ivl_signal_t net) { unsigned idx; const char*type = "?"; const char*port = ""; const char*sign = ivl_signal_signed(net)? "signed" : "unsigned"; switch (ivl_signal_type(net)) { case IVL_SIT_REG: type = "reg"; if (ivl_signal_integer(net)) type = "integer"; break; case IVL_SIT_TRI: type = "tri"; break; case IVL_SIT_TRI0: type = "tri0"; break; case IVL_SIT_TRI1: type = "tri1"; break; case IVL_SIT_UWIRE: type = "uwire"; break; default: break; } switch (ivl_signal_port(net)) { case IVL_SIP_INPUT: port = "input "; break; case IVL_SIP_OUTPUT: port = "output "; break; case IVL_SIP_INOUT: port = "inout "; break; case IVL_SIP_NONE: break; } const char*discipline_txt = "NONE"; if (ivl_signal_discipline(net)) { ivl_discipline_t dis = ivl_signal_discipline(net); discipline_txt = ivl_discipline_name(dis); } for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) { ivl_nexus_t nex = ivl_signal_nex(net, idx); fprintf(out, " %s %s %s", type, sign, port); show_type_of_signal(net); fprintf(out, " %s[word=%u, adr=%u] ", ivl_signal_basename(net), idx, ivl_signal_array_base(net)+idx, ivl_signal_width(net), ivl_signal_local(net)? ", local":"", discipline_txt); if (nex == NULL) { fprintf(out, "nexus=\n"); continue; } else { fprintf(out, "nexus=%p\n", nex); } show_nexus_details(net, nex); } for (idx = 0 ; idx < ivl_signal_npath(net) ; idx += 1) { ivl_delaypath_t path = ivl_signal_path(net,idx); ivl_nexus_t nex = ivl_path_source(path); ivl_nexus_t con = ivl_path_condit(path); int posedge = ivl_path_source_posedge(path); int negedge = ivl_path_source_negedge(path); fprintf(out, " path %p", nex); if (posedge) fprintf(out, " posedge"); if (negedge) fprintf(out, " negedge"); if (con) fprintf(out, " (if %p)", con); else if (ivl_path_is_condit(path)) fprintf(out, " (ifnone)"); fprintf(out, " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64 " %" PRIu64 ",%" PRIu64 ",%" PRIu64, ivl_path_delay(path, IVL_PE_01), ivl_path_delay(path, IVL_PE_10), ivl_path_delay(path, IVL_PE_0z), ivl_path_delay(path, IVL_PE_z1), ivl_path_delay(path, IVL_PE_1z), ivl_path_delay(path, IVL_PE_z0), ivl_path_delay(path, IVL_PE_0x), ivl_path_delay(path, IVL_PE_x1), ivl_path_delay(path, IVL_PE_1x), ivl_path_delay(path, IVL_PE_x0), ivl_path_delay(path, IVL_PE_xz), ivl_path_delay(path, IVL_PE_zx)); fprintf(out, " scope=%s\n", ivl_scope_name(ivl_path_scope(path))); } for (idx = 0 ; idx < ivl_signal_attr_cnt(net) ; idx += 1) { ivl_attribute_t atr = ivl_signal_attr_val(net, idx); switch (atr->type) { case IVL_ATT_STR: fprintf(out, " %s = %s\n", atr->key, atr->val.str); break; case IVL_ATT_NUM: fprintf(out, " %s = %ld\n", atr->key, atr->val.num); break; case IVL_ATT_VOID: fprintf(out, " %s\n", atr->key); break; } } switch (ivl_signal_data_type(net)) { case IVL_VT_NO_TYPE: case IVL_VT_VOID: fprintf(out, " ERROR: Invalid type for signal.\n"); stub_errors += 1; break; default: break; } if (ivl_signal_integer(net) && ivl_signal_type(net)!=IVL_SIT_REG) { fprintf(out, " ERROR: integers must be IVL_SIT_REG\n"); stub_errors += 1; } } void test_expr_is_delay(ivl_expr_t expr) { switch (ivl_expr_type(expr)) { case IVL_EX_ULONG: return; case IVL_EX_NUMBER: return; case IVL_EX_SIGNAL: return; default: break; } fprintf(out, " ERROR: Expression is not a suitable delay\n"); stub_errors += 1; } /* * All logic gates have inputs and outputs that match exactly in * width. For example, and AND gate with 4 bit inputs generates a 4 * bit output, and all the inputs are 4 bits. */ static void show_logic(ivl_net_logic_t net) { unsigned npins, idx; const char*name = ivl_logic_basename(net); ivl_drive_t drive0 = ivl_logic_drive0(net); ivl_drive_t drive1 = ivl_logic_drive1(net); switch (ivl_logic_type(net)) { case IVL_LO_AND: fprintf(out, " and %s", name); break; case IVL_LO_BUF: fprintf(out, " buf %s", name); break; case IVL_LO_BUFIF0: fprintf(out, " bufif0 %s", name); break; case IVL_LO_BUFIF1: fprintf(out, " bufif1 %s", name); break; case IVL_LO_BUFT: fprintf(out, " buft %s", name); break; case IVL_LO_BUFZ: fprintf(out, " bufz %s", name); break; case IVL_LO_CMOS: fprintf(out, " cmos %s", name); break; case IVL_LO_NAND: fprintf(out, " nand %s", name); break; case IVL_LO_NMOS: fprintf(out, " nmos %s", name); break; case IVL_LO_NOR: fprintf(out, " nor %s", name); break; case IVL_LO_NOT: fprintf(out, " not %s", name); break; case IVL_LO_NOTIF0: fprintf(out, " notif0 %s", name); break; case IVL_LO_NOTIF1: fprintf(out, " notif1 %s", name); break; case IVL_LO_OR: fprintf(out, " or %s", name); break; case IVL_LO_PMOS: fprintf(out, " pmos %s", name); break; case IVL_LO_PULLDOWN: fprintf(out, " pulldown %s", name); break; case IVL_LO_PULLUP: fprintf(out, " pullup %s", name); break; case IVL_LO_RCMOS: fprintf(out, " rcmos %s", name); break; case IVL_LO_RNMOS: fprintf(out, " rnmos %s", name); break; case IVL_LO_RPMOS: fprintf(out, " rpmos %s", name); break; case IVL_LO_XNOR: fprintf(out, " xnor %s", name); break; case IVL_LO_XOR: fprintf(out, " xor %s", name); break; case IVL_LO_UDP: fprintf(out, " primitive<%s> %s", ivl_udp_name(ivl_logic_udp(net)), name); break; default: fprintf(out, " unsupported gate %s", ivl_logic_type(net), name); break; } fprintf(out, " \n", ivl_logic_width(net)); fprintf(out, " \n"); if (ivl_logic_delay(net,0)) { test_expr_is_delay(ivl_logic_delay(net,0)); show_expression(ivl_logic_delay(net,0), 6); } if (ivl_logic_delay(net,1)) { test_expr_is_delay(ivl_logic_delay(net,1)); show_expression(ivl_logic_delay(net,1), 6); } if (ivl_logic_delay(net,2)) { test_expr_is_delay(ivl_logic_delay(net,2)); show_expression(ivl_logic_delay(net,2), 6); } npins = ivl_logic_pins(net); /* Show the pins of the gate. Pin-0 is always the output, and the remaining pins are the inputs. Inputs may be unconnected, but if connected the nexus width must exactly match the gate width. */ for (idx = 0 ; idx < npins ; idx += 1) { ivl_nexus_t nex = ivl_logic_pin(net, idx); fprintf(out, " %u: %p", idx, nex); if (idx == 0) fprintf(out, " ", drive0, drive1); fprintf(out, "\n"); if (nex == 0) { if (idx == 0) { fprintf(out, " 0: ERROR: Pin 0 must not " "be unconnected\n"); stub_errors += 1; } continue; } if (ivl_logic_width(net) != width_of_nexus(nex)) { fprintf(out, " %u: ERROR: Nexus width is %u\n", idx, width_of_nexus(nex)); stub_errors += 1; } } /* If this is an instance of a UDP, then check that the instantiation is consistent with the definition. */ if (ivl_logic_type(net) == IVL_LO_UDP) { ivl_udp_t udp = ivl_logic_udp(net); if (npins != 1+ivl_udp_nin(udp)) { fprintf(out, " ERROR: UDP %s expects %u inputs\n", ivl_udp_name(udp), ivl_udp_nin(udp)); stub_errors += 1; } /* Add a reference to this udp definition. */ reference_udp_definition(udp); } npins = ivl_logic_attr_cnt(net); for (idx = 0 ; idx < npins ; idx += 1) { ivl_attribute_t cur = ivl_logic_attr_val(net,idx); switch (cur->type) { case IVL_ATT_VOID: fprintf(out, " %s\n", cur->key); break; case IVL_ATT_NUM: fprintf(out, " %s = %ld\n", cur->key, cur->val.num); break; case IVL_ATT_STR: fprintf(out, " %s = %s\n", cur->key, cur->val.str); break; } } } static int show_scope(ivl_scope_t net, void*x) { unsigned idx; const char *is_auto; (void)x; /* Parameter is not used. */ fprintf(out, "scope: %s (%u parameters, %u signals, %u logic)", ivl_scope_name(net), ivl_scope_params(net), ivl_scope_sigs(net), ivl_scope_logs(net)); is_auto = ivl_scope_is_auto(net) ? "automatic " : ""; switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: fprintf(out, " module %s%s", ivl_scope_tname(net), ivl_scope_is_cell(net) ? " (cell)" : ""); break; case IVL_SCT_FUNCTION: fprintf(out, " function %s%s", is_auto, ivl_scope_tname(net)); break; case IVL_SCT_BEGIN: fprintf(out, " begin : %s", ivl_scope_tname(net)); break; case IVL_SCT_FORK: fprintf(out, " fork : %s", ivl_scope_tname(net)); break; case IVL_SCT_TASK: fprintf(out, " task %s%s", is_auto, ivl_scope_tname(net)); break; case IVL_SCT_CLASS: fprintf(out, " class %s", ivl_scope_tname(net)); break; default: fprintf(out, " type(%d) %s", ivl_scope_type(net), ivl_scope_tname(net)); break; } fprintf(out, " time units = 1e%d\n", ivl_scope_time_units(net)); fprintf(out, " time precision = 1e%d\n", ivl_scope_time_precision(net)); for (idx = 0 ; idx < ivl_scope_attr_cnt(net) ; idx += 1) { ivl_attribute_t attr = ivl_scope_attr_val(net, idx); switch (attr->type) { case IVL_ATT_VOID: fprintf(out, " (* %s *)\n", attr->key); break; case IVL_ATT_STR: fprintf(out, " (* %s = \"%s\" *)\n", attr->key, attr->val.str); break; case IVL_ATT_NUM: fprintf(out, " (* %s = %ld *)\n", attr->key, attr->val.num); break; } } for (idx = 0 ; idx < ivl_scope_classes(net) ; idx += 1) show_class(ivl_scope_class(net, idx)); for (idx = 0 ; idx < ivl_scope_params(net) ; idx += 1) show_parameter(ivl_scope_param(net, idx)); for (idx = 0 ; idx < ivl_scope_enumerates(net) ; idx += 1) show_enumerate(ivl_scope_enumerate(net, idx)); for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) show_signal(ivl_scope_sig(net, idx)); for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1) show_event(ivl_scope_event(net, idx)); for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1) show_logic(ivl_scope_log(net, idx)); for (idx = 0 ; idx < ivl_scope_lpms(net) ; idx += 1) show_lpm(ivl_scope_lpm(net, idx)); for (idx = 0 ; idx < ivl_scope_switches(net) ; idx += 1) show_switch(ivl_scope_switch(net, idx)); switch (ivl_scope_type(net)) { case IVL_SCT_FUNCTION: case IVL_SCT_TASK: fprintf(out, " scope function/task definition\n"); if (ivl_scope_def(net) == 0) { fprintf(out, " ERROR: scope missing required task definition\n"); stub_errors += 1; } else { show_statement(ivl_scope_def(net), 6); } break; default: if (ivl_scope_def(net)) { fprintf(out, " ERROR: scope has an attached task definition:\n"); show_statement(ivl_scope_def(net), 6); stub_errors += 1; } break; } fprintf(out, "end scope %s\n", ivl_scope_name(net)); return ivl_scope_children(net, show_scope, 0); } static void show_primitive(ivl_udp_t net, unsigned ref_count) { unsigned rdx; fprintf(out, "primitive %s (referenced %u times)\n", ivl_udp_name(net), ref_count); if (ivl_udp_sequ(net)) fprintf(out, " reg out = %c;\n", ivl_udp_init(net)); else fprintf(out, " wire out;\n"); fprintf(out, " table\n"); for (rdx = 0 ; rdx < ivl_udp_rows(net) ; rdx += 1) { /* Each row has the format: Combinational: iii...io Sequential: oiii...io In the sequential case, the o value in the front is the current output value. */ unsigned idx; const char*row = ivl_udp_row(net,rdx); fprintf(out, " "); if (ivl_udp_sequ(net)) fprintf(out, " cur=%c :", *row++); for (idx = 0 ; idx < ivl_udp_nin(net) ; idx += 1) fprintf(out, " %c", *row++); fprintf(out, " : out=%c\n", *row++); } fprintf(out, " endtable\n"); fprintf(out, "endprimitive\n"); } int target_design(ivl_design_t des) { ivl_scope_t*root_scopes; unsigned nroot = 0; unsigned idx; const char*path = ivl_design_flag(des, "-o"); if (path == 0) { return -1; } out = fopen(path, "w"); if (out == 0) { perror(path); return -2; } for (idx = 0 ; idx < ivl_design_disciplines(des) ; idx += 1) { ivl_discipline_t dis = ivl_design_discipline(des,idx); fprintf(out, "discipline %s\n", ivl_discipline_name(dis)); } ivl_design_roots(des, &root_scopes, &nroot); for (idx = 0 ; idx < nroot ; idx += 1) { ivl_scope_t cur = root_scopes[idx]; switch (ivl_scope_type(cur)) { case IVL_SCT_TASK: fprintf(out, "task = %s\n", ivl_scope_name(cur)); break; case IVL_SCT_FUNCTION: fprintf(out, "function = %s\n", ivl_scope_name(cur)); break; case IVL_SCT_CLASS: fprintf(out, "class = %s\n", ivl_scope_name(cur)); break; case IVL_SCT_PACKAGE: fprintf(out, "package = %s\n", ivl_scope_name(cur)); break; case IVL_SCT_MODULE: fprintf(out, "root module = %s\n", ivl_scope_name(cur)); break; default: fprintf(out, "ERROR scope %s unknown type\n", ivl_scope_name(cur)); stub_errors += 1; break; } show_scope(root_scopes[idx], 0); } while (udp_define_list) { struct udp_define_cell*cur = udp_define_list; udp_define_list = cur->next; show_primitive(cur->udp, cur->ref); free(cur); } fprintf(out, "# There are %u constants detected\n", ivl_design_consts(des)); for (idx = 0 ; idx < ivl_design_consts(des) ; idx += 1) { ivl_net_const_t con = ivl_design_const(des, idx); show_constant(con); } ivl_design_process(des, show_process, 0); fclose(out); return stub_errors; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } iverilog-12_0/tgt-stub/stub.conf000066400000000000000000000000611435245347300167410ustar00rootroot00000000000000functor:cprop functor:nodangle flag:DLL=stub.tgt iverilog-12_0/tgt-stub/switches.c000066400000000000000000000110411435245347300171120ustar00rootroot00000000000000/* * Copyright (c) 2008-2009 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 "priv.h" # include # include # include void show_switch(ivl_switch_t net) { const char*name = ivl_switch_basename(net); int has_enable = 0; ivl_nexus_t nexa, nexb; ivl_variable_type_t nex_type_a, nex_type_b; switch (ivl_switch_type(net)) { case IVL_SW_TRAN: fprintf(out, " tran %s", name); break; case IVL_SW_RTRAN: fprintf(out, " rtran %s", name); break; case IVL_SW_TRANIF0: fprintf(out, " tranif0 %s", name); has_enable = 1; break; case IVL_SW_RTRANIF0: fprintf(out, " rtranif0 %s", name); has_enable = 1; break; case IVL_SW_TRANIF1: fprintf(out, " tranif1 %s", name); has_enable = 1; break; case IVL_SW_RTRANIF1: fprintf(out, " rtranif1 %s", name); has_enable = 1; break; case IVL_SW_TRAN_VP: fprintf(out, " tran(VP wid=%u, part=%u, off=%u) %s", ivl_switch_width(net), ivl_switch_part(net), ivl_switch_offset(net), name); break; } fprintf(out, " island=%p\n", ivl_switch_island(net)); fprintf(out, " \n"); if (ivl_switch_delay(net,0)) { test_expr_is_delay(ivl_switch_delay(net,0)); show_expression(ivl_switch_delay(net,0), 6); } if (ivl_switch_delay(net,1)) { test_expr_is_delay(ivl_switch_delay(net,1)); show_expression(ivl_switch_delay(net,1), 6); } if (ivl_switch_delay(net,2)) { test_expr_is_delay(ivl_switch_delay(net,2)); show_expression(ivl_switch_delay(net,2), 6); } nexa = ivl_switch_a(net); nex_type_a = nexa? type_of_nexus(nexa) : IVL_VT_NO_TYPE; fprintf(out, " A: %p \n", nexa, data_type_string(nex_type_a)); nexb = ivl_switch_b(net); nex_type_b = nexb? type_of_nexus(nexb) : IVL_VT_NO_TYPE; fprintf(out, " B: %p \n", nexb, data_type_string(nex_type_b)); /* The A/B pins of the switch must be present, and must match. */ if (nex_type_a == IVL_VT_NO_TYPE) { fprintf(out, " A: ERROR: Type missing for pin A\n"); stub_errors += 1; } if (nex_type_b == IVL_VT_NO_TYPE) { fprintf(out, " B: ERROR: Type missing for pin B\n"); stub_errors += 1; } if (nex_type_a != nex_type_b) { fprintf(out, " A/B: ERROR: Type mismatch between pins A and B\n"); stub_errors += 1; } if (ivl_switch_type(net) == IVL_SW_TRAN_VP) { /* The TRAN_VP nodes are special in that the specific width matters for each port and should be exactly right for both. */ if (width_of_nexus(nexa) != ivl_switch_width(net)) { fprintf(out, " A: ERROR: part vector nexus " "width=%u, expecting width=%u\n", width_of_nexus(nexa), ivl_switch_width(net)); stub_errors += 1; } if (width_of_nexus(nexb) != ivl_switch_part(net)) { fprintf(out, " B: ERROR: part select nexus " "width=%u, expecting width=%u\n", width_of_nexus(nexb), ivl_switch_part(net)); stub_errors += 1; } } else { /* All other TRAN nodes will have matching vector widths, but the actual value doesn't matter. */ if (width_of_nexus(nexa) != width_of_nexus(nexb)) { fprintf(out, " A/B: ERROR: Width of ports don't match" ": A=%u, B=%u\n", width_of_nexus(nexa), width_of_nexus(nexb)); stub_errors += 1; } } if (has_enable) { ivl_nexus_t nexe = ivl_switch_enable(net); ivl_variable_type_t nexe_type = type_of_nexus(nexe); fprintf(out, " E: %p \n", nexe, data_type_string(nexe_type)); if (width_of_nexus(nexe) != 1) { fprintf(out, " E: ERROR: Nexus width is %u\n", width_of_nexus(nexe)); } } } iverilog-12_0/tgt-stub/types.c000066400000000000000000000077531435245347300164440ustar00rootroot00000000000000/* * Copyright (c) 2012 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 "priv.h" # include static void show_net_type_darray(ivl_type_t net_type) { /* Dynamic arrays have a single element type. */ ivl_type_t element_type = ivl_type_element(net_type); fprintf(out, "darray of "); show_net_type(element_type); } static void show_net_type_queue(ivl_type_t net_type) { /* Dynamic arrays have a single element type. */ ivl_type_t element_type = ivl_type_element(net_type); fprintf(out, "queue of "); show_net_type(element_type); } void show_net_type(ivl_type_t net_type) { ivl_variable_type_t data_type = ivl_type_base(net_type); switch (data_type) { case IVL_VT_NO_TYPE: fprintf(out, ""); stub_errors += 1; break; case IVL_VT_BOOL: fprintf(out, "bool"); break; case IVL_VT_LOGIC: fprintf(out, "logic"); break; case IVL_VT_REAL: fprintf(out, "real"); break; case IVL_VT_STRING: fprintf(out, "string"); break; case IVL_VT_DARRAY: show_net_type_darray(net_type); break; case IVL_VT_CLASS: fprintf(out, "class"); break; case IVL_VT_QUEUE: show_net_type_queue(net_type); break; case IVL_VT_VOID: fprintf(out, "void"); break; } unsigned packed_dimensions = ivl_type_packed_dimensions(net_type); unsigned idx; for (idx = 0 ; idx < packed_dimensions ; idx += 1) { fprintf(out, "[%d:%d]", ivl_type_packed_msb(net_type, idx), ivl_type_packed_lsb(net_type, idx)); } } void show_type_of_signal(ivl_signal_t net) { unsigned dim; /* The data_type is the base type of the signal. This the the starting point for the type. In the long run I think I want to remove this in favor of the ivl_signal_net_type below. */ ivl_variable_type_t data_type = ivl_signal_data_type(net); /* This gets the more general type description. This is a newer form so doesn't yet handle all the cases. Newer types, such DARRAY types, REQUIRE this method to get at the type details. */ ivl_type_t net_type = ivl_signal_net_type(net); if (net_type) { show_net_type(net_type); return; } switch (data_type) { case IVL_VT_NO_TYPE: fprintf(out, ""); break; case IVL_VT_BOOL: fprintf(out, "bool"); break; case IVL_VT_LOGIC: fprintf(out, "logic"); break; case IVL_VT_REAL: fprintf(out, "real"); break; case IVL_VT_STRING: fprintf(out, "string"); break; case IVL_VT_DARRAY: /* The DARRAY type MUST be described by an ivl_signal_net_type object. */ fprintf(out, "ERROR-DARRAY"); stub_errors += 1; break; case IVL_VT_QUEUE: /* The QUEUE type MUST be described by an ivl_signal_net_type object. */ fprintf(out, "ERROR-QUEUE"); stub_errors += 1; break; case IVL_VT_VOID: fprintf(out, "void"); break; case IVL_VT_CLASS: fprintf(out, "class"); break; } for (dim = 0 ; dim < ivl_signal_packed_dimensions(net) ; dim += 1) { fprintf(out, "[%d:%d]", ivl_signal_packed_msb(net,dim), ivl_signal_packed_lsb(net,dim)); } } iverilog-12_0/tgt-verilog/000077500000000000000000000000001435245347300156125ustar00rootroot00000000000000iverilog-12_0/tgt-verilog/Makefile.in000066400000000000000000000046301435245347300176620ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = @ident_support@ $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = verilog.o all: dep verilog.tgt check: all clean: rm -rf *.o dep verilog.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-verilog/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS= -L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif verilog.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) install: all installdirs installfiles F = ./verilog.tgt \ $(srcdir)/vpi_user.h installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./verilog.tgt "$(DESTDIR)$(libdir)/ivl/verilog.tgt" $(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl/verilog.tgt" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-verilog/cppcheck.sup000066400000000000000000000002211435245347300201160ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:verilog.c:411 iverilog-12_0/tgt-verilog/verilog.c000066400000000000000000000247141435245347300174350ustar00rootroot00000000000000/* * Copyright (c) 2000-2017 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" /* * This target writes a Verilog description of the design. The output * Verilog is a single module that has the name of the root module of * the design, but is internally the complete design. */ # include "ivl_target.h" # include # include /* This is the output file where the Verilog program is sent. */ static FILE*out; /* * Scoped objects are the signals, reg and wire and what-not. What * this function does is draw the objects of the scope, along with a * fake scope context so that the hierarchical name remains * pertinent. */ static void draw_scoped_objects(ivl_design_t des) { ivl_scope_t root = ivl_design_root(des); unsigned cnt, idx; cnt = ivl_scope_sigs(root); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(root, idx); switch (ivl_signal_type(sig)) { case IVL_SIT_REG: if (ivl_signal_pins(sig) > 1) fprintf(out, " reg [%u:0] %s;\n", ivl_signal_pins(sig), ivl_signal_basename(sig)); else fprintf(out, " reg %s;\n", ivl_signal_basename(sig)); break; case IVL_SIT_TRI: fprintf(out, " wire %s;\n", ivl_signal_basename(sig)); break; default: assert(0); } } } /* * Given a nexus, this function draws a signal reference. We don't * care really whether the signal is a reg or wire, because this may * be an input or output of a gate. Just print it. And if this is a * bit of a vector, draw the bit select needed to get at the right bit. */ static void draw_nexus(ivl_nexus_t nex) { ivl_signal_t sig=NULL; ivl_nexus_ptr_t ptr=NULL; unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ptr = ivl_nexus_ptr(nex, idx); sig = ivl_nexus_ptr_sig(ptr); if (sig) break; } assert(sig); if (ivl_signal_pins(sig) == 1) { fprintf(out, "%s", ivl_signal_name(sig)); } else { fprintf(out, "%s[%u]", ivl_signal_name(sig), ivl_nexus_ptr_pin(ptr)); } } /* * Draw a single logic gate. Escape the name so that it is preserved * completely. This drawing is happening in the root scope so signal * references can remain hierarchical. */ static int draw_logic(ivl_net_logic_t net) { unsigned npins, idx; const char*name = ivl_logic_name(net); switch (ivl_logic_type(net)) { case IVL_LO_AND: fprintf(out, " and \\%s (", name); break; case IVL_LO_BUF: fprintf(out, " buf \\%s (", name); break; case IVL_LO_OR: fprintf(out, " or \\%s (", name); break; case IVL_LO_XOR: fprintf(out, " xor \\%s (", name); break; default: fprintf(out, "STUB: %s: unsupported gate\n", name); return -1; } draw_nexus(ivl_logic_pin(net, 0)); npins = ivl_logic_pins(net); for (idx = 1 ; idx < npins ; idx += 1) { fprintf(out, ", "); draw_nexus(ivl_logic_pin(net,idx)); } fprintf(out, ");\n"); return 0; } /* * Scan the scope and its children for logic gates. Use the draw_logic * function to draw the actual gate. */ static int draw_scope_logic(ivl_scope_t scope, void*x) { unsigned cnt = ivl_scope_logs(scope); unsigned idx; for (idx = 0 ; idx < cnt ; idx += 1) { draw_logic(ivl_scope_log(scope, idx)); } ivl_scope_children(scope, draw_scope_logic, 0); return 0; } static void show_expression(ivl_expr_t net) { if (net == 0) return; switch (ivl_expr_type(net)) { case IVL_EX_BINARY: { char code = ivl_expr_opcode(net); show_expression(ivl_expr_oper1(net)); switch (code) { case 'e': fprintf(out, "=="); break; case 'n': fprintf(out, "!="); break; case 'N': fprintf(out, "!=="); break; case 'r': fprintf(out, ">>"); break; default: fprintf(out, "%c", code); } show_expression(ivl_expr_oper2(net)); break; } case IVL_EX_CONCAT: { unsigned idx; fprintf(out, "{"); show_expression(ivl_expr_parm(net, 0)); for (idx = 1 ; idx < ivl_expr_parms(net) ; idx += 1) { fprintf(out, ", "); show_expression(ivl_expr_parm(net, idx)); } fprintf(out, "}"); break; } case IVL_EX_NUMBER: { int sigflag = ivl_expr_signed(net); unsigned idx, width = ivl_expr_width(net); const char*bits = ivl_expr_bits(net); fprintf(out, "%u'%sb", width, sigflag? "s" : ""); for (idx = width ; idx > 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); break; } case IVL_EX_SFUNC: fprintf(out, "%s", ivl_expr_name(net)); break; case IVL_EX_STRING: fprintf(out, "\"%s\"", ivl_expr_string(net)); break; case IVL_EX_SIGNAL: fprintf(out, "%s", ivl_expr_name(net)); break; default: fprintf(out, "..."); } } /* * An assignment is one of a possible list of l-values to a behavioral * assignment. Each l-value is either a part select of a signal or a * non-constant bit select. */ static void show_assign_lval(ivl_lval_t lval) { ivl_nexus_t nex; ivl_signal_t sig=NULL; unsigned idx; unsigned lsb=0; assert(ivl_lval_mux(lval) == 0); assert(ivl_lval_mem(lval) == 0); nex = ivl_lval_pin(lval, 0); for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { unsigned pin; ivl_nexus_ptr_t ptr; ptr = ivl_nexus_ptr(nex, idx); sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; lsb = ivl_nexus_ptr_pin(ptr); for (pin = 1 ; pin < ivl_lval_pins(lval) ; pin += 1) { if (ivl_signal_pin(sig, lsb+pin) != ivl_lval_pin(lval,pin)) break; } if (pin < ivl_lval_pins(lval)) continue; break; } assert(sig); if ((lsb > 0) || (lsb + ivl_lval_pins(lval)) < ivl_signal_pins(sig)) { fprintf(out, "%s[%u:%u]", ivl_signal_name(sig), lsb+ivl_lval_pins(lval)-1, lsb); } else { fprintf(out, "%s", ivl_signal_name(sig)); } } static void show_assign_lvals(ivl_statement_t net) { const unsigned cnt = ivl_stmt_lvals(net); if (cnt == 1) { show_assign_lval(ivl_stmt_lval(net, 0)); } else { unsigned idx; fprintf(out, "{"); show_assign_lval(ivl_stmt_lval(net, 0)); for (idx = 1 ; idx < cnt ; idx += 1) { fprintf(out, ", "); show_assign_lval(ivl_stmt_lval(net, idx)); } fprintf(out, "}"); } } static void show_statement(ivl_statement_t net, unsigned ind) { const ivl_statement_type_t code = ivl_statement_type(net); switch (code) { case IVL_ST_ASSIGN: fprintf(out, "%*s", ind, ""); show_assign_lvals(net); fprintf(out, " = "); show_expression(ivl_stmt_rval(net)); fprintf(out, ";\n"); break; case IVL_ST_BLOCK: { unsigned cnt = ivl_stmt_block_count(net); unsigned idx; fprintf(out, "%*sbegin\n", ind, ""); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_statement_t cur = ivl_stmt_block_stmt(net, idx); show_statement(cur, ind+4); } fprintf(out, "%*send\n", ind, ""); break; } case IVL_ST_CONDIT: { ivl_statement_t t = ivl_stmt_cond_true(net); ivl_statement_t f = ivl_stmt_cond_false(net); fprintf(out, "%*sif (", ind, ""); show_expression(ivl_stmt_cond_expr(net)); fprintf(out, ")\n"); if (t) show_statement(t, ind+4); else fprintf(out, "%*s;\n", ind+4, ""); if (f) { fprintf(out, "%*selse\n", ind, ""); show_statement(f, ind+4); } break; } case IVL_ST_DELAY: fprintf(out, "%*s#%lu\n", ind, "", ivl_stmt_delay_val(net)); show_statement(ivl_stmt_sub_stmt(net), ind+2); break; case IVL_ST_NOOP: fprintf(out, "%*s/* noop */;\n", ind, ""); break; case IVL_ST_STASK: if (ivl_stmt_parm_count(net) == 0) { fprintf(out, "%*s%s;\n", ind, "", ivl_stmt_name(net)); } else { unsigned idx; fprintf(out, "%*s%s(", ind, "", ivl_stmt_name(net)); show_expression(ivl_stmt_parm(net, 0)); for (idx = 1 ; idx < ivl_stmt_parm_count(net) ; idx += 1) { fprintf(out, ", "); show_expression(ivl_stmt_parm(net, idx)); } fprintf(out, ");\n"); } break; case IVL_ST_WAIT: fprintf(out, "%*s@(...)\n", ind, ""); show_statement(ivl_stmt_sub_stmt(net), ind+2); break; case IVL_ST_WHILE: fprintf(out, "%*swhile ()\n", ind, ""); show_statement(ivl_stmt_sub_stmt(net), ind+2); break; default: fprintf(out, "%*sunknown statement type (%d)\n", ind, "", code); } } /* * Processes are all collected by ivl and I draw them here in the root * scope. This way, I don't need to do anything about scope * references. */ static int show_process(ivl_process_t net, void*x) { switch (ivl_process_type(net)) { case IVL_PR_INITIAL: fprintf(out, " initial\n"); break; case IVL_PR_ALWAYS: case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: fprintf(out, " always\n"); break; case IVL_PR_FINAL: fprintf(out, " final\n"); break; } show_statement(ivl_process_stmt(net), 8); return 0; } int target_design(ivl_design_t des) { const char*path = ivl_design_flag(des, "-o"); if (path == 0) { return -1; } out = fopen(path, "w"); if (out == 0) { perror(path); return -2; } fprintf(out, "module %s;\n", ivl_scope_name(ivl_design_root(des))); /* Declare all the signals. */ draw_scoped_objects(des); /* Declare logic gates. */ draw_scope_logic(ivl_design_root(des), 0); /* Write out processes. */ ivl_design_process(des, show_process, 0); fprintf(out, "endmodule\n"); fclose(out); return 0; } iverilog-12_0/tgt-vhdl/000077500000000000000000000000001435245347300151005ustar00rootroot00000000000000iverilog-12_0/tgt-vhdl/Makefile.in000066400000000000000000000060141435245347300171460ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CXX = @CXX@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ O = vhdl.o state.o vhdl_element.o vhdl_type.o vhdl_syntax.o scope.o process.o \ stmt.o expr.o lpm.o support.o cast.o logic.o all: dep vhdl.tgt vhdl.conf vhdl-s.conf check: all clean: rm -rf $(O) dep vhdl.tgt distclean: clean rm -f Makefile config.log rm -f stamp-vhdl_config-h vhdl_config.h cppcheck: $(O:.o=.cc) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-vhdl/$@ dep: mkdir dep %.o: %.cc vhdl_config.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif vhdl.tgt: $O $(TGTDEPLIBS) $(CXX) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) stamp-vhdl_config-h: $(srcdir)/vhdl_config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=tgt-vhdl/vhdl_config.h vhdl_config.h: stamp-vhdl_config-h install: all installdirs installfiles F = ./vhdl.tgt \ $(srcdir)/vhdl.conf \ $(srcdir)/vhdl-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vhdl.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl.tgt" $(INSTALL_DATA) $(srcdir)/vhdl.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl.conf" $(INSTALL_DATA) $(srcdir)/vhdl-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl.tgt" "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl.conf" "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdl-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-vhdl/cast.cc000066400000000000000000000232531435245347300163460ustar00rootroot00000000000000/* * Generate code to convert between VHDL types. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_syntax.hh" #include "vhdl_target.h" #include "support.hh" #include #include using namespace std; vhdl_expr *vhdl_expr::cast(const vhdl_type *to) { #if 0 std::cout << "Cast: from=" << type_->get_string() << " (" << type_->get_width() << ") " << " to=" << to->get_string() << " (" << to->get_width() << ")" << std::endl; #endif // If this expression hasn't been given a type then // we can't generate any type conversion code if (NULL == type_) return this; if (to->get_name() == type_->get_name()) { if (to->get_width() == type_->get_width()) return this; // Identical else return resize(to->get_width()); } else { switch (to->get_name()) { case VHDL_TYPE_BOOLEAN: return to_boolean(); case VHDL_TYPE_INTEGER: return to_integer(); case VHDL_TYPE_UNSIGNED: case VHDL_TYPE_SIGNED: case VHDL_TYPE_STD_LOGIC_VECTOR: return to_vector(to->get_name(), to->get_width()); case VHDL_TYPE_STD_LOGIC: return to_std_logic(); case VHDL_TYPE_STD_ULOGIC: return to_std_ulogic(); case VHDL_TYPE_STRING: return to_string(); default: assert(false); } } assert(false); return NULL; } /* * Generate code to cast an expression to a vector type (std_logic_vector, * signed, unsigned). */ vhdl_expr *vhdl_expr::to_vector(vhdl_type_name_t name, int w) { if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { vhdl_expr *others = w == 1 ? NULL : new vhdl_const_bit('0'); vhdl_bit_spec_expr *bs = new vhdl_bit_spec_expr(new vhdl_type(name, w - 1, 0), others); bs->add_bit(0, this); return bs; } else { // We have to cast the expression before resizing or the // wrong sign bit may be extended (i.e. when casting between // signed/unsigned *and* resizing) vhdl_type *t = new vhdl_type(name, w - 1, 0); vhdl_fcall *conv = new vhdl_fcall(t->get_string().c_str(), t); conv->add_expr(this); if (w != type_->get_width()) return conv->resize(w); else return conv; } } /* * Convert a generic expression to an Integer. */ vhdl_expr *vhdl_expr::to_integer() { vhdl_fcall *conv; if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { require_support_function(SF_LOGIC_TO_INTEGER); conv = new vhdl_fcall(support_function::function_name(SF_LOGIC_TO_INTEGER), vhdl_type::integer()); } else conv = new vhdl_fcall("To_Integer", vhdl_type::integer()); conv->add_expr(this); return conv; } vhdl_expr *vhdl_expr::to_string() { bool numeric = type_->get_name() == VHDL_TYPE_UNSIGNED || type_->get_name() == VHDL_TYPE_SIGNED; if (numeric) { vhdl_fcall *image = new vhdl_fcall("integer'image", vhdl_type::string()); image->add_expr(this->cast(vhdl_type::integer())); return image; } else { // Assume type'image exists vhdl_fcall *image = new vhdl_fcall(type_->get_string() + "'image", vhdl_type::string()); image->add_expr(this); return image; } } /* * Convert a generic expression to a Boolean. */ vhdl_expr *vhdl_expr::to_boolean() { if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { // '1' is true all else are false vhdl_const_bit *one = new vhdl_const_bit('1'); return new vhdl_binop_expr (this, VHDL_BINOP_EQ, one, vhdl_type::boolean()); } else if (type_->get_name() == VHDL_TYPE_UNSIGNED) { // Need to use a support function for this conversion require_support_function(SF_UNSIGNED_TO_BOOLEAN); vhdl_fcall *conv = new vhdl_fcall(support_function::function_name(SF_UNSIGNED_TO_BOOLEAN), vhdl_type::boolean()); conv->add_expr(this); return conv; } else if (type_->get_name() == VHDL_TYPE_SIGNED) { require_support_function(SF_SIGNED_TO_BOOLEAN); vhdl_fcall *conv = new vhdl_fcall(support_function::function_name(SF_SIGNED_TO_BOOLEAN), vhdl_type::boolean()); conv->add_expr(this); return conv; } assert(false); return NULL; } /* * Generate code to convert and expression to std_logic. */ vhdl_expr *vhdl_expr::to_std_logic() { if (type_->get_name() == VHDL_TYPE_BOOLEAN) { require_support_function(SF_BOOLEAN_TO_LOGIC); vhdl_fcall *ah = new vhdl_fcall(support_function::function_name(SF_BOOLEAN_TO_LOGIC), vhdl_type::std_logic()); ah->add_expr(this); return ah; } else if (type_->get_name() == VHDL_TYPE_SIGNED) { require_support_function(SF_SIGNED_TO_LOGIC); vhdl_fcall *ah = new vhdl_fcall(support_function::function_name(SF_SIGNED_TO_LOGIC), vhdl_type::std_logic()); ah->add_expr(this); return ah; } else if (type_->get_name() == VHDL_TYPE_UNSIGNED) { require_support_function(SF_UNSIGNED_TO_LOGIC); vhdl_fcall *ah = new vhdl_fcall(support_function::function_name(SF_UNSIGNED_TO_LOGIC), vhdl_type::std_logic()); ah->add_expr(this); return ah; } assert(false); return NULL; } vhdl_expr *vhdl_expr::to_std_ulogic() { if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { vhdl_fcall *f = new vhdl_fcall("std_logic", vhdl_type::std_logic()); f->add_expr(this); return f; } else assert(false); return NULL; } /* * Change the width of a signed/unsigned type. */ vhdl_expr *vhdl_expr::resize(int newwidth) { vhdl_type *rtype; assert(type_); if (type_->get_name() == VHDL_TYPE_SIGNED) rtype = vhdl_type::nsigned(newwidth); else if (type_->get_name() == VHDL_TYPE_UNSIGNED) rtype = vhdl_type::nunsigned(newwidth); else if (type_->get_name() == VHDL_TYPE_STD_LOGIC) { // Pad it with zeros vhdl_expr* zeros = new vhdl_const_bits(string(newwidth - 1, '0').c_str(), newwidth - 1, false, true); vhdl_binop_expr* concat = new vhdl_binop_expr(zeros, VHDL_BINOP_CONCAT, this, vhdl_type::nunsigned(newwidth)); return concat; } else return this; // Doesn't make sense to resize non-vector type vhdl_fcall *resizef = new vhdl_fcall("Resize", rtype); resizef->add_expr(this); resizef->add_expr(new vhdl_const_int(newwidth)); return resizef; } vhdl_expr *vhdl_const_int::to_vector(vhdl_type_name_t name, int w) { if (name == VHDL_TYPE_SIGNED || name == VHDL_TYPE_UNSIGNED) { const char *fname = name == VHDL_TYPE_SIGNED ? "To_Signed" : "To_Unsigned"; vhdl_fcall *conv = new vhdl_fcall(fname, new vhdl_type(name, w - 1, 0)); conv->add_expr(this); conv->add_expr(new vhdl_const_int(w)); return conv; } else return vhdl_expr::to_vector(name, w); } int64_t vhdl_const_bits::bits_to_int() const { char msb = value_[value_.size() - 1]; int64_t result = 0, bit; for (int i = sizeof(int64_t)*8 - 1; i >= 0; i--) { if (i > (int)value_.size() - 1) bit = (msb == '1' && signed_) ? 1 : 0; else bit = value_[i] == '1' ? 1 : 0; result = (result << 1) | bit; } return result; } vhdl_expr *vhdl_const_bits::to_std_logic() { // VHDL won't let us cast directly between a vector and // a scalar type // But we don't need to here as we have the bits available // Take the least significant bit char lsb = value_[0]; return new vhdl_const_bit(lsb); } char vhdl_const_bits::sign_bit() const { return signed_ ? value_[value_.length()-1] : '0'; } vhdl_expr *vhdl_const_bits::to_vector(vhdl_type_name_t name, int w) { if (name == VHDL_TYPE_STD_LOGIC_VECTOR) { // Don't need to do anything return this; } else if (name == VHDL_TYPE_SIGNED || name == VHDL_TYPE_UNSIGNED) { // Extend with sign bit value_.resize(w, sign_bit()); return this; } assert(false); return NULL; } vhdl_expr *vhdl_const_bits::to_integer() { return new vhdl_const_int(bits_to_int()); } vhdl_expr *vhdl_const_bits::resize(int w) { // Rather than generating a call to Resize, when can just sign-extend // the bits here. As well as looking better, this avoids any ambiguity // between which of the signed/unsigned versions of Resize to use. value_.resize(w, sign_bit()); return this; } vhdl_expr *vhdl_const_bit::to_integer() { return new vhdl_const_int(bit_ == '1' ? 1 : 0); } vhdl_expr *vhdl_const_bit::to_boolean() { return new vhdl_const_bool(bit_ == '1'); } vhdl_expr *vhdl_const_bit::to_std_ulogic() { return this; } vhdl_expr *vhdl_const_bit::to_vector(vhdl_type_name_t name, int w) { // Zero-extend this bit to the correct width return (new vhdl_const_bits(&bit_, 1, name == VHDL_TYPE_SIGNED))->resize(w); } iverilog-12_0/tgt-vhdl/cppcheck.sup000066400000000000000000000002741435245347300174140ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:vhdl.cc:96 // target_query() unusedFunction:vhdl.cc:137 iverilog-12_0/tgt-vhdl/expr.cc000066400000000000000000000553331435245347300163760ustar00rootroot00000000000000/* * VHDL code generation for expressions. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "support.hh" #include "state.hh" #include #include #include using namespace std; /* * Change the signedness of a vector. */ static vhdl_expr *change_signedness(vhdl_expr *e, bool issigned) { int msb = e->get_type()->get_msb(); int lsb = e->get_type()->get_lsb(); vhdl_type u(issigned ? VHDL_TYPE_SIGNED : VHDL_TYPE_UNSIGNED, msb, lsb); return e->cast(&u); } /* * Generate code to ensure that the VHDL expression vhd_e has the * same signedness as the Verilog expression vl_e. */ static vhdl_expr *correct_signedness(vhdl_expr *vhd_e, ivl_expr_t vl_e) { bool should_be_signed = ivl_expr_signed(vl_e) != 0; if (vhd_e->get_type()->get_name() == VHDL_TYPE_UNSIGNED && should_be_signed) { //operand->print(); //std::cout << "^ should be signed but is not" << std::endl; return change_signedness(vhd_e, true); } else if (vhd_e->get_type()->get_name() == VHDL_TYPE_SIGNED && !should_be_signed) { //operand->print(); //std::cout << "^ should be unsigned but is not" << std::endl; return change_signedness(vhd_e, false); } else return vhd_e; } /* * Convert a constant Verilog string to a constant VHDL string. */ static vhdl_expr *translate_string(ivl_expr_t e) { // TODO: May need to inspect or escape parts of this const char *str = ivl_expr_string(e); return new vhdl_const_string(str); } /* * A reference to a signal in an expression. It's assumed that the * signal has already been defined elsewhere. */ static vhdl_var_ref *translate_signal(ivl_expr_t e) { ivl_signal_t sig = ivl_expr_signal(e); const vhdl_scope *scope = find_scope_for_signal(sig); assert(scope); const char *renamed = get_renamed_signal(sig).c_str(); vhdl_decl *decl = scope->get_decl(renamed); assert(decl); // Make sure we can read from this declaration // E.g. if this is an `out' port then we need to make it a buffer decl->ensure_readable(); // Can't generate a constant initialiser for this signal // later as it has already been read if (scope->initializing()) decl->set_initial(NULL); vhdl_var_ref *ref = new vhdl_var_ref(renamed, new vhdl_type(*decl->get_type())); ivl_expr_t off; if (ivl_signal_array_count(sig) > 0 && (off = ivl_expr_oper1(e))) { // Select from an array vhdl_expr *vhd_off = translate_expr(off); if (NULL == vhd_off) { delete ref; return NULL; } vhdl_type integer(VHDL_TYPE_INTEGER); ref->set_slice(vhd_off->cast(&integer)); } return ref; } /* * A numeric literal ends up as std_logic bit string. */ static vhdl_expr *translate_number(ivl_expr_t e) { if (ivl_expr_width(e) == 1) return new vhdl_const_bit(ivl_expr_bits(e)[0]); else return new vhdl_const_bits(ivl_expr_bits(e), ivl_expr_width(e), ivl_expr_signed(e) != 0); } static vhdl_expr *translate_ulong(ivl_expr_t e) { return new vhdl_const_int(ivl_expr_uvalue(e)); } static vhdl_expr *translate_delay(ivl_expr_t e) { return scale_time(get_active_entity(), ivl_expr_delay_val(e)); } static vhdl_expr *translate_reduction(support_function_t f, bool neg, vhdl_expr *operand) { vhdl_expr *result; if (operand->get_type()->get_name() == VHDL_TYPE_STD_LOGIC) result = operand; else { require_support_function(f); vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(f), vhdl_type::std_logic()); vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR); fcall->add_expr(operand->cast(&std_logic_vector)); result = fcall; } if (neg) return new vhdl_unaryop_expr(VHDL_UNARYOP_NOT, result, vhdl_type::std_logic()); else return result; } static vhdl_expr *translate_unary(ivl_expr_t e) { vhdl_expr *operand = translate_expr(ivl_expr_oper1(e)); if (NULL == operand) return NULL; operand = correct_signedness(operand, e); char opcode = ivl_expr_opcode(e); switch (opcode) { case '!': case '~': return new vhdl_unaryop_expr (VHDL_UNARYOP_NOT, operand, new vhdl_type(*operand->get_type())); case '-': operand = change_signedness(operand, true); return new vhdl_unaryop_expr (VHDL_UNARYOP_NEG, operand, new vhdl_type(*operand->get_type())); case 'N': // NOR return translate_reduction(SF_REDUCE_OR, true, operand); case '|': return translate_reduction(SF_REDUCE_OR, false, operand); case 'A': // NAND return translate_reduction(SF_REDUCE_AND, true, operand); case '&': return translate_reduction(SF_REDUCE_AND, false, operand); case '^': // XOR return translate_reduction(SF_REDUCE_XOR, false, operand); case 'X': // XNOR return translate_reduction(SF_REDUCE_XNOR, false, operand); default: error("No translation for unary opcode '%c'\n", ivl_expr_opcode(e)); delete operand; return NULL; } } /* * Translate a numeric binary operator (+, -, etc.) to * a VHDL equivalent using the numeric_std package. */ static vhdl_expr *translate_numeric(vhdl_expr *lhs, vhdl_expr *rhs, vhdl_binop_t op) { // May need to make either side Boolean for operators // to work vhdl_type boolean(VHDL_TYPE_BOOLEAN); if (lhs->get_type()->get_name() == VHDL_TYPE_BOOLEAN) rhs = rhs->cast(&boolean); else if (rhs->get_type()->get_name() == VHDL_TYPE_BOOLEAN) lhs = lhs->cast(&boolean); vhdl_type *rtype; if (op == VHDL_BINOP_MULT) rtype = new vhdl_type(lhs->get_type()->get_name(), (lhs->get_type()->get_width()*2) - 1, 0); else rtype = new vhdl_type(*lhs->get_type()); return new vhdl_binop_expr(lhs, op, rhs, rtype); } static vhdl_expr *translate_relation(vhdl_expr *lhs, vhdl_expr *rhs, vhdl_binop_t op) { // Generate any necessary casts // Arbitrarily, the RHS is casted to the type of the LHS vhdl_expr *r_cast = rhs->cast(lhs->get_type()); return new vhdl_binop_expr(lhs, op, r_cast, vhdl_type::boolean()); } /* * Like translate_relation but both operands must be Boolean. */ static vhdl_expr *translate_logical(vhdl_expr *lhs, vhdl_expr *rhs, vhdl_binop_t op) { vhdl_type boolean(VHDL_TYPE_BOOLEAN); return translate_relation(lhs->cast(&boolean), rhs->cast(&boolean), op); } static vhdl_expr *translate_shift(vhdl_expr *lhs, vhdl_expr *rhs, vhdl_binop_t op) { // The RHS must be an integer vhdl_type integer(VHDL_TYPE_INTEGER); vhdl_expr *r_cast = rhs->cast(&integer); vhdl_type *rtype = new vhdl_type(*lhs->get_type()); // The sra operator is not defined on numeric_std types until // VHDL-2006 which is not well supported. Instead we can use // the shift_right function which does the same thing and // exists in earlier versions of numeric_std. if (op == VHDL_BINOP_SRA) { vhdl_fcall *sra = new vhdl_fcall("shift_right", rtype); sra->add_expr(lhs); sra->add_expr(r_cast); return sra; } else return new vhdl_binop_expr(lhs, op, r_cast, rtype); } /* * The exponentiation operator in VHDL is not defined for numeric_std * types. We can get around this by converting the operands to integers, * performing the operation, then converting the result back to the * original type. This will work OK in simulation but certainly will not * synthesise unless the operands are constant. * * However, even this does not work quite correctly. The Integer type in * VHDL is signed and usually only 32 bits, therefore any result larger * than this will overflow and raise an exception. I can't see a way * around this at the moment. */ static vhdl_expr *translate_power(ivl_expr_t e, vhdl_expr *lhs, vhdl_expr *rhs) { vhdl_type integer(VHDL_TYPE_INTEGER); vhdl_expr *lhs_int = lhs->cast(&integer); vhdl_expr *rhs_int = rhs->cast(&integer); vhdl_expr *result = new vhdl_binop_expr(lhs_int, VHDL_BINOP_POWER, rhs_int, vhdl_type::integer()); int width = ivl_expr_width(e); const char *func = ivl_expr_signed(e) ? "To_Signed" : "To_Unsigned"; vhdl_type *type = ivl_expr_signed(e) ? vhdl_type::nsigned(width) : vhdl_type::nunsigned(width); vhdl_fcall *conv = new vhdl_fcall(func, type); conv->add_expr(result); conv->add_expr(new vhdl_const_int(width)); return conv; } static vhdl_expr *translate_binary(ivl_expr_t e) { vhdl_expr *lhs = translate_expr(ivl_expr_oper1(e)); if (NULL == lhs) return NULL; vhdl_expr *rhs = translate_expr(ivl_expr_oper2(e)); if (NULL == rhs) { delete lhs; return NULL; } int lwidth = lhs->get_type()->get_width(); int rwidth = rhs->get_type()->get_width(); int result_width = ivl_expr_width(e); // There's a funny corner-case where both the LHS and RHS are constant // single bit numbers and the VHDL compiler can't decide between the // std_ulogic and bit overloads of various operators const bool lnumber = ivl_expr_type(ivl_expr_oper1(e)) == IVL_EX_NUMBER; const bool rnumber = ivl_expr_type(ivl_expr_oper2(e)) == IVL_EX_NUMBER; if (lwidth == 1 && rwidth == 1 && lnumber && rnumber) { // It's sufficient to qualify only one side vhdl_fcall *lqual = new vhdl_fcall("std_logic'", lhs->get_type()); lqual->add_expr(lhs); lhs = lqual; } // For === and !== we need to compare std_logic_vectors // rather than signeds vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR, result_width-1, 0); vhdl_type_name_t ltype = lhs->get_type()->get_name(); vhdl_type_name_t rtype = rhs->get_type()->get_name(); bool vectorop = (ltype == VHDL_TYPE_SIGNED || ltype == VHDL_TYPE_UNSIGNED) && (rtype == VHDL_TYPE_SIGNED || rtype == VHDL_TYPE_UNSIGNED); // May need to resize the left or right hand side or change the // signedness if (vectorop) { if (lwidth < rwidth) lhs = lhs->resize(rwidth); else if (rwidth < lwidth) rhs = rhs->resize(lwidth); lhs = correct_signedness(lhs, ivl_expr_oper1(e)); rhs = correct_signedness(rhs, ivl_expr_oper2(e)); } vhdl_expr *result; switch (ivl_expr_opcode(e)) { case '+': result = translate_numeric(lhs, rhs, VHDL_BINOP_ADD); break; case '-': result = translate_numeric(lhs, rhs, VHDL_BINOP_SUB); break; case '*': result = translate_numeric(lhs, rhs, VHDL_BINOP_MULT); break; case '/': result = translate_numeric(lhs, rhs, VHDL_BINOP_DIV); break; case '%': result = translate_numeric(lhs, rhs, VHDL_BINOP_MOD); break; case 'e': result = translate_relation(lhs, rhs, VHDL_BINOP_EQ); break; case 'E': if (vectorop) result = translate_relation(lhs->cast(&std_logic_vector), rhs->cast(&std_logic_vector), VHDL_BINOP_EQ); else result = translate_relation(lhs, rhs, VHDL_BINOP_EQ); break; case 'n': result = translate_relation(lhs, rhs, VHDL_BINOP_NEQ); break; case 'N': if (vectorop) result = translate_relation(lhs->cast(&std_logic_vector), rhs->cast(&std_logic_vector), VHDL_BINOP_NEQ); else result = translate_relation(lhs, rhs, VHDL_BINOP_NEQ); break; case '&': // Bitwise AND result = translate_numeric(lhs, rhs, VHDL_BINOP_AND); break; case 'a': // Logical AND result = translate_logical(lhs, rhs, VHDL_BINOP_AND); break; case 'A': // Bitwise NAND result = translate_numeric(lhs, rhs, VHDL_BINOP_NAND); break; case 'O': // Bitwise NOR result = translate_numeric(lhs, rhs, VHDL_BINOP_NOR); break; case 'X': // Bitwise XNOR result = translate_numeric(lhs, rhs, VHDL_BINOP_XNOR); break; case '|': // Bitwise OR result = translate_numeric(lhs, rhs, VHDL_BINOP_OR); break; case 'o': // Logical OR result = translate_logical(lhs, rhs, VHDL_BINOP_OR); break; case '<': result = translate_relation(lhs, rhs, VHDL_BINOP_LT); break; case 'L': result = translate_relation(lhs, rhs, VHDL_BINOP_LEQ); break; case '>': result = translate_relation(lhs, rhs, VHDL_BINOP_GT); break; case 'G': result = translate_relation(lhs, rhs, VHDL_BINOP_GEQ); break; case 'l': result = translate_shift(lhs, rhs, VHDL_BINOP_SL); break; case 'r': result = translate_shift(lhs, rhs, VHDL_BINOP_SR); break; case 'R': // Arithmetic right shift // Verilog only actually performs a signed shift if the // argument being shifted is signed, otherwise it defaults // to a normal shift if (ivl_expr_signed(ivl_expr_oper1(e))) result = translate_shift(lhs, rhs, VHDL_BINOP_SRA); else result = translate_shift(lhs, rhs, VHDL_BINOP_SR); break; case '^': result = translate_numeric(lhs, rhs, VHDL_BINOP_XOR); break; case 'p': // Power result = translate_power(e, lhs, rhs); break; default: error("No translation for binary opcode '%c'\n", ivl_expr_opcode(e)); delete lhs; delete rhs; return NULL; } if (NULL == result) return NULL; if (vectorop) { result = correct_signedness(result, e); int actual_width = result->get_type()->get_width(); if (actual_width != result_width) { //result->print(); //std::cout << "^ should be " << result_width << " but is " << actual_width << std::endl; } } return result; } static vhdl_expr *translate_select(ivl_expr_t e) { vhdl_expr *from = translate_expr(ivl_expr_oper1(e)); if (NULL == from) return NULL; ivl_expr_t o2 = ivl_expr_oper2(e); if (o2) { vhdl_expr *base = translate_expr(ivl_expr_oper2(e)); if (NULL == base) return NULL; vhdl_var_ref *from_var_ref = dynamic_cast(from); if (NULL == from_var_ref) { // We can't directly select bits from something that's not // a variable reference in VHDL, but we can emulate the // effect with a shift and a resize if (ivl_expr_signed(ivl_expr_oper1(e))) { vhdl_fcall *sra = new vhdl_fcall("shift_right", from->get_type()); sra->add_expr(from); sra->add_expr(base->to_integer()); return sra; } else return new vhdl_binop_expr(from, VHDL_BINOP_SR, base->to_integer(), from->get_type()); } else if (from_var_ref->get_type()->get_name() != VHDL_TYPE_STD_LOGIC) { // We can use the more idiomatic VHDL slice notation on a // single variable reference vhdl_type integer(VHDL_TYPE_INTEGER); from_var_ref->set_slice(base->cast(&integer), ivl_expr_width(e) - 1); return from_var_ref; } else { // Make sure we're not trying to select more than one bit // from a std_logic (this shouldn't actually happen) if (ivl_expr_width(e) > 1) { error("%s:%d: trying to select more than one bit from a std_logic", ivl_expr_file(e), ivl_expr_lineno(e)); return NULL; } else return from_var_ref; } } else return correct_signedness(from, e)->resize(ivl_expr_width(e)); } template static T *translate_parms(T *t, ivl_expr_t e) { int nparams = ivl_expr_parms(e); for (int i = 0; i < nparams; i++) { vhdl_expr *param = translate_expr(ivl_expr_parm(e, i)); if (NULL == param) return NULL; t->add_expr(param); } return t; } static vhdl_expr *translate_ufunc(ivl_expr_t e) { ivl_scope_t defscope = ivl_expr_def(e); ivl_scope_t parentscope = ivl_scope_parent(defscope); assert(ivl_scope_type(parentscope) == IVL_SCT_MODULE); // A function is always declared in a module, which should have // a corresponding entity by this point: so we can get type // information, etc. from the declaration vhdl_entity *parent_ent = find_entity(parentscope); assert(parent_ent); const char *funcname = ivl_scope_tname(defscope); vhdl_type *rettype = vhdl_type::type_for(ivl_expr_width(e), ivl_expr_signed(e) != 0); vhdl_fcall *fcall = new vhdl_fcall(funcname, rettype); int nparams = ivl_expr_parms(e); for (int i = 0; i < nparams; i++) { vhdl_expr *param = translate_expr(ivl_expr_parm(e, i)); if (NULL == param) { delete fcall; return NULL; } // Ensure the parameter has the correct VHDL type // Parameter number is i + 1 since 0th parameter is return value ivl_signal_t param_sig = ivl_scope_port(defscope, i + 1); vhdl_type *param_type = vhdl_type::type_for(ivl_signal_width(param_sig), ivl_signal_signed(param_sig) != 0); fcall->add_expr(param->cast(param_type)); delete param_type; } return fcall; } static vhdl_expr *translate_ternary(ivl_expr_t e) { support_function_t sf; int width = ivl_expr_width(e); bool issigned = ivl_expr_signed(e) != 0; if (width == 1) sf = SF_TERNARY_LOGIC; else if (issigned) sf = SF_TERNARY_SIGNED; else sf = SF_TERNARY_UNSIGNED; require_support_function(sf); vhdl_expr *test = translate_expr(ivl_expr_oper1(e)); vhdl_expr *true_part = translate_expr(ivl_expr_oper2(e)); vhdl_expr *false_part = translate_expr(ivl_expr_oper3(e)); if (!test || !true_part || !false_part) return NULL; vhdl_type boolean(VHDL_TYPE_BOOLEAN); test = test->cast(&boolean); vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(sf), vhdl_type::type_for(width, issigned)); fcall->add_expr(test); fcall->add_expr(true_part); fcall->add_expr(false_part); return fcall; } static vhdl_expr *translate_concat(ivl_expr_t e) { vhdl_type *rtype = vhdl_type::type_for(ivl_expr_width(e), ivl_expr_signed(e) != 0); vhdl_binop_expr *concat = new vhdl_binop_expr(VHDL_BINOP_CONCAT, rtype); int nrepeat = ivl_expr_repeat(e); while (nrepeat--) translate_parms(concat, e); return concat; } vhdl_expr *translate_sfunc_time(ivl_expr_t) { cerr << "warning: no translation for $time (returning 0)" << endl; vhdl_expr *result = new vhdl_const_int(0); result->set_comment("$time not supported, returned 0 instead!"); return result; } vhdl_expr *translate_sfunc_stime(ivl_expr_t) { cerr << "warning: no translation for $stime (returning 0)" << endl; vhdl_expr *result = new vhdl_const_int(0); result->set_comment("$stime not supported, returned 0 instead!"); return result; } vhdl_expr *translate_sfunc_simtime(ivl_expr_t) { cerr << "warning: no translation for $simtime (returning 0)" << endl; vhdl_expr *result = new vhdl_const_int(0); result->set_comment("$simtime not supported, returned 0 instead!"); return result; } vhdl_expr *translate_sfunc_random(ivl_expr_t) { cerr << "warning: no translation for $random (returning 0)" << endl; vhdl_expr *result = new vhdl_const_int(0); result->set_comment("$random not supported, returned 0 instead!"); return result; } vhdl_expr *translate_sfunc_fopen(ivl_expr_t) { cerr << "warning: no translation for $fopen (returning 0)" << endl; vhdl_expr *result = new vhdl_const_int(0); result->set_comment("$fopen not supported, returned 0 instead!"); return result; } vhdl_expr *translate_sfunc(ivl_expr_t e) { const char *name = ivl_expr_name(e); if (strcmp(name, "$time") == 0) return translate_sfunc_time(e); else if (strcmp(name, "$stime") == 0) return translate_sfunc_stime(e); else if (strcmp(name, "$simtime") == 0) return translate_sfunc_simtime(e); else if (strcmp(name, "$random") == 0) return translate_sfunc_random(e); else if (strcmp(name, "$fopen") == 0) return translate_sfunc_random(e); else { error("No translation for system function %s", name); return NULL; } } /* * Generate a VHDL expression from a Verilog expression. */ vhdl_expr *translate_expr(ivl_expr_t e) { assert(e); ivl_expr_type_t type = ivl_expr_type(e); switch (type) { case IVL_EX_STRING: return translate_string(e); case IVL_EX_SIGNAL: return translate_signal(e); case IVL_EX_NUMBER: return translate_number(e); case IVL_EX_ULONG: return translate_ulong(e); case IVL_EX_UNARY: return translate_unary(e); case IVL_EX_BINARY: return translate_binary(e); case IVL_EX_SELECT: return translate_select(e); case IVL_EX_UFUNC: return translate_ufunc(e); case IVL_EX_TERNARY: return translate_ternary(e); case IVL_EX_CONCAT: return translate_concat(e); case IVL_EX_SFUNC: return translate_sfunc(e); case IVL_EX_DELAY: return translate_delay(e); case IVL_EX_REALNUM: error("No VHDL translation for real expression at %s:%d", ivl_expr_file(e), ivl_expr_lineno(e)); return NULL; default: error("No VHDL translation for expression at %s:%d (type = %d)", ivl_expr_file(e), ivl_expr_lineno(e), type); return NULL; } } /* * Translate an expression into a time. This is achieved simply * by multiplying the expression by 1ns. */ vhdl_expr *translate_time_expr(ivl_expr_t e) { vhdl_expr *time = translate_expr(e); if (NULL == time) return NULL; if (time->get_type()->get_name() != VHDL_TYPE_TIME) { vhdl_type integer(VHDL_TYPE_INTEGER); time = time->cast(&integer); vhdl_expr *ns1 = scale_time(get_active_entity(), 1); return new vhdl_binop_expr(time, VHDL_BINOP_MULT, ns1, vhdl_type::time()); } else // Translating IVL_EX_DELAY will always return a time type return time; } iverilog-12_0/tgt-vhdl/logic.cc000066400000000000000000000215461435245347300165140ustar00rootroot00000000000000/* * VHDL code generation for logic devices. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "vhdl_element.hh" #include "state.hh" #include #include #include using namespace std; /* * Convert the inputs of a logic gate to a binary expression. */ static vhdl_expr *inputs_to_expr(vhdl_scope *scope, vhdl_binop_t op, ivl_net_logic_t log) { // Not always std_logic but this is probably OK since // the program has already been type checked vhdl_binop_expr *gate = new vhdl_binop_expr(op, vhdl_type::std_logic()); int npins = ivl_logic_pins(log); for (int i = 1; i < npins; i++) { ivl_nexus_t input = ivl_logic_pin(log, i); gate->add_expr(readable_ref(scope, input)); } return gate; } /* * Convert a gate input to an unary expression. */ static vhdl_expr *input_to_expr(vhdl_scope *scope, vhdl_unaryop_t op, ivl_net_logic_t log) { ivl_nexus_t input = ivl_logic_pin(log, 1); assert(input); vhdl_expr *operand = readable_ref(scope, input); return new vhdl_unaryop_expr(op, operand, vhdl_type::std_logic()); } static void bufif_logic(vhdl_arch *arch, ivl_net_logic_t log, bool if0) { ivl_nexus_t output = ivl_logic_pin(log, 0); vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output); assert(lhs); vhdl_expr *val = readable_ref(arch->get_scope(), ivl_logic_pin(log, 1)); vhdl_expr *sel = readable_ref(arch->get_scope(), ivl_logic_pin(log, 2)); vhdl_expr *cmp; if (ivl_logic_width(log) == 1) { vhdl_expr *on = new vhdl_const_bit(if0 ? '0' : '1'); cmp = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, on, NULL); } else { vhdl_expr *zero = (new vhdl_const_int(0))->cast(sel->get_type()); vhdl_binop_t op = if0 ? VHDL_BINOP_EQ : VHDL_BINOP_NEQ; cmp = new vhdl_binop_expr(sel, op, zero, NULL); } ivl_signal_t sig = find_signal_named(lhs->get_name(), arch->get_scope()); char zbit; switch (ivl_signal_type(sig)) { case IVL_SIT_TRI0: zbit = '0'; break; case IVL_SIT_TRI1: zbit = '1'; break; case IVL_SIT_TRI: default: zbit = 'Z'; } vhdl_expr *z = new vhdl_const_bit(zbit); if (ivl_logic_width(log) > 1) z = new vhdl_bit_spec_expr(NULL, z); vhdl_cassign_stmt *cass = new vhdl_cassign_stmt(lhs, z); cass->add_condition(val, cmp); arch->add_stmt(cass); } static void comb_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) { ivl_udp_t udp = ivl_logic_udp(log); // As with regular case statements, the expression in a // `with .. select' statement must be "locally static". // This is achieved by first combining the inputs into // a temporary ostringstream ss; ss << ivl_logic_basename(log) << "_Tmp"; int msb = ivl_udp_nin(udp) - 1; vhdl_type *tmp_type = vhdl_type::std_logic_vector(msb, 0); vhdl_signal_decl *tmp_decl = new vhdl_signal_decl(ss.str(), tmp_type); arch->get_scope()->add_decl(tmp_decl); int nin = ivl_udp_nin(udp); vhdl_expr *tmp_rhs; if (nin == 1) { tmp_rhs = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 1)); tmp_rhs = tmp_rhs->cast(tmp_type); } else tmp_rhs = inputs_to_expr(arch->get_scope(), VHDL_BINOP_CONCAT, log); ss.str(""); ss << "Input to " << ivl_logic_basename(log) << " " << ivl_udp_name(udp) << " UDP"; tmp_decl->set_comment(ss.str()); vhdl_var_ref *tmp_ref = new vhdl_var_ref(tmp_decl->get_name().c_str(), NULL); arch->add_stmt(new vhdl_cassign_stmt(tmp_ref, tmp_rhs)); // Now we can implement the UDP as a `with .. select' statement // by reading values out of the table ivl_nexus_t output_nex = ivl_logic_pin(log, 0); vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), output_nex); vhdl_with_select_stmt *ws = new vhdl_with_select_stmt(new vhdl_var_ref(*tmp_ref), out); // Ensure the select statement completely covers the input space // or some strict VHDL compilers will complain ws->add_default(new vhdl_const_bit('X')); int nrows = ivl_udp_rows(udp); for (int i = 0; i < nrows; i++) { const char *row = ivl_udp_row(udp, i); vhdl_expr *value = new vhdl_const_bit(row[nin]); vhdl_expr *cond = new vhdl_const_bits(row, nin, false); ivl_expr_t delay_ex = ivl_logic_delay(log, 1); vhdl_expr *delay = NULL; if (delay_ex) delay = translate_time_expr(delay_ex); ws->add_condition(value, cond, delay); } ss.str(""); ss << "UDP " << ivl_udp_name(udp); ws->set_comment(ss.str()); arch->add_stmt(ws); } static void seq_udp_logic(vhdl_arch *arch, ivl_net_logic_t log) { ivl_udp_t udp = ivl_logic_udp(log); // These will be translated to a process with a single // case statement vhdl_process *proc = new vhdl_process(ivl_logic_basename(log)); ostringstream ss; ss << "Generated from UDP " << ivl_udp_name(udp); proc->set_comment(ss.str().c_str()); // Create a variable to hold the concatenation of the inputs int msb = ivl_udp_nin(udp) - 1; vhdl_type *tmp_type = vhdl_type::std_logic_vector(msb, 0); proc->get_scope()->add_decl(new vhdl_var_decl("UDP_Inputs", tmp_type)); // Concatenate the inputs into a single expression that can be // used as the test in a case statement (this can't be inserted // directly into the case statement due to the requirement that // the test expression be "locally static") int nin = ivl_udp_nin(udp); vhdl_expr *tmp_rhs = NULL; if (nin == 1) { vhdl_var_ref *ref = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, 1)); tmp_rhs = ref->cast(tmp_type); proc->add_sensitivity(ref->get_name()); } else { vhdl_binop_expr *concat = new vhdl_binop_expr(VHDL_BINOP_CONCAT, NULL); for (int i = 1; i < nin; i++) { vhdl_var_ref *ref = nexus_to_var_ref(arch->get_scope(), ivl_logic_pin(log, i)); concat->add_expr(ref); proc->add_sensitivity(ref->get_name()); } tmp_rhs = concat; } proc->get_container()->add_stmt (new vhdl_assign_stmt(new vhdl_var_ref("UDP_Inputs", NULL), tmp_rhs)); arch->add_stmt(proc); } static void udp_logic(vhdl_arch *arch, ivl_net_logic_t log) { if (ivl_udp_sequ(ivl_logic_udp(log))) seq_udp_logic(arch, log); else comb_udp_logic(arch, log); } static vhdl_expr *translate_logic_inputs(vhdl_scope *scope, ivl_net_logic_t log) { switch (ivl_logic_type(log)) { case IVL_LO_NOT: return input_to_expr(scope, VHDL_UNARYOP_NOT, log); case IVL_LO_AND: return inputs_to_expr(scope, VHDL_BINOP_AND, log); case IVL_LO_OR: return inputs_to_expr(scope, VHDL_BINOP_OR, log); case IVL_LO_NAND: return inputs_to_expr(scope, VHDL_BINOP_NAND, log); case IVL_LO_NOR: return inputs_to_expr(scope, VHDL_BINOP_NOR, log); case IVL_LO_XOR: return inputs_to_expr(scope, VHDL_BINOP_XOR, log); case IVL_LO_XNOR: return inputs_to_expr(scope, VHDL_BINOP_XNOR, log); case IVL_LO_BUF: case IVL_LO_BUFT: case IVL_LO_BUFZ: return nexus_to_var_ref(scope, ivl_logic_pin(log, 1)); case IVL_LO_PULLUP: return new vhdl_const_bit('1'); case IVL_LO_PULLDOWN: return new vhdl_const_bit('0'); default: error("Don't know how to translate logic type = %d to expression", ivl_logic_type(log)); return NULL; } } void draw_logic(vhdl_arch *arch, ivl_net_logic_t log) { switch (ivl_logic_type(log)) { case IVL_LO_BUFIF0: bufif_logic(arch, log, true); break; case IVL_LO_BUFIF1: bufif_logic(arch, log, false); break; case IVL_LO_UDP: udp_logic(arch, log); break; default: { // The output is always pin zero ivl_nexus_t output = ivl_logic_pin(log, 0); vhdl_var_ref *lhs = nexus_to_var_ref(arch->get_scope(), output); vhdl_expr *rhs = translate_logic_inputs(arch->get_scope(), log); vhdl_cassign_stmt *ass = new vhdl_cassign_stmt(lhs, rhs); ivl_expr_t delay = ivl_logic_delay(log, 1); if (delay) ass->set_after(translate_time_expr(delay)); arch->add_stmt(ass); } } } iverilog-12_0/tgt-vhdl/lpm.cc000066400000000000000000000251631435245347300162060ustar00rootroot00000000000000/* * VHDL code generation for LPM devices. * * Copyright (C) 2008-2009 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "state.hh" #include #include /* * Return the base of a part select. */ static vhdl_expr *part_select_base(vhdl_scope *scope, ivl_lpm_t lpm) { vhdl_expr *off; ivl_nexus_t base = ivl_lpm_data(lpm, 1); if (base != NULL) off = readable_ref(scope, base); else off = new vhdl_const_int(ivl_lpm_base(lpm)); // Array indexes must be integers vhdl_type integer(VHDL_TYPE_INTEGER); return off->cast(&integer); } static vhdl_expr *binop_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t op) { unsigned out_width = ivl_lpm_width(lpm); vhdl_type *result_type = vhdl_type::type_for(out_width, ivl_lpm_signed(lpm) != 0); vhdl_binop_expr *expr = new vhdl_binop_expr(op, result_type); for (unsigned i = 0; i < ivl_lpm_size(lpm); i++) { vhdl_expr *e = readable_ref(scope, ivl_lpm_data(lpm, i)); if (NULL == e) return NULL; // It's possible that the inputs are a mixture of signed and unsigned // in which case we must cast them to the output type e = e->cast(vhdl_type::type_for(e->get_type()->get_width(), ivl_lpm_signed(lpm) != 0)); // Bit of a hack: the LPM inputs are in the wrong order for concatenation if (op == VHDL_BINOP_CONCAT) expr->add_expr_front(e); else expr->add_expr(e); } if (op == VHDL_BINOP_MULT) { // Need to resize the output to the desired size, // as this does not happen automatically in VHDL vhdl_fcall *resize = new vhdl_fcall("Resize", vhdl_type::nsigned(out_width)); resize->add_expr(expr); resize->add_expr(new vhdl_const_int(out_width)); return resize; } else return expr; } static vhdl_expr *rel_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t op) { vhdl_binop_expr *expr = new vhdl_binop_expr(op, vhdl_type::boolean()); vhdl_expr *lhs = readable_ref(scope, ivl_lpm_data(lpm, 0)); if (NULL == lhs) return NULL; vhdl_expr *rhs = readable_ref(scope, ivl_lpm_data(lpm, 1)); if (NULL == rhs) { delete lhs; return NULL; } // Ensure LHS and RHS are the same type if (lhs->get_type() != rhs->get_type()) rhs = rhs->cast(lhs->get_type()); expr->add_expr(lhs); expr->add_expr(rhs); return expr; } static vhdl_expr *part_select_vp_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { vhdl_var_ref *selfrom = readable_ref(scope, ivl_lpm_data(lpm, 0)); if (NULL == selfrom) return NULL; vhdl_expr *off = part_select_base(scope, lpm);; if (NULL == off) return NULL; if (selfrom->get_type()->get_width() > 1) selfrom->set_slice(off, ivl_lpm_width(lpm) - 1); return selfrom; } static vhdl_expr *part_select_pv_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { return readable_ref(scope, ivl_lpm_data(lpm, 0)); } static vhdl_expr *ufunc_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { ivl_scope_t f_scope = ivl_lpm_define(lpm); vhdl_fcall *fcall = new vhdl_fcall(ivl_scope_basename(f_scope), NULL); for (unsigned i = 0; i < ivl_lpm_size(lpm); i++) { vhdl_var_ref *ref = readable_ref(scope, ivl_lpm_data(lpm, i)); if (NULL == ref) { delete fcall; return NULL; } fcall->add_expr(ref); } return fcall; } static vhdl_expr *reduction_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, support_function_t f, bool invert) { vhdl_var_ref *ref = readable_ref(scope, ivl_lpm_data(lpm, 0)); if (NULL == ref) return NULL; vhdl_expr *result; if (ref->get_type()->get_name() == VHDL_TYPE_STD_LOGIC) result = ref; else { require_support_function(f); vhdl_fcall *fcall = new vhdl_fcall(support_function::function_name(f), vhdl_type::std_logic()); vhdl_type std_logic_vector(VHDL_TYPE_STD_LOGIC_VECTOR); fcall->add_expr(ref->cast(&std_logic_vector)); result = fcall; } if (invert) return new vhdl_unaryop_expr (VHDL_UNARYOP_NOT, result, vhdl_type::std_logic()); else return result; } static vhdl_expr *sign_extend_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { vhdl_expr *ref = readable_ref(scope, ivl_lpm_data(lpm, 0)); if (ref) return ref->resize(ivl_lpm_width(lpm)); else return NULL; } static vhdl_expr *array_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { ivl_signal_t array = ivl_lpm_array(lpm); if (!seen_signal_before(array)) return NULL; const char *renamed = get_renamed_signal(array).c_str(); vhdl_decl *adecl = scope->get_decl(renamed); assert(adecl); vhdl_type *atype = new vhdl_type(*adecl->get_type()); vhdl_expr *select = readable_ref(scope, ivl_lpm_select(lpm)); if (NULL == select) { delete atype; return NULL; } vhdl_var_ref *ref = new vhdl_var_ref(renamed, atype); vhdl_type integer(VHDL_TYPE_INTEGER); ref->set_slice(select->cast(&integer)); return ref; } static vhdl_expr *shift_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm, vhdl_binop_t shift_op) { vhdl_expr *lhs = readable_ref(scope, ivl_lpm_data(lpm, 0)); vhdl_expr *rhs = readable_ref(scope, ivl_lpm_data(lpm, 1)); if (!lhs || !rhs) return NULL; // The RHS must be an integer vhdl_type integer(VHDL_TYPE_INTEGER); vhdl_expr *r_cast = rhs->cast(&integer); vhdl_type *rtype = new vhdl_type(*lhs->get_type()); return new vhdl_binop_expr(lhs, shift_op, r_cast, rtype); } static vhdl_expr *repeat_lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { vhdl_expr *in = readable_ref(scope, ivl_lpm_data(lpm, 0)); return new vhdl_bit_spec_expr(NULL, in); } static vhdl_expr *lpm_to_expr(vhdl_scope *scope, ivl_lpm_t lpm) { switch (ivl_lpm_type(lpm)) { case IVL_LPM_ADD: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_ADD); case IVL_LPM_SUB: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_SUB); case IVL_LPM_MULT: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_MULT); case IVL_LPM_DIVIDE: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_DIV); case IVL_LPM_MOD: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_MOD); case IVL_LPM_CONCAT: return binop_lpm_to_expr(scope, lpm, VHDL_BINOP_CONCAT); case IVL_LPM_CMP_GE: return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GEQ); case IVL_LPM_CMP_GT: return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_GT); case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_NEQ); case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EEQ: return rel_lpm_to_expr(scope, lpm, VHDL_BINOP_EQ); case IVL_LPM_PART_VP: return part_select_vp_lpm_to_expr(scope, lpm); case IVL_LPM_PART_PV: return part_select_pv_lpm_to_expr(scope, lpm); case IVL_LPM_UFUNC: return ufunc_lpm_to_expr(scope, lpm); case IVL_LPM_RE_AND: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_AND, false); case IVL_LPM_RE_NAND: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_AND, true); case IVL_LPM_RE_NOR: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_OR, true); case IVL_LPM_RE_OR: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_OR, false); case IVL_LPM_RE_XOR: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XOR, false); case IVL_LPM_RE_XNOR: return reduction_lpm_to_expr(scope, lpm, SF_REDUCE_XNOR, true); case IVL_LPM_SIGN_EXT: return sign_extend_lpm_to_expr(scope, lpm); case IVL_LPM_ARRAY: return array_lpm_to_expr(scope, lpm); case IVL_LPM_SHIFTL: return shift_lpm_to_expr(scope, lpm, VHDL_BINOP_SL); case IVL_LPM_SHIFTR: return shift_lpm_to_expr(scope, lpm, VHDL_BINOP_SR); case IVL_LPM_REPEAT: return repeat_lpm_to_expr(scope, lpm); default: error("Unsupported LPM type: %d", ivl_lpm_type(lpm)); return NULL; } } static int draw_mux_lpm(vhdl_arch *arch, ivl_lpm_t lpm) { int nselects = ivl_lpm_selects(lpm); if (nselects > 1) { error("Only 1 LPM select bit supported at the moment"); return 1; } vhdl_scope *scope = arch->get_scope(); vhdl_expr *s0 = readable_ref(scope, ivl_lpm_data(lpm, 0)); vhdl_expr *s1 = readable_ref(scope, ivl_lpm_data(lpm, 1)); vhdl_expr *sel = readable_ref(scope, ivl_lpm_select(lpm)); vhdl_expr *b1 = new vhdl_const_bit('1'); vhdl_expr *t1 = new vhdl_binop_expr(sel, VHDL_BINOP_EQ, b1, vhdl_type::boolean()); vhdl_var_ref *out = nexus_to_var_ref(scope, ivl_lpm_q(lpm)); // Make sure s0 and s1 have the same type as the output s0 = s0->cast(out->get_type()); s1 = s1->cast(out->get_type()); vhdl_cassign_stmt *s = new vhdl_cassign_stmt(out, s0); s->add_condition(s1, t1); arch->add_stmt(s); return 0; } int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm) { if (ivl_lpm_type(lpm) == IVL_LPM_MUX) return draw_mux_lpm(arch, lpm); vhdl_expr *f = lpm_to_expr(arch->get_scope(), lpm); if (NULL == f) return 1; vhdl_var_ref *out = nexus_to_var_ref(arch->get_scope(), ivl_lpm_q(lpm)); if (ivl_lpm_type(lpm) == IVL_LPM_PART_PV) { vhdl_expr *off = part_select_base(arch->get_scope(), lpm); assert(off); out->set_slice(off, ivl_lpm_width(lpm) - 1); } // Converting from Boolean to std_logic is a common case so should be // replaced by an idiomatic VHDL construct rather than a call to a // conversion function bool bool_to_logic = out->get_type()->get_name() == VHDL_TYPE_STD_LOGIC && f->get_type()->get_name() == VHDL_TYPE_BOOLEAN; if (bool_to_logic) { vhdl_cassign_stmt* s = new vhdl_cassign_stmt(out, new vhdl_const_bit('0')); s->add_condition(new vhdl_const_bit('1'), f); arch->add_stmt(s); } else arch->add_stmt(new vhdl_cassign_stmt(out, f->cast(out->get_type()))); return 0; } iverilog-12_0/tgt-vhdl/process.cc000066400000000000000000000104141435245347300170650ustar00rootroot00000000000000/* * VHDL code generation for processes. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "vhdl_element.hh" #include "state.hh" #include #include #include /* * Check to see if the process should have a name. */ static const char * get_process_name(ivl_process_t proc) { const char* name = ""; // Look for always @(...) begin : to find the name if (ivl_process_type(proc) == IVL_PR_ALWAYS) { ivl_statement_t stmt = ivl_process_stmt(proc); if (ivl_statement_type(stmt) == IVL_ST_WAIT) { stmt = ivl_stmt_sub_stmt(stmt); if (ivl_statement_type(stmt) == IVL_ST_BLOCK) { ivl_scope_t proc_scope = ivl_stmt_block_scope(stmt); if (proc_scope) name = ivl_scope_basename(proc_scope); } } } return name; } /* * Convert a Verilog process to VHDL and add it to the architecture * of the given entity. */ static int generate_vhdl_process(vhdl_entity *ent, ivl_process_t proc) { set_active_entity(ent); // Create a new process and store it in the entity's // architecture. This needs to be done first or the // parent link won't be valid (and draw_stmt needs this // to add information to the architecture) vhdl_process *vhdl_proc = new vhdl_process(get_process_name(proc)); ent->get_arch()->add_stmt(vhdl_proc); // If this is an initial process, push signal initialisation // into the declarations vhdl_proc->get_scope()->set_initializing (ivl_process_type(proc) == IVL_PR_INITIAL); ivl_statement_t stmt = ivl_process_stmt(proc); int rc = draw_stmt(vhdl_proc, vhdl_proc->get_container(), stmt); if (rc != 0) return rc; // Initial processes are translated to VHDL processes with // no sensitivity list and and indefinite wait statement at // the end // However, if no statements were added to the container // by draw_stmt, don't bother adding a wait as `emit' // will optimise the process out of the output bool is_initial = ivl_process_type(proc) == IVL_PR_INITIAL; bool is_empty = vhdl_proc->get_container()->empty(); if (is_initial && !is_empty) { vhdl_wait_stmt *wait = new vhdl_wait_stmt(); vhdl_proc->get_container()->add_stmt(wait); } // Add a comment indicating where it came from ivl_scope_t scope = ivl_process_scope(proc); const char *type = ivl_process_type(proc) == IVL_PR_INITIAL ? "initial" : "always"; std::ostringstream ss; ss << "Generated from " << type << " process in " << ivl_scope_tname(scope) << " (" << ivl_process_file(proc) << ":" << ivl_process_lineno(proc) << ")"; vhdl_proc->set_comment(ss.str()); set_active_entity(NULL); return 0; } extern "C" int draw_process(ivl_process_t proc, void *) { ivl_scope_t scope = ivl_process_scope(proc); if (!is_default_scope_instance(scope)) return 0; // Ignore this process at it's not in a scope that // we're using to generate code debug_msg("Translating process in scope type %s (%s:%d)", ivl_scope_tname(scope), ivl_process_file(proc), ivl_process_lineno(proc)); // Skip over any generate and begin scopes until we find // the module that contains them - this is where we will // generate the process while (ivl_scope_type(scope) == IVL_SCT_GENERATE || ivl_scope_type(scope) == IVL_SCT_BEGIN) scope = ivl_scope_parent(scope); assert(ivl_scope_type(scope) == IVL_SCT_MODULE); vhdl_entity *ent = find_entity(scope); assert(ent != NULL); return generate_vhdl_process(ent, proc); } iverilog-12_0/tgt-vhdl/scope.cc000066400000000000000000001144121435245347300165230ustar00rootroot00000000000000/* * VHDL code generation for scopes. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "vhdl_element.hh" #include "state.hh" #include #include #include #include using namespace std; /* * This represents the portion of a nexus that is visible within * a VHDL scope. If that nexus portion does not contain a signal, * then `tmpname' gives the name of the temporary that will be * used when this nexus is used in `scope' (e.g. for LPMs that * appear in instantiations). The list `connect' lists all the * signals that should be joined together to re-create the net. */ struct scope_nexus_t { vhdl_scope *scope; ivl_signal_t sig; // A real signal unsigned pin; // The pin this signal is connected to string tmpname; // A new temporary signal list connect; // Other signals to wire together }; /* * This structure is stored in the private part of each nexus. * It stores a scope_nexus_t for each VHDL scope which is * connected to that nexus. It's stored as a list so we can use * contained_within to allow several nested scopes to reference * the same signal. */ struct nexus_private_t { list signals; vhdl_expr *const_driver; }; /* * Returns the scope_nexus_t of this nexus visible within scope. */ static scope_nexus_t *visible_nexus(nexus_private_t *priv, vhdl_scope *scope) { list::iterator it; for (it = priv->signals.begin(); it != priv->signals.end(); ++it) { if (scope->contained_within((*it).scope)) return &*it; } return NULL; } /* * Remember that a signal in `scope' is part of this nexus. The * first signal passed to this function for a scope will be used * as the canonical representation of this nexus when we need to * convert it to a variable reference (e.g. in a LPM input/output). */ static void link_scope_to_nexus_signal(nexus_private_t *priv, vhdl_scope *scope, ivl_signal_t sig, unsigned pin) { scope_nexus_t *sn; if ((sn = visible_nexus(priv, scope))) { assert(sn->tmpname == ""); // Remember to connect this signal up later // If one of the signals is a input, make sure the input is not being driven if (ivl_signal_port(sn->sig) == IVL_SIP_INPUT) sn->sig = sig; else sn->connect.push_back(sig); } else { scope_nexus_t new_sn = { scope, sig, pin, "", list() }; priv->signals.push_back(new_sn); } } /* * Make a temporary the representative of this nexus in scope. */ static void link_scope_to_nexus_tmp(nexus_private_t *priv, vhdl_scope *scope, const string &name) { scope_nexus_t new_sn = { scope, NULL, 0, name, list() }; priv->signals.push_back(new_sn); } /* * Finds the name of the nexus signal within this scope. */ static string visible_nexus_signal_name(nexus_private_t *priv, vhdl_scope *scope, unsigned *pin) { scope_nexus_t *sn = visible_nexus(priv, scope); assert(sn); *pin = sn->pin; return sn->sig ? get_renamed_signal(sn->sig) : sn->tmpname; } /* * Calculate the signal type of a nexus. This is modified from * draw_net_input in tgt-vvp. This also returns the width of * the signal(s) connected to the nexus. */ static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex, int &width) { ivl_signal_type_t out = IVL_SIT_TRI; width = 0; for (unsigned idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { ivl_signal_type_t stype; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; width = ivl_signal_width(sig); stype = ivl_signal_type(sig); if (stype == IVL_SIT_TRI) continue; if (stype == IVL_SIT_NONE) continue; out = stype; } return out; } /* * Generates VHDL code to fully represent a nexus. */ void draw_nexus(ivl_nexus_t nexus) { nexus_private_t *priv = new nexus_private_t; int nexus_signal_width = -1; priv->const_driver = NULL; int nptrs = ivl_nexus_ptrs(nexus); // Number of drivers for this nexus int ndrivers = 0; // First pass through connect all the signals up for (int i = 0; i < nptrs; i++) { ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i); ivl_signal_t sig; if ((sig = ivl_nexus_ptr_sig(nexus_ptr))) { vhdl_scope *scope = find_scope_for_signal(sig); if (scope) { unsigned pin = ivl_nexus_ptr_pin(nexus_ptr); link_scope_to_nexus_signal(priv, scope, sig, pin); } nexus_signal_width = ivl_signal_width(sig); } } // Second pass through make sure logic/LPMs have signal // inputs and outputs for (int i = 0; i < nptrs; i++) { ivl_nexus_ptr_t nexus_ptr = ivl_nexus_ptr(nexus, i); ivl_net_logic_t log; ivl_lpm_t lpm; ivl_net_const_t con; if ((log = ivl_nexus_ptr_log(nexus_ptr))) { ivl_scope_t log_scope = ivl_logic_scope(log); if (!is_default_scope_instance(log_scope)) continue; vhdl_entity *ent = find_entity(log_scope); assert(ent); vhdl_scope *vhdl_scope = ent->get_arch()->get_scope(); if (visible_nexus(priv, vhdl_scope)) { // Already seen this signal in vhdl_scope } else { // Create a temporary signal to connect it to the nexus vhdl_type *type = vhdl_type::type_for(ivl_logic_width(log), false); ostringstream ss; ss << "LO" << ivl_logic_basename(log); vhdl_scope->add_decl(new vhdl_signal_decl(ss.str(), type)); link_scope_to_nexus_tmp(priv, vhdl_scope, ss.str()); } // If this is connected to pin-0 then this nexus is driven // by this logic gate if (ivl_logic_pin(log, 0) == nexus) ndrivers++; } else if ((lpm = ivl_nexus_ptr_lpm(nexus_ptr))) { ivl_scope_t lpm_scope = ivl_lpm_scope(lpm); vhdl_entity *ent = find_entity(lpm_scope); assert(ent); vhdl_scope *vhdl_scope = ent->get_arch()->get_scope(); if (visible_nexus(priv, vhdl_scope)) { // Already seen this signal in vhdl_scope } else { // Create a temporary signal to connect the nexus // TODO: we could avoid this for IVL_LPM_PART_PV // If we already know how wide the temporary should be // (i.e. because we've seen a signal it's connected to) // then use that, otherwise use the width of the LPM int lpm_temp_width; if (nexus_signal_width != -1) lpm_temp_width = nexus_signal_width; else lpm_temp_width = ivl_lpm_width(lpm); vhdl_type *type = vhdl_type::type_for(lpm_temp_width, ivl_lpm_signed(lpm) != 0); ostringstream ss; ss << "LPM"; if (nexus == ivl_lpm_q(lpm)) ss << "_q"; else { for (unsigned d = 0; d < ivl_lpm_size(lpm); d++) { if (nexus == ivl_lpm_data(lpm, d)) ss << "_d" << d; } } ss << ivl_lpm_basename(lpm); if (!vhdl_scope->have_declared(ss.str())) vhdl_scope->add_decl(new vhdl_signal_decl(ss.str(), type)); link_scope_to_nexus_tmp(priv, vhdl_scope, ss.str()); } // If this is connected to the LPM output then this nexus // is driven by the LPM if (ivl_lpm_q(lpm) == nexus) ndrivers++; } else if ((con = ivl_nexus_ptr_con(nexus_ptr))) { if (ivl_const_type(con) == IVL_VT_REAL) { error("No VHDL translation for real constant (%g)", ivl_const_real(con)); continue; } if (ivl_const_width(con) == 1) priv->const_driver = new vhdl_const_bit(ivl_const_bits(con)[0]); else priv->const_driver = new vhdl_const_bits(ivl_const_bits(con), ivl_const_width(con), ivl_const_signed(con) != 0); // A constant is a sort of driver ndrivers++; } } // Drive undriven nets with a constant if (ndrivers == 0) { char def = 0; int width; switch (signal_type_of_nexus(nexus, width)) { case IVL_SIT_TRI: case IVL_SIT_UWIRE: def = 'Z'; break; case IVL_SIT_TRI0: def = '0'; break; case IVL_SIT_TRI1: def = '1'; break; case IVL_SIT_TRIAND: error("No VHDL translation for triand nets"); break; case IVL_SIT_TRIOR: error("No VHDL translation for trior nets"); break; default: ; } if (def) { if (width > 1) priv->const_driver = new vhdl_bit_spec_expr(vhdl_type::std_logic(), new vhdl_const_bit(def)); else priv->const_driver = new vhdl_const_bit(def); } } // Save the private data in the nexus ivl_nexus_set_private(nexus, priv); } /* * Ensure that a nexus has been initialised. I.e. all the necessary * statements, declarations, etc. have been generated. */ static void seen_nexus(ivl_nexus_t nexus) { if (ivl_nexus_get_private(nexus) == NULL) draw_nexus(nexus); } /* * Translate a nexus to a variable reference. Given a nexus and a * scope, this function returns a reference to a signal that is * connected to the nexus and within the given scope. This signal * might not exist in the original Verilog source (even as a * compiler-generated temporary). If this nexus hasn't been * encountered before, the necessary code to connect up the nexus * will be generated. */ vhdl_var_ref *nexus_to_var_ref(vhdl_scope *scope, ivl_nexus_t nexus) { seen_nexus(nexus); nexus_private_t *priv = static_cast(ivl_nexus_get_private(nexus)); unsigned pin; string renamed(visible_nexus_signal_name(priv, scope, &pin)); vhdl_decl *decl = scope->get_decl(renamed); assert(decl); vhdl_type *type = new vhdl_type(*(decl->get_type())); vhdl_var_ref *ref = new vhdl_var_ref(renamed.c_str(), type); if (decl->get_type()->get_name() == VHDL_TYPE_ARRAY) ref->set_slice(new vhdl_const_int(pin), 0); return ref; } // Return a variable reference for a nexus that is guaranteed to // be readable. vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex) { vhdl_var_ref* ref = nexus_to_var_ref(scope, nex); vhdl_decl* decl = scope->get_decl(ref->get_name()); decl->ensure_readable(); return ref; } /* * Translate all the primitive logic gates into concurrent * signal assignments. */ static void declare_logic(vhdl_arch *arch, ivl_scope_t scope) { debug_msg("Declaring logic in scope type %s", ivl_scope_tname(scope)); int nlogs = ivl_scope_logs(scope); for (int i = 0; i < nlogs; i++) draw_logic(arch, ivl_scope_log(scope, i)); } // Replace consecutive underscores with a single underscore static void replace_consecutive_underscores(string& str) { size_t pos = str.find("__"); while (pos != string::npos) { str.replace(pos, 2, "_"); pos = str.find("__"); } } static bool is_vhdl_reserved_word(const string& word) { // This is the complete list of VHDL reserved words const char *vhdl_reserved[] = { "abs", "access", "after", "alias", "all", "and", "architecture", "array", "assert", "attribute", "begin", "block", "body", "buffer", "bus", "case", "component", "configuration", "constant", "disconnect", "downto", "else", "elsif", "end", "entity", "exit", "file", "for", "function", "generate", "generic", "group", "guarded", "if", "impure", "in", "inertial", "inout", "is", "label", "library", "linkage", "literal", "loop", "map", "mod", "nand", "new", "next", "nor", "not", "null", "of", "on", "open", "or", "others", "out", "package", "port", "postponed", "procedure", "process", "pure", "range", "record", "register", "reject", "rem", "report", "return", "rol", "ror", "select", "severity", "signal", "shared", "sla", "sll", "sra", "srl", "subtype", "then", "to", "transport", "type", "unaffected", "units", "until", "use", "variable", "wait", "when", "while", "with", "xnor", "xor", NULL }; for (const char **p = vhdl_reserved; *p != NULL; p++) { if (strcasecmp(*p, word.c_str()) == 0) return true; } return false; } // Return a valid VHDL name for a Verilog module static string valid_entity_name(const string& module_name) { string name(module_name); replace_consecutive_underscores(name); if (name[0] == '_') name = "module" + name; if (*name.rbegin() == '_') name += "module"; if (is_vhdl_reserved_word(name)) name += "_module"; ostringstream ss; int i = 1; ss << name; while (find_entity(ss.str())) { // Keep adding an extra number until we get a unique name ss.str(""); ss << name << i++; } return ss.str(); } // Make sure a signal name conforms to VHDL naming rules. string make_safe_name(ivl_signal_t sig) { string base(ivl_signal_basename(sig)); if (ivl_signal_local(sig)) base = "tmp" + base; if (base[0] == '_') base = "sig" + base; if (*base.rbegin() == '_') base += "sig"; // Can't have two consecutive underscores replace_consecutive_underscores(base); // A signal name may not be the same as a component name if (find_entity(base) != NULL) base += "_sig"; if (is_vhdl_reserved_word(base)) base += "_sig"; return base; } // Check if `name' differs from an existing name only in case and // make it unique if it does. static void avoid_name_collision(string& name, vhdl_scope* scope) { if (scope->name_collides(name)) { name += "_"; ostringstream ss; int i = 1; do { // Keep adding an extra number until we get a unique name ss.str(""); ss << name << i++; } while (scope->name_collides(ss.str())); name = ss.str(); } } // Concatenate the expanded genvar values together to make a unique // instance name // This isn't ideal: it would be better to replace the Verilog // generate with an equivalent VHDL generate, but this isn't possible // with the current API static string genvar_unique_suffix(ivl_scope_t scope) { ostringstream suffix; while (scope && ivl_scope_type(scope) == IVL_SCT_GENERATE) { for (unsigned i = 0; i < ivl_scope_params(scope); i++) { ivl_parameter_t param = ivl_scope_param(scope, i); ivl_expr_t e = ivl_parameter_expr(param); if (ivl_expr_type(e) == IVL_EX_NUMBER) { vhdl_expr* value = translate_expr(e); assert(value); value = value->cast(vhdl_type::integer()); suffix << "_" << ivl_parameter_basename(param); value->emit(suffix, 0); delete value; } else { error("Only numeric genvars supported at the moment"); return "_ERROR"; // Never used } } scope = ivl_scope_parent(scope); } return suffix.str(); } // Declare a single signal in a scope static void declare_one_signal(vhdl_entity *ent, ivl_signal_t sig, ivl_scope_t scope) { remember_signal(sig, ent->get_arch()->get_scope()); string name(make_safe_name(sig)); name += genvar_unique_suffix(scope); avoid_name_collision(name, ent->get_arch()->get_scope()); rename_signal(sig, name); vhdl_type *sig_type; unsigned dimensions = ivl_signal_dimensions(sig); if (dimensions > 0) { // Arrays are implemented by generating a separate type // declaration for each array, and then declaring a // signal of that type if (dimensions > 1) { error("> 1 dimension arrays not implemented yet"); return; } string type_name = name + "_Type"; vhdl_type *base_type = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); int lsb = ivl_signal_array_base(sig); int msb = lsb + ivl_signal_array_count(sig) - 1; vhdl_type *array_type = vhdl_type::array_of(base_type, type_name, msb, lsb); vhdl_decl *array_decl = new vhdl_type_decl(type_name, array_type); ent->get_arch()->get_scope()->add_decl(array_decl); sig_type = new vhdl_type(*array_type); } else { sig_type = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0, 0, ivl_signal_type(sig) == IVL_SIT_UWIRE); } ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { case IVL_SIP_NONE: { vhdl_decl *decl = new vhdl_signal_decl(name, sig_type); ostringstream ss; if (ivl_signal_local(sig)) { ss << "Temporary created at " << ivl_signal_file(sig) << ":" << ivl_signal_lineno(sig); } else { ss << "Declared at " << ivl_signal_file(sig) << ":" << ivl_signal_lineno(sig); } decl->set_comment(ss.str().c_str()); ent->get_arch()->get_scope()->add_decl(decl); } break; case IVL_SIP_INPUT: ent->get_scope()->add_decl (new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_IN)); break; case IVL_SIP_OUTPUT: { vhdl_port_decl *decl = new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_OUT); ent->get_scope()->add_decl(decl); } if (ivl_signal_type(sig) == IVL_SIT_REG) { // A registered output // In Verilog the output and reg can have the // same name: this is not valid in VHDL // Instead a new signal foo_Reg is created // which represents the register std::string newname(name); newname += "_Reg"; rename_signal(sig, newname); vhdl_type *reg_type = new vhdl_type(*sig_type); ent->get_arch()->get_scope()->add_decl (new vhdl_signal_decl(newname, reg_type)); // Create a concurrent assignment statement to // connect the register to the output ent->get_arch()->add_stmt (new vhdl_cassign_stmt (new vhdl_var_ref(name.c_str(), NULL), new vhdl_var_ref(newname.c_str(), NULL))); } break; case IVL_SIP_INOUT: ent->get_scope()->add_decl (new vhdl_port_decl(name.c_str(), sig_type, VHDL_PORT_INOUT)); break; default: assert(false); } } // Declare all signals and ports for a scope. // This is done in two phases: first the ports are added, then // internal signals. Making two passes like this ensures ports get // first pick of names when there is a collision. static void declare_signals(vhdl_entity *ent, ivl_scope_t scope) { debug_msg("Declaring signals in scope type %s", ivl_scope_tname(scope)); int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) != IVL_SIP_NONE) declare_one_signal(ent, sig, scope); } for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) == IVL_SIP_NONE) declare_one_signal(ent, sig, scope); } } /* * Generate VHDL for LPM instances in a module. */ static void declare_lpm(vhdl_arch *arch, ivl_scope_t scope) { int nlpms = ivl_scope_lpms(scope); for (int i = 0; i < nlpms; i++) { ivl_lpm_t lpm = ivl_scope_lpm(scope, i); if (draw_lpm(arch, lpm) != 0) error("Failed to translate LPM %s", ivl_lpm_name(lpm)); } } /* * Map two signals together in an instantiation. * The signals are joined by a nexus. */ static void map_signal(ivl_signal_t to, vhdl_entity *parent, vhdl_comp_inst *inst) { // TODO: Work for multiple words ivl_nexus_t nexus = ivl_signal_nex(to, 0); seen_nexus(nexus); vhdl_scope *arch_scope = parent->get_arch()->get_scope(); nexus_private_t *priv = static_cast(ivl_nexus_get_private(nexus)); assert(priv); vhdl_expr *map_to = NULL; const string name(make_safe_name(to)); // We can only map ports to signals or constants if (visible_nexus(priv, arch_scope)) { vhdl_var_ref *ref = nexus_to_var_ref(parent->get_arch()->get_scope(), nexus); // If we're mapping an output of this entity to an output of // the child entity, then VHDL will not let us read the value // of the signal (i.e. it must pass straight through). // However, Verilog allows the signal to be read in the parent. // The solution used here is to create an intermediate signal // and connect it to both ports. vhdl_decl* from_decl = parent->get_arch()->get_scope()->get_decl(ref->get_name()); if (!from_decl->is_readable() && !arch_scope->have_declared(name + "_Readable")) { vhdl_decl* tmp_decl = new vhdl_signal_decl(name + "_Readable", ref->get_type()); // Add a comment to explain what this is for tmp_decl->set_comment("Needed to connect outputs"); arch_scope->add_decl(tmp_decl); parent->get_arch()->add_stmt (new vhdl_cassign_stmt(from_decl->make_ref(), tmp_decl->make_ref())); map_to = tmp_decl->make_ref(); } else map_to = ref; } else if (priv->const_driver && ivl_signal_port(to) == IVL_SIP_INPUT) { map_to = priv->const_driver; priv->const_driver = NULL; } else { // This nexus isn't attached to anything in the parent return; } inst->map_port(name, map_to); } /* * Find all the port mappings of a module instantiation. */ static void port_map(ivl_scope_t scope, vhdl_entity *parent, vhdl_comp_inst *inst) { // Find all the port mappings int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); ivl_signal_port_t mode = ivl_signal_port(sig); switch (mode) { case IVL_SIP_NONE: // Internal signals don't appear in the port map break; case IVL_SIP_INPUT: case IVL_SIP_OUTPUT: case IVL_SIP_INOUT: map_signal(sig, parent, inst); break; default: assert(false); } } } /* * Create a VHDL function from a Verilog function definition. */ static int draw_function(ivl_scope_t scope, ivl_scope_t parent) { assert(ivl_scope_type(scope) == IVL_SCT_FUNCTION); debug_msg("Generating function %s (%s)", ivl_scope_tname(scope), ivl_scope_name(scope)); // Find the containing entity vhdl_entity *ent = find_entity(parent); assert(ent); const char *funcname = ivl_scope_tname(scope); assert(!ent->get_arch()->get_scope()->have_declared(funcname)); // The return type is worked out from the output port vhdl_function *func = new vhdl_function(funcname, NULL); // Set the parent scope of this function to be the containing // architecture. This allows us to look up non-local variables // referenced in the body, but if we do the `impure' flag must // be set on the function // (There are actually two VHDL scopes in a function: the local // variables and the formal parameters hence the call to get_parent) func->get_scope()->get_parent()->set_parent(ent->get_arch()->get_scope()); // First we add the input/output parameters in order int nports = ivl_scope_ports(scope); for (int i = 0; i < nports; i++) { ivl_signal_t sig = ivl_scope_port(scope, i); vhdl_type *sigtype = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); string signame(make_safe_name(sig)); switch (ivl_signal_port(sig)) { case IVL_SIP_INPUT: func->add_param(new vhdl_param_decl(signame.c_str(), sigtype)); break; case IVL_SIP_OUTPUT: // The magic variable _Result holds the return value signame = funcname; signame += "_Result"; func->set_type(new vhdl_type(*sigtype)); func->get_scope()->add_decl (new vhdl_var_decl(signame, sigtype)); break; default: // Only expecting inputs and outputs assert(false); } remember_signal(sig, func->get_scope()); rename_signal(sig, signame); } int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); if (ivl_signal_port(sig) == IVL_SIP_NONE) { vhdl_type *sigtype = vhdl_type::type_for( ivl_signal_width(sig), ivl_signal_signed(sig) != 0); string signame(make_safe_name(sig)); func->get_scope()->add_decl( new vhdl_var_decl(signame, sigtype)); remember_signal(sig, func->get_scope()); rename_signal(sig, signame); } } // Non-blocking assignment not allowed in functions func->get_scope()->set_allow_signal_assignment(false); set_active_entity(ent); { draw_stmt(func, func->get_container(), ivl_scope_def(scope)); } set_active_entity(NULL); // Add a forward declaration too in case it is called by // another function that has already been added ent->get_arch()->get_scope()->add_forward_decl (new vhdl_forward_fdecl(func)); ostringstream ss; ss << "Generated from function " << funcname << " at " << ivl_scope_def_file(scope) << ":" << ivl_scope_def_lineno(scope); func->set_comment(ss.str().c_str()); ent->get_arch()->get_scope()->add_decl(func); return 0; } /* * Create the signals necessary to expand this task later. */ static int draw_task(ivl_scope_t scope, ivl_scope_t parent) { assert(ivl_scope_type(scope) == IVL_SCT_TASK); // Find the containing entity vhdl_entity *ent = find_entity(parent); assert(ent); const char *taskname = ivl_scope_tname(scope); int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); vhdl_type *sigtype = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig) != 0); string signame(make_safe_name(sig)); // Check this signal isn't declared in the outer scope if (ent->get_arch()->get_scope()->have_declared(signame)) { signame += "_"; signame += taskname; } vhdl_signal_decl *decl = new vhdl_signal_decl(signame, sigtype); ostringstream ss; ss << "Declared at " << ivl_signal_file(sig) << ":" << ivl_signal_lineno(sig) << " (in task " << taskname << ")"; decl->set_comment(ss.str().c_str()); ent->get_arch()->get_scope()->add_decl(decl); remember_signal(sig, ent->get_arch()->get_scope()); rename_signal(sig, signame); } return 0; } /* * Create an empty VHDL entity for a Verilog module. */ static void create_skeleton_entity_for(ivl_scope_t scope, int depth) { assert(ivl_scope_type(scope) == IVL_SCT_MODULE); // The type name will become the entity name const string tname = valid_entity_name(ivl_scope_tname(scope)); // Verilog does not have the entity/architecture distinction // so we always create a pair and associate the architecture // with the entity for convenience (this also means that we // retain a 1-to-1 mapping of scope to VHDL element) vhdl_arch *arch = new vhdl_arch(tname, "from_verilog"); vhdl_entity *ent = new vhdl_entity(tname, arch, depth); // Calculate the VHDL units to use for time values ent->set_time_units(ivl_scope_time_units(scope), ivl_scope_time_precision(scope)); // Build a comment to add to the entity/architecture ostringstream ss; ss << "Generated from Verilog module " << ivl_scope_tname(scope) << " (" << ivl_scope_def_file(scope) << ":" << ivl_scope_def_lineno(scope) << ")"; unsigned nparams = ivl_scope_params(scope); for (unsigned i = 0; i < nparams; i++) { ivl_parameter_t param = ivl_scope_param(scope, i); // Type parameter usages get replaced with their actual type if (ivl_parameter_is_type(param)) continue; ivl_expr_t value = ivl_parameter_expr(param); ss << "\n " << ivl_parameter_basename(param) << " = "; switch (ivl_expr_type(value)) { case IVL_EX_STRING: ss << "\"" << ivl_expr_string(value) << "\""; break; case IVL_EX_NUMBER: ss << ivl_expr_uvalue(value); break; case IVL_EX_REALNUM: ss << ivl_expr_dvalue(value); break; default: assert(false); } } arch->set_comment(ss.str()); ent->set_comment(ss.str()); remember_entity(ent, scope); } /* * A first pass through the hierarchy: create VHDL entities for * each unique Verilog module type. */ extern "C" int draw_skeleton_scope(ivl_scope_t scope, void *) { static int depth = 0; if (seen_this_scope_type(scope)) return 0; // Already generated a skeleton for this scope type debug_msg("Initial visit to scope type %s at depth %d", ivl_scope_tname(scope), depth); switch (ivl_scope_type(scope)) { case IVL_SCT_MODULE: create_skeleton_entity_for(scope, depth); break; case IVL_SCT_FORK: error("No translation for fork statements yet"); return 1; default: // The other scope types are expanded later on break; } ++depth; int rc = ivl_scope_children(scope, draw_skeleton_scope, NULL); --depth; return rc; } extern "C" int draw_all_signals(ivl_scope_t scope, void *) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); declare_signals(ent, scope); } else if (ivl_scope_type(scope) == IVL_SCT_GENERATE) { // Because generate scopes don't appear in the // output VHDL all their signals are added to the // containing entity (after being uniqued) ivl_scope_t parent = ivl_scope_parent(scope); while (ivl_scope_type(parent) == IVL_SCT_GENERATE) parent = ivl_scope_parent(scope); vhdl_entity* ent = find_entity(parent); assert(ent); declare_signals(ent, scope); } return ivl_scope_children(scope, draw_all_signals, scope); } /* * Draw all tasks and functions in the hierarchy. */ extern "C" int draw_functions(ivl_scope_t scope, void *_parent) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance ivl_scope_t parent = static_cast(_parent); if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) { if (draw_function(scope, parent) != 0) return 1; } else if (ivl_scope_type(scope) == IVL_SCT_TASK) { if (draw_task(scope, parent) != 0) return 1; } return ivl_scope_children(scope, draw_functions, scope); } /* * Make concurrent assignments for constants in nets. This works * bottom-up so that the driver is in the lowest instance it can. * This also has the side effect of generating all the necessary * nexus code. */ extern "C" int draw_constant_drivers(ivl_scope_t scope, void *) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance ivl_scope_children(scope, draw_constant_drivers, scope); if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); int nsigs = ivl_scope_sigs(scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); for (unsigned j = ivl_signal_array_base(sig); j < ivl_signal_array_count(sig); j++) { // Make sure the nexus code is generated ivl_nexus_t nex = ivl_signal_nex(sig, j); if (!nex) continue; // skip virtual pins seen_nexus(nex); nexus_private_t *priv = static_cast(ivl_nexus_get_private(nex)); assert(priv); vhdl_scope *arch_scope = ent->get_arch()->get_scope(); if (priv->const_driver && ivl_signal_port(sig) != IVL_SIP_INPUT) { // Don't drive inputs assert(j == 0); // TODO: Make work for more words vhdl_var_ref *ref = nexus_to_var_ref(arch_scope, nex); ent->get_arch()->add_stmt (new vhdl_cassign_stmt(ref, priv->const_driver)); priv->const_driver = NULL; } // Connect up any signals which are wired together in the // same nexus scope_nexus_t *sn = visible_nexus(priv, arch_scope); // Make sure we don't drive inputs if (ivl_signal_port(sn->sig) != IVL_SIP_INPUT) { for (list::const_iterator it = sn->connect.begin(); it != sn->connect.end(); ++it) { vhdl_type* rtype = vhdl_type::type_for(ivl_signal_width(sn->sig), ivl_signal_signed(sn->sig)); vhdl_type* ltype = vhdl_type::type_for(ivl_signal_width(*it), ivl_signal_signed(*it)); vhdl_var_ref *rref = new vhdl_var_ref(get_renamed_signal(sn->sig).c_str(), rtype); vhdl_var_ref *lref = new vhdl_var_ref(get_renamed_signal(*it).c_str(), ltype); // Make sure the LHS and RHS have the same type vhdl_expr* rhs = rref->cast(lref->get_type()); ent->get_arch()->add_stmt(new vhdl_cassign_stmt(lref, rhs)); } } sn->connect.clear(); } } } return 0; } extern "C" int draw_all_logic_and_lpm(ivl_scope_t scope, void *) { if (!is_default_scope_instance(scope)) return 0; // Not interested in this instance if (ivl_scope_type(scope) == IVL_SCT_MODULE) { vhdl_entity *ent = find_entity(scope); assert(ent); set_active_entity(ent); { declare_logic(ent->get_arch(), scope); declare_lpm(ent->get_arch(), scope); } set_active_entity(NULL); } return ivl_scope_children(scope, draw_all_logic_and_lpm, scope); } extern "C" int draw_hierarchy(ivl_scope_t scope, void *_parent) { if (ivl_scope_type(scope) == IVL_SCT_MODULE && _parent) { ivl_scope_t parent = static_cast(_parent); // Skip over any containing generate scopes while (ivl_scope_type(parent) == IVL_SCT_GENERATE) parent = ivl_scope_parent(parent); if (!is_default_scope_instance(parent)) return 0; // Not generating code for the parent instance so // don't generate for the child vhdl_entity *ent = find_entity(scope); assert(ent); vhdl_entity *parent_ent = find_entity(parent); assert(parent_ent); vhdl_arch *parent_arch = parent_ent->get_arch(); assert(parent_arch != NULL); // Create a forward declaration for it vhdl_scope *parent_scope = parent_arch->get_scope(); if (!parent_scope->have_declared(ent->get_name())) { vhdl_decl *comp_decl = vhdl_component_decl::component_decl_for(ent); parent_arch->get_scope()->add_decl(comp_decl); } // And an instantiation statement string inst_name = ivl_scope_basename(scope); inst_name += genvar_unique_suffix(ivl_scope_parent(scope)); if (inst_name == ent->get_name() || parent_scope->name_collides(inst_name) || find_entity(inst_name) != NULL || is_vhdl_reserved_word(inst_name)) { // Would produce an invalid instance name inst_name += "_inst"; } // Need to replace any [ and ] characters that result // from generate statements string::size_type loc = inst_name.find('[', 0); if (loc != string::npos) inst_name.erase(loc, 1); loc = inst_name.find(']', 0); if (loc != string::npos) inst_name.erase(loc, 1); // No leading or trailing underscores if (inst_name[0] == '_') inst_name = "inst" + inst_name; if (*inst_name.rbegin() == '_') inst_name += "inst"; // Can't have two consecutive underscores replace_consecutive_underscores(inst_name); // Make sure the name doesn't collide with anything we've // already declared avoid_name_collision(inst_name, parent_arch->get_scope()); vhdl_comp_inst *inst = new vhdl_comp_inst(inst_name.c_str(), ent->get_name().c_str()); port_map(scope, parent_ent, inst); ostringstream ss; ss << "Generated from instantiation at " << ivl_scope_file(scope) << ":" << ivl_scope_lineno(scope); inst->set_comment(ss.str().c_str()); parent_arch->add_stmt(inst); } return ivl_scope_children(scope, draw_hierarchy, scope); } int draw_scope(ivl_scope_t scope, void *_parent) { int rc = draw_skeleton_scope(scope, _parent); if (rc != 0) return rc; rc = draw_all_signals(scope, _parent); if (rc != 0) return rc; rc = draw_all_logic_and_lpm(scope, _parent); if (rc != 0) return rc; rc = draw_hierarchy(scope, _parent); if (rc != 0) return rc; rc = draw_functions(scope, _parent); if (rc != 0) return rc; rc = draw_constant_drivers(scope, _parent); if (rc != 0) return rc; return 0; } iverilog-12_0/tgt-vhdl/state.cc000066400000000000000000000230051435245347300165270ustar00rootroot00000000000000/* * Managing global state for the VHDL code generator. * * Copyright (C) 2009 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "state.hh" #include "vhdl_syntax.hh" #include "vhdl_target.h" #include #include #include #include #include #include using namespace std; /* * This file stores all the global state required during VHDL code * generation. At present we store the following: * * - A mapping from Verilog signals to the VHDL scope (entity, etc.) * where it is found, and the name of the corresponding VHDL signal. * This allows us to support renaming invalid Verilog signal names * to valid VHDL ones. * * - The set of all VHDL entities generated. * * - The currently active entity. "Active" here means that we are * currently generating code for a process inside the corresponding * scope. This is useful, for example, if a statement or expression * in a process needs to add are referencing something in the containing * architecture object. */ /* * Maps a signal to the scope it is defined within. Also * provides a mechanism for renaming signals -- i.e. when * an output has the same name as register: valid in Verilog * but not in VHDL, so two separate signals need to be * defined. */ struct signal_defn_t { std::string renamed; // The name of the VHDL signal vhdl_scope *scope; // The scope where it is defined }; // All entities to emit. // These are stored in a list rather than a set so the first // entity added will correspond to the first (top) Verilog module // encountered and hence it will appear first in the output file. static entity_list_t g_entities; // Store the mapping of ivl scope names to entity names typedef map scope_name_map_t; static scope_name_map_t g_scope_names; typedef std::map signal_defn_map_t; static signal_defn_map_t g_known_signals; static vhdl_entity *g_active_entity = NULL; // Set of scopes that are treated as the default examples of // that type. Any other scopes of the same type are ignored. typedef std::vector default_scopes_t; static default_scopes_t g_default_scopes; // True if signal `sig' has already been encountered by the code // generator. This means we have already assigned it to a VHDL code // object and possibly renamed it. bool seen_signal_before(ivl_signal_t sig) { return g_known_signals.find(sig) != g_known_signals.end(); } // Remember the association of signal to a VHDL code object (typically // an entity). void remember_signal(ivl_signal_t sig, vhdl_scope *scope) { assert(!seen_signal_before(sig)); signal_defn_t defn = { ivl_signal_basename(sig), scope }; g_known_signals[sig] = defn; } // Change the VHDL name of a Verilog signal. void rename_signal(ivl_signal_t sig, const std::string &renamed) { assert(seen_signal_before(sig)); g_known_signals[sig].renamed = renamed; } // Given a Verilog signal, return the VHDL code object where it should // be defined. Note that this can return a NULL pointer if `sig' hasn't // be encountered yet. vhdl_scope *find_scope_for_signal(ivl_signal_t sig) { if (seen_signal_before(sig)) return g_known_signals[sig].scope; else return NULL; } // Get the name of the VHDL signal corresponding to Verilog signal `sig'. const std::string &get_renamed_signal(ivl_signal_t sig) { assert(seen_signal_before(sig)); return g_known_signals[sig].renamed; } // TODO: Can we dispose of this??? // -> This is only used in logic.cc to get the type of a signal connected // to a logic device -> we should be able to get this from the nexus ivl_signal_t find_signal_named(const std::string &name, const vhdl_scope *scope) { signal_defn_map_t::const_iterator it; for (it = g_known_signals.begin(); it != g_known_signals.end(); ++it) { if (((*it).second.scope == scope || (*it).second.scope == scope->get_parent()) && (*it).second.renamed == name) return (*it).first; } assert(false); return NULL; } // Compare the name of an entity against a string struct cmp_ent_name { explicit cmp_ent_name(const string& n) : name_(n) {} bool operator()(const vhdl_entity* ent) const { return ent->get_name() == name_; } const string& name_; }; // Find an entity given its name. vhdl_entity* find_entity(const string& name) { entity_list_t::const_iterator it = find_if(g_entities.begin(), g_entities.end(), cmp_ent_name(name)); if (it != g_entities.end()) return *it; else return NULL; } // Find a VHDL entity given a Verilog module scope. The VHDL entity // name should be the same as the Verilog module type name. // Note that this will return NULL if no entity has been recorded // for this scope type. vhdl_entity* find_entity(ivl_scope_t scope) { // Skip over generate scopes while (ivl_scope_type(scope) == IVL_SCT_GENERATE) scope = ivl_scope_parent(scope); assert(ivl_scope_type(scope) == IVL_SCT_MODULE); if (is_default_scope_instance(scope)) { scope_name_map_t::iterator it = g_scope_names.find(scope); if (it != g_scope_names.end()) return find_entity((*it).second); else return NULL; } else { const char *tname = ivl_scope_tname(scope); for (scope_name_map_t::iterator it = g_scope_names.begin(); it != g_scope_names.end(); ++it) { if (strcmp(tname, ivl_scope_tname((*it).first)) == 0) return find_entity((*it).second); } return NULL; } } // Add an entity/architecture pair to the list of entities to emit. void remember_entity(vhdl_entity* ent, ivl_scope_t scope) { g_entities.push_back(ent); g_scope_names[scope] = ent->get_name(); } // Print all VHDL entities, in order, to the specified output stream. void emit_all_entities(std::ostream& os, int max_depth) { for (entity_list_t::iterator it = g_entities.begin(); it != g_entities.end(); ++it) { if ((max_depth == 0 || (*it)->depth < max_depth)) (*it)->emit(os); } } // Release all memory for the VHDL objects. No vhdl_element pointers // will be valid after this call. void free_all_vhdl_objects() { int freed = vhdl_element::free_all_objects(); debug_msg("Deallocated %d VHDL syntax objects", freed); size_t total = vhdl_element::total_allocated(); debug_msg("%d total bytes used for VHDL syntax objects", total); g_entities.clear(); } // Return the currently active entity vhdl_entity *get_active_entity() { return g_active_entity; } // Change the currently active entity void set_active_entity(vhdl_entity *ent) { g_active_entity = ent; } /* * True if two scopes have the same type name. */ static bool same_scope_type_name(ivl_scope_t a, ivl_scope_t b) { if (strcmp(ivl_scope_tname(a), ivl_scope_tname(b)) != 0) return false; unsigned nparams_a = ivl_scope_params(a); unsigned nparams_b = ivl_scope_params(b); if (nparams_a != nparams_b) return false; for (unsigned i = 0; i < nparams_a; i++) { ivl_parameter_t param_a = ivl_scope_param(a, i); ivl_parameter_t param_b = ivl_scope_param(b, i); if (strcmp(ivl_parameter_basename(param_a), ivl_parameter_basename(param_b)) != 0) return false; if (ivl_parameter_local(param_a) && ivl_parameter_local(param_b)) continue; // If this is a type parameter consider the scopes not equal since we do // not have support for comparing the actual types yet. if (ivl_parameter_is_type(param_a) || ivl_parameter_is_type(param_b)) return false; ivl_expr_t value_a = ivl_parameter_expr(param_a); ivl_expr_t value_b = ivl_parameter_expr(param_b); if (ivl_expr_type(value_a) != ivl_expr_type(value_b)) return false; switch (ivl_expr_type(value_a)) { case IVL_EX_STRING: if (strcmp(ivl_expr_string(value_a), ivl_expr_string(value_b)) != 0) return false; break; case IVL_EX_NUMBER: if (ivl_expr_uvalue(value_a) != ivl_expr_uvalue(value_b)) return false; break; default: assert(false); } } return true; } /* * True if we have already seen a scope with this type before. * If the result is `false' then s is stored in the set of seen * scopes. */ bool seen_this_scope_type(ivl_scope_t s) { for (auto cur = g_default_scopes.begin() ; cur != g_default_scopes.end() ; cur++) { if (same_scope_type_name(s, *cur)) return true; } g_default_scopes.push_back(s); return false; } /* * True if this scope is the default example of this scope type. * All other instances of this scope type are ignored. */ bool is_default_scope_instance(ivl_scope_t s) { return find(g_default_scopes.begin(), g_default_scopes.end(), s) != g_default_scopes.end(); } iverilog-12_0/tgt-vhdl/state.hh000066400000000000000000000036631435245347300165510ustar00rootroot00000000000000/* * Managing global state for the VHDL code generator. * * Copyright (C) 2009 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_VHDL_STATE_HH #define INC_VHDL_STATE_HH #include "ivl_target.h" #include #include class vhdl_scope; class vhdl_entity; // Mapping of Verilog to VHDL signals bool seen_signal_before(ivl_signal_t sig); void remember_signal(ivl_signal_t sig, vhdl_scope *scope); void rename_signal(ivl_signal_t sig, const std::string &renamed); vhdl_scope *find_scope_for_signal(ivl_signal_t sig); const std::string &get_renamed_signal(ivl_signal_t sig); ivl_signal_t find_signal_named(const std::string &name, const vhdl_scope *scope); // Manage the set of VHDL entities void remember_entity(vhdl_entity *ent, ivl_scope_t scope); vhdl_entity* find_entity(ivl_scope_t scope); vhdl_entity* find_entity(const std::string& name); void emit_all_entities(std::ostream& os, int max_depth); void free_all_vhdl_objects(); // Get and set the active entity vhdl_entity *get_active_entity(); void set_active_entity(vhdl_entity *ent); // Manage mapping of scopes to a single VHDL entity bool is_default_scope_instance(ivl_scope_t s); bool seen_this_scope_type(ivl_scope_t s); #endif // #ifndef INC_VHDL_STATE_HH iverilog-12_0/tgt-vhdl/stmt.cc000066400000000000000000001577571435245347300164240ustar00rootroot00000000000000/* * VHDL code generation for statements. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "state.hh" #include #include #include #include #include #include #include #include using namespace std; static void emit_wait_for_0(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, vhdl_expr *expr); /* * VHDL has no real equivalent of Verilog's $finish task. The * current solution is to use `assert false ...' to terminate * the simulator. This isn't great, as the simulator will * return a failure exit code when in fact it completed * successfully. * * An alternative is to use the VHPI interface supported by * some VHDL simulators and implement the $finish functionality * in C. This function can be enabled with the flag * -puse-vhpi-finish=1. */ static int draw_stask_finish(vhdl_procedural *, stmt_container *container, ivl_statement_t) { const char *use_vhpi = ivl_design_flag(get_vhdl_design(), "use-vhpi-finish"); if (strcmp(use_vhpi, "1") == 0) { //get_active_entity()->requires_package("work.Verilog_Support"); container->add_stmt(new vhdl_pcall_stmt("work.Verilog_Support.Finish")); } else { container->add_stmt( new vhdl_report_stmt(new vhdl_const_string("SIMULATION FINISHED"), SEVERITY_FAILURE)); } return 0; } static char parse_octal(const char *p) { assert(*p && *(p+1) && *(p+2)); assert(isdigit(*p) && isdigit(*(p+1)) && isdigit(*(p+2))); return (*p - '0') * 64 + (*(p+1) - '0') * 8 + (*(p+2) - '0') * 1; } // Generate VHDL report statements for Verilog $display/$write static int draw_stask_display(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { vhdl_binop_expr *text = new vhdl_binop_expr(VHDL_BINOP_CONCAT, vhdl_type::string()); const int count = ivl_stmt_parm_count(stmt); int i = 0; while (i < count) { // $display may have an empty parameter, in which case // the expression will be null // The behaviour here seems to be to output a space ivl_expr_t net = ivl_stmt_parm(stmt, i++); if (net == NULL) { text->add_expr(new vhdl_const_string(" ")); continue; } if (ivl_expr_type(net) == IVL_EX_STRING) { ostringstream ss; for (const char *p = ivl_expr_string(net); *p; p++) { if (*p == '\\') { // Octal escape char ch = parse_octal(p+1); if (ch == '\n') { // Is there a better way of handling newlines? // Maybe generate another report statement } else ss << ch; p += 3; } else if (*p == '%' && *(++p) != '%') { // Flush the output string up to this point text->add_expr(new vhdl_const_string(ss.str())); ss.str(""); // Skip over width for now while (isdigit(*p)) ++p; switch (*p) { case 'm': // TODO: we can get the module name via attributes cerr << "Warning: no VHDL translation for %m format code" << endl; break; default: { assert(i < count); ivl_expr_t netp = ivl_stmt_parm(stmt, i++); assert(netp); vhdl_expr *base = translate_expr(netp); if (NULL == base) return 1; emit_wait_for_0(proc, container, stmt, base); text->add_expr(base->cast(text->get_type())); } } } else ss << *p; } // Emit any non-empty string data left in the buffer if (!ss.str().empty()) text->add_expr(new vhdl_const_string(ss.str())); } else { vhdl_expr *base = translate_expr(net); if (NULL == base) return 1; emit_wait_for_0(proc, container, stmt, base); text->add_expr(base->cast(text->get_type())); } } if (count == 0) text->add_expr(new vhdl_const_string("")); container->add_stmt(new vhdl_report_stmt(text)); return 0; } /* * Generate VHDL for system tasks (like $display). Not all of * these are supported. */ static int draw_stask(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { const char *name = ivl_stmt_name(stmt); if (strcmp(name, "$display") == 0) return draw_stask_display(proc, container, stmt); else if (strcmp(name, "$write") == 0) return draw_stask_display(proc, container, stmt); else if (strcmp(name, "$finish") == 0) return draw_stask_finish(proc, container, stmt); else { vhdl_seq_stmt *result = new vhdl_null_stmt(); ostringstream ss; ss << "Unsupported system task " << name << " omitted here (" << ivl_stmt_file(stmt) << ":" << ivl_stmt_lineno(stmt) << ")"; result->set_comment(ss.str()); container->add_stmt(result); cerr << "Warning: no VHDL translation for system task " << name << endl; return 0; } } /* * Generate VHDL for a block of Verilog statements. If this block * doesn't have its own scope then this function does nothing, other * than recursively translate the block's statements and add them * to the process. This is OK as the stmt_container class behaves * like a Verilog block. * * If this block has its own scope with local variables then these * are added to the process as local variables and the statements * are generated as above. */ static int draw_block(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { ivl_scope_t block_scope = ivl_stmt_block_scope(stmt); if (block_scope) { int nsigs = ivl_scope_sigs(block_scope); for (int i = 0; i < nsigs; i++) { ivl_signal_t sig = ivl_scope_sig(block_scope, i); remember_signal(sig, proc->get_scope()); vhdl_type* type = vhdl_type::type_for(ivl_signal_width(sig), ivl_signal_signed(sig)); proc->get_scope()->add_decl (new vhdl_var_decl(make_safe_name(sig), type)); } } int count = ivl_stmt_block_count(stmt); for (int i = 0; i < count; i++) { ivl_statement_t stmt_i = ivl_stmt_block_stmt(stmt, i); if (draw_stmt(proc, container, stmt_i, is_last && i == count - 1) != 0) return 1; } return 0; } /* * A no-op statement. This corresponds to a `null' statement in VHDL. */ static int draw_noop(vhdl_procedural *, stmt_container *container, ivl_statement_t) { container->add_stmt(new vhdl_null_stmt()); return 0; } static vhdl_var_ref *make_assign_lhs(ivl_lval_t lval, vhdl_scope *scope) { ivl_signal_t sig = ivl_lval_sig(lval); if (!sig) { error("Only signals as lvals supported at the moment"); return NULL; } vhdl_expr *base = NULL; ivl_expr_t e_off = ivl_lval_part_off(lval); if (NULL == e_off) e_off = ivl_lval_idx(lval); if (e_off) { if ((base = translate_expr(e_off)) == NULL) return NULL; vhdl_type integer(VHDL_TYPE_INTEGER); base = base->cast(&integer); } unsigned lval_width = ivl_lval_width(lval); string signame(get_renamed_signal(sig)); vhdl_decl *decl = scope->get_decl(signame); assert(decl); // Verilog allows assignments to elements that are constant in VHDL: // function parameters, for example // To work around this we generate a local variable to shadow the // constant and assign to that if (decl->assignment_type() == vhdl_decl::ASSIGN_CONST) { const string shadow_name = signame + "_Shadow"; vhdl_var_decl* shadow_decl = new vhdl_var_decl(shadow_name, decl->get_type()); shadow_decl->set_initial (new vhdl_var_ref(signame, decl->get_type())); scope->add_decl(shadow_decl); // Make sure all future references to this signal use the // shadow variable rename_signal(sig, shadow_name); // ...and use this new variable as the assignment LHS decl = shadow_decl; } vhdl_type *ltype = new vhdl_type(*decl->get_type()); vhdl_var_ref *lval_ref = new vhdl_var_ref(decl->get_name(), ltype); if (base) { if (decl->get_type()->get_name() == VHDL_TYPE_ARRAY) lval_ref->set_slice(base, 0); else if (ivl_signal_width(sig) > 1) lval_ref->set_slice(base, lval_width - 1); } return lval_ref; } static bool assignment_lvals(ivl_statement_t stmt, vhdl_procedural *proc, list &lvals) { int nlvals = ivl_stmt_lvals(stmt); for (int i = 0; i < nlvals; i++) { ivl_lval_t lval = ivl_stmt_lval(stmt, i); vhdl_var_ref *lhs = make_assign_lhs(lval, proc->get_scope()); if (NULL == lhs) return false; lvals.push_back(lhs); } return true; } /* * Generate the right sort of assignment statement for assigning * `lhs' to `rhs'. */ static vhdl_abstract_assign_stmt * assign_for(vhdl_decl::assign_type_t atype, vhdl_var_ref *lhs, vhdl_expr *rhs) { switch (atype) { case vhdl_decl::ASSIGN_BLOCK: case vhdl_decl::ASSIGN_CONST: return new vhdl_assign_stmt(lhs, rhs); case vhdl_decl::ASSIGN_NONBLOCK: return new vhdl_nbassign_stmt(lhs, rhs); } assert(false); return NULL; } /* * Check that this assignment type is valid within the context of `proc'. * For example, a <= assignment is not valid within a function. */ bool check_valid_assignment(vhdl_decl::assign_type_t atype, vhdl_procedural *proc, ivl_statement_t stmt) { if (atype == vhdl_decl::ASSIGN_NONBLOCK && !proc->get_scope()->allow_signal_assignment()) { error("Unable to translate assignment at %s:%d\n" " Translating this would require generating a non-blocking (<=)\n" " assignment in a VHDL context where this is disallowed (e.g.\n" " a function).", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); return false; } else return true; } // Generate a "wait for 0 ns" statement to emulate the behaviour of // Verilog blocking assignment using VHDL signals. This is only generated // if we read from the target of a blocking assignment in the same // process (i.e. it is only generated when required, not for every // blocking assignment). An example: // // begin // x = 5; // if (x == 2) // y = 7; // end // // Becomes: // // x <= 5; // wait for 0 ns; -- Required to implement assignment semantics // if x = 2 then // y <= 7; -- No need for wait here, not read // end if; // static void emit_wait_for_0(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, vhdl_expr *expr) { vhdl_var_set_t read; expr->find_vars(read); bool need_wait_for_0 = false; for (vhdl_var_set_t::const_iterator it = read.begin(); it != read.end(); ++it) { if (proc->is_blocking_target(*it)) need_wait_for_0 = true; } stmt_container::stmt_list_t &stmts = container->get_stmts(); bool last_was_wait = !stmts.empty() && dynamic_cast(stmts.back()); if (need_wait_for_0 && !last_was_wait) { debug_msg("Generated wait-for-0 for %s:%d", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vhdl_seq_stmt *wait = new vhdl_wait_stmt(VHDL_WAIT_FOR0); ostringstream ss; ss << "Read target of blocking assignment (" << ivl_stmt_file(stmt) << ":" << ivl_stmt_lineno(stmt) << ")"; wait->set_comment(ss.str()); container->add_stmt(wait); proc->added_wait_stmt(); } } // Generate an assignment of type T for the Verilog statement stmt. // If a statement was generated then `assign_type' will contain the // type of assignment that was generated; this should be initialised // to some sensible default. void make_assignment(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool emul_blocking, vhdl_decl::assign_type_t& assign_type) { list lvals; if (!assignment_lvals(stmt, proc, lvals)) return; vhdl_expr *rhs, *rhs2 = NULL; ivl_expr_t rval = ivl_stmt_rval(stmt); if (ivl_expr_type(rval) == IVL_EX_TERNARY) { rhs = translate_expr(ivl_expr_oper2(rval)); rhs2 = translate_expr(ivl_expr_oper3(rval)); if (rhs2 == NULL) return; } else rhs = translate_expr(rval); if (rhs == NULL) return; emit_wait_for_0(proc, container, stmt, rhs); if (rhs2) emit_wait_for_0(proc, container, stmt, rhs2); if (lvals.size() == 1) { vhdl_var_ref *lhs = lvals.front(); rhs = rhs->cast(lhs->get_type()); ivl_expr_t i_delay; vhdl_expr *after = NULL; if ((i_delay = ivl_stmt_delay_expr(stmt)) != NULL) { after = translate_time_expr(i_delay); if (after == NULL) return; emit_wait_for_0(proc, container, stmt, after); } // Find the declaration of the LHS so we know what type // of assignment statement to generate (is it a signal, // a variable, etc?) vhdl_decl *decl = proc->get_scope()->get_decl(lhs->get_name()); assign_type = decl->assignment_type(); if (assign_type == vhdl_decl::ASSIGN_NONBLOCK && emul_blocking) proc->add_blocking_target(lhs); // A small optimisation is to expand ternary RHSs into an // if statement (eliminates a function call and produces // more idiomatic code) if (ivl_expr_type(rval) == IVL_EX_TERNARY) { rhs2 = rhs2->cast(lhs->get_type()); vhdl_var_ref *lhs2 = make_assign_lhs(ivl_stmt_lval(stmt, 0), proc->get_scope()); vhdl_expr *test = translate_expr(ivl_expr_oper1(rval)); if (NULL == test) return; emit_wait_for_0(proc, container, stmt, test); if (!check_valid_assignment(decl->assignment_type(), proc, stmt)) return; vhdl_if_stmt *vhdif = new vhdl_if_stmt(test); // True part { vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), lhs, rhs); if (after) a->set_after(after); vhdif->get_then_container()->add_stmt(a); } // False part { vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), lhs2, rhs2); if (after) a->set_after(translate_time_expr(i_delay)); vhdif->get_else_container()->add_stmt(a); } container->add_stmt(vhdif); return; } // Where possible, move constant assignments into the // declaration as initialisers. This optimisation is only // performed on assignments of constant values to prevent // ordering problems. // This also has another application: If this is an `initial' // process and we haven't yet generated a `wait' statement then // moving the assignment to the initialization preserves the // expected Verilog behaviour: VHDL does not distinguish // `initial' and `always' processes so an `always' process might // be activated before an `initial' process at time 0. The // `always' process may then use the uninitialised signal value. // The second test ensures that we only try to initialise // internal signals not ports ivl_lval_t lval = ivl_stmt_lval(stmt, 0); if (proc->get_scope()->initializing() && ivl_signal_port(ivl_lval_sig(lval)) == IVL_SIP_NONE && !decl->has_initial() && rhs->constant() && decl->get_type()->get_name() != VHDL_TYPE_ARRAY) { // If this assignment is not in the top-level container // it will not be made on all paths through the code // This precludes any future extraction of an initialiser if (container != proc->get_container()) decl->set_initial(NULL); // Default initial value else { decl->set_initial(rhs); proc->get_scope()->hoisted_initialiser(true); delete lhs; return; } } if (!check_valid_assignment(decl->assignment_type(), proc, stmt)) return; vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), lhs, rhs); container->add_stmt(a); a->set_after(after); } else { // Multiple lvals are implemented by first assigning the complete // RHS to a temporary, and then assigning each lval in turn as // bit-selects of the temporary static int tmp_count = 0; ostringstream ss; ss << "Verilog_Assign_Tmp_" << tmp_count++; vhdl_decl* tmp_decl = new vhdl_var_decl(ss.str(), rhs->get_type()); proc->get_scope()->add_decl(tmp_decl); container->add_stmt(new vhdl_assign_stmt(tmp_decl->make_ref(), rhs)); list::iterator it; int width_so_far = 0; for (it = lvals.begin(); it != lvals.end(); ++it) { vhdl_var_ref *tmp_rhs = tmp_decl->make_ref(); int lval_width = (*it)->get_type()->get_width(); vhdl_expr *slice_base = new vhdl_const_int(width_so_far); tmp_rhs->set_slice(slice_base, lval_width - 1); ivl_expr_t i_delay; vhdl_expr *after = NULL; if ((i_delay = ivl_stmt_delay_expr(stmt)) != NULL) { after = translate_time_expr(i_delay); if (after == NULL) return; emit_wait_for_0(proc, container, stmt, after); } // Find the declaration of the LHS so we know what type // of assignment statement to generate (is it a signal, // a variable, etc?) vhdl_decl *decl = proc->get_scope()->get_decl((*it)->get_name()); assign_type = decl->assignment_type(); if (!check_valid_assignment(decl->assignment_type(), proc, stmt)) return; vhdl_abstract_assign_stmt *a = assign_for(decl->assignment_type(), *it, tmp_rhs); if (after) a->set_after(after); container->add_stmt(a); width_so_far += lval_width; if (assign_type == vhdl_decl::ASSIGN_NONBLOCK && emul_blocking) proc->add_blocking_target(*it); } } } /* * A non-blocking assignment inside a process. The semantics for * this are essentially the same as VHDL's non-blocking signal * assignment. */ static int draw_nbassign(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { assert(proc->get_scope()->allow_signal_assignment()); vhdl_decl::assign_type_t ignored; make_assignment(proc, container, stmt, false, ignored); return 0; } static int draw_assign(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { vhdl_decl::assign_type_t assign_type = vhdl_decl::ASSIGN_NONBLOCK; bool emulate_blocking = proc->get_scope()->allow_signal_assignment(); make_assignment(proc, container, stmt, emulate_blocking, assign_type); return 0; } /* * Delay statements are equivalent to the `wait for' form of the * VHDL wait statement. */ static int draw_delay(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { // This currently ignores the time units and precision // of the enclosing scope // A neat way to do this would be to make these values // constants in the scope (type is Time), and have the // VHDL wait statement compute the value from that. // The other solution is to add them as parameters to // the vhdl_process class vhdl_expr *time; if (ivl_statement_type(stmt) == IVL_ST_DELAY) { uint64_t value = ivl_stmt_delay_val(stmt); time = scale_time(get_active_entity(), value); } else { time = translate_time_expr(ivl_stmt_delay_expr(stmt)); if (NULL == time) return 1; } ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); vhdl_wait_stmt *wait = new vhdl_wait_stmt(VHDL_WAIT_FOR, time); // Remember that we needed a wait statement so if this is // a process it cannot have a sensitivity list proc->added_wait_stmt(); container->add_stmt(wait); // Expand the sub-statement as well // Often this would result in a useless `null' statement which // is caught here instead if (ivl_statement_type(sub_stmt) != IVL_ST_NOOP) draw_stmt(proc, container, sub_stmt); // Any further assignments occur after simulation time 0 // so they cannot be used to initialise signal declarations // (if this scope is an initial process) proc->get_scope()->set_initializing(false); return 0; } /* * Build a set of all the nexuses referenced by signals in `expr'. */ static void get_nexuses_from_expr(ivl_expr_t expr, set &out) { switch (ivl_expr_type(expr)) { case IVL_EX_SIGNAL: out.insert(ivl_signal_nex(ivl_expr_signal(expr), 0)); break; case IVL_EX_TERNARY: get_nexuses_from_expr(ivl_expr_oper3(expr), out); // fallthrough case IVL_EX_BINARY: get_nexuses_from_expr(ivl_expr_oper2(expr), out); // fallthrough case IVL_EX_UNARY: get_nexuses_from_expr(ivl_expr_oper1(expr), out); break; default: break; } } /* * Attempt to identify common forms of wait statements and produce * more idiomatic VHDL than would be produced by the generic * draw_wait function. The main application of this is a input to * synthesis tools that don't synthesise the full VHDL language. * If none of these patterns are matched, the function returns false * and the default draw_wait is used. * * Current patterns: * always @(posedge A or posedge B) * if (A) * ... * else * ... * * This is assumed to be the template for a FF with asynchronous * reset. A is assumed to be the reset as it is dominant. This will * produce the following VHDL: * * process (A, B) is * begin * if A = '1' then * ... * else if rising_edge(B) then * ... * end if; * end process; */ static bool draw_synthesisable_wait(vhdl_process *proc, stmt_container *container, ivl_statement_t stmt) { // At the moment this only detects FFs with an asynchronous reset // All other code will fall back on the default draw_wait // Store a set of the edge triggered signals // The second item is true if this is positive-edge set edge_triggered; const int nevents = ivl_stmt_nevent(stmt); for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); if (ivl_event_nany(event) > 0) return false; int npos = ivl_event_npos(event); for (int j = 0; j < npos; j++) edge_triggered.insert(ivl_event_pos(event, j)); int nneg = ivl_event_nneg(event); for (int j = 0; j < nneg; j++) edge_triggered.insert(ivl_event_neg(event, j)); } // If we're edge-sensitive to less than two signals this doesn't // match the expected template, so use the default draw_wait if (edge_triggered.size() < 2) return false; // Now check to see if the immediately embedded statement is an `if' ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); if (ivl_statement_type(sub_stmt) != IVL_ST_CONDIT) return false; // The if should have two branches: one is the reset branch and // one is the clocked branch if (ivl_stmt_cond_false(sub_stmt) == NULL) return false; // Check the first branch of the if statement // If it matches exactly one of the edge-triggered signals then assume // this is the (dominant) reset branch set test_nexuses; get_nexuses_from_expr(ivl_stmt_cond_expr(sub_stmt), test_nexuses); // If the test is not a simple function of one variable then this // template will not work if (test_nexuses.size() != 1) return false; // Now subtracting this set from the set of edge triggered events // should leave just one nexus, which is hopefully the clock. // If not, then we fall back on the default draw_wait set clock_net; set_difference(edge_triggered.begin(), edge_triggered.end(), test_nexuses.begin(), test_nexuses.end(), inserter(clock_net, clock_net.begin())); if (clock_net.size() != 1) return false; // Build a VHDL `if' statement to model this vhdl_expr *reset_test = translate_expr(ivl_stmt_cond_expr(sub_stmt)); vhdl_if_stmt *body = new vhdl_if_stmt(reset_test); // Draw the reset branch draw_stmt(proc, body->get_then_container(), ivl_stmt_cond_true(sub_stmt)); // Build a test for the clock event vhdl_fcall *edge = NULL; ivl_nexus_t the_clock_net = *clock_net.begin(); for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); const unsigned npos = ivl_event_npos(event); for (unsigned j = 0; j < npos; j++) { if (ivl_event_pos(event, j) == the_clock_net) edge = new vhdl_fcall("rising_edge", vhdl_type::boolean()); } const unsigned nneg = ivl_event_nneg(event); for (unsigned j = 0; j < nneg; j++) if (ivl_event_neg(event, j) == the_clock_net) edge = new vhdl_fcall("falling_edge", vhdl_type::boolean()); } assert(edge); edge->add_expr(nexus_to_var_ref(proc->get_scope(), *clock_net.begin())); // Draw the clocked branch // For an asynchronous reset we just want this around the else branch, stmt_container *else_container = body->add_elsif(edge); draw_stmt(proc, else_container, ivl_stmt_cond_false(sub_stmt)); if (proc->contains_wait_stmt()) { // Expanding the body produced a `wait' statement which can't // be included in a sensitised process so undo all this work // and fall back on the default draw_wait delete body; return false; } else container->add_stmt(body); // Add all the edge triggered signals to the sensitivity list for (set::const_iterator it = edge_triggered.begin(); it != edge_triggered.end(); ++it) { // Get the signal that represents this nexus in this scope vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), *it); proc->add_sensitivity(ref->get_name()); // Don't need the reference any more delete ref; } // Don't bother with the default draw_wait return true; } /* * A wait statement waits for a level change on a @(..) list of * signals. The logic here might seem a little bit convoluted, * it attempts to always produce something that will simulate * correctly, and tries to produce something that will also * synthesise correctly (although not at the expense of simulation * accuracy). * * The difficulty stems from VHDL's restriction that a process with * a sensitivity list may not contain any `wait' statements: we need * to generate these to accurately model some Verilog statements. * * The steps followed are: * 1) Determine whether this is the top-level statement in the process * 2) If this is top-level, call draw_synthesisable_wait to see if the * process and wait statement match any templates for which we know * how to produce good, idiomatic synthesisable VHDL (e.g. FF with * async reset) * 3) Determine whether the process is combinatorial (purely level * sensitive), or sequential (edge sensitive) * 4) Draw all of the statements in the body * 5) One of the following will be true: * A) The process is combinatorial, top-level, and there are * no `wait' statements in the body: add all the level-sensitive * signals to the VHDL sensitivity list * B) The process is combinatorial, and there *are* `wait' * statements in the body or it is not top-level: generate * a VHDL `wait-on' statement at the end of the body containing * the level-sensitive signals * C) The process is sequential, top-level, and there are * no `wait' statements in the body: build an `if' statement * with the edge-detecting expression and wrap the process * in it. * D) The process is sequential, there *are* `wait' statements * in the body, or it is not top-level: generate a VHDL * `wait-until' with the edge-detecting expression and add * it before the body of the wait event. */ static int draw_wait(vhdl_procedural *_proc, stmt_container *container, ivl_statement_t stmt) { // Wait statements only occur in processes vhdl_process *proc = dynamic_cast(_proc); assert(proc); // Catch not process // If this container is the top-level statement (i.e. it is the // first thing inside a process) then we can extract these // events out into the sensitivity list as long as we haven't // promoted any preceding assignments to initialisers bool is_top_level = container == proc->get_container() && container->empty() && !proc->get_scope()->hoisted_initialiser(); // See if this can be implemented in a more idiomatic way before we // fall back on the generic translation if (is_top_level && draw_synthesisable_wait(proc, container, stmt)) return 0; int nevents = ivl_stmt_nevent(stmt); bool combinatorial = true; // True if no negedge/posedge events for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); if (ivl_event_npos(event) > 0 || ivl_event_nneg(event) > 0) combinatorial = false; } if (combinatorial) { // If the process has no wait statement in its body then // add all the events to the sensitivity list, otherwise // build a wait-on statement at the end of the process draw_stmt(proc, container, ivl_stmt_sub_stmt(stmt), true); vhdl_wait_stmt *wait = NULL; if (proc->contains_wait_stmt() || !is_top_level) wait = new vhdl_wait_stmt(VHDL_WAIT_ON); for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); int nany = ivl_event_nany(event); for (int j = 0; j < nany; j++) { ivl_nexus_t nexus = ivl_event_any(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); if (wait) wait->add_sensitivity(ref->get_name()); else proc->add_sensitivity(ref->get_name()); delete ref; } } if (wait) container->add_stmt(wait); } else { // Build a test expression to represent the edge event // If this process contains no `wait' statements and this // is the top-level container, then we // wrap it in an `if' statement with this test and add the // edge triggered signals to the sensitivity, otherwise // build a `wait until' statement at the top of the process vhdl_binop_expr *test = new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean()); stmt_container tmp_container; draw_stmt(proc, &tmp_container, ivl_stmt_sub_stmt(stmt), true); for (int i = 0; i < nevents; i++) { ivl_event_t event = ivl_stmt_events(stmt, i); int nany = ivl_event_nany(event); for (int j = 0; j < nany; j++) { ivl_nexus_t nexus = ivl_event_any(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); ref->set_name(ref->get_name() + "'Event"); test->add_expr(ref); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } int nneg = ivl_event_nneg(event); for (int j = 0; j < nneg; j++) { ivl_nexus_t nexus = ivl_event_neg(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); vhdl_fcall *detect = new vhdl_fcall("falling_edge", vhdl_type::boolean()); detect->add_expr(ref); test->add_expr(detect); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } int npos = ivl_event_npos(event); for (int j = 0; j < npos; j++) { ivl_nexus_t nexus = ivl_event_pos(event, j); vhdl_var_ref *ref = nexus_to_var_ref(proc->get_scope(), nexus); vhdl_fcall *detect = new vhdl_fcall("rising_edge", vhdl_type::boolean()); detect->add_expr(ref); test->add_expr(detect); if (!proc->contains_wait_stmt() && is_top_level) proc->add_sensitivity(ref->get_name()); } } if (proc->contains_wait_stmt() || !is_top_level) { container->add_stmt(new vhdl_wait_stmt(VHDL_WAIT_UNTIL, test)); container->move_stmts_from(&tmp_container); } else { // Wrap the whole process body in an `if' statement to detect // the edge event vhdl_if_stmt *edge_detect = new vhdl_if_stmt(test); // Move all the statements from the process body into the `if' // statement edge_detect->get_then_container()->move_stmts_from(&tmp_container); container->add_stmt(edge_detect); } } return 0; } static int draw_if(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { vhdl_expr *test = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == test) return 1; emit_wait_for_0(proc, container, stmt, test); vhdl_if_stmt *vhdif = new vhdl_if_stmt(test); container->add_stmt(vhdif); ivl_statement_t cond_true_stmt = ivl_stmt_cond_true(stmt); if (cond_true_stmt) draw_stmt(proc, vhdif->get_then_container(), cond_true_stmt, is_last); ivl_statement_t cond_false_stmt = ivl_stmt_cond_false(stmt); if (cond_false_stmt) draw_stmt(proc, vhdif->get_else_container(), cond_false_stmt, is_last); return 0; } static vhdl_var_ref *draw_case_test(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { vhdl_expr *test = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == test) return NULL; // VHDL case expressions are required to be quite simple: variable // references or slices. So we may need to create a temporary // variable to hold the result of the expression evaluation if (typeid(*test) != typeid(vhdl_var_ref)) { const char *tmp_name = "Verilog_Case_Ex"; vhdl_type *test_type = new vhdl_type(*test->get_type()); if (!proc->get_scope()->have_declared(tmp_name)) { proc->get_scope()->add_decl (new vhdl_var_decl(tmp_name, new vhdl_type(*test_type))); } vhdl_var_ref *tmp_ref = new vhdl_var_ref(tmp_name, NULL); container->add_stmt(new vhdl_assign_stmt(tmp_ref, test)); return new vhdl_var_ref(tmp_name, test_type); } else return dynamic_cast(test); } static int draw_case(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { vhdl_var_ref *test = draw_case_test(proc, container, stmt); if (NULL == test) return 1; vhdl_case_stmt *vhdlcase = new vhdl_case_stmt(test); container->add_stmt(vhdlcase); // VHDL is more strict than Verilog about covering every // possible case. So make sure we add an 'others' branch // if there isn't a default one. bool have_others = false; int nbranches = ivl_stmt_case_count(stmt); for (int i = 0; i < nbranches; i++) { vhdl_expr *when; ivl_expr_t net = ivl_stmt_case_expr(stmt, i); if (net) { when = translate_expr(net)->cast(test->get_type()); if (NULL == when) return 1; } else { when = new vhdl_var_ref("others", NULL); have_others = true; } vhdl_case_branch *branch = new vhdl_case_branch(when); vhdlcase->add_branch(branch); ivl_statement_t stmt_i = ivl_stmt_case_stmt(stmt, i); draw_stmt(proc, branch->get_container(), stmt_i, is_last); } if (!have_others) { vhdl_case_branch *others = new vhdl_case_branch(new vhdl_var_ref("others", NULL)); others->get_container()->add_stmt(new vhdl_null_stmt()); vhdlcase->add_branch(others); } return 0; } /* * Check to see if the given number (expression) can be represented * accurately in a long value. */ static bool number_is_long(ivl_expr_t expr) { ivl_expr_type_t type = ivl_expr_type(expr); assert(type == IVL_EX_NUMBER || type == IVL_EX_ULONG); // Make sure the ULONG can be represented correctly in a long. if (type == IVL_EX_ULONG) { unsigned long val = ivl_expr_uvalue(expr); if (val > static_cast(numeric_limits::max())) { return false; } return true; } // Check to see if the number actually fits in a long. unsigned nbits = ivl_expr_width(expr); if (nbits >= 8*sizeof(long)) { const char*bits = ivl_expr_bits(expr); char pad_bit = bits[nbits-1]; for (unsigned idx = 8*sizeof(long); idx < nbits; idx++) { if (bits[idx] != pad_bit) return false; } } return true; } /* * Return the given number (expression) as a signed long value. * * Make sure to call number_is_long() first to verify that the number * can be represented accurately in a long value. */ static long get_number_as_long(ivl_expr_t expr) { long imm = 0; switch (ivl_expr_type(expr)) { case IVL_EX_ULONG: imm = ivl_expr_uvalue(expr); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(expr); unsigned nbits = ivl_expr_width(expr); if (nbits > 8*sizeof(long)) nbits = 8*sizeof(long); for (unsigned idx = 0; idx < nbits; idx++) { switch (bits[idx]) { case '0': break; case '1': imm |= 1L << idx; break; default: assert(0); } if (ivl_expr_signed(expr) && bits[nbits-1] == '1' && nbits < 8*sizeof(long)) imm |= -1UL << nbits; } break; } default: assert(0); } return imm; } /* * Build a check against a constant 'x'. This is for an out of range * or undefined select. */ static void check_against_x(vhdl_binop_expr *all, vhdl_var_ref *test, ivl_expr_t expr, unsigned width, unsigned base, bool is_casez) { if (is_casez) { // For a casez we need to check against 'x'. for (unsigned i = 0; i < ivl_expr_width(expr); i++) { vhdl_binop_expr *sub_expr = new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean()); vhdl_type *type; vhdl_var_ref *ref; // Check if the test bit is 'z'. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); vhdl_binop_expr *cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('z')); sub_expr->add_expr(cmp); // Compare the test bit against a constant 'x'. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('x')); sub_expr->add_expr(cmp); all->add_expr(sub_expr); } } else { // For a casex 'x' is a don't care, so just put 'true'. all->add_expr(new vhdl_const_bool(true)); } } /* * Build the test signal to constant bits check. */ static void process_number(vhdl_binop_expr *all, vhdl_var_ref *test, ivl_expr_t expr, unsigned width, unsigned base, bool is_casez) { const char *bits = ivl_expr_bits(expr); bool just_dont_care = true; for (unsigned i = 0; i < ivl_expr_width(expr); i++) { switch (bits[i]) { case 'x': if (is_casez) break; // fallthrough case '?': case 'z': continue; // Ignore these. } vhdl_binop_expr *sub_expr = new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean()); vhdl_type *type; vhdl_var_ref *ref; // Check if the test bit is 'z'. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); vhdl_binop_expr *cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('z')); sub_expr->add_expr(cmp); // If this is a casex statement check if the test bit is 'x'. if (!is_casez) { type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('x')); sub_expr->add_expr(cmp); } // Compare the bit against the constant value. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit(bits[i])); sub_expr->add_expr(cmp); all->add_expr(sub_expr); just_dont_care = false; } // If there are no bits comparisons then just put a True if (just_dont_care) { all->add_expr(new vhdl_const_bool(true)); } } /* * Build the test signal to label signal check. */ static bool process_signal(vhdl_binop_expr *all, vhdl_var_ref *test, ivl_expr_t expr, unsigned width, unsigned base, bool is_casez, unsigned swid, long sbase) { // If the word or dimensions are not zero then we have an array. if (ivl_expr_oper1(expr) != 0 || ivl_signal_dimensions(ivl_expr_signal(expr)) != 0) { error("Sorry, array selects are not currently allowed in this " "context."); return true; } unsigned ewid = ivl_expr_width(expr); if (sizeof(unsigned) >= sizeof(long)) { // Since we will be casting i (constrained by swid) to a long make sure // it will fit into a long. This is actually off by one, but this is the // best we can do since on 32 bit machines an unsigned and long are the // same size. assert(swid <= static_cast(numeric_limits::max())); // We are also going to cast ewid to long so check it as well. assert(ewid <= static_cast(numeric_limits::max())); } for (unsigned i = 0; i < swid; i++) { // Generate a comparison for this bit position vhdl_binop_expr *cmp; vhdl_type *type; vhdl_var_ref *ref; // Check if this is an out of bounds access. If this is a casez // then check against a constant 'x' for the out of bound bits // otherwise skip the check (casex). if (static_cast(i) + sbase >= static_cast(ewid) || static_cast(i) + sbase < 0) { if (is_casez) { // Get the current test bit. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); // Compare the bit against 'x'. cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('x')); all->add_expr(cmp); continue; } else { // The compiler replaces a completely out of range select // with a constant so we know there will be at least one // valid bit here. We don't need a just_dont_care test. continue; } } vhdl_binop_expr *sub_expr = new vhdl_binop_expr(VHDL_BINOP_OR, vhdl_type::boolean()); vhdl_var_ref *bit; // Get the current expression bit. // Why can we reuse the expression bit, but not the condition bit? type = vhdl_type::nunsigned(ivl_expr_width(expr)); bit = new vhdl_var_ref(ivl_expr_name(expr), type); bit->set_slice(new vhdl_const_int(i+sbase)); // Check if the expression bit is 'z'. cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(bit); cmp->add_expr(new vhdl_const_bit('z')); sub_expr->add_expr(cmp); // If this is a casex statement check if the expression bit is 'x'. if (!is_casez) { cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(bit); cmp->add_expr(new vhdl_const_bit('x')); sub_expr->add_expr(cmp); } // Check if the test bit is 'z'. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('z')); sub_expr->add_expr(cmp); // If this is a casex statement check if the test bit is 'x'. if (!is_casez) { type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(new vhdl_const_bit('x')); sub_expr->add_expr(cmp); } // Next check if the test and expression bits are equal. type = vhdl_type::nunsigned(width); ref = new vhdl_var_ref(test->get_name().c_str(), type); ref->set_slice(new vhdl_const_int(i+base)); cmp = new vhdl_binop_expr(VHDL_BINOP_EQ, vhdl_type::boolean()); cmp->add_expr(ref); cmp->add_expr(bit); sub_expr->add_expr(cmp); all->add_expr(sub_expr); } return false; } /* * These are the constructs that we allow in a casex/z label * expression. Returns true on failure. */ static bool process_expr_bits(vhdl_binop_expr *all, vhdl_var_ref *test, ivl_expr_t expr, unsigned width, unsigned base, bool is_casez) { assert(ivl_expr_width(expr)+base <= width); switch (ivl_expr_type(expr)) { case IVL_EX_CONCAT: // Loop repeat number of times processing each sub element. for (unsigned repeat = 0; repeat < ivl_expr_repeat(expr); repeat++) { unsigned nparms = ivl_expr_parms(expr) - 1; for (unsigned parm = 0; parm <= nparms; parm++) { ivl_expr_t pexpr = ivl_expr_parm(expr, nparms-parm); if (process_expr_bits(all, test, pexpr, width, base, is_casez)) return true; base += ivl_expr_width(pexpr); } } break; case IVL_EX_NUMBER: process_number(all, test, expr, width, base, is_casez); break; case IVL_EX_SIGNAL: if (process_signal(all, test, expr, width, base, is_casez, ivl_expr_width(expr), 0)) return true; break; case IVL_EX_SELECT: { ivl_expr_t bexpr = ivl_expr_oper2(expr); if (ivl_expr_type(bexpr) != IVL_EX_NUMBER && ivl_expr_type(bexpr) != IVL_EX_ULONG) { error("Sorry, only constant bit/part selects are currently allowed " "in this context."); return true; } // If the number is out of bounds or an 'x' then check against 'x'. if (!number_is_long(bexpr)) { check_against_x(all, test, expr, width, base, is_casez); } else if (process_signal(all, test, ivl_expr_oper1(expr), width, base, is_casez, ivl_expr_width(expr), get_number_as_long(bexpr))) return true; break; } default: error("Sorry, expression type %d is not currently supported.", ivl_expr_type(expr)); return true; break; } return false; } /* * A casex/z statement cannot be directly translated to a VHDL case * statement as VHDL does not treat the don't-care bit as special. * The solution here is to generate an if statement from the casex/z * which compares only the non-don't-care bit positions. */ int draw_casezx(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { vhdl_var_ref *test = draw_case_test(proc, container, stmt); if (NULL == test) return 1; vhdl_if_stmt *result = NULL; int nbranches = ivl_stmt_case_count(stmt); bool is_casez = ivl_statement_type(stmt) == IVL_ST_CASEZ; for (int i = 0; i < nbranches; i++) { stmt_container *where = NULL; ivl_expr_t net = ivl_stmt_case_expr(stmt, i); if (net) { vhdl_binop_expr *all = new vhdl_binop_expr(VHDL_BINOP_AND, vhdl_type::boolean()); // The net must be something we can generate a comparison for. if (process_expr_bits(all, test, net, ivl_expr_width(net), 0, is_casez)) { error("%s:%d: Sorry, only case%s statements with simple " "expression labels can be translated to VHDL", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), (is_casez ? "z" : "x")); delete all; return 1; } if (result) where = result->add_elsif(all); else { result = new vhdl_if_stmt(all); where = result->get_then_container(); } } else { // This the default case and therefore the `else' branch assert(result); where = result->get_else_container(); } // `where' now points to a branch of an if statement which // corresponds to this casex/z branch assert(where); draw_stmt(proc, where, ivl_stmt_case_stmt(stmt, i), is_last); } // Add a comment to say that this corresponds to a casex/z statement // as this may not be obvious ostringstream ss; ss << "Generated from case" << (is_casez ? 'z' : 'x') << " statement at " << ivl_stmt_file(stmt) << ":" << ivl_stmt_lineno(stmt); result->set_comment(ss.str()); container->add_stmt(result); // We don't actually use the generated `test' expression delete test; return 0; } int draw_while(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { // Generate the body inside a temporary container before // generating the test // The reason for this is that some of the signals in the // test might be renamed while expanding the body (e.g. if // we need to generate an assignment to a constant signal) stmt_container tmp_container; int rc = draw_stmt(proc, &tmp_container, ivl_stmt_sub_stmt(stmt)); if (rc != 0) return 1; vhdl_expr *test = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == test) return 1; // The test must be a Boolean (and std_logic and (un)signed types // must be explicitly cast unlike in Verilog) vhdl_type boolean(VHDL_TYPE_BOOLEAN); test = test->cast(&boolean); emit_wait_for_0(proc, container, stmt, test); vhdl_while_stmt *loop = new vhdl_while_stmt(test); draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); emit_wait_for_0(proc, loop->get_container(), stmt, test); container->add_stmt(loop); return 0; } int draw_forever(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { vhdl_loop_stmt *loop = new vhdl_loop_stmt; container->add_stmt(loop); draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); return 0; } int draw_repeat(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { vhdl_expr *times = translate_expr(ivl_stmt_cond_expr(stmt)); if (NULL == times) return 1; vhdl_type integer(VHDL_TYPE_INTEGER); times = times->cast(&integer); const char *it_name = "Verilog_Repeat"; vhdl_for_stmt *loop = new vhdl_for_stmt(it_name, new vhdl_const_int(1), times); container->add_stmt(loop); draw_stmt(proc, loop->get_container(), ivl_stmt_sub_stmt(stmt)); return 0; } /* * Tasks are difficult to translate to VHDL since they allow things * not allowed by VHDL's corresponding procedures (e.g. updating * global variables. The solution here is to expand tasks in-line. */ int draw_utask(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt) { ivl_scope_t tscope = ivl_stmt_call(stmt); // TODO: adding some comments to the output would be helpful // TODO: this completely ignores parameters! draw_stmt(proc, container, ivl_scope_def(tscope), false); return 0; } /* * Generate VHDL statements for the given Verilog statement and * add them to the given VHDL process. The container is the * location to add statements: e.g. the process body, a branch * of an if statement, etc. * * The flag is_last should be set if this is the final statement * in a block or process. It avoids generating useless `wait for 0ns' * statements if the next statement would be a wait anyway. */ int draw_stmt(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last) { assert(stmt); switch (ivl_statement_type(stmt)) { case IVL_ST_STASK: return draw_stask(proc, container, stmt); case IVL_ST_BLOCK: return draw_block(proc, container, stmt, is_last); case IVL_ST_NOOP: return draw_noop(proc, container, stmt); case IVL_ST_ASSIGN: return draw_assign(proc, container, stmt); case IVL_ST_ASSIGN_NB: return draw_nbassign(proc, container, stmt); case IVL_ST_DELAY: case IVL_ST_DELAYX: return draw_delay(proc, container, stmt); case IVL_ST_WAIT: return draw_wait(proc, container, stmt); case IVL_ST_CONDIT: return draw_if(proc, container, stmt, is_last); case IVL_ST_CASE: return draw_case(proc, container, stmt, is_last); case IVL_ST_WHILE: return draw_while(proc, container, stmt); case IVL_ST_FOREVER: return draw_forever(proc, container, stmt); case IVL_ST_REPEAT: return draw_repeat(proc, container, stmt); case IVL_ST_UTASK: return draw_utask(proc, container, stmt); case IVL_ST_FORCE: case IVL_ST_RELEASE: error("force/release statements cannot be translated to VHDL"); return 1; case IVL_ST_DISABLE: error("disable statement cannot be translated to VHDL"); return 1; case IVL_ST_CASEX: case IVL_ST_CASEZ: return draw_casezx(proc, container, stmt, is_last); case IVL_ST_FORK: error("fork statement cannot be translated to VHDL"); return 1; case IVL_ST_CASSIGN: case IVL_ST_DEASSIGN: error("continuous procedural assignment cannot be translated to VHDL"); return 1; default: error("No VHDL translation for statement at %s:%d (type = %d)", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), ivl_statement_type(stmt)); return 1; } } iverilog-12_0/tgt-vhdl/support.cc000066400000000000000000000137111435245347300171260ustar00rootroot00000000000000/* * Support functions for VHDL output. * * Copyright (C) 2008-2009 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_target.h" #include "support.hh" #include "state.hh" #include #include void require_support_function(support_function_t f) { vhdl_scope *scope = get_active_entity()->get_arch()->get_scope(); if (!scope->have_declared(support_function::function_name(f))) scope->add_decl(new support_function(f)); } const char *support_function::function_name(support_function_t type) { switch (type) { case SF_UNSIGNED_TO_BOOLEAN: return "Unsigned_To_Boolean"; case SF_SIGNED_TO_BOOLEAN: return "Signed_To_Boolean"; case SF_BOOLEAN_TO_LOGIC: return "Boolean_To_Logic"; case SF_REDUCE_OR: return "Reduce_OR"; case SF_REDUCE_AND: return "Reduce_AND"; case SF_REDUCE_XOR: return "Reduce_XOR"; case SF_REDUCE_XNOR: return "Reduce_XNOR"; case SF_TERNARY_LOGIC: return "Ternary_Logic"; case SF_TERNARY_UNSIGNED: return "Ternary_Unsigned"; case SF_TERNARY_SIGNED: return "Ternary_Signed"; case SF_LOGIC_TO_INTEGER: return "Logic_To_Integer"; case SF_SIGNED_TO_LOGIC: return "Signed_To_Logic"; case SF_UNSIGNED_TO_LOGIC: return "Unsigned_To_Logic"; default: assert(false); } return "Invalid"; } vhdl_type *support_function::function_type(support_function_t type) { switch (type) { case SF_UNSIGNED_TO_BOOLEAN: case SF_SIGNED_TO_BOOLEAN: return vhdl_type::boolean(); case SF_BOOLEAN_TO_LOGIC: case SF_REDUCE_OR: case SF_REDUCE_AND: case SF_REDUCE_XOR: case SF_REDUCE_XNOR: case SF_TERNARY_LOGIC: case SF_SIGNED_TO_LOGIC: case SF_UNSIGNED_TO_LOGIC: return vhdl_type::std_logic(); case SF_TERNARY_SIGNED: return new vhdl_type(VHDL_TYPE_SIGNED); case SF_TERNARY_UNSIGNED: return new vhdl_type(VHDL_TYPE_UNSIGNED); case SF_LOGIC_TO_INTEGER: return vhdl_type::integer(); } assert(false); return vhdl_type::boolean(); } void support_function::emit_ternary(std::ostream &of, int level) const { of << nl_string(level) << "begin" << nl_string(indent(level)) << "if T then return X; else return Y; end if;"; } void support_function::emit_reduction(std::ostream &of, int level, const char *op, char unit) const { // Emit a VHDL function emulating a Verilog reduction operator // Where op is the corresponding VHDL operator and unit is the // right-unit of the operator of << "(X : std_logic_vector) return std_logic is" << nl_string(indent(level)) << "variable R : std_logic := '" << unit << "';" << nl_string(level) << "begin" << nl_string(indent(level)) << "for I in X'Range loop" << nl_string(indent(indent(level))) << "R := X(I) " << op << " R;" << nl_string(indent(level)) << "end loop;" << nl_string(indent(level)) << "return R;"; } void support_function::emit(std::ostream &of, int level) const { of << nl_string(level) << "function " << function_name(type_); switch (type_) { case SF_UNSIGNED_TO_BOOLEAN: of << "(X : unsigned) return Boolean is" << nl_string(level) << "begin" << nl_string(indent(level)) << "return X /= To_Unsigned(0, X'Length);"; break; case SF_SIGNED_TO_BOOLEAN: of << "(X : signed) return Boolean is" << nl_string(level) << "begin" << nl_string(indent(level)) << "return X /= To_Signed(0, X'Length);"; break; case SF_BOOLEAN_TO_LOGIC: of << "(B : Boolean) return std_logic is" << nl_string(level) << "begin" << nl_string(indent(level)) << "if B then" << nl_string(indent(indent(level))) << "return '1';" << nl_string(indent(level)) << "else" << nl_string(indent(indent(level))) << "return '0';" << nl_string(indent(level)) << "end if;"; break; case SF_UNSIGNED_TO_LOGIC: of << "(X : unsigned) return std_logic is" << nl_string(level) << "begin" << nl_string(indent(level)) << "return X(0);"; break; case SF_SIGNED_TO_LOGIC: of << "(X : signed) return std_logic is" << nl_string(level) << "begin" << nl_string(indent(level)) << "return X(0);"; break; case SF_REDUCE_OR: emit_reduction(of, level, "or", '0'); break; case SF_REDUCE_AND: emit_reduction(of, level, "and", '1'); break; case SF_REDUCE_XOR: emit_reduction(of, level, "xor", '0'); break; case SF_REDUCE_XNOR: emit_reduction(of, level, "xnor", '0'); break; case SF_TERNARY_LOGIC: of << "(T : Boolean; X, Y : std_logic) return std_logic is"; emit_ternary(of, level); break; case SF_TERNARY_SIGNED: of << "(T : Boolean; X, Y : signed) return signed is"; emit_ternary(of, level); break; case SF_TERNARY_UNSIGNED: of << "(T : Boolean; X, Y : unsigned) return unsigned is"; emit_ternary(of, level); break; case SF_LOGIC_TO_INTEGER: of << "(X : std_logic) return integer is" << nl_string(level) << "begin" << nl_string(indent(level)) << "if X = '1' then return 1; else return 0; end if;"; break; default: assert(false); } of << nl_string(level) << "end function;"; } iverilog-12_0/tgt-vhdl/support.hh000066400000000000000000000034361435245347300171430ustar00rootroot00000000000000/* * Support functions for VHDL output. * * Copyright (C) 2008-2010 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_SUPPORT_HH #define INC_SUPPORT_HH #include "vhdl_syntax.hh" enum support_function_t { SF_UNSIGNED_TO_BOOLEAN = 0, SF_SIGNED_TO_BOOLEAN, SF_BOOLEAN_TO_LOGIC, SF_REDUCE_OR, SF_REDUCE_AND, SF_REDUCE_XOR, SF_REDUCE_XNOR, SF_TERNARY_LOGIC, SF_TERNARY_UNSIGNED, SF_TERNARY_SIGNED, SF_LOGIC_TO_INTEGER, SF_SIGNED_TO_LOGIC, SF_UNSIGNED_TO_LOGIC }; class support_function : public vhdl_function { public: explicit support_function(support_function_t type) : vhdl_function(function_name(type), function_type(type)), type_(type) {} void emit(std::ostream &of, int level) const; static const char *function_name(support_function_t type); static vhdl_type *function_type(support_function_t type); private: void emit_ternary(std::ostream &of, int level) const; void emit_reduction(std::ostream &of, int level, const char *op, char unit) const; support_function_t type_; }; #endif iverilog-12_0/tgt-vhdl/vhdl-s.conf000066400000000000000000000001471435245347300171460ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle -t:dll flag:DLL=vhdl.tgt iverilog-12_0/tgt-vhdl/vhdl.cc000066400000000000000000000102451435245347300163460ustar00rootroot00000000000000/* * VHDL code generator for Icarus Verilog. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "version_base.h" #include "version_tag.h" #include "vhdl_target.h" #include "state.hh" #include #include #include #include #include #include #include using namespace std; static const char*version_string = "Icarus Verilog VHDL Code Generator " VERSION " (" VERSION_TAG ")\n\n" "Copyright (C) 2008-2020 Nick Gasson (nick@nickg.me.uk)\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; static int g_errors = 0; // Total number of errors encountered static ivl_design_t g_design; /* * Called when an unrecoverable problem is encountered. */ void error(const char *fmt, ...) { std::va_list args; va_start(args, fmt); std::printf("VHDL conversion error: "); // Source/line number? std::vprintf(fmt, args); std::putchar('\n'); va_end(args); g_errors++; } /* * Print a message only if -pdebug was specified. */ void debug_msg(const char *fmt, ...) { std::va_list args; va_start(args, fmt); if (std::strcmp(ivl_design_flag(g_design, "debug"), "")) { std::fputs("[DEBUG] ", stdout); std::vprintf(fmt, args); std::putchar('\n'); } va_end(args); } ivl_design_t get_vhdl_design() { return g_design; } extern "C" int target_design(ivl_design_t des) { ivl_scope_t *roots; unsigned int nroots; ivl_design_roots(des, &roots, &nroots); g_design = des; for (unsigned int i = 0; i < nroots; i++) draw_scope(roots[i], NULL); // Only generate processes if there were no errors generating entities // (otherwise the necessary information won't be present) if (0 == g_errors) ivl_design_process(des, draw_process, NULL); // Write the generated elements to the output file // only if there were no errors generating entities or processes if (0 == g_errors) { const char *ofname = ivl_design_flag(des, "-o"); ofstream outfile(ofname); outfile << "-- This VHDL was converted from Verilog using the" << endl << "-- Icarus Verilog VHDL Code Generator " VERSION " (" VERSION_TAG ")" << endl << endl; // If the user passed -pdepth=N then only emit entities with // depth < N // I.e. -pdepth=1 emits only the top-level entity // If max_depth is zero then all entities will be emitted // (This is handy since it means we can use atoi ;-) int max_depth = std::atoi(ivl_design_flag(des, "depth")); emit_all_entities(outfile, max_depth); } // Clean up free_all_vhdl_objects(); return g_errors; } extern "C" const char* target_query(const char*key) { if (strcmp(key, "version") == 0) return version_string; return 0; } iverilog-12_0/tgt-vhdl/vhdl.conf000066400000000000000000000001261435245347300167030ustar00rootroot00000000000000functor:cprop functor:nodangle flag:DLL=vhdl.tgt flag:DISABLE_CONCATZ_GENERATION=true iverilog-12_0/tgt-vhdl/vhdl_config.h.in000066400000000000000000000022701435245347300201410ustar00rootroot00000000000000/* vhdl_config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS iverilog-12_0/tgt-vhdl/vhdl_element.cc000066400000000000000000000114321435245347300200560ustar00rootroot00000000000000/* * VHDL abstract syntax elements. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_element.hh" #include #include #include #include #include #include using namespace std; static const int VHDL_INDENT = 2; // Spaces to indent int indent(int level) { return level + VHDL_INDENT; } std::string nl_string(int level) { std::ostringstream ss; newline(ss, level); return ss.str(); } /* * Emit a newline and indent to the correct level. */ void newline(std::ostream &of, int level) { of << std::endl; while (level--) of << ' '; } void blank_line(std::ostream &of, int level) { of << std::endl; newline(of, level); } // The array of all vhdl_elements allocated so we can quickly // clean them up just before the code generator exits vector vhdl_element::allocated_; // Just a counter of total bytes allocated for statistics size_t vhdl_element::total_alloc_(0); void vhdl_element::set_comment(const std::string&comment) { comment_ = comment; } /* * Draw the comment for any element. The comment is either on * a line before the element (end_of_line is false) or at the * end of the line containing the element (end_of_line is true). */ void vhdl_element::emit_comment(std::ostream &of, int level, bool end_of_line) const { if (! comment_.empty()) { if (end_of_line) of << " -- " << comment_; else { // Comment may contain embedded newlines of << "-- "; for (string::const_iterator it = comment_.begin(); it != comment_.end(); ++it) { if (*it == '\n') { newline(of, level); of << "-- "; } else of << *it; } newline(of, level); } } } void vhdl_element::print() const { emit(std::cout, 0); std::cout << std::endl; } // Trap allocations of vhdl_element subclasses. // This records the pointer allocated in a static field of vhdl_element // so we can delete it just before the code generator exits. void* vhdl_element::operator new(size_t size) { // Let the default new handle the allocation void* ptr = ::operator new(size); // Remember this element so we can delete it later vhdl_element* elem = static_cast(ptr); allocated_.push_back(elem); total_alloc_ += size; return ptr; } // Explicitly delete a vhdl_element object. // This just sets the corresponding pointer in vhdl_element::allocated_ // to NULL (since it's safe to delete a NULL pointer). void vhdl_element::operator delete(void* ptr) { // Let the default delete handle the deallocation ::operator delete(ptr); // Remember that we've already deleted this pointer so we don't // delete it again in the call to free_all_objects vector::iterator it = find(allocated_.begin(), allocated_.end(), static_cast(ptr)); if (it != allocated_.end()) { *it = NULL; // It's safe to delete a NULL pointer and much cheaper // than removing an element from the middle of a vector } else { // This shouldn't really happen but it's harmless cerr << "??? vhdl_element::operator delete called on an object not " << "allocated by vhdl_element::operator new" << endl; } } // Return the total number of bytes our custom operator new has seen. size_t vhdl_element::total_allocated() { return total_alloc_; } // Free every object derived from vhdl_element that has not yet been // explicitly deallocated. // Any pointers to vhdl_elements will be invalid after this call! // Returns the number of objects freed. int vhdl_element::free_all_objects() { for (vector::iterator it = allocated_.begin(); it != allocated_.end(); ++it) { if (*it) ::operator delete(*it); // Explicitly use the default delete } int freed = allocated_.size(); // Just in case we want to allocated any more vhdl_element objects allocated_.clear(); return freed; } iverilog-12_0/tgt-vhdl/vhdl_element.hh000066400000000000000000000047751435245347300201040ustar00rootroot00000000000000/* * VHDL abstract syntax elements. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_VHDL_ELEMENT_HH #define INC_VHDL_ELEMENT_HH #include #include #include #include #include typedef std::list string_list_t; // Any VHDL syntax element. Each element can also contain a comment. // // Memory management is handled specially for vhdl_element subclasses: // The vast majority of vhdl_elements will be created during code generation // and persist until after they have been printed, at which point *all* // vhdl_element objects should be destroyed. To support this all allocations // of vhdl_element subclasses call a special operator new which records // the pointer allocated so we can ensure that it is disposed of when // the code generator completes -- by free_all_objects. // // The two big advantages of this are that we don't have to worry about // memory leaks of vhdl_element objects, and we can freely share pointers // between different parts of the AST. class vhdl_element { public: virtual ~vhdl_element() {} void* operator new(size_t size); void operator delete(void* ptr); virtual void emit(std::ostream &of, int level=0) const = 0; void print() const; void set_comment(const std::string&comment); static int free_all_objects(); static size_t total_allocated(); protected: void emit_comment(std::ostream &of, int level, bool end_of_line=false) const; private: std::string comment_; static std::vector allocated_; static size_t total_alloc_; }; typedef std::list element_list_t; int indent(int level); void newline(std::ostream &of, int level); std::string nl_string(int level); void blank_line(std::ostream &of, int level); #endif iverilog-12_0/tgt-vhdl/vhdl_helper.hh000066400000000000000000000035441435245347300177230ustar00rootroot00000000000000/* * Helper functions for VHDL syntax elements. * * Copyright (C) 2008-2012 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_VHDL_HELPER_HH #define INC_VHDL_HELPER_HH #include #include #include template void emit_children(std::ostream &of, const std::list &children, int level, const char *delim = "", bool trailing_newline = true) { // Don't indent if there are no children if (children.empty()) newline(of, level); else { typename std::list::const_iterator it; int sz = children.size(); for (it = children.begin(); it != children.end(); ++it) { newline(of, indent(level)); (*it)->emit(of, indent(level)); if (--sz > 0) of << delim; } if (trailing_newline) newline(of, level); } } static inline char vl_to_vhdl_bit(char bit) { switch (bit) { case '0': case 'Z': case '1': return bit; case 'z': return 'Z'; case 'x': case 'X': return 'U'; case '?': return '-'; } assert(false); return 0; } #endif iverilog-12_0/tgt-vhdl/vhdl_syntax.cc000066400000000000000000000632771435245347300177710ustar00rootroot00000000000000/* * VHDL abstract syntax elements. * * Copyright (C) 2008-2013 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_syntax.hh" #include "vhdl_helper.hh" #include #include #include #include #include #include using namespace std; vhdl_scope::vhdl_scope() : parent_(NULL), init_(false), sig_assign_(true), hoisted_init_(false) { } vhdl_scope::~vhdl_scope() { } void vhdl_scope::set_initializing(bool i) { init_ = i; if (parent_) parent_->set_initializing(i); } void vhdl_scope::add_decl(vhdl_decl *decl) { decls_.push_back(decl); } void vhdl_scope::add_forward_decl(vhdl_decl *decl) { decls_.push_front(decl); } vhdl_decl *vhdl_scope::get_decl(const std::string &name) const { decl_list_t::const_iterator it; for (it = decls_.begin(); it != decls_.end(); ++it) { if (strcasecmp((*it)->get_name().c_str(), name.c_str()) == 0) return *it; } return parent_ ? parent_->get_decl(name) : NULL; } bool vhdl_scope::have_declared(const std::string &name) const { return get_decl(name) != NULL; } // True if `name' differs in all but case from another declaration bool vhdl_scope::name_collides(const string& name) const { const vhdl_decl* decl = get_decl(name); if (decl) return strcasecmp(decl->get_name().c_str(), name.c_str()) == 0; else return false; } bool vhdl_scope::contained_within(const vhdl_scope *other) const { if (this == other) return true; else if (NULL == parent_) return false; else return parent_->contained_within(other); } vhdl_scope *vhdl_scope::get_parent() const { assert(parent_); return parent_; } bool vhdl_scope::hoisted_initialiser() const { return hoisted_init_; } void vhdl_scope::hoisted_initialiser(bool h) { hoisted_init_ = h; } vhdl_entity::vhdl_entity(const string& name, vhdl_arch *arch, int depth__) : depth(depth__), name_(name), arch_(arch), time_unit_(TIME_UNIT_NS) { arch->get_scope()->set_parent(&ports_); } vhdl_entity::~vhdl_entity() { } void vhdl_entity::add_port(vhdl_port_decl *decl) { ports_.add_decl(decl); } void vhdl_entity::emit(std::ostream &of, int level) const { // Pretty much every design will use std_logic so we // might as well include it by default of << "library ieee;" << std::endl; of << "use ieee.std_logic_1164.all;" << std::endl; of << "use ieee.numeric_std.all;" << std::endl; of << std::endl; emit_comment(of, level); of << "entity " << name_ << " is"; if (!ports_.empty()) { newline(of, indent(level)); of << "port ("; emit_children(of, ports_.get_decls(), indent(level), ";"); of << ");"; } newline(of, level); of << "end entity; "; blank_line(of, level); // Extra blank line after entities arch_->emit(of, level); } // Return a VHDL time constant scaled to the correct time scale // for this entity vhdl_const_time* scale_time(const vhdl_entity* ent, uint64_t t) { return new vhdl_const_time(t, ent->time_unit_); } // Work out the best VHDL units to use given the Verilog timescale void vhdl_entity::set_time_units(int units, int precision) { int vhdl_units = std::min(units, precision); if (vhdl_units >= -3) time_unit_ = TIME_UNIT_MS; else if (vhdl_units >= -6) time_unit_ = TIME_UNIT_US; else if (vhdl_units >= -9) time_unit_ = TIME_UNIT_NS; else time_unit_ = TIME_UNIT_PS; } vhdl_arch::~vhdl_arch() { } void vhdl_arch::add_stmt(vhdl_process *proc) { proc->get_scope()->set_parent(&scope_); stmts_.push_back(proc); } void vhdl_arch::add_stmt(vhdl_conc_stmt *stmt) { stmts_.push_back(stmt); } void vhdl_arch::emit(std::ostream &of, int level) const { emit_comment(of, level); of << "architecture " << name_ << " of " << entity_; of << " is"; emit_children(of, scope_.get_decls(), level); of << "begin"; emit_children(of, stmts_, level); of << "end architecture;"; blank_line(of, level); // Extra blank line after architectures; } void vhdl_procedural::add_blocking_target(vhdl_var_ref* ref) { blocking_targets_.insert(ref->get_name()); } bool vhdl_procedural::is_blocking_target(vhdl_var_ref* ref) const { return blocking_targets_.find(ref->get_name()) != blocking_targets_.end(); } void vhdl_process::add_sensitivity(const std::string &name) { sens_.push_back(name); } void vhdl_process::emit(std::ostream &of, int level) const { // If there are no statements in the body, this process // can't possibly do anything, so don't bother to emit it if (stmts_.empty()) { of << "-- Removed one empty process"; newline(of, level); return; } newline(of, level); emit_comment(of, level); if (! name_.empty()) of << name_ << ": "; of << "process "; int num_sens = sens_.size(); if (num_sens > 0) { of << "("; string_list_t::const_iterator it; for (it = sens_.begin(); it != sens_.end(); ++it) { of << *it; if (--num_sens > 0) of << ", "; } of << ") "; } of << "is"; emit_children(of, scope_.get_decls(), level); of << "begin"; stmts_.emit(of, level); of << "end process;"; } stmt_container::~stmt_container() { } void stmt_container::add_stmt(vhdl_seq_stmt *stmt) { // Add a statement at the end of the block stmts_.push_back(stmt); } /* * Move all the statements from one container into another. * This is useful, for example, if we want to wrap a container * in an `if' statement. */ void stmt_container::move_stmts_from(stmt_container *other) { copy(other->stmts_.begin(), other->stmts_.end(), back_inserter(stmts_)); other->stmts_.clear(); } void stmt_container::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { // Iterate over each sub-statement and find all its // read/written variables for (stmt_list_t::const_iterator it = stmts_.begin(); it != stmts_.end(); ++it) (*it)->find_vars(read, write); } void stmt_container::emit(std::ostream &of, int level, bool newline) const { emit_children(of, stmts_, level, "", newline); } vhdl_comp_inst::vhdl_comp_inst(const char *inst_name, const char *comp_name) : comp_name_(comp_name), inst_name_(inst_name) { } vhdl_comp_inst::~vhdl_comp_inst() { } void vhdl_comp_inst::map_port(const string& name, vhdl_expr *expr) { port_map_t pmap = { name, expr }; mapping_.push_back(pmap); } void vhdl_comp_inst::emit(std::ostream &of, int level) const { newline(of, level); emit_comment(of, level); of << inst_name_ << ": " << comp_name_; // If there are no ports or generics we don't need to mention them... if (! mapping_.empty()) { newline(of, indent(level)); of << "port map ("; int sz = mapping_.size(); port_map_list_t::const_iterator it; for (it = mapping_.begin(); it != mapping_.end(); ++it) { newline(of, indent(indent(level))); of << (*it).name << " => "; (*it).expr->emit(of, level); if (--sz > 0) of << ","; } newline(of, indent(level)); of << ")"; } of << ";"; } vhdl_component_decl::vhdl_component_decl(const char *name) : vhdl_decl(name) { } /* * Create a component declaration for the given entity. */ vhdl_component_decl *vhdl_component_decl::component_decl_for(vhdl_entity *ent) { assert(ent != NULL); vhdl_component_decl *decl = new vhdl_component_decl (ent->get_name().c_str()); decl->ports_ = ent->get_scope()->get_decls(); return decl; } void vhdl_component_decl::emit(std::ostream &of, int level) const { newline(of, level); emit_comment(of, level); of << "component " << name_ << " is"; if (! ports_.empty()) { newline(of, indent(level)); of << "port ("; emit_children(of, ports_, indent(level), ";"); of << ");"; } newline(of, level); of << "end component;"; } vhdl_wait_stmt::~vhdl_wait_stmt() { } void vhdl_wait_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t&) { if (expr_) expr_->find_vars(read); } void vhdl_wait_stmt::emit(std::ostream &of, int level) const { of << "wait"; switch (type_) { case VHDL_WAIT_INDEF: break; case VHDL_WAIT_FOR: assert(expr_); of << " for "; expr_->emit(of, level); break; case VHDL_WAIT_FOR0: of << " for 0 ns"; break; case VHDL_WAIT_UNTIL: assert(expr_); of << " until "; expr_->emit(of, level); break; case VHDL_WAIT_ON: { of << " on "; string_list_t::const_iterator it = sensitivity_.begin(); while (it != sensitivity_.end()) { of << *it; if (++it != sensitivity_.end()) of << ", "; } } break; } of << ";"; emit_comment(of, level, true); } vhdl_decl::~vhdl_decl() { } // Make a reference object to this declaration vhdl_var_ref* vhdl_decl::make_ref() const { return new vhdl_var_ref(name_, type_); } const vhdl_type *vhdl_decl::get_type() const { assert(type_); return type_; } void vhdl_decl::set_initial(vhdl_expr *initial) { if (!has_initial_) { assert(initial_ == NULL); initial_ = initial; has_initial_ = true; } } void vhdl_port_decl::emit(std::ostream &of, int level) const { of << name_ << " : "; switch (mode_) { case VHDL_PORT_IN: of << "in "; break; case VHDL_PORT_OUT: of << "out "; break; case VHDL_PORT_INOUT: of << "inout "; break; case VHDL_PORT_BUFFER: of << "buffer "; break; } type_->emit(of, level); } // If this is an `out' port make it a `buffer' so we can read from it void vhdl_port_decl::ensure_readable() { if (mode_ == VHDL_PORT_OUT) mode_ = VHDL_PORT_BUFFER; } // A port is readable if it is not `out'. // We also make `buffer' ports not readable for these purposes since // buffers cannot be directly mapped to outputs without an intermediate // signal. bool vhdl_port_decl::is_readable() const { return mode_ != VHDL_PORT_OUT && mode_ != VHDL_PORT_BUFFER; } void vhdl_var_decl::emit(std::ostream &of, int level) const { of << "variable " << name_ << " : "; type_->emit(of, level); if (initial_) { of << " := "; initial_->emit(of, level); } of << ";"; emit_comment(of, level, true); } void vhdl_signal_decl::emit(std::ostream &of, int level) const { of << "signal " << name_ << " : "; type_->emit(of, level); if (initial_) { of << " := "; initial_->emit(of, level); } of << ";"; emit_comment(of, level, true); } void vhdl_type_decl::emit(std::ostream &of, int level) const { of << "type " << name_ << " is "; of << type_->get_type_decl_string() << ";"; emit_comment(of, level, true); } vhdl_expr::~vhdl_expr() { } void vhdl_expr_list::add_expr(vhdl_expr *e) { exprs_.push_back(e); } vhdl_expr_list::~vhdl_expr_list() { } void vhdl_expr_list::find_vars(vhdl_var_set_t& read) { for (list::const_iterator it = exprs_.begin(); it != exprs_.end(); ++it) (*it)->find_vars(read); } void vhdl_expr_list::emit(std::ostream &of, int level) const { of << "("; int size = exprs_.size(); std::list::const_iterator it; for (it = exprs_.begin(); it != exprs_.end(); ++it) { (*it)->emit(of, level); if (--size > 0) of << ", "; } of << ")"; } void vhdl_pcall_stmt::emit(std::ostream &of, int level) const { of << name_; if (!exprs_.empty()) exprs_.emit(of, level); of << ";"; } void vhdl_pcall_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t&) { exprs_.find_vars(read); } vhdl_var_ref::~vhdl_var_ref() { } void vhdl_var_ref::set_slice(vhdl_expr *s, int w) { assert(type_); slice_ = s; slice_width_ = w; vhdl_type_name_t tname = type_->get_name(); if (tname == VHDL_TYPE_ARRAY) { type_ = type_->get_base(); } else { assert(tname == VHDL_TYPE_UNSIGNED || tname == VHDL_TYPE_SIGNED); if (w > 0) type_ = new vhdl_type(tname, w); else type_ = vhdl_type::std_logic(); } } void vhdl_var_ref::find_vars(vhdl_var_set_t& read) { read.insert(this); } void vhdl_var_ref::emit(std::ostream &of, int level) const { of << name_; if (slice_) { of << "("; if (slice_width_ > 0) { slice_->emit(of, level); of << " + " << slice_width_ << " downto "; } slice_->emit(of, level); of << ")"; } } void vhdl_const_string::emit(std::ostream &of, int) const { of << "\"" << value_ << "\""; } void vhdl_null_stmt::emit(std::ostream &of, int level) const { of << "null;"; emit_comment(of, level, true); } void vhdl_fcall::find_vars(vhdl_var_set_t& read) { exprs_.find_vars(read); } void vhdl_fcall::emit(std::ostream &of, int level) const { of << name_; exprs_.emit(of, level); } vhdl_abstract_assign_stmt::~vhdl_abstract_assign_stmt() { } void vhdl_abstract_assign_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { lhs_->find_vars(write); rhs_->find_vars(read); } void vhdl_nbassign_stmt::emit(std::ostream &of, int level) const { lhs_->emit(of, level); of << " <= "; rhs_->emit(of, level); if (after_) { of << " after "; after_->emit(of, level); } of << ";"; } void vhdl_assign_stmt::emit(std::ostream &of, int level) const { lhs_->emit(of, level); of << " := "; rhs_->emit(of, level); of << ";"; } vhdl_const_bits::vhdl_const_bits(const char *value, int width, bool issigned, bool qualify) : vhdl_expr(issigned ? vhdl_type::nsigned(width) : vhdl_type::nunsigned(width), true), qualified_(qualify), signed_(issigned) { // Can't rely on value being NULL-terminated while (width--) value_.push_back(*value++); } // True if char is not '1' or '0' static bool is_meta_bit(char c) { return c != '1' && c != '0'; } // True if the bit strings contains characters other than '1' and '0' bool vhdl_const_bits::has_meta_bits() const { return find_if(value_.begin(), value_.end(), is_meta_bit) != value_.end(); } void vhdl_const_bits::emit(std::ostream &of, int) const { if (qualified_) of << (signed_ ? "signed" : "unsigned") << "'("; // If it's a width we can write in hex, prefer that over binary size_t bits = value_.size(); int64_t ival = bits_to_int(); if ((!signed_ || ival >= 0) && !has_meta_bits() && bits <= 64 && bits % 4 == 0) { of << "X\"" << hex << setfill('0') << setw(bits / 4) << ival; } else { of << "\""; std::string::const_reverse_iterator it; for (it = value_.rbegin(); it != value_.rend(); ++it) of << vl_to_vhdl_bit(*it); } of << (qualified_ ? "\")" : "\""); } void vhdl_const_bit::emit(std::ostream &of, int) const { of << "'" << vl_to_vhdl_bit(bit_) << "'"; } void vhdl_const_int::emit(std::ostream &of, int) const { of << dec << value_; // We need to find a way to display a comment, since $time, etc. add one. } void vhdl_const_bool::emit(std::ostream &of, int) const { of << (value_ ? "True" : "False"); } void vhdl_const_time::emit(std::ostream &of, int) const { of << dec << value_; switch (units_) { case TIME_UNIT_PS: of << " ps"; break; case TIME_UNIT_NS: of << " ns"; break; case TIME_UNIT_US: of << " us"; break; case TIME_UNIT_MS: of << " ms"; break; } } vhdl_cassign_stmt::~vhdl_cassign_stmt() { } void vhdl_cassign_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond) { when_part_t when = { value, cond, NULL }; whens_.push_back(when); } void vhdl_cassign_stmt::emit(std::ostream &of, int level) const { lhs_->emit(of, level); of << " <= "; if (!whens_.empty()) { for (std::list::const_iterator it = whens_.begin(); it != whens_.end(); ++it) { (*it).value->emit(of, level); of << " when "; (*it).cond->emit(of, level); of << " "; } of << "else "; } rhs_->emit(of, level); if (after_) { of << " after "; after_->emit(of, level); } of << ";"; } vhdl_report_stmt::vhdl_report_stmt(vhdl_expr *text, vhdl_severity_t severity) : severity_(severity), text_(text) { } void vhdl_report_stmt::emit(ostream& of, int level) const { of << "report "; text_->emit(of, level); if (severity_ != SEVERITY_NOTE) { const char *levels[] = { "note", "warning", "error", "failure" }; of << " severity " << levels[severity_]; } of << ";"; } void vhdl_report_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t&) { text_->find_vars(read); } vhdl_assert_stmt::vhdl_assert_stmt(const char *reason) : vhdl_report_stmt(new vhdl_const_string(reason), SEVERITY_FAILURE) { } void vhdl_assert_stmt::emit(std::ostream &of, int level) const { of << "assert false "; // TODO: Allow arbitrary expression vhdl_report_stmt::emit(of, level); } vhdl_if_stmt::vhdl_if_stmt(vhdl_expr *test) { // Need to ensure that the expression is Boolean vhdl_type boolean(VHDL_TYPE_BOOLEAN); test_ = test->cast(&boolean); } vhdl_if_stmt::~vhdl_if_stmt() { } stmt_container *vhdl_if_stmt::add_elsif(vhdl_expr *test) { elsif ef = { test, new stmt_container }; elsif_parts_.push_back(ef); return ef.container; } void vhdl_if_stmt::emit(std::ostream &of, int level) const { emit_comment(of, level); of << "if "; test_->emit(of, level); of << " then"; then_part_.emit(of, level); std::list::const_iterator it; for (it = elsif_parts_.begin(); it != elsif_parts_.end(); ++it) { of << "elsif "; (*it).test->emit(of, level); of << " then"; (*it).container->emit(of, level); } if (!else_part_.empty()) { of << "else"; else_part_.emit(of, level); } of << "end if;"; } void vhdl_if_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { test_->find_vars(read); then_part_.find_vars(read, write); else_part_.find_vars(read, write); for (list::const_iterator it = elsif_parts_.begin(); it != elsif_parts_.end(); ++it) { (*it).test->find_vars(read); (*it).container->find_vars(read, write); } } int vhdl_expr::paren_levels(0); void vhdl_expr::open_parens(std::ostream& of) { if (paren_levels++ > 0) of << "("; } void vhdl_expr::close_parens(std::ostream& of) { assert(paren_levels > 0); if (--paren_levels > 0) of << ")"; } vhdl_unaryop_expr::~vhdl_unaryop_expr() { } void vhdl_unaryop_expr::find_vars(vhdl_var_set_t& read) { operand_->find_vars(read); } void vhdl_unaryop_expr::emit(std::ostream &of, int level) const { open_parens(of); switch (op_) { case VHDL_UNARYOP_NOT: of << "not "; break; case VHDL_UNARYOP_NEG: of << "-"; break; } operand_->emit(of, level); close_parens(of); } vhdl_binop_expr::vhdl_binop_expr(vhdl_expr *left, vhdl_binop_t op, vhdl_expr *right, const vhdl_type *type) : vhdl_expr(type), op_(op) { add_expr(left); add_expr(right); } vhdl_binop_expr::~vhdl_binop_expr() { } void vhdl_binop_expr::add_expr(vhdl_expr *e) { operands_.push_back(e); } void vhdl_binop_expr::add_expr_front(vhdl_expr *e) { operands_.push_front(e); } void vhdl_binop_expr::find_vars(vhdl_var_set_t& read) { for (list::const_iterator it = operands_.begin(); it != operands_.end(); ++it) (*it)->find_vars(read); } void vhdl_binop_expr::emit(std::ostream &of, int level) const { open_parens(of); assert(! operands_.empty()); std::list::const_iterator it = operands_.begin(); (*it)->emit(of, level); while (++it != operands_.end()) { const char* ops[] = { "and", "or", "=", "/=", "+", "-", "*", "<", ">", "<=", ">=", "sll", "srl", "xor", "&", "nand", "nor", "xnor", "/", "mod", "**", "sra", NULL }; of << " " << ops[op_] << " "; (*it)->emit(of, level); } close_parens(of); } vhdl_bit_spec_expr::~vhdl_bit_spec_expr() { } void vhdl_bit_spec_expr::add_bit(int bit, vhdl_expr *e) { bit_map bm = { bit, e }; bits_.push_back(bm); } void vhdl_bit_spec_expr::emit(std::ostream &of, int level) const { of << "("; std::list::const_iterator it; it = bits_.begin(); while (it != bits_.end()) { of << (*it).bit << " => "; (*it).e->emit(of, level); if (++it != bits_.end()) of << ", "; } if (others_) { of << (bits_.empty() ? "" : ", ") << "others => "; others_->emit(of, level); } of << ")"; } vhdl_case_branch::~vhdl_case_branch() { } void vhdl_case_branch::emit(std::ostream &of, int level) const { of << "when "; when_->emit(of, level); of << " =>"; stmts_.emit(of, indent(level), false); } vhdl_case_stmt::~vhdl_case_stmt() { } void vhdl_case_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { test_->find_vars(read); for (case_branch_list_t::const_iterator it = branches_.begin(); it != branches_.end(); ++it) { (*it)->when_->find_vars(read); (*it)->stmts_.find_vars(read, write); } } void vhdl_case_stmt::emit(std::ostream &of, int level) const { of << "case "; test_->emit(of, level); of << " is"; newline(of, indent(level)); case_branch_list_t::const_iterator it; int n = branches_.size(); for (it = branches_.begin(); it != branches_.end(); ++it) { (*it)->emit(of, level); if (--n > 0) newline(of, indent(level)); else newline(of, level); } of << "end case;"; } vhdl_while_stmt::~vhdl_while_stmt() { } void vhdl_while_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { test_->find_vars(read); vhdl_loop_stmt::find_vars(read, write); } void vhdl_while_stmt::emit(std::ostream &of, int level) const { of << "while "; test_->emit(of, level); of << " "; vhdl_loop_stmt::emit(of, level); } void vhdl_loop_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { stmts_.find_vars(read, write); } void vhdl_loop_stmt::emit(std::ostream &of, int level) const { of << "loop"; stmts_.emit(of, level); of << "end loop;"; } vhdl_for_stmt::~vhdl_for_stmt() { } void vhdl_for_stmt::find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) { from_->find_vars(read); to_->find_vars(write); vhdl_loop_stmt::find_vars(read, write); } void vhdl_for_stmt::emit(std::ostream &of, int level) const { of << "for " << lname_ << " in "; from_->emit(of, level); of << " to "; to_->emit(of, level); of << " "; vhdl_loop_stmt::emit(of, level); } vhdl_function::vhdl_function(const char *name, vhdl_type *ret_type) : vhdl_decl(name, ret_type) { // A function contains two scopes: // scope_ = The parameters // variables_ = Local variables // A call to get_scope returns variables_ whose parent is scope_ variables_.set_parent(&scope_); } void vhdl_function::emit(std::ostream &of, int level) const { newline(of, level); emit_comment(of, level); of << "function " << name_ << " ("; emit_children(of, scope_.get_decls(), level, ";"); of << ") "; newline(of, level); of << "return " << type_->get_string() << " is"; emit_children(of, variables_.get_decls(), level); of << "begin"; stmts_.emit(of, level); of << " return " << name_ << "_Result;"; newline(of, level); of << "end function;"; } void vhdl_forward_fdecl::emit(std::ostream &of, int level) const { of << "function " << f_->get_name() << " ("; emit_children(of, f_->scope_.get_decls(), level, ";"); of << ") "; newline(of, level); of << "return " << f_->type_->get_string() << ";"; newline(of, level); } void vhdl_param_decl::emit(std::ostream &of, int level) const { of << name_ << " : "; type_->emit(of, level); } vhdl_with_select_stmt::~vhdl_with_select_stmt() { } void vhdl_with_select_stmt::emit(std::ostream &of, int level) const { of << "with "; test_->emit(of, level); of << " select"; emit_comment(of, level, true); newline(of, indent(level)); out_->emit(of, level); of << " <= "; when_list_t::const_iterator it = whens_.begin(); while (it != whens_.end()) { (*it).value->emit(of, level); if ((*it).delay) { of << " after "; (*it).delay->emit(of, level); } of << " when "; (*it).cond->emit(of, level); if (++it != whens_.end() || others_ != NULL) { of << ","; newline(of, indent(level)); } else of << ";"; } if (others_) { others_->emit(of, level); of << " when others;"; } } void vhdl_with_select_stmt::add_condition(vhdl_expr *value, vhdl_expr *cond, vhdl_expr *delay) { when_part_t when = { value, cond, delay }; whens_.push_back(when); } void vhdl_with_select_stmt::add_default(vhdl_expr* value) { others_ = value; } iverilog-12_0/tgt-vhdl/vhdl_syntax.hh000066400000000000000000000620651435245347300177750ustar00rootroot00000000000000/* * VHDL abstract syntax elements. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_VHDL_SYNTAX_HH #define INC_VHDL_SYNTAX_HH #include #include #include #include "vhdl_element.hh" #include "vhdl_type.hh" class vhdl_scope; class vhdl_entity; class vhdl_arch; class vhdl_var_ref; typedef std::set vhdl_var_set_t; class vhdl_expr : public vhdl_element { public: explicit vhdl_expr(const vhdl_type* type, bool isconst=false) : type_(type), isconst_(isconst) {} virtual ~vhdl_expr(); const vhdl_type *get_type() const { return type_; } bool constant() const { return isconst_; } vhdl_expr *cast(const vhdl_type *to); virtual vhdl_expr *resize(int newwidth); virtual vhdl_expr *to_boolean(); virtual vhdl_expr *to_integer(); virtual vhdl_expr *to_std_logic(); virtual vhdl_expr *to_std_ulogic(); virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w); virtual vhdl_expr *to_string(); virtual void find_vars(vhdl_var_set_t&) {} protected: static void open_parens(std::ostream& of); static void close_parens(std::ostream& of); static int paren_levels; const vhdl_type *type_; bool isconst_; }; /* * A scalar or array variable reference. */ class vhdl_var_ref : public vhdl_expr { public: vhdl_var_ref(const std::string& name, const vhdl_type *type, vhdl_expr *slice = NULL) : vhdl_expr(type), name_(name), slice_(slice), slice_width_(0) {} ~vhdl_var_ref(); void emit(std::ostream &of, int level) const; const std::string &get_name() const { return name_; } void set_name(const std::string &name) { name_ = name; } void set_slice(vhdl_expr *s, int w=0); void find_vars(vhdl_var_set_t& read); private: std::string name_; vhdl_expr *slice_; unsigned slice_width_; }; enum vhdl_binop_t { VHDL_BINOP_AND = 0, VHDL_BINOP_OR, VHDL_BINOP_EQ, VHDL_BINOP_NEQ, VHDL_BINOP_ADD, VHDL_BINOP_SUB, VHDL_BINOP_MULT, VHDL_BINOP_LT, VHDL_BINOP_GT, VHDL_BINOP_LEQ, VHDL_BINOP_GEQ, VHDL_BINOP_SL, VHDL_BINOP_SR, VHDL_BINOP_XOR, VHDL_BINOP_CONCAT, VHDL_BINOP_NAND, VHDL_BINOP_NOR, VHDL_BINOP_XNOR, VHDL_BINOP_DIV, VHDL_BINOP_MOD, VHDL_BINOP_POWER, VHDL_BINOP_SRA }; /* * A binary expression contains a list of operands rather * than just two: this is to model n-input gates and the * like. A second constructor is provided to handle the * common case of a true binary expression. */ class vhdl_binop_expr : public vhdl_expr { public: vhdl_binop_expr(vhdl_binop_t op, const vhdl_type *type) : vhdl_expr(type), op_(op) {} vhdl_binop_expr(vhdl_expr *left, vhdl_binop_t op, vhdl_expr *right, const vhdl_type *type); ~vhdl_binop_expr(); void add_expr(vhdl_expr *e); void add_expr_front(vhdl_expr *e); void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read); private: std::list operands_; vhdl_binop_t op_; }; enum vhdl_unaryop_t { VHDL_UNARYOP_NOT, VHDL_UNARYOP_NEG }; class vhdl_unaryop_expr : public vhdl_expr { public: vhdl_unaryop_expr(vhdl_unaryop_t op, vhdl_expr *operand, vhdl_type *type) : vhdl_expr(type), op_(op), operand_(operand) {} ~vhdl_unaryop_expr(); void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read); private: vhdl_unaryop_t op_; vhdl_expr *operand_; }; /* * An expression like (0 => '1', 2 => '0', others => 'Z') */ class vhdl_bit_spec_expr : public vhdl_expr { public: vhdl_bit_spec_expr(vhdl_type *type, vhdl_expr *others) : vhdl_expr(type), others_(others) {} ~vhdl_bit_spec_expr(); void add_bit(int bit, vhdl_expr *e); void emit(std::ostream &of, int level) const; private: vhdl_expr *others_; struct bit_map { int bit; vhdl_expr *e; }; std::list bits_; }; class vhdl_const_string : public vhdl_expr { public: explicit vhdl_const_string(const std::string& value) : vhdl_expr(vhdl_type::string(), true), value_(value) {} void emit(std::ostream &of, int level) const; private: std::string value_; }; class vhdl_const_bits : public vhdl_expr { public: vhdl_const_bits(const char *value, int width, bool issigned, bool qualify=false); void emit(std::ostream &of, int level) const; const std::string &get_value() const { return value_; } vhdl_expr *to_integer(); vhdl_expr *to_std_logic(); vhdl_expr *to_vector(vhdl_type_name_t name, int w); vhdl_expr *resize(int w); private: int64_t bits_to_int() const; char sign_bit() const; bool has_meta_bits() const; std::string value_; bool qualified_, signed_; }; class vhdl_const_bit : public vhdl_expr { public: explicit vhdl_const_bit(char bit) : vhdl_expr(vhdl_type::std_logic(), true), bit_(bit) {} void emit(std::ostream &of, int level) const; vhdl_expr *to_boolean(); vhdl_expr *to_integer(); vhdl_expr *to_vector(vhdl_type_name_t name, int w); vhdl_expr *to_std_ulogic(); private: char bit_; }; enum time_unit_t { TIME_UNIT_PS, TIME_UNIT_NS, TIME_UNIT_US, TIME_UNIT_MS }; class vhdl_const_time : public vhdl_expr { public: explicit vhdl_const_time(uint64_t value, time_unit_t units = TIME_UNIT_NS) : vhdl_expr(vhdl_type::time(), true), value_(value), units_(units) {} void emit(std::ostream &of, int level) const; private: uint64_t value_; time_unit_t units_; }; class vhdl_const_int : public vhdl_expr { public: explicit vhdl_const_int(int64_t value) : vhdl_expr(vhdl_type::integer(), true), value_(value) {} void emit(std::ostream &of, int level) const; vhdl_expr *to_vector(vhdl_type_name_t name, int w); private: int64_t value_; }; class vhdl_const_bool : public vhdl_expr { public: explicit vhdl_const_bool(bool value) : vhdl_expr(vhdl_type::boolean(), true), value_(value) {} void emit(std::ostream &of, int level) const; private: bool value_; }; class vhdl_expr_list : public vhdl_element { public: ~vhdl_expr_list(); void emit(std::ostream &of, int level) const; bool empty() const { return exprs_.empty(); } void add_expr(vhdl_expr *e); void find_vars(vhdl_var_set_t& read); private: std::list exprs_; }; /* * A function call within an expression. */ class vhdl_fcall : public vhdl_expr { public: vhdl_fcall(const std::string& name, const vhdl_type *rtype) : vhdl_expr(rtype), name_(name) {}; ~vhdl_fcall() {} void add_expr(vhdl_expr *e) { exprs_.add_expr(e); } void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read); private: std::string name_; vhdl_expr_list exprs_; }; /* * A concurrent statement appears in architecture bodies/ */ class vhdl_conc_stmt : public vhdl_element { public: virtual ~vhdl_conc_stmt() {} }; typedef std::list conc_stmt_list_t; /* * A ' when ' clause that appears in several * statement types. */ struct when_part_t { vhdl_expr *value, *cond, *delay; }; typedef std::list when_list_t; /* * A concurrent signal assignment (i.e. not part of a process). * Can have any number of `when' clauses, in which case the original * rhs becomes the `else' part. */ class vhdl_cassign_stmt : public vhdl_conc_stmt { public: vhdl_cassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) : lhs_(lhs), rhs_(rhs), after_(NULL) {} ~vhdl_cassign_stmt(); void emit(std::ostream &of, int level) const; void add_condition(vhdl_expr *value, vhdl_expr *cond); void set_after(vhdl_expr *a) { after_ = a; } private: vhdl_var_ref *lhs_; vhdl_expr *rhs_; vhdl_expr *after_; when_list_t whens_; }; class vhdl_with_select_stmt : public vhdl_conc_stmt { public: vhdl_with_select_stmt(vhdl_expr *test, vhdl_var_ref *out) : test_(test), out_(out), others_(NULL) {} ~vhdl_with_select_stmt(); void emit(std::ostream &of, int level) const; void add_condition(vhdl_expr *value, vhdl_expr *cond, vhdl_expr *delay=NULL); void add_default(vhdl_expr* value); private: vhdl_expr *test_; vhdl_var_ref *out_; when_list_t whens_; vhdl_expr* others_; }; /* * Any sequential statement in a process. */ class vhdl_seq_stmt : public vhdl_element { public: virtual ~vhdl_seq_stmt() {} // Find all the variables that are read or written in the // expressions within this statement // This is used to clean up the VHDL output virtual void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) = 0; }; /* * A list of sequential statements. For example inside a * process, loop, or if statement. */ class stmt_container { public: ~stmt_container(); void add_stmt(vhdl_seq_stmt *stmt); void move_stmts_from(stmt_container *other); void emit(std::ostream &of, int level, bool newline=true) const; bool empty() const { return stmts_.empty(); } void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); typedef std::list stmt_list_t; stmt_list_t &get_stmts() { return stmts_; } private: stmt_list_t stmts_; }; /* * Shared between blocking and non-blocking assignment. */ class vhdl_abstract_assign_stmt : public vhdl_seq_stmt { public: vhdl_abstract_assign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) : lhs_(lhs), rhs_(rhs), after_(NULL) {} virtual ~vhdl_abstract_assign_stmt(); void set_after(vhdl_expr *after) { after_ = after; } void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); protected: vhdl_var_ref *lhs_; vhdl_expr *rhs_, *after_; }; /* * Similar to Verilog non-blocking assignment, except the LHS * must be a signal not a variable. */ class vhdl_nbassign_stmt : public vhdl_abstract_assign_stmt { public: vhdl_nbassign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) : vhdl_abstract_assign_stmt(lhs, rhs) {} void emit(std::ostream &of, int level) const; }; class vhdl_assign_stmt : public vhdl_abstract_assign_stmt { public: vhdl_assign_stmt(vhdl_var_ref *lhs, vhdl_expr *rhs) : vhdl_abstract_assign_stmt(lhs, rhs) {} void emit(std::ostream &of, int level) const; }; enum vhdl_wait_type_t { VHDL_WAIT_INDEF, // Suspend indefinitely VHDL_WAIT_FOR, // Wait for a constant amount of time VHDL_WAIT_FOR0, // Special wait for zero time VHDL_WAIT_UNTIL, // Wait on an expression VHDL_WAIT_ON // Wait on a sensitivity list }; /* * Delay simulation indefinitely, until an event, or for a * specified time. */ class vhdl_wait_stmt : public vhdl_seq_stmt { public: vhdl_wait_stmt(vhdl_wait_type_t type = VHDL_WAIT_INDEF, vhdl_expr *expr = NULL) : type_(type), expr_(expr) {} ~vhdl_wait_stmt(); void emit(std::ostream &of, int level) const; void add_sensitivity(const std::string &s) { sensitivity_.push_back(s); } vhdl_wait_type_t get_type() const { return type_; } void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_wait_type_t type_; vhdl_expr *expr_; string_list_t sensitivity_; }; class vhdl_null_stmt : public vhdl_seq_stmt { public: void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t&, vhdl_var_set_t&) {} }; enum vhdl_severity_t { SEVERITY_NOTE, SEVERITY_WARNING, SEVERITY_ERROR, SEVERITY_FAILURE }; class vhdl_report_stmt : public vhdl_seq_stmt { public: explicit vhdl_report_stmt(vhdl_expr *text, vhdl_severity_t severity = SEVERITY_NOTE); virtual ~vhdl_report_stmt() {} virtual void emit(std::ostream& of, int level) const; void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_severity_t severity_; vhdl_expr *text_; }; class vhdl_assert_stmt : public vhdl_report_stmt { public: explicit vhdl_assert_stmt(const char *reason); void emit(std::ostream &of, int level) const; }; class vhdl_if_stmt : public vhdl_seq_stmt { public: explicit vhdl_if_stmt(vhdl_expr *test); ~vhdl_if_stmt(); stmt_container *get_then_container() { return &then_part_; } stmt_container *get_else_container() { return &else_part_; } stmt_container *add_elsif(vhdl_expr *test); void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: struct elsif { vhdl_expr *test; stmt_container *container; }; vhdl_expr *test_; stmt_container then_part_, else_part_; std::list elsif_parts_; }; /* * A single branch in a case statement consisting of an * expression part and a statement container. */ class vhdl_case_branch : public vhdl_element { friend class vhdl_case_stmt; public: explicit vhdl_case_branch(vhdl_expr *when) : when_(when) {} ~vhdl_case_branch(); stmt_container *get_container() { return &stmts_; } void emit(std::ostream &of, int level) const; private: vhdl_expr *when_; stmt_container stmts_; }; typedef std::list case_branch_list_t; class vhdl_case_stmt : public vhdl_seq_stmt { public: explicit vhdl_case_stmt(vhdl_expr *test) : test_(test) {} ~vhdl_case_stmt(); void add_branch(vhdl_case_branch *b) { branches_.push_back(b); } void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_expr *test_; case_branch_list_t branches_; }; class vhdl_loop_stmt : public vhdl_seq_stmt { public: virtual ~vhdl_loop_stmt() {} stmt_container *get_container() { return &stmts_; } void emit(std::ostream &of, int level) const; virtual void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: stmt_container stmts_; }; class vhdl_while_stmt : public vhdl_loop_stmt { public: explicit vhdl_while_stmt(vhdl_expr *test) : test_(test) {} ~vhdl_while_stmt(); void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: vhdl_expr *test_; }; class vhdl_for_stmt : public vhdl_loop_stmt { public: vhdl_for_stmt(const char *lname, vhdl_expr *from, vhdl_expr *to) : lname_(lname), from_(from), to_(to) {} ~vhdl_for_stmt(); void emit(std::ostream &of, int level) const; void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: const char *lname_; vhdl_expr *from_, *to_; }; /* * A procedure call. Which is a statement, unlike a function * call which is an expression. */ class vhdl_pcall_stmt : public vhdl_seq_stmt { public: explicit vhdl_pcall_stmt(const char *name) : name_(name) {} void emit(std::ostream &of, int level) const; void add_expr(vhdl_expr *e) { exprs_.add_expr(e); } void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write); private: std::string name_; vhdl_expr_list exprs_; }; /* * A declaration of some sort (variable, component, etc.). * Declarations have names, which is the identifier of the variable, * constant, etc. not the type. */ class vhdl_decl : public vhdl_element { public: explicit vhdl_decl(const std::string& name, const vhdl_type *type = NULL, vhdl_expr *initial = NULL) : name_(name), type_(type), initial_(initial), has_initial_(initial != NULL) {} virtual ~vhdl_decl(); const std::string &get_name() const { return name_; } const vhdl_type *get_type() const; void set_type(vhdl_type *t) { type_ = t; } void set_initial(vhdl_expr *initial); bool has_initial() const { return has_initial_; } // Return a new reference to this declaration vhdl_var_ref* make_ref() const; // The different sorts of assignment statement // ASSIGN_CONST is used to generate a variable to shadow a // constant that cannot be assigned to (e.g. a function parameter) enum assign_type_t { ASSIGN_BLOCK, ASSIGN_NONBLOCK, ASSIGN_CONST }; // Get the sort of assignment statement to generate for // assignments to this declaration // For some sorts of declarations it doesn't make sense // to assign to it so calling assignment_type just raises // an assertion failure virtual assign_type_t assignment_type() const { assert(false); return ASSIGN_BLOCK; } // True if this declaration can be read from virtual bool is_readable() const { return true; } // Modify this declaration so it can be read from // This does nothing for most declaration types virtual void ensure_readable() {} protected: std::string name_; const vhdl_type *type_; vhdl_expr *initial_; bool has_initial_; }; typedef std::list decl_list_t; /* * A forward declaration of a component. At the moment it is assumed * that components declarations will only ever be for entities * generated by this code generator. This is enforced by making the * constructor private (use component_decl_for instead). */ class vhdl_component_decl : public vhdl_decl { public: static vhdl_component_decl *component_decl_for(vhdl_entity *ent); void emit(std::ostream &of, int level) const; private: explicit vhdl_component_decl(const char *name); decl_list_t ports_; }; class vhdl_type_decl : public vhdl_decl { public: vhdl_type_decl(const std::string& name, const vhdl_type *base) : vhdl_decl(name, base) {} void emit(std::ostream &of, int level) const; }; /* * A variable declaration inside a process (although this isn't * enforced here). */ class vhdl_var_decl : public vhdl_decl { public: vhdl_var_decl(const std::string& name, const vhdl_type *type) : vhdl_decl(name, type) {} void emit(std::ostream &of, int level) const; assign_type_t assignment_type() const { return ASSIGN_BLOCK; } }; /* * A signal declaration in architecture. */ class vhdl_signal_decl : public vhdl_decl { public: vhdl_signal_decl(const std::string& name, const vhdl_type* type) : vhdl_decl(name, type) {} virtual void emit(std::ostream &of, int level) const; assign_type_t assignment_type() const { return ASSIGN_NONBLOCK; } }; /* * A parameter to a function. */ class vhdl_param_decl : public vhdl_decl { public: vhdl_param_decl(const char *name, vhdl_type *type) : vhdl_decl(name, type) {} void emit(std::ostream &of, int level) const; assign_type_t assignment_type() const { return ASSIGN_CONST; } }; enum vhdl_port_mode_t { VHDL_PORT_IN, VHDL_PORT_OUT, VHDL_PORT_INOUT, VHDL_PORT_BUFFER }; /* * A port declaration is like a signal declaration except * it has a direction and appears in the entity rather than * the architecture. */ class vhdl_port_decl : public vhdl_decl { public: vhdl_port_decl(const char *name, vhdl_type *type, vhdl_port_mode_t mode) : vhdl_decl(name, type), mode_(mode) {} void emit(std::ostream &of, int level) const; vhdl_port_mode_t get_mode() const { return mode_; } void set_mode(vhdl_port_mode_t m) { mode_ = m; } assign_type_t assignment_type() const { return ASSIGN_NONBLOCK; } void ensure_readable(); bool is_readable() const; private: vhdl_port_mode_t mode_; }; /* * A mapping from port name to an expression. */ struct port_map_t { std::string name; vhdl_expr *expr; }; typedef std::list port_map_list_t; /* * Instantiation of component. This is really only a placeholder * at the moment until the port mappings are worked out. */ class vhdl_comp_inst : public vhdl_conc_stmt { public: vhdl_comp_inst(const char *inst_name, const char *comp_name); ~vhdl_comp_inst(); void emit(std::ostream &of, int level) const; void map_port(const std::string& name, vhdl_expr *expr); const std::string &get_comp_name() const { return comp_name_; } const std::string &get_inst_name() const { return inst_name_; } private: std::string comp_name_, inst_name_; port_map_list_t mapping_; }; /* * Contains a list of declarations in a hierarchy. * A scope can be `initializing' where assignments automatically * create initial values for declarations. */ class vhdl_scope { public: vhdl_scope(); ~vhdl_scope(); void add_decl(vhdl_decl *decl); void add_forward_decl(vhdl_decl *decl); vhdl_decl *get_decl(const std::string &name) const; bool have_declared(const std::string &name) const; bool name_collides(const std::string& name) const; bool contained_within(const vhdl_scope *other) const; vhdl_scope *get_parent() const; bool empty() const { return decls_.empty(); } const decl_list_t &get_decls() const { return decls_; } void set_parent(vhdl_scope *p) { parent_ = p; } bool initializing() const { return init_; } void set_initializing(bool i); bool hoisted_initialiser() const; void hoisted_initialiser(bool h); void set_allow_signal_assignment(bool b) { sig_assign_ = b; } bool allow_signal_assignment() const { return sig_assign_; } private: decl_list_t decls_; vhdl_scope *parent_; bool init_, sig_assign_; bool hoisted_init_; }; /* * Any sort of procedural element: process, function, or * procedure. Roughly these map onto Verilog's processes, * functions, and tasks. */ class vhdl_procedural { public: vhdl_procedural() : contains_wait_stmt_(false) {} virtual ~vhdl_procedural() {} virtual stmt_container *get_container() { return &stmts_; } virtual vhdl_scope *get_scope() { return &scope_; } void added_wait_stmt() { contains_wait_stmt_ = true; } bool contains_wait_stmt() const { return contains_wait_stmt_; } // Managing set of blocking assignment targets in this block void add_blocking_target(vhdl_var_ref* ref); bool is_blocking_target(vhdl_var_ref* ref) const; protected: stmt_container stmts_; vhdl_scope scope_; // If this is true then the body contains a `wait' statement // embedded in it somewhere // If this is the case then we can't use a sensitivity list for // the process bool contains_wait_stmt_; // The set of variable we have performed a blocking // assignment to std::set blocking_targets_; }; class vhdl_function : public vhdl_decl, public vhdl_procedural { friend class vhdl_forward_fdecl; public: vhdl_function(const char *name, vhdl_type *ret_type); virtual void emit(std::ostream &of, int level) const; vhdl_scope *get_scope() { return &variables_; } void add_param(vhdl_param_decl *p) { scope_.add_decl(p); } private: vhdl_scope variables_; }; class vhdl_forward_fdecl : public vhdl_decl { public: explicit vhdl_forward_fdecl(const vhdl_function *f) : vhdl_decl((f->get_name() + "_Forward").c_str()), f_(f) {} void emit(std::ostream &of, int level) const; private: const vhdl_function *f_; }; class vhdl_process : public vhdl_conc_stmt, public vhdl_procedural { public: explicit vhdl_process(const char *name = "") : name_(name) {} void emit(std::ostream &of, int level) const; void add_sensitivity(const std::string &name); private: std::string name_; string_list_t sens_; }; /* * An architecture which implements an entity. */ class vhdl_arch : public vhdl_element { public: vhdl_arch(const std::string& entity, const std::string& name) : name_(name), entity_(entity) {} virtual ~vhdl_arch(); void emit(std::ostream &of, int level=0) const; void add_stmt(vhdl_process *proc); void add_stmt(vhdl_conc_stmt *stmt); vhdl_scope *get_scope() { return &scope_; } private: conc_stmt_list_t stmts_; vhdl_scope scope_; std::string name_, entity_; }; /* * An entity defines the ports, parameters, etc. of a module. Each * entity is associated with a single architecture (although * technically this need not be the case). Entities are `derived' * from instantiations of Verilog module scopes in the hierarchy. */ class vhdl_entity : public vhdl_element { public: vhdl_entity(const std::string& name, vhdl_arch *arch, int depth=0); virtual ~vhdl_entity(); void emit(std::ostream &of, int level=0) const; void add_port(vhdl_port_decl *decl); vhdl_arch *get_arch() const { return arch_; } const std::string &get_name() const { return name_; } vhdl_scope *get_scope() { return &ports_; } void set_time_units(int units, int precision); friend vhdl_const_time* scale_time(const vhdl_entity* ent, uint64_t t); // Each entity has an associated depth which is how deep in // the Verilog module hierarchy it was found // This is used to limit the maximum depth of modules emitted const int depth; private: std::string name_; vhdl_arch *arch_; // Entity may only have a single architecture vhdl_scope ports_; // Entities have an associated VHDL time unit // This is used to implement the Verilog timescale directive time_unit_t time_unit_; }; typedef std::list entity_list_t; #endif iverilog-12_0/tgt-vhdl/vhdl_target.h000066400000000000000000000017441435245347300175620ustar00rootroot00000000000000// -*- mode: c++ -*- #ifndef INC_VHDL_TARGET_H #define INC_VHDL_TARGET_H #include "vhdl_config.h" #include "ivl_target.h" #include "support.hh" #include "vhdl_syntax.hh" #include void error(const char *fmt, ...); void debug_msg(const char *fmt, ...); int draw_scope(ivl_scope_t scope, void *_parent); extern "C" int draw_process(ivl_process_t net, void *cd); int draw_stmt(vhdl_procedural *proc, stmt_container *container, ivl_statement_t stmt, bool is_last = false); int draw_lpm(vhdl_arch *arch, ivl_lpm_t lpm); void draw_logic(vhdl_arch *arch, ivl_net_logic_t log); vhdl_expr *translate_expr(ivl_expr_t e); vhdl_expr *translate_time_expr(ivl_expr_t e); ivl_design_t get_vhdl_design(); vhdl_var_ref *nexus_to_var_ref(vhdl_scope *arch_scope, ivl_nexus_t nexus); vhdl_var_ref* readable_ref(vhdl_scope* scope, ivl_nexus_t nex); std::string make_safe_name(ivl_signal_t sig); void require_support_function(support_function_t f); #endif /* #ifndef INC_VHDL_TARGET_H */ iverilog-12_0/tgt-vhdl/vhdl_type.cc000066400000000000000000000110141435245347300174020ustar00rootroot00000000000000/* * VHDL variable and signal types. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #include "vhdl_type.hh" #include #include #include vhdl_type *vhdl_type::std_logic() { return new vhdl_type(VHDL_TYPE_STD_LOGIC); } vhdl_type *vhdl_type::std_ulogic() { return new vhdl_type(VHDL_TYPE_STD_ULOGIC); } vhdl_type *vhdl_type::string() { return new vhdl_type(VHDL_TYPE_STRING); } vhdl_type *vhdl_type::line() { return new vhdl_type(VHDL_TYPE_LINE); } vhdl_type *vhdl_type::boolean() { return new vhdl_type(VHDL_TYPE_BOOLEAN); } vhdl_type *vhdl_type::integer() { return new vhdl_type(VHDL_TYPE_INTEGER); } vhdl_type *vhdl_type::nunsigned(int width, int lsb) { return new vhdl_type(VHDL_TYPE_UNSIGNED, width-1+lsb, lsb); } vhdl_type *vhdl_type::nsigned(int width, int lsb) { return new vhdl_type(VHDL_TYPE_SIGNED, width-1+lsb, lsb); } vhdl_type *vhdl_type::time() { return new vhdl_type(VHDL_TYPE_TIME); } vhdl_type *vhdl_type::get_base() const { assert(name_ == VHDL_TYPE_ARRAY); return base_; } /* * This is just the name of the type, without any parameters. */ std::string vhdl_type::get_string() const { switch (name_) { case VHDL_TYPE_STD_LOGIC: return std::string("std_logic"); case VHDL_TYPE_STD_ULOGIC: return std::string("std_ulogic"); case VHDL_TYPE_STD_LOGIC_VECTOR: return std::string("std_logic_vector"); case VHDL_TYPE_STRING: return std::string("String"); case VHDL_TYPE_LINE: return std::string("Line"); case VHDL_TYPE_FILE: return std::string("File"); case VHDL_TYPE_INTEGER: return std::string("Integer"); case VHDL_TYPE_BOOLEAN: return std::string("Boolean"); case VHDL_TYPE_SIGNED: return std::string("signed"); case VHDL_TYPE_UNSIGNED: return std::string("unsigned"); case VHDL_TYPE_ARRAY: // Each array has its own type declaration return array_name_; default: return std::string("BadType"); } } /* * The is the qualified name of the type. */ std::string vhdl_type::get_decl_string() const { switch (name_) { case VHDL_TYPE_STD_LOGIC_VECTOR: case VHDL_TYPE_UNSIGNED: case VHDL_TYPE_SIGNED: { std::ostringstream ss; ss << get_string() << "(" << msb_; ss << " downto " << lsb_ << ")"; return ss.str(); } default: return get_string(); } } /* * Like get_decl_string but completely expands array declarations. */ std::string vhdl_type::get_type_decl_string() const { switch (name_) { case VHDL_TYPE_ARRAY: { std::ostringstream ss; ss << "array (" << msb_ << " downto " << lsb_ << ") of " << base_->get_decl_string(); return ss.str(); } default: return get_decl_string(); } } void vhdl_type::emit(std::ostream &of, int) const { of << get_decl_string(); } vhdl_type::vhdl_type(const vhdl_type &other) : vhdl_element(other), name_(other.name_), msb_(other.msb_), lsb_(other.lsb_), array_name_(other.array_name_) { if (other.base_ != NULL) base_ = new vhdl_type(*other.base_); else base_ = NULL; } vhdl_type::~vhdl_type() { delete base_; } vhdl_type *vhdl_type::std_logic_vector(int msb, int lsb) { return new vhdl_type(VHDL_TYPE_STD_LOGIC_VECTOR, msb, lsb); } vhdl_type *vhdl_type::type_for(int width, bool issigned, int lsb, bool unresolved) { if (width == 1) { if (unresolved) return vhdl_type::std_ulogic(); else return vhdl_type::std_logic(); } else if (issigned) return vhdl_type::nsigned(width, lsb); else return vhdl_type::nunsigned(width, lsb); } vhdl_type *vhdl_type::array_of(vhdl_type *b, const std::string &n, int m, int l) { return new vhdl_type(b, n, m, l); } iverilog-12_0/tgt-vhdl/vhdl_type.hh000066400000000000000000000060031435245347300174160ustar00rootroot00000000000000/* * VHDL variable and signal types. * * Copyright (C) 2008-2021 Nick Gasson (nick@nickg.me.uk) * * 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. */ #ifndef INC_VHDL_TYPE_HH #define INC_VHDL_TYPE_HH #include "vhdl_element.hh" enum vhdl_type_name_t { VHDL_TYPE_STD_LOGIC, VHDL_TYPE_STD_ULOGIC, VHDL_TYPE_STD_LOGIC_VECTOR, VHDL_TYPE_STRING, VHDL_TYPE_LINE, VHDL_TYPE_FILE, VHDL_TYPE_INTEGER, VHDL_TYPE_BOOLEAN, VHDL_TYPE_SIGNED, VHDL_TYPE_UNSIGNED, VHDL_TYPE_TIME, VHDL_TYPE_ARRAY }; /* * A type at the moment is just a name. It shouldn't get * too much more complex, as Verilog's type system is much * simpler than VHDL's. */ class vhdl_type : public vhdl_element { public: // Scalar constructor explicit vhdl_type(vhdl_type_name_t name, int msb = 0, int lsb = 0) : name_(name), msb_(msb), lsb_(lsb), base_(NULL) {} // Array constructor vhdl_type(vhdl_type *base, const std::string &array_name, int msb, int lsb) : name_(VHDL_TYPE_ARRAY), msb_(msb), lsb_(lsb), base_(base), array_name_(array_name) {} // Copy constructor vhdl_type(const vhdl_type &other); virtual ~vhdl_type(); void emit(std::ostream &of, int level) const; vhdl_type_name_t get_name() const { return name_; } std::string get_string() const; std::string get_decl_string() const; std::string get_type_decl_string() const; vhdl_type *get_base() const; int get_width() const { return msb_ - lsb_ + 1; } int get_msb() const { return msb_; } int get_lsb() const { return lsb_; } // Common types static vhdl_type *std_logic(); static vhdl_type *std_ulogic(); static vhdl_type *string(); static vhdl_type *line(); static vhdl_type *std_logic_vector(int msb, int lsb); static vhdl_type *nunsigned(int width, int lsb=0); static vhdl_type *nsigned(int width, int lsb=0); static vhdl_type *integer(); static vhdl_type *boolean(); static vhdl_type *time(); static vhdl_type *type_for(int width, bool issigned, int lsb=0, bool unresolved=false); static vhdl_type *array_of(vhdl_type *b, const std::string &n, int m, int l); protected: vhdl_type_name_t name_; int msb_, lsb_; vhdl_type *base_; // Array base type for VHDL_TYPE_ARRAY std::string array_name_; // Type name for the array `type array_name_ is ...' }; #endif iverilog-12_0/tgt-vhdl/vhpi/000077500000000000000000000000001435245347300160465ustar00rootroot00000000000000iverilog-12_0/tgt-vhdl/vhpi/finish.c000066400000000000000000000000671435245347300174750ustar00rootroot00000000000000#include void finish(void) { exit(0); } iverilog-12_0/tgt-vlog95/000077500000000000000000000000001435245347300152705ustar00rootroot00000000000000iverilog-12_0/tgt-vlog95/Makefile.in000066400000000000000000000053541435245347300173440ustar00rootroot00000000000000# # Copyright (C) 2011-2012 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. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = vlog95.o event.o expr.o logic_lpm.o misc.o numbers.o scope.o stmt.o udp.o all: dep vlog95.tgt check: all clean: rm -rf *.o dep vlog95.tgt distclean: clean rm -f Makefile config.log cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-vlog95/$@ dep: mkdir dep %.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif vlog95.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O -lm $(TGTLDFLAGS) install: all installdirs installfiles F = ./vlog95.tgt \ $(srcdir)/vlog95.conf \ $(srcdir)/vlog95-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vlog95.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95.tgt" $(INSTALL_DATA) $(srcdir)/vlog95.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95.conf" $(INSTALL_DATA) $(srcdir)/vlog95-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95.tgt" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95.conf" rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vlog95-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-vlog95/cppcheck.sup000066400000000000000000000002761435245347300176060ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:vlog95.c:59 // target_query() unusedFunction:vlog95.c:257 iverilog-12_0/tgt-vlog95/event.c000066400000000000000000000070231435245347300165570ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ # include # include # include "config.h" # include "vlog95_priv.h" static unsigned need_ivl_top_module = 0; void emit_icarus_generated_top_module() { if (need_ivl_top_module) { fprintf(vlog_out, "\n" "/*\n" " * This module is used to trigger any always_comb or always_latch processes\n" " * at time zero to make sure all the outputs have the correct values.\n" "*/\n" "module IVL_top_priv_module;\n" " event IVL_T0_trigger_event;\n" " initial #0 -> IVL_T0_trigger_event;\n" "endmodule /* IVL_top_priv_module */\n"); } } void emit_event(ivl_scope_t scope, ivl_statement_t stmt) { unsigned eidx, nevents, first = 1; nevents = ivl_stmt_nevent(stmt); for (eidx = 0; eidx < nevents; eidx += 1) { unsigned idx, count, had_edge = 0; ivl_event_t event = ivl_stmt_events(stmt, eidx); /* Check for any edge events. */ count = ivl_event_nany(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); emit_nexus_as_ca(scope, ivl_event_any(event, idx), 0, 0); } /* Check for positive edge events. */ count = ivl_event_npos(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); fprintf(vlog_out, "posedge "); emit_nexus_as_ca(scope, ivl_event_pos(event, idx), 0, 0); } /* Check for negative edge events. */ count = ivl_event_nneg(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); fprintf(vlog_out, "negedge "); emit_nexus_as_ca(scope, ivl_event_neg(event, idx), 0, 0); } /* Check for edge events. */ count = ivl_event_nedg(event); if (count) had_edge = 1; for (idx = 0; idx < count; idx += 1) { if (first) first = 0; else fprintf(vlog_out, " or "); fprintf(vlog_out, "posedge "); emit_nexus_as_ca(scope, ivl_event_edg(event, idx), 0, 0); fprintf(vlog_out, " or negedge "); emit_nexus_as_ca(scope, ivl_event_edg(event, idx), 0, 0); } /* We have a named event if there were no edge events. */ if (!had_edge) { ivl_scope_t ev_scope = ivl_event_scope(event); if (first) first = 0; else fprintf(vlog_out, " or "); emit_scope_module_path(scope, ev_scope); emit_id(ivl_event_basename(event)); } } /* If this is an always_comb/latch then we need to add a trigger to * get the correct functionality. */ if (ivl_stmt_needs_t0_trigger(stmt)) { if (! first) { fprintf(vlog_out, " or "); } fprintf(vlog_out, "IVL_top_priv_module.IVL_T0_trigger_event"); need_ivl_top_module = 1; }; } iverilog-12_0/tgt-vlog95/expr.c000066400000000000000000001253571435245347300164270ustar00rootroot00000000000000/* * Copyright (C) 2011-2020 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. */ # include # include # include "config.h" # include "vlog95_priv.h" /* The expression code needs to know when a parameter definition is being * emitted so it can print the numeric value instead of the parameter name. */ ivl_parameter_t emitting_param = 0; /* * Data type used to signify if a $signed or $unsigned should be emitted. */ typedef enum expr_sign_e { NO_SIGN = 0, NEED_SIGNED = 1, NEED_UNSIGNED = 2 } expr_sign_t; static expr_sign_t expr_get_binary_sign_type(ivl_expr_t expr) { ivl_expr_t oper1, oper2; int opr_sign = 0; int expr_sign = ivl_expr_signed(expr); expr_sign_t rtn = NO_SIGN; switch (ivl_expr_opcode(expr)) { case 'E': case 'e': case 'w': case 'N': case 'n': case 'W': case '<': case 'L': case '>': case 'G': /* The comparison operators always act as if the argument is * unsigned. */ break; case 'l': case 'r': case 'R': /* For the shift operators only the left operand is used to * determine the sign information. */ opr_sign = ivl_expr_signed(ivl_expr_oper1(expr)); break; default: /* For the rest of the opcodes the operator is considered to * be signed if either argument is real or if both arguments * are signed. */ oper1 = ivl_expr_oper1(expr); oper2 = ivl_expr_oper2(expr); if ((ivl_expr_value(oper1) == IVL_VT_REAL) || (ivl_expr_value(oper2) == IVL_VT_REAL)) { opr_sign = 1; } else if (ivl_expr_signed(oper1) && ivl_expr_signed(oper2)) { opr_sign = 1; } break; } /* Check to see if a $signed() or $unsigned() is needed. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign) rtn = NEED_UNSIGNED; return rtn; } static expr_sign_t expr_get_select_sign_type(ivl_expr_t expr, unsigned can_skip_unsigned) { int opr_sign = 0; int expr_sign = ivl_expr_signed(expr); expr_sign_t rtn = NO_SIGN; /* If there is no select expression then the sign is determined by * the expression that is being selected (padded). */ if (! ivl_expr_oper2(expr)) { ivl_expr_t oper1 = ivl_expr_oper1(expr); opr_sign = ivl_expr_signed(oper1); /* If the expression being padded is not a signal then don't * skip a soft $unsigned() (from the binary operator). */ if (ivl_expr_type(oper1) != IVL_EX_SIGNAL) can_skip_unsigned -= 1; } /* Check to see if a $signed() or $unsigned() is needed. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; return rtn; } static expr_sign_t expr_get_signal_sign_type(ivl_expr_t expr, unsigned can_skip_unsigned) { int opr_sign = ivl_signal_signed(ivl_expr_signal(expr)); int expr_sign = ivl_expr_signed(expr); expr_sign_t rtn = NO_SIGN; /* Check to see if a $signed() or $unsigned() is needed. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; return rtn; } static expr_sign_t expr_get_unary_sign_type(ivl_expr_t expr) { ivl_expr_t expr1; int opr_sign = 0; int expr_sign = ivl_expr_signed(expr); expr_sign_t rtn = NO_SIGN; switch (ivl_expr_opcode(expr)) { case '&': case '|': case '^': case 'A': case 'N': case 'X': /* The reduction operators always act as if the argument is * unsigned. */ case '!': /* The logical negation operator works on either type. */ break; case 'r': /* For a cast to real the expression should be signed and no * sign conversion is needed. */ opr_sign = expr_sign; if (! expr_sign) { fprintf(stderr, "%s:%u: vlog95 error: Cast to real " "expression is not signed.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } break; case '2': case 'v': /* If the cast to a vector value is from a real then no sign * conversion is needed. Otherwise use the actual argument. */ expr1 = ivl_expr_oper1(expr); if (ivl_expr_value(expr1) == IVL_VT_REAL) { opr_sign = expr_sign; } else { opr_sign = ivl_expr_signed(expr1); } break; default: /* For the rest of the opcodes the argument sign type depends * on the actual argument. */ opr_sign = ivl_expr_signed(ivl_expr_oper1(expr)); break; } /* Check to see if a $signed() or $unsigned() is needed. */ if (expr_sign && ! opr_sign) rtn = NEED_SIGNED; if (! expr_sign && opr_sign) rtn = NEED_UNSIGNED; return rtn; } /* * This routine is used to determine if the expression is a binary operator * where the width could be different to create a self-determined context. */ static unsigned expr_is_binary_self_det(ivl_expr_t expr) { unsigned rtn = 0; if (ivl_expr_type(expr) == IVL_EX_BINARY) { switch (ivl_expr_opcode(expr)) { case '+': case '-': case '*': case '/': case '%': case '&': case '|': case '^': case 'X': case 'A': case 'O': case 'R': case 'l': case 'r': rtn = 1; break; default: break; } } return rtn; } /* * Determine if a $signed() or $unsigned() system function is needed to get * the expression sign information correct. can_skip_unsigned may be set for * the binary/ternary operators if one of the operands will implicitly cast * the expression to unsigned. See calc_can_skip_unsigned() for the details. */ static expr_sign_t expr_get_sign_type(ivl_expr_t expr, unsigned wid, unsigned can_skip_unsigned, unsigned is_full_prec) { unsigned expr_wid = ivl_expr_width(expr); expr_sign_t rtn = NO_SIGN; ivl_expr_type_t type = ivl_expr_type(expr); switch (type) { case IVL_EX_BINARY: rtn = expr_get_binary_sign_type(expr); break; case IVL_EX_CONCAT: /* A concatenation is always unsigned so add a $signed() when * needed. */ if (ivl_expr_signed(expr)) rtn = NEED_SIGNED; break; case IVL_EX_SELECT: rtn = expr_get_select_sign_type(expr, can_skip_unsigned); /* If there is no select expression then this is padding so use * the actual expressions width if it is a binary operator that * could create a self-determined context. */ if (! ivl_expr_oper2(expr)) { ivl_expr_t oper1 = ivl_expr_oper1(expr); if (expr_is_binary_self_det(oper1)) { expr_wid = ivl_expr_width(oper1); } } break; case IVL_EX_SIGNAL: rtn = expr_get_signal_sign_type(expr, can_skip_unsigned); break; case IVL_EX_UNARY: rtn = expr_get_unary_sign_type(expr); break; /* These do not currently have sign casting information. A select * is used for that purpose. */ case IVL_EX_ARRAY: case IVL_EX_DELAY: case IVL_EX_ENUMTYPE: case IVL_EX_EVENT: case IVL_EX_NEW: case IVL_EX_NULL: case IVL_EX_NUMBER: case IVL_EX_PROPERTY: case IVL_EX_REALNUM: case IVL_EX_SCOPE: case IVL_EX_SFUNC: case IVL_EX_SHALLOWCOPY: case IVL_EX_STRING: case IVL_EX_TERNARY: case IVL_EX_UFUNC: default: break; } /* Check for a self-determined context. A zero width expression * is special and is not considered a self determined context. */ if ((rtn == NO_SIGN) && (wid != expr_wid) && expr_wid && ! (is_full_prec && ((expr_wid < wid) || (type == IVL_EX_SIGNAL)))) { if (ivl_expr_signed(expr)) rtn = NEED_SIGNED; else rtn = NEED_UNSIGNED; } return rtn; } /* * We can convert any 2^n ** expression to * 1 << (n * ). If the variable is signed then we need * to add a check for less than zero and for that case return 0. */ static unsigned emit_power_as_shift(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { int rtype; int64_t value, scale; unsigned is_signed_rval = 0; unsigned is_signed_expr = ivl_expr_signed(expr); unsigned expr_wid; ivl_expr_t lval = ivl_expr_oper1(expr); ivl_expr_t rval = ivl_expr_oper2(expr); (void)wid; /* Parameter is not used. */ /* The L-value must be a number. */ if (ivl_expr_type(lval) != IVL_EX_NUMBER) return 0; /* The L-value must of the form 2^n. */ value = get_int64_from_number(lval, &rtype); if (rtype) return 0; expr_wid = ivl_expr_width(lval); if (value < 2) return 0; if (value % 2) return 0; /* Generate the appropriate conversion. */ if (ivl_expr_signed(rval)) { emit_expr(scope, rval, 0, 0, 0, 0); fprintf(vlog_out, " < 0 ? "); if (is_signed_expr) { if (expr_wid == 32) { fprintf(vlog_out, "0"); } else if (allow_signed) { fprintf(vlog_out, "%u'sh0", expr_wid); } else { fprintf(stderr, "%s:%u: vlog95 error: Sized signed " "power operator l-value is not " "supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; fprintf(vlog_out, "%u'h0", expr_wid); } } else { fprintf(vlog_out, "%u'h0", expr_wid); } fprintf(vlog_out, " : ("); is_signed_rval = 1; } scale = value / 2; if (is_signed_expr) { if (expr_wid == 32) { fprintf(vlog_out, "1"); } else if (allow_signed) { fprintf(vlog_out, "%u'sh1", expr_wid); } else { /* This is an error condition and has already been * reported above. */ fprintf(vlog_out, "%u'h1", expr_wid); } } else { fprintf(vlog_out, "%u'h1", expr_wid); } fprintf(vlog_out, " << "); if (scale != 1) { if (is_signed_rval) { fprintf(vlog_out, "(%"PRId64, scale); } else { fprintf(vlog_out, "(%u'h%"PRIx64, ivl_expr_width(rval), scale); } fprintf(vlog_out, " * "); } emit_expr(scope, rval, 0, 0, 0, 0); if (scale != 1) fprintf(vlog_out, ")"); if (is_signed_rval) fprintf(vlog_out, ")"); return 1; } static void emit_expr_array(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_signal_t sig = ivl_expr_signal(expr); (void)wid; /* Parameter is not used. */ emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); } /* * Some of the operators can do an implicit cast to real so for them emit * the non-real argument in a self-determined context. */ static unsigned get_cast_width(ivl_expr_t expr, ivl_expr_t oper, unsigned wid) { ivl_variable_type_t expr_type = ivl_expr_value(expr); if ((expr_type == IVL_VT_REAL) && (expr_type != ivl_expr_value(oper))) { wid = 0; } return wid; } static unsigned calc_can_skip_unsigned(ivl_expr_t oper1, ivl_expr_t oper2) { unsigned oper1_signed, oper2_signed; /* Check to see if the operands are signed or softly signed. * The expression is signed (hard). * It is a signed signal cast to unsigned (soft). * It is a padding cast from signed to unsigned (soft). */ oper1_signed = ivl_expr_signed(oper1); oper1_signed |= (ivl_expr_type(oper1) == IVL_EX_SIGNAL) && (ivl_signal_signed(ivl_expr_signal(oper1))); oper1_signed |= (ivl_expr_type(oper1) == IVL_EX_SELECT) && (! ivl_expr_oper2(oper1)) && (ivl_expr_signed(ivl_expr_oper1(oper1))); oper2_signed = ivl_expr_signed(oper2); oper2_signed |= (ivl_expr_type(oper2) == IVL_EX_SIGNAL) && (ivl_signal_signed(ivl_expr_signal(oper2))); oper2_signed |= (ivl_expr_type(oper2) == IVL_EX_SELECT) && (! ivl_expr_oper2(oper2)) && (ivl_expr_signed(ivl_expr_oper1(oper2))); /* If either operand is a hard unsigned skip adding an explicit * $unsigned() since it will be added implicitly. */ return ! oper1_signed || ! oper2_signed; } static void emit_expr_binary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, unsigned is_full_prec) { const char *oper = ""; ivl_expr_t oper1 = ivl_expr_oper1(expr); ivl_expr_t oper2 = ivl_expr_oper2(expr); unsigned can_skip_unsigned = calc_can_skip_unsigned(oper1, oper2); switch (ivl_expr_opcode(expr)) { case '+': oper = "+"; break; case '-': oper = "-"; break; case '*': oper = "*"; break; case '/': oper = "/"; break; case '%': oper = "%"; break; case 'p': oper = "**"; break; case 'E': oper = "==="; break; case 'e': oper = "=="; break; case 'w': oper = "==?"; break; case 'N': oper = "!=="; break; case 'n': oper = "!="; break; case 'W': oper = "!=?"; break; case '<': oper = "<"; break; case 'L': oper = "<="; break; case '>': oper = ">"; break; case 'G': oper = ">="; break; case '&': oper = "&"; break; case '|': oper = "|"; break; case '^': oper = "^"; break; case 'A': oper = "&"; break; case 'O': oper = "|"; break; case 'X': oper = "~^"; break; case 'a': oper = "&&"; break; case 'o': oper = "||"; break; case 'l': oper = "<<"; break; case 'r': oper = ">>"; break; case 'R': oper = ">>>"; break; case 'm': oper = "min"; break; case 'M': oper = "max"; break; } fprintf(vlog_out, "("); switch (ivl_expr_opcode(expr)) { case '%': if (ivl_expr_value(expr) == IVL_VT_REAL) { fprintf(stderr, "%s:%u: vlog95 error: Real modulus operator " "is not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } //fallthrough case '+': case '-': case '*': case '/': emit_expr(scope, oper1, get_cast_width(expr, oper1, wid), 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, get_cast_width(expr, oper2, wid), 0, can_skip_unsigned, is_full_prec); break; case '&': case '|': case '^': case 'X': emit_expr(scope, oper1, wid, 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, wid, 0, can_skip_unsigned, is_full_prec); break; case 'w': case 'W': fprintf(stderr, "%s:%u: vlog95 error: The wild equality operators " "cannot be converted.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; // fallthrough case 'E': case 'e': case 'N': case 'n': case '<': case 'L': case '>': case 'G': emit_expr(scope, oper1, ivl_expr_width(oper1), 0, can_skip_unsigned, 0); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, can_skip_unsigned, 0); break; case 'a': case 'o': emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0); break; case 'q': // The arguments have already been reduced fprintf(vlog_out, "{~"); emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0); fprintf(vlog_out, " | "); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0); fprintf(vlog_out, "}"); break; case 'Q': // The arguments have already been reduced fprintf(vlog_out, "{"); emit_expr(scope, oper1, ivl_expr_width(oper1), 0, 1, 0); fprintf(vlog_out, " ~^ "); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 1, 0); fprintf(vlog_out, "}"); break; case 'R': if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: >>> operator is not " "supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } // fallthrough case 'l': case 'r': emit_expr(scope, oper1, wid, 0, 0, 0); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 2, 0); break; case 'A': case 'O': fprintf(vlog_out, "~("); emit_expr(scope, oper1, wid, 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, " %s ", oper); emit_expr(scope, oper2, wid, 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, ")"); break; case 'p': if (! emit_power_as_shift(scope, expr, wid)) { emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, " ** "); emit_expr(scope, oper2, ivl_expr_width(oper2), 0, 0, 0); fprintf(stderr, "%s:%u: vlog95 error: Power operator is not " "supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } break; /* Convert the Verilog-A min() or max() functions. */ case 'm': case 'M': if (ivl_expr_value(expr) == IVL_VT_REAL) { /* For a real expression use the $min()/$max() function. */ if (ivl_expr_opcode(expr) == 'm') fprintf(vlog_out, "$min("); else fprintf(vlog_out, "$max("); emit_expr(scope, oper1, wid, 0, 0, 0); fprintf(vlog_out, ","); emit_expr(scope, oper2, wid, 0, 0, 0); fprintf(vlog_out, ")"); } else { /* This only works when the argument has no side effect. */ fprintf(vlog_out, "(("); emit_expr(scope, oper1, wid, 0, 0, 0); fprintf(vlog_out, ") %s (", oper); emit_expr(scope, oper2, wid, 0, 0, 0); fprintf(vlog_out, ") ? ("); emit_expr(scope, oper1, wid, 0, 0, 0); fprintf(vlog_out, ") : ("); emit_expr(scope, oper2, wid, 0, 0, 0); fprintf(vlog_out, "))"); } break; default: emit_expr(scope, oper1, wid, 0, can_skip_unsigned, 0); fprintf(vlog_out, ""); emit_expr(scope, oper2, wid, 0, can_skip_unsigned, 0); fprintf(stderr, "%s:%u: vlog95 error: Unknown expression " "operator (%c).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_opcode(expr)); vlog_errors += 1; break; } fprintf(vlog_out, ")"); } static void emit_expr_concat(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { unsigned repeat = ivl_expr_repeat(expr); unsigned idx, count = ivl_expr_parms(expr); (void)wid; /* Parameter is not used. */ if (repeat != 1) fprintf(vlog_out, "{%u", repeat); fprintf(vlog_out, "{"); count -= 1; for (idx = 0; idx < count; idx += 1) { emit_expr(scope, ivl_expr_parm(expr, idx), 0, 0, 0, 0); fprintf(vlog_out, ", "); } emit_expr(scope, ivl_expr_parm(expr, count), 0, 0, 0, 0); fprintf(vlog_out, "}"); if (repeat != 1) fprintf(vlog_out, "}"); } static void emit_expr_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { (void)wid; /* Parameter is not used. */ emit_scaled_delay(scope, ivl_expr_delay_val(expr)); } /* * An event in an expression context must be a named event. */ static void emit_expr_event(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_event_t event = ivl_expr_event(expr); ivl_scope_t ev_scope = ivl_event_scope(event); (void)wid; /* Parameter is not used. */ assert(! ivl_event_nany(event)); assert(! ivl_event_npos(event)); assert(! ivl_event_nneg(event)); emit_scope_call_path(scope, ev_scope); emit_id(ivl_event_basename(event)); } /* * A number can also be a parameter reference. If it is a parameter * reference then emit the appropriate parameter name instead of the * numeric value unless this is the actual parameter definition. */ static void emit_expr_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_parameter_t param = ivl_expr_parameter(expr); (void)wid; /* Parameter is not used. */ if (param && (param != emitting_param)) { emit_scope_call_path(scope, ivl_parameter_scope(param)); emit_id(ivl_parameter_basename(param)); } else { emit_number(ivl_expr_bits(expr), ivl_expr_width(expr), ivl_expr_signed(expr), ivl_expr_file(expr), ivl_expr_lineno(expr)); } } static void emit_expr_real_number(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_parameter_t param = ivl_expr_parameter(expr); (void)wid; /* Parameter is not used. */ if (param && (param != emitting_param)) { emit_scope_call_path(scope, ivl_parameter_scope(param)); emit_id(ivl_parameter_basename(param)); } else { emit_real_number(ivl_expr_dvalue(expr)); } } /* * Class properties are not supported in vlog95, but they can be translated. */ static void emit_class_property(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_signal_t sig = ivl_expr_signal(expr); (void)wid; /* Parameter is not used. */ emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); fprintf(vlog_out, ".%s", ivl_expr_name(expr)); } static void emit_expr_scope_piece(ivl_scope_t scope) { ivl_scope_t parent = ivl_scope_parent(scope); /* If this scope has a parent then emit it first. */ if (parent) { emit_expr_scope_piece(parent); fprintf(vlog_out, "."); } emit_id(ivl_scope_basename(scope)); } static void emit_expr_scope(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { (void)scope; /* Parameter is not used. */ (void)wid; /* Parameter is not used. */ emit_expr_scope_piece(ivl_expr_scope(expr)); } static void emit_select_name(ivl_scope_t scope, ivl_expr_t expr) { /* A select of a number is really a parameter select. */ if (ivl_expr_type(expr) == IVL_EX_NUMBER) { ivl_parameter_t param = ivl_expr_parameter(expr); if (param) { emit_scope_call_path(scope, ivl_parameter_scope(param)); emit_id(ivl_parameter_basename(param)); } else { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unable to find " "parameter for select expression \n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } } else { emit_expr(scope, expr, 0, 0, 0, 0); } } /* * Emit a packed array access as a concatenation of bit selects. */ static void emit_expr_packed(ivl_scope_t scope, ivl_expr_t sig_expr, ivl_expr_t sel_expr, unsigned wid) { unsigned idx; assert(wid > 0); fprintf(vlog_out, "{"); for (idx = wid - 1; idx > 0; idx -= 1) { emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_expr(scope, sel_expr, 0, 0, 0, 1); fprintf(vlog_out, " + %u], ", idx); } emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_expr(scope, sel_expr, 0, 0, 0, 1); fprintf(vlog_out, "]}"); } /* * Emit an indexed part select as a concatenation of bit selects. Since a * parameter in 1364-1995 is always zero based the select expression needs * to keep any scaling that was done by the compiler. */ static void emit_expr_ips(ivl_scope_t scope, ivl_expr_t sig_expr, ivl_expr_t sel_expr, ivl_select_type_t sel_type, unsigned wid, int msb, int lsb, unsigned is_param) { unsigned idx; assert(wid > 0); /* If it was not already given, note that a down index part select will * require the -pallowsigned=1 flag to get the index values correct if * the select expression is not signed. */ if ((! allow_signed ) && (sel_type == IVL_SEL_IDX_DOWN) && (! ivl_expr_signed(sel_expr))) { fprintf(stderr, "%s:%u: vlog95 note: Translating a down indexed " "part select requires the -pallowsigned=1 flag.\n", ivl_expr_file(sel_expr), ivl_expr_lineno(sel_expr)); } fprintf(vlog_out, "{"); if (msb >= lsb) { if ((sel_type == IVL_SEL_IDX_DOWN) && ! is_param) { lsb += wid - 1; msb += wid - 1; emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); for (idx = 1; idx < wid; idx += 1) { fprintf(vlog_out, ", "); emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " - %u]", idx); } fprintf(vlog_out, "}"); } else { assert((sel_type == IVL_SEL_IDX_UP) || (is_param && (sel_type == IVL_SEL_IDX_DOWN))); for (idx = wid - 1; idx > 0; idx -= 1) { emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " + %u], ", idx); } emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]}"); } } else { if ((sel_type == IVL_SEL_IDX_UP) && ! is_param) { lsb -= wid - 1; msb -= wid - 1; emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); for (idx = 1; idx < wid; idx += 1) { fprintf(vlog_out, ", "); emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " + %u]", idx); } fprintf(vlog_out, "}"); } else { assert((sel_type == IVL_SEL_IDX_DOWN) || (is_param && (sel_type == IVL_SEL_IDX_UP))); for (idx = wid - 1; idx > 0; idx -= 1) { emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " - %u], ", idx); } emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]}"); } } } static void check_select_signed(ivl_expr_t sig_expr, ivl_expr_t sel_expr, int msb, int lsb) { expr_sign_t sign_type = expr_get_sign_type(sel_expr, ivl_expr_width(sel_expr), 0, 1); char msg[64]; snprintf(msg, sizeof(msg), "%s:%u", ivl_expr_file(sel_expr), ivl_expr_lineno(sel_expr)); msg[sizeof(msg)-1] = 0; // HERE: These first two can be fixed if the compiler is enhanced to pass // the original sign information for the base expression. /* If the element has a MSB that is greater than or equal to the LSB * and the LSB is greater than zero the compiler created a signed * expression to normalize the access. This normalization will be * removed, but we cannot currently determine if the base expression * started out signed or not so any extra $signed() operators will * need to be removed manually. */ if ((msb >= lsb) && (lsb > 0) && (sign_type == NEED_SIGNED)) { fprintf(stderr, "%s: vlog95 sorry: The translation of a select " "with MSB >= LSB > 0 is not smart enough to remove " "the extra $signed() operators.\n", msg); fprintf(stderr, "%*s Any extra $signed() operators " "will need to be removed manually.\n", (int)strlen(msg), " "); vlog_errors += 1; /* If the element is not a parameter and the LSB > MSB then the cast * to signed ($signed()) from the normalization process may need to * be removed. If the select expression is a constant number then * this is not needed. */ } else if ((lsb > msb) && (ivl_expr_type(sig_expr) != IVL_EX_NUMBER) && (ivl_expr_type(sel_expr) != IVL_EX_NUMBER) && (sign_type == NEED_SIGNED)) { fprintf(stderr, "%s: vlog95 sorry: The translation of a select " "with LSB > MSB is not smart enough to remove " "the extra $signed() operators.\n", msg); fprintf(stderr, "%*s Any extra $signed() operators " "will need to be removed manually.\n", (int)strlen(msg), " "); vlog_errors += 1; /* Parameters are translated with normalization so for some of them * the -pallowsigned=1 flag is required to get the selection * expression 100% correct. */ } else if ((! allow_signed) && (ivl_expr_type(sig_expr) == IVL_EX_NUMBER)) { int pmsb, plsb; ivl_parameter_t param = ivl_expr_parameter(sig_expr); assert(param); pmsb = ivl_parameter_msb(param); plsb = ivl_parameter_lsb(param); if ((pmsb >= plsb) && (plsb > 0)) { fprintf(stderr, "%s: vlog95 note: Translating a MSB >= " "LSB > 0 parameter select requires the " "-pallowsigned=1 flag.\n", msg); } else if (plsb > pmsb) { fprintf(stderr, "%s: vlog95 note: Translating a LSB > " "MSB parameter select requires the " "-pallowsigned=1 flag.\n", msg); } } } static void emit_expr_select(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_expr_t sel_expr = ivl_expr_oper2(expr); ivl_expr_t sig_expr = ivl_expr_oper1(expr); ivl_select_type_t sel_type = ivl_expr_sel_type(expr); (void)wid; /* Parameter is not used. */ /* If this is a dynamic array or queue select, translate the * select differently. */ if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) && ((ivl_signal_data_type(ivl_expr_signal(sig_expr)) == IVL_VT_DARRAY) || (ivl_signal_data_type(ivl_expr_signal(sig_expr)) == IVL_VT_QUEUE))) { assert(sel_expr); emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_expr(scope, sel_expr, 0, 0, 0, 1); fprintf(vlog_out, "]"); return; } if (sel_expr) { unsigned width = ivl_expr_width(expr); ivl_expr_type_t type = ivl_expr_type(sig_expr); assert(width > 0); /* The compiler uses selects for some shifts. */ if (type != IVL_EX_NUMBER && type != IVL_EX_SIGNAL) { fprintf(vlog_out, "(" ); emit_select_name(scope, sig_expr); fprintf(vlog_out, " >> " ); emit_scaled_expr(scope, sel_expr, 1, 0); fprintf(vlog_out, ")" ); } else { /* A constant/parameter must be zero based in 1364-1995 * so keep the compiler generated normalization. This * does not always work for selects before the parameter * since 1364-1995 does not support signed math. */ int msb = 1; int lsb = 0; if (type == IVL_EX_SIGNAL) { get_sig_msb_lsb(ivl_expr_signal(sig_expr), &msb, &lsb); } /* A bit select. */ if (width == 1) { check_select_signed(sig_expr, sel_expr, msb, lsb); emit_select_name(scope, sig_expr); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); } else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) { /* A constant part select. */ emit_select_name(scope, sig_expr); emit_scaled_range(scope, sel_expr, width, msb, lsb); } else if (sel_type == IVL_SEL_OTHER) { /* A packed array access. */ assert(lsb == 0); assert(msb >= 0); emit_expr_packed(scope, sig_expr, sel_expr, width); } else { /* An indexed part select. */ check_select_signed(sig_expr, sel_expr, msb, lsb); emit_expr_ips(scope, sig_expr, sel_expr, sel_type, width, msb, lsb, type == IVL_EX_NUMBER); } } } else { // HERE: Should this sign extend if the expression is signed? unsigned width = ivl_expr_width(expr); unsigned sig_wid = ivl_expr_width(sig_expr); emit_expr(scope, sig_expr, sig_wid, 0, 0, 0); /* Select part of a signal when needed. */ if ((ivl_expr_type(sig_expr) == IVL_EX_SIGNAL) && (width < sig_wid)) { int msb, lsb; int64_t value; get_sig_msb_lsb(ivl_expr_signal(sig_expr), &msb, &lsb); value = lsb; if (msb >= lsb) value += width - 1; else value -= width - 1; fprintf(vlog_out, "[%"PRId64":%u]", value, lsb); } } } /* * This routine is used to emit both system and user functions. */ static void emit_expr_func(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { unsigned count = ivl_expr_parms(expr); (void)wid; /* Parameter is not used. */ if (count) { unsigned idx; fprintf(vlog_out, "("); count -= 1; for (idx = 0; idx < count; idx += 1) { // HERE: For a user function should the argument width be used here. emit_expr(scope, ivl_expr_parm(expr, idx), 0, 1, 0, 0); fprintf(vlog_out, ", "); } // HERE: For a user function should the argument width be used here. emit_expr(scope, ivl_expr_parm(expr, count), 0, 1, 0, 0); fprintf(vlog_out, ")"); /* User functions without arguments are not supported so a dummy * argument is added both here and in the definition. */ } else if (ivl_expr_type(expr) == IVL_EX_UFUNC) { fprintf(vlog_out, "(1'bx)"); } } static void emit_expr_signal(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { ivl_signal_t sig = ivl_expr_signal(expr); (void)wid; /* Parameter is not used. */ emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int lsb = ivl_signal_array_base(sig); int msb = lsb + ivl_signal_array_count(sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, ivl_expr_oper1(expr), msb, lsb); fprintf(vlog_out, "]"); } } static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, unsigned is_full_prec) { ivl_expr_t oper2 = ivl_expr_oper2(expr); ivl_expr_t oper3 = ivl_expr_oper3(expr); unsigned can_skip_unsigned = calc_can_skip_unsigned(oper2, oper3); fprintf(vlog_out, "("); emit_expr(scope, ivl_expr_oper1(expr), 0, 0, 0, 0); fprintf(vlog_out, " ? "); // HERE: Do these two emits need to use get_cast_width() like the binary // arithmetic operators? emit_expr(scope, oper2, wid, 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, " : "); emit_expr(scope, oper3, wid, 0, can_skip_unsigned, is_full_prec); fprintf(vlog_out, ")"); } static void emit_expr_unary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, unsigned is_full_prec) { const char *oper = "invalid"; ivl_expr_t oper1 = ivl_expr_oper1(expr); switch (ivl_expr_opcode(expr)) { case '-': oper = "-"; break; case '~': oper = "~"; break; case '&': oper = "&"; break; case '|': oper = "|"; break; case '^': oper = "^"; break; case 'A': oper = "~&"; break; case 'N': oper = "~|"; break; case 'X': oper = "~^"; break; case '!': oper = "!"; break; } switch (ivl_expr_opcode(expr)) { case '-': case '~': fprintf(vlog_out, "(%s", oper); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ")"); break; case '&': case '|': case '^': case 'A': case 'N': case 'X': case '!': fprintf(vlog_out, "(%s", oper); emit_expr(scope, oper1, 0, 0, 0, 0); fprintf(vlog_out, ")"); break; case '2': case 'v': case 'r': /* A cast is a noop. */ emit_expr(scope, oper1, 0, 0, 0, 0); break; case 'I': fprintf(vlog_out, "(++"); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 sorry: Pre-increment " "operator is not currently translated.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case 'i': fprintf(vlog_out, "("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, "++)"); fprintf(stderr, "%s:%u: vlog95 sorry: Post-increment " "operator is not currently translated.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case 'D': fprintf(vlog_out, "(--"); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 sorry: Pre-decrement " "operator is not currently translated.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case 'd': fprintf(vlog_out, "("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, "--)"); fprintf(stderr, "%s:%u: vlog95 sorry: Post-decrement " "operator is not currently translated.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; /* Convert the Verilog-A abs() function. */ case 'm': if (ivl_expr_value(expr) == IVL_VT_REAL) { /* For a real expression use the $abs() function. */ fprintf(vlog_out, "$abs("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ")"); } else { /* This only works when the argument has no side effect. */ fprintf(vlog_out, "(("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ") > 0 ? ("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, ") : -("); emit_expr(scope, oper1, wid, 0, 0, is_full_prec); fprintf(vlog_out, "))"); } break; default: fprintf(vlog_out, ""); emit_expr(scope, oper1, wid, 0, 0, 0); fprintf(stderr, "%s:%u: vlog95 error: Unknown unary " "operator (%c).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_opcode(expr)); vlog_errors += 1; break; } } void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid, unsigned is_lval_width, unsigned can_skip_unsigned, unsigned is_full_prec) { expr_sign_t sign_type; /* If the width is from an L-value (assignment) then the actual * expression width can be larger. */ if (is_lval_width) { unsigned expr_wid = ivl_expr_width(expr); if (wid < expr_wid) wid = expr_wid; } /* In a self-determined context the expression set the width. */ if (! wid) wid = ivl_expr_width(expr); sign_type = expr_get_sign_type(expr, wid, can_skip_unsigned, is_full_prec); /* Check to see if a $signed() or $unsigned() needs to be emitted * before the expression. */ if (sign_type == NEED_SIGNED) { fprintf(vlog_out, "$signed("); if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: $signed() is not " "supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } /* A $signed() creates a self-determined context. */ wid = 0; /* It also clears the full precision flag. */ is_full_prec = 0; } if (sign_type == NEED_UNSIGNED) { fprintf(vlog_out, "$unsigned("); if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: $unsigned() is not " "supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; } /* A $unsigned() creates a self-determined context. */ wid = 0; /* It also clears the full precision flag. */ is_full_prec = 0; } /* Emit the expression. */ switch (ivl_expr_type(expr)) { case IVL_EX_ARRAY: emit_expr_array(scope, expr, wid); break; case IVL_EX_ARRAY_PATTERN: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Array pattern expressions " "are not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_BINARY: emit_expr_binary(scope, expr, wid, is_full_prec); break; case IVL_EX_CONCAT: emit_expr_concat(scope, expr, wid); break; case IVL_EX_DELAY: emit_expr_delay(scope, expr, wid); break; case IVL_EX_ENUMTYPE: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Enum expressions " "are not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_EVENT: emit_expr_event(scope, expr, wid); break; case IVL_EX_NEW: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: New operator " "is not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_NULL: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Null operator " "is not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_NUMBER: emit_expr_number(scope, expr, wid); break; case IVL_EX_PROPERTY: emit_class_property(scope, expr, wid); break; case IVL_EX_REALNUM: emit_expr_real_number(scope, expr, wid); break; case IVL_EX_SCOPE: emit_expr_scope(scope, expr, wid); break; case IVL_EX_SELECT: emit_expr_select(scope, expr, wid); break; case IVL_EX_SFUNC: fprintf(vlog_out, "%s", ivl_expr_name(expr)); emit_expr_func(scope, expr, wid); break; case IVL_EX_SHALLOWCOPY: fprintf(vlog_out, " "); emit_expr(scope, ivl_expr_oper2(expr), wid, 0, 0, 0); fprintf(stderr, "%s:%u: vlog95 error: New operator " "is not supported.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; break; case IVL_EX_SIGNAL: emit_expr_signal(scope, expr, wid); break; case IVL_EX_STRING: emit_string(ivl_expr_string(expr)); break; case IVL_EX_TERNARY: emit_expr_ternary(scope, expr, wid, is_full_prec); break; case IVL_EX_UFUNC: emit_scope_path(scope, ivl_expr_def(expr)); emit_expr_func(scope, expr, wid); break; case IVL_EX_UNARY: emit_expr_unary(scope, expr, wid, is_full_prec); break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown expression " "type (%d).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), (int)ivl_expr_type(expr)); vlog_errors += 1; break; } /* Close the $signed() or $unsigned() if need. */ if (sign_type != NO_SIGN) fprintf(vlog_out, ")"); } iverilog-12_0/tgt-vlog95/logic_lpm.c000066400000000000000000002543211435245347300174100ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ # include # include # include "config.h" # include "vlog95_priv.h" /* * Data type used to signify if a $signed or $unsigned should be emitted. */ typedef enum lpm_sign_e { NO_SIGN = 0, NEED_SIGNED = 1, NEED_UNSIGNED = 2 } lpm_sign_t; static ivl_signal_t nexus_is_signal(ivl_scope_t scope, ivl_nexus_t nex, int*msb, int*lsb, unsigned*array_word, ivl_net_const_t*accept_const); /* * Look to see if the nexus driver is signed. */ static int nexus_driver_is_signed(ivl_scope_t scope, ivl_nexus_t nex) { int is_signed = 0; unsigned sign_set = 0; unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t t_nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); ivl_drive_t cur_drive1 = ivl_nexus_ptr_drive1(nex_ptr); ivl_drive_t cur_drive0 = ivl_nexus_ptr_drive0(nex_ptr); if ((cur_drive1 == IVL_DR_HiZ) && (cur_drive0 == IVL_DR_HiZ)) continue; /* Only one driver can set the sign information. */ assert( ! sign_set); if (t_lpm) { sign_set = 1; is_signed = ivl_lpm_signed(t_lpm); } if (t_net_const) { sign_set = 1; is_signed = ivl_const_signed(t_net_const); } if (t_nlogic) { sign_set = 1; /* A BUFZ is used to drive a local signal so look for the * local signal to get the sign information. */ if (ivl_logic_type(t_nlogic) == IVL_LO_BUFZ) { unsigned array_word = 0; int msb = 0, lsb = 0; ivl_signal_t sig; assert(ivl_logic_pins(t_nlogic) == 2); sig = nexus_is_signal(scope, ivl_logic_pin(t_nlogic, 0), &msb, &lsb, &array_word, 0); assert(sig); is_signed = ivl_signal_signed(sig); } /* The rest of the logic type are always unsigned. */ } if (t_sig) { sign_set = 1; is_signed = ivl_signal_signed(t_sig); } } return is_signed; } static unsigned get_nexus_width(ivl_nexus_t nex) { unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (sig) return ivl_signal_width(sig); } assert(0); return 0; } static lpm_sign_t lpm_get_sign_type(ivl_lpm_t lpm, unsigned can_skip_unsigned) { lpm_sign_t rtn = NO_SIGN; int opr_sign = 0; int lpm_sign = ivl_lpm_signed(lpm); switch (ivl_lpm_type(lpm)) { case IVL_LPM_SIGN_EXT: opr_sign = nexus_driver_is_signed(ivl_lpm_scope(lpm), ivl_lpm_data(lpm, 0)); break; default: opr_sign = lpm_sign; break; } /* Check to see if a $signed() or $unsigned() is needed. */ if (lpm_sign && ! opr_sign) rtn = NEED_SIGNED; if (! lpm_sign && opr_sign && ! can_skip_unsigned) rtn = NEED_UNSIGNED; return rtn; } static unsigned emit_drive(ivl_drive_t drive) { switch (drive) { case IVL_DR_HiZ: fprintf(vlog_out, "highz"); break; case IVL_DR_WEAK: fprintf(vlog_out, "weak"); break; case IVL_DR_PULL: fprintf(vlog_out, "pull"); break; case IVL_DR_STRONG: fprintf(vlog_out, "strong"); break; case IVL_DR_SUPPLY: fprintf(vlog_out, "supply"); break; default: return 1; break; } return 0; } /* * If the strength type is 2 then emit both strengths. If it is 1 then only * emit the 1 strength (pullup) and if it is 0 only emit the 0 strength * (pulldown). */ static void emit_strength(ivl_drive_t drive1, ivl_drive_t drive0, unsigned strength_type, const char *type, const char *file, unsigned lineno) { assert(strength_type <= 2); if ((strength_type == 2) && ((drive1 != IVL_DR_STRONG) || (drive0 != IVL_DR_STRONG))) { fprintf(vlog_out, " ("); if (emit_drive(drive1)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unsupported %s " "1 drive (%d)\n", file, lineno, type, (int)drive1); vlog_errors += 1; } fprintf(vlog_out, "1, "); if (emit_drive(drive0)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unsupported %s " "0 drive (%d)\n", file, lineno, type, (int)drive0); vlog_errors += 1; } fprintf(vlog_out, "0)"); } else if ((strength_type == 1) && (drive1 != IVL_DR_PULL)) { fprintf(vlog_out, " ("); if (emit_drive(drive1)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unsupported %s " "1 drive (%d)\n", file, lineno, type, (int)drive1); vlog_errors += 1; } fprintf(vlog_out, "1)"); } else if ((strength_type == 0) && (drive0 != IVL_DR_PULL)) { fprintf(vlog_out, " ("); if (emit_drive(drive0)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unsupported %s " "0 drive (%d)\n", file, lineno, type, (int)drive0); vlog_errors += 1; } fprintf(vlog_out, "0)"); } } static void emit_gate_strength(ivl_net_logic_t nlogic, unsigned strength_type) { emit_strength(ivl_logic_drive1(nlogic), ivl_logic_drive0(nlogic), strength_type, "gate", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic)); } static void emit_part_selector(int msb, int lsb) { if (msb != lsb) fprintf(vlog_out, "[%d:%d]", msb, lsb); else fprintf(vlog_out, "[%d]", lsb); } /* * Look for a single driver behind an LPM that passes strength information * and get the real drive information from it. */ static void get_unique_lpm_drive(ivl_lpm_t lpm, ivl_drive_t *drive1, ivl_drive_t *drive0) { ivl_nexus_t nex = ivl_lpm_data(lpm, 0); unsigned idx, count = ivl_nexus_ptrs(nex); unsigned have_driver = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_drive_t cur_drive1 = ivl_nexus_ptr_drive1(nex_ptr); ivl_drive_t cur_drive0 = ivl_nexus_ptr_drive0(nex_ptr); if ((cur_drive1 == IVL_DR_HiZ) && (cur_drive0 == IVL_DR_HiZ)) continue; assert(! have_driver); *drive1 = cur_drive1; *drive0 = cur_drive0; have_driver = 1; } /* This should never happen. */ if (! have_driver) { fprintf(stderr, "%s:%u: vlog95 error: Unable to find drive " "information for strength transparent LPM.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } } static void emit_lpm_strength(ivl_lpm_t lpm) { ivl_lpm_type_t type = ivl_lpm_type(lpm); ivl_drive_t drive1 = IVL_DR_STRONG; ivl_drive_t drive0 = IVL_DR_STRONG; /* This LPM object passes strength information so we need to look * for the strength information at the real driver. */ if (type == IVL_LPM_PART_PV) { get_unique_lpm_drive(lpm, &drive1, &drive0); } else { drive1 = ivl_lpm_drive1(lpm); drive0 = ivl_lpm_drive0(lpm); } emit_strength(drive1, drive0, 2, "LPM", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); } static void emit_delay(ivl_scope_t scope, ivl_expr_t rise, ivl_expr_t fall, ivl_expr_t decay, unsigned dly_count) { assert((dly_count >= 2) && (dly_count <= 3)); /* No delays. */ if (! rise) { assert(! fall); assert(! decay); return; } /* If all three delays match then we only have a single delay. */ if ((rise == fall) && (rise == decay)) { fprintf(vlog_out, " #("); emit_scaled_delayx(scope, rise, 0); fprintf(vlog_out, ")"); return; } /* If we have a gate that only supports two delays then print them. */ if (dly_count == 2) { fprintf(vlog_out, " #("); emit_scaled_delayx(scope, rise, 0); fprintf(vlog_out, ", "); emit_scaled_delayx(scope, fall, 0); fprintf(vlog_out, ")"); return; } /* What's left is a gate that supports three delays. */ fprintf(vlog_out, " #("); emit_scaled_delayx(scope, rise, 0); fprintf(vlog_out, ", "); emit_scaled_delayx(scope, fall, 0); if (decay) { fprintf(vlog_out, ", "); emit_scaled_delayx(scope, decay, 0); } fprintf(vlog_out, ")"); } static void emit_driver_delay(ivl_scope_t scope, ivl_nexus_t nex) { ivl_expr_t rise = 0; ivl_expr_t fall = 0; ivl_expr_t decay = 0; unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t t_nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_drive_t cur_drive1 = ivl_nexus_ptr_drive1(nex_ptr); ivl_drive_t cur_drive0 = ivl_nexus_ptr_drive0(nex_ptr); if ((cur_drive1 == IVL_DR_HiZ) && (cur_drive0 == IVL_DR_HiZ)) continue; /* Only one driver can set the delay. */ assert( ! rise); if (t_lpm) { rise = ivl_lpm_delay(t_lpm, 0); fall = ivl_lpm_delay(t_lpm, 1); decay = ivl_lpm_delay(t_lpm, 2); } if (t_net_const) { rise = ivl_const_delay(t_net_const, 0); fall = ivl_const_delay(t_net_const, 1); decay = ivl_const_delay(t_net_const, 2); } if (t_nlogic) { rise = ivl_logic_delay(t_nlogic, 0); fall = ivl_logic_delay(t_nlogic, 1); decay = ivl_logic_delay(t_nlogic, 2); } } emit_delay(scope, rise, fall, decay, 3); } static unsigned is_local_nexus(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count = ivl_nexus_ptrs(nex); unsigned is_local = 1; unsigned has_output_driver = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (! sig) continue; /* Check to see if there is an output or inout port * driving into the local scope. */ if ((scope == ivl_scope_parent(ivl_signal_scope(sig))) && ((ivl_signal_port(sig) == IVL_SIP_OUTPUT) || (ivl_signal_port(sig) == IVL_SIP_INOUT))) { has_output_driver = 1; continue; } if (scope != ivl_signal_scope(sig)) continue; if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) continue; if (ivl_signal_local(sig)) { is_local = 1; } else { is_local = 0; break; } } /* We return is_local=true only if there is not an output or inout * driving into this scope. This is needed since some module outputs * are combined with a concatenation and some inouts are connected * with a tran_VP. */ return is_local && !has_output_driver; } /* * This returns the nexus of the LPM if it is not a local signal. */ static ivl_nexus_t get_lpm_output(ivl_scope_t scope, ivl_lpm_t lpm) { ivl_nexus_t output = 0; switch (ivl_lpm_type(lpm)) { case IVL_LPM_ABS: case IVL_LPM_ADD: case IVL_LPM_ARRAY: case IVL_LPM_CAST_INT: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_REAL: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: case IVL_LPM_DIVIDE: case IVL_LPM_FF: case IVL_LPM_LATCH: case IVL_LPM_MOD: case IVL_LPM_MULT: case IVL_LPM_MUX: case IVL_LPM_PART_PV: case IVL_LPM_PART_VP: case IVL_LPM_POW: case IVL_LPM_RE_AND: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_XNOR: case IVL_LPM_REPEAT: case IVL_LPM_SFUNC: case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: case IVL_LPM_SIGN_EXT: case IVL_LPM_SUB: case IVL_LPM_SUBSTITUTE: case IVL_LPM_UFUNC: /* If the output of this LPM is a local signal then something * else will request that this be emitted. */ output = ivl_lpm_q(lpm); if (is_local_nexus(scope, output)) return 0; break; default: // HERE: Can this be a simple assert at some point in time? fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown LPM type (%d).\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm), (int)ivl_lpm_type(lpm)); vlog_errors += 1; return 0; } return output; } static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic); static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm, unsigned sign_extend); /* For an undriven port look for the local signal to get the nexus name. */ static void emit_nexus_port_signal(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count = ivl_nexus_ptrs(nex); ivl_signal_t sig = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) assert(0); if (t_sig) { if (scope != ivl_signal_scope(t_sig)) continue; assert(! sig); sig = t_sig; } } /* There will not be a signal for an empty port. */ if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0, 0); else fprintf(vlog_out, "/* Empty */"); } static ivl_signal_t find_local_signal(ivl_scope_t scope, ivl_nexus_t nex, unsigned *word) { unsigned idx, count = ivl_nexus_ptrs(nex); ivl_signal_t sig = 0; *word = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if (!t_sig) continue; if (ivl_signal_local(t_sig) && (ivl_signal_port(t_sig) != IVL_SIP_INPUT)) continue; if (ivl_signal_scope(t_sig) != scope) continue; assert(! sig); sig = t_sig; *word = ivl_nexus_ptr_pin(nex_ptr); } return sig; } /* * Emit the input port driving expression. */ void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count = ivl_nexus_ptrs(nex); ivl_lpm_t lpm = 0; ivl_net_const_t net_const = 0; ivl_net_logic_t nlogic = 0; ivl_signal_t sig = 0; unsigned word = 0; /* Look for the nexus driver. */ for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t t_nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) continue; if (t_lpm) { assert(! lpm); lpm = t_lpm; } if (t_net_const) { assert(! net_const); net_const = t_net_const; } if (t_nlogic) { assert(! nlogic); nlogic = t_nlogic; } if (t_sig) { assert(! sig); sig = t_sig; word = ivl_nexus_ptr_pin(nex_ptr); } } /* An LPM is driving the nexus. */ if (lpm) { assert(! net_const); assert(! nlogic); assert(! sig); /* If there is a signal in this scope that is also driven by * the LPM then use the signal instead. */ sig = find_local_signal(scope, ivl_lpm_q(lpm), &word); if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0); else emit_lpm_as_ca(scope, lpm, 0); /* A constant is driving the nexus. */ } else if (net_const) { assert( !nlogic); assert(! sig); /* If there is a signal in this scope that is also driven by * the constant then use the signal instead. */ sig = find_local_signal(scope, ivl_const_nex(net_const), &word); if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0); else emit_const_nexus(scope, net_const); /* A logic gate is driving the nexus. */ } else if (nlogic) { assert(! sig); /* If there is a signal in this scope that is also driven by * the logic then use the signal instead. */ sig = find_local_signal(scope, ivl_logic_pin(nlogic, 0), &word); if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0); else emit_logic_as_ca(scope, nlogic); /* A signal is driving the nexus. */ } else if (sig) { emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0); /* If there is no driver then look for a single signal that is * driven by this nexus that has the correct scope. This is needed * to translate top level ports. */ } else { emit_nexus_port_signal(scope, nex); } } void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD, unsigned sign_extend) { /* If there is no nexus then there is nothing to print. */ if (! nex) return; /* A local nexus only has a single driver. */ if (is_local_nexus(scope, nex)) { unsigned idx, count = ivl_nexus_ptrs(nex); unsigned must_be_sig = 0; unsigned out_of_scope_drive = 0; ivl_lpm_t lpm = 0; ivl_net_const_t net_const = 0; ivl_net_logic_t nlogic = 0; ivl_signal_t sig = 0; unsigned word = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t t_nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) { /* If we only have a single input then we want * the nexus this signal is driven by. */ if (count == 1) { must_be_sig = 1; } else continue; } if (t_lpm) { assert(! lpm); lpm = t_lpm; } if (t_net_const) { if (scope != ivl_const_scope(t_net_const)) { // HERE: Need to verify that this is not a parameter out_of_scope_drive = 1; } assert(! net_const); net_const = t_net_const; } if (t_nlogic) { assert(! nlogic); nlogic = t_nlogic; } if (t_sig) { assert(! sig); sig = t_sig; word = ivl_nexus_ptr_pin(nex_ptr); } } if (lpm) { assert(! net_const); assert(! nlogic); assert(! sig); assert(! must_be_sig); // HERE: I think we need special input code like the following. #if 0 /* If there is a signal in this scope that is also driven by * the LPM then use the signal instead. */ sig = find_local_signal(scope, ivl_lpm_q(lpm), &word); if (sig) emit_nexus_as_ca(scope, ivl_signal_nex(sig, word), 0, 0); else emit_lpm_as_ca(scope, lpm, sign_extend); #endif emit_lpm_as_ca(scope, lpm, sign_extend); } else if (net_const) { assert( !nlogic); assert(! sig); assert(! must_be_sig); if (out_of_scope_drive) { // HERE: An out of scope const drive that is not a parameter is really a // port so look for and emit the local signal name (nexus_is_signal // may work). The is_local_nexus code also needs to be changed to // not emit the port expressions as a CA. Make sure this works // correctly if the parameter is passed as a port argument. // For now report this as missing. fprintf(vlog_out, ""); } else emit_const_nexus(scope, net_const); } else if (nlogic) { assert(! sig); assert(! must_be_sig); emit_logic_as_ca(scope, nlogic); } else if (sig) { // HERE: should these be allow_UD? if (must_be_sig) { emit_nexus_as_ca(ivl_signal_scope(sig), ivl_signal_nex(sig, word), 0, 0); } else emit_name_of_nexus(scope, nex, 0); // HERE: The assert causes pr1703959 to fail. // } else assert(0); } else { fprintf(stderr, "?:?: vlog95 error: Could not emit " "nexus as a CA.\n"); vlog_errors += 1; fprintf(vlog_out, ""); } } else { emit_name_of_nexus(scope, nex, allow_UD); } } static void emit_pull_const(char value, unsigned width) { unsigned idx; fprintf(vlog_out, "%u'b", width); for (idx = 0; idx < width; idx += 1) { fprintf(vlog_out, "%c", value); } } static void emit_logic_as_ca(ivl_scope_t scope, ivl_net_logic_t nlogic) { unsigned inputs = ivl_logic_pins(nlogic) - 1; switch (ivl_logic_type(nlogic)) { case IVL_LO_AND: assert(inputs == 2); fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " & "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_BUF: case IVL_LO_BUFT: case IVL_LO_BUFZ: assert(inputs == 1); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); break; case IVL_LO_EQUIV: assert(inputs == 2); fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " ~^ "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_IMPL: assert(inputs == 2); fprintf(vlog_out, "(~"); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_NAND: assert(inputs == 2); fprintf(vlog_out, "~("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " & "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_NOR: assert(inputs == 2); fprintf(vlog_out, "~("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_NOT: assert(inputs == 1); fprintf(vlog_out, "(~ "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_OR: assert(inputs == 2); fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_XNOR: assert(inputs == 2); fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " ~^ "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LO_XOR: assert(inputs == 2); fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, " ^ "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 2), 0, 0); fprintf(vlog_out, ")"); break; /* A pull up/down at this point has been turned into an assignment * with strength so just emit the appropriate constant. */ case IVL_LO_PULLDOWN: emit_pull_const('0', ivl_logic_width(nlogic)); break; case IVL_LO_PULLUP: emit_pull_const('1', ivl_logic_width(nlogic)); break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown CA logic type " "(%d).\n", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic), (int)ivl_logic_type(nlogic)); vlog_errors += 1; } } static void emit_lpm_array(ivl_scope_t scope, ivl_lpm_t lpm) { ivl_signal_t sig = ivl_lpm_array(lpm); emit_scope_module_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); fprintf(vlog_out, "["); // HERE: Need to remove the scale to match array base instead of adding it back. emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0, 0); fprintf(vlog_out, " + %d]", ivl_signal_array_base(sig)); } static void emit_lpm_concat(ivl_scope_t scope, ivl_lpm_t lpm) { unsigned idx, count= ivl_lpm_size(lpm); ivl_nexus_t nex; fprintf(vlog_out, "{"); // HERE: Need to check for a zero repeat that was dropped from the concat. /* Check to see if this is a repeat. */ nex = ivl_lpm_data(lpm, 0); for (idx = 1; idx < count; idx += 1) { if (nex != ivl_lpm_data(lpm, idx)) break; } /* If all the nexus match then we have a repeat. */ if ((idx == count) && (count > 1)) { fprintf(vlog_out, "%u{", count); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, "}"); /* Icarus uses a concat to combine the output from multiple devices * into a single vector, because of this we need to also look for * the nexus driver outside the scope. emit_nexus_as_ca( , , 1, ) */ } else { for (idx = count-1; idx > 0; idx -= 1) { emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 1, 0); fprintf(vlog_out, ", "); } emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 0); } fprintf(vlog_out, "}"); } /* * Look for an output signal in the nexus that is driving into this scope. */ static ivl_signal_t find_output_signal(ivl_scope_t scope, ivl_nexus_t nex, unsigned*array_word) { unsigned idx, count = ivl_nexus_ptrs(nex); (void)array_word; /* Parameter is not used. */ for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if (! t_sig) continue; /* The signal must not be a driver. */ if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) continue; /* The signal must be an output. */ if (ivl_signal_port(t_sig) != IVL_SIP_OUTPUT) continue; /* The signal must be driving into this scope. */ if (ivl_scope_parent(ivl_signal_scope(t_sig)) == scope) { return t_sig; } } return 0; } static ivl_signal_t nexus_is_signal(ivl_scope_t scope, ivl_nexus_t nex, int*msb, int*lsb, unsigned*array_word, ivl_net_const_t*accept_const) { unsigned idx, count = ivl_nexus_ptrs(nex); ivl_lpm_t lpm = 0; ivl_net_const_t net_const = 0; ivl_net_logic_t nlogic = 0; ivl_signal_t sig; /* Look for a signal in the local scope first. */ sig = find_local_signal(scope, nex, array_word); if (sig) { get_sig_msb_lsb(sig, msb, lsb); return sig; } /* Now look for an output signal driving into the local scope. */ sig = find_output_signal(scope, nex, array_word); if (sig) { get_sig_msb_lsb(sig, msb, lsb); return sig; } /* Now scan the nexus looking for a driver. */ for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t t_lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t t_net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t t_nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) continue; if (t_lpm) { assert(! lpm); /* The real signal could be hidden behind a select. */ if (ivl_lpm_type(t_lpm) == IVL_LPM_PART_VP) { t_sig = nexus_is_signal(scope, ivl_lpm_data(t_lpm, 0), msb, lsb, array_word, 0); } if (t_sig) { if (*msb >= *lsb) { *lsb += ivl_lpm_base(t_lpm); *msb = *lsb + (int)ivl_lpm_width(t_lpm) - 1; } else { *lsb -= ivl_lpm_base(t_lpm); *msb = *lsb - (int)ivl_lpm_width(t_lpm) + 1; } } else lpm = t_lpm; } if (t_net_const) { assert(! net_const); net_const = t_net_const; } if (t_nlogic) { assert(! nlogic); /* The real signal could be hidden behind a BUFZ gate. */ if (ivl_logic_type(t_nlogic) == IVL_LO_BUFZ) { assert(ivl_logic_pins(t_nlogic) == 2); t_sig = nexus_is_signal(scope, ivl_logic_pin(t_nlogic, 1), msb, lsb, array_word, 0); } else nlogic = t_nlogic; } if (t_sig) { assert(! sig); sig = t_sig; /* This could be an array word so save the word. */ *array_word = ivl_nexus_ptr_pin(nex_ptr); } } if (sig) return sig; if (accept_const && net_const) { *lsb = 0; *msb = ivl_const_width(net_const) - 1; *accept_const = net_const; } return 0; } static void emit_part_name(ivl_scope_t scope, ivl_signal_t sig, unsigned array_word) { emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int array_idx = (int) array_word + ivl_signal_array_base(sig); fprintf(vlog_out, "[%d]", array_idx); } } static void emit_lpm_part_select(ivl_scope_t scope, ivl_lpm_t lpm, unsigned sign_extend) { unsigned width = ivl_lpm_width(lpm); unsigned array_word = 0; int base = ivl_lpm_base(lpm); int msb = 0, lsb = 0; ivl_signal_t sig = nexus_is_signal(scope, ivl_lpm_data(lpm, 0), &msb, &lsb, &array_word, 0); if (sign_extend && !allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: >>> operator is not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } // HERE: variable parameter select needs to be rebuilt. if (! sig) { /* Check if the compiler used a select for a shift. */ assert(base >= 0); if (base) fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); if (base) { fprintf(vlog_out, " "); if (sign_extend) fprintf(vlog_out, ">"); fprintf(vlog_out, ">> %d)", base); } return; } if (sign_extend) fprintf(vlog_out, "("); if (sign_extend) { assert(base != lsb); // HERE: This looks wrong. if (msb >= lsb) base += lsb; else base = lsb - base; emit_part_name(scope, sig, array_word); fprintf(vlog_out, " >>> %d)", base); return; } if (width == 1) { emit_part_name(scope, sig, array_word); ivl_nexus_t sel = ivl_lpm_data(lpm, 1); if (sel) { fprintf(vlog_out, "["); if ((msb >= lsb) && (lsb == 0)) { emit_nexus_as_ca(scope, sel, 0, 0); // HERE: Need to scale the select nexus. } else { fprintf(stderr, "%s:%u: vlog95 sorry: Non-zero based " "variable part selects are not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; fprintf(vlog_out, ""); } } else { /* Skip a select of the entire bit. */ if ((msb == lsb) && (base == 0)) return; fprintf(vlog_out, "["); if (msb >= lsb) base += lsb; else base = lsb - base; fprintf(vlog_out, "%d", base); } fprintf(vlog_out, "]"); } else { ivl_nexus_t sel = ivl_lpm_data(lpm, 1); if (sel) { if ((msb >= lsb) && (lsb == 0)) { unsigned idx; fprintf(vlog_out, "{"); for (idx = width-1; idx > 0; idx -= 1) { emit_part_name(scope, sig, array_word); fprintf(vlog_out, "["); emit_nexus_as_ca(scope, sel, 0, 0); fprintf(vlog_out, "+%u],", idx); } emit_part_name(scope, sig, array_word); fprintf(vlog_out, "["); emit_nexus_as_ca(scope, sel, 0, 0); fprintf(vlog_out, "]}"); // HERE: Need to scale the select nexus. } else { fprintf(stderr, "%s:%u: vlog95 sorry: Non-zero based " "variable part selects are not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; emit_part_name(scope, sig, array_word); fprintf(vlog_out, "[]"); } } else { emit_part_name(scope, sig, array_word); fprintf(vlog_out, "["); if (msb >= lsb) { base += lsb; fprintf(vlog_out, "%d:%d", base+(int)width-1, base); } else { base = lsb - base; fprintf(vlog_out, "%d:%d", base-(int)width+1, base); } fprintf(vlog_out, "]"); } } } // HERE: No support for trigger. Is this actually needed? static void emit_lpm_func(ivl_scope_t scope, ivl_lpm_t lpm) { unsigned count = ivl_lpm_size(lpm); if (count) { unsigned idx; count -= 1; fprintf(vlog_out, "("); for (idx = 0; idx < count; idx += 1) { emit_nexus_as_ca(scope, ivl_lpm_data(lpm, idx), 0, 0); fprintf(vlog_out, ", "); } emit_nexus_as_ca(scope, ivl_lpm_data(lpm, count), 0, 0); fprintf(vlog_out, ")"); } } static void emit_mux_select_bit(ivl_scope_t scope, ivl_lpm_t lpm, unsigned bit) { unsigned array_word = 0; int msb = 0, lsb = 0; ivl_signal_t sig = nexus_is_signal(scope, ivl_lpm_select(lpm), &msb, &lsb, &array_word, 0); assert(sig); emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int array_idx = (int) array_word + ivl_signal_array_base(sig); fprintf(vlog_out, "[%d]", array_idx); } if (msb >= lsb) { fprintf(vlog_out, "[%d]", lsb + (int)bit); } else { fprintf(vlog_out, "[%d]", lsb - (int)bit); } } static void emit_lpm_mux(ivl_scope_t scope, ivl_lpm_t lpm, unsigned sel_bit, unsigned offset) { assert(sel_bit < sizeof(unsigned)*8); fprintf(vlog_out, "("); emit_mux_select_bit(scope, lpm, sel_bit); fprintf(vlog_out, " ? "); if (sel_bit > 0) { emit_lpm_mux(scope, lpm, sel_bit - 1, offset + (1U << sel_bit)); fprintf(vlog_out, " : "); emit_lpm_mux(scope, lpm, sel_bit - 1, offset); } else { emit_nexus_as_ca(scope, ivl_lpm_data(lpm, offset + 1), 0, 0); fprintf(vlog_out, " : "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, offset + 0), 0, 0); } fprintf(vlog_out, ")"); } static void emit_lpm_substitute(ivl_scope_t scope, ivl_lpm_t lpm) { unsigned array_word = 0; int msb = 0, lsb = 0; unsigned base = ivl_lpm_base(lpm); unsigned width; int psb; int wid; /* Find the wider signal. Accept a constant if there's no signal. */ ivl_net_const_t net_const = 0; ivl_signal_t sig = nexus_is_signal(scope, ivl_lpm_data(lpm, 0), &msb, &lsb, &array_word, &net_const); assert(sig || net_const); // Get the width of the part being substituted. width = get_nexus_width(ivl_lpm_data(lpm, 1)); fprintf(vlog_out, "{"); if (msb >= lsb) { psb = lsb + base + width; wid = 1 + msb - psb; } else { psb = lsb - base - width; wid = 1 + psb - msb; } if (wid > 0) { if (sig) { emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int array_idx = (int) array_word + ivl_signal_array_base(sig); fprintf(vlog_out, "[%d]", array_idx); } emit_part_selector(msb, psb); } else { assert (msb >= psb); emit_number(ivl_const_bits(net_const) + psb, wid, 0, ivl_const_file(net_const), ivl_const_lineno(net_const)); } fprintf(vlog_out, ", "); } emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); if (msb >= lsb) { psb = lsb + base - 1; wid = 1 + psb - lsb; } else { psb = lsb - base + 1; wid = 1 + lsb - psb; } if (wid > 0) { fprintf(vlog_out, ", "); if (sig) { emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { int array_idx = (int) array_word + ivl_signal_array_base(sig); fprintf(vlog_out, "[%d]", array_idx); } emit_part_selector(psb, lsb); } else { assert (psb >= lsb); emit_number(ivl_const_bits(net_const), wid, 0, ivl_const_file(net_const), ivl_const_lineno(net_const)); } } fprintf(vlog_out, "}"); } static void emit_lpm_as_ca(ivl_scope_t scope, ivl_lpm_t lpm, unsigned sign_extend) { lpm_sign_t sign_type; /* Check to see if a $signed() or $unsigned() needs to be emitted * before the expression. */ sign_type = lpm_get_sign_type(lpm, 0); if (sign_type == NEED_SIGNED) { fprintf(vlog_out, "$signed("); if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: $signed() is not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } } if (sign_type == NEED_UNSIGNED) { fprintf(vlog_out, "$unsigned("); if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: $unsigned() is not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } } switch (ivl_lpm_type(lpm)) { /* Convert the Verilog-A abs() function. This only works when the * argument has no side effect. */ case IVL_LPM_ABS: // HERE: If this is a real net then use the $abs() function to get NaN to // work correctly. See the expr code. fprintf(vlog_out, "(("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ") > "); fprintf(vlog_out, "0 ? ("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ") : -("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, "))"); break; case IVL_LPM_ADD: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " + "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_ARRAY: emit_lpm_array(scope, lpm); break; case IVL_LPM_CAST_INT: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_REAL: emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 0); break; case IVL_LPM_CMP_EEQ: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " === "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_EQ: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " == "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_EQX: // HERE: Need to check that this is not a real nexus. fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " ==? "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 error: Compare wildcard equal (caseX) " "operator is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; break; case IVL_LPM_CMP_EQZ: // HERE: Need to check that this is not a real nexus. fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " == "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 error: Compare equal Z (caseZ) " "operator is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; break; case IVL_LPM_CMP_GE: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " >= "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_GT: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " > "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_NE: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " != "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_NEE: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " !== "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_CMP_WEQ: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " ==? "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 error: Wild equality " "operator is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; break; case IVL_LPM_CMP_WNE: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " !=? "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 error: Wild inequality " "operator is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; break; /* A concat-Z should never be generated, but report it as an * error if one is generated. */ case IVL_LPM_CONCATZ: fprintf(stderr, "%s:%u: vlog95 error: Transparent concatenations " "should not be generated.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; // fallthrough case IVL_LPM_CONCAT: emit_lpm_concat(scope, lpm); break; case IVL_LPM_DIVIDE: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " / "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_MOD: // HERE: Need to check if this LPM is IVL_VT_REAL. if (0) { fprintf(stderr, "%s:%u: vlog95 error: Real modulus operator " "is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " %% "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_MULT: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " * "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_MUX: if (ivl_lpm_selects(lpm) > 1) { emit_lpm_mux(scope, lpm, ivl_lpm_selects(lpm) - 1, 0); } else { fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_select(lpm), 0, 0); fprintf(vlog_out, " ? "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, " : "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); } break; case IVL_LPM_PART_PV: emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 0); break; case IVL_LPM_PART_VP: emit_lpm_part_select(scope, lpm, sign_extend); break; case IVL_LPM_POW: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " ** "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); fprintf(stderr, "%s:%u: vlog95 error: Power operator is not " "supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; break; case IVL_LPM_RE_AND: fprintf(vlog_out, "(&"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_RE_NAND: fprintf(vlog_out, "(~&"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_RE_NOR: fprintf(vlog_out, "(~|"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_RE_OR: fprintf(vlog_out, "(|"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_RE_XOR: fprintf(vlog_out, "(^"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_RE_XNOR: fprintf(vlog_out, "(~^"); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_REPEAT: fprintf(vlog_out, "{%u{", ivl_lpm_size(lpm)); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, "}}"); break; case IVL_LPM_SFUNC: fprintf(vlog_out, "%s", ivl_lpm_string(lpm)); emit_lpm_func(scope, lpm); break; case IVL_LPM_SHIFTL: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " << "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_SHIFTR: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " "); if (ivl_lpm_signed(lpm)) { if (! allow_signed) { fprintf(stderr, "%s:%u: vlog95 error: >>> operator " "is not supported.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } fprintf(vlog_out, ">"); } fprintf(vlog_out, ">> "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_SIGN_EXT: assert(! sign_extend); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 1, 1); break; case IVL_LPM_SUB: fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 0), 0, 0); fprintf(vlog_out, " - "); emit_nexus_as_ca(scope, ivl_lpm_data(lpm, 1), 0, 0); fprintf(vlog_out, ")"); break; case IVL_LPM_SUBSTITUTE: emit_lpm_substitute(scope, lpm); break; case IVL_LPM_UFUNC: emit_scope_path(scope, ivl_lpm_define(lpm)); emit_lpm_func(scope, lpm); break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown LPM type (%d).\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm), (int)ivl_lpm_type(lpm)); vlog_errors += 1; } /* Close the $signed() or $unsigned() if needed. */ if (sign_type != NO_SIGN) fprintf(vlog_out, ")"); } static void emit_posedge_dff_prim(void) { fprintf(vlog_out, "\n"); fprintf(vlog_out, "/* Icarus generated UDP to represent a synthesized " "positive edge D-FF. */\n"); fprintf(vlog_out, "primitive IVL_posedge_DFF " "(q, clk, en, d, clr, set);\n"); fprintf(vlog_out, "%*coutput q;\n", indent_incr, ' '); fprintf(vlog_out, "%*cinput clk, en, d, clr, set;\n", indent_incr, ' '); fprintf(vlog_out, "%*creg q;\n", indent_incr, ' '); fprintf(vlog_out, "%*ctable\n", indent_incr, ' '); fprintf(vlog_out, "%*cr 1 0 0 0 : ? : 0 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cr 1 1 0 0 : ? : 1 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cp 1 0 0 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cp 1 1 0 0 : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cp x 0 0 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cp x 1 0 0 : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cn ? ? 0 0 : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c* 0 ? 0 0 : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? * ? ? ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? * ? ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? * ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? ? * : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 1 : ? : 1 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 x : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 x : 0 : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 1 ? : ? : 0 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 0 : 1 : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x x : ? : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 1 : ? : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cendtable\n", indent_incr, ' '); fprintf(vlog_out, "endprimitive\n"); } static void emit_negedge_dff_prim(void) { fprintf(vlog_out, "\n"); fprintf(vlog_out, "/* Icarus generated UDP to represent a synthesized " "negative edge D-FF. */\n"); fprintf(vlog_out, "primitive IVL_negedge_DFF " "(q, clk, en, d, clr, set);\n"); fprintf(vlog_out, "%*coutput q;\n", indent_incr, ' '); fprintf(vlog_out, "%*cinput clk, en, d, clr, set;\n", indent_incr, ' '); fprintf(vlog_out, "%*creg q;\n", indent_incr, ' '); fprintf(vlog_out, "%*ctable\n", indent_incr, ' '); fprintf(vlog_out, "%*cf 1 0 0 0 : ? : 0 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cf 1 1 0 0 : ? : 1 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cn 1 0 0 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cn 1 1 0 0 : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cn x 0 0 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cn x 1 0 0 : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cp ? ? 0 0 : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c* 0 ? 0 0 : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? * ? ? ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? * ? ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? * ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? ? * : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 1 : ? : 1 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 x : 1 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 0 x : 0 : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? 1 ? : ? : 0 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 0 : 0 : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 0 : 1 : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x x : ? : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c? ? ? x 1 : ? : x ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cendtable\n", indent_incr, ' '); fprintf(vlog_out, "endprimitive\n"); } static void emit_latch_prim(void) { fprintf(vlog_out, "\n"); fprintf(vlog_out, "/* Icarus generated UDP to represent a synthesized " "LATCH. */\n"); fprintf(vlog_out, "primitive IVL_LATCH " "(q, en, d);\n"); fprintf(vlog_out, "%*coutput q;\n", indent_incr, ' '); fprintf(vlog_out, "%*cinput en, d;\n", indent_incr, ' '); fprintf(vlog_out, "%*creg q;\n", indent_incr, ' '); fprintf(vlog_out, "%*ctable\n", indent_incr, ' '); fprintf(vlog_out, "%*c 1 0 : ? : 0 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c 1 1 : ? : 1 ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*c 0 ? : ? : - ;\n", 2*indent_incr, ' '); fprintf(vlog_out, "%*cendtable\n", indent_incr, ' '); fprintf(vlog_out, "endprimitive\n"); } static unsigned need_posedge_dff_prim = 0; static unsigned need_negedge_dff_prim = 0; static unsigned need_latch_prim = 0; /* * Synthesis creates a D-FF LPM object. To allow this to be simulated as * Verilog we need to generate a D-FF UDP that is used to represent this * LPM. Since this must be included with user derived code it must be * licensed using the lesser GPL to avoid the requirement that their code * also be licensed under the GPL. We print a note that LGPL code is * being included in the output so the user can remove it if desired. * * The general idea with all this is that we want the user to be able to * simulate a synthesized D-FF, etc., but we don't want them to take the * ideas behind the primitive(s) and claim them as their own. */ void emit_icarus_generated_udps() { /* Emit the copyright information and LGPL note and then emit any * needed primitives. */ if (need_posedge_dff_prim || need_negedge_dff_prim || need_latch_prim) { fprintf(vlog_out, "\n" "/*\n" " * This is the copyright information for the following primitive(s)\n" " * (library elements).\n" " *\n" " * Copyright (C) 2011-2016 Cary R. (cygcary@yahoo.com)\n" " *\n" " * This library is free software; you can redistribute it and/or\n" " * modify it under the terms of the GNU Lesser General Public\n" " * License as published by the Free Software Foundation; either\n" " * version 2.1 of the License, or (at your option) any later version.\n" " *\n" " * This library is distributed in the hope that it will be useful,\n" " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" " * Lesser General Public License for more details.\n" " *\n" " * You should have received a copy of the GNU Lesser General Public\n" " * License along with this library; if not, write to the Free Software\n" " * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" " */\n"); fprintf(stderr, "NOTE: vlog95: Adding LGPL 2.1 primitive(s) at the end of the output file.\n"); } if (need_posedge_dff_prim) emit_posedge_dff_prim(); if (need_negedge_dff_prim) emit_negedge_dff_prim(); if (need_latch_prim) emit_latch_prim(); } static void emit_lpm_ff(ivl_scope_t scope, ivl_lpm_t lpm) { unsigned negedge = ivl_lpm_negedge(lpm); ivl_expr_t aset_expr = ivl_lpm_aset_value(lpm); ivl_expr_t sset_expr = ivl_lpm_sset_value(lpm); ivl_nexus_t nex; unsigned emitted, have_data, have_sset; const char *aset_bits = 0; const char *sset_bits = 0; /* For now we only support a width of 1 for these bits. */ if (aset_expr) { if (ivl_expr_width(aset_expr) != 1) { fprintf(stderr, "%s:%u: vlog95 sorry: FF LPMs with " "multi-bit asynchronous set values are not " "currently translated.\n", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); vlog_errors += 1; } aset_bits = ivl_expr_bits(aset_expr); } if (sset_expr) { assert(ivl_expr_width(sset_expr) == 1); sset_bits = ivl_expr_bits(sset_expr); } fprintf(vlog_out, "%*c", indent, ' '); if (negedge) { fprintf(vlog_out, "IVL_negedge_DFF"); } else { fprintf(vlog_out, "IVL_posedge_DFF"); } emit_lpm_strength(lpm); /* The lpm FF does not support any delays. */ /* The FF name is a temporary so we don't bother to print it unless * we have a range. Then we need to use a made up name. */ if (ivl_lpm_width(lpm) > 1) { fprintf(vlog_out, " synth_%p [%u:0]", lpm, ivl_lpm_width(lpm)-1U); } fprintf(vlog_out, " ("); /* Emit the q pin. */ emit_name_of_nexus(scope, ivl_lpm_q(lpm), 0); fprintf(vlog_out, ", "); /* Emit the clock pin. */ emit_nexus_as_ca(scope, ivl_lpm_clk(lpm), 0, 0); fprintf(vlog_out, ", "); /* Emit the enable pin expression(s) if needed. */ emitted = 0; nex = ivl_lpm_enable(lpm); if (nex) { emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; } nex = ivl_lpm_sync_clr(lpm); if (nex) { if (emitted) fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; } have_sset = 0; nex = ivl_lpm_sync_set(lpm); if (nex) { if (emitted) fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; have_sset = 1; } if (!emitted) fprintf(vlog_out, "1'b1"); fprintf(vlog_out, ", "); /* Emit the data pin expression(s). */ have_data = ivl_lpm_data(lpm, 0) != 0; nex = ivl_lpm_sync_clr(lpm); if (nex) { emit_nexus_as_ca(scope, nex, 0, 0); if (have_data | have_sset) fprintf(vlog_out, " & "); if (have_data & have_sset) fprintf(vlog_out, "("); } nex = ivl_lpm_sync_set(lpm); if (nex) { if (! sset_bits || (sset_bits[0] == '1')) { emit_nexus_as_ca(scope, nex, 0, 0); if (have_data) fprintf(vlog_out, " | "); } else { fprintf(vlog_out, "~"); emit_nexus_as_ca(scope, nex, 0, 0); if (have_data) fprintf(vlog_out, " & "); } } nex = ivl_lpm_data(lpm, 0); if (nex) emit_nexus_as_ca(scope, nex, 0, 0); if (have_data & have_sset) fprintf(vlog_out, ")"); fprintf(vlog_out, ", "); /* Emit the clear pin expression(s) if needed. */ emitted = 0; nex = ivl_lpm_async_clr(lpm); if (nex) { emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; } nex = ivl_lpm_async_set(lpm); if (!aset_bits || (aset_bits[0] != '0')) nex = 0; if (nex) { if (emitted) fprintf(vlog_out, " | "); emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; } if (!emitted) fprintf(vlog_out, "1'b0"); fprintf(vlog_out, ", "); /* Emit the set pin expression(s) if needed. */ nex = ivl_lpm_async_set(lpm); if (aset_bits && (aset_bits[0] != '1')) nex = 0; if (nex) emit_nexus_as_ca(scope, nex, 0, 0); else fprintf(vlog_out, "1'b0"); fprintf(vlog_out, ");\n"); /* We need to emit a primitive for this instance. */ if (negedge) need_negedge_dff_prim = 1; else need_posedge_dff_prim = 1; } static void emit_lpm_latch(ivl_scope_t scope, ivl_lpm_t lpm) { ivl_nexus_t nex; unsigned emitted; fprintf(vlog_out, "%*c", indent, ' '); fprintf(vlog_out, "IVL_LATCH"); emit_lpm_strength(lpm); /* The lpm LATCH does not support any delays. */ /* The LATCH name is a temporary so we don't bother to print it unless * we have a range. Then we need to use a made up name. */ if (ivl_lpm_width(lpm) > 1) { fprintf(vlog_out, " synth_%p [%u:0]", lpm, ivl_lpm_width(lpm)-1U); } fprintf(vlog_out, " ("); /* Emit the q pin. */ emit_name_of_nexus(scope, ivl_lpm_q(lpm), 0); fprintf(vlog_out, ", "); /* Emit the enable pin expression(s) if needed. */ emitted = 0; nex = ivl_lpm_enable(lpm); if (nex) { emit_nexus_as_ca(scope, nex, 0, 0); emitted = 1; } if (!emitted) fprintf(vlog_out, "1'b1"); fprintf(vlog_out, ", "); /* Emit the data pin expression(s). */ nex = ivl_lpm_data(lpm, 0); assert (nex); emit_nexus_as_ca(scope, nex, 0, 0); fprintf(vlog_out, ");\n"); need_latch_prim = 1; } static ivl_signal_t get_output_from_nexus(ivl_scope_t scope, ivl_nexus_t nex, int64_t*array_idx) { ivl_signal_t use_sig = 0; unsigned is_array = 0; unsigned idx, count; count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (! sig) continue; if (ivl_signal_local(sig)) { /* If the local signal is another receiver skip it. */ if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) { continue; } assert(0); } /* The signal must be in the correct scope. */ if (scope != ivl_signal_scope(sig)) continue; /* Since we are looking for the output signal it is a receiver. */ if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) { continue; } if (use_sig) { // HERE: Which one should we use? For now it's the first one found. // I believe this needs to be solved (see the inout.v test). fprintf(stderr, "%s:%u: vlog95 warning: Duplicate name (%s", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig) > 0) { int64_t tmp_idx = ivl_nexus_ptr_pin(nex_ptr); tmp_idx += ivl_signal_array_base(sig); fprintf(stderr, "[%"PRId64"]", tmp_idx); } fprintf(stderr, ") found for nexus (%s", ivl_signal_basename(use_sig)); if (is_array) fprintf(stderr, "[%"PRId64"]", *array_idx); fprintf(stderr, ")\n"); } else { /* We have a signal that can be used to find the name. */ use_sig = sig; if (ivl_signal_dimensions(sig) > 0) { is_array = 1; *array_idx = ivl_nexus_ptr_pin(nex_ptr); *array_idx += ivl_signal_array_base(sig); } } } return use_sig; } static void emit_lpm_part_pv(ivl_scope_t scope, ivl_lpm_t lpm) { unsigned width = ivl_lpm_width(lpm); int64_t array_word = 0; int base = ivl_lpm_base(lpm); int msb, lsb; ivl_signal_t sig = get_output_from_nexus(scope, ivl_lpm_q(lpm), &array_word); assert(sig); assert(ivl_lpm_data(lpm, 1) == 0); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig)) { fprintf(vlog_out, "[%"PRId64"]", array_word); } get_sig_msb_lsb(sig, &msb, &lsb); fprintf(vlog_out, "["); if (width == 1) { if (msb >= lsb) base += lsb; else base = lsb - base; fprintf(vlog_out, "%d", base); } else { if (msb >= lsb) { base += lsb; fprintf(vlog_out, "%d:%d", base+(int)width-1, base); } else { base = lsb - base; fprintf(vlog_out, "%d:%d", base-(int)width+1, base); } } fprintf(vlog_out, "]"); } static unsigned output_is_module_instantiation_input(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count = ivl_nexus_ptrs(nex); unsigned rtn = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); /* Skip drivers. */ if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) continue; ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); /* If the nexus is driving other things or signals that are * not a module instantiation input then return false. */ // HERE: debug this to see if the output can drive other things local to the // module that is being called. // if (! t_sig) return 0; if (! t_sig) continue; if (ivl_signal_port(t_sig) != IVL_SIP_INPUT) return 0; if (ivl_scope_parent(ivl_signal_scope(t_sig)) != scope) return 0; if (rtn) return 0; rtn = 1; } return rtn; } void emit_lpm(ivl_scope_t scope, ivl_lpm_t lpm) { ivl_nexus_t output = get_lpm_output(scope, lpm); ivl_lpm_type_t type = ivl_lpm_type(lpm); /* If the output is local then someone else will output this lpm. */ if (! output) return; /* If the LPM is a D-FF then we need to emit it as a UDP. */ if (type == IVL_LPM_FF) { emit_lpm_ff(scope, lpm); return; } if (type == IVL_LPM_LATCH) { emit_lpm_latch(scope, lpm); return; } // HERE: Look for a select passed to a pull device (pr2019553). /* Skip assignments to a module instantiation input. */ if (output_is_module_instantiation_input(scope, output)) return; fprintf(vlog_out, "%*cassign", indent, ' '); emit_lpm_strength(lpm); if (type == IVL_LPM_PART_PV) { emit_driver_delay(scope, ivl_lpm_data(lpm, 0)); fprintf(vlog_out, " "); emit_lpm_part_pv(scope, lpm); } else { emit_delay(scope, ivl_lpm_delay(lpm, 0), ivl_lpm_delay(lpm, 1), ivl_lpm_delay(lpm, 2), 3); fprintf(vlog_out, " "); emit_name_of_nexus(scope, output, 0); } fprintf(vlog_out, " = "); emit_lpm_as_ca(scope, lpm, 0); fprintf(vlog_out, ";"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); } fprintf(vlog_out, "\n"); } static void emit_logic_file_line(ivl_net_logic_t nlogic) { if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic)); } } /* * A BUFZ is a simple variable assignment possibly with strength and/or delay. */ static void emit_bufz(ivl_scope_t scope, ivl_net_logic_t nlogic) { assert(ivl_logic_pins(nlogic) == 2); fprintf(vlog_out, "assign"); emit_gate_strength(nlogic, 2); emit_delay(scope, ivl_logic_delay(nlogic, 0), ivl_logic_delay(nlogic, 1), ivl_logic_delay(nlogic, 2), 3); fprintf(vlog_out, " "); emit_name_of_nexus(scope, ivl_logic_pin(nlogic, 0), 0); fprintf(vlog_out, " = "); emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, 1), 0, 0); fprintf(vlog_out, ";"); emit_logic_file_line(nlogic); fprintf(vlog_out, "\n"); } static void emit_and_save_udp_name(ivl_net_logic_t nlogic){ ivl_udp_t udp = ivl_logic_udp(nlogic); assert(udp); emit_id(ivl_udp_name(udp)); add_udp_to_list(udp); } static void emit_name_of_logic_nexus(ivl_scope_t scope, ivl_net_logic_t nlogic, ivl_nexus_t nex) { if (nex) { emit_name_of_nexus(scope, nex, 0); } else { if (ivl_logic_type(nlogic) != IVL_LO_UDP) { fprintf(stderr, "%s:%u: vlog95 warning: Missing logic pin " "for (%d) named: %s.\n", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic), ivl_logic_type(nlogic), ivl_logic_basename(nlogic)); } fprintf(vlog_out, "1'bz"); } } void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic) { // HERE: We need to investigate if this is really the base of a CA. A real // gate only allows a signal or a signal bit select for the output(s) // and a scalar expression for the input. We also need to modify the // compiler to support logical 'and' and logical 'or' since they // short circuit. Verify input count. unsigned idx, count, dly_count, strength_type = 2; unsigned outputs = 1; const char *name; /* Skip gates that have a local nexus as the output since they are * part of a continuous assignment. */ if (is_local_nexus(scope, ivl_logic_pin(nlogic, 0))) return; fprintf(vlog_out, "%*c", indent, ' '); /* Check to see if this logical should really be emitted as/was * generated from a continuous assignment. */ if (ivl_logic_is_cassign(nlogic)) { unsigned pin_count = 2; if (ivl_logic_type(nlogic) != IVL_LO_NOT) pin_count += 1; assert(ivl_logic_pins(nlogic) == pin_count); fprintf(vlog_out, "assign"); emit_gate_strength(nlogic, strength_type); emit_delay(scope, ivl_logic_delay(nlogic, 0), ivl_logic_delay(nlogic, 1), ivl_logic_delay(nlogic, 2), 3); fprintf(vlog_out, " "); emit_name_of_nexus(scope, ivl_logic_pin(nlogic, 0), 0); fprintf(vlog_out, " = "); emit_logic_as_ca(scope, nlogic); fprintf(vlog_out, ";"); emit_logic_file_line(nlogic); fprintf(vlog_out, "\n"); return; } switch (ivl_logic_type(nlogic)) { case IVL_LO_AND: fprintf(vlog_out, "and"); dly_count = 2; break; case IVL_LO_BUF: fprintf(vlog_out, "buf"); dly_count = 2; outputs = 0; break; case IVL_LO_BUFIF0: fprintf(vlog_out, "bufif0"); dly_count = 3; break; case IVL_LO_BUFIF1: fprintf(vlog_out, "bufif1"); dly_count = 3; break; case IVL_LO_BUFT: return; case IVL_LO_BUFZ: emit_bufz(scope, nlogic); return; case IVL_LO_CMOS: fprintf(vlog_out, "cmos"); dly_count = 3; break; case IVL_LO_NAND: fprintf(vlog_out, "nand"); dly_count = 2; break; case IVL_LO_NMOS: fprintf(vlog_out, "nmos"); dly_count = 3; break; case IVL_LO_NOR: fprintf(vlog_out, "nor"); dly_count = 2; break; case IVL_LO_NOT: fprintf(vlog_out, "not"); dly_count = 2; outputs = 0; break; case IVL_LO_NOTIF0: fprintf(vlog_out, "notif0"); dly_count = 3; break; case IVL_LO_NOTIF1: fprintf(vlog_out, "notif1"); dly_count = 3; break; case IVL_LO_OR: fprintf(vlog_out, "or"); dly_count = 2; break; case IVL_LO_PMOS: fprintf(vlog_out, "pmos"); dly_count = 3; break; case IVL_LO_PULLDOWN: fprintf(vlog_out, "pulldown"); dly_count = 0; outputs = 0; strength_type = 0; break; case IVL_LO_PULLUP: fprintf(vlog_out, "pullup"); dly_count = 0; outputs = 0; strength_type = 1; break; case IVL_LO_RCMOS: fprintf(vlog_out, "rcmos"); dly_count = 3; break; case IVL_LO_RNMOS: fprintf(vlog_out, "rnmos"); dly_count = 3; break; case IVL_LO_RPMOS: fprintf(vlog_out, "rpmos"); dly_count = 3; break; case IVL_LO_UDP: emit_and_save_udp_name(nlogic); dly_count = 2; break; case IVL_LO_XNOR: fprintf(vlog_out, "xnor"); dly_count = 2; break; case IVL_LO_XOR: fprintf(vlog_out, "xor"); dly_count = 2; break; default: fprintf(vlog_out, "("); fprintf(stderr, "%s:%u: vlog95 error: Unsupported logic type " "(%d) named: %s.\n", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic), ivl_logic_type(nlogic), ivl_logic_basename(nlogic)); vlog_errors += 1; dly_count = 0; break; } emit_gate_strength(nlogic, strength_type); if (dly_count) emit_delay(scope, ivl_logic_delay(nlogic, 0), ivl_logic_delay(nlogic, 1), ivl_logic_delay(nlogic, 2), dly_count); // HERE: The name has the location information encoded in it. We need to // remove this and rebuild the instance array. For now we just make // this encoding a real name and create a zero based range. Need to // skip the local names _s. // This can also be an escaped id. name = ivl_logic_basename(nlogic); if (name && *name) { char *fixed_name = strdup(name); unsigned lp = strlen(name) - 1; unsigned width = ivl_logic_width(nlogic); if (fixed_name[lp] == '>') { fixed_name[lp] = 0; while (fixed_name[lp] != '.') { assert(lp > 0); lp -= 1; } fixed_name[lp] = '_'; while (fixed_name[lp] != '<') { assert(lp > 0); lp -= 1; } fixed_name[lp] = '_'; } fprintf(vlog_out, " "); emit_id(fixed_name); free(fixed_name); if (width > 1) { fprintf(vlog_out, " [%u:0]", width-1); } } fprintf(vlog_out, " ("); count = ivl_logic_pins(nlogic); count -= 1; if (outputs == 0) outputs = count; for (idx = 0; idx < outputs; idx += 1) { emit_name_of_logic_nexus(scope, nlogic, ivl_logic_pin(nlogic, idx)); fprintf(vlog_out, ", "); } for (/* None */; idx < count; idx += 1) { emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0, 0); fprintf(vlog_out, ", "); } if (strength_type == 2) { emit_nexus_as_ca(scope, ivl_logic_pin(nlogic, idx), 0, 0); } else { /* A pull gate only has a single output connection. */ assert(count == 0); emit_name_of_logic_nexus(scope, nlogic, ivl_logic_pin(nlogic, idx)); } fprintf(vlog_out, ");"); emit_logic_file_line(nlogic); fprintf(vlog_out, "\n"); } void emit_tran(ivl_scope_t scope, ivl_switch_t tran) { unsigned dly_count, pins; const char *name; fprintf(vlog_out, "%*c", indent, ' '); switch (ivl_switch_type(tran)) { case IVL_SW_RTRAN: fprintf(vlog_out, "rtran"); dly_count = 0; pins = 2; break; case IVL_SW_RTRANIF0: fprintf(vlog_out, "rtranif0"); dly_count = 3; pins = 3; break; case IVL_SW_RTRANIF1: fprintf(vlog_out, "rtranif1"); dly_count = 3; pins = 3; break; case IVL_SW_TRAN: fprintf(vlog_out, "tran"); dly_count = 0; pins = 2; break; case IVL_SW_TRANIF0: fprintf(vlog_out, "tranif0"); dly_count = 3; pins = 3; break; case IVL_SW_TRANIF1: fprintf(vlog_out, "tranif1"); dly_count = 3; pins = 3; break; case IVL_SW_TRAN_VP: default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: No supported for a TRAN_VP " "named: %s.\n", ivl_switch_file(tran), ivl_switch_lineno(tran), ivl_switch_basename(tran)); dly_count = 0; pins = 2; vlog_errors += 1; break; } if (dly_count) emit_delay(scope, ivl_switch_delay(tran, 0), ivl_switch_delay(tran, 1), ivl_switch_delay(tran, 2), dly_count); assert(pins == 2 || pins == 3); // The same problem here as for the gates above. name = ivl_switch_basename(tran); if (name && *name) { char *fixed_name = strdup(name); unsigned lp = strlen(name) - 1; unsigned width = ivl_switch_width(tran); if (fixed_name[lp] == '>') { while (fixed_name[lp] != '<') { assert(lp > 0); lp -= 1; } fixed_name[lp] = 0; } fprintf(vlog_out, " "); emit_id(fixed_name); free(fixed_name); if (width > 1) { fprintf(vlog_out, " [%u:0]", width-1); } } fprintf(vlog_out, " ("); emit_name_of_nexus(scope, ivl_switch_a(tran), 0); fprintf(vlog_out, ", "); emit_name_of_nexus(scope, ivl_switch_b(tran), 0); if (pins == 3) { fprintf(vlog_out, ", "); emit_nexus_as_ca(scope, ivl_switch_enable(tran), 0, 0); } fprintf(vlog_out, ");"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_switch_file(tran), ivl_switch_lineno(tran)); } fprintf(vlog_out, "\n"); } void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig) { ivl_nexus_t nex = ivl_signal_nex(sig, 0); unsigned idx, count = ivl_nexus_ptrs(nex); unsigned long emitted = (uintptr_t) ivl_nexus_get_private(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr); if (! net_const) continue; if (scope != ivl_const_scope(net_const)) continue; /* Found the constant so emit it if it has not been emitted. */ if (emitted) { --emitted; continue; } fprintf(vlog_out, "%*cassign", indent, ' '); emit_strength(ivl_nexus_ptr_drive1(nex_ptr), ivl_nexus_ptr_drive0(nex_ptr), 2, "assign", ivl_signal_file(sig), ivl_signal_lineno(sig)); emit_delay(scope, ivl_const_delay(net_const, 0), ivl_const_delay(net_const, 1), ivl_const_delay(net_const, 2), 3); fprintf(vlog_out, " "); emit_id(ivl_signal_basename(sig)); fprintf(vlog_out, " = "); emit_const_nexus(scope, net_const); fprintf(vlog_out, ";"); emit_sig_file_line(sig); fprintf(vlog_out, "\n"); /* Increment the emitted constant count by one. */ ivl_nexus_set_private(nex, (void *) ((uintptr_t) ivl_nexus_get_private(nex) + 1U)); return; } /* We must find the constant in the nexus. */ assert(0); } static void dump_drive(ivl_drive_t drive) { switch (drive) { case IVL_DR_HiZ: fprintf(stderr, "highz"); break; case IVL_DR_SMALL: fprintf(stderr, "small"); break; case IVL_DR_MEDIUM: fprintf(stderr, "medium"); break; case IVL_DR_WEAK: fprintf(stderr, "weak"); break; case IVL_DR_LARGE: fprintf(stderr, "large"); break; case IVL_DR_PULL: fprintf(stderr, "pull"); break; case IVL_DR_STRONG: fprintf(stderr, "strong"); break; case IVL_DR_SUPPLY: fprintf(stderr, "supply"); break; } } /* * Routine to dump the nexus information. */ void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count; if ((scope == 0) || (nex == 0)) return; count = ivl_nexus_ptrs(nex); fprintf(stderr, "Dumping nexus %p from scope: %s\n", nex, ivl_scope_name(scope)); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_lpm_t lpm = ivl_nexus_ptr_lpm(nex_ptr); ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr); ivl_net_logic_t nlogic = ivl_nexus_ptr_log(nex_ptr); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); fprintf(stderr, " %u (", idx); dump_drive(ivl_nexus_ptr_drive1(nex_ptr)); fprintf(stderr, "1 ,"); dump_drive(ivl_nexus_ptr_drive0(nex_ptr)); fprintf(stderr, "0) "); if (lpm) { ivl_scope_t lpm_scope = ivl_lpm_scope(lpm); assert(! net_const); assert(! nlogic); assert(! sig); fprintf(stderr, "LPM: "); fprintf(stderr, "{%s:%u} ", ivl_lpm_file(lpm), ivl_lpm_lineno(lpm)); if (scope != lpm_scope) fprintf(stderr, "(%s) ", ivl_scope_name(lpm_scope)); switch (ivl_lpm_type(lpm)) { case IVL_LPM_ABS: fprintf(stderr, "abs"); break; case IVL_LPM_ADD: fprintf(stderr, "add"); break; case IVL_LPM_ARRAY: fprintf(stderr, "array"); break; case IVL_LPM_CAST_INT: fprintf(stderr, ""); break; case IVL_LPM_CAST_INT2: fprintf(stderr, ""); break; case IVL_LPM_CAST_REAL: fprintf(stderr, ""); break; case IVL_LPM_CONCAT: fprintf(stderr, "concat"); break; case IVL_LPM_CONCATZ: fprintf(stderr, "concatz"); break; case IVL_LPM_CMP_EEQ: fprintf(stderr, "eeq"); break; case IVL_LPM_CMP_EQ: fprintf(stderr, "eq"); break; case IVL_LPM_CMP_GE: fprintf(stderr, "ge"); break; case IVL_LPM_CMP_GT: fprintf(stderr, "gt"); break; case IVL_LPM_CMP_NE: fprintf(stderr, "ne"); break; case IVL_LPM_CMP_NEE: fprintf(stderr, "nee"); break; case IVL_LPM_DIVIDE: fprintf(stderr, "divide"); break; case IVL_LPM_FF: fprintf(stderr, "dff"); break; case IVL_LPM_LATCH: fprintf(stderr, "latch"); break; case IVL_LPM_MOD: fprintf(stderr, "mod"); break; case IVL_LPM_MULT: fprintf(stderr, "mult"); break; case IVL_LPM_MUX: fprintf(stderr, "mux"); break; case IVL_LPM_PART_VP: fprintf(stderr, "part-VP"); fprintf(stderr, "(%u+%u)", ivl_lpm_base(lpm), ivl_lpm_width(lpm)); break; case IVL_LPM_PART_PV: fprintf(stderr, "part-PV"); break; case IVL_LPM_POW: fprintf(stderr, "pow"); break; case IVL_LPM_RE_AND: fprintf(stderr, "R-AND"); break; case IVL_LPM_RE_NAND: fprintf(stderr, "R-NAND"); break; case IVL_LPM_RE_OR: fprintf(stderr, "R-OR"); break; case IVL_LPM_RE_NOR: fprintf(stderr, "R-NOR"); break; case IVL_LPM_RE_XNOR: fprintf(stderr, "R-XNOR"); break; case IVL_LPM_RE_XOR: fprintf(stderr, "R-XOR"); break; case IVL_LPM_REPEAT: fprintf(stderr, "repeat"); break; case IVL_LPM_SFUNC: fprintf(stderr, "S-func"); break; case IVL_LPM_SHIFTL: fprintf(stderr, "shiftl"); break; case IVL_LPM_SHIFTR: fprintf(stderr, "shiftr"); break; case IVL_LPM_SIGN_EXT: fprintf(stderr, "sign"); break; case IVL_LPM_SUB: fprintf(stderr, "sub"); break; case IVL_LPM_UFUNC: fprintf(stderr, "U-func"); break; default: fprintf(stderr, "<%d>", ivl_lpm_type(lpm)); } if (ivl_lpm_signed(lpm)) fprintf(stderr, " "); } else if (net_const) { ivl_scope_t const_scope = ivl_const_scope(net_const); assert(! nlogic); assert(! sig); fprintf(stderr, "Const:"); if (scope != const_scope) { fprintf(stderr, " (%s)", ivl_scope_name(const_scope)); } if (ivl_const_signed(net_const)) fprintf(stderr, " "); } else if (nlogic) { ivl_scope_t logic_scope = ivl_logic_scope(nlogic); ivl_logic_t logic_type = ivl_logic_type(nlogic); assert(! sig); fprintf(stderr, "Logic: "); fprintf(stderr, "{%s:%u} ", ivl_logic_file(nlogic), ivl_logic_lineno(nlogic)); if (scope != logic_scope) { fprintf(stderr, "(%s) ", ivl_scope_name(logic_scope)); } switch (logic_type) { case IVL_LO_AND: fprintf(stderr, "and"); break; case IVL_LO_BUF: fprintf(stderr, "buf"); break; case IVL_LO_BUFIF0: fprintf(stderr, "bufif0"); break; case IVL_LO_BUFIF1: fprintf(stderr, "bufif1"); break; case IVL_LO_BUFT: fprintf(stderr, "buft"); break; case IVL_LO_BUFZ: fprintf(stderr, "bufz"); break; case IVL_LO_CMOS: fprintf(stderr, "cmos"); break; case IVL_LO_NAND: fprintf(stderr, "nand"); break; case IVL_LO_NMOS: fprintf(stderr, "nmos"); break; case IVL_LO_NOR: fprintf(stderr, "nor"); break; case IVL_LO_NOT: fprintf(stderr, "not"); break; case IVL_LO_NOTIF0: fprintf(stderr, "notif0"); break; case IVL_LO_NOTIF1: fprintf(stderr, "notif1"); break; case IVL_LO_OR: fprintf(stderr, "or"); break; case IVL_LO_PMOS: fprintf(stderr, "pmos"); break; case IVL_LO_PULLDOWN: fprintf(stderr, "pulldown"); break; case IVL_LO_PULLUP: fprintf(stderr, "pullup"); break; case IVL_LO_RCMOS: fprintf(stderr, "rcmos"); break; case IVL_LO_RNMOS: fprintf(stderr, "rnmos"); break; case IVL_LO_RPMOS: fprintf(stderr, "rpmos"); break; case IVL_LO_UDP: { ivl_udp_t udp = ivl_logic_udp(nlogic); assert(udp); fprintf(stderr, "UDP %s", ivl_udp_name(udp)); break; } case IVL_LO_XNOR: fprintf(stderr, "xnor"); break; case IVL_LO_XOR: fprintf(stderr, "xor"); break; default: fprintf(stderr, "<%d>", ivl_logic_type(nlogic)); } /* The BUF and NOT gates can have multiple outputs and a * single input. . */ if ((logic_type == IVL_LO_BUF) || (logic_type == IVL_LO_NOT)) { unsigned outputs = ivl_logic_pins(nlogic) - 1; if (outputs == 1) fprintf(stderr, "(1 output)"); else fprintf(stderr, "(%u outputs)", outputs); /* The rest of the gates have a single output and can * have zero or more inputs. */ } else { unsigned inputs = ivl_logic_pins(nlogic) - 1; if (inputs == 1) fprintf(stderr, "(1 input)"); else fprintf(stderr, "(%u inputs)", inputs); } } else if (sig) { ivl_scope_t sig_scope = ivl_signal_scope(sig); fprintf(stderr, "Signal: \""); if (scope != sig_scope) fprintf(stderr, "%s.", ivl_scope_name(sig_scope)); fprintf(stderr, "%s", ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "[]"); } fprintf(stderr, "\""); // HERE: Do we need to add support for an array word or is that an LPM. if (ivl_signal_local(sig)) fprintf(stderr, " {local}"); else fprintf(stderr, " {%s:%u}", ivl_signal_file(sig), ivl_signal_lineno(sig)); switch (ivl_signal_port(sig)) { case IVL_SIP_INPUT: fprintf(stderr, " input"); break; case IVL_SIP_OUTPUT: fprintf(stderr, " output"); break; case IVL_SIP_INOUT: fprintf(stderr, " inout"); break; case IVL_SIP_NONE: break; } switch (ivl_signal_type(sig)) { case IVL_SIT_NONE: fprintf(stderr, " "); break; case IVL_SIT_REG: fprintf(stderr, " reg"); break; case IVL_SIT_TRI: fprintf(stderr, " tri"); break; case IVL_SIT_TRI0: fprintf(stderr, " tri0"); break; case IVL_SIT_TRI1: fprintf(stderr, " tri1"); break; case IVL_SIT_TRIAND: fprintf(stderr, " triand"); break; case IVL_SIT_TRIOR: fprintf(stderr, " trior"); break; case IVL_SIT_UWIRE: fprintf(stderr, " uwire"); break; } switch (ivl_signal_data_type(sig)) { case IVL_VT_VOID: fprintf(stderr, " "); break; case IVL_VT_NO_TYPE: fprintf(stderr, " "); break; case IVL_VT_REAL: fprintf(stderr, " real"); break; case IVL_VT_BOOL: fprintf(stderr, " bool"); break; case IVL_VT_LOGIC: fprintf(stderr, " logic"); break; case IVL_VT_STRING: fprintf(stderr, " string"); break; case IVL_VT_DARRAY: fprintf(stderr, " dynamic array"); break; case IVL_VT_CLASS: fprintf(stderr, " class"); break; case IVL_VT_QUEUE: fprintf(stderr, " queue"); break; } if (ivl_signal_signed(sig)) fprintf(stderr, " "); } else fprintf(stderr, "Error: No/missing information!"); fprintf(stderr, " (%u)\n", ivl_nexus_ptr_pin(nex_ptr)); } } iverilog-12_0/tgt-vlog95/misc.c000066400000000000000000001014251435245347300163720ustar00rootroot00000000000000/* * Copyright (C) 2011-2020 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. */ # include # include # include # include "config.h" # include "vlog95_priv.h" # include "ivl_alloc.h" /* * Emit a constant delay that has been rescaled to the given scopes timescale. */ void emit_scaled_delay(ivl_scope_t scope, uint64_t delay) { int scale = ivl_scope_time_units(scope) - sim_precision; int pre = ivl_scope_time_units(scope) - ivl_scope_time_precision(scope); char *frac; unsigned real_dly = 0; assert(scale >= 0); assert(pre >= 0); assert(scale >= pre); frac = (char *)malloc(pre+1); frac[pre] = 0; for (/* none */; scale > 0; scale -= 1) { if (scale > pre) { assert((delay % 10) == 0); } else { frac[scale-1] = (delay % 10) + '0'; if (frac[scale-1] != '0') { real_dly = 1; } else if (!real_dly) { frac[scale-1] = 0; } } delay /= 10; } if (real_dly) { fprintf(vlog_out, "%"PRIu64".%s", delay, frac); } else { if (delay & 0xffffffff80000000) { fprintf(vlog_out, "(64'd%"PRIu64")", delay); } else { fprintf(vlog_out, "%"PRIu64, delay); } } free(frac); } static void emit_delay(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt) { /* A delay in a continuous assignment can also be a continuous * assignment expression. */ if (ivl_expr_type(expr) == IVL_EX_SIGNAL) { ivl_signal_t sig = ivl_expr_signal(expr); if (ivl_signal_local(sig)) { assert(! is_stmt); emit_nexus_as_ca(scope, ivl_signal_nex(sig, 0), 0, 0); return; } } emit_expr(scope, expr, 0, 0, 0, 1); } /* * Check to see if the bit based expression is of the form (expr) * */ static unsigned check_scaled_expr(ivl_expr_t expr, uint64_t scale, const char *msg, unsigned must_match) { uint64_t scale_val; int rtype; if ((ivl_expr_type(expr) != IVL_EX_BINARY) || (ivl_expr_opcode(expr) != '*') || (ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_NUMBER)) { fprintf(stderr, "%s:%u: vlog95 error: %s expression/value " "cannot be scaled.\n ", ivl_expr_file(expr), ivl_expr_lineno(expr), msg); vlog_errors += 1; return 0; } scale_val = get_uint64_from_number(ivl_expr_oper2(expr), &rtype); if (rtype > 0) { fprintf(stderr, "%s:%u: vlog95 error: %s expression/value " "scale coefficient was greater than 64 bits " "(%d).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg, rtype); vlog_errors += 1; return 0; } if (rtype < 0) { fprintf(stderr, "%s:%u: vlog95 error: %s expression/value " "scale coefficient has an undefined bit.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg); vlog_errors += 1; return 0; } if (scale != scale_val) { if (must_match) { fprintf(stderr, "%s:%u: vlog95 error: %s expression/value " "scale coefficient did not match expected " "value (%"PRIu64" != %"PRIu64").\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg, scale, scale_val); vlog_errors += 1; return 0; } return 2; } /* Yes, this expression is of the correct form. */ return 1; } /* * Check to see if the real expression is of the form (expr) * */ static unsigned check_scaled_real_expr(ivl_expr_t expr, double scale) { double scale_val; if ((ivl_expr_type(expr) != IVL_EX_BINARY) || (ivl_expr_opcode(expr) != '*') || (ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_REALNUM)) { fprintf(stderr, "%s:%u: vlog95 error: Variable real time unit " " expression/value cannot be scaled.\n ", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return 0; } scale_val = ivl_expr_dvalue(ivl_expr_oper2(expr)); if (scale != scale_val) { fprintf(stderr, "%s:%u: vlog95 error: Variable real time unit " "expression/value scale coefficient did not " "match expected value (%g != %g).\n", ivl_expr_file(expr), ivl_expr_lineno(expr), scale, scale_val); vlog_errors += 1; return 0; } /* Yes, this expression is of the correct form. */ return 1; } /* * Emit a constant or variable delay that has been rescaled to the given * scopes timescale. */ void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt) { ivl_expr_type_t type = ivl_expr_type(expr); if (type == IVL_EX_DELAY) { emit_scaled_delay(scope, ivl_expr_delay_val(expr)); } else if (type == IVL_EX_NUMBER) { assert(! ivl_expr_signed(expr)); int rtype; uint64_t value = get_uint64_from_number(expr, &rtype); if (rtype > 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Time value is " "greater than 64 bits (%d) and cannot be " "safely represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), rtype); vlog_errors += 1; return; } if (rtype < 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Time value has an " "undefined bit and cannot be represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } emit_scaled_delay(scope, value); } else { int exponent = ivl_scope_time_units(scope) - sim_precision; assert(exponent >= 0); if ((exponent == 0) && (type == IVL_EX_SIGNAL)) { emit_delay(scope, expr, is_stmt); /* A real delay variable is not scaled by the compiler. */ } else if (type == IVL_EX_SIGNAL) { if (is_stmt) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Only continuous " "assignment delay variables are scaled " "at run time.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } emit_delay(scope, expr, is_stmt); } else { uint64_t iscale = 1; unsigned rtn; assert(! ivl_expr_signed(expr)); /* Calculate the integer time scaling coefficient. */ while (exponent > 0) { iscale *= 10; exponent -= 1; } /* Check to see if this is an integer time value. */ rtn = check_scaled_expr(expr, iscale, "Variable time", 0); /* This may be a scaled real value. */ if (rtn == 2){ ivl_expr_t tmp_expr; uint64_t rprec = 1; /* This could be a scaled real time so calculate * the real time scaling coefficients and check * that the expression matches (statements only). */ exponent = ivl_scope_time_precision(scope) - sim_precision; assert(exponent >= 0); while (exponent > 0) { rprec *= 10; exponent -= 1; } /* Verify that the precision scaling is correct. */ if (! check_scaled_expr(expr, rprec, "Variable real time prec.", 1)) { fprintf(vlog_out, ""); return; } /* Verify that the left operator is a real to * integer cast. */ tmp_expr = ivl_expr_oper1(expr); if ((ivl_expr_type(tmp_expr) != IVL_EX_UNARY) || (ivl_expr_opcode(tmp_expr) != 'v')) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Real time " "value does not have a cast to " "integer.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return; } /* Check that the cast value is scaled correctly. */ assert(iscale >= rprec); tmp_expr = ivl_expr_oper1(tmp_expr); assert(ivl_expr_value(tmp_expr) == IVL_VT_REAL); if (! check_scaled_real_expr(tmp_expr, iscale/rprec)) { fprintf(vlog_out, ""); return; } assert(is_stmt); emit_delay(scope, ivl_expr_oper1(tmp_expr), is_stmt); return; } else if (rtn == 1) { emit_delay(scope, ivl_expr_oper1(expr), is_stmt); return; } fprintf(vlog_out, ""); } } } static int64_t get_valid_int64_from_number(ivl_expr_t expr, int *rtype, const char *msg) { int64_t value = get_int64_from_number(expr, rtype); if (*rtype > 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled %s is greater than " "64 bits (%d) and cannot be safely represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg, *rtype); vlog_errors += 1; } else if (*rtype < 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled %s has an undefined " "bit and cannot be represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg); vlog_errors += 1; } return value; } // HERE: Probably need to pass in a msg string to make this work with // indexed part selects. static unsigned is_scaled_expr(ivl_expr_t expr, int msb, int lsb) { int64_t scale_val; int rtype; /* This is as easy as removing the addition/subtraction that was * added to scale the value to be zero based, but we need to verify * that the scaling value is correct first. */ if (msb > lsb) { if ((ivl_expr_type(expr) != IVL_EX_BINARY) || ((ivl_expr_opcode(expr) != '+') && (ivl_expr_opcode(expr) != '-')) || (ivl_expr_type(ivl_expr_oper2(expr)) != IVL_EX_NUMBER)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled " "expression value cannot be scaled.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return 0; } scale_val = get_valid_int64_from_number( ivl_expr_oper2(expr), &rtype, "expression value scale coefficient"); } else { if ((ivl_expr_type(expr) != IVL_EX_BINARY) || ((ivl_expr_opcode(expr) != '+') && (ivl_expr_opcode(expr) != '-')) || (ivl_expr_type(ivl_expr_oper1(expr)) != IVL_EX_NUMBER)) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled " "expression value cannot be scaled.\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); vlog_errors += 1; return 0; } scale_val = get_valid_int64_from_number( ivl_expr_oper1(expr), &rtype, "expression value scale coefficient"); } if (rtype) return 0; if (ivl_expr_opcode(expr) == '+') scale_val *= -1; if (lsb != scale_val) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled expression value " "scaling coefficient did not match expected " "value (%d != %"PRIu64").\n", ivl_expr_file(expr), ivl_expr_lineno(expr), lsb, scale_val); vlog_errors += 1; return 0; } return 1; } static int64_t get_in_range_int64_from_number(ivl_expr_t expr, int *rtype, const char *msg) { int64_t value = get_int64_from_number(expr, rtype); if (*rtype > 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Scaled %s is greater than " "64 bits (%d) and cannot be safely represented.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), msg, *rtype); vlog_errors += 1; } return value; } void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width, int msb, int lsb) { int rtype; int64_t value = get_in_range_int64_from_number(expr, &rtype, "range value"); (void)scope; /* Parameter is not used. */ if (rtype < 0) fprintf(vlog_out, "[1'bx:1'bx]"); if (rtype) return; if (msb >= lsb) { value += lsb; fprintf(vlog_out, "[%"PRId64":%"PRId64"]", value + (int64_t)(width - 1), value); } else { value = (int64_t)lsb - value; fprintf(vlog_out, "[%"PRId64":%"PRId64"]", value - (int64_t)(width - 1), value); } } void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb) { if (msb >= lsb) { if (ivl_expr_type(expr) == IVL_EX_NUMBER) { int rtype; int64_t value = get_in_range_int64_from_number(expr, &rtype, "value"); if (rtype < 0) fprintf(vlog_out, "1'bx"); if (rtype) return; value += lsb; fprintf(vlog_out, "%"PRId64, value); } else if (lsb == 0) { /* If the LSB is zero then there is no scale. */ emit_expr(scope, expr, 0, 0, 0, 1); } else { if (is_scaled_expr(expr, msb, lsb)) { emit_expr(scope, ivl_expr_oper1(expr), 0, 0, 0, 1); } } } else { if (ivl_expr_type(expr) == IVL_EX_NUMBER) { int rtype; int64_t value = get_in_range_int64_from_number(expr, &rtype, "value"); if (rtype < 0) fprintf(vlog_out, "1'bx"); if (rtype) return; value = (int64_t)lsb - value; fprintf(vlog_out, "%"PRId64, value); } else { if (is_scaled_expr(expr, msb, lsb)) { emit_expr(scope, ivl_expr_oper2(expr), 0, 0, 0, 1); } } } } static unsigned find_signal_in_nexus(ivl_scope_t scope, ivl_nexus_t nex) { ivl_signal_t use_sig = 0; unsigned is_driver = 0; unsigned is_array = 0; int64_t array_idx = 0; unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (! sig) continue; if (ivl_signal_local(sig)) { /* If the local signal is another receiver skip it. */ if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) { continue; } assert(0); } /* We have a signal that can be used to find the name. */ if (scope == ivl_signal_scope(sig)) { if (use_sig) { /* Swap a receiver for a driver. */ if (is_driver && (ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ)) { use_sig = sig; is_driver = 0; if (ivl_signal_dimensions(sig) > 0) { is_array = 1; array_idx = ivl_nexus_ptr_pin(nex_ptr); array_idx += ivl_signal_array_base(sig); } continue; } // HERE: Which one should we use? For now it's the first one found. // I believe this needs to be solved (see the inout.v test). fprintf(stderr, "%s:%u: vlog95 warning: Duplicate " "name (%s", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig) > 0) { int64_t tmp_idx = ivl_nexus_ptr_pin(nex_ptr); tmp_idx += ivl_signal_array_base(sig); fprintf(stderr, "[%"PRId64"]", tmp_idx); } fprintf(stderr, ") found for nexus (%s", ivl_signal_basename(use_sig)); if (is_array) fprintf(stderr, "[%"PRId64"]", array_idx); fprintf(stderr, ")\n"); } else { use_sig = sig; /* This signal is a driver. */ if ((ivl_nexus_ptr_drive1(nex_ptr) != IVL_DR_HiZ) || (ivl_nexus_ptr_drive0(nex_ptr) != IVL_DR_HiZ)) { is_driver = 1; } if (ivl_signal_dimensions(sig) > 0) { is_array = 1; array_idx = ivl_nexus_ptr_pin(nex_ptr); array_idx += ivl_signal_array_base(sig); } } } } if (use_sig) { emit_id(ivl_signal_basename(use_sig)); if (is_array) fprintf(vlog_out, "[%"PRId64"]", array_idx); return 1; } return 0; } static void emit_number_as_string(ivl_net_const_t net_const) { const char *bits = ivl_const_bits(net_const); unsigned count = ivl_const_width(net_const); int idx; assert((count % 8) == 0); fprintf(vlog_out, "\""); for (idx = (int)count-1; idx >= 0; idx -= 8) { unsigned bit; char val = 0; for (bit = 0; bit < 8; bit += 1) { val |= (bits[idx-bit] == '1') ? 1 << (7-bit) : 0x00; } /* Skip any NULL bytes. */ if (val == 0) continue; /* Print some values that can be escaped. */ if (val == '"') fprintf(vlog_out, "\\\""); else if (val == '\\') fprintf(vlog_out, "\\\\"); else if (val == '\n') fprintf(vlog_out, "\\n"); else if (val == '\t') fprintf(vlog_out, "\\t"); /* Print the printable characters. */ else if (isprint((int)val)) fprintf(vlog_out, "%c", val); /* Print the non-printable characters as an octal escape. */ else fprintf(vlog_out, "\\%03o", val); } fprintf(vlog_out, "\""); } static unsigned emit_as_input(ivl_scope_t scope, ivl_net_const_t net_const) { ivl_scope_t const_scope = ivl_const_scope(net_const); ivl_scope_t parent = ivl_scope_parent(scope); /* Look to see if the constant scope is a parent of this scope. */ while (parent) { if (parent == const_scope) break; parent = ivl_scope_parent(parent); } /* If the constant scope is a parent then look for an input in * this scope and use that for the name. */ if (parent) { ivl_nexus_t nex = ivl_const_nex(net_const); unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(nex_ptr); if (sig && (ivl_signal_port(sig) == IVL_SIP_INPUT)) { emit_id(ivl_signal_basename(sig)); return 1; } } } return 0; } void emit_const_nexus(ivl_scope_t scope, ivl_net_const_t net_const) { ivl_scope_t const_scope = ivl_const_scope(net_const); unsigned idx, count, lineno; const char *file; count = ivl_scope_params(const_scope); file = ivl_const_file(net_const); lineno = ivl_const_lineno(net_const); /* Look to see if the constant matches a parameter in its scope. */ for (idx = 0; idx < count; idx += 1) { ivl_parameter_t par = ivl_scope_param(const_scope, idx); if (lineno != ivl_parameter_lineno(par)) continue; if (strcmp(file, ivl_parameter_file(par)) == 0) { /* Check that the appropriate expression bits match the * original parameter bits. */ // HERE: Verify that the values match and then print the name. // Does this work with out of scope references? Check real parameters. emit_id(ivl_parameter_basename(par)); return; } } /* If the scopes don't match then we assume this is an empty port. */ if (const_scope != scope) { /* This constant could really be from an input port. */ if (emit_as_input(scope, net_const)) return; fprintf(vlog_out, "/* Empty */"); return; } switch (ivl_const_type(net_const)) { case IVL_VT_LOGIC: case IVL_VT_BOOL: emit_number(ivl_const_bits(net_const), ivl_const_width(net_const), ivl_const_signed(net_const), ivl_const_file(net_const), ivl_const_lineno(net_const)); break; case IVL_VT_STRING: emit_number_as_string(net_const); break; case IVL_VT_REAL: emit_real_number(ivl_const_real(net_const)); break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown constant type " "(%d).\n", ivl_const_file(net_const), ivl_const_lineno(net_const), (int)ivl_const_type(net_const)); vlog_errors += 1; break; } } static unsigned find_const_nexus(ivl_scope_t scope, ivl_nexus_t nex) { unsigned idx, count; count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr); // HERE: Do we need to check for duplicates? if (net_const) { assert(! ivl_nexus_ptr_pin(nex_ptr)); emit_const_nexus(scope, net_const); return 1; } } return 0; } static unsigned find_driving_signal(ivl_scope_t scope, ivl_nexus_t nex) { ivl_signal_t sig = 0; unsigned is_array = 0; int64_t array_idx = 0; unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if (! t_sig) continue; if (ivl_signal_local(t_sig)) continue; /* An output can be used if it is driven by this nexus. */ if ((ivl_nexus_ptr_drive1(nex_ptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive0(nex_ptr) == IVL_DR_HiZ) && (ivl_signal_port(t_sig) != IVL_SIP_OUTPUT)) { continue; } /* We have a signal that can be used to find the name. */ if (sig) { // HERE: Which one should we use? For now it's the first one found. // I believe this needs to be solved (see above). fprintf(stderr, "%s:%u: vlog95 warning: Duplicate name (%s", ivl_signal_file(t_sig), ivl_signal_lineno(t_sig), ivl_signal_basename(t_sig)); if (ivl_signal_dimensions(t_sig) > 0) { int64_t tmp_idx = ivl_nexus_ptr_pin(nex_ptr); tmp_idx += ivl_signal_array_base(t_sig); fprintf(stderr, "[%"PRId64"]", tmp_idx); } fprintf(stderr, ") found for nexus (%s", ivl_signal_basename(sig)); if (is_array) fprintf(stderr, "[%"PRId64"]", array_idx); fprintf(stderr, ")\n"); } else { sig = t_sig; if (ivl_signal_dimensions(sig) > 0) { is_array = 1; array_idx = ivl_nexus_ptr_pin(nex_ptr); array_idx += ivl_signal_array_base(sig); } } } if (sig) { emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (is_array) fprintf(vlog_out, "[%"PRId64"]", array_idx); return 1; } return 0; } static unsigned is_local_input(ivl_scope_t scope, ivl_nexus_t nex) { ivl_signal_t sig = 0; unsigned idx, count = ivl_nexus_ptrs(nex); (void)scope; /* Parameter is not used. */ for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if (! t_sig) continue; if (! ivl_signal_local(t_sig)) continue; if (ivl_signal_port(t_sig) != IVL_SIP_INPUT) continue; assert(! sig); assert(ivl_signal_dimensions(t_sig) == 0); sig = t_sig; } if (sig) { fprintf(vlog_out, "ivlog%s", ivl_signal_basename(sig)); return 1; } return 0; } // HERE: Does this work correctly with an array reference created from @*? void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD) { unsigned idx; ivl_scope_t mod_scope; /* First look in the local scope for the nexus name. */ if (find_signal_in_nexus(scope, nex)) return; /* If the signal was not found in the passed scope then look in * the module scope if the passed scope was not the module scope. */ mod_scope = get_module_scope(scope); if (mod_scope != scope) { if (find_signal_in_nexus(mod_scope, nex)) return; } /* Look to see if this is a up/down reference. */ if (allow_UD && find_driving_signal(scope, nex)) return; /* If there is no signals driving this then look for a constant. */ if (find_const_nexus(scope, nex)) return; /* Module inputs that are split (arg[7:4], arg[3:0]) need to use * the local signal names. */ if (is_local_input(scope, nex)) return; // HERE: Need to check arr[var]? Can this be rebuilt? // Then look for down scopes and then any scope. For all this warn if // multiples are found in a given scope. This all needs to be before // the constant code. /* It is possible that the nexus does not have a name. First check if it drives another nexus through a transparent buffer. */ for (idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_net_logic_t nlogic = ivl_nexus_ptr_log(nex_ptr); if (nlogic && ivl_logic_type(nlogic) == IVL_LO_BUFT && ivl_logic_pin(nlogic, 1) == nex) { emit_name_of_nexus(scope, ivl_logic_pin(nlogic, 0), allow_UD); return; } } /* If not, do not print an actual name. */ fprintf(vlog_out, "/* Empty */"); // dump_nexus_information(scope, nex); } /* * This function traverses the scope tree looking for the enclosing module * scope. When it is found the module scope is returned. As far as this * translation is concerned a package is a special form of a module * definition and a class is also a top level scope. In SystemVerilog, * tasks and functions can also be top level scopes - we create a wrapper * module for these later. */ ivl_scope_t get_module_scope(ivl_scope_t scope) { while ((ivl_scope_type(scope) != IVL_SCT_MODULE) && (ivl_scope_type(scope) != IVL_SCT_PACKAGE) && (ivl_scope_type(scope) != IVL_SCT_CLASS)) { ivl_scope_t pscope = ivl_scope_parent(scope); if (pscope == 0) { if (ivl_scope_type(scope) == IVL_SCT_TASK) break; if (ivl_scope_type(scope) == IVL_SCT_FUNCTION) break; } assert(pscope); scope = pscope; } return scope; } /* * A package is emitted as a module with a special name. This routine * calculates the name for the package. The returned string must be freed * by the calling routine. */ char * get_package_name(ivl_scope_t scope) { char *package_name; const char *name = ivl_scope_basename(scope); package_name = (char *)malloc(strlen(name)+13); strcpy(package_name, "ivl_package_"); strcat(package_name, name); return package_name; } static void emit_scope_piece(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t parent = ivl_scope_parent(call_scope); /* If we are not at the top of the scope (parent != 0) and the two * scopes do not match then print the parent scope. */ if ((parent != 0) && (scope != parent)) { emit_scope_piece(scope, parent); } /* If the scope is a package then add the special part of the name. */ if (ivl_scope_type(call_scope) == IVL_SCT_PACKAGE) { char *package_name = get_package_name(call_scope); emit_id(package_name); free(package_name); /* Print the base scope. */ } else emit_id(ivl_scope_basename(call_scope)); fprintf(vlog_out, "."); } /* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then do nothing. If * the module scopes are different, but the call_scope begins with the * entire module scope of scope then we can trim the top off the call_scope * (it is a sub-scope of the module that contains scope). Otherwise we need * to print the entire path of call_scope. */ void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope = get_module_scope(scope); ivl_scope_t call_mod_scope = get_module_scope(call_scope); if (mod_scope == call_mod_scope) return; emit_scope_piece(mod_scope, call_mod_scope); } /* This is the same as emit_scope_module_path() except we need to add down * references for variables, etc. */ void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope, call_mod_scope; if (scope == call_scope) return; mod_scope = get_module_scope(scope); call_mod_scope = get_module_scope(call_scope); if (mod_scope != call_mod_scope) { emit_scope_piece(mod_scope, call_mod_scope); } else if (scope != call_scope) { ivl_scope_t parent; /* We only emit a scope path if the scope is a parent of the * call scope. */ for (parent = ivl_scope_parent(call_scope); parent != 0; parent = ivl_scope_parent(parent)) { if (parent == scope) { emit_scope_piece(scope, call_scope); return; } } } } static void emit_scope_path_piece(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t parent = ivl_scope_parent(call_scope); /* If we are not at the top of the scope (parent != 0) and the two * scopes do not match then print the parent scope. */ if ((parent != 0) && (scope != parent)) { emit_scope_path_piece(scope, parent); fprintf(vlog_out, "."); } /* If the scope is a package then add the special part of the name. */ if (ivl_scope_type(call_scope) == IVL_SCT_PACKAGE) { char *package_name = get_package_name(call_scope); emit_id(package_name); free(package_name); /* Print the base scope. */ } else emit_id(ivl_scope_basename(call_scope)); } /* * This routine emits the appropriate string to call the call_scope from the * given scope. If the module scopes for the two match then just return the * base name of the call_scope. If the module scopes are different, but the * call_scope begins with the entire module scope of scope then we can trim * the top off the call_scope (it is a sub-scope of the module that contains * scope). Otherwise we need to print the entire path of call_scope. */ void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope) { ivl_scope_t mod_scope, call_mod_scope; /* Check to see if this is a root scope task or function. */ if (ivl_scope_parent(call_scope) == 0) { fprintf(vlog_out, "ivl_root_scope_%s.", ivl_scope_basename(call_scope)); mod_scope = 0; call_mod_scope = 0; } else { mod_scope = get_module_scope(scope); call_mod_scope = get_module_scope(call_scope); } if (mod_scope == call_mod_scope) { emit_id(ivl_scope_basename(call_scope)); } else { emit_scope_path_piece(mod_scope, call_scope); } } static unsigned is_escaped(const char *id) { assert(id); /* The first digit must be alpha or '_' to be a normal id. */ if (isalpha((int)id[0]) || id[0] == '_') { unsigned idx; for (idx = 1; id[idx] != '\0'; idx += 1) { if (! (isalnum((int)id[idx]) || id[idx] == '_' || id[idx] == '$')) { return 1; } } /* Any Verilog keyword should also be escaped. */ // HERE: Create a keyword.gperf file to do this check. if ((strcmp(id, "input") == 0) || (strcmp(id, "output") == 0) ) return 1; /* We looked at all the digits, so this is a normal id. */ return 0; } return 1; } void emit_id(const char *id) { if (is_escaped(id)) fprintf(vlog_out, "\\%s ", id); else fprintf(vlog_out, "%s", id); } /* * Get the correct MSB and LSB for a signal. */ void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb) { switch (ivl_signal_packed_dimensions(sig)) { /* For a scalar we use zero for both the MSB and LSB. */ case 0: *msb = 0; *lsb = 0; break; case 1: /* For a vector we use the real MSB and LSB. */ *msb = ivl_signal_packed_msb(sig, 0); *lsb = ivl_signal_packed_lsb(sig, 0); break; /* For a packed vector we use the normalized MSB and LSB. */ default: *msb = ivl_signal_width(sig) - 1; *lsb = 0; break; } } const char*get_time_const(int time_value) { switch (time_value) { case 2: return "100s"; case 1: return "10s"; case 0: return "1s"; case -1: return "100ms"; case -2: return "10ms"; case -3: return "1ms"; case -4: return "100us"; case -5: return "10us"; case -6: return "1us"; case -7: return "100ns"; case -8: return "10ns"; case -9: return "1ns"; case -10: return "100ps"; case -11: return "10ps"; case -12: return "1ps"; case -13: return "100fs"; case -14: return "10fs"; case -15: return "1fs"; default: fprintf(stderr, "Invalid time constant value %d.\n", time_value); return "N/A"; } } iverilog-12_0/tgt-vlog95/numbers.c000066400000000000000000000306631435245347300171170ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ # include # include # include # include "config.h" # include "vlog95_priv.h" /* * Extract an int32_t value from the given bit information. If the result * type is 0 then the returned value is valid. If it is positive then the * value was too large and if it is negative then the value had undefined * bits. -2 is all bits z and -3 is all bits x. */ static int32_t get_int32_from_bits(const char *bits, unsigned nbits, unsigned is_signed, int *result_type) { unsigned trim_wid = nbits - 1; const char msb = is_signed ? bits[trim_wid] : '0'; unsigned idx; int32_t value = 0; /* Trim any duplicate bits from the MSB. */ for (/* none */; trim_wid > 0; trim_wid -= 1) { if (msb != bits[trim_wid]) { trim_wid += 1; break; } } if (trim_wid < nbits) trim_wid += 1; /* Check to see if the value is too large. */ if (trim_wid > 32U) { *result_type = trim_wid; return 0; } /* Now build the value from the bits. */ for (idx = 0; idx < trim_wid; idx += 1) { if (bits[idx] == '1') value |= (int32_t)1 << idx; else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } return 0; } } /* Sign extend as needed. */ // HERE: Need to emit 1 instead of -1 for some of the constants. // if (is_signed && (nbits > 1) && (msb == '1') && (trim_wid < 32U)) { if (is_signed && (msb == '1') && (trim_wid < 32U)) { value |= ~(((uint32_t)1 << trim_wid) - (uint32_t)1); } *result_type = 0; return value; } /* Emit the given bits as either a signed or unsigned constant. If the * bits contain an undefined value then emit them as a binary constant * otherwise emit them as a hex constant. */ static void emit_bits(const char *bits, unsigned nbits, unsigned is_signed) { unsigned has_undef = 0; assert(nbits > 0); /* Check for an undefined bit. */ for (int idx = (int)nbits-1; idx >= 0; idx -= 1) { if ((bits[idx] != '0') && (bits[idx] != '1')) { has_undef = 1; break; } } fprintf(vlog_out, "%u'", nbits); if (is_signed) fprintf(vlog_out, "s"); /* Emit as a binary constant. */ if (has_undef || (nbits < 2)) { int start = nbits - 1; char sbit = bits[start]; /* Trim extra leading bits. */ if (! is_signed && (sbit == '1')) sbit = ' '; while (start && (sbit == bits[start-1])) start -= 1; /* Print the trimmed value. */ fprintf(vlog_out, "b"); for (int idx = start; idx >= 0; idx -= 1) { fprintf(vlog_out, "%c", bits[idx]); } /* Emit as a hex constant. */ } else { unsigned start = 4*(nbits/4); unsigned result = 0; fprintf(vlog_out, "h"); /* The first digit may not be a full hex digit. */ if (start < nbits) { for (unsigned idx = start; idx < nbits; idx += 1) { if (bits[idx] == '1') result |= 1U << (idx%4); } fprintf(vlog_out, "%1x", result); } /* Now print the full hex digits. */ for (int idx = start-1; idx >= 0; idx -= 4) { result = 0; if (bits[idx] == '1') result |= 0x8; if (bits[idx-1] == '1') result |= 0x4; if (bits[idx-2] == '1') result |= 0x2; if (bits[idx-3] == '1') result |= 0x1; fprintf(vlog_out, "%1x", result); } } } void emit_number(const char *bits, unsigned nbits, unsigned is_signed, const char *file, unsigned lineno) { /* If the user is allowing signed constructs then we can emit a * signed number as a normal integer or with the 's syntax if * an integer is not appropriate. */ if (is_signed && allow_signed) { int rtype; int32_t value = get_int32_from_bits(bits, nbits, 1, &rtype); if (rtype != 0) emit_bits(bits, nbits, is_signed); else fprintf(vlog_out, "%"PRId32, value); /* Otherwise a signed value can only be 32 bits long since it can * only be represented as an integer. We can trim any matching MSB * bits to make it fit. We cannot support individual undefined * bits in the constant. */ } else if (is_signed) { int rtype; int32_t value = get_int32_from_bits(bits, nbits, 1, &rtype); if (rtype > 0) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Signed number is " "greater than 32 bits (%d) and cannot be " "safely represented.\n", file, lineno, rtype); vlog_errors += 1; } else if (rtype == -1) { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Signed number has " "an undefined bit and cannot be " "represented.\n", file, lineno); vlog_errors += 1; return; } else if (rtype == -2) { fprintf(vlog_out, "%u'bz", nbits); } else if (rtype == -3) { /* If this is a 32-bit wide constant then generate the * undefined with integers to get a signed value. */ if (nbits == 32) fprintf(vlog_out, "1/0"); else fprintf(vlog_out, "%u'bx", nbits); } else { fprintf(vlog_out, "%"PRId32, value); } /* An unsigned number is represented in hex if all the bits are * defined and it is more than a single bit otherwise it is * represented in binary form to preserve all the information. */ } else { emit_bits(bits, nbits, is_signed); } } void emit_real_number(double value) { /* Check for NaN. */ if (isnan(value)) { fprintf(vlog_out, "(0.0/0.0)"); return; } /* Check for the infinities. */ if (isinf(value)) { if (signbit(value)) fprintf(vlog_out, "(-1.0/0.0)"); else fprintf(vlog_out, "(1.0/0.0)"); return; } /* Check for +/- zero. */ if (value == 0.0) { if (signbit(value)) fprintf(vlog_out, "-0.0"); else fprintf(vlog_out, "0.0"); } else { char buffer[32]; char *cptr; unsigned len; /* Print the double to a temporary string using an extra digit. */ buffer[sizeof(buffer)-1] = 0; snprintf(buffer, sizeof(buffer), "%#.17g", value); assert(buffer[sizeof(buffer)-1] == 0); /* Check to see if there is a digit after the decimal point and * add a digit if it is missing. */ len = strlen(buffer); if (buffer[len-1] == '.') { assert((len + 1) < sizeof(buffer)); buffer[len] = '0'; len += 1; buffer[len] = 0; } /* Now trim any extra trailing zero digits. */ cptr = buffer + len - 1; while ((*cptr == '0') && (*(cptr-1) != '.')) cptr -= 1; *(cptr+1) = 0; /* Now print the processed output. */ fprintf(vlog_out, "%s", buffer); } } /* * Extract an uint64_t value from the given number expression. If the result * type is 0 then the returned value is valid. If it is positive then the * value was too large and if it is negative then the value had undefined * bits. */ uint64_t get_uint64_from_number(ivl_expr_t expr, int *result_type) { unsigned nbits = ivl_expr_width(expr); unsigned trim_wid = nbits - 1; const char *bits = ivl_expr_bits(expr); unsigned idx; uint64_t value = 0; assert(ivl_expr_type(expr) == IVL_EX_NUMBER); assert(! ivl_expr_signed(expr)); /* Trim any '0' bits from the MSB. */ for (/* none */; trim_wid > 0; trim_wid -= 1) { if ('0' != bits[trim_wid]) { trim_wid += 1; break; } } if (trim_wid < nbits) trim_wid += 1; /* Check to see if the value is too large. */ if (trim_wid > 64U) { *result_type = trim_wid; return 0; } /* Now build the value from the bits. */ for (idx = 0; idx < trim_wid; idx += 1) { if (bits[idx] == '1') value |= (uint64_t)1 << idx; else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } return 0; } } *result_type = 0; return value; } /* * Extract an int64_t value from the given number expression. If the result * type is 0 then the returned value is valid. If it is positive then the * value was too large and if it is negative then the value had undefined * bits. -2 is all bits z and -3 is all bits x. */ int64_t get_int64_from_number(ivl_expr_t expr, int *result_type) { unsigned is_signed = ivl_expr_signed(expr); unsigned nbits = ivl_expr_width(expr); unsigned trim_wid = nbits - 1; const char *bits = ivl_expr_bits(expr); const char msb = is_signed ? bits[trim_wid] : '0'; unsigned idx; int64_t value = 0; assert(ivl_expr_type(expr) == IVL_EX_NUMBER); /* Trim any duplicate bits from the MSB. */ for (/* none */; trim_wid > 0; trim_wid -= 1) { if (msb != bits[trim_wid]) { trim_wid += 1; break; } } if (trim_wid < nbits) trim_wid += 1; /* Check to see if the value is too large. */ if (trim_wid > 64U) { *result_type = trim_wid; return 0; } /* Now build the value from the bits. */ for (idx = 0; idx < trim_wid; idx += 1) { if (bits[idx] == '1') value |= (int64_t)1 << idx; else if (bits[idx] != '0') { *result_type = -1; /* If the value is entirely x/z then return -2 or -3. */ if (trim_wid == 1) { if (bits[idx] == 'x') *result_type -= 1; *result_type -= 1; } return 0; } } /* Sign extend as needed. */ if (is_signed && (msb == '1') && (trim_wid < 64U)) { value |= ~(((uint64_t)1 << trim_wid) - (uint64_t)1); } *result_type = 0; return value; } /* * Extract an int32_t value from the given number expression. If the result * type is 0 then the returned value is valid. If it is positive then the * value was too large and if it is negative then the value had undefined * bits. -2 is all bits z and -3 is all bits x. */ int32_t get_int32_from_number(ivl_expr_t expr, int *result_type) { assert(ivl_expr_type(expr) == IVL_EX_NUMBER); return get_int32_from_bits(ivl_expr_bits(expr), ivl_expr_width(expr), ivl_expr_signed(expr), result_type); } /* * Routine to remove two characters starting at the given address. */ static void remove_two_chars(char* str) { for (; str[2]; str += 1) { str[0] = str[2]; } str[0] = 0; } /* * Routine to print a string value as a string after removing any leading * escaped NULL bytes. */ void emit_string(const char* string) { char *buffer = strdup(string); char *bptr = buffer; char *cptr; fprintf(vlog_out, "\""); /* Prune any leading escaped NULL bytes. */ while ((bptr[0] == '\\') && (bptr[1] == '0') && (bptr[2] == '0') && (bptr[3] == '0')) bptr += 4; for (cptr = bptr; *cptr; cptr += 1) { if (*cptr == '\\') { /* Replace any \011 with \t */ if ((cptr[1] == '0') && (cptr[2] == '1') && (cptr[3] == '1')) { cptr[1] = 't'; remove_two_chars(cptr+2); cptr += 1; /* Replace any \012 with \n */ } else if ((cptr[1] == '0') && (cptr[2] == '1') && (cptr[3] == '2')) { cptr[1] = 'n'; remove_two_chars(cptr+2); cptr += 1; /* Replace any \042 with \" */ } else if ((cptr[1] == '0') && (cptr[2] == '4') && (cptr[3] == '2')) { cptr[1] = '"'; remove_two_chars(cptr+2); cptr += 1; /* Replace any \134 with \\ */ } else if ((cptr[1] == '1') && (cptr[2] == '3') && (cptr[3] == '4')) { cptr[1] = '\\'; remove_two_chars(cptr+2); cptr += 1; } else cptr += 3; } } if (*bptr) fprintf(vlog_out, "%s", bptr); free(buffer); fprintf(vlog_out, "\""); } iverilog-12_0/tgt-vlog95/scope.c000066400000000000000000001274401435245347300165550ustar00rootroot00000000000000/* * Copyright (C) 2010-2021 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. */ # include # include # include "config.h" # include "vlog95_priv.h" # include "ivl_alloc.h" const char *func_rtn_name = 0; static void emit_func_return(ivl_signal_t sig) { // Handle SV void functions. if (sig == 0) return; if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "%s:%u: vlog95 error: A function cannot return " "an array.\n", ivl_signal_file(sig), ivl_signal_lineno(sig)); vlog_errors += 1; } else if (ivl_signal_integer(sig)) { fprintf(vlog_out, " integer"); } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { fprintf(vlog_out, " real"); } else { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); if (msb != 0 || lsb != 0) fprintf(vlog_out, " [%d:%d]", msb, lsb); } } void emit_sig_file_line(ivl_signal_t sig) { if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_signal_file(sig), ivl_signal_lineno(sig)); } } static void emit_sig_id(ivl_signal_t sig) { emit_id(ivl_signal_basename(sig)); fprintf(vlog_out, ";"); emit_sig_file_line(sig); fprintf(vlog_out, "\n"); } static void emit_var_def(ivl_signal_t sig) { if (ivl_signal_local(sig)) return; fprintf(vlog_out, "%*c", indent, ' '); if (ivl_signal_integer(sig)) { fprintf(vlog_out, "integer "); emit_sig_id(sig); if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "%s:%u: vlog95 error: Integer arrays (%s) " "are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { fprintf(vlog_out, "real "); emit_sig_id(sig); if (ivl_signal_dimensions(sig) > 0) { fprintf(stderr, "%s:%u: vlog95 error: Real arrays (%s) " "are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } else if (ivl_signal_data_type(sig) == IVL_VT_STRING) { fprintf(vlog_out, "string "); emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: SystemVerilog strings (%s) " "are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) { fprintf(vlog_out, " "); emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: SystemVerilog dynamic " "arrays (%s) are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else if (ivl_signal_data_type(sig) == IVL_VT_QUEUE) { fprintf(vlog_out, " "); emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: SystemVerilog queues " "(%s) are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); fprintf(vlog_out, "reg "); if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, "signed "); } else { fprintf(stderr, "%s:%u: vlog95 error: Signed registers " "(%s) are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); emit_id(ivl_signal_basename(sig)); if (ivl_signal_dimensions(sig) > 0) { unsigned wd_count = ivl_signal_array_count(sig); int first = ivl_signal_array_base(sig); int last = first + wd_count - 1; if (ivl_signal_array_addr_swapped(sig)) { fprintf(vlog_out, " [%d:%d]", last, first); } else { fprintf(vlog_out, " [%d:%d]", first, last); } } fprintf(vlog_out, ";"); emit_sig_file_line(sig); fprintf(vlog_out, "\n"); } } /* * Keep a list of constants that drive nets and need to be emitted as * a continuous assignment. */ static ivl_signal_t *net_consts = 0; static unsigned num_net_consts = 0; static void add_net_const_to_list(ivl_signal_t net_const) { num_net_consts += 1; net_consts = realloc(net_consts, num_net_consts * sizeof(ivl_signal_t)); net_consts[num_net_consts-1] = net_const; } static unsigned emit_and_free_net_const_list(ivl_scope_t scope) { unsigned idx; for (idx = 0; idx < num_net_consts; idx += 1) { emit_signal_net_const_as_ca(scope, net_consts[idx]); } free(net_consts); net_consts = 0; idx = num_net_consts != 0; num_net_consts = 0; return idx; } static void save_net_constants(ivl_scope_t scope, ivl_signal_t sig) { ivl_nexus_t nex = ivl_signal_nex(sig, 0); unsigned idx, count = ivl_nexus_ptrs(nex); for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_net_const_t net_const = ivl_nexus_ptr_con(nex_ptr); if (! net_const) continue; if (scope != ivl_const_scope(net_const)) continue; add_net_const_to_list(sig); } } static void emit_net_def(ivl_scope_t scope, ivl_signal_t sig) { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_local(sig)) return; fprintf(vlog_out, "%*c", indent, ' '); if (ivl_signal_data_type(sig) == IVL_VT_REAL){ fprintf(vlog_out, "wire "); emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: Real nets (%s) are " "not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else if (ivl_signal_dimensions(sig) > 0) { fprintf(vlog_out, "wire "); if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); emit_sig_id(sig); fprintf(stderr, "%s:%u: vlog95 error: Array nets (%s) are " "not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else { switch (ivl_signal_type(sig)) { case IVL_SIT_TRI: case IVL_SIT_UWIRE: // HERE: Need to add support for supply nets. Probably supply strength // with a constant 0/1 driver for all the bits. fprintf(vlog_out, "wire "); break; case IVL_SIT_TRI0: fprintf(vlog_out, "tri0 "); break; case IVL_SIT_TRI1: fprintf(vlog_out, "tri1 "); break; case IVL_SIT_TRIAND: fprintf(vlog_out, "wand "); break; case IVL_SIT_TRIOR: fprintf(vlog_out, "wor "); break; default: fprintf(vlog_out, " "); fprintf(stderr, "%s:%u: vlog95 error: Unknown net type " "(%d).\n", ivl_signal_file(sig), ivl_signal_lineno(sig), (int)ivl_signal_type(sig)); vlog_errors += 1; break; } if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, "signed "); } else { fprintf(stderr, "%s:%u: vlog95 error: Signed nets (%s) " "are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } if (msb != 0 || lsb != 0) fprintf(vlog_out, "[%d:%d] ", msb, lsb); emit_sig_id(sig); /* A constant driving a net does not create an lpm or logic * element in the design so save them from the definition. */ save_net_constants(scope, sig); } } static bool scope_is_unique(ivl_scope_t scope) { unsigned int count = ivl_scope_params(scope); for (unsigned int idx = 0; idx < count; idx++) { ivl_parameter_t par = ivl_scope_param(scope, idx); if (!ivl_parameter_local(par)) { return false; } } return true; } static void emit_mangled_name(ivl_scope_t scope, unsigned root) { /* If the module has non-local parameters and it's not a root module then it * may not be unique so we create a mangled name version instead. The * mangled name is of the form: * []. */ if (!root && !scope_is_unique(scope)) { char *name; size_t len = strlen(ivl_scope_name(scope)) + strlen(ivl_scope_tname(scope)) + 3; name = (char *)malloc(len); (void) strcpy(name, ivl_scope_tname(scope)); (void) strcat(name, "["); (void) strcat(name, ivl_scope_name(scope)); (void) strcat(name, "]"); assert(name[len-1] == 0); /* Emit the mangled name as an escaped identifier. */ fprintf(vlog_out, "\\%s ", name); free(name); } else { emit_id(ivl_scope_tname(scope)); } } /* * This function is called for each process in the design so that we * can extract the processes for the given scope. */ static int find_process(ivl_process_t proc, ivl_scope_t scope) { if (scope == ivl_process_scope(proc)) emit_process(scope, proc); return 0; } void emit_scope_variables(ivl_scope_t scope) { unsigned idx, count; assert(! num_net_consts); /* Output the parameters for this scope. */ count = ivl_scope_params(scope); for (idx = 0; idx < count; idx += 1) { ivl_parameter_t par = ivl_scope_param(scope, idx); // vlog95 does not support type parameters. Places where type // parameters have been used it will be replaced with the actual // type that the module was instantiated with. Similar to // typedefs. if (ivl_parameter_is_type(par)) continue; ivl_expr_t pex = ivl_parameter_expr(par); fprintf(vlog_out, "%*cparameter ", indent, ' '); emit_id(ivl_parameter_basename(par)); fprintf(vlog_out, " = "); /* Need to emit the parameters value not its name. */ emitting_param = par; emit_expr(scope, pex, ivl_parameter_width(par), 1, 0, 0); emitting_param = 0; fprintf(vlog_out, ";"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_parameter_file(par), ivl_parameter_lineno(par)); } fprintf(vlog_out, "\n"); } if (count) fprintf(vlog_out, "\n"); /* Output the signals for this scope. */ count = ivl_scope_sigs(scope); for (idx = 0; idx < count; idx += 1) { ivl_signal_t sig = ivl_scope_sig(scope, idx); if (ivl_signal_type(sig) == IVL_SIT_REG) { /* Do not output the implicit function return register. */ if (ivl_scope_type(scope) == IVL_SCT_FUNCTION && strcmp(ivl_signal_basename(sig), ivl_scope_tname(scope)) == 0) continue; emit_var_def(sig); } else { emit_net_def(scope, sig); } } if (count) fprintf(vlog_out, "\n"); /* Output the named events for this scope. */ count = ivl_scope_events(scope); for (idx = 0; idx < count; idx += 1) { ivl_event_t event = ivl_scope_event(scope, idx); /* If this event has any type of edge sensitivity then it is * not a named event. */ if (ivl_event_nany(event)) continue; if (ivl_event_npos(event)) continue; if (ivl_event_nneg(event)) continue; fprintf(vlog_out, "%*cevent ", indent, ' '); emit_id(ivl_event_basename(event)); fprintf(vlog_out, ";"); if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_event_file(event), ivl_event_lineno(event)); } fprintf(vlog_out, "\n"); } if (count) fprintf(vlog_out, "\n"); if (emit_and_free_net_const_list(scope)) fprintf(vlog_out, "\n"); } static void emit_scope_file_line(ivl_scope_t scope) { if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_scope_file(scope), ivl_scope_lineno(scope)); } } static void emit_module_ports(ivl_scope_t scope) { unsigned idx, count = ivl_scope_ports(scope); if (count == 0) return; fprintf(vlog_out, "("); emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, 0), 0, 0); for (idx = 1; idx < count; idx += 1) { fprintf(vlog_out, ", "); emit_nexus_as_ca(scope, ivl_scope_mod_port(scope, idx), 0, 0); } fprintf(vlog_out, ")"); } static ivl_signal_t get_port_from_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned *word) { assert(nex); unsigned idx, count = ivl_nexus_ptrs(nex); ivl_signal_t sig = 0; *word = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_ptr_t nex_ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t t_sig = ivl_nexus_ptr_sig(nex_ptr); if (t_sig) { if (ivl_signal_scope(t_sig) != scope) continue; assert(! sig); sig = t_sig; *word = ivl_nexus_ptr_pin(nex_ptr); } } return sig; } static void emit_sig_type(ivl_signal_t sig) { ivl_signal_type_t type = ivl_signal_type(sig); if (ivl_signal_dimensions(sig) != 0) { fprintf(stderr, "%s:%u: vlog95 error: Array ports (%s) are not " "supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } /* Check to see if we have a variable (reg) or a net. */ if (type == IVL_SIT_REG) { /* The variable data type will be declared later, so here we just want to declare the range and whether or not it is signed. */ if (ivl_signal_integer(sig)) { /* nothing to do */ } else if (ivl_signal_data_type(sig) == IVL_VT_REAL) { /* nothing to do */ } else { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, " signed"); } else { fprintf(stderr, "%s:%u: vlog95 error: Signed " "ports (%s) are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } if (msb != 0 || lsb != 0) { fprintf(vlog_out, " [%d:%d]", msb, lsb); } } } else { assert((type == IVL_SIT_TRI) || (type == IVL_SIT_TRI0) || (type == IVL_SIT_TRI1) || (type == IVL_SIT_UWIRE)); if (ivl_signal_data_type(sig) == IVL_VT_REAL) { fprintf(stderr, "%s:%u: vlog95 error: Real net ports (%s) " "are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } else { int msb, lsb; get_sig_msb_lsb(sig, &msb, &lsb); if (ivl_signal_signed(sig)) { if (allow_signed) { fprintf(vlog_out, " signed"); } else { fprintf(stderr, "%s:%u: vlog95 error: Signed net " "ports (%s) are not supported.\n", ivl_signal_file(sig), ivl_signal_lineno(sig), ivl_signal_basename(sig)); vlog_errors += 1; } } if (msb != 0 || lsb != 0) { fprintf(vlog_out, " [%d:%d]", msb, lsb); } } } } static void emit_port(ivl_signal_t port) { assert(port); fprintf(vlog_out, "%*c", indent, ' '); switch (ivl_signal_port(port)) { case IVL_SIP_INPUT: fprintf(vlog_out, "input"); break; case IVL_SIP_OUTPUT: fprintf(vlog_out, "output"); break; case IVL_SIP_INOUT: fprintf(vlog_out, "inout"); break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown port direction (%d) " "for signal %s.\n", ivl_signal_file(port), ivl_signal_lineno(port), (int)ivl_signal_port(port), ivl_signal_basename(port)); vlog_errors += 1; break; } emit_sig_type(port); fprintf(vlog_out, " "); /* Split port (arg[7:4],arg[3:0]) are generated using local signals. */ if (ivl_signal_local(port)) { fprintf(vlog_out, "ivlog%s", ivl_signal_basename(port)); } else { emit_id(ivl_signal_basename(port)); } fprintf(vlog_out, ";"); emit_sig_file_line(port); fprintf(vlog_out, "\n"); } static void emit_module_port_defs(ivl_scope_t scope) { unsigned word, idx, count = ivl_scope_ports(scope); for (idx = 0; idx < count; idx += 1) { ivl_nexus_t nex = ivl_scope_mod_port(scope, idx); ivl_signal_t port = get_port_from_nexus(scope, nex, &word); // HERE: Do we need to use word? if (port) emit_port(port); else { fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Could not find signal " "definition for port (%u) of module %s.\n", ivl_scope_file(scope), ivl_scope_lineno(scope), idx + 1, ivl_scope_basename(scope)); vlog_errors += 1; } } if (count) fprintf(vlog_out, "\n"); } static void emit_module_call_expr(ivl_scope_t scope, unsigned idx) { unsigned word; ivl_nexus_t nex = ivl_scope_mod_port(scope, idx); ivl_signal_t port = get_port_from_nexus(scope, nex, &word); /* For an input port we need to emit the driving expression. */ if (ivl_signal_port(port) == IVL_SIP_INPUT) { emit_nexus_port_driver_as_ca(ivl_scope_parent(scope), ivl_signal_nex(port, word)); /* For an output we need to emit the signal the output is driving. */ } else { emit_nexus_as_ca(ivl_scope_parent(scope), ivl_signal_nex(port, word), 0, 0); } } static void emit_module_call_expressions(ivl_scope_t scope) { unsigned idx, count = ivl_scope_ports(scope); if (count == 0) return; emit_module_call_expr(scope, 0); for (idx = 1; idx < count; idx += 1) { fprintf(vlog_out, ", "); emit_module_call_expr(scope, idx); } } static void emit_task_func_port_defs(ivl_scope_t scope) { unsigned idx, count = ivl_scope_ports(scope); unsigned start = ivl_scope_type(scope) == IVL_SCT_FUNCTION; for (idx = start; idx < count; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); emit_port(port); } /* If the start and count are both 1 then this is a SystemVerilog * function that does not have an argument so add a dummy one. */ if ((start == 1) && (count == 1)) { fprintf(vlog_out, "%*cinput _vlog95_dummy;", indent, ' '); if (emit_file_line) fprintf(vlog_out, " /* no file/line */"); fprintf(vlog_out, "\n"); } if (count) fprintf(vlog_out, "\n"); } /* * Recursively look for the named block in the given statement. */ static int has_named_block(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, count; int rtn = 0; if (! stmt) return 0; switch (ivl_statement_type(stmt)) { /* Block or fork items can contain a named block. */ case IVL_ST_BLOCK: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: if (ivl_stmt_block_scope(stmt) == scope) return 1; count = ivl_stmt_block_count(stmt); for (idx = 0; (idx < count) && ! rtn ; idx += 1) { rtn |= has_named_block(scope, ivl_stmt_block_stmt(stmt, idx)); } break; /* Case items can contain a named block. */ case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: count = ivl_stmt_case_count(stmt); for (idx = 0; (idx < count) && ! rtn; idx += 1) { rtn |= has_named_block(scope, ivl_stmt_case_stmt(stmt, idx)); } break; /* Either the true or false clause may have a named block. */ case IVL_ST_CONDIT: rtn = has_named_block(scope, ivl_stmt_cond_true(stmt)); if (! rtn) { rtn = has_named_block(scope, ivl_stmt_cond_false(stmt)); } break; /* The looping statements may have a named block. */ case IVL_ST_DO_WHILE: case IVL_ST_FOREVER: case IVL_ST_REPEAT: case IVL_ST_WHILE: /* The delay and wait statements may have a named block. */ case IVL_ST_DELAY: case IVL_ST_DELAYX: case IVL_ST_WAIT: rtn = has_named_block(scope, ivl_stmt_sub_stmt(stmt)); break; default: /* The rest cannot have a named block. */ ; } return rtn; } /* * Look at all the processes to see if we can find one with the expected * scope. If we don't find one then we can assume the block only has * variable definitions and needs to be emitted here in the scope code. */ static int no_stmts_in_process(ivl_process_t proc, ivl_scope_t scope) { return has_named_block(scope, ivl_process_stmt(proc)); } /* * If a named block has no statements then we may need to emit it here if * there are variable definitions in the scope. We translate all this to * an initial and named begin since that is enough to hold the variables. */ static void emit_named_block_scope(ivl_scope_t scope) { unsigned idx, count = ivl_scope_events(scope); unsigned named_ev = 0; /* If there are no parameters, signals or named events then skip * this block. */ for (idx = 0; idx < count; idx += 1) { ivl_event_t event = ivl_scope_event(scope, idx); /* If this event has any type of edge sensitivity then it is * not a named event. */ if (ivl_event_nany(event)) continue; if (ivl_event_npos(event)) continue; if (ivl_event_nneg(event)) continue; named_ev = 1; break; } if ((ivl_scope_params(scope) == 0) && (ivl_scope_sigs(scope) == 0) && (named_ev == 0)) return; /* Currently we only need to emit a named block for the variables * if the parent scope is a module. This gets much more complicated * if this is not true. */ if (ivl_scope_type(ivl_scope_parent(scope)) != IVL_SCT_MODULE) return; /* Scan all the processes looking for one that matches this scope. * If a match is found then this named block was already emitted by * the process code. */ if (ivl_design_process(design, (ivl_process_f)no_stmts_in_process, scope)) return; /* A match was not found so emit the named block here to get the * variable definitions. */ fprintf(vlog_out, "\n%*cinitial begin: ", indent, ' '); emit_id(ivl_scope_tname(scope)); emit_scope_file_line(scope); fprintf(vlog_out, "\n"); indent += indent_incr; emit_scope_variables(scope); indent -= indent_incr; fprintf(vlog_out, "%*cend /* ", indent, ' '); emit_id(ivl_scope_tname(scope)); fprintf(vlog_out, " */\n"); } /* * In SystemVerilog a task, function, or block can have a process to * initialize variables. SystemVerilog requires this to be before the * initial/always blocks are processed, but there's no way to express * this in Verilog-95. */ static int find_tfb_process(ivl_process_t proc, ivl_scope_t scope) { if (scope == ivl_process_scope(proc)) { ivl_scope_t mod_scope = scope; /* A task or function or named block can only have initial * processes that are used to set local variables. */ assert(ivl_process_type(proc) == IVL_PR_INITIAL); /* Find the module scope for this task/function. */ while (ivl_scope_type(mod_scope) != IVL_SCT_MODULE && ivl_scope_type(mod_scope) != IVL_SCT_PACKAGE) { mod_scope = ivl_scope_parent(mod_scope); assert(mod_scope); } /* Emit the process in the module scope since that is where * this all started. */ emit_process(mod_scope, proc); } return 0; } /* * Emit any initial blocks for the tasks/functions/named blocks in a module. */ static int emit_tfb_process(ivl_scope_t scope, ivl_scope_t parent) { ivl_scope_type_t sc_type = ivl_scope_type(scope); (void)parent; /* Parameter is not used. */ if ((sc_type == IVL_SCT_FUNCTION) || (sc_type == IVL_SCT_TASK) || (sc_type == IVL_SCT_BEGIN) || (sc_type == IVL_SCT_FORK)) { /* Output the initial/always blocks for this module. */ ivl_design_process(design, (ivl_process_f)find_tfb_process, scope); } return 0; } static void emit_path_delay(ivl_scope_t scope, ivl_delaypath_t dpath) { unsigned idx, count = 6; uint64_t pdlys [12]; pdlys[0] = ivl_path_delay(dpath, IVL_PE_01); pdlys[1] = ivl_path_delay(dpath, IVL_PE_10); pdlys[2] = ivl_path_delay(dpath, IVL_PE_0z); pdlys[3] = ivl_path_delay(dpath, IVL_PE_z1); pdlys[4] = ivl_path_delay(dpath, IVL_PE_1z); pdlys[5] = ivl_path_delay(dpath, IVL_PE_z0); pdlys[6] = ivl_path_delay(dpath, IVL_PE_0x); pdlys[7] = ivl_path_delay(dpath, IVL_PE_x1); pdlys[8] = ivl_path_delay(dpath, IVL_PE_1x); pdlys[9] = ivl_path_delay(dpath, IVL_PE_x0); pdlys[10] = ivl_path_delay(dpath, IVL_PE_xz); pdlys[11] = ivl_path_delay(dpath, IVL_PE_zx); /* If the first six pdlys match then this may be a 1 delay form. */ if ((pdlys[0] == pdlys[1]) && (pdlys[0] == pdlys[2]) && (pdlys[0] == pdlys[3]) && (pdlys[0] == pdlys[4]) && (pdlys[0] == pdlys[5])) count = 1; /* Check to see if only a rise and fall value are given for the first * six pdlys. */ else if ((pdlys[0] == pdlys[2]) && (pdlys[0] == pdlys[3]) && (pdlys[1] == pdlys[4]) && (pdlys[1] == pdlys[5])) count = 2; /* Check to see if a rise, fall and high-Z value are given for the * first six pdlys. */ else if ((pdlys[0] == pdlys[3]) && (pdlys[1] == pdlys[5]) && (pdlys[2] == pdlys[4])) count = 3; /* Now check to see if the 'bx related pdlys match the reduced * delay form. If not then this is a twelve delay value. */ if ((pdlys[6] != ((pdlys[0] < pdlys[2]) ? pdlys[0] : pdlys[2])) || (pdlys[8] != ((pdlys[1] < pdlys[4]) ? pdlys[1] : pdlys[4])) || (pdlys[11] != ((pdlys[3] < pdlys[5]) ? pdlys[3] : pdlys[5])) || (pdlys[7] != ((pdlys[0] > pdlys[3]) ? pdlys[0] : pdlys[3])) || (pdlys[9] != ((pdlys[1] > pdlys[5]) ? pdlys[1] : pdlys[5])) || (pdlys[10] != ((pdlys[2] > pdlys[4]) ? pdlys[2] : pdlys[4]))) { count = 12; } emit_scaled_delay(scope, pdlys[0]); for(idx = 1; idx < count; idx += 1) { fprintf(vlog_out, ", "); emit_scaled_delay(scope, pdlys[idx]); } } static void emit_specify_paths(ivl_scope_t scope, ivl_signal_t sig) { unsigned idx, count = ivl_signal_npath(sig); for(idx = 0; idx < count; idx += 1) { ivl_delaypath_t dpath = ivl_signal_path(sig, idx); ivl_nexus_t cond = ivl_path_condit(dpath); ivl_nexus_t source = ivl_path_source(dpath); unsigned has_edge = 0; fprintf(vlog_out, "%*c", indent, ' '); if (cond) { fprintf(vlog_out, "if ("); emit_nexus_as_ca(scope, cond, 0, 0); fprintf(vlog_out, ") "); } else if (ivl_path_is_condit(dpath)) { fprintf(vlog_out, "ifnone "); } fprintf(vlog_out, "("); if (ivl_path_source_posedge(dpath)) { fprintf(vlog_out, "posedge "); has_edge = 1; } if (ivl_path_source_negedge(dpath)) { fprintf(vlog_out, "negedge "); has_edge = 1; } emit_nexus_as_ca(scope, source, 0, 0); if (ivl_path_is_parallel(dpath)) { fprintf(vlog_out, " =>"); } else { fprintf(vlog_out, " *>"); } /* The compiler does not keep the source expression for an edge * sensitive path so add a constant to get the syntax right. */ if (has_edge) { fprintf(vlog_out, "(%s : 1'bx /* Missing */)", ivl_signal_basename(sig)); } else { fprintf(vlog_out, "%s", ivl_signal_basename(sig)); } fprintf(vlog_out, ") = ("); emit_path_delay(scope, dpath); fprintf(vlog_out, ");\n"); } } /* * The path delay information from the specify block is attached to the * output ports. */ static void emit_specify(ivl_scope_t scope) { unsigned word, idx, count = ivl_scope_ports(scope); unsigned need_specify = 0; for (idx = 0; idx < count; idx += 1) { ivl_nexus_t nex = ivl_scope_mod_port(scope, idx); ivl_signal_t port = get_port_from_nexus(scope, nex, &word); // HERE: Do we need to use word? See emit_module_port_def(). assert(port); if (ivl_signal_npath(port)) { if (! need_specify) { fprintf(vlog_out, "\n%*cspecify\n", indent, ' '); need_specify = 1; indent += indent_incr; } emit_specify_paths(scope, port); } } if (need_specify) { indent -= indent_incr; fprintf(vlog_out, "%*cendspecify\n", indent, ' '); } } /* * Look for a disable in the statement (function body) for this scope. */ static unsigned has_func_disable(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, count, rtn = 0; /* If there is a statement then look to see if it is or has a * disable for this function scope. */ if (! stmt) return 0; assert(ivl_scope_type(scope) == IVL_SCT_FUNCTION); switch (ivl_statement_type(stmt)) { /* These are not allowed in a function. */ case IVL_ST_ASSIGN_NB: case IVL_ST_DELAY: case IVL_ST_DELAYX: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: case IVL_ST_WAIT: assert(0); break; /* These are allowed in a function and cannot have a disable. */ case IVL_ST_NOOP: case IVL_ST_ALLOC: case IVL_ST_ASSIGN: case IVL_ST_CASSIGN: case IVL_ST_DEASSIGN: case IVL_ST_FORCE: case IVL_ST_FREE: case IVL_ST_RELEASE: case IVL_ST_STASK: case IVL_ST_UTASK: // this will be generated for a SV void function case IVL_ST_TRIGGER: case IVL_ST_NB_TRIGGER: break; /* Look for a disable in each block statement. */ case IVL_ST_BLOCK: count = ivl_stmt_block_count(stmt); for (idx = 0; (idx < count) && ! rtn; idx += 1) { rtn |= has_func_disable(scope, ivl_stmt_block_stmt(stmt, idx)); } break; /* Look for a disable in each case branch. */ case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: count = ivl_stmt_case_count(stmt); for (idx = 0; (idx < count) && ! rtn; idx += 1) { rtn |= has_func_disable(scope, ivl_stmt_case_stmt(stmt, idx)); } break; /* Either the true or false clause may have a disable. */ case IVL_ST_CONDIT: rtn = has_func_disable(scope, ivl_stmt_cond_true(stmt)); if (! rtn) { rtn = has_func_disable(scope, ivl_stmt_cond_false(stmt)); } break; /* These have a single sub-statement so look for a disable there. */ case IVL_ST_DO_WHILE: case IVL_ST_FOREVER: case IVL_ST_REPEAT: case IVL_ST_WHILE: rtn = has_func_disable(scope, ivl_stmt_sub_stmt(stmt)); break; /* The function has a disable if the disable scope matches the * function scope. */ case IVL_ST_DISABLE: rtn = scope == ivl_stmt_call(stmt); break; default: fprintf(stderr, "%s:%u: vlog95 error: Unknown statement type (%d) " "in function disable check.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), (int)ivl_statement_type(stmt)); vlog_errors += 1; break; } return rtn; } /* * This is the block name used when a SystemVerilog return is used in a * function and the body does not already have an enclosing named block. * This is needed since the actual function cannot be disabled. */ static char *get_func_return_name(ivl_scope_t scope) { const char *name_func = ivl_scope_basename(scope); const char *name_head = "_ivl_"; const char *name_tail = "_return"; char *name_return; name_return = (char *)malloc(strlen(name_head) + strlen(name_func) + strlen(name_tail) + 1); name_return[0] = 0; (void) strcpy(name_return, name_head); (void) strcat(name_return, name_func); (void) strcat(name_return, name_tail); return name_return; } /* * This search method may be slow for a large structural design with a * large number of gate types. That's not what this converter was built * for so this is probably OK. If this becomes an issue then we need a * better method/data structure. */ static const char **scopes_emitted = 0; static unsigned num_scopes_emitted = 0; static unsigned scope_has_been_emitted(ivl_scope_t scope) { unsigned idx; for (idx = 0; idx < num_scopes_emitted; idx += 1) { if (! strcmp(ivl_scope_tname(scope), scopes_emitted[idx])) return 1; } return 0; } static void add_scope_to_list(ivl_scope_t scope) { num_scopes_emitted += 1; scopes_emitted = realloc(scopes_emitted, num_scopes_emitted * sizeof(char *)); scopes_emitted[num_scopes_emitted-1] = ivl_scope_tname(scope); } void free_emitted_scope_list() { free(scopes_emitted); scopes_emitted = 0; num_scopes_emitted = 0; } /* * A list of module scopes that need to have their definition emitted when * the current root scope (module) is finished is kept here. */ static ivl_scope_t *scopes_to_emit = 0; static unsigned num_scopes_to_emit = 0; static unsigned emitting_scopes = 0; int emit_scope(ivl_scope_t scope, ivl_scope_t parent) { char *package_name = 0; ivl_scope_type_t sc_type = ivl_scope_type(scope); unsigned is_auto = ivl_scope_is_auto(scope); unsigned idx; /* Output the scope definition. */ switch (sc_type) { case IVL_SCT_MODULE: assert(!is_auto); /* This is an instantiation. */ if (parent) { assert(indent != 0); /* If the module has parameters then it may not be unique * so we create a mangled name version instead. */ fprintf(vlog_out, "\n%*c", indent, ' '); emit_mangled_name(scope, !parent && !emitting_scopes); fprintf(vlog_out, " "); emit_id(ivl_scope_basename(scope)); fprintf(vlog_out, "("); emit_module_call_expressions(scope); fprintf(vlog_out, ");"); emit_scope_file_line(scope); fprintf(vlog_out, "\n"); num_scopes_to_emit += 1; scopes_to_emit = realloc(scopes_to_emit, num_scopes_to_emit * sizeof(ivl_scope_t)); scopes_to_emit[num_scopes_to_emit-1] = scope; return 0; } assert(indent == 0); /* Set the time scale for this scope. */ fprintf(vlog_out, "\n`timescale %s/%s\n", get_time_const(ivl_scope_time_units(scope)), get_time_const(ivl_scope_time_precision(scope))); if (ivl_scope_is_cell(scope)) { fprintf(vlog_out, "`celldefine\n"); } fprintf(vlog_out, "/* This module was originally defined in " "file %s at line %u. */\n", ivl_scope_def_file(scope), ivl_scope_def_lineno(scope)); fprintf(vlog_out, "module "); emit_mangled_name(scope, !parent && !emitting_scopes); emit_module_ports(scope); break; case IVL_SCT_FUNCTION: /* Root scope functions have already been emitted. */ if (! parent) return 0; assert(indent != 0); fprintf(vlog_out, "\n%*cfunction", indent, ' '); if (ivl_scope_ports(scope) < 1) { fprintf(stderr, "%s:%u: vlog95 error: Function (%s) has " "no return value.\n", ivl_scope_file(scope), ivl_scope_lineno(scope), ivl_scope_tname(scope)); vlog_errors += 1; } /* The function return information is the zero port. */ emit_func_return(ivl_scope_port(scope, 0)); fprintf(vlog_out, " "); emit_id(ivl_scope_tname(scope)); if (is_auto) { fprintf(stderr, "%s:%u: vlog95 error: Automatic functions " "(%s) are not supported.\n", ivl_scope_file(scope), ivl_scope_lineno(scope), ivl_scope_tname(scope)); vlog_errors += 1; } break; case IVL_SCT_TASK: /* Root scope tasks have already been emitted. */ if (! parent) return 0; assert(indent != 0); fprintf(vlog_out, "\n%*ctask ", indent, ' '); emit_id(ivl_scope_tname(scope)); if (is_auto) { fprintf(stderr, "%s:%u: vlog95 error: Automatic tasks " "(%s) are not supported.\n", ivl_scope_file(scope), ivl_scope_lineno(scope), ivl_scope_tname(scope)); vlog_errors += 1; } break; case IVL_SCT_BEGIN: case IVL_SCT_FORK: assert(indent != 0); emit_named_block_scope(scope); return 0; /* A named begin/fork is handled in line. */ case IVL_SCT_GENERATE: fprintf(stderr, "%s:%u: vlog95 sorry: generate scopes are not " "currently translated \"%s\".\n", ivl_scope_file(scope), ivl_scope_lineno(scope), ivl_scope_tname(scope)); vlog_errors += 1; return 0; case IVL_SCT_PACKAGE: assert(indent == 0); assert(! parent); /* Set the time scale for this scope. */ fprintf(vlog_out, "\n`timescale %s/%s\n", get_time_const(ivl_scope_time_units(scope)), get_time_const(ivl_scope_time_precision(scope))); /* Emit a package as a module with a special name. */ fprintf(vlog_out, "/* This package (module) was originally " "defined in file %s at line %u. */\n", ivl_scope_def_file(scope), ivl_scope_def_lineno(scope)); fprintf(vlog_out, "module "); package_name = get_package_name(scope); emit_id(package_name); break; case IVL_SCT_CLASS: fprintf(stderr, "%s:%u: vlog95 sorry: class scopes are not " "currently translated \"%s\".\n", ivl_scope_file(scope), ivl_scope_lineno(scope), ivl_scope_tname(scope)); vlog_errors += 1; return 0; default: fprintf(stderr, "%s:%u: vlog95 error: Unsupported scope type " "(%d) named: %s.\n", ivl_scope_file(scope), ivl_scope_lineno(scope), sc_type, ivl_scope_tname(scope)); vlog_errors += 1; return 0; } fprintf(vlog_out, ";"); emit_scope_file_line(scope); fprintf(vlog_out, "\n"); indent += indent_incr; /* Output the scope ports for this scope. */ if (sc_type == IVL_SCT_MODULE) { emit_module_port_defs(scope); } else { emit_task_func_port_defs(scope); } emit_scope_variables(scope); if (sc_type == IVL_SCT_MODULE) { unsigned count = ivl_scope_lpms(scope); /* Output the LPM devices. */ for (idx = 0; idx < count; idx += 1) { emit_lpm(scope, ivl_scope_lpm(scope, idx)); } /* Output any logic devices. */ count = ivl_scope_logs(scope); for (idx = 0; idx < count; idx += 1) { emit_logic(scope, ivl_scope_log(scope, idx)); } /* Output any switch (logic) devices. */ count = ivl_scope_switches(scope); for (idx = 0; idx < count; idx += 1) { emit_tran(scope, ivl_scope_switch(scope, idx)); } } if (sc_type == IVL_SCT_MODULE || sc_type == IVL_SCT_PACKAGE) { /* Output any initial blocks for tasks or functions or named * blocks defined in this module. Used to initialize local * variables. */ ivl_scope_children(scope, (ivl_scope_f*) emit_tfb_process, scope); /* Output the initial/always blocks for this module. */ ivl_design_process(design, (ivl_process_f)find_process, scope); } /* Output the function body. */ if (sc_type == IVL_SCT_FUNCTION) { ivl_statement_t body = ivl_scope_def(scope); assert(func_rtn_name == 0); /* If the function disables itself then that is really a * SystemVerilog return statement in disguise. A toplevel * named begin is needed to make this work in standard Verilog * so add one if it is needed. */ if (ivl_statement_type(body) == IVL_ST_BLOCK) { ivl_scope_t blk_scope = ivl_stmt_block_scope(body); if (blk_scope) { func_rtn_name = ivl_scope_basename(blk_scope); emit_stmt(scope, body); func_rtn_name = 0; } else if (has_func_disable(scope, body)) { char *name_return = get_func_return_name(scope); unsigned count = ivl_stmt_block_count(body); fprintf(vlog_out, "%*cbegin: %s\n", indent, ' ', name_return); indent += indent_incr; func_rtn_name = name_return; for (idx = 0; idx < count; idx += 1) { emit_stmt(scope, ivl_stmt_block_stmt(body, idx)); } func_rtn_name = 0; indent -= indent_incr; fprintf(vlog_out, "%*cend /* %s */\n", indent, ' ', name_return); free(name_return); } else emit_stmt(scope, body); /* A non-block statement may need a named block for a return. */ } else if (has_func_disable(scope, body)) { char *name_return = get_func_return_name(scope); fprintf(vlog_out, "%*cbegin: %s\n", indent, ' ', name_return); indent += indent_incr; func_rtn_name = name_return; emit_stmt(scope, body); func_rtn_name = 0; indent -= indent_incr; fprintf(vlog_out, "%*cend /* %s */\n", indent, ' ', name_return); free(name_return); } else emit_stmt(scope, body); } /* Output the task body. */ if (sc_type == IVL_SCT_TASK) emit_stmt(scope, ivl_scope_def(scope)); /* Print any sub-scopes. */ ivl_scope_children(scope, (ivl_scope_f*) emit_scope, scope); /* And finally print a specify block when needed. */ if (sc_type == IVL_SCT_MODULE) emit_specify(scope); /* Output the scope ending. */ assert(indent >= indent_incr); indent -= indent_incr; switch (sc_type) { case IVL_SCT_MODULE: assert(indent == 0); fprintf(vlog_out, "endmodule /* "); emit_mangled_name(scope, !parent && !emitting_scopes); fprintf(vlog_out, " */\n"); if (ivl_scope_is_cell(scope)) { fprintf(vlog_out, "`endcelldefine\n"); } /* If this is a root scope then emit any saved instance scopes. * Save any scope that does not have parameters/a mangled name * to a list so we don't print duplicate module definitions. */ if (!emitting_scopes) { emitting_scopes = 1; for (idx =0; idx < num_scopes_to_emit; idx += 1) { ivl_scope_t scope_to_emit = scopes_to_emit[idx]; if (scope_has_been_emitted(scope_to_emit)) continue; (void) emit_scope(scope_to_emit, 0); /* If we used a mangled name then the instance is * unique so don't add it to the list. */ if (!scope_is_unique(scope_to_emit)) continue; add_scope_to_list(scope_to_emit); } free(scopes_to_emit); scopes_to_emit = 0; num_scopes_to_emit = 0; emitting_scopes = 0; } break; case IVL_SCT_FUNCTION: fprintf(vlog_out, "%*cendfunction /* %s */\n", indent, ' ', ivl_scope_tname(scope)); break; case IVL_SCT_TASK: fprintf(vlog_out, "%*cendtask /* %s */\n", indent, ' ', ivl_scope_tname(scope)); break; case IVL_SCT_PACKAGE: fprintf(vlog_out, "endmodule /* "); emit_id(package_name); free(package_name); fprintf(vlog_out, " */\n"); break; default: assert(0); break; } return 0; } iverilog-12_0/tgt-vlog95/stmt.c000066400000000000000000001572041435245347300164340ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ # include # include # include "config.h" # include "vlog95_priv.h" static unsigned single_indent = 0; static unsigned get_indent(void) { if (single_indent) { single_indent = 0; return single_indent; } return indent; } static void emit_stmt_file_line(ivl_statement_t stmt) { if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); } } static void emit_stmt_block_body(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, count = ivl_stmt_block_count(stmt); ivl_scope_t my_scope = ivl_stmt_block_scope(stmt); indent += indent_incr; if (my_scope) emit_scope_variables(my_scope); else my_scope = scope; for (idx = 0; idx < count; idx += 1) { emit_stmt(my_scope, ivl_stmt_block_stmt(stmt, idx)); } assert(indent >= indent_incr); indent -= indent_incr; } static void emit_stmt_inter_delay(ivl_scope_t scope, ivl_statement_t stmt) { ivl_expr_t delay = ivl_stmt_delay_expr(stmt); unsigned nevents = ivl_stmt_nevent(stmt); if (nevents) { ivl_expr_t count = ivl_stmt_cond_expr(stmt); if (count) { if (ivl_expr_type(count) == IVL_EX_ULONG) { unsigned long repeat = ivl_expr_uvalue(count); if (repeat != 1) { fprintf(vlog_out, "repeat(%lu) ", repeat); } } else { fprintf(vlog_out, "repeat("); emit_expr(scope, count, 0, 0, 0, 0); fprintf(vlog_out, ") "); } } assert(delay == 0); fprintf(vlog_out, "@("); emit_event(scope, stmt); fprintf(vlog_out, ") "); } if (delay) { assert(nevents == 0); fprintf(vlog_out, "#("); emit_scaled_delayx(scope, delay, 1); fprintf(vlog_out, ") "); } } static void emit_stmt_lval_name(ivl_scope_t scope, ivl_lval_t lval, ivl_signal_t sig) { ivl_expr_t array_idx = ivl_lval_idx(lval); emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (array_idx) { int msb, lsb; ivl_type_t net_type = ivl_signal_net_type(sig); fprintf(vlog_out, "["); if (ivl_type_base(net_type) == IVL_VT_QUEUE) { lsb = 0; msb = 1; } else { assert(ivl_signal_dimensions(sig)); /* For an array the LSB/MSB order is not important. * They are always accessed from base counting up. */ lsb = ivl_signal_array_base(sig); msb = lsb + ivl_signal_array_count(sig) - 1; } emit_scaled_expr(scope, array_idx, msb, lsb); fprintf(vlog_out, "]"); } } static void emit_stmt_lval_packed(ivl_scope_t scope, ivl_lval_t lval, ivl_signal_t sig, ivl_expr_t sel_expr, unsigned wid) { unsigned idx; assert(wid > 0); fprintf(vlog_out, "{"); for (idx = wid - 1; idx > 0; idx -= 1) { emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_expr(scope, sel_expr, 0, 0, 0, 1); fprintf(vlog_out, " + %u], ", idx); } emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_expr(scope, sel_expr, 0, 0, 0, 1); fprintf(vlog_out, "]}"); } static void emit_stmt_lval_ips(ivl_scope_t scope, ivl_lval_t lval, ivl_signal_t sig, ivl_expr_t sel_expr, ivl_select_type_t sel_type, unsigned wid, int msb, int lsb) { unsigned idx; assert(wid > 0); fprintf(vlog_out, "{"); if (msb >= lsb) { if (sel_type == IVL_SEL_IDX_DOWN) { lsb += wid - 1; msb += wid - 1; emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); for (idx = 1; idx < wid; idx += 1) { fprintf(vlog_out, ", "); emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " - %u]", idx); } fprintf(vlog_out, "}"); } else { assert(sel_type == IVL_SEL_IDX_UP); for (idx = wid - 1; idx > 0; idx -= 1) { emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " + %u], ", idx); } emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]}"); } } else { if (sel_type == IVL_SEL_IDX_UP) { lsb -= wid - 1; msb -= wid - 1; emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); for (idx = 1; idx < wid; idx += 1) { fprintf(vlog_out, ", "); emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " + %u]", idx); } fprintf(vlog_out, "}"); } else { assert(sel_type == IVL_SEL_IDX_DOWN); for (idx = wid - 1; idx > 0; idx -= 1) { emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, " - %u], ", idx); } emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]}"); } } } /* * Dynamic arrays are not supported in vlog95, but this assignment can be * translated correctly. */ static void emit_stmt_lval_darray(ivl_scope_t scope, ivl_lval_t lval, ivl_signal_t sig) { ivl_expr_t idx = ivl_lval_idx(lval); emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); if (idx) { fprintf(vlog_out, "["); emit_expr(scope, idx, 0, 0, 0, 1); fprintf(vlog_out, "]"); } } /* * Class or class properties are not supported in vlog95, but this assignment * can be translated correctly. */ static ivl_type_t emit_stmt_lval_class(ivl_scope_t scope, ivl_lval_t lval) { ivl_lval_t nest = ivl_lval_nest(lval); ivl_signal_t sig = ivl_lval_sig(lval); ivl_type_t type; int idx = ivl_lval_property_idx(lval); if (nest) { type = emit_stmt_lval_class(scope, nest); assert(type); } else { assert(sig); emit_scope_call_path(scope, ivl_signal_scope(sig)); emit_id(ivl_signal_basename(sig)); type = ivl_signal_net_type(sig); } if (idx >= 0) { fprintf(vlog_out, ".%s", ivl_type_prop_name(type, idx)); return ivl_type_prop_type(type, idx); } else return 0; } static void emit_stmt_lval_piece(ivl_scope_t scope, ivl_lval_t lval) { ivl_signal_t sig = ivl_lval_sig(lval); ivl_expr_t sel_expr; ivl_select_type_t sel_type; unsigned width = ivl_lval_width(lval); int msb, lsb; assert(width > 0); /* A class supports a nested L-value so it may not have a signal * at this level. */ if (! sig) { (void) emit_stmt_lval_class(scope, lval); return; } switch (ivl_signal_data_type(sig)) { case IVL_VT_DARRAY: emit_stmt_lval_darray(scope, lval, sig); return; case IVL_VT_CLASS: (void) emit_stmt_lval_class(scope, lval); return; default: break; } /* If there are no selects then just print the name. */ sel_expr = ivl_lval_part_off(lval); if (! sel_expr && ((width == ivl_signal_width(sig)) || (ivl_signal_data_type(sig) == IVL_VT_QUEUE))) { emit_stmt_lval_name(scope, lval, sig); return; } /* We have some kind of select. */ get_sig_msb_lsb(sig, &msb, &lsb); sel_type = ivl_lval_sel_type(lval); assert(sel_expr); /* A bit select. */ if (width == 1) { emit_stmt_lval_name(scope, lval, sig); fprintf(vlog_out, "["); emit_scaled_expr(scope, sel_expr, msb, lsb); fprintf(vlog_out, "]"); } else if (ivl_expr_type(sel_expr) == IVL_EX_NUMBER) { /* A constant part select. */ emit_stmt_lval_name(scope, lval, sig); emit_scaled_range(scope, sel_expr, width, msb, lsb); } else if (sel_type == IVL_SEL_OTHER) { assert(lsb == 0); assert(msb >= 0); emit_stmt_lval_packed(scope, lval, sig, sel_expr, width); } else { /* An indexed part select. */ emit_stmt_lval_ips(scope, lval, sig, sel_expr, sel_type, width, msb, lsb); } } static unsigned emit_stmt_lval(ivl_scope_t scope, ivl_statement_t stmt) { unsigned count = ivl_stmt_lvals(stmt); unsigned wid = 0; if (count > 1) { unsigned idx; ivl_lval_t lval; fprintf(vlog_out, "{"); for (idx = count - 1; idx > 0; idx -= 1) { lval = ivl_stmt_lval(stmt, idx); wid += ivl_lval_width(lval); emit_stmt_lval_piece(scope, lval); fprintf(vlog_out, ", "); } lval = ivl_stmt_lval(stmt, 0); wid += ivl_lval_width(lval); emit_stmt_lval_piece(scope, lval); fprintf(vlog_out, "}"); } else { ivl_lval_t lval = ivl_stmt_lval(stmt, 0); wid = ivl_lval_width(lval); emit_stmt_lval_piece(scope, lval); } return wid; } /* * Icarus translated = into * begin * = ; * = ; * end * This routine looks for this pattern and turns it back into the * appropriate blocking assignment. */ static unsigned is_delayed_or_event_assign(ivl_scope_t scope, ivl_statement_t stmt) { unsigned wid; ivl_statement_t assign, delay, delayed_assign; ivl_statement_type_t delay_type; ivl_lval_t lval; ivl_expr_t rval; ivl_signal_t lsig, rsig; /* We must have two block elements. */ if (ivl_stmt_block_count(stmt) != 2) return 0; /* The first must be an assign. */ assign = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0; /* The second must be a delayx. */ delay = ivl_stmt_block_stmt(stmt, 1); delay_type = ivl_statement_type(delay); if ((delay_type != IVL_ST_DELAYX) && (delay_type != IVL_ST_WAIT)) return 0; /* The statement for the delayx must be an assign. */ delayed_assign = ivl_stmt_sub_stmt(delay); if (ivl_statement_type(delayed_assign) != IVL_ST_ASSIGN) return 0; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(assign) != 1) return 0; lval = ivl_stmt_lval(assign, 0); /* It must not have an array select. */ if (ivl_lval_idx(lval)) return 0; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return 0; lsig = ivl_lval_sig(lval); /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return 0; /* The R-value must be a single signal. */ rval = ivl_stmt_rval(delayed_assign); if (ivl_expr_type(rval) != IVL_EX_SIGNAL) return 0; /* It must not be an array word. */ if (ivl_expr_oper1(rval)) return 0; rsig = ivl_expr_signal(rval); /* The two signals must be the same. */ if (lsig != rsig) return 0; /* And finally the three statements must have the same line number * as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delay)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delayed_assign))) { return 0; } /* The pattern matched so generate the appropriate code. */ fprintf(vlog_out, "%*c", get_indent(), ' '); wid = emit_stmt_lval(scope, delayed_assign); fprintf(vlog_out, " = "); if (delay_type == IVL_ST_DELAYX) { fprintf(vlog_out, "#("); emit_scaled_delayx(scope, ivl_stmt_delay_expr(delay), 1); } else { fprintf(vlog_out, "@("); emit_event(scope, delay); } fprintf(vlog_out, ") "); emit_expr(scope, ivl_stmt_rval(assign), wid, 1, 0, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); return 1; } /* * A common routine to emit the basic assignment construct. It can also * translate an assignment with an opcode when allowed. */ static void emit_assign_and_opt_opcode(ivl_scope_t scope, ivl_statement_t stmt, unsigned allow_opcode) { unsigned wid; char opcode; const char *opcode_str; assert (ivl_statement_type(stmt) == IVL_ST_ASSIGN); // HERE: Do we need to calculate the width? The compiler should have already // done this for us. wid = emit_stmt_lval(scope, stmt); /* Get the opcode and the string version of the opcode. */ opcode = ivl_stmt_opcode(stmt); switch (opcode) { case 0: opcode_str = ""; break; case '+': opcode_str = "+"; break; case '-': opcode_str = "-"; break; case '*': opcode_str = "*"; break; case '/': opcode_str = "/"; break; case '%': opcode_str = "%"; break; case '&': opcode_str = "&"; break; case '|': opcode_str = "|"; break; case '^': opcode_str = "^"; break; case 'l': opcode_str = "<<"; break; case 'r': opcode_str = ">>"; break; case 'R': opcode_str = ">>>"; break; default: fprintf(stderr, "%s:%u: vlog95 error: unknown assignment operator " "(%c).\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), opcode); vlog_errors += 1; opcode_str = ""; break; } if (opcode && ! allow_opcode) { fprintf(stderr, "%s:%u: vlog95 error: assignment operator %s= is " "not allowed in this context.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), opcode_str); vlog_errors += 1; } fprintf(vlog_out, " = "); if (opcode) { unsigned twid = emit_stmt_lval(scope, stmt); assert(twid == wid); fprintf(vlog_out, " %s ", opcode_str); /* The >>>= assignment operator is only allowed when the allow * signed flag is true. */ if ((! allow_signed) && (opcode == 'R')) { fprintf(stderr, "%s:%u: vlog95 error: >>>= operator is not " "supported.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; } } emit_expr(scope, ivl_stmt_rval(stmt), wid, 1, 0, 0); } /* * Icarus translated for(; ; ) into * * begin * ; * while () begin * * * end * end * This routine looks for this pattern and turns it back into the * appropriate for loop. */ static unsigned is_for_loop(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t assign, while_lp, while_blk, body, incr_assign; /* We must have two block elements. */ if (ivl_stmt_block_count(stmt) != 2) return 0; /* The first must be an assign. */ assign = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0; /* The second must be a while. */ while_lp = ivl_stmt_block_stmt(stmt, 1); if (ivl_statement_type(while_lp) != IVL_ST_WHILE) return 0; /* The while statement must be a block. */ while_blk = ivl_stmt_sub_stmt(while_lp); if (ivl_statement_type(while_blk) != IVL_ST_BLOCK) return 0; /* It must not be a named block. */ if (ivl_stmt_block_scope(while_blk)) return 0; /* It must have two elements. */ if (ivl_stmt_block_count(while_blk) != 2) return 0; /* The first block element (the body) can be anything. */ body = ivl_stmt_block_stmt(while_blk, 0); /* The second block element must be the increment assign. */ incr_assign = ivl_stmt_block_stmt(while_blk, 1); if (ivl_statement_type(incr_assign) != IVL_ST_ASSIGN) return 0; /* And finally the for statements must have the same line number * as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(while_lp)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(while_blk)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(incr_assign))) { return 0; } /* The pattern matched so generate the appropriate code. */ fprintf(vlog_out, "%*cfor(", get_indent(), ' '); /* Emit the initialization statement (no opcode is allowed). */ emit_assign_and_opt_opcode(scope, assign, 0); fprintf(vlog_out, "; "); /* Emit the condition. */ emit_expr(scope, ivl_stmt_cond_expr(while_lp), 0, 0, 0, 0); fprintf(vlog_out, "; "); /* Emit the increment statement (an opcode is allowed). */ emit_assign_and_opt_opcode(scope, incr_assign, 1); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); /* Now emit the body. */ single_indent = 1; emit_stmt(scope, body); return 1; } /* * Icarus translated = repeat() into * begin * = ; * repeat() ; * = ; * end * This routine looks for this pattern and turns it back into the * appropriate blocking assignment. */ static unsigned is_repeat_event_assign(ivl_scope_t scope, ivl_statement_t stmt) { unsigned wid; ivl_statement_t assign, event, event_assign, repeat; ivl_lval_t lval; ivl_expr_t rval; ivl_signal_t lsig, rsig; /* We must have three block elements. */ if (ivl_stmt_block_count(stmt) != 3) return 0; /* The first must be an assign. */ assign = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0; /* The second must be a repeat with an event or an event. */ repeat = ivl_stmt_block_stmt(stmt, 1); if (ivl_statement_type(repeat) != IVL_ST_REPEAT) return 0; /* The repeat must have an event statement. */ event = ivl_stmt_sub_stmt(repeat); if (ivl_statement_type(event) != IVL_ST_WAIT) return 0; /* The third must be an assign. */ event_assign = ivl_stmt_block_stmt(stmt, 2); if (ivl_statement_type(event_assign) != IVL_ST_ASSIGN) return 0; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(assign) != 1) return 0; lval = ivl_stmt_lval(assign, 0); /* It must not have an array select. */ if (ivl_lval_idx(lval)) return 0; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return 0; lsig = ivl_lval_sig(lval); /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return 0; /* The R-value must be a single signal. */ rval = ivl_stmt_rval(event_assign); if (ivl_expr_type(rval) != IVL_EX_SIGNAL) return 0; /* It must not be an array word. */ if (ivl_expr_oper1(rval)) return 0; rsig = ivl_expr_signal(rval); /* The two signals must be the same. */ if (lsig != rsig) return 0; /* And finally the four statements must have the same line number * as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(repeat)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event_assign))) { return 0; } /* The pattern matched so generate the appropriate code. */ fprintf(vlog_out, "%*c", get_indent(), ' '); wid = emit_stmt_lval(scope, event_assign); fprintf(vlog_out, " ="); if (repeat) { fprintf(vlog_out, " repeat ("); emit_expr(scope, ivl_stmt_cond_expr(repeat), 0, 0, 0, 0); fprintf(vlog_out, ")"); } fprintf(vlog_out, " @("); emit_event(scope, event); fprintf(vlog_out, ") "); emit_expr(scope, ivl_stmt_rval(assign), wid, 1, 0, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); return 1; } /* * Icarus translated wait( into * begin * while ( !== 1'b1) @(); * * end * This routine looks for this pattern and turns it back into a * wait statement. */ static unsigned is_wait(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t while_wait, wait, wait_stmt; ivl_expr_t while_expr, expr; const char *bits; /* We must have two block elements. */ if (ivl_stmt_block_count(stmt) != 2) return 0; /* The first must be a while. */ while_wait = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(while_wait) != IVL_ST_WHILE) return 0; /* That has a wait with a NOOP statement. */ wait = ivl_stmt_sub_stmt(while_wait); if (ivl_statement_type(wait) != IVL_ST_WAIT) return 0; wait_stmt = ivl_stmt_sub_stmt(wait); if (ivl_statement_type(wait_stmt) != IVL_ST_NOOP) return 0; /* Check that the while condition has the correct form. */ while_expr = ivl_stmt_cond_expr(while_wait); if (ivl_expr_type(while_expr) != IVL_EX_BINARY) return 0; if (ivl_expr_opcode(while_expr) != 'N') return 0; /* Has a second operator that is a constant 1'b1. */ expr = ivl_expr_oper2(while_expr); if (ivl_expr_type(expr) != IVL_EX_NUMBER) return 0; if (ivl_expr_width(expr) != 1) return 0; bits = ivl_expr_bits(expr); if (*bits != '1') return 0; // HERE: There is no easy way to verify that the @ sensitivity list // matches the first expression so we don't check for that yet. /* And finally the two statements that represent the wait must * have the same line number as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(while_wait)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(wait))) { return 0; } /* The pattern matched so generate the appropriate code. */ fprintf(vlog_out, "%*cwait(", get_indent(), ' '); emit_expr(scope, ivl_expr_oper1(while_expr), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_block_stmt(stmt, 1)); return 1; } /* * Check to see if the statement L-value is a port in the given scope. * If it is return the zero based port number. */ static unsigned utask_in_port_idx(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports = ivl_scope_ports(scope); unsigned first_arg = is_void_function(scope) ? 1 : 0; ivl_lval_t lval = ivl_stmt_lval(stmt, 0); ivl_signal_t lsig = ivl_lval_sig(lval); const char *sig_name; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(stmt) != 1) return ports; /* It must not have an array select. */ if (ivl_lval_idx(lval)) return ports; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return ports; /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return ports; /* It must have the same scope as the task. */ if (scope != ivl_signal_scope(lsig)) return ports; /* It must be an input or inout port of the task. */ sig_name = ivl_signal_basename(lsig); for (idx = first_arg; idx < ports; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); ivl_signal_port_t port_type = ivl_signal_port(port); if ((port_type != IVL_SIP_INPUT) && (port_type != IVL_SIP_INOUT)) continue; if (strcmp(sig_name, ivl_signal_basename(port)) == 0) break; } return idx; } /* * Check to see if the statement R-value is a port in the given scope. * If it is return the zero based port number. */ static unsigned utask_out_port_idx(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports = ivl_scope_ports(scope); unsigned first_arg = is_void_function(scope) ? 1 : 0; ivl_expr_t rval = ivl_stmt_rval(stmt); ivl_signal_t rsig = 0; ivl_expr_type_t expr_type = ivl_expr_type(rval); const char *sig_name; /* We can have a simple signal. */ if (expr_type == IVL_EX_SIGNAL) { rsig = ivl_expr_signal(rval); /* Or a simple select of a simple signal. */ } else if (expr_type == IVL_EX_SELECT) { ivl_expr_t expr = ivl_expr_oper1(rval); /* We must have a zero select base. */ if (ivl_expr_oper2(rval)) return ports; /* We must be selecting a signal. */ if (ivl_expr_type(expr) != IVL_EX_SIGNAL) return ports; rsig = ivl_expr_signal(expr); /* Or a cast of a simple signal. */ } else if (expr_type == IVL_EX_UNARY) { ivl_expr_t expr = ivl_expr_oper1(rval); char opcode = ivl_expr_opcode(rval); /* This must be a cast opcode. */ if ((opcode != '2') && (opcode != 'v') && (opcode != 'r')) return ports; /* We must be casting a signal. */ if (ivl_expr_type(expr) != IVL_EX_SIGNAL) return ports; rsig = ivl_expr_signal(expr); } else return ports; /* The R-value must have the same scope as the task. */ if (scope != ivl_signal_scope(rsig)) return ports; /* It must not be an array element. */ if (ivl_signal_dimensions(rsig)) return ports; /* It must be an output or inout port of the task. */ sig_name = ivl_signal_basename(rsig); for (idx = first_arg; idx < ports; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); ivl_signal_port_t port_type = ivl_signal_port(port); if ((port_type != IVL_SIP_OUTPUT) && (port_type != IVL_SIP_INOUT)) continue; if (strcmp(sig_name, ivl_signal_basename(port)) == 0) break; } return idx; } /* * Structure to hold the port information as we extract it from the block. */ typedef struct port_expr_s { ivl_signal_port_t type; union { ivl_statement_t lval; ivl_expr_t rval; } expr; } *port_expr_t; /* * An input prints the R-value and an output or inout print the L-value. */ static void emit_port(ivl_scope_t scope, struct port_expr_s port_expr) { if (port_expr.type == IVL_SIP_INPUT) { // HERE: For a user should the argument width be used here. emit_expr(scope, port_expr.expr.rval, 0, 1, 0, 0); } else { /* This is a self-determined context so we don't care about * the width of the L-value. */ (void) emit_stmt_lval(scope, port_expr.expr.lval); } } /* * Icarus encodes a user task call with arguments as: * begin * = * ... * = * * = * ... * = * end * This routine looks for that pattern and translates it into the * appropriate task call. It returns true (1) if it successfully * translated the block to a task call, otherwise it returns false * (0) to indicate the block needs to be emitted. * * When calling automatic tasks there is an initial ALLOC statement * and a final FREE statement. */ static unsigned is_utask_call_with_args(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports, task_idx = 0; unsigned count = ivl_stmt_block_count(stmt); unsigned lineno = ivl_stmt_lineno(stmt); unsigned start, stop, is_auto = 0; ivl_scope_t task_scope = 0; unsigned is_void_func = 0; port_expr_t port_exprs; /* Check to see if the block is of the basic form first. */ for (idx = 0; idx < count; idx += 1) { ivl_statement_t tmp = ivl_stmt_block_stmt(stmt, idx); /* For an automatic task the ALLOC must be first. */ if (ivl_statement_type(tmp) == IVL_ST_ALLOC) { if (idx == 0) { is_auto = 1; continue; } } if (ivl_statement_type(tmp) == IVL_ST_ASSIGN) continue; if (ivl_statement_type(tmp) == IVL_ST_UTASK && !task_scope) { task_idx = idx; task_scope = ivl_stmt_call(tmp); is_void_func = is_void_function(task_scope); assert(ivl_scope_type(task_scope) == IVL_SCT_TASK || is_void_func); continue; } /* For an automatic task the FREE must be last. */ if (ivl_statement_type(tmp) == IVL_ST_FREE) { if (idx == count-1) { if (is_auto) continue; } } return 0; } /* If there is no task call or it takes no argument then return. */ if (!task_scope) return 0; ports = ivl_scope_ports(task_scope); if (ports == 0) return 0; /* Allocate space to save the port information and initialize it. */ port_exprs = (port_expr_t) malloc(sizeof(struct port_expr_s)*ports); for (idx = 0; idx < ports; idx += 1) { port_exprs[idx].type = IVL_SIP_NONE; port_exprs[idx].expr.rval = 0; } /* Check that the input arguments are correct. */ if (is_auto) start = 1; else start = 0; for (idx = start; idx < task_idx; idx += 1) { ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx); unsigned port = utask_in_port_idx(task_scope, assign); if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) { free(port_exprs); return 0; } port_exprs[port].type = IVL_SIP_INPUT; port_exprs[port].expr.rval = ivl_stmt_rval(assign); } /* Check that the output arguments are correct. */ if (is_auto) stop = count-1; else stop = count; for (idx = task_idx + 1; idx < stop; idx += 1) { ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx); unsigned port = utask_out_port_idx(task_scope, assign); if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) { free(port_exprs); return 0; } if (port_exprs[port].type == IVL_SIP_INPUT) { port_exprs[port].type = IVL_SIP_INOUT; // HERE: We probably should verify that the current R-value matches the // new L-value. } else { port_exprs[port].type = IVL_SIP_OUTPUT; } port_exprs[port].expr.lval = assign; } /* Check that the task call has the correct line number. */ if (lineno != ivl_stmt_lineno(ivl_stmt_block_stmt(stmt, task_idx))) { free(port_exprs); return 0; } /* Verify that all the ports were defined. */ start = is_void_func ? 1 : 0; for (idx = start; idx < ports; idx += 1) { if (port_exprs[idx].type == IVL_SIP_NONE) { free(port_exprs); return 0; } } /* Now that we have the arguments figured out, print the task call. */ fprintf(vlog_out, "%*c", get_indent(), ' '); if (is_void_func) fprintf(vlog_out, "if ("); emit_scope_path(scope, task_scope); fprintf(vlog_out, "("); emit_port(scope, port_exprs[start]); for (idx = start + 1; idx < ports; idx += 1) { fprintf(vlog_out, ", "); emit_port(scope, port_exprs[idx]); } free(port_exprs); if (is_void_func) fprintf(vlog_out, ")"); fprintf(vlog_out, ");"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); return 1; } static void emit_stmt_assign(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c", get_indent(), ' '); /* Emit the basic assignment (an opcode is allowed).*/ emit_assign_and_opt_opcode(scope, stmt, 1); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_assign_nb(ivl_scope_t scope, ivl_statement_t stmt) { unsigned wid; fprintf(vlog_out, "%*c", get_indent(), ' '); // HERE: Do we need to calculate the width? The compiler should have already // done this for us. wid = emit_stmt_lval(scope, stmt); fprintf(vlog_out, " <= "); emit_stmt_inter_delay(scope, stmt); emit_expr(scope, ivl_stmt_rval(stmt), wid, 1, 0, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_block(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*cbegin", get_indent(), ' '); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); fprintf(vlog_out, "%*cend\n", get_indent(), ' '); } static void emit_stmt_block_named(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t my_scope = ivl_stmt_block_scope(stmt); fprintf(vlog_out, "%*cbegin: ", get_indent(), ' '); emit_id(ivl_scope_basename(my_scope)); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); fprintf(vlog_out, "%*cend /* %s */\n", get_indent(), ' ', ivl_scope_basename(my_scope)); } static void emit_stmt_case(ivl_scope_t scope, ivl_statement_t stmt) { const char *case_type = 0; unsigned idx, default_case, count = ivl_stmt_case_count(stmt); switch (ivl_statement_type(stmt)) { case IVL_ST_CASE: case IVL_ST_CASER: case_type = "case"; break; case IVL_ST_CASEX: case_type = "casex"; break; case IVL_ST_CASEZ: case_type = "casez"; break; default: assert(0); } fprintf(vlog_out, "%*c%s (", get_indent(), ' ', case_type); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); indent += indent_incr; default_case = count; for (idx = 0; idx < count; idx += 1) { ivl_expr_t expr = ivl_stmt_case_expr(stmt, idx); /* This is the default case so emit it last. */ if (expr == 0) { assert(default_case == count); default_case = idx; continue; } fprintf(vlog_out, "%*c", get_indent(), ' '); emit_expr(scope, expr, 0, 0, 0, 0); fprintf(vlog_out, ":"); single_indent = 1; emit_stmt(scope, ivl_stmt_case_stmt(stmt, idx)); } if (default_case < count) { fprintf(vlog_out, "%*cdefault:", get_indent(), ' '); single_indent = 1; emit_stmt(scope, ivl_stmt_case_stmt(stmt, default_case)); } assert(indent >= indent_incr); indent -= indent_incr; fprintf(vlog_out, "%*cendcase\n", get_indent(), ' '); } static void emit_stmt_cassign(ivl_scope_t scope, ivl_statement_t stmt) { unsigned wid; fprintf(vlog_out, "%*cassign ", get_indent(), ' '); // HERE: Do we need to calculate the width? The compiler should have already // done this for us. wid = emit_stmt_lval(scope, stmt); fprintf(vlog_out, " = "); emit_expr(scope, ivl_stmt_rval(stmt), wid, 1, 0, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_condit(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t true_stmt = ivl_stmt_cond_true(stmt); ivl_statement_t false_stmt = ivl_stmt_cond_false(stmt); unsigned nest = 0; fprintf(vlog_out, "%*cif (", get_indent(), ' '); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); if (true_stmt) { /* If we have a false statement and the true statement is a * condition that does not have a false clause then we need * to add a begin/end pair to keep the else clause attached * to this condition. */ if (false_stmt && (ivl_statement_type(true_stmt) == IVL_ST_CONDIT) && (! ivl_stmt_cond_false(true_stmt))) nest = 1; if (nest) { fprintf(vlog_out, " begin\n"); indent += indent_incr; } else single_indent = 1; emit_stmt(scope, true_stmt); } else { fprintf(vlog_out, ";\n"); } if (false_stmt) { if (nest) { assert(indent >= indent_incr); indent -= indent_incr; } fprintf(vlog_out, "%*c", get_indent(), ' '); if (nest) fprintf(vlog_out, "end "); fprintf(vlog_out, "else"); single_indent = 1; emit_stmt(scope, false_stmt); } } static void emit_stmt_deassign(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*cdeassign ", get_indent(), ' '); (void) emit_stmt_lval(scope, stmt); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_delay(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c#", get_indent(), ' '); emit_scaled_delay(scope, ivl_stmt_delay_val(stmt)); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } static void emit_stmt_delayx(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c#(", get_indent(), ' '); emit_scaled_delayx(scope, ivl_stmt_delay_expr(stmt), 1); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } static unsigned is_func_disable(ivl_scope_t scope, ivl_scope_t disable_scope) { assert(func_rtn_name); /* Find the enclosing function scope. */ while (ivl_scope_type(scope) != IVL_SCT_FUNCTION) { scope = ivl_scope_parent(scope); assert(scope); } /* If the function scope and the scope to be disabled match then this * is a function disable (SystemVerilog return). */ return scope == disable_scope; } static void emit_stmt_disable(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t disable_scope = ivl_stmt_call(stmt); fprintf(vlog_out, "%*cdisable ", get_indent(), ' '); /* A normal disable statement. */ if (disable_scope) { /* If this disable is in a function and it is disabling the * function then emit the appropriate function return name. */ if (func_rtn_name && is_func_disable(scope, disable_scope)) { fprintf(vlog_out, "%s", func_rtn_name); } else emit_scope_path(scope, disable_scope); /* A SystemVerilog disable fork statement cannot be converted. */ } else { fprintf(vlog_out, "fork"); fprintf(stderr, "%s:%u: vlog95 sorry: disable fork is not " "currently translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; } fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } /* * Emit just the statements for this named block since an outer named block * was added to keep all the translated code inside a single named block. */ static void emit_stmt_do_while_body(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, count = ivl_stmt_block_count(stmt); unsigned is_begin = 0; assert(ivl_stmt_block_scope(stmt)); switch (ivl_statement_type(stmt)) { case IVL_ST_BLOCK: fprintf(vlog_out, "%*cbegin", get_indent(), ' '); is_begin = 1; break; case IVL_ST_FORK_JOIN_ANY: fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_any is not " "currently translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; return; case IVL_ST_FORK_JOIN_NONE: fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_none is not " "currently translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; return; case IVL_ST_FORK: fprintf(vlog_out, "%*cfork", get_indent(), ' '); break; /* Only named blocks should make it to this code. */ default: assert(0); break; } emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); indent += indent_incr; for (idx = 0; idx < count; idx += 1) { emit_stmt(scope, ivl_stmt_block_stmt(stmt, idx)); } assert(indent >= indent_incr); indent -= indent_incr; if (is_begin) fprintf(vlog_out, "%*cend\n", get_indent(), ' '); else fprintf(vlog_out, "%*cjoin\n", get_indent(), ' '); } /* * Currently a do/while can be translated in two ways: no named blocks in * the do/while statement and only a named block as the top level statement. * Anything else cannot be translated since a hierarchical variable reference * or disable cannot work correctly when the statement is duplicated. */ typedef enum stmt_named_type_e { NO_NAMED = 0, TOP_NAMED = 1, OTHER_NAMED = 2 } stmt_named_type_t; static stmt_named_type_t get_named_type(ivl_statement_t stmt, unsigned is_top); /* * A block can start as either a NO_NAMED or a TOP_NAMED so pass this in. */ static stmt_named_type_t get_named_type_block(ivl_statement_t stmt, stmt_named_type_t def_type) { stmt_named_type_t rtn = def_type; unsigned idx, count = ivl_stmt_block_count(stmt); for (idx = 0; idx < count; idx += 1) { stmt_named_type_t lrtn; lrtn = get_named_type(ivl_stmt_block_stmt(stmt, idx), 0); if (lrtn > rtn) rtn = lrtn; if (rtn == OTHER_NAMED) break; } return rtn; } static stmt_named_type_t get_named_type_case(ivl_statement_t stmt) { stmt_named_type_t rtn = NO_NAMED; unsigned idx, count = ivl_stmt_case_count(stmt); for (idx = 0; idx < count; idx += 1) { stmt_named_type_t lrtn; lrtn = get_named_type(ivl_stmt_case_stmt(stmt, idx), 0); if (lrtn > rtn) rtn = lrtn; if (rtn == OTHER_NAMED) break; } return rtn; } static stmt_named_type_t get_named_type_condit(ivl_statement_t stmt) { stmt_named_type_t true_rtn, false_rtn; true_rtn = get_named_type(ivl_stmt_cond_true(stmt), 0); false_rtn = get_named_type(ivl_stmt_cond_false(stmt), 0); if (false_rtn > true_rtn) return false_rtn; return true_rtn; } static stmt_named_type_t get_named_type(ivl_statement_t stmt, unsigned is_top) { stmt_named_type_t rtn = NO_NAMED; if (! stmt) return NO_NAMED; switch (ivl_statement_type(stmt)) { case IVL_ST_BLOCK: case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: /* Check to see if this is a named top block or sub block. */ if (ivl_stmt_block_scope(stmt)) { if (is_top) rtn = TOP_NAMED; else return OTHER_NAMED; } rtn = get_named_type_block(stmt, rtn); break; case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: rtn = get_named_type_case(stmt); break; case IVL_ST_CONDIT: rtn = get_named_type_condit(stmt); break; /* These statements only have a single sub-statement that is not * a top level statement relative to the original do/while. */ case IVL_ST_DELAY: case IVL_ST_DELAYX: case IVL_ST_DO_WHILE: case IVL_ST_FOREVER: case IVL_ST_REPEAT: case IVL_ST_WAIT: case IVL_ST_WHILE: rtn = get_named_type(ivl_stmt_sub_stmt(stmt), 0); break; default: /* The rest of the statement types do not have sub-statements. */ break; } return rtn; } /* * Translate a do/while to the following: * * statement * while (expr) statement */ static void emit_stmt_do_while(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t sub_stmt = ivl_stmt_sub_stmt(stmt); stmt_named_type_t named_type = get_named_type(sub_stmt, 1); /* If just the original do/while statement is named then emit it as: * * begin : name * * statement * while (expr) statement * end */ if (named_type == TOP_NAMED) { ivl_scope_t my_scope = ivl_stmt_block_scope(sub_stmt); assert(my_scope); fprintf(vlog_out, "%*cbegin: ", get_indent(), ' '); emit_id(ivl_scope_basename(my_scope)); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); indent += indent_incr; emit_scope_variables(my_scope); emit_stmt_do_while_body(my_scope, sub_stmt); fprintf(vlog_out, "%*cwhile (", get_indent(), ' '); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt_do_while_body(my_scope, sub_stmt); assert(indent >= indent_incr); indent -= indent_incr; fprintf(vlog_out, "%*cend /* %s */\n", get_indent(), ' ', ivl_scope_basename(my_scope)); } else { emit_stmt(scope, sub_stmt); fprintf(vlog_out, "%*cwhile (", get_indent(), ' '); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, sub_stmt); } /* * If the do/while has sub-statements that are named it cannot be * translated since the original do/while statement needs to be * duplicated and doing this will create two statements with the * same name. */ if (named_type == OTHER_NAMED) { fprintf(stderr, "%s:%u: vlog95 sorry: do/while with named " "sub-statements cannot be translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; } } static void emit_stmt_force(ivl_scope_t scope, ivl_statement_t stmt) { unsigned wid; fprintf(vlog_out, "%*cforce ", get_indent(), ' '); // HERE: Do we need to calculate the width? The compiler should have already // done this for us. wid = emit_stmt_lval(scope, stmt); fprintf(vlog_out, " = "); emit_expr(scope, ivl_stmt_rval(stmt), wid, 1, 0, 0); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_forever(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*cforever", get_indent(), ' '); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } static void emit_stmt_fork(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*cfork", get_indent(), ' '); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); fprintf(vlog_out, "%*cjoin\n", get_indent(), ' '); } static void emit_stmt_fork_named(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t my_scope = ivl_stmt_block_scope(stmt); fprintf(vlog_out, "%*cfork: ", get_indent(), ' '); emit_id(ivl_scope_basename(my_scope)); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); emit_stmt_block_body(scope, stmt); fprintf(vlog_out, "%*cjoin /* %s */\n", get_indent(), ' ', ivl_scope_basename(my_scope)); } static void emit_stmt_release(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*crelease ", get_indent(), ' '); (void) emit_stmt_lval(scope, stmt); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_repeat(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*crepeat (", get_indent(), ' '); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } static void emit_stmt_stask(ivl_scope_t scope, ivl_statement_t stmt) { unsigned count = ivl_stmt_parm_count(stmt); fprintf(vlog_out, "%*c%s", get_indent(), ' ', ivl_stmt_name(stmt)); if (count != 0) { unsigned idx; ivl_expr_t expr; fprintf(vlog_out, "("); count -= 1; for (idx = 0; idx < count; idx += 1) { expr = ivl_stmt_parm(stmt, idx); if (expr) emit_expr(scope, expr, 0, 0, 0, 0); fprintf(vlog_out, ", "); } expr = ivl_stmt_parm(stmt, count); if (expr) emit_expr(scope, expr, 0, 0, 0, 0); fprintf(vlog_out, ")"); } fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_trigger(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c-> ", get_indent(), ' '); assert(ivl_stmt_nevent(stmt) == 1); emit_event(scope, stmt); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } static void emit_stmt_nb_trigger(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c->> ", get_indent(), ' '); ivl_expr_t delay = ivl_stmt_delay_expr(stmt); if (delay) { fprintf(vlog_out, "#("); emit_scaled_delayx(scope, delay, 1); fprintf(vlog_out, ") "); } assert(ivl_stmt_nevent(stmt) == 1); emit_event(scope, stmt); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); fprintf(stderr, "%s:%u: vlog95 sorry: wait fork is not currently " "translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; } /* * A user defined task call with arguments is generated as a block with * input assignments, a simple call and then output assignments. This is * handled by the is_utask_call_with_args() routine above. */ static void emit_stmt_utask(ivl_scope_t scope, ivl_statement_t stmt) { ivl_scope_t task_scope = ivl_stmt_call(stmt); assert((ivl_scope_type(task_scope) == IVL_SCT_TASK && ivl_scope_ports(task_scope) == 0) || (is_void_function(task_scope) && ivl_scope_ports(task_scope) == 1)); fprintf(vlog_out, "%*c", get_indent(), ' '); if (is_void_function(task_scope)) fprintf(vlog_out, "if ("); emit_scope_path(scope, task_scope); if (is_void_function(task_scope)) fprintf(vlog_out, "(1'bx))"); fprintf(vlog_out, ";"); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); } /* Look to see if this is a SystemVerilog wait fork statement. */ static unsigned is_wait_fork(ivl_scope_t scope, ivl_statement_t stmt) { (void)scope; /* Parameter is not used. */ if (ivl_stmt_nevent(stmt) != 1) return 0; if (ivl_stmt_events(stmt, 0) != 0) return 0; assert(ivl_statement_type(ivl_stmt_sub_stmt(stmt)) == IVL_ST_NOOP); fprintf(vlog_out, "%*cwait fork;", get_indent(), ' '); emit_stmt_file_line(stmt); fprintf(vlog_out, "\n"); fprintf(stderr, "%s:%u: vlog95 sorry: wait fork is not currently " "translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; return 1; } static void emit_stmt_wait(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*c@(", get_indent(), ' '); emit_event(scope, stmt); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } static void emit_stmt_while(ivl_scope_t scope, ivl_statement_t stmt) { fprintf(vlog_out, "%*cwhile (", get_indent(), ' '); emit_expr(scope, ivl_stmt_cond_expr(stmt), 0, 0, 0, 0); fprintf(vlog_out, ")"); emit_stmt_file_line(stmt); single_indent = 1; emit_stmt(scope, ivl_stmt_sub_stmt(stmt)); } void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt) { switch (ivl_statement_type(stmt)) { case IVL_ST_NOOP: /* If this is a statement termination then just finish the * statement, otherwise print an empty begin/end pair. */ if (single_indent) { single_indent = 0; fprintf(vlog_out, ";\n"); } else { fprintf(vlog_out, "%*cbegin\n", get_indent(), ' '); fprintf(vlog_out, "%*cend\n", get_indent(), ' '); } break; case IVL_ST_ALLOC: /* This statement is only used with an automatic task so we * can safely skip it. The automatic task definition will * generate an appropriate error message.*/ break; case IVL_ST_ASSIGN: emit_stmt_assign(scope, stmt); break; case IVL_ST_ASSIGN_NB: emit_stmt_assign_nb(scope, stmt); break; case IVL_ST_BLOCK: if (ivl_stmt_block_scope(stmt)) { emit_stmt_block_named(scope, stmt); } else { if (is_delayed_or_event_assign(scope, stmt)) break; if (is_for_loop(scope, stmt)) break; if (is_repeat_event_assign(scope, stmt)) break; if (is_wait(scope, stmt)) break; if (is_utask_call_with_args(scope, stmt)) break; emit_stmt_block(scope, stmt); } break; case IVL_ST_CASE: case IVL_ST_CASER: case IVL_ST_CASEX: case IVL_ST_CASEZ: emit_stmt_case(scope, stmt); break; case IVL_ST_CASSIGN: emit_stmt_cassign(scope, stmt); break; case IVL_ST_CONDIT: emit_stmt_condit(scope, stmt); break; case IVL_ST_DEASSIGN: emit_stmt_deassign(scope, stmt); break; case IVL_ST_DELAY: emit_stmt_delay(scope, stmt); break; case IVL_ST_DELAYX: emit_stmt_delayx(scope, stmt); break; case IVL_ST_DISABLE: emit_stmt_disable(scope, stmt); break; case IVL_ST_DO_WHILE: emit_stmt_do_while(scope, stmt); break; case IVL_ST_FORCE: emit_stmt_force(scope, stmt); break; case IVL_ST_FOREVER: emit_stmt_forever(scope, stmt); break; case IVL_ST_FORK: if (ivl_stmt_block_scope(stmt)) { emit_stmt_fork_named(scope, stmt); } else { emit_stmt_fork(scope, stmt); } break; case IVL_ST_FORK_JOIN_ANY: fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_any is not " "currently translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; break; case IVL_ST_FORK_JOIN_NONE: fprintf(stderr, "%s:%u: vlog95 sorry: fork/join_none is not " "currently translated.\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt)); vlog_errors += 1; break; case IVL_ST_FREE: /* This statement is only used with an automatic task so we * can safely skip it. The automatic task definition will * generate an appropriate error message.*/ break; case IVL_ST_RELEASE: emit_stmt_release(scope, stmt); break; case IVL_ST_REPEAT: emit_stmt_repeat(scope, stmt); break; case IVL_ST_STASK: emit_stmt_stask(scope, stmt); break; case IVL_ST_TRIGGER: emit_stmt_trigger(scope, stmt); break; case IVL_ST_NB_TRIGGER: emit_stmt_nb_trigger(scope, stmt); break; case IVL_ST_UTASK: emit_stmt_utask(scope, stmt); break; case IVL_ST_WAIT: if (is_wait_fork(scope, stmt)) break; emit_stmt_wait(scope, stmt); break; case IVL_ST_WHILE: emit_stmt_while(scope, stmt); break; default: fprintf(vlog_out, "%*c;\n", get_indent(), ' '); fprintf(stderr, "%s:%u: vlog95 error: Unknown statement " "type (%d).\n", ivl_stmt_file(stmt), ivl_stmt_lineno(stmt), (int)ivl_statement_type(stmt)); vlog_errors += 1; break; } } void emit_process(ivl_scope_t scope, ivl_process_t proc) { ivl_statement_t stmt = ivl_process_stmt(proc); if (ivl_statement_type(stmt) == IVL_ST_NOOP) return; fprintf(vlog_out, "\n%*c", get_indent(), ' '); switch (ivl_process_type(proc)) { case IVL_PR_INITIAL: fprintf(vlog_out, "initial"); break; case IVL_PR_ALWAYS: case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: fprintf(vlog_out, "always"); break; case IVL_PR_FINAL: fprintf(vlog_out, "final"); fprintf(stderr, "%s:%u: vlog95 sorry: final blocks are not " "currently translated.\n", ivl_process_file(proc), ivl_process_lineno(proc)); vlog_errors+= 1; break; default: fprintf(vlog_out, ""); fprintf(stderr, "%s:%u: vlog95 error: Unknown process type (%d).\n", ivl_process_file(proc), ivl_process_lineno(proc), (int)ivl_process_type(proc)); vlog_errors+= 1; break; } if (emit_file_line) { fprintf(vlog_out, " /* %s:%u */", ivl_process_file(proc), ivl_process_lineno(proc)); } if (ivl_statement_type(stmt) == IVL_ST_NOOP) { fprintf(vlog_out, " begin\n%*cend\n", get_indent(), ' '); } else { single_indent = 1; emit_stmt(scope, stmt); } } iverilog-12_0/tgt-vlog95/udp.c000066400000000000000000000155551435245347300162370ustar00rootroot00000000000000/* * Copyright (C) 2011 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. */ # include # include # include "config.h" # include "vlog95_priv.h" # include "ivl_alloc.h" static void emit_entry(ivl_udp_t udp, char entry, unsigned *rerun) { const char *value = 0; switch (entry) { case '0': value = " 0 "; break; case '1': value = " 1 "; break; case 'x': value = " x "; break; case '?': /* 0, 1 or x */ value = " ? "; break; case 'b': /* 0 or 1 */ value = " b "; break; case '-': /* Current value. */ value = " - "; break; case '*': /* (??) */ value = " * "; break; case 'r': /* (01) */ value = " r "; break; case 'f': /* (10) */ value = " f "; break; case 'p': /* (01), (0x) or (x1) */ value = " p "; break; case 'n': /* (10), (1x) or (x0) */ value = " n "; break; /* Icarus encodings/extensions. */ case 'h': if (*rerun) { value = " x "; } else { value = " 1 "; *rerun = 1; } break; case 'l': if (*rerun) { value = " x "; } else { value = " 0 "; *rerun = 1; } break; case 'q': value = "(bx)"; break; case 'B': value = "(x?)"; break; case 'F': value = "(x0)"; break; case 'M': value = "(1x)"; break; case 'N': value = "(1?)"; break; case 'P': value = "(0?)"; break; case 'Q': value = "(0x)"; break; case 'R': value = "(x1)"; break; case '%': /* This is effectively the same as q. */ value = "(?x)"; break; case '+': value = "(?1)"; break; case '_': value = "(?0)"; break; default: fprintf(stderr, "%s:%u: vlog95 error: Unknown primitive table " "entry %c in primitive %s.\n", ivl_udp_file(udp), ivl_udp_lineno(udp), entry, ivl_udp_name(udp)); vlog_errors += 1; value = " "; break; } fprintf(vlog_out, "%s ", value); } static void emit_sequ_table(ivl_udp_t udp) { unsigned idx, count = ivl_udp_rows(udp); for (idx = 0; idx < count; idx += 1) { const char *row = ivl_udp_row(udp, idx); unsigned need_to_rerun = 0; do { unsigned entry, inputs = ivl_udp_nin(udp); unsigned rerun, rerunning = need_to_rerun; need_to_rerun = 0; fprintf(vlog_out, "%*c", 2*indent_incr, ' '); for (entry = 1; entry <= inputs; entry += 1) { rerun = rerunning; emit_entry(udp, row[entry], &rerun); if (rerun && ! rerunning) need_to_rerun = rerun; } fprintf(vlog_out, ": "); /* The first entry is the current state. */ rerun = rerunning; emit_entry(udp, row[0], &rerun); if (rerun && ! rerunning) need_to_rerun = rerun; fprintf(vlog_out, ": "); /* The new value is after the inputs. */ rerun = rerunning; emit_entry(udp, row[inputs+1], &rerun); if (rerun && ! rerunning) need_to_rerun = rerun; fprintf(vlog_out, ";\n"); } while (need_to_rerun); } } static void emit_comb_table(ivl_udp_t udp) { unsigned idx, count = ivl_udp_rows(udp); for (idx = 0; idx < count; idx += 1) { const char *row = ivl_udp_row(udp, idx); unsigned need_to_rerun = 0; do { unsigned entry, inputs = ivl_udp_nin(udp); unsigned rerun, rerunning = need_to_rerun; need_to_rerun = 0; fprintf(vlog_out, "%*c", 2*indent_incr, ' '); for (entry = 0; entry < inputs; entry += 1) { rerun = rerunning; emit_entry(udp, row[entry], &rerun); if (rerun && ! rerunning) need_to_rerun = rerun; } /* The new value is after the inputs. */ fprintf(vlog_out, ": "); rerun = rerunning; emit_entry(udp, row[inputs], &rerun); if (rerun && ! rerunning) need_to_rerun = rerun; fprintf(vlog_out, ";\n"); } while (need_to_rerun); } } static void emit_udp(ivl_udp_t udp) { unsigned idx, count; fprintf(vlog_out, "\n"); fprintf(vlog_out, "/* This primitive was originally defined in " "file %s at line %u. */\n", ivl_udp_file(udp), ivl_udp_lineno(udp)); fprintf(vlog_out, "primitive "); emit_id(ivl_udp_name(udp)); fprintf(vlog_out, " ("); emit_id(ivl_udp_port(udp, 0)); count = ivl_udp_nin(udp); for (idx = 1; idx <= count; idx += 1) { fprintf(vlog_out, ", "); emit_id(ivl_udp_port(udp, idx)); } fprintf(vlog_out, ");\n"); fprintf(vlog_out, "%*coutput ", indent_incr, ' '); emit_id(ivl_udp_port(udp, 0)); fprintf(vlog_out, ";\n"); for (idx = 1; idx <= count; idx += 1) { fprintf(vlog_out, "%*cinput ", indent_incr, ' '); emit_id(ivl_udp_port(udp, idx)); fprintf(vlog_out, ";\n"); } if (ivl_udp_sequ(udp)) { char init = ivl_udp_init(udp); fprintf(vlog_out, "\n"); fprintf(vlog_out, "%*creg ", indent_incr, ' '); emit_id(ivl_udp_port(udp, 0)); fprintf(vlog_out, ";\n"); switch (init) { case '0': case '1': break; default: init = 'x'; break; } fprintf(vlog_out, "%*cinitial ", indent_incr, ' '); emit_id(ivl_udp_port(udp, 0)); fprintf(vlog_out, " = 1'b%c;\n", init); } fprintf(vlog_out, "\n"); fprintf(vlog_out, "%*ctable\n", indent_incr, ' '); if (ivl_udp_sequ(udp)) emit_sequ_table(udp); else emit_comb_table(udp); fprintf(vlog_out, "%*cendtable\n", indent_incr, ' '); fprintf(vlog_out, "endprimitive /* %s */\n", ivl_udp_name(udp)); } static ivl_udp_t *udps = 0; static unsigned num_udps = 0; void add_udp_to_list(ivl_udp_t udp) { unsigned idx; /* Look to see if the UDP is already in the list. */ for (idx = 0; idx < num_udps; idx += 1) { if ((ivl_udp_lineno(udp) == ivl_udp_lineno(udps[idx])) && (strcmp(ivl_udp_name(udp), ivl_udp_name(udps[idx])) == 0)) { return; } } num_udps += 1; udps = realloc(udps, num_udps * sizeof(ivl_udp_t)); udps[num_udps-1] = udp; } void emit_udp_list() { unsigned idx; for (idx = 0; idx < num_udps; idx += 1) { emit_udp(udps[idx]); } free(udps); udps = 0; num_udps = 0; } iverilog-12_0/tgt-vlog95/vlog95-s.conf000066400000000000000000000002151435245347300175220ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:nodangle functor:exposenodes flag:DLL=vlog95.tgt flag:DISABLE_CONCATZ_GENERATION=true iverilog-12_0/tgt-vlog95/vlog95.c000066400000000000000000000217501435245347300165660ustar00rootroot00000000000000#define COPYRIGHT \ "Copyright (c) 2010-2021 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. * * * This is the vlog95 target module. It generates a 1364-1995 compliant * netlist from the input netlist. The generated netlist is expected to * be simulation equivalent to the original. */ # include "version_base.h" # include "version_tag.h" # include "config.h" # include "vlog95_priv.h" # include # include static const char*version_string = "Icarus Verilog VLOG95 Code Generator " VERSION " (" VERSION_TAG ")\n\n" COPYRIGHT "\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n" ; FILE*vlog_out; int vlog_errors = 0; int sim_precision = 0; unsigned indent = 0; unsigned indent_incr = 2; unsigned emit_file_line = 0; unsigned allow_signed = 0; ivl_design_t design = 0; int target_design(ivl_design_t des) { ivl_scope_t *roots; unsigned nroots, idx; const char*path = ivl_design_flag(des, "-o"); /* Set the indent spacing with the -pspacing flag passed to iverilog * (e.g. -pspacing=4). The default is 2 spaces. */ const char*spacing_str = ivl_design_flag(des, "spacing"); /* Use -pfileline to determine if file and line information is * printed for most lines. (e.g. -pfileline=1). The default is no * file/line information will be printed for individual lines. */ const char*fileline_str = ivl_design_flag(des, "fileline"); /* Use -pallowsigned to allow signed registers/nets and the * $signed() and $unsigned() system tasks as an extension. */ const char*allowsigned_str = ivl_design_flag(des, "allowsigned"); assert(path); /* Check for and use a provided indent spacing. */ if (strcmp(spacing_str, "") != 0) { char *eptr; long value = strtol(spacing_str, &eptr, 0); /* Nothing usable in the spacing string. */ if (spacing_str == eptr) { fprintf(stderr, "vlog95 error: Unable to extract spacing " "increment from string: %s\n", spacing_str); return 1; } /* Extra stuff at the end. */ if (*eptr != 0) { fprintf(stderr, "vlog95 error: Extra characters '%s' " "included at end of spacing string: %s\n", eptr, spacing_str); return 1; } /* The increment must be greater than zero. */ if (value < 1) { fprintf(stderr, "vlog95 error: Spacing increment (%ld) must " "be greater than zero.\n", value); return 1; } /* An increment of more than sixteen is too much. */ if (value > 16) { fprintf(stderr, "vlog95 error: Spacing increment (%ld) must " "be sixteen or less.\n", value); return 1; } indent_incr = value; } /* Check to see if file/line information should be printed. */ if (strcmp(fileline_str, "") != 0) { char *eptr; long value = strtol(fileline_str, &eptr, 0); /* Nothing usable in the file/line string. */ if (fileline_str == eptr) { fprintf(stderr, "vlog95 error: Unable to extract file/line " "information from string: %s\n", fileline_str); return 1; } /* Extra stuff at the end. */ if (*eptr != 0) { fprintf(stderr, "vlog95 error: Extra characters '%s' " "included at end of file/line string: %s\n", eptr, fileline_str); return 1; } /* The file/line flag must be positive. */ if (value < 0) { fprintf(stderr, "vlog95 error: File/line flag (%ld) must " "be positive.\n", value); return 1; } emit_file_line = value > 0; } /* Check to see if we should also print signed constructs. */ if (strcmp(allowsigned_str, "") != 0) { char *eptr; long value = strtol(allowsigned_str, &eptr, 0); /* Nothing usable in the allow signed string. */ if (allowsigned_str == eptr) { fprintf(stderr, "vlog95 error: Unable to extract allow " "signed information from string: %s\n", allowsigned_str); return 1; } /* Extra stuff at the end. */ if (*eptr != 0) { fprintf(stderr, "vlog95 error: Extra characters '%s' " "included at end of allow signed string: " "%s\n", eptr, allowsigned_str); return 1; } /* The allow signed flag must be positive. */ if (value < 0) { fprintf(stderr, "vlog95 error: Allow signed flag (%ld) must " "be positive.\n", value); return 1; } allow_signed = value > 0; } design = des; #ifdef HAVE_FOPEN64 vlog_out = fopen64(path, "w"); #else vlog_out = fopen(path, "w"); #endif if (vlog_out == 0) { perror(path); return -1; } fprintf(vlog_out, "/*\n"); fprintf(vlog_out, " * 1364-1995 Verilog generated by Icarus Verilog " "VLOG95 Code Generator,\n"); fprintf(vlog_out, " * Version: " VERSION " (" VERSION_TAG ")\n"); fprintf(vlog_out, " * Converted using %s delays and %s signed support.\n", ivl_design_delay_sel(des), allow_signed ? "with" : "without"); fprintf(vlog_out, " */\n"); sim_precision = ivl_design_time_precision(des); /* Get all the root modules and then convert each one. */ ivl_design_roots(des, &roots, &nroots); /* Emit any root scope tasks or functions first. */ for (idx = 0; idx < nroots; idx += 1) { switch(ivl_scope_type(roots[idx])) { case IVL_SCT_FUNCTION: case IVL_SCT_TASK: /* Create a separate module for each task/function. This allows us to handle different timescales. */ fprintf(vlog_out, "\n`timescale %s/%s\n", get_time_const(ivl_scope_time_units(roots[idx])), get_time_const(ivl_scope_time_precision(roots[idx]))); fprintf(vlog_out, "module ivl_root_scope_%s;\n", ivl_scope_basename(roots[idx])); indent += indent_incr; /* Say this task/function has a parent so the * definition is emitted correctly. */ emit_scope(roots[idx], roots[idx]); indent -= indent_incr; assert(indent == 0); fprintf(vlog_out, "endmodule /* ivl_root_scope_%p */\n", roots[idx]); break; default: break; } } /* Emit the rest of the scope objects. */ for (idx = 0; idx < nroots; idx += 1) emit_scope(roots[idx], 0); free_emitted_scope_list(); /* Emit any UDP definitions that the design used. */ emit_udp_list(); /* Emit any UDPs that are Icarus generated (D-FF or latch). */ emit_icarus_generated_udps(); /* Emit the Icarus top module used to trigger translated always_comb/latch processes at T0. */ emit_icarus_generated_top_module(); /* If there were errors then add this information to the output. */ if (vlog_errors) { fprintf(vlog_out, "\n"); fprintf(vlog_out, "/*\n"); if (vlog_errors == 1) { fprintf(vlog_out, " * There was 1 error during " "translation.\n"); } else { fprintf(vlog_out, " * There were %d errors during " "translation.\n", vlog_errors); } fprintf(vlog_out, " */\n"); /* Add something that makes the file invalid to make sure * the user knows there were errors. */ fprintf(vlog_out, "\n"); } fclose(vlog_out); /* A do nothing call to prevent warnings about this routine not * being used. */ dump_nexus_information(0, 0); return vlog_errors; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } iverilog-12_0/tgt-vlog95/vlog95.conf000066400000000000000000000000711435245347300172620ustar00rootroot00000000000000flag:DLL=vlog95.tgt flag:DISABLE_CONCATZ_GENERATION=true iverilog-12_0/tgt-vlog95/vlog95_priv.h000066400000000000000000000133711435245347300176330ustar00rootroot00000000000000#ifndef IVL_vlog95_priv_H #define IVL_vlog95_priv_H /* * Copyright (C) 2010-2019 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. */ # include "config.h" # include "ivl_target.h" # include # include # include /* * The design we are emitting. */ extern ivl_design_t design; /* * This is the file that the converted design is written to. */ extern FILE*vlog_out; /* * Keep a count of the fatal errors that happen during code generation. */ extern int vlog_errors; /* * Keep the simulation time precision so that we can scale delays. */ extern int sim_precision; /* * The expression code needs to know when a parameter definition is being * emitted so it can emit the numeric value instead of the name. */ extern ivl_parameter_t emitting_param; /* * The statement code needs to know what name to use for a translated * function return statement (disable). */ extern const char *func_rtn_name; /* * Keep the current indent level. */ extern unsigned indent; extern unsigned indent_incr; /* * Set to non-zero when the user wants to emit all the file and line * number information. */ extern unsigned emit_file_line; /* * Some tools that are mostly 1364-1995 compliant also support signed so * add support for that as an extension. */ extern unsigned allow_signed; /* * Emit various Verilog types. */ extern void emit_event(ivl_scope_t scope, ivl_statement_t stmt); extern void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned width, unsigned is_lval_width, unsigned can_skip_unsigned, unsigned is_full_prec); extern void emit_logic(ivl_scope_t scope, ivl_net_logic_t nlogic); extern void emit_lpm(ivl_scope_t scope, ivl_lpm_t lpm); extern void emit_process(ivl_scope_t scope, ivl_process_t proc); extern int emit_scope(ivl_scope_t scope, ivl_scope_t parent); extern void emit_stmt(ivl_scope_t scope, ivl_statement_t stmt); extern void emit_tran(ivl_scope_t scope, ivl_switch_t tran); extern void emit_scaled_delay(ivl_scope_t scope, uint64_t delay); extern void emit_scaled_delayx(ivl_scope_t scope, ivl_expr_t expr, unsigned is_stmt); extern void emit_scaled_expr(ivl_scope_t scope, ivl_expr_t expr, int msb, int lsb); extern void emit_scaled_range(ivl_scope_t scope, ivl_expr_t expr, unsigned width, int msb, int lsb); extern void emit_scope_path(ivl_scope_t scope, ivl_scope_t call_scope); extern void emit_scope_variables(ivl_scope_t scope); extern void emit_scope_call_path(ivl_scope_t scope, ivl_scope_t call_scope); extern void emit_scope_module_path(ivl_scope_t scope, ivl_scope_t call_scope); extern void emit_name_of_nexus(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD); extern void emit_nexus_as_ca(ivl_scope_t scope, ivl_nexus_t nex, unsigned allow_UD, unsigned sign_extend); extern void emit_nexus_port_driver_as_ca(ivl_scope_t scope, ivl_nexus_t nex); extern void emit_const_nexus(ivl_scope_t scope, ivl_net_const_t const_net); extern void emit_signal_net_const_as_ca(ivl_scope_t scope, ivl_signal_t sig); extern void add_udp_to_list(ivl_udp_t udp); extern void emit_udp_list(void); extern void emit_sig_file_line(ivl_signal_t sig); extern void emit_id(const char *id); extern void emit_real_number(double value); extern void emit_number(const char *bits, unsigned nbits, unsigned is_signed, const char *file, unsigned lineno); extern void emit_string(const char *string); extern void emit_icarus_generated_udps(void); extern void emit_icarus_generated_top_module(void); /* * Find the enclosing module scope. */ extern ivl_scope_t get_module_scope(ivl_scope_t scope); /* * Get an int32_t/uint64_t from a number is possible. The return type is * 0 for a valid value, negative for a number with undefined bits and * positive it the value is too large. The positive value is the minimum * number of bits required to represent the value. */ extern int32_t get_int32_from_number(ivl_expr_t expr, int *return_type); extern int64_t get_int64_from_number(ivl_expr_t expr, int *return_type); extern uint64_t get_uint64_from_number(ivl_expr_t expr, int *return_type); /* * A package is translated to a module with a special name. This routine * does that translation. To avoid a memory leak the calling routine must * use free() to cleanup the string returned. */ extern char * get_package_name(ivl_scope_t scope); /* * Get the appropriate MSB and LSB for a signal. */ extern void get_sig_msb_lsb(ivl_signal_t sig, int *msb, int *lsb); /* * Convert a timescale value to a string. */ extern const char*get_time_const(int time_value); /* * Cleanup functions. */ extern void free_emitted_scope_list(void); /* * Debug routine to dump the various pieces of nexus information. */ extern void dump_nexus_information(ivl_scope_t scope, ivl_nexus_t nex); static inline unsigned is_void_function(ivl_scope_t scope) { return ivl_scope_type(scope) == IVL_SCT_FUNCTION && ivl_scope_port(scope, 0) == 0; } #endif /* IVL_vlog95_priv_H */ iverilog-12_0/tgt-vvp/000077500000000000000000000000001435245347300147565ustar00rootroot00000000000000iverilog-12_0/tgt-vvp/COPYING.lesser000066400000000000000000000636421435245347300173200ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 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. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; 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. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! iverilog-12_0/tgt-vvp/Makefile.in000066400000000000000000000067051435245347300170330ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # #ident "$Id: Makefile.in,v 1.26 2007/02/06 05:07:32 steve Exp $" # # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ LDFLAGS = @LDFLAGS@ O = vvp.o draw_class.o draw_delay.o draw_enum.o draw_mux.o draw_net_input.o \ draw_substitute.o draw_switch.o draw_ufunc.o draw_vpi.o \ eval_condit.o \ eval_expr.o eval_object.o eval_real.o eval_string.o \ eval_vec4.o \ modpath.o stmt_assign.o \ vvp_process.o vvp_scope.o all: dep vvp.tgt vvp.conf vvp-s.conf check: all clean: rm -rf *.o dep vvp.tgt vvp.conf vvp-s.conf distclean: clean rm -f Makefile config.log rm -f stamp-vvp_config-h vvp_config.h cppcheck: $(O:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=tgt-vvp/$@ dep: mkdir dep %.o: %.c vvp_config.h $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep ifeq (@WIN32@,yes) TGTLDFLAGS=-L.. -livl TGTDEPLIBS=../libivl.a else TGTLDFLAGS= TGTDEPLIBS= endif vvp.tgt: $O $(TGTDEPLIBS) $(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS) vvp.conf: $(srcdir)/vvp.conf.in Makefile echo 'flag:VVP_EXECUTABLE=$(bindir)/vvp$(suffix)' | cat $(srcdir)/vvp.conf.in - > vvp.conf vvp-s.conf: $(srcdir)/vvp-s.conf.in Makefile echo 'flag:VVP_EXECUTABLE=$(bindir)/vvp$(suffix)' | cat $(srcdir)/vvp-s.conf.in - > vvp-s.conf stamp-vvp_config-h: $(srcdir)/vvp_config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=tgt-vvp/vvp_config.h vvp_config.h: stamp-vvp_config-h install: all installdirs installfiles F = ./vvp.tgt \ ./vvp.conf \ ./vvp-s.conf installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vvp.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp.tgt" $(INSTALL_DATA) ./vvp.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp.conf" $(INSTALL_DATA) ./vvp-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp-s.conf" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp.tgt" "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp.conf" "$(DESTDIR)$(libdir)/ivl$(suffix)/vvp-s.conf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/tgt-vvp/README.txt000066400000000000000000000017211435245347300164550ustar00rootroot00000000000000 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-12_0/tgt-vvp/cppcheck.sup000066400000000000000000000002711435245347300172670ustar00rootroot00000000000000// These are the global access functions called from the compiler so they // are not used here. // target_design() unusedFunction:vvp.c:152 // target_query() unusedFunction:vvp.c:250 iverilog-12_0/tgt-vvp/draw_class.c000066400000000000000000000056621435245347300172550ustar00rootroot00000000000000/* * Copyright (c) 2012 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 "vvp_priv.h" # include # include # include # include static void show_prop_type_vector(ivl_type_t ptype) { ivl_variable_type_t data_type = ivl_type_base(ptype); unsigned packed_dimensions = ivl_type_packed_dimensions(ptype); assert(packed_dimensions < 2); const char*signed_flag = ivl_type_signed(ptype)? "s" : ""; char code = data_type==IVL_VT_BOOL? 'b' : 'L'; if (packed_dimensions == 0) { fprintf(vvp_out, "\"%s%c1\"", signed_flag, code); } else { assert(packed_dimensions == 1); assert(ivl_type_packed_lsb(ptype,0) == 0); assert(ivl_type_packed_msb(ptype,0) >= 0); fprintf(vvp_out, "\"%s%c%d\"", signed_flag, code, ivl_type_packed_msb(ptype,0)+1); } } static void show_prop_type(ivl_type_t ptype) { ivl_variable_type_t data_type = ivl_type_base(ptype); unsigned packed_dimensions = ivl_type_packed_dimensions(ptype); switch (data_type) { case IVL_VT_REAL: fprintf(vvp_out, "\"r\""); break; case IVL_VT_STRING: fprintf(vvp_out, "\"S\""); break; case IVL_VT_BOOL: case IVL_VT_LOGIC: show_prop_type_vector(ptype); break; case IVL_VT_DARRAY: case IVL_VT_CLASS: fprintf(vvp_out, "\"o\""); if (packed_dimensions > 0) { unsigned idx; fprintf(vvp_out, " "); for (idx = 0 ; idx < packed_dimensions ; idx += 1) { fprintf(vvp_out, "[%d:%d]", ivl_type_packed_msb(ptype,idx), ivl_type_packed_lsb(ptype,idx)); } } break; default: fprintf(vvp_out, "\"\""); assert(0); break; } } void draw_class_in_scope(ivl_type_t classtype) { int idx; fprintf(vvp_out, "C%p .class \"%s\" [%d]\n", classtype, ivl_type_name(classtype), ivl_type_properties(classtype)); for (idx = 0 ; idx < ivl_type_properties(classtype) ; idx += 1) { fprintf(vvp_out, " %3d: \"%s\", ", idx, ivl_type_prop_name(classtype,idx)); show_prop_type(ivl_type_prop_type(classtype,idx)); fprintf(vvp_out, "\n"); } fprintf(vvp_out, " ;\n"); } iverilog-12_0/tgt-vvp/draw_delay.c000066400000000000000000000100251435245347300172330ustar00rootroot00000000000000/* * Copyright (c) 2016 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 "vvp_priv.h" # include # include # include /* * This function draws a BUFT to drive a constant delay value. */ static char* draw_const_net(void*ptr, char*suffix, uint64_t value) { char tmp[64]; char c4_value[69]; unsigned idx; c4_value[0] = 'C'; c4_value[1] = '4'; c4_value[2] = '<'; for (idx = 0; idx < 64; idx += 1) { c4_value[66-idx] = (value & 1) ? '1' : '0'; value >>= 1; } c4_value[67] = '>'; c4_value[68] = 0; /* Make the constant an argument to a BUFT, which is what we use to drive the value. */ fprintf(vvp_out, "L_%p/%s .functor BUFT 1, %s, C4<0>, C4<0>, C4<0>;\n", ptr, suffix, c4_value); snprintf(tmp, sizeof tmp, "L_%p/%s", ptr, suffix); return strdup(tmp); } /* * Draw the appropriate delay statement. */ void draw_delay(void*ptr, unsigned wid, const char*input, ivl_expr_t rise_exp, ivl_expr_t fall_exp, ivl_expr_t decay_exp) { char tmp[64]; if (input == 0) { snprintf(tmp, sizeof tmp, "L_%p/d", ptr); input = tmp; } /* If the delays are all constants then process them here. */ if (number_is_immediate(rise_exp, 64, 0) && number_is_immediate(fall_exp, 64, 0) && number_is_immediate(decay_exp, 64, 0)) { assert(! number_is_unknown(rise_exp)); assert(! number_is_unknown(fall_exp)); assert(! number_is_unknown(decay_exp)); fprintf(vvp_out, "L_%p .delay %u " "(%" PRIu64 ",%" PRIu64 ",%" PRIu64 ") %s;\n", ptr, wid, get_number_immediate64(rise_exp), get_number_immediate64(fall_exp), get_number_immediate64(decay_exp), input); /* For a variable delay we indicate only two delays by setting the * decay time to zero. */ } else { char*rise_const = 0; char*fall_const = 0; char*decay_const = 0; const char*rise_str; const char*fall_str; const char*decay_str; if (number_is_immediate(rise_exp, 64, 0)) { uint64_t value = get_number_immediate64(rise_exp); rise_str = rise_const = draw_const_net(ptr, "tr", value); } else { ivl_signal_t sig = ivl_expr_signal(rise_exp); assert(sig && ivl_signal_dimensions(sig) == 0); rise_str = draw_net_input(ivl_signal_nex(sig,0)); } if (number_is_immediate(fall_exp, 64, 0)) { uint64_t value = get_number_immediate64(fall_exp); fall_str = fall_const = draw_const_net(ptr, "tf", value); } else { ivl_signal_t sig = ivl_expr_signal(fall_exp); assert(sig && ivl_signal_dimensions(sig) == 0); fall_str = draw_net_input(ivl_signal_nex(sig,0)); } if (decay_exp == 0) { decay_str = "0"; } else if (number_is_immediate(decay_exp, 64, 0)) { uint64_t value = get_number_immediate64(decay_exp); decay_str = decay_const = draw_const_net(ptr, "td", value); } else { ivl_signal_t sig = ivl_expr_signal(decay_exp); assert(sig && ivl_signal_dimensions(sig) == 0); decay_str = draw_net_input(ivl_signal_nex(sig,0)); } fprintf(vvp_out, "L_%p .delay %u %s, %s, %s, %s;\n", ptr, wid, input, rise_str, fall_str, decay_str); free(rise_const); free(fall_const); free(decay_const); } } iverilog-12_0/tgt-vvp/draw_enum.c000066400000000000000000000057641435245347300171170ustar00rootroot00000000000000/* * Copyright (c) 2010-2011 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 "vvp_priv.h" # include "ivl_alloc.h" # include # include # include # include // HERE: This still needs work! Fall back to 'b format for // very large constants. We also should pass the file and // line number information for the enum type and the MSB and // LSB should be used instead of the width. /* * If it fits we always print this as a uint64_t the run time will turn * it back into a signed value when needed. */ static void draw_enum2_value(ivl_enumtype_t enumtype, unsigned idx) { uint64_t val, mask; const char*bits = ivl_enum_bits(enumtype, idx); const char*bit; unsigned len = strlen(bits); // HERE: If this doesn't fit then write it as a enum4 and modify the run // time to deal with the conversion. assert(len <= sizeof(uint64_t)*8); val = 0; for (bit = bits, mask = 1 ; *bit != 0 ; bit += 1, mask <<= 1) { if (*bit == '1') val |= mask; } fprintf(vvp_out, "%" PRIu64, val); } static void draw_enum4_value(ivl_enumtype_t enumtype, unsigned idx) { const char*bits = ivl_enum_bits(enumtype, idx); const char*bit; fprintf(vvp_out, "%u'b", ivl_enum_width(enumtype)); for (bit = bits+strlen(bits) ; bit > bits ; bit -= 1) fputc(bit[-1], vvp_out); } void draw_enumeration_in_scope(ivl_enumtype_t enumtype) { unsigned idx; unsigned name_count = ivl_enum_names(enumtype); const char*dtype = ivl_enum_type(enumtype)==IVL_VT_BOOL? "2" : "4"; const char*stype = ivl_enum_signed(enumtype) ? "/s" : ""; fprintf(vvp_out, "enum%p .enum%s%s (%u)\n", enumtype, dtype, stype, ivl_enum_width(enumtype)); for (idx = 0 ; idx < name_count ; idx += 1) { fprintf(vvp_out, " \"%s\" ", ivl_enum_name(enumtype, idx)); switch (ivl_enum_type(enumtype)) { case IVL_VT_BOOL: draw_enum2_value(enumtype, idx); break; case IVL_VT_LOGIC: draw_enum4_value(enumtype, idx); break; default: assert(0); } if ((idx+1) < name_count) fputc(',', vvp_out); fputc('\n', vvp_out); } fprintf(vvp_out, " ;\n"); } iverilog-12_0/tgt-vvp/draw_mux.c000066400000000000000000000113251435245347300167520ustar00rootroot00000000000000/* * Copyright (c) 2002-2016 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 "vvp_priv.h" # include # include # include /* * This draws a simple A/B mux. The mux can have any width, enough * MUXZ nodes are created to support the vector. */ static void draw_lpm_mux_ab(ivl_lpm_t net, const char*muxz) { unsigned width = ivl_lpm_width(net); ivl_expr_t d_rise, d_fall, d_decay; const char*dly; const char* input[3]; /* Only support A-B muxes in this function. */ assert(ivl_lpm_size(net) == 2); assert(ivl_lpm_selects(net) == 1); d_rise = ivl_lpm_delay(net, 0); d_fall = ivl_lpm_delay(net, 1); d_decay = ivl_lpm_delay(net, 2); ivl_drive_t str0 = ivl_lpm_drive0(net); ivl_drive_t str1 = ivl_lpm_drive1(net); dly = ""; if (d_rise != 0) { unsigned dly_width = width; if (data_type_of_nexus(ivl_lpm_q(net)) == IVL_VT_REAL) dly_width = 0; draw_delay(net, dly_width, 0, d_rise, d_fall, d_decay); dly = "/d"; } input[0] = draw_net_input(ivl_lpm_data(net,0)); input[1] = draw_net_input(ivl_lpm_data(net,1)); input[2] = draw_net_input(ivl_lpm_select(net)); fprintf(vvp_out, "L_%p%s .functor %s %u", net, dly, muxz, width); if (str0!=IVL_DR_STRONG || str1!=IVL_DR_STRONG) fprintf(vvp_out, " [%d %d]", str0, str1); fprintf(vvp_out, ", %s", input[0]); fprintf(vvp_out, ", %s", input[1]); fprintf(vvp_out, ", %s", input[2]); fprintf(vvp_out, ", C4<>;\n"); } static void draw_lpm_mux_nest(ivl_lpm_t net, const char*muxz) { unsigned idx, level; unsigned width = ivl_lpm_width(net); unsigned swidth = ivl_lpm_selects(net); char*select_input; assert(swidth < 8*sizeof(unsigned)); assert(ivl_lpm_size(net) == (1U << swidth)); select_input = strdup(draw_net_input(ivl_lpm_select(net))); fprintf(vvp_out, "L_%p/0s .part %s, 0, 1; Bit 0 of the select\n", net, select_input); for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 2) { fprintf(vvp_out, "L_%p/0/%u .functor %s %u", net, idx/2, muxz, width); fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,idx+0))); fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,idx+1))); fprintf(vvp_out, ", L_%p/0s, C4<>;\n", net); } for (level = 1 ; level < swidth-1 ; level += 1) { fprintf(vvp_out, "L_%p/%us .part %s, %u, 1; Bit %u of the select\n", net, level, select_input, level, level); for (idx = 0 ; idx < (ivl_lpm_size(net) >> level); idx += 2) { fprintf(vvp_out, "L_%p/%u/%u .functor %s %u", net, level, idx/2, muxz, width); fprintf(vvp_out, ", L_%p/%u/%u", net, level-1, idx+0); fprintf(vvp_out, ", L_%p/%u/%u", net, level-1, idx+1); fprintf(vvp_out, ", L_%p/%us", net, level); fprintf(vvp_out, ", C4<>;\n"); } } fprintf(vvp_out, "L_%p/%us .part %s, %u, 1; Bit %u of the select\n", net, swidth-1, select_input, swidth-1, swidth-1); fprintf(vvp_out, "L_%p .functor %s %u", net, muxz, width); fprintf(vvp_out, ", L_%p/%u/0", net, swidth-2); fprintf(vvp_out, ", L_%p/%u/1", net, swidth-2); fprintf(vvp_out, ", L_%p/%us", net, swidth-1); fprintf(vvp_out, ", C4<>;\n"); free(select_input); } void draw_lpm_mux(ivl_lpm_t net) { const char*muxz = "MUXZ"; /* The output of the mux defines the type of the mux. the ivl_target should guarantee that all the inputs are the same type as the output. */ switch (data_type_of_nexus(ivl_lpm_q(net))) { case IVL_VT_REAL: muxz = "MUXR"; break; default: muxz = "MUXZ"; break; } if ((ivl_lpm_size(net) == 2) && (ivl_lpm_selects(net) == 1)) { draw_lpm_mux_ab(net, muxz); return; } /* Here we are at the worst case, we generate a tree of MUXZ devices to handle the arbitrary size. */ draw_lpm_mux_nest(net, muxz); } iverilog-12_0/tgt-vvp/draw_net_input.c000066400000000000000000000556611435245347300201610ustar00rootroot00000000000000/* * Copyright (c) 2001-2020 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 "vvp_priv.h" # include # include # include # include # include # include # include "ivl_alloc.h" static ivl_signal_type_t signal_type_of_nexus(ivl_nexus_t nex) { unsigned idx; ivl_signal_type_t out = IVL_SIT_TRI; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_signal_type_t stype; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; stype = ivl_signal_type(sig); if (stype == IVL_SIT_REG) continue; if (stype == IVL_SIT_TRI) continue; if (stype == IVL_SIT_NONE) continue; if (stype == IVL_SIT_UWIRE) return IVL_SIT_UWIRE; out = stype; } return out; } static ivl_variable_type_t signal_data_type_of_nexus(ivl_nexus_t nex) { unsigned idx; ivl_variable_type_t out = IVL_VT_NO_TYPE; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_variable_type_t vtype; ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; vtype = ivl_signal_data_type(sig); if (out == IVL_VT_NO_TYPE && vtype == IVL_VT_BOOL) { out = vtype; continue; } if (out != IVL_VT_LOGIC && vtype == IVL_VT_LOGIC) { out = vtype; continue; } if (vtype == IVL_VT_REAL) { out = vtype; break; } } return out; } static char* draw_C4_to_string(ivl_net_const_t cptr) { const char*bits = ivl_const_bits(cptr); unsigned idx; size_t result_len = 5 + ivl_const_width(cptr); char*result = malloc(result_len); char*dp = result; strcpy(dp, "C4<"); dp += strlen(dp); for (idx = 0 ; idx < ivl_const_width(cptr) ; idx += 1) { char bitchar = bits[ivl_const_width(cptr)-idx-1]; *dp++ = bitchar; assert(dp >= result); assert((unsigned)(dp - result) < result_len); } strcpy(dp, ">"); return result; } static char* draw_C8_to_string(ivl_net_const_t cptr, ivl_drive_t dr0, ivl_drive_t dr1) { size_t nresult = 5 + 3*ivl_const_width(cptr); char*result = malloc(nresult); const char*bits = ivl_const_bits(cptr); unsigned idx; char dr0c = "01234567"[dr0]; char dr1c = "01234567"[dr1]; char*dp = result; strcpy(dp, "C8<"); dp += strlen(dp); for (idx = 0 ; idx < ivl_const_width(cptr) ; idx += 1) { switch (bits[ivl_const_width(cptr)-idx-1]) { case '0': *dp++ = dr0c; *dp++ = dr0c; *dp++ = '0'; break; case '1': *dp++ = dr1c; *dp++ = dr1c; *dp++ = '1'; break; case 'x': case 'X': *dp++ = dr0c; *dp++ = dr1c; *dp++ = 'x'; break; case 'z': case 'Z': *dp++ = '0'; *dp++ = '0'; *dp++ = 'z'; break; default: assert(0); break; } assert(dp >= result); assert((unsigned)(dp - result) < nresult); } strcpy(dp, ">"); return result; } static struct vvp_nexus_data*new_nexus_data(void) { struct vvp_nexus_data*data = calloc(1, sizeof(struct vvp_nexus_data)); return data; } static int nexus_drive_is_strength_aware(ivl_nexus_ptr_t nptr) { ivl_net_logic_t logic; if (ivl_nexus_ptr_drive0(nptr) != IVL_DR_STRONG) return 1; if (ivl_nexus_ptr_drive1(nptr) != IVL_DR_STRONG) return 1; logic = ivl_nexus_ptr_log(nptr); if (logic != 0) { /* These logic gates are able to generate unusual strength values and so their outputs are considered strength aware. */ if (ivl_logic_type(logic) == IVL_LO_BUFIF0) return 1; if (ivl_logic_type(logic) == IVL_LO_BUFIF1) return 1; if (ivl_logic_type(logic) == IVL_LO_PMOS) return 1; if (ivl_logic_type(logic) == IVL_LO_NMOS) return 1; if (ivl_logic_type(logic) == IVL_LO_CMOS) return 1; } return 0; } /* * Given a nexus, look for a signal that has module delay * paths. Return that signal. (There should be no more than 1.) If we * don't find any, then return nil. */ static ivl_signal_t find_modpath(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex,idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; if (ivl_signal_npath(sig) == 0) continue; return sig; } return 0; } static void str_repeat(char*buf, const char*str, unsigned rpt) { unsigned idx; size_t len = strlen(str); for (idx = 0 ; idx < rpt ; idx += 1) { strcpy(buf, str); buf += len; } } /* * This function draws a BUFT to drive a net pullup or pulldown value. * If the drive strength is strong we can draw a C4<> constant as the * pull value, otherwise we need to draw a C8<> constant. */ static char* draw_net_pull(ivl_net_logic_t lptr, ivl_drive_t drive, const char*level) { char*result; char tmp[32]; if (drive == IVL_DR_STRONG) { size_t result_len = 5 + ivl_logic_width(lptr); result = malloc(result_len); char*dp = result; strcpy(dp, "C4<"); dp += strlen(dp); str_repeat(dp, level, ivl_logic_width(lptr)); dp += ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; assert(dp >= result); assert((unsigned)(dp - result) <= result_len); } else { char val[4]; size_t result_len = 5 + 3*ivl_logic_width(lptr); result = malloc(result_len); char*dp = result; val[0] = "01234567"[drive]; val[1] = val[0]; val[2] = level[0]; val[3] = 0; strcpy(dp, "C8<"); dp += strlen(dp); str_repeat(dp, val, ivl_logic_width(lptr)); dp += 3*ivl_logic_width(lptr); *dp++ = '>'; *dp = 0; assert(dp >= result); assert((unsigned)(dp - result) <= result_len); } /* Make the constant an argument to a BUFZ, which is what we use to drive the PULLed value. */ fprintf(vvp_out, "L_%p .functor BUFT 1, %s, C4<0>, C4<0>, C4<0>;\n", lptr, result); snprintf(tmp, sizeof tmp, "L_%p", lptr); result = realloc(result, strlen(tmp)+1); strcpy(result, tmp); return result; } /* * This function takes a nexus and looks for an input functor. It then * draws to the output a string that represents that functor. What we * are trying to do here is find the input to the net that is attached * to this nexus. */ static char* draw_net_input_drive(ivl_nexus_t nex, ivl_nexus_ptr_t nptr) { unsigned nptr_pin = ivl_nexus_ptr_pin(nptr); ivl_net_const_t cptr; ivl_net_logic_t lptr; ivl_signal_t sptr; ivl_lpm_t lpm; lptr = ivl_nexus_ptr_log(nptr); if (lptr && ((ivl_logic_type(lptr)==IVL_LO_BUFZ)||(ivl_logic_type(lptr)==IVL_LO_BUFT)) && (nptr_pin == 0)) do { if (! can_elide_bufz(lptr, nptr)) break; return strdup(draw_net_input(ivl_logic_pin(lptr, 1))); } while(0); if (lptr && (ivl_logic_type(lptr) == IVL_LO_PULLDOWN)) { return draw_net_pull(lptr, ivl_nexus_ptr_drive0(nptr), "0"); } if (lptr && (ivl_logic_type(lptr) == IVL_LO_PULLUP)) { return draw_net_pull(lptr, ivl_nexus_ptr_drive1(nptr), "1"); } if (lptr && (nptr_pin == 0)) { char tmp[128]; snprintf(tmp, sizeof tmp, "L_%p", lptr); return strdup(tmp); } sptr = ivl_nexus_ptr_sig(nptr); if (sptr && (ivl_signal_type(sptr) == IVL_SIT_REG)) { char tmp[128]; /* Input is a .var. This device may be a non-zero pin because it may be an array of reg vectors. */ snprintf(tmp, sizeof tmp, "v%p_%u", sptr, nptr_pin); if (ivl_signal_dimensions(sptr) > 0) { fprintf(vvp_out, "v%p_%u .array/port v%p, %u;\n", sptr, nptr_pin, sptr, nptr_pin); } return strdup(tmp); } cptr = ivl_nexus_ptr_con(nptr); if (cptr) { char tmp[64]; char *result = 0; ivl_expr_t d_rise, d_fall, d_decay; unsigned dly_width = 0; char *dly; /* Constants should have exactly 1 pin, with a literal value. */ assert(nptr_pin == 0); switch (ivl_const_type(cptr)) { case IVL_VT_LOGIC: case IVL_VT_BOOL: case IVL_VT_STRING: if ((ivl_nexus_ptr_drive0(nptr) == IVL_DR_STRONG) && (ivl_nexus_ptr_drive1(nptr) == IVL_DR_STRONG)) { result = draw_C4_to_string(cptr); } else { result = draw_C8_to_string(cptr, ivl_nexus_ptr_drive0(nptr), ivl_nexus_ptr_drive1(nptr)); } dly_width = ivl_const_width(cptr); break; case IVL_VT_REAL: result = draw_Cr_to_string(ivl_const_real(cptr)); dly_width = 0; break; default: assert(0); break; } d_rise = ivl_const_delay(cptr, 0); d_fall = ivl_const_delay(cptr, 1); d_decay = ivl_const_delay(cptr, 2); dly = ""; if (d_rise != 0) { draw_delay(cptr, dly_width, 0, d_rise, d_fall, d_decay); dly = "/d"; } fprintf(vvp_out, "L_%p%s .functor BUFT 1, %s, C4<0>, C4<0>, C4<0>;\n", cptr, dly, result); free(result); snprintf(tmp, sizeof tmp, "L_%p", cptr); return strdup(tmp); } lpm = ivl_nexus_ptr_lpm(nptr); if (lpm) switch (ivl_lpm_type(lpm)) { case IVL_LPM_FF: case IVL_LPM_LATCH: case IVL_LPM_ABS: case IVL_LPM_ADD: case IVL_LPM_ARRAY: case IVL_LPM_CAST_INT2: case IVL_LPM_CAST_INT: case IVL_LPM_CAST_REAL: case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: case IVL_LPM_SFUNC: case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: case IVL_LPM_SIGN_EXT: case IVL_LPM_SUB: case IVL_LPM_MULT: case IVL_LPM_MUX: case IVL_LPM_POW: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_UFUNC: case IVL_LPM_PART_VP: case IVL_LPM_PART_PV: /* NOTE: This is only a partial driver. */ case IVL_LPM_REPEAT: case IVL_LPM_SUBSTITUTE: if (ivl_lpm_q(lpm) == nex) { char tmp[128]; snprintf(tmp, sizeof tmp, "L_%p", lpm); return strdup(tmp); } break; } fprintf(stderr, "vvp.tgt error: no input to nexus.\n"); assert(0); return strdup("C"); } static char* draw_island_port(ivl_island_t island, int island_input_flag, ivl_nexus_t nex, struct vvp_nexus_data*nex_data, const char*src) { char result[64]; if (ivl_island_flag_test(island,0) == 0) { fprintf(vvp_out, "I%p .island tran;\n", island); ivl_island_flag_set(island,0,1); } snprintf(result, sizeof result, "p%p", nex); assert(nex_data->island == 0); nex_data->island = island; assert(nex_data->island_input == 0); nex_data->island_input = strdup(result); if (island_input_flag) { fprintf(vvp_out, "p%p .import I%p, %s;\n", nex, island, src); return strdup(src); } else { fprintf(vvp_out, "p%p .port I%p, %s;\n", nex, island, src); return strdup(nex_data->island_input); } } /* * This routine is called to display an error message when a uwire or * wire real has multiple drivers. */ typedef enum mdriver_type_e { MDRV_UWIRE = 0, MDRV_REAL = 1 } mdriver_type_t; static void display_multi_driver_error(ivl_nexus_t nex, unsigned ndrivers, mdriver_type_t type) { unsigned idx; unsigned scope_len = UINT_MAX; ivl_signal_t sig = 0; /* Find the signal. */ for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t tsig = ivl_nexus_ptr_sig(ptr); if (tsig != 0) { ivl_scope_t scope; unsigned len; if (ivl_signal_local(tsig)) continue; /* If this is not a local signal then find the signal * that has the shortest scope (is the furthest up * the hierarchy). */ scope = ivl_signal_scope(tsig); assert(scope); len = strlen(ivl_scope_name(scope)); if (len < scope_len) { scope_len = len; sig = tsig; } } } assert(sig); fprintf(stderr, "%s:%u: vvp.tgt error: ", ivl_signal_file(sig), ivl_signal_lineno(sig)); switch (type) { case MDRV_UWIRE: if (ivl_signal_type(sig) != IVL_SIT_UWIRE) { fprintf(stderr, "(implicit) "); } fprintf(stderr, "uwire"); break; case MDRV_REAL: assert(ivl_signal_type(sig) == IVL_SIT_TRI); if (ivl_signal_data_type(sig) != IVL_VT_REAL) { fprintf(stderr, "(implicit) "); } fprintf(stderr, "wire real"); break; default: assert(0);; } fprintf(stderr, " \"%s\" must have a single driver, found (%u).\n", ivl_signal_basename(sig), ndrivers); vvp_errors += 1; } /* * This function draws the input to a net into a string. What that * means is that it returns a static string that can be used to * represent a resolved driver to a nexus. If there are multiple * drivers to the nexus, then it writes out the resolver declarations * needed to perform strength resolution. * * The string that this returns is malloced, and that means that the * caller must free the string or store it permanently. This function * does *not* check for a previously calculated string. Use the * draw_net_input for the general case. */ static ivl_nexus_ptr_t *drivers = 0x0; static unsigned adrivers = 0; void EOC_cleanup_drivers() { free(drivers); drivers = NULL; adrivers = 0; } static void draw_net_input_x(ivl_nexus_t nex, struct vvp_nexus_data*nex_data) { ivl_island_t island = 0; int island_input_flag = -1; ivl_signal_type_t res; char result[512]; unsigned idx; char**driver_labels; unsigned ndrivers = 0; const char*resolv_type; char*nex_private = 0; /* Accumulate nex_data flags. */ int nex_flags = 0; res = signal_type_of_nexus(nex); switch (res) { case IVL_SIT_TRI: case IVL_SIT_UWIRE: resolv_type = "tri"; break; case IVL_SIT_TRI0: resolv_type = "tri0"; nex_flags |= VVP_NEXUS_DATA_STR; break; case IVL_SIT_TRI1: resolv_type = "tri1"; nex_flags |= VVP_NEXUS_DATA_STR; break; case IVL_SIT_TRIAND: resolv_type = "triand"; break; case IVL_SIT_TRIOR: resolv_type = "trior"; break; default: fprintf(stderr, "vvp.tgt: Unsupported signal type: %d\n", res); assert(0); resolv_type = "tri"; break; } for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_switch_t sw = 0; ivl_nexus_ptr_t nptr = ivl_nexus_ptr(nex, idx); /* If this object is part of an island, then we'll be making a port. If this nexus is an output from any switches in the island, then set island_input_flag to false. Save the island cookie. */ if ( (sw = ivl_nexus_ptr_switch(nptr)) ) { assert(island == 0 || island == ivl_switch_island(sw)); island = ivl_switch_island(sw); if (nex == ivl_switch_a(sw)) { nex_flags |= VVP_NEXUS_DATA_STR; island_input_flag = 0; } else if (nex == ivl_switch_b(sw)) { nex_flags |= VVP_NEXUS_DATA_STR; island_input_flag = 0; } else if (island_input_flag == -1) { assert(nex == ivl_switch_enable(sw)); island_input_flag = 1; } } /* Skip input only pins. */ if ((ivl_nexus_ptr_drive0(nptr) == IVL_DR_HiZ) && (ivl_nexus_ptr_drive1(nptr) == IVL_DR_HiZ)) continue; /* Mark the strength-aware flag if the driver can generate values other than the standard "6" strength. */ if (nexus_drive_is_strength_aware(nptr)) nex_flags |= VVP_NEXUS_DATA_STR; /* Save this driver. */ if (ndrivers >= adrivers) { adrivers += 4; drivers = realloc(drivers, adrivers*sizeof(ivl_nexus_ptr_t)); } drivers[ndrivers] = nptr; ndrivers += 1; } if (island_input_flag < 0) island_input_flag = 0; /* Save the nexus driver count in the nex_data. */ assert(nex_data); nex_data->drivers_count = ndrivers; nex_data->flags |= nex_flags; /* If the nexus has no drivers, then send a constant HiZ or 0.0 into the net. */ if (ndrivers == 0) { unsigned wid = width_of_nexus(nex); int pull = (res == IVL_SIT_TRI0) || (res == IVL_SIT_TRI1); /* For real nets put 0.0. */ if (signal_data_type_of_nexus(nex) == IVL_VT_REAL) { nex_private = draw_Cr_to_string(0.0); } else { unsigned jdx; char*tmp = malloc((pull ? 3 : 1) * wid + 5); nex_private = tmp; strcpy(tmp, pull ? "C8<" : "C4<"); tmp += strlen(tmp); switch (res) { case IVL_SIT_TRI: case IVL_SIT_TRIAND: case IVL_SIT_TRIOR: case IVL_SIT_UWIRE: for (jdx = 0 ; jdx < wid ; jdx += 1) *tmp++ = 'z'; break; case IVL_SIT_TRI0: for (jdx = 0 ; jdx < wid ; jdx += 1) { *tmp++ = '5'; *tmp++ = '5'; *tmp++ = '0'; } break; case IVL_SIT_TRI1: for (jdx = 0 ; jdx < wid ; jdx += 1) { *tmp++ = '5'; *tmp++ = '5'; *tmp++ = '1'; } break; default: assert(0); } *tmp++ = '>'; *tmp = 0; } /* Create an "open" driver to hold the HiZ or 0.0. We need to do this so that .nets have something to hang onto. */ char buf[64]; snprintf(buf, sizeof buf, "o%p", nex); if (pull) { fprintf(vvp_out, "%s .functor BUFT %u, %s, C4<0>, C4<0>, C4<0>; pull drive\n", buf, wid, nex_private); } else { fprintf(vvp_out, "%s .functor BUFZ %u, %s; HiZ drive\n", buf, wid, nex_private); } nex_private = realloc(nex_private, strlen(buf)+1); strcpy(nex_private, buf); if (island) { char*tmp2 = draw_island_port(island, island_input_flag, nex, nex_data, nex_private); free(nex_private); nex_private = tmp2; } assert(nex_data->net_input == 0); nex_data->net_input = nex_private; return; } /* A uwire is a tri with only one driver. */ if (res == IVL_SIT_UWIRE) { if (ndrivers > 1) { display_multi_driver_error(nex, ndrivers, MDRV_UWIRE); } res = IVL_SIT_TRI; } /* If the nexus has exactly one driver, then simply draw it. Note that this will *not* work if the nexus is not a TRI type nexus. */ if (ndrivers == 1 && res == IVL_SIT_TRI) { ivl_signal_t path_sig = find_modpath(nex); if (path_sig) { char*nex_str = draw_net_input_drive(nex, drivers[0]); char modpath_label[64]; snprintf(modpath_label, sizeof modpath_label, "V_%p_0/m", path_sig); nex_private = strdup(modpath_label); draw_modpath(path_sig, nex_str, 0); } else { nex_private = draw_net_input_drive(nex, drivers[0]); } if (island) { char*tmp = draw_island_port(island, island_input_flag, nex, nex_data, nex_private); free(nex_private); nex_private = tmp; } assert(nex_data->net_input == 0); nex_data->net_input = nex_private; return; } /* We currently only support one driver on real nets. */ if (ndrivers > 1 && signal_data_type_of_nexus(nex) == IVL_VT_REAL) { display_multi_driver_error(nex, ndrivers, MDRV_REAL); } driver_labels = malloc(ndrivers * sizeof(char*)); ivl_signal_t path_sig = find_modpath(nex); if (path_sig) { for (idx = 0; idx < ndrivers; idx += 1) { char*nex_str = draw_net_input_drive(nex, drivers[idx]); char modpath_label[64]; snprintf(modpath_label, sizeof modpath_label, "V_%p_%u/m", path_sig, idx); driver_labels[idx] = strdup(modpath_label); draw_modpath(path_sig, nex_str, idx); } } else { for (idx = 0; idx < ndrivers; idx += 1) { driver_labels[idx] = draw_net_input_drive(nex, drivers[idx]); } } fprintf(vvp_out, "RS_%p .resolv %s", nex, resolv_type); for (idx = 0; idx < ndrivers; idx += 1) { fprintf(vvp_out, ", %s", driver_labels[idx]); free(driver_labels[idx]); } fprintf(vvp_out, ";\n"); free(driver_labels); snprintf(result, sizeof result, "RS_%p", nex); if (island) nex_private = draw_island_port(island, island_input_flag, nex, nex_data, result); else nex_private = strdup(result); assert(nex_data->net_input == 0); nex_data->net_input = nex_private; } /* * Get a cached description of the nexus input, or create one if this * nexus has not been cached yet. This is a wrapper for the common * case call to draw_net_input_x. */ const char*draw_net_input(ivl_nexus_t nex) { struct vvp_nexus_data*nex_data = (struct vvp_nexus_data*) ivl_nexus_get_private(nex); /* If this nexus already has a label, then its input is already figured out. Just return the existing label. */ if (nex_data && nex_data->net_input) return nex_data->net_input; if (nex_data == 0) { nex_data = new_nexus_data(); ivl_nexus_set_private(nex, nex_data); } assert(nex_data->net_input == 0); draw_net_input_x(nex, nex_data); return nex_data->net_input; } const char*draw_island_net_input(ivl_island_t island, ivl_nexus_t nex) { struct vvp_nexus_data*nex_data = (struct vvp_nexus_data*) ivl_nexus_get_private(nex); /* If this nexus already has a label, then its input is already figured out. Just return the existing label. */ if (nex_data && nex_data->island_input) { assert(nex_data->island == island); return nex_data->island_input; } if (nex_data == 0) { nex_data = new_nexus_data(); ivl_nexus_set_private(nex, nex_data); } assert(nex_data->net_input == 0); draw_net_input_x(nex, nex_data); assert(nex_data->island == island); assert(nex_data->island_input); return nex_data->island_input; } iverilog-12_0/tgt-vvp/draw_substitute.c000066400000000000000000000024241435245347300203540ustar00rootroot00000000000000/* * Copyright (c) 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 "vvp_priv.h" # include # include # include void draw_lpm_substitute(ivl_lpm_t net) { unsigned swidth = width_of_nexus(ivl_lpm_data(net,1)); fprintf(vvp_out, "L_%p .substitute %u, %u %u", net, ivl_lpm_width(net), ivl_lpm_base(net), swidth); fprintf(vvp_out, ", %s", draw_net_input(ivl_lpm_data(net,0))); fprintf(vvp_out, ", %s;\n", draw_net_input(ivl_lpm_data(net,1))); } iverilog-12_0/tgt-vvp/draw_switch.c000066400000000000000000000065071435245347300174500ustar00rootroot00000000000000/* * Copyright (c) 2008-2020 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 "vvp_priv.h" # include # include # include static void draw_tran_island(ivl_island_t island) { fprintf(vvp_out, "I%p .island tran;\n", island); ivl_island_flag_set(island, 0, 1); } void draw_switch_in_scope(ivl_switch_t sw) { ivl_island_t island; ivl_nexus_t nex_a, nex_b, enable; const char*str_a, *str_b, *str_e; ivl_expr_t rise_exp = ivl_switch_delay(sw, 0); ivl_expr_t fall_exp = ivl_switch_delay(sw, 1); ivl_expr_t decay_exp= ivl_switch_delay(sw, 2); island = ivl_switch_island(sw); if (ivl_island_flag_test(island, 0) == 0) draw_tran_island(island); nex_a = ivl_switch_a(sw); assert(nex_a); str_a = draw_island_net_input(island, nex_a); nex_b = ivl_switch_b(sw); assert(nex_b); str_b = draw_island_net_input(island, nex_b); enable = ivl_switch_enable(sw); str_e = 0; char str_e_buf[4 + 2*sizeof(void*)]; if (enable && rise_exp) { /* If the enable has a delay, then generate a .delay node to delay the input by the specified amount. Do the delay outside of the island so that the island processing doesn't have to deal with it. */ const char*raw = draw_net_input(enable); draw_delay(sw, 1, raw, rise_exp, fall_exp, decay_exp); snprintf(str_e_buf, sizeof str_e_buf, "p%p", sw); str_e = str_e_buf; fprintf(vvp_out, "%s .import I%p, L_%p;\n", str_e, island, sw); } else if (enable) { str_e = draw_island_net_input(island, enable); } switch (ivl_switch_type(sw)) { case IVL_SW_RTRAN: fprintf(vvp_out, " .rtran"); break; case IVL_SW_RTRANIF0: fprintf(vvp_out, " .rtranif0"); break; case IVL_SW_RTRANIF1: fprintf(vvp_out, " .rtranif1"); break; case IVL_SW_TRAN: fprintf(vvp_out, " .tran"); break; case IVL_SW_TRANIF0: fprintf(vvp_out, " .tranif0"); break; case IVL_SW_TRANIF1: fprintf(vvp_out, " .tranif1"); break; case IVL_SW_TRAN_VP: fprintf(vvp_out, " .tranvp %u %u %u,", ivl_switch_width(sw), ivl_switch_part(sw), ivl_switch_offset(sw)); break; default: fprintf(stderr, "%s:%u: vvp.tgt error: unrecognised switch type.\n", ivl_switch_file(sw), ivl_switch_lineno(sw)); vvp_errors += 1; return; } fprintf(vvp_out, " I%p, %s %s", island, str_a, str_b); if (enable) { fprintf(vvp_out, ", %s", str_e); } fprintf(vvp_out, ";\n"); } iverilog-12_0/tgt-vvp/draw_ufunc.c000066400000000000000000000155761435245347300172750ustar00rootroot00000000000000/* * Copyright (c) 2005-2016 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 "vvp_priv.h" # include # include # include static void function_argument_logic(ivl_signal_t port, ivl_expr_t expr) { unsigned ewidth, pwidth; /* ports cannot be arrays. */ assert(ivl_signal_dimensions(port) == 0); ewidth = ivl_expr_width(expr); pwidth = ivl_signal_width(port); draw_eval_vec4(expr); if (ewidth < pwidth) fprintf(vvp_out, " %%pad/u %u;\n", pwidth); } static void function_argument_real(ivl_signal_t port, ivl_expr_t expr) { /* ports cannot be arrays. */ assert(ivl_signal_dimensions(port) == 0); draw_eval_real(expr); } static void draw_eval_function_argument(ivl_signal_t port, ivl_expr_t expr) { ivl_variable_type_t dtype = ivl_signal_data_type(port); switch (dtype) { case IVL_VT_BOOL: /* For now, treat bit2 variables as bit4 variables. */ case IVL_VT_LOGIC: function_argument_logic(port, expr); break; case IVL_VT_REAL: function_argument_real(port, expr); break; case IVL_VT_CLASS: vvp_errors += draw_eval_object(expr); break; case IVL_VT_STRING: draw_eval_string(expr); break; case IVL_VT_DARRAY: vvp_errors += draw_eval_object(expr); break; default: fprintf(stderr, "XXXX function argument %s type=%d?!\n", ivl_signal_basename(port), dtype); assert(0); } } static void draw_send_function_argument(ivl_signal_t port) { ivl_variable_type_t dtype = ivl_signal_data_type(port); switch (dtype) { case IVL_VT_BOOL: /* For now, treat bit2 variables as bit4 variables. */ case IVL_VT_LOGIC: fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", port, ivl_signal_width(port)); break; case IVL_VT_REAL: fprintf(vvp_out, " %%store/real v%p_0;\n", port); break; case IVL_VT_CLASS: fprintf(vvp_out, " %%store/obj v%p_0;\n", port); break; case IVL_VT_STRING: fprintf(vvp_out, " %%store/str v%p_0;\n", port); break; case IVL_VT_DARRAY: fprintf(vvp_out, " %%store/obj v%p_0;\n", port); break; default: fprintf(stderr, "XXXX function argument %s type=%d?!\n", ivl_signal_basename(port), dtype); assert(0); } } static void draw_ufunc_preamble(ivl_expr_t expr) { ivl_scope_t def = ivl_expr_def(expr); unsigned idx; /* If this is an automatic function, allocate the local storage. */ if (ivl_scope_is_auto(def)) { fprintf(vvp_out, " %%alloc S_%p;\n", def); } /* Evaluate the expressions and send the results to the function ports. Do this in two passes - evaluate, then send - this avoids the function input variables being overwritten if the same (non-automatic) function is called in one of the expressions. */ assert(ivl_expr_parms(expr) == (ivl_scope_ports(def)-1)); for (idx = 0 ; idx < ivl_expr_parms(expr) ; idx += 1) { ivl_signal_t port = ivl_scope_port(def, idx+1); draw_eval_function_argument(port, ivl_expr_parm(expr, idx)); } for (idx = ivl_expr_parms(expr) ; idx > 0 ; idx -= 1) { ivl_signal_t port = ivl_scope_port(def, idx); draw_send_function_argument(port); } /* Call the function */ switch (ivl_expr_value(expr)) { case IVL_VT_VOID: fprintf(vvp_out, " %%callf/void TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_REAL: fprintf(vvp_out, " %%callf/real TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_BOOL: case IVL_VT_LOGIC: fprintf(vvp_out, " %%callf/vec4 TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_STRING: fprintf(vvp_out, " %%callf/str TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; case IVL_VT_CLASS: case IVL_VT_DARRAY: case IVL_VT_QUEUE: fprintf(vvp_out, " %%callf/obj TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); break; default: fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(def))); fprintf(vvp_out, ", S_%p;\n", def); fprintf(vvp_out, " %%join;\n"); break; } } static void draw_ufunc_epilogue(ivl_expr_t expr) { ivl_scope_t def = ivl_expr_def(expr); /* If this is an automatic function, free the local storage. */ if (ivl_scope_is_auto(def)) { fprintf(vvp_out, " %%free S_%p;\n", def); } } /* * A call to a user defined function generates a result that is the * result of this expression. * * The result of the function is placed by the function execution into * a signal within the scope of the function that also has a basename * the same as the function. The ivl_target API handled the result * mapping already, and we get the name of the result signal as * parameter 0 of the function definition. */ void draw_ufunc_vec4(ivl_expr_t expr) { /* Take in arguments to function and call function code. */ draw_ufunc_preamble(expr); draw_ufunc_epilogue(expr); } void draw_ufunc_real(ivl_expr_t expr) { /* Take in arguments to function and call the function code. */ draw_ufunc_preamble(expr); /* The %callf/real function emitted by the preamble leaves the result in the stack for us. */ draw_ufunc_epilogue(expr); } void draw_ufunc_string(ivl_expr_t expr) { /* Take in arguments to function and call the function code. */ draw_ufunc_preamble(expr); /* The %callf/str function emitted by the preamble leaves the result in the stack for us. */ draw_ufunc_epilogue(expr); } void draw_ufunc_object(ivl_expr_t expr) { ivl_scope_t def = ivl_expr_def(expr); ivl_signal_t retval = ivl_scope_port(def, 0); /* Take in arguments to function and call the function code. */ draw_ufunc_preamble(expr); /* Load the result into the object stack. */ fprintf(vvp_out, " %%load/obj v%p_0;\n", retval); draw_ufunc_epilogue(expr); } iverilog-12_0/tgt-vvp/draw_vpi.c000066400000000000000000000404371435245347300167450ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 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 "vvp_priv.h" # include # include # include # include "ivl_alloc.h" struct args_info { char*text; /* True ('s' or 'u' if this argument is a calculated vec4. */ char vec_flag; /* True if this argument is a calculated string. */ char str_flag; /* True if this argument is a calculated real. */ char real_flag; /* Stack position if this argument is a calculated value. */ unsigned stack; /* Expression width: Only used of vec_flag is true. */ unsigned vec_wid; struct args_info *child; /* Arguments can be nested. */ }; static const char* magic_sfuncs[] = { "$time", "$stime", "$realtime", "$simtime", 0 }; static int is_magic_sfunc(const char*name) { int idx; for (idx = 0 ; magic_sfuncs[idx] ; idx += 1) if (strcmp(magic_sfuncs[idx],name) == 0) return 1; return 0; } static int is_fixed_memory_word(ivl_expr_t net) { ivl_signal_t sig; if (ivl_expr_type(net) != IVL_EX_SIGNAL) return 0; sig = ivl_expr_signal(net); if (ivl_signal_dimensions(sig) == 0) return 1; if (ivl_signal_type(sig) == IVL_SIT_REG) return 0; if (number_is_immediate(ivl_expr_oper1(net), IMM_WID, 0)) return 1; return 0; } static int get_vpi_taskfunc_signal_arg(struct args_info *result, ivl_expr_t expr) { char buffer[4096]; switch (ivl_expr_type(expr)) { case IVL_EX_SIGNAL: /* If the signal node is narrower than the signal itself, then this is a part select so I'm going to need to evaluate the expression. Also, if the signedness of the expression is different from the signedness of the signal. This could be caused by a $signed or $unsigned system function. If I don't need to do any evaluating, then skip it as I'll be passing the handle to the signal itself. */ if ((ivl_expr_width(expr) != ivl_signal_width(ivl_expr_signal(expr))) && ivl_expr_value(expr) != IVL_VT_DARRAY) { /* This should never happen since we have IVL_EX_SELECT. */ /* For a queue (type of darray) we return the maximum size of the queue as the signal width. */ assert(0); return 0; } else if (signal_is_return_value(ivl_expr_signal(expr))) { /* If the signal is the return value of a function, then this can't be handled as a true signal, so fall back on general expression processing. */ return 0; } else if (ivl_expr_signed(expr) != ivl_signal_signed(ivl_expr_signal(expr))) { return 0; } else if (is_fixed_memory_word(expr)) { /* This is a word of a non-array, or a word of a net array, so we can address the word directly. */ ivl_signal_t sig = ivl_expr_signal(expr); unsigned use_word = 0; ivl_expr_t word_ex = ivl_expr_oper1(expr); if (word_ex) { /* Some array select have been evaluated. */ if (number_is_immediate(word_ex,IMM_WID, 0)) { assert(! number_is_unknown(word_ex)); use_word = get_number_immediate(word_ex); word_ex = 0; } } if (word_ex) return 0; assert(word_ex == 0); snprintf(buffer, sizeof buffer, "v%p_%u", sig, use_word); result->text = strdup(buffer); return 1; } else { /* What's left, this is the work of a var array. Create the right code to handle it. */ ivl_signal_t sig = ivl_expr_signal(expr); unsigned use_word = 0; unsigned use_word_defined = 0; ivl_expr_t word_ex = ivl_expr_oper1(expr); if (word_ex) { /* Some array select have been evaluated. */ if (number_is_immediate(word_ex, IMM_WID, 0)) { assert(! number_is_unknown(word_ex)); use_word = get_number_immediate(word_ex); use_word_defined = 1; word_ex = 0; } } if (word_ex && (ivl_expr_type(word_ex)==IVL_EX_SIGNAL || ivl_expr_type(word_ex)==IVL_EX_SELECT)) { /* Special case: the index is a signal/select. */ result->child = calloc(1, sizeof(struct args_info)); if (get_vpi_taskfunc_signal_arg(result->child, word_ex)) { snprintf(buffer, sizeof buffer, "&A", sig, result->child->text); free(result->child->text); } else { free(result->child); result->child = NULL; return 0; } } else if (word_ex) { /* Fallback case: Give up and evaluate expression. */ return 0; } else { assert(use_word_defined); snprintf(buffer, sizeof buffer, "&A", sig, use_word); } result->text = strdup(buffer); return 1; } case IVL_EX_SELECT: { ivl_expr_t vexpr = ivl_expr_oper1(expr); ivl_expr_t bexpr; ivl_expr_t wexpr; assert(vexpr); /* This code is only for signals or selects. */ if (ivl_expr_type(vexpr) != IVL_EX_SIGNAL && ivl_expr_type(vexpr) != IVL_EX_SELECT) return 0; /* If the expression is a substring expression, then the xPV method of passing the argument will not work and we have to resort to the default method. */ if (ivl_expr_value(vexpr) == IVL_VT_STRING) return 0; /* If the sub-expression is a DARRAY, then this select is a dynamic-array word select. Handle that elsewhere. */ if (ivl_expr_value(vexpr) == IVL_VT_DARRAY) return 0; /* Part select is always unsigned. If the expression is signed * fallback. */ if (ivl_expr_signed(expr)) return 0; /* The signal is part of an array. */ /* Add &APV<> code here when it is finished. */ bexpr = ivl_expr_oper2(expr); /* This is a pad operation. */ if (!bexpr) return 0; wexpr = ivl_expr_oper1(vexpr); /* If vexpr has an operand, then that operand is a word index and we are taking a select from an array word. This would come up in expressions like "array[][]" where wexpr is */ if (wexpr && number_is_immediate(wexpr, 64, 1) && number_is_immediate(bexpr, 64, 1)) { assert(! number_is_unknown(bexpr)); assert(! number_is_unknown(wexpr)); snprintf(buffer, sizeof buffer, "&APV", ivl_expr_signal(vexpr), get_number_immediate(wexpr), get_number_immediate(bexpr), ivl_expr_width(expr)); } else if (wexpr) { return 0; /* This is a constant bit/part select. */ } else if (number_is_immediate(bexpr, 64, 1)) { assert(! number_is_unknown(bexpr)); snprintf(buffer, sizeof buffer, "&PV", ivl_expr_signal(vexpr), get_number_immediate(bexpr), ivl_expr_width(expr)); /* This is an indexed bit/part select. */ } else if (ivl_expr_type(bexpr) == IVL_EX_SIGNAL || ivl_expr_type(bexpr) == IVL_EX_SELECT) { /* Special case: the base is a signal/select. */ result->child = calloc(1, sizeof(struct args_info)); if (get_vpi_taskfunc_signal_arg(result->child, bexpr)) { snprintf(buffer, sizeof buffer, "&PV", ivl_expr_signal(vexpr), result->child->text, ivl_expr_width(expr)); free(result->child->text); } else { free(result->child); result->child = NULL; return 0; } } else { /* Fallback case: Punt and let caller handle it. */ return 0; } result->text = strdup(buffer); return 1; } default: return 0; } } static void draw_vpi_taskfunc_args(const char*call_string, ivl_statement_t tnet, ivl_expr_t fnet) { unsigned idx; unsigned parm_count = tnet ? ivl_stmt_parm_count(tnet) : ivl_expr_parms(fnet); struct args_info *args = calloc(parm_count, sizeof(struct args_info)); char buffer[4096]; ivl_parameter_t par; /* Keep track of how much string stack this function call is going to need. We'll need this for making stack references, and also to clean out the stack when done. */ unsigned vec4_stack_need = 0; unsigned str_stack_need = 0; unsigned real_stack_need = 0; /* Figure out how many expressions are going to be evaluated for this task call. I won't need to evaluate expressions for items that are VPI objects directly. */ for (idx = 0 ; idx < parm_count ; idx += 1) { ivl_expr_t expr = tnet ? ivl_stmt_parm(tnet, idx) : ivl_expr_parm(fnet, idx); switch (ivl_expr_type(expr)) { /* These expression types can be handled directly, with VPI handles of their own. Therefore, skip them in the process of evaluating expressions. */ case IVL_EX_NONE: args[idx].text = strdup("\" \""); continue; case IVL_EX_ARRAY: snprintf(buffer, sizeof buffer, "v%p", ivl_expr_signal(expr)); args[idx].text = strdup(buffer); continue; case IVL_EX_NUMBER: { if (( par = ivl_expr_parameter(expr) )) { snprintf(buffer, sizeof buffer, "P_%p", par); } else { unsigned bit, wid = ivl_expr_width(expr); const char*bits = ivl_expr_bits(expr); char*dp; snprintf(buffer, sizeof buffer, "%u'%sb", wid, ivl_expr_signed(expr)? "s" : ""); dp = buffer + strlen(buffer); for (bit = wid ; bit > 0 ; bit -= 1) *dp++ = bits[bit-1]; *dp++ = 0; assert(dp >= buffer); assert((unsigned)(dp - buffer) <= sizeof buffer); } args[idx].text = strdup(buffer); continue; } case IVL_EX_STRING: if (( par = ivl_expr_parameter(expr) )) { snprintf(buffer, sizeof buffer, "P_%p", par); args[idx].text = strdup(buffer); } else { size_t needed_len = strlen(ivl_expr_string(expr)) + 3; args[idx].text = malloc(needed_len); snprintf(args[idx].text, needed_len, "\"%s\"", ivl_expr_string(expr)); } continue; case IVL_EX_REALNUM: if (( par = ivl_expr_parameter(expr) )) { snprintf(buffer, sizeof buffer, "P_%p", par); args[idx].text = strdup(buffer); continue; } break; case IVL_EX_ENUMTYPE: snprintf(buffer, sizeof buffer, "enum%p", ivl_expr_enumtype(expr)); args[idx].text = strdup(buffer); continue; case IVL_EX_EVENT: snprintf(buffer, sizeof buffer, "E_%p", ivl_expr_event(expr)); args[idx].text = strdup(buffer); continue; case IVL_EX_SCOPE: snprintf(buffer, sizeof buffer, "S_%p", ivl_expr_scope(expr)); args[idx].text = strdup(buffer); continue; case IVL_EX_SFUNC: if (is_magic_sfunc(ivl_expr_name(expr))) { snprintf(buffer, sizeof buffer, "%s", ivl_expr_name(expr)); args[idx].text = strdup(buffer); continue; } break; case IVL_EX_SIGNAL: case IVL_EX_SELECT: args[idx].stack = vec4_stack_need; if (get_vpi_taskfunc_signal_arg(&args[idx], expr)) { if (args[idx].vec_flag) { vec4_stack_need += 1; } else { args[idx].stack = 0; } continue; } else { args[idx].stack = 0; break; } case IVL_EX_NULL: snprintf(buffer, sizeof buffer, "null"); args[idx].text = strdup(buffer); continue; /* Everything else will need to be evaluated and passed as a constant to the vpi task. */ default: break; } switch (ivl_expr_value(expr)) { case IVL_VT_LOGIC: case IVL_VT_BOOL: draw_eval_vec4(expr); args[idx].vec_flag = ivl_expr_signed(expr)? 's' : 'u'; args[idx].str_flag = 0; args[idx].real_flag = 0; args[idx].stack = vec4_stack_need; args[idx].vec_wid = ivl_expr_width(expr); vec4_stack_need += 1; buffer[0] = 0; break; case IVL_VT_REAL: draw_eval_real(expr); args[idx].vec_flag = 0; args[idx].str_flag = 0; args[idx].real_flag = 1; args[idx].stack = real_stack_need; real_stack_need += 1; buffer[0] = 0; break; case IVL_VT_STRING: /* Eval the string into the stack, and tell VPI about the stack position. */ draw_eval_string(expr); args[idx].vec_flag = 0; args[idx].str_flag = 1; args[idx].real_flag = 0; args[idx].stack = str_stack_need; args[idx].real_flag = 0; str_stack_need += 1; buffer[0] = 0; break; default: fprintf(stderr, "%s:%u: Sorry, cannot generate code for argument %u.\n", ivl_expr_file(expr), ivl_expr_lineno(expr), idx+1); fprintf(vvp_out, "\nXXXX Unexpected argument: call_string=<%s>, arg=%u, type=%d\n", call_string, idx, ivl_expr_value(expr)); fflush(vvp_out); assert(0); } args[idx].text = strdup(buffer); } fprintf(vvp_out, "%s", call_string); for (idx = 0 ; idx < parm_count ; idx += 1) { struct args_info*ptr; if (args[idx].str_flag) { /* If this is a stack reference, then calculate the stack depth and use that to generate the completed string. */ unsigned pos = str_stack_need - args[idx].stack - 1; fprintf(vvp_out, ", S<%u,str>",pos); } else if (args[idx].real_flag) { unsigned pos = real_stack_need - args[idx].stack - 1; fprintf(vvp_out, ", W<%u,r>",pos); } else if (args[idx].vec_flag) { unsigned pos = vec4_stack_need - args[idx].stack - 1; char sign_flag = args[idx].vec_flag; unsigned wid = args[idx].vec_wid; fprintf(vvp_out, ", S<%u,vec4,%c%u>",pos, sign_flag, wid); } else { fprintf(vvp_out, ", %s", args[idx].text); } free(args[idx].text); /* Free the nested children. */ ptr = args[idx].child; while (ptr != NULL) { struct args_info*tptr = ptr; ptr = ptr->child; free(tptr); } } free(args); fprintf(vvp_out, " {%u %u %u}", vec4_stack_need, real_stack_need, str_stack_need); fprintf(vvp_out, ";\n"); } void draw_vpi_task_call(ivl_statement_t tnet) { unsigned parm_count = ivl_stmt_parm_count(tnet); const char *command = "error"; switch (ivl_stmt_sfunc_as_task(tnet)) { case IVL_SFUNC_AS_TASK_ERROR: command = "%vpi_call"; break; case IVL_SFUNC_AS_TASK_WARNING: command = "%vpi_call/w"; break; case IVL_SFUNC_AS_TASK_IGNORE: command = "%vpi_call/i"; break; } if (parm_count == 0) { fprintf(vvp_out, " %s %u %u \"%s\" {0 0 0};\n", command, ivl_file_table_index(ivl_stmt_file(tnet)), ivl_stmt_lineno(tnet), ivl_stmt_name(tnet)); } else { char call_string[1024]; snprintf(call_string, sizeof(call_string), " %s %u %u \"%s\"", command, ivl_file_table_index(ivl_stmt_file(tnet)), ivl_stmt_lineno(tnet), ivl_stmt_name(tnet)); draw_vpi_taskfunc_args(call_string, tnet, 0); } } void draw_vpi_func_call(ivl_expr_t fnet) { char call_string[1024]; snprintf(call_string, sizeof(call_string), " %%vpi_func %u %u \"%s\" %u", ivl_file_table_index(ivl_expr_file(fnet)), ivl_expr_lineno(fnet), ivl_expr_name(fnet), ivl_expr_width(fnet)); draw_vpi_taskfunc_args(call_string, 0, fnet); } void draw_vpi_rfunc_call(ivl_expr_t fnet) { char call_string[1024]; snprintf(call_string, sizeof(call_string), " %%vpi_func/r %u %u \"%s\"", ivl_file_table_index(ivl_expr_file(fnet)), ivl_expr_lineno(fnet), ivl_expr_name(fnet)); draw_vpi_taskfunc_args(call_string, 0, fnet); } void draw_vpi_sfunc_call(ivl_expr_t fnet) { char call_string[1024]; snprintf(call_string, sizeof(call_string), " %%vpi_func/s %u %u \"%s\"", ivl_file_table_index(ivl_expr_file(fnet)), ivl_expr_lineno(fnet), ivl_expr_name(fnet)); draw_vpi_taskfunc_args(call_string, 0, fnet); } iverilog-12_0/tgt-vvp/eval_condit.c000066400000000000000000000214511435245347300174140ustar00rootroot00000000000000/* * Copyright (c) 2014-2016 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 "vvp_priv.h" # include # include static int draw_condition_fallback(ivl_expr_t expr) { int use_flag = allocate_flag(); /* Evaluate the condition expression, including optionally reducing it to a single bit. Put the result into a flag bit for use by all the tests. */ draw_eval_vec4(expr); if (ivl_expr_width(expr) > 1) fprintf(vvp_out, " %%or/r;\n"); fprintf(vvp_out, " %%flag_set/vec4 %d;\n", use_flag); return use_flag; } static int draw_condition_binary_compare(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); if ((ivl_expr_value(le) == IVL_VT_REAL) || (ivl_expr_value(re) == IVL_VT_REAL)) { return draw_condition_fallback(expr); } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { return draw_condition_fallback(expr); } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_type(re)==IVL_EX_STRING)) { return draw_condition_fallback(expr); } if ((ivl_expr_type(le)==IVL_EX_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { return draw_condition_fallback(expr); } if ((ivl_expr_value(le)==IVL_VT_CLASS) && (ivl_expr_value(re)==IVL_VT_CLASS)) { return draw_condition_fallback(expr); } unsigned use_wid = ivl_expr_width(le); if (ivl_expr_width(re) > use_wid) use_wid = ivl_expr_width(re); /* If the le is constant, then swap the operands so that we can possibly take advantage of the immediate version of the %cmp instruction. */ if (ivl_expr_width(le)==use_wid && test_immediate_vec4_ok(le)) { ivl_expr_t tmp = le; le = re; re = tmp; } draw_eval_vec4(le); resize_vec4_wid(le, use_wid); char use_opcode = ivl_expr_opcode(expr); if (ivl_expr_width(re)==use_wid && test_immediate_vec4_ok(re)) { /* Special case: If the right operand can be handled as an immediate operand, then use that instead. */ if (use_opcode=='n' || use_opcode=='N') draw_immediate_vec4(re, "%cmpi/ne"); else draw_immediate_vec4(re, "%cmpi/e"); } else { draw_eval_vec4(re); resize_vec4_wid(re, use_wid); if (use_opcode=='n' || use_opcode=='N') fprintf(vvp_out, " %%cmp/ne;\n"); else fprintf(vvp_out, " %%cmp/e;\n"); } switch (ivl_expr_opcode(expr)) { case 'n': /* != */ case 'e': /* == */ return 4; break; case 'N': /* !== */ case 'E': /* === */ return 6; default: assert(0); return -1; } } static int draw_condition_binary_real_le(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); ivl_expr_t tmp; char use_opcode = ivl_expr_opcode(expr); /* If this is a > or >=, then convert it to < or <= by swapping the operands. Adjust the opcode to match. */ switch (use_opcode) { case 'G': tmp = le; le = re; re = tmp; use_opcode = 'L'; break; case '>': tmp = le; le = re; re = tmp; use_opcode = '<'; break; } draw_eval_real(le); draw_eval_real(re); fprintf(vvp_out, " %%cmp/wr;\n"); switch (use_opcode) { case '<': return 5; case 'L': fprintf(vvp_out, " %%flag_or 5, 4;\n"); return 5; default: assert(0); return -1; } } static int draw_condition_binary_le(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); ivl_expr_t tmp; if ((ivl_expr_value(le) == IVL_VT_REAL) || (ivl_expr_value(re) == IVL_VT_REAL)) { return draw_condition_binary_real_le(expr); } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { return draw_condition_fallback(expr); } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_type(re)==IVL_EX_STRING)) { return draw_condition_fallback(expr); } if ((ivl_expr_type(le)==IVL_EX_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { return draw_condition_fallback(expr); } char use_opcode = ivl_expr_opcode(expr); char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u'; if (test_immediate_vec4_ok(le) && !test_immediate_vec4_ok(re)) { tmp = le; le = re; re = tmp; switch (use_opcode) { case 'G': use_opcode = 'L'; break; case 'L': use_opcode = 'G'; break; case '>': use_opcode = '<'; break; case '<': use_opcode = '>'; break; default: assert(0); break; } } else if (!test_immediate_vec4_ok(re)) { /* If this is a > or >=, then convert it to < or <= by swapping the operands. Adjust the opcode to match. Do this because the instruction really only supports < and <= and we can avoid a %flag_inv instruction. */ switch (use_opcode) { case 'G': tmp = le; le = re; re = tmp; use_opcode = 'L'; break; case '>': tmp = le; le = re; re = tmp; use_opcode = '<'; break; } } /* NOTE: I think I would rather the elaborator handle the operand widths. When that happens, take this code out. */ unsigned use_wid = ivl_expr_width(le); if (ivl_expr_width(re) > use_wid) use_wid = ivl_expr_width(re); draw_eval_vec4(le); resize_vec4_wid(le, use_wid); if (ivl_expr_width(re)==use_wid && test_immediate_vec4_ok(re)) { /* Special case: If the right operand can be handled as an immediate operand, then use that instead. */ char opcode[8]; snprintf(opcode, sizeof opcode, "%%cmpi/%c", s_flag); draw_immediate_vec4(re, opcode); } else { draw_eval_vec4(re); resize_vec4_wid(re, use_wid); fprintf(vvp_out, " %%cmp/%c;\n", s_flag); } switch (use_opcode) { case '>': fprintf(vvp_out, " %%flag_or 5, 4; GT is !LE\n"); fprintf(vvp_out, " %%flag_inv 5;\n"); return 5; case 'G': fprintf(vvp_out, " %%flag_inv 5; GE is !LT\n"); return 5; case '<': return 5; case 'L': fprintf(vvp_out, " %%flag_or 5, 4;\n"); return 5; default: assert(0); return -1; } } static int draw_condition_binary_lor(ivl_expr_t expr) { unsigned label_out = local_count++; ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); int lx = draw_eval_condition(le); int tmp_flag = lx; /* Short circuit right hand side if necessary */ fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", thread_count, label_out, lx); if (lx < 8) { tmp_flag = allocate_flag(); fprintf(vvp_out, " %%flag_mov %d, %d;\n", tmp_flag, lx); } int rx = draw_eval_condition(re); /* * The flag needs to be in the same position regardless of whether the * right side is short-cicuited or not. */ if (lx == tmp_flag) { fprintf(vvp_out, " %%flag_or %d, %d;\n", lx, rx); } else { fprintf(vvp_out, " %%flag_or %d, %d;\n", rx, tmp_flag); if (lx != rx) fprintf(vvp_out, " %%flag_mov %d, %d;\n", lx, rx); clr_flag(tmp_flag); } fprintf(vvp_out, "T_%u.%u;\n", thread_count, label_out); clr_flag(rx); return lx; } static int draw_condition_binary(ivl_expr_t expr) { switch (ivl_expr_opcode(expr)) { case 'e': /* == */ case 'E': /* === */ case 'n': /* != */ case 'N': /* !== */ return draw_condition_binary_compare(expr); case '<': case '>': case 'L': /* <= */ case 'G': /* >= */ return draw_condition_binary_le(expr); case 'o': /* Logical or (||) */ return draw_condition_binary_lor(expr); default: return draw_condition_fallback(expr); } } int draw_eval_condition(ivl_expr_t expr) { switch (ivl_expr_type(expr)) { case IVL_EX_BINARY: return draw_condition_binary(expr); default: return draw_condition_fallback(expr); } } iverilog-12_0/tgt-vvp/eval_expr.c000066400000000000000000000216051435245347300171130ustar00rootroot00000000000000/* * Copyright (c) 2001-2020 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 "vvp_priv.h" # include # include # include # include # include "ivl_alloc.h" int number_is_unknown(ivl_expr_t expr) { const char*bits; unsigned idx; if (ivl_expr_type(expr) == IVL_EX_ULONG) return 0; assert(ivl_expr_type(expr) == IVL_EX_NUMBER); bits = ivl_expr_bits(expr); for (idx = 0 ; idx < ivl_expr_width(expr) ; idx += 1) if ((bits[idx] != '0') && (bits[idx] != '1')) return 1; return 0; } /* * This function returns TRUE if the number can be represented as a * lim_wid immediate value. This amounts to verifying that any upper * bits are the same. For a negative value we do not support the most * negative twos-complement value since it can not be negated. This * code generator always emits positive values, hence the negation * requirement. */ int number_is_immediate(ivl_expr_t expr, unsigned lim_wid, int negative_ok_flag) { const char *bits; unsigned nbits = ivl_expr_width(expr); char pad_bit = '0'; unsigned idx; /* We can only convert numbers to an immediate value. */ if (ivl_expr_type(expr) != IVL_EX_NUMBER && ivl_expr_type(expr) != IVL_EX_ULONG && ivl_expr_type(expr) != IVL_EX_DELAY) return 0; /* If a negative value is OK, then we really have one less * significant bit because of the sign bit. */ if (negative_ok_flag) lim_wid -= 1; /* This is an unsigned value so it can not have the -2**N problem. */ if (ivl_expr_type(expr) == IVL_EX_ULONG) { unsigned long imm; if (lim_wid >= 8*sizeof(unsigned long)) return 1; /* At this point we know that lim_wid is smaller than an * unsigned long variable. */ imm = ivl_expr_uvalue(expr); if (imm < (1UL << lim_wid)) return 1; else return 0; } /* This is an unsigned value so it can not have the -2**N problem. */ if (ivl_expr_type(expr) == IVL_EX_DELAY) { uint64_t imm; if (lim_wid >= 8*sizeof(uint64_t)) return 1; /* At this point we know that lim_wid is smaller than a * uint64_t variable. */ imm = ivl_expr_delay_val(expr); if (imm < ((uint64_t)1 << lim_wid)) return 1; else return 0; } bits = ivl_expr_bits(expr); if (ivl_expr_signed(expr) && bits[nbits-1]=='1') pad_bit = '1'; if (pad_bit == '1' && !negative_ok_flag) return 0; /* Check if all the bits are either x or z. */ if ((bits[0] == 'x') || (bits[0] == 'z')) { char first_bit = bits[0]; unsigned bits_match = 1; for (idx = 1 ; idx < nbits ; idx += 1) if (bits[idx] != first_bit) { bits_match = 0; break; } if (bits_match) return 1; } for (idx = lim_wid ; idx < nbits ; idx += 1) if (bits[idx] != pad_bit) return 0; /* If we have a negative number make sure it is not too big. */ if (pad_bit == '1') { for (idx = 0; idx < lim_wid; idx += 1) if (bits[idx] == '1') return 1; return 0; } return 1; } /* * We can return positive or negative values. You must verify that the * number is not unknown (number_is_unknown) and is small enough * (number_is_immediate). */ long get_number_immediate(ivl_expr_t expr) { long imm = 0; switch (ivl_expr_type(expr)) { case IVL_EX_ULONG: imm = ivl_expr_uvalue(expr); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(expr); unsigned nbits = ivl_expr_width(expr); unsigned idx; /* We can not copy more bits than fit into a long. */ if (nbits > 8*sizeof(long)) nbits = 8*sizeof(long); for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]){ case '0': break; case '1': imm |= 1L << idx; break; default: assert(0); } if (ivl_expr_signed(expr) && bits[nbits-1]=='1' && nbits < 8*sizeof(long)) imm |= -1UL << nbits; break; } default: assert(0); } return imm; } uint64_t get_number_immediate64(ivl_expr_t expr) { uint64_t imm = 0; switch (ivl_expr_type(expr)) { case IVL_EX_ULONG: imm = ivl_expr_uvalue(expr); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(expr); unsigned nbits = ivl_expr_width(expr); unsigned idx; for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]){ case '0': break; case '1': assert(idx < 64); imm |= UINT64_C(1) << idx; break; default: assert(0); } if (ivl_expr_signed(expr) && bits[nbits-1]=='1' && nbits < 64) imm |= (-UINT64_C(1)) << nbits; break; } default: assert(0); } return imm; } void eval_logic_into_integer(ivl_expr_t expr, unsigned ix) { switch (ivl_expr_type(expr)) { case IVL_EX_NUMBER: case IVL_EX_ULONG: { assert(number_is_immediate(expr, IMM_WID, 1)); if (number_is_unknown(expr)) { /* We are loading a 'bx so mimic %ix/get. */ fprintf(vvp_out, " %%ix/load %u, 0, 0;\n", ix); fprintf(vvp_out, " %%flag_set/imm 4, 1;\n"); break; } long imm = get_number_immediate(expr); if (imm >= 0) { fprintf(vvp_out, " %%ix/load %u, %ld, 0;\n", ix, imm); } else { fprintf(vvp_out, " %%ix/load %u, 0, 0; loading %ld\n", ix, imm); fprintf(vvp_out, " %%ix/sub %u, %ld, 0;\n", ix, -imm); } /* This can not have have a X/Z value so clear flag 4. */ fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); } break; /* Special case: There is an %ix instruction for reading index values directly from variables. In this case, try to use that special instruction. */ case IVL_EX_SIGNAL: { ivl_signal_t sig = ivl_expr_signal(expr); unsigned word = 0; if (ivl_signal_dimensions(sig) > 0) { ivl_expr_t ixe; const char*type = ivl_expr_signed(expr) ? "/s" : ""; /* Detect the special case that this is a variable array. In this case, the ix/getv will not work, so do it the hard way. */ if (ivl_signal_type(sig) == IVL_SIT_REG) { draw_eval_vec4(expr); fprintf(vvp_out, " %%ix/vec4%s %u;\n", type, ix); break; } ixe = ivl_expr_oper1(expr); if (number_is_immediate(ixe, IMM_WID, 0)) { assert(! number_is_unknown(ixe)); word = get_number_immediate(ixe); } else { draw_eval_vec4(expr); fprintf(vvp_out, " %%ix/vec4%s %u;\n", type, ix); break; } } const char*type = ivl_signal_signed(sig) ? "/s" : ""; fprintf(vvp_out, " %%ix/getv%s %u, v%p_%u;\n", type, ix, sig, word); break; } default: draw_eval_vec4(expr); /* Is this a signed expression? */ if (ivl_expr_signed(expr)) { fprintf(vvp_out, " %%ix/vec4/s %u;\n", ix); } else { fprintf(vvp_out, " %%ix/vec4 %u;\n", ix); } break; } } /* * This function, in addition to setting the value into index 0, sets * bit 4 to 1 if the value is unknown. */ void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix) { switch (ivl_expr_value(expr)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: eval_logic_into_integer(expr, ix); break; case IVL_VT_REAL: draw_eval_real(expr); fprintf(vvp_out, " %%cvt/sr %u;\n", ix); break; default: fprintf(stderr, "XXXX ivl_expr_value == %d\n", ivl_expr_value(expr)); assert(0); } } char *process_octal_codes(const char *in, unsigned width) { unsigned idx = 0; unsigned ridx = 0; unsigned str_len = strlen(in); char *out = (char *)malloc(str_len+1); /* If we do not have any octal codes just return the input. */ if (width/8 == str_len) { strcpy(out, in); return out; } while (ridx < str_len) { /* An octal constant always has three digits. */ if (in[ridx] == '\\') { out[idx] = (in[ridx+1]-'0')*64 + (in[ridx+2]-'0')*8 + (in[ridx+3]-'0'); idx += 1; ridx += 4; } else { out[idx] = in[ridx]; idx += 1; ridx += 1; } } out[idx] = '\0'; return out; } iverilog-12_0/tgt-vvp/eval_object.c000066400000000000000000000213261435245347300174030ustar00rootroot00000000000000/* * Copyright (c) 2012-2020 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 "vvp_priv.h" # include # include void darray_new(ivl_type_t element_type, unsigned size_reg) { int wid; char*signed_char; ivl_variable_type_t type = ivl_type_base(element_type); if ((type == IVL_VT_BOOL) || (type == IVL_VT_LOGIC)) { wid = ivl_type_packed_width(element_type); signed_char = ivl_type_signed(element_type) ? "s" : ""; } else { // REAL or STRING objects are not packable. assert(ivl_type_packed_dimensions(element_type) == 0); wid = 0; signed_char = ""; } switch (type) { case IVL_VT_REAL: fprintf(vvp_out, " %%new/darray %u, \"r\";\n", size_reg); break; case IVL_VT_STRING: fprintf(vvp_out, " %%new/darray %u, \"S\";\n", size_reg); break; case IVL_VT_BOOL: fprintf(vvp_out, " %%new/darray %u, \"%sb%d\";\n", size_reg, signed_char, wid); break; case IVL_VT_LOGIC: fprintf(vvp_out, " %%new/darray %u, \"%sv%d\";\n", size_reg, signed_char, wid); break; default: assert(0); break; } clr_word(size_reg); } static int eval_darray_new(ivl_expr_t ex) { int errors = 0; unsigned size_reg = allocate_word(); ivl_expr_t size_expr = ivl_expr_oper1(ex); ivl_expr_t init_expr = ivl_expr_oper2(ex); draw_eval_expr_into_integer(size_expr, size_reg); // The new function has a net_type that contains the details // of the type. ivl_type_t net_type = ivl_expr_net_type(ex); assert(net_type); ivl_type_t element_type = ivl_type_element(net_type); assert(element_type); darray_new(element_type, size_reg); if (init_expr && ivl_expr_type(init_expr)==IVL_EX_ARRAY_PATTERN) { unsigned idx; switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) { draw_eval_vec4(ivl_expr_parm(init_expr,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n"); fprintf(vvp_out, " %%pop/vec4 1;\n"); } break; case IVL_VT_REAL: for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) { draw_eval_real(ivl_expr_parm(init_expr,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/real 3;\n"); fprintf(vvp_out, " %%pop/real 1;\n"); } break; case IVL_VT_STRING: for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) { draw_eval_string(ivl_expr_parm(init_expr,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/str 3;\n"); fprintf(vvp_out, " %%pop/str 1;\n"); } break; default: fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n"); errors += 1; break; } } else if (init_expr && (ivl_expr_value(init_expr) == IVL_VT_DARRAY)) { ivl_signal_t sig = ivl_expr_signal(init_expr); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%scopy;\n"); } else if (init_expr && number_is_immediate(size_expr,32,0)) { /* In this case, there is an init expression, the expression is NOT an array_pattern, and the size expression used to calculate the size of the array is a constant. Generate an unrolled set of assignments. */ long idx; long cnt = get_number_immediate(size_expr); unsigned wid; switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: wid = ivl_type_packed_width(element_type); for (idx = 0 ; idx < cnt ; idx += 1) { draw_eval_vec4(init_expr); fprintf(vvp_out, " %%parti/%c %u, %ld, 6;\n", ivl_expr_signed(init_expr) ? 's' : 'u', wid, idx * wid); fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", cnt - idx - 1); fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n"); fprintf(vvp_out, " %%pop/vec4 1;\n"); } break; case IVL_VT_REAL: draw_eval_real(init_expr); for (idx = 0 ; idx < cnt ; idx += 1) { fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/real 3;\n"); } fprintf(vvp_out, " %%pop/real 1;\n"); break; case IVL_VT_STRING: draw_eval_string(init_expr); for (idx = 0 ; idx < cnt ; idx += 1) { fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/str 3;\n"); } fprintf(vvp_out, " %%pop/str 1;\n"); break; default: fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n"); errors += 1; break; } } else if (init_expr) { fprintf(vvp_out, "; ERROR: Sorry, I don't know how to work with this size expr.\n"); errors += 1; } return errors; } static int eval_class_new(ivl_expr_t ex) { ivl_type_t class_type = ivl_expr_net_type(ex); fprintf(vvp_out, " %%new/cobj C%p;\n", class_type); return 0; } static int eval_object_null(ivl_expr_t ex) { (void)ex; /* Parameter is not used. */ fprintf(vvp_out, " %%null;\n"); return 0; } static int eval_object_property(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); unsigned pidx = ivl_expr_property_idx(expr); int idx = 0; ivl_expr_t idx_expr = 0; /* If there is an array index expression, then this is an array'ed property, and we need to calculate the index for the expression. */ if ( (idx_expr = ivl_expr_oper1(expr)) ) { idx = allocate_word(); draw_eval_expr_into_integer(idx_expr, idx); } fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%prop/obj %u, %d; eval_object_property\n", pidx, idx); fprintf(vvp_out, " %%pop/obj 1, 1;\n"); if (idx != 0) clr_word(idx); return 0; } static int eval_object_shallowcopy(ivl_expr_t ex) { int errors = 0; ivl_expr_t dest = ivl_expr_oper1(ex); ivl_expr_t src = ivl_expr_oper2(ex); errors += draw_eval_object(dest); errors += draw_eval_object(src); /* The %scopy opcode pops the top of the object stack as the source object, and shallow-copies it to the new top, the destination object. The destination is left on the top of the stack. */ fprintf(vvp_out, " %%scopy;\n"); return errors; } static int eval_object_signal(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); /* Simple case: This is a simple variable. Generate a load statement to load the string into the stack. */ if (ivl_signal_dimensions(sig) == 0) { fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); return 0; } /* There is a word select expression, so load the index into a register and load from the array. */ ivl_expr_t word_ex = ivl_expr_oper1(expr); int word_ix = allocate_word(); draw_eval_expr_into_integer(word_ex, word_ix); fprintf(vvp_out, " %%load/obja v%p, %d;\n", sig, word_ix); clr_word(word_ix); return 0; } static int eval_object_ufunc(ivl_expr_t ex) { draw_ufunc_object(ex); return 0; } int draw_eval_object(ivl_expr_t ex) { switch (ivl_expr_type(ex)) { case IVL_EX_NEW: switch (ivl_expr_value(ex)) { case IVL_VT_CLASS: return eval_class_new(ex); case IVL_VT_DARRAY: return eval_darray_new(ex); default: fprintf(vvp_out, "; ERROR: draw_eval_object: Invalid type (%d) for \n", ivl_expr_value(ex)); return 0; } case IVL_EX_NULL: return eval_object_null(ex); case IVL_EX_PROPERTY: return eval_object_property(ex); case IVL_EX_SHALLOWCOPY: return eval_object_shallowcopy(ex); case IVL_EX_SIGNAL: return eval_object_signal(ex); case IVL_EX_UFUNC: return eval_object_ufunc(ex); default: fprintf(vvp_out, "; ERROR: draw_eval_object: Invalid expression type %d\n", ivl_expr_type(ex)); return 1; } } iverilog-12_0/tgt-vvp/eval_real.c000066400000000000000000000350021435245347300170540ustar00rootroot00000000000000/* * Copyright (c) 2003-2020 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. */ /* * This file includes functions for evaluating REAL expressions. */ # include "vvp_priv.h" # include # include # include # include # include static unsigned long word_alloc_mask = 0x0f; int allocate_word() { int res = 4; while (res < WORD_COUNT && (1U << res) & word_alloc_mask) res += 1; if (res >= WORD_COUNT) { fprintf(stderr, "vvp.tgt error: Thread words (%d) exhausted " "during VVP code generation.\n", WORD_COUNT); exit(1); } word_alloc_mask |= 1U << res; return res; } void clr_word(int res) { assert(res < WORD_COUNT); word_alloc_mask &= ~ (1U << res); } static void draw_binary_real(ivl_expr_t expr) { switch (ivl_expr_opcode(expr)) { case 'E': case 'N': case 'w': case 'W': case 'l': case 'r': case 'R': case '&': case '|': case '^': case 'A': case 'O': case 'X': /* These should be caught in draw_eval_real(). */ assert(0); } draw_eval_real(ivl_expr_oper1(expr)); draw_eval_real(ivl_expr_oper2(expr)); switch (ivl_expr_opcode(expr)) { case '+': fprintf(vvp_out, " %%add/wr;\n"); break; case '-': fprintf(vvp_out, " %%sub/wr;\n"); break; case '*': fprintf(vvp_out, " %%mul/wr;\n"); break; case '/': fprintf(vvp_out, " %%div/wr;\n"); break; case '%': fprintf(vvp_out, " %%mod/wr;\n"); break; case 'p': fprintf(vvp_out, " %%pow/wr;\n"); break; case 'm': fprintf(vvp_out, " %%min/wr;\n"); break; case 'M': fprintf(vvp_out, " %%max/wr;\n"); break; default: fprintf(stderr, "vvp.tgt error: draw_binary_real(%c)\n", ivl_expr_opcode(expr)); assert(0); } } static void draw_number_real(ivl_expr_t expr) { unsigned int idx; const char*bits = ivl_expr_bits(expr); unsigned wid = ivl_expr_width(expr); unsigned long mant = 0; int vexp = 0x1000; /* If this is a negative number, then arrange for the 2's complement to be calculated as we scan through the value. Real values are sign-magnitude, and this negation gets us a magnitude. */ int negate = 0; int carry = 0; if (ivl_expr_signed(expr) && (bits[wid-1] == '1')) { negate = 1; carry = 1; } for (idx = 0 ; idx < wid && idx < IMM_WID ; idx += 1) { int cur_bit = bits[idx] == '1'? 1 : 0; if (negate) { cur_bit ^= 1; cur_bit += carry; carry = (cur_bit >> 1) & 1; cur_bit &= 1; } if (cur_bit) mant |= 1 << idx; } for ( ; idx < wid ; idx += 1) { if (ivl_expr_signed(expr) && (bits[idx] == bits[IMM_WID-1])) continue; if (bits[idx] == '0') continue; fprintf(stderr, "vvp.tgt error: mantissa doesn't fit!\n"); assert(0); } /* If required, add in a sign bit. */ if (negate) vexp |= 0x4000; fprintf(vvp_out, " %%pushi/real %lu, %d; load(num)= %c%lu (wid=%u)\n", mant, vexp, (vexp&0x4000)? '-' : '+', mant, wid); } static void draw_property_real(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); unsigned pidx = ivl_expr_property_idx(expr); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%prop/r %u;\n", pidx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } static void draw_realnum_real(ivl_expr_t expr) { double value = ivl_expr_dvalue(expr); double fract; int expo, vexp; unsigned long mant; int sign = 0; /* Handle the special case that the value is +-inf. */ if (isinf(value)) { if (value > 0) fprintf(vvp_out, " %%pushi/real 0, %d; load=+inf\n", 0x3fff); else fprintf(vvp_out, " %%pushi/real 0, %d; load=-inf\n", 0x7fff); return; } /* Handle the special case that the value is NaN. */ if (value != value) { fprintf(vvp_out, " %%pushi/real 1, %d; load=NaN\n", 0x3fff); return; } if (value < 0) { sign = 0x4000; value *= -1; } fract = frexp(value, &expo); fract = ldexp(fract, 31); mant = fract; expo -= 31; vexp = expo + 0x1000; assert(vexp >= 0); assert(vexp < 0x2000); vexp += sign; fprintf(vvp_out, " %%pushi/real %lu, %d; load=%#g\n", mant, vexp, ivl_expr_dvalue(expr)); /* Capture the residual bits, if there are any. Note that an IEEE754 mantissa has 52 bits, 31 of which were accounted for already. */ fract -= floor(fract); fract = ldexp(fract, 22); mant = fract; expo -= 22; vexp = expo + 0x1000; assert(vexp >= 0); assert(vexp < 0x2000); vexp += sign; if (mant != 0) { fprintf(vvp_out, " %%pushi/real %lu, %d; load=%#g\n", mant, vexp, ivl_expr_dvalue(expr)); fprintf(vvp_out, " %%add/wr;\n"); } } /* * The real value of a logic expression is the integer value of the * expression converted to real. */ static void draw_real_logic_expr(ivl_expr_t expr) { draw_eval_vec4(expr); const char*sign_flag = ivl_expr_signed(expr)? "/s" : ""; fprintf(vvp_out, " %%cvt/rv%s;\n", sign_flag); } static void draw_select_real(ivl_expr_t expr) { /* The sube references the expression to be selected from. */ ivl_expr_t sube = ivl_expr_oper1(expr); /* This is the select expression */ ivl_expr_t shift= ivl_expr_oper2(expr); /* Assume the sub-expression is a signal */ ivl_signal_t sig = ivl_expr_signal(sube); assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY || ivl_signal_data_type(sig) == IVL_VT_QUEUE); draw_eval_expr_into_integer(shift, 3); fprintf(vvp_out, " %%load/dar/r v%p_0;\n", sig); } static void real_ex_pop(ivl_expr_t expr) { const char*fb; ivl_expr_t arg; if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) fb = "b"; else fb = "f"; arg = ivl_expr_parm(expr, 0); assert(ivl_expr_type(arg) == IVL_EX_SIGNAL); fprintf(vvp_out, " %%qpop/%s/real v%p_0;\n", fb, ivl_expr_signal(arg)); } static void draw_sfunc_real(ivl_expr_t expr) { switch (ivl_expr_value(expr)) { case IVL_VT_REAL: if (ivl_expr_parms(expr) == 0) { fprintf(vvp_out, " %%vpi_func/r %u %u \"%s\" {0 0 0};\n", ivl_file_table_index(ivl_expr_file(expr)), ivl_expr_lineno(expr), ivl_expr_name(expr)); } else { draw_vpi_rfunc_call(expr); } break; case IVL_VT_VECTOR: /* If the value of the sfunc is a vector, then evaluate it as a vector, then convert the result to a real (via an index register) for the result. */ draw_real_logic_expr(expr); break; default: assert(0); } } static void draw_signal_real_real(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); /* Special Case: If the signal is the return value of the function, then use a different opcode to get the value. */ if (signal_is_return_value(sig)) { assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, " %%retload/real 0; Load %s (draw_signal_real_real)\n", ivl_signal_basename(sig)); return; } if (ivl_signal_dimensions(sig) == 0) { fprintf(vvp_out, " %%load/real v%p_0;\n", sig); return; } ivl_expr_t word_ex = ivl_expr_oper1(expr); int word_ix = allocate_word(); draw_eval_expr_into_integer(word_ex, word_ix); fprintf(vvp_out, " %%load/ar v%p, %d;\n", sig, word_ix); clr_word(word_ix); } static void draw_signal_real(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); switch (ivl_signal_data_type(sig)) { case IVL_VT_LOGIC: draw_real_logic_expr(expr); return; case IVL_VT_REAL: draw_signal_real_real(expr); return; default: fprintf(stderr, "vvp.tgt error: signal_data_type=%d\n", ivl_signal_data_type(sig)); assert(0); return; } } /* If we have nested ternary operators they are likely tail recursive. * This code is structured to allow this recursion without overflowing * the available thread words. */ static void draw_ternary_real(ivl_expr_t expr) { ivl_expr_t cond = ivl_expr_oper1(expr); ivl_expr_t true_ex = ivl_expr_oper2(expr); ivl_expr_t false_ex = ivl_expr_oper3(expr); unsigned lab_true = local_count++; unsigned lab_out = local_count++; int cond_flag = allocate_flag(); /* Evaluate the ternary condition. */ draw_eval_vec4(cond); if (ivl_expr_width(cond) > 1) fprintf(vvp_out, " %%or/r;\n"); fprintf(vvp_out, " %%flag_set/vec4 %d;\n", cond_flag); /* Evaluate the true expression second. */ fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", thread_count, lab_true, cond_flag); /* Evaluate the false expression. */ draw_eval_real(false_ex); fprintf(vvp_out, " %%jmp/0 T_%u.%u, %d; End of false expr.\n", thread_count, lab_out, cond_flag); /* If the conditional is undefined then blend the real words. */ draw_eval_real(true_ex); fprintf(vvp_out, " %%blend/wr;\n"); fprintf(vvp_out, " %%jmp T_%u.%u; End of blend\n", thread_count, lab_out); /* Evaluate the true expression. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_true); draw_eval_real(true_ex); /* This is the out label. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_out); clr_flag(cond_flag); } static void increment(ivl_expr_t e, bool pre) { ivl_signal_t sig = ivl_expr_signal(e); fprintf(vvp_out, " %%load/real v%p_0;\n", sig); if (!pre) fprintf(vvp_out, " %%dup/real;\n"); fprintf(vvp_out, " %%pushi/real 1, 0x1000;\n"); fprintf(vvp_out, " %%add/wr;\n"); if ( pre) fprintf(vvp_out, " %%dup/real;\n"); fprintf(vvp_out, " %%store/real v%p_0;\n", sig); } static void decrement(ivl_expr_t e, bool pre) { ivl_signal_t sig = ivl_expr_signal(e); fprintf(vvp_out, " %%load/real v%p_0;\n", sig); if (!pre) fprintf(vvp_out, " %%dup/real;\n"); fprintf(vvp_out, " %%pushi/real 1, 0x1000;\n"); fprintf(vvp_out, " %%sub/wr;\n"); if ( pre) fprintf(vvp_out, " %%dup/real;\n"); fprintf(vvp_out, " %%store/real v%p_0;\n", sig); } static void draw_unary_real(ivl_expr_t expr) { ivl_expr_t sube; /* If the opcode is a ~ or a ! then the sub expression must not be * a real expression, so use vector evaluation and then convert * that result to a real value. */ if ((ivl_expr_opcode(expr) == '~') || (ivl_expr_opcode(expr) == '!')) { draw_real_logic_expr(expr); return; } sube = ivl_expr_oper1(expr); if (ivl_expr_opcode(expr) == 'r') { /* Cast an integer value to a real. */ const char *suffix = ""; assert(ivl_expr_value(sube) != IVL_VT_REAL); draw_eval_vec4(sube); if (ivl_expr_signed(sube)) suffix = "/s"; fprintf(vvp_out, " %%cvt/rv%s;\n", suffix); return; } if (ivl_expr_opcode(expr) == '+') { draw_eval_real(sube); return; } if (ivl_expr_opcode(expr) == '-') { fprintf(vvp_out, " %%pushi/real 0, 0; load 0.0\n"); draw_eval_real(sube); fprintf(vvp_out, " %%sub/wr;\n"); return; } if (ivl_expr_opcode(expr) == 'm') { /* abs() */ draw_eval_real(sube); fprintf(vvp_out, " %%abs/wr;\n"); return; } if (ivl_expr_opcode(expr) == 'v') { /* Handled in eval_expr.c. */ fprintf(stderr, "vvp.tgt error: real -> integer cast in real " "context.\n"); assert(0); } switch (ivl_expr_opcode(expr)) { case 'I': increment(sube, true); return; case 'i': increment(sube, false); return; case 'D': decrement(sube, true); return; case 'd': decrement(sube, false); return; } fprintf(stderr, "vvp.tgt error: unhandled real unary operator: %c.\n", ivl_expr_opcode(expr)); assert(0); } void draw_eval_real(ivl_expr_t expr) { /* If this expression/sub-expression is not real then we need * to evaluate it as a bit value and then convert the bit based * result to a real value. This is required to get integer * division to work correctly. */ if (ivl_expr_value(expr) != IVL_VT_REAL) { draw_real_logic_expr(expr); return; } switch (ivl_expr_type(expr)) { case IVL_EX_BINARY: draw_binary_real(expr); break; case IVL_EX_NUMBER: draw_number_real(expr); break; case IVL_EX_PROPERTY: draw_property_real(expr); break; case IVL_EX_REALNUM: draw_realnum_real(expr); break; case IVL_EX_SELECT: draw_select_real(expr); break; case IVL_EX_SFUNC: if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) real_ex_pop(expr); else if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_front")==0) real_ex_pop(expr); else draw_sfunc_real(expr); break; case IVL_EX_SIGNAL: draw_signal_real(expr); break; case IVL_EX_TERNARY: draw_ternary_real(expr); break; case IVL_EX_UFUNC: draw_ufunc_real(expr); break; case IVL_EX_UNARY: draw_unary_real(expr); break; default: if (ivl_expr_value(expr) == IVL_VT_VECTOR) { draw_eval_vec4(expr); const char*sign_flag = ivl_expr_signed(expr)? "/s" : ""; fprintf(vvp_out, " %%cvt/rv%s;\n", sign_flag); } else { fprintf(stderr, "vvp.tgt error: XXXX Evaluate real expression (%d)\n", ivl_expr_type(expr)); fprintf(vvp_out, " ; XXXX Evaluate real expression (%d)\n", ivl_expr_type(expr)); return; } break; } } iverilog-12_0/tgt-vvp/eval_string.c000066400000000000000000000144451435245347300174470ustar00rootroot00000000000000/* * Copyright (c) 2012-2013 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 "vvp_priv.h" # include # include static void fallback_eval(ivl_expr_t expr) { draw_eval_vec4(expr); fprintf(vvp_out, " %%pushv/str; Cast BOOL/LOGIC to string\n"); } static void string_ex_concat(ivl_expr_t expr) { unsigned repeat; assert(ivl_expr_parms(expr) != 0); assert(ivl_expr_repeat(expr) != 0); /* Push the first string onto the stack, no matter what. */ draw_eval_string(ivl_expr_parm(expr,0)); for (repeat = 0 ; repeat < ivl_expr_repeat(expr) ; repeat += 1) { unsigned idx; for (idx = (repeat==0)? 1 : 0 ; idx < ivl_expr_parms(expr) ; idx += 1) { ivl_expr_t sub = ivl_expr_parm(expr,idx); /* Special case: If operand is a string literal, then concat it using the %concati/str instruction. */ if (ivl_expr_type(sub) == IVL_EX_STRING) { fprintf(vvp_out, " %%concati/str \"%s\";\n", ivl_expr_string(sub)); continue; } draw_eval_string(sub); fprintf(vvp_out, " %%concat/str;\n"); } } } static void string_ex_property(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); unsigned pidx = ivl_expr_property_idx(expr); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%prop/str %u;\n", pidx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } static void string_ex_signal(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); if (ivl_signal_data_type(sig) != IVL_VT_STRING) { fallback_eval(expr); return; } /* Special Case: If the signal is the return value of the function, then use a different opcode to get the value. */ if (signal_is_return_value(sig)) { assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, " %%retload/str 0; Load %s (string_ex_signal)\n", ivl_signal_basename(sig)); return; } /* Simple case: This is a simple variable. Generate a load statement to load the string into the stack. */ if (ivl_signal_dimensions(sig) == 0) { fprintf(vvp_out, " %%load/str v%p_0;\n", sig); return; } /* There is a word select expression, so load the index into a register and load from the array. */ ivl_expr_t word_ex = ivl_expr_oper1(expr); int word_ix = allocate_word(); draw_eval_expr_into_integer(word_ex, word_ix); fprintf(vvp_out, " %%load/stra v%p, %d;\n", sig, word_ix); clr_word(word_ix); } static void string_ex_select(ivl_expr_t expr) { /* The sube references the expression to be selected from. */ ivl_expr_t sube = ivl_expr_oper1(expr); /* This is the select expression */ ivl_expr_t shift= ivl_expr_oper2(expr); /* Assume the sub-expression is a signal */ ivl_signal_t sig = ivl_expr_signal(sube); assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY || ivl_signal_data_type(sig) == IVL_VT_QUEUE); draw_eval_expr_into_integer(shift, 3); fprintf(vvp_out, " %%load/dar/str v%p_0;\n", sig); } static void string_ex_string(ivl_expr_t expr) { const char*val = ivl_expr_string(expr); /* Special case: The elaborator converts the string "" to an 8-bit zero, which is in turn escaped to the 4-character string \000. Detect this special case and convert it back to an empty string. [Perhaps elaboration should be fixed?] */ if (ivl_expr_width(expr)==8 && (strcmp(val,"\\000") == 0)) { fprintf(vvp_out, " %%pushi/str \"\";\n"); return; } fprintf(vvp_out, " %%pushi/str \"%s\";\n", val); } static void string_ex_substr(ivl_expr_t expr) { ivl_expr_t arg; unsigned arg1; unsigned arg2; assert(ivl_expr_parms(expr) == 3); arg = ivl_expr_parm(expr,0); draw_eval_string(arg); /* Evaluate the arguments... */ arg = ivl_expr_parm(expr, 1); arg1 = allocate_word(); draw_eval_expr_into_integer(arg, arg1); arg = ivl_expr_parm(expr, 2); arg2 = allocate_word(); draw_eval_expr_into_integer(arg, arg2); fprintf(vvp_out, " %%substr %u, %u;\n", arg1, arg2); clr_word(arg1); clr_word(arg2); } static void string_ex_pop(ivl_expr_t expr) { const char*fb; ivl_expr_t arg; if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) fb = "b"; else fb = "f"; arg = ivl_expr_parm(expr, 0); assert(ivl_expr_type(arg) == IVL_EX_SIGNAL); fprintf(vvp_out, " %%qpop/%s/str v%p_0;\n", fb, ivl_expr_signal(arg)); } static void draw_sfunc_string(ivl_expr_t expr) { assert(ivl_expr_value(expr) == IVL_VT_STRING); draw_vpi_sfunc_call(expr); } void draw_eval_string(ivl_expr_t expr) { switch (ivl_expr_type(expr)) { case IVL_EX_STRING: string_ex_string(expr); break; case IVL_EX_SIGNAL: string_ex_signal(expr); break; case IVL_EX_CONCAT: string_ex_concat(expr); break; case IVL_EX_PROPERTY: string_ex_property(expr); break; case IVL_EX_SELECT: string_ex_select(expr); break; case IVL_EX_SFUNC: if (strcmp(ivl_expr_name(expr), "$ivl_string_method$substr") == 0) string_ex_substr(expr); else if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) string_ex_pop(expr); else if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_front")==0) string_ex_pop(expr); else draw_sfunc_string(expr); break; case IVL_EX_UFUNC: draw_ufunc_string(expr); break; default: fallback_eval(expr); break; } } iverilog-12_0/tgt-vvp/eval_vec4.c000066400000000000000000001136321435245347300170000ustar00rootroot00000000000000/* * Copyright (c) 2013-2020 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. */ /* * This file includes functions for evaluating VECTOR expressions. */ # include "vvp_priv.h" # include # include # include # include # include void resize_vec4_wid(ivl_expr_t expr, unsigned wid) { if (ivl_expr_width(expr) == wid) return; if (ivl_expr_signed(expr)) fprintf(vvp_out, " %%pad/s %u;\n", wid); else fprintf(vvp_out, " %%pad/u %u;\n", wid); } /* * Test if the draw_immediate_vec4 instruction can be used. */ int test_immediate_vec4_ok(ivl_expr_t re) { const char*bits; unsigned idx; if (ivl_expr_type(re) != IVL_EX_NUMBER) return 0; if (ivl_expr_width(re) <= 32) return 1; bits = ivl_expr_bits(re); for (idx = 32 ; idx < ivl_expr_width(re) ; idx += 1) { if (bits[idx] != '0') return 0; } return 1; } static void make_immediate_vec4_words(ivl_expr_t re, unsigned long*val0p, unsigned long*valxp, unsigned*widp) { unsigned long val0 = 0; unsigned long valx = 0; unsigned wid = ivl_expr_width(re); const char*bits = ivl_expr_bits(re); unsigned idx; for (idx = 0 ; idx < wid ; idx += 1) { assert( ((val0|valx)&0x80000000UL) == 0UL ); val0 <<= 1; valx <<= 1; switch (bits[wid-idx-1]) { case '0': break; case '1': val0 |= 1; break; case 'x': val0 |= 1; valx |= 1; break; case 'z': val0 |= 0; valx |= 1; break; default: assert(0); break; } } *val0p = val0; *valxp = valx; *widp = wid; } void draw_immediate_vec4(ivl_expr_t re, const char*opcode) { unsigned long val0, valx; unsigned wid; make_immediate_vec4_words(re, &val0, &valx, &wid); fprintf(vvp_out, " %s %lu, %lu, %u;\n", opcode, val0, valx, wid); } static void draw_binary_vec4_arith(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); unsigned lwid = ivl_expr_width(le); unsigned rwid = ivl_expr_width(re); unsigned ewid = ivl_expr_width(expr); int is_power_op = ivl_expr_opcode(expr) == 'p' ? 1 : 0; /* The power operation differs from the other arithmetic operations in that we only use the signed version of the operation if the right hand operand (the exponent) is signed. */ int signed_flag = (ivl_expr_signed(le) || is_power_op) && ivl_expr_signed(re) ? 1 : 0; const char*signed_string = signed_flag? "/s" : ""; /* All the arithmetic operations handled here (except for the power operation) require that the operands (and the result) be the same width. We further assume that the core has not given us an operand wider then the expression width. So pad operands as needed. */ draw_eval_vec4(le); if (lwid != ewid) { fprintf(vvp_out, " %%pad/%c %u;\n", ivl_expr_signed(le)? 's' : 'u', ewid); } /* Special case: If the re expression can be collected into an immediate operand, and the instruction supports it, then generate an immediate instruction instead of the generic version. */ if (rwid==ewid && test_immediate_vec4_ok(re)) { switch (ivl_expr_opcode(expr)) { case '+': draw_immediate_vec4(re, "%addi"); return; case '-': draw_immediate_vec4(re, "%subi"); return; case '*': draw_immediate_vec4(re, "%muli"); return; default: break; } } draw_eval_vec4(re); if ((rwid != ewid) && !is_power_op) { fprintf(vvp_out, " %%pad/%c %u;\n", ivl_expr_signed(re)? 's' : 'u', ewid); } switch (ivl_expr_opcode(expr)) { case '+': fprintf(vvp_out, " %%add;\n"); break; case '-': fprintf(vvp_out, " %%sub;\n"); break; case '*': fprintf(vvp_out, " %%mul;\n"); break; case '/': fprintf(vvp_out, " %%div%s;\n", signed_string); break; case '%': fprintf(vvp_out, " %%mod%s;\n", signed_string); break; case 'p': fprintf(vvp_out, " %%pow%s;\n", signed_string); break; default: assert(0); break; } } static void draw_binary_vec4_bitwise(ivl_expr_t expr) { draw_eval_vec4(ivl_expr_oper1(expr)); draw_eval_vec4(ivl_expr_oper2(expr)); switch (ivl_expr_opcode(expr)) { case '&': fprintf(vvp_out, " %%and;\n"); break; case '|': fprintf(vvp_out, " %%or;\n"); break; case '^': fprintf(vvp_out, " %%xor;\n"); break; case 'A': /* ~& */ fprintf(vvp_out, " %%nand;\n"); break; case 'O': /* ~| */ fprintf(vvp_out, " %%nor;\n"); break; case 'X': /* ~^ */ fprintf(vvp_out, " %%xnor;\n"); break; default: assert(0); break; } } static void draw_binary_vec4_compare_real(ivl_expr_t expr) { draw_eval_real(ivl_expr_oper1(expr)); draw_eval_real(ivl_expr_oper2(expr)); switch (ivl_expr_opcode(expr)) { case 'e': /* == */ fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; case 'n': /* != */ fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_inv 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; default: assert(0); } } static void draw_binary_vec4_compare_string(ivl_expr_t expr) { draw_eval_string(ivl_expr_oper1(expr)); draw_eval_string(ivl_expr_oper2(expr)); switch (ivl_expr_opcode(expr)) { case 'e': /* == */ fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; case 'n': /* != */ fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_inv 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; default: assert(0); } } static void draw_binary_vec4_compare_class(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); if (ivl_expr_type(le) == IVL_EX_NULL) { ivl_expr_t tmp = le; le = re; re = tmp; } /* Special case: If both operands are null, then the expression has a constant value. */ if (ivl_expr_type(le)==IVL_EX_NULL && ivl_expr_type(re)==IVL_EX_NULL) { switch (ivl_expr_opcode(expr)) { case 'e': /* == */ fprintf(vvp_out, " %%pushi/vec4 1, 0, 1;\n"); break; case 'n': /* != */ fprintf(vvp_out, " %%pushi/vec4 0, 0, 1;\n"); break; default: assert(0); break; } return; } /* A signal/variable is compared to null. Implement this with the %test_nul statement, which peeks at the variable contents directly. */ if (ivl_expr_type(re)==IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_SIGNAL) { ivl_signal_t sig= ivl_expr_signal(le); if (ivl_signal_dimensions(sig) == 0) { fprintf(vvp_out, " %%test_nul v%p_0;\n", sig); } else { ivl_expr_t word_ex = ivl_expr_oper1(le); int word_ix = allocate_word(); draw_eval_expr_into_integer(word_ex, word_ix); fprintf(vvp_out, " %%test_nul/a v%p, %d;\n", sig, word_ix); clr_word(word_ix); } if (ivl_expr_opcode(expr) == 'n') fprintf(vvp_out, " %%flag_inv 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); return; } if (ivl_expr_type(re)==IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_PROPERTY) { ivl_signal_t sig = ivl_expr_signal(le); unsigned pidx = ivl_expr_property_idx(le); ivl_expr_t idx_expr = ivl_expr_oper1(le); int idx = 0; /* If the property has an array index, then evaluate it into an index register. */ if ( idx_expr ) { idx = allocate_word(); draw_eval_expr_into_integer(idx_expr, idx); } fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%test_nul/prop %u, %d;\n", pidx, idx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); if (ivl_expr_opcode(expr) == 'n') fprintf(vvp_out, " %%flag_inv 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); if (idx != 0) clr_word(idx); return; } fprintf(stderr, "SORRY: Compare class handles not implemented\n"); fprintf(vvp_out, " ; XXXX compare class handles. re-type=%d, le-type=%d\n", ivl_expr_type(re), ivl_expr_type(le)); vvp_errors += 1; } static void draw_binary_vec4_compare(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); if ((ivl_expr_value(le) == IVL_VT_REAL) || (ivl_expr_value(re) == IVL_VT_REAL)) { draw_binary_vec4_compare_real(expr); return; } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { draw_binary_vec4_compare_string(expr); return; } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_type(re)==IVL_EX_STRING)) { draw_binary_vec4_compare_string(expr); return; } if ((ivl_expr_type(le)==IVL_EX_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { draw_binary_vec4_compare_string(expr); return; } if ((ivl_expr_value(le)==IVL_VT_CLASS) && (ivl_expr_value(re)==IVL_VT_CLASS)) { draw_binary_vec4_compare_class(expr); return; } unsigned use_wid = ivl_expr_width(le); if (ivl_expr_width(re) > use_wid) use_wid = ivl_expr_width(re); draw_eval_vec4(le); resize_vec4_wid(le, use_wid); draw_eval_vec4(re); resize_vec4_wid(re, use_wid); switch (ivl_expr_opcode(expr)) { case 'e': /* == */ fprintf(vvp_out, " %%cmp/e;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; case 'n': /* != */ fprintf(vvp_out, " %%cmp/ne;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; case 'E': /* === */ fprintf(vvp_out, " %%cmp/e;\n"); fprintf(vvp_out, " %%flag_get/vec4 6;\n"); break; case 'N': /* !== */ fprintf(vvp_out, " %%cmp/ne;\n"); fprintf(vvp_out, " %%flag_get/vec4 6;\n"); break; case 'w': /* ==? */ fprintf(vvp_out, " %%cmp/we;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; case 'W': /* !=? */ fprintf(vvp_out, " %%cmp/wne;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); break; default: assert(0); } } /* * Handle the logical implication: * -> * which is the same as the expression * ! || * */ static void draw_binary_vec4_limpl(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); /* The arguments should have alreacy been reduced. */ assert(ivl_expr_width(le) == 1); assert(ivl_expr_width(re) == 1); draw_eval_vec4(le); fprintf(vvp_out, " %%inv;\n"); draw_eval_vec4(re); fprintf(vvp_out, " %%or;\n"); } static void draw_binary_vec4_lequiv(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); /* The arguments should have already been reduced. */ assert(ivl_expr_width(le) == 1); draw_eval_vec4(le); assert(ivl_expr_width(re) == 1); draw_eval_vec4(re); fprintf(vvp_out, " %%xnor;\n"); assert(ivl_expr_width(expr) == 1); } static void draw_binary_vec4_logical(ivl_expr_t expr, char op) { const char *opcode; const char *jmp_type; switch (op) { case 'a': opcode = "and"; jmp_type = "0"; break; case 'o': opcode = "or"; jmp_type = "1"; break; default: assert(0); break; } unsigned label_out = local_count++; ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); /* Evaluate the left expression as a conditon and skip the right expression * if the left is false. */ int flag = draw_eval_condition(le); fprintf(vvp_out, " %%flag_get/vec4 %d;\n", flag); fprintf(vvp_out, " %%jmp/%s T_%u.%u, %d;\n", jmp_type, thread_count, label_out, flag); clr_flag(flag); /* Now push the right expression. Reduce to a single bit if necessary. */ draw_eval_vec4(re); if (ivl_expr_width(re) > 1) fprintf(vvp_out, " %%or/r;\n"); fprintf(vvp_out, " %%%s;\n", opcode); fprintf(vvp_out, "T_%u.%u;\n", thread_count, label_out); if (ivl_expr_width(expr) > 1) fprintf(vvp_out, " %%pad/u %u;\n", ivl_expr_width(expr)); } static void draw_binary_vec4_le_real(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); switch (ivl_expr_opcode(expr)) { case '<': draw_eval_real(le); draw_eval_real(re); fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); break; case 'L': /* <= */ draw_eval_real(le); draw_eval_real(re); fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); fprintf(vvp_out, " %%or;\n"); break; case '>': draw_eval_real(re); draw_eval_real(le); fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); break; case 'G': /* >= */ draw_eval_real(re); draw_eval_real(le); fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); fprintf(vvp_out, " %%or;\n"); break; default: assert(0); break; } } static void draw_binary_vec4_le_string(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); switch (ivl_expr_opcode(expr)) { case '<': draw_eval_string(le); draw_eval_string(re); fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); break; case 'L': /* <= */ draw_eval_string(le); draw_eval_string(re); fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); fprintf(vvp_out, " %%or;\n"); break; case '>': draw_eval_string(re); draw_eval_string(le); fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); break; case 'G': /* >= */ draw_eval_string(re); draw_eval_string(le); fprintf(vvp_out, " %%cmp/str;\n"); fprintf(vvp_out, " %%flag_get/vec4 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); fprintf(vvp_out, " %%or;\n"); break; default: assert(0); break; } } static void draw_binary_vec4_le(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); ivl_expr_t tmp; if ((ivl_expr_value(le) == IVL_VT_REAL) || (ivl_expr_value(re) == IVL_VT_REAL)) { draw_binary_vec4_le_real(expr); return; } char use_opcode = ivl_expr_opcode(expr); char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u'; /* If this is a > or >=, then convert it to < or <= by swapping the operands. Adjust the opcode to match. */ switch (use_opcode) { case 'G': tmp = le; le = re; re = tmp; use_opcode = 'L'; break; case '>': tmp = le; le = re; re = tmp; use_opcode = '<'; break; } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { draw_binary_vec4_le_string(expr); return; } if ((ivl_expr_value(le)==IVL_VT_STRING) && (ivl_expr_type(re)==IVL_EX_STRING)) { draw_binary_vec4_le_string(expr); return; } if ((ivl_expr_type(le)==IVL_EX_STRING) && (ivl_expr_value(re)==IVL_VT_STRING)) { draw_binary_vec4_le_string(expr); return; } /* NOTE: I think I would rather the elaborator handle the operand widths. When that happens, take this code out. */ unsigned use_wid = ivl_expr_width(le); if (ivl_expr_width(re) > use_wid) use_wid = ivl_expr_width(re); draw_eval_vec4(le); resize_vec4_wid(le, use_wid); if (ivl_expr_width(re)==use_wid && test_immediate_vec4_ok(re)) { /* Special case: If the right operand can be handled as an immediate operand, then use that instead. */ char opcode[8]; snprintf(opcode, sizeof opcode, "%%cmpi/%c", s_flag); draw_immediate_vec4(re, opcode); } else { draw_eval_vec4(re); resize_vec4_wid(re, use_wid); fprintf(vvp_out, " %%cmp/%c;\n", s_flag); } switch (use_opcode) { case 'L': fprintf(vvp_out, " %%flag_get/vec4 4;\n"); fprintf(vvp_out, " %%flag_get/vec4 5;\n"); fprintf(vvp_out, " %%or;\n"); break; case '<': fprintf(vvp_out, " %%flag_get/vec4 5;\n"); break; default: assert(0); break; } } static void draw_binary_vec4_lrs(ivl_expr_t expr) { ivl_expr_t le = ivl_expr_oper1(expr); ivl_expr_t re = ivl_expr_oper2(expr); // Push the left expression onto the stack. draw_eval_vec4(le); // Calculate the shift amount into an index register. int use_index_reg = allocate_word(); assert(use_index_reg >= 0); draw_eval_expr_into_integer(re, use_index_reg); // Emit the actual shift instruction. This will pop the top of // the stack and replace it with the result of the shift. switch (ivl_expr_opcode(expr)) { case 'l': /* << */ fprintf(vvp_out, " %%shiftl %d;\n", use_index_reg); break; case 'r': /* >> */ fprintf(vvp_out, " %%shiftr %d;\n", use_index_reg); break; case 'R': /* >>> */ if (ivl_expr_signed(le)) fprintf(vvp_out, " %%shiftr/s %d;\n", use_index_reg); else fprintf(vvp_out, " %%shiftr %d;\n", use_index_reg); break; default: assert(0); break; } clr_word(use_index_reg); } static void draw_binary_vec4(ivl_expr_t expr) { switch (ivl_expr_opcode(expr)) { case 'a': /* Logical && */ case 'o': /* || (logical or) */ draw_binary_vec4_logical(expr, ivl_expr_opcode(expr)); break; case '+': case '-': case '*': case '/': case '%': case 'p': /* ** (power) */ draw_binary_vec4_arith(expr); break; case '&': case '|': case '^': case 'A': /* NAND (~&) */ case 'O': /* NOR (~|) */ case 'X': /* exclusive nor (~^) */ draw_binary_vec4_bitwise(expr); break; case 'e': /* == */ case 'E': /* === */ case 'n': /* != */ case 'N': /* !== */ case 'w': /* ==? */ case 'W': /* !=? */ draw_binary_vec4_compare(expr); break; case 'G': /* >= */ case 'L': /* <= */ case '>': case '<': draw_binary_vec4_le(expr); break; case 'l': /* << */ case 'r': /* >> */ case 'R': /* >>> */ draw_binary_vec4_lrs(expr); break; case 'q': /* -> (logical implication) */ draw_binary_vec4_limpl(expr); break; case 'Q': /* <-> (logical equivalence) */ draw_binary_vec4_lequiv(expr); break; default: fprintf(stderr, "vvp.tgt error: unsupported binary (%c)\n", ivl_expr_opcode(expr)); assert(0); } } /* * This handles two special cases: * 1) Making a large IVL_EX_NUMBER as an immediate value. In this * case, start with a %pushi/vec4 to get the stack started, then * continue with %concati/vec4 instructions to build that number * up. * * 2) Concatenating a large IVL_EX_NUMBER to the current top of the * stack. In this case, start with %concati/vec4 and continue * generating %concati/vec4 instructions to finish up the large number. */ static void draw_concat_number_vec4(ivl_expr_t expr, int as_concati) { unsigned long val0 = 0; unsigned long valx = 0; unsigned wid = ivl_expr_width(expr); const char*bits = ivl_expr_bits(expr); unsigned idx; int accum = 0; int count_pushi = as_concati? 1 : 0; /* Scan the literal bits, MSB first. */ for (idx = 0 ; idx < wid ; idx += 1) { val0 <<= 1; valx <<= 1; switch (bits[wid-idx-1]) { case '0': break; case '1': val0 |= 1; break; case 'x': val0 |= 1; valx |= 1; break; case 'z': val0 |= 0; valx |= 1; break; default: assert(0); break; } accum += 1; /* Collect as many bits as can be written by a single %pushi/vec4 instruction. This may be more than 32 if the higher bits are zero, but if the currently accumulated value fills what a %pushi/vec4 can do, then write it out, generate a %concat/vec4, and set up to handle more bits. */ if ( (val0|valx) & 0x80000000UL ) { if (count_pushi) { fprintf(vvp_out, " %%concati/vec4 %lu, %lu, %d;\n", val0, valx, accum); } else { fprintf(vvp_out, " %%pushi/vec4 %lu, %lu, %d;\n", val0, valx, accum); } accum = 0; val0 = 0; valx = 0; count_pushi += 1; } } if (accum) { if (count_pushi) { fprintf(vvp_out, " %%concati/vec4 %lu, %lu, %d;\n", val0, valx, accum); } else { fprintf(vvp_out, " %%pushi/vec4 %lu, %lu, %d;\n", val0, valx, accum); } } } static void draw_concat_vec4(ivl_expr_t expr) { /* Repeat the concatenation this many times to make a super-concatenation. */ unsigned repeat = ivl_expr_repeat(expr); /* This is the number of expressions that go into the concatenation. */ unsigned num_sube = ivl_expr_parms(expr); unsigned sub_idx = 0; ivl_expr_t sube; assert(num_sube > 0); /* Start with the most-significant bits. */ sube = ivl_expr_parm(expr, sub_idx); draw_eval_vec4(sube); /* Evaluate, but skip any zero replication expressions at the * head of this concatenation. */ while ((ivl_expr_type(sube) == IVL_EX_CONCAT) && (ivl_expr_repeat(sube) == 0)) { fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n"); sub_idx += 1; sube = ivl_expr_parm(expr, sub_idx); draw_eval_vec4(sube); } for ( sub_idx += 1 ; sub_idx < num_sube ; sub_idx += 1) { /* Concatenate progressively lower parts. */ sube = ivl_expr_parm(expr, sub_idx); /* Special case: The next expression is a NUMBER that can be concatenated using %concati/vec4 instructions. */ if (ivl_expr_type(sube) == IVL_EX_NUMBER) { draw_concat_number_vec4(sube, 1); continue; } draw_eval_vec4(sube); /* Evaluate, but skip any zero replication expressions in the * rest of this concatenation. */ if ((ivl_expr_type(sube) == IVL_EX_CONCAT) && (ivl_expr_repeat(sube) == 0)) { fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n"); continue; } fprintf(vvp_out, " %%concat/vec4; draw_concat_vec4\n"); } if (repeat > 1) { fprintf(vvp_out, " %%replicate %u;\n", repeat); } } /* * Push a number into the vec4 stack using %pushi/vec4 * instructions. The %pushi/vec4 instruction can only handle up to 32 * non-zero bits, so if there are more than that, then generate * multiple %pushi/vec4 statements, and use %concat/vec4 statements to * concatenate the vectors into the desired result. */ static void draw_number_vec4(ivl_expr_t expr) { draw_concat_number_vec4(expr, 0); } static void draw_property_vec4(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); unsigned pidx = ivl_expr_property_idx(expr); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%prop/v %u;\n", pidx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } static void draw_select_vec4(ivl_expr_t expr) { // This is the sub-expression to part-select. ivl_expr_t subexpr = ivl_expr_oper1(expr); // This is the base of the part select ivl_expr_t base = ivl_expr_oper2(expr); // This is the part select width unsigned wid = ivl_expr_width(expr); // Is the select base expression signed or unsigned? char sign_suff = ivl_expr_signed(base)? 's' : 'u'; // Special Case: If the sub-expression is a STRING, then this // is a select from that string. if (ivl_expr_value(subexpr)==IVL_VT_STRING) { assert(base); assert(wid==8); draw_eval_string(subexpr); int base_idx = allocate_word(); draw_eval_expr_into_integer(base, base_idx); fprintf(vvp_out, " %%substr/vec4 %d, %u;\n", base_idx, wid); fprintf(vvp_out, " %%pop/str 1;\n"); clr_word(base_idx); return; } if (ivl_expr_value(subexpr)==IVL_VT_DARRAY) { ivl_signal_t sig = ivl_expr_signal(subexpr); assert(sig); assert( (ivl_signal_data_type(sig)==IVL_VT_DARRAY) || (ivl_signal_data_type(sig)==IVL_VT_QUEUE) ); assert(base); draw_eval_expr_into_integer(base, 3); fprintf(vvp_out, " %%load/dar/vec4 v%p_0;\n", sig); return; } if (test_immediate_vec4_ok(base)) { unsigned long val0, valx; unsigned base_wid; make_immediate_vec4_words(base, &val0, &valx, &base_wid); assert(valx == 0); draw_eval_vec4(subexpr); fprintf(vvp_out, " %%parti/%c %u, %lu, %u;\n", sign_suff, wid, val0, base_wid); } else { draw_eval_vec4(subexpr); draw_eval_vec4(base); fprintf(vvp_out, " %%part/%c %u;\n", sign_suff, wid); } } static void draw_select_pad_vec4(ivl_expr_t expr) { // This is the sub-expression to pad/truncate ivl_expr_t subexpr = ivl_expr_oper1(expr); // This is the target width of the expression unsigned wid = ivl_expr_width(expr); // Push the sub-expression onto the stack. draw_eval_vec4(subexpr); // Special case: The expression is already the correct width, // so there is nothing to be done. if (wid == ivl_expr_width(subexpr)) return; if (ivl_expr_signed(expr)) fprintf(vvp_out, " %%pad/s %u;\n", wid); else fprintf(vvp_out, " %%pad/u %u;\n", wid); } /* * This function handles the special case of a call to the internal * functions $ivl_queue_method$pop_back et al. The first (and only) * argument is the signal that represents a dynamic queue. Generate a * %qpop instruction to pop a value and push it to the vec4 stack. */ static void draw_darray_pop(ivl_expr_t expr) { const char*fb; if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) fb = "b"; else fb = "f"; ivl_expr_t arg = ivl_expr_parm(expr, 0); assert(ivl_expr_type(arg) == IVL_EX_SIGNAL); fprintf(vvp_out, " %%qpop/%s/v v%p_0, %u;\n", fb, ivl_expr_signal(arg), ivl_expr_width(expr)); } static void draw_sfunc_vec4(ivl_expr_t expr) { unsigned parm_count = ivl_expr_parms(expr); /* Special case: If there are no arguments to print, then the %vpi_call statement is easy to draw. */ if (parm_count == 0) { assert(ivl_expr_value(expr)==IVL_VT_LOGIC || ivl_expr_value(expr)==IVL_VT_BOOL); fprintf(vvp_out, " %%vpi_func %u %u \"%s\" %u {0 0 0};\n", ivl_file_table_index(ivl_expr_file(expr)), ivl_expr_lineno(expr), ivl_expr_name(expr), ivl_expr_width(expr)); return; } if (strcmp(ivl_expr_name(expr), "$ivl_queue_method$pop_back")==0) { draw_darray_pop(expr); return; } if (strcmp(ivl_expr_name(expr),"$ivl_queue_method$pop_front")==0) { draw_darray_pop(expr); return; } draw_vpi_func_call(expr); } static void draw_signal_vec4(ivl_expr_t expr) { ivl_signal_t sig = ivl_expr_signal(expr); /* Special Case: If the signal is the return value of the function, then use a different opcode to get the value. */ if (signal_is_return_value(sig)) { assert(ivl_signal_dimensions(sig) == 0); fprintf(vvp_out, " %%retload/vec4 0; Load %s (draw_signal_vec4)\n", ivl_signal_basename(sig)); return; } /* Handle the simple case, a signal expression that is a simple vector, no array dimensions. */ if (ivl_signal_dimensions(sig) == 0) { fprintf(vvp_out, " %%load/vec4 v%p_0;\n", sig); return; } /* calculate the array index... */ int addr_index = allocate_word(); draw_eval_expr_into_integer(ivl_expr_oper1(expr), addr_index); fprintf(vvp_out, " %%load/vec4a v%p, %d;\n", sig, addr_index); clr_word(addr_index); } static void draw_string_vec4(ivl_expr_t expr) { unsigned wid = ivl_expr_width(expr); char*fp = process_octal_codes(ivl_expr_string(expr), wid); char*p = fp; unsigned long tmp = 0; unsigned tmp_wid = 0; int push_flag = 0; for (unsigned idx = 0 ; idx < wid ; idx += 8) { tmp <<= 8; tmp |= (unsigned long)*p; p += 1; tmp_wid += 8; if (tmp_wid == 32) { fprintf(vvp_out, " %%pushi/vec4 %lu, 0, 32; draw_string_vec4\n", tmp); tmp = 0; tmp_wid = 0; if (push_flag == 0) push_flag += 1; else fprintf(vvp_out, " %%concat/vec4; draw_string_vec4\n"); } } if (tmp_wid > 0) { fprintf(vvp_out, " %%pushi/vec4 %lu, 0, %u; draw_string_vec4\n", tmp, tmp_wid); if (push_flag != 0) fprintf(vvp_out, " %%concat/vec4; draw_string_vec4\n"); } free(fp); } static void draw_ternary_vec4(ivl_expr_t expr) { ivl_expr_t cond = ivl_expr_oper1(expr); ivl_expr_t true_ex = ivl_expr_oper2(expr); ivl_expr_t false_ex = ivl_expr_oper3(expr); unsigned lab_true = local_count++; unsigned lab_out = local_count++; int use_flag = draw_eval_condition(cond); /* The condition flag is used after possibly other statements, so we need to put it into a non-common place. Allocate a safe flag bit and move the condition to the flag position. */ if (use_flag < 8) { int tmp_flag = allocate_flag(); assert(tmp_flag >= 8); fprintf(vvp_out, " %%flag_mov %d, %d;\n", tmp_flag, use_flag); use_flag = tmp_flag; } fprintf(vvp_out, " %%jmp/0 T_%u.%u, %d;\n", thread_count, lab_true, use_flag); /* If the condition is true or xz (not false), we need the true expression. If the condition is true, then we ONLY need the true expression. */ draw_eval_vec4(true_ex); fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", thread_count, lab_out, use_flag); fprintf(vvp_out, "T_%u.%u ; End of true expr.\n", thread_count, lab_true); /* If the condition is false or xz (not true), we need the false expression. If the condition is false, then we ONLY need the false expression. */ draw_eval_vec4(false_ex); fprintf(vvp_out, " %%jmp/0 T_%u.%u, %d;\n", thread_count, lab_out, use_flag); fprintf(vvp_out, " ; End of false expr.\n"); /* Here, the condition is not true or false, it is xz. Both the true and false expressions have been pushed onto the stack, we just need to blend the bits. */ fprintf(vvp_out, " %%blend;\n"); fprintf(vvp_out, "T_%u.%u;\n", thread_count, lab_out); clr_flag(use_flag); } static void draw_unary_inc_dec(ivl_expr_t sub, bool incr, bool pre) { ivl_signal_t sig = 0; unsigned wid = 0; switch (ivl_expr_type(sub)) { case IVL_EX_SELECT: { ivl_expr_t e1 = ivl_expr_oper1(sub); sig = ivl_expr_signal(e1); wid = ivl_expr_width(e1); break; } case IVL_EX_SIGNAL: sig = ivl_expr_signal(sub); wid = ivl_expr_width(sub); break; default: assert(0); break; } draw_eval_vec4(sub); const char*cmd = incr? "%add" : "%sub"; if (pre) { /* prefix means we add the result first, and store the result, as well as leaving a copy on the stack. */ fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", wid); fprintf(vvp_out, " %s;\n", cmd); fprintf(vvp_out, " %%dup/vec4;\n"); fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", sig, wid); } else { /* The post-fix decrement returns the non-decremented version, so there is a slight re-arrange. */ fprintf(vvp_out, " %%dup/vec4;\n"); fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", wid); fprintf(vvp_out, " %s;\n", cmd); fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", sig, wid); } } static void draw_unary_vec4(ivl_expr_t expr) { ivl_expr_t sub = ivl_expr_oper1(expr); if (debug_draw) { fprintf(vvp_out, " ; %s:%u:draw_unary_vec4: opcode=%c\n", ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_opcode(expr)); } switch (ivl_expr_opcode(expr)) { case '&': draw_eval_vec4(sub); fprintf(vvp_out, " %%and/r;\n"); break; case '|': draw_eval_vec4(sub); fprintf(vvp_out, " %%or/r;\n"); break; case '^': draw_eval_vec4(sub); fprintf(vvp_out, " %%xor/r;\n"); break; case '~': draw_eval_vec4(sub); fprintf(vvp_out, " %%inv;\n"); break; case '!': draw_eval_vec4(sub); fprintf(vvp_out, " %%nor/r;\n"); break; case '-': draw_eval_vec4(sub); fprintf(vvp_out, " %%inv;\n"); fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", ivl_expr_width(sub)); fprintf(vvp_out, " %%add;\n"); break; case 'A': /* nand (~&) */ draw_eval_vec4(sub); fprintf(vvp_out, " %%nand/r;\n"); break; case 'D': /* pre-decrement (--x) */ draw_unary_inc_dec(sub, false, true); break; case 'd': /* post_decrement (x--) */ draw_unary_inc_dec(sub, false, false); break; case 'I': /* pre-increment (++x) */ draw_unary_inc_dec(sub, true, true); break; case 'i': /* post-increment (x++) */ draw_unary_inc_dec(sub, true, false); break; case 'N': /* nor (~|) */ draw_eval_vec4(sub); fprintf(vvp_out, " %%nor/r;\n"); break; case 'X': /* xnor (~^) */ draw_eval_vec4(sub); fprintf(vvp_out, " %%xnor/r;\n"); break; case 'm': /* abs(m) */ draw_eval_vec4(sub); if (! ivl_expr_signed(sub)) break; /* Test if (m) < 0 */ fprintf(vvp_out, " %%dup/vec4;\n"); fprintf(vvp_out, " %%pushi/vec4 0, 0, %u;\n", ivl_expr_width(sub)); fprintf(vvp_out, " %%cmp/s;\n"); fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, local_count); /* If so, calculate -(m) */ fprintf(vvp_out, " %%inv;\n"); fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", ivl_expr_width(sub)); fprintf(vvp_out, " %%add;\n"); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_count); local_count += 1; break; case 'v': /* Cast expression to vec4 */ switch (ivl_expr_value(sub)) { case IVL_VT_REAL: draw_eval_real(sub); fprintf(vvp_out, " %%cvt/vr %u;\n", ivl_expr_width(expr)); break; case IVL_VT_STRING: draw_eval_string(sub); fprintf(vvp_out, " %%cast/vec4/str %u;\n", ivl_expr_width(expr)); break; case IVL_VT_DARRAY: draw_eval_object(sub); fprintf(vvp_out, " %%cast/vec4/dar %u;\n", ivl_expr_width(expr)); break; default: assert(0); break; } break; case '2': /* Cast expression to bool */ switch (ivl_expr_value(sub)) { case IVL_VT_LOGIC: draw_eval_vec4(sub); fprintf(vvp_out, " %%cast2;\n"); resize_vec4_wid(sub, ivl_expr_width(expr)); break; case IVL_VT_BOOL: draw_eval_vec4(sub); resize_vec4_wid(sub, ivl_expr_width(expr)); break; case IVL_VT_REAL: draw_eval_real(sub); fprintf(vvp_out, " %%cvt/vr %u;\n", ivl_expr_width(expr)); break; case IVL_VT_STRING: draw_eval_string(sub); fprintf(vvp_out, " %%cast/vec4/str %u;\n", ivl_expr_width(expr)); break; case IVL_VT_DARRAY: draw_eval_object(sub); fprintf(vvp_out, " %%cast/vec2/dar %u;\n", ivl_expr_width(expr)); break; default: assert(0); break; } break; default: fprintf(stderr, "XXXX Unary operator %c not implemented\n", ivl_expr_opcode(expr)); break; } } void draw_eval_vec4(ivl_expr_t expr) { if (debug_draw) { fprintf(vvp_out, " ; %s:%u:draw_eval_vec4: expr_type=%d\n", ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_type(expr)); } switch (ivl_expr_type(expr)) { case IVL_EX_BINARY: draw_binary_vec4(expr); return; case IVL_EX_CONCAT: draw_concat_vec4(expr); return; case IVL_EX_NUMBER: draw_number_vec4(expr); return; case IVL_EX_SELECT: if (ivl_expr_oper2(expr)==0) draw_select_pad_vec4(expr); else draw_select_vec4(expr); return; case IVL_EX_SFUNC: draw_sfunc_vec4(expr); return; case IVL_EX_SIGNAL: draw_signal_vec4(expr); return; case IVL_EX_STRING: draw_string_vec4(expr); return; case IVL_EX_TERNARY: draw_ternary_vec4(expr); return; case IVL_EX_UFUNC: draw_ufunc_vec4(expr); return; case IVL_EX_UNARY: draw_unary_vec4(expr); return; case IVL_EX_PROPERTY: draw_property_vec4(expr); return; case IVL_EX_NULL: fprintf(stderr, "%s:%u: Error: 'null' used in an expression\n", ivl_expr_file(expr), ivl_expr_lineno(expr)); fprintf(vvp_out, "; Error 'null' used in an expression\n"); vvp_errors += 1; return; default: break; } fprintf(stderr, "%s:%u: Sorry: cannot evaluate VEC4 expression (%d)\n", ivl_expr_file(expr), ivl_expr_lineno(expr), ivl_expr_type(expr)); fprintf(vvp_out, "; Sorry: cannot evaluate VEC4 expression (%d)\n", ivl_expr_type(expr)); vvp_errors += 1; } iverilog-12_0/tgt-vvp/modpath.c000066400000000000000000000120361435245347300165600ustar00rootroot00000000000000/* * Copyright (c) 2007-2020 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 "vvp_priv.h" # include # include # include # include "ivl_alloc.h" static ivl_signal_t find_path_source_port(ivl_delaypath_t path) { unsigned idx; ivl_nexus_t nex = ivl_path_source(path); ivl_scope_t path_scope = ivl_path_scope(path); for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; if (ivl_signal_port(sig) == IVL_SIP_NONE) continue; /* The path source scope must match the modpath scope.*/ if (ivl_signal_scope(sig) != path_scope) continue; return sig; } return 0; } /* * Draw a .modpath record. The label is the label to use for this * record. The driver is the label of the net that feeds into the * modpath device. (Note that there is only 1 driver.) The path_sig is * the signal that is the output of this modpath. From that signal we * can find all the modpath source nodes to generate the complete * modpath record. */ static void draw_modpath_record(const char*label, const char*driver, ivl_signal_t path_sig) { unsigned idx; typedef const char*ccharp; ccharp*src_drivers; ccharp*con_drivers; unsigned width = ivl_signal_width(path_sig); src_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); con_drivers = calloc(ivl_signal_npath(path_sig), sizeof(ccharp)); for (idx = 0 ; idx < ivl_signal_npath(path_sig) ; idx += 1) { ivl_delaypath_t path = ivl_signal_path(path_sig, idx); ivl_nexus_t src = ivl_path_source(path); ivl_nexus_t con = ivl_path_condit(path); src_drivers[idx] = draw_net_input(src); if (con) con_drivers[idx] = draw_net_input(con); else if (ivl_path_is_condit(path)) con_drivers[idx] = ""; else con_drivers[idx] = 0; } fprintf(vvp_out, " .scope S_%p;\n", ivl_path_scope(ivl_signal_path(path_sig,0))); fprintf(vvp_out, "%s .modpath %u %s v%p_0", label, width, driver, path_sig); for (idx = 0 ; idx < ivl_signal_npath(path_sig); idx += 1) { ivl_delaypath_t path = ivl_signal_path(path_sig, idx); int ppos = ivl_path_source_posedge(path); int pneg = ivl_path_source_negedge(path); const char*edge = ppos? " +" : pneg ? " -" : ""; ivl_signal_t src_sig; fprintf(vvp_out, ",\n %s%s", src_drivers[idx], edge); fprintf(vvp_out, " (%"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64 ", %"PRIu64",%"PRIu64",%"PRIu64, ivl_path_delay(path, IVL_PE_01), ivl_path_delay(path, IVL_PE_10), ivl_path_delay(path, IVL_PE_0z), ivl_path_delay(path, IVL_PE_z1), ivl_path_delay(path, IVL_PE_1z), ivl_path_delay(path, IVL_PE_z0), ivl_path_delay(path, IVL_PE_0x), ivl_path_delay(path, IVL_PE_x1), ivl_path_delay(path, IVL_PE_1x), ivl_path_delay(path, IVL_PE_x0), ivl_path_delay(path, IVL_PE_xz), ivl_path_delay(path, IVL_PE_zx)); if (con_drivers[idx]) { fprintf(vvp_out, " ? %s", con_drivers[idx]); } fprintf(vvp_out, ")"); src_sig = find_path_source_port(path); fprintf(vvp_out, " v%p_0", src_sig); } fprintf(vvp_out, ";\n"); free(src_drivers); free(con_drivers); } struct modpath_item { ivl_signal_t path_sig; char*drive_label; unsigned drive_index; struct modpath_item*next; }; static struct modpath_item*modpath_list = 0; void draw_modpath(ivl_signal_t path_sig, char*drive_label, unsigned drive_index) { struct modpath_item*cur = calloc(1, sizeof(struct modpath_item)); cur->path_sig = path_sig; cur->drive_label = drive_label; cur->drive_index = drive_index; cur->next = modpath_list; modpath_list = cur; } void cleanup_modpath(void) { while (modpath_list) { struct modpath_item*cur = modpath_list; char modpath_label[64]; modpath_list = cur->next; snprintf(modpath_label, sizeof modpath_label, "V_%p_%u/m", cur->path_sig, cur->drive_index); draw_modpath_record(modpath_label, cur->drive_label, cur->path_sig); free(cur->drive_label); free(cur); } } iverilog-12_0/tgt-vvp/stmt_assign.c000066400000000000000000001270011435245347300174560ustar00rootroot00000000000000/* * Copyright (c) 2011-2020 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 "vvp_priv.h" # include # include # include # include /* * These functions handle the blocking assignment. Use the %set * instruction to perform the actual assignment, and calculate any * lvalues and rvalues that need calculating. * * The set_to_lvariable function takes a particular nexus and generates * the %set statements to assign the value. * * The show_stmt_assign function looks at the assign statement, scans * the l-values, and matches bits of the r-value with the correct * nexus. */ enum slice_type_e { SLICE_NO_TYPE = 0, SLICE_SIMPLE_VECTOR, SLICE_PART_SELECT_STATIC, SLICE_PART_SELECT_DYNAMIC, SLICE_MEMORY_WORD_STATIC, SLICE_MEMORY_WORD_DYNAMIC }; struct vec_slice_info { enum slice_type_e type; union { struct { unsigned long use_word; } simple_vector; struct { unsigned long part_off; } part_select_static; struct { /* Index reg that holds the memory word index */ int word_idx_reg; /* Stored x/non-x flag */ unsigned x_flag; } part_select_dynamic; struct { unsigned long use_word; } memory_word_static; struct { /* Index reg that holds the memory word index */ int word_idx_reg; /* Stored x/non-x flag */ unsigned x_flag; } memory_word_dynamic; } u_; }; static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice, unsigned wid) { ivl_signal_t sig = ivl_lval_sig(lval); ivl_expr_t part_off_ex = ivl_lval_part_off(lval); unsigned long part_off = 0; /* Although Verilog doesn't support it, we'll handle here the case of an l-value part select of an array word if the address is constant. */ ivl_expr_t word_ix = ivl_lval_idx(lval); unsigned long use_word = 0; if (part_off_ex == 0) { part_off = 0; } else if (number_is_immediate(part_off_ex, IMM_WID, 0) && !number_is_unknown(part_off_ex)) { part_off = get_number_immediate(part_off_ex); part_off_ex = 0; } /* If the word index is a constant expression, then evaluate it to select the word, and pay no further heed to the expression itself. */ if (word_ix && number_is_immediate(word_ix, IMM_WID, 0)) { if (number_is_unknown(word_ix)) use_word = ULONG_MAX; // The largest valid index is ULONG_MAX - 1 else use_word = get_number_immediate(word_ix); word_ix = 0; } if (ivl_signal_dimensions(sig)==0 && part_off_ex==0 && word_ix==0 && part_off==0 && wid==ivl_signal_width(sig)) { slice->type = SLICE_SIMPLE_VECTOR; slice->u_.simple_vector.use_word = use_word; if (signal_is_return_value(sig)) { assert(use_word==0); fprintf(vvp_out, " %%retload/vec4 0;\n"); } else { fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word); } } else if (ivl_signal_dimensions(sig)==0 && part_off_ex==0 && word_ix==0) { assert(use_word == 0); slice->type = SLICE_PART_SELECT_STATIC; slice->u_.part_select_static.part_off = part_off; if (signal_is_return_value(sig)) { assert(use_word==0); fprintf(vvp_out, " %%retload/vec4 0;\n"); } else { fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word); } fprintf(vvp_out, " %%pushi/vec4 %lu, 0, 32;\n", part_off); fprintf(vvp_out, " %%part/u %u;\n", wid); } else if (ivl_signal_dimensions(sig)==0 && part_off_ex!=0 && word_ix==0) { assert(use_word == 0); assert(part_off == 0); assert(!signal_is_return_value(sig)); // NOT IMPLEMENTED slice->type = SLICE_PART_SELECT_DYNAMIC; slice->u_.part_select_dynamic.word_idx_reg = allocate_word(); slice->u_.part_select_dynamic.x_flag = allocate_flag(); fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word); draw_eval_vec4(part_off_ex); fprintf(vvp_out, " %%dup/vec4;\n"); fprintf(vvp_out, " %%ix/vec4 %d;\n", slice->u_.part_select_dynamic.word_idx_reg); fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag); fprintf(vvp_out, " %%part/u %u;\n", wid); } else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) { assert(!signal_is_return_value(sig)); // NOT IMPLEMENTED slice->type = SLICE_MEMORY_WORD_STATIC; slice->u_.memory_word_static.use_word = use_word; if (use_word < ivl_signal_array_count(sig)) { fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n", use_word); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%load/vec4a v%p, 3;\n", sig); } else { if (wid <= 32) { fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, %u;\n", wid); } else { fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, 32;\n"); fprintf(vvp_out, " %%pad/s %u;\n", wid); } } } else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) { assert(!signal_is_return_value(sig)); // NOT IMPLEMENTED slice->type = SLICE_MEMORY_WORD_DYNAMIC; slice->u_.memory_word_dynamic.word_idx_reg = allocate_word(); slice->u_.memory_word_dynamic.x_flag = allocate_flag(); draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg); fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.memory_word_dynamic.x_flag); fprintf(vvp_out, " %%load/vec4a v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg); } else { assert(0); } } /* * This loads the l-value values into the top of the stack, and also * leaves in the slices the information needed to store the slice * results back. */ static void get_vec_from_lval(ivl_statement_t net, struct vec_slice_info*slices) { unsigned lidx; unsigned cur_bit; unsigned wid = ivl_stmt_lwidth(net); cur_bit = 0; for (lidx = ivl_stmt_lvals(net) ; lidx > 0 ; lidx -= 1) { ivl_lval_t lval; unsigned bit_limit = wid - cur_bit; lval = ivl_stmt_lval(net, lidx-1); if (bit_limit > ivl_lval_width(lval)) bit_limit = ivl_lval_width(lval); get_vec_from_lval_slice(lval, slices+lidx-1, bit_limit); if (cur_bit > 0) { fprintf(vvp_out, " %%concat/vec4;\n"); } cur_bit += bit_limit; } } static void put_vec_to_ret_slice(ivl_signal_t sig, struct vec_slice_info*slice, unsigned wid) { int part_off_idx; /* If the slice of the l-value is a BOOL variable, then cast the data to a BOOL vector so that the stores can be valid. */ if (ivl_signal_data_type(sig) == IVL_VT_BOOL) { fprintf(vvp_out, " %%cast2;\n"); } switch (slice->type) { default: fprintf(vvp_out, " ; XXXX slice->type=%d\n", slice->type); assert(0); break; case SLICE_SIMPLE_VECTOR: assert(slice->u_.simple_vector.use_word == 0); fprintf(vvp_out, " %%ret/vec4 0, 0, %u;\n", wid); break; case SLICE_PART_SELECT_STATIC: part_off_idx = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", part_off_idx, slice->u_.part_select_static.part_off); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%ret/vec4 0, %d, %u;\n", part_off_idx, wid); clr_word(part_off_idx); break; case SLICE_PART_SELECT_DYNAMIC: fprintf(vvp_out, " %%flag_mov 4, %u;\n", slice->u_.part_select_dynamic.x_flag); fprintf(vvp_out, " %%ret/vec4 0, %d, %u;\n", slice->u_.part_select_dynamic.word_idx_reg, wid); clr_word(slice->u_.part_select_dynamic.word_idx_reg); clr_flag(slice->u_.part_select_dynamic.x_flag); break; } } static void put_vec_to_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice, unsigned wid) { //unsigned skip_set = transient_id++; ivl_signal_t sig = ivl_lval_sig(lval); int part_off_idx; /* Special Case: If the l-value signal is named after its scope, and the scope is a function, then this is an assign to a return value and should be handled differently. */ if (signal_is_return_value(sig)) { put_vec_to_ret_slice(sig, slice, wid); return; } /* If the slice of the l-value is a BOOL variable, then cast the data to a BOOL vector so that the stores can be valid. */ if (ivl_signal_data_type(sig) == IVL_VT_BOOL) { fprintf(vvp_out, " %%cast2;\n"); } switch (slice->type) { default: fprintf(vvp_out, " ; XXXX slice->type=%d\n", slice->type); assert(0); break; case SLICE_SIMPLE_VECTOR: fprintf(vvp_out, " %%store/vec4 v%p_%lu, 0, %u;\n", sig, slice->u_.simple_vector.use_word, wid); break; case SLICE_PART_SELECT_STATIC: part_off_idx = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", part_off_idx, slice->u_.part_select_static.part_off); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n", sig, part_off_idx, wid); clr_word(part_off_idx); break; case SLICE_PART_SELECT_DYNAMIC: fprintf(vvp_out, " %%flag_mov 4, %u;\n", slice->u_.part_select_dynamic.x_flag); fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n", sig, slice->u_.part_select_dynamic.word_idx_reg, wid); clr_word(slice->u_.part_select_dynamic.word_idx_reg); clr_flag(slice->u_.part_select_dynamic.x_flag); break; case SLICE_MEMORY_WORD_STATIC: if (slice->u_.memory_word_static.use_word < ivl_signal_array_count(sig)) { int word_idx = allocate_word(); fprintf(vvp_out," %%flag_set/imm 4, 0;\n"); fprintf(vvp_out," %%ix/load %d, %lu, 0;\n", word_idx, slice->u_.memory_word_static.use_word); fprintf(vvp_out," %%store/vec4a v%p, %d, 0;\n", sig, word_idx); clr_word(word_idx); } else { fprintf(vvp_out," ; Skip this slice write to v%p [%lu]\n", sig, slice->u_.memory_word_static.use_word); fprintf(vvp_out," %%pop/vec4 1;\n"); } break; case SLICE_MEMORY_WORD_DYNAMIC: fprintf(vvp_out, " %%flag_mov 4, %u;\n", slice->u_.memory_word_dynamic.x_flag); fprintf(vvp_out, " %%store/vec4a v%p, %d, 0;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg); clr_word(slice->u_.memory_word_dynamic.word_idx_reg); clr_flag(slice->u_.memory_word_dynamic.x_flag); break; } } static void put_vec_to_lval(ivl_statement_t net, struct vec_slice_info*slices) { unsigned lidx; unsigned cur_bit; unsigned wid = ivl_stmt_lwidth(net); cur_bit = 0; for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { ivl_lval_t lval; unsigned bit_limit = wid - cur_bit; lval = ivl_stmt_lval(net, lidx); if (bit_limit > ivl_lval_width(lval)) bit_limit = ivl_lval_width(lval); if (lidx+1 < ivl_stmt_lvals(net)) fprintf(vvp_out, " %%split/vec4 %u;\n", bit_limit); put_vec_to_lval_slice(lval, slices+lidx, bit_limit); cur_bit += bit_limit; } } static ivl_type_t draw_lval_expr(ivl_lval_t lval) { ivl_lval_t lval_nest = ivl_lval_nest(lval); ivl_signal_t lval_sig = ivl_lval_sig(lval); ivl_type_t sub_type; if (lval_nest) { sub_type = draw_lval_expr(lval_nest); } else { assert(lval_sig); sub_type = ivl_signal_net_type(lval_sig); assert(ivl_type_base(sub_type) == IVL_VT_CLASS); fprintf(vvp_out, " %%load/obj v%p_0;\n", lval_sig); } assert(ivl_type_base(sub_type) == IVL_VT_CLASS); if (ivl_lval_idx(lval)) { fprintf(vvp_out, " ; XXXX Don't know how to handle ivl_lval_idx values here.\n"); } fprintf(vvp_out, " %%prop/obj %d, 0; draw_lval_expr\n", ivl_lval_property_idx(lval)); fprintf(vvp_out, " %%pop/obj 1, 1;\n"); return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval)); } /* * Store a vector from the vec4 stack to the statement l-values. This * all assumes that the value to be assigned is already on the top of * the stack. * * NOTE TO SELF: The %store/vec4 takes a width, but the %assign/vec4 * instructions do not, instead relying on the expression width. I * think that it the proper way to do it, so soon I should change the * %store/vec4 to not include the width operand. */ static void store_vec4_to_lval(ivl_statement_t net) { for (unsigned lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { ivl_lval_t lval = ivl_stmt_lval(net,lidx); ivl_signal_t lsig = ivl_lval_sig(lval); ivl_lval_t nest = ivl_lval_nest(lval); unsigned lwid = ivl_lval_width(lval); ivl_expr_t part_off_ex = ivl_lval_part_off(lval); /* This is non-nil if the l-val is the word of a memory, and nil otherwise. */ ivl_expr_t word_ex = ivl_lval_idx(lval); if (lidx+1 < ivl_stmt_lvals(net)) fprintf(vvp_out, " %%split/vec4 %u;\n", lwid); if (word_ex) { /* Handle index into an array */ int word_index = allocate_word(); int part_index = 0; /* Calculate the word address into word_index */ draw_eval_expr_into_integer(word_ex, word_index); /* If there is a part_offset, calculate it into part_index. */ if (part_off_ex) { int flag_index = allocate_flag(); part_index = allocate_word(); fprintf(vvp_out, " %%flag_mov %d, 4;\n", flag_index); draw_eval_expr_into_integer(part_off_ex, part_index); fprintf(vvp_out, " %%flag_or 4, %d;\n", flag_index); clr_flag(flag_index); } assert(lsig); fprintf(vvp_out, " %%store/vec4a v%p, %d, %d;\n", lsig, word_index, part_index); clr_word(word_index); if (part_index) clr_word(part_index); } else if (part_off_ex) { /* Dynamically calculated part offset */ int offset_index = allocate_word(); draw_eval_expr_into_integer(part_off_ex, offset_index); /* Note that flag4 is set by the eval above. */ assert(lsig); if (signal_is_return_value(lsig)) { fprintf(vvp_out, " %%ret/vec4 0, %d, %u; Assign to %s (store_vec4_to_lval)\n", offset_index, lwid, ivl_signal_basename(lsig)); } else if (ivl_signal_type(lsig)==IVL_SIT_UWIRE) { fprintf(vvp_out, " %%force/vec4/off v%p_0, %d;\n", lsig, offset_index); } else { fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n", lsig, offset_index, lwid); } clr_word(offset_index); } else if (nest) { /* No offset expression, but the l-value is nested, which probably means that it is a class member. We will use a property assign function. */ assert(!lsig); ivl_type_t sub_type = draw_lval_expr(nest); assert(ivl_type_base(sub_type) == IVL_VT_CLASS); fprintf(vvp_out, " %%store/prop/v %d, %u;\n", ivl_lval_property_idx(lval), lwid); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else { /* No offset expression, so use simpler store function. */ assert(lsig); assert(lwid == ivl_signal_width(lsig)); if (signal_is_return_value(lsig)) { fprintf(vvp_out, " %%ret/vec4 0, 0, %u; Assign to %s (store_vec4_to_lval)\n", lwid, ivl_signal_basename(lsig)); } else { fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", lsig, lwid); } } } } static int show_stmt_assign_vector(ivl_statement_t net) { ivl_expr_t rval = ivl_stmt_rval(net); //struct vector_info res; //struct vector_info lres = {0, 0}; struct vec_slice_info*slices = 0; int idx_reg; /* If this is a compressed assignment, then get the contents of the l-value. We need these values as part of the r-value calculation. */ if (ivl_stmt_opcode(net) != 0) { fprintf(vvp_out, " ; show_stmt_assign_vector: Get l-value for compressed %c= operand\n", ivl_stmt_opcode(net)); slices = calloc(ivl_stmt_lvals(net), sizeof(struct vec_slice_info)); get_vec_from_lval(net, slices); } /* Handle the special case that the expression is a real value. Evaluate the real expression, then convert the result to a vector. Then store that vector into the l-value. */ if (ivl_expr_value(rval) == IVL_VT_REAL) { draw_eval_real(rval); /* This is the accumulated with of the l-value of the assignment. */ unsigned wid = ivl_stmt_lwidth(net); /* Convert a calculated real value to a vec4 value of the given width. We need to include the width of the result because real values to not have any inherit width. The real value will be popped, and a vec4 value pushed. */ fprintf(vvp_out, " %%cvt/vr %u;\n", wid); } else { unsigned wid = ivl_stmt_lwidth(net); draw_eval_vec4(rval); resize_vec4_wid(rval, wid); } switch (ivl_stmt_opcode(net)) { case 0: store_vec4_to_lval(net); break; case '+': fprintf(vvp_out, " %%add;\n"); put_vec_to_lval(net, slices); break; case '-': fprintf(vvp_out, " %%sub;\n"); put_vec_to_lval(net, slices); break; case '*': fprintf(vvp_out, " %%mul;\n"); put_vec_to_lval(net, slices); break; case '/': fprintf(vvp_out, " %%div%s;\n", ivl_expr_signed(rval)? "/s":""); put_vec_to_lval(net, slices); break; case '%': fprintf(vvp_out, " %%mod%s;\n", ivl_expr_signed(rval)? "/s":""); put_vec_to_lval(net, slices); break; case '&': fprintf(vvp_out, " %%and;\n"); put_vec_to_lval(net, slices); break; case '|': fprintf(vvp_out, " %%or;\n"); put_vec_to_lval(net, slices); break; case '^': fprintf(vvp_out, " %%xor;\n"); put_vec_to_lval(net, slices); break; case 'l': /* lval <<= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftl %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; case 'r': /* lval >>= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftr %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; case 'R': /* lval >>>= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftr/s %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; default: fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net)); assert(0); break; } if (slices) free(slices); return 0; } enum real_lval_type_e { REAL_NO_TYPE = 0, REAL_SIMPLE_WORD, REAL_MEMORY_WORD_STATIC, REAL_MEMORY_WORD_DYNAMIC }; struct real_lval_info { enum real_lval_type_e type; union { struct { unsigned long use_word; } simple_word; struct { unsigned long use_word; } memory_word_static; struct { /* Index reg that holds the memory word index */ int word_idx_reg; /* Stored x/non-x flag */ unsigned x_flag; } memory_word_dynamic; } u_; }; static void get_real_from_lval(ivl_lval_t lval, struct real_lval_info*slice) { ivl_signal_t sig = ivl_lval_sig(lval); ivl_expr_t word_ix = ivl_lval_idx(lval); unsigned long use_word = 0; /* If the word index is a constant expression, then evaluate it to select the word, and pay no further heed to the expression itself. */ if (word_ix && number_is_immediate(word_ix, IMM_WID, 0)) { if (number_is_unknown(word_ix)) use_word = ULONG_MAX; // The largest valid index is ULONG_MAX - 1 else use_word = get_number_immediate(word_ix); word_ix = 0; } if (ivl_signal_dimensions(sig)==0 && word_ix==0) { slice->type = REAL_SIMPLE_WORD; slice->u_.simple_word.use_word = use_word; if (signal_is_return_value(sig)) { assert(use_word==0); fprintf(vvp_out, " %%retload/real 0;\n"); } else { fprintf(vvp_out, " %%load/real v%p_%lu;\n", sig, use_word); } } else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) { assert(!signal_is_return_value(sig)); // NOT IMPLEMENTED slice->type = REAL_MEMORY_WORD_STATIC; slice->u_.memory_word_static.use_word = use_word; if (use_word < ivl_signal_array_count(sig)) { fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n", use_word); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%load/ar v%p, 3;\n", sig); } else { fprintf(vvp_out, " %%pushi/real 0, 0;\n"); } } else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) { assert(!signal_is_return_value(sig)); // NOT IMPLEMENTED slice->type = REAL_MEMORY_WORD_DYNAMIC; slice->u_.memory_word_dynamic.word_idx_reg = allocate_word(); slice->u_.memory_word_dynamic.x_flag = allocate_flag(); draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg); fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.memory_word_dynamic.x_flag); fprintf(vvp_out, " %%load/ar v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg); } else { assert(0); } } static void put_real_to_lval(ivl_lval_t lval, struct real_lval_info*slice) { ivl_signal_t sig = ivl_lval_sig(lval); /* Special Case: If the l-value signal is named after its scope, and the scope is a function, then this is an assign to a return value and should be handled differently. */ if (signal_is_return_value(sig)) { assert(slice->u_.simple_word.use_word == 0); fprintf(vvp_out, " %%ret/real 0;\n"); return; } switch (slice->type) { default: fprintf(vvp_out, " ; XXXX slice->type=%d\n", slice->type); assert(0); break; case REAL_SIMPLE_WORD: fprintf(vvp_out, " %%store/real v%p_%lu;\n", sig, slice->u_.simple_word.use_word); break; case REAL_MEMORY_WORD_STATIC: if (slice->u_.memory_word_static.use_word < ivl_signal_array_count(sig)) { int word_idx = allocate_word(); fprintf(vvp_out," %%flag_set/imm 4, 0;\n"); fprintf(vvp_out," %%ix/load %d, %lu, 0;\n", word_idx, slice->u_.memory_word_static.use_word); fprintf(vvp_out," %%store/reala v%p, %d;\n", sig, word_idx); clr_word(word_idx); } else { fprintf(vvp_out," ; Skip this slice write to v%p [%lu]\n", sig, slice->u_.memory_word_static.use_word); fprintf(vvp_out," %%pop/real 1;\n"); } break; case REAL_MEMORY_WORD_DYNAMIC: fprintf(vvp_out, " %%flag_mov 4, %u;\n", slice->u_.memory_word_dynamic.x_flag); fprintf(vvp_out, " %%store/reala v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg); clr_word(slice->u_.memory_word_dynamic.word_idx_reg); clr_flag(slice->u_.memory_word_dynamic.x_flag); break; } } static void store_real_to_lval(ivl_lval_t lval) { ivl_signal_t var; var = ivl_lval_sig(lval); assert(var != 0); /* Special Case: If the l-value signal is named after its scope, and the scope is a function, then this is an assign to a return value and should be handled differently. */ ivl_scope_t sig_scope = ivl_signal_scope(var); if ((ivl_scope_type(sig_scope) == IVL_SCT_FUNCTION) && (strcmp(ivl_signal_basename(var), ivl_scope_basename(sig_scope)) == 0)) { assert(ivl_signal_dimensions(var) == 0); fprintf(vvp_out, " %%ret/real 0; Assign to %s\n", ivl_signal_basename(var)); return; } if (ivl_signal_dimensions(var) == 0) { fprintf(vvp_out, " %%store/real v%p_0;\n", var); return; } ivl_expr_t word_ex = ivl_lval_idx(lval); int word_ix = allocate_word(); draw_eval_expr_into_integer(word_ex, word_ix); fprintf(vvp_out, " %%store/reala v%p, %d;\n", var, word_ix); clr_word(word_ix); } /* * This function assigns a value to a real variable. This is destined * for /dev/null when typed ivl_signal_t takes over all the real * variable support. */ static int show_stmt_assign_sig_real(ivl_statement_t net) { struct real_lval_info*slice = 0; ivl_lval_t lval; assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); /* If this is a compressed assignment, then get the contents of the l-value. We need this value as part of the r-value calculation. */ if (ivl_stmt_opcode(net) != 0) { fprintf(vvp_out, " ; show_stmt_assign_real: Get l-value for compressed %c= operand\n", ivl_stmt_opcode(net)); slice = calloc(1, sizeof(struct real_lval_info)); get_real_from_lval(lval, slice); } draw_eval_real(ivl_stmt_rval(net)); switch (ivl_stmt_opcode(net)) { case 0: store_real_to_lval(lval); if (slice) free(slice); return 0; case '+': fprintf(vvp_out, " %%add/wr;\n"); break; case '-': fprintf(vvp_out, " %%sub/wr;\n"); break; case '*': fprintf(vvp_out, " %%mul/wr;\n"); break; case '/': fprintf(vvp_out, " %%div/wr;\n"); break; case '%': fprintf(vvp_out, " %%mod/wr;\n"); break; default: fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net)); assert(0); break; } put_real_to_lval(lval, slice); free(slice); return 0; } static int show_stmt_assign_sig_string(ivl_statement_t net) { ivl_lval_t lval = ivl_stmt_lval(net, 0); ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t part = ivl_lval_part_off(lval); ivl_expr_t aidx = ivl_lval_idx(lval); ivl_signal_t var= ivl_lval_sig(lval); assert(ivl_stmt_lvals(net) == 1); assert(ivl_stmt_opcode(net) == 0); /* Special case: If the l-value signal (string) is named after its scope, and the scope is a function, then this is an assign to a return value and should be handled differently. */ if (signal_is_return_value(var)) { assert(ivl_signal_dimensions(var) == 0); assert(part == 0 && aidx == 0); draw_eval_string(rval); fprintf(vvp_out, " %%ret/str 0; Assign to %s\n", ivl_signal_basename(var)); return 0; } /* Simplest case: no mux. Evaluate the r-value as a string and store the result into the variable. Note that the %store/str opcode pops the string result. */ if (part == 0 && aidx == 0) { draw_eval_string(rval); fprintf(vvp_out, " %%store/str v%p_0;\n", var); return 0; } /* Assign to array. The l-value has an index expression expression so we are assigning to an array word. */ if (aidx != 0) { unsigned ix; assert(part == 0); draw_eval_string(rval); draw_eval_expr_into_integer(aidx, (ix = allocate_word())); fprintf(vvp_out, " %%store/stra v%p, %u;\n", var, ix); clr_word(ix); return 0; } assert(ivl_expr_width(rval)==8); draw_eval_vec4(rval); /* Calculate the character select for the word. */ int mux_word = allocate_word(); draw_eval_expr_into_integer(part, mux_word); fprintf(vvp_out, " %%putc/str/vec4 v%p_0, %d;\n", var, mux_word); clr_word(mux_word); return 0; } /* * This function handles the special case that we assign an array * pattern to a dynamic array. Handle this by assigning each * element. The array pattern will have a fixed size. */ static int show_stmt_assign_darray_pattern(ivl_statement_t net) { int errors = 0; ivl_lval_t lval = ivl_stmt_lval(net, 0); ivl_expr_t rval = ivl_stmt_rval(net); ivl_signal_t var = ivl_lval_sig(lval); ivl_type_t var_type= ivl_signal_net_type(var); assert(ivl_type_base(var_type) == IVL_VT_DARRAY); ivl_type_t element_type = ivl_type_element(var_type); unsigned idx; unsigned size_reg = allocate_word(); #if 0 unsigned element_width = 1; if (ivl_type_base(element_type) == IVL_VT_BOOL) element_width = ivl_type_packed_width(element_type); else if (ivl_type_base(element_type) == IVL_VT_LOGIC) element_width = ivl_type_packed_width(element_type); #endif // FIXME: At the moment we reallocate the array space. // This probably should be a resize to avoid values glitching /* Allocate at least enough space for the array pattern. */ fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", size_reg, ivl_expr_parms(rval)); /* This can not have have a X/Z value so clear flag 4. */ fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); darray_new(element_type, size_reg); fprintf(vvp_out, " %%store/obj v%p_0;\n", var); assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN); for (idx = 0 ; idx < ivl_expr_parms(rval) ; idx += 1) { switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: draw_eval_vec4(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var); break; case IVL_VT_REAL: draw_eval_real(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var); break; case IVL_VT_STRING: draw_eval_string(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var); break; default: fprintf(vvp_out, "; ERROR: show_stmt_assign_darray_pattern: type_base=%d not implemented\n", ivl_type_base(element_type)); errors += 1; break; } } return errors; } static int show_stmt_assign_sig_darray(ivl_statement_t net) { int errors = 0; ivl_lval_t lval = ivl_stmt_lval(net, 0); ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t part = ivl_lval_part_off(lval); ivl_signal_t var= ivl_lval_sig(lval); ivl_type_t var_type= ivl_signal_net_type(var); assert(ivl_type_base(var_type) == IVL_VT_DARRAY); ivl_type_t element_type = ivl_type_element(var_type); ivl_expr_t mux = ivl_lval_idx(lval); assert(ivl_stmt_lvals(net) == 1); assert(ivl_stmt_opcode(net) == 0); assert(part == 0); if (mux && (ivl_type_base(element_type) == IVL_VT_REAL)) { draw_eval_real(rval); /* The %store/dar/r expects the array index to be in index register 3. Calculate the index in place. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var); } else if (mux && ivl_type_base(element_type) == IVL_VT_STRING) { draw_eval_string(rval); /* The %store/dar/str expects the array index to me in index register 3. Calculate the index in place. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var); } else if (mux) { draw_eval_vec4(rval); resize_vec4_wid(rval, ivl_stmt_lwidth(net)); /* The %store/dar/vec4 expects the array index to be in index register 3. Calculate the index in place. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var); } else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) { /* There is no l-value mux, but the r-value is an array pattern. This is a special case of an assignment to elements of the l-value. */ errors += show_stmt_assign_darray_pattern(net); } else if (ivl_expr_type(rval) == IVL_EX_NEW) { // There is no l-value mux, and the r-value expression is // a "new" expression. Handle this by simply storing the // new object to the lval. errors += draw_eval_object(rval); fprintf(vvp_out, " %%store/obj v%p_0; %s:%u: %s = new ...\n", var, ivl_stmt_file(net), ivl_stmt_lineno(net), ivl_signal_basename(var)); } else if (ivl_expr_type(rval) == IVL_EX_SIGNAL) { // There is no l-value mux, and the r-value expression is // a "signal" expression. Store a duplicate into the lvalue // By using the %dup/obj. Remember to pop the rvalue that // is no longer needed. errors += draw_eval_object(rval); fprintf(vvp_out, " %%dup/obj;\n"); fprintf(vvp_out, " %%store/obj v%p_0; %s:%u: %s = \n", var, ivl_stmt_file(net), ivl_stmt_lineno(net), ivl_signal_basename(var)); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else { // There is no l-value mux, so this must be an // assignment to the array as a whole. Evaluate the // "object", and store the evaluated result. errors += draw_eval_object(rval); fprintf(vvp_out, " %%store/obj v%p_0; %s:%u: %s = \n", var, ivl_stmt_file(net), ivl_stmt_lineno(net), ivl_signal_basename(var), ivl_expr_type(rval)); } return errors; } /* * This function handles the special case that we assign an array * pattern to a queue. Handle this by assigning each element. * The array pattern will have a fixed size. */ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval, ivl_type_t element_type, int max_idx) { int errors = 0; unsigned idx; unsigned max_size; unsigned max_elems; assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN); max_size = ivl_signal_array_count(var); max_elems = ivl_expr_parms(rval); if ((max_size != 0) && (max_elems > max_size)) { fprintf(stderr, "%s:%u: Warning: Array pattern assignment has more elements " "(%u) than bounded queue '%s' supports (%u).\n" " Only using first %u elements.\n", ivl_expr_file(rval), ivl_expr_lineno(rval), max_elems, ivl_signal_basename(var), max_size, max_size); max_elems = max_size; } for (idx = 0 ; idx < max_elems ; idx += 1) { switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: draw_eval_vec4(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, max_idx, ivl_type_packed_width(element_type)); break; case IVL_VT_REAL: draw_eval_real(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, max_idx); break; case IVL_VT_STRING: draw_eval_string(ivl_expr_parm(rval,idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, max_idx); break; default: fprintf(vvp_out, "; ERROR: show_stmt_assign_queue_pattern: " "type_base=%d not implemented\n", ivl_type_base(element_type)); errors += 1; break; } } if ((max_size == 0) || (max_elems < max_size)) { int del_idx = allocate_word(); assert(del_idx >= 0); /* Save the first queue element to delete. */ fprintf(vvp_out, " %%ix/load %d, %u, 0;\n", del_idx, max_elems); fprintf(vvp_out, " %%delete/tail v%p_0, %d;\n", var, del_idx); clr_word(del_idx); } return errors; } static int show_stmt_assign_sig_queue(ivl_statement_t net) { int errors = 0; ivl_lval_t lval = ivl_stmt_lval(net, 0); ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t part = ivl_lval_part_off(lval); ivl_signal_t var= ivl_lval_sig(lval); ivl_type_t var_type= ivl_signal_net_type(var); ivl_type_t element_type = ivl_type_element(var_type); ivl_expr_t mux = ivl_lval_idx(lval); assert(ivl_stmt_lvals(net) == 1); assert(ivl_stmt_opcode(net) == 0); assert(part == 0); assert(ivl_type_base(var_type) == IVL_VT_QUEUE); int idx = allocate_word(); assert(idx >= 0); /* Save the queue maximum index value to an integer register. */ fprintf(vvp_out, " %%ix/load %d, %u, 0;\n", idx, ivl_signal_array_count(var)); if (ivl_expr_type(rval) == IVL_EX_NULL) { errors += draw_eval_object(rval); fprintf(vvp_out, " %%store/obj v%p_0;\n", var); } else if (mux && (ivl_type_base(element_type) == IVL_VT_REAL)) { draw_eval_real(rval); /* The %store/qdar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, idx); } else if (mux && ivl_type_base(element_type) == IVL_VT_STRING) { draw_eval_string(rval); /* The %store/qdar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, idx); } else if (mux) { // What is left must be some form of vector assert(ivl_type_base(element_type) == IVL_VT_BOOL || ivl_type_base(element_type) == IVL_VT_LOGIC); draw_eval_vec4(rval); resize_vec4_wid(rval, ivl_stmt_lwidth(net)); /* The %store/qdar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, idx, ivl_type_packed_width(element_type)); } else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) { /* There is no l-value mux, but the r-value is an array pattern. This is a special case of an assignment to the l-value. */ errors += show_stmt_assign_queue_pattern(var, rval, element_type, idx); } else { /* There is no l-value mux, so this must be an assignment to the array as a whole. Evaluate the "object", and store the evaluated result. */ errors += draw_eval_object(rval); if (ivl_type_base(element_type) == IVL_VT_REAL) fprintf(vvp_out, " %%store/qobj/r v%p_0, %d;\n", var, idx); else if (ivl_type_base(element_type) == IVL_VT_STRING) fprintf(vvp_out, " %%store/qobj/str v%p_0, %d;\n", var, idx); else { assert(ivl_type_base(element_type) == IVL_VT_BOOL || ivl_type_base(element_type) == IVL_VT_LOGIC); fprintf(vvp_out, " %%store/qobj/v v%p_0, %d, %u;\n", var, idx, ivl_type_packed_width(element_type)); } } clr_word(idx); return errors; } static int show_stmt_assign_sig_cobject(ivl_statement_t net) { int errors = 0; ivl_lval_t lval = ivl_stmt_lval(net, 0); ivl_expr_t rval = ivl_stmt_rval(net); ivl_signal_t sig= ivl_lval_sig(lval); unsigned lwid = ivl_lval_width(lval); int prop_idx = ivl_lval_property_idx(lval); if (prop_idx >= 0) { ivl_type_t sig_type = ivl_signal_net_type(sig); ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx); if (ivl_type_base(prop_type) == IVL_VT_BOOL) { assert(ivl_type_packed_dimensions(prop_type) == 0 || (ivl_type_packed_dimensions(prop_type) == 1 && ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0))); draw_eval_vec4(rval); if (ivl_expr_value(rval)!=IVL_VT_BOOL) fprintf(vvp_out, " %%cast2;\n"); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%store/prop/v %d, %u; Store in bool property %s\n", prop_idx, lwid, ivl_type_prop_name(sig_type, prop_idx)); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else if (ivl_type_base(prop_type) == IVL_VT_LOGIC) { assert(ivl_type_packed_dimensions(prop_type) == 0 || (ivl_type_packed_dimensions(prop_type) == 1 && ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0))); draw_eval_vec4(rval); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%store/prop/v %d, %u; Store in logic property %s\n", prop_idx, lwid, ivl_type_prop_name(sig_type, prop_idx)); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else if (ivl_type_base(prop_type) == IVL_VT_REAL) { /* Calculate the real value into the real value stack. The %store/prop/r will pop the stack value. */ draw_eval_real(rval); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%store/prop/r %d;\n", prop_idx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else if (ivl_type_base(prop_type) == IVL_VT_STRING) { /* Calculate the string value into the string value stack. The %store/prop/r will pop the stack value. */ draw_eval_string(rval); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%store/prop/str %d;\n", prop_idx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else if (ivl_type_base(prop_type) == IVL_VT_DARRAY) { int idx = 0; /* The property is a darray, and there is no mux expression to the assignment is of an entire array object. */ fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); errors += draw_eval_object(rval); fprintf(vvp_out, " %%store/prop/obj %d, %d; IVL_VT_DARRAY\n", prop_idx, idx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); } else if (ivl_type_base(prop_type) == IVL_VT_CLASS) { int idx = 0; ivl_expr_t idx_expr; if ( (idx_expr = ivl_lval_idx(lval)) ) { idx = allocate_word(); } /* The property is a class object. */ fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); errors += draw_eval_object(rval); if (idx_expr) draw_eval_expr_into_integer(idx_expr, idx); fprintf(vvp_out, " %%store/prop/obj %d, %d; IVL_VT_CLASS\n", prop_idx, idx); fprintf(vvp_out, " %%pop/obj 1, 0;\n"); if (idx_expr) clr_word(idx); } else { fprintf(vvp_out, " ; ERROR: ivl_type_base(prop_type) = %d\n", ivl_type_base(prop_type)); assert(0); } } else { /* There is no property select, so evaluate the r-value as an object and assign the entire object to the variable. */ errors += draw_eval_object(rval); if (ivl_signal_array_count(sig) > 1) { unsigned ix; ivl_expr_t aidx = ivl_lval_idx(lval); draw_eval_expr_into_integer(aidx, (ix = allocate_word())); fprintf(vvp_out, " %%store/obja v%p, %u;\n", sig, ix); clr_word(ix); } else { /* Not an array, so no index expression */ fprintf(vvp_out, " %%store/obj v%p_0;\n", sig); } } return errors; } int show_stmt_assign(ivl_statement_t net) { ivl_lval_t lval; ivl_signal_t sig; show_stmt_file_line(net, "Blocking assignment."); lval = ivl_stmt_lval(net, 0); sig = ivl_lval_sig(lval); if (sig && (ivl_signal_data_type(sig) == IVL_VT_REAL)) { return show_stmt_assign_sig_real(net); } if (sig && (ivl_signal_data_type(sig) == IVL_VT_STRING)) { return show_stmt_assign_sig_string(net); } if (sig && (ivl_signal_data_type(sig) == IVL_VT_DARRAY)) { return show_stmt_assign_sig_darray(net); } if (sig && (ivl_signal_data_type(sig) == IVL_VT_QUEUE)) { return show_stmt_assign_sig_queue(net); } if (sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) { return show_stmt_assign_sig_cobject(net); } return show_stmt_assign_vector(net); } iverilog-12_0/tgt-vvp/vvp-s.conf.in000066400000000000000000000001371435245347300173060ustar00rootroot00000000000000functor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle flag:DLL=vvp.tgt iverilog-12_0/tgt-vvp/vvp.c000066400000000000000000000166031435245347300157430ustar00rootroot00000000000000#define COPYRIGHT \ "Copyright (c) 2001-2021 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 "version_base.h" # include "version_tag.h" # include "vvp_priv.h" # include # include # include # include # include static const char*version_string = "Icarus Verilog VVP Code Generator " VERSION " (" VERSION_TAG ")\n\n" COPYRIGHT "\n\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; FILE*vvp_out = 0; int vvp_errors = 0; unsigned show_file_line = 0; int debug_draw = 0; /* This needs to match the actual flag count in the VVP thread. */ # define FLAGS_COUNT 512 static uint32_t allocate_flag_mask[FLAGS_COUNT / 32] = { 0x000000ff, 0 }; __inline__ static void draw_execute_header(ivl_design_t des) { const char*cp = ivl_design_flag(des, "VVP_EXECUTABLE"); if (cp) { const char *extra_args = ivl_design_flag(des, "VVP_EXTRA_ARGS"); if (!extra_args) extra_args = ""; fprintf(vvp_out, "#! %s%s\n", cp, extra_args); #if !defined(__MINGW32__) fchmod(fileno(vvp_out), 0755); #endif } fprintf(vvp_out, ":ivl_version \"" VERSION "\""); /* I am assuming that a base release will have a blank tag. */ if (*VERSION_TAG != 0) { fprintf(vvp_out, " \"(" VERSION_TAG ")\""); } fprintf(vvp_out, ";\n"); } __inline__ static void draw_module_declarations(ivl_design_t des) { const char*cp = ivl_design_flag(des, "VPI_MODULE_LIST"); while (*cp) { const char*comma = strchr(cp, ','); if (comma == 0) comma = cp + strlen(cp); char*buffer = malloc(comma - cp + 1); strncpy(buffer, cp, comma-cp); buffer[comma-cp] = 0; fprintf(vvp_out, ":vpi_module \"%s\";\n", buffer); free(buffer); cp = comma; if (*cp) cp += 1; } } int allocate_flag(void) { int idx; for (idx = 0 ; idx < FLAGS_COUNT ; idx += 1) { int word = idx / 32; uint32_t mask = 1U << (idx%32); if (allocate_flag_mask[word] & mask) continue; allocate_flag_mask[word] |= mask; return idx; } fprintf(stderr, "vvp.tgt error: Exceeded the maximum flag count of " "%d during VVP code generation.\n", FLAGS_COUNT); exit(1); } void clr_flag(int idx) { if (idx < 8) return; assert(idx < FLAGS_COUNT); int word = idx / 32; uint32_t mask = 1 << (idx%32); assert(allocate_flag_mask[word] & mask); allocate_flag_mask[word] &= ~mask; } static void process_debug_string(const char*debug_string) { const char*cp = debug_string; debug_draw = 0; while (*cp) { const char*tail = strchr(cp, ','); if (tail == 0) tail = cp + strlen(cp); size_t len = tail - cp; if (len == 4 && strncmp(cp,"draw", 4)==0) { debug_draw = 1; } while (*tail == ',') tail += 1; cp = tail; } } int target_design(ivl_design_t des) { int rc; ivl_scope_t *roots; unsigned nroots, i; unsigned size; unsigned idx; const char*path = ivl_design_flag(des, "-o"); /* Use -pfileline to determine if file and line information is * printed for procedural statements. (e.g. -pfileline=1). * The default is no file/line information will be included. */ const char*fileline = ivl_design_flag(des, "fileline"); const char*debug_flags = ivl_design_flag(des, "debug_flags"); process_debug_string(debug_flags); assert(path); /* Check to see if file/line information should be included. */ if (strcmp(fileline, "") != 0) { char *eptr; long fl_value = strtol(fileline, &eptr, 0); /* Nothing usable in the file/line string. */ if (fileline == eptr) { fprintf(stderr, "vvp.tgt error: Unable to extract file/line " "information from string: %s\n", fileline); return 1; } /* Extra stuff at the end. */ if (*eptr != 0) { fprintf(stderr, "vvp.tgt error: Extra characters '%s' " "included at end of file/line string: %s\n", eptr, fileline); return 1; } /* The file/line flag must be positive. */ if (fl_value < 0) { fprintf(stderr, "vvp.tgt error: File/line flag (%ld) must " "be positive.\n", fl_value); return 1; } show_file_line = fl_value > 0; } #ifdef HAVE_FOPEN64 vvp_out = fopen64(path, "w"); #else vvp_out = fopen(path, "w"); #endif if (vvp_out == 0) { perror(path); return -1; } vvp_errors = 0; draw_execute_header(des); fprintf(vvp_out, ":ivl_delay_selection \"%s\";\n", ivl_design_delay_sel(des)); { int pre = ivl_design_time_precision(des); char sign = '+'; if (pre < 0) { pre = -pre; sign = '-'; } fprintf(vvp_out, ":vpi_time_precision %c %d;\n", sign, pre); } draw_module_declarations(des); /* This causes all structural records to be drawn. */ ivl_design_roots(des, &roots, &nroots); for (i = 0; i < nroots; i++) draw_scope(roots[i], 0); /* Finish up any modpaths that are not yet emitted. */ cleanup_modpath(); rc = ivl_design_process(des, draw_process, 0); /* Dump the file name table. */ size = ivl_file_table_size(); fprintf(vvp_out, "# The file index is used to find the file name in " "the following table.\n:file_names %u;\n", size); for (idx = 0; idx < size; idx++) { fprintf(vvp_out, " \"%s\";\n", ivl_file_table_item(idx)); } fclose(vvp_out); EOC_cleanup_drivers(); return rc + vvp_errors; } const char* target_query(const char*key) { if (strcmp(key,"version") == 0) return version_string; return 0; } iverilog-12_0/tgt-vvp/vvp.conf.in000066400000000000000000000000601435245347300170410ustar00rootroot00000000000000functor:cprop functor:nodangle flag:DLL=vvp.tgt iverilog-12_0/tgt-vvp/vvp_config.h.in000066400000000000000000000020151435245347300176720ustar00rootroot00000000000000#ifndef IVL_vvp_config_H #define IVL_vvp_config_H /* * Copyright (c) 2004-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. */ # undef HAVE_STDINT_H # undef HAVE_INTTYPES_H # undef _LARGEFILE_SOURCE # undef _LARGEFILE64_SOURCE #endif /* IVL_vvp_config_H */ iverilog-12_0/tgt-vvp/vvp_priv.h000066400000000000000000000210731435245347300170050ustar00rootroot00000000000000#ifndef IVL_vvp_priv_H #define IVL_vvp_priv_H /* * Copyright (c) 2001-2020 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 "vvp_config.h" # include "ivl_target.h" # include extern int debug_draw; /* * The target_design entry opens the output file that receives the * compiled design, and sets the vvp_out to the descriptor. */ extern FILE* vvp_out; /* * Keep a count of errors that would render the output unusable. */ extern int vvp_errors; extern unsigned transient_id; /* * Set to non-zero when the user wants to display file and line number * information for procedural statements. */ extern unsigned show_file_line; struct vector_info { unsigned base; unsigned wid; }; /* * Convenient constants... */ /* Width limit for typical immediate arguments. */ # define IMM_WID 32 /* The number of words available in a thread. */ # define WORD_COUNT 16 /* * Mangle all non-symbol characters in an identifier, quotes in names */ extern const char *vvp_mangle_id(const char *); extern const char *vvp_mangle_name(const char *); extern char* draw_Cr_to_string(double value); /* * This generates a string from a signal that uniquely identifies * that signal with letters that can be used in a label. * * NOTE: vvp_signal_label should be removed. All it does is a %p of * the pointer, and return a pointer to a static. The code that wants * to reference a signal needs to use the format V_%p, so the presence * of this function is just plain inconsistent. */ extern const char* vvp_signal_label(ivl_signal_t sig); extern unsigned width_of_nexus(ivl_nexus_t nex); extern ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex); extern int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr); /* * This function draws a process (initial or always) into the output * file. It normally returns 0, but returns !0 of there is some sort * of error. */ extern int draw_process(ivl_process_t net, void*x); extern int draw_task_definition(ivl_scope_t scope); extern int draw_func_definition(ivl_scope_t scope); extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent); extern void draw_lpm_mux(ivl_lpm_t net); extern void draw_lpm_substitute(ivl_lpm_t net); extern void draw_ufunc_vec4(ivl_expr_t expr); extern void draw_ufunc_real(ivl_expr_t expr); extern void draw_ufunc_string(ivl_expr_t expr); extern void draw_ufunc_object(ivl_expr_t expr); extern char* process_octal_codes(const char*txt, unsigned wid); /* * modpath.c symbols. * * draw_modpath arranges for a .modpath record to be written out. * * cleanup_modpath() cleans up any pending .modpath records that may * have been scheduled by draw_modpath() but not yet written. * * Note: draw_modpath drive_label must be malloc'ed by the * caller. This function will free the string sometime in the future. */ extern void draw_modpath(ivl_signal_t path_sig, char*drive_label, unsigned drive_index); extern void cleanup_modpath(void); /* * This function draws the execution of a vpi_call statement, along * with the tricky handling of arguments. If this is called with a * statement handle, it will generate a %vpi_call * instruction. Otherwise, it will generate a %vpi_func instruction. */ extern void draw_vpi_task_call(ivl_statement_t net); extern void draw_vpi_func_call(ivl_expr_t expr); extern void draw_vpi_rfunc_call(ivl_expr_t expr); extern void draw_vpi_sfunc_call(ivl_expr_t expr); extern void draw_class_in_scope(ivl_type_t classtype); /* * Enumeration draw routine. */ void draw_enumeration_in_scope(ivl_enumtype_t enumtype); /* * Switches (tran) */ extern void draw_switch_in_scope(ivl_switch_t sw); /* Draw_net_input and friends uses this. */ struct vvp_nexus_data { /* draw_net_input uses this */ const char*net_input; /* draw_isnald_net_input uses these */ const char*island_input; ivl_island_t island; /* */ unsigned drivers_count; int flags; /* draw_net_in_scope uses these to identify the controlling word. */ ivl_signal_t net; unsigned net_word; }; #define VVP_NEXUS_DATA_STR 0x0001 /* * Given a nexus, draw a string that represents the functor output * that feeds the nexus. This function can be used to get the input to * a functor, event, or even a %load in cases where I have the * ivl_nexus_t object. The draw_net_input function will get the string * cached in the nexus, if there is one, or will generate a string and * cache it. */ extern const char* draw_net_input(ivl_nexus_t nex); void EOC_cleanup_drivers(void); /* * This is different from draw_net_input in that it is intended to be * used within the network of an island. This finds and prepares the * link for a nexus within the scope of the given island, instead of * the net as a whole. */ extern const char* draw_island_net_input(ivl_island_t island, ivl_nexus_t nex); /* * This function is different from draw_net_input in that it will * return a reference to a net as its first choice. This reference * will follow the net value, even if the net is assigned or * forced. The draw_net_input above will return a reference to the * *input* to the net and so will not follow direct assignments to * the net. This function will not return references to local signals, * and will in those cases resort to the net input, or a non-local * signal if one exists for the nexus. */ extern const char*draw_input_from_net(ivl_nexus_t nex); /* * This evaluates an expression and leaves the result in the numbered * integer index register. It also will set bit-4 to 1 if the value is * not fully defined (i.e. contains x or z). */ extern void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix); /* * This evaluates an expression as a condition flag and leaves the * result in a flag that is returned. This result may be used as an * operand for conditional jump instructions. */ extern int draw_eval_condition(ivl_expr_t expr); /* * Return true if the signal is the return value of a function. */ extern int signal_is_return_value(ivl_signal_t sig); extern int number_is_unknown(ivl_expr_t ex); extern int number_is_immediate(ivl_expr_t ex, unsigned lim_wid, int negative_is_ok); extern long get_number_immediate(ivl_expr_t ex); extern uint64_t get_number_immediate64(ivl_expr_t ex); /* * draw_eval_vec4 evaluates vec4 expressions. The result of the * evaluation is the vec4 result in the top of the vec4 expression stack. */ extern void draw_eval_vec4(ivl_expr_t ex); extern void resize_vec4_wid(ivl_expr_t expr, unsigned wid); /* * draw_eval_real evaluates real value expressions. The result of the * evaluation is the real result in the top of the real expression stack. */ extern void draw_eval_real(ivl_expr_t ex); /* * The draw_eval_string function evaluates the expression as a string, * and pushes the string onto the string stack. */ extern void draw_eval_string(ivl_expr_t ex); /* * The draw_eval_string function evaluates the expression as an object, * and pushes the object onto the object stack. */ extern int draw_eval_object(ivl_expr_t ex); extern int show_stmt_assign(ivl_statement_t net); extern void show_stmt_file_line(ivl_statement_t net, const char*desc); /* */ extern int test_immediate_vec4_ok(ivl_expr_t expr); extern void draw_immediate_vec4(ivl_expr_t expr, const char*opcode); /* * Draw a delay statement. */ extern void draw_delay(void*ptr, unsigned wid, const char*input, ivl_expr_t rise_exp, ivl_expr_t fall_exp, ivl_expr_t decay_exp); /* * These functions manage word register allocation. */ extern int allocate_word(void); extern void clr_word(int idx); /* * These functions manage flag bit allocation. */ extern int allocate_flag(void); extern void clr_flag(int idx); /* * These are used to count labels as I generate code. */ extern unsigned local_count; extern unsigned thread_count; extern void darray_new(ivl_type_t element_type, unsigned size_reg); #endif /* IVL_vvp_priv_H */ iverilog-12_0/tgt-vvp/vvp_process.c000066400000000000000000002346711435245347300175100ustar00rootroot00000000000000/* * Copyright (c) 2001-2021 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 "vvp_priv.h" # include # include # include # include static int show_statement(ivl_statement_t net, ivl_scope_t sscope); unsigned local_count = 0; unsigned thread_count = 0; unsigned transient_id = 0; /* * This file includes the code needed to generate VVP code for * processes. Scopes are already declared, we generate here the * executable code for the processes. */ /* Support a non-blocking assignment to a real array word. The real value to be written is already in the top of the stack. */ static void assign_to_array_r_word(ivl_signal_t lsig, ivl_expr_t word_ix, uint64_t delay, ivl_expr_t dexp, unsigned nevents) { unsigned end_assign = transient_id++; int word_ix_reg = 3; /* if we have to evaluate a delay expression, evaluate word index into temp register */ if (dexp != 0) { word_ix_reg = allocate_word(); } /* This code is common to all the different types of array delays. */ if (number_is_immediate(word_ix, IMM_WID, 0) && !number_is_unknown(word_ix)) { fprintf(vvp_out, " %%ix/load %d, %ld, 0; address\n", word_ix_reg, get_number_immediate(word_ix)); } else { /* Calculate array word index into index register 3 */ draw_eval_expr_into_integer(word_ix, word_ix_reg); /* Skip assignment if word expression is not defined. */ unsigned do_assign = transient_id++; fprintf(vvp_out, " %%jmp/0 t_%u, 4;\n", do_assign); fprintf(vvp_out, " %%pop/real 1;\n"); fprintf(vvp_out, " %%jmp t_%u;\n", end_assign); fprintf(vvp_out, "t_%u ;\n", do_assign); } if (dexp != 0) { /* Calculated delay... */ int delay_index = allocate_word(); draw_eval_expr_into_integer(dexp, delay_index); fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg); fprintf(vvp_out, " %%assign/ar/d v%p, %d;\n", lsig, delay_index); clr_word(word_ix_reg); clr_word(delay_index); } else if (nevents != 0) { /* Event control delay... */ fprintf(vvp_out, " %%assign/ar/e v%p;\n", lsig); } else { /* Constant delay... */ unsigned long low_d = delay % UINT64_C(0x100000000); unsigned long hig_d = delay / UINT64_C(0x100000000); /* * The %assign can only take a 32 bit delay. For a larger * delay we need to put it into an index register. */ if (hig_d != 0) { int delay_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n", delay_index, low_d, hig_d); fprintf(vvp_out, " %%assign/ar/d v%p, %d;\n", lsig, delay_index); clr_word(delay_index); } else { fprintf(vvp_out, " %%assign/ar v%p, %lu;\n", lsig, low_d); } } fprintf(vvp_out, "t_%u ;\n", end_assign); if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n"); } static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, uint64_t delay, ivl_expr_t dexp, ivl_expr_t part_off_ex, unsigned nevents) { int word_ix_reg = 3; int part_off_reg = 0; int delay_index; unsigned long part_off = 0; int error_flag = allocate_flag(); /* Figure the constant part offset, if possible. If we can do so, then forget about the expression and use the calculated value. After this block, if the part_off_ex!=0, then the part offset is used, otherwise, use part_off. */ if (part_off_ex == 0) { part_off = 0; } else if (number_is_immediate(part_off_ex, IMM_WID, 0) && !number_is_unknown(part_off_ex)) { part_off = get_number_immediate(part_off_ex); part_off_ex = 0; } if (dexp != 0) { word_ix_reg = allocate_word(); } else if (part_off_ex) { word_ix_reg = allocate_word(); } /* Calculate array word index into word index register */ draw_eval_expr_into_integer(word_ix, word_ix_reg); if (part_off_ex) { part_off_reg = allocate_word(); /* Save the index calculation error flag to a global. */ fprintf(vvp_out, " %%flag_mov %d, 4;\n", error_flag); draw_eval_expr_into_integer(part_off_ex, part_off_reg); /* Add the error state of the part select to the global. */ fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag); } else if (part_off != 0) { /* Store word part select into part_off_reg */ part_off_reg = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, 0; part off\n", part_off_reg, part_off); } /* Calculated delay... */ if (dexp != 0) { delay_index = allocate_word(); /* If needed save the index calculation error flag. */ if (! part_off_ex) { fprintf(vvp_out, " %%flag_mov %d, 4;\n", error_flag); } draw_eval_expr_into_integer(dexp, delay_index); if (word_ix_reg != 3) { fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg); clr_word(word_ix_reg); } /* Restore the error state since an undefined delay is okay. */ fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag); fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %d;\n", lsig, part_off_reg, delay_index); clr_word(delay_index); /* Event control delay... */ } else if (nevents != 0) { /* If needed use the global error state. */ if (part_off_ex) { fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag); fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg); clr_word(word_ix_reg); } fprintf(vvp_out, " %%assign/vec4/a/e v%p, %d;\n", lsig, part_off_reg); /* Constant delay... */ } else { unsigned long low_d = delay % UINT64_C(0x100000000); unsigned long hig_d = delay / UINT64_C(0x100000000); delay_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, %lu; Constant delay\n", delay_index, low_d, hig_d); if (word_ix_reg != 3) { fprintf(vvp_out, " %%ix/mov 3, %d;\n", word_ix_reg); clr_word(word_ix_reg); } /* If needed use the global error state. */ if (part_off_ex) { fprintf(vvp_out, " %%flag_mov 4, %d;\n", error_flag); } fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %d;\n", lsig, part_off_reg, delay_index); clr_word(delay_index); } clr_flag(error_flag); if (part_off_reg) clr_word(part_off_reg); } /* * The code to generate here assumes that a vec4 vector of the right * width is top of the vec4 stack. Arrange for it to be popped and * assigned to the given l-value. */ static void assign_to_lvector(ivl_lval_t lval, uint64_t delay, ivl_expr_t dexp, unsigned nevents) { ivl_signal_t sig = ivl_lval_sig(lval); ivl_expr_t part_off_ex = ivl_lval_part_off(lval); unsigned long part_off = 0; const unsigned long use_word = 0; const char*assign_op = "%assign"; if (ivl_signal_type(sig) == IVL_SIT_UWIRE) assign_op = "%force"; // Detect the case that this is actually a non-blocking assign // to an array word. In that case, run off somewhere else to // deal with it. if (ivl_signal_dimensions(sig) > 0) { ivl_expr_t word_ix = ivl_lval_idx(lval); assert(word_ix); assign_to_array_word(sig, word_ix, delay, dexp, part_off_ex, nevents); return; } if (part_off_ex == 0) { part_off = 0; } else if (number_is_immediate(part_off_ex, IMM_WID, 0) && !number_is_unknown(part_off_ex)) { part_off = get_number_immediate(part_off_ex); part_off_ex = 0; } unsigned long low_d = delay % UINT64_C(0x100000000); unsigned long hig_d = delay / UINT64_C(0x100000000); if (part_off_ex) { // The part select offset is calculated (not constant) // so in these cases we'll need to use // %assign/vec4/off/... variants. if (dexp != 0) { /* Calculated offset... */ int offset_index = allocate_word(); /* Calculated delay... */ int delay_index = allocate_word(); draw_eval_expr_into_integer(dexp, delay_index); /* Calculated part offset. This will leave flag bit 4 set to 1 if the copy into the index detected xz values. The %assign will use that to know to skip the assign. */ draw_eval_expr_into_integer(part_off_ex, offset_index); /* If the index expression has XZ bits, skip the assign. */ fprintf(vvp_out, " %s/vec4/off/d v%p_%lu, %d, %d;\n", assign_op, sig, use_word, offset_index, delay_index); clr_word(offset_index); clr_word(delay_index); } else if (nevents != 0) { int offset_index = allocate_word(); /* Event control delay... */ draw_eval_expr_into_integer(part_off_ex, offset_index); fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n", assign_op, sig, use_word, offset_index); clr_word(offset_index); } else { int offset_index = allocate_word(); int delay_index = allocate_word(); /* Constant delay... */ fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n", delay_index, low_d, hig_d); /* Calculated part offset. This will leave flag bit 4 set to 1 if the copy into the index detected xz values. The %assign will use that to know to skip the assign. */ draw_eval_expr_into_integer(part_off_ex, offset_index); /* If the index expression has XZ bits, skip the assign. */ fprintf(vvp_out, " %s/vec4/off/d v%p_%lu, %d, %d;\n", assign_op, sig, use_word, offset_index, delay_index); clr_word(offset_index); clr_word(delay_index); } } else if (part_off>0 || ivl_lval_width(lval)!=ivl_signal_width(sig)) { if (nevents != 0) { assert(dexp==0); int offset_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", offset_index, part_off); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); fprintf(vvp_out, " %s/vec4/off/e v%p_%lu, %d;\n", assign_op, sig, use_word, offset_index); clr_word(offset_index); } else { // Constant part offset, non-constant (calculated) // assignment delay. Use the %assign/vec4/off/d // instruction to handle this case. int offset_index = allocate_word(); int delay_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", offset_index, part_off); if (dexp) { draw_eval_expr_into_integer(dexp,delay_index); } else { fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n", delay_index, low_d, hig_d); fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); } fprintf(vvp_out, " %s/vec4/off/d v%p_%lu, %d, %d;\n", assign_op, sig, use_word, offset_index, delay_index); clr_word(offset_index); clr_word(delay_index); } } else if (dexp != 0) { /* Calculated delay... */ int delay_index = allocate_word(); draw_eval_expr_into_integer(dexp, delay_index); fprintf(vvp_out, " %s/vec4/d v%p_%lu, %d;\n", assign_op, sig, use_word, delay_index); clr_word(delay_index); } else if (nevents != 0) { /* Event control delay... */ fprintf(vvp_out, " %s/vec4/e v%p_%lu;\n", assign_op, sig, use_word); } else { /* * The %assign can only take a 32 bit delay. For a larger * delay we need to put it into an index register. */ if (hig_d != 0) { int delay_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n", delay_index, low_d, hig_d); fprintf(vvp_out, " %s/vec4/d v%p_%lu, %d;\n", assign_op, sig, use_word, delay_index); clr_word(delay_index); } else { fprintf(vvp_out, " %s/vec4 v%p_%lu, %lu;\n", assign_op, sig, use_word, low_d); } } } /* * Routine to insert statement tracing information into the output stream * when requested by the user (compiler). */ void show_stmt_file_line(ivl_statement_t net, const char* desc) { if (show_file_line) { /* If the line number is not zero then the file should also * be set. It's safe to skip the assert during debug, but * the assert represents missing file/line information that * should be reported/fixed. */ unsigned lineno = ivl_stmt_lineno(net); assert(lineno); fprintf(vvp_out, " %%file_line %u %u \"%s\";\n", ivl_file_table_index(ivl_stmt_file(net)), lineno, desc); } } static int show_stmt_alloc(ivl_statement_t net) { ivl_scope_t scope = ivl_stmt_call(net); fprintf(vvp_out, " %%alloc S_%p;\n", scope); return 0; } /* * This function handles the case of non-blocking assign to word * variables such as real, i.e: * * real foo; * foo <= 1.0; * * In this case we know (by Verilog syntax) that there is only exactly * 1 l-value, the target identifier, so it should be relatively easy. */ static int show_stmt_assign_nb_real(ivl_statement_t net) { ivl_lval_t lval; ivl_signal_t sig; ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t del = ivl_stmt_delay_expr(net); /* variables for the selection of word from an array. */ unsigned long use_word = 0; uint64_t delay = 0; unsigned nevents = ivl_stmt_nevent(net); /* Must be exactly 1 l-value. */ assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); sig = ivl_lval_sig(lval); assert(sig); if (del && (ivl_expr_type(del) == IVL_EX_DELAY)) { assert(number_is_immediate(del, 64, 0)); delay = ivl_expr_delay_val(del); del = 0; } /* Evaluate the r-value */ draw_eval_real(rval); if (ivl_signal_dimensions(sig) > 0) { ivl_expr_t word_ix = ivl_lval_idx(lval); assert(word_ix); assign_to_array_r_word(sig, word_ix, delay, del, nevents); return 0; } /* We need to calculate the delay expression. */ if (del) { assert(nevents == 0); int delay_index = allocate_word(); draw_eval_expr_into_integer(del, delay_index); fprintf(vvp_out, " %%assign/wr/d v%p_%lu, %d;\n", sig, use_word, delay_index); clr_word(delay_index); } else if (nevents) { fprintf(vvp_out, " %%assign/wr/e v%p_%lu;\n", sig, use_word); } else { unsigned long low_d = delay % UINT64_C(0x100000000); unsigned long hig_d = delay / UINT64_C(0x100000000); /* * The %assign can only take a 32 bit delay. For a larger * delay we need to put it into an index register. */ if (hig_d != 0) { int delay_index = allocate_word(); fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n", delay_index, low_d, hig_d); fprintf(vvp_out, " %%assign/wr/d v%p_%lu, %d;\n", sig, use_word, delay_index); clr_word(delay_index); } else { fprintf(vvp_out, " %%assign/wr v%p_%lu, %lu;\n", sig, use_word, low_d); } } return 0; } static int show_stmt_assign_nb(ivl_statement_t net) { ivl_lval_t lval; ivl_expr_t rval = ivl_stmt_rval(net); ivl_expr_t del = ivl_stmt_delay_expr(net); ivl_signal_t sig; unsigned nevents = ivl_stmt_nevent(net); show_stmt_file_line(net, "Nonblocking assignment."); /* If we have an event control build the control structure. */ if (nevents) { assert(del == 0); ivl_expr_t cnt = ivl_stmt_cond_expr(net); unsigned long count = 1; if (cnt && (ivl_expr_type(cnt) == IVL_EX_ULONG)) { assert(number_is_immediate(cnt, IMM_WID, 0)); count = ivl_expr_uvalue(cnt); cnt = 0; } char name[256]; if (nevents == 1) { ivl_event_t ev = ivl_stmt_events(net, 0); snprintf(name, sizeof(name), "E_%p", ev); } else { unsigned idx; static unsigned int cascade_counter = 0; ivl_event_t ev = ivl_stmt_events(net, 0); fprintf(vvp_out, "Eassign_%u .event/or E_%p", cascade_counter, ev); for (idx = 1; idx < nevents; idx += 1) { ev = ivl_stmt_events(net, idx); fprintf(vvp_out, ", E_%p", ev); } fprintf(vvp_out, ";\n"); snprintf(name, sizeof(name), "Eassign_%u", cascade_counter); cascade_counter += 1; } if (cnt) { int count_index = allocate_word(); const char*type = ivl_expr_signed(cnt) ? "/s" : ""; draw_eval_expr_into_integer(cnt, count_index); fprintf(vvp_out, " %%evctl%s %s, %d;\n", type, name, count_index); clr_word(count_index); } else { fprintf(vvp_out, " %%evctl/i %s, %lu;\n", name, count); } } else { assert(ivl_stmt_cond_expr(net) == 0); } uint64_t delay = 0; /* Detect special cases that are handled elsewhere. */ lval = ivl_stmt_lval(net,0); if ((sig = ivl_lval_sig(lval))) { switch (ivl_signal_data_type(sig)) { case IVL_VT_REAL: return show_stmt_assign_nb_real(net); default: break; } } if (del && (ivl_expr_type(del) == IVL_EX_DELAY)) { assert(number_is_immediate(del, 64, 0)); delay = ivl_expr_delay_val(del); del = 0; } { unsigned wid; unsigned lidx; unsigned cur_rbit = 0; /* Handle the special case that the expression is a real value. Evaluate the real expression, then convert the result to a vector. */ if (ivl_expr_value(rval) == IVL_VT_REAL) { draw_eval_real(rval); /* This is the accumulated with of the l-value of the assignment. */ wid = ivl_stmt_lwidth(net); fprintf(vvp_out, " %%cvt/vr %u;\n", wid); } else { wid = ivl_stmt_lwidth(net); draw_eval_vec4(rval); if (ivl_expr_width(rval) != wid) { if (ivl_expr_signed(rval)) fprintf(vvp_out, " %%pad/s %u;\n", wid); else fprintf(vvp_out, " %%pad/u %u;\n", wid); } } /* Spread the r-value vector over the bits of the l-value. */ for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { unsigned bit_limit = wid - cur_rbit; lval = ivl_stmt_lval(net, lidx); if (bit_limit > ivl_lval_width(lval)) bit_limit = ivl_lval_width(lval); /* If there are more lvals after this, split off from the top of the vec4 stack only the bits (lsb) that we need for the current lval. */ if (lidx+1 < ivl_stmt_lvals(net)) fprintf(vvp_out, " %%split/vec4 %u;\n", bit_limit); assign_to_lvector(lval, delay, del, nevents); cur_rbit += bit_limit; } } if (nevents) fprintf(vvp_out, " %%evctl/c;\n"); return 0; } static int show_stmt_block(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; unsigned idx; unsigned cnt = ivl_stmt_block_count(net); for (idx = 0 ; idx < cnt ; idx += 1) { rc += show_statement(ivl_stmt_block_stmt(net, idx), sscope); } return rc; } /* * This draws an invocation of a named block. This is a little * different because a subscope is created. We do that by creating * a thread to deal with this. */ static int show_stmt_block_named(ivl_statement_t net, ivl_scope_t scope) { int rc; unsigned out_id, sub_id; ivl_scope_t subscope = ivl_stmt_block_scope(net); out_id = transient_id++; sub_id = transient_id++; fprintf(vvp_out, " %%fork t_%u, S_%p;\n", sub_id, subscope); fprintf(vvp_out, " %%jmp t_%u;\n", out_id); /* Change the compiling scope to be the named blocks scope. */ fprintf(vvp_out, " .scope S_%p;\n", subscope); fprintf(vvp_out, "t_%u ;\n", sub_id); rc = show_stmt_block(net, subscope); fprintf(vvp_out, " %%end;\n"); /* Return to the previous scope. */ fprintf(vvp_out, " .scope S_%p;\n", scope); fprintf(vvp_out, "t_%u %%join;\n", out_id); return rc; } static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; ivl_case_quality_t qual = ivl_stmt_case_quality(net); ivl_expr_t expr = ivl_stmt_cond_expr(net); unsigned count = ivl_stmt_case_count(net); unsigned local_base = local_count; unsigned idx, default_case; if (qual != IVL_CASE_QUALITY_BASIC && qual != IVL_CASE_QUALITY_PRIORITY) { fprintf(stderr, "%s:%u: vvp.tgt sorry: " "Case unique/unique0 qualities are ignored.\n", ivl_stmt_file(net), ivl_stmt_lineno(net)); } show_stmt_file_line(net, "Case statement."); local_count += count + 1; /* Evaluate the case condition to the top of the vec4 stack. This expression will be compared multiple times to each case guard. */ draw_eval_vec4(expr); /* First draw the branch table. All the non-default cases generate a branch out of here, to the code that implements the case. The default will fall through all the tests. */ default_case = count; for (idx = 0 ; idx < count ; idx += 1) { ivl_expr_t cex = ivl_stmt_case_expr(net, idx); if (cex == 0) { default_case = idx; continue; } /* Duplicate the case expression so that the cmp instructions below do not completely erase the value. Do this in front of each compare. */ fprintf(vvp_out, " %%dup/vec4;\n"); draw_eval_vec4(cex); switch (ivl_statement_type(net)) { case IVL_ST_CASE: fprintf(vvp_out, " %%cmp/u;\n"); fprintf(vvp_out, " %%jmp/1 T_%u.%u, 6;\n", thread_count, local_base+idx); break; case IVL_ST_CASEX: fprintf(vvp_out, " %%cmp/x;\n"); fprintf(vvp_out, " %%jmp/1 T_%u.%u, 4;\n", thread_count, local_base+idx); break; case IVL_ST_CASEZ: fprintf(vvp_out, " %%cmp/z;\n"); fprintf(vvp_out, " %%jmp/1 T_%u.%u, 4;\n", thread_count, local_base+idx); break; default: assert(0); } } /* Emit code for the default case. */ if (default_case < count) { ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case); rc += show_statement(cst, sscope); } /* Emit code to check unique and priority have handled a value (when there is no default). */ else if (default_case == count) { switch (qual) { case IVL_CASE_QUALITY_UNIQUE: case IVL_CASE_QUALITY_PRIORITY: fprintf(vvp_out, " %%vpi_call/w %u %u \"$warning\", " "\"value is unhandled for priority or unique case statement\"" " {0 0 0};\n", ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net)); break; default: break; } } /* Jump to the out of the case. */ fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, local_base+count); for (idx = 0 ; idx < count ; idx += 1) { ivl_statement_t cst = ivl_stmt_case_stmt(net, idx); if (idx == default_case) continue; fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+idx); rc += show_statement(cst, sscope); /* Statement is done, jump to the out of the case. */ fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, local_base+count); } /* The out of the case. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+count); /* The case tests will leave the case expression on the top of the stack, but we are done with it now. Pop it. */ fprintf(vvp_out, " %%pop/vec4 1;\n"); return rc; } static int show_stmt_case_r(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; ivl_expr_t expr = ivl_stmt_cond_expr(net); unsigned count = ivl_stmt_case_count(net); unsigned local_base = local_count; unsigned idx, default_case; show_stmt_file_line(net, "Case statement."); /* Build the reference value into the top of the stack. All the case comparisons will make duplicates of this value in order to do their tests. */ draw_eval_real(expr); local_count += count + 1; /* First draw the branch table. All the non-default cases generate a branch out of here, to the code that implements the case. The default will fall through all the tests. */ default_case = count; for (idx = 0 ; idx < count ; idx += 1) { ivl_expr_t cex = ivl_stmt_case_expr(net, idx); if (cex == 0) { default_case = idx; continue; } /* The reference value... */ fprintf(vvp_out, " %%dup/real;\n"); /* The guard value... */ draw_eval_real(cex); /* The comparison. */ fprintf(vvp_out, " %%cmp/wr;\n"); fprintf(vvp_out, " %%jmp/1 T_%u.%u, 4;\n", thread_count, local_base+idx); } /* Emit code for the case default. The above jump table will fall through to this statement. */ if (default_case < count) { ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case); rc += show_statement(cst, sscope); } /* Jump to the out of the case. */ fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, local_base+count); for (idx = 0 ; idx < count ; idx += 1) { ivl_statement_t cst = ivl_stmt_case_stmt(net, idx); if (idx == default_case) continue; fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+idx); rc += show_statement(cst, sscope); fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, local_base+count); } /* The out of the case. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_base+count); fprintf(vvp_out, " %%pop/real 1;\n"); return rc; } /* * The real value is already pushed to the top of the real value stack. */ static void force_real_to_lval(ivl_statement_t net) { const char*command_name; ivl_lval_t lval; ivl_signal_t lsig; switch (ivl_statement_type(net)) { case IVL_ST_CASSIGN: command_name = "%cassign/wr"; break; case IVL_ST_FORCE: command_name = "%force/wr"; break; default: command_name = "ERROR"; assert(0); break; } assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); lsig = ivl_lval_sig(lval); assert(ivl_lval_width(lval) == 1); assert(ivl_lval_part_off(lval) == 0); ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(word_idx)) { fprintf(vvp_out, " %%pop/real 1;\n"); return; } use_word = get_number_immediate(word_idx); /* We do not currently support using a word from a variable array as the L-value (SystemVerilog / Icarus extension). */ if (ivl_signal_type(lsig) == IVL_SIT_REG) { fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s to the " "word of a variable array (%s[%ld]).\n", ivl_stmt_file(net), ivl_stmt_lineno(net), command_name, ivl_signal_basename(lsig), ivl_signal_array_base(lsig) + (long)use_word); vvp_errors += 1; } } /* L-Value must be a signal: reg or wire */ assert(lsig != 0); fprintf(vvp_out, " %s v%p_%lu;\n", command_name, lsig, use_word); } static void force_vector_to_lval(ivl_statement_t net) { unsigned lidx; const char*command_name; switch (ivl_statement_type(net)) { case IVL_ST_CASSIGN: command_name = "%cassign/vec4"; break; case IVL_ST_FORCE: command_name = "%force/vec4"; break; default: command_name = "ERROR"; assert(0); break; } for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { ivl_lval_t lval = ivl_stmt_lval(net, lidx); ivl_signal_t lsig = ivl_lval_sig(lval); ivl_expr_t part_off_ex = ivl_lval_part_off(lval); ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(word_idx)) { fprintf(vvp_out, " %%pop/vec4 1; force to out of bounds index suppressed.\n"); return; } use_word = get_number_immediate(word_idx); /* We do not currently support using a word from a variable array as the L-value (SystemVerilog / Icarus extension). */ if (ivl_signal_type(lsig) == IVL_SIT_REG) { fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s to the " "word of a variable array (%s[%ld]).\n", ivl_stmt_file(net), ivl_stmt_lineno(net), command_name, ivl_signal_basename(lsig), ivl_signal_array_base(lsig) + (long)use_word); vvp_errors += 1; } } if (lidx+1 < ivl_stmt_lvals(net)) fprintf(vvp_out, " %%split/vec4 %u;\n", ivl_lval_width(lval)); /* L-Value must be a signal: reg or wire */ assert(lsig != 0); /* Do not support bit or part selects of l-values yet. */ if (part_off_ex) { int off_index = allocate_word(); draw_eval_expr_into_integer(part_off_ex, off_index); fprintf(vvp_out, " %s/off v%p_%lu, %d;\n", command_name, lsig, use_word, off_index); clr_word(off_index); } else { assert(ivl_lval_width(lval) == ivl_signal_width(lsig)); assert(!ivl_lval_part_off(lval)); fprintf(vvp_out, " %s v%p_%lu;\n", command_name, lsig, use_word); } } } static void force_link_rval(ivl_statement_t net, ivl_expr_t rval) { ivl_signal_t rsig; ivl_lval_t lval; ivl_signal_t lsig; const char*command_name; ivl_expr_t part_off_ex; ivl_expr_t lword_idx, rword_idx; unsigned long use_lword = 0, use_rword = 0; if (ivl_expr_type(rval) != IVL_EX_SIGNAL) { if (ivl_expr_type(rval) == IVL_EX_NUMBER || ivl_expr_type(rval) == IVL_EX_REALNUM) return; fprintf(stderr, "%s:%u: vvp.tgt sorry: procedural continuous " "assignments are not yet fully supported. The RHS of " "this assignment will only be evaluated once, at the " "time the assignment statement is executed.\n", ivl_stmt_file(net), ivl_stmt_lineno(net)); return; } switch (ivl_statement_type(net)) { case IVL_ST_CASSIGN: command_name = "%cassign"; break; case IVL_ST_FORCE: command_name = "%force"; break; default: command_name = "ERROR"; assert(0); break; } rsig = ivl_expr_signal(rval); assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); lsig = ivl_lval_sig(lval); /* We do not currently support driving a signal to a bit or * part select (this could give us multiple drivers). */ part_off_ex = ivl_lval_part_off(lval); /* This should be verified in force_vector_to_lval() which is called * before this procedure. */ if (part_off_ex) { assert(number_is_immediate(part_off_ex, IMM_WID, 0)); assert(! number_is_unknown(part_off_ex)); } if (ivl_signal_width(lsig) > ivl_signal_width(rsig) || (part_off_ex && get_number_immediate(part_off_ex) != 0)) { /* Normalize the bit/part select. This also needs to be * reworked to support packed arrays. */ long real_msb = ivl_signal_packed_msb(lsig, 0); long real_lsb = ivl_signal_packed_lsb(lsig, 0); long use_wid = ivl_signal_width(rsig); long use_lsb, use_msb; if (ivl_signal_packed_dimensions(lsig) > 1) { fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s part of a " "packed array.\n", ivl_stmt_file(net), ivl_stmt_lineno(net), command_name); } if (real_msb >= real_lsb) { use_lsb = get_number_immediate(part_off_ex); use_lsb += real_lsb; use_msb = use_lsb + use_wid - 1; } else { use_lsb = real_lsb; use_lsb -= get_number_immediate(part_off_ex); use_msb = use_lsb; use_msb -= use_wid - 1; } fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s signal to a ", ivl_stmt_file(net), ivl_stmt_lineno(net), command_name); if (use_wid > 1) { fprintf(stderr, "part select (%s[%ld:%ld]).\n", ivl_signal_basename(lsig), use_msb, use_lsb); } else { fprintf(stderr, "bit select (%s[%ld]).\n", ivl_signal_basename(lsig), use_lsb); } vvp_errors += 1; } /* At least for now, only handle force to fixed words of an array. */ if ((lword_idx = ivl_lval_idx(lval)) != 0) { assert(number_is_immediate(lword_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(lword_idx)) return; use_lword = get_number_immediate(lword_idx); /* We do not currently support using a word from a variable * array as the L-value (SystemVerilog / Icarus extension). */ if (ivl_signal_type(lsig) == IVL_SIT_REG) { /* Normalize the array access. */ long real_word = use_lword; real_word += ivl_signal_array_base(lsig); fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s to the " "word of a variable array (%s[%ld]).\n", ivl_stmt_file(net), ivl_stmt_lineno(net), command_name, ivl_signal_basename(lsig), real_word); vvp_errors += 1; } } if ((rword_idx = ivl_expr_oper1(rval)) != 0) { assert(ivl_signal_dimensions(rsig) != 0); if (!number_is_immediate(rword_idx, IMM_WID, 0)) { fprintf(stderr, "%s:%u: vvp.tgt sorry: procedural continuous " "assignments are not yet fully supported. The RHS of " "this assignment will only be evaluated once, at the " "time the assignment statement is executed.\n", ivl_stmt_file(net), ivl_stmt_lineno(net)); return; } /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(rword_idx)) return; use_rword = get_number_immediate(rword_idx); /* We do not currently support using a word from a variable * array as the R-value. */ if (ivl_signal_type(rsig) == IVL_SIT_REG) { /* Normalize the array access. */ long real_word = use_rword; real_word += ivl_signal_array_base(rsig); fprintf(stderr, "%s:%u: vvp.tgt sorry: cannot %s from the " "word of a variable array (%s[%ld]).\n", ivl_expr_file(rval), ivl_expr_lineno(rval), command_name, ivl_signal_basename(rsig), real_word); vvp_errors += 1; } } else { assert(ivl_signal_dimensions(rsig) == 0); use_rword = 0; } fprintf(vvp_out, " %s/link", command_name); fprintf(vvp_out, " v%p_%lu", lsig, use_lword); fprintf(vvp_out, ", v%p_%lu;\n", rsig, use_rword); } static int show_stmt_cassign(ivl_statement_t net) { ivl_expr_t rval; ivl_signal_t sig; show_stmt_file_line(net, "Assign statement."); rval = ivl_stmt_rval(net); assert(rval); sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { draw_eval_real(ivl_stmt_rval(net)); force_real_to_lval(net); } else { draw_eval_vec4(rval); resize_vec4_wid(rval, ivl_stmt_lwidth(net)); /* Write out initial continuous assign instructions to assign the expression value to the l-value. */ force_vector_to_lval(net); } force_link_rval(net, rval); return 0; } /* * Handle the deassign similar to cassign. The lvals must all be * vectors without bit or part selects. Simply call %deassign for all * the values. */ static int show_stmt_deassign(ivl_statement_t net) { ivl_signal_t sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); unsigned lidx; show_stmt_file_line(net, "Deassign statement."); if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { ivl_lval_t lval; assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); assert(ivl_lval_width(lval) == 1); assert(ivl_lval_part_off(lval) == 0); ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the deassignment in this case. */ if (number_is_unknown(word_idx)) return 0; use_word = get_number_immediate(word_idx); } fprintf(vvp_out, " %%deassign/wr v%p_%lu;\n", sig, use_word); return 0; } for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { ivl_lval_t lval = ivl_stmt_lval(net, lidx); ivl_signal_t lsig = ivl_lval_sig(lval); ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; unsigned use_wid; ivl_expr_t part_off_ex; unsigned part_off; assert(lsig != 0); use_wid = ivl_lval_width(lval); part_off_ex = ivl_lval_part_off(lval); part_off = 0; if (part_off_ex != 0) { assert(number_is_immediate(part_off_ex, 64, 0)); if (number_is_unknown(part_off_ex)) return 0; part_off = get_number_immediate(part_off_ex); } if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the deassignment in this case. */ if (number_is_unknown(word_idx)) return 0; use_word = get_number_immediate(word_idx); } fprintf(vvp_out, " %%deassign v%p_%lu, %u, %u;\n", lsig, use_word, part_off, use_wid); } return 0; } static int show_stmt_condit(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; unsigned lab_false, lab_out; ivl_expr_t expr = ivl_stmt_cond_expr(net); show_stmt_file_line(net, "If statement."); lab_false = local_count++; lab_out = local_count++; int use_flag = draw_eval_condition(expr); fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n", thread_count, lab_false, use_flag); clr_flag(use_flag); if (ivl_stmt_cond_true(net)) rc += show_statement(ivl_stmt_cond_true(net), sscope); if (ivl_stmt_cond_false(net)) { fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, lab_out); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_false); rc += show_statement(ivl_stmt_cond_false(net), sscope); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_out); } else { fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_false); } return rc; } /* * The delay statement is easy. Simply write a ``%delay '' * instruction to delay the thread, then draw the included statement. * The delay statement comes from Verilog code like this: * * ... * # ; */ static int show_stmt_delay(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; uint64_t delay = ivl_stmt_delay_val(net); ivl_statement_t stmt = ivl_stmt_sub_stmt(net); unsigned long low = delay % UINT64_C(0x100000000); unsigned long hig = delay / UINT64_C(0x100000000); show_stmt_file_line(net, "Delay statement."); fprintf(vvp_out, " %%delay %lu, %lu;\n", low, hig); rc += show_statement(stmt, sscope); return rc; } static void draw_expr_into_idx(ivl_expr_t expr, int use_idx) { switch (ivl_expr_value(expr)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: { draw_eval_vec4(expr); fprintf(vvp_out, " %%ix/vec4 %d;\n", use_idx); break; } case IVL_VT_REAL: { draw_eval_real(expr); fprintf(vvp_out, " %%cvt/ur %d;\n", use_idx); break; } default: assert(0); } } /* * The delayx statement is slightly more complex in that it is * necessary to calculate the delay first. Load the calculated delay * into and index register and use the %delayx instruction to do the * actual delay. */ static int show_stmt_delayx(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; ivl_expr_t expr = ivl_stmt_delay_expr(net); ivl_statement_t stmt = ivl_stmt_sub_stmt(net); show_stmt_file_line(net, "Delay statement."); int use_idx = allocate_word(); draw_expr_into_idx(expr, use_idx); fprintf(vvp_out, " %%delayx %d;\n", use_idx); clr_word(use_idx); rc += show_statement(stmt, sscope); return rc; } static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; ivl_scope_t target = ivl_stmt_call(net); (void)sscope; /* Parameter is not used. */ /* A normal disable statement. */ if (target) { if (ivl_stmt_flow_control(net)) { show_stmt_file_line(net, "Flow control disable statement."); fprintf(vvp_out, " %%disable/flow S_%p;\n", target); } else { show_stmt_file_line(net, "Disable statement."); fprintf(vvp_out, " %%disable S_%p;\n", target); } /* A SystemVerilog disable fork statement. */ } else { show_stmt_file_line(net, "Disable fork statement."); fprintf(vvp_out, " %%disable/fork;\n"); } return rc; } static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; unsigned top_label = local_count++; show_stmt_file_line(net, "Do/While statement."); /* Start the loop. The top of the loop starts a basic block because it can be entered from above or from the bottom of the loop. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); /* Draw the body of the loop. */ rc += show_statement(ivl_stmt_sub_stmt(net), sscope); /* Draw the evaluation of the condition expression, and test the result. If the expression evaluates to true, then branch to the top label. */ int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net)); fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", thread_count, top_label, use_flag); clr_flag(use_flag); return rc; } static int show_stmt_force(ivl_statement_t net) { ivl_expr_t rval; ivl_signal_t sig; show_stmt_file_line(net, "Force statement."); rval = ivl_stmt_rval(net); assert(rval); sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { draw_eval_real(ivl_stmt_rval(net)); force_real_to_lval(net); } else { draw_eval_vec4(rval); /* Write out initial continuous assign instructions to assign the expression value to the l-value. */ force_vector_to_lval(net); } force_link_rval(net, rval); return 0; } static int show_stmt_forever(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; ivl_statement_t stmt = ivl_stmt_sub_stmt(net); unsigned lab_top = local_count++; show_stmt_file_line(net, "Forever statement."); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_top); rc += show_statement(stmt, sscope); fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, lab_top); return rc; } static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) { unsigned idx; int rc = 0; unsigned join_count = ivl_stmt_block_count(net); unsigned join_detach_count = 0; ivl_scope_t scope = ivl_stmt_block_scope(net); int is_named = (scope != 0); unsigned out = transient_id++; unsigned id_base = transient_id; /* Increment the number of IDs needed before the join count is * modified by the join_any or join_none code below. */ transient_id += join_count; switch (ivl_statement_type(net)) { case IVL_ST_FORK: break; case IVL_ST_FORK_JOIN_ANY: if (join_count < 2) break; join_detach_count = join_count - 1; join_count = 1; break; case IVL_ST_FORK_JOIN_NONE: join_detach_count = join_count; join_count = 0; break; default: assert(0); } if (scope==0) scope = sscope; /* Draw a fork statement for all but one of the threads of the fork/join. Send the threads off to a bit of code where they are implemented. */ for (idx = 0 ; idx < (join_count+join_detach_count) ; idx += 1) { fprintf(vvp_out, " %%fork t_%u, S_%p;\n", id_base+idx, scope); } /* Generate enough joins to collect all the sub-threads. */ for (idx = 0 ; idx < join_count ; idx += 1) fprintf(vvp_out, " %%join;\n"); if (join_detach_count > 0) fprintf(vvp_out, " %%join/detach %u;\n", join_detach_count); /* Jump around all the threads that I'm creating. */ fprintf(vvp_out, " %%jmp t_%u;\n", out); /* Change the compiling scope to be the named forks scope. */ if (is_named) fprintf(vvp_out, " .scope S_%p;\n", scope); /* Generate the sub-threads themselves. */ for (idx = 0 ; idx < (join_count + join_detach_count) ; idx += 1) { fprintf(vvp_out, "t_%u ;\n", id_base+idx); rc += show_statement(ivl_stmt_block_stmt(net, idx), scope); fprintf(vvp_out, " %%end;\n"); } /* Return to the previous scope. */ if (sscope) fprintf(vvp_out, " .scope S_%p;\n", sscope); /* This is the label for the out. Use this to branch around the implementations of all the child threads. */ fprintf(vvp_out, "t_%u ;\n", out); return rc; } static int show_stmt_free(ivl_statement_t net) { ivl_scope_t scope = ivl_stmt_call(net); fprintf(vvp_out, " %%free S_%p;\n", scope); return 0; } /* * noop statements are implemented by doing nothing. */ static int show_stmt_noop(ivl_statement_t net) { (void)net; /* Parameter is not used. */ return 0; } static int show_stmt_release(ivl_statement_t net) { ivl_signal_t sig = ivl_lval_sig(ivl_stmt_lval(net, 0)); unsigned lidx; show_stmt_file_line(net, "Release statement."); if (sig && ivl_signal_data_type(sig) == IVL_VT_REAL) { unsigned type = 0; ivl_lval_t lval; assert(ivl_stmt_lvals(net) == 1); lval = ivl_stmt_lval(net, 0); assert(ivl_lval_width(lval) == 1); assert(ivl_lval_part_off(lval) == 0); ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the deassignment in this case. */ if (number_is_unknown(word_idx)) return 0; use_word = get_number_immediate(word_idx); } if (ivl_signal_type(sig) == IVL_SIT_REG) type = 1; fprintf(vvp_out, " %%release/wr v%p_%lu, %u;\n", sig, use_word, type); return 0; } for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { ivl_lval_t lval = ivl_stmt_lval(net, lidx); ivl_signal_t lsig = ivl_lval_sig(lval); const char*opcode = 0; ivl_expr_t word_idx = ivl_lval_idx(lval); unsigned long use_word = 0; unsigned use_wid; ivl_expr_t part_off_ex; unsigned part_off; assert(lsig != 0); use_wid = ivl_lval_width(lval); part_off_ex = ivl_lval_part_off(lval); part_off = 0; if (part_off_ex != 0) { assert(number_is_immediate(part_off_ex, 64, 0)); /* An out-of-range or undefined offset will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(part_off_ex)) return 0; part_off = get_number_immediate(part_off_ex); } switch (ivl_signal_type(lsig)) { case IVL_SIT_REG: opcode = "reg"; break; default: opcode = "net"; break; } if (word_idx != 0) { assert(number_is_immediate(word_idx, IMM_WID, 0)); /* An out-of-range or undefined index will have been converted to a canonical offset of 1'bx. Skip the assignment in this case. */ if (number_is_unknown(word_idx)) return 0; use_word = get_number_immediate(word_idx); } /* Generate the appropriate release statement for this l-value. */ fprintf(vvp_out, " %%release/%s v%p_%lu, %u, %u;\n", opcode, lsig, use_word, part_off, use_wid); } return 0; } static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; unsigned lab_top = local_count++, lab_out = local_count++; ivl_expr_t expr = ivl_stmt_cond_expr(net); const char *sign = ivl_expr_signed(expr) ? "s" : "u"; show_stmt_file_line(net, "Repeat statement."); /* Calculate the repeat count onto the top of the vec4 stack. */ draw_eval_vec4(expr); /* Test that 0 < expr, escape if expr <= 0. If the expr is unsigned, then we only need to try to escape if expr==0 as it will never be <0. */ fprintf(vvp_out, "T_%u.%u %%dup/vec4;\n", thread_count, lab_top); fprintf(vvp_out, " %%pushi/vec4 0, 0, %u;\n", ivl_expr_width(expr)); fprintf(vvp_out, " %%cmp/%s;\n", sign); if (ivl_expr_signed(expr)) fprintf(vvp_out, " %%jmp/1xz T_%u.%u, 5;\n", thread_count, lab_out); fprintf(vvp_out, " %%jmp/1 T_%u.%u, 4;\n", thread_count, lab_out); /* This adds -1 (all ones in 2's complement) to the count. */ fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", ivl_expr_width(expr)); fprintf(vvp_out, " %%sub;\n"); rc += show_statement(ivl_stmt_sub_stmt(net), sscope); fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, lab_top); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_out); fprintf(vvp_out, " %%pop/vec4 1;\n"); return rc; } /* * The trigger statement is straight forward. All we have to do is * write a single bit of fake data to the event object. */ static int show_stmt_trigger(ivl_statement_t net) { ivl_event_t ev = ivl_stmt_events(net, 0); assert(ev); show_stmt_file_line(net, "Event trigger statement."); fprintf(vvp_out, " %%event E_%p;\n", ev); return 0; } /* * The non-blocking trigger statement is straight forward. All we have to * do is write a single bit of fake data to the event object. */ static int show_stmt_nb_trigger(ivl_statement_t net) { ivl_event_t ev = ivl_stmt_events(net, 0); assert(ev); show_stmt_file_line(net, "Non-blocking event trigger statement."); ivl_expr_t expr = ivl_stmt_delay_expr(net); int use_idx = allocate_word(); if (expr) { draw_expr_into_idx(expr, use_idx); } else { fprintf(vvp_out, " %%ix/load %d, 0, 0;\n", use_idx); } fprintf(vvp_out, " %%event/nb E_%p, %d;\n", ev, use_idx); clr_word(use_idx); // FIXME: VVP needs to be updated to correctly support %event/nb fprintf(stderr, "%s:%u: vvp.tgt sorry: ->> is not currently supported.\n", ivl_stmt_file(net), ivl_stmt_lineno(net)); vvp_errors += 1; return 0; } static int show_stmt_utask(ivl_statement_t net) { ivl_scope_t task = ivl_stmt_call(net); show_stmt_file_line(net, "User task call."); if (ivl_scope_type(task) == IVL_SCT_FUNCTION) { // A function called as a task is (presumably) a void function. // Use the %callf/void instruction to call it. fprintf(vvp_out, " %%callf/void TD_%s", vvp_mangle_id(ivl_scope_name(task))); fprintf(vvp_out, ", S_%p;\n", task); } else { fprintf(vvp_out, " %%fork TD_%s", vvp_mangle_id(ivl_scope_name(task))); fprintf(vvp_out, ", S_%p;\n", task); fprintf(vvp_out, " %%join;\n"); } return 0; } static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope) { static unsigned int cascade_counter = 0; /* Look to see if this is a SystemVerilog wait fork. */ if ((ivl_stmt_nevent(net) == 1) && (ivl_stmt_events(net, 0) == 0)) { assert(ivl_statement_type(ivl_stmt_sub_stmt(net)) == IVL_ST_NOOP); show_stmt_file_line(net, "Wait fork statement."); fprintf(vvp_out, " %%wait/fork;\n"); return 0; } show_stmt_file_line(net, "Event wait (@) statement."); if (ivl_stmt_nevent(net) == 0) { assert(ivl_stmt_needs_t0_trigger(net) == 1); fprintf(vvp_out, " %%wait E_0x0;\n"); } else if (ivl_stmt_nevent(net) == 1) { ivl_event_t ev = ivl_stmt_events(net, 0); if (ivl_stmt_needs_t0_trigger(net)) { fprintf(vvp_out, "Ewait_%u .event/or E_%p, E_0x0;\n", cascade_counter, ev); fprintf(vvp_out, " %%wait Ewait_%u;\n", cascade_counter); cascade_counter += 1; } else { fprintf(vvp_out, " %%wait E_%p;\n", ev); } } else { unsigned idx; ivl_event_t ev = ivl_stmt_events(net, 0); fprintf(vvp_out, "Ewait_%u .event/or E_%p", cascade_counter, ev); for (idx = 1 ; idx < ivl_stmt_nevent(net) ; idx += 1) { ev = ivl_stmt_events(net, idx); fprintf(vvp_out, ", E_%p", ev); } assert(ivl_stmt_needs_t0_trigger(net) == 0); fprintf(vvp_out, ";\n %%wait Ewait_%u;\n", cascade_counter); cascade_counter += 1; } return show_statement(ivl_stmt_sub_stmt(net), sscope); } static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) { int rc = 0; unsigned top_label = local_count++; unsigned out_label = local_count++; show_stmt_file_line(net, "While statement."); /* Start the loop. The top of the loop starts a basic block because it can be entered from above or from the bottom of the loop. */ fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); /* Draw the evaluation of the condition expression, and test the result. If the expression evaluates to false, then branch to the out label. */ int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net)); fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n", thread_count, out_label, use_flag); clr_flag(use_flag); /* Draw the body of the loop. */ rc += show_statement(ivl_stmt_sub_stmt(net), sscope); /* This is the bottom of the loop. branch to the top where the test is repeated, and also draw the out label. */ fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, top_label); fprintf(vvp_out, "T_%u.%u ;\n", thread_count, out_label); return rc; } static int show_delete_method(ivl_statement_t net) { show_stmt_file_line(net, "Delete object"); unsigned parm_count = ivl_stmt_parm_count(net); if ((parm_count < 1) || (parm_count > 2)) return 1; ivl_expr_t parm = ivl_stmt_parm(net, 0); assert(ivl_expr_type(parm) == IVL_EX_SIGNAL); ivl_signal_t var = ivl_expr_signal(parm); /* If this is a queue then it can have an element to delete. */ if (parm_count == 2) { if (ivl_type_base(ivl_signal_net_type(var)) != IVL_VT_QUEUE) return 1; draw_eval_expr_into_integer(ivl_stmt_parm(net, 1), 3); fprintf(vvp_out, " %%delete/elem v%p_0;\n", var); } else { fprintf(vvp_out, " %%delete/obj v%p_0;\n", var); } return 0; } static int show_insert_method(ivl_statement_t net) { show_stmt_file_line(net, "queue: insert"); unsigned parm_count = ivl_stmt_parm_count(net); if (parm_count != 3) return 1; ivl_expr_t parm0 = ivl_stmt_parm(net,0); assert(ivl_expr_type(parm0) == IVL_EX_SIGNAL); ivl_signal_t var = ivl_expr_signal(parm0); ivl_type_t var_type = ivl_signal_net_type(var); assert(ivl_type_base(var_type) == IVL_VT_QUEUE); int idx = allocate_word(); assert(idx >= 0); /* Save the queue maximum index value to an integer register. */ fprintf(vvp_out, " %%ix/load %d, %u, 0;\n", idx, ivl_signal_array_count(var)); ivl_type_t element_type = ivl_type_element(var_type); ivl_expr_t parm1 = ivl_stmt_parm(net,1); /* The %qinsert expects the array index to be in index register 3. */ draw_eval_expr_into_integer(parm1, 3); ivl_expr_t parm2 = ivl_stmt_parm(net,2); switch (ivl_type_base(element_type)) { case IVL_VT_REAL: draw_eval_real(parm2); fprintf(vvp_out, " %%qinsert/real v%p_0, %d;\n", var, idx); break; case IVL_VT_STRING: draw_eval_string(parm2); fprintf(vvp_out, " %%qinsert/str v%p_0, %d;\n", var, idx); break; default: draw_eval_vec4(parm2); fprintf(vvp_out, " %%qinsert/v v%p_0, %d, %u;\n", var, idx, ivl_type_packed_width(element_type)); break; } return 0; } static int show_push_frontback_method(ivl_statement_t net, bool is_front) { const char*type_code; if (is_front) { show_stmt_file_line(net, "queue: push_front"); type_code = "qf"; } else { show_stmt_file_line(net, "queue: push_back"); type_code = "qb"; } unsigned parm_count = ivl_stmt_parm_count(net); if (parm_count != 2) return 1; ivl_expr_t parm0 = ivl_stmt_parm(net,0); assert(ivl_expr_type(parm0) == IVL_EX_SIGNAL); ivl_signal_t var = ivl_expr_signal(parm0); ivl_type_t var_type = ivl_signal_net_type(var); assert(ivl_type_base(var_type) == IVL_VT_QUEUE); int idx = allocate_word(); assert(idx >= 0); /* Save the queue maximum index value to an integer register. */ fprintf(vvp_out, " %%ix/load %d, %u, 0;\n", idx, ivl_signal_array_count(var)); ivl_type_t element_type = ivl_type_element(var_type); ivl_expr_t parm1 = ivl_stmt_parm(net,1); switch (ivl_type_base(element_type)) { case IVL_VT_REAL: draw_eval_real(parm1); fprintf(vvp_out, " %%store/%s/r v%p_0, %d;\n", type_code, var, idx); break; case IVL_VT_STRING: draw_eval_string(parm1); fprintf(vvp_out, " %%store/%s/str v%p_0, %d;\n", type_code, var, idx); break; default: draw_eval_vec4(parm1); fprintf(vvp_out, " %%store/%s/v v%p_0, %d, %u;\n", type_code, var, idx, ivl_type_packed_width(element_type)); break; } clr_word(idx); return 0; } static int show_system_task_call(ivl_statement_t net) { const char*stmt_name = ivl_stmt_name(net); if (strcmp(stmt_name,"$ivl_darray_method$delete") == 0) return show_delete_method(net); if (strcmp(stmt_name,"$ivl_queue_method$insert") == 0) return show_insert_method(net); if (strcmp(stmt_name,"$ivl_queue_method$push_front") == 0) return show_push_frontback_method(net, true); if (strcmp(stmt_name,"$ivl_queue_method$push_back") == 0) return show_push_frontback_method(net, false); show_stmt_file_line(net, "System task call."); draw_vpi_task_call(net); return 0; } /* * Icarus translated = into * begin * = ; * = ; * end * This routine looks for this pattern so we only emit one %file_line opcode. */ static unsigned is_delayed_or_event_assign(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t assign, delay, delayed_assign; ivl_statement_type_t delay_type; ivl_lval_t lval; ivl_expr_t rval; ivl_signal_t lsig, rsig; (void)scope; /* Parameter is not used. */ /* We must have two block elements. */ if (ivl_stmt_block_count(stmt) != 2) return 0; /* The first must be an assign. */ assign = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0; /* The second must be a delayx. */ delay = ivl_stmt_block_stmt(stmt, 1); delay_type = ivl_statement_type(delay); if ((delay_type != IVL_ST_DELAYX) && (delay_type != IVL_ST_WAIT)) return 0; /* The statement for the delayx must be an assign. */ delayed_assign = ivl_stmt_sub_stmt(delay); if (ivl_statement_type(delayed_assign) != IVL_ST_ASSIGN) return 0; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(assign) != 1) return 0; lval = ivl_stmt_lval(assign, 0); /* It must not have an array select. */ if (ivl_lval_idx(lval)) return 0; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return 0; lsig = ivl_lval_sig(lval); /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return 0; /* The R-value must be a single signal. */ rval = ivl_stmt_rval(delayed_assign); if (ivl_expr_type(rval) != IVL_EX_SIGNAL) return 0; /* It must not be an array word. */ if (ivl_expr_oper1(rval)) return 0; rsig = ivl_expr_signal(rval); /* The two signals must be the same. */ if (lsig != rsig) return 0; /* And finally the three statements must have the same line number * as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delay)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(delayed_assign))) { return 0; } /* The pattern matched so this block represents a blocking * assignment with an inter-assignment delay or event. */ if (delay_type == IVL_ST_DELAYX) { show_stmt_file_line(stmt, "Blocking assignment (delay)."); } else { show_stmt_file_line(stmt, "Blocking assignment (event)."); } return 1; } /* * Icarus translated = repeat() into * begin * = ; * repeat() ; * = ; * end * This routine looks for this pattern so we only emit one %file_line opcode. */ static unsigned is_repeat_event_assign(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t assign, event, event_assign, repeat; ivl_lval_t lval; ivl_expr_t rval; ivl_signal_t lsig, rsig; (void)scope; /* Parameter is not used. */ /* We must have three block elements. */ if (ivl_stmt_block_count(stmt) != 3) return 0; /* The first must be an assign. */ assign = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(assign) != IVL_ST_ASSIGN) return 0; /* The second must be a repeat with an event or an event. */ repeat = ivl_stmt_block_stmt(stmt, 1); if (ivl_statement_type(repeat) != IVL_ST_REPEAT) return 0; /* The repeat must have an event statement. */ event = ivl_stmt_sub_stmt(repeat); if (ivl_statement_type(event) != IVL_ST_WAIT) return 0; /* The third must be an assign. */ event_assign = ivl_stmt_block_stmt(stmt, 2); if (ivl_statement_type(event_assign) != IVL_ST_ASSIGN) return 0; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(assign) != 1) return 0; lval = ivl_stmt_lval(assign, 0); /* It must not have an array select. */ if (ivl_lval_idx(lval)) return 0; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return 0; lsig = ivl_lval_sig(lval); /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return 0; /* The R-value must be a single signal. */ rval = ivl_stmt_rval(event_assign); if (ivl_expr_type(rval) != IVL_EX_SIGNAL) return 0; /* It must not be an array word. */ if (ivl_expr_oper1(rval)) return 0; rsig = ivl_expr_signal(rval); /* The two signals must be the same. */ if (lsig != rsig) return 0; /* And finally the four statements must have the same line number * as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(assign)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(repeat)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(event_assign))) { return 0; } /* The pattern matched so this block represents a blocking * assignment with an inter-assignment repeat event. */ show_stmt_file_line(stmt, "Blocking assignment (repeat event)."); return 1; } /* * Icarus translated wait( into * begin * while ( !== 1'b1) @(); * * end * This routine looks for this pattern and turns it back into a * wait statement. */ static unsigned is_wait(ivl_scope_t scope, ivl_statement_t stmt) { ivl_statement_t while_wait, wait_x, wait_stmt; ivl_expr_t while_expr, expr; const char *bits; (void)scope; /* Parameter is not used. */ /* We must have two block elements. */ if (ivl_stmt_block_count(stmt) != 2) return 0; /* The first must be a while. */ while_wait = ivl_stmt_block_stmt(stmt, 0); if (ivl_statement_type(while_wait) != IVL_ST_WHILE) return 0; /* That has a wait with a NOOP statement. */ wait_x = ivl_stmt_sub_stmt(while_wait); if (ivl_statement_type(wait_x) != IVL_ST_WAIT) return 0; wait_stmt = ivl_stmt_sub_stmt(wait_x); if (ivl_statement_type(wait_stmt) != IVL_ST_NOOP) return 0; /* Check that the while condition has the correct form. */ while_expr = ivl_stmt_cond_expr(while_wait); if (ivl_expr_type(while_expr) != IVL_EX_BINARY) return 0; if (ivl_expr_opcode(while_expr) != 'N') return 0; /* Has a second operator that is a constant 1'b1. */ expr = ivl_expr_oper2(while_expr); if (ivl_expr_type(expr) != IVL_EX_NUMBER) return 0; if (ivl_expr_width(expr) != 1) return 0; bits = ivl_expr_bits(expr); if (*bits != '1') return 0; /* There is no easy way to verify that the @ sensitivity list * matches the first expression so that is not currently checked. */ /* And finally the two statements that represent the wait must * have the same line number as the block. */ if ((ivl_stmt_lineno(stmt) != ivl_stmt_lineno(while_wait)) || (ivl_stmt_lineno(stmt) != ivl_stmt_lineno(wait_x))) { return 0; } /* The pattern matched so this block represents a wait statement. */ show_stmt_file_line(stmt, "Wait statement."); return 1; } /* * Check to see if the statement L-value is a port in the given scope. * If it is return the zero based port number. */ static unsigned utask_in_port_idx(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports = ivl_scope_ports(scope); ivl_lval_t lval = ivl_stmt_lval(stmt, 0); ivl_signal_t lsig = ivl_lval_sig(lval); const char *sig_name; /* The L-value must be a single signal. */ if (ivl_stmt_lvals(stmt) != 1) return ports; /* It must not have an array select. */ if (ivl_lval_idx(lval)) return ports; /* It must not have a non-zero base. */ if (ivl_lval_part_off(lval)) return ports; /* It must not be part of the signal. */ if (ivl_lval_width(lval) != ivl_signal_width(lsig)) return ports; /* It must have the same scope as the task. */ if (scope != ivl_signal_scope(lsig)) return ports; /* It must be an input or inout port of the task. */ sig_name = ivl_signal_basename(lsig); for (idx = 0; idx < ports; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); if (!port) continue; ivl_signal_port_t port_type = ivl_signal_port(port); if ((port_type != IVL_SIP_INPUT) && (port_type != IVL_SIP_INOUT)) continue; if (strcmp(sig_name, ivl_signal_basename(port)) == 0) break; } return idx; } /* * Check to see if the statement R-value is a port in the given scope. * If it is return the zero based port number. */ static unsigned utask_out_port_idx(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports = ivl_scope_ports(scope); ivl_expr_t rval = ivl_stmt_rval(stmt); ivl_signal_t rsig = 0; ivl_expr_type_t expr_type = ivl_expr_type(rval); const char *sig_name; /* We can have a simple signal. */ if (expr_type == IVL_EX_SIGNAL) { rsig = ivl_expr_signal(rval); /* Or a simple select of a simple signal. */ } else if (expr_type == IVL_EX_SELECT) { ivl_expr_t expr = ivl_expr_oper1(rval); /* We must have a zero select base. */ if (ivl_expr_oper2(rval)) return ports; /* We must be selecting a signal. */ if (ivl_expr_type(expr) != IVL_EX_SIGNAL) return ports; rsig = ivl_expr_signal(expr); } else return ports; /* The R-value must have the same scope as the task. */ if (scope != ivl_signal_scope(rsig)) return ports; /* It must not be an array element. */ if (ivl_signal_dimensions(rsig)) return ports; /* It must be an output or inout port of the task. */ sig_name = ivl_signal_basename(rsig); for (idx = 0; idx < ports; idx += 1) { ivl_signal_t port = ivl_scope_port(scope, idx); if (!port) continue; ivl_signal_port_t port_type = ivl_signal_port(port); if ((port_type != IVL_SIP_OUTPUT) && (port_type != IVL_SIP_INOUT)) continue; if (strcmp(sig_name, ivl_signal_basename(port)) == 0) break; } return idx; } /* * Structure to hold the port information as we extract it from the block. */ typedef struct port_expr_s { ivl_signal_port_t type; union { ivl_statement_t lval; ivl_expr_t rval; } expr; } *port_expr_t; /* * Icarus encodes a user task call with arguments as: * begin * = * ... * = * * = * ... * = * end * This routine looks for that pattern and translates it into the * appropriate task call. It returns true (1) if it successfully * translated the block to a task call, otherwise it returns false * (0) to indicate the block needs to be emitted. */ static unsigned is_utask_call_with_args(ivl_scope_t scope, ivl_statement_t stmt) { unsigned idx, ports, task_idx = 0; unsigned is_void_func; unsigned count = ivl_stmt_block_count(stmt); unsigned lineno = ivl_stmt_lineno(stmt); ivl_scope_t task_scope = 0; port_expr_t port_exprs; (void)scope; /* Parameter is not used. */ /* Check to see if the block is of the basic form first. */ for (idx = 0; idx < count; idx += 1) { ivl_statement_t tmp = ivl_stmt_block_stmt(stmt, idx); if (ivl_statement_type(tmp) == IVL_ST_ASSIGN) continue; if (ivl_statement_type(tmp) == IVL_ST_UTASK && !task_scope) { task_idx = idx; task_scope = ivl_stmt_call(tmp); assert((ivl_scope_type(task_scope) == IVL_SCT_TASK) || (ivl_scope_type(task_scope) == IVL_SCT_FUNCTION)); continue; } return 0; } /* If there is no task call or it takes no argument then return. */ if (!task_scope) return 0; ports = ivl_scope_ports(task_scope); if (ports == 0) return 0; /* Allocate space to save the port information and initialize it. */ port_exprs = (port_expr_t) malloc(sizeof(struct port_expr_s)*ports); for (idx = 0; idx < ports; idx += 1) { port_exprs[idx].type = IVL_SIP_NONE; port_exprs[idx].expr.rval = 0; } /* Check that the input arguments are correct. */ for (idx = 0; idx < task_idx; idx += 1) { ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx); unsigned port = utask_in_port_idx(task_scope, assign); if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) { free(port_exprs); return 0; } port_exprs[port].type = IVL_SIP_INPUT; port_exprs[port].expr.rval = ivl_stmt_rval(assign); } /* Check that the output arguments are correct. */ for (idx = task_idx + 1; idx < count; idx += 1) { ivl_statement_t assign = ivl_stmt_block_stmt(stmt, idx); unsigned port = utask_out_port_idx(task_scope, assign); if ((port == ports) || (lineno != ivl_stmt_lineno(assign))) { free(port_exprs); return 0; } if (port_exprs[port].type == IVL_SIP_INPUT) { /* We probably should verify that the current R-value * matches the new L-value. */ port_exprs[port].type = IVL_SIP_INOUT; } else { port_exprs[port].type = IVL_SIP_OUTPUT; } port_exprs[port].expr.lval = assign; } /* Check that the task call has the correct line number. */ if (lineno != ivl_stmt_lineno(ivl_stmt_block_stmt(stmt, task_idx))) { free(port_exprs); return 0; } /* Verify that all the ports were defined. */ is_void_func = (ivl_scope_type(task_scope) == IVL_SCT_FUNCTION); if (is_void_func) { assert(port_exprs[0].type == IVL_SIP_NONE); } for (idx = is_void_func; idx < ports; idx += 1) { if (port_exprs[idx].type == IVL_SIP_NONE) { free(port_exprs); return 0; } } /* The pattern matched so this block represents a call to a user * defined task with arguments. */ show_stmt_file_line(stmt, "User task call (with arguments)."); free(port_exprs); return 1; } /* * This function draws a statement as vvp assembly. It basically * switches on the statement type and draws code based on the type and * further specifics. */ static int show_statement(ivl_statement_t net, ivl_scope_t sscope) { const ivl_statement_type_t code = ivl_statement_type(net); int rc = 0; switch (code) { case IVL_ST_ALLOC: rc += show_stmt_alloc(net); break; case IVL_ST_ASSIGN: rc += show_stmt_assign(net); break; case IVL_ST_ASSIGN_NB: rc += show_stmt_assign_nb(net); break; case IVL_ST_BLOCK: if (ivl_stmt_block_scope(net)) rc += show_stmt_block_named(net, sscope); else { unsigned saved_file_line = 0; /* This block could really represent a single statement. * If so only emit a single %file_line opcode. */ if (show_file_line) { if (is_delayed_or_event_assign(sscope, net) || is_repeat_event_assign(sscope, net) || is_wait(sscope, net) || is_utask_call_with_args(sscope, net)) { saved_file_line = show_file_line; show_file_line = 0; } } rc += show_stmt_block(net, sscope); if (saved_file_line) show_file_line = 1; } break; case IVL_ST_CASE: case IVL_ST_CASEX: case IVL_ST_CASEZ: rc += show_stmt_case(net, sscope); break; case IVL_ST_CASER: rc += show_stmt_case_r(net, sscope); break; case IVL_ST_CASSIGN: rc += show_stmt_cassign(net); break; case IVL_ST_CONDIT: rc += show_stmt_condit(net, sscope); break; case IVL_ST_DEASSIGN: rc += show_stmt_deassign(net); break; case IVL_ST_DELAY: rc += show_stmt_delay(net, sscope); break; case IVL_ST_DELAYX: rc += show_stmt_delayx(net, sscope); break; case IVL_ST_DISABLE: rc += show_stmt_disable(net, sscope); break; case IVL_ST_DO_WHILE: rc += show_stmt_do_while(net, sscope); break; case IVL_ST_FORCE: rc += show_stmt_force(net); break; case IVL_ST_FOREVER: rc += show_stmt_forever(net, sscope); break; case IVL_ST_FORK: case IVL_ST_FORK_JOIN_ANY: case IVL_ST_FORK_JOIN_NONE: rc += show_stmt_fork(net, sscope); break; case IVL_ST_FREE: rc += show_stmt_free(net); break; case IVL_ST_NOOP: rc += show_stmt_noop(net); break; case IVL_ST_RELEASE: rc += show_stmt_release(net); break; case IVL_ST_REPEAT: rc += show_stmt_repeat(net, sscope); break; case IVL_ST_STASK: rc += show_system_task_call(net); break; case IVL_ST_TRIGGER: rc += show_stmt_trigger(net); break; case IVL_ST_NB_TRIGGER: rc += show_stmt_nb_trigger(net); break; case IVL_ST_UTASK: rc += show_stmt_utask(net); break; case IVL_ST_WAIT: rc += show_stmt_wait(net, sscope); break; case IVL_ST_WHILE: rc += show_stmt_while(net, sscope); break; default: fprintf(stderr, "vvp.tgt: Unable to draw statement type %d\n", code); rc += 1; break; } return rc; } /* * The process as a whole is surrounded by this code. We generate a * start label that the .thread statement can use, and we generate * code to terminate the thread. */ int draw_process(ivl_process_t net, void*x) { int rc = 0; unsigned idx; ivl_scope_t scope = ivl_process_scope(net); ivl_statement_t stmt = ivl_process_stmt(net); int init_flag = 0; int push_flag = 0; (void)x; /* Parameter is not used. */ for (idx = 0 ; idx < ivl_process_attr_cnt(net) ; idx += 1) { ivl_attribute_t attr = ivl_process_attr_val(net, idx); if (strcmp(attr->key, "_ivl_schedule_init") == 0) { init_flag = 1; } if (strcmp(attr->key, "_ivl_schedule_push") == 0) { push_flag = 1; } else if (strcmp(attr->key, "ivl_combinational") == 0) { push_flag = 1; } } local_count = 0; fprintf(vvp_out, " .scope S_%p;\n", scope); /* Generate the entry label. Just give the thread a number so that we are certain the label is unique. */ fprintf(vvp_out, "T_%u ;\n", thread_count); /* Draw the contents of the thread. */ rc += show_statement(stmt, scope); /* Terminate the thread with either an %end instruction (initial statements) or a %jmp back to the beginning of the thread. */ switch (ivl_process_type(net)) { case IVL_PR_INITIAL: case IVL_PR_FINAL: fprintf(vvp_out, " %%end;\n"); break; case IVL_PR_ALWAYS: case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: fprintf(vvp_out, " %%jmp T_%u;\n", thread_count); break; } /* Now write out the directive that tells vvp where the thread starts. */ switch (ivl_process_type(net)) { case IVL_PR_INITIAL: case IVL_PR_ALWAYS: case IVL_PR_ALWAYS_COMB: case IVL_PR_ALWAYS_FF: case IVL_PR_ALWAYS_LATCH: if (init_flag) { fprintf(vvp_out, " .thread T_%u, $init;\n", thread_count); } else if (push_flag) { fprintf(vvp_out, " .thread T_%u, $push;\n", thread_count); } else { fprintf(vvp_out, " .thread T_%u;\n", thread_count); } break; case IVL_PR_FINAL: fprintf(vvp_out, " .thread T_%u, $final;\n", thread_count); break; } thread_count += 1; return rc; } int draw_task_definition(ivl_scope_t scope) { int rc = 0; ivl_statement_t def = ivl_scope_def(scope); fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope))); assert(def); rc += show_statement(def, scope); fprintf(vvp_out, " %%end;\n"); thread_count += 1; return rc; } int draw_func_definition(ivl_scope_t scope) { int rc = 0; ivl_statement_t def = ivl_scope_def(scope); fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope))); assert(def); rc += show_statement(def, scope); fprintf(vvp_out, " %%end;\n"); thread_count += 1; return rc; } iverilog-12_0/tgt-vvp/vvp_scope.c000066400000000000000000002107171435245347300171360ustar00rootroot00000000000000/* * Copyright (c) 2001-2022 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 "vvp_priv.h" # include # include # include # include # include # include "ivl_alloc.h" /* * Escape non-symbol characters in ids, and quotes in strings. */ __inline__ static char hex_digit(unsigned i) { i &= 0xf; return i>=10 ? i-10+'A' : i+'0'; } const char *vvp_mangle_id(const char *id) { static char *out = 0x0; static size_t out_len; int nesc = 0; int iout = 0; const char *inp = id; const char nosym[] = "!\"#%&'()*+,-/:;<=>?@[\\]^`{|}~"; char *se = strpbrk(inp, nosym); if (!se) return id; do { int n = se - inp; unsigned int nlen = strlen(id) + 4*(++nesc) + 1; if (out_len < nlen) { out = realloc(out, nlen); out_len = nlen; } if (n) { strncpy(out+iout, inp, n); iout += n; } inp += n+1; out[iout++] = '\\'; switch (*se) { case '\\': case '/': case '<': case '>': out[iout++] = *se; break; default: out[iout++] = 'x'; out[iout++] = hex_digit(*se >> 4); out[iout++] = hex_digit(*se); break; } se = strpbrk(inp, nosym); } while (se); strcpy(out+iout, inp); return out; } const char *vvp_mangle_name(const char *id) { static char *out = 0x0; static size_t out_len; int nesc = 0; int iout = 0; const char *inp = id; const char nosym[] = "\"\\"; char *se = strpbrk(inp, nosym); if (!se) return id; do { int n = se - inp; unsigned int nlen = strlen(id) + 2*(++nesc) + 1; if (out_len < nlen) { out = realloc(out, nlen); out_len = nlen; } if (n) { strncpy(out+iout, inp, n); iout += n; } inp += n+1; out[iout++] = '\\'; out[iout++] = *se; se = strpbrk(inp, nosym); } while (se); strcpy(out+iout, inp); return out; } /* REMOVE ME: vvp_signal_label should not be used. DEAD CODE * Given a signal, generate a string name that is suitable for use as * a label. The only rule is that the same signal will always have the * same label. The result is stored in static memory, so remember to * copy it out. */ const char* vvp_signal_label(ivl_signal_t sig) { static char buf[32]; sprintf(buf, "%p", sig); return buf; } static ivl_signal_t signal_of_nexus(ivl_nexus_t nex, unsigned*word) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; if (ivl_signal_local(sig)) continue; *word = ivl_nexus_ptr_pin(ptr); return sig; } return 0; } unsigned width_of_nexus(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig != 0) return ivl_signal_width(sig); } return 0; } ivl_variable_type_t data_type_of_nexus(ivl_nexus_t nex) { unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig != 0) return ivl_signal_data_type(sig); } /* shouldn't happen! */ return IVL_VT_NO_TYPE; } static ivl_nexus_ptr_t ivl_logic_pin_ptr(ivl_net_logic_t net, unsigned pin) { ivl_nexus_t nex = ivl_logic_pin(net, pin); unsigned idx; for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_net_logic_t tmp = ivl_nexus_ptr_log(ptr); if (tmp == 0) continue; if (tmp != net) continue; if (ivl_nexus_ptr_pin(ptr) != pin) continue; return ptr; } assert(0); return 0; } #if 0 const char*drive_string(ivl_drive_t drive) { switch (drive) { case IVL_DR_HiZ: return ""; case IVL_DR_SMALL: return "sm"; case IVL_DR_MEDIUM: return "me"; case IVL_DR_WEAK: return "we"; case IVL_DR_LARGE: return "la"; case IVL_DR_PULL: return "pu"; case IVL_DR_STRONG: return ""; case IVL_DR_SUPPLY: return "su"; } return ""; } #endif /* * The draw_scope function draws the major functional items within a * scope. This includes the scopes themselves, of course. All the * other functions in this file are in support of that task. */ /* * NEXUS * ivl builds up the netlist into objects connected together by * ivl_nexus_t objects. The nexus receives all the drivers of the * point in the net and resolves the value. The result is then sent to * all the nets that are connected to the nexus. The nets, then, are * read to get the value of the nexus. * * NETS * Nets are interesting and special, because a nexus may be connected * to several of them at once. This can happen, for example, as an * artifact of module port connects, where the inside and the outside * of the module are connected through an in-out port. (In fact, ivl * will simply connect signals that are bound through a port, because * the input/output/inout properties are enforced as compile time.) * * This case is handled by choosing one to receive the value of the * nexus. This one then feeds to another net at the nexus, and so * on. The last net is selected as the output of the nexus. */ /* * When checking if we can elide a buffer we need to keep the buffer * if both the input and output for the buffer are connected only * to netlist signals. This routine performs this check on the * given nexus. */ static unsigned is_netlist_signal(ivl_net_logic_t net, ivl_nexus_t nex) { unsigned idx, rtn; /* Assume that this is a netlist signal. */ rtn = 1; for (idx = 0; idx < ivl_nexus_ptrs(nex); idx += 1) { ivl_nexus_ptr_t nptr; ivl_signal_t sptr; nptr = ivl_nexus_ptr(nex, idx); /* Skip a pointer to the buffer we're checking. */ if (ivl_nexus_ptr_log(nptr) == net) continue; /* Check to see if this is a netlist signal. */ sptr = ivl_nexus_ptr_sig(nptr); if (sptr && !ivl_signal_local(sptr)) continue; /* If we get here then this is not just a netlist signal. */ rtn = 0; break; } return rtn; } int signal_is_return_value(ivl_signal_t sig) { ivl_scope_t sig_scope = ivl_signal_scope(sig); if (ivl_scope_type(sig_scope) != IVL_SCT_FUNCTION) return 0; if (strcmp(ivl_signal_basename(sig), ivl_scope_basename(sig_scope)) == 0) return 1; return 0; } /* * This tests a bufz device against an output receiver, and determines * if the device can be skipped. If this function returns false, then a * gate will be generated for this node. Otherwise, the code generator * will connect its input to its output and skip the gate. */ int can_elide_bufz(ivl_net_logic_t net, ivl_nexus_ptr_t nptr) { ivl_nexus_t in_n, out_n; unsigned idx; /* These are the drives we expect. */ ivl_drive_t dr0 = ivl_nexus_ptr_drive0(nptr); ivl_drive_t dr1 = ivl_nexus_ptr_drive1(nptr); int drive_count = 0; /* If the gate carries a delay, it must remain. */ if (ivl_logic_delay(net, 0) != 0) return 0; /* If the input is connected to the output, then do not elide the gate. This is some sort of cycle. */ if (ivl_logic_pin(net, 0) == ivl_logic_pin(net, 1)) return 0; in_n = ivl_logic_pin(net, 1); for (idx = 0 ; idx < ivl_nexus_ptrs(in_n) ; idx += 1) { ivl_nexus_ptr_t in_np = ivl_nexus_ptr(in_n, idx); if (ivl_nexus_ptr_log(in_np) == net) continue; /* If the driver for the source does not match the expected drive, then we need to keep the bufz. This test also catches the case that the input device is really also an input, as that device will have a drive of HiZ. We need to keep BUFZ devices in that case in order to prevent back-flow of data. */ if (ivl_nexus_ptr_drive0(in_np) != dr0) return 0; if (ivl_nexus_ptr_drive1(in_np) != dr1) return 0; drive_count += 1; } /* If the BUFZ input has multiple drivers on its input, then we need to keep this device in order to hide the resolution. */ if (drive_count != 1) return 0; /* If the BUFZ output is connected to a net that is subject to a force statement, we need to keep the BUFZ to prevent back-flow of the forced value. */ out_n = ivl_logic_pin(net, 0); for (idx = 0 ; idx < ivl_nexus_ptrs(out_n) ; idx += 1) { ivl_nexus_ptr_t out_np = ivl_nexus_ptr(out_n, idx); ivl_signal_t out_sig = ivl_nexus_ptr_sig(out_np); if (out_sig && ivl_signal_forced_net(out_sig)) return 0; } /* If both the input and output are netlist signal then we cannot elide a BUFZ since it represents a continuous assignment. */ if (is_netlist_signal(net, ivl_logic_pin(net, 0)) && is_netlist_signal(net, ivl_logic_pin(net, 1)) && (ivl_logic_type(net) == IVL_LO_BUFZ)) { return 0; } return 1; } char* draw_Cr_to_string(double value) { char tmp[256]; uint64_t mant = 0; int sign, expo, vexp; double fract; if (isinf(value)) { if (value > 0) snprintf(tmp, sizeof(tmp), "Cr"); else snprintf(tmp, sizeof(tmp), "Cr"); return strdup(tmp); } if (value != value) { snprintf(tmp, sizeof(tmp), "Cr"); return strdup(tmp); } sign = 0; if (value < 0.0 || (value == 0.0 && 1.0/value < 0.0)) { sign = 0x4000; value *= -1; } fract = frexp(value, &expo); fract = ldexp(fract, 63); mant = fract; expo -= 63; vexp = expo + 0x1000; assert(vexp >= 0); assert(vexp < 0x2000); vexp += sign; snprintf(tmp, sizeof(tmp), "Cr", mant, vexp); return strdup(tmp); } const char*draw_input_from_net(ivl_nexus_t nex) { static char result[32]; unsigned word; ivl_signal_t sig = signal_of_nexus(nex, &word); if (sig == 0) return draw_net_input(nex); if (ivl_signal_type(sig)==IVL_SIT_REG && ivl_signal_dimensions(sig)>0) return draw_net_input(nex); snprintf(result, sizeof result, "v%p_%u", sig, word); return result; } static const char *local_flag_str( ivl_signal_t sig ) { return ivl_signal_local(sig)? "*" : ""; } /* * This function draws a reg/int/variable in the scope. This is a very * simple device to draw as there are no inputs to connect so no need * to scan the nexus. We do have to account for the possibility that * the device is arrayed, though, by making a node for each array element. */ static void draw_reg_in_scope(ivl_signal_t sig) { int msb; int lsb; switch (ivl_signal_packed_dimensions(sig)) { case 0: msb = 0; lsb = 0; break; case 1: msb = ivl_signal_packed_msb(sig, 0); lsb = ivl_signal_packed_lsb(sig, 0); break; default: msb = ivl_signal_width(sig) - 1; lsb = 0; break; } /* Special Case: If this variable is the return value of a function, then it need to exist as an actual variable. */ if ((ivl_signal_data_type(sig)==IVL_VT_REAL) && signal_is_return_value(sig)) { fprintf(vvp_out, "; Variable %s is REAL return value of scope S_%p\n", ivl_signal_basename(sig), ivl_signal_scope(sig)); return; } if ((ivl_signal_data_type(sig)==IVL_VT_STRING) && signal_is_return_value(sig)) { fprintf(vvp_out, "; Variable %s is string return value of scope S_%p\n", ivl_signal_basename(sig), ivl_signal_scope(sig)); return; } if ((ivl_signal_data_type(sig)==IVL_VT_LOGIC) && signal_is_return_value(sig)) { fprintf(vvp_out, "; Variable %s is vec4 return value of scope S_%p\n", ivl_signal_basename(sig), ivl_signal_scope(sig)); return; } if ((ivl_signal_data_type(sig)==IVL_VT_BOOL) && signal_is_return_value(sig)) { fprintf(vvp_out, "; Variable %s is bool return value of scope S_%p\n", ivl_signal_basename(sig), ivl_signal_scope(sig)); return; } const char *datatype_flag = ivl_signal_integer(sig) ? "/i" : ivl_signal_signed(sig)? "/s" : ""; const char *local_flag = local_flag_str(sig); int vector_dims = 1; switch (ivl_signal_data_type(sig)) { case IVL_VT_BOOL: if (ivl_signal_signed(sig)) datatype_flag = "/2s"; else datatype_flag = "/2u"; break; case IVL_VT_REAL: datatype_flag = "/real"; vector_dims = 0; break; case IVL_VT_STRING: datatype_flag = "/str"; vector_dims = 0; break; case IVL_VT_CLASS: datatype_flag = "/obj"; vector_dims = 0; break; default: break; } /* If the reg objects are collected into an array, then first write out the .array record to declare the array indices. */ if (ivl_signal_dimensions(sig) > 0 && vector_dims==0) { /* Some types cannot be placed in packed dimensions, so do not include packed dimensions. */ unsigned word_count = ivl_signal_array_count(sig); unsigned swapped = ivl_signal_array_addr_swapped(sig); int last = ivl_signal_array_base(sig)+word_count-1; int first = ivl_signal_array_base(sig); fprintf(vvp_out, "v%p .array%s \"%s\", %d %d;\n", sig, datatype_flag, vvp_mangle_name(ivl_signal_basename(sig)), swapped ? first: last, swapped ? last : first); } else if (ivl_signal_dimensions(sig) > 0) { unsigned word_count = ivl_signal_array_count(sig); unsigned swapped = ivl_signal_array_addr_swapped(sig); int last = ivl_signal_array_base(sig)+word_count-1; int first = ivl_signal_array_base(sig); fprintf(vvp_out, "v%p .array%s \"%s\", %d %d, %d %d;\n", sig, datatype_flag, vvp_mangle_name(ivl_signal_basename(sig)), swapped ? first: last, swapped ? last : first, msb, lsb); } else if (ivl_signal_data_type(sig) == IVL_VT_DARRAY) { ivl_type_t var_type = ivl_signal_net_type(sig); ivl_type_t element_type = ivl_type_element(var_type); fprintf(vvp_out, "v%p_0 .var/darray \"%s\", %u;%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), ivl_type_packed_width(element_type), ivl_signal_local(sig)? " Local signal" : ""); } else if (ivl_signal_data_type(sig) == IVL_VT_QUEUE) { ivl_type_t var_type = ivl_signal_net_type(sig); ivl_type_t element_type = ivl_type_element(var_type); fprintf(vvp_out, "v%p_0 .var/queue \"%s\", %u;%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), ivl_type_packed_width(element_type), ivl_signal_local(sig)? " Local signal" : ""); } else if (ivl_signal_data_type(sig) == IVL_VT_STRING) { fprintf(vvp_out, "v%p_0 .var/str \"%s\";%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), ivl_signal_local(sig)? " Local signal" : ""); } else if (ivl_signal_data_type(sig) == IVL_VT_CLASS) { fprintf(vvp_out, "v%p_0 .var/cobj \"%s\";%s\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), ivl_signal_local(sig)? " Local signal" : ""); } else { fprintf(vvp_out, "v%p_0 .var%s %s\"%s\", %d %d;%s\n", sig, datatype_flag, local_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, ivl_signal_local(sig)? " Local signal" : "" ); } } /* * This function draws a net. This is a bit more complicated as we * have to find an appropriate functor to connect to the input. */ static void draw_net_in_scope(ivl_signal_t sig) { int msb; int lsb; switch (ivl_signal_packed_dimensions(sig)) { case 0: msb = 0; lsb = 0; break; case 1: msb = ivl_signal_packed_msb(sig, 0); lsb = ivl_signal_packed_lsb(sig, 0); break; default: msb = ivl_signal_width(sig) - 1; lsb = 0; break; } const char*datatype_flag = ivl_signal_signed(sig)? "/s" : ""; const char *local_flag = local_flag_str(sig); unsigned iword; switch (ivl_signal_data_type(sig)) { case IVL_VT_BOOL: if (ivl_signal_signed(sig)) datatype_flag = "/2s"; else datatype_flag = "/2u"; break; case IVL_VT_REAL: datatype_flag = "/real"; break; default: break; } for (iword = 0 ; iword < ivl_signal_array_count(sig); iword += 1) { unsigned word_count = ivl_signal_array_count(sig); unsigned dimensions = ivl_signal_dimensions(sig); struct vvp_nexus_data*nex_data; /* Connect the pin of the signal to something. */ ivl_nexus_t nex = ivl_signal_nex(sig, iword); const char*driver = draw_net_input(nex); nex_data = (struct vvp_nexus_data*)ivl_nexus_get_private(nex); assert(nex_data); if (nex_data->net == 0) { int strength_aware_flag = 0; const char*vec8 = ""; if (nex_data->flags&VVP_NEXUS_DATA_STR) strength_aware_flag = 1; if (nex_data->drivers_count > 1) vec8 = "8"; if (strength_aware_flag) vec8 = "8"; if (iword == 0 && dimensions > 0) { unsigned swapped = ivl_signal_array_addr_swapped(sig); int last = ivl_signal_array_base(sig) + word_count-1; int first = ivl_signal_array_base(sig); fprintf(vvp_out, "v%p .array \"%s\", %d %d;\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), swapped ? first : last, swapped ? last : first); } if (dimensions > 0) { /* If this is a word of an array, then use an array reference in place of the net name. */ fprintf(vvp_out, "v%p_%u .net%s%s v%p %u, %d %d, %s;" " %u drivers%s\n", sig, iword, vec8, datatype_flag, sig, iword, msb, lsb, driver, nex_data->drivers_count, strength_aware_flag?", strength-aware":"" ); } else if (ivl_signal_local(sig) && ivl_scope_is_auto(ivl_signal_scope(sig))) { assert(word_count == 1); fprintf(vvp_out, "; Elide local/automatic net v%p_%u name=%s\n", sig, iword, ivl_signal_basename(sig)); } else if (ivl_signal_local(sig) && nex_data->drivers_count==0) { assert(word_count == 1); fprintf(vvp_out, "; Elide local net with no drivers, v%p_%u name=%s\n", sig, iword, ivl_signal_basename(sig)); } else { /* If this is an isolated word, it uses its own name. */ assert(word_count == 1); fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s; " " %u drivers%s\n", sig, iword, vec8, datatype_flag, local_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, driver, nex_data->drivers_count, strength_aware_flag?", strength-aware":"" ); } nex_data->net = sig; nex_data->net_word = iword; } else if (dimensions > 0) { /* In this case, we have an alias to an existing signal array. this typically is an instance of port collapsing that the elaborator combined to discover that the entire array can be collapsed, so the word count for the signal and the alias *must* match. */ if (word_count == ivl_signal_array_count(nex_data->net)) { if (iword == 0) { fprintf(vvp_out, "v%p .array \"%s\", v%p; Alias to %s \n", sig, vvp_mangle_name(ivl_signal_basename(sig)), nex_data->net, ivl_signal_basename(nex_data->net)); } /* An alias for an individual word. */ } else { if (iword == 0) { unsigned swapped = ivl_signal_array_addr_swapped(sig); int first = ivl_signal_array_base(sig); int last = first + word_count-1; fprintf(vvp_out, "v%p .array \"%s\", %d %d;\n", sig, vvp_mangle_name(ivl_signal_basename(sig)), swapped ? first : last, swapped ? last : first ); } fprintf(vvp_out, "v%p_%u .net%s v%p %u, %d %d, " "v%p_%u; Alias to %s\n", sig, iword, datatype_flag, sig, iword, msb, lsb, nex_data->net, nex_data->net_word, ivl_signal_basename(nex_data->net)); } } else { /* Finally, we may have an alias that is a word connected to another word. Again, this is a case of port collapsing. */ int strength_aware_flag = 0; const char*vec8 = ""; if (nex_data->flags&VVP_NEXUS_DATA_STR) strength_aware_flag = 1; if (nex_data->drivers_count > 1) vec8 = "8"; if (strength_aware_flag) vec8 = "8"; fprintf(vvp_out, "v%p_%u .net%s%s %s\"%s\", %d %d, %s; " " alias, %u drivers%s\n", sig, iword, vec8, datatype_flag, local_flag, vvp_mangle_name(ivl_signal_basename(sig)), msb, lsb, driver, nex_data->drivers_count, strength_aware_flag?", strength-aware":""); } } } /* * Check to see if we need a delay. */ static unsigned need_delay(ivl_net_logic_t lptr) { /* If we have no rising delay then we do not have any delays. */ if (ivl_logic_delay(lptr, 0) == 0) { assert(ivl_logic_delay(lptr, 1) == 0); assert(ivl_logic_delay(lptr, 2) == 0); return 0; } return 1; } /* * Draw the appropriate delay statement. Returns zero if there is not a delay. */ static void draw_logic_delay(ivl_net_logic_t lptr) { ivl_expr_t rise_exp = ivl_logic_delay(lptr, 0); ivl_expr_t fall_exp = ivl_logic_delay(lptr, 1); ivl_expr_t decay_exp = ivl_logic_delay(lptr, 2); /* Calculate the width of the delay. We also use a BUFZ for real * values so we need to resize if the first input is real. */ unsigned delay_wid = width_of_nexus(ivl_logic_pin(lptr, 0)); if (data_type_of_nexus(ivl_logic_pin(lptr, 0)) == IVL_VT_REAL) { delay_wid = 0; } draw_delay(lptr, delay_wid, 0, rise_exp, fall_exp, decay_exp); } static void draw_udp_def(ivl_udp_t udp) { unsigned init; unsigned i; switch (ivl_udp_init(udp)) { case '0': init = 0; break; case '1': init = 1; break; default: init = 2; break; } if (ivl_udp_sequ(udp)) fprintf(vvp_out, "UDP_%s .udp/sequ \"%s\", %u, %u", vvp_mangle_id(ivl_udp_name(udp)), vvp_mangle_name(ivl_udp_name(udp)), ivl_udp_nin(udp), init ); else fprintf(vvp_out, "UDP_%s .udp/comb \"%s\", %u", vvp_mangle_id(ivl_udp_name(udp)), vvp_mangle_name(ivl_udp_name(udp)), ivl_udp_nin(udp)); for (i=0; i= nudps) { udps = realloc(udps, (nudps+1)*sizeof(ivl_udp_t)); udps[nudps++] = udp; draw_udp_def(udp); } /* * We need to process the arguments first so any evaluation code * (.resolv, etc.) can be built before we build the .udp call. * This matches what is done for the other primitives. */ assert(ivl_logic_pins(lptr) > 0); ninp = ivl_logic_pins(lptr) - 1; input_strings = calloc(ninp, sizeof(char*)); for (pdx = 0 ; pdx < ninp ; pdx += 1) { ivl_nexus_t nex = ivl_logic_pin(lptr, pdx+1); /* Unlike other logic gates, primitives may have unconnected * inputs. The proper behavior is to attach a HiZ to the * port. */ if (nex == 0) { assert(ivl_logic_width(lptr) == 1); input_strings[pdx] = "C4"; } else { input_strings[pdx] = draw_net_input(nex); } } /* Because vvp uses a wide functor for the output of a UDP we need * to define the output delay net when needed, otherwise it will * not be cleaned up correctly (gives a valgrind warning). */ if (need_delay_flag) { fprintf(vvp_out, "v%p_0 .net *\"_d%p\", 0 0, L_%p/d;\n", lptr, lptr, lptr); } /* The same situation exists if a modpath is used to connect the UDP * output to the true output signal. For this case the modpath is * the only thing connected to the UDP output. */ if (udp_has_modpath_output(lptr)) { fprintf(vvp_out, "v%p_0 .net *\"_m%p\", 0 0, L_%p;\n", lptr, lptr, lptr); } /* Generate the UDP call. */ fprintf(vvp_out, "L_%p%s .udp UDP_%s", lptr, need_delay_flag ? "/d" : "", vvp_mangle_id(ivl_udp_name(udp))); for (pdx = 0 ; pdx < ninp ; pdx += 1) { fprintf(vvp_out, ", %s", input_strings[pdx]); } free(input_strings); fprintf(vvp_out, ";\n"); /* Generate a delay when needed. */ if (need_delay_flag) draw_logic_delay(lptr); } static void draw_equiv_impl_in_scope(ivl_net_logic_t lptr) { unsigned ninp; const char *lval; const char *rval; const char*ltype = "?"; assert(width_of_nexus(ivl_logic_pin(lptr, 0)) == 1); assert(ivl_logic_pins(lptr) > 0); ninp = ivl_logic_pins(lptr) - 1; assert(ninp == 2); lval = draw_net_input(ivl_logic_pin(lptr, 1)); rval = draw_net_input(ivl_logic_pin(lptr, 2)); if (ivl_logic_type(lptr) == IVL_LO_EQUIV) { ltype = "EQUIV"; } else { assert(ivl_logic_type(lptr) == IVL_LO_IMPL); ltype = "IMPL"; } fprintf(vvp_out, "L_%p .functor %s 1, %s, %s, C4<0>, C4<0>;\n", lptr, ltype, lval, rval); } static void draw_logic_in_scope(ivl_net_logic_t lptr) { unsigned pdx; const char*ltype = "?"; const char*lcasc = 0; char identity_val = '0'; /* Do we need a delay? */ unsigned need_delay_flag = need_delay(lptr); unsigned vector_width = width_of_nexus(ivl_logic_pin(lptr, 0)); ivl_drive_t str0 = ivl_logic_drive0(lptr); ivl_drive_t str1 = ivl_logic_drive1(lptr); int level; unsigned ninp; const char **input_strings; switch (ivl_logic_type(lptr)) { case IVL_LO_UDP: draw_udp_in_scope(lptr); return; case IVL_LO_BUFZ: { /* Draw bufz objects, but only if the gate cannot be elided. If I can elide it, then the draw_nex_input will take care of it for me. */ ivl_nexus_ptr_t nptr = ivl_logic_pin_ptr(lptr,0); ltype = "BUFZ"; if (can_elide_bufz(lptr, nptr)) return; break; } case IVL_LO_BUFT: { /* Draw bufz objects, but only if the gate cannot be elided. If I can elide it, then the draw_nex_input will take care of it for me. */ ivl_nexus_ptr_t nptr = ivl_logic_pin_ptr(lptr,0); ltype = "BUFT"; if (can_elide_bufz(lptr, nptr)) return; break; } case IVL_LO_PULLDOWN: case IVL_LO_PULLUP: /* Skip pullup and pulldown objects. Things that have pull objects as inputs will instead generate the appropriate C symbol. */ return; case IVL_LO_AND: ltype = "AND"; identity_val = '1'; break; case IVL_LO_BUF: ltype = "BUF"; break; case IVL_LO_BUFIF0: ltype = "BUFIF0"; break; case IVL_LO_BUFIF1: ltype = "BUFIF1"; break; case IVL_LO_EQUIV: case IVL_LO_IMPL: draw_equiv_impl_in_scope(lptr); return; case IVL_LO_NAND: ltype = "NAND"; lcasc = "AND"; identity_val = '1'; break; case IVL_LO_NOR: ltype = "NOR"; lcasc = "OR"; break; case IVL_LO_NOT: ltype = "NOT"; break; case IVL_LO_OR: ltype = "OR"; break; case IVL_LO_XNOR: ltype = "XNOR"; lcasc = "XOR"; break; case IVL_LO_XOR: ltype = "XOR"; break; case IVL_LO_CMOS: ltype = "CMOS"; break; case IVL_LO_PMOS: ltype = "PMOS"; break; case IVL_LO_NMOS: ltype = "NMOS"; break; case IVL_LO_RCMOS: ltype = "RCMOS"; break; case IVL_LO_RPMOS: ltype = "RPMOS"; break; case IVL_LO_RNMOS: ltype = "RNMOS"; break; case IVL_LO_NOTIF0: ltype = "NOTIF0"; break; case IVL_LO_NOTIF1: ltype = "NOTIF1"; break; default: fprintf(stderr, "vvp.tgt: error: Unhandled logic type: %d\n", ivl_logic_type(lptr)); ltype = "?"; break; } if (!lcasc) lcasc = ltype; /* Get all the input label that I will use for parameters to the functor that I create later. */ assert(ivl_logic_pins(lptr) > 0); ninp = ivl_logic_pins(lptr) - 1; input_strings = calloc(ninp, sizeof(char*)); for (pdx = 0 ; pdx < (unsigned)ninp ; pdx += 1) input_strings[pdx] = draw_net_input(ivl_logic_pin(lptr, pdx+1)); level = 0; while (ninp) { unsigned inst; for (inst = 0; inst < (unsigned)ninp; inst += 4) { if (ninp > 4) fprintf(vvp_out, "L_%p/%d/%u .functor %s %u", lptr, level, inst, lcasc, vector_width); else { fprintf(vvp_out, "L_%p%s .functor %s %u", lptr, need_delay_flag? "/d" : "", ltype, vector_width); if (str0 != IVL_DR_STRONG || str1 != IVL_DR_STRONG) fprintf(vvp_out, " [%d %d]", str0, str1); } for (pdx = inst; pdx < (unsigned)ninp && pdx < inst+4 ; pdx += 1) { if (level) { fprintf(vvp_out, ", L_%p/%d/%u", lptr, level - 1, pdx*4); } else { fprintf(vvp_out, ", %s", input_strings[pdx]); } } for ( ; pdx < inst+4 ; pdx += 1) { unsigned wdx; fprintf(vvp_out, ", C4<"); for (wdx = 0 ; wdx < vector_width ; wdx += 1) fprintf(vvp_out, "%c", identity_val); fprintf(vvp_out, ">"); } fprintf(vvp_out, ";\n"); } if (ninp > 4) ninp = (ninp+3) / 4; else ninp = 0; level += 1; } /* Free the array of char*. The strings themselves are persistent, held by the ivl_nexus_t objects. */ free(input_strings); /* Generate a delay when needed. */ if (need_delay_flag) draw_logic_delay(lptr); } static void draw_event_in_scope(ivl_event_t obj) { char tmp[4][32]; const unsigned ntmp = sizeof(tmp) / sizeof(tmp[0]); unsigned nany = ivl_event_nany(obj); unsigned nneg = ivl_event_nneg(obj); unsigned npos = ivl_event_npos(obj); unsigned nedg = ivl_event_nedg(obj); unsigned cnt = 0; /* Figure out how many probe functors are needed. */ if (nany > 0) cnt += (nany+ntmp-1) / ntmp; if (nneg > 0) cnt += (nneg+ntmp-1) / ntmp; if (npos > 0) cnt += (npos+ntmp-1) / ntmp; if (nedg > 0) cnt += (nedg+ntmp-1) / ntmp; if (cnt == 0) { /* If none are needed, then this is a named event. The code needed is easy. */ fprintf(vvp_out, "E_%p .event \"%s\";\n", obj, vvp_mangle_name(ivl_event_basename(obj))); } else if (cnt > 1) { /* There are a bunch of events that need to be event/or combined. */ unsigned idx; unsigned ecnt = 0; for (idx = 0 ; idx < nany ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (nany < top) top = nany; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_any(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event anyedge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } for (idx = 0 ; idx < nneg ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (nneg < top) top = nneg; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_neg(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event negedge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } for (idx = 0 ; idx < npos ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (npos < top) top = npos; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_pos(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event posedge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } for (idx = 0 ; idx < nedg ; idx += ntmp, ecnt += 1) { unsigned sub, top; top = idx + ntmp; if (nedg < top) top = nedg; for (sub = idx ; sub < top ; sub += 1) { ivl_nexus_t nex = ivl_event_edg(obj, sub); strncpy(tmp[sub-idx], draw_input_from_net(nex), sizeof(tmp[0])); } fprintf(vvp_out, "E_%p/%u .event edge", obj, ecnt); for (sub = idx ; sub < top ; sub += 1) fprintf(vvp_out, ", %s", tmp[sub-idx]); fprintf(vvp_out, ";\n"); } assert(ecnt == cnt); fprintf(vvp_out, "E_%p .event/or", obj); fprintf(vvp_out, " E_%p/0", obj); for (idx = 1 ; idx < cnt ; idx += 1) fprintf(vvp_out, ", E_%p/%u", obj, idx); fprintf(vvp_out, ";\n"); } else { unsigned num_input_strings = nany + nneg + npos + nedg; unsigned idx; const char*edge = 0; assert(num_input_strings <= ntmp); if (nany > 0) { assert((nneg + npos + nedg) == 0); edge = "anyedge"; for (idx = 0 ; idx < nany ; idx += 1) { ivl_nexus_t nex = ivl_event_any(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } else if (nneg > 0) { assert((nany + npos + nedg) == 0); edge = "negedge"; for (idx = 0 ; idx < nneg ; idx += 1) { ivl_nexus_t nex = ivl_event_neg(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } else if (npos > 0) { assert((nany + nneg + nedg) == 0); edge = "posedge"; for (idx = 0 ; idx < npos ; idx += 1) { ivl_nexus_t nex = ivl_event_pos(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } else { assert((nany + nneg + npos) == 0); edge = "edge"; for (idx = 0 ; idx < nedg ; idx += 1) { ivl_nexus_t nex = ivl_event_edg(obj, idx); strncpy(tmp[idx], draw_input_from_net(nex), sizeof(tmp[0])); } } fprintf(vvp_out, "E_%p .event %s", obj, edge); for (idx = 0 ; idx < num_input_strings ; idx += 1) { fprintf(vvp_out, ", %s", tmp[idx]); } fprintf(vvp_out, ";\n"); } } /* * This function draws any functors needed to calculate the input to * this nexus, and leaves in the data array strings that can be used * as functor arguments. The strings are from the draw_net_input * function, which in turn returns nexus names, so the strings are * safe to pass around. */ static void draw_lpm_data_inputs(ivl_lpm_t net, unsigned base, unsigned ndata, const char**src_table) { unsigned idx; for (idx = 0 ; idx < ndata ; idx += 1) { ivl_nexus_t nex = ivl_lpm_data(net, base+idx); src_table[idx] = draw_net_input(nex); } } /* * If needed, draw a .delay node to delay the output from the LPM * device. Return the "/d" string if we drew this .delay node, or the * "" string if the node was not needed. The caller uses that string * to modify labels that are generated. */ static const char* draw_lpm_output_delay(ivl_lpm_t net, ivl_variable_type_t dt) { ivl_expr_t d_rise = ivl_lpm_delay(net, 0); ivl_expr_t d_fall = ivl_lpm_delay(net, 1); ivl_expr_t d_decay = ivl_lpm_delay(net, 2); unsigned width = ivl_lpm_width(net); /* The comparison and reduction operators only have a single output * bit to delay. */ switch (ivl_lpm_type(net)) { case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_RE_AND: case IVL_LPM_RE_OR: case IVL_LPM_RE_XOR: case IVL_LPM_RE_NAND: case IVL_LPM_RE_NOR: case IVL_LPM_RE_XNOR: width = 1; default: break; } if (dt == IVL_VT_REAL) width = 0; const char*dly = ""; if (d_rise != 0) { draw_delay(net, width, 0, d_rise, d_fall, d_decay); dly = "/d"; } return dly; } static void draw_lpm_abs(ivl_lpm_t net) { const char*src_table[1]; ivl_variable_type_t dt = data_type_of_nexus(ivl_lpm_data(net,0)); const char*dly; draw_lpm_data_inputs(net, 0, 1, src_table); dly = draw_lpm_output_delay(net, dt); fprintf(vvp_out, "L_%p%s .abs %s;\n", net, dly, src_table[0]); } static void draw_lpm_cast_int2(ivl_lpm_t net) { const char*src_table[1]; const char*dly; draw_lpm_data_inputs(net, 0, 1, src_table); dly = draw_lpm_output_delay(net, IVL_VT_BOOL); fprintf(vvp_out, "L_%p%s .cast/2 %u, %s;\n", net, dly, ivl_lpm_width(net), src_table[0]); } static void draw_lpm_cast_int(ivl_lpm_t net) { const char*src_table[1]; const char*dly; draw_lpm_data_inputs(net, 0, 1, src_table); dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); fprintf(vvp_out, "L_%p%s .cast/int %u, %s;\n", net, dly, ivl_lpm_width(net), src_table[0]); } static void draw_lpm_cast_real(ivl_lpm_t net) { const char*src_table[1]; const char*dly; const char*is_signed = ""; draw_lpm_data_inputs(net, 0, 1, src_table); dly = draw_lpm_output_delay(net, IVL_VT_REAL); if (ivl_lpm_signed(net)) is_signed = ".s"; fprintf(vvp_out, "L_%p%s .cast/real%s %s;\n", net, dly, is_signed, src_table[0]); } static void draw_lpm_add(ivl_lpm_t net) { const char*src_table[2]; unsigned width; const char*type = ""; ivl_variable_type_t dta = data_type_of_nexus(ivl_lpm_data(net,0)); ivl_variable_type_t dtb = data_type_of_nexus(ivl_lpm_data(net,1)); ivl_variable_type_t dto = IVL_VT_LOGIC; const char*dly; if (dta == IVL_VT_REAL || dtb == IVL_VT_REAL) dto = IVL_VT_REAL; width = ivl_lpm_width(net); switch (ivl_lpm_type(net)) { case IVL_LPM_ADD: if (dto == IVL_VT_REAL) type = "sum.r"; else type = "sum"; break; case IVL_LPM_SUB: if (dto == IVL_VT_REAL) type = "sub.r"; else type = "sub"; break; case IVL_LPM_MULT: if (dto == IVL_VT_REAL) type = "mult.r"; else type = "mult"; break; case IVL_LPM_DIVIDE: if (dto == IVL_VT_REAL) type = "div.r"; else if (ivl_lpm_signed(net)) type = "div.s"; else type = "div"; break; case IVL_LPM_MOD: if (dto == IVL_VT_REAL) type = "mod.r"; else if (ivl_lpm_signed(net)) type = "mod.s"; else type = "mod"; break; case IVL_LPM_POW: if (dto == IVL_VT_REAL) type = "pow.r"; else if (ivl_lpm_signed(net)) type = "pow.s"; else type = "pow"; break; default: assert(0); } draw_lpm_data_inputs(net, 0, 2, src_table); dly = draw_lpm_output_delay(net, dto); fprintf(vvp_out, "L_%p%s .arith/%s %u, %s, %s;\n", net, dly, type, width, src_table[0], src_table[1]); } /* * The read port to an array is generated as a single record that takes * the address as an input. */ static void draw_lpm_array(ivl_lpm_t net) { ivl_nexus_t nex; ivl_signal_t mem = ivl_lpm_array(net); const char*tmp; nex = ivl_lpm_select(net); tmp = draw_net_input(nex); fprintf(vvp_out, "L_%p .array/port v%p, %s;\n", net, mem, tmp); } static void draw_lpm_cmp(ivl_lpm_t net) { const char*src_table[2]; unsigned width; const char*type = ""; const char*signed_string = ivl_lpm_signed(net)? ".s" : ""; ivl_variable_type_t dta = data_type_of_nexus(ivl_lpm_data(net,0)); ivl_variable_type_t dtb = data_type_of_nexus(ivl_lpm_data(net,1)); ivl_variable_type_t dtc = IVL_VT_LOGIC; const char*dly; if (dta == IVL_VT_REAL || dtb == IVL_VT_REAL) dtc = IVL_VT_REAL; width = ivl_lpm_width(net); switch (ivl_lpm_type(net)) { case IVL_LPM_CMP_EEQ: assert(dtc != IVL_VT_REAL); /* Should never get here! */ type = "eeq"; signed_string = ""; break; case IVL_LPM_CMP_EQ: if (dtc == IVL_VT_REAL) type = "eq.r"; else type = "eq"; signed_string = ""; break; case IVL_LPM_CMP_EQX: assert(dtc != IVL_VT_REAL); type = "eqx"; signed_string = ""; break; case IVL_LPM_CMP_EQZ: assert(dtc != IVL_VT_REAL); type = "eqz"; signed_string = ""; break; case IVL_LPM_CMP_GE: if (dtc == IVL_VT_REAL) { type = "ge.r"; signed_string = ""; } else type = "ge"; break; case IVL_LPM_CMP_GT: if (dtc == IVL_VT_REAL) { type = "gt.r"; signed_string = ""; } else type = "gt"; break; case IVL_LPM_CMP_NE: if (dtc == IVL_VT_REAL) type = "ne.r"; else type = "ne"; signed_string = ""; break; case IVL_LPM_CMP_NEE: assert(dtc != IVL_VT_REAL); /* Should never get here! */ type = "nee"; signed_string = ""; break; case IVL_LPM_CMP_WEQ: assert(dtc != IVL_VT_REAL); /* Should never get here! */ type = "weq"; signed_string = ""; break; case IVL_LPM_CMP_WNE: assert(dtc != IVL_VT_REAL); /* Should never get here! */ type = "wne"; signed_string = ""; break; default: assert(0); } draw_lpm_data_inputs(net, 0, 2, src_table); /* The output of a compare is always logical. */ dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); fprintf(vvp_out, "L_%p%s .cmp/%s%s %u, %s, %s;\n", net, dly, type, signed_string, width, src_table[0], src_table[1]); } /* * This function draws the arguments to a .const node using the * lpm inputs starting at "start" and for "cnt" inputs. This input * count must be <= 4. It is up to the caller to write the header part * of the statement, and to organize the data into multiple * statements. * * Return the width of the final concatenation. */ static unsigned lpm_concat_inputs(ivl_lpm_t net, unsigned start, unsigned cnt, const char*src_table[]) { unsigned idx; unsigned wid = 0; assert(cnt <= 4); /* First, draw the [L M N O] part of the statement, the list of widths for the .concat statement. */ fprintf(vvp_out, "["); for (idx = 0 ; idx < cnt ; idx += 1) { ivl_nexus_t nex = ivl_lpm_data(net, start+idx); unsigned nexus_width = width_of_nexus(nex); fprintf(vvp_out, " %u", nexus_width); wid += nexus_width; } for ( ; idx < 4 ; idx += 1) fprintf(vvp_out, " 0"); fprintf(vvp_out, "]"); for (idx = 0 ; idx < cnt ; idx += 1) { fprintf(vvp_out, ", %s", src_table[idx]); } fprintf(vvp_out, ";\n"); return wid; } /* * Implement the general IVL_LPM_CONCAT using .concat nodes. Use as * many nested nodes as necessary to support the desired number of * input vectors. */ static void draw_lpm_concat(ivl_lpm_t net) { const char*src_table[4]; unsigned icnt = ivl_lpm_size(net); const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); const char*z = ivl_lpm_type(net)==IVL_LPM_CONCATZ? "8" : ""; if (icnt <= 4) { /* This is the easiest case. There are 4 or fewer input vectors, so the entire IVL_LPM_CONCAT can be implemented with a single .concat node. */ draw_lpm_data_inputs(net, 0, icnt, src_table); fprintf(vvp_out, "L_%p%s .concat%s ", net, dly, z); lpm_concat_inputs(net, 0, icnt, src_table); } else { /* If there are more than 4 inputs, things get more complicated. We need to generate a balanced tree of .concat nodes to blend the inputs down to a single root node, that becomes the output from the concatenation. */ unsigned idx, depth; struct concat_tree { unsigned base; unsigned wid; } *tree; tree = malloc((icnt + 3)/4 * sizeof(struct concat_tree)); /* First, fill in all the leaves with the initial inputs to the tree. After this loop, there are (icnt+3)/4 .concat nodes drawn, that together take all the inputs. */ for (idx = 0 ; idx < icnt ; idx += 4) { unsigned wid = 0; unsigned trans = 4; if ((idx + trans) > icnt) trans = icnt - idx; draw_lpm_data_inputs(net, idx, trans, src_table); fprintf(vvp_out, "LS_%p_0_%u .concat%s ", net, idx, z); wid = lpm_concat_inputs(net, idx, trans, src_table); tree[idx/4].base = idx; tree[idx/4].wid = wid; } /* icnt is the input count for the level. It is the number of .concats of the previous level that have to be concatenated at the current level. (This is not the same as the bit width.) */ icnt = (icnt + 3)/4; /* Tree now has icnt nodes that are depth=0 concat nodes which take in the leaf inputs. The while loop below starts and ends with a tree of icnt nodes. Each time through, there are 1/4 the nodes we started with. Thus, we eventually get down to <=4 nodes, and that is when we fall out of the loop. */ depth = 1; while (icnt > 4) { for (idx = 0 ; idx < icnt ; idx += 4) { unsigned tdx; unsigned wid = 0; unsigned trans = 4; if ((idx+trans) > icnt) trans = icnt - idx; fprintf(vvp_out, "LS_%p_%u_%u .concat%s [", net, depth, idx, z); for (tdx = 0 ; tdx < trans ; tdx += 1) { fprintf(vvp_out, " %u", tree[idx+tdx].wid); wid += tree[idx+tdx].wid; } for ( ; tdx < 4 ; tdx += 1) fprintf(vvp_out, " 0"); fprintf(vvp_out, "]"); for (tdx = 0; tdx < trans ; tdx += 1) { fprintf(vvp_out, ", LS_%p_%u_%u", net, depth-1, tree[idx+tdx].base); } fprintf(vvp_out, ";\n"); tree[idx/4].base = idx; tree[idx/4].wid = wid; } depth += 1; icnt = (icnt + 3)/4; } /* Finally, draw the root node that takes in the final row of tree nodes and generates a single output. */ fprintf(vvp_out, "L_%p%s .concat%s [", net, dly, z); for (idx = 0 ; idx < icnt ; idx += 1) fprintf(vvp_out, " %u", tree[idx].wid); for ( ; idx < 4 ; idx += 1) fprintf(vvp_out, " 0"); fprintf(vvp_out, "]"); for (idx = 0 ; idx < icnt ; idx += 1) fprintf(vvp_out, ", LS_%p_%u_%u", net, depth-1, tree[idx].base); fprintf(vvp_out, ";\n"); free(tree); } } /* * Emit a DFF primitive. This uses the following syntax: * * .dff , , [, [, ]]; */ static void draw_lpm_ff(ivl_lpm_t net) { ivl_nexus_t nex; const char*clk_in; const char*d_in; const char*e_in; const char*clr_in; const char*set_in; /* Sync set/clear control is not currently supported. This is not * a problem, as synthesis can incorporate this in the D input * expression. All modern synthesis tools do this as a matter of * course, as most cell libraries don't contain flip-flops with * sync set/clear. */ assert(ivl_lpm_sync_clr(net) == 0); assert(ivl_lpm_sync_set(net) == 0); unsigned width = ivl_lpm_width(net); char*edge = ivl_lpm_negedge(net) ? "n" : "p"; nex = ivl_lpm_clk(net); assert(nex); assert(width_of_nexus(nex) == 1); clk_in = draw_net_input(nex); nex = ivl_lpm_data(net,0); assert(nex); assert(width_of_nexus(nex) == width); d_in = draw_net_input(nex); nex = ivl_lpm_enable(net); if (nex) { assert(width_of_nexus(nex) == 1); e_in = draw_net_input(nex); } else { e_in = ", C4<1>"; } nex = ivl_lpm_async_clr(net); if (nex) { assert(width_of_nexus(nex) == 1); clr_in = draw_net_input(nex); } else { clr_in = 0; } nex = ivl_lpm_async_set(net); if (nex) { assert(width_of_nexus(nex) == 1); set_in = draw_net_input(nex); } else { set_in = 0; } if (clr_in) { /* Synthesis doesn't currently support both set and clear. If it ever does, it might be better to implement the flip-flop as a UDP. See tgt-vlog95 for an example of how to do this. */ if (set_in) { fprintf(stderr, "%s:%u:vvp.tgt: sorry: No support for a DFF " "with both an async. set and clear.\n", ivl_lpm_file(net), ivl_lpm_lineno(net)); vvp_errors += 1; } fprintf(vvp_out, "L_%p .dff/%s/aclr %u ", net, edge, width); } else if (ivl_lpm_async_set(net)) { fprintf(vvp_out, "L_%p .dff/%s/aset %u ", net, edge, width); } else { fprintf(vvp_out, "L_%p .dff/%s %u ", net, edge, width); } fprintf(vvp_out, "%s, %s, %s", d_in, clk_in, e_in); if (clr_in) { fprintf(vvp_out, ", %s", clr_in); } if (set_in) { ivl_expr_t val = ivl_lpm_aset_value(net); fprintf(vvp_out, ", %s", set_in); if (val) { unsigned nbits = ivl_expr_width(val); const char*bits = ivl_expr_bits(val); unsigned bb; assert(nbits == width); fprintf(vvp_out, ", C4<"); for (bb = 0 ; bb < nbits; bb += 1) fprintf(vvp_out, "%c", bits[nbits-bb-1]); fprintf(vvp_out, ">"); } } fprintf(vvp_out, ";\n"); } /* * Emit a LATCH primitive. This uses the following syntax: * * .latch , ; */ static void draw_lpm_latch(ivl_lpm_t net) { ivl_nexus_t nex; const char*d_in; const char*e_in; unsigned width = ivl_lpm_width(net); nex = ivl_lpm_data(net,0); assert(nex); assert(width_of_nexus(nex) == width); d_in = draw_net_input(nex); nex = ivl_lpm_enable(net); assert(nex); assert(width_of_nexus(nex) == 1); e_in = draw_net_input(nex); fprintf(vvp_out, "L_%p .latch %u %s, %s;\n", net, width, d_in, e_in); } static void draw_lpm_shiftl(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); const char* signed_flag = ivl_lpm_signed(net)? "s" : ""; const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); const char *lval = draw_net_input(ivl_lpm_data(net, 0)); const char *rval = draw_net_input(ivl_lpm_data(net, 1)); if (ivl_lpm_type(net) == IVL_LPM_SHIFTR) fprintf(vvp_out, "L_%p%s .shift/r%s %u", net, dly, signed_flag, width); else fprintf(vvp_out, "L_%p%s .shift/l %u", net, dly, width); fprintf(vvp_out, ", %s, %s;\n", lval, rval); } static void draw_type_string_of_nex(ivl_nexus_t nex) { switch (data_type_of_nexus(nex)) { case IVL_VT_REAL: fprintf(vvp_out, "r"); break; case IVL_VT_LOGIC: case IVL_VT_BOOL: fprintf(vvp_out, "v%u", width_of_nexus(nex)); break; default: assert(0); break; } } /* Check to see if the output of the system function is connected with * a modpath. */ static int sfunc_has_modpath_output(ivl_lpm_t lptr) { /* The q port is the output connection (nexus). */ ivl_nexus_t nex = ivl_lpm_q(lptr); ivl_scope_t scope = ivl_lpm_scope(lptr); unsigned idx; /* Check to see if there is a signal connected to the output. */ for (idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) { ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex, idx); ivl_signal_t sig = ivl_nexus_ptr_sig(ptr); if (sig == 0) continue; /* The modpath will be connected to the system function * output. */ if ((ivl_signal_scope(sig) == scope) && (ivl_signal_port(sig) == IVL_SIP_OUTPUT) && (ivl_signal_npath(sig))) return 1; } return 0; } /* Emit a definition for a net that has a delay or modpath. */ static void draw_sfunc_output_def(ivl_lpm_t net, char type) { ivl_nexus_t nex = ivl_lpm_q(net); const char *suf = (type == 'd') ? "/d" : ""; switch (data_type_of_nexus(nex)) { case IVL_VT_REAL: fprintf(vvp_out, "v%p_0 .net/real *\"_%c%p\", 0 0, L_%p%s;\n", net, type, net, net, suf); break; case IVL_VT_LOGIC: case IVL_VT_BOOL: fprintf(vvp_out, "v%p_0 .net *\"_%c%p\", %u 0, L_%p%s;\n", net, type, net, width_of_nexus(nex)-1, net, suf); break; default: assert(0); break; } } static void draw_lpm_sfunc(ivl_lpm_t net) { unsigned idx; ivl_variable_type_t dt = data_type_of_nexus(ivl_lpm_q(net)); const char*dly = draw_lpm_output_delay(net, dt); /* Get all the input labels that I will use for net signals that connect to the inputs of the function. */ unsigned ninp = ivl_lpm_size(net); const char**input_strings = calloc(ninp, sizeof(char*)); for (idx = 0 ; idx < ninp ; idx += 1) input_strings[idx] = draw_net_input(ivl_lpm_data(net, idx)); /* Because vvp uses a wide functor for the output of a system * function we need to define the output delay net when needed, * otherwise it will not be cleaned up correctly (gives a * valgrind warning). */ if (*dly != 0) { draw_sfunc_output_def(net, 'd'); } /* The same situation exists if a modpath is used to connect the * system function output to the true output signal. For this case * the modpath is the only thing connected to the UDP output. */ if (sfunc_has_modpath_output(net)) { draw_sfunc_output_def(net, 'm'); } if (ivl_lpm_trigger(net)) fprintf(vvp_out, "L_%p%s .sfunc/e %u %u \"%s\", E_%p", net, dly, ivl_file_table_index(ivl_lpm_file(net)), ivl_lpm_lineno(net), ivl_lpm_string(net), ivl_lpm_trigger(net)); else fprintf(vvp_out, "L_%p%s .sfunc %u %u \"%s\"", net, dly, ivl_file_table_index(ivl_lpm_file(net)), ivl_lpm_lineno(net), ivl_lpm_string(net)); /* Print the function type descriptor string. */ fprintf(vvp_out, ", \""); draw_type_string_of_nex(ivl_lpm_q(net)); for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 1) draw_type_string_of_nex(ivl_lpm_data(net,idx)); fprintf(vvp_out, "\""); for (idx = 0 ; idx < ivl_lpm_size(net) ; idx += 1) { fprintf(vvp_out, ", %s", input_strings[idx]); } fprintf(vvp_out, ";\n"); } static void draw_lpm_ufunc(ivl_lpm_t net) { unsigned idx; unsigned ninp; const char**input_strings; ivl_scope_t def = ivl_lpm_define(net); ivl_variable_type_t dt = data_type_of_nexus(ivl_lpm_q(net)); const char*dly = draw_lpm_output_delay(net, dt); const char*type_string = ""; switch (dt) { case IVL_VT_REAL: type_string = "/real"; break; case IVL_VT_BOOL: case IVL_VT_LOGIC: type_string = "/vec4"; break; default: break; } /* Get all the input labels that I will use for net signals that connect to the inputs of the function. */ ninp = ivl_lpm_size(net); input_strings = calloc(ninp, sizeof(char*)); for (idx = 0 ; idx < ninp ; idx += 1) input_strings[idx] = draw_net_input(ivl_lpm_data(net, idx)); if (ivl_lpm_trigger(net)) fprintf(vvp_out, "L_%p%s .ufunc/e TD_%s, %u, E_%p", net, dly, vvp_mangle_id(ivl_scope_name(def)), ivl_lpm_width(net), ivl_lpm_trigger(net)); else fprintf(vvp_out, "L_%p%s .ufunc%s TD_%s, %u", net, dly, type_string, vvp_mangle_id(ivl_scope_name(def)), ivl_lpm_width(net)); /* Print all the net signals that connect to the input of the function. */ for (idx = 0 ; idx < ninp ; idx += 1) { fprintf(vvp_out, ", %s", input_strings[idx]); } free(input_strings); assert((ninp+1) == ivl_scope_ports(def)); /* Now print all the variables in the function scope that receive the input values given in the previous list. */ for (idx = 0 ; idx < ninp ; idx += 1) { ivl_signal_t psig = ivl_scope_port(def, idx+1); if (idx == 0) fprintf(vvp_out, " ("); else fprintf(vvp_out, ", "); assert(ivl_signal_dimensions(psig) == 0); fprintf(vvp_out, "v%p_0", psig); } fprintf(vvp_out, ")"); #if 0 /* Now print the reference to the signal from which the result is collected. */ { ivl_signal_t psig = ivl_scope_port(def, 0); assert(ivl_lpm_width(net) == ivl_signal_width(psig)); assert(ivl_signal_dimensions(psig) == 0); fprintf(vvp_out, " v%p_0", psig); } #endif /* Finally, print the scope identifier. */ fprintf(vvp_out, " S_%p;\n", def); } /* * Handle a PART SELECT device. This has a single input and output, * plus an optional extra input that is a non-constant base. */ static void draw_lpm_part(ivl_lpm_t net) { unsigned width, base; ivl_nexus_t sel; const char*input = draw_net_input(ivl_lpm_data(net, 0)); const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); width = ivl_lpm_width(net); base = ivl_lpm_base(net); sel = ivl_lpm_data(net,1); if (sel == 0) { fprintf(vvp_out, "L_%p%s .part %s", net, dly, input); fprintf(vvp_out, ", %u, %u;\n", base, width); } else { const char*sel_symbol = draw_net_input(sel); fprintf(vvp_out, "L_%p%s .part/v%s %s", net, dly, (ivl_lpm_signed(net) ? ".s" : ""), input); fprintf(vvp_out, ", %s", sel_symbol); fprintf(vvp_out, ", %u;\n", width); } } /* * Handle a PART SELECT PV device. Generate a .part/pv node that * includes the part input, and the geometry of the part. */ static void draw_lpm_part_pv(ivl_lpm_t net) { unsigned width = ivl_lpm_width(net); unsigned base = ivl_lpm_base(net); unsigned signal_width = width_of_nexus(ivl_lpm_q(net)); const char*input = draw_net_input(ivl_lpm_data(net, 0)); fprintf(vvp_out, "L_%p .part/pv %s", net, input); fprintf(vvp_out, ", %u, %u, %u;\n", base, width, signal_width); } /* * Draw unary reduction devices. */ static void draw_lpm_re(ivl_lpm_t net, const char*type) { const char*input = draw_net_input(ivl_lpm_data(net, 0)); const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); fprintf(vvp_out, "L_%p%s .reduce/%s %s;\n", net, dly, type, input); } static void draw_lpm_repeat(ivl_lpm_t net) { const char*input = draw_net_input(ivl_lpm_data(net, 0)); const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); fprintf(vvp_out, "L_%p%s .repeat %u, %u, %s;\n", net, dly, ivl_lpm_width(net), ivl_lpm_size(net), input); } static void draw_lpm_sign_ext(ivl_lpm_t net) { const char*input = draw_net_input(ivl_lpm_data(net, 0)); const char*dly = draw_lpm_output_delay(net, IVL_VT_LOGIC); fprintf(vvp_out, "L_%p%s .extend/s %u, %s;\n", net, dly, ivl_lpm_width(net), input); } static void draw_lpm_in_scope(ivl_lpm_t net) { switch (ivl_lpm_type(net)) { case IVL_LPM_ABS: draw_lpm_abs(net); return; case IVL_LPM_CAST_INT: draw_lpm_cast_int(net); return; case IVL_LPM_CAST_INT2: draw_lpm_cast_int2(net); return; case IVL_LPM_CAST_REAL: draw_lpm_cast_real(net); return; case IVL_LPM_ADD: case IVL_LPM_SUB: case IVL_LPM_MULT: case IVL_LPM_DIVIDE: case IVL_LPM_MOD: case IVL_LPM_POW: draw_lpm_add(net); return; case IVL_LPM_ARRAY: draw_lpm_array(net); return; case IVL_LPM_PART_VP: draw_lpm_part(net); return; case IVL_LPM_PART_PV: draw_lpm_part_pv(net); return; case IVL_LPM_CONCAT: case IVL_LPM_CONCATZ: draw_lpm_concat(net); return; case IVL_LPM_FF: draw_lpm_ff(net); return; case IVL_LPM_LATCH: draw_lpm_latch(net); return; case IVL_LPM_CMP_EEQ: case IVL_LPM_CMP_EQ: case IVL_LPM_CMP_EQX: case IVL_LPM_CMP_EQZ: case IVL_LPM_CMP_GE: case IVL_LPM_CMP_GT: case IVL_LPM_CMP_NE: case IVL_LPM_CMP_NEE: case IVL_LPM_CMP_WEQ: case IVL_LPM_CMP_WNE: draw_lpm_cmp(net); return; case IVL_LPM_MUX: draw_lpm_mux(net); return; case IVL_LPM_RE_AND: draw_lpm_re(net, "and"); return; case IVL_LPM_RE_OR: draw_lpm_re(net, "or"); return; case IVL_LPM_RE_XOR: draw_lpm_re(net, "xor"); return; case IVL_LPM_RE_NAND: draw_lpm_re(net, "nand"); return; case IVL_LPM_RE_NOR: draw_lpm_re(net, "nor"); return; case IVL_LPM_RE_XNOR: draw_lpm_re(net, "xnor"); return; case IVL_LPM_REPEAT: draw_lpm_repeat(net); return; case IVL_LPM_SHIFTL: case IVL_LPM_SHIFTR: draw_lpm_shiftl(net); return; case IVL_LPM_SIGN_EXT: draw_lpm_sign_ext(net); return; case IVL_LPM_SFUNC: draw_lpm_sfunc(net); return; case IVL_LPM_SUBSTITUTE: draw_lpm_substitute(net); return; case IVL_LPM_UFUNC: draw_lpm_ufunc(net); return; default: fprintf(stderr, "XXXX LPM not supported: %s.%s\n", ivl_scope_name(ivl_lpm_scope(net)), ivl_lpm_basename(net)); } } static const char *vvp_port_info_type_str(ivl_signal_port_t ptype) { switch( ptype ) { case IVL_SIP_INPUT : return "/INPUT"; case IVL_SIP_OUTPUT : return "/OUTPUT"; case IVL_SIP_INOUT : return "/INOUT"; case IVL_SIP_NONE : return "/NODIR"; default : abort(); // NO SUPPORT FOR ANYTHING ELSE YET... } } int draw_scope(ivl_scope_t net, ivl_scope_t parent) { unsigned idx; const char *type; const char*prefix = ivl_scope_is_auto(net) ? "auto" : ""; char suffix[32]; suffix[0] = 0; switch (ivl_scope_type(net)) { case IVL_SCT_MODULE: type = "module"; break; case IVL_SCT_FUNCTION: type = "function"; break; case IVL_SCT_TASK: type = "task"; break; case IVL_SCT_BEGIN: type = "begin"; break; case IVL_SCT_FORK: type = "fork"; break; case IVL_SCT_GENERATE: type = "generate"; break; case IVL_SCT_PACKAGE: type = "package"; break; case IVL_SCT_CLASS: type = "class"; break; default: type = "?"; assert(0); } if (ivl_scope_type(net)==IVL_SCT_FUNCTION) { switch (ivl_scope_func_type(net)) { case IVL_VT_LOGIC: snprintf(suffix, sizeof suffix, ".vec4.%c%u", ivl_scope_func_signed(net)? 'u' : 's', ivl_scope_func_width(net)); break; case IVL_VT_BOOL: snprintf(suffix, sizeof suffix, ".vec2.%c%u", ivl_scope_func_signed(net)? 'u' : 's', ivl_scope_func_width(net)); break; case IVL_VT_REAL: snprintf(suffix, sizeof suffix, ".real"); break; case IVL_VT_STRING: snprintf(suffix, sizeof suffix, ".str"); break; case IVL_VT_CLASS: case IVL_VT_DARRAY: case IVL_VT_QUEUE: snprintf(suffix, sizeof suffix, ".obj"); break; case IVL_VT_VOID: snprintf(suffix, sizeof suffix, ".void"); break; default: assert(0); break; } } fprintf(vvp_out, "S_%p .scope %s%s%s, \"%s\" \"%s\" %u %u", net, prefix, type, suffix, vvp_mangle_name(ivl_scope_basename(net)), vvp_mangle_name(ivl_scope_tname(net)), ivl_file_table_index(ivl_scope_file(net)), ivl_scope_lineno(net)); if (parent) { fprintf(vvp_out, ", %u %u %u, S_%p;\n", ivl_file_table_index(ivl_scope_def_file(net)), ivl_scope_def_lineno(net), ivl_scope_is_cell(net), parent); } else { fprintf(vvp_out, ";\n"); } fprintf(vvp_out, " .timescale %d %d;\n", ivl_scope_time_units(net), ivl_scope_time_precision(net)); if( ivl_scope_type(net) == IVL_SCT_MODULE ) { // Port data for VPI: needed for vpiPorts property of vpiModule for( idx = 0; idx < ivl_scope_mod_module_ports(net); ++idx ) { const char *name = ivl_scope_mod_module_port_name(net,idx); ivl_signal_port_t ptype = ivl_scope_mod_module_port_type(net,idx); unsigned width = ivl_scope_mod_module_port_width(net,idx); if( name == 0 ) name = ""; fprintf( vvp_out, " .port_info %u %s %u \"%s\";\n", idx, vvp_port_info_type_str(ptype), width, vvp_mangle_name(name) ); } } for (idx = 0 ; idx < ivl_scope_params(net) ; idx += 1) { ivl_parameter_t par = ivl_scope_param(net, idx); // Skip type parameters for now. Support for type parameters // should be added together with support for quering types through // VPI. if (ivl_parameter_is_type(par)) continue; ivl_expr_t pex = ivl_parameter_expr(par); switch (ivl_expr_type(pex)) { case IVL_EX_STRING: fprintf(vvp_out, "P_%p .param/str \"%s\" %d %u %u, \"%s\";\n", par, vvp_mangle_name(ivl_parameter_basename(par)), ivl_parameter_local(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), ivl_expr_string(pex)); break; case IVL_EX_NUMBER: fprintf(vvp_out, "P_%p .param/l \"%s\" %d %u %u, %sC4<", par, vvp_mangle_name(ivl_parameter_basename(par)), ivl_parameter_local(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), ivl_expr_signed(pex)? "+":""); { const char*bits = ivl_expr_bits(pex); unsigned nbits = ivl_expr_width(pex); unsigned bb; for (bb = 0 ; bb < nbits; bb += 1) fprintf(vvp_out, "%c", bits[nbits-bb-1]); } fprintf(vvp_out, ">;\n"); break; case IVL_EX_REALNUM: { char *res = draw_Cr_to_string(ivl_expr_dvalue(pex)); fprintf(vvp_out, "P_%p .param/real \"%s\" %d %u %u, %s; " "value=%#g\n", par, vvp_mangle_name(ivl_parameter_basename(par)), ivl_parameter_local(par), ivl_file_table_index(ivl_parameter_file(par)), ivl_parameter_lineno(par), res, ivl_expr_dvalue(pex)); free(res); } break; default: fprintf(vvp_out, "; parameter type %d unsupported\n", ivl_expr_type(pex)); break; } } for (idx = 0 ; idx < ivl_scope_classes(net) ; idx += 1) { ivl_type_t class_type = ivl_scope_class(net,idx); draw_class_in_scope(class_type); } /* Scan the scope for enumeration types, and write out enumeration typespecs. */ for (idx = 0 ; idx < ivl_scope_enumerates(net) ; idx += 1) { ivl_enumtype_t enumtype = ivl_scope_enumerate(net, idx); draw_enumeration_in_scope(enumtype); } /* Scan the scope for logic devices. For each device, draw out a functor that connects pin 0 to the output, and the remaining pins to inputs. */ for (idx = 0 ; idx < ivl_scope_logs(net) ; idx += 1) { ivl_net_logic_t lptr = ivl_scope_log(net, idx); draw_logic_in_scope(lptr); } /* Scan the signals (reg and net) and draw the appropriate statements to make the signal function. */ for (idx = 0 ; idx < ivl_scope_sigs(net) ; idx += 1) { ivl_signal_t sig = ivl_scope_sig(net, idx); switch (ivl_signal_type(sig)) { case IVL_SIT_REG: draw_reg_in_scope(sig); break; default: draw_net_in_scope(sig); break; } } for (idx = 0 ; idx < ivl_scope_events(net) ; idx += 1) { ivl_event_t event = ivl_scope_event(net, idx); draw_event_in_scope(event); } for (idx = 0 ; idx < ivl_scope_lpms(net) ; idx += 1) { ivl_lpm_t lpm = ivl_scope_lpm(net, idx); draw_lpm_in_scope(lpm); } for (idx = 0 ; idx < ivl_scope_switches(net) ; idx += 1) { ivl_switch_t sw = ivl_scope_switch(net, idx); draw_switch_in_scope(sw); } if (ivl_scope_type(net) == IVL_SCT_TASK) draw_task_definition(net); if (ivl_scope_type(net) == IVL_SCT_FUNCTION) vvp_errors += draw_func_definition(net); ivl_scope_children(net, (ivl_scope_f*) draw_scope, net); return 0; } iverilog-12_0/util.h000066400000000000000000000027771435245347300145120ustar00rootroot00000000000000#ifndef IVL_util_H #define IVL_util_H /* * Copyright (c) 2000-2021 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 # include # include "StringHeap.h" # include "verinum.h" class PExpr; class Design; class NetScope; /* * This file attempts to locate a module in a file. It operates by * looking for a plausible Verilog file to hold the module, and * invoking the parser to bring in that file's contents. */ extern bool load_module(const char*type, int&parser_errors); struct attrib_list_t { perm_string key; verinum val; }; extern attrib_list_t* evaluate_attributes(const std::map&att, unsigned&natt, Design*des, NetScope*scope); #endif /* IVL_util_H */ iverilog-12_0/va_math.txt000066400000000000000000000073401435245347300155330ustar00rootroot00000000000000 The following is from the README.va_math that was included with the initial contribution of the va_math module. I've removed the parts that are obviously not applicable, i.e. how to compile the library, to this bundled version of the library. -------- License. -------- Verilog-A math library built for Icarus Verilog http://www.icarus.com/eda/verilog/ Copyright (C) 2007-2010 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. -------- The End. -------- iverilog-12_0/verilog.spec000066400000000000000000000120371435245347300156750ustar00rootroot00000000000000#norootforbuild # %define rev_date 20221226 # Normally, the suff-ix is %nil, meaning the suffix is to not be used. # But if the builder wants to make a suffixed package, he may set this # to a value (i.e. -test) to cause suffixes to be put in all the right # places. %define suff %nil # # Summary: Icarus Verilog Name: verilog%{suff} Version: 12.0.%{rev_date} Release: 0 License: GPL Group: Productivity/Scientific/Electronics Source: verilog%{suff}-%{rev_date}.tar.gz URL: http://www.icarus.com/eda/verilog/index.html Packager: Stephen Williams BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: gcc-c++, zlib-devel, bison, flex, gperf, readline-devel # This provides tag allows me to use a more specific name for things # that actually depend on me, Icarus Verilog. Provides: iverilog %description Icarus Verilog is a Verilog compiler that generates a variety of engineering formats, including simulation. It strives to be true to the IEEE-1364 standard. %prep %setup -n verilog%{suff}-%{rev_date} %build if test X%{suff} != X then %{configure} --enable-suffix=%{suff} else %{configure} fi make CXXFLAGS=-O %install %if 0%{?suse_version} %{makeinstall} %else make DESTDIR=$RPM_BUILD_ROOT install %endif %clean rm -rf $RPM_BUILD_ROOT %files %attr(-,root,root) %doc COPYING README.txt BUGS.txt QUICK_START.txt ieee1364-notes.txt mingw.txt swift.txt netlist.txt t-dll.txt vpi.txt cadpli/cadpli.txt %attr(-,root,root) %doc examples/* %attr(-,root,root) %{_mandir}/man1/iverilog%{suff}.1.gz %attr(-,root,root) %{_mandir}/man1/iverilog-vpi%{suff}.1.gz %attr(-,root,root) %{_mandir}/man1/vvp%{suff}.1.gz %attr(-,root,root) %{_bindir}/iverilog%{suff} %attr(-,root,root) %{_bindir}/iverilog-vpi%{suff} %attr(-,root,root) %{_bindir}/vvp%{suff} %attr(-,root,root) %{_libdir}/ivl%{suff}/ivl %attr(-,root,root) %{_libdir}/ivl%{suff}/ivlpp %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdlpp %attr(-,root,root) %{_libdir}/ivl%{suff}/blif.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/blif.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/blif-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/null.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/null.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/null-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/sizer.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/sizer.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/sizer-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/stub.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/stub.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/stub-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vvp.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/vvp.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vvp-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vlog95.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/vlog95.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/vlog95-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/pcb.tgt %attr(-,root,root) %{_libdir}/ivl%{suff}/pcb.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/pcb-s.conf %attr(-,root,root) %{_libdir}/ivl%{suff}/system.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/system.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/va_math.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/va_math.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/v2005_math.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/v2005_math.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/v2009.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/v2009.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_sys.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_sys.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_textio.sft %attr(-,root,root) %{_libdir}/ivl%{suff}/vhdl_textio.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/vpi_debug.vpi %attr(-,root,root) %{_libdir}/ivl%{suff}/cadpli.vpl %attr(-,root,root) %{_libdir}/libvpi%{suff}.a %attr(-,root,root) %{_libdir}/libveriuser%{suff}.a %attr(-,root,root) %{_libdir}/ivl%{suff}/include/constants.vams %attr(-,root,root) %{_libdir}/ivl%{suff}/include/disciplines.vams %attr(-,root,root) /usr/include/iverilog%{suff}/ivl_target.h %attr(-,root,root) /usr/include/iverilog%{suff}/vpi_user.h %attr(-,root,root) /usr/include/iverilog%{suff}/sv_vpi_user.h %attr(-,root,root) /usr/include/iverilog%{suff}/acc_user.h %attr(-,root,root) /usr/include/iverilog%{suff}/veriuser.h %attr(-,root,root) /usr/include/iverilog%{suff}/_pli_types.h %changelog -n verilog * Thu Jul 25 2013 - steve@icarus.com - Add blif code generator files. * Wed Feb 25 2009 - steve@icarus.com - Handle a package suffix if desired. * Tue Nov 25 2008 - steve@icarus.com - Move header files frim /verilog/ to /iverilog/ * Tue Nov 18 2008 - steve@icarus.com - New snapshot 20080905 * Fri Sep 03 2008 - steve@icarus.com - New snapshot 20080905 * Sat Aug 30 2008 - steve@icarus.com - Add vhdl target files - Add V/AMS header files. * Fri Jan 25 2008 - steve@icarus.com - Removed vvp32 support for x86_64 build. * Sun Feb 28 2007 - steve@icarus.com - Added formatting suitable for openSUSE packaging. iverilog-12_0/verinum.cc000066400000000000000000001260601435245347300153500ustar00rootroot00000000000000/* * Copyright (c) 1998-2021 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 "verinum.h" # include # include # include # include // Needed to get pow for as_double(). # include // Needed to get snprintf for as_string(). # include using namespace std; #if !defined(HAVE_LROUND) /* * If the system doesn't provide the lround function, then we provide * it ourselves here. It is simply the nearest integer, rounded away * from zero. */ extern "C" long int lround(double x) { if (x >= 0.0) return (long)floor(x+0.5); else return (long)ceil(x-0.5); } #endif static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c); verinum::verinum() : bits_(0), nbits_(0), has_len_(false), has_sign_(false), is_single_(false), string_flag_(false) { } verinum::verinum(const V*bits, unsigned nbits, bool has_len__) : has_len_(has_len__), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = nbits; bits_ = new V [nbits]; for (unsigned idx = 0 ; idx < nbits ; idx += 1) { bits_[idx] = bits[idx]; } } static string process_verilog_string_quotes(const string&str) { string res; int idx = 0; int str_len = str.length(); while (idx < str_len) { if (str[idx] == '\\') { idx += 1; assert(idx < str_len); switch (str[idx]) { case 'n': res = res + '\n'; idx += 1; break; case 't': res = res + '\t'; idx += 1; break; case 'v': res = res + '\v'; idx += 1; break; case 'f': res = res + '\f'; idx += 1; break; case 'a': res = res + '\a'; idx += 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { char byte_val = 0; int odx = 0; while (odx < 3 && idx+odx < str_len && str[idx+odx] >= '0' && str[idx+odx] <= '7') { byte_val = 8*byte_val + str[idx+odx]-'0'; odx += 1; } idx += odx; res = res + byte_val; break; } case 'x': { char byte_val = 0; int odx = 1; while (odx < 3 && idx+odx < str_len) { if (str[idx+odx] >= '0' && str[idx+odx] <= '9') { byte_val = 16*byte_val + str[idx+odx]-'0'; odx += 1; } else if (str[idx+odx] >= 'a' && str[idx+odx] <= 'f') { byte_val = 16*byte_val + str[idx+odx]-'a'+10; odx += 1; } else if (str[idx+odx] >= 'A' && str[idx+odx] <= 'F') { byte_val = 16*byte_val + str[idx+odx]-'A'+10; odx += 1; } else { break; } } idx += odx; res = res + byte_val; break; } default: res = res + str[idx]; idx += 1; break; } } else { res = res + str[idx]; idx += 1; } } return res; } verinum::verinum(const string&s) : has_len_(true), has_sign_(false), is_single_(false), string_flag_(true) { string str = process_verilog_string_quotes(s); nbits_ = str.length() * 8; // Special case: The string "" is 8 bits of 0. if (nbits_ == 0) { nbits_ = 8; bits_ = new V [nbits_]; bits_[0] = V0; bits_[1] = V0; bits_[2] = V0; bits_[3] = V0; bits_[4] = V0; bits_[5] = V0; bits_[6] = V0; bits_[7] = V0; return; } bits_ = new V [nbits_]; unsigned idx, cp; V*bp = bits_+nbits_; for (idx = nbits_, cp = 0 ; idx > 0 ; idx -= 8, cp += 1) { char ch = str[cp]; *(--bp) = (ch&0x80) ? V1 : V0; *(--bp) = (ch&0x40) ? V1 : V0; *(--bp) = (ch&0x20) ? V1 : V0; *(--bp) = (ch&0x10) ? V1 : V0; *(--bp) = (ch&0x08) ? V1 : V0; *(--bp) = (ch&0x04) ? V1 : V0; *(--bp) = (ch&0x02) ? V1 : V0; *(--bp) = (ch&0x01) ? V1 : V0; } } verinum::verinum(verinum::V val, unsigned n, bool h) : has_len_(h), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = n; bits_ = new V[nbits_]; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) bits_[idx] = val; } verinum::verinum(uint64_t val, unsigned n) : has_len_(true), has_sign_(false), is_single_(false), string_flag_(false) { nbits_ = n; bits_ = new V[nbits_]; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) { bits_[idx] = (val&1) ? V1 : V0; val >>= (uint64_t)1; } } /* The second argument is not used! It is there to make this * constructor unique. */ verinum::verinum(double val, bool) : has_len_(false), has_sign_(true), is_single_(false), string_flag_(false) { bool is_neg = false; double fraction; int exponent; const unsigned BITS_IN_LONG = 8*sizeof(long); /* We return `bx for a NaN or +/- infinity. */ if (val != val || (val && (val == 0.5*val))) { nbits_ = 1; bits_ = new V[nbits_]; bits_[0] = Vx; return; } /* Convert to a positive result. */ if (val < 0.0) { is_neg = true; val = -val; } /* Round to the nearest integer now, as this may increase the number of bits we need to allocate. */ val = round(val); /* Get the exponent and fractional part of the number. */ fraction = frexp(val, &exponent); nbits_ = exponent+1; bits_ = new V[nbits_]; /* If the value is small enough just use lround(). */ if (nbits_ <= BITS_IN_LONG) { long sval = lround(val); if (is_neg) sval = -sval; for (unsigned idx = 0; idx < nbits_; idx += 1) { bits_[idx] = (sval&1) ? V1 : V0; sval >>= 1; } /* Trim the result. */ signed_trim(); return; } unsigned nwords = (exponent-1)/BITS_IN_LONG; fraction = ldexp(fraction, (exponent-1) % BITS_IN_LONG + 1); if (nwords == 0) { unsigned long bits = (unsigned long) fraction; fraction = fraction - (double) bits; for (unsigned idx = 0; idx < nbits_; idx += 1) { bits_[idx] = (bits&1) ? V1 : V0; bits >>= 1; } } else { for (int wd = nwords; wd >= 0; wd -= 1) { unsigned long bits = (unsigned long) fraction; fraction = fraction - (double) bits; unsigned max_idx = (wd+1)*BITS_IN_LONG; if (max_idx > nbits_) max_idx = nbits_; for (unsigned idx = wd*BITS_IN_LONG; idx < max_idx; idx += 1) { bits_[idx] = (bits&1) ? V1 : V0; bits >>= 1; } fraction = ldexp(fraction, BITS_IN_LONG); } } /* Convert a negative number if needed. */ if (is_neg) { *this = -(*this); } /* Trim the result. */ signed_trim(); } /* This is used by the double constructor above. It is needed to remove * extra sign bits that can occur when calculating a negative value. */ void verinum::signed_trim() { /* Do we have any extra digits? */ unsigned tlen = nbits_-1; verinum::V sign = bits_[tlen]; while ((tlen > 0) && (bits_[tlen] == sign)) tlen -= 1; /* tlen now points to the first digit that is not the sign. * or bit 0. Set the length to include this bit and one proper * sign bit if needed. */ if (bits_[tlen] != sign) tlen += 1; tlen += 1; /* Trim the bits if needed. */ if (tlen < nbits_) { V* tbits = new V[tlen]; for (unsigned idx = 0; idx < tlen; idx += 1) tbits[idx] = bits_[idx]; delete[] bits_; bits_ = tbits; nbits_ = tlen; } } verinum::verinum(const verinum&that) { string_flag_ = that.string_flag_; nbits_ = that.nbits_; bits_ = new V[nbits_]; has_len_ = that.has_len_; has_sign_ = that.has_sign_; is_single_ = that.is_single_; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) bits_[idx] = that.bits_[idx]; } verinum::verinum(const verinum&that, unsigned nbits) { string_flag_ = that.string_flag_ && (that.nbits_ == nbits); nbits_ = nbits; bits_ = new V[nbits_]; has_len_ = true; has_sign_ = that.has_sign_; is_single_ = false; unsigned copy = nbits; if (copy > that.nbits_) copy = that.nbits_; for (unsigned idx = 0 ; idx < copy ; idx += 1) bits_[idx] = that.bits_[idx]; if (copy < nbits_) { if (has_sign_ || that.is_single_) { for (unsigned idx = copy ; idx < nbits_ ; idx += 1) bits_[idx] = bits_[idx-1]; } else { for (unsigned idx = copy ; idx < nbits_ ; idx += 1) bits_[idx] = verinum::V0; } } } verinum::verinum(int64_t that) : has_len_(false), has_sign_(true), is_single_(false), string_flag_(false) { int64_t tmp; if (that < 0) tmp = (that+1)/2; else tmp = that/2; nbits_ = 1; while (tmp != 0) { nbits_ += 1; tmp /= 2; } nbits_ += 1; bits_ = new V[nbits_]; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) { bits_[idx] = (that & 1)? V1 : V0; that >>= 1; } } verinum::~verinum() { delete[]bits_; } verinum& verinum::operator= (const verinum&that) { if (this == &that) return *this; if (nbits_ != that.nbits_) { delete[]bits_; nbits_ = that.nbits_; bits_ = new V[that.nbits_]; } for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) bits_[idx] = that.bits_[idx]; has_len_ = that.has_len_; has_sign_ = that.has_sign_; is_single_ = that.is_single_; string_flag_ = that.string_flag_; return *this; } verinum::V verinum::get(unsigned idx) const { assert(idx < nbits_); return bits_[idx]; } verinum::V verinum::set(unsigned idx, verinum::V val) { assert(idx < nbits_); return bits_[idx] = val; } void verinum::set(unsigned off, const verinum&val) { assert(off + val.len() <= nbits_); for (unsigned idx = 0 ; idx < val.len() ; idx += 1) bits_[off+idx] = val[idx]; } unsigned verinum::as_unsigned() const { if (nbits_ == 0) return 0; if (!is_defined()) return 0; unsigned val = 0; unsigned mask = 1; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1) if (bits_[idx] == V1) { if (mask == 0) return ~mask; val |= mask; } return val; } unsigned long verinum::as_ulong() const { if (nbits_ == 0) return 0; if (!is_defined()) return 0; unsigned long val = 0; unsigned long mask = 1; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1) if (bits_[idx] == V1) { if (mask == 0) return ~mask; val |= mask; } return val; } uint64_t verinum::as_ulong64() const { if (nbits_ == 0) return 0; if (!is_defined()) return 0; uint64_t val = 0; uint64_t mask = 1; for (unsigned idx = 0 ; idx < nbits_ ; idx += 1, mask <<= 1) if (bits_[idx] == V1) { if (mask == 0) return ~mask; val |= mask; } return val; } /* * This function returns the native long integer that represents the * value of this object. It accounts for sign extension if the value * is signed. * * If the value is undefined, return 0. * * This function presumes that the native format is 2s complement * (pretty safe these days) and masks/sets bits accordingly. If the * value is too large for the native form, it truncates the high bits. */ signed long verinum::as_long() const { #define IVLLBITS (8 * sizeof(long) - 1) if (nbits_ == 0) return 0; if (!is_defined()) return 0; signed long val = 0; unsigned diag_top = 0; unsigned top = nbits_; if (top > IVLLBITS) { diag_top = top; top = IVLLBITS; } int lost_bits=0; if (has_sign_ && (bits_[nbits_-1] == V1)) { val = -1; signed long mask = ~1L; for (unsigned idx = 0 ; idx < top ; idx += 1) { if (bits_[idx] == V0) val &= mask; mask = (mask << 1) | 1L; } if (diag_top) { for (unsigned idx = top; idx < diag_top; idx += 1) { if (bits_[idx] == V0) lost_bits=1; } } } else { signed long mask = 1; for (unsigned idx = 0 ; idx < top ; idx += 1, mask <<= 1) { if (bits_[idx] == V1) val |= mask; } if (diag_top) { for (unsigned idx = top; idx < diag_top; idx += 1) { if (bits_[idx] == V1) lost_bits=1; } } } if (lost_bits) cerr << "warning: verinum::as_long() truncated " << diag_top << " bits to " << IVLLBITS << ", returns " << val << endl; return val; #undef IVLLBITS } double verinum::as_double() const { if (nbits_ == 0) return 0.0; double val = 0.0; /* Do we have/want a signed value? */ if (has_sign_ && bits_[nbits_-1] == V1) { V carry = V1; for (unsigned idx = 0; idx < nbits_; idx += 1) { V sum = add_with_carry(~bits_[idx], V0, carry); if (sum == V1) val += pow(2.0, (double)idx); } val *= -1.0; } else { for (unsigned idx = 0; idx < nbits_; idx += 1) { if (bits_[idx] == V1) val += pow(2.0, (double)idx); } } return val; } string verinum::as_string() const { assert( nbits_%8 == 0 ); if (nbits_ == 0) return ""; string res; for (unsigned idx = nbits_ ; idx > 0 ; idx -= 8) { char char_val = 0; V*bp = bits_+idx; if (*(--bp) == V1) char_val |= 0x80; if (*(--bp) == V1) char_val |= 0x40; if (*(--bp) == V1) char_val |= 0x20; if (*(--bp) == V1) char_val |= 0x10; if (*(--bp) == V1) char_val |= 0x08; if (*(--bp) == V1) char_val |= 0x04; if (*(--bp) == V1) char_val |= 0x02; if (*(--bp) == V1) char_val |= 0x01; if (char_val == '"' || char_val == '\\') { char tmp[5]; snprintf(tmp, sizeof tmp, "\\%03o", char_val); res = res + tmp; } else if (isprint(char_val)) { res = res + char_val; } else { char tmp[5]; snprintf(tmp, sizeof tmp, "\\%03o", (unsigned char)char_val); res = res + tmp; } } return res; } bool verinum::is_before(const verinum&that) const { if (that.nbits_ > nbits_) return true; if (that.nbits_ < nbits_) return false; for (unsigned idx = nbits_ ; idx > 0 ; idx -= 1) { if (bits_[idx-1] < that.bits_[idx-1]) return true; if (bits_[idx-1] > that.bits_[idx-1]) return false; } return false; } bool verinum::is_defined() const { for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) { if (bits_[idx] == Vx) return false; if (bits_[idx] == Vz) return false; } return true; } bool verinum::is_zero() const { for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) if (bits_[idx] != V0) return false; return true; } bool verinum::is_negative() const { return (bits_[nbits_-1] == V1) && has_sign(); } unsigned verinum::significant_bits() const { unsigned sbits = nbits_; if (has_sign_) { V sgn_bit = bits_[sbits-1]; while ((sbits > 1) && (bits_[sbits-2] == sgn_bit)) sbits -= 1; } else { while ((sbits > 1) && (bits_[sbits-1] == verinum::V0)) sbits -= 1; } return sbits; } void verinum::cast_to_int2() { for (unsigned idx = 0 ; idx < nbits_ ; idx += 1) { if (bits_[idx] == Vx || bits_[idx] == Vz) bits_[idx] = V0; } } verinum pad_to_width(const verinum&that, unsigned width) { if (that.len() >= width) return that; if (that.len() == 0) { verinum val (verinum::V0, width, that.has_len()); val.has_sign(that.has_sign()); return val; } verinum::V pad = that[that.len()-1]; if (pad==verinum::V1 && !that.has_sign() && !that.is_single()) pad = verinum::V0; if (that.has_len() && !that.has_sign() && !that.is_single()) { if (pad==verinum::Vx) pad = verinum::V0; if (pad==verinum::Vz) pad = verinum::V0; } verinum val(pad, width, that.has_len()); for (unsigned idx = 0 ; idx < that.len() ; idx += 1) val.set(idx, that[idx]); val.has_sign(that.has_sign()); if (that.is_string() && (width % 8) == 0) { val = verinum(val.as_string()); } return val; } verinum cast_to_width(const verinum&that, unsigned width) { if (that.has_len() && (that.len() == width)) return that; if (that.len() >= width) return verinum(that, width); if (that.len() == 0) { verinum val (verinum::V0, width, true); val.has_sign(that.has_sign()); return val; } verinum::V pad = that[that.len()-1]; if (pad==verinum::V1 && !that.has_sign() && !that.is_single()) pad = verinum::V0; if (that.has_len() && !that.has_sign() && !that.is_single()) { if (pad==verinum::Vx) pad = verinum::V0; if (pad==verinum::Vz) pad = verinum::V0; } verinum val(pad, width, true); for (unsigned idx = 0 ; idx < that.len() ; idx += 1) val.set(idx, that[idx]); val.has_sign(that.has_sign()); return val; } /* * This function returns a version of the verinum that has only as * many bits as are needed to accurately represent the value. It takes * into account the signedness of the value. * * If the input value has a definite length, then that value is just * returned as is. */ verinum trim_vnum(const verinum&that) { unsigned tlen; if (that.has_len()) return that; if (that.len() < 2) return that; if (that.has_sign()) { unsigned top = that.len()-1; verinum::V sign = that.get(top); while ((top > 0) && (that.get(top) == sign)) top -= 1; /* top points to the first digit that is not the sign. Set the length to include this and one proper sign bit. */ if (that.get(top) != sign) top += 1; tlen = top+1; } else { /* If the result is unsigned and has an indefinite length, then trim off all but one leading zero. */ unsigned top = that.len()-1; while ((top > 0) && (that.get(top) == verinum::V0)) top -= 1; /* Now top is the index of the highest non-zero bit. If that turns out to the highest bit in the vector, then there is no trimming possible. */ if (top+1 == that.len()) return that; /* Make tlen wide enough to include the highest non-zero bit, plus one extra 0 bit. */ tlen = top+2; /* This can only happen when the verinum is all zeros, so make it a single bit wide. */ if (that.get(top) == verinum::V0) tlen -= 1; } verinum tmp (verinum::V0, tlen, false); tmp.has_sign(that.has_sign()); for (unsigned idx = 0 ; idx < tmp.len() ; idx += 1) tmp.set(idx, that.get(idx)); return tmp; } ostream& operator<< (ostream&o, verinum::V v) { switch (v) { case verinum::V0: o << "0"; break; case verinum::V1: o << "1"; break; case verinum::Vx: o << "x"; break; case verinum::Vz: o << "z"; break; } return o; } /* * This operator is used by various dumpers to write the Verilog * number in a Verilog format. */ ostream& operator<< (ostream&o, const verinum&v) { if (v.is_string()) { o << "\"" << v.as_string() << "\""; return o; } /* If the verinum number has a fixed length, dump all the bits literally. This is how we express the fixed length in the output. */ if (v.has_len()) { o << v.len(); } /* If the number is fully defined (no x or z) then print it out as a decimal number. */ unsigned dec_len = 8*sizeof(int); /* avoid 32/64 bit differences. */ if (! v.has_sign()) dec_len -= 1; /* an unsigned number. */ if (v.is_defined() && v.len() <= dec_len) { if (v.has_sign()) o << "'sd" << v.as_long(); else o << "'d" << v.as_ulong(); return o; } /* Oh, well. Print the minimum to get the value properly displayed. */ if (v.has_sign()) o << "'sb"; else o << "'b"; if (v.len() == 0) { o << "0"; return o; } verinum::V trim_left = v.get(v.len()-1); unsigned idx; if (v.has_sign()) { for (idx = v.len()-1; idx > 0; idx -= 1) if (trim_left != v.get(idx-1)) break; o << trim_left; } else { idx = v.len(); } while (idx > 0) { o << v.get(idx-1); idx -= 1; } return o; } verinum::V operator == (const verinum&left, const verinum&right) { verinum::V left_pad = verinum::V0; verinum::V right_pad = verinum::V0; if (left.has_sign() && right.has_sign()) { left_pad = left.get(left.len()-1); right_pad = right.get(right.len()-1); if (left_pad == verinum::V1 && right_pad == verinum::V0) return verinum::V0; if (left_pad == verinum::V0 && right_pad == verinum::V1) return verinum::V0; } unsigned max_len = left.len(); if (right.len() > max_len) max_len = right.len(); for (unsigned idx = 0 ; idx < max_len ; idx += 1) { verinum::V left_bit = idx < left.len() ? left[idx] : left_pad; verinum::V right_bit = idx < right.len()? right[idx] : right_pad; if (left_bit != right_bit) return verinum::V0; } return verinum::V1; } verinum::V operator <= (const verinum&left, const verinum&right) { verinum::V left_pad = verinum::V0; verinum::V right_pad = verinum::V0; bool signed_calc = left.has_sign() && right.has_sign(); if (signed_calc) { left_pad = left.get(left.len()-1); right_pad = right.get(right.len()-1); if (left_pad == verinum::V1 && right_pad == verinum::V0) return verinum::V1; if (left_pad == verinum::V0 && right_pad == verinum::V1) return verinum::V0; } unsigned idx; for (idx = left.len() ; idx > right.len() ; idx -= 1) { if (left[idx-1] != right_pad) { // A change of padding for a negative left argument // denotes the left value is less than the right. return (signed_calc && (left_pad == verinum::V1)) ? verinum::V1 : verinum::V0; } } for (idx = right.len() ; idx > left.len() ; idx -= 1) { if (right[idx-1] != left_pad) { // A change of padding for a negative right argument // denotes the left value is not less than the right. return (signed_calc && (right_pad == verinum::V1)) ? verinum::V0 : verinum::V1; } } idx = right.len(); if (left.len() < idx) idx = left.len(); while (idx > 0) { if (left[idx-1] == verinum::Vx) return verinum::Vx; if (left[idx-1] == verinum::Vz) return verinum::Vx; if (right[idx-1] == verinum::Vx) return verinum::Vx; if (right[idx-1] == verinum::Vz) return verinum::Vx; if (left[idx-1] > right[idx-1]) return verinum::V0; if (left[idx-1] < right[idx-1]) return verinum::V1; idx -= 1; } return verinum::V1; } verinum::V operator < (const verinum&left, const verinum&right) { verinum::V left_pad = verinum::V0; verinum::V right_pad = verinum::V0; bool signed_calc = left.has_sign() && right.has_sign(); if (signed_calc) { left_pad = left.get(left.len()-1); right_pad = right.get(right.len()-1); if (left_pad == verinum::V1 && right_pad == verinum::V0) return verinum::V1; if (left_pad == verinum::V0 && right_pad == verinum::V1) return verinum::V0; } unsigned idx; for (idx = left.len() ; idx > right.len() ; idx -= 1) { if (left[idx-1] != right_pad) { // A change of padding for a negative left argument // denotes the left value is less than the right. return (signed_calc && (left_pad == verinum::V1)) ? verinum::V1 : verinum::V0; } } for (idx = right.len() ; idx > left.len() ; idx -= 1) { if (right[idx-1] != left_pad) { // A change of padding for a negative right argument // denotes the left value is not less than the right. return (signed_calc && (right_pad == verinum::V1)) ? verinum::V0 : verinum::V1; } } while (idx > 0) { if (left[idx-1] == verinum::Vx) return verinum::Vx; if (left[idx-1] == verinum::Vz) return verinum::Vx; if (right[idx-1] == verinum::Vx) return verinum::Vx; if (right[idx-1] == verinum::Vz) return verinum::Vx; if (left[idx-1] > right[idx-1]) return verinum::V0; if (left[idx-1] < right[idx-1]) return verinum::V1; idx -= 1; } return verinum::V0; } static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c) { unsigned sum = 0; switch (c) { case verinum::Vx: case verinum::Vz: c = verinum::Vx; return verinum::Vx; case verinum::V0: break; case verinum::V1: sum += 1; } switch (l) { case verinum::Vx: case verinum::Vz: c = verinum::Vx; return verinum::Vx; case verinum::V0: break; case verinum::V1: sum += 1; break; } switch (r) { case verinum::Vx: case verinum::Vz: c = verinum::Vx; return verinum::Vx; case verinum::V0: break; case verinum::V1: sum += 1; break; } if (sum & 2) c = verinum::V1; else c = verinum::V0; if (sum & 1) return verinum::V1; else return verinum::V0; } verinum operator ~ (const verinum&left) { verinum val = left; for (unsigned idx = 0 ; idx < val.len() ; idx += 1) switch (val[idx]) { case verinum::V0: val.set(idx, verinum::V1); break; case verinum::V1: val.set(idx, verinum::V0); break; default: val.set(idx, verinum::Vx); break; } return val; } /* * Addition and subtraction works a bit at a time, from the least * significant up to the most significant. The result is signed only * if both of the operands are signed. If either operand is unsized, * the result is expanded as needed to prevent overflow. */ verinum operator + (const verinum&left, const verinum&right) { const bool has_len_flag = left.has_len() && right.has_len(); const bool signed_flag = left.has_sign() && right.has_sign(); unsigned min_len = min(left.len(), right.len()); unsigned max_len = max(left.len(), right.len()); // If either the left or right values are undefined, the // entire result is undefined. if (!left.is_defined() || !right.is_defined()) { unsigned len = has_len_flag ? max_len : 1; verinum result (verinum::Vx, len, has_len_flag); result.has_sign(signed_flag); return result; } verinum::V*val_bits = new verinum::V[max_len+1]; verinum::V carry = verinum::V0; for (unsigned idx = 0 ; idx < min_len ; idx += 1) val_bits[idx] = add_with_carry(left[idx], right[idx], carry); verinum::V rpad = sign_bit(right); verinum::V lpad = sign_bit(left); if (left.len() > right.len()) { for (unsigned idx = min_len ; idx < max_len ; idx += 1) val_bits[idx] = add_with_carry(left[idx], rpad, carry); } else { for (unsigned idx = min_len ; idx < max_len ; idx += 1) val_bits[idx] = add_with_carry(lpad, right[idx], carry); } unsigned len = max_len; if (!has_len_flag) { val_bits[max_len] = add_with_carry(lpad, rpad, carry); if (signed_flag) { if (val_bits[max_len] != val_bits[max_len-1]) len += 1; } else { if (val_bits[max_len] != verinum::V0) len += 1; } } verinum result (val_bits, len, has_len_flag); result.has_sign(signed_flag); delete[]val_bits; return result; } verinum operator - (const verinum&left, const verinum&right) { const bool has_len_flag = left.has_len() && right.has_len(); const bool signed_flag = left.has_sign() && right.has_sign(); unsigned min_len = min(left.len(), right.len()); unsigned max_len = max(left.len(), right.len()); // If either the left or right values are undefined, the // entire result is undefined. if (!left.is_defined() || !right.is_defined()) { unsigned len = has_len_flag ? max_len : 1; verinum result (verinum::Vx, len, has_len_flag); result.has_sign(signed_flag); return result; } verinum::V*val_bits = new verinum::V[max_len+1]; verinum::V carry = verinum::V1; for (unsigned idx = 0 ; idx < min_len ; idx += 1) val_bits[idx] = add_with_carry(left[idx], ~right[idx], carry); verinum::V rpad = sign_bit(right); verinum::V lpad = sign_bit(left); if (left.len() > right.len()) { for (unsigned idx = min_len ; idx < max_len ; idx += 1) val_bits[idx] = add_with_carry(left[idx], ~rpad, carry); } else { for (unsigned idx = min_len ; idx < max_len ; idx += 1) val_bits[idx] = add_with_carry(lpad, ~right[idx], carry); } unsigned len = max_len; if (signed_flag && !has_len_flag) { val_bits[max_len] = add_with_carry(lpad, ~rpad, carry); if (val_bits[max_len] != val_bits[max_len-1]) len += 1; } verinum result (val_bits, len, has_len_flag); result.has_sign(signed_flag); delete[]val_bits; return result; } verinum operator - (const verinum&right) { const bool has_len_flag = right.has_len(); const bool signed_flag = right.has_sign(); unsigned len = right.len(); // If either the left or right values are undefined, the // entire result is undefined. if (!right.is_defined()) { verinum result (verinum::Vx, has_len_flag ? len : 1, has_len_flag); result.has_sign(signed_flag); return result; } verinum::V*val_bits = new verinum::V[len+1]; verinum::V carry = verinum::V1; for (unsigned idx = 0 ; idx < len ; idx += 1) val_bits[idx] = add_with_carry(verinum::V0, ~right[idx], carry); if (signed_flag && !has_len_flag) { val_bits[len] = add_with_carry(verinum::V0, ~sign_bit(right), carry); if (val_bits[len] != val_bits[len-1]) len += 1; } verinum result (val_bits, len, has_len_flag); result.has_sign(signed_flag); delete[]val_bits; return result; } /* * This operator multiplies the left number by the right number. The * result is signed only if both of the operands are signed. If either * operand is unsized, the resulting number is as large as the sum of * the sizes of the operands. * * The algorithm used is successive shift and add operations, * implemented as the nested loops. */ verinum operator * (const verinum&left, const verinum&right) { const bool has_len_flag = left.has_len() && right.has_len(); const bool signed_flag = left.has_sign() && right.has_sign(); const unsigned l_len = left.len(); const unsigned r_len = right.len(); unsigned len = has_len_flag ? max(l_len, r_len) : l_len + r_len; // If either the left or right values are undefined, the // entire result is undefined. if (!left.is_defined() || !right.is_defined()) { verinum result (verinum::Vx, has_len_flag ? len : 1, has_len_flag); result.has_sign(signed_flag); return result; } verinum result(verinum::V0, len, has_len_flag); result.has_sign(signed_flag); verinum::V r_sign = sign_bit(right); for (unsigned rdx = 0 ; rdx < len ; rdx += 1) { verinum::V r_bit = rdx < r_len ? right.get(rdx) : r_sign; if (r_bit == verinum::V0) continue; verinum::V l_sign = sign_bit(left); verinum::V carry = verinum::V0; for (unsigned ldx = 0 ; ldx < (len - rdx) ; ldx += 1) { verinum::V l_bit = ldx < l_len ? left[ldx] : l_sign; result.set(ldx+rdx, add_with_carry(l_bit, result[rdx+ldx], carry)); } } return trim_vnum(result); } static verinum make_p_one(unsigned len, bool has_len, bool has_sign) { verinum tmp (verinum::V0, has_len ? len : 2, has_len); tmp.set(0, verinum::V1); tmp.has_sign(has_sign); return tmp; } static verinum make_m_one(unsigned len, bool has_len, bool has_sign) { verinum tmp (verinum::V1, has_len ? len : 1, has_len); tmp.has_sign(has_sign); return tmp; } static verinum recursive_pow(const verinum&left, verinum&right) { // If the exponent is zero, return a value of 1 if (right.is_zero()) { return make_p_one(left.len(), left.has_len(), left.has_sign()); } verinum result; if (right.get(0) == 1) { // The exponent is odd, so subtract 1 from it and recurse. // We know it's odd, so the subtraction is easy. right.set(0, verinum::V0); result = pow(left, right); result = left * result; } else { // The exponent is even, so divide it by 2 and recurse right = right >> 1; result = pow(left, right); result = result * result; } return result; } verinum pow(const verinum&left, const verinum&right) { verinum result; // We need positive and negative one in a few places. verinum p_one = make_p_one(left.len(), left.has_len(), left.has_sign()); verinum m_one = make_m_one(left.len(), left.has_len(), left.has_sign()); // If either the left or right values are undefined, the // entire result is undefined. if (!left.is_defined() || !right.is_defined()) { result = verinum(verinum::Vx, left.len(), left.has_len()); result.has_sign(left.has_sign()); // If the right value is zero we need to set the result to 1. } else if (right.is_zero()) { result = p_one; } else if (right.is_negative()) { // 0 ** is 'bx. if (left.is_zero()) { result = verinum(verinum::Vx, left.len(), left.has_len()); result.has_sign(left.has_sign()); // -1 ** is 1 or -1. Note that this must be done // before testing for +1 in case 'left' has a width of 1. } else if (left.has_sign() && left == m_one) { if (right.get(0) == verinum::V0) { result = p_one; } else { result = m_one; } // 1 ** is 1. } else if (left == p_one) { result = p_one; // Everything else is 0. } else { result = verinum(verinum::V0, left.len(), left.has_len()); result.has_sign(left.has_sign()); } } else { verinum exponent = right; result = recursive_pow(left, exponent); } return trim_vnum(result); } verinum operator << (const verinum&that, unsigned shift) { bool has_len_flag = that.has_len(); unsigned len = that.len(); if (!has_len_flag) len += shift; verinum result(verinum::V0, len, has_len_flag); result.has_sign(that.has_sign()); for (unsigned idx = shift ; idx < len ; idx += 1) result.set(idx, that.get(idx - shift)); return trim_vnum(result); } verinum operator >> (const verinum&that, unsigned shift) { bool has_len_flag = that.has_len(); unsigned len = that.len(); verinum::V sgn_bit = that.has_sign() ? that.get(len-1) : verinum::V0; if (shift >= len) { if (!has_len_flag) len = 1; verinum result(sgn_bit, len, has_len_flag); result.has_sign(that.has_sign()); return result; } if (!has_len_flag) len -= shift; verinum result(sgn_bit, len, has_len_flag); result.has_sign(that.has_sign()); for (unsigned idx = shift ; idx < that.len() ; idx += 1) result.set(idx-shift, that.get(idx)); return trim_vnum(result); } static verinum unsigned_divide(verinum num, verinum den, bool signed_result) { // We need the following calculations to be lossless. The // result will be cast to the required width by the caller. num.has_len(false); den.has_len(false); unsigned nwid = num.len(); while (nwid > 0 && (num.get(nwid-1) == verinum::V0)) nwid -= 1; unsigned dwid = den.len(); while (dwid > 0 && (den.get(dwid-1) == verinum::V0)) dwid -= 1; if (dwid > nwid) return verinum(verinum::V0, 1); den = den << (nwid-dwid); unsigned idx = nwid - dwid + 1; verinum result (verinum::V0, signed_result ? idx + 1 : idx); if (signed_result) { result.set(idx, verinum::V0); result.has_sign(true); } while (idx > 0) { if (den <= num) { verinum dif = num - den; num = dif; result.set(idx-1, verinum::V1); } den = den >> 1; idx -= 1; } return result; } static verinum unsigned_modulus(verinum num, verinum den) { // We need the following calculations to be lossless. The // result will be cast to the required width by the caller. num.has_len(false); den.has_len(false); unsigned nwid = num.len(); while (nwid > 0 && (num.get(nwid-1) == verinum::V0)) nwid -= 1; unsigned dwid = den.len(); while (dwid > 0 && (den.get(dwid-1) == verinum::V0)) dwid -= 1; if (dwid > nwid) return num; den = den << (nwid-dwid); unsigned idx = nwid - dwid + 1; while (idx > 0) { if (den <= num) { verinum dif = num - den; num = dif; } den = den >> 1; idx -= 1; } return num; } /* * This operator divides the left number by the right number. The result * is signed only if both of the operands are signed. */ verinum operator / (const verinum&left, const verinum&right) { const bool has_len_flag = left.has_len() && right.has_len(); const bool signed_flag = left.has_sign() && right.has_sign(); unsigned use_len = left.len(); // If either the left or right values are undefined, or the // right value is zero, the entire result is undefined. if (!left.is_defined() || !right.is_defined() || right.is_zero()) { verinum result (verinum::Vx, use_len, has_len_flag); result.has_sign(signed_flag); return result; } verinum result(verinum::Vz, use_len, has_len_flag); /* do the operation differently, depending on whether the result is signed or not. */ if (signed_flag) { if (use_len <= (8*sizeof(long) - 1)) { long l = left.as_long(); long r = right.as_long(); bool overflow = (l == LONG_MIN) && (r == -1); long v = overflow ? LONG_MIN : l / r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; } } else { verinum use_left, use_right; bool negative = false; if (left.is_negative()) { use_left = -left; negative = !negative; } else { use_left = left; } use_left.has_sign(false); if (right.is_negative()) { use_right = -right; negative = !negative; } else { use_right = right; } use_right.has_sign(false); result = unsigned_divide(use_left, use_right, true); if (negative) result = -result; } } else { if (use_len <= 8 * sizeof(unsigned long)) { /* Use native unsigned division to do the work. */ unsigned long l = left.as_ulong(); unsigned long r = right.as_ulong(); unsigned long v = l / r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; } } else { result = unsigned_divide(left, right, false); } } if (has_len_flag) result = cast_to_width(result, use_len); result.has_sign(signed_flag); return trim_vnum(result); } verinum operator % (const verinum&left, const verinum&right) { const bool has_len_flag = left.has_len() && right.has_len(); const bool signed_flag = left.has_sign() && right.has_sign(); unsigned use_len = left.len(); // If either the left or right values are undefined, or the // right value is zero, the entire result is undefined. if (!left.is_defined() || !right.is_defined() || right.is_zero()) { verinum result (verinum::Vx, use_len, has_len_flag); result.has_sign(signed_flag); return result; } verinum result(verinum::Vz, use_len, has_len_flag); if (signed_flag) { if (use_len <= 8*sizeof(long)) { /* Use native signed modulus to do the work. */ long l = left.as_long(); long r = right.as_long(); bool overflow = (l == LONG_MIN) && (r == -1); long v = overflow ? 0 : l % r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; } } else { verinum use_left, use_right; bool negative = false; if (left.is_negative()) { use_left = -left; negative = true; } else { use_left = left; } use_left.has_sign(false); if (right.is_negative()) { use_right = -right; } else { use_right = right; } use_right.has_sign(false); result = unsigned_modulus(use_left, use_right); if (negative) result = -result; } } else { if (use_len <= 8*sizeof(unsigned long)) { /* Use native unsigned modulus to do the work. */ unsigned long l = left.as_ulong(); unsigned long r = right.as_ulong(); unsigned long v = l % r; for (unsigned idx = 0 ; idx < use_len ; idx += 1) { result.set(idx, (v & 1)? verinum::V1 : verinum::V0); v >>= 1; } } else { result = unsigned_modulus(left, right); } } if (has_len_flag) result = cast_to_width(result, use_len); result.has_sign(signed_flag); return trim_vnum(result); } verinum concat(const verinum&left, const verinum&right) { if (left.is_string() && right.is_string()) { std::string tmp = left.as_string() + right.as_string(); verinum res (tmp); return res; } verinum res (verinum::V0, left.len() + right.len()); for (unsigned idx = 0 ; idx < right.len() ; idx += 1) res.set(idx, right.get(idx)); for (unsigned idx = 0 ; idx < left.len() ; idx += 1) res.set(idx+right.len(), left.get(idx)); return res; } verinum::V operator ~ (verinum::V l) { switch (l) { case verinum::V0: return verinum::V1; case verinum::V1: return verinum::V0; default: return verinum::Vx; } } verinum::V operator | (verinum::V l, verinum::V r) { if (l == verinum::V1) return verinum::V1; if (r == verinum::V1) return verinum::V1; if (l != verinum::V0) return verinum::Vx; if (r != verinum::V0) return verinum::Vx; return verinum::V0; } verinum::V operator & (verinum::V l, verinum::V r) { if (l == verinum::V0) return verinum::V0; if (r == verinum::V0) return verinum::V0; if (l != verinum::V1) return verinum::Vx; if (r != verinum::V1) return verinum::Vx; return verinum::V1; } verinum::V operator ^ (verinum::V l, verinum::V r) { if (l == verinum::V0) return bit4_z2x(r); if (r == verinum::V0) return bit4_z2x(l); if ((l == verinum::V1) && (r == verinum::V1)) return verinum::V0; return verinum::Vx; } iverilog-12_0/verinum.h000066400000000000000000000161751435245347300152170ustar00rootroot00000000000000#ifndef IVL_verinum_H #define IVL_verinum_H /* * Copyright (c) 1998-2021 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 "config.h" #ifdef HAVE_IOSFWD # include #else # include #endif /* * Numbers in Verilog are multibit strings, where each bit has 4 * possible values: 0, 1, x or z. The verinum number is store in * little-endian format. This means that if the long value is 2b'10, * get(0) is 0 and get(1) is 1. */ class verinum { public: enum V { V0 = 0, V1, Vx, Vz }; verinum(); explicit verinum(const std::string&str); verinum(const V*v, unsigned nbits, bool has_len =true); explicit verinum(V, unsigned nbits =1, bool has_len =true); verinum(uint64_t val, unsigned bits); verinum(double val, bool); verinum(const verinum&); // Create a signed number, with an unspecified number of bits. explicit verinum(int64_t val); // Copy only the specified number of bits from the // source. Also mark this number as has_len. verinum(const verinum&, unsigned bits); ~verinum(); verinum& operator= (const verinum&); // Number of stored bits in this number. unsigned len() const { return nbits_; } // A number "has a length" if the length was specified fixed // in some way. bool has_len(bool flag) { has_len_ = flag; return has_len_; } bool has_len() const { return has_len_; } bool has_sign(bool flag) { has_sign_ = flag; return has_sign_; } bool has_sign() const { return has_sign_; } // A number "is single" if it comes from a SystemVerilog 'N bit vector bool is_single(bool flag) { is_single_ = flag; return is_single_; } bool is_single() const { return is_single_; } // A number is "defined" if there are no x or z bits in its value. bool is_defined() const; bool is_zero() const; bool is_negative() const; // A number is "a string" if its value came directly from // an ASCII description instead of a number value. bool is_string() const { return string_flag_; } // Comparison for use in sorting algorithms. bool is_before(const verinum&that) const; // Number of significant bits in this number. unsigned significant_bits() const; // Convert 4-state to 2-state void cast_to_int2(); // Individual bits can be accessed with the get and set // methods. V get(unsigned idx) const; V set(unsigned idx, V val); void set(unsigned idx, const verinum&val); V operator[] (unsigned idx) const { return get(idx); } // Return the value as a native unsigned integer. If the value is // larger than can be represented by the returned type, return // the maximum value of that type. If the value has any x or z // bits or has zero width, return the value 0. uint64_t as_ulong64() const; unsigned as_unsigned() const; unsigned long as_ulong() const; signed long as_long() const; double as_double() const; std::string as_string() const; private: void signed_trim(); private: V* bits_; unsigned nbits_; bool has_len_; bool has_sign_; bool is_single_; // These are some convenience flags that help us do a better // job of pretty-printing values. bool string_flag_; }; /* * This returns the sign bit of the verinum value. If the value is * unsigned, then return an implicit sign bit of 0. Otherwise, return * the high bit. */ inline verinum::V sign_bit(const verinum&val) { if (val.has_sign()) return val.get(val.len()-1); else return verinum::V0; } /* Return a verinum that has the same value as the input, but is at least as wide as the requested width. This may involve sign extension, if the value is signed. */ extern verinum pad_to_width(const verinum&, unsigned width); /* Return a verinum that has the same value as the input, but is exactly the requested width. This may involve sign extension, if the value is signed. The returned verinum will have fixed width. */ extern verinum cast_to_width(const verinum&, unsigned width); /* Return a verinum that is minimal. That is, it has only the length needed to accurately represent the contained value, signed or not. */ extern verinum trim_vnum(const verinum&); extern std::ostream& operator<< (std::ostream&, const verinum&); extern std::ostream& operator<< (std::ostream&, verinum::V); inline verinum::V bit4_z2x(verinum::V bit) { return bit<2? bit : verinum::Vx; /* Relies on V0 and V1 being <2 */} extern verinum::V operator ~ (verinum::V l); extern verinum::V operator | (verinum::V l, verinum::V r); extern verinum::V operator & (verinum::V l, verinum::V r); extern verinum::V operator ^ (verinum::V l, verinum::V r); extern verinum::V operator == (const verinum&left, const verinum&right); extern verinum::V operator <= (const verinum&left, const verinum&right); extern verinum::V operator < (const verinum&left, const verinum&right); inline verinum::V operator > (const verinum&left, const verinum&right) { return right < left; } inline verinum::V operator >= (const verinum&left, const verinum&right) { return right <= left; } inline verinum::V operator != (const verinum&left, const verinum&right) { return (left == right)? verinum::V0 : verinum::V1; } /* These are arithmetic operators. If any operand is unsized, they generally work to produce results that do not overflow. That means the result may expand or contract to hold the bits needed to hold the operation results accurately. It is up to the caller to truncate or pad if a specific width is expected. If all operands are sized, the normal Verilog rules for result size are used. */ extern verinum operator - (const verinum&right); extern verinum operator + (const verinum&left, const verinum&right); extern verinum operator - (const verinum&left, const verinum&right); extern verinum operator * (const verinum&left, const verinum&right); extern verinum operator / (const verinum&left, const verinum&right); extern verinum operator % (const verinum&left, const verinum&right); extern verinum pow(const verinum&left, const verinum&right); extern verinum operator<< (const verinum&left, unsigned shift); extern verinum operator>> (const verinum&left, unsigned shift); extern verinum concat(const verinum&left, const verinum&right); /* Bitwise not returns the ones complement. */ extern verinum operator ~ (const verinum&left); #endif /* IVL_verinum_H */ iverilog-12_0/verireal.cc000066400000000000000000000065131435245347300154740ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "compiler.h" # include "verireal.h" # include "verinum.h" # include # include # include # include # include # include using namespace std; verireal::verireal() { value_ = 0.0; } verireal::verireal(const char*txt) { char*tmp = new char[strlen(txt)+1]; char*cp = tmp; for (unsigned idx = 0 ; txt[idx] ; idx += 1) { if (txt[idx] == '_') continue; *cp++ = txt[idx]; } cp[0] = 0; value_ = strtod(tmp, 0); delete[]tmp; } verireal::verireal(long val) { value_ = (double)val; } verireal::verireal(double val) { value_ = val; } verireal::~verireal() { } long verireal::as_long() const { double out = value_; double outf; if (out >= 0.0) { outf = floor(out); if (out >= (outf + 0.5)) outf += 1.0; } else { outf = ceil(out); if (out <= (outf - 0.5)) outf -= 1.0; } return (long) outf; } int64_t verireal::as_long64(int shift) const { double out = value_ * pow(10.0,shift); double outf; if (out >= 0.0) { outf = floor(out); if (out >= (outf + 0.5)) outf += 1.0; } else { outf = ceil(out); if (out <= (outf - 0.5)) outf -= 1.0; } return (int64_t) outf; } double verireal::as_double() const { return value_; } verireal operator+ (const verireal&l, const verireal&r) { verireal res; res.value_ = l.value_ + r.value_; return res; } verireal operator- (const verireal&l, const verireal&r) { verireal res; res.value_ = l.value_ - r.value_; return res; } verireal operator* (const verireal&l, const verireal&r) { verireal res; res.value_ = l.value_ * r.value_; return res; } verireal operator/ (const verireal&l, const verireal&r) { verireal res; res.value_ = l.value_ / r.value_; return res; } verireal operator% (const verireal&l, const verireal&r) { verireal res; // Modulus of a real value is not supported by the standard, // but we support it as an extension. Assert that we are in // the correct state before doing the operation. assert(gn_icarus_misc_flag); res.value_ = fmod(l.value_, r.value_); return res; } verireal operator- (const verireal&l) { verireal res; res.value_ = - l.value_; return res; } ostream& operator<< (ostream&out, const verireal&v) { out << showpoint << v.value_; return out; } iverilog-12_0/verireal.h000066400000000000000000000051631435245347300153360ustar00rootroot00000000000000#ifndef IVL_verireal_H #define IVL_verireal_H /* * Copyright (c) 1999-2021 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" #ifdef HAVE_IOSFWD # include #else # include #endif class verinum; /* * This class holds a floating point decimal number. The number is * stored as an integer mantissa and a power of 10. The mantissa is an * integer so that decimal numbers in the source (which are decimal) * can be stored exactly. */ class verireal { friend std::ostream& operator<< (std::ostream&, const verireal&); friend verireal operator+ (const verireal&, const verireal&); friend verireal operator- (const verireal&, const verireal&); friend verireal operator* (const verireal&, const verireal&); friend verireal operator/ (const verireal&, const verireal&); friend verireal operator% (const verireal&, const verireal&); // Unary minus. friend verireal operator- (const verireal&); public: explicit verireal(); explicit verireal(const char*text); explicit verireal(long val); explicit verireal(double val); ~verireal(); // Return the value of the floating point number as an // integer, rounded as needed. The shift is the power of 10 to // multiply the value before calculating the result. So for // example if the value is 2.5 and shift == 1, the result // is 25. long as_long() const; int64_t as_long64(int shift =0) const; double as_double() const; private: double value_; }; extern std::ostream& operator<< (std::ostream&, const verireal&); extern verireal operator* (const verireal&, const verireal&); extern verireal operator/ (const verireal&, const verireal&); extern verireal operator% (const verireal&, const verireal&); extern verireal operator- (const verireal&); #endif /* IVL_verireal_H */ iverilog-12_0/veriuser.h000066400000000000000000000267141435245347300153760ustar00rootroot00000000000000#ifndef VERIUSER_H #define VERIUSER_H /* * Copyright (c) 2002-2019 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. */ /* * This header file contains the definitions and declarations needed * by an Icarus Verilog user using tf_ routines. * * NOTE 1: Icarus Verilog does not directly support tf_ routines. This * header file defines a tf_ compatibility later. The functions that * are implemented here are actually implemented using VPI routines. * * NOTE 2: The routines and definitions of the tf_ library were * clearly not designed to account for C++, or even ANSI-C. This * header file attempts to fix these problems in a source code * compatible way. In the end, though, it is not completely * possible. Instead, users should not use this or the acc_user.h * header files or functions in new applications, and instead use the * more modern vpi_user.h and VPI functions. * * This API is provided by Icarus Verilog only to support legacy software. */ #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_END } #else # define EXTERN_C_START # define EXTERN_C_END #endif #ifndef __GNUC__ # undef __attribute__ # define __attribute__(x) #endif EXTERN_C_START # include "_pli_types.h" /* * defines for tf_message */ #define ERR_MESSAGE 1 #define ERR_WARNING 2 #define ERR_ERROR 3 #define ERR_INTERNAL 4 #define ERR_SYSTEM 5 /* * These are some defines for backwards compatibility. They should not * be used in new code. */ #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif #ifndef __cplusplus # ifndef true # define true 1 # endif # ifndef false # define false 0 # endif # ifndef bool # define bool int # endif #endif /* * structure for veriusertfs array */ typedef struct t_tfcell { short type; /* usertask|userfunction|userrealfunction */ short data; /* data passed to user routine */ int (*checktf)(int user_data, int reason); int (*sizetf)(int user_data, int reason); int (*calltf)(int user_data, int reason); int (*misctf)(int user_data, int reason, int paramvc); char *tfname; /* name of the system task/function */ int forwref; /* usually set to 1 */ char *tfveritool; /* usually ignored */ char *tferrmessage; /* usually ignored */ char reserved[20]; /* reserved */ } s_tfcell, *p_tfcell; /* * Normal PLI1.0 modules export a veriusertfs array that contains all * the function definitions for use by the simulator. The user code is * expected to supply that array. The method of export varies amongst * Verilog simulators, but at least one vendor gets a pointer to the * veriusertfs array by calling a boot function that takes no * arguments and returns a pointer to the table. * * The Icarus Verilog bootstrap process is a little bit different, and * is described in the vpi_user.h header file. However, a fairly * simple adaptation to your application fixes it so that it * automatically boots with Icarus Verilog. * * The trick is to write a vlog_startup_routine that calls the * veriusertfs_register_table function. A simple example: * * static struct s_tfcell my_veriusertfs_table[] = { * [... table entries, null terminated ...] * }; * * // Cadence compatibility * struct s_tfcell* my_bootstrap(void) * { return my_veriusertfs_table; } * * // Icarus Verilog compatibility * static void veriusertfs_register(void) * { * veriusertfs_register_table(my_veriusertfs_table); * } * void (*vlog_startup_routines[])() = { &veriusertfs_register, 0 }; * * The veriusertfs_register function and vlog_startup_routines table * are specific to Icarus Verilog, and arrange for automatic loading * of the PLI1 application. The vvp program will treat this as any * other VPI module. * * By structuring the bootstrap process in this manner, it is * plausible to make source code compatibility with a variety of * Verilog simulators. * * NOTE: The cadpli module of Icarus Verilog also makes it possible to * be *binary* compatible with other simulators. Create the * my_bootstrap function and leave out the vlog_startup_routines, then * use the "-mcadpli" module to load it in compatibility mode. */ extern s_tfcell veriusertfs[]; extern void veriusertfs_register_table(p_tfcell vtable); #if defined(__MINGW32__) || defined (__CYGWIN__) extern __declspec(dllexport) void (*vlog_startup_routines[])(void); #endif #define usertask 1 #define userfunction 2 #define userrealfunction 3 /* callback reasons */ #define reason_checktf 1 #define reason_sizetf 2 #define reason_calltf 3 #define reason_paramvc 7 #define reason_synch 8 #define REASON_SYNCH reason_synch #define reason_finish 9 #define reason_reactivate 10 #define REASON_REACTIVATE reason_reactivate #define reason_rosynch 11 #define REASON_ROSYNCH reason_rosynch #define reason_endofcompile 16 /* These are values returned by tf_typep */ #define tf_nullparam 0 #define TF_NULLPARAM tf_nullparam #define tf_string 1 #define TF_STRING tf_string #define tf_readonly 10 #define TF_READONLY tf_readonly #define tf_readwrite 11 #define TF_READWRITE tf_readwrite #define tf_rwbitselect 12 #define TF_RWBITSELECT tf_rwbitselect #define tf_rwpartselect 13 #define TF_RWPARTSELECT tf_rwpartselect #define tf_rwmemselect 14 #define TF_RWMEMSELECT tf_rwmemselect #define tf_readonlyreal 15 #define TF_READONLYREAL tf_readonlyreal #define tf_readwritereal 16 #define TF_READWRITEREAL tf_readwritereal typedef struct t_tfnodeinfo { PLI_INT16 node_type; PLI_INT16 padding; union { struct t_vecval *vecval_p; struct t_strengthval *strengthval_p; PLI_BYTE8 *memoryval_p; double *read_value_p; } node_value; char* node_symbol; PLI_INT32 node_ngroups; PLI_INT32 node_vec_size; PLI_INT32 node_sign; PLI_INT32 node_ms_index; PLI_INT32 node_ls_index; PLI_INT32 node_mem_size; PLI_INT32 node_lhs_element; PLI_INT32 node_rhs_element; PLI_INT32*node_handle; } s_tfnodeinfo, *p_tfnodeinfo; /* values used in the node_type of the tfnodeinfo structure. */ #define tf_null_node 100 #define TF_NULL_NODE tf_null_node #define tf_reg_node 101 #define TF_REG_NODE tf_reg_node #define tf_integer_node 102 #define TF_INTEGER_NODE tf_integer_node #define tf_time_node 103 #define TF_TIME_NODE tf_time_node #define tf_netvector_node 104 #define TF_NETVECTOR_NODE tf_netvector_node #define tf_netscalar_node 105 #define TF_NETSCALAR_NODE tf_netscalar_node #define tf_memory_node 106 #define TF_MEMORY_NODE tf_memory_node #define tf_real_node 107 #define TF_REAL_NODE tf_real_node /* Structure used by the tf_exprinfo function. */ typedef struct t_tfexprinfo { PLI_INT16 expr_type; PLI_INT16 padding; struct t_vecval*expr_value_p; double real_value; char*expr_string; PLI_INT32 expr_ngroups; PLI_INT32 expr_vec_size; PLI_INT32 expr_sign; PLI_INT32 expr_lhs_select; PLI_INT32 expr_rhs_select; } s_tfexprinfo, *p_tfexprinfo; /* Extern functions from the library. */ extern void io_printf (const char *, ...) __attribute__((format (printf,1,2))); extern char* mc_scan_plusargs(char*plusarg); extern int tf_asynchoff(void); extern int tf_asynchon(void); extern int tf_dofinish(void); extern int tf_dostop(void); extern void tf_error(const char*, ...) __attribute__((format (printf,1,2))); extern struct t_tfexprinfo* tf_exprinfo(PLI_INT32 a, struct t_tfexprinfo*ip); extern char* tf_getcstringp(int nparam); extern PLI_BYTE8* tf_getinstance(void); extern int tf_getlongp(int*aof_highvalue, int pnum); extern PLI_INT32 tf_getp(PLI_INT32); extern PLI_INT32 tf_igetp(PLI_INT32, void*); extern double tf_getrealp(PLI_INT32); extern double tf_igetrealp(PLI_INT32, void*); extern char *tf_strgetp(PLI_INT32, PLI_INT32); extern char *tf_istrgetp(PLI_INT32, PLI_INT32, void*); extern char *tf_strgettime(void); extern PLI_INT32 tf_gettime(void); extern PLI_INT32 tf_getlongtime(PLI_INT32*); extern PLI_INT32 tf_igetlongtime(PLI_INT32*, void*); extern void tf_scale_longdelay(void*,PLI_INT32,PLI_INT32,PLI_INT32*,PLI_INT32*); extern void tf_unscale_longdelay(void*,PLI_INT32,PLI_INT32,PLI_INT32*,PLI_INT32*); extern void tf_scale_realdelay(void*,double,double*); extern void tf_unscale_realdelay(void*,double,double*); extern PLI_INT32 tf_gettimeprecision(void); extern PLI_INT32 tf_igettimeprecision(void*); extern PLI_INT32 tf_gettimeunit(void); extern PLI_INT32 tf_igettimeunit(void*); extern PLI_BYTE8* tf_getworkarea(void); extern PLI_INT32 tf_message(PLI_INT32 level, char*facility, char*messno, char*fmt, ...) __attribute__((format (printf,4,5))); extern void tf_multiply_long(PLI_INT32*aof_low1, PLI_INT32*aof_high1, PLI_INT32 aof_low2, PLI_INT32 aof_high2); extern void tf_real_to_long(double real, PLI_INT32*low, PLI_INT32*high); extern void tf_long_to_real(PLI_INT32 low, PLI_INT32 high, double *real); extern PLI_INT32 tf_nump(void); extern PLI_INT32 tf_inump(void*); /* IEEE1364 NOTE: tf_putlongp is listed as returning in in the header file shown in the standard, but as returning void in the detailed description of the function. So I call it void. */ extern void tf_putlongp(int pnum, int lowvalue, int highvalue); extern PLI_INT32 tf_putp(PLI_INT32, PLI_INT32); extern PLI_INT32 tf_iputp(PLI_INT32, PLI_INT32, void*); extern PLI_INT32 tf_putrealp(PLI_INT32, double); extern PLI_INT32 tf_iputrealp(PLI_INT32, double, void*); /* Activate the misctf function after a delay. The units are of the current scope. The tf_isetdelay variant specifies a particular system task instance to use as the context for the units. tf_getinstance gets that value. */ extern int tf_setdelay(PLI_INT32 delay); extern int tf_isetdelay(PLI_INT32 delay, void* sys); /* IEEE1364 NOTE: tf_setworkarea is listed as taking a PLI_BYTE8*, but that is silly, it really takes any kind of pointer. Taking void* is compatible with those who pass a PLI_BYTE8*. */ extern PLI_INT32 tf_setworkarea(void*workarea); /* Return the complete, hierarchical name of the current scope. The current scope is the scope containing the currently running system task call. */ extern char* tf_spname(void); extern char* tf_mipname(void); extern char* tf_imipname(void*); extern PLI_INT32 tf_synchronize(void); extern PLI_INT32 tf_isynchronize(void* sys); extern PLI_INT32 tf_rosynchronize(void); extern PLI_INT32 tf_irosynchronize(void* sys); extern PLI_INT32 tf_setrealdelay(double realdelay); extern PLI_INT32 tf_isetrealdelay(double realdelay, void*inst); extern PLI_INT32 tf_typep(PLI_INT32 narg); extern void tf_warning(const char*, ...) __attribute__((format (printf,1,2))); EXTERN_C_END #endif /* VERIUSER_H */ iverilog-12_0/version.c000066400000000000000000000037261435245347300152100ustar00rootroot00000000000000/* * Copyright (c) 2009-2015 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 "version_base.h" # include "version_tag.h" # include # include static void run_string(const char*txt) { const char*cp = txt; while (*cp) { if (cp[0] == '%' && cp[1] != 0) { switch (cp[1]) { case 'M': fprintf(stdout, "%d", VERSION_MAJOR); break; case 'n': fprintf(stdout, "%d", VERSION_MINOR); break; case 'E': fprintf(stdout, "%s", VERSION_EXTRA); break; case 'T': fprintf(stdout, "%s", VERSION_TAG); break; case '%': putc('%', stdout); break; default: break; } cp += 2; } else if (cp[0] == '\\' && cp[1] != 0) { switch (cp[1]) { case 'n': putc('\n', stdout); break; default: putc(cp[1], stdout); break; } cp += 2; } else { putc(cp[0], stdout); cp += 1; } } } int main(int argc, char*argv[]) { int idx; if (argc == 1) { printf("%s\n", VERSION); return 0; } run_string(argv[1]); for (idx = 2 ; idx < argc ; idx += 1) { printf(" "); run_string(argv[idx]); } return 0; } iverilog-12_0/version_base.h000066400000000000000000000007611435245347300162030ustar00rootroot00000000000000#ifndef VERSION /* * Edit this definition in version_base.in to define the base version * number for the compiled result. */ # define VERSION_MAJOR 12 # define VERSION_MINOR 0 /* * This will be appended to the version. Use this to mark development * versions and the like. */ # define VERSION_EXTRA " (stable)" # define VERSION_STRINGIFY(x) #x # define VERSION_STR(a,b,extra) VERSION_STRINGIFY(a.b) extra #define VERSION VERSION_STR(VERSION_MAJOR,VERSION_MINOR,VERSION_EXTRA) #endif iverilog-12_0/vhdlpp/000077500000000000000000000000001435245347300146445ustar00rootroot00000000000000iverilog-12_0/vhdlpp/Makefile.in000066400000000000000000000105741435245347300167200ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ # Look in the appropriate source directory for the C++ files. The one # exception to this is if we need to rebuild the lexor_keyword.cc file. # If we do, then we want to use the local version instead of the one is # $(srcdir). vpath lexor_keyword.cc . vpath %.cc $(srcdir)/../libmisc vpath %.cc $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include CC = @CC@ CXX = @CXX@ INSTALL = @INSTALL@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ YACC = @YACC@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. -I../libmisc else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../libmisc endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @EXTRALIBS@ M = StringHeap.o LineInfo.o O = main.o architec.o compiler.o entity.o std_funcs.o std_types.o \ expression.o package.o scope.o sequential.o subprogram.o vsignal.o vtype.o \ vtype_match.o \ architec_elaborate.o entity_elaborate.o expression_elaborate.o \ expression_evaluate.o \ sequential_elaborate.o \ vtype_elaborate.o \ entity_stream.o expression_stream.o vtype_stream.o \ lexor.o lexor_keyword.o parse.o \ parse_misc.o library.o vhdlreal.o vhdlint.o \ architec_emit.o entity_emit.o expression_emit.o package_emit.o \ sequential_emit.o subprogram_emit.o vtype_emit.o \ debug.o architec_debug.o expression_debug.o sequential_debug.o \ $M all: dep vhdlpp@EXEEXT@ check: all clean: rm -f *.o *~ parse.cc parse.h lexor.cc parse.output lexor_keyword.cc rm -rf dep vhdlpp@EXEEXT@ distclean: clean rm -f Makefile config.log rm -f stamp-vhdlpp_config-h vhdlpp_config.h cppcheck: $(O:.o=.cc) cppcheck --enable=all --std=c99 --std=c++03 -f \ -UYY_USER_INIT \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYSTYPE -U__SIZE_TYPE__ -Ufree \ $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in cd ..; ./config.status --file=vhdlpp/$@ dep: mkdir dep vhdlpp@EXEEXT@: $O $(CXX) -o vhdlpp@EXEEXT@ $(LDFLAGS) $O $(LIBS) %.o: $(srcdir)/../libmisc/%.cc $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep/$*.d %.o: %.cc vhdlpp_config.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep/$*.d lexor.o: lexor.cc parse.h parse.o: parse.cc lexor.cc: $(srcdir)/lexor.lex $(LEX) -s -olexor.cc $(srcdir)/lexor.lex # Use pattern rules to avoid parallel build issues (see pr3462585) parse%cc parse%h: $(srcdir)/parse%y $(YACC) --verbose -t --defines=parse.h -o parse.cc $< lexor_keyword.o: lexor_keyword.cc parse.h lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf gperf -o -i 7 --ignore-case -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false) install: all installdirs installfiles F = vhdlpp@EXEEXT@ installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vhdlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)" uninstall: rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@" stamp-vhdlpp_config-h: $(srcdir)/vhdlpp_config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=vhdlpp/vhdlpp_config.h vhplpp_config.h: stamp-vhdlpp_config-h -include $(patsubst %.o, dep/%.d, $O $M) iverilog-12_0/vhdlpp/README.txt000066400000000000000000000025331435245347300163450ustar00rootroot00000000000000 vhdlpp COMMAND LINE FLAGS: -D Debug flags. The token can be: * yydebug | no-yydebug * entities= -L Library path. Add the directory name to the front of the library search path. The library search path is initially empty. -V Display version on stdout -v Verbose: Display version on stderr, and enable verbose messages to stderr. -w Work path. This is the directory where the working directory is. LIBRARY FORMAT: The vhdlpp program stores libraries as directory that contain packages. The name of the directory (in lower case) is the name of the library as used on the "import" statement. Within that library, there are packages in files named .pkg. For example: /... sample/... test1.pkg test2.pkg bar/... test3.pkg Use the "+vhdl-libdir+" record in a config file to tell Icarus Verilog that is a place to look for libraries. Then in your VHDL code, access packages like this: library sample; library bar; use sample.test1.all; use bar.test3.all; The *.pkg files are just VHDL code containing only the package with the same name. When Icarus Verilog encounters the "use ..*;" statement, it looks for the .pkg file in the library and parses that file to get the package header declared therein. iverilog-12_0/vhdlpp/architec.cc000066400000000000000000000170651435245347300167460ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "architec.h" # include "expression.h" # include "parse_types.h" # include "sequential.h" // Need this for parse_errors? # include "parse_api.h" # include using namespace std; Architecture::Architecture(perm_string name, const ActiveScope&ref, list&s) : Scope(ref), name_(name), cur_component_(NULL), cur_process_(NULL) { statements_.splice(statements_.end(), s); } Architecture::~Architecture() { delete_all(statements_); ScopeBase::cleanup(); } bool Architecture::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const { if(Scope::find_constant(by_name, typ, exp)) return true; // Check generics in components if(cur_component_) { std::map::const_iterator c = new_components_.find(cur_component_->component_name()); if(c == new_components_.end()) c = old_components_.find(cur_component_->component_name()); assert(c != old_components_.end()); ComponentBase*base = c->second; const InterfacePort*generic = base->find_generic(by_name); if(!generic) return false; // apparently there is no such generic in the component Expression*e = cur_component_->find_generic_map(by_name); typ = generic->type; exp = e ? e : generic->expr; return true; } return false; } Variable* Architecture::find_variable(perm_string by_name) const { if(cur_process_) return cur_process_->find_variable(by_name); return ScopeBase::find_variable(by_name); } void Architecture::push_genvar_type(perm_string gname, const VType*gtype) { genvar_type_t tmp; tmp.name = gname; tmp.vtype = gtype; genvar_type_stack_.push_back(tmp); } void Architecture::pop_genvar_type(void) { assert(! genvar_type_stack_.empty()); genvar_type_stack_.pop_back(); } const VType* Architecture::probe_genvar_type(perm_string gname) { for (std::list::reverse_iterator cur = genvar_type_stack_.rbegin() ; cur != genvar_type_stack_.rend() ; ++cur) { if (cur->name == gname) return cur->vtype; } return 0; } void Architecture::push_genvar_emit(perm_string gname, const GenerateStatement*gen) { genvar_emit_t tmp; tmp.name = gname; tmp.gen = gen; genvar_emit_stack_.push_back(tmp); } void Architecture::pop_genvar_emit(void) { assert(! genvar_emit_stack_.empty()); genvar_emit_stack_.pop_back(); } const GenerateStatement* Architecture::probe_genvar_emit(perm_string gname) { for (std::list::reverse_iterator cur = genvar_emit_stack_.rbegin() ; cur != genvar_emit_stack_.rend() ; ++cur) { if (cur->name == gname) return cur->gen; } return 0; } Architecture::Statement::Statement() { } Architecture::Statement::~Statement() { } GenerateStatement::GenerateStatement(perm_string gname, std::list&s) : name_(gname) { statements_.splice(statements_.end(), s); } GenerateStatement::~GenerateStatement() { for_each(statements_.begin(), statements_.end(), ::delete_object()); } ForGenerate::ForGenerate(perm_string gname, perm_string genvar, ExpRange*rang, std::list&s) : GenerateStatement(gname, s), genvar_(genvar), lsb_(rang->lsb()), msb_(rang->msb()) { } ForGenerate::~ForGenerate() { } IfGenerate::IfGenerate(perm_string gname, Expression*cond, std::list&s) : GenerateStatement(gname, s), cond_(cond) { } IfGenerate::~IfGenerate() { } SignalAssignment::SignalAssignment(ExpName*name, list&rv) : lval_(name) { rval_.splice(rval_.end(), rv); } SignalAssignment::SignalAssignment(ExpName*name, Expression*rv) : lval_(name) { rval_.push_back(rv); } SignalAssignment::~SignalAssignment() { for (list::iterator cur = rval_.begin() ; cur != rval_.end() ; ++cur) { delete *cur; } delete lval_; } CondSignalAssignment::CondSignalAssignment(ExpName*target, std::list&options) : lval_(target) { options_.splice(options_.end(), options); } CondSignalAssignment::~CondSignalAssignment() { delete lval_; for(list::iterator it = options_.begin(); it != options_.end(); ++it) { delete *it; } } ComponentInstantiation::ComponentInstantiation(perm_string i, perm_string c, list*parms, list*ports) : iname_(i), cname_(c) { typedef pair::iterator,bool> insert_rc; while (parms && ! parms->empty()) { named_expr_t*cur = parms->front(); parms->pop_front(); insert_rc rc = generic_map_.insert(make_pair(cur->name(), cur->expr())); if (! rc.second) { cerr << "?:?: error: Duplicate map of generic " << cur->name() << " ignored." << endl; parse_errors += 1; } } while (ports && ! ports->empty()) { named_expr_t*cur = ports->front(); ports->pop_front(); insert_rc rc = port_map_.insert(make_pair(cur->name(), cur->expr())); if (! rc.second) { cerr << "?:?: error: Duplicate map of port " << cur->name() << " ignored." << endl; parse_errors += 1; } } } ComponentInstantiation::~ComponentInstantiation() { for (map::iterator it = generic_map_.begin() ; it != generic_map_.end() ; ++it) { delete it->second; } for (map::iterator it = port_map_.begin() ; it != port_map_.end(); ++it) { delete it->second; } } Expression*ComponentInstantiation::find_generic_map(perm_string by_name) const { map::const_iterator p = generic_map_.find(by_name); if(p == generic_map_.end()) return NULL; return p->second; } StatementList::StatementList(std::list*statement_list) { if(statement_list) statements_.splice(statements_.end(), *statement_list); } StatementList::~StatementList() { for(std::list::iterator it = statements_.begin(); it != statements_.end(); ++it) { delete *it; } } ProcessStatement::ProcessStatement(perm_string iname, const ActiveScope&ref, std::list*sensitivity_list, std::list*statements_list) : StatementList(statements_list), Scope(ref), iname_(iname) { if (sensitivity_list) sensitivity_list_.splice(sensitivity_list_.end(), *sensitivity_list); } ProcessStatement::~ProcessStatement() { for(std::list::iterator it = sensitivity_list_.begin(); it != sensitivity_list_.end(); ++it) { delete *it; } } iverilog-12_0/vhdlpp/architec.h000066400000000000000000000240461435245347300166050ustar00rootroot00000000000000#ifndef IVL_architec_H #define IVL_architec_H /* * Copyright (c) 2011-2021 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 "LineInfo.h" # include "scope.h" # include # include class ComponentInstantiation; class Entity; class Expression; class ExpName; class GenerateStatement; class ProcessStatement; class SequentialStmt; class Signal; class named_expr_t; class ExpRange; /* * The Architecture class carries the contents (name, statements, * etc.) of a parsed VHDL architecture. These objects are ultimately * put into entities. */ class Architecture : public Scope, public LineInfo { public: // Architectures contain concurrent statements, that are // derived from this nested class. class Statement : public LineInfo { public: Statement(); virtual ~Statement() =0; virtual int elaborate(Entity*ent, Architecture*arc); virtual int emit(std::ostream&out, Entity*ent, Architecture*arc); virtual void dump(std::ostream&out, int indent = 0) const; }; public: // Create an architecture from its name and its statements. // NOTE: The statement list passed in is emptied. Architecture(perm_string name, const ActiveScope&ref, std::list&s); ~Architecture(); perm_string get_name() const { return name_; } bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const; Variable* find_variable(perm_string by_name) const; // Sets the currently processed component (to be able to reach its parameters). void set_cur_component(ComponentInstantiation*component) { assert(!cur_component_ || !component); cur_component_ = component; } // Sets the currently elaborated process (to use its scope for variable resolving). void set_cur_process(ProcessStatement*process) { assert(!cur_process_ || !process); cur_process_ = process; } // Elaborate this architecture in the context of the given entity. int elaborate(Entity*entity); // These methods are used while in the scope of a generate // block to mark that a name is a genvar at this point. const VType* probe_genvar_type(perm_string); void push_genvar_type(perm_string gname, const VType*gtype); void pop_genvar_type(void); // These methods are used during EMIT to check for names that // are genvar names. const GenerateStatement* probe_genvar_emit(perm_string); void push_genvar_emit(perm_string gname, const GenerateStatement*); void pop_genvar_emit(void); // Emit this architecture to the given out file in the context // of the specified entity. This method is used by the // elaborate code to display generated code to the specified // output. int emit(std::ostream&out, Entity*entity); // The dump method writes a debug display to the given output. void dump(std::ostream&out, perm_string of_entity, int indent = 0) const; private: perm_string name_; // Concurrent statements local to this architecture std::list statements_; struct genvar_type_t { perm_string name; const VType*vtype; }; std::list genvar_type_stack_; struct genvar_emit_t { perm_string name; const GenerateStatement*gen; }; std::list genvar_emit_stack_; // Currently processed component (or NULL if none). ComponentInstantiation*cur_component_; // Currently elaborated process (or NULL if none). ProcessStatement*cur_process_; }; /* * This is a base class for various generate statement types. It holds * the generate statement name, and a list of substatements. */ class GenerateStatement : public Architecture::Statement { public: GenerateStatement(perm_string gname, std::list&s); ~GenerateStatement(); inline perm_string get_name() const { return name_; } protected: int elaborate_statements(Entity*ent, Architecture*arc); int emit_statements(std::ostream&out, Entity*ent, Architecture*arc); void dump_statements(std::ostream&out, int indent) const; private: perm_string name_; std::list statements_; }; class ForGenerate : public GenerateStatement { public: ForGenerate(perm_string gname, perm_string genvar, ExpRange*rang, std::list&s); ~ForGenerate(); int elaborate(Entity*ent, Architecture*arc); int emit(std::ostream&out, Entity*entity, Architecture*arc); void dump(std::ostream&out, int ident =0) const; private: perm_string genvar_; Expression*lsb_; Expression*msb_; }; class IfGenerate : public GenerateStatement { public: IfGenerate(perm_string gname, Expression*cond, std::list&s); ~IfGenerate(); int elaborate(Entity*ent, Architecture*arc); int emit(std::ostream&out, Entity*entity, Architecture*arc); private: Expression*cond_; }; /* * The SignalAssignment class represents the * concurrent_signal_assignment that is placed in an architecture. */ class SignalAssignment : public Architecture::Statement { public: SignalAssignment(ExpName*target, std::list&rval); SignalAssignment(ExpName*target, Expression*rval); ~SignalAssignment(); virtual int elaborate(Entity*ent, Architecture*arc); virtual int emit(std::ostream&out, Entity*entity, Architecture*arc); virtual void dump(std::ostream&out, int ident =0) const; private: ExpName*lval_; std::list rval_; }; class CondSignalAssignment : public Architecture::Statement { public: CondSignalAssignment(ExpName*target, std::list&options); ~CondSignalAssignment(); int elaborate(Entity*ent, Architecture*arc); int emit(std::ostream&out, Entity*entity, Architecture*arc); void dump(std::ostream&out, int ident =0) const; private: ExpName*lval_; std::list options_; // List of signals that should be emitted in the related process // sensitivity list. It is filled during the elaboration step. std::listsens_list_; }; class ComponentInstantiation : public Architecture::Statement { public: ComponentInstantiation(perm_string iname, perm_string cname, std::list*parms, std::list*ports); ~ComponentInstantiation(); virtual int elaborate(Entity*ent, Architecture*arc); virtual int emit(std::ostream&out, Entity*entity, Architecture*arc); virtual void dump(std::ostream&out, int indent =0) const; // Returns the expression that initializes a generic (or NULL if not found). Expression*find_generic_map(perm_string by_name) const; inline perm_string instance_name() const { return iname_; } inline perm_string component_name() const { return cname_; } private: perm_string iname_; perm_string cname_; std::map generic_map_; std::map port_map_; }; class StatementList : public Architecture::Statement { public: explicit StatementList(std::list*statement_list); virtual ~StatementList(); int elaborate(Entity*ent, Architecture*arc) { return elaborate(ent, static_cast(arc)); } int emit(std::ostream&out, Entity*ent, Architecture*arc) { return emit(out, ent, static_cast(arc)); } virtual int elaborate(Entity*ent, ScopeBase*scope); virtual int emit(std::ostream&out, Entity*entity, ScopeBase*scope); virtual void dump(std::ostream&out, int indent =0) const; std::list& stmt_list() { return statements_; } private: std::list statements_; }; // There is no direct VHDL counterpart to SV 'initial' statement, // but we can still use it during the translation process. class InitialStatement : public StatementList { public: explicit InitialStatement(std::list*statement_list) : StatementList(statement_list) {} int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void dump(std::ostream&out, int indent =0) const; }; // There is no direct VHDL counterpart to SV 'final' statement, // but we can still use it during the translation process. class FinalStatement : public StatementList { public: explicit FinalStatement(std::list*statement_list) : StatementList(statement_list) {} int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void dump(std::ostream&out, int indent =0) const; }; class ProcessStatement : public StatementList, public Scope { public: ProcessStatement(perm_string iname, const ActiveScope&ref, std::list*sensitivity_list, std::list*statement_list); ~ProcessStatement(); int elaborate(Entity*ent, Architecture*arc); int emit(std::ostream&out, Entity*entity, Architecture*arc); void dump(std::ostream&out, int indent =0) const; private: perm_string iname_; std::list sensitivity_list_; }; #endif /* IVL_architec_H */ iverilog-12_0/vhdlpp/architec_debug.cc000066400000000000000000000111301435245347300200770ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "architec.h" # include "expression.h" # include "sequential.h" # include # include # include using namespace std; void Architecture::dump(ostream&out, perm_string of_entity, int indent) const { out << setw(indent) << "" << "architecture " << name_ << " of entity " << of_entity << " file=" << get_fileline() << endl; dump_scope(out); for (list::const_iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { (*cur)->dump(out, indent+3); } } void Architecture::Statement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Architecture::Statement at file=" << get_fileline() << endl; } void ComponentInstantiation::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Component Instantiation " << "instance=" << iname_ << " of component=" << cname_ << ", file=" << get_fileline() << endl; for (map::const_iterator cur = port_map_.begin() ; cur != port_map_.end() ; ++cur) { out << setw(indent+2) <<""<< cur->first << " => ..." << endl; if (cur->second) cur->second->dump(out, indent+6); else out << setw(indent+6) <<""<< "OPEN" << endl; } } void GenerateStatement::dump_statements(ostream&out, int indent) const { for (list::const_iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { Statement*curp = *cur; curp->dump(out, indent); } } void ForGenerate::dump(ostream&out, int indent) const { out << setw(indent) << "" << "for " << genvar_ << " in" << endl; msb_->dump(out, indent+4); lsb_->dump(out, indent+4); out << setw(indent) << "" << "generate" << endl; dump_statements(out, indent+4); out << setw(indent) << "" << "end generate" << endl; } void SignalAssignment::dump(ostream&out, int indent) const { out << setw(indent) << "" << "SignalAssignment file=" << get_fileline() << endl; lval_->dump(out, indent+1); out << setw(indent+2) << "" << "<= ..." << endl; for (list::const_iterator cur = rval_.begin() ; cur != rval_.end() ; ++cur) { (*cur)->dump(out, indent+2); } } void CondSignalAssignment::dump(ostream&out, int indent) const { out << setw(indent) << "" << "CondSignalAssignment file=" << get_fileline() << endl; lval_->dump(out, indent+1); out << setw(indent+2) << "" << "<= ..." << endl; for(list::const_iterator it = options_.begin(); it != options_.end(); ++it) { (*it)->dump(out, indent+2); } } void StatementList::dump(ostream&out, int indent) const { out << setw(indent+3) << "" << "sequence of statements:" << endl; for (list::const_iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { (*cur)->dump(out, indent+4); } } void InitialStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "InitialStatement file=" << get_fileline() << endl; StatementList::dump(out, indent); } void FinalStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "FinalStatement file=" << get_fileline() << endl; StatementList::dump(out, indent); } void ProcessStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ProcessStatement name_=" << iname_ << " file=" << get_fileline() << endl; out << setw(indent+3) << "" << "Sensitivity_list:" << endl; for (list::const_iterator cur = sensitivity_list_.begin() ; cur != sensitivity_list_.end() ; ++cur) { (*cur)->dump(out, indent+4); } StatementList::dump(out, indent); } iverilog-12_0/vhdlpp/architec_elaborate.cc000066400000000000000000000217341435245347300207620ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "architec.h" # include "entity.h" # include "expression.h" # include "sequential.h" # include "subprogram.h" # include # include using namespace std; int Architecture::elaborate(Entity*entity) { int errors = 0; // Constant assignments in the architecture get their types // from the constant declaration itself. Elaborate the value // expression with the declared type. for (map::iterator cur = use_constants_.begin() ; cur != use_constants_.end() ; ++cur) { cur->second->val->elaborate_expr(entity, this, cur->second->typ); } for (map::iterator cur = cur_constants_.begin() ; cur != cur_constants_.end() ; ++cur) { cur->second->val->elaborate_expr(entity, this, cur->second->typ); } // Elaborate initializer expressions for signals & variables for (map::iterator cur = old_signals_.begin() ; cur != old_signals_.end() ; ++cur) { cur->second->elaborate(entity, this); } for (map::iterator cur = new_signals_.begin() ; cur != new_signals_.end() ; ++cur) { cur->second->elaborate(entity, this); } for (map::iterator cur = old_variables_.begin() ; cur != old_variables_.end() ; ++cur) { cur->second->elaborate(entity, this); } for (map::iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { cur->second->elaborate(entity, this); } // Elaborate subprograms for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { errors += (*it)->elaborate(); } } // Create 'initial' and 'final' blocks for implicit // initialization and clean-up actions if(!initializers_.empty()) statements_.push_front(new InitialStatement(&initializers_)); if(!finalizers_.empty()) statements_.push_front(new FinalStatement(&finalizers_)); for (list::iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { int cur_errors = (*cur)->elaborate(entity, this); errors += cur_errors; } if (errors > 0) { cerr << errors << " errors in " << name_ << " architecture of " << entity->get_name() << "." << endl; } return errors; } int Architecture::Statement::elaborate(Entity*, Architecture*) { return 0; } int ComponentInstantiation::elaborate(Entity*ent, Architecture*arc) { int errors = 0; ComponentBase*base = arc->find_component(cname_); if (base == 0) { cerr << get_fileline() << ": error: No component declaration" << " for instance " << iname_ << " of " << cname_ << "." << endl; return 1; } arc->set_cur_component(this); for (map::const_iterator cur = generic_map_.begin() ; cur != generic_map_.end() ; ++cur) { // check if generic from component instantiation // exists in the component declaration const InterfacePort*iparm = base->find_generic(cur->first); if (iparm == 0) { cerr << get_fileline() << ": warning: No generic " << cur->first << " in component " << cname_ << "." << endl; continue; } ExpName* tmp; if (cur->second && (tmp = dynamic_cast(cur->second))) errors += tmp->elaborate_rval(ent, arc, iparm); if (cur->second) errors += cur->second->elaborate_expr(ent, arc, iparm->type); } for (map::const_iterator cur = port_map_.begin() ; cur != port_map_.end() ; ++cur) { // check if a port from component instantiation // exists in the component declaration const InterfacePort*iport = base->find_port(cur->first); if (iport == 0) { cerr << get_fileline() << ": error: No port " << cur->first << " in component " << cname_ << "." << endl; errors += 1; continue; } ExpName* tmp; if (cur->second && (tmp = dynamic_cast(cur->second))) errors += tmp->elaborate_rval(ent, arc, iport); /* It is possible for the port to be explicitly unconnected. In that case, the Expression will be nil */ if (cur->second) cur->second->elaborate_expr(ent, arc, iport->type); } arc->set_cur_component(NULL); return errors; } int GenerateStatement::elaborate_statements(Entity*ent, Architecture*arc) { int errors = 0; for (list::iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { Architecture::Statement*curp = *cur; errors += curp->elaborate(ent, arc); } return errors; } int ForGenerate::elaborate(Entity*ent, Architecture*arc) { int errors = 0; arc->push_genvar_type(genvar_, lsb_->probe_type(ent, arc)); errors += elaborate_statements(ent, arc); arc->pop_genvar_type(); return errors; } int IfGenerate::elaborate(Entity*ent, Architecture*arc) { int errors = 0; errors += elaborate_statements(ent, arc); return errors; } int StatementList::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; for (std::list::iterator it = statements_.begin(); it != statements_.end(); ++it) { errors += (*it)->elaborate(ent, scope); } return errors; } int ProcessStatement::elaborate(Entity*ent, Architecture*arc) { int errors = 0; arc->set_cur_process(this); for (map::iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { cur->second->elaborate(ent, arc); } StatementList::elaborate(ent, arc); arc->set_cur_process(NULL); return errors; } int SignalAssignment::elaborate(Entity*ent, Architecture*arc) { int errors = 0; // Elaborate the l-value expression. errors += lval_->elaborate_lval(ent, arc, false); // The elaborate_lval should have resolved the type of the // l-value expression. We'll use that type to elaborate the // r-value. const VType*lval_type = lval_->peek_type(); if (lval_type == 0) { if (errors == 0) { errors += 1; cerr << get_fileline() << ": error: Unable to calculate type for l-value expression." << endl; } return errors; } for (list::iterator cur = rval_.begin() ; cur != rval_.end() ; ++cur) { errors += (*cur)->elaborate_expr(ent, arc, lval_type); } return errors; } int CondSignalAssignment::elaborate(Entity*ent, Architecture*arc) { int errors = 0; // Visitor to extract signal names occurring in the conditional // statements to create the sensitivity list struct name_extractor_t : public ExprVisitor { explicit name_extractor_t(list& name_list) : name_list_(name_list) {} void operator() (Expression*s) { if(const ExpName*name = dynamic_cast(s)) name_list_.push_back(name); } private: list& name_list_; } name_extractor(sens_list_); // Elaborate the l-value expression. errors += lval_->elaborate_lval(ent, arc, true); // The elaborate_lval should have resolved the type of the // l-value expression. We'll use that type to elaborate the // r-value. const VType*lval_type = lval_->peek_type(); if (lval_type == 0) { if (errors == 0) { errors += 1; cerr << get_fileline() << ": error: Unable to calculate type for l-value expression." << endl; } return errors; } for(list::iterator it = options_.begin(); it != options_.end(); ++it) { ExpConditional::case_t*cas = (*it); cas->elaborate_expr(ent, arc, lval_type); cas->visit(name_extractor); } return errors; } iverilog-12_0/vhdlpp/architec_emit.cc000066400000000000000000000257021435245347300177610ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "architec.h" # include "entity.h" # include "expression.h" # include "sequential.h" # include "subprogram.h" # include "vsignal.h" # include "std_types.h" # include # include # include using namespace std; int Scope::emit_signals(ostream&out, Entity*entity, ScopeBase*scope) { int errors = 0; for (map::iterator cur = new_signals_.begin() ; cur != new_signals_.end() ; ++cur) { errors += cur->second->emit(out, entity, scope); } return errors; } int Scope::emit_variables(ostream&out, Entity*entity, ScopeBase*scope) { int errors = 0; for (map::iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { errors += cur->second->emit(out, entity, scope); } return errors; } int Architecture::emit(ostream&out, Entity*entity) { int errors = 0; // Find typedefs that are present in the architecture body and // emit them, so that following code can use the name instead // of the full definition. typedef_context_t typedef_ctx; for (map::iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { if(is_global_type(cur->first)) continue; if(const VTypeDef*def = dynamic_cast(cur->second)) errors += def->emit_typedef(out, typedef_ctx); } for (map::iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { if(const VTypeDef*def = dynamic_cast(cur->second)) errors += def->emit_typedef(out, typedef_ctx); } for (map::iterator cur = use_constants_.begin() ; cur != use_constants_.end() ; ++cur) { out << "localparam " << cur->first << " = "; errors += cur->second->val->emit(out, entity, this); out << ";" << endl; } for (map::iterator cur = cur_constants_.begin() ; cur != cur_constants_.end() ; ++cur) { out << "localparam " << cur->first << " = "; errors += cur->second->val->emit(out, entity, this); out << ";" << endl; } errors += emit_signals(out, entity, this); errors += emit_variables(out, entity, this); for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++ cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { SubprogramHeader*subp = *it; // Do not emit unbounded functions, we will just need fixed instances later if(!subp->unbounded()) errors += subp->emit_package(out); } } for (list::iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { errors += (*cur)->emit(out, entity, this); } return errors; } int Architecture::Statement::emit(ostream&out, Entity*, Architecture*) { out << " // " << get_fileline() << ": internal error: " << "I don't know how to emit this statement! " << "type=" << typeid(*this).name() << endl; return 1; } int SignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; ivl_assert(*this, rval_.size() == 1); const Expression*rval = rval_.front(); out << "// " << get_fileline() << endl; out << "assign "; if(const ExpDelay*delayed = dynamic_cast(rval)) { out << "#("; delayed->peek_delay()->emit(out, ent, arc); out << ") "; rval = delayed->peek_expr(); } errors += lval_->emit(out, ent, arc); out << " = "; errors += rval->emit(out, ent, arc); out << ";" << endl; return errors; } int CondSignalAssignment::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; out << "// " << get_fileline() << endl; out << "always begin" << endl; bool first = true; for(list::iterator it = options_.begin(); it != options_.end(); ++it) { ExpConditional::case_t*cas = *it; ivl_assert(*this, cas->true_clause().size() == 1); const Expression*rval = cas->true_clause().front(); if(first) first = false; else out << "else "; if(Expression*cond = cas->condition()) { out << "if("; cond->emit(out, ent, arc); out << ") "; } out << endl; lval_->emit(out, ent, arc); out << " = "; rval->emit(out, ent, arc); out << ";" << endl; } // Sensitivity list first = true; out << "@("; for(list::const_iterator it = sens_list_.begin(); it != sens_list_.end(); ++it) { if(first) first = false; else out << ","; errors += (*it)->emit(out, ent, arc); } out << ");" << endl; out << "end" << endl; return errors; } int ComponentInstantiation::emit(ostream&out, Entity*ent, Architecture*arc) { const char*comma = ""; int errors = 0; arc->set_cur_component(this); if(ComponentBase*comp = arc->find_component(cname_)) { const std::vector& generics = comp->get_generics(); if(generics.size() != generic_map_.size()) // Display an error for generics that do not have neither // default nor component specific value defined for(vector::const_iterator it = generics.begin(); it != generics.end(); ++it) { if(!(*it)->expr && generic_map_.count((*it)->name) == 0) { cerr << get_fileline() << ": generic " << (*it)->name << "value is not defined" << endl; ++errors; } } } out << cname_; if (! generic_map_.empty()) { out << " #("; comma = ""; for (map::iterator cur = generic_map_.begin() ; cur != generic_map_.end() ; ++cur) { ivl_assert(*this, cur->second); out << comma << ".\\" << cur->first << " ("; errors += cur->second->emit(out, ent, arc); out << ")"; comma = ", "; } out << ")"; } out << " \\" << iname_ << " ("; comma = ""; for (map::iterator cur = port_map_.begin() ; cur != port_map_.end() ; ++cur) { // Skip unconnected ports if (cur->second == 0) continue; out << comma << ".\\" << cur->first << " ("; errors += cur->second->emit(out, ent, arc); out << ")"; comma = ", "; } out << ");" << endl; arc->set_cur_component(NULL); return errors; } int GenerateStatement::emit_statements(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; for (list::iterator cur = statements_.begin() ; cur != statements_.end() ; ++cur) { Architecture::Statement*curp = *cur; errors += curp->emit(out, ent, arc); } return errors; } int ForGenerate::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; out << "genvar \\" << get_name() << ":" << genvar_ << " ;" << endl; out << "for (\\" << get_name() << ":" << genvar_ << " = "; errors += lsb_->emit(out, ent, arc); out << "; \\" << get_name() << ":" << genvar_ << " <= "; errors += msb_->emit(out, ent, arc); out << "; \\" << get_name() << ":" << genvar_ << " = \\" << get_name() << ":" << genvar_ << " + 1)" << " begin : \\" << get_name() << endl; arc->push_genvar_emit(genvar_, this); errors += emit_statements(out, ent, arc); arc->pop_genvar_emit(); out << "end" << endl; return errors; } int IfGenerate::emit(ostream&out, Entity*ent, Architecture*arc) { int errors = 0; out << "if ("; cond_->emit(out, ent, arc); out << ") begin : \\" << get_name() << endl; errors += emit_statements(out, ent, arc); out << "end" << endl; return errors; } int StatementList::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; for (std::list::iterator it = statements_.begin(); it != statements_.end(); ++it) { errors += (*it)->emit(out, ent, scope); } return errors; } int InitialStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { out << "initial begin" << endl; int errors = StatementList::emit(out, ent, scope); out << "end" << endl; return errors; } int FinalStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { out << "final begin" << endl; int errors = StatementList::emit(out, ent, scope); out << "end" << endl; return errors; } /* * Emit a process statement using "always" syntax. * * Note that VHDL is different from Verilog, in that the sensitivity * list goes at the END of the statement list, not at the * beginning. In VHDL, all the statements are initially executed once * before blocking in the first wait on the sensitivity list. */ int ProcessStatement::emit(ostream&out, Entity*ent, Architecture*) { int errors = 0; /* Check if the process has no sensitivity list and ends up with * a final wait. If so, convert the process to an initial block. */ const WaitStmt*wait_stmt = NULL; if (!stmt_list().empty()) wait_stmt = dynamic_cast(stmt_list().back()); if (wait_stmt && wait_stmt->type() == WaitStmt::FINAL) out << "initial begin : "; else out << "always begin : "; out << peek_name() << endl; errors += emit_variables(out, ent, this); errors += StatementList::emit(out, ent, this); if (! sensitivity_list_.empty()) { out << "@("; const char*comma = 0; for (list::iterator cur = sensitivity_list_.begin() ; cur != sensitivity_list_.end() ; ++cur) { if (comma) out << comma; errors += (*cur)->emit(out, ent, this); comma = ", "; } out << "); /* sensitivity list for process */" << endl; } out << "end /* " << peek_name() << " */" << endl; return errors; } iverilog-12_0/vhdlpp/compiler.cc000066400000000000000000000017021435245347300167650ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "compiler.h" StringHeapLex lex_strings; StringHeapLex filename_strings; StringHeapLex gen_strings; iverilog-12_0/vhdlpp/compiler.h000066400000000000000000000025561435245347300166370ustar00rootroot00000000000000#ifndef IVL_compiler_H #define IVL_compiler_H /* * Copyright (c) 2011-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 const int GN_KEYWORD_2008 = 0x0001; // TRUE if processing is supposed to dump progress to stderr. extern bool verbose_flag; extern bool debug_elaboration; extern std::ofstream debug_log_file; // Stores strings created by the lexer extern StringHeapLex lex_strings; // Stores file names extern StringHeapLex filename_strings; // Stores generated strings (e.g. scope names) extern StringHeapLex gen_strings; #endif /* IVL_compiler_H */ iverilog-12_0/vhdlpp/debug.cc000066400000000000000000000333621435245347300162500ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2014 CERN * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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. * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704. */ # include "entity.h" # include "architec.h" # include "expression.h" # include "parse_types.h" # include "subprogram.h" # include "sequential.h" # include "vsignal.h" # include "vtype.h" # include # include # include using namespace std; static ostream& operator << (ostream&out, port_mode_t that) { switch (that) { case PORT_NONE: out << "NO-PORT"; break; case PORT_IN: out << "IN"; break; case PORT_OUT: out << "OUT"; break; default: out << "PORT-????"; break; } return out; } void dump_design_entities(ostream&file) { for (map::iterator cur = design_entities.begin() ; cur != design_entities.end() ; ++cur) { cur->second->dump(file); } } void ComponentBase::dump_generics(ostream&out, int indent) const { if (parms_.empty()) { out << setw(indent) << "" << "No generics" << endl; } else { out << setw(indent) << "" << "GENERICS:" << endl; for (vector::const_iterator cur = parms_.begin() ; cur != parms_.end() ; ++cur) { InterfacePort*item = *cur; out << setw(indent+2) << "" << item->name << " : " << item->mode << ", type="; if (item->type) item->type->show(out); else out << ""; out << ", file=" << item->get_fileline() << endl; } } } void ComponentBase::dump_ports(ostream&out, int indent) const { if (ports_.empty()) { out << setw(indent) << "" << "No ports" << endl; } else { out << setw(indent) << "" << "PORTS:" << endl; for (vector::const_iterator cur = ports_.begin() ; cur != ports_.end() ; ++cur) { InterfacePort*item = *cur; out << setw(indent+2) << "" << item->name << " : " << item->mode << ", type="; if (item->type) item->type->show(out); else out << ""; out << ", file=" << item->get_fileline() << endl; } } } void ScopeBase::dump_scope(ostream&out) const { // Dump types out << " -- imported types" << endl; for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { out << " " << cur->first << ": "; cur->second->show(out); out << endl; } out << " -- Types from this scope" << endl; for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { out << " " << cur->first << ": "; cur->second->show(out); out << endl; } // Dump constants out << " -- imported constants" << endl; for (map::const_iterator cur = use_constants_.begin() ; cur != use_constants_.end() ; ++cur) { out << " constant " << cur->first << " = "; out << endl; } out << " -- Constants from this scope" << endl; for (map::const_iterator cur = cur_constants_.begin() ; cur != cur_constants_.end() ; ++cur) { out << " constant " << cur->first << " = "; out << endl; } // Dump signal declarations out << " -- Signals" << endl; for (map::const_iterator cur = old_signals_.begin() ; cur != old_signals_.end() ; ++cur) { if (cur->second) cur->second->dump(out, 3); else out << " signal " << cur->first.str() << ": ???" << endl; } for (map::const_iterator cur = new_signals_.begin() ; cur != new_signals_.end() ; ++cur) { if (cur->second) cur->second->dump(out, 3); else out << " signal " << cur->first.str() << ": ???" << endl; } // Dump subprograms out << " -- Imported Subprograms" << endl; for (map::const_iterator cur = use_subprograms_.begin() ; cur != use_subprograms_.end() ; ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { const SubprogramHeader*subp = *it; out << " subprogram " << cur->first << " is" << endl; subp->dump(out); if(subp->body()) subp->body()->dump(out); out << " end subprogram " << cur->first << endl; } } out << " -- Subprograms from this scope" << endl; for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { const SubprogramHeader*subp = *it; out << " subprogram " << cur->first << " is" << endl; subp->dump(out); if(subp->body()) subp->body()->dump(out); out << " end subprogram " << cur->first << endl; } } // Dump component declarations out << " -- Components" << endl; for (map::const_iterator cur = old_components_.begin() ; cur != old_components_.end() ; ++cur) { out << " component " << cur->first << " is" << endl; cur->second->dump_generics(out); cur->second->dump_ports(out); out << " end component " << cur->first << endl; } for (map::const_iterator cur = new_components_.begin() ; cur != new_components_.end() ; ++cur) { out << " component " << cur->first << " is" << endl; cur->second->dump_generics(out); cur->second->dump_ports(out); out << " end component " << cur->first << endl; } } void Entity::dump(ostream&out, int indent) const { out << setw(indent) << "" << "entity " << get_name() << " file=" << get_fileline() << endl; dump_ports(out, indent+2); for (map::const_iterator cur = arch_.begin() ; cur != arch_.end() ; ++cur) { cur->second->dump(out, get_name(), indent); } } void SigVarBase::dump(ostream&out, int indent) const { out << setw(indent) << "" << "signal/variable " << name_ << " is "; if (type_) out << *type_; else out << "?NO TYPE?"; out << endl; } void Expression::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Expression [" << typeid(*this).name() << "]" << " at " << get_fileline()<< endl; } void ExpAggregate::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Aggregate expression at " << get_fileline() << endl; for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) elements_[idx]->dump(out, indent+2); } void ExpAggregate::element_t::dump(ostream&out, int indent) const { out << setw(indent) << "" << "choices:" << endl; for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) fields_[idx]->dump(out, indent+4); out << setw(indent) << "" << "expression:" << endl; val_->dump(out, indent+4); } void ExpAggregate::choice_t::dump(ostream&out, int indent) const { if (others()) { out << setw(indent) << "" << "=> others" << endl; return; } if (expr_.get()) { expr_->dump(out, indent); return; } if (range_.get()) { range_->dump(out, indent); return; } out << setw(indent) << "" << "?choice_t?" << endl; } void ExpTypeAttribute::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Attribute (type-related) " << name_ << " at " << get_fileline() << endl; base_->show(out); } void ExpObjAttribute::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Attribute (object-related) " << name_ << " at " << get_fileline() << endl; base_->dump(out, indent+4); } void ExpBinary::dump_operands(ostream&out, int indent) const { operand1_->dump(out, indent); operand2_->dump(out, indent); } void ExpBitstring::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Bit string " << value_.size() << "b\""; for (size_t idx = value_.size() ; idx > 0 ; idx -= 1) { out << value_[idx-1]; } out << "\"" << endl; } void ExpCharacter::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Character '" << value_ << "'" << " at " << get_fileline() << endl; } void ExpConditional::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Conditional expression at "<< get_fileline() << endl; for (list::const_iterator cur = options_.begin() ; cur != options_.end() ; ++cur) { (*cur)->dump(out, indent); } } void ExpConditional::case_t::dump(ostream&out, int indent) const { out << setw(indent) << "" << "when:" << endl; if (cond_) cond_->dump(out, indent+4); out << setw(indent) << "" << "do:" << endl; for (list::const_iterator cur = true_clause_.begin() ; cur != true_clause_.end() ; ++cur) { (*cur)->dump(out, indent+4); } } void ExpEdge::dump(ostream&out, int indent) const { out << setw(indent) << ""; switch (fun_) { case NEGEDGE: out << "negedge "; break; case ANYEDGE: out << "ANYedge "; break; case POSEDGE: out << "posedge "; } out << "at " << get_fileline() << endl; dump_operand1(out, indent+3); } void ExpFunc::dump(ostream&out, int indent) const { out << setw(indent) << "" << "function " << name_ << " has " << argv_.size() << " arguments:" << endl; for (size_t idx = 0 ; idx < argv_.size() ; idx += 1) { argv_[idx]->dump(out, indent+2); } } void ExpInteger::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Integer " << value_ << " at " << get_fileline() << endl; } void ExpReal::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Integer " << value_ << " at " << get_fileline() << endl; } void ExpLogical::dump(ostream&out, int indent) const { const char*fun_name = "?"; switch (fun_) { case AND: fun_name = "AND"; break; case OR: fun_name = "OR"; break; case NAND: fun_name = "NAND"; break; case NOR: fun_name = "NOR"; break; case XOR: fun_name = "XOR"; break; case XNOR: fun_name = "XNOR"; break; } out << setw(indent) << "" << "Logical " << fun_name << " at " << get_fileline() << endl; dump_operands(out, indent+4); } void ExpName::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ExpName(\"" << name_ << "\")" << " at " << get_fileline() << endl; if (prefix_.get()) prefix_->dump(out, indent+8); if (indices_) { for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { (*it)->dump(out, indent+6); } } } void ExpNameALL::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ExpNameALL at " << get_fileline() << endl; } void ExpRelation::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Relation "; switch (fun_) { case EQ: out << "="; break; case LT: out << "<"; break; case GT: out << ">"; break; case NEQ: out << "/="; break; case LE: out << "<="; break; case GE: out << ">="; break; } out << endl; dump_operands(out, indent+4); } void named_expr_t::dump(ostream&out, int indent) const { out << setw(indent) << "" << name_ << "=>"; expr_->dump(out, indent); } ostream& Expression::dump_inline(ostream&out) const { out << typeid(*this).name(); return out; } ostream& ExpInteger::dump_inline(ostream&out) const { out << value_; return out; } ostream& ExpReal::dump_inline(ostream&out) const { out << value_; return out; } void SubprogramBody::dump(ostream&fd) const { if (statements_== 0 || statements_->empty()) { fd << " " << endl; } else { for (list::const_iterator cur = statements_->begin() ; cur != statements_->end() ; ++cur) { SequentialStmt*curp = *cur; curp->dump(fd, 8); } } } void SubprogramHeader::dump(ostream&fd) const { fd << " " << name_; if (ports_->empty()) { fd << "()"; } else { fd << "("; list::const_iterator cur = ports_->begin(); InterfacePort*curp = *cur; fd << curp->name << ":"; curp->type->show(fd); for (++ cur ; cur != ports_->end() ; ++ cur) { curp = *cur; fd << "; " << curp->name << ":"; curp->type->show(fd); } fd << ")"; } fd << " return "; return_type_->show(fd); fd << endl; } iverilog-12_0/vhdlpp/entity.cc000066400000000000000000000052361435245347300164750ustar00rootroot00000000000000 /* * Copyright (c) 2011 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 "entity.h" # include "architec.h" # include using namespace std; std::map design_entities; ComponentBase::ComponentBase(perm_string name) : name_(name) { } ComponentBase::~ComponentBase() { for(std::vector::iterator it = ports_.begin() ; it != ports_.end(); ++it) delete *it; } void ComponentBase::set_interface(std::list*parms, std::list*ports) { if (parms) { while (! parms->empty()) { parms_.push_back(parms->front()); parms->pop_front(); } } if (ports) { while (! ports->empty()) { ports_.push_back(ports->front()); ports->pop_front(); } } } const InterfacePort* ComponentBase::find_port(perm_string my_name) const { for (size_t idx = 0 ; idx < ports_.size() ; idx += 1) { if (ports_[idx]->name == my_name) return ports_[idx]; } return 0; } const InterfacePort* ComponentBase::find_generic(perm_string my_name) const { for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) { if (parms_[idx]->name == my_name) return parms_[idx]; } return 0; } Entity::Entity(perm_string name) : ComponentBase(name) { bind_arch_ = 0; } Entity::~Entity() { for(map::reverse_iterator it = arch_.rbegin() ; it != arch_.rend(); ++it) delete it->second; } Architecture* Entity::add_architecture(Architecture*that) { if (Architecture*tmp = arch_ [that->get_name()]) { return tmp; } return arch_[that->get_name()] = that; } void Entity::set_declaration_l_value(perm_string nam, bool flag) { map::iterator cur = declarations_.find(nam); assert(cur != declarations_.end()); cur->second.reg_flag = flag; } iverilog-12_0/vhdlpp/entity.h000066400000000000000000000121451435245347300163340ustar00rootroot00000000000000#ifndef IVL_entity_H #define IVL_entity_H /* * Copyright (c) 2011-2021 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 # include # include # include "vtype.h" # include "StringHeap.h" # include "LineInfo.h" typedef enum { PORT_NONE=0, PORT_IN, PORT_OUT, PORT_INOUT } port_mode_t; class Architecture; class Expression; class InterfacePort : public LineInfo { public: InterfacePort(port_mode_t mod = PORT_NONE, perm_string nam = empty_perm_string, const VType*typ = NULL, Expression*exp = NULL) : mode(mod), name(nam), type(typ), expr(exp) {} explicit InterfacePort(const VType*typ) : mode(PORT_NONE), type(typ), expr(NULL) {} InterfacePort(const VType*typ, port_mode_t mod) : mode(mod), type(typ), expr(NULL) {} // Port direction from the source code. port_mode_t mode; // Name of the port from the source code perm_string name; // Name of interface type as given in the source code. const VType*type; // Default value expression (or nil) Expression*expr; }; /* * The ComponentBase class represents the base entity * declaration. When used as is, then this represents a forward * declaration of an entity. Elaboration will match it to a proper * entity. Or this can be the base class for a full-out Entity. */ class ComponentBase : public LineInfo { public: explicit ComponentBase(perm_string name); ~ComponentBase(); // Entities have names. perm_string get_name() const { return name_; } const InterfacePort* find_port(perm_string by_name) const; const InterfacePort* find_generic(perm_string by_name) const; const std::vector& get_generics() const { return parms_; } // Declare the ports for the entity. The parser calls this // method with a list of interface elements that were parsed // for the entity. This method collects those entities, and // empties the list in the process. void set_interface(std::list*parms, std::list*ports); void write_to_stream(std::ostream&fd) const; public: void dump_generics(std::ostream&out, int indent =0) const; void dump_ports(std::ostream&out, int indent = 0) const; private: perm_string name_; protected: std::vector parms_; std::vector ports_; }; /* * Entities are fully declared components. */ class Entity : public ComponentBase { public: explicit Entity(perm_string name); ~Entity(); // bind an architecture to the entity, and return the // Architecture that was bound. If there was a previous // architecture with the same name bound, then do not replace // the architecture and instead return the old // value. The caller can tell that the bind worked if the // returned pointer is the same as the passed pointer. Architecture* add_architecture(Architecture*); // After the architecture is bound, elaboration calls this // method to elaborate this entity. This method arranges for // elaboration to happen all the way through the architecture // that is bound to this entity. int elaborate(); // During elaboration, it may be discovered that a port is // used as an l-value in an assignment. This method tweaks the // declaration to allow for that case. void set_declaration_l_value(perm_string by_name, bool flag); int emit(std::ostream&out); void dump(std::ostream&out, int indent = 0) const; private: std::maparch_; Architecture*bind_arch_; std::map declarations_; int elaborate_generic_exprs_(void); int elaborate_ports_(void); }; /* * As the parser parses entities, it puts them into this map. It uses * a map because sometimes it needs to look back at an entity by name. */ extern std::map design_entities; /* * Elaborate the collected entities, and return the number of * elaboration errors. */ extern int elaborate_entities(void); extern int emit_entities(void); /* * Use this function to dump a description of the design entities to a * file. This is for debug, not for any useful purpose. */ extern void dump_design_entities(std::ostream&file); #endif /* IVL_entity_H */ iverilog-12_0/vhdlpp/entity_elaborate.cc000066400000000000000000000073361435245347300205160ustar00rootroot00000000000000/* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "entity.h" # include "compiler.h" # include "architec.h" # include "vtype.h" # include # include # include # include # include # include using namespace std; int elaborate_entities(void) { int errors = 0; for (map::iterator cur = design_entities.begin() ; cur != design_entities.end() ; ++cur) { errors += cur->second->elaborate(); } return errors; } int Entity::elaborate() { int errors = 0; if (verbose_flag) cerr << "Elaborate entity " << get_name() << "..." << endl; if (arch_.empty()) { cerr << get_fileline() << ": error: " << "No architectures to choose from for entity " << get_name() << "." << endl; return 1; } /* FIXME: the architecture for the entity should be chosen in configuration block (not yet implemented). Multiple architectures are allowed in general */ if (arch_.size() > 1) { cerr << get_fileline() << ": sorry: " << "Multiple architectures for an entity are not yet supported" << ". Architectures for entity " << get_name() << " are:" << endl; for (map::const_iterator cur = arch_.begin() ; cur != arch_.end() ; ++cur) { cerr << get_fileline() << ": : " << cur->first << " at " << cur->second->get_fileline() << endl; } //errors += 1; } /* FIXME: here we should look at configuration block */ bind_arch_ = arch_.begin()->second; if (verbose_flag) cerr << "For entity " << get_name() << ", choosing architecture " << bind_arch_->get_name() << "." << endl; errors += elaborate_generic_exprs_(); errors += elaborate_ports_(); errors += bind_arch_->elaborate(this); return errors; } int Entity::elaborate_generic_exprs_() { int errors = 0; for (vector::const_iterator cur = parms_.begin() ; cur != parms_.end() ; ++cur) { InterfacePort*curp = *cur; if(curp->expr) curp->expr->elaborate_expr(this, 0, curp->type); } return errors; } int Entity::elaborate_ports_(void) { int errors = 0; for (std::vector::const_iterator cur = ports_.begin() ; cur != ports_.end() ; ++cur) { InterfacePort*cur_port = *cur; const VType*type = cur_port->type; if (type == 0) { cerr << get_fileline() << ": error: " << "Giving up on unknown type for port " << cur_port->name << "." << endl; errors += 1; continue; } // Elaborate the type to elaborate any expressions that // are used by the types. errors += type->elaborate(this, bind_arch_); VType::decl_t cur_decl; cur_decl.type = type; declarations_[cur_port->name] = cur_decl; } return errors; } iverilog-12_0/vhdlpp/entity_emit.cc000066400000000000000000000055031435245347300175100ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "entity.h" # include "architec.h" # include # include # include # include using namespace std; int emit_entities(void) { int errors = 0; for (map::iterator cur = design_entities.begin() ; cur != design_entities.end() ; ++cur) { errors += cur->second->emit(cout); } return errors; } int Entity::emit(ostream&out) { int errors = 0; out << "module \\" << get_name() << " "; // If there are generics, emit them if (parms_.size() > 0) { out << "#("; for (vector::const_iterator cur = parms_.begin() ; cur != parms_.end() ; ++cur) { const InterfacePort*curp = *cur; if (cur != parms_.begin()) out << ", "; out << "parameter \\" << curp->name << " = "; if(curp->expr) { errors += curp->expr->emit(out, this, 0); } else { // Unlike VHDL, Verilog module parameter port list // elements are always assignments. Fill in the blank. out << "1'bx"; } } out << ") "; } // If there are ports, emit them. if (ports_.size() > 0) { out << "("; const char*sep = 0; for (vector::const_iterator cur = ports_.begin() ; cur != ports_.end() ; ++cur) { InterfacePort*port = *cur; VType::decl_t&decl = declarations_[port->name]; if (sep) out << sep << endl; else sep = ", "; switch (port->mode) { case PORT_NONE: // Should not happen cerr << get_fileline() << ": error: Undefined port direction." << endl; out << "NO_PORT " << port->name; break; case PORT_IN: out << "input "; break; case PORT_OUT: out << "output "; break; case PORT_INOUT: out << "inout "; break; } errors += decl.emit(out, port->name); } cout << ")"; } out << ";" << endl; errors += bind_arch_->emit(out, this); out << "endmodule" << endl; return errors; } iverilog-12_0/vhdlpp/entity_stream.cc000066400000000000000000000051051435245347300200430ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "entity.h" # include "expression.h" using namespace std; void ComponentBase::write_to_stream(ostream&fd) const { fd << " component " << name_ << " is" << endl; if(!parms_.empty()) { fd << " generic(" << endl; for(vector::const_iterator it = parms_.begin(); it != parms_.end(); ++it) { const InterfacePort*parm = *it; if(it != parms_.begin()) fd << ";"; fd << " " << parm->name << " : "; parm->type->write_to_stream(fd); if(parm->expr) { fd << " := "; parm->expr->write_to_stream(fd); } fd << endl; } fd << " );" << endl; } if(!ports_.empty()) { fd << " port(" << endl; vector::const_iterator cur = ports_.begin(); while (cur != ports_.end()) { InterfacePort*item = *cur; ++cur; fd << " " << item->name << " : "; switch (item->mode) { case PORT_NONE: fd << "???? "; break; case PORT_IN: fd << "in "; break; case PORT_OUT: fd << "out "; break; case PORT_INOUT: fd << "inout "; break; } item->type->write_to_stream(fd); if (cur != ports_.end()) fd << ";" << endl; else fd << endl; } fd << " );" << endl; } fd << " end component;" << endl; } iverilog-12_0/vhdlpp/expression.cc000066400000000000000000000515011435245347300173540ustar00rootroot00000000000000/* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2015 / Stephen Williams (steve@icarus.com), * Copyright CERN 2016 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "expression.h" # include "subprogram.h" # include "parse_types.h" # include "scope.h" # include "library.h" # include # include # include # include # include using namespace std; Expression::Expression() : type_(0) { } Expression::~Expression() { } void Expression::set_type(const VType*typ) { assert(type_==0 || type_==typ); type_ = typ; } bool Expression::symbolic_compare(const Expression*) const { cerr << get_fileline() << ": internal error: " << "symbolic_compare() method not implemented " << "for " << typeid(*this).name() << endl; return false; } ExpAttribute::ExpAttribute(perm_string nam, list*args) : name_(nam), args_(args) { } ExpAttribute::~ExpAttribute() { if(args_) { for(list::iterator it = args_->begin(); it != args_->end(); ++it) { delete *it; } } delete args_; } list*ExpAttribute::clone_args() const { list*new_args = NULL; if(args_) { for(list::iterator it = args_->begin(); it != args_->end(); ++it) { new_args->push_back((*it)->clone()); } } return new_args; } void ExpAttribute::visit_args(ExprVisitor& func) { func.down(); func(this); if(args_) { for(list::iterator it = args_->begin(); it != args_->end(); ++it) { (*it)->visit(func); } } func.up(); } ExpObjAttribute::ExpObjAttribute(ExpName*base, perm_string name, list*args) : ExpAttribute(name, args), base_(base) { } ExpObjAttribute::~ExpObjAttribute() { delete base_; } Expression*ExpObjAttribute::clone() const { return new ExpObjAttribute(static_cast(base_->clone()), name_, clone_args()); } void ExpObjAttribute::visit(ExprVisitor&func) { func.down(); func(this); visit_args(func); base_->visit(func); func.up(); } ExpTypeAttribute::ExpTypeAttribute(const VType*base, perm_string name, list*args) : ExpAttribute(name, args), base_(base) { } Expression*ExpTypeAttribute::clone() const { return new ExpTypeAttribute(base_, name_, clone_args()); } void ExpTypeAttribute::visit(ExprVisitor&func) { func.down(); func(this); visit_args(func); func.up(); } const perm_string ExpAttribute::LEFT = perm_string::literal("left"); const perm_string ExpAttribute::RIGHT = perm_string::literal("right"); ExpBinary::ExpBinary(Expression*op1, Expression*op2) : operand1_(op1), operand2_(op2) { } ExpBinary::~ExpBinary() { delete operand1_; delete operand2_; } bool ExpBinary::eval_operand1(Entity*ent, ScopeBase*scope, int64_t&val) const { return operand1_->evaluate(ent, scope, val); } bool ExpBinary::eval_operand2(Entity*ent, ScopeBase*scope, int64_t&val) const { return operand2_->evaluate(ent, scope, val); } void ExpBinary::visit(ExprVisitor&func) { func.down(); func(this); operand1_->visit(func); operand2_->visit(func); func.up(); } ExpUnary::ExpUnary(Expression*op1) : operand1_(op1) { } ExpUnary::~ExpUnary() { delete operand1_; } void ExpUnary::visit(ExprVisitor&func) { func.down(); func(this); operand1_->visit(func); func.up(); } ExpAggregate::ExpAggregate(std::list*el) : elements_(el? el->size() : 0) { assert(el); size_t idx = 0; while (! el->empty()) { assert(idx < elements_.size()); elements_[idx++] = el->front(); el->pop_front(); } delete el; } ExpAggregate::~ExpAggregate() { for(std::vector::iterator it = elements_.begin(); it != elements_.end(); ++it) { delete *it; } for(std::vector::iterator it = aggregate_.begin(); it != aggregate_.end(); ++it) { delete it->choice; if(!it->alias_flag) delete it->expr; } } Expression* ExpAggregate::clone() const { std::list*new_elements = NULL; if(!elements_.empty()) { new_elements = new std::list(); for(std::vector::const_iterator it = elements_.begin(); it != elements_.end(); ++it) { new_elements->push_back(new element_t(**it)); } } assert(aggregate_.empty()); // cloning should not happen after elab return new ExpAggregate(new_elements); } void ExpAggregate::visit(ExprVisitor&func) { func.down(); func(this); for(std::vector::iterator it = elements_.begin(); it != elements_.end(); ++it) { (*it)->extract_expression()->visit(func); } for(std::vector::iterator it = aggregate_.begin(); it != aggregate_.end(); ++it) { if(Expression*choice_expr = it->choice->simple_expression(false)) choice_expr->visit(func); it->expr->visit(func); } func.up(); } ExpAggregate::choice_t::choice_t(Expression*exp) : expr_(exp) { } ExpAggregate::choice_t::choice_t() { } ExpAggregate::choice_t::choice_t(ExpRange*rang) : range_(rang) { } ExpAggregate::choice_t::choice_t(const choice_t&other) { if(Expression*e = other.expr_.get()) expr_.reset(e->clone()); if(other.range_.get()) range_.reset(static_cast(other.range_.get()->clone())); } ExpAggregate::choice_t::~choice_t() { } bool ExpAggregate::choice_t::others() const { return expr_.get() == 0 && range_.get() == 0; } Expression*ExpAggregate::choice_t::simple_expression(bool detach_flag) { Expression*res = detach_flag? expr_.release() : expr_.get(); return res; } ExpRange*ExpAggregate::choice_t::range_expressions(void) { return range_.get(); } ExpAggregate::element_t::element_t(list*fields, Expression*val) : fields_(fields? fields->size() : 0), val_(val) { if (fields) { size_t idx = 0; while (! fields->empty()) { assert(idx < fields_.size()); fields_[idx++] = fields->front(); fields->pop_front(); } } } ExpAggregate::element_t::element_t(const ExpAggregate::element_t&other) { fields_.reserve(other.fields_.size()); for(std::vector::const_iterator it = other.fields_.begin(); it != other.fields_.end(); ++it) { fields_.push_back(*it); } val_ = other.val_->clone(); } ExpAggregate::element_t::~element_t() { for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) delete fields_[idx]; delete val_; } ExpArithmetic::ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2) : ExpBinary(op1, op2), fun_(op) { // The xCONCAT type is not actually used. assert(op != xCONCAT); } ExpArithmetic::~ExpArithmetic() { } /* * Store bitstrings in little-endian order. */ ExpBitstring::ExpBitstring(const char*val) : value_(strlen(val)) { for (size_t idx = value_.size() ; idx > 0 ; idx -= 1) value_[idx-1] = *val++; } ExpBitstring::~ExpBitstring() { } ExpCharacter::ExpCharacter(char val) : value_(val) { } ExpCharacter::~ExpCharacter() { } ExpConcat::ExpConcat(Expression*op1, Expression*op2) : operand1_(op1), operand2_(op2) { } ExpConcat::~ExpConcat() { delete operand1_; delete operand2_; } void ExpConcat::visit(ExprVisitor&func) { func.down(); func(this); operand1_->visit(func); operand2_->visit(func); func.up(); } ExpConditional::ExpConditional(Expression*co, list*tru, list*options) { if(co && tru) options_.push_back(new case_t(co, tru)); if(options) options_.splice(options_.end(), *options); } ExpConditional::~ExpConditional() { while (!options_.empty()) { case_t*tmp = options_.front(); options_.pop_front(); delete tmp; } } Expression*ExpConditional::clone() const { std::list*new_options = NULL; if(!options_.empty()) { new_options = new std::list(); for(std::list::const_iterator it = options_.begin(); it != options_.end(); ++it) { new_options->push_back(new case_t(**it)); } } return new ExpConditional(NULL, NULL, new_options); } void ExpConditional::visit(ExprVisitor&func) { func.down(); func(this); for(std::list::iterator it = options_.begin(); it != options_.end(); ++it) (*it)->visit(func); func.up(); } ExpConditional::case_t::case_t(Expression*cond, std::list*tru) : cond_(cond) { if (tru) true_clause_.splice(true_clause_.end(), *tru); } ExpConditional::case_t::case_t(const case_t&other) : LineInfo(other) { cond_ = other.cond_->clone(); for(std::list::const_iterator it = other.true_clause_.begin(); it != other.true_clause_.end(); ++it) { true_clause_.push_back((*it)->clone()); } } ExpConditional::case_t::~case_t() { delete cond_; while (! true_clause_.empty()) { Expression*tmp = true_clause_.front(); true_clause_.pop_front(); delete tmp; } } ExpSelected::ExpSelected(Expression*selector, std::list*options) : ExpConditional(NULL, NULL, options), selector_(selector) { // Currently condition field contains only value, // so substitute it with a comparison to create a valid condition for(std::list::iterator it = options_.begin(); it != options_.end(); ++it) { Expression*cond = (*it)->condition(); if(cond) (*it)->set_condition(new ExpRelation(ExpRelation::EQ, selector_->clone(), cond)); } } ExpSelected::~ExpSelected() { } Expression*ExpSelected::clone() const { std::list*new_options = NULL; if(!options_.empty()) { new_options = new std::list(); for(std::list::const_iterator it = options_.begin(); it != options_.end(); ++it) { new_options->push_back(new case_t(**it)); } } return new ExpSelected(selector_->clone(), new_options); } void ExpConditional::case_t::visit(ExprVisitor&func) { func.down(); if(cond_) cond_->visit(func); for(std::list::iterator it = true_clause_.begin(); it != true_clause_.end(); ++it) (*it)->visit(func); func.up(); } ExpEdge::ExpEdge(ExpEdge::fun_t typ, Expression*op) : ExpUnary(op), fun_(typ) { } ExpEdge::~ExpEdge() { } ExpFunc::ExpFunc(perm_string nn) : name_(nn), def_(0) { } ExpFunc::ExpFunc(perm_string nn, list*args) : name_(nn), argv_(args->size()), def_(0) { for (size_t idx = 0; idx < argv_.size() ; idx += 1) { ivl_assert(*this, !args->empty()); argv_[idx] = args->front(); args->pop_front(); } ivl_assert(*this, args->empty()); } ExpFunc::~ExpFunc() { for (size_t idx = 0 ; idx < argv_.size() ; idx += 1) delete argv_[idx]; } Expression*ExpFunc::clone() const { std::list*new_args = NULL; if(!argv_.empty()) { new_args = new std::list(); for(std::vector::const_iterator it = argv_.begin(); it != argv_.end(); ++it) new_args->push_back((*it)->clone()); } ExpFunc*f = new ExpFunc(name_, new_args); f->def_ = def_; return f; } void ExpFunc::visit(ExprVisitor&func) { func.down(); func(this); if(!argv_.empty()) { for(std::vector::iterator it = argv_.begin(); it != argv_.end(); ++it) (*it)->visit(func); } func.up(); } const VType* ExpFunc::func_ret_type() const { return def_ ? def_->peek_return_type() : NULL; } SubprogramHeader*ExpFunc::match_signature(Entity*ent, ScopeBase*scope) const { SubprogramHeader*prog = NULL; list arg_types; // Create a list of argument types to find a matching subprogram for(vector::const_iterator it = argv_.begin(); it != argv_.end(); ++it) { arg_types.push_back((*it)->probe_type(ent, scope)); } prog = scope->match_subprogram(name_, &arg_types); if(!prog) prog = library_match_subprogram(name_, &arg_types); if(!prog) { cerr << get_fileline() << ": sorry: could not find function "; emit_subprogram_sig(cerr, name_, arg_types); cerr << endl; ivl_assert(*this, false); } return prog; } ExpInteger::ExpInteger(int64_t val) : value_(val) { } ExpInteger::~ExpInteger() { } bool ExpInteger::evaluate(Entity*, ScopeBase*, int64_t&val) const { val = value_; return true; } ExpReal::ExpReal(double val) : value_(val) { } ExpReal::~ExpReal() { } ExpLogical::ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2) : ExpBinary(op1, op2), fun_(ty) { } ExpLogical::~ExpLogical() { } ExpName::ExpName(perm_string nn) : name_(nn), indices_(NULL) { } ExpName::ExpName(perm_string nn, list*indices) : name_(nn), indices_(indices) { } ExpName::ExpName(ExpName*prefix, perm_string nn, std::list*indices) : prefix_(prefix), name_(nn), indices_(indices) { } ExpName::~ExpName() { if(indices_) { for(list::iterator it = indices_->begin(); it != indices_->end(); ++it) { delete *it; } delete indices_; } } Expression*ExpName::clone() const { list*new_indices = NULL; if(indices_) { new_indices = new list(); for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { new_indices->push_back((*it)->clone()); } } return new ExpName(static_cast(safe_clone(prefix_.get())), name_, new_indices); } void ExpName::add_index(std::list*idx) { if(!indices_) indices_ = new list(); indices_->splice(indices_->end(), *idx); } bool ExpName::symbolic_compare(const Expression*that) const { const ExpName*that_name = dynamic_cast (that); if (that_name == 0) return false; if (name_ != that_name->name_) return false; if (that_name->indices_ && !indices_) return false; if (indices_ && !that_name->indices_) return false; if (indices_) { assert(that_name->indices_); if(indices_->size() != that_name->indices_->size()) return false; list::const_iterator it, jt; it = indices_->begin(); jt = that_name->indices_->begin(); for(unsigned int i = 0; i < indices_->size(); ++i) { if(!(*it)->symbolic_compare(*jt)) return false; ++it; ++jt; } } return true; } Expression*ExpName::index(unsigned int number) const { if(!indices_) return NULL; if(number >= indices_->size()) return NULL; if(number == 0) return indices_->front(); list::const_iterator it = indices_->begin(); advance(it, number); return *it; } void ExpName::visit(ExprVisitor&func) { func.down(); func(this); if(prefix_.get()) prefix_.get()->visit(func); if(indices_) { for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { (*it)->visit(func); } } func.up(); } int ExpName::index_t::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "("; if(idx_ && size_) { errors += idx_->emit(out, ent, scope); out << "*"; errors += size_->emit(out, ent, scope); } if(offset_) { if(idx_ && size_) out << "+"; errors += offset_->emit(out, ent, scope); } out << ")"; return errors; } ExpRelation::ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2) : ExpBinary(op1, op2), fun_(ty) { } ExpRelation::~ExpRelation() { } ExpScopedName::ExpScopedName(perm_string scope, ExpName*exp) : scope_name_(scope), scope_(NULL), name_(exp) { } ExpScopedName::~ExpScopedName() { delete name_; } void ExpScopedName::visit(ExprVisitor&func) { func.down(); func(this); name_->visit(func); func.up(); } ScopeBase*ExpScopedName::get_scope(const ScopeBase*scope) { if(!scope_) scope_ = scope->find_scope(scope_name_); return scope_; } ScopeBase*ExpScopedName::get_scope(const ScopeBase*scope) const { return scope_ ? scope_ : scope->find_scope(scope_name_); } ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2) : ExpBinary(op1, op2), shift_(op) { } ExpString::ExpString(const char* value) : value_(value) { } ExpString::~ExpString() { } ExpUAbs::ExpUAbs(Expression*op1) : ExpUnary(op1) { } ExpUAbs::~ExpUAbs() { } ExpUNot::ExpUNot(Expression*op1) : ExpUnary(op1) { } ExpUNot::~ExpUNot() { } ExpUMinus::ExpUMinus(Expression*op1) : ExpUnary(op1) { } ExpUMinus::~ExpUMinus() { } ExpCast::ExpCast(Expression*base, const VType*type) : base_(base), type_(type) { } ExpCast::~ExpCast() { } void ExpCast::visit(ExprVisitor&func) { func.down(); func(this); base_->visit(func); func.up(); } ExpNew::ExpNew(Expression*size) : size_(size) { } ExpNew::~ExpNew() { delete size_; } void ExpNew::visit(ExprVisitor&func) { func.down(); func(this); size_->visit(func); func.up(); } ExpTime::ExpTime(uint64_t amount, timeunit_t unit) : amount_(amount), unit_(unit) { } double ExpTime::to_fs() const { double val = amount_; switch(unit_) { case FS: break; case PS: val *= 1e3; break; case NS: val *= 1e6; break; case US: val *= 1e9; break; case MS: val *= 1e12; break; case S: val *= 1e15; break; default: ivl_assert(*this, false); break; } return val; } ExpRange::ExpRange(Expression*left_idx, Expression*right_idx, range_dir_t dir) : left_(left_idx), right_(right_idx), direction_(dir), range_expr_(false), range_base_(NULL) { } ExpRange::ExpRange(ExpName*base, bool reverse_range) : left_(NULL), right_(NULL), direction_(AUTO), range_expr_(true), range_base_(base), range_reverse_(reverse_range) { } ExpRange::~ExpRange() { delete left_; delete right_; delete range_base_; } Expression*ExpRange::clone() const { if(range_expr_) return new ExpRange(static_cast(range_base_->clone()), range_reverse_); else return new ExpRange(left_->clone(), right_->clone(), direction_); } Expression* ExpRange::msb() { ivl_assert(*this, direction() != AUTO); switch(direction()) { case DOWNTO: return left_; case TO: return right_; default: return NULL; } return NULL; } Expression* ExpRange::lsb() { ivl_assert(*this, direction() != AUTO); switch(direction()) { case DOWNTO: return right_; case TO: return left_; default: return NULL; } return NULL; } Expression*ExpRange::left() { if(range_expr_ && !left_) // TODO check if it is an object or type left_ = new ExpObjAttribute(static_cast(range_base_->clone()), ExpAttribute::LEFT, NULL); return left_; } Expression*ExpRange::right() { if(range_expr_ && !right_) // TODO check if it is an object or type right_ = new ExpObjAttribute(static_cast(range_base_->clone()), ExpAttribute::RIGHT, NULL); return right_; } ExpDelay::ExpDelay(Expression*expr, Expression*delay) : expr_(expr), delay_(delay) { } ExpDelay::~ExpDelay() { delete expr_; delete delay_; } void ExpDelay::visit(ExprVisitor&func) { func.down(); func(this); expr_->visit(func); delay_->visit(func); func.up(); } iverilog-12_0/vhdlpp/expression.h000066400000000000000000001116041435245347300172170ustar00rootroot00000000000000#ifndef IVL_expression_H #define IVL_expression_H /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2015 / Stephen Williams (steve@icarus.com), * Copyright CERN 2016 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "LineInfo.h" # include "entity.h" # include # include # include # include # include class ExpRange; class ScopeBase; class SubprogramHeader; class VType; class VTypeArray; class VTypePrimitive; class ExpName; #if __cplusplus < 201103L #define unique_ptr auto_ptr #endif /* * Helper class to recursively traverse an expression tree * (i.e. complex expressions). */ struct ExprVisitor { ExprVisitor() : level_(0) {} virtual ~ExprVisitor() {} virtual void operator() (Expression*s) = 0; // Methods to manage recursion depth. Every Expression::visit() method // should call down() in the beginning and up() in the end. inline void down() { ++level_; } inline void up() { --level_; assert(level_ >= 0); } protected: int level() const { return level_; } private: int level_; }; /* * The Expression class represents parsed expressions from the parsed * VHDL input. The Expression class is a virtual class that holds more * specific derived expression types. */ class Expression : public LineInfo { public: Expression(); virtual ~Expression() =0; // Returns a deep copy of the expression. virtual Expression*clone() const =0; // This virtual method handles the special case of elaborating // an expression that is the l-value of a sequential variable // assignment. This generates an error for most cases, but // expressions that are valid l-values return 0 and set any // flags needed to indicate their status as writable variables. virtual int elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ); // This virtual method probes the expression to get the most // constrained type for the expression. For a given instance, // this may be called before the elaborate_expr method. virtual const VType*probe_type(Entity*ent, ScopeBase*scope) const; // The fit_type virtual method is used by the ExpConcat class // to probe the type of operands. The atype argument is the // type of the ExpConcat expression itself. This expression // returns its type as interpreted in this context. Really, // this is mostly about helping aggregate expressions within // concatenations to figure out their type. virtual const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; // This virtual method elaborates an expression. The ltype is // the type of the lvalue expression, if known, and can be // used to calculate the type for the expression being // elaborated. virtual int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); // Return the type that this expression would be if it were an // l-value. This should only be called after elaborate_lval is // called and only if elaborate_lval succeeded. inline const VType*peek_type(void) const { return type_; } // This virtual method writes a VHDL-accurate representation // of this expression to the designated stream. This is used // for writing parsed types to library files. virtual void write_to_stream(std::ostream&fd) const =0; // The emit virtual method is called by architecture emit to // output the generated code for the expression. The derived // class fills in the details of what exactly happened. virtual int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const =0; // The emit_package virtual message is similar, but is called // in a package context and to emit SV packages. virtual int emit_package(std::ostream&out) const; // The evaluate virtual method tries to evaluate expressions // to constant literal values. Return true and set the val // argument if the evaluation works, or return false if it // cannot be done. virtual bool evaluate(Entity*, ScopeBase*, int64_t&) const { return false; } bool evaluate(ScopeBase*scope, int64_t&val) const { return evaluate(NULL, scope, val); } // The symbolic compare returns true if the two expressions // are equal without actually calculating the value. virtual bool symbolic_compare(const Expression*that) const; // This method returns true if the drawn Verilog for this // expression is a primary. A containing expression can use // this method to know if it needs to wrap parentheses. This // is somewhat optional, so it is better to return false if // not certain. The default implementation does return false. virtual bool is_primary(void) const; // Debug dump of the expression. virtual void dump(std::ostream&out, int indent = 0) const =0; virtual std::ostream& dump_inline(std::ostream&out) const; // Recursively visits a tree of expressions (useful for complex expressions). virtual void visit(ExprVisitor& func) { func.down(); func(this); func.up(); } protected: // This function is called by the derived class during // elaboration to set the type of the current expression that // elaboration assigns to this expression. void set_type(const VType*); private: const VType*type_; private: // Not implemented Expression(const Expression&); Expression& operator = (const Expression&); }; /* * Checks before cloning if the other expression actually exists (!=NULL). */ static inline Expression*safe_clone(const Expression*other) { return (other ? other->clone() : NULL); } static inline void FILE_NAME(Expression*tgt, const LineInfo*src) { tgt->set_line(*src); } static inline std::ostream& operator <<(std::ostream&out, const Expression&exp) { return exp.dump_inline(out); } class ExpUnary : public Expression { public: explicit ExpUnary(Expression*op1); virtual ~ExpUnary() =0; inline const Expression*peek_operand() const { return operand1_; } const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void visit(ExprVisitor& func); protected: inline void write_to_stream_operand1(std::ostream&fd) const { operand1_->write_to_stream(fd); } int emit_operand1(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump_operand1(std::ostream&out, int indent = 0) const; private: Expression*operand1_; }; /* * This is an abstract class that collects some of the common features * of binary operators. */ class ExpBinary : public Expression { public: ExpBinary(Expression*op1, Expression*op2); virtual ~ExpBinary() =0; inline const Expression* peek_operand1(void) const { return operand1_; } inline const Expression* peek_operand2(void) const { return operand2_; } const VType*probe_type(Entity*ent, ScopeBase*scope) const; void visit(ExprVisitor& func); protected: int elaborate_exprs(Entity*, ScopeBase*, const VType*); int emit_operand1(std::ostream&out, Entity*ent, ScopeBase*scope) const; int emit_operand2(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool eval_operand1(Entity*ent, ScopeBase*scope, int64_t&val) const; bool eval_operand2(Entity*ent, ScopeBase*scope, int64_t&val) const; inline void write_to_stream_operand1(std::ostream&out) const { operand1_->write_to_stream(out); } inline void write_to_stream_operand2(std::ostream&out) const { operand2_->write_to_stream(out); } void dump_operands(std::ostream&out, int indent = 0) const; private: virtual const VType*resolve_operand_types_(const VType*t1, const VType*t2) const; private: Expression*operand1_; Expression*operand2_; }; class ExpAggregate : public Expression { public: // A "choice" is only part of an element. It is the thing that // is used to identify an element of the aggregate. It can // represent the index (or range) of an array, or the name of // a record member. class choice_t { public: // Create an "others" choice choice_t(); // Create a simple_expression choice explicit choice_t(Expression*exp); // Create a named choice explicit choice_t(perm_string name); // discreate_range choice explicit choice_t(ExpRange*ran); choice_t(const choice_t&other); ~choice_t(); // true if this represents an "others" choice bool others() const; // Return expression if this represents a simple_expression. Expression*simple_expression(bool detach_flag =true); // Return ExpRange if this represents a range_expression ExpRange*range_expressions(void); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; private: std::unique_ptrexpr_; std::unique_ptr range_; private: // not implemented choice_t& operator= (const choice_t&); }; struct choice_element { choice_element() : choice(), expr() {} choice_element(const choice_element&other) { choice = other.choice ? new choice_t(*other.choice) : NULL; expr = safe_clone(other.expr); } # if __cplusplus >= 201103L choice_element& operator = (const choice_element&that) = default; # endif choice_t*choice; Expression*expr; bool alias_flag; }; // Elements are the syntactic items in an aggregate // expression. Each element expressions a bunch of fields // (choices) and binds them to a single expression class element_t { public: explicit element_t(std::list*fields, Expression*val); element_t(const element_t&other); ~element_t(); size_t count_choices() const { return fields_.size(); } void map_choices(choice_element*dst); inline Expression* extract_expression() { return val_; } void write_to_stream(std::ostream&fd) const; void dump(std::ostream&out, int indent) const; private: std::vectorfields_; Expression*val_; private: // not implemented element_t& operator = (const element_t&); }; public: explicit ExpAggregate(std::list*el); ~ExpAggregate(); Expression*clone() const; const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype); int elaborate_expr_record_(Entity*ent, ScopeBase*scope, const VTypeRecord*ltype); int emit_array_(std::ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*ltype) const; int emit_record_(std::ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*ltype) const; private: // This is the elements as directly parsed. std::vector elements_; // These are the elements after elaboration. This form is // easier to check and emit. std::vector aggregate_; }; class ExpArithmetic : public ExpBinary { public: enum fun_t { PLUS, MINUS, MULT, DIV, MOD, REM, POW, xCONCAT }; public: ExpArithmetic(ExpArithmetic::fun_t op, Expression*op1, Expression*op2); ~ExpArithmetic(); Expression*clone() const { return new ExpArithmetic(fun_, peek_operand1()->clone(), peek_operand2()->clone()); } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; virtual bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; private: const VType* resolve_operand_types_(const VType*t1, const VType*t2) const; private: fun_t fun_; }; class ExpAttribute : public Expression { public: ExpAttribute(perm_string name,std::list*args); virtual ~ExpAttribute(); inline perm_string peek_attribute() const { return name_; } // Constants for the standard attributes static const perm_string LEFT; static const perm_string RIGHT; protected: std::list*clone_args() const; int elaborate_args(Entity*ent, ScopeBase*scope, const VType*ltype); void visit_args(ExprVisitor& func); bool evaluate_type_attr(const VType*type, Entity*ent, ScopeBase*scope, int64_t&val) const; bool test_array_type(const VType*type) const; perm_string name_; std::list*args_; }; class ExpObjAttribute : public ExpAttribute { public: ExpObjAttribute(ExpName*base, perm_string name, std::list*args); ~ExpObjAttribute(); Expression*clone() const; inline const ExpName* peek_base() const { return base_; } int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; // Some attributes can be evaluated at compile time bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: ExpName*base_; }; class ExpTypeAttribute : public ExpAttribute { public: ExpTypeAttribute(const VType*base, perm_string name, std::list*args); // no destructor - VType objects (base_) are shared between many expressions Expression*clone() const; inline const VType* peek_base() const { return base_; } int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; // Some attributes can be evaluated at compile time bool evaluate(ScopeBase*scope, int64_t&val) const; bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: const VType*base_; }; class ExpBitstring : public Expression { public: explicit ExpBitstring(const char*); ExpBitstring(const ExpBitstring&other) : Expression() { value_ = other.value_; } ~ExpBitstring(); Expression*clone() const { return new ExpBitstring(*this); } const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; private: std::vectorvalue_; }; class ExpCharacter : public Expression { public: explicit ExpCharacter(char val); ExpCharacter(const ExpCharacter&other) : Expression() { value_ = other.value_; } ~ExpCharacter(); Expression*clone() const { return new ExpCharacter(*this); } const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool is_primary(void) const; void dump(std::ostream&out, int indent = 0) const; char value() const { return value_; } private: int emit_primitive_bit_(std::ostream&out, Entity*ent, ScopeBase*scope, const VTypePrimitive*etype) const; private: char value_; }; class ExpConcat : public Expression { public: ExpConcat(Expression*op1, Expression*op2); ~ExpConcat(); Expression*clone() const { return new ExpConcat(operand1_->clone(), operand2_->clone()); } const VType*probe_type(Entity*ent, ScopeBase*scope) const; const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool is_primary(void) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: int elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype); private: Expression*operand1_; Expression*operand2_; }; /* * The conditional expression represents the VHDL when-else * expressions. Note that by the VHDL syntax rules, these cannot show * up other than at the root of an expression. */ class ExpConditional : public Expression { public: class case_t : public LineInfo { public: case_t(Expression*cond, std::list*tru); case_t(const case_t&other); ~case_t(); inline Expression*condition() const { return cond_; } inline void set_condition(Expression*cond) { cond_ = cond; } inline const std::list& true_clause() const { return true_clause_; } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*lt); int emit_option(std::ostream&out, Entity*ent, ScopeBase*scope) const; int emit_default(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; std::list& extract_true_clause() { return true_clause_; } void visit(ExprVisitor& func); private: Expression*cond_; std::list true_clause_; }; public: ExpConditional(Expression*cond, std::list*tru, std::list*options); virtual ~ExpConditional(); virtual Expression*clone() const; const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); protected: std::list options_; }; /* * Expression to handle selected assignments (with .. select target <= value when ..) */ class ExpSelected : public ExpConditional { public: ExpSelected(Expression*selector, std::list*options); ~ExpSelected(); Expression*clone() const; private: Expression*selector_; }; /* * This is a special expression type that represents posedge/negedge * expressions in sensitivity lists. */ class ExpEdge : public ExpUnary { public: enum fun_t { NEGEDGE, ANYEDGE, POSEDGE }; public: explicit ExpEdge(ExpEdge::fun_t ty, Expression*op); ~ExpEdge(); Expression*clone() const { return new ExpEdge(fun_, peek_operand()->clone()); } inline fun_t edge_fun() const { return fun_; } void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; private: fun_t fun_; }; class ExpFunc : public Expression { public: explicit ExpFunc(perm_string nn); ExpFunc(perm_string nn, std::list*args); ~ExpFunc(); Expression*clone() const; const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; inline perm_string func_name() const { return name_; } inline size_t func_args() const { return argv_.size(); } inline const Expression*func_arg(size_t idx) const { return argv_[idx]; } const VType*func_ret_type() const; public: // Base methods const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); // NOTE: does not handle expressions in subprogram body // Returns a subprogram header that matches the function call SubprogramHeader*match_signature(Entity*ent, ScopeBase*scope) const; private: perm_string name_; std::vector argv_; mutable SubprogramHeader*def_; }; class ExpInteger : public Expression { public: explicit ExpInteger(int64_t val); ExpInteger(const ExpInteger&other) : Expression(), value_(other.value_) {} ~ExpInteger(); Expression*clone() const { return new ExpInteger(*this); } const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; int emit_package(std::ostream&out) const; bool is_primary(void) const { return true; } bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; virtual std::ostream& dump_inline(std::ostream&out) const; private: int64_t value_; }; class ExpReal : public Expression { public: explicit ExpReal(double val); ExpReal(const ExpReal&other) : Expression(), value_(other.value_) {} ~ExpReal(); Expression*clone() const { return new ExpReal(*this); } const VType*probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; int emit_package(std::ostream&out) const; bool is_primary(void) const; void dump(std::ostream&out, int indent = 0) const; virtual std::ostream& dump_inline(std::ostream&out) const; private: double value_; }; class ExpLogical : public ExpBinary { public: enum fun_t { AND, OR, NAND, NOR, XOR, XNOR }; public: ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2); ~ExpLogical(); Expression*clone() const { return new ExpLogical(fun_, peek_operand1()->clone(), peek_operand2()->clone()); } inline fun_t logic_fun() const { return fun_; } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; private: fun_t fun_; }; /* * The ExpName class represents an expression that is an identifier or * other sort of name. The ExpNameALL is a special case of ExpName * that represents the "all" keyword is contexts that can handle it. */ class ExpName : public Expression { public: explicit ExpName(perm_string nn); ExpName(perm_string nn, std::list*indices); ExpName(ExpName*prefix, perm_string nn, std::list*indices = NULL); virtual ~ExpName(); public: // Base methods Expression*clone() const; int elaborate_lval(Entity*ent, ScopeBase*scope, bool); int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*); const VType* probe_type(Entity*ent, ScopeBase*scope) const; const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit_indices(std::ostream&out, Entity*ent, ScopeBase*scope) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool is_primary(void) const; bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; bool symbolic_compare(const Expression*that) const; void dump(std::ostream&out, int indent = 0) const; inline const char* name() const { return name_; } inline const perm_string& peek_name() const { return name_; } void add_index(std::list*idx); void visit(ExprVisitor& func); private: class index_t { public: index_t(Expression*idx, Expression*size, Expression*offset = NULL) : idx_(idx), size_(size), offset_(offset) {} ~index_t() { delete idx_; delete size_; delete offset_; } int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; private: Expression*idx_; Expression*size_; Expression*offset_; }; const VType* elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*scope, const VType*type); int elaborate_lval_(Entity*ent, ScopeBase*scope, bool, ExpName*suffix); const VType* probe_prefix_type_(Entity*ent, ScopeBase*scope) const; const VType* probe_prefixed_type_(Entity*ent, ScopeBase*scope) const; int emit_as_prefix_(std::ostream&out, Entity*ent, ScopeBase*scope) const; // There are some workarounds required for constant arrays/records, as // they are currently emitted as flat localparams (without any type // information). The following workarounds adjust the access indices // to select appropriate parts of the localparam. bool try_workarounds_(std::ostream&out, Entity*ent, ScopeBase*scope, std::list&indices, int&data_size) const; bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope, std::list&indices, int&data_size) const; bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope, std::list&indices, int&data_size) const; int emit_workaround_(std::ostream&out, Entity*ent, ScopeBase*scope, const std::list&indices, int field_size) const; private: Expression*index(unsigned int number) const; std::unique_ptr prefix_; perm_string name_; std::list*indices_; }; class ExpNameALL : public ExpName { public: ExpNameALL() : ExpName(empty_perm_string) { } public: const VType* probe_type(Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent =0) const; }; class ExpRelation : public ExpBinary { public: enum fun_t { EQ, LT, GT, NEQ, LE, GE }; inline fun_t relation_fun(void) const { return fun_; } public: ExpRelation(ExpRelation::fun_t ty, Expression*op1, Expression*op2); ~ExpRelation(); Expression*clone() const { return new ExpRelation(fun_, peek_operand1()->clone(), peek_operand2()->clone()); } const VType* probe_type(Entity*ent, ScopeBase*scope) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; private: fun_t fun_; }; /* * Helper class to handle name expressions coming from another scope. As such, * we get more information regarding their type, etc. from the associated scope. */ class ExpScopedName : public Expression { public: ExpScopedName(perm_string scope, ExpName*exp); ~ExpScopedName(); Expression*clone() const { return new ExpScopedName(scope_name_, static_cast(name_->clone())); } int elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ) { return name_->elaborate_lval(ent, get_scope(scope), is_sequ); } int elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval) { return name_->elaborate_rval(ent, get_scope(scope), lval); } const VType* probe_type(Entity*ent, ScopeBase*scope) const { return name_->probe_type(ent, get_scope(scope)); } const VType* fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*host) const { return name_->fit_type(ent, get_scope(scope), host); } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { return name_->elaborate_expr(ent, get_scope(scope), ltype); } void write_to_stream(std::ostream&fd) const { name_->write_to_stream(fd); } int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const { out << scope_name_ << "."; return name_->emit(out, ent, scope); } bool is_primary(void) const { return name_->is_primary(); } bool evaluate(Entity*ent, ScopeBase*, int64_t&val) const { return name_->evaluate(ent, scope_, val); } bool symbolic_compare(const Expression*that) const { return name_->symbolic_compare(that); } void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor&func); private: // Functions that resolve the origin scope for the name expression ScopeBase*get_scope(const ScopeBase*scope); ScopeBase*get_scope(const ScopeBase*scope) const; perm_string scope_name_; ScopeBase*scope_; ExpName*name_; }; class ExpShift : public ExpBinary { public: enum shift_t { SRL, SLL, SRA, SLA, ROL, ROR }; public: ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2); Expression*clone() const { return new ExpShift(shift_, peek_operand1()->clone(), peek_operand2()->clone()); } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; private: shift_t shift_; }; class ExpString : public Expression { public: explicit ExpString(const char*); ExpString(const ExpString&other) : Expression(), value_(other.value_) {} ~ExpString(); Expression*clone() const { return new ExpString(*this); } const VType*fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; bool is_primary(void) const; void dump(std::ostream&out, int indent = 0) const; const std::string& get_value() const { return value_; } // Converts quotation marks (") to its escaped // counterpart in SystemVerilog (\") static std::string escape_quot(const std::string& str); private: int emit_as_array_(std::ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr) const; private: std::string value_; }; class ExpUAbs : public ExpUnary { public: explicit ExpUAbs(Expression*op1); ~ExpUAbs(); Expression*clone() const { return new ExpUAbs(peek_operand()->clone()); } void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; }; class ExpUNot : public ExpUnary { public: explicit ExpUNot(Expression*op1); ~ExpUNot(); Expression*clone() const { return new ExpUNot(peek_operand()->clone()); } void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; }; class ExpUMinus : public ExpUnary { public: explicit ExpUMinus(Expression*op1); ~ExpUMinus(); Expression*clone() const { return new ExpUMinus(peek_operand()->clone()); } void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; }; /* * Class that wraps other expressions to cast them to other types. */ class ExpCast : public Expression { public: ExpCast(Expression*base, const VType*type); ~ExpCast(); Expression*clone() const { return new ExpCast(base_->clone(), type_->clone()); } inline int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) { return base_->elaborate_expr(ent, scope, type_); } void write_to_stream(std::ostream&fd) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: Expression*base_; const VType*type_; }; /* * Class that handles 'new' statement. VHDL is not capable of dynamic memory * allocation, but it is useful for emitting some cases. */ class ExpNew : public Expression { public: explicit ExpNew(Expression*size); ~ExpNew(); Expression*clone() const { return new ExpNew(size_->clone()); } // There is no 'new' in VHDL - do not emit anything void write_to_stream(std::ostream&) const {}; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); private: Expression*size_; }; class ExpTime : public Expression { public: typedef enum { FS, PS, NS, US, MS, S } timeunit_t; ExpTime(uint64_t amount, timeunit_t unit); Expression*clone() const { return new ExpTime(amount_, unit_); } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; //bool evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const; void dump(std::ostream&out, int indent = 0) const; private: // Returns the time value expressed in femtoseconds double to_fs() const; uint64_t amount_; timeunit_t unit_; }; class ExpRange : public Expression { public: typedef enum { DOWNTO, TO, AUTO } range_dir_t; // Regular range ExpRange(Expression*left_idx, Expression*right_idx, range_dir_t dir); // 'range/'reverse range attribute ExpRange(ExpName*base, bool reverse_range); ~ExpRange(); Expression*clone() const; // Returns the upper boundary Expression*msb(); // Returns the lower boundary Expression*lsb(); Expression*left(); Expression*right(); range_dir_t direction() const { return direction_; } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; private: // Regular range related fields Expression*left_, *right_; range_dir_t direction_; // 'range/'reverse_range attribute related fields // Flag to indicate it is a 'range/'reverse_range expression bool range_expr_; // Object name to which the attribute is applied ExpName*range_base_; // Flag to distinguish between 'range & 'reverse_range bool range_reverse_; }; // Helper class that wraps other expression to specify delay. class ExpDelay : public Expression { public: ExpDelay(Expression*expr, Expression*delay); ~ExpDelay(); Expression*clone() const { return new ExpDelay(expr_->clone(), delay_->clone()); } int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); void write_to_stream(std::ostream&) const; int emit(std::ostream&out, Entity*ent, ScopeBase*scope) const; void dump(std::ostream&out, int indent = 0) const; void visit(ExprVisitor& func); const Expression*peek_expr() const { return expr_; } const Expression*peek_delay() const { return delay_; } private: Expression*expr_; Expression*delay_; }; #if __cplusplus < 201103L #undef unique_ptr #endif #endif /* IVL_expression_H */ iverilog-12_0/vhdlpp/expression_debug.cc000066400000000000000000000102421435245347300205170ustar00rootroot00000000000000/* * Copyright (c) 2012 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 "entity.h" # include "architec.h" # include "expression.h" # include # include # include # include using namespace std; void ExpArithmetic::dump(ostream&out, int indent) const { const char*fun_name = "?"; switch (fun_) { case PLUS: fun_name = "+"; break; case MINUS: fun_name = "-"; break; case MULT: fun_name = "*"; break; case DIV: fun_name = "/"; break; case MOD: fun_name = "mod"; break; case REM: fun_name = "rem"; break; case POW: fun_name = "**"; break; case xCONCAT: ivl_assert(*this, 0); break; } out << setw(indent) << "" << "Arithmetic " << fun_name << " at " << get_fileline() << endl; dump_operands(out, indent+4); } void ExpConcat::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Concatenation at " << get_fileline() << endl; operand1_->dump(out, indent); operand2_->dump(out, indent); } void ExpCast::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Casting "; base_->dump(out, indent+4); out << " to "; type_->emit_def(out, empty_perm_string); } void ExpNew::dump(ostream&out, int indent) const { out << setw(indent) << "" << "New dynamic array size: " << endl; size_->dump(out, indent); } void ExpScopedName::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Scoped name expression: " << endl; out << " scope " << scope_name_ << " " << scope_ << endl; name_->dump(out, indent+4); } void ExpShift::dump(ostream&out, int indent) const { const char*fun_name = "?"; switch (shift_) { case SRL: fun_name = "srl"; break; case SLL: fun_name = "sll"; break; case SLA: fun_name = "sla"; break; case SRA: fun_name = "sra"; break; case ROR: fun_name = "ror"; break; case ROL: fun_name = "rol"; break; } out << setw(indent) << "" << "Shift " << fun_name << " at " << get_fileline() << endl; dump_operands(out, indent+4); } void ExpString::dump(ostream&out, int indent) const { out << setw(indent) << "" << "String \"" << value_; out << "\"" << " at " << get_fileline() << endl; } void ExpUAbs::dump(ostream&out, int indent) const { out << setw(indent) << "" << "abs() at " << get_fileline() << endl; dump_operand1(out, indent+4); } void ExpUnary::dump_operand1(ostream&out, int indent) const { operand1_->dump(out, indent); } void ExpUNot::dump(ostream&out, int indent) const { out << setw(indent) << "" << "not() at " << get_fileline() << endl; dump_operand1(out, indent+4); } void ExpUMinus::dump(ostream&out, int indent) const { out << setw(indent) << "" << "unary_minus() at " << get_fileline() << endl; dump_operand1(out, indent+4); } void ExpTime::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Time "; write_to_stream(out); } void ExpRange::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Range "; write_to_stream(out); } void ExpDelay::dump(ostream&out, int indent) const { out << setw(indent) << "" << "Expression "; expr_->write_to_stream(out); out << " delayed by "; delay_->write_to_stream(out); } iverilog-12_0/vhdlpp/expression_elaborate.cc000066400000000000000000001036341435245347300213770ustar00rootroot00000000000000/* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2016 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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. * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704. */ # include "expression.h" # include "architec.h" # include "entity.h" # include "vsignal.h" # include "subprogram.h" # include "std_types.h" # include # include # include "parse_types.h" # include "compiler.h" # include "ivl_assert.h" using namespace std; int Expression::elaborate_lval(Entity*, ScopeBase*, bool) { cerr << get_fileline() << ": error: Expression is not a valid l-value." << endl; return 1; } const VType* Expression::probe_type(Entity*, ScopeBase*) const { return 0; } const VType* Expression::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*) const { const VType*res = probe_type(ent,scope); if (res == 0) { cerr << get_fileline() << ": internal error: " << "fit_type for " << typeid(*this).name() << " is not implemented." << endl; } return res; } const VType*ExpName::elaborate_adjust_type_with_range_(Entity*ent, ScopeBase*scope, const VType*type) { // Unfold typedefs while (const VTypeDef*tdef = dynamic_cast(type)) { type = tdef->peek_definition(); } if (const VTypeArray*array = dynamic_cast(type)) { Expression*idx = index(0); if (ExpRange*range = dynamic_cast(idx)) { // If the name is an array, then a part select is // also an array, but with different bounds. int64_t use_msb, use_lsb; bool flag = true; flag &= range->msb()->evaluate(ent, scope, use_msb); flag &= range->lsb()->evaluate(ent, scope, use_lsb); if(flag) type = new VTypeArray(array->element_type(), use_msb, use_lsb); } else if(idx) { // If the name is an array or a vector, then an // indexed name has the type of the element. type = array->element_type(); } } return type; } int ExpName::elaborate_lval_(Entity*ent, ScopeBase*scope, bool is_sequ, ExpName*suffix) { int errors = 0; if (debug_elaboration) { debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " << "name_=" << name_ << ", suffix->name()=" << suffix->name(); if (indices_) { for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { debug_log_file << "["; debug_log_file << **it; debug_log_file << "]"; } } debug_log_file << endl; } if (prefix_.get()) { cerr << get_fileline() << ": sorry: I don't know how to elaborate " << "ExpName prefix of " << name_ << " in l-value expressions." << endl; errors += 1; } const VType*found_type = 0; if (const InterfacePort*cur = ent->find_port(name_)) { if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) { cerr << get_fileline() << ": error: Assignment to " "input port " << name_ << "." << endl; return errors + 1; } if (is_sequ) ent->set_declaration_l_value(name_, is_sequ); found_type = cur->type; } else if (ent->find_generic(name_)) { cerr << get_fileline() << ": error: Assignment to generic " << name_ << " from entity " << ent->get_name() << "." << endl; return errors + 1; } else if (Signal*sig = scope->find_signal(name_)) { // Tell the target signal that this may be a sequential l-value. if (is_sequ) sig->count_ref_sequ(); found_type = sig->peek_type(); } else if (Variable*var = scope->find_variable(name_)) { // Tell the target signal that this may be a sequential l-value. if (is_sequ) var->count_ref_sequ(); found_type = var->peek_type(); } // Resolve type definition to get an actual type. while (const VTypeDef*tdef = dynamic_cast (found_type)) { found_type = tdef->peek_definition(); if (debug_elaboration) { debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " << "Resolve typedef " << tdef->peek_name() << " to defined type=" << typeid(*found_type).name() << endl; } } ivl_assert(*this, found_type); // If the prefix type is an array, then we may actually have a // case of an array of structs. For example: // foo(n).bar // where foo is an array, (n) is an array index and foo(n) is // something that takes a suffix. For the purpose of our // expression type calculations, we need the element type. if (const VTypeArray*array = dynamic_cast (found_type)) { found_type = array->element_type(); while (const VTypeDef*tdef = dynamic_cast (found_type)) { found_type = tdef->peek_definition(); } if (debug_elaboration) { debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " << "Extract array element type=" << typeid(*found_type).name() << endl; } } const VType*suffix_type = 0; if (const VTypeRecord*record = dynamic_cast (found_type)) { const VTypeRecord::element_t*element = record->element_by_name(suffix->name_); ivl_assert(*this, element); const VType*element_type = element->peek_type(); ivl_assert(*this, element_type); suffix_type = element_type; } if (suffix_type == 0) { cerr << get_fileline() << ": error: I don't know how to handle prefix " << name_ << " with suffix " << suffix->name_ << endl; errors += 1; return errors; } suffix_type = suffix->elaborate_adjust_type_with_range_(ent, scope, suffix_type); ivl_assert(*this, suffix_type); suffix->set_type(suffix_type); return errors; } int ExpName::elaborate_lval(Entity*ent, ScopeBase*scope, bool is_sequ) { int errors = 0; if (prefix_.get()) { return prefix_->elaborate_lval_(ent, scope, is_sequ, this); } const VType*found_type = 0; if (ent) { if (const InterfacePort*cur = ent->find_port(name_)) { if (cur->mode != PORT_OUT && cur->mode != PORT_INOUT) { cerr << get_fileline() << ": error: Assignment to " "input port " << name_ << "." << endl; return errors += 1; } if (is_sequ) ent->set_declaration_l_value(name_, is_sequ); found_type = cur->type; } else if (ent->find_generic(name_)) { cerr << get_fileline() << ": error: Assignment to generic " << name_ << " from entity " << ent->get_name() << "." << endl; return 1; } } if (!found_type && scope) { if (Signal*sig = scope->find_signal(name_)) { // Tell the target signal that this may be a sequential l-value. if (is_sequ) sig->count_ref_sequ(); found_type = sig->peek_type(); } else if (Variable*var = scope->find_variable(name_)) { // Tell the target signal that this may be a sequential l-value. if (is_sequ) var->count_ref_sequ(); found_type = var->peek_type(); } else if (const InterfacePort*port = scope->find_param(name_)) { found_type = port->type; } } if (found_type == 0) { cerr << get_fileline() << ": error: Signal/variable " << name_ << " not found in this context." << endl; return errors + 1; } found_type = elaborate_adjust_type_with_range_(ent, scope, found_type); set_type(found_type); return errors; } int ExpName::elaborate_rval(Entity*ent, ScopeBase*scope, const InterfacePort*lval) { int errors = 0; if (prefix_.get()) { cerr << get_fileline() << ": sorry: I don't know how to elaborate " << "ExpName prefix parts in r-value expressions." << endl; errors += 1; } const VType*dummy_type; Expression*dummy_expr; if (const InterfacePort*cur = ent->find_port(name_)) { /* IEEE 1076-2008, p.80: * For a formal port IN, associated port should be IN, OUT, INOUT or BUFFER * For a formal port OUT, associated port should be OUT, INOUT or BUFFER * For a formal port INOUT, associated port should be OUT, INOUT or BUFFER * For a formal port BUFFER, associated port should be OUT, INOUT or BUFFER */ switch(lval->mode) { case PORT_OUT: //case PORT_INOUT: if (cur->mode == PORT_IN) { cerr << get_fileline() << ": error: Connecting " "formal output port " << lval->name << " to actual input port " << name_ << "." << endl; errors += 1; } break; case PORT_IN: case PORT_NONE: default: break; } } else if (scope->find_signal(name_)) { /* OK */ } else if (ent->find_generic(name_)) { /* OK */ } else if (scope->find_constant(name_, dummy_type, dummy_expr)) { /* OK */ } else if (scope->is_enum_name(name_)) { /* OK */ } else { cerr << get_fileline() << ": error: No port, signal or constant " << name_ << " to be used as r-value." << endl; errors += 1; } return errors; } int Expression::elaborate_expr(Entity*, ScopeBase*, const VType*) { cerr << get_fileline() << ": internal error: I don't know how to " << "elaborate expression type=" << typeid(*this).name() << endl; return 1; } const VType* ExpBinary::probe_type(Entity*ent, ScopeBase*scope) const { const VType*t1 = operand1_->probe_type(ent, scope); const VType*t2 = operand2_->probe_type(ent, scope); if (t1 == 0) return t2; if (t2 == 0) return t1; if (t1->type_match(t2)) return t1; if (t2->type_match(t1)) return t2; if (const VType*tb = resolve_operand_types_(t1, t2)) return tb; // FIXME: I should at this point try harder to find an // operator that has the proper argument list and use this // here, but for now we leave it for the back-end to figure out. #if 0 cerr << get_fileline() << ": internal error: I don't know how to resolve types of generic binary expressions." << endl; #endif return 0; } const VType*ExpBinary::resolve_operand_types_(const VType*, const VType*) const { return 0; } int ExpBinary::elaborate_exprs(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; errors += operand1_->elaborate_expr(ent, scope, ltype); errors += operand2_->elaborate_expr(ent, scope, ltype); return errors; } /* * the default fit_type method for unary operator expressions is to * return the fit_type for the operand. The assumption is that the * operator doesn't change the type. */ const VType*ExpUnary::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const { return operand1_->fit_type(ent, scope, atype); } const VType*ExpUnary::probe_type(Entity*ent, ScopeBase*scope) const { return operand1_->probe_type(ent, scope); } int ExpUnary::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { ivl_assert(*this, ltype != 0); set_type(ltype); return operand1_->elaborate_expr(ent, scope, ltype); } const VType*ExpAggregate::fit_type(Entity*, ScopeBase*, const VTypeArray*host) const { ivl_assert(*this, elements_.size() == 1); size_t choice_count = elements_[0]->count_choices(); ivl_assert(*this, choice_count > 0); vector ce (choice_count); elements_[0]->map_choices(&ce[0]); ivl_assert(*this, ce.size() == 1); ExpRange*prange = ce[0].choice->range_expressions(); ivl_assert(*this, prange); Expression*use_msb = prange->msb(); Expression*use_lsb = prange->lsb(); ivl_assert(*this, host->dimensions().size() == 1); vector range (1); range[0] = VTypeArray::range_t(use_msb, use_lsb); const VTypeArray*res = new VTypeArray(host->element_type(), range); return res; } int ExpAggregate::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { if (ltype == 0) { cerr << get_fileline() << ": error: Elaboration of aggregate types needs well known type context?" << endl; return 1; } set_type(ltype); while (const VTypeDef*cur = dynamic_cast(ltype)) { ltype = cur->peek_definition(); } if (const VTypeArray*larray = dynamic_cast(ltype)) { return elaborate_expr_array_(ent, scope, larray); } else if(const VTypeRecord*lrecord = dynamic_cast(ltype)) { return elaborate_expr_record_(ent, scope, lrecord); } cerr << get_fileline() << ": internal error: I don't know how to elaborate aggregate expressions. type=" << typeid(*ltype).name() << endl; return 1; } /* * Elaboration of array aggregates is elaboration of the element * expressions (the elements_ member) using the element type as the * ltype for the subexpression. */ int ExpAggregate::elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*ltype) { const VType*element_type = ltype->element_type(); int errors = 0; size_t choice_count = 0; // Figure out how many total elements we have here. Note that // each parsed element may be bound to multiple choices, so // account for that. for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) { element_t*ecur = elements_[edx]; if (ecur->count_choices() == 0) choice_count += 1; else choice_count += ecur->count_choices(); } aggregate_.resize(choice_count); // Translate the elements_ array to the aggregate_ array. In // the target array, each expression is attached to a single // choice. size_t cdx = 0; for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) { element_t*ecur = elements_[edx]; if (ecur->count_choices() == 0) { // positional associations have no "choice" // associated with them. aggregate_[cdx].choice = 0; aggregate_[cdx].expr = ecur->extract_expression(); aggregate_[cdx].alias_flag = false; cdx += 1; } else { ecur->map_choices(&aggregate_[cdx]); cdx += ecur->count_choices(); } } ivl_assert(*this, cdx == choice_count); // Now run through the more convenient mapping and elaborate // all the expressions that I find. for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { if (aggregate_[idx].alias_flag) continue; errors += aggregate_[idx].expr->elaborate_expr(ent, scope, element_type); } // done with the obsolete elements_ vector. elements_.clear(); return errors; } int ExpAggregate::elaborate_expr_record_(Entity*ent, ScopeBase*scope, const VTypeRecord*ltype) { int errors = 0; aggregate_.resize(elements_.size()); choice_element tmp; int idx; // Translate the elements_ array to the aggregate_ array. In // the target array, each expression is attached to a single // choice. for (size_t edx = 0 ; edx < elements_.size() ; edx += 1) { element_t*ecur = elements_[edx]; // it is invalid to have more than one choice in record assignment ivl_assert(*this, ecur->count_choices() == 1); ecur->map_choices(&tmp); choice_t*ch = tmp.choice; ivl_assert(*this, !ch->others()); ivl_assert(*this, !tmp.alias_flag); // Get the appropriate type for a field const ExpName*field = dynamic_cast(ch->simple_expression(false)); ivl_assert(*this, field); perm_string field_name = field->peek_name(); idx = -1; const VTypeRecord::element_t*el = ltype->element_by_name(field_name, &idx); ivl_assert(*this, idx >= 0); aggregate_[idx] = tmp; errors += aggregate_[idx].expr->elaborate_expr(ent, scope, el->peek_type()); } // done with the obsolete elements_ vector. elements_.clear(); return errors; } void ExpAggregate::element_t::map_choices(ExpAggregate::choice_element*dst) { for (size_t idx = 0 ; idx < fields_.size() ; idx += 1) { dst->choice = fields_[idx]; dst->expr = val_; dst->alias_flag = (idx != 0); dst += 1; } } int ExpArithmetic::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, scope, ltype); return errors; } const VType* ExpArithmetic::resolve_operand_types_(const VType*t1, const VType*t2) const { // Ranges while (const VTypeRange*tmp = dynamic_cast (t1)) t1 = tmp->base_type(); while (const VTypeRange*tmp = dynamic_cast (t2)) t2 = tmp->base_type(); if (t1->type_match(t2)) return t1; // Signed & unsigned (resized to the widest argument) const VTypeArray*t1_arr = dynamic_cast(t1); const VTypeArray*t2_arr = dynamic_cast(t2); if(t1_arr && t2_arr) { const VTypeArray*t1_parent = t1_arr->get_parent_type(); const VTypeArray*t2_parent = t2_arr->get_parent_type(); if(t1_parent == t2_parent && (t1_parent == &primitive_SIGNED || t1_parent == &primitive_UNSIGNED)) { int t1_size = t1_arr->get_width(NULL); int t2_size = t2_arr->get_width(NULL); // Easy, the same sizes, so we do not need to resize if(t1_size == t2_size && t1_size > 0) return t1; // == t2 VTypeArray*resolved = new VTypeArray(t1_parent->element_type(), std::max(t1_size, t2_size) - 1, 0, t1_parent->signed_vector()); resolved->set_parent_type(t1_parent); return resolved; } } else if(t1_arr) { if(const VTypePrimitive*prim = dynamic_cast(t2)) { const VTypeArray*t1_parent = t1_arr->get_parent_type(); VTypePrimitive::type_t t2_type = prim->type(); if((t2_type == VTypePrimitive::NATURAL || t2_type == VTypePrimitive::INTEGER) && t1_parent == &primitive_SIGNED) return t1; if((t2_type == VTypePrimitive::NATURAL) && t1_parent == &primitive_UNSIGNED) return t1; } } else if(t2_arr) { if(const VTypePrimitive*prim = dynamic_cast(t1)) { const VTypeArray*t2_parent = t2_arr->get_parent_type(); VTypePrimitive::type_t t1_type = prim->type(); if((t1_type == VTypePrimitive::NATURAL || t1_type == VTypePrimitive::INTEGER) && t2_parent == &primitive_SIGNED) return t2; if((t1_type == VTypePrimitive::NATURAL) && t2_parent == &primitive_UNSIGNED) return t2; } } return 0; } int ExpAttribute::elaborate_args(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if(args_) { for(list::iterator it = args_->begin(); it != args_->end(); ++it) { errors += (*it)->elaborate_expr(ent, scope, ltype); } } return errors; } int ExpObjAttribute::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) { int errors = 0; const VType*sub_type = base_->probe_type(ent, scope); errors += elaborate_args(ent, scope, sub_type); errors += base_->elaborate_expr(ent, scope, sub_type); return errors; } const VType* ExpObjAttribute::probe_type(Entity*, ScopeBase*) const { if (name_ == "length" || name_ == "left" || name_ == "right") return &primitive_NATURAL; return NULL; } int ExpTypeAttribute::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { return elaborate_args(ent, scope, ltype); } const VType* ExpTypeAttribute::probe_type(Entity*, ScopeBase*) const { if(name_ == "image") return &primitive_STRING; return NULL; } const VType*ExpBitstring::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const { // Really should check that this string can work with the // array element type? return atype->element_type(); } int ExpBitstring::elaborate_expr(Entity*, ScopeBase*, const VType*) { int errors = 0; const VTypeArray*type = new VTypeArray(&primitive_STDLOGIC, value_.size() - 1, 0); set_type(type); return errors; } const VType*ExpCharacter::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const { // Really should check that this character can work with the // array element type? return atype->element_type(); } int ExpCharacter::elaborate_expr(Entity*, ScopeBase*, const VType*ltype) { ivl_assert(*this, ltype != 0); set_type(ltype); return 0; } const VType*ExpConcat::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*atype) const { Expression*operands[2] = {operand1_, operand2_}; const VType*types[2] = {NULL, NULL}; Expression*sizes[2] = {NULL, NULL}; // determine the type and size of concatenated expressions for(int i = 0; i < 2; ++i) { types[i] = operands[i]->fit_type(ent, scope, atype); if(const VTypeArray*arr = dynamic_cast(types[i])) { types[i] = arr->element_type(); ivl_assert(*this, arr->dimensions().size() == 1); const VTypeArray::range_t&dim = arr->dimension(0); sizes[i] = new ExpArithmetic(ExpArithmetic::MINUS, dim.msb(), dim.lsb()); } else { sizes[i] = new ExpInteger(0); } } // the range of the concatenated expression is (size1 + size2 + 1):0 // note that each of the sizes are already decreased by one, // e.g. 3:0 <=> size == 3 even though there are 4 bits Expression*size = new ExpArithmetic(ExpArithmetic::PLUS, new ExpArithmetic(ExpArithmetic::PLUS, sizes[0], sizes[1]), new ExpInteger(1)); std::list ranges; ranges.push_front(new ExpRange(size, new ExpInteger(0), ExpRange::DOWNTO)); const VType*array = new VTypeArray(types[1], &ranges); return array; } /* * I don't know how to probe the type of a concatenation, quite yet. */ const VType*ExpConcat::probe_type(Entity*, ScopeBase*) const { ivl_assert(*this, 0); return 0; } int ExpConcat::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); if (const VTypeArray*atype = dynamic_cast(ltype)) { errors += elaborate_expr_array_(ent, scope, atype); } else { errors += operand1_->elaborate_expr(ent, scope, ltype); errors += operand2_->elaborate_expr(ent, scope, ltype); } return errors; } int ExpConcat::elaborate_expr_array_(Entity*ent, ScopeBase*scope, const VTypeArray*atype) { int errors = 0; // For now, only support single-dimension arrays here. ivl_assert(*this, atype->dimensions().size() == 1); const VType*type1 = operand1_->fit_type(ent, scope, atype); ivl_assert(*this, type1); const VType*type2 = operand2_->fit_type(ent, scope, atype); ivl_assert(*this, type2); errors += operand1_->elaborate_expr(ent, scope, type1); errors += operand2_->elaborate_expr(ent, scope, type2); return errors; } const VType* ExpConditional::probe_type(Entity*, ScopeBase*) const { return 0; } int ExpConditional::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) ltype = probe_type(ent, scope); ivl_assert(*this, ltype); set_type(ltype); /* Note that the type for the condition expression need not have anything to do with the type of this expression. */ for (list::const_iterator cur = options_.begin() ; cur != options_.end() ; ++cur) { errors += (*cur)->elaborate_expr(ent, scope, ltype); } return errors; } int ExpConditional::case_t::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (cond_) errors += cond_->elaborate_expr(ent, scope, 0); for (list::const_iterator cur = true_clause_.begin() ; cur != true_clause_.end() ; ++cur) { errors += (*cur)->elaborate_expr(ent, scope, ltype); } return errors; } const VType*ExpFunc::probe_type(Entity*ent, ScopeBase*scope) const { if(!def_) def_ = match_signature(ent, scope); return def_ ? def_->exact_return_type(argv_, ent, scope) : NULL; } int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) { int errors = 0; if(def_) return 0; def_ = match_signature(ent, scope); if(!def_) return 1; // Elaborate arguments for (size_t idx = 0; idx < argv_.size(); ++idx) { errors += def_->elaborate_argument(argv_[idx], idx, ent, scope); } // SystemVerilog functions work only with defined size data types, therefore // if header does not specify argument or return type size, create a function // instance that work with this particular size. if(def_ && !def_->is_std() && def_->unbounded()) { def_ = def_->make_instance(argv_, scope); name_ = def_->name(); // TODO necessary? } return errors; } const VType* ExpFunc::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*) const { return probe_type(ent, scope); } const VType* ExpInteger::probe_type(Entity*, ScopeBase*) const { if(value_ >= 0) return &primitive_NATURAL; else return &primitive_INTEGER; } int ExpInteger::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); return errors; } const VType* ExpReal::probe_type(Entity*, ScopeBase*) const { return &primitive_REAL; } int ExpReal::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); return errors; } int ExpLogical::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, scope, ltype); return errors; } const VType* ExpName::probe_prefix_type_(Entity*ent, ScopeBase*scope) const { if (prefix_.get()) { cerr << get_fileline() << ": sorry: I do not know how to support nested prefix parts." << endl; return 0; } const VType*type = probe_type(ent, scope); return type; } /* * This method is the probe_type() implementation for ExpName objects * that have prefix parts. In this case we try to get the type of the * prefix and interpret the name in that context. */ const VType* ExpName::probe_prefixed_type_(Entity*ent, ScopeBase*scope) const { // First, get the type of the prefix. const VType*prefix_type = prefix_->probe_prefix_type_(ent, scope); if (prefix_type == 0) { return 0; } while (const VTypeDef*def = dynamic_cast (prefix_type)) { prefix_type = def->peek_definition(); } const VType*element_type = prefix_type; bool type_changed = true; // Keep unwinding the type until we find the basic element type while (type_changed) { type_changed = false; // If the prefix type is a record, then the current name is // the name of a member. if (const VTypeRecord*pref_record = dynamic_cast(element_type)) { const VTypeRecord::element_t*element = pref_record->element_by_name(name_); ivl_assert(*this, element); element_type = element->peek_type(); ivl_assert(*this, element_type); type_changed = true; } if (const VTypeArray*pref_array = dynamic_cast(element_type)) { element_type = pref_array->basic_type(false); ivl_assert(*this, element_type); type_changed = true; } } if(!element_type) { cerr << get_fileline() << ": sorry: I don't know how to probe " << "prefix type " << typeid(*prefix_type).name() << " of " << name_ << "." << endl; return NULL; } return element_type; } const VType* ExpName::probe_type(Entity*ent, ScopeBase*scope) const { if (prefix_.get()) return probe_prefixed_type_(ent, scope); if(ent) { if (const InterfacePort*cur = ent->find_port(name_)) { ivl_assert(*this, cur->type); return cur->type; } if (const InterfacePort*cur = ent->find_generic(name_)) { ivl_assert(*this, cur->type); return cur->type; } } if(scope) { if (Signal*sig = scope->find_signal(name_)) return sig->peek_type(); if (Variable*var = scope->find_variable(name_)) return var->peek_type(); const VType*type = 0; Expression*cval = 0; if (scope->find_constant(name_, type, cval)) return type; Architecture*arc = dynamic_cast(scope); if (arc && (type = arc->probe_genvar_type(name_))) { return type; } if (const InterfacePort*port = scope->find_param(name_)) { return port->type; } if ((type = scope->is_enum_name(name_))) { return type; } } if(ent || scope) { // Do not display error messages if there was no entity or scope // specified. There are functions that are called without any specific // context and they still may want to probe the expression type. cerr << get_fileline() << ": error: Signal/variable " << name_ << " not found in this context." << endl; } return 0; } const VType* ExpName::fit_type(Entity*ent, ScopeBase*scope, const VTypeArray*)const { return probe_type(ent, scope); } int ExpName::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { if (ltype) { ivl_assert(*this, ltype != 0); set_type(ltype); } if(prefix_.get()) prefix_.get()->elaborate_expr(ent, scope, NULL); if (indices_) { for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { (*it)->elaborate_expr(ent, scope, &primitive_INTEGER); } } return 0; } const VType* ExpNameALL::probe_type(Entity*, ScopeBase*) const { return 0; } const VType* ExpRelation::probe_type(Entity*, ScopeBase*) const { return &type_BOOLEAN; } int ExpRelation::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); // The type of the operands must match, but need not match the // type for the ExpRelation itself. So get the operand type // separately. const VType*otype = ExpBinary::probe_type(ent, scope); errors += elaborate_exprs(ent, scope, otype); return errors; } int ExpShift::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (ltype == 0) { ltype = probe_type(ent, scope); } ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, scope, ltype); return errors; } /* * When a string appears in a concatenation, then the type of the * string is an array with the same element type of the concatenation, * but with elements for each character of the string. */ const VType*ExpString::fit_type(Entity*, ScopeBase*, const VTypeArray*atype) const { vector range (atype->dimensions()); // Generate an array range for this string ivl_assert(*this, range.size() == 1); VTypeArray*type = new VTypeArray(atype->element_type(), value_.size(), 0); return type; } int ExpString::elaborate_expr(Entity*, ScopeBase*, const VType*ltype) { ivl_assert(*this, ltype != 0); set_type(ltype); return 0; } int ExpTime::elaborate_expr(Entity*, ScopeBase*, const VType*) { set_type(&primitive_INTEGER); return 0; } int ExpRange::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*) { int errors = 0; if(left_) errors += left_->elaborate_expr(ent, scope, &primitive_INTEGER); if(right_) errors += right_->elaborate_expr(ent, scope, &primitive_INTEGER); return errors; } int ExpDelay::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; errors += expr_->elaborate_expr(ent, scope, ltype); errors += delay_->elaborate_expr(ent, scope, ltype); return errors; } iverilog-12_0/vhdlpp/expression_emit.cc000066400000000000000000000717651435245347300204100ustar00rootroot00000000000000/* * Copyright (c) 2011-2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2015 / Stephen Williams (steve@icarus.com) * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "expression.h" # include "vtype.h" # include "architec.h" # include "package.h" # include "std_funcs.h" # include "std_types.h" # include "parse_types.h" # include # include # include # include # include "ivl_assert.h" # include using namespace std; inline static int emit_logic(char val, ostream& out, const VTypePrimitive::type_t type) { // TODO case 'W': case 'L': case 'H': switch (val) { case '-': case 'U': val = 'x'; /* fall through */ case 'X': case 'Z': assert(type == VTypePrimitive::STDLOGIC); /* fall through */ case '0': case '1': out << (char) tolower(val); break; default: assert(false); out << "x"; return 1; } return 0; } int Expression::emit(ostream&out, Entity*, ScopeBase*) const { out << " /* " << get_fileline() << ": internal error: " << "I don't know how to emit this expression! " << "type=" << typeid(*this).name() << " */ "; return 1; } int Expression::emit_package(ostream&out) const { out << " /* " << get_fileline() << ": internal error: " << "I don't know how to emit_package this expression! " << "type=" << typeid(*this).name() << " */ "; return 1; } bool Expression::is_primary(void) const { return false; } int ExpBinary::emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; bool oper_primary = operand1_->is_primary(); if (! oper_primary) out << "("; errors += operand1_->emit(out, ent, scope); if (! oper_primary) out << ")"; return errors; } int ExpBinary::emit_operand2(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; bool oper_primary = operand2_->is_primary(); if (! oper_primary) out << "("; errors += operand2_->emit(out, ent, scope); if (! oper_primary) out << ")"; return errors; } int ExpUnary::emit_operand1(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; errors += operand1_->emit(out, ent, scope); return errors; } int ExpAggregate::emit(ostream&out, Entity*ent, ScopeBase*scope) const { if (peek_type() == 0) { out << "/* " << get_fileline() << ": internal error: " << "Aggregate literal needs well defined type." << endl; return 1; } const VType*use_type = peek_type(); while (const VTypeDef*def = dynamic_cast (use_type)) { use_type = def->peek_definition(); } if (const VTypeArray*atype = dynamic_cast (use_type)) return emit_array_(out, ent, scope, atype); else if (const VTypeRecord*arecord = dynamic_cast (use_type)) return emit_record_(out, ent, scope, arecord); out << "/* " << get_fileline() << ": internal error: " << "I don't know how to elab/emit aggregate in " << typeid(use_type).name() << " type context. */"; return 1; } int ExpAggregate::emit_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*atype) const { int errors = 0; // Special case: The aggregate is a single "others" item. if (aggregate_.size() == 1 && aggregate_[0].choice->others()) { assert(atype->dimensions().size() == 1); const VTypeArray::range_t&rang = atype->dimension(0); assert(! rang.is_box()); int64_t use_msb; int64_t use_lsb; bool rc_msb, rc_lsb; rc_msb = rang.msb()->evaluate(ent, scope, use_msb); rc_lsb = rang.lsb()->evaluate(ent, scope, use_lsb); if (rc_msb && rc_lsb) { int asize = (use_msb >= use_lsb) ? (use_msb - use_lsb) + 1 : (use_lsb - use_msb) + 1; out << "{" << asize << "{"; errors += aggregate_[0].expr->emit(out, ent, scope); out << "}}"; } else { out << "{("; if (rc_msb) { out << use_msb; } else { out << "("; errors += rang.msb()->emit(out, ent, scope); out << ")"; } if (rc_lsb && use_lsb==0) { } else if (rc_lsb) { out << "-" << use_lsb; } else { out << "-("; errors += rang.lsb()->emit(out, ent, scope); out << ")"; } out << "+1){"; errors += aggregate_[0].expr->emit(out, ent, scope); out << "}}"; } return errors; } const VTypeArray::range_t&rang = atype->dimension(0); assert(! rang.is_box()); // Fully calculate the range numbers. int64_t use_msb, use_lsb; bool rc; rc = rang.msb()->evaluate(ent, scope, use_msb); ivl_assert(*this, rc); rc = rang.lsb()->evaluate(ent, scope, use_lsb); ivl_assert(*this, rc); if(use_msb < use_lsb) swap(use_msb, use_lsb); map element_map; const choice_element*element_other = 0; bool positional_section = true; int64_t positional_idx = use_msb; for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { if (aggregate_[idx].choice == 0) { // positional association! if (!positional_section) { cerr << get_fileline() << ": error: " << "All positional associations must be before" << " any named associations." << endl; errors += 1; } element_map[positional_idx] = &aggregate_[idx]; positional_idx -= 1; continue; } if (aggregate_[idx].choice->others()) { ivl_assert(*this, element_other == 0); element_other = &aggregate_[idx]; continue; } // If this is a range choice, then calculate the bounds // of the range and scan through the values, mapping the // value to the aggregate_[idx] element. if (ExpRange*range = aggregate_[idx].choice->range_expressions()) { int64_t begin_val, end_val; if (! range->msb()->evaluate(ent, scope, begin_val)) { cerr << range->msb()->get_fileline() << ": error: " << "Unable to evaluate aggregate choice expression." << endl; errors += 1; continue; } if (! range->lsb()->evaluate(ent, scope, end_val)) { cerr << range->msb()->get_fileline() << ": error: " << "Unable to evaluate aggregate choice expression." << endl; errors += 1; continue; } if (begin_val < end_val) { int64_t tmp = begin_val; begin_val = end_val; end_val = tmp; } while (begin_val >= end_val) { element_map[begin_val] = &aggregate_[idx]; begin_val -= 1; } continue; } int64_t tmp_val; Expression*tmp = aggregate_[idx].choice->simple_expression(false); ivl_assert(*this, tmp); // Named aggregate element. Once we see one of // these, we can no longer accept positional // elements so disable further positional // processing. positional_section = false; if (! tmp->evaluate(ent, scope, tmp_val)) { cerr << tmp->get_fileline() << ": error: " << "Unable to evaluate aggregate choice expression." << endl; errors += 1; continue; } element_map[tmp_val] = &aggregate_[idx]; } // Emit the elements as a concatenation. This works great for // vectors of bits. We implement VHDL arrays as packed arrays, // so this should be generally correct. // TODO uncomment this once ivl supports assignments of '{} /*if(!peek_type()->can_be_packed()) out << "'";*/ out << "{"; for (int64_t idx = use_msb ; idx >= use_lsb ; idx -= 1) { const choice_element*cur = element_map[idx]; if (cur == 0) cur = element_other; if (idx < use_msb) out << ", "; if (cur == 0) { out << "/* Missing element " << idx << " */"; cerr << get_fileline() << ": error: " << "Missing element " << idx << "." << endl; errors += 1; } else { errors += cur->expr->emit(out, ent, scope); } } out << "}"; return errors; } int ExpAggregate::emit_record_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeRecord*) const { int errors = 0; out << "{"; for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { ivl_assert(*this, !aggregate_[idx].choice->others()); ivl_assert(*this, !aggregate_[idx].choice->range_expressions()); //Expression*name = aggregate_[idx].choice->simple_expression(false); //ivl_assert(*this, name); Expression*val = aggregate_[idx].expr; ivl_assert(*this, val); if(idx != 0) out << ","; //errors += name->emit(out, ent, scope); //out << ": "; errors += val->emit(out, ent, scope); } out << "}"; return errors; } int ExpObjAttribute::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; // Try to evaluate first int64_t val; if(evaluate(ent, scope, val)) { out << val; return 0; } if (name_ == "event") { out << "$ivlh_attribute_event("; errors += base_->emit(out, ent, scope); out << ")"; return errors; } /* Special Case: The length,left & right attributes can be calculated all the down to a literal integer at compile time, and all it needs is the type of the base expression. (The base expression doesn't even need to be evaluated.) */ if (name_=="length") { out << "$bits("; errors += base_->emit(out, ent, scope); out << ")"; return errors; } else if (name_=="left" || name_=="right") { out << "$" << name_ << "("; errors += base_->emit(out, ent, scope); out << ")"; return errors; } // Fallback out << "$ivl_attribute("; errors += base_->emit(out, ent, scope); out << ", \"" << name_ << "\")"; return errors; } int ExpTypeAttribute::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; // Special case: The image attribute if (name_=="image") { if(!args_ || args_->size() != 1) { out << "/* Invalid 'image attribute */" << endl; cerr << get_fileline() << ": error: 'image attribute takes " << "exactly one argument." << endl; ++errors; } else { out << "$sformatf(\""; if(base_->type_match(&primitive_INTEGER)) out << "%0d"; else if(base_->type_match(&primitive_REAL)) out << "%f"; else if(base_->type_match(&primitive_CHARACTER)) out << "'%c'"; else if(base_->type_match(&primitive_TIME)) out << "%+0t"; out << "\","; args_->front()->emit(out, ent, scope); out << ")"; } return errors; } // Fallback out << "$ivl_attribute("; errors += base_->emit_def(out, empty_perm_string); out << ", \"" << name_ << "\")"; return errors; } int ExpArithmetic::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; if(fun_ == REM) { // Special case: division remainder, defined in the VHDL standard 1076-2008/9.2.7 // there is no direct counterpart, therefore output the formula to // compute a remainder: A rem B = A - (A/B) * B; out << "(("; errors += emit_operand1(out, ent, scope); out << ")-(("; errors += emit_operand1(out, ent, scope); out << ")/("; errors += emit_operand2(out, ent, scope); out << "))*("; errors += emit_operand2(out, ent, scope); out << "))"; return errors; } errors += emit_operand1(out, ent, scope); switch (fun_) { case PLUS: out << " + "; break; case MINUS: out << " - "; break; case MULT: out << " * "; break; case DIV: out << " / "; break; case MOD: out << " % "; break; case POW: out << " ** "; break; case REM: // should not happen as it is handled above, suppress warnings ivl_assert(*this, 0); case xCONCAT: ivl_assert(*this, 0); out << " /* ?concat? */ "; break; } errors += emit_operand2(out, ent, scope); return errors; } int ExpBitstring::emit(ostream&out, Entity*, ScopeBase*) const { int errors = 0; out << value_.size() << "'b"; for (size_t idx = 0 ; idx < value_.size() ; idx += 1) out << value_[value_.size()-idx-1]; return errors; } int ExpCharacter::emit_primitive_bit_(ostream&out, Entity*, ScopeBase*, const VTypePrimitive*etype) const { out << "1'b"; int res = emit_logic(value_, out, etype->type()); if(res) cerr << get_fileline() << ": internal error: " << "Don't know how to handle bit " << value_ << " with etype==" << etype->type() << endl; return res; } int ExpCharacter::emit(ostream&out, Entity*ent, ScopeBase*scope) const { const VType*etype = peek_type(); const VTypeArray*array; if (etype != &primitive_CHARACTER && (array = dynamic_cast(etype))) { etype = array->element_type(); } if (const VTypePrimitive*use_type = dynamic_cast(etype)) { return emit_primitive_bit_(out, ent, scope, use_type); } out << "\"" << value_ << "\""; return 0; } bool ExpCharacter::is_primary(void) const { return true; } /* * This is not exactly a "primary", but it is wrapped in its own * parentheses (braces) so we return true here. */ bool ExpConcat::is_primary(void) const { return true; } int ExpConcat::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "{"; errors += operand1_->emit(out, ent, scope); out << ", "; errors += operand2_->emit(out, ent, scope); out << "}"; return errors; } int ExpConditional::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "("; // Draw out any when-else expressions. These are all the else_ // clauses besides the last. if (options_.size() > 1) { list::const_iterator last = options_.end(); --last; for (list::const_iterator cur = options_.begin() ; cur != last ; ++cur) { errors += (*cur)->emit_option(out, ent, scope); } } errors += options_.back()->emit_default(out, ent, scope); out << ")"; // The emit_option() functions do not close the last // parentheses so that the following expression can be // nested. But that means come the end, we have some // expressions to close. for (size_t idx = 1 ; idx < options_.size() ; idx += 1) out << ")"; return errors; } int ExpConditional::case_t::emit_option(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; assert(cond_ != 0); out << "("; errors += cond_->emit(out, ent, scope); out << ")? ("; if (true_clause_.size() > 1) { cerr << get_fileline() << ": sorry: Multiple expression waveforms not supported here." << endl; errors += 1; } Expression*tmp = true_clause_.front(); errors += tmp->emit(out, ent, scope); out << ") : ("; return errors; } int ExpConditional::case_t::emit_default(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; // Trailing else must have no condition. assert(cond_ == 0); if (true_clause_.size() > 1) { cerr << get_fileline() << ": sorry: Multiple expression waveforms not supported here." << endl; errors += 1; } Expression*tmp = true_clause_.front(); errors += tmp->emit(out, ent, scope); return errors; } int ExpEdge::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; switch (fun_) { case NEGEDGE: out << "negedge "; break; case POSEDGE: out << "posedge "; break; case ANYEDGE: break; } errors += emit_operand1(out, ent, scope); return errors; } int ExpFunc::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; if(!def_) { cerr << get_fileline() << ": error: unknown function: " << name_ << endl; return 1; } def_->emit_full_name(argv_, out, ent, scope); out << " ("; def_->emit_args(argv_, out, ent, scope); out << ")"; return errors; } int ExpInteger::emit(ostream&out, Entity*, ScopeBase*) const { out << "32'd" << value_; return 0; } int ExpInteger::emit_package(ostream&out) const { out << value_; return 0; } int ExpReal::emit(ostream&out, Entity*, ScopeBase*) const { out << value_; return 0; } int ExpReal::emit_package(ostream&out) const { out << value_; return 0; } bool ExpReal::is_primary(void) const { return true; } int ExpLogical::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; errors += emit_operand1(out, ent, scope); switch (fun_) { case AND: out << " & "; break; case OR: out << " | "; break; case XOR: out << " ^ "; break; case NAND: out << " ~& "; break; case NOR: out << " ~| "; break; case XNOR: out << " ~^ "; break; } errors += emit_operand2(out, ent, scope); return errors; } int ExpName::emit_indices(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; if (indices_) { for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { out << "["; errors += (*it)->emit(out, ent, scope); out << "]"; } } return errors; } int ExpName::emit_as_prefix_(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; if (prefix_.get()) { errors += prefix_->emit_as_prefix_(out, ent, scope); } out << "\\" << name_ << " "; errors += emit_indices(out, ent, scope); out << "."; return errors; } int ExpName::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; int field_size = 0; list indices; if(try_workarounds_(out, ent, scope, indices, field_size)) { emit_workaround_(out, ent, scope, indices, field_size); for(list::iterator it = indices.begin(); it != indices.end(); ++it) { delete *it; } return 0; } if (prefix_.get()) { errors += prefix_->emit_as_prefix_(out, ent, scope); } const GenerateStatement*gs = 0; Architecture*arc = dynamic_cast(scope); if (arc && (gs = arc->probe_genvar_emit(name_))) out << "\\" << gs->get_name() << ":" << name_ << " "; else out << "\\" << name_ << " "; errors += emit_indices(out, ent, scope); return errors; } bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope, list& indices, int& data_size) const { Expression*exp = NULL; bool wrkand_required = false; const VType*type = NULL; Expression*idx = index(0); ExpRange*range = dynamic_cast(idx); if(!scope) return false; if(prefix_.get()) prefix_->try_workarounds_(out, ent, scope, indices, data_size); if(idx && !range && scope->find_constant(name_, type, exp)) { while(const VTypeDef*type_def = dynamic_cast(type)) { type = type_def->peek_definition(); } const VTypeArray*arr = dynamic_cast(type); assert(arr); wrkand_required |= check_const_array_workaround_(arr, scope, indices, data_size); } if(prefix_.get() && scope->find_constant(prefix_->name_, type, exp)) { // Handle the case of array of records if(prefix_->index(0)) { const VTypeArray*arr = dynamic_cast(type); assert(arr); type = arr->element_type(); data_size = type->get_width(scope); } while(const VTypeDef*type_def = dynamic_cast(type)) { type = type_def->peek_definition(); } const VTypeRecord*rec = dynamic_cast(type); assert(rec); wrkand_required |= check_const_record_workaround_(rec, scope, indices, data_size); } // Workarounds are currently implemented only for one-dimensional arrays assert(!indices_ || indices_->size() == 1 || !wrkand_required); return wrkand_required; } bool ExpName::check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope, list&indices, int&data_size) const { assert(indices_ && indices_->size() == 1); const VType*element = arr->element_type(); data_size = element->get_width(scope); if(data_size < 0) return false; indices.push_back(new index_t(index(0)->clone(), new ExpInteger(data_size))); return true; } bool ExpName::check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope, list&indices, int&data_size) const { int tmp_offset = 0; const vector& elements = rec->get_elements(); for(vector::const_reverse_iterator it = elements.rbegin(); it != elements.rend(); ++it) { VTypeRecord::element_t* el = (*it); if(el->peek_name() == name_) { const VType*type = el->peek_type(); int tmp_field = type->get_width(scope); if(tmp_field < 0) return false; data_size = tmp_field; indices.push_back(new index_t(NULL, NULL, new ExpInteger(tmp_offset))); if(index(0)) { const VTypeArray*arr = dynamic_cast(type); assert(arr); return check_const_array_workaround_(arr, scope, indices, data_size); } return true; } int w = el->peek_type()->get_width(scope); if(w < 0) return false; tmp_offset += w; } return false; } int ExpName::emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope, const list& indices, int field_size) const { int errors = 0; out << "\\" << (prefix_.get() ? prefix_->name_ : name_) << " ["; for(list::const_iterator it = indices.begin(); it != indices.end(); ++it) { errors += (*it)->emit(out, ent, scope); out << "+"; } out << ":" << field_size << "]"; return errors; } bool ExpName::is_primary(void) const { return true; } int ExpRelation::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; errors += emit_operand1(out, ent, scope); const VType*type1 = peek_operand1()->probe_type(ent, scope); const VType*type2 = peek_operand2()->probe_type(ent, scope); bool logical_compare = false; // Apply case equality operator if any of the operands is of logic type if(((type1 && (type1->type_match(&primitive_STDLOGIC) || type1->type_match(&primitive_STDLOGIC_VECTOR))) || (type2 && (type2->type_match(&primitive_STDLOGIC) || type2->type_match(&primitive_STDLOGIC_VECTOR))))) { logical_compare = true; } switch (fun_) { case EQ: out << (logical_compare ? " === " : " == "); break; case LT: out << " < "; break; case GT: out << " > "; break; case NEQ: out << (logical_compare ? " !== " : " != "); break; case LE: out << " <= "; break; case GE: out << " >= "; break; } errors += emit_operand2(out, ent, scope); return errors; } int ExpShift::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; errors += emit_operand1(out, ent, scope); switch (shift_) { case SRL: out << " >> "; break; case SLL: out << " << "; break; case SRA: out << " >>> "; break; case SLA: out << " <<< "; break; case ROR: case ROL: out << " /* ?ror/rol? */ "; break; } errors += emit_operand2(out, ent, scope); return errors; } bool ExpString::is_primary(void) const { return true; } int ExpString::emit(ostream& out, Entity*ent, ScopeBase*scope) const { const VTypeArray*arr; const VType*type = peek_type(); assert(type != 0); if (type != &primitive_STRING && (arr = dynamic_cast(type))) { return emit_as_array_(out, ent, scope, arr); } out << "\"" << escape_quot(value_) << "\""; return 0; } int ExpString::emit_as_array_(ostream& out, Entity*, ScopeBase*, const VTypeArray*arr) const { int errors = 0; assert(arr->dimensions().size() == 1); const VTypePrimitive*etype = dynamic_cast (arr->basic_type()); assert(etype); // Detect the special case that this is an array of // CHARACTER. In this case, emit at a Verilog string. if (arr->element_type() == &primitive_CHARACTER) { vector tmp (value_.size() + 3); tmp[0] = '"'; memcpy(&tmp[1], &value_[0], value_.size()); tmp[value_.size()+1] = '"'; tmp[value_.size()+2] = 0; out << &tmp[0]; return errors; } assert(etype->type() != VTypePrimitive::INTEGER); out << value_.size() << "'b"; for (size_t idx = 0 ; idx < value_.size() ; idx += 1) { int res = emit_logic(value_[idx], out, etype->type()); errors += res; if(res) cerr << get_fileline() << ": internal error: " << "Don't know how to handle bit " << value_[idx] << " with etype==" << etype->type() << endl; } return errors; } std::string ExpString::escape_quot(const std::string& str) { size_t idx = 0; string result(str); while((idx = result.find('"', idx)) != string::npos) { result.replace(idx, 1, "\\\""); idx += 2; } return result; } int ExpUAbs::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "abs("; errors += emit_operand1(out, ent, scope); out << ")"; return errors; } int ExpUNot::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; const VType*op_type = peek_operand()->probe_type(ent, scope); if(op_type && op_type->type_match(&type_BOOLEAN)) out << "!("; else out << "~("; errors += emit_operand1(out, ent, scope); out << ")"; return errors; } int ExpUMinus::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "-("; errors += emit_operand1(out, ent, scope); out << ")"; return errors; } int ExpCast::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; errors += type_->emit_def(out, empty_perm_string); out << "'("; errors += base_->emit(out, ent, scope); out << ")"; return errors; } int ExpNew::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "new["; errors += size_->emit(out, ent, scope); out << "]"; return errors; } int ExpTime::emit(ostream&out, Entity*, ScopeBase*) const { out << amount_; switch(unit_) { case FS: out << "fs"; break; case PS: out << "ps"; break; case NS: out << "ns"; break; case US: out << "us"; break; case MS: out << "ms"; break; case S: out << "s"; break; } return 0; } int ExpRange::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; if(range_expr_) { out << "$left("; errors += range_base_->emit(out, ent, scope); out << "):$right("; errors += range_base_->emit(out, ent, scope); out << ")"; } else if(direction_ == AUTO) { ivl_assert(*this, false); out << "/* auto dir */"; } else { errors += left_->emit(out, ent, scope); out << ":"; errors += right_->emit(out, ent, scope); } return errors; } int ExpDelay::emit(ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; out << "#("; errors += delay_->emit(out, ent, scope); out << ") "; errors += expr_->emit(out, ent, scope); return errors; } iverilog-12_0/vhdlpp/expression_evaluate.cc000066400000000000000000000124411435245347300212420ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2015 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "expression.h" # include "architec.h" # include # include # include using namespace std; bool ExpArithmetic::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const { int64_t val1, val2; bool rc; rc = eval_operand1(ent, scope, val1); if (rc == false) return false; rc = eval_operand2(ent, scope, val2); if (rc == false) return false; switch (fun_) { case PLUS: val = val1 + val2; break; case MINUS: val = val1 - val2; break; case MULT: val = val1 * val2; break; case DIV: if (val2 == 0) return false; val = val1 / val2; break; case MOD: if (val2 == 0) return false; val = val1 % val2; break; case REM: if (val2 == 0) return false; val = val1 - (val1 / val2) * val2; return false; case POW: val = (int64_t) pow(val1, val2); break; case xCONCAT: // not possible return false; } return true; } bool ExpAttribute::test_array_type(const VType*type) const { const VTypeArray*arr = dynamic_cast(type); if (arr == 0) { cerr << endl << get_fileline() << ": error: " << "Cannot apply the '" << name_ << " attribute to non-array objects" << endl; ivl_assert(*this, false); return false; } if (arr->dimensions().size() > 1) { cerr << endl << get_fileline() << ": error: " << "Cannot apply the '" << name_ << " attribute to multidimensional arrays" << endl; return false; } if (arr->dimension(0).is_box()) return false; return true; } bool ExpAttribute::evaluate_type_attr(const VType*type, Entity*ent, ScopeBase*scope, int64_t&val) const { if (name_ == "length" && test_array_type(type)) { int64_t size = type->get_width(scope); if(size > 0) { val = size; return true; } } else if (name_ == "left" && test_array_type(type)) { const VTypeArray*arr = dynamic_cast(type); return arr->dimension(0).msb()->evaluate(ent, scope, val); } else if (name_ == "right" && test_array_type(type)) { const VTypeArray*arr = dynamic_cast(type); return arr->dimension(0).lsb()->evaluate(ent, scope, val); } return false; } bool ExpObjAttribute::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const { const VType*base_type = base_->peek_type(); if (base_type == NULL) base_type = base_->probe_type(ent, scope); if (base_type) return evaluate_type_attr(base_type, ent, scope, val); return false; } bool ExpTypeAttribute::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const { return evaluate_type_attr(base_, ent, scope, val); } bool ExpName::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const { if (prefix_.get()) { cerr << get_fileline() << ": sorry: I don't know how to evaluate " << "ExpName prefix parts." << endl; return false; } if (scope) { const VType*type; Expression*exp; if (scope->find_constant(name_, type, exp)) return exp->evaluate(ent, scope, val); } return false; } bool ExpShift::evaluate(Entity*ent, ScopeBase*scope, int64_t&val) const { int64_t val1, val2; bool rc; rc = eval_operand1(ent, scope, val1); if (rc == false) return false; rc = eval_operand2(ent, scope, val2); if (rc == false) return false; switch (shift_) { case SRL: val = (uint64_t)val1 >> (uint64_t)val2; break; case SLL: val = (uint64_t)val1 << (uint64_t)val2; break; case SRA: val = (int64_t)val1 >> (int64_t)val2; break; case SLA: val = (int64_t)val1 << (int64_t)val2; break; case ROR: case ROL: return false; } return true; } /*bool ExpTime::evaluate(Entity*, ScopeBase*, int64_t&val) const { double v = to_fs(); if(v > std::numeric_limits::max()) { val = std::numeric_limits::max(); cerr << get_fileline() << ": sorry: Time value is higher than the " << "handled limit, reduced to " << val << " fs." << endl; } val = v; return true; } }*/ iverilog-12_0/vhdlpp/expression_stream.cc000066400000000000000000000173221435245347300207320ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "expression.h" # include "parse_types.h" # include # include using namespace std; void ExpAggregate::write_to_stream(ostream&fd) const { fd << "("; for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { if(cur != elements_.begin()) fd << ", "; (*cur)->write_to_stream(fd); } fd << ")"; } void ExpAggregate::element_t::write_to_stream(ostream&fd) const { for (vector::const_iterator cur = fields_.begin() ; cur != fields_.end() ; ++cur) { (*cur)->write_to_stream(fd); } if(!fields_.empty()) fd << "=>"; val_->write_to_stream(fd); } void ExpAggregate::choice_t::write_to_stream(ostream&fd) { if (others()) { fd << "others"; return; } if (Expression*sim = simple_expression()) { sim->write_to_stream(fd); return; } if (ExpRange*rp = range_expressions()) { rp->write_to_stream(fd); return; } fd << "/* ERROR */"; } void ExpArithmetic::write_to_stream(ostream&out) const { out << "("; write_to_stream_operand1(out); out << ")"; switch (fun_) { case PLUS: out << "+"; break; case MINUS: out << "-"; break; case MULT: out << "*"; break; case DIV: out << "/"; break; case MOD: out << "mod"; break; case REM: out << "rem"; break; case POW: out << "**"; break; case xCONCAT: ivl_assert(*this, 0); break; } out << "("; write_to_stream_operand2(out); out << ")"; } void ExpObjAttribute::write_to_stream(ostream&fd) const { base_->write_to_stream(fd); fd << "'" << name_; } void ExpTypeAttribute::write_to_stream(ostream&fd) const { base_->write_to_stream(fd); fd << "'" << name_; } void ExpBitstring::write_to_stream(ostream&fd) const { fd << "B\""; for(vector::const_reverse_iterator it = value_.rbegin(); it != value_.rend(); ++it) { fd << *it; } fd << "\""; } void ExpCharacter::write_to_stream(ostream&fd) const { char buf[4]; buf[0] = '\''; buf[1] = value_; buf[2] = '\''; buf[3] = 0; fd << buf; } void ExpConcat::write_to_stream(ostream&fd) const { fd << "("; operand1_->write_to_stream(fd); fd << ")&("; operand2_->write_to_stream(fd); fd << ")"; } void ExpConditional::write_to_stream(ostream&) const { ivl_assert(*this, !"Not supported"); } void ExpEdge::write_to_stream(ostream&) const { ivl_assert(*this, !"Not supported"); } void ExpFunc::write_to_stream(ostream&fd) const { const char*comma = ""; fd << name_ << "("; for (vector::const_iterator cur = argv_.begin() ; cur != argv_.end() ; ++cur) { fd << comma; (*cur)->write_to_stream(fd); comma = ", "; } fd << ")"; } void ExpInteger::write_to_stream(ostream&fd) const { fd << value_; } void ExpReal::write_to_stream(ostream&fd) const { fd << value_; } void ExpLogical::write_to_stream(ostream&out) const { peek_operand1()->write_to_stream(out); switch (fun_) { case AND: out << " and "; break; case OR: out << " or "; break; case XOR: out << " xor "; break; case NAND: out << " nand "; break; case NOR: out << " nor "; break; case XNOR: out << " xnor "; break; } peek_operand2()->write_to_stream(out); } void ExpName::write_to_stream(ostream&fd) const { if (prefix_.get()) { prefix_->write_to_stream(fd); fd << "."; } fd << name_; if (indices_) { fd << "("; bool first = true; for(list::const_iterator it = indices_->begin(); it != indices_->end(); ++it) { if(first) first = false; else fd << ","; (*it)->write_to_stream(fd); } fd << ")"; } } void ExpRelation::write_to_stream(ostream&fd) const { peek_operand1()->write_to_stream(fd); switch(fun_) { case EQ: fd << " = "; break; case LT: fd << " < "; break; case GT: fd << " > "; break; case NEQ: fd << " != "; break; case LE: fd << " <= "; break; case GE: fd << " >= "; break; } peek_operand2()->write_to_stream(fd); } void ExpShift::write_to_stream(ostream&out) const { out << "("; write_to_stream_operand1(out); out << ")"; switch (shift_) { case SRL: out << "srl"; break; case SLL: out << "sll"; break; case SLA: out << "sla"; break; case SRA: out << "sra"; break; case ROR: out << "ror"; break; case ROL: out << "rol"; break; } out << "("; write_to_stream_operand2(out); out << ")"; } void ExpString::write_to_stream(ostream&fd) const { fd << "\""; // Restore double quotation marks for(string::const_iterator it = value_.begin(); it != value_.end(); ++it) { if(*it == '"') fd << "\"\""; else fd << *it; } fd << "\""; } void ExpUAbs::write_to_stream(ostream&fd) const { fd << "abs "; write_to_stream_operand1(fd); } void ExpUNot::write_to_stream(ostream&fd) const { fd << "not "; write_to_stream_operand1(fd); } void ExpUMinus::write_to_stream(ostream&fd) const { fd << "-("; write_to_stream_operand1(fd); fd << ")"; } void ExpCast::write_to_stream(ostream&fd) const { // Type casting is introduced only for a few specific cases in // SystemVerilog, so no need to use it here base_->write_to_stream(fd); } void ExpTime::write_to_stream(ostream&fd) const { fd << amount_; switch(unit_) { case FS: fd << " fs"; break; case PS: fd << " ps"; break; case NS: fd << " ns"; break; case US: fd << " us"; break; case MS: fd << " ms"; break; case S: fd << " s"; break; } } void ExpRange::write_to_stream(ostream&fd) const { if(range_expr_) { range_base_->write_to_stream(fd); fd << (range_reverse_ ? "'reverse_range" : "'range"); } else { left_->write_to_stream(fd); switch(direction_) { case DOWNTO: fd << " downto "; break; case TO: fd << " to "; break; default: ivl_assert(*this, false); break; } right_->write_to_stream(fd); } } void ExpDelay::write_to_stream(ostream&out) const { expr_->write_to_stream(out); out << " after "; delay_->write_to_stream(out); } iverilog-12_0/vhdlpp/ivl_assert.h000066400000000000000000000023221435245347300171670ustar00rootroot00000000000000#ifndef IVL_ivl_assert_H #define IVL_ivl_assert_H /* * Copyright (c) 2007-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 #define ivl_assert(tok, expression) \ do { \ if (! (expression)) { \ cerr << (tok).get_fileline() << ": assert: " \ << __FILE__ << ":" << __LINE__ \ << ": failed assertion " << #expression << endl; \ abort(); \ } \ } while (0) #endif /* IVL_ivl_assert_H */ iverilog-12_0/vhdlpp/lexor.lex000066400000000000000000000441671435245347300165230ustar00rootroot00000000000000%option prefix="yy" %option never-interactive %option nounput %option reentrant %option noyywrap %{ /* * Copyright (c) 2011-2017 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 * aint64_t with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # include "parse_api.h" # include "lexor_keyword.h" # include "vhdlint.h" # include "vhdlreal.h" # include "parse_wrap.h" # include # include # include # include # define YY_NO_INPUT # define YY_DECL int yylex(YYSTYPE*yylvalp, YYLTYPE*yyllocp, yyscan_t yyscanner) //class vhdlnum; //class vhdlreal; extern int lexor_keyword_code (const char*str, unsigned len); /* * Lexical location information is passed in the yylloc variable to the * parser. The file names, strings, are kept in a list so that I can * re-use them. The set_file_name function will return a pointer to * the name as it exists in the list (and delete the passed string). * If the name is new, it will be added to the list. */ #define yylloc (*yyllocp) #define yylval (*yylvalp) static bool are_underscores_correct(char* text); static bool is_based_correct(char* text); static char* escape_quot_and_dup(char* text); static char* escape_apostrophe_and_dup(char* text); static double make_double_from_based(char* text); static int64_t make_long_from_based(char* text); static char* make_bitstring_literal(const char*text); static int64_t lpow(int64_t left, int64_t right); static unsigned short short_from_hex_char(char ch); static char* strdupnew(char const *str) { return str ? strcpy(new char [strlen(str)+1], str) : 0; } static int comment_enter; %} %x CCOMMENT %x LCOMMENT W [ \t\b\f\r]+ decimal_literal {integer}(\.{integer})?({exponent})? integer [0-9](_?[0-9])* exponent [eE][-+]?{integer} based_literal {integer}#{based_integer}(\.{based_integer})?#{exponent}? based_integer [0-9a-fA-F](_?[0-9a-fA-F])* time {integer}{W}*([fFpPnNuUmM]?[sS]) %% [ \t\b\f\r] { ; } \n { yylloc.first_line += 1; } /* Single-line comments start with -- and run to the end of the current line. These are very easy to handle. */ "--".* { comment_enter = YY_START; BEGIN(LCOMMENT); } . { yymore(); } \n { yylloc.first_line += 1; BEGIN(comment_enter); } /* The contents of C-style comments are ignored, like white space. */ "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); } . { ; } \n { yylloc.first_line += 1; } "*/" { BEGIN(comment_enter); } \'.\' { yylval.text = escape_apostrophe_and_dup(yytext); return CHARACTER_LITERAL; } (\"([^\"]|(\"\"))*?\") { yylval.text = escape_quot_and_dup(yytext); assert(yylval.text); return STRING_LITERAL; } [a-zA-Z_][a-zA-Z0-9_]* { for (char*cp = yytext ; *cp ; cp += 1) *cp = tolower(*cp); int rc = lexor_keyword_code(yytext, yyleng); switch (rc) { case IDENTIFIER: if(!are_underscores_correct(yytext)) std::cerr << "An invalid underscore in the identifier:" << yytext << std::endl; //yywarn(yylloc, "An invalid underscore in the identifier"); yylval.text = strdupnew(yytext); break; default: break; } return rc; } \\([^\\]|\\\\)*\\ { /* extended identifiers */ yylval.text = strdupnew(yytext); return IDENTIFIER; } {decimal_literal} { char*tmp = new char[strlen(yytext)+1]; char*dst, *src; int rc = INT_LITERAL; for (dst = tmp, src = yytext ; *src ; ++src) { if (*src == '_') continue; if (*src == '.') rc = REAL_LITERAL; *dst++ = *src; } *dst = 0; if (rc == REAL_LITERAL) { yylval.uni_real = strtod(tmp, 0); } else { yylval.uni_integer = strtoimax(tmp, 0, 10); } delete[]tmp; return rc; } {based_literal} { for(char*cp = yytext ; *cp ; ++cp) *cp = tolower(*cp); if(!are_underscores_correct(yytext) || !is_based_correct(yytext)) std::cerr << "An invalid form of based literal:" << yytext << std::endl; if(strchr(yytext, '.')) { double val = make_double_from_based(yytext); yylval.uni_real = val; return REAL_LITERAL; } else { int64_t val = make_long_from_based(yytext); yylval.uni_integer = val; return INT_LITERAL; } } {integer}?[sSuU]?[xXbBoOdD]\"[^\"]+\" { yylval.text = make_bitstring_literal(yytext); return BITSTRING_LITERAL; } /* Compound symbols */ "<=" { return LEQ; } ">=" { return GEQ; } ":=" { return VASSIGN; } "/=" { return NE; } "<>" { return BOX; } "**" { return EXP; } "=>" { return ARROW; } "<<" { return DLT; } ">>" { return DGT; } "??" { return CC; } "?=" { return M_EQ;} "?/=" { return M_NE;} "?<" { return M_LT; } "?<=" { return M_LEQ;} "?>" { return M_GT; } "?>=" {return M_GEQ; } . { return yytext[0]; } %% extern void yyparse_set_filepath(const char*path); /** * This function checks if underscores in an identifier * or in a number are correct. * * \return true is returned if underscores are placed * correctly according to specification */ static bool are_underscores_correct(char* text) { unsigned char underscore_allowed = 0; const char* cp; for( cp = text; *cp; ++cp) { if (*cp == '_') { if (!underscore_allowed || *(cp+1) == '\0') return 0; underscore_allowed = 0; } else underscore_allowed = 1; } return 1; } static bool is_char_ok(char c, int base) { if(base <= 10) return '0' <= c && c - '0' < base; else return isdigit(c) || (c >= 'a' && c < 'a' + base - 10); } /** * This function checks if the format of a based number * is correct according to the VHDL standard * * \return true is returned if a based number * is formed well according to specification */ static bool is_based_correct(char* text) { char* ptr; //BASE examination char clean_base[4] = {0,}; char* clean_base_end = clean_base + sizeof(clean_base); char* clean_base_ptr = clean_base; for(ptr = text; ptr != strchr(text, '#'); ++ptr) { if(*ptr == '_') ++ptr; if(!(*ptr >= '0' && *ptr <= '9')) //the base uses chars other than digits return 0; if(clean_base_ptr == clean_base_end) break; *clean_base_ptr = *ptr; ++clean_base_ptr; } unsigned length = clean_base_ptr - clean_base; unsigned base; if(length > 2 || length == 0) return 0; //the base is too big or too small if(length == 2) { base = 10*(clean_base[0] - '0') + (clean_base[1] - '0'); //the base exceeds 16 or equals 0 if(base > 16 || base == 0) return 0; } else { //the base consists of one char and is equal to zero base = clean_base[0] - '0'; if(base == 0) return 0; } bool point = false; //MANTISSA examination for(ptr = strchr(text, '#') + 1, length = 0; ptr != strrchr(text, '#'); ++ptr) { if(*ptr == '.') { //we found a dot and another one was already found if(point) return 0; else { //notice the fact of finding a point and continue, without increasing the length point = true; continue; } } //check if the number consists of other chars than allowed if(!is_char_ok(*ptr, base)) return 0; ++length; } if(length == 0) return 0; //EXPONENT examination if(strchr(text, '\0') - strrchr(text, '#') > 1) { //the number contains an exponent if(*(strrchr(text, '#') + 2) == '-') return 0; length = 0; for(ptr = strrchr(text, '#')+2; *ptr != '\0'; ++ptr) { //the exponent consists of other chars than {'0'.,'9','a'..'f'} if(!((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'a' && *ptr <= 'f'))) return 0; } } return 1; } /** * This function takes a string literal, gets rid of * quotation marks and copies the remaining characters * to a new persistent C-string * * \return pointer to the new string is returned */ static char* escape_quot_and_dup(char* text) { char* newstr = new char[strlen(text)+1]; unsigned old_idx, new_idx; for(new_idx = 0, old_idx = 0; old_idx < strlen(text); ) { if(text[old_idx] == '"' && old_idx == 0) { //the beginning of the literal ++old_idx; continue; } else if(text[old_idx] == '"' && text[old_idx+1] == '\0') { //the end newstr[new_idx] = '\0'; return newstr; } else if(text[old_idx] == '"' && text[old_idx+1] == '"') { newstr[new_idx++] = '"'; old_idx += 2; //jump across two chars } else { newstr[new_idx] = text[old_idx]; ++old_idx; ++new_idx; } } //the function should never reach this point return 0; } /** * This function takes a character literal, gets rid * of the apostrophes and returns new C-string * * \return pointer to the new string is returned */ static char* escape_apostrophe_and_dup(char* text) { char* newstr = new char[2]; newstr[0] = text[1]; newstr[1] = '\0'; return newstr; } static char*make_bitstring_bin(int width_prefix, bool sflag, bool, const char*src) { int src_len = strlen(src); if (width_prefix < 0) width_prefix = src_len; char*res = new char[width_prefix+1]; char*rp = res; if (width_prefix > src_len) { size_t pad = width_prefix - src_len; for (size_t idx = 0 ; idx < pad ; idx += 1) *rp++ = sflag? src[0] : '0'; } else if (src_len > width_prefix) { src += src_len - width_prefix; } while (*src) { *rp++ = *src++; } *rp = 0; return res; } static char*make_bitstring_oct(int width_prefix, bool sflag, bool, const char*src) { int src_len = strlen(src); if (width_prefix < 0) width_prefix = 3*src_len; char*res = new char[width_prefix+1]; char*rp = res + width_prefix; *rp = 0; rp -= 1; for (const char*sp = src + src_len - 1; sp >= src ; sp -= 1) { int val; switch (*sp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val = *sp - '0'; *rp-- = (val&1)? '1' : '0'; if (rp >= res) *rp-- = (val&2)? '1' : '0'; if (rp >= res) *rp-- = (val&4)? '1' : '0'; break; default: *rp-- = *sp; if (rp >= res) *rp-- = *sp; if (rp >= res) *rp-- = *sp; break; } if (rp < res) break; } if (rp >= res) { char pad = sflag? src[0] : '0'; while (rp >= res) *rp-- = pad; } return res; } static char*make_bitstring_hex(int width_prefix, bool sflag, bool, const char*src) { int src_len = strlen(src); if (width_prefix <= 0) width_prefix = 4*src_len; char*res = new char[width_prefix+1]; char*rp = res + width_prefix; *rp = 0; rp -= 1; for (const char*sp = src + src_len - 1; sp >= src ; sp -= 1) { int val; switch (*sp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': val = *sp - '0'; *rp-- = (val&1)? '1' : '0'; if (rp >= res) *rp-- = (val&2)? '1' : '0'; if (rp >= res) *rp-- = (val&4)? '1' : '0'; if (rp >= res) *rp-- = (val&8)? '1' : '0'; break; case 'a': case 'A': case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'e': case 'E': case 'f': case 'F': val = 10 + toupper(*sp) - 'A'; *rp-- = (val&1)? '1' : '0'; if (rp >= res) *rp-- = (val&2)? '1' : '0'; if (rp >= res) *rp-- = (val&4)? '1' : '0'; if (rp >= res) *rp-- = (val&8)? '1' : '0'; break; default: *rp-- = *sp; if (rp >= res) *rp-- = *sp; if (rp >= res) *rp-- = *sp; if (rp >= res) *rp-- = *sp; break; } if (rp < res) break; } if (rp >= res) { char pad = sflag? src[0] : '0'; while (rp >= res) *rp-- = pad; } return res; } static char*make_bitstring_dec(int, bool, bool, const char*) { assert(0); return 0; } static char* make_bitstring_literal(const char*text) { int width_prefix = -1; const char*cp = text; bool signed_flag = false; bool unsigned_flag = false; unsigned base = 0; // Parse out the explicit width, if present. if (size_t len = strspn(cp, "0123456789")) { width_prefix = 0; while (len > 0) { width_prefix *= 10; width_prefix += *cp - '0'; cp += 1; --len; } } else { width_prefix = -1; } // Detect and s/u flags. if (*cp == 's' || *cp == 'S') { signed_flag = true; cp += 1; } else if (*cp == 'u' || *cp == 'U') { unsigned_flag = true; cp += 1; } // Now get the base marker. switch (*cp) { case 'b': case 'B': base = 2; break; case 'o': case 'O': base = 8; break; case 'x': case 'X': base = 16; break; case 'd': case 'D': base = 10; break; default: assert(0); } cp += 1; char*simplified = new char [strlen(cp) + 1]; char*dp = simplified; assert(*cp == '"'); cp += 1; while (*cp && *cp != '"') { if (*cp == '_') { cp += 1; continue; } *dp++ = *cp++; } *dp = 0; char*res; switch (base) { case 2: res = make_bitstring_bin(width_prefix, signed_flag, unsigned_flag, simplified); break; case 8: res = make_bitstring_oct(width_prefix, signed_flag, unsigned_flag, simplified); break; case 10: res = make_bitstring_dec(width_prefix, signed_flag, unsigned_flag, simplified); break; case 16: res = make_bitstring_hex(width_prefix, signed_flag, unsigned_flag, simplified); break; default: assert(0); res = 0; } delete[]simplified; return res; } /** * This function takes a floating point based number * in form of a C-strings and converts it to a double. * * \return new double is returned */ static double make_double_from_based(char* text) { char* first_hash_ptr = strchr(text, '#'); char* second_hash_ptr = strrchr(text, '#'); char* last_char_ptr = strchr(text, '\0') - 1; //put null byte in lieu of hashes *first_hash_ptr = '\0'; *second_hash_ptr = '\0'; //now let's deduce the base unsigned base = (unsigned)strtol(text, 0, 10) ; double mantissa = 0.0; char*ptr = first_hash_ptr + 1; for( ; ptr != second_hash_ptr ; ++ptr) { if(*ptr == '.') break; if(*ptr != '_') { mantissa = mantissa*base + short_from_hex_char(*ptr); } } double fraction = 0.0; double factor = 1.0/base; for(++ptr ; ptr != second_hash_ptr; ++ptr) { if(*ptr != '_') { fraction = fraction + short_from_hex_char(*ptr)*factor; factor = factor / base; } } if(last_char_ptr == second_hash_ptr) //there is no exponent { return mantissa + fraction; } //now calculate the value of the exponent double exponent = 0.0; //leave 'e'/'E' and '+' ptr = *(second_hash_ptr + 2) == '+' ? second_hash_ptr + 3 : second_hash_ptr + 2; for( ; *ptr != '\0'; ++ptr) { if(*ptr != '_') { exponent = exponent*base + short_from_hex_char(*ptr); } } return pow(mantissa + fraction, exponent); } /** * This function takes a hexadecimal digit in form of * a char and returns its litteral value as short */ static unsigned short short_from_hex_char(char ch) { if(ch >= '0' && ch <= '9') return ch - '0'; else return ch - 'a' + 10; } /** * This function takes a based number in form of * a C-strings and converts it to a int64_t. * * \return new double is returned */ static int64_t make_long_from_based(char* text) { char* first_hash_ptr = strchr(text, '#'); char* second_hash_ptr = strrchr(text, '#'); char* end_ptr = strrchr(text, '\0'); //now lets deduce the base *first_hash_ptr = '\0'; unsigned base = (unsigned)strtol(text, 0, 10) ; char *ptr = first_hash_ptr + 1; int64_t mantissa = 0; for( ; ptr != second_hash_ptr ; ++ptr) { if(*ptr != '_') { mantissa = mantissa * base + short_from_hex_char(*ptr); } } //if there is an exponent if(end_ptr - second_hash_ptr > 1) { int64_t exponent = 0L; ptr = *(second_hash_ptr + 2) == '+' ? second_hash_ptr + 3 : second_hash_ptr + 2; for( ; *ptr != '\0'; ++ptr) { if(*ptr != '_') exponent = base*exponent + short_from_hex_char(*ptr); } return lpow(mantissa, exponent); } else return mantissa; } /** * Recursive power function for int64_t */ static int64_t lpow(int64_t left, int64_t right) { if(right == 0) return 1; else return left*lpow(left, right - 1); } yyscan_t prepare_lexor(FILE*fd) { yyscan_t scanner; yylex_init(&scanner); yyrestart(fd, scanner); return scanner; } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_lexor(yyscan_t scanner) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(scanner); # endif # endif # endif } iverilog-12_0/vhdlpp/lexor_keyword.gperf000066400000000000000000000110311435245347300205620ustar00rootroot00000000000000/* * We need this to prevent -Wextra (-W) from complaining that the mask and * tokenType values are not initialized for the empty table entries. */ %define initializer-suffix ,0,0 %language=C++ %define class-name Lkwd %{ /* Command-line: gperf -o -i 7 --ignore-case -C -k '1-4,6,9,$' -H keyword_hash -N check_identifier -t lexor_keyword.gperf */ #include "vhdlpp_config.h" #include #include "compiler.h" #include "parse_api.h" #include "parse_wrap.h" %} struct lexor_keyword { const char*name; int mask; int tokenType; }; %% abs, GN_KEYWORD_2008, K_abs access, GN_KEYWORD_2008, K_access after, GN_KEYWORD_2008, K_after alias, GN_KEYWORD_2008, K_alias all, GN_KEYWORD_2008, K_all and, GN_KEYWORD_2008, K_and architecture, GN_KEYWORD_2008, K_architecture array, GN_KEYWORD_2008, K_array assert, GN_KEYWORD_2008, K_assert attribute, GN_KEYWORD_2008, K_attribute begin, GN_KEYWORD_2008, K_begin block, GN_KEYWORD_2008, K_block body, GN_KEYWORD_2008, K_body buffer, GN_KEYWORD_2008, K_buffer bus, GN_KEYWORD_2008, K_bus case, GN_KEYWORD_2008, K_case component, GN_KEYWORD_2008, K_component configuration, GN_KEYWORD_2008, K_configuration constant, GN_KEYWORD_2008, K_constant context, GN_KEYWORD_2008, K_context cover, GN_KEYWORD_2008, K_cover default, GN_KEYWORD_2008, K_default disconnect, GN_KEYWORD_2008, K_disconnect downto, GN_KEYWORD_2008, K_downto else, GN_KEYWORD_2008, K_else elsif, GN_KEYWORD_2008, K_elsif end, GN_KEYWORD_2008, K_end entity, GN_KEYWORD_2008, K_entity exit, GN_KEYWORD_2008, K_exit fairness, GN_KEYWORD_2008, K_fairness file, GN_KEYWORD_2008, K_file for, GN_KEYWORD_2008, K_for force, GN_KEYWORD_2008, K_force function, GN_KEYWORD_2008, K_function generate, GN_KEYWORD_2008, K_generate generic, GN_KEYWORD_2008, K_generic group, GN_KEYWORD_2008, K_group guarded, GN_KEYWORD_2008, K_guarded if, GN_KEYWORD_2008, K_if impure, GN_KEYWORD_2008, K_impure in, GN_KEYWORD_2008, K_in inertial, GN_KEYWORD_2008, K_inertial inout, GN_KEYWORD_2008, K_inout is, GN_KEYWORD_2008, K_is label, GN_KEYWORD_2008, K_label library, GN_KEYWORD_2008, K_library linkage, GN_KEYWORD_2008, K_linkage literal, GN_KEYWORD_2008, K_literal loop, GN_KEYWORD_2008, K_loop map, GN_KEYWORD_2008, K_map mod, GN_KEYWORD_2008, K_mod nand, GN_KEYWORD_2008, K_nand new, GN_KEYWORD_2008, K_new next, GN_KEYWORD_2008, K_next nor, GN_KEYWORD_2008, K_nor not, GN_KEYWORD_2008, K_not null, GN_KEYWORD_2008, K_null of, GN_KEYWORD_2008, K_of on, GN_KEYWORD_2008, K_on open, GN_KEYWORD_2008, K_open or, GN_KEYWORD_2008, K_or others, GN_KEYWORD_2008, K_others out, GN_KEYWORD_2008, K_out package, GN_KEYWORD_2008, K_package port, GN_KEYWORD_2008, K_port postponed, GN_KEYWORD_2008, K_postponed procedure, GN_KEYWORD_2008, K_procedure process, GN_KEYWORD_2008, K_process property, GN_KEYWORD_2008, K_property protected, GN_KEYWORD_2008, K_protected pure, GN_KEYWORD_2008, K_pure range, GN_KEYWORD_2008, K_range record, GN_KEYWORD_2008, K_record register, GN_KEYWORD_2008, K_register reject, GN_KEYWORD_2008, K_reject release, GN_KEYWORD_2008, K_release rem, GN_KEYWORD_2008, K_rem report, GN_KEYWORD_2008, K_report restrict, GN_KEYWORD_2008, K_restrict return, GN_KEYWORD_2008, K_return reverse_range, GN_KEYWORD_2008, K_reverse_range rol, GN_KEYWORD_2008, K_rol ror, GN_KEYWORD_2008, K_ror select, GN_KEYWORD_2008, K_select sequence, GN_KEYWORD_2008, K_sequence severity, GN_KEYWORD_2008, K_severity signal, GN_KEYWORD_2008, K_signal shared, GN_KEYWORD_2008, K_shared sla, GN_KEYWORD_2008, K_sla sll, GN_KEYWORD_2008, K_sll sra, GN_KEYWORD_2008, K_sra srl, GN_KEYWORD_2008, K_srl strong, GN_KEYWORD_2008, K_strong subtype, GN_KEYWORD_2008, K_subtype then, GN_KEYWORD_2008, K_then to, GN_KEYWORD_2008, K_to transport, GN_KEYWORD_2008, K_transport type, GN_KEYWORD_2008, K_type unaffected, GN_KEYWORD_2008, K_unaffected units, GN_KEYWORD_2008, K_units until, GN_KEYWORD_2008, K_until use, GN_KEYWORD_2008, K_use variable, GN_KEYWORD_2008, K_variable vmode, GN_KEYWORD_2008, K_vmode vprop, GN_KEYWORD_2008, K_vprop vunit, GN_KEYWORD_2008, K_vunit wait, GN_KEYWORD_2008, K_wait when, GN_KEYWORD_2008, K_when while, GN_KEYWORD_2008, K_while with, GN_KEYWORD_2008, K_with xnor, GN_KEYWORD_2008, K_xnor xor, GN_KEYWORD_2008, K_xor %% int lexor_keyword_mask = GN_KEYWORD_2008; int lexor_keyword_code(const char*str, unsigned nstr) { const struct lexor_keyword*rc = Lkwd::check_identifier(str, nstr); if (rc == 0) return IDENTIFIER; else if ((rc->mask & lexor_keyword_mask) == 0) return IDENTIFIER; else return rc->tokenType; } iverilog-12_0/vhdlpp/library.cc000066400000000000000000000351451435245347300166270ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2016 * @author Maciej Suminski * * 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. */ # define __STDC_LIMIT_MACROS # include "parse_misc.h" # include "compiler.h" # include "package.h" # include "std_types.h" # include "std_funcs.h" # include # include # include # include # include # include # include using namespace std; /* * The library_work_path is the path to the work directory. */ static const char*library_work_path = 0; /* * The library_search_path is a list of directory names to search to * find a named library. The library name is the name given to the * "import" statement. */ static list library_search_path; /* * The "import" statement causes me to build a map of a library name * to a library directory. */ static map library_dir; /* * The "libraries" table maps library name to a set of packages. This * map is filled in by "use" statements. */ struct library_contents { map packages; }; static map libraries; void library_add_directory(const char*directory) { // Make sure the directory path really is a directory. Ignore // it if it is not. struct stat stat_buf; int rc = stat(directory, &stat_buf); if (rc < 0 || !S_ISDIR(stat_buf.st_mode)) { return; } library_search_path.push_front(directory); } SubprogramHeader*library_match_subprogram(perm_string name, const list*params) { SubprogramHeader*subp; map::const_iterator lib_it; for(lib_it = libraries.begin(); lib_it != libraries.end(); ++lib_it) { const struct library_contents&lib = lib_it->second; map::const_iterator pack_it; for(pack_it = lib.packages.begin(); pack_it != lib.packages.end(); ++pack_it) { if((subp = pack_it->second->match_subprogram(name, params))) return subp; } } return NULL; } static void store_package_in_work(const Package*pack); static string make_work_package_path(const char*name) { return string(library_work_path).append("/").append(name).append(".pkg"); } static string make_library_package_path(perm_string lib_name, perm_string name) { string path = library_dir[lib_name]; if (path == "") return ""; path = path.append("/").append(name).append(".pkg"); return path; } static void import_ieee(void); static void import_ieee_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name); static void import_std_use(const YYLTYPE&loc, ActiveScope*res, perm_string package, perm_string name); static void dump_library_package(ostream&file, perm_string lname, perm_string pname, Package*pack) { file << "package " << lname << "." << pname << endl; if (pack) { pack->dump_scope(file); } else { file << " " << endl; } file << "end package " << lname << "." << pname << endl; } static void dump_library_packages(ostream&file, perm_string lname, mappackages) { for (map::iterator cur = packages.begin() ; cur != packages.end() ; ++cur) { dump_library_package(file, lname, cur->first, cur->second); } } void dump_libraries(ostream&file) { for (map::iterator cur = libraries.begin() ; cur != libraries.end() ; ++cur) { dump_library_packages(file, cur->first, cur->second.packages); } } /* * This function saves a package into the named library. Create the * library if necessary. The parser uses this when it is finished with * a package declaration. */ void library_save_package(perm_string parse_library_name, Package*pack) { perm_string use_libname = parse_library_name.str() ? parse_library_name : perm_string::literal("work"); struct library_contents&lib = libraries[use_libname]; lib.packages[pack->name()] = pack; // If this is a work package, and we are NOT parsing the work // library right now, then store it in the work library. if (parse_library_name.str() == 0) store_package_in_work(pack); else pack->set_library(parse_library_name); } /* * The parser uses this function in the package body rule to recall * the package that was declared earlier. */ Package*library_recall_package(perm_string parse_library_name, perm_string package_name) { perm_string use_libname = parse_library_name.str() ? parse_library_name : perm_string::literal("work"); map::iterator lib = libraries.find(use_libname); if (lib == libraries.end()) return 0; map::iterator pkg = lib->second.packages.find(package_name); if (pkg == lib->second.packages.end()) return 0; return pkg->second; } static void import_library_name(const YYLTYPE&loc, perm_string name) { if (library_dir[name] != string()) return; for (list::const_iterator cur = library_search_path.begin() ; cur != library_search_path.end() ; ++cur) { string curdir = *cur; string try_path = curdir.append("/").append(name); struct stat stat_buf; int rc = stat(try_path.c_str(), &stat_buf); if (rc < 0) continue; if (!S_ISDIR(stat_buf.st_mode)) continue; library_dir[name] = try_path; return; } errormsg(loc, "library import cannot find library %s\n", name.str()); } void library_import(const YYLTYPE&loc, const std::list*names) { for (std::list::const_iterator cur = names->begin() ; cur != names->end() ; ++cur) { if (*cur == "ieee") { // The ieee library is special and handled by an // internal function. import_ieee(); } else if (*cur == "std") { // The std library is always implicitly imported. } else if (*cur == "work") { // The work library is always implicitly imported. } else { // Otherwise, do a generic library import import_library_name(loc, *cur); } } } void library_use(const YYLTYPE&loc, ActiveScope*res, const char*libname, const char*package, const char*name) { if (libname == 0) { errormsg(loc, "error: No library name for this use clause?\n"); return; } perm_string use_library = lex_strings.make(libname); perm_string use_package = lex_strings.make(package); perm_string use_name = name? lex_strings.make(name) : perm_string::literal("all"); // Special case handling for the IEEE library. if (use_library == "ieee") { import_ieee_use(loc, res, use_package, use_name); return; } // Special case handling for the STD library. if (use_library == "std") { import_std_use(loc, res, use_package, use_name); return; } struct library_contents&lib = libraries[use_library]; Package*pack = lib.packages[use_package]; // If the package is not found in the work library already // parsed, then see if it exists unparsed. if (use_library=="work" && pack == 0) { string path = make_work_package_path(use_package.str()); parse_source_file(path.c_str(), use_library); pack = lib.packages[use_package]; } else if (use_library != "ieee" && pack == 0) { string path = make_library_package_path(use_library, use_package); if (path == "") { errormsg(loc, "Unable to find library %s\n", use_library.str()); return; } int rc = parse_source_file(path.c_str(), use_library); if (rc < 0) errormsg(loc, "Unable to open library file %s\n", path.c_str()); else if (rc > 0) errormsg(loc, "Errors in library file %s\n", path.c_str()); else pack = lib.packages[use_package]; } // If the package is still not found, then error. if (pack == 0) { errormsg(loc, "No package %s in library %s\n", use_package.str(), use_library.str()); return; } // We have a package that we are going to extract names // from. Use the name to get the selected objects, and write // results into the "res" members. if (use_name == "all") { res->use_from(pack); return; } if (ComponentBase*cur = pack->find_component(use_name)) { res->bind_name(use_name, cur); return; } errormsg(loc, "No such name %s in package %s\n", use_name.str(), pack->name().str()); } static void import_ieee(void) { } static void import_ieee_use_std_logic_1164(ActiveScope*res, perm_string name) { bool all_flag = name=="all"; if (all_flag || name == "std_logic_vector") { res->use_name(perm_string::literal("std_logic_vector"), &primitive_STDLOGIC_VECTOR); } } static void import_ieee_use_std_logic_misc(ActiveScope*, perm_string name) { bool all_flag = name=="all"; list*args; if (all_flag || name == "or_reduce") { /* function or_reduce(arg : std_logic_vector) return std_logic; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("or_reduce"), perm_string::literal("|"), args, &primitive_STDLOGIC)); } if (all_flag || name == "and_reduce") { /* function and_reduce(arg : std_logic_vector) return std_logic; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("and_reduce"), perm_string::literal("&"), args, &primitive_STDLOGIC)); } } static void import_ieee_use_numeric_bit(ActiveScope*res, perm_string name) { bool all_flag = name=="all"; if (all_flag || name == "signed") { res->use_name(perm_string::literal("signed"), &primitive_SIGNED); } if (all_flag || name == "unsigned") { res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED); } } static void import_ieee_use_numeric_std(ActiveScope*res, perm_string name) { bool all_flag = name=="all"; if (all_flag || name == "signed") { res->use_name(perm_string::literal("signed"), &primitive_SIGNED); } if (all_flag || name == "unsigned") { res->use_name(perm_string::literal("unsigned"), &primitive_UNSIGNED); } } static void import_ieee_use(const YYLTYPE&/*loc*/, ActiveScope*res, perm_string package, perm_string name) { if (package == "std_logic_1164") { import_ieee_use_std_logic_1164(res, name); return; } if (package == "std_logic_arith") { // arithmetic operators for std_logic_vector return; } if (package == "std_logic_misc") { import_ieee_use_std_logic_misc(res, name); return; } if (package == "std_logic_unsigned") { // arithmetic operators for std_logic_vector return; } if (package == "numeric_bit") { import_ieee_use_numeric_bit(res, name); return; } if (package == "numeric_std") { import_ieee_use_numeric_std(res, name); return; } cerr << "Warning: Package ieee." << package.str() <<" is not yet supported" << endl; } static void import_std_use(const YYLTYPE&/*loc*/, ActiveScope*res, perm_string package, perm_string /*name*/) { if (package == "standard") { // do nothing return; } else if (package == "textio") { res->use_name(perm_string::literal("text"), &primitive_INTEGER); res->use_name(perm_string::literal("line"), &primitive_STRING); res->use_name(type_FILE_OPEN_KIND.peek_name(), &type_FILE_OPEN_KIND); res->use_name(type_FILE_OPEN_STATUS.peek_name(), &type_FILE_OPEN_STATUS); return; } else { cerr << "Warning: Package std." << package.str() <<" is not yet supported" << endl; return; } } void library_set_work_path(const char*path) { assert(library_work_path == 0); library_work_path = path; } list work_packages; static void store_package_in_work(const Package*pack) { work_packages.push_back(pack); } static int emit_packages(perm_string, const map&packages) { int errors = 0; for (map::const_iterator cur = packages.begin() ; cur != packages.end() ; ++cur) { errors += cur->second->emit_package(cout); } for (list::const_iterator cur = work_packages.begin() ; cur != work_packages.end(); ++cur) { string path = make_work_package_path((*cur)->name()); ofstream file (path.c_str(), ios_base::out); (*cur)->write_to_stream(file); } return errors; } int emit_packages(void) { int errors = 0; for (map::iterator cur = libraries.begin() ; cur != libraries.end() ; ++cur) { errors += emit_packages(cur->first, cur->second.packages); } return errors; } static int elaborate_library_packages(mappackages) { int errors = 0; for (map::iterator cur = packages.begin() ; cur != packages.end() ; ++cur) { errors += cur->second->elaborate(); } return errors; } int elaborate_libraries() { int errors = 0; for (map::iterator cur = libraries.begin() ; cur != libraries.end() ; ++cur) { errors += elaborate_library_packages(cur->second.packages); } return errors; } iverilog-12_0/vhdlpp/library.h000066400000000000000000000023271435245347300164650ustar00rootroot00000000000000#ifndef IVL_library_H #define IVL_library_H /* * Copyright (c) 2011-2021 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 class SubprogramHeader; class VType; void library_set_work_path(const char*work_path); void library_add_directory(const char*directory); int elaborate_libraries(void); int emit_packages(void); SubprogramHeader*library_match_subprogram(perm_string name, const std::list*params); #endif /* IVL_library_H */ iverilog-12_0/vhdlpp/main.cc000066400000000000000000000171471435245347300161110ustar00rootroot00000000000000 const char COPYRIGHT[] = "Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com)\n" "Copyright CERN 2012 / 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 "vhdlpp_config.h" # include "version_base.h" # include "version_tag.h" using namespace std; /* * Usage: vhdlpp [flags] sourcefile... * Flags: * ** -D * This activates various sorts of debugging aids. The * specifies which debugging aid to activate. Valid tokens are: * * yydebug | no-yydebug * Enable (disable) debug prints from the bison parser * * libraries= * Enable debugging of library support by dumping library * information to the file named . * * elaboration= * Enable debugging of elaboration by dumping elaboration * process information to the file named . * * entities= * Enable debugging of elaborated entities by writing the * elaboration results to the file named . * ** -v * Verbose operation. Display verbose non-debug information. * ** -V * Version. Print the version of this binary. * ** -w * Work path. This sets the path to the working library * directory. I write into that directory files for packages that * I declare, and I read from that directory packages that are * already declared. The default path is "ivl_vhdl_work". */ const char NOTICE[] = " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation; either version 2 of the License, or\n" " (at your option) any later version.\n" "\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n" "\n" " You should have received a copy of the GNU General Public License along\n" " with this program; if not, write to the Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" ; # include "compiler.h" # include "library.h" # include "std_funcs.h" # include "std_types.h" # include "parse_api.h" # include "vtype.h" # include # include # include # include # include # include #if defined(HAVE_GETOPT_H) # include #endif # include // MinGW only supports mkdir() with a path. If this stops working because // we need to use _mkdir() for mingw-w32 and mkdir() for mingw-w64 look // at using the autoconf AX_FUNC_MKDIR macro to figure this all out. #if defined(__MINGW32__) # include # define mkdir(path, mode) mkdir(path) #endif bool verbose_flag = false; // Where to dump design entities const char*dump_design_entities_path = 0; const char*dump_libraries_path = 0; const char*debug_log_path = 0; bool debug_elaboration = false; ofstream debug_log_file; extern void dump_libraries(ostream&file); extern void parser_cleanup(); static void process_debug_token(const char*word) { if (strcmp(word, "yydebug") == 0) { yydebug = 1; } else if (strcmp(word, "no-yydebug") == 0) { yydebug = 0; } else if (strncmp(word, "entities=", 9) == 0) { dump_design_entities_path = strdup(word+9); } else if (strncmp(word, "libraries=", 10) == 0) { dump_libraries_path = strdup(word+10); } else if (strncmp(word, "log=", 4) == 0) { debug_log_path = strdup(word+4); } else if (strcmp(word, "elaboration") == 0) { debug_elaboration = true; } } int main(int argc, char*argv[]) { int opt; int rc; const char*work_path = "ivl_vhdl_work"; while ( (opt=getopt(argc, argv, "D:L:vVw:")) != EOF) switch (opt) { case 'D': process_debug_token(optarg); break; case 'L': library_add_directory(optarg); break; case 'v': fprintf(stderr, "Icarus Verilog VHDL Parse version " VERSION " (" VERSION_TAG ")\n\n"); fprintf(stderr, "%s\n\n", COPYRIGHT); fputs(NOTICE, stderr); verbose_flag = true; break; case 'V': fprintf(stdout, "Icarus Verilog VHDL Parse version " VERSION " (" VERSION_TAG ")\n\n"); fprintf(stdout, "%s\n\n", COPYRIGHT); fputs(NOTICE, stdout); break; case 'w': work_path = optarg; break; } if (debug_log_path) { debug_log_file.open(debug_log_path); } if ( (mkdir(work_path, 0777)) < 0 ) { if (errno != EEXIST) { fprintf(stderr, "Icarus Verilog VHDL unable to create work directory %s, errno=%d\n", work_path, errno); return -1; } struct stat stat_buf; rc = stat(work_path, &stat_buf); if (rc || !S_ISDIR(stat_buf.st_mode)) { fprintf(stderr, "Icarus Verilog VHDL work path `%s' is not a directory.\n", work_path); return -1; } } std::cout.precision(std::numeric_limits::digits10); library_set_work_path(work_path); preload_global_types(); preload_std_funcs(); int errors = 0; for (int idx = optind ; idx < argc ; idx += 1) { parse_errors = 0; parse_sorrys = 0; rc = parse_source_file(argv[idx], perm_string()); if (rc < 0) return 1; if (verbose_flag) fprintf(stderr, "parse_source_file() returns %d, parse_errors=%d, parse_sorrys=%d\n", rc, parse_errors, parse_sorrys); if (parse_errors > 0) { fprintf(stderr, "Encountered %d errors parsing %s\n", parse_errors, argv[idx]); } if (parse_sorrys > 0) { fprintf(stderr, "Encountered %d unsupported constructs parsing %s\n", parse_sorrys, argv[idx]); } if (parse_errors || parse_sorrys) { errors += parse_errors; errors += parse_sorrys; break; } } if (dump_libraries_path) { ofstream file(dump_libraries_path); dump_libraries(file); } if (dump_design_entities_path) { ofstream file(dump_design_entities_path); dump_design_entities(file); } if (errors > 0) { parser_cleanup(); return 2; } errors = elaborate_entities(); if (errors > 0) { fprintf(stderr, "%d errors elaborating design.\n", errors); parser_cleanup(); return 3; } errors = elaborate_libraries(); if (errors > 0) { fprintf(stderr, "%d errors elaborating libraries.\n", errors); parser_cleanup(); return 4; } emit_std_types(cout); errors = emit_packages(); if (errors > 0) { fprintf(stderr, "%d errors emitting packages.\n", errors); parser_cleanup(); return 5; } errors = emit_entities(); if (errors > 0) { fprintf(stderr, "%d errors emitting design.\n", errors); parser_cleanup(); return 6; } parser_cleanup(); return 0; } iverilog-12_0/vhdlpp/package.cc000066400000000000000000000120201435245347300165410ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "package.h" # include "entity.h" # include "subprogram.h" # include "parse_misc.h" # include "std_types.h" # include "ivl_assert.h" # include # include using namespace std; Package::Package(perm_string n, const ActiveScope&ref) : Scope(ref), name_(n) { } Package::~Package() { ScopeBase::cleanup(); } void Package::set_library(perm_string lname) { ivl_assert(*this, from_library_.str() == 0); from_library_ = lname; } int Package::elaborate() { int errors = 0; for (map::iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++ cur) { SubHeaderList& subp_list = cur->second; for(SubHeaderList::iterator it = subp_list.begin(); it != subp_list.end(); ++it) { (*it)->set_package(this); errors += (*it)->elaborate(); } } return errors; } /* * The Package::write_to_stream is used to write the package to the * work space (or library) so writes proper VHDL that the library * parser can bring back in as needed. */ void Package::write_to_stream(ostream&fd) const { fd << "package " << name_ << " is" << endl; // Start out pre-declaring all the type definitions so that // there is no confusion later in the package between types // and identifiers. for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { // Do not include global types in types dump if (is_global_type(cur->first)) continue; fd << "type " << cur->first << ";" << endl; } for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { // Do not include global types in types dump if (is_global_type(cur->first)) continue; fd << "type " << cur->first << ";" << endl; } for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { cur->second->write_typedef_to_stream(fd, cur->first); } for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { cur->second->write_typedef_to_stream(fd, cur->first); } for (map::const_iterator cur = cur_constants_.begin() ; cur != cur_constants_.end() ; ++ cur) { if (cur->second==0 || cur->second->typ==0) { fd << "-- const " << cur->first << " has errors." << endl; continue; } fd << "constant " << cur->first << ": "; cur->second->typ->write_to_stream(fd); fd << " := "; cur->second->val->write_to_stream(fd); fd << ";" << endl; } for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { (*it)->write_to_stream(fd); fd << ";" << endl; } } for (map::const_iterator cur = old_components_.begin() ; cur != old_components_.end() ; ++cur) { cur->second->write_to_stream(fd); } for (map::const_iterator cur = new_components_.begin() ; cur != new_components_.end() ; ++cur) { cur->second->write_to_stream(fd); } fd << "end package " << name_ << ";" << endl; fd << "package body " << name_ << " is" << endl; for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { const SubprogramHeader*subp = *it; if(subp->body()) { subp->write_to_stream(fd); fd << " is" << endl; subp->body()->write_to_stream(fd); } } } fd << "end " << name_ << ";" << endl; } iverilog-12_0/vhdlpp/package.h000066400000000000000000000031641435245347300164140ustar00rootroot00000000000000#ifndef IVL_package_H #define IVL_package_H /* * Copyright (c) 2011-2014 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "scope.h" # include "LineInfo.h" # include class Package : public Scope, public LineInfo { public: Package(perm_string name, const ActiveScope&ref); ~Package(); // The the library from which this package came. Having a // source library influences the emit_package() method. void set_library(perm_string); perm_string name() const { return name_; } // This method writes a package header to a library file. void write_to_stream(std::ostream&fd) const; int emit_package(std::ostream&fd) const; int elaborate(); private: perm_string from_library_; perm_string name_; }; #endif /* IVL_package_H */ iverilog-12_0/vhdlpp/package_emit.cc000066400000000000000000000065271435245347300175760ustar00rootroot00000000000000/* * Copyright (c) 2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "package.h" # include "subprogram.h" # include "ivl_assert.h" # include # include using namespace std; int Package::emit_package(ostream&fd) const { // Don't emit the package if there is nothing in it that SV // cares about. if (cur_types_.empty() && cur_constants_.empty() && cur_subprograms_.empty()) return 0; int errors = 0; fd << "`ifndef package_" << name() << endl; fd << "`define package_" << name() << endl; // Only emit types that were defined within this package. Skip // the types that were imported from elsewhere. typedef_context_t typedef_ctx; for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++ cur) { if(const VTypeDef*def = dynamic_cast(cur->second)) errors += def->emit_typedef(fd, typedef_ctx); //fd << "typedef "; //errors += cur->second->emit_def(fd, //dynamic_cast(cur->second) ? empty_perm_string : cur->first); //fd << " ;" << endl; } //for (map::const_iterator cur = use_constants_.begin() //; cur != use_constants_.end() ; ++cur) { //fd << "localparam \\" << cur->first << " = "; //errors += cur->second->val->emit_package(fd); //fd << ";" << endl; //} //for (map::const_iterator cur = cur_constants_.begin() //; cur != cur_constants_.end() ; ++cur) { //fd << "localparam " << cur->first << " = "; //errors += cur->second->val->emit_package(fd); //fd << ";" << endl; //} fd << "package \\" << name() << " ;" << endl; for (map::const_iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++ cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { SubprogramHeader*header = *it; // Do not emit unbounded functions, we will just need fixed instances later if(!header->unbounded()) errors += header->emit_package(fd); else fd << "/* function " << header->name() << " has to be instantiated, skipping */" << endl; } } fd << "endpackage /* " << name() << " */" << endl; fd << "`endif" << endl; return errors; } iverilog-12_0/vhdlpp/parse.y000066400000000000000000002303211435245347300161510ustar00rootroot00000000000000 %define api.pure %lex-param { yyscan_t yyscanner } %parse-param {yyscan_t yyscanner } %parse-param {const char*file_path} %parse-param {perm_string parse_library_name} %{ /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2012-2016 / Stephen Williams (steve@icarus.com), * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "vhdlpp_config.h" # include "vhdlint.h" # include "vhdlreal.h" # include "compiler.h" # include "parse_api.h" # include "parse_misc.h" # include "architec.h" # include "expression.h" # include "sequential.h" # include "subprogram.h" # include "package.h" # include "vsignal.h" # include "vtype.h" # include "std_funcs.h" # include "std_types.h" # include # include # include # include # include # include # include "parse_types.h" # include # include using namespace std; inline void FILE_NAME(LineInfo*tmp, const struct yyltype&where) { tmp->set_lineno(where.first_line); tmp->set_file(filename_strings.make(where.text)); } /* Recent version of bison expect that the user supply a YYLLOC_DEFAULT macro that makes up a yylloc value from existing values. I need to supply an explicit version to account for the text field, that otherwise won't be copied. */ # define YYLLOC_DEFAULT(Current, Rhs, N) do { \ (Current).first_line = (Rhs)[1].first_line; \ (Current).text = file_path; /*(Rhs)[1].text;*/ } while (0) static void yyerror(YYLTYPE*yyllocp,yyscan_t yyscanner,const char*file_path,bool, const char*msg); int parse_errors = 0; int parse_sorrys = 0; /* * The parser calls yylex to get the next lexical token. It is only * called by the bison-generated parser. */ extern int yylex(union YYSTYPE*yylvalp,YYLTYPE*yyllocp,yyscan_t yyscanner); /* * Create an initial scope that collects all the global * declarations. Also save a stack of previous scopes, as a way to * manage lexical scopes. */ static ActiveScope*active_scope = new ActiveScope; static stack scope_stack; static SubprogramHeader*active_sub = NULL; static ActiveScope*arc_scope = NULL; /* * When a scope boundary starts, call the push_scope function to push * a scope context. Preload this scope context with the contents of * the parent scope, then make this the current scope. When the scope * is done, the pop_scope function pops the scope off the stack and * resumes the scope that was the parent. */ static void push_scope(void) { assert(active_scope); scope_stack.push(active_scope); active_scope = new ActiveScope (active_scope); } static void pop_scope(void) { delete active_scope; assert(! scope_stack.empty()); active_scope = scope_stack.top(); scope_stack.pop(); } static bool is_subprogram_param(perm_string name) { if(!active_sub) return false; return (active_sub->find_param(name) != NULL); } void preload_global_types(void) { generate_global_types(active_scope); } //Remove the scope created at the beginning of parser's work. //After the parsing active_scope should keep it's address static void delete_global_scope(void) { active_scope->destroy_global_scope(); delete active_scope; } //delete global entities that were gathered over the parsing process static void delete_design_entities(void) { for(map::iterator cur = design_entities.begin() ; cur != design_entities.end(); ++cur) delete cur->second; } //clean the mess caused by the parser void parser_cleanup(void) { delete_design_entities(); delete_global_scope(); delete_std_funcs(); lex_strings.cleanup(); } const VType*parse_type_by_name(perm_string name) { return active_scope->find_type(name); } // This function is called when an aggregate expression is detected by // the parser. It makes the ExpAggregate. It also tries to detect the // special case that the aggregate is really a primary. The problem is // that this: // ( ) // also matches the pattern: // ( [ choices => ] ... ) // so try to assume that a single expression in parentheses is a // primary and fix the parse by returning an Expression instead of an // ExpAggregate. static Expression*aggregate_or_primary(const YYLTYPE&loc, std::list*el) { if (el->size() != 1) { ExpAggregate*tmp = new ExpAggregate(el); FILE_NAME(tmp,loc); return tmp; } ExpAggregate::element_t*el1 = el->front(); if (el1->count_choices() > 0) { ExpAggregate*tmp = new ExpAggregate(el); FILE_NAME(tmp,loc); return tmp; } return el1->extract_expression(); } static list* record_elements(list*names, const VType*type) { list*res = new list; for (list::iterator cur = names->begin() ; cur != names->end() ; ++cur) { res->push_back(new VTypeRecord::element_t(*cur, type)); } return res; } static void touchup_interface_for_functions(std::list*ports) { for (list::iterator cur = ports->begin() ; cur != ports->end() ; ++cur) { InterfacePort*curp = *cur; if (curp->mode == PORT_NONE) curp->mode = PORT_IN; } } %} %union { port_mode_t port_mode; char*text; std::list* name_list; bool flag; int64_t uni_integer; double uni_real; Expression*expr; std::list* expr_list; SequentialStmt* sequ; std::list*sequ_list; IfSequential::Elsif*elsif; std::list*elsif_list; ExpConditional::case_t*exp_options; std::list*exp_options_list; CaseSeqStmt::CaseStmtAlternative* case_alt; std::list* case_alt_list; named_expr_t*named_expr; std::list*named_expr_list; entity_aspect_t* entity_aspect; instant_list_t* instantiation_list; std::pair* component_specification; const VType* vtype; ExpRange*range; std::list*range_list; ExpRange::range_dir_t range_dir; ExpArithmetic::fun_t arithmetic_op; std::list*adding_terms; ExpAggregate::choice_t*choice; std::list*choice_list; ExpAggregate::element_t*element; std::list*element_list; std::list*record_elements; std::list* interface_list; Architecture::Statement* arch_statement; std::list* arch_statement_list; ReportStmt::severity_t severity; SubprogramHeader*subprogram; file_open_info_t*file_info; }; /* The keywords are all tokens. */ %token K_abs K_access K_after K_alias K_all K_and K_architecture %token K_array K_assert K_assume K_assume_guarantee K_attribute %token K_begin K_block K_body K_buffer K_bus %token K_case K_component K_configuration K_constant K_context K_cover %token K_default K_disconnect K_downto %token K_else K_elsif K_end K_entity K_exit %token K_fairness K_file K_for K_force K_function %token K_generate K_generic K_group K_guarded %token K_if K_impure K_in K_inertial K_inout K_is %token K_label K_library K_linkage K_literal K_loop %token K_map K_mod %token K_nand K_new K_next K_nor K_not K_null %token K_of K_on K_open K_or K_others K_out %token K_package K_parameter K_port K_postponed K_procedure K_process %token K_property K_protected K_pure %token K_range K_record K_register K_reject K_release K_rem K_report %token K_restrict K_restrict_guarantee K_return K_reverse_range K_rol K_ror %token K_select K_sequence K_severity K_signal K_shared %token K_sla K_sll K_sra K_srl K_strong K_subtype %token K_then K_to K_transport K_type %token K_unaffected K_units K_until K_use %token K_variable K_vmode K_vprop K_vunit %token K_wait K_when K_while K_with %token K_xnor K_xor /* Identifiers that are not keywords are identifiers. */ %token IDENTIFIER %token INT_LITERAL %token REAL_LITERAL %token STRING_LITERAL CHARACTER_LITERAL BITSTRING_LITERAL /* compound symbols */ %token LEQ GEQ VASSIGN NE BOX EXP ARROW DLT DGT CC M_EQ M_NE M_LT M_LEQ M_GT M_GEQ /* The rules may have types. */ %type adding_operator %type simple_expression_terms %type interface_element interface_list %type port_clause port_clause_opt %type generic_clause generic_clause_opt %type parameter_list parameter_list_opt %type mode mode_opt %type entity_aspect entity_aspect_opt binding_indication binding_indication_semicolon_opt %type instantiation_list %type component_specification %type concurrent_statement component_instantiation_statement %type concurrent_conditional_signal_assignment %type concurrent_signal_assignment_statement concurrent_simple_signal_assignment %type concurrent_assertion_statement %type for_generate_statement generate_statement if_generate_statement %type process_statement selected_signal_assignment %type architecture_statement_part generate_statement_body %type choice %type choices %type element_association %type element_association_list %type expression factor primary relation %type expression_logical expression_logical_and expression_logical_or %type expression_logical_xnor expression_logical_xor %type name prefix selected_name indexed_name %type shift_expression signal_declaration_assign_opt %type simple_expression simple_expression_2 term %type variable_declaration_assign_opt waveform_element interface_element_expression %type waveform waveform_elements %type name_list expression_list argument_list argument_list_opt %type process_sensitivity_list process_sensitivity_list_opt %type selected_names use_clause %type file_open_information file_open_information_opt %type association_element %type association_list port_map_aspect port_map_aspect_opt %type generic_map_aspect generic_map_aspect_opt %type composite_type_definition record_type_definition %type subtype_indication type_definition %type element_declaration element_declaration_list %type architecture_body_start package_declaration_start %type package_body_start process_start %type identifier_opt identifier_colon_opt logical_name suffix instantiated_unit %type logical_name_list identifier_list %type enumeration_literal_list enumeration_literal %type if_statement_else list_of_statements %type sequence_of_statements subprogram_statement_part %type sequential_statement if_statement signal_assignment signal_assignment_statement %type case_statement procedure_call procedure_call_statement %type loop_statement variable_assignment variable_assignment_statement %type assertion_statement report_statement return_statement wait_statement %type range %type range_list index_constraint %type direction %type case_statement_alternative %type case_statement_alternative_list %type if_statement_elsif %type if_statement_elsif_list if_statement_elsif_list_opt %type else_when_waveform selected_waveform %type else_when_waveforms else_when_waveforms_opt selected_waveform_list %type function_specification procedure_specification %type subprogram_specification subprogram_body_start %type severity severity_opt %% /* The design_file is the root for the VHDL parse. This rule is also where I put some run-time initializations. */ design_file : { yylloc.text = file_path; } design_units ; adding_operator : '+' { $$ = ExpArithmetic::PLUS; } | '-' { $$ = ExpArithmetic::MINUS; } | '&' { $$ = ExpArithmetic::xCONCAT; } ; architecture_body : architecture_body_start K_of IDENTIFIER { bind_entity_to_active_scope($3, active_scope); } K_is block_declarative_items_opt K_begin architecture_statement_part K_end K_architecture_opt identifier_opt ';' { Architecture*tmp = new Architecture(lex_strings.make($1), *active_scope, *$8); FILE_NAME(tmp, @1); bind_architecture_to_entity($3, tmp); if ($11 && tmp->get_name() != $11) errormsg(@1, "Architecture name doesn't match closing name.\n"); delete[]$1; delete[]$3; delete $8; pop_scope(); assert(arc_scope); arc_scope = NULL; if ($11) delete[]$11; } ; architecture_body_start : K_architecture IDENTIFIER { $$ = $2; push_scope(); assert(!arc_scope); arc_scope = active_scope; } ; /* * The architecture_statement_part is a list of concurrent * statements. */ architecture_statement_part : architecture_statement_part concurrent_statement { std::list*tmp = $1; if ($2) tmp->push_back($2); $$ = tmp; } | concurrent_statement { std::list*tmp = new std::list; if ($1) tmp->push_back($1); $$ = tmp; } | error ';' { $$ = 0; errormsg(@1, "Syntax error in architecture statement.\n"); yyerrok; } ; argument_list : '(' expression_list ')' { $$ = $2; }; argument_list_opt : argument_list { $$ = $1; } | { $$ = 0; } ; assertion_statement : K_assert expression report_statement { ReportStmt*report = dynamic_cast($3); assert(report); AssertStmt*tmp = new AssertStmt($2, report->message(), report->severity()); delete report; FILE_NAME(tmp,@2); $$ = tmp; } | K_assert expression severity_opt ';' { AssertStmt*tmp = new AssertStmt($2, NULL, $3); FILE_NAME(tmp,@2); $$ = tmp; } ; association_element : IDENTIFIER ARROW expression { named_expr_t*tmp = new named_expr_t(lex_strings.make($1), $3); delete[]$1; $$ = tmp; } | IDENTIFIER ARROW K_open { named_expr_t*tmp = new named_expr_t(lex_strings.make($1), 0); delete[]$1; $$ = tmp; } | IDENTIFIER ARROW error { errormsg(@3, "Invalid target for port map association.\n"); yyerrok; $$ = 0; } ; association_list : association_list ',' association_element { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | association_element { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; binding_indication : K_use entity_aspect_opt port_map_aspect_opt generic_map_aspect_opt { $$ = $2; if ($3) sorrymsg(@3, "Port map aspect not supported here. (binding_indication)\n"); if ($4) sorrymsg(@4, "Generic map aspect not supported here. (binding_indication)\n"); delete $3; delete $4; } ; binding_indication_semicolon_opt : binding_indication ';' { $$ = $1; } | { $$ = 0; } ; block_configuration : K_for IDENTIFIER use_clauses_opt configuration_items_opt K_end K_for ';' { delete[] $2; } ; block_configuration_opt : block_configuration | ; block_declarative_item : K_signal identifier_list ':' subtype_indication signal_declaration_assign_opt ';' { /* Save the signal declaration in the block_signals map. */ for (std::list::iterator cur = $2->begin() ; cur != $2->end() ; ++cur) { Signal*sig = new Signal(*cur, $4, $5 ? $5->clone() : 0); FILE_NAME(sig, @1); active_scope->bind_name(*cur, sig); } delete $2; } | component_declaration | constant_declaration | subprogram_declaration | subprogram_body | subtype_declaration | type_declaration | use_clause_lib /* Various error handling rules for block_declarative_item... */ | K_signal error ';' { errormsg(@2, "Syntax error declaring signals.\n"); yyerrok; } | error ';' { errormsg(@1, "Syntax error in block declarations.\n"); yyerrok; } ; /* * The block_declarative_items rule matches "{ block_declarative_item }" * which is a synonym for "architecture_declarative_part" and * "block_declarative_part". */ block_declarative_items : block_declarative_items block_declarative_item | block_declarative_item ; block_declarative_items_opt : block_declarative_items | ; case_statement : K_case expression K_is case_statement_alternative_list K_end K_case ';' { CaseSeqStmt* tmp = new CaseSeqStmt($2, $4); FILE_NAME(tmp, @1); delete $4; $$ = tmp; } ; case_statement_alternative_list : case_statement_alternative_list case_statement_alternative { std::list* tmp = $1; tmp->push_back($2); $$ = tmp; } | case_statement_alternative { std::list*tmp = new std::list(); tmp->push_back($1); $$ = tmp; } ; /* * The case_statement_alternative uses the "choice" rule to select the * reference expression, but that rule is shared with the aggregate * expression. So convert the ExpAggregate::choice_t to a case * statement alternative and pass that up instead. */ case_statement_alternative : K_when choices ARROW sequence_of_statements { CaseSeqStmt::CaseStmtAlternative* tmp; std::list*choices = $2; std::list*exp_list = new std::list; bool others = false; for(std::list::iterator it = choices->begin(); it != choices->end(); ++it) { if((*it)->others() || others) // If there is one "others", then it also covers all other alternatives // Continue the loop to delete every choice_t, but do not // bother to add the expressions to the exp_list (we are going to // delete them very soon) others = true; else exp_list->push_back((*it)->simple_expression()); delete (*it); } if(others) { tmp = new CaseSeqStmt::CaseStmtAlternative(0, $4); for(std::list::iterator it = exp_list->begin(); it != exp_list->end(); ++it) { delete (*it); } } else { tmp = new CaseSeqStmt::CaseStmtAlternative(exp_list, $4); } if (tmp) FILE_NAME(tmp, @1); delete choices; delete $4; $$ = tmp; } ; choice : simple_expression { $$ = new ExpAggregate::choice_t($1);} | K_others { $$ = new ExpAggregate::choice_t; } | range /* discrete_range: range */ { $$ = new ExpAggregate::choice_t($1); } ; choices : choices '|' choice { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | choice { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; component_configuration : K_for component_specification binding_indication_semicolon_opt block_configuration_opt K_end K_for ';' { sorrymsg(@1, "Component configuration in not yet supported\n"); if($3) delete $3; delete $2; } | K_for component_specification error K_end K_for { errormsg(@1, "Error in component configuration statement.\n"); delete $2; } ; component_declaration : K_component IDENTIFIER K_is_opt generic_clause_opt port_clause_opt K_end K_component identifier_opt ';' { perm_string name = lex_strings.make($2); if($8 && name != $8) { errormsg(@8, "Identifier %s doesn't match component name %s.\n", $8, name.str()); } ComponentBase*comp = new ComponentBase(name); comp->set_interface($4, $5); if ($4) delete $4; if ($5) delete $5; active_scope->bind_name(name, comp); delete[]$2; if ($8) delete[] $8; } | K_component IDENTIFIER K_is_opt error K_end K_component identifier_opt ';' { errormsg(@4, "Syntax error in component declaration.\n"); delete[] $2; if($7) delete[] $7; yyerrok; } ; instantiated_unit : IDENTIFIER | K_component IDENTIFIER { $$ = $2; } ; component_instantiation_statement : IDENTIFIER ':' instantiated_unit generic_map_aspect_opt port_map_aspect_opt ';' { perm_string iname = lex_strings.make($1); perm_string cname = lex_strings.make($3); ComponentInstantiation*tmp = new ComponentInstantiation(iname, cname, $4, $5); delete $4; delete $5; FILE_NAME(tmp, @1); delete[]$1; delete[]$3; $$ = tmp; } | IDENTIFIER ':' instantiated_unit error ';' { errormsg(@4, "Errors in component instantiation.\n"); delete[]$1; delete[]$3; $$ = 0; } ; component_specification : instantiation_list ':' name { ExpName* name = dynamic_cast($3); std::pair* tmp = new std::pair($1, name); $$ = tmp; } ; composite_type_definition /* constrained_array_definition */ : K_array index_constraint K_of subtype_indication { VTypeArray*tmp = new VTypeArray($4, $2); delete $2; $$ = tmp; } /* unbounded_array_definition IEEE 1076-2008 P5.3.2.1 */ | K_array '(' index_subtype_definition_list ')' K_of subtype_indication { std::list r; // NULL boundaries indicate unbounded array type ExpRange*tmp = new ExpRange(NULL, NULL, ExpRange::DOWNTO); r.push_back(tmp); FILE_NAME(tmp, @1); VTypeArray*arr = new VTypeArray($6, &r); $$ = arr; } | record_type_definition { $$ = $1; } ; concurrent_assertion_statement : assertion_statement { /* See more explanations at IEEE 1076-2008 P11.5 */ std::list stmts; stmts.push_back($1); stmts.push_back(new WaitStmt(WaitStmt::FINAL, NULL)); push_scope(); ProcessStatement*tmp = new ProcessStatement(empty_perm_string, *active_scope, NULL, &stmts); pop_scope(); FILE_NAME(tmp, @1); $$ = tmp; } ; /* The when...else..when...else syntax is not a general expression in VHDL but a specific sort of assignment statement model. We create Expression objects for it, but the parser will only recognize it it in specific situations. */ concurrent_conditional_signal_assignment /* IEEE 1076-2008 P11.6 */ : name LEQ waveform K_when expression else_when_waveforms_opt ';' { std::list*options; options = $6 ? $6 : new std::list; options->push_front(new ExpConditional::case_t($5, $3)); ExpName*name = dynamic_cast($1); assert(name); CondSignalAssignment*tmp = new CondSignalAssignment(name, *options); FILE_NAME(tmp, @1); delete options; $$ = tmp; } /* Error recovery rules. */ | name LEQ error K_when expression else_when_waveforms ';' { errormsg(@3, "Syntax error in waveform of conditional signal assignment.\n"); ExpConditional*tmp = new ExpConditional($5, 0, $6); FILE_NAME(tmp, @3); delete $6; ExpName*name = dynamic_cast ($1); assert(name); SignalAssignment*tmpa = new SignalAssignment(name, tmp); FILE_NAME(tmpa, @1); $$ = tmpa; } ; concurrent_simple_signal_assignment : name LEQ waveform ';' { ExpName*name = dynamic_cast ($1); assert(name); SignalAssignment*tmp = new SignalAssignment(name, *$3); FILE_NAME(tmp, @1); $$ = tmp; delete $3; } else_when_waveforms : else_when_waveforms else_when_waveform { list*tmp = $1; tmp ->push_back($2); $$ = tmp; } | else_when_waveform { list*tmp = new list; tmp->push_back($1); $$ = tmp; } ; else_when_waveforms_opt : else_when_waveforms { $$ = $1; } | { $$ = 0; } ; else_when_waveform : K_else waveform K_when expression { ExpConditional::case_t*tmp = new ExpConditional::case_t($4, $2); FILE_NAME(tmp, @1); $$ = tmp; } | K_else waveform { ExpConditional::case_t*tmp = new ExpConditional::case_t(0, $2); FILE_NAME(tmp, @1); $$ = tmp; } ; concurrent_signal_assignment_statement /* IEEE 1076-2008 P11.6 */ : concurrent_simple_signal_assignment | IDENTIFIER ':' concurrent_simple_signal_assignment { delete[] $1; $$ = $3; } | concurrent_conditional_signal_assignment | IDENTIFIER ':' concurrent_conditional_signal_assignment { delete[] $1; $$ = $3; } | selected_signal_assignment | IDENTIFIER ':' selected_signal_assignment { $$ = $3; } | name LEQ error ';' { errormsg(@2, "Syntax error in signal assignment waveform.\n"); delete $1; $$ = 0; yyerrok; } | error LEQ waveform ';' { errormsg(@1, "Syntax error in l-value of signal assignment.\n"); yyerrok; delete $3; $$ = 0; } ; concurrent_statement : component_instantiation_statement | concurrent_signal_assignment_statement | concurrent_assertion_statement | generate_statement | process_statement ; configuration_declaration : K_configuration IDENTIFIER K_of IDENTIFIER K_is configuration_declarative_part block_configuration K_end K_configuration_opt identifier_opt ';' { if(design_entities.find(lex_strings.make($4)) == design_entities.end()) errormsg(@4, "Couldn't find entity %s used in configuration declaration\n", $4); //choose_architecture_for_entity(); sorrymsg(@1, "Configuration declaration is not yet supported.\n"); } | K_configuration error K_end K_configuration_opt identifier_opt ';' { errormsg(@2, "Too many errors, giving up on configuration declaration.\n"); if($5) delete $5; yyerrok; } ; //TODO: this list is only a sketch. It must be filled out later configuration_declarative_item : use_clause ; configuration_declarative_items : configuration_declarative_items configuration_declarative_item | configuration_declarative_item ; configuration_declarative_part : configuration_declarative_items | ; configuration_item : block_configuration | component_configuration ; configuration_items : configuration_items configuration_item | configuration_item ; configuration_items_opt : configuration_items | ; constant_declaration : K_constant identifier_list ':' subtype_indication VASSIGN expression ';' { // The syntax allows multiple names to have the same type/value. for (std::list::iterator cur = $2->begin() ; cur != $2->end() ; ++cur) { active_scope->bind_name(*cur, $4, $6); } delete $2; } | K_constant identifier_list ':' subtype_indication ';' { sorrymsg(@1, "Deferred constant declarations not supported\n"); delete $2; } /* Some error handling... */ | K_constant identifier_list ':' subtype_indication VASSIGN error ';' { // The syntax allows multiple names to have the same type/value. errormsg(@6, "Error in value expression for constants.\n"); yyerrok; for (std::list::iterator cur = $2->begin() ; cur != $2->end() ; ++cur) { active_scope->bind_name(*cur, $4, 0); } delete $2; } | K_constant identifier_list ':' error ';' { errormsg(@4, "Syntax error in constant declaration type.\n"); yyerrok; delete $2; } | K_constant error ';' { errormsg(@2, "Syntax error in constant declaration.\n"); yyerrok; } ; context_clause : context_items | ; context_item : library_clause | use_clause_lib ; context_items : context_items context_item | context_item ; design_unit : context_clause library_unit | error { errormsg(@1, "Invalid design_unit\n"); } ; design_units : design_units design_unit | design_unit ; direction : K_to { $$ = ExpRange::TO; } | K_downto { $$ = ExpRange::DOWNTO; } ; element_association : choices ARROW expression { ExpAggregate::element_t*tmp = new ExpAggregate::element_t($1, $3); delete $1; $$ = tmp; } | expression { ExpAggregate::element_t*tmp = new ExpAggregate::element_t(0, $1); $$ = tmp; } ; element_association_list : element_association_list ',' element_association { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | element_association { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; element_declaration : identifier_list ':' subtype_indication ';' { $$ = record_elements($1, $3); delete $1; } ; element_declaration_list : element_declaration_list element_declaration { $$ = $1; $$->splice($$->end(), *$2); delete $2; } | element_declaration { $$ = $1; } ; /* As an entity is declared, add it to the map of design entities. */ entity_aspect : K_entity name { ExpName* name = dynamic_cast($2); entity_aspect_t* tmp = new entity_aspect_t(entity_aspect_t::ENTITY, name); $$ = tmp; } | K_configuration name { ExpName* name = dynamic_cast($2); entity_aspect_t* tmp = new entity_aspect_t(entity_aspect_t::CONFIGURATION, name); $$ = tmp; } | K_open { entity_aspect_t* tmp = new entity_aspect_t(entity_aspect_t::OPEN, 0); $$ = tmp; } ; entity_aspect_opt : entity_aspect { $$ = $1; } | { $$ = 0; } ; entity_declaration : K_entity IDENTIFIER K_is generic_clause_opt port_clause_opt K_end K_entity_opt identifier_opt';' { Entity*tmp = new Entity(lex_strings.make($2)); FILE_NAME(tmp, @1); // Transfer the ports tmp->set_interface($4, $5); delete $4; delete $5; // Save the entity in the entity map. design_entities[tmp->get_name()] = tmp; delete[]$2; if($8 && tmp->get_name() != $8) { errormsg(@1, "Syntax error in entity clause. Closing name doesn't match.\n"); } delete[]$8; } | K_entity error K_end K_entity_opt identifier_opt ';' { errormsg(@1, "Too many errors, giving up on entity declaration.\n"); yyerrok; if ($5) delete[]$5; } ; enumeration_literal : IDENTIFIER { list*tmp = new list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } ; enumeration_literal_list : enumeration_literal_list ',' enumeration_literal { list*tmp = $1; list*tmp3 = $3; if (tmp3) { tmp->splice(tmp->end(), *tmp3); delete tmp3; } $$ = tmp; } | enumeration_literal { list*tmp = $1; $$ = tmp; } ; expression_list : expression_list ',' expression { list*tmp = $1; tmp->push_back($3); $$ = tmp; } | expression { list*tmp = new list; tmp->push_back($1); $$ = tmp; } ; expression : expression_logical { $$ = $1; } | range { $$ = $1; } ; /* * The expression_logical matches the logical_expression from the * standard. Note that this is a little more tricky then usual because * of the strange VHDL rules for logical expressions. We have to * account for things like this: * * and and ... * * which is matched by the standard rule: * * logical_expression ::= * ... * relation { and relation } * * The {} is important, and implies that "and" can be strung together * with other "and" operators without parentheses. This is true for * "and", "or", "xor", and "xnor". The tricky part is that these * cannot be mixed. For example, this is not OK: * * and or * * Also note that "nand" and "nor" can not be chained in this manner. */ expression_logical : relation { $$ = $1; } | relation K_and expression_logical_and { ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | relation K_or expression_logical_or { ExpLogical*tmp = new ExpLogical(ExpLogical::OR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | relation K_xor expression_logical_xor { ExpLogical*tmp = new ExpLogical(ExpLogical::XOR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | relation K_nand relation { ExpLogical*tmp = new ExpLogical(ExpLogical::NAND, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | relation K_nor relation { ExpLogical*tmp = new ExpLogical(ExpLogical::NOR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | relation K_xnor expression_logical_xnor { ExpLogical*tmp = new ExpLogical(ExpLogical::XNOR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; expression_logical_and : relation { $$ = $1; } | expression_logical_and K_and relation { ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; expression_logical_or : relation { $$ = $1; } | expression_logical_or K_or relation { ExpLogical*tmp = new ExpLogical(ExpLogical::OR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; expression_logical_xnor : relation { $$ = $1; } | expression_logical_xnor K_xnor relation { ExpLogical*tmp = new ExpLogical(ExpLogical::XNOR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; expression_logical_xor : relation { $$ = $1; } | expression_logical_xor K_xor relation { ExpLogical*tmp = new ExpLogical(ExpLogical::XOR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; factor : primary { $$ = $1; } | primary EXP primary { ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::POW, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | K_abs primary { ExpUAbs*tmp = new ExpUAbs($2); FILE_NAME(tmp, @1); $$ = tmp; } | K_not primary { ExpUNot*tmp = new ExpUNot($2); FILE_NAME(tmp, @1); $$ = tmp; } ; file_declaration : K_file identifier_list ':' IDENTIFIER file_open_information_opt ';' { if (strcasecmp($4, "TEXT")) sorrymsg(@1, "file declaration currently handles only TEXT type.\n"); for (std::list::iterator cur = $2->begin() ; cur != $2->end() ; ++cur) { Variable*var = new Variable(*cur, &primitive_INTEGER); FILE_NAME(var, @1); active_scope->bind_name(*cur, var); // there was a file name specified, so it needs an implicit call // to open it at the beginning of simulation and close it at the end if($5) { std::list params; // add file_open() call in 'initial' block params.push_back(new ExpScopedName(active_scope->peek_name(), new ExpName(*cur))); params.push_back($5->filename()->clone()); params.push_back($5->kind()->clone()); ProcedureCall*fopen_call = new ProcedureCall( perm_string::literal("file_open"), ¶ms); arc_scope->add_initializer(fopen_call); // add file_close() call in 'final' block params.clear(); params.push_back(new ExpScopedName(active_scope->peek_name(), new ExpName(*cur))); ProcedureCall*fclose_call = new ProcedureCall( perm_string::literal("file_close"), ¶ms); arc_scope->add_finalizer(fclose_call); delete $5; } } delete $2; } | K_file error ';' { errormsg(@2, "Syntax error in file declaration.\n"); yyerrok; } ; file_open_information : K_open IDENTIFIER K_is STRING_LITERAL { ExpName*mode = new ExpName(lex_strings.make($2)); delete[]$2; FILE_NAME(mode, @1); $$ = new file_open_info_t(new ExpString($4), mode); } | K_is STRING_LITERAL { $$ = new file_open_info_t(new ExpString($2)); } file_open_information_opt : file_open_information { $$ = $1; } | { $$ = 0; } ; for_generate_statement : IDENTIFIER ':' K_for IDENTIFIER K_in range K_generate generate_statement_body K_end K_generate identifier_opt ';' { perm_string name = lex_strings.make($1); perm_string gvar = lex_strings.make($4); ForGenerate*tmp = new ForGenerate(name, gvar, $6, *$8); FILE_NAME(tmp, @1); if ($11 && name != $11) { errormsg(@1, "for-generate name %s does not match closing name %s\n", name.str(), $11); } delete[]$1; delete[]$4; delete $8; delete[]$11; $$ = tmp; } ; function_specification /* IEEE 1076-2008 P4.2.1 */ : K_function IDENTIFIER parameter_list K_return IDENTIFIER { perm_string type_name = lex_strings.make($5); perm_string name = lex_strings.make($2); const VType*type_mark = active_scope->find_type(type_name); touchup_interface_for_functions($3); SubprogramHeader*tmp = new SubprogramHeader(name, $3, type_mark); FILE_NAME(tmp, @1); delete[]$2; delete[]$5; $$ = tmp; } ; generate_statement /* IEEE 1076-2008 P11.8 */ : if_generate_statement | for_generate_statement ; generate_statement_body : architecture_statement_part { $$ = $1; } ; generic_clause_opt : generic_clause { $$ = $1;} | { $$ = 0; } ; generic_clause : K_generic parameter_list ';' { $$ = $2; } | K_generic '(' error ')' ';' { errormsg(@3, "Error in interface list for generic.\n"); yyerrok; $$ = 0; } ; generic_map_aspect_opt : generic_map_aspect { $$ = $1; } | { $$ = 0; } ; generic_map_aspect : K_generic K_map '(' association_list ')' { $$ = $4; } | K_generic K_map '(' error ')' { errormsg(@4, "Error in association list for generic map.\n"); yyerrok; $$ = 0; } ; identifier_list : identifier_list ',' IDENTIFIER { std::list* tmp = $1; tmp->push_back(lex_strings.make($3)); delete[]$3; $$ = tmp; } | IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } ; identifier_opt : IDENTIFIER { $$ = $1; } | { $$ = 0; } ; identifier_colon_opt : IDENTIFIER ':' { $$ = $1; } | { $$ = 0; }; /* The if_generate_statement rule describes the if_generate syntax. NOTE: This does not yet implement the elsif and else parts of the syntax. This shouldn't be hard, but is simply not done yet. */ if_generate_statement /* IEEE 1076-2008 P11.8 */ : IDENTIFIER ':' K_if expression K_generate generate_statement_body K_end K_generate identifier_opt ';' { perm_string name = lex_strings.make($1); IfGenerate*tmp = new IfGenerate(name, $4, *$6); FILE_NAME(tmp, @3); if ($9 && name != $9) { errormsg(@1, "if-generate name %s does not match closing name %s\n", name.str(), $9); } delete[]$1; delete $6; delete[]$9; $$ = tmp; } ; if_statement : K_if expression K_then sequence_of_statements if_statement_elsif_list_opt if_statement_else K_end K_if ';' { IfSequential*tmp = new IfSequential($2, $4, $5, $6); FILE_NAME(tmp, @1); delete $4; delete $5; delete $6; $$ = tmp; } | K_if error K_then sequence_of_statements if_statement_elsif_list_opt if_statement_else K_end K_if ';' { errormsg(@2, "Error in if_statement condition expression.\n"); yyerrok; $$ = 0; delete $4; } | K_if expression K_then error K_end K_if ';' { errormsg(@4, "Too many errors in sequence within if_statement.\n"); yyerrok; $$ = 0; } | K_if error K_end K_if ';' { errormsg(@2, "Too many errors in if_statement.\n"); yyerrok; $$ = 0; } ; if_statement_elsif_list_opt : if_statement_elsif_list { $$ = $1; } | { $$ = 0; } ; if_statement_elsif_list : if_statement_elsif_list if_statement_elsif { list*tmp = $1; tmp->push_back($2); $$ = tmp; } | if_statement_elsif { list*tmp = new list; tmp->push_back($1); $$ = tmp; } ; if_statement_elsif : K_elsif expression K_then sequence_of_statements { IfSequential::Elsif*tmp = new IfSequential::Elsif($2, $4); FILE_NAME(tmp, @1); delete $4; $$ = tmp; } | K_elsif expression K_then error { errormsg(@4, "Too many errors in elsif sub-statements.\n"); yyerrok; $$ = 0; } ; if_statement_else : K_else sequence_of_statements { $$ = $2; } | K_else error { errormsg(@2, "Too many errors in else sub-statements.\n"); yyerrok; $$ = 0; } | { $$ = 0; } ; index_constraint : '(' range_list ')' { $$ = $2; } | '(' error ')' { errormsg(@2, "Errors in the index constraint.\n"); yyerrok; $$ = new list; } ; /* The identifier should be a type name */ index_subtype_definition /* IEEE 1076-2008 P5.3.2.1 */ : IDENTIFIER K_range BOX ; index_subtype_definition_list : index_subtype_definition_list ',' index_subtype_definition | index_subtype_definition ; instantiation_list : identifier_list { instant_list_t* tmp = new instant_list_t(instant_list_t::NO_DOMAIN, $1); $$ = tmp; } | K_others { instant_list_t* tmp = new instant_list_t(instant_list_t::OTHERS, 0); $$ = tmp; } | K_all { instant_list_t* tmp = new instant_list_t(instant_list_t::ALL, 0); $$ = tmp; } ; /* The interface_element is also an interface_declaration */ interface_element : identifier_list ':' mode_opt subtype_indication interface_element_expression { std::list*tmp = new std::list; for (std::list::iterator cur = $1->begin() ; cur != $1->end() ; ++cur) { InterfacePort*port = new InterfacePort; FILE_NAME(port, @1); port->mode = $3; port->name = *(cur); port->type = $4; port->expr = $5; tmp->push_back(port); } delete $1; $$ = tmp; } ; interface_element_expression : VASSIGN expression { $$ = $2; } | { $$ = 0; } ; interface_list : interface_list ';' interface_element { std::list*tmp = $1; tmp->splice(tmp->end(), *$3); delete $3; $$ = tmp; } | interface_element { std::list*tmp = $1; $$ = tmp; } ; library_clause : K_library logical_name_list ';' { library_import(@1, $2); delete $2; } | K_library error ';' { errormsg(@1, "Syntax error in library clause.\n"); yyerrok; } ; /* Collapse the primary_unit and secondary_unit of the library_unit into this single set of rules. */ library_unit : primary_unit | secondary_unit ; logical_name : IDENTIFIER { $$ = $1; } ; logical_name_list : logical_name_list ',' logical_name { std::list*tmp = $1; tmp->push_back(lex_strings.make($3)); delete[]$3; $$ = tmp; } | logical_name { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } ; loop_statement : identifier_colon_opt K_while expression_logical K_loop sequence_of_statements K_end K_loop identifier_opt ';' { perm_string loop_name = $1? lex_strings.make($1) : perm_string() ; if ($8 && !$1) { errormsg(@8, "Loop statement closing name %s for un-named statement\n", $8); } else if($8 && loop_name != $8) { errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $8); } if($1) delete[]$1; if($8) delete[]$8; WhileLoopStatement* tmp = new WhileLoopStatement(loop_name, $3, $5); FILE_NAME(tmp, @1); $$ = tmp; } | identifier_colon_opt K_for IDENTIFIER K_in range K_loop sequence_of_statements K_end K_loop identifier_opt ';' { perm_string loop_name = $1? lex_strings.make($1) : perm_string() ; perm_string index_name = lex_strings.make($3); if ($10 && !$1) { errormsg(@10, "Loop statement closing name %s for un-named statement\n", $10); } else if($10 && loop_name != $10) { errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $10); } if($1) delete[] $1; delete[] $3; if($10) delete[] $10; ForLoopStatement* tmp = new ForLoopStatement(loop_name, index_name, $5, $7); FILE_NAME(tmp, @1); $$ = tmp; } | identifier_colon_opt K_loop sequence_of_statements K_end K_loop identifier_opt ';' { perm_string loop_name = $1? lex_strings.make($1) : perm_string() ; if ($6 && !$1) { errormsg(@6, "Loop statement closing name %s for un-named statement\n", $6); } else if($6 && loop_name != $6) { errormsg(@1, "Loop statement name %s doesn't match closing name %s.\n", loop_name.str(), $6); } if($1) delete[]$1; if($6) delete[]$6; BasicLoopStatement* tmp = new BasicLoopStatement(loop_name, $3); FILE_NAME(tmp, @2); $$ = tmp; }; mode : K_in { $$ = PORT_IN; } | K_out { $$ = PORT_OUT; } | K_inout { $$ = PORT_INOUT; } ; mode_opt : mode {$$ = $1;} | {$$ = PORT_NONE;} ; name /* IEEE 1076-2008 P8.1 */ : IDENTIFIER /* simple_name (IEEE 1076-2008 P8.2) */ { Expression*tmp; /* Check if the IDENTIFIER is one of CHARACTER enums (LF, CR, etc.) */ tmp = parse_char_enums($1); if(!tmp) { perm_string name = lex_strings.make($1); /* There are functions that have the same name types, e.g. integer */ if(!active_scope->find_subprogram(name).empty() && !parse_type_by_name(name)) tmp = new ExpFunc(name); else tmp = new ExpName(name); } FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | selected_name { $$ = $1; } | indexed_name { $$ = $1; } | selected_name '(' expression_list ')' { ExpName*name = dynamic_cast($1); assert(name); name->add_index($3); delete $3; // contents of the list is moved to the selected_name } ; indexed_name /* Note that this rule can match array element selects and various function calls. The only way we can tell the difference is from left context, namely whether the name is a type name or function name. If none of the above, treat it as a array element select. */ : IDENTIFIER '(' expression_list ')' { Expression*tmp; perm_string name = lex_strings.make($1); delete[]$1; if (active_scope->is_vector_name(name) || is_subprogram_param(name)) tmp = new ExpName(name, $3); else tmp = new ExpFunc(name, $3); FILE_NAME(tmp, @1); $$ = tmp; } | indexed_name '(' expression_list ')' { ExpName*name = dynamic_cast($1); assert(name); name->add_index($3); $$ = $1; } ; /* Handle name lists as lists of expressions. */ name_list : name_list ',' name { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | name { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; package_declaration : package_declaration_start K_is package_declarative_part_opt K_end K_package_opt identifier_opt ';' { perm_string name = lex_strings.make($1); if($6 && name != $6) { errormsg(@1, "Identifier %s doesn't match package name %s.\n", $6, name.str()); } Package*tmp = new Package(name, *active_scope); FILE_NAME(tmp, @1); delete[]$1; if ($6) delete[]$6; pop_scope(); /* Put this package into the work library, or the currently parsed library. Note that parse_library_name is an argument to the parser. */ library_save_package(parse_library_name, tmp); } | package_declaration_start K_is error K_end K_package_opt identifier_opt ';' { errormsg(@3, "Syntax error in package clause.\n"); yyerrok; pop_scope(); } ; package_declaration_start : K_package IDENTIFIER { push_scope(); $$ = $2; } ; /* TODO: this list must be extended in the future presently it is only a sketch */ package_body_declarative_item /* IEEE1076-2008 P4.8 */ : use_clause | subprogram_body ; package_body_declarative_items : package_body_declarative_items package_body_declarative_item | package_body_declarative_item ; package_body_declarative_part_opt : package_body_declarative_items | ; package_declarative_item : component_declaration | constant_declaration | subprogram_declaration | subtype_declaration | type_declaration | use_clause | error ';' { errormsg(@1, "Syntax error in package declarative item.\n"); yyerrok; } ; package_declarative_items : package_declarative_items package_declarative_item | package_declarative_item ; package_declarative_part_opt : package_declarative_items | ; package_body /* IEEE 1076-2008 P4.8 */ : package_body_start K_is package_body_declarative_part_opt K_end K_package_opt identifier_opt ';' { perm_string name = lex_strings.make($1); if ($6 && name != $6) errormsg(@6, "Package name (%s) doesn't match closing name (%s).\n", $1, $6); delete[] $1; if($6) delete[]$6; pop_scope(); } | package_body_start K_is error K_end K_package_opt identifier_opt ';' { errormsg(@1, "Errors in package %s body.\n", $1); yyerrok; pop_scope(); } ; /* * This is a portion of the package_body rule that we factor out so * that we can use this rule to start the scope. */ package_body_start : K_package K_body IDENTIFIER { perm_string name = lex_strings.make($3); push_scope(); Package*pkg = library_recall_package(parse_library_name, name); if (pkg != 0) { active_scope->set_package_header(pkg); } else { errormsg(@1, "Package body for %s has no matching header.\n", $3); } $$ = $3; } ; parameter_list : '(' interface_list ')' { $$ = $2; } ; parameter_list_opt : parameter_list { $$ = $1; } | { $$ = 0; } ; port_clause : K_port parameter_list ';' { $$ = $2; } | K_port '(' error ')' ';' { errormsg(@1, "Syntax error in port list.\n"); yyerrok; $$ = 0; } ; port_clause_opt : port_clause {$$ = $1;} | {$$ = 0;} ; port_map_aspect : K_port K_map '(' association_list ')' { $$ = $4; } | K_port K_map '(' error ')' { errormsg(@1, "Syntax error in port map aspect.\n"); yyerrok; } ; port_map_aspect_opt : port_map_aspect { $$ = $1; } | { $$ = 0; } ; prefix /* IEEE 1076-2008 P8.1 */ : name { $$ = $1; } ; primary : name { $$ = $1; } | name '\'' IDENTIFIER argument_list_opt { ExpAttribute*tmp = NULL; perm_string attr = lex_strings.make($3); ExpName*base = dynamic_cast($1); const VType*type = parse_type_by_name(base->peek_name()); if(type) { tmp = new ExpTypeAttribute(type, attr, $4); } else { tmp = new ExpObjAttribute(base, attr, $4); } FILE_NAME(tmp, @1); delete[]$3; $$ = tmp; } | CHARACTER_LITERAL { ExpCharacter*tmp = new ExpCharacter($1[0]); FILE_NAME(tmp,@1); delete[]$1; $$ = tmp; } | INT_LITERAL { ExpInteger*tmp = new ExpInteger($1); FILE_NAME(tmp, @1); $$ = tmp; } | REAL_LITERAL { ExpReal*tmp = new ExpReal($1); FILE_NAME(tmp, @1); $$ = tmp; } | STRING_LITERAL { ExpString*tmp = new ExpString($1); FILE_NAME(tmp,@1); delete[]$1; $$ = tmp; } | BITSTRING_LITERAL { ExpBitstring*tmp = new ExpBitstring($1); FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; } | INT_LITERAL IDENTIFIER { ExpTime::timeunit_t unit = ExpTime::FS; if(!strcasecmp($2, "us")) unit = ExpTime::US; else if(!strcasecmp($2, "ms")) unit = ExpTime::MS; else if(!strcasecmp($2, "ns")) unit = ExpTime::NS; else if(!strcasecmp($2, "s")) unit = ExpTime::S; else if(!strcasecmp($2, "ps")) unit = ExpTime::PS; else if(!strcasecmp($2, "fs")) unit = ExpTime::FS; else errormsg(@2, "Invalid time unit (accepted are fs, ps, ns, us, ms, s).\n"); if($1 < 0) errormsg(@1, "Time cannot be negative.\n"); ExpTime*tmp = new ExpTime($1, unit); FILE_NAME(tmp, @1); delete[] $2; $$ = tmp; } /*XXXX Caught up in element_association_list? | '(' expression ')' { $$ = $2; } */ /* This catches function calls that use association lists for the argument list. The position argument list is discovered elsewhere and must be discovered by elaboration (thanks to the ambiguity of VHDL syntax). */ | IDENTIFIER '(' association_list ')' { sorrymsg(@1, "Function calls not supported\n"); delete[] $1; $$ = 0; } /* Aggregates */ | '(' element_association_list ')' { Expression*tmp = aggregate_or_primary(@1, $2); $$ = tmp; } ; primary_unit : entity_declaration | configuration_declaration | package_declaration ; procedure_call : IDENTIFIER ';' { ProcedureCall* tmp = new ProcedureCall(lex_strings.make($1)); FILE_NAME(tmp, @1); delete[] $1; $$ = tmp; } | IDENTIFIER '(' association_list ')' ';' { ProcedureCall* tmp = new ProcedureCall(lex_strings.make($1), $3); FILE_NAME(tmp, @1); delete[] $1; $$ = tmp; } | IDENTIFIER argument_list ';' { ProcedureCall* tmp = new ProcedureCall(lex_strings.make($1), $2); FILE_NAME(tmp, @1); delete[] $1; delete $2; // parameters are copied in this variant $$ = tmp; } | IDENTIFIER '(' error ')' ';' { errormsg(@1, "Errors in procedure call.\n"); yyerrok; delete[]$1; $$ = 0; } ; procedure_call_statement : IDENTIFIER ':' procedure_call { delete[] $1; $$ = $3; } | procedure_call { $$ = $1; } ; procedure_specification /* IEEE 1076-2008 P4.2.1 */ : K_procedure IDENTIFIER parameter_list_opt { perm_string name = lex_strings.make($2); touchup_interface_for_functions($3); SubprogramHeader*tmp = new SubprogramHeader(name, $3, NULL); FILE_NAME(tmp, @1); delete[]$2; $$ = tmp; } ; process_declarative_item : variable_declaration | file_declaration ; process_declarative_part : process_declarative_part process_declarative_item | process_declarative_item ; process_declarative_part_opt : process_declarative_part | ; process_start : identifier_colon_opt K_postponed_opt K_process { push_scope(); $$ = $1; } ; process_statement : process_start process_sensitivity_list_opt K_is_opt process_declarative_part_opt K_begin sequence_of_statements K_end K_postponed_opt K_process identifier_opt ';' { perm_string iname = $1? lex_strings.make($1) : empty_perm_string; if ($1) delete[]$1; if ($10) { if (iname.nil()) { errormsg(@10, "Process end name %s for un-named processes.\n", $10); } else if (iname != $10) { errormsg(@10, "Process name %s does not match opening name %s.\n", $10, $1); } delete[]$10; } ProcessStatement*tmp = new ProcessStatement(iname, *active_scope, $2, $6); arc_scope->bind_scope(tmp->peek_name(), tmp); pop_scope(); FILE_NAME(tmp, @3); delete $2; delete $6; $$ = tmp; } | process_start process_sensitivity_list_opt K_is_opt process_declarative_part_opt K_begin error K_end K_postponed_opt K_process identifier_opt ';' { errormsg(@7, "Too many errors in process sequential statements.\n"); yyerrok; $$ = 0; } ; /* * A process_sensitivity_list is: * if the list is not present, or * or a non-empty list of actual expressions. */ process_sensitivity_list_opt : '(' process_sensitivity_list ')' { $$ = $2; } | '(' error ')' { errormsg(@2, "Error in process sensitivity list\n"); yyerrok; $$ = 0; } | { $$ = 0; } ; process_sensitivity_list : K_all { std::list*tmp = new std::list; ExpName*all = new ExpNameALL; FILE_NAME(all, @1); tmp->push_back(all); $$ = tmp; } | name_list { $$ = $1; } ; range : simple_expression direction simple_expression { ExpRange* tmp = new ExpRange($1, $3, $2); FILE_NAME(tmp, @1); $$ = tmp; } | name '\'' K_range { ExpRange*tmp = NULL; ExpName*name = NULL; if((name = dynamic_cast($1))) { tmp = new ExpRange(name, false); FILE_NAME(tmp, @1); } else { errormsg(@1, "'range attribute can be used with named expressions only"); } $$ = tmp; } | name '\'' K_reverse_range { ExpRange*tmp = NULL; ExpName*name = NULL; if((name = dynamic_cast($1))) { tmp = new ExpRange(name, true); FILE_NAME(tmp, @1); } else { errormsg(@1, "'reverse_range attribute can be used with named expressions only"); } $$ = tmp; } ; range_list : range { list*tmp = new list; tmp->push_back($1); $$ = tmp; } | range_list ',' range { list*tmp = $1; tmp->push_back($3); $$ = tmp; } ; record_type_definition : K_record element_declaration_list K_end K_record { VTypeRecord*tmp = new VTypeRecord($2); $$ = tmp; } ; relation : shift_expression { $$ = $1; } | shift_expression '=' shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::EQ, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | shift_expression '<' shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::LT, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | shift_expression '>' shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::GT, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | shift_expression LEQ shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::LE, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | shift_expression GEQ shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::GE, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | shift_expression NE shift_expression { ExpRelation*tmp = new ExpRelation(ExpRelation::NEQ, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; report_statement : K_report expression severity_opt ';' { ReportStmt*tmp = new ReportStmt($2, $3); FILE_NAME(tmp,@2); $$ = tmp; } return_statement : K_return expression ';' { ReturnStmt*tmp = new ReturnStmt($2); FILE_NAME(tmp, @1); $$ = tmp; } | K_return ';' { ReturnStmt*tmp = new ReturnStmt(0); FILE_NAME(tmp, @1); $$ = tmp; } | K_return error ';' { ReturnStmt*tmp = new ReturnStmt(0); FILE_NAME(tmp, @1); $$ = tmp; errormsg(@2, "Error in expression in return statement.\n"); yyerrok; } ; secondary_unit : architecture_body | package_body ; selected_name /* IEEE 1076-2008 P8.3 */ : prefix '.' suffix { Expression*pfx = $1; ExpName*pfx1 = dynamic_cast(pfx); assert(pfx1); perm_string tmp = lex_strings.make($3); $$ = new ExpName(pfx1, tmp); FILE_NAME($$, @3); delete[]$3; } | error '.' suffix { errormsg(@1, "Syntax error in prefix in front of \"%s\".\n", $3); yyerrok; $$ = new ExpName(lex_strings.make($3)); FILE_NAME($$, @3); delete[]$3; } ; selected_names : selected_names ',' selected_name { std::list* tmp = $1; tmp->push_back($3); $$ = tmp; } | selected_name { std::list* tmp = new std::list(); tmp->push_back($1); $$ = tmp; } ; /* The *_lib variant of selected_name is used by the "use" clause. It is syntactically identical to other selected_name rules, but is a convenient place to attach use_clause actions. */ selected_name_lib : IDENTIFIER '.' K_all { library_use(@1, active_scope, 0, $1, 0); delete[]$1; } | IDENTIFIER '.' IDENTIFIER '.' K_all { library_use(@1, active_scope, $1, $3, 0); delete[]$1; delete[]$3; } | IDENTIFIER '.' IDENTIFIER '.' IDENTIFIER { library_use(@1, active_scope, $1, $3, $5); delete[]$1; delete[]$3; delete[]$5; } ; selected_names_lib : selected_names_lib ',' selected_name_lib | selected_name_lib ; selected_signal_assignment : K_with expression K_select name LEQ selected_waveform_list ';' { ExpSelected*tmp = new ExpSelected($2, $6); FILE_NAME(tmp, @3); delete $2; delete $6; ExpName*name = dynamic_cast($4); assert(name); SignalAssignment*tmpa = new SignalAssignment(name, tmp); FILE_NAME(tmpa, @1); $$ = tmpa; } ; selected_waveform : waveform K_when expression { ExpConditional::case_t*tmp = new ExpConditional::case_t($3, $1); FILE_NAME(tmp, @1); $$ = tmp; } | waveform K_when K_others { ExpConditional::case_t*tmp = new ExpConditional::case_t(0, $1); FILE_NAME(tmp, @1); $$ = tmp; } ; selected_waveform_list : selected_waveform_list ',' selected_waveform { list*tmp = $1; tmp->push_back($3); $$ = tmp; } | selected_waveform { list*tmp = new list; tmp->push_back($1); $$ = tmp; } ; list_of_statements : list_of_statements sequential_statement { std::list*tmp = $1; if($2) tmp->push_back($2); $$ = tmp; } | sequential_statement { std::list*tmp = new std::list; if($1) tmp->push_back($1); $$ = tmp; } ; sequence_of_statements : list_of_statements { $1 = $$; } | { $$ = NULL; } ; sequential_statement : if_statement { $$ = $1; } | signal_assignment_statement { $$ = $1; } | variable_assignment_statement { $$ = $1; } | case_statement { $$ = $1; } | procedure_call_statement { $$ = $1; } | loop_statement { $$ = $1; } | return_statement { $$ = $1; } | report_statement { $$ = $1; } | assertion_statement { $$ = $1; } | wait_statement { $$ = $1; } | K_null ';' { $$ = 0; } | error ';' { errormsg(@1, "Syntax error in sequential statement.\n"); $$ = 0; yyerrok; } ; severity : K_severity IDENTIFIER { if(!strcasecmp($2, "NOTE")) $$ = ReportStmt::NOTE; else if(!strcasecmp($2, "WARNING")) $$ = ReportStmt::WARNING; else if(!strcasecmp($2, "ERROR")) $$ = ReportStmt::ERROR; else if(!strcasecmp($2, "FAILURE")) $$ = ReportStmt::FAILURE; else { errormsg(@1, "Invalid severity level (possible values: NOTE, WARNING, ERROR, FAILURE).\n"); $$ = ReportStmt::UNSPECIFIED; } delete[] $2; } severity_opt : severity { $$ = $1; } | { $$ = ReportStmt::UNSPECIFIED; } shift_expression : simple_expression | simple_expression K_srl simple_expression { ExpShift*tmp = new ExpShift(ExpShift::SRL, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | simple_expression K_sll simple_expression { ExpShift*tmp = new ExpShift(ExpShift::SLL, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | simple_expression K_sra simple_expression { ExpShift*tmp = new ExpShift(ExpShift::SRA, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | simple_expression K_sla simple_expression { ExpShift*tmp = new ExpShift(ExpShift::SLA, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | simple_expression K_ror simple_expression { sorrymsg(@2, "ROR is not supported.\n"); ExpShift*tmp = new ExpShift(ExpShift::ROR, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | simple_expression K_rol simple_expression { sorrymsg(@2, "ROL is not supported.\n"); ExpShift*tmp = new ExpShift(ExpShift::ROL, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; signal_declaration_assign_opt : VASSIGN expression { $$ = $2; } | { $$ = 0; } ; /* * The LRM rule for simple_expression is: * simple_expression ::= [sign] term { adding_operator term } * * This is functionally a list of terms, with the adding_operator used * as a list element separator instead of a ','. The LRM rule, * however, is right-recursive, which is not too nice in real LALR * parsers. The solution is to rewrite it as below, to make it * left-recursive. This is much more efficient use of the parse stack. * * Note that although the concatenation operator '&' is syntactically * an addition operator, it is handled differently during elaboration * so detect it and create a different expression type. * * Note too that I'm using *right* recursion to implement the {...} * part of the rule. This is normally bad, but expression lists aren't * normally that long, and the while loop going through the formed * list fixes up the associations. */ simple_expression : '-' simple_expression_2 { $$ = new ExpUMinus($2); } | '+' simple_expression_2 { $$ = $2; } | simple_expression_2 { $$ = $1; } ; simple_expression_2 : term { $$ = $1; } | term simple_expression_terms { Expression*tmp = $1; list*lst = $2; while (! lst->empty()) { struct adding_term item = lst->front(); lst->pop_front(); if (item.op == ExpArithmetic::xCONCAT) tmp = new ExpConcat(tmp, item.term); else tmp = new ExpArithmetic(item.op, tmp, item.term); } delete lst; FILE_NAME(tmp, @1); $$ = tmp; } ; simple_expression_terms : adding_operator term { struct adding_term item; item.op = $1; item.term = $2; list*tmp = new list; tmp->push_back(item); $$ = tmp; } | simple_expression_terms adding_operator term { list*tmp = $1; struct adding_term item; item.op = $2; item.term = $3; tmp->push_back(item); $$ = tmp; } ; signal_assignment : name LEQ waveform ';' { SignalSeqAssignment*tmp = new SignalSeqAssignment($1, $3); FILE_NAME(tmp, @1); delete $3; $$ = tmp; } | name LEQ waveform K_when expression K_else waveform ';' { SignalSeqAssignment*tmp = new SignalSeqAssignment($1, $3); FILE_NAME(tmp, @1); sorrymsg(@4, "Conditional signal assignment not supported.\n"); $$ = tmp; } ; signal_assignment_statement : signal_assignment | IDENTIFIER ':' signal_assignment { delete[] $1; $$ = $3; } subprogram_body_start : subprogram_specification K_is { assert(!active_sub); active_sub = $1; $$ = $1; } ; /* This is a function/task body. This may have a matching subprogram declaration, and if so it will be in the active scope. */ subprogram_body /* IEEE 1076-2008 P4.3 */ : subprogram_body_start subprogram_declarative_part K_begin subprogram_statement_part K_end subprogram_kind_opt identifier_opt ';' { SubprogramHeader*prog = $1; SubprogramHeader*tmp = active_scope->recall_subprogram(prog); if (tmp) { delete prog; prog = tmp; } SubprogramBody*body = new SubprogramBody(); body->transfer_from(*active_scope, ScopeBase::VARIABLES); body->set_statements($4); prog->set_body(body); active_scope->bind_subprogram(prog->name(), prog); active_sub = NULL; } | subprogram_body_start subprogram_declarative_part K_begin error K_end subprogram_kind_opt identifier_opt ';' { errormsg(@2, "Syntax errors in subprogram body.\n"); yyerrok; active_sub = NULL; if ($1) delete $1; if ($7) delete[]$7; } ; subprogram_declaration : subprogram_specification ';' { if ($1) active_scope->bind_subprogram($1->name(), $1); } ; subprogram_declarative_item /* IEEE 1079-2008 P4.3 */ : variable_declaration | file_declaration ; subprogram_declarative_item_list : subprogram_declarative_item_list subprogram_declarative_item | subprogram_declarative_item ; subprogram_declarative_part /* IEEE 1076-2008 P4.3 */ : subprogram_declarative_item_list | ; subprogram_kind /* IEEE 1076-2008 P4.3 */ : K_function | K_procedure ; subprogram_kind_opt : subprogram_kind | ; subprogram_specification : function_specification { $$ = $1; } | procedure_specification { $$ = $1; } ; /* This is an implementation of the rule: subprogram_statement_part ::= { sequential_statement } where the sequence_of_statements rule is a list of sequential_statement. */ subprogram_statement_part : sequence_of_statements { $$ = $1; } ; subtype_declaration : K_subtype IDENTIFIER K_is subtype_indication ';' { perm_string name = lex_strings.make($2); if ($4 == 0) { errormsg(@1, "Failed to declare type name %s.\n", name.str()); } else { VTypeDef*tmp; map::iterator cur = active_scope->incomplete_types.find(name); if (cur == active_scope->incomplete_types.end()) { tmp = new VSubTypeDef(name, $4); active_scope->bind_name(name, tmp); } else { tmp = cur->second; tmp->set_definition($4); active_scope->incomplete_types.erase(cur); } } delete[]$2; } ; subtype_indication : IDENTIFIER { const VType*tmp = parse_type_by_name(lex_strings.make($1)); if (tmp == 0) { errormsg(@1, "Can't find type name `%s'\n", $1); tmp = new VTypeERROR; } delete[]$1; $$ = tmp; } | IDENTIFIER index_constraint { const VType*tmp = calculate_subtype_array(@1, $1, active_scope, $2); if (tmp == 0) { errormsg(@1, "Unable to calculate bounds for array of %s.\n", $1); } delete[]$1; delete $2; $$ = tmp; } | IDENTIFIER K_range simple_expression direction simple_expression { const VType*tmp = calculate_subtype_range(@1, $1, active_scope, $3, $4, $5); if (tmp == 0) { errormsg(@1, "Unable to calculate bounds for range of %s.\n", $1); } delete[]$1; $$ = tmp; } ; suffix : IDENTIFIER { $$ = $1; } | CHARACTER_LITERAL { $$ = $1; } | K_all { //do not have now better idea than using char constant $$ = strdup("all"); } ; term : factor { $$ = $1; } | factor '*' factor { ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MULT, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | factor '/' factor { ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::DIV, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | factor K_mod factor { ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::MOD, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } | factor K_rem factor { ExpArithmetic*tmp = new ExpArithmetic(ExpArithmetic::REM, $1, $3); FILE_NAME(tmp, @2); $$ = tmp; } ; type_declaration : K_type IDENTIFIER K_is type_definition ';' { perm_string name = lex_strings.make($2); if ($4 == 0) { errormsg(@1, "Failed to declare type name %s.\n", name.str()); } else { VTypeDef*tmp; map::iterator cur = active_scope->incomplete_types.find(name); if (cur == active_scope->incomplete_types.end()) { tmp = new VTypeDef(name, $4); active_scope->bind_name(name, tmp); } else { tmp = cur->second; tmp->set_definition($4); active_scope->incomplete_types.erase(cur); } } delete[]$2; } | K_type IDENTIFIER ';' { perm_string name = lex_strings.make($2); VTypeDef*tmp = new VTypeDef(name); active_scope->incomplete_types[name] = tmp; active_scope->bind_name(name, tmp); delete[]$2; } | K_type IDENTIFIER K_is error ';' { errormsg(@4, "Error in type definition for %s\n", $2); yyerrok; delete[]$2; } | K_type error ';' { errormsg(@1, "Error in type definition\n"); yyerrok; } ; type_definition : '(' enumeration_literal_list ')' { VTypeEnum*tmp = new VTypeEnum($2); active_scope->use_enum(tmp); delete $2; $$ = tmp; } | composite_type_definition { $$ = $1; } ; use_clause : K_use selected_names ';' { $$ = $2; } | K_use error ';' { errormsg(@1, "Syntax error in use clause.\n"); yyerrok; } ; use_clause_lib : K_use selected_names_lib ';' | K_use error ';' { errormsg(@1, "Syntax error in use clause.\n"); yyerrok; } ; use_clauses_lib : use_clauses_lib use_clause_lib | use_clause_lib ; use_clauses_opt : use_clauses_lib | ; variable_assignment_statement /* IEEE 1076-2008 P10.6.1 */ : variable_assignment | IDENTIFIER ':' variable_assignment { delete[] $1; $$ = $3; } variable_assignment : name VASSIGN expression ';' { VariableSeqAssignment*tmp = new VariableSeqAssignment($1, $3); FILE_NAME(tmp, @1); $$ = tmp; } | name VASSIGN error ';' { errormsg(@3, "Syntax error in r-value expression of assignment.\n"); yyerrok; delete $1; $$ = 0; } | error VASSIGN expression ';' { errormsg(@1, "Syntax error in l-value expression of assignment.\n"); yyerrok; delete $3; $$ = 0; } ; variable_declaration /* IEEE 1076-2008 P6.4.2.4 */ : K_shared_opt K_variable identifier_list ':' subtype_indication variable_declaration_assign_opt ';' { /* Save the signal declaration in the block_signals map. */ for (std::list::iterator cur = $3->begin() ; cur != $3->end() ; ++cur) { Variable*sig = new Variable(*cur, $5, $6); FILE_NAME(sig, @2); active_scope->bind_name(*cur, sig); } delete $3; } | K_shared_opt K_variable error ';' { errormsg(@2, "Syntax error in variable declaration.\n"); yyerrok; } ; variable_declaration_assign_opt : VASSIGN expression { $$ = $2; } | { $$ = 0; } ; wait_statement : K_wait K_for expression ';' { WaitForStmt*tmp = new WaitForStmt($3); FILE_NAME(tmp, @1); $$ = tmp; } | K_wait K_on expression ';' { WaitStmt*tmp = new WaitStmt(WaitStmt::ON, $3); FILE_NAME(tmp, @1); $$ = tmp; } | K_wait K_until expression ';' { WaitStmt*tmp = new WaitStmt(WaitStmt::UNTIL, $3); FILE_NAME(tmp, @1); $$ = tmp; } | K_wait ';' { WaitStmt*tmp = new WaitStmt(WaitStmt::FINAL, NULL); FILE_NAME(tmp, @1); $$ = tmp; } ; waveform : waveform_elements { $$ = $1; } | K_unaffected { $$ = 0; } ; waveform_elements : waveform_elements ',' waveform_element { std::list*tmp = $1; tmp->push_back($3); $$ = tmp; } | waveform_element { std::list*tmp = new std::list; tmp->push_back($1); $$ = tmp; } ; waveform_element : expression { $$ = $1; } | expression K_after expression { ExpDelay*tmp = new ExpDelay($1, $3); FILE_NAME(tmp, @1); $$ = tmp; } | K_null { $$ = 0; } ; /* Some keywords are optional in some contexts. In all such cases, a similar rule is used, as described here. */ K_architecture_opt : K_architecture | ; K_configuration_opt: K_configuration| ; K_entity_opt : K_entity | ; K_is_opt : K_is | ; K_package_opt : K_package | ; K_postponed_opt : K_postponed | ; K_shared_opt : K_shared | ; %% static void yyerror(YYLTYPE*loc, yyscan_t, const char*, bool, const char*msg) { fprintf(stderr, "%s:%u: %s\n", loc->text, loc->first_line, msg); parse_errors += 1; } void errormsg(const YYLTYPE&loc, const char*fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%u: error: ", loc.text, loc.first_line); vfprintf(stderr, fmt, ap); va_end(ap); parse_errors += 1; } void sorrymsg(const YYLTYPE&loc, const char*fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%u: sorry: ", loc.text, loc.first_line); vfprintf(stderr, fmt, ap); va_end(ap); parse_sorrys += 1; } /* * The reset_lexor function takes the fd and makes it the input file * for the lexor. The path argument is used in lexor/parser error messages. */ extern yyscan_t prepare_lexor(FILE*fd); extern void destroy_lexor(yyscan_t scanner); int parse_source_file(const char*file_path, perm_string parse_library_name) { FILE*fd = fopen(file_path, "r"); if (fd == 0) { perror(file_path); return -1; } yyscan_t scanner = prepare_lexor(fd); int rc = yyparse(scanner, file_path, parse_library_name); fclose(fd); destroy_lexor(scanner); return rc; } iverilog-12_0/vhdlpp/parse_api.h000066400000000000000000000047761435245347300167760ustar00rootroot00000000000000#ifndef IVL_parse_api_H #define IVL_parse_api_H /* * Copyright (c) 2011-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 # include "entity.h" typedef void*yyscan_t; /* * The yyltype supports the passing of detailed source file location * information between the lexical analyzer and the parser. Defining * YYLTYPE compels the lexor to use this type and not something other. */ struct yyltype { unsigned first_line; const char*text; yyltype() { first_line = 1; text = ""; } }; # define YYLTYPE struct yyltype /* * This calls the bison-generated parser with the given file path as * the input stream. If the file cannot be opened, this returns -1. * The "library_name" argument is the name of the library that is * being parsed. If this is a regular source file, then this name is * nil. Note that the "work" library is handled specially. */ extern int parse_source_file(const char*file_path, perm_string library_name); /* * Use this function during parse to generate error messages. The "loc" * is the location of the token that triggered the error, and the fmt * is printf-style format. */ extern void errormsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3))); extern void sorrymsg(const YYLTYPE&loc, const char*fmt, ...) __attribute__((format (printf, 2, 3))); /* * Set this to a non-zero value to enable parser debug output. */ extern int yydebug; /* * The parser counts the errors that is handed in the parse_errors * variable. For a clean compile, this value should not change. (The * caller sets its initial value.) The sorrys are the count of * unsupported constructs that are encountered. */ extern int parse_errors; extern int parse_sorrys; #endif /* IVL_parse_api_H */ iverilog-12_0/vhdlpp/parse_misc.cc000066400000000000000000000126031435245347300173020ustar00rootroot00000000000000/* * Copyright (c) 2011,2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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. * Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704. */ # include "parse_misc.h" # include "parse_types.h" # include "parse_api.h" # include "entity.h" # include "architec.h" # include "expression.h" # include "vtype.h" # include "compiler.h" # include # include # include using namespace std; void bind_entity_to_active_scope(const char*ename, ActiveScope*scope) { perm_string ekey = lex_strings.make(ename); std::map::const_iterator idx = design_entities.find(ekey); if (idx == design_entities.end()) { return; } scope->bind(idx->second); } void bind_architecture_to_entity(const char*ename, Architecture*arch) { perm_string ekey = lex_strings.make(ename); std::map::const_iterator idx = design_entities.find(ekey); if (idx == design_entities.end()) { cerr << arch->get_fileline() << ": error: No entity " << ekey << " for architecture " << arch->get_name() << "." << endl; parse_errors += 1; return; } /* FIXME: entities can have multiple architectures attached to them This is to be configured by VHDL's configurations (not yet implemented) */ Architecture*old_arch = idx->second->add_architecture(arch); if (old_arch != arch) { cerr << arch->get_fileline() << ": warning: " << "Architecture " << arch->get_name() << " for entity " << idx->first << " is already defined here: " << old_arch->get_fileline() << endl; parse_errors += 1; } } static const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, ScopeBase* /* scope */, Expression*array_left, bool downto, Expression*array_right) { const VType*base_type = parse_type_by_name(lex_strings.make(base_name)); if (base_type == 0) { errormsg(loc, "Unable to find array base type '%s'.\n", base_name); return 0; } assert(array_left==0 || array_right!=0); // unfold typedef, there might be VTypeArray inside const VType*origin_type = base_type; const VTypeDef*type_def = dynamic_cast (base_type); if (type_def) { base_type = type_def->peek_definition(); } const VTypeArray*base_array = dynamic_cast (base_type); if (base_array) { assert(array_left && array_right); vector range (base_array->dimensions()); // For now, I only know how to handle 1 dimension assert(base_array->dimensions().size() == 1); range[0] = VTypeArray::range_t(array_left, array_right, downto); // use typedef as the element type if possible const VType*element = type_def ? origin_type : base_array->element_type(); VTypeArray*subtype = new VTypeArray(element, range, base_array->signed_vector()); subtype->set_parent_type(base_array); return subtype; } return base_type; } const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, ScopeBase*scope, list*ranges) { if (ranges->size() == 1) { ExpRange*tmpr = ranges->front(); Expression*lef = tmpr->left(); Expression*rig = tmpr->right(); return calculate_subtype_array(loc, base_name, scope, lef, (tmpr->direction() == ExpRange::DOWNTO ? true : false), rig); } sorrymsg(loc, "Don't know how to handle multiple ranges here.\n"); return 0; } const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name, ScopeBase*scope, Expression*range_left, int direction, Expression*range_right) { const VType*base_type = parse_type_by_name(lex_strings.make(base_name)); if (base_type == 0) { errormsg(loc, "Unable to find range base type '%s'.\n", base_name); return 0; } assert(range_left && range_right); int64_t left_val, right_val; VTypeRange*subtype; if(range_left->evaluate(scope, left_val) && range_right->evaluate(scope, right_val)) { subtype = new VTypeRangeConst(base_type, left_val, right_val); } else { subtype = new VTypeRangeExpr(base_type, range_left, range_right, direction); } return subtype; } ExpString*parse_char_enums(const char*str) { if(!strcasecmp(str, "LF")) return new ExpString("\\n"); if(!strcasecmp(str, "CR")) return new ExpString("\\r"); return NULL; } iverilog-12_0/vhdlpp/parse_misc.h000066400000000000000000000052471435245347300171520ustar00rootroot00000000000000#ifndef IVL_parse_misc_H #define IVL_parse_misc_H /* * Copyright (c) 2011,2014 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "parse_api.h" class ActiveScope; class Architecture; class Expression; class Package; class ExpRange; class ExpString; class ScopeBase; class VType; extern void bind_entity_to_active_scope(const char*ename, ActiveScope*scope); extern void bind_architecture_to_entity(const char*ename, Architecture*arch); extern const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, ScopeBase*scope, std::list*ranges); extern const VType* calculate_subtype_range(const YYLTYPE&loc, const char*base_name, ScopeBase*scope, Expression*range_left, int direction, Expression*range_right); /* * This function searches the currently active scope, or the global * scope, for the named type. */ extern const VType* parse_type_by_name(perm_string name); /* * The parser calls the library_save_package function when it parses a * package. The library_parse_name is the name of the library that is * currently being processed (by a recursive call to the parser to * load a package from a library) or a nil name to indicate that this * is from the live parser. */ extern void library_save_package(perm_string library_parse_name, Package*pack); extern Package*library_recall_package(perm_string library_parse_name, perm_string name); extern void library_import(const YYLTYPE&loc, const std::list*names); extern void library_use(const YYLTYPE&loc, ActiveScope*res, const char*libname, const char*pack, const char*ident); /* * Converts CHARACTER enums to an ExpString* if applicable. * See the standard VHDL library (package STANDARD) or VHDL-2008/16.3 * for more details). */ extern ExpString*parse_char_enums(const char*str); #endif /* IVL_parse_misc_H */ iverilog-12_0/vhdlpp/parse_types.h000066400000000000000000000060551435245347300173610ustar00rootroot00000000000000#ifndef IVL_parse_types_H #define IVL_parse_types_H /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "expression.h" class named_expr_t { public: named_expr_t(perm_string n, Expression*e) : name_(n), expr_(e) { } ~named_expr_t() { delete expr_; } perm_string name() const { return name_; } Expression* expr() const { return expr_; } void dump(std::ostream&out, int indent) const; private: perm_string name_; Expression* expr_; private: // Not implemented named_expr_t(const named_expr_t&); named_expr_t& operator = (const named_expr_t&); }; class entity_aspect_t { public: typedef enum { ENTITY = 0, CONFIGURATION, OPEN } entity_aspect_type_t; entity_aspect_t(entity_aspect_type_t t, ExpName* n) : type_(t), name_(n) {} ~entity_aspect_t() { delete name_; } ExpName* name() const { return name_; } entity_aspect_type_t type() const {return type_; } entity_aspect_type_t type_; ExpName* name_; }; class instant_list_t { public: typedef enum { ALL = 0, OTHERS, NO_DOMAIN } application_domain_t; instant_list_t(application_domain_t d, std::list* l) : domain_(d), labels_(l) {} ~instant_list_t() { delete labels_; } std::list* labels() const { return labels_; } application_domain_t domain() const { return domain_; } application_domain_t domain_; std::list* labels_; }; struct adding_term { ExpArithmetic::fun_t op; Expression*term; }; // Stores information for file declarations containing a file name and open mode // (VHDL-2008 6.4.2.5) class file_open_info_t { public: explicit file_open_info_t(ExpString*filename__, ExpName*kind__ = NULL) : kind_(kind__), filename_(filename__) { // By default files are opened in read-only mode if(!kind_) kind_ = new ExpName(perm_string::literal("read_mode")); } ~file_open_info_t() { delete kind_; delete filename_; } ExpName*kind() { return kind_; } ExpString*filename() { return filename_; } private: ExpName*kind_; ExpString*filename_; }; #endif /* IVL_parse_types_H */ iverilog-12_0/vhdlpp/parse_wrap.h000066400000000000000000000025031435245347300171600ustar00rootroot00000000000000#ifndef IVL_parse_wrap_H #define IVL_parse_wrap_H /* * Copyright (c) 2011-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. */ /* * This header wraps the parse.h header file that is generated from * the parse.y source file. This is used to include definitions that * are needed by the parse type, etc. */ # include # include "vhdlint.h" # include "vhdlreal.h" # include "architec.h" # include "expression.h" # include "sequential.h" # include "subprogram.h" # include "parse_types.h" class VType; # include "parse.h" #endif /* IVL_parse_wrap_H */ iverilog-12_0/vhdlpp/scope.cc000066400000000000000000000314721435245347300162730ustar00rootroot00000000000000/* * Copyright (c) 2011-2016 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "scope.h" # include "package.h" # include "subprogram.h" # include "entity.h" # include "std_funcs.h" # include "std_types.h" # include "compiler.h" # include # include # include # include # include # include # include using namespace std; static int scope_counter = 0; ScopeBase::ScopeBase(const ActiveScope&ref) : old_signals_(ref.old_signals_), new_signals_(ref.new_signals_), old_variables_(ref.old_variables_), new_variables_(ref.new_variables_), old_components_(ref.old_components_), new_components_(ref.new_components_), use_types_(ref.use_types_), cur_types_(ref.cur_types_), use_constants_(ref.use_constants_), cur_constants_(ref.cur_constants_), use_subprograms_(ref.use_subprograms_), cur_subprograms_(ref.cur_subprograms_), scopes_(ref.scopes_), use_enums_(ref.use_enums_), initializers_(ref.initializers_), finalizers_(ref.finalizers_), package_header_(ref.package_header_), name_(ref.name_) { } ScopeBase::~ScopeBase() { //freeing of member objects is performed by child classes } void ScopeBase::cleanup() { /* * A parent scope is destroyed only if all child scopes * were previously destroyed. There for we can delete all * objects that were defined in this scope, leaving * objects from the other scopes untouched. */ delete_all(new_signals_); delete_all(new_variables_); delete_all(new_components_); delete_all(cur_types_); delete_all(cur_constants_); for (map::iterator cur = cur_subprograms_.begin() ; cur != cur_subprograms_.end() ; ++cur) { delete_all(cur->second); } } ScopeBase*ScopeBase::find_scope(perm_string name) const { map::const_iterator it = scopes_.find(name); if(it != scopes_.end()) return it->second; return NULL; } const VType*ScopeBase::find_type(perm_string by_name) { map::const_iterator cur = cur_types_.find(by_name); if (cur == cur_types_.end()) { cur = use_types_.find(by_name); if (cur == use_types_.end()) return NULL; // nothing found } return cur->second; } bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const { typ = NULL; exp = NULL; map::const_iterator cur = cur_constants_.find(by_name); if (cur == cur_constants_.end()) { cur = use_constants_.find(by_name); if (cur == use_constants_.end()) return false; // nothing found } typ = cur->second->typ; exp = cur->second->val; return true; } Signal* ScopeBase::find_signal(perm_string by_name) const { map::const_iterator cur = new_signals_.find(by_name); if (cur == new_signals_.end()) { cur = old_signals_.find(by_name); if (cur == old_signals_.end()) return NULL; // nothing found } return cur->second; } Variable* ScopeBase::find_variable(perm_string by_name) const { map::const_iterator cur = new_variables_.find(by_name); if (cur == new_variables_.end()) { cur = old_variables_.find(by_name); if (cur == old_variables_.end()) return 0; // nothing found } return cur->second; } const InterfacePort* ScopeBase::find_param(perm_string) const { return NULL; } const InterfacePort* ScopeBase::find_param_all(perm_string by_name) const { for(map::const_iterator cur = use_subprograms_.begin(); cur != use_subprograms_.end(); ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { if(const InterfacePort*port = (*it)->find_param(by_name)) return port; } } for(map::const_iterator cur = cur_subprograms_.begin(); cur != cur_subprograms_.end(); ++cur) { const SubHeaderList& subp_list = cur->second; for(SubHeaderList::const_iterator it = subp_list.begin(); it != subp_list.end(); ++it) { if(const InterfacePort*port = (*it)->find_param(by_name)) return port; } } return NULL; } SubHeaderList ScopeBase::find_subprogram(perm_string name) const { map::const_iterator cur; cur = cur_subprograms_.find(name); if (cur != cur_subprograms_.end()) return cur->second; cur = use_subprograms_.find(name); if (cur != use_subprograms_.end()) return cur->second; return find_std_subprogram(name); } const VTypeEnum* ScopeBase::is_enum_name(perm_string name) const { for(list::const_iterator it = use_enums_.begin(); it != use_enums_.end(); ++it) { if((*it)->has_name(name)) return *it; } return find_std_enum_name(name); } /* * This method is only used by the ActiveScope derived class to import * definition from another scope. */ void ScopeBase::do_use_from(const ScopeBase*that) { for (map::const_iterator cur = that->old_components_.begin() ; cur != that->old_components_.end() ; ++ cur) { if (cur->second == 0) continue; old_components_[cur->first] = cur->second; } for (map::const_iterator cur = that->new_components_.begin() ; cur != that->new_components_.end() ; ++ cur) { if (cur->second == 0) continue; old_components_[cur->first] = cur->second; } for (map::const_iterator cur = that->cur_subprograms_.begin() ; cur != that->cur_subprograms_.end() ; ++ cur) { if (cur->second.empty()) continue; use_subprograms_[cur->first] = cur->second; } for (map::const_iterator cur = that->cur_types_.begin() ; cur != that->cur_types_.end() ; ++ cur) { if (cur->second == 0) continue; use_types_[cur->first] = cur->second; } for (map::const_iterator cur = that->cur_constants_.begin() ; cur != that->cur_constants_.end() ; ++ cur) { use_constants_[cur->first] = cur->second; } use_enums_ = that->use_enums_; } void ScopeBase::transfer_from(ScopeBase&ref, transfer_type_t what) { if(what & SIGNALS) { std::copy(ref.new_signals_.begin(), ref.new_signals_.end(), insert_iterator >( new_signals_, new_signals_.end()) ); ref.new_signals_.clear(); } if(what & VARIABLES) { std::copy(ref.new_variables_.begin(), ref.new_variables_.end(), insert_iterator >( new_variables_, new_variables_.end()) ); ref.new_variables_.clear(); } if(what & COMPONENTS) { std::copy(ref.new_components_.begin(), ref.new_components_.end(), insert_iterator >( new_components_, new_components_.end()) ); ref.new_components_.clear(); } } SubprogramHeader*ScopeBase::match_subprogram(perm_string name, const list*params) const { int req_param_count = params ? params->size() : 0; // Find all subprograms with matching name SubHeaderList l = find_std_subprogram(name); map::const_iterator cur; cur = use_subprograms_.find(name); if (cur != use_subprograms_.end()) copy(cur->second.begin(), cur->second.end(), front_insert_iterator(l)); cur = cur_subprograms_.find(name); if(cur != cur_subprograms_.end()) copy(cur->second.begin(), cur->second.end(), front_insert_iterator(l)); // Find the matching one for(SubHeaderList::iterator it = l.begin(); it != l.end(); ++it) { SubprogramHeader*subp = *it; if(req_param_count != subp->param_count()) continue; // Do not check the return type here, it might depend on the arguments if(params) { list::const_iterator p = params->begin(); bool ok = true; for(int i = 0; i < req_param_count; ++i) { const VType*param_type = subp->peek_param_type(i); if(*p && param_type && !param_type->type_match(*p)) { ok = false; break; } ++p; } if(!ok) continue; // check another function } // Yay, we have a match! return subp; } return NULL; } void ScopeBase::generate_name() { char buf[64]; // Generate a name for the scope snprintf(buf, sizeof(buf), "__scope_%d", scope_counter++); name_ = gen_strings.make(buf); } SubprogramHeader* ActiveScope::recall_subprogram(const SubprogramHeader*subp) const { list arg_types; SubprogramHeader*tmp; for(int i = 0; i < subp->param_count(); ++i) arg_types.push_back(subp->peek_param_type(i)); if ((tmp = match_subprogram(subp->name(), &arg_types))) { assert(!tmp->body()); return tmp; } if (package_header_) { tmp = package_header_->match_subprogram(subp->name(), &arg_types); assert(!tmp || !tmp->body()); return tmp; } return NULL; } bool ActiveScope::is_vector_name(perm_string name) const { if (find_signal(name)) return true; if (find_variable(name)) return true; const VType*dummy_type; Expression*dummy_exp; if (find_constant(name, dummy_type, dummy_exp)) return true; if (context_entity_ && context_entity_->find_port(name)) return true; return false; } ComponentBase* Scope::find_component(perm_string by_name) { map::const_iterator cur = new_components_.find(by_name); if (cur == new_components_.end()) { cur = old_components_.find(by_name); if (cur == old_components_.end()) return 0; else return cur->second; } else return cur->second; } ActiveScope::ActiveScope(const ActiveScope*par) : ScopeBase(*par), context_entity_(par->context_entity_) { generate_name(); // Move all the objects available in higher level scopes to use*/old* maps. // This way we can store the new items in now empty cur*/new* maps. merge(par->old_signals_.begin(), par->old_signals_.end(), par->new_signals_.begin(), par->new_signals_.end(), insert_iterator >( old_signals_, old_signals_.end()) ); merge(par->old_variables_.begin(), par->old_variables_.end(), par->new_variables_.begin(), par->new_variables_.end(), insert_iterator >( old_variables_, old_variables_.end()) ); merge(par->old_components_.begin(), par->old_components_.end(), par->new_components_.begin(), par->new_components_.end(), insert_iterator >( old_components_, old_components_.end()) ); merge(par->use_types_.begin(), par->use_types_.end(), par->cur_types_.begin(), par->cur_types_.end(), insert_iterator >( use_types_, use_types_.end()) ); merge(par->use_subprograms_.begin(), par->use_subprograms_.end(), par->cur_subprograms_.begin(), par->cur_subprograms_.end(), insert_iterator >( use_subprograms_, use_subprograms_.end()) ); } iverilog-12_0/vhdlpp/scope.h000066400000000000000000000237251435245347300161370ustar00rootroot00000000000000#ifndef IVL_scope_H #define IVL_scope_H /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 # include # include "StringHeap.h" # include "entity.h" # include "expression.h" # include "vsignal.h" class ActiveScope; class Architecture; class ComponentBase; class Package; class SubprogramHeader; class VType; class SequentialStmt; typedef std::list SubHeaderList; template struct delete_object{ void operator()(T* item) { delete item; } }; template struct delete_pair_second{ void operator()(std::pair item){ delete item.second; } }; class ScopeBase { public: ScopeBase() : package_header_(0) { } explicit ScopeBase(const ActiveScope&ref); virtual ~ScopeBase() =0; ScopeBase* find_scope(perm_string name) const; const VType* find_type(perm_string by_name); virtual bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp) const; Signal* find_signal(perm_string by_name) const; virtual Variable* find_variable(perm_string by_name) const; virtual const InterfacePort* find_param(perm_string by_name) const; const InterfacePort* find_param_all(perm_string by_name) const; SubHeaderList find_subprogram(perm_string by_name) const; // Checks if a string is one of possible enum values. If so, the enum // type is returned, otherwise NULL. const VTypeEnum* is_enum_name(perm_string name) const; virtual bool is_subprogram() const { return false; } // Moves signals, variables and components from another scope to // this one. After the transfer new_* maps are cleared in the source scope. enum transfer_type_t { SIGNALS = 1, VARIABLES = 2, COMPONENTS = 4, ALL = 0xffff }; void transfer_from(ScopeBase&ref, transfer_type_t what = ALL); inline void bind_subprogram(perm_string name, SubprogramHeader*obj) { std::map::iterator it; if((it = use_subprograms_.find(name)) != use_subprograms_.end() ) it->second.remove(obj); cur_subprograms_[name].push_back(obj); } // Adds a statement to implicit initializers list // (emitted in a 'initial block). void add_initializer(SequentialStmt* s) { initializers_.push_back(s); } // Adds a statement to implicit finalizers list // (emitted in a 'final' block). void add_finalizer(SequentialStmt* s) { finalizers_.push_back(s); } void dump_scope(std::ostream&out) const; // Looks for a subprogram with specified name and parameter types. SubprogramHeader*match_subprogram(perm_string name, const std::list*params) const; perm_string peek_name() const { return name_; } void set_package_header(Package*pkg) { assert(package_header_ == 0); package_header_ = pkg; } protected: void cleanup(); //containers' cleaning helper functions template void delete_all(std::list& c) { for_each(c.begin(), c.end(), ::delete_object()); } template void delete_all(std::map& c) { for_each(c.begin(), c.end(), ::delete_pair_second()); } // The new_*_ maps below are managed only by the ActiveScope // derived class. When any scope is constructed from the // ActiveScope, the new_*_ and old_*_ maps are merged and // installed into the old_*_ maps. Thus, all other derived // classes should only use the old_*_ maps. // Signal declarations... std::map old_signals_; //previous scopes std::map new_signals_; //current scope // Variable declarations... std::map old_variables_; //previous scopes std::map new_variables_; //current scope // Component declarations... std::map old_components_; //previous scopes std::map new_components_; //current scope // Type declarations... std::map use_types_; //imported types std::map cur_types_; //current types // Constant declarations... struct const_t { ~const_t() {delete val;} const_t(const VType*t, Expression* v) : typ(t), val(v) {}; const VType*typ; Expression*val; }; std::map use_constants_; //imported constants std::map cur_constants_; //current constants std::map use_subprograms_; //imported std::map cur_subprograms_; //current std::map scopes_; std::list use_enums_; // List of statements that should be emitted in a 'initial' block std::list initializers_; // List of statements that should be emitted in a 'final' block std::list finalizers_; void do_use_from(const ScopeBase*that); // If this is a package body, then there is a Package header // already declared. Package*package_header_; // Generates an unique name for the scope void generate_name(); private: perm_string name_; }; class Scope : public ScopeBase { public: explicit Scope(const ActiveScope&ref) : ScopeBase(ref) {} virtual ~Scope() {} ComponentBase* find_component(perm_string by_name); protected: // Helper method for emitting signals in the scope. int emit_signals(std::ostream&out, Entity*ent, ScopeBase*scope); int emit_variables(std::ostream&out, Entity*ent, ScopeBase*scope); }; /* * The active_scope object accumulates declarations for the scope that * is in the process of being parsed. When the declarations are over, * they are transferred over to the specific scope. The ActiveScope is * used by the parser to build up scopes. */ class ActiveScope : public ScopeBase { public: ActiveScope() : context_entity_(0) { } explicit ActiveScope(const ActiveScope*par); ~ActiveScope() { } // Pull items from "that" scope into "this" scope as is // defined by a "use" directive. The parser uses this method // to implement the "use ::*" directive. void use_from(const Scope*that) { do_use_from(that); } // This function returns true if the name is a vectorable // name. The parser uses this to distinguish between function // calls and array index operations. bool is_vector_name(perm_string name) const; // Locate the subprogram by name. The subprogram body uses // this to locate the subprogram declaration. Note that the // subprogram may be in a package header. SubprogramHeader* recall_subprogram(const SubprogramHeader*subp) const; /* All bind_name function check if the given name was present * in previous scopes. If it is found, it is erased (but the pointer * is not freed), in order to implement name shadowing. The pointer * be freed only in the scope where the object was defined. This is * done in ScopeBase::cleanup() function .*/ void bind_name(perm_string name, Signal*obj) { std::map::iterator it; if((it = old_signals_.find(name)) != old_signals_.end() ) old_signals_.erase(it); new_signals_[name] = obj; } void bind_name(perm_string name, Variable*obj) { std::map::iterator it; if((it = old_variables_.find(name)) != old_variables_.end() ) old_variables_.erase(it); new_variables_[name] = obj; } void bind_name(perm_string name, ComponentBase*obj) { std::map::iterator it; if((it = old_components_.find(name)) != old_components_.end() ) old_components_.erase(it); new_components_[name] = obj; } void bind_name(perm_string name, const VType* t) { std::map::iterator it; if((it = use_types_.find(name)) != use_types_.end() ) use_types_.erase(it); cur_types_[name] = t; } void bind_scope(perm_string name, ScopeBase*scope) { assert(scopes_.find(name) == scopes_.end()); scopes_[name] = scope; } inline void use_enum(const VTypeEnum* t) { use_enums_.push_back(t); } inline void use_name(perm_string name, const VType* t) { use_types_[name] = t; } void bind_name(perm_string name, const VType*obj, Expression*val) { std::map::iterator it; if((it = use_constants_.find(name)) != use_constants_.end() ) use_constants_.erase(it); cur_constants_[name] = new const_t(obj, val); } void bind(Entity*ent) { context_entity_ = ent; } void destroy_global_scope() { cleanup(); } // Keep track of incomplete types until their proper // definition shows up. std::map incomplete_types; private: Entity*context_entity_; }; #endif /* IVL_scope_H */ iverilog-12_0/vhdlpp/sequential.cc000066400000000000000000000155721435245347300173370ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "sequential.h" # include "expression.h" # include using namespace std; template inline static void visit_stmt_list(std::list& stmts, SeqStmtVisitor& func) { for(typename std::list::iterator it = stmts.begin(); it != stmts.end(); ++it) { (*it)->visit(func); } } SequentialStmt::SequentialStmt() { } SequentialStmt::~SequentialStmt() { } IfSequential::IfSequential(Expression*cond, std::list*tr, std::list*el, std::list*fa) { cond_ = cond; if (tr) if_.splice(if_.end(), *tr); if (el) elsif_.splice(elsif_.end(), *el); if (fa) else_.splice(else_.end(), *fa); } IfSequential::~IfSequential() { delete cond_; while (!if_.empty()) { SequentialStmt*cur = if_.front(); if_.pop_front(); delete cur; } while (!elsif_.empty()) { IfSequential::Elsif*cur = elsif_.front(); elsif_.pop_front(); delete cur; } while (!else_.empty()) { SequentialStmt*cur = else_.front(); else_.pop_front(); delete cur; } } void IfSequential::extract_true(std::list&that) { while (! if_.empty()) { that.push_back(if_.front()); if_.pop_front(); } } void IfSequential::extract_false(std::list&that) { while (! else_.empty()) { that.push_back(else_.front()); else_.pop_front(); } } void IfSequential::visit(SeqStmtVisitor& func) { visit_stmt_list(if_, func); visit_stmt_list(elsif_, func); visit_stmt_list(else_, func); func(this); } IfSequential::Elsif::Elsif(Expression*cond, std::list*tr) : cond_(cond) { if (tr) if_.splice(if_.end(), *tr); } IfSequential::Elsif::~Elsif() { delete cond_; while (!if_.empty()) { SequentialStmt*cur = if_.front(); if_.pop_front(); delete cur; } } void IfSequential::Elsif::visit(SeqStmtVisitor& func) { visit_stmt_list(if_, func); } SignalSeqAssignment::SignalSeqAssignment(Expression*sig, std::list*wav) { lval_ = sig; if (wav) waveform_.splice(waveform_.end(), *wav); } SignalSeqAssignment::~SignalSeqAssignment() { delete lval_; } CaseSeqStmt::CaseSeqStmt(Expression*cond, list* ap) : cond_(cond) { if (ap) alt_.splice(alt_.end(), *ap); } CaseSeqStmt::~CaseSeqStmt() { delete cond_; while(!alt_.empty()) { CaseSeqStmt::CaseStmtAlternative* cur = alt_.front(); alt_.pop_front(); delete cur; } } void CaseSeqStmt::visit(SeqStmtVisitor& func) { visit_stmt_list(alt_, func); func(this); } CaseSeqStmt::CaseStmtAlternative::CaseStmtAlternative(std::list*exp, list*stmts) : exp_(exp) { if (stmts) stmts_.splice(stmts_.end(), *stmts); } CaseSeqStmt::CaseStmtAlternative::~CaseStmtAlternative() { delete exp_; while(!stmts_.empty()) { SequentialStmt* cur = stmts_.front(); stmts_.pop_front(); delete cur; } } void CaseSeqStmt::CaseStmtAlternative::visit(SeqStmtVisitor& func) { visit_stmt_list(stmts_, func); } ProcedureCall::ProcedureCall(perm_string name) : name_(name), param_list_(NULL), def_(NULL) { } ProcedureCall::ProcedureCall(perm_string name, std::list* param_list) : name_(name), param_list_(param_list), def_(NULL) { } ProcedureCall::ProcedureCall(perm_string name, std::list* param_list) : name_(name), def_(NULL) { param_list_ = new std::list; for(std::list::const_iterator it = param_list->begin(); it != param_list->end(); ++it) { param_list_->push_back(new named_expr_t(empty_perm_string, *it)); } } ProcedureCall::~ProcedureCall() { if(!param_list_) return; while(!param_list_->empty()) { named_expr_t* cur = param_list_->front(); param_list_->pop_front(); delete cur; } delete param_list_; } ReturnStmt::ReturnStmt(Expression*val) : val_(val) { } ReturnStmt::~ReturnStmt() { delete val_; } void ReturnStmt::cast_to(const VType*type) { assert(val_); val_ = new ExpCast(val_, type); } LoopStatement::LoopStatement(perm_string name, list* stmts) : name_(name) { if (stmts) stmts_.splice(stmts_.end(), *stmts); } LoopStatement::~LoopStatement() { while(!stmts_.empty()) { SequentialStmt* cur = stmts_.front(); stmts_.pop_front(); delete cur; } } void LoopStatement::visit(SeqStmtVisitor& func) { visit_stmt_list(stmts_, func); func(this); } ForLoopStatement::ForLoopStatement(perm_string scope_name, perm_string it, ExpRange* range, list* stmts) : LoopStatement(scope_name, stmts), it_(it), range_(range) { } ForLoopStatement::~ForLoopStatement() { delete range_; } VariableSeqAssignment::VariableSeqAssignment(Expression*lval, Expression*rval) : lval_(lval), rval_(rval) { } VariableSeqAssignment::~VariableSeqAssignment() { delete lval_; delete rval_; } WhileLoopStatement::WhileLoopStatement(perm_string lname, Expression* cond, list* stmts) : LoopStatement(lname, stmts), cond_(cond) { } WhileLoopStatement::~WhileLoopStatement() { delete cond_; } BasicLoopStatement::BasicLoopStatement(perm_string lname, list* stmts) : LoopStatement(lname, stmts) { } BasicLoopStatement::~BasicLoopStatement() { } ReportStmt::ReportStmt(Expression*msg, severity_t sev) : msg_(msg), severity_(sev) { if(sev == ReportStmt::UNSPECIFIED) severity_ = ReportStmt::NOTE; } AssertStmt::AssertStmt(Expression*condition, Expression*msg, ReportStmt::severity_t sev) : ReportStmt(msg, sev), cond_(condition) { if(msg == NULL) msg_ = new ExpString(default_msg_); if(sev == ReportStmt::UNSPECIFIED) severity_ = ReportStmt::ERROR; } const char*AssertStmt::default_msg_ = "Assertion violation."; WaitForStmt::WaitForStmt(Expression*delay) : delay_(delay) { } WaitStmt::WaitStmt(wait_type_t typ, Expression*expr) : type_(typ), expr_(expr) { } iverilog-12_0/vhdlpp/sequential.h000066400000000000000000000256471435245347300172050ustar00rootroot00000000000000#ifndef IVL_sequential_H #define IVL_sequential_H /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "LineInfo.h" # include "parse_types.h" # include class ScopeBase; class Entity; class Expression; class SequentialStmt; struct SeqStmtVisitor { virtual ~SeqStmtVisitor() {}; virtual void operator() (SequentialStmt*s) = 0; }; class SequentialStmt : public LineInfo { public: SequentialStmt(); virtual ~SequentialStmt() =0; public: virtual int elaborate(Entity*ent, ScopeBase*scope); virtual int emit(std::ostream&out, Entity*entity, ScopeBase*scope); virtual void dump(std::ostream&out, int indent) const; virtual void write_to_stream(std::ostream&fd); // Recursively visits a tree of sequential statements. virtual void visit(SeqStmtVisitor& func) { func(this); } }; /* * The LoopStatement is an abstract base class for the various loop * statements. */ class LoopStatement : public SequentialStmt { public: LoopStatement(perm_string block_name, std::list*); virtual ~LoopStatement(); inline perm_string loop_name() const { return name_; } void dump(std::ostream&out, int indent) const; void visit(SeqStmtVisitor& func); protected: int elaborate_substatements(Entity*ent, ScopeBase*scope); int emit_substatements(std::ostream&out, Entity*ent, ScopeBase*scope); void write_to_stream_substatements(std::ostream&fd); private: perm_string name_; std::list stmts_; }; class IfSequential : public SequentialStmt { public: class Elsif : public LineInfo { public: Elsif(Expression*cond, std::list*tr); ~Elsif(); int elaborate(Entity*entity, ScopeBase*scope); int condition_emit(std::ostream&out, Entity*entity, ScopeBase*scope); int statement_emit(std::ostream&out, Entity*entity, ScopeBase*scope); void condition_write_to_stream(std::ostream&fd); void statement_write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; void visit(SeqStmtVisitor& func); private: Expression*cond_; std::listif_; private: // not implemented Elsif(const Elsif&); Elsif& operator =(const Elsif&); }; public: IfSequential(Expression*cond, std::list*tr, std::list*elsif, std::list*fa); ~IfSequential(); public: int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; void visit(SeqStmtVisitor& func); const Expression*peek_condition() const { return cond_; } size_t false_size() const { return else_.size(); } // These method extract (and remove) the sub-statements from // the true or false clause. void extract_true(std::list&that); void extract_false(std::list&that); private: Expression*cond_; std::list if_; std::list elsif_; std::list else_; }; class ReturnStmt : public SequentialStmt { public: explicit ReturnStmt(Expression*val); ~ReturnStmt(); public: int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; const Expression*peek_expr() const { return val_; }; void cast_to(const VType*type); private: Expression*val_; }; class SignalSeqAssignment : public SequentialStmt { public: SignalSeqAssignment(Expression*sig, std::list*wav); ~SignalSeqAssignment(); public: int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; private: Expression*lval_; std::list waveform_; }; class CaseSeqStmt : public SequentialStmt { public: class CaseStmtAlternative : public LineInfo { public: CaseStmtAlternative(std::list*exp, std::list*stmts); ~CaseStmtAlternative(); void dump(std::ostream& out, int indent) const; int elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype); int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void visit(SeqStmtVisitor& func); private: std::list*exp_; std::list stmts_; private: // not implemented CaseStmtAlternative(const CaseStmtAlternative&); CaseStmtAlternative& operator =(const CaseStmtAlternative&); }; public: CaseSeqStmt(Expression*cond, std::list*sp); ~CaseSeqStmt(); public: void dump(std::ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void visit(SeqStmtVisitor& func); private: Expression* cond_; std::list alt_; }; class ProcedureCall : public SequentialStmt { public: explicit ProcedureCall(perm_string name); ProcedureCall(perm_string name, std::list* param_list); ProcedureCall(perm_string name, std::list* param_list); ~ProcedureCall(); int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void dump(std::ostream&out, int indent) const; private: perm_string name_; std::list* param_list_; SubprogramHeader*def_; }; class VariableSeqAssignment : public SequentialStmt { public: VariableSeqAssignment(Expression*sig, Expression*rval); ~VariableSeqAssignment(); public: int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; private: Expression*lval_; Expression*rval_; }; class WhileLoopStatement : public LoopStatement { public: WhileLoopStatement(perm_string loop_name, Expression*, std::list*); ~WhileLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*ent, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; private: Expression* cond_; }; class ForLoopStatement : public LoopStatement { public: ForLoopStatement(perm_string loop_name, perm_string index, ExpRange*, std::list*); ~ForLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*ent, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; private: // Emits for-loop which direction is determined at run-time. // It is used for 'range & 'reverse_range attributes. int emit_runtime_(std::ostream&out, Entity*ent, ScopeBase*scope); perm_string it_; ExpRange* range_; }; class BasicLoopStatement : public LoopStatement { public: BasicLoopStatement(perm_string lname, std::list*); ~BasicLoopStatement(); int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*ent, ScopeBase*scope); void write_to_stream(std::ostream&fd); void dump(std::ostream&out, int indent) const; }; class ReportStmt : public SequentialStmt { public: typedef enum { UNSPECIFIED, NOTE, WARNING, ERROR, FAILURE } severity_t; ReportStmt(Expression*message, severity_t severity); virtual ~ReportStmt() {} void dump(std::ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); inline Expression*message() const { return msg_; } inline severity_t severity() const { return severity_; } protected: void dump_sev_msg(std::ostream&out, int indent) const; Expression*msg_; severity_t severity_; }; class AssertStmt : public ReportStmt { public: AssertStmt(Expression*condition, Expression*message, ReportStmt::severity_t severity = ReportStmt::ERROR); void dump(std::ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); private: Expression*cond_; // Message displayed when there is no report assigned. static const char*default_msg_; }; class WaitForStmt : public SequentialStmt { public: explicit WaitForStmt(Expression*delay); void dump(std::ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); private: Expression*delay_; }; class WaitStmt : public SequentialStmt { public: typedef enum { ON, UNTIL, FINAL } wait_type_t; WaitStmt(wait_type_t typ, Expression*expression); void dump(std::ostream&out, int indent) const; int elaborate(Entity*ent, ScopeBase*scope); int emit(std::ostream&out, Entity*entity, ScopeBase*scope); void write_to_stream(std::ostream&fd); inline wait_type_t type() const { return type_; } private: wait_type_t type_; Expression*expr_; // Sensitivity list for 'wait until' statement std::set sens_list_; }; #endif /* IVL_sequential_H */ iverilog-12_0/vhdlpp/sequential_debug.cc000066400000000000000000000155661435245347300205100ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "sequential.h" # include "expression.h" # include # include # include using namespace std; void SequentialStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "SequentialStmt[" << typeid(*this).name() << "]" << " at file=" << get_fileline() << endl; } void IfSequential::dump(ostream&out, int indent) const { out << setw(indent) << "" << "IfSequential at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "Condition:" << endl; cond_->dump(out, indent+4); out << setw(indent+3) << "" << "TRUE clause (" << if_.size() << "):" << endl; for (list::const_iterator cur = if_.begin() ; cur != if_.end() ; ++cur) (*cur)->dump(out, indent+4); for (list::const_iterator cur = elsif_.begin() ; cur != elsif_.end() ; ++cur) (*cur)->dump(out, indent); out << setw(indent+3) << "" << "FALSE clause (" << else_.size() << "):" << endl; for (list::const_iterator cur = else_.begin() ; cur != else_.end() ; ++cur) (*cur)->dump(out, indent+4); } void IfSequential::Elsif::dump(ostream&out, int indent) const { out << setw(indent+3) << "" << "Elsif Condition at " << get_fileline() << ":" << endl; cond_->dump(out, indent+4); out << setw(indent+3) << "" << "ELSIF TRUE clause (" << if_.size() << "):" << endl; for (list::const_iterator cur = if_.begin() ; cur != if_.end() ; ++cur) (*cur)->dump(out, indent+4); } void ReturnStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ReturnStmt at file=" << get_fileline() << endl; if (val_) val_->dump(out, indent+4); else out << setw(indent+4) << "" << "()" << endl; } void SignalSeqAssignment::dump(ostream&out, int indent) const { out << setw(indent) << "" << "SignalSeqAssignment at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "l-value:" << endl; lval_->dump(out, indent+4); out << setw(indent+3) << "" << "r-values (" << waveform_.size() << "):" << endl; for (list::const_iterator cur = waveform_.begin() ; cur != waveform_.end() ; ++cur) (*cur)->dump(out, indent+4); } void CaseSeqStmt::dump(ostream& out, int indent) const { out << setw(indent) << "" << "CaseSeqStmt at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "Case: " << endl; cond_->dump(out, indent+4); for (list::const_iterator cur = alt_.begin() ; cur != alt_.end() ; ++cur) (*cur)->dump(out, indent+4); } void CaseSeqStmt::CaseStmtAlternative::dump(ostream& out, int indent) const { out << setw(indent) << "" << "CaseStmtAlternative at file=" << get_fileline() << endl; out << setw(indent) << "" << "when "; if (exp_) for (list::iterator it = exp_->begin(); it != exp_->end(); ++it) { (*it)->dump(out, 0); } else out << "others" << endl; for (list::const_iterator cur = stmts_.begin() ; cur != stmts_.end(); ++cur) (*cur)->dump(out, indent+1); } void ProcedureCall::dump(ostream& out, int indent) const { out << setw(indent) << "" << "ProcedureCall at file=" << get_fileline() << endl; out << setw(indent+2) << "" << name_ << "("; for(list::const_iterator it = param_list_->begin(); it != param_list_->end(); ++it) (*it)->dump(out, indent); out << ")" << endl; } void LoopStatement::dump(ostream&out, int indent) const { for(list::const_iterator it = stmts_.begin(); it != stmts_.end(); ++it) (*it)->dump(out, indent); } void ForLoopStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ForLoopStatement at file=" << get_fileline() << endl; out << setw(indent) << "" << it_ << " in "; range_->dump(out, indent); LoopStatement::dump(out, indent+2); } void VariableSeqAssignment::dump(ostream&out, int indent) const { out << setw(indent) << "" << "VariableSeqAssignment at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "l-value:" << endl; lval_->dump(out, indent+4); out << setw(indent+3) << "" << "r-value:" << endl; rval_->dump(out, indent+4); } void WhileLoopStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "WhileLoopStatement at file=" << get_fileline() << endl; out << setw(indent) << "" << "condition: "; cond_->dump(out, indent); LoopStatement::dump(out, indent+2); } void BasicLoopStatement::dump(ostream&out, int indent) const { out << setw(indent) << "" << "BasicLoopStatement at file=" << get_fileline() << endl; LoopStatement::dump(out, indent+2); } void ReportStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "ReportStmt at file=" << get_fileline() << endl; dump_sev_msg(out, indent+3); } void ReportStmt::dump_sev_msg(ostream&out, int indent) const { out << setw(indent) << "" << "severity: " << severity_ << endl; if(msg_) { out << setw(indent) << "" << "message: "; msg_->dump(out, indent); } } void AssertStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "AssertStmt at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "condition: "; dump_sev_msg(out, indent+3); } void WaitForStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "WaitForStmt at file=" << get_fileline() << endl; out << setw(indent+3) << "" << "delay: "; delay_->dump(out, indent+3); } void WaitStmt::dump(ostream&out, int indent) const { out << setw(indent) << "" << "WaitStmt at file=" << get_fileline() << endl; out << setw(indent+3) << "type = "; switch(type_) { case ON: out << "ON" << endl; break; case UNTIL: out << "UNTIL" << endl; break; case FINAL: out << "FINAL" << endl; break; } if(type_ != FINAL) { out << setw(indent+3) << "" << "expression: "; expr_->dump(out, indent+3); } } iverilog-12_0/vhdlpp/sequential_elaborate.cc000066400000000000000000000202151435245347300213430ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "sequential.h" # include "expression.h" # include "scope.h" # include "library.h" # include "subprogram.h" # include "std_types.h" using namespace std; int SequentialStmt::elaborate(Entity*, ScopeBase*) { return 0; } int LoopStatement::elaborate_substatements(Entity*ent, ScopeBase*scope) { int errors = 0; for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { errors += (*cur)->elaborate(ent, scope); } return errors; } int CaseSeqStmt::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; const VType*ctype = cond_->probe_type(ent, scope); errors += cond_->elaborate_expr(ent, scope, ctype); for (list::iterator cur = alt_.begin() ; cur != alt_.end() ; ++cur) { CaseStmtAlternative*curp = *cur; errors += curp->elaborate_expr(ent, scope, ctype); errors += curp->elaborate(ent, scope); } return errors; } /* * This method elaborates the case expression for the alternative. The * ltype is the probed type for the main case condition. The * expression needs to elaborate itself in that context. */ int CaseSeqStmt::CaseStmtAlternative::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype) { int errors = 0; if (exp_) { for (list::iterator it = exp_->begin(); it != exp_->end(); ++it) { errors += (*it)->elaborate_expr(ent, scope, ltype); } } return errors; } int CaseSeqStmt::CaseStmtAlternative::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { SequentialStmt*curp = *cur; errors += curp->elaborate(ent, scope); } return errors; } int ForLoopStatement::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; errors += elaborate_substatements(ent, scope); return errors; } int IfSequential::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; errors += cond_->elaborate_expr(ent, scope, &type_BOOLEAN); for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) { errors += (*cur)->elaborate(ent, scope); } for (list::iterator cur = elsif_.begin() ; cur != elsif_.end() ; ++cur) { errors += (*cur)->elaborate(ent, scope); } for (list::iterator cur = else_.begin() ; cur != else_.end() ; ++cur) { errors += (*cur)->elaborate(ent, scope); } return errors; } int IfSequential::Elsif::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; errors += cond_->elaborate_expr(ent, scope, &type_BOOLEAN); for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) { errors += (*cur)->elaborate(ent, scope); } return errors; } int ReturnStmt::elaborate(Entity*ent, ScopeBase*scope) { const VType*ltype = NULL; // Try to determine the expression type by // looking up the function return type. const SubprogramBody*subp = dynamic_cast(scope); if(subp) { if(const SubprogramHeader*header = subp->header()) { ltype = header->peek_return_type(); } } return val_->elaborate_expr(ent, scope, ltype); } int SignalSeqAssignment::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; // Elaborate the l-value expression. errors += lval_->elaborate_lval(ent, scope, true); // The elaborate_lval should have resolved the type of the // l-value expression. We'll use that type to elaborate the // r-value. const VType*lval_type = lval_->peek_type(); if (lval_type == 0) { if (errors == 0) errors += 1; return errors; } // Elaborate the r-value expressions. for (list::iterator cur = waveform_.begin() ; cur != waveform_.end() ; ++cur) { errors += (*cur)->elaborate_expr(ent, scope, lval_type); } return errors; } int ProcedureCall::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; assert(!def_); // do not elaborate twice // Create a list of argument types to find a matching subprogram list arg_types; if(param_list_) { for(list::iterator it = param_list_->begin(); it != param_list_->end(); ++it) { named_expr_t* e = *it; arg_types.push_back(e->expr()->probe_type(ent, scope)); } } def_ = scope->match_subprogram(name_, &arg_types); if(!def_) def_ = library_match_subprogram(name_, &arg_types); if(!def_) { cerr << get_fileline() << ": error: could not find procedure "; emit_subprogram_sig(cerr, name_, arg_types); cerr << endl; return 1; } // Elaborate arguments if(param_list_) { size_t idx = 0; for(list::iterator cur = param_list_->begin() ; cur != param_list_->end() ; ++cur) { errors += def_->elaborate_argument((*cur)->expr(), idx, ent, scope); ++idx; } } return errors; } int VariableSeqAssignment::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; // Elaborate the l-value expression. errors += lval_->elaborate_lval(ent, scope, true); // The elaborate_lval should have resolved the type of the // l-value expression. We'll use that type to elaborate the // r-value. const VType*lval_type = lval_->peek_type(); if (lval_type == 0) { if (errors == 0) errors += 1; return errors; } // Elaborate the r-value expression. errors += rval_->elaborate_expr(ent, scope, lval_type); return errors; } int WhileLoopStatement::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; errors += elaborate_substatements(ent, scope); errors += cond_->elaborate_expr(ent, scope, cond_->probe_type(ent, scope)); return errors; } int BasicLoopStatement::elaborate(Entity*ent, ScopeBase*scope) { return elaborate_substatements(ent, scope); } int ReportStmt::elaborate(Entity*ent, ScopeBase*scope) { return msg_->elaborate_expr(ent, scope, &primitive_STRING); } int AssertStmt::elaborate(Entity*ent, ScopeBase*scope) { int errors = 0; errors += ReportStmt::elaborate(ent, scope); errors += cond_->elaborate_expr(ent, scope, cond_->probe_type(ent, scope)); return errors; } int WaitForStmt::elaborate(Entity*ent, ScopeBase*scope) { return delay_->elaborate_expr(ent, scope, &primitive_TIME); } int WaitStmt::elaborate(Entity*ent, ScopeBase*scope) { if(type_ == UNTIL) { struct fill_sens_list_t : public ExprVisitor { explicit fill_sens_list_t(set& sig_list) : sig_list_(sig_list) {}; void operator() (Expression*s) { if(ExpName*name = dynamic_cast(s)) sig_list_.insert(name); } private: set& sig_list_; } fill_sens_list(sens_list_); // Fill the sensitivity list expr_->visit(fill_sens_list); } else if(type_ == FINAL) { return 0; // nothing to be elaborated } return expr_->elaborate_expr(ent, scope, 0); } iverilog-12_0/vhdlpp/sequential_emit.cc000066400000000000000000000417541435245347300203560ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2015 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "sequential.h" # include "expression.h" # include "architec.h" # include "package.h" # include "compiler.h" # include "subprogram.h" # include "std_types.h" # include # include # include # include # include using namespace std; int SequentialStmt::emit(ostream&out, Entity*, ScopeBase*) { out << " // " << get_fileline() << ": internal error: " << "I don't know how to emit this sequential statement! " << "type=" << typeid(*this).name() << endl; return 1; } void SequentialStmt::write_to_stream(std::ostream&fd) { fd << " // " << get_fileline() << ": internal error: " << "I don't know how to write_to_stream this sequential statement! " << "type=" << typeid(*this).name() << endl; } int IfSequential::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "if ("; errors += cond_->emit(out, ent, scope); out << ") begin" << endl; for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) errors += (*cur)->emit(out, ent, scope); for (list::iterator cur = elsif_.begin() ; cur != elsif_.end() ; ++cur) { out << "end else if ("; errors += (*cur)->condition_emit(out, ent, scope); out << ") begin" << endl; errors += (*cur)->statement_emit(out, ent, scope); } if (! else_.empty()) { out << "end else begin" << endl; for (list::iterator cur = else_.begin() ; cur != else_.end() ; ++cur) errors += (*cur)->emit(out, ent, scope); } out << "end" << endl; return errors; } void IfSequential::write_to_stream(std::ostream&fd) { fd << "if "; cond_->write_to_stream(fd); fd << " then" << endl; for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) (*cur)->write_to_stream(fd); for (list::iterator cur = elsif_.begin() ; cur != elsif_.end() ; ++cur) { fd << "elsif "; (*cur)->condition_write_to_stream(fd); fd << " " << endl; (*cur)->statement_write_to_stream(fd); } if (! else_.empty()) { fd << " else " << endl; for (list::iterator cur = else_.begin() ; cur != else_.end() ; ++cur) (*cur)->write_to_stream(fd); } fd << "end if;" << endl; } int IfSequential::Elsif::condition_emit(ostream&out, Entity*ent, ScopeBase*scope) { return cond_->emit(out, ent, scope); } int IfSequential::Elsif::statement_emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) errors += (*cur)->emit(out, ent, scope); return errors; } void IfSequential::Elsif::condition_write_to_stream(ostream&fd) { cond_->write_to_stream(fd); } void IfSequential::Elsif::statement_write_to_stream(ostream&fd) { for (list::iterator cur = if_.begin() ; cur != if_.end() ; ++cur) (*cur)->write_to_stream(fd); } int ReturnStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "return "; errors += val_->emit(out, ent, scope); out << ";" << endl; return errors; } void ReturnStmt::write_to_stream(ostream&fd) { fd << "return "; val_->write_to_stream(fd); fd << ";" << endl; } int SignalSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; errors += lval_->emit(out, ent, scope); if (waveform_.size() != 1) { out << "/* Confusing waveform? */;" << endl; errors += 1; } else { Expression*tmp = waveform_.front(); out << " <= "; errors += tmp->emit(out, ent, scope); out << ";" << endl; } return errors; } void SignalSeqAssignment::write_to_stream(ostream&fd) { lval_->write_to_stream(fd); if (waveform_.size() != 1) { fd << "-- Confusing waveform?" << endl; } else { Expression*tmp = waveform_.front(); fd << " <= "; tmp->write_to_stream(fd); fd << ";" << endl; } } int VariableSeqAssignment::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; errors += lval_->emit(out, ent, scope); out << " = "; errors += rval_->emit(out, ent, scope); out << ";" << endl; return errors; } void VariableSeqAssignment::write_to_stream(ostream&fd) { lval_->write_to_stream(fd); fd << " := "; rval_->write_to_stream(fd); fd << ";" << endl; } int ProcedureCall::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; vectorargv; if(!def_) { cerr << get_fileline() << ": error: unknown procedure: " << name_ << endl; return 1; } // Convert the parameter list to vector if(param_list_) { argv.reserve(param_list_->size()); for(std::list::iterator it = param_list_->begin(); it != param_list_->end(); ++it) argv.push_back((*it)->expr()); } def_->emit_full_name(argv, out, ent, scope); out << " ("; if(param_list_) errors += def_->emit_args(argv, out, ent, scope); out << ");" << endl; return errors; } int LoopStatement::emit_substatements(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { SequentialStmt*tmp = *cur; errors += tmp->emit(out, ent, scope); } return errors; } void LoopStatement::write_to_stream_substatements(ostream&fd) { for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { SequentialStmt*tmp = *cur; tmp->write_to_stream(fd); } } int CaseSeqStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "case ("; errors += cond_->emit(out, ent, scope); out << ")" << endl; for (list::iterator cur = alt_.begin() ; cur != alt_.end() ; ++cur) { CaseStmtAlternative*curp = *cur; errors += curp ->emit(out, ent, scope); } out << "endcase" << endl; return errors; } void CaseSeqStmt::write_to_stream(ostream&fd) { fd << "case "; cond_->write_to_stream(fd); fd << " is" << endl; for (list::iterator cur = alt_.begin() ; cur != alt_.end() ; ++cur) { CaseStmtAlternative*curp = *cur; curp ->write_to_stream(fd); } fd << "end case;" << endl; } int CaseSeqStmt::CaseStmtAlternative::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; if (exp_) { bool first = true; for (list::iterator it = exp_->begin(); it != exp_->end(); ++it) { if(first) first = false; else out << ","; errors += (*it)->emit(out, ent, scope); } } else { out << "default"; } out << ":" << endl; SequentialStmt*curp; switch (stmts_.size()) { case 0: out << "/* no op */;" << endl; break; case 1: curp = stmts_.front(); errors += curp->emit(out, ent, scope); break; default: out << "begin" << endl; for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { curp = *cur; errors += curp->emit(out, ent, scope); } out << "end" << endl; break; } return errors; } void CaseSeqStmt::CaseStmtAlternative::write_to_stream(ostream&fd) { fd << "when "; if (exp_) { bool first = true; for (list::iterator it = exp_->begin(); it != exp_->end(); ++it) { if(first) first = false; else fd << "|"; (*it)->write_to_stream(fd); } } else { fd << "others" << endl; } fd << "=>" << endl; for (list::iterator cur = stmts_.begin() ; cur != stmts_.end() ; ++cur) { (*cur)->write_to_stream(fd); } } int WhileLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "while("; errors += cond_->emit(out, ent, scope); out << ") begin" << endl; errors += emit_substatements(out, ent, scope); out << "end" << endl; return errors; } void WhileLoopStatement::write_to_stream(ostream&out) { out << "while("; cond_->write_to_stream(out); out << ") loop" << endl; write_to_stream_substatements(out); out << "end loop;" << endl; } int ForLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; ivl_assert(*this, range_); int64_t start_val; bool start_rc = range_->left()->evaluate(ent, scope, start_val); int64_t finish_val; bool finish_rc = range_->right()->evaluate(ent, scope, finish_val); perm_string scope_name = loop_name(); if (scope_name.nil()) { char buf[80]; snprintf(buf, sizeof buf, "__%p", this); scope_name = lex_strings.make(buf); } out << "begin : " << scope_name << endl; out << "longint \\" << it_ << " ;" << endl; if(!start_rc || !finish_rc) { // Could not evaluate one of the loop boundaries, it has to be // determined during the run-time errors += emit_runtime_(out, ent, scope); } else { ExpRange::range_dir_t dir = range_->direction(); if(dir == ExpRange::AUTO) dir = start_val < finish_val ? ExpRange::TO : ExpRange::DOWNTO; if ((dir == ExpRange::DOWNTO && start_val < finish_val) || (dir == ExpRange::TO && start_val > finish_val)) { out << "begin /* Degenerate loop at " << get_fileline() << ": " << start_val; out << (dir == ExpRange::DOWNTO ? " downto " : " to "); out << finish_val << " */ end" << endl << "end" << endl; return errors; } out << "for (\\" << it_ << " = " << start_val << " ; "; if (dir == ExpRange::DOWNTO) out << "\\" << it_ << " >= " << finish_val; else out << "\\" << it_ << " <= " << finish_val; out << "; \\" << it_ << " = \\" << it_; if (dir == ExpRange::DOWNTO) out << " - 1)"; else out << " + 1)"; } out << " begin" << endl; errors += emit_substatements(out, ent, scope); out << "end" << endl; out << "end /* " << scope_name << " */" << endl; return errors; } void ForLoopStatement::write_to_stream(ostream&fd) { fd << "for " << it_ << " in "; range_->write_to_stream(fd); fd << " loop" << endl; write_to_stream_substatements(fd); fd << "end loop;" << endl; } int ForLoopStatement::emit_runtime_(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "for (\\" << it_ << " = "; errors += range_->left()->emit(out, ent, scope); // Twisted way of determining the loop direction at runtime out << " ;\n("; errors += range_->left()->emit(out, ent, scope); out << " < "; errors += range_->right()->emit(out, ent, scope); out << " ? \\" << it_ << " <= "; errors += range_->right()->emit(out, ent, scope); out << " : \\" << it_ << " >= "; errors += range_->right()->emit(out, ent, scope); out << ");\n\\" << it_ << " = \\" << it_ << " + ("; errors += range_->left()->emit(out, ent, scope); out << " < "; errors += range_->right()->emit(out, ent, scope); out << " ? 1 : -1))"; return errors; } int BasicLoopStatement::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "forever begin" << endl; errors += emit_substatements(out, ent, scope); out << "end" << endl; return errors; } void BasicLoopStatement::write_to_stream(std::ostream&fd) { fd << "loop" << endl; write_to_stream_substatements(fd); fd << "end loop;" << endl; } int ReportStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { out << "$display(\"** "; switch(severity_) { case NOTE: out << "Note"; break; case WARNING: out << "Warning"; break; case ERROR: out << "Error"; break; case FAILURE: out << "Failure"; break; case UNSPECIFIED: ivl_assert(*this, false); break; } out << ": \","; struct emitter : public ExprVisitor { emitter(ostream&outp, Entity*enti, ScopeBase*scop) : out_(outp), ent_(enti), scope_(scop), level_lock_(numeric_limits::max()) {} void operator() (Expression*s) { if(!dynamic_cast(s)) { if(level() > level_lock_) return; if(dynamic_cast(s)) { level_lock_ = level(); } else { level_lock_ = numeric_limits::max(); } const VType*type = s->probe_type(ent_, scope_); if(dynamic_cast(s) && type && type->type_match(&primitive_STRING)) { out_ << "$sformatf(\"%s\", ("; s->emit(out_, ent_, scope_); out_ << "))"; } else { s->emit(out_, ent_, scope_); } out_ << ", "; } } private: ostream&out_; Entity*ent_; ScopeBase*scope_; int level_lock_; } emit_visitor(out, ent, scope); msg_->visit(emit_visitor); out << "\" (" << get_fileline() << ")\");"; if(severity_ == FAILURE) out << "$finish(0);"; out << std::endl; return 0; } void ReportStmt::write_to_stream(std::ostream&fd) { fd << "report "; msg_->write_to_stream(fd); fd << "severity "; switch(severity_) { case NOTE: fd << "NOTE"; break; case WARNING: fd << "WARNING"; break; case ERROR: fd << "ERROR"; break; case FAILURE: fd << "FAILURE"; break; case UNSPECIFIED: break; } fd << ";" << std::endl; } int AssertStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "if(!("; errors += cond_->emit(out, ent, scope); out << ")) begin" << std::endl; errors += ReportStmt::emit(out, ent, scope); out << "end" << std::endl; return errors; } void AssertStmt::write_to_stream(std::ostream&fd) { fd << "assert "; cond_->write_to_stream(fd); fd << std::endl; ReportStmt::write_to_stream(fd); } int WaitForStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; out << "#("; errors += delay_->emit(out, ent, scope); out << ");" << std::endl; return errors; } void WaitForStmt::write_to_stream(std::ostream&fd) { fd << "wait for "; delay_->write_to_stream(fd); } int WaitStmt::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; switch(type_) { case ON: out << "@("; break; case UNTIL: if(!sens_list_.empty()) { out << "@("; for(std::set::iterator it = sens_list_.begin(); it != sens_list_.end(); ++it) { if(it != sens_list_.begin()) out << ","; (*it)->emit(out, ent, scope); } out << "); "; } out << "wait("; break; case FINAL: out << "/* final wait */" << endl; return 0; // no expression to be emitted } errors += expr_->emit(out, ent, scope); out << ");" << endl; return errors; } void WaitStmt::write_to_stream(std::ostream&fd) { switch(type_) { case ON: fd << "wait on "; break; case UNTIL: fd << "wait until "; break; case FINAL: fd << "wait"; return; // no expression to be emitted } expr_->write_to_stream(fd); } iverilog-12_0/vhdlpp/std_funcs.cc000066400000000000000000000507041435245347300171510ustar00rootroot00000000000000/* * Copyright CERN 2016-2021 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "std_funcs.h" #include "std_types.h" #include "scope.h" using namespace std; static std::map std_subprograms; void register_std_subprogram(SubprogramHeader*header) { std_subprograms[header->name()].push_back(header); } // Special case: to_integer function class SubprogramToInteger : public SubprogramStdHeader { public: SubprogramToInteger() : SubprogramStdHeader(perm_string::literal("to_integer"), NULL, &primitive_REAL) { ports_ = new list(); ports_->push_back(new InterfacePort(&primitive_INTEGER)); } int emit_name(const std::vector&argv, std::ostream&out, Entity*ent, ScopeBase*scope) const { bool signed_flag = false; // to_integer converts unsigned to natural // signed to integer // try to determine the converted type const VType*type = argv[0]->probe_type(ent, scope); const VTypeArray*array = dynamic_cast(type); if(array) { signed_flag = array->signed_vector(); } else { cerr << get_fileline() << ": sorry: Could not determine the " << "expression sign. Output may be erroneous." << endl; return 1; } out << (signed_flag ? "$signed" : "$unsigned"); return 0; } }; // Special case: size casting (e.g. conv_std_logic_vector() / resize()). class SubprogramSizeCast : public SubprogramStdHeader { public: explicit SubprogramSizeCast(perm_string nam, const VType*base, const VType*target) : SubprogramStdHeader(nam, NULL, target) { ports_ = new list(); ports_->push_back(new InterfacePort(base)); ports_->push_back(new InterfacePort(&primitive_NATURAL)); } int emit_name(const std::vector&, std::ostream&, Entity*, ScopeBase*) const { return 0; } int emit_args(const std::vector&argv, std::ostream&out, Entity*ent, ScopeBase*scope) const { int64_t new_size, old_size; const VType*type = argv[0]->probe_type(ent, scope); if(!type) { cerr << get_fileline() << ": sorry: Could not determine " << "the argument type. Size casting impossible." << endl; return 1; } old_size = type->get_width(scope); if(old_size <= 0) { cerr << get_fileline() << ": sorry: Could not determine " << "the argument size. Size casting impossible." << endl; return 1; } if(!argv[1]->evaluate(ent, scope, new_size)) { cerr << get_fileline() << ": sorry: Could not evaluate the requested" << "expression size. Size casting impossible." << endl; return 1; } out << new_size << "'(" << old_size << "'("; if(const VTypeArray*arr = dynamic_cast(type)) out << (arr->signed_vector() ? "$signed" : "$unsigned"); out << "("; bool res = argv[0]->emit(out, ent, scope); out << ")))"; return res; } }; class SubprogramReadWrite : public SubprogramBuiltin { public: SubprogramReadWrite(perm_string nam, perm_string newnam, bool hex = false) : SubprogramBuiltin(nam, newnam, NULL, NULL), hex_format_(hex) { ports_ = new list(); ports_->push_back(new InterfacePort(&primitive_STRING)); ports_->push_back(new InterfacePort(NULL)); } // Format types handled by $ivlh_read/write (see vpi/vhdl_textio.c) enum format_t { FORMAT_STD, FORMAT_BOOL, FORMAT_TIME, FORMAT_HEX, FORMAT_STRING }; int emit_args(const std::vector&argv, std::ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; for(int i = 0; i < 2; ++i) { errors += argv[i]->emit(out, ent, scope); out << ", "; } const VType*arg_type = argv[1]->probe_type(ent, scope); while(const VTypeDef*tdef = dynamic_cast(arg_type)) arg_type = tdef->peek_definition(); // Pick the right format if(hex_format_) { out << FORMAT_HEX; } else if(arg_type) { if(arg_type->type_match(&primitive_TIME)) { out << FORMAT_TIME; } else if(arg_type->type_match(&type_BOOLEAN)) { out << FORMAT_BOOL; } else if(arg_type->type_match(&primitive_CHARACTER)) { out << FORMAT_STRING; } else { const VTypeArray*arr = dynamic_cast(arg_type); if(arr && arr->element_type() == &primitive_CHARACTER) out << FORMAT_STRING; else out << FORMAT_STD; } } else { out << FORMAT_STD; } return errors; } private: bool hex_format_; }; void preload_std_funcs(void) { list*args; /* function now */ SubprogramBuiltin*fn_now = new SubprogramBuiltin(perm_string::literal("now"), perm_string::literal("$time"), NULL, NULL); register_std_subprogram(fn_now); /* numeric_std library * function unsigned */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("unsigned"), perm_string::literal("$unsigned"), args, &primitive_UNSIGNED)); args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("unsigned"), perm_string::literal("$unsigned"), args, &primitive_UNSIGNED)); /* function integer */ args = new list(); args->push_back(new InterfacePort(&primitive_REAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("integer"), perm_string::literal("int'"), args, &primitive_INTEGER)); /* function std_logic_vector Special case: The std_logic_vector function casts its argument to std_logic_vector. Internally, we don't have to do anything for that to work. */ args = new list(); args->push_back(new InterfacePort(&primitive_SIGNED)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("std_logic_vector"), empty_perm_string, args, &primitive_STDLOGIC_VECTOR)); args = new list(); args->push_back(new InterfacePort(&primitive_UNSIGNED)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("std_logic_vector"), empty_perm_string, args, &primitive_STDLOGIC_VECTOR)); /* numeric_std library * function shift_left (arg: unsigned; count: natural) return unsigned; * function shift_left (arg: signed; count: natural) return signed; */ args = new list(); args->push_back(new InterfacePort(&primitive_UNSIGNED)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_left"), perm_string::literal("$ivlh_shift_left"), args, &primitive_UNSIGNED)); args = new list(); args->push_back(new InterfacePort(&primitive_SIGNED)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_left"), perm_string::literal("$ivlh_shift_left"), args, &primitive_SIGNED)); /* numeric_std library * function shift_right (arg: unsigned; count: natural) return unsigned; * function shift_right (arg: signed; count: natural) return signed; */ args = new list(); args->push_back(new InterfacePort(&primitive_UNSIGNED)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_right"), perm_string::literal("$ivlh_shift_right"), args, &primitive_UNSIGNED)); args = new list(); args->push_back(new InterfacePort(&primitive_SIGNED)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("shift_right"), perm_string::literal("$ivlh_shift_right"), args, &primitive_SIGNED)); /* function resize */ register_std_subprogram(new SubprogramSizeCast(perm_string::literal("resize"), &primitive_UNSIGNED, &primitive_UNSIGNED)); register_std_subprogram(new SubprogramSizeCast(perm_string::literal("resize"), &primitive_SIGNED, &primitive_SIGNED)); /* std_logic_arith library * function conv_std_logic_vector(arg: integer; size: integer) return std_logic_vector; */ register_std_subprogram(new SubprogramSizeCast( perm_string::literal("conv_std_logic_vector"), &primitive_INTEGER, &primitive_STDLOGIC_VECTOR)); /* numeric_bit library * function to_integer (arg: unsigned) return natural; */ args = new list(); args->push_back(new InterfacePort(&primitive_UNSIGNED)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_integer"), perm_string::literal("$unsigned"), args, &primitive_NATURAL)); /* numeric_bit library * function to_integer (arg: signed) return integer; */ args = new list(); args->push_back(new InterfacePort(&primitive_SIGNED)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_integer"), perm_string::literal("$signed"), args, &primitive_INTEGER)); /* std_logic_1164 library * function to_bit (signal s : std_ulogic) return bit; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_bit"), empty_perm_string, args, &primitive_BIT)); /* std_logic_1164 library * function to_bitvector (signal s : std_logic_vector) return bit_vector; * function to_bitvector (signal s : std_ulogic_vector) return bit_vector; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_bitvector"), empty_perm_string, args, &primitive_BIT_VECTOR)); /* std_logic_1164 library * function rising_edge (signal s : std_ulogic) return boolean; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("rising_edge"), perm_string::literal("$ivlh_rising_edge"), args, &type_BOOLEAN)); /* std_logic_1164 library * function falling_edge (signal s : std_ulogic) return boolean; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("falling_edge"), perm_string::literal("$ivlh_falling_edge"), args, &type_BOOLEAN)); /* reduce_pack library * function or_reduce(arg : std_logic_vector) return std_logic; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("or_reduce"), perm_string::literal("|"), args, &primitive_STDLOGIC)); /* reduce_pack library * function and_reduce(arg : std_logic_vector) return std_logic; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("and_reduce"), perm_string::literal("&"), args, &primitive_STDLOGIC)); /* fixed_pkg library * function to_unsigned ( * arg : ufixed; -- fixed point input * constant size : natural) -- length of output * return unsigned; */ args = new list(); args->push_back(new InterfacePort(&primitive_REAL)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_unsigned"), perm_string::literal("$ivlh_to_unsigned"), args, &primitive_UNSIGNED)); /* numeric_std library * function to_unsigned(arg, size : natural) return unsigned; */ args = new list(); args->push_back(new InterfacePort(&primitive_NATURAL)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_unsigned"), perm_string::literal("$ivlh_to_unsigned"), args, &primitive_UNSIGNED)); /* numeric_std library * function to_unsigned(arg : std_logic_vector, size : natural) return unsigned; */ args = new list(); args->push_back(new InterfacePort(&primitive_STDLOGIC_VECTOR)); args->push_back(new InterfacePort(&primitive_NATURAL)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("to_unsigned"), perm_string::literal("$ivlh_to_unsigned"), args, &primitive_UNSIGNED)); /* procedure file_open (file f: text; filename: in string, file_open_kind: in mode); */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); args->push_back(new InterfacePort(&primitive_STRING, PORT_IN)); args->push_back(new InterfacePort(&type_FILE_OPEN_KIND, PORT_IN)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("file_open"), perm_string::literal("$ivlh_file_open"), args, NULL)); /* procedure file_open (status: out file_open_status, file f: text; filename: in string, file_open_kind: in mode); */ args = new list(); args->push_back(new InterfacePort(&type_FILE_OPEN_STATUS, PORT_OUT)); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); args->push_back(new InterfacePort(&primitive_STRING, PORT_IN)); args->push_back(new InterfacePort(&type_FILE_OPEN_KIND, PORT_IN)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("file_open"), perm_string::literal("$ivlh_file_open"), args, NULL)); /* std.textio library * procedure file_close (file f: text); */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("file_close"), perm_string::literal("$fclose"), args, NULL)); /* std.textio library * procedure read (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); */ register_std_subprogram(new SubprogramReadWrite(perm_string::literal("read"), perm_string::literal("$ivlh_read"))); /* std.textio library * procedure write (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); */ register_std_subprogram(new SubprogramReadWrite(perm_string::literal("write"), perm_string::literal("$ivlh_write"))); /* std.textio library * procedure hread (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); */ register_std_subprogram(new SubprogramReadWrite(perm_string::literal("hread"), perm_string::literal("$ivlh_read"), true)); /* std.textio library * procedure hwrite (l: inout line; value: out bit/bit_vector/boolean/character/integer/real/string/time); */ register_std_subprogram(new SubprogramReadWrite(perm_string::literal("hwrite"), perm_string::literal("$ivlh_write"), true)); /* std.textio library * procedure readline (file f: text; l: inout line); */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); args->push_back(new InterfacePort(&primitive_STRING, PORT_OUT)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("readline"), perm_string::literal("$ivlh_readline"), args, NULL)); /* std.textio library * procedure writeline (file f: text; l: inout line); */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); args->push_back(new InterfacePort(&primitive_STRING, PORT_IN)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("writeline"), perm_string::literal("$ivlh_writeline"), args, NULL)); /* function endline (file f: text) return boolean; */ args = new list(); args->push_back(new InterfacePort(&primitive_INTEGER, PORT_IN)); register_std_subprogram(new SubprogramBuiltin(perm_string::literal("endfile"), perm_string::literal("$feof"), args, &type_BOOLEAN)); } void delete_std_funcs() { for(std::map::iterator cur = std_subprograms.begin(); cur != std_subprograms.end(); ++cur) { for(SubHeaderList::const_iterator it = cur->second.begin(); it != cur->second.end(); ++it) { delete *it; } } } SubHeaderList find_std_subprogram(perm_string name) { map::const_iterator cur = std_subprograms.find(name); if(cur != std_subprograms.end()) return cur->second; return SubHeaderList(); } iverilog-12_0/vhdlpp/std_funcs.h000066400000000000000000000026061435245347300170110ustar00rootroot00000000000000#ifndef IVL_std_funcs_H #define IVL_std_funcs_H /* * Copyright CERN 2016 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "subprogram.h" // Generates subprogram headers for standard VHDL library functions. void preload_std_funcs(); // Destroys subprogram headers for standard VHDL library functions. void delete_std_funcs(); // Adds a subprogram to the standard library subprogram set void register_std_subprogram(SubprogramHeader*header); // Returns subprogram header for a requested function or NULL if it does not exist. SubHeaderList find_std_subprogram(perm_string name); #endif /* IVL_std_funcs_H */ iverilog-12_0/vhdlpp/std_types.cc000066400000000000000000000143031435245347300171720ustar00rootroot00000000000000/* * Copyright CERN 2015-2021 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "std_types.h" #include "scope.h" using namespace std; static map std_types; // this list contains enums used by typedefs in the std_types map static list std_enums; const VTypePrimitive primitive_BIT(VTypePrimitive::BIT, true); const VTypePrimitive primitive_INTEGER(VTypePrimitive::INTEGER); const VTypePrimitive primitive_NATURAL(VTypePrimitive::NATURAL); const VTypePrimitive primitive_REAL(VTypePrimitive::REAL); const VTypePrimitive primitive_STDLOGIC(VTypePrimitive::STDLOGIC, true); const VTypePrimitive primitive_TIME(VTypePrimitive::TIME, true); VTypeDef type_BOOLEAN(perm_string::literal("boolean")); VTypeDef type_FILE_OPEN_KIND(perm_string::literal("file_open_kind")); VTypeDef type_FILE_OPEN_STATUS(perm_string::literal("file_open_status")); const VTypeArray primitive_CHARACTER(&primitive_BIT, 7, 0); const VTypeArray primitive_BIT_VECTOR(&primitive_BIT, vector (1)); const VTypeArray primitive_BOOL_VECTOR(&type_BOOLEAN, vector (1)); const VTypeArray primitive_STDLOGIC_VECTOR(&primitive_STDLOGIC, vector (1)); const VTypeArray primitive_STRING(&primitive_CHARACTER, vector (1)); const VTypeArray primitive_SIGNED(&primitive_STDLOGIC, vector (1), true); const VTypeArray primitive_UNSIGNED(&primitive_STDLOGIC, vector (1), false); void generate_global_types(ActiveScope*res) { // boolean list enum_BOOLEAN_vals; enum_BOOLEAN_vals.push_back(perm_string::literal("false")); enum_BOOLEAN_vals.push_back(perm_string::literal("true")); VTypeEnum*enum_BOOLEAN = new VTypeEnum(&enum_BOOLEAN_vals); type_BOOLEAN.set_definition(enum_BOOLEAN); std_types[type_BOOLEAN.peek_name()] = &type_BOOLEAN; std_enums.push_back(enum_BOOLEAN); // file_open_kind list enum_FILE_OPEN_KIND_vals; enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("read_mode")); enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("write_mode")); enum_FILE_OPEN_KIND_vals.push_back(perm_string::literal("append_mode")); VTypeEnum*enum_FILE_OPEN_KIND = new VTypeEnum(&enum_FILE_OPEN_KIND_vals); type_FILE_OPEN_KIND.set_definition(enum_FILE_OPEN_KIND); std_types[type_FILE_OPEN_KIND.peek_name()] = &type_FILE_OPEN_KIND; std_enums.push_back(enum_FILE_OPEN_KIND); // file_open_status list enum_FILE_OPEN_STATUS_vals; enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("open_ok")); enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("status_error")); enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("name_error")); enum_FILE_OPEN_STATUS_vals.push_back(perm_string::literal("mode_error")); VTypeEnum*enum_FILE_OPEN_STATUS = new VTypeEnum(&enum_FILE_OPEN_STATUS_vals); type_FILE_OPEN_STATUS.set_definition(enum_FILE_OPEN_STATUS); std_types[type_FILE_OPEN_STATUS.peek_name()] = &type_FILE_OPEN_STATUS; std_enums.push_back(enum_FILE_OPEN_STATUS); res->use_name(type_BOOLEAN.peek_name(), &type_BOOLEAN); res->use_name(perm_string::literal("bit"), &primitive_BIT); res->use_name(perm_string::literal("bit_vector"), &primitive_BIT_VECTOR); res->use_name(perm_string::literal("integer"), &primitive_INTEGER); res->use_name(perm_string::literal("real"), &primitive_REAL); res->use_name(perm_string::literal("std_logic"), &primitive_STDLOGIC); res->use_name(perm_string::literal("character"), &primitive_CHARACTER); res->use_name(perm_string::literal("string"), &primitive_STRING); res->use_name(perm_string::literal("natural"), &primitive_NATURAL); res->use_name(perm_string::literal("time"), &primitive_TIME); } void delete_global_types() { for(map::iterator cur = std_types.begin(); cur != std_types.end(); ++cur) { delete cur->second->peek_definition(); delete cur->second; } // std_enums are destroyed above } const VTypeEnum*find_std_enum_name(perm_string name) { for(list::const_iterator it = std_enums.begin(); it != std_enums.end(); ++it) { if((*it)->has_name(name)) return *it; } return NULL; } void emit_std_types(ostream&fd) { fd << "`ifndef __VHDL_STD_TYPES" << endl; fd << "`define __VHDL_STD_TYPES" << endl; typedef_context_t typedef_ctx; for(map::iterator cur = std_types.begin(); cur != std_types.end() ; ++ cur) { cur->second->emit_typedef(fd, typedef_ctx); } fd << "`endif" << endl; } bool is_global_type(perm_string name) { if (name == "boolean") return true; if (name == "bit") return true; if (name == "bit_vector") return true; if (name == "integer") return true; if (name == "real") return true; if (name == "std_logic") return true; if (name == "std_logic_vector") return true; if (name == "character") return true; if (name == "string") return true; if (name == "natural") return true; if (name == "signed") return true; if (name == "unsigned") return true; if (name == "time") return true; return std_types.count(name) > 0; } iverilog-12_0/vhdlpp/std_types.h000066400000000000000000000035661435245347300170450ustar00rootroot00000000000000/* * Copyright CERN 2015-2021 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "vtype.h" class ActiveScope; void emit_std_types(std::ostream&out); void generate_global_types(ActiveScope*res); bool is_global_type(perm_string type_name); void delete_global_types(); const VTypeEnum*find_std_enum_name(perm_string name); extern const VTypePrimitive primitive_BIT; extern const VTypePrimitive primitive_INTEGER; extern const VTypePrimitive primitive_NATURAL; extern const VTypePrimitive primitive_REAL; extern const VTypePrimitive primitive_STDLOGIC; extern const VTypePrimitive primitive_TIME; extern const VTypePrimitive primitive_TEXT; extern const VTypePrimitive primitive_LINE; extern VTypeDef type_BOOLEAN; extern VTypeDef type_FILE_OPEN_KIND; extern VTypeDef type_FILE_OPEN_STATUS; extern const VTypeArray primitive_CHARACTER; extern const VTypeArray primitive_BIT_VECTOR; extern const VTypeArray primitive_BOOL_VECTOR; extern const VTypeArray primitive_STDLOGIC_VECTOR; extern const VTypeArray primitive_STRING; extern const VTypeArray primitive_SIGNED; extern const VTypeArray primitive_UNSIGNED; iverilog-12_0/vhdlpp/subprogram.cc000066400000000000000000000244701435245347300173430ustar00rootroot00000000000000/* * Copyright (c) 2013-2014 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2015 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "subprogram.h" # include "entity.h" # include "vtype.h" # include "sequential.h" # include "ivl_assert.h" # include "compiler.h" # include using namespace std; SubprogramBody::SubprogramBody() : statements_(NULL), header_(NULL) { } SubprogramBody::~SubprogramBody() { } const InterfacePort*SubprogramBody::find_param(perm_string nam) const { if(!header_) return NULL; return header_->find_param(nam); } void SubprogramBody::set_statements(list*stmt) { ivl_assert(*this, statements_==0); statements_ = stmt; } int SubprogramBody::elaborate() { int errors = 0; for (list::const_iterator cur = statements_->begin() ; cur != statements_->end() ; ++cur) { errors += (*cur)->elaborate(0, this); } return errors; } void SubprogramBody::write_to_stream(ostream&fd) const { for (map::const_iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { cur->second->write_to_stream(fd); } fd << "begin" << endl; if (statements_) { for (list::const_iterator cur = statements_->begin() ; cur != statements_->end() ; ++cur) { (*cur)->write_to_stream(fd); } } else { fd << "--empty body" << endl; } fd << "end function " << header_->name() << ";" << endl; } SubprogramHeader::SubprogramHeader(perm_string nam, list*ports, const VType*return_type) : name_(nam), ports_(ports), return_type_(return_type), body_(NULL), package_(NULL) { } SubprogramHeader::~SubprogramHeader() { delete body_; if(ports_) { for(list::iterator it = ports_->begin(); it != ports_->end(); ++it) { delete *it; } delete ports_; } } bool SubprogramHeader::compare_specification(SubprogramHeader*that) const { if (name_ != that->name_) return false; if (return_type_==0) { if (that->return_type_!=0) return false; } else { if (that->return_type_==0) return false; if (! return_type_->type_match(that->return_type_)) return false; } if (ports_==0) { if (that->ports_!=0) return false; } else { if (that->ports_==0) return false; if (ports_->size() != that->ports_->size()) return false; } return true; } const InterfacePort*SubprogramHeader::find_param(perm_string nam) const { if(!ports_) return NULL; for (std::list::const_iterator it = ports_->begin() ; it != ports_->end(); ++it) { if((*it)->name == nam) return *it; } return NULL; } const InterfacePort*SubprogramHeader::peek_param(int idx) const { if(!ports_ || idx < 0 || (size_t)idx >= ports_->size()) return NULL; std::list::const_iterator p = ports_->begin(); std::advance(p, idx); return *p; } const VType*SubprogramHeader::peek_param_type(int idx) const { const InterfacePort*port = peek_param(idx); if(port) return port->type; return NULL; } const VType*SubprogramHeader::exact_return_type(const std::vector&argv, Entity*ent, ScopeBase*scope) { const VTypeArray*orig_ret = dynamic_cast(return_type_); if(!orig_ret) return return_type_; const VTypeArray*arg = dynamic_cast(argv[0]->fit_type(ent, scope, orig_ret)); if(!arg) return return_type_; VTypeArray*ret = new VTypeArray(orig_ret->element_type(), arg->dimensions(), orig_ret->signed_vector()); ret->set_parent_type(orig_ret); return ret; } bool SubprogramHeader::unbounded() const { if(return_type_ && return_type_->is_unbounded()) return true; if(ports_) { for(std::list::const_iterator it = ports_->begin(); it != ports_->end(); ++it) { if((*it)->type->is_unbounded()) return true; } } return false; } void SubprogramHeader::set_body(SubprogramBody*bdy) { ivl_assert(*this, !body_); body_ = bdy; ivl_assert(*this, !bdy->header_); bdy->header_ = this; } int SubprogramHeader::elaborate_argument(Expression*expr, int idx, Entity*ent, ScopeBase*scope) { const VType*type = expr->probe_type(ent, scope); const InterfacePort*param = peek_param(idx); if(!param) { cerr << expr->get_fileline() << ": error: Too many arguments when calling " << name_ << "." << endl; return 1; } // Enable reg_flag for variables that might be modified in subprograms if(param->mode == PORT_OUT || param->mode == PORT_INOUT) { if(const ExpName*e = dynamic_cast(expr)) { if(Signal*sig = scope->find_signal(e->peek_name())) sig->count_ref_sequ(); else if(Variable*var = scope->find_variable(e->peek_name())) var->count_ref_sequ(); } } if(!type) type = param->type; return expr->elaborate_expr(ent, scope, type); } SubprogramHeader*SubprogramHeader::make_instance(std::vector arguments, ScopeBase*scope) const { assert(arguments.size() == ports_->size()); std::list*ports = new std::list; int i = 0; // Change the argument types to match the ones that were used during // the function call for(std::list::iterator it = ports_->begin(); it != ports_->end(); ++it) { InterfacePort*p = new InterfacePort(**it); p->type = arguments[i++]->peek_type()->clone(); assert(p->type); ports->push_back(p); } char buf[80]; snprintf(buf, sizeof(buf), "__%s_%p", name_.str(), ports); perm_string new_name = lex_strings.make(buf); SubprogramHeader*instance = new SubprogramHeader(new_name, ports, return_type_); if(body_) { SubprogramBody*body_inst = new SubprogramBody(); // Copy variables for(std::map::iterator it = body_->new_variables_.begin(); it != body_->new_variables_.end(); ++it) { Variable*v = new Variable(it->first, it->second->peek_type()->clone()); body_inst->new_variables_[it->first] = v; } body_inst->set_statements(body_->statements_); instance->set_package(package_); instance->set_body(body_inst); instance->fix_return_type(); } scope->bind_subprogram(new_name, instance); return instance; } struct check_return_type : public SeqStmtVisitor { explicit check_return_type(const SubprogramBody*subp) : subp_(subp), ret_type_(NULL) {} void operator() (SequentialStmt*s) { ReturnStmt*ret; if((ret = dynamic_cast(s))) { const Expression*expr = ret->peek_expr(); const VType*t = NULL; if(const ExpName*n = dynamic_cast(expr)) { if(Variable*v = subp_->find_variable(n->peek_name())) t = v->peek_type(); } else { t = expr->peek_type(); } if(!t) { // cannot determine the type at least in one case ret_type_ = NULL; return; } if(!ret_type_) { // this is first processed return statement ret_type_ = t; } else if(!t->type_match(ret_type_)) { // the function can return different types, // we cannot have fixed width ret_type_ = NULL; return; } } } const VType*get_type() const { return ret_type_; } private: const SubprogramBody*subp_; const VType*ret_type_; }; void SubprogramHeader::fix_return_type() { if(!body_ || !body_->statements_) return; check_return_type r(body_); for (std::list::iterator s = body_->statements_->begin() ; s != body_->statements_->end(); ++s) { (*s)->visit(r); } VType*return_type = const_cast(r.get_type()); if(return_type && !return_type->is_unbounded()) { // Let's check if the variable length can be evaluated without any scope. // If not, then it depends on information about e.g. function params if(return_type->is_variable_length(NULL)) { if(VTypeArray*arr = dynamic_cast(return_type)) arr->evaluate_ranges(body_); } return_type_ = return_type; } } void SubprogramHeader::write_to_stream(ostream&fd) const { if(return_type_) fd << "function "; else fd << "procedure "; fd << name_; if (ports_ && ! ports_->empty()) { fd << "("; list::const_iterator cur = ports_->begin(); InterfacePort*curp = *cur; fd << curp->name << " : "; curp->type->write_to_stream(fd); for (++cur ; cur != ports_->end() ; ++cur) { curp = *cur; fd << "; " << curp->name << " : "; curp->type->write_to_stream(fd); } fd << ")"; } if( return_type_) { fd << " return "; return_type_->write_to_stream(fd); } } iverilog-12_0/vhdlpp/subprogram.h000066400000000000000000000151701435245347300172020ustar00rootroot00000000000000#ifndef IVL_subprogram_H #define IVL_subprogram_H /* * Copyright (c) 2013-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * Copyright CERN 2015 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "LineInfo.h" # include "scope.h" # include # include # include class InterfacePort; class SequentialStmt; class Package; class VType; class SubprogramBody : public LineInfo, public ScopeBase { public: SubprogramBody(); ~SubprogramBody(); const InterfacePort*find_param(perm_string nam) const; void set_statements(std::list*statements); inline bool empty_statements() const { return !statements_ || statements_->empty(); } int elaborate(); int emit(std::ostream&out, Entity*ent, ScopeBase*scope); // Emit body as it would show up in a package. int emit_package(std::ostream&fd); void write_to_stream(std::ostream&fd) const; void dump(std::ostream&fd) const; const SubprogramHeader*header() const { return header_; } bool is_subprogram() const { return true; } private: std::list*statements_; SubprogramHeader*header_; friend class SubprogramHeader; }; class SubprogramHeader : public LineInfo { public: SubprogramHeader(perm_string name, std::list*ports, const VType*return_type); virtual ~SubprogramHeader(); // Return true if the specification (name, types, ports) // matches this subprogram and that subprogram. bool compare_specification(SubprogramHeader*that) const; int param_count() const { return ports_ ? ports_->size() : 0; } const InterfacePort*find_param(perm_string nam) const; const InterfacePort*peek_param(int idx) const; const VType*peek_param_type(int idx) const; const VType*peek_return_type() const { return return_type_; } // Computes the exact return type (e.g. std_logic_vector(7 downto 0) // instead of generic std_logic_vector) virtual const VType*exact_return_type(const std::vector&, Entity*, ScopeBase*); inline void set_package(const Package*pkg) { assert(!package_); package_ = pkg; } inline const Package*get_package() const { return package_; } // Checks if either return type or parameters are unbounded vectors. bool unbounded() const; // Is the subprogram coming from the standard library? virtual bool is_std() const { return false; } inline SubprogramBody*body() const { return body_; } void set_body(SubprogramBody*bdy); inline perm_string name() const { return name_; } int elaborate() { return (body_ ? body_->elaborate() : 0); } // Elaborates an argument basing on the types stored in the subprogram header. int elaborate_argument(Expression*expr, int idx, Entity*ent, ScopeBase*scope); // Emits the function name, including the package if required. int emit_full_name(const std::vector&argv, std::ostream&out, Entity*, ScopeBase*) const; // Function name used in the emission step. The main purpose of this // method is to handle functions offered by standard VHDL libraries. // Allows to return different function names depending on the arguments // (think of size casting or signed/unsigned functions). virtual int emit_name(const std::vector&argv, std::ostream&out, Entity*, ScopeBase*) const; // Emit arguments for a specific call. It allows to reorder or skip // some of the arguments if function signature is different in // SystemVerilog compared to VHDL. virtual int emit_args(const std::vector&argv, std::ostream&out, Entity*, ScopeBase*) const; // Creates a new instance of the function that takes arguments of // a different type. It is used to allow VHDL functions that work with // unbounded std_logic_vectors, so there can be a separate instance // for limited length logic vector. SubprogramHeader*make_instance(std::vector arguments, ScopeBase*scope) const; // Emit header as it would show up in a package. int emit_package(std::ostream&fd) const; void write_to_stream(std::ostream&fd) const; void dump(std::ostream&fd) const; protected: // Tries to set the return type to a fixed type. VHDL functions that // return std_logic_vectors do not specify its length, as SystemVerilog // demands. void fix_return_type(); // Procedure/function name perm_string name_; std::list*ports_; const VType*return_type_; SubprogramBody*body_; const Package*package_; }; // Class to define functions headers defined in the standard VHDL libraries. class SubprogramStdHeader : public SubprogramHeader { public: SubprogramStdHeader(perm_string nam, std::list*ports, const VType*return_type) : SubprogramHeader(nam, ports, return_type) {} virtual ~SubprogramStdHeader() {}; bool is_std() const { return true; } }; // The simplest case, when only function name has to be changed. class SubprogramBuiltin : public SubprogramStdHeader { public: SubprogramBuiltin(perm_string vhdl_name, perm_string sv_name, std::list*ports, const VType*return_type) : SubprogramStdHeader(vhdl_name, ports, return_type), sv_name_(sv_name) {} ~SubprogramBuiltin() {} int emit_name(const std::vector&, std::ostream&out, Entity*, ScopeBase*) const; private: // SystemVerilog counterpart function name perm_string sv_name_; }; // Helper function to print out a human-readable function signature. void emit_subprogram_sig(std::ostream&out, perm_string name, const std::list&arg_types); #endif /* IVL_subprogram_H */ iverilog-12_0/vhdlpp/subprogram_emit.cc000066400000000000000000000121471435245347300203570ustar00rootroot00000000000000/* * Copyright (c) 2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "subprogram.h" # include "sequential.h" # include "vtype.h" # include "package.h" # include using namespace std; int SubprogramBody::emit_package(ostream&fd) { int errors = 0; for (map::const_iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { // Enable reg_flag for variables cur->second->count_ref_sequ(); errors += cur->second->emit(fd, NULL, this, false); } // Emulate automatic functions (add explicit initial value assignments) for (map::const_iterator cur = new_variables_.begin() ; cur != new_variables_.end() ; ++cur) { Variable*var = cur->second; if(const Expression*init = var->peek_init_expr()) { fd << cur->first << " = "; init->emit(fd, NULL, this); fd << "; // automatic function emulation" << endl; } } if (statements_) { for (list::const_iterator cur = statements_->begin() ; cur != statements_->end() ; ++cur) { errors += (*cur)->emit(fd, NULL, const_cast(this)); } } else { fd << " begin /* empty body */ end" << endl; } return errors; } int SubprogramHeader::emit_package(ostream&fd) const { int errors = 0; if (return_type_) { fd << "function automatic "; return_type_->emit_def(fd, empty_perm_string); } else { fd << "task automatic"; } fd << " \\" << name_ << " ("; for (list::const_iterator cur = ports_->begin() ; cur != ports_->end() ; ++cur) { if (cur != ports_->begin()) fd << ", "; InterfacePort*curp = *cur; switch (curp->mode) { case PORT_IN: fd << "input "; break; case PORT_OUT: fd << "output "; break; case PORT_INOUT: fd << "inout "; break; case PORT_NONE: fd << "inout /* PORT_NONE? */ "; break; } errors += curp->type->emit_def(fd, curp->name); } fd << ");" << endl; if (body_) body_->emit_package(fd); if (return_type_) fd << "endfunction" << endl; else fd << "endtask" << endl; return errors; } int SubprogramHeader::emit_full_name(const std::vector&argv, std::ostream&out, Entity*ent, ScopeBase*scope) const { // If this function has an elaborated definition, and if // that definition is in a package, then include the // package name as a scope qualifier. This assures that // the SV elaborator finds the correct VHDL elaborated // definition. It should not be emitted only if we call another // function from the same package. const SubprogramBody*subp = dynamic_cast(scope); if (package_ && (!subp || !subp->header() || subp->header()->get_package() != package_)) out << "\\" << package_->name() << " ::"; return emit_name(argv, out, ent, scope); } int SubprogramHeader::emit_name(const std::vector&, std::ostream&out, Entity*, ScopeBase*) const { out << "\\" << name_; return 0; } int SubprogramHeader::emit_args(const std::vector&argv, std::ostream&out, Entity*ent, ScopeBase*scope) const { int errors = 0; for (size_t idx = 0; idx < argv.size() ; idx += 1) { if (idx > 0) out << ", "; errors += argv[idx]->emit(out, ent, scope); } return errors; } int SubprogramBuiltin::emit_name(const std::vector&, std::ostream&out, Entity*, ScopeBase*) const { // do not escape the names for builtin functions out << sv_name_; return 0; } void emit_subprogram_sig(ostream&out, perm_string name, const list&arg_types) { out << name << "("; bool first = true; for(list::const_iterator it = arg_types.begin(); it != arg_types.end(); ++it) { if(first) first = false; else out << ", "; if(*it) (*it)->write_to_stream(out); else out << ""; } out << ")"; } iverilog-12_0/vhdlpp/vhdlint.cc000066400000000000000000000036211435245347300166250ustar00rootroot00000000000000 /* * Copyright (c) 2011 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 "vhdlint.h" #include #include #include using namespace std; bool vhdlint::is_negative() const { return value_ < 0L; } bool vhdlint::is_positive() const { return value_ > 0L; } bool vhdlint::is_zero() const { return value_ == 0L; } vhdlint::vhdlint(const char* text) { unsigned text_length = strlen(text); if(text_length == 0) { value_ = 0L; return; } char* new_text = new char[text_length + 1]; const char* ptr; char* new_ptr; for(ptr = text, new_ptr = new_text; *ptr != 0; ++ptr) { if(*ptr == '_') continue; else { *new_ptr = *ptr; ++new_ptr; } } *new_ptr = 0; istringstream str(new_text); delete[] new_text; //TODO: check if numbers greater than MAX_INT are handled correctly str >> value_; } vhdlint::vhdlint(const int64_t& val) { value_ = val; } vhdlint::vhdlint(const vhdlint& val) { value_ = val.as_long(); } int64_t vhdlint::as_long() const { return value_; } iverilog-12_0/vhdlpp/vhdlint.h000066400000000000000000000026571435245347300164770ustar00rootroot00000000000000#ifndef IVL_vhdlint_H #define IVL_vhdlint_H /* * Copyright (c) 2011-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 class vhdlint { public: explicit vhdlint(const char* text); explicit vhdlint(const int64_t& val); explicit vhdlint(const vhdlint& val); bool is_negative() const; bool is_positive() const; bool is_zero() const; int64_t as_long() const; //vhdlv get(const unsigned index) const; //void set(const unsigned index, const unsigned val); // unsigned short operator[](const unsigned index); private: int64_t value_; }; #endif /* IVL_vhdlint_H */ iverilog-12_0/vhdlpp/vhdlnum.h000066400000000000000000000002561435245347300164750ustar00rootroot00000000000000#ifndef IVL_vhdlnum_H #define IVL_vhdlnum_H #include "config.h" #warning vhdlnum class vhdlnum { public: vhdlnum(char* text) {} }; #endif /* IVL_vhdlnum_H */ iverilog-12_0/vhdlpp/vhdlpp_config.h.in000066400000000000000000000022171435245347300202460ustar00rootroot00000000000000#ifndef IVL_vhdlpp_config_H /* -*- c++ -*- */ #define IVL_vhdlpp_config_H /* * Copyright (c) 2011-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. */ # undef HAVE_GETOPT_H # undef HAVE_INTTYPES_H # undef HAVE_LIBIBERTY_H # undef HAVE_FCHMOD # undef HAVE_SYS_WAIT_H #ifdef HAVE_INTTYPES_H # include #endif #endif /* IVL_vhdlpp_config_H */ iverilog-12_0/vhdlpp/vhdlreal.cc000066400000000000000000000044761435245347300167670ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "vhdlreal.h" #include #include #include using namespace std; vhdlreal::vhdlreal() { value_ = 0.0; } vhdlreal::vhdlreal(const double& r) { value_ = r; } vhdlreal::vhdlreal(const vhdlreal& val) { value_ = val.as_double(); } vhdlreal::vhdlreal(const char* text) { assert(strlen(text) != 0); char* buffer = new char[strlen(text)+1]; char* buf_ptr; for(buf_ptr = buffer; *text != 0; ++buf_ptr, ++text) { if(*text == '_') continue; *buf_ptr = *text; } *buf_ptr = '\0'; value_ = strtod(buffer, NULL); delete[] buffer; } ostream& operator<< (ostream& str, const vhdlreal& r) { return (str << r.as_double()); } vhdlreal operator+ (const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(r1.as_double() + r2.as_double()); } vhdlreal operator- (const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(r1.as_double() - r2.as_double()); } vhdlreal operator* (const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(r1.as_double() * r2.as_double()); } vhdlreal operator/ (const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(r1.as_double() / r2.as_double()); } vhdlreal operator% (const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(fmod(r1.as_double(), r2.as_double())); } vhdlreal pow(const vhdlreal& r1, const vhdlreal& r2) { return vhdlreal(pow(r1.as_double(), r2.as_double())); } vhdlreal operator- (const vhdlreal& r) { return vhdlreal(-r.as_double()); } iverilog-12_0/vhdlpp/vhdlreal.h000066400000000000000000000037451435245347300166270ustar00rootroot00000000000000#ifndef IVL_vhdlreal_h #define IVL_vhdlreal_h /* * Copyright (c) 2011-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 #include /* * This class holds a floating point decimal number. The number is * stored as double. All based numbers are converted by an external * function to a double and then stored as class instance. */ class vhdlreal { public: friend std::ostream& operator<< (std::ostream&, const vhdlreal&); friend vhdlreal operator+ (const vhdlreal&, const vhdlreal&); friend vhdlreal operator- (const vhdlreal&, const vhdlreal&); friend vhdlreal operator* (const vhdlreal&, const vhdlreal&); friend vhdlreal operator/ (const vhdlreal&, const vhdlreal&); friend vhdlreal operator% (const vhdlreal&, const vhdlreal&); friend vhdlreal pow(const vhdlreal&, const vhdlreal&); // Unary minus. friend vhdlreal operator- (const vhdlreal&); explicit vhdlreal(); explicit vhdlreal(const char*text); explicit vhdlreal(const double& val); vhdlreal(const vhdlreal& val); virtual ~vhdlreal() {}; double as_double() const { return value_; } private: double value_; }; #endif /* IVL_vhdlreal_h */ iverilog-12_0/vhdlpp/vsignal.cc000066400000000000000000000057211435245347300166230ustar00rootroot00000000000000/* * Copyright (c) 2011 Stephen Williams (steve@icarus.com) * Copyright CERN 2014 * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "vsignal.h" # include "expression.h" # include "scope.h" # include "vtype.h" # include "std_types.h" # include using namespace std; SigVarBase::SigVarBase(perm_string nam, const VType*typ, Expression*exp) : name_(nam), type_(typ), init_expr_(exp), refcnt_sequ_(0) { } SigVarBase::~SigVarBase() { } void SigVarBase::elaborate(Entity*ent, ScopeBase*scope) { if(init_expr_) init_expr_->elaborate_expr(ent, scope, peek_type()); type_->elaborate(ent, scope); } void SigVarBase::type_elaborate_(VType::decl_t&decl) { decl.type = type_; } int Signal::emit(ostream&out, Entity*ent, ScopeBase*scope, bool initialize) { int errors = 0; VType::decl_t decl; type_elaborate_(decl); const VType*type = peek_type(); if (peek_refcnt_sequ_() > 0 || (!type->can_be_packed() && dynamic_cast(type))) decl.reg_flag = true; errors += decl.emit(out, peek_name()); const Expression*init_expr = peek_init_expr(); if (initialize && init_expr) { /* Emit initialization value for wires as a weak assignment */ if(!decl.reg_flag && !type->type_match(&primitive_REAL)) out << ";" << endl << "/*init*/ assign (weak1, weak0) " << peek_name(); out << " = "; init_expr->emit(out, ent, scope); } out << ";" << endl; return errors; } int Variable::emit(ostream&out, Entity*ent, ScopeBase*scope, bool initialize) { int errors = 0; out << (!scope->is_subprogram() ? "static " : "automatic "); VType::decl_t decl; type_elaborate_(decl); decl.reg_flag = true; errors += decl.emit(out, peek_name()); const Expression*init_expr = peek_init_expr(); if (initialize && init_expr) { out << " = "; init_expr->emit(out, ent, scope); } out << ";" << endl; return errors; } void Variable::write_to_stream(std::ostream&fd) { fd << "variable " << peek_name() << " : "; peek_type()->write_to_stream(fd); fd << ";" << endl; } iverilog-12_0/vhdlpp/vsignal.h000066400000000000000000000054711435245347300164670ustar00rootroot00000000000000#ifndef IVL_vsignal_H #define IVL_vsignal_H /* * Copyright (c) 2011-2021 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 "LineInfo.h" # include "vtype.h" class Architecture; class ScopeBase; class Entity; class Expression; class SigVarBase : public LineInfo { public: SigVarBase(perm_string name, const VType*type, Expression*init_expr); virtual ~SigVarBase(); const VType* peek_type(void) const { return type_; } // Call this method for each occasion where this signal is the // l-value of a sequential assignment. void count_ref_sequ(); void dump(std::ostream&out, int indent = 0) const; // Elaborates type & initializer expressions. void elaborate(Entity*ent, ScopeBase*scope); perm_string peek_name() const { return name_; } const Expression* peek_init_expr() const { return init_expr_; } protected: unsigned peek_refcnt_sequ_() const { return refcnt_sequ_; } void type_elaborate_(VType::decl_t&decl); private: perm_string name_; const VType*type_; Expression*init_expr_; unsigned refcnt_sequ_; private: // Not implemented SigVarBase(const SigVarBase&); SigVarBase& operator = (const SigVarBase&); }; class Signal : public SigVarBase { public: Signal(perm_string name, const VType*type, Expression*init_expr); int emit(std::ostream&out, Entity*ent, ScopeBase*scope, bool initalize = true); }; class Variable : public SigVarBase { public: Variable(perm_string name, const VType*type, Expression*init_expr = NULL); int emit(std::ostream&out, Entity*ent, ScopeBase*scope, bool initialize = true); void write_to_stream(std::ostream&fd); }; inline void SigVarBase::count_ref_sequ() { refcnt_sequ_ += 1; } inline Signal::Signal(perm_string name, const VType*type, Expression*init_expr) : SigVarBase(name, type, init_expr) { } inline Variable::Variable(perm_string name, const VType*type, Expression*init_expr) : SigVarBase(name, type, init_expr) { } #endif /* IVL_vsignal_H */ iverilog-12_0/vhdlpp/vtype.cc000066400000000000000000000227061435245347300163310ustar00rootroot00000000000000/* * Copyright (c) 2011 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 "vtype.h" # include "parse_types.h" # include "compiler.h" # include # include # include # include using namespace std; VType::~VType() { } void VType::show(ostream&out) const { write_to_stream(out); } perm_string VType::get_generic_typename() const { char buf[16] = {0,}; snprintf(buf, 16, "type_%p", this); return lex_strings.make(buf); } VTypePrimitive::VTypePrimitive(VTypePrimitive::type_t tt, bool packed) : type_(tt), packed_(packed) { } VTypePrimitive::~VTypePrimitive() { } void VTypePrimitive::show(ostream&out) const { switch (type_) { case BIT: out << "BIT"; break; case INTEGER: out << "INTEGER"; break; case NATURAL: out << "NATURAL"; break; case REAL: out << "REAL"; break; case STDLOGIC: out << "STD_LOGIC"; break; case TIME: out << "TIME"; break; } } int VTypePrimitive::get_width(ScopeBase*) const { switch(type_) { case BIT: case STDLOGIC: return 1; case INTEGER: case NATURAL: return 32; default: std::cerr << "sorry: primitive type " << type_ << " has no get_width() implementation." << std::endl; break; } return -1; } VTypeArray::range_t*VTypeArray::range_t::clone() const { return new VTypeArray::range_t(safe_clone(msb_), safe_clone(lsb_), direction_); } VTypeArray::VTypeArray(const VType*element, const vector&r, bool sv) : etype_(element), ranges_(r), signed_flag_(sv), parent_(NULL) { } /* * Create a VTypeArray range set from a list of parsed ranges. * FIXME: We are copying pointers from the ExpRange object into the * range_t. This means that we cannot delete the ExpRange object * unless we invent a way to remove the pointers from that object. So * this is a memory leak. Something to fix. */ VTypeArray::VTypeArray(const VType*element, std::list*r, bool sv) : etype_(element), ranges_(r->size()), signed_flag_(sv), parent_(NULL) { for (size_t idx = 0 ; idx < ranges_.size() ; idx += 1) { ExpRange*curp = r->front(); r->pop_front(); ranges_[idx] = range_t(curp->msb(), curp->lsb(), (curp->direction() == ExpRange::DOWNTO ? true : false)); } } VTypeArray::VTypeArray(const VType*element, int msb, int lsb, bool sv) : etype_(element), ranges_(1), signed_flag_(sv), parent_(NULL) { bool down_to = msb > lsb; ranges_[0] = range_t(new ExpInteger(msb), new ExpInteger(lsb), down_to); } VTypeArray::~VTypeArray() { } VType*VTypeArray::clone() const { std::vector new_ranges; new_ranges.reserve(ranges_.size()); for(std::vector::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) { new_ranges.push_back(*(it->clone())); } VTypeArray*a = new VTypeArray(etype_->clone(), new_ranges, signed_flag_); a->set_parent_type(parent_); return a; } const VType* VTypeArray::basic_type(bool typedef_allowed) const { const VType*t = etype_; const VTypeDef*tdef = NULL; bool progress = false; do { progress = false; if((tdef = dynamic_cast(t))) { t = tdef->peek_definition(); } if(const VTypeArray*arr = dynamic_cast(t)) { t = arr->element_type(); progress = true; } else if(tdef) { // return the typedef if it does not define an array t = typedef_allowed ? tdef : tdef->peek_definition(); } } while(progress); return t; } void VTypeArray::show(ostream&out) const { out << "array "; for (vector::const_iterator cur = ranges_.begin() ; cur != ranges_.end() ; ++cur) { out << "("; if (cur->msb()) cur->msb()->write_to_stream(out); else out << "<>"; out << " downto "; if (cur->lsb()) cur->lsb()->write_to_stream(out); else out << "<>"; out << ")"; } out << " of "; if (signed_flag_) out << "signed "; if (etype_) etype_->show(out); else out << ""; } int VTypeArray::get_width(ScopeBase*scope) const { int64_t size = 1; for(vector::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) { const VTypeArray::range_t&dim = *it; int64_t msb_val, lsb_val; if(dim.is_box()) return -1; if(!dim.msb()->evaluate(scope, msb_val)) return -1; if(!dim.lsb()->evaluate(scope, lsb_val)) return -1; size *= 1 + labs(msb_val - lsb_val); } return element_type()->get_width(scope) * size; } bool VTypeArray::is_unbounded() const { for(std::vector::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) { if(it->is_box()) return true; } return etype_->is_unbounded(); } bool VTypeArray::is_variable_length(ScopeBase*scope) const { int64_t dummy; if(is_unbounded()) return true; for(std::vector::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) { if(!it->lsb()->evaluate(scope, dummy)) return true; if(!it->msb()->evaluate(scope, dummy)) return true; } return etype_->is_variable_length(scope); } void VTypeArray::evaluate_ranges(ScopeBase*scope) { for(std::vector::iterator it = ranges_.begin(); it != ranges_.end(); ++it ) { int64_t lsb_val = -1, msb_val = -1; if(it->msb()->evaluate(scope, msb_val) && it->lsb()->evaluate(scope, lsb_val)) { assert(lsb_val >= 0); assert(msb_val >= 0); *it = range_t(new ExpInteger(msb_val), new ExpInteger(lsb_val), msb_val > lsb_val); } } } VTypeRange::VTypeRange(const VType*base) : base_(base) { } VTypeRange::~VTypeRange() { } VTypeRangeConst::VTypeRangeConst(const VType*base, int64_t start_val, int64_t end_val) : VTypeRange(base), start_(start_val), end_(end_val) { } VTypeRangeExpr::VTypeRangeExpr(const VType*base, Expression*start_expr, Expression*end_expr, bool downto) : VTypeRange(base), start_(start_expr), end_(end_expr), downto_(downto) { } VTypeRangeExpr::~VTypeRangeExpr() { delete start_; delete end_; } VType*VTypeRangeExpr::clone() const { return new VTypeRangeExpr(base_type()->clone(), start_->clone(), end_->clone(), downto_); } VTypeEnum::VTypeEnum(const std::list*names) : names_(names->size()) { size_t idx = 0; for (list::const_iterator cur = names->begin() ; cur != names->end() ; ++cur, ++idx) { names_[idx] = *cur; } } VTypeEnum::~VTypeEnum() { } void VTypeEnum::show(ostream&out) const { out << "("; if (names_.size() >= 1) out << names_[0]; for (size_t idx = 1 ; idx < names_.size() ; idx += 1) out << ", " << names_[idx]; out << ")"; } bool VTypeEnum::has_name(perm_string name) const { return std::find(names_.begin(), names_.end(), name) != names_.end(); } VTypeRecord::VTypeRecord(std::list*elements) : elements_(elements->size()) { for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) { elements_[idx] = elements->front(); elements->pop_front(); } delete elements; } VTypeRecord::~VTypeRecord() { for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) delete elements_[idx]; } void VTypeRecord::show(ostream&out) const { write_to_stream(out); } int VTypeRecord::get_width(ScopeBase*scope) const { int width = 0; for(vector::const_iterator it = elements_.begin(); it != elements_.end(); ++it) { int w = (*it)->peek_type()->get_width(scope); if(w < 0) return -1; width += w; } return width; } const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name, int*index) const { for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { element_t*curp = *cur; if (curp->peek_name() == name) { if (index) *index = std::distance(elements_.begin(), cur); return curp; } } return 0; } VTypeRecord::element_t::element_t(perm_string name, const VType*typ) : name_(name), type_(typ) { } VTypeDef::VTypeDef(perm_string nam) : name_(nam), type_(0) { } VTypeDef::VTypeDef(perm_string nam, const VType*typ) : name_(nam), type_(typ) { } VTypeDef::~VTypeDef() { } void VTypeDef::set_definition(const VType*typ) { assert(type_ == 0); type_ = typ; } iverilog-12_0/vhdlpp/vtype.h000066400000000000000000000330761435245347300161750ustar00rootroot00000000000000#ifndef IVL_vtype_H #define IVL_vtype_H /* * Copyright (c) 2011-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2014 / Stephen Williams (steve@icarus.com), * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 # include # include # include # include # include "StringHeap.h" class Architecture; class ScopeBase; class Entity; class Expression; class ExpRange; class VTypeDef; class ScopeBase; typedef enum typedef_topo_e { NONE=0, PENDING, MARKED } typedef_topo_t; typedef std::map typedef_context_t; /* * A description of a VHDL type consists of a graph of VType * objects. Derived types are specific kinds of types, and those that * are compound may in turn reference other types. */ class VType { public: VType() { } virtual ~VType() =0; virtual VType*clone() const =0; // This is rarely used, but some types may have expressions // that need to be elaborated. virtual int elaborate(Entity*end, ScopeBase*scope) const; // This virtual method returns true if that is equivalent to // this type. This method is used for example to compare // function prototypes. virtual bool type_match(const VType*that) const; // This virtual method writes a VHDL-accurate representation // of this type to the designated stream. This is used for // writing parsed types to library files. virtual void write_to_stream(std::ostream&fd) const; // This is like the above, but is the root function called // directly after the "type is..." when writing type // definitions. Most types accept the default definition of this. virtual void write_type_to_stream(std::ostream&fd) const; // Emits a type definition. This is used to distinguish types and // subtypes. virtual void write_typedef_to_stream(std::ostream&fd, perm_string name) const; // This virtual method writes a human-readable version of the // type to a given file for debug purposes. (Question: is this // really necessary given the write_to_stream method?) virtual void show(std::ostream&) const; // This virtual method emits a definition for the specific // type. It is used to emit typedef's. virtual int emit_def(std::ostream&out, perm_string name) const =0; // This virtual method causes VTypeDef types to emit typedefs // of themselves. The VTypeDef implementation of this method // uses this method recursively to do a depth-first emit of // all the types that it emits. virtual int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; // Determines if a type can be used in Verilog packed array. virtual bool can_be_packed() const { return false; } // Returns true if the type has an undefined dimension. virtual bool is_unbounded() const { return false; } // Checks if the variable length is dependent on other expressions, that // cannot be evaluated (e.g. 'length, 'left, 'right). virtual bool is_variable_length(ScopeBase*) const { return false; } // Returns a perm_string that can be used in automatically created // typedefs (i.e. not ones defined by the user). perm_string get_generic_typename() const; // Returns the type width in bits or negative number if it is impossible // to evaluate. virtual int get_width(ScopeBase*) const { return -1; } // This virtual method is called to emit the declaration. This // is used by the decl_t object to emit variable/wire/port declarations. virtual int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; public: // A couple places use the VType along with a few // per-declaration details, so provide a common structure for // holding that stuff together. struct decl_t { decl_t() : type(0), reg_flag(false) { } int emit(std::ostream&out, perm_string name) const; const VType*type; bool reg_flag; }; protected: inline void emit_name(std::ostream&out, perm_string name) const { if(name != empty_perm_string) out << " \\" << name << " "; } }; inline std::ostream&operator << (std::ostream&out, const VType&item) { item.show(out); return out; } extern void preload_global_types(void); /* * This type is a placeholder for ERROR types. */ class VTypeERROR : public VType { VType*clone() const { return NULL; } public: int emit_def(std::ostream&out, perm_string name) const; }; /* * This class represents the primitive types that are available to the * type subsystem. */ class VTypePrimitive : public VType { public: enum type_t { BIT, INTEGER, NATURAL, REAL, STDLOGIC, TIME }; public: explicit VTypePrimitive(type_t tt, bool packed = false); ~VTypePrimitive(); VType*clone() const { return new VTypePrimitive(*this); } bool type_match(const VType*that) const; void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int get_width(ScopeBase*scope) const; type_t type() const { return type_; } int emit_primitive_type(std::ostream&fd) const; int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return packed_; } private: type_t type_; bool packed_; }; /* * An array is a compound N-dimensional array of element type. The * construction of the array is from an element type and a vector of * ranges. The array type can be left incomplete by leaving some * ranges as "box" ranges, meaning present but not defined. */ class VTypeArray : public VType { public: class range_t { public: range_t(Expression*m = NULL, Expression*l = NULL, bool down_to = true) : msb_(m), lsb_(l), direction_(down_to) { } range_t*clone() const; inline bool is_box() const { return msb_==0 && lsb_==0; } inline bool is_downto() const { return direction_; } inline Expression* msb() const { return msb_; } inline Expression* lsb() const { return lsb_; } private: Expression* msb_; Expression* lsb_; bool direction_; }; public: VTypeArray(const VType*etype, const std::vector&r, bool signed_vector = false); VTypeArray(const VType*etype, std::list*r, bool signed_vector = false); VTypeArray(const VType*etype, int msb, int lsb, bool signed_vector = false); ~VTypeArray(); VType*clone() const; int elaborate(Entity*ent, ScopeBase*scope) const; bool type_match(const VType*that) const; void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int get_width(ScopeBase*scope) const; const std::vector&dimensions() const { return ranges_; }; const range_t&dimension(size_t idx) const { return ranges_[idx]; } inline bool signed_vector() const { return signed_flag_; } // returns the type of element held in the array inline const VType* element_type() const { return parent_ ? parent_->element_type() : etype_; } // returns the basic type of element held in the array // (unfolds typedefs and multidimensional arrays) // typedef_allowed decides if VTypeDef can be returned or should // it be unfolded const VType* basic_type(bool typedef_allowed = true) const; int emit_def(std::ostream&out, perm_string name) const; int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; bool can_be_packed() const { return etype_->can_be_packed(); } bool is_unbounded() const; bool is_variable_length(ScopeBase*scope) const; // To handle subtypes inline void set_parent_type(const VTypeArray*parent) { parent_ = parent; } const VTypeArray*get_parent_type() const { return parent_; } // Wherever it is possible, replaces range lsb & msb expressions with // constant integers. void evaluate_ranges(ScopeBase*scope); private: int emit_with_dims_(std::ostream&out, bool packed, perm_string name) const; // Handles a few special types of array (*_vector, string types). bool write_special_case(std::ostream&out) const; void write_range_to_stream_(std::ostream&fd) const; const VType*etype_; std::vector ranges_; bool signed_flag_; const VTypeArray*parent_; }; class VTypeRange : public VType { public: VTypeRange(const VType*base); virtual ~VTypeRange() = 0; bool write_std_types(std::ostream&fd) const; int emit_def(std::ostream&out, perm_string name) const; bool type_match(const VType*that) const; // Get the type that is limited by the range. inline const VType*base_type() const { return base_; } protected: const VType*base_; }; class VTypeRangeConst : public VTypeRange { public: VTypeRangeConst(const VType*base, int64_t end, int64_t start); VType*clone() const { return new VTypeRangeConst(base_type()->clone(), start_, end_); } int64_t start() const { return start_; } int64_t end() const { return end_; } void write_to_stream(std::ostream&fd) const; private: const int64_t start_, end_; }; class VTypeRangeExpr : public VTypeRange { public: VTypeRangeExpr(const VType*base, Expression*end, Expression*start, bool downto); ~VTypeRangeExpr(); VType*clone() const; int elaborate(Entity*end, ScopeBase*scope) const; public: // Virtual methods void write_to_stream(std::ostream&fd) const; private: // Boundaries Expression*start_, *end_; // Range direction (downto/to) bool downto_; }; class VTypeEnum : public VType { public: explicit VTypeEnum(const std::list*names); ~VTypeEnum(); VType*clone() const { return new VTypeEnum(*this); } void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int get_width(ScopeBase*) const { return 32; } int emit_def(std::ostream&out, perm_string name) const; int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; // Checks if the name is stored in the enum. bool has_name(perm_string name) const; private: std::vectornames_; }; class VTypeRecord : public VType { public: class element_t { public: element_t(perm_string name, const VType*type); void write_to_stream(std::ostream&) const; inline perm_string peek_name() const { return name_; } inline const VType* peek_type() const { return type_; } private: perm_string name_; const VType*type_; private:// Not implement element_t(const element_t&); element_t& operator= (const element_t); }; public: explicit VTypeRecord(std::list*elements); ~VTypeRecord(); VType*clone() const { return new VTypeRecord(*this); } void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int get_width(ScopeBase*scope) const; int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return true; } const element_t* element_by_name(perm_string name, int*index = NULL) const; inline const std::vector get_elements() const { return elements_; } private: std::vector elements_; }; class VTypeDef : public VType { public: explicit VTypeDef(perm_string name); explicit VTypeDef(perm_string name, const VType*is); virtual ~VTypeDef(); VType*clone() const { return new VTypeDef(*this); } bool type_match(const VType*that) const; inline perm_string peek_name() const { return name_; } // If the type is not given a definition in the constructor, // then this must be used to set the definition later. void set_definition(const VType*is); // In some situations, we only need the definition of the // type, and this method gets it for us. inline const VType* peek_definition(void) const { return type_; } virtual void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; int get_width(ScopeBase*scope) const { return type_->get_width(scope); } int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; int emit_def(std::ostream&out, perm_string name) const; int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; bool can_be_packed() const { return type_->can_be_packed(); } bool is_unbounded() const { return type_->is_unbounded(); } protected: perm_string name_; const VType*type_; }; class VSubTypeDef : public VTypeDef { public: explicit VSubTypeDef(perm_string name) : VTypeDef(name) {} explicit VSubTypeDef(perm_string name, const VType*is) : VTypeDef(name, is) {} void write_typedef_to_stream(std::ostream&fd, perm_string name) const; }; #endif /* IVL_vtype_H */ iverilog-12_0/vhdlpp/vtype_elaborate.cc000066400000000000000000000033541435245347300203450ustar00rootroot00000000000000/* * Copyright (c) 2013-2021 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "vtype.h" # include "expression.h" using namespace std; int VType::elaborate(Entity*, ScopeBase*) const { return 0; } int VTypeArray::elaborate(Entity*ent, ScopeBase*scope) const { int errors = 0; errors += etype_->elaborate(ent, scope); for (vector::const_iterator cur = ranges_.begin() ; cur != ranges_.end() ; ++ cur) { Expression*tmp = cur->msb(); if (tmp) errors += tmp->elaborate_expr(ent, scope, 0); tmp = cur->lsb(); if (tmp) errors += tmp->elaborate_expr(ent, scope, 0); } return errors; } int VTypeRangeExpr::elaborate(Entity*ent, ScopeBase*scope) const { int errors = 0; errors += base_->elaborate(ent, scope); errors += start_->elaborate_expr(ent, scope, 0); errors += end_->elaborate_expr(ent, scope, 0); return errors; } iverilog-12_0/vhdlpp/vtype_emit.cc000066400000000000000000000163711435245347300173500ustar00rootroot00000000000000/* * Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2014 CERN * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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 "vtype.h" # include "expression.h" # include "std_types.h" # include # include # include using namespace std; int VType::decl_t::emit(ostream&out, perm_string name) const { return type->emit_decl(out, name, reg_flag); } int VType::emit_decl(ostream&out, perm_string name, bool reg_flag) const { int errors = 0; if (!reg_flag) out << "wire "; errors += emit_def(out, name); out << " "; return errors; } int VType::emit_typedef(std::ostream&, typedef_context_t&) const { return 0; } int VTypeERROR::emit_def(ostream&out, perm_string) const { out << "/* ERROR */"; return 1; } int VTypeArray::emit_def(ostream&out, perm_string name) const { int errors = 0; const VType*raw_base = basic_type(); const VTypePrimitive*base = dynamic_cast (raw_base); if (base) { assert(dimensions().size() == 1); // If this is a string type without any boundaries specified, then // there is a direct counterpart in SV called.. 'string' if(this == &primitive_STRING) { out << "string"; emit_name(out, name); return errors; } base->emit_def(out, empty_perm_string); if (signed_flag_) out << " signed"; } else { raw_base->emit_def(out, empty_perm_string); } errors += emit_with_dims_(out, raw_base->can_be_packed(), name); return errors; } int VTypeArray::emit_typedef(std::ostream&out, typedef_context_t&ctx) const { return etype_->emit_typedef(out, ctx); } int VTypeArray::emit_with_dims_(std::ostream&out, bool packed, perm_string name) const { int errors = 0; list dims; const VTypeArray*cur = this; bool added_dim = true; while(added_dim) { added_dim = false; const VType*el_type = cur->element_type(); while(const VTypeDef*tdef = dynamic_cast(el_type)) { el_type = tdef->peek_definition(); } if(const VTypeArray*sub = dynamic_cast(el_type)) { dims.push_back(cur); cur = sub; added_dim = true; } } dims.push_back(cur); bool name_emitted = false; while (! dims.empty()) { cur = dims.front(); dims.pop_front(); if(!packed) { emit_name(out, name); name_emitted = true; } for(unsigned i = 0; i < cur->dimensions().size(); ++i) { if(cur->dimension(i).is_box() && !name_emitted) { emit_name(out, name); name_emitted = true; } out << "["; if (!cur->dimension(i).is_box()) { // if not unbounded errors += cur->dimension(i).msb()->emit(out, 0, 0); out << ":"; errors += cur->dimension(i).lsb()->emit(out, 0, 0); } out << "]"; } } if(!name_emitted) { emit_name(out, name); } return errors; } int VTypeEnum::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "enum int {"; assert(names_.size() >= 1); out << "\\" << names_[0] << " "; for (size_t idx = 1 ; idx < names_.size() ; idx += 1) out << ", \\" << names_[idx] << " "; out << "}"; emit_name(out, name); return errors; } int VTypeEnum::emit_decl(std::ostream&out, perm_string name, bool reg_flag) const { if (!reg_flag) out << "wire "; out << "int"; emit_name(out, name); return 0; } int VTypePrimitive::emit_primitive_type(ostream&out) const { int errors = 0; switch (type_) { case BIT: out << "bit"; break; case STDLOGIC: out << "logic"; break; case NATURAL: out << "int unsigned"; break; case INTEGER: out << "int"; break; case REAL: out << "real"; break; case TIME: out << "time"; break; default: assert(0); break; } return errors; } int VTypePrimitive::emit_def(ostream&out, perm_string name) const { int errors = 0; errors += emit_primitive_type(out); emit_name(out, name); return errors; } int VTypeRange::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "/* Internal error: Don't know how to emit range */"; errors += base_->emit_def(out, name); return errors; } int VTypeRecord::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "struct packed {"; for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { perm_string element_name = (*cur)->peek_name(); const VType*element_type = (*cur)->peek_type(); element_type->emit_def(out, empty_perm_string); out << " \\" << element_name << " ; "; } out << "}"; emit_name(out, name); return errors; } /* * For VTypeDef objects, use the name of the defined type as the * type. (We are defining a variable here, not the type itself.) The * emit_typedef() method was presumably called to define type already. */ int VTypeDef::emit_def(ostream&out, perm_string name) const { emit_name(out, name_); emit_name(out, name); return 0; } int VTypeDef::emit_decl(ostream&out, perm_string name, bool reg_flag) const { return type_->emit_decl(out, name, reg_flag); } int VTypeDef::emit_typedef(ostream&out, typedef_context_t&ctx) const { // The typedef_context_t is used by me to determine if this // typedef has already been emitted in this architecture. If // it has, then it is MARKED, give up. Otherwise, recurse the // emit_typedef to make sure all sub-types that I use have // been emitted, then emit my typedef. typedef_topo_t&flag = ctx[this]; switch (flag) { case MARKED: return 0; case PENDING: out << "typedef \\" << name_ << " ; /* typedef cycle? */" << endl; return 0; case NONE: break; } flag = PENDING; int errors = type_->emit_typedef(out, ctx); flag = MARKED; // Array types are used directly anyway and typedefs for unpacked // arrays do not work currently if(dynamic_cast(type_)) out << "// "; out << "typedef "; errors += type_->emit_def(out, name_); out << " ;" << endl; return errors; } iverilog-12_0/vhdlpp/vtype_match.cc000066400000000000000000000062141435245347300175010ustar00rootroot00000000000000/* * Copyright (c) 2013 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / 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 "vtype.h" bool VType::type_match(const VType*that) const { if(this == that) return true; if(const VTypeDef*tdef = dynamic_cast(that)) { if(type_match(tdef->peek_definition())) return true; } return false; } bool VTypeDef::type_match(const VType*that) const { if(VType::type_match(that)) return true; return type_->type_match(that); } bool VTypePrimitive::type_match(const VType*that) const { if(VType::type_match(that)) return true; if(const VTypePrimitive*prim = dynamic_cast(that)) { // TODO it is not always true, but works for many cases type_t that_type = prim->type(); return ((type_ == NATURAL || type_ == INTEGER) && (that_type == NATURAL || that_type == INTEGER)); } if(const VTypeRangeConst*range = dynamic_cast(that)) { if (type_ == INTEGER) return true; if (type_ == NATURAL && range->start() >= 0 && range->end() >= 0) return true; } return false; } bool VTypeArray::type_match(const VType*that) const { if(VType::type_match(that)) return true; // Check if both arrays are of the same size if(const VTypeArray*arr = dynamic_cast(that)) { const VTypeArray*this_parent = this; while(const VTypeArray*tmp = this_parent->get_parent_type()) this_parent = tmp; const VTypeArray*that_parent = arr; while(const VTypeArray*tmp = that_parent->get_parent_type()) that_parent = tmp; if(this_parent != that_parent) return false; int this_width = get_width(NULL); int that_width = arr->get_width(NULL); // Either one of the sizes is undefined, or both are the same size if(this_width > 0 && that_width > 0 && this_width != that_width) return false; return true; } return false; } bool VTypeRange::type_match(const VType*that) const { if(VType::type_match(that)) return true; if(base_->type_match(that)) return true; return false; } iverilog-12_0/vhdlpp/vtype_stream.cc000066400000000000000000000136131435245347300177010ustar00rootroot00000000000000/* * Copyright (c) 2011 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. */ # define __STDC_LIMIT_MACROS # include "std_types.h" # include "expression.h" # include # include # include using namespace std; void VType::write_to_stream(ostream&fd) const { fd << "/* UNKNOWN TYPE: " << typeid(*this).name() << " */"; } void VType::write_type_to_stream(ostream&fd) const { write_to_stream(fd); } void VType::write_typedef_to_stream(ostream&fd, perm_string name) const { if(is_global_type(name)) return; fd << "type " << name << " is "; write_type_to_stream(fd); fd << ";" << endl; } void VTypeArray::write_to_stream(ostream&fd) const { if(write_special_case(fd)) return; bool typedefed = false; if(const VTypeDef*tdef = dynamic_cast(etype_)) { tdef->write_to_stream(fd); typedefed = true; } else { fd << "array "; } if (! ranges_.empty()) { assert(ranges_.size() < 2); if (ranges_[0].is_box()) { fd << "(INTEGER range <>) "; } else { write_range_to_stream_(fd); } } if(!typedefed) { fd << "of "; etype_->write_to_stream(fd); } } void VTypeArray::write_range_to_stream_(std::ostream&fd) const { assert(ranges_.size() < 2); assert(ranges_[0].msb() && ranges_[0].lsb()); fd << "("; if (ranges_[0].msb()) ranges_[0].msb()->write_to_stream(fd); else fd << "<>"; fd << (ranges_[0].is_downto() ? " downto " : " to "); if (ranges_[0].lsb()) ranges_[0].lsb()->write_to_stream(fd); else fd << "<>"; fd << ") "; } bool VTypeArray::write_special_case(std::ostream&fd) const { if(this == &primitive_SIGNED) { fd << "signed"; } else if(this == &primitive_UNSIGNED) { fd << "unsigned"; } else if(etype_ == &primitive_STDLOGIC) { fd << "std_logic_vector"; } else if(etype_ == &primitive_BIT) { fd << "bit_vector"; } else if(etype_ == &primitive_CHARACTER) { fd << "string"; } else { return false; } if(!ranges_.empty() && !ranges_[0].is_box()) { write_range_to_stream_(fd); } return true; } void VTypeArray::write_type_to_stream(ostream&fd) const { if(write_special_case(fd)) return; fd << "array "; // Unbounded array if (! ranges_.empty()) { assert(ranges_.size() < 2); if (ranges_[0].is_box()) { fd << "(INTEGER range <>) "; } else { write_range_to_stream_(fd); } } fd << "of "; if(const VTypeDef*tdef = dynamic_cast(etype_)) { tdef->write_to_stream(fd); } else { etype_->write_to_stream(fd); } } void VTypeDef::write_type_to_stream(ostream&fd) const { type_->write_type_to_stream(fd); } void VTypeDef::write_to_stream(ostream&fd) const { fd << name_; } void VTypePrimitive::write_to_stream(ostream&fd) const { switch (type_) { case BIT: fd << "bit"; break; case INTEGER: fd << "integer"; break; case NATURAL: fd << "natural"; break; case REAL: fd << "real"; break; case STDLOGIC: fd << "std_logic"; break; case TIME: fd << "time"; break; default: assert(0); fd << "/* PRIMITIVE: " << type_ << " */"; break; } } bool VTypeRange::write_std_types(ostream&fd) const { // Detect some special cases that can be written as ieee or // standard types. if (const VTypePrimitive*tmp = dynamic_cast(base_)) { if (tmp->type()==VTypePrimitive::NATURAL) { fd << "natural"; return true; } } return false; } void VTypeRangeConst::write_to_stream(ostream&fd) const { if(write_std_types(fd)) return; base_type()->write_to_stream(fd); fd << " range " << start_; fd << (start_ < end_ ? " to " : " downto "); fd << end_; } void VTypeRangeExpr::write_to_stream(ostream&fd) const { if(write_std_types(fd)) return; base_type()->write_to_stream(fd); fd << " range "; start_->write_to_stream(fd); fd << (downto_ ? " downto " : " to "); end_->write_to_stream(fd); } void VTypeRecord::write_to_stream(ostream&fd) const { fd << "record "; for (size_t idx = 0 ; idx < elements_.size() ; idx += 1) { elements_[idx]->write_to_stream(fd); fd << "; "; } fd << "end record"; } void VTypeRecord::element_t::write_to_stream(ostream&fd) const { fd << name_ << ": "; type_->write_to_stream(fd); } void VTypeEnum::write_to_stream(std::ostream&fd) const { fd << "("; for (vector::const_iterator it = names_.begin(); it != names_.end(); ++it) { if(it != names_.begin()) fd << ","; fd << *it; } fd << ")"; } void VSubTypeDef::write_typedef_to_stream(ostream&fd, perm_string name) const { if(is_global_type(name)) return; fd << "subtype " << name << " is "; write_type_to_stream(fd); fd << ";" << endl; } iverilog-12_0/vpi.txt000066400000000000000000000040541435245347300147110ustar00rootroot00000000000000 HOW IT WORKS 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 iverilog-vpi documentation. 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-12_0/vpi/000077500000000000000000000000001435245347300141455ustar00rootroot00000000000000iverilog-12_0/vpi/Makefile.in000066400000000000000000000163441435245347300162220ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ includedir = $(prefix)/include vpidir = $(libdir)/ivl$(suffix) CC = @CC@ CXX = @CXX@ AR = @AR@ RANLIB = @RANLIB@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ YACC = @YACC@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @file64_support@ @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const @PICFLAG@ CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @LDFLAGS@ # Object files for system.vpi O = sys_table.o sys_convert.o sys_countdrivers.o sys_darray.o sys_deposit.o \ sys_display.o \ sys_fileio.o sys_finish.o sys_icarus.o sys_plusargs.o sys_queue.o \ sys_random.o sys_random_mti.o sys_readmem.o sys_readmem_lex.o sys_scanf.o \ sys_sdf.o sys_time.o sys_vcd.o sys_vcdoff.o vcd_priv.o mt19937int.o \ sys_priv.o sdf_parse.o sdf_lexor.o stringheap.o vams_simparam.o \ table_mod.o table_mod_parse.o table_mod_lexor.o OPP = vcd_priv2.o ifeq (@HAVE_LIBZ@,yes) ifeq (@HAVE_LIBBZ2@,yes) O += sys_lxt.o lxt_write.o endif O += sys_lxt2.o lxt2_write.o O += sys_fst.o fstapi.o fastlz.o lz4.o endif # Object files for v2005_math.vpi V2005 = sys_clog2.o v2005_math.o # Object files for va_math.vpi VA_MATH = va_math.o V2009 = v2009_table.o v2009_array.o v2009_bitvec.o v2009_enum.o v2009_string.o \ sys_priv.o VHDL_SYS = vhdl_table.o sys_priv.o VHDL_TEXTIO = vhdl_textio.o sys_priv.o VPI_DEBUG = vpi_debug.o all: dep libvpi.a system.vpi va_math.vpi v2005_math.vpi v2009.vpi vhdl_sys.vpi vhdl_textio.vpi vpi_debug.vpi $(ALL32) check: all clean: rm -rf *.o sys_readmem_lex.c dep libvpi.a system.vpi rm -f sdf_lexor.c sdf_parse.c sdf_parse.output sdf_parse.h rm -f table_mod_parse.c table_mod_parse.h table_mod_parse.output rm -f table_mod_lexor.c rm -f va_math.vpi v2005_math.vpi v2009.vpi vhdl_sys.vpi vhdl_textio.vpi vpi_debug.vpi distclean: clean rm -f Makefile config.log rm -f vpi_config.h stamp-vpi_config-h # The -U flag is used to skip checking paths that depend on that define having # an explicit value (i.e. the define is expected to be real code). cppcheck: $(O:.o=.c) $(OPP:.o=.cc) $(M:.o=.c) $(V:.o=.c) cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ -UYY_USER_INIT \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYLTYPE -UYYSTYPE -U__SIZE_TYPE__ -Umalloc -Usize_t -Ufree \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in ../config.status cd ..; ./config.status --file=vpi/$@ dep: mkdir dep %.o: %.c vpi_config.h $(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep %.o: %.cc vpi_config.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep libvpi.a: libvpi.c ../vpi_user.h $(CC) $(CPPFLAGS) $(CFLAGS) -c $< rm -f libvpi.a $(AR) cqv libvpi.a libvpi.o $(RANLIB) libvpi.a LIBS = @LIBS@ SYSTEM_VPI_LDFLAGS = $(LIBS) VA_MATH_LDFLAGS = ifeq (@MINGW32@,yes) SYSTEM_VPI_LDFLAGS += @EXTRALIBS@ VA_MATH_LDFLAGS += @EXTRALIBS@ endif system.vpi: $O $(OPP) libvpi.a $(CXX) @shared@ -o $@ $O $(OPP) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS) sys_readmem_lex.c: $(srcdir)/sys_readmem_lex.lex $(LEX) -t $< > $@ sdf_lexor.o: sdf_lexor.c sdf_parse.h sdf_lexor.c: $(srcdir)/sdf_lexor.lex $(LEX) -t $< > $@ # Use pattern rules to avoid parallel build issues (see pr3462585) sdf_parse%c sdf_parse%h: $(srcdir)/sdf_parse%y $(YACC) --verbose -t -p sdf -d -o sdf_parse.c $< table_mod_lexor.o: table_mod_lexor.c table_mod_parse.h table_mod_lexor.c: $(srcdir)/table_mod_lexor.lex $(LEX) -t $< > $@ # Use pattern rules to avoid parallel build issues (see pr3462585) table_mod_parse%c table_mod_parse%h: $(srcdir)/table_mod_parse%y $(YACC) --verbose -t -p tblmod -d -o table_mod_parse.c $< v2005_math.vpi: $(V2005) libvpi.a $(CC) @shared@ -o $@ $(V2005) -L. $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS) v2009.vpi: $(V2009) libvpi.a $(CC) @shared@ -o $@ $(V2009) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS) va_math.vpi: $(VA_MATH) libvpi.a $(CC) @shared@ -o $@ $(VA_MATH) -L. $(LDFLAGS) -lvpi $(VA_MATH_VPI_LDFLAGS) vhdl_sys.vpi: $(VHDL_SYS) libvpi.a $(CC) @shared@ -o $@ $(VHDL_SYS) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS) vhdl_textio.vpi: $(VHDL_TEXTIO) libvpi.a $(CC) @shared@ -o $@ $(VHDL_TEXTIO) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS) vpi_debug.vpi: $(VPI_DEBUG) libvpi.a $(CC) @shared@ -o $@ $(VPI_DEBUG) -L. $(LDFLAGS) -lvpi $(SYSTEM_VPI_LDFLAGS) stamp-vpi_config-h: $(srcdir)/vpi_config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=vpi/vpi_config.h vpi_config.h: stamp-vpi_config-h install: all installdirs installfiles F = ./libvpi.a \ ./system.vpi \ ./va_math.vpi \ ./v2005_math.vpi \ ./v2009.vpi \ ./vhdl_sys.vpi \ ./vhdl_textio.vpi \ ./vpi_debug.vpi installfiles: $(F) | installdirs $(INSTALL_DATA) ./libvpi.a "$(DESTDIR)$(libdir)/libvpi$(suffix).a" $(INSTALL_PROGRAM) ./system.vpi "$(DESTDIR)$(vpidir)/system.vpi" $(INSTALL_PROGRAM) ./va_math.vpi "$(DESTDIR)$(vpidir)/va_math.vpi" $(INSTALL_PROGRAM) ./v2005_math.vpi "$(DESTDIR)$(vpidir)/v2005_math.vpi" $(INSTALL_PROGRAM) ./v2009.vpi "$(DESTDIR)$(vpidir)/v2009.vpi" $(INSTALL_PROGRAM) ./vhdl_sys.vpi "$(DESTDIR)$(vpidir)/vhdl_sys.vpi" $(INSTALL_PROGRAM) ./vhdl_textio.vpi "$(DESTDIR)$(vpidir)/vhdl_textio.vpi" $(INSTALL_PROGRAM) ./vpi_debug.vpi "$(DESTDIR)$(vpidir)/vpi_debug.vpi" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)" "$(DESTDIR)$(vpidir)" uninstall: rm -f "$(DESTDIR)$(libdir)/libvpi$(suffix).a" rm -f "$(DESTDIR)$(vpidir)/system.vpi" rm -f "$(DESTDIR)$(vpidir)/va_math.vpi" rm -f "$(DESTDIR)$(vpidir)/v2005_math.vpi" rm -f "$(DESTDIR)$(vpidir)/v2009.vpi" rm -f "$(DESTDIR)$(vpidir)/vhdl_sys.vpi" rm -f "$(DESTDIR)$(vpidir)/vhdl_textio.vpi" rm -f "$(DESTDIR)$(vpidir)/vpi_debug.vpi" -include $(patsubst %.o, dep/%.d, $O) -include $(patsubst %.o, dep/%.d, $(OPP)) -include $(patsubst %.o, dep/%.d, $(V2005)) -include $(patsubst %.o, dep/%.d, $(VA_MATH)) -include $(patsubst %.o, dep/%.d, $(V2009)) -include $(patsubst %.o, dep/%.d, $(VHDL_SYS)) -include $(patsubst %.o, dep/%.d, $(VHDL_TEXTIO)) -include $(patsubst %.o, dep/%.d, $(VPI_DEBUG)) iverilog-12_0/vpi/cppcheck.sup000066400000000000000000000233421435245347300164620ustar00rootroot00000000000000// The following three files are copied directly from GTKWave and we do not // have control over them. Tony has a specific programming style so these // problems will not be fixed. // fstapi.c from GTKWave asctimeCalled:fstapi.c:955 allocaCalled:fstapi.c:2386 unreadVariable:fstapi.c:204 unreadVariable:fstapi.c:205 unreadVariable:fstapi.c:1645 unreadVariable:fstapi.c:1653 unreadVariable:fstapi.c:1657 unreadVariable:fstapi.c:1662 unreadVariable:fstapi.c:1685 unreadVariable:fstapi.c:1691 unreadVariable:fstapi.c:1692 unreadVariable:fstapi.c:1696 unreadVariable:fstapi.c:2818 unreadVariable:fstapi.c:6521 variableScope:fstapi.c:684 variableScope:fstapi.c:1078 variableScope:fstapi.c:1385 variableScope:fstapi.c:1386 variableScope:fstapi.c:1387 variableScope:fstapi.c:1444 variableScope:fstapi.c:2056 variableScope:fstapi.c:2189 variableScope:fstapi.c:2622 variableScope:fstapi.c:2623 variableScope:fstapi.c:2812 variableScope:fstapi.c:2813 variableScope:fstapi.c:2814 variableScope:fstapi.c:2815 variableScope:fstapi.c:2816 variableScope:fstapi.c:2817 variableScope:fstapi.c:2818 variableScope:fstapi.c:2919 variableScope:fstapi.c:2920 variableScope:fstapi.c:2924 variableScope:fstapi.c:3161 variableScope:fstapi.c:3200 variableScope:fstapi.c:3201 variableScope:fstapi.c:3920 variableScope:fstapi.c:4098 variableScope:fstapi.c:4100 variableScope:fstapi.c:4542 variableScope:fstapi.c:4543 variableScope:fstapi.c:4552 variableScope:fstapi.c:4815 variableScope:fstapi.c:5086 variableScope:fstapi.c:5089 variableScope:fstapi.c:5585 variableScope:fstapi.c:5589 variableScope:fstapi.c:5590 variableScope:fstapi.c:5748 variableScope:fstapi.c:5806 variableScope:fstapi.c:6119 variableScope:fstapi.c:6122 variableScope:fstapi.c:6416 variableScope:fstapi.c:6521 variableScope:fstapi.c:6522 variableScope:fstapi.c:6553 variableScope:fstapi.c:6781 variableScope:fstapi.c:6957 variableScope:fstapi.c:6958 variableScope:fstapi.c:6959 // These functions are not used by Icarus // fstReaderClrFacProcessMask() unusedFunction:fstapi.c:3652 // fstReaderClrFacProcessMaskAll() unusedFunction:fstapi.c:3681 // fstReaderGetAliasCount() unusedFunction:fstapi.c:3744 // fstReaderGetCurrentFlatScope() unusedFunction:fstapi.c:3490 // fstReaderGetCurrentScopeLen() unusedFunction:fstapi.c:3587 // fstReaderGetCurrentScopeUserInfo() unusedFunction:fstapi.c:3504 // fstReaderGetDateString() unusedFunction:fstapi.c:3772 // fstReaderGetDoubleEndianMatchState() unusedFunction:fstapi.c:3758 // fstReaderGetDumpActivityChangeTime() unusedFunction:fstapi.c:3800 // fstReaderGetDumpActivityChangeValue() unusedFunction:fstapi.c:3815 // fstReaderGetEndTime() unusedFunction:fstapi.c:3709 // fstReaderGetFacProcessMask() unusedFunction:fstapi.c:3615 // fstReaderGetFileType() unusedFunction:fstapi.c:3779 // fstReaderGetFseekFailed() unusedFunction:fstapi.c:3600 // fstReaderGetMaxHandle() unusedFunction:fstapi.c:3737 // fstReaderGetMemoryUsedByWriter() unusedFunction:fstapi.c:3716 // fstReaderGetNumberDumpActivityChanges() unusedFunction:fstapi.c:3793 // fstReaderGetScopeCount() unusedFunction:fstapi.c:3723 // fstReaderGetStartTime() unusedFunction:fstapi.c:3702 // fstReaderGetTimescale() unusedFunction:fstapi.c:3695 // fstReaderGetTimezero() unusedFunction:fstapi.c:3786 // fstReaderGetValueChangeSectionCount() unusedFunction:fstapi.c:3751 // fstReaderGetValueFromHandleAtTime() unusedFunction:fstapi.c:6001 // fstReaderGetVarCount() unusedFunction:fstapi.c:3730 // fstReaderGetVersionString() unusedFunction:fstapi.c:3765 // fstReaderIterBlocks() unusedFunction:fstapi.c:4964 // fstReaderIterBlocksSetNativeDoublesOnCallback() unusedFunction:fstapi.c:3865 // fstReaderIterateHier() unusedFunction:fstapi.c:4094 // fstReaderIterateHierRewind() unusedFunction:fstapi.c:4074 // fstReaderOpen() unusedFunction:fstapi.c:4862 // fstReaderOpenForUtilitiesOnly() unusedFunction:fstapi.c:4854 // fstReaderPushScope() unusedFunction:fstapi.c:3552 // fstReaderResetScope() unusedFunction:fstapi.c:3541 // fstReaderSetFacProcessMask() unusedFunction:fstapi.c:3634 // fstReaderSetFacProcessMaskAll() unusedFunction:fstapi.c:3670 // fstReaderSetLimitTimeRange() unusedFunction:fstapi.c:3830 // fstReaderSetUnlimitedTimeRange() unusedFunction:fstapi.c:3843 // fstReaderSetVcdExtensions() unusedFunction:fstapi.c:3854 // fstUtilityExtractEnumTableFromString() unusedFunction:fstapi.c:6954 // fstUtilityFreeEnumTable() unusedFunction:fstapi.c:7015 // fstWriterCreateEnumTable() unusedFunction:fstapi.c:2807 // fstWriterCreateVar2() unusedFunction:fstapi.c:2609 // fstWriterEmitEnumTableRef() unusedFunction:fstapi.c:2902 // fstWriterEmitValueChangeVec32() unusedFunction:fstapi.c:3054 // fstWriterEmitValueChangeVec64() unusedFunction:fstapi.c:3103 // fstWriterEmitVariableLengthValueChange() unusedFunction:fstapi.c:3154 // fstWriterGetFseekFailed() unusedFunction:fstapi.c:2592 // fstWriterSetAttrEnd() unusedFunction:fstapi.c:2795 // fstWriterSetComment() unusedFunction:fstapi.c:2441 // fstWriterSetEnvVar() unusedFunction:fstapi.c:2453 // fstWriterSetFileType() unusedFunction:fstapi.c:2316 // fstWriterSetParallelMode() unusedFunction:fstapi.c:2552 // fstWriterSetTimezero() unusedFunction:fstapi.c:2517 // fstWriterSetValueList() unusedFunction:fstapi.c:2447 // lxt2_write.c from GTKWave allocaCalled:lxt2_write.c:1813 allocaCalled:lxt2_write.c:1819 variableScope:lxt2_write.c:33 variableScope:lxt2_write.c:63 variableScope:lxt2_write.c:196 variableScope:lxt2_write.c:463 variableScope:lxt2_write.c:464 variableScope:lxt2_write.c:523 variableScope:lxt2_write.c:581 variableScope:lxt2_write.c:587 variableScope:lxt2_write.c:1157 variableScope:lxt2_write.c:1613 variableScope:lxt2_write.c:2060 // These functions are not used by Icarus // lxt2_wr_emit_value_int() unusedFunction:lxt2_write.c:1611 // lxt2_wr_inc_time_by_delta() unusedFunction:lxt2_write.c:997 // lxt2_wr_inc_time_by_delta64() unusedFunction:lxt2_write.c:1007 // lxt2_wr_set_checkpoint_off() unusedFunction:lxt2_write.c:835 // lxt2_wr_set_checkpoint_on() unusedFunction:lxt2_write.c:843 // lxt2_wr_set_maxgranule() unusedFunction:lxt2_write.c:1567 // lxt2_wr_set_partial_preference() unusedFunction:lxt2_write.c:812 // lxt2_wr_set_timezero() unusedFunction:lxt2_write.c:2201 // lxt2_wr_symbol_bracket_stripping() unusedFunction:lxt2_write.c:1581 // lxt2_wr_symbol_find() unusedFunction:lxt2_write.c:877 // lxt_write.c from GTKWave shiftNegative:lxt_write.c:2700 shiftNegative:lxt_write.c:2744 variableScope:lxt_write.c:31 variableScope:lxt_write.c:83 variableScope:lxt_write.c:527 variableScope:lxt_write.c:528 variableScope:lxt_write.c:587 variableScope:lxt_write.c:640 variableScope:lxt_write.c:780 variableScope:lxt_write.c:880 variableScope:lxt_write.c:1056 variableScope:lxt_write.c:1057 variableScope:lxt_write.c:1058 variableScope:lxt_write.c:1194 variableScope:lxt_write.c:1850 variableScope:lxt_write.c:2029 variableScope:lxt_write.c:2030 variableScope:lxt_write.c:2147 variableScope:lxt_write.c:2148 variableScope:lxt_write.c:2265 variableScope:lxt_write.c:2266 variableScope:lxt_write.c:2595 variableScope:lxt_write.c:2596 variableScope:lxt_write.c:2597 variableScope:lxt_write.c:2598 // These functions are not used by Icarus // lt_emit_value_int() unusedFunction:lxt_write.c:1661 // lt_emit_value_string() unusedFunction:lxt_write.c:2144 // lt_inc_time_by_delta() unusedFunction:lxt_write.c:1374 // lt_inc_time_by_delta64() unusedFunction:lxt_write.c:1384 // lt_set_chg_compress() unusedFunction:lxt_write.c:1457 // lt_set_dict_compress() unusedFunction:lxt_write.c:1474 // lt_set_time() unusedFunction:lxt_write.c:1379 // lt_set_timezero() unusedFunction:lxt_write.c:2820 // lt_symbol_bracket_stripping() unusedFunction:lxt_write.c:1585 // lt_symbol_find() unusedFunction:lxt_write.c:1277 // fastlz.c from GTKWave unreadVariable:fastlz.c:423 unusedLabel:fastlz.c:545 // These functions are not used by Icarus // fastlz_compress_level() unusedFunction:fastlz.c:152 // FASTLZ_COMPRESSOR() unusedFunction:fastlz.c:164 // FASTLZ_DECOMPRESSOR() unusedFunction:fastlz.c:418 // lz4.c from GTKWave unusedStructMember:lz4.c:140 // These functions are not used by Icarus // LZ4_compress_continue() unusedFunction:lz4.c:1465 // LZ4_compress_destSize() unusedFunction:lz4.c:917 // LZ4_compress_fast_force() unusedFunction:lz4.c:710 // LZ4_compress_forceExtDict() unusedFunction:lz4.c:1068 // LZ4_compress_limitedOutput() unusedFunction:lz4.c:1460 // LZ4_compress_limitedOutput_continue() unusedFunction:lz4.c:1464 // LZ4_compress_limitedOutput_withState() unusedFunction:lz4.c:1462 // LZ4_compress_withState() unusedFunction:lz4.c:1463 // LZ4_create() unusedFunction:lz4.c:1494 // LZ4_createStream() unusedFunction:lz4.c:940 // LZ4_createStreamDecode() unusedFunction:lz4.c:1324 // LZ4_decompress_fast_continue() unusedFunction:lz4.c:1389 // LZ4_decompress_fast_usingDict() unusedFunction:lz4.c:1444 // LZ4_decompress_fast_withPrefix64k() unusedFunction:lz4.c:1515 // LZ4_decompress_safe_continue() unusedFunction:lz4.c:1360 // LZ4_decompress_safe_forceExtDict() unusedFunction:lz4.c:1450 // LZ4_decompress_safe_usingDict() unusedFunction:lz4.c:1439 // LZ4_decompress_safe_withPrefix64k() unusedFunction:lz4.c:1510 // LZ4_freeStream() unusedFunction:lz4.c:953 // LZ4_freeStreamDecode() unusedFunction:lz4.c:1330 // LZ4_loadDict() unusedFunction:lz4.c:961 // LZ4_resetStreamState() unusedFunction:lz4.c:1487 // LZ4_setStreamDecode() unusedFunction:lz4.c:1343 // LZ4_sizeofState() unusedFunction:lz4.c:378 // LZ4_sizeofStreamState() unusedFunction:lz4.c:1479 // LZ4_slideInputBuffer() unusedFunction:lz4.c:1501 // LZ4_uncompress() unusedFunction:lz4.c:1473 // LZ4_uncompress_unknownOutputSize() unusedFunction:lz4.c:1474 // LZ4_versionNumber() unusedFunction:lz4.c:376 // The routines in sys_random.c are exact copies from IEEE1364-2005 and // they have scope warnings that we need to ignore. variableScope:sys_random.c:46 variableScope:sys_random.c:69 variableScope:sys_random.c:92 variableScope:sys_random.c:147 iverilog-12_0/vpi/fastlz.c000066400000000000000000000323711435245347300156220ustar00rootroot00000000000000/* FastLZ - lightning-fast lossless compression library Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SPDX-License-Identifier: MIT */ #include "fastlz.h" #if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) /* * Always check for bound when decompressing. * Generally it is best to leave it defined. */ #define FASTLZ_SAFE /* * Give hints to the compiler for branch prediction optimization. */ #if defined(__GNUC__) && (__GNUC__ > 2) #define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) #define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) #else #define FASTLZ_EXPECT_CONDITIONAL(c) (c) #define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) #endif /* * Use inlined functions for supported systems. */ #if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) #define FASTLZ_INLINE inline #elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) #define FASTLZ_INLINE __inline #else #define FASTLZ_INLINE #endif /* * Prevent accessing more than 8-bit at once, except on x86 architectures. */ #if !defined(FASTLZ_STRICT_ALIGN) #define FASTLZ_STRICT_ALIGN #if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ #undef FASTLZ_STRICT_ALIGN #elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */ #undef FASTLZ_STRICT_ALIGN #elif defined(_M_IX86) /* Intel, MSVC */ #undef FASTLZ_STRICT_ALIGN #elif defined(__386) #undef FASTLZ_STRICT_ALIGN #elif defined(_X86_) /* MinGW */ #undef FASTLZ_STRICT_ALIGN #elif defined(__I86__) /* Digital Mars */ #undef FASTLZ_STRICT_ALIGN #endif #endif /* prototypes */ int fastlz_compress(const void* input, int length, void* output); int fastlz_compress_level(int level, const void* input, int length, void* output); int fastlz_decompress(const void* input, int length, void* output, int maxout); #define MAX_COPY 32 #define MAX_LEN 264 /* 256 + 8 */ #define MAX_DISTANCE 8192 #if !defined(FASTLZ_STRICT_ALIGN) #define FASTLZ_READU16(p) *((const flzuint16*)(p)) #else #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) #endif #define HASH_LOG 13 #define HASH_SIZE (1<< HASH_LOG) #define HASH_MASK (HASH_SIZE-1) #define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } #undef FASTLZ_LEVEL #define FASTLZ_LEVEL 1 #undef FASTLZ_COMPRESSOR #undef FASTLZ_DECOMPRESSOR #define FASTLZ_COMPRESSOR fastlz1_compress #define FASTLZ_DECOMPRESSOR fastlz1_decompress static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); #include "fastlz.c" #undef FASTLZ_LEVEL #define FASTLZ_LEVEL 2 #undef MAX_DISTANCE #define MAX_DISTANCE 8191 #define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) #undef FASTLZ_COMPRESSOR #undef FASTLZ_DECOMPRESSOR #define FASTLZ_COMPRESSOR fastlz2_compress #define FASTLZ_DECOMPRESSOR fastlz2_decompress static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); #include "fastlz.c" int fastlz_compress(const void* input, int length, void* output) { /* for short block, choose fastlz1 */ if(length < 65536) return fastlz1_compress(input, length, output); /* else... */ return fastlz2_compress(input, length, output); } int fastlz_decompress(const void* input, int length, void* output, int maxout) { /* magic identifier for compression level */ int level = ((*(const flzuint8*)input) >> 5) + 1; if(level == 1) return fastlz1_decompress(input, length, output, maxout); if(level == 2) return fastlz2_decompress(input, length, output, maxout); /* unknown level, trigger error */ return 0; } int fastlz_compress_level(int level, const void* input, int length, void* output) { if(level == 1) return fastlz1_compress(input, length, output); if(level == 2) return fastlz2_compress(input, length, output); return 0; } #else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) { const flzuint8* ip = (const flzuint8*) input; const flzuint8* ip_bound = ip + length - 2; const flzuint8* ip_limit = ip + length - 12; flzuint8* op = (flzuint8*) output; const flzuint8* htab[HASH_SIZE]; const flzuint8** hslot; flzuint32 hval; flzuint32 copy; /* sanity check */ if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) { if(length) { /* create literal copy only */ *op++ = length-1; ip_bound++; while(ip <= ip_bound) *op++ = *ip++; return length+1; } else return 0; } /* initializes hash table */ for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) *hslot = ip; /* we start with literal copy */ copy = 2; *op++ = MAX_COPY-1; *op++ = *ip++; *op++ = *ip++; /* main loop */ while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) { const flzuint8* ref; flzuint32 distance; /* minimum match length */ flzuint32 len = 3; /* comparison starting-point */ const flzuint8* anchor = ip; /* check for a run */ #if FASTLZ_LEVEL==2 if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) { distance = 1; /* ip += 3; */ /* scan-build, never used */ ref = anchor - 1 + 3; goto match; } #endif /* find potential match */ HASH_FUNCTION(hval,ip); hslot = htab + hval; ref = htab[hval]; /* calculate distance to the match */ distance = anchor - ref; /* update hash table */ *hslot = anchor; /* is this a match? check the first 3 bytes */ if(distance==0 || #if FASTLZ_LEVEL==1 (distance >= MAX_DISTANCE) || #else (distance >= MAX_FARDISTANCE) || #endif *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) goto literal; #if FASTLZ_LEVEL==2 /* far, needs at least 5-byte match */ if(distance >= MAX_DISTANCE) { if(*ip++ != *ref++ || *ip++!= *ref++) goto literal; len += 2; } match: #endif /* last matched byte */ ip = anchor + len; /* distance is biased */ distance--; if(!distance) { /* zero distance means a run */ flzuint8 x = ip[-1]; while(ip < ip_bound) if(*ref++ != x) break; else ip++; } else for(;;) { /* safe because the outer check against ip limit */ if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; while(ip < ip_bound) if(*ref++ != *ip++) break; break; } /* if we have copied something, adjust the copy count */ if(copy) /* copy is biased, '0' means 1 byte copy */ *(op-copy-1) = copy-1; else /* back, to overwrite the copy count */ op--; /* reset literal counter */ copy = 0; /* length is biased, '1' means a match of 3 bytes */ ip -= 3; len = ip - anchor; /* encode the match */ #if FASTLZ_LEVEL==2 if(distance < MAX_DISTANCE) { if(len < 7) { *op++ = (len << 5) + (distance >> 8); *op++ = (distance & 255); } else { *op++ = (7 << 5) + (distance >> 8); for(len-=7; len >= 255; len-= 255) *op++ = 255; *op++ = len; *op++ = (distance & 255); } } else { /* far away, but not yet in the another galaxy... */ if(len < 7) { distance -= MAX_DISTANCE; *op++ = (len << 5) + 31; *op++ = 255; *op++ = distance >> 8; *op++ = distance & 255; } else { distance -= MAX_DISTANCE; *op++ = (7 << 5) + 31; for(len-=7; len >= 255; len-= 255) *op++ = 255; *op++ = len; *op++ = 255; *op++ = distance >> 8; *op++ = distance & 255; } } #else if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) while(len > MAX_LEN-2) { *op++ = (7 << 5) + (distance >> 8); *op++ = MAX_LEN - 2 - 7 -2; *op++ = (distance & 255); len -= MAX_LEN-2; } if(len < 7) { *op++ = (len << 5) + (distance >> 8); *op++ = (distance & 255); } else { *op++ = (7 << 5) + (distance >> 8); *op++ = len - 7; *op++ = (distance & 255); } #endif /* update the hash at match boundary */ HASH_FUNCTION(hval,ip); htab[hval] = ip++; HASH_FUNCTION(hval,ip); htab[hval] = ip++; /* assuming literal copy */ *op++ = MAX_COPY-1; continue; literal: *op++ = *anchor++; ip = anchor; copy++; if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) { copy = 0; *op++ = MAX_COPY-1; } } /* left-over as literal copy */ ip_bound++; while(ip <= ip_bound) { *op++ = *ip++; copy++; if(copy == MAX_COPY) { copy = 0; *op++ = MAX_COPY-1; } } /* if we have copied something, adjust the copy length */ if(copy) *(op-copy-1) = copy-1; else op--; #if FASTLZ_LEVEL==2 /* marker for fastlz2 */ *(flzuint8*)output |= (1 << 5); #endif return op - (flzuint8*)output; } static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) { const flzuint8* ip = (const flzuint8*) input; const flzuint8* ip_limit = ip + length; flzuint8* op = (flzuint8*) output; flzuint8* op_limit = op + maxout; flzuint32 ctrl = (*ip++) & 31; int loop = 1; do { const flzuint8* ref = op; flzuint32 len = ctrl >> 5; flzuint32 ofs = (ctrl & 31) << 8; if(ctrl >= 32) { #if FASTLZ_LEVEL==2 flzuint8 code; #endif len--; ref -= ofs; if (len == 7-1) #if FASTLZ_LEVEL==1 len += *ip++; ref -= *ip++; #else do { code = *ip++; len += code; } while (code==255); code = *ip++; ref -= code; /* match from 16-bit distance */ if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) { ofs = (*ip++) << 8; ofs += *ip++; ref = op - ofs - MAX_DISTANCE; } #endif #ifdef FASTLZ_SAFE if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) return 0; if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) return 0; #endif if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) ctrl = *ip++; else loop = 0; if(ref == op) { /* optimize copy for a run */ flzuint8 b = ref[-1]; *op++ = b; *op++ = b; *op++ = b; for(; len; --len) *op++ = b; } else { #if !defined(FASTLZ_STRICT_ALIGN) const flzuint16* p; flzuint16* q; #endif /* copy from reference */ ref--; *op++ = *ref++; *op++ = *ref++; *op++ = *ref++; #if !defined(FASTLZ_STRICT_ALIGN) /* copy a byte, so that now it's word aligned */ if(len & 1) { *op++ = *ref++; len--; } /* copy 16-bit at once */ q = (flzuint16*) op; op += len; p = (const flzuint16*) ref; for(len>>=1; len > 4; len-=4) { *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = *p++; } for(; len; --len) *q++ = *p++; #else for(; len; --len) *op++ = *ref++; #endif } } else { ctrl++; #ifdef FASTLZ_SAFE if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) return 0; if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) return 0; #endif *op++ = *ip++; for(--ctrl; ctrl; ctrl--) *op++ = *ip++; loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); if(loop) ctrl = *ip++; } } while(FASTLZ_EXPECT_CONDITIONAL(loop)); return op - (flzuint8*)output; } #endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ iverilog-12_0/vpi/fastlz.h000066400000000000000000000071451435245347300156300ustar00rootroot00000000000000/* FastLZ - lightning-fast lossless compression library Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SPDX-License-Identifier: MIT */ #ifndef FASTLZ_H #define FASTLZ_H #include #define flzuint8 uint8_t #define flzuint16 uint16_t #define flzuint32 uint32_t #define FASTLZ_VERSION 0x000100 #define FASTLZ_VERSION_MAJOR 0 #define FASTLZ_VERSION_MINOR 0 #define FASTLZ_VERSION_REVISION 0 #define FASTLZ_VERSION_STRING "0.1.0" #if defined (__cplusplus) extern "C" { #endif /** Compress a block of data in the input buffer and returns the size of compressed block. The size of input buffer is specified by length. The minimum input buffer size is 16. The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes. If the input is not compressible, the return value might be larger than length (input buffer size). The input buffer and the output buffer can not overlap. */ int fastlz_compress(const void* input, int length, void* output); /** Decompress a block of compressed data and returns the size of the decompressed block. If error occurs, e.g. the compressed data is corrupted or the output buffer is not large enough, then 0 (zero) will be returned instead. The input buffer and the output buffer can not overlap. Decompression is memory safe and guaranteed not to write the output buffer more than what is specified in maxout. */ int fastlz_decompress(const void* input, int length, void* output, int maxout); /** Compress a block of data in the input buffer and returns the size of compressed block. The size of input buffer is specified by length. The minimum input buffer size is 16. The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes. If the input is not compressible, the return value might be larger than length (input buffer size). The input buffer and the output buffer can not overlap. Compression level can be specified in parameter level. At the moment, only level 1 and level 2 are supported. Level 1 is the fastest compression and generally useful for short data. Level 2 is slightly slower but it gives better compression ratio. Note that the compressed data, regardless of the level, can always be decompressed using the function fastlz_decompress above. */ int fastlz_compress_level(int level, const void* input, int length, void* output); #if defined (__cplusplus) } #endif #endif /* FASTLZ_H */ iverilog-12_0/vpi/fstapi.c000066400000000000000000007544551435245347300156230ustar00rootroot00000000000000/* * Copyright (c) 2009-2018 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * SPDX-License-Identifier: MIT */ /* * possible disables: * * FST_DYNAMIC_ALIAS_DISABLE : dynamic aliases are not processed * FST_DYNAMIC_ALIAS2_DISABLE : new encoding for dynamic aliases is not generated * FST_WRITEX_DISABLE : fast write I/O routines are disabled * * possible enables: * * FST_DEBUG : not for production use, only enable for development * FST_REMOVE_DUPLICATE_VC : glitch removal (has writer performance impact) * HAVE_LIBPTHREAD -> FST_WRITER_PARALLEL : enables inclusion of parallel writer code * FST_DO_MISALIGNED_OPS (defined automatically for x86 and some others) : CPU architecture can handle misaligned loads/stores * _WAVE_HAVE_JUDY : use Judy arrays instead of Jenkins (undefine if LGPL is not acceptable) * */ #ifndef FST_CONFIG_INCLUDE # define FST_CONFIG_INCLUDE #endif #include FST_CONFIG_INCLUDE #include "fstapi.h" #include "fastlz.h" #include "lz4.h" #include #ifndef HAVE_LIBPTHREAD #undef FST_WRITER_PARALLEL #endif #ifdef FST_WRITER_PARALLEL #include #endif #ifdef __MINGW32__ #include #endif #ifdef HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef __MINGW32__ #ifndef alloca #define alloca __builtin_alloca #endif #else #include #endif #elif defined(_MSC_VER) #include #define alloca _alloca #endif #ifndef PATH_MAX #define PATH_MAX (4096) #endif #if defined(_MSC_VER) typedef int64_t fst_off_t; #else typedef off_t fst_off_t; #endif /* note that Judy versus Jenkins requires more experimentation: they are */ /* functionally equivalent though it appears Jenkins is slightly faster. */ /* in addition, Jenkins is not bound by the LGPL. */ #ifdef _WAVE_HAVE_JUDY #include #else /* should be more than enough for fstWriterSetSourceStem() */ #define FST_PATH_HASHMASK ((1UL << 16) - 1) typedef const void *Pcvoid_t; typedef void *Pvoid_t; typedef void **PPvoid_t; #define JudyHSIns(a,b,c,d) JenkinsIns((a),(b),(c),(hashmask)) #define JudyHSFreeArray(a,b) JenkinsFree((a),(hashmask)) void JenkinsFree(void *base_i, uint32_t hashmask); void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask); #endif #ifndef FST_WRITEX_DISABLE #define FST_WRITEX_MAX (64 * 1024) #else #define fstWritex(a,b,c) fstFwrite((b), (c), 1, fv) #endif /* these defines have a large impact on writer speed when a model has a */ /* huge number of symbols. as a default, use 128MB and increment when */ /* every 1M signals are defined. */ #define FST_BREAK_SIZE (1UL << 27) #define FST_BREAK_ADD_SIZE (1UL << 22) #define FST_BREAK_SIZE_MAX (1UL << 31) #define FST_ACTIVATE_HUGE_BREAK (1000000) #define FST_ACTIVATE_HUGE_INC (1000000) #define FST_WRITER_STR "fstWriter" #define FST_ID_NAM_SIZ (512) #define FST_ID_NAM_ATTR_SIZ (65536+4096) #define FST_DOUBLE_ENDTEST (2.7182818284590452354) #define FST_HDR_SIM_VERSION_SIZE (128) #define FST_HDR_DATE_SIZE (119) #define FST_HDR_FILETYPE_SIZE (1) #define FST_HDR_TIMEZERO_SIZE (8) #define FST_GZIO_LEN (32768) #define FST_HDR_FOURPACK_DUO_SIZE (4*1024*1024) #if defined(__i386__) || defined(__x86_64__) || defined(_AIX) #define FST_DO_MISALIGNED_OPS #endif #if defined(__APPLE__) && defined(__MACH__) #define FST_MACOSX #include #endif #if defined(FST_MACOSX) || defined(__MINGW32__) || defined(__OpenBSD__) || defined(__FreeBSD__) #define FST_UNBUFFERED_IO #endif #ifdef __GNUC__ /* Boolean expression more often true than false */ #define FST_LIKELY(x) __builtin_expect(!!(x), 1) /* Boolean expression more often false than true */ #define FST_UNLIKELY(x) __builtin_expect(!!(x), 0) #else #define FST_LIKELY(x) (!!(x)) #define FST_UNLIKELY(x) (!!(x)) #endif #define FST_APIMESS "FSTAPI | " /***********************/ /*** ***/ /*** common function ***/ /*** ***/ /***********************/ #ifdef __MINGW32__ #include #ifndef HAVE_FSEEKO #define ftello _ftelli64 #define fseeko _fseeki64 #endif #endif /* * the recoded "extra" values... * note that FST_RCV_Q is currently unused and is for future expansion. * its intended use is as another level of escape such that any arbitrary * value can be stored as the value: { time_delta, 8 bits, FST_RCV_Q }. * this is currently not implemented so that the branchless decode is: * uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; */ #define FST_RCV_X (1 | (0<<1)) #define FST_RCV_Z (1 | (1<<1)) #define FST_RCV_H (1 | (2<<1)) #define FST_RCV_U (1 | (3<<1)) #define FST_RCV_W (1 | (4<<1)) #define FST_RCV_L (1 | (5<<1)) #define FST_RCV_D (1 | (6<<1)) #define FST_RCV_Q (1 | (7<<1)) #define FST_RCV_STR "xzhuwl-?" /* 01234567 */ /* * prevent old file overwrite when currently being read */ static FILE *unlink_fopen(const char *nam, const char *mode) { unlink(nam); return(fopen(nam, mode)); } /* * system-specific temp file handling */ #ifdef __MINGW32__ static FILE* tmpfile_open(char **nam) { char *fname = NULL; TCHAR szTempFileName[MAX_PATH]; TCHAR lpTempPathBuffer[MAX_PATH]; DWORD dwRetVal = 0; UINT uRetVal = 0; FILE *fh = NULL; if(nam) /* cppcheck warning fix: nam is always defined, so this is not needed */ { dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); if((dwRetVal > MAX_PATH) || (dwRetVal == 0)) { fprintf(stderr, FST_APIMESS "GetTempPath() failed in " __FILE__ " line %d, exiting.\n", __LINE__); exit(255); } else { uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("FSTW"), 0, szTempFileName); if (uRetVal == 0) { fprintf(stderr, FST_APIMESS "GetTempFileName() failed in " __FILE__ " line %d, exiting.\n", __LINE__); exit(255); } else { fname = strdup(szTempFileName); } } if(fname) { *nam = fname; fh = unlink_fopen(fname, "w+b"); } } return(fh); } #else static FILE* tmpfile_open(char **nam) { FILE *f = tmpfile(); /* replace with mkstemp() + fopen(), etc if this is not good enough */ if(nam) { *nam = NULL; } return(f); } #endif static void tmpfile_close(FILE **f, char **nam) { if(f) { if(*f) { fclose(*f); *f = NULL; } } if(nam) { if(*nam) { unlink(*nam); free(*nam); *nam = NULL; } } } /*****************************************/ /* * to remove warn_unused_result compile time messages * (in the future there needs to be results checking) */ static size_t fstFread(void *buf, size_t siz, size_t cnt, FILE *fp) { return(fread(buf, siz, cnt, fp)); } static size_t fstFwrite(const void *buf, size_t siz, size_t cnt, FILE *fp) { return(fwrite(buf, siz, cnt, fp)); } static int fstFtruncate(int fd, fst_off_t length) { return(ftruncate(fd, length)); } /* * realpath compatibility */ static char *fstRealpath(const char *path, char *resolved_path) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH #if (defined(__MACH__) && defined(__APPLE__)) if(!resolved_path) { resolved_path = (char *)malloc(PATH_MAX+1); /* fixes bug on Leopard when resolved_path == NULL */ } #endif return(realpath(path, resolved_path)); #else #ifdef __MINGW32__ if(!resolved_path) { resolved_path = (char *)malloc(PATH_MAX+1); } return(_fullpath(resolved_path, path, PATH_MAX)); #else (void)path; (void)resolved_path; return(NULL); #endif #endif } /* * mmap compatibility */ #if defined __CYGWIN__ || defined __MINGW32__ #include #define fstMmap(__addr,__len,__prot,__flags,__fd,__off) fstMmap2((__len), (__fd), (__off)) #define fstMunmap(__addr,__len) free(__addr) static void *fstMmap2(size_t __len, int __fd, fst_off_t __off) { (void)__off; unsigned char *pnt = (unsigned char *)malloc(__len); fst_off_t cur_offs = lseek(__fd, 0, SEEK_CUR); size_t i; lseek(__fd, 0, SEEK_SET); for(i=0;i<__len;i+=SSIZE_MAX) { read(__fd, pnt + i, ((__len - i) >= SSIZE_MAX) ? SSIZE_MAX : (__len - i)); } lseek(__fd, cur_offs, SEEK_SET); return(pnt); } #else #include #if defined(__SUNPRO_C) #define FST_CADDR_T_CAST (caddr_t) #else #define FST_CADDR_T_CAST #endif #define fstMmap(__addr,__len,__prot,__flags,__fd,__off) (void*)mmap(FST_CADDR_T_CAST (__addr),(__len),(__prot),(__flags),(__fd),(__off)) #define fstMunmap(__addr,__len) { if(__addr) munmap(FST_CADDR_T_CAST (__addr),(__len)); } #endif /* * regular and variable-length integer access functions */ #ifdef FST_DO_MISALIGNED_OPS #define fstGetUint32(x) (*(uint32_t *)(x)) #else static uint32_t fstGetUint32(unsigned char *mem) { uint32_t u32; unsigned char *buf = (unsigned char *)(&u32); buf[0] = mem[0]; buf[1] = mem[1]; buf[2] = mem[2]; buf[3] = mem[3]; return(*(uint32_t *)buf); } #endif static int fstWriterUint64(FILE *handle, uint64_t v) { unsigned char buf[8]; int i; for(i=7;i>=0;i--) { buf[i] = v & 0xff; v >>= 8; } fstFwrite(buf, 8, 1, handle); return(8); } static uint64_t fstReaderUint64(FILE *f) { uint64_t val = 0; unsigned char buf[sizeof(uint64_t)]; unsigned int i; fstFread(buf, sizeof(uint64_t), 1, f); for(i=0;i>7)) /* determine len to avoid temp buffer copying to cut down on load-hit-store */ { cnt++; } pnt -= cnt; spnt = pnt; cnt--; for(i=0;i>7; *(spnt++) = ((unsigned char)v) | 0x80; v = nxt; } *spnt = (unsigned char)v; return(pnt); } static unsigned char *fstCopyVarint64ToRight(unsigned char *pnt, uint64_t v) { uint64_t nxt; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; return(pnt); } static uint64_t fstGetVarint64(unsigned char *mem, int *skiplen) { unsigned char *mem_orig = mem; uint64_t rc = 0; while(*mem & 0x80) { mem++; } *skiplen = mem - mem_orig + 1; for(;;) { rc <<= 7; rc |= (uint64_t)(*mem & 0x7f); if(mem == mem_orig) { break; } mem--; } return(rc); } static uint32_t fstReaderVarint32(FILE *f) { unsigned char buf[5]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); mem--; for(;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static uint32_t fstReaderVarint32WithSkip(FILE *f, uint32_t *skiplen) { unsigned char buf[5]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); *skiplen = mem - buf; mem--; for(;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static uint64_t fstReaderVarint64(FILE *f) { unsigned char buf[16]; unsigned char *mem = buf; uint64_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); mem--; for(;;) { rc <<= 7; rc |= (uint64_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static int fstWriterVarint(FILE *handle, uint64_t v) { uint64_t nxt; unsigned char buf[10]; /* ceil(64/7) = 10 */ unsigned char *pnt = buf; int len; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; len = pnt-buf; fstFwrite(buf, len, 1, handle); return(len); } /* signed integer read/write routines are currently unused */ static int64_t fstGetSVarint64(unsigned char *mem, int *skiplen) { unsigned char *mem_orig = mem; int64_t rc = 0; const int64_t one = 1; const int siz = sizeof(int64_t) * 8; int shift = 0; unsigned char byt; do { byt = *(mem++); rc |= ((int64_t)(byt & 0x7f)) << shift; shift += 7; } while(byt & 0x80); if((shift>= 7; if (((!v) && (!(byt & 0x40))) || ((v == -1) && (byt & 0x40))) { more = 0; byt &= 0x7f; } *(pnt++) = byt; } while(more); len = pnt-buf; fstFwrite(buf, len, 1, handle); return(len); } #endif /***********************/ /*** ***/ /*** writer function ***/ /*** ***/ /***********************/ /* * private structs */ struct fstBlackoutChain { struct fstBlackoutChain *next; uint64_t tim; unsigned active : 1; }; struct fstWriterContext { FILE *handle; FILE *hier_handle; FILE *geom_handle; FILE *valpos_handle; FILE *curval_handle; FILE *tchn_handle; unsigned char *vchg_mem; fst_off_t hier_file_len; uint32_t *valpos_mem; unsigned char *curval_mem; unsigned char *outval_mem; /* for two-state / Verilator-style value changes */ uint32_t outval_alloc_siz; char *filename; fstHandle maxhandle; fstHandle numsigs; uint32_t maxvalpos; unsigned vc_emitted : 1; unsigned is_initial_time : 1; unsigned fourpack : 1; unsigned fastpack : 1; int64_t timezero; fst_off_t section_header_truncpos; uint32_t tchn_cnt, tchn_idx; uint64_t curtime; uint64_t firsttime; uint32_t vchg_siz; uint32_t vchg_alloc_siz; uint32_t secnum; fst_off_t section_start; uint32_t numscopes; double nan; /* nan value for uninitialized doubles */ struct fstBlackoutChain *blackout_head; struct fstBlackoutChain *blackout_curr; uint32_t num_blackouts; uint64_t dump_size_limit; unsigned char filetype; /* default is 0, FST_FT_VERILOG */ unsigned compress_hier : 1; unsigned repack_on_close : 1; unsigned skip_writing_section_hdr : 1; unsigned size_limit_locked : 1; unsigned section_header_only : 1; unsigned flush_context_pending : 1; unsigned parallel_enabled : 1; unsigned parallel_was_enabled : 1; /* should really be semaphores, but are bytes to cut down on read-modify-write window size */ unsigned char already_in_flush; /* in case control-c handlers interrupt */ unsigned char already_in_close; /* in case control-c handlers interrupt */ #ifdef FST_WRITER_PARALLEL pthread_mutex_t mutex; pthread_t thread; pthread_attr_t thread_attr; struct fstWriterContext *xc_parent; #endif unsigned in_pthread : 1; size_t fst_orig_break_size; size_t fst_orig_break_add_size; size_t fst_break_size; size_t fst_break_add_size; size_t fst_huge_break_size; fstHandle next_huge_break; Pvoid_t path_array; uint32_t path_array_count; unsigned fseek_failed : 1; char *geom_handle_nam; char *valpos_handle_nam; char *curval_handle_nam; char *tchn_handle_nam; fstEnumHandle max_enumhandle; }; static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, fst_off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if(rc<0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "Seek to #%" PRId64 " (whence = %d) failed!\n", offset, whence); perror("Why"); #endif } return(rc); } static uint32_t fstWriterUint32WithVarint32(struct fstWriterContext *xc, uint32_t *u, uint32_t v, const void *dbuf, uint32_t siz) { unsigned char *buf = xc->vchg_mem + xc->vchg_siz; unsigned char *pnt = buf; uint32_t nxt; uint32_t len; #ifdef FST_DO_MISALIGNED_OPS (*(uint32_t *)(pnt)) = (*(uint32_t *)(u)); #else memcpy(pnt, u, sizeof(uint32_t)); #endif pnt += 4; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; memcpy(pnt, dbuf, siz); len = pnt-buf + siz; return(len); } static uint32_t fstWriterUint32WithVarint32AndLength(struct fstWriterContext *xc, uint32_t *u, uint32_t v, const void *dbuf, uint32_t siz) { unsigned char *buf = xc->vchg_mem + xc->vchg_siz; unsigned char *pnt = buf; uint32_t nxt; uint32_t len; #ifdef FST_DO_MISALIGNED_OPS (*(uint32_t *)(pnt)) = (*(uint32_t *)(u)); #else memcpy(pnt, u, sizeof(uint32_t)); #endif pnt += 4; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; v = siz; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; memcpy(pnt, dbuf, siz); len = pnt-buf + siz; return(len); } /* * header bytes, write here so defines are set up before anything else * that needs to use them */ static void fstWriterEmitHdrBytes(struct fstWriterContext *xc) { char vbuf[FST_HDR_SIM_VERSION_SIZE]; char dbuf[FST_HDR_DATE_SIZE]; double endtest = FST_DOUBLE_ENDTEST; time_t walltime; #define FST_HDR_OFFS_TAG (0) fputc(FST_BL_HDR, xc->handle); /* +0 tag */ #define FST_HDR_OFFS_SECLEN (FST_HDR_OFFS_TAG + 1) fstWriterUint64(xc->handle, 329); /* +1 section length */ #define FST_HDR_OFFS_START_TIME (FST_HDR_OFFS_SECLEN + 8) fstWriterUint64(xc->handle, 0); /* +9 start time */ #define FST_HDR_OFFS_END_TIME (FST_HDR_OFFS_START_TIME + 8) fstWriterUint64(xc->handle, 0); /* +17 end time */ #define FST_HDR_OFFS_ENDIAN_TEST (FST_HDR_OFFS_END_TIME + 8) fstFwrite(&endtest, 8, 1, xc->handle); /* +25 endian test for reals */ #define FST_HDR_OFFS_MEM_USED (FST_HDR_OFFS_ENDIAN_TEST + 8) fstWriterUint64(xc->handle, xc->fst_break_size);/* +33 memory used by writer */ #define FST_HDR_OFFS_NUM_SCOPES (FST_HDR_OFFS_MEM_USED + 8) fstWriterUint64(xc->handle, 0); /* +41 scope creation count */ #define FST_HDR_OFFS_NUM_VARS (FST_HDR_OFFS_NUM_SCOPES + 8) fstWriterUint64(xc->handle, 0); /* +49 var creation count */ #define FST_HDR_OFFS_MAXHANDLE (FST_HDR_OFFS_NUM_VARS + 8) fstWriterUint64(xc->handle, 0); /* +57 max var idcode */ #define FST_HDR_OFFS_SECTION_CNT (FST_HDR_OFFS_MAXHANDLE + 8) fstWriterUint64(xc->handle, 0); /* +65 vc section count */ #define FST_HDR_OFFS_TIMESCALE (FST_HDR_OFFS_SECTION_CNT + 8) fputc((-9)&255, xc->handle); /* +73 timescale 1ns */ #define FST_HDR_OFFS_SIM_VERSION (FST_HDR_OFFS_TIMESCALE + 1) memset(vbuf, 0, FST_HDR_SIM_VERSION_SIZE); strcpy(vbuf, FST_WRITER_STR); fstFwrite(vbuf, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle); /* +74 version */ #define FST_HDR_OFFS_DATE (FST_HDR_OFFS_SIM_VERSION + FST_HDR_SIM_VERSION_SIZE) memset(dbuf, 0, FST_HDR_DATE_SIZE); time(&walltime); strcpy(dbuf, asctime(localtime(&walltime))); fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */ /* date size is deliberately overspecified at 119 bytes (originally 128) in order to provide backfill for new args */ #define FST_HDR_OFFS_FILETYPE (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE) fputc(xc->filetype, xc->handle); /* +321 filetype */ #define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_FILETYPE + FST_HDR_FILETYPE_SIZE) fstWriterUint64(xc->handle, xc->timezero); /* +322 timezero */ #define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + FST_HDR_TIMEZERO_SIZE) /* +330 next section starts here */ fflush(xc->handle); } /* * mmap functions */ static void fstWriterMmapSanity(void *pnt, const char *file, int line, const char *usage) { #if !defined(__CYGWIN__) && !defined(__MINGW32__) if(pnt == MAP_FAILED) { fprintf(stderr, "fstMmap() assigned to %s failed: errno: %d, file %s, line %d.\n", usage, errno, file, line); perror("Why"); pnt = NULL; } #endif } static void fstWriterCreateMmaps(struct fstWriterContext *xc) { fst_off_t curpos = ftello(xc->handle); fflush(xc->hier_handle); /* write out intermediate header */ fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET); fstWriterUint64(xc->handle, xc->firsttime); fstWriterUint64(xc->handle, xc->curtime); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET); fstWriterUint64(xc->handle, xc->numscopes); fstWriterUint64(xc->handle, xc->numsigs); fstWriterUint64(xc->handle, xc->maxhandle); fstWriterUint64(xc->handle, xc->secnum); fstWriterFseeko(xc, xc->handle, curpos, SEEK_SET); fflush(xc->handle); /* do mappings */ if(!xc->valpos_mem) { fflush(xc->valpos_handle); errno = 0; if(xc->maxhandle) { fstWriterMmapSanity(xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0), __FILE__, __LINE__, "xc->valpos_mem"); } } if(!xc->curval_mem) { fflush(xc->curval_handle); errno = 0; if(xc->maxvalpos) { fstWriterMmapSanity(xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0), __FILE__, __LINE__, "xc->curval_handle"); } } } static void fstDestroyMmaps(struct fstWriterContext *xc, int is_closing) { #if !defined __CYGWIN__ && !defined __MINGW32__ (void)is_closing; #endif fstMunmap(xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t)); xc->valpos_mem = NULL; #if defined __CYGWIN__ || defined __MINGW32__ if(xc->curval_mem) { if(!is_closing) /* need to flush out for next emulated mmap() read */ { unsigned char *pnt = xc->curval_mem; int __fd = fileno(xc->curval_handle); fst_off_t cur_offs = lseek(__fd, 0, SEEK_CUR); size_t i; size_t __len = xc->maxvalpos; lseek(__fd, 0, SEEK_SET); for(i=0;i<__len;i+=SSIZE_MAX) { write(__fd, pnt + i, ((__len - i) >= SSIZE_MAX) ? SSIZE_MAX : (__len - i)); } lseek(__fd, cur_offs, SEEK_SET); } } #endif fstMunmap(xc->curval_mem, xc->maxvalpos); xc->curval_mem = NULL; } /* * set up large and small memory usages * crossover point in model is FST_ACTIVATE_HUGE_BREAK number of signals */ static void fstDetermineBreakSize(struct fstWriterContext *xc) { #if defined(__linux__) || defined(FST_MACOSX) int was_set = 0; #ifdef __linux__ FILE *f = fopen("/proc/meminfo", "rb"); if(f) { char buf[257]; char *s; while(!feof(f)) { buf[0] = 0; s = fgets(buf, 256, f); if(s && *s) { if(!strncmp(s, "MemTotal:", 9)) { size_t v = atol(s+10); v *= 1024; /* convert to bytes */ v /= 8; /* chop down to 1/8 physical memory */ if(v > FST_BREAK_SIZE) { if(v > FST_BREAK_SIZE_MAX) { v = FST_BREAK_SIZE_MAX; } xc->fst_huge_break_size = v; was_set = 1; break; } } } } fclose(f); } if(!was_set) { xc->fst_huge_break_size = FST_BREAK_SIZE; } #else int mib[2]; int64_t v; size_t length; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; length = sizeof(int64_t); if(!sysctl(mib, 2, &v, &length, NULL, 0)) { v /= 8; if(v > (int64_t)FST_BREAK_SIZE) { if(v > (int64_t)FST_BREAK_SIZE_MAX) { v = FST_BREAK_SIZE_MAX; } xc->fst_huge_break_size = v; was_set = 1; } } if(!was_set) { xc->fst_huge_break_size = FST_BREAK_SIZE; } #endif #else xc->fst_huge_break_size = FST_BREAK_SIZE; #endif xc->fst_break_size = xc->fst_orig_break_size = FST_BREAK_SIZE; xc->fst_break_add_size = xc->fst_orig_break_add_size = FST_BREAK_ADD_SIZE; xc->next_huge_break = FST_ACTIVATE_HUGE_BREAK; } /* * file creation and close */ void *fstWriterCreate(const char *nam, int use_compressed_hier) { struct fstWriterContext *xc = (struct fstWriterContext *)calloc(1, sizeof(struct fstWriterContext)); xc->compress_hier = use_compressed_hier; fstDetermineBreakSize(xc); if((!nam)|| (!(xc->handle=unlink_fopen(nam, "w+b")))) { free(xc); xc=NULL; } else { int flen = strlen(nam); char *hf = (char *)calloc(1, flen + 6); memcpy(hf, nam, flen); strcpy(hf + flen, ".hier"); xc->hier_handle = unlink_fopen(hf, "w+b"); xc->geom_handle = tmpfile_open(&xc->geom_handle_nam); /* .geom */ xc->valpos_handle = tmpfile_open(&xc->valpos_handle_nam); /* .offs */ xc->curval_handle = tmpfile_open(&xc->curval_handle_nam); /* .bits */ xc->tchn_handle = tmpfile_open(&xc->tchn_handle_nam); /* .tchn */ xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size; xc->vchg_mem = (unsigned char *)malloc(xc->vchg_alloc_siz); if(xc->hier_handle && xc->geom_handle && xc->valpos_handle && xc->curval_handle && xc->vchg_mem && xc->tchn_handle) { xc->filename = strdup(nam); xc->is_initial_time = 1; fstWriterEmitHdrBytes(xc); xc->nan = strtod("NaN", NULL); #ifdef FST_WRITER_PARALLEL pthread_mutex_init(&xc->mutex, NULL); pthread_attr_init(&xc->thread_attr); pthread_attr_setdetachstate(&xc->thread_attr, PTHREAD_CREATE_DETACHED); #endif } else { fclose(xc->handle); if(xc->hier_handle) { fclose(xc->hier_handle); unlink(hf); } tmpfile_close(&xc->geom_handle, &xc->geom_handle_nam); tmpfile_close(&xc->valpos_handle, &xc->valpos_handle_nam); tmpfile_close(&xc->curval_handle, &xc->curval_handle_nam); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); free(xc->vchg_mem); free(xc); xc=NULL; } free(hf); } return(xc); } /* * generation and writing out of value change data sections */ static void fstWriterEmitSectionHeader(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { unsigned long destlen; unsigned char *dmem; int rc; destlen = xc->maxvalpos; dmem = (unsigned char *)malloc(compressBound(destlen)); rc = compress2(dmem, &destlen, xc->curval_mem, xc->maxvalpos, 4); /* was 9...which caused performance drag on traces with many signals */ fputc(FST_BL_SKIP, xc->handle); /* temporarily tag the section, use FST_BL_VCDATA on finalize */ xc->section_start = ftello(xc->handle); #ifdef FST_WRITER_PARALLEL if(xc->xc_parent) xc->xc_parent->section_start = xc->section_start; #endif xc->section_header_only = 1; /* indicates truncate might be needed */ fstWriterUint64(xc->handle, 0); /* placeholder = section length */ fstWriterUint64(xc->handle, xc->is_initial_time ? xc->firsttime : xc->curtime); /* begin time of section */ fstWriterUint64(xc->handle, xc->curtime); /* end time of section (placeholder) */ fstWriterUint64(xc->handle, 0); /* placeholder = amount of buffer memory required in reader for full vc traversal */ fstWriterVarint(xc->handle, xc->maxvalpos); /* maxvalpos = length of uncompressed data */ if((rc == Z_OK) && (destlen < xc->maxvalpos)) { fstWriterVarint(xc->handle, destlen); /* length of compressed data */ } else { fstWriterVarint(xc->handle, xc->maxvalpos); /* length of (unable to be) compressed data */ } fstWriterVarint(xc->handle, xc->maxhandle); /* max handle associated with this data (in case of dynamic facility adds) */ if((rc == Z_OK) && (destlen < xc->maxvalpos)) { fstFwrite(dmem, destlen, 1, xc->handle); } else /* comparison between compressed / decompressed len tells if compressed */ { fstFwrite(xc->curval_mem, xc->maxvalpos, 1, xc->handle); } free(dmem); } } /* * only to be called directly by fst code...otherwise must * be synced up with time changes */ #ifdef FST_WRITER_PARALLEL static void fstWriterFlushContextPrivate2(void *ctx) #else static void fstWriterFlushContextPrivate(void *ctx) #endif { #ifdef FST_DEBUG int cnt = 0; #endif unsigned int i; unsigned char *vchg_mem; FILE *f; fst_off_t fpos, indxpos, endpos; uint32_t prevpos; int zerocnt; unsigned char *scratchpad; unsigned char *scratchpnt; unsigned char *tmem; fst_off_t tlen; fst_off_t unc_memreq = 0; /* for reader */ unsigned char *packmem; unsigned int packmemlen; uint32_t *vm4ip; struct fstWriterContext *xc = (struct fstWriterContext *)ctx; #ifdef FST_WRITER_PARALLEL struct fstWriterContext *xc2 = xc->xc_parent; #else struct fstWriterContext *xc2 = xc; #endif #ifndef FST_DYNAMIC_ALIAS_DISABLE Pvoid_t PJHSArray = (Pvoid_t) NULL; #ifndef _WAVE_HAVE_JUDY uint32_t hashmask = xc->maxhandle; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; #endif #endif if((xc->vchg_siz <= 1)||(xc->already_in_flush)) return; xc->already_in_flush = 1; /* should really do this with a semaphore */ xc->section_header_only = 0; scratchpad = (unsigned char *)malloc(xc->vchg_siz); vchg_mem = xc->vchg_mem; f = xc->handle; fstWriterVarint(f, xc->maxhandle); /* emit current number of handles */ fputc(xc->fourpack ? '4' : (xc->fastpack ? 'F' : 'Z'), f); fpos = 1; packmemlen = 1024; /* maintain a running "longest" allocation to */ packmem = (unsigned char *)malloc(packmemlen); /* prevent continual malloc...free every loop iter */ for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { uint32_t offs = vm4ip[2]; uint32_t next_offs; unsigned int wrlen; vm4ip[2] = fpos; scratchpnt = scratchpad + xc->vchg_siz; /* build this buffer backwards */ if(vm4ip[1] <= 1) { if(vm4ip[1] == 1) { wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ #ifndef FST_REMOVE_DUPLICATE_VC xc->curval_mem[vm4ip[0]] = vchg_mem[offs + 4 + wrlen]; /* checkpoint variable */ #endif while(offs) { unsigned char val; uint32_t time_delta, rcv; next_offs = fstGetUint32(vchg_mem + offs); offs += 4; time_delta = fstGetVarint32(vchg_mem + offs, (int *)&wrlen); val = vchg_mem[offs+wrlen]; offs = next_offs; switch(val) { case '0': case '1': rcv = ((val&1)<<1) | (time_delta<<2); break; /* pack more delta bits in for 0/1 vchs */ case 'x': case 'X': rcv = FST_RCV_X | (time_delta<<4); break; case 'z': case 'Z': rcv = FST_RCV_Z | (time_delta<<4); break; case 'h': case 'H': rcv = FST_RCV_H | (time_delta<<4); break; case 'u': case 'U': rcv = FST_RCV_U | (time_delta<<4); break; case 'w': case 'W': rcv = FST_RCV_W | (time_delta<<4); break; case 'l': case 'L': rcv = FST_RCV_L | (time_delta<<4); break; default: rcv = FST_RCV_D | (time_delta<<4); break; } scratchpnt = fstCopyVarint32ToLeft(scratchpnt, rcv); } } else { /* variable length */ /* fstGetUint32 (next_offs) + fstGetVarint32 (time_delta) + fstGetVarint32 (len) + payload */ unsigned char *pnt; uint32_t record_len; uint32_t time_delta; while(offs) { next_offs = fstGetUint32(vchg_mem + offs); offs += 4; pnt = vchg_mem + offs; offs = next_offs; time_delta = fstGetVarint32(pnt, (int *)&wrlen); pnt += wrlen; record_len = fstGetVarint32(pnt, (int *)&wrlen); pnt += wrlen; scratchpnt -= record_len; memcpy(scratchpnt, pnt, record_len); scratchpnt = fstCopyVarint32ToLeft(scratchpnt, record_len); scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1)); /* reserve | 1 case for future expansion */ } } } else { wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ #ifndef FST_REMOVE_DUPLICATE_VC memcpy(xc->curval_mem + vm4ip[0], vchg_mem + offs + 4 + wrlen, vm4ip[1]); /* checkpoint variable */ #endif while(offs) { unsigned int idx; char is_binary = 1; unsigned char *pnt; uint32_t time_delta; next_offs = fstGetUint32(vchg_mem + offs); offs += 4; time_delta = fstGetVarint32(vchg_mem + offs, (int *)&wrlen); pnt = vchg_mem+offs+wrlen; offs = next_offs; for(idx=0;idxvchg_siz - scratchpnt; unc_memreq += wrlen; if(wrlen > 32) { unsigned long destlen = wrlen; unsigned char *dmem; unsigned int rc; if(!xc->fastpack) { if(wrlen <= packmemlen) { dmem = packmem; } else { free(packmem); dmem = packmem = (unsigned char *)malloc(compressBound(packmemlen = wrlen)); } rc = compress2(dmem, &destlen, scratchpnt, wrlen, 4); if(rc == Z_OK) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, dmem, destlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, wrlen); fpos += destlen; fstFwrite(dmem, destlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } } else { /* this is extremely conservative: fastlz needs +5% for worst case, lz4 needs siz+(siz/255)+16 */ if(((wrlen * 2) + 2) <= packmemlen) { dmem = packmem; } else { free(packmem); dmem = packmem = (unsigned char *)malloc(packmemlen = (wrlen * 2) + 2); } rc = (xc->fourpack) ? LZ4_compress((char *)scratchpnt, (char *)dmem, wrlen) : fastlz_compress(scratchpnt, wrlen, dmem); if(rc < destlen) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, dmem, rc, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, wrlen); fpos += rc; fstFwrite(dmem, rc, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } } } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } /* vm4ip[3] = 0; ...redundant with clearing below */ #ifdef FST_DEBUG cnt++; #endif } } #ifndef FST_DYNAMIC_ALIAS_DISABLE JudyHSFreeArray(&PJHSArray, NULL); #endif free(packmem); packmem = NULL; /* packmemlen = 0; */ /* scan-build */ prevpos = 0; zerocnt = 0; free(scratchpad); scratchpad = NULL; indxpos = ftello(f); xc->secnum++; #ifndef FST_DYNAMIC_ALIAS2_DISABLE if(1) { uint32_t prev_alias = 0; for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { if(zerocnt) { fpos += fstWriterVarint(f, (zerocnt << 1)); zerocnt = 0; } if(vm4ip[2] & 0x80000000) { if(vm4ip[2] != prev_alias) { fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1); } else { fpos += fstWriterSVarint(f, (0 << 1) | 1); } } else { fpos += fstWriterSVarint(f, ((vm4ip[2] - prevpos) << 1) | 1); prevpos = vm4ip[2]; } vm4ip[2] = 0; vm4ip[3] = 0; /* clear out tchn idx */ } else { zerocnt++; } } } else #endif { for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { if(zerocnt) { fpos += fstWriterVarint(f, (zerocnt << 1)); zerocnt = 0; } if(vm4ip[2] & 0x80000000) { fpos += fstWriterVarint(f, 0); /* signal, note that using a *signed* varint would be more efficient than this byte escape! */ fpos += fstWriterVarint(f, (-(int32_t)vm4ip[2])); } else { fpos += fstWriterVarint(f, ((vm4ip[2] - prevpos) << 1) | 1); prevpos = vm4ip[2]; } vm4ip[2] = 0; vm4ip[3] = 0; /* clear out tchn idx */ } else { zerocnt++; } } } if(zerocnt) { /* fpos += */ fstWriterVarint(f, (zerocnt << 1)); /* scan-build */ } #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "value chains: %d\n", cnt); #endif xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; endpos = ftello(xc->handle); fstWriterUint64(xc->handle, endpos-indxpos); /* write delta index position at very end of block */ /*emit time changes for block */ fflush(xc->tchn_handle); tlen = ftello(xc->tchn_handle); fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); errno = 0; fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0), __FILE__, __LINE__, "tmem"); if(tmem) { unsigned long destlen = tlen; unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if((rc == Z_OK) && (((fst_off_t)destlen) < tlen)) { fstFwrite(dmem, destlen, 1, xc->handle); } else /* comparison between compressed / decompressed len tells if compressed */ { fstFwrite(tmem, tlen, 1, xc->handle); destlen = tlen; } free(dmem); fstMunmap(tmem, tlen); fstWriterUint64(xc->handle, tlen); /* uncompressed */ fstWriterUint64(xc->handle, destlen); /* compressed */ fstWriterUint64(xc->handle, xc->tchn_cnt); /* number of time items */ } xc->tchn_cnt = xc->tchn_idx = 0; fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); fstFtruncate(fileno(xc->tchn_handle), 0); /* write block trailer */ endpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, xc->section_start, SEEK_SET); fstWriterUint64(xc->handle, endpos - xc->section_start); /* write block length */ fstWriterFseeko(xc, xc->handle, 8, SEEK_CUR); /* skip begin time */ fstWriterUint64(xc->handle, xc->curtime); /* write end time for section */ fstWriterUint64(xc->handle, unc_memreq); /* amount of buffer memory required in reader for full traversal */ fflush(xc->handle); fstWriterFseeko(xc, xc->handle, xc->section_start-1, SEEK_SET); /* write out FST_BL_VCDATA over FST_BL_SKIP */ #ifndef FST_DYNAMIC_ALIAS_DISABLE #ifndef FST_DYNAMIC_ALIAS2_DISABLE fputc(FST_BL_VCDATA_DYN_ALIAS2, xc->handle); #else fputc(FST_BL_VCDATA_DYN_ALIAS, xc->handle); #endif #else fputc(FST_BL_VCDATA, xc->handle); #endif fflush(xc->handle); fstWriterFseeko(xc, xc->handle, endpos, SEEK_SET); /* seek to end of file */ xc2->section_header_truncpos = endpos; /* cache in case of need to truncate */ if(xc->dump_size_limit) { if(endpos >= ((fst_off_t)xc->dump_size_limit)) { xc2->skip_writing_section_hdr = 1; xc2->size_limit_locked = 1; xc2->is_initial_time = 1; /* to trick emit value and emit time change */ #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "<< dump file size limit reached, stopping dumping >>\n"); #endif } } if(!xc2->skip_writing_section_hdr) { fstWriterEmitSectionHeader(xc); /* emit next section header */ } fflush(xc->handle); xc->already_in_flush = 0; } #ifdef FST_WRITER_PARALLEL static void *fstWriterFlushContextPrivate1(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; struct fstWriterContext *xc_parent; pthread_mutex_lock(&(xc->xc_parent->mutex)); fstWriterFlushContextPrivate2(xc); #ifdef FST_REMOVE_DUPLICATE_VC free(xc->curval_mem); #endif free(xc->valpos_mem); free(xc->vchg_mem); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); xc_parent = xc->xc_parent; free(xc); xc_parent->in_pthread = 0; pthread_mutex_unlock(&(xc_parent->mutex)); return(NULL); } static void fstWriterFlushContextPrivate(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc->parallel_enabled) { struct fstWriterContext *xc2 = (struct fstWriterContext *)malloc(sizeof(struct fstWriterContext)); unsigned int i; pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); xc->xc_parent = xc; memcpy(xc2, xc, sizeof(struct fstWriterContext)); xc2->valpos_mem = (uint32_t *)malloc(xc->maxhandle * 4 * sizeof(uint32_t)); memcpy(xc2->valpos_mem, xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t)); /* curval mem is updated in the thread */ #ifdef FST_REMOVE_DUPLICATE_VC xc2->curval_mem = (unsigned char *)malloc(xc->maxvalpos); memcpy(xc2->curval_mem, xc->curval_mem, xc->maxvalpos); #endif xc->vchg_mem = (unsigned char *)malloc(xc->vchg_alloc_siz); xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; for(i=0;imaxhandle;i++) { uint32_t *vm4ip = &(xc->valpos_mem[4*i]); vm4ip[2] = 0; /* zero out offset val */ vm4ip[3] = 0; /* zero out last time change val */ } xc->tchn_cnt = xc->tchn_idx = 0; xc->tchn_handle = tmpfile_open(&xc->tchn_handle_nam); /* child thread will deallocate file/name */ fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); fstFtruncate(fileno(xc->tchn_handle), 0); xc->section_header_only = 0; xc->secnum++; while (xc->in_pthread) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); }; pthread_mutex_lock(&xc->mutex); xc->in_pthread = 1; pthread_mutex_unlock(&xc->mutex); pthread_create(&xc->thread, &xc->thread_attr, fstWriterFlushContextPrivate1, xc2); } else { if(xc->parallel_was_enabled) /* conservatively block */ { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); } xc->xc_parent = xc; fstWriterFlushContextPrivate2(xc); } } #endif /* * queues up a flush context operation */ void fstWriterFlushContext(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { if(xc->tchn_idx > 1) { xc->flush_context_pending = 1; } } } /* * close out FST file */ void fstWriterClose(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; #ifdef FST_WRITER_PARALLEL if(xc) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); } #endif if(xc && !xc->already_in_close && !xc->already_in_flush) { unsigned char *tmem = NULL; fst_off_t fixup_offs, tlen, hlen; xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */ if(xc->section_header_only && xc->section_header_truncpos && (xc->vchg_siz <= 1) && (!xc->is_initial_time)) { fstFtruncate(fileno(xc->handle), xc->section_header_truncpos); fstWriterFseeko(xc, xc->handle, xc->section_header_truncpos, SEEK_SET); xc->section_header_only = 0; } else { xc->skip_writing_section_hdr = 1; if(!xc->size_limit_locked) { if(FST_UNLIKELY(xc->is_initial_time)) /* simulation time never advanced so mock up the changes as time zero ones */ { fstHandle dupe_idx; fstWriterEmitTimeChange(xc, 0); /* emit some time change just to have one */ for(dupe_idx = 0; dupe_idx < xc->maxhandle; dupe_idx++) /* now clone the values */ { fstWriterEmitValueChange(xc, dupe_idx+1, xc->curval_mem + xc->valpos_mem[4*dupe_idx]); } } fstWriterFlushContextPrivate(xc); #ifdef FST_WRITER_PARALLEL pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); while (xc->in_pthread) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); }; #endif } } fstDestroyMmaps(xc, 1); if(xc->outval_mem) { free(xc->outval_mem); xc->outval_mem = NULL; xc->outval_alloc_siz = 0; } /* write out geom section */ fflush(xc->geom_handle); tlen = ftello(xc->geom_handle); errno = 0; if(tlen) { fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0), __FILE__, __LINE__, "tmem"); } if(tmem) { unsigned long destlen = tlen; unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if((rc != Z_OK) || (((fst_off_t)destlen) > tlen)) { destlen = tlen; } fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ fstWriterUint64(xc->handle, destlen + 24); /* section length */ fstWriterUint64(xc->handle, tlen); /* uncompressed */ /* compressed len is section length - 24 */ fstWriterUint64(xc->handle, xc->maxhandle); /* maxhandle */ fstFwrite((((fst_off_t)destlen) != tlen) ? dmem : tmem, destlen, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(FST_BL_GEOM, xc->handle); /* actual tag */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); free(dmem); fstMunmap(tmem, tlen); } if(xc->num_blackouts) { uint64_t cur_bl = 0; fst_off_t bpos, eos; uint32_t i; fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ bpos = fixup_offs + 1; fstWriterUint64(xc->handle, 0); /* section length */ fstWriterVarint(xc->handle, xc->num_blackouts); for(i=0;inum_blackouts;i++) { fputc(xc->blackout_head->active, xc->handle); fstWriterVarint(xc->handle, xc->blackout_head->tim - cur_bl); cur_bl = xc->blackout_head->tim; xc->blackout_curr = xc->blackout_head->next; free(xc->blackout_head); xc->blackout_head = xc->blackout_curr; } eos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, bpos, SEEK_SET); fstWriterUint64(xc->handle, eos - bpos); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(FST_BL_BLACKOUT, xc->handle); /* actual tag */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); } if(xc->compress_hier) { fst_off_t hl, eos; gzFile zhandle; int zfd; int fourpack_duo = 0; #ifndef __MINGW32__ char *fnam = (char *)malloc(strlen(xc->filename) + 5 + 1); #endif fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ hlen = ftello(xc->handle); fstWriterUint64(xc->handle, 0); /* section length */ fstWriterUint64(xc->handle, xc->hier_file_len); /* uncompressed length */ if(!xc->fourpack) { unsigned char *mem = (unsigned char *)malloc(FST_GZIO_LEN); zfd = dup(fileno(xc->handle)); fflush(xc->handle); zhandle = gzdopen(zfd, "wb4"); if(zhandle) { fstWriterFseeko(xc, xc->hier_handle, 0, SEEK_SET); for(hl = 0; hl < xc->hier_file_len; hl += FST_GZIO_LEN) { unsigned len = ((xc->hier_file_len - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (xc->hier_file_len - hl); fstFread(mem, len, 1, xc->hier_handle); gzwrite(zhandle, mem, len); } gzclose(zhandle); } else { close(zfd); } free(mem); } else { int lz4_maxlen; unsigned char *mem; unsigned char *hmem = NULL; int packed_len; fflush(xc->handle); lz4_maxlen = LZ4_compressBound(xc->hier_file_len); mem = (unsigned char *)malloc(lz4_maxlen); errno = 0; if(xc->hier_file_len) { fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem"); } packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len); fstMunmap(hmem, xc->hier_file_len); fourpack_duo = (!xc->repack_on_close) && (xc->hier_file_len > FST_HDR_FOURPACK_DUO_SIZE); /* double pack when hierarchy is large */ if(fourpack_duo) /* double packing with LZ4 is faster than gzip */ { unsigned char *mem_duo; int lz4_maxlen_duo; int packed_len_duo; lz4_maxlen_duo = LZ4_compressBound(packed_len); mem_duo = (unsigned char *)malloc(lz4_maxlen_duo); packed_len_duo = LZ4_compress((char *)mem, (char *)mem_duo, packed_len); fstWriterVarint(xc->handle, packed_len); /* 1st round compressed length */ fstFwrite(mem_duo, packed_len_duo, 1, xc->handle); free(mem_duo); } else { fstFwrite(mem, packed_len, 1, xc->handle); } free(mem); } fstWriterFseeko(xc, xc->handle, 0, SEEK_END); eos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, hlen, SEEK_SET); fstWriterUint64(xc->handle, eos - hlen); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(xc->fourpack ? ( fourpack_duo ? FST_BL_HIER_LZ4DUO : FST_BL_HIER_LZ4) : FST_BL_HIER, xc->handle); /* actual tag now also == compression type */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); #ifndef __MINGW32__ sprintf(fnam, "%s.hier", xc->filename); unlink(fnam); free(fnam); #endif } /* finalize out header */ fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET); fstWriterUint64(xc->handle, xc->firsttime); fstWriterUint64(xc->handle, xc->curtime); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET); fstWriterUint64(xc->handle, xc->numscopes); fstWriterUint64(xc->handle, xc->numsigs); fstWriterUint64(xc->handle, xc->maxhandle); fstWriterUint64(xc->handle, xc->secnum); fflush(xc->handle); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); free(xc->vchg_mem); xc->vchg_mem = NULL; tmpfile_close(&xc->curval_handle, &xc->curval_handle_nam); tmpfile_close(&xc->valpos_handle, &xc->valpos_handle_nam); tmpfile_close(&xc->geom_handle, &xc->geom_handle_nam); if(xc->hier_handle) { fclose(xc->hier_handle); xc->hier_handle = NULL; } if(xc->handle) { if(xc->repack_on_close) { FILE *fp; fst_off_t offpnt, uclen; int flen = strlen(xc->filename); char *hf = (char *)calloc(1, flen + 5); strcpy(hf, xc->filename); strcpy(hf+flen, ".pak"); fp = fopen(hf, "wb"); if(fp) { gzFile dsth; int zfd; char gz_membuf[FST_GZIO_LEN]; fstWriterFseeko(xc, xc->handle, 0, SEEK_END); uclen = ftello(xc->handle); fputc(FST_BL_ZWRAPPER, fp); fstWriterUint64(fp, 0); fstWriterUint64(fp, uclen); fflush(fp); fstWriterFseeko(xc, xc->handle, 0, SEEK_SET); zfd = dup(fileno(fp)); dsth = gzdopen(zfd, "wb4"); if(dsth) { for(offpnt = 0; offpnt < uclen; offpnt += FST_GZIO_LEN) { size_t this_len = ((uclen - offpnt) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - offpnt); fstFread(gz_membuf, this_len, 1, xc->handle); gzwrite(dsth, gz_membuf, this_len); } gzclose(dsth); } else { close(zfd); } fstWriterFseeko(xc, fp, 0, SEEK_END); offpnt = ftello(fp); fstWriterFseeko(xc, fp, 1, SEEK_SET); fstWriterUint64(fp, offpnt - 1); fclose(fp); fclose(xc->handle); xc->handle = NULL; unlink(xc->filename); rename(hf, xc->filename); } else { xc->repack_on_close = 0; fclose(xc->handle); xc->handle = NULL; } free(hf); } else { fclose(xc->handle); xc->handle = NULL; } } #ifdef __MINGW32__ { int flen = strlen(xc->filename); char *hf = (char *)calloc(1, flen + 6); strcpy(hf, xc->filename); if(xc->compress_hier) { strcpy(hf + flen, ".hier"); unlink(hf); /* no longer needed as a section now exists for this */ } free(hf); } #endif #ifdef FST_WRITER_PARALLEL pthread_mutex_destroy(&xc->mutex); pthread_attr_destroy(&xc->thread_attr); #endif if(xc->path_array) { #ifndef _WAVE_HAVE_JUDY const uint32_t hashmask = FST_PATH_HASHMASK; #endif JudyHSFreeArray(&(xc->path_array), NULL); } free(xc->filename); xc->filename = NULL; free(xc); } } /* * functions to set miscellaneous header/block information */ void fstWriterSetDate(void *ctx, const char *dat) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { char s[FST_HDR_DATE_SIZE]; fst_off_t fpos = ftello(xc->handle); int len = strlen(dat); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_DATE, SEEK_SET); memset(s, 0, FST_HDR_DATE_SIZE); memcpy(s, dat, (len < FST_HDR_DATE_SIZE) ? len : FST_HDR_DATE_SIZE); fstFwrite(s, FST_HDR_DATE_SIZE, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetVersion(void *ctx, const char *vers) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && vers) { char s[FST_HDR_SIM_VERSION_SIZE]; fst_off_t fpos = ftello(xc->handle); int len = strlen(vers); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET); memset(s, 0, FST_HDR_SIM_VERSION_SIZE); memcpy(s, vers, (len < FST_HDR_SIM_VERSION_SIZE) ? len : FST_HDR_SIM_VERSION_SIZE); fstFwrite(s, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetFileType(void *ctx, enum fstFileType filetype) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { if(/*(filetype >= FST_FT_MIN) &&*/ (filetype <= FST_FT_MAX)) { fst_off_t fpos = ftello(xc->handle); xc->filetype = filetype; fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_FILETYPE, SEEK_SET); fputc(xc->filetype, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } } static void fstWriterSetAttrDoubleArgGeneric(void *ctx, int typ, uint64_t arg1, uint64_t arg2) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { unsigned char buf[11]; /* ceil(64/7) = 10 + null term */ unsigned char *pnt = fstCopyVarint64ToRight(buf, arg1); if(arg1) { *pnt = 0; /* this converts any *nonzero* arg1 when made a varint into a null-term string */ } fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, (char *)buf, arg2); } } static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ, uint64_t arg) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && comm) { char *s = strdup(comm); char *sf = s; while(*s) { if((*s == '\n') || (*s == '\r')) *s = ' '; s++; } fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, arg); free(sf); } } static void fstWriterSetSourceStem_2(void *ctx, const char *path, unsigned int line, unsigned int use_realpath, int typ) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && path && path[0]) { uint64_t sidx = 0; int slen = strlen(path); #ifndef _WAVE_HAVE_JUDY const uint32_t hashmask = FST_PATH_HASHMASK; const unsigned char *path2 = (const unsigned char *)path; PPvoid_t pv; #else char *path2 = (char *)alloca(slen + 1); /* judy lacks const qualifier in its JudyHSIns definition */ PPvoid_t pv; strcpy(path2, path); #endif pv = JudyHSIns(&(xc->path_array), path2, slen, NULL); if(*pv) { sidx = (intptr_t)(*pv); } else { char *rp = NULL; sidx = ++xc->path_array_count; *pv = (void *)(intptr_t)(xc->path_array_count); if(use_realpath) { rp = fstRealpath( #ifndef _WAVE_HAVE_JUDY (const char *) #endif path2, NULL); } fstWriterSetAttrGeneric(xc, rp ? rp : #ifndef _WAVE_HAVE_JUDY (const char *) #endif path2, FST_MT_PATHNAME, sidx); if(rp) { free(rp); } } fstWriterSetAttrDoubleArgGeneric(xc, typ, sidx, line); } } void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCESTEM); } void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCEISTEM); } void fstWriterSetComment(void *ctx, const char *comm) { fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT, 0); } void fstWriterSetValueList(void *ctx, const char *vl) { fstWriterSetAttrGeneric(ctx, vl, FST_MT_VALUELIST, 0); } void fstWriterSetEnvVar(void *ctx, const char *envvar) { fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR, 0); } void fstWriterSetTimescale(void *ctx, int ts) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fst_off_t fpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET); fputc(ts & 255, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetTimescaleFromString(void *ctx, const char *s) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && s) { int mat = 0; int seconds_exp = -9; int tv = atoi(s); const char *pnt = s; while(*pnt) { switch(*pnt) { case 'm': seconds_exp = -3; mat = 1; break; case 'u': seconds_exp = -6; mat = 1; break; case 'n': seconds_exp = -9; mat = 1; break; case 'p': seconds_exp = -12; mat = 1; break; case 'f': seconds_exp = -15; mat = 1; break; case 'a': seconds_exp = -18; mat = 1; break; case 'z': seconds_exp = -21; mat = 1; break; case 's': seconds_exp = 0; mat = 1; break; default: break; } if(mat) break; pnt++; } if(tv == 10) { seconds_exp++; } else if(tv == 100) { seconds_exp+=2; } fstWriterSetTimescale(ctx, seconds_exp); } } void fstWriterSetTimezero(void *ctx, int64_t tim) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fst_off_t fpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET); fstWriterUint64(xc->handle, (xc->timezero = tim)); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->fastpack = (typ != FST_WR_PT_ZLIB); xc->fourpack = (typ == FST_WR_PT_LZ4); } } void fstWriterSetRepackOnClose(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->repack_on_close = (enable != 0); } } void fstWriterSetParallelMode(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->parallel_was_enabled |= xc->parallel_enabled; /* make sticky */ xc->parallel_enabled = (enable != 0); #ifndef FST_WRITER_PARALLEL if(xc->parallel_enabled) { fprintf(stderr, FST_APIMESS "fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled during compile, exiting.\n"); exit(255); } #endif } } void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->dump_size_limit = numbytes; } } int fstWriterGetDumpSizeLimitReached(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { return(xc->size_limit_locked != 0); } return(0); } int fstWriterGetFseekFailed(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { return(xc->fseek_failed != 0); } return(0); } /* * writer attr/scope/var creation: * fstWriterCreateVar2() is used to dump VHDL or other languages, but the * underlying variable needs to map to Verilog/SV via the proper fstVarType vt */ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle, const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt) { fstWriterSetAttrGeneric(ctx, type ? type : "", FST_MT_SUPVAR, (svt<valpos_mem) { fstDestroyMmaps(xc, 0); } fputc(vt, xc->hier_handle); fputc(vd, xc->hier_handle); nlen = strlen(nam); fstFwrite(nam, nlen, 1, xc->hier_handle); fputc(0, xc->hier_handle); xc->hier_file_len += (nlen+3); if((vt == FST_VT_VCD_REAL) || (vt == FST_VT_VCD_REAL_PARAMETER) || (vt == FST_VT_VCD_REALTIME) || (vt == FST_VT_SV_SHORTREAL)) { is_real = 1; len = 8; /* recast number of bytes to that of what a double is */ } else { is_real = 0; if(vt == FST_VT_GEN_STRING) { len = 0; } } xc->hier_file_len += fstWriterVarint(xc->hier_handle, len); if(aliasHandle > xc->maxhandle) aliasHandle = 0; xc->hier_file_len += fstWriterVarint(xc->hier_handle, aliasHandle); xc->numsigs++; if(xc->numsigs == xc->next_huge_break) { if(xc->fst_break_size < xc->fst_huge_break_size) { xc->next_huge_break += FST_ACTIVATE_HUGE_INC; xc->fst_break_size += xc->fst_orig_break_size; xc->fst_break_add_size += xc->fst_orig_break_add_size; xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size; if(xc->vchg_mem) { xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); } } } if(!aliasHandle) { uint32_t zero = 0; if(len) { fstWriterVarint(xc->geom_handle, !is_real ? len : 0); /* geom section encodes reals as zero byte */ } else { fstWriterVarint(xc->geom_handle, 0xFFFFFFFF); /* geom section encodes zero len as 32b -1 */ } fstFwrite(&xc->maxvalpos, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&len, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle); if(!is_real) { for(i=0;icurval_handle); } } else { fstFwrite(&xc->nan, 8, 1, xc->curval_handle); /* initialize doubles to NaN rather than x */ } xc->maxvalpos+=len; xc->maxhandle++; return(xc->maxhandle); } else { return(aliasHandle); } } return(0); } void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, const char *scopename, const char *scopecomp) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_VCD_SCOPE, xc->hier_handle); if(/*(scopetype < FST_ST_VCD_MODULE) ||*/ (scopetype > FST_ST_MAX)) { scopetype = FST_ST_VCD_MODULE; } fputc(scopetype, xc->hier_handle); fprintf(xc->hier_handle, "%s%c%s%c", scopename ? scopename : "", 0, scopecomp ? scopecomp : "", 0); if(scopename) { xc->hier_file_len += strlen(scopename); } if(scopecomp) { xc->hier_file_len += strlen(scopecomp); } xc->hier_file_len += 4; /* FST_ST_VCD_SCOPE + scopetype + two string terminating zeros */ xc->numscopes++; } } void fstWriterSetUpscope(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_VCD_UPSCOPE, xc->hier_handle); xc->hier_file_len++; } } void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_GEN_ATTRBEGIN, xc->hier_handle); if(/*(attrtype < FST_AT_MISC) ||*/ (attrtype > FST_AT_MAX)) { attrtype = FST_AT_MISC; subtype = FST_MT_UNKNOWN; } fputc(attrtype, xc->hier_handle); switch(attrtype) { case FST_AT_ARRAY: if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE; break; case FST_AT_ENUM: if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER; break; case FST_AT_PACK: if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE; break; case FST_AT_MISC: default: break; } fputc(subtype, xc->hier_handle); fprintf(xc->hier_handle, "%s%c", attrname ? attrname : "", 0); if(attrname) { xc->hier_file_len += strlen(attrname); } xc->hier_file_len += 4; /* FST_ST_GEN_ATTRBEGIN + type + subtype + string terminating zero */ xc->hier_file_len += fstWriterVarint(xc->hier_handle, arg); } } void fstWriterSetAttrEnd(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_GEN_ATTREND, xc->hier_handle); xc->hier_file_len++; } } fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr) { fstEnumHandle handle = 0; unsigned int *literal_lens = NULL; unsigned int *val_lens = NULL; int lit_len_tot = 0; int val_len_tot = 0; int name_len; char elem_count_buf[16]; int elem_count_len; int total_len; int pos = 0; char *attr_str = NULL; if(ctx && name && literal_arr && val_arr && (elem_count != 0)) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; uint32_t i; name_len = strlen(name); elem_count_len = sprintf(elem_count_buf, "%" PRIu32, elem_count); literal_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int)); val_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int)); for(i=0;i 0) { if(val_lens[i] < min_valbits) { val_len_tot += (min_valbits - val_lens[i]); /* additional converted len is same for '0' character */ } } } total_len = name_len + 1 + elem_count_len + 1 + lit_len_tot + elem_count + val_len_tot + elem_count; attr_str = (char*)malloc(total_len); pos = 0; memcpy(attr_str+pos, name, name_len); pos += name_len; attr_str[pos++] = ' '; memcpy(attr_str+pos, elem_count_buf, elem_count_len); pos += elem_count_len; attr_str[pos++] = ' '; for(i=0;i 0) { if(val_lens[i] < min_valbits) { memset(attr_str+pos, '0', min_valbits - val_lens[i]); pos += (min_valbits - val_lens[i]); } } pos += fstUtilityBinToEsc((unsigned char*)attr_str+pos, (unsigned char*)val_arr[i], val_lens[i]); attr_str[pos++] = ' '; } attr_str[pos-1] = 0; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "fstWriterCreateEnumTable() total_len: %d, pos: %d\n", total_len, pos); fprintf(stderr, FST_APIMESS "*%s*\n", attr_str); #endif fstWriterSetAttrBegin(xc, FST_AT_MISC, FST_MT_ENUMTABLE, attr_str, handle = ++xc->max_enumhandle); free(attr_str); free(val_lens); free(literal_lens); } return(handle); } void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && handle) { fstWriterSetAttrBegin(xc, FST_AT_MISC, FST_MT_ENUMTABLE, NULL, handle); } } /* * value and time change emission */ void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; const unsigned char *buf = (const unsigned char *)val; uint32_t offs; int len; if(FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; if(FST_UNLIKELY(!xc->valpos_mem)) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); } handle--; /* move starting at 1 index to starting at 0 */ vm4ip = &(xc->valpos_mem[4*handle]); len = vm4ip[1]; if(FST_LIKELY(len)) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */ { if(FST_LIKELY(!xc->is_initial_time)) { fpos = xc->vchg_siz; if(FST_UNLIKELY((fpos + len + 10) > xc->vchg_alloc_siz)) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); if(FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChange, exiting.\n"); exit(255); } } #ifdef FST_REMOVE_DUPLICATE_VC offs = vm4ip[0]; if(len != 1) { if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2])) { unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */ while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ } memcpy(old_value, buf, len); /* overlay new value */ memcpy(xc->curval_mem + offs, buf, len); return; } else { if(!memcmp(xc->curval_mem + offs, buf, len)) { if(!xc->curtime) { int i; for(i=0;icurval_mem + offs, buf, len); } else { if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2])) { unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */ while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ } *old_value = *buf; /* overlay new value */ *(xc->curval_mem + offs) = *buf; return; } else { if((*(xc->curval_mem + offs)) == (*buf)) { if(!xc->curtime) { if(*buf != 'x') return; } else { return; } } } *(xc->curval_mem + offs) = *buf; } #endif xc->vchg_siz += fstWriterUint32WithVarint32(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ vm4ip[3] = xc->tchn_idx; vm4ip[2] = fpos; } else { offs = vm4ip[0]; memcpy(xc->curval_mem + offs, buf, len); } } } } void fstWriterEmitValueChange32(void *ctx, fstHandle handle, uint32_t bits, uint32_t val) { char buf[32]; char *s = buf; uint32_t i; for (i = 0; i < bits; ++i) { *s++ = '0' + ((val >> (bits - i - 1)) & 1); } fstWriterEmitValueChange(ctx, handle, buf); } void fstWriterEmitValueChange64(void *ctx, fstHandle handle, uint32_t bits, uint64_t val) { char buf[64]; char *s = buf; uint32_t i; for (i = 0; i < bits; ++i) { *s++ = '0' + ((val >> (bits - i - 1)) & 1); } fstWriterEmitValueChange(ctx, handle, buf); } void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle, uint32_t bits, const uint32_t *val) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if (FST_UNLIKELY(bits <= 32)) { fstWriterEmitValueChange32(ctx, handle, bits, val[0]); } else if(FST_LIKELY(xc)) { int bq = bits / 32; int br = bits & 31; int i; int w; uint32_t v; unsigned char* s; if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) { xc->outval_alloc_siz = bits*2 + 1; xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz); if (FST_UNLIKELY(!xc->outval_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec32, exiting.\n"); exit(255); } } s = xc->outval_mem; { w = bq; v = val[w]; for (i = 0; i < br; ++i) { *s++ = '0' + ((v >> (br - i - 1)) & 1); } } for (w = bq - 1; w >= 0; --w) { v = val[w]; for (i = (32 - 4); i >= 0; i -= 4) { s[0] = '0' + ((v >> (i + 3)) & 1); s[1] = '0' + ((v >> (i + 2)) & 1); s[2] = '0' + ((v >> (i + 1)) & 1); s[3] = '0' + ((v >> (i + 0)) & 1); s += 4; } } fstWriterEmitValueChange(ctx, handle, xc->outval_mem); } } void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle, uint32_t bits, const uint64_t *val) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if (FST_UNLIKELY(bits <= 64)) { fstWriterEmitValueChange64(ctx, handle, bits, val[0]); } else if(FST_LIKELY(xc)) { int bq = bits / 64; int br = bits & 63; int i; int w; uint32_t v; unsigned char* s; if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) { xc->outval_alloc_siz = bits*2 + 1; xc->outval_mem = (unsigned char*)realloc(xc->outval_mem, xc->outval_alloc_siz); if (FST_UNLIKELY(!xc->outval_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec64, exiting.\n"); exit(255); } } s = xc->outval_mem; { w = bq; v = val[w]; for (i = 0; i < br; ++i) { *s++ = '0' + ((v >> (br - i - 1)) & 1); } } for (w = bq - 1; w >= 0; --w) { v = val[w]; for (i = (64 - 4); i >= 0; i -= 4) { s[0] = '0' + ((v >> (i + 3)) & 1); s[1] = '0' + ((v >> (i + 2)) & 1); s[2] = '0' + ((v >> (i + 1)) & 1); s[3] = '0' + ((v >> (i + 0)) & 1); s += 4; } } fstWriterEmitValueChange(ctx, handle, xc->outval_mem); } } void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; const unsigned char *buf = (const unsigned char *)val; if(FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; if(FST_UNLIKELY(!xc->valpos_mem)) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); } handle--; /* move starting at 1 index to starting at 0 */ vm4ip = &(xc->valpos_mem[4*handle]); /* there is no initial time dump for variable length value changes */ if(FST_LIKELY(!vm4ip[1])) /* len of zero = variable length */ { fpos = xc->vchg_siz; if(FST_UNLIKELY((fpos + len + 10 + 5) > xc->vchg_alloc_siz)) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); if(FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n"); exit(255); } } xc->vchg_siz += fstWriterUint32WithVarint32AndLength(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ vm4ip[3] = xc->tchn_idx; vm4ip[2] = fpos; } } } void fstWriterEmitTimeChange(void *ctx, uint64_t tim) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; unsigned int i; int skip = 0; if(xc) { if(FST_UNLIKELY(xc->is_initial_time)) { if(xc->size_limit_locked) /* this resets xc->is_initial_time to one */ { return; } if(!xc->valpos_mem) { fstWriterCreateMmaps(xc); } skip = 1; xc->firsttime = (xc->vc_emitted) ? 0: tim; xc->curtime = 0; xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; fstWriterEmitSectionHeader(xc); for(i=0;imaxhandle;i++) { xc->valpos_mem[4*i+2] = 0; /* zero out offset val */ xc->valpos_mem[4*i+3] = 0; /* zero out last time change val */ } xc->is_initial_time = 0; } else { if((xc->vchg_siz >= xc->fst_break_size) || (xc->flush_context_pending)) { xc->flush_context_pending = 0; fstWriterFlushContextPrivate(xc); xc->tchn_cnt++; fstWriterVarint(xc->tchn_handle, xc->curtime); } } if(!skip) { xc->tchn_idx++; } fstWriterVarint(xc->tchn_handle, tim - xc->curtime); xc->tchn_cnt++; xc->curtime = tim; } } void fstWriterEmitDumpActive(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { struct fstBlackoutChain *b = (struct fstBlackoutChain *)calloc(1, sizeof(struct fstBlackoutChain)); b->tim = xc->curtime; b->active = (enable != 0); xc->num_blackouts++; if(xc->blackout_curr) { xc->blackout_curr->next = b; xc->blackout_curr = b; } else { xc->blackout_head = b; xc->blackout_curr = b; } } } /***********************/ /*** ***/ /*** reader function ***/ /*** ***/ /***********************/ /* * private structs */ static const char *vartypes[] = { "event", "integer", "parameter", "real", "real_parameter", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "sparray", "realtime", "string", "bit", "logic", "int", "shortint", "longint", "byte", "enum", "shortreal" }; static const char *modtypes[] = { "module", "task", "function", "begin", "fork", "generate", "struct", "union", "class", "interface", "package", "program", "vhdl_architecture", "vhdl_procedure", "vhdl_function", "vhdl_record", "vhdl_process", "vhdl_block", "vhdl_for_generate", "vhdl_if_generate", "vhdl_generate", "vhdl_package" }; static const char *attrtypes[] = { "misc", "array", "enum", "class" }; static const char *arraytypes[] = { "none", "unpacked", "packed", "sparse" }; static const char *enumvaluetypes[] = { "integer", "bit", "logic", "int", "shortint", "longint", "byte", "unsigned_integer", "unsigned_bit", "unsigned_logic", "unsigned_int", "unsigned_shortint", "unsigned_longint", "unsigned_byte" }; static const char *packtypes[] = { "none", "unpacked", "packed", "tagged_packed" }; struct fstCurrHier { struct fstCurrHier *prev; void *user_info; int len; }; struct fstReaderContext { /* common entries */ FILE *f, *fh; uint64_t start_time, end_time; uint64_t mem_used_by_writer; uint64_t scope_count; uint64_t var_count; fstHandle maxhandle; uint64_t num_alias; uint64_t vc_section_count; uint32_t *signal_lens; /* maxhandle sized */ unsigned char *signal_typs; /* maxhandle sized */ unsigned char *process_mask; /* maxhandle-based, bitwise sized */ uint32_t longest_signal_value_len; /* longest len value encountered */ unsigned char *temp_signal_value_buf; /* malloced for len in longest_signal_value_len */ signed char timescale; unsigned char filetype; unsigned use_vcd_extensions : 1; unsigned double_endian_match : 1; unsigned native_doubles_for_cb : 1; unsigned contains_geom_section : 1; unsigned contains_hier_section : 1; /* valid for hier_pos */ unsigned contains_hier_section_lz4duo : 1; /* valid for hier_pos (contains_hier_section_lz4 always also set) */ unsigned contains_hier_section_lz4 : 1; /* valid for hier_pos */ unsigned limit_range_valid : 1; /* valid for limit_range_start, limit_range_end */ char version[FST_HDR_SIM_VERSION_SIZE + 1]; char date[FST_HDR_DATE_SIZE + 1]; int64_t timezero; char *filename, *filename_unpacked; fst_off_t hier_pos; uint32_t num_blackouts; uint64_t *blackout_times; unsigned char *blackout_activity; uint64_t limit_range_start, limit_range_end; /* entries specific to read value at time functions */ unsigned rvat_data_valid : 1; uint64_t *rvat_time_table; uint64_t rvat_beg_tim, rvat_end_tim; unsigned char *rvat_frame_data; uint64_t rvat_frame_maxhandle; fst_off_t *rvat_chain_table; uint32_t *rvat_chain_table_lengths; uint64_t rvat_vc_maxhandle; fst_off_t rvat_vc_start; uint32_t *rvat_sig_offs; int rvat_packtype; uint32_t rvat_chain_len; unsigned char *rvat_chain_mem; fstHandle rvat_chain_facidx; uint32_t rvat_chain_pos_tidx; uint32_t rvat_chain_pos_idx; uint64_t rvat_chain_pos_time; unsigned rvat_chain_pos_valid : 1; /* entries specific to hierarchy traversal */ struct fstHier hier; struct fstCurrHier *curr_hier; fstHandle current_handle; char *curr_flat_hier_nam; int flat_hier_alloc_len; unsigned do_rewind : 1; char str_scope_nam[FST_ID_NAM_SIZ+1]; char str_scope_comp[FST_ID_NAM_SIZ+1]; unsigned fseek_failed : 1; /* self-buffered I/O for writes */ #ifndef FST_WRITEX_DISABLE int writex_pos; int writex_fd; unsigned char writex_buf[FST_WRITEX_MAX]; #endif char *f_nam; char *fh_nam; }; int fstReaderFseeko(struct fstReaderContext *xc, FILE *stream, fst_off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if(rc<0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "Seek to #%" PRId64 " (whence = %d) failed!\n", offset, whence); perror("Why"); #endif } return(rc); } #ifndef FST_WRITEX_DISABLE static void fstWritex(struct fstReaderContext *xc, void *v, int len) { unsigned char *s = (unsigned char *)v; if(len) { if(len < FST_WRITEX_MAX) { if(xc->writex_pos + len >= FST_WRITEX_MAX) { fstWritex(xc, NULL, 0); } memcpy(xc->writex_buf + xc->writex_pos, s, len); xc->writex_pos += len; } else { fstWritex(xc, NULL, 0); if (write(xc->writex_fd, s, len)) { }; } } else { if(xc->writex_pos) { if(write(xc->writex_fd, xc->writex_buf, xc->writex_pos)) { }; xc->writex_pos = 0; } } } #endif /* * scope -> flat name handling */ static void fstReaderDeallocateScopeData(struct fstReaderContext *xc) { struct fstCurrHier *chp; free(xc->curr_flat_hier_nam); xc->curr_flat_hier_nam = NULL; while(xc->curr_hier) { chp = xc->curr_hier->prev; free(xc->curr_hier); xc->curr_hier = chp; } } const char *fstReaderGetCurrentFlatScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : ""); } else { return(NULL); } } void *fstReaderGetCurrentScopeUserInfo(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->curr_hier ? xc->curr_hier->user_info : NULL); } else { return(NULL); } } const char *fstReaderPopScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && xc->curr_hier) { struct fstCurrHier *ch = xc->curr_hier; if(xc->curr_hier->prev) { xc->curr_flat_hier_nam[xc->curr_hier->prev->len] = 0; } else { *xc->curr_flat_hier_nam = 0; } xc->curr_hier = xc->curr_hier->prev; free(ch); return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : ""); } return(NULL); } void fstReaderResetScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { while(fstReaderPopScope(xc)); /* remove any already-built scoping info */ } } const char *fstReaderPushScope(void *ctx, const char *nam, void *user_info) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { struct fstCurrHier *ch = (struct fstCurrHier *)malloc(sizeof(struct fstCurrHier)); int chl = xc->curr_hier ? xc->curr_hier->len : 0; int len = chl + 1 + strlen(nam); if(len >= xc->flat_hier_alloc_len) { xc->curr_flat_hier_nam = xc->curr_flat_hier_nam ? (char *)realloc(xc->curr_flat_hier_nam, len+1) : (char *)malloc(len+1); } if(chl) { xc->curr_flat_hier_nam[chl] = '.'; strcpy(xc->curr_flat_hier_nam + chl + 1, nam); } else { strcpy(xc->curr_flat_hier_nam, nam); len--; } ch->len = len; ch->prev = xc->curr_hier; ch->user_info = user_info; xc->curr_hier = ch; return(xc->curr_flat_hier_nam); } return(NULL); } int fstReaderGetCurrentScopeLen(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && xc->curr_hier) { return(xc->curr_hier->len); } return(0); } int fstReaderGetFseekFailed(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->fseek_failed != 0); } return(0); } /* * iter mask manipulation util functions */ int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { facidx--; if(facidxmaxhandle) { int process_idx = facidx/8; int process_bit = facidx&7; return( (xc->process_mask[process_idx]&(1<maxhandle) { int idx = facidx/8; int bitpos = facidx&7; xc->process_mask[idx] |= (1<maxhandle) { int idx = facidx/8; int bitpos = facidx&7; xc->process_mask[idx] &= (~(1<process_mask, 0xff, (xc->maxhandle+7)/8); } } void fstReaderClrFacProcessMaskAll(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { memset(xc->process_mask, 0x00, (xc->maxhandle+7)/8); } } /* * various utility read/write functions */ signed char fstReaderGetTimescale(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->timescale : 0); } uint64_t fstReaderGetStartTime(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->start_time : 0); } uint64_t fstReaderGetEndTime(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->end_time : 0); } uint64_t fstReaderGetMemoryUsedByWriter(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->mem_used_by_writer : 0); } uint64_t fstReaderGetScopeCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->scope_count : 0); } uint64_t fstReaderGetVarCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->var_count : 0); } fstHandle fstReaderGetMaxHandle(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->maxhandle : 0); } uint64_t fstReaderGetAliasCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->num_alias : 0); } uint64_t fstReaderGetValueChangeSectionCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->vc_section_count : 0); } int fstReaderGetDoubleEndianMatchState(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->double_endian_match : 0); } const char *fstReaderGetVersionString(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->version : NULL); } const char *fstReaderGetDateString(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->date : NULL); } int fstReaderGetFileType(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? (int)xc->filetype : (int)FST_FT_VERILOG); } int64_t fstReaderGetTimezero(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->timezero : 0); } uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->num_blackouts : 0); } uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && (idx < xc->num_blackouts) && (xc->blackout_times)) { return(xc->blackout_times[idx]); } else { return(0); } } unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && (idx < xc->num_blackouts) && (xc->blackout_activity)) { return(xc->blackout_activity[idx]); } else { return(0); } } void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->limit_range_valid = 1; xc->limit_range_start = start_time; xc->limit_range_end = end_time; } } void fstReaderSetUnlimitedTimeRange(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->limit_range_valid = 0; } } void fstReaderSetVcdExtensions(void *ctx, int enable) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->use_vcd_extensions = (enable != 0); } } void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->native_doubles_for_cb = (enable != 0); } } /* * hierarchy processing */ static void fstVcdID(char *buf, unsigned int value) { char *pnt = buf; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } *pnt = 0; } static int fstVcdIDForFwrite(char *buf, unsigned int value) { char *pnt = buf; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } return(pnt - buf); } static int fstReaderRecreateHierFile(struct fstReaderContext *xc) { int pass_status = 1; if(!xc->fh) { fst_off_t offs_cache = ftello(xc->f); char *fnam = (char *)malloc(strlen(xc->filename) + 6 + 16 + 32 + 1); unsigned char *mem = (unsigned char *)malloc(FST_GZIO_LEN); fst_off_t hl, uclen; fst_off_t clen = 0; gzFile zhandle = NULL; int zfd; int htyp = FST_BL_SKIP; /* can't handle both set at once should never happen in a real file */ if(!xc->contains_hier_section_lz4 && xc->contains_hier_section) { htyp = FST_BL_HIER; } else if(xc->contains_hier_section_lz4 && !xc->contains_hier_section) { htyp = xc->contains_hier_section_lz4duo ? FST_BL_HIER_LZ4DUO : FST_BL_HIER_LZ4; } sprintf(fnam, "%s.hier_%d_%p", xc->filename, getpid(), (void *)xc); fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET); uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif if(htyp == FST_BL_HIER) { fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET); uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif zfd = dup(fileno(xc->f)); zhandle = gzdopen(zfd, "rb"); if(!zhandle) { close(zfd); free(mem); free(fnam); return(0); } } else if((htyp == FST_BL_HIER_LZ4) || (htyp == FST_BL_HIER_LZ4DUO)) { fstReaderFseeko(xc, xc->f, xc->hier_pos - 8, SEEK_SET); /* get section len */ clen = fstReaderUint64(xc->f) - 16; uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif } #ifndef __MINGW32__ xc->fh = fopen(fnam, "w+b"); if(!xc->fh) #endif { xc->fh = tmpfile_open(&xc->fh_nam); free(fnam); fnam = NULL; if(!xc->fh) { tmpfile_close(&xc->fh, &xc->fh_nam); free(mem); return(0); } } #ifndef __MINGW32__ if(fnam) unlink(fnam); #endif if(htyp == FST_BL_HIER) { for(hl = 0; hl < uclen; hl += FST_GZIO_LEN) { size_t len = ((uclen - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - hl); size_t gzreadlen = gzread(zhandle, mem, len); /* rc should equal len... */ size_t fwlen; if(gzreadlen != len) { pass_status = 0; break; } fwlen = fstFwrite(mem, len, 1, xc->fh); if(fwlen != 1) { pass_status = 0; break; } } gzclose(zhandle); } else if(htyp == FST_BL_HIER_LZ4DUO) { unsigned char *lz4_cmem = (unsigned char *)malloc(clen); unsigned char *lz4_ucmem = (unsigned char *)malloc(uclen); unsigned char *lz4_ucmem2; uint64_t uclen2; int skiplen2 = 0; fstFread(lz4_cmem, clen, 1, xc->f); uclen2 = fstGetVarint64(lz4_cmem, &skiplen2); lz4_ucmem2 = (unsigned char *)malloc(uclen2); pass_status = (uclen2 == (uint64_t)LZ4_decompress_safe_partial ((char *)lz4_cmem + skiplen2, (char *)lz4_ucmem2, clen - skiplen2, uclen2, uclen2)); if(pass_status) { pass_status = (uclen == LZ4_decompress_safe_partial ((char *)lz4_ucmem2, (char *)lz4_ucmem, uclen2, uclen, uclen)); if(fstFwrite(lz4_ucmem, uclen, 1, xc->fh) != 1) { pass_status = 0; } } free(lz4_ucmem2); free(lz4_ucmem); free(lz4_cmem); } else if(htyp == FST_BL_HIER_LZ4) { unsigned char *lz4_cmem = (unsigned char *)malloc(clen); unsigned char *lz4_ucmem = (unsigned char *)malloc(uclen); fstFread(lz4_cmem, clen, 1, xc->f); pass_status = (uclen == LZ4_decompress_safe_partial ((char *)lz4_cmem, (char *)lz4_ucmem, clen, uclen, uclen)); if(fstFwrite(lz4_ucmem, uclen, 1, xc->fh) != 1) { pass_status = 0; } free(lz4_ucmem); free(lz4_cmem); } else /* FST_BL_SKIP */ { pass_status = 0; if(xc->fh) { fclose(xc->fh); xc->fh = NULL; /* needed in case .hier file is missing and there are no hier sections */ } } free(mem); free(fnam); fstReaderFseeko(xc, xc->f, offs_cache, SEEK_SET); } return(pass_status); } int fstReaderIterateHierRewind(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; int pass_status = 0; if(xc) { pass_status = 1; if(!xc->fh) { pass_status = fstReaderRecreateHierFile(xc); } xc->do_rewind = 1; } return(pass_status); } struct fstHier *fstReaderIterateHier(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; int isfeof; fstHandle alias; char *pnt; int ch; if(!xc) return(NULL); if(!xc->fh) { if(!fstReaderRecreateHierFile(xc)) { return(NULL); } } if(xc->do_rewind) { xc->do_rewind = 0; xc->current_handle = 0; fstReaderFseeko(xc, xc->fh, 0, SEEK_SET); clearerr(xc->fh); } if(!(isfeof=feof(xc->fh))) { int tag = fgetc(xc->fh); switch(tag) { case FST_ST_VCD_SCOPE: xc->hier.htyp = FST_HT_SCOPE; xc->hier.u.scope.typ = fgetc(xc->fh); xc->hier.u.scope.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; xc->hier.u.scope.name_length = pnt - xc->hier.u.scope.name; xc->hier.u.scope.component = pnt = xc->str_scope_comp; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopecomp */ *pnt = 0; xc->hier.u.scope.component_length = pnt - xc->hier.u.scope.component; break; case FST_ST_VCD_UPSCOPE: xc->hier.htyp = FST_HT_UPSCOPE; break; case FST_ST_GEN_ATTRBEGIN: xc->hier.htyp = FST_HT_ATTRBEGIN; xc->hier.u.attr.typ = fgetc(xc->fh); xc->hier.u.attr.subtype = fgetc(xc->fh); xc->hier.u.attr.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; xc->hier.u.attr.name_length = pnt - xc->hier.u.scope.name; xc->hier.u.attr.arg = fstReaderVarint64(xc->fh); if(xc->hier.u.attr.typ == FST_AT_MISC) { if((xc->hier.u.attr.subtype == FST_MT_SOURCESTEM)||(xc->hier.u.attr.subtype == FST_MT_SOURCEISTEM)) { int sidx_skiplen_dummy = 0; xc->hier.u.attr.arg_from_name = fstGetVarint64((unsigned char *)xc->str_scope_nam, &sidx_skiplen_dummy); } } break; case FST_ST_GEN_ATTREND: xc->hier.htyp = FST_HT_ATTREND; break; case FST_VT_VCD_EVENT: case FST_VT_VCD_INTEGER: case FST_VT_VCD_PARAMETER: case FST_VT_VCD_REAL: case FST_VT_VCD_REAL_PARAMETER: case FST_VT_VCD_REG: case FST_VT_VCD_SUPPLY0: case FST_VT_VCD_SUPPLY1: case FST_VT_VCD_TIME: case FST_VT_VCD_TRI: case FST_VT_VCD_TRIAND: case FST_VT_VCD_TRIOR: case FST_VT_VCD_TRIREG: case FST_VT_VCD_TRI0: case FST_VT_VCD_TRI1: case FST_VT_VCD_WAND: case FST_VT_VCD_WIRE: case FST_VT_VCD_WOR: case FST_VT_VCD_PORT: case FST_VT_VCD_SPARRAY: case FST_VT_VCD_REALTIME: case FST_VT_GEN_STRING: case FST_VT_SV_BIT: case FST_VT_SV_LOGIC: case FST_VT_SV_INT: case FST_VT_SV_SHORTINT: case FST_VT_SV_LONGINT: case FST_VT_SV_BYTE: case FST_VT_SV_ENUM: case FST_VT_SV_SHORTREAL: xc->hier.htyp = FST_HT_VAR; xc->hier.u.var.svt_workspace = FST_SVT_NONE; xc->hier.u.var.sdt_workspace = FST_SDT_NONE; xc->hier.u.var.sxt_workspace = 0; xc->hier.u.var.typ = tag; xc->hier.u.var.direction = fgetc(xc->fh); xc->hier.u.var.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* varname */ *pnt = 0; xc->hier.u.var.name_length = pnt - xc->hier.u.var.name; xc->hier.u.var.length = fstReaderVarint32(xc->fh); if(tag == FST_VT_VCD_PORT) { xc->hier.u.var.length -= 2; /* removal of delimiting spaces */ xc->hier.u.var.length /= 3; /* port -> signal size adjust */ } alias = fstReaderVarint32(xc->fh); if(!alias) { xc->current_handle++; xc->hier.u.var.handle = xc->current_handle; xc->hier.u.var.is_alias = 0; } else { xc->hier.u.var.handle = alias; xc->hier.u.var.is_alias = 1; } break; default: isfeof = 1; break; } } return(!isfeof ? &xc->hier : NULL); } int fstReaderProcessHier(void *ctx, FILE *fv) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; char *str; char *pnt; int ch, scopetype; int vartype; uint32_t len, alias; /* uint32_t maxvalpos=0; */ unsigned int num_signal_dyn = 65536; int attrtype, subtype; uint64_t attrarg; fstHandle maxhandle_scanbuild; if(!xc) return(0); xc->longest_signal_value_len = 32; /* arbitrarily set at 32...this is much longer than an expanded double */ if(!xc->fh) { if(!fstReaderRecreateHierFile(xc)) { return(0); } } str = (char *)malloc(FST_ID_NAM_ATTR_SIZ+1); if(fv) { char time_dimension[2] = {0, 0}; int time_scale = 1; fprintf(fv, "$date\n\t%s\n$end\n", xc->date); fprintf(fv, "$version\n\t%s\n$end\n", xc->version); if(xc->timezero) fprintf(fv, "$timezero\n\t%" PRId64 "\n$end\n", xc->timezero); switch(xc->timescale) { case 2: time_scale = 100; time_dimension[0] = 0; break; case 1: time_scale = 10; /* fallthrough */ case 0: time_dimension[0] = 0; break; case -1: time_scale = 100; time_dimension[0] = 'm'; break; case -2: time_scale = 10; /* fallthrough */ case -3: time_dimension[0] = 'm'; break; case -4: time_scale = 100; time_dimension[0] = 'u'; break; case -5: time_scale = 10; /* fallthrough */ case -6: time_dimension[0] = 'u'; break; case -10: time_scale = 100; time_dimension[0] = 'p'; break; case -11: time_scale = 10; /* fallthrough */ case -12: time_dimension[0] = 'p'; break; case -13: time_scale = 100; time_dimension[0] = 'f'; break; case -14: time_scale = 10; /* fallthrough */ case -15: time_dimension[0] = 'f'; break; case -16: time_scale = 100; time_dimension[0] = 'a'; break; case -17: time_scale = 10; /* fallthrough */ case -18: time_dimension[0] = 'a'; break; case -19: time_scale = 100; time_dimension[0] = 'z'; break; case -20: time_scale = 10; /* fallthrough */ case -21: time_dimension[0] = 'z'; break; case -7: time_scale = 100; time_dimension[0] = 'n'; break; case -8: time_scale = 10; /* fallthrough */ case -9: default: time_dimension[0] = 'n'; break; } if(fv) fprintf(fv, "$timescale\n\t%d%ss\n$end\n", time_scale, time_dimension); } xc->maxhandle = 0; xc->num_alias = 0; free(xc->signal_lens); xc->signal_lens = (uint32_t *)malloc(num_signal_dyn*sizeof(uint32_t)); free(xc->signal_typs); xc->signal_typs = (unsigned char *)malloc(num_signal_dyn*sizeof(unsigned char)); fstReaderFseeko(xc, xc->fh, 0, SEEK_SET); while(!feof(xc->fh)) { int tag = fgetc(xc->fh); switch(tag) { case FST_ST_VCD_SCOPE: scopetype = fgetc(xc->fh); if((scopetype < FST_ST_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE; pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; while(fgetc(xc->fh)) { }; /* scopecomp */ if(fv) fprintf(fv, "$scope %s %s $end\n", modtypes[scopetype], str); break; case FST_ST_VCD_UPSCOPE: if(fv) fprintf(fv, "$upscope $end\n"); break; case FST_ST_GEN_ATTRBEGIN: attrtype = fgetc(xc->fh); subtype = fgetc(xc->fh); pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* attrname */ *pnt = 0; if(!str[0]) { strcpy(str, "\"\""); } attrarg = fstReaderVarint64(xc->fh); if(fv && xc->use_vcd_extensions) { switch(attrtype) { case FST_AT_ARRAY: if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE; fprintf(fv, "$attrbegin %s %s %s %" PRId64 " $end\n", attrtypes[attrtype], arraytypes[subtype], str, attrarg); break; case FST_AT_ENUM: if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER; fprintf(fv, "$attrbegin %s %s %s %" PRId64 " $end\n", attrtypes[attrtype], enumvaluetypes[subtype], str, attrarg); break; case FST_AT_PACK: if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE; fprintf(fv, "$attrbegin %s %s %s %" PRId64 " $end\n", attrtypes[attrtype], packtypes[subtype], str, attrarg); break; case FST_AT_MISC: default: attrtype = FST_AT_MISC; if(subtype == FST_MT_COMMENT) { fprintf(fv, "$comment\n\t%s\n$end\n", str); } else { if((subtype == FST_MT_SOURCESTEM)||(subtype == FST_MT_SOURCEISTEM)) { int sidx_skiplen_dummy = 0; uint64_t sidx = fstGetVarint64((unsigned char *)str, &sidx_skiplen_dummy); fprintf(fv, "$attrbegin %s %02x %" PRId64 " %" PRId64 " $end\n", attrtypes[attrtype], subtype, sidx, attrarg); } else { fprintf(fv, "$attrbegin %s %02x %s %" PRId64 " $end\n", attrtypes[attrtype], subtype, str, attrarg); } } break; } } break; case FST_ST_GEN_ATTREND: if(fv && xc->use_vcd_extensions) fprintf(fv, "$attrend $end\n"); break; case FST_VT_VCD_EVENT: case FST_VT_VCD_INTEGER: case FST_VT_VCD_PARAMETER: case FST_VT_VCD_REAL: case FST_VT_VCD_REAL_PARAMETER: case FST_VT_VCD_REG: case FST_VT_VCD_SUPPLY0: case FST_VT_VCD_SUPPLY1: case FST_VT_VCD_TIME: case FST_VT_VCD_TRI: case FST_VT_VCD_TRIAND: case FST_VT_VCD_TRIOR: case FST_VT_VCD_TRIREG: case FST_VT_VCD_TRI0: case FST_VT_VCD_TRI1: case FST_VT_VCD_WAND: case FST_VT_VCD_WIRE: case FST_VT_VCD_WOR: case FST_VT_VCD_PORT: case FST_VT_VCD_SPARRAY: case FST_VT_VCD_REALTIME: case FST_VT_GEN_STRING: case FST_VT_SV_BIT: case FST_VT_SV_LOGIC: case FST_VT_SV_INT: case FST_VT_SV_SHORTINT: case FST_VT_SV_LONGINT: case FST_VT_SV_BYTE: case FST_VT_SV_ENUM: case FST_VT_SV_SHORTREAL: vartype = tag; /* vardir = */ fgetc(xc->fh); /* unused in VCD reader, but need to advance read pointer */ pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* varname */ *pnt = 0; len = fstReaderVarint32(xc->fh); alias = fstReaderVarint32(xc->fh); if(!alias) { if(xc->maxhandle == num_signal_dyn) { num_signal_dyn *= 2; xc->signal_lens = (uint32_t *)realloc(xc->signal_lens, num_signal_dyn*sizeof(uint32_t)); xc->signal_typs = (unsigned char *)realloc(xc->signal_typs, num_signal_dyn*sizeof(unsigned char)); } xc->signal_lens[xc->maxhandle] = len; xc->signal_typs[xc->maxhandle] = vartype; /* maxvalpos+=len; */ if(len > xc->longest_signal_value_len) { xc->longest_signal_value_len = len; } if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL)) { len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32; xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL; } if(fv) { char vcdid_buf[16]; uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3); fstVcdID(vcdid_buf, xc->maxhandle+1); fprintf(fv, "$var %s %" PRIu32 " %s %s $end\n", vartypes[vartype], modlen, vcdid_buf, str); } xc->maxhandle++; } else { if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL)) { len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32; xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL; } if(fv) { char vcdid_buf[16]; uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3); fstVcdID(vcdid_buf, alias); fprintf(fv, "$var %s %" PRIu32 " %s %s $end\n", vartypes[vartype], modlen, vcdid_buf, str); } xc->num_alias++; } break; default: break; } } if(fv) fprintf(fv, "$enddefinitions $end\n"); maxhandle_scanbuild = xc->maxhandle ? xc->maxhandle : 1; /*scan-build warning suppression, in reality we have at least one signal */ xc->signal_lens = (uint32_t *)realloc(xc->signal_lens, maxhandle_scanbuild*sizeof(uint32_t)); xc->signal_typs = (unsigned char *)realloc(xc->signal_typs, maxhandle_scanbuild*sizeof(unsigned char)); free(xc->process_mask); xc->process_mask = (unsigned char *)calloc(1, (maxhandle_scanbuild+7)/8); free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = (unsigned char *)malloc(xc->longest_signal_value_len + 1); xc->var_count = xc->maxhandle + xc->num_alias; free(str); return(1); } /* * reader file open/close functions */ int fstReaderInit(struct fstReaderContext *xc) { fst_off_t blkpos = 0; fst_off_t endfile; uint64_t seclen; int sectype; uint64_t vc_section_count_actual = 0; int hdr_incomplete = 0; int hdr_seen = 0; int gzread_pass_status = 1; sectype = fgetc(xc->f); if(sectype == FST_BL_ZWRAPPER) { FILE *fcomp; fst_off_t offpnt, uclen; char gz_membuf[FST_GZIO_LEN]; gzFile zhandle; int zfd; int flen = strlen(xc->filename); char *hf; seclen = fstReaderUint64(xc->f); uclen = fstReaderUint64(xc->f); if(!seclen) return(0); /* not finished compressing, this is a failed read */ hf = (char *)calloc(1, flen + 16 + 32 + 1); sprintf(hf, "%s.upk_%d_%p", xc->filename, getpid(), (void *)xc); fcomp = fopen(hf, "w+b"); if(!fcomp) { fcomp = tmpfile_open(&xc->f_nam); free(hf); hf = NULL; if(!fcomp) { tmpfile_close(&fcomp, &xc->f_nam); return(0); } } #if defined(FST_UNBUFFERED_IO) setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ #endif #ifdef __MINGW32__ xc->filename_unpacked = hf; #else if(hf) { unlink(hf); free(hf); } #endif fstReaderFseeko(xc, xc->f, 1+8+8, SEEK_SET); #ifndef __MINGW32__ fflush(xc->f); #endif zfd = dup(fileno(xc->f)); zhandle = gzdopen(zfd, "rb"); if(zhandle) { for(offpnt = 0; offpnt < uclen; offpnt += FST_GZIO_LEN) { size_t this_len = ((uclen - offpnt) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - offpnt); size_t gzreadlen = gzread(zhandle, gz_membuf, this_len); size_t fwlen; if(gzreadlen != this_len) { gzread_pass_status = 0; break; } fwlen = fstFwrite(gz_membuf, this_len, 1, fcomp); if(fwlen != 1) { gzread_pass_status = 0; break; } } gzclose(zhandle); } else { close(zfd); } fflush(fcomp); fclose(xc->f); xc->f = fcomp; } if(gzread_pass_status) { fstReaderFseeko(xc, xc->f, 0, SEEK_END); endfile = ftello(xc->f); while(blkpos < endfile) { fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if(sectype == EOF) { break; } if((hdr_incomplete) && (!seclen)) { break; } if(!hdr_seen && (sectype != FST_BL_HDR)) { break; } blkpos++; if(sectype == FST_BL_HDR) { if(!hdr_seen) { int ch; double dcheck; xc->start_time = fstReaderUint64(xc->f); xc->end_time = fstReaderUint64(xc->f); hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); fstFread(&dcheck, 8, 1, xc->f); xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); if(!xc->double_endian_match) { union { unsigned char rvs_buf[8]; double d; } vu; unsigned char *dcheck_alias = (unsigned char *)&dcheck; int rvs_idx; for(rvs_idx=0;rvs_idx<8;rvs_idx++) { vu.rvs_buf[rvs_idx] = dcheck_alias[7-rvs_idx]; } if(vu.d != FST_DOUBLE_ENDTEST) { break; /* either corrupt file or wrong architecture (offset +33 also functions as matchword) */ } } hdr_seen = 1; xc->mem_used_by_writer = fstReaderUint64(xc->f); xc->scope_count = fstReaderUint64(xc->f); xc->var_count = fstReaderUint64(xc->f); xc->maxhandle = fstReaderUint64(xc->f); xc->num_alias = xc->var_count - xc->maxhandle; xc->vc_section_count = fstReaderUint64(xc->f); ch = fgetc(xc->f); xc->timescale = (signed char)ch; fstFread(xc->version, FST_HDR_SIM_VERSION_SIZE, 1, xc->f); xc->version[FST_HDR_SIM_VERSION_SIZE] = 0; fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f); xc->date[FST_HDR_DATE_SIZE] = 0; ch = fgetc(xc->f); xc->filetype = (unsigned char)ch; xc->timezero = fstReaderUint64(xc->f); } } else if((sectype == FST_BL_VCDATA) || (sectype == FST_BL_VCDATA_DYN_ALIAS) || (sectype == FST_BL_VCDATA_DYN_ALIAS2)) { if(hdr_incomplete) { uint64_t bt = fstReaderUint64(xc->f); xc->end_time = fstReaderUint64(xc->f); if(!vc_section_count_actual) { xc->start_time = bt; } } vc_section_count_actual++; } else if(sectype == FST_BL_GEOM) { if(!hdr_incomplete) { uint64_t clen = seclen - 24; uint64_t uclen = fstReaderUint64(xc->f); unsigned char *ucdata = (unsigned char *)malloc(uclen); unsigned char *pnt = ucdata; unsigned int i; xc->contains_geom_section = 1; xc->maxhandle = fstReaderUint64(xc->f); xc->longest_signal_value_len = 32; /* arbitrarily set at 32...this is much longer than an expanded double */ free(xc->process_mask); xc->process_mask = (unsigned char *)calloc(1, (xc->maxhandle+7)/8); if(clen != uclen) { unsigned char *cdata = (unsigned char *)malloc(clen); unsigned long destlen = uclen; unsigned long sourcelen = clen; int rc; fstFread(cdata, clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderInit(), geom uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, uclen, 1, xc->f); } free(xc->signal_lens); xc->signal_lens = (uint32_t *)malloc(sizeof(uint32_t) * xc->maxhandle); free(xc->signal_typs); xc->signal_typs = (unsigned char *)malloc(sizeof(unsigned char) * xc->maxhandle); for(i=0;imaxhandle;i++) { int skiplen; uint64_t val = fstGetVarint32(pnt, &skiplen); pnt += skiplen; if(val) { xc->signal_lens[i] = (val != 0xFFFFFFFF) ? val : 0; xc->signal_typs[i] = FST_VT_VCD_WIRE; if(xc->signal_lens[i] > xc->longest_signal_value_len) { xc->longest_signal_value_len = xc->signal_lens[i]; } } else { xc->signal_lens[i] = 8; /* backpatch in real */ xc->signal_typs[i] = FST_VT_VCD_REAL; /* xc->longest_signal_value_len handled above by overly large init size */ } } free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = (unsigned char *)malloc(xc->longest_signal_value_len + 1); free(ucdata); } } else if(sectype == FST_BL_HIER) { xc->contains_hier_section = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_HIER_LZ4DUO) { xc->contains_hier_section_lz4 = 1; xc->contains_hier_section_lz4duo = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_HIER_LZ4) { xc->contains_hier_section_lz4 = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_BLACKOUT) { uint32_t i; uint64_t cur_bl = 0; uint64_t delta; xc->num_blackouts = fstReaderVarint32(xc->f); free(xc->blackout_times); xc->blackout_times = (uint64_t *)calloc(xc->num_blackouts, sizeof(uint64_t)); free(xc->blackout_activity); xc->blackout_activity = (unsigned char *)calloc(xc->num_blackouts, sizeof(unsigned char)); for(i=0;inum_blackouts;i++) { xc->blackout_activity[i] = fgetc(xc->f) != 0; delta = fstReaderVarint64(xc->f); cur_bl += delta; xc->blackout_times[i] = cur_bl; } } blkpos += seclen; if(!hdr_seen) break; } if(hdr_seen) { if(xc->vc_section_count != vc_section_count_actual) { xc->vc_section_count = vc_section_count_actual; } if(!xc->contains_geom_section) { fstReaderProcessHier(xc, NULL); /* recreate signal_lens/signal_typs info */ } } } return(hdr_seen); } void *fstReaderOpenForUtilitiesOnly(void) { struct fstReaderContext *xc = (struct fstReaderContext *)calloc(1, sizeof(struct fstReaderContext)); return(xc); } void *fstReaderOpen(const char *nam) { struct fstReaderContext *xc = (struct fstReaderContext *)calloc(1, sizeof(struct fstReaderContext)); if((!nam)||(!(xc->f=fopen(nam, "rb")))) { free(xc); xc=NULL; } else { int flen = strlen(nam); char *hf = (char *)calloc(1, flen + 6); int rc; #if defined(FST_UNBUFFERED_IO) setvbuf(xc->f, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ #endif memcpy(hf, nam, flen); strcpy(hf + flen, ".hier"); xc->fh = fopen(hf, "rb"); free(hf); xc->filename = strdup(nam); rc = fstReaderInit(xc); if((rc) && (xc->vc_section_count) && (xc->maxhandle) && ((xc->fh)||(xc->contains_hier_section||(xc->contains_hier_section_lz4)))) { /* more init */ xc->do_rewind = 1; } else { fstReaderClose(xc); xc = NULL; } } return(xc); } static void fstReaderDeallocateRvatData(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { free(xc->rvat_chain_mem); xc->rvat_chain_mem = NULL; free(xc->rvat_frame_data); xc->rvat_frame_data = NULL; free(xc->rvat_time_table); xc->rvat_time_table = NULL; free(xc->rvat_chain_table); xc->rvat_chain_table = NULL; free(xc->rvat_chain_table_lengths); xc->rvat_chain_table_lengths = NULL; xc->rvat_data_valid = 0; } } void fstReaderClose(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { fstReaderDeallocateScopeData(xc); fstReaderDeallocateRvatData(xc); free(xc->rvat_sig_offs); xc->rvat_sig_offs = NULL; free(xc->process_mask); xc->process_mask = NULL; free(xc->blackout_times); xc->blackout_times = NULL; free(xc->blackout_activity); xc->blackout_activity = NULL; free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = NULL; free(xc->signal_typs); xc->signal_typs = NULL; free(xc->signal_lens); xc->signal_lens = NULL; free(xc->filename); xc->filename = NULL; if(xc->fh) { tmpfile_close(&xc->fh, &xc->fh_nam); } if(xc->f) { tmpfile_close(&xc->f, &xc->f_nam); if(xc->filename_unpacked) { unlink(xc->filename_unpacked); free(xc->filename_unpacked); } } free(xc); } } /* * read processing */ /* normal read which re-interleaves the value change data */ int fstReaderIterBlocks(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void *user_callback_data_pointer, FILE *fv) { return(fstReaderIterBlocks2(ctx, value_change_callback, NULL, user_callback_data_pointer, fv)); } int fstReaderIterBlocks2(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), void *user_callback_data_pointer, FILE *fv) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; uint64_t previous_time = UINT64_MAX; uint64_t *time_table = NULL; uint64_t tsec_nitems; unsigned int secnum = 0; int blocks_skipped = 0; fst_off_t blkpos = 0; uint64_t seclen, beg_tim; uint64_t end_tim; uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle; fst_off_t vc_start; fst_off_t indx_pntr, indx_pos; fst_off_t *chain_table = NULL; uint32_t *chain_table_lengths = NULL; unsigned char *chain_cmem; unsigned char *pnt; long chain_clen; fstHandle idx, pidx=0, i; uint64_t pval; uint64_t vc_maxhandle_largest = 0; uint64_t tsec_uclen = 0, tsec_clen = 0; int sectype; uint64_t mem_required_for_traversal; unsigned char *mem_for_traversal = NULL; uint32_t traversal_mem_offs; uint32_t *scatterptr, *headptr, *length_remaining; uint32_t cur_blackout = 0; int packtype; unsigned char *mc_mem = NULL; uint32_t mc_mem_len; /* corresponds to largest value encountered in chain_table_lengths[i] */ int dumpvars_state = 0; if(!xc) return(0); scatterptr = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); headptr = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); length_remaining = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); if(fv) { #ifndef FST_WRITEX_DISABLE fflush(fv); setvbuf(fv, (char *) NULL, _IONBF, 0); /* even buffered IO is slow so disable it and use our own routines that don't need seeking */ xc->writex_fd = fileno(fv); #endif } for(;;) { uint32_t *tc_head = NULL; traversal_mem_offs = 0; fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if((sectype == EOF) || (sectype == FST_BL_SKIP)) { #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "<< EOF >>\n"); #endif break; } blkpos++; if((sectype != FST_BL_VCDATA) && (sectype != FST_BL_VCDATA_DYN_ALIAS) && (sectype != FST_BL_VCDATA_DYN_ALIAS2)) { blkpos += seclen; continue; } if(!seclen) break; beg_tim = fstReaderUint64(xc->f); end_tim = fstReaderUint64(xc->f); if(xc->limit_range_valid) { if(end_tim < xc->limit_range_start) { blocks_skipped++; blkpos += seclen; continue; } if(beg_tim > xc->limit_range_end) /* likely the compare in for(i=0;if); mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */ #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal); #endif /* process time block */ { unsigned char *ucdata; unsigned char *cdata; unsigned long destlen /* = tsec_uclen */; /* scan-build */ unsigned long sourcelen /*= tsec_clen */; /* scan-build */ int rc; unsigned char *tpnt; uint64_t tpval; unsigned int ti; if(fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET) != 0) break; tsec_uclen = fstReaderUint64(xc->f); tsec_clen = fstReaderUint64(xc->f); tsec_nitems = fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "time section unc: %d, com: %d (%d items)\n", (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems); #endif if(tsec_clen > seclen) break; /* corrupted tsec_clen: by definition it can't be larger than size of section */ ucdata = (unsigned char *)malloc(tsec_uclen); if(!ucdata) break; /* malloc fail as tsec_uclen out of range from corrupted file */ destlen = tsec_uclen; sourcelen = tsec_clen; fstReaderFseeko(xc, xc->f, -24 - ((fst_off_t)tsec_clen), SEEK_CUR); if(tsec_uclen != tsec_clen) { cdata = (unsigned char *)malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderIterBlocks2(), tsec uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } free(time_table); time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for(ti=0;tif, blkpos+32, SEEK_SET); frame_uclen = fstReaderVarint64(xc->f); frame_clen = fstReaderVarint64(xc->f); frame_maxhandle = fstReaderVarint64(xc->f); if(secnum == 0) { if((beg_tim != time_table[0]) || (blocks_skipped)) { unsigned char *mu = (unsigned char *)malloc(frame_uclen); uint32_t sig_offs = 0; if(fv) { char wx_buf[32]; int wx_len; if(beg_tim) { if(dumpvars_state == 1) { wx_len = sprintf(wx_buf, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; } wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", beg_tim); fstWritex(xc, wx_buf, wx_len); if(!dumpvars_state) { wx_len = sprintf(wx_buf, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; } } if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts)) { if(beg_tim == xc->blackout_times[cur_blackout]) { wx_len = sprintf(wx_buf, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off"); fstWritex(xc, wx_buf, wx_len); } } } if(frame_uclen == frame_clen) { fstFread(mu, frame_uclen, 1, xc->f); } else { unsigned char *mc = (unsigned char *)malloc(frame_clen); int rc; unsigned long destlen = frame_uclen; unsigned long sourcelen = frame_clen; fstFread(mc, sourcelen, 1, xc->f); rc = uncompress(mu, &destlen, mc, sourcelen); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderIterBlocks2(), frame uncompress rc: %d, exiting.\n", rc); exit(255); } free(mc); } for(idx=0;idxprocess_mask[process_idx]&(1<signal_lens[idx] <= 1) { if(xc->signal_lens[idx] == 1) { unsigned char val = mu[sig_offs]; if(value_change_callback) { xc->temp_signal_value_buf[0] = val; xc->temp_signal_value_buf[1] = 0; value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = val; /* collapse 3 writes into one I/O call */ vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len + 2); } } } else { /* variable-length ("0" length) records have no initial state */ } } else { if(xc->signal_typs[idx] != FST_VT_VCD_REAL) { if(value_change_callback) { memcpy(xc->temp_signal_value_buf, mu+sig_offs, xc->signal_lens[idx]); xc->temp_signal_value_buf[xc->signal_lens[idx]] = 0; value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, vcd_id, 1); fstWritex(xc,mu+sig_offs, xc->signal_lens[idx]); vcd_id[0] = ' '; /* collapse 3 writes into one I/O call */ vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len + 2); } } } else { double d; unsigned char *clone_d; unsigned char *srcdata = mu+sig_offs; if(value_change_callback) { if(xc->native_doubles_for_cb) { if(xc->double_endian_match) { clone_d = srcdata; } else { int j; clone_d = (unsigned char *)&d; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } value_change_callback(user_callback_data_pointer, beg_tim, idx+1, clone_d); } else { clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)xc->temp_signal_value_buf, "%.16g", d); value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } } else { if(fv) { char vcdid_buf[16]; char wx_buf[64]; int wx_len; clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } fstVcdID(vcdid_buf, idx+1); wx_len = sprintf(wx_buf, "r%.16g %s\n", d, vcdid_buf); fstWritex(xc, wx_buf, wx_len); } } } } } sig_offs += xc->signal_lens[idx]; } free(mu); fstReaderFseeko(xc, xc->f, -((fst_off_t)frame_clen), SEEK_CUR); } } fstReaderFseeko(xc, xc->f, (fst_off_t)frame_clen, SEEK_CUR); /* skip past compressed data */ vc_maxhandle = fstReaderVarint64(xc->f); vc_start = ftello(xc->f); /* points to '!' character */ packtype = fgetc(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)frame_maxhandle); fprintf(stderr, FST_APIMESS "vc_maxhandle: %d, packtype: %c\n", (int)vc_maxhandle, packtype); #endif indx_pntr = blkpos + seclen - 24 -tsec_clen -8; fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET); chain_clen = fstReaderUint64(xc->f); indx_pos = indx_pntr - chain_clen; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = (unsigned char *)malloc(chain_clen); if(!chain_cmem) goto block_err; fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET); fstFread(chain_cmem, chain_clen, 1, xc->f); if(vc_maxhandle > vc_maxhandle_largest) { free(chain_table); free(chain_table_lengths); vc_maxhandle_largest = vc_maxhandle; chain_table = (fst_off_t *)calloc((vc_maxhandle+1), sizeof(fst_off_t)); chain_table_lengths = (uint32_t *)calloc((vc_maxhandle+1), sizeof(uint32_t)); } if(!chain_table || !chain_table_lengths) goto block_err; pnt = chain_cmem; idx = 0; pval = 0; if(sectype == FST_BL_VCDATA_DYN_ALIAS2) { uint32_t prev_alias = 0; do { int skiplen; if(*pnt & 0x01) { int64_t shval = fstGetSVarint64(pnt, &skiplen) >> 1; if(shval > 0) { pval = chain_table[idx] = pval + shval; if(idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; } pidx = idx++; } else if(shval < 0) { chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ chain_table_lengths[idx] = prev_alias = shval; /* because during this loop iter would give stale data! */ idx++; } else { chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ chain_table_lengths[idx] = prev_alias; /* because during this loop iter would give stale data! */ idx++; } } else { uint64_t val = fstGetVarint32(pnt, &skiplen); fstHandle loopcnt = val >> 1; for(i=0;i> 1); if(idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; } pidx = idx++; } else { fstHandle loopcnt = val >> 1; for(i=0;i xc->maxhandle) idx = xc->maxhandle; for(i=0;iprocess_mask[process_idx]&(1<f, vc_start + chain_table[i], SEEK_SET); val = fstReaderVarint32WithSkip(xc->f, &skiplen); if(val) { unsigned char *mu = mem_for_traversal + traversal_mem_offs; /* uncomp: dst */ unsigned char *mc; /* comp: src */ unsigned long destlen = val; unsigned long sourcelen = chain_table_lengths[i]; if(mc_mem_len < chain_table_lengths[i]) { free(mc_mem); mc_mem = (unsigned char *)malloc(mc_mem_len = chain_table_lengths[i]); } mc = mc_mem; fstFread(mc, chain_table_lengths[i], 1, xc->f); switch(packtype) { case '4': rc = (destlen == (unsigned long)LZ4_decompress_safe_partial((char *)mc, (char *)mu, sourcelen, destlen, destlen)) ? Z_OK : Z_DATA_ERROR; break; case 'F': fastlz_decompress(mc, sourcelen, mu, destlen); /* rc appears unreliable */ break; default: rc = uncompress(mu, &destlen, mc, sourcelen); break; } /* data to process is for(j=0;jf); /* data to process is for(j=0;jsignal_lens[i] == 1) { uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]); uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; } else { uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]); tdelta = vli >> 1; } scatterptr[i] = tc_head[tdelta]; tc_head[tdelta] = i+1; } } } free(mc_mem); /* there is no usage below for this, no real need to clear out mc_mem or mc_mem_len */ for(i=0;ilimit_range_valid) { if(time_table[i] > xc->limit_range_end) { break; } } if(dumpvars_state == 1) { wx_len = sprintf(wx_buf, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; } wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", time_table[i]); fstWritex(xc, wx_buf, wx_len); if(!dumpvars_state) { wx_len = sprintf(wx_buf, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; } if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts)) { if(time_table[i] == xc->blackout_times[cur_blackout]) { wx_len = sprintf(wx_buf, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off"); fstWritex(xc, wx_buf, wx_len); } } previous_time = time_table[i]; } } while(tc_head[i]) { idx = tc_head[i] - 1; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); if(xc->signal_lens[idx] <= 1) { if(xc->signal_lens[idx] == 1) { unsigned char val; if(!(vli & 1)) { /* tdelta = vli >> 2; */ /* scan-build */ val = ((vli >> 1) & 1) | '0'; } else { /* tdelta = vli >> 4; */ /* scan-build */ val = FST_RCV_STR[((vli >> 1) & 7)]; } if(value_change_callback) { xc->temp_signal_value_buf[0] = val; xc->temp_signal_value_buf[1] = 0; value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = val; vcd_id[vcdid_len+1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } } headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { int shamt; vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); shamt = 2 << (vli & 1); tdelta = vli >> shamt; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } else { unsigned char *vdata; uint32_t len; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); len = fstGetVarint32(mem_for_traversal + headptr[idx] + skiplen, &skiplen2); /* tdelta = vli >> 1; */ /* scan-build */ skiplen += skiplen2; vdata = mem_for_traversal + headptr[idx] + skiplen; if(!(vli & 1)) { if(value_change_callback_varlen) { value_change_callback_varlen(user_callback_data_pointer, time_table[i], idx+1, vdata, len); } else { if(fv) { char vcd_id[16]; int vcdid_len; vcd_id[0] = 's'; fstWritex(xc, vcd_id, 1); vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); { unsigned char *vesc = (unsigned char *)malloc(len*4 + 1); int vlen = fstUtilityBinToEsc(vesc, vdata, len); fstWritex(xc, vesc, vlen); free(vesc); } vcd_id[0] = ' '; vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } } } skiplen += len; headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); tdelta = vli >> 1; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } } else { uint32_t len = xc->signal_lens[idx]; unsigned char *vdata; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); /* tdelta = vli >> 1; */ /* scan-build */ vdata = mem_for_traversal + headptr[idx] + skiplen; if(xc->signal_typs[idx] != FST_VT_VCD_REAL) { if(!(vli & 1)) { int byte = 0; int bit; unsigned int j; for(j=0;j> bit) & 1) | '0'; xc->temp_signal_value_buf[j] = ch; } xc->temp_signal_value_buf[j] = 0; if(value_change_callback) { value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, &ch_bp, 1); fstWritex(xc, xc->temp_signal_value_buf, len); } } len = byte+1; } else { if(value_change_callback) { memcpy(xc->temp_signal_value_buf, vdata, len); xc->temp_signal_value_buf[len] = 0; value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, &ch_bp, 1); fstWritex(xc, vdata, len); } } } } else { double d; unsigned char *clone_d /*= (unsigned char *)&d */; /* scan-build */ unsigned char buf[8]; unsigned char *srcdata; if(!(vli & 1)) /* very rare case, but possible */ { int bit; int j; for(j=0;j<8;j++) { unsigned char ch; bit = 7 - (j & 7); ch = ((vdata[0] >> bit) & 1) | '0'; buf[j] = ch; } len = 1; srcdata = buf; } else { srcdata = vdata; } if(value_change_callback) { if(xc->native_doubles_for_cb) { if(xc->double_endian_match) { clone_d = srcdata; } else { int j; clone_d = (unsigned char *)&d; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } value_change_callback(user_callback_data_pointer, time_table[i], idx+1, clone_d); } else { clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)xc->temp_signal_value_buf, "%.16g", d); value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } } else { if(fv) { char wx_buf[32]; int wx_len; clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } wx_len = sprintf(wx_buf, "r%.16g", d); fstWritex(xc, wx_buf, wx_len); } } } if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = ' '; vcd_id[vcdid_len+1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } skiplen += len; headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); tdelta = vli >> 1; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } } } block_err: free(tc_head); free(chain_cmem); free(mem_for_traversal); mem_for_traversal = NULL; secnum++; if(secnum == xc->vc_section_count) break; /* in case file is growing, keep with original block count */ blkpos += seclen; } if(mem_for_traversal) free(mem_for_traversal); /* scan-build */ free(length_remaining); free(headptr); free(scatterptr); if(chain_table) free(chain_table); if(chain_table_lengths) free(chain_table_lengths); free(time_table); #ifndef FST_WRITEX_DISABLE if(fv) { fstWritex(xc, NULL, 0); } #endif return(1); } /* rvat functions */ static char *fstExtractRvatDataFromFrame(struct fstReaderContext *xc, fstHandle facidx, char *buf) { if(facidx >= xc->rvat_frame_maxhandle) { return(NULL); } if(xc->signal_lens[facidx] == 1) { buf[0] = (char)xc->rvat_frame_data[xc->rvat_sig_offs[facidx]]; buf[1] = 0; } else { if(xc->signal_typs[facidx] != FST_VT_VCD_REAL) { memcpy(buf, xc->rvat_frame_data + xc->rvat_sig_offs[facidx], xc->signal_lens[facidx]); buf[xc->signal_lens[facidx]] = 0; } else { double d; unsigned char *clone_d = (unsigned char *)&d; unsigned char *srcdata = xc->rvat_frame_data + xc->rvat_sig_offs[facidx]; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)buf, "%.16g", d); } } return(buf); } char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; fst_off_t blkpos = 0, prev_blkpos; uint64_t beg_tim, end_tim, beg_tim2, end_tim2; int sectype; unsigned int secnum = 0; uint64_t seclen; uint64_t tsec_uclen = 0, tsec_clen = 0; uint64_t tsec_nitems; uint64_t frame_uclen, frame_clen; #ifdef FST_DEBUG uint64_t mem_required_for_traversal; #endif fst_off_t indx_pntr, indx_pos; long chain_clen; unsigned char *chain_cmem; unsigned char *pnt; fstHandle idx, pidx=0, i; uint64_t pval; if((!xc) || (!facidx) || (facidx > xc->maxhandle) || (!buf) || (!xc->signal_lens[facidx-1])) { return(NULL); } if(!xc->rvat_sig_offs) { uint32_t cur_offs = 0; xc->rvat_sig_offs = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); for(i=0;imaxhandle;i++) { xc->rvat_sig_offs[i] = cur_offs; cur_offs += xc->signal_lens[i]; } } if(xc->rvat_data_valid) { if((xc->rvat_beg_tim <= tim) && (tim <= xc->rvat_end_tim)) { goto process_value; } fstReaderDeallocateRvatData(xc); } xc->rvat_chain_pos_valid = 0; for(;;) { fstReaderFseeko(xc, xc->f, (prev_blkpos = blkpos), SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if((sectype == EOF) || (sectype == FST_BL_SKIP) || (!seclen)) { return(NULL); /* if this loop exits on break, it's successful */ } blkpos++; if((sectype != FST_BL_VCDATA) && (sectype != FST_BL_VCDATA_DYN_ALIAS) && (sectype != FST_BL_VCDATA_DYN_ALIAS2)) { blkpos += seclen; continue; } beg_tim = fstReaderUint64(xc->f); end_tim = fstReaderUint64(xc->f); if((beg_tim <= tim) && (tim <= end_tim)) { if((tim == end_tim) && (tim != xc->end_time)) { fst_off_t cached_pos = ftello(xc->f); fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); beg_tim2 = fstReaderUint64(xc->f); end_tim2 = fstReaderUint64(xc->f); if(((sectype != FST_BL_VCDATA)&&(sectype != FST_BL_VCDATA_DYN_ALIAS)&&(sectype != FST_BL_VCDATA_DYN_ALIAS2)) || (!seclen) || (beg_tim2 != tim)) { blkpos = prev_blkpos; break; } beg_tim = beg_tim2; end_tim = end_tim2; fstReaderFseeko(xc, xc->f, cached_pos, SEEK_SET); } break; } blkpos += seclen; secnum++; } xc->rvat_beg_tim = beg_tim; xc->rvat_end_tim = end_tim; #ifdef FST_DEBUG mem_required_for_traversal = #endif fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "rvat sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal); #endif /* process time block */ { unsigned char *ucdata; unsigned char *cdata; unsigned long destlen /* = tsec_uclen */; /* scan-build */ unsigned long sourcelen /* = tsec_clen */; /* scan-build */ int rc; unsigned char *tpnt; uint64_t tpval; unsigned int ti; fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET); tsec_uclen = fstReaderUint64(xc->f); tsec_clen = fstReaderUint64(xc->f); tsec_nitems = fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "time section unc: %d, com: %d (%d items)\n", (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems); #endif ucdata = (unsigned char *)malloc(tsec_uclen); destlen = tsec_uclen; sourcelen = tsec_clen; fstReaderFseeko(xc, xc->f, -24 - ((fst_off_t)tsec_clen), SEEK_CUR); if(tsec_uclen != tsec_clen) { cdata = (unsigned char *)malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), tsec uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } xc->rvat_time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for(ti=0;tirvat_time_table[ti] = tpval + val; tpnt += skiplen; } free(ucdata); } fstReaderFseeko(xc, xc->f, blkpos+32, SEEK_SET); frame_uclen = fstReaderVarint64(xc->f); frame_clen = fstReaderVarint64(xc->f); xc->rvat_frame_maxhandle = fstReaderVarint64(xc->f); xc->rvat_frame_data = (unsigned char *)malloc(frame_uclen); if(frame_uclen == frame_clen) { fstFread(xc->rvat_frame_data, frame_uclen, 1, xc->f); } else { unsigned char *mc = (unsigned char *)malloc(frame_clen); int rc; unsigned long destlen = frame_uclen; unsigned long sourcelen = frame_clen; fstFread(mc, sourcelen, 1, xc->f); rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), frame decompress rc: %d, exiting.\n", rc); exit(255); } free(mc); } xc->rvat_vc_maxhandle = fstReaderVarint64(xc->f); xc->rvat_vc_start = ftello(xc->f); /* points to '!' character */ xc->rvat_packtype = fgetc(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)xc->rvat_frame_maxhandle); fprintf(stderr, FST_APIMESS "vc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle); #endif indx_pntr = blkpos + seclen - 24 -tsec_clen -8; fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET); chain_clen = fstReaderUint64(xc->f); indx_pos = indx_pntr - chain_clen; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = (unsigned char *)malloc(chain_clen); fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET); fstFread(chain_cmem, chain_clen, 1, xc->f); xc->rvat_chain_table = (fst_off_t *)calloc((xc->rvat_vc_maxhandle+1), sizeof(fst_off_t)); xc->rvat_chain_table_lengths = (uint32_t *)calloc((xc->rvat_vc_maxhandle+1), sizeof(uint32_t)); pnt = chain_cmem; idx = 0; pval = 0; if(sectype == FST_BL_VCDATA_DYN_ALIAS2) { uint32_t prev_alias = 0; do { int skiplen; if(*pnt & 0x01) { int64_t shval = fstGetSVarint64(pnt, &skiplen) >> 1; if(shval > 0) { pval = xc->rvat_chain_table[idx] = pval + shval; if(idx) { xc->rvat_chain_table_lengths[pidx] = pval - xc->rvat_chain_table[pidx]; } pidx = idx++; } else if(shval < 0) { xc->rvat_chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ xc->rvat_chain_table_lengths[idx] = prev_alias = shval; /* because during this loop iter would give stale data! */ idx++; } else { xc->rvat_chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ xc->rvat_chain_table_lengths[idx] = prev_alias; /* because during this loop iter would give stale data! */ idx++; } } else { uint64_t val = fstGetVarint32(pnt, &skiplen); fstHandle loopcnt = val >> 1; for(i=0;irvat_chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); } else { do { int skiplen; uint64_t val = fstGetVarint32(pnt, &skiplen); if(!val) { pnt += skiplen; val = fstGetVarint32(pnt, &skiplen); xc->rvat_chain_table[idx] = 0; xc->rvat_chain_table_lengths[idx] = -val; idx++; } else if(val&1) { pval = xc->rvat_chain_table[idx] = pval + (val >> 1); if(idx) { xc->rvat_chain_table_lengths[pidx] = pval - xc->rvat_chain_table[pidx]; } pidx = idx++; } else { fstHandle loopcnt = val >> 1; for(i=0;irvat_chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); } free(chain_cmem); xc->rvat_chain_table[idx] = indx_pos - xc->rvat_vc_start; xc->rvat_chain_table_lengths[pidx] = xc->rvat_chain_table[idx] - xc->rvat_chain_table[pidx]; for(i=0;irvat_chain_table_lengths[i]; if((v32 < 0) && (!xc->rvat_chain_table[i])) { v32 = -v32; v32--; if(((uint32_t)v32) < i) /* sanity check */ { xc->rvat_chain_table[i] = xc->rvat_chain_table[v32]; xc->rvat_chain_table_lengths[i] = xc->rvat_chain_table_lengths[v32]; } } } #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "decompressed chain idx len: %" PRIu32 "\n", idx); #endif xc->rvat_data_valid = 1; /* all data at this point is loaded or resident in fst cache, process and return appropriate value */ process_value: if(facidx > xc->rvat_vc_maxhandle) { return(NULL); } facidx--; /* scale down for array which starts at zero */ if(((tim == xc->rvat_beg_tim)&&(!xc->rvat_chain_table[facidx])) || (!xc->rvat_chain_table[facidx])) { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } if(facidx != xc->rvat_chain_facidx) { if(xc->rvat_chain_mem) { free(xc->rvat_chain_mem); xc->rvat_chain_mem = NULL; xc->rvat_chain_pos_valid = 0; } } if(!xc->rvat_chain_mem) { uint32_t skiplen; fstReaderFseeko(xc, xc->f, xc->rvat_vc_start + xc->rvat_chain_table[facidx], SEEK_SET); xc->rvat_chain_len = fstReaderVarint32WithSkip(xc->f, &skiplen); if(xc->rvat_chain_len) { unsigned char *mu = (unsigned char *)malloc(xc->rvat_chain_len); unsigned char *mc = (unsigned char *)malloc(xc->rvat_chain_table_lengths[facidx]); unsigned long destlen = xc->rvat_chain_len; unsigned long sourcelen = xc->rvat_chain_table_lengths[facidx]; int rc = Z_OK; fstFread(mc, xc->rvat_chain_table_lengths[facidx], 1, xc->f); switch(xc->rvat_packtype) { case '4': rc = (destlen == (unsigned long)LZ4_decompress_safe_partial((char *)mc, (char *)mu, sourcelen, destlen, destlen)) ? Z_OK : Z_DATA_ERROR; break; case 'F': fastlz_decompress(mc, sourcelen, mu, destlen); /* rc appears unreliable */ break; default: rc = uncompress(mu, &destlen, mc, sourcelen); break; } free(mc); if(rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), rvat decompress clen: %d (rc=%d), exiting.\n", (int)xc->rvat_chain_len, rc); exit(255); } /* data to process is for(j=0;jrvat_chain_mem = mu; } else { int destlen = xc->rvat_chain_table_lengths[facidx] - skiplen; unsigned char *mu = (unsigned char *)malloc(xc->rvat_chain_len = destlen); fstFread(mu, destlen, 1, xc->f); /* data to process is for(j=0;jrvat_chain_mem = mu; } xc->rvat_chain_facidx = facidx; } /* process value chain here */ { uint32_t tidx = 0, ptidx = 0; uint32_t tdelta; int skiplen; unsigned int iprev = xc->rvat_chain_len; uint32_t pvli = 0; int pskip = 0; if((xc->rvat_chain_pos_valid)&&(tim >= xc->rvat_chain_pos_time)) { i = xc->rvat_chain_pos_idx; tidx = xc->rvat_chain_pos_tidx; } else { i = 0; tidx = 0; xc->rvat_chain_pos_time = xc->rvat_beg_tim; } if(xc->signal_lens[facidx] == 1) { while(irvat_chain_len) { uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen); uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; if(xc->rvat_time_table[tidx + tdelta] <= tim) { iprev = i; pvli = vli; ptidx = tidx; /* pskip = skiplen; */ /* scan-build */ tidx += tdelta; i+=skiplen; } else { break; } } if(iprev != xc->rvat_chain_len) { xc->rvat_chain_pos_tidx = ptidx; xc->rvat_chain_pos_idx = iprev; xc->rvat_chain_pos_time = tim; xc->rvat_chain_pos_valid = 1; if(!(pvli & 1)) { buf[0] = ((pvli >> 1) & 1) | '0'; } else { buf[0] = FST_RCV_STR[((pvli >> 1) & 7)]; } buf[1] = 0; return(buf); } else { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } } else { while(irvat_chain_len) { uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen); tdelta = vli >> 1; if(xc->rvat_time_table[tidx + tdelta] <= tim) { iprev = i; pvli = vli; ptidx = tidx; pskip = skiplen; tidx += tdelta; i+=skiplen; if(!(pvli & 1)) { i+=((xc->signal_lens[facidx]+7)/8); } else { i+=xc->signal_lens[facidx]; } } else { break; } } if(iprev != xc->rvat_chain_len) { unsigned char *vdata = xc->rvat_chain_mem + iprev + pskip; xc->rvat_chain_pos_tidx = ptidx; xc->rvat_chain_pos_idx = iprev; xc->rvat_chain_pos_time = tim; xc->rvat_chain_pos_valid = 1; if(xc->signal_typs[facidx] != FST_VT_VCD_REAL) { if(!(pvli & 1)) { int byte = 0; int bit; unsigned int j; for(j=0;jsignal_lens[facidx];j++) { unsigned char ch; byte = j/8; bit = 7 - (j & 7); ch = ((vdata[byte] >> bit) & 1) | '0'; buf[j] = ch; } buf[j] = 0; return(buf); } else { memcpy(buf, vdata, xc->signal_lens[facidx]); buf[xc->signal_lens[facidx]] = 0; return(buf); } } else { double d; unsigned char *clone_d = (unsigned char *)&d; unsigned char bufd[8]; unsigned char *srcdata; if(!(pvli & 1)) /* very rare case, but possible */ { int bit; int j; for(j=0;j<8;j++) { unsigned char ch; bit = 7 - (j & 7); ch = ((vdata[0] >> bit) & 1) | '0'; bufd[j] = ch; } srcdata = bufd; } else { srcdata = vdata; } if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf(buf, "r%.16g", d); return(buf); } } else { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } } } /* return(NULL); */ } /**********************************************************************/ #ifndef _WAVE_HAVE_JUDY /***********************/ /*** ***/ /*** jenkins hash ***/ /*** ***/ /***********************/ /* -------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. For every delta with one or two bits set, and the deltas of all three high bits or all three low bits, whether the original value of a,b,c is almost all zero or is uniformly distributed, * If mix() is run forward or backward, at least 32 bits in a,b,c have at least 1/4 probability of changing. * If mix() is run forward, every bit of c will change between 1/3 and 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) mix() was built out of 36 single-cycle latency instructions in a structure that could supported 2x parallelism, like so: a -= b; a -= c; x = (c>>13); b -= c; a ^= x; b -= a; x = (a<<8); c -= a; b ^= x; c -= b; x = (b>>13); ... Unfortunately, superscalar Pentiums and Sparcs can't take advantage of that parallelism. They've also turned some of those single-cycle latency instructions into multi-cycle latency instructions. Still, this is the fastest good hash I could find. There were about 2^^68 to choose from. I only looked at a billion or so. -------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ b -= c; b -= a; b ^= (a<<8); \ c -= a; c -= b; c ^= (b>>13); \ a -= b; a -= c; a ^= (c>>12); \ b -= c; b -= a; b ^= (a<<16); \ c -= a; c -= b; c ^= (b>>5); \ a -= b; a -= c; a ^= (c>>3); \ b -= c; b -= a; b ^= (a<<10); \ c -= a; c -= b; c ^= (b>>15); \ } /* -------------------------------------------------------------------- j_hash() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) len : the length of the key, counting by bytes initval : can be any 4-byte value Returns a 32-bit value. Every bit of the key affects every bit of the return value. Every 1-bit and 2-bit delta achieves avalanche. About 6*len+35 instructions. The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. If you are hashing n strings (uint8_t **)k, do it like this: for (i=0, h=0; i= 12) { a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24)); b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24)); c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); mix(a,b,c); k += 12; len -= 12; } /*------------------------------------- handle the last 11 bytes */ c += length; switch(len) /* all the case statements fall through */ { case 11: c+=((uint32_t)k[10]<<24); /* fallthrough */ case 10: c+=((uint32_t)k[9]<<16); /* fallthrough */ case 9 : c+=((uint32_t)k[8]<<8); /* fallthrough */ /* the first byte of c is reserved for the length */ case 8 : b+=((uint32_t)k[7]<<24); /* fallthrough */ case 7 : b+=((uint32_t)k[6]<<16); /* fallthrough */ case 6 : b+=((uint32_t)k[5]<<8); /* fallthrough */ case 5 : b+=k[4]; /* fallthrough */ case 4 : a+=((uint32_t)k[3]<<24); /* fallthrough */ case 3 : a+=((uint32_t)k[2]<<16); /* fallthrough */ case 2 : a+=((uint32_t)k[1]<<8); /* fallthrough */ case 1 : a+=k[0]; /* case 0: nothing left to add */ } mix(a,b,c); /*-------------------------------------------- report the result */ return(c); } /********************************************************************/ /***************************/ /*** ***/ /*** judy HS emulation ***/ /*** ***/ /***************************/ struct collchain_t { struct collchain_t *next; void *payload; uint32_t fullhash, length; unsigned char mem[1]; }; void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask) { struct collchain_t ***base = (struct collchain_t ***)base_i; uint32_t hf, h; struct collchain_t **ar; struct collchain_t *chain, *pchain; if(!*base) { *base = (struct collchain_t **)calloc(1, (hashmask + 1) * sizeof(void *)); } ar = *base; h = (hf = j_hash(mem, length, length)) & hashmask; pchain = chain = ar[h]; while(chain) { if((chain->fullhash == hf) && (chain->length == length) && !memcmp(chain->mem, mem, length)) { if(pchain != chain) /* move hit to front */ { pchain->next = chain->next; chain->next = ar[h]; ar[h] = chain; } return(&(chain->payload)); } pchain = chain; chain = chain->next; } chain = (struct collchain_t *)calloc(1, sizeof(struct collchain_t) + length - 1); memcpy(chain->mem, mem, length); chain->fullhash = hf; chain->length = length; chain->next = ar[h]; ar[h] = chain; return(&(chain->payload)); } void JenkinsFree(void *base_i, uint32_t hashmask) { struct collchain_t ***base = (struct collchain_t ***)base_i; uint32_t h; struct collchain_t **ar; struct collchain_t *chain, *chain_next; if(base && *base) { ar = *base; for(h=0;h<=hashmask;h++) { chain = ar[h]; while(chain) { chain_next = chain->next; free(chain); chain = chain_next; } } free(*base); *base = NULL; } } #endif /**********************************************************************/ /************************/ /*** ***/ /*** utility function ***/ /*** ***/ /************************/ int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len) { const unsigned char *src = s; int dlen = 0; int i; for(i=0;i ' ') && (src[i] <= '~')) /* no white spaces in output */ { dlen++; } else { dlen += 4; } break; } } return(dlen); } int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len) { const unsigned char *src = s; unsigned char *dst = d; unsigned char val; int i; for(i=0;i ' ') && (src[i] <= '~')) /* no white spaces in output */ { *(dst++) = src[i]; } else { val = src[i]; *(dst++) = '\\'; *(dst++) = (val/64) + '0'; val = val & 63; *(dst++) = (val/8) + '0'; val = val & 7; *(dst++) = (val) + '0'; } break; } } return(dst - d); } /* * this overwrites the original string if the destination pointer is NULL */ int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len) { unsigned char *src = s; unsigned char *dst = (!d) ? s : (s = d); unsigned char val[3]; int i; for(i=0;i='A')&&(val[0]<='F')) ? (val[0] - 'A' + 10) : (val[0] - '0'); val[1] = ((val[1]>='A')&&(val[1]<='F')) ? (val[1] - 'A' + 10) : (val[1] - '0'); *(dst++) = val[0] * 16 + val[1]; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val[0] = src[ i] - '0'; val[1] = src[++i] - '0'; val[2] = src[++i] - '0'; *(dst++) = val[0] * 64 + val[1] * 8 + val[2]; break; default: *(dst++) = src[i]; break; } } } return(dst - s); } struct fstETab *fstUtilityExtractEnumTableFromString(const char *s) { struct fstETab *et = NULL; int num_spaces = 0; int i; int newlen; if(s) { const char *csp = strchr(s, ' '); int cnt = atoi(csp+1); for(;;) { csp = strchr(csp+1, ' '); if(csp) { num_spaces++; } else { break; } } if(num_spaces == (2*cnt)) { char *sp, *sp2; et = (struct fstETab*)calloc(1, sizeof(struct fstETab)); et->elem_count = cnt; et->name = strdup(s); et->literal_arr = (char**)calloc(cnt, sizeof(char *)); et->val_arr = (char**)calloc(cnt, sizeof(char *)); sp = strchr(et->name, ' '); *sp = 0; sp = strchr(sp+1, ' '); for(i=0;iliteral_arr[i] = sp+1; sp = sp2; newlen = fstUtilityEscToBin(NULL, (unsigned char*)et->literal_arr[i], strlen(et->literal_arr[i])); et->literal_arr[i][newlen] = 0; } for(i=0;ival_arr[i] = sp+1; sp = sp2; newlen = fstUtilityEscToBin(NULL, (unsigned char*)et->val_arr[i], strlen(et->val_arr[i])); et->val_arr[i][newlen] = 0; } } } return(et); } void fstUtilityFreeEnumTable(struct fstETab *etab) { if(etab) { free(etab->literal_arr); free(etab->val_arr); free(etab->name); free(etab); } } iverilog-12_0/vpi/fstapi.h000066400000000000000000000440571435245347300156160ustar00rootroot00000000000000/* * Copyright (c) 2009-2018 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * SPDX-License-Identifier: MIT */ #ifndef FST_API_H #define FST_API_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #if defined(_MSC_VER) #include "fst_win_unistd.h" #else #include #endif #include #define FST_RDLOAD "FSTLOAD | " typedef uint32_t fstHandle; typedef uint32_t fstEnumHandle; enum fstWriterPackType { FST_WR_PT_ZLIB = 0, FST_WR_PT_FASTLZ = 1, FST_WR_PT_LZ4 = 2 }; enum fstFileType { FST_FT_MIN = 0, FST_FT_VERILOG = 0, FST_FT_VHDL = 1, FST_FT_VERILOG_VHDL = 2, FST_FT_MAX = 2 }; enum fstBlockType { FST_BL_HDR = 0, FST_BL_VCDATA = 1, FST_BL_BLACKOUT = 2, FST_BL_GEOM = 3, FST_BL_HIER = 4, FST_BL_VCDATA_DYN_ALIAS = 5, FST_BL_HIER_LZ4 = 6, FST_BL_HIER_LZ4DUO = 7, FST_BL_VCDATA_DYN_ALIAS2 = 8, FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */ FST_BL_SKIP = 255 /* used while block is being written */ }; enum fstScopeType { FST_ST_MIN = 0, FST_ST_VCD_MODULE = 0, FST_ST_VCD_TASK = 1, FST_ST_VCD_FUNCTION = 2, FST_ST_VCD_BEGIN = 3, FST_ST_VCD_FORK = 4, FST_ST_VCD_GENERATE = 5, FST_ST_VCD_STRUCT = 6, FST_ST_VCD_UNION = 7, FST_ST_VCD_CLASS = 8, FST_ST_VCD_INTERFACE = 9, FST_ST_VCD_PACKAGE = 10, FST_ST_VCD_PROGRAM = 11, FST_ST_VHDL_ARCHITECTURE = 12, FST_ST_VHDL_PROCEDURE = 13, FST_ST_VHDL_FUNCTION = 14, FST_ST_VHDL_RECORD = 15, FST_ST_VHDL_PROCESS = 16, FST_ST_VHDL_BLOCK = 17, FST_ST_VHDL_FOR_GENERATE = 18, FST_ST_VHDL_IF_GENERATE = 19, FST_ST_VHDL_GENERATE = 20, FST_ST_VHDL_PACKAGE = 21, FST_ST_MAX = 21, FST_ST_GEN_ATTRBEGIN = 252, FST_ST_GEN_ATTREND = 253, FST_ST_VCD_SCOPE = 254, FST_ST_VCD_UPSCOPE = 255 }; enum fstVarType { FST_VT_MIN = 0, /* start of vartypes */ FST_VT_VCD_EVENT = 0, FST_VT_VCD_INTEGER = 1, FST_VT_VCD_PARAMETER = 2, FST_VT_VCD_REAL = 3, FST_VT_VCD_REAL_PARAMETER = 4, FST_VT_VCD_REG = 5, FST_VT_VCD_SUPPLY0 = 6, FST_VT_VCD_SUPPLY1 = 7, FST_VT_VCD_TIME = 8, FST_VT_VCD_TRI = 9, FST_VT_VCD_TRIAND = 10, FST_VT_VCD_TRIOR = 11, FST_VT_VCD_TRIREG = 12, FST_VT_VCD_TRI0 = 13, FST_VT_VCD_TRI1 = 14, FST_VT_VCD_WAND = 15, FST_VT_VCD_WIRE = 16, FST_VT_VCD_WOR = 17, FST_VT_VCD_PORT = 18, FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */ FST_VT_VCD_REALTIME = 20, FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */ FST_VT_SV_BIT = 22, FST_VT_SV_LOGIC = 23, FST_VT_SV_INT = 24, /* declare as size = 32 */ FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */ FST_VT_SV_LONGINT = 26, /* declare as size = 64 */ FST_VT_SV_BYTE = 27, /* declare as size = 8 */ FST_VT_SV_ENUM = 28, /* declare as appropriate type range */ FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */ FST_VT_MAX = 29 /* end of vartypes */ }; enum fstVarDir { FST_VD_MIN = 0, FST_VD_IMPLICIT = 0, FST_VD_INPUT = 1, FST_VD_OUTPUT = 2, FST_VD_INOUT = 3, FST_VD_BUFFER = 4, FST_VD_LINKAGE = 5, FST_VD_MAX = 5 }; enum fstHierType { FST_HT_MIN = 0, FST_HT_SCOPE = 0, FST_HT_UPSCOPE = 1, FST_HT_VAR = 2, FST_HT_ATTRBEGIN = 3, FST_HT_ATTREND = 4, /* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */ FST_HT_TREEBEGIN = 5, FST_HT_TREEEND = 6, FST_HT_MAX = 6 }; enum fstAttrType { FST_AT_MIN = 0, FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */ FST_AT_ARRAY = 1, FST_AT_ENUM = 2, FST_AT_PACK = 3, FST_AT_MAX = 3 }; enum fstMiscType { FST_MT_MIN = 0, FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */ FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */ FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */ FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */ FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */ FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */ FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */ FST_MT_ENUMTABLE = 7, /* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */ FST_MT_UNKNOWN = 8, FST_MT_MAX = 8 }; enum fstArrayType { FST_AR_MIN = 0, FST_AR_NONE = 0, FST_AR_UNPACKED = 1, FST_AR_PACKED = 2, FST_AR_SPARSE = 3, FST_AR_MAX = 3 }; enum fstEnumValueType { FST_EV_SV_INTEGER = 0, FST_EV_SV_BIT = 1, FST_EV_SV_LOGIC = 2, FST_EV_SV_INT = 3, FST_EV_SV_SHORTINT = 4, FST_EV_SV_LONGINT = 5, FST_EV_SV_BYTE = 6, FST_EV_SV_UNSIGNED_INTEGER = 7, FST_EV_SV_UNSIGNED_BIT = 8, FST_EV_SV_UNSIGNED_LOGIC = 9, FST_EV_SV_UNSIGNED_INT = 10, FST_EV_SV_UNSIGNED_SHORTINT = 11, FST_EV_SV_UNSIGNED_LONGINT = 12, FST_EV_SV_UNSIGNED_BYTE = 13, FST_EV_REG = 14, FST_EV_TIME = 15, FST_EV_MAX = 15 }; enum fstPackType { FST_PT_NONE = 0, FST_PT_UNPACKED = 1, FST_PT_PACKED = 2, FST_PT_TAGGED_PACKED = 3, FST_PT_MAX = 3 }; enum fstSupplementalVarType { FST_SVT_MIN = 0, FST_SVT_NONE = 0, FST_SVT_VHDL_SIGNAL = 1, FST_SVT_VHDL_VARIABLE = 2, FST_SVT_VHDL_CONSTANT = 3, FST_SVT_VHDL_FILE = 4, FST_SVT_VHDL_MEMORY = 5, FST_SVT_MAX = 5 }; enum fstSupplementalDataType { FST_SDT_MIN = 0, FST_SDT_NONE = 0, FST_SDT_VHDL_BOOLEAN = 1, FST_SDT_VHDL_BIT = 2, FST_SDT_VHDL_BIT_VECTOR = 3, FST_SDT_VHDL_STD_ULOGIC = 4, FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5, FST_SDT_VHDL_STD_LOGIC = 6, FST_SDT_VHDL_STD_LOGIC_VECTOR = 7, FST_SDT_VHDL_UNSIGNED = 8, FST_SDT_VHDL_SIGNED = 9, FST_SDT_VHDL_INTEGER = 10, FST_SDT_VHDL_REAL = 11, FST_SDT_VHDL_NATURAL = 12, FST_SDT_VHDL_POSITIVE = 13, FST_SDT_VHDL_TIME = 14, FST_SDT_VHDL_CHARACTER = 15, FST_SDT_VHDL_STRING = 16, FST_SDT_MAX = 16, FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */ FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1) }; struct fstHier { unsigned char htyp; union { /* if htyp == FST_HT_SCOPE */ struct fstHierScope { unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */ const char *name; const char *component; uint32_t name_length; /* strlen(u.scope.name) */ uint32_t component_length; /* strlen(u.scope.component) */ } scope; /* if htyp == FST_HT_VAR */ struct fstHierVar { unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */ unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */ unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */ unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */ unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */ const char *name; uint32_t length; fstHandle handle; uint32_t name_length; /* strlen(u.var.name) */ unsigned is_alias : 1; } var; /* if htyp == FST_HT_ATTRBEGIN */ struct fstHierAttr { unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */ unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */ const char *name; uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */ uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */ uint32_t name_length; /* strlen(u.attr.name) */ } attr; } u; }; struct fstETab { char *name; uint32_t elem_count; char **literal_arr; char **val_arr; }; /* * writer functions */ void fstWriterClose(void *ctx); void * fstWriterCreate(const char *nam, int use_compressed_hier); fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr); /* used for Verilog/SV */ fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle); /* future expansion for VHDL and other languages. The variable type, data type, etc map onto the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle, const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt); void fstWriterEmitDumpActive(void *ctx, int enable); void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle); void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val); void fstWriterEmitValueChange32(void *ctx, fstHandle handle, uint32_t bits, uint32_t val); void fstWriterEmitValueChange64(void *ctx, fstHandle handle, uint32_t bits, uint64_t val); void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle, uint32_t bits, const uint32_t *val); void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle, uint32_t bits, const uint64_t *val); void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len); void fstWriterEmitTimeChange(void *ctx, uint64_t tim); void fstWriterFlushContext(void *ctx); int fstWriterGetDumpSizeLimitReached(void *ctx); int fstWriterGetFseekFailed(void *ctx); void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg); void fstWriterSetAttrEnd(void *ctx); void fstWriterSetComment(void *ctx, const char *comm); void fstWriterSetDate(void *ctx, const char *dat); void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes); void fstWriterSetEnvVar(void *ctx, const char *envvar); void fstWriterSetFileType(void *ctx, enum fstFileType filetype); void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ); void fstWriterSetParallelMode(void *ctx, int enable); void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */ void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, const char *scopename, const char *scopecomp); void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetTimescale(void *ctx, int ts); void fstWriterSetTimescaleFromString(void *ctx, const char *s); void fstWriterSetTimezero(void *ctx, int64_t tim); void fstWriterSetUpscope(void *ctx); void fstWriterSetValueList(void *ctx, const char *vl); void fstWriterSetVersion(void *ctx, const char *vers); /* * reader functions */ void fstReaderClose(void *ctx); void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx); void fstReaderClrFacProcessMaskAll(void *ctx); uint64_t fstReaderGetAliasCount(void *ctx); const char * fstReaderGetCurrentFlatScope(void *ctx); void * fstReaderGetCurrentScopeUserInfo(void *ctx); int fstReaderGetCurrentScopeLen(void *ctx); const char * fstReaderGetDateString(void *ctx); int fstReaderGetDoubleEndianMatchState(void *ctx); uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx); unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx); uint64_t fstReaderGetEndTime(void *ctx); int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx); int fstReaderGetFileType(void *ctx); int fstReaderGetFseekFailed(void *ctx); fstHandle fstReaderGetMaxHandle(void *ctx); uint64_t fstReaderGetMemoryUsedByWriter(void *ctx); uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx); uint64_t fstReaderGetScopeCount(void *ctx); uint64_t fstReaderGetStartTime(void *ctx); signed char fstReaderGetTimescale(void *ctx); int64_t fstReaderGetTimezero(void *ctx); uint64_t fstReaderGetValueChangeSectionCount(void *ctx); char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf); uint64_t fstReaderGetVarCount(void *ctx); const char * fstReaderGetVersionString(void *ctx); struct fstHier *fstReaderIterateHier(void *ctx); int fstReaderIterateHierRewind(void *ctx); int fstReaderIterBlocks(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void *user_callback_data_pointer, FILE *vcdhandle); int fstReaderIterBlocks2(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), void *user_callback_data_pointer, FILE *vcdhandle); void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable); void * fstReaderOpen(const char *nam); void * fstReaderOpenForUtilitiesOnly(void); const char * fstReaderPopScope(void *ctx); int fstReaderProcessHier(void *ctx, FILE *vcdhandle); const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info); void fstReaderResetScope(void *ctx); void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx); void fstReaderSetFacProcessMaskAll(void *ctx); void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time); void fstReaderSetUnlimitedTimeRange(void *ctx); void fstReaderSetVcdExtensions(void *ctx, int enable); /* * utility functions */ int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */ int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len); int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len); struct fstETab *fstUtilityExtractEnumTableFromString(const char *s); void fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */ #ifdef __cplusplus } #endif #endif iverilog-12_0/vpi/libvpi.c000066400000000000000000000161771435245347300156120ustar00rootroot00000000000000/* * Copyright (c) 2019 Martin Whitaker (icarus@martin-whitaker.me.uk) * * 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. */ #if defined(__MINGW32__) || defined (__CYGWIN__) #include "vpi_user.h" #include static vpip_routines_s*vpip_routines = 0; // callback related vpiHandle vpi_register_cb(p_cb_data data) { assert(vpip_routines); return vpip_routines->register_cb(data); } PLI_INT32 vpi_remove_cb(vpiHandle ref) { assert(vpip_routines); return vpip_routines->remove_cb(ref); } vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss) { assert(vpip_routines); return vpip_routines->register_systf(ss); } void vpi_get_systf_info(vpiHandle obj, p_vpi_systf_data data) { assert(vpip_routines); vpip_routines->get_systf_info(obj, data); } // for obtaining handles vpiHandle vpi_handle_by_name(const char*name, vpiHandle scope) { assert(vpip_routines); return vpip_routines->handle_by_name(name, scope); } vpiHandle vpi_handle_by_index(vpiHandle ref, PLI_INT32 idx) { assert(vpip_routines); return vpip_routines->handle_by_index(ref, idx); } // for traversing relationships vpiHandle vpi_handle(PLI_INT32 type, vpiHandle ref) { assert(vpip_routines); return vpip_routines->handle(type, ref); } vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle ref) { assert(vpip_routines); return vpip_routines->iterate(type, ref); } vpiHandle vpi_scan(vpiHandle iter) { assert(vpip_routines); return vpip_routines->scan(iter); } // for processing properties PLI_INT32 vpi_get(int property, vpiHandle ref) { assert(vpip_routines); return vpip_routines->get(property, ref); } char*vpi_get_str(PLI_INT32 property, vpiHandle ref) { assert(vpip_routines); return vpip_routines->get_str(property, ref); } // delay processing void vpi_get_delays(vpiHandle expr, p_vpi_delay delays) { assert(vpip_routines); vpip_routines->get_delays(expr, delays); } void vpi_put_delays(vpiHandle expr, p_vpi_delay delays) { assert(vpip_routines); vpip_routines->put_delays(expr, delays); } // value processing void vpi_get_value(vpiHandle expr, p_vpi_value value) { assert(vpip_routines); vpip_routines->get_value(expr, value); } vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, p_vpi_time when, PLI_INT32 flags) { assert(vpip_routines); return vpip_routines->put_value(obj, value, when, flags); } // time processing void vpi_get_time(vpiHandle obj, s_vpi_time*t) { assert(vpip_routines); vpip_routines->get_time(obj, t); } // data processing void*vpi_get_userdata(vpiHandle obj) { assert(vpip_routines); return vpip_routines->get_userdata(obj); } PLI_INT32 vpi_put_userdata(vpiHandle obj, void*data) { assert(vpip_routines); return vpip_routines->put_userdata(obj, data); } // I/O routines PLI_UINT32 vpi_mcd_open(char*name) { assert(vpip_routines); return vpip_routines->mcd_open(name); } PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) { assert(vpip_routines); return vpip_routines->mcd_close(mcd); } PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) { assert(vpip_routines); return vpip_routines->mcd_flush(mcd); } char*vpi_mcd_name(PLI_UINT32 mcd) { assert(vpip_routines); return vpip_routines->mcd_name(mcd); } PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, const char*fmt, ...) { va_list ap; va_start(ap, fmt); assert(vpip_routines); PLI_INT32 rv = vpip_routines->mcd_vprintf(mcd, fmt, ap); va_end(ap); return rv; } PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, const char*fmt, va_list ap) { assert(vpip_routines); return vpip_routines->mcd_vprintf(mcd, fmt, ap); } PLI_INT32 vpi_flush(void) { assert(vpip_routines); return vpip_routines->flush(); } PLI_INT32 vpi_printf(const char*fmt, ...) { va_list ap; va_start(ap, fmt); assert(vpip_routines); PLI_INT32 rv = vpip_routines->vprintf(fmt, ap); va_end(ap); return rv; } PLI_INT32 vpi_vprintf(const char*fmt, va_list ap) { assert(vpip_routines); return vpip_routines->vprintf(fmt, ap); } // utility routines PLI_INT32 vpi_chk_error(p_vpi_error_info info) { assert(vpip_routines); return vpip_routines->chk_error(info); } PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2) { assert(vpip_routines); return vpip_routines->compare_objects(obj1, obj2); } PLI_INT32 vpi_free_object(vpiHandle ref) { assert(vpip_routines); return vpip_routines->free_object(ref); } PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info info) { assert(vpip_routines); return vpip_routines->get_vlog_info(info); } // control routines void vpi_control(PLI_INT32 operation, ...) { va_list ap; va_start(ap, operation); assert(vpip_routines); vpip_routines->vcontrol(operation, ap); va_end(ap); } void vpi_sim_control(PLI_INT32 operation, ...) { va_list ap; va_start(ap, operation); assert(vpip_routines); vpip_routines->vcontrol(operation, ap); va_end(ap); } // proposed standard extensions PLI_INT32 vpi_fopen(const char*name, const char*mode) { assert(vpip_routines); return vpip_routines->fopen(name, mode); } FILE*vpi_get_file(PLI_INT32 fd) { assert(vpip_routines); return vpip_routines->get_file(fd); } // Icarus extensions s_vpi_vecval vpip_calc_clog2(vpiHandle arg) { assert(vpip_routines); return vpip_routines->calc_clog2(arg); } void vpip_count_drivers(vpiHandle ref, unsigned idx, unsigned counts[4]) { assert(vpip_routines); vpip_routines->count_drivers(ref, idx, counts); } void vpip_format_strength(char*str, s_vpi_value*value, unsigned bit) { assert(vpip_routines); vpip_routines->format_strength(str, value, bit); } void vpip_make_systf_system_defined(vpiHandle ref) { assert(vpip_routines); vpip_routines->make_systf_system_defined(ref); } void vpip_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count) { assert(vpip_routines); vpip_routines->mcd_rawwrite(mcd, buf, count); } void vpip_set_return_value(int value) { assert(vpip_routines); vpip_routines->set_return_value(value); } DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version) { if (version != vpip_routines_version) return 0; vpip_routines = routines; return 1; } #else void __libvpi_c_dummy_function(void) { } #endif iverilog-12_0/vpi/lxt2_write.c000066400000000000000000001345511435245347300164250ustar00rootroot00000000000000/* * Copyright (c) 2003-2016 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef _AIX #pragma alloca #endif #include #include "lxt2_write.h" static char *lxt2_wr_vcd_truncate_bitvec(char *s) { char l, r; r=*s; if(r=='1') { return s; } else { s++; } for(;;s++) { l=r; r=*s; if(!r) return (s-1); if(l!=r) { return(((l=='0')&&(r=='1'))?s:s-1); } } } /* * in-place sort to keep chained facs from migrating... */ static void wave_mergesort(struct lxt2_wr_symbol **a, struct lxt2_wr_symbol **b, int lo, int hi) { int i, j, k; if (loname, a[j]->name) <= 0) { a[k++]=b[i++]; } else { a[k++]=a[j++]; } } while (kitem) { if (t->left == NULL) break; if (i < t->left->item) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (i > t->item) { if (t->right == NULL) break; if (i > t->right->item) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static lxt2_wr_ds_Tree * lxt2_wr_ds_insert(granmsk_t i, lxt2_wr_ds_Tree * t, int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ lxt2_wr_ds_Tree * n; n = (lxt2_wr_ds_Tree *) calloc (1, sizeof (lxt2_wr_ds_Tree)); if (n == NULL) { fprintf(stderr, "ds_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = lxt2_wr_ds_splay(i,t); if (i < t->item) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (i > t->item) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ static int lxt2_wr_dslxt_success; static lxt2_wr_dslxt_Tree * lxt2_wr_dslxt_splay (char *i, lxt2_wr_dslxt_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ lxt2_wr_dslxt_Tree N, *l, *r, *y; int dir; lxt2_wr_dslxt_success = 0; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = strcmp(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (strcmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { lxt2_wr_dslxt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static lxt2_wr_dslxt_Tree * lxt2_wr_dslxt_insert(char *i, lxt2_wr_dslxt_Tree * t, unsigned int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ lxt2_wr_dslxt_Tree * n; int dir; n = (lxt2_wr_dslxt_Tree *) calloc (1, sizeof (lxt2_wr_dslxt_Tree)); if (n == NULL) { fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = lxt2_wr_dslxt_splay(i,t); dir = strcmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ /* * functions which emit various big endian * data to a file */ static int lxt2_wr_emit_u8(struct lxt2_wr_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u16(struct lxt2_wr_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u32(struct lxt2_wr_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u64(struct lxt2_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=lxt2_wr_emit_u32(lt, valueh))) { rc=lxt2_wr_emit_u32(lt, valuel); } return(rc); } /* * gzfunctions which emit various big endian * data to a file. (lt->position needs to be * fixed up on gzclose so the tables don't * get out of sync!) */ static int gzwrite_buffered(struct lxt2_wr_trace *lt) { int rc = 1; if(lt->gzbufpnt > LXT2_WR_GZWRITE_BUFFER) { rc = gzwrite(lt->zhandle, lt->gzdest, lt->gzbufpnt); rc = rc ? 1 : 0; lt->gzbufpnt = 0; } return(rc); } static void gzflush_buffered(struct lxt2_wr_trace *lt, int doclose) { if(lt->gzbufpnt) { gzwrite(lt->zhandle, lt->gzdest, lt->gzbufpnt); lt->gzbufpnt = 0; if(!doclose) { gzflush(lt->zhandle, Z_SYNC_FLUSH); } } if(doclose) { gzclose(lt->zhandle); } } static int lxt2_wr_emit_u8z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount++; lt->position++; return(nmemb); } static int lxt2_wr_emit_u16z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb = gzwrite_buffered(lt); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lxt2_wr_emit_u24z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lxt2_wr_emit_u32z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>24) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lxt2_wr_emit_u64z(struct lxt2_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=lxt2_wr_emit_u32z(lt, valueh))) { rc=lxt2_wr_emit_u32z(lt, valuel); } return(rc); } static int lxt2_wr_emit_stringz(struct lxt2_wr_trace *lt, char *value) { int rc=1; do { rc&=lxt2_wr_emit_u8z(lt, *value); } while(*(value++)); return(rc); } /* * hash/symtable manipulation */ static int lxt2_wr_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%LXT2_WR_SYMPRIME); } static struct lxt2_wr_symbol *lxt2_wr_symadd(struct lxt2_wr_trace *lt, const char *name, int hv) { struct lxt2_wr_symbol *s; s=(struct lxt2_wr_symbol *)calloc(1,sizeof(struct lxt2_wr_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct lxt2_wr_symbol *lxt2_wr_symfind(struct lxt2_wr_trace *lt, const char *s) { int hv; struct lxt2_wr_symbol *temp; hv=lxt2_wr_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void lxt2_wr_compress_fac(struct lxt2_wr_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } lxt2_wr_emit_u16z(lt, i); lxt2_wr_emit_stringz(lt, str+i); free(lt->compress_fac_str); } else { lxt2_wr_emit_u16z(lt, 0); lxt2_wr_emit_stringz(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } /* * emit facs in sorted order along with geometry * and sync table info */ static void strip_brack(struct lxt2_wr_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='.') { return; /* MTI SV [0.3] notation for implicit vars */ } if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void lxt2_wr_emitfacs(struct lxt2_wr_trace *lt) { unsigned int i; if((lt)&&(lt->numfacs)) { struct lxt2_wr_symbol *s = lt->symchain; struct lxt2_wr_symbol **aliascache = (struct lxt2_wr_symbol**)calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *)); unsigned int aliases_encountered, facs_encountered; lt->sorted_facs = (struct lxt2_wr_symbol **)calloc(lt->numfacs, sizeof(struct lxt2_wr_symbol *)); if(lt->sorted_facs && aliascache) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); if(lt->partial_preference) { /* move preferenced facs up */ struct lxt2_wr_symbol **prefcache = aliascache; int prefs_encountered = 0; facs_encountered = 0; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->partial_preference)==0) { lt->sorted_facs[facs_encountered] = lt->sorted_facs[i]; facs_encountered++; } else { prefcache[prefs_encountered] = lt->sorted_facs[i]; prefs_encountered++; } } /* then append the non-preferenced facs */ for(i=0;isorted_facs[i]; } /* now make prefcache the main cache */ aliascache = lt->sorted_facs; lt->sorted_facs = prefcache; } /* move facs up */ aliases_encountered = 0, facs_encountered = 0; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&LXT2_WR_SYM_F_ALIAS)==0) { lt->sorted_facs[facs_encountered] = lt->sorted_facs[i]; facs_encountered++; } else { aliascache[aliases_encountered] = lt->sorted_facs[i]; aliases_encountered++; } } /* then append the aliases */ for(i=0;isorted_facs[facs_encountered+i] = aliascache[i]; } for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } if(!lt->timezero) { lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ } else { lxt2_wr_emit_u32(lt, 0); /* uncompressed, flag to insert extra parameters */ lxt2_wr_emit_u32(lt, 8); /* uncompressed 8 counts timezero and on */ lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ lxt2_wr_emit_u64(lt, (lt->timezero >> 32) & 0xffffffffL, lt->timezero & 0xffffffffL); /* uncompressed */ } lxt2_wr_emit_u32(lt, lt->numfacbytes); /* uncompressed */ lxt2_wr_emit_u32(lt, lt->longestname); /* uncompressed */ lt->facname_offset=lt->position; lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacnamesize */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacname_predec_size */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacgeometrysize */ lxt2_wr_emit_u8(lt, lt->timescale); /* timescale (-9 default == nsec) */ fflush(lt->handle); lt->zfacname_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->zpackcount = 0; for(i=0;inumfacs;i++) { lxt2_wr_compress_fac(lt, lt->sorted_facs[i]->name); free(lt->sorted_facs[i]->name); lt->sorted_facs[i]->name = NULL; } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->zfacname_predec_size = lt->zpackcount; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacname_size = lt->position - lt->zfacname_size; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&LXT2_WR_SYM_F_ALIAS)==0) { lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->rows); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->flags); } else { lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); lxt2_wr_emit_u32z(lt, LXT2_WR_SYM_F_ALIAS); } } gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->break_header_size = lt->position; /* in case we need to emit multiple lxt2s with same header */ lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; fseeko(lt->handle, lt->facname_offset, SEEK_SET); lxt2_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */ lxt2_wr_emit_u32(lt, lt->zfacname_predec_size); lxt2_wr_emit_u32(lt, lt->zfacgeometry_size); lt->numfacs = facs_encountered; /* don't process alias value changes ever */ } free(aliascache); } } /* * initialize the trace and get back an lt context */ struct lxt2_wr_trace *lxt2_wr_init(const char *name) { struct lxt2_wr_trace *lt=(struct lxt2_wr_trace *)calloc(1, sizeof(struct lxt2_wr_trace)); if((!name)||(!(lt->handle=fopen(name, "wb")))) { free(lt); lt=NULL; } else { lt->lxtname = strdup(name); lxt2_wr_emit_u16(lt, LXT2_WR_HDRID); lxt2_wr_emit_u16(lt, LXT2_WR_VERSION); lxt2_wr_emit_u8 (lt, LXT2_WR_GRANULE_SIZE); /* currently 32 or 64 */ lt->timescale = -9; lt->maxgranule = LXT2_WR_GRANULE_NUM; lxt2_wr_set_compression_depth(lt, 4); /* set fast/loose compression depth, user can fix this any time after init */ lt->initial_value = 'x'; } return(lt); } /* * setting break size */ void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz) { if(lt) { lt->break_size = siz; } } /* * enable/disable partial dump mode (for faster reads) */ void lxt2_wr_set_partial_off(struct lxt2_wr_trace *lt) { if(lt) { lt->partial = 0; lt->partial_zip = 0; } } void lxt2_wr_set_partial_on(struct lxt2_wr_trace *lt, int zipmode) { if(lt) { lt->partial = 1; lt->partial_zip = (zipmode != 0); lt->partial_iter = LXT2_WR_PARTIAL_SIZE; } } void lxt2_wr_set_partial_preference(struct lxt2_wr_trace *lt, const char *name) { struct lxt2_wr_symbol *s; if((lt)&&(name)&&(!lt->sorted_facs)) { s=lxt2_wr_symfind(lt, name); if(s) { while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } s->partial_preference = 1; } } } /* * enable/disable checkpointing (for smaller files) */ void lxt2_wr_set_checkpoint_off(struct lxt2_wr_trace *lt) { if(lt) { lt->no_checkpoint = 1; } } void lxt2_wr_set_checkpoint_on(struct lxt2_wr_trace *lt) { if(lt) { lt->no_checkpoint = 0; } } /* * set initial value of trace (0, 1, x, z) only legal vals */ void lxt2_wr_set_initial_value(struct lxt2_wr_trace *lt, char value) { if(lt) { switch(value) { case '0': case '1': case 'x': case 'z': break; case 'Z': value = 'z'; break; default: value = 'x'; break; } lt->initial_value = value; } } /* * maint function for finding a symbol if it exists */ struct lxt2_wr_symbol *lxt2_wr_symbol_find(struct lxt2_wr_trace *lt, const char *name) { struct lxt2_wr_symbol *s=NULL; if((lt)&&(name)) s=lxt2_wr_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct lxt2_wr_symbol *lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct lxt2_wr_symbol *s; int len; int flagcnt; if((!lt)||(lt->sorted_facs)) return(NULL); flagcnt = ((flags&LXT2_WR_SYM_F_INTEGER)!=0) + ((flags&LXT2_WR_SYM_F_DOUBLE)!=0) + ((flags&LXT2_WR_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(lxt2_wr_symfind(lt, name))) return (NULL); s=lxt2_wr_symadd(lt, name, lxt2_wr_hash(name)); s->rows = rows; s->flags = flags&(~LXT2_WR_SYM_F_ALIAS); /* aliasing makes no sense here.. */ if(!flagcnt) { s->msb = msb; s->lsb = lsb; s->len = (msbvalue = strdup("NaN"); } else { if(flags & LXT2_WR_SYM_F_INTEGER) { s->len = 32; } s->value = (char*)malloc(s->len + 1); memset(s->value, lt->initial_value, s->len); s->value[s->len]=0; s->msk = LXT2_WR_GRAN_1VAL; /* stuff in an initial value */ switch(lt->initial_value) { case '0': s->chg[0] = LXT2_WR_ENC_0; break; case '1': s->chg[0] = LXT2_WR_ENC_1; break; case 'z': s->chg[0] = LXT2_WR_ENC_Z; break; default: s->chg[0] = LXT2_WR_ENC_X; break; } s->chgpos++; /* don't worry that a time doesn't exist as it will soon enough.. */ } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct lxt2_wr_symbol *lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct lxt2_wr_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=lxt2_wr_symfind(lt, existing_name)))||(lxt2_wr_symfind(lt, alias))) return (NULL); if(lt->sorted_facs) return(NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags&LXT2_WR_SYM_F_INTEGER)!=0) + ((s->flags&LXT2_WR_SYM_F_DOUBLE)!=0) + ((s->flags&LXT2_WR_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=lxt2_wr_symadd(lt, alias, lxt2_wr_hash(alias)); sa->flags = LXT2_WR_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; lt->numalias++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time/granule updating */ int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval) { return(lxt2_wr_set_time64(lt, lt->maxtime + (lxttime_t)timeval)); } int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval) { return(lxt2_wr_set_time64(lt, (lxttime_t)timeval)); } int lxt2_wr_inc_time_by_delta64(struct lxt2_wr_trace *lt, lxttime_t timeval) { return(lxt2_wr_set_time64(lt, lt->maxtime + timeval)); } /* * file size limiting/header cloning... */ static void lxt2_wr_emit_do_breakfile(struct lxt2_wr_trace *lt) { unsigned int len = strlen(lt->lxtname); int i; char *tname = (char*)malloc(len + 30); FILE *f2, *clone; off_t cnt, seg; char buf[32768]; for(i=len;i>0;i--) { if(lt->lxtname[i]=='.') break; } if(!i) { sprintf(tname, "%s_%03u.lxt", lt->lxtname, ++lt->break_number); } else { memcpy(tname, lt->lxtname, i); sprintf(tname+i, "_%03u.lxt", ++lt->break_number); } f2 = fopen(tname, "wb"); if(!f2) /* if error, keep writing to same output file...sorry */ { free(tname); return; } clone = fopen(lt->lxtname, "rb"); if(!clone) { /* this should never happen */ fclose(f2); unlink(tname); free(tname); return; } /* clone original header */ for(cnt = 0; cnt < lt->break_header_size; cnt += sizeof(buf)) { seg = lt->break_header_size - cnt; if(seg > (off_t)sizeof(buf)) { seg = sizeof(buf); } if(fread(buf, seg, 1, clone)) { if(!fwrite(buf, seg, 1, f2)) break; /* write error! */ } } fclose(clone); fclose(lt->handle); lt->handle = f2; free(tname); } /* * emit granule */ void lxt2_wr_flush_granule(struct lxt2_wr_trace *lt, int do_finalize) { unsigned int idx_nbytes, map_nbytes, i, j; struct lxt2_wr_symbol *s; unsigned int partial_iter; unsigned int iter, iter_hi; unsigned char using_partial, using_partial_zip=0; off_t current_iter_pos=0; int early_flush; if(lt->flush_valid) { if(lt->flushtime == lt->lasttime) { return; } lt->flush_valid = 0; } lt->granule_dirty = 0; if((using_partial=(lt->partial)&&(lt->numfacs>lt->partial_iter))) { partial_iter = lt->partial_iter; using_partial_zip = lt->partial_zip; } else { partial_iter = lt->numfacs; } if(!lt->timegranule) { int attempt_break_state = 2; do { fseeko(lt->handle, 0L, SEEK_END); lt->current_chunk=lt->position = ftello(lt->handle); if((lt->break_size)&&(attempt_break_state==2)&&(lt->position >= lt->break_size)&&(lt->position != lt->break_header_size)) { lxt2_wr_emit_do_breakfile(lt); attempt_break_state--; } else { attempt_break_state = 0; } } while(attempt_break_state); /* fprintf(stderr, "First chunk position is %d (0x%08x)\n", lt->current_chunk, lt->current_chunk); */ lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u64(lt, 0, 0); /* begin time of section */ lxt2_wr_emit_u64(lt, 0, 0); /* end time of section */ fflush(lt->handle); lt->current_chunkz = lt->position; /* fprintf(stderr, "First chunkz position is %d (0x%08x)\n", lt->current_chunkz, lt->current_chunkz); */ if(!using_partial_zip) { lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); } else { lt->zpackcount_cumulative = 0; } lt->zpackcount = 0; } for(iter=0; iternumfacs; iter=iter_hi) { unsigned int total_chgs; unsigned int partial_length; total_chgs = 0; /* partial_length = 0; */ /* scan-build : never read */ iter_hi = iter + partial_iter; if(iter_hi > lt->numfacs) iter_hi = lt->numfacs; for(j=iter;jsorted_facs[j]->msk; lt->mapdict = lxt2_wr_ds_splay (msk, lt->mapdict); if((!lt->mapdict)||(lt->mapdict->item != msk)) { lt->mapdict = lxt2_wr_ds_insert(msk, lt->mapdict, lt->num_map_entries); lt->num_map_entries++; if(lt->mapdict_curr) { lt->mapdict_curr->next = lt->mapdict; lt->mapdict_curr = lt->mapdict; } else { lt->mapdict_head = lt->mapdict_curr = lt->mapdict; } } } if(lt->num_map_entries <= 256) { map_nbytes = 1; } else if(lt->num_map_entries <= 256*256) { map_nbytes = 2; } else if(lt->num_map_entries <= 256*256*256) { map_nbytes = 3; } else { map_nbytes = 4; } if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256) { idx_nbytes = 1; } else if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256*256) { idx_nbytes = 2; } else if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256*256*256) { idx_nbytes = 3; } else { idx_nbytes = 4; } if(using_partial) { /* skip */ partial_length = 1 + /* lt->timepos */ lt->timepos * sizeof(lxttime_t)+ /* timevals */ 1 + /* map_nbytes */ (iter_hi-iter) * map_nbytes + /* actual map */ 1; /* idx_nbytes */ for(j=iter;jsorted_facs[j]; total_chgs += s->chgpos; } total_chgs *= idx_nbytes; /* vch skip */ partial_length += total_chgs; /* actual changes */ if(using_partial_zip) { fseeko(lt->handle, 0L, SEEK_END); current_iter_pos = ftello(lt->handle); lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u32(lt, partial_length+9); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, iter); /* begin iter of section */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); lt->zpackcount = 0; } lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_TIME_PARTIAL); lxt2_wr_emit_u32z(lt, iter); lxt2_wr_emit_u32z(lt, partial_length); } else { lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_TIME); } lxt2_wr_emit_u8z(lt, lt->timepos); for(i=0;itimepos;i++) { lxt2_wr_emit_u64z(lt, (lt->timetable[i]>>32)&0xffffffff, lt->timetable[i]&0xffffffff); } gzflush_buffered(lt, 0); lxt2_wr_emit_u8z(lt, map_nbytes); for(j=iter;jsorted_facs[j]; lt->mapdict = lxt2_wr_ds_splay (s->msk, lt->mapdict); val = lt->mapdict->val; switch(map_nbytes) { case 1: lxt2_wr_emit_u8z(lt, val); break; case 2: lxt2_wr_emit_u16z(lt, val); break; case 3: lxt2_wr_emit_u24z(lt, val); break; case 4: lxt2_wr_emit_u32z(lt, val); break; } s->msk = LXT2_WR_GRAN_0VAL; } lxt2_wr_emit_u8z(lt, idx_nbytes); gzflush_buffered(lt, 0); for(j=iter;jsorted_facs[j]; for(i=0;ichgpos;i++) { switch(idx_nbytes) { case 1: lxt2_wr_emit_u8z (lt, s->chg[i]); break; case 2: lxt2_wr_emit_u16z(lt, s->chg[i]); break; case 3: lxt2_wr_emit_u24z(lt, s->chg[i]); break; case 4: lxt2_wr_emit_u32z(lt, s->chg[i]); break; } } s->chgpos = 0; } if(using_partial_zip) { off_t clen; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); clen = lt->position - current_iter_pos - 12; fseeko(lt->handle, current_iter_pos, SEEK_SET); lt->zpackcount_cumulative+=lt->zpackcount; lxt2_wr_emit_u32(lt, clen); } else { gzflush_buffered(lt, 0); } } /* ...for(iter) */ lt->timepos = 0; lt->timegranule++; if(lt->break_size) { early_flush = (ftello(lt->handle) >= lt->break_size); } else { early_flush = 0; } if((lt->timegranule>=lt->maxgranule)||(do_finalize)||(early_flush)) { off_t unclen, clen; lxt2_wr_ds_Tree *dt, *dt2; lxt2_wr_dslxt_Tree *ds, *ds2; if(using_partial_zip) { fseeko(lt->handle, 0L, SEEK_END); current_iter_pos = ftello(lt->handle); lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, ~0); /* control section */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); lt->zpackcount = 0; } /* fprintf(stderr, "reached granule %d, finalizing block for section %d\n", lt->timegranule, lt->numsections); */ lt->numsections++; /* finalize string dictionary */ lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_DICT); ds = lt->dict_head; /* fprintf(stderr, "num_dict_entries: %d\n", lt->num_dict_entries); */ gzflush_buffered(lt, 0); for(i=0;inum_dict_entries;i++) { /* fprintf(stderr, "%8d %8d) '%s'\n", ds->val, i, ds->item); */ if(ds->val != i) { fprintf(stderr, "internal error line %d\n", __LINE__); exit(255); } lxt2_wr_emit_stringz(lt, ds->item); ds2 = ds->next; free(ds->item); free(ds); ds = ds2; } lt->dict_head = lt->dict_curr = lt->dict = NULL; /* finalize map dictionary */ dt = lt->mapdict_head; /* fprintf(stderr, "num_map_entries: %d\n", lt->num_map_entries); */ gzflush_buffered(lt, 0); for(i=0;inum_map_entries;i++) { /* fprintf(stderr, "+++ %08x (%d)(%d)\n", dt->item, i, dt->val); */ if(((unsigned int)dt->val) != i) { fprintf(stderr, "internal error line %d\n", __LINE__); exit(255); } #if LXT2_WR_GRANULE_SIZE > 32 lxt2_wr_emit_u64z(lt, (dt->item>>32)&0xffffffff, dt->item&0xffffffff); #else lxt2_wr_emit_u32z(lt, dt->item); #endif dt2 = dt->next; free(dt); dt = dt2; } lt->mapdict_head = lt->mapdict_curr = lt->mapdict = NULL; lxt2_wr_emit_u32z(lt, lt->num_dict_entries); /* -12 */ lxt2_wr_emit_u32z(lt, lt->dict_string_mem_required); /* -8 */ lxt2_wr_emit_u32z(lt, lt->num_map_entries); /* -4 */ lt->num_map_entries = 0; lt->num_dict_entries = lt->dict_string_mem_required = 0; /* fprintf(stderr, "returned from finalize..\n"); */ if(using_partial_zip) { off_t c_len; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); c_len = lt->position - current_iter_pos - 12; fseeko(lt->handle, current_iter_pos, SEEK_SET); lt->zpackcount_cumulative+=lt->zpackcount; lxt2_wr_emit_u32(lt, c_len); lxt2_wr_emit_u32(lt, lt->zpackcount); } else { gzflush_buffered(lt, 1); } fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); /* fprintf(stderr, "file position after dumping dict: %d 0x%08x\n", lt->position, lt->position); */ unclen = lt->zpackcount; clen = lt->position - lt->current_chunkz; /* fprintf(stderr, "%d/%d un/compressed bytes in section\n", unclen, clen); */ fseeko(lt->handle, lt->current_chunk, SEEK_SET); if(using_partial_zip) { lxt2_wr_emit_u32(lt, lt->zpackcount_cumulative); lxt2_wr_emit_u32(lt, clen); } else { lxt2_wr_emit_u32(lt, unclen); lxt2_wr_emit_u32(lt, clen); } lxt2_wr_emit_u64(lt, (lt->firsttime>>32)&0xffffffff, lt->firsttime&0xffffffff); lxt2_wr_emit_u64(lt, (lt->lasttime>>32)&0xffffffff, lt->lasttime&0xffffffff); /* fprintf(stderr, "start: %lld, end %lld\n", lt->firsttime, lt->lasttime); */ lt->timegranule=0; lt->numblock++; } if(do_finalize) { lt->flush_valid = 1; lt->flushtime = lt->lasttime; } } int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval) { int rc=0; if(lt) { if(lt->timeset) { if(timeval > lt->maxtime) { if(lt->bumptime) { lt->bumptime = 0; if(!lt->flush_valid) { lt->timepos++; } else { lt->flush_valid = 0; } if(lt->timepos == LXT2_WR_GRANULE_SIZE) { /* fprintf(stderr, "flushing granule to disk at time %d\n", (unsigned int)timeval); */ lxt2_wr_flush_granule(lt, 0); } } /* fprintf(stderr, "updating time to %d (%d dict entries/%d bytes)\n", (unsigned int)timeval, lt->num_dict_entries, lt->dict_string_mem_required); */ lt->timetable[lt->timepos] = timeval; lt->lasttime = timeval; } } else { lt->timeset = 1; lt->mintime = lt->maxtime = timeval; lt->timetable[lt->timepos] = timeval; } if( (!lt->timepos) && (!lt->timegranule) ) { lt->firsttime = timeval; lt->lasttime = timeval; } if( (!lt->timepos) && (!lt->timegranule) && ((!lt->numblock)||(!lt->no_checkpoint)) ) { /* fprintf(stderr, "initial value burst timepos==0, timegranule==0\n"); */ if(lt->blackout) { lt->blackout = 0; lxt2_wr_set_dumpoff(lt); } else { struct lxt2_wr_symbol *s = lt->symchain; while(s) { if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2)) { if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { lxt2_wr_emit_value_bit_string(lt, s, 0, s->value); } else if (s->flags&LXT2_WR_SYM_F_DOUBLE) { double value = 0; sscanf(s->value, "%lg", &value); errno = 0; lxt2_wr_emit_value_double(lt, s, 0, value); } else if (s->flags&LXT2_WR_SYM_F_STRING) { lxt2_wr_emit_value_string(lt, s, 0, s->value); } } s=s->symchain; } } /* fprintf(stderr, "done initial value burst timepos==0, timegranule==0\n"); */ } lt->granule_dirty = 1; rc = 1; } return(rc); } /* * sets trace timescale as 10**x seconds */ void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * set number of granules per section * (can modify dynamically) */ void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule) { if(lt) { if(!maxgranule) maxgranule = ~0; lt->maxgranule = maxgranule; } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } static char *lxt2_wr_expand_integer_to_bits(unsigned int len, int value) { static char s[33]; char *p = s; unsigned int i; if(len>32) len=32; len--; for(i=0;i<=len;i++) { *(p++) = '0' | ((value & (1<<(len-i)))!=0); } *p = 0; return(s); } int lxt2_wr_emit_value_int(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(row)) return(rc); return(lxt2_wr_emit_value_bit_string(lt, s, row, lxt2_wr_expand_integer_to_bits(s->len, value))); } int lxt2_wr_emit_value_double(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, double value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(s->flags&LXT2_WR_SYM_F_DOUBLE) { char d_buf[32]; unsigned int idx; rc = 1; sprintf(d_buf, "%.16g", value); if(!strcmp(d_buf, s->value)) return(rc); lt->bumptime = 1; free(s->value); s->value = strdup(d_buf); lt->dict = lxt2_wr_dslxt_splay (s->value, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(d_buf)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, d_buf); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } lt->granule_dirty = 1; } return(rc); } int lxt2_wr_emit_value_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(!value)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(s->flags&LXT2_WR_SYM_F_STRING) { unsigned int idx; rc = 1; if(!strcmp(value, s->value)) return(rc); lt->bumptime = 1; free(s->value); s->value = strdup(value); lt->dict = lxt2_wr_dslxt_splay (s->value, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(value)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, value); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } lt->granule_dirty = 1; } return(rc); } int lxt2_wr_emit_value_bit_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value) { int rc=0; char *vpnt; char *vfix; int valuelen; int i; if((!lt)||(lt->blackout)||(!s)||(!value)||(!*value)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } valuelen = strlen(value); /* ensure string is proper length */ if(valuelen == s->len) { vfix = (char*)wave_alloca(s->len+1); strcpy(vfix, value); value = vfix; } else { vfix = (char*)wave_alloca(s->len+1); if(valuelen < s->len) { int lendelta = s->len - valuelen; memset(vfix, (value[0]!='1') ? value[0] : '0', lendelta); strcpy(vfix+lendelta, value); } else { memcpy(vfix, value, s->len); vfix[s->len] = 0; } value = vfix; } for(i=0;ilen;i++) { unsigned char ch = value[i]; if((ch>='A')&&(ch<='Z')) value[i] = ch + ('a'-'A'); } if ( (lt->timepos || lt->timegranule) && !strcmp(value, s->value) ) { return(1); /* redundant value change */ } if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { char prevch; int idx; lt->bumptime = 1; vpnt = value; prevch = *vpnt; while(*vpnt) { if(prevch == *vpnt) { vpnt++; } else { prevch = 0; break; } } switch(prevch) { case '0': idx = LXT2_WR_ENC_0; break; case '1': idx = LXT2_WR_ENC_1; break; case 'X': case 'x': idx = LXT2_WR_ENC_X; break; case 'Z': case 'z': idx = LXT2_WR_ENC_Z; break; default: idx = -1; break; } if((lt->timepos)||(lt->timegranule)) { for(i=0;ilen;i++) { char ch = value[i]; switch(ch) { case '0': if(s->value[i]!='1') goto nextalg; else break; case '1': if(s->value[i]!='0') goto nextalg; else break; default: goto nextalg; } } idx = LXT2_WR_ENC_INV; goto do_enc; nextalg: if(s->len > 1) { if(!memcmp(s->value+1, value, s->len-1)) { if((value[s->len-1]&0xfe)=='0') { idx = LXT2_WR_ENC_LSH0 + (value[s->len-1]&0x01); goto do_enc; } } else if(!memcmp(s->value, value+1, s->len-1)) { if((value[0]&0xfe)=='0') { idx = LXT2_WR_ENC_RSH0 + (value[0]&0x01); goto do_enc; } } if(s->len <= 32) { unsigned int intval_old = 0, intval_new = 0; unsigned int msk; for(i=0;ilen;i++) { char ch = value[i]; if((ch!='0')&&(ch!='1')) goto idxchk; intval_new <<= 1; intval_new |= ((unsigned int)(ch&1)); ch = s->value[i]; if((ch!='0')&&(ch!='1')) goto idxchk; intval_old <<= 1; intval_old |= ((unsigned int)(ch&1)); } msk = (~0)>>(32-s->len); if( ((intval_old+1)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD1; goto do_enc; } if( ((intval_old-1)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB1; goto do_enc; } if( ((intval_old+2)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD2; goto do_enc; } if( ((intval_old-2)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB2; goto do_enc; } if( ((intval_old+3)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD3; goto do_enc; } if( ((intval_old-3)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB3; goto do_enc; } if(s->len > 2) { if( ((intval_old+4)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD4; goto do_enc; } if( ((intval_old-4)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB4; goto do_enc; } } } } } idxchk: if(idx<0) { vpnt = lxt2_wr_vcd_truncate_bitvec(value); lt->dict = lxt2_wr_dslxt_splay (vpnt, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } } do_enc: if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } strncpy(s->value, value, s->len); lt->granule_dirty = 1; } return(rc); } /* * dumping control */ void lxt2_wr_set_dumpoff(struct lxt2_wr_trace *lt) { struct lxt2_wr_symbol *s; if((lt)&&(!lt->blackout)) { if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } s = lt->symchain; while(s) { if(!(s->flags&LXT2_WR_SYM_F_ALIAS)) { if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = LXT2_WR_ENC_BLACKOUT; s->chgpos++; } else { s->chg[s->chgpos-1] = LXT2_WR_ENC_BLACKOUT; } } s=s->symchain; } lt->bumptime = 1; lt->blackout = 1; lt->granule_dirty = 1; } } void lxt2_wr_set_dumpon(struct lxt2_wr_trace *lt) { int i; struct lxt2_wr_symbol *s; if((lt)&&(lt->blackout)) { lt->blackout = 0; s = lt->symchain; while(s) { if(!(s->flags&LXT2_WR_SYM_F_ALIAS)) { if(s->flags&LXT2_WR_SYM_F_DOUBLE) { free(s->value); s->value = strdup("0"); /* will cause mismatch then flush */ } else { if(!(s->flags&LXT2_WR_SYM_F_STRING)) { s->value[0] = '-'; /* will cause mismatch then flush */ for(i=1;ilen;i++) { s->value[i] = 'x'; /* initial value */ } s->value[i]=0; } else { free(s->value); s->value = (char*)calloc(1, 1*sizeof(char)); } } } s=s->symchain; } s = lt->symchain; while(s) { if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2)) { char tmp[16]; /* To get rid of the warning */ if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { strcpy(tmp, "x"); lxt2_wr_emit_value_bit_string(lt, s, 0, tmp); } else if (s->flags&LXT2_WR_SYM_F_DOUBLE) { double value; sscanf("NaN", "%lg", &value); lxt2_wr_emit_value_double(lt, s, 0, value); } else if (s->flags&LXT2_WR_SYM_F_STRING) { strcpy(tmp, "UNDEF"); lxt2_wr_emit_value_string(lt, s, 0, tmp); } } s=s->symchain; } } } /* * flush the trace... */ void lxt2_wr_flush(struct lxt2_wr_trace *lt) { if(lt) { if((lt->timegranule)||(lt->timepos > 0)) { if(lt->granule_dirty) { lt->timepos++; lxt2_wr_flush_granule(lt, 1); } } } } /* * close out the trace and fixate it */ void lxt2_wr_close(struct lxt2_wr_trace *lt) { if(lt) { if(lt->granule_dirty) { lt->timepos++; lxt2_wr_flush_granule(lt, 1); } if(lt->symchain) { struct lxt2_wr_symbol *s = lt->symchain; struct lxt2_wr_symbol *s2; while(s) { free(s->name); free(s->value); s2=s->symchain; free(s); s=s2; } lt->symchain=NULL; } free(lt->lxtname); free(lt->sorted_facs); fclose(lt->handle); free(lt); } } /* * set compression depth */ void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth) { if(lt) { if(depth > 9) depth = 9; sprintf(lt->zmode, "wb%u", depth); } } /* * time zero offset */ void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval) { if(lt) { lt->timezero = timeval; } } iverilog-12_0/vpi/lxt2_write.h000066400000000000000000000232141435245347300164230ustar00rootroot00000000000000/* * Copyright (c) 2003-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXTW_H #define DEFS_LXTW_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #include #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #include "wavealloca.h" #define LXT2_WR_HDRID (0x1380) #define LXT2_WR_VERSION (0x0001) #define LXT2_WR_GRANULE_SIZE (64) #define LXT2_WR_GRANULE_NUM (256) #define LXT2_WR_PARTIAL_SIZE (2048) #define LXT2_WR_GRAN_SECT_TIME 0 #define LXT2_WR_GRAN_SECT_DICT 1 #define LXT2_WR_GRAN_SECT_TIME_PARTIAL 2 #define LXT2_WR_GZWRITE_BUFFER 4096 #define LXT2_WR_SYMPRIME 500009 typedef uint64_t lxttime_t; typedef int64_t lxtstime_t; #ifndef _MSC_VER #ifdef __MINGW32__ #define LXT2_WR_LLD "%I64d" #else #define LXT2_WR_LLD "%lld" #endif #define LXT2_WR_LLDESC(x) x##LL #define LXT2_WR_ULLDESC(x) x##ULL #else #define LXT2_WR_LLD "%I64d" #define LXT2_WR_LLDESC(x) x##i64 #define LXT2_WR_ULLDESC(x) x##i64 #endif #if LXT2_WR_GRANULE_SIZE > 32 typedef unsigned long long granmsk_t; #define LXT2_WR_GRAN_0VAL (LXT2_WR_ULLDESC(0)) #define LXT2_WR_GRAN_1VAL (LXT2_WR_ULLDESC(1)) #else typedef unsigned int granmsk_t; #define LXT2_WR_GRAN_0VAL (0) #define LXT2_WR_GRAN_1VAL (1) #endif enum LXT2_WR_Encodings { LXT2_WR_ENC_0, LXT2_WR_ENC_1, LXT2_WR_ENC_INV, LXT2_WR_ENC_LSH0, LXT2_WR_ENC_LSH1, LXT2_WR_ENC_RSH0, LXT2_WR_ENC_RSH1, LXT2_WR_ENC_ADD1, LXT2_WR_ENC_ADD2, LXT2_WR_ENC_ADD3, LXT2_WR_ENC_ADD4, LXT2_WR_ENC_SUB1, LXT2_WR_ENC_SUB2, LXT2_WR_ENC_SUB3, LXT2_WR_ENC_SUB4, LXT2_WR_ENC_X, LXT2_WR_ENC_Z, LXT2_WR_ENC_BLACKOUT, LXT2_WR_DICT_START }; /* * integer splay */ typedef struct lxt2_wr_ds_tree_node lxt2_wr_ds_Tree; struct lxt2_wr_ds_tree_node { lxt2_wr_ds_Tree * left, * right; granmsk_t item; int val; lxt2_wr_ds_Tree * next; }; /* * string splay */ typedef struct lxt2_wr_dslxt_tree_node lxt2_wr_dslxt_Tree; struct lxt2_wr_dslxt_tree_node { lxt2_wr_dslxt_Tree * left, * right; char *item; unsigned int val; lxt2_wr_dslxt_Tree * next; }; struct lxt2_wr_trace { FILE *handle; gzFile zhandle; lxt2_wr_dslxt_Tree *dict; /* dictionary manipulation */ unsigned int num_dict_entries; unsigned int dict_string_mem_required; lxt2_wr_dslxt_Tree *dict_head; lxt2_wr_dslxt_Tree *dict_curr; lxt2_wr_ds_Tree *mapdict; /* bitmap compression */ unsigned int num_map_entries; lxt2_wr_ds_Tree *mapdict_head; lxt2_wr_ds_Tree *mapdict_curr; off_t position; off_t zfacname_predec_size, zfacname_size, zfacgeometry_size; off_t zpackcount, zpackcount_cumulative; off_t current_chunk, current_chunkz; struct lxt2_wr_symbol *sym[LXT2_WR_SYMPRIME]; struct lxt2_wr_symbol **sorted_facs; struct lxt2_wr_symbol *symchain; unsigned int numfacs, numalias; int numfacbytes; int longestname; int numsections, numblock; off_t facname_offset, facgeometry_offset; lxttime_t mintime, maxtime; lxtstime_t timezero; unsigned int timegranule; int timescale; unsigned int timepos; unsigned int maxgranule; lxttime_t firsttime, lasttime; lxttime_t timetable[LXT2_WR_GRANULE_SIZE]; unsigned int partial_iter; char *compress_fac_str; int compress_fac_len; lxttime_t flushtime; unsigned flush_valid : 1; unsigned do_strip_brackets : 1; unsigned emitted : 1; /* gate off change field zmode changes when set */ unsigned timeset : 1; /* time has been modified from 0..0 */ unsigned bumptime : 1; /* says that must go to next time position in granule as value change exists for current time */ unsigned granule_dirty : 1; /* for flushing out final block */ unsigned blackout : 1; /* blackout on/off */ unsigned partial : 1; /* partial (vertical) trace support */ unsigned partial_zip : 1; /* partial (vertical) trace support for zip subregions */ unsigned no_checkpoint : 1; /* turns off interblock checkpointing */ unsigned partial_preference : 1; /* partial preference encountered on some facs */ char initial_value; char zmode[4]; /* fills in with "wb0".."wb9" */ unsigned int gzbufpnt; unsigned char gzdest[LXT2_WR_GZWRITE_BUFFER + 4]; /* enough for zlib buffering */ char *lxtname; off_t break_size; off_t break_header_size; unsigned int break_number; }; struct lxt2_wr_symbol { struct lxt2_wr_symbol *next; struct lxt2_wr_symbol *symchain; char *name; int namlen; int facnum; struct lxt2_wr_symbol *aliased_to; char *value; /* fac's actual value */ unsigned int rows; int msb, lsb; int len; int flags; unsigned partial_preference : 1; /* in order to shove nets to the first partial group */ unsigned int chgpos; granmsk_t msk; /* must contain LXT2_WR_GRANULE_SIZE bits! */ unsigned int chg[LXT2_WR_GRANULE_SIZE]; }; #define LXT2_WR_SYM_F_BITS (0) #define LXT2_WR_SYM_F_INTEGER (1<<0) #define LXT2_WR_SYM_F_DOUBLE (1<<1) #define LXT2_WR_SYM_F_STRING (1<<2) #define LXT2_WR_SYM_F_TIME (LXT2_WR_SYM_F_STRING) /* user must correctly format this as a string */ #define LXT2_WR_SYM_F_ALIAS (1<<3) #define LXT2_WR_SYM_F_SIGNED (1<<4) #define LXT2_WR_SYM_F_BOOLEAN (1<<5) #define LXT2_WR_SYM_F_NATURAL ((1<<6)|(LXT2_WR_SYM_F_INTEGER)) #define LXT2_WR_SYM_F_POSITIVE ((1<<7)|(LXT2_WR_SYM_F_INTEGER)) #define LXT2_WR_SYM_F_CHARACTER (1<<8) #define LXT2_WR_SYM_F_CONSTANT (1<<9) #define LXT2_WR_SYM_F_VARIABLE (1<<10) #define LXT2_WR_SYM_F_SIGNAL (1<<11) #define LXT2_WR_SYM_F_IN (1<<12) #define LXT2_WR_SYM_F_OUT (1<<13) #define LXT2_WR_SYM_F_INOUT (1<<14) #define LXT2_WR_SYM_F_WIRE (1<<15) #define LXT2_WR_SYM_F_REG (1<<16) /* file I/O */ struct lxt2_wr_trace * lxt2_wr_init(const char *name); void lxt2_wr_flush(struct lxt2_wr_trace *lt); void lxt2_wr_close(struct lxt2_wr_trace *lt); /* for dealing with very large traces, split into multiple files approximately "siz" in length */ void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz); /* 0 = no compression, 9 = best compression, 4 = default */ void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth); /* default is partial off, turning on makes for faster trace reads, nonzero zipmode causes vertical compression */ void lxt2_wr_set_partial_off(struct lxt2_wr_trace *lt); void lxt2_wr_set_partial_on(struct lxt2_wr_trace *lt, int zipmode); void lxt2_wr_set_partial_preference(struct lxt2_wr_trace *lt, const char *name); /* turning off checkpointing makes for smaller files */ void lxt2_wr_set_checkpoint_off(struct lxt2_wr_trace *lt); void lxt2_wr_set_checkpoint_on(struct lxt2_wr_trace *lt); /* facility creation */ void lxt2_wr_set_initial_value(struct lxt2_wr_trace *lt, char value); struct lxt2_wr_symbol * lxt2_wr_symbol_find(struct lxt2_wr_trace *lt, const char *name); struct lxt2_wr_symbol * lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct lxt2_wr_symbol * lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit); /* each granule is LXT2_WR_GRANULE_SIZE (32 or 64) timesteps, default is 256 per section */ void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule); /* time ops */ void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale); void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval); int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval); int lxt2_wr_inc_time_by_delta64(struct lxt2_wr_trace *lt, lxttime_t timeval); /* allows blackout regions in LXT files */ void lxt2_wr_set_dumpoff(struct lxt2_wr_trace *lt); void lxt2_wr_set_dumpon(struct lxt2_wr_trace *lt); /* left fill on bit_string uses vcd semantics (left fill with value[0] unless value[0]=='1', then use '0') */ int lxt2_wr_emit_value_int(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, int value); int lxt2_wr_emit_value_double(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, double value); int lxt2_wr_emit_value_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value); int lxt2_wr_emit_value_bit_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value); #ifdef __cplusplus } #endif #endif iverilog-12_0/vpi/lxt_write.c000066400000000000000000001632061435245347300163420ustar00rootroot00000000000000/* * Copyright (c) 2001-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "lxt_write.h" /* * in-place sort to keep chained facs from migrating... */ static void wave_mergesort(struct lt_symbol **a, struct lt_symbol **b, int lo, int hi) { int i, j, k; if (loname, a[j]->name) <= 0) { a[k++]=b[i++]; } else { a[k++]=a[j++]; } } while (kitem); if (dir < 0) { if (t->left == NULL) break; if (strcmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { dslxt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static dslxt_Tree * dslxt_insert(char *i, dslxt_Tree * t, unsigned int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ dslxt_Tree * n; int dir; n = (dslxt_Tree *) calloc (1, sizeof (dslxt_Tree)); if (n == NULL) { fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = dslxt_splay(i,t); dir = strcmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } #if 0 /* unused for now but delete is here for completeness */ static dslxt_Tree * dslxt_delete(char *i, dslxt_Tree * t) { /* Deletes i from the tree if it's there. */ /* Return a pointer to the resulting tree. */ dslxt_Tree * x; if (t==NULL) return NULL; t = dslxt_splay(i,t); if (!strcmp(i, t->item)) { /* found it */ if (t->left == NULL) { x = t->right; } else { x = dslxt_splay(i, t->left); x->right = t->right; } free(t); return x; } return t; /* It wasn't there */ } #endif /************************ splay ************************/ /* * functions which emit various big endian * data to a file */ static int lt_emit_u8(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u16(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u24(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 3, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u32(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u64(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32(lt, valueh))) { rc=lt_emit_u32(lt, valuel); } return(rc); } static int lt_emit_double(struct lt_trace *lt, double value) { int nmemb; nmemb=fwrite(&value, sizeof(char), sizeof(double)/sizeof(char), lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_string(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8(lt, *value); } while(*(value++)); return(rc); } /* * gzfunctions which emit various big endian * data to a file. (lt->position needs to be * fixed up on gzclose so the tables don't * get out of sync!) */ static int lt_emit_u8z(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 1); lt->zpackcount++; lt->position++; return(nmemb); } static int lt_emit_u16z(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = gzwrite(lt->zhandle, buf, 2); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lt_emit_u24z(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 3); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lt_emit_u32z(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 4); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lt_emit_u64z(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32z(lt, valueh))) { rc=lt_emit_u32z(lt, valuel); } return(rc); } static int lt_emit_doublez(struct lt_trace *lt, double value) { int nmemb; nmemb=gzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char)); lt->zpackcount+=(sizeof(double)/sizeof(char)); lt->position+=(sizeof(double)/sizeof(char));; return(nmemb); } static int lt_emit_stringz(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8z(lt, *value); } while(*(value++)); return(rc); } /* * bz2functions which emit various big endian * data to a file. (lt->position needs to be * fixed up on BZ2_bzclose so the tables don't * get out of sync!) */ static int lt_emit_u8bz(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 1); lt->zpackcount++; lt->position++; return(nmemb); } static int lt_emit_u16bz(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = BZ2_bzwrite(lt->zhandle, buf, 2); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lt_emit_u24bz(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 3); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lt_emit_u32bz(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 4); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lt_emit_u64bz(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32bz(lt, valueh))) { rc=lt_emit_u32bz(lt, valuel); } return(rc); } static int lt_emit_doublebz(struct lt_trace *lt, double value) { int nmemb; nmemb=BZ2_bzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char)); lt->zpackcount+=(sizeof(double)/sizeof(char)); lt->position+=(sizeof(double)/sizeof(char));; return(nmemb); } static int lt_emit_stringbz(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8bz(lt, *value); } while(*(value++)); return(rc); } /* * switch between compression modes above */ static void lt_set_zmode(struct lt_trace *lt, int mode) { switch(mode) { case LT_ZMODE_NONE: lt->lt_emit_u8 = lt_emit_u8; lt->lt_emit_u16 = lt_emit_u16; lt->lt_emit_u24 = lt_emit_u24; lt->lt_emit_u32 = lt_emit_u32; lt->lt_emit_u64 = lt_emit_u64; lt->lt_emit_double = lt_emit_double; lt->lt_emit_string = lt_emit_string; break; case LT_ZMODE_GZIP: lt->lt_emit_u8 = lt_emit_u8z; lt->lt_emit_u16 = lt_emit_u16z; lt->lt_emit_u24 = lt_emit_u24z; lt->lt_emit_u32 = lt_emit_u32z; lt->lt_emit_u64 = lt_emit_u64z; lt->lt_emit_double = lt_emit_doublez; lt->lt_emit_string = lt_emit_stringz; break; case LT_ZMODE_BZIP2: lt->lt_emit_u8 = lt_emit_u8bz; lt->lt_emit_u16 = lt_emit_u16bz; lt->lt_emit_u24 = lt_emit_u24bz; lt->lt_emit_u32 = lt_emit_u32bz; lt->lt_emit_u64 = lt_emit_u64bz; lt->lt_emit_double = lt_emit_doublebz; lt->lt_emit_string = lt_emit_stringbz; break; } } /* * hash/symtable manipulation */ static int lt_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%LT_SYMPRIME); } static struct lt_symbol *lt_symadd(struct lt_trace *lt, const char *name, int hv) { struct lt_symbol *s; s=(struct lt_symbol *)calloc(1,sizeof(struct lt_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct lt_symbol *lt_symfind(struct lt_trace *lt, const char *s) { int hv; struct lt_symbol *temp; hv=lt_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void lt_compress_fac(struct lt_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } lt_emit_u16z(lt, i); lt_emit_stringz(lt, str+i); free(lt->compress_fac_str); } else { lt_emit_u16z(lt, 0); lt_emit_stringz(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } static void strip_brack(struct lt_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='.') { return; /* MTI SV [0.3] notation for implicit vars */ } if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void lt_emitfacs(struct lt_trace *lt) { int i; if((lt)&&(lt->numfacs)) { struct lt_symbol *s = lt->symchain; char is_interlaced_trace = (lt->sorted_facs==NULL); if(!lt->sorted_facs) { if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *)))) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing*/ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } } } if(lt->sorted_facs) { lt->facname_offset=lt->position; lt_emit_u32(lt, lt->numfacs); /* uncompressed */ lt_emit_u32(lt, lt->numfacbytes); /* uncompressed */ fflush(lt->handle); lt->zfacname_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->zpackcount = 0; for(i=0;inumfacs;i++) { lt_compress_fac(lt, lt->sorted_facs[i]->name); } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->zfacname_predec_size = lt->zpackcount; gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacname_size = lt->position - lt->zfacname_size; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags<_SYM_F_ALIAS)==0) { lt_emit_u32z(lt, lt->sorted_facs[i]->rows); lt_emit_u32z(lt, lt->sorted_facs[i]->msb); lt_emit_u32z(lt, lt->sorted_facs[i]->lsb); lt_emit_u32z(lt, lt->sorted_facs[i]->flags); } else { lt_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum); lt_emit_u32z(lt, lt->sorted_facs[i]->msb); lt_emit_u32z(lt, lt->sorted_facs[i]->lsb); lt_emit_u32z(lt, LT_SYM_F_ALIAS); } } gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; if(is_interlaced_trace) { lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->sync_table_offset = lt->position; for(i=0;inumfacs;i++) { lt_emit_u32z(lt, lt->sorted_facs[i]->last_change); } gzclose(lt->zhandle); lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zsync_table_size = lt->position - lt->sync_table_offset; } } } } /* * initialize the trace and get back an lt context */ struct lt_trace *lt_init(const char *name) { struct lt_trace *lt=(struct lt_trace *)calloc(1, sizeof(struct lt_trace)); if(!(lt->handle=fopen(name, "wb"))) { free(lt); lt=NULL; } else { lt_emit_u16(lt, LT_HDRID); lt_emit_u16(lt, LT_VERSION); lt->change_field_offset = lt->position; lt->initial_value = -1; /* if a user sets this it will have a different POSITIVE val */ lt->timescale = -256; /* will be in range of -128<=x<=127 if set */ lt_set_zmode(lt, LT_ZMODE_NONE); lt->mintime=ULLDescriptor(1); lt->maxtime=ULLDescriptor(0); } return(lt); } /* * clock flushing.. */ static void lt_flushclock(struct lt_trace *lt, struct lt_symbol *s) { unsigned int last_change_delta = lt->position - s->last_change - 2; unsigned int start_position = lt->position; int tag; int numbytes, numbytes_trans; int numtrans = s->clk_numtrans - LT_CLKPACK - 1; if(numtrans<0) { /* it never got around to caching */ fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans); return; } if(numtrans >= 256*65536) { numbytes_trans = 3; } else if(numtrans >= 65536) { numbytes_trans = 2; } else if(numtrans >= 256) { numbytes_trans = 1; } else { numbytes_trans = 0; } if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */ lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { tag = 0xC + numbytes_trans; /* yields C..F */ switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, tag); } s->last_change = start_position; /* s->clk_prevval CAN BE INFERRED! */ /* s->clk_prevtrans CAN BE INFERRED! */ /* s->clk_delta CAN BE INFERRED! */ switch(numbytes_trans&3) { case 0: lt->lt_emit_u8(lt, numtrans); break; case 1: lt->lt_emit_u16(lt, numtrans); break; case 2: lt->lt_emit_u24(lt, numtrans); break; case 3: lt->lt_emit_u32(lt, numtrans); break; } /* printf("Clock finish for '%s' at %lld ending with '%c' for %d repeats over a switch delta of %d\n", s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK, s->clk_delta); */ s->clk_prevtrans = ULLDescriptor(~0); s->clk_numtrans = 0; } static void lt_flushclock_m(struct lt_trace *lt, struct lt_symbol *s) { unsigned int last_change_delta = lt->position - s->last_change - 2; unsigned int start_position = lt->position; int tag; int numbytes, numbytes_trans; int numtrans = s->clk_numtrans - LT_CLKPACK_M - 1; if(numtrans<0) { /* it never got around to caching */ fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans); return; } if(numtrans >= 256*65536) { numbytes_trans = 3; } else if(numtrans >= 65536) { numbytes_trans = 2; } else if(numtrans >= 256) { numbytes_trans = 1; } else { numbytes_trans = 0; } if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */ lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { tag = 0xC + numbytes_trans; /* yields C..F */ switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, tag); } s->last_change = start_position; /* s->clk_prevval CAN BE INFERRED! */ /* s->clk_prevtrans CAN BE INFERRED! */ /* s->clk_delta CAN BE INFERRED! */ switch(numbytes_trans&3) { case 0: lt->lt_emit_u8(lt, numtrans); break; case 1: lt->lt_emit_u16(lt, numtrans); break; case 2: lt->lt_emit_u24(lt, numtrans); break; case 3: lt->lt_emit_u32(lt, numtrans); break; } /* printf("Clock finish for '%s' at %lld ending with '%08x' for %d repeats over a switch delta of %lld\n", s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK_M, s->clk_delta); */ s->clk_prevtrans = ULLDescriptor(~0); s->clk_numtrans = 0; } /* * recurse through dictionary */ static void lt_recurse_dictionary(struct lt_trace *lt, dslxt_Tree *ds) { if(ds->left) lt_recurse_dictionary(lt, ds->left); lt->sorted_dict[ds->val] = ds; if(ds->right) lt_recurse_dictionary(lt, ds->right); } static void lt_recurse_dictionary_free(struct lt_trace *lt, dslxt_Tree *ds) { dslxt_Tree *lft = ds->left; dslxt_Tree *rgh = ds->right; if(lft) lt_recurse_dictionary_free(lt, lft); free(ds->item); free(ds); if(rgh) lt_recurse_dictionary_free(lt, rgh); } static int lt_dictval_compare(const void *v1, const void *v2) { const dslxt_Tree *s1 = *(const dslxt_Tree * const *)v1; const dslxt_Tree *s2 = *(const dslxt_Tree * const *)v2; if(s1->val > s2->val) return(1); else return(-1); /* they're *never* equal */ } static void lt_finalize_dictionary(struct lt_trace *lt) { unsigned int i; lt->sorted_dict = calloc(lt->num_dict_entries, sizeof(dslxt_Tree *)); lt->dictionary_offset=lt->position; lt_emit_u32(lt, lt->num_dict_entries); /* uncompressed */ lt_emit_u32(lt, lt->dict_string_mem_required - lt->num_dict_entries); /* uncompressed : minus because leading '1' is implied so its stripped */ lt_emit_u32(lt, lt->dict16_offset); /* uncompressed */ lt_emit_u32(lt, lt->dict24_offset); /* uncompressed */ lt_emit_u32(lt, lt->dict32_offset); /* uncompressed */ lt_emit_u32(lt, lt->mindictwidth); /* uncompressed */ fflush(lt->handle); #if 0 fprintf(stderr, "*** dictionary_offset = %08x\n", lt->dictionary_offset); fprintf(stderr, "*** num_dict_entries = %d\n", lt->num_dict_entries); #endif lt->zdictionary_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt_recurse_dictionary(lt, lt->dict); qsort((void *)lt->sorted_dict, lt->num_dict_entries, sizeof(struct dsTree **), lt_dictval_compare); for(i=0;inum_dict_entries;i++) { dslxt_Tree *ds = lt->sorted_dict[i]; /* fprintf(stderr, "%8d) '%s'\n", ds->val, ds->item); */ lt_emit_stringz(lt, ds->item+1); } gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zdictionary_size = lt->position - lt->zdictionary_size; free(lt->sorted_dict); lt->sorted_dict = NULL; lt_recurse_dictionary_free(lt, lt->dict); lt->dict = NULL; } /* * close out the trace and fixate it */ void lt_close(struct lt_trace *lt) { lxttime_t lasttime=ULLDescriptor(0); int lastposition=0; char is64=0; if(lt) { struct lt_symbol *s = lt->symchain; if(lt->clock_compress) while(s) { if(s->clk_prevtrans!=ULLDescriptor(~0)) { int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if(len>1) { if(s->clk_numtrans > LT_CLKPACK_M) lt_flushclock_m(lt, s); } else { if(s->clk_numtrans > LT_CLKPACK) lt_flushclock(lt, s); } } s=s->symchain; } lt_set_dumpon(lt); /* in case it was turned off */ if(lt->zmode!=LT_ZMODE_NONE) { lt->chg_table_size = lt->position - lt->change_field_offset; switch(lt->zmode) { case LT_ZMODE_GZIP: gzclose(lt->zhandle); break; case LT_ZMODE_BZIP2: BZ2_bzclose(lt->zhandle); break; } lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt_set_zmode(lt, LT_ZMODE_NONE); lt->zchg_table_size = lt->position - lt->change_field_offset; } lt_emitfacs(lt); if(lt->dict) lt_finalize_dictionary(lt); free(lt->timebuff); lt->timebuff=NULL; if(lt->timehead) { struct lt_timetrail *t=lt->timehead; struct lt_timetrail *t2; lt->time_table_offset = lt->position; lt_emit_u32(lt, lt->timechangecount); /* this is uncompressed! */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->ztime_table_size = lt->position; is64=(lt->maxtime > ULLDescriptor(0xFFFFFFFF)); if(is64) { lt_emit_u64z(lt, (int)((lt->mintime)>>32), (int)lt->mintime); lt_emit_u64z(lt, (int)((lt->maxtime)>>32), (int)lt->maxtime); } else { lt_emit_u32z(lt, (int)lt->mintime); lt_emit_u32z(lt, (int)lt->maxtime); } while(t) { lt_emit_u32z(lt, t->position - lastposition); lastposition = t->position; t=t->next; } t=lt->timehead; if(is64) { while(t) { lxttime_t delta = t->timeval - lasttime; lt_emit_u64z(lt, (int)(delta>>32), (int)delta); lasttime = t->timeval; t2=t->next; free(t); t=t2; } } else { while(t) { lt_emit_u32z(lt, (int)(t->timeval - lasttime)); lasttime = t->timeval; t2=t->next; free(t); t=t2; } lt->timehead = lt->timecurr = NULL; } gzclose(lt->zhandle); lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->ztime_table_size = lt->position - lt->ztime_table_size; } if(lt->initial_value>=0) { lt->initial_value_offset = lt->position; lt_emit_u8(lt, lt->initial_value); } if((lt->timescale>-129)&&(lt->timescale<128)) { lt->timescale_offset = lt->position; lt_emit_u8(lt, lt->timescale); } if(lt->double_used) { lt->double_test_offset = lt->position; lt_emit_double(lt, 3.14159); } if(lt->dumpoffcount) { struct lt_timetrail *ltt = lt->dumpoffhead; struct lt_timetrail *ltt2; lt->exclude_offset = lt->position; lt_emit_u32(lt, lt->dumpoffcount); while(ltt) { lt_emit_u64(lt, (int)((ltt->timeval)>>32), (int)ltt->timeval); ltt2 = ltt; ltt=ltt->next; free(ltt2); } lt->dumpoffhead = lt->dumpoffcurr = NULL; lt->dumpoffcount = 0; } if(lt->timezero) { lt->timezero_offset = lt->position; lt_emit_u64(lt, (int)((lt->timezero)>>32), (int)lt->timezero); } /* prefix */ lt_emit_u8(lt, LT_SECTION_END); /* Version 1 */ if(lt->change_field_offset) { lt_emit_u32(lt, lt->change_field_offset); lt_emit_u8(lt, LT_SECTION_CHG); lt->change_field_offset = 0; } if(lt->sync_table_offset) { lt_emit_u32(lt, lt->sync_table_offset); lt_emit_u8(lt, LT_SECTION_SYNC_TABLE); lt->sync_table_offset = 0; } if(lt->facname_offset) { lt_emit_u32(lt, lt->facname_offset); lt_emit_u8(lt, LT_SECTION_FACNAME); lt->facname_offset = 0; } if(lt->facgeometry_offset) { lt_emit_u32(lt, lt->facgeometry_offset); lt_emit_u8(lt, LT_SECTION_FACNAME_GEOMETRY); lt->facgeometry_offset = 0; } if(lt->timescale_offset) { lt_emit_u32(lt, lt->timescale_offset); lt_emit_u8(lt, LT_SECTION_TIMESCALE); lt->timescale_offset = 0; } if(lt->time_table_offset) { lt_emit_u32(lt, lt->time_table_offset); lt_emit_u8(lt, is64 ? LT_SECTION_TIME_TABLE64 : LT_SECTION_TIME_TABLE); lt->time_table_offset = 0; } if(lt->initial_value_offset) { lt_emit_u32(lt, lt->initial_value_offset); lt_emit_u8(lt, LT_SECTION_INITIAL_VALUE); lt->initial_value_offset = 0; } if(lt->double_test_offset) { lt_emit_u32(lt, lt->double_test_offset); lt_emit_u8(lt, LT_SECTION_DOUBLE_TEST); lt->double_test_offset = 0; } /* Version 2 adds */ if(lt->zfacname_predec_size) { lt_emit_u32(lt, lt->zfacname_predec_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_PREDEC_SIZE); lt->zfacname_predec_size = 0; } if(lt->zfacname_size) { lt_emit_u32(lt, lt->zfacname_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_SIZE); lt->zfacname_size = 0; } if(lt->zfacgeometry_size) { lt_emit_u32(lt, lt->zfacgeometry_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_GEOMETRY_SIZE); lt->zfacgeometry_size = 0; } if(lt->zsync_table_size) { lt_emit_u32(lt, lt->zsync_table_size); lt_emit_u8(lt, LT_SECTION_ZSYNC_SIZE); lt->zsync_table_size = 0; } if(lt->ztime_table_size) { lt_emit_u32(lt, lt->ztime_table_size); lt_emit_u8(lt, LT_SECTION_ZTIME_TABLE_SIZE); lt->ztime_table_size = 0; } if(lt->chg_table_size) { lt_emit_u32(lt, lt->chg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_PREDEC_SIZE); lt->chg_table_size = 0; } if(lt->zchg_table_size) { lt_emit_u32(lt, lt->zchg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_SIZE); lt->zchg_table_size = 0; } /* Version 4 adds */ if(lt->dictionary_offset) { lt_emit_u32(lt, lt->dictionary_offset); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY); lt->dictionary_offset = 0; } if(lt->zdictionary_size) { lt_emit_u32(lt, lt->zdictionary_size); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY_SIZE); lt->zdictionary_size = 0; } /* Version 5 adds */ if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; } /* Version 6 adds */ if(lt->timezero_offset) { lt_emit_u32(lt, lt->timezero_offset); lt_emit_u8(lt, LT_SECTION_TIMEZERO); lt->timezero_offset = 0; } /* suffix */ lt_emit_u8(lt, LT_TRLID); if(lt->symchain) { struct lt_symbol *sc = lt->symchain; struct lt_symbol *s2; while(sc) { free(sc->name); s2=sc->symchain; free(sc); sc=s2; } } free(lt->sorted_facs); fclose(lt->handle); free(lt); } } /* * maint function for finding a symbol if it exists */ struct lt_symbol *lt_symbol_find(struct lt_trace *lt, const char *name) { struct lt_symbol *s=NULL; if((lt)&&(name)) s=lt_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct lt_symbol *lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct lt_symbol *s; int len; int flagcnt; if((!lt)||(lt->sorted_facs)) return(NULL); flagcnt = ((flags<_SYM_F_INTEGER)!=0) + ((flags<_SYM_F_DOUBLE)!=0) + ((flags<_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(lt_symfind(lt, name))) return (NULL); if(flags<_SYM_F_DOUBLE) lt->double_used = 1; s=lt_symadd(lt, name, lt_hash(name)); s->rows = rows; s->flags = flags&(~LT_SYM_F_ALIAS); /* aliasing makes no sense here.. */ if(!flagcnt) { s->msb = msb; s->lsb = lsb; s->len = (msblen==1)&&(s->rows==0)) s->clk_prevtrans = ULLDescriptor(~0); } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct lt_symbol *lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct lt_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=lt_symfind(lt, existing_name)))||(lt_symfind(lt, alias))) return (NULL); if(lt->sorted_facs) return(NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags<_SYM_F_INTEGER)!=0) + ((s->flags<_SYM_F_DOUBLE)!=0) + ((s->flags<_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=lt_symadd(lt, alias, lt_hash(alias)); sa->flags = LT_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time */ int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval) { return(lt_set_time64(lt, lt->maxtime + (lxttime_t)timeval)); } int lt_set_time(struct lt_trace *lt, unsigned int timeval) { return(lt_set_time64(lt, (lxttime_t)timeval)); } int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval) { return(lt_set_time64(lt, lt->maxtime + timeval)); } int lt_set_time64(struct lt_trace *lt, lxttime_t timeval) { int rc=0; if(lt) { struct lt_timetrail *trl=(struct lt_timetrail *)calloc(1, sizeof(struct lt_timetrail)); if(trl) { trl->timeval = timeval; trl->position = lt->position; if((lt->timecurr)||(lt->timebuff)) { if(((timeval>lt->mintime)&&(timeval>lt->maxtime))||((lt->mintime==ULLDescriptor(1))&&(lt->maxtime==ULLDescriptor(0)))) { lt->maxtime = timeval; } else { free(trl); goto bail; } } else { lt->mintime = lt->maxtime = timeval; } free(lt->timebuff); lt->timebuff = trl; lt->timeval = timeval; rc=1; } } bail: return(rc); } /* * sets trace timescale as 10**x seconds */ void lt_set_timescale(struct lt_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * sets clock compression heuristic */ void lt_set_clock_compress(struct lt_trace *lt) { if(lt) { lt->clock_compress = 1; } } /* * sets change dump compression */ void lt_set_chg_compress(struct lt_trace *lt) { if(lt) { if((lt->zmode==LT_ZMODE_NONE)&&(!lt->emitted)) { lt_set_zmode(lt, lt->zmode = LT_ZMODE_GZIP); fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); } } } /* * sets change dictionary compression */ void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth) { if((lt)&&(!lt->emitted)) { lt->dictmode = 1; if(minwidth>1) { lt->mindictwidth = minwidth; } } } /* * sets change interlace */ void lt_set_no_interlace(struct lt_trace *lt) { if((lt)&&(!lt->emitted)&&(!lt->sorted_facs)) { if(lt->zmode==LT_ZMODE_NONE) /* this mode implies BZIP2 compression! */ { lt_set_zmode(lt, lt->zmode = LT_ZMODE_BZIP2); fflush(lt->handle); lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "wb9"); } if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *)))) { struct lt_symbol *s = lt->symchain; int i; if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } if(lt->numfacs >= 256*65536) { lt->numfacs_bytes = 4; } else if(lt->numfacs >= 65536) { lt->numfacs_bytes = 3; } else if(lt->numfacs >= 256) { lt->numfacs_bytes = 2; } else { lt->numfacs_bytes = 1; } } } } /* * sets trace initial value */ void lt_set_initial_value(struct lt_trace *lt, char value) { if(lt) { int tag; switch(value) { case '0': tag = 0; break; case '1': tag = 1; break; case 'Z': case 'z': tag = 2; break; case 'X': case 'x': tag = 3; break; case 'H': case 'h': tag = 4; break; case 'U': case 'u': tag = 5; break; case 'W': case 'w': tag = 6; break; case 'L': case 'l': tag = 0x7; break; case '-': tag = 0x8; break; default: tag = -1; break; } lt->initial_value = tag; } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } /* * emission for trace values.. */ static int lt_optimask[]= { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; static char *lt_expand_integer_to_bits(int len, int value) { static char s[33]; char *p = s; int i; len--; for(i=0;i<=len;i++) { *(p++) = '0' | ((value & (1<<(len-i)))!=0); } *p = 0; return(s); } int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(!s)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; unsigned int last_change_delta; if((lt->clock_compress)&&(s->rows==0)) { if((len>1)&&(len<=32)) { int ivalue = value; int delta1, delta2; s->clk_mask <<= 1; s->clk_mask |= 1; if( ((s->clk_mask&0x1f)==0x1f) && ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) && ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) && ( (delta1==delta2) || ((!delta1)&&(!delta2)) ) ) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK_M) { s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; /* printf("Clock value '%08x' for '%s' at %lld (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; } else if(len==1) /* possible clock handling */ { int ivalue = value&1; if(((s->clk_prevval == '1') && (ivalue==0)) || ((s->clk_prevval == '0') && (ivalue==1))) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = ivalue + '0'; /* printf("Clock value '%d' for '%s' at %d (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval = ivalue + '0'; } } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } if(len<=32) { int start_position = lt->position; int tag; int optimized0 = ((value<_optimask[len])==0); int optimized1 = ((value<_optimask[len])==lt_optimask[len]); int optimized = optimized0|optimized1; if(!lt->numfacs_bytes) { if(optimized) { tag = (numbytes<<4) | (3+optimized1); /* for x3 and x4 cases */ } else { tag = (numbytes<<4); } lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, optimized ? (3+optimized1) : 0); } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } if(!optimized) { if((lt->dictmode)&&(len>lt->mindictwidth)) { char *vpnt_orig = lt_expand_integer_to_bits(len, value); char *vpnt = vpnt_orig; while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++; lt->dict = dslxt_splay (vpnt, lt->dict); if(!dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(!lt->dict16_offset) { if(lt->num_dict_entries==256) lt->dict16_offset = lt->position; } else if(!lt->dict24_offset) { if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position; } else if(!lt->dict32_offset) { if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position; } lt->num_dict_entries++; } if(lt->dict24_offset) { if(lt->dict32_offset) { lt->lt_emit_u32(lt, lt->dict->val); } else { lt->lt_emit_u24(lt, lt->dict->val); } } else { if(lt->dict16_offset) { lt->lt_emit_u16(lt, lt->dict->val); } else { lt->lt_emit_u8(lt, lt->dict->val); } } } else if(len<9) { value <<= (8-len); rc=lt->lt_emit_u8(lt, value); } else if(len<17) { value <<= (16-len); rc=lt->lt_emit_u16(lt, value); } else if(len<25) { value <<= (24-len); rc=lt->lt_emit_u24(lt, value); } else { value <<= (32-len); rc=lt->lt_emit_u32(lt, value); } } } if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value) { int rc=0; int start_position; int tag; if((!lt)||(!s)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_DOUBLE) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; s->last_change = start_position; tag = (numbytes<<4); lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } } if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } rc=lt->lt_emit_double(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag; if((!lt)||(!s)||(!value)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_STRING) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; s->last_change = start_position; tag = (numbytes<<4); lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } } if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } rc=lt->lt_emit_string(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag, tagadd; if((!lt)||(!s)||(!value)||(!*value)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ char *pnt; int mvl=0; char ch; char prevch; unsigned int last_change_delta; unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if((lt->clock_compress)&&(s->rows==0)) { if((len>1)&&(len<=32)) { int legal = 0; int ivalue = 0; unsigned int i; char *pntv = value; int delta1, delta2; for(i=0;i0)) { pntv--; } else { legal = 0; break; } } ivalue = (((unsigned int)ivalue) << 1); ivalue |= (*pntv & 1); legal = 1; pntv++; } s->clk_mask <<= 1; s->clk_mask |= legal; if( ((s->clk_mask&0x1f)==0x1f) && ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) && ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) && ( (delta1==delta2) || ((!delta1)&&(!delta2)) ) ) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK_M) { s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; /* printf("Clock value '%08x' for '%s' [len=%d] at %lld (#%d)\n", ivalue, s->name, len, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; } else if(len==1) /* possible clock handling */ { if(((s->clk_prevval == '1') && (value[0]=='0')) || ((s->clk_prevval == '0') && (value[0]=='1'))) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = value[0]; /* printf("Clock value '%c' for '%s' at %lld (#%d)\n", value[0], s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval = value[0]; } } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } pnt = value; prevch = *pnt; while((ch=*(pnt++))) { switch(ch) { case '0': case '1': mvl|=LT_MVL_2; break; case 'Z': case 'z': case 'X': case 'x': mvl|=LT_MVL_4; break; default: mvl|=LT_MVL_9; break; } if(prevch!=ch) prevch = 0; } switch(prevch) { case 0x00: tagadd = 0; break; case '0': tagadd = 3; break; case '1': tagadd = 4; break; case 'Z': case 'z': tagadd = 5; break; case 'X': case 'x': tagadd = 6; break; case 'H': case 'h': tagadd = 7; break; case 'U': case 'u': tagadd = 8; break; case 'W': case 'w': tagadd = 9; break; case 'L': case 'l': tagadd = 0xa; break; default: tagadd = 0xb; break; } if(mvl) { start_position = lt->position; if(!lt->numfacs_bytes) { if(tagadd) { tag = (numbytes<<4) + tagadd; } else { tag = (numbytes<<4) + ((mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0)); } lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } if(tagadd) { lt->lt_emit_u8(lt, tagadd); } else { lt->lt_emit_u8(lt, (mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0) ); } } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } if(!tagadd) { unsigned int len2 = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if((mvl & (LT_MVL_2|LT_MVL_4|LT_MVL_9)) == LT_MVL_2) { unsigned int i; int bitpos = 7; int outval = 0; int thisval= 0; pnt = value; if((lt->dictmode)&&(len2>lt->mindictwidth)) { char *vpnt = value; while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++; lt->dict = dslxt_splay (vpnt, lt->dict); if(!dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(!lt->dict16_offset) { if(lt->num_dict_entries==256) lt->dict16_offset = lt->position; } else if(!lt->dict24_offset) { if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position; } else if(!lt->dict32_offset) { if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position; } lt->num_dict_entries++; } if(lt->dict24_offset) { if(lt->dict32_offset) { lt->lt_emit_u32(lt, lt->dict->val); } else { lt->lt_emit_u24(lt, lt->dict->val); } } else { if(lt->dict16_offset) { lt->lt_emit_u16(lt, lt->dict->val); } else { lt->lt_emit_u8(lt, lt->dict->val); } } } else for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 7; } } } else if((mvl & (LT_MVL_4|LT_MVL_9)) == LT_MVL_4) { unsigned int i; int bitpos = 6; int outval = 0; int thisval= 0; pnt = value; for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 6; } } } else /* if(mvl & LT_MVL_9) */ { unsigned int i; int bitpos = 4; int outval = 0; int thisval= 0; pnt = value; for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 4; } } } } rc=1; } if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } /* * blackout functions */ void lt_set_dumpoff(struct lt_trace *lt) { if((lt)&&(!lt->dumpoff_active)) { struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail)); ltt->timeval = lt->timeval; if(lt->dumpoffhead) { lt->dumpoffcurr->next = ltt; lt->dumpoffcurr = ltt; } else { lt->dumpoffhead = lt->dumpoffcurr = ltt; } lt->dumpoff_active = 1; lt->dumpoffcount++; } } void lt_set_dumpon(struct lt_trace *lt) { if((lt)&&(lt->dumpoff_active)) { struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail)); ltt->timeval = lt->timeval; lt->dumpoffcurr->next = ltt; lt->dumpoffcurr = ltt; lt->dumpoff_active = 0; } } void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval) { if(lt) { lt->timezero = timeval; } } iverilog-12_0/vpi/lxt_write.h000066400000000000000000000201441435245347300163400ustar00rootroot00000000000000/* * Copyright (c) 2001-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXT_H #define DEFS_LXT_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif typedef struct dslxt_tree_node dslxt_Tree; struct dslxt_tree_node { dslxt_Tree * left, * right; char *item; unsigned int val; }; #define LT_HDRID (0x0138) #define LT_VERSION (0x0004) #define LT_TRLID (0xB4) #define LT_CLKPACK (4) #define LT_CLKPACK_M (2) #define LT_MVL_2 (1<<0) #define LT_MVL_4 (1<<1) #define LT_MVL_9 (1<<2) #define LT_MINDICTWIDTH (16) enum lt_zmode_types { LT_ZMODE_NONE, LT_ZMODE_GZIP, LT_ZMODE_BZIP2 }; #ifndef _MSC_VER typedef uint64_t lxttime_t; #define ULLDescriptor(x) x##ULL typedef int64_t lxtotime_t; #else typedef unsigned __int64 lxttime_t; #define ULLDescriptor(x) x##i64 typedef __int64 lxtotime_t; #endif struct lt_timetrail { struct lt_timetrail *next; lxttime_t timeval; unsigned int position; }; #define LT_SYMPRIME 500009 #define LT_SECTION_END (0) #define LT_SECTION_CHG (1) #define LT_SECTION_SYNC_TABLE (2) #define LT_SECTION_FACNAME (3) #define LT_SECTION_FACNAME_GEOMETRY (4) #define LT_SECTION_TIMESCALE (5) #define LT_SECTION_TIME_TABLE (6) #define LT_SECTION_INITIAL_VALUE (7) #define LT_SECTION_DOUBLE_TEST (8) #define LT_SECTION_TIME_TABLE64 (9) #define LT_SECTION_ZFACNAME_PREDEC_SIZE (10) #define LT_SECTION_ZFACNAME_SIZE (11) #define LT_SECTION_ZFACNAME_GEOMETRY_SIZE (12) #define LT_SECTION_ZSYNC_SIZE (13) #define LT_SECTION_ZTIME_TABLE_SIZE (14) #define LT_SECTION_ZCHG_PREDEC_SIZE (15) #define LT_SECTION_ZCHG_SIZE (16) #define LT_SECTION_ZDICTIONARY (17) #define LT_SECTION_ZDICTIONARY_SIZE (18) #define LT_SECTION_EXCLUDE_TABLE (19) #define LT_SECTION_TIMEZERO (20) struct lt_trace { FILE *handle; gzFile zhandle; dslxt_Tree *dict; /* dictionary manipulation */ unsigned int mindictwidth; unsigned int num_dict_entries; unsigned int dict_string_mem_required; dslxt_Tree **sorted_dict; /* assume dict8_offset == filepos zero */ unsigned int dict16_offset; unsigned int dict24_offset; unsigned int dict32_offset; int (*lt_emit_u8)(struct lt_trace *lt, int value); int (*lt_emit_u16)(struct lt_trace *lt, int value); int (*lt_emit_u24)(struct lt_trace *lt, int value); int (*lt_emit_u32)(struct lt_trace *lt, int value); int (*lt_emit_u64)(struct lt_trace *lt, int valueh, int valuel); int (*lt_emit_double)(struct lt_trace *lt, double value); int (*lt_emit_string)(struct lt_trace *lt, char *value); unsigned int position; unsigned int zfacname_predec_size, zfacname_size, zfacgeometry_size, zsync_table_size, ztime_table_size, zdictionary_size; unsigned int zpackcount, zchg_table_size, chg_table_size; struct lt_symbol *sym[LT_SYMPRIME]; struct lt_symbol **sorted_facs; struct lt_symbol *symchain; int numfacs, numfacs_bytes; int numfacbytes; int longestname; lxttime_t mintime, maxtime; int timescale; int initial_value; struct lt_timetrail *timehead, *timecurr, *timebuff; int timechangecount; struct lt_timetrail *dumpoffhead, *dumpoffcurr; int dumpoffcount; unsigned int change_field_offset; unsigned int facname_offset; unsigned int facgeometry_offset; unsigned int time_table_offset; unsigned int sync_table_offset; unsigned int initial_value_offset; unsigned int timescale_offset; unsigned int double_test_offset; unsigned int dictionary_offset; unsigned int exclude_offset; unsigned int timezero_offset; char *compress_fac_str; int compress_fac_len; lxttime_t timeval; /* for clock induction, current time */ lxtotime_t timezero; /* for allowing negative values */ unsigned dumpoff_active : 1; /* when set we're not dumping */ unsigned double_used : 1; unsigned do_strip_brackets : 1; unsigned clock_compress : 1; unsigned dictmode : 1; /* dictionary compression enabled */ unsigned zmode : 2; /* for value changes */ unsigned emitted : 1; /* gate off change field zmode changes when set */ }; struct lt_symbol { struct lt_symbol *next; struct lt_symbol *symchain; char *name; int namlen; int facnum; struct lt_symbol *aliased_to; unsigned int rows; int msb, lsb; int len; int flags; unsigned int last_change; lxttime_t clk_delta; lxttime_t clk_prevtrans; int clk_numtrans; int clk_prevval; int clk_prevval1; int clk_prevval2; int clk_prevval3; int clk_prevval4; unsigned char clk_mask; }; #define LT_SYM_F_BITS (0) #define LT_SYM_F_INTEGER (1<<0) #define LT_SYM_F_DOUBLE (1<<1) #define LT_SYM_F_STRING (1<<2) #define LT_SYM_F_ALIAS (1<<3) struct lt_trace * lt_init(const char *name); void lt_close(struct lt_trace *lt); struct lt_symbol * lt_symbol_find(struct lt_trace *lt, const char *name); struct lt_symbol * lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct lt_symbol * lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit); /* lt_set_no_interlace implies bzip2 compression. if you use lt_set_chg_compress before this, */ /* less efficient gzip compression will be used instead so make sure lt_set_no_interlace is first */ /* if you are using it! */ void lt_set_no_interlace(struct lt_trace *lt); void lt_set_chg_compress(struct lt_trace *lt); void lt_set_clock_compress(struct lt_trace *lt); void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth); void lt_set_initial_value(struct lt_trace *lt, char value); void lt_set_timescale(struct lt_trace *lt, int timescale); void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval); int lt_set_time(struct lt_trace *lt, unsigned int timeval); int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval); int lt_set_time64(struct lt_trace *lt, lxttime_t timeval); int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval); /* allows blackout regions in LXT files */ void lt_set_dumpoff(struct lt_trace *lt); void lt_set_dumpon(struct lt_trace *lt); /* * value change functions..note that if the value string len for * lt_emit_value_bit_string() is shorter than the symbol length * it will be left justified with the rightmost character used as * a repeat value that will be propagated to pad the value string out: * * "10x" for 8 bits becomes "10xxxxxx" * "z" for 8 bits becomes "zzzzzzzz" */ int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value); int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value); int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); #ifdef __cplusplus } #endif #endif iverilog-12_0/vpi/lz4.c000066400000000000000000001532541435245347300150340ustar00rootroot00000000000000/* LZ4 - Fast LZ compression algorithm Copyright (C) 2011-2015, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SPDX-License-Identifier: BSD-2-Clause You can contact the author at : - LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /************************************** * Tuning parameters **************************************/ /* * HEAPMODE : * Select how default compression functions will allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ #define HEAPMODE 0 /* * ACCELERATION_DEFAULT : * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 */ #define ACCELERATION_DEFAULT 1 /************************************** * CPU Feature Detection **************************************/ /* * LZ4_FORCE_SW_BITCOUNT * Define this parameter if your target system or compiler does not support hardware bit count */ #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ # define LZ4_FORCE_SW_BITCOUNT #endif /************************************** * Includes **************************************/ #include "lz4.h" /************************************** * Compiler Options **************************************/ #ifdef _MSC_VER /* Visual Studio */ # define FORCE_INLINE static __forceinline # include # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ #else # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # if defined(__GNUC__) || defined(__clang__) # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif # else # define FORCE_INLINE static # endif /* __STDC_VERSION__ */ #endif /* _MSC_VER */ /* LZ4_GCC_VERSION is defined into lz4.h */ #if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) #endif #define likely(expr) expect((expr) != 0, 1) #define unlikely(expr) expect((expr) != 0, 0) /************************************** * Memory routines **************************************/ #include /* malloc, calloc, free */ #define ALLOCATOR(n,s) calloc(n,s) #define FREEMEM free #include /* memset, memcpy */ #define MEM_INIT memset /************************************** * Basic Types **************************************/ #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif /************************************** * Reading and writing into memory **************************************/ #define STEPSIZE sizeof(size_t) static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } static unsigned LZ4_isLittleEndian(void) { const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } static U16 LZ4_read16(const void* memPtr) { U16 val16; memcpy(&val16, memPtr, 2); return val16; } static U16 LZ4_readLE16(const void* memPtr) { if (LZ4_isLittleEndian()) { return LZ4_read16(memPtr); } else { const BYTE* p = (const BYTE*)memPtr; return (U16)((U16)p[0] + (p[1]<<8)); } } static void LZ4_writeLE16(void* memPtr, U16 value) { if (LZ4_isLittleEndian()) { memcpy(memPtr, &value, 2); } else { BYTE* p = (BYTE*)memPtr; p[0] = (BYTE) value; p[1] = (BYTE)(value>>8); } } static U32 LZ4_read32(const void* memPtr) { U32 val32; memcpy(&val32, memPtr, 4); return val32; } static U64 LZ4_read64(const void* memPtr) { U64 val64; memcpy(&val64, memPtr, 8); return val64; } static size_t LZ4_read_ARCH(const void* p) { if (LZ4_64bits()) return (size_t)LZ4_read64(p); else return (size_t)LZ4_read32(p); } static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); } static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); } /* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = (BYTE*)dstPtr; const BYTE* s = (const BYTE*)srcPtr; BYTE* e = (BYTE*)dstEnd; do { LZ4_copy8(d,s); d+=8; s+=8; } while (d>3); # elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll((U64)val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; # endif } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, (U32)val ); return (int)(r>>3); # elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz((U32)val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif } } else /* Big Endian CPU */ { if (LZ4_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); return (unsigned)(r>>3); # elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll((U64)val) >> 3); # else unsigned r; if (!(val>>32)) { r=4; } else { r=0; val>>=32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; # endif } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse( &r, (unsigned long)val ); return (unsigned)(r>>3); # elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz((U32)val) >> 3); # else unsigned r; if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } r += (!val); return r; # endif } } } static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) { const BYTE* const pStart = pIn; while (likely(pIn compression run slower on incompressible data */ /************************************** * Local Structures and types **************************************/ typedef struct { U32 hashTable[HASH_SIZE_U32]; U32 currentOffset; U32 initCheck; const BYTE* dictionary; BYTE* bufferStart; /* obsolete, used for slideInputBuffer */ U32 dictSize; } LZ4_stream_t_internal; typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; typedef enum { byPtr, byU32, byU16 } tableType_t; typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; typedef enum { full = 0, partial = 1 } earlyEnd_directive; /************************************** * Local Utils **************************************/ int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } int LZ4_sizeofState() { return LZ4_STREAMSIZE; } /******************************** * Compression functions ********************************/ static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType) { if (tableType == byU16) return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } static const U64 prime5bytes = 889523592379ULL; static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType) { const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; const U32 hashMask = (1<> (40 - hashLog)) & hashMask; } static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType) { if (LZ4_64bits()) return LZ4_hashSequence64(sequence, tableType); return LZ4_hashSequence((U32)sequence, tableType); } static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); } static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) { switch (tableType) { case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } } } static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); } static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ } static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); } FORCE_INLINE int LZ4_compress_generic( void* const ctx, const char* const source, char* const dest, const int inputSize, const int maxOutputSize, const limitedOutput_directive outputLimited, const tableType_t tableType, const dict_directive dict, const dictIssue_directive dictIssue, const U32 acceleration) { LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; const BYTE* ip = (const BYTE*) source; const BYTE* base; const BYTE* lowLimit; const BYTE* const lowRefLimit = ip - dictPtr->dictSize; const BYTE* const dictionary = dictPtr->dictionary; const BYTE* const dictEnd = dictionary + dictPtr->dictSize; const size_t dictDelta = dictEnd - (const BYTE*)source; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = iend - LASTLITERALS; BYTE* op = (BYTE*) dest; BYTE* const olimit = op + maxOutputSize; U32 forwardH; size_t refDelta=0; /* Init conditions */ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ switch(dict) { case noDict: default: base = (const BYTE*)source; lowLimit = (const BYTE*)source; break; case withPrefix64k: base = (const BYTE*)source - dictPtr->currentOffset; lowLimit = (const BYTE*)source - dictPtr->dictSize; break; case usingExtDict: base = (const BYTE*)source - dictPtr->currentOffset; lowLimit = (const BYTE*)source; break; } if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ if (inputSize> LZ4_skipTrigger); if (unlikely(forwardIp > mflimit)) goto _last_literals; match = LZ4_getPositionOnHash(h, ctx, tableType, base); if (dict==usingExtDict) { if (match<(const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; } else { refDelta = 0; lowLimit = (const BYTE*)source; } } forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putPositionOnHash(ip, h, ctx, tableType, base); } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); } /* Catch up */ while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } { /* Encode Literal length */ unsigned litLength = (unsigned)(ip - anchor); token = op++; if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) return 0; /* Check output limit */ if (litLength>=RUN_MASK) { int len = (int)litLength-RUN_MASK; *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } else *token = (BYTE)(litLength< matchlimit) limit = matchlimit; matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); ip += MINMATCH + matchLength; if (ip==limit) { unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); matchLength += more; ip += more; } } else { matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); ip += MINMATCH + matchLength; } if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) return 0; /* Check output limit */ if (matchLength>=ML_MASK) { *token += ML_MASK; matchLength -= ML_MASK; for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } if (matchLength >= 255) { matchLength-=255; *op++ = 255; } *op++ = (BYTE)matchLength; } else *token += (BYTE)(matchLength); } anchor = ip; /* Test end of chunk */ if (ip > mflimit) break; /* Fill table */ LZ4_putPosition(ip-2, ctx, tableType, base); /* Test next position */ match = LZ4_getPosition(ip, ctx, tableType, base); if (dict==usingExtDict) { if (match<(const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; } else { refDelta = 0; lowLimit = (const BYTE*)source; } } LZ4_putPosition(ip, ctx, tableType, base); if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) && (match+MAX_DISTANCE>=ip) && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } /* Prepare next loop */ forwardH = LZ4_hashPosition(++ip, tableType); } _last_literals: /* Encode Last Literals */ { const size_t lastRun = (size_t)(iend - anchor); if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ if (lastRun >= RUN_MASK) { size_t accumulator = lastRun - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; } else { *op++ = (BYTE)(lastRun<= LZ4_compressBound(inputSize)) { if (inputSize < LZ4_64Klimit) return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); else return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); } else { if (inputSize < LZ4_64Klimit) return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); } } int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { #if (HEAPMODE) void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctx; void* ctxPtr = &ctx; #endif int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); #if (HEAPMODE) FREEMEM(ctxPtr); #endif return result; } int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1); } /* hidden debug function */ /* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { LZ4_stream_t ctx; LZ4_resetStream(&ctx); if (inputSize < LZ4_64Klimit) return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); else return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); } /******************************** * destSize variant ********************************/ static int LZ4_compress_destSize_generic( void* const ctx, const char* const src, char* const dst, int* const srcSizePtr, const int targetDstSize, const tableType_t tableType) { const BYTE* ip = (const BYTE*) src; const BYTE* base = (const BYTE*) src; const BYTE* lowLimit = (const BYTE*) src; const BYTE* anchor = ip; const BYTE* const iend = ip + *srcSizePtr; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = iend - LASTLITERALS; BYTE* op = (BYTE*) dst; BYTE* const oend = op + targetDstSize; BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */; BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */); BYTE* const oMaxSeq = oMaxLit - 1 /* token */; U32 forwardH; /* Init conditions */ if (targetDstSize < 1) return 0; /* Impossible to store anything */ if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ if (*srcSizePtr> LZ4_skipTrigger); if (unlikely(forwardIp > mflimit)) goto _last_literals; match = LZ4_getPositionOnHash(h, ctx, tableType, base); forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putPositionOnHash(ip, h, ctx, tableType, base); } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match) != LZ4_read32(ip)) ); } /* Catch up */ while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; } { /* Encode Literal length */ unsigned litLength = (unsigned)(ip - anchor); token = op++; if (op + ((litLength+240)/255) + litLength > oMaxLit) { /* Not enough space for a last match */ op--; goto _last_literals; } if (litLength>=RUN_MASK) { unsigned len = litLength - RUN_MASK; *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } else *token = (BYTE)(litLength< oMaxMatch) { /* Match description too long : reduce it */ matchLength = (15-1) + (oMaxMatch-op) * 255; } /*printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH);*/ ip += MINMATCH + matchLength; if (matchLength>=ML_MASK) { *token += ML_MASK; matchLength -= ML_MASK; while (matchLength >= 255) { matchLength-=255; *op++ = 255; } *op++ = (BYTE)matchLength; } else *token += (BYTE)(matchLength); } anchor = ip; /* Test end of block */ if (ip > mflimit) break; if (op > oMaxSeq) break; /* Fill table */ LZ4_putPosition(ip-2, ctx, tableType, base); /* Test next position */ match = LZ4_getPosition(ip, ctx, tableType, base); LZ4_putPosition(ip, ctx, tableType, base); if ( (match+MAX_DISTANCE>=ip) && (LZ4_read32(match)==LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } /* Prepare next loop */ forwardH = LZ4_hashPosition(++ip, tableType); } _last_literals: /* Encode Last Literals */ { size_t lastRunSize = (size_t)(iend - anchor); if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) { /* adapt lastRunSize to fill 'dst' */ lastRunSize = (oend-op) - 1; lastRunSize -= (lastRunSize+240)/255; } ip = anchor + lastRunSize; if (lastRunSize >= RUN_MASK) { size_t accumulator = lastRunSize - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; } else { *op++ = (BYTE)(lastRunSize<= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */ { return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); } else { if (*srcSizePtr < LZ4_64Klimit) return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16); else return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr); } } int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { #if (HEAPMODE) void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ #else LZ4_stream_t ctxBody; void* ctx = &ctxBody; #endif int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); #if (HEAPMODE) FREEMEM(ctx); #endif return result; } /******************************** * Streaming functions ********************************/ LZ4_stream_t* LZ4_createStream(void) { LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64); LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ LZ4_resetStream(lz4s); return lz4s; } void LZ4_resetStream (LZ4_stream_t* LZ4_stream) { MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); } int LZ4_freeStream (LZ4_stream_t* LZ4_stream) { FREEMEM(LZ4_stream); return (0); } #define HASH_UNIT sizeof(size_t) int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) { LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; const BYTE* p = (const BYTE*)dictionary; const BYTE* const dictEnd = p + dictSize; const BYTE* base; if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ LZ4_resetStream(LZ4_dict); if (dictSize < (int)HASH_UNIT) { dict->dictionary = NULL; dict->dictSize = 0; return 0; } if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; dict->currentOffset += 64 KB; base = p - dict->currentOffset; dict->dictionary = p; dict->dictSize = (U32)(dictEnd - p); dict->currentOffset += dict->dictSize; while (p <= dictEnd-HASH_UNIT) { LZ4_putPosition(p, dict->hashTable, byU32, base); p+=3; } return dict->dictSize; } static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) { if ((LZ4_dict->currentOffset > 0x80000000) || ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ { /* rescale hash table */ U32 delta = LZ4_dict->currentOffset - 64 KB; const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; int i; for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; else LZ4_dict->hashTable[i] -= delta; } LZ4_dict->currentOffset = 64 KB; if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; } } int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = (const BYTE*) source; if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd; LZ4_renormDictT(streamPtr, smallest); if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; /* Check overlapping input/dictionary space */ { const BYTE* sourceEnd = (const BYTE*) source + inputSize; if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { streamPtr->dictSize = (U32)(dictEnd - sourceEnd); if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; streamPtr->dictionary = dictEnd - streamPtr->dictSize; } } /* prefix mode : source data follows dictionary */ if (dictEnd == (const BYTE*)source) { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); else result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); streamPtr->dictSize += (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } /* external dictionary mode */ { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); else result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } } /* Hidden debug function, to force external dictionary mode */ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) { LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; int result; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = dictEnd; if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) { LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; memmove(safeBuffer, previousDictEnd - dictSize, dictSize); dict->dictionary = (const BYTE*)safeBuffer; dict->dictSize = (U32)dictSize; return dictSize; } /******************************* * Decompression functions *******************************/ /* * This generic decompression function cover all use cases. * It shall be instantiated several times, using different sets of directives * Note that it is essential this generic function is really inlined, * in order to remove useless branches during compilation optimization. */ FORCE_INLINE int LZ4_decompress_generic( const char* const source, char* const dest, int inputSize, int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ int endOnInput, /* endOnOutputSize, endOnInputSize */ int partialDecoding, /* full, partial */ int targetOutputSize, /* only used if partialDecoding==partial */ int dict, /* noDict, withPrefix64k, usingExtDict */ const BYTE* const lowPrefix, /* == dest if dict == noDict */ const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note : = 0 if noDict */ ) { /* Local Variables */ const BYTE* ip = (const BYTE*) source; const BYTE* const iend = ip + inputSize; BYTE* op = (BYTE*) dest; BYTE* const oend = op + outputSize; BYTE* cpy; BYTE* oexit = op + targetOutputSize; const BYTE* const lowLimit = lowPrefix - dictSize; const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; const int safeDecode = (endOnInput==endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); /* Special cases */ if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); /* Main Loop */ while (1) { unsigned token; size_t length; const BYTE* match; /* get literal length */ token = *ip++; if ((length=(token>>ML_BITS)) == RUN_MASK) { unsigned s; do { s = *ip++; length += s; } while (likely((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) || ((!endOnInput) && (cpy>oend-COPYLENGTH))) { if (partialDecoding) { if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ } else { if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ } memcpy(op, ip, length); ip += length; op += length; break; /* Necessarily EOF, due to parsing restrictions */ } LZ4_wildCopy(op, ip, cpy); ip += length; op = cpy; /* get offset */ match = cpy - LZ4_readLE16(ip); ip+=2; if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ /* get matchlength */ length = token & ML_MASK; if (length == ML_MASK) { unsigned s; do { if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; s = *ip++; length += s; } while (s==255); if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ } length += MINMATCH; /* check external dictionary */ if ((dict==usingExtDict) && (match < lowPrefix)) { if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ if (length <= (size_t)(lowPrefix-match)) { /* match can be copied as a single segment from external dictionary */ match = dictEnd - (lowPrefix-match); memmove(op, match, length); op += length; } else { /* match encompass external dictionary and current segment */ size_t copySize = (size_t)(lowPrefix-match); memcpy(op, dictEnd - copySize, copySize); op += copySize; copySize = length - copySize; if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ { BYTE* const endOfMatch = op + copySize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) *op++ = *copyFrom++; } else { memcpy(op, lowPrefix, copySize); op += copySize; } } continue; } /* copy repeated sequence */ cpy = op + length; if (unlikely((op-match)<8)) { const size_t dec64 = dec64table[op-match]; op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; match += dec32table[op-match]; LZ4_copy4(op+4, match); op += 8; match -= dec64; } else { LZ4_copy8(op, match); op+=8; match+=8; } if (unlikely(cpy>oend-12)) { if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ if (op < oend-8) { LZ4_wildCopy(op, match, oend-8); match += (oend-8) - op; op = oend-8; } while (opprefixSize = (size_t) dictSize; lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; lz4sd->externalDict = NULL; lz4sd->extDictSize = 0; return 1; } /* *_continue() : These decoding functions allow decompression of multiple blocks in "streaming" mode. Previously decoded blocks must still be available at the memory position where they were decoded. If it's not possible, save the relevant part of decoded data into a safe buffer, and indicate where it stands using LZ4_setStreamDecode() */ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) { LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; int result; if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += result; lz4sd->prefixEnd += result; } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = result; lz4sd->prefixEnd = (BYTE*)dest + result; } return result; } int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) { LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; int result; if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += originalSize; lz4sd->prefixEnd += originalSize; } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = originalSize; lz4sd->prefixEnd = (BYTE*)dest + originalSize; } return result; } /* Advanced decoding functions : *_usingDict() : These decoding functions work the same as "_continue" ones, the dictionary must be explicitly provided within parameters */ FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) { if (dictSize==0) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); if (dictStart+dictSize == dest) { if (dictSize >= (int)(64 KB - 1)) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); } return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); } int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); } /* debug function */ int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } /*************************************************** * Obsolete Functions ***************************************************/ /* obsolete compression functions */ int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); } int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); } int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); } int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); } int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); } int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); } /* These function names are deprecated and should no longer be used. They are only provided here for compatibility with older user programs. - LZ4_uncompress is totally equivalent to LZ4_decompress_fast - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe */ int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } /* Obsolete Streaming functions */ int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base) { MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); lz4ds->bufferStart = base; } int LZ4_resetStreamState(void* state, char* inputBuffer) { if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer); return 0; } void* LZ4_create (char* inputBuffer) { void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer); return lz4ds; } char* LZ4_slideInputBuffer (void* LZ4_Data) { LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB); return (char*)(ctx->bufferStart + dictSize); } /* Obsolete streaming decompression functions */ int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); } int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) { return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); } #endif /* LZ4_COMMONDEFS_ONLY */ iverilog-12_0/vpi/lz4.h000066400000000000000000000446701435245347300150420ustar00rootroot00000000000000/* LZ4 - Fast LZ compression algorithm Header File Copyright (C) 2011-2015, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SPDX-License-Identifier: BSD-2-Clause You can contact the author at : - LZ4 source repository : https://github.com/Cyan4973/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ #pragma once #if defined (__cplusplus) extern "C" { #endif /* * lz4.h provides block compression functions, and gives full buffer control to programmer. * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), * and can let the library handle its own memory, please use lz4frame.h instead. */ /************************************** * Version **************************************/ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ #define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) int LZ4_versionNumber (void); /************************************** * Tuning parameter **************************************/ /* * LZ4_MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Increasing memory usage improves compression ratio * Reduced memory usage can improve speed, due to cache effect * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ #define LZ4_MEMORY_USAGE 14 /************************************** * Simple Functions **************************************/ int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); /* LZ4_compress_default() : Compresses 'sourceSize' bytes from buffer 'source' into already allocated 'dest' buffer of size 'maxDestSize'. Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize). It also runs faster, so it's a recommended setting. If the function cannot compress 'source' into a more limited 'dest' budget, compression stops *immediately*, and the function result is zero. As a consequence, 'dest' content is not valid. This function never writes outside 'dest' buffer, nor read outside 'source' buffer. sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) or 0 if compression fails LZ4_decompress_safe() : compressedSize : is the precise full size of the compressed block. maxDecompressedSize : is the size of destination buffer, which must be already allocated. return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) If destination buffer is not large enough, decoding will stop and output an error code (<0). If the source stream is detected malformed, the function will stop decoding and return a negative result. This function is protected against buffer overflow exploits, including malicious data packets. It never writes outside output buffer, nor reads outside input buffer. */ /************************************** * Advanced Functions **************************************/ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) /* LZ4_compressBound() : Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) This function is primarily useful for memory allocation purposes (destination buffer size). Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize) inputSize : max supported value is LZ4_MAX_INPUT_SIZE return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ int LZ4_compressBound(int inputSize); /* LZ4_compress_fast() : Same as LZ4_compress_default(), but allows to select an "acceleration" factor. The larger the acceleration value, the faster the algorithm, but also the lesser the compression. It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. An acceleration value of "1" is the same as regular LZ4_compress_default() Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. */ int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); /* LZ4_compress_fast_extState() : Same compression function, just using an externally allocated memory space to store compression state. Use LZ4_sizeofState() to know how much memory must be allocated, and allocate it on 8-bytes boundaries (using malloc() typically). Then, provide it as 'void* state' to compression function. */ int LZ4_sizeofState(void); int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration); /* LZ4_compress_destSize() : Reverse the logic, by compressing as much data as possible from 'source' buffer into already allocated buffer 'dest' of size 'targetDestSize'. This function either compresses the entire 'source' content into 'dest' if it's large enough, or fill 'dest' buffer completely with as much data as possible from 'source'. *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'. New value is necessarily <= old value. return : Nb bytes written into 'dest' (necessarily <= targetDestSize) or 0 if compression fails */ int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); /* LZ4_decompress_fast() : originalSize : is the original and therefore uncompressed size return : the number of bytes read from the source buffer (in other words, the compressed size) If the source stream is detected malformed, the function will stop decoding and return a negative result. Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. note : This function fully respect memory boundaries for properly formed compressed data. It is a bit faster than LZ4_decompress_safe(). However, it does not provide any protection against intentionally modified data stream (malicious input). Use this function in trusted environment only (data to decode comes from a trusted source). */ int LZ4_decompress_fast (const char* source, char* dest, int originalSize); /* LZ4_decompress_safe_partial() : This function decompress a compressed block of size 'compressedSize' at position 'source' into destination buffer 'dest' of size 'maxDecompressedSize'. The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, reducing decompression time. return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. Always control how many bytes were decoded. If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); /*********************************************** * Streaming Compression Functions ***********************************************/ #define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) #define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) /* * LZ4_stream_t * information structure to track an LZ4 stream. * important : init this structure content before first use ! * note : only allocated directly the structure if you are statically linking LZ4 * If you are using liblz4 as a DLL, please use below construction methods instead. */ typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; /* * LZ4_resetStream * Use this function to init an allocated LZ4_stream_t structure */ void LZ4_resetStream (LZ4_stream_t* streamPtr); /* * LZ4_createStream will allocate and initialize an LZ4_stream_t structure * LZ4_freeStream releases its memory. * In the context of a DLL (liblz4), please use these methods rather than the static struct. * They are more future proof, in case of a change of LZ4_stream_t size. */ LZ4_stream_t* LZ4_createStream(void); int LZ4_freeStream (LZ4_stream_t* streamPtr); /* * LZ4_loadDict * Use this function to load a static dictionary into LZ4_stream. * Any previous data will be forgotten, only 'dictionary' will remain in memory. * Loading a size of 0 is allowed. * Return : dictionary size, in bytes (necessarily <= 64 KB) */ int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); /* * LZ4_compress_fast_continue * Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio. * Important : Previous data blocks are assumed to still be present and unmodified ! * 'dst' buffer must be already allocated. * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. * If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero. */ int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration); /* * LZ4_saveDict * If previously compressed data block is not guaranteed to remain available at its memory location * save it into a safer place (char* safeBuffer) * Note : you don't need to call LZ4_loadDict() afterwards, * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue() * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error */ int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize); /************************************************ * Streaming Decompression Functions ************************************************/ #define LZ4_STREAMDECODESIZE_U64 4 #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; /* * LZ4_streamDecode_t * information structure to track an LZ4 stream. * init this structure content using LZ4_setStreamDecode or memset() before first use ! * * In the context of a DLL (liblz4) please prefer usage of construction methods below. * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure * LZ4_freeStreamDecode releases its memory. */ LZ4_streamDecode_t* LZ4_createStreamDecode(void); int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); /* * LZ4_setStreamDecode * Use this function to instruct where to find the dictionary. * Setting a size of 0 is allowed (same effect as reset). * Return : 1 if OK, 0 if error */ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); /* *_continue() : These decoding functions allow decompression of multiple blocks in "streaming" mode. Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) In the case of a ring buffers, decoding buffer must be either : - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions) In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB). - Larger than encoding buffer, by a minimum of maxBlockSize more bytes. maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block. In which case, encoding and decoding buffers do not need to be synchronized, and encoding ring buffer can have any size, including small ones ( < 64 KB). - _At least_ 64 KB + 8 bytes + maxBlockSize. In which case, encoding and decoding buffers do not need to be synchronized, and encoding ring buffer can have any size, including larger than decoding buffer. Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer, and indicate where it is saved using LZ4_setStreamDecode() */ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); /* Advanced decoding functions : *_usingDict() : These decoding functions work the same as a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue() They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure. */ int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); /************************************** * Obsolete Functions **************************************/ /* Deprecate Warnings */ /* Should these warnings messages be a problem, it is generally possible to disable them, with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual for example. You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */ #ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK # define LZ4_DEPRECATE_WARNING_DEFBLOCK # define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) # if (LZ4_GCC_VERSION >= 405) || defined(__clang__) # define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) # elif (LZ4_GCC_VERSION >= 301) # define LZ4_DEPRECATED(message) __attribute__((deprecated)) # elif defined(_MSC_VER) # define LZ4_DEPRECATED(message) __declspec(deprecated(message)) # else # pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") # define LZ4_DEPRECATED(message) # endif #endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */ /* Obsolete compression functions */ /* These functions are planned to start generate warnings by r131 approximately */ int LZ4_compress (const char* source, char* dest, int sourceSize); int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); /* Obsolete decompression functions */ /* These function names are completely deprecated and must no longer be used. They are only provided here for compatibility with older programs. - LZ4_uncompress is the same as LZ4_decompress_fast - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe These function prototypes are now disabled; uncomment them only if you really need them. It is highly recommended to stop using these prototypes and migrate to maintained ones */ /* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ /* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ /* Obsolete streaming functions; use new streaming interface whenever possible */ LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer); LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void); LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer); LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state); /* Obsolete streaming decoding functions */ LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); #if defined (__cplusplus) } #endif iverilog-12_0/vpi/mt19937int.c000066400000000000000000000110141435245347300160560ustar00rootroot00000000000000/* * NOTE: This code as been slightly modified to interface with the * PLI implementations of $random. The copyright and license * information are given in the comment block below. * * The Modifications include: * * Remove the "main" function, as this is being used for its functions. * * Change the function prototypes to use ANSI/ISO C syntax. */ /* A C-program for MT19937: Integer version (1998/4/6) */ /* genrand() generates one pseudorandom unsigned integer (32bit) */ /* which is uniformly distributed among 0 to 2^32-1 for each */ /* call. sgenrand(seed) set initial values to the working area */ /* of 624 words. Before genrand(), sgenrand(seed) must be */ /* called once. (seed is any 32-bit integer except for 0). */ /* Coded by Takuji Nishimura, considering the suggestions by */ /* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Library General Public */ /* License as published by the Free Software Foundation; either */ /* version 2 of the License, or (at your option) any later */ /* version. */ /* This library is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* See the GNU Library General Public License for more details. */ /* You should have received a copy of the GNU Library General */ /* Public License along with this library; if not, write to the */ /* Free Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, */ /* MA 02110-1301, USA */ /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */ /* When you use this, send an email to: matumoto@math.keio.ac.jp */ /* with an appropriate reference to your work. */ /* REFERENCE */ /* M. Matsumoto and T. Nishimura, */ /* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */ /* Pseudo-Random Number Generator", */ /* ACM Transactions on Modeling and Computer Simulation, */ /* Vol. 8, No. 1, January 1998, pp 3--30. */ #include "sys_priv.h" /* Period parameters */ #define N 624 #define M 397 #define MATRIX_A 0x9908b0df /* constant vector a */ #define UPPER_MASK 0x80000000 /* most significant w-r bits */ #define LOWER_MASK 0x7fffffff /* least significant r bits */ /* Tempering parameters */ #define TEMPERING_MASK_B 0x9d2c5680 #define TEMPERING_MASK_C 0xefc60000 #define TEMPERING_SHIFT_U(y) (y >> 11) #define TEMPERING_SHIFT_S(y) (y << 7) #define TEMPERING_SHIFT_T(y) (y << 15) #define TEMPERING_SHIFT_L(y) (y >> 18) /* initializing the array with a NONZERO seed */ void sgenrand(struct context_s *context, unsigned long seed) { unsigned long *mt = context->mt; int mti; /* setting initial seeds to mt[N] using */ /* the generator Line 25 of Table 1 in */ /* [KNUTH 1981, The Art of Computer Programming */ /* Vol. 2 (2nd Ed.), pp102] */ mt[0]= seed & 0xffffffff; for (mti=1; mtimti = mti; } unsigned long genrand(struct context_s *context) { unsigned long y; unsigned long *mt = context->mt; int mti = context->mti; if (mti >= N) { /* generate N words at one time */ /* mag01[x] = x * MATRIX_A for x=0,1 */ static unsigned long mag01[2]={0x0, MATRIX_A}; int kk; if (mti == N+1) /* if sgenrand() has not been called, */ sgenrand(context, 4357); /* a default initial seed is used */ for (kk=0;kk> 1) ^ mag01[y & 0x1]; } for (;kk> 1) ^ mag01[y & 0x1]; } y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; mti = 0; } y = mt[mti++]; y ^= TEMPERING_SHIFT_U(y); y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; y ^= TEMPERING_SHIFT_L(y); context->mti = mti; return y; } iverilog-12_0/vpi/sdf_lexor.lex000066400000000000000000000136361435245347300166550ustar00rootroot00000000000000%option prefix="sdf" %option never-interactive %option nounput %option noinput %{ /* * Copyright (c) 2007-2019 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 "sdf_priv.h" # include "sdf_parse_priv.h" # include "sdf_parse.h" # include # include # include # include static void process_quoted_string(void); static int lookup_keyword(const char*text); const char*sdf_parse_path = 0; static int yywrap(void) { return 1; } # define yylval sdflval %} %x CCOMMENT %x COND_EDGE_ID %x EDGE_ID %% /* Skip C++-style comments. */ "//".* { ; } /* Skip C-style comments. */ "/*" { BEGIN(CCOMMENT); } . { ; } \n { sdflloc.first_line += 1; } "*/" { BEGIN(0); } [ \m\t] { /* Skip white space. */; } /* Count lines so that the parser can assign line numbers. */ \n { sdflloc.first_line += 1; } /* The other edge identifiers. */ "01" {return K_01; } "10" {return K_10; } "0"[zZ] {return K_0Z; } [zZ]"1" {return K_Z1; } "1"[zZ] {return K_1Z; } [zZ]"0" {return K_Z0; } [pP][oO][sS][eE][dD][gG][eE] {return K_POSEDGE; } [nN][eE][gG][eE][dD][gG][eE] {return K_NEGEDGE; } [cC][oO][nN][dD] {return K_COND; } /* Integer values */ [0-9]+ { yylval.int_val = strtoul(yytext, 0, 10); return INTEGER; } /* Real values */ [0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)? { yylval.real_val = strtod(yytext, 0); return REAL_NUMBER; } ([a-zA-Z_]|(\\[^ \t\b\f\r\n]))([a-zA-Z0-9$_]|(\\[^ \t\b\f\r\n]))* { return lookup_keyword(yytext); } \"[^\"]*\" { process_quoted_string(); return QSTRING; } /* Scalar constants. */ ("1"?"'"[bB])?"0" { return K_LOGICAL_ZERO; } ("1"?"'"[bB])?"1" { return K_LOGICAL_ONE; } /* Equality operators. */ "==" { return K_EQ; } "!=" { return K_NE; } "===" { return K_CEQ; } "!==" { return K_CNE; } /* Other operators. */ "&&" { return K_LAND; } "||" { return K_LOR; } /* The HCHAR (hierarchy separator) is set by the SDF file itself. We recognize here the HCHAR. */ [./] { if (sdf_use_hchar==yytext[0]) return HCHAR; else return yytext[0]; } . { return yytext[0]; } %% static struct { const char*name; int code; } keywords[] = { { "ABSOLUTE", K_ABSOLUTE }, { "CELL", K_CELL }, { "CELLTYPE", K_CELLTYPE }, { "DATE", K_DATE }, { "COND", K_COND }, { "CONDELSE", K_CONDELSE }, { "DELAY", K_DELAY }, { "DELAYFILE", K_DELAYFILE }, { "DESIGN", K_DESIGN }, { "DIVIDER", K_DIVIDER }, { "HOLD", K_HOLD }, { "INCREMENT", K_INCREMENT }, { "INTERCONNECT", K_INTERCONNECT }, { "INSTANCE", K_INSTANCE }, { "IOPATH", K_IOPATH }, { "PATHPULSE", K_PATHPULSE }, { "PATHPULSEPERCENT", K_PATHPULSEPERCENT }, { "PERIOD", K_PERIOD }, { "PROCESS", K_PROCESS }, { "PROGRAM", K_PROGRAM }, { "RECREM", K_RECREM }, { "RECOVERY", K_RECOVERY }, { "REMOVAL", K_REMOVAL }, { "SDFVERSION", K_SDFVERSION }, { "SETUP", K_SETUP }, { "SETUPHOLD", K_SETUPHOLD }, { "TEMPERATURE", K_TEMPERATURE }, { "TIMESCALE", K_TIMESCALE }, { "TIMINGCHECK", K_TIMINGCHECK }, { "VENDOR", K_VENDOR }, { "VERSION", K_VERSION }, { "VOLTAGE", K_VOLTAGE }, { "WIDTH", K_WIDTH }, { 0, IDENTIFIER } }; void start_edge_id(unsigned cond) { if (cond) BEGIN(COND_EDGE_ID); else BEGIN(EDGE_ID); } void stop_edge_id(void) { BEGIN(0); } static int lookup_keyword(const char*text) { unsigned idx, len, skip; for (idx = 0 ; keywords[idx].name ; idx += 1) { if (strcasecmp(text, keywords[idx].name) == 0) return keywords[idx].code; } /* Process any escaped characters. */ skip = 0; len = strlen(yytext); for (idx = 0; idx < len; idx += 1) { if (yytext[idx] == '\\') { skip += 1; idx += 1; } yytext[idx-skip] = yytext[idx]; } yytext[idx-skip] = 0; yylval.string_val = strdup(yytext); return IDENTIFIER; } /* * Create a string without the leading and trailing quotes. */ static void process_quoted_string(void) { char*endp; yylval.string_val = strdup(yytext+1); endp = yylval.string_val+strlen(yylval.string_val); assert(endp[-1] == '"'); endp[-1] = 0; } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ static void destroy_sdf_lexor(void) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } extern int sdfparse(void); void sdf_process_file(FILE*fd, const char*path) { yyrestart(fd); sdf_parse_path = path; sdfparse(); destroy_sdf_lexor(); sdf_parse_path = 0; } iverilog-12_0/vpi/sdf_parse.y000066400000000000000000000325171435245347300163150ustar00rootroot00000000000000 %{ /* * Copyright (c) 1998-2019 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. */ extern int sdflex(void); static void yyerror(const char*msg); # include "vpi_user.h" # include "sdf_parse_priv.h" # include "sdf_priv.h" # include # include # include # include "ivl_alloc.h" /* This is the hierarchy separator to use. */ char sdf_use_hchar = '.'; %} %union { unsigned long int_val; double real_val; char* string_val; struct sdf_delay_s delay; struct port_with_edge_s port_with_edge; struct sdf_delval_list_s delval_list; }; %token K_ABSOLUTE K_CELL K_CELLTYPE K_COND K_CONDELSE K_DATE K_DELAYFILE %token K_DELAY K_DESIGN K_DIVIDER K_HOLD K_INCREMENT K_INSTANCE %token K_INTERCONNECT K_IOPATH K_NEGEDGE K_PATHPULSE K_PATHPULSEPERCENT %token K_PERIOD K_POSEDGE K_PROCESS K_PROGRAM %token K_RECREM K_RECOVERY K_REMOVAL K_SDFVERSION K_SETUP K_SETUPHOLD %token K_TEMPERATURE K_TIMESCALE K_TIMINGCHECK K_VENDOR K_VERSION %token K_VOLTAGE K_WIDTH %token K_01 K_10 K_0Z K_Z1 K_1Z K_Z0 %token K_EQ K_NE K_CEQ K_CNE K_LOGICAL_ONE K_LOGICAL_ZERO %token K_LAND K_LOR %token HCHAR %token QSTRING IDENTIFIER %token REAL_NUMBER %token INTEGER %type celltype %type cell_instance %type hierarchical_identifier %type port port_instance port_interconnect %type signed_real_number %type delval rvalue_opt rvalue rtriple signed_real_number_opt %type edge_identifier %type port_edge port_spec %type delval_list %left K_LOR %left K_LAND %left K_EQ K_NE K_CEQ K_CNE %% source_file : '(' K_DELAYFILE sdf_header_list cell_list ')' | '(' K_DELAYFILE error ')' { vpi_printf("%s:%d:SDF ERROR: Invalid DELAYFILE format\n", sdf_parse_path, @2.first_line); } ; sdf_header_list : sdf_header_list sdf_header_item | sdf_header_item ; sdf_header_item : sdfversion | design_name | date | vendor | program_name | program_version | hierarchy_divider | voltage | process | temperature | time_scale ; sdfversion : '(' K_SDFVERSION QSTRING ')' { free($3); } ; design_name : '(' K_DESIGN QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Design: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; date : '(' K_DATE QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Date: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; vendor : '(' K_VENDOR QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Vendor: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; program_name : '(' K_PROGRAM QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Program: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; program_version : '(' K_VERSION QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Program Version: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; hierarchy_divider : '(' K_DIVIDER '.' ')' { sdf_use_hchar = '.'; } | '(' K_DIVIDER '/' ')' { sdf_use_hchar = '/'; } | '(' K_DIVIDER HCHAR ')' { /* sdf_use_hchar no-change */; } ; voltage : '(' K_VOLTAGE rtriple ')' | '(' K_VOLTAGE signed_real_number ')' ; process : '(' K_PROCESS QSTRING ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: Process: %s\n", sdf_parse_path, @2.first_line, $3); free($3); } ; temperature : '(' K_TEMPERATURE rtriple ')' | '(' K_TEMPERATURE signed_real_number ')' ; time_scale : '(' K_TIMESCALE REAL_NUMBER IDENTIFIER ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: TIMESCALE : %f%s\n", sdf_parse_path, @2.first_line, $3, $4); free($4); } | '(' K_TIMESCALE INTEGER IDENTIFIER ')' { if (sdf_flag_inform) vpi_printf("%s:%d:SDF INFO: TIMESCALE : %lu%s\n", sdf_parse_path, @2.first_line, $3, $4); free($4); } ; cell_list : cell_list cell | cell ; cell : '(' K_CELL celltype cell_instance { sdf_select_instance($3, $4); /* find the instance in the design */} timing_spec_list_opt ')' { free($3); if ($4) free($4); } | '(' K_CELL error ')' { vpi_printf("%s:%d: Syntax error in CELL\n", sdf_parse_path, @2.first_line); } ; celltype : '(' K_CELLTYPE QSTRING ')' { $$ = $3; } ; cell_instance : '(' K_INSTANCE hierarchical_identifier ')' { $$ = $3; } | '(' K_INSTANCE ')' { $$ = strdup(""); } | '(' K_INSTANCE '*' ')' { $$ = 0; } | '(' K_INSTANCE error ')' { vpi_printf("%s:%d:SDF ERROR: Invalid/malformed INSTANCE argument\n", sdf_parse_path, @2.first_line); $$ = strdup(""); } ; timing_spec_list_opt : /* Empty */ | timing_spec_list_opt timing_spec ; timing_spec : '(' K_DELAY deltype_list ')' | '(' K_DELAY error ')' { vpi_printf("%s:%d: Syntax error in CELL DELAY SPEC\n", sdf_parse_path, @2.first_line); } | '(' K_TIMINGCHECK tchk_def_list ')' | '(' K_TIMINGCHECK error ')' { vpi_printf("%s:%d: Syntax error in TIMINGCHECK SPEC\n", sdf_parse_path, @2.first_line); } ; deltype_list : deltype_list deltype | deltype ; deltype : '(' K_PATHPULSE input_output_path_opt rvalue rvalue_opt ')' | '(' K_PATHPULSEPERCENT input_output_path_opt rvalue rvalue_opt ')' | '(' K_ABSOLUTE del_def_list ')' | '(' K_INCREMENT del_def_list ')' | '(' error ')' { vpi_printf("%s:%d: SDF ERROR: Invalid/malformed delay type\n", sdf_parse_path, @1.first_line); } ; del_def_list : del_def_list del_def | del_def ; del_def : '(' K_IOPATH port_spec port_instance delval_list ')' { sdf_iopath_delays($3.vpi_edge, $3.string_val, $4, &$5); free($3.string_val); free($4); } | '(' K_IOPATH error ')' { vpi_printf("%s:%d: SDF ERROR: Invalid/malformed IOPATH\n", sdf_parse_path, @2.first_line); } | '(' K_COND conditional_port_expr '(' K_IOPATH port_spec port_instance delval_list ')' ')' { if (sdf_flag_warning) vpi_printf("%s:%d: SDF WARNING: " "COND not supported.\n", sdf_parse_path, @2.first_line); free($6.string_val); free($7); } | '(' K_COND QSTRING conditional_port_expr '(' K_IOPATH port_spec port_instance delval_list ')' ')' { if (sdf_flag_warning) vpi_printf("%s:%d: SDF WARNING: " "COND not supported.\n", sdf_parse_path, @2.first_line); free($3); free($7.string_val); free($8); } | '(' K_COND error ')' { vpi_printf("%s:%d: SDF ERROR: Invalid/malformed COND\n", sdf_parse_path, @2.first_line); } | '(' K_CONDELSE '(' K_IOPATH port_spec port_instance delval_list ')' ')' { if (sdf_flag_warning) vpi_printf("%s:%d: SDF WARNING: " "CONDELSE not supported.\n", sdf_parse_path, @2.first_line); free($5.string_val); free($6); } | '(' K_CONDELSE error ')' { vpi_printf("%s:%d: SDF ERROR: Invalid/malformed CONDELSE\n", sdf_parse_path, @2.first_line); } /* | '(' K_INTERCONNECT port_instance port_instance delval_list ')' */ | '(' K_INTERCONNECT port_interconnect port_interconnect delval_list ')' { if (sdf_flag_warning) vpi_printf("%s:%d: SDF WARNING: " "INTERCONNECT not supported.\n", sdf_parse_path, @2.first_line); free($3); free($4); } | '(' K_INTERCONNECT error ')' { vpi_printf("%s:%d: SDF ERROR: Invalid/malformed INTERCONNECT\n", sdf_parse_path, @2.first_line); } ; tchk_def_list : tchk_def_list tchk_def | tchk_def ; /* Timing checks are ignored. */ tchk_def : '(' K_SETUP port_tchk port_tchk rvalue ')' | '(' K_HOLD port_tchk port_tchk rvalue ')' | '(' K_SETUPHOLD port_tchk port_tchk rvalue rvalue ')' | '(' K_RECOVERY port_tchk port_tchk rvalue ')' | '(' K_RECREM port_tchk port_tchk rvalue rvalue ')' | '(' K_REMOVAL port_tchk port_tchk rvalue ')' | '(' K_WIDTH port_tchk rvalue ')' | '(' K_PERIOD port_tchk rvalue ')' ; port_tchk : port_instance { free($1); } /* This must only be an edge. For now we just accept everything. */ | cond_edge_start port_instance ')' { free($2); } /* These must only be a cond. For now we just accept everything. */ | cond_edge_start timing_check_condition port_spec ')' { free($3.string_val); } | cond_edge_start QSTRING timing_check_condition port_spec ')' { free($2); free($4.string_val); } ; cond_edge_start : '(' { start_edge_id(1); } cond_edge_identifier { stop_edge_id(); } ; cond_edge_identifier : K_POSEDGE | K_NEGEDGE | K_01 | K_10 | K_0Z | K_Z1 | K_1Z | K_Z0 | K_COND ; timing_check_condition : port_interconnect { free($1); } | '~' port_interconnect { free($2); } | '!' port_interconnect { free($2); } | port_interconnect equality_operator scalar_constant { free($1); } ; /* This is not complete! */ conditional_port_expr : port { free($1); } | scalar_constant | '(' conditional_port_expr ')' | conditional_port_expr K_LAND conditional_port_expr | conditional_port_expr K_LOR conditional_port_expr | conditional_port_expr K_EQ conditional_port_expr | conditional_port_expr K_NE conditional_port_expr | conditional_port_expr K_CEQ conditional_port_expr | conditional_port_expr K_CNE conditional_port_expr ; equality_operator : K_EQ | K_NE | K_CEQ | K_CNE ; scalar_constant : K_LOGICAL_ONE | K_LOGICAL_ZERO ; input_output_path_opt : input_output_path | ; input_output_path : port_instance port_instance ; port_spec : port_instance { $$.vpi_edge = vpiNoEdge; $$.string_val = $1; } | port_edge { $$ = $1; } ; port_instance : port { $$ = $1; } ; port : hierarchical_identifier { $$ = $1; } /* | hierarchical_identifier '[' INTEGER ']' */ ; /* Since INTERCONNECT is ignored we can also ignore a vector bit. */ port_interconnect : hierarchical_identifier { $$ = $1; } | hierarchical_identifier '[' INTEGER ']' { $$ = $1;} ; port_edge : '(' {start_edge_id(0);} edge_identifier {stop_edge_id();} port_instance ')' { $$.vpi_edge = $3; $$.string_val = $5; } ; edge_identifier : K_POSEDGE { $$ = vpiPosedge; } | K_NEGEDGE { $$ = vpiNegedge; } | K_01 { $$ = vpiEdge01; } | K_10 { $$ = vpiEdge10; } | K_0Z { $$ = vpiEdge0x; } | K_Z1 { $$ = vpiEdgex1; } | K_1Z { $$ = vpiEdge1x; } | K_Z0 { $$ = vpiEdgex0; } ; delval_list : delval_list delval { int idx; $$.count = $1.count; for (idx = 0 ; idx < $$.count ; idx += 1) $$.val[idx] = $1.val[idx]; // Is this correct? if ($$.count < 12) { $$.val[$$.count] = $2; $$.count += 1; } } | delval { $$.count = 1; $$.val[0] = $1; } ; delval : rvalue { $$ = $1; } | '(' rvalue rvalue ')' { $$ = $2; vpi_printf("%s:%d: SDF WARNING: Pulse rejection limits ignored\n", sdf_parse_path, @3.first_line); } | '(' rvalue rvalue rvalue ')' { $$ = $2; vpi_printf("%s:%d: SDF WARNING: Pulse rejection limits ignored\n", sdf_parse_path, @3.first_line); } ; rvalue_opt : /* When missing. */ { $$.value = 0.0; $$.defined = 0; } | rvalue ; rvalue : '(' signed_real_number ')' { $$.defined = 1; $$.value = $2; } | '(' rtriple ')' { $$ = $2; } | '(' ')' { $$.defined = 0; $$.value = 0.0; } ; hierarchical_identifier : IDENTIFIER { $$ = $1; } | hierarchical_identifier HCHAR IDENTIFIER { int len = strlen($1) + strlen($3) + 2; char*tmp = realloc($1, len); strcat(tmp, "."); strcat(tmp, $3); free($3); $$ = tmp; } ; rtriple : signed_real_number_opt ':' signed_real_number_opt ':' signed_real_number_opt { switch(sdf_min_typ_max) { case _vpiDelaySelMinimum: $$ = $1; break; case _vpiDelaySelTypical: $$ = $3; break; case _vpiDelaySelMaximum: $$ = $5; break; } /* At least one of the values must be defined. */ if (! ($1.defined || $3.defined || $5.defined)) { vpi_printf("%s:%d: SDF ERROR: rtriple must have at least one " "defined value.\n", sdf_parse_path, @1.first_line); } } ; signed_real_number_opt : /* When missing. */ { $$.value = 0.0; $$.defined = 0; } | signed_real_number { $$.value = $1; $$.defined = 1; } ; signed_real_number : REAL_NUMBER { $$ = $1; } | '+' REAL_NUMBER { $$ = $2; } | '-' REAL_NUMBER { $$ = -$2; } | INTEGER { $$ = $1; } | '+' INTEGER { $$ = $2; } | '-' INTEGER { $$ = -$2; } ; %% void yyerror(const char*msg) { vpi_printf("%s:SDF ERROR: Too many errors: %s\n", sdf_parse_path, msg); } iverilog-12_0/vpi/sdf_parse_priv.h000066400000000000000000000025521435245347300173300ustar00rootroot00000000000000#ifndef IVL_sdf_parse_priv_h #define IVL_sdf_parse_priv_h /* * Copyright (c) 2007-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. */ /* * This file is only included by sdf_parse.y and sdf_lexor.lex. It is * used to share declarations between the parse and the lexor. */ struct port_with_edge_s { int vpi_edge; char*string_val; }; /* Path to source for error messages. */ extern const char*sdf_parse_path; /* Hierarchy separator character to use. */ extern char sdf_use_hchar; extern void start_edge_id(unsigned cond); extern void stop_edge_id(void); #endif /* IVL_sdf_parse_priv_h */ iverilog-12_0/vpi/sdf_priv.h000066400000000000000000000033061435245347300161340ustar00rootroot00000000000000#ifndef IVL_sdf_priv_h #define IVL_sdf_priv_h /* * Copyright (c) 2007-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 /* * Invoke the parser to parse the opened SDF file. The fd is the SDF * file already opened and ready for reading. The path is the path to * the file and is only used for error messages. */ extern void sdf_process_file(FILE*fd, const char*path); extern int sdf_flag_warning; extern int sdf_flag_inform; extern int sdf_min_typ_max; /* **** * These functions are called by the parser to process the SDF file as * it is parsed. */ struct sdf_delay_s { int defined; double value; }; struct sdf_delval_list_s { int count; struct sdf_delay_s val[12]; }; extern void sdf_select_instance(const char*celltype, const char*inst); extern void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, const struct sdf_delval_list_s*delval); #endif /* IVL_sdf_priv_h */ iverilog-12_0/vpi/stringheap.c000066400000000000000000000037521435245347300164640ustar00rootroot00000000000000/* * Copyright (c) 2003-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 "sys_priv.h" # include "stringheap.h" # include # include # include # include "ivl_alloc.h" struct stringheap_cell { struct stringheap_cell*next; }; # define PAGE_SIZE 8192 # define STRINGHEAP_SIZE (PAGE_SIZE - sizeof(struct stringheap_cell)) const char*strdup_sh(struct stringheap_s*hp, const char*txt) { char*res; unsigned len = strlen(txt); assert(len < STRINGHEAP_SIZE); if (hp->cell_lst == 0) { hp->cell_lst = malloc(PAGE_SIZE); hp->cell_lst->next = 0; hp->cell_off = 0; } if ((STRINGHEAP_SIZE - hp->cell_off - 1) <= len) { struct stringheap_cell*tmp = malloc(PAGE_SIZE); tmp->next = hp->cell_lst; hp->cell_lst = tmp; hp->cell_off = 0; } res = (char*) (hp->cell_lst + 1); res += hp->cell_off; strcpy(res, txt); hp->cell_off += len + 1; return res; } void string_heap_delete(struct stringheap_s*hp) { struct stringheap_cell *cur, *tmp; for (cur = hp->cell_lst; cur ; cur = tmp) { tmp = cur->next; free((char *)cur); } hp->cell_lst = 0; hp->cell_off = 0; } iverilog-12_0/vpi/stringheap.h000066400000000000000000000022701435245347300164630ustar00rootroot00000000000000#ifndef IVL_stringheap_H #define IVL_stringheap_H /* * Copyright (c) 2003-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. */ struct stringheap_cell; struct stringheap_s { struct stringheap_cell*cell_lst; unsigned cell_off; }; /* * Allocate the string from the heap. */ const char*strdup_sh(struct stringheap_s*hp, const char*str); void string_heap_delete(struct stringheap_s*hp); #endif /* IVL_stringheap_H */ iverilog-12_0/vpi/sys_clog2.c000066400000000000000000000104561435245347300162230ustar00rootroot00000000000000/* * Copyright (C) 2008-2021 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. */ #include #include #include #include "vpi_user.h" #include "sv_vpi_user.h" /* * This routine returns 1 if the argument supports has a numeric value, * otherwise it returns 0. * * This is copied from sys_priv.c. */ static unsigned is_numeric_obj(vpiHandle obj) { unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { case vpiConstant: case vpiParameter: /* These cannot be a string constant. */ if (vpi_get(vpiConstType, obj) != vpiStringConst) rtn = 1; break; /* These can have a valid numeric value. */ case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNet: case vpiPartSelect: case vpiRealVar: case vpiReg: case vpiTimeVar: rtn = 1; break; } return rtn; } /* * Check that the function is called with the correct argument. */ static PLI_INT32 sys_clog2_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, arg; assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); (void)name; /* Parameter is not used. */ /* We must have an argument. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$clog2 requires one numeric argument.\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The argument must be numeric. */ arg = vpi_scan(argv); if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("The first argument to $clog2 must be numeric.\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* We can have a maximum of one argument. */ if (vpi_scan(argv) != 0) { char msg[64]; unsigned argc; snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; argc = 1; while (vpi_scan(argv)) argc += 1; vpi_printf("%s $clog2 takes at most one argument.\n", msg); vpi_printf("%*s Found %u extra argument%s.\n", (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_clog2_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; s_vpi_vecval vec; (void)name; /* Parameter is not used. */ /* Get the argument. */ arg = vpi_scan(argv); vpi_free_object(argv); vec = vpip_calc_clog2(arg); val.format = vpiVectorVal; val.value.vector = &vec; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Register the function with Verilog. */ void sys_clog2_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.calltf = sys_clog2_calltf; tf_data.compiletf = sys_clog2_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$clog2"; tf_data.user_data = 0; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_convert.c000066400000000000000000000202601435245347300166670ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 Michael Ruff (mruff at chiaro.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 "sys_priv.h" # include # include # include static double bits2double(PLI_UINT32 bits[2]) { union conv { double rval; unsigned char bval[sizeof(double)]; } conv; #ifdef WORDS_BIGENDIAN conv.bval[7] = (bits[0] >> 0) & 0xff; conv.bval[6] = (bits[0] >> 8) & 0xff; conv.bval[5] = (bits[0] >> 16) & 0xff; conv.bval[4] = (bits[0] >> 24) & 0xff; conv.bval[3] = (bits[1] >> 0) & 0xff; conv.bval[2] = (bits[1] >> 8) & 0xff; conv.bval[1] = (bits[1] >> 16) & 0xff; conv.bval[0] = (bits[1] >> 24) & 0xff; #else conv.bval[0] = (bits[0] >> 0) & 0xff; conv.bval[1] = (bits[0] >> 8) & 0xff; conv.bval[2] = (bits[0] >> 16) & 0xff; conv.bval[3] = (bits[0] >> 24) & 0xff; conv.bval[4] = (bits[1] >> 0) & 0xff; conv.bval[5] = (bits[1] >> 8) & 0xff; conv.bval[6] = (bits[1] >> 16) & 0xff; conv.bval[7] = (bits[1] >> 24) & 0xff; #endif return conv.rval; } static void double2bits(double real, PLI_UINT32 bits[2]) { union conv { double rval; unsigned char bval[sizeof(double)]; } conv; conv.rval = real; #ifdef WORDS_BIGENDIAN bits[0] = conv.bval[7] | (conv.bval[6] << 8) | (conv.bval[5] <<16) | (conv.bval[4] <<24); bits[1] = conv.bval[3] | (conv.bval[2] << 8) | (conv.bval[1] <<16) | (conv.bval[0] <<24); #else bits[0] = conv.bval[0] | (conv.bval[1] << 8) | (conv.bval[2] <<16) | (conv.bval[3] <<24); bits[1] = conv.bval[4] | (conv.bval[5] << 8) | (conv.bval[6] <<16) | (conv.bval[7] <<24); #endif } static void error_message(vpiHandle callh, const char* msg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf(msg, vpi_get_str(vpiName, callh)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } static PLI_INT32 sizetf_64 (ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ return 64; } static PLI_INT32 sys_convert_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there is an argument. */ if (argv == 0) { error_message(callh, "%s requires one argument.\n"); return 0; } /* In Icarus if we have an argv we have at least one argument. */ arg = vpi_scan(argv); /* Validate the argument. Only $bitstoreal for now. */ if (!strcmp("$bitstoreal", name) && vpi_get(vpiSize, arg) != 64) { error_message(callh, "%s requires a 64-bit argument.\n"); return 0; } /* Save the argument away to make the calltf faster. */ vpi_put_userdata(callh, (void *) arg); /* These functions only take one argument. */ check_for_extra_args(argv, callh, name, "one argument", 0); return 0; } static PLI_INT32 sys_bitstoreal_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle arg = (vpiHandle) vpi_get_userdata(callh); s_vpi_value value; PLI_UINT32 bits[2]; (void)name; /* Parameter is not used. */ /* get value */ value.format = vpiVectorVal; vpi_get_value(arg, &value); /* convert */ bits[0] = (value.value.vector[0]).aval; bits[1] = (value.value.vector[1]).aval; value.value.real = bits2double(bits); value.format = vpiRealVal; /* return converted value */ vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_itor_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle arg = (vpiHandle) vpi_get_userdata(callh); s_vpi_value value; (void)name; /* Parameter is not used. */ /* get value */ value.format = vpiIntVal; vpi_get_value(arg, &value); /* convert */ value.value.real = value.value.integer; value.format = vpiRealVal; /* return converted value */ vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_realtobits_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle arg = (vpiHandle) vpi_get_userdata(callh); s_vpi_value value; static struct t_vpi_vecval res[2]; PLI_UINT32 bits[2]; (void)name; /* Parameter is not used. */ /* get value */ value.format = vpiRealVal; vpi_get_value(arg, &value); /* convert */ double2bits(value.value.real, bits); res[0].aval = bits[0]; res[0].bval = 0; res[1].aval = bits[1]; res[1].bval = 0; value.format = vpiVectorVal; value.value.vector = res; /* return converted value */ vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_rtoi_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle arg = (vpiHandle) vpi_get_userdata(callh); s_vpi_value value; static struct t_vpi_vecval res; double val; (void)name; /* Parameter is not used. */ /* get value */ value.format = vpiRealVal; vpi_get_value(arg, &value); /* If the value is NaN or +/- infinity then return 'bx */ val = value.value.real; if (val != val || (val && (val == 0.5*val))) { res.aval = ~(PLI_INT32)0; res.bval = ~(PLI_INT32)0; } else { /* This is not 100% correct since large real values may break this * code. See the verinum code for a more rigorous implementation. */ if (val >= 0.0) res.aval = (PLI_UINT64) val; else res.aval = - (PLI_UINT64) -val; res.bval = 0; } value.format = vpiVectorVal; value.value.vector = &res; /* return converted value */ vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } void sys_convert_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.user_data = "$bitstoreal"; tf_data.tfname = tf_data.user_data; tf_data.sizetf = 0; tf_data.compiletf = sys_convert_compiletf; tf_data.calltf = sys_bitstoreal_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.user_data = "$itor"; tf_data.tfname = tf_data.user_data; tf_data.sizetf = 0; tf_data.compiletf = sys_convert_compiletf; tf_data.calltf = sys_itor_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.user_data = "$realtobits"; tf_data.tfname = tf_data.user_data; tf_data.sizetf = sizetf_64; tf_data.compiletf = sys_convert_compiletf; tf_data.calltf = sys_realtobits_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.user_data = "$rtoi"; tf_data.tfname = tf_data.user_data; tf_data.sizetf = 0; tf_data.compiletf = sys_convert_compiletf; tf_data.calltf = sys_rtoi_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_countdrivers.c000066400000000000000000000154161435245347300177450ustar00rootroot00000000000000/* * Copyright (C) 2012-2021 Martin Whitaker. (icarus@martin-whitaker.me.uk) * * 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. */ #include "sys_priv.h" #include #include #include #include "ivl_alloc.h" /* * Check to see if an argument is a single bit net. */ static void check_net_arg(vpiHandle arg, vpiHandle callh, const char *name) { assert(arg); switch (vpi_get(vpiType, arg)) { case vpiPartSelect: if (vpi_get(vpiType, vpi_handle(vpiParent, arg)) != vpiNet) break; // fallthrough case vpiNet: if (vpi_get(vpiSize, arg) != 1) break; return; default: break; } vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a scalar net or " "a bit-select of a vector net.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* * Check to see if an argument is a variable. */ static void check_var_arg(vpiHandle arg, vpiHandle callh, const char *name, const char *arg_name) { assert(arg); switch (vpi_get(vpiType, arg)) { case vpiPartSelect: if (vpi_get(vpiType, vpi_handle(vpiParent, arg)) == vpiNet) break; case vpiMemoryWord: case vpiBitVar: case vpiReg: case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: return; default: break; } vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s argument must be a variable.\n", name, arg_name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } static PLI_INT32 sys_countdrivers_sizetf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ return 1; } /* * Check that the given $countdrivers() call has valid arguments. */ static PLI_INT32 sys_countdrivers_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; unsigned arg_num; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least one argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a scalar net or a net bit select. */ arg = vpi_scan(argv); check_net_arg(arg, callh, name); /* The optional arguments must be variables. */ for (arg_num = 2; arg_num < 7; arg_num += 1) { const char *arg_name = NULL; switch (arg_num) { case 2: arg_name = "second"; break; case 3: arg_name = "third"; break; case 4: arg_name = "fourth"; break; case 5: arg_name = "fifth"; break; case 6: arg_name = "sixth"; break; default: assert(0); } arg = vpi_scan(argv); if (arg == 0) return 0; check_var_arg(arg, callh, name, arg_name); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "six arguments", 0); return 0; } /* * The runtime code for $countdrivers(). */ static PLI_INT32 sys_countdrivers_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; unsigned idx; unsigned counts[4]; unsigned num_drivers; s_vpi_value val; (void)name; /* Parameter is not used. */ /* All returned values are integers. */ val.format = vpiIntVal; /* Get the base net reference and bit select */ idx = 0; arg = vpi_scan(argv); assert(arg); if (vpi_get(vpiType, arg) == vpiPartSelect) { idx = vpi_get(vpiLeftRange, arg); arg = vpi_handle(vpiParent, arg); assert(arg); } /* Get the net driver counts from the runtime. */ vpip_count_drivers(arg, idx, counts); num_drivers = counts[0] + counts[1] + counts[2]; /* Handle optional net_is_forced argument. */ arg = vpi_scan(argv); if (arg == 0) goto args_done; val.value.integer = counts[3]; vpi_put_value(arg, &val, 0, vpiNoDelay); /* Handle optional number_of_01x_drivers argument. */ arg = vpi_scan(argv); if (arg == 0) goto args_done; val.value.integer = num_drivers; vpi_put_value(arg, &val, 0, vpiNoDelay); /* Handle optional number_of_0_drivers argument. */ arg = vpi_scan(argv); if (arg == 0) goto args_done; val.value.integer = counts[0]; vpi_put_value(arg, &val, 0, vpiNoDelay); /* Handle optional number_of_1_drivers argument. */ arg = vpi_scan(argv); if (arg == 0) goto args_done; val.value.integer = counts[1]; vpi_put_value(arg, &val, 0, vpiNoDelay); /* Handle optional number_of_x_drivers argument. */ arg = vpi_scan(argv); if (arg == 0) goto args_done; val.value.integer = counts[2]; vpi_put_value(arg, &val, 0, vpiNoDelay); /* Free the argument iterator. */ vpi_free_object(argv); args_done: val.value.integer = (num_drivers > 1) ? 1 : 0; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Routine to register the system tasks/functions provided in this file. */ void sys_countdrivers_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.tfname = "$countdrivers"; tf_data.calltf = sys_countdrivers_calltf; tf_data.compiletf = sys_countdrivers_compiletf; tf_data.sizetf = sys_countdrivers_sizetf; tf_data.user_data = "$countdrivers"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_darray.c000066400000000000000000000072311435245347300164740ustar00rootroot00000000000000/* * Copyright (c) 2012-2021 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 "sys_priv.h" # include # include # include # include static PLI_INT32 dobject_size_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, arg; argv = vpi_iterate(vpiArgument, callh); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a dynamic array, queue or string " "argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); /* This should never be zero. */ assert(arg); /* The argument must be a dynamic array, queue or string. */ switch (vpi_get(vpiType, arg)) { case vpiStringVar: break; case vpiArrayVar: switch(vpi_get(vpiArrayType, arg)) { case vpiDynamicArray: case vpiQueueArray: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s argument must be a dynamic array, queue or " "string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s argument must be a dynamic array, queue or string, " "given a %s.\n", name, vpi_get_str(vpiType, arg)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s has too many arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); vpi_free_object(argv); } return 0; } static PLI_INT32 dobject_size_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg = vpi_scan(argv); (void)name; /* Parameter is not used. */ vpi_free_object(argv); s_vpi_value value; value.format = vpiIntVal; value.value.integer = vpi_get(vpiSize, arg); vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } void sys_darray_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$size"; tf_data.calltf = dobject_size_calltf; tf_data.compiletf = dobject_size_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$size"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_deposit.c000066400000000000000000000067701435245347300166700ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com) * Copyright (c) 2000 Stephan Boettcher * * 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 "sys_priv.h" # include # include static PLI_INT32 sys_deposit_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle target, value; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there are at least two arguments. */ target = vpi_scan(argv); /* This should never be zero. */ value = vpi_scan(argv); if (value == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } assert(target); /* Check the targets type. It must be a net or a register. */ switch (vpi_get(vpiType, target)) { case vpiNet: case vpiReg: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid target type (%s) for %s.\n", vpi_get_str(vpiType, target), name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that there is at most two arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } static PLI_INT32 sys_deposit_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, target, value; s_vpi_value val; (void)name; /* Parameter is not used. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); target = vpi_scan(argv); assert(target); value = vpi_scan(argv); assert(value); val.format = vpiIntVal; vpi_get_value(value, &val); vpi_put_value(target, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } void sys_deposit_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysTask; tf_data.tfname = "$deposit"; tf_data.calltf = sys_deposit_calltf; tf_data.compiletf = sys_deposit_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$deposit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_display.c000066400000000000000000002474501435245347300166700ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "sys_priv.h" # include # include # include # include # include # include # include # include "ivl_alloc.h" // Flag to enable better compatibility with other simulators static unsigned compatible_flag = 0; static void check_command_line_args(void) { struct t_vpi_vlog_info vlog_info; vpi_get_vlog_info(&vlog_info); for (int idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-compatible") == 0) { compatible_flag = 1; } } } /* Printf wrapper to handle both MCD/FD */ static PLI_INT32 my_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...) { int r = 0; va_list ap; va_start(ap, fmt); if (IS_MCD(mcd)) { r = vpi_mcd_vprintf(mcd, fmt, ap); } else { FILE *fp = vpi_get_file(mcd); if (fp) r = vfprintf(fp, fmt, ap); } va_end(ap); return r; } static void my_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count) { if (IS_MCD(mcd)) { vpip_mcd_rawwrite(mcd, buf, count); } else { FILE*fp = vpi_get_file(mcd); if (fp) { while (count > 0) { size_t rc = fwrite(buf, 1, count, fp); if (rc == 0) break; count -= rc; buf += rc; } } } } struct timeformat_info_s timeformat_info = { 0, 0, 0, 20 }; struct strobe_cb_info { const char*name; char*filename; int lineno; int default_format; vpiHandle scope; vpiHandle*items; unsigned nitems; unsigned fd_mcd; }; /* * The number of decimal digits needed to represent a * nr_bits binary number is floor(nr_bits*log_10(2))+1, * where log_10(2) = 0.30102999566398.... and I approximate * this transcendental number as 146/485, to avoid the vagaries * of floating-point. The smallest nr_bits for which this * approximation fails is 2621, * 2621*log_10(2)=789.9996, but (2621*146+484)/485=790 (exactly). * In cases like this, all that happens is we allocate one * unneeded char for the output. I add a "L" suffix to 146 * to make sure the computation is done as long ints, otherwise * on a 16-bit int machine (allowed by ISO C) we would mangle * this computation for bit-length of 224. I'd like to put * in a test for nr_bits < LONG_MAX/146, but don't know how * to fail, other than crashing. * * In an April 2000 thread in comp.unix.programmer, with subject * "integer -> string", I give the 28/93 * approximation, but overstate its accuracy: that version first * fails when the number of bits is 289, not 671. * * This result does not include space for a trailing '\0', if any. */ __inline__ static int calc_dec_size(int nr_bits, int is_signed) { int r; if (is_signed) --nr_bits; r = (nr_bits * 146L + 484) / 485; if (is_signed) ++r; return r; } static int vpi_get_dec_size(vpiHandle item) { return calc_dec_size( vpi_get(vpiSize, item), vpi_get(vpiSigned, item)==1 ); } static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv) { if (argv) { vpiHandle item; unsigned nitems = 1; vpiHandle*items = malloc(sizeof(vpiHandle)); items[0] = vpi_scan(argv); if (items[0] == 0) { free(items); info->nitems = 0; info->items = 0; return; } for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) { items = realloc(items, (nitems+1)*sizeof(vpiHandle)); items[nitems] = item; nitems += 1; } info->nitems = nitems; info->items = items; } else { info->nitems = 0; info->items = 0; } } static int get_default_format(const char *name) { int default_format; switch(name[ strlen(name)-1 ]){ /* writE/strobE or monitoR or displaY/fdisplaY or sformaT/sformatF */ case 'e': case 'r': case 't': case 'f': case 'y': default_format = vpiDecStrVal; break; case 'h': default_format = vpiHexStrVal; break; case 'o': default_format = vpiOctStrVal; break; case 'b': default_format = vpiBinStrVal; break; default: default_format = -1; assert(0); } return default_format; } /* Build the format using the variables that control how the item will * be printed. This is used in error messages and directly by the e/f/g * format codes (minus the enclosing <>). The user needs to free the * returned string. */ static char * format_as_string(int ljust, int plus, int ld_zero, int width, int prec, char fmt) { char buf[256]; unsigned int size = 0; /* Do not remove/change the "<" without also changing the e/f/g format * code below! */ buf[size++] = '<'; buf[size++] = '%'; if (ljust == 1) buf[size++] = '-'; if (plus == 1) buf[size++] = '+'; if (ld_zero == 1) buf[size++] = '0'; if (width != -1) size += sprintf(&buf[size], "%d", width); if (prec != -1) size += sprintf(&buf[size], ".%d", prec); if (fmt) buf[size++] = fmt; /* The same goes here ">"! */ buf[size++] = '>'; buf[size] = '\0'; return strdup(buf); } static void get_time(char *rtn, const char *value, int prec, PLI_INT32 time_units) { int shift = time_units - timeformat_info.units; /* Strip any leading zeros, but leave a single zero. */ while (value[0] == '0' && value[1] != '\0') value += 1; /* We need to scale the number up. */ if (shift >= 0) { strcpy(rtn, value); /* Shift only non-zero values. */ while (shift > 0 && value[0] != '0') { strcat(rtn, "0"); shift -= 1; } if (prec > 0) strcat(rtn, "."); while (prec > 0) { strcat(rtn, "0"); prec -= 1; } /* We need to scale the number down. */ } else { int len = strlen(value); int head = len + shift; int tail; /* We have digits to the left of the decimal point. */ if (head > 0) { strncpy(rtn, value, head); *(rtn+head) = '\0'; if (prec > 0) { strcat(rtn, "."); strncat(rtn, &value[head], prec); tail = prec + shift; while (tail > 0) { strcat(rtn, "0"); tail -= 1; } } /* All digits are to the right of the decimal point. */ } else { strcpy(rtn, "0"); if (prec > 0) strcat(rtn, "."); /* Add leading zeros as needed. */ head = -head; if (head > prec) head = prec; while (head > 0) { strcat(rtn, "0"); head -= 1; } /* Add digits from the value if they fit. */ tail = prec + len + shift; if (tail > 0) { strncat(rtn, value, tail); /* Add trailing zeros to fill out the precision. */ tail = prec + shift + 1 - len; while (tail > 0) { strcat(rtn, "0"); tail -= 1; } } } } strcat(rtn, timeformat_info.suff); } static void get_time_real(char *rtn, double value, int prec, PLI_INT32 time_units) { /* Scale the value from its time units to the format time units. */ if (time_units >= timeformat_info.units) { value *= pow(10.0, time_units - timeformat_info.units); } else { value /= pow(10.0, timeformat_info.units - time_units); } sprintf(rtn, "%0.*f%s", prec, value, timeformat_info.suff); } static unsigned int get_format_char(char **rtn, int ljust, int plus, int ld_zero, int width, int prec, char fmt, const struct strobe_cb_info *info, unsigned int *idx) { s_vpi_value value; char *result, *fmtb; unsigned int size; unsigned int ini_size = 512; /* The initial size of the buffer. */ /* Make sure the width fits in the initial buffer. */ assert(width >= -1); if ((unsigned int)(width+1) > ini_size) ini_size = width + 1; /* The default return value is the full format. */ result = malloc(ini_size*sizeof(char)); fmtb = format_as_string(ljust, plus, ld_zero, width, prec, fmt); strcpy(result, fmtb); size = strlen(result) + 1; /* fallback value if errors */ switch (fmt) { case '\0': vpi_printf("WARNING: %s:%d: a single %% at the end of format string " "%s%s will be displayed as '%%'.\n", info->filename, info->lineno, info->name, fmtb); // fallthrough case '%': if (ljust != 0 || plus != 0 || ld_zero != 0 || width != -1 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } strcpy(result, "%"); size = strlen(result) + 1; break; case 'b': case 'B': case 'o': case 'O': case 'h': case 'H': case 'x': case 'X': *idx += 1; if (plus != 0 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { switch (fmt) { case 'b': case 'B': value.format = vpiBinStrVal; break; case 'o': case 'O': value.format = vpiOctStrVal; break; case 'h': case 'H': case 'x': case 'X': value.format = vpiHexStrVal; break; } vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { unsigned swidth = strlen(value.value.str), free_flag = 0;; char *cp = value.value.str; if (ld_zero == 1) { /* Strip the leading zeros if a width is not given. */ if (width == -1) while (*cp == '0' && *(cp+1) != '\0') cp++; /* Pad with leading zeros. */ else if (ljust == 0 && (signed)swidth < width) { unsigned pad = (unsigned)width - swidth; cp = malloc((width+1)*sizeof(char)); memset(cp, '0', pad); strcpy(cp+pad, value.value.str); free_flag = 1; /* For a left aligned value also strip the leading zeros. */ } else if (ljust != 0) while (*cp == '0' && *(cp+1) != '\0') cp++; } /* If a width was not given, use a width of zero. */ if (width == -1) width = 0; /* If the default buffer is too small, make it big enough. */ size = strlen(cp) + 1; if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); if (ljust == 0) sprintf(result, "%*s", width, cp); else sprintf(result, "%-*s", width, cp); if (free_flag) free(cp); size = strlen(result) + 1; } } break; case 'c': case 'C': *idx += 1; if (plus != 0 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiIntVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { char ch = value.value.integer; /* If the width is less than one then use a width of one. */ if (width < 1) width = 1; size = width + 1; assert(size <= ini_size); if (ljust == 0) { if (width > 1) { memset(result, (ld_zero == 1 ? '0': ' '), width-1); } result[width-1] = ch; } else { result[0] = ch; if (width > 1) { memset(result+1, ' ', width-1); } } result[width] = '\0'; } } break; case 'd': case 'D': *idx += 1; if (prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiDecStrVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { unsigned pad = 0; unsigned swidth = strlen(value.value.str) + (value.value.str[0] == '-' ? 0 : (unsigned)plus); char *tbuf, *cpb, *cp = value.value.str; /* Allocate storage and calculate the pad if needed. */ if (ljust == 0 && ld_zero == 1 && (signed)swidth < width) { tbuf = malloc((width+1)*sizeof(char)); pad = (unsigned)width - swidth; } else { tbuf = malloc((swidth+1)*sizeof(char)); } cpb = tbuf; /* Insert the sign if needed. */ if (plus == 1 && *cp != '-') { *cpb = '+'; cpb += 1; } else if (*cp == '-') { *cpb = '-'; cpb += 1; cp += 1; } /* Now add padding if it is needed and then add the value. */ memset(cpb, '0', pad); strcpy(cpb+pad, cp); /* If a width was not given, use the default, unless we have a * leading zero (width of zero). Because the width of a real in * Icarus is 1 the string length will set the width of a real * displayed using %d. */ if (width == -1) { width = (ld_zero == 1) ? 0 : vpi_get_dec_size(info->items[*idx]); } /* If the default buffer is too small make it big enough. */ size = strlen(tbuf) + 1; if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); if (ljust == 0) sprintf(result, "%*s", width, tbuf); else sprintf(result, "%-*s", width, tbuf); free(tbuf); size = strlen(result) + 1; } } break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': *idx += 1; if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiRealVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { char *cp = fmtb; if (fmt == 'F') { while (*cp != 'F') cp++; *cp = 'f'; } while (*cp != '>') cp++; *cp = '\0'; /* If the default buffer is too small make it big enough. * * This should always give enough space. The maximum double * is approximately 1.8*10^308 this means we could need 310 * characters plus the precision. We'll use 320 to give some * extra buffer space. The initial buffers size should work * for most cases, but to be safe we add the precision to * the maximum size (think %6.300f when passed 1.2*10^308). */ size = width + 1; if (size < 320) size = 320; size += prec; if (size > ini_size) result = realloc(result, size*sizeof(char)); #if !defined(__GNUC__) if (isnan(value.value.real)) sprintf(result, "%s", "nan"); else sprintf(result, fmtb+1, value.value.real); #else sprintf(result, fmtb+1, value.value.real); #endif size = strlen(result) + 1; } } break; /* This Verilog format specifier is not currently supported! * vpiCell and vpiLibrary need to be implemented first. */ case 'l': case 'L': vpi_printf("WARNING: %s:%d: %%%c currently unsupported %s%s.\n", info->filename, info->lineno, fmt, info->name, fmtb); break; case 'm': case 'M': if (plus != 0 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } /* If a width was not given, use a width of zero. */ if (width == -1) width = 0; { char *cp = vpi_get_str(vpiFullName, info->scope); /* If the default buffer is too small, make it big enough. */ size = strlen(cp) + 1; if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); if (ljust == 0) sprintf(result, "%*s", width, cp); else sprintf(result, "%-*s", width, cp); } size = strlen(result) + 1; break; case 's': case 'S': /* Strings are not numeric and are not zero filled, so %08s => %8s. */ *idx += 1; if (plus != 0 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiStringVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { if (width == -1) { /* If all we have is a leading zero then we want a zero width. */ if (ld_zero == 1) width = 0; /* Otherwise if a width was not given, use the value width. */ else width = (vpi_get(vpiSize, info->items[*idx])+7) / 8; } /* If the default buffer is too small make it big enough. */ size = strlen(value.value.str) + 1; if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); if (ljust == 0) sprintf(result, "%*s", width, value.value.str); else sprintf(result, "%-*s", width, value.value.str); size = strlen(result) + 1; } } break; case 't': case 'T': *idx += 1; if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { PLI_INT32 type; /* Get the argument type and value. */ type = vpi_get(vpiType, info->items[*idx]); if (((type == vpiConstant || type == vpiParameter) && vpi_get(vpiConstType, info->items[*idx]) == vpiRealConst) || type == vpiRealVar || (type == vpiSysFuncCall && vpi_get(vpiFuncType, info->items[*idx]) == vpiRealFunc)) { value.format = vpiRealVal; } else { value.format = vpiDecStrVal; } vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { char *tbuf, *prev_suff = 0; PLI_INT32 time_units = vpi_get(vpiTimeUnit, info->scope); if (plus != 0) { /* Icarus-specific extension to print out time units. * It is needed by vhdlpp to correctly implement time'image(). */ PLI_INT32 time_prec = vpi_get(vpiTimePrecision, info->scope); /* We are about to override the suffix string set with $timeformat(), * therefore we need to restore it after the call. */ prev_suff = timeformat_info.suff; if (time_units < -12) timeformat_info.suff = strdup(" fs"); else if (time_units < -9) timeformat_info.suff = strdup(" ps"); else if (time_units < -6) timeformat_info.suff = strdup(" ns"); else if (time_units < -3) timeformat_info.suff = strdup(" us"); else if (time_units < 0) timeformat_info.suff = strdup(" ms"); else timeformat_info.suff = strdup(" s"); /* Adjust shift for get_time(), so the number indeed matches the unit */ time_units += (3 + (time_units % 3)) % 3 + (time_prec - time_units); } unsigned swidth, free_flag = 0; unsigned suff_len = strlen(timeformat_info.suff); char *cp; /* The 512 (513-1 for EOL) is more than enough for any double * value (309 digits plus a decimal point maximum). Because of * scaling this could be larger. For decimal values you can * have an arbitrary value so you can overflow the buffer, but * for now we will assume the user will use this as intended * (pass a time variable or the result of a time function). */ tbuf = malloc((513+suff_len)*sizeof(char)); if (prec == -1) prec = timeformat_info.prec; if (value.format == vpiRealVal) { get_time_real(tbuf, value.value.real, prec, time_units); } else { get_time(tbuf, value.value.str, prec, time_units); } cp = tbuf; swidth = strlen(tbuf); if (plus != 0) { /* Restore the previous suffix string, overridden by * a vhdlpp-specific $sformatf() call. */ free(timeformat_info.suff); timeformat_info.suff = prev_suff; } if (ld_zero == 1) { /* No leading zeros are created by this conversion so just make * the width 0 for this case. */ if (width == -1) width = 0; /* Pad with leading zeros. */ else if (ljust == 0 && (signed)swidth < width) { unsigned pad = (unsigned)width - swidth; cp = malloc((width+1)*sizeof(char)); memset(cp, '0', pad); strcpy(cp+pad, tbuf); free_flag = 1; } } if (width == -1) width = timeformat_info.width; /* If the default buffer is too small make it big enough. */ size = strlen(tbuf) + 1; if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); if (ljust == 0) sprintf(result, "%*s", width, cp); else sprintf(result, "%-*s", width, cp); if (free_flag) free(cp); free(tbuf); size = strlen(result) + 1; } } break; case 'u': case 'U': *idx += 1; if (ljust != 0 || plus != 0 || ld_zero != 0 || width != -1 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiVectorVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { PLI_INT32 veclen, word, byte; char *cp; veclen = (vpi_get(vpiSize, info->items[*idx])+31)/32; size = veclen * 4 + 1; /* If the default buffer is too small, make it big enough. */ if (size > ini_size) result = realloc(result, size*sizeof(char)); cp = result; for (word = 0; word < veclen; word += 1) { PLI_INT32 bits = value.value.vector[word].aval & ~value.value.vector[word].bval; #ifdef WORDS_BIGENDIAN for (byte = 3; byte >= 0; byte -= 1) { #else for (byte = 0; byte <= 3; byte += 1) { #endif *cp = (bits >> byte*8) & 0xff; cp += 1; } } *cp = '\0'; } } /* size is defined above! We can't use strlen here since this can * be a binary string (can contain NULLs). */ break; case 'v': case 'V': *idx += 1; if (plus != 0 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiStrengthVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { char tbuf[4], *rbuf; PLI_INT32 nbits; int bit; /* If a width was not given use a width of zero. */ if (width == -1) width = 0; nbits = vpi_get(vpiSize, info->items[*idx]); /* This is 4 chars for all but the last bit (strength + "_") * which only needs three chars (strength), but then you need * space for the EOS '\0', so it is just number of bits * 4. */ size = nbits*4; rbuf = malloc(size*sizeof(char)); if ((signed)size < (width+1)) size = width+1; if (size > ini_size) result = realloc(result, size*sizeof(char)); strcpy(rbuf, ""); for (bit = nbits-1; bit >= 0; bit -= 1) { vpip_format_strength(tbuf, &value, bit); strcat(rbuf, tbuf); if (bit > 0) strcat(rbuf, "_"); } if (ljust == 0) sprintf(result, "%*s", width, rbuf); else sprintf(result, "%-*s", width, rbuf); free(rbuf); size = strlen(result) + 1; } } break; case 'z': case 'Z': *idx += 1; size = strlen(result) + 1; /* fallback value if errors */ if (ljust != 0 || plus != 0 || ld_zero != 0 || width != -1 || prec != -1) { vpi_printf("WARNING: %s:%d: invalid format %s%s.\n", info->filename, info->lineno, info->name, fmtb); } if (*idx >= info->nitems) { vpi_printf("WARNING: %s:%d: missing argument for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { value.format = vpiVectorVal; vpi_get_value(info->items[*idx], &value); if (value.format == vpiSuppressVal) { vpi_printf("WARNING: %s:%d: incompatible value for %s%s.\n", info->filename, info->lineno, info->name, fmtb); } else { PLI_INT32 veclen, word, elem, bits, byte; char *cp; veclen = (vpi_get(vpiSize, info->items[*idx])+31)/32; size = 2 * veclen * 4 + 1; /* If the default buffer is too small, make it big enough. */ if (size > ini_size) result = realloc(result, size*sizeof(char)); cp = result; for (word = 0; word < veclen; word += 1) { /* Write the aval followed by the bval in endian order. */ for (elem = 0; elem < 2; elem += 1) { bits = *(&value.value.vector[word].aval+elem); #ifdef WORDS_BIGENDIAN for (byte = 3; byte >= 0; byte -= 1) { #else for (byte = 0; byte <= 3; byte += 1) { #endif *cp = (bits >> byte*8) & 0xff; cp += 1; } } } *cp = '\0'; } } /* size is defined above! We can't use strlen here since this can * be a binary string (can contain NULLs). */ break; default: vpi_printf("WARNING: %s:%d: unknown format %s%s.\n", info->filename, info->lineno, info->name, fmtb); size = strlen(result) + 1; break; } free(fmtb); /* We can't use strdup here since %u and %z can insert NULL * characters into the stream. */ *rtn = malloc(size*sizeof(char)); memcpy(*rtn, result, size); free(result); return size - 1; } /* We can't use the normal str functions on the return value since * %u and %z can insert NULL characters into the stream. */ static unsigned int get_format(char **rtn, char *fmt, const struct strobe_cb_info *info, unsigned int *idx) { char *cp = fmt; unsigned int size; *rtn = strdup(""); size = 1; while (*cp) { size_t cnt = strcspn(cp, "%"); if (cnt > 0) { *rtn = realloc(*rtn, (size+cnt)*sizeof(char)); memcpy(*rtn+size-1, cp, cnt); size += cnt; cp += cnt; } else { int ljust = 0, plus = 0, ld_zero = 0, width = -1, prec = -1; char *result; cp += 1; while ((*cp == '-') || (*cp == '+')) { if (*cp == '-') ljust = 1; else plus = 1; cp += 1; } if (*cp == '0') { ld_zero = 1; cp += 1; } if (isdigit((int)*cp)) width = strtoul(cp, &cp, 10); if (*cp == '.') { cp += 1; prec = strtoul(cp, &cp, 10); } cnt = get_format_char(&result, ljust, plus, ld_zero, width, prec, *cp, info, idx); *rtn = realloc(*rtn, (size+cnt)*sizeof(char)); memcpy(*rtn+size-1, result, cnt); free(result); size += cnt; if (*cp) cp += 1; } } *(*rtn+size-1) = '\0'; return size - 1; } static unsigned int get_numeric(char **rtn, const struct strobe_cb_info *info, vpiHandle item) { int size, min; s_vpi_value val; val.format = info->default_format; vpi_get_value(item, &val); switch(info->default_format){ case vpiDecStrVal: size = vpi_get_dec_size(item); /* -1 can be represented as a one bit signed value. This returns * a size of 1 which is too small for the -1 string value so make * the string width the minimum display width. */ min = strlen(val.value.str); if (size < min) size = min; *rtn = malloc((size+1)*sizeof(char)); sprintf(*rtn, "%*s", size, val.value.str); break; default: *rtn = strdup(val.value.str); } return strlen(*rtn); } /* In many places we can't use the normal str functions since %u and %z * can insert NULL characters into the stream. */ static char *get_display(unsigned int *rtnsz, const struct strobe_cb_info *info) { char *result, *fmt, *rtn, *func_name; const char *cresult; s_vpi_value value; unsigned int idx, size, width; char buf[256]; rtn = strdup(""); size = 1; for (idx = 0; idx < info->nitems; idx += 1) { vpiHandle item = info->items[idx]; switch (vpi_get(vpiType, item)) { case vpiConstant: case vpiParameter: if (vpi_get(vpiConstType, item) == vpiStringConst) { value.format = vpiStringVal; vpi_get_value(item, &value); fmt = strdup(value.value.str); width = get_format(&result, fmt, info, &idx); free(fmt); } else if (vpi_get(vpiConstType, item) == vpiRealConst) { value.format = vpiRealVal; vpi_get_value(item, &value); #if !defined(__GNUC__) if (compatible_flag) sprintf(buf, "%g", value.value.real); else { if (value.value.real == 0.0 || value.value.real == -0.0) sprintf(buf, "%.05f", value.value.real); else sprintf(buf, "%#g", value.value.real); } #else sprintf(buf, compatible_flag ? "%g" : "%#g", value.value.real); #endif result = strdup(buf); width = strlen(result); } else { width = get_numeric(&result, info, item); } rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, result, width); free(result); break; case vpiNet: case vpiReg: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiIntegerVar: case vpiMemoryWord: case vpiPartSelect: width = get_numeric(&result, info, item); rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, result, width); free(result); break; /* It appears that this is not currently used! A time variable is passed as an integer and processed above. Hence this code has only been visually checked. */ case vpiTimeVar: value.format = vpiDecStrVal; vpi_get_value(item, &value); get_time(buf, value.value.str, timeformat_info.prec, vpi_get(vpiTimeUnit, info->scope)); width = strlen(buf); if (width < timeformat_info.width) width = timeformat_info.width; rtn = realloc(rtn, (size+width)*sizeof(char)); sprintf(rtn+size-1, "%*s", width, buf); break; /* Realtime variables are also processed here. */ case vpiRealVar: value.format = vpiRealVal; vpi_get_value(item, &value); #if !defined(__GNUC__) if (compatible_flag) sprintf(buf, "%g", value.value.real); else { if (value.value.real == 0.0 || value.value.real == -0.0) sprintf(buf, "%.05f", value.value.real); else sprintf(buf, "%#g", value.value.real); } #else sprintf(buf, compatible_flag ? "%g" : "%#g", value.value.real); #endif width = strlen(buf); rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, buf, width); break; /* Process string variables like string constants: interpret the contained strings like format strings. */ case vpiStringVar: value.format = vpiStringVal; vpi_get_value(item, &value); fmt = strdup(value.value.str); width = get_format(&result, fmt, info, &idx); free(fmt); rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, result, width); free(result); break; case vpiSysFuncCall: func_name = vpi_get_str(vpiName, item); if (strcmp(func_name, "$time") == 0) { value.format = vpiDecStrVal; vpi_get_value(item, &value); width = strlen(value.value.str); if (width < 20) width = 20; rtn = realloc(rtn, (size+width)*sizeof(char)); sprintf(rtn+size-1, "%*s", width, value.value.str); } else if (strcmp(func_name, "$stime") == 0) { value.format = vpiDecStrVal; vpi_get_value(item, &value); width = strlen(value.value.str); if (width < 10) width = 10; rtn = realloc(rtn, (size+width)*sizeof(char)); sprintf(rtn+size-1, "%*s", width, value.value.str); } else if (strcmp(func_name, "$simtime") == 0) { value.format = vpiDecStrVal; vpi_get_value(item, &value); width = strlen(value.value.str); if (width < 20) width = 20; rtn = realloc(rtn, (size+width)*sizeof(char)); sprintf(rtn+size-1, "%*s", width, value.value.str); } else if (strcmp(func_name, "$realtime") == 0) { /* Use the local scope precision. */ int use_prec = vpi_get(vpiTimeUnit, info->scope) - vpi_get(vpiTimePrecision, info->scope); assert(use_prec >= 0); value.format = vpiRealVal; vpi_get_value(item, &value); sprintf(buf, "%.*f", use_prec, value.value.real); width = strlen(buf); rtn = realloc(rtn, (size+width)*sizeof(char)); sprintf(rtn+size-1, "%*s", width, buf); } else { vpi_printf("WARNING: %s:%d: %s does not support %s as an argument!\n", info->filename, info->lineno, info->name, func_name); strcpy(buf, ""); width = strlen(buf); rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, buf, width); } break; default: vpi_printf("WARNING: %s:%d: unknown argument type (%s) given to %s!\n", info->filename, info->lineno, vpi_get_str(vpiType, item), info->name); cresult = ""; width = strlen(cresult); rtn = realloc(rtn, (size+width)*sizeof(char)); memcpy(rtn+size-1, cresult, width); break; } size += width; } rtn[size-1] = '\0'; *rtnsz = size - 1; return rtn; } #ifdef BR916_STOPGAP_FIX static char br916_hint_issued = 0; #endif static int sys_check_args(vpiHandle callh, vpiHandle argv, const PLI_BYTE8*name, int no_auto, int is_monitor) { vpiHandle arg; int ret = 0; /* If there are no arguments, just return. */ if (argv == 0) return ret; for (arg = vpi_scan(argv); arg; arg = vpi_scan(argv)) { if (no_auto && vpi_get(vpiAutomatic, arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s argument \"%s\" is an automatic variable.\n", name, vpi_get_str(vpiName, arg)); ret = 1; } switch (vpi_get(vpiType, arg)) { case vpiMemoryWord: case vpiPartSelect: if (is_monitor && vpi_get(vpiConstantSelect, arg) == 0) { vpi_printf("SORRY: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s must have a constant %s select.\n", name, vpi_get_str(vpiType, arg)); ret = 1; } // fallthrough case vpiConstant: case vpiParameter: case vpiNet: case vpiReg: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: case vpiRealVar: case vpiStringVar: #ifdef BR916_STOPGAP_FIX // no_auto implies either $strobe or $monitor if (no_auto) { switch (vpi_get(_vpiFromThr, arg)) { case _vpiVThr: case _vpiWord: case _vpiString: vpi_printf("SORRY: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("currently only simple signals or constant " "expressions may be passed to %s.\n", name); if (!br916_hint_issued) { vpi_printf("NOTE: You can work around this by " "assigning the desired expression " "to an\n" " intermediate net (using a " "continuous assignment) and passing " "that net\n" " to %s.\n", name); br916_hint_issued = 1; } ret = 2; default: break; } } #endif case vpiClassVar: case vpiSysFuncCall: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s does not support argument type (%s).\n", name, vpi_get_str(vpiType, arg)); ret = 1; break; } } return ret; } /* Common compiletf routine. */ static PLI_INT32 sys_common_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name, int no_auto, int is_monitor) { vpiHandle callh, argv; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); if (name[1] == 'f') { /* Check that there is a fd/mcd and that it is numeric. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least a file descriptor/MCD.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's file descriptor/MCD must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } int rtn = sys_check_args(callh, argv, name, no_auto, is_monitor); if (rtn) { if (rtn==1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } /* Check the $display, $write, $fdisplay and $fwrite based tasks. */ static PLI_INT32 sys_display_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { /* These tasks can have automatic variables and are not monitor. */ return sys_common_compiletf(name, 0, 0); } /* This implements the $sformatf, $display/$fdisplay * and the $write/$fwrite based tasks. */ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, scope; struct strobe_cb_info info; char* result; unsigned int size; PLI_UINT32 fd_mcd; s_vpi_value val; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); /* Get the file/MC descriptor and verify it is valid. */ if (name[1] == 'f') { vpiHandle fd = vpi_scan(argv); if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) { vpi_free_object(argv); return 0; } } else if (strncmp(name, "$sformatf", 9) == 0) { /* return as a string */ fd_mcd = 0; } else { /* stdout */ fd_mcd = 1; } scope = vpi_handle(vpiScope, callh); assert(scope); /* We could use vpi_get_str(vpiName, callh) to get the task name, * but name is already defined. */ info.name = name; info.filename = strdup(vpi_get_str(vpiFile, callh)); info.lineno = (int)vpi_get(vpiLineNo, callh); info.default_format = get_default_format(name); info.scope = scope; array_from_iterator(&info, argv); /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, &info); if (fd_mcd > 0) { my_mcd_rawwrite(fd_mcd, result, size); if ((strncmp(name,"$display",8) == 0) || (strncmp(name,"$fdisplay",9) == 0)) my_mcd_rawwrite(fd_mcd, "\n", 1); } else { /* Return as a string ($sformatf) */ val.format = vpiStringVal; val.value.str = result; vpi_put_value(callh, &val, 0, vpiNoDelay); } free(result); free(info.filename); free(info.items); return 0; } /* * The strobe implementation takes the parameter handles that are * passed to the calltf and puts them in to an array for safe * keeping. That array (and other bookkeeping) is passed, via the * struct_cb_info object, to the REadOnlySych function strobe_cb, * where it is used to perform the actual formatting and printing. */ static PLI_INT32 strobe_cb(p_cb_data cb) { struct strobe_cb_info*info = (struct strobe_cb_info*)cb->user_data; /* We really need to cancel any $fstrobe() calls for a file when it * is closed, but for now we will just skip processing the result. * Which has the same basic effect. */ if (is_valid_fd_mcd(info->fd_mcd)) { char* result; unsigned int size; /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, info); my_mcd_rawwrite(info->fd_mcd, result, size); my_mcd_rawwrite(info->fd_mcd, "\n", 1); free(result); } free(info->filename); free(info->items); free(info); return 0; } /* Check both the $strobe and $fstrobe based tasks. */ static PLI_INT32 sys_strobe_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { /* These tasks can not have automatic variables and are not monitor. */ return sys_common_compiletf(name, 1, 0); } /* This implements both the $strobe and $fstrobe based tasks. */ static PLI_INT32 sys_strobe_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh, argv, scope; struct t_cb_data cb; struct t_vpi_time timerec; struct strobe_cb_info*info; PLI_UINT32 fd_mcd; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); /* Get the file/MC descriptor and verify it is valid. */ if (name[1] == 'f') { vpiHandle fd = vpi_scan(argv); if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) { vpi_free_object(argv); return 0; } } else { fd_mcd = 1; } scope = vpi_handle(vpiScope, callh); assert(scope); info = calloc(1, sizeof(struct strobe_cb_info)); info->fd_mcd = fd_mcd; /* We could use vpi_get_str(vpiName, callh) to get the task name, * but name is already defined. */ info->name = name; info->filename = strdup(vpi_get_str(vpiFile, callh)); info->lineno = (int)vpi_get(vpiLineNo, callh); info->default_format = get_default_format(name); info->scope= scope; array_from_iterator(info, argv); timerec.type = vpiSimTime; timerec.low = 0; timerec.high = 0; cb.reason = cbReadOnlySynch; cb.cb_rtn = strobe_cb; cb.time = &timerec; cb.obj = 0; cb.value = 0; cb.user_data = (char*)info; vpi_register_cb(&cb); return 0; } /* * The $monitor system task works by managing these static variables, * and the cbValueChange callbacks associated with registers and * nets. Note that it is proper to keep the state in static variables * because there can only be one monitor at a time pending (even * though that monitor may be watching many variables). */ static struct strobe_cb_info monitor_info = { 0, 0, 0, 0, 0, 0, 0, 0 }; static vpiHandle *monitor_callbacks = 0; static int monitor_scheduled = 0; static int monitor_enabled = 1; static PLI_INT32 monitor_cb_2(p_cb_data cb) { char* result; unsigned int size; (void)cb; /* Parameter is not used. */ /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, &monitor_info); my_mcd_rawwrite(monitor_info.fd_mcd, result, size); my_mcd_rawwrite(monitor_info.fd_mcd, "\n", 1); monitor_scheduled = 0; free(result); return 0; } /* * The monitor_cb_1 callback is called when an event occurs somewhere * in the simulation. All this function does is schedule the actual * display to occur in a ReadOnlySync callback. The monitor_scheduled * flag is used to allow only one monitor strobe to be scheduled. */ static PLI_INT32 monitor_cb_1(p_cb_data cause) { struct t_cb_data cb; struct t_vpi_time timerec; (void)cause; /* Parameter is not used. */ if (monitor_enabled == 0) return 0; if (monitor_scheduled) return 0; /* This this action caused the first trigger, then schedule the monitor to happen at the end of the time slice and mark it as scheduled. */ monitor_scheduled += 1; timerec.type = vpiSimTime; timerec.low = 0; timerec.high = 0; cb.reason = cbReadOnlySynch; cb.cb_rtn = monitor_cb_2; cb.time = &timerec; cb.obj = 0; cb.value = 0; vpi_register_cb(&cb); return 0; } static PLI_INT32 sys_monitor_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); int rtn = sys_check_args(callh, argv, name, 1, 1); if (rtn) { if (rtn == 1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_monitor_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh, argv, scope; unsigned idx; struct t_cb_data cb; struct t_vpi_time timerec; (void)name; /* Parameter is not used. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); /* If there was a previous $monitor, then remove the callbacks related to it. */ if (monitor_callbacks) { for (idx = 0 ; idx < monitor_info.nitems ; idx += 1) if (monitor_callbacks[idx]) vpi_remove_cb(monitor_callbacks[idx]); free(monitor_callbacks); monitor_callbacks = 0; free(monitor_info.filename); free(monitor_info.items); monitor_info.items = 0; monitor_info.nitems = 0; monitor_info.name = 0; } scope = vpi_handle(vpiScope, callh); assert(scope); /* Make an array of handles from the argument list. */ array_from_iterator(&monitor_info, argv); monitor_info.name = name; monitor_info.filename = strdup(vpi_get_str(vpiFile, callh)); monitor_info.lineno = (int)vpi_get(vpiLineNo, callh); monitor_info.default_format = get_default_format(name); monitor_info.scope = scope; monitor_info.fd_mcd = 1; /* Attach callbacks to all the parameters that might change. */ monitor_callbacks = calloc(monitor_info.nitems, sizeof(vpiHandle)); timerec.type = vpiSuppressTime; cb.reason = cbValueChange; cb.cb_rtn = monitor_cb_1; cb.time = &timerec; cb.value = NULL; for (idx = 0 ; idx < monitor_info.nitems ; idx += 1) { switch (vpi_get(vpiType, monitor_info.items[idx])) { case vpiMemoryWord: /* * We only support constant selections. Make this * better when we add a real compiletf routine. */ assert(vpi_get(vpiConstantSelect, monitor_info.items[idx])); case vpiNet: case vpiReg: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiRealVar: case vpiPartSelect: /* Monitoring reg and net values involves setting a callback for value changes. Pass the storage pointer for the callback itself as user_data so that the callback can refresh itself. */ cb.user_data = (char*)(monitor_callbacks+idx); cb.obj = monitor_info.items[idx]; monitor_callbacks[idx] = vpi_register_cb(&cb); break; } } /* When the $monitor is called, it schedules a first display for the end of the current time, like a $strobe. */ monitor_cb_1(0); return 0; } static PLI_INT32 sys_monitoron_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ monitor_enabled = 1; monitor_cb_1(0); return 0; } static PLI_INT32 sys_monitoroff_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ monitor_enabled = 0; return 0; } static PLI_INT32 sys_swrite_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; PLI_INT32 type; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least one argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a register or a SV string. */ arg = vpi_scan(argv); /* This should never be zero. */ type = vpi_get(vpiType, arg); if (type != vpiReg && type != vpiStringVar) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a register or SV string.\n", name); vpi_control(vpiFinish, 1); return 0; } int rtn = sys_check_args(callh, argv, name, 0, 0); if (rtn) { if (rtn == 1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_swrite_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, reg, scope; struct strobe_cb_info info; s_vpi_value val; unsigned int size; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); reg = vpi_scan(argv); scope = vpi_handle(vpiScope, callh); assert(scope); /* We could use vpi_get_str(vpiName, callh) to get the task name, but * name is already defined. */ info.name = name; info.filename = strdup(vpi_get_str(vpiFile, callh)); info.lineno = (int)vpi_get(vpiLineNo, callh); info.default_format = get_default_format(name); info.scope = scope; array_from_iterator(&info, argv); /* Because %u and %z may put embedded NULL characters into the returned * string strlen() may not match the real size! */ val.value.str = get_display(&size, &info); val.format = vpiStringVal; vpi_put_value(reg, &val, 0, vpiNoDelay); if (size != strlen(val.value.str)) { vpi_printf("WARNING: %s:%d: %s returned a value with an embedded NULL " "(see %%u/%%z).\n", info.filename, info.lineno, name); } free(val.value.str); free(info.filename); free(info.items); return 0; } static PLI_INT32 sys_sformat_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; PLI_INT32 type; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a register or a SV string. */ arg = vpi_scan(argv); /* This should never be zero. */ type = vpi_get(vpiType, arg); if (type != vpiReg && type != vpiStringVar) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a register or SV string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The second argument must be a string, a register or a SV string. */ arg = vpi_scan(argv); if (arg == 0) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } type = vpi_get(vpiType, arg); if (((type != vpiConstant && type != vpiParameter) || vpi_get(vpiConstType, arg) != vpiStringConst) && type != vpiReg && type != vpiStringVar) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be a string or a register.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } int rtn = sys_check_args(callh, argv, name, 0, 0); if (rtn) { if (rtn == 1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_sformat_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, reg, scope; struct strobe_cb_info info; s_vpi_value val; char *result, *fmt; unsigned int idx, size; callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); reg = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(vpi_scan(argv), &val); fmt = strdup(val.value.str); scope = vpi_handle(vpiScope, callh); assert(scope); /* We could use vpi_get_str(vpiName, callh) to get the task name, but * name is already defined. */ info.name = name; info.filename = strdup(vpi_get_str(vpiFile, callh)); info.lineno = (int)vpi_get(vpiLineNo, callh); info.default_format = get_default_format(name); info.scope = scope; array_from_iterator(&info, argv); idx = -1; size = get_format(&result, fmt, &info, &idx); free(fmt); if (idx+1< info.nitems) { vpi_printf("WARNING: %s:%d: %s has %d extra argument(s).\n", info.filename, info.lineno, name, info.nitems-idx-1); } val.value.str = result; val.format = vpiStringVal; vpi_put_value(reg, &val, 0, vpiNoDelay); if (size != strlen(val.value.str)) { vpi_printf("WARNING: %s:%d: %s returned a value with an embedded NULL " "(see %%u/%%z).\n", info.filename, info.lineno, name); } free(val.value.str); free(info.filename); free(info.items); return 0; } static PLI_INT32 sys_sformatf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; PLI_INT32 type; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least one argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a string, a register or a SV string. */ arg = vpi_scan(argv); if (arg == 0) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least one argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } type = vpi_get(vpiType, arg); if (((type != vpiConstant && type != vpiParameter) || vpi_get(vpiConstType, arg) != vpiStringConst) && type != vpiReg && type != vpiStringVar) { vpi_printf("ERROR:%s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a string or a register.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } int rtn = sys_check_args(callh, argv, name, 0, 0); if (rtn) { if (rtn == 1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_end_of_compile(p_cb_data cb_data) { (void)cb_data; /* Parameter is not used. */ /* The default timeformat prints times in unit of simulation precision. */ free(timeformat_info.suff); timeformat_info.suff = strdup(""); timeformat_info.units = vpi_get(vpiTimePrecision, 0); timeformat_info.prec = 0; timeformat_info.width = 20; return 0; } static PLI_INT32 sys_timeformat_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); if (argv) { vpiHandle arg; /* Check that the unit argument is numeric. */ if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's units argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the precision argument is given and is numeric. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires zero or four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's precision argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the suffix argument is given and is a string. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires zero or four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's suffix argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the min. width argument is given and is numeric. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires zero or four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's minimum width argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 0); } return 0; } static PLI_INT32 sys_timeformat_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_value value; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); (void)name; /* Parameter is not used. */ if (argv) { vpiHandle units = vpi_scan(argv); vpiHandle prec = vpi_scan(argv); vpiHandle suff = vpi_scan(argv); vpiHandle wid = vpi_scan(argv); vpi_free_object(argv); value.format = vpiIntVal; vpi_get_value(units, &value); timeformat_info.units = value.value.integer; value.format = vpiIntVal; vpi_get_value(prec, &value); timeformat_info.prec = value.value.integer; value.format = vpiStringVal; vpi_get_value(suff, &value); free(timeformat_info.suff); timeformat_info.suff = strdup(value.value.str); value.format = vpiIntVal; vpi_get_value(wid, &value); timeformat_info.width = value.value.integer; } else { /* If no arguments are given then use the default values. */ sys_end_of_compile(NULL); } return 0; } static const char *pts_convert(int value) { const char *string; switch (value) { case 2: string = "100s"; break; case 1: string = "10s"; break; case 0: string = "1s"; break; case -1: string = "100ms"; break; case -2: string = "10ms"; break; case -3: string = "1ms"; break; case -4: string = "100us"; break; case -5: string = "10us"; break; case -6: string = "1us"; break; case -7: string = "100ns"; break; case -8: string = "10ns"; break; case -9: string = "1ns"; break; case -10: string = "100ps"; break; case -11: string = "10ps"; break; case -12: string = "1ps"; break; case -13: string = "100fs"; break; case -14: string = "10fs"; break; case -15: string = "1fs"; break; default: string = "invalid"; assert(0); } return string; } static PLI_INT32 sys_printtimescale_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); if (argv) { vpiHandle arg = vpi_scan(argv); switch (vpi_get(vpiType, arg)) { case vpiFunction: case vpiGenScope: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemory: case vpiMemoryWord: case vpiModule: case vpiNamedBegin: case vpiNamedEvent: case vpiNamedFork: case vpiNet: case vpiNetArray: // case vpiNetBit: // Unused and unavailable in Icarus case vpiParameter: case vpiPartSelect: case vpiRealVar: case vpiReg: // case vpiRegBit: // Unused and unavailable in Icarus case vpiTask: case vpiTimeVar: // Unused in Icarus break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument must have a module, given a %s.\n", name, vpi_get_str(vpiType, arg)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "one argument", 1); } return 0; } static PLI_INT32 sys_printtimescale_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item, scope; (void)name; /* Parameter is not used. */ if (!argv) { item = sys_func_module(callh); } else { item = vpi_scan(argv); vpi_free_object(argv); } scope = sys_func_module(item); vpi_printf("Time scale of (%s) is ", vpi_get_str(vpiFullName, item)); vpi_printf("%s / ", pts_convert(vpi_get(vpiTimeUnit, scope))); vpi_printf("%s\n", pts_convert(vpi_get(vpiTimePrecision, scope))); return 0; } static PLI_INT32 sys_fatal_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); if (argv) { vpiHandle arg = vpi_scan(argv); /* Check that finish_number (1st argument) is numeric */ if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's finish number must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } int rtn = sys_check_args(callh, argv, name, 0, 0); if (rtn) { if (rtn == 1) vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } return 0; } static PLI_INT32 sys_severity_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle scope; struct strobe_cb_info info; struct t_vpi_time now; PLI_UINT64 now64; char *sstr, *t, *dstr; unsigned int size, location=0; s_vpi_value finish_number; /* Set the default finish number for $fatal. */ finish_number.value.integer = 1; /* Check that the finish number is in range. */ if (strncmp(name,"$fatal", 6) == 0 && argv) { vpiHandle arg = vpi_scan(argv); finish_number.format = vpiIntVal; vpi_get_value(arg, &finish_number); if ((finish_number.value.integer < 0) || (finish_number.value.integer > 2)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$fatal called with finish_number of %d, " "but it must be 0, 1, or 2.\n", (int)finish_number.value.integer); finish_number.value.integer = 1; } } /* convert name to upper and drop $ to get severity string */ sstr = strdup(name) + 1; for (t=sstr; *t; t+=1) *t = toupper((int)*t); scope = vpi_handle(vpiScope, callh); assert(scope); info.name = name; info.filename = strdup(vpi_get_str(vpiFile, callh)); info.lineno = (int)vpi_get(vpiLineNo, callh); info.default_format = vpiDecStrVal; info.scope = scope; array_from_iterator(&info, argv); vpi_printf("%s: %s:%d: ", sstr, info.filename, info.lineno); dstr = get_display(&size, &info); while (location < size) { if (dstr[location] == '\0') { my_mcd_printf(1, "%c", '\0'); location += 1; } else { my_mcd_printf(1, "%s", &dstr[location]); location += strlen(&dstr[location]); } } now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); vpi_printf("\n%*s Time: %" PLI_UINT64_FMT " Scope: %s\n", (int)strlen(sstr), " ", now64, vpi_get_str(vpiFullName, scope)); free(--sstr); /* Get the $ back. */ free(info.filename); free(info.items); free(dstr); if (strncmp(name,"$fatal",6) == 0) { /* Set the exit code from vvp as an error code. */ vpip_set_return_value(1); /* Now tell the simulator to finish. */ vpi_control(vpiFinish, finish_number.value.integer); } return 0; } static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) { (void)cb_data; /* Parameter is not used. */ free(monitor_callbacks); monitor_callbacks = 0; free(monitor_info.filename); free(monitor_info.items); monitor_info.items = 0; monitor_info.nitems = 0; monitor_info.name = 0; free(timeformat_info.suff); timeformat_info.suff = 0; return 0; } void sys_display_register(void) { s_cb_data cb_data; s_vpi_systf_data tf_data; vpiHandle res; check_command_line_args(); /*============================== display */ tf_data.type = vpiSysTask; tf_data.tfname = "$display"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$display"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$displayh"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$displayh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$displayo"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$displayo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$displayb"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$displayb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== write */ tf_data.type = vpiSysTask; tf_data.tfname = "$write"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$write"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$writeh"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$writeh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$writeo"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$writeo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$writeb"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$writeb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== strobe */ tf_data.type = vpiSysTask; tf_data.tfname = "$strobe"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$strobe"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$strobeh"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$strobeh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$strobeo"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$strobeo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$strobeb"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$strobeb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fstrobe */ tf_data.type = vpiSysTask; tf_data.tfname = "$fstrobe"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstrobe"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fstrobeh"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstrobeh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fstrobeo"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstrobeo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fstrobeb"; tf_data.calltf = sys_strobe_calltf; tf_data.compiletf = sys_strobe_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstrobeb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== monitor */ tf_data.type = vpiSysTask; tf_data.tfname = "$monitor"; tf_data.calltf = sys_monitor_calltf; tf_data.compiletf = sys_monitor_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitor"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$monitorh"; tf_data.calltf = sys_monitor_calltf; tf_data.compiletf = sys_monitor_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitorh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$monitoro"; tf_data.calltf = sys_monitor_calltf; tf_data.compiletf = sys_monitor_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitoro"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$monitorb"; tf_data.calltf = sys_monitor_calltf; tf_data.compiletf = sys_monitor_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitorb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$monitoron"; tf_data.calltf = sys_monitoron_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitoron"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$monitoroff"; tf_data.calltf = sys_monitoroff_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$monitoroff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fdisplay */ tf_data.type = vpiSysTask; tf_data.tfname = "$fdisplay"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fdisplay"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fdisplayh"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fdisplayh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fdisplayo"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fdisplayo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fdisplayb"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fdisplayb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fwrite */ tf_data.type = vpiSysTask; tf_data.tfname = "$fwrite"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fwrite"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fwriteh"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fwriteh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fwriteo"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fwriteo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$fwriteb"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fwriteb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== swrite */ tf_data.type = vpiSysTask; tf_data.tfname = "$swrite"; tf_data.calltf = sys_swrite_calltf; tf_data.compiletf = sys_swrite_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$swrite"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$swriteh"; tf_data.calltf = sys_swrite_calltf; tf_data.compiletf = sys_swrite_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$swriteh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$swriteo"; tf_data.calltf = sys_swrite_calltf; tf_data.compiletf = sys_swrite_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$swriteo"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$swriteb"; tf_data.calltf = sys_swrite_calltf; tf_data.compiletf = sys_swrite_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$swriteb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$sformat"; tf_data.calltf = sys_sformat_calltf; tf_data.compiletf = sys_sformat_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$sformat"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiStringFunc; tf_data.tfname = "$sformatf"; tf_data.calltf = sys_display_calltf; tf_data.compiletf = sys_sformatf_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$sformatf"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================ timeformat */ tf_data.type = vpiSysTask; tf_data.tfname = "$timeformat"; tf_data.calltf = sys_timeformat_calltf; tf_data.compiletf = sys_timeformat_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$timeformat"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$printtimescale"; tf_data.calltf = sys_printtimescale_calltf; tf_data.compiletf = sys_printtimescale_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$printtimescale"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================ severity tasks */ tf_data.type = vpiSysTask; tf_data.tfname = "$fatal"; tf_data.calltf = sys_severity_calltf; tf_data.compiletf = sys_fatal_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fatal"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$error"; tf_data.calltf = sys_severity_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$error"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$warning"; tf_data.calltf = sys_severity_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$warning"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$info"; tf_data.calltf = sys_severity_calltf; tf_data.compiletf = sys_display_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$info"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); cb_data.reason = cbEndOfCompile; cb_data.time = 0; cb_data.cb_rtn = sys_end_of_compile; cb_data.user_data = "system"; vpi_register_cb(&cb_data); cb_data.reason = cbEndOfSimulation; cb_data.cb_rtn = sys_end_of_simulation; cb_data.user_data = "system"; vpi_register_cb(&cb_data); } iverilog-12_0/vpi/sys_fileio.c000066400000000000000000001133071435245347300164630ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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 "sys_priv.h" # include # include # include # include # include # include # include "ivl_alloc.h" /* * Implement the $fopen system function. */ static PLI_INT32 sys_fopen_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); /* Check that there is a file name argument and that it is a string. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a string file name argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_string_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's file name argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The type argument is optional. */ arg = vpi_scan(argv); if (arg == 0) return 0; /* When provided, the type argument must be a string. */ if (! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's type argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two string arguments", 1); return 0; } static PLI_INT32 sys_fopen_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; int fail = 0; char *mode_string = 0; vpiHandle fileh = vpi_scan(argv); char *fname; vpiHandle mode = vpi_scan(argv); errno = 0; /* Get the mode handle if it exists. */ if (mode) { char *esc_md; val.format = vpiStringVal; vpi_get_value(mode, &val); /* Verify that we have a string and that it is not NULL. */ if (val.format != vpiStringVal || !*(val.value.str)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's mode argument is not a valid string.\n", name); fail = 1; } /* Make sure the mode string is correct. */ if (strlen(val.value.str) > 3) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); esc_md = as_escaped(val.value.str); vpi_printf("%s's mode argument (%s) is too long.\n", name, esc_md); free(esc_md); fail = 1; } else { unsigned bin = 0, plus = 0, idx; switch (val.value.str[0]) { case 'r': case 'w': case 'a': for (idx = 1; idx < 3 ; idx++) { if (val.value.str[idx] == '\0') break; switch (val.value.str[idx]) { case 'b': if (bin) fail = 1; bin = 1; break; case '+': if (plus) fail = 1; plus = 1; break; default: fail = 1; break; } } if (! fail) break; // fallthrough default: vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); esc_md = as_escaped(val.value.str); vpi_printf("%s's mode argument (%s) is invalid.\n", name, esc_md); free(esc_md); fail = 1; break; } } mode_string = strdup(val.value.str); vpi_free_object(argv); } fname = get_filename(callh, name, fileh); /* If either the mode or file name are not valid just return. */ if (fail || fname == 0) { free(fname); if (mode) free(mode_string); return 0; } val.format = vpiIntVal; if (mode) { val.value.integer = vpi_fopen(fname, mode_string); free(mode_string); } else val.value.integer = vpi_mcd_open(fname); vpi_put_value(callh, &val, 0, vpiNoDelay); free(fname); return 0; } /* * Implement the $fopenr(), $fopenw() and $fopena() system functions * from Chris Spear's File I/O for Verilog. */ static PLI_INT32 sys_fopenrwa_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; char *fname; const char *mode; errno = 0; /* Get the mode. */ mode = name + strlen(name) - 1; /* Get the file name. */ fname = get_filename(callh, name, vpi_scan(argv)); vpi_free_object(argv); if (fname == 0) return 0; /* Open the file and return the result. */ val.format = vpiIntVal; val.value.integer = vpi_fopen(fname, mode); vpi_put_value(callh, &val, 0, vpiNoDelay); free(fname); return 0; } /* * Implement $fclose system function */ static PLI_INT32 sys_fclose_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle fd = vpi_scan(argv); PLI_UINT32 fd_mcd; vpi_free_object(argv); /* Get the file/MC descriptor and verify that it is valid. */ if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) return 0; /* We need to cancel any active $fstrobe()'s for this FD/MCD. * For now we check in the strobe callback and skip the output * generation when needed. */ fd_mcd = vpi_mcd_close(fd_mcd); if (fd_mcd) { char *fd_mcd_name; switch(fd_mcd) { case 0x00000001: // MCD STDOUT case 0x80000001: // FD STDOUT fd_mcd_name = "STDOUT "; break; case 0x80000000: // FD STDIN fd_mcd_name = "STDIN "; break; case 0x80000002: // FD STDERR fd_mcd_name = "STDERR "; break; default: fd_mcd_name = ""; } vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("could not close %s %s(0x%x) in %s().\n", IS_MCD(fd_mcd) ? "MCD" : "file descriptor", fd_mcd_name, (unsigned int)fd_mcd, name); } return 0; } /* * Implement $fflush system function */ static PLI_INT32 sys_fflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle fd; PLI_UINT32 fd_mcd; /* If we have no argument then flush all the streams. */ if (argv == 0) { fflush(NULL); return 0; } /* Get the file/MC descriptor and verify that it is valid. */ fd = vpi_scan(argv); vpi_free_object(argv); if (get_fd_mcd_from_arg(&fd_mcd, fd, callh, name)) return 0; if (IS_MCD(fd_mcd)) { vpi_mcd_flush(fd_mcd); } else { fflush(vpi_get_file(fd_mcd)); } return 0; } static PLI_INT32 sys_fputc_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; unsigned char chr; errno = 0; /* Get the character. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); chr = val.value.integer; /* Get the file/MC descriptor. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Put the character and return the result. */ fp = vpi_get_file(fd_mcd); val.format = vpiIntVal; if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.value.integer = EOF; } else { val.value.integer = fputc(chr, fp); if (val.value.integer != EOF) val.value.integer = 0; } vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_fgets_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* * Check that there are two arguments and that the first is a * register and that the second is numeric. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, vpi_scan(argv)) != vpiReg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a reg.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (numeric) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } static PLI_INT32 sys_fgets_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle regh; vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; PLI_INT32 reg_size; char*text; errno = 0; /* Get the register handle. */ regh = vpi_scan(argv); /* Get the file/MCD descriptor. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Return zero if this is not a valid fd. */ fp = vpi_get_file(fd_mcd); if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* Get the register size in bytes and allocate the buffer. */ reg_size = vpi_get(vpiSize, regh) / 8; text = malloc(reg_size + 1); /* Read in the bytes. Return 0 if there was an error. */ if (fgets(text, reg_size+1, fp) == 0) { val.format = vpiIntVal; val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); free(text); return 0; } /* Return the number of character read. */ val.format = vpiIntVal; val.value.integer = strlen(text); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the characters to the register. */ val.format = vpiStringVal; val.value.str = text; vpi_put_value(regh, &val, 0, vpiNoDelay); free(text); return 0; } static PLI_INT32 sys_fread_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; PLI_INT32 type; /* We must have at least two arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first required argument is a register or memory. */ type = vpi_get(vpiType, vpi_scan(argv)); if (type != vpiReg && type != vpiMemory) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a reg or memory.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the second required argument is numeric (a fd). */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (file descriptor) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* * If given check that the third argument is numeric (start). * * Technically you can give the fourth argument (count) with * out a third argument (start), but Icarus does not currently * support missing function arguments! */ arg = vpi_scan(argv); if (arg) { if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's third argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* If given check that the fourth argument is numeric (count). */ arg = vpi_scan(argv); if (arg) { if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's fourth argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 1); } } return 0; } /* * The pattern here is get the current vector, load the new bits on * top of the old ones and then put the modified vector. We need the * "get" first so that if we run out of bits in the file we keep the * original ones. */ static unsigned fread_word(FILE *fp, vpiHandle word, unsigned words, unsigned bpe, s_vpi_vecval *vector) { int bidx; s_vpi_value val; struct t_vpi_vecval *cur = &vector[words-1]; unsigned rtn = 0; /* Get the current bits from the register and copy them to * my local vector. */ val.format = vpiVectorVal; vpi_get_value(word, &val); for (bidx = 0; (unsigned)bidx < words; bidx += 1) { vector[bidx].aval = val.value.vector[bidx].aval; vector[bidx].bval = val.value.vector[bidx].bval; } /* Copy the bytes to the local vector MSByte first. */ for (bidx = bpe-1; bidx >= 0; bidx -= 1) { unsigned clr_mask, bnum; int byte = fgetc(fp); if (byte == EOF) break; /* Clear the current byte and load the new value. */ bnum = bidx % 4; clr_mask = ~(0xff << bnum*8); cur->aval &= clr_mask; cur->bval &= clr_mask; cur->aval |= byte << bnum*8; rtn += 1; if (bnum == 0) cur -= 1; } /* Put the updated bits into the register. */ val.value.vector = vector; vpi_put_value(word, &val, 0, vpiNoDelay); return rtn; } static PLI_INT32 sys_fread_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg, mem_reg; s_vpi_value val; PLI_UINT32 fd_mcd; PLI_INT32 start, count, width, rtn; unsigned is_mem, bpe, words; FILE *fp; s_vpi_vecval *vector; errno = 0; /* Get the register/memory. */ mem_reg = vpi_scan(argv); /* Get the file descriptor. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Return 0 if this is not a valid fd. */ fp = vpi_get_file(fd_mcd); if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } /* Are we reading into a memory? */ if (vpi_get(vpiType, mem_reg) == vpiReg) is_mem = 0; else is_mem = 1; /* We only need to get these for memories. */ if (is_mem) { PLI_INT32 left, right, max, min; /* Get the left and right memory address. */ val.format = vpiIntVal; vpi_get_value(vpi_handle(vpiLeftRange, mem_reg), &val); left = val.value.integer; val.format = vpiIntVal; vpi_get_value(vpi_handle(vpiRightRange, mem_reg), &val); right = val.value.integer; max = (left > right) ? left : right; min = (left < right) ? left : right; /* Get the starting address (optional). */ arg = vpi_scan(argv); if (arg) { val.format = vpiIntVal; vpi_get_value(arg, &val); start = val.value.integer; if (start < min || start > max) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's start argument (%d) is outside " "memory range [%d:%d].\n", name, (int)start, (int)left, (int)right); val.format = vpiIntVal; val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } /* Get the count (optional). */ arg = vpi_scan(argv); if (arg) { val.format = vpiIntVal; vpi_get_value(arg, &val); count = val.value.integer; if (count > max-start+1) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's count argument (%d) is too " "large for start (%d) and memory " "range [%d:%d].\n", name, (int)count, (int)start, (int)left, (int)right); count = max - start + 1; } vpi_free_object(argv); } else { count = max - start + 1; } } else { start = min; count = max - min + 1; } width = vpi_get(vpiSize, vpi_handle_by_index(mem_reg, start)); } else { start = 0; count = 1; width = vpi_get(vpiSize, mem_reg); vpi_free_object(argv); } assert(width > 0); words = (width - 1)/32 + 1; vector = calloc(words, sizeof(s_vpi_vecval)); bpe = (width+7)/8; assert(count >= 0); if (is_mem) { unsigned idx; rtn = 0; for (idx = 0; idx < (unsigned)count; idx += 1) { vpiHandle word; word = vpi_handle_by_index(mem_reg, start+(signed)idx); rtn += fread_word(fp, word, words, bpe, vector); if (feof(fp)) break; } } else { rtn = fread_word(fp, mem_reg, words, bpe, vector); } free(vector); /* Return the number of bytes read. */ val.format = vpiIntVal; val.value.integer = rtn; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_ungetc_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; int chr; errno = 0; /* Get the character. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); chr = val.value.integer; /* Get the file/MC descriptor. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Return EOF if this is not a valid fd. */ fp = vpi_get_file(fd_mcd); if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = EOF; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* ungetc the character and return the result. */ val.format = vpiIntVal; val.value.integer = ungetc(chr, fp); if (val.value.integer != EOF) val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_fseek_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are three numeric arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first argument is numeric. */ if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the second argument exists and is numeric. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (numeric) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the third argument exists and is numeric. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a third (numeric) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's third argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "three arguments", 0); return 0; } static PLI_INT32 sys_fseek_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; PLI_INT32 offset, oper; FILE *fp; errno = 0; /* Get the file pointer. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Get the offset. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); offset = val.value.integer; /* Get the operation. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); oper = val.value.integer; /* Check that the operation is in the valid range. */ switch (oper) { case 0: oper = SEEK_SET; break; case 1: oper = SEEK_CUR; break; case 2: oper = SEEK_END; break; default: vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's operation must be 0, 1 or 2 given %d.\n", name, (int)oper); oper = -1; /* An invalid argument value. */ } /* Return EOF if this is not a valid fd. */ fp = vpi_get_file(fd_mcd); if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = EOF; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } val.format = vpiIntVal; #if defined(__GNUC__) val.value.integer = fseek(fp, offset, oper); #else if (oper < 0) { val.value.integer = EOF; errno = EINVAL; } else val.value.integer = fseek(fp, offset, oper); #endif vpi_put_value(callh, &val, 0 , vpiNoDelay); return 0; } static PLI_INT32 sys_common_fd_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; PLI_UINT32 fd_mcd; FILE *fp; errno = 0; /* Get the file pointer. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd_mcd = val.value.integer; /* Return EOF if this is not a valid fd. */ fp = vpi_get_file(fd_mcd); if (!fp) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = EOF; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } val.format = vpiIntVal; switch (name[4]) { case 'l': /* $ftell() */ val.value.integer = ftell(fp); break; case 'f': /* $feof() is from 1264-2005*/ val.value.integer = feof(fp); break; case 'i': /* $rewind() */ val.value.integer = fseek(fp, 0L, SEEK_SET); break; case 't': /* $fgetc() */ val.value.integer = fgetc(fp); break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s cannot be processed with this routine.\n", name); assert(0); break; } vpi_put_value(callh, &val, 0 , vpiNoDelay); return 0; } /* * Implement the $ferror system function. */ static PLI_INT32 sys_ferror_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; argv = vpi_iterate(vpiArgument, callh); /* * Check that there are two arguments and that the first is * numeric and that the second is a 640 bit or larger register. * * The parser requires that a function have at least one argument, * so argv should always be defined with one argument. */ assert(argv); if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's fd (first) argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that the second argument is given and that it is a 640 bit * or larger register. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (register) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, arg) != vpiReg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be a reg (>=640 bits).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } else if (vpi_get(vpiSize, arg) < 640) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must have 640 bit or more.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } static PLI_INT32 sys_ferror_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle reg; s_vpi_value val; char *msg; PLI_INT32 size; unsigned chars; PLI_UINT32 fd_mcd; /* Get the file pointer. */ val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); fd_mcd = val.value.integer; /* Get the register to put the string result and figure out how many * characters it will hold. */ reg = vpi_scan(argv); size = vpi_get(vpiSize, reg); chars = size / 8; vpi_free_object(argv); /* If we do not already have an error check that the fd is valid. * The assumption is that the other routines have set errno to * EBADF when they encounter a bad file descriptor, so we do not * need to check here. We also need to special case this since * $fopen() will return 0 (a bad file descriptor) when it has a * problem (sets errno). */ if (!errno && !vpi_get_file(fd_mcd) ) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd_mcd, name); errno = EBADF; } /* Return the error code. */ val.format = vpiIntVal; val.value.integer = errno; vpi_put_value(callh, &val, 0, vpiNoDelay); /* Only return the number of characters that will fit in the reg. */ msg = (char *) malloc(chars); if (errno != 0) strncpy(msg, strerror(errno), chars-1); else strncpy(msg, "", chars-1); msg[chars-1] = '\0'; val.format = vpiStringVal; val.value.str = msg; vpi_put_value(reg, &val, 0, vpiNoDelay); free(msg); return 0; } void sys_fileio_register(void) { s_vpi_systf_data tf_data; vpiHandle res; /*============================== fopen */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fopen"; tf_data.calltf = sys_fopen_calltf; tf_data.compiletf = sys_fopen_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fopen"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fopenr */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fopenr"; tf_data.calltf = sys_fopenrwa_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fopenr"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fopenw */ tf_data.tfname = "$fopenw"; tf_data.user_data = "$fopenw"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fopena */ tf_data.tfname = "$fopena"; tf_data.user_data = "$fopena"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fclose */ tf_data.type = vpiSysTask; tf_data.tfname = "$fclose"; tf_data.calltf = sys_fclose_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fclose"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fflush */ tf_data.type = vpiSysTask; tf_data.tfname = "$fflush"; tf_data.calltf = sys_fflush_calltf; tf_data.compiletf = sys_one_opt_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fgetc */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fgetc"; tf_data.calltf = sys_common_fd_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fgetc"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fgets */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fgets"; tf_data.calltf = sys_fgets_calltf; tf_data.compiletf = sys_fgets_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fgets"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fread */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fread"; tf_data.calltf = sys_fread_calltf; tf_data.compiletf = sys_fread_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fread"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== ungetc */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ungetc"; tf_data.calltf = sys_ungetc_calltf; tf_data.compiletf = sys_two_numeric_args_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ungetc"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== ftell */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ftell"; tf_data.calltf = sys_common_fd_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ftell"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== fseek */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fseek"; tf_data.calltf = sys_fseek_calltf; tf_data.compiletf = sys_fseek_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fseek"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); vpip_make_systf_system_defined(res); /*============================== rewind */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$rewind"; tf_data.calltf = sys_common_fd_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$rewind"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== ferror */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ferror"; tf_data.calltf = sys_ferror_calltf; tf_data.compiletf = sys_ferror_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ferror"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* $feof() is from 1364-2005. */ /*============================== feof */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$feof"; tf_data.calltf = sys_common_fd_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$feof"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Icarus specific. */ /*============================== fputc */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fputc"; tf_data.calltf = sys_fputc_calltf; tf_data.compiletf = sys_two_numeric_args_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fputc"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_finish.c000066400000000000000000000100361435245347300164670ustar00rootroot00000000000000/* * Copyright (c) 1999-2020 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 "sys_priv.h" #include #include static PLI_INT32 sys_finish_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv; s_vpi_value val; int diag_msg = 1; int had_arg = 0; /* Get the argument list and look for the diagnostic message level. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); if (argv) { vpiHandle arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); diag_msg = val.value.integer; if ((diag_msg < 0) || (diag_msg > 2)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s(%d) argument must be 0, 1, or 2.\n", (const char*)name, (int)diag_msg); } had_arg = 1; } if (diag_msg != 0) { s_vpi_time now; int units; uint64_t raw_time; vpi_printf("%s:%d: %s", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), (const char*)name); if (had_arg) vpi_printf("(%d)", diag_msg); now.type = vpiSimTime; vpi_get_time(0, &now); raw_time = now.high; raw_time <<= 32; raw_time |= now.low; vpi_printf(" called at %" PRIu64, raw_time); units = vpi_get(vpiTimePrecision, 0); switch (units) { case 2: vpi_printf(" (100s)\n"); break; case 1: vpi_printf(" (10s)\n"); break; case 0: vpi_printf(" (1s)\n"); break; case -1: vpi_printf(" (100ms)\n"); break; case -2: vpi_printf(" (10ms)\n"); break; case -3: vpi_printf(" (1ms)\n"); break; case -4: vpi_printf(" (100us)\n"); break; case -5: vpi_printf(" (10us)\n"); break; case -6: vpi_printf(" (1us)\n"); break; case -7: vpi_printf(" (100ns)\n"); break; case -8: vpi_printf(" (10ns)\n"); break; case -9: vpi_printf(" (1ns)\n"); break; case -10: vpi_printf(" (100ps)\n"); break; case -11: vpi_printf(" (10ps)\n"); break; case -12: vpi_printf(" (1ps)\n"); break; case -13: vpi_printf(" (100fs)\n"); break; case -14: vpi_printf(" (10fs)\n"); break; case -15: vpi_printf(" (1fs)\n"); break; default: vpi_printf("unknown time unit '%d'", units); assert(0); } } if (strcmp((const char*)name, "$stop") == 0) { vpi_control(vpiStop, diag_msg); return 0; } vpip_set_return_value(0); vpi_control(vpiFinish, diag_msg); return 0; } void sys_finish_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysTask; tf_data.tfname = "$finish"; tf_data.calltf = sys_finish_calltf; tf_data.compiletf = sys_one_opt_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$finish"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$stop"; tf_data.calltf = sys_finish_calltf; tf_data.compiletf = sys_one_opt_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$stop"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_fst.c000066400000000000000000000720511435245347300160100ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "sys_priv.h" # include "vcd_priv.h" # include "fstapi.h" /* * This file contains the implementations of the FST related functions. */ # include # include # include # include # include # include "ivl_alloc.h" static char *dump_path = NULL; static int dump_no_date = 0; static struct fstContext *dump_file = NULL; static struct t_vpi_time zero_delay = { vpiSimTime, 0, 0, 0.0 }; DECLARE_VCD_INFO(vcd_info, fstHandle); static struct vcd_info *vcd_list = NULL; static struct vcd_info *vcd_const_list = NULL; static struct vcd_info *vcd_dmp_list = NULL; static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; static int finish_status = 0; static enum lxm_optimum_mode_e { LXM_NONE = 0, LXM_SPACE = 1, LXM_SPEED = 2, LXM_BOTH = 3 } lxm_optimum_mode = LXM_NONE; static const char*units_names[] = { "s", "ms", "us", "ns", "ps", "fs" }; static void show_this_item(struct vcd_info*info) { s_vpi_value value; PLI_INT32 type = vpi_get(vpiType, info->item); if (type == vpiRealVar) { value.format = vpiRealVal; vpi_get_value(info->item, &value); fstWriterEmitValueChange(dump_file, info->ident, &value.value.real); } else if (type == vpiParameter && vpi_get(vpiConstType, info->item) == vpiRealConst) { value.format = vpiRealVal; vpi_get_value(info->item, &value); fstWriterEmitValueChange(dump_file, info->ident, &value.value.real); } else { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); fstWriterEmitValueChange(dump_file, info->ident, (type != vpiNamedEvent) ? value.value.str : "1"); } } /* Dump values for a $dumpoff. */ static void show_this_item_x(struct vcd_info*info) { PLI_INT32 type = vpi_get(vpiType, info->item); if (type == vpiRealVar) { /* Some tools dump nothing here...? */ double mynan = strtod("NaN", NULL); fstWriterEmitValueChange(dump_file, info->ident, &mynan); } else if (type == vpiNamedEvent) { /* Do nothing for named events. */ } else { int siz = vpi_get(vpiSize, info->item); char *xmem = malloc(siz); memset(xmem, 'x', siz); fstWriterEmitValueChange(dump_file, info->ident, xmem); free(xmem); } } /* * managed qsorted list of scope names/variables for duplicates bsearching */ struct vcd_names_list_s fst_tab = { 0, 0, 0, 0 }; struct vcd_names_list_s fst_var = { 0, 0, 0, 0 }; static int dumpvars_status = 0; /* 0:fresh 1:cb installed, 2:callback done */ static PLI_UINT64 dumpvars_time; __inline__ static int dump_header_pending(void) { return dumpvars_status != 2; } static PLI_INT32 variable_cb_2(p_cb_data cause) { struct vcd_info* info = vcd_dmp_list; PLI_UINT64 now = timerec_to_time64(cause->time); if (now != vcd_cur_time) { fstWriterEmitTimeChange(dump_file, now); vcd_cur_time = now; } do { show_this_item(info); info->scheduled = 0; } while ((info = info->dmp_next) != 0); vcd_dmp_list = 0; return 0; } static PLI_INT32 variable_cb_1(p_cb_data cause) { struct t_cb_data cb; struct vcd_info*info = (struct vcd_info*)cause->user_data; if (dump_is_full) return 0; if (dump_is_off) return 0; if (dump_header_pending()) return 0; if (info->scheduled) return 0; if ((dump_limit > 0) && fstWriterGetDumpSizeLimitReached(dump_file)) { dump_is_full = 1; vpi_printf("WARNING: Dump file limit (%ld bytes) " "exceeded.\n", dump_limit); return 0; } if (!vcd_dmp_list) { cb = *cause; cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = variable_cb_2; vpi_register_cb(&cb); } info->scheduled = 1; info->dmp_next = vcd_dmp_list; vcd_dmp_list = info; return 0; } static PLI_INT32 dumpvars_cb(p_cb_data cause) { if (dumpvars_status != 1) return 0; dumpvars_status = 2; dumpvars_time = timerec_to_time64(cause->time); vcd_cur_time = dumpvars_time; /* nothing to do for $enddefinitions $end */ if (!dump_is_off) { fstWriterEmitTimeChange(dump_file, dumpvars_time); /* nothing to do for $dumpvars... */ ITERATE_VCD_INFO(vcd_const_list, vcd_info, next, show_this_item); ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); /* ...nothing to do for $end */ } return 0; } static PLI_INT32 finish_cb(p_cb_data cause) { struct vcd_info *cur, *next; if (finish_status != 0) return 0; finish_status = 1; dumpvars_time = timerec_to_time64(cause->time); if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) { fstWriterEmitTimeChange(dump_file, dumpvars_time); } fstWriterClose(dump_file); for (cur = vcd_list ; cur ; cur = next) { next = cur->next; free(cur); } vcd_list = 0; for (cur = vcd_const_list ; cur ; cur = next) { next = cur->next; free(cur); } vcd_const_list = 0; vcd_names_delete(&fst_tab); vcd_names_delete(&fst_var); nexus_ident_delete(); free(dump_path); dump_path = 0; return 0; } __inline__ static int install_dumpvars_callback(void) { struct t_cb_data cb; if (dumpvars_status == 1) return 0; if (dumpvars_status == 2) { vpi_printf("FST warning: $dumpvars ignored, previously" " called at simtime %" PLI_UINT64_FMT "\n", dumpvars_time); return 1; } cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = dumpvars_cb; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); cb.reason = cbEndOfSimulation; cb.cb_rtn = finish_cb; vpi_register_cb(&cb); dumpvars_status = 1; return 0; } static PLI_INT32 sys_dumpoff_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; dump_is_off = 1; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fstWriterEmitTimeChange(dump_file, now64); vcd_cur_time = now64; } fstWriterEmitDumpActive(dump_file, 0); /* $dumpoff */ ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item_x); return 0; } static PLI_INT32 sys_dumpon_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (!dump_is_off) return 0; dump_is_off = 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fstWriterEmitTimeChange(dump_file, now64); vcd_cur_time = now64; } fstWriterEmitDumpActive(dump_file, 1); /* $dumpon */ ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); return 0; } static PLI_INT32 sys_dumpall_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fstWriterEmitTimeChange(dump_file, now64); vcd_cur_time = now64; } /* nothing to do for $dumpall... */ ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); return 0; } static void open_dumpfile(vpiHandle callh) { if (dump_path == 0) dump_path = strdup("dump.fst"); dump_file = fstWriterCreate(dump_path, 1); if (dump_file == 0) { vpi_printf("FST Error: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open %s for output.\n", dump_path); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(dump_path); dump_path = 0; return; } else { int prec = vpi_get(vpiTimePrecision, 0); unsigned scale = 1; unsigned udx = 0; time_t walltime; char scale_buf[65]; vpi_printf("FST info: dumpfile %s opened for output.\n", dump_path); time(&walltime); assert(prec >= -15); while (prec < 0) { udx += 1; prec += 3; } while (prec > 0) { scale *= 10; prec -= 1; } if (!dump_no_date) fstWriterSetDate(dump_file, asctime(localtime(&walltime))); else fstWriterSetDate(dump_file, ""); fstWriterSetVersion(dump_file, "Icarus Verilog"); sprintf(scale_buf, "\t%u%s\n", scale, units_names[udx]); fstWriterSetTimescaleFromString(dump_file, scale_buf); /* Set the faster dump type when requested. */ if ((lxm_optimum_mode == LXM_SPEED) || (lxm_optimum_mode == LXM_BOTH)) { fstWriterSetPackType(dump_file, 1); } /* Set the most effective compression when requested. */ if ((lxm_optimum_mode == LXM_SPACE) || (lxm_optimum_mode == LXM_BOTH)) { fstWriterSetRepackOnClose(dump_file, 1); } } } static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); char *path; /* $dumpfile must be called before $dumpvars starts! */ if (dumpvars_status != 0) { char msg[64]; snprintf(msg, sizeof(msg), "FST warning: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s called after $dumpvars started,\n", msg, name); vpi_printf("%*s using existing file (%s).\n", (int) strlen(msg), " ", dump_path); vpi_free_object(argv); return 0; } path = get_filename_with_suffix(callh, name, vpi_scan(argv), "fst"); vpi_free_object(argv); if (! path) return 0; if (dump_path) { vpi_printf("FST warning: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Overriding dump file %s with %s.\n", dump_path, path); free(dump_path); } dump_path = path; return 0; } static PLI_INT32 sys_dumpflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ if (dump_file) fstWriterFlushContext(dump_file); return 0; } static PLI_INT32 sys_dumplimit_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; (void)name; /* Parameter is not used. */ /* Get the value and set the dump limit. */ val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); dump_limit = val.value.integer; fstWriterSetDumpSizeLimit(dump_file, dump_limit); vpi_free_object(argv); return 0; } static void scan_item(unsigned depth, vpiHandle item, int skip) { struct t_cb_data cb; struct vcd_info* info; enum fstVarType type = FST_VT_MAX; enum fstScopeType stype = FST_ST_MAX; enum fstVarDir dir; const char *name; const char *fullname; char *escname; const char *ident; fstHandle new_ident; int nexus_id; unsigned size; PLI_INT32 item_type; /* Get the displayed type for the various $var and $scope types. */ /* Not all of these are supported now, but they should be in a * future development version. */ item_type = vpi_get(vpiType, item); switch (item_type) { case vpiNamedEvent: type = FST_VT_VCD_EVENT; break; case vpiIntVar: case vpiIntegerVar: type = FST_VT_VCD_INTEGER; break; /* FST (gtkwave) assumes PARAMETER are bit, so handle other cases */ case vpiParameter: switch (vpi_get(vpiConstType, item)) { case vpiRealConst: type = FST_VT_VCD_REAL; break; default: type = FST_VT_VCD_PARAMETER; break; } break; /* Icarus converts realtime to real. */ case vpiRealVar: type = FST_VT_VCD_REAL; break; case vpiMemoryWord: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiLongIntVar: case vpiReg: type = FST_VT_VCD_REG; break; /* Icarus converts a time to a plain register. */ case vpiTimeVar: type = FST_VT_VCD_TIME; break; case vpiNet: switch (vpi_get(vpiNetType, item)) { case vpiWand: type = FST_VT_VCD_WAND; break; case vpiWor: type = FST_VT_VCD_WOR; break; case vpiTri: type = FST_VT_VCD_TRI; break; case vpiTri0: type = FST_VT_VCD_TRI0; break; case vpiTri1: type = FST_VT_VCD_TRI1; break; case vpiTriReg: type = FST_VT_VCD_TRIREG; break; case vpiTriAnd: type = FST_VT_VCD_TRIAND; break; case vpiTriOr: type = FST_VT_VCD_TRIOR; break; case vpiSupply1: type = FST_VT_VCD_SUPPLY1; break; case vpiSupply0: type = FST_VT_VCD_SUPPLY0; break; default: type = FST_VT_VCD_WIRE; break; } break; case vpiNamedBegin: stype = FST_ST_VCD_BEGIN; break; case vpiNamedFork: stype = FST_ST_VCD_FORK; break; case vpiFunction: stype = FST_ST_VCD_FUNCTION; break; case vpiGenScope: stype = FST_ST_VCD_GENERATE; break; case vpiModule: stype = FST_ST_VCD_MODULE; break; case vpiPackage: stype = FST_ST_VCD_PACKAGE; break; case vpiTask: stype = FST_ST_VCD_TASK; break; default: vpi_printf("FST warning: $dumpvars: Unsupported argument " "type (%s).\n", vpi_get_str(vpiType, item)); return; } /* Do some special processing/checking on array words. Dumping * array words is an Icarus extension. */ if (item_type == vpiMemoryWord) { /* Turn a non-constant array word select into a constant * word select. */ if (vpi_get(vpiConstantSelect, item) == 0) { vpiHandle array = vpi_handle(vpiParent, item); PLI_INT32 idx = vpi_get(vpiIndex, item); item = vpi_handle_by_index(array, idx); } /* An array word is implicitly escaped so look for an * escaped identifier that this could conflict with. */ /* This does not work as expected since we always find at * least the array word. We likely need a custom routine. */ if (vpi_get(vpiType, item) == vpiMemoryWord && vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) { vpi_printf("FST warning: array word %s will conflict " "with an escaped identifier.\n", vpi_get_str(vpiFullName, item)); } } fullname = vpi_get_str(vpiFullName, item); /* Generate the $var or $scope commands. */ switch (item_type) { case vpiNamedEvent: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiRealVar: case vpiMemoryWord: case vpiReg: case vpiTimeVar: case vpiNet: /* If we are skipping all signal or this is in an automatic * scope then just return. */ if (skip || vpi_get(vpiAutomatic, item)) return; /* Skip this signal if it has already been included. * This can only happen for implicitly given signals. */ if (vcd_names_search(&fst_var, fullname)) return; /* Declare the variable in the FST file. */ name = vpi_get_str(vpiName, item); if (is_escaped_id(name)) { escname = malloc(strlen(name) + 2); sprintf(escname, "\\%s", name); } else escname = strdup(name); /* Some signals can have an alias so handle that. */ nexus_id = vpi_get(_vpiNexusId, item); ident = 0; if (nexus_id) ident = find_nexus_ident(nexus_id); /* Named events do not have a size, but other tools use * a size of 1 and some viewers do not accept a width of * zero so we will also use a width of one for events. */ if (item_type == vpiNamedEvent) size = 1; else size = vpi_get(vpiSize, item); /* The FST format supports a port direction so if the net * is a port set the direction to one of the following: * FST_VD_INPUT, FST_VD_OUTPUT or FST_VD_INOUT */ dir = FST_VD_IMPLICIT; if (size > 1 || vpi_get(vpiLeftRange, item) != 0) { char *buf = malloc(strlen(escname) + 65); sprintf(buf, "%s [%i:%i]", escname, (int)vpi_get(vpiLeftRange, item), (int)vpi_get(vpiRightRange, item)); new_ident = fstWriterCreateVar(dump_file, type, dir, size, buf, (fstHandle)(intptr_t)ident); free(buf); } else { new_ident = fstWriterCreateVar(dump_file, type, dir, size, escname, (fstHandle)(intptr_t)ident); } free(escname); if (!ident) { if (nexus_id) set_nexus_ident(nexus_id, (const char *)(intptr_t)new_ident); /* Add a callback for the signal. */ info = malloc(sizeof(*info)); info->time.type = vpiSimTime; info->item = item; info->ident = new_ident; info->scheduled = 0; cb.time = &info->time; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->dmp_next = 0; info->next = vcd_list; vcd_list = info; info->cb = vpi_register_cb(&cb); } break; case vpiParameter: /* If we are skipping all pamaeters then just return. */ if (skip) return; /* Skip this signal if it has already been included. * This can only happen for implicitly given signals. */ if (vcd_names_search(&fst_var, fullname)) return; name = vpi_get_str(vpiName, item); if (is_escaped_id(name)) { escname = malloc(strlen(name) + 2); sprintf(escname, "\\%s", name); } else escname = strdup(name); size = vpi_get(vpiSize, item); dir = FST_VD_IMPLICIT; new_ident = fstWriterCreateVar(dump_file, type, dir, size, escname, 0); free(escname); info = malloc(sizeof(*info)); info->item = item; info->ident = new_ident; info->scheduled = 0; info->dmp_next = 0; info->next = vcd_const_list; info->cb = NULL; vcd_const_list = info; break; case vpiModule: case vpiPackage: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: if (depth > 0) { char *instname; char *defname = NULL; /* list of types to iterate upon */ static int types[] = { /* Value */ vpiNamedEvent, vpiNet, vpiParameter, vpiReg, vpiVariables, /* Scope */ vpiFunction, vpiGenScope, vpiModule, vpiNamedBegin, vpiNamedFork, vpiTask, -1 }; int i; int nskip = (vcd_names_search(&fst_tab, fullname) != 0); /* We have to always scan the scope because the * depth could be different for this call. */ if (nskip) { vpi_printf("FST warning: ignoring signals in " "previously scanned scope %s.\n", fullname); } else { vcd_names_add(&fst_tab, fullname); } /* Set the file and line information for this scope. * Everything has instance information. Only a module * has separate definition information. */ instname = vpi_get_str(vpiFile, item); fstWriterSetSourceInstantiationStem(dump_file, instname, (int)vpi_get(vpiLineNo, item), 0); if (item_type == vpiModule) { fstWriterSetSourceStem(dump_file, vpi_get_str(vpiDefFile, item), (int)vpi_get(vpiDefLineNo, item), 0); } else { fstWriterSetSourceStem(dump_file, instname, (int)vpi_get(vpiLineNo, item), 0); } /* This must be done before the other name is fetched * and the string must always be freed */ if (item_type == vpiModule) { defname = strdup(vpi_get_str(vpiDefName, item)); } name = vpi_get_str(vpiName, item); /* If the two names match only use the vpiName. */ if (defname && (strcmp(defname, name) == 0)) { free(defname); defname = NULL; } fstWriterSetScope(dump_file, stype, name, defname); free(defname); for (i=0; types[i]>0; i++) { vpiHandle hand; vpiHandle argv = vpi_iterate(types[i], item); while (argv && (hand = vpi_scan(argv))) { scan_item(depth-1, hand, nskip); } } /* Sort any signals that we added above. */ fstWriterSetUpscope(dump_file); } break; } } static int draw_scope(vpiHandle item, vpiHandle callh) { int depth; const char *name; char *defname = NULL; PLI_INT32 scope_type, type; vpiHandle scope = vpi_handle(vpiScope, item); if (!scope) return 0; depth = 1 + draw_scope(scope, callh); scope_type = vpi_get(vpiType, scope); /* This must be done before the other name is fetched * and the string must always be freed */ if (scope_type == vpiModule) { defname = strdup(vpi_get_str(vpiDefName, scope)); } name = vpi_get_str(vpiName, scope); /* If the two names match only use the vpiName. */ if (defname && (strcmp(defname, name) == 0)) { free(defname); defname = NULL; } switch (scope_type) { case vpiNamedBegin: type = FST_ST_VCD_BEGIN; break; case vpiFunction: type = FST_ST_VCD_FUNCTION; break; case vpiNamedFork: type = FST_ST_VCD_FORK; break; case vpiGenScope: type = FST_ST_VCD_GENERATE; break; case vpiModule: type = FST_ST_VCD_MODULE; break; case vpiTask: type = FST_ST_VCD_TASK; break; default: type = FST_ST_VCD_MODULE; vpi_printf("FST Error: %s:%d: $dumpvars: Unsupported scope " "type (%d)\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), (int)vpi_get(vpiType, item)); assert(0); } fstWriterSetScope(dump_file, type, name, defname); free(defname); return depth; } static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; s_vpi_value value; unsigned depth = 0; (void)name; /* Parameter is not used. */ if (dump_file == 0) { open_dumpfile(callh); if (dump_file == 0) { if (argv) vpi_free_object(argv); return 0; } } if (install_dumpvars_callback()) { if (argv) vpi_free_object(argv); return 0; } /* Get the depth if it exists. */ if (argv) { value.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &value); depth = value.value.integer; } if (!depth) depth = 10000; /* This dumps all the instances in the design if none are given. */ if (!argv || !(item = vpi_scan(argv))) { argv = vpi_iterate(vpiInstance, 0x0); assert(argv); /* There must be at least one top level instance. */ item = vpi_scan(argv); } for ( ; item; item = vpi_scan(argv)) { char *scname; const char *fullname; int add_var = 0; int dep; PLI_INT32 item_type = vpi_get(vpiType, item); /* If this is a signal make sure it has not already * been included. */ switch (item_type) { case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNamedEvent: case vpiNet: case vpiParameter: case vpiRealVar: case vpiReg: case vpiTimeVar: /* Warn if the variables scope (which includes the * variable) or the variable itself was already * included. A scope does not automatically include * memory words so do not check the scope for them. */ scname = strdup(vpi_get_str(vpiFullName, vpi_handle(vpiScope, item))); fullname = vpi_get_str(vpiFullName, item); if (((item_type != vpiMemoryWord) && vcd_names_search(&fst_tab, scname)) || vcd_names_search(&fst_var, fullname)) { vpi_printf("FST warning: skipping signal %s, " "it was previously included.\n", fullname); free(scname); continue; } else { add_var = 1; } free(scname); } dep = draw_scope(item, callh); scan_item(depth, item, 0); /* The scope list must be sorted after we scan an item. */ vcd_names_sort(&fst_tab); while (dep--) fstWriterSetUpscope(dump_file); /* Add this signal to the variable list so we can verify it * is not included twice. This must be done after it has * been added */ if (add_var) { vcd_names_add(&fst_var, vpi_get_str(vpiFullName, item)); vcd_names_sort(&fst_var); } } return 0; } void sys_fst_register(void) { int idx; struct t_vpi_vlog_info vlog_info; s_vpi_systf_data tf_data; vpiHandle res; /* Scan the extended arguments, looking for fst optimization flags. */ vpi_get_vlog_info(&vlog_info); /* The "speed" option is not used in this dumper. */ for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-fst-space") == 0) { lxm_optimum_mode = LXM_SPACE; } else if (strcmp(vlog_info.argv[idx],"-fst-speed") == 0) { lxm_optimum_mode = LXM_SPEED; } else if (strcmp(vlog_info.argv[idx],"-fst-space-speed") == 0) { lxm_optimum_mode = LXM_BOTH; } else if (strcmp(vlog_info.argv[idx],"-fst-speed-space") == 0) { lxm_optimum_mode = LXM_BOTH; } else if (strcmp(vlog_info.argv[idx],"-no-date") == 0) { dump_no_date = 1; } } /* All the compiletf routines are located in vcd_priv.c. */ tf_data.type = vpiSysTask; tf_data.tfname = "$dumpall"; tf_data.calltf = sys_dumpall_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpfile"; tf_data.calltf = sys_dumpfile_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpfile"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpflush"; tf_data.calltf = sys_dumpflush_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumplimit"; tf_data.calltf = sys_dumplimit_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumplimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpoff"; tf_data.calltf = sys_dumpoff_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpon"; tf_data.calltf = sys_dumpon_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpon"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_icarus.c000066400000000000000000000246711435245347300165070ustar00rootroot00000000000000/* * Copyright (C) 2008-2021 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. */ #include "sys_priv.h" #include static PLI_INT32 finish_and_return_calltf(ICARUS_VPI_CONST PLI_BYTE8* name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; (void) name; /* Not used! */ /* Get the return value. */ arg = vpi_scan(argv); vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); /* Set the return value. */ vpip_set_return_value(val.value.integer); /* Now finish. */ vpi_control(vpiFinish, 1); return 0; } static PLI_INT32 task_not_implemented_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpi_printf("SORRY: %s:%d: task %s() is not currently implemented.\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* * This is used to warn the user that the specified optional system * task/function is not available (from Annex C 1364-2005). */ static PLI_INT32 missing_optional_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpi_printf("SORRY: %s:%d: %s() is not available in Icarus Verilog.\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* * Register the function with Verilog. */ void sys_special_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysTask; tf_data.calltf = finish_and_return_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$finish_and_return"; tf_data.user_data = "$finish_and_return"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* These tasks are not currently implemented. */ tf_data.type = vpiSysTask; tf_data.calltf = 0; tf_data.sizetf = 0; tf_data.compiletf = task_not_implemented_compiletf; tf_data.tfname = "$fmonitor"; tf_data.user_data = "$fmonitor"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$fmonitorb"; tf_data.user_data = "$fmonitorb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$fmonitoro"; tf_data.user_data = "$fmonitoro"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$fmonitorh"; tf_data.user_data = "$fmonitorh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$and$array"; tf_data.user_data = "$async$and$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$nand$array"; tf_data.user_data = "$async$nand$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$or$array"; tf_data.user_data = "$async$or$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$nor$array"; tf_data.user_data = "$async$nor$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$and$plane"; tf_data.user_data = "$async$and$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$nand$plane"; tf_data.user_data = "$async$nand$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$or$plane"; tf_data.user_data = "$async$or$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$async$nor$plane"; tf_data.user_data = "$async$nor$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$and$array"; tf_data.user_data = "$sync$and$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$nand$array"; tf_data.user_data = "$sync$nand$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$or$array"; tf_data.user_data = "$sync$or$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$nor$array"; tf_data.user_data = "$sync$nor$array"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$and$plane"; tf_data.user_data = "$sync$and$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$nand$plane"; tf_data.user_data = "$sync$nand$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$or$plane"; tf_data.user_data = "$sync$or$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sync$nor$plane"; tf_data.user_data = "$sync$nor$plane"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpports"; tf_data.user_data = "$dumpports"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpportsoff"; tf_data.user_data = "$dumpportsoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpportson"; tf_data.user_data = "$dumpportson"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpportsall"; tf_data.user_data = "$dumpportsall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpportslimit"; tf_data.user_data = "$dumpportslimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$dumpportsflush"; tf_data.user_data = "$dumpportsflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* The following optional system tasks/functions are not implemented * in Icarus Verilog (from Annex C 1364-2005). */ tf_data.type = vpiSysTask; tf_data.calltf = 0; tf_data.sizetf = 0; tf_data.compiletf = missing_optional_compiletf; tf_data.tfname = "$input"; tf_data.user_data = "$input"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$key"; tf_data.user_data = "$key"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$nokey"; tf_data.user_data = "$nokey"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$list"; tf_data.user_data = "$list"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$log"; tf_data.user_data = "$log"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$nolog"; tf_data.user_data = "$nolog"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$save"; tf_data.user_data = "$save"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$restart"; tf_data.user_data = "$restart"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$incsave"; tf_data.user_data = "$incsave"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$scope"; tf_data.user_data = "$scope"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$showscopes"; tf_data.user_data = "$showscopes"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$showvars"; tf_data.user_data = "$showvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sreadmemb"; tf_data.user_data = "$sreadmemb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$sreadmemh"; tf_data.user_data = "$sreadmemh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Optional functions. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$getpattern"; tf_data.user_data = "$getpattern"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$scale"; tf_data.user_data = "$scale"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_lxt.c000066400000000000000000000533621435245347300160270ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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. */ /* The sys_priv.h include must be before the lxt_write.h include! */ # include "sys_priv.h" # include "lxt_write.h" # include "vcd_priv.h" /* * This file contains the implementations of the LXT related functions. */ # include # include # include # include # include # include "stringheap.h" # include "ivl_alloc.h" static char *dump_path = NULL; static struct lt_trace *dump_file = NULL; static struct t_vpi_time zero_delay = { vpiSimTime, 0, 0, 0.0 }; struct vcd_info { vpiHandle item; vpiHandle cb; struct t_vpi_time time; struct lt_symbol *sym; struct vcd_info *next; struct vcd_info *dmp_next; int scheduled; }; static struct vcd_info *vcd_list = NULL; static struct vcd_info *vcd_dmp_list = NULL; static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; static int finish_status = 0; static enum lxm_optimum_mode_e { LXM_NONE = 0, LXM_SPACE = 1, LXM_SPEED = 2 } lxm_optimum_mode = LXM_SPEED; /* * The lxt_scope head and current pointers are used to keep a scope * stack that can be accessed from the bottom. The lxt_scope_head * points to the first (bottom) item in the stack and * lxt_scope_current points to the last (top) item in the stack. The * push_scope and pop_scope methods manipulate the stack. */ struct lxt_scope { struct lxt_scope *next, *prev; char *name; int len; }; static struct lxt_scope *lxt_scope_head=NULL, *lxt_scope_current=NULL; static void push_scope(const char *name) { struct lxt_scope *t = (struct lxt_scope *) calloc(1, sizeof(struct lxt_scope)); t->name = strdup(name); t->len = strlen(name); if(!lxt_scope_head) { lxt_scope_head = lxt_scope_current = t; } else { lxt_scope_current->next = t; t->prev = lxt_scope_current; lxt_scope_current = t; } } static void pop_scope(void) { struct lxt_scope *t; assert(lxt_scope_current); t=lxt_scope_current->prev; free(lxt_scope_current->name); free(lxt_scope_current); lxt_scope_current = t; if (lxt_scope_current) { lxt_scope_current->next = 0; } else { lxt_scope_head = 0; } } /* * This function uses the scope stack to generate a hierarchical * name. Scan the scope stack from the bottom up to construct the * name. */ static char *create_full_name(const char *name) { char *n, *n2; int len = 0; int is_esc_id = is_escaped_id(name); struct lxt_scope *t = lxt_scope_head; /* Figure out how long the combined string will be. */ while(t) { len+=t->len+1; t=t->next; } len += strlen(name) + 1; if (is_esc_id) len += 1; /* Allocate a string buffer. */ n = n2 = malloc(len); t = lxt_scope_head; while(t) { strcpy(n2, t->name); n2 += t->len; *n2 = '.'; n2++; t=t->next; } if (is_esc_id) { *n2 = '\\'; n2++; } strcpy(n2, name); n2 += strlen(n2); assert( (n2 - n + 1) == len ); return n; } static void show_this_item(struct vcd_info*info) { s_vpi_value value; if (vpi_get(vpiType, info->item) == vpiRealVar) { value.format = vpiRealVal; vpi_get_value(info->item, &value); lt_emit_value_double(dump_file, info->sym, 0, value.value.real); } else { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); lt_emit_value_bit_string(dump_file, info->sym, 0 /* array row */, value.value.str); } } static void show_this_item_x(struct vcd_info*info) { if (vpi_get(vpiType,info->item) == vpiRealVar) { /* Should write a NaN here? */ } else { lt_emit_value_bit_string(dump_file, info->sym, 0, "x"); } } /* * managed qsorted list of scope names for duplicates bsearching */ struct vcd_names_list_s lxt_tab; static int dumpvars_status = 0; /* 0:fresh 1:cb installed, 2:callback done */ static PLI_UINT64 dumpvars_time; __inline__ static int dump_header_pending(void) { return dumpvars_status != 2; } /* * This function writes out all the traced variables, whether they * changed or not. */ static void vcd_checkpoint(void) { struct vcd_info*cur; for (cur = vcd_list ; cur ; cur = cur->next) show_this_item(cur); } static void vcd_checkpoint_x(void) { struct vcd_info*cur; for (cur = vcd_list ; cur ; cur = cur->next) show_this_item_x(cur); } static PLI_INT32 variable_cb_2(p_cb_data cause) { struct vcd_info* info = vcd_dmp_list; PLI_UINT64 now = timerec_to_time64(cause->time); if (now != vcd_cur_time) { lt_set_time64(dump_file, now); vcd_cur_time = now; } do { show_this_item(info); info->scheduled = 0; } while ((info = info->dmp_next) != 0); vcd_dmp_list = 0; return 0; } static PLI_INT32 variable_cb_1(p_cb_data cause) { struct t_cb_data cb; struct vcd_info*info = (struct vcd_info*)cause->user_data; if (dump_is_full) return 0; if (dump_is_off) return 0; if (dump_header_pending()) return 0; if (info->scheduled) return 0; if ((dump_limit > 0) && (ftell(dump_file->handle) > dump_limit)) { dump_is_full = 1; vpi_printf("WARNING: Dump file limit (%ld bytes) " "exceeded.\n", dump_limit); return 0; } if (!vcd_dmp_list) { cb = *cause; cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = variable_cb_2; vpi_register_cb(&cb); } info->scheduled = 1; info->dmp_next = vcd_dmp_list; vcd_dmp_list = info; return 0; } static PLI_INT32 dumpvars_cb(p_cb_data cause) { if (dumpvars_status != 1) return 0; dumpvars_status = 2; dumpvars_time = timerec_to_time64(cause->time); vcd_cur_time = dumpvars_time; if (!dump_is_off) { lt_set_time64(dump_file, dumpvars_time); vcd_checkpoint(); } return 0; } static PLI_INT32 finish_cb(p_cb_data cause) { struct vcd_info *cur, *next; if (finish_status != 0) return 0; finish_status = 1; dumpvars_time = timerec_to_time64(cause->time); if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) { lt_set_time64(dump_file, dumpvars_time); } for (cur = vcd_list ; cur ; cur = next) { next = cur->next; free(cur); } vcd_list = 0; vcd_names_delete(&lxt_tab); nexus_ident_delete(); free(dump_path); dump_path = 0; return 0; } __inline__ static int install_dumpvars_callback(void) { struct t_cb_data cb; if (dumpvars_status == 1) return 0; if (dumpvars_status == 2) { vpi_printf("LXT warning: $dumpvars ignored, previously" " called at simtime %" PLI_UINT64_FMT "\n", dumpvars_time); return 1; } cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = dumpvars_cb; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); cb.reason = cbEndOfSimulation; cb.cb_rtn = finish_cb; vpi_register_cb(&cb); dumpvars_status = 1; return 0; } static PLI_INT32 sys_dumpoff_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; dump_is_off = 1; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { lt_set_time64(dump_file, now64); vcd_cur_time = now64; } lt_set_dumpoff(dump_file); vcd_checkpoint_x(); return 0; } static PLI_INT32 sys_dumpon_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (!dump_is_off) return 0; dump_is_off = 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { lt_set_time64(dump_file, now64); vcd_cur_time = now64; } lt_set_dumpon(dump_file); vcd_checkpoint(); return 0; } static PLI_INT32 sys_dumpall_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { lt_set_time64(dump_file, now64); vcd_cur_time = now64; } vcd_checkpoint(); return 0; } static void *close_dumpfile(void) { lt_close(dump_file); dump_file = NULL; return NULL; } static void open_dumpfile(vpiHandle callh) { if (dump_path == 0) dump_path = strdup("dump.lxt"); dump_file = lt_init(dump_path); if (dump_file == 0) { vpi_printf("LXT Error: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open %s for output.\n", dump_path); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(dump_path); dump_path = 0; return; } else { int prec = vpi_get(vpiTimePrecision, 0); vpi_printf("LXT info: dumpfile %s opened for output.\n", dump_path); assert(prec >= -15); lt_set_timescale(dump_file, prec); lt_set_initial_value(dump_file, 'x'); lt_set_clock_compress(dump_file); atexit((void(*)(void))close_dumpfile); } } static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); char *path; /* $dumpfile must be called before $dumpvars starts! */ if (dumpvars_status != 0) { char msg[64]; snprintf(msg, sizeof(msg), "LXT warning: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s called after $dumpvars started,\n", msg, name); vpi_printf("%*s using existing file (%s).\n", (int) strlen(msg), " ", dump_path); vpi_free_object(argv); return 0; } path = get_filename_with_suffix(callh, name, vpi_scan(argv), "lxt"); vpi_free_object(argv); if (! path) return 0; if (dump_path) { vpi_printf("LXT warning: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Overriding dump file %s with %s.\n", dump_path, path); free(dump_path); } dump_path = path; return 0; } /* * The LXT1 format has no concept of file flushing. */ static PLI_INT32 sys_dumpflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ return 0; } static PLI_INT32 sys_dumplimit_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; (void)name; /* Parameter is not used. */ /* Get the value and set the dump limit. */ val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); dump_limit = val.value.integer; vpi_free_object(argv); return 0; } static void scan_item(unsigned depth, vpiHandle item, int skip) { struct t_cb_data cb; struct vcd_info* info; const char* name; const char* ident; int nexus_id; switch (vpi_get(vpiType, item)) { case vpiMemoryWord: if (vpi_get(vpiConstantSelect, item) == 0) { /* Turn a non-constant array word select into a * constant word select. */ vpiHandle array = vpi_handle(vpiParent, item); PLI_INT32 idx = vpi_get(vpiIndex, item); item = vpi_handle_by_index(array, idx); } // fallthrough case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: case vpiReg: case vpiNet: /* An array word is implicitly escaped so look for an * escaped identifier that this could conflict with. */ if (vpi_get(vpiType, item) == vpiMemoryWord && vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) { vpi_printf("LXT warning: dumping array word %s will " "conflict with an escaped identifier.\n", vpi_get_str(vpiFullName, item)); } if (skip || vpi_get(vpiAutomatic, item)) break; name = vpi_get_str(vpiName, item); nexus_id = vpi_get(_vpiNexusId, item); if (nexus_id) { ident = find_nexus_ident(nexus_id); } else { ident = 0; } if (!ident) { char*tmp = create_full_name(name); ident = strdup_sh(&name_heap, tmp); free(tmp); if (nexus_id) set_nexus_ident(nexus_id, ident); info = malloc(sizeof(*info)); info->time.type = vpiSimTime; info->item = item; info->sym = lt_symbol_add(dump_file, ident, 0 /* array rows */, vpi_get(vpiLeftRange, item), vpi_get(vpiRightRange, item), LT_SYM_F_BITS); info->scheduled = 0; cb.time = &info->time; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->next = vcd_list; vcd_list = info; info->cb = vpi_register_cb(&cb); } else { char *n = create_full_name(name); lt_symbol_alias(dump_file, ident, n, vpi_get(vpiSize, item)-1, 0); free(n); } break; case vpiRealVar: if (skip || vpi_get(vpiAutomatic, item)) break; name = vpi_get_str(vpiName, item); { char*tmp = create_full_name(name); ident = strdup_sh(&name_heap, tmp); free(tmp); } info = malloc(sizeof(*info)); info->time.type = vpiSimTime; info->item = item; info->sym = lt_symbol_add(dump_file, ident, 0 /* array rows */, vpi_get(vpiSize, item)-1, 0, LT_SYM_F_DOUBLE); info->scheduled = 0; cb.time = &info->time; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->next = vcd_list; vcd_list = info; info->cb = vpi_register_cb(&cb); break; case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: if (depth > 0) { const char* fullname = vpi_get_str(vpiFullName, item); /* list of types to iterate upon */ static int types[] = { /* Value */ /* vpiNamedEvent, */ vpiNet, /* vpiParameter, */ vpiReg, vpiVariables, /* Scope */ vpiFunction, vpiGenScope, vpiModule, vpiNamedBegin, vpiNamedFork, vpiTask, -1 }; int i; int nskip = (vcd_names_search(&lxt_tab, fullname) != 0); #if 0 vpi_printf("LXT info: scanning scope %s, %u levels\n", fullname, depth); #endif if (nskip) { vpi_printf("LXT warning: ignoring signals in " "previously scanned scope %s\n", fullname); } else { vcd_names_add(&lxt_tab, fullname); } name = vpi_get_str(vpiName, item); push_scope(name); for (i=0; types[i]>0; i++) { vpiHandle hand; vpiHandle argv = vpi_iterate(types[i], item); while (argv && (hand = vpi_scan(argv))) { scan_item(depth-1, hand, nskip); } } pop_scope(); } break; case vpiPackage: /* Skipped */ vpi_printf("LXT warning: $dumpvars: Package (%s) is not dumpable " "with LXT.\n", vpi_get_str(vpiFullName, item)); break; default: vpi_printf("LXT warning: $dumpvars: Unsupported parameter " "type (%s).\n", vpi_get_str(vpiType, item)); } } static int draw_scope(vpiHandle item) { int depth; const char *name; vpiHandle scope = vpi_handle(vpiScope, item); if (!scope) return 0; depth = 1 + draw_scope(scope); name = vpi_get_str(vpiName, scope); push_scope(name); return depth; } static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; s_vpi_value value; unsigned depth = 0; (void)name; /* Parameter is not used. */ if (dump_file == 0) { open_dumpfile(callh); if (dump_file == 0) { if (argv) vpi_free_object(argv); return 0; } } if (install_dumpvars_callback()) { if (argv) vpi_free_object(argv); return 0; } /* Get the depth if it exists. */ if (argv) { value.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &value); depth = value.value.integer; } if (!depth) depth = 10000; /* This dumps all the instances in the design if none are given. */ if (!argv || !(item = vpi_scan(argv))) { argv = vpi_iterate(vpiInstance, 0x0); assert(argv); /* There must be at least one top level instance. */ item = vpi_scan(argv); } for ( ; item; item = vpi_scan(argv)) { int dep = draw_scope(item); scan_item(depth, item, 0); /* The scope list must be sorted after we scan an item. */ vcd_names_sort(&lxt_tab); while (dep--) pop_scope(); } /* Most effective compression. */ if (lxm_optimum_mode == LXM_SPACE) { lt_set_no_interlace(dump_file); } return 0; } void sys_lxt_register(void) { int idx; struct t_vpi_vlog_info vlog_info; s_vpi_systf_data tf_data; vpiHandle res; /* Scan the extended arguments, looking for lxt optimization flags. */ vpi_get_vlog_info(&vlog_info); /* The "speed" option is not used in this dumper. */ for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-lxt-space") == 0) { lxm_optimum_mode = LXM_SPACE; } else if (strcmp(vlog_info.argv[idx],"-lxt-speed") == 0) { lxm_optimum_mode = LXM_SPEED; } } /* All the compiletf routines are located in vcd_priv.c. */ tf_data.type = vpiSysTask; tf_data.tfname = "$dumpall"; tf_data.calltf = sys_dumpall_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpfile"; tf_data.calltf = sys_dumpfile_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpfile"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpflush"; tf_data.calltf = sys_dumpflush_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumplimit"; tf_data.calltf = sys_dumplimit_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumplimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpoff"; tf_data.calltf = sys_dumpoff_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpon"; tf_data.calltf = sys_dumpon_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpon"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_lxt2.c000066400000000000000000000616241435245347300161110ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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. */ /* The sys_priv.h include must be before the lxt2_write.h include! */ # include "sys_priv.h" # include "lxt2_write.h" # include "vcd_priv.h" /* * This file contains the implementations of the LXT2 related functions. */ # include # include # include # include # include "stringheap.h" # include # include "ivl_alloc.h" static char *dump_path = NULL; static struct lxt2_wr_trace *dump_file = NULL; static void* lxt2_thread(void*arg); static struct t_vpi_time zero_delay = { vpiSimTime, 0, 0, 0.0 }; /* * Manage a table of all the dump-enabled vcd item. The cells of this * table are allocated incrementally, but are released all at once, so * we can allocate the items in chunks. */ struct vcd_info { vpiHandle item; vpiHandle cb; struct lxt2_wr_symbol *sym; struct vcd_info *dmp_next; }; struct vcd_info_chunk { struct vcd_info_chunk*chunk_next; uint16_t chunk_fill; struct vcd_info data[0x10000]; }; struct vcd_info_chunk*info_chunk_list = 0; struct vcd_info*new_vcd_info(void) { struct vcd_info_chunk*cur_chunk = info_chunk_list; if (cur_chunk == 0 || cur_chunk->chunk_fill == 0xffff) { struct vcd_info_chunk*tmp = calloc(1, sizeof(struct vcd_info_chunk)); tmp->chunk_fill = 0; tmp->chunk_next = cur_chunk; info_chunk_list = cur_chunk = tmp; return info_chunk_list->data + 0; } cur_chunk->chunk_fill += 1; struct vcd_info*ptr = cur_chunk->data + cur_chunk->chunk_fill; return ptr; } void functor_all_vcd_info( void (*fun) (struct vcd_info*info) ) { struct vcd_info_chunk*cur; for (cur = info_chunk_list ; cur ; cur = cur->chunk_next) { int idx; struct vcd_info*ptr; for (idx=0, ptr=cur->data ; idx <= cur->chunk_fill ; idx += 1, ptr += 1) fun (ptr); } } void delete_all_vcd_info(void) { while (info_chunk_list) { struct vcd_info_chunk*tmp = info_chunk_list->chunk_next; free(info_chunk_list); info_chunk_list = tmp; } } /* * Use this pointer to keep a list of vcd_info items that are * scheduled to be dumped. Use the VCD_INFO_ENDP value as a trailer * pointer instead of 0 so that individual vcd_info objects can tell * if they are in the list already, even if they are at the end of the * list. */ # define VCD_INFO_ENDP ((struct vcd_info*)1) static struct vcd_info *vcd_dmp_list = VCD_INFO_ENDP; static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; static int finish_status = 0; static enum lxm_optimum_mode_e { LXM_NONE = 0, LXM_SPACE = 1, LXM_SPEED = 2 } lxm_optimum_mode = LXM_SPEED; static off_t lxt2_file_size_limit = 0x40000000UL; /* * The lxt_scope head and current pointers are used to keep a scope * stack that can be accessed from the bottom. The lxt_scope_head * points to the first (bottom) item in the stack and * lxt_scope_current points to the last (top) item in the stack. The * push_scope and pop_scope methods manipulate the stack. */ struct lxt_scope { struct lxt_scope *next, *prev; char *name; int len; }; static struct lxt_scope *lxt_scope_head=NULL, *lxt_scope_current=NULL; static void push_scope(const char *name) { struct lxt_scope *t = (struct lxt_scope *) calloc(1, sizeof(struct lxt_scope)); t->name = strdup(name); t->len = strlen(name); if(!lxt_scope_head) { lxt_scope_head = lxt_scope_current = t; } else { lxt_scope_current->next = t; t->prev = lxt_scope_current; lxt_scope_current = t; } } static void pop_scope(void) { struct lxt_scope *t; assert(lxt_scope_current); t=lxt_scope_current->prev; free(lxt_scope_current->name); free(lxt_scope_current); lxt_scope_current = t; if (lxt_scope_current) { lxt_scope_current->next = 0; } else { lxt_scope_head = 0; } } /* * This function uses the scope stack to generate a hierarchical * name. Scan the scope stack from the bottom up to construct the * name. */ static char *create_full_name(const char *name) { char *n, *n2; int len = 0; int is_esc_id = is_escaped_id(name); struct lxt_scope *t = lxt_scope_head; /* Figure out how long the combined string will be. */ while(t) { len+=t->len+1; t=t->next; } len += strlen(name) + 1; if (is_esc_id) len += 1; /* Allocate a string buffer. */ n = n2 = malloc(len); t = lxt_scope_head; while(t) { strcpy(n2, t->name); n2 += t->len; *n2 = '.'; n2++; t=t->next; } if (is_esc_id) { *n2 = '\\'; n2++; } strcpy(n2, name); n2 += strlen(n2); assert( (n2 - n + 1) == len ); return n; } static void show_this_item(struct vcd_info*info) { s_vpi_value value; if (vpi_get(vpiType, info->item) == vpiRealVar) { value.format = vpiRealVal; vpi_get_value(info->item, &value); vcd_work_emit_double(info->sym, value.value.real); } else { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); vcd_work_emit_bits(info->sym, value.value.str); } } static void show_this_item_x(struct vcd_info*info) { if (vpi_get(vpiType,info->item) == vpiRealVar) { /* Should write a NaN here? */ } else { vcd_work_emit_bits(info->sym, "x"); } } static int dumpvars_status = 0; /* 0:fresh 1:cb installed, 2:callback done */ static PLI_UINT64 dumpvars_time; __inline__ static int dump_header_pending(void) { return dumpvars_status != 2; } /* * This function writes out all the traced variables, whether they * changed or not. */ static void vcd_checkpoint(void) { functor_all_vcd_info( show_this_item ); } static void vcd_checkpoint_x(void) { functor_all_vcd_info( show_this_item_x ); } static PLI_INT32 variable_cb_2(p_cb_data cause) { assert(cause->time->type == vpiSimTime); PLI_UINT64 now = timerec_to_time64(cause->time); if (now != vcd_cur_time) { vcd_work_set_time(now); vcd_cur_time = now; } while (vcd_dmp_list != VCD_INFO_ENDP) { struct vcd_info* info = vcd_dmp_list; show_this_item(info); vcd_dmp_list = info->dmp_next; info->dmp_next = 0; } return 0; } static PLI_INT32 variable_cb_1(p_cb_data cause) { struct t_cb_data cb; struct vcd_info*info = (struct vcd_info*)cause->user_data; if (dump_is_full) return 0; if (dump_is_off) return 0; if (dump_header_pending()) return 0; if (info->dmp_next) return 0; if ((dump_limit > 0) && (ftell(dump_file->handle) > dump_limit)) { dump_is_full = 1; vpi_printf("WARNING: Dump file limit (%ld bytes) " "exceeded.\n", dump_limit); return 0; } if (vcd_dmp_list == VCD_INFO_ENDP) { cb = *cause; cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = variable_cb_2; vpi_register_cb(&cb); } info->dmp_next = vcd_dmp_list; vcd_dmp_list = info; return 0; } static PLI_INT32 dumpvars_cb(p_cb_data cause) { if (dumpvars_status != 1) return 0; dumpvars_status = 2; dumpvars_time = timerec_to_time64(cause->time); vcd_cur_time = dumpvars_time; if (!dump_is_off) { vcd_work_set_time(dumpvars_time); vcd_checkpoint(); } return 0; } static PLI_INT32 finish_cb(p_cb_data cause) { if (finish_status != 0) return 0; finish_status = 1; dumpvars_time = timerec_to_time64(cause->time); if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) { vcd_work_set_time(dumpvars_time); } vcd_work_terminate(); delete_all_vcd_info(); vcd_scope_names_delete(); nexus_ident_delete(); free(dump_path); dump_path = 0; return 0; } __inline__ static int install_dumpvars_callback(void) { struct t_cb_data cb; if (dumpvars_status == 1) return 0; if (dumpvars_status == 2) { vpi_printf("LXT2 warning: $dumpvars ignored, previously" " called at simtime %" PLI_UINT64_FMT "\n", dumpvars_time); return 1; } cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = dumpvars_cb; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); cb.reason = cbEndOfSimulation; cb.cb_rtn = finish_cb; vpi_register_cb(&cb); dumpvars_status = 1; return 0; } static PLI_INT32 sys_dumpoff_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; dump_is_off = 1; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { vcd_work_set_time(now64); vcd_cur_time = now64; } vcd_work_dumpoff(); vcd_checkpoint_x(); return 0; } static PLI_INT32 sys_dumpon_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (!dump_is_off) return 0; dump_is_off = 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { vcd_work_set_time(now64); vcd_cur_time = now64; } vcd_work_dumpon(); vcd_checkpoint(); return 0; } static PLI_INT32 sys_dumpall_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { vcd_work_set_time(now64); vcd_cur_time = now64; } vcd_checkpoint(); return 0; } static void *close_dumpfile(void) { vcd_work_terminate(); lxt2_wr_close(dump_file); dump_file = NULL; return NULL; } static void open_dumpfile(vpiHandle callh) { off_t use_file_size_limit = lxt2_file_size_limit; if (dump_path == 0) dump_path = strdup("dump.lx2"); dump_file = lxt2_wr_init(dump_path); if (getenv("LXT_FILE_SIZE_LIMIT")) { const char*limit_string = getenv("LXT_FILE_SIZE_LIMIT"); char*ep; use_file_size_limit = strtoul(limit_string,&ep,0); if (use_file_size_limit == 0 || ep[0] != 0) { vpi_printf("LXT2 Warning: %s:%d: LXT_FILE_SIZE_LIMIT is invalid: %s\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), limit_string); use_file_size_limit = lxt2_file_size_limit; } } if (dump_file == 0) { vpi_printf("LXT2 Error: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open %s for output.\n", dump_path); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(dump_path); dump_path = 0; return; } else { int prec = vpi_get(vpiTimePrecision, 0); vpi_printf("LXT2 info: dumpfile %s opened for output.\n", dump_path); assert(prec >= -15); lxt2_wr_set_timescale(dump_file, prec); lxt2_wr_set_initial_value(dump_file, 'x'); lxt2_wr_set_compression_depth(dump_file, 4); lxt2_wr_set_partial_on(dump_file, 1); lxt2_wr_set_break_size(dump_file, use_file_size_limit); vcd_work_start(lxt2_thread, 0); atexit((void(*)(void))close_dumpfile); } } static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); char *path; /* $dumpfile must be called before $dumpvars starts! */ if (dumpvars_status != 0) { char msg[64]; snprintf(msg, sizeof(msg), "LXT2 warning: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s called after $dumpvars started,\n", msg, name); vpi_printf("%*s using existing file (%s).\n", (int) strlen(msg), " ", dump_path); vpi_free_object(argv); return 0; } path = get_filename_with_suffix(callh, name, vpi_scan(argv), "lx2"); vpi_free_object(argv); if (! path) return 0; if (dump_path) { vpi_printf("LXT2 warning: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Overriding dump file %s with %s.\n", dump_path, path); free(dump_path); } dump_path = path; return 0; } /* * The LXT2 format is a binary format, but a $dumpflush causes what is * in the binary file at the moment to be consistent with itself so * that the waveforms can be read by another process. LXT2 normally * writes checkpoints out, but this makes it happen at a specific * time. */ static PLI_INT32 sys_dumpflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ if (dump_file) vcd_work_flush(); return 0; } static PLI_INT32 sys_dumplimit_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; (void)name; /* Parameter is not used. */ /* Get the value and set the dump limit. */ assert(argv); val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); dump_limit = val.value.integer; vpi_free_object(argv); return 0; } static void scan_item(unsigned depth, vpiHandle item, int skip) { struct t_cb_data cb; struct vcd_info* info; const char* name; const char* ident; int nexus_id; switch (vpi_get(vpiType, item)) { case vpiMemoryWord: if (vpi_get(vpiConstantSelect, item) == 0) { /* Turn a non-constant array word select into a * constant word select. */ vpiHandle array = vpi_handle(vpiParent, item); PLI_INT32 idx = vpi_get(vpiIndex, item); item = vpi_handle_by_index(array, idx); } // fallthrough case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: case vpiReg: case vpiNet: /* An array word is implicitly escaped so look for an * escaped identifier that this could conflict with. */ if (vpi_get(vpiType, item) == vpiMemoryWord && vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) { vpi_printf("LXT2 warning: dumping array word %s will " "conflict with an escaped identifier.\n", vpi_get_str(vpiFullName, item)); } if (skip || vpi_get(vpiAutomatic, item)) break; name = vpi_get_str(vpiName, item); nexus_id = vpi_get(_vpiNexusId, item); if (nexus_id) { ident = find_nexus_ident(nexus_id); } else { ident = 0; } if (!ident) { char*tmp = create_full_name(name); ident = strdup_sh(&name_heap, tmp); free(tmp); if (nexus_id) set_nexus_ident(nexus_id, ident); info = new_vcd_info(); info->item = item; info->sym = lxt2_wr_symbol_add(dump_file, ident, 0 /* array rows */, vpi_get(vpiLeftRange, item), vpi_get(vpiRightRange, item), LXT2_WR_SYM_F_BITS); info->dmp_next = 0; cb.time = 0; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->cb = vpi_register_cb(&cb); } else { char *n = create_full_name(name); lxt2_wr_symbol_alias(dump_file, ident, n, vpi_get(vpiSize, item)-1, 0); free(n); } break; case vpiRealVar: if (skip || vpi_get(vpiAutomatic, item)) break; name = vpi_get_str(vpiName, item); { char*tmp = create_full_name(name); ident = strdup_sh(&name_heap, tmp); free(tmp); } info = new_vcd_info(); info->item = item; info->sym = lxt2_wr_symbol_add(dump_file, ident, 0 /* array rows */, vpi_get(vpiSize, item)-1, 0, LXT2_WR_SYM_F_DOUBLE); info->dmp_next = 0; cb.time = 0; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->cb = vpi_register_cb(&cb); break; case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: if (depth > 0) { const char* fullname = vpi_get_str(vpiFullName, item); /* list of types to iterate upon */ static int types[] = { /* Value */ /* vpiNamedEvent, */ vpiNet, /* vpiParameter, */ vpiReg, vpiVariables, /* Scope */ vpiFunction, vpiGenScope, vpiModule, vpiNamedBegin, vpiNamedFork, vpiTask, -1 }; int i; int nskip = vcd_scope_names_test(fullname); #if 0 vpi_printf("LXT2 info: scanning scope %s, %u levels\n", fullname, depth); #endif if (nskip) { vpi_printf("LXT2 warning: ignoring signals in " "previously scanned scope %s\n", fullname); } else { vcd_scope_names_add(fullname); } name = vpi_get_str(vpiName, item); push_scope(name); for (i=0; types[i]>0; i++) { vpiHandle hand; vpiHandle argv = vpi_iterate(types[i], item); while (argv && (hand = vpi_scan(argv))) { scan_item(depth-1, hand, nskip); } } pop_scope(); } break; case vpiPackage: vpi_printf("LXT2 warning: $dumpvars: Package (%s) is not dumpable " "with LXT2.\n", vpi_get_str(vpiFullName, item)); break; default: vpi_printf("LXT2 warning: $dumpvars: Unsupported parameter " "type (%s).\n", vpi_get_str(vpiType, item)); } } static int draw_scope(vpiHandle item) { int depth; const char *name; vpiHandle scope = vpi_handle(vpiScope, item); if (!scope) return 0; depth = 1 + draw_scope(scope); name = vpi_get_str(vpiName, scope); push_scope(name); return depth; } static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; s_vpi_value value; unsigned depth = 0; (void)name; /* Parameter is not used. */ if (dump_file == 0) { open_dumpfile(callh); if (dump_file == 0) { if (argv) vpi_free_object(argv); return 0; } } if (install_dumpvars_callback()) { if (argv) vpi_free_object(argv); return 0; } /* Get the depth if it exists. */ if (argv) { value.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &value); depth = value.value.integer; } if (!depth) depth = 10000; /* This dumps all the instances in the design if none are given. */ if (!argv || !(item = vpi_scan(argv))) { argv = vpi_iterate(vpiInstance, 0x0); assert(argv); /* There must be at least one top level instance. */ item = vpi_scan(argv); } for ( ; item; item = vpi_scan(argv)) { int dep = draw_scope(item); scan_item(depth, item, 0); while (dep--) pop_scope(); } /* Most effective compression. */ if (lxm_optimum_mode == LXM_SPACE) { lxt2_wr_set_compression_depth(dump_file, 9); lxt2_wr_set_partial_off(dump_file); } return 0; } static void* lxt2_thread(void*arg) { /* Keep track of the current time, and only call the set_time function when the time changes. */ uint64_t cur_time = 0; int run_flag = 1; (void)arg; /* Parameter is not used. */ while (run_flag) { struct vcd_work_item_s*cell = vcd_work_thread_peek(); if (cell->time != cur_time) { cur_time = cell->time; lxt2_wr_set_time64(dump_file, cur_time); } switch (cell->type) { case WT_NONE: break; case WT_FLUSH: lxt2_wr_flush(dump_file); break; case WT_DUMPON: lxt2_wr_set_dumpon(dump_file); break; case WT_DUMPOFF: lxt2_wr_set_dumpoff(dump_file); break; case WT_EMIT_DOUBLE: lxt2_wr_emit_value_double(dump_file, cell->sym_.lxt2, 0, cell->op_.val_double); break; case WT_EMIT_BITS: lxt2_wr_emit_value_bit_string(dump_file, cell->sym_.lxt2, 0, cell->op_.val_char); break; case WT_TERMINATE: run_flag = 0; break; } vcd_work_thread_pop(); } return 0; } void sys_lxt2_register(void) { int idx; struct t_vpi_vlog_info vlog_info; s_vpi_systf_data tf_data; vpiHandle res; /* Scan the extended arguments, looking for lxt2 optimization flags. */ vpi_get_vlog_info(&vlog_info); /* The "speed" option is not used in this dumper. */ for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-lxt2-space") == 0) { lxm_optimum_mode = LXM_SPACE; } else if (strcmp(vlog_info.argv[idx],"-lxt2-speed") == 0) { lxm_optimum_mode = LXM_SPEED; } else if (strcmp(vlog_info.argv[idx],"-lx2-space") == 0) { lxm_optimum_mode = LXM_SPACE; } else if (strcmp(vlog_info.argv[idx],"-lx2-speed") == 0) { lxm_optimum_mode = LXM_SPEED; } } /* All the compiletf routines are located in vcd_priv.c. */ tf_data.type = vpiSysTask; tf_data.tfname = "$dumpall"; tf_data.calltf = sys_dumpall_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpfile"; tf_data.calltf = sys_dumpfile_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpfile"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpflush"; tf_data.calltf = sys_dumpflush_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumplimit"; tf_data.calltf = sys_dumplimit_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumplimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpoff"; tf_data.calltf = sys_dumpoff_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpon"; tf_data.calltf = sys_dumpon_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpon"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_plusargs.c000066400000000000000000000303241435245347300170510ustar00rootroot00000000000000/* * Copyright (c) 2002-2021 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 "sys_priv.h" # include # include # include /* * Compare the +arguments passed to the simulator with the argument * passed to the $test$plusargs. If there is a simulator argument that * is like this argument, then return true. Otherwise return false. */ static PLI_INT32 sys_test_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_value val; s_vpi_vlog_info info; int idx; int flag = 0; size_t slen, len; (void)name; /* Parameter is not used. */ vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); val.format = vpiStringVal; vpi_get_value(vpi_scan(argv), &val); slen = strlen(val.value.str); vpi_get_vlog_info(&info); /* Look for a +arg that matches the prefix supplied. */ for (idx = 0 ; idx < info.argc ; idx += 1) { /* Skip arguments that are not +args. */ if (info.argv[idx][0] != '+') continue; len = strlen(info.argv[idx]+1); if (len < slen) continue; if (strncmp(val.value.str, info.argv[idx]+1, slen) != 0) continue; flag = 1; break; } val.format = vpiIntVal; val.value.integer = flag; vpi_put_value(callh, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_value_plusargs_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first argument is a string. */ arg = vpi_scan(argv); assert(arg != 0); if ( ! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's requires a second variable argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } switch (vpi_get(vpiType, arg)) { case vpiReg: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiRealVar: case vpiTimeVar: case vpiStringVar: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be a variable, found a %s.\n", name, vpi_get_str(vpiType, arg)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } static PLI_INT32 sys_value_plusargs_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_vlog_info info; s_vpi_value fmt; s_vpi_value res; char msg[64]; char*cp; int idx; int flag = 0; size_t slen, len; vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); fmt.format = vpiStringVal; vpi_get_value(vpi_scan(argv), &fmt); /* Check for the start of a format string. */ cp = strchr(fmt.value.str, '%'); if (cp == 0) { snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s is missing a format code.\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* This is the length of string we will look for. */ slen = cp - fmt.value.str; /* Skip a zero. */ cp += 1; if (*cp == '0') cp += 1; /* Check the format code. */ switch (*cp) { case 'd': case 'D': case 'o': case 'O': case 'h': case 'H': case 'x': case 'X': case 'b': case 'B': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': case 's': case 'S': break; default: snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s has an invalid format string:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Warn if there is any trailing garbage. */ if (*(cp+1) != '\0') { snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Skipping trailing garbage in %s's format string:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", fmt.value.str); *(cp+1) = '\0'; } vpi_get_vlog_info(&info); /* Look for a +arg that matches the prefix supplied. */ for (idx = 0 ; idx < info.argc ; idx += 1) { char*sp, *tp, *end; size_t sp_len; /* Skip arguments that are not +args. */ if (info.argv[idx][0] != '+') continue; len = strlen(info.argv[idx]+1); if (len < slen) continue; if (strncmp(fmt.value.str, info.argv[idx]+1, slen) != 0) continue; sp = info.argv[idx]+1+slen; sp_len = strlen(sp); switch (*cp) { case 'd': case 'D': res.format = vpiDecStrVal; /* A decimal string can set the value to "x" or "z". */ if (sp_len == strspn(sp, "xX_") || sp_len == strspn(sp, "zZ_")) { res.value.str = sp; /* A decimal string must contain only these characters. * A decimal string can not start with an "_" character. * A "-" can only be at the start of the string. */ } else if (sp_len != strspn(sp, "-0123456789_") || *sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) { res.value.str = "x"; snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Invalid decimal value passed to %s:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); } else { res.value.str = sp; } break; case 'o': case 'O': res.format = vpiOctStrVal; /* An octal string must contain only these characters. * An octal string can not start with an "_" character. * A "-" can only be at the start of the string. */ if (sp_len != strspn(sp, "-01234567_xXzZ") || *sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) { res.value.str = "x"; snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Invalid octal value passed to %s:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); } else { res.value.str = sp; } break; case 'h': case 'H': case 'x': case 'X': res.format = vpiHexStrVal; /* A hex. string must contain only these characters. * A hex. string can not start with an "_" character. * A "-" can only be at the start of the string. */ if (sp_len != strspn(sp, "-0123456789aAbBcCdDeEfF_xXzZ") || *sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) { res.value.str = "x"; snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Invalid hex value passed to %s:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); } else { res.value.str = sp; } break; case 'b': case 'B': res.format = vpiBinStrVal; /* A binary string must contain only these characters. * A binary string can not start with an "_" character. * A "-" can only be at the start of the string. */ if (sp_len != strspn(sp, "-01_xXzZ") || *sp == '_' || ((tp = strrchr(sp, '-')) && tp != sp)) { res.value.str = "x"; snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Invalid binary value passed to %s:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); } else { res.value.str = sp; } break; case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': res.format = vpiRealVal; res.value.real = strtod(sp, &end); /* If we didn't get a full conversion print a warning. */ if (*end) { /* We had an invalid value passed. */ if (end == sp) { snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Invalid real value passed to " "%s:\n", msg, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); /* We have extra garbage at the end. */ } else { snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s Extra character(s) \"%s\" found " "in %s's real string:\n", msg, end, name); vpi_printf("%*s \"%s\".\n", (int)strlen(msg), " ", sp); } } break; case 's': case 'S': res.format = vpiStringVal; res.value.str = sp; break; default: assert(0); } vpi_put_value(vpi_scan(argv), &res, 0, vpiNoDelay); flag = 1; break; } res.format = vpiIntVal; res.value.integer = flag; vpi_put_value(callh, &res, 0, vpiNoDelay); vpi_free_object(argv); return 0; } void sys_plusargs_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$test$plusargs"; tf_data.calltf = sys_test_plusargs_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$test$plusargs"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$value$plusargs"; tf_data.calltf = sys_value_plusargs_calltf; tf_data.compiletf = sys_value_plusargs_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$value$plusargs"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_priv.c000066400000000000000000000346451435245347300162030ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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 "sys_priv.h" #include #include #include #include #include #include "ivl_alloc.h" PLI_UINT64 timerec_to_time64(const struct t_vpi_time*timerec) { PLI_UINT64 tmp; tmp = timerec->high; tmp <<= 32; tmp |= (PLI_UINT64) timerec->low; return tmp; } char *as_escaped(char *arg) { unsigned idx, cur, cnt, len = strlen(arg) + 1; char *res = (char *) malloc(sizeof(char) * len); cur = 0; cnt = len - 1; for (idx = 0; idx < cnt; idx++) { if (isprint((int)arg[idx])) { res[cur] = arg[idx]; cur += 1; } else { len += 3; res = (char *) realloc(res, sizeof(char) * len); sprintf(&(res[cur]), "\\%03o", arg[idx]); cur += 4; } } res[cur] = 0; return res; } /* * Generic routine to get the filename from the given handle. * The result is duplicated so call free when the name is no * longer needed. Returns 0 (NULL) for an error. */ char *get_filename(vpiHandle callh, const char *name, vpiHandle file) { s_vpi_value val; unsigned len, idx; /* Get the filename. */ val.format = vpiStringVal; vpi_get_value(file, &val); /* Verify that we have a string and that it is not NULL. */ if (val.format != vpiStringVal || !*(val.value.str)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's file name argument (%s) is not a valid string.\n", name, vpi_get_str(vpiType, file)); return 0; } /* * Verify that the file name is composed of only printable * characters. */ len = strlen(val.value.str); for (idx = 0; idx < len; idx++) { if (! isprint((int)val.value.str[idx])) { char msg[64]; char *esc_fname = as_escaped(val.value.str); snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s's file name argument contains non-" "printable characters.\n", msg, name); vpi_printf("%*s \"%s\"\n", (int) strlen(msg), " ", esc_fname); free(esc_fname); return 0; } } return strdup(val.value.str); } char* get_filename_with_suffix(vpiHandle callh, const char *name, vpiHandle file, const char*suff) { char*path = get_filename(callh, name, file); if (path == 0) return 0; /* If the name already has a suffix, then don't replace it or add another suffix. Just return this path. */ char*tailp = strrchr(path, '.'); if (tailp != 0) return path; /* The name doesn't have a suffix, so append the passed in suffix to the file name. */ char*new_path = malloc(strlen(path) + strlen(suff) + 2); strcpy(new_path, path); strcat(new_path, "."); strcat(new_path, suff); free(path); return new_path; } void check_for_extra_args(vpiHandle argv, vpiHandle callh, const char *name, const char *arg_str, unsigned opt) { /* Check that there are no extra arguments. */ if (vpi_scan(argv) != 0) { char msg[64]; unsigned argc; snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; argc = 1; while (vpi_scan(argv)) argc += 1; vpi_printf("%s %s takes %s%s.\n", msg, name, opt ? "at most ": "", arg_str); vpi_printf("%*s Found %u extra argument%s.\n", (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } /* * This routine returns 1 if the argument is a constant value, * otherwise it returns 0. * * This routine was also copied to sys_clog2.c since it is not * part of the standard system functions. */ unsigned is_constant_obj(vpiHandle obj) { unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { case vpiConstant: case vpiParameter: rtn = 1; break; } return rtn; } /* * This routine returns 1 if the argument supports has a numeric value, * otherwise it returns 0. */ unsigned is_numeric_obj(vpiHandle obj) { unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { case vpiConstant: case vpiParameter: /* These cannot be a string constant. */ if (vpi_get(vpiConstType, obj) != vpiStringConst) rtn = 1; break; /* These can have a valid numeric value. */ case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNet: case vpiPartSelect: case vpiRealVar: case vpiReg: case vpiTimeVar: rtn = 1; break; } return rtn; } /* * This routine returns 1 if the argument supports a valid string value, * otherwise it returns 0. */ unsigned is_string_obj(vpiHandle obj) { unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { case vpiConstant: case vpiParameter: { /* These must be a string or binary constant. */ PLI_INT32 ctype = vpi_get(vpiConstType, obj); if (ctype == vpiStringConst || ctype == vpiBinaryConst) rtn = 1; break; } /* These can have a valid string value. */ case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNet: case vpiPartSelect: case vpiReg: case vpiTimeVar: case vpiStringVar: rtn = 1; break; } return rtn; } /* * Check if the file descriptor or MCD is valid. * For a MCD check that every bit set is a valid file and * for a FD make sure it exists. */ unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd) { assert(fd_mcd); // Should already be handled! if (IS_MCD(fd_mcd)){ if (vpi_mcd_printf(fd_mcd, "%s", "") == EOF) return 0; } else { if (vpi_get_file(fd_mcd) == NULL) return 0; } return 1; } /* * Get a FD/MCD from the given argument and check if it is valid. Return the * FD/MCD in the fd_mcd argument and return 0 if it is valid and 1 if it is * invalid. We do not print a warning mesage if the FD/MCD is zero. */ unsigned get_fd_mcd_from_arg(PLI_UINT32 *fd_mcd, vpiHandle arg, vpiHandle callh, const char *name) { s_vpi_value val; val.format = vpiIntVal; vpi_get_value(arg, &val); *fd_mcd = val.value.integer; if (*fd_mcd == 0) return 1; errno = 0; if (! is_valid_fd_mcd(*fd_mcd)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid %s (0x%x) given to %s().\n", IS_MCD(*fd_mcd) ? "MCD" : "file descriptor", (unsigned int)*fd_mcd, name); errno = EBADF; return 1; } return 0; } /* * Find the enclosing module. If there is no enclosing module (which can be * the case in SystemVerilog), return the highest enclosing scope. */ vpiHandle sys_func_module(vpiHandle obj) { assert(obj); while (vpi_get(vpiType, obj) != vpiModule) { vpiHandle scope = vpi_handle(vpiScope, obj); if (scope == 0) break; obj = scope; } return obj; } /* * Standard compiletf routines. */ /* For system tasks/functions that do not take an argument. */ PLI_INT32 sys_no_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* Make sure there are no arguments. */ if (argv != 0) { char msg[64]; unsigned argc; snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; argc = 0; while (vpi_scan(argv)) argc += 1; vpi_printf("%s %s does not take an argument.\n", msg, name); vpi_printf("%*s Found %u extra argument%s.\n", (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } /* For system tasks/functions that take a single numeric argument. */ PLI_INT32 sys_one_numeric_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* Check that there is an argument and that it is numeric. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a single numeric argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "a single numeric argument", 0); return 0; } /* For system tasks/functions that take a single optional numeric argument. */ PLI_INT32 sys_one_opt_numeric_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* The argument is optional so just return if none are found. */ if (argv == 0) return 0; if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "one numeric argument", 1); return 0; } /* For system tasks/functions that take two numeric arguments. */ PLI_INT32 sys_two_numeric_args_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are two argument and that they are numeric. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two numeric arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (numeric) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two numeric arguments", 0); return 0; } /* For system tasks/functions that take a single string argument. */ PLI_INT32 sys_one_string_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* Check that there is an argument and that it is a string. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a single string argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_string_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "a single string argument", 0); return 0; } /* Return an integer value to the caller. */ void put_integer_value(vpiHandle callh, PLI_INT32 result) { s_vpi_value val; val.format = vpiIntVal; val.value.integer = result; vpi_put_value(callh, &val, 0, vpiNoDelay); } /* Return a scalar value to the caller. */ void put_scalar_value(vpiHandle callh, PLI_INT32 result) { s_vpi_value val; val.format = vpiScalarVal; val.value.scalar = result; vpi_put_value(callh, &val, 0, vpiNoDelay); } iverilog-12_0/vpi/sys_priv.h000066400000000000000000000056621435245347300162050ustar00rootroot00000000000000#ifndef IVL_sys_priv_H #define IVL_sys_priv_H /* * Copyright (c) 2002-2020 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 "vpi_config.h" #include "sv_vpi_user.h" #define IS_MCD(mcd) !((mcd)>>31&1) /* * Context structure for PRNG in mt19937int.c */ struct context_s { int mti; /* the array for the state vector */ unsigned long mt[1023]; /* mti==N+1 means mt[N] is not init */ }; extern void sgenrand(struct context_s *context, unsigned long seed); extern unsigned long genrand(struct context_s *context); extern PLI_UINT64 timerec_to_time64(const struct t_vpi_time*timerec); extern char *as_escaped(char *arg); extern char *get_filename(vpiHandle callh, const char *name, vpiHandle file); extern char *get_filename_with_suffix(vpiHandle callh, const char*name, vpiHandle file, const char*suff); extern void check_for_extra_args(vpiHandle argv, vpiHandle callh, const char *name, const char *arg_str, unsigned opt); struct timeformat_info_s { int units; unsigned prec; char*suff; unsigned width; }; extern struct timeformat_info_s timeformat_info; extern unsigned is_constant_obj(vpiHandle obj); extern unsigned is_numeric_obj(vpiHandle obj); extern unsigned is_string_obj(vpiHandle obj); extern unsigned is_valid_fd_mcd(PLI_UINT32 fd_mcd); extern unsigned get_fd_mcd_from_arg(PLI_UINT32 *fd_mcd, vpiHandle arg, vpiHandle callh, const char *name); extern vpiHandle sys_func_module(vpiHandle obj); /* * The standard compiletf routines. */ extern PLI_INT32 sys_no_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); extern PLI_INT32 sys_one_numeric_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); extern PLI_INT32 sys_one_opt_numeric_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); extern PLI_INT32 sys_two_numeric_args_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); extern PLI_INT32 sys_one_string_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); /* * The standard put/return a value to the caller routines. */ extern void put_integer_value(vpiHandle callh, PLI_INT32 result); extern void put_scalar_value(vpiHandle callh, PLI_INT32 result); #endif /* IVL_sys_priv_H */ iverilog-12_0/vpi/sys_queue.c000066400000000000000000001271251435245347300163430ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ #include "sys_priv.h" #include #include #include #include "ivl_alloc.h" /* * The two queue types. */ #define IVL_QUEUE_FIFO 1 #define IVL_QUEUE_LIFO 2 /* * The statistical codes that can be passed to $q_exam(). */ #define IVL_QUEUE_LENGTH 1 #define IVL_QUEUE_MEAN 2 #define IVL_QUEUE_MAX_LENGTH 3 #define IVL_QUEUE_SHORTEST 4 #define IVL_QUEUE_LONGEST 5 #define IVL_QUEUE_AVERAGE 6 /* * All the values that can be returned by the queue tasks/function. */ #define IVL_QUEUE_OK 0 #define IVL_QUEUE_FULL 1 #define IVL_QUEUE_UNDEFINED_ID 2 #define IVL_QUEUE_EMPTY 3 #define IVL_QUEUE_UNSUPPORTED_TYPE 4 #define IVL_QUEUE_INVALID_LENGTH 5 #define IVL_QUEUE_DUPLICATE_ID 6 #define IVL_QUEUE_OUT_OF_MEMORY 7 /* Icarus specific status codes. */ #define IVL_QUEUE_UNDEFINED_STAT_CODE 8 #define IVL_QUEUE_VALUE_OVERFLOWED 9 #define IVL_QUEUE_NO_STATISTICS 10 /* * Routine to add the given time to the the total time (high/low). */ static void add_to_wait_time(uint64_t *high, uint64_t *low, uint64_t c_time) { uint64_t carry = 0U; if ((UINT64_MAX - *low) < c_time) carry = 1U; *low += c_time; assert((carry == 0U) || (*high < UINT64_MAX)); *high += carry; } /* * Routine to divide the given total time (high/low) by the number of * items to get the average. */ static uint64_t calc_average_wait_time(uint64_t high, uint64_t low, uint64_t total) { int bit = 64; uint64_t result = 0U; assert(total != 0U); if (high == 0U) return (low/total); /* This is true by design, but since we can only return 64 bits * make sure nothing went wrong. */ assert(high < total); /* It's a big value so calculate the average the long way. */ do { unsigned carry = 0U; /* Copy bits from low to high until we have a bit to place * in the result or there are no bits left. */ while ((bit >= 0) && (high < total) && !carry) { /* If the MSB is set then we will have a carry. */ if (high > (UINT64_MAX >> 1)) carry = 1U; high <<= 1; high |= (low & 0x8000000000000000) != 0; low <<= 1; bit -= 1; } /* If this is a valid bit, set the appropriate bit in the * result and subtract the total from the current value. */ if (bit >= 0) { result |= UINT64_C(1) << bit; high = high - total; } /* Loop until there are no bits left. */ } while (bit > 0); return result; } /* * The data structure used for an individual queue element. It hold four * state result for the jobs and inform fields along with the time that * the element was added in base time units. */ typedef struct t_ivl_queue_elem { uint64_t time; s_vpi_vecval job; s_vpi_vecval inform; } s_ivl_queue_elem, *p_ivl_queue_elem; /* * This structure is used to represent a specific queue. The time * information is in base simulation units. */ typedef struct t_ivl_queue_base { uint64_t shortest_wait_time; uint64_t first_add_time; uint64_t latest_add_time; uint64_t wait_time_high; uint64_t wait_time_low; uint64_t number_of_adds; p_ivl_queue_elem queue; PLI_INT32 id; PLI_INT32 length; PLI_INT32 type; PLI_INT32 head; PLI_INT32 elems; PLI_INT32 max_len; PLI_INT32 have_shortest_statistic; } s_ivl_queue_base, *p_ivl_queue_base; /* * For now we keep the queues in a vector since there are likely not too many * of them. We may need something more efficient later. */ static p_ivl_queue_base base = NULL; static int64_t base_len = 0; /* * This routine is called at the end of simulation to free the queue memory. */ static PLI_INT32 cleanup_queue(p_cb_data cause) { PLI_INT32 idx; (void) cause; /* Unused argument. */ for (idx = 0; idx < base_len; idx += 1) free(base[idx].queue); free(base); base = NULL; base_len = 0; return 0; } /* * Add a new queue to the list, return 1 if there is not enough memory, * otherwise return 0. */ static unsigned create_queue(PLI_INT32 id, PLI_INT32 type, PLI_INT32 length) { p_ivl_queue_base new_base; p_ivl_queue_elem queue; /* Allocate space for the new queue base. */ base_len += 1; new_base = (p_ivl_queue_base) realloc(base, base_len*sizeof(s_ivl_queue_base)); /* If we ran out of memory then fix the length and return a fail. */ if (new_base == NULL) { base_len -= 1; return 1; } base = new_base; /* Allocate space for the queue elements. */ queue = (p_ivl_queue_elem) malloc(length*sizeof(s_ivl_queue_elem)); /* If we ran out of memory then fix the length and return a fail. */ if (queue == NULL) { base_len -= 1; return 1; } /* The memory was allocated so configure it. */ base[base_len-1].queue = queue; base[base_len-1].id = id; base[base_len-1].length = length; base[base_len-1].type = type; base[base_len-1].head = 0; base[base_len-1].elems = 0; base[base_len-1].max_len = 0; base[base_len-1].shortest_wait_time = UINT64_MAX; base[base_len-1].first_add_time = 0U; base[base_len-1].latest_add_time = 0U; base[base_len-1].wait_time_high = 0U; base[base_len-1].wait_time_low = 0U; base[base_len-1].number_of_adds = 0U; base[base_len-1].have_shortest_statistic = 0; return 0; } /* * Check to see if the given queue is full. */ static unsigned is_queue_full(int64_t idx) { if (base[idx].elems >= base[idx].length) return 1; return 0; } /* * Add the job and inform to the queue. Return 1 if the queue is full, * otherwise return 0. */ static unsigned add_to_queue(int64_t idx, p_vpi_vecval job, p_vpi_vecval inform) { PLI_INT32 length = base[idx].length; PLI_INT32 type = base[idx].type; PLI_INT32 head = base[idx].head; PLI_INT32 elems = base[idx].elems; PLI_INT32 loc; s_vpi_time cur_time; uint64_t c_time; assert(elems <= length); /* If the queue is full we can't add anything. */ if (elems == length) return 1; /* Increment the number of element since one will be added.*/ base[idx].elems += 1; /* Save the job and inform to the queue. */ if (type == IVL_QUEUE_LIFO) { assert(head == 0); /* For a LIFO head must always be zero. */ loc = elems; } else { assert(type == IVL_QUEUE_FIFO); loc = head + elems; if (loc >= length) loc -= length; } base[idx].queue[loc].job.aval = job->aval; base[idx].queue[loc].job.bval = job->bval; base[idx].queue[loc].inform.aval = inform->aval; base[idx].queue[loc].inform.bval = inform->bval; /* Save the current time with this entry for the statistics. */ cur_time.type = vpiSimTime; vpi_get_time(NULL, &cur_time); c_time = cur_time.high; c_time <<= 32; c_time |= cur_time.low; base[idx].queue[loc].time = c_time; /* Increment the maximum length if needed. */ if (base[idx].max_len == elems) base[idx].max_len += 1; /* Update the inter-arrival statistics. */ assert(base[idx].number_of_adds < UINT64_MAX); base[idx].number_of_adds += 1; if (base[idx].number_of_adds == 1) base[idx].first_add_time = c_time; base[idx].latest_add_time = c_time; return 0; } /* * Get the job and inform values from the queue. Return 1 if the queue is * empty, otherwise return 0. */ static unsigned remove_from_queue(int64_t idx, p_vpi_vecval job, p_vpi_vecval inform) { PLI_INT32 type = base[idx].type; PLI_INT32 head = base[idx].head; PLI_INT32 elems = base[idx].elems - 1; PLI_INT32 loc; s_vpi_time cur_time; uint64_t c_time; assert(elems >= -1); /* If the queue is empty we can't remove anything. */ if (elems < 0) return 1; /* Decrement the number of element in the queue structure since one * will be removed.*/ base[idx].elems -= 1; /* Remove the job and inform from the queue. */ if (type == IVL_QUEUE_LIFO) { assert(head == 0); /* For a LIFO head must always be zero. */ loc = elems; } else { assert(type == IVL_QUEUE_FIFO); loc = head; if (head + 1 == base[idx].length) base[idx].head = 0; else base[idx].head += 1; } job->aval = base[idx].queue[loc].job.aval; job->bval = base[idx].queue[loc].job.bval; inform->aval = base[idx].queue[loc].inform.aval; inform->bval = base[idx].queue[loc].inform.bval; /* Get the current simulation time. */ cur_time.type = vpiSimTime; vpi_get_time(NULL, &cur_time); c_time = cur_time.high; c_time <<= 32; c_time |= cur_time.low; /* Set the shortest wait time if needed. */ assert(c_time >= base[idx].queue[loc].time); c_time -= base[idx].queue[loc].time; if (c_time < base[idx].shortest_wait_time) { base[idx].shortest_wait_time = c_time; } base[idx].have_shortest_statistic = 1; /* Add the current element wait time to the total wait time. */ add_to_wait_time(&(base[idx].wait_time_high), &(base[idx].wait_time_low), c_time); return 0; } /* * Return the current queue length. */ static PLI_INT32 get_current_queue_length(int64_t idx) { return base[idx].elems; } /* * Return the maximum queue length. */ static PLI_INT32 get_maximum_queue_length(int64_t idx) { return base[idx].max_len; } /* * Return the longest wait time in the queue in base simulation units. * Make sure to check that there are elements in the queue before calling * this routine. The caller will need to scale the time as appropriate. */ static uint64_t get_longest_queue_time(int64_t idx) { s_vpi_time cur_time; uint64_t c_time; /* Get the current simulation time. */ cur_time.type = vpiSimTime; vpi_get_time(NULL, &cur_time); c_time = cur_time.high; c_time <<= 32; c_time |= cur_time.low; /* Subtract the element with the longest time (the head) from the * current time. */ assert(c_time >= base[idx].queue[base[idx].head].time); c_time -= base[idx].queue[base[idx].head].time; return c_time; } /* * Check to see if there are inter-arrival time statistics. */ static unsigned have_interarrival_statistic(int64_t idx) { return (base[idx].number_of_adds >= 2U); } /* * Return the mean inter-arrival time for the queue. This is just the * latest add time minus the first add time divided be the number of time * deltas (the number of adds - 1). */ static uint64_t get_mean_interarrival_time(int64_t idx) { return ((base[idx].latest_add_time - base[idx].first_add_time) / (base[idx].number_of_adds - 1U)); } /* * Check to see if there are shortest wait time statistics. */ static unsigned have_shortest_wait_statistic(int64_t idx) { return (base[idx].have_shortest_statistic != 0); } /* * Return the shortest amount of time an element has waited in the queue. */ static uint64_t get_shortest_wait_time(int64_t idx) { return base[idx].shortest_wait_time; } /* * Check to see if we have an average wait time statistics. */ static unsigned have_average_wait_statistic(int64_t idx) { return (base[idx].number_of_adds >= 1U); } /* * Return the average wait time in the queue. */ static uint64_t get_average_wait_time(int64_t idx) { PLI_INT32 length = base[idx].length; PLI_INT32 loc = base[idx].head; PLI_INT32 elems = base[idx].elems; PLI_INT32 count; /* Initialize the high and low time with the current total time. */ uint64_t high = base[idx].wait_time_high; uint64_t low = base[idx].wait_time_low; s_vpi_time cur_time; uint64_t c_time; /* Get the current simulation time. */ cur_time.type = vpiSimTime; vpi_get_time(NULL, &cur_time); c_time = cur_time.high; c_time <<= 32; c_time |= cur_time.low; /* For each element still in the queue, add its wait time to the * total wait time. */ for (count = 0; count < elems; count += 1) { uint64_t add_time = base[idx].queue[loc].time; assert(c_time >= add_time); add_to_wait_time(&high, &low, c_time-add_time); /* Move to the next element. */ loc += 1; if (loc == length) loc = 0; } /* Return the average wait time. */ return calc_average_wait_time(high, low, base[idx].number_of_adds); } /* * Check to see if the given id already exists. Return the index for the * queue if it exists, otherwise return -1. */ static int64_t get_id_index(PLI_INT32 id) { int64_t idx; for (idx = 0; idx < base_len; idx += 1) { if (id == base[idx].id) return idx; } return -1; } /* * Check to see if the given value is bit based and has 32 or fewer bits. */ static unsigned is_32_or_smaller_obj(vpiHandle obj) { PLI_INT32 const_type; unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { case vpiConstant: case vpiParameter: const_type = vpi_get(vpiConstType, obj); if ((const_type != vpiRealConst) && (const_type != vpiStringConst)) rtn = 1; break; /* These can have valid 32 bit or smaller numeric values. */ case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiMemoryWord: case vpiNet: case vpiPartSelect: case vpiReg: rtn = 1; break; } /* The object must be 32 bits or smaller. */ if (vpi_get(vpiSize, obj) > 32) rtn = 0; return rtn; } /* * Check to see if the argument is a variable that is exactly 32 bits in size. */ static void check_var_arg_32(vpiHandle arg, vpiHandle callh, const char *name, const char *desc) { assert(arg); switch (vpi_get(vpiType, arg)) { case vpiMemoryWord: case vpiPartSelect: case vpiBitVar: case vpiReg: // Check that we have exactly 32 bits. if (vpi_get(vpiSize, arg) != 32) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s (variable) argument must be 32 bits.\n", name, desc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } case vpiIntegerVar: case vpiIntVar: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s argument must be a 32 bit variable.\n", name, desc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } /* * Check to see if the argument is a variable of at least 32 bits. */ static void check_var_arg_large(vpiHandle arg, vpiHandle callh, const char *name, const char *desc) { assert(arg); switch (vpi_get(vpiType, arg)) { case vpiMemoryWord: case vpiPartSelect: case vpiBitVar: case vpiReg: // Check that we have at least 32 bits. if (vpi_get(vpiSize, arg) < 32) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s (variable) argument must have at least " "32 bits.\n", name, desc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s argument must be a variable.\n", name, desc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } /* * Check that the given number of arguments are numeric. */ static unsigned check_numeric_args(vpiHandle argv, unsigned count, vpiHandle callh, const char *name) { unsigned idx; /* Check that the first count arguments are numeric. Currently * only three are needed/supported. */ for (idx = 0; idx < count; idx += 1) { const char *loc = NULL; vpiHandle arg = vpi_scan(argv); /* Get the name for this argument. */ switch (idx) { case 0: loc = "first"; break; case 1: loc = "second"; break; case 2: loc = "third"; break; default: assert(0); } /* Check that there actually is an argument. */ if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a %s (<= 32 bit numeric) argument.\n", name, loc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Check that it is no more than 32 bits. */ if (! is_32_or_smaller_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's %s argument must be numeric (<= 32 bits).\n", name, loc); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } return 0; } /* * Check to see if the given argument is valid (does not have any X/Z bits). * Return zero if it is valid and a positive value if it is invalid. */ static unsigned get_valid_32(vpiHandle arg, PLI_INT32 *value) { PLI_INT32 size, mask; s_vpi_value val; size = vpi_get(vpiSize, arg); /* The compiletf routine should have already verified that this is * <= 32 bits. */ assert((size <= 32) && (size > 0)); /* Create a mask so that we only check the appropriate bits. */ mask = UINT32_MAX >> (32 - size); /* Get the value and return the possible integer value in the value * variable. Return the b-value bits to indicate if the value is * undefined (has X/Z bit). */ val.format = vpiVectorVal; vpi_get_value(arg, &val); *value = val.value.vector->aval & mask; /* If the argument is signed and less than 32 bit we need to sign * extend the value. */ if (vpi_get(vpiSigned, arg) && (size < 32)) { if ((*value) & (1 << (size - 1))) *value |= ~mask; } return (val.value.vector->bval & mask); } static void get_four_state(vpiHandle arg, p_vpi_vecval vec) { PLI_INT32 size, mask; s_vpi_value val; size = vpi_get(vpiSize, arg); /* The compiletf routine should have already verified that this is * <= 32 bits. */ assert((size <= 32) && (size > 0)); /* Create a mask so that we only use the appropriate bits. */ mask = UINT32_MAX >> (32 - size); /* Get the bits for the argument and save them in the return value. */ val.format = vpiVectorVal; vpi_get_value(arg, &val); vec->aval = val.value.vector->aval & mask; vec->bval = val.value.vector->bval & mask; /* If the argument is signed and less than 32 bit we need to sign * extend the value. */ if (vpi_get(vpiSigned, arg) && (size < 32)) { if (vec->aval & (1 << (size - 1))) vec->aval |= ~mask; if (vec->bval & (1 << (size - 1))) vec->bval |= ~mask; } } /* * Fill the passed variable with x. */ static void fill_variable_with_x(vpiHandle var) { s_vpi_value val; PLI_INT32 words = ((vpi_get(vpiSize, var) - 1) / 32) + 1; PLI_INT32 idx; p_vpi_vecval val_ptr = (p_vpi_vecval) malloc(words*sizeof(s_vpi_vecval)); assert(val_ptr); /* Fill the vector with X. */ for (idx = 0; idx < words; idx += 1) { val_ptr[idx].aval = 0xffffffff; val_ptr[idx].bval = 0xffffffff; } /* Put the vector to the variable. */ val.format = vpiVectorVal; val.value.vector = val_ptr; vpi_put_value(var, &val, 0, vpiNoDelay); free(val_ptr); } /* * Fill the passed variable with the passed value if it fits. If it doesn't * fit then set all bits to one and return that the value is too big instead * of the normal OK. The value is a time and needs to be scaled to the * calling module's timescale. */ static PLI_INT32 fill_variable_with_scaled_time(vpiHandle var, uint64_t c_time) { s_vpi_value val; PLI_INT32 size = vpi_get(vpiSize, var); PLI_INT32 is_signed = vpi_get(vpiSigned, var); PLI_INT32 words = ((size - 1) / 32) + 1; uint64_t max_val = 0; uint64_t scale = 1; uint64_t frac; PLI_INT32 rtn, units, prec; p_vpi_vecval val_ptr = (p_vpi_vecval) malloc(words*sizeof(s_vpi_vecval)); assert(val_ptr); assert(size >= 32); assert(words > 0); /* Scale the variable to match the calling module's timescale. */ prec = vpi_get(vpiTimePrecision, 0); units = vpi_get(vpiTimeUnit, vpi_handle(vpiModule, var)); assert(units >= prec); while (units > prec) { scale *= 10; units -= 1; } frac = c_time % scale; c_time /= scale; if ((scale > 1) && (frac >= scale/2)) c_time += 1; /* Find the maximum value + 1 that can be put into the variable. */ if (size < 64) { max_val = 1; max_val <<= (size - is_signed); } /* If the time is too big to fit then return the maximum positive * value and that the value overflowed. Otherwise, return the time * and OK. */ if (max_val && (c_time >= max_val)) { /* For a single word only the MSB is cleared if signed. */ if (words == 1) { if (is_signed) { val_ptr[0].aval = 0x7fffffff; } else { val_ptr[0].aval = 0xffffffff; } val_ptr[0].bval = 0x00000000; /* For two words the lower word is filled with 1 and the top * word has a size dependent fill if signed. */ } else { assert(words == 2); val_ptr[0].aval = 0xffffffff; val_ptr[0].bval = 0x00000000; if (is_signed) { val_ptr[1].aval = ~(UINT32_MAX >> (size - 32)); } else { val_ptr[1].aval = 0xffffffff; } val_ptr[1].bval = 0x00000000; } rtn = IVL_QUEUE_VALUE_OVERFLOWED; } else { /* Fill the vector with 0. */ for (PLI_INT32 idx = 0; idx < words; idx += 1) { val_ptr[idx].aval = 0x00000000; val_ptr[idx].bval = 0x00000000; } /* Add the time to the vector. */ switch (words) { default: val_ptr[1].aval = (c_time >> 32) & 0xffffffff; // fallthrough case 1: val_ptr[0].aval = c_time & 0xffffffff; } rtn = IVL_QUEUE_OK; } /* Put the vector to the variable. */ val.format = vpiVectorVal; val.value.vector = val_ptr; vpi_put_value(var, &val, 0, vpiNoDelay); free(val_ptr); return rtn; } /* * Check that the given $q_initialize() call has valid arguments. */ static PLI_INT32 sys_q_initialize_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first three arguments (the id, type and maximum * length) are numeric. */ if (check_numeric_args(argv, 3, callh, name)) return 0; /* The fourth argument (the status) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a fourth (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the status argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "fourth"); /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 0); return 0; } /* * The runtime code for $q_initialize(). */ static PLI_INT32 sys_q_initialize_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle status; PLI_INT32 id, type, length; s_vpi_value val; unsigned invalid_id, invalid_type, invalid_length; (void)name; /* Parameter is not used. */ /* Get the id. */ invalid_id = get_valid_32(vpi_scan(argv), &id); /* Get the queue type. */ invalid_type = get_valid_32(vpi_scan(argv), &type); /* Get the queue maximum length. */ invalid_length = get_valid_32(vpi_scan(argv), &length); /* Get the status variable. */ status = vpi_scan(argv); /* We are done with the argument iterator so free it. */ vpi_free_object(argv); /* If the id is invalid then return. */ if (invalid_id) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_ID; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Verify that the type is valid. */ if (invalid_type || ((type != IVL_QUEUE_FIFO) && (type != IVL_QUEUE_LIFO))) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNSUPPORTED_TYPE; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Verify that the queue length is greater than zero. */ if (invalid_length || (length <= 0)) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_INVALID_LENGTH; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Check that this is not a duplicate queue id. */ if (get_id_index(id) >= 0) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_DUPLICATE_ID; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Create the queue and fail if we do not have enough memory. */ if (create_queue(id, type, length)) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_OUT_OF_MEMORY; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* The queue was initialized correctly so return OK. */ val.format = vpiIntVal; val.value.integer = IVL_QUEUE_OK; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* * Check that the given $q_add() call has valid arguments. */ static PLI_INT32 sys_q_add_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first three arguments (the id, job and information) * are numeric. */ if (check_numeric_args(argv, 3, callh, name)) return 0; /* The fourth argument (the status) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a fourth (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the status argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "fourth"); /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 0); return 0; } /* * The runtime code for $q_add(). */ static PLI_INT32 sys_q_add_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle status; PLI_INT32 id; int64_t idx; s_vpi_vecval job, inform; s_vpi_value val; unsigned invalid_id; (void)name; /* Parameter is not used. */ /* Get the id. */ invalid_id = get_valid_32(vpi_scan(argv), &id); /* Get the job. */ get_four_state(vpi_scan(argv), &job); /* Get the value. */ get_four_state(vpi_scan(argv), &inform); /* Get the status variable. */ status = vpi_scan(argv); /* We are done with the argument iterator so free it. */ vpi_free_object(argv); /* Verify that the id is valid. */ idx = get_id_index(id); if (invalid_id || (idx < 0)) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_ID; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Add the data to the queue if it is not already full. */ if (add_to_queue(idx, &job, &inform)) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_FULL; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* The data was added to the queue so return OK. */ val.format = vpiIntVal; val.value.integer = IVL_QUEUE_OK; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* * Check that the given $q_remove() call has valid arguments. */ static PLI_INT32 sys_q_remove_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument (the id) must be numeric. */ if (! is_32_or_smaller_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be numeric (<= 32 bits).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The second argument (the job id) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the job id argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "second"); /* The third argument (the information id) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a third (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the information id argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "third"); /* The fourth argument (the status) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a fourth (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the status argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "fourth"); /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 0); return 0; } /* * The runtime code for $q_remove(). */ static PLI_INT32 sys_q_remove_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle job, inform, status; PLI_INT32 id, idx; s_vpi_vecval job_val, inform_val; s_vpi_value val; unsigned invalid_id; (void)name; /* Parameter is not used. */ /* Get the id. */ invalid_id = get_valid_32(vpi_scan(argv), &id); /* Get the job variable. */ job = vpi_scan(argv); /* Get the inform variable. */ inform = vpi_scan(argv); /* Get the status variable. */ status = vpi_scan(argv); /* We are done with the argument iterator so free it. */ vpi_free_object(argv); /* Verify that the id is valid. */ idx = get_id_index(id); if (invalid_id || (idx < 0)) { fill_variable_with_x(job); fill_variable_with_x(inform); val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_ID; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Remove the data from the queue if it is not already empty. */ if (remove_from_queue(idx, &job_val, &inform_val)) { fill_variable_with_x(job); fill_variable_with_x(inform); val.format = vpiIntVal; val.value.integer = IVL_QUEUE_EMPTY; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } val.format = vpiVectorVal; val.value.vector = &job_val; vpi_put_value(job, &val, 0, vpiNoDelay); val.format = vpiVectorVal; val.value.vector = &inform_val; vpi_put_value(inform, &val, 0, vpiNoDelay); /* The data was added to the queue so return OK. */ val.format = vpiIntVal; val.value.integer = IVL_QUEUE_OK; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* * Check that the given $q_full() call has valid arguments. */ static PLI_INT32 sys_q_full_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument (the id) must be numeric. */ if (! is_32_or_smaller_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be numeric (<= 32 bits).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The second argument (the status) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the status argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "second"); /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } /* * The runtime code for $q_full(). */ static PLI_INT32 sys_q_full_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle status; PLI_INT32 id, idx; s_vpi_value val; unsigned invalid_id; (void)name; /* Parameter is not used. */ /* Get the id. */ invalid_id = get_valid_32(vpi_scan(argv), &id); /* Get the status variable. */ status = vpi_scan(argv); /* We are done with the argument iterator so free it. */ vpi_free_object(argv); /* Verify that the id is valid. */ idx = get_id_index(id); if (invalid_id || (idx < 0)) { val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_ID; vpi_put_value(status, &val, 0, vpiNoDelay); fill_variable_with_x(callh); return 0; } /* Get the queue state and return it. */ val.format = vpiIntVal; if (is_queue_full(idx)) val.value.integer = 1; else val.value.integer = 0; vpi_put_value(callh, &val, 0, vpiNoDelay); /* The queue state was passed back so return OK. */ val.format = vpiIntVal; val.value.integer = IVL_QUEUE_OK; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* * Check that the given $q_exam() call has valid arguments. */ static PLI_INT32 sys_q_exam_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires four arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the first two arguments (the id and code) are numeric. */ if (check_numeric_args(argv, 2, callh, name)) return 0; /* The third argument (the value) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a third (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the value argument is a variable with at least * 32 bits. */ check_var_arg_large(arg, callh, name, "third"); /* The fourth argument (the status) must be a variable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a fourth (variable) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that the status argument is a 32 bit variable. */ check_var_arg_32(arg, callh, name, "fourth"); /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } /* * The runtime code for $q_exam(). */ static PLI_INT32 sys_q_exam_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle value, status; PLI_INT32 id, code, idx, rtn; s_vpi_value val; unsigned invalid_id, invalid_code; (void)name; /* Parameter is not used. */ /* Get the id. */ invalid_id = get_valid_32(vpi_scan(argv), &id); /* Get the code. */ invalid_code = get_valid_32(vpi_scan(argv), &code); /* Get the value variable. */ value = vpi_scan(argv); /* Get the status variable. */ status = vpi_scan(argv); /* We are done with the argument iterator so free it. */ vpi_free_object(argv); /* Verify that the id is valid. */ idx = get_id_index(id); if (invalid_id || (idx < 0)) { fill_variable_with_x(value); val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_ID; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* Verify that the code is valid. */ if (invalid_code || (code <= 0) || (code > 6)) { fill_variable_with_x(value); val.format = vpiIntVal; val.value.integer = IVL_QUEUE_UNDEFINED_STAT_CODE; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } rtn = IVL_QUEUE_OK; /* Calculate the requested queue information. */ switch (code) { /* The current queue length. */ case IVL_QUEUE_LENGTH: val.format = vpiIntVal; val.value.integer = get_current_queue_length(idx); vpi_put_value(value, &val, 0, vpiNoDelay); break; /* The mean inter-arrival time. */ case IVL_QUEUE_MEAN: if (have_interarrival_statistic(idx) == 0) { fill_variable_with_x(value); rtn = IVL_QUEUE_NO_STATISTICS; } else { uint64_t ia_time = get_mean_interarrival_time(idx); rtn = fill_variable_with_scaled_time(value, ia_time); } break; /* The maximum queue length. */ case IVL_QUEUE_MAX_LENGTH: val.format = vpiIntVal; val.value.integer = get_maximum_queue_length(idx); vpi_put_value(value, &val, 0, vpiNoDelay); break; /* The shortest queue wait time ever. */ case IVL_QUEUE_SHORTEST: if (have_shortest_wait_statistic(idx) == 0) { fill_variable_with_x(value); rtn = IVL_QUEUE_NO_STATISTICS; } else { uint64_t sw_time = get_shortest_wait_time(idx); rtn = fill_variable_with_scaled_time(value, sw_time); } break; /* The longest wait time for elements still in the queue. */ case IVL_QUEUE_LONGEST: if (get_current_queue_length(idx) == 0) { fill_variable_with_x(value); rtn = IVL_QUEUE_NO_STATISTICS; } else { uint64_t lq_time = get_longest_queue_time(idx); rtn = fill_variable_with_scaled_time(value, lq_time); } break; /* The average queue wait time. */ case IVL_QUEUE_AVERAGE: if (have_average_wait_statistic(idx) == 0) { fill_variable_with_x(value); rtn = IVL_QUEUE_NO_STATISTICS; } else { uint64_t aw_time = get_average_wait_time(idx); rtn = fill_variable_with_scaled_time(value, aw_time); } break; default: assert(0); } /* The queue information was passed back so now return the status. */ val.format = vpiIntVal; val.value.integer = rtn; vpi_put_value(status, &val, 0, vpiNoDelay); return 0; } /* * Routine to register the system tasks/functions provided in this file. */ void sys_queue_register(void) { s_vpi_systf_data tf_data; s_cb_data cb; vpiHandle res; tf_data.type = vpiSysTask; tf_data.tfname = "$q_initialize"; tf_data.calltf = sys_q_initialize_calltf; tf_data.compiletf = sys_q_initialize_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$q_initialize"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$q_add"; tf_data.calltf = sys_q_add_calltf; tf_data.compiletf = sys_q_add_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$q_add"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$q_remove"; tf_data.calltf = sys_q_remove_calltf; tf_data.compiletf = sys_q_remove_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$q_remove"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$q_full"; tf_data.calltf = sys_q_full_calltf; tf_data.compiletf = sys_q_full_compiletf; tf_data.sizetf = 0; /* Not needed for a vpiSysFuncInt. */ tf_data.user_data = "$q_full"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$q_exam"; tf_data.calltf = sys_q_exam_calltf; tf_data.compiletf = sys_q_exam_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$q_exam"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Create a callback to clear all the queue memory when the * simulator finishes. */ cb.time = NULL; cb.reason = cbEndOfSimulation; cb.cb_rtn = cleanup_queue; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); } iverilog-12_0/vpi/sys_random.c000066400000000000000000000717501435245347300165010ustar00rootroot00000000000000/* * Copyright (c) 2000-2022 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 "sys_priv.h" # include "sys_random.h" # include # include # include # include /* * The following code is largely copied from the IEEE standard (section 17.9.3 * in IEEE 1364-2005, Annex N in IEEE 1800-2017). The code in the IEEE standard * predates the widespread availability of 64-bit processors, so assumes 'long' * is a 32 bit value (https://accellera.mantishub.io/view.php?id=1136). So we * replace 'long' with 'int32_t' to ensure correct and consistent behaviour * regardless of how the code is built. */ static double uniform(int32_t *seed, int32_t start, int32_t end); static double normal(int32_t *seed, int32_t mean, int32_t deviation); static double exponential(int32_t *seed, int32_t mean); static int32_t poisson(int32_t *seed, int32_t mean); static double chi_square(int32_t *seed, int32_t deg_of_free); static double t(int32_t *seed, int32_t deg_of_free); static double erlangian(int32_t *seed, int32_t k, int32_t mean); static int32_t rtl_dist_chi_square(int32_t *seed, int32_t df) { double r; int32_t i; if (df > 0) { r = chi_square(seed, df); if (r >= 0) { i = (int32_t) (r + 0.5); } else { r = -r; i = (int32_t) (r + 0.5); i = -i; } } else { vpi_printf("WARNING: Chi_square distribution must have " "a positive degree of freedom\n"); i = 0; } return i; } static int32_t rtl_dist_erlang(int32_t *seed, int32_t k, int32_t mean) { double r; int32_t i; if (k > 0) { r = erlangian(seed, k, mean); if (r >= 0) { i = (int32_t) (r + 0.5); } else { r = -r; i = (int32_t) (r + 0.5); i = -i; } } else { vpi_printf("WARNING: K-stage erlangian distribution must have " "a positive k\n"); i = 0; } return i; } static int32_t rtl_dist_exponential(int32_t *seed, int32_t mean) { double r; int32_t i; if (mean > 0) { r = exponential(seed, mean); if (r >= 0) { i = (int32_t) (r + 0.5); } else { r = -r; i = (int32_t) (r + 0.5); i = -i; } } else { vpi_printf("WARNING: Exponential distribution must have " "a positive mean\n"); i = 0; } return i; } static int32_t rtl_dist_normal(int32_t *seed, int32_t mean, int32_t sd) { double r; int32_t i; r = normal(seed, mean, sd); if (r >= 0) { i = (int32_t) (r + 0.5); } else { r = -r; i = (int32_t) (r + 0.5); i = -i; } return i; } static int32_t rtl_dist_poisson(int32_t *seed, int32_t mean) { int32_t i; if (mean > 0) { i = poisson(seed, mean); } else { vpi_printf("WARNING: Poisson distribution must have " "a positive mean\n"); i = 0; } return i; } static int32_t rtl_dist_t(int32_t *seed, int32_t df) { double r; int32_t i; if (df > 0) { r = t(seed, df); if (r >= 0) { i = (int32_t) (r + 0.5); } else { r = -r; i = (int32_t) (r + 0.5); i = -i; } } else { vpi_printf("WARNING: t distribution must have " "a positive degree of freedom\n"); i = 0; } return i; } static int32_t rtl_dist_uniform(int32_t *seed, int32_t start, int32_t end) { double r; int32_t i; if (start >= end) return start; if (end != INT32_MAX) { end++; r = uniform(seed, start, end); if (r >= 0) { i = (int32_t) r; } else { i = (int32_t) (r - 1); } if (i < start) i = start; if (i >= end) i = end - 1; } else if (start != INT32_MIN) { start--; r = uniform(seed, start, end) + 1.0; if (r >= 0) { i = (int32_t) r; } else { i = (int32_t) (r - 1); } if (i <= start) i = start + 1; if (i > end) i = end; } else { r = (uniform(seed, start, end) + 2147483648.0) / 4294967295.0; r = r * 4294967296.0 - 2147483648.0; if (r >= 0) { i = (int32_t) r; } else { i = (int32_t) (r - 1); } } return i; } static double uniform(int32_t *seed, int32_t start, int32_t end) { double d = 0.00000011920928955078125; double a, b, c; uint32_t oldseed, newseed; oldseed = *seed; if (oldseed == 0) oldseed = 259341593; if (start >= end) { a = 0.0; b = 2147483647.0; } else { a = (double)start; b = (double)end; } /* Original routine used signed arithmetic, and the (frequent) * overflows trigger "Undefined Behavior" according to the * C standard (both c89 and c99). Using unsigned arithmetic * forces a conforming C implementation to get the result * that the IEEE-1364-2001 committee wants. */ newseed = 69069 * oldseed + 1; *seed = newseed; #if 0 /* Cadence-donated conversion from unsigned int to double */ { union { float s; unsigned stemp; } u; u.stemp = (newseed >> 9) | 0x3f800000; c = (double) u.s; } #else /* Equivalent conversion without assuming IEEE 32-bit float */ /* constant is 2^(-23) */ c = 1.0 + (newseed >> 9) * 0.00000011920928955078125; #endif c = c + (c*d); c = ((b - a) * (c - 1.0)) + a; return c; } static double normal(int32_t *seed, int32_t mean, int32_t deviation) { double v1, v2, s; s = 1.0; while ((s >= 1.0) || (s == 0.0)) { v1 = uniform(seed, -1, 1); v2 = uniform(seed, -1, 1); s = v1 * v1 + v2 * v2; } s = v1 * sqrt(-2.0 * log(s) / s); v1 = (double) deviation; v2 = (double) mean; return s * v1 + v2; } static double exponential(int32_t *seed, int32_t mean) { double n; n = uniform(seed, 0, 1); if (n != 0.0) { n = -log(n) * mean; } return n; } static int32_t poisson(int32_t *seed, int32_t mean) { int32_t n; double p, q; n = 0; q = -(double) mean; p = exp(q); q = uniform(seed, 0, 1); while (p < q) { n++; q = uniform(seed, 0, 1) * q; } return n; } static double chi_square(int32_t *seed, int32_t deg_of_free) { double x; int32_t k; if (deg_of_free % 2) { x = normal(seed, 0, 1); x = x * x; } else { x = 0.0; } for (k = 2; k <= deg_of_free; k = k + 2) { x = x + 2 * exponential(seed, 1); } return x; } static double t( int32_t *seed, int32_t deg_of_free) { double x, chi2, dv, root; chi2 = chi_square(seed, deg_of_free); dv = chi2 / (double) deg_of_free; root = sqrt(dv); x = normal(seed, 0, 1) / root; return x; } static double erlangian(int32_t *seed, int32_t k, int32_t mean) { double x, a, b; int32_t i; x = 1.0; for (i = 1; i <= k; i++) { x = x * uniform(seed, 0, 1); } a = (double) mean; b = (double) k; x = -a * log(x) / b; return x; } /* A seed can only be an integer/time variable or a register. */ static unsigned is_seed_obj(vpiHandle obj, vpiHandle callh, const char *name) { unsigned rtn = 0; assert(obj); switch (vpi_get(vpiType, obj)) { case vpiTimeVar: case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: rtn = 1; break; case vpiBitVar: case vpiReg: if (vpi_get(vpiSize, obj) < 32) { vpi_printf("Error: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's seed variable is less than 32 bits " " (%d).\n", name, (int)vpi_get(vpiSize, obj)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } else rtn = 1; break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's seed must be an integer/time" " variable or a register.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return rtn; } static PLI_INT32 sys_rand_two_args_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle seed, arg2; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there are at least two arguments. */ seed = vpi_scan(argv); /* This should never be zero. */ arg2 = vpi_scan(argv); if (arg2 == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The seed must be a time/integer variable or a register. */ if (! is_seed_obj(seed, callh, name)) return 0; /* The second argument must be numeric. */ if (! is_numeric_obj(arg2)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there is at most two arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } PLI_INT32 sys_rand_three_args_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle seed, arg2, arg3; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there are at least three arguments. */ seed = vpi_scan(argv); /* This should never be zero. */ arg2 = vpi_scan(argv); if (arg2) { arg3 = vpi_scan(argv); } else { arg3 = 0; } if (arg2 == 0 || arg3 == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The seed must be a time/integer variable or a register. */ if (! is_seed_obj(seed, callh, name)) return 0; /* The second argument must be numeric. */ if (! is_numeric_obj(arg2)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s second argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The third argument must be numeric. */ if (! is_numeric_obj(arg3)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s third argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there is at most three arguments. */ check_for_extra_args(argv, callh, name, "three arguments", 0); return 0; } PLI_INT32 sys_random_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* The seed is optional. */ if (argv == 0) return 0; /* The seed must be a time/integer variable or a register. */ if (! is_seed_obj(vpi_scan(argv), callh, name)) return 0; /* Check that there no extra arguments. */ check_for_extra_args(argv, callh, name, "one argument", 1); return 0; } static PLI_INT32 sys_random_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed = 0; s_vpi_value val; static int32_t i_seed = 0; int32_t a_seed; (void)name; /* Parameter is not used. */ /* Get the argument list and look for a seed. If it is there, get the value and reseed the random number generator. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); val.format = vpiIntVal; if (argv) { seed = vpi_scan(argv); vpi_free_object(argv); vpi_get_value(seed, &val); a_seed = val.value.integer; } else a_seed = i_seed; /* Calculate and return the result. */ val.value.integer = rtl_dist_uniform(&a_seed, INT_MIN, INT_MAX); vpi_put_value(callh, &val, 0, vpiNoDelay); /* If it exists send the updated seed back to seed parameter. */ if (seed) { val.value.integer = a_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); } else i_seed = a_seed; return 0; } /* From SystemVerilog. */ static PLI_INT32 sys_urandom_range_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s requires one or two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check that there is at least one argument. */ arg = vpi_scan(argv); /* This should never be zero. */ assert(arg); arg = vpi_scan(argv); /* Is this a single argument function call? */ if (arg == 0) return 0; /* These functions takes at most two argument. */ arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s takes at most two argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* vpi_scan returning 0 (NULL) has already freed argv. */ return 0; } /* From SystemVerilog. */ static uint32_t urandom(int32_t *seed, uint32_t max, uint32_t min) { static int32_t i_seed = 0; int32_t max_i, min_i; uint32_t result; max_i = max + INT32_MIN; min_i = min + INT32_MIN; if (seed != 0) i_seed = *seed; result = (uint32_t)rtl_dist_uniform(&i_seed, min_i, max_i) - INT32_MIN; if (seed != 0) *seed = i_seed; return result; } /* From SystemVerilog. */ static PLI_INT32 sys_urandom_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed = 0; s_vpi_value val; int32_t i_seed; (void)name; /* Parameter is not used. */ /* Get the argument list and look for a seed. If it is there, get the value and reseed the random number generator. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); val.format = vpiIntVal; if (argv) { seed = vpi_scan(argv); vpi_free_object(argv); vpi_get_value(seed, &val); i_seed = val.value.integer; } /* Calculate and return the result. */ if (seed) { val.value.integer = urandom(&i_seed, UINT32_MAX, 0); } else { val.value.integer = urandom(0, UINT32_MAX, 0); } vpi_put_value(callh, &val, 0, vpiNoDelay); /* If it exists send the updated seed back to seed parameter. */ if (seed) { val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); } return 0; } /* From SystemVerilog. */ static PLI_INT32 sys_urandom_range_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, maxval, minval; s_vpi_value val; uint32_t i_maxval, i_minval; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); maxval = vpi_scan(argv); minval = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(maxval, &val); i_maxval = val.value.integer; /* Is this a two or one argument function call? */ if (minval) { vpi_get_value(minval, &val); i_minval = val.value.integer; vpi_free_object(argv); } else { i_minval = 0; } /* Swap the two arguments if they are out of order. */ if (i_minval > i_maxval) { uint32_t tmp = i_minval; i_minval = i_maxval; i_maxval = tmp; } /* Calculate and return the result. */ val.value.integer = urandom(0, i_maxval, i_minval); vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 sys_dist_uniform_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, start, end; s_vpi_value val; int32_t i_seed, i_start, i_end; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); start = vpi_scan(argv); end = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(start, &val); i_start = val.value.integer; vpi_get_value(end, &val); i_end = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_uniform(&i_seed, i_start, i_end); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_normal_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, mean, sd; s_vpi_value val; int32_t i_seed, i_mean, i_sd; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); mean = vpi_scan(argv); sd = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(mean, &val); i_mean = val.value.integer; vpi_get_value(sd, &val); i_sd = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_normal(&i_seed, i_mean, i_sd); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_exponential_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, mean; s_vpi_value val; int32_t i_seed, i_mean; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); mean = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(mean, &val); i_mean = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_exponential(&i_seed, i_mean); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_poisson_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, mean; s_vpi_value val; int32_t i_seed, i_mean; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); mean = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(mean, &val); i_mean = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_poisson(&i_seed, i_mean); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_chi_square_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, df; s_vpi_value val; int32_t i_seed, i_df; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); df = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(df, &val); i_df = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_chi_square(&i_seed, i_df); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_t_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, df; s_vpi_value val; int32_t i_seed, i_df; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); df = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(df, &val); i_df = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_t(&i_seed, i_df); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_dist_erlang_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh, argv, seed, k, mean; s_vpi_value val; int32_t i_seed, i_k, i_mean; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); k = vpi_scan(argv); mean = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(k, &val); i_k = val.value.integer; vpi_get_value(mean, &val); i_mean = val.value.integer; /* Calculate and return the result. */ val.value.integer = rtl_dist_erlang(&i_seed, i_k, i_mean); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_rand_func_sizetf(ICARUS_VPI_CONST PLI_BYTE8 *name) { (void)name; /* Parameter is not used. */ return 32; } void sys_random_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$random"; tf_data.calltf = sys_random_calltf; tf_data.compiletf = sys_random_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$random"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* From SystemVerilog. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncSized; tf_data.tfname = "$urandom"; tf_data.calltf = sys_urandom_calltf; tf_data.compiletf = sys_random_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$urandom"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* From SystemVerilog. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncSized; tf_data.tfname = "$urandom_range"; tf_data.calltf = sys_urandom_range_calltf; tf_data.compiletf = sys_urandom_range_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$urandom_range"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_uniform"; tf_data.calltf = sys_dist_uniform_calltf; tf_data.compiletf = sys_rand_three_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_uniform"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_normal"; tf_data.calltf = sys_dist_normal_calltf; tf_data.compiletf = sys_rand_three_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_normal"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_exponential"; tf_data.calltf = sys_dist_exponential_calltf; tf_data.compiletf = sys_rand_two_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_exponential"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_poisson"; tf_data.calltf = sys_dist_poisson_calltf; tf_data.compiletf = sys_rand_two_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_poisson"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_chi_square"; tf_data.calltf = sys_dist_chi_square_calltf; tf_data.compiletf = sys_rand_two_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_chi_square"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_t"; tf_data.calltf = sys_dist_t_calltf; tf_data.compiletf = sys_rand_two_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_t"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$dist_erlang"; tf_data.calltf = sys_dist_erlang_calltf; tf_data.compiletf = sys_rand_three_args_compiletf; tf_data.sizetf = sys_rand_func_sizetf; tf_data.user_data = "$dist_erlang"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_random.h000066400000000000000000000022521435245347300164750ustar00rootroot00000000000000#ifndef IVL_sys_random_H #define IVL_sys_random_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 /* * Common compiletf routines for the different random implementations. */ extern PLI_INT32 sys_rand_three_args_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); extern PLI_INT32 sys_random_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); #endif /* IVL_sys_random_H */ iverilog-12_0/vpi/sys_random_mti.c000066400000000000000000000116301435245347300173410ustar00rootroot00000000000000/* * 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 "sys_priv.h" # include "sys_random.h" # include # include # include # include # include "ivl_alloc.h" /* * Implement the $random system function using the ``Mersenne * Twister'' random number generator MT19937. */ /* make sure this matches N+1 in mti19937int.c */ #define NP1 624+1 /* Icarus seed cookie */ #define COOKIE 0x1ca1ca1c static struct context_s global_context = {NP1, {0} }; static long mti_dist_uniform(long*seed, long start, long end) { (void)seed; /* Parameter is not used. */ if (start >= end) return start; if ((start > LONG_MIN) || (end < LONG_MAX)) { long range = end - start; return start + genrand(&global_context)%range; } else { return genrand(&global_context); } } static PLI_INT32 sys_mti_dist_uniform_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh, argv, seed, start, end; s_vpi_value val; long i_seed, i_start, i_end; (void)name; /* Parameter is not used. */ /* Get the argument handles and convert them. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); seed = vpi_scan(argv); start = vpi_scan(argv); end = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(seed, &val); i_seed = val.value.integer; vpi_get_value(start, &val); i_start = val.value.integer; vpi_get_value(end, &val); i_end = val.value.integer; /* Calculate and return the result. */ val.value.integer = mti_dist_uniform(&i_seed, i_start, i_end); vpi_put_value(callh, &val, 0, vpiNoDelay); /* Return the seed. */ val.value.integer = i_seed; vpi_put_value(seed, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } static PLI_INT32 sys_mti_random_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh, argv, seed = 0; s_vpi_value val; int i_seed = COOKIE; struct context_s *context; (void)name; /* Parameter is not used. */ /* Get the argument list and look for a seed. If it is there, get the value and reseed the random number generator. */ callh = vpi_handle(vpiSysTfCall, 0); argv = vpi_iterate(vpiArgument, callh); val.format = vpiIntVal; if (argv) { seed = vpi_scan(argv); vpi_free_object(argv); vpi_get_value(seed, &val); i_seed = val.value.integer; /* Since there is a seed use the current context or create a new one */ context = (struct context_s *)vpi_get_userdata(callh); if (!context) { context = (struct context_s *)calloc(1, sizeof(*context)); context->mti = NP1; /* squirrel away context */ vpi_put_userdata(callh, (void *)context); } /* If the argument is not the Icarus cookie, then reseed context */ if (i_seed != COOKIE) sgenrand(context, i_seed); } else { /* use global context */ context = &global_context; } /* Calculate and return the result */ val.value.integer = genrand(context); vpi_put_value(callh, &val, 0, vpiNoDelay); /* mark seed with cookie */ if (seed && i_seed != COOKIE) { val.value.integer = COOKIE; vpi_put_value(seed, &val, 0, vpiNoDelay); } return 0; } void sys_random_mti_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$mti_random"; tf_data.calltf = sys_mti_random_calltf; tf_data.compiletf = sys_random_compiletf; tf_data.user_data = "$mti_random"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncInt; tf_data.tfname = "$mti_dist_uniform"; tf_data.calltf = sys_mti_dist_uniform_calltf; tf_data.compiletf = sys_rand_three_args_compiletf; tf_data.user_data = "$mti_dist_uniform"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_readmem.c000066400000000000000000000514621435245347300166310ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "sys_priv.h" # include # include # include # include # include # include "sys_readmem_lex.h" # include # include "ivl_alloc.h" char **search_list = NULL; unsigned sl_count = 0; static void get_mem_params(vpiHandle argv, vpiHandle callh, const char *name, char **fname, vpiHandle *mitem, vpiHandle *start_item, vpiHandle *stop_item) { /* Get the first parameter (file name). */ *fname = get_filename(callh, name, vpi_scan(argv)); /* Get the second parameter (memory). */ *mitem = vpi_scan(argv); /* Get optional third parameter (start address). */ *start_item = vpi_scan(argv); if (*start_item) { /* Warn the user if they gave a real value for the start * address. */ switch (vpi_get(vpiType, *start_item)) { case vpiConstant: case vpiParameter: if (vpi_get(vpiConstType, *start_item) != vpiRealConst) break; // fallthrough case vpiRealVar: vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's third argument (start address) is a real " "value.\n", name); } /* Get optional fourth parameter (finish address). */ *stop_item = vpi_scan(argv); if (*stop_item) { /* Warn the user if they gave a real value for the finish * address. */ switch (vpi_get(vpiType, *stop_item)) { case vpiConstant: case vpiParameter: if (vpi_get(vpiConstType, *stop_item) != vpiRealConst) { break; } // fallthrough case vpiRealVar: vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's fourth argument (finish address) is a " "real value.\n", name); } vpi_free_object(argv); } } else { *stop_item = 0; } } static int process_params(vpiHandle mitem, vpiHandle start_item, vpiHandle stop_item, vpiHandle callh, const char *name, int *start_addr, int *stop_addr, int *addr_incr, int *min_addr, int *max_addr) { s_vpi_value val; int left_addr, right_addr; /* Get left addr of memory */ val.format = vpiIntVal; vpi_get_value(vpi_handle(vpiLeftRange, mitem), &val); left_addr = val.value.integer; /* Get right addr of memory */ val.format = vpiIntVal; vpi_get_value(vpi_handle(vpiRightRange, mitem), &val); right_addr = val.value.integer; /* Get start_addr, stop_addr and addr_incr */ if (! start_item) { *start_addr = left_addr right_addr)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: The behaviour for reg[...] mem[N:0]; %s(\"...\", mem);" " changed in the 1364-2005 standard. To avoid ambiguity," " use mem[0:N] or explicit range parameters" " %s(\"...\", mem, start, stop);. Defaulting to 1364-2005" " behavior.\n", name, name, name); } /* Check that start_addr and stop_addr are within the memory range */ if (left_addr < right_addr) { if (*start_addr < left_addr || *start_addr > right_addr) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Start address %d is out of bounds for memory " "\'%s[%d:%d]\'!\n", name, *start_addr, vpi_get_str(vpiFullName, mitem), left_addr, right_addr); return 1; } if (*stop_addr < left_addr || *stop_addr > right_addr) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Finish address %d is out of bounds for memory " "\'%s[%d:%d]\'!\n", name, *stop_addr, vpi_get_str(vpiFullName, mitem), left_addr, right_addr); return 1; } } else { if (*start_addr < right_addr || *start_addr > left_addr) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Start address %d is out of bounds for memory " "\'%s[%d:%d]\'!\n", name, *start_addr, vpi_get_str(vpiFullName, mitem), left_addr, right_addr); return 1; } if (*stop_addr < right_addr || *stop_addr > left_addr) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Finish address %d is out of bounds for memory " "\'%s[%d:%d]\'!\n", name, *stop_addr, vpi_get_str(vpiFullName, mitem), left_addr, right_addr); return 1; } } return 0; } static PLI_INT32 sys_mem_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there is a file name argument. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_string_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a file name (string).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check that there is a memory argument. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a second (memory) argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, arg) != vpiMemory) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be a memory.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check if there is a starting address argument. */ arg = vpi_scan(argv); if (! arg) return 0; if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's third argument must be a start address " "(numeric).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check if there is a finish address argument. */ arg = vpi_scan(argv); if (! arg) return 0; if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's fourth argument must be a finish address " "(numeric).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 1); return 0; } static PLI_INT32 sys_readmem_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { int code, wwid, addr; FILE*file; char *fname = 0; s_vpi_value value; vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle mitem = 0; vpiHandle start_item = 0; vpiHandle stop_item = 0; /* start_addr and stop_addr are the parameters given to $readmem in the Verilog code. When not specified, start_addr is equal to the lower of the [left,right]_addr and stop_addr is equal to the higher of the [left,right]_addr. */ int start_addr, stop_addr, addr_incr; /* min_addr and max_addr are equal to start_addr and stop_addr if start_addr 0 && fname[0] != '/') { unsigned idx; char path[4096]; for (idx = 0; idx < sl_count; idx += 1) { snprintf(path, sizeof(path), "%s/%s", search_list[idx], fname); path[sizeof(path)-1] = 0; if ((file = fopen(path, "r"))) break; } } if (file == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Unable to open %s for reading.\n", name, fname); free(fname); return 0; } /* We need this many words from the file. */ word_count = max_addr-min_addr+1; wwid = vpi_get(vpiSize, vpi_handle_by_index(mitem, min_addr)); /* variable that will be used by the lexer to pass values back to this code */ value.format = vpiVectorVal; value.value.vector = calloc((wwid+31)/32, sizeof(s_vpi_vecval)); /* Configure the readmem lexer */ if (strcmp(name,"$readmemb") == 0) sys_readmem_start_file(callh, file, 1, wwid, value.value.vector); else sys_readmem_start_file(callh, file, 0, wwid, value.value.vector); /*======================================== Read memory file */ /* Run through the input file and store the new contents in the memory */ addr = start_addr; while ((code = readmemlex()) != 0) { switch (code) { case MEM_ADDRESS: addr = value.value.vector->aval; if (addr < min_addr || addr > max_addr) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s(%s): address (0x%x) is out of range " "[0x%x:0x%x]\n", name, fname, addr, start_addr, stop_addr); goto bailout; } /* if there is an address in the memory file, then turn off any possible warnings about not having enough words to load the memory. This is standard behavior from 1364-2005. */ word_count = 0; break; case MEM_WORD: if (addr >= min_addr && addr <= max_addr) { vpiHandle word_index; word_index = vpi_handle_by_index(mitem, addr); assert(word_index); vpi_put_value(word_index, &value, 0, vpiNoDelay); if (word_count > 0) word_count -= 1; } else { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s(%s): Too many words in the file for the " "requested range [%d:%d].\n", name, fname, start_addr, stop_addr); goto bailout; } addr += addr_incr; break; case MEM_ERROR: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s(%s): Invalid input character: %s\n", name, fname, readmem_error_token); goto bailout; break; default: assert(0); break; } } /* Print a warning if there are not enough words in the data file. */ if (word_count > 0) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s(%s): Not enough words in the file for the " "requested range [%d:%d].\n", name, fname, start_addr, stop_addr); } bailout: free(value.value.vector); free(fname); fclose(file); destroy_readmem_lexor(); return 0; } static PLI_INT32 free_readmempath(p_cb_data cb_data) { unsigned idx; (void)cb_data; /* Parameter is not used. */ for(idx = 0; idx < sl_count; idx += 1) { free(search_list[idx]); } free(search_list); search_list = NULL; sl_count = 0; return 0; } static PLI_INT32 sys_readmempath_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle paths = vpi_scan(argv); s_vpi_value val; unsigned len, idx; char *path; vpi_free_object(argv); /* Get the search path string. */ val.format = vpiStringVal; vpi_get_value(paths, &val); /* Verify that we have a string and that it is not NULL. */ if (val.format != vpiStringVal || !*(val.value.str)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument (%s) is not a valid string.\n", name, vpi_get_str(vpiType, paths)); return 0; } /* * Verify that the search path is composed of only printable * characters. */ len = strlen(val.value.str); for (idx = 0; idx < len; idx++) { if (! isprint((int)val.value.str[idx])) { char msg[64]; char *esc_path = as_escaped(val.value.str); snprintf(msg, sizeof(msg), "WARNING: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s's argument contains non-printable " "characters.\n", msg, name); vpi_printf("%*s \"%s\"\n", (int) strlen(msg), " ", esc_path); free(esc_path); return 0; } } /* Clear the old list before creating the new list. */ free_readmempath(NULL); /* * Break the string into individual paths and add them to the list. * Print a warning if the path is not valid. */ for (path = strtok(val.value.str, ":"); path; path = strtok(NULL, ":")) { int res; struct stat sb; /* Warn the user if the path is not valid. */ res = stat(path, &sb); if (res == 0) { if (!S_ISDIR(sb.st_mode)) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's path element \"%s\" is not a " "directory!\n", name, path); continue; } } else { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s could not find directory \"%s\"!\n", name, path); continue; } /* Add a valid search path element to the list. */ sl_count += 1; search_list = (char **) realloc(search_list, sizeof(char **)*sl_count); search_list[sl_count-1] = strdup(path); } return 0; } static PLI_INT32 sys_writemem_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { int addr; FILE*file; char*fname = 0; unsigned cnt; s_vpi_value value; vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle mitem = 0; vpiHandle start_item = 0; vpiHandle stop_item = 0; int start_addr, stop_addr, addr_incr; int min_addr, max_addr; // Not used in this routine. /*======================================== Get parameters */ get_mem_params(argv, callh, name, &fname, &mitem, &start_item, &stop_item); if (fname == 0) return 0; /*======================================== Process parameters */ if (process_params(mitem, start_item, stop_item, callh, name, &start_addr, &stop_addr, &addr_incr, &min_addr, &max_addr)) { free(fname); return 0; } /* Open the data file. */ file = fopen(fname, "w"); if (file == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s: Unable to open %s for writing.\n", name, fname); free(fname); return 0; } if (strcmp(name,"$writememb")==0) value.format = vpiBinStrVal; else value.format = vpiHexStrVal; /*======================================== Write memory file */ cnt = 0; for(addr=start_addr; addr!=stop_addr+addr_incr; addr+=addr_incr, ++cnt) { vpiHandle word_index; if (cnt%16 == 0) fprintf(file, "// 0x%08x\n", cnt); word_index = vpi_handle_by_index(mitem, addr); assert(word_index); vpi_get_value(word_index, &value); fprintf(file, "%s\n", value.value.str); } fclose(file); free(fname); return 0; } void sys_readmem_register(void) { s_vpi_systf_data tf_data; vpiHandle res; s_cb_data cb_data; tf_data.type = vpiSysTask; tf_data.tfname = "$readmemh"; tf_data.calltf = sys_readmem_calltf; tf_data.compiletf = sys_mem_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$readmemh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$readmemb"; tf_data.calltf = sys_readmem_calltf; tf_data.compiletf = sys_mem_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$readmemb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$readmempath"; tf_data.calltf = sys_readmempath_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$readmempath"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$writememh"; tf_data.calltf = sys_writemem_calltf; tf_data.compiletf = sys_mem_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$writememh"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$writememb"; tf_data.calltf = sys_writemem_calltf; tf_data.compiletf = sys_mem_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$writememb"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); cb_data.reason = cbEndOfSimulation; cb_data.time = 0; cb_data.cb_rtn = free_readmempath; cb_data.user_data = "system"; vpi_register_cb(&cb_data); } iverilog-12_0/vpi/sys_readmem_lex.h000066400000000000000000000024341435245347300175010ustar00rootroot00000000000000#ifndef IVL_sys_readmem_lex_H #define IVL_sys_readmem_lex_H /* * Copyright (c) 1999-2014,2019 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 "vpi_user.h" # define MEM_ADDRESS 257 # define MEM_WORD 258 # define MEM_ERROR 259 extern char *readmem_error_token; extern void sys_readmem_start_file(vpiHandle callh, FILE*in, int bin_flag, unsigned width, struct t_vpi_vecval*val); extern int readmemlex(void); extern void destroy_readmem_lexor(void); #endif /* IVL_sys_readmem_lex_H */ iverilog-12_0/vpi/sys_readmem_lex.lex000066400000000000000000000140071435245347300200410ustar00rootroot00000000000000%option prefix="readmem" %option nounput %option noinput %{ /* * Copyright (c) 1999-2021 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 "sys_readmem_lex.h" # include static void make_addr(void); static void make_hex_value(void); static void make_bin_value(void); static int save_state; char *readmem_error_token = 0; %} %x BIN %x HEX %x CCOMMENT %option noyywrap %% "//".* { ; } [ \t\f\n\r] { ; } @[0-9a-fA-F]+ { make_addr(); return MEM_ADDRESS; } [0-9a-fA-FxXzZ_]+ { make_hex_value(); return MEM_WORD; } [01xXzZ_]+ { make_bin_value(); return MEM_WORD; } "/*" { save_state = YY_START; BEGIN(CCOMMENT); } [^*]* { ; } "*" { ; } "*"+"/" { BEGIN(save_state); } /* Catch any invalid tokens and flagged them as an error. */ . { readmem_error_token = yytext; return MEM_ERROR; } %% /* The call_handle is the handle for the call to the $readmem() system task. This is used for adding line numbers to warnings and error messages. */ static vpiHandle call_handle = 0; static int too_many_digits_warning = 0; static unsigned word_width = 0; static struct t_vpi_vecval*vecval = 0; static void make_addr(void) { sscanf(yytext+1, "%x", (unsigned int*)&vecval->aval); } static void make_hex_value(void) { char*beg = yytext; char*end = beg + strlen(beg); struct t_vpi_vecval*cur; int idx; int width = 0, word_max = word_width; for (idx = 0, cur = vecval ; idx < word_max ; idx += 32, cur += 1) { cur->aval = 0; cur->bval = 0; } cur = vecval; while ((width < word_max) && (end > beg)) { int aval = 0; int bval = 0; end -= 1; if (*end == '_') continue; switch (*end) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': aval = *end - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': aval = *end - 'a' + 10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': aval = *end - 'A' + 10; break; case 'x': case 'X': aval = 15; bval = 15; break; case 'z': case 'Z': bval = 15; break; } cur->aval |= aval << width; cur->bval |= bval << width; width += 4; if (width == 32) { cur += 1; width = 0; word_max -= 32; } } /* If there are more text digits then needed to fill the memory word, count those digits and print a warning message. Print that warning only once per call to $readmemh() so that the user isn't flooded. */ int count_extra_digits = 0; while (end > beg) { end -= 1; if (*end == '_') continue; count_extra_digits += 1; } if (count_extra_digits && too_many_digits_warning==0) { vpi_printf("WARNING: %s:%d: Excess hex digits (%d of '%s') while reading %d-bit words.\n", vpi_get_str(vpiFile, call_handle), vpi_get(vpiLineNo, call_handle), count_extra_digits, beg, word_width); too_many_digits_warning += 1; } } static void make_bin_value(void) { char*beg = yytext; char*end = beg + strlen(beg); struct t_vpi_vecval*cur; int idx; int width = 0, word_max = word_width; for (idx = 0, cur = vecval ; idx < word_max ; idx += 32, cur += 1) { cur->aval = 0; cur->bval = 0; } cur = vecval; while ((width < word_max) && (end > beg)) { PLI_UINT32 aval = 0; PLI_UINT32 bval = 0; end -= 1; if (*end == '_') continue; switch (*end) { case '0': case '1': aval = *end - '0'; break; case 'x': case 'X': aval = 1; bval = 1; break; case 'z': case 'Z': bval = 1; break; } cur->aval |= aval << width; cur->bval |= bval << width; width += 1; if (width == 32) { cur += 1; width = 0; word_max -= 32; } } /* If there are more text digits then needed to fill the memory word, count those digits and print a warning message. Print that warning only once per call to $readmem() so that the user isn't flooded. */ int count_extra_digits = 0; while (end > beg) { end -= 1; if (*end == '_') continue; count_extra_digits += 1; } if (count_extra_digits && too_many_digits_warning==0) { vpi_printf("WARNING: %s:%d: Excess binary digits (%d of '%s') while reading %d-bit words.\n", vpi_get_str(vpiFile, call_handle), vpi_get(vpiLineNo, call_handle), count_extra_digits, beg, word_width); too_many_digits_warning += 1; } } void sys_readmem_start_file(vpiHandle callh, FILE*in, int bin_flag, unsigned width, struct t_vpi_vecval *vv) { call_handle = callh; too_many_digits_warning = 0; yyrestart(in); BEGIN(bin_flag? BIN : HEX); word_width = width; vecval = vv; } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_readmem_lexor(void) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } iverilog-12_0/vpi/sys_scanf.c000066400000000000000000001257351435245347300163160ustar00rootroot00000000000000/* * Copyright (c) 2006-2021 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. */ /* round() is ISO C99 from math.h. This define should enable it. */ # define _ISOC99_SOURCE 1 # define _SVID_SOURCE 1 # define _DEFAULT_SOURCE 1 # include "sys_priv.h" # include # include # include # include # include # include # include # include # include "ivl_alloc.h" /* * The wrapper routines below get a value from either a string or a file. * This structure is used to determine which one is used. The unused one * must be assigned a zero value. */ struct byte_source { const char *str; FILE *fd; }; /* * Wrapper routine to get a byte from either a string or a file descriptor. */ static int byte_getc(struct byte_source *src) { if (src->str) { assert(! src->fd); if (src->str[0] == 0) return EOF; return *(src->str)++; } assert(src->fd); return fgetc(src->fd); } /* * Wrapper routine to unget a byte to either a string or a file descriptor. */ static void byte_ungetc(struct byte_source *src, int ch) { if (ch == EOF) return; if (src->str) { assert(! src->fd); src->str -= 1; return; } assert(src->fd); ungetc(ch, src->fd); } /* * This function matches the input characters of a floating point * number and generates a floating point (double) from that string. * * Do we need support for +-Inf and NaN? It's not in the standard. * * The match variable is set to 1 for a match or 0 for no match. */ static double get_float(struct byte_source *src, unsigned width, int *match) { char *endptr; char *strval = malloc(1); unsigned len = 0; double result; int ch; /* Skip any leading space. */ ch = byte_getc(src); while (isspace(ch)) ch = byte_getc(src); /* If we are being asked for no digits then return a match fail. */ if (width == 0) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } /* Look for the optional sign. */ if ((ch == '+') || (ch == '-')) { /* If we have a sign then the width must not be * one since we need a sign and a digit. */ if (width == 1) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } /* Get any digits before the optional decimal point, but no more * than width. */ while (isdigit(ch) && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } /* Get the optional decimal point and any following digits, but * no more than width total characters are copied. */ if ((ch == '.') && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); /* Get any trailing digits. */ while (isdigit(ch) && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } } /* No leading digits were matched. */ if ((len == 0) || ((len == 1) && ((strval[0] == '+') || (strval[0] == '-')))) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } /* Match an exponent. */ if (((ch == 'e') || (ch == 'E')) && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); /* We must have enough space for at least one digit after * the exponent. */ if (len == width) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } /* Check to see if the exponent has a sign. */ if ((ch == '-') || (ch == '+')) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); /* We must have enough space for at least one digit * after the exponent sign. */ if (len == width) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } } /* We must have at least one digit after the exponent/sign. */ if (! isdigit(ch)) { byte_ungetc(src, ch); free(strval); *match = 0; return 0.0; } /* Get the exponent digits, but no more than width total * characters are copied. */ while (isdigit(ch) && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } } strval[len] = 0; /* Put the last character back. */ byte_ungetc(src, ch); /* Calculate and return the result. */ result = strtod(strval, &endptr); /* If this asserts then there is a bug in the code above.*/ assert(*endptr == 0); free(strval); *match = 1; return result; } /* * Routine to return a floating point value (implements %e, %f and %g). * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_float(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name, char code) { vpiHandle arg; int match; s_vpi_value val; double result; /* Get the real value. */ result = get_float(src, width, &match); /* Nothing was matched. */ if (match == 0) return 0; /* If this match is being suppressed then return after consuming * the digits and report that no arguments were used. */ if (suppress_flag) return -1; /* We must have a variable to put the double value into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%%c format code.", name, code); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Put the value into the variable. */ val.format = vpiRealVal; val.value.real = result; vpi_put_value(arg, &val, 0, vpiNoDelay); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a floating point value scaled and rounded to the * current time scale and precision (implements %t). * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_float_time(vpiHandle callh, vpiHandle argv, struct byte_source*src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle scope = vpi_handle(vpiScope, callh); int time_units = vpi_get(vpiTimeUnit, scope); vpiHandle arg; int match; s_vpi_value val; double result; double scale; /* Get the raw real value. */ result = get_float(src, width, &match); /* Nothing was matched. */ if (match == 0) return 0; /* If this match is being suppressed then return after consuming * the digits and report that no arguments were used. */ if (suppress_flag) return -1; /* Round the raw value to the specified precision. Handle this by shifting the decimal point to the precision where we want to round, do the rounding, then shift the decimal point back */ scale = pow(10.0, timeformat_info.prec); result = round(result*scale) / scale; /* Scale the value from the timeformat units to the current * timescale units. To minimize the error keep the scale an * integer value. */ if (timeformat_info.units >= time_units) { scale = pow(10.0, timeformat_info.units - time_units); result *= scale; } else { scale = pow(10.0, time_units - timeformat_info.units); result /= scale; } /* We must have a variable to put the double value into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%t format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Put the value into the variable. */ val.format = vpiRealVal; val.value.real = result; vpi_put_value(arg, &val, 0, vpiNoDelay); /* We always consume one variable if it is available. */ return 1; } /* * Base routine for getting binary, octal and hex values. * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_base(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name, const char *match, char code, PLI_INT32 type) { vpiHandle arg; char *strval = malloc(1); unsigned len = 0; s_vpi_value val; int ch; /* Skip any leading space. */ ch = byte_getc(src); while (isspace(ch)) ch = byte_getc(src); /* If we are being asked for no digits or the first character is * an underscore then return a match fail. */ if ((width == 0) || (ch == '_')) { byte_ungetc(src, ch); free(strval); return 0; } /* Get all the digits, but no more than width. */ while (strchr(match , ch) && (len < width)) { if (ch == '?') ch = 'x'; strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } strval[len] = 0; /* Put the last character back. */ byte_ungetc(src, ch); /* Nothing was matched. */ if (len == 0) { free(strval); return 0; } /* If this match is being suppressed then return after consuming * the digits and report that no arguments were used. */ if (suppress_flag) { free(strval); return -1; } /* We must have a variable to put the binary value into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%%c format code.", name, code); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(strval); return 0; } /* Put the value into the variable. */ val.format = type; val.value.str = strval; vpi_put_value(arg, &val, 0, vpiNoDelay); free(strval); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a binary value (implements %b). */ static int scan_format_binary(vpiHandle callh, vpiHandle argv, struct byte_source *src, int width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { return scan_format_base(callh, argv, src, width, suppress_flag, name, "01xzXZ?_", 'b', vpiBinStrVal); } /* * Routine to return a character value (implements %c). * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_char(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle arg; s_vpi_value val; int ch; /* If we are being asked for no digits then return a match fail. */ if (width == 0) return 0; /* Get the character to return. */ ch = byte_getc(src); /* Nothing was matched. */ if (ch == EOF) return 0; /* If this match is being suppressed then return after consuming * the character and report that no arguments were used. */ if (suppress_flag) return -1; /* We must have a variable to put the character value into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%c format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Put the character into the variable. */ val.format = vpiIntVal; val.value.integer = ch; vpi_put_value(arg, &val, 0, vpiNoDelay); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a decimal value (implements %d). * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_decimal(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle arg; char *strval = malloc(1); s_vpi_value val; int ch; /* Skip any leading space. */ ch = byte_getc(src); while (isspace(ch)) ch = byte_getc(src); /* If we are being asked for no digits or the first character is * an underscore then return a match fail. */ if ((width == 0) || (ch == '_')) { byte_ungetc(src, ch); free(strval); return 0; } /* A decimal can match a single x/X, ? or z/Z character. */ if (strchr("xX?", ch)) { strval = realloc(strval, 2); strval[0] = 'x'; strval[1] = 0; } else if (strchr("zZ", ch)) { strval = realloc(strval, 2); strval[0] = 'z'; strval[1] = 0; } else { unsigned len = 0; /* To match a + or - we must have a digit after it. */ if (ch == '+') { /* If we have a '+' sign then the width must not be * one since we need a sign and a digit. */ if (width == 1) { free(strval); return 0; } ch = byte_getc(src); if (! isdigit(ch)) { byte_ungetc(src, ch); free(strval); return 0; } /* The '+' used up a character. */ width -= 1; } else if (ch == '-') { /* If we have a '-' sign then the width must not be * one since we need a sign and a digit. */ if (width == 1) { free(strval); return 0; } ch = byte_getc(src); if (isdigit(ch)) { strval = realloc(strval, len+2); strval[len++] = '-'; } else { byte_ungetc(src, ch); free(strval); return 0; } } /* Get all the characters, but no more than width. */ while ((isdigit(ch) || ch == '_') && (len < width)) { strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } strval[len] = 0; /* Put the last character back. */ byte_ungetc(src, ch); /* Nothing was matched. */ if (len == 0) { free(strval); return 0; } } /* If this match is being suppressed then return after consuming * the digits and report that no arguments were used. */ if (suppress_flag) { free(strval); return -1; } /* We must have a variable to put the decimal value into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%d format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(strval); return 0; } /* Put the decimal value into the variable. */ val.format = vpiDecStrVal; val.value.str = strval; vpi_put_value(arg, &val, 0, vpiNoDelay); free(strval); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a hex value (implements %h). */ static int scan_format_hex(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { return scan_format_base(callh, argv, src, width, suppress_flag, name, "0123456789abcdefxzABCDEFXZ?_", 'h', vpiHexStrVal); } /* * Routine to return an octal value (implements %o). */ static int scan_format_octal(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { return scan_format_base(callh, argv, src, width, suppress_flag, name, "01234567xzXZ?_", 'o', vpiOctStrVal); } /* * Routine to return the current hierarchical path (implements %m). */ static int scan_format_module_path(vpiHandle callh, vpiHandle argv, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle scope, arg; char *module_path; s_vpi_value val; /* If this format code is being suppressed then just return that no * arguments were used. */ if (suppress_flag) return -1; /* We must have a variable to put the hierarchical path into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%m format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Get the current hierarchical path. */ scope = vpi_handle(vpiScope, callh); assert(scope); module_path = vpi_get_str(vpiFullName, scope); /* Put the hierarchical path into the variable. */ val.format = vpiStringVal; val.value.str = module_path; vpi_put_value(arg, &val, 0, vpiNoDelay); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a string value (implements %s). * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_string(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle arg; char *strval = malloc(1); unsigned len = 0; s_vpi_value val; int ch; /* Skip any leading space. */ ch = byte_getc(src); while (isspace(ch)) ch = byte_getc(src); /* If we are being asked for no digits then return a match fail. */ if (width == 0) { byte_ungetc(src, ch); free(strval); return 0; } /* Get all the non-space characters, but no more than width. */ while (! isspace(ch) && (len < width)) { if (ch == EOF) break; strval = realloc(strval, len+2); strval[len++] = ch; ch = byte_getc(src); } strval[len] = 0; /* Nothing was matched (this can only happen at EOF). */ if (len == 0) { assert(ch == EOF); free(strval); return 0; } /* Put the last character back. */ byte_ungetc(src, ch); /* If this match is being suppressed then return after consuming * the string and report that no arguments were used. */ if (suppress_flag) { free(strval); return -1; } /* We must have a variable to put the string into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%s format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(strval); return 0; } /* Put the string into the variable. */ val.format = vpiStringVal; val.value.str = strval; vpi_put_value(arg, &val, 0, vpiNoDelay); free(strval); /* We always consume one variable if it is available. */ return 1; } /* * Routine to return a two state value (implements %u). * * Note: Since this is a binary routine it also does not check for leading * space characters or use space as a boundary character. * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_two_state(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle arg; p_vpi_vecval val_ptr; s_vpi_value val; unsigned words, word; PLI_INT32 varlen; /* If we are being asked for no data then return a match fail. */ if (width == 0) return 0; /* Since this is a binary format we do not have an ending sequence. * Consequently we need to use the width to determine how many word * pairs to remove from the input stream. */ if (suppress_flag) { /* If no width was given then just remove one word pair. */ if (width == UINT_MAX) words = 1; else words = (width+31)/32; for (word = 0; word < words; word += 1) { unsigned byte; /* For a suppression we do not care about the endian order * of the bytes. */ for (byte = 0; byte < 4; byte += 1) { int ch = byte_getc(src); /* See the EOF comments below for more details. */ if (ch == EOF) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() only found %u of %u bytes " "needed by %%u format code.\n", name, word*4U + byte, words*4U); return 0; } } } return -1; } /* We must have a variable to put the bits into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%u format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Extract either the given number of word pairs or enough to fill * the variable. */ varlen = (vpi_get(vpiSize, arg)+31)/32; assert(varlen > 0); val_ptr = (p_vpi_vecval) malloc(varlen*sizeof(s_vpi_vecval)); if (width == UINT_MAX) words = (unsigned)varlen; else words = (width+31)/32; for (word = 0; word < words; word += 1) { int byte; PLI_INT32 bits = 0; #ifdef WORDS_BIGENDIAN for (byte = 3; byte >= 0; byte -= 1) { #else for (byte = 0; byte <= 3; byte += 1) { #endif int ch = byte_getc(src); /* If there is an EOF while reading the bytes then treat * that as a non-match. It could be argued that the bytes * should be put back, but that is not practical and since * a binary read should be treated as an atomic operation * it's not helpful either. An EOF while reading is an * error in the data stream so print a message to help the * user debug what is going wrong. The calling routine has * already verified that there is at least one byte * available so this message is not printed when an EOF * occurs at a format code boundary. Which may not be an * error in the data stream. */ if (ch == EOF) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() only found %d of %u bytes needed by " "%%u format code.\n", name, word*4 + #ifdef WORDS_BIGENDIAN (3-byte), #else byte, #endif words*4U); free(val_ptr); return 0; } bits |= (ch & 0xff) << byte*8; } /* Only save the words that are in range. */ assert(varlen>=0); if (word < (unsigned)varlen) { val_ptr[word].aval = bits; val_ptr[word].bval = 0; } } /* Mask the upper bits to match the specified width when required. */ if (width != UINT_MAX) { PLI_INT32 mask = UINT32_MAX >> (32U - ((width - 1U) % 32U + 1U)); val_ptr[words-1].aval &= mask; } /* Not enough words were read to fill the variable so zero fill the * upper words. */ assert(varlen>=0); if (words < (unsigned)varlen) { for (word = words; word < (unsigned)varlen ; word += 1) { val_ptr[word].aval = 0; val_ptr[word].bval = 0; } } /* Put the two-state value into the variable. */ val.format = vpiVectorVal; val.value.vector = val_ptr; vpi_put_value(arg, &val, 0, vpiNoDelay); free(val_ptr); /* One variable was consumed. */ return 1; } /* * Routine to return a four state value (implements %z). * * Note: Since this is a binary routine it also does not check for leading * space characters or use space as a boundary character. * * Return: 1 for a match, 0 for no match/variable and -1 for a * suppressed match. No variable is fatal. */ static int scan_format_four_state(vpiHandle callh, vpiHandle argv, struct byte_source *src, unsigned width, unsigned suppress_flag, ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle arg; p_vpi_vecval val_ptr; s_vpi_value val; unsigned words, word; PLI_INT32 varlen; /* If we are being asked for no data then return a match fail. */ if (width == 0) return 0; /* Since this is a binary format we do not have an ending sequence. * Consequently we need to use the width to determine how many word * pairs to remove from the input stream. */ if (suppress_flag) { /* If no width was given then just remove one word pair. */ if (width == UINT_MAX) words = 1; else words = (width+31)/32; for (word = 0; word < words; word += 1) { unsigned byte; /* For a suppression we do not care about the endian order * of the bytes. */ for (byte = 0; byte < 8; byte += 1) { int ch = byte_getc(src); /* See the EOF comments below for more details. */ if (ch == EOF) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() only found %u of %u bytes " "needed by %%z format code.\n", name, word*8U + byte, words*8U); return 0; } } } return -1; } /* We must have a variable to put the bits into. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() ran out of variables for %%z format code.", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Extract either the given number of word pairs or enough to fill * the variable. */ varlen = (vpi_get(vpiSize, arg)+31)/32; assert(varlen > 0); val_ptr = (p_vpi_vecval) malloc(varlen*sizeof(s_vpi_vecval)); if (width == UINT_MAX) words = (unsigned)varlen; else words = (width+31)/32; for (word = 0; word < words; word += 1) { unsigned elem; for (elem = 0; elem < 2; elem += 1) { int byte; PLI_INT32 bits = 0; #ifdef WORDS_BIGENDIAN for (byte = 3; byte >= 0; byte -= 1) { #else for (byte = 0; byte <= 3; byte += 1) { #endif int ch = byte_getc(src); /* If there is an EOF while reading the bytes then * treat that as a non-match. It could be argued that * the bytes should be put back, but that is not * practical and since a binary read should be * treated as an atomic operation it's not helpful * either. An EOF while reading is an error in the * data stream so print a message to help the user * debug what is going wrong. The calling routine has * already verified that there is at least one byte * available so this message is not printed when an * EOF occurs at a format code boundary. Which may * not be an error in the data stream. */ if (ch == EOF) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() only found %d of %u bytes " "needed by %%z format code.\n", name, word*8 + elem*4 + #ifdef WORDS_BIGENDIAN (3-byte), #else byte, #endif words*8U); free(val_ptr); return 0; } bits |= (ch & 0xff) << byte*8; } /* Only save the words that are in range. */ if (word < (unsigned)varlen) { *(&val_ptr[word].aval+elem) = bits; } } } /* Mask the upper bits to match the specified width when required. */ if (width != UINT_MAX) { PLI_INT32 mask = UINT32_MAX >> (32U - ((width - 1U) % 32U + 1U)); val_ptr[words-1].aval &= mask; val_ptr[words-1].bval &= mask; } /* Not enough words were read to fill the variable so zero fill the * upper words. */ assert(varlen>=0); if (words < (unsigned)varlen) { for (word = words; word < (unsigned)varlen ; word += 1) { val_ptr[word].aval = 0; val_ptr[word].bval = 0; } } /* Put the four-state value into the variable. */ val.format = vpiVectorVal; val.value.vector = val_ptr; vpi_put_value(arg, &val, 0, vpiNoDelay); free(val_ptr); /* One variable was consumed. */ return 1; } /* * The $fscanf and $sscanf functions are the same except for the first * argument, which is the source. The wrapper functions below peel off * the first argument and make a byte_source object that then gets * passed to this function, which processes the rest of the function. */ static int scan_format(vpiHandle callh, struct byte_source*src, vpiHandle argv, ICARUS_VPI_CONST PLI_BYTE8 *name) { s_vpi_value val; vpiHandle item; PLI_INT32 len, words, idx, mask; char *fmt, *fmtp; int rc = 0; int ch; int match = 1; /* Get the format string. */ item = vpi_scan(argv); assert(item); /* Look for an undefined bit (X/Z) in the format string. If one is * found just return EOF. */ len = vpi_get(vpiSize, item); words = ((len + 31) / 32) - 1; val.format = vpiVectorVal; vpi_get_value(item, &val); /* Check the full words for an undefined bit. */ for (idx = 0; idx < words; idx += 1) { if (val.value.vector[idx].bval) { match = 0; rc = EOF; break; } } /* The mask is defined to be 32 bits. */ mask = UINT32_MAX >> (32U - ((len - 1U) % 32U + 1U)); /* Check the top word for an undefined bit. */ if (match && (val.value.vector[words].bval & mask)) { match = 0; rc = EOF; } /* Now get the format as a string. */ val.format = vpiStringVal; vpi_get_value(item, &val); fmtp = fmt = strdup(val.value.str); /* See if we are at EOF before we even start. */ ch = byte_getc(src); if (ch == EOF) { rc = EOF; match = 0; } byte_ungetc(src, ch); while ( fmtp && *fmtp != 0 && match) { if (isspace((int)*fmtp)) { /* White space matches a string of white space in the * input. The number of spaces is not relevant, and * the match may be 0 or more spaces. */ while (*fmtp && isspace((int)*fmtp)) fmtp += 1; ch = byte_getc(src); while (isspace(ch)) ch = byte_getc(src); byte_ungetc(src, ch); } else if (*fmtp != '%') { /* Characters other than % match themselves. */ ch = byte_getc(src); if (ch != *fmtp) { byte_ungetc(src, ch); break; } fmtp += 1; } else { /* We are at a pattern character. The pattern has * the format %x no matter what the x code, so * parse it generically first. */ unsigned suppress_flag = 0; unsigned max_width = UINT_MAX; int code = 0; /* Look for the suppression character '*'. */ fmtp += 1; if (*fmtp == '*') { suppress_flag = 1; fmtp += 1; } /* Look for the maximum match width. */ if (isdigit((int)*fmtp)) { max_width = 0; while (isdigit((int)*fmtp)) { max_width *= 10; max_width += *fmtp - '0'; fmtp += 1; } } /* Get the format character. */ code = *fmtp; fmtp += 1; /* The format string is parsed: * - max_width is the width, * - code is the format code character, * - suppress_flag is true if the match is to be ignored. * Now interpret the code. */ switch (code) { /* Read a '%' character from the input. */ case '%': assert(max_width == -1U); assert(suppress_flag == 0); ch = byte_getc(src); if (ch != '%') { byte_ungetc(src, ch); match = 0; } break; case 'b': match = scan_format_binary(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 'c': match = scan_format_char(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 'd': match = scan_format_decimal(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 'e': case 'f': case 'g': match = scan_format_float(callh, argv, src, max_width, suppress_flag, name, code); if (match == 1) rc += 1; break; case 'h': case 'x': match = scan_format_hex(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 'm': /* Since this code does not consume any characters * the width makes no difference. */ match = scan_format_module_path(callh, argv, suppress_flag, name); if (match == 1) rc += 1; break; case 'o': match = scan_format_octal(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 's': match = scan_format_string(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 't': match = scan_format_float_time(callh, argv, src, max_width, suppress_flag, name); if (match == 1) rc += 1; break; case 'u': match = scan_format_two_state(callh, argv, src, max_width, suppress_flag, name); /* If a binary match fails and it is the first item * matched then treat that as an EOF. */ if ((match == 0) && (rc == 0)) rc = EOF; if (match == 1) rc += 1; break; case 'v': vpi_printf("SORRY: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() format code '%%%c' is not " "currently supported.\n", name, code); vpip_set_return_value(1); vpi_control(vpiFinish, 1); break; case 'z': match = scan_format_four_state(callh, argv, src, max_width, suppress_flag, name); /* If a binary match fails and it is the first item * matched then treat that as an EOF. */ if ((match == 0) && (rc == 0)) rc = EOF; if (match == 1) rc += 1; break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() was given an invalid format code: " "%%%c\n", name, code); vpip_set_return_value(1); vpi_control(vpiFinish, 1); break; } } } /* Clean up the allocated memory. */ free(fmt); vpi_free_object(argv); /* Return the number of successful matches. */ val.format = vpiIntVal; val.value.integer = rc; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Is the object a variable/register or a piece of one. */ static int is_assignable_obj(vpiHandle obj) { unsigned rtn = 0; assert(obj); switch(vpi_get(vpiType, obj)) { /* We can not assign to a vpiNetArray. */ case vpiMemoryWord: if (vpi_get(vpiType, vpi_handle(vpiParent, obj)) == vpiMemory) { rtn = 1; } break; case vpiPartSelect: if (! is_assignable_obj(vpi_handle(vpiParent, obj))) break; // fallthrough case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiRealVar: case vpiReg: case vpiTimeVar: case vpiStringVar: rtn = 1; break; } return rtn; } static int sys_check_args(vpiHandle callh, vpiHandle argv, const PLI_BYTE8 *name) { vpiHandle arg; int cnt = 3, rtn = 0; /* The format (2nd) argument must be a string. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least three argument.\n", name); return 1; } if(! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s format argument must be a string.\n", name); rtn = 1; } /* The rest of the arguments must be assignable. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least three argument.\n", name); return 1; } do { if (! is_assignable_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s argument %d (a %s) is not assignable.\n", name, cnt, vpi_get_str(vpiType, arg)); rtn = 1; } arg = vpi_scan(argv); cnt += 1; } while (arg); return rtn; } static PLI_INT32 sys_fscanf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least three argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a file descriptor. */ if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument (fd) must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); vpi_free_object(argv); return 0; } if (sys_check_args(callh, argv, name)) { vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_fscanf_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; struct byte_source src; FILE *fd; errno = 0; val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); fd = vpi_get_file(val.value.integer); if (!fd) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (int)val.value.integer, name); errno = EBADF; val.format = vpiIntVal; val.value.integer = EOF; vpi_put_value(callh, &val, 0, vpiNoDelay); vpi_free_object(argv); return 0; } src.str = 0; src.fd = fd; scan_format(callh, &src, argv, name); return 0; } static PLI_INT32 sys_sscanf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle reg; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least three argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a register or a string. */ reg = vpi_scan(argv); /* This should never be zero. */ switch(vpi_get(vpiType, reg)) { case vpiReg: case vpiStringVar: break; case vpiConstant: case vpiParameter: if (vpi_get(vpiConstType, reg) == vpiStringConst) break; // fallthrough default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's first argument must be a register or a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); vpi_free_object(argv); return 0; } if (sys_check_args(callh, argv, name)) { vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 sys_sscanf_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; struct byte_source src; char *str; val.format = vpiStringVal; vpi_get_value(vpi_scan(argv), &val); str = strdup(val.value.str); src.str = str; src.fd = 0; scan_format(callh, &src, argv, name); free(str); return 0; } void sys_scanf_register(void) { s_vpi_systf_data tf_data; vpiHandle res; /*============================== fscanf */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$fscanf"; tf_data.calltf = sys_fscanf_calltf; tf_data.compiletf = sys_fscanf_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fscanf"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /*============================== sscanf */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$sscanf"; tf_data.calltf = sys_sscanf_calltf; tf_data.compiletf = sys_sscanf_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$sscanf"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_sdf.c000066400000000000000000000243771435245347300160000ustar00rootroot00000000000000/* * Copyright (c) 2007-2021 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 "sys_priv.h" # include "sdf_priv.h" # include # include # include /* * These are static context */ int sdf_flag_warning = 0; int sdf_flag_inform = 0; int sdf_min_typ_max; /* Scope of the $sdf_annotate call. Annotation starts here. */ static vpiHandle sdf_scope; static vpiHandle sdf_callh = 0; /* The cell in process. */ static vpiHandle sdf_cur_cell; static vpiHandle find_scope(vpiHandle scope, const char*name) { vpiHandle idx = vpi_iterate(vpiModule, scope); /* If this scope has no modules then it can't have the one we * are looking for so just return 0. */ if (idx == 0) return 0; vpiHandle cur; while ( (cur = vpi_scan(idx)) ) { if ( strcmp(name, vpi_get_str(vpiName,cur)) == 0) { vpi_free_object(idx); return cur; } } return 0; } /* * These functions are called by the SDF parser during parsing to * handling items discovered in the parse. */ void sdf_select_instance(const char*celltype, const char*cellinst) { char buffer[128]; /* First follow the hierarchical parts of the cellinst name to get to the cell that I'm looking for. */ vpiHandle scope = sdf_scope; const char*src = cellinst; const char*dp; while ( (dp=strchr(src, '.')) ) { unsigned len = dp - src; assert(dp >= src); assert(len < sizeof buffer); strncpy(buffer, src, len); buffer[len] = 0; vpiHandle tmp_scope = find_scope(scope, buffer); if (tmp_scope == 0) { vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), (int)vpi_get(vpiLineNo, sdf_callh)); vpi_printf("Cannot find %s in scope %s.\n", buffer, vpi_get_str(vpiFullName, scope)); break; } assert(tmp_scope); scope = tmp_scope; src = dp + 1; } /* Now find the cell. */ if (src[0] == 0) sdf_cur_cell = sdf_scope; else sdf_cur_cell = find_scope(scope, src); if (sdf_cur_cell == 0) { vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), (int)vpi_get(vpiLineNo, sdf_callh)); vpi_printf("Unable to find %s in scope %s.\n", src, vpi_get_str(vpiFullName, scope)); return; } /* The scope that matches should be a module. */ if (vpi_get(vpiType,sdf_cur_cell) != vpiModule) { vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), (int)vpi_get(vpiLineNo, sdf_callh)); vpi_printf("Scope %s in %s is not a module.\n", src, vpi_get_str(vpiFullName, scope)); } /* The matching scope (a module) should have the expected type. */ if (strcmp(celltype,vpi_get_str(vpiDefName,sdf_cur_cell)) != 0) { vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), (int)vpi_get(vpiLineNo, sdf_callh)); vpi_printf("Module %s in %s is not a %s; it is a ", src, vpi_get_str(vpiFullName, scope), celltype); vpi_printf("%s\n", vpi_get_str(vpiDefName, sdf_cur_cell)); } } static const char*edge_str(int vpi_edge) { if (vpi_edge == vpiNoEdge) return ""; if (vpi_edge == vpiPosedge) return "posedge "; if (vpi_edge == vpiNegedge) return "negedge "; return "edge.. "; } void sdf_iopath_delays(int vpi_edge, const char*src, const char*dst, const struct sdf_delval_list_s*delval_list) { vpiHandle iter, path; int match_count = 0; if (sdf_cur_cell == 0) return; iter = vpi_iterate(vpiModPath, sdf_cur_cell); /* Search for the modpath that matches the IOPATH by looking for the modpath that uses the same ports as the ports that the parser has found. */ if (iter) while ( (path = vpi_scan(iter)) ) { s_vpi_delay delays; struct t_vpi_time delay_vals[12]; int idx; vpiHandle path_t_in = vpi_handle(vpiModPathIn,path); vpiHandle path_t_out = vpi_handle(vpiModPathOut,path); vpiHandle path_in = vpi_handle(vpiExpr,path_t_in); vpiHandle path_out = vpi_handle(vpiExpr,path_t_out); /* The expressions for the path terms must be signals, vpiNet or vpiReg. */ assert(vpi_get(vpiType,path_in) == vpiNet); assert(vpi_get(vpiType,path_out) == vpiNet || vpi_get(vpiType,path_out) == vpiReg); /* If the src name doesn't match, go on. */ if (strcmp(src,vpi_get_str(vpiName,path_in)) != 0) continue; /* The edge type must match too. But note that if this IOPATH has no edge, then it matches with all edges of the modpath object. */ /* --> Is this correct in the context of the 10, 01, etc. edges? */ if (vpi_edge != vpiNoEdge && vpi_get(vpiEdge,path_t_in) != vpi_edge) continue; /* If the dst name doesn't match, go on. */ if (strcmp(dst,vpi_get_str(vpiName,path_out)) != 0) continue; /* Ah, this must be a match! */ delays.da = delay_vals; delays.no_of_delays = delval_list->count; delays.time_type = vpiScaledRealTime; delays.mtm_flag = 0; delays.append_flag = 0; delays.pulsere_flag = 0; vpi_get_delays(path, &delays); for (idx = 0 ; idx < delval_list->count ; idx += 1) { delay_vals[idx].type = vpiScaledRealTime; if (delval_list->val[idx].defined) { delay_vals[idx].real = delval_list->val[idx].value; } } vpi_put_delays(path, &delays); match_count += 1; } if (match_count == 0) { vpi_printf("SDF WARNING: %s:%d: ", vpi_get_str(vpiFile, sdf_callh), (int)vpi_get(vpiLineNo, sdf_callh)); vpi_printf("Unable to match ModPath %s%s -> %s in %s\n", edge_str(vpi_edge), src, dst, vpi_get_str(vpiFullName, sdf_cur_cell)); } } static void check_command_line_args(void) { struct t_vpi_vlog_info vlog_info; int idx; static int sdf_command_line_done = 0; if (sdf_command_line_done) return; vpi_get_vlog_info(&vlog_info); for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-sdf-warn") == 0) { sdf_flag_warning = 1; } else if (strcmp(vlog_info.argv[idx],"-sdf-info") == 0) { sdf_flag_inform = 1; } else if (strcmp(vlog_info.argv[idx],"-sdf-verbose") == 0) { sdf_flag_warning = 1; sdf_flag_inform = 1; } } sdf_command_line_done = 1; } static PLI_INT32 sys_sdf_annotate_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall,0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle module; check_command_line_args(); /* Check that we have a file name argument. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a file name argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (! is_string_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's file name must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The module argument is optional. */ module = vpi_scan(argv); if (module == 0) return 0; if (vpi_get(vpiType, module) != vpiModule) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's second argument must be a module instance.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Warn the user that we only use the first two arguments. */ if (vpi_scan(argv) != 0) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s currently only uses the first two argument.\n", name); vpi_free_object(argv); } return 0; } static PLI_INT32 sys_sdf_annotate_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); FILE *sdf_fd; char *fname = get_filename(callh, name, vpi_scan(argv)); if (fname == 0) { vpi_free_object(argv); return 0; } sdf_fd = fopen(fname, "r"); if (sdf_fd == 0) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open SDF file \"%s\"." " Skipping this annotation.\n", fname); vpi_free_object(argv); free(fname); return 0; } /* The optional second argument is the scope to annotate. */ sdf_scope = vpi_scan(argv); if (sdf_scope) vpi_free_object(argv); else sdf_scope = vpi_handle(vpiScope, callh); /* Select which delay to use. */ sdf_min_typ_max = vpi_get(_vpiDelaySelection, 0); sdf_cur_cell = 0; sdf_callh = callh; sdf_process_file(sdf_fd, fname); sdf_callh = 0; fclose(sdf_fd); free(fname); return 0; } void sys_sdf_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysTask; tf_data.tfname = "$sdf_annotate"; tf_data.calltf = sys_sdf_annotate_calltf; tf_data.compiletf = sys_sdf_annotate_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$sdf_annotate"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_table.c000066400000000000000000000145361435245347300163070ustar00rootroot00000000000000/* * Copyright (c) 1999-2018 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 "vpi_config.h" # include "vpi_user.h" # include # include # include extern void sys_convert_register(void); extern void sys_countdrivers_register(void); extern void sys_darray_register(void); extern void sys_fileio_register(void); extern void sys_finish_register(void); extern void sys_deposit_register(void); extern void sys_display_register(void); extern void sys_plusargs_register(void); extern void sys_queue_register(void); extern void sys_random_register(void); extern void sys_random_mti_register(void); extern void sys_readmem_register(void); extern void sys_scanf_register(void); extern void sys_sdf_register(void); extern void sys_time_register(void); extern void sys_vcd_register(void); extern void sys_vcdoff_register(void); extern void sys_special_register(void); extern void table_model_register(void); extern void vams_simparam_register(void); #ifdef HAVE_LIBZ #ifdef HAVE_LIBBZ2 extern void sys_lxt_register(void); #else static void sys_lxt_register(void) { fputs("LXT support disabled since libbzip2 not available\n",stderr); exit(1); } #endif extern void sys_lxt2_register(void); extern void sys_fst_register(void); #else static void sys_lxt_register(void) { fputs("LXT support disabled since zlib not available\n",stderr); exit(1); } static void sys_lxt2_register(void) { fputs("LXT2 support disabled since zlib not available\n",stderr); exit(1); } static void sys_fst_register(void) { fputs("FST support disabled since zlib not available\n",stderr); exit(1); } #endif static void sys_lxt_or_vcd_register(void) { int idx; struct t_vpi_vlog_info vlog_info; const char*dumper; /* Get the dumper of choice from the IVERILOG_DUMPER environment variable. */ dumper = getenv("IVERILOG_DUMPER"); if (dumper) { char*cp = strchr(dumper,'='); if (cp != 0) dumper = cp + 1; } else { dumper = "vcd"; } /* Scan the extended arguments, looking for flags that select major features. This can override the environment variable settings. */ vpi_get_vlog_info(&vlog_info); for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-fst") == 0) { dumper = "fst"; } else if (strcmp(vlog_info.argv[idx],"-fst-space") == 0) { dumper = "fst"; } else if (strcmp(vlog_info.argv[idx],"-fst-speed") == 0) { dumper = "fst"; } else if (strcmp(vlog_info.argv[idx],"-fst-space-speed") == 0) { dumper = "fst"; } else if (strcmp(vlog_info.argv[idx],"-fst-speed-space") == 0) { dumper = "fst"; } else if (strcmp(vlog_info.argv[idx],"-fst-none") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-lxt") == 0) { dumper = "lxt"; } else if (strcmp(vlog_info.argv[idx],"-lxt-space") == 0) { dumper = "lxt"; } else if (strcmp(vlog_info.argv[idx],"-lxt-speed") == 0) { dumper = "lxt"; } else if (strcmp(vlog_info.argv[idx],"-lxt-none") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-lxt2") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lxt2-space") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lxt2-speed") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lxt2-none") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-lx2") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lx2-space") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lx2-speed") == 0) { dumper = "lxt2"; } else if (strcmp(vlog_info.argv[idx],"-lx2-none") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-vcd") == 0) { dumper = "vcd"; } else if (strcmp(vlog_info.argv[idx],"-vcd-off") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-vcd-none") == 0) { dumper = "none"; } else if (strcmp(vlog_info.argv[idx],"-none") == 0) { dumper = "none"; } } if (strcmp(dumper, "vcd") == 0) sys_vcd_register(); else if (strcmp(dumper, "VCD") == 0) sys_vcd_register(); else if (strcmp(dumper, "fst") == 0) sys_fst_register(); else if (strcmp(dumper, "FST") == 0) sys_fst_register(); else if (strcmp(dumper, "lxt") == 0) sys_lxt_register(); else if (strcmp(dumper, "LXT") == 0) sys_lxt_register(); else if (strcmp(dumper, "lxt2") == 0) sys_lxt2_register(); else if (strcmp(dumper, "LXT2") == 0) sys_lxt2_register(); else if (strcmp(dumper, "lx2") == 0) sys_lxt2_register(); else if (strcmp(dumper, "LX2") == 0) sys_lxt2_register(); else if (strcmp(dumper, "none") == 0) sys_vcdoff_register(); else if (strcmp(dumper, "NONE") == 0) sys_vcdoff_register(); else { vpi_mcd_printf(1, "system.vpi: Unknown dumper format: %s," " using VCD instead.\n", dumper); sys_vcd_register(); } } void (*vlog_startup_routines[])(void) = { sys_convert_register, sys_countdrivers_register, sys_darray_register, sys_fileio_register, sys_finish_register, sys_deposit_register, sys_display_register, sys_plusargs_register, sys_queue_register, sys_random_register, sys_random_mti_register, sys_readmem_register, sys_scanf_register, sys_time_register, sys_lxt_or_vcd_register, sys_sdf_register, sys_special_register, table_model_register, vams_simparam_register, 0 }; iverilog-12_0/vpi/sys_time.c000066400000000000000000000116001435245347300161430ustar00rootroot00000000000000/* * Copyright (c) 2000-2011 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 "sys_priv.h" #include #include #include static PLI_INT32 sys_time_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_value val; s_vpi_time now; vpiHandle call_handle; vpiHandle mod; int units, prec; long scale; call_handle = vpi_handle(vpiSysTfCall, 0); assert(call_handle); mod = sys_func_module(call_handle); now.type = vpiSimTime; vpi_get_time(0, &now); /* All the variants but $simtime return the time in units of the local scope. The $simtime function returns the simulation time. */ if (strcmp(name, "$simtime") == 0) units = vpi_get(vpiTimePrecision, 0); else units = vpi_get(vpiTimeUnit, mod); prec = vpi_get(vpiTimePrecision, 0); scale = 1; while (units > prec) { scale *= 10; units -= 1; } assert(8*sizeof(long long) >= 64); { long frac; long long tmp_now = ((long long)now.high) << 32; tmp_now += (long long)now.low; frac = tmp_now % (long long)scale; tmp_now /= (long long)scale; /* Round to the nearest integer, which may be up. */ if ((scale > 1) && (frac >= scale/2)) tmp_now += 1; now.low = tmp_now & 0xffffffff; now.high = tmp_now >> 32LL; } val.format = vpiTimeVal; val.value.time = &now; vpi_put_value(call_handle, &val, 0, vpiNoDelay); return 0; } /* This also supports $abstime() from VAMS-2.3. */ static PLI_INT32 sys_realtime_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_value val; s_vpi_time now; vpiHandle callh; vpiHandle mod; callh = vpi_handle(vpiSysTfCall, 0); assert(callh); mod = sys_func_module(callh); now.type = vpiScaledRealTime; vpi_get_time(mod, &now); /* For $abstime() we return the time in second. */ if (strcmp(name, "$abstime") == 0) { PLI_INT32 scale = vpi_get(vpiTimeUnit, mod); if (scale >= 0) now.real *= pow(10.0, scale); else now.real /= pow(10.0, -scale); } val.format = vpiRealVal; val.value.real = now.real; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } void sys_time_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.tfname = "$time"; tf_data.sysfunctype = vpiTimeFunc; tf_data.calltf = sys_time_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$time"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.tfname = "$realtime"; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = sys_realtime_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$realtime"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.tfname = "$stime"; tf_data.sysfunctype = vpiIntFunc; tf_data.calltf = sys_time_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$stime"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.tfname = "$simtime"; tf_data.sysfunctype = vpiTimeFunc; tf_data.calltf = sys_time_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$simtime"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.tfname = "$abstime"; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = sys_realtime_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$abstime"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_vcd.c000066400000000000000000000670621435245347300157760ustar00rootroot00000000000000/* * Copyright (c) 1999-2021 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 "sys_priv.h" # include "vcd_priv.h" /* * This file contains the implementations of the VCD related functions. */ # include # include # include # include # include # include "ivl_alloc.h" static char *dump_path = NULL; static FILE *dump_file = NULL; static int dump_no_date = 0; static struct t_vpi_time zero_delay = { vpiSimTime, 0, 0, 0.0 }; /* * The vcd_list is the list of all the objects that are tracked for * dumping. The vcd_checkpoint goes through the list to dump the current * values for everything. When the item has a value change, it is added to the * vcd_dmp_list for dumping in the current time step. * * The vcd_const_list is a list of all of the parameters that are being * dumped. This list is scanned less often, since parameters do not change * values. */ DECLARE_VCD_INFO(vcd_info, const char*); static struct vcd_info *vcd_const_list = NULL; static struct vcd_info *vcd_list = NULL; static struct vcd_info *vcd_dmp_list = NULL; static PLI_UINT64 vcd_cur_time = 0; static int dump_is_off = 0; static long dump_limit = 0; static int dump_is_full = 0; static int finish_status = 0; static const char*units_names[] = { "s", "ms", "us", "ns", "ps", "fs" }; static char vcdid[8] = "!"; static void gen_new_vcd_id(void) { static unsigned value = 0; unsigned v = ++value; unsigned int i; for (i=0; i < sizeof(vcdid)-1; i++) { vcdid[i] = (char)((v%94)+33); /* for range 33..126 */ v /= 94; if(!v) { vcdid[i+1] = '\0'; return; } } // This should never happen since 94**7 is a lot if identifiers! assert(0); } static char *truncate_bitvec(char *s) { char r; r=*s; if(r=='1') return s; else s += 1; for(;;s++) { char l; l=r; r=*s; if(!r) return (s-1); if(l!=r) return(((l=='0')&&(r=='1'))?s:s-1); } } static void show_this_item(struct vcd_info*info) { s_vpi_value value; PLI_INT32 type = vpi_get(vpiType, info->item); if (type == vpiRealVar) { value.format = vpiRealVal; vpi_get_value(info->item, &value); fprintf(dump_file, "r%.16g %s\n", value.value.real, info->ident); } else if (type == vpiNamedEvent) { fprintf(dump_file, "1%s\n", info->ident); } else if (type == vpiParameter && vpi_get(vpiConstType, info->item) == vpiRealConst) { value.format = vpiRealVal; vpi_get_value(info->item, &value); fprintf(dump_file, "r%.16g %s\n", value.value.real, info->ident); } else if (vpi_get(vpiSize, info->item) == 1) { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); fprintf(dump_file, "%s%s\n", value.value.str, info->ident); } else { value.format = vpiBinStrVal; vpi_get_value(info->item, &value); fprintf(dump_file, "b%s %s\n", truncate_bitvec(value.value.str), info->ident); } } /* Dump values for a $dumpoff. */ static void show_this_item_x(struct vcd_info*info) { PLI_INT32 type = vpi_get(vpiType, info->item); if (type == vpiRealVar) { /* Some tools dump nothing here...? */ fprintf(dump_file, "rNaN %s\n", info->ident); } else if (type == vpiNamedEvent) { /* Do nothing for named events. */ } else if (vpi_get(vpiSize, info->item) == 1) { fprintf(dump_file, "x%s\n", info->ident); } else { fprintf(dump_file, "bx %s\n", info->ident); } } /* * managed qsorted list of scope names/variables for duplicates bsearching */ struct vcd_names_list_s vcd_tab = { 0, 0, 0, 0 }; struct vcd_names_list_s vcd_var = { 0, 0, 0, 0 }; static int dumpvars_status = 0; /* 0:fresh 1:cb installed, 2:callback done */ static PLI_UINT64 dumpvars_time; __inline__ static int dump_header_pending(void) { return dumpvars_status != 2; } static PLI_INT32 variable_cb_2(p_cb_data cause) { struct vcd_info* info = vcd_dmp_list; PLI_UINT64 now = timerec_to_time64(cause->time); if (now != vcd_cur_time) { fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now); vcd_cur_time = now; } do { show_this_item(info); info->scheduled = 0; } while ((info = info->dmp_next) != 0); vcd_dmp_list = 0; return 0; } static PLI_INT32 variable_cb_1(p_cb_data cause) { struct t_cb_data cb; struct vcd_info*info = (struct vcd_info*)cause->user_data; if (dump_is_full) return 0; if (dump_is_off) return 0; if (dump_header_pending()) return 0; if (info->scheduled) return 0; if ((dump_limit > 0) && (ftell(dump_file) > dump_limit)) { dump_is_full = 1; vpi_printf("WARNING: Dump file limit (%ld bytes) " "exceeded.\n", dump_limit); fprintf(dump_file, "$comment Dump file limit (%ld bytes) " "exceeded. $end\n", dump_limit); return 0; } if (!vcd_dmp_list) { cb = *cause; cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = variable_cb_2; vpi_register_cb(&cb); } info->scheduled = 1; info->dmp_next = vcd_dmp_list; vcd_dmp_list = info; return 0; } /* * This is called at the end of the timestep where the $dumpvars task is * called. This allows for values to settle for the timestep, so that the * checkpoint gets the current values. */ static PLI_INT32 dumpvars_cb(p_cb_data cause) { if (dumpvars_status != 1) return 0; dumpvars_status = 2; dumpvars_time = timerec_to_time64(cause->time); vcd_cur_time = dumpvars_time; fprintf(dump_file, "$enddefinitions $end\n"); if (!dump_is_off) { fprintf(dump_file, "$comment Show the parameter values. $end\n"); fprintf(dump_file, "$dumpall\n"); ITERATE_VCD_INFO(vcd_const_list, vcd_info, next, show_this_item); fprintf(dump_file, "$end\n"); fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time); fprintf(dump_file, "$dumpvars\n"); ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); fprintf(dump_file, "$end\n"); } return 0; } static PLI_INT32 finish_cb(p_cb_data cause) { struct vcd_info *cur, *next; if (finish_status != 0) return 0; finish_status = 1; dumpvars_time = timerec_to_time64(cause->time); if (!dump_is_off && !dump_is_full && dumpvars_time != vcd_cur_time) { fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time); } fclose(dump_file); for (cur = vcd_list ; cur ; cur = next) { next = cur->next; free((char *)cur->ident); free(cur); } vcd_list = 0; for (cur = vcd_const_list ; cur ; cur = next) { next = cur->next; free((char *)cur->ident); free(cur); } vcd_const_list = 0; vcd_names_delete(&vcd_tab); vcd_names_delete(&vcd_var); nexus_ident_delete(); free(dump_path); dump_path = 0; return 0; } __inline__ static int install_dumpvars_callback(void) { struct t_cb_data cb; if (dumpvars_status == 1) return 0; if (dumpvars_status == 2) { vpi_printf("VCD warning: $dumpvars ignored, previously" " called at simtime %" PLI_UINT64_FMT "\n", dumpvars_time); return 1; } cb.time = &zero_delay; cb.reason = cbReadOnlySynch; cb.cb_rtn = dumpvars_cb; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); cb.reason = cbEndOfSimulation; cb.cb_rtn = finish_cb; vpi_register_cb(&cb); dumpvars_status = 1; return 0; } static PLI_INT32 sys_dumpoff_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; dump_is_off = 1; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64); vcd_cur_time = now64; } fprintf(dump_file, "$dumpoff\n"); ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item_x); fprintf(dump_file, "$end\n"); return 0; } static PLI_INT32 sys_dumpon_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (!dump_is_off) return 0; dump_is_off = 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64); vcd_cur_time = now64; } fprintf(dump_file, "$dumpon\n"); ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); fprintf(dump_file, "$end\n"); return 0; } static PLI_INT32 sys_dumpall_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { s_vpi_time now; PLI_UINT64 now64; (void)name; /* Parameter is not used. */ if (dump_is_off) return 0; if (dump_file == 0) return 0; if (dump_header_pending()) return 0; now.type = vpiSimTime; vpi_get_time(0, &now); now64 = timerec_to_time64(&now); if (now64 > vcd_cur_time) { fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", now64); vcd_cur_time = now64; } fprintf(dump_file, "$dumpall\n"); ITERATE_VCD_INFO(vcd_list, vcd_info, next, show_this_item); fprintf(dump_file, "$end\n"); return 0; } static void open_dumpfile(vpiHandle callh) { if (dump_path == 0) dump_path = strdup("dump.vcd"); dump_file = fopen(dump_path, "w"); if (dump_file == 0) { vpi_printf("VCD Error: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unable to open %s for output.\n", dump_path); vpip_set_return_value(1); vpi_control(vpiFinish, 1); free(dump_path); dump_path = 0; return; } else { int prec = vpi_get(vpiTimePrecision, 0); unsigned scale = 1; unsigned udx = 0; time_t walltime; vpi_printf("VCD info: dumpfile %s opened for output.\n", dump_path); time(&walltime); assert(prec >= -15); while (prec < 0) { udx += 1; prec += 3; } while (prec > 0) { scale *= 10; prec -= 1; } if (!dump_no_date) { fprintf(dump_file, "$date\n"); fprintf(dump_file, "\t%s",asctime(localtime(&walltime))); fprintf(dump_file, "$end\n"); } fprintf(dump_file, "$version\n"); fprintf(dump_file, "\tIcarus Verilog\n"); fprintf(dump_file, "$end\n"); fprintf(dump_file, "$timescale\n"); fprintf(dump_file, "\t%u%s\n", scale, units_names[udx]); fprintf(dump_file, "$end\n"); } } static PLI_INT32 sys_dumpfile_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); char *path; /* $dumpfile must be called before $dumpvars starts! */ if (dumpvars_status != 0) { char msg[64]; snprintf(msg, sizeof(msg), "VCD warning: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; vpi_printf("%s %s called after $dumpvars started,\n", msg, name); vpi_printf("%*s using existing file (%s).\n", (int) strlen(msg), " ", dump_path); vpi_free_object(argv); return 0; } path = get_filename_with_suffix(callh, name, vpi_scan(argv), "vcd"); vpi_free_object(argv); if (! path) return 0; if (dump_path) { vpi_printf("VCD warning: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Overriding dump file %s with %s.\n", dump_path, path); free(dump_path); } dump_path = path; return 0; } static PLI_INT32 sys_dumpflush_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ if (dump_file) fflush(dump_file); return 0; } static PLI_INT32 sys_dumplimit_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; (void)name; /* Parameter is not used. */ /* Get the value and set the dump limit. */ val.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &val); dump_limit = val.value.integer; vpi_free_object(argv); return 0; } static void scan_item(unsigned depth, vpiHandle item, int skip) { struct t_cb_data cb; struct vcd_info* info; const char *type; const char *name; const char *fullname; const char *prefix; const char *ident; int nexus_id; unsigned size; PLI_INT32 item_type; /* Get the displayed type for the various $var and $scope types. */ /* Not all of these are supported now, but they should be in a * future development version. */ item_type = vpi_get(vpiType, item); switch (item_type) { case vpiNamedEvent: type = "event"; break; case vpiIntVar: case vpiIntegerVar: type = "integer"; break; /* VCD doesn't support real parameters, so lie. */ case vpiParameter: switch (vpi_get(vpiConstType, item)) { case vpiRealConst: type = "real"; break; default: type = "parameter"; break; } break; /* Icarus converts realtime to real. */ case vpiRealVar: type = "real"; break; case vpiMemoryWord: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiLongIntVar: case vpiReg: type = "reg"; break; /* Icarus converts a time to a plain register. */ case vpiTimeVar: type = "time"; break; case vpiNet: switch (vpi_get(vpiNetType, item)) { case vpiWand: type = "wand"; break; case vpiWor: type = "wor"; break; case vpiTri: type = "tri"; break; case vpiTri0: type = "tri0"; break; case vpiTri1: type = "tri1"; break; case vpiTriReg: type = "trireg"; break; case vpiTriAnd: type = "triand"; break; case vpiTriOr: type = "trior"; break; case vpiSupply1: type = "supply1"; break; case vpiSupply0: type = "supply0"; break; default: type = "wire"; break; } break; case vpiNamedBegin: type = "begin"; break; case vpiGenScope: type = "begin"; break; case vpiNamedFork: type = "fork"; break; case vpiFunction: type = "function"; break; case vpiModule: type = "module"; break; case vpiPackage: type = "package"; break; case vpiTask: type = "task"; break; default: vpi_printf("VCD warning: $dumpvars: Unsupported argument " "type (%s).\n", vpi_get_str(vpiType, item)); return; } /* Do some special processing/checking on array words. Dumping * array words is an Icarus extension. */ if (item_type == vpiMemoryWord) { /* Turn a non-constant array word select into a constant * word select. */ if (vpi_get(vpiConstantSelect, item) == 0) { vpiHandle array = vpi_handle(vpiParent, item); PLI_INT32 idx = vpi_get(vpiIndex, item); item = vpi_handle_by_index(array, idx); } /* An array word is implicitly escaped so look for an * escaped identifier that this could conflict with. */ /* This does not work as expected since we always find at * least the array word. We likely need a custom routine. */ if (vpi_get(vpiType, item) == vpiMemoryWord && vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) { vpi_printf("VCD warning: array word %s will conflict " "with an escaped identifier.\n", vpi_get_str(vpiFullName, item)); } } fullname = vpi_get_str(vpiFullName, item); /* Generate the $var or $scope commands. */ switch (item_type) { case vpiNamedEvent: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiRealVar: case vpiMemoryWord: case vpiReg: case vpiTimeVar: case vpiNet: /* If we are skipping all signal or this is in an automatic * scope then just return. */ if (skip || vpi_get(vpiAutomatic, item)) return; /* Skip this signal if it has already been included. * This can only happen for implicitly given signals. */ if (vcd_names_search(&vcd_var, fullname)) return; /* Declare the variable in the VCD file. */ name = vpi_get_str(vpiName, item); prefix = is_escaped_id(name) ? "\\" : ""; /* Some signals can have an alias so handle that. */ nexus_id = vpi_get(_vpiNexusId, item); ident = 0; if (nexus_id) ident = find_nexus_ident(nexus_id); if (!ident) { ident = strdup(vcdid); gen_new_vcd_id(); if (nexus_id) set_nexus_ident(nexus_id, ident); /* Add a callback for the signal. */ info = malloc(sizeof(*info)); info->time.type = vpiSimTime; info->item = item; info->ident = ident; info->scheduled = 0; cb.time = &info->time; cb.user_data = (char*)info; cb.value = NULL; cb.obj = item; cb.reason = cbValueChange; cb.cb_rtn = variable_cb_1; info->dmp_next = 0; info->next = vcd_list; vcd_list = info; info->cb = vpi_register_cb(&cb); } /* Named events do not have a size, but other tools use * a size of 1 and some viewers do not accept a width of * zero so we will also use a width of one for events. */ if (item_type == vpiNamedEvent) size = 1; else size = vpi_get(vpiSize, item); fprintf(dump_file, "$var %s %u %s %s%s", type, size, ident, prefix, name); /* Add a range for vectored values. */ if (size > 1 || vpi_get(vpiLeftRange, item) != 0) { fprintf(dump_file, " [%i:%i]", (int)vpi_get(vpiLeftRange, item), (int)vpi_get(vpiRightRange, item)); } fprintf(dump_file, " $end\n"); break; case vpiParameter: /* If we are skipping all pamaeters then just return. */ if (skip) return; size = vpi_get(vpiSize, item); /* Declare the parameter in the VCD file. */ name = vpi_get_str(vpiName, item); prefix = is_escaped_id(name) ? "\\" : ""; ident = strdup(vcdid); gen_new_vcd_id(); /* Make an info item to go in the vcd_const_list. */ info = malloc(sizeof(*info)); info->item = item; info->ident = ident; info->scheduled = 0; info->dmp_next = 0; info->next = vcd_const_list; vcd_const_list = info; info->cb = NULL; /* Generate the $var record. Now the parameter is declared. */ fprintf(dump_file, "$var %s %u %s %s%s $end\n", type, size, ident, prefix, name); break; case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: if (depth > 0) { /* list of types to iterate upon */ static int types[] = { /* Value */ vpiNamedEvent, vpiNet, vpiParameter, vpiReg, vpiVariables, /* Scope */ vpiFunction, vpiGenScope, vpiModule, vpiNamedBegin, vpiNamedFork, vpiTask, -1 }; int i; int nskip = (vcd_names_search(&vcd_tab, fullname) != 0); /* We have to always scan the scope because the * depth could be different for this call. */ if (nskip) { vpi_printf("VCD warning: ignoring signals in " "previously scanned scope %s.\n", fullname); } else { vcd_names_add(&vcd_tab, fullname); } name = vpi_get_str(vpiName, item); fprintf(dump_file, "$scope %s %s $end\n", type, name); for (i=0; types[i]>0; i++) { vpiHandle hand; vpiHandle argv = vpi_iterate(types[i], item); while (argv && (hand = vpi_scan(argv))) { scan_item(depth-1, hand, nskip); } } /* Sort any signals that we added above. */ fprintf(dump_file, "$upscope $end\n"); } break; case vpiPackage: vpi_printf("VCD warning: $dumpvars: Package (%s) is not dumpable " "with VCD.\n", vpi_get_str(vpiFullName, item)); break; } } static int draw_scope(vpiHandle item, vpiHandle callh) { int depth; const char *name; const char *type; vpiHandle scope = vpi_handle(vpiScope, item); if (!scope) return 0; depth = 1 + draw_scope(scope, callh); name = vpi_get_str(vpiName, scope); switch (vpi_get(vpiType, scope)) { case vpiNamedBegin: type = "begin"; break; case vpiGenScope: type = "begin"; break; case vpiTask: type = "task"; break; case vpiFunction: type = "function"; break; case vpiNamedFork: type = "fork"; break; case vpiModule: type = "module"; break; default: type = "invalid"; vpi_printf("VCD Error: %s:%d: $dumpvars: Unsupported scope " "type (%d)\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), (int)vpi_get(vpiType, item)); assert(0); } fprintf(dump_file, "$scope %s %s $end\n", type, name); return depth; } static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; s_vpi_value value; unsigned depth = 0; (void)name; /* Parameter is not used. */ if (dump_file == 0) { open_dumpfile(callh); if (dump_file == 0) { if (argv) vpi_free_object(argv); return 0; } } if (install_dumpvars_callback()) { if (argv) vpi_free_object(argv); return 0; } /* Get the depth if it exists. */ if (argv) { value.format = vpiIntVal; vpi_get_value(vpi_scan(argv), &value); depth = value.value.integer; } if (!depth) depth = 10000; /* This dumps all the instances in the design if none are given. */ if (!argv || !(item = vpi_scan(argv))) { argv = vpi_iterate(vpiInstance, 0x0); assert(argv); /* There must be at least one top level instance. */ item = vpi_scan(argv); } for ( ; item; item = vpi_scan(argv)) { char *scname; const char *fullname; int add_var = 0; int dep; PLI_INT32 item_type = vpi_get(vpiType, item); /* If this is a signal make sure it has not already * been included. */ switch (item_type) { case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNamedEvent: case vpiNet: case vpiParameter: case vpiRealVar: case vpiReg: case vpiTimeVar: /* Warn if the variables scope (which includes the * variable) or the variable itself was already * included. A scope does not automatically include * memory words so do not check the scope for them. */ scname = strdup(vpi_get_str(vpiFullName, vpi_handle(vpiScope, item))); fullname = vpi_get_str(vpiFullName, item); if (((item_type != vpiMemoryWord) && vcd_names_search(&vcd_tab, scname)) || vcd_names_search(&vcd_var, fullname)) { vpi_printf("VCD warning: skipping signal %s, " "it was previously included.\n", fullname); free(scname); continue; } else { add_var = 1; } free(scname); } dep = draw_scope(item, callh); scan_item(depth, item, 0); /* The scope list must be sorted after we scan an item. */ vcd_names_sort(&vcd_tab); while (dep--) fprintf(dump_file, "$upscope $end\n"); /* Add this signal to the variable list so we can verify it * is not included twice. This must be done after it has * been added */ if (add_var) { vcd_names_add(&vcd_var, vpi_get_str(vpiFullName, item)); vcd_names_sort(&vcd_var); } } return 0; } void sys_vcd_register(void) { s_vpi_systf_data tf_data; vpiHandle res; int idx; struct t_vpi_vlog_info vlog_info; /* Scan the extended arguments */ vpi_get_vlog_info(&vlog_info); for (idx = 0 ; idx < vlog_info.argc ; idx += 1) { if (strcmp(vlog_info.argv[idx],"-no-date") == 0) { dump_no_date = 1; } } /* All the compiletf routines are located in vcd_priv.c. */ tf_data.type = vpiSysTask; tf_data.tfname = "$dumpall"; tf_data.calltf = sys_dumpall_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpfile"; tf_data.calltf = sys_dumpfile_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpfile"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpflush"; tf_data.calltf = sys_dumpflush_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumplimit"; tf_data.calltf = sys_dumplimit_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumplimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpoff"; tf_data.calltf = sys_dumpoff_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpon"; tf_data.calltf = sys_dumpon_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpon"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/sys_vcdoff.c000066400000000000000000000075321435245347300164650ustar00rootroot00000000000000/* * Copyright (c) 2003-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 "sys_priv.h" /* * This file contains do nothing stubs of all the VCD routines. */ # include # include # include # include # include # include "vcd_priv.h" static int dump_flag = 0; static PLI_INT32 sys_dummy_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ return 0; } static PLI_INT32 sys_dumpvars_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ if (dump_flag == 0) { vpi_printf("VCD info: dumping is suppressed.\n"); dump_flag = 1; } return 0; } void sys_vcdoff_register(void) { s_vpi_systf_data tf_data; vpiHandle res; /* All the compiletf routines are located in vcd_priv.c. */ tf_data.type = vpiSysTask; tf_data.tfname = "$dumpall"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpall"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpfile"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_one_string_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpfile"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpflush"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpflush"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumplimit"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumplimit"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpoff"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpoff"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpon"; tf_data.calltf = sys_dummy_calltf; tf_data.compiletf = sys_no_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpon"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$dumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$dumpvars"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/table_mod.c000066400000000000000000000544631435245347300162530ustar00rootroot00000000000000/* * Copyright (C) 2011-2021 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. */ #include "sys_priv.h" #include #include #include #include #include #include #include "table_mod.h" #include "ivl_alloc.h" /* * Flag used to enable/disable debug output. */ static unsigned table_model_debug = 0; static p_table_mod *tables = 0; static unsigned table_count = 0; /* * Routine to cleanup the table model data at the end of simulation. */ static PLI_INT32 cleanup_table_mod(p_cb_data cause) { unsigned idx; (void)cause; /* Parameter is not used. */ for (idx = 0; idx < table_count; idx += 1) { free(tables[idx]->indep); free(tables[idx]->indep_val); if (tables[idx]->have_fname) free(tables[idx]->file.name); if (tables[idx]->have_ctl) { free(tables[idx]->control.info.interp); free(tables[idx]->control.info.extrap_low); free(tables[idx]->control.info.extrap_high); } free(tables[idx]); } free(tables); tables = 0; table_count = 0; return 0; } /* * Create an empty table model object and add it to the list of table * model objects. */ static p_table_mod create_table(void) { /* Create an empty table model object. */ p_table_mod obj = (p_table_mod) malloc(sizeof(s_table_mod)); assert(obj); /* Add it to the list of tables. */ table_count += 1; tables = (p_table_mod *) realloc(tables, sizeof(p_table_mod)*table_count); tables[table_count-1] = obj; /* Initialize and return the table object. */ obj->indep = 0; obj->indep_val = 0; obj->have_fname = 0; obj->have_ctl = 0; obj->control.arg = 0; obj->depend = 0; obj->dims = 0; obj->fields = 0; return obj; } /* * Check to see if this is a constant string. It returns 1 if the argument * is a constant string otherwise it returns 0. */ static unsigned is_const_string_obj(vpiHandle arg) { unsigned rtn = 0; assert(arg); switch (vpi_get(vpiType, arg)) { case vpiConstant: case vpiParameter: /* This must be a constant string. */ if (vpi_get(vpiConstType, arg) == vpiStringConst) rtn = 1; } return rtn; } /* * Get any command line flags. For now we only have a debug flag. */ static void check_command_line_flags(void) { struct t_vpi_vlog_info vlog_info; static unsigned command_line_processed = 0; /* If we have already processed the arguments then just return. */ if (command_line_processed) return; vpi_get_vlog_info(&vlog_info); for (int idx = 0; idx < vlog_info.argc; idx += 1) { if (strcmp(vlog_info.argv[idx], "-table-model-debug") == 0) { table_model_debug = 1; } } command_line_processed = 1; } /* * Check that the given $table_model() call has valid arguments. */ static PLI_INT32 sys_table_model_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; p_table_mod table = create_table(); /* See if there are any table model arguments. */ check_command_line_flags(); /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires at least two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first N (dimensions) arguments must be numeric. */ for (arg = vpi_scan(argv); arg && is_numeric_obj(arg); arg = vpi_scan(argv)) { table->dims += 1; table->indep = (vpiHandle *)realloc(table->indep, sizeof(vpiHandle)*table->dims); table->indep[table->dims-1] = arg; } /* We must have a data file. */ if (arg == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a file name argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* For now we only allow a constant string (file name). */ if (! is_const_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s file name argument must be a constant string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } table->file.arg = arg; /* There may be an optional constant string (control string). */ arg = vpi_scan(argv); if (arg) { if (! is_const_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s control string argument must be a constant " "string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } check_for_extra_args(argv, callh, name, "N numeric and 1 or 2 " " constant string arguments", 0); table->control.arg = arg; } /* Save the table data information. */ vpi_put_userdata(callh, table); return 0; } /* * Initialize the control string fields with the default value. */ static void initialize_control_fields_def(p_table_mod table) { char *val; unsigned width = table->dims; /* Set the default interpolation for each dimension. */ val = (char *) malloc(width); assert(val); table->control.info.interp = memset(val, IVL_LINEAR_INTERP, width); /* Set the default low extrapolation for each dimension. */ val = (char *) malloc(width); assert(val); table->control.info.extrap_low = memset(val, IVL_LINEAR_EXTRAP, width); /* Set the default low extrapolation for each dimension. */ val = (char *) malloc(width); assert(val); table->control.info.extrap_high = memset(val, IVL_LINEAR_EXTRAP, width); /* By default the dependent data column is the first one after the * independent data column(s). */ table->depend = 1; /* Set the number of control fields. */ table->fields = width; /* We have defined the interpolation/extrapolation fields. */ table->have_ctl = 1; } /* * Parse the extrapolation control codes. */ static unsigned parse_extrap(vpiHandle callh, p_table_mod table, unsigned idx, char **extrap, char *control) { /* Advance to the first extrapolation code. */ *extrap += 1; /* By default both the low and high extrapolation is set by the * first extrapolation character. We'll override the high value * later if there is a second character. */ switch (**extrap) { /* Clamp (no) extrapolation. */ case 'C': table->control.info.extrap_low[idx] = IVL_CONSTANT_EXTRAP; table->control.info.extrap_high[idx] = IVL_CONSTANT_EXTRAP; break; /* Linear extrapolation. */ case 'L': table->control.info.extrap_low[idx] = IVL_LINEAR_EXTRAP; table->control.info.extrap_high[idx] = IVL_LINEAR_EXTRAP; break; /* Error on extrapolation. */ case 'E': table->control.info.extrap_low[idx] = IVL_ERROR_EXTRAP; table->control.info.extrap_high[idx] = IVL_ERROR_EXTRAP; break; /* There are no extrapolation characters so use the default * (linear extrapolation). */ case 0: case ',': table->control.info.extrap_low[idx] = IVL_LINEAR_EXTRAP; table->control.info.extrap_high[idx] = IVL_LINEAR_EXTRAP; return 0; /* Anything else is an error. */ default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unknown extrapolation code '%c' for dimension " "%u: %s\n", **extrap, idx+1, control); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Advance to the next (high) extrapolation code. */ *extrap += 1; /* Override the high extrapolation value if needed. */ switch (**extrap) { /* Clamp (no) extrapolation. */ case 'C': table->control.info.extrap_high[idx] = IVL_CONSTANT_EXTRAP; break; /* Linear extrapolation. */ case 'L': table->control.info.extrap_high[idx] = IVL_LINEAR_EXTRAP; break; /* Error on extrapolation. */ case 'E': table->control.info.extrap_high[idx] = IVL_ERROR_EXTRAP; break; /* There is no high extrapolation character so just return. */ case 0: case ',': return 0; /* Anything else is an error. */ default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unknown high extrapolation code '%c' for dimension " "%u: %s\n", **extrap, idx+1, control); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Advance to the next field. */ *extrap += 1; return 0; } /* * Load the control string fields for the given string. Return 0 if there * is a problem parsing the control string. */ static unsigned initialize_control_fields(vpiHandle callh, p_table_mod table, char *control) { unsigned num_fields, num_ignore, idx; char *cp; /* If we need to fail these must be defined to zero until memory * has actually been allocated. */ table->control.info.interp = 0; table->control.info.extrap_low = 0; table->control.info.extrap_high = 0; /* We have defined the interpolation/extrapolation fields. */ table->have_ctl = 1; /* Look for the dependent data field. */ cp = strchr(control, ';'); if (cp) { size_t len; unsigned long val; char *end; /* NULL terminate the independent part of the string. */ *cp = 0; cp += 1; len = strlen(cp); /* If the length is zero or not all digits then the string * is invalid. */ // HERE: Do we need to support/ignore an underscore? What about in the file? if ((! len) || (len != strspn(cp, "0123456789"))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Control string dependent selector is " "invalid: %s.\n", cp); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } val = strtoul(cp, &end, 10); assert(*end == 0); /* If the value is too big also report an error. */ if (val > UINT_MAX) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Control string dependent value is " "to large: %lu.\n", val); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } table->depend = (unsigned) val; } else table->depend = 1; /* Find the number of interpolation/extrapolation control fields. */ num_fields = 1; cp = control; while ((cp = strchr(cp, ','))) { cp += 1; num_fields += 1; } /* We must have at least as many control fields as dimensions. */ if (num_fields < table->dims) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Not enough control field(s) (%u) for the dimension(s) " "(%u).", num_fields, table->dims); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Allocate space for the interpolation/extrapolation values. */ table->control.info.interp = (char *) malloc(num_fields); assert(table->control.info.interp); table->control.info.extrap_low = (char *) malloc(num_fields); assert(table->control.info.extrap_low); table->control.info.extrap_high = (char *) malloc(num_fields); assert(table->control.info.extrap_high); /* Parse the individual dimension control string. */ num_ignore = 0; cp = control; for (idx = 0; idx < num_fields; idx += 1) { switch (*cp) { /* Closest point interpolation. */ case 'D': table->control.info.interp[idx] = IVL_CLOSEST_POINT; if (parse_extrap(callh, table, idx, &cp, control)) return 0; break; /* Linear interpolation. */ case '1': table->control.info.interp[idx] = IVL_LINEAR_INTERP; if (parse_extrap(callh, table, idx, &cp, control)) return 0; break; /* Quadratic interpolation. */ case '2': table->control.info.interp[idx] = IVL_QUADRATIC_INTERP; if (parse_extrap(callh, table, idx, &cp, control)) return 0; break; /* Cubic interpolation. */ case '3': table->control.info.interp[idx] = IVL_CUBIC_INTERP; if (parse_extrap(callh, table, idx, &cp, control)) return 0; break; /* Ignore column. No extrapolation codes are allowed. */ case 'I': table->control.info.interp[idx] = IVL_IGNORE_COLUMN; table->control.info.extrap_low[idx] = IVL_ERROR_EXTRAP; table->control.info.extrap_high[idx] = IVL_ERROR_EXTRAP; cp += 1; num_ignore += 1; break; /* This field is not specified so use the default values. * Linear interpolation and extrapolation. */ case 0: assert(idx == num_fields-1); case ',': table->control.info.interp[idx] = IVL_LINEAR_INTERP; table->control.info.extrap_low[idx] = IVL_LINEAR_EXTRAP; table->control.info.extrap_high[idx] = IVL_LINEAR_EXTRAP; break; /* Anything else is an error. */ default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unknown interpolation code '%c' for dimension " "%u: %s\n", *cp, idx+1, control); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Verify that there is no extra junk at the end of the field. */ if (*cp && (*cp != ',')) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Extra control characters found for dimension " "%u: %s\n", idx+1, control); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Advance to the next field if we are not at the end of the * control string. */ if (*cp == ',') cp += 1; } /* We must have a usable control field for each dimensions. */ if ((num_fields - num_ignore) != table->dims) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Usable control field(s) (%u) do not match dimension(s) " "(%u).", (num_fields - num_ignore), table->dims); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 1; } /* Set the number of control fields. */ table->fields = num_fields; return 0; } /* * Print out the interpolation code. */ static void dump_interp(char interp) { switch (interp) { case IVL_CLOSEST_POINT: fprintf(stderr, "D"); break; case IVL_LINEAR_INTERP: fprintf(stderr, "1"); break; case IVL_QUADRATIC_INTERP: fprintf(stderr, "2"); break; case IVL_CUBIC_INTERP: fprintf(stderr, "3"); break; case IVL_IGNORE_COLUMN: fprintf(stderr, "I"); break; default: fprintf(stderr, "<%d>", interp); break; } } /* * Print out the extrapolation code. */ static void dump_extrap(char extrap) { switch (extrap) { case IVL_CONSTANT_EXTRAP: fprintf(stderr, "C"); break; case IVL_LINEAR_EXTRAP: fprintf(stderr, "L"); break; case IVL_ERROR_EXTRAP: fprintf(stderr, "E"); break; default: fprintf(stderr, "<%d>", extrap); break; } } /* * Print some diagnostic information about the $table_model() call. */ static void dump_diag_info(vpiHandle callh, p_table_mod table) { unsigned idx; char msg[64]; snprintf(msg, sizeof(msg), "DEBUG: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; fprintf(stderr, "%s Building %u variable table using \"%s\" and\n", msg, table->dims, table->file.name); fprintf(stderr, "%*s the following control string: ", (int) strlen(msg), " "); dump_interp(table->control.info.interp[0]); dump_extrap(table->control.info.extrap_low[0]); dump_extrap(table->control.info.extrap_high[0]); for (idx = 1; idx < table->fields; idx += 1) { fprintf(stderr, ","); dump_interp(table->control.info.interp[idx]); dump_extrap(table->control.info.extrap_low[idx]); dump_extrap(table->control.info.extrap_high[idx]); } fprintf(stderr, ";%u\n", table->depend); fprintf(stderr, "%*s The data file must have at least %u columns.\n", (int) strlen(msg), " ", table->fields+table->depend); } /* * Initialize the table model data structure. * * The first time $table_model() is called we need to evaluate the file name * and control strings. Then we must load the data from the file. */ static unsigned initialize_table_model(vpiHandle callh, const char *name, p_table_mod table) { s_vpi_value val; FILE *fp; /* Get the table file name. */ table->file.name = get_filename(callh, name, table->file.arg); table->have_fname = 1; if (table->file.name == 0) return 1; /* Open the file. */ fp = fopen(table->file.name, "r"); if (fp == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() cannot open file \"%s\" for reading (%s).\n", name, table->file.name, strerror(errno)); return 1; } /* Check to see if there is a control string. */ if (table->control.arg) { val.format = vpiStringVal; vpi_get_value(table->control.arg, &val); if (*(val.value.str) == 0) { /* If there is an empty control string field then we just * use the default values for interpolation/extrapolation. * We also assume that there only dimensions + 1 fields. */ initialize_control_fields_def(table); } else { if (initialize_control_fields(callh, table, val.value.str)) { return 1; } } } else { /* If there is no control string field then we just use the * default values for interpolation/extrapolation. We also * assume that there only dimensions + 1 fields. */ initialize_control_fields_def(table); } /* If requested dump some diagnostic information. */ if (table_model_debug) dump_diag_info(callh, table); /* Parse the given file and produce the basic data structure. We * need to have columns for each control string field and for the * dependent data. */ if (parse_table_model(fp, callh, table)) return 1; // HERE: once we are done with the control string should we build a table // of function pointer for the interp/extrap? /* Close the file now that we have loaded all the data. */ if (fclose(fp)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s() cannot close file \"%s\" (%s).\n", name, table->file.name, strerror(errno)); return 1; } /* Allocate space for the current argument values. */ table->indep_val = (double*) malloc(sizeof(double)*table->dims); assert(table->indep_val); return 0; } /* * Routine to evaluate the table model using the current input values. */ static double eval_table_model(vpiHandle callh, p_table_mod table) { unsigned idx; (void)callh; /* Parameter is not used. */ fprintf(stderr, "Evaluating table \"%s\" with %u variables\n", table->file.name, table->dims); for (idx = 0; idx < table->dims; idx += 1) { fprintf(stderr, " Arg %u: %#g\n", idx, table->indep_val[idx]); } return 0.0; } /* * Runtime routine for the $table_model(). */ static PLI_INT32 sys_table_model_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); s_vpi_value val; p_table_mod table; unsigned idx; double result; /* Retrieve the table data. */ table = vpi_get_userdata(callh); /* If this is the first call then build the data structure. */ if ((table->have_fname == 0) && initialize_table_model(callh, name, table)) { vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Load the current argument values into the table structure. */ for (idx = 0; idx < table->dims; idx += 1) { val.format = vpiRealVal; vpi_get_value(table->indep[idx], &val); table->indep_val[idx] = val.value.real; } /* Interpolate/extrapolate the data structure to find the value. */ result = eval_table_model(callh, table); /* Return the calculated value. */ val.format = vpiRealVal; val.value.real = result; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Routine to register the system function provided in this file. */ void table_model_register(void) { s_vpi_systf_data tf_data; s_cb_data cb; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSysFuncReal; tf_data.tfname = "$table_model"; tf_data.calltf = sys_table_model_calltf; tf_data.compiletf = sys_table_model_compiletf; tf_data.sizetf = 0; /* Not needed for a vpiSysFuncReal. */ tf_data.user_data = "$table_model"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Create a callback to clear all the table model memory when the * simulator finishes. */ cb.time = NULL; cb.reason = cbEndOfSimulation; cb.cb_rtn = cleanup_table_mod; cb.user_data = 0x0; cb.obj = 0x0; vpi_register_cb(&cb); } iverilog-12_0/vpi/table_mod.h000066400000000000000000000062621435245347300162520ustar00rootroot00000000000000#ifndef IVL_table_mod_H #define IVL_table_mod_H /* * Copyright (C) 2011-2014 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. */ #include #include /* * Define the allowed interpolation control values. */ #define IVL_CLOSEST_POINT 0 /* D */ #define IVL_LINEAR_INTERP 1 /* 1 - Default */ #define IVL_QUADRATIC_INTERP 2 /* 2 */ #define IVL_CUBIC_INTERP 3 /* 3 */ #define IVL_IGNORE_COLUMN 4 /* I */ /* * Define the allowed extrapolation control values. */ #define IVL_CONSTANT_EXTRAP 0 /* C */ #define IVL_LINEAR_EXTRAP 1 /* L - Default */ #define IVL_ERROR_EXTRAP 2 /* E */ /* * Structure that represents an individual iso line element. */ typedef struct t_indep { double value; struct t_indep *left; /* previous element. */ struct t_indep *right; /* next element. */ union { double data; struct t_indep *child; struct t_build *build; } data; } s_indep, *p_indep; /* * This is used as an interface element while building the iso lines. It will * be removed when the list is converted to a balanced threaded tree. It is * used to make in order insertion faster. */ typedef struct t_build { p_indep first; p_indep last; unsigned count; } s_build, *p_build; /* * This structure is saved for each table model instance. */ typedef struct t_table_mod { vpiHandle *indep; /* Independent variable arguments. */ double *indep_val; /* Current independent variable values. */ union { /* Data file or argument to get the data file. */ char *name; vpiHandle arg; } file; union { /* Control string argument. */ struct { char *interp; char *extrap_low; char *extrap_high; } info; vpiHandle arg; } control; // HERE need a pointer to the dependent data and the final table. unsigned dims; /* The number of independent variables. */ unsigned fields; /* The number of control fields. */ unsigned depend; /* Where the dependent column is located. */ char have_fname; /* Has the file name been allocated? */ char have_ctl; /* Has the file name been allocated? */ } s_table_mod, *p_table_mod; /* * Define the non-static table model routines. */ extern unsigned parse_table_model(FILE *fp, vpiHandle callh, p_table_mod table); extern int tblmodlex(void); extern void destroy_tblmod_lexor(void); extern void init_tblmod_lexor(FILE *fp); #endif /* IVL_table_mod_H */ iverilog-12_0/vpi/table_mod_lexor.lex000066400000000000000000000075501435245347300200250ustar00rootroot00000000000000%option prefix="tblmod" %option never-interactive %option noinput %option nounput %option noyywrap %{ /* * Copyright (C) 2011-2017 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. */ #include #include #include #include #include "table_mod.h" #include "table_mod_parse.h" #include "ivl_alloc.h" static double get_scaled_real(const char *text); static double get_real(const char *text); #define yylval tblmodlval %} SPACE [ \t] EOL [\r\n]+ SCALE [afpnumkKMGT] %% /* Skip comment lines. */ "#".*{EOL} { tblmodlloc.first_line += 1; } /* Skip white space. */ {SPACE} { ; } {EOL} { tblmodlloc.first_line += 1; return END_LINE; } /* Recognize a real value with a Verilog-AMS scale. */ [+-]?[0-9][0-9_]*(\.[0-9][0-9_]*)?{SCALE} { yylval.real = get_scaled_real(yytext); return REAL; } /* Recognize and other numeric value. */ [+-]?[0-9][0-9_]*(\.[0-9][0-9_]*)?([eE][+-]?[0-9][0-9_]*)? { yylval.real = get_real(yytext); return REAL; } %% /* * Convert a Verilog-AMS scaled real number to a real value. */ double get_scaled_real(const char *text) { double result; size_t len = strlen(text); char *buf = malloc(len + 5); const char *scale; /* Copy the number to the buffer. */ strcpy(buf, text); /* Convert the scale character to exponential form. */ switch (text[len-1]) { case 'a': scale = "e-18"; break; /* atto */ case 'f': scale = "e-15"; break; /* femto */ case 'p': scale = "e-12"; break; /* pico */ case 'n': scale = "e-9"; break; /* nano */ case 'u': scale = "e-6"; break; /* micro */ case 'm': scale = "e-3"; break; /* milli */ case 'k': case 'K': scale = "e3"; break; /* kilo */ case 'M': scale = "e6"; break; /* mega */ case 'G': scale = "e9"; break; /* giga */ case 'T': scale = "e12"; break; /* tera */ default: scale = ""; assert(0); break; } buf[len-1] = 0; strcat(buf, scale); /* Convert the exponential string to a real value, */ result = get_real(buf); free(buf); return result; } /* * Convert a normal number to a real value. */ double get_real(const char *text) { double result; char *buf = malloc(strlen(text) + 1); char *cptr = buf; char *end; unsigned idx; /* We must have a buffer to remove any '_' characters. */ assert(buf); /* Remove any '_' characters from the string. */ for (idx = 0; text[idx]; idx += 1) { if (text[idx] == '_') continue; *cptr = text[idx]; cptr += 1; } *cptr = 0; /* Convert the buffer to a double value and check that the * conversion was done successfully. */ result = strtod(buf, &end); assert(*end == 0); free(buf); return result; } void init_tblmod_lexor(FILE *fp) { yyrestart(fp); } /* * Modern version of flex (>=2.5.9) can clean up the scanner data. */ void destroy_tblmod_lexor(void) { # ifdef FLEX_SCANNER # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 yylex_destroy(); # endif # endif # endif } iverilog-12_0/vpi/table_mod_parse.y000066400000000000000000000140031435245347300174550ustar00rootroot00000000000000 %{ /* * Copyright (C) 2011-2015 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. */ #include #include #include #include "table_mod.h" #include "ivl_alloc.h" /* * The number of parse errors encountered while parsing the data file. */ static unsigned errors = 0; /* * The minimum number of columns needed in the data file to satisfy the * control string/input variable requirements. */ static unsigned minimum_columns; /* * The number of independent values we expect to keep based on the control * string/independent variables. */ static unsigned indep_values; /* * The total number of independent columns to expect. This includes any * ignored columns. */ static unsigned indep_columns; /* * The zero based dependent column location. This is just minimum_columns - 1. */ static unsigned dep_column; /* * The number of columns to expect in this data file. This must be * greater than or equal to the minimum_columns above. */ static unsigned number_of_columns = 0; /* * The number of columns that this point currently has. */ static unsigned cur_columns; /* * The zero based current independent value we are looking for. */ static unsigned cur_value; /* * The usable values for this point. The independent values are first and * the dependent value is the last entry. */ static double *values; /* * The name of the file we are getting data from. */ static const char *in_file_name; /* * The table structure that we are getting data for. */ static p_table_mod table_def; /* * The lexor and error routines. */ extern int tblmodlex(void); static void yyerror(const char *fmt, ...); static void process_point(void) { assert(cur_value == indep_values); #if 0 unsigned idx; fprintf(stderr, "%#g", values[0]); for (idx = 1; idx < indep_values; idx += 1) { fprintf(stderr, ", %#g", values[idx]); } fprintf(stderr, " => %#g\n", values[indep_values]); #endif } %} %locations %union { double real; }; %token END_LINE %token REAL %% /* * A table is just a bunch of points. The lexor ignores any comments. */ table : point | table point ; /* * An individual point is just a bunch of columns followed by one or more * end of line characters. */ point : columns END_LINE { /* * If the number of columns has been defined then we must have * enough columns and we expect every line to have the same * number of columns. */ if (number_of_columns) { if (cur_columns < minimum_columns) { yyerror("Found %u columns, need at least %u.", cur_columns, minimum_columns); } else if (cur_columns != number_of_columns) { yyerror("Found %u columns, expected %u.", cur_columns, number_of_columns); } else process_point(); /* * If this is the first point then we must have enough columns. * If there are enough then we define this to be the number of * columns that the file must have. */ } else { if (cur_columns < minimum_columns) { yyerror("Found %u columns, need at least %u.", cur_columns, minimum_columns); } else { number_of_columns = cur_columns; process_point(); } } } ; /* * Each column is a real value. We only save the columns we care about. */ columns : REAL { if (table_def->control.info.interp[0] != IVL_IGNORE_COLUMN) { values[0] = $1; cur_value = 1; } else cur_value = 0; cur_columns = 1; } | columns REAL { if (cur_columns < indep_columns) { if (table_def->control.info.interp[cur_columns] != IVL_IGNORE_COLUMN) { values[cur_value] = $2; cur_value += 1; } } else if (cur_columns == dep_column) values[indep_values] = $2; cur_columns += 1; } ; %% /* * Setup the various variables, then parse the input file and then cleanup * the lexor and the allocated memory. */ unsigned parse_table_model(FILE *fp, vpiHandle callh, p_table_mod table) { unsigned rtn = 0; assert(table); assert(table->fields > 0); assert(table->depend > 0); /* Initialize the variables used by the parser. */ table_def = table; indep_values = table->dims; indep_columns = table->fields; minimum_columns = table->fields + table->depend; dep_column = minimum_columns - 1; values = malloc(sizeof(double)*(indep_values+1)); assert(values); in_file_name = table->file.name; /* Parse the input file. */ init_tblmod_lexor(fp); /* If there are errors then print a message. */ if (yyparse()) errors += 1; if (errors) { vpi_printf("ERROR: %s:%u: ", vpi_get_str(vpiFile, callh), (int) vpi_get(vpiLineNo, callh)); vpi_printf("Had %u error(s) while reading table file.\n", errors); rtn = 1; } /* Cleanup the lexor and allocated memory. */ destroy_tblmod_lexor(); free(values); return rtn; } /* * Currently every parse error is reported after the newline so subtract * one from the line count. */ void yyerror(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s:%d: TABLE ERROR: ", in_file_name, yylloc.first_line-1); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); errors += 1; } iverilog-12_0/vpi/v2005_math.c000066400000000000000000000242621435245347300161040ustar00rootroot00000000000000/* * Verilog-2005 math library for Icarus Verilog * http://www.icarus.com/eda/verilog/ * * Copyright (C) 2007-2021 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. */ #include "vpi_config.h" #include #include #include #include #include "vpi_user.h" #include "ivl_alloc.h" /* Single argument functions. */ typedef struct s_single_data { const char *name; double (*func)(double); } t_single_data; static t_single_data va_single_data[]= { {"$sqrt", sqrt}, {"$ln", log}, {"$log10", log10}, {"$exp", exp}, {"$ceil", ceil}, {"$floor", floor}, {"$sin", sin}, {"$cos", cos}, {"$tan", tan}, {"$asin", asin}, {"$acos", acos}, {"$atan", atan}, {"$sinh", sinh}, {"$cosh", cosh}, {"$tanh", tanh}, {"$asinh", asinh}, {"$acosh", acosh}, {"$atanh", atanh}, {0, 0} /* Must be NULL terminated! */ }; /* Double argument functions. */ typedef struct s_double_data { const char *name; double (*func)(double, double); } t_double_data; static t_double_data va_double_data[]= { {"$pow", pow}, {"$atan2", atan2}, {"$hypot", hypot}, {0, 0} /* Must be NULL terminated! */ }; /* * This structure holds the single argument information. */ typedef struct { vpiHandle arg; double (*func)(double); } va_single_t; /* * This structure holds the double argument information. */ typedef struct { vpiHandle arg1; vpiHandle arg2; double (*func)(double, double); } va_double_t; /* * Cleanup the allocated memory at the end of simulation. */ static va_single_t** single_funcs = 0; static unsigned single_funcs_count = 0; static va_double_t** double_funcs = 0; static unsigned double_funcs_count = 0; static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) { unsigned idx; (void)cb_data; /* Parameter is not used. */ for (idx = 0; idx < single_funcs_count; idx += 1) { free(single_funcs[idx]); } free(single_funcs); single_funcs = 0; single_funcs_count = 0; for (idx = 0; idx < double_funcs_count; idx += 1) { free(double_funcs[idx]); } free(double_funcs); double_funcs = 0; double_funcs_count = 0; return 0; } /* * Standard error message routine. The format string must take one * string argument (the name of the function). */ static void va_error_message(vpiHandle callh, const char *format, const char *name) { vpi_printf("%s:%d: error: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf(format, name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* * Process an argument. */ static vpiHandle va_process_argument(vpiHandle callh, const char *name, vpiHandle arg, const char *post) { PLI_INT32 type; if (arg == NULL) return 0; type = vpi_get(vpiType, arg); /* Math function cannot do anything with a string. */ if ((type == vpiConstant || type == vpiParameter) && (vpi_get(vpiConstType, arg) == vpiStringConst)) { const char* basemsg = "%s cannot process strings"; char* msg = malloc(strlen(basemsg)+strlen(post)+3); strcpy(msg, basemsg); strcat(msg, post); strcat(msg, ".\n"); va_error_message(callh, msg, name); free(msg); return 0; } return arg; } /* * Routine to check all the single argument math functions. */ static PLI_INT32 va_single_argument_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh, argv, arg; const t_single_data *data; const char *name; va_single_t* fun_data; assert(ud != 0); callh = vpi_handle(vpiSysTfCall, 0); assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); data = (const t_single_data *) ud; name = data->name; fun_data = malloc(sizeof(va_single_t)); /* Check that there are arguments. */ if (argv == 0) { va_error_message(callh, "%s requires one argument.\n", name); free(fun_data); return 0; } /* In Icarus if we have an argv we have at least one argument. */ arg = vpi_scan(argv); fun_data->arg = va_process_argument(callh, name, arg, ""); /* These functions only take one argument. */ arg = vpi_scan(argv); if (arg != 0) { va_error_message(callh, "%s takes only one argument.\n", name); vpi_free_object(argv); } /* Get the function that is to be used by the calltf routine. */ fun_data->func = data->func; vpi_put_userdata(callh, fun_data); single_funcs_count += 1; single_funcs = (va_single_t **)realloc(single_funcs, single_funcs_count*sizeof(va_single_t **)); single_funcs[single_funcs_count-1] = fun_data; /* vpi_scan() returning 0 (NULL) has already freed argv. */ return 0; } /* * Routine to implement the single argument math functions. */ static PLI_INT32 va_single_argument_calltf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); s_vpi_value val; va_single_t* fun_data; (void)ud; /* Parameter is not used. */ /* Retrieve the function and argument data. */ fun_data = vpi_get_userdata(callh); /* Calculate the result */ val.format = vpiRealVal; vpi_get_value(fun_data->arg, &val); val.value.real = (fun_data->func)(val.value.real); /* Return the result */ vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Routine to check all the double argument math functions. */ static PLI_INT32 va_double_argument_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh, argv, arg; const t_double_data *data; const char *name; va_double_t* fun_data; assert(ud != 0); callh = vpi_handle(vpiSysTfCall, 0); assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); data = (const t_double_data *) ud; name = data->name; fun_data = malloc(sizeof(va_double_t)); /* Check that there are arguments. */ if (argv == 0) { va_error_message(callh, "%s requires two arguments.\n", name); free(fun_data); return 0; } /* In Icarus if we have an argv we have at least one argument. */ arg = vpi_scan(argv); fun_data->arg1 = va_process_argument(callh, name, arg, " (arg1)"); /* Check that there are at least two arguments. */ arg = vpi_scan(argv); if (arg == 0) { va_error_message(callh, "%s requires two arguments.\n", name); } fun_data->arg2 = va_process_argument(callh, name, arg, " (arg2)"); /* These functions only take two arguments. */ arg = vpi_scan(argv); if (arg != 0) { va_error_message(callh, "%s takes only two arguments.\n", name); vpi_free_object(argv); } /* Get the function that is to be used by the calltf routine. */ fun_data->func = data->func; vpi_put_userdata(callh, fun_data); double_funcs_count += 1; double_funcs = (va_double_t **)realloc(double_funcs, double_funcs_count*sizeof(va_double_t **)); double_funcs[double_funcs_count-1] = fun_data; /* vpi_scan() returning 0 (NULL) has already freed argv. */ return 0; } /* * Routine to implement the double argument math functions. */ static PLI_INT32 va_double_argument_calltf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); s_vpi_value val; double first_arg; va_double_t* fun_data; (void)ud; /* Parameter is not used. */ /* Retrieve the function and argument data. */ fun_data = vpi_get_userdata(callh); /* Calculate the result */ val.format = vpiRealVal; vpi_get_value(fun_data->arg1, &val); first_arg = val.value.real; vpi_get_value(fun_data->arg2, &val); val.value.real = (fun_data->func)(first_arg, val.value.real); /* Return the result */ vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Register all the functions with Verilog. */ static void sys_v2005_math_register(void) { s_cb_data cb_data; s_vpi_systf_data tf_data; vpiHandle res; unsigned idx; /* Register the single argument functions. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = va_single_argument_calltf; tf_data.compiletf = va_single_argument_compiletf; tf_data.sizetf = 0; for (idx=0; va_single_data[idx].name != 0; idx++) { tf_data.tfname = va_single_data[idx].name; tf_data.user_data = (PLI_BYTE8 *) &va_single_data[idx]; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } /* Register the double argument functions. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = va_double_argument_calltf; tf_data.compiletf = va_double_argument_compiletf; tf_data.sizetf = 0; for (idx=0; va_double_data[idx].name != 0; idx++) { tf_data.tfname = va_double_data[idx].name; tf_data.user_data = (PLI_BYTE8 *) &va_double_data[idx]; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } /* We need to clean up the userdata. */ cb_data.reason = cbEndOfSimulation; cb_data.time = 0; cb_data.cb_rtn = sys_end_of_simulation; cb_data.user_data = "system"; vpi_register_cb(&cb_data); } /* * Hook to get Icarus Verilog to find the registration function. */ extern void sys_clog2_register(void); void (*vlog_startup_routines[])(void) = { sys_v2005_math_register, sys_clog2_register, 0 }; iverilog-12_0/vpi/v2009_array.c000066400000000000000000000224751435245347300163010ustar00rootroot00000000000000/* * Copyright (C) 2013-2021 Cary R. (cygcary@yahoo.com) * Copyright (C) 2014 Stephen Williams (steve@icarus.com) * Copyright (C) 2014 CERN * @author Maciej Suminski (maciej.suminski@cern.ch) * * 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. */ # include "sys_priv.h" # include static PLI_INT32 one_array_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; argv = vpi_iterate(vpiArgument, callh); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires an array argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (arg == 0) return 0; arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s has too many arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } return 0; } // Checks if a function is passed an array and optionally an integer. static PLI_INT32 array_int_opt_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { #if defined(__GNUC__) const int MAX_ARGC = 3; // one more is to verify there are at most 2 args #else #define MAX_ARGC 3 #endif vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, arg[MAX_ARGC]; PLI_INT32 arg_type[MAX_ARGC]; int argc; argv = vpi_iterate(vpiArgument, callh); argc = 0; if(argv) { for(int i = 0; i < MAX_ARGC; ++i) { arg[i] = vpi_scan(argv); if(arg[i]) { arg_type[i] = vpi_get(vpiType, arg[i]); ++argc; } else { break; } } } if (!argv || argc == MAX_ARGC || (arg_type[0] != vpiRegArray && arg_type[0] != vpiStringVar) || (argc == 2 && arg_type[1] != vpiIntegerVar && !(arg_type[1] == vpiConstant && vpi_get(vpiConstType, arg[1]) == vpiBinaryConst))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s expects an array and optionally an integer.\n", name); if(argc == MAX_ARGC) vpi_free_object(argv); vpip_set_return_value(1); vpi_control(vpiFinish, 0); return 0; } return 0; } static PLI_INT32 func_not_implemented_compiletf(ICARUS_VPI_CONST PLI_BYTE8* name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpi_printf("SORRY: %s:%d: function %s() is not currently implemented.\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh), name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } static PLI_INT32 array_get_property(int property, ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, array, dim; s_vpi_value value; argv = vpi_iterate(vpiArgument, callh); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires an array argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } array = vpi_scan(argv); dim = vpi_scan(argv); if(dim != 0) { vpi_printf("SORRY: %s:%d: multiple dimensions are not handled yet.\n", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } value.format = vpiIntVal; value.value.integer = vpi_get(property, array); vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 left_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { return array_get_property(vpiLeftRange, name); } static PLI_INT32 right_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { return array_get_property(vpiRightRange, name); } static void high_array(const char*name, vpiHandle callh, vpiHandle arg) { s_vpi_value value; int array_type; int size; switch ( (array_type = vpi_get(vpiArrayType, arg)) ) { case vpiDynamicArray: case vpiQueueArray: size = vpi_get(vpiSize, arg); value.format = vpiIntVal; value.value.integer = size - 1; vpi_put_value(callh, &value, 0, vpiNoDelay); break; default: vpi_printf("SORRY: %s:%d: function %s() argument object code is %d\n", vpi_get_str(vpiFile,callh), (int)vpi_get(vpiLineNo, callh), name, array_type); break; } } static PLI_INT32 high_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; int object_code; (void)name; /* Parameter is not used. */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); switch ( (object_code = vpi_get(vpiType, arg)) ) { case vpiArrayVar: high_array(name, callh, arg); break; default: vpi_printf("SORRY: %s:%d: function %s() argument object code is %d\n", vpi_get_str(vpiFile,callh), (int)vpi_get(vpiLineNo, callh), name, object_code); return 0; } return 0; } static void low_array(const char*name, vpiHandle callh, vpiHandle arg) { s_vpi_value value; int array_type; switch ( (array_type = vpi_get(vpiArrayType, arg)) ) { case vpiDynamicArray: case vpiQueueArray: value.format = vpiIntVal; value.value.integer = 0; vpi_put_value(callh, &value, 0, vpiNoDelay); break; default: vpi_printf("SORRY: %s:%d: function %s() argument object code is %d\n", vpi_get_str(vpiFile,callh), (int)vpi_get(vpiLineNo, callh), name, array_type); break; } } static PLI_INT32 low_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; int object_code; (void)name; /* Parameter is not used. */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); switch ( (object_code = vpi_get(vpiType, arg)) ) { case vpiArrayVar: low_array(name, callh, arg); break; default: vpi_printf("SORRY: %s:%d: function %s() argument object code is %d\n", vpi_get_str(vpiFile,callh), (int)vpi_get(vpiLineNo, callh), name, object_code); return 0; } return 0; } void v2009_array_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.calltf = 0; tf_data.compiletf = func_not_implemented_compiletf;; tf_data.sizetf = 0; tf_data.tfname = "$high"; tf_data.user_data = "$high"; tf_data.compiletf = one_array_arg_compiletf; tf_data.calltf = high_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$low"; tf_data.user_data = "$low"; tf_data.compiletf = one_array_arg_compiletf; tf_data.calltf = low_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$left"; tf_data.user_data = "$left"; tf_data.compiletf = array_int_opt_arg_compiletf; tf_data.calltf = left_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$right"; tf_data.user_data = "$right"; tf_data.compiletf = array_int_opt_arg_compiletf; tf_data.calltf = right_calltf; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* These functions are not currently implemented. */ tf_data.tfname = "$dimensions"; tf_data.user_data = "$dimensions"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$unpacked_dimensions"; tf_data.user_data = "$unpacked_dimensions"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = "$increment"; tf_data.user_data = "$increment"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/v2009_bitvec.c000066400000000000000000000237751435245347300164430ustar00rootroot00000000000000/* * Copyright (C) 2018-2021 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. */ #include #include "vpi_user.h" #include "sys_priv.h" /* * Check that $couintbits() is called with the correct arguments. */ static PLI_INT32 countbits_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, arg; int cb_count = 1; assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); (void)name; /* Parameter is not used. */ /* $countbits() must have arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$countbits() requires at least two arguments.\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The 1st argument must be numeric. */ arg = vpi_scan(argv); if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("The first argument to $countbits() must be numeric.\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* We need one or more numeric control bit arguments. */ arg = vpi_scan(argv); if (! arg) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$countbits() requires at least one control bit " "argument.\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } do { if (arg && ! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Control bit argument %d to $countbits() must " "be numeric.\n", cb_count); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } ++cb_count; if (arg) arg = vpi_scan(argv); } while (arg); return 0; } /* Count the number of bits in the expression that match the search bits. */ static PLI_INT32 count_bits_in_expr(vpiHandle expr_arg, char search[4]) { s_vpi_value val; PLI_INT32 result; PLI_INT32 size = vpi_get(vpiSize, expr_arg); assert(size > 0); val.format = vpiVectorVal; vpi_get_value(expr_arg, &val); result = 0; for (unsigned lp = 0; lp < (unsigned)size; ++lp) { unsigned offset = lp / 32; unsigned bit = lp % 32; unsigned abit, bbit; abit = (val.value.vector[offset].aval >> bit) & 0x1; bbit = (val.value.vector[offset].bval >> bit) & 0x1; if (search[(bbit<<1)|abit]) ++result; } return result; } static PLI_INT32 countbits_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle expr_arg = vpi_scan(argv); vpiHandle arg; char search[4]; (void)name; /* Parameter is not used. */ /* Scan the control bit arguments and mark which control bits to * include in the count. */ for (unsigned lp = 0; lp < 4 ; ++lp) search[lp] = 0; while ((arg = vpi_scan(argv))) { s_vpi_value val; val.format = vpiScalarVal; vpi_get_value(arg, &val); switch (val.value.scalar) { case vpi0: search[0] = 1; break; case vpi1: search[1] = 1; break; case vpiZ: search[2] = 1; break; case vpiX: search[3] = 1; break; default: vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("Unknown scalar control bit argument %d passed " "to $countbits() will be ignored.\n", val.value.scalar); break; } } put_integer_value(callh, count_bits_in_expr(expr_arg, search)); return 0; } /* Count the number of ones in the expression. */ static PLI_INT32 count_ones_in_expr(vpiHandle expr_arg) { s_vpi_value val; PLI_INT32 result; PLI_INT32 size = vpi_get(vpiSize, expr_arg); assert(size > 0); val.format = vpiVectorVal; vpi_get_value(expr_arg, &val); result = 0; size = (size + 31) / 32; for (unsigned lp = 0; lp < (unsigned)size; ++lp) { PLI_UINT32 ones = ~val.value.vector[lp].bval & val.value.vector[lp].aval; while (ones) { if (ones & 0x1) ++result; ones >>= 1; } } return result; } static PLI_INT32 countones_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle expr_arg = vpi_scan(argv); (void)name; /* Parameter is not used. */ vpi_free_object(argv); put_integer_value(callh, count_ones_in_expr(expr_arg)); return 0; } /* Check to see if the expression is onehot. */ static PLI_INT32 is_onehot(vpiHandle expr_arg, unsigned zero_is_okay) { s_vpi_value val; unsigned found_a_one; PLI_INT32 size = vpi_get(vpiSize, expr_arg); assert(size > 0); val.format = vpiVectorVal; vpi_get_value(expr_arg, &val); found_a_one = 0; size = (size + 31) / 32; for (unsigned lp = 0; lp < (unsigned)size; ++lp) { PLI_UINT32 ones = ~val.value.vector[lp].bval & val.value.vector[lp].aval; while (ones) { if (ones & 0x1) { if (found_a_one) return vpi0; found_a_one = 1; } ones >>= 1; } } if (found_a_one) return vpi1; else if (zero_is_okay) return vpi1; return vpi0; } static PLI_INT32 onehot_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle expr_arg = vpi_scan(argv); (void)name; /* Parameter is not used. */ vpi_free_object(argv); put_scalar_value(callh, is_onehot(expr_arg, 0)); return 0; } static PLI_INT32 onehot0_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle expr_arg = vpi_scan(argv); (void)name; /* Parameter is not used. */ vpi_free_object(argv); put_scalar_value(callh, is_onehot(expr_arg, 1)); return 0; } /* Check to see if the expression has an undefined value. */ static PLI_INT32 is_unknown(vpiHandle expr_arg) { s_vpi_value val; PLI_INT32 size = vpi_get(vpiSize, expr_arg); assert(size > 0); val.format = vpiVectorVal; vpi_get_value(expr_arg, &val); size = (size + 31) / 32; for (unsigned lp = 0; lp < (unsigned)size; ++lp) { if (val.value.vector[lp].bval) return vpi1; } return vpi0; } static PLI_INT32 isunknown_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle expr_arg = vpi_scan(argv); (void)name; /* Parameter is not used. */ vpi_free_object(argv); put_scalar_value(callh, is_unknown(expr_arg)); return 0; } static PLI_INT32 bit_vec_sizetf(ICARUS_VPI_CONST PLI_BYTE8 *name) { (void)name; /* Parameter is not used. */ return 1; } /* * Register the functions with Verilog. */ void v2009_bitvec_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.calltf = countbits_calltf; tf_data.compiletf = countbits_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$countbits"; tf_data.user_data = 0; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.calltf = countones_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$countones"; tf_data.user_data = "$countones"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.calltf = onehot_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = bit_vec_sizetf; tf_data.tfname = "$onehot"; tf_data.user_data = "$onehot"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.calltf = onehot0_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = bit_vec_sizetf; tf_data.tfname = "$onehot0"; tf_data.user_data = "$onehot0"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.calltf = isunknown_calltf; tf_data.compiletf = sys_one_numeric_arg_compiletf; tf_data.sizetf = bit_vec_sizetf; tf_data.tfname = "$isunknown"; tf_data.user_data = "$isunknown"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/v2009_enum.c000066400000000000000000000437111435245347300161230ustar00rootroot00000000000000/* * Copyright (c) 2010-2021 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 "vpi_config.h" # include "sv_vpi_user.h" # include # include # include /* * The compiletf routine for the enumeration next() and prev() methods. */ static PLI_INT32 ivl_enum_method_next_prev_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg_enum, arg_var, arg_count; /* These routines must have arguments. */ if (argv == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No arguments given for enum method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check for the enumeration type argument. */ arg_enum = vpi_scan(argv); if (arg_enum == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No enumeration type argument given for enum " "method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, arg_enum) != vpiEnumTypespec) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The first argument to enum method %s() must be an " "enumeration type, found a %s.\n", name, vpi_get_str(vpiType, arg_enum)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check for the enumeration variable. */ arg_var = vpi_scan(argv); if (arg_var == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No enumeration variable argument given for enum " "method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } switch(vpi_get(vpiType, arg_var)) { case vpiBitVar: case vpiByteVar: case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: case vpiReg: case vpiShortIntVar: break; default: vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The second argument to enum method %s() must be an " "enumeration variable, found a %s.\n", name, vpi_get_str(vpiType, arg_var)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* We can have an optional numeric count value. */ arg_count = vpi_scan(argv); if (arg_count) { switch(vpi_get(vpiType, arg_count)) { case vpiBitVar: case vpiByteVar: case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: case vpiMemoryWord: case vpiNet: case vpiPartSelect: case vpiRealVar: case vpiReg: case vpiShortIntVar: case vpiTimeVar: break; case vpiConstant: case vpiParameter: if (vpi_get(vpiConstType, arg_count) != vpiStringConst) break; // fallthrough default: vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The second argument to enum method %s() must be " "numeric, found a %s.\n", name, vpi_get_str(vpiType, arg_count)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } /* If we have a count argument then check to see if any extra * arguments were given. */ if (arg_count && (vpi_scan(argv) != 0)) { vpi_free_object(argv); vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("Extra argument(s) given to enum method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The method return value and the enum variable must be the * same size */ if (vpi_get(vpiSize, sys) != vpi_get(vpiSize, arg_var)) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The enum method %s() return width (%d) must match " "the enum variable width (%d).\n", name, (int) vpi_get(vpiSize, sys), (int) vpi_get(vpiSize, arg_var)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } /* * Compare it two values are equal to each other. */ static int compare_value_eequal(s_vpi_value*ref1, s_vpi_value*ref2, PLI_INT32 wid) { /* Two integer values are easy. */ if (ref1->format == vpiIntVal && ref2->format == vpiIntVal) return ref1->value.integer == ref2->value.integer; /* For two vectors compare them word by word. */ if (ref1->format == vpiVectorVal && ref2->format == vpiVectorVal) { PLI_INT32 words = (wid-1)/32 + 1; PLI_INT32 idx; for (idx = 0 ; idx < words ; idx += 1) { if (ref1->value.vector[idx].aval != ref2->value.vector[idx].aval) return 0; if (ref1->value.vector[idx].bval != ref2->value.vector[idx].bval) return 0; } return 1; } /* Swap the order so the code below can be used. */ if (ref1->format == vpiVectorVal && ref2->format == vpiIntVal) { s_vpi_value*tmp = ref1; ref1 = ref2; ref2 = tmp; } /* Compare an integer to a vector. */ if (ref1->format == vpiIntVal && ref2->format == vpiVectorVal) { PLI_INT32 aval = ref1->value.integer; PLI_INT32 words = (wid-1)/32 + 1; PLI_INT32 idx; for (idx = 0 ; idx < words ; idx += 1) { if (aval != ref2->value.vector[idx].aval) return 0; if (ref2->value.vector[idx].bval) return 0; aval = 0; } return 1; } /* Unsupported types. */ vpi_printf("XXXX formats are: %d vs %d\n", ref1->format, ref2->format); assert(0); return 0; } /* * If the current value is not found in the enumeration. Then we need to * return X/0 for the next()/prev() value. */ static void fill_handle_with_init(vpiHandle arg, int is_two_state) { s_vpi_value val; PLI_INT32 words = ((vpi_get(vpiSize, arg) - 1) / 32) + 1; PLI_INT32 idx; p_vpi_vecval val_ptr = (p_vpi_vecval) malloc(words*sizeof(s_vpi_vecval)); PLI_INT32 fill = (is_two_state) ? 0x0 : 0xffffffff; assert(val_ptr); /* Fill the vector with X. */ for (idx=0; idx < words; idx += 1) { val_ptr[idx].aval = fill; val_ptr[idx].bval = fill; } /* Put the vector to the argument. */ val.format = vpiVectorVal; val.value.vector = val_ptr; vpi_put_value(arg, &val, 0, vpiNoDelay); free(val_ptr); } /* * Implement the next()/prev() enumeration methods. */ static PLI_INT32 ivl_enum_method_next_prev_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg_enum = vpi_scan(argv); vpiHandle arg_var = vpi_scan(argv); vpiHandle arg_count = vpi_scan(argv); vpiHandle enum_list; vpiHandle cur; PLI_INT32 var_width = vpi_get(vpiSize, arg_var); PLI_UINT32 enum_size = vpi_get(vpiSize, arg_enum); PLI_UINT32 count = 1; PLI_UINT32 loc = 0; s_vpi_value cur_val, var_val; /* Get the count value if one was given. */ if (arg_count) { s_vpi_value count_val; /* Get the count value. */ count_val.format = vpiIntVal; vpi_get_value(arg_count, &count_val); count = count_val.value.integer; /* Remove any multiple loops around the enumeration. */ count %= enum_size; /* Free the argument iterator. */ vpi_free_object(argv); } /* Get the current value. */ var_val.format = vpiObjTypeVal; vpi_get_value(arg_var, &var_val); /* If the count is zero then just return the current value. */ if (count == 0) { vpi_put_value(sys, &var_val, 0, vpiNoDelay); return 0; } /* If the current value is a vector, then make a safe copy of it so that other vpi_get_value() calls don't trash the value. */ if (var_val.format == vpiVectorVal) { PLI_INT32 idx; PLI_INT32 words = (var_width - 1)/32 + 1; p_vpi_vecval nvec = malloc(words*sizeof(s_vpi_vecval)); for (idx = 0 ; idx < words ; idx += 1) { nvec[idx].aval = var_val.value.vector[idx].aval; nvec[idx].bval = var_val.value.vector[idx].bval; } var_val.value.vector = nvec; } /* Search for the current value in the enumeration list. */ enum_list = vpi_iterate(vpiEnumConst, arg_enum); assert(enum_list); do { cur = vpi_scan(enum_list); if (cur == 0) break; cur_val.format = vpiObjTypeVal; vpi_get_value(cur, &cur_val); assert(var_width == vpi_get(vpiSize, cur)); loc += 1; } while (! compare_value_eequal(&cur_val, &var_val, var_width)); /* If the variable is a vector then free the copy we created above. */ if (var_val.format == vpiVectorVal) free(var_val.value.vector); /* The current value was not found in the list so return X/0. */ if (cur == 0) { /* This only works correctly since we don't really define the * the correct base typespec. */ int is_two_state = vpi_get(vpiBaseTypespec, arg_enum) != vpiReg; fill_handle_with_init(sys, is_two_state); } else { if (strcmp(name, "$ivl_enum_method$next") == 0) { /* Check to see if we need to wrap to the beginning. */ if (loc + count > enum_size) { /* Free the current iterator before creating a new * one that is at the beginning of the list. */ vpi_free_object(enum_list); enum_list = vpi_iterate(vpiEnumConst, arg_enum); assert(enum_list); count -= (enum_size - loc); } } else if (strcmp(name, "$ivl_enum_method$prev") == 0) { /* Because of wrapping the count could be either before * or after the current element. */ if (loc <= count ) { /* The element we want is after the current * element. */ count = enum_size - count; } else { /* The element we want is before the current * element (at the beginning of the list). Free * the current iterator before creating a new * one that is at the beginning of the list. */ vpi_free_object(enum_list); enum_list = vpi_iterate(vpiEnumConst, arg_enum); assert(enum_list); count = loc - count; } } else assert(0); /* Find the correct element. */ while (count) { cur = vpi_scan(enum_list); count -= 1; } assert(cur != 0); /* Free the iterator. */ vpi_free_object(enum_list); /* Get the value and return it. */ cur_val.format = vpiObjTypeVal; vpi_get_value(cur, &cur_val); vpi_put_value(sys, &cur_val, 0, vpiNoDelay); } return 0; } /* * The compiletf routine for the enumeration name() method. */ static PLI_INT32 ivl_enum_method_name_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg_enum, arg_var; /* This routine must have arguments. */ if (argv == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No arguments given for enum method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Check for the enumeration type argument. */ arg_enum = vpi_scan(argv); if (arg_enum == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No enumeration type argument given for enum " "method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } if (vpi_get(vpiType, arg_enum) != vpiEnumTypespec) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The first argument to enum method %s() must be an " "enumeration type, found a %s.\n", name, vpi_get_str(vpiType, arg_enum)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Check for the enumeration variable. */ arg_var = vpi_scan(argv); if (arg_var == 0) { vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("No enumeration variable argument given for enum " "method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } switch(vpi_get(vpiType, arg_var)) { case vpiBitVar: case vpiByteVar: case vpiIntegerVar: case vpiIntVar: case vpiLongIntVar: case vpiReg: case vpiShortIntVar: break; default: vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("The second argument to enum method %s() must be an " "enumeration variable, found a %s.\n", name, vpi_get_str(vpiType, arg_var)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Only two arguments are supported. */ if (vpi_scan(argv) != 0) { vpi_free_object(argv); vpi_printf("%s:%d: compiler error: ", vpi_get_str(vpiFile, sys), (int) vpi_get(vpiLineNo,sys)); vpi_printf("Extra argument(s) given to enum method %s().\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } /* * Implement the name() enumeration method. */ static PLI_INT32 ivl_enum_method_name_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg_enum = vpi_scan(argv); vpiHandle arg_var = vpi_scan(argv); vpiHandle enum_list; vpiHandle cur; PLI_INT32 var_width = vpi_get(vpiSize, arg_var); s_vpi_value cur_val, var_val; (void)name; /* Parameter is not used. */ /* Free the argument iterator. */ vpi_free_object(argv); /* Get the current value. */ var_val.format = vpiObjTypeVal; vpi_get_value(arg_var, &var_val); /* If the current value is a vector, then make a safe copy of it so that other vpi_get_value() calls don't trash the value. */ if (var_val.format == vpiVectorVal) { PLI_INT32 idx; PLI_INT32 words = (var_width - 1)/32 + 1; p_vpi_vecval nvec = malloc(words*sizeof(s_vpi_vecval)); for (idx = 0 ; idx < words ; idx += 1) { nvec[idx].aval = var_val.value.vector[idx].aval; nvec[idx].bval = var_val.value.vector[idx].bval; } var_val.value.vector = nvec; } /* Search for the current value in the enumeration list. */ enum_list = vpi_iterate(vpiEnumConst, arg_enum); assert(enum_list); do { cur = vpi_scan(enum_list); if (cur == 0) break; cur_val.format = vpiObjTypeVal; vpi_get_value(cur, &cur_val); assert(var_width == vpi_get(vpiSize, cur)); } while (! compare_value_eequal(&cur_val, &var_val, var_width)); /* If the variable is a vector then free the copy we created above. */ if (var_val.format == vpiVectorVal) free(var_val.value.vector); /* The current value was not found in the list so return an empty * string. */ cur_val.format = vpiStringVal; if (cur == 0) { cur_val.value.str = ""; } else { cur_val.value.str = vpi_get_str(vpiName, cur); /* Free the iterator. */ vpi_free_object(enum_list); } /* Return the appropriate string value. */ vpi_put_value(sys, &cur_val, 0, vpiNoDelay); return 0; } void v2009_enum_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiOtherFunc; tf_data.calltf = ivl_enum_method_name_calltf; tf_data.compiletf = ivl_enum_method_name_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$ivl_enum_method$name"; tf_data.user_data = "$ivl_enum_method$name"; res = vpi_register_systf(&tf_data); /* This is not a user defined system function so hide it. */ vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiOtherFunc; tf_data.calltf = ivl_enum_method_next_prev_calltf; tf_data.compiletf = ivl_enum_method_next_prev_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$ivl_enum_method$next"; tf_data.user_data = "$ivl_enum_method$next"; res = vpi_register_systf(&tf_data); /* This is not a user defined system function so hide it. */ vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiOtherFunc; tf_data.calltf = ivl_enum_method_next_prev_calltf; tf_data.compiletf = ivl_enum_method_next_prev_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$ivl_enum_method$prev"; tf_data.user_data = "$ivl_enum_method$prev"; res = vpi_register_systf(&tf_data); /* This is not a user defined system function so hide it. */ vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/v2009_string.c000066400000000000000000000300451435245347300164610ustar00rootroot00000000000000/* * Copyright (c) 2012-2021 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 "sys_priv.h" # include # include # include # include # include static PLI_INT32 one_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; argv = vpi_iterate(vpiArgument, callh); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s requires a single argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (arg == 0) return 0; arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s has too many arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } return 0; } static PLI_INT32 two_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; argv = vpi_iterate(vpiArgument, callh); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s missing arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s missing object argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s missing method argument.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s has too many arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } return 0; } static PLI_INT32 len_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; (void)name; /* Parameter is not used. */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); int res = vpi_get(vpiSize, arg); s_vpi_value value; value.format = vpiIntVal; value.value.integer = res; vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 atoi_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; s_vpi_value value; (void)name; /* Parameter not used */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); int res = 0; value.format = vpiStringVal; vpi_get_value(arg, &value); const char*bufp = value.value.str; while (bufp && *bufp) { if (isdigit(*bufp)) { res = (res * 10) + (*bufp - '0'); bufp += 1; } else if (*bufp == '_') { bufp += 1; } else { bufp = 0; } } value.format = vpiIntVal; value.value.integer = res; vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 atoreal_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; s_vpi_value value; (void)name; /* Parameter not used */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); double res = 0; value.format = vpiStringVal; vpi_get_value(arg, &value); res = strtod(value.value.str, 0); value.format = vpiRealVal; value.value.real = res; vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 atohex_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle arg; s_vpi_value value; (void)name; /* Parameter not used */ argv = vpi_iterate(vpiArgument, callh); assert(argv); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); int res = 0; value.format = vpiStringVal; vpi_get_value(arg, &value); const char*bufp = value.value.str; while (bufp && *bufp) { switch (*bufp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': res = (res * 16) + (*bufp - '0'); bufp += 1; break; case 'a': case 'A': case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'e': case 'E': case 'f': case 'F': res = (res * 16) + (toupper(*bufp) - 'A' + 10); bufp += 1; break; case '_': bufp += 1; break; default: bufp = 0; break; } } value.format = vpiIntVal; value.value.integer = res; vpi_put_value(callh, &value, 0, vpiNoDelay); return 0; } /* * Convert a val to a text string that represents the value. The base * is the integer base to use for the conversion. The base will be one * of the values 2, 8, 10, or 16. If the input value is negative, then * extract the sign out (and put a '-' in the beginning of the string and * write the digits for the abs(val). For example, if the input value * is -11 and base is 8, then the text output will be "-13". */ static void value_to_text_base(char*text, long val, long base) { static const char digit_map[16] = "0123456789abcdef"; char* ptr; assert(base <= 16); if (val == 0) { text[0] = '0'; text[1] = 0; return; } if (val < 0) { *text++ = '-'; val = 0-val; } ptr = text; while (val != 0) { long digit = val % base; val /= base; *(ptr++) = digit_map[digit]; *ptr = 0; } /* Now the text string is valid, but digits are reversed. */ ptr -= 1; while (text < ptr) { char tmp = *ptr; *ptr = *text; *text = tmp; ptr -= 1; text += 1; } } /* * This function implements the .itoa(arg) method. * The first argument to this task is the object, and the second * is the value to interpret. */ static PLI_INT32 xtoa_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle obj, arg; s_vpi_value value; char text_buf[64]; long use_base; use_base = strtoul(name, 0, 10); argv = vpi_iterate(vpiArgument, callh); assert(argv); obj = vpi_scan(argv); assert(obj); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); value.format = vpiIntVal; vpi_get_value(arg, &value); value_to_text_base(text_buf, value.value.integer, use_base); value.format = vpiStringVal; value.value.str = text_buf; vpi_put_value(obj, &value, 0, vpiNoDelay); return 0; } static PLI_INT32 realtoa_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; vpiHandle obj, arg; s_vpi_value value; char text_buf[64]; (void) name; argv = vpi_iterate(vpiArgument, callh); assert(argv); obj = vpi_scan(argv); assert(obj); arg = vpi_scan(argv); assert(arg); vpi_free_object(argv); value.format = vpiRealVal; vpi_get_value(arg, &value); snprintf(text_buf, sizeof text_buf, "%g", value.value.real); value.format = vpiStringVal; value.value.str = text_buf; vpi_put_value(obj, &value, 0, vpiNoDelay); return 0; } void v2009_string_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ivl_string_method$len"; tf_data.calltf = len_calltf; tf_data.compiletf = one_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ivl_string_method$len"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ivl_string_method$atoi"; tf_data.calltf = atoi_calltf; tf_data.compiletf = one_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ivl_string_method$atoi"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.tfname = "$ivl_string_method$atoreal"; tf_data.calltf = atoreal_calltf; tf_data.compiletf = one_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ivl_string_method$atoreal"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiIntFunc; tf_data.tfname = "$ivl_string_method$atohex"; tf_data.calltf = atohex_calltf; tf_data.compiletf = one_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ivl_string_method$atohex"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysTask; tf_data.tfname = "$ivl_string_method$itoa"; tf_data.calltf = xtoa_calltf; tf_data.compiletf = two_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "10"; res = vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$ivl_string_method$hextoa"; tf_data.calltf = xtoa_calltf; tf_data.compiletf = two_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "16"; res = vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$ivl_string_method$octtoa"; tf_data.calltf = xtoa_calltf; tf_data.compiletf = two_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "8"; res = vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$ivl_string_method$bintoa"; tf_data.calltf = xtoa_calltf; tf_data.compiletf = two_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "2"; res = vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$ivl_string_method$realtoa"; tf_data.calltf = realtoa_calltf; tf_data.compiletf = two_arg_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$ivl_string_method$realtoa"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/v2009_table.c000066400000000000000000000022671435245347300162470ustar00rootroot00000000000000/* * Copyright (c) 2010-2019 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 "vpi_user.h" extern void v2009_array_register(void); extern void v2009_bitvec_register(void); extern void v2009_enum_register(void); extern void v2009_string_register(void); void (*vlog_startup_routines[])(void) = { v2009_array_register, v2009_bitvec_register, v2009_enum_register, v2009_string_register, 0 }; iverilog-12_0/vpi/va_math.c000066400000000000000000000254001435245347300157310ustar00rootroot00000000000000/* * Verilog-A math library for Icarus Verilog * http://www.icarus.com/eda/verilog/ * * Copyright (C) 2007-2021 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. */ #include "vpi_config.h" #include #include #include #include #include "vpi_user.h" #include "ivl_alloc.h" /* * Compile time options: (set in the Makefile.) * * The functions fmax() and fmin() may not be available in pre-c99 * libraries, so if they are not available you need to uncomment the * -DUSE_MY_FMAX_AND_FMIN in the Makefile. * * Most of the math functions have been moved to v2005_math. This * allows them to be supported separately from the Verilog-A * specific functions. */ /* * These are functionally equivalent fmax() and fmin() implementations * that can be used when needed. */ #ifndef HAVE_FMIN static double va_fmin(const double x, const double y) { if (x != x) {return y;} /* x is NaN so return y. */ if (y != y) {return x;} /* y is NaN so return x. */ return (x < y) ? x : y; } #endif #ifndef HAVE_FMAX static double va_fmax(const double x, const double y) { if (x != x) {return y;} /* x is NaN so return y. */ if (y != y) {return x;} /* y is NaN so return x. */ return (x > y) ? x : y; } #endif /* Single argument functions. */ typedef struct s_single_data { const char *name; double (*func)(double); } t_single_data; static t_single_data va_single_data[]= { {"$abs", fabs}, {0, 0} /* Must be NULL terminated! */ }; /* Double argument functions. */ typedef struct s_double_data { const char *name; double (*func)(double, double); } t_double_data; static t_double_data va_double_data[]= { #ifdef HAVE_FMAX {"$max", fmax}, #else {"$max", va_fmax}, #endif #ifdef HAVE_FMIN {"$min", fmin}, #else {"$min", va_fmin}, #endif {0, 0} /* Must be NULL terminated! */ }; /* * This structure holds the single argument information. */ typedef struct { vpiHandle arg; double (*func)(double); } va_single_t; /* * This structure holds the double argument information. */ typedef struct { vpiHandle arg1; vpiHandle arg2; double (*func)(double, double); } va_double_t; /* * Cleanup the allocated memory at the end of simulation. */ static va_single_t** single_funcs = 0; static unsigned single_funcs_count = 0; static va_double_t** double_funcs = 0; static unsigned double_funcs_count = 0; static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) { unsigned idx; (void)cb_data; /* Parameter is not used. */ for (idx = 0; idx < single_funcs_count; idx += 1) { free(single_funcs[idx]); } free(single_funcs); single_funcs = 0; single_funcs_count = 0; for (idx = 0; idx < double_funcs_count; idx += 1) { free(double_funcs[idx]); } free(double_funcs); double_funcs = 0; double_funcs_count = 0; return 0; } /* * Standard error message routine. The format string must take one * string argument (the name of the function). */ static void va_error_message(vpiHandle callh, const char *format, const char *name) { vpi_printf("%s:%d: error: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf(format, name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* * Process an argument. */ static vpiHandle va_process_argument(vpiHandle callh, const char *name, vpiHandle arg, const char *post) { PLI_INT32 type; if (arg == NULL) return 0; type = vpi_get(vpiType, arg); /* Math function cannot do anything with a string. */ if ((type == vpiConstant || type == vpiParameter) && (vpi_get(vpiConstType, arg) == vpiStringConst)) { const char* basemsg = "%s cannot process strings"; char* msg = malloc(strlen(basemsg)+strlen(post)+3); strcpy(msg, basemsg); strcat(msg, post); strcat(msg, ".\n"); va_error_message(callh, msg, name); free(msg); return 0; } return arg; } /* * Routine to check all the single argument math functions. */ static PLI_INT32 va_single_argument_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh, argv, arg; const t_single_data *data; const char *name; va_single_t* fun_data; assert(ud != 0); callh = vpi_handle(vpiSysTfCall, 0); assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); data = (const t_single_data *) ud; name = data->name; fun_data = malloc(sizeof(va_single_t)); /* Check that there are arguments. */ if (argv == 0) { va_error_message(callh, "%s requires one argument.\n", name); free(fun_data); return 0; } /* In Icarus if we have an argv we have at least one argument. */ arg = vpi_scan(argv); fun_data->arg = va_process_argument(callh, name, arg, ""); /* These functions only take one argument. */ arg = vpi_scan(argv); if (arg != 0) { va_error_message(callh, "%s takes only one argument.\n", name); vpi_free_object(argv); } /* Get the function that is to be used by the calltf routine. */ fun_data->func = data->func; vpi_put_userdata(callh, fun_data); single_funcs_count += 1; single_funcs = (va_single_t **)realloc(single_funcs, single_funcs_count*sizeof(va_single_t **)); single_funcs[single_funcs_count-1] = fun_data; /* vpi_scan() returning 0 (NULL) has already freed argv. */ return 0; } /* * Routine to implement the single argument math functions. */ static PLI_INT32 va_single_argument_calltf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); s_vpi_value val; va_single_t* fun_data; (void)ud; /* Parameter is not used. */ /* Retrieve the function and argument data. */ fun_data = vpi_get_userdata(callh); /* Calculate the result */ val.format = vpiRealVal; vpi_get_value(fun_data->arg, &val); val.value.real = (fun_data->func)(val.value.real); /* Return the result */ vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Routine to check all the double argument math functions. */ static PLI_INT32 va_double_argument_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh, argv, arg; const t_double_data *data; const char *name; va_double_t* fun_data; assert(ud != 0); callh = vpi_handle(vpiSysTfCall, 0); assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); data = (const t_double_data *) ud; name = data->name; fun_data = malloc(sizeof(va_double_t)); /* Check that there are arguments. */ if (argv == 0) { va_error_message(callh, "%s requires two arguments.\n", name); free(fun_data); return 0; } /* In Icarus if we have an argv we have at least one argument. */ arg = vpi_scan(argv); fun_data->arg1 = va_process_argument(callh, name, arg, " (arg1)"); /* Check that there are at least two arguments. */ arg = vpi_scan(argv); if (arg == 0) { va_error_message(callh, "%s requires two arguments.\n", name); } fun_data->arg2 = va_process_argument(callh, name, arg, " (arg2)"); /* These functions only take two arguments. */ arg = vpi_scan(argv); if (arg != 0) { va_error_message(callh, "%s takes only two arguments.\n", name); vpi_free_object(argv); } /* Get the function that is to be used by the calltf routine. */ fun_data->func = data->func; vpi_put_userdata(callh, fun_data); double_funcs_count += 1; double_funcs = (va_double_t **)realloc(double_funcs, double_funcs_count*sizeof(va_double_t **)); double_funcs[double_funcs_count-1] = fun_data; /* vpi_scan() returning 0 (NULL) has already freed argv. */ return 0; } /* * Routine to implement the double argument math functions. */ static PLI_INT32 va_double_argument_calltf(ICARUS_VPI_CONST PLI_BYTE8 *ud) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); s_vpi_value val; double first_arg; va_double_t* fun_data; (void)ud; /* Parameter is not used. */ /* Retrieve the function and argument data. */ fun_data = vpi_get_userdata(callh); /* Calculate the result */ val.format = vpiRealVal; vpi_get_value(fun_data->arg1, &val); first_arg = val.value.real; vpi_get_value(fun_data->arg2, &val); val.value.real = (fun_data->func)(first_arg, val.value.real); /* Return the result */ vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } /* * Register all the functions with Verilog. */ static void va_math_register(void) { s_cb_data cb_data; s_vpi_systf_data tf_data; vpiHandle res; unsigned idx; /* Register the single argument functions. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = va_single_argument_calltf; tf_data.compiletf = va_single_argument_compiletf; tf_data.sizetf = 0; for (idx=0; va_single_data[idx].name != 0; idx++) { tf_data.tfname = va_single_data[idx].name; tf_data.user_data = (PLI_BYTE8 *) &va_single_data[idx]; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } /* Register the double argument functions. */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = va_double_argument_calltf; tf_data.compiletf = va_double_argument_compiletf; tf_data.sizetf = 0; for (idx=0; va_double_data[idx].name != 0; idx++) { tf_data.tfname = va_double_data[idx].name; tf_data.user_data = (PLI_BYTE8 *) &va_double_data[idx]; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } /* We need to clean up the userdata. */ cb_data.reason = cbEndOfSimulation; cb_data.time = 0; cb_data.cb_rtn = sys_end_of_simulation; cb_data.user_data = "system"; vpi_register_cb(&cb_data); } /* * Hook to get Icarus Verilog to find the registration function. */ void (*vlog_startup_routines[])(void) = { va_math_register, 0 }; iverilog-12_0/vpi/vams_simparam.c000066400000000000000000000226641435245347300171620ustar00rootroot00000000000000/* * Copyright (C) 2008-2021 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. */ #include "sys_priv.h" #include #include #include #include #include #include "version_base.h" /* Once we have real string objects replace this with a dynamic string. */ #define MAX_STRING_RESULT 1024 /* * Check that the routines are called with the correct arguments. */ static PLI_INT32 simparam_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name_ext) { vpiHandle callh, argv, arg; callh = vpi_handle(vpiSysTfCall, 0); assert(callh != 0); argv = vpi_iterate(vpiArgument, callh); /* We must have at least one argument. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$simparam%s requires a string argument.\n", name_ext); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* The first argument must be a string. */ arg = vpi_scan(argv); if (! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("The first argument to $simparam%s must be a string.\n", name_ext); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The second argument (default value) is optional. */ arg = vpi_scan(argv); if (arg == 0) return 0; /* For the string version the default must also be a string. */ if (strcmp(name_ext, "$str") == 0) { if (! is_string_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("When provided, the second argument to $simparam%s" "must be a string.\n", name_ext); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* For the rest the default must be numeric. */ } else { if (! is_numeric_obj(arg)) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("When provided, the second argument to $simparam%s" "must be numeric.\n", name_ext); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } /* We can have a maximum of two arguments. */ if (vpi_scan(argv) != 0) { char msg[64]; unsigned argc; snprintf(msg, sizeof(msg), "ERROR: %s:%d:", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); msg[sizeof(msg)-1] = 0; argc = 1; while (vpi_scan(argv)) argc += 1; vpi_printf("%s $simparam%s takes at most two arguments.\n", msg, name_ext); vpi_printf("%*s Found %u extra argument%s.\n", (int) strlen(msg), " ", argc, argc == 1 ? "" : "s"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 simparam_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name_ext) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; char *param; unsigned have_def_val = 0; double retval, defval = 0.0; /* Get the parameter we are looking for. */ arg = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(arg, &val); param = strdup(val.value.str); /* See if there is a default value. */ arg = vpi_scan(argv); if (arg != 0) { vpi_free_object(argv); have_def_val = 1; val.format = vpiRealVal; vpi_get_value(arg, &val); defval = val.value.real; } /* Now check the various things we can return. */ if (strcmp(param, "gdev") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "gmin") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "imax") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "imelt") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "iteration") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "scale") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "shrink") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "simulatorSubversion") == 0) { retval = VERSION_MINOR; } else if (strcmp(param, "simulatorVersion") == 0) { retval = VERSION_MAJOR; } else if (strcmp(param, "sourceScaleFactor") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "tnom") == 0) { retval = 0.0; /* Nothing for now. */ } else if (strcmp(param, "timeUnit") == 0) { retval = pow(10, vpi_get(vpiTimeUnit, sys_func_module(callh))); } else if (strcmp(param, "timePrecision") == 0) { retval = pow(10, vpi_get(vpiTimePrecision, sys_func_module(callh))); } else if (strcmp(param, "CPUWordSize") == 0) { retval = 8.0*sizeof(long); } else { if (! have_def_val) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$simparam%s unknown parameter name \"%s\".\n", name_ext, param); } retval = defval; } free(param); /* Return the value to the system. */ val.format = vpiRealVal; val.value.real = retval; vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 simparam_str_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name_ext) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; s_vpi_value val; char *param; char *retval, *defval = NULL; /* Get the parameter we are looking for. */ arg = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(arg, &val); param = strdup(val.value.str); /* See if there is a default value. */ arg = vpi_scan(argv); if (arg != 0) { vpi_free_object(argv); val.format = vpiStringVal; vpi_get_value(arg, &val); defval = strdup(val.value.str); } /* Now check the various things we can return. */ /* For now we limit the result to 1024 characters. */ if (strcmp(param, "analysis_name") == 0) { retval = strdup("N/A"); /* Nothing for now. */ } else if (strcmp(param, "analysis_type") == 0) { retval = strdup("N/A"); /* Nothing for now. */ } else if (strcmp(param, "cwd") == 0) { char path [MAX_STRING_RESULT]; char *ptr = getcwd(path, MAX_STRING_RESULT); if (ptr == NULL) { strcpy(path, ""); } retval = strdup(path); } else if (strcmp(param, "module") == 0) { retval = strdup(vpi_get_str(vpiDefName, sys_func_module(callh))); } else if (strcmp(param, "instance") == 0) { retval = strdup(vpi_get_str(vpiFullName, sys_func_module(callh))); } else if (strcmp(param, "path") == 0) { retval = strdup(vpi_get_str(vpiFullName, vpi_handle(vpiScope,callh))); } else { if (defval == NULL) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("$simparam%s unknown parameter name \"%s\".\n", name_ext, param); defval = strdup(""); } retval = defval; } free(param); /* Return the value to the system. */ val.format = vpiStringVal; val.value.str = retval; vpi_put_value(callh, &val, 0, vpiNoDelay); if (defval != retval) free(defval); free(retval); return 0; } static PLI_INT32 simparam_str_sizetf(ICARUS_VPI_CONST PLI_BYTE8 *name_ext) { (void) name_ext; /* Parameter is not used. */ return MAX_STRING_RESULT; /* 128 characters max! */ } /* * Register the function with Verilog. */ void vams_simparam_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiRealFunc; tf_data.calltf = simparam_calltf; tf_data.compiletf = simparam_compiletf; tf_data.sizetf = 0; tf_data.tfname = "$simparam"; tf_data.user_data = ""; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; /* What should this be? */ tf_data.calltf = simparam_str_calltf; tf_data.compiletf = simparam_compiletf; tf_data.sizetf = simparam_str_sizetf; /* Only 128 characters! */ tf_data.tfname = "$simparam$str"; tf_data.user_data = "$str"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } iverilog-12_0/vpi/vcd_priv.c000066400000000000000000000150211435245347300161240ustar00rootroot00000000000000/* * Copyright (c) 2003-2021 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 "sys_priv.h" #include "vcd_priv.h" #include "ivl_alloc.h" #include #include #include #include #include #include "stringheap.h" int is_escaped_id(const char *name) { assert(name); /* The first digit must be alpha or '_' to be a normal id. */ if (isalpha((int)name[0]) || name[0] == '_') { int lp; for (lp=1; name[lp] != '\0'; lp++) { /* If this digit is not alpha-numeric or '_' we have * an escaped identifier. */ if (!(isalnum((int)name[lp]) || name[lp] == '_') || name[lp] == '$') { return 1; } } /* We looked at all the digits, so this is a normal id. */ return 0; } return 1; } struct stringheap_s name_heap = {0, 0}; struct vcd_names_s { const char *name; struct vcd_names_s *next; }; void vcd_names_add(struct vcd_names_list_s*tab, const char *name) { struct vcd_names_s *nl = (struct vcd_names_s *) malloc(sizeof(struct vcd_names_s)); nl->name = strdup_sh(&name_heap, name); nl->next = tab->vcd_names_list; tab->vcd_names_list = nl; tab->listed_names ++; } void vcd_names_delete(struct vcd_names_list_s*tab) { struct vcd_names_s *cur, *tmp; for (cur = tab->vcd_names_list; cur; cur = tmp) { tmp = cur->next; free(cur); } tab->vcd_names_list = 0; tab->listed_names = 0; free(tab->vcd_names_sorted); tab->vcd_names_sorted = 0; tab->sorted_names = 0; string_heap_delete(&name_heap); } static int vcd_names_compare(const void *s1, const void *s2) { const char *v1 = *(const char * const *) s1; const char *v2 = *(const char * const *) s2; return strcmp(v1, v2); } const char *vcd_names_search(struct vcd_names_list_s*tab, const char *key) { const char **v; if (tab->vcd_names_sorted == 0) return 0; v = (const char **) bsearch(&key, tab->vcd_names_sorted, tab->sorted_names, sizeof(const char *), vcd_names_compare ); return(v ? *v : NULL); } void vcd_names_sort(struct vcd_names_list_s*tab) { if (tab->listed_names) { struct vcd_names_s *r; const char **l; tab->sorted_names += tab->listed_names; tab->vcd_names_sorted = (const char **) realloc(tab->vcd_names_sorted, tab->sorted_names*(sizeof(const char *))); l = tab->vcd_names_sorted + tab->sorted_names - tab->listed_names; tab->listed_names = 0; r = tab->vcd_names_list; tab->vcd_names_list = 0x0; while (r) { struct vcd_names_s *rr = r; r = rr->next; *(l++) = rr->name; free(rr); } qsort(tab->vcd_names_sorted, tab->sorted_names, sizeof(const char **), vcd_names_compare); } } /* * Since the compiletf routines are all the same they are located here, * so we only need a single copy. Some are generic enough they can use * the ones in sys_priv.c (no arg, one numeric argument, etc.). */ /* $dumpvars takes a variety of arguments. */ PLI_INT32 sys_dumpvars_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* No arguments is OK, dump everything. */ if (argv == 0) return 0; /* The first argument is the numeric level. */ if (! is_numeric_obj(vpi_scan(argv))) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s's argument must be numeric.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* The rest of the arguments are either a module or a variable. */ while ((arg=vpi_scan(argv)) != NULL) { switch(vpi_get(vpiType, arg)) { case vpiMemoryWord: /* * We need to allow non-constant selects to support the following: * * for (lp = 0; lp < max ; lp = lp + 1) $dumpvars(0, array[lp]); * * We need to do a direct callback on the selected element vs using * the &A<> structure. The later will not give us what we want. * This is implemented in the calltf routine. */ #if 0 if (vpi_get(vpiConstantSelect, arg) == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s cannot dump a non-constant select %s.\n", name, vpi_get_str(vpiType, arg)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } #endif /* The module types. */ case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: /* The variable types. */ #if 0 case vpiParameter: /* A constant! */ #endif case vpiNet: case vpiReg: case vpiIntegerVar: case vpiBitVar: case vpiByteVar: case vpiShortIntVar: case vpiIntVar: case vpiLongIntVar: case vpiTimeVar: case vpiRealVar: case vpiNamedEvent: break; case vpiParameter: /* A constant! */ vpi_printf("SORRY: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s cannot currently dump a parameter.\n", name); break; default: vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); vpi_printf("%s cannot dump a %s.\n", name, vpi_get_str(vpiType, arg)); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } } return 0; } iverilog-12_0/vpi/vcd_priv.h000066400000000000000000000115361435245347300161400ustar00rootroot00000000000000#ifndef IVL_vcd_priv_H #define IVL_vcd_priv_H /* * Copyright (c) 2003-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 "vpi_user.h" #ifdef __cplusplus # define EXTERN extern "C" #else # define EXTERN extern #endif EXTERN int is_escaped_id(const char *name); struct vcd_names_s; EXTERN struct stringheap_s name_heap; struct vcd_names_list_s { struct vcd_names_s *vcd_names_list; const char **vcd_names_sorted; int listed_names, sorted_names; }; EXTERN void vcd_names_add(struct vcd_names_list_s*tab, const char *name); EXTERN const char *vcd_names_search(struct vcd_names_list_s*tab, const char *key); EXTERN void vcd_names_sort(struct vcd_names_list_s*tab); EXTERN void vcd_names_delete(struct vcd_names_list_s*tab); /* * Keep a map of nexus ident's to help with alias detection. */ EXTERN const char*find_nexus_ident(int nex); EXTERN void set_nexus_ident(int nex, const char *id); EXTERN void nexus_ident_delete(void); /* * Keep a set of scope names to help with duplicate detection. */ EXTERN void vcd_scope_names_add(const char*name); EXTERN int vcd_scope_names_test(const char*name); EXTERN void vcd_scope_names_delete(void); /* * Implement a work queue that can be used to send commands to a * dumper thread. */ typedef enum vcd_work_item_type_e { WT_NONE, WT_EMIT_BITS, WT_EMIT_DOUBLE, WT_DUMPON, WT_DUMPOFF, WT_FLUSH, WT_TERMINATE } vcd_work_item_type_t; struct lxt2_wr_symbol; struct vcd_work_item_s { vcd_work_item_type_t type; uint64_t time; union { struct lxt2_wr_symbol*lxt2; } sym_; union { double val_double; char*val_char; } op_; }; /* * The thread_peek and thread_pop functions work as pairs. The work * thread processing work items uses vcd_work_thread_peek to look at * the first item in the work queue. The work thread can be assured * that the work item it stable. When it is done with the work item, * it calls vcd_work_thread_pop to cause it to be popped from the work * queue. */ EXTERN struct vcd_work_item_s* vcd_work_thread_peek(void); EXTERN void vcd_work_thread_pop(void); /* * Create work threads with the vcd_work_start function, and terminate * the work thread (gracefully) with the vcd_work_terminate * function. Synchronize with the work thread with the vcd_work_sync * function. This blocks until the work thread is done all the work it * has so far. */ EXTERN void vcd_work_start( void* (*fun) (void*arg), void*arg); EXTERN void vcd_work_terminate(void); EXTERN void vcd_work_sync(void); /* * The remaining vcd_work_* functions send messages to the work thread * causing it to perform various VCD-related tasks. */ EXTERN void vcd_work_flush(void); /* Drain output caches. */ EXTERN void vcd_work_set_time(uint64_t val); EXTERN void vcd_work_dumpon(void); EXTERN void vcd_work_dumpoff(void); EXTERN void vcd_work_emit_double(struct lxt2_wr_symbol*sym, double val); EXTERN void vcd_work_emit_bits(struct lxt2_wr_symbol*sym, const char*bits); /* The compiletf routines are common for the VCD, LXT and LXT2 dumpers. */ EXTERN PLI_INT32 sys_dumpvars_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name); /* * The vcd_list is the list of all the objects that are tracked for * dumping. The vcd_checkpoint goes through the list to dump the current * values for everything. When the item has a value change, it is added to the * vcd_dmp_list for dumping in the current time step. * * The vcd_const_list is a list of all of the parameters that are being * dumped. This list is scanned less often, since parameters do not change * values. */ #define DECLARE_VCD_INFO(type_name, ident_type) \ struct type_name { \ vpiHandle item; \ vpiHandle cb;\ struct t_vpi_time time; \ struct vcd_info *next; \ struct vcd_info *dmp_next; \ int scheduled; \ ident_type ident; \ } #define ITERATE_VCD_INFO(use_list, use_type, use_next, method) \ do { \ struct use_type*cur; \ for (cur = use_list ; cur ; cur = cur->use_next) \ method(cur); \ } while (0) #undef EXTERN #endif /* IVL_vcd_priv_H */ iverilog-12_0/vpi/vcd_priv2.cc000066400000000000000000000176701435245347300163650ustar00rootroot00000000000000/* * Copyright (c) 2010-2011 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 "vcd_priv.h" # include # include # include # include # include # include # include /* Nexus Id cache In structural models, many signals refer to the same nexus. Some structural models also have very many signals. This cache saves nexus_id - vcd_id pairs, and reuses the vcd_id when a signal refers to a nexus that is already dumped. The new signal will be listed as a $var, but no callback will be installed. This saves considerable CPU time and leads to smaller VCD files. The _vpiNexusId is a private (int) property of IVL simulators. */ static std::map nexus_ident_map; extern "C" const char*find_nexus_ident(int nex) { std::map::const_iterator cur = nexus_ident_map.find(nex); if (cur == nexus_ident_map.end()) return 0; else return cur->second; } extern "C" void set_nexus_ident(int nex, const char*id) { nexus_ident_map[nex] = id; } extern "C" void nexus_ident_delete() { nexus_ident_map.clear(); } static std::set vcd_scope_names_set; extern "C" void vcd_scope_names_add(const char*name) { vcd_scope_names_set .insert(name); } extern "C" int vcd_scope_names_test(const char*name) { if (vcd_scope_names_set.find(name) == vcd_scope_names_set.end()) return 0; else return 1; } extern "C" void vcd_scope_names_delete(void) { vcd_scope_names_set.clear(); } static pthread_t work_thread; static const unsigned WORK_QUEUE_SIZE = 128*1024; static const unsigned WORK_QUEUE_BATCH_MIN = 4*1024; static const unsigned WORK_QUEUE_BATCH_MAX = 32*1024; static struct vcd_work_item_s work_queue[WORK_QUEUE_SIZE]; static volatile unsigned work_queue_next = 0; static volatile unsigned work_queue_fill = 0; static pthread_mutex_t work_queue_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t work_queue_is_empty_sig = PTHREAD_COND_INITIALIZER; static pthread_cond_t work_queue_notempty_sig = PTHREAD_COND_INITIALIZER; static pthread_cond_t work_queue_minfree_sig = PTHREAD_COND_INITIALIZER; extern "C" struct vcd_work_item_s* vcd_work_thread_peek(void) { // There must always only be 1 vcd work thread, and only the // work thread decreases the fill, so if the work_queue_fill // is non-zero, I can reliably assume that there is at least // one item that I can peek at. I only need to lock if I must // wait for the work_queue_fill to become non-zero. if (work_queue_fill == 0) { pthread_mutex_lock(&work_queue_mutex); while (work_queue_fill == 0) pthread_cond_wait(&work_queue_notempty_sig, &work_queue_mutex); pthread_mutex_unlock(&work_queue_mutex); } return work_queue + work_queue_next; } extern "C" void vcd_work_thread_pop(void) { pthread_mutex_lock(&work_queue_mutex); unsigned use_fill = work_queue_fill - 1; work_queue_fill = use_fill; unsigned use_next = work_queue_next; struct vcd_work_item_s*cell = work_queue + use_next; if (cell->type == WT_EMIT_BITS) { free(cell->op_.val_char); } use_next += 1; if (use_next >= WORK_QUEUE_SIZE) use_next = 0; work_queue_next = use_next; if (use_fill == WORK_QUEUE_SIZE-WORK_QUEUE_BATCH_MIN) pthread_cond_signal(&work_queue_minfree_sig); else if (use_fill == 0) pthread_cond_signal(&work_queue_is_empty_sig); pthread_mutex_unlock(&work_queue_mutex); } /* * Work queue items are created in batches to reduce thread * bouncing. When the producer gets a free work item, it actually * locks the queue in order to produce a batch. The queue stays locked * until the batch is complete. Then the releases the whole lot to the * consumer. */ static uint64_t work_queue_next_time = 0; static unsigned current_batch_cnt = 0; static unsigned current_batch_alloc = 0; static unsigned current_batch_base = 0; extern "C" void vcd_work_start( void* (*fun) (void*), void*arg ) { pthread_create(&work_thread, 0, fun, arg); } static struct vcd_work_item_s* grab_item(void) { if (current_batch_alloc == 0) { pthread_mutex_lock(&work_queue_mutex); while ((WORK_QUEUE_SIZE-work_queue_fill) < WORK_QUEUE_BATCH_MIN) pthread_cond_wait(&work_queue_minfree_sig, &work_queue_mutex); current_batch_base = work_queue_next + work_queue_fill; current_batch_alloc = WORK_QUEUE_SIZE - work_queue_fill; pthread_mutex_unlock(&work_queue_mutex); if (current_batch_base >= WORK_QUEUE_SIZE) current_batch_base -= WORK_QUEUE_SIZE; if (current_batch_alloc > WORK_QUEUE_BATCH_MAX) current_batch_alloc = WORK_QUEUE_BATCH_MAX; current_batch_cnt = 0; } assert(current_batch_cnt < current_batch_alloc); unsigned cur = current_batch_base + current_batch_cnt; if (cur >= WORK_QUEUE_SIZE) cur -= WORK_QUEUE_SIZE; // Write the new timestamp into the work item. struct vcd_work_item_s*cell = work_queue + cur; cell->time = work_queue_next_time; return cell; } static void end_batch(void) { pthread_mutex_lock(&work_queue_mutex); unsigned use_fill = work_queue_fill; bool was_empty_flag = (use_fill==0) && (current_batch_cnt > 0); use_fill += current_batch_cnt; work_queue_fill = use_fill; current_batch_alloc = 0; current_batch_cnt = 0; if (was_empty_flag) pthread_cond_signal(&work_queue_notempty_sig); pthread_mutex_unlock(&work_queue_mutex); } static inline void unlock_item(bool flush_batch =false) { current_batch_cnt += 1; if (current_batch_cnt == current_batch_alloc || flush_batch) end_batch(); } extern "C" void vcd_work_sync(void) { if (current_batch_alloc > 0) end_batch(); if (work_queue_fill > 0) { pthread_mutex_lock(&work_queue_mutex); while (work_queue_fill > 0) pthread_cond_wait(&work_queue_is_empty_sig, &work_queue_mutex); pthread_mutex_unlock(&work_queue_mutex); } } extern "C" void vcd_work_flush(void) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_FLUSH; unlock_item(true); } extern "C" void vcd_work_dumpon(void) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_DUMPON; unlock_item(); } extern "C" void vcd_work_dumpoff(void) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_DUMPOFF; unlock_item(); } extern "C" void vcd_work_set_time(uint64_t val) { work_queue_next_time = val; } extern "C" void vcd_work_emit_double(struct lxt2_wr_symbol*sym, double val) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_EMIT_DOUBLE; cell->sym_.lxt2 = sym; cell->op_.val_double = val; unlock_item(); } extern "C" void vcd_work_emit_bits(struct lxt2_wr_symbol*sym, const char* val) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_EMIT_BITS; cell->sym_.lxt2 = sym; cell->op_.val_char = strdup(val); unlock_item(); } extern "C" void vcd_work_terminate(void) { struct vcd_work_item_s*cell = grab_item(); cell->type = WT_TERMINATE; unlock_item(true); pthread_join(work_thread, 0); } iverilog-12_0/vpi/vhdl_table.c000066400000000000000000000207721435245347300164250ustar00rootroot00000000000000/* * Copyright (c) 2011-2021 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 "vpi_config.h" # include "vpi_user.h" # include # include "ivl_alloc.h" # include "sys_priv.h" /* * The $ivlh_attribute_event implements the VHDL 'event * attribute. It does this by monitoring value-change events on the * operand, and noting the time. If the $ivlh_attribute_event is * called at the same simulation time as a value-change, then the * function returns logic true. Otherwise it returns false. * * $ivlh_{rising,falling}_edge implement the VHDL rising_edge() and * falling_edge() system functions. */ struct monitor_data { struct t_vpi_time last_event; struct t_vpi_value last_value; }; static struct monitor_data **mdata = 0; static unsigned mdata_count = 0; typedef enum { EVENT = 0, RISING_EDGE = 1, FALLING_EDGE = 2 } event_type_t; static const char* attr_func_names[] = { "$ivlh_attribute_event", "$ivlh_rising_edge", "$ivlh_falling_edge" }; typedef enum { SHIFT_LEFT = 0, SHIFT_RIGHT = 1, } shift_type_t; static const char* shift_func_names[] = { "$ivlh_shift_left", "$ivlh_shift_right", }; /* To keep valgrind happy free the allocated memory. */ static PLI_INT32 cleanup_mdata(p_cb_data cause) { unsigned idx; (void) cause; /* Parameter is not used. */ for (idx= 0; idx < mdata_count; idx += 1) { free(mdata[idx]); } free(mdata); mdata = 0; mdata_count = 0; return 0; } static PLI_INT32 monitor_events(struct t_cb_data*cb) { struct monitor_data*mon = (struct monitor_data*)(cb->user_data); assert(cb->time); assert(cb->time->type == vpiSimTime); mon->last_event = *(cb->time); mon->last_value = *(cb->value); return 0; } static PLI_INT32 ivlh_attribute_event_compiletf(ICARUS_VPI_CONST PLI_BYTE8*data) { event_type_t type = (event_type_t) data; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle arg; struct monitor_data*mon; struct t_cb_data cb; struct t_vpi_time tb; struct t_vpi_value vb; /* Check that there are arguments. */ if (argv == 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_printf("(compiler error) %s requires a single argument.\n", attr_func_names[type]); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Icarus either returns 0 above or has one argument. */ arg = vpi_scan(argv); assert(arg); mon = malloc(sizeof(struct monitor_data)); /* Add this to the list of data. */ mdata_count += 1; mdata = (struct monitor_data **) realloc(mdata, sizeof(struct monitor_data **) * mdata_count); mdata[mdata_count-1] = mon; tb.type = vpiSimTime; vb.format = vpiScalarVal; cb.reason = cbValueChange; cb.cb_rtn = monitor_events; cb.obj = arg; cb.time = &tb; cb.value = &vb; cb.user_data = (char*) (mon); vpi_register_cb(&cb); vpi_put_userdata(sys, mon); /* Check that there is no more than one argument. */ arg = vpi_scan(argv); if (arg != 0) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys)); vpi_printf("(compiler error) %s only takes a single argument.\n", attr_func_names[type]); vpi_free_object(argv); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } return 0; } static PLI_INT32 ivlh_attribute_event_calltf(ICARUS_VPI_CONST PLI_BYTE8*data) { event_type_t type = (event_type_t) data; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); struct t_vpi_value rval; struct monitor_data*mon; rval.format = vpiScalarVal; mon = (struct monitor_data*) (vpi_get_userdata(sys)); if (mon->last_event.type == 0) { rval.value.scalar = vpi0; } else { struct t_vpi_time tnow; tnow.type = vpiSimTime; vpi_get_time(0, &tnow); rval.value.scalar = vpi1; // Detect if change occurred in this moment if (mon->last_event.high != tnow.high) rval.value.scalar = vpi0; if (mon->last_event.low != tnow.low) rval.value.scalar = vpi0; // Determine the edge, if required if (type == RISING_EDGE && mon->last_value.value.scalar != vpi1) rval.value.scalar = vpi0; else if (type == FALLING_EDGE && mon->last_value.value.scalar != vpi0) rval.value.scalar = vpi0; } vpi_put_value(sys, &rval, 0, vpiNoDelay); return 0; } static PLI_INT32 ivlh_attribute_event_sizetf(ICARUS_VPI_CONST PLI_BYTE8*type) { (void) type; /* Parameter is not used. */ return 1; } static PLI_INT32 ivlh_shift_calltf(ICARUS_VPI_CONST PLI_BYTE8*data) { shift_type_t shift_type = (shift_type_t) data; vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle argh = vpi_scan(argv); vpiHandle counth = vpi_scan(argv); s_vpi_value val; PLI_INT32 count; vpi_free_object(argv); val.format = vpiIntVal; vpi_get_value(counth, &val); count = val.value.integer; val.format = vpiIntVal; vpi_get_value(argh, &val); if(shift_type == SHIFT_LEFT) val.value.integer <<= count; else if(shift_type == SHIFT_RIGHT) val.value.integer >>= count; else assert(0); vpi_put_value(callh, &val, 0, vpiNoDelay); return 0; } static PLI_INT32 ivlh_shift_sizetf(ICARUS_VPI_CONST PLI_BYTE8*type) { (void) type; /* Parameter is not used. */ return 32; } static void vhdl_register(void) { s_vpi_systf_data tf_data; s_cb_data cb; vpiHandle res; /* Event attribute functions */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.calltf = ivlh_attribute_event_calltf; tf_data.compiletf = ivlh_attribute_event_compiletf; tf_data.sizetf = ivlh_attribute_event_sizetf; tf_data.tfname = attr_func_names[EVENT]; tf_data.user_data = (PLI_BYTE8*) EVENT; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = attr_func_names[RISING_EDGE]; tf_data.user_data = (PLI_BYTE8*) RISING_EDGE; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = attr_func_names[FALLING_EDGE]; tf_data.user_data = (PLI_BYTE8*) FALLING_EDGE; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Shift functions */ tf_data.type = vpiSysFunc; tf_data.sysfunctype = vpiSizedFunc; tf_data.calltf = ivlh_shift_calltf; tf_data.compiletf = sys_two_numeric_args_compiletf; tf_data.sizetf = ivlh_shift_sizetf; tf_data.tfname = shift_func_names[SHIFT_LEFT]; tf_data.user_data = (PLI_BYTE8*) SHIFT_LEFT; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); tf_data.tfname = shift_func_names[SHIFT_RIGHT]; tf_data.user_data = (PLI_BYTE8*) SHIFT_RIGHT; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); /* Create a callback to clear the monitor data memory when the * simulator finishes. */ cb.time = NULL; cb.reason = cbEndOfSimulation; cb.cb_rtn = cleanup_mdata; cb.user_data = NULL; cb.obj = NULL; vpi_register_cb(&cb); } void (*vlog_startup_routines[])(void) = { vhdl_register, 0 }; iverilog-12_0/vpi/vhdl_textio.c000066400000000000000000000735301435245347300166520ustar00rootroot00000000000000/* * Copyright (c) 2015-2021 CERN * @author Maciej Suminski * * 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. */ /** * The following VPI module implements some of the functions available * in std.textio library. * * Type counterparts: * VHDL SystemVerilog * ------------------------------ * LINE string (line of text, in VHDL it is a pointer to string) * TEXT int (file handle) * * Some of functions offered by std.textio library are not implemented here, * as they can be directly replaced with SystemVerilog system functions. * * VHDL SystemVerilog * -------------------------------------- * FILE_CLOSE(file F: TEXT) $fclose(fd) * ENDFILE(file F: TEXT) $feof(fd) * * Procedures: * HREAD (L: inout LINE; VALUE: out BIT_VECTOR) * HWRITE (L: inout LINE; VALUE: out BIT_VECTOR) * are handled with $ivlh_read/write() using FORMAT_HEX parameter (see format_t enum). */ # include "sys_priv.h" # include "vpi_config.h" # include "vpi_user.h" # include # include # include # include # include "ivl_alloc.h" /* additional parameter values to distinguish between integer, boolean and * time types or to use hex format */ enum format_t { FORMAT_STD, FORMAT_BOOL, FORMAT_TIME, FORMAT_HEX, FORMAT_STRING }; enum file_mode_t { FILE_MODE_READ, FILE_MODE_WRITE, FILE_MODE_APPEND, FILE_MODE_LAST }; enum file_open_status_t { FS_OPEN_OK, FS_STATUS_ERROR, FS_NAME_ERROR, FS_MODE_ERROR }; /* bits per vector, in a single s_vpi_vecval struct */ static const size_t BPW = 8 * sizeof(PLI_INT32); /* string buffer size */ static const size_t STRING_BUF_SIZE = 1024; static int is_integer_var(vpiHandle obj) { PLI_INT32 type = vpi_get(vpiType, obj); return (type == vpiIntegerVar || type == vpiShortIntVar || type == vpiIntVar || type == vpiLongIntVar || /* In vlog95 translation this is a signed 32-bit register. */ (type == vpiReg && vpi_get(vpiSigned, obj) && vpi_get(vpiSize, obj) == 32)); } static int is_const(vpiHandle obj) { return vpi_get(vpiType, obj) == vpiConstant; } static void show_error_line(vpiHandle callh) { vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); } static void show_warning_line(vpiHandle callh) { vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh), (int)vpi_get(vpiLineNo, callh)); } /* sets a single bit value in a bit/logic vector */ static int set_vec_val(s_vpi_vecval* vector, char value, int idx) { s_vpi_vecval*v = &vector[idx / BPW]; PLI_INT32 bit = idx % BPW; switch(value) { case '0': v->bval &= ~(1 << bit); v->aval &= ~(1 << bit); break; case '1': v->bval &= ~(1 << bit); v->aval |= (1 << bit); break; case 'z': case 'Z': v->bval |= (1 << bit); v->aval &= ~(1 << bit); break; case 'x': case 'X': v->bval |= (1 << bit); v->aval |= (1 << bit); break; default: return 1; } return 0; } /* Converts a string of characters to a vector in s_vpi_value struct. * Returns number of processed characters, 0 in case of failure. * string is the data to be converted. * val is the target s_vpi_value struct. * var is the variable that is converted (to obtain size & type [2/4-state]). */ static int read_vector(const char *string, s_vpi_value *val, vpiHandle var) { #if 0 /* It could be easier to simply use val.format = vpiBinStrVal * but there is no way to check if processing went fine */ val.format = vpiBinStrVal; val.value.str = string; processed_chars = size; #endif /* Vector size (==1 for scalars) */ int size = vpi_get(vpiSize, var); /* Number of required s_vpi_vecval structs to store the result */ int words = (size + BPW - 1) / BPW; /* == ceil(size / BPW) */ int len = strlen(string); val->format = vpiVectorVal; /* it also covers scalars */ val->value.vector = calloc(words, sizeof(s_vpi_vecval)); /* Skip spaces in the beginning */ int skipped = 0; while(*string && *string == ' ') { --len; ++string; ++skipped; } /* Process bits */ int p; for(p = 0; p < size && p < len; ++p) { if(set_vec_val(val->value.vector, string[p], size - p - 1)) { free(val->value.vector); /* error */ return 0; } } /* 2-logic variables cannot hold X or Z values, so change them to 0 */ if(vpi_get(vpiType, var) == vpiBitVar) { for(int i = 0; i < words; ++i) { val->value.vector[i].aval &= ~val->value.vector[i].bval; val->value.vector[i].bval = 0; } } return p + skipped; } /* Converts a string of characters to a time value, stored in vector filed of * s_vpi_value struct. * Returns number of processed characters, 0 in case of failure. * string is the data to be converted. * val is the target s_vpi_value struct. * scope_unit is the time unit used in the scope (-3 for millisecond, * -6 for microsecond, etc.) */ static int read_time(const char *string, s_vpi_value *val, PLI_INT32 scope_unit) { PLI_UINT64 period; char units[3]; int time_unit, processed_chars; if(sscanf(string, "%" PLI_UINT64_FMT " %2s%n", &period, units, &processed_chars) != 2) return 0; if(!strncasecmp(units, "fs", 2)) time_unit = -15; else if(!strncasecmp(units, "ps", 2)) time_unit = -12; else if(!strncasecmp(units, "ns", 2)) time_unit = -9; else if(!strncasecmp(units, "us", 2)) time_unit = -6; else if(!strncasecmp(units, "ms", 2)) time_unit = -3; else if(!strncasecmp(units, "s", 1)) time_unit = 0; else return 0; /* Scale the time units to the one used in the scope */ int scale_diff = time_unit - scope_unit; if(scale_diff > 0) { for(int i = 0; i < scale_diff; ++i) period *= 10; } else { for(int i = 0; i < -scale_diff; ++i) period /= 10; } /* vpiTimeVal format is not handled at the moment, * so return the read value as a vector*/ val->format = vpiVectorVal; val->value.vector = calloc(2, sizeof(s_vpi_vecval)); memset(val->value.vector, 0, 2 * sizeof(s_vpi_vecval)); val->value.vector[1].aval = (PLI_UINT32) (period >> 32); val->value.vector[0].aval = (PLI_UINT32) period; return processed_chars; } static int read_string(const char *string, s_vpi_value *val, int count) { char buf[STRING_BUF_SIZE]; int processed_chars; char format_str[32]; /* No string length limit imposed */ if(count <= 0 || count >= (int)STRING_BUF_SIZE) count = STRING_BUF_SIZE - 1; snprintf(format_str, 32, "%%%ds%%n", count); if(sscanf(string, format_str, buf, &processed_chars) != 1) return 0; val->format = vpiStringVal; val->value.str = strdup(buf); return processed_chars; } static int write_time(char *string, const s_vpi_value* val, size_t width, PLI_INT32 scope_unit) { char prefix = 0; PLI_UINT64 period; switch(val->format) { case vpiIntVal: period = val->value.integer; break; case vpiVectorVal: period = val->value.vector[0].aval; if(width > BPW) period |= (PLI_UINT64)(val->value.vector[1].aval) << 32; break; default: return 1; } /* Handle the case when the time unit base is 10 or 100 */ int remainder = scope_unit % -3; if(remainder) { remainder += 3; scope_unit -= remainder; while(remainder--) period *= 10; } switch(scope_unit) { case -15: prefix = 'f'; break; case -12: prefix = 'p'; break; case -9: prefix = 'n'; break; case -6: prefix = 'u'; break; case -3: prefix = 'm'; break; } if(prefix) sprintf(string, "%" PLI_UINT64_FMT " %cs", period, prefix); else sprintf(string, "%" PLI_UINT64_FMT " s", period); return 0; } /* slightly modified sys_fopen_compiletf */ static PLI_INT32 ivlh_file_open_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv, arg; assert(callh != 0); int ok = 1; argv = vpi_iterate(vpiArgument, callh); /* Check that there is a file name argument and that it is a string. */ if (argv == 0) ok = 0; arg = vpi_scan(argv); if (!arg || !is_integer_var(arg)) ok = 0; arg = vpi_scan(argv); if (arg && is_integer_var(arg)) arg = vpi_scan(argv); // no vpi_scan() here, if we had both 'status' and 'file' arguments, // then the next arg is read in the above if, otherwise we are going // to check the second argument once again if (!arg || !is_string_obj(arg)) ok = 0; arg = vpi_scan(argv); if (arg && !is_const(arg)) ok = 0; if (!ok) { show_error_line(callh); vpi_printf("%s() function is available in following variants:\n", name); vpi_printf("* (file f: text; filename: in string, file_open_kind: in mode)\n"); vpi_printf("* (status: out file_open_status, file f: text; filename: in string, file_open_kind: in mode)\n"); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "four arguments", 1); return 0; } /* procedure FILE_MODE(file F: TEXT; External_Name; in STRING; Open_Kind: in FILE_MODE_KIND := READ_MODE); */ /* slightly modified sys_fopen_calltf */ static PLI_INT32 ivlh_file_open_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); s_vpi_value val; int mode; char *fname; vpiHandle fstatush = vpi_scan(argv); vpiHandle fhandleh = vpi_scan(argv); vpiHandle fnameh = vpi_scan(argv); vpiHandle modeh = vpi_scan(argv); if(!modeh) { /* There are only three arguments, so rearrange handles */ modeh = fnameh; fnameh = fhandleh; fhandleh = fstatush; fstatush = 0; } else { vpi_free_object(argv); } /* Get the mode handle */ val.format = vpiIntVal; vpi_get_value(modeh, &val); mode = val.value.integer; if(mode < 0 || mode >= FILE_MODE_LAST) { show_error_line(callh); vpi_printf("%s's file open mode argument is invalid.\n", name); return 0; } fname = get_filename(callh, name, fnameh); if(fname == 0) { show_error_line(callh); vpi_printf("%s's could not obtain the file name.\n", name); return 0; } /* Open file and save the handle */ PLI_INT32 result = -1; switch(mode) { case FILE_MODE_READ: result = vpi_fopen(fname, "r"); break; case FILE_MODE_WRITE: result = vpi_fopen(fname, "w"); break; case FILE_MODE_APPEND: result = vpi_fopen(fname, "a"); break; } if(fstatush) { val.format = vpiIntVal; if(!result) { switch(errno) { case ENOENT: case ENAMETOOLONG: val.value.integer = FS_NAME_ERROR; break; case EINVAL: case EACCES: case EEXIST: case EISDIR: val.value.integer = FS_MODE_ERROR; break; default: val.value.integer = FS_STATUS_ERROR; break; } } else { val.value.integer = FS_OPEN_OK; } vpi_put_value(fstatush, &val, 0, vpiNoDelay); } val.format = vpiIntVal; val.value.integer = result; vpi_put_value(fhandleh, &val, 0, vpiNoDelay); free(fname); return 0; } static PLI_INT32 ivlh_readwriteline_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; /* Check that there are two arguments and that the first is an integer (file handle) and that the second is string. */ if(argv == 0) { show_error_line(callh); vpi_printf("%s requires two arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if(!arg || !is_integer_var(arg)) { show_error_line(callh); vpi_printf("%s's first argument must be an integer variable (file handle).\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if(!arg || !is_string_obj(arg)) { show_error_line(callh); vpi_printf("%s's second argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "two arguments", 0); return 0; } /* procedure READLINE (file F: TEXT; L: inout LINE); */ /* slightly modified sys_fgets_calltf */ static PLI_INT32 ivlh_readline_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle stringh, arg; s_vpi_value val; PLI_UINT32 fd; FILE *fp; char *text; char buf[STRING_BUF_SIZE]; /* Get the file descriptor. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd = val.value.integer; /* Get the string handle. */ stringh = vpi_scan(argv); vpi_free_object(argv); /* Return zero if this is not a valid fd. */ fp = vpi_get_file(fd); if(!fp) { show_warning_line(callh); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd, name); return 0; } /* Read in the bytes. Return 0 if there was an error. */ if(fgets(buf, STRING_BUF_SIZE, fp) == 0) { show_error_line(callh); vpi_printf("%s reading past the end of file.\n", name); return 0; } int len = strlen(buf); if(len == 0) { show_error_line(callh); vpi_printf("%s read 0 bytes.\n", name); return 0; } else if(len == STRING_BUF_SIZE - 1) { show_warning_line(callh); vpi_printf("%s has reached the buffer limit, part of the " "processed string might have been skipped.\n", name); } /* Remove the newline character(s) */ while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) { buf[len-1] = 0; len--; } /* Return the characters to the register. */ text = strdup(buf); val.format = vpiStringVal; val.value.str = text; vpi_put_value(stringh, &val, 0, vpiNoDelay); free(text); /* Set end-of-file flag if we have just reached the end of the file. * Otherwise the flag would be set only after the next read operation. */ int c = fgetc(fp); ungetc(c, fp); return 0; } /* procedure WRITELINE (file F: TEXT; L: inout LINE); */ /* slightly modified sys_fgets_calltf */ static PLI_INT32 ivlh_writeline_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle stringh, arg; s_vpi_value val; PLI_UINT32 fd; FILE *fp; char *empty; /* Get the file descriptor. */ arg = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(arg, &val); fd = val.value.integer; /* Get the string contents. */ stringh = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(stringh, &val); vpi_free_object(argv); /* Return zero if this is not a valid fd. */ fp = vpi_get_file(fd); if(!fp) { show_warning_line(callh); vpi_printf("invalid file descriptor (0x%x) given to %s.\n", (unsigned int)fd, name); return 0; } fprintf(fp, "%s\n", val.value.str); /* Clear the written string */ empty = strdup(""); val.format = vpiStringVal; val.value.str = empty; vpi_put_value(stringh, &val, 0, vpiNoDelay); free(empty); return 0; } static PLI_INT32 ivlh_read_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; if(argv == 0) { show_error_line(callh); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if(!arg || !is_string_obj(arg)) { show_error_line(callh); vpi_printf("%s's first argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if(!arg || is_constant_obj(arg)) { show_error_line(callh); vpi_printf("%s's second argument must be a variable.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if(!arg) { show_error_line(callh); vpi_printf("%s's third argument must be an integer.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "three arguments", 0); return 0; } /* procedure READ (L: inout LINE; VALUE: out BIT/BIT_VECTOR/BOOLEAN/CHARACTER/INTEGER/REAL/STRING/TIME); */ static PLI_INT32 ivlh_read_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle stringh, varh, formath; s_vpi_value val; PLI_INT32 type, format, dest_size; char *string = 0; unsigned int processed_chars = 0, fail = 0; /* Get the string */ stringh = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(stringh, &val); if(strlen(val.value.str) == 0) { show_error_line(callh); vpi_printf("%s cannot read from an empty string.\n", name); return 0; } string = strdup(val.value.str); /* Get the destination variable */ varh = vpi_scan(argv); type = vpi_get(vpiType, varh); dest_size = vpi_get(vpiSize, varh); /* Get the format (see enum format_t) */ formath = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(formath, &val); format = val.value.integer; vpi_free_object(argv); switch(format) { case FORMAT_STD: switch(type) { /* TODO longint is 64-bit, so it has to be handled by vector */ /*case vpiLongIntVar:*/ case vpiShortIntVar: case vpiIntVar: case vpiByteVar: case vpiIntegerVar: val.format = vpiIntVal; if(sscanf(string, "%d%n", &val.value.integer, &processed_chars) != 1) fail = 1; break; case vpiBitVar: /* bit, bit vector */ case vpiLogicVar: /* ==vpiReg time, logic, logic vector */ processed_chars = read_vector(string, &val, varh); break; case vpiRealVar: val.format = vpiRealVal; if(sscanf(string, "%lf%n", &val.value.real, &processed_chars) != 1) fail = 1; break; case vpiStringVar: processed_chars = read_string(string, &val, dest_size / 8); break; default: fail = 1; show_warning_line(callh); vpi_printf("%s does not handle such type (%d).\n", name, type); break; } break; case FORMAT_BOOL: { char buf[6]; val.format = vpiIntVal; if(sscanf(string, "%5s%n", buf, &processed_chars) == 1) { if(!strncasecmp(buf, "true", 4)) val.value.integer = 1; else if(!strncasecmp(buf, "false", 5)) val.value.integer = 0; else fail = 1; } } break; case FORMAT_TIME: val.format = vpiIntVal; processed_chars = read_time(string, &val, vpi_get(vpiTimeUnit, callh)); break; case FORMAT_HEX: val.format = vpiIntVal; if(sscanf(string, "%x%n", &val.value.integer, &processed_chars) != 1) fail = 1; break; case FORMAT_STRING: processed_chars = read_string(string, &val, dest_size / 8); break; } if(processed_chars == 0) { show_error_line(callh); vpi_printf("%s could not read a valid value.\n", name); fail = 1; } else if(val.format == vpiStringVar && processed_chars == STRING_BUF_SIZE) { show_warning_line(callh); vpi_printf("%s has reached the buffer limit, part of the " "processed string might have been skipped.\n", name); } if(!fail) { assert(processed_chars > 0); /* Store the read value */ vpi_put_value(varh, &val, 0, vpiNoDelay); /* Clean up */ if(val.format == vpiStringVal) free(val.value.str); else if(val.format == vpiVectorVal) free(val.value.vector); /* Strip the read token from the string */ char* tmp = strdup(&string[processed_chars]); val.format = vpiStringVal; val.value.str = tmp; vpi_put_value(stringh, &val, 0, vpiNoDelay); free(tmp); } else { show_error_line(callh); vpi_printf("%s failed.\n", name); /*vpip_set_return_value(1);*/ /*vpi_control(vpiFinish, 1);*/ } free(string); return 0; } static PLI_INT32 ivlh_write_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle arg; if(argv == 0) { show_error_line(callh); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if(!arg || !is_string_obj(arg)) { show_error_line(callh); vpi_printf("%s's first argument must be a string.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); } arg = vpi_scan(argv); if(!arg) { show_error_line(callh); vpi_printf("%s requires three arguments.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } arg = vpi_scan(argv); if(!arg) { show_error_line(callh); vpi_printf("%s's third argument must be an integer.\n", name); vpip_set_return_value(1); vpi_control(vpiFinish, 1); return 0; } /* Make sure there are no extra arguments. */ check_for_extra_args(argv, callh, name, "three arguments", 0); return 0; } /*procedure WRITE (L: inout LINE; VALUE: in BIT/BIT_VECTOR/BOOLEAN/CHARACTER/INTEGER/REAL/STRING/TIME); JUSTIFIED: in SIDE:= RIGHT; FIELD: in WIDTH := 0); */ /* JUSTIFIED & FIELD are not handled at the moment */ static PLI_INT32 ivlh_write_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle stringh, varh, formath; s_vpi_value val; PLI_INT32 type, format; char *string = 0; unsigned int fail = 0, res = 0; char buf[STRING_BUF_SIZE]; /* Get the string */ stringh = vpi_scan(argv); val.format = vpiStringVal; vpi_get_value(stringh, &val); string = strdup(val.value.str); /* Get the destination variable */ varh = vpi_scan(argv); type = vpi_get(vpiType, varh); /* Get the format (see enum format_t) */ formath = vpi_scan(argv); val.format = vpiIntVal; vpi_get_value(formath, &val); format = val.value.integer; vpi_free_object(argv); /* Convert constant types to variable types */ if(type == vpiConstant) { type = vpi_get(vpiConstType, varh); switch(type) { case vpiRealConst: type = vpiRealVar; break; case vpiStringConst: type = vpiStringVar; break; case vpiDecConst: case vpiOctConst: case vpiHexConst: type = vpiIntVar; break; case vpiBinaryConst: type = vpiBitVar; break; } } switch(format) { case FORMAT_STD: switch(type) { /* TODO longint is 64-bit, so it has to be handled by vector */ /*case vpiLongIntVar:*/ case vpiShortIntVar: case vpiIntVar: case vpiByteVar: case vpiIntegerVar: val.format = vpiIntVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%d", string, val.value.integer); break; case vpiBitVar: /* bit, bit vector */ case vpiLogicVar: /* ==vpiReg time, logic, logic vector */ val.format = vpiBinStrVal; vpi_get_value(varh, &val); /* VHDL stores X/Z values uppercase, so follow the rule */ for(size_t i = 0; i< strlen(val.value.str); ++i) val.value.str[i] = toupper(val.value.str[i]); res = snprintf(buf, STRING_BUF_SIZE, "%s%s", string, val.value.str); break; case vpiRealVar: val.format = vpiRealVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%lf", string, val.value.real); break; case vpiStringVar: val.format = vpiStringVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%s", string, val.value.str); break; default: fail = 1; show_warning_line(callh); vpi_printf("%s does not handle such type (%d).\n", name, type); break; } break; case FORMAT_BOOL: val.format = vpiIntVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%s", string, val.value.integer ? "TRUE" : "FALSE"); break; case FORMAT_TIME: { char tmp[64]; val.format = vpiIntVal; vpi_get_value(varh, &val); if(write_time(tmp, &val, vpi_get(vpiSize, varh), vpi_get(vpiTimeUnit, callh))) { fail = 1; break; } res = snprintf(buf, STRING_BUF_SIZE, "%s%s", string, tmp); } break; case FORMAT_HEX: val.format = vpiIntVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%X", string, val.value.integer); break; case FORMAT_STRING: val.format = vpiStringVal; vpi_get_value(varh, &val); res = snprintf(buf, STRING_BUF_SIZE, "%s%s", string, val.value.str); break; } if(res >= STRING_BUF_SIZE) fail = 1; if(!fail) { /* Strip the read token from the string */ char* tmp = strdup(buf); val.format = vpiStringVal; val.value.str = tmp; vpi_put_value(stringh, &val, 0, vpiNoDelay); free(tmp); } else { show_error_line(callh); vpi_printf("%s failed.\n", name); /*vpip_set_return_value(1);*/ /*vpi_control(vpiFinish, 1);*/ } free(string); return 0; } static void vhdl_register(void) { vpiHandle res; s_vpi_systf_data tf_data[] = { { vpiSysTask, 0, "$ivlh_file_open", ivlh_file_open_calltf, ivlh_file_open_compiletf, 0, "$ivlh_file_open" }, { vpiSysTask, 0, "$ivlh_readline", ivlh_readline_calltf, ivlh_readwriteline_compiletf, 0, "$ivlh_readline" }, { vpiSysTask, 0, "$ivlh_writeline", ivlh_writeline_calltf, ivlh_readwriteline_compiletf, 0, "$ivlh_writeline" }, { vpiSysTask, 0, "$ivlh_read", ivlh_read_calltf, ivlh_read_compiletf, 0, "$ivlh_read" }, { vpiSysTask, 0, "$ivlh_write", ivlh_write_calltf, ivlh_write_compiletf, 0, "$ivlh_write" }, }; for(unsigned int i = 0; i < sizeof(tf_data) / sizeof(s_vpi_systf_data); ++i) { res = vpi_register_systf(&tf_data[i]); vpip_make_systf_system_defined(res); } } void (*vlog_startup_routines[])(void) = { vhdl_register, 0 }; iverilog-12_0/vpi/vpi_config.h.in000066400000000000000000000022241435245347300170460ustar00rootroot00000000000000#ifndef IVL_vpi_config_H #define IVL_vpi_config_H /* * Copyright (c) 2004-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. */ # undef HAVE_LIBIBERTY_H # undef HAVE_INTTYPES_H # undef HAVE_LIBZ # undef HAVE_LIBBZ2 # undef HAVE_FMIN # undef HAVE_FMAX # undef WORDS_BIGENDIAN # undef _LARGEFILE_SOURCE #ifdef _LARGEFILE_SOURCE # define _FILE_OFFSET_BITS 64 #endif #endif /* IVL_vpi_config_H */ iverilog-12_0/vpi/vpi_debug.c000066400000000000000000000064531435245347300162650ustar00rootroot00000000000000/* * Copyright (c) 2011-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. */ /* * The $vpi_tree(...) system task dumps the scopes listed in the * arguments. If no arguments are given, then dump the scope that * contains the call to the $vpi_tree function. */ # include "vpi_user.h" # include # include static void dump_object(vpiHandle item) { PLI_INT32 item_type = vpi_get(vpiType, item); vpiHandle argv, cur; vpi_printf("%s: ", vpi_get_str(vpiFullName, item)); vpi_printf("vpiType=%s (%d)\n", vpi_get_str(vpiType, item), item_type); switch (item_type) { /* These types are themselves scopes and have objects within. */ case vpiModule: case vpiGenScope: case vpiFunction: case vpiTask: case vpiNamedBegin: case vpiNamedFork: argv = vpi_iterate(vpiScope, item); for (cur = vpi_scan(argv) ; cur ; cur = vpi_scan(argv)) dump_object(cur); break; #if 0 case vpiRegArray: case vpiNetArray: vpi_printf("%s: ", vpi_get_str(vpiFullName, item)); vpi_printf("vpiType=%s (%d)\n", vpi_get_str(vpiType, item), item_type); argv = vpi_iterate(vpiMember, item); for (cur = vpi_scan(argv) ; cur ; cur = vpi_scan(argv)) dump_object(cur); break; #endif /* vpiMemory contains words. */ case vpiMemory: argv = vpi_iterate(vpiMemoryWord, item); for (cur = vpi_scan(argv) ; cur ; cur = vpi_scan(argv)) dump_object(cur); break; default: break; } } static PLI_INT32 vpi_tree_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name) { (void)name; /* Parameter is not used. */ return 0; } static PLI_INT32 vpi_tree_calltf(ICARUS_VPI_CONST PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, callh); vpiHandle item; (void)name; /* Parameter is not used. */ if (argv == 0) { item = vpi_handle(vpiScope, callh); dump_object(item); return 0; } for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) dump_object(item); return 0; } void sys_register(void) { s_vpi_systf_data tf_data; vpiHandle res; tf_data.type = vpiSysTask; tf_data.tfname = "$vpi_tree"; tf_data.calltf = vpi_tree_calltf; tf_data.compiletf = vpi_tree_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$vpi_tree"; res = vpi_register_systf(&tf_data); vpip_make_systf_system_defined(res); } void (*vlog_startup_routines[])(void) = { sys_register, 0 }; iverilog-12_0/vpi/wavealloca.h000066400000000000000000000027321435245347300164400ustar00rootroot00000000000000/* * Copyright (c) 1999 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * SPDX-License-Identifier: MIT */ #ifndef WAVE_ALLOCA_H #define WAVE_ALLOCA_H #include #ifdef HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef __MINGW32__ #ifndef alloca #define alloca __builtin_alloca #endif #else #include #endif #elif defined(_MSC_VER) #include #define alloca _alloca #endif #define wave_alloca alloca #endif iverilog-12_0/vpi_modules.cc000066400000000000000000000223441435245347300162110ustar00rootroot00000000000000/* * Copyright (c) 2019-2021 Martin Whitaker (icarus@martin-whitaker.me.uk) * * 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 "compiler.h" #include "vpi_user.h" #include "sv_vpi_user.h" #include "vvp/ivl_dlfcn.h" using namespace std; /* The only VPI routines that can be legally called when the functions in the vlog_startup_routines[] array are executed are vpi_register_systf() and vpi_register_cb(), so we can simply provide stubs for the rest. We aren't going to execute any callbacks, so we can just provide a stub for vpi_register_cb() too. Note that the Icarus system module illegally calls vpi_get_vlog_info() during startup, so take care to fill in the data structure for that. */ // callback related vpiHandle vpi_register_cb(p_cb_data) { return 0; } PLI_INT32 vpi_remove_cb(vpiHandle) { return 0; } void vpi_get_systf_info(vpiHandle, p_vpi_systf_data) { } // for obtaining handles vpiHandle vpi_handle_by_name(const char*, vpiHandle) { return 0; } vpiHandle vpi_handle_by_index(vpiHandle, PLI_INT32) { return 0; } // for traversing relationships vpiHandle vpi_handle(PLI_INT32, vpiHandle) { return 0; } vpiHandle vpi_iterate(PLI_INT32, vpiHandle) { return 0; } vpiHandle vpi_scan(vpiHandle) { return 0; } // for processing properties PLI_INT32 vpi_get(int, vpiHandle) { return 0; } char* vpi_get_str(PLI_INT32, vpiHandle) { return 0; } // delay processing void vpi_get_delays(vpiHandle, p_vpi_delay) { } void vpi_put_delays(vpiHandle, p_vpi_delay) { } // value processing void vpi_get_value(vpiHandle, p_vpi_value) { } vpiHandle vpi_put_value(vpiHandle, p_vpi_value, p_vpi_time, PLI_INT32) { return 0; } // time processing void vpi_get_time(vpiHandle, s_vpi_time*) { } // data processing void* vpi_get_userdata(vpiHandle) { return 0; } PLI_INT32 vpi_put_userdata(vpiHandle, void*) { return 0; } // I/O routines PLI_UINT32 vpi_mcd_open(char *) { return 0; } PLI_UINT32 vpi_mcd_close(PLI_UINT32) { return 0; } PLI_INT32 vpi_mcd_flush(PLI_UINT32) { return 0; } char* vpi_mcd_name(PLI_UINT32) { return 0; } PLI_INT32 vpi_mcd_printf(PLI_UINT32, const char*, ...) { return 0; } PLI_INT32 vpi_mcd_vprintf(PLI_UINT32, const char*, va_list) { return 0; } PLI_INT32 vpi_flush(void) { return 0; } PLI_INT32 vpi_printf(const char*, ...) { return 0; } PLI_INT32 vpi_vprintf(const char*, va_list) { return 0; } // utility routines PLI_INT32 vpi_chk_error(p_vpi_error_info) { return 0; } PLI_INT32 vpi_compare_objects(vpiHandle, vpiHandle) { return 0; } PLI_INT32 vpi_free_object(vpiHandle) { return 0; } PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info info) { info->argc = 0; info->argv = 0; info->product = 0; info->version = 0; return 0; } // control routines void vpi_control(PLI_INT32, ...) { } void vpi_sim_control(PLI_INT32, ...) { } // proposed standard extensions PLI_INT32 vpi_fopen(const char*, const char*) { return 0; } FILE* vpi_get_file(PLI_INT32) { return 0; } // Icarus extensions s_vpi_vecval vpip_calc_clog2(vpiHandle) { s_vpi_vecval val = { 0, 0 }; return val; } void vpip_count_drivers(vpiHandle, unsigned, unsigned [4]) { } void vpip_format_strength(char*, s_vpi_value*, unsigned) { } void vpip_make_systf_system_defined(vpiHandle) { } void vpip_mcd_rawwrite(PLI_UINT32, const char*, size_t) { } void vpip_set_return_value(int) { } void vpi_vcontrol(PLI_INT32, va_list) { } /* When a module registers a system function, extract and save the return type for use during elaboration. */ vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss) { if (ss->type != vpiSysFunc) return 0; struct sfunc_return_type ret_type; ret_type.name = ss->tfname; switch (ss->sysfunctype) { case vpiIntFunc: ret_type.type = IVL_VT_LOGIC; ret_type.wid = 32; ret_type.signed_flag = true; break; case vpiRealFunc: ret_type.type = IVL_VT_REAL; ret_type.wid = 1; ret_type.signed_flag = true; break; case vpiTimeFunc: ret_type.type = IVL_VT_LOGIC; ret_type.wid = 64; ret_type.signed_flag = false; break; case vpiSizedFunc: ret_type.type = IVL_VT_LOGIC; ret_type.wid = ss->sizetf ? ss->sizetf(ss->user_data) : 32; ret_type.signed_flag = false; break; case vpiSizedSignedFunc: ret_type.type = IVL_VT_LOGIC; ret_type.wid = ss->sizetf ? ss->sizetf(ss->user_data) : 32; ret_type.signed_flag = true; break; case vpiStringFunc: ret_type.type = IVL_VT_STRING; ret_type.wid = 0; ret_type.signed_flag = false; break; case vpiOtherFunc: ret_type.type = IVL_VT_NO_TYPE; ret_type.wid = 0; ret_type.signed_flag = false; break; default: cerr << "warning: " << ss->tfname << " has an unknown return type. " "Assuming 32 bit unsigned." << endl; ret_type.type = IVL_VT_LOGIC; ret_type.wid = 32; ret_type.signed_flag = false; break; } ret_type.override_flag = false; add_sys_func(ret_type); return 0; } #if defined(__MINGW32__) || defined (__CYGWIN__) vpip_routines_s vpi_routines = { .register_cb = vpi_register_cb, .remove_cb = vpi_remove_cb, .register_systf = vpi_register_systf, .get_systf_info = vpi_get_systf_info, .handle_by_name = vpi_handle_by_name, .handle_by_index = vpi_handle_by_index, .handle = vpi_handle, .iterate = vpi_iterate, .scan = vpi_scan, .get = vpi_get, .get_str = vpi_get_str, .get_delays = vpi_get_delays, .put_delays = vpi_put_delays, .get_value = vpi_get_value, .put_value = vpi_put_value, .get_time = vpi_get_time, .get_userdata = vpi_get_userdata, .put_userdata = vpi_put_userdata, .mcd_open = vpi_mcd_open, .mcd_close = vpi_mcd_close, .mcd_flush = vpi_mcd_flush, .mcd_name = vpi_mcd_name, .mcd_vprintf = vpi_mcd_vprintf, .flush = vpi_flush, .vprintf = vpi_vprintf, .chk_error = vpi_chk_error, .compare_objects = vpi_compare_objects, .free_object = vpi_free_object, .get_vlog_info = vpi_get_vlog_info, .vcontrol = vpi_vcontrol, .fopen = vpi_fopen, .get_file = vpi_get_file, .calc_clog2 = vpip_calc_clog2, .count_drivers = vpip_count_drivers, .format_strength = vpip_format_strength, .make_systf_system_defined = vpip_make_systf_system_defined, .mcd_rawwrite = vpip_mcd_rawwrite, .set_return_value = vpip_set_return_value, }; typedef PLI_UINT32 (*vpip_set_callback_t)(vpip_routines_s*, PLI_UINT32); #endif typedef void (*vlog_startup_routines_t)(void); bool load_vpi_module(const char*path) { ivl_dll_t dll = ivl_dlopen(path, false); if (dll == 0) { cerr << "error: Failed to open '" << path << "' because:" << endl; cerr << " : " << dlerror() << endl; return false; } #if defined(__MINGW32__) || defined (__CYGWIN__) void*function = ivl_dlsym(dll, "vpip_set_callback"); if (function == 0) { cerr << "warning: '" << path << "' has no vpip_set_callback()" << endl; ivl_dlclose(dll); return true; } vpip_set_callback_t set_callback = (vpip_set_callback_t)function; if (!set_callback(&vpi_routines, vpip_routines_version)) { cerr << "error: Failed to link '" << path << "'. " "Try rebuilding it with iverilog-vpi." << endl; ivl_dlclose(dll); return true; } #endif void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU); if (table == 0) { cerr << "warning: '" << path << "' has no vlog_startup_routines" << endl; ivl_dlclose(dll); return true; } vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table; for (unsigned idx = 0; routines[idx]; idx += 1) { (routines[idx])(); } ivl_dlclose(dll); return true; } iverilog-12_0/vpi_user.h000066400000000000000000000604631435245347300153650ustar00rootroot00000000000000#ifndef VPI_USER_H #define VPI_USER_H /* * Copyright (c) 1999-2020 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. */ #if defined(__MINGW32__) || defined (__CYGWIN__) # define DLLEXPORT __declspec(dllexport) #else # define DLLEXPORT #endif #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_END } #else # define EXTERN_C_START # define EXTERN_C_END #endif #ifndef __GNUC__ # undef __attribute__ # define __attribute__(x) #endif EXTERN_C_START # include # include # include # include "_pli_types.h" #ifndef ICARUS_VPI_CONST #define ICARUS_VPI_CONST #endif #ifdef __cplusplus typedef class __vpiHandle *vpiHandle; #else typedef struct __vpiHandle *vpiHandle; #endif /* * This structure is created by the VPI application to provide hooks * into the application that the compiler/simulator can access. */ typedef struct t_vpi_systf_data { PLI_INT32 type; PLI_INT32 sysfunctype; const char *tfname; PLI_INT32 (*calltf) (ICARUS_VPI_CONST PLI_BYTE8*); PLI_INT32 (*compiletf)(ICARUS_VPI_CONST PLI_BYTE8*); PLI_INT32 (*sizetf) (ICARUS_VPI_CONST PLI_BYTE8*); ICARUS_VPI_CONST PLI_BYTE8 *user_data; } s_vpi_systf_data, *p_vpi_systf_data; /* The type in the above structure can have one of the following values: */ #define vpiSysTask 1 #define vpiSysFunc 2 typedef struct t_vpi_vlog_info { PLI_INT32 argc; char **argv; char *product; char *version; } s_vpi_vlog_info, *p_vpi_vlog_info; typedef struct t_vpi_time { /* Type can be : vpiScaledRealTime == 1 vpiSimTime == 2 vpiSuppressTime == 3 */ PLI_INT32 type; PLI_UINT32 high; PLI_UINT32 low; double real; } s_vpi_time, *p_vpi_time; #define vpiScaledRealTime 1 #define vpiSimTime 2 #define vpiSuppressTime 3 typedef struct t_vpi_vecval { PLI_INT32 aval, bval; /* ab encoding: 00=0, 10=1, 11=X, 01=Z */ } s_vpi_vecval, *p_vpi_vecval; typedef struct t_vpi_strengthval { PLI_INT32 logic; PLI_INT32 s0, s1; } s_vpi_strengthval, *p_vpi_strengthval; /* * This structure holds values that are passed back and forth between * the simulator and the application. */ typedef struct t_vpi_value { PLI_INT32 format; union { char *str; PLI_INT32 scalar; PLI_INT32 integer; double real; struct t_vpi_time *time; struct t_vpi_vecval *vector; struct t_vpi_strengthval *strength; char *misc; } value; } s_vpi_value, *p_vpi_value; /* Conform the IEEE 1364, We add the Standard vpi_delay structure to enable the modpath delay values Conform IEEE 1364, Pg 670 : The "da" field of the s_vpi_delay structure shall be a user allocated array of "s_vpi_time" structure The array shall store delay values returned by vpi_get_delay(). The number of elements in the array shall be determined by (1) The number of delays to be retrieved ( normally this is used in vpi_get_delays (..) ) { (1.1) Set by "no_of_delays" field (1.2) For the primitive_object, the no_of_delays shall be 2 or 3 (1.3) For path_delay object the no_of_delays shall be 1,2,3,6, 12 (1.4) For timing_check_object, the no_of_delays shall be match the number of limits existing in the Time Check (1.5) For intermodule_path object, the no_of_delays shall be 2 or 3 } (2) The "mtm_flag" && "pulsere_flag" Normally, if you set mtm = X, pulsere = Y then, you will need allocate (num * no_of_delay) s_vpi_time elements for 'da' array before calling the vpi_get/put_delays (..) --------------------------------------------------------------------------- | | | | | mtm_flag | No of s_vpi_time array | order in which delay | | pulsere_flag | element required by the | elements shall be filed | | | s_vpi_delay->da | | | | | | |----------------|-------------------------|------------------------------| | | | 1o delay da[0]--> 1o delay | | mtm = false | no_of_delay | 2o delay da[1]--> 2o delay | | pulere = false | | | | | | | |----------------|-------------------------|------------------------------| | | | 1o delay da[0]--> min delay | | mtm = true | | da[1]--> typ delay | | pulere = false | 3*no_of_delay | da[2]--> max delay | | | | 2o delay da[3]--> min delay | | | | da[4]--> typ delay | | | | .... | |----------------|-------------------------|------------------------------| | | | 1o delay da[0]--> delay | | mtm = false | | da[1]--> rej limit | | pulere = true | 3*no_of_delay | da[2]--> err limit | | | | 2o delay da[3]--> delay | | | | da[4]--> rej limit | | | | .... | |----------------|-------------------------|------------------------------| | | | 1o delay da[0]--> min delay | | mtm = true | | da[1]--> typ delay | | pulere = true | 9*no_of_delay | da[2]--> max delay | | | | da[3]--> min delay | | | | da[4]--> typ delay | | | | da[5]--> max delay | | | | da[6]--> min delay | | | | da[7]--> typ delay | | | | da[8]--> max delay | | | | 2o delay da[9]--> min delay | | | | .... | ------------------------------------------------------------------------- IMPORTANT : The delay Structure has to be allocated before passing a pointer to "vpi_get_delays ( )". */ typedef struct t_vpi_delay { struct t_vpi_time *da; /* Array of delay data */ PLI_INT32 no_of_delays ; PLI_INT32 time_type; /* vpiScaledRealTime, vpiSimTime */ PLI_INT32 mtm_flag; PLI_INT32 append_flag; PLI_INT32 pulsere_flag; } s_vpi_delay, *p_vpi_delay; /* These are valid codes for the format of the t_vpi_value structure. */ #define vpiBinStrVal 1 #define vpiOctStrVal 2 #define vpiDecStrVal 3 #define vpiHexStrVal 4 #define vpiScalarVal 5 #define vpiIntVal 6 #define vpiRealVal 7 #define vpiStringVal 8 #define vpiVectorVal 9 #define vpiStrengthVal 10 #define vpiTimeVal 11 #define vpiObjTypeVal 12 #define vpiSuppressVal 13 /* SCALAR VALUES */ #define vpi0 0 #define vpi1 1 #define vpiZ 2 #define vpiX 3 #define vpiH 4 #define vpiL 5 #define vpiDontCare 6 /* STRENGTH VALUES */ #define vpiSupplyDrive 0x80 #define vpiStrongDrive 0x40 #define vpiPullDrive 0x20 #define vpiLargeCharge 0x10 #define vpiWeakDrive 0x08 #define vpiMediumCharge 0x04 #define vpiSmallCharge 0x02 #define vpiHiZ 0x01 /* OBJECT CODES */ #define vpiConstant 7 #define vpiFunction 20 #define vpiIntegerVar 25 #define vpiIterator 27 #define vpiMemory 29 #define vpiMemoryWord 30 #define vpiModPath 31 #define vpiModule 32 #define vpiNamedBegin 33 #define vpiNamedEvent 34 #define vpiNamedFork 35 #define vpiNet 36 #define vpiNetBit 37 #define vpiParameter 41 #define vpiPartSelect 42 #define vpiPathTerm 43 #define vpiPort 44 #define vpiRealVar 47 #define vpiReg 48 #define vpiRegBit 49 #define vpiSysFuncCall 56 #define vpiSysTaskCall 57 #define vpiTask 59 #define vpiTimeVar 63 #define vpiUdpDefn 66 #define vpiUserSystf 67 #define vpiNetArray 114 #define vpiIndex 78 #define vpiLeftRange 79 #define vpiParent 81 #define vpiRightRange 83 #define vpiScope 84 #define vpiSysTfCall 85 #define vpiArgument 89 #define vpiInternalScope 92 #define vpiModPathIn 95 #define vpiModPathOut 96 #define vpiVariables 100 #define vpiExpr 102 /********************** object types added with 1364-2001 *********************/ #define vpiCallback 107 #define vpiRegArray 116 /********************** object types added with 1364-2005 *********************/ #define vpiGenScope 134 /* PROPERTIES */ #define vpiUndefined (-1) #define vpiType 1 #define vpiName 2 #define vpiFullName 3 #define vpiSize 4 #define vpiFile 5 #define vpiLineNo 6 #define vpiTopModule 7 #define vpiCellInstance 8 #define vpiDefName 9 #define vpiTimeUnit 11 #define vpiTimePrecision 12 #define vpiDefFile 15 #define vpiDefLineNo 16 #define vpiScalar 17 #define vpiVector 18 #define vpiDirection 20 /* direction of port: */ # define vpiInput 1 # define vpiOutput 2 # define vpiInout 3 # define vpiMixedIO 4 /* Not currently output */ # define vpiNoDirection 5 #define vpiNetType 22 # define vpiWire 1 # define vpiWand 2 # define vpiWor 3 # define vpiTri 4 # define vpiTri0 5 # define vpiTri1 6 # define vpiTriReg 7 # define vpiTriAnd 8 # define vpiTriOr 9 # define vpiSupply1 10 # define vpiSupply0 11 #define vpiArray 28 #define vpiPortIndex 29 #define vpiEdge 36 # define vpiNoEdge 0x00 /* No edge */ # define vpiEdge01 0x01 /* 0 --> 1 */ # define vpiEdge10 0x02 /* 1 --> 0 */ # define vpiEdge0x 0x04 /* 0 --> x */ # define vpiEdgex1 0x08 /* x --> 1 */ # define vpiEdge1x 0x10 /* 1 --> x */ # define vpiEdgex0 0x20 /* x --> 0 */ # define vpiPosedge (vpiEdgex1|vpiEdge01|vpiEdge0x) # define vpiNegedge (vpiEdgex0|vpiEdge10|vpiEdge1x) # define vpiAnyEdge (vpiPosedge|vpiNegedge) #define vpiConstType 40 # define vpiDecConst 1 # define vpiRealConst 2 # define vpiBinaryConst 3 # define vpiOctConst 4 # define vpiHexConst 5 # define vpiStringConst 6 #define vpiFuncType 44 # define vpiIntFunc 1 # define vpiRealFunc 2 # define vpiTimeFunc 3 # define vpiSizedFunc 4 # define vpiSizedSignedFunc 5 #define vpiSysFuncType vpiFuncType # define vpiSysFuncInt vpiIntFunc # define vpiSysFuncReal vpiRealFunc # define vpiSysFuncTime vpiTimeFunc # define vpiSysFuncSized vpiSizedFunc #define vpiUserDefn 45 #define vpiAutomatic 50 #define vpiConstantSelect 53 #define vpiSigned 65 #define vpiLocalParam 70 /* IVL private properties, also see vvp/vpi_priv.h for other properties */ #define _vpiNexusId 0x1000000 /* used in vvp/vpi_priv.h 0x1000001 */ #define _vpiDelaySelection 0x1000002 # define _vpiDelaySelMinimum 1 # define _vpiDelaySelTypical 2 # define _vpiDelaySelMaximum 3 /* used in vvp/vpi_priv.h 0x1000003 */ /* used in vvp/vpi_priv.h 0x1000004 */ /* DELAY MODES */ #define vpiNoDelay 1 #define vpiInertialDelay 2 #define vpiTransportDelay 3 #define vpiPureTransportDelay 4 #define vpiForceFlag 5 #define vpiReleaseFlag 6 #define vpiReturnEvent 0x1000 /* VPI FUNCTIONS */ extern vpiHandle vpi_register_systf(const struct t_vpi_systf_data*ss); extern void vpi_get_systf_info(vpiHandle obj, p_vpi_systf_data data); /* I/O routines */ extern PLI_UINT32 vpi_mcd_open(char *name); extern PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd); extern char *vpi_mcd_name(PLI_UINT32 mcd); extern PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, const char*fmt, ...) #ifdef __MINGW32__ __attribute__((format (gnu_printf,2,3))); #else __attribute__((format (printf,2,3))); #endif extern PLI_INT32 vpi_printf(const char*fmt, ...) #ifdef __MINGW32__ __attribute__((format (gnu_printf,1,2))); #else __attribute__((format (printf,1,2))); #endif extern PLI_INT32 vpi_vprintf(const char*fmt, va_list ap); extern PLI_INT32 vpi_mcd_vprintf(PLI_UINT32 mcd, const char*fmt, va_list ap); extern PLI_INT32 vpi_flush(void); extern PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd); /* proposed extensions */ /* * These functions are proposed extensions to Verilog, and * are described by the Verilog PLI task force as issue#347. * * The vpi_fopen() function is exactly the same as the $fopen system * function. That is, it takes a path string and a mode string, and * opens the file. The result is a 32bit value with bit 31 set, the * remaining bits made up a small integer to represent the file. * * The vpi_get_file(fd) function takes as input a descriptor as * returned by vpi_fopen or $fopen. Bit 31 must be set. The result * is the C FILE* that represents the file. */ extern PLI_INT32 vpi_fopen(const char*name, const char*mode); extern FILE *vpi_get_file(PLI_INT32 fd); /* * support for VPI callback functions. */ typedef struct t_cb_data { PLI_INT32 reason; PLI_INT32 (*cb_rtn)(struct t_cb_data*cb); vpiHandle obj; p_vpi_time time; p_vpi_value value; PLI_INT32 index; ICARUS_VPI_CONST PLI_BYTE8 *user_data; } s_cb_data, *p_cb_data; #define cbValueChange 1 #define cbStmt 2 #define cbForce 3 #define cbRelease 4 #define cbAtStartOfSimTime 5 #define cbReadWriteSynch 6 #define cbReadOnlySynch 7 #define cbNextSimTime 8 #define cbAfterDelay 9 #define cbEndOfCompile 10 #define cbStartOfSimulation 11 #define cbEndOfSimulation 12 #define cbError 13 #define cbTchkViolation 14 #define cbStartOfSave 15 #define cbEndOfSave 16 #define cbStartOfRestart 17 #define cbEndOfRestart 18 #define cbStartOfReset 19 #define cbEndOfReset 20 #define cbEnterInteractive 21 #define cbExitInteractive 22 #define cbInteractiveScopeChange 23 #define cbUnresolvedSystf 24 #define cbAtEndOfSimTime 31 extern vpiHandle vpi_register_cb(p_cb_data data); extern PLI_INT32 vpi_remove_cb(vpiHandle ref); /* * This function allows a vpi application to control the simulation * engine. The operation parameter specifies the function to * perform. The remaining parameters (if any) are interpreted by the * operation. The vpi_sim_control definition (now named vpi_control) * was added to P1364-2000 14 July 1999. See PLI Task Force ID: PTF-161 * * vpiFinish - perform the $finish operation, as soon as the user * function returns. This operation takes a single * parameter, a diagnostic exit code. * * vpiStop - * vpiReset - * vpiSetInteractiveScope - */ extern void vpi_control(PLI_INT32 operation, ...); /************* vpi_control() constants (added with 1364-2000) *************/ #define vpiStop 66 /* execute simulator's $stop */ #define vpiFinish 67 /* execute simulator's $finish */ #define vpiReset 68 /* execute simulator's $reset */ #define vpiSetInteractiveScope 69 /* set simulator's interactive scope */ #define __ivl_legacy_vpiStop 1 #define __ivl_legacy_vpiFinish 2 /* vpi_sim_control is the incorrect name for vpi_control. */ extern void vpi_sim_control(PLI_INT32 operation, ...); extern vpiHandle vpi_handle(PLI_INT32 type, vpiHandle ref); extern vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle ref); extern vpiHandle vpi_scan(vpiHandle iter); extern vpiHandle vpi_handle_by_index(vpiHandle ref, PLI_INT32 idx); extern vpiHandle vpi_handle_by_name(const char*name, vpiHandle scope); extern void vpi_get_time(vpiHandle obj, s_vpi_time*t); extern PLI_INT32 vpi_get(int property, vpiHandle ref); extern char *vpi_get_str(PLI_INT32 property, vpiHandle ref); extern void vpi_get_value(vpiHandle expr, p_vpi_value value); /* * This function puts a value into the object referenced by the * handle. This assumes that the value supports having its value * written to. The time parameter specifies when the assignment is to * take place. This allows you to schedule an assignment to happen in * the future. * * The flags value specifies the delay model to use in assigning the * value. This specifies how the time value is to be used. * * vpiNoDelay -- Set the value immediately. The p_vpi_time parameter * may be NULL, in this case. This is like a blocking assignment * in behavioral code. * * vpiInertialDelay -- Set the value using the transport delay. The * p_vpi_time parameter is required and specifies when the * assignment is to take place. This is like a non-blocking * assignment in behavioral code. */ extern vpiHandle vpi_put_value(vpiHandle obj, p_vpi_value value, p_vpi_time when, PLI_INT32 flags); extern PLI_INT32 vpi_free_object(vpiHandle ref); extern PLI_INT32 vpi_get_vlog_info(p_vpi_vlog_info vlog_info_p); /* These Routines will enable the modpath vpiHandle to read/write delay values */ extern void vpi_get_delays(vpiHandle expr, p_vpi_delay delays); extern void vpi_put_delays(vpiHandle expr, p_vpi_delay delays); /* * Check to see if two handles point to the same object. */ extern PLI_INT32 vpi_compare_objects(vpiHandle obj1, vpiHandle obj2); /* * These functions support attaching user data to an instance of a * system task or function. These functions only apply to * vpiSysTaskCall or vpiSysFuncCall handles. */ extern PLI_INT32 vpi_put_userdata(vpiHandle obj, void*data); extern void*vpi_get_userdata(vpiHandle obj); /* * Support for handling errors. */ typedef struct t_vpi_error_info { PLI_INT32 state; PLI_INT32 level; char *message; char *product; char *code; char *file; PLI_INT32 line; } s_vpi_error_info, *p_vpi_error_info; /* error_info states */ # define vpiCompile 1 # define vpiPLI 2 # define vpiRun 3 /* error_info levels */ # define vpiNotice 1 # define vpiWarning 2 # define vpiError 3 # define vpiSystem 4 # define vpiInternal 5 extern PLI_INT32 vpi_chk_error(p_vpi_error_info info); /* This is the table of startup routines included in each module. */ extern DLLEXPORT void (*vlog_startup_routines[])(void); /* * ICARUS VERILOG EXTENSIONS * * The vpip_* functions are Icarus Verilog extensions. They are not * standard VPI functions, so use these at your own risk. * * The vpip_format_* functions format values in string format in the * manner of the $display system task. */ /* Format a scalar a la %v. The str points to a 4byte character buffer. The value must be a vpiStrengthVal. */ extern void vpip_format_strength(char*str, s_vpi_value*value, unsigned bit); /* Set the return value to return from the vvp run time. This is usually 0 or 1. This is the exit code that the vvp process returns, and in distinct from the finish_number that is an argument to $fatal and other severity tasks. The $fatal and $finish system tasks bundled with iverilog use this function to tell vvp to exit SUCCESS or FAILURE. */ extern void vpip_set_return_value(int value); extern s_vpi_vecval vpip_calc_clog2(vpiHandle arg); extern void vpip_make_systf_system_defined(vpiHandle ref); /* Perform fwrite to mcd files. This is used to write raw data, which may include nulls. */ extern void vpip_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count); /* Return driver information for a net bit. The information is returned in the 'counts' array as follows: counts[0] - number of drivers driving '0' onto the net counts[1] - number of drivers driving '1' onto the net counts[2] - number of drivers driving 'X' onto the net counts[3] - set to 1 if the net is forced, 0 otherwise The 'ref' argument should reference a net. The 'idx' argument selects which bit of the net is examined. */ extern void vpip_count_drivers(vpiHandle ref, unsigned idx, unsigned counts[4]); /* * Stopgap fix for br916. We need to reject any attempt to pass a thread * variable to $strobe or $monitor. To do this, we use some private VPI * properties that are normally only used by the VVP thread cleanup code. * Normally the following definitions are provided by vvp/vpi_priv.h, but * for the stopgap fix we need to make them more widely available. */ #define BR916_STOPGAP_FIX #ifdef BR916_STOPGAP_FIX #define _vpiFromThr 0x1000001 # define _vpiNoThr 0 # define _vpiString 1 # define _vpiVThr 2 # define _vpiWord 3 # define _vpi_at_PV 4 # define _vpi_at_A 5 # define _vpi_at_APV 6 #endif #if defined(__MINGW32__) || defined (__CYGWIN__) /* * In Linux, when loaded, a shared library can automatically bind to functions * provided by its client. In Windows, a DLL can only do this statically at * link time, and is then tied to a specific client. So to enable VPI modules * to be used by both the compiler and the simulator, we construct a jump table * for the VPI routines that we can pass down to the VPI modules. */ // Increment the version number any time vpip_routines_s is changed. static const PLI_UINT32 vpip_routines_version = 1; typedef struct { vpiHandle (*register_cb)(p_cb_data); PLI_INT32 (*remove_cb)(vpiHandle); vpiHandle (*register_systf)(const struct t_vpi_systf_data*ss); void (*get_systf_info)(vpiHandle, p_vpi_systf_data); vpiHandle (*handle_by_name)(const char*, vpiHandle); vpiHandle (*handle_by_index)(vpiHandle, PLI_INT32); vpiHandle (*handle)(PLI_INT32, vpiHandle); vpiHandle (*iterate)(PLI_INT32, vpiHandle); vpiHandle (*scan)(vpiHandle); PLI_INT32 (*get)(int, vpiHandle); char* (*get_str)(PLI_INT32, vpiHandle); void (*get_delays)(vpiHandle, p_vpi_delay); void (*put_delays)(vpiHandle, p_vpi_delay); void (*get_value)(vpiHandle, p_vpi_value); vpiHandle (*put_value)(vpiHandle, p_vpi_value, p_vpi_time, PLI_INT32); void (*get_time)(vpiHandle, s_vpi_time*); void* (*get_userdata)(vpiHandle); PLI_INT32 (*put_userdata)(vpiHandle, void*); PLI_UINT32 (*mcd_open)(char *); PLI_UINT32 (*mcd_close)(PLI_UINT32); PLI_INT32 (*mcd_flush)(PLI_UINT32); char* (*mcd_name)(PLI_UINT32); PLI_INT32 (*mcd_vprintf)(PLI_UINT32, const char*, va_list); PLI_INT32 (*flush)(void); PLI_INT32 (*vprintf)(const char*, va_list); PLI_INT32 (*chk_error)(p_vpi_error_info); PLI_INT32 (*compare_objects)(vpiHandle, vpiHandle); PLI_INT32 (*free_object)(vpiHandle); PLI_INT32 (*get_vlog_info)(p_vpi_vlog_info info) ; void (*vcontrol)(PLI_INT32, va_list); PLI_INT32 (*fopen)(const char*, const char*); FILE* (*get_file)(PLI_INT32); s_vpi_vecval(*calc_clog2)(vpiHandle); void (*count_drivers)(vpiHandle, unsigned, unsigned [4]); void (*format_strength)(char*, s_vpi_value*, unsigned); void (*make_systf_system_defined)(vpiHandle); void (*mcd_rawwrite)(PLI_UINT32, const char*, size_t); void (*set_return_value)(int); } vpip_routines_s; extern DLLEXPORT PLI_UINT32 vpip_set_callback(vpip_routines_s*routines, PLI_UINT32 version); #endif // defined(__MINGW32__) || defined (__CYGWIN__) EXTERN_C_END #endif /* VPI_USER_H */ iverilog-12_0/vvp/000077500000000000000000000000001435245347300141625ustar00rootroot00000000000000iverilog-12_0/vvp/Makefile.in000066400000000000000000000150641435245347300162350ustar00rootroot00000000000000# # This source code is free software; you can redistribute it # and/or modify it in source code form under the terms of the GNU # Library General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # SHELL = /bin/sh suffix = @install_suffix@ prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ datarootdir = @datarootdir@ VPATH = $(srcdir) bindir = @bindir@ libdir = @libdir@ mandir = @mandir@ includedir = @includedir@ # For a cross compile these defines will need to be set accordingly. HOSTCC = @CC@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ BUILDCC = @CC_FOR_BUILD@ BUILDEXT = @BUILD_EXEEXT@ CXX = @CXX@ DLLTOOL = @DLLTOOL@ INSTALL = @INSTALL@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ LEX = @LEX@ YACC = @YACC@ MAN = @MAN@ PS2PDF = @PS2PDF@ ifeq (@srcdir@,.) INCLUDE_PATH = -I. -I.. else INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/.. endif CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ -DICARUS_VPI_CONST=const CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@ LDFLAGS = @rdynamic@ @LDFLAGS@ LIBS = @LIBS@ @EXTRALIBS@ dllib=@DLLIB@ MDIR1 = -DMODULE_DIR1='"$(libdir)/ivl$(suffix)"' VPI = vpi_modules.o vpi_bit.o vpi_callback.o vpi_cobject.o vpi_const.o vpi_darray.o \ vpi_event.o vpi_iter.o vpi_mcd.o \ vpi_priv.o vpi_scope.o vpi_real.o vpi_signal.o vpi_string.o vpi_tasks.o vpi_time.o \ vpi_vthr_vector.o vpip_bin.o vpip_hex.o vpip_oct.o \ vpip_to_dec.o vpip_format.o vvp_vpi.o O = main.o parse.o parse_misc.o lexor.o arith.o array_common.o array.o bufif.o compile.o \ concat.o dff.o class_type.o enum_type.o extend.o file_line.o latch.o npmos.o part.o \ permaheap.o reduce.o resolv.o \ sfunc.o stop.o \ substitute.o \ symbols.o ufunc.o codes.o vthread.o schedule.o \ statistics.o tables.o udp.o vvp_island.o vvp_net.o vvp_net_sig.o \ vvp_object.o vvp_cobject.o vvp_darray.o event.o logic.o delay.o \ words.o island_tran.o $(VPI) all: dep vvp@EXEEXT@ vvp.man check: all ifeq (@WIN32@,yes) ifeq (@install_suffix@,) ./vvp -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.' else # On Windows if we have a suffix we must run the vvp test with # a suffix since it was built/linked that way. ln vvp.exe vvp$(suffix).exe ./vvp$(suffix) -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.' rm -f vvp$(suffix).exe endif else ./vvp -M../vpi $(srcdir)/examples/hello.vvp | grep 'Hello, World.' endif clean: rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc rm -rf dep vvp@EXEEXT@ parse.output vvp.man vvp.ps vvp.pdf vvp.exp distclean: clean rm -f Makefile config.log rm -f stamp-config-h config.h cppcheck: $(O:.o=.cc) draw_tt.c cppcheck --enable=all --std=c99 --std=c++03 -f \ --suppressions-list=$(srcdir)/cppcheck.sup \ -UMODULE_DIR1 -UMODULE_DIR2 -UYY_USER_INIT \ -UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \ -UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \ -UYYSTYPE -UINFINITY -U__SIZE_TYPE__ -Ufree \ --relative-paths=$(srcdir) $(INCLUDE_PATH) $^ Makefile: $(srcdir)/Makefile.in cd ..; ./config.status --file=vvp/$@ dep: mkdir dep ifeq (@WIN32@,yes) # To support cocotb, we export the VPI functions directly. This allows # cocotb to build VPI modules without using our vpi_user.h and libvpi.a. # This requires making the vvp.exe in two steps. The first step makes # a vvp.exe that dlltool can use to make an export library, and the # second step makes a vvp.exe that really exports those things. vvp@EXEEXT@: $O $(srcdir)/vvp.def $(CXX) -o vvp$(suffix)@EXEEXT@ $(LDFLAGS) $O $(dllib) $(LIBS) $(DLLTOOL) --dllname vvp$(suffix)@EXEEXT@ --def $(srcdir)/vvp.def \ --output-exp vvp.exp rm -f vvp$(suffix)@EXEEXT@ $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ vvp.exp $(LDFLAGS) $O $(dllib) $(LIBS) else vvp@EXEEXT@: $O $(CXX) $(LDFLAGS) -o vvp@EXEEXT@ $O $(LIBS) $(dllib) endif %.o: %.cc config.h $(CXX) $(CPPFLAGS) -DIVL_SUFFIX='"$(suffix)"' $(MDIR1) $(MDIR2) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep/$*.d %.o: %.c config.h $(CC) $(CPPFLAGS) $(MDIR1) $(MDIR2) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o mv $*.d dep/$*.d tables.cc: $(srcdir)/draw_tt.c $(BUILDCC) $(CFLAGS) -o draw_tt$(BUILDEXT) $(srcdir)/draw_tt.c ./draw_tt$(BUILDEXT) > tables.cc rm draw_tt$(BUILDEXT) lexor.o: lexor.cc parse.h parse.o: parse.cc tables.o: tables.cc # Use pattern rules to avoid parallel build issues (see pr3462585) parse%cc parse%h: $(srcdir)/parse%y $(YACC) --verbose -t --defines=parse.h -o parse.cc $< lexor.cc: $(srcdir)/lexor.lex $(LEX) -s -olexor.cc $(srcdir)/lexor.lex vvp.man: $(srcdir)/vvp.man.in ../version.exe ../version.exe `head -1 $(srcdir)/vvp.man.in`'\n' > $@ tail -n +2 $(srcdir)/vvp.man.in >> $@ vvp.ps: vvp.man $(MAN) -t ./vvp.man > vvp.ps vvp.pdf: vvp.ps $(PS2PDF) vvp.ps vvp.pdf ifeq (@MINGW32@,yes) ifeq ($(MAN),none) INSTALL_DOC = installman else ifeq ($(PS2PDF),none) INSTALL_DOC = installman else INSTALL_DOC = installpdf installman all: vvp.pdf endif endif INSTALL_DOCDIR = $(mandir)/man1 else INSTALL_DOC = installman INSTALL_DOCDIR = $(mandir)/man1 endif stamp-config-h: $(srcdir)/config.h.in ../config.status @rm -f $@ cd ..; ./config.status --header=vvp/config.h config.h: stamp-config-h install: all installdirs installfiles F = ./vvp@EXEEXT@ $(INSTALL_DOC) installman: vvp.man installdirs $(INSTALL_DATA) vvp.man "$(DESTDIR)$(mandir)/man1/vvp$(suffix).1" installpdf: vvp.pdf installdirs $(INSTALL_DATA) vvp.pdf "$(DESTDIR)$(prefix)/vvp$(suffix).pdf" installfiles: $(F) | installdirs $(INSTALL_PROGRAM) ./vvp@EXEEXT@ "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@" installdirs: $(srcdir)/../mkinstalldirs $(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(INSTALL_DOCDIR)" uninstall: $(UNINSTALL32) rm -f "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@" rm -f "$(DESTDIR)$(mandir)/man1/vvp$(suffix).1" "$(DESTDIR)$(prefix)/vvp$(suffix).pdf" -include $(patsubst %.o, dep/%.d, $O) iverilog-12_0/vvp/README.txt000066400000000000000000001324171435245347300156700ustar00rootroot00000000000000/* * Copyright (c) 2001-2021 Stephen Williams (steve@icarus.com) * */ VVP SIMULATION ENGINE The VVP simulator takes as input source code not unlike assembly language for a conventional processor. It is intended to be machine generated code emitted by other tools, including the Icarus Verilog compiler, so the syntax, though readable, is not necessarily convenient for humans. GENERAL FORMAT The source file is a collection of statements. Each statement may have a label, an opcode, and operands that depend on the opcode. For some opcodes, the label is optional (or meaningless) and for others it is required. Every statement is terminated by a semicolon. The semicolon is also the start of a comment line, so you can put comment text after the semicolon that terminates a statement. Like so: Label .functor and, 0x5a, x, y ; This is a comment. The semicolon is required, whether the comment is there or not. Statements may span multiple lines, as long as there is no text (other then the first character of a label) in the first column of the continuation line. HEADER SYNTAX Before any other non-commentary code starts, the source may contain some header statements. These are used for passing parameters or global details from the compiler to the vvp run-time. In all cases, the header statement starts with a left-justified keyword. * :module "name" ; This header statement names a vpi module that vvp should load before the rest of the program is compiled. The compiler looks in the standard VPI_MODULE_PATH for files named "name.vpi", and tries to dynamic load them. * :vpi_time_precision [+|-]; This header statement specifies the time precision of a single tick of the simulation clock. This is mostly used for display (and VPI) purposes, because the engine itself does not care about units. The compiler scales time values ahead of time. The value is the size of a simulation tick in seconds, and is expressed as a power of 10. For example, +0 is 1 second, and -9 is 1 nanosecond. If the record is left out, then the precision is taken to be +0. LABELS AND SYMBOLS Labels and symbols consist of the characters: a-z A-Z 0-9 .$_<> Labels and symbols may not start with a digit or a '.', so that they are easily distinguished from keywords and numbers. A Label is a symbol that starts a statement. If a label is present in a statement, it must start in the first text column. This is how the lexical analyzer distinguishes a label from a symbol. If a symbol is present in a statement, it is in the operand. Opcodes of statements must be a keyword. Symbols are references to labels. It is not necessary for a label to be declared before its use in a symbol, but it must be declared eventually. When symbols refer to functors, the symbol represents the vvp_ipoint_t pointer to the output. (Inputs cannot, and need not, be references symbolically.) If the functor is part of a vector, then the symbol is the vvp_ipoint_t for the first functor. The [] operator can then be used to reference a functor other than the first in the vector. There are some special symbols that in certain contexts have special meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C" and "C" represent a constant driver of the given value. NUMBERS: decimal number tokens are limited to 64bits, and are unsigned. Some contexts may constrain the number size further. SCOPE STATEMENTS: The syntax of a scope statement is: ; foo[n] = ; The format of the substitute statement is: , ; , ; , ; , ; , ; In all cases, there are no width limits, so long as the width is fixed. NOTE: The .arith/mult inputs are not necessarily the width of the output. I have not decided how to handle this. These devices support .s and .r suffixes. The .s means the node is a signed vector device, the .r a real valued device. STRUCTURAL COMPARE STATEMENTS: The arithmetic statements handle various arithmetic operators that have wide outputs, but the comparators have single bit output, so they are implemented a bit differently. The syntax, however, is very similar: , ; , ; , ; , ; , ; , ; , ; , ; , ; , ; Whereas the arithmetic statements generate an output the width of , the comparisons produce a single bit vector result. The plain versions do unsigned comparison, but the ".s" versions to signed comparisons. (Equality doesn't need to care about sign.) STRUCTURAL SHIFTER STATEMENTS: Variable shifts in structural context are implemented with .shift statements: : ). The two source vectors are popped from the vec4 stack (and must have the same width) and the result pushed in their place. The truth table for each bit is: 1 1 --> 1 0 0 --> 0 z z --> z x x --> x .... --> x In other words, if the bits are identical, then take that value. Otherwise, the value is x. * %blend/wr This instruction blends real values for the ternary operator. If the values match return that otherwise return 0.0. Two values are popped from the stack, one is pushed back. * %breakpoint This instruction unconditionally breaks the simulator into the interactive debugger. The idea is to stop the simulator here and give the user a chance to display the state of the simulation using debugger commands. This may not work on all platforms. If run-time debugging is compiled out, then this function is a no-op. * %callf/obj , * %callf/real , * %callf/str , * %callf/vec4 , * %callf/void , More directly implement function calling. This subsumes the %fork and %join of the more general task and block calling, but is optimized for functions, which are threads of a special, constrained sort. The different variants reflect the different return types for the called function. For example, if the function returns a string, the %callf/str opcode is used, and will push the string return value into the caller's string stack. The %callf/void function is special in that is pushes no value onto any stack. * %cassign/vec4 * %cassign/vec4/off , Perform a continuous assign of a constant value to the target variable. This is similar to %set, but it uses the cassign port (port-1) of the signal functor instead of the normal assign, so the signal responds differently. See "VARIABLE STATEMENTS" in the README.txt file. The %cassign/vec4/off instruction will check the flags[4] flag, and if it is 1, it will suppress the assignment. This is so that failed index calculations can report the failure by setting the flag. * %cassign/wr Perform a continuous assign of a constant real value to the target variable. See %cassign/v above. The value is popped from the real value stack. * %cast2 Pop a value from the vec4 stack, convert it using Verilog rules to a vector2 (binary) value, and push the result. * %cast/vec2/dar Pop a dynamic array value from the object stack, convert it to a 2-state vector that is bits wide, and push the result to the vec4 stack. If the dynamic array does not fit exactly in bits, print an error message and stop the simulation. * %cast/vec4/dar Pop a dynamic array value from the object stack, convert it to a 4-state vector that is bits wide, and push the result to the vec4 stack. If the dynamic array does not fit exactly in bits, print an error message and stop the simulation. * %cast/vec4/str Pop a value from the string stack, convert it to a vector that is bits wide, and push the result to the vec4 stack. If the string does not fit exactly in bits, print an error message and stop the simulation. * %cmp/s * %cmp/u * %cmp/e * %cmp/ne * %cmpi/s , , * %cmpi/u , , * %cmpi/e , , * %cmpi/ne , , These instructions perform a generic comparison of two vectors of equal size. Two values are pulled from the top of the stack, and not replaced. The results are written into flag bits 4,5,6. The expressions (a Pop the top string, and concatenate it to the new top string. Or think of it as passing the tail, then the head, concatenating them, and pushing the result. The stack starts with two strings in the stack, and ends with one string in the stack. The %concati/str form pops only one value from the stack. The right part comes from the immediate value. * %concat/vec4 * %concati/vec4 , , Pop two vec4 vectors, concatenate them, and push the combined result. The top of the vec4 stack is the LSB of the result, and the next in this stack is the MSB bits of the result. The %concati/vec4 form takes an immediate value and appends it (lsb) to the value on the top of the stack. See the %pushi/vec4 instruction for how to describe the immediate value. * %cvt/sr * %cvt/ur Pop a word from the real-value stack, convert it to a signed or unsigned integer, and write it to the index register. Precision may be lost in the conversion. * %cvt/rv * %cvt/rv/s The %cvt/rv instruction pops a value from the thread vec4 stack and converts it to a real word. Push the result onto the real value stack. Precision may be lost in the conversion. The %cvt/rv/s instruction is the same as %cvt/rv, but treats the thread vector as a signed value. * %cvt/vr The %cvt/vr opcode converts a real word from the stack to a vec4 that is wide. Non-integer precision is lost in the conversion, and the real value is popped from the stack. The result is pushed to the vec4 stack. * %deassign , , Deactivate and disconnect a procedural continuous assignment to a variable. The identifies the affected variable. The and are used to determine what part of the signal will be deactivated. For a full deactivation the is 0 and is the entire signal width. * %deassign/wr The same as %deassign above except this is used for real variables. * %debug/thr These opcodes are aids for debugging the vvp engine. The vvp code generator should not generate these, and they should not alter code flow, data contents, etc. * %delay , This opcode pauses the thread, and causes it to be rescheduled for a time in the future. The amount is the number of the ticks in the future to reschedule, and is >= 0. If the %delay is zero, then the thread yields the processor for another thread, but will be resumed in the current time step. The delay amount is given as 2 32bit numbers, so that 64bit times may be represented. * %delayx This is similar to the %delay opcode, except that the parameter selects an index register, which contains the actual delay. This supports run-time calculated delays. * %delete/obj Arrange for the dynamic object at the target label to be deleted. This has no effect on the object or string stack. Note that this is the same as: %null ; %store/obj but that idiom is expected to be common enough that it warrants an optimized shorthand. * %disable This instruction terminates threads that are part of a specific scope. The label identifies the scope in question, and the threads are the threads that are currently within that scope. * %disable/flow This instruction is similar to `%disable` except that it will only disable a single thread of the specified scope. The disabled thread will be the thread closest to the current thread in the thread hierarchy. This can either be thread itself or one of its parents. It is used to implement flow control statements called from within a thread that only affect the thread or its parents. E.g. SystemVerilog `return`, `continue` or `break`. * %disable/fork This instruction terminates all the detached children for the current thread. There should not be any non-detached children. * %div , , * %div/s , , This instruction arithmetically divides the vector by the vector, and leaves the result in the vector. IF any of the bits in either vector are x or z, the entire result is x. The %div/s instruction is the same as %div, but does signed division. * %div/wr This opcode divides the left operand by the right operand. If the right operand is 0, then the result is NaN. * %dup/real * %dup/vec4 * %dup/obj These opcodes duplicate the value on the top of the stack for the corresponding type. * %evctl * %evctl/c * %evctl/s * %evctl/i These instructions are used to put event and repetition information into the thread event control registers. These values are then used by the %assign/e instructions to do not blocking event control. The is the event to trigger on and the is an index register to read the repetition count from (signed or unsigned). %evctl/i sets the repetition to an immediate unsigned value. %evctl/c clears the event control information. This is needed if a %assign/e may be skipped since the %assign/e statements clear the event control information and the other %evctl statements assert that this information has been cleared. You can get an assert if this information is not managed correctly. * %event * %event/nb This instruction is used to send a pulse to an event object. The is an event variable. This instruction simply writes an arbitrary value to the event to trigger the event. * %file_line This command emits the provided file and line information along with the description when it is executed. The output is sent to stderr and the format of the output is: :: is the unsigned numeric file index. is the unsigned line number. is a string, if string is 0 then the following default message is used: "Procedural tracing.". * %flag_inv This instruct inverts a flag bit. * %flag_mov , This instruction copies the flag bit from to . * %flag_or , This instruction calculates the Verilog OR of the flag bits in and , and leaves the result in . * %flag_set/imm , This instruction sets an immediate value into a flag bit. This is a single bit, and the value is 0==0, 1==1, 2==z, 3==x. * %flag_get/vec4 * %flag_set/vec4 These instructions provide a means for accessing flag bits. The %flag_get/vec4 loads the numbered flag as a vec4 on top of the vec4 stack, and the %flag_set/vec4 pops the top of the vec4 stack and writes the LSB to the selected flag. * %force/vec4